[ Table of Contents ] [ Front Page ] [ Prev ] [ Linux Gazette FAQ ] [ Next ]

"Linux Gazette...making Linux just a little more fun!"


Private Networks and Roadrunner using IP Masquerading

By Mark Nielsen and Andrew Byrd


Abstract

This article is intended to assist in setting up a masqueraded private TCP/IP network connected to the internet via Time Warner's Roadrunner cable modem service. It is a rewrite of a previous article on the same subject -- with Redhat 6 available and Roadrunner's migration to DHCP (at least in Columbus, Ohio, check to see if they use DHCP in your city) several things have changed. This is a serious exercise in networking, involving concepts from DNS to firewalls. When you complete this project, you will truly have some experience in small-scale networking.

One thing to note, I called up RR, and they were very vague about whether they allow people to use IP Masquerading. The sales rep basically said that if you hog bandwidth, they will get upset. If you run servers that hog bandwidth, they will get upset.

There are two "I"'s in this document. Sometimes it is Andrew talking, and sometimes it is Mark.


Table of Contents

  1. Required Reading
  2. The Big Picture
  3. Selecting Hardware
  4. Setting up the Gateway
  5. Configuring IPChains / Masquerading
  6. Configuring DNS on the Private Network
  7. Setting up the Workstation Machines
  8. Security Concerns
  9. Dynamic DNS
  10. Comments and Other Notes
  11. Example Files

Required Reading

These HOWTOs contain the necessary background information required to understand the rest of this document. If you proceed without having read these, you may not fully grasp what is being done.
  1. Networking - Basic Ethernet and TCP/IP information. Sections 5 and 6 are most relevant.
  2. IPCHAINS - IP Firewall Chains will do most of the work in our configuration. Also has many security implications.
  3. DNS - setting up DNS will be a lot easier if you understand how it works.
  4. IP Masquerading - covered in a more general sense than we will here.
  5. Our Previous article on this topic.
  6. RRLinux Help Site
  7. Unix Security located on Yahoo.
  8. The Central Ohio Linux User Group -- where lots of ideas come from.

The Big Picture

This diagram demonstrates the basic idea:


Each heavy black dot in this diagram is an ethernet interface card, and each connecting line is a length of CAT5 cable, with the exception of the one running down from the cable modem, which is your cable connection to Time Warner. Note that you need one interface card in each workstation, and two in your gateway machine.

Your workstations and hub are inside your private network, indicated by a white background in the image, and the rest of the world is shown as the gray area. Note that the gateway machine is riding the fence between the two. Each of the Ethernet cards has an IP address assigned to it, and your gateway has one in the outside world and one on the inside. Positioned as such, the gateway has the power to forward communications from your private network to the outside world.

For the purpose of this discussion, I have assigned the internal network the 10.x.x.x (netmask 255.0.0.0) block of reserved private IP addresses and chosen the domain name "local". These can of course be changed if you know what you are doing, but they should work for most people.

The workstations are named "w1.local" (10.0.0.10) through "w3.local" (10.0.0.30) and the masquerading gateway is called "main.local" (10.0.0.1 on its private adaptor.) As before, you can modify or expand this scheme if you feel comfortable with it.

Selecting Hardware

The gateway machine requires relatively few resources, and can even be an old '486 machine with relatively little memory; routing packets is not particularly strenuous work. If it can run Linux at all, it should do the trick.

The workstations can be any machine running a TCP/IP capable OS, such as Linux, MacOS, or even MS operating systems, and you will need to outfit each machine with an ethernet card.

Choose a 10/100 autosensing hub. It makes your life a lot easier. Use 100 mbit ethernet cards on the inside, and the ethernet card connecting your gateway computer to the outside can be just a 10 mbit ethernet card. I will still use all the same type of ethernet cards and make them all 10/100. Using the same hardware across the board makes your life easier most of the time.

