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