Using multiple ADSL IPs with Linux and iptables
Please note: This document assumes more than basic networking knowledge, although not too much more. If you don't understand some of the terms or concepts used, please make a good effort to find out yourself before emailing with questions, or be prepared for a beating.
When we moved to a sensible ISP for ADSL, we were offered the chance to have multiple real IP addresses. This is handy, since it gives us chance to have machines other than our internet gateway directly addressable from outside. Normally, using linux and iptables to do the address routing, you'd end up with 4 usable internal IP addresses from a block of 8.
Lets assume you normally use 192.168.0.0/24 internally, with the router assigned the IP address 192.168.0.1 internally, masquerading all outgoing traffic. We keep this working as normal, and assign the the external addresses to hosts in addition to the internal ones.
Lets also assume you've been allocated the address range 184.108.40.206/29 by your ISP - this gives you the addresses 220.127.116.11 to 18.104.22.168, which would normally be used like this:
- 22.214.171.124 - Network base address, not usable by a computer
- 126.96.36.199 - Router external address
- 188.8.131.52 - Router internal address
- 184.108.40.206 - host1
- 220.127.116.11 - host2
- 18.104.22.168 - host3
- 22.214.171.124 - host4
- 126.96.36.199 - Broadcast address - not usable by a computer
This becomes a problem when you have 5 internal hosts that you want to assign external IP addresses, not including the machine acting as router. Fortunately, there's a nice convenient way around this.
ARP proxying is a convenient way of bridging 2 networks together - where you have 2 sides of a network (such as the internal public part of your network, and the external gateway), and you want packets to be transferred between them. Effectively, this means we can give the same IP to both sides of the router, freeing up another IP (.18 in this case) for internal use. It's also trivially easy to apply normal firewall rules with iptables using ARP proxying, which means the internal network is still protected by a firewall.
Firstly, and for the sake of sanity, you'll want a firewall. This is also a fairly convenient place to put the ARP proxying config. You can get a tidied up version of my current firewall script here. It's the same as we're currently using, only with the accounting stuff removed, and IP addresses changed to protect the innocent.
Secondly, you'll need iproute2 - under debian this is apt-get'able as 'iproute'. You'll also need appropriate kernel support.
To use this script, change the internal and external network ranges to whatever you're using (the script currently assumes 192.168.0.0/24 internally and 188.8.131.52/29 externally), and edit the section where allowed ports through to public addresses are defined.
Under debian, the best way to run this script is to have it called when the eth0 (or whatever your internal interface is called) device is brought up. Once you've edited the rc.firewall, save it as /etc/rc.firewall. Edit /etc/network/interfaces and add the following to the end of the eth0 section:
up /bin/sh /etc/rc.firewall
The edited section should look something like this:
auto eth0 iface eth0 inet static address 192.168.0.1 netmask 255.255.255.0 network 192.168.0.0 broadcast 192.168.0.255 up /bin/sh /etc/rc.firewall
I'm not sure of the best way to do this under other distros, but their online documentation, or google should be able to help you out.
Restart the ADSL and eth0 interfaces, and all should be well and good. Your public internal hosts can use 184.108.40.206 as their default gateway, once their external IP addresses have been assigned, and private internal hosts can continue to use 192.168.0.1.
If you already have a working firewall in place that you don't want to change much, the important bits for ARP proxying are:
echo 1 >/proc/sys/net/ipv4/conf/eth0/proxy_arp /bin/ip addr add 220.127.116.11/29 dev eth0
Obviously, the firewall rules you'll want to apply to this range should be added to your existing firewall script.
Comments, questions, and corrections to email@example.com.