Cover V09, I06
Article
Figure 1
Figure 2

jun2000.tar


A Linux Internet Gateway

Marcel Gagné

Back in the February 2000 issue, I covered the idea of setting up an intra-office email server using Linux. Designed to work as a standalone email solution for a small or home office, the logical next step is to branch this machine to an Internet connection and bring the office online. Online means many things to many people, but email is still arguably the most powerful reason to provide company-wide Internet access. Consequently, your setup will no doubt require providing email as well as Web-browsing capabilities. You can define who gets access and to what.

While I will review some of the topics covered earlier, I'll assume that you can refer to the February 2000 issue for how to set up the original mail server. This beginning-level article will show how to configure a Linux system to provide Internet access. I'll also show how to accomplish this for a minimum of cost, with one company sharing a single phone line, a single modem, and a single dial-up account to an ISP. This setup demonstrates the magic of IP forwarding and masquerading -- a technique that makes all hosts in a network appear as though they are coming from the single Internet-connected Linux server.

The setup I will present here is actually comprised of two main components. One is the technical side -- the nuts and bolts of using Linux to create this simple, powerful server. The second is more marketing related. I will start with the second component -- the search for a friendly ISP begins.

What to Look for in an ISP

One of the great things about this solution is that we can keep the costs of Internet access for a small company down to a minimum. Depending on your ISP, service can range from a few dollars a month for a casual dial-up connection to a few hundred dollars for dedicated 24 by 7 service.

Web services are the least demanding requirement. Almost any ISP that you can configure in your Windows 9x Dial-up Networking is a candidate for office sharing. Services like AOL that require special software to connect can be more difficult and sometimes virtually impossible to use.

I recommend that you contact some of the smaller ISPs in your area. Strange as it may seem, smaller ISPs often provide more service options than their larger competitors. I have also found that smaller providers are often extremely knowledgeable. Their small staff means that their people truly understand the nature of the service they provide, and technical support is second nature to them.

While Internet accounts at both large and small providers generally make it easy to share a single phone line and dial-up connection, you may find your choices more limited if you want to provide mail as well as Web services. This is particularly true if you want your mail delivered to your domain address. For example, you want all people in your office to get mail addressed to user_name@mycompany.com. Don't despair. There are still a couple of ways to do this. Some ISPs will allow a domain or multi-drop mailbox. This means that any and all mail directed at mycompany.com is delivered to the individual who controls the dial-up account. You then use a program like fetchmail (more on that later) to disassemble the messages and deliver them to appropriate individuals. Some ISPs will also set up individual accounts for the various people in your office. The first of these options, the multi-drop mailbox, is the most flexible, because you can create new users or mail aliases on the fly.

The single most flexible option involves a 24-hour connection to your ISP through a dedicated-access service. This is also, unfortunately, the most expensive option.

Setting up your ISP Dial-up with diald

Let's work with the idea that we have purchased a dial-up PPP connection from a mythical company called we-are-an-isp.com. This connection costs a mere $24 a month, provides a multi-drop domain mailbox, and is limited to 200 hours per month. While that may seem like a fair amount of time, we don't want to stretch that too far. Thus, we will use diald for our dialer.

You may not have diald in your Linux distribution -- it was not included in my Red Hat distribution, but it was present on my Caldera 2.3 CD, so you should check before deciding whether you need to hunt it down. diald, by the way, is an intelligent dial-on-demand program originally written by Eric Schenk. Eric has since handed over the reins to a new maintainer, Mike Jagdis. Look for links to both sites in the Resources section at the end of this article.

We are going to set up diald with a minimum of fuss. On this system, I am using an ordinary 56-K modem on my COM1 port. You can either install diald directly from the tarred and gzipped distribution from the diald Web site, or pick up one of the binary distributions that are available. The main control file for diald is /etc/diald.conf. The one from my system looks like this:

#
# Diald configuration script for Internet gateway
#
mode ppp
connect "/etc/ppp/ppp-on-diald"
device /dev/ttyS0
speed 115200
modem
crtscts
local 192.168.1.150
remote 192.168.1.151
dynamic
defaultroute
include /usr/lib/diald/standard.filter
Before I show you the connect script, I'd like to point out what some of these things mean. In particular, look at the local, remote, and dynamic entries. For diald to work, it sets up a temporary slip connection that waits for requests from the network. For instance, a user clicking on a link in a Web browser is such a request. When the PPP connection is established, the dynamic entry tells diald to assign this new address to the PPP connection. Then, defaultroute tells diald to assign the new address as the default route to the Internet:

And now, the connect script.

#!/bin/sh
#
# This is the diald connect script.
# Location : /etc/ppp.ppp-on-diald
#
exec /usr/sbin/chat -v                              \
TIMEOUT              3                              \
ABORT               '\nBUSY\r'                      \
ABORT               '\nNO ANSWER\r'                 \
ABORT               '\nRINGING\r\n\r\nRINGING\r'    \
''                  \rATZ                           \
'OK-+++\c-OK'       ATH0                            \
TIMEOUT             30                              \
OK                  ATDTmy_isp_phone_number         \
CONNECT             ''                              \
ogin:--ogin:    Pmy_isp_login                   \
assword:            my_isp_passwd
This script must be executable. All you need to do is substitute your ISP's phone number, as well as the login name and password.

To start diald, use the following command:

   # /usr/sbin/diald
diald runs as a daemon and, under normal circumstances, requires no further user intervention. On systems I set up, I always include diald in the startup scripts so that it runs on boot up.

Automatic Remote Mail Pickup with fetchmail

fetchmail is a remote mail collection agent written by Eric S. Raymond. This package is so popular, it is included in virtually every Linux distribution and is available in source form to run on many different flavors of UNIX. This great package handles almost every mail collection protocol out there. We'll only concern ourselves with POP3 at this time. POP3 is still the most popular and common mail collection protocol offered by ISPs. fetchmail can log in with your ISP login and password and collect mail for a single account or for many. One of the really great things about fetchmail is that it can take apart the header information of incoming email messages and decipher their intended location.

At this point, I should mention that the author of fetchmail does not wholeheartedly recommend this method. This is because not all messages are so easily decoded, and some header information may be lost or misinterpreted. Messages delivered via large mailing lists, where the To: information is buried or rewritten, is the most common area of problems for fetchmail. For most day-to-day messaging, however, you should find fetchmail more than capable. Any mail messages that cannot be delivered will wind up in the root mailbox where the systems administrator can re-route them later.

fetchmail can be run as a daemon at system start up, from the command line, or from a shell script run through a cron job. The first option is by far the simplest, but the third allows you to add other options when fetchmail runs, such as a date and time stamp to confirm mail pickup. It also allows you to define exactly when fetchmail runs. For instance, in a number of environments where I have configured fetchmail, I am limited by a certain number of hours alloted by the dial-up account. Running fetchmail from cron lets me run it every 15 minutes during business hours.

Most of what you need to configure is done in a file called .fetchmailrc, which lives in the root directory. A sample script is provided with the distribution and is well documented. Using vi (or your favorite editor), edit the file /root/.fetchmailrc. Near the bottom of the file, there are several sample entries. You should see a paragraph that looks something like this:

# Use this for production
poll mail.myisp.com with protocol pop3:
no dns, aka mycompany.com mailserv.mycompany.com
user myaccount with password mypassword to root bob carol
ted alice natika marcel office info here;
The poll line defines the mail server connection. As you can see, I am connecting to myisp.com's mail server (as defined by the ISP) with the POP3 protocol. The next line tells my fetchmail program not to do DNS lookups for every address, and lists my mail server aliases. In other words, it should accept mail for those domains and hostnames listed.

Finally, look at the line that begins “user ...” Substitute myaccount and mypassword with the login name and password your ISP has provided. Then, before the word here, add your new users' names. Save the file and exit. You might also want to put in other names than those listed here if these people don't work for you. Keep in mind that these must be real names on your system or aliases in your /etc/aliases file. This is the case for the office and the info addresses.

If you want to run fetchmail as a daemon, look for or add the line that defines the interval in the .fetchmailrc. It looks like this:

set daemon 300
Then, start fetchmail in this manner:

fetchmail -d
You can also add the time interval directly to the daemon command if you don't want to include it in the .fetchmailrc file. That variant would look like this:

