LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Help improving a script / test Internet connectivity without using ping (https://www.linuxquestions.org/questions/programming-9/help-improving-a-script-test-internet-connectivity-without-using-ping-902657/)

Mouse750 09-12-2011 05:23 PM

Help improving a script / test Internet connectivity without using ping
 
Here is the script so far: (credit to David the H and Nominal Animal for making the script)

Code:

#!/bin/sh /etc/rc.common

START=99
start() {
        # If vpn is up Internet works, If vpn is down block Internet traffic.
        iptables -R zone_wan_ACCEPT 1 -j ACCEPT -p tcp --destination-port 443 -o eth1

        # Put *.ovpn files in /etc/config/vpn_servers/
        [ -n "$CONFIGDIR" ] || CONFIGDIR=/etc/config/vpn_servers/

        # Begin Loop
        while true; do

                # Use find to list all *.ovpn files, and
                # awk to pick one file at random.
                CONFIG=$(find "$CONFIGDIR" -maxdepth 1 -name '*.ovpn' '!' -name '*
                *' | awk '{ file[n++] = $0 } END { srand(); print file[int(n * rand())] }')

                sleep 2

                killall openvpn

                sleep 2

                #Pick Random Server
                ( openvpn --config "$CONFIG" & )

                # Use this server for 7200 seconds
                sleep 7200

        # End Loop
        done
}

The purpose of the script is to connect to a random vpn server every 2 hours. The script works great,

However there are 3 scenarios that could happen.

Scenario 1:
The script connects to a random vpn server and everything works as normal. This is of course what happens 95% of the time.

Scenario 2:
The script connects to a random vpn server but is latter dropped by the vpn server. I purposely added an iptable rule in the event, that blocks any Internet traffic not being tunneled through port 443 (the vpn connection). The end result is the end user will be without Internet for up to 7200 seconds. (until it connects to another vpn server)

Scenario 3:
The script connects to a random vpn server however the vpn server itself does not have Internet access. This is very rare but does happen once in awhile. The end result is you will be without Internet for up to 7200 seconds. (until it connects to another vpn server)


Both Scenarios 2 and 3 can be solved by manually issuing the command "killall sleep". I would like to find a way to automate this when needed.

My first thought was using the ping command. However using the ping command gives me a false positive. For example ping google.com works when connected to the vpn AND when NOT connected. As stated above I do have an iptable rule that forces the flow of traffic thru 443 but ping is not effected because ping is not port based. Long story short, I don't think I can use ping.

My second thought would be to monitor the iface's in ifconfig. If tun0 (the vpn's virtual iface) is not present, then killall sleep. However, this would only work for Scenario 2.

Ok, this whole thread is just a really long way of asking how can I test for Internet connectivity without using ping?

As a human, when I see "page not found" in my web browser, I can pretty much assume that Scenario 2 or 3 has occurred.

Tinkster 09-12-2011 06:43 PM

Quote:

Originally Posted by Mouse750 (Post 4470072)
Here is the script so far: (credit to David the H and Nominal Animal for making the script)

Code:

#!/bin/sh /etc/rc.common

START=99
start() {
        # If vpn is up Internet works, If vpn is down block Internet traffic.
        iptables -R zone_wan_ACCEPT 1 -j ACCEPT -p tcp --destination-port 443 -o eth1

        # Put *.ovpn files in /etc/config/vpn_servers/
        [ -n "$CONFIGDIR" ] || CONFIGDIR=/etc/config/vpn_servers/

        # Begin Loop
        while true; do

                # Use find to list all *.ovpn files, and
                # awk to pick one file at random.
                CONFIG=$(find "$CONFIGDIR" -maxdepth 1 -name '*.ovpn' '!' -name '*
                *' | awk '{ file[n++] = $0 } END { srand(); print file[int(n * rand())] }')

                sleep 2

                killall openvpn

                sleep 2

                #Pick Random Server
                ( openvpn --config "$CONFIG" & )

                # Use this server for 7200 seconds
                sleep 7200

        # End Loop
        done
}

The purpose of the script is to connect to a random vpn server every 2 hours. The script works great,

However there are 3 scenarios that could happen.

Scenario 1:
The script connects to a random vpn server and everything works as normal. This is of course what happens 95% of the time.

Scenario 2:
The script connects to a random vpn server but is latter dropped by the vpn server. I purposely added an iptable rule in the event, that blocks any Internet traffic not being tunneled through port 443 (the vpn connection). The end result is the end user will be without Internet for up to 7200 seconds. (until it connects to another vpn server)

Scenario 3:
The script connects to a random vpn server however the vpn server itself does not have Internet access. This is very rare but does happen once in awhile. The end result is you will be without Internet for up to 7200 seconds. (until it connects to another vpn server)


Both Scenarios 2 and 3 can be solved by manually issuing the command "killall sleep". I would like to find a way to automate this when needed.

My first thought was using the ping command. However using the ping command gives me a false positive. For example ping google.com works when connected to the vpn AND when NOT connected. As stated above I do have an iptable rule that forces the flow of traffic thru 443 but ping is not effected because ping is not port based. Long story short, I don't think I can use ping.

My second thought would be to monitor the iface's in ifconfig. If tun0 (the vpn's virtual iface) is not present, then killall sleep. However, this would only work for Scenario 2.

Ok, this whole thread is just a really long way of asking how can I test for Internet connectivity without using ping?

As a human, when I see "page not found" in my web browser, I can pretty much assume that Scenario 2 or 3 has occurred.


You could conceivably use nc (netcat ) or wget (maybe w/ a timeout of a few seconds?)
to retrieve http headers/pages from a well-known page, and if the response (timeout!)
is empty run killall.


Cheers,
Tink

grail 09-13-2011 02:27 AM

Maybe also something like dig could be used as it can check on a specific port.

I thought I would add some suggestions about the code (and definitely not to detract from NA or David):
Code:

[ -n "$CONFIGDIR" ] || CONFIGDIR=/etc/config/vpn_servers/

# could be simply
CONFIGDIR="${CONFIGDIR:-/etc/config/vpn_servers/}"

CONFIG=$(find "$CONFIGDIR" -maxdepth 1 -name '*.ovpn' '!' -name '**' | awk '{ file[n++] = $0 } END { srand(); print file[int(n * rand())] }')

# awk has few more subtleties
CONFIG=$(awk 'BEGIN{srand(); print ARGV[int((ARGC - 1) * rand()) + 1]}' "$CONFIGDIR/*.ovpn")


Mouse750 09-13-2011 04:25 PM

This is starting to get complex.

I guess I forgot to mention that this script is being run from my router.

I have a iptable rule written for my FORWARD chain that forces traffic thru my vpn. SSH'ing a wget or nc from my router does not pass thru the FORWARD chain. In other words wget or nc is going to always pass thru whether or not I am connected to the vpn server.

My head hurts,

I am going to have to sleep on this.

Maybe it would be better to monitor the iface's in ifconfig. If tun0 (the vpn's virtual iface) is not present, then killall sleep. However, this would only work for Scenario 2. It would be nice to figure out a solution that works for both Scenario 2 and 3.

