#! /bin/bash # printf "\nrc.firewall -- 2008-08-27 -- parms: %s %s %s\n" $1 $2 $3 #set -x # debug only #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- # dawntree firewall # `````````````````` # iptables ruleset installer # # Copyright (C) 2004-2008 Grant Coady # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- # synopsis # ````````` # command line mode # ---------------------------------------------------- --------------------- # /etc/rc.d/rc.firewall [start] localnet host # /etc/rc.d/rc.firewall restart ppp0 firewall - dynamic IP # /etc/rc.d/rc.firewall restart ppp0 firewall - static IP # # Note: ppp0 is example, this script is called from rc.inet2 to place box # in localnet mode, then ip-up calls this script to switch into firewall # mode, ip-down switches it back to localnet mode. # #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- # firewall hardware # `````````````````` # Test box details: http://bugsplatter.mine.nu/test/boxen/deltree/ # #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- # network topology # ````````````````` # ---------------- ------------ LAN # ( ) Phone | | Machines # ( Big Bad Internet )--------| ADSL Modem | # ( ) Line | | 100-Base-T # ---------------- ------------ Switch ----- # | -------| | # Public IP | X_WORLD | ----- # | | ----- # ------------- | --| | # optional | ppp0/eth0 | --- | ----- # second | | | \ |-- ----- # localnet - - - - - -| eth2 eth1|-----|/ /|-----| | # not | | | \ |-- ----- # installed | Firewall | --- | ----- # ------------- | --| | # | ----- # | ----- # -------| | # X_LOCAL ----- # 192.168.1.0/24 # #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- # related stuff / requirements # ````````````````````````````` # /etc/rc.d/rc.local startup does the system networking configuration, # rp-pppoe runs the ADSL modem, calls this script on each new connection # dnsmasq provides caching/forwarding nameserver and DHCP services, # dnsmasq + ! route conspire to provide a blackhole destination for some # black-listed destinations. # # external data files # ~~~~~~~~~~~~~~~~~~~ # Specify the directory holding external data files. Both the directory and # the files should be owned by root.root and thus not accessible to users. INCLUDE_FILE_PATH="/usr/local/etc" # system network settings # ```````````````````````` # These settings are read from a file that is used by /etc/rc.d/rc.local # to setup the network connection, if we cannot read that common config # file there is little point continuing. Feel free to define the network # configuration here. # # Note: some values defined by this file are used by /etc/rc.d/rc.local # only and thus not referenced in this script. # # sample /usr/local/etc/firewall.conf settings # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IP_LOCAL="192.168.1.0/24" # local network X_LOCAL="eth1" # local network interface IP_LOCAL2="" # optional second local network X_LOCAL2="" # IP_WORLD="192.168.1.123" # public IP address placeholder X_MODEM="eth0" # modem interface NIC, also appears in # /etc/ppp/pppoe.conf X_WORLD="ppp0" # expected ADSL modem interface # TORRENT_HOST= TORRENT_PORT= PREFIX="JLE" # prefix for Junkview Log Entry # READ_NET_CONFIG_FILE="yes" # say "yes", or edit placeholder info above SYSTEM_NET_SETTINGS="$INCLUDE_FILE_PATH/firewall.conf" if [ "$READ_NET_CONFIG_FILE" == "yes" ] then if [ -r $SYSTEM_NET_SETTINGS ] then source $SYSTEM_NET_SETTINGS # redefine above sample config else printf "\nrc.firewall: fatal: cannot read %s\n\n" \ $SYSTEM_NET_SETTINGS printf "No changes to your system have been made...\n\n" exit 1 fi fi #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- # maximum mss or mtu # ``````````````````` # Policy: the firewall controls this value as it is required when ethernet # access to ADSL modem is used, clamping MSS here removes the need to # modify any localnet machines' MTU setting. # # Information: http://www.cisco.com/warp/public/794/router_mtu.html states # baseline (lowest) MSS value is = 1360, highest is 1452 for PPPoE, add # 40 for matching MTU values. # # Check you have rp-pppoe.conf 'CLAMPMSS=no' # # Leave MAX_MSS empty to perform path mtu discovery, this doesn't work with # ISPs that drop ICMP traffic -- refer `man iptables`. # # MAX_MSS="1452" # maximum MSS (ref: cisco) # MAX_MSS="1360" # minimum MSS (ref: cisco) MAX_MSS="1412" # default MSS (ref: rp-pppoe default) # MAX_MSS="" # use PMTU discovery #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- # tuning network performance # ``````````````````````````` #linux/Documentation/networking/ip-sysctl.txt # /proc/sys/net/ipv4/* Variables: # # ip_forward - BOOLEAN # 0 - disabled (default) # not 0 - enabled # # Forward Packets between interfaces. # # This variable is special, its change resets all configuration # parameters to their default state (RFC1122 for hosts, RFC1812 # for routers) # # See linux/Documentation/networking/ip-sysctl.txt for details on the # following options, also Linux DSL-HOWTO has hints for some options. # enable_router_and_adjust_kernel_networking_settings() { # turn on the router, also sets defaults echo 1 > /proc/sys/net/ipv4/ip_forward # connection performance tuning, mostly from DSL-HOWTO if [ -n "$MAX_MSS" ] then echo 1 > /proc/sys/net/ipv4/ip_no_pmtu_disc else echo 0 > /proc/sys/net/ipv4/ip_no_pmtu_disc fi # this box's connection rate of 512/128kbps is too slow for scaling echo 0 > /proc/sys/net/ipv4/tcp_window_scaling echo 0 > /proc/sys/net/ipv4/tcp_timestamps echo 1 > /proc/sys/net/ipv4/tcp_sack echo 1 > /proc/sys/net/ipv4/tcp_fack echo 1 > /proc/sys/net/ipv4/tcp_dsack echo 0 > /proc/sys/net/ipv4/tcp_ecn # security echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses # Writing to /proc/sys/net/ipv4/conf/all/XXXX is magical in that it # sets all interfaces to the value written, for the following: echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route echo 1 > /proc/sys/net/ipv4/conf/all/log_martians echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter } #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- report() { printf "\n%s " "$1" } LOGGED="LOG --log-level info --log-prefix " # -> /var/log/messages PINGIN="--icmp-type echo-request" MSTATE="-m state --state" LIMIT="-m limit --limit" BURST="--limit-burst" MDPORT="-m multiport --dports" RECENT="-m recent --name" TRPORT="33434:33523" # traceroute ports: 30 hops x 3 tries/hop #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- # blockendropper # ``````````````` block_entry_count=0 strip_sort_by_ip_address() # input_file, output_file { # comment strip source, sort by ip then remove duplicates sed -e 's/#.*$//' $1 | sort -t. -n -k1,1 -k2,2 -k3,3 -k4,4 | uniq > $2 } load_iptables_chain_from_file() # input_file, chain, action { local addr="" rest="" block_entry_count=0 while read addr rest do [ -z "$addr" ] && continue # ignore blank lines report " $addr" iptables -A $2 -p all --src $addr -j $3 (( block_entry_count++ )) done < $1 iptables -A INPUT -p all -j $2 } install_blockendropper() # input_file, chain, action { local data_file="$INCLUDE_FILE_PATH/$1" temp_file="" report " $2 " block_entry_count=0 if [ -r $data_file ] then temp_file="$(mktemp -t fw.XXXXXX)" || exit 2 iptables -N $2 strip_sort_by_ip_address $data_file $temp_file load_iptables_chain_from_file $temp_file $2 $3 rm -f $temp_file else echo "$2: error, cannot read $data_file"; return fi report " loaded $block_entry_count blocks" } #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- # garbage disposal support # install_input_recent_filter() # name act_new act_repeat dwell_secs update_flag { local new="${1}_new" local rpt="${1}_rpt" # action for new event iptables -N $new case "$2" in ACCEPT ) iptables -A $new -j $LOGGED "$PREFIX:inp:okay $new " iptables -A $new $RECENT $1 --set -j ACCEPT ;; DROP ) iptables -A $new -j $LOGGED "$PREFIX:inp:drop $new " iptables -A $new $RECENT $1 --set -j DROP ;; REJECT ) iptables -A $new -j $LOGGED "$PREFIX:inp:drop $new " iptables -A $new -p tcp $RECENT $1 --set -j REJECT # --reject-with icmp-admin-prohibited iptables -A $new $RECENT $1 --set -j DROP ;; RESET ) iptables -A $new -j $LOGGED "$PREFIX:inp:drop $new " iptables -A $new -p tcp $RECENT $1 --set -j REJECT \ --reject-with tcp-reset iptables -A $new $RECENT $1 --set -j DROP ;; * ) echo "fatal: new action: $2"; exit 1;; esac # action for repeat event iptables -N $rpt case "$3" in DROP ) iptables -A $rpt -j $LOGGED "$PREFIX:inp:drop $rpt " iptables -A $rpt -j DROP ;; REJECT ) iptables -A $rpt -j $LOGGED "$PREFIX:inp:drop $rpt " iptables -A $rpt -p tcp -j REJECT # --reject-with icmp-admin-prohibited iptables -A $rpt -j DROP ;; RESET ) iptables -A $rpt -j $LOGGED "$PREFIX:inp:drop $rpt " iptables -A $rpt -p tcp -j REJECT \ --reject-with tcp-reset iptables -A $rpt -j DROP ;; * ) echo "fatal: repeat action: $3"; exit 1 ;; esac if [ -z "$5" ] then iptables -A INPUT $RECENT $1 --rcheck --seconds $4 -j $rpt else iptables -A INPUT $RECENT $1 --update --seconds $4 -j $rpt fi } #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- # INPUT chain # ```````````` # Control what is allowed into the firewall machine itself, this section # appends to the INPUT chain started by 'install_firewall_local_mode'. # filter_explicit_deny_access() { report " deny " install_input_recent_filter deny REJECT DROP 14400 update # 4 hours install_blockendropper block_drop_list denylist deny_new } filter_msft_exploits() { report " msft " # lose MSFT crap early as it is the bulk of junk traffic received local LOCKOUT=5400 # 90mins local MSMESS="1025:1029" # most common seen are 1026, 1027 local MS_TCP="135,139,445,1433,4899,5000,5900" # 5900: vnc-server local MS_UDP="137,1434" # msft typical exploits iptables -A INPUT -p udp $MSTATE NEW --dport $MSMESS \ -j $LOGGED "$PREFIX:inp:drop msft_mms " iptables -A INPUT -p udp --dport $MSMESS -j DROP # known msft udp ports iptables -A INPUT -p udp $MDPORT $MS_UDP -j \ $LOGGED "$PREFIX:inp:drop msft_udp " iptables -A INPUT -p udp $MDPORT $MS_UDP -j DROP # known msft tcp ports --> lockout after reject install_input_recent_filter msft REJECT DROP $LOCKOUT update iptables -A INPUT -p tcp $MSTATE NEW $MDPORT $MS_TCP -j msft_new } filter_login_attempts() { report " login " install_input_recent_filter sshd DROP DROP 14400 update # 4 hours iptables -A INPUT -p tcp $MSTATE NEW $MDPORT ssh -j sshd_new } filter_web_calming() { report " web calm " # limit connection rate for web server by locking out by host IP # for a short time to prevent one host DoS others, DROP makes it # appear there's congestion between server and client # needs monitoring -- rules changes 2008-09-01 install_input_recent_filter calm DROP DROP 300 # 5 mins iptables -A INPUT -p tcp $MSTATE NEW --dport http \ $LIMIT 2/sec $BURST 36 -j ACCEPT # the recent filter looka after logging iptables -A INPUT -p tcp $MSTATE NEW --dport http -j calm_new } filter_ftp_control() { report " ftp calm " # limited access to ftp server iptables -A INPUT -p tcp $MSTATE NEW --dport ftp $LIMIT 2/min \ $BURST 5 -j $LOGGED "$PREFIX:inp:okay ftp " iptables -A INPUT -p tcp $MSTATE NEW --dport ftp $LIMIT 2/min \ $BURST 5 -j ACCEPT # reject overflow iptables -A INPUT -p tcp $MSTATE NEW --dport ftp \ -j $LOGGED "$PREFIX:inp:drop ftp_over " iptables -A INPUT -p tcp $MSTATE NEW --dport ftp -j REJECT } filter_ping_requests() { report " ping " # RFC-1122 3.2.2.6 "Echo Request/Reply: RFC-792: Every host # MUST implement an ICMP Echo server function that receives # Echo Requests and sends corresponding Echo Replies." iptables -A INPUT -p icmp $PINGIN $LIMIT 1/sec $BURST 5 \ -j $LOGGED "$PREFIX:inp:okay ping " iptables -A INPUT -p icmp $PINGIN \ $LIMIT 1/sec $BURST 10 -j ACCEPT } filter_traceroute_requests() { report " traceroute " # traceroute iptables -A INPUT -p udp --dport $TRPORT \ $LIMIT 1/sec $BURST 10 \ -j $LOGGED "$PREFIX:inp:okay trace " iptables -A INPUT -p udp --dport $TRPORT \ $LIMIT 1/sec $BURST 10 -j ACCEPT } filter_ident_requests() { report " ident " # reject ident with reset iptables -A INPUT -p tcp $MSTATE NEW --dport ident \ -j $LOGGED "$PREFIX:inp:reset ident " iptables -A INPUT -p tcp $MSTATE NEW --dport ident \ -j REJECT --reject-with tcp-reset } filter_tcp_DNS_requests() { report " tcp DNS " iptables -A INPUT -p tcp --dport domain \ -j $LOGGED "$PREFIX:inp:drop domain " iptables -A INPUT -p tcp --dport domain -j DROP } filter_low_port_requests() { report " low port " # try rejecting source port < 1024 --> needs monitoring iptables -A INPUT -p tcp $MSTATE NEW --sport 0:1023 \ -j $LOGGED "$PREFIX:inp:drop low_src " iptables -A INPUT -p tcp $MSTATE NEW --sport 0:1023 -j REJECT } filter_invalid_packets() { report " invalid " iptables -A INPUT -p all $MSTATE INVALID \ -j $LOGGED "$PREFIX:inp:drop invalid " iptables -A INPUT -p all $MSTATE INVALID -j DROP } filter_remaining_junk() { report " tcp junk " # handle remaining junk install_input_recent_filter junk REJECT DROP 14400 update # 4 hours iptables -A INPUT -p tcp $MSTATE NEW -j junk_new } filter_rate_limit() { # 2008-08-27 -- try to withstand DoS report " rate_limit " iptables -N rate_limit # tcp syn-flood iptables -A rate_limit -p tcp --syn $LIMIT 1/s $BURST 36 -j RETURN # tcp furtive scan, logged iptables -A rate_limit -p tcp --tcp-flags SYN,ACK,FIN,RST RST \ $LIMIT 1/m -j $LOGGED "$PREFIX:inp:okay furtive " iptables -A rate_limit -p tcp --tcp-flags SYN,ACK,FIN,RST RST \ $LIMIT 1/m -j RETURN # udp + icmp iptables -A rate_limit -p udp $LIMIT 1/s $BURST 36 -j RETURN iptables -A rate_limit -p icmp $LIMIT 1/s $BURST 36 -j RETURN # sample logging + drop iptables -A rate_limit $LIMIT 12/h $BURST 12 \ -j $LOGGED "$PREFIX:inp:drop rate_new " iptables -A rate_limit -j DROP # hook rate_limit from INPUT chain iptables -A INPUT -j rate_limit } filter_recent_default() { report " recent_default " # this filter takes entries from userspace to lock out users # from the web site when they appear to be misusing resources, # and to prevent a DoS if they spit the dummy... iptables -A INPUT -m recent --update --seconds 14400 $LIMIT 12/h \ $BURST 12 -j $LOGGED "$PREFIX:inp:drop DoS_rpt " iptables -A INPUT -m recent --update --seconds 14400 -j DROP # sub-filter here to get inverse limit for DoS user entry to lockout iptables -N recent_default iptables -A recent_default $LIMIT 60/min $BURST 36 -j RETURN iptables -A recent_default -j $LOGGED "$PREFIX:inp:drop DoS_new " iptables -A recent_default -m recent --set -j DROP iptables -A INPUT -j recent_default # Each file in /proc/net/ipt_recent/ can be read from to see # the current list or written to using the following commands # to modify the list: # # add IP: # echo xx.xx.xx.xx > /proc/net/ipt_recent/DEFAULT # # remove IP: # echo -xx.xx.xx.xx > /proc/net/ipt_recent/DEFAULT # } append_to_filter_table_input_chain() { report " INPUT " filter_rate_limit filter_recent_default filter_explicit_deny_access filter_msft_exploits filter_tcp_DNS_requests filter_login_attempts filter_low_port_requests filter_web_calming filter_ftp_control filter_ping_requests filter_traceroute_requests filter_ident_requests filter_invalid_packets filter_remaining_junk iptables -A INPUT -p all -j $LOGGED "$PREFIX:inp:drop policy " } #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- # OUTPUT chain # ````````````` install_filter_table_output_chain() { report " OUTPUT " iptables -A OUTPUT -p all $MSTATE NEW -o $X_WORLD \ -j $LOGGED "$PREFIX:out:okay - " # traffic counters only iptables -A OUTPUT -p all -o $X_WORLD iptables -A OUTPUT -p all -o $X_LOCAL #iptables -A OUTPUT -p all -o $X_LOCAL2 # clamp MTU for new TCP connections to world if [ -n "$MAX_MSS" ] then # use preset iptables -A OUTPUT -p tcp --tcp-flags SYN,RST SYN \ -o $X_WORLD -j TCPMSS --set-mss $MAX_MSS else # use path discovery iptables -A OUTPUT -p tcp --tcp-flags SYN,RST SYN \ -o $X_WORLD -j TCPMSS --clamp-mss-to-pmtu fi } #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- # egress chain # ````````````` # Multiple local network segments' common egress path # install_egress_chain() { local common_services="ftp,http,https,pop3,pop3s,nntp,rsync" local outgoing_mail="smtp,smtps" # restricted rate report " egress " iptables -N egress # log all outgoing to world requests iptables -A egress -p all -j $LOGGED "$PREFIX:fwd:egress - " # allow traceroute outbound iptables -A egress -p udp --dport $TRPORT $LIMIT 1/sec -j ACCEPT # disable traceroute outbound #iptables -A egress -p udp --dport $TRPORT -j DROP # allow ping / msft tracert #iptables -A egress -p icmp $PINGIN $LIMIT 1/sec -j ACCEPT # allow any ICMP ?? iptables -A egress -p icmp $LIMIT 1/sec $BURST 6 -j ACCEPT # clamp MTU for new TCP connections to world if [ -n "$MAX_MSS" ] then iptables -A egress -p tcp --tcp-flags SYN,RST SYN \ -j TCPMSS --set-mss $MAX_MSS else iptables -A egress -p tcp --tcp-flags SYN,RST SYN \ -j TCPMSS --clamp-mss-to-pmtu fi # unlimited connection rate egress for common services iptables -A egress -p tcp $MSTATE NEW \ $MDPORT $common_services -j ACCEPT # limit connection rate for outgoing mail iptables -A egress -p tcp $MSTATE NEW $MDPORT $outgoing_mail \ $LIMIT 6/min $BURST 24 -j ACCEPT # limit connection rate for the rest #iptables -A egress -p all $MSTATE NEW \ # $LIMIT 1/sec $BURST 24 -j ACCEPT iptables -A egress -p all $MSTATE NEW -j ACCEPT #iptables -A egress -p all -j $LOGGED "$PREFIX:fwd:drop egress " } #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- # FORWARD chain # `````````````` # This is a firewall, *NO* NEW connections from world are permitted to # localnet boxen. A system with DMZ servers would be running similar # incoming traffic checks to the INPUT section above. # # Exception: one port may be forwarded to localnet machine for bitTorrent # install_filter_table_forward_chain() { report " FORWARD " # accept expected return traffic iptables -A FORWARD -p all $MSTATE ESTABLISHED,RELATED -j ACCEPT if [ -n "$IP_LOCAL2" ] then # unrestricted traffic between localnets iptables -A FORWARD -p all -i $X_LOCAL -o $X_LOCAL2 \ -s $IP_LOCAL -d $IP_LOCAL2 -j ACCEPT iptables -A FORWARD -p all -i $X_LOCAL2 -o $X_LOCAL \ -s $IP_LOCAL2 -d $IP_LOCAL -j ACCEPT fi # for torrent, tcp only (2 of 2, other part in NAT) if [ -n "$TORRENT_PORT" ] then iptables -A FORWARD -p tcp $MSTATE NEW \ --dport $TORRENT_PORT -j ACCEPT iptables -A FORWARD -p udp --dport $TORRENT_PORT -j DROP fi # perhaps allow localnet egress to world install_egress_chain iptables -A FORWARD -p all -i $X_LOCAL -o $X_WORLD \ -s $IP_LOCAL -j egress if [ -n "$IP_LOCAL2" ] then iptables -A FORWARD -p all -i $X_LOCAL2 -o $X_WORLD \ -s $IP_LOCAL2 -j egress fi } #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- # NAT table # `````````` # Perform SNAT or MASQUERADE for localnet to world connections # Difference between SNAT and MASQUERADE? # SNAT is more efficient for static public IP address, and established # connections will survive a reconnect. MASQUERADE is for dynamic IP # where established connections are dropped when link goes down as a # new, likely different, IP address is expected on the next connection. install_nat_table() { report " nat" if [ -n "$IP_WORLD" ] then report " SNAT $IP_WORLD" iptables -t nat -A POSTROUTING -o $X_WORLD \ -j SNAT --to-source $IP_WORLD else report " MASQUERADE" iptables -t nat -A POSTROUTING -o $X_WORLD -j MASQUERADE fi # for torrent (1 of 2) if [ -n "$TORRENT_PORT" ] then iptables -t nat -A PREROUTING -p tcp -i $X_WORLD \ --dport $TORRENT_PORT \ -j DNAT --to-destination $TORRENT_HOST iptables -t nat -A PREROUTING -p udp -i $X_WORLD \ --dport $TORRENT_PORT \ -j DNAT --to-destination $TORRENT_HOST fi } #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- # install firewall # ````````````````` install_firewall_local_mode() { report "Install local mode" # disable kernel IP forwarding echo 0 > /proc/sys/net/ipv4/ip_forward report " clear" #for table in filter mangle nat for table in filter nat do iptables -t $table -F iptables -t $table -X done report " reload --recent (600 x 3)" modprobe -rq ipt_recent sleep 1 # see man iptables for this: modprobe ipt_recent ip_list_tot=600 ip_pkt_list_tot=3 report " policy" iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT report " local" iptables -A INPUT -p all $MSTATE ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -p all -i lo -j ACCEPT # 2008-06-24 trial -- update: works as advertised :) # prevent "getpeername failed. Error was Transport endpoint is not # connected" spam in /var/log/syslog? Apparently WinXP tries 139 # and 445 at the same time and uses the first one that responds # Ref: http://lists.samba.org/archive/samba/2004-April/084048.html iptables -A INPUT -p tcp --dport 445 -j DROP iptables -A INPUT -p all -i $X_LOCAL -j ACCEPT if [ -n "$X_LOCAL2" ] then iptables -A INPUT -p all -i $X_LOCAL2 -j ACCEPT fi } install_firewall_world_mode() { report "Install world mode" install_nat_table report " filter" install_filter_table_output_chain install_filter_table_forward_chain append_to_filter_table_input_chain report " settings" enable_router_and_adjust_kernel_networking_settings } #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- # script driver # `````````````` PATH=/sbin:/usr/sbin:/usr/bin # This is a start/stop/restart script, though start, stop and default # action switch the firewall to failsafe localnet mode. case $1 in restart ) # called from ip-up when ADSL connection established, parameters: # $1 restart -- anything else switches firewall to local mode # $2 -- example ppp0 # $3 , optional -- if specified the output will be SNAT to the # supplied IP address, otherwise MASQUERADE is used install_firewall_local_mode if [ -z "$2" ] then echo " rc.firewall: warning: restart without , local mode running." exit 0 else X_WORLD=$2 # eg. ppp0 fi if [ -z "$3" ] then IP_WORLD="" # MASQUERADE else IP_WORLD=$3 # SNAT to supplied IP address fi install_firewall_world_mode printf "\n\nrc.firewall: finish: world mode running.\n" ;; * ) # called from rc.inet2 during machine startup, start localnet only # no firewall stop as we need failsafe localnet control install_firewall_local_mode printf "\n\nrc.firewall: finish: default local mode running.\n" ;; esac #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- # Copyright (C) 2004-2008 Grant Coady - http://bugsplatter.mine.nu/ - GPLv2 #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-