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