grail 09-13-2011 08:41 PM

I am not sure I understand the issue exactly? We are not suggesting that just by using the commands it will indicate
access but rather what you get back information wise will indicate what you are looking for. So if you dig on port 443,
which if I understand correctly is the only open port your iptables entry is allowing, then you can test the
connection. Am I on the right idea here??

Mouse750 09-13-2011 08:51 PM

The target machine this script is destined for does not come with dig. It is available for install but it would be nice to share this script in the future. I do have wget and nc but I don't think those are going to help.

grail 09-14-2011 02:35 AM

I am not overly familiar with nc but it's man page seems to have a number of port options?

Mouse750 09-14-2011 11:07 AM

I don't think It wouldn't matter, If the nc, wget, or (insert whatever program), request is made by my router , then it will pass through the INPUT chain.

On the other hand, the traffic that gets forced through the tun0 (port 443) are Desktops, Laptops, Xboxs, netbooks, PS3s, ect, and that traffic is forced through the vpn tunnel. This all occurs in the FORWARD chain which I have rules written for.

It's also more than possible I am not understanding the situation correctly.

I'm thinking I should give up on this idea and try monitoring the tun0 iface, if it is not present then I can killall sleep which will start the loop again and connect to a different server.

TimothyEBaldwin 09-17-2011 09:37 AM

iptables on it's own can not control routing, it can block, modify or mark packets before routing them. If you altered your iptables rules appropriately the ping test will work.

If you are using OpenVPN's redirect-gateway option to default route is altered to point though the VPN.

OpenVPN can pick random VPN servers and re-connect on failure by itself. How is it possible to connect to a VPN server which doesn't have internet access whilst be able to connect to a server that does?

Mouse750 09-17-2011 11:39 AM

Quote:

Originally Posted by TimothyEBaldwin (Post 4474445)
OpenVPN can pick random VPN servers and re-connect on failure by itself. How is it possible to connect to a VPN server which doesn't have internet access whilst be able to connect to a server that does?

Maybe I should not have used the term "no Internet access". I just meant when I block everything but port 443 (the port openvpn connects to the vpn servers on) on eth1 forward chain and leave tun0 unrestricted (on the routers' iptable), it gives the desired effect of no Internet access when the tun0 is down. And by no Internet access what I really mean is that web browsers and torrent clients do not work (unless by chance they are using 443). So if for example, I see that my web browser is getting web page not found I know to ssh into my router and re-start openvpn. What I was trying to do was to write something that would detect this behavior and automatically re-start openvpn with a new vpn server.

Quote:

iptables on it's own can not control routing, it can block, modify or mark packets before routing them. If you altered your iptables rules appropriately the ping test will work.
Yes I realize this. I should have used the term filter not force. I just meant I was able to track down the appropriate place in the forward chain to add my 443 rule but got stumped when trying to do the same for the input chain. When ssh'd in and wget'ing a large file I can see the MB's in input state RELATED,ESTABLISHED rule increasing in size but gave up on trying to find the right place to add another 443 rule.

Quote:

OpenVPN can pick random VPN servers and re-connect on failure by itself.
what is the command to do this?

Code:

openvpn --config random *.ovpn # Sorry this was my crazy guess
I read the manual but I don't see how to do this. I have a bunch of *.ovpn config files each with the vpn servers ip address inside them.


All times are GMT -5. The time now is 01:16 PM.