8d9cb504fe179fd83b86b0052420627bdcdfe895
[rahunas] / tools / firewall.sh.in
1 #!/bin/sh
2 # The firewall script to provides the ability to capture the web request from 
3 # the clients and redirect them to the login page to get the authorization to 
4 # access the network.
5
6 PATH=/sbin:/bin:/usr/sbin:/usr/bin:@prefix@/sbin:@prefix@/bin
7 prefix=@prefix@
8 exec_prefix=@exec_prefix@
9
10 IPTABLES=/sbin/iptables
11 IPSET=/usr/sbin/ipset
12
13 NAME="rahunas"
14 INIT=@sysconfdir@/default/rahunas
15 RUN=@localstatedir@/run/rahunas-firewall
16 VSERVER_LIST=@localstatedir@/run/rahunas-vserver
17
18 RUN_DAEMON=no
19
20 test -f $INIT || exit 0 
21 . $INIT
22
23 test "$RUN_DAEMON" = "yes" || exit 0
24 test -f $RAHUNAS_CONFIG || exit 1
25 test -f $VSERVER_LIST || touch $VSERVER_LIST
26
27 get_section_name () {
28   file=$1
29   
30   grep "^.*\= {$" $file | sed "s/= {//" |  sed "s/^ *\(.*[^ ]\) *$/\1/"
31 }
32
33 get_config_value () {
34   section=$1
35   key=$2
36   file=$3
37
38   cat $file | sed -e "0,/$section = {/ ! { /}/,/$section = {/ ! s/^/>>/ }" | grep "^>>" | sed -e "s/^>>//g" | grep -w "$key" | cut -d= -f2 | sed "s/^ *\(.*[^ ]\) *$/\1/" | sed 's/"//g'
39 }
40
41 ##
42 #  Global Declaration
43 ##
44
45 # Main
46 MAIN_CONF_DIR=`get_config_value main conf_dir $RAHUNAS_CONFIG`
47 MAIN_BANDWIDTH_SHAPE=`get_config_value main bandwidth_shape $RAHUNAS_CONFIG`
48 MAIN_BITTORRENT_DOWNLOAD_MAX=`get_config_value main bittorrent_download_max $RAHUNAS_CONFIG`
49 MAIN_BITTORRENT_UPLOAD_MAX=`get_config_value main bittorrent_upload_max $RAHUNAS_CONFIG`
50 MAIN_DHCP=`get_config_value main dhcp $RAHUNAS_CONFIG`
51
52 # Virtual Server : config
53 VSERVER_ID=
54 DEV_EXTERNAL=
55 DEV_INTERNAL=
56 BRIDGE=
57 MASQUERADE=
58 IGNORE_MAC=
59 VSERVER_IP=
60 CLIENTS=
61 EXCLUDED=
62 BANDWIDTH_SHAPE=
63 DNS=
64 SSH=
65 PROXY=
66 PROXY_HOST=
67 PROXY_PORT=
68 BITTORRENT=
69 BITTORRENT_ALLOW=
70 BITTORRENT_DOWNLOAD_MAX=
71 BITTORRENT_UPLOAD_MAX=
72 VSERVER_PORTS_ALLOW=
73 VSERVER_PORTS_INTERCEPT=
74
75 # Virtual Server : set and chains
76 CHAIN_INPUT=
77 CHAIN_INPUT_AUTH=
78 CHAIN_FORWARD=
79 CHAIN_FORWARD_AUTH=
80 CHAIN_MANGLE_PREROUTING=
81 CHAIN_MANGLE_FORWARD=
82 CHAIN_MANGLE_POSTROUTING=
83 CHAIN_NAT_PREROUTING=
84 CHAIN_NAT_POSTROUTING=
85 CHAIN_NAT_AUTHEN=
86 CHAIN_P2P_DETECT=
87 CHAIN_P2P_RECHECK=
88 CHAIN_P2P_CHECK=
89 P2P_SET=
90 P2P_ALLOW_SET=
91 DEV_IN_PARAM=
92 DEV_OUT_PARAM=
93 SETNAME=
94
95 get_config () {
96   file=$1
97   opt=$2
98
99   test -f $file || return 1
100
101   NAME=`get_section_name $file`
102
103   # Get configuration
104   VSERVER_ID=`get_config_value $NAME vserver_id $file`
105   test -n "$VSERVER_ID" || return 2
106
107   if [ "$opt" = "start" ]; then
108     hash="$VSERVER_ID:$NAME"
109     test1=`grep -w "$hash" $VSERVER_LIST` || true
110     test2=`grep -w "$NAME" $VSERVER_LIST` || true
111   
112     test -n "$test1" -o -n "$test2" && return 3 
113
114     echo "$hash:$file" >> $VSERVER_LIST
115   fi
116
117   DEV_EXTERNAL=`get_config_value $NAME dev_external $file`
118   DEV_INTERNAL=`get_config_value $NAME dev_internal $file`
119   BRIDGE=`get_config_value $NAME bridge $file`
120   MASQUERADE=`get_config_value $NAME masquerade $file`
121   IGNORE_MAC=`get_config_value $NAME ignore_mac $file`
122   VSERVER_IP=`get_config_value $NAME vserver_ip $file`
123   CLIENTS=`get_config_value $NAME clients $file`
124   EXCLUDED=`get_config_value $NAME excluded $file`
125   BANDWIDTH_SHAPE=$MAIN_BANDWIDTH_SHAPE
126   DNS=`get_config_value $NAME dns $file`
127   SSH=`get_config_value $NAME ssh $file`
128   PROXY=`get_config_value $NAME proxy $file`
129   PROXY_HOST=`get_config_value $NAME proxy_host $file`
130   PROXY_PORT=`get_config_value $NAME proxy_port $file`
131   BITTORRENT=`get_config_value $NAME bittorrent $file`
132   BITTORRENT_ALLOW=`get_config_value $NAME bittorrent_allow $file`
133   BITTORRENT_DOWNLOAD_MAX=$MAIN_BITTORRENT_DOWNLOAD_MAX
134   BITTORRENT_UPLOAD_MAX=$MAIN_BITTORRENT_UPLOAD_MAX
135   VSERVER_PORTS_ALLOW=`get_config_value $NAME vserver_ports_allow $file`
136   VSERVER_PORTS_INTERCEPT=`get_config_value $NAME vserver_ports_intercept $file`
137  
138   # Bridge config
139   if [ "$BRIDGE" = "yes" ]; then
140     DEV_IN_PARAM="-m physdev --physdev-in"
141     DEV_OUT_PARAM="-m physdev --physdev-out"
142   else
143     DEV_IN_PARAM="-i"
144     DEV_OUT_PARAM="-o"
145   fi
146   
147   # Set declaration
148   SETNAME="${NAME}"
149   
150   # Chains declaration
151   CHAIN_INPUT="${NAME}_in"
152   CHAIN_INPUT_AUTH="${NAME}_in_auth"
153   CHAIN_FORWARD="${NAME}_fwd"
154   CHAIN_FORWARD_AUTH="${NAME}_fwd_auth"
155   CHAIN_MANGLE_PREROUTING="${NAME}_mg_pre"
156   CHAIN_MANGLE_FORWARD="${NAME}_mg_fwd"
157   CHAIN_MANGLE_POSTROUTING="${NAME}_mg_post"
158   CHAIN_NAT_PREROUTING="${NAME}_nat_pre"
159   CHAIN_NAT_POSTROUTING="${NAME}_nat_post"
160   CHAIN_NAT_AUTHEN="${NAME}_nat_authen"
161   
162   # P2P checking chains declaration
163   CHAIN_P2P_DETECT="${NAME}_p2p_detect"
164   CHAIN_P2P_RECHECK="${NAME}_p2p_rechk"
165   CHAIN_P2P_CHECK="${NAME}_p2p_chk"
166   P2P_SET="${NAME}_p2p"
167   P2P_ALLOW_SET="${NAME}_p2p_allow"
168 }
169
170 ##
171 # Add set
172 ##
173 add_set () {
174   ipset_opt=""
175   ipset_ignoremac=""
176   
177   ipset_opt="--network $CLIENTS"
178   
179   if [ "$IGNORE_MAC" = "yes" ]; then
180     ipset_ignoremac="--ignoremac"
181   fi
182   
183   $IPSET -N $SETNAME rahunas $ipset_opt $ipset_ignoremac 
184
185   if [ "$BITTORRENT" = "throttle" ]; then
186     $IPSET -N $P2P_SET iphash
187   fi
188
189   if [ -n "$BITTORRENT_ALLOW" ]; then
190     $IPSET -N $P2P_ALLOW_SET iphash 
191     for ip in $BITTORRENT_ALLOW
192     do
193       $IPSET -A $P2P_ALLOW_SET $ip
194     done
195   fi
196 }
197
198 ##
199 # Cleanup set
200 ##
201 cleanup_set () {
202   $IPSET -F $SETNAME
203   $IPSET -X $SETNAME
204
205   if [ "$BITTORRENT" = "throttle" ]; then
206     $IPSET -F $P2P_SET
207     $IPSET -X $P2P_SET 
208   fi
209
210   if [ -n "$BITTORRENT_ALLOW" ]; then
211     $IPSET -F $P2P_ALLOW_SET
212     $IPSET -X $P2P_ALLOW_SET 
213   fi
214 }
215
216 ##
217 # Navigation rules
218 ##
219 navigation_rules () {
220   opt=$1
221   if [ "$opt" = "start" ]; then
222     action="-I"
223   elif [ "$opt" = "stop" ]; then
224     action="-D"
225   fi
226
227   # INPUT from external
228   # TODO: Make a common firewall to filter the external requests.
229   $IPTABLES $action INPUT \
230     $DEV_IN_PARAM $DEV_EXTERNAL -j ACCEPT 
231
232   # INPUT
233   $IPTABLES $action INPUT \
234     $DEV_IN_PARAM $DEV_INTERNAL -s $CLIENTS \
235     -j $CHAIN_INPUT
236   $IPTABLES $action INPUT -m connmark --mark 2/2 \
237     $DEV_IN_PARAM $DEV_INTERNAL -s $CLIENTS \
238     -j $CHAIN_INPUT_AUTH
239
240   # FORWARD
241   $IPTABLES $action FORWARD \
242     $DEV_OUT_PARAM $DEV_INTERNAL -d $CLIENTS \
243     -j $CHAIN_FORWARD
244   $IPTABLES $action FORWARD \
245     $DEV_IN_PARAM $DEV_INTERNAL -s $CLIENTS \
246     -j $CHAIN_FORWARD
247
248   # In some situation the connections could not established before
249   # the FORWARD rules allow the clients, thus the connections never mark.
250   # Just allow them passthrough the rules if the connections do not mark but
251   # the clients are in the set (allow them).
252   $IPTABLES $action FORWARD -m set --set $SETNAME dst -j $CHAIN_FORWARD_AUTH
253   $IPTABLES $action FORWARD -m set --set $SETNAME src -j $CHAIN_FORWARD_AUTH
254
255   $IPTABLES $action FORWARD -m connmark --mark 2/2 \
256     $DEV_OUT_PARAM $DEV_INTERNAL -d $CLIENTS \
257     -j $CHAIN_FORWARD_AUTH
258   $IPTABLES $action FORWARD -m connmark --mark 2/2 \
259     $DEV_IN_PARAM $DEV_INTERNAL -s $CLIENTS \
260     -j $CHAIN_FORWARD_AUTH
261
262   # MANGLE
263   $IPTABLES -t mangle $action PREROUTING \
264     $DEV_IN_PARAM $DEV_INTERNAL -s $CLIENTS \
265     -j $CHAIN_MANGLE_PREROUTING
266   $IPTABLES -t mangle $action PREROUTING \
267     $DEV_IN_PARAM $DEV_EXTERNAL -d $CLIENTS \
268     -j $CHAIN_MANGLE_PREROUTING
269
270   $IPTABLES -t mangle $action FORWARD \
271     $DEV_OUT_PARAM $DEV_INTERNAL -d $CLIENTS \
272     -j $CHAIN_MANGLE_FORWARD
273   $IPTABLES -t mangle $action FORWARD \
274     $DEV_IN_PARAM $DEV_INTERNAL -s $CLIENTS \
275     -j $CHAIN_MANGLE_FORWARD
276
277   $IPTABLES -t mangle $action POSTROUTING \
278     $DEV_OUT_PARAM $DEV_INTERNAL -d $CLIENTS \
279     -j $CHAIN_MANGLE_POSTROUTING
280   $IPTABLES -t mangle $action POSTROUTING \
281     $DEV_OUT_PARAM $DEV_EXTERNAL -s $CLIENTS \
282     -j $CHAIN_MANGLE_POSTROUTING
283
284   # NAT
285   $IPTABLES -t nat $action PREROUTING \
286     $DEV_IN_PARAM $DEV_INTERNAL -s $CLIENTS \
287     -j $CHAIN_NAT_PREROUTING
288   $IPTABLES -t nat $action PREROUTING \
289     $DEV_IN_PARAM $DEV_EXTERNAL -d $CLIENTS \
290     -j $CHAIN_NAT_PREROUTING
291
292   $IPTABLES -t nat $action POSTROUTING \
293     $DEV_OUT_PARAM $DEV_INTERNAL -d $CLIENTS \
294     -j $CHAIN_NAT_POSTROUTING
295   $IPTABLES -t nat $action POSTROUTING \
296     $DEV_OUT_PARAM $DEV_EXTERNAL -s $CLIENTS \
297     -j $CHAIN_NAT_POSTROUTING
298 }
299
300 ##
301 # Cleanup old rules
302 ##
303 cleanup () {
304
305   navigation_rules stop  
306
307   $IPTABLES -F $CHAIN_INPUT_AUTH
308   $IPTABLES -X $CHAIN_INPUT_AUTH
309
310   $IPTABLES -F $CHAIN_INPUT
311   $IPTABLES -X $CHAIN_INPUT
312   
313   $IPTABLES -F $CHAIN_FORWARD_AUTH
314   $IPTABLES -X $CHAIN_FORWARD_AUTH
315
316   $IPTABLES -F $CHAIN_FORWARD
317   $IPTABLES -X $CHAIN_FORWARD
318   
319   $IPTABLES -t mangle -F $CHAIN_MANGLE_PREROUTING
320   $IPTABLES -t mangle -X $CHAIN_MANGLE_PREROUTING
321
322   $IPTABLES -t mangle -F $CHAIN_MANGLE_POSTROUTING
323   $IPTABLES -t mangle -X $CHAIN_MANGLE_POSTROUTING
324   
325   $IPTABLES -t nat -F $CHAIN_NAT_PREROUTING
326   $IPTABLES -t nat -X $CHAIN_NAT_PREROUTING
327   
328   $IPTABLES -t mangle -F $CHAIN_MANGLE_FORWARD
329   $IPTABLES -t mangle -X $CHAIN_MANGLE_FORWARD
330
331   $IPTABLES -t nat -F $CHAIN_NAT_POSTROUTING
332   $IPTABLES -t nat -X $CHAIN_NAT_POSTROUTING
333   
334   $IPTABLES -t nat -F $CHAIN_NAT_AUTHEN
335   $IPTABLES -t nat -X $CHAIN_NAT_AUTHEN
336
337   if [ "$BITTORRENT" = "throttle" ]; then
338     $IPTABLES -t mangle -F $CHAIN_P2P_CHECK
339     $IPTABLES -t mangle -X $CHAIN_P2P_CHECK
340
341     $IPTABLES -t mangle -F $CHAIN_P2P_RECHECK
342     $IPTABLES -t mangle -X $CHAIN_P2P_RECHECK
343
344     $IPTABLES -t mangle -F $CHAIN_P2P_DETECT
345     $IPTABLES -t mangle -X $CHAIN_P2P_DETECT
346   fi
347 }
348
349 ##
350 # Define new chains
351 ##
352 new_chains () {
353   $IPTABLES -N $CHAIN_INPUT_AUTH
354   $IPTABLES -N $CHAIN_INPUT
355   $IPTABLES -N $CHAIN_FORWARD_AUTH
356   $IPTABLES -N $CHAIN_FORWARD
357   $IPTABLES -t mangle -N $CHAIN_MANGLE_PREROUTING
358   $IPTABLES -t mangle -N $CHAIN_MANGLE_FORWARD
359   $IPTABLES -t mangle -N $CHAIN_MANGLE_POSTROUTING
360   $IPTABLES -t nat -N $CHAIN_NAT_PREROUTING
361   $IPTABLES -t nat -N $CHAIN_NAT_POSTROUTING
362   $IPTABLES -t nat -N $CHAIN_NAT_AUTHEN
363
364   if [ "$BITTORRENT" = "throttle" ]; then
365     $IPTABLES -t mangle -N $CHAIN_P2P_CHECK
366     $IPTABLES -t mangle -N $CHAIN_P2P_RECHECK
367     $IPTABLES -t mangle -N $CHAIN_P2P_DETECT
368   fi
369 }
370
371 ##
372 # Policy
373 ##
374 policy () {
375   $IPTABLES -P INPUT DROP
376   $IPTABLES -P OUTPUT ACCEPT
377   $IPTABLES -P FORWARD DROP 
378
379   $IPTABLES -A INPUT -i lo -j ACCEPT
380
381   # DHCP Settings
382
383   if [ "$MAIN_DHCP" = "yes" ]; then
384     $IPTABLES -A INPUT -p udp --dport 67:68 -j ACCEPT 
385     $IPTABLES -A FORWARD -p udp --dport 67:68 -j DROP
386   elif [ "$MAIN_DHCP" = "no" ]; then
387     $IPTABLES -A INPUT -p udp --dport 67:68 -j DROP 
388     $IPTABLES -A FORWARD -p udp --dport 67:68 -j DROP
389   elif [ "$MAIN_DHCP" = "forward" ]; then
390     $IPTABLES -A INPUT -p udp --dport 67:68 -j DROP 
391     $IPTABLES -A FORWARD -p udp --dport 67:68 -j ACCEPT
392   fi
393 }
394
395 cleanup_policy () {
396   # Assume before the script running the default policy are all ACCEPT
397   $IPTABLES -P INPUT ACCEPT
398   $IPTABLES -P OUTPUT ACCEPT
399   $IPTABLES -P FORWARD ACCEPT 
400
401   $IPTABLES -D INPUT -i lo -j ACCEPT
402
403   # DHCP Settings
404
405   if [ "$MAIN_DHCP" = "yes" ]; then
406     $IPTABLES -D INPUT -p udp --dport 67:68 -j ACCEPT 
407     $IPTABLES -D FORWARD -p udp --dport 67:68 -j DROP
408   elif [ "$MAIN_DHCP" = "no" ]; then
409     $IPTABLES -D INPUT -p udp --dport 67:68 -j DROP 
410     $IPTABLES -D FORWARD -p udp --dport 67:68 -j DROP
411   elif [ "$MAIN_DHCP" = "forward" ]; then
412     $IPTABLES -D INPUT -p udp --dport 67:68 -j DROP 
413     $IPTABLES -D FORWARD -p udp --dport 67:68 -j ACCEPT
414   fi
415 }
416
417 rules () {
418
419   navigation_rules start
420   
421   ##
422   # Allow all traffic for established and related connections
423   ##
424   
425   $IPTABLES -A $CHAIN_INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
426   $IPTABLES -A $CHAIN_FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
427   
428   $IPTABLES -A $CHAIN_INPUT -i lo -j ACCEPT
429   
430   ##
431   # Allow incoming to our DNS server
432   ##
433   if [ "$DNS" = "yes" ]; then
434     $IPTABLES -A $CHAIN_INPUT -p udp --dport domain -j ACCEPT
435     $IPTABLES -A $CHAIN_FORWARD -p udp --dport domain -j DROP
436   elif [ "$DNS" = "no" ]; then
437     $IPTABLES -A $CHAIN_INPUT -p udp --dport domain -j DROP
438     $IPTABLES -A $CHAIN_FORWARD -p udp --dport domain -j ACCEPT
439   elif [ "$DNS" = "forward" ]; then
440     $IPTABLES -A $CHAIN_INPUT -p udp --dport domain -j ACCEPT
441     $IPTABLES -A $CHAIN_FORWARD -p udp --dport domain -j ACCEPT
442   fi 
443
444   ##
445   # Allow incoming to our HTTP server for login page
446   ##
447   $IPTABLES -A $CHAIN_INPUT -p tcp -m multiport -d $VSERVER_IP\
448      --dports $VSERVER_PORTS_ALLOW \
449     -m recent --rcheck --seconds 6 --name incoming_throttle -j DROP
450
451   $IPTABLES -A $CHAIN_INPUT -p tcp -m multiport -d $VSERVER_IP \
452     --dports $VSERVER_PORTS_ALLOW \
453     -m hashlimit --hashlimit 20/sec \
454     --hashlimit-mode srcip --hashlimit-burst 30 \
455     --hashlimit-htable-expire 4000 --hashlimit-name incoming \
456     -j ACCEPT
457
458   $IPTABLES -A $CHAIN_INPUT -p tcp -m multiport -d $VSERVER_IP \
459     --dports $VSERVER_PORTS_ALLOW \
460     -m recent --set --name incoming_throttle -j DROP
461   
462   ##
463   # Allow incoming to our SSH server for remote maintenance access
464   ##
465   if [ "$SSH" = "yes" ]; then
466     $IPTABLES -A $CHAIN_INPUT -p tcp -d $VSERVER_IP --dport ssh -j ACCEPT
467   fi
468
469   ##
470   # Allow rate limited ICMP 
471   ##
472   $IPTABLES -A $CHAIN_INPUT -p icmp -m limit --limit 5/second \
473     -d $VSERVER_IP -j ACCEPT
474
475
476
477   ##
478   # Bittorrent Blocking (layer7 module in kernel is needed)
479   # Note: 
480   #   bittorrent-announce is customized pattern, warning if not exists.
481   ##
482   if [ "$BITTORRENT" = "yes" -o -n "$BITTORRENT_ALLOW" ]; then
483     if [ -n "$BITTORRENT_ALLOW" ]; then
484       BITTORRENT_ALLOW_OPTIONS="-m set ! --set $P2P_ALLOW_SET"
485
486       # Source host
487       $IPTABLES -t mangle -A $CHAIN_MANGLE_PREROUTING -m layer7 --l7proto bittorrent-announce $BITTORRENT_ALLOW_OPTIONS src -j DROP
488       $IPTABLES -t mangle -A $CHAIN_MANGLE_PREROUTING -m layer7 --l7proto bittorrent $BITTORRENT_ALLOW_OPTIONS src -j DROP
489     fi
490   else
491       $IPTABLES -t mangle -A $CHAIN_MANGLE_PREROUTING -m layer7 --l7proto bittorrent-announce -j DROP
492       $IPTABLES -t mangle -A $CHAIN_MANGLE_PREROUTING -m layer7 --l7proto bittorrent -j DROP
493   fi
494   
495   ##
496   # Mark the connections that have been authorized
497   ##
498   $IPTABLES -t mangle -A $CHAIN_MANGLE_PREROUTING -m set --set $SETNAME dst -j CONNMARK --set-mark 2 
499   $IPTABLES -t mangle -A $CHAIN_MANGLE_PREROUTING -m set --set $SETNAME src -j CONNMARK --set-mark 2 
500
501   ##
502   # P2P Throttle
503   ##
504   if [ "$BITTORRENT" = "throttle" ]; then
505     $IPTABLES -t mangle -A $CHAIN_MANGLE_FORWARD -m connmark --mark 2/2 -j $CHAIN_P2P_CHECK
506     $IPTABLES -t mangle -A $CHAIN_MANGLE_FORWARD -m set --set $P2P_SET src -j MARK --set-mark 3
507     $IPTABLES -t mangle -A $CHAIN_MANGLE_FORWARD -m set --set $P2P_SET dst -j MARK --set-mark 3
508
509
510     $IPTABLES -t mangle -A $CHAIN_P2P_CHECK -m layer7 --l7proto bittorrent -j $CHAIN_P2P_DETECT
511     $IPTABLES -t mangle -A $CHAIN_P2P_CHECK -m layer7 --l7proto bittorrent-announce -j $CHAIN_P2P_DETECT
512     $IPTABLES -t mangle -A $CHAIN_P2P_CHECK -m set --set $P2P_SET src -j $CHAIN_P2P_RECHECK
513     $IPTABLES -t mangle -A $CHAIN_P2P_CHECK -j RETURN
514
515
516     $IPTABLES -t mangle -A $CHAIN_P2P_DETECT -m recent --name $P2P_SET --update --seconds 600 -j RETURN
517     $IPTABLES -t mangle -A $CHAIN_P2P_DETECT -j SET --add-set $P2P_SET src
518     $IPTABLES -t mangle -A $CHAIN_P2P_DETECT -m recent --name $P2P_SET --set -j RETURN
519
520     $IPTABLES -t mangle -A $CHAIN_P2P_RECHECK -m recent --name $P2P_SET --rcheck --seconds 600 -j RETURN
521     $IPTABLES -t mangle -A $CHAIN_P2P_RECHECK -j SET --del-set $P2P_SET src
522     $IPTABLES -t mangle -A $CHAIN_P2P_RECHECK -m recent --name $P2P_SET --remove -j RETURN 
523   fi
524    
525   ##
526   # Accept Forwarding for the authorized clients
527   ##
528   $IPTABLES -A $CHAIN_FORWARD_AUTH -j ACCEPT
529
530   ##
531   # SQUID Cache-Proxy
532   ##
533   if [ "$PROXY" = "yes" -o "$PROXY" = "transparent" ]; then
534     if [ "$PROXY_HOST" = "localhost" -o "$PROXY_HOST" = "127.0.0.1" ]; then
535       $IPTABLES -A $CHAIN_INPUT_AUTH -p tcp --dport $PROXY_PORT -j ACCEPT
536     fi
537
538     if [ "$PROXY" = "transparent" ]; then
539       if [ "$PROXY_HOST" = "localhost" -o "$PROXY_HOST" = "127.0.0.1" ]; then
540         $IPTABLES -t nat -A $CHAIN_NAT_PREROUTING -p tcp --dport http \
541           -m connmark --mark 2/2 -j REDIRECT --to-ports $PROXY_PORT
542       else
543         $IPTABLES -t nat -A $CHAIN_NAT_PRETROUTING -p tcp --dport http \
544           -m connmark --mark 2/2 \
545           -j DNAT --to-destination $PROXY_HOST:$PROXY_PORT
546       fi
547     fi
548   fi
549   
550   ##
551   # Redirect unauthorized clients to login page (with rate limited throttling)
552   ##
553   
554   $IPTABLES -t nat -A $CHAIN_NAT_PREROUTING -p tcp -m multiport \
555     --dports $VSERVER_PORTS_INTERCEPT -d ! $VSERVER_IP \
556     -m connmark ! --mark 2/2 \
557     -j $CHAIN_NAT_AUTHEN
558   
559   $IPTABLES -t nat -A $CHAIN_NAT_AUTHEN -p tcp \
560     -j DNAT --to-destination $VSERVER_IP:80
561
562   ##
563   # MASQUERADE
564   ##
565   if [ "$MASQUERADE" = "yes" ]; then
566     $IPTABLES -t nat -A $CHAIN_NAT_POSTROUTING $DEV_OUT_PARAM $DEV_EXTERNAL \
567       -j MASQUERADE
568   fi
569
570   ##
571   # Excluded IP
572   ##
573   for excluded in $EXCLUDED;
574   do
575     $IPTABLES -t mangle -I $CHAIN_MANGLE_PREROUTING -s $excluded \
576       -j CONNMARK --set-mark 2
577     $IPTABLES -t mangle -I $CHAIN_MANGLE_PREROUTING -d $excluded \
578       -j CONNMARK --set-mark 2
579   done 
580   
581   ##
582   # Bandwidth Shaping: IMQ - Intermediate Queueing Device
583   ##
584   if [ "$BANDWIDTH_SHAPE" = "yes" ]; then
585     $IPTABLES -t mangle -I $CHAIN_MANGLE_POSTROUTING $DEV_OUT_PARAM $DEV_INTERNAL -j IMQ --todev 0
586     $IPTABLES -t mangle -I $CHAIN_MANGLE_PREROUTING $DEV_IN_PARAM $DEV_INTERNAL -j IMQ --todev 1
587   fi
588
589   ##
590   # Return to main chains
591   ##
592   $IPTABLES -A $CHAIN_INPUT_AUTH -j RETURN
593   $IPTABLES -A $CHAIN_INPUT -j RETURN
594   $IPTABLES -A $CHAIN_FORWARD_AUTH -j RETURN
595   $IPTABLES -A $CHAIN_FORWARD -j RETURN
596   $IPTABLES -t mangle -A $CHAIN_MANGLE_PREROUTING -j RETURN
597   $IPTABLES -t mangle -A $CHAIN_MANGLE_FORWARD -j RETURN
598   $IPTABLES -t mangle -A $CHAIN_MANGLE_POSTROUTING -j RETURN
599   $IPTABLES -t nat -A $CHAIN_NAT_PREROUTING -j RETURN
600   $IPTABLES -t nat -A $CHAIN_NAT_POSTROUTING -j RETURN
601 }
602
603 do_get_config () {
604   file=$1
605   opt=$2
606   get_config $file $opt || true
607   if [ $? -eq 1 ]; then
608     echo "Error: Could not parsing $file, file does not exists"
609     return 1
610   elif [ $? -eq 2 ]; then
611     echo "Error: Could not parsing $file, config file is malformed"
612     return 2
613   elif [ $? -eq 3 ]; then
614     if [ "$opt" != "stop" ]; then
615       echo "Error: Could not parsing $file, network's name is duplicated!"
616       return 3
617     fi
618   fi
619 }
620
621 start () {
622   test ! -f $RUN || return 0
623
624   if [ ! -d $MAIN_CONF_DIR ]; then
625     echo "Error: The config directory $MAIN_CONF_DIR does not exists"
626     exit 1
627   fi
628
629   for file in `find $MAIN_CONF_DIR -name '*.conf'`;
630   do
631     do_get_config $file start
632     if [ $? -gt 0 ]; then
633       continue
634     fi 
635
636     add_set
637     new_chains
638     policy 
639     rules  
640   done
641
642   touch $RUN
643 }
644
645 stop () {
646   opt=$1
647   test -f $RUN || return 0
648
649   for line in `cat $VSERVER_LIST`;
650   do
651     file=`echo $line | cut -d: -f3` 
652     test -n $file || continue;
653     do_get_config $file stop
654     if [ $? -gt 0 ]; then
655       continue
656     fi
657
658     cleanup
659     cleanup_policy
660     test "$opt" = "reload" || cleanup_set
661   done
662
663    
664   rm -f $RUN
665   echo "" > $VSERVER_LIST
666 }
667
668 restart() {
669   stop
670   start
671 }
672
673 reload() {
674   stop reload
675   start
676 }
677
678 case "$1" in
679   start)
680     start
681     ;;
682   stop)
683     stop
684     ;;
685   restart)
686     restart
687     ;;
688   reload)
689     reload     
690     ;; 
691   *)
692     N=@sysconfdir@/rahunas/firewall.sh
693     echo "Usage: $N {start|stop|restart|reload}"
694     exit 3
695     ;;
696 esac 
697
698 exit 0