More PL-specific stuff
[iptables.git] / iptables.init
1 #!/bin/sh
2 #
3 # iptables      Start iptables firewall
4 #
5 # chkconfig: 2345 08 92
6 # description:  Starts, stops and saves iptables firewall
7 #
8 # config: /etc/sysconfig/iptables
9 # config: /etc/sysconfig/iptables-config
10
11 # Source function library.
12 . /etc/init.d/functions
13
14 IPTABLES=iptables
15 IPTABLES_DATA=/etc/sysconfig/$IPTABLES
16 IPTABLES_CONFIG=/etc/sysconfig/${IPTABLES}-config
17 IPV=${IPTABLES%tables} # ip for ipv4 | ip6 for ipv6
18 PROC_IPTABLES_NAMES=/proc/net/${IPV}_tables_names
19 VAR_SUBSYS_IPTABLES=/var/lock/subsys/$IPTABLES
20
21 if [ ! -x /sbin/$IPTABLES ]; then
22     echo -n $"/sbin/$IPTABLES does not exist."; warning; echo
23     exit 0
24 fi
25
26 if lsmod 2>/dev/null | grep -q ipchains ; then
27     echo -n $"ipchains and $IPTABLES can not be used together."; warning; echo
28     exit 0
29 fi
30
31 # Old or new modutils
32 /sbin/modprobe --version 2>&1 | grep -q module-init-tools \
33     && NEW_MODUTILS=1 \
34     || NEW_MODUTILS=0
35
36 # Default firewall configuration:
37 IPTABLES_MODULES=""
38 IPTABLES_MODULES_UNLOAD="yes"
39 IPTABLES_SAVE_ON_STOP="no"
40 IPTABLES_SAVE_ON_RESTART="no"
41 IPTABLES_SAVE_COUNTER="no"
42 IPTABLES_STATUS_NUMERIC="no"
43
44 # Load firewall configuration.
45 [ -f "$IPTABLES_CONFIG" ] && . "$IPTABLES_CONFIG"
46
47 rmmod_r() {
48     # Unload module with all referring modules.
49     # At first all referring modules will be unloaded, then the module itself.
50     local mod=$1
51     local ret=0
52     local ref=
53
54     # Get referring modules.
55     # New modutils have another output format.
56     [ $NEW_MODUTILS = 1 ] \
57         && ref=`lsmod | awk "/^${mod}/ { print \\\$4; }" | tr ',' ' '` \
58         || ref=`lsmod | grep ^${mod} | cut -d "[" -s -f 2 | cut -d "]" -s -f 1`
59
60     # recursive call for all referring modules
61     for i in $ref; do
62         rmmod_r $i
63         let ret+=$?;
64     done
65
66     # Unload module.
67     # The extra test is for 2.6: The module might have autocleaned,
68     # after all referring modules are unloaded.
69     if grep -q "^${mod}" /proc/modules ; then
70         modprobe -r $mod > /dev/null 2>&1
71         let ret+=$?;
72     fi
73
74     return $ret
75 }
76
77 flush_n_delete() {
78     # Flush firewall rules and delete chains.
79     [ -e "$PROC_IPTABLES_NAMES" ] || return 1
80
81     # Check if firewall is configured (has tables)
82     tables=`cat $PROC_IPTABLES_NAMES 2>/dev/null`
83     [ -z "$tables" ] && return 1
84
85     echo -n $"Flushing firewall rules: "
86     ret=0
87     # For all tables
88     for i in $tables; do
89         # Flush firewall rules.
90         $IPTABLES -t $i -F;
91         let ret+=$?;
92
93         # Delete firewall chains.
94         $IPTABLES -t $i -X;
95         let ret+=$?;
96
97         # Set counter to zero.
98         $IPTABLES -t $i -Z;
99         let ret+=$?;
100     done
101
102     [ $ret -eq 0 ] && success || failure
103     echo
104     return $ret
105 }
106
107 set_policy() {
108     # Set policy for configured tables.
109     policy=$1
110
111     # Check if iptable module is loaded
112     [ ! -e "$PROC_IPTABLES_NAMES" ] && return 1
113
114     # Check if firewall is configured (has tables)
115     tables=`cat $PROC_IPTABLES_NAMES 2>/dev/null`
116     [ -z "$tables" ] && return 1
117
118     echo -n $"Setting chains to policy $policy: "
119     ret=0
120     for i in $tables; do
121         echo -n "$i "
122         case "$i" in
123             filter)
124                 $IPTABLES -t filter -P INPUT $policy \
125                     && $IPTABLES -t filter -P OUTPUT $policy \
126                     && $IPTABLES -t filter -P FORWARD $policy \
127                     || let ret+=1
128                 ;;
129             nat)
130                 $IPTABLES -t nat -P PREROUTING $policy \
131                     && $IPTABLES -t nat -P POSTROUTING $policy \
132                     && $IPTABLES -t nat -P OUTPUT $policy \
133                     || let ret+=1
134                 ;;
135             mangle)
136                 $IPTABLES -t mangle -P PREROUTING $policy \
137                     && $IPTABLES -t mangle -P POSTROUTING $policy \
138                     && $IPTABLES -t mangle -P INPUT $policy \
139                     && $IPTABLES -t mangle -P OUTPUT $policy \
140                     && $IPTABLES -t mangle -P FORWARD $policy \
141                     || let ret+=1
142                 ;;
143             *)
144                 let ret+=1
145                 ;;
146         esac
147     done
148
149     [ $ret -eq 0 ] && success || failure
150     echo
151     return $ret
152 }
153
154 start() {
155     # Do not start if there is no config file.
156     [ -f "$IPTABLES_DATA" ] || return 1
157
158     echo -n $"Applying $IPTABLES firewall rules: "
159
160     OPT=
161     [ "x$IPTABLES_SAVE_COUNTER" = "xyes" ] && OPT="-c"
162
163     $IPTABLES-restore $OPT $IPTABLES_DATA
164     if [ $? -eq 0 ]; then
165         success; echo
166     else
167         failure; echo; return 1
168     fi
169     
170     # Tuntap initialization
171
172     if [ -z "$taps" -a -r /etc/planetlab/node_id ] ; then
173         # If this node is not "virtually multi-homed", just bring up
174         # the tap interface with a PLB private address. The PLB
175         # convention is to assign a unique 10.x.y.0/24 network to each
176         # node where x.y is the PlanetLab node ID of the machine in
177         # host order:
178         #
179         # x = (node_id / 256) % 256
180         # y = node_id % 256
181         #
182         node_id=$(cat /etc/planetlab/node_id)
183         taps="tap0"
184         tap0=$(printf 10.%d.%d.1 $((($node_id / 256) % 256)) $(($node_id % 256)))
185         tapmask=255.0.0.0
186     fi
187
188     # Load additional modules (helpers)
189     if [ -n "$IPTABLES_MODULES" ]; then
190         echo -n $"Loading additional $IPTABLES modules: "
191         ret=0
192         for mod in $IPTABLES_MODULES; do
193             echo -n "$mod "
194             modprobe $mod > /dev/null 2>&1
195             let ret+=$?;
196         done
197         [ $ret -eq 0 ] && success || failure
198         echo
199     fi
200
201     for tap in $taps ; do
202         # Configuration for this tap (address/proxy)
203         eval cfg=\$$tap
204         addr=${cfg%/*}
205         proxy=${cfg#*/}
206
207         # Set MAC address to something predictable
208         mac=$(printf 00:FF:%X:%X:%X:%X $(echo $addr | sed -e 's/\./ /g'))
209
210         # Bring up this interface. Optimize the MTU for the PlanetLab
211         # Backbone (1500/Ethernet - 4/GRE - 8/UDP - 20/IP = 1468).
212             ifconfig $tap down && \
213             ifconfig $tap hw ether $mac mtu 1468 && \
214             ifconfig $tap $addr ${proxy:+pointopoint $proxy} netmask ${tapmask:=255.255.255.255} up
215
216         # Stuffing the proxy for this address in the pointopoint field
217         # creates a static route to the proxy that we do not want
218         # present.
219         if [ -n "$proxy" -a "$proxy" != "$addr" ] ; then
220                 ip route del $proxy
221         fi
222
223         # Enable route through this interface
224             ip route add default dev $tap tab 1 && \
225             ip rule add from $addr tab 1
226     done
227
228     
229     touch $VAR_SUBSYS_IPTABLES
230     return $ret
231 }
232
233 stop() {
234     
235         # Do not stop if iptables module is not loaded.
236     [ -e "$PROC_IPTABLES_NAMES" ] || return 1
237
238     flush_n_delete
239     set_policy ACCEPT
240     
241     if [ "x$IPTABLES_MODULES_UNLOAD" = "xyes" ]; then
242         echo -n $"Unloading $IPTABLES modules: "
243         ret=0
244         rmmod_r ${IPV}_tables
245         let ret+=$?;
246         rmmod_r ${IPV}_conntrack
247         let ret+=$?;
248         [ $ret -eq 0 ] && success || failure
249         echo
250     fi
251
252     # Take down vnet interfaces
253     for dev in $taps tap0 ; do
254         action $"Shutting down interface $dev: " \
255             ifconfig $dev 0.0.0.0 down
256     done                
257
258     rm -f $VAR_SUBSYS_IPTABLES
259     return $ret
260 }
261
262 save() {
263     # Check if iptable module is loaded
264     [ ! -e "$PROC_IPTABLES_NAMES" ] && return 1
265
266     # Check if firewall is configured (has tables)
267     tables=`cat $PROC_IPTABLES_NAMES 2>/dev/null`
268     [ -z "$tables" ] && return 1
269
270     echo -n $"Saving firewall rules to $IPTABLES_DATA: "
271
272     OPT=
273     [ "x$IPTABLES_SAVE_COUNTER" = "xyes" ] && OPT="-c"
274
275     ret=0
276     TMP_FILE=`/bin/mktemp -q /tmp/$IPTABLES.XXXXXX` \
277         && chmod 600 "$TMP_FILE" \
278         && $IPTABLES-save $OPT > $TMP_FILE 2>/dev/null \
279         && size=`stat -c '%s' $TMP_FILE` && [ $size -gt 0 ] \
280         || ret=1
281     if [ $ret -eq 0 ]; then
282         if [ -e $IPTABLES_DATA ]; then
283             cp -f $IPTABLES_DATA $IPTABLES_DATA.save \
284                 && chmod 600 $IPTABLES_DATA.save \
285                 || ret=1
286         fi
287         if [ $ret -eq 0 ]; then
288             cp -f $TMP_FILE $IPTABLES_DATA \
289                 && chmod 600 $IPTABLES_DATA \
290                 || ret=1
291         fi
292     fi
293     [ $ret -eq 0 ] && success || failure
294     echo
295     rm -f $TMP_FILE
296     return $ret
297 }
298
299 status() {
300     # Do not print status if lockfile is missing and iptables modules are not 
301     # loaded.
302     # Check if iptable module is loaded
303     if [ ! -f "$VAR_SUBSYS_IPTABLES" ]; then
304         echo $"Firewall is stopped."
305         return 1
306     fi
307
308     # Check if firewall is configured (has tables)
309     if [ ! -e "$PROC_IPTABLES_NAMES" ]; then
310         echo $"Firewall is not configured. "
311         return 1
312     fi
313     tables=`cat $PROC_IPTABLES_NAMES 2>/dev/null`
314     if [ -z "$tables" ]; then
315         echo $"Firewall is not configured. "
316         return 1
317     fi
318
319     NUM=
320     [ "x$IPTABLES_STATUS_NUMERIC" = "xyes" ] && NUM="-n"
321
322     for table in $tables; do
323         echo $"Table: $table"
324         $IPTABLES -t $table --list $NUM && echo
325     done
326
327     return 0
328 }
329
330 restart() {
331     [ "x$IPTABLES_SAVE_ON_RESTART" = "xyes" ] && save
332     stop
333     start
334 }
335
336 case "$1" in
337     start)
338         stop
339         start
340         RETVAL=$?
341         ;;
342     stop)
343         [ "x$IPTABLES_SAVE_ON_STOP" = "xyes" ] && save
344         stop
345         RETVAL=$?
346         ;;
347     restart)
348         restart
349         RETVAL=$?
350         ;;
351     condrestart)
352         [ -e "$VAR_SUBSYS_IPTABLES" ] && restart
353         ;;
354     status)
355         status
356         RETVAL=$?
357         ;;
358     panic)
359         flush_n_delete
360         set_policy DROP
361         RETVAL=$?
362         ;;
363     save)
364         save
365         RETVAL=$?
366         ;;
367     *)
368         echo $"Usage: $0 {start|stop|restart|condrestart|status|panic|save}"
369         exit 1
370         ;;
371 esac
372
373 exit $RETVAL