= Firewalls = For a brief introduction see [[attachment:Filtering Firewalls in Linux.ppt]] If you are using Ubuntu, you should look at the ubuntul [[https://help.ubuntu.com/community/IptablesHowTo|Iptables Howto]]. Take special note of the iptables-apply script that you should use to test your connection. This page includes firewall examples that were used on an actual (although now non-existent) network. It successfully protected some 16 static IPs for six years. At one time I recorded a 3-way coordinated attack from university networks in Italy, France and Germany. Through all this time, the bridging firewall was used successfully to protect a small business with several computers. The script that follows is final form. == Bridge Setup == {{{ #! /bin/bash # /etc/rc.d/init.d/bridge # return=$rc_done case "$1" in start) echo "Starting service bridge br0" ifconfig eth0 0.0.0.0 promisc ifconfig eth1 0.0.0.0 promisc brctl addbr br0 || return=$rc_failed brctl addif br0 eth0 || return=$rc_failed brctl addif br0 eth1 || return=$rc_failed brctl sethello br0 1 || return=$rc_failed brctl setmaxage br0 4 || return=$rc_failed brctl setfd br0 4 || return=$rc_failed ifconfig br0 promisc up 209.50.17.211 netmask 255.255.255.240 broadcast 209.50.17.223 || return=$rc_failed route add default gw 209.50.17.209 echo -e "$return" ;; stop) echo "Shutting down service bridge br0" ifconfig br0 down || return=$rc_failed brctl delif br0 eth0 || return=$rc_failed brctl delif br0 eth1 || return=$rc_failed brctl delbr br0 || return=$rc_failed ifconfig eth0 down || return=$rc_failed ifconfig eth1 down || return=$rc_failed route del default echo -e "$return" ;; status) ifconfig br0 brctl show br0 ;; restart) $0 stop && $0 start || return=$rc_failed ;; *) echo "Usage: $0 {start|stop|status|restart}" exit 1 esac test "$return" = "$rc_done" || exit 1 exit 0 }}} == Firewall Setup == {{{ #! /bin/bash # /etc/init.d/firewall # return=$rc_done case "$1" in start) ############################################################################### #SETUP INFORMATION INTERNET="eth0" DMZ="eth1" LOOPBACK_INTERFACE="lo" CONNECTION_TRACKING="1" ICMP_STRICT="1" L2TP="0" INET_SSH="0" BRAIN="209.50.17.210" BRAIN2="209.50.17.212" CISCO="209.50.17.209" YAKKO="209.50.17.215" CSE="129.93.165.2" TIMESERVER1="132.163.4.101" TIMESERVER2="132.163.4.102" TIMESERVER3="132.163.4.103" DMZ_NETWORK="209.50.17.213-222" SUBNET_BROADCAST="209.50.17.223" SUBNET_NETWORK="209.50.17.208" LOOPBACK="127.0.0.0/8" CLASS_A="10.0.0.0/8" CLASS_B="172.16.0.0/12" CLASS_C="192.168.0.0/16" CLASS_D_MULTICAST="224.0.0.0/4" CLASS_E_RESERVED_NET="240.0.0.0/5" BROADCAST_SRC="0.0.0.0" BROADCAST_DEST="255.255.255.255" PRIVPORTS="0:1023" UNPRIVPORTS="1024:65535" ############################################################################### # in /proc/sys/net/ipv4 protections available # Enable broadcast echo Protection echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts # Disable Source Routed Packets for f in /proc/sys/net/ipv4/conf/*/accept_source_route; do echo 0 > $f done # Enable TCP SYN Cookie Protection echo 1 > /proc/sys/net/ipv4/tcp_syncookies # Disable ICMP Redirect Acceptance for f in /proc/sys/net/ipv4/conf/*/accept_redirects; do echo 0 > $f done # Don't Send Redirect Messages for f in /proc/sys/net/ipv4/conf/*/send_redirects; do echo 0 > $f done # Drop Spoofed Packets coming in on an interface, which if replied to, # would result in the reply going out a different interface. for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 1 > $f done # Log packets with impossible addresses. (Do we really want to do this?) #for f in /proc/sys/net/ipv4/conf/*/log_martians; do # echo 1 > $f #done ############################################################################### #FLUSH EVERYTHING AND DELETE CHAINS echo "Flushing all rules and chains ..." /sbin/iptables -F /sbin/iptables -t nat -F /sbin/iptables -t mangle -F /sbin/iptables --delete-chain /sbin/iptables -t nat --delete-chain /sbin/iptables -t mangle --delete-chain #DEFAULT POLICIES #default filter policy /sbin/iptables --policy INPUT DROP /sbin/iptables --policy OUTPUT DROP /sbin/iptables --policy FORWARD DROP #default nat policy /sbin/iptables -t nat --policy PREROUTING ACCEPT /sbin/iptables -t nat --policy OUTPUT ACCEPT /sbin/iptables -t nat --policy POSTROUTING ACCEPT #default mangle policy /sbin/iptables -t mangle --policy PREROUTING ACCEPT /sbin/iptables -t mangle --policy OUTPUT ACCEPT #Allow loopback /sbin/iptables -A INPUT -m physdev --physdev-in lo -j ACCEPT /sbin/iptables -A OUTPUT -m physdev --physdev-out lo -j ACCEPT ############################################################################### #CREATE VALIDATION CHAINS iptables -N TCP-STF iptables -N CON-TRK iptables -N SRC-CHK iptables -N FWL-OUT #CREATE TRAFFIC CHAINS iptables -N INET-SVRS iptables -N SVRS-INET #CREATE ICMP CHAINS iptables -N passicmp ############################################################################### echo "Creating firewall rules..." #INSERT A PACKET INTO THE APPROPRIATE CHAIN ## Allow SSH to DMZ /sbin/iptables -A INPUT -m physdev --physdev-in $DMZ -p tcp --destination-port 22 -j ACCEPT /sbin/iptables -A INPUT -m physdev --physdev-in $DMZ -p udp --destination-port 22 -j ACCEPT if [ $INET_SSH = 1 ] ; then /sbin/iptables -A INPUT -m physdev --physdev-in $INTERNET -p tcp --destination-port 22 -j ACCEPT /sbin/iptables -A INPUT -m physdev --physdev-in $INTERNET -p udp --destination-port 22 -j ACCEPT fi /sbin/iptables -A INPUT -d $SUBNET_BROADCAST -j DROP /sbin/iptables -A INPUT -p icmp -j passicmp /sbin/iptables -A INPUT -j TCP-STF /sbin/iptables -A INPUT -j CON-TRK /sbin/iptables -A INPUT -j SRC-CHK #/sbin/iptables -A INPUT -p tcp --destination-port 22 -j ACCEPT ################################################################################ # On 9/28/03 we denied these idiots who are just hammering our site! /sbin/iptables -A INPUT -s 216.39.48.0/24 -j DROP /sbin/iptables -A FORWARD -s 216.39.48.0/24 -j DROP /sbin/iptables -A FORWARD -s 68.116.156.85 -j DROP /sbin/iptables -A FORWARD -s 213.37.82.0/24 -j DROP /sbin/iptables -A FORWARD -s 63.107.252.0/24 -p tcp --destination-port 25 -j DROP /sbin/iptables -A FORWARD -s 63.107.252.0/24 -p udp --destination-port 25 -j DROP /sbin/iptables -A FORWARD -s 65.212.41.0/24 -p tcp --destination-port 25 -j DROP /sbin/iptables -A FORWARD -s 65.212.41.0/24 -p udp --destination-port 25 -j DROP /sbin/iptables -A FORWARD -s 65.186.8.0/24 -j DROP # ################################################################################ /sbin/iptables -A FORWARD -p icmp -j passicmp /sbin/iptables -A FORWARD -j TCP-STF /sbin/iptables -A FORWARD -j CON-TRK /sbin/iptables -A FORWARD -j SRC-CHK /sbin/iptables -A FORWARD -m physdev --physdev-in $INTERNET --physdev-out $DMZ -j INET-SVRS /sbin/iptables -A FORWARD -m physdev --physdev-in $DMZ --physdev-out $INTERNET -j SVRS-INET # Allow the firewall to talk to the DMZ /sbin/iptables -A OUTPUT -m physdev --physdev-out $DMZ -j ACCEPT # Otherwise do the normal check /sbin/iptables -A OUTPUT -p icmp -j passicmp /sbin/iptables -A OUTPUT -j TCP-STF /sbin/iptables -A OUTPUT -j CON-TRK /sbin/iptables -A OUTPUT -j SRC-CHK /sbin/iptables -A OUTPUT -m physdev --physdev-out $INTERNET -j FWL-OUT ############################################################################## # FWL-OUT What we allow the firewall to talk to # Allow this machine to talk to the internet over SSH /sbin/iptables -A FWL-OUT -p tcp --destination-port 22 -j ACCEPT /sbin/iptables -A FWL-OUT -p tcp -d 209.50.17.209 -j ACCEPT /sbin/iptables -A FWL-OUT -j DROP ############################################################################### # the ICMP chain # strict version: if [ $ICMP_STRICT = 1 ] ; then /sbin/iptables -A passicmp -p icmp --icmp-type destination-unreachable -j ACCEPT /sbin/iptables -A passicmp -p icmp --icmp-type source-quench -j ACCEPT /sbin/iptables -A passicmp -p icmp --icmp-type time-exceeded -j ACCEPT /sbin/iptables -A passicmp -p icmp -j DROP else /sbin/iptables -A passicmp -p icmp -j ACCEPT fi ############################################################################### #TCP-STATE-FLAGES # All of the bits are cleared iptables -A TCP-STF -p tcp --tcp-flags ALL NONE -j DROP # SYN and FIN are both set iptables -A TCP-STF -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP # SYN and RST are both set iptables -A TCP-STF -p tcp --tcp-flags SYN,RST SYN,RST -j DROP # FIN and RST are both set iptables -A TCP-STF -p tcp --tcp-flags FIN,RST FIN,RST -j DROP # FIN is the only bit set, without the expected accompanying ACK iptables -A TCP-STF -p tcp --tcp-flags ACK,FIN FIN -j DROP #PSH is the only bit set, without the expected accompanying ACK iptables -A TCP-STF -p tcp --tcp-flags ACK,PSH PSH -j DROP #URG is the only bit set, without the expected accompanyin iptables -A TCP-STF -p tcp --tcp-flags ACK,URG URG -j DROP ############################################################################### # Allows established and related connections through if [ $CONNECTION_TRACKING = 1 ] ; then iptables -A CON-TRK -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A CON-TRK -m state --state INVALID -j LOG --log-level info --log-prefix "CS" iptables -A CON-TRK -m state --state INVALID -j DROP fi ############################################################################### #Refuse various invalid sources # Refuse spoofed packets pretending to be from the external interface’s IP address iptables -A SRC-CHK -m physdev --physdev-in $INTERNET -s $BRAIN -j DROP #Refuse packets claiming to be from a Class A,B,C private network iptables -A SRC-CHK -s $CLASS_A -j DROP iptables -A SRC-CHK -s $CLASS_B -j DROP iptables -A SRC-CHK -s $CLASS_C -j DROP #Refuse multicast packets iptables -A SRC-CHK -s $CLASS_D_MULTICAST -j DROP iptables -A SRC-CHK -s $CLASS_E_RESERVED_NET -j DROP iptables -A SRC-CHK -d $BROADCAST_DEST -j DROP #Refuse packets claiming to be from loopback iptables -A SRC-CHK -m physdev --physdev-in $INTERNET -s $LOOPBACK -j DROP #Refuse malformed broadcast packests iptables -A SRC-CHK -s $BROADCAST_DEST -j DROP iptables -A SRC-CHK -s $BROADCAST_SRC -j DROP #Refuse directed broadcasts iptables -A SRC-CHK -m physdev --physdev-in $INTERNET -s $SUBNET_NETWORK -j DROP iptables -A SRC-CHK -m physdev --physdev-in $INTERNET -s $SUBNET_BROADCAST -j DROP ############################################################################### # Brain/Gateway Server Table # Currently we accept FTP, SMTP, DNS, WWW, POP3, NTP* # We have also added the private forwards at the bottom # this is for servers that on the private IP range # SMTP /sbin/iptables -A INET-SVRS -d $BRAIN -p tcp --destination-port 25 -j ACCEPT /sbin/iptables -A INET-SVRS -d $BRAIN -p udp --destination-port 25 -j ACCEPT # Domain/Nameserver as of 9/28 this service is not available - no longer serving Inviationsource.com /sbin/iptables -A INET-SVRS -d $BRAIN -p tcp --destination-port 42 -j ACCEPT /sbin/iptables -A INET-SVRS -d $BRAIN -p udp --destination-port 42 -j ACCEPT /sbin/iptables -A INET-SVRS -d $BRAIN -p tcp --destination-port 53 -j ACCEPT /sbin/iptables -A INET-SVRS -d $BRAIN -p udp --destination-port 53 -j ACCEPT # WWW /sbin/iptables -A INET-SVRS -d $BRAIN -p tcp --destination-port 80 -j ACCEPT /sbin/iptables -A INET-SVRS -d $BRAIN -p udp --destination-port 80 -j ACCEPT # WWW/SSL /sbin/iptables -A INET-SVRS -d $BRAIN -p tcp --destination-port 443 -j ACCEPT /sbin/iptables -A INET-SVRS -d $BRAIN -p udp --destination-port 443 -j ACCEPT # Allow time server to gateway /sbin/iptables -A INET-SVRS -s $TIMESERVER1 -d $BRAIN -p udp --destination-port 123 -j ACCEPT /sbin/iptables -A INET-SVRS -s $TIMESERVER2 -d $BRAIN -p udp --destination-port 123 -j ACCEPT /sbin/iptables -A INET-SVRS -s $TIMESERVER3 -d $BRAIN -p udp --destination-port 123 -j ACCEPT /sbin/iptables -A INET-SVRS -s $TIMESERVER1 -d $BRAIN2 -p udp --destination-port 123 -j ACCEPT /sbin/iptables -A INET-SVRS -s $TIMESERVER2 -d $BRAIN2 -p udp --destination-port 123 -j ACCEPT /sbin/iptables -A INET-SVRS -s $TIMESERVER3 -d $BRAIN2 -p udp --destination-port 123 -j ACCEPT # PPTP # /sbin/iptables -A INET-SVRS -d $BRAIN -p 47 -j ACCEPT # /sbin/iptables -A INET-SVRS -d $BRAIN -p tcp --destination-port 1723 -j ACCEPT # /sbin/iptables -A INET-SVRS -d $BRAIN2 -p 47 -j ACCEPT # /sbin/iptables -A INET-SVRS -d $BRAIN2 -p tcp --destination-port 1723 -j ACCEPT # L2TP/IPSec if [ $L2TP = 1 ] ; then /sbin/iptables -A INET-SVRS -d $BRAIN -p 50 -j ACCEPT /sbin/iptables -A INET-SVRS -d $BRAIN -p 51 -j ACCEPT /sbin/iptables -A INET-SVRS -d $BRAIN -p udp --destination-port 500 -j ACCEPT /sbin/iptables -A INET-SVRS -d $BRAIN2 -p 50 -j ACCEPT /sbin/iptables -A INET-SVRS -d $BRAIN2 -p 51 -j ACCEPT /sbin/iptables -A INET-SVRS -d $BRAIN2 -p udp --destination-port 500 -j ACCEPT fi # ALLOW X Apps from cse.unl.edu to yakko /sbin/iptables -A INET-SVRS -s $CSE -d $YAKKO -p tcp --destination-port 6000 -j ACCEPT #/sbin/iptables -A INET-SVRS -s $CSE -d $YAKKO -p udp --destination-port 6000 -j ACCEPT # PACKETS THAT MAKE IT THIS FAR ARE LOGGED AND DROPPED BY POLICY /sbin/iptables -A INET-SVRS -j LOG --log-level info --log-prefix "SC: " /sbin/iptables -A INET-SVRS -j DROP ############################################################################### # SVRS-INET' # Allow out SMTP /sbin/iptables -A SVRS-INET -s $BRAIN -p tcp --source-port 25 -j ACCEPT /sbin/iptables -A SVRS-INET -s $BRAIN -p udp --source-port 25 -j ACCEPT # Allow out nameserver /sbin/iptables -A SVRS-INET -s $BRAIN -p tcp --source-port 42 -j ACCEPT /sbin/iptables -A SVRS-INET -s $BRAIN -p udp --source-port 42 -j ACCEPT # Allow out Domain (DNS) /sbin/iptables -A SVRS-INET -s $BRAIN -p tcp --source-port 53 -j ACCEPT /sbin/iptables -A SVRS-INET -s $BRAIN -p udp --source-port 53 -j ACCEPT # Allow out HTTP(s) /sbin/iptables -A SVRS-INET -s $BRAIN -p tcp --source-port 80 -j ACCEPT /sbin/iptables -A SVRS-INET -s $BRAIN -p udp --source-port 80 -j ACCEPT /sbin/iptables -A SVRS-INET -s $BRAIN -p tcp --source-port 443 -j ACCEPT /sbin/iptables -A SVRS-INET -s $BRAIN -p udp --source-port 443 -j ACCEPT # Allow NTP requests out /sbin/iptables -A SVRS-INET -s $BRAIN -d $TIMESERVER1 -p udp --source-port 123 -j ACCEPT /sbin/iptables -A SVRS-INET -s $BRAIN -d $TIMESERVER2 -p udp --source-port 123 -j ACCEPT /sbin/iptables -A SVRS-INET -s $BRAIN -d $TIMESERVER3 -p udp --source-port 123 -j ACCEPT /sbin/iptables -A SVRS-INET -s $BRAIN2 -d $TIMESERVER1 -p udp --source-port 123 -j ACCEPT /sbin/iptables -A SVRS-INET -s $BRAIN2 -d $TIMESERVER2 -p udp --source-port 123 -j ACCEPT /sbin/iptables -A SVRS-INET -s $BRAIN2 -d $TIMESERVER3 -p udp --source-port 123 -j ACCEPT # PPTP Is currently not allowed instead use L2TP # /sbin/iptables -A SVRS-INET -s $BRAIN -p 47 -j ACCEPT # /sbin/iptables -A SVRS-INET -s $BRAIN -p tcp --destination-port 1723 -j ACCEPT # /sbin/iptables -A SVRS-INET -s $BRAIN2 -p 47 -j ACCEPT # /sbin/iptables -A SVRS-INET -s $BRAIN2 -p tcp --destination-port 1723 -j ACCEPT # Next four lines stop anyone except our mail server from sending mail /sbin/iptables -A SVRS-INET -s $BRAIN -p tcp --destination-port 25 -j ACCEPT /sbin/iptables -A SVRS-INET -s $BRAIN -p udp --destination-port 25 -j ACCEPT /sbin/iptables -A SVRS-INET -s 0.0.0.0 -p tcp --destination-port 25 -j DROP /sbin/iptables -A SVRS-INET -s 0.0.0.0 -p udp --destination-port 25 -j DROP # These lines allow any activity outbound on unprivileged ports all # other outbound traffic is denied by policy /sbin/iptables -A SVRS-INET -p tcp --source-port 1024:65535 -j ACCEPT /sbin/iptables -A SVRS-INET -p udp --source-port 1024:65535 -j ACCEPT echo "Finished Firewall setup." ;; stop) echo "Flushing all rules and chains ..." /sbin/iptables -F /sbin/iptables -t nat -F /sbin/iptables -t mangle -F /sbin/iptables --delete-chain /sbin/iptables -t nat --delete-chain /sbin/iptables -t mangle --delete-chain /sbin/iptables --policy INPUT ACCEPT /sbin/iptables --policy OUTPUT ACCEPT /sbin/iptables --policy FORWARD ACCEPT #default nat policy /sbin/iptables -t nat --policy PREROUTING ACCEPT /sbin/iptables -t nat --policy OUTPUT ACCEPT /sbin/iptables -t nat --policy POSTROUTING ACCEPT #default mangle policy /sbin/iptables -t mangle --policy PREROUTING ACCEPT /sbin/iptables -t mangle --policy OUTPUT ACCEPT ;; restart) /etc/init.d/firewall stop && /etc/init.d/firewall start ;; *) echo "use firewall [start|stop]" exit 1 esac test "$return" = "$rc_done" || exit 1 exit 0 }}} == At times, I have also used NAT == In this extremely simple NAT setup I do not forward anthing to the interior of the network, although I have some commented lines that had been used to do that. This too is from a long since dead network. {{{ #!/bin/bash #Postrouting nat stuff from 10.0.0.0 iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j SNAT --to-source x.y.z.21 # DON'T DO IT ANYMORE BECAUSE WE GOT A REGUALR IP FOR PINKY 220 - 5/30/03 #Pre routing stuff to Pinky #iptables -t nat -A PREROUTING -i eth0 -p tcp -d x.y.z.22 --sport 1024:65535 --dport 80 -j DNAT --to-destination 10.0.0.2 #iptables -t nat -A PREROUTING -i eth1 -p tcp -d x.y.z.22 --sport 1024:65535 --dport 80 -j DNAT --to-destination 10.0.0.2 }}} Once you have NAT setup, there really isn't much difference in how the firewall is setup. You can use the one listed above. = Blocking SSH repeated login attempts = Obviously a person should use a package where appropriate, like fail2ban. But if you want to play with the nuts and bolts of your iptables firewall a bit, you might try the following: First: Configure /etc/ssh/sshd_config to contain {{{MaxAuthTries 1}}}. Second: Add a new chain to your firewall: {{{ iptables -N SSHDENY iptables -A SSHDENY -j LOG --log-prefix "Possible ssh attack. " --log-level 7 iptables -A SSHDENY -j DROP }}} You also need to put an entry point for your new chain. {{{ iptables -A INPUT -i eth0 -p tcp -m state --dport 22 --state NEW -m recent --set iptables -A INPUT -i eth0 -p tcp -m state --dport 22 --state NEW -m recent --update --seconds 120 --hitcount 7 -j SSHDENY }}} Third: watch {{{/var/log/syslog}}} for entries that include your log line. Fourth: If you see some idiot just killing your machine with logs, consider adding the IP or range of IPs to your block list.