fetchmail -d 300
This means that fetchmail should run every 5 minutes. The catch here is that diald will bring your connection up every 5 minutes, 24 hours per day. Even if you change the line to every 30 or 60 minutes, it still polls around the clock. I prefer to use a simple script like the one that follows along with a crontab entry to control when fetchmail runs. My current script looks like this. I call it (strangely enough) pickup.mail. It also leaves a time and date stamp so that if something were to go wrong with mail pickup, I could verify the last time that fetchmail ran successfully:

#
# Pick up mail using fetchmail
#
/usr/bin/fetchmail -a -s
echo "Fetchmail ran at 'date'" > /usr/local/.Admin/fmranlast
The -s flag means that fetchmail should run silently, while the -a flag tells fetchmail to pick up all mail regardless of its status on the server (it may have been read on the mail host itself with a reader like pine, for instance). As I mentioned, I run fetchmail from a cron job. The following crontab entry ensures that mail pickup (which calls diald and brings up my connection) happens Monday to Friday, 7 a.m. to 7 p.m. at 30-minute intervals (essentially during business hours), thus preserving my limited hours:

0,30 7-21 * * 1-5 /usr/local/.Admin/  \
   pickup.mail 1> /dev/null \
   2> /dev/null
The How-To of Sharing a Single Line for Browsing

IP Forwarding and Masquerading

Modern distributions of Linux have made things much simpler for setting up a networked office. For instance, it used to be that IP forwarding and masquerading needed to be compiled into the kernel after the fact. This wonderful means of sharing access has long since left the experimental stage and now comes built in. This doesn't mean, however, that you will find IP forwarding pre-enabled.

In the directory /etc/sysconfig, you will find a file called network, which quite simply defines the basic network rules. The one for my Internet server looks something like this:

NETWORKING=yes
FORWARD_IPV4=yes
HOSTNAME=mailserv.mycompany.com
DOMAINNAME=mycompany.com
GATEWAY=
GATEWAYDEV=
The important line here is the second one. FORWARD_IPV4 is by default set to no. To allow an office of PCs to access your single dial-up connection, you will need to set this to yes and restart networking. Notice also that the GATEWAY and GATEWAYDEV are not set. As mentioned earlier, these are set when diald brings up the PPP connection.

On the PC side, you should make sure that your Internet gateway is set up as the default gateway for the server. On your Windows 9x system, click on Start, then Settings, then Control Panel. Then, double-click on the network icon and double-click again on the TCP/IP configuration line. If you have one for your network card and a dial-up networking TCP/IP line, make sure you pick the one for your network card. Finally, click on the Gateway tab and add the address for your Internet server. In this example (see Figure 1), the address is 192.168.1.100.

Finally, turn on IP forwarding for the PCs on your network. Depending on the realease of your Linux kernel, this could be either ipfwadm or ipchains. Pre-2.2 kernels use ipfwadm, whereas 2.2 kernel releases and higher use ipchains. This listing shows IP forwarding turned on with examples of both commands. Please note that this example shows the simplest possible form of these commands for external routing of an internal network. Both ipfwadm and ipchains can also be used to provide limits on internal and external access to all parts of your network. Essentially, these are building blocks for a powerful firewall system and should be visited in greater detail, a detail that is beyond the scope of this article. For further information, either refer to future (and past) articles in Sys Admin, or visit the Linux Documentation Project (listed in the Resources section).

IP forwarding with ipfwadm:

# Set up IP forwarding and IP   \
 masquerading with ipfwadm
#
/sbin/ipfwadm -F -f
/sbin/ipfwadm -F -p accept
/sbin/ipfwadm -F -a m -S   \
 192.168.22.0 -D 0.0.0.0/0
IP forwarding with ipchains:

# Set up IP forwarding and IP   \
  masquerading using ipchains
#
/sbin/ipchains -A forward -j MASQ  \
  -s 192.168.22.0/24 -d 0.0.0.0/0
DNS Revisited

Once again, for the sake of simplicity, I won't go into a complex description of Domain Name Services -- that too is beyond the scope of this article. The simple answer is to run the caching-only nameserver with a simple entry in your /etc/resolv.conf. A single line (or two) pointing to your ISP's nameserver will serve under the circumstances, for example:

nameserver XXX.XXX.XXX.XXX   (ISP's first DNS)
nameserver YYY.YYY.YYY.YYY   (ISP's second DNS)
You can also set your Windows 9x PCs to point to your ISP's nameserver by adding DNS entries through your control panel. An example of this is shown in Figure 2. In this example, I point to the Internet server as the primary nameserver.

If you want to put together a simple (but completely functional) DNS for your site, you can visit my Web site and check the downloads section for a set of template files. The tarball is called easydns.tar.gz. Change the references to reflect your domain and ISP nameserver entries, and you are all set.

Putting It All Together

After making all these changes, it's probably more than time to reset the network. The easy way is to reboot; however, one of the joys of Linux is that you don't have to do that all the time. On my Red Hat system, I simply stop and restart both networking and inetd:

# /etc/rc.d/init.d/network stop
# /etc/rc.d/init.d/inet stop
# /etc/rc.d/init.d/inet start
# /etc/rc.d/init.d/network start
The above example assumes that I am logged directly in to my server. If I am telnetted in, the first line will pretty much bring an end to the rest of my commands.

Since you will no doubt want all these services activated at boot time, it would be wise to add them to one of the bootup scripts. I recommend the /etc/rc.d/rc.local file. If you are following this example, then the things you need to start are diald, and your IP forwarding and masquerading. If you want around-the-clock mail checking, then add your fetchmail process in the startup script as well.

Basic Firewall Services

Once you expose yourself and your company to the Internet, you will want to institute some basic security at the very least. Nearly bullet-proof security is not impossible with your freeware Internet gateway, but it is beyond the scope of this article.

That said, it is fairly easy to say “Stay Out!” with a few simple configurations. TCP wrappers are a means by which you can control access to network services provided by your machine. The services that can be controlled by the wrapper are listed in your /etc/inetd.conf file. Programs controlled by the TCP wrapper will have a listing with tcpd in the line. For example, here's the line dealing with the rlogin service.

#login   stream  tcp     nowait  root    \
    /usr/sbin/tcpd   in.rlogind
As you can see, the line is commented out, which means that this service is not available to the outside world. The problem is that it is not available to my inside network either. If I wanted to turn on that service(by uncommenting the line and restarting the inetd process), I could use the TCP wrapper to regulate access.

Access through the TCP wrapper is handled by two main files. They are /etc/hosts.allow and /etc/hosts.deny. If you want to maintain services in your inetd.conf file open to you but cut off from the outside world, you would start by adding this line to the /etc/hosts.deny:

ALL:ALL
This means stop ALL people everywhere from accessing this system. Since that would mean the internal site as well, the next step is to add an entry for the local network in the /etc/hosts.allow file. This network, as you may recall, was an internal Class C network using the format with 192.168.1.xxx. To be safe, I will also add the localhost address for the Linux server itself:

ALL: 127.0.0.1
ALL: 192.168.1
In other words, allow all localhost access and all local network traffic. To activate these changes, reset the inetd process.

Conclusion

As you can see, an inexpensive solution to office-wide Internet access is simple with an out-of-the-box Linux distribution. Unlike its NT competition, a Linux server requires surprisingly little hardware and power. I have set up several servers that are nothing more than old 486 computers with as little as 16 MB of RAM. The available tools are mature and reliable, and since Linux is available free for downloading, the price just can't be beat.

Resources

Diald Network Link Management

http://diald.unix.ch/
The fetchmail Home Page
http://www.tuxedo.org/~esr/fetchmail/
The Linux Documentation Project
http://metalab.unc.edu/mdw/linux.html
Red Hat Software
http://www.redhat.com
Salmar Consulting Inc. (my Web site, for downloading template files)
http://www.salmar.com

About the Author

Marcel Gagné lives in Mississauga, Ontario. He is president of Salmar Consulting Inc, a systems integration and network consulting firm. He is also a pilot, writes science fiction and fantasy, and edits TransVersions, a science fiction, fantasy, and horror magazine. He loves Linux and all flavors of UNIX and will even admit it in public. He can be reached via email at: mggagne@salmar.com. You can discover lots of other things from his Web site at: www.salmar.com.