It is a good idea to stick with PCI ethernet cards in linux systems. Ethernet cards are quite cheap now, and having PCI cards will save you some possible headaches in the configuration phase. I have used the Netgear FA310TX card flawlessly in several machines, and have been told that Intel cards provide extremely reliable service. In any case, do some web research and make sure that there are commonly available modules for the cards you buy. The Netgear card and most 3com cards (which I have used extensively) have drivers that ship with Redhat 6. If you must use ISA cards, 3com 3c509s are quite easy to use. Keep in mind that if you are using an older machine for your gateway, it may have only ISA slots, possibly requiring you to use two ISA ethernet cards. In this case, you will have to acquire a utility program (which usually runs only in DOS) for your cards from their manufacturer, and use this program to set the IO address and/or IRQ of the cards to prevent conflicts.

Setting up the Gateway

The computer which will be your gateway will be the computer which RR is connected to.

First, physically install your carefully selected Ethernet cards in the machine. It is much less confusing to use two different brand cards on the gateway; by having a unique driver for each card you can be sure which one will be called eth0 and which will be eth1, and also lessen the chances of interrupt conflicts (to be avoided like the plague). If you opt for ISA cards, you may need to download some DOS utilities to set the IRQ and I/O addresses.

Start with a clean install of the Redhat 6 (for the purpose of this article) distribution on the gateway. If you've got the hard drive space, go ahead and install everything, but you really don't need an X server, graphics processing software, etc. on this machine. Just make sure that you are installing the ipchains, BIND, cacheing nameserver, pump, and other packages critical to what we are doing here. Also tell the install program to start named at boot.

