4.12. Using Routing Instead of Bridging

You would rather use routing between your two LAN segments instead of bridging because it gives better performance and more control. For example, you might set up a separate link just to give Internet access to visitors and easily keep them out of your network. Or, you want some separation and different sets of LAN services for each network segment. You know it's a bit more work to set up, but that doesn't bother you, you just want to know how to make it go.

The example access point in this chapter has three Ethernet interfaces: ath0, eth0, and eth1. Instead of bridging ath0 and eth0 to create the br0 LAN interface, ath0 and eth0 are going to be two separate LAN interfaces, and eth1 will still be the WAN interface. iptables will forward traffic between eth0 and eth0, and dnsmasq.conf will need some additional lines to handle the extra subnet.

This recipe assumes you are using either WPA-PSK or WPA-Enterprise with a separate RADIUS server. (See the previous recipes in this chapter to learn how to configure encryption and authentication.) You may create an open access point for testing by commenting out the two lines that control hostapd:

	##/etc/network/interfaces
	auto lo
	iface lo inet loopback

	auto ath0
	iface ath0 inet static
	        address 192.168.2.50
	        network 192.168.2.0
	        netmask 255.255.255.0
	        broadcast 192.168.2.255
	        post-down wlanconfig ath0 destroy
	        pre-up wlanconfig ath0 create wlandev wifi0 wlanmode ap
	        pre-up iwconfig ath0 essid "alrac-net" channel 01 rate auto
	        pre-up ifconfig ath0 up
	        pre-up sleep 3
	        up hostapd -B /etc/hostapd.conf
	        post-down killall hostapd

	auto eth0
	iface eth0 inet static
	       address 192.168.1.50
	       network 192.168.1.0
	       netmask 255.255.255.0
	       broadcast 192.168.1.255

	auto eth1
	iface eth1 inet static
	    address 12.169.163.241
	    gateway 12.169.163.1
	    netmask 255.255.255.0

	##/etc/dnsmasq.conf
	domain-needed
	bogus-priv
	local=/alrac.net/
	expand-hosts
	domain=alrac.net
	listen-address=127.0.0.1
	listen-address=192.168.1.50
	listen-address=192.168.2.50
	server=12.169.174.2
	server=12.169.174.3

	dhcp-range=lan,192.168.1.100,192.168.1.200,255.255.255.0,12h
	dhcp-range=wifi,192.168.2.100,192.168.2.200,255.255.255.0,12h
	dhcp-lease-max=100

	#default gateway
	dhcp-option=lan,3,192.168.1.50
	dhcp-option=wifi,3,192.168.2.50

	#DNS server
	dhcp-option=lan,6,192.168.1.50
	dhcp-option=wifi,6,192.168.2.50

	#assign static IP addresses
	dhcp-host=stinkpad,192.168.2.74,net:wifi
	dhcp-host=penguina,192.168.2.75,net:wifi
	dhcp-host=uberpc,192.168.1.76,net:lan
	dhcp-host=xena,192.168.1.10,net:lan

You'll need to add a batch of iptables rules to your firewall script. See the Discussion for a complete example iptables firewall script.

This iptables example forwards all traffic freely between your two LAN segments, and makes name services available to all. This is a liberal configuration with no restrictions.

Remember that broadcast traffic does not cross routes, and some network protocols are nonroutable, such as Samba and other NetBIOS traffic. All routable traffic, such as SSH, ping, mail and web servers, and so forth will travel between your subnets with no problems.

By routing between your wired and wireless network segments, your options are legion: limit the services available to either network segment, filter on individual hosts, do some fine-grained traffic shaping—anything you want to do is possible.

dnsmasq.conf uses RFC 2132 numbers to represent servers, so refer to it for a complete list. Some common servers are:

Because our LAN routes pass through an iptables firewall with a default DROP policy, permitted traffic must be explicitly accepted and forwarded.

If you followed Chapter 3 to build your iptables firewall, don't forget you can use /etc/init.d/firewall/stop|start|restart when you're testing new rules.

