PPPoE / SNAT / DNAT / Linux / WiredCountry HowTo/Setup Notes

In this setup I have Wired country with two static IP addresses. There are several internal servers
and workstations which can have external access. Some of the servers present their services to the
external internet, in this example there is a webserver on each IP and an smtp server on one.

Here's how our setup looks, the ppp0 interface is the wired country link.
This graphic shows the path traffic would go for each webserver:

Wiring wise, eth0 is directly connected to the box that comes down from the roof antenna.

eth1 & eth2 are connected to their respective networks. The central server is a Linux box
running the 2.6 kernel. The distribution is irrelevant in that the script does pretty well everything.

Consider this script a starting point only, just enough to get you going. If you spot any errors then
please let me know. I'm just putting these notes up for anyone else who needs to do this.


Here is the network script that does pretty well everything: startnet.sh
#! /bin/sh

# Author: Clark Mills (c.mills@auckland.ac.nz)
# Date: Fri Nov  4 15:30:47 NZDT 2005
# Comment: Test setup of WiredCountry with 2 static IPs.  Each IP presents
#	   its own services to the world.  Also the internal networks wants
#	   some seperation and firewalling.
# Note: If you spot any errors then please let me know and I'll update
#	things.  Cheers...  Clark

EXT_IP1=12.34.56.78	# Given to us by PPP
EXT_IP2=12.34.56.79

EXT_IF=ppp0		# Created by rp-PPPoE
# eth0 is used by rp-PPPoE
NET_1=eth1
NET_2=eth2

###################################################################
###################################################################
# Start Roaring Penguin PPP.  This sets our static IP, EXT_IP1 and is
# configured to use eth0.  It's also configured to keep the link up.
# All part of the "go" script that's part of the rp-PPPoE build.
#
# Get this from:
# http://www.roaringpenguin.com/penguin/pppoe/rp-pppoe-3.6.tar.gz
/usr/sbin/pppoe-start 

###################################################################
###################################################################
# Forwarding is needed
echo 1 > /proc/sys/net/ipv4/ip_forward 

###################################################################
###################################################################
# Configure our interfaces

# Our external interface has 2 ips
ip addr add $EXT_IP2 dev $EXT_IF

# Bring up our internal interfaces
ifconfig $NET_1 10.0.1.254 netmask 255.255.255.0 broadcast 10.0.1.255 up
ifconfig $NET_2 10.0.2.254 netmask 255.255.255.0 broadcast 10.0.2.255 up

###################################################################
###################################################################
# Stuff

# Connection tracking (Copy typing, monkey see, monkey do)
modprobe ip_conntrack
modprobe ip_conntrack_ftp

# Default to block
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP

# Clear any settings
iptables -F
iptables -t nat -F

# "delete" chain [re] create
iptables -X delete	2> /dev/null
iptables -N delete
iptables -A delete -j DROP

# "log" chain [re] create
iptables -X log		2> /dev/null
iptables -N log
iptables -A log -j LOG --log-prefix "Dropped: " --log-level INFO
iptables -A log -j delete

# Connection tracking (Copy typing, monkey see, monkey do)
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

# Loopback open
iptables -A INPUT -j ACCEPT	\
	--in-interface lo -s 127.0.0.0/8

iptables -A OUTPUT -j ACCEPT	\
	--out-interface lo -d 127.0.0.0/8

###################################################################
###################################################################
# This allows external hosts to access our internal servers
# by port forwarding to present our services to the world on their own IPs

# NET_1 stuff
for SERVICE in http https; do
  # dNAT $EXT_IP1(SERVICE) -> 10.0.1.1(SERVICE)
  iptables -t nat -A PREROUTING -p tcp -i $EXT_IF \
	-d $EXT_IP1 --dport $SERVICE -j DNAT --to 10.0.1.1:$SERVICE

  # Poke a hole in the firewall
  iptables -A FORWARD -p tcp -j ACCEPT	\
	--in-interface $EXT_IF	\
	--out-interface $NET_1 -d 10.0.1.1 --dport $SERVICE
done


# NET_2 stuff
for SERVICE in smtp http https; do
  # dNAT $EXT_IP2(SERVICE) -> 10.0.1.1(SERVICE)
  iptables -t nat -A PREROUTING -p tcp -i $EXT_IF \
	-d $EXT_IP2 --dport $SERVICE -j DNAT --to 10.0.2.1:$SERVICE

  # Poke a hole in the firewall
  iptables -A FORWARD -p tcp -j ACCEPT	\
	--in-interface $EXT_IF	\
	--out-interface $NET_2 -d 10.0.2.1 --dport $SERVICE
done

###################################################################
###################################################################
# This allows our networks out.  Because we have a static IP
# we don't need masquerading and can use SNAT.  It's supposed to be a
# bit faster and besides, since we have 2 IPs I'm going to assign an IP
# to each network (because I can :)

# Anything from 10.0.1.x to the internet will go out with the ip of EXT_IP1
iptables -A POSTROUTING -t nat -s 10.0.1.0/24 -o $EXT_IF	\
	-j SNAT --to-source $EXT_IP1

# Poke a hole in the firewall
iptables -A FORWARD -j ACCEPT	\
	--in-interface $NET_1 -s 10.0.1.0/24	\
	--out-interface $EXT_IF -d ! 10.0.1.0/8

####

# Anything from 10.0.2.x to the internet will go out with the ip of EXT_IP2
iptables -A POSTROUTING -t nat -s 10.0.2.0/24 -o $EXT_IF	\
	-j SNAT --to-source $EXT_IP2

# Poke a hole in the firewall
iptables -A FORWARD -j ACCEPT	\
	--in-interface $NET_2 -s 10.0.2.0/24	\
	--out-interface $EXT_IF -d ! 10.0.2.0/8

###################################################################
###################################################################
# Boring firewall stuff below here

# Allow pings to this box
  # From NET_1
iptables -A INPUT -p icmp -j ACCEPT	\
	--in-interface $NET_1 -s 10.0.1.0/24	\
	-d 10.0.1.254 --icmp-type echo-request

  # From NET_2
iptables -A INPUT -p icmp -j ACCEPT	\
	--in-interface $NET_2 -s 10.0.2.0/24	\
	-d 10.0.2.254 --icmp-type echo-request

  # From External
iptables -A INPUT -p icmp -j ACCEPT	\
	--in-interface $EXT_IF	\
	-d 12.34.56.78/31 --icmp-type echo-request

###################################################################

# Allow email from one host to 10.0.2.1 -> 10.0.1.1 (smtp)
iptables -A FORWARD -p tcp -j ACCEPT	\
	--in-interface $NET_2 -s 10.0.2.1	\
	--out-interface $NET_1 -d 10.0.1.1 --dport 25

###################################################################

# NET_1 can connect to NET_2 any which way it likes
iptables -A FORWARD -j ACCEPT	\
	--in-interface $NET_1 -s 10.0.1.0/24	\
	--out-interface $NET_2 -d 10.0.2.0/24

###################################################################
###################################################################
# Log and drop anything that falls through

# Final catch alls
iptables -A INPUT -j log
iptables -A OUTPUT -j log
iptables -A FORWARD -j log

# EOF

Google keywords: Wired country WiredCountry Wired-Country wc linux howto example script forward
masquerade help nz New Zealand ihug.co.nz iconz.co.nz

Document History
Fri Nov  4 16:02:39 NZDT 2005 c.mills Created
Clark Mills c.mills@auckland.ac.nz