File: adsl-failover

package info (click to toggle)
arno-iptables-firewall 2.0.1.c-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 1,348 kB
  • sloc: sh: 5,991; makefile: 18
file content (161 lines) | stat: -rwxr-xr-x 6,959 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/bin/bash

# This script was written by Mark Cleverdon 22/11/2007 under the GPL license
# email: mark at lanzarote1.com
#
# For automatic Failover from the main external network provider on failure
# to a dialup modem or UMTS modem connection. 
#
# REQUREMENTS
# You must have IP forwarding enabled in the system.
# ADSL connection with a static IP
# wvdial must be installed and setup with a script that works for your service provider.
# A firewall like arnos iptables firewall script or shorewall etc
#
# You can set this script in the system cron to check the connection at regular time intervals.
#
# METHODS USED IN THIS SCRIPT
# We have both eth1 and ppp0 as external interfaces in iptables, if both were functioning at the same time
# we would have load balancing (which could get expensive), but here we only need one active connection so
# all we need to do is to adjust the dynamic IP address of the dialup connection in the firwall when there
# is a problem in order to allow routing through the dialup device. Once the emergency is over we can can-
# cel the dialup connection and the original routing will continue as usual with no need to adjust
# the firewall again. When a new failure happens then the new IP address is assigned to the second external
# interface (normally ppp0) and the firewall restarted to allow routing.
#
# PARAMETERS HERE
# The normal external interface (DSL or cable etc)
interface="eth1"
normal_ext_ip="XXX.XXX.XXX.XXX"
# Admin email address for failover notification
admin_email="admin@your-domain"
# The dialup device PCMCIA UMTS card or regular modem will normally be a ttyS0/1/2/3 etc
# But here you need the device that wvdial returns which is generally ppp0
dialup_if="ppp0"
# Full path and name of your firewall script I use Arnos iptables firewall
firewall="/etc/arno-iptables-firewall.conf"
# The /etc/init.d/firewall-script that your system uses to restart the firewall
firestarter="/etc/init.d/arno-iptables-firewall"
# WARNING if you are not using arnos firewall script you will need to edit the sed commands parameters below
# eg. on line 111 of this script  
# sed 's/\(search string just before substitution \)[0-9]*.[0-9]*.[0-9]*.[0-9]*/\1'$OUT_IP'/g' $firewall
#
# The wvdial command for dialup (you must set this up previously) 
# eg. this would be like "myserver:#/wvdial internet" on the command line
connection="internet"
# The following are the ip address of any reliable public server ie. google.com
# if all three servers fail then the dialup connection will be started.
# But beware of ping_server1, it must be the most reliable of the three because 
# it is used in further tests on its own.
# Further, note it is important to use IP addresses and not domain names because if
# your system is totally isolated you will not be able to do name resolution. 
ping_server1="64.233.167.99"
ping_server2="216.109.112.135"
ping_server3="66.45.254.244"

route add $ping_server1 gw $normal_ext_ip
if (ping -w 5 -nq -I $interface $ping_server1 |grep '100%\ packet\ loss' 2>&1>/dev/null) then
	SERVER1="DOWN"
else 
	SERVER1="UP"
fi
route del $ping_server1
route add $ping_server2 gw $normal_ext_ip
if (ping -w 5 -nq -I $interface $ping_server2 |grep '100%\ packet\ loss' 2>&1>/dev/null) then
	SERVER2="DOWN"
else
	SERVER2="UP"
fi
route del $ping_server2
route add $ping_server3 gw $normal_ext_ip
if (ping -w 5 -nq -I $interface $ping_server3 |grep '100%\ packet\ loss' 2>&1>/dev/null) then
	SERVER3="DOWN"
else
	SERVER3="UP"
fi
route del $ping_server3