Here is a complete example /usr/local/bin/fw-nat that gives the wired and wireless subnets nearly unlimited access to each other:

	#!/bin/sh
	#iptables firewall script for sharing a cable or DSL Internet
	#connection, with no public services

	#define variables
	ipt="/sbin/iptables"
	mod="/sbin/modprobe"
	LAN_IFACE="eth0"
	WAN_IFACE="eth1"
	WIFI_IFACE="ath0"

	#load kernel modules
	$mod ip_tables
	$mod iptable_filter
	$mod iptable_nat
	$mod ip_conntrack
	$mod ipt_LOG
	$mod ipt_limit
	$mod ipt_state
	$mod iptable_mangle
	$mod ipt_MASQUERADE
	$mod ip_nat_ftp
	$mod ip_nat_irc
	$mod ip_conntrack_ftp
	$mod ip_conntrack_irc

	# Flush all active rules and delete all custom chains
	$ipt -F
	$ipt -t nat -F
	$ipt -t mangle -F
	$ipt -X
	$ipt -t nat -X
	$ipt -t mangle -X

	#Set default policies
	$ipt -P INPUT DROP
	$ipt -P FORWARD DROP
	$ipt -P OUTPUT ACCEPT
	$ipt -t nat -P OUTPUT ACCEPT
	$ipt -t nat -P PREROUTING ACCEPT
	$ipt -t nat -P POSTROUTING ACCEPT
	$ipt -t mangle -P PREROUTING ACCEPT
	$ipt -t mangle -P POSTROUTING ACCEPT
	#this line is necessary for the loopback interface
	#and internal socket-based services to work correctly
	$ipt -A INPUT -i lo -j ACCEPT

	#Allow incoming SSH from the wired LAN only to the gateway box
	$ipt -A INPUT -p tcp -i $LAN_IFACE -s 192.168.1.0/24 --dport 22 \
	-m state --state NEW -j ACCEPT

	#Enable IP masquerading
	$ipt -t nat -A POSTROUTING -o $WAN_IFACE -j SNAT --to-source 12.34.56.789

	#Enable unrestricted outgoing traffic, incoming
	#is restricted to locally-initiated sessions only
	#unrestricted between WIFI and LAN
	$ipt -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
	$ipt -A FORWARD -i $WAN_IFACE -o $LAN_IFACE -m state --state \
	ESTABLISHED,RELATED -j ACCEPT
	$ipt -A FORWARD -i $LAN_IFACE -o $WAN_IFACE -m state --state \
	NEW,ESTABLISHED,RELATED -j ACCEPT
	#$ipt -A FORWARD -i $LAN_IFACE -o $WIFI_IFACE -m state --state \
	NEW,ESTABLISHED,RELATED -j ACCEPT
	#$ipt -A FORWARD -i $WIFI_IFACE -o $LAN_IFACE -m state --state \
	NEW,ESTABLISHED,RELATED -j ACCEPT
	#$ipt -A FORWARD -i $WIFI_IFACE -o $WAN_IFACE -m state --state \
	NEW,ESTABLISHED,RELATED -j ACCEPT
	#$ipt -A FORWARD -i $WAN_IFACE -o $WIFI_IFACE -m state --state \
	ESTABLISHED,RELATED -j ACCEPT

	#Enable internal DHCP and DNS
	$ipt -A INPUT -p udp -i $LAN_IFACE -s 192.168.1.0/24 --dport 53 -j ACCEPT
	$ipt -A INPUT -p tcp -i $LAN_IFACE -s 192.168.1.0/24 --dport 53 -j ACCEPT
	$ipt -A INPUT -p udp -i $LAN_IFACE --dport 67 -j ACCEPT
	$ipt -A INPUT -p udp -i $WIFI_IFACE -s 192.168.2.0/24 --dport 53 -j ACCEPT
	$ipt -A INPUT -p tcp -i $WIFI_IFACE -s 192.168.2.0/24 --dport 53 -j ACCEPT
	$ipt -A INPUT -p udp -i $WIFI_IFACE --dport 67 -j ACCEPT

	#allow LAN to access router HTTP server
	$ipt -A INPUT -p tcp -i $LAN_IFACE --dport 443 -j ACCEPT
	$ipt -A INPUT -p tcp -i $WIFI_IFACE --dport 443 -j ACCEPT

	# Accept ICMP echo-request and time-exceeded
	$ipt -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
	$ipt -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
	$ipt -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT

	#Reject connection attempts not initiated from inside the LAN
	$ipt -A INPUT -p tcp --syn -j DROP

	echo "The firewall has now started up and is faithfully protecting your system"
  • Chapter 3

  • man 5 dhclient

  • dnsmasq.conf is a great help resource

  • dnsmasq home page (http://www.thekelleys.org.uk/dnsmasq/doc.html) is where you'll find mailing list archives and excellent help documents

  • Chapter 24, "Managing Name Resolution," in Linux Cookbook, by Carla Schroder (O'Reilly)