Projet

Général

Profil

agregation.sh

script corrigé - Karim Ayari, 17/08/2012 10:54

Télécharger (15,1 ko)

 
1
#!/bin/bash -x
2
##############################
3
# Script Agregation de lien  #
4
# Gabriel CORGNE             #
5
##############################
6

    
7
# Ajout marquage de packet pour SNAT
8
# ac-creteil.fr Olivier Sauzet - Rachid Bouhassoun
9
# le 10 Juin 2009
10

    
11
[ -e /etc/agregation.conf ] || {
12
    # Pas de fichier de configuration
13
    echo "Fichier de configuration /etc/agregation.conf non trouvé"
14
    exit 1
15
}
16
. /etc/agregation.conf
17
# Chargement de la bibliotheque Eole
18
[ -x /usr/share/eole/FonctionsEoleNg ] || {
19
        echo "Pas de bibliotheque Eole !"
20
        exit 1
21
}
22
. /usr/share/eole/FonctionsEoleNg
23
#Chargement des dicos
24
. ParseDico
25
#
26

    
27
#Initialisation des variables d'etat
28
# Dernier etat du lien
29
LLS1=1
30
LLS2=1
31
# Dernier etat du host
32
LHS1=1
33
LHS2=1
34
# Etat actuel du host
35
CHS1=1
36
CHS2=1
37
# Le lien doit changer (O:oui , 1:non)
38
CLS1=1
39
CLS2=1
40
# Nombre de changement d'etat
41
COUNT1=0
42
COUNT2=0
43
# Nombre de serveurs DNS a tester
44
ID1_C=${#DNS1[@]}
45
ID2_C=${#DNS2[@]}
46
# Nombre de mires a tester
47
IM_C=${#MIRE[@]}
48
# Calcul du coefficient pour iptables
49
if [ -n "$W1" -a -n "$W2" ];then
50
WCO=$[$[$W2*1000]/$[$W1+$W2]]
51
fi
52

    
53
# Fonction explicitant les messages d'etat
54
expl() {
55
    if [ $1 -eq 0 ];then
56
        echo "actif"
57
    else
58
        echo "inactif"
59
    fi
60
}
61

    
62
# Fonction de Log dans /var/log/agregation.log + Zephir
63
Aecho () {
64
    if [ -z "$2" ];then
65
        level="ERR"
66
    else
67
        level=$2
68
    fi
69
    DATE=`date +%Y-%m-%d_%H:%M:%S`
70
    echo "$DATE $1" >> /var/log/agregation.log
71
    [ "$level" != 'ERR' ] && echo "$1"
72
    Zephir "$level" "$1" agregation
73
}
74

    
75
#Mise à jour des routes $1=T1
76
ipruleclear () {
77
    for r in `ip rule list|grep $1|awk '{print $2"-"$3"-"$4"-"$5"-"$6"-"$7}'`
78
        do ip rule del `echo $r|sed "s/-/ /g"`
79
    done
80
}
81

    
82
#Vidage des règles iptables de SNAT
83
iptablessnatclear () {
84
	i=1
85
	while [ $i -le `/sbin/iptables -t nat -S POSTROUTING|wc -l` ]
86
	do
87
		if [ -n "`/sbin/iptables -t nat -S POSTROUTING $i|grep SNAT|grep "o eth0"`" ];then
88
			/sbin/iptables -t nat -D POSTROUTING $i
89
		else
90
			let i++
91
		fi
92
	done
93
}
94

    
95
#Vidage des règles iptables de MANGLE $1 = nom de la carte
96
iptablesmangleclear () {
97
	i=1
98
	while [ "$i" -le `/sbin/iptables -t mangle -S PREROUTING|wc -l` ]
99
	do
100
		if [ -n "`/sbin/iptables -t mangle -S PREROUTING $i|grep "i $1"`" ];then
101
			/sbin/iptables -t mangle -D PREROUTING $i
102
		else
103
			let i++
104
		fi
105
	done
106
}
107

    
108
#Definition de la repartition par interface $1 = nom de la carte
109
balance () {
110
	iptablesmangleclear $1
111
	network="$(eval echo \$adresse_network_$1)/$(eval echo \$adresse_netmask_$1)"
112
	#Si non NEW
113
	/sbin/iptables -t mangle -A PREROUTING -i $1 -s $network -m state ! --state NEW -j RESTOREMARK
114
	/sbin/iptables -t mangle -A PREROUTING -i $1 -s $network -m state ! --state NEW -j RETURN
115
	#Routes forcees
116
	for ip_force1 in ${FORCE1[@]}; do
117
		/sbin/iptables -t mangle -A PREROUTING -i $1 -s $network -d $ip_force1 -m state --state NEW -j T1
118
		/sbin/iptables -t mangle -A PREROUTING -i $1 -s $network -d $ip_force1 -m state --state NEW -j RETURN ; done
119
	for ip_force2 in ${FORCE2[@]}; do
120
		/sbin/iptables -t mangle -A PREROUTING -i $1 -s $network -d $ip_force2 -m state --state NEW -j T2
121
		/sbin/iptables -t mangle -A PREROUTING -i $1 -s $network -d $ip_force2 -m state --state NEW -j RETURN ; done
122
	#Si NEW et recent alors Tag puis RETURN
123
	/sbin/iptables -t mangle -A PREROUTING -i $1 -s $network -m state --state NEW -m recent --name T1 --update --rdest --seconds 3600 -j T1
124
	/sbin/iptables -t mangle -A PREROUTING -i $1 -s $network -m state --state NEW -m recent --name T1 --update --rdest --seconds 3600 -j RETURN
125
	/sbin/iptables -t mangle -A PREROUTING -i $1 -s $network -m state --state NEW -m recent --name T2 --update --rdest --seconds 3600 -j T2
126
	/sbin/iptables -t mangle -A PREROUTING -i $1 -s $network -m state --state NEW -m recent --name T2 --update --rdest --seconds 3600 -j RETURN
127
	#Si NEW sans recent alors Tag puis RETURN
128
	/sbin/iptables -t mangle -A PREROUTING -i $1 -s $network -m state --state NEW -j T2
129
	/sbin/iptables -t mangle -A PREROUTING -i $1 -s $network -m state --state NEW -m statistic --mode random --probability 0.$WCO -m recent --name T2 --set --rdest -j RETURN
130
	/sbin/iptables -t mangle -A PREROUTING -i $1 -s $network -m state --state NEW -m recent --name T1 --set --rdest -j T1
131
}
132
#Definition du flux par interface $1 = nom de la carte
133
wan1 () {
134
	iptablesmangleclear $1
135
	network="$(eval echo \$adresse_network_$1)/$(eval echo \$adresse_netmask_$1)"
136
	#Si non NEW
137
	/sbin/iptables -t mangle -A PREROUTING -i $1 -s $network -m state ! --state NEW -j RESTOREMARK
138
	/sbin/iptables -t mangle -A PREROUTING -i $1 -s $network -m state ! --state NEW -j RETURN
139
	#Marques sur T1
140
	/sbin/iptables -t mangle -A PREROUTING -i $1 -s $network -m state --state NEW -j T1
141
}
142
#Definition du flux par interface $1 = nom de la carte
143
wan2 () {
144
	iptablesmangleclear $1
145
	network="$(eval echo \$adresse_network_$1)/$(eval echo \$adresse_netmask_$1)"
146
	#Si non NEW
147
	/sbin/iptables -t mangle -A PREROUTING -i $1 -s $network -m state ! --state NEW -j RESTOREMARK
148
	/sbin/iptables -t mangle -A PREROUTING -i $1 -s $network -m state ! --state NEW -j RETURN
149
	#Marques sur T2
150
	/sbin/iptables -t mangle -A PREROUTING -i $1 -s $network -m state --state NEW -j T2
151
}
152
## Initialisation
153
# Large recent table
154
/sbin/modprobe ipt_recent ip_list_tot=4000
155
# Declaration des tables iproute2
156
cat > /etc/iproute2/rt_tables <<Eof
157
# reserved values
158
255	local
159
254	main
160
253	default
161
0	unspec
162
# local
163
2 T2
164
1 T1
165
Eof
166

    
167
# Vidage du cache
168
/sbin/ip route flush cache
169

    
170
# Chargement des regles de routage
171
/sbin/ip route del default
172

    
173
ipruleclear T1
174
/sbin/ip rule add from $WAN1 table T1
175
/sbin/ip route add $NET1 dev eth0 src $WAN1 table T1
176
/sbin/ip route add default via $GW1 table T1
177
/sbin/ip rule add fwmark 1 table T1
178

    
179
ipruleclear T2
180
/sbin/ip rule add from $WAN2 table T2
181
/sbin/ip route add $NET2 dev eth0 src $WAN2 table T2
182
/sbin/ip route add default via $GW2 table T2
183
/sbin/ip rule add fwmark 2 table T2
184

    
185
for ip_force1 in ${FORCE1[@]}; do /sbin/ip route add $ip_force1 via $GW1 table main ; done
186
for ip_force2 in ${FORCE2[@]}; do /sbin/ip route add $ip_force2 via $GW2 table main ; done
187

    
188
for ip_dns1 in ${DNS1[@]}; do /sbin/ip route add $ip_dns1 via $GW1 table main ; done
189
for ip_dns2 in ${DNS2[@]}; do /sbin/ip route add $ip_dns2 via $GW2 table main ; done
190

    
191
####################
192
# test mode load balancing ou fail-over (actif/passif)
193
if [ $ag_mode == "mode_lb" ] ; then
194
	/sbin/ip route delete default via $GW1 dev eth0
195
	/sbin/ip route delete default via $GW2 dev eth0
196
	/sbin/ip route add default scope global nexthop via $GW1 dev eth0 weight $W1 nexthop via $GW2 dev eth0 weight $W2
197
fi
198

    
199
if [ $ag_mode == "mode_fo" ] ;then
200
    if [ $ag_fo_etat_eth0 == "actif" ] && [ $ag_fo_etat_eth0_0 == "passif" ] ; then
201
        /sbin/ip route delete default
202
        /sbin/ip route add default via $GW1 dev eth0
203
    elif [ $ag_fo_etat_eth0 == "passif" ] && [ $ag_fo_etat_eth0_0 == "actif" ] ; then
204
        /sbin/ip route delete default
205
        /sbin/ip route add default via $GW2 dev eth0
206
    fi
207
fi
208
####################
209

    
210
# Vidage des chaines MANGLE
211
check_T1=$(iptables-save |grep "RESTOREMARK" |wc -l)
212
check_T2=$(iptables-save |grep "T2" | wc -l)
213
check_RESTOREMARK=$(iptables-save |grep "T1" |wc -l)
214
check_PREROUTING=$(iptables-save |grep "T1" |wc -l)
215
if [ "$check_PREROUTING" -gt "1" ] ; then
216
/sbin/iptables -t mangle -F PREROUTING
217
fi
218
if [ "$check_T1" -gt "1" ] ; then
219
/sbin/iptables -t mangle -F T1
220
fi
221
if [ "$check_T2" -gt "1" ] ; then
222
/sbin/iptables -t mangle -F T2
223
fi
224
if [ "$check_RESTOREMARK" -gt "1" ] ; then
225
/sbin/iptables -t mangle -F RESTOREMARK
226
fi
227

    
228
## creation de la chaine marquage pour agregation de lien
229
chaine_T1=$(iptables-save | grep ":T1")
230
if [ -z "$chaine_T1" ] ; then
231
/sbin/iptables -t mangle -N T1
232
/sbin/iptables -t mangle -A T1 -d 10.0.0.0/8 -j RETURN
233
/sbin/iptables -t mangle -A T1 -d 172.16.0.0/12 -j RETURN
234
/sbin/iptables -t mangle -A T1 -d 192.168.0.0/16 -j RETURN
235
/sbin/iptables -t mangle -A T1 -d 161.48.0.0/19 -j RETURN
236
/sbin/iptables -t mangle -A T1 -j MARK --set-mark 1
237
/sbin/iptables -t mangle -A T1 -j CONNMARK --save-mark
238
fi
239
chaine_T2=$(iptables-save | grep ":T2")
240
if [ -z "$chaine_T1" ] ; then
241
/sbin/iptables -t mangle -N T2
242
/sbin/iptables -t mangle -A T2 -d 10.0.0.0/8 -j RETURN
243
/sbin/iptables -t mangle -A T2 -d 172.16.0.0/12 -j RETURN
244
/sbin/iptables -t mangle -A T2 -d 192.168.0.0/16 -j RETURN
245
/sbin/iptables -t mangle -A T2 -d 161.48.0.0/19 -j RETURN
246
/sbin/iptables -t mangle -A T2 -j MARK --set-mark 2
247
/sbin/iptables -t mangle -A T2 -j CONNMARK --save-mark
248
fi
249
chaine_RESTOREMARK=$(iptables-save | grep ":RESTOREMARK")
250
if [ -z "$chaine_RESTOREMARK" ] ; then
251
/sbin/iptables -t mangle -N RESTOREMARK
252
/sbin/iptables -t mangle -A RESTOREMARK -d 10.0.0.0/8 -j RETURN
253
/sbin/iptables -t mangle -A RESTOREMARK -d 172.16.0.0/12 -j RETURN
254
/sbin/iptables -t mangle -A RESTOREMARK -d 192.168.0.0/16 -j RETURN
255
/sbin/iptables -t mangle -A RESTOREMARK -d 161.48.0.0/19 -j RETURN
256
/sbin/iptables -t mangle -A RESTOREMARK -j CONNMARK --restore-mark
257
fi
258

    
259
## Mise a jour des règles de SNAT
260
iptablessnatclear
261
/sbin/iptables -t nat -A POSTROUTING -o eth0 -m mark --mark 1 -j SNAT --to-source $WAN1
262
/sbin/iptables -t nat -A POSTROUTING -o eth0 -m mark --mark 2 -j SNAT --to-source $WAN2
263

    
264

    
265
# Test vers $MIRE sur le lien $L
266
Checkstate () {
267

    
268
L=$1
269
#Nombre de serveurs DNS a tester
270
#ID_C=$(eval echo \${#DNS$L[@]})
271
ID=0
272
#Nombre de mires a tester
273
#IM_C=$(eval echo \${#MIRE$L[@]})
274
IM=0
275
SUCCES=1
276
while [ $IM -lt $IM_C ] && [ $SUCCES -eq 1 ] ; do
277
	while [ "$ID" -lt $(eval echo \$ID$L\_C) ] && [ $SUCCES -eq 1 ] ; do
278
		host -W $TIMEOUT ${MIRE[$IM]} $(eval echo \${DNS$L[$ID]})> /dev/null  2>&1
279
		if [ $? -ne 0 ]; then
280
			[ $(eval echo \$LLS$L) -eq 0 ] && Aecho "Erreur de resolution de $(eval echo \${MIRE[$IM]}) sur le dns $(eval echo \${DNS$L[$ID]}) du lien $L"
281
			ID=$(( $ID + 1 ))
282
		else
283
			SUCCES=0
284
		fi
285
	done
286
	IM=$(( $IM + 1 ))
287
	ID=0
288
done
289

    
290
	if [ $SUCCES -eq 1 ]; then
291
		Aecho "Le lien $L est tombe"
292
		eval CHS$L=1
293
	else
294
		eval CHS$L=0
295
	fi
296
	if [ $(eval echo \$LHS$L) -ne $(eval echo \$CHS$L) ]; then
297
		Aecho "L'etat du lien $L a change de $(expl $(eval echo \$LHS$L)) a $(expl $(eval echo \$CHS$L))"
298
		eval COUNT$L=1
299
	else
300
		if [ $(eval echo \$LHS$L) -ne $(eval echo \$LLS$L) ]; then
301
			eval COUNT$L=$(( $(eval echo \$COUNT$L) + 1 ))
302
		fi
303
	fi
304
	if [[ $(eval echo \$COUNT$L) -ge $NBSUCCES || ($(eval echo \$LLS$L) -eq 0 && $(eval echo \$COUNT$L) -ge $NBECHECS) ]]; then
305
		Aecho "Le lien $L n'est plus $(expl $(eval echo \$LLS$L))"
306
		eval CLS$L=0
307
		eval COUNT$L=0
308
		if [ $(eval echo \$LLS$L) -eq "1" ]; then
309
			eval LLS$L=0
310
		else
311
			eval LLS$L=1
312
		fi
313
	else
314
		eval CLS$L=1
315
	fi
316

    
317
	eval LHS$L=$(eval echo \$CHS$L)
318
}
319

    
320

    
321
# Log du démarrage
322
Aecho "Initialisation de l'agregation de liens" 'MSG'
323

    
324
while : ; do
325
	Checkstate 1
326
	Checkstate 2
327

    
328
    if [[ $CLS1 -eq 0 || $CLS2 -eq 0 ]]; then
329

    
330
        if [[ $LLS1 -eq 1 && $LLS2 -eq 0 ]]; then
331

    
332
			Aecho "Seul le lien 2 est actif, redirection des flux sur ce lien"
333

    
334
            if [ "$ag_active_mail" == "oui" ] ; then
335
				MssG="Seul le lien 2 est actif, redirection des flux sur ce lien"
336
				SubJ="Liaison $nom_domaine_local_supp  ($numero_etab)"
337
                if [ -z "${CC[@]}" ] ; then
338
                    echo "$MssG"|mutt -s "$SubJ" "$DEST"
339
                else
340
                    echo "$MssG"|mutt -s "$SubJ" "$DEST" -c "${CC[@]}"
341
                fi
342
	        fi
343

    
344
                # Iproute2 sur le lien2
345
	                /sbin/ip route replace default via $GW2 dev eth0
346
				# bascule des destinations forcées (lien 1) sur le lien 2
347
				for ip_force in ${FORCE1[@]} ; do
348
					/sbin/ip route replace $ip_force via $GW2 dev eth0
349
				done
350
				# Mangle sur le lien2
351
	                        wan2 eth1
352
	                        [ $nombre_interfaces -ge 3 ] && wan2 eth2
353
	                        [ $nombre_interfaces -ge 4 ] && wan2 eth3
354
	                        [ $nombre_interfaces -eq 5 ] && wan2 eth4
355

    
356
        elif [[ $LLS1 -eq 0 && $LLS2 -eq 1 ]]; then
357
            Aecho "Seul le lien 1 est actif, redirection des flux sur ce lien"
358

    
359
            if [ "$ag_active_mail" == "oui" ] ; then
360
				MssG="Seul le lien 1 est actif, redirection des flux sur ce lien"
361
				SubJ="Liaison $nom_domaine_local_supp  ($numero_etab)"
362
                if [ -z "${CC[@]}" ] ; then
363
                    echo "$MssG"|mutt -s "$SubJ" "$DEST"
364
                else
365
                    echo "$MssG"|mutt -s "$SubJ" "$DEST" -c "${CC[@]}"
366
                fi
367
            fi
368

    
369
                # Iproute2 sur le lien1
370
	                /sbin/ip route replace default via $GW1 dev eth0
371
				# bascule des destinations forcées (lien 2) sur le lien 1
372
				for ip_force in ${FORCE2[@]} ; do
373
					/sbin/ip route replace $ip_force via $GW1 dev eth0
374
				done
375

    
376
			        # Mangle sur lien1
377
                    wan1 eth1
378
                    [ $nombre_interfaces -ge 3 ] && wan1 eth2
379
                    [ $nombre_interfaces -ge 4 ] && wan1 eth3
380
                    [ $nombre_interfaces -eq 5 ] && wan1 eth4
381

    
382
        elif [[ $LLS1 -eq 0 && $LLS2 -eq 0 ]]; then
383
			Aecho "Rechargement de la repartition sur les 2 liens" 'MSG'
384

    
385
            if [ "$ag_active_mail" == "oui" ] ; then
386
				MssG="Rechargement de la repartition sur les 2 liens"
387
				SubJ="Liaison $nom_domaine_local_supp  ($numero_etab)"
388
                if [ -z "${CC[@]}" ] ; then
389
                    echo "$MssG"|mutt -s "$SubJ" "$DEST"
390
                else
391
                    echo "$MssG"|mutt -s "$SubJ" "$DEST" -c "${CC[@]}"
392
                fi
393
	        fi
394

    
395
			# Iproute si mode load balancing
396
            if [ $ag_mode == "mode_lb" ] ; then
397
    	    	# Iproute2 sur les 2 liens
398
	    	    /sbin/ip route replace default proto static nexthop via $GW1 dev eth0 weight $W1 nexthop via $GW2 dev eth0 weight $W2
399

    
400
                # retablit les destination forcees lien 1
401
	            for ip_force in ${FORCE1[@]} ; do
402
                    /sbin/ip route replace $ip_force via $GW1 dev eth0
403
                done
404
                # retablit les destination forcees lien 2
405
	            for ip_force in ${FORCE2[@]} ; do
406
                    /sbin/ip route replace $ip_force via $GW2 dev eth0
407
                done
408

    
409
                # Mangle sur les 2 liens
410
	            balance eth1
411
	            [ $nombre_interfaces -ge 3 ] && balance eth2
412
	            [ $nombre_interfaces -ge 4 ] && wan2 eth3
413
    	        [ $nombre_interfaces -eq 5 ] && wan2 eth4
414
			else
415
                #mode fail-over
416
                # retablit les destination forcees lien 1
417
	            for ip_force in ${FORCE1[@]} ; do
418
                    /sbin/ip route replace $ip_force via $GW1 dev eth0
419
                done
420
                # retablit les destination forcees lien 2
421
	            for ip_force in ${FORCE2[@]} ; do
422
                    /sbin/ip route replace $ip_force via $GW2 dev eth0
423
                done
424
                if [ $ag_fo_etat_eth0 == "actif" ] && [ $ag_fo_etat_eth0_0 == "passif" ] ; then
425
                    /sbin/ip route replace default via $GW1 dev eth0
426
                elif [ $ag_fo_etat_eth0 == "passif" ] && [ $ag_fo_etat_eth0_0 == "actif" ] ; then
427
                    /sbin/ip route replace default via $GW2 dev eth0
428
                fi
429

    
430
	    		# Mangle sur les 2 liens
431
	            balance eth1
432
	            [ $nombre_interfaces -ge 3 ] && balance eth2
433
	            [ $nombre_interfaces -ge 4 ] && wan2 eth3
434
	            [ $nombre_interfaces -eq 5 ] && wan2 eth4
435
			fi
436

    
437
		fi
438
        # rechargement des tunnels, plus utile en 2.3
439
        #/usr/share/eole/magic-rvp &
440
	fi
441

    
442
    if [ $PAUSE -le 5 ];then
443
		sleep 5
444
	else
445
		sleep $PAUSE
446
	fi
447
done