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