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.
    • RicoR
      Rico LAYER 8 Rebel Alliance
      last edited by

      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 Reply Quote 1
      • G
        guardian Rebel Alliance @Rico
        last edited by guardian

        @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
        • JKnottJ
          JKnott @guardian
          last edited by

          @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 Reply Quote 0
          • G
            guardian Rebel Alliance @JKnott
            last edited by

            @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

            JKnottJ 1 Reply Last reply Reply Quote 0
            • JKnottJ
              JKnott @guardian
              last edited by

              @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

                @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)

                JKnottJ G 2 Replies Last reply Reply Quote 1
                • JKnottJ
                  JKnott @Derelict
                  last edited by

                  @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

                    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

                      @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

                        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.