• Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Search
  • Register
  • Login
Netgate Discussion Forum
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Search
  • Register
  • Login

How to test if a gateway is online from a bash script? (Script Included)

Scheduled Pinned Locked Moved OpenVPN
13 Posts 6 Posters 1.7k Views
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G
    guardian Rebel Alliance
    last edited by guardian Mar 8, 2020, 11:15 PM Mar 3, 2020, 7:03 AM

    Can someone please tell me how I can test if a VPN gateway is online and has connectivity from a bash script?

    I tried:

    [2.4.4-RELEASE][root@pfsense]/root: ping -c 3 -I ovpnc1 8.8.8.8
    ping: invalid multicast interface: `ovpnc1'
    

    which didn't work, so just as a test I also tried to ping on the main WAN gateway interface:

    [2.4.4-RELEASE][root@pfsense]/root: ping -c 3 -I em0 8.8.8.8
    ping: invalid multicast interface: `em0'
    

    and that didn't work either. (see relevent ifconfig output for those interfaces)

    What I'm missing? (My plan is to test $? from the ping command.)

    [2.4.4-RELEASE][root@pfsense]/root: ifconfig
    em0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
    options=219b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,TSO4,WOL_MAGIC>
    	ether 00:28:1a:e0:10:04
    	hwaddr 00:28:1a:e0:10:04
    	inet6 fe80::228:1aff:fee0:1004%em0 prefixlen 64 scopeid 0x1 
    	inet 99.254.36.133 netmask 0xfffffe00 broadcast 255.255.255.255 
    	nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
    	media: Ethernet autoselect (1000baseT <full-duplex>)
    	status: active
    
    ovpnc1: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1500
    	options=80000<LINKSTATE>
    	inet6 fe80::228:1aff:fee0:1004%ovpnc1 prefixlen 64 scopeid 0x28 
    	inet 10.62.10.6 --> 10.62.10.5 netmask 0xffffffff 
    	nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
    	groups: tun openvpn 
    	Opened by PID 96995
    
    

    If you find my post useful, please give it a thumbs up!
    pfSense 2.7.2-RELEASE

    J 1 Reply Last reply Mar 6, 2020, 11:55 AM Reply Quote 0
    • H
      heper
      last edited by Mar 3, 2020, 7:47 AM

      parse this

      root@pfsense.lan]/root: pfSsh.php playback gatewaystatus
      
      G 1 Reply Last reply Mar 3, 2020, 11:39 AM Reply Quote 1
      • G
        guardian Rebel Alliance @heper
        last edited by Mar 3, 2020, 11:39 AM

        Thanks @heper -- I guess that could work. BTW, are these calls documented somewhere?

        Is there any way I can directly communicate through the VPN interface?

        @heper said in How to test if a gateway is online from a bash script?:

        parse this

        root@pfsense.lan]/root: pfSsh.php playback gatewaystatus
        

        If you find my post useful, please give it a thumbs up!
        pfSense 2.7.2-RELEASE

        G 1 Reply Last reply Apr 24, 2020, 9:50 PM Reply Quote 0
        • R
          Rico LAYER 8 Rebel Alliance
          last edited by Mar 3, 2020, 12:11 PM

          From the FreeBSD manpage:

               -I interface
          	     Source multicast packets with the given interface address.  This
          	     flag only applies if the ping destination is a multicast address.
          

          Try -S instead with your Interface address.

          -Rico

          G 1 Reply Last reply Mar 6, 2020, 7:44 AM Reply Quote 1
          • G
            guardian Rebel Alliance @Rico
            last edited by guardian Mar 6, 2020, 7:45 AM Mar 6, 2020, 7:44 AM

            @Rico said in How to test if a gateway is online from a bash script?:

            From the FreeBSD manpage:

                 -I interface
            	     Source multicast packets with the given interface address.  This
            	     flag only applies if the ping destination is a multicast address.
            

            Try -S instead with your Interface address.

            -Rico

            Thanks @Rico that worked.... only problem is that it turns out that ICMP is firewalled off on the VPN.

            So I tred to do something with curl, and I'm wondering why this doesn't work:

            ovpnc1: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1500
            	options=80000<LINKSTATE>
            	inet6 fe80::228:1aff:fee0:1004%ovpnc1 prefixlen 64 scopeid 0x28 
            	inet 10.62.10.6 --> 10.62.10.5 netmask 0xffffffff 
            	nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
            	groups: tun openvpn 
            	Opened by PID 96995
            
            
            curl -v -4 --interface 10.62.10.6 http://google.com
            * Expire in 0 ms for 6 (transfer 0x803a94000)
            * Expire in 1 ms for 1 (transfer 0x803a94000)
              [Similar lines removed]
            * Expire in 0 ms for 1 (transfer 0x803a94000)
            * Expire in 0 ms for 1 (transfer 0x803a94000)
            *   Trying 172.217.1.174...
            * TCP_NODELAY set
            * Name '10.62.10.6' family 2 resolved to '10.62.10.6' family 2
            * Local port: 0
            * Expire in 200 ms for 4 (transfer 0x803a94000)
            * connect to 172.217.1.174 port 80 failed: Operation timed out
            * Failed to connect to google.com port 80: Operation timed out
            * Closing connection 0
            curl: (7) Failed to connect to google.com port 80: Operation timed out
            
            
             curl -v -4 --interface 10.62.10.5 http://google.com
            * Expire in 0 ms for 6 (transfer 0x803a94000)
            * Expire in 1 ms for 1 (transfer 0x803a94000)
              [Similar lines removed]
            * Expire in 50 ms for 1 (transfer 0x803a94000)
            *   Trying 172.217.1.174...
            * TCP_NODELAY set
            * Name '10.62.10.5' family 2 resolved to '10.62.10.5' family 2
            * bind failed with errno 49: Can't assign requested address
            * Closing connection 0
            curl: (45) bind failed with errno 49: Can't assign requested address
            

            The curl statement does work when I don't specify an interface:

            curl -v -4  http://google.com
            * Expire in 0 ms for 6 (transfer 0x803a94000)
            * Expire in 1 ms for 1 (transfer 0x803a94000)
              [Similar lines removed]
            * Expire in 200 ms for 1 (transfer 0x803a94000)
            * Expire in 200 ms for 1 (transfer 0x803a94000)
            *   Trying 172.217.1.174...
            * TCP_NODELAY set
            * Expire in 200 ms for 4 (transfer 0x803a94000)
            * Connected to google.com (172.217.1.174) port 80 (#0)
            > GET / HTTP/1.1
            > Host: google.com
            > User-Agent: curl/7.64.0
            > Accept: */*
            > 
            < HTTP/1.1 301 Moved Permanently
            < Location: http://www.google.com/
            < Content-Type: text/html; charset=UTF-8
            < Date: Fri, 06 Mar 2020 07:39:36 GMT
            < Expires: Sun, 05 Apr 2020 07:39:36 GMT
            < Cache-Control: public, max-age=2592000
            < Server: gws
            < Content-Length: 219
            < X-XSS-Protection: 0
            < X-Frame-Options: SAMEORIGIN
            < 
            <HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
            <TITLE>301 Moved</TITLE></HEAD><BODY>
            <H1>301 Moved</H1>
            The document has moved
            <A HREF="http://www.google.com/">here</A>.
            </BODY></HTML>
            * Connection #0 to host google.com left intact
            [2.4.4-RELEASE][root@guardian.pvt]/root: 
            

            Alternatively is there any other way I might route out the OpenVPN interface to test connectivity to a site that is very unlikely to be down, and hence a reliable way to determine if the interface is working.

            If you find my post useful, please give it a thumbs up!
            pfSense 2.7.2-RELEASE

            1 Reply Last reply Reply Quote 0
            • J
              JKnott @guardian
              last edited by Mar 6, 2020, 11:55 AM

              @guardian

              Here's a script I wrote a few years ago. It's for bash on LInux, but it should work with FreeBSD.

              #! /bin/sh
              while [ 1 ]
              do
              ping <destination> -4 -c 1 || date >> ~/log;sleep 50
              done

              Replace <destination> with the gateway address and you will have a log file of when it failed. You can adjust the sleep time to taste.

              PfSense running on Qotom mini PC
              i5 CPU, 4 GB memory, 32 GB SSD & 4 Intel Gb Ethernet ports.
              UniFi AC-Lite access point

              I haven't lost my mind. It's around here...somewhere...

              G 1 Reply Last reply Mar 6, 2020, 8:02 PM Reply Quote 0
              • G
                guardian Rebel Alliance @JKnott
                last edited by Mar 6, 2020, 8:02 PM

                @JKnott said in How to test if a gateway is online from a bash script?:

                @guardian

                Here's a script I wrote a few years ago. It's for bash on LInux, but it should work with FreeBSD.

                #! /bin/sh
                while [ 1 ]
                do
                ping <destination> -4 -c 1 || date >> ~/log;sleep 50
                done

                Replace <destination> with the gateway address and you will have a log file of when it failed. You can adjust the sleep time to taste.

                @JKnott unfortunately that won't work... a couple of problmes

                • FreeBSD doesn't have a -4 option (I wish FreeBSD would get their utilities on par with GNU linux)
                • The ping doesn't route through the OpenVPN interface. AFAICR connectivity can go down but the interface address doesn't disappear
                • ping -S does work, but on testing it, I found out that the VPN Tunnel firewall blocks ICMP, so I can't use ping at all.

                Since ping is blocked, I need to use something like curl (not attached to curl) that uses a common protocol to a site like google.

                I tried

                curl --interface ovpnc1 http://ifconfig.me
                and
                curl --interface 10.62.10.6 http://ifconfig.me
                

                and neither of them worked - the connection timed out., but once I removed --interface the command:

                curl  http://ifconfig.me
                

                correctly returns the IP address of the main WAN interface. How can I make curl use the VPN?

                Alternatively this dig command looks interesting as well, but I can't route it through the VPN.

                dig TXT +short o-o.myaddr.l.google.com @ns1.google.com
                

                Th above command correctly returns the main WAN IP address, but this command:

                dig -b10.62.10.5 TXT +short o-o.myaddr.l.google.com @ns1.google.com
                dig: isc_socket_bind: address not available
                

                fails as shown.

                Any suggestions would be much appreciated.

                If you find my post useful, please give it a thumbs up!
                pfSense 2.7.2-RELEASE

                J 1 Reply Last reply Mar 6, 2020, 9:01 PM Reply Quote 0
                • J
                  JKnott @guardian
                  last edited by Mar 6, 2020, 9:01 PM

                  @guardian said in How to test if a gateway is online from a bash script?:

                  FreeBSD doesn't have a -4 option

                  All that does is force IPv4, when a host name returns both IPv4 and IPv6 addresses. If you specify an actual IPv4 address, rather than host name, IPv4 will be used. You used. 8.8.8.8, so the -4 option is irrelevant.

                  PfSense running on Qotom mini PC
                  i5 CPU, 4 GB memory, 32 GB SSD & 4 Intel Gb Ethernet ports.
                  UniFi AC-Lite access point

                  I haven't lost my mind. It's around here...somewhere...

                  1 Reply Last reply Reply Quote 0
                  • DerelictD
                    Derelict LAYER 8 Netgate
                    last edited by Mar 7, 2020, 2:35 AM

                    @guardian said in How to test if a gateway is online from a bash script?:

                    I wish FreeBSD would get their utilities on par with GNU linux

                    There is zero reason for ping -4 on FreeBSD since there is ping and ping6

                    Chattanooga, Tennessee, USA
                    A comprehensive network diagram is worth 10,000 words and 15 conference calls.
                    DO NOT set a source address/port in a port forward or firewall rule unless you KNOW you need it!
                    Do Not Chat For Help! NO_WAN_EGRESS(TM)

                    J G 2 Replies Last reply Mar 7, 2020, 3:31 AM Reply Quote 1
                    • J
                      JKnott @Derelict
                      last edited by Mar 7, 2020, 3:31 AM

                      @Derelict said in How to test if a gateway is online from a bash script?:

                      There is zero reason for ping -4 on FreeBSD since there is ping and ping6

                      Linux used to work that way. Now, ping works with both IPv4 and IPv6. If both addresses are returned for a host name, it prefers IPv6. However, there is still a ping6 command, which is linked to ping.

                      PfSense running on Qotom mini PC
                      i5 CPU, 4 GB memory, 32 GB SSD & 4 Intel Gb Ethernet ports.
                      UniFi AC-Lite access point

                      I haven't lost my mind. It's around here...somewhere...

                      1 Reply Last reply Reply Quote 1
                      • hectorspcH
                        hectorspc
                        last edited by Mar 7, 2020, 11:47 AM

                        This is for tcsh but I understand that should be very similar and easy to apply to bash

                        #!/bin/tcsh
                        set gw = `/usr/local/bin/php /usr/local/sbin/pfSsh.php playback gatewaystatus | grep WAN `
                        set gwping = `echo $gw | awk '{ ORS="  "; print $6 }' `
                        set gwstatus = `echo $gw | awk '{ ORS="  "; print $7 }' `
                        
                        1 Reply Last reply Reply Quote 1
                        • G
                          guardian Rebel Alliance @Derelict
                          last edited by guardian Mar 8, 2020, 11:14 PM Mar 8, 2020, 11:13 PM

                          @Derelict said in How to test if a gateway is online from a bash script?:

                          @guardian said in How to test if a gateway is online from a bash script?:

                          I wish FreeBSD would get their utilities on par with GNU linux

                          There is zero reason for ping -4 on FreeBSD since there is ping and ping6

                          @JKnott said in How to test if a gateway is online from a bash script?:

                          @Derelict said in How to test if a gateway is online from a bash script?:

                          There is zero reason for ping -4 on FreeBSD since there is ping and ping6

                          Linux used to work that way. Now, ping works with both IPv4 and IPv6. If both addresses are returned for a host name, it prefers IPv6. However, there is still a ping6 command, which is linked to ping.

                          @JKnott @Derelict Thanks very much for this - I'm struggling with FreeBSD, after 2 years, I'm just beginning to get comfotable with Linux

                          @hectorspc said in How to test if a gateway is online from a bash script?:

                          This is for tcsh but I understand that should be very similar and easy to apply to bash

                          #!/bin/tcsh
                          set gw = `/usr/local/bin/php /usr/local/sbin/pfSsh.php playback gatewaystatus | grep WAN `
                          set gwping = `echo $gw | awk '{ ORS="  "; print $6 }' `
                          set gwstatus = `echo $gw | awk '{ ORS="  "; print $7 }' `
                          

                          @hectorspc - I decided to just use the gateway status.

                          For the benefit of anyone who may wish to do something similar, here's the script I came up with;
                          (Code review's welcome - goal was clarity/ease if maintenace/self-documenting not conciseness)

                          #!/bin/sh 
                          #
                          # restartvpn: Restart the OpenVPN client if it is down.  The restart is supressed
                          #             if the WAN is down.
                          #
                          #   -f / -F : Force: Force reset even if VPN is not down
                          #   -q / -Q : Quiet: Supress printed output
                          #
                          
                          WAN_ID='WAN_DHCP'                    # WAN Gateway ID String
                          VPN_IDs='VPN_UDP_TOS_VPNV4'          # VPN Gateway ID Strings (Separate with a space)
                          VPN_GWs='1'                          # VPN Client ID of gateway
                          GW_DOWN='down'                       # Gateway down status string
                          
                          # -q / -Q : Quiet: Supress printed output
                          silent=$(echo $@- | awk '{print (/-[qQ]/ ? 1 : 0)}')
                          
                          # -f / -F : Force: Force reset even if VPN is not down
                          force=$(echo $@ | awk '{print (/-[fF]/ ? 1 : 0)}')
                          
                          restartvpn(){
                             #
                             #  Restart VPN client $VPN_GW  
                             #
                             WD=$([ "$WAN_STAT" = "$GW_DOWN" ] && echo "WAN DOWN:" || echo "")
                             FC=$([ $force -eq 1 ] && echo "FORCED:" || echo "")
                             echo $(date +%y/%m/%d-%H:%M:%S-)${ID}-${WD}${FC}$(/usr/local/sbin/pfSsh.php playback svc restart openvpn client $VPN_GW)
                          }
                          
                          gwstat=$(pfSsh.php playback gatewaystatus)
                          WAN_STAT=$(echo "$gwstat" | awk '/'$WAN_ID'/{print $NF}')
                          PUBLIC_IP=$(echo "$gwstat" | awk '/'$WAN_ID'/{print $3}')
                          
                          if [ $silent -eq 0 ];then 
                             echo -e "$(basename $0) - Public IP: $PUBLIC_IP - $(date)\n\n$gwstat\n"
                          fi
                          
                          if [ "$WAN_STAT" = "$GW_DOWN" -a $force -eq 0 ];then
                             echo "$(date +%y/%m/%d-%H:%M:%S-)WAN is down-VPN restart not attempted."
                             return 1
                          fi
                          
                          gw=1
                          for ID in $VPN_IDs;do
                             VPN_STAT=$(echo "$gwstat" | awk '/'$ID'/{print $NF}')
                             VPN_GW=$(echo $VPN_GWs|cut -w -f $gw)
                             if [ -n "$VPN_STAT" ];then
                                [ $silent -eq 0 ] && echo VPN Gateway: $ID - $([ "$VPN_STAT" = "$GW_DOWN" ] && echo "DOWN" || echo "UP") 
                                 if [ "$VPN_STAT" = "$GW_DOWN" -o $force -eq 1 ];then
                                   restartvpn
                                   return 1
                                 fi
                             else
                                [ $silent -eq 0 ] && echo No active gateway $ID
                             fi
                          gw=gw+1
                          done
                          

                          When run from the command line the output looks like this:

                          # restartvpn 
                          restartvpn - Public IP: 99.254.36.133 - Sun Mar  8 17:15:45 EDT 2020
                          
                          Name               Monitor  Source              Delay    StdDev  Loss  Status
                          VPN_UDP_TOS_VPNV4  8.8.4.4  10.12.11.6       29.443ms  10.624ms   27%    down
                          WAN_DHCP           8.8.8.8  99.254.36.133    11.329ms   6.142ms  0.0%    none
                          
                          VPN Gateway: VPN_UDP_TOS_VPNV4 - DOWN
                          20/03/08-17:15:45-VPN_UDP_TOS_VPNV4-Attempting to issue restart to openvpn service... openvpn has been restarted.
                          

                          I have set it up to run as a cron job:

                          */3	*	*	*	*	root	/root/bin/restartvpn -q
                          

                          Hopefully someone will find this helpful.

                          If you find my post useful, please give it a thumbs up!
                          pfSense 2.7.2-RELEASE

                          1 Reply Last reply Reply Quote 0
                          • G
                            guardian Rebel Alliance @guardian
                            last edited by guardian Apr 24, 2020, 9:54 PM Apr 24, 2020, 9:50 PM

                            Many thanks to all who provided assistance. Here is the finished script for anyone who may want to use/adapt it. If anyone wants to review/ provide suggestions or sees that I've done anything that could cause issues, please feel free to do so.

                            #!/bin/sh 
                            #
                            # restartvpn: Restart the OpenVPN client if it is down.  The restart is supressed
                            #             if the WAN is down.
                            #
                            #   -f / -F : Force: Force reset even if VPN is not down
                            #   -q / -Q : Quiet: Supress printed output
                            #
                            
                            WAN_ID='WAN_DHCP'                    # WAN Gateway ID String
                            VPN_IDs='XXXXX_VPNV4'                # VPN Gateway ID Strings (Separate with a space)
                            VPN_GWs='1'                          # VPN Client ID of gateway
                            GW_DOWN='down'                       # Gateway down status string
                            
                            # -q / -Q : Quiet: Supress printed output
                            silent=$(echo $@- | awk '{print (/-[qQ]/ ? 1 : 0)}')
                            
                            # -f / -F : Force: Force reset even if VPN is not down
                            force=$(echo $@ | awk '{print (/-[fF]/ ? 1 : 0)}')
                            
                            restartvpn(){
                               #
                               #  Restart VPN client $VPN_GW
                               #
                               WD=$([ "$WAN_STAT" = "$GW_DOWN" ] && echo "WAN DOWN:" || echo "")
                               FC=$([ $force -eq 1 ] && echo "FORCED:" || echo "")
                               msg=$(echo $(date +%y/%m/%d-%H:%M:%S-)${ID}-${WD}${FC}$(/usr/local/sbin/pfSsh.php playback svc restart openvpn client $VPN_GW))
                               [ $silent -eq 0 ] && echo $msg
                               logger "***** ${msg}"
                            }
                            
                            gwstat=$(pfSsh.php playback gatewaystatus)
                            WAN_STAT=$(echo "$gwstat" | awk '/'$WAN_ID'/{print $NF}')
                            PUBLIC_IP=$(echo "$gwstat" | awk '/'$WAN_ID'/{print $3}')
                            
                            if [ $silent -eq 0 ];then
                               echo -e "$(basename $0) - Public IP: $PUBLIC_IP - $(date)\n\n$gwstat\n"
                            fi
                            
                            if [ "$WAN_STAT" = "$GW_DOWN" -a $force -eq 0 ];then
                               msg=$(echo "$(date +%y/%m/%d-%H:%M:%S-)WAN is down-VPN restart not attempted.")
                               [ $silent -eq 0 ] && echo $msg
                               logger "***** ${msg}"
                               return 1
                            fi
                            
                            gw=1
                            for ID in $VPN_IDs;do
                               VPN_STAT=$(echo "$gwstat" | awk '/'$ID'/{print $NF}')
                               VPN_GW=$(echo $VPN_GWs|cut -w -f $gw)
                               if [ -n "$VPN_STAT" ];then
                                  [ $silent -eq 0 ] && echo VPN Gateway: $ID - $([ "$VPN_STAT" = "$GW_DOWN" ] && echo "DOWN" || echo "UP")
                                   if [ "$VPN_STAT" = "$GW_DOWN" -o $force -eq 1 ];then
                                     restartvpn
                                     return 1
                                   fi
                               else
                                  [ $silent -eq 0 ] && echo No active gateway $ID
                               fi
                            gw=gw+1
                            done
                            

                            If you find my post useful, please give it a thumbs up!
                            pfSense 2.7.2-RELEASE

                            1 Reply Last reply Reply Quote 1
                            • First post
                              Last post
                            Copyright 2025 Rubicon Communications LLC (Netgate). All rights reserved.
                              [[user:consent.lead]]
                              [[user:consent.not_received]]