#!/bin/bash #
# # picoFIREWALL # Do not change this line! Version: -V2.9- 28Apr2004 / uk # # picofirewall.conf # # - This file contains HTML-commands to be viewed through a browser! # # - picoFIREWALL is - as the name implies - a small firewall. It is based on # information I have received from various sources; see file REFERENCES. # - More information is given in the file README. # - The installation of picoFIREWALL is explained in the file INSTALL. # - Configuration of picoFIREWALL is done below, between the lines with '=====' # #============================================================================== ## START of your personal configuration... # #>>> Please note: after any changes made in this file you have to enter <<< #>>> ' picofirewall start ' <<< # # Interface to the Internet: eth0, ppp0 ... or whatever it is: # IFACE="eth0" # # Would you like that all machines can send a ping to your machine? # Select "yes" or "no" on the following line. You may still exclude certain # machines from pinging to you in the files noise_log.cfg or noise_nolog.cfg : # ALLOW_PING="no" # # Is the machine we are running on, a web- or a mail-server? # Add the hostnames of those machines into the variables WEBSERVERS (and # SECWEBSERVERS for secure webservers [https]), and MAILSERVERS below. # If you have to maintain several machines, you may like this; add the host # names of your web- and mail-servers here: # WEBSERVERS="zak seismo50 yogibear" SECWEBSERVERS="" MAILSERVERS="zak yogibear" # # Is this machine a DHCP server? Add the hostnames of those machines into the # variable DHCPSERVERS below; if this script is for just one machine, add one. # DHCPSERVERS="" # # Many annoying packets, which are dropped anyway, are now only minimally # logged. However, there are more than 65'000 ports... and we usually just want # to be informed, but not have our log-file filled. Therefore, the default is # now to log all dropped packets only partially (1 per hour). If you want more # entries in the log-file, set the variable below to "no". # LIMIT_DROP_LOGGING="yes" # # If you really trust the TRUSTED hosts defined in /etc/picofirewall.trusted, # then you may also want to limit the logging from packets of these machines. # If you want more entries in the log-file, set the variable below to "no". # LIMIT_ACCEPT_LOGGING="yes" # ## ...END of your personal configuration. #============================================================================== # # check, whether we are on a Debian system: if test -x /usr/bin/apt-get ; then debian="true" LOGLEVEL="warn" else debian="false" LOGLEVEL="warning" fi # # Check, whether we are a webserver, a secure webserver, a mailserver, or # a dhcp server: # webserver="no" secwebserver="no" mailserver="no" dhcpserver="no" for ws in $WEBSERVERS ; do if test `hostname` = "$ws" ; then webserver="yes" fi done for sws in $SECWEBSERVERS ; do if test `hostname` = "$sws" ; then secwebserver="yes" fi done for ms in $MAILSERVERS ; do if test `hostname` = "$ms" ; then mailserver="yes" fi done for dhs in $DHCPSERVERS ; do if test `hostname` = "$dhs" ; then dhcpserver="yes" fi done # # Here we define the limited logging for DROPped and ACCEPTed packets, as well # as the logging of packets from noisy machines: # if test "$LIMIT_DROP_LOGGING" = "yes" ; then limD="-m limit --limit 1/hour --limit-burst 1" else limD="-m limit --limit 1/minute --limit-burst 1" fi # if test "$LIMIT_ACCEPT_LOGGING" = "yes" ; then limA="-m limit --limit 1/day --limit-burst 1" else limA="-m limit --limit 1/hour --limit-burst 1" fi # limN="-m limit --limit 1/day --limit-burst 1" # # # Load appropriate modules of the kernel: # modprobe ip_tables modprobe ip_conntrack modprobe ip_conntrack_ftp # # In case we rerun this script: flush all chains, delete every non-builtin # chain, and zero the packet and byte counters in all chains. # iptables -F iptables -X iptables -Z # # Set up a default DROP policy for the built-in chains. # 'filter' is the default table. It contains the built-in chains INPUT, # FORWARD, and OUTPUT. # If we modify and re-run the script mid-session then (because we have a default # DROP policy), what happens is that there is a small time period when packets # are denied until the new rules are back in place. There is no period, however # small, when packets we don't want are allowed. # iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT DROP # # find out IP address for this interface: # IPADDR=`ifconfig $IFACE | grep "inet addr" |cut -d':' -f 2 |cut -d' ' -f 1` # # find out Broadcast address for this interface: # BROADCAST=`ifconfig $IFACE | grep Bcast |cut -d':' -f 3 |cut -d' ' -f 1` # # find out the Domain Name Servers (DNS) used on this machine: # #NAMESERVER=`grep ^nameserver /etc/resolv.conf | tr ' ' ' ' | cut -d" " -f 2` # Currently, this is not used... we allow incoming tcp/udp packets from port 53 # # Definitions of some IPs... # 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" ##uk##CLASS_D_MULTICAST="224.0.0.0/4" # uk # see e.g. http://koeln.ccc.de/~drt/multicast.txt # uk # see e.g. http://www.faqs.org/rfcs/rfc3171.html #uk???#CLASS_D_MULTICAST="224.0.0/24" CLASS_D_MULTICAST="224.0.0.1" # # # Attention: DHCP server answers messages on the IP address 224.0.0.12 # (but only on a subnet) # # If you do not need multicast, uncomment the following line: # (Do *not* do it if you are running VMware) # # iptables -t mangle -I PREROUTING -j DROP -d 224.0.0.0/8 # CLASS_E_RESERVED_NET="240.0.0.0/5" # not used#P_PORTS="0:1023" UP_PORTS="1024:65535" TR_SRC_PORTS="32769:65535" TR_DEST_PORTS="33434:33523" # #------------------------------------------------------------------------------ ## Kernel flags # To dynamically change kernel parameters and variables on the fly you need # CONFIG_SYSCTL defined in your kernel. I would advise the following: # Disable response to ping. # We are *not* doing this by default anymore; this is now handled in the # ICMP section below in order to be more flexible. # ###/bin/echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_all # We do the following in case someone has used an older version of picoFirewall: /bin/echo "0" > /proc/sys/net/ipv4/icmp_echo_ignore_all # # Disable response to broadcasts. # You don't want yourself becoming a Smurf amplifier. # /bin/echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts # # Don't accept source routed packets. Attackers can use source routing to # generate traffic pretending to be from inside your network, but which is # routed back along the path from which it came, namely outside, so attackers # can compromise your network. Source routing is rarely used for legitimate # purposes. # /bin/echo "0" > /proc/sys/net/ipv4/conf/all/accept_source_route # # Disable ICMP redirect acceptance. ICMP redirects can be used to alter your # routing tables, possibly to a bad end. # for interface in /proc/sys/net/ipv4/conf/*/accept_redirects; do /bin/echo "0" > ${interface} done # # Enable bad error message protection. # /bin/echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses # # Turn on reverse path filtering. This helps make sure that packets use # legitimate source addresses, by automatically rejecting incoming packets # if the routing table entry for their source address doesn't match the network # interface they're arriving on. This has security advantages because it # prevents so-called IP spoofing, however it can pose problems if you use # asymmetric routing (packets from you to a host take a different path than # packets from that host to you) or if you operate a non-routing host which has # several IP addresses on different interfaces. (Note - If you turn on IP # forwarding, you will also get this). # for interface in /proc/sys/net/ipv4/conf/*/rp_filter; do /bin/echo "1" > ${interface} done # # Log spoofed packets, source routed packets, redirect packets. # /bin/echo "1" > /proc/sys/net/ipv4/conf/all/log_martians # # Make sure that IP forwarding is turned off. We only want this for a # multi-homed host. # /bin/echo "0" > /proc/sys/net/ipv4/ip_forward # # Note: With connection tracking, all fragments are reassembled before being # passed to the packet-filtering code so there is no ip_always_defrag switch # as there was in the 2.2 kernel. #------------------------------------------------------------------------------ # RULES # # Define the logging parameters/text (to be referenced in the commands below): # LOGP="--log-level $LOGLEVEL --log-tcp-options --log-ip-options --log-prefix P-Fw" # #------------------------------------------------------------------------------ ## LOOPBACK # Allow unlimited traffic on the loopback interface: # iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # #------------------------------------------------------------------------------ ## VMWARE # Allow unlimited traffic for the VMware interface vmnet8: # iptables -A INPUT -i vmnet8 -j ACCEPT iptables -A OUTPUT -o vmnet8 -j ACCEPT # #------------------------------------------------------------------------------ ## ESTABLISHED & RELATED CONNECTIONS # Accept (no log) packets to ESTABLISHED or RELATED connections. Things worked # mostly fine without this, but listening radio or watching TV with RealPlayer # did not work without this. Instead of only allowing it for port 554, we # allow such packets generally. # iptables -A INPUT -i $IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT # #------------------------------------------------------------------------------ ## WEB- AND MAIL-SERVER: # Allow tcp inbound for the corresponging ports, if we are a web-/mail-server: # if test "$webserver" = "yes" ; then iptables -A INPUT -i $IFACE -p tcp --dport 80 \ -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT fi if test "$secwebserver" = "yes" ; then iptables -A INPUT -i $IFACE -p tcp --dport 443 \ -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT fi if test "$mailserver" = "yes" ; then iptables -A INPUT -i $IFACE -p tcp --dport 25 \ -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT fi # #------------------------------------------------------------------------------ ## NOISY HOSTS/PORTS - NOT LOGGED if test -r /etc/picofirewall/noise_nolog.cfg ; then NOISENOLOG=`cat /etc/picofirewall/noise_nolog.cfg | grep -v ^# | cut -d# -f 1` else NOISENOLOG="" fi # for noise in $NOISENOLOG ; do ips="" pro="" por="" ip=`echo $noise | cut -d, -f 1` pr=`echo $noise | cut -d, -s -f 2` po=`echo $noise | cut -d, -s -f 3` if test ! -z "$ip" ; then ips="-s $ip" ; fi if test ! -z "$pr" ; then pro="-p $pr" ; fi if test ! -z "$po" ; then if test "$pr" = "icmp" ; then por="--icmp-type $po" else por="--dport $po" fi fi iptables -A INPUT -i $IFACE $ips $pro $por \ -m state --state NEW,ESTABLISHED,RELATED,INVALID -j DROP done # #------------------------------------------------------------------------------ ## NOISY HOSTS/PORTS - LOGGED if test -r /etc/picofirewall/noise_log.cfg ; then NOISELOG=`cat /etc/picofirewall/noise_log.cfg | grep -v ^# | cut -d# -f 1` else NOISELOG="" fi # for noise in $NOISELOG ; do ips="" pro="" por="" ip=`echo $noise | cut -d, -f 1` pr=`echo $noise | cut -d, -s -f 2` po=`echo $noise | cut -d, -s -f 3` if test ! -z "$ip" ; then ips="-s $ip" ; fi if test ! -z "$pr" ; then pro="-p $pr" ; fi if test ! -z "$po" ; then if test "$pr" = "icmp" ; then por="--icmp-type $po" else por="--dport $po" fi fi iptables -A INPUT -i $IFACE $ips $pro $por \ -m state --state NEW \ $limN -j LOG ${LOGP}"-DROP-noise_log-in: " iptables -A INPUT -i $IFACE $ips $pro $por \ -m state --state NEW -j DROP iptables -A INPUT -i $IFACE $ips $pro $por \ -m state --state ESTABLISHED,RELATED -j DROP done # #------------------------------------------------------------------------------ ## OPEN HOSTS/PORTS - NOT LOGGED if test -r /etc/picofirewall/open_nolog.cfg ; then OPENNOLOG=`cat /etc/picofirewall/open_nolog.cfg | grep -v ^# | cut -d# -f 1` else OPENNOLOG="" fi # for open in $OPENNOLOG ; do ips="" pro="" por="" ip=`echo $open | cut -d, -f 1` pr=`echo $open | cut -d, -s -f 2` po=`echo $open | cut -d, -s -f 3` if test ! -z "$ip" ; then ips="-s $ip" ; fi if test ! -z "$pr" ; then pro="-p $pr" ; fi if test ! -z "$po" ; then if test "$pr" = "icmp" ; then por="--icmp-type $po" else por="--dport $po" fi fi iptables -A INPUT -i $IFACE $ips $pro $por \ -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT done # #------------------------------------------------------------------------------ ## OPEN HOSTS/PORTS - LOGGED if test -r /etc/picofirewall/open_log.cfg ; then OPENLOG=`cat /etc/picofirewall/open_log.cfg | grep -v ^# | cut -d# -f 1` else OPENLOG="" fi # for open in $OPENLOG ; do ips="" pro="" por="" ip=`echo $open | cut -d, -f 1` pr=`echo $open | cut -d, -s -f 2` po=`echo $open | cut -d, -s -f 3` if test ! -z "$ip" ; then ips="-s $ip" ; fi if test ! -z "$pr" ; then pro="-p $pr" ; fi if test ! -z "$po" ; then if test "$pr" = "icmp" ; then por="--icmp-type $po" else por="--dport $po" fi fi iptables -A INPUT -i $IFACE $ips $pro $por \ -m state --state NEW \ $limA -j LOG ${LOGP}"-ACCEPT-open_log-in: " iptables -A INPUT -i $IFACE $ips $pro $por \ -m state --state NEW -j ACCEPT iptables -A INPUT -i $IFACE $ips $pro $por \ -m state --state ESTABLISHED,RELATED -j ACCEPT done # #------------------------------------------------------------------------------ ## SYN-FLOODING PROTECTION # This rule maximises the rate of incoming connections. In order to do this we # divert tcp packets with the SYN bit set off to a user-defined chain. Up to # limit-burst connections can arrive in 1/limit seconds ..... in this case 4 # connections in one second. After this, one of the burst is regained every # second and connections are allowed again. The default limit is 3/hour. The # default limit burst is 5. # # We start a new chain 'syn-flood' and do some tests there; then we have the # possibility to pass the OK packets back to the ruleset by the command # '-j RETURN' and drop the others. # # However, first we treat the case of web and mail servers: here we allow more # SYN packets per time interval: 60/sec & limit-burst 60 --> (1/60)*60=1sec # and hence the time burst-limit is recharged after one second. # if test "$webserver" = "yes" ; then ### iptables -N syn-flood-web ### iptables -A INPUT -i $IFACE -p tcp --dport 80 --syn -j syn-flood-web iptables -A INPUT -i $IFACE -p tcp --dport 80 --syn -j ACCEPT ### iptables -A syn-flood-web -m limit --limit 1000/s --limit-burst 1000 -j RETURN # The following is a testing version only....!!!!! ### iptables -A syn-flood-web -m limit --limit 4/hour --limit-burst 11 \ ### -j LOG ${LOGP}"-DROP-SYN_floodWEB-IN: " ### iptables -A syn-flood-web -j DROP fi # if test "$mailserver" = "yes" ; then iptables -A INPUT -i $IFACE -p tcp --dport 25 --syn -j ACCEPT fi # # Now treat syn-floods to all other ports: # iptables -N syn-flood iptables -A INPUT -i $IFACE -p tcp --syn -j syn-flood iptables -A syn-flood -m limit --limit 1/s --limit-burst 4 -j RETURN # ## If *lots* of packets are arriving, logging should definitely be limited; ## burst-limit=11 --> detected by picofirescan, if maxpackspermin=10 ## limit=4/hour --> 15min*11=165min --> after this time burst-limit is recharged # iptables -A syn-flood -m limit --limit 4/hour --limit-burst 11 \ -j LOG ${LOGP}"-DROP-SYN_flood-IN: " iptables -A syn-flood -j DROP # #------------------------------------------------------------------------------ ## Make sure NEW tcp connections are SYN packets # iptables -A INPUT -i $IFACE -p tcp ! --syn -m state --state NEW \ $limD -j LOG ${LOGP}"-DROP-NEWnoSYN-IN: " iptables -A INPUT -i $IFACE -p tcp ! --syn -m state --state NEW -j DROP # #------------------------------------------------------------------------------ ## DHCP # Allow dhcp replies from servers # The following is not necessary, since we already accept ESTABLISHED & RELATED # connections! # ###iptables -A INPUT -i $IFACE -p udp --sport 67 -d 255.255.255.255 --dport 68 \ ### -m state --state ESTABLISHED \ ### $limA -j LOG ${LOGP}"-ACCEPT-DHCP_reply-IN: " ###iptables -A INPUT -i $IFACE -p udp --sport 67 -d 255.255.255.255 --dport 68 \ ### -m state --state ESTABLISHED \ ### -j ACCEPT # # DHCP-SERVER # if test "$dhcpserver" = "yes" ; then iptables -A INPUT -i $IFACE -p udp --sport 68 --dport 67 \ -m state --state NEW \ $limA -j LOG ${LOGP}"-ACCEPT-DHCP_request-IN: " iptables -A INPUT -i $IFACE -p udp --sport 68 --dport 67 \ -m state --state NEW,ESTABLISHED -j ACCEPT fi # #------------------------------------------------------------------------------ ## SPOOFING # Most of this anti-spoofing stuff is theoretically not really necessary with # the flags we have set in the kernel above ........... but you never know there # isn't a bug somewhere in your IP stack. # # Refuse spoofed packets pretending to be from your IP address. # iptables -A INPUT -i $IFACE -s $IPADDR \ $limD -j LOG ${LOGP}"-DROP-is_from_me-IN: " iptables -A INPUT -i $IFACE -s $IPADDR -j DROP # # Refuse packets claiming to be from a Class A private network. # iptables -A INPUT -i $IFACE -s $CLASS_A $limD -j LOG ${LOGP}"-DROP-class_a-IN: " iptables -A INPUT -i $IFACE -s $CLASS_A -j DROP # # Refuse packets claiming to be from a Class B private network. # iptables -A INPUT -i $IFACE -s $CLASS_B $limD -j LOG ${LOGP}"-DROP-class_b-IN: " iptables -A INPUT -i $IFACE -s $CLASS_B -j DROP # # Refuse packets claiming to be from a Class C private network. # iptables -A INPUT -i $IFACE -s $CLASS_C $limD -j LOG ${LOGP}"-DROP-class_c-IN: " iptables -A INPUT -i $IFACE -s $CLASS_C -j DROP # # Refuse Class D multicast addresses. Multicast is illegal as a source address. # Do not log them... # iptables -A INPUT -i $IFACE -s $CLASS_D_MULTICAST \ $limD -j LOG ${LOGP}"-DROP-multicast-IN: " iptables -A INPUT -i $IFACE -s $CLASS_D_MULTICAST -j DROP # # Refuse Class E reserved IP addresses. # iptables -A INPUT -i $IFACE -s $CLASS_E_RESERVED_NET \ $limD -j LOG ${LOGP}"-DROP-reserved_class-IN: " iptables -A INPUT -i $IFACE -s $CLASS_E_RESERVED_NET -j DROP # # Refuse packets claiming to be to the loopback interface. # Refusing packets claiming to be to the loopback interface protects against # source quench, whereby a machine can be told to slow itself down by an icmp # source # # quench to the loopback. # iptables -A INPUT -i $IFACE -d $LOOPBACK \ $limD -j LOG ${LOGP}"-DROP-to_loopback-IN: " iptables -A INPUT -i $IFACE -d $LOOPBACK -j DROP # # Refuse broadcast address packets. # iptables -A INPUT -i $IFACE -d $BROADCAST \ $limD -j LOG ${LOGP}"-DROP-BROADCASTaddr-IN: " iptables -A INPUT -i $IFACE -d $BROADCAST -j DROP # #------------------------------------------------------------------------------ ## ICMP # # First we handle 'pings' seperately: # If pings are allowed generally, we allow them here: # if test "ALLOW_PING" = "yes" ; then iptables -A INPUT -i $IFACE -p icmp --icmp-type 8 -s 0/0 -d $IPADDR -j ACCEPT fi # # We prefilter icmp by pulling it off to user-defined chains so that we can # restrict which types are allowed from the beginning rather than leaving it to # the connection tracking. # For instance, we don't want redirects whatever happens. # In case you hadn't realised, ICMP scares me ....(the words of snp...) # My words: # We start new chains 'icmp-in' and 'icmp-out' and do some tests there; then we # have the possibility to pass the OK packets back to the ruleset by the # command '-j RETURN' and drop the others. # # 0: echo reply (pong) # 3: destination-unreachable (port-unreachable, fragmentation-needed etc). # 4: source quench # 5: redirect # 8: echo request (ping) # 9: router advertisement # 10: router solicitation # 11: time-exceeded # 12: parameter-problem # 13: timestamp request # 14: timestamp reply # 15: information request # 16: information reply # 17: address mask request # 18: address mask reply # # iptables -N icmp-in iptables -N icmp-out iptables -A INPUT -i $IFACE -p icmp -j icmp-in iptables -A OUTPUT -o $IFACE -p icmp -j icmp-out # # Accept 0,3,4,11,12,14,16,18 in. # iptables -A icmp-in -i $IFACE -p icmp --icmp-type 0 -s 0/0 -d $IPADDR -j RETURN iptables -A icmp-in -i $IFACE -p icmp --icmp-type 3 -s 0/0 -d $IPADDR -j RETURN iptables -A icmp-in -i $IFACE -p icmp --icmp-type 4 -s 0/0 -d $IPADDR -j RETURN iptables -A icmp-in -i $IFACE -p icmp --icmp-type 11 -s 0/0 -d $IPADDR -j RETURN iptables -A icmp-in -i $IFACE -p icmp --icmp-type 12 -s 0/0 -d $IPADDR -j RETURN iptables -A icmp-in -i $IFACE -p icmp --icmp-type 14 -s 0/0 -d $IPADDR -j RETURN iptables -A icmp-in -i $IFACE -p icmp --icmp-type 16 -s 0/0 -d $IPADDR -j RETURN iptables -A icmp-in -i $IFACE -p icmp --icmp-type 18 -s 0/0 -d $IPADDR -j RETURN # # Allow 4,8,12,13,15,17 out. # iptables -A icmp-out -o $IFACE -p icmp --icmp-type 4 -s $IPADDR -d 0/0 -j RETURN iptables -A icmp-out -o $IFACE -p icmp --icmp-type 8 -s $IPADDR -d 0/0 -j RETURN iptables -A icmp-out -o $IFACE -p icmp --icmp-type 12 -s $IPADDR -d 0/0 -j RETURN iptables -A icmp-out -o $IFACE -p icmp --icmp-type 13 -s $IPADDR -d 0/0 -j RETURN iptables -A icmp-out -o $IFACE -p icmp --icmp-type 15 -s $IPADDR -d 0/0 -j RETURN iptables -A icmp-out -o $IFACE -p icmp --icmp-type 17 -s $IPADDR -d 0/0 -j RETURN # # Any ICMP not already allowed is logged and then dropped. # # We do not want to be alerted just by pings... So log them partially but not # fully: # iptables -A INPUT -i $IFACE -p icmp --icmp-type 8 \ $limD -j LOG ${LOGP}"-DROP-ICMP-ping-in: " iptables -A INPUT -i $IFACE -p icmp --icmp-type 8 -j DROP # ###why not? OUT should be ok...###iptables -A icmp-out -o $IFACE \ ###why not? OUT should be ok...###-j LOG --log-level warning --log-tcp-options \ ###why not? OUT should be ok...### --log-ip-options --log-prefix \ ###why not? OUT should be ok...###"P-Fw-DROP-ICMP-BAD-TYPE-OUT: " ###why not? OUT should be ok...###iptables -A icmp-out -o $IFACE -j DROP # iptables -A icmp-out -o $IFACE -j ACCEPT # # Now we have returned from the icmp-in chain allowing only certain types # of icmp inbound, we can accept it if it is related to other connections # (e.g a time exceed from a traceroute) or part of an established one # (e.g. an echo reply) # iptables -A INPUT -i $IFACE -p icmp -m state --state ESTABLISHED,RELATED \ -j ACCEPT # # Now we have returned from the icmp-out chain allowing only certain types # of icmp outbound, we can just accept it under all circumstances. # iptables -A OUTPUT -o $IFACE -p icmp -m state --state NEW,ESTABLISHED,RELATED \ -j ACCEPT # #------------------------------------------------------------------------------ ## ICMP 2 # This is the second part of 'ICMP' - I will do some more tests and possibly # this part will replace the first part above. (uk) # # We accept icmp in if it is "related" to other connections (e.g a time # exceeded (11) from a traceroute) or it is part of an "established" connection # (e.g. an echo reply (0) from an echo-request (8)). # iptables -A INPUT -i $IFACE -p icmp -m state --state ESTABLISHED,RELATED \ -j ACCEPT # # We always allow icmp out. # iptables -A OUTPUT -o $IFACE -p icmp -m state --state NEW,ESTABLISHED,RELATED \ -j ACCEPT # #------------------------------------------------------------------------------ ## DNS # NOTE: DNS uses tcp for zone transfers, for transfers greater than 512 bytes # (possible, but unusual), and on certain platforms like AIX (I am told), so # you might have to add a copy of this rule for tcp if you need it # Allow UDP packets in for DNS client from nameservers. # I added NEW & RELATED, because if you send masses of queries to a DNS, another # (alternate) nameserver might respond due to load-balancing and these packets # are then DROPped, and we do not want this! Mhh, maybe we should completely # remove the '-m state --state ...' (?) # You may want the flexibility to change your preferred DNS, you may even get # new DNS assigned if you start a VPN connection; so let's just accept tcp/udp # packets coming from (remote) port 53, which is also recommended on # http://www.usyd.edu.au/is/comms/security/accesslists.html and # http://www.siliconvalleyccie.com/linux-hn/iptables-intro.htm # We also allow tcp, because replies larger than 512 bytes will come via tcp. # For now, we (minimally) log such packets... # iptables -A INPUT -i $IFACE -p udp -s 0/0 --sport 53 --dport $UP_PORTS \ -m state --state NEW,ESTABLISHED,RELATED \ $limA -j LOG ${LOGP}"-ACCEPT-from_53-in: " iptables -A INPUT -i $IFACE -p udp -s 0/0 --sport 53 --dport $UP_PORTS \ -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -i $IFACE -p tcp -s 0/0 --sport 53 --dport $UP_PORTS \ -m state --state NEW,ESTABLISHED,RELATED \ $limA -j LOG ${LOGP}"-ACCEPT-from_53-in: " iptables -A INPUT -i $IFACE -p tcp -s 0/0 --sport 53 --dport $UP_PORTS \ -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT # # Allow UDP packets to DNS servers from client. # iptables -A OUTPUT -o $IFACE -p udp -d 0/0 --dport 53 \ -m state --state NEW,ESTABLISHED -j ACCEPT # #------------------------------------------------------------------------------ ## SSH # Allow ssh outbound. # iptables -A INPUT -i $IFACE -p tcp --sport 22 -m state \ --state ESTABLISHED -j ACCEPT iptables -A OUTPUT -o $IFACE -p tcp --dport 22 -m state \ --state NEW,ESTABLISHED -j ACCEPT # #------------------------------------------------------------------------------ ## WWW # Allow www outbound to 80. # iptables -A INPUT -i $IFACE -p tcp --sport 80 -m state \ --state ESTABLISHED -j ACCEPT iptables -A OUTPUT -o $IFACE -p tcp --dport 80 -m state \ --state NEW,ESTABLISHED -j ACCEPT # # Allow www outbound to 443. # iptables -A INPUT -i $IFACE -p tcp --sport 443 -m state \ --state ESTABLISHED -j ACCEPT iptables -A OUTPUT -o $IFACE -p tcp --dport 443 -m state \ --state NEW,ESTABLISHED -j ACCEPT # #------------------------------------------------------------------------------ ## TELNET # Allow telnet outbound - should actually be forbidden ;-) # iptables -A INPUT -i $IFACE -p tcp --sport 23 -m state \ --state ESTABLISHED -j ACCEPT iptables -A OUTPUT -o $IFACE -p tcp --dport 23 -m state \ --state NEW,ESTABLISHED -j ACCEPT # #------------------------------------------------------------------------------ ## FTP # Allow ftp outbound. # iptables -A INPUT -i $IFACE -p tcp --sport 21 -m state \ --state ESTABLISHED -j ACCEPT iptables -A OUTPUT -o $IFACE -p tcp --dport 21 -m state \ --state NEW,ESTABLISHED -j ACCEPT # # Now for the connection tracking part of ftp. This is discussed more # completely in the section on connection tracking on # the page http://www.sns.ias.edu/~jns/security/iptables/ # 1) Active ftp. # 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 INPUT -i $IFACE -p tcp --sport 20 -m state \ --state ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -o $IFACE -p tcp --dport 20 -m state \ --state ESTABLISHED -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 INPUT -i $IFACE -p tcp --sport $UP_PORTS --dport $UP_PORTS \ -m state --state ESTABLISHED -j ACCEPT iptables -A OUTPUT -o $IFACE -p tcp --sport $UP_PORTS --dport $UP_PORTS \ -m state --state ESTABLISHED,RELATED -j ACCEPT # #------------------------------------------------------------------------------ ## SMTP # Allow smtp outbound. # iptables -A INPUT -i $IFACE -p tcp --sport 25 -m state \ --state ESTABLISHED -j ACCEPT iptables -A OUTPUT -o $IFACE -p tcp --dport 25 -m state \ --state NEW,ESTABLISHED -j ACCEPT # #------------------------------------------------------------------------------ ## AUTH server # Reject ident probes with a tcp reset. # I need to do this for a broken mailhost that won't accept my mail if I just # drop its ident probe. (This is not from me (uk), but from another author) # We leave this, according to http://www.seifried.org/security/ports/0/113.html # and we also send a reset packet, but we log it: # iptables -A INPUT -i $IFACE -p tcp --dport 113 \ $limD -j LOG ${LOGP}"-REJECT-AUTH-IN: " iptables -A INPUT -i $IFACE -p tcp --dport 113 -j REJECT --reject-with tcp-reset # #------------------------------------------------------------------------------ ## TRACEROUTE # Outgoing traceroute anywhere. # The reply to a traceroute is an icmp time-exceeded which is dealt with by the # next rule. # iptables -A OUTPUT -o $IFACE -p udp --sport $TR_SRC_PORTS \ --dport $TR_DEST_PORTS -m state --state NEW -j ACCEPT # #------------------------------------------------------------------------------ # DROP invalid packets - they may have been mangled...: # iptables -A INPUT -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -m state \ --state INVALID \ $limD -j LOG ${LOGP}"-INVALID-invalid-IN: " iptables -A INPUT -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -m state \ --state INVALID -j DROP # #------------------------------------------------------------------------------ # Accept all (?) outgoing packets: # iptables -A OUTPUT -o $IFACE -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT # #------------------------------------------------------------------------------ ## Packets that should be DROPped without logging; these are special cases, # which cannot be handled in the file /etc/picofirewall/noise_nolog.cfg : # # DROP & do not log packets to 224.0.0.1...: # iptables -t mangle -A PREROUTING -d 224.0.0.1 -j DROP # # DROP & do not log the numerous udp packets from/to port 520: # (in our case, they come from our nearest router) # iptables -t mangle -A PREROUTING -i $IFACE -p udp --sport 520 \ -d 255.255.255.255 --dport 520 -j DROP # #------------------------------------------------------------------------------ ## LOG ANYTHING NOT ALREADY ALLOWED # You don't have to split up your logging like I do below, but I prefer to do it # this way because one can then grep for things in the logs more easily. # The default is now to only partially log things - you may change this by # setting LIMIT_DROP_LOGGING to "no". This could e.g. be done while # experimenting with your firewall or when you are looking for errors. # (Part of the orig. text: "-m limit --limit 6/h --limit-burst 5") # ??? In order to see what is going on, I usually log everything. If logging is # restricted too much, port scans cannot be detected (e.g. by using # 'picofirescan'; see http://www.seismo.ethz.ch/linux/picofirescan.html). # # # Any udp not already allowed is logged and then dropped. # iptables -A INPUT -i $IFACE -p udp -m state --state NEW \ $limD -j LOG ${LOGP}"-DROP-UDP-IN: " iptables -A INPUT -i $IFACE -p udp -m state --state NEW -j DROP iptables -A OUTPUT -o $IFACE -p udp \ $limD -j LOG ${LOGP}"-DROP-UDP-OUT: " iptables -A OUTPUT -o $IFACE -p udp -j DROP # # Any icmp not already allowed is logged and then dropped. # iptables -A INPUT -i $IFACE -p icmp -m state --state NEW \ $limD -j LOG ${LOGP}"-DROP-ICMP-IN: " iptables -A INPUT -i $IFACE -p icmp -m state --state NEW -j DROP iptables -A OUTPUT -o $IFACE -p icmp $limD -j LOG ${LOGP}"-DROP-ICMP-OUT: " iptables -A OUTPUT -o $IFACE -p icmp -j DROP # # Any tcp not already allowed is logged and then dropped. # iptables -A INPUT -i $IFACE -p tcp -m state --state NEW \ $limD -j LOG ${LOGP}"-DROP-TCP-IN: " iptables -A INPUT -i $IFACE -p tcp -m state --state NEW -j DROP iptables -A OUTPUT -o $IFACE -p tcp $limD -j LOG ${LOGP}"-DROP-TCP-OUT: " iptables -A OUTPUT -o $IFACE -p tcp -j DROP # # Anything else not already allowed is logged and then dropped. # It will be dropped by the default policy anyway ... but let's be careful... # e.g. we once got the following packet: # Nov 30 17:06:10 zak kernel: P-Fw-DROP-PROTOCOL-X-IN: IN=eth0 OUT= MAC=00:00:1c:b6:24:25:00:d0:bc:f0:ad:2c:08:00 SRC=147.51.166.174 DST=129.132.95.155 LEN=172 TOS=0x00 PREC=0x00 TTL=233 ID=0 PROTO=99 # iptables -A INPUT -i $IFACE $limD -j LOG ${LOGP}"-DROP-PROTOCOL-X-IN: " iptables -A INPUT -i $IFACE -j DROP iptables -A OUTPUT -o $IFACE $limD -j LOG ${LOGP}"-DROP-PROTOCOL-X-OUT: " iptables -A OUTPUT -o $IFACE -j DROP # # #------------------------------------------------------------------------------ # end.