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