Firewalls

For a brief introduction see Filtering Firewalls in Linux.ppt

If you are using Ubuntu, you should look at the ubuntul 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

# /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

# /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.

#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.

NetworkSecurity/FireWall (last edited 2019-03-24 23:30:37 by scot)