1

I use Ubuntu server as NAT router. WAN interface is eth1 and LAN interface is eth0. I use ucarp virtual ip on LAN side for failover. I am writing a script which will bring down LAN interface eth0 if WAN link or default gateway goes down (If LAN interface goes down, then ucarp can release the NAT gateway ip to another router on the network). Also if the WAN ip gets pinged then LAN interface should come up and should remain up until WAN ip can be pinged.

Bash Script:

#!/bin/bash
t1=$(ifconfig | grep -o eth0)
t2="eth0"
#RMT_IP = "8.8.8.8"
SLEEP_TIME="10"

ping -c 2 8.8.8.8 > /dev/null
   PING_1=$?

if [ $PING_1 = 1 ]; then
    if [ "$t1" != "$t2" ]; then
        ifconfig eth0 up
        echo "Iface brought up"
    else
        echo "Iface is already up"
    fi
else
    if [ "$t1" = "$t2" ]; then
        ifconfig eth0 down
        echo "Iface brought down"
    else
        echo "iface already down"
    fi
fi

sleep $SLEEP_TIME

The script does not work for me. What I want is, if a WAN ip can be pinged then the LAN interface eth0 should remain up. If the WAN ip cannot be pinged, then the interface should be brought down. The script should run on loop every 10 seconds. If the WAN ip cannot be pinged for extended period of time then eth0 should remain down only and if the WAN ip gets pinged after some time then eth0 should be brought up. I also plan to run the script on boot up as an upstart job.

EDIT 1: My final script:

#!/bin/bash

timeout=5         # delay between checks
pingip='8.8.8.8'   # what to ping
iface="eth0"
LOG_FILE="/var/log/syslog"
isdown=0            # indicate whether the interface is up or down
                   # start assuming interface is up

while true; do
    LOG_TIME=`date +%b' '%d' '%T`
    if ping -q -c 2 "$pingip" >> /dev/null ; then      # ping is good - bring iface up
        if [ "$isdown" -ne 0 ] ; then
            ifup $iface && isdown=0
            printf "$LOG_TIME $0: Interface brought up: %s\n" "$iface" | tee -a $LOG_FILE
        fi
    else                                 # ping is bad - bring iface down
        beep -f 4000
        if [ "$isdown" -ne 1 ] ;  then
            ifdown $iface && isdown=1
            printf "$LOG_TIME $0: Interface brought down: %s\n" "$iface" | tee -a $LOG_FILE
        fi
    fi
    sleep "$timeout"
done
1
  • 1
    you can use logger to log to syslog, like logger -t ifup "bringing iface $iface up" which will automatically convert the message to the syslog format. You should also quote your vars (iface LOG_FILE) and dont use variables inside printf strings, use them as parameteres, like printf "time is %s\n" "$time". Also, capital variables are by convension used by the environment, you should use lower case ones. Lastly, this should work fine with sh, you don't need #!/bin/bash, just #!/bin/sh Commented May 5, 2012 at 15:10

1 Answer 1

3

try this one
if ping succeeds then bring $iface up
if ping fails then bring $iface down

#!/bin/bash

timeout=3               # delay between checks
iface="eth0"            # which interface to bring up/down
pingip='8.8.8.8'        # what to ping
isdown=-1               # indicate whether the interface is up(0) or down(1)
                        # start in unknown state

while true; do
    if ping -q -c 2 "$pingip"; then       # if ping is succeeds bring iface up
        if [ "$isdown" -ne 0 ]; then      # if not already up
            ifconfig "$iface" up && isdown=0
            printf ":: iface brought up: %s\n" "$iface"
        fi
    elif [ "$isdown" -ne 1 ]; then        # if ping failed, bring iface down, if not already down
        ifconfig "$iface" down && isdown=1
        printf ":: iface brought down: %s\n" "$iface"
    fi
    sleep "$timeout"
done
Sign up to request clarification or add additional context in comments.

8 Comments

If the interface is already up, and after 10 seconds the scripts again executes the code to bring up the interface, then wouldn't that affect the performance? But if the same line is executed again again, it doesn't show an error though.
as I dont know of a direct way to check if the iface is up, to find out if it is, I'd have to use something like ifconfig | grep eth0 which actually is much worse, cause 1. it calls ifconfig either way, 2. the pipe spawns a subshell, and that means the environment has to be loaded again, and 3. loads and executes grep, all that to decide if eth0 is up, and if not re-execut ifconfig to bring it up. So, no, I dont think it's worth it.
alright, I introduced isdown var, that gets the value 1 (true) when the interface is down. so ifconfig up is executed only when isdown is set. ifup and ifdown are not standard. I dont have them in my system. Use them if you like, but dont expect your script to be working elsewhere then. Keep that in mind ;)
done, will invoke ifconfig down (or ifdown) only if interface is not down already. by default it is assumed that the interface is down. to change that change the initial value of isdown on the top (and fix the comment appropriately)
that's because of #!/bin/sh and not using a bash shebang, ((..)) is bash syntax. I will alter that, so that it's sh/POSIX compatible. Also some small fixtures ;)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.