Having just such a setup at home, I think I know how to do this.
Your linux router will have two physical interfaces. I'll call them
eth0(connected to your inside network and with a static IP address) and
eth1(connected to your ISP, and presumably an address provided via DHCP).
Turning on packet forwarding
/etc/sysctl.conf, there may be two lines matching the following:
# Controls IP packet forwarding
net.ipv4.ip_forward = 0
If not, you will need to add at least the last line. Here's an important piece: change the 0 to a 1. That tells the kernel, down deep, to send packets from one interface to another if the routing tables on the linux router tell it that it's the next step. You will then need to either reboot, or run the following command:
echo 1 > /proc/sys/net/ipv4/ip_forward.
Setting up NAT
Right now, everything going out either eth0 or eth1 is going out with the same IP address that it comes in with. So Google will get pings from 192.168.1.x(or whatever your IP scheme is). Trouble with that is, those IP addresses can't be routed across the public internet. So you will have to tell your Linux router to modify outgoing packets so that they can be routed back to you. I have done so with the following rule:
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
This tells the system that, after it's done all the routing(because it's in the POSTROUTING iptables chain), and if the outgoing interface is eth1("-o eth1"), then apply target MASQUERADE. This means "change the source IP address to be the IP address for the interface.
Setting up DHCP
At this point, your system is doing the basics. You will, however, have to set up each connected system to have a static IP & point to external DNS servers. This can be changed with a package called
dhcp. Install it, and set it to boot at start time. On my Red Hat-based system, this can be done with two commands:
yum install dhcp and
chkconfig dhcpd on. However, it won't do anything because you haven't configured DHCP as to what your IP scheme is and what interfaces it should listen on.(although I could be wrong). Below is what your
/etc/dhcpd.conf could look like:
# DHCP Server Configuration file.
# see /usr/share/doc/dhcp*/dhcpd.conf.sample
subnet 192.168.1.0 netmask 255.255.255.0
range 192.168.1.10 192.168.1.100;
option routers 192.168.1.1;
option domain-name-servers 192.168.1.1;
max-lease-time 14400; #4 hours
default-lease-time 14400; #4 hours
A few key points here:
- Subnet line: This must be the network address for eth0. The netmask must also match.
- Range line: This is where you set the start and end addresses for your internal network. I would strongly recommend making this exclude the address for the linux router itself.
- Option routers line: This is where you tell clients what their default gateway will be. In the case you've described, this will be the IP address of the linux router's eth0.
- Option domain-name-servers line: This is where you tell clients what their DNS servers will be. You can make it
option domain-name-servers 18.104.22.168 22.214.171.124 if you want to use OpenDNS,
option domain-name-servers 126.96.36.199 188.8.131.52 if you want to use Google Public DNS, or
option domain-name-servers 192.168.1.1 if you want to set up your system to handle it all.
You can now start it by doing(on a Red-Hat based system),
service dhcpd start as root. If you're not using Red Hat or a derivitave, then you will need to run the startup script for that system.
The lease time is defined in seconds. At least according to the documentation I've been able to find, sometimes clients will ask for a specific lease duration, in which case the max-lease-time and min-lease-time statements are checked and adjusted to fit within those boundaries. Other times, clients won't ask for a lease duration, in which case the default-lease-time is used.
This is safe in terms of not serving other clients of your ISP with your internal network DHCP because DHCPD will not serve an address if it does not know about the IP scheme of the interface it came in on. So if a dhcp request comes in on eth1, which has an IP of 184.108.40.206, the DHCP setup doesn't have a subnet block for that IP. So it won't send out any DHCP offers for that request. But if it comes in on eth0, which has an IP of 192.168.1.1, it does have a subnet block that matches that address, and it does offer DHCP.
Setting up DNS
This one might be the simplest of all. On my RHEL 5.1 system, it was install, start, and point clients at it. Out of the box, it's configured to point at the root name servers and serve clients on any interface that is active at DNS startup.
To install, keep in mind that it's not dnsd, it's named. It's not the past tense of naming. Instead, read it as "name-D".
yum install named #installation
service named start #start it for right now
chkconfig named on #set it to start at system boot.