#!/bin/sh # # ********** VARIABLE DEFINITIONS ********** # # External interface EXTIF="eth1" # Internal interface INTIF="eth0" # Loop device/localhost LPDIF="lo" LPDIP="127.0.0.1" LPDMSK="255.0.0.0" LPDNET="$LPDIP/$LPDMSK" # Text tools variables IPT="/sbin/iptables" IFC="/sbin/ifconfig" G="/bin/grep" SED="/bin/sed" AWK="/bin/awk" # Setting up external interface environment variables # The following doesn't play nice with localization #EXTIP="`$IFC $EXTIF|$G addr:|$SED 's/.*addr:\([^ ]*\) .*/\1/'`" # This one does AFAIK EXTIP="`$IFC $EXTIF|$AWK /$EXTIF/'{next}//{split($0,a,":");split(a[2],a," ");print a[1];exit}'`" #EXTBC="`$IFC $EXTIF|$G Bcast:|$SED 's/.*Bcast:\([^ ]*\) .*/\1/'`" EXTBC="255.255.255.255" # same problem here with localization EXTMSK="`$IFC $EXTIF|$G Mask:|$SED 's/.*Mask:\([^ ]*\)/\1/'`" EXTMSK="`$IFC $EXTIF|$AWK /$EXTIF/'{next}//{split($0,a,":");split(a[4],a," ");print a[1];exit}'`" EXTNET="$EXTIP/$EXTMSK" echo "EXTIP=$EXTIP EXTBC=$EXTBC EXTMSK=$EXTMSK EXTNET=$EXTNET" # Due to absence of EXTBC I manually set it to 255.255.255.255 # this (hopefully) will serve the same purpose # Setting up environment variables for internal interface INTIP="`$IFC $INTIF|$AWK /$INTIF/'{next}//{split($0,a,":");split(a[2],a," ");print a[1];exit}'`" #INTIP="`$IFC $INTIF|$G addr:|$SED 's/.*addr:\([^ ]*\) .*/\1/'`" INTBC="`$IFC $INTIF|$AWK /$INTIF/'{next}//{split($0,a,":");split(a[3],a," ");print a[1];exit}'`" #INTBC="`$IFC $INTIF|$G Bcast:|$SED 's/.*Bcast:\([^ ]*\) .*/\1/'`" INTMSK="`$IFC $INTIF|$AWK /$INTIF/'{next}//{split($0,a,":");split(a[4],a," ");print a[1];exit}'`" #INTMSK="`$IFC $INTIF|$G Mask:|$SED 's/.*Mask:\([^ ]*\)/\1/'`" INTNET="$INTIP/$INTMSK" echo "INTIP=$INTIP INTBC=$INTBC INTMSK=$INTMSK INTNET=$INTNET" # Last but not least, the users for owner matching P2PUSER="root" # ********** INITIALIZATION ********** # # Deny then accept: this keeps holes from opening up # while we close ports and such $IPT -P INPUT DROP $IPT -P OUTPUT DROP $IPT -P FORWARD DROP #IPT -P INPUT ACCEPT #IPT -P OUTPUT ACCEPT #IPT -P FORWARD ACCEPT # Flush all existing chains and erase personal chains CHAINS=`cat /proc/net/ip_tables_names 2>/dev/null` for i in $CHAINS; do $IPT -t $i -F done for i in $CHAINS; do $IPT -t $i -X done # enable syncookies & ignore icmp broadcasts echo 1 > /proc/sys/net/ipv4/tcp_syncookies echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts # Source Address Verification for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 1 > $f done # Disable IP source routing and ICMP redirects for f in /proc/sys/net/ipv4/conf/*/accept_source_route; do echo 0 > $f done for f in /proc/sys/net/ipv4/conf/*/accept_redirects; do echo 0 > $f done # Log Martians for i in /proc/sys/net/ipv4/conf/*/log_martians ; do echo 1 > $i done # activate forwarding & dynamic address echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv4/ip_dynaddr # Loading necessary kernel modules # example: MODULES="ip_nat_ftp ip_conntrack_ftp" MODULES="ipt_owner" for i in $MODULES; do echo "Inserting module $i" modprobe $i done # ********** LOGGING CHAINS ********** # # We are now going to create a few custom chains that will result in # logging of dropped packets. This will enable us to avoid having to # enter a log command prior to every drop we wish to log. The # first will be first log drops the other will log rejects. # Do not complain if chain already exists (so restart is clean) $IPT -N DROPl 2> /dev/null $IPT -A DROPl -m limit --limit 3/minute --limit-burst 10 -j LOG --log-prefix 'FIREWALL DROP BLOCKED:' $IPT -A DROPl -j DROP $IPT -N REJECTl 2> /dev/null $IPT -A REJECTl -m limit --limit 3/minute --limit-burst 10 -j LOG --log-prefix 'FIREWALL REJECT BLOCKED:' $IPT -A REJECTl -j REJECT $IPT -N DROP2 2> /dev/null $IPT -A DROP2 -m limit --limit 3/second --limit-burst 10 -j LOG --log-prefix 'FIREWALL DROP UNKNOWN:' $IPT -A DROP2 -j DROP $IPT -N REJECT2 2> /dev/null $IPT -A REJECT2 -m limit --limit 3/second --limit-burst 10 -j LOG --log-prefix 'FIREWALL REJECT UNKNOWN:' $IPT -A REJECT2 -j REJECT # For testing, a logging ACCEPT chain $IPT -N ACCEPTl 2> /dev/null $IPT -A ACCEPTl -m limit --limit 10/second --limit-burst 50 -j LOG --log-prefix 'FIREWALL ACCEPT:' $IPT -A ACCEPTl -j ACCEPT # ********** SANE COMMON RULES ********** # # Now we are going to accept all traffic from or to our loopback device # if the IP matches any of our interfaces. $IPT -A INPUT -i $LPDIF -s $LPDIP -j ACCEPT $IPT -A INPUT -i $LPDIF -s $EXTIP -j ACCEPT $IPT -A INPUT -i $LPDIF -s $INTIP -j ACCEPT $IPT -A OUTPUT -o $LPDIF -d $LPDIP -j ACCEPT $IPT -A OUTPUT -o $LPDIF -d $EXTIP -j ACCEPT $IPT -A OUTPUT -o $LPDIF -d $INTIP -j ACCEPT # Blocking Broadcasts $IPT -A INPUT -i $EXTIF -d $EXTBC -j DROPl $IPT -A INPUT -i $INTIF -d $INTBC -j DROPl $IPT -A OUTPUT -o $EXTIF -d $EXTBC -j DROPl $IPT -A OUTPUT -o $INTIF -d $INTBC -j DROPl $IPT -A FORWARD -o $EXTIF -d $EXTBC -j DROPl $IPT -A FORWARD -o $INTIF -d $INTBC -j DROPl # Block WAN access to internal network # This also stops nefarious crackers from using our network as a # launching point to attack other people # iptables translation: # "if input going into our external interface does not our isp assigned # ip address, drop it like a hot potato $IPT -A INPUT -i $EXTIF -d ! $EXTIP -j DROPl # Now we will block internal addresses originating from anything but our # predefined interface.....just remember that if you jack your # laptop or another pc into one of these NIC's directly, you'll need # to ensure that they either have the same ip or that you add a line explicitly # that IP as well # Interface one/internal net one $IPT -A INPUT -i $INTIF -s ! $INTNET -j DROPl $IPT -A OUTPUT -o $INTIF -d ! $INTNET -j DROPl $IPT -A FORWARD -i $INTIF -s ! $INTNET -j DROPl $IPT -A FORWARD -o $INTIF -d ! $INTNET -j DROPl # An additional Egress check $IPT -A OUTPUT -o $EXTIF -s ! $EXTNET -j DROPl # Block outbound ICMP (except for PING) $IPT -A OUTPUT -o $EXTIF -p icmp \ --icmp-type ! 8 -j DROPl $IPT -A FORWARD -o $EXTIF -p icmp \ --icmp-type ! 8 -j DROPl # Allow to ping out $IPT -A OUTPUT -o $EXTIF -p icmp -s $EXTIP \ --icmp-type 8 -m state --state NEW -j ACCEPT $IPT -A FORWARD -i $INTIF -p icmp -s $INTNET \ --icmp-type 8 -m state --state NEW -j ACCEPT # Allow internal network to ping internal systems $IPT -A OUTPUT -o $INTIF -p icmp -s $INTNET \ --icmp-type 8 -m state --state NEW -j ACCEPT $IPT -A INPUT -i $INTIF -p icmp -s $INTNET \ --icmp-type 8 -m state --state NEW -j ACCEPT # ********** BLOCKING THE EVIL PORTS ********** # # COMmon ports: # 0 is tcpmux; SGI had vulnerability, 1 is common attack # 13 is daytime # 98 is Linuxconf # 111 is sunrpc (portmap) # 135 is DCOM RPC # 137:139, 445 is Microsoft # SNMP: 161,2 # Squid flotilla: 3128, 8000, 8008, 8080 # 1214 is Morpheus or KaZaA # 2049 is NFS # 3049 is very virulent Linux Trojan, mistakable for NFS # Common attacks: 1999, 4329, 6346 (gnutella - removed) # Common Trojans 12345 65535 INTCOMBLOCK="0:1 13 98 111 135 161:162 1214 1999 2049 3049 4329 3128 8000 8008 8080 12345 65535" EXTCOMBLOCK="137:139 445" # TCP ports: # 512-5!5 is rexec, rlogin, rsh, printer(lpd) # [very serious vulnerabilities; attacks continue daily] # 1080 is Socks proxy server # 6000 is X (NOTE X over SSH is secure and runs on TCP 22) # Block 6112 (Sun's/HP's CDE) INTTCPBLOCK="$INTCOMBLOCK 512:515 1080 6000:6009 6112" EXTTCPBLOCK="$INTCOMBLOCK $EXTCOMBLOCK 512:515 1080 6000:6009 6112" # UDP ports: # 161:162 is SNMP # 520=RIP, 9000 is Sangoma # 517:518 are talk and ntalk (more annoying than anything) INTUDPBLOCK="$INTCOMBLOCK 161:162 520 517:518 1427 9000" EXTUDPBLOCK="$INTCOMBLOCK $EXTCOMBLOCK 161:162 520 123 517:518 1427 9000" echo -n "FW: Blocking internal attacks to TCP port: " for i in $INTTCPBLOCK; do echo -n "$i " $IPT -A INPUT -p tcp -s $INTNET --dport $i -j DROPl $IPT -A OUTPUT -p tcp -s $INTNET --dport $i -j DROPl $IPT -A FORWARD -p tcp -s $INTNET --dport $i -j DROPl done echo "" echo -n "FW: Blocking external attacks to TCP port: " for i in $EXTTCPBLOCK; do echo -n "$i " $IPT -A INPUT -p tcp -s ! $INTNET --dport $i -j DROPl $IPT -A OUTPUT -p tcp -s ! $INTNET --dport $i -j DROPl $IPT -A FORWARD -p tcp -s ! $INTNET --dport $i -j DROPl done echo "" echo -n "FW: Blocking internal attacks to UDP port: " for i in $INTUDPBLOCK; do echo -n "$i " $IPT -A INPUT -p udp -s $INTNET --dport $i -j DROPl $IPT -A OUTPUT -p udp -s $INTNET --dport $i -j DROPl $IPT -A FORWARD -p udp -s $INTNET --dport $i -j DROPl done echo "" echo -n "FW: Blocking external attacks to UDP port: " for i in $EXTUDPBLOCK; do echo -n "$i " $IPT -A INPUT -p udp -s ! $INTNET --dport $i -j DROPl $IPT -A OUTPUT -p udp -s ! $INTNET --dport $i -j DROPl $IPT -A FORWARD -p udp -s ! $INTNET --dport $i -j DROPl done echo "" # ********** ALLOWING INSIDE TO OUTSIDE SERVICES ********** # # This is where things go you want to use from your network on the internet # # Defining some common chat clients. Remove these from your accepted list for better security. IRC='ircd' MSN=1863 ICQ=5190 NFS='sunrpc' # We have to sync!! PORTAGE='rsync' OpenPGP_HTTP_Keyserver=11371 Secure_SMTP=465 # All services ports are read from /etc/services TCPSERV="domain ssh ntp http https ftp ftp-data mail pop3 pop3s imap3 imaps imap2 time $PORTAGE $IRC $OpenPGP_HTTP_Keyserver $Secure_SMTP 5154 2401" UDPSERV="domain time ntp 5154" echo -n "FW: Allowing inside systems to use services: " for i in $TCPSERV; do echo -n "$i " $IPT -A OUTPUT -o $EXTIF -p tcp -s $EXTIP \ --dport $i --syn -m state --state NEW -j ACCEPT $IPT -A FORWARD -i $INTIF -p tcp -s $INTNET \ --dport $i --syn -m state --state NEW -j ACCEPT done echo "" echo -n "FW: Allowing inside systems to use services: " for i in $UDPSERV; do echo -n "$i " $IPT -A OUTPUT -o $EXTIF -p udp -s $EXTIP \ --dport $i -m state --state NEW -j ACCEPT $IPT -A FORWARD -i $INTIF -p udp -s $INTNET \ --dport $i -m state --state NEW -j ACCEPT done echo "" # ********** ALLOWING SERVICES ON FIREWALL ********** # # DAEMONS on firewall which should be accessible to inside/outside. # it is presumed that DAEMONS advertised to the outside can also # be advertised safely to the inside # # This is generally NOT A GOOD IDEA (as told by "security experts") # since if some service on this machine gets hacked, the firewall is # compromised as well, but what the heck ;) it's only a home network # # 50369 is my p2p port # microsoft-ds is for samba # 5901 is vnc # domain is nameserver # ntp is for timeserving #EXTTCPDAEMONS="ssh http https ftp ftp-data mail pop3 pop3s imap3 imaps imap2" EXTTCPDAEMONS="ssh auth 50369" INTTCPDAEMONS="$EXTTCPDAEMONS 67 microsoft-ds" EXTUDPDAEMONS="" INTUDPDAEMONS="$EXTUDPDAEMONS 67 domain ntp" echo -n "FW: Allowing external systems to use tcp services on localhost: " for i in $EXTTCPDAEMONS; do echo -n "$i " $IPT -A INPUT -i $EXTIF -p tcp -d $EXTIP \ --dport $i --syn -m state --state NEW -j ACCEPT done echo "" echo -n "FW: Allowing internal systems to use tcp services on localhost: " for i in $INTTCPDAEMONS; do echo -n "$i " $IPT -A INPUT -i $INTIF -p tcp -d $INTIP \ --dport $i --syn -m state --state NEW -j ACCEPT done echo "" echo -n "FW: Allowing external systems to use udp services on localhost: " for i in $EXTUDPDAEMONS; do echo -n "$i " $IPT -A INPUT -i $EXTIF -p udp -d $EXTIP \ --dport $i -m state --state NEW -j ACCEPT done echo "" echo -n "FW: Allowing internal systems to use udp services on localhost: " for i in $INTUDPDAEMONS; do echo -n "$i " $IPT -A INPUT -i $INTIF -p udp -d $INTIP \ --dport $i -m state --state NEW -j ACCEPT done echo "" echo "FW: Allowing broadcasts to go out on ntp & microsoft-ds ports " $IPT -A OUTPUT -s $INTIP -d $INTBC -p udp --sport ntp -j ACCEPT $IPT -A OUTPUT -o $INTIF -s $INTIP -d $INTBC -p udp --sport microsoft-ds -j ACCEPT # # Even worse idea :) # # Allowing all packages generated by processes owned by the P2PUSER out $IPT -A OUTPUT -o $EXTIF -d ! $INTNET -m owner --uid-owner $P2PUSER -j ACCEPT # ********** FINALIZING NAT & FIREWALL ********** # # Setup NAT $IPT -t nat -A PREROUTING -j ACCEPT $IPT -t nat -A POSTROUTING -o $EXTIF -s $INTNET -j MASQUERADE $IPT -t nat -A POSTROUTING -j ACCEPT $IPT -t nat -A OUTPUT -j ACCEPT # allow existing connections $IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPT -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPT -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # block and log what me may have forgot $IPT -A INPUT -j DROP2 $IPT -A OUTPUT -j REJECT2 $IPT -A FORWARD -j DROP2