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.8k 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 @heper
      last edited by

      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 Reply Quote 0
      • 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.