if [ "$SERVER1" = "DOWN" ] && [ "$SERVER2" = "DOWN" ] && [  "$SERVER3" = "DOWN" ] 
	then
	echo "WARNING! -- We have an internet connection problem. I will attempt to discover the situation and fix it."
	if [[ "$interface"="eth1" ]] 
		then
		echo .
		# Check to see if we have any connection at all (if not we dial)
		if (ping -w 5 -nq $ping_server1|grep '100%\ packet\ loss' 2>&1>/dev/null) 
			then
			# Check for existing wvdial processes that may be hungup
			if (ps ax|grep wvdial) 
				then
				echo "finishing any previous hung connection"
				killall wvdial
				sleep 15
			fi
			echo .
			echo "Dialing out ...."
			wvdial $connection &
			sleep 25
			if (ping -w 5 -nq -I $dialup_if $ping_server1|grep -v '100%\ packet\ loss' 2>&1>/dev/null) 
				then
				# Pick up the new IP for adjusting the firewall script.
				OUT_IP=`ifconfig|grep -A 2 $dialup_if|grep inet\ addr:|sed 's/.*inet\ addr\:\([0-9]*.[0-9]*.[0-9]*.[0-9]*\).*/\1/g'`
				echo .
				echo "New public IP address is <$OUT_IP> from UMTS/dialup device $dialup."
				echo .
				echo "Restarting the Firewall routing for new connection."
				echo .
				# Make sure the original firewall script is saved (here we datestamp it just in case)
				cp -p $firewall $firewall.`date +"%d%m%Y%H%M%S"`
				sed 's/\(NAT_STATIC_IP="$normal_ext_ip \)[0-9]*.[0-9]*.[0-9]*.[0-9]*/\1'$OUT_IP'/g' $firewall >/tmp/firewall.conf
				mv /tmp/firewall.conf $firewall
				$firestarter restart
				# Get myself a copy of all this stuff for a remote firewall setup etc.
				echo "The ADSL connection has failed">/tmp/ifconfig_ppp0
				echo ".">>/tmp/ifconfig_ppp0
				echo "The new IP address is $OUT_IP">>/tmp/ifconfig_ppp0
				ifconfig $dialup_if>>/tmp/ifconfig_ppp0			
				echo $OUT_IP>/tmp/FAILOVER_IP
				mail -s "FAILOVER IP $OUT_IP" $admin_email </tmp/ifconfig_ppp0
			else
				echo "UMTS/Dialup connection has failed, I will kill it. Please try again."
				killall wvdial
			fi		
		else 
			# Failover is working 
			echo .
			echo "Failover system is already working"
			OUT_IP1=`cat /tmp/FAILOVER_IP`
			OUT_IP2=`ifconfig|grep -A 2 $dialup_if|grep inet\ addr:|sed 's/.*inet\ addr\:\([0-9]*.[0-9]*.[0-9]*.[0-9]*\).*/\1/g'`
			# Check to see if dynamic ip has changed 
			if [ "$OUT_IP1" = "$OUT_IP2" ]
				then
				echo $OUT_IP2>/tmp/FAILOVER_IP
				echo "The ADSL connection has failed">/tmp/ifconfig_ppp0
				echo ".">>/tmp/ifconfig_ppp0
				echo "The new IP address is $OUT_IP2">>/tmp/ifconfig_ppp0
				echo ".">>/tmp/ifconfig_ppp0
				ifconfig $dialup_if>>/tmp/ifconfig_ppp0			
				mail -s "NEW FAILOVER IP $OUT_IP2" $admin_email </tmp/ifconfig_ppp0			
			fi
		fi
	fi
	echo "Through DSL connection $ping_server1 is $SERVER1, $ping_server2 is $SERVER2, $ping_server3 is $SERVER3"
else
# Everything is Normal.
	# Check if Normality is recent and if so kill off all failover devices.
	if (ps ax|grep wvdial|grep -v grep) 
		then
		echo "ADSL is now OK, I will kill any UMTS/Dialup connection..."
		killall wvdial 2>&1>/dev/null
                echo "The ADSL connection is now working">/tmp/ifconfig
                echo ".">>/tmp/ifconfig
                echo "Use the original connection information to connect">>/tmp/ifconfig
                echo ".">>/tmp/ifconfig
 		mail -s "FAILOVER STOPED - ADSL OK" $admin_email </tmp/ifconfig
		echo "Through DSL connection $ping_server1 is $SERVER1, $ping_server2 is $SERVER2, $ping_server3 is $SERVER3"
		ifdown eth1
		sleep 10
		ifup eth1
	fi
fi