A default-deny stance on in-bound traffic makes a good firewall; a default-deny stance on out-bound traffic in addition to this makes a better one. Firewalls in which not a single packet is allowed in or out of a machine unless it matches a tightly-specified rule are called pinprick (or pinhole) firewalls.
This example is implemented using IPTables. Points to note --- the machine running this firewall is:
#!/bin/sh # -- where's the iptables binary? IPT="/sbin/iptables" # ------------------------------------------------------------------------------------------ # -- to start with, clean out the bath : # ------------------------------------------------------------------------------------------ for i in filter nat mangle do $IPT -t $i -F $IPT -t $i -X done # ------------------------------------------------------------------------------------------ # -- create our tables : # ------------------------------------------------------------------------------------------ # ...we use separate tables for different things, since it's faster... $IPT -N TCP_IN $IPT -N TCP_OUT $IPT -N UDP_IN $IPT -N UDP_OUT # ------------------------------------------------------------------------------------------ # -- me/local : # ------------------------------------------------------------------------------------------ # ...allow me to talk to myself on both loopback and external-facing devices... $IPT -t filter -A INPUT -s 127.0.0.1 -j ACCEPT $IPT -t filter -A OUTPUT -s 127.0.0.1 -j ACCEPT $IPT -t filter -A INPUT -i lo -p tcp -s 130.88.253.254 -j ACCEPT $IPT -t filter -A OUTPUT -o lo -p tcp -s 130.88.253.254 -j ACCEPT # ------------------------------------------------------------------------------------------ # -- remote debug : # ------------------------------------------------------------------------------------------ # ...occasionally we are crazy enough to modify the IPTables rules remotely, so offer # a safety net: allow in a hardened machine to sort it out : $IPT -t filter -A INPUT -s 130.88.253.255 -j ACCEPT $IPT -t filter -A OUTPUT -d 130.88.253.255 -j ACCEPT # ------------------------------------------------------------------------------------------ # -- handle TCP and UDP : # ------------------------------------------------------------------------------------------ # ...TCP and UDP traffic, in-bound and out-bound, is handled by the # appropriate table, so we jump to it... $IPT -t filter -A INPUT -p tcp -i eth0 -d 130.88.253.254 -j TCP_IN $IPT -t filter -A OUTPUT -p tcp -o eth0 -s 130.88.253.254 -j TCP_OUT $IPT -t filter -A INPUT -p udp -i eth0 -d 130.88.253.254 -j UDP_IN $IPT -t filter -A OUTPUT -p udp -o eth0 -s 130.88.253.254 -j UDP_OUT # ------------------------------------------------------------------------------------------ # -- handle ICMP : # ------------------------------------------------------------------------------------------ # ...we don't like it... $IPT -t filter -A INPUT -p icmp -j DROP # ------------------------------------------------------------------------------------------ # -- default drops : # ------------------------------------------------------------------------------------------ # ...frankly, anything that gets this far is something we are not interested in, # and which is going to the bin... # # -- e.g., windoze broadcast/netbios-type crap is going straight down the hole # -- other stuff we log, before dropping, just to see what it is... $IPT -t filter -A INPUT -p udp --sport 137 --dport 137 -j DROP $IPT -t filter -A INPUT -p udp --sport 138 --dport 138 -j DROP $IPT -t filter -A INPUT -j LOG --log-prefix " **INPUT DROP** " $IPT -t filter -A INPUT -j DROP $IPT -t filter -A OUTPUT -j LOG --log-prefix " **OUTPUT DROP** " $IPT -t filter -A OUTPUT -j DROP # ------------------------------------------------------------------------------------------ # -- the policies which override everything else : # ------------------------------------------------------------------------------------------ $IPT -t filter -P INPUT DROP $IPT -t filter -P OUTPUT DROP $IPT -t filter -P FORWARD DROP # ------------------------------------------------------------------------------------------ # -- THE END. (End of "main"; following are the "subroutines/functions".) # ------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------ # -- CHAIN TCP_IN : new inward TCP connections : # ------------------------------------------------------------------------------------------ # -- bad stuff : # $IPT -t filter -A TCP_IN -p tcp ! --syn -m state --state NEW -j LOG --log-prefix " **NEW NOT SYN** " $IPT -t filter -A TCP_IN -p tcp ! --syn -m state --state NEW -j DROP # -- incoming packets related to connections we initiated out-bound : # $IPT -t filter -A TCP_IN -p tcp --dport 1024: -m state --state ESTABLISHED,RELATED -j ACCEPT # -- allow new connections to our http-server plus traffic on established connections from all hosts : # $IPT -t filter -A TCP_IN -p tcp --sport 1024: --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT # -- ssh connections to our daemon from selected hosts only : # $IPT -t filter -A TCP_IN -p tcp -s 130.88.254.254 --sport 1024: --dport 22 -m state --state NEW -j LOG --log-level warn $IPT -t filter -A TCP_IN -p tcp -s 130.88.254.254 --sport 1024: --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT # -- nfs (mount a remote disk from 254.254) : # $IPT -t filter -A TCP_IN -p tcp -s 130.88.254.254 --sport 111 -m state --state NEW,ESTABLISHED -j ACCEPT $IPT -t filter -A TCP_IN -p tcp -s 130.88.254.254 --sport 2049 --dport 1024: -m state --state NEW,ESTABLISHED -j ACCEPT # -- est/rel ftp (for apt-get) : # # ...need to deal with initial connection out to 21, passive FTP (high to high, # originating from client/us) and active FTP (originates from server on 20 # to client/us on high)... # # ...addresses reflect contencts of /etc/apt/sources.list... # $IPT -t filter -A TCP_IN -p tcp -s 195.224.53.39 --sport 21 -m state --state ESTABLISHED -j ACCEPT $IPT -t filter -A TCP_IN -p tcp -s 195.224.53.39 --sport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT $IPT -t filter -A TCP_IN -p tcp -s 195.224.53.39 --sport 1024: --dport 1024: -m state --state ESTABLISHED -j ACCEPT # -- every other tcp connection can go in the bin : # # ...alternatively: $IPT -t filter -A TCP_IN -m state --state NEW -j DROP... # $IPT -t filter -A TCP_IN -m state --state NEW -j REJECT --reject-with icmp-port-unreachable # -- drop any other tcp packet : # $IPT -t filter -A TCP_IN -p tcp -j LOG --log-prefix " **TCP_IN DROP** " $IPT -t filter -A TCP_IN -p tcp -j DROP # ------------------------------------------------------------------------------------------ # -- CHAIN TCP_OUT : outward TCP : # ------------------------------------------------------------------------------------------ # ...output is default-deny too... # # allow connections from all local high-numbered ports to all remote --- so that any TCP # client on our machine can get new connections out : # # $IPT -t filter -A TCP_OUT -p tcp --sport 1024:65535 -j ACCEPT # # NO! The above rule is common, but lazy/sloppy. # YES: allow strictly limited TCP client access out : # $IPT -t filter -A TCP_OUT -p tcp --sport 1024: --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT $IPT -t filter -A TCP_OUT -p tcp --sport 1024: --dport 2222 -m state --state NEW,ESTABLISHED -j ACCEPT # -- allow established outward http to any host : # $IPT -t filter -A TCP_OUT -p tcp --sport 80 --dport 1024: -m state --state ESTABLISHED -j ACCEPT # -- allow established outward traffic to vips from our sshd : # $IPT -t filter -A TCP_OUT -p tcp --sport 22 -d 130.88.254.254 -m state --state ESTABLISHED -j ACCEPT # -- nfs (mount a remote disk from 254.254) : # $IPT -t filter -A TCP_OUT -p tcp -d 130.88.254.254 --dport 111 -m state --state NEW,ESTABLISHED -j ACCEPT $IPT -t filter -A TCP_OUT -p tcp -d 130.88.254.254 --sport 1024: --dport 2049 -m state --state NEW,ESTABLISHED -j ACCEPT # -- allow ftp so apt-get can do its stuff : # # ...need to deal with initial connection out to 21, passive FTP (high to high, # originating from client/us) and active FTP (originates from server on 20 # to client/us on high)... # # ...addresses reflect contencts of /etc/apt/sources.list... # $IPT -t filter -A TCP_OUT -p tcp -d 195.224.53.39 --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT $IPT -t filter -A TCP_OUT -p tcp -d 195.224.53.39 --dport 20 -m state --state ESTABLISHED -j ACCEPT $IPT -t filter -A TCP_OUT -p tcp -d 195.224.53.39 --sport 1024: --dport 1024: -m state --state ESTABLISHED,RELATED -j ACCEPT # -- default deny : # $IPT -t filter -A TCP_OUT -p tcp -j LOG --log-prefix " **TCP_OUT DROP** " $IPT -t filter -A TCP_OUT -p tcp -j DROP # ------------------------------------------------------------------------------------------ # -- CHAIN UDP_IN : new inward UDP connections : # ------------------------------------------------------------------------------------------ $IPT -t filter -A UDP_IN -p udp -m state --state ESTABLISHED,RELATED -j ACCEPT # -- nfs (mount a remote disk from 254.254) : # $IPT -t filter -A UDP_IN -p udp -s 130.88.254.254 --sport 111 -m state --state NEW,ESTABLISHED -j ACCEPT $IPT -t filter -A UDP_IN -p udp -s 130.88.254.254 --sport 2049 --dport 1024: -j ACCEPT # -- default deny : # $IPT -t filter -A UDP_IN -p udp -j DROP # ------------------------------------------------------------------------------------------ # -- CHAIN UDP_OUT : new outward UDP connections : # ------------------------------------------------------------------------------------------ # -- DNS lookups (we must have these!) : # $IPT -t filter -A UDP_OUT -p udp --sport 1024: --dport 53 -j ACCEPT # -- nfs (mount a remote disk from 254.254) : # $IPT -t filter -A UDP_OUT -p udp -d 130.88.254.254 --dport 111 -j ACCEPT $IPT -t filter -A UDP_OUT -p udp -d 130.88.254.254 --dport 1024: -j ACCEPT # -- remote syslog logs (syslogs are copied to a secure remote server) : # $IPT -t filter -A UDP_OUT -p udp -d 130.88.254.253 --sport 514 -j ACCEPT # -- default deny : # $IPT -t filter -A UDP_OUT -p udp -j DROP # ------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------
...previous | up (conts) | next... |