· 5 years ago · Sep 09, 2020, 03:30 PM
1#!/bin/bash
2#
3# rc.firewall Linux Firewall version 2.0rc9 -- 05/02/03
4# http://projectfiles.com/firewall/
5#
6# Copyright (C) 2001-2003 Scott Bartlett <srb@mnsolutions.com>
7#
8# This program is free software; you can redistribute it and/or
9# modify it under the terms of the GNU General Public License as
10# published by the Free Software Foundation; either version 2 of
11# the License, or (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details:
17# http://www.gnu.org/licenses/gpl.html
18#
19#####################################
20# -- Basic Configuration Options -- #
21#####################################
22#
23# NOTE: All lists are delimited by single spaces, eg "eth0 eth1 ppp0".
24#
25# The PERMIT option below allows remote access to this machine in the three
26# ways listed below. Note that by default hosts in internal networks are
27# already allowed to connect to all services on the firewall.
28# 1.) Listed PORTS will be open to ANY connecting host. Protocols 'tcp' and
29# 'udp' can optionally be specified. If no protocol is specified, then
30# connections using either protocol will be accepted on the given port(s).
31# Format: <port or port-range>[/<protocol>]
32# Example: PERMIT="80/tcp 53 2400-2500/tcp"
33# 2.) Listed NETWORKS or HOSTS will be allowed to connect to ANY service
34# on the firewall itself. This option should be used to specify machines
35# allowed to connect for administrative purposes.
36# Format: <host or network address>[/<netmask>]
37# Example: PERMIT="207.198.61.33 128.173.0.0/16"
38# NOTE (for advanced users): These networks and hosts will also be allowed to
39# bypass DENY_OUTBOUND and ALLOW_INBOUND restrictions for Linux routers.
40# 3.) Connections can be allowed from specific networks to specific ports by
41# listing entries in the following format:
42# Format:<host or network address>[/<netmask>]:<port or port-range>[/<protocol>]
43# Example: PERMIT="198.82.0.0/16:80/tcp" -- (Allow web traffic from 198.82.*.*)
44
45iptables -F
46
47
48# List internal (private) interfaces here to allow this machine to act as a
49# router. All interfaces NOT listed here are considered external (public)
50# and will be automatically protected by the firewall.
51# Example: INTERNAL_INTERFACES="eth1 eth2 brg0"
52
53#INTERNAL_INTERFACES="eth0"
54#INTERNAL_INTERFACES="lo"
55
56# List dial-up and other interfaces without a static IP address here.
57# Interfaces configured to obtain an IP address automatically (DHCP) do not
58# need to be listed here unless for some reason your DHCP client does not
59# receive the same address each time it renews the lease.
60# Example: DYNAMIC_INTERFACES="ppp0"
61
62DYNAMIC_INTERFACES=""
63
64# Most users do not need to change anything below this point.
65
66########################################
67# -- Advanced Configuration Options -- #
68########################################
69
70# ** DO NOT ** modify anything below unless you know what you are doing!!
71# See online documentation at: http://projectfiles.com/firewall/config.html
72
73DENY_OUTBOUND=""
74ALLOW_INBOUND=""
75BLACKLIST=""
76STATIC_INSIDE_OUTSIDE=""
77PORT_FORWARDS=""
78PORT_FWD_ALL="yes"
79PORT_FWD_ROUTED_NETWORKS="yes"
80ADDITIONAL_ROUTED_NETWORKS=""
81TRUST_ROUTED_NETWORKS="yes"
82SHARED_INTERNAL="yes"
83FIREWALL_IP=""
84TRUST_LOCAL_EXTERNAL_NETWORKS="no"
85DMZ_INTERFACES=""
86NAT_EXTERNAL="yes"
87ADDITIONAL_NAT_INTERFACES=""
88IGNORE_INTERFACES=""
89LOGGING="yes"
90REQUIRE_EXTERNAL_CONFIG="no"
91
92############################################
93# -- Advanced Firewall Behavior Options -- #
94############################################
95
96# The default settings provide the suggested firewall configuration.
97
98NO_RP_FILTER_INTERFACES=""
99INTERNAL_DHCP="yes"
100RFC_1122_COMPLIANT="yes"
101DROP_NEW_WITHOUT_SYN="no"
102DUMP_TCP_ON_INIT="no"
103TTL_STEALTH_ROUTER="no"
104LOG_LIMIT="1/minute"
105LOG_BURST="5"
106LOG_LEVEL="notice"
107
108###########################################################
109# -- Nothing below this point should need modification -- #
110###########################################################
111
112# Set version information.
113
114VERSION="2.0rc9"
115COMPATIBLE_VERSIONS="2.0rc9"
116
117# Welcome!
118
119echo "-> Projectfiles.com Linux Firewall version $VERSION running."
120
121# Set PATH explicitly.
122
123export PATH="/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin"
124
125# Tell everyone if we are loading data from an external configuration file.
126
127if [ "$1" == "update" ] || [ "$1" == "load" ] || [ "$1" == "fast" ] || \
128 [ "$1" == "save" ] || [ "$REQUIRE_EXTERNAL_CONFIG" == "yes" ] || \
129 ( [ "$1" == "check" ] && [ -n "$2" ] ); then
130 if [ -z "$2" ]; then
131 CONFIG="/etc/firewall.conf"
132 else
133 CONFIG=`echo $2 | sed s#^\./#$PWD/#`
134 fi
135 if [ "$1" != "save" ]; then
136 echo "-> Loading configuration from $CONFIG."
137 fi
138fi
139
140# Define exit/failure function.
141
142exit_failure() {
143 echo " [ FAILED ]"
144 echo "-> FATAL: $FAILURE" 1>&2
145 if [ "$1" != "check" ]; then
146 echo "-> Firewall configuration ** ABORTED **." 1>&2
147 fi
148 exit 1
149}
150
151# Sanity checking section
152
153echo -n "-> Performing sanity checks."
154
155# Make sure we are running the script with root privileges.
156
157#BK commented out...
158#if [ "$EUID" != "0" ]; then
159# FAILURE="You must have root privileges to configure the firewall."
160# exit_failure $1
161#fi
162
163# Make sure we have iptables installed.
164
165if (( `iptables -V 2>&1 | grep -c "command not found"` )); then
166 FAILURE="Cannot find 'iptables' command. Did you forget to install iptables?"
167 exit_failure $1
168fi
169
170# Add SysV style initialization support. (start and restart are the same as running the script without any arguments)
171
172if [ "$1" == "stop" ] || [ "$1" == "clear" ]; then
173 echo " [ PASSED ]"
174 iptables -t filter -F > /dev/null 2>&1
175 iptables -t filter -X > /dev/null 2>&1
176 iptables -t nat -F > /dev/null 2>&1
177 iptables -t nat -X > /dev/null 2>&1
178 iptables -t mangle -F > /dev/null 2>&1
179 iptables -t mangle -X > /dev/null 2>&1
180 iptables -t filter -P INPUT ACCEPT > /dev/null 2>&1
181 iptables -t filter -P OUTPUT ACCEPT > /dev/null 2>&1
182 iptables -t filter -P FORWARD ACCEPT > /dev/null 2>&1
183 iptables -t nat -P PREROUTING ACCEPT > /dev/null 2>&1
184 iptables -t nat -P POSTROUTING ACCEPT > /dev/null 2>&1
185 iptables -t nat -P OUTPUT ACCEPT > /dev/null 2>&1
186 iptables -t mangle -P POSTROUTING ACCEPT > /dev/null 2>&1
187 iptables -t mangle -P OUTPUT ACCEPT > /dev/null 2>&1
188 iptables -t mangle -P PREROUTING ACCEPT > /dev/null 2>&1
189 iptables -t mangle -P INPUT ACCEPT > /dev/null 2>&1
190 iptables -t mangle -P FORWARD ACCEPT > /dev/null 2>&1
191 if !(( `which modprobe 2>&1 | grep -c "which: no modprobe in"` )) && [ -a "/proc/modules" ]; then
192 for MODULE in ipt_TTL iptable_mangle ipt_mark ipt_MARK ipt_MASQUERADE \
193 ip_nat_irc ip_nat_ftp ipt_LOG ipt_limit ipt_REJECT \
194 ip_conntrack_irc ip_conntrack_ftp ipt_state iptable_nat \
195 iptable_filter ip_tables; do
196 if (( `lsmod | grep -c "$MODULE"` )); then
197 rmmod $MODULE > /dev/null 2>&1
198 fi
199 done
200 fi
201 echo "-> Firewall disabled."
202 exit
203fi
204
205# Cleanup tcp session dump rules. Note that ESTABLISHED TCP session can take up to 5 days to expire.
206
207if [ "$1" == "cleanup" ]; then
208 echo " [ PASSED ]"
209 COUNT=`iptables -nL INPUT | grep -c "tcp-reset"`
210 TAB=$COUNT
211 while [ "$((COUNT--))" -gt "0" ]; do
212 iptables -D INPUT 1
213 done
214 COUNT=`iptables -nL FORWARD | grep -c "tcp-reset"`
215 while [ "$((COUNT--))" -gt "0" ]; do
216 iptables -D FORWARD 1
217 done
218 echo "-> Old TCP session dump rules expunged ( $TAB )...."
219 exit
220fi
221
222# Check external configuration file.
223
224if [ "$1" == "update" ] || [ "$1" == "load" ] || [ "$1" == "fast" ] || \
225 ( [ "$REQUIRE_EXTERNAL_CONFIG" == "yes" ] && [ "$1" != "save" ] ) || \
226 ( [ "$1" == "check" ] && [ -n "$2" ] ); then
227 if [ -r "$CONFIG" ]; then
228 if (( `head -1 "$CONFIG" | grep -c "# Linux Firewall configuration -- http://projectfiles.com/firewall/"` )); then
229 CONFIG_VERSION='echo `head -4 "$CONFIG" | tail -1 | cut -d\\" -f2`'
230 if [ "$1" == "update" ] || (( $(echo "$COMPATIBLE_VERSIONS" | grep -c "`eval $CONFIG_VERSION`" ) )); then
231 . $CONFIG
232 else
233 if [ "$CONFIG" == "/etc/firewall.conf" ]; then
234 CONFIG=""
235 else
236 CONFIG=" $CONFIG"
237 fi
238 FAILURE="Configuration file outdated. Please run '$0 update$CONFIG'."
239 exit_failure $1
240 fi
241 else
242 FAILURE="The configuration file '$CONFIG' does not appear to be associated with this program. Refusing to load data."
243 exit_failure $1
244 fi
245 else
246 FAILURE="Cannot read from file '$CONFIG'. Did you forget to save your configuration with './rc.firewall save' or has the file moved?"
247 exit_failure $1
248 fi
249fi
250
251# Make sure we have proc filesystem support.
252
253if ! [ -a "/proc/version" ]; then
254 FAILURE="proc filesystem support required. Please mount /proc or add proc filesystem support in your kernel."
255 exit_failure $1
256fi
257
258# Create DUMP_TCP_ON_INIT function
259
260dump_tcp() {
261 echo -n "-> Dumping current TCP sessions...."
262 if [ "$1" != "fast" ]; then
263 sleep 1 # Allow a few moments for that last message to be delivered before we reset remote connections.
264 fi
265 COUNT=10
266 TAB=0
267 NET=`cat /proc/net/ip_conntrack | grep "^tcp" | grep ESTABLISHED | awk '{ gsub(/\ /,"\n"); print }'`
268 for ADDRESS in `echo "$NET" | sed -n $COUNT~20p | cut -d= -f2`; do
269 if !(( `echo $INTERNAL_ADDRESSES $EXTERNAL_ADDRESSES | grep -c "$ADDRESS"` )); then
270 DEST=`echo "$NET" | sed -n $((COUNT+1))~20p | cut -d= -f2 | head -1`
271 PORTS=`echo "$NET" | sed -n $((COUNT+2))~20p | cut -d= -f2 | head -1`
272 DPORTS=`echo "$NET" | sed -n $((COUNT+3))~20p | cut -d= -f2 | head -1`
273 iptables -I INPUT -s $ADDRESS -d $DEST -p tcp --sport $PORTS --dport $DPORTS -j REJECT --reject-with tcp-reset
274 if [ "$IS_ROUTER" == "yes" ]; then
275 iptables -I FORWARD -s $ADDRESS -d $DEST -p tcp --sport $PORTS --dport $DPORTS -j REJECT --reject-with tcp-reset
276 fi
277 TAB=$((TAB+1))
278 fi
279 COUNT=$((COUNT+20))
280 done
281 echo "( $TAB dumped )"
282}
283
284# Handle 'fast' argument.
285
286if [ "$1" == "fast" ]; then
287 if (( `which iptables-restore 2>&1 | grep -c "which: no iptables-restore in"` )); then
288 FAILURE="Required program 'iptables-restore' not found."
289 exit_failure $1
290 fi
291 echo " [ SKIPPED ]"
292 echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
293 for INTERFACE in $NO_RP_FILTER_INTERFACES; do
294 echo "0" > /proc/sys/net/ipv4/conf/$INTERFACE/rp_filter
295 done
296 cat $CONFIG | sed -n 40~1p | iptables-restore
297 if [ -n "$DYNAMIC_INTERFACES" ]; then
298 echo "1" > /proc/sys/net/ipv4/ip_dynaddr
299 else
300 echo "0" > /proc/sys/net/ipv4/ip_dynaddr
301 fi
302 if [ "$LOGGING" == "yes" ]; then
303 echo "1" > /proc/sys/net/ipv4/conf/all/log_martians
304 fi
305 if [ -n "$INTERNAL_INTERFACES" ] || [ -n "$PORT_FORWARDS" ]; then
306 echo "1" > /proc/sys/net/ipv4/ip_forward
307 else
308 echo "0" > /proc/sys/net/ipv4/ip_forward
309 fi
310 echo "-> Firewall configuration complete. No sanity checking was performed."
311 if [ "$DUMP_TCP_ON_INIT" == "yes" ]; then
312 dump_tcp fast
313 fi
314 exit
315fi
316
317# Create a few sanity checking functions.
318
319check_network() { # Checks NET variable.
320 FAILURE=""
321 HOST=`echo "$NET/" | cut -d/ -f1`
322 MASK=`echo "$NET/" | cut -d/ -f2` # Optional: Netfilter assumes /32 if not defined.
323 if (( `echo "$NET/" | cut -d/ -f3 | grep -c "."` )); then
324 FAILURE="Syntax error"
325 return 1
326 fi
327 if [ -z "$HOST" ]; then
328 FAILURE="Syntax error"
329 return 1
330 fi
331 for OCTET in 1 2 3 4; do
332 OCTET=`echo "$HOST." | cut -d. -f$OCTET --output-delimiter=" "`
333 if [ -z "$OCTET" ] || (( `echo "$OCTET" | grep -c "[^[:digit:]]"` )) || [ "$OCTET" -lt "0" ] || [ "$OCTET" -gt "255" ]; then
334 FAILURE="Network addresses must be in dotted decimal format"
335 return 1
336 fi
337 done
338 if (( `echo "$HOST." | cut -d. -f5 | grep -c "."` )); then
339 FAILURE="Network address must be in dotted decimal format"
340 return 1
341 fi
342 if [ -n "$MASK" ]; then
343 if (( `echo "$MASK" | grep -c "[^[:digit:]]"` )) || [ "$MASK" -lt "0" ] || [ "$MASK" -gt "32" ]; then
344 FAILURE="Network mask must be between '/0' (0.0.0.0) and '/32' (255.255.255.255) inclusive"
345 return 1
346 fi
347 else
348 if (( `echo "$NET" | grep -c "/"` )); then
349 FAILURE="Mask expected but not found"
350 return 1
351 fi
352 fi
353}
354
355check_ports() { # Checks PORTS variable.
356 FAILURE=""
357 RANGE=`echo "$PORTS/" | cut -d/ -f1`
358 PROTOCOL=`echo "$PORTS/" | cut -d/ -f2`
359 if (( `echo "$PORTS/" | cut -d/ -f3 | grep -c "."` )); then
360 FAILURE="Syntax error"
361 return 1
362 fi
363 if [ -z "$RANGE" ]; then
364 FAILURE="Syntax error"
365 return 1
366 fi
367 if (( `echo "$RANGE" | grep -c "[^[:digit:]]"` )) || [ "$RANGE" -lt "1" ] || [ "$RANGE" -gt "65535" ]; then
368 for PORT in `echo "$RANGE-" | cut -d- -f1,2 --output-delimiter=" "`; do
369 if (( `echo "$PORT" | grep -c "[^[:digit:]]"` )) || [ "$PORT" -lt "1" ] || [ "$PORT" -gt "65535" ]; then
370 FAILURE="Valid port numbers must be between 1 and 65535"
371 return 1
372 fi
373 done
374 if (( `echo "$RANGE-" | cut -d- -f3 | grep -c "."` )); then
375 FAILURE="Syntax error"
376 return 1
377 fi
378 fi
379 if [ -n "$PROTOCOL" ]; then
380 if ! ( [ "$PROTOCOL" == "tcp" ] || [ "$PROTOCOL" == "udp" ] ); then
381 FAILURE="Invalid protocol"
382 return 1
383 fi
384 else
385 if (( `echo "$PORTS" | grep -c "/"` )); then
386 FAILURE="Protocol expected but not found"
387 return 1
388 fi
389 fi
390}
391
392xbits() { # Set XBITS to the number of network bits that two addresses NET and NET1 are the same.
393 XBITS=0
394 for NUM in 1 2 3 4; do
395 OCTET=`echo "$NET./" | cut -d/ -f1 | cut -d. -f$NUM`
396 OCTET1=`echo "$NET1./" | cut -d/ -f1 | cut -d. -f$NUM`
397 if [ "$OCTET" == "$OCTET1" ]; then
398 XBITS=$((XBITS + 8))
399 continue
400 fi
401 for SUBTRACT in 128 64 32 16 8 4 2 1; do
402 if [ "$((OCTET - SUBTRACT))" -ge "0" ] && [ "$((OCTET1 - SUBTRACT))" -ge "0" ]; then
403 XBITS=$((XBITS + 1))
404 OCTET=$((OCTET - SUBTRACT))
405 OCTET1=$((OCTET1 - SUBTRACT))
406 elif [ "$((OCTET - SUBTRACT))" -lt "0" ] && [ "$((OCTET1 - SUBTRACT))" -lt "0" ]; then
407 XBITS=$((XBITS + 1))
408 else
409 return
410 fi
411 done
412 done
413}
414
415# Save selected variable settings if we are going to back up our configuration.
416
417if [ "$1" == "save" ] || [ "$1" == "update" ]; then
418 if (( `which iptables-save 2>&1 | grep -c "which: no iptables-save in"` )); then
419 FAILURE="iptables-save not found; required for '$1' argument."
420 exit_failure $1
421 fi
422 if [ "$1" == "update" ]; then
423 PERMIT=`echo $PERMIT $TRUSTED_NETWORKS $OPEN_PORTS`
424 OPEN_PORTS=""
425 fi
426 ORIG_PERMIT="$PERMIT"
427 ORIG_INTERNAL_INTERFACES="$INTERNAL_INTERFACES"
428 ORIG_PORT_FORWARDS="$PORT_FORWARDS"
429 ORIG_ALLOW_INBOUND="$ALLOW_INBOUND"
430 ORIG_DENY_OUTBOUND="$DENY_OUTBOUND"
431 ORIG_DYNAMIC_INTERFACES="$DYNAMIC_INTERFACES"
432 ORIG_STATIC_INSIDE_OUTSIDE="$STATIC_INSIDE_OUTSIDE"
433fi
434
435# Add DMZ interfaces to list of internal interfaces.
436
437if [ -n "$DMZ_INTERFACES" ]; then
438 INTERNAL_INTERFACES="$INTERNAL_INTERFACES $DMZ_INTERFACES"
439fi
440
441# Remove duplicate internal interfaces.
442
443if [ -n "$INTERNAL_INTERFACES" ]; then
444 for INTERFACE in $INTERNAL_INTERFACES; do
445 if !(( `echo "$MOD_INTERFACES" | grep -c "$INTERFACE"` )); then
446 MOD_INTERFACES="$MOD_INTERFACES $INTERFACE"
447 fi
448 done
449 INTERNAL_INTERFACES=`echo $MOD_INTERFACES`
450fi
451
452# Determine if we are a router.
453
454if [ -n "$INTERNAL_INTERFACES" ] || [ -n "$PORT_FORWARDS" ]; then
455 IS_ROUTER="yes"
456fi
457
458# Sanity check PERMIT and BLACKLIST.
459
460for PARAM in PERMIT BLACKLIST; do
461 if [ "$PARAM" == "PERMIT" ]; then
462 ITEM="$PERMIT"
463 else
464 ITEM="$BLACKLIST"
465 fi
466 for NETWORK in $ITEM; do
467 NET=`echo "$NETWORK:" | cut -d: -f1`
468 PORTS=`echo "$NETWORK:" | cut -d: -f2`
469 if (( `echo "$NETWORK:" | cut -d: -f3 | grep -c "."` )); then
470 FAILURE="Syntax error in $PARAM."
471 exit_failure $1
472 fi
473 if ! check_network; then
474 PORTS="$NET"
475 FAIL="$FAILURE in $PARAM."
476 if ! check_ports; then
477 FAILURE="$FAIL"
478 exit_failure $1
479 fi
480 fi
481 if [ -n "$PORTS" ]; then
482 if ! check_ports; then
483 FAILURE="$FAILURE in $PARAM."
484 exit_failure $1
485 fi
486 fi
487 done
488done
489
490echo -n "."
491
492# Remove entries with ports and put them in their own variable.
493
494if [ -n "$PERMIT" ]; then
495 for NETWORK in $PERMIT; do
496 NET=`echo "$NETWORK:" | cut -d: -f1`
497 PORTS=`echo "$NETWORK:" | cut -d: -f2`
498 if [ -z "$PORTS" ]; then
499 if ! check_network; then
500 OPEN_PORTS="$OPEN_PORTS $NET"
501 else
502 TEMP_PERMIT="$TEMP_PERMIT $NET"
503 fi
504 else
505 PROTOCOL=`echo "$PORTS/" | cut -d/ -f2`
506 if [ "$PROTOCOL" == "tcp" ] || [ "$PROTOCOL" == "udp" ]; then
507 TRUSTED_PORTS="$TRUSTED_PORTS $NET:$PORTS/$PROTOCOL"
508 else
509 TRUSTED_PORTS="$TRUSTED_PORTS $NET:$PORTS/tcp"
510 TRUSTED_PORTS="$TRUSTED_PORTS $NET:$PORTS/udp"
511 fi
512 fi
513 done
514 PERMIT=`echo $TEMP_PERMIT`
515 TRUSTED_PORTS=`echo $TRUSTED_PORTS`
516 OPEN_PORTS=`echo $OPEN_PORTS`
517fi
518
519# Sanity check additional routed networks.
520
521if [ -n "$INTERNAL_INTERFACES" ]; then
522 for NET in $ADDITIONAL_ROUTED_NETWORKS; do
523 if ! check_network; then
524 FAILURE="$FAILURE in ADDITIONAL_ROUTED_NETWORKS."
525 exit_failure $1
526 fi
527 done
528fi
529
530# Sanity check port forwarding definitions. Protocol and destination ports are optional.
531
532if [ -n "$PORT_FORWARDS" ]; then
533 for FORWARD in $PORT_FORWARDS; do
534 if (( `echo "$FORWARD:" | cut -d: -f5 | grep -c "."` )); then
535 FAILURE="Syntax error in PORT_FORWARDS."
536 exit_failure $1
537 fi
538 PROTOCOL=`echo "$FORWARD:" | cut -d: -f1`
539 if [ "$PROTOCOL" != "tcp" ] && [ "$PROTOCOL" != "udp" ]; then
540 COUNT="1"
541 MOD_FORWARDS="$MOD_FORWARDS tcp:$FORWARD udp:$FORWARD"
542 PROT=""
543 else
544 COUNT="0"
545 MOD_FORWARDS="$MOD_FORWARDS $FORWARD"
546 PROT="/$PROTOCOL"
547 fi
548 PORTS=`echo "$FORWARD:" | cut -d: -f$((2-COUNT))`
549 FAILURE="Invalid syntax "
550 if ! check_ports || [ -n "$PROTOCOL" ]; then
551 FAILURE="$FAILURE in PORT_FORWARDS."
552 exit_failure $1
553 fi
554 if [ "$PORT_FWD_ALL" == "yes" ]; then
555 for TAB in NULL; do
556 for PORT in $OPEN_PORTS; do
557 if [ "$PORT" == "${PORTS}$PROT" ]; then
558 break 2
559 fi
560 done
561 OPEN_PORTS="$OPEN_PORTS ${PORTS}$PROT"
562 done
563 fi
564 NET=`echo "$FORWARD:" | cut -d: -f$((3-COUNT))`
565 FAILURE="Destination must be a single host"
566 if ! check_network || [ -n "$MASK" ]; then
567 FAILURE="$FAILURE in PORT_FORWARDS."
568 exit_failure $1
569 fi
570 PORTS=`echo "$FORWARD:" | cut -d: -f$((4-COUNT))`
571 if [ -n "$PORTS" ]; then
572 FAILURE="Invalid syntax"
573 if ! check_ports || [ -n "$PROTOCOL" ]; then
574 FAILURE="$FAILURE in PORT_FORWARDS."
575 exit_failure $1
576 fi
577 fi
578 done
579 PORT_FORWARDS=`echo $MOD_FORWARDS`
580 OPEN_PORTS=`echo $OPEN_PORTS`
581fi
582
583# Sanity check open ports. Expand undefined protocols into tcp and udp.
584
585if [ -n "$OPEN_PORTS" ]; then
586 for PORTS in $OPEN_PORTS; do
587 if ! check_ports; then
588 FAILURE="$FAILURE in OPEN_PORTS."
589 exit_failure $1
590 fi
591 if [ "$PROTOCOL" == "tcp" ] || [ "$PROTOCOL" == "udp" ]; then
592 MOD_PORTS="$MOD_PORTS $PORTS"
593 else
594 MOD_PORTS="$MOD_PORTS $PORTS/tcp $PORTS/udp"
595 fi
596 done
597 OPEN_PORTS=`echo $MOD_PORTS`
598fi
599
600# Sanity check static inside,outside translations.
601
602if [ -n "$STATIC_INSIDE_OUTSIDE" ]; then
603 MOD_STATIC=""
604 for FORWARD in $STATIC_INSIDE_OUTSIDE; do
605 if (( `echo "$FORWARD:" | cut -d: -f3 | grep -c "."` )); then
606 FAILURE="Syntax error in STATIC_INSIDE_OUTSIDE."
607 exit_failure $1
608 fi
609 NET=`echo "$FORWARD:" | cut -d: -f1`
610 if ! check_network; then
611 FAILURE="$FAILURE in STATIC_INSIDE_OUTSIDE."
612 exit_failure $1
613 fi
614 NET1=`echo $NET | cut -d\/ -f1`
615 STROKE="$MASK"
616 NET=`echo "$FORWARD:" | cut -d: -f2`
617 if ! check_network; then
618 FAILURE="$FAILURE in STATIC_INSIDE_OUTSIDE."
619 exit_failure $1
620 fi
621 if [ -n "$MASK" ]; then
622 if [ "$STROKE" != "$MASK" ]; then
623 FAILURE="If outside address in STATIC_INSIDE_OUTSIDE has a netmask, it must be the same as the inside address."
624 exit_failure $1
625 fi
626 if [ "$MASK" -lt "24" ]; then
627 FAILURE="Networks larger than class C (254 hosts) are not supported on the OUTSIDE address of STATIC_INSIDE_OUTSIDE."
628 exit_failure $1
629 fi
630 TAB="1"
631 NET=`echo $NET | cut -d\/ -f1`
632 COUNT=`echo $NET | cut -d. -f4`
633 if [ "$COUNT" -ne "`echo $NET1 | cut -d. -f4`" ]; then
634 FAILURE="When using a subnet mask on the OUTSIDE address in STATIC_INSIDE_OUTSIDE, last octet of both inside and outside addresses must be the same."
635 exit_failure $1
636 fi
637 NET1=`echo $NET1 | cut -d. -f1,2,3`
638 NET=`echo $NET | cut -d. -f1,2,3`
639 while [ "$MASK" -lt "32" ]; do
640 TAB=$((TAB * 2))
641 MASK=$((MASK+1))
642 done
643 STROKE="$TAB"
644 while [ "$TAB" -gt "0" ]; do
645 TAB=$((TAB-1))
646 OCTET=$((COUNT-(COUNT%STROKE)+TAB))
647 if [ "$OCTET" != "0" ] && [ "$OCTET" != "255" ]; then
648 MOD_STATIC="$MOD_STATIC $NET1.$OCTET:$NET.$OCTET"
649 fi
650 done
651 else
652 MOD_STATIC="$MOD_STATIC $FORWARD"
653 fi
654 done
655 STATIC_INSIDE_OUTSIDE=`echo $MOD_STATIC`
656fi
657
658# Sanity check FIREWALL_IP.
659
660for ADDRESS in $FIREWALL_IP; do
661 if (( `echo "$ADDRESS:" | cut -d: -f3 | grep -c "."` )); then
662 FAILURE="Syntax error in FIREWALL_IP."
663 exit_failure $1
664 fi
665 NET=`echo "$ADDRESS:" | cut -d: -f1`
666 if ! check_network; then
667 FAILURE="$FAILURE in FIREWALL_IP."
668 exit_failure $1
669 fi
670 if [ -n "$MASK" ]; then
671 FAILURE="FIREWALL_IP may not contain network masks."
672 exit_failure $1
673 fi
674 NET=`echo "$ADDRESS:" | cut -d: -f2`
675 if ! check_network; then
676 FAILURE="$FAILURE in FIREWALL_IP."
677 exit_failure $1
678 fi
679 if [ -n "$MASK" ]; then
680 FAILURE="FIREWALL_IP may not contain network masks."
681 exit_failure $1
682 fi
683done
684
685# Make sure dynamic, nat, and rp_filter interface definitions do not use IP aliases.
686
687if (( `echo "$INTERNAL_INTERFACES $DYNAMIC_INTERFACES $NO_RP_FILTER_INTERFACES $ADDITIONAL_NAT_INTERFACES" | grep -c ":"` )); then
688 FAILURE="Definitions cannot contain IP aliases."
689 exit_failure $1
690fi
691
692# Obtain list of external interfaces.
693
694EXTERNAL_INTERFACES=`ifconfig | grep "^[[:alpha:]]" | cut -d\ -f1 | sed s/^lo.*//`
695PARAM=`echo $EXTERNAL_INTERFACES`
696for INTERFACE in $INTERNAL_INTERFACES; do
697 EXTERNAL_INTERFACES=`echo "$EXTERNAL_INTERFACES" | sed s/^$INTERFACE//`
698done
699for INTERFACE in $PARAM; do
700 if !(( `echo "$EXTERNAL_INTERFACES $INTERNAL_INTERFACES" | grep -c "$INTERFACE"` )); then
701 INTERNAL_INTERFACES="$INTERNAL_INTERFACES $INTERFACE"
702 fi
703done
704EXTERNAL_INTERFACES=`echo $EXTERNAL_INTERFACES | sed 's/[^0-9]\:[0-9]\+//g'` # Cleanup.
705for INTERFACE in $IGNORE_INTERFACES; do
706 if !(( `echo "$EXTERNAL_INTERFACES" | grep -c "$INTERFACE"` )); then
707 FAILURE="Interface specified to IGNORE was not found. Check the configuration."
708 exit_failure $1
709 else
710 EXTERNAL_INTERFACES=`echo $EXTERNAL_INTERFACES | sed s#$INTERFACE##g`
711 fi
712done
713EXTERNAL_INTERFACES=`echo $EXTERNAL_INTERFACES` # Remove whitespace.
714
715echo -n "."
716
717# Divide internal and external interfaces into static and dynamic groups.
718
719for INTERFACE in $INTERNAL_INTERFACES; do
720 if (( `echo "$DYNAMIC_INTERFACES" | grep -c "$INTERFACE"` )); then
721 if [ -n "$DMZ_INTERFACES" ]; then
722 FAILURE="Cannot have dynamic internal interfaces with a DMZ."
723 exit_failure $1
724 fi
725 DYNAMIC_INTERNAL_INTERFACES="$DYNAMIC_INTERNAL_INTERFACES $INTERFACE"
726 else
727 STATIC_INTERNAL_INTERFACES="$STATIC_INTERNAL_INTERFACES $INTERFACE"
728 fi
729done
730for INTERFACE in $EXTERNAL_INTERFACES; do
731 if (( `echo "$DYNAMIC_INTERFACES" | grep -c "$(echo $INTERFACE | cut -d: -f1)"` )); then
732 if !(( `echo "$INTERFACE" | grep -c ":"` )); then
733 DYNAMIC_EXTERNAL_INTERFACES="$DYNAMIC_EXTERNAL_INTERFACES $INTERFACE"
734 fi
735 else
736 STATIC_EXTERNAL_INTERFACES="$STATIC_EXTERNAL_INTERFACES $INTERFACE"
737 fi
738done
739for INTERFACE in $DYNAMIC_INTERFACES; do
740 if !(( `echo "$INTERNAL_INTERFACES $EXTERNAL_INTERFACES" | grep -c "$INTERFACE"` )); then
741 DYNAMIC_EXTERNAL_INTERFACES="$DYNAMIC_EXTERNAL_INTERFACES $INTERFACE"
742 fi
743done
744DYNAMIC_INTERNAL_INTERFACES=`echo $DYNAMIC_INTERNAL_INTERFACES`
745DYNAMIC_EXTERNAL_INTERFACES=`echo $DYNAMIC_EXTERNAL_INTERFACES`
746STATIC_INTERNAL_INTERFACES=`echo $STATIC_INTERNAL_INTERFACES`
747STATIC_EXTERNAL_INTERFACES=`echo $STATIC_EXTERNAL_INTERFACES`
748
749# If we are configured to be a router, then make sure we have somewhere to route traffic.
750
751if [ -n "$INTERNAL_INTERFACES" ] && ( [ -z "$STATIC_EXTERNAL_INTERFACES" ] && [ -z "$DYNAMIC_EXTERNAL_INTERFACES" ] ); then
752 if (( `echo "$INTERNAL_INTERFACES" | wc -w | grep -c "1"` )); then
753 FAILURE="Routing enabled, with no place to route traffic! Did you forget to ifconfig an interface, or list DYNAMIC_INTERFACES?"
754 exit_failure $1
755 fi
756fi
757
758# Obtain list of interfaces to NAT outbound connections
759
760if [ "$IS_ROUTER" == "yes" ]; then
761 if [ "$NAT_EXTERNAL" == "yes" ]; then
762 for INTERFACE in $STATIC_EXTERNAL_INTERFACES; do
763 if !(( `echo "$INTERFACE" | grep -c ":"` )); then
764 STATIC_NAT_INTERFACES="$STATIC_NAT_INTERFACES $INTERFACE"
765 fi
766 done
767 for INTERFACE in $DYNAMIC_EXTERNAL_INTERFACES; do
768 if !(( `echo "$INTERFACE" | grep -c ":"` )); then
769 DYNAMIC_NAT_INTERFACES="$DYNAMIC_NAT_INTERFACES $INTERFACE"
770 fi
771 done
772 fi
773 for INTERFACE in $ADDITIONAL_NAT_INTERFACES; do
774 if (( `echo "$DYNAMIC_INTERFACES" | grep -c "$INTERFACE"` )); then
775 DYNAMIC_NAT_INTERFACES="$DYNAMIC_NAT_INTERFACES $INTERFACE"
776 else
777 STATIC_NAT_INTERFACES="$STATIC_NAT_INTERFACES $INTERFACE"
778 fi
779 done
780fi
781
782# If we are a router, check that all static internal interfaces are up.
783
784for INTERFACE in $STATIC_INTERNAL_INTERFACES; do
785 if !(( `ifconfig | grep -c "^$INTERFACE\ "` )); then
786 FAILURE="A static internal interface is down. Did you forgot to configure interfaces before running the firewall?"
787 exit_failure $1
788 fi
789done
790
791# Obtain list of NAT addresses if we are a router doing nat.
792
793if [ -n "$STATIC_NAT_INTERFACES" ]; then
794 for INTERFACE in $STATIC_NAT_INTERFACES; do
795 ADDRESS=`ifconfig | grep "^$INTERFACE\ " -A1 | grep "inet" | cut -d: -f2 | cut -d\ -f1 | head -1`
796 if [ -z "$ADDRESS" ]; then
797 echo " [ WAIT ]"
798 echo -n "-> $INTERFACE has no IP address. Waiting for DHCP"
799 for COUNT in 1 2 3 4 5 6 7 8 9 10; do
800 sleep 1
801 echo -n "."
802 ADDRESS=`ifconfig | grep "^$INTERFACE\ " -A1 | grep "inet" | cut -d: -f2 | cut -d\ -f1 | head -1`
803 if [ -n "$ADDRESS" ]; then
804 echo " [ FOUND ]"
805 break
806 else
807 if [ "$COUNT" == "10" ]; then
808 echo " [ MISSING ]"
809 echo "-> WARNING: IP address for $INTERFACE not found. Coverting to dynamic interface."
810 DYNAMIC_EXTERNAL_INTERFACES="$DYNAMIC_EXTERNAL_INTERFACES $INTERFACE"
811 DYNAMIC_INTERFACES="$DYNAMIC_INTERFACES $INTERFACE"
812 if [ "$NAT_EXTERNAL" == "yes" ]; then
813 DYNAMIC_NAT_INTERFACES="$DYNAMIC_NAT_INTERFACES $INTERFACE"
814 fi
815 for INT in $STATIC_EXTERNAL_INTERFACES; do
816 if [ "$INTERFACE" != "$INT" ]; then
817 MOD_STATIC_EXTERNAL_INTERFACES="$MOD_STATIC_EXTERNAL_INTERFACES $INTERFACE"
818 fi
819 done
820 STATIC_EXTERNAL_INTERFACES=`echo $MOD_STATIC_EXTERNAL_INTERFACES`
821 fi
822 fi
823 done
824 echo -n "-> Continuing sanity checks.."
825 else
826 MOD_STATIC_NAT_INTERFACES="$MOD_STATIC_NAT_INTERFACES $INTERFACE"
827 if [ -n "$FIREWALL_IP" ]; then
828 for FORWARD in $FIREWALL_IP; do
829 if [ `echo "$FORWARD" | cut -d: -f1` == "$ADDRESS" ]; then
830 ADDRESS=`echo "$FORWARD" | cut -d: -f2`
831 fi
832 done
833 fi
834 NAT_ADDRESSES="$NAT_ADDRESSES $ADDRESS"
835 fi
836 done
837 STATIC_NAT_INTERFACES=`echo $MOD_STATIC_NAT_INTERFACES`
838 NAT_ADDRESSES=`echo $NAT_ADDRESSES`
839fi
840
841echo -n "."
842
843# Determine if this is a modular kernel, if so modprobe the required modules.
844
845if !(( `which modprobe 2>&1 | grep -c "which: no modprobe in"` )) && [ -a "/proc/modules" ]; then
846 if (( `lsmod | grep -c "ipchains"` )); then
847 rmmod ipchains > /dev/null 2>&1
848 fi
849 REQUIRED_MODULES="ip_tables ip_conntrack ipt_state iptable_filter ip_conntrack_irc ip_conntrack_ftp"
850 if [ "$RFC_1122_COMPLIANT" == "yes" ]; then
851 REQUIRED_MODULES="$REQUIRED_MODULES ipt_REJECT"
852 fi
853 if [ "$LOGGING" == "yes" ]; then
854 REQUIRED_MODULES="$REQUIRED_MODULES ipt_LOG ipt_limit"
855 fi
856 if [ "$IS_ROUTER" == "yes" ]; then
857 if [ -n "$STATIC_NAT_INTERFACES" ] || [ -n "$DYNAMIC_NAT_INTERFACES" ] || \
858 [ -n "$PORT_FORWARDS" ] || [ -n "$STATIC_INSIDE_OUTSIDE" ]; then
859 REQUIRED_MODULES="$REQUIRED_MODULES iptable_nat ip_nat_irc ip_nat_ftp"
860 if [ -n "$DYNAMIC_NAT_INTERFACES" ] || \
861 ( [ -n "$DYNAMIC_INTERFACES" ] && ( [ -n "$PORT_FORWARDS" ] || [ -n "$STATIC_INSIDE_OUTSIDE" ] ) ); then
862 REQUIRED_MODULES="$REQUIRED_MODULES ipt_MASQUERADE"
863 fi
864 fi
865 if [ -n "$PORT_FORWARDS" ] || [ "$TTL_STEALTH_ROUTER" == "yes" ]; then
866 REQUIRED_MODULES="$REQUIRED_MODULES iptable_mangle"
867 fi
868 if [ -n "$PORT_FORWARDS" ]; then
869 REQUIRED_MODULES="$REQUIRED_MODULES ipt_mark ipt_MARK"
870 fi
871 if [ "$TTL_STEALTH_ROUTER" == "yes" ]; then
872 REQUIRED_MODULES="$REQUIRED_MODULES ipt_TTL"
873 fi
874 fi
875 for MODULE in $REQUIRED_MODULES; do
876 #BK v3.94 some of the module names may be old names, but are an alias to
877 #the actual module name. for example ip_conntrack_ftp is now an alias to
878 #nf_conntrack_ftp. modinfo can report the alias, but only after the module
879 #is fetched from the zdrv file. The following modprobe -l only lists actual
880 #module names not aliases. Fix: comment out the if...
881 #if (( `modprobe -l | grep -c "$MODULE"` )); then
882 modprobe $MODULE > /dev/null 2>&1
883 #fi
884 done
885fi
886
887# Obtain list of internal networks with subnet masks corresponding to internal interfaces.
888
889if [ -n "$STATIC_INTERNAL_INTERFACES" ]; then
890 for INTERFACE in $STATIC_INTERNAL_INTERFACES; do
891 STROKE="0"
892 MASK=`ifconfig | grep "^$INTERFACE\ " -A1 | grep "Mask" | cut -d: -f4 | head -1`
893 for OCTET in 1 2 3 4; do
894 BINARY=`echo "$MASK" | cut -d. -f$OCTET`
895 for SUBTRACT in 128 64 32 16 8 4 2 1; do
896 if [ "$((BINARY - SUBTRACT))" -ge "0" ]; then
897 BINARY=$((BINARY - SUBTRACT))
898 STROKE=$((STROKE + 1))
899 fi
900 done
901 done
902 ADDRESS=`ifconfig | grep "^$INTERFACE\ " -A1 | grep "inet" | cut -d: -f2 | cut -d\ -f1 | head -1`
903 INTERNAL_ADDRESSES="$INTERNAL_ADDRESSES $ADDRESS"
904 INTERNAL_NETWORKS="$INTERNAL_NETWORKS $ADDRESS/$STROKE"
905 if [ -z "$DMZ_INTERFACES" ] || !(( `echo "$DMZ_INTERFACES" | grep -c "$INTERFACE"` )); then
906 NAT_NETWORKS="$NAT_NETWORKS $ADDRESS/$STROKE"
907 fi
908 done
909 INTERNAL_ADDRESSES=`echo $INTERNAL_ADDRESSES`
910 INTERNAL_NETWORKS=`echo $INTERNAL_NETWORKS`
911 NAT_NETWORKS=`echo $NAT_NETWORKS`
912fi
913
914# Obtain a list of external addresses.
915
916if [ -n "$STATIC_EXTERNAL_INTERFACES" ]; then
917 for INTERFACE in $STATIC_EXTERNAL_INTERFACES; do
918 STROKE="0"
919 MASK=`ifconfig | grep "^$INTERFACE\ " -A1 | grep "Mask" | cut -d: -f4 | head -1`
920 for OCTET in 1 2 3 4; do
921 BINARY=`echo "$MASK" | cut -d. -f$OCTET`
922 for SUBTRACT in 128 64 32 16 8 4 2 1; do
923 if [ "$((BINARY - SUBTRACT))" -ge "0" ]; then
924 BINARY=$((BINARY - SUBTRACT))
925 STROKE=$((STROKE + 1))
926 fi
927 done
928 done
929 ADDRESS=`ifconfig | grep "^$INTERFACE\ " -A1 | grep "inet" | cut -d: -f2 | cut -d\ -f1 | head -1`
930 EXTERNAL_ADDRESSES="$EXTERNAL_ADDRESSES $ADDRESS"
931 EXTERNAL_NETWORKS="$EXTERNAL_NETWORKS $ADDRESS/$STROKE"
932 done
933 EXTERNAL_ADDRESSES=`echo $EXTERNAL_ADDRESSES`
934 EXTERNAL_NETWORKS=`echo $EXTERNAL_NETWORKS`
935fi
936
937# Make a table of interfaces for marking packets based on their incoming interface for port forwarding.
938
939if [ -n "$PORT_FORWARDS" ]; then
940 COUNT="0"
941 TAB="1"
942 for INTERFACE in $STATIC_INTERNAL_INTERFACES $STATIC_EXTERNAL_INTERFACES; do
943 COUNT=$((COUNT + 1))
944 ADDRESS=`echo $INTERNAL_ADDRESSES $EXTERNAL_ADDRESSES | cut -d\ -f$COUNT`
945 # Do not forward packets destined for an address in STATIC_INSIDE_OUTSIDE.
946 if !(( `echo "$STATIC_INSIDE_OUTSIDE" | awk '{ gsub(/\ /,"\n"); print }' | \
947 cut -d: -f2 | grep -c "$ADDRESS"` )); then
948 if [ -n "$FIREWALL_IP" ]; then
949 # Nobody will ever use the address of the private network between us and our gateway for port forwarding.
950 if (( `echo "$FIREWALL_IP" | awk '{ gsub(/\ /,"\n"); print }' | \
951 cut -d: -f2 | grep -c "$ADDRESS"` )); then
952 continue
953 fi
954 if (( `echo "$FIREWALL_IP" | awk '{ gsub(/\ /,"\n"); print }' | \
955 cut -d: -f1 | grep -c "$ADDRESS"` )); then
956 ADDRESS=`echo "$FIREWALL_IP" | awk '{ gsub(/\ /,"\n"); print }' | \
957 grep "$ADDRESS" | cut -d: -f2`
958 fi
959 fi
960 INTERFACE=`echo "$INTERFACE" | cut -d: -f1`
961 INTERFACE_TAB[$TAB]="$INTERFACE"
962 ADDRESS_TAB[$TAB]="$ADDRESS"
963 PORT_FORWARD_ADDRESSES="$PORT_FORWARD_ADDRESSES $ADDRESS"
964 if [ "$PORT_FWD_ROUTED_NETWORKS" == "yes" ]; then
965 if (( `echo "$STATIC_INTERNAL_INTERFACES" | grep -c "$INTERFACE"` )); then
966 NETWORK_TAB[$TAB]="$ADDITIONAL_ROUTED_NETWORKS $(echo "$INTERNAL_NETWORKS" | cut -d\ -f$COUNT)"
967 fi
968 fi
969 TAB=$((TAB + 1))
970 fi
971 done
972 for INTERFACE in $DYNAMIC_INTERNAL_INTERFACES $DYNAMIC_EXTERNAL_INTERFACES; do
973 INTERFACE_TAB[$TAB]="$INTERFACE"
974 TAB=$((TAB + 1))
975 done
976 PORT_FORWARD_ADDRESSES=`echo $PORT_FORWARD_ADDRESSES`
977fi
978
979# Obtain broadcast list if we are doing logging (so that we will not log them).
980# We have to do this before we hax0r STATIC_INTERNAL_INTERFACES.
981
982if [ "$LOGGING" == "yes" ]; then
983 BCAST_LIST="255.255.255.255"
984 for INTERFACE in $STATIC_INTERNAL_INTERFACES $STATIC_EXTERNAL_INTERFACES; do
985 BROADCAST=`ifconfig | grep "^$INTERFACE\ " -A1 | grep "Bcast" | cut -d: -f3 | cut -d\ -f1 | head -1`
986 if !(( `echo "$BCAST_LIST" | grep -c "$BROADCAST"` )); then
987 BCAST_LIST="$BCAST_LIST $BROADCAST"
988 fi
989 done
990fi
991
992# Remove redundant networks from INTERNAL_INTERFACES, STATIC_INTERNAL_INTERFACES, and INTERNAL_NETWORKS.
993
994if [ -n "$INTERNAL_NETWORKS" ]; then
995 CHANGE=1
996 until [ "$CHANGE" == "0" ]; do
997 COUNT=0
998 CHANGE=0
999 for NET in $INTERNAL_NETWORKS; do
1000 TAB=0
1001 COUNT=$((COUNT + 1))
1002 INTERFACE=`echo "$STATIC_INTERNAL_INTERFACES" | cut -d\ -f$COUNT`
1003 STROKE=`echo "$NET" | cut -d/ -f2`
1004 for NET1 in $INTERNAL_NETWORKS; do
1005 TAB=$((TAB + 1))
1006 INTERFACE1=`echo "$STATIC_INTERNAL_INTERFACES" | cut -d\ -f$TAB`
1007 if [ "$INTERFACE" == "$INTERFACE1" ]; then
1008 continue # Obviously we don't want to compare a network to itself.'
1009 fi
1010 PARAM=`echo "$INTERFACE1" | cut -d: -f1`
1011 if !(( `echo "$INTERFACE" | cut -d: -f1 | grep -c "$PARAM"` )); then
1012 continue # We only want to compare networks attached to the same interface.
1013 fi
1014 MASK=`echo "$NET1/" | cut -d/ -f2`
1015 xbits
1016 if [ "$STROKE" -le "$MASK" ]; then # Then NET defines a larger network than NET1.
1017 if [ "$XBITS" -ge "$STROKE" ]; then # Then delete the second one if they are the same up to STROKE.
1018 INTERNAL_NETWORKS=`echo "$INTERNAL_NETWORKS" | sed s#$NET1##`
1019 INTERNAL_NETWORKS=`echo $INTERNAL_NETWORKS`
1020 STATIC_INTERNAL_INTERFACES=`echo "$STATIC_INTERNAL_INTERFACES" | sed s#$INTERFACE1##`
1021 STATIC_INTERNAL_INTERFACES=`echo $STATIC_INTERNAL_INTERFACES`
1022 if [ -z "$DMZ_INTERFACES" ] || !(( `echo "$DMZ_INTERFACES" | grep -c "$PARAM"` )); then
1023 NAT_NETWORKS=`echo "$NAT_NETWORKS" | sed s#$NET1##`
1024 NAT_NETWORKS=`echo $NAT_NETWORKS`
1025 fi
1026 CHANGE=1
1027 continue 3
1028 fi
1029 elif [ "$XBITS" -ge "$MASK" ]; then # Else delete the first one (provided it is still the same interface).
1030 INTERNAL_NETWORKS=`echo "$INTERNAL_NETWORKS" | sed s#$NET##`
1031 INTERNAL_NETWORKS=`echo $INTERNAL_NETWORKS`
1032 STATIC_INTERNAL_INTERFACES=`echo "$STATIC_INTERNAL_INTERFACES" | sed s#$INTERFACE##`
1033 STATIC_INTERNAL_INTERFACES=`echo $STATIC_INTERNAL_INTERFACES`
1034 if [ -z "$DMZ_INTERFACES" ] || !(( `echo "$DMZ_INTERFACES" | grep -c "$PARAM"` )); then
1035 NAT_NETWORKS=`echo "$NAT_NETWORKS" | sed s#$NET##`
1036 NAT_NETWORKS=`echo $NAT_NETWORKS`
1037 fi
1038 CHANGE=1
1039 continue 3
1040 fi
1041 done
1042 done
1043 done
1044fi
1045
1046echo -n "."
1047
1048# Sanity check ALLOW_INBOUND and DENY_OUTBOUND and compare against INTERNAL_NETWORKS.
1049
1050if [ -n "$ALLOW_INBOUND" ] || [ -n "$DENY_OUTBOUND" ]; then
1051 for PARAM in DENY_OUTBOUND ALLOW_INBOUND; do
1052 if [ "$PARAM" == "DENY_OUTBOUND" ]; then
1053 LIST="$DENY_OUTBOUND"
1054 else
1055 LIST="$ALLOW_INBOUND"
1056 fi
1057 for FORWARD in $LIST; do
1058 for TEMP in NULL; do # You'll see why.
1059 if (( `echo "$FORWARD:" | cut -d: -f4 | grep -c "."` )); then
1060 FAILURE="Too many parameters in $PARAM."
1061 exit_failure $1
1062 fi
1063 NET=`echo "$FORWARD:" | cut -d: -f1`
1064 if [ -n "$NET" ] && ! check_network; then
1065 PORTS="$NET"
1066 if ! check_ports; then
1067 FAILURE="Syntax error in $PARAM."
1068 exit_failure $1
1069 else
1070 eval TEMP_$PARAM="any:any:$PORTS"
1071 break
1072 fi
1073 elif [ -z "$NET" ]; then
1074 NET="any"
1075 else
1076 if [ "$PARAM" == "DENY_OUTBOUND" ]; then
1077 STROKE=`echo "$NET/" | cut -d/ -f2`
1078 if [ -z "$STROKE" ]; then
1079 STROKE=32
1080 fi
1081 for TAB in NULL; do
1082 for NET1 in $INTERNAL_NETWORKS $ADDITIONAL_ROUTED_NETWORKS; do
1083 MASK=`echo "$NET1/" | cut -d/ -f2`
1084 if [ -z "$MASK" ]; then
1085 MASK=32
1086 fi
1087 xbits
1088 # Is this host/network from one of our internal networks?
1089 if [ "$STROKE" -lt "$MASK" ]; then
1090 continue # Can't tell
1091 elif [ "$XBITS" -ge "$MASK" ]; then
1092 break 2 # Yes!
1093 fi # Can't tell
1094 done
1095 FAILURE="Source host from DENY_OUTBOUND not found in an internal network."
1096 exit_failure $1
1097 done
1098 fi
1099 fi
1100 NET2="$NET"
1101 NET=`echo "$FORWARD:" | cut -d: -f2`
1102 if [ -n "$NET" ] && ! check_network; then
1103 PORTS="$NET"
1104 if ! check_ports; then
1105 FAILURE="Syntax error in $PARAM."
1106 exit_failure $1
1107 else
1108 eval TEMP_$PARAM="$NET2:any:$PORTS"
1109 break
1110 fi
1111 elif [ -z "$NET" ]; then
1112 eval TEMP_$PARAM="$NET2:any:any"
1113 break
1114 fi
1115 if [ "$PARAM" == "ALLOW_INBOUND" ]; then
1116 STROKE=`echo "$NET/" | cut -d/ -f2`
1117 if [ -z "$STROKE" ]; then
1118 STROKE=32
1119 fi
1120 for TAB in NULL; do
1121 for NET1 in $INTERNAL_NETWORKS $ADDITIONAL_ROUTED_NETWORKS; do
1122 MASK=`echo "$NET1/" | cut -d/ -f2`
1123 if [ -z "$MASK" ]; then
1124 MASK=32
1125 fi
1126 xbits
1127 # Is this host/network from one of our internal networks?
1128 if [ "$STROKE" -lt "$MASK" ]; then
1129 continue # Can't tell on this network
1130 elif [ "$XBITS" -ge "$MASK" ]; then
1131 break 2 # Yes!
1132 fi # Can't tell
1133 done
1134 FAILURE="Destination host in ALLOW_INBOUND not found in an internal network."
1135 exit_failure $1
1136 done
1137 fi
1138 PORTS=`echo "$FORWARD:" | cut -d: -f3`
1139 if [ -z "$PORTS" ]; then
1140 eval TEMP_$PARAM="$NET2:$NET:any"
1141 break
1142 else
1143 if ! check_ports; then
1144 FAILURE="$FAILURE in $PARAM."
1145 exit_failure $1
1146 else
1147 eval TEMP_$PARAM="$NET2:$NET:$PORTS"
1148 break
1149 fi
1150 fi
1151 done
1152 if [ "$PARAM" == "ALLOW_INBOUND" ]; then
1153 MOD_ALLOW_INBOUND="$MOD_ALLOW_INBOUND $TEMP_ALLOW_INBOUND"
1154 else
1155 MOD_DENY_OUTBOUND="$MOD_DENY_OUTBOUND $TEMP_DENY_OUTBOUND"
1156 fi
1157 done
1158 done
1159 ALLOW_INBOUND=`echo $MOD_ALLOW_INBOUND`
1160 DENY_OUTBOUND=`echo $MOD_DENY_OUTBOUND`
1161fi
1162
1163# Remove duplicate external addresses, for example those created when using channel bonding.
1164
1165if [ -n "$EXTERNAL_ADDRESSES" ]; then
1166 MOD_ADDRESSES=""
1167 for ADDRESS in $EXTERNAL_ADDRESSES; do
1168 if !(( `echo "$MOD_ADDRESSES" | grep -c "$ADDRESS"` )); then
1169 MOD_ADDRESSES="$MOD_ADDRESSES $ADDRESS"
1170 fi
1171 done
1172 EXTERNAL_ADDRESSES=`echo $MOD_ADDRESSES`
1173fi
1174
1175# Make sure we own the addresses that we are staticly mapping through the firewall, and verify internal hosts are actually from internal networks.
1176
1177if [ -n "$STATIC_INSIDE_OUTSIDE" ]; then
1178 for FORWARD in $STATIC_INSIDE_OUTSIDE; do
1179 NET1=`echo "$FORWARD:" | cut -d: -f1`
1180 OUTSIDE=`echo "$FORWARD:" | cut -d: -f2`
1181 for TAB in NULL; do
1182 for ADDRESS in $EXTERNAL_ADDRESSES $INTERNAL_ADDRESSES; do
1183 if [ "$ADDRESS" == "$OUTSIDE" ]; then
1184 break 2
1185 fi
1186 done
1187 FAILURE="Could not find an interface with address given in STATIC_INSIDE_OUTSIDE."
1188 exit_failure $1
1189 done
1190 STROKE=`echo "$NET1/" | cut -d/ -f2`
1191 if [ -z "$STROKE" ]; then
1192 STROKE=32
1193 fi
1194 for TAB in NULL; do
1195 for NET in $INTERNAL_NETWORKS $ADDITIONAL_ROUTED_NETWORKS; do
1196 MASK=`echo "$NET/" | cut -d/ -f2`
1197 if [ -z "$MASK" ]; then
1198 MASK=32
1199 fi
1200 xbits
1201 # Is this host/network from one of our internal networks?
1202 if [ "$STROKE" -lt "$MASK" ]; then
1203 continue # Can't tell
1204 elif [ "$XBITS" -ge "$MASK" ]; then
1205 break 2 # Yes!
1206 fi # Can't tell
1207 done
1208 FAILURE="Internal host from STATIC_INSIDE_OUTSIDE not found in an internal network."
1209 exit_failure $1
1210 done
1211 done
1212fi
1213
1214# For FIREWALL_IP, make sure that our source address is on an external interface and our destination address is on an internal interface.
1215
1216for ADDRESS in $FIREWALL_IP; do
1217 OUTSIDE=`echo "$ADDRESS:" | cut -d: -f1`
1218 INSIDE=`echo "$ADDRESS:" | cut -d: -f2`
1219 for TAB in NULL; do
1220 for ADDRESS in $EXTERNAL_ADDRESSES; do
1221 if [ "$ADDRESS" == "$OUTSIDE" ]; then
1222 break 2
1223 fi
1224 done
1225 FAILURE="Source address given in FIREWALL_IP must be configured on an *external* interface."
1226 exit_failure $1
1227 done
1228 for TAB in NULL; do
1229 for ADDRESS in $INTERNAL_ADDRESSES; do
1230 if [ "$ADDRESS" == "$INSIDE" ]; then
1231 break 2
1232 fi
1233 done
1234 FAILURE="Destination address given in FIREWALL_IP must be configured on an *internal* interface."
1235 exit_failure $1
1236 done
1237done
1238
1239# If we do not trust routed networks then add internal interfaces as "secured" addresses in the exit message.
1240
1241if [ -n "$STATIC_INTERNAL_INTERFACES" ] && [ "$TRUST_ROUTED_NETWORKS" != "yes" ]; then
1242 EXTERNAL_ADDRESSES="$EXTERNAL_ADDRESSES $INTERNAL_ADDRESSES"
1243fi
1244
1245echo -n "."
1246
1247# Check that rp_filter interfaces are valid.
1248
1249for INTERFACE in $NO_RP_FILTER_INTERFACES; do
1250 if ! [ -w "/proc/sys/net/ipv4/conf/$INTERFACE/rp_filter" ]; then
1251 FAILURE="Cannot write to /proc/sys/net/ipv4/conf/$INTERFACE/rp_filter. Is the interface definition valid?"
1252 exit_failure $1
1253 fi
1254done
1255
1256# Check for Local Loopback interface.
1257
1258if !(( `ifconfig | grep -A1 "^lo" | grep "127\." | grep -c "255\.0\.0\.0"` )); then
1259 FAILURE="Local Loopback interface (lo) required but not found."
1260 exit_failure $1
1261fi
1262
1263# Make sure the filter table exists.
1264
1265if (( `iptables -t filter -nL 2>&1 | grep -c "Table does not exist"` )) || (( `iptables -t filter -nL 2>&1 | grep -c "can't initialize iptables table"` )); then
1266 FAILURE="Could not find 'filter' table. Did you compile support for all necessary modules?"
1267 exit_failure $1
1268fi
1269
1270# Check for the REJECT target if RFC 1122 compliance is enabled.
1271
1272if [ "$RFC_1122_COMPLIANT" == "yes" ]; then
1273 if ((`iptables -t filter -i lo -o lo -I FORWARD -j REJECT 2>&1 | grep -c "No chain/target/match by that name"`)); then
1274 FAILURE="Could not find 'REJECT' target. Did you compile support for all necessary modules?"
1275 exit_failure $1
1276 else
1277 iptables -t filter -D FORWARD 1
1278 fi
1279fi
1280
1281# If logging is enabled check for LOG and limit targets.
1282
1283if [ "$LOGGING" == "yes" ]; then
1284 if (( `iptables -t filter -i lo -o lo -I FORWARD -m limit 2>&1 | \
1285 grep -c "No chain/target/match by that name"` )); then
1286 FAILURE="Could not find 'limit' target. Did you compile support for all necessary modules?"
1287 exit_failure $1
1288 else
1289 iptables -t filter -D FORWARD 1
1290 fi
1291 if (( `iptables -t filter -i lo -o lo -I FORWARD -j LOG 2>&1 | grep -c "No chain/target/match by that name"` )); then
1292 FAILURE="Could not find 'LOG' target. Did you compile support for all necessary modules?"
1293 exit_failure $1
1294 else
1295 iptables -t filter -D FORWARD 1
1296 fi
1297fi
1298
1299# Check for the nat table if we need it.
1300
1301if [ -n "$STATIC_NAT_INTERFACES" ] || [ -n "$DYNAMIC_NAT_INTERFACES" ] || [ -n "$PORT_FORWARDS" ]; then
1302 if (( `iptables -t nat -nL 2>&1 | grep -c "Table does not exist"` )) || (( `iptables -t nat -nL 2>&1 | grep -c "can't initialize iptables table"` )); then
1303 FAILURE="Could not find 'nat' table. Did you compile support for all necessary modules?"
1304 exit_failure $1
1305 fi
1306fi
1307
1308# Determine if we need the MASQUERADE target.
1309
1310if [ -n "$DYNAMIC_NAT_INTERFACES" ] || ( [ -n "$DYNAMIC_INTERFACES" ] && [ -n "$PORT_FORWARDS" ] ); then
1311 if ((`iptables -t nat -I POSTROUTING -o lo -j MASQUERADE 2>&1 | grep -c "No chain/target/match by that name"`)); then
1312 FAILURE="Could not find 'MASQUERADE' target. Did you compile support for all necessary modules?"
1313 exit_failure $1
1314 else
1315 iptables -t nat -D POSTROUTING 1
1316 fi
1317fi
1318
1319# Check for state match module.
1320
1321if (( `iptables -t filter -I OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT 2>&1 | \
1322 grep -c "No chain/target/match by that name"` )); then
1323 FAILURE="Failed to load state match module. Did you compile support for all necessary modules?"
1324 exit_failure $1
1325else
1326 iptables -t filter -D OUTPUT 1
1327fi
1328
1329# Check for various port forwarding and ttl_stealth_router requirements.
1330
1331if [ -n "$PORT_FORWARDS" ] || [ "$TTL_STEALTH_ROUTER" == "yes" ]; then
1332 if (( `iptables -t mangle -nL 2>&1 | grep -c "Table does not exist"` )) || (( `iptables -t mangle -nL 2>&1 | grep -c "can't initialize iptables table"` )); then
1333 FAILURE="Could not find 'mangle' table, required for port forwarding and TTL stealth router mode. Did you compile support for all necessary modules?"
1334 exit_failure $1
1335 fi
1336 if [ -n "$PORT_FORWARDS" ]; then
1337 if (( `iptables -t mangle -I OUTPUT -j MARK --set-mark "1" 2>&1 | grep -c "No chain/target/match by that name"` )); then
1338 FAILURE="Failed to load MARK target, required for port forwarding. Did you compile support for all necessary modules?"
1339 exit_failure $1
1340 else
1341 iptables -t mangle -D OUTPUT 1
1342 fi
1343 if (( `iptables -t mangle -I OUTPUT -m mark --mark "1" -j ACCEPT 2>&1 | grep -c "No chain/target/match by that name"` )); then
1344 FAILURE="Failed to netfilter MARK match module, required for port forwarding. Did you compile support for all necessary modules?"
1345 exit_failure $1
1346 else
1347 iptables -t mangle -D OUTPUT 1
1348 fi
1349 fi
1350 if [ "$TTL_STEALTH_ROUTER" == "yes" ]; then
1351 if (( `iptables -t mangle -I FORWARD -j ACCEPT 2>&1 | grep -c "No chain/target/match by that name"` )); then
1352 FAILURE="Linux kernel 2.4.18 or newer required for TTL_STEALTH_ROUTER mode."
1353 exit_failure $1
1354 else
1355 iptables -t mangle -D FORWARD 1
1356 fi
1357 fi
1358fi
1359
1360# Test for ipt_TTL support.
1361
1362if [ "$TTL_STEALTH_ROUTER" == "yes" ]; then
1363 if (( `iptables -t mangle -I FORWARD -j TTL --ttl-inc "1" 2>&1 | grep -c "No chain/target/match by that name"` )); then
1364 FAILURE="TTL_STEALTH_ROUTER mode requires a patched kernel. See http://projectfiles.com/firewall/ for details."
1365 exit_failure $1
1366 else
1367 iptables -t mangle -D FORWARD 1
1368 fi
1369fi
1370
1371# System and configuration approved.
1372
1373echo " [ PASSED ]"
1374
1375# Exit if we only want to do sanity checking.
1376
1377if [ "$1" == "check" ]; then
1378 exit
1379fi
1380
1381##########################
1382# -- Firewall Section -- #
1383##########################
1384
1385echo -n "-> Building firewall."
1386
1387# Let no packets slip by while we are configuring the firewall.
1388
1389echo "0" > /proc/sys/net/ipv4/ip_forward
1390
1391# Enable kernel level reverse path filtering.
1392
1393echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
1394for INTERFACE in $NO_RP_FILTER_INTERFACES; do
1395 echo "0" > /proc/sys/net/ipv4/conf/$INTERFACE/rp_filter
1396done
1397
1398# Enable kernel level dynamic address handling.
1399
1400if [ -n "$DYNAMIC_INTERFACES" ]; then
1401 echo "1" > /proc/sys/net/ipv4/ip_dynaddr
1402else
1403 echo "0" > /proc/sys/net/ipv4/ip_dynaddr
1404fi
1405
1406# Set default policies.
1407
1408iptables -t filter -F
1409iptables -t filter -X
1410iptables -t filter -P INPUT DROP
1411iptables -t filter -P FORWARD DROP
1412iptables -t filter -P OUTPUT ACCEPT
1413
1414if !(( `iptables -t nat -F 2>&1 | grep -c "Table does not exist"` )); then
1415 iptables -t nat -X
1416 iptables -t nat -P PREROUTING ACCEPT
1417 iptables -t nat -P POSTROUTING ACCEPT
1418 iptables -t nat -P OUTPUT ACCEPT
1419fi
1420
1421if !(( `iptables -t mangle -F 2>&1 | grep -c "Table does not exist"` )); then
1422 iptables -t mangle -F
1423 iptables -t mangle -X
1424 iptables -t mangle -P PREROUTING ACCEPT
1425 iptables -t mangle -P OUTPUT ACCEPT
1426 iptables -t mangle -P POSTROUTING ACCEPT > /dev/null 2>&1 # New 2.4.18 builtin mangle chains
1427 iptables -t mangle -P INPUT ACCEPT > /dev/null 2>&1
1428 iptables -t mangle -P FORWARD ACCEPT > /dev/null 2>&1
1429fi
1430
1431# Drop traffic to and from blacklisted networks.
1432
1433for NETWORK in $BLACKLIST; do
1434 NET=`echo "$NETWORK:" | cut -d: -f1`
1435 if ! check_network; then
1436 PORTS="$NET"
1437 NET="0.0.0.0/0"
1438 else
1439 PORTS=`echo "$NETWORK:" | cut -d: -f2`
1440 fi
1441 if [ -n "$PORTS" ]; then
1442 PROTOCOL=`echo "$PORTS/" | cut -d/ -f2`
1443 PORT="--dport `echo "$PORTS/" | cut -d/ -f1 | cut -d- -f1,2 --output-delimiter=":"`"
1444 if [ "$PROTOCOL" == "tcp" ] || [ -z "$PROTOCOL" ]; then
1445 if [ "$IS_ROUTER" == "yes" ]; then
1446 iptables -t filter -I FORWARD -s $NET -p tcp $PORT -j DROP
1447 iptables -t filter -I FORWARD -d $NET -p tcp $PORT -j DROP
1448 fi
1449 iptables -t filter -I INPUT -s $NET -p tcp $PORT -j DROP
1450 iptables -t filter -I INPUT -d $NET -p tcp $PORT -j DROP
1451 iptables -t filter -I OUTPUT -s $NET -p tcp $PORT -j DROP
1452 iptables -t filter -I OUTPUT -d $NET -p tcp $PORT -j DROP
1453 fi
1454 if [ "$PROTOCOL" == "udp" ] || [ -z "$PROTOCOL" ]; then
1455 if [ "$IS_ROUTER" == "yes" ]; then
1456 iptables -t filter -I FORWARD -s $NET -p udp $PORT -j DROP
1457 iptables -t filter -I FORWARD -d $NET -p udp $PORT -j DROP
1458 fi
1459 iptables -t filter -I INPUT -s $NET -p udp $PORT -j DROP
1460 iptables -t filter -I INPUT -d $NET -p udp $PORT -j DROP
1461 iptables -t filter -I OUTPUT -s $NET -p udp $PORT -j DROP
1462 iptables -t filter -I OUTPUT -d $NET -p udp $PORT -j DROP
1463 fi
1464 else
1465 if [ "$IS_ROUTER" == "yes" ]; then
1466 iptables -t filter -I FORWARD -s $NET -j DROP
1467 iptables -t filter -I FORWARD -d $NET -j DROP
1468 fi
1469 iptables -t filter -I INPUT -s $NET -j DROP
1470 iptables -t filter -I INPUT -d $NET -j DROP
1471 iptables -t filter -I OUTPUT -s $NET -j DROP
1472 iptables -t filter -I OUTPUT -d $NET -j DROP
1473 fi
1474done
1475
1476# Initialize trusted chain
1477
1478iptables -t filter -N TRUSTED
1479if [ "$RFC_1122_COMPLIANT" == "yes" ]; then
1480 iptables -t filter -A TRUSTED -p icmp -j DROP # ICMP will be permitted elsewhere.
1481 iptables -t filter -A TRUSTED -j REJECT
1482else
1483 iptables -t filter -A TRUSTED -j DROP
1484fi
1485
1486# Reject state NEW without SYN flag set. (paranoia setting)
1487
1488if [ "$DROP_NEW_WITHOUT_SYN" == "yes" ]; then
1489 if [ "$LOGGING" == "yes" ]; then
1490 iptables -A INPUT -p tcp ! --syn -m state --state NEW -m limit --limit $LOG_LIMIT \
1491 --limit-burst $LOG_BURST -j LOG --log-level $LOG_LEVEL --log-prefix "firewall: "
1492 fi
1493 iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
1494 if [ "$IS_ROUTER" == "yes" ]; then
1495 if [ "$LOGGING" == "yes" ]; then
1496 iptables -A FORWARD -p tcp ! --syn -m state --state NEW -m limit --limit $LOG_LIMIT \
1497 --limit-burst $LOG_BURST -j LOG --log-level $LOG_LEVEL --log-prefix "firewall: "
1498 fi
1499 iptables -A FORWARD -p tcp ! --syn -m state --state NEW -j DROP
1500 fi
1501fi
1502
1503# Set logging preferences. Do not log broadcasts.
1504
1505if [ "$LOGGING" == "yes" ]; then
1506 echo "1" > /proc/sys/net/ipv4/conf/all/log_martians
1507 iptables -t filter -N LOGME
1508 iptables -t filter -I TRUSTED -j LOGME
1509 for BROADCAST in $BCAST_LIST; do
1510 iptables -t filter -I LOGME -d $BROADCAST -j RETURN
1511 done
1512 iptables -t filter -A LOGME -p icmp -m limit --limit $LOG_LIMIT --limit-burst $LOG_BURST -j LOG --log-level $LOG_LEVEL \
1513 --log-prefix "firewall: "
1514 iptables -t filter -A LOGME -p tcp -m limit --limit $LOG_LIMIT --limit-burst $LOG_BURST -j LOG --log-level $LOG_LEVEL \
1515 --log-prefix "firewall: "
1516 iptables -t filter -A LOGME -p udp -m limit --limit $LOG_LIMIT --limit-burst $LOG_BURST -j LOG --log-level $LOG_LEVEL \
1517 --log-prefix "firewall: "
1518fi
1519
1520echo -n "."
1521
1522# Accept icmp-echo-request packets if RFC-1122 compliance option is enabled. Limit logging of icmp packets.
1523
1524if [ "$RFC_1122_COMPLIANT" == "yes" ]; then
1525 if [ "$LOGGING" == "yes" ]; then
1526 for ADDRESS in $INTERNAL_ADDRESSES $EXTERNAL_ADDRESSES; do
1527 iptables -t filter -I TRUSTED 2 -d $ADDRESS -p icmp --icmp-type echo-request -j ACCEPT
1528 done
1529 for FORWARD in $STATIC_INSIDE_OUTSIDE; do
1530 ADDRESS=`echo "$FORWARD:" | cut -d: -f1`
1531 iptables -t filter -I TRUSTED 2 -d $ADDRESS -p icmp --icmp-type echo-request -j ACCEPT
1532 done
1533 for ADDRESS in $INTERNAL_ADDRESSES $EXTERNAL_ADDRESSES; do
1534 iptables -t filter -I TRUSTED -d $ADDRESS -p icmp --icmp-type echo-request -m limit --limit 2/second --limit-burst 10 -j ACCEPT
1535 done
1536 for FORWARD in $STATIC_INSIDE_OUTSIDE; do
1537 ADDRESS=`echo "$FORWARD:" | cut -d: -f1`
1538 iptables -t filter -I TRUSTED -d $ADDRESS -p icmp --icmp-type echo-request -m limit --limit 2/second --limit-burst 10 -j ACCEPT
1539 done
1540 if [ "$IS_ROUTER" != "yes" ] && [ -z "$EXTERNAL_ADDRESSES" ]; then
1541 iptables -t filter -I TRUSTED 2 -p icmp --icmp-type echo-request -j ACCEPT
1542 iptables -t filter -I TRUSTED -p icmp --icmp-type echo-request -m limit --limit 2/second --limit-burst 10 -j ACCEPT
1543 elif [ -n "$DMZ_INTERFACES" ]; then
1544 for INTERFACE in $DMZ_INTERFACES; do
1545 iptables -t filter -I TRUSTED 2 -o $INTERFACE -p icmp --icmp-type echo-request -j ACCEPT
1546 iptables -t filter -I TRUSTED -o $INTERFACE -p icmp --icmp-type echo-request -m limit --limit 2/second --limit-burst 10 -j ACCEPT
1547 done
1548 fi
1549 else
1550 for ADDRESS in $INTERNAL_ADDRESSES $EXTERNAL_ADDRESSES; do
1551 iptables -t filter -I TRUSTED -d $ADDRESS -p icmp --icmp-type echo-request -j ACCEPT
1552 done
1553 for FORWARD in $STATIC_INSIDE_OUTSIDE; do
1554 ADDRESS=`echo "$FORWARD:" | cut -d: -f1`
1555 iptables -t filter -I TRUSTED -d $ADDRESS -p icmp --icmp-type echo-request -j ACCEPT
1556 done
1557 if [ "$IS_ROUTER" != "yes" ] && [ -z "$EXTERNAL_ADDRESSES" ]; then
1558 iptables -t filter -I TRUSTED -p icmp --icmp-type echo-request -j ACCEPT
1559 elif [ -n "$DMZ_INTERFACES" ]; then
1560 for INTERFACE in $DMZ_INTERFACES; do
1561 iptables -t filter -I TRUSTED -o $INTERFACE -p icmp --icmp-type echo-request -j ACCEPT
1562 done
1563 fi
1564 fi
1565fi
1566
1567# Insert trusted networks into trusted chain before everything else.
1568
1569for NETWORK in $PERMIT ; do
1570 iptables -t filter -I TRUSTED -s $NETWORK -j ACCEPT
1571done
1572
1573# Insert local external networks into the trusted chain if option is enabled.
1574
1575if [ "$TRUST_LOCAL_EXTERNAL_NETWORKS" == "yes" ]; then
1576 for NETWORK in $EXTERNAL_NETWORKS; do
1577 iptables -t filter -I TRUSTED -s $NETWORK -j ACCEPT
1578 done
1579fi
1580
1581# Set default policy for ESTABLISHED and RELATED connections to ACCEPT on FORWARD chains.
1582
1583iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
1584if [ "$IS_ROUTER" == "yes" ]; then
1585 iptables -t filter -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
1586fi
1587
1588# Configure ALLOW_INBOUND and DENY_OUTBOUND.
1589
1590if [ -n "$INTERNAL_INTERFACES" ]; then
1591 for PARAM in ACCEPT TRUSTED; do
1592 if [ "$PARAM" == "TRUSTED" ]; then
1593 LIST="$DENY_OUTBOUND"
1594 else
1595 LIST="$ALLOW_INBOUND"
1596 fi
1597 for ITEM in $LIST; do
1598 NET="-s `echo "$ITEM:" | cut -d: -f1`"
1599 if [ "$NET" == "-s any" ]; then
1600 NET=""
1601 fi
1602 DEST="-d `echo "$ITEM:" | cut -d: -f2`"
1603 if [ "$DEST" == "-d any" ]; then
1604 DEST=""
1605 fi
1606 PORTS=`echo "$ITEM:" | cut -d: -f3`
1607 PROTOCOL=`echo "$PORTS/" | cut -d/ -f2`
1608 PORT="--dport `echo "$PORTS/" | cut -d/ -f1 | cut -d- -f1,2 --output-delimiter=":"`"
1609 if [ -z "$DEST" ] || [ -z "$NET" ]; then
1610 if [ "$PARAM" == "ACCEPT" ]; then
1611 TAB="-o" # (just to reuse the variable) For ALLOW_INBOUND
1612 else # classify packets sent out on internal interfaces and
1613 TAB="-i" # for DENY_OUTBOUND, received by internal interfaces,
1614 fi # unless both source and destination addresses are available.
1615 for INTERFACE in $INTERNAL_INTERFACES; do
1616 if !(( `echo "$INTERFACE" | grep -c ":"` )); then
1617 if [ "$PORTS" == "any" ]; then
1618 iptables -t filter -A FORWARD -m state --state NEW $TAB $INTERFACE $NET $DEST -j $PARAM
1619 else
1620 if [ "$PROTOCOL" == "tcp" ] || [ -z "$PROTOCOL" ]; then
1621 iptables -t filter -A FORWARD -m state --state NEW $TAB $INTERFACE $NET $DEST -p tcp $PORT -j $PARAM
1622 fi
1623 if [ "$PROTOCOL" == "udp" ] || [ -z "$PROTOCOL" ]; then
1624 iptables -t filter -A FORWARD -m state --state NEW $TAB $INTERFACE $NET $DEST -p udp $PORT -j $PARAM
1625 fi
1626 fi
1627 fi
1628 done
1629 else # The exception where we have both source and destination addresses
1630 if [ "$PORTS" == "any" ]; then
1631 iptables -t filter -A FORWARD -m state --state NEW $NET $DEST -j $PARAM
1632 else
1633 if [ "$PROTOCOL" == "tcp" ] || [ -z "$PROTOCOL" ]; then
1634 iptables -t filter -A FORWARD -m state --state NEW $NET $DEST -p tcp $PORT -j $PARAM
1635 fi
1636 if [ "$PROTOCOL" == "udp" ] || [ -z "$PROTOCOL" ]; then
1637 iptables -t filter -A FORWARD -m state --state NEW $NET $DEST -p udp $PORT -j $PARAM
1638 fi
1639 fi
1640 fi
1641 done
1642 done
1643fi
1644
1645# For servers, only allow NEW connections to specified INPUT ports. For port forwarding, allow on FORWARD chain.
1646
1647for ITEM in $OPEN_PORTS $TRUSTED_PORTS; do
1648 NET=""
1649 if (( `echo "$ITEM:" | cut -d: -f2 | grep -c "."` )); then
1650 NET="-s `echo "$ITEM:" | cut -d: -f1`"
1651 ITEM=`echo "$ITEM:" | cut -d: -f2`
1652 fi
1653 PORTS=`echo "$ITEM" | cut -d/ -f1`
1654 PORTS=`echo "$PORTS" | cut -d- -f1,2 --output-delimiter=":"`
1655 PROTOCOL=`echo "$ITEM" | cut -d/ -f2`
1656 COUNT="0"
1657 for FORWARD in $PORT_FORWARDS; do
1658 IN_PORTS=`echo "$FORWARD" | cut -d: -f2 | cut -d- -f1,2 --output-delimiter=":"`
1659 if [ "`echo "$FORWARD" | cut -d: -f1`" == "$PROTOCOL" ] && [ "$PORTS" == "$IN_PORTS" ]; then
1660 DEST=`echo "$FORWARD" | cut -d: -f3`
1661 DPORTS=`echo "$FORWARD" | cut -d: -f4 | cut -d- -f1,2 --output-delimiter=":"`
1662 if [ -z "$DPORTS" ]; then
1663 DPORTS="$IN_PORTS"
1664 fi
1665 iptables -t filter -A FORWARD -m state --state NEW $NET -d $DEST -p $PROTOCOL --dport $DPORTS -j ACCEPT
1666 COUNT="1"
1667 if [ -z "$NET" ]; then
1668 continue 2 # i.e. This port forward is open to everyone.
1669 fi
1670 fi
1671 done
1672 if [ "$COUNT" == "0" ]; then
1673 iptables -t filter -A INPUT -m state --state NEW $NET -p $PROTOCOL --dport $PORTS -j ACCEPT
1674 fi
1675done
1676
1677echo -n "."
1678
1679# For routers, allow routing of internal and routed networks on internal interfaces. Fix traceroutes under DNAT info-leak-bug.
1680
1681if [ "$IS_ROUTER" == "yes" ]; then
1682 COUNT="0"
1683 TAB=""
1684 for INTERFACE in $STATIC_INTERNAL_INTERFACES; do
1685 COUNT=$((COUNT + 1))
1686 NETWORK=`echo "$INTERNAL_NETWORKS" | cut -d\ -f$COUNT`
1687 INTERFACE=`echo "$INTERFACE" | cut -d: -f1`
1688 iptables -t filter -A OUTPUT -o $INTERFACE -d $NETWORK -p icmp -j ACCEPT
1689 if [ -z "$DMZ_INTERFACES" ] || !(( `echo "$DMZ_INTERFACES" | grep -c "$INTERFACE"` )); then
1690 if [ "$SHARED_INTERNAL" == "yes" ]; then
1691 iptables -t filter -A FORWARD -m state --state NEW -i $INTERFACE -s $NETWORK -j ACCEPT
1692 else
1693 for DEST in $EXTERNAL_INTERFACES $DMZ_INTERFACES; do
1694 if !(( `echo "$DEST" | grep -c ":"` )); then
1695 iptables -t filter -A FORWARD -m state --state NEW -i $INTERFACE -s $NETWORK -o $DEST -j ACCEPT
1696 fi
1697 done
1698 fi
1699 else
1700 for DEST in $EXTERNAL_INTERFACES; do
1701 if !(( `echo "$DEST" | grep -c ":"` )); then
1702 iptables -t filter -A FORWARD -m state --state NEW -i $INTERFACE -s $NETWORK -o $DEST -j ACCEPT
1703 fi
1704 done
1705 fi
1706 if [ "$TRUST_ROUTED_NETWORKS" == "yes" ] && ( [ -z "$DMZ_INTERFACES" ] || \
1707 !(( `echo "$DMZ_INTERFACES" | grep -c "$INTERFACE"` )) ); then
1708 iptables -t filter -A INPUT -m state --state NEW -i $INTERFACE -s $NETWORK -j ACCEPT
1709 fi
1710 if [ "$INTERNAL_DHCP" == "yes" ]; then
1711 if !(( `echo "$TAB" | grep -c "$INTERFACE"` )); then
1712 iptables -t filter -A INPUT -m state --state NEW -i $INTERFACE -p udp --dport 67 -j ACCEPT
1713 fi
1714 TAB="$TAB $INTERFACE"
1715 fi
1716 if [ -z "$DMZ_INTERFACES" ] || !(( `echo "$DMZ_INTERFACES" | grep -c "$INTERFACE"` )); then
1717 for NETWORK in $ADDITIONAL_ROUTED_NETWORKS; do
1718 iptables -t filter -A OUTPUT -o $INTERFACE -d $NETWORK -p icmp -j ACCEPT
1719 if [ "$SHARED_INTERNAL" == "yes" ]; then
1720 iptables -t filter -A FORWARD -m state --state NEW -i $INTERFACE -s $NETWORK -j ACCEPT
1721 else
1722 for DEST in $EXTERNAL_INTERFACES $DMZ_INTERFACES; do
1723 if !(( `echo "$DEST" | grep -c ":"` )); then
1724 iptables -t filter -A FORWARD -m state --state NEW -i $INTERFACE -s $NETWORK -o $DEST -j ACCEPT
1725 fi
1726 done
1727 fi
1728 if [ "$TRUST_ROUTED_NETWORKS" == "yes" ]; then
1729 iptables -t filter -A INPUT -m state --state NEW -i $INTERFACE -s $NETWORK -j ACCEPT
1730 fi
1731 done
1732 fi
1733 done
1734 for INTERFACE in $DYNAMIC_INTERNAL_INTERFACES; do
1735 iptables -t filter -A OUTPUT -o $INTERFACE -p icmp -j ACCEPT
1736 iptables -t filter -A FORWARD -m state --state NEW -i $INTERFACE -j ACCEPT
1737 if [ "$TRUST_ROUTED_NETWORKS" == "yes" ]; then
1738 iptables -t filter -A INPUT -m state --state NEW -i $INTERFACE -j ACCEPT
1739 fi
1740 done
1741fi
1742
1743# ICMP DNAT information leak workaround.
1744
1745iptables -t filter -A OUTPUT -p icmp -m state --state INVALID -j DROP
1746
1747# Set up static address translations.
1748
1749if [ "$IS_ROUTER" == "yes" ]; then
1750 for FORWARD in $STATIC_INSIDE_OUTSIDE; do
1751 INSIDE=`echo "$FORWARD:" | cut -d: -f1`
1752 OUTSIDE=`echo "$FORWARD:" | cut -d: -f2`
1753 iptables -t nat -A POSTROUTING -s $INSIDE -j SNAT --to-source $OUTSIDE
1754 if !(( `echo "$INSIDE" | grep -c "/"` )); then
1755 for ITEM in $ALLOW_INBOUND; do
1756 NETWORK="-s `echo "$ITEM" | cut -d: -f1`" # Source
1757 if [ "$NETWORK" == "-s any" ]; then
1758 NETWORK=""
1759 fi
1760 NET=`echo "$ITEM" | cut -d: -f2` # Destination
1761 PORTS=`echo "$ITEM" | cut -d: -f3`
1762 if [ -n "$PORTS" ]; then
1763 PORT="--dport `echo "$PORTS/" | cut -d/ -f1 | cut -d- -f1,2 --output-delimiter=":"`"
1764 PROTOCOL=`echo "$PORTS/" | cut -d/ -f2`
1765 fi
1766 if [ "$NET" != "any" ]; then # If there is a specific destination --
1767 NET1="$INSIDE" # Determine if this is part of it.
1768 xbits
1769 MASK=`echo "$NET/" | cut -d/ -f2`
1770 if [ -z "$MASK" ]; then
1771 MASK=32
1772 fi
1773 fi
1774 if [ "$NET" == "any" ] || [ "$XBITS" -ge "$MASK" ]; then
1775 if [ "$RFC_1122_COMPLIANT" == "yes" ]; then
1776 iptables -t nat -A PREROUTING $NETWORK -d $OUTSIDE \
1777 -p icmp --icmp-type echo-request -j DNAT --to-destination $INSIDE
1778 fi
1779 if [ "$PORTS" == "any" ]; then
1780 iptables -t nat -A PREROUTING $NETWORK -d $OUTSIDE -p tcp -j DNAT --to-destination $INSIDE
1781 iptables -t nat -A PREROUTING $NETWORK -d $OUTSIDE -p udp -j DNAT --to-destination $INSIDE
1782 else
1783 if [ "$PROTOCOL" == "tcp" ] || [ "$PROTOCOL" == "udp" ]; then
1784 iptables -t nat -A PREROUTING $NETWORK -d $OUTSIDE -p $PROTOCOL $PORT -j DNAT --to-destination $INSIDE
1785 else
1786 iptables -t nat -A PREROUTING $NETWORK -d $OUTSIDE -p tcp $PORT -j DNAT --to-destination $INSIDE
1787 iptables -t nat -A PREROUTING $NETWORK -d $OUTSIDE -p udp $PORT -j DNAT --to-destination $INSIDE
1788 fi
1789 fi
1790 fi
1791 done
1792 for NETWORK in $PERMIT; do
1793 iptables -t nat -A PREROUTING -s $NETWORK -d $OUTSIDE -j DNAT --to-destination $INSIDE
1794 done
1795 COUNT="0"
1796 NET1="$INSIDE"
1797 for INTERFACE in $STATIC_INTERNAL_INTERFACES; do
1798 COUNT=$((COUNT + 1))
1799 NET=`echo $INTERNAL_NETWORKS | cut -d\ -f$COUNT`
1800 INTERFACE=`echo $INTERFACE | cut -d: -f1`
1801 iptables -t nat -A PREROUTING -s $NET -d $OUTSIDE -j DNAT --to-destination $INSIDE
1802 xbits
1803 MASK=`echo "$NET/" | cut -d/ -f2`
1804 if [ -z "$MASK" ]; then
1805 MASK=32
1806 fi
1807 ADDRESS=`echo $INTERNAL_ADDRESSES | cut -d\ -f$COUNT`
1808 if [ "$XBITS" -ge "$MASK" ]; then
1809 iptables -t nat -A POSTROUTING -s $NET -o $INTERFACE -d $INSIDE -j SNAT --to-source $ADDRESS
1810 fi
1811 for NET in $ADDITIONAL_ROUTED_NETWORKS; do
1812 xbits
1813 if [ "$XBITS" -ge "$MASK" ]; then
1814 iptables -t nat -A POSTROUTING -s $NET -o $INTERFACE -d $INSIDE -j SNAT --to-source $ADDRESS
1815 fi
1816 iptables -t nat -A PREROUTING -s $NET -d $OUTSIDE -j DNAT --to-destination $INSIDE
1817 done
1818 done
1819 for INTERFACE in $DYNAMIC_INTERNAL_INTERFACES; do
1820 iptables -t nat -A PREROUTING -s $NETWORK -d $OUTSIDE -j DNAT --to-destination $INSIDE
1821 done
1822 fi
1823 # Lets not have people mistaking the router for the internal host.
1824 iptables -t filter -I INPUT -d $OUTSIDE -j DROP
1825 done
1826fi
1827
1828# Configure NAT.
1829
1830if [ "$IS_ROUTER" == "yes" ]; then
1831 COUNT="0"
1832 for INTERFACE in $STATIC_NAT_INTERFACES; do
1833 COUNT=$((COUNT + 1))
1834 ADDRESS=`echo "$NAT_ADDRESSES" | cut -d\ -f$COUNT`
1835 if [ -n "$DYNAMIC_INTERNAL_INTERFACES" ]; then
1836 iptables -t nat -A POSTROUTING -o $INTERFACE -j SNAT --to-source $ADDRESS
1837 else
1838 for NETWORK in $NAT_NETWORKS $ADDITIONAL_ROUTED_NETWORKS; do
1839 iptables -t nat -A POSTROUTING -s $NETWORK -o $INTERFACE -j SNAT --to-source $ADDRESS
1840 done
1841 fi
1842 done
1843 for INTERFACE in $DYNAMIC_NAT_INTERFACES; do
1844 if [ -n "$DYNAMIC_INTERNAL_INTERFACES" ]; then
1845 iptables -t nat -I POSTROUTING -o $INTERFACE -j MASQUERADE
1846 else
1847 for NETWORK in $NAT_NETWORKS $ADDITIONAL_ROUTED_NETWORKS; do
1848 iptables -t nat -I POSTROUTING -s $NETWORK -o $INTERFACE -j MASQUERADE
1849 done
1850 fi
1851 done
1852fi
1853
1854echo -n "."
1855
1856# Configure port forwarding.
1857
1858for FORWARD in $PORT_FORWARDS; do
1859 PROTOCOL=`echo "$FORWARD" | cut -d: -f1`
1860 IN_PORTS=`echo "$FORWARD" | cut -d: -f2 | cut -d- -f1,2 --output-delimiter=":"`
1861 DEST=`echo "$FORWARD" | cut -d: -f3`
1862 PORTS=`echo "$FORWARD" | cut -d: -f4`
1863 if [ -z "$PORTS" ]; then
1864 PORTS="$IN_PORTS"
1865 fi
1866 DPORTS=`echo "$PORTS" | cut -d- -f1,2 --output-delimiter=":"`
1867 # Support DNAT for locally generated connections, new in iptables 1.2.6a and kernel 2.4.19
1868 iptables -t nat -A OUTPUT -o lo -p $PROTOCOL --dport $IN_PORTS -j DNAT --to-destination $DEST:$PORTS > /dev/null 2>&1
1869 COUNT="0"
1870 while (( `echo "${INTERFACE_TAB[$((COUNT + 1))]}" | grep -c "."` )); do
1871 COUNT=$((COUNT + 1))
1872 if (( `echo "$DYNAMIC_INTERFACES" | grep -c "${INTERFACE_TAB[$COUNT]}"` )); then
1873 iptables -t nat -I POSTROUTING -m mark --mark "$COUNT" -o ${INTERFACE_TAB[$COUNT]} -d $DEST \
1874 -p $PROTOCOL --dport $DPORTS -j MASQUERADE
1875 else
1876 iptables -t nat -I POSTROUTING -m mark --mark "$COUNT" -o ${INTERFACE_TAB[$COUNT]} -d $DEST \
1877 -p $PROTOCOL --dport $DPORTS -j SNAT --to-source ${ADDRESS_TAB[$COUNT]}
1878 fi
1879 if (( `echo "$DYNAMIC_INTERNAL_INTERFACES" | grep -c "${INTERFACE_TAB[$COUNT]}"` )) && \
1880 [ "$PORT_FWD_ROUTED_NETWORKS" == "yes" ]; then
1881 iptables -t nat -A PREROUTING -i ${INTERFACE_TAB[$COUNT]} \
1882 -p $PROTOCOL --dport $IN_PORTS -j DNAT --to-destination $DEST:$PORTS
1883 iptables -t mangle -A PREROUTING -i ${INTERFACE_TAB[$COUNT]} \
1884 -p $PROTOCOL --dport $IN_PORTS -j MARK --set-mark "$COUNT"
1885 continue # We will accept anything on this interface.
1886 fi
1887 for ADDRESS in $PORT_FORWARD_ADDRESSES; do
1888 for ITEM in $OPEN_PORTS $TRUSTED_PORTS; do
1889 if (( `echo "$ITEM:" | cut -d: -f2 | grep -c "."` )); then
1890 NET="-s `echo "$ITEM:" | cut -d: -f1`"
1891 ITEM=`echo "$ITEM:" | cut -d: -f2`
1892 else
1893 NET=""
1894 fi
1895 PORT=`echo "$ITEM/" | cut -d/ -f1`
1896 PORT=`echo "$PORT" | cut -d- -f1,2 --output-delimiter=":"`
1897 if [ "$PROTOCOL" == "$(echo "$ITEM/" | cut -d/ -f2)" ] && [ "$PORT" == "$IN_PORTS" ]; then
1898 if (( `echo "$DYNAMIC_NAT_INTERFACES" | grep -c "${INTERFACE_TAB[$COUNT]}"` )); then
1899 iptables -t nat -A PREROUTING $NET -i ${INTERFACE_TAB[$COUNT]} \
1900 -p $PROTOCOL --dport $IN_PORTS -j DNAT --to-destination $DEST:$PORTS
1901 iptables -t mangle -A PREROUTING $NET -i ${INTERFACE_TAB[$COUNT]} \
1902 -p $PROTOCOL --dport $IN_PORTS -j MARK --set-mark "$COUNT"
1903 else
1904 iptables -t nat -A PREROUTING $NET -d $ADDRESS -i ${INTERFACE_TAB[$COUNT]} \
1905 -p $PROTOCOL --dport $IN_PORTS -j DNAT --to-destination $DEST:$PORTS
1906 iptables -t mangle -A PREROUTING $NET -d $ADDRESS -i ${INTERFACE_TAB[$COUNT]} \
1907 -p $PROTOCOL --dport $IN_PORTS -j MARK --set-mark "$COUNT"
1908 fi
1909 if [ -z "$NET" ]; then
1910 continue 2 # This port forward is open to everyone.
1911 fi
1912 fi
1913 done
1914 for NETWORK in ${NETWORK_TAB[$COUNT]}; do
1915 if (( `echo "$DYNAMIC_NAT_INTERFACES" | grep -c "${INTERFACE_TAB[$COUNT]}"` )); then
1916 iptables -t nat -A PREROUTING -i ${INTERFACE_TAB[$COUNT]} -s $NETWORK \
1917 -p $PROTOCOL --dport $IN_PORTS -j DNAT --to-destination $DEST:$PORTS
1918 iptables -t mangle -A PREROUTING -i ${INTERFACE_TAB[$COUNT]} -s $NETWORK \
1919 -p $PROTOCOL --dport $IN_PORTS -j MARK --set-mark "$COUNT"
1920 else
1921 iptables -t nat -A PREROUTING -d $ADDRESS -i ${INTERFACE_TAB[$COUNT]} -s $NETWORK \
1922 -p $PROTOCOL --dport $IN_PORTS -j DNAT --to-destination $DEST:$PORTS
1923 iptables -t mangle -A PREROUTING -d $ADDRESS -i ${INTERFACE_TAB[$COUNT]} -s $NETWORK \
1924 -p $PROTOCOL --dport $IN_PORTS -j MARK --set-mark "$COUNT"
1925 fi
1926 done
1927 for NETWORK in $PERMIT; do
1928 if (( `echo "$DYNAMIC_NAT_INTERFACES" | grep -c "${INTERFACE_TAB[$COUNT]}"` )); then
1929 iptables -t nat -A PREROUTING -i ${INTERFACE_TAB[$COUNT]} -s $NETWORK \
1930 -p $PROTOCOL --dport $IN_PORTS -j DNAT --to-destination $DEST:$PORTS
1931 iptables -t mangle -A PREROUTING -i ${INTERFACE_TAB[$COUNT]} -s $NETWORK \
1932 -p $PROTOCOL --dport $IN_PORTS -j MARK --set-mark "$COUNT"
1933 else
1934 iptables -t nat -A PREROUTING -d $ADDRESS -i ${INTERFACE_TAB[$COUNT]} -s $NETWORK \
1935 -p $PROTOCOL --dport $IN_PORTS -j DNAT --to-destination $DEST:$PORTS
1936 iptables -t mangle -A PREROUTING -d $ADDRESS -i ${INTERFACE_TAB[$COUNT]} -s $NETWORK \
1937 -p $PROTOCOL --dport $IN_PORTS -j MARK --set-mark "$COUNT"
1938 fi
1939 done # Done with sources
1940 if (( `echo "$DYNAMIC_NAT_INTERFACES" | grep -c "${INTERFACE_TAB[$COUNT]}"` )); then
1941 break
1942 fi
1943 done # Done with destination addresses
1944 done # Done with interfaces
1945done # Done with forwards
1946
1947# Source nat outbound connections generated by the local machine to address defined in FIREWALL_IP.
1948
1949for ADDRESS in $FIREWALL_IP; do
1950 OUTSIDE=`echo "$ADDRESS:" | cut -d: -f1`
1951 INSIDE=`echo "$ADDRESS:" | cut -d: -f2`
1952 iptables -t nat -A POSTROUTING -s $OUTSIDE -j SNAT --to-source $INSIDE
1953done
1954
1955# Accept new connections from the loopback interface (localhost).
1956
1957iptables -t filter -A INPUT -i lo -m state --state NEW -j ACCEPT
1958
1959# Jump to the trusted chain if this packet establishes a NEW connection.
1960
1961iptables -t filter -A INPUT -m state --state NEW -j TRUSTED
1962if [ "$IS_ROUTER" == "yes" ]; then
1963 iptables -t filter -A FORWARD -m state --state NEW -j TRUSTED
1964fi
1965
1966# Enable TTL stealth router mode.
1967
1968if [ "$TTL_STEALTH_ROUTER" == "yes" ]; then
1969 iptables -t mangle -I FORWARD -j TTL --ttl-inc "1"
1970fi
1971
1972# Now that everything is configured we can enable ip_forward for routers.
1973
1974if [ "$IS_ROUTER" == "yes" ]; then
1975 echo "1" > /proc/sys/net/ipv4/ip_forward
1976fi
1977
1978# Print exit message.
1979
1980echo " [ DONE ]"
1981if [ -n "$EXTERNAL_ADDRESSES" ]; then
1982 echo "-> Successfully secured the following addresses: `echo $EXTERNAL_ADDRESSES | sed s/\ /,\ /g`."
1983fi
1984if [ "$IS_ROUTER" == "yes" ]; then
1985 if [ -n "$DYNAMIC_EXTERNAL_INTERFACES" ]; then
1986 echo "-> Successfully secured the following external interfaces: `echo $DYNAMIC_EXTERNAL_INTERFACES | sed s/\ /,\ /g`."
1987 fi
1988 if [ -n "$INTERNAL_NETWORKS" ] || [ -n "$ADDITIONAL_ROUTED_NETWORKS" ]; then
1989 echo "-> Routing is enabled for the following networks: `echo $INTERNAL_NETWORKS $ADDITIONAL_ROUTED_NETWORKS | \
1990 sed s/\ /,\ /g`."
1991 fi
1992 if [ -n "$DYNAMIC_INTERNAL_INTERFACES" ]; then
1993 echo "-> Alert! Routing is enabled for ALL connections through: `echo $DYNAMIC_INTERNAL_INTERFACES \
1994 | sed s/\ /,\ /g`."
1995 fi
1996fi
1997
1998# Write a configuration file if passed appropriate arguments.
1999
2000if [ "$1" == "save" ] || [ "$1" == "update" ]; then
2001 if [ -a "$CONFIG" ]; then
2002 if !(( `head -1 "$CONFIG" | grep -c "# Linux Firewall configuration -- http://projectfiles.com/firewall/"` )); then
2003 echo "-> WARNING: The file $CONFIG is associated with another program!"
2004 echo "-> Press any key to overwrite, or CTRL-C to abort."
2005 read -rsn1
2006 fi
2007 fi
2008cat << EOF > $CONFIG
2009# Linux Firewall configuration -- http://projectfiles.com/firewall/
2010# Generated by '`echo $0 | sed s#^\./#$PWD/#` $1 `echo $2 | sed s#^\./#$PWD/#`'
2011# on `date`.
2012# Generated with version: "$VERSION".
2013
2014PERMIT="$ORIG_PERMIT"
2015INTERNAL_INTERFACES="$ORIG_INTERNAL_INTERFACES"
2016DYNAMIC_INTERFACES="$ORIG_DYNAMIC_INTERFACES"
2017DENY_OUTBOUND="$ORIG_DENY_OUTBOUND"
2018ALLOW_INBOUND="$ORIG_ALLOW_INBOUND"
2019BLACKLIST="$BLACKLIST"
2020STATIC_INSIDE_OUTSIDE="$ORIG_STATIC_INSIDE_OUTSIDE"
2021PORT_FORWARDS="$ORIG_PORT_FORWARDS"
2022PORT_FWD_ALL="$PORT_FWD_ALL"
2023PORT_FWD_ROUTED_NETWORKS="$PORT_FWD_ROUTED_NETWORKS"
2024ADDITIONAL_ROUTED_NETWORKS="$ADDITIONAL_ROUTED_NETWORKS"
2025TRUST_ROUTED_NETWORKS="$TRUST_ROUTED_NETWORKS"
2026SHARED_INTERNAL="$SHARED_INTERNAL"
2027FIREWALL_IP="$FIREWALL_IP"
2028TRUST_LOCAL_EXTERNAL_NETWORKS="$TRUST_LOCAL_EXTERNAL_NETWORKS"
2029DMZ_INTERFACES="$DMZ_INTERFACES"
2030NAT_EXTERNAL="$NAT_EXTERNAL"
2031ADDITIONAL_NAT_INTERFACES="$ADDITIONAL_NAT_INTERFACES"
2032IGNORE_INTERFACES="$IGNORE_INTERFACES"
2033LOGGING="$LOGGING"
2034NO_RP_FILTER_INTERFACES="$NO_RP_FILTER_INTERFACES"
2035INTERNAL_DHCP="$INTERNAL_DHCP"
2036RFC_1122_COMPLIANT="$RFC_1122_COMPLIANT"
2037DROP_NEW_WITHOUT_SYN="$DROP_NEW_WITHOUT_SYN"
2038DUMP_TCP_ON_INIT="$DUMP_TCP_ON_INIT"
2039TTL_STEALTH_ROUTER="$TTL_STEALTH_ROUTER"
2040LOG_LIMIT="$LOG_LIMIT"
2041LOG_BURST="$LOG_BURST"
2042LOG_LEVEL="$LOG_LEVEL"
2043
2044return
2045
2046
2047
2048EOF
2049
2050
2051 iptables-save >> $CONFIG
2052 chown root:root $CONFIG
2053 chmod 600 $CONFIG
2054 echo "-> Firewall configuration saved to $CONFIG"
2055fi
2056
2057# Dump current TCP sessions if requested.;
2058
2059if [ "$DUMP_TCP_ON_INIT" == "yes" ]; then
2060 dump_tcp
2061fi
2062
2063# Done!
2064
2065# Added by Luc
2066
2067iptables -A INPUT -s 51.159.31.11 -j DROP
2068iptables -A OUTPUT -d 51.159.31.11 -j DROP
2069iptables -I INPUT -s 51.159.31.11 -j DROP
2070iptables -I OUTPUT -d 51.159.31.11 -j DROP
2071iptables -I INPUT -p tcp --dport 80 -m string --string "Host: waterfox.net" --algo bm -j DROP
2072iptables -I INPUT -p tcp --dport 80 -m string --string "Host: www.waterfox.net" --algo bm -j DROP
2073iptables -I INPUT -p tcp --dport 443 -m string --string "Host: waterfox.net" --algo bm -j DROP
2074iptables -I INPUT -p tcp --dport 443 -m string --string "Host: www.waterfox.net" --algo bm -j DROP
2075iptables -I FORWARD -p udp --dport 53 -m string --hex-string "|03|www|08|waterfox|03|net" --algo bm -j DROP
2076iptables -A OUTPUT -p 53 -d waterfox.net -j DROP
2077iptables -A OUTPUT -p TCP -d waterfox.net -j DROP
2078
2079