For the purpose of this article, eth0 will be going to the cable modem and eth1 will be on your private network. You can probably get the first ethernet device up and running during the initial install. Have eth0 connected to the cable modem with the necessary crossover cable and tell it to use DHCP to get its IP address (don't specify one) since the Roadrunner service will be assigning us an internet IP. Use the netconf utility (or edit the /etc/sysconfig/network-scripts/ifcfg-eth? and /etc/conf.modules files directly) to get eth1 working once you can boot, and assign this one a private network IP address (10.0.0.1). It may take a bit of tinkering to get both cards detected and up. Be sure to specify the correct kernel modules/drivers, and once you can do an 'ifconfig' and see both eth0 and eth1 (or see them both go up at boot time), you should be ready to continue. It is possible to compile network card drivers into the kernel (this was often done in the past) but it is common and perfectly acceptable to simply use modular drivers as we've suggested here.

Ensure that your /etc/sysconfig/network looks like this and replace /etc/hosts with your own version of this file. The /etc/hosts file isn't absolutely necessary since we'll be setting up a DNS server, but it's a good backup.

NOTE ON TWO 3c509 NETWORK CARDS:
Install both ISA ethernet cards before you install RedHat Linux. The two ethernet cards Mark used (a long time ago) were 3com 3c509. The first had values of, irq=10, address=300 and the second had irq=11, address=310. Also, when you install RedHat, go ahead and install it for a LAN and have it autoprobe the ethernet cards.

NOTE ON DHCP:
You can setup DHCP using RedHat's control panel, netconf, editing the files manually, or during the installation of RedHat (or whatever other Linux distribution you are using).

Configuring IPChains / Masquerading

Try pinging a few outside servers or retrieving a few web pages with lynx to see if your Roadrunner connection is functioning. If so, you are ready to add masquerading. Append this block of modprobe and ipchains commands to your /etc/rc.d/rc.local script to enable forwarding/masquerading and also provide some fairly strong firewall rules.

Configuring DNS on the Private Network

As of now, 'pump' (which retrieves the DHCP information for eth0) is also setting the /etc/resolv.conf file to use Roadrunner's DNS servers. This provides no functionality for looking up hostnames in our private network and would require that each workstation have an identical copy of /etc/hosts and be manually set to use a Roadrunner nameserver. This is a little messy, so it's advisable to run your own DNS service.

Armed with some knowledge from the DNS-HOWTO, create or modify /etc/named.conf, /etc/resolv.conf, and the related files in /var/named. You must also create or edit /etc/pump.conf to keep pump from overwriting your resolv.conf settings every time eth0 goes up. Verify that 'named' is being run at bootup (there will be an S??named link in /etc/rc.d/rc3.d/ if it is) and you should have a cacheing nameserver running upon reboot, as well as DNS for your private network.

Setting up the Workstation Machines

Make sure all of your private network machines (including the gateway) are connected via a hub and Cat5 cable, and then configure the workstations. Give each machine/interface a unique IP address within the private block, and here is an example /etc/sysconfig/network for the Linux workstations. Add a customized /etc/hosts and this /etc/resolv.conf file, and you should be on your way. Try some pings or read some web documents from a workstaion to ensure that masquerading and DNS are operating correctly.

Here is an example for other computers in your network.

  1. ip address = 10.0.0.10
  2. name address = w1.local
  3. netmask = 255.255.255.0
  4. /etc/resolv.conf for your other Linux computers.
  5. /etc/hosts is a file I would use, but don't need. Just in case your dns server fails, this is handy for a backup.
The only thing you should have to change to each additional computer is the ip address and the name address. w2.local and 10.0.0.20 would be used for the next computer. Get the idea?

Also, if you are using pc or mac clients or other stuff, check out the masquerading mini-howto.

The general idea is to specify your masquerading machine (10.0.0.1) as the gateway and DNS server for each machine. The IP-Masquerading HOWTO has an excellent section on how to configure workstations running several different non-Linux operating systems in a masq'd private network.

Security Concerns

Being connected to the internet constantly has its risks. There are plenty of people out there who have nothing better to do than wreck unprotected systems, and many more who would like to use your system as a jumping-off point for illegal activities.

Masquerading is inherently somewhat unsafe because we must allow traffic to pass through the firewall. By disabling telnet, ftp, or other daemons that listen at ports on your gateway you can avert much of the danger, and fully understanding IP firewall chains is also valuable. A port forwarder such as ipportfw can also be used to redirect incoming requests for connections to other machines on your network (which would then be running the requested service), directing the danger away from your gateway.

You can prevent access to your DNS server by moving it to another machine on your network or by simply giving an appropriate listen-on directive to named (see the named.conf man page) to keep it from binding to a port on your external interface. If you would like higher security but need login capabilities from the outside, look into openssh, which allows telnet-like logins over an encrypted connection. It is also advisable to install an advanced logger such as tcplogd which can detect and inform you of most portscans and malicious activity.

Lastly, in many cases you can simply turn off the interface to the outside world when not using your connection, thereby lessening the chances of someone gaining unauthorized access. Simply issue 'ifdown eth0' on your gateway machine to disable your connection and 'ifup eth0' when you need to use it again.

Summary of Security

  1. The only service on your firewall computer should openssh. Ideally, you shouldn't have your DNS on your gateway computer. Although our server configuration has DNS on it, again, ideally, you should put the DNS service on another internal computer. If you must, keep it firewalled at least so that the outside can't use it.
  2. All other services (like a webserver) that you want available to the outside should be port forwarded using ipportfw to another computer on the inside of your network.
  3. Do NOT NOT NOT NOT have any services under /etc/inetd.conf turned on, or just don't have inet running.
    chkconfig inet off ### for RedHat users
    /etc/rc.d/init.d/inet stop
  4. Have all other internal services on a separate computer (printing, filesharing, database, etc).
  5. Install tcplogd and post the people who have scanned your computer -- hey, it is public information isn't it?
  6. There are ways to tunnel VNC, mail, ftp, and other programs through OpenSSH. This can keep things secure.
  7. Check out Abacus Project - The Intrusion Prevention System

Dynamic DNS

Unless you asked for a fixed IP address, RoadRunner gives you a different ip address every time you log in. Dynamic DNS gives you an alias so that you can find your computer at home when you are at work or let other people know where it is.

Dyndns.org can provide for you a static domain name despite your dynamic IP address, giving others on the internet an easy to remember and constant name for your gateway machine. Once you have registered with dyndns, a utility called 'ddup' can contact dyndns.org and update your nameserver record when your IP address changes. Appending this shell script fragment to our /etc/rc.d/rc.local will update your dyndns record at boot time, but only if your IP address has changed (dyndns doesn't like you to update your record for no reason.) This assumes that you have 'ddup' installed properly.

I tend to reboot the gateway machine every day or two and haven't had any problems with my assigned IP changing while it was up, though this is technically possible. If you plan on leaving your gateway up for weeks at a time, you might want to have cron run this script occasionally to make sure your dyndns record is always current. This will take a little reworking -- experiment and see what you can do.


Comments and Other Notes

  1. For even more security, you may want to buy a network switch where you can isolate traffic on the inside on your network. They are expensive, but worth it for the serious networker.
  2. There are more advanced things you can do once you get your internal network setup. You can have fetchmail download all email from a domain and match up email addresses to your local users, use a proxy server to save bandwith (which may not be necessary, set VPN set tunneling of services through openssh, etc.
Mark Nielsen works as a book binder for ZING and TCU and Andrew is a Linux consultant.

Example Files

(these are just syntactic examples, you will probably have to modify domain names, etc. for your own use)

/etc/rc.d/rc.local (gateway)

# Firewall config - Should be appended to the end of /etc/rc.d/rc.local to run on boot.
# Adapted from examples in the IP Masquerading HOWTO and IPChains HOTWO. See the original
# documents to learn more. These examples should provide a fairly safe masquerading
# firewall.

echo "Loading IP masquerading modules..."
# load modules to handle masquerading some tricky but common protocols
/sbin/depmod -a
/sbin/modprobe ip_masq_ftp
/sbin/modprobe ip_masq_raudio
/sbin/modprobe ip_masq_irc

echo "Turning IP forwarding on..."
# make sure the forwarding is turned on
echo "1" > /proc/sys/net/ipv4/ip_forward

# Get the dynamic IP address assigned via DHCP
# and external interface name, save them to variables for easy use
extip="`/sbin/ifconfig eth0 | grep 'inet addr' | awk '{print $2}' | sed -e 's/.*://'`"
extint="eth0"

# Do the same for internal network name and interface
intint="eth1"
intnet="10.0.0.0/8"

echo "Configuring firewall chains:"
echo -n "input..."
#############################################################################
# Input chain: flush and set default policy of reject. Actually the default policy
# is irrelevant because there is a catch all rule with deny and log.

ipchains -F input
ipchains -P input REJECT

# local interface, local machines, going anywhere is valid
ipchains -A input -i $intint -s $intnet -d 0.0.0.0/0 -j ACCEPT

# remote interface, claiming to be local machines, IP spoofing, get lost
ipchains -A input -i $extint -s $intnet -d 0.0.0.0/0 -l -j REJECT

# remote interface, bounce anything trying to open a connection to us
# this should keep anyone from opening TCP connections to this machine from
# the outside world. Just an example of what we can do with IPChains, and not
# a bad idea unless you have a reason for letting people connect to your firewall.
# ipchains -A input ! -f -i $extint -p TCP -y -j REJECT

# remote interface, any source, going to roadrunner dhcp address is ok
ipchains -A input -i $extint -s 0.0.0.0/0 -d $extip/32 -j ACCEPT

# loopback interface is valid.
ipchains -A input -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT

# catch all rule, all other incoming is denied and logged.
ipchains -A input -s 0.0.0.0/0 -d 0.0.0.0/0 -l -j REJECT

echo -n "output..."
#############################################################################
# Output chain: flush and set default policy of reject. Actually the default policy
# is irrelevant because there is a catch all rule with deny and log.

ipchains -F output
ipchains -P output REJECT

# local interface, any source going to local net is valid
ipchains -A output -i $intint -s 0.0.0.0/0 -d $intnet -j ACCEPT

# outgoing to local net on remote interface, stuffed routing, deny
ipchains -A output -i $extint -s 0.0.0.0/0 -d $intnet -l -j REJECT

# outgoing from local net on remote interface, stuffed masquerading, deny
ipchains -A output -i $extint -s $intnet -d 0.0.0.0/0 -l -j REJECT

# anything else outgoing on remote interface is valid
ipchains -A output -i $extint -s $extip/32 -d 0.0.0.0/0 -j ACCEPT

# loopback interface is valid.
ipchains -A output -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT

# catch all rule, all other outgoing is denied and logged.
ipchains -A output -s 0.0.0.0/0 -d 0.0.0.0/0 -l -j REJECT

echo -n "forward..."
#############################################################################
# Forward chain: flush and set default policy of deny. Actually the default policy
# is irrelevant because there is a catch all rule with deny and log.
#
ipchains -F forward
ipchains -P forward DENY

# Masquerade from local net on local interface to anywhere.
# This is the line that does all the work, most of the rest if the lines
# in this file are just for security reasons.
ipchains -A forward -i $extint -s $intnet -d 0.0.0.0/0 -j MASQ

# catch all rule, all other forwarding is denied and logged. pity there is no
# log option on the policy but this does the job instead.
ipchains -A forward -s 0.0.0.0/0 -d 0.0.0.0/0 -l -j REJECT

echo "done."


/etc/sysconfig/network (gateway)

NETWORKING="yes"
FORWARD_IPV4="yes"
HOSTNAME="main.local"
DOMAINNAME="local"
GATEWAY="10.0.0.1"
GATEWAYDEV="eth0"


/etc/sysconfig/network (workstations)

NETWORKING="yes"
FORWARD_IPV4="no"
# change hostname on each machine
HOSTNAME="w1.local"
DOMAINNAME="local"
GATEWAY="10.0.0.1"
GATEWAYDEV="eth0"


/etc/hosts (gateway and workstations)

127.0.0.1	localhost	localhost.localdomain
10.0.0.1	main		main.local
10.0.0.10	w1		w1.local
10.0.0.20	w2		w2.local
10.0.0.30	w3		w3.local


/etc/resolv.conf (gateway and workstations)

search local columbus.rr.com
nameserver 10.0.0.1		#our local nameserver
nameserver 128.146.1.7		#fill in a backup server. do not use this one, it is for OSU students only.


/etc/pump.conf (on gateway only)

device  eth0 {  
	nodns 
	}


/etc/named.conf (on gateway only)

options {
	directory "/var/named";
};
zone "." {
	type hint;
	file "named.ca";
};
zone "local"{
	type master;
	file "local.zone";
	notify no;
};
zone "0.0.10.in-addr.arpa"{
	type master;
	file "local.reverse";
	notify no;
};
zone "0.0.127.in-addr.arpa"{
	type master;
	file "named.local";
};


/var/named/local.zone (on gateway only)

@		IN	SOA	main.local.	root.main.local. (
				200001151 ; serial
				8 ; refresh
				2 ; retry
				1 ; expire
				1 ; default_ttl
				)
@		IN	NS	main.local.
localhost	IN	A	127.0.0.1
main		IN	A	10.0.0.1
w1		IN	A	10.0.0.10
w2		IN	A	10.0.0.20
w3		IN	A	10.0.0.30


/var/named/local.reverse (on gateway only)

0.0.10.in-addr.arpa.  	IN 	SOA 	main.local. root.main.local. (
					1997022700 ; serial
					28800 ; refresh
					14400 ; retry
					3600000 ; expire
					86400 ; default_ttl
					)
1.0.0.10.in-addr.arpa.	IN	PTR	main.local.
10.0.0.10.in-addr.arpa.	IN	PTR	w1.local.
20.0.0.10.in-addr.arpa.	IN	PTR	w2.local.	
30.0.0.10.in-addr.apra.	IN	PTR	w3.local.


append to /etc/rc.d/rc.local (dyndns support with ddup)

# Update dyndns.org entry with crafty abuse prevention
# This will not work unless you have a dyndns account and the ddup package installed.
# This requires some variables that are set in the firewall config script,
# so this should be appended to the end of the firewall script.

# replace dummy.hostname with your registered hostname
reghost="dummy.hostname" 
regip="`nslookup $reghost main.dyndns.org | tail -n 3 | grep 'ddress' | awk '{print $2}'`"

echo -e "\n Dyndns.org abuse prevention IP address check:"
echo "$reghost registered: $regip"
echo -e "$extint has IP address: $extip \n"

if [ "$regip" = "$extip" ]; then
	echo "Address has not changed. DDUP not run."; 
	else
	echo "Address has changed. Updating your record.";
	ddup --host $reghost;
fi


/etc/conf.modules (gateway; only 'alias ethx' lines are relevant)

alias eth0 3c509
alias parport_lowlevel parport_pc
pre-install pcmcia_core /etc/rc.d/init.d/pcmcia start
alias eth1 tulip


Copyright © 2000, Mark Nielsen, Andrew oyd
Published in Issue 51 of Linux Gazette, March 2000

Talkbacks

[ Table of Contents ] [ Front Page ] [ Prev ] [ Linux Gazette FAQ ] [ Next ]