#!/bin/sh # example of simple firewall for a gateway machine # default deny in, default allow out for the host, same for forwarding ######################################################################## # Date : 27 Feb 2002 # copyright : (C) 2002 by Arthur Clune # email : arthur@clune.org # # 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; either version 2 of the License, or # (at your option) any later version. ######################################################################## # 1 Apr 2002 - Minor changes with thanks to Ewan Mac Mahon (ecm103@york.ac.uk) # Only very limited logging to keep the example short, add more if you want. # Note that FW logs go to kern.warn by default, so you can sort them to # a separate file by editing /etc/syslog.conf. This is a good idea if # you do lots of logging otherwise /var/log/messages gets huge # # You can also specifiy a log level via the --log-level option to the LOG target # define some config vars INTERNAL_NET=144.32.0.0/16 INTERNAL_IF=eth0 EXTERNAL_IF=eth1 # load some modules modprobe ip_tables modprobe ip_conntrack modprobe ip_conntrack_ftp # Enable broadcast echo protection if [ -e /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts ]; then echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts fi # no source routing for f in /proc/sys/net/ipv4/conf/*/accept_source_route; do echo 0 > $f done # TCP SYN cookies protection if [ -f /proc/sys/net/ipv4/tcp_syncookies ]; then echo 1 > /proc/sys/net/ipv4/tcp_syncookies fi # ignore ICMP redirects for f in /proc/sys/net/ipv4/conf/*/accept_redirects; do echo 0 > $f done # don't send redirects for f in /proc/sys/net/ipv4/conf/*/send_redirects; do echo 0 > $f done # reverse path filtering (anti-spoofing) for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 1 > $f done # drop packets with impossible address for f in /proc/sys/net/ipv4/conf/*/log_martians; do echo 1 > $f done # we are a router # only enable forwarding for given devices for f in /proc/sys/net/ipv4/conf/*/forwarding; do echo 1 > $f done echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv4/conf/eth0/forwarding echo 1 > /proc/sys/net/ipv4/conf/eth1/forwarding # # Some paranioa # Kill malformed packets. Add logging here if you want, first # one gives an example # # You can try replacing all these rules with the 'unclean' modules # iptables -A INPUT -m unclean -j DROP # Block NULL packets iptables -A INPUT -p tcp --tcp-flags ALL NONE -j LOG --log-prefix "[***] NULL scan : " -m limit --limit 1/second iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP iptables -A FORWARD -p tcp --tcp-flags ALL NONE -j DROP # SYN/FIN iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP iptables -A FORWARD -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP # SYN/RST iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN,RST -j DROP # FIN only bit set, with no accompanying ACK iptables -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j DROP iptables -A FORWARD -p tcp --tcp-flags ACK,FIN FIN -j DROP # PSH only bit set, with no accompanying ACK iptables -A INPUT -p tcp --tcp-flags ACK,PSH PSH -j DROP iptables -A FORWARD -p tcp --tcp-flags ACK,PSH PSH -j DROP # XMAS scans are caught implicitly by the rules above # block the private/non-routable address blocks iptables -A INPUT -s 10.0.0.0/8 -j DROP iptables -A FORWARD -s 10.0.0.0/8 -j DROP iptables -A INPUT -s 172.16.0.0/12 -j DROP iptables -A FORWARD -s 172.16.0.0/12 -j DROP iptables -A INPUT -s 172.17.0.0/12 -j DROP iptables -A FORWARD -s 172.17.0.0/12 -j DROP iptables -A INPUT -s 192.168.0.0/16 -j DROP iptables -A FORWARD -s 192.168.0.0/16 -j DROP # drop multicast traffic iptables -A INPUT -d 224.0.0.0/4 -j DROP iptables -A FORWARD -d 224.0.0.0/4 -j DROP # reverse path filtering should supply anti-spoofing. # (as long as the routing is correct!) # but here is some more # This should be logged, since anything that gets # caught by this rule is either bad or misconfigured iptables -A INPUT -s $INTERNAL_NET -i $EXTERNAL_IF -j DROP iptables -A INPUT -s ! $INTERNAL_NET -i $INTERNAL_IF -j DROP iptables -A FORWARD -s $INTERNAL_NET -i $EXTERNAL_IF -j DROP iptables -A FORWARD -s ! $INTERNAL_NET -i $INTERNAL_IF -j DROP # # Now the setup for the firewall machine itself # # allow related connections iptables -A INPUT -j ACCEPT -m state --state ESTABLISHED,RELATED # accept from lo iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # what is the firewall a server for? iptables -A INPUT -j LOG -p tcp --dport 22 -i $INTERNAL_IF --log-prefix "[***] SSH accept: " iptables -A INPUT -j ACCEPT -p tcp --dport 22 -i $INTERNAL_IF # and the default behaviour for the firewall itself iptables -A INPUT -j LOG --log-prefix "[***] Default drop (I): " iptables -A INPUT -j DROP iptables -A OUTPUT -j ACCEPT # # now the forwarding setup # # allow all established/related traffic iptables -A FORWARD -j ACCEPT -m state --state ESTABLISHED,RELATED # allow outgoing FTP # ftp is more complex, since we use ip_conntrack_ftp to handle PASV/ACTIVE etc # (this section taken from # http://www.sns.ias.edu/~jns/security/iptables/index.html) # This involves a connection INbound from port 20 on the remote machine, to a local port # passed over the ftp channel via a PORT command. The ip_conntrack_ftp module recognizes # the connection as RELATED to the original outgoing connection to port 21 so we don't # need NEW as a state match. iptables -A FORWARD -i $EXTERNAL_IF -p tcp --sport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT # 2) Passive ftp. # This involves a connection outbound from a port >1023 on the local machine, to a port >1023 # on the remote machine previously passed over the ftp channel via a PORT command. The # ip_conntrack_ftp module recognizes the connection as RELATED to the original outgoing # connection to port 21 so we don't need NEW as a state match. iptables -A FORWARD -i $EXTERNAL -p tcp --sport 1024: --dport 1024: \ -m state --state ESTABLISHED,RELATED -j ACCEPT # # allow access to servers # # 144.32.23.23 is our webserver iptables -A FORWARD -j ACCEPT -i $EXTERNAL_IF -p tcp --dport 80 -d 144.32.23.23 # 144.32.32.32 is our mailserver iptables -A FORWARD -j ACCEPT -i $EXTERNAL_IF -p tcp --dport 25 -d 144.32.32.32 # (would be more of the same here in a real setup) # REJECT auth, don't drop it (keeps mail quick) iptables -A FORWARD -j REJECT -p tcp --dport 113 # setup our mail server # remember that we will block outgoing SMTP later, so must # allow it here # 144.32.1.1 is our mail server iptables -A FORWARD -j ACCEPT -i $INTERNAL_IF -p tcp --dport 25 -s 144.32.1.1 iptables -A FORWARD -j ACCEPT -i $EXTERNAL_IF -p tcp --dport 25 -d 144.32.1.1 # Now we block all the stuff that we don't want to leave our network # drop pings iptables -A FORWARD -i $INTERNAL_IF -p icmp --icmp-type echo-request -j DROP iptables -A FORWARD -i $INTERNAL_IF -p icmp --icmp-type echo-reply -j DROP # all the nasty MS protocols # an example of specifying several ports in one line # SMB/CIFS/NMB iptables -A FORWARD -p tcp --sport 135:139 -j DROP iptables -A FORWARD -p udp --sport 135:139 -j DROP iptables -A FORWARD -p tcp --dport 135:139 -j DROP iptables -A FORWARD -p udp --dport 135:139 -j DROP # and for W2K/XP iptables -A FORWARD -p tcp --sport 445 -j DROP iptables -A FORWARD -p udp --sport 445 -j DROP iptables -A FORWARD -p tcp --dport 445 -j DROP iptables -A FORWARD -p udp --dport 445 -j DROP # NFS Mount Service (TCP/UDP 635) # there's logging here just becuase it was there in the script that I cut and # pasted this bit from :) iptables -A FORWARD -i $INTERNAL_IF -p tcp --sport 635 -j LOG --log-prefix "[***] NFS (tcp-635) : " iptables -A FORWARD -i $INTERNAL_IF -p tcp --sport 635 -j DROP iptables -A FORWARD -i $INTERNAL_IF -p udp --sport 635 -j LOG --log-prefix "[***] NFS (udp-635) : " iptables -A FORWARD -i $INTERNAL_IF -p udp --sport 635 -j DROP # NFS (TCP/UDP 2049) iptables -A FORWARD -i $INTERNAL_IF -p tcp --sport 2049 -j LOG --log-prefix "[***] NFS (tcp-2049) : " iptables -A FORWARD -i $INTERNAL_IF -p tcp --sport 2049 -j DROP iptables -A FORWARD -i $INTERNAL_IF -p udp --sport 2049 -j LOG --log-prefix "[***] NFS (udp-2049) : " iptables -A FORWARD -i $INTERNAL_IF -p udp --sport 2049 -j DROP # Portmapper (TCP/UDP 111) iptables -A FORWARD -i $INTERNAL_IF -p tcp --sport 111 -j LOG --log-prefix "[***] Portmapper (tcp) : " iptables -A FORWARD -i $INTERNAL_IF -p tcp --sport 111 -j DROP iptables -A FORWARD -i $INTERNAL_IF -p udp --sport 111 -j LOG --log-prefix "[***] Portmapper (udp) : " iptables -A FORWARD -i $INTERNAL_IF -p udp --sport 111 -j DROP # Set default policies # Allow out anything not blocked above, and drop anything coming in # that we haven't allowed iptables -A FORWARD -i $INTERNAL_IF -j ACCEPT iptables -A FORWARD -j LOG --log-prefix "[***] Default drop (F): " iptables -A FORWARD -j DROP # some people may prefer to set the default policy rather than making the # last rule a drop : # iptables -P INPUT DROP # iptables -P FORWARD DROP