Setting Up Ubuntu as a Firewall / Router / Nat

As described in the overview I executed this task in three steps. This  document describes the second step in which eth0 was set to request an address using dhcp and the Ubuntu system could replace the Linksys router.

eth0: Set to request an address via dhcp and connected directly to cable modem.
eth1: Set as a static address (192.168.1.1) and connected to a switch (replacing a Linksys router).

Note: The first two tasks of step one - installing a dhcp server and enabling packet forwarding - are assumed to have been completed. See those notes if you are starting here.

Set Interface Addresses

We need to have eth0 request an address using dhcp. The second network interface, eth1, is the connection for my home network. It is set to 192.168.1.1 as was my previous Linksys router.

Set the file /etc/network/interfaces contents like so:
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
	pre-up iptables-restore < /etc/iptables.rules
auto eth1
iface eth1 inet static
	address 192.168.1.1
	netmask 255.255.255.0
	network 192.168.1.0

Configure DHCP Server

This has not changed from step one, so skip if already done.
Edit the file /etc/default/dhcp3-server and enter the line:
INTERFACES="eth1"
This should be the only line in the file unless you have more than two network interfaces and need a dhcp server on another one.

Set DHCP Configuration

Edit the file /etc/dhcp3/dhcpd.conf and set your configuration.
Set the domain name as you want it to appear for the network. I have the lease time set to 1 hour (3600 seconds). The default is 600.
The file has quite a few default entries.

Note: I have entered the domain servers that appeared in the file "/etc/resolv.conf". Those were populated when eth0 received an address from the cable modem. Your name servers will be different. In step three we need to update these name servers automatically.

My uncommented entries at this step are:
ddns-update-style none;
option domain-name "mydomain.com";
option domain-name-servers 68.185.34.67, 68.185.32.10, 68.116.46.115, 68.116.46.70;
default-lease-time 3600;
max-lease-time 7200;
option subnet-mask 255.255.255.0;
option broadcast-address 192.168.1.255;
option routers 192.168.1.1;
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.100 192.168.1.150;
}
log-facility local7;

Set Up Firewall

The firewall rules will vary depending on your needs. Create some text containing the initial iptables setting such as "iptable-rules-thisbox" and load iptables with the command:
sudo sh iptables-rules-thisbox
This simply executes the rules as root. Then test the rules until they meet your needs and you are satisfied with them. Now save the rules like so:
iptables-save > /etc/iptables.rules
The rules I am using are listed below.  Some of the addresses have "x" in the dotted notation. Those are addresses that are allowed to ssh into my box. The "x" characters represent digits in addresses meaningful to my requirements. You will need to tailor the firewall to your specific needs.

EXT_IF=eth0             # Define your external interface here
INT_IF=eth1             # Define your internal interface here
INT_NET='192.168.1.0/24'    # Define your internal network address here
IPTABLES="/sbin/iptables"

# Set up some default policies at this point to avoid any potential race
# condition between flushing the rules and setting up temporary blocks.
#
$IPTABLES -P INPUT DROP
$IPTABLES -P FORWARD DROP

# Flush and delete existing chains
#
$IPTABLES -F
$IPTABLES -t nat -F
$IPTABLES -X
$IPTABLES -Z

# Temporary blocks while the chains are being set up
#
$IPTABLES -A INPUT -i ! lo -j DROP
$IPTABLES -A OUTPUT -o ! lo -j DROP
$IPTABLES -A FORWARD -j DROP

# Unblock loopback traffic right away.
#
$IPTABLES -A INPUT -i lo -j ACCEPT     # Internal, no restrictions

# Log error, then drop
$IPTABLES -N ERRORDROP
$IPTABLES -A ERRORDROP -j LOG --log-level alert --log-prefix "netfilter:ERROR:generic: "
$IPTABLES -A ERRORDROP -j DROP

# Log, then drop
$IPTABLES -N LOGDROP
$IPTABLES -A LOGDROP -j LOG --log-prefix "netfilter:badpac: "
$IPTABLES -A LOGDROP -j DROP

# NoLog drop
$IPTABLES -N NOLOGDROP
$IPTABLES -A NOLOGDROP -j DROP

#SSH trusted host log connection...
$IPTABLES -N ssh-trusted-syn-log
$IPTABLES -A ssh-trusted-syn-log -p tcp --tcp-flags SYN SYN -j LOG --log-prefix "netfilter:SSH_TRUSTED: "
$IPTABLES -A ssh-trusted-syn-log -j ACCEPT
$IPTABLES -N ssh-in
$IPTABLES -A ssh-in -p tcp --tcp-flags SYN SYN -s 32.x.x.x/24 -j ssh-trusted-syn-log #Acme Outbound address
$IPTABLES -A ssh-in -p tcp --tcp-flags SYN SYN -s 24.x.x.x/32 -j ssh-trusted-syn-log #fred's box
$IPTABLES -A ssh-in -p tcp --tcp-flags SYN SYN -s 208.x.x.x/32 -j ssh-trusted-syn-log #joe's box
$IPTABLES -A ssh-in -p tcp --tcp-flags SYN SYN -s 75.x.x.x/32 -j ssh-trusted-syn-log #bob's box
$IPTABLES -A ssh-in -p tcp --tcp-flags SYN SYN -s 192.168.1.0/24  -j ssh-trusted-syn-log #TEMPORARY HACK while this box sits behind linksys
$IPTABLES -A ssh-in -j LOG --log-prefix "netfilter:SSH_ILLEGAL: "
$IPTABLES -A ssh-in -j DROP

#$IPTABLES -i eth0 -t nat -A PREROUTING  -p tcp --dport ssh -j DNAT --to-destination 192.168.1.16  #all ssh is DNAT'd to p6;

# External-Input chain
$IPTABLES -N ext-in
$IPTABLES -A ext-in -m state --state ESTABLISHED,RELATED -j ACCEPT # Allow established and related connections/traffic
$IPTABLES -A ext-in -p tcp --dport ssh -j ssh-in #all "new" ssh external connections
$IPTABLES -A ext-in -p udp --dport 6798 -j ACCEPT # FWTOOL upd port
$IPTABLES -A ext-in -j LOGDROP

# Input chain
$IPTABLES -A INPUT -i $INT_IF -j ACCEPT     # Internal, no restrictions
$IPTABLES -A INPUT -j ext-in     # External interface(s)
$IPTABLES -A INPUT -j ERRORDROP             # Shouldn't be here

# Output chain # The following takes care of an info leak problem if you configure any NAT port forwarding rules in the future.
$IPTABLES -A OUTPUT -o $EXT_IF -m state -p icmp --state INVALID -j DROP

# Forward chain
$IPTABLES -A FORWARD -i $INT_IF -j ACCEPT
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
#anything beyond here is NOT established, and is coming from an external interface
$IPTABLES -A FORWARD -p tcp --dport ssh -j ssh-in #all "new" ssh external connections
#FORWARD TABLE HAS A POLICY OF DROP, so if we didn't pick it up above, it's gone
#the question is HOW did it get here,
$IPTABLES -A FORWARD -j LOG --log-prefix "netfilter:ERROR:FORWARD: "
$IPTABLES -A FORWARD -j DROP

# NAT handling
$IPTABLES -t nat -A POSTROUTING -s $INT_NET -o $EXT_IF -j MASQUERADE

#open things up now that all is setup
$IPTABLES -D INPUT 1
$IPTABLES -D OUTPUT 1
$IPTABLES -D FORWARD 1