Connecting LAN Users to the Internet
Using Linux and IP Masquerade
Charles C. Bundy
Connecting the users on your office/home LAN and to the Internet
need not be an expensive proposition. You can manage it without IP address
registration or Domain Name Service fees - all you need is a standard PPP
account from an Internet Service Provider (ISP). At our site at the Virginia
Department of Transporation (VDOT), we pay $85 a month for unlimited PPP
access and 10 email accounts. The services provided on user computers are
POP email, WWW browsing, and telnet. The number of client connections
is limited only by the bandwidth provided by your modem. This article describes
the VDOT system and provides tools for monitoring and managing the system.
A key component of the setup is a gateway machine running Linux
v1.2.13 with a patched kernel that allows IP masquerade. IP masquerade
is a way of aliasing IP addresses from one subnet range to a single IP
address (the one that is assigned when you connect via PPP to the Internet).
This aliasing is necessary because the routing information on the Internet
side of the link leads back only to the ISP, and thus to the PPP interface
on Linux, rather than to your LAN. The Linux gateway exchanges the PPP
interface IP to your client's IP address and ships the packet out to the
Ethernet interface. Figure 1 shows an idealized layout of the LAN <->
Internet connection for my site.
Note that IPC ports play a major role in IP masquerade. The LAN
IP uses the port assigned by the IP masquerade to replace the return source
IP address of incoming packets on the Internet PPP interface. Thus IP masquerade
works only with "ported" applications, such as httpd, telnetd,
popd, etc. ftpd works in kernel rev 1.3.39 or greater.
Fetching and Installing Linux
Linux is a POSIX-compliant Free UNIX for Intel x86, Alpha,
and 68K processors. To get the version you'll need here, your best bet
is to invest $50 in a slackware 3.0 book/CD. Make certain that it contains
kernel v1.2.13, which includes the ip_masq patch. If your Linux distribution contains kernel
revision 2.0 or greater, ip_masq and ftpPASV mode are included in the kernel
source. If you cannot find this kernel rev, you'll need to get the ip_masq patch as well.
Your target machine should have at least 8 Mb of RAM. If you decide
to run it solely as a router/gateway, a 386DX is adequate. Instead of installing
an internal modem, use a COM port to make bandwidth upgrades easier (e.g.,
14.4 -> 28.8 -> 64K ISDN -> 128K ISDN, etc.). Be sure the UART is a high-speed/buffered
type (16540 or 16550). At my site, the router/gateway is a 486DX2-66 PC.
Full Linux installation instructions are beyond the scope of this
article (if you need more details, Matt Welsh provides a good tutorial
at http://sunsite.unc.edu). I will simply review the basics and
then concentrate on installation specifics related to building an IP
masquerade kernel.
For simplicity's sake, let's assume your PC has no important data/programs
on its HD, and you are going to sacrifice DOS for Linux. If you don't have
a minimum setup of DOS CD-ROM drivers, you either need to create the setup
or find a machine with an operational CD-ROM drive. Insert the CD-ROM,
then find the program rawrite.exe and copy it to C:\DOS.
Find the Install subdirectory and enter the 3.5" 1.44M
bootdisk subdirectory. If your CD-ROM drive is SCSI, use the "scsi" boot
disk, otherwise pick a boot disk that contains a CD-ROM IDE driver (check
the file which.one). Type rawrite and respond appropriately
to the source file and destination drive questions. Go to the rootdisk
subdirectory, repeat rawrite, and choose color.gz as the
source file. Do not try to decompress this file: as of kernel 1.2.x, kernel
files are compressed. Return to the designated Linux gateway/router and
fire up Linux using the newly created boot/root disks.
Once you've logged in as root (no password), use the Linux fdisk
command to partition your HD. I recommend doing three partitions, the first
mounted as /, the second as swap, and the third as /usr.
Once you've partitioned and set the Linux Partition Type (83 for Linux
Native, 82 for Linux Swap), do the following:
cd /
setup
Now it's just a matter of setting up your target drives (formatting
and doing mkswap), selecting the source drive, and choosing which
disksets to install. The default Linux kernels (IDE and SCSI) that are
installed during setup don't have the correct network configuration for
our purpose. You'll need to patch the kernel source for IP masquerade,
so installation of the kernel source is mandatory. Below are the required
router/gateway disksets. For simplicity's sake, select "ALL" items in each
diskset.
A - base installation
AP - additional program/utilities
D - development
F - FAQ's and HOWTO documents
N - networking
I recommend creating a boot floppy versus installing the Linux Loader
(LILO) boot menu on the HD. If you decide to install LILO, use the MBR
(Master Boot Record) and only add "Linux" as a bootable partition in lilo.conf.
If your initial install went well, type <CTRL><ALT><DEL>.
Watch your boot sequence messages. If you see the following error message,
BIOS32 error, sorry this version still depends on it.
don't be concerned; PCI BUS support is the default in this kernel. Simply
make certain it is turned off when you reconfigure the kernel. In fact,
it is important to avoid unnecessary hardware autoprobing, since such probing
can cause the Ethernet driver (eth0) to fail.
Configuring and Recompiling the Linux Kernel
After logging in as root, enter the following command:
gcc -v
If you don't have gcc version 2.7.x, you need to fetch and create
a development disk set that contains it. Prior versions are buggy, and
some don't fully support kernel compilation of rev 1.2.x or greater. Check
out the following URL for the above mentioned Linux disks and IP masquerade
patch:
http://www.preferred.com/~ccb8m/ISPout
The most up-to-date information on IP masquerade for Linux is available
at:
http://www.indyramp.com in /pub/masq for kernel 1.2.13.
The firewall interface program (ipfw) is precompiled and available
there as well. For the 1.2.13 kernel use the 1.2.n.ip_masquerade
patch file, which I will refer to as masq.p. Make sure you are root
before using the following commands.
cp masq.p to /usr/src
cd /usr/src
patch < masq.p
The next step is kernel configuration. My Linux box is a 486 with a
SCSI CD-ROM/TAPE backup and an IDE hard drive. The Ethernet card is an
Etherlink III board made by 3COM. The 1.2.13 kernel had trouble recognizing
a no-name NE2000 brand Ethernet card and a 3COM 3c509 Etherlink III circa
1992. When I installed a 3c509 circa 1994, the eth0 interface came
up. If you are having problems, read the NET2-HOWTO document to find out
about specifying NIC board configurations at boot time. I highly recommend
the 3COM 3c509 Etherlink III - just make certain it is of recent vintage.
To configure the kernel, type:
cd /usr/src/linux
make config
Listing 6 is the output from my configuration session. You can use it
as a guide for predetermining answers based on your installed hardware.
Here are the TCP/IP specific answers:
Networking support' CONFIG_NET - y
...
'TCP/IP networking' CONFIG_INET - y
'IP forwarding/gatewaying' CONFIG_IP_FORWARD - y
'IP multicasting' CONFIG_IP_MULTICAST - n
'IP firewalling' CONFIG_IP_FIREWALL - y
'IP accounting' CONFIG_IP_ACCT - y
'IP masquerading (ALPHA)' CONFIG_IP_MASQUERADE - y
'PC/TCP compatibility mode' CONFIG_INET_PCTCP - n
'Reverse ARP' CONFIG_INET_RARP y
'Assume subnets are local' CONFIG_INET_SNARL - n
'Disable NAGLE algorithm (normally enabled)'
CONFIG_TCP_NAGLE_OFF - n
'The IPX protocol' CONFIG_IPX - n
...
'Network device support?' CONFIG_NETDEVICES - y
'Dummy net driver support' CONFIG_DUMMY - y
'SLIP (serial line) support' CONFIG_SLIP - y
'CSLIP compressed headers' CONFIG_SLIP_COMPRESSED -y
'16 channels instead of 4' SL_SLIP_LOTS - n
'PPP (point-to-point) support' CONFIG_PPP - y
'PLIP (parallel port) support' CONFIG_PLIP - n
Next, you'll need to compile the kernel. Enter the following:
make dep
make clean
make zImage
cd /usr/src/linux/arch/i386/boot
If you installed LILO, enter the following to install the kernel (my
LILO config file uses vmlinuz as the kernel filename):
cp /vmlinuz /vmlinuz.no_masq
cp zImage /vmlinuz
cd /
/sbin/lilo
If you boot off a floppy, you'll need to do this:
(put a formatted disk in drive A:)
dd if=zImage of=/dev/fd0
Use the rdev and swapdev commands to set the root and
swap partitions in the kernel. Since my hard drive is IDE, I use /dev/hda1
for the root partition. Listed below are example root and swap set commands
(based on my system).
rdev /dev/fd0 /dev/hda1
rdev -R /dev/fd0 1
swapdev /dev/fd0 /dev/hda2
Reboot to make certain the new kernel works before changing system files.
If it doesn't work, use the install boot disk to bring the system up and
see what went wrong.
Using ipfw to configure IP masquerade and Firewall
If you retrieved the precompiled version of ipfw
from my URL or www.indyramp.com, copy it to /sbin. Add the
following lines to /etc/rc.d/rc.local to enable IP masquerade for
all the hosts on your subnet (in the example, I use a class C address of
111.222.33.0 for MY_SUBNET):
MY_SUBNET=111.222.33.0/24
/sbin/ipfw a m all from ${MY_SUBNET} to 0.0.0.0/0
Next, you'll need to modify /etc/rc.d/rc.local to limit forwarding
of LAN traffic to the Internet. In the example below, I let the ISP see
a certain amount of our LAN traffic (TCP/IP). If you prefer, you can limit
this view to the Linux box by running ipfw on the fly when a PPP
address is assigned.
WAN_PORT_IP=200.100.10.0
/sbin/ipfw ad bl deny all iface ${WAN_PORT_IP} from 0/0 to 0/0
/sbin/ipfw ad bl accept all iface ${WAN_PORT_IP} from ${WAN_PORT_IP} \
to 0/0
/sbin/ipfw ad bl accept all iface ${WAN_PORT_IP} from 0/0 to \
${WAN_PORT_IP}
You now have a kernel capable of forwarding IP traffic from a PPP interface
to an Ethernet card. You also have IP masquerade set for client machines
on your LAN. The next step is to make the actual dial/PPP connection. Once
this is working, routing and DNS setup can be tested. Before proceeding,
reboot your machine. This "reboot" test will enable firewalling and IP
masquerade in the kernel.
Setting Up the PPP Link to ISP
If everything went well, your kernel should have PPP support
compiled in, so that you can run the PPP daemon (pppd). You'll also
need a modem of some sort, the faster the better. I decided to use an external
COM port to facilitate speed upgrades. Thus, I hooked a 28.8 modem to COM1.
Outgoing modem configuration is simple, unlike dial-in modems. You can
use it right out of the box with the default user settings (echo on, verbose
status, etc).
With pppd running on your system and the serial port assigned,
the last requirement is to make sure PPP is running on the remote end.
This requires the following:
1. Dial the ISP (terminate gracefully using modem status)
2. Login
3. If PPP isn't automatically started, issue a PPP command to
the terminal server. Our ISP automatically starts up PPP when a user logs in.
To automate the process use chat. chat reads a script
file that contains phone number, login ID, and password information and
automatically negotiates the ISP login. Listed below is a working chat
script with dummy login information. It is safer to put this information
in a script file rather than supplying it on a command line. If your Linux
box supports multiple users, they can type ps -aux.
ABORT BUSY ABORT 'NO CARRIER' '' ATZ OK ATDT123-9876 CONNECT '' login: spam word: RuCrazy
Rather than typing in two different commands (chat and pppd),
you can use the connect argument to pppd to invoke the chat
script. Listed below is a working pppd command line. Note the use
of the lock file option: this is important for modem line monitoring (Listings
1, 2, and 5.) All listings for this article can be found at ftp.mfi.com
in /pub/sysadmin.
/usr/sbin/pppd mru 296 connect "/usr/sbin/chat -vf /usr/lib/ppp/dial-ISP" \
/dev/modem 57600 crtscts modem defaultroute lock
At this point, save the chat script listed above to a file called
dial-ISP in /usr/lib/ppp (you may need to create the subdirectory.)
Replace the phone number, login, and password with your real ISP account
information.
Listing 5 shows a script called check that runs pppd
if the uucp lock file isn't set. Put it in /usr/lib/ppp and make
certain it is called check, is owned by root, and has only user
read and execute permissions set.
Check your current route table, and if the default is set, delete
it:
/sbin/route
/sbin/route del default
Now type:
/usr/lib/ppp/check
Wait a minute, then enter /sbin/route: you should see a new interface,
listed as ppp0. Try pinging an Internet IP, such as preferred.com
at 205.138.52.10 (ping works from the Linux gateway, but it won't
work from the LAN clients that are using IP masquerade). Use telnet
to test IP masquerade. Assuming ping worked, check out the sidebar,
"PPP Monitoring/Connection Options," which discusses options for keeping
the link up, as well as shutting it down.
Setting Up config files for Routing/DNS
In firing up the PPP interface, we deleted the default
route (if set) temporarily. To ensure that LAN users can hit the Internet
after a reboot, comment out the following line in /etc/rc.d/rc.inet1:
/sbin/route add default gw ${GATEWAY} metric 1
This allows pppd to set the default route to your ISP (using
the defaultroute flag.) Thus any foreign traffic gets routed to
the Internet. Our office has another router that connects the LAN to a
corporate WAN. Those PC clients with Internet access will use the Linux
box rather than the WAN router. The Linux box thus had to explicitly set
routes for each WAN subnet through the WAN router. If this route information
isn't set, a PC whose gateway IP gets changed will be unable to access
WAN subnets. Listed below is a sample route redirect to the WAN router
from the Linux box. The route commands are in /etc/rc.d/rc.local:
/sbin/route add -net 111.222.33.0 gw 111.222.33.66
Once the default route is set, Internet addresses can reach their destination.
However, since no nameserver has been set, telneting to an IP address
works, but trying to use a domain name fails. Find out the IP address for
your ISP's DNS and add it to the file /etc/resolv.conf. Listed below
is resolv.conf from my system:
domain brist.vdot.gov
nameserver 205.138.52.10
nameserver 128.143.2.7
Make certain the file /etc/host.conf uses bind, in addition
to host, for name resolution, that is:
order hosts, bind
multi on
At this point, you should be able to type:
ping home.netscape.com
And get a response. Assuming this works, the last step is client configuration.
Again, client installation of TCP/IP and the various Internet client software
packages is beyond the scope of this article, but the following are my
top picks for free/share/licenseware:
TCPIP32 - Great if you are running Windows for WorkGroups
TRUMPET - Good for pre WfWG Windows (3.1 & 3.11)
Netscape - The defacto WWW browser standard. If you can't
afford license fees, use Mosaic
Eudora - Lite version is free and it is a great POP email client
WinQVT - A good shareware package which has a great telnet
VT220 emulation. We would have picked this except that Attachmate software's
KEA! package provides Netscape and excellent mainframe connectivity (IBM
3270)
Go to http://www.winsite.com for these and other Winsock
packages.
Setting Up Windows 95/Windows for Workgroups/Trumpet Winsock
VDOT PC clients typically run Windows with a few Windows
95 test platforms. I won't discuss TCP/IP installation for Windows here
(see References for resources on this subject). Instead the focus is on
configuration of pre-installed TCP/IP protocol stacks.
If you are running Trumpet Winsock, run/maximize tcpman.exe
and choose FILE | SETUP. Using Figure 2 as a model, fill in the
Gateway and DNS sections according to your ISP. Restart tcpman.exe
and try running your Web browser with an Internet URL. Try home.netscape.com
or www.preferred.com.
If you are running WfWG and TCPIP32, select the Network program
group. Run "network setup" and double-click on the TCPIP32 protocol. Referring,
to Figures 3 through 5, fill in the Gateway and DNS sections.
If you use 3C509 cards, you'll need to choose the driver name
carefully. We use an ODI driver called 3C5X9. WfWG insists on modifying
C:\Windows\protocol.ini and renaming 3C5X9 to 3C509.
This change really confuses WfWG when you restart, so manual modification
of protocol.ini following a network setup session is mandatory.
If you are running Windows 95, step through the following buttons/menus/icons:
Start | Settings | Control Panel | Network
Refer to Figures 6 through 9 for various setup sections in the network
program.
Conclusion
Performance of our setup varies based upon the user task
mix along with the speed of the external modem. With a 28.8 modem, six
WWW users typically get 800-850 bytes/sec throughput. This is somewhat
better than might be expected, largely because of the interactive nature
of Web browsing. If all six clients were attempting to grab full bandwidth,
their throughput would ideally be 2800 bps/6 = 466 bps.
We use an MTU of 1500, which is a compromise between file transfers
and interactive sessions. When ftping from the Linux box, file transfers
cause delays with interactive telnet sessions. This results in interactive
sessions having a "bursty" flow of information: that is, you might type
in a UNIX command and the resulting echo/command output would be delivered
back in a few seconds as one burst of traffic.
Overall, the throughput doesn't seem to bother our users, and
qualitatively the sessions seem as fast as they would be with a dedicated
modem. At the moment, there are 11 PCs, one Sparc 10, and a VAX/VMS minicomputer
using the Linux gateway. If more users request access, we intend to upgrade
to a 64K ISDN line. This is easily accomplished since ISDN modems support
the Hayes AT command set, and we are using an external COM port. The 16550
is capable of sustaining 115K bps, so a 128K ISDN connection is possible.
Any opening to the Internet of course raises security issues.
This method of access is fairly secure. The IP address of our gateway is
dynamically assigned, so hackers would have to probe for it frequently.
Further, unless they have an account with our ISP, they should not be able
to snoop on our IP traffic. And even if they are able to snoop, they should
only see a fairly energetic IP, which is of course the IP masquerade, and
certain generic broadcasts.
If they came across interesting IPs on our LAN, they would still
have to go through our gateway to get there. Using the hosts.deny
and hosts.allow files in /etc, I have limited access to telnet
sessions and other inetd type services. A word of caution: those
daemons that are run at boot and are not instantiated from inetd
do not use hosts.deny and hosts.allow.
While this method is more secure than having a well-known IP (static)
with published routing information, does limit Internet activity to gathering
information versus supplying it. Right now this isn't a problem, since
VDOT has Internet hosts that aren't connected to our WAN. If you are interested,
check out VDOT's home page at:
http://www.vdot.state.va.us
About the Author
Charles Bundy received B.S. and M.CS degrees from the University of Virginia. He is currently a programmer/analyst for the Virginia Department of Transportation and has implemented a statewide WWW server program using surplus equipment and the Linux OS. He also founded an Internet Technology transfer program in 1994.
|