Sunday, July 8, 2007

KB: Firewall Configuration on Ubuntu

Configuration guide for iptables on Ubuntu Linux.

Contents

Overview

This article assumes that you already have iptables installed on your system.

Flush Script

flush_iptables.sh:
  #!/bin/sh

  #
  # Set the default policy
  #
  iptables -P INPUT ACCEPT
  iptables -P FORWARD ACCEPT
  iptables -P OUTPUT ACCEPT

  #
  # Set the default policy for the NAT table
  #
  iptables -t nat -P PREROUTING ACCEPT
  iptables -t nat -P POSTROUTING ACCEPT
  iptables -t nat -P OUTPUT ACCEPT

  #
  # Delete all rules
  #
  iptables -F
  iptables -t nat -F

  #
  # Delete all chains
  #
  iptables -X
  iptables -t nat -X

  # End message
  echo " [End of flush]"

Firewall Rules Script

start_iptables.sh:
  #!/bin/bash

  #
  # For a system to function as a firewall the kernel has to be told to forward
  # packets between interfaces, i.e., it needs to be a router.
  # IP fordarding must be enabled by other than this script for production use.
  # That is best done by editing /etc/sysctl.conf and setting:
  #
  # net.ipv4.ip_forward = 1
  #
  # Since that file will only be read at boot, you can uncomment the following
  # line to enable forwarding on the fly for initial testing. Just remember that
  # the saved iptables data will not include the command.
  #
  echo 0 > /proc/sys/net/ipv4/ip_forward

  # No spoofing
  #if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ]
  #then
  #for filtre in /proc/sys/net/ipv4/conf/*/rp_filter
  #do
  #echo 1 > $filtre
  #done
  #fi 

  # No icmp
  #echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
  #echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

  #load some modules you may need
  modprobe ip_tables
  modprobe ip_nat_ftp
  modprobe ip_nat_irc
  modprobe iptable_filter
  modprobe iptable_nat 

  #
  # Set an absolute path to IPTABLES and define the interfaces.
  #
  IPTABLES="/sbin/iptables"

  #
  # OUTSIDE is the outside or untrusted interface that connects to the Internet
  # and INSIDE is, well that ought to be obvious. INSIDE_IP is the IP configured for the
  # inside interface and INSIDE_BCAST is the broadcast IP, necssary if you will be running
  # a DHCP server on the firewall
  #
  OUTSIDE=eth1
  INSIDE=eth0
  INSIDE_IP=192.168.16.1
  INSIDE_BCAST=192.168.16.255

  #
  # Clear out any existing firewall rules, and any chains that might have
  # been created. Then set the default policies.
  #
  $IPTABLES -F
  $IPTABLES -F INPUT
  $IPTABLES -F OUTPUT
  $IPTABLES -F FORWARD
  $IPTABLES -F -t mangle
  $IPTABLES -F -t nat
  $IPTABLES -X
  $IPTABLES -P INPUT DROP
  $IPTABLES -P OUTPUT ACCEPT
  $IPTABLES -P FORWARD ACCEPT

  #
  # Begin setting up the rulesets. First define some rule chains to handle
  # exception conditions. These chains will receive packets that we are not
  # willing to pass. Limiters on logging are used so as to not to swamp the
  # firewall in a DOS scenario.
  #
  # silent       - Just dop the packet
  # tcpflags     - Log packets with bad flags, most likely an attack
  # firewalled   - Log packets that that we refuse, possibly from an attack
  #
  $IPTABLES -N silent
  $IPTABLES -A silent -j DROP

  $IPTABLES -N tcpflags
  $IPTABLES -A tcpflags -m limit --limit 15/minute -j LOG --log-prefix TCPflags:
  $IPTABLES -A tcpflags -j DROP

  $IPTABLES -N firewalled
  $IPTABLES -A firewalled -m limit --limit 15/minute -j LOG --log-prefix Firewalled:
  $IPTABLES -A firewalled -j DROP

  #
  # Use  NPAT if you have a dynamic IP. Otherwise comment out the following
  # line and use the Source NAT below.
  #
  $IPTABLES -t nat -A POSTROUTING -o $OUTSIDE -j MASQUERADE

  #
  # Use Source NAT if to do the NPAT you have a static IP or netblock.
  # Remember to change the IP to be that of your OUTSIDE NIC.

  #
  #$IPTABLES -t nat -A POSTROUTING -o $OUTSIDE -j SNAT --to 10.0.0.5

  #
  # Examples of Port forwarding.
  #
  # The first forwards HTTP traffic to 10.0.0.10
  # The second forwards SSH to 10.0.0.10
  # The third forwards a block of tcp and udp ports (2300-2400) to 10.0.0.10
  #
  # Remember that if you intend to forward something that you will also
  # have to add a rule to permit the inbound traffic.
  #
  $IPTABLES -t nat -A PREROUTING -i $OUTSIDE -p tcp --dport 80 -j DNAT --to 192.168.16.1:80
  #$IPTABLES -t nat -A PREROUTING -i $OUTSIDE -p tcp --dport 443 -j DNAT --to 169.254.174.2:443
  #$IPTABLES -t nat -A PREROUTING -i $OUTSIDE -p tcp --dport 8000 -j DNAT --to 169.254.174.2:8000

  $IPTABLES -t nat -A PREROUTING -i $OUTSIDE -p tcp --dport 25 -j DNAT --to 192.168.16.1:25
  #$IPTABLES -t nat -A PREROUTING -i $OUTSIDE -p tcp --dport 21 -j DNAT --to 169.254.174.2:21
  #$IPTABLES -t nat -A PREROUTING -i $OUTSIDE -p tcp --dport 22 -j DNAT --to 169.254.174.2

  #$IPTABLES -t nat -A PREROUTING -i $OUTSIDE -p tcp --dport 2300:2400 -j DNAT --to 10.0.0.10
  #$IPTABLES -t nat -A PREROUTING -i $OUTSIDE -p udp --dport 2300:2400 -j DNAT --to 10.0.0.10

  #$IPTABLES -t nat -A PREROUTING -i $OUTSIDE -p tcp --dport 1720 -j DNAT --to 169.254.174.3
  #$IPTABLES -t nat -A PREROUTING -i $OUTSIDE -p tcp --dport 9550 -j DNAT --to 169.254.174.4
  #$IPTABLES -t nat -A PREROUTING -i $OUTSIDE -p tcp --dport 1723 -j DNAT --to 169.254.174.4
  #$IPTABLES -t nat -A PREROUTING -i $OUTSIDE -p 47 -j DNAT --to 169.254.174.4
  #$IPTABLES -t nat -A PREROUTING -i $OUTSIDE -p udp --dport 500 -j DNAT --to 169.254.174.4

  #$IPTABLES -t nat -A PREROUTING -i $OUTSIDE -p tcp --dport 2401 -j DNAT --to 169.254.174.2:2401
  #$IPTABLES -t nat -A PREROUTING -i $OUTSIDE -p tcp --dport 30000:30010 -j DNAT --to 169.254.174.3
  #$IPTABLES -t nat -A PREROUTING -i $OUTSIDE -p udp --dport 5000:5003 -j DNAT --to 169.254.174.3

  #
  # These are all TCP flag combinations that should never, ever, occur in the
  # wild. All of these are illegal combinations that are used to attack a box
  # in various ways.
  #
  $IPTABLES -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j tcpflags
  $IPTABLES -A INPUT -p tcp --tcp-flags ALL ALL -j tcpflags
  $IPTABLES -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j tcpflags
  $IPTABLES -A INPUT -p tcp --tcp-flags ALL NONE -j tcpflags
  $IPTABLES -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j tcpflags
  $IPTABLES -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j tcpflags

  #
  # Allow selected ICMP types and drop the rest.
  #
  $IPTABLES -A INPUT -p icmp --icmp-type 0 -j ACCEPT
  $IPTABLES -A INPUT -p icmp --icmp-type 3 -j ACCEPT
  $IPTABLES -A INPUT -p icmp --icmp-type 11 -j ACCEPT
  $IPTABLES -A INPUT -p icmp --icmp-type 8 -m limit --limit 1/second -j ACCEPT
  $IPTABLES -A INPUT -p icmp -j firewalled

  #
  # The loopback interface is inheritly trustworthy. Do not disable it or
  # a number of things on the firewall will break.
  #
  $IPTABLES -A INPUT -i lo -j ACCEPT

  #
  # Uncomment the following  if the inside machines are trustworthy and
  # there are services on the firewall, like DNS, web, etc., that they need to access.
  # And remember to change the  IP to be that of the INSIDE interface of the firewall.
  #
  $IPTABLES -A INPUT -i $INSIDE -d $INSIDE_IP -j ACCEPT

  #
  # If you are running a DHCP server on the firewall uncomment the next two lines
  #
  $IPTABLES -A INPUT -i $INSIDE -d $INSIDE_BCAST -j ACCEPT
  $IPTABLES -A INPUT -i $INSIDE -d 255.255.255.255 -j ACCEPT
  #$IPTABLES -A INPUT -i $OUTSIDE -s 10.0.0.1 -d 255.255.255.255 -j ACCEPT

  #
  # Allow packets that are part of an established connection to pass
  # through the firewall. This is required for normal Internet activity
  # by inside clients.
  #
  $IPTABLES -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

  #
  # Silently drop and SMB traffic. We have slipped the surly bonds of windows
  # and are dancing on the silvery wings of Linux, so block that windows trash.
  #
  $IPTABLES -A INPUT -p udp --sport 137 --dport 137 -j silent

  #
  # If you want to be able to connect via SSH from the Internet
  # uncomment the next line.
  #
  #$IPTABLES -A INPUT -i $OUTSIDE -d 0/0 -p tcp --dport 22 -j ACCEPT

  #
  # Examples of allowing inbound for the port forwarding examples above.
  #
  $IPTABLES -A INPUT -i $OUTSIDE -d 0/0 -p tcp --dport 80 -j ACCEPT
  #$IPTABLES -A INPUT -i $OUTSIDE -d 0/0 -p tcp --dport 443 -j ACCEPT

  $IPTABLES -A INPUT -i $OUTSIDE -d 0/0 -p tcp --dport 25 -j ACCEPT

  #$IPTABLES -A INPUT -i $OUTSIDE -d 0/0 -p tcp --dport 21 -j ACCEPT

  #$IPTABLES -A INPUT -i $OUTSIDE -d 0/0 -p tcp --dport 2300:2400 -j ACCEPT
  #$IPTABLES -A INPUT -i $OUTSIDE -d 0/0 -p udp --dport 2300:2400 -j ACCEPT

  #$IPTABLES -A INPUT -i $OUTSIDE -d 0/0 -p tcp --dport 8000 -j ACCEPT
  #$IPTABLES -A INPUT -i $OUTSIDE -d 0/0 -p tcp --dport 1720 -j ACCEPT

  #$IPTABLES -A INPUT -i $OUTSIDE -d 0/0 -p tcp --dport 9550 -j ACCEPT
  #$IPTABLES -A INPUT -i $OUTSIDE -d 0/0 -p tcp --dport 1723 -j ACCEPT
  #$IPTABLES -A INPUT -i $OUTSIDE -d 0/0 -p 47 -j ACCEPT
  #$IPTABLES -A INPUT -i $OUTSIDE -d 0/0 -p udp --dport 500 -j ACCEPT

  #$IPTABLES -A INPUT -i $OUTSIDE -d 0/0 -p tcp --dport 2401 -j ACCEPT
  #$IPTABLES -A INPUT -i $OUTSIDE -d 0/0 -p tcp --dport 30000:30010 -j ACCEPT
  #$IPTABLES -A INPUT -i $OUTSIDE -d 0/0 -p udp --dport 5000:5003 -j ACCEPT

  #
  # Anything that has not already matched gets logged and then dropped.
  #
  $IPTABLES -A INPUT -j firewalled

  echo 1 > /proc/sys/net/ipv4/ip_forward

Startup Script

1. Startup script (firewall.sh):
  #!/bin/bash

  RETVAL=0

  # To start the firewall
  start() {
      echo -n "Iptables rules creation: "
      /etc/firewall.bash
      RETVAL=0
  }

  # To stop the firewall
  stop() {
      echo -n "Removing all iptables rules: "
      /etc/flush_iptables.bash
      RETVAL=0
  }

  case $1 in
    start)
      start
      ;;
    stop)
      stop
      ;;
    restart)
      stop
      start
      ;;
    status)
      /sbin/iptables -L
      /sbin/iptables -t nat -L
      RETVAL=0
      ;;
    *)
      echo "Usage: firewall {start|stop|restart|status}"
      RETVAL=1
  esac

  exit
2. Update system startup:

update-rc.d firewall.sh start 20 2 3 4 5 . stop 99 0 1 6 .
or
update-rc.d firewall.sh defaults
To Top