• 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.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.
  • 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.
                        This community forum collects and processes your personal information.
                        consent.not_received