Linux Devours
Microsoft

UnixWorld Online: Tutorial Article: No. 015

Be a Linux-based ISP

By Charles Fisher

If one word could be said about Microsoft Windows products, the word would be ubiquitous. For better or for worse, the stuff is everywhere. While it is fairly simple to make Linux and Windows 95 inter-operate over a LAN, the Windows PPP (Point-to-Point Protocol) implementation is much more exacting. Rather than pour over manual pages on pppd configuration, you can read this article for a direct approach to establishing PPP sessions between these software architectures.

This article has been updated for Red Hat Linux 5.0, and it now contains additional information on automatic DNS configuration for Windows clients. Graphical browsers will show the new material in a distinct color. Those using non-graphical browsers look for the text “Red Hat 5.0 Update”.

Questions regarding this article should be directed to the author at cfisher@netexpress.net

How You Can Use This Information

There are a number of different applications for a Windows Dial-Up server:

  1. A commercial Internet Service Provider (ISP)
  2. Corporate IS staff who are responsible for providing Dial-Up services to other employees
  3. Corporate IS staff who want Dial-Up services for their own use

Each of these target audiences will install their server differently.

A startup ISP on a limited budget might tend to put all their services on a single machine. A single-server solution should work for the common services, including DNS, electronic mail, WWW server, FTP server, but not NNTP. If a site does not outsource NNTP services, then plan on a separate machine with nine gigabytes of disk space for a full feed.

An established ISP might be deploying Linux systems next to commercial terminal servers. Users within a corporate environment might require NIS, DNS, or mail services provided by different departments. However, the configuration of the Dial-Up lines remains the same under all environments for this article.

The information presented within this document is intended for Intel-based systems running Red Hat Linux 4.2. Much reference is made to Red Hat RPM archives and the out-of-box configuration files on a freshly installed Red Hat system. Much of the same information will be applicable, however, to other Unix platforms where the PPP daemon and mgetty are able to compile (which includes AIX and SunOS 4.x). While the expense of these other platforms makes them more appropriate for use as application servers, they can also assume the Dial-Up Networking role.

Red Hat 5.0 Update.
This article has been updated with information on Red Hat Linux 5.0. To be blunt, PPP support in Red Hat 5 is a mess. New and largely undocumented kernel parameters combined with a constant stream of patches and updates at the Red Hat Linux 5.0 Errata Site are making for unstable systems everywhere. Until the stream of updates slows, Red Hat Linux 4.2 will remain a much-preferable platform for dialup services.
End of Update

This article assumes that you have a system that reliably runs Red Hat 4.2. It is also assumed that your network interface cards are properly configured, that your serial boards and associated device files have been installed, that your network routers are functioning, and that you have added user accounts to your Unix system for each of your Dial-Up users.

Major Challenges

The Linux pppd daemon (version 2.2.0f) has flexible configuration options, and it is fully capable of communication with the Windows TCP/IP protocol stack. However, pppd has few options for controlling a modem. It does not send a modem initialization string, and it does not answer the ringing telephone line.

The various getty implementations are usually responsible for establishing modem sessions. However, most of these know nothing about PPP network sessions.

A further difficulty is in /etc/shadow password databases. Shadow passwords offer extra security for a Unix system, and a site should make use of them even if the administrator knows and trusts all of the users. The Linux pppd has a “login” option that forces authentication against the system password database, but the pppd binary that is shipped with Red Hat 4.2 will not authenticate against /etc/shadow. Red Hat technical support is aware of the problem.

There are two software components that will solve these problems. First, mgetty+sendfax will be used to control the serial lines and answer the modems. And, mgetty must be compiled with the “AUTO_PPP” option, to allow it to use exec() to spawn pppd. Second, pppd itself must be recompiled to employ /etc/shadow.

Compiling mgetty

An RPM containingmgetty and relevant Red Hat patches is available (<URL:ftp://ftp.redhat.com/pub/redhat/redhat-4.2/SRPMS/mgetty-1.1.5-1.src.rpm>). For other platforms, you can get a copy from the mgettyhomepage.

Red Hat 5.0 Update
If you are running Red Hat 5.0, your task is a little easier. A slightly newer version of mgetty is available, and the binary RPM package is now compiled with AUTO_PPP. If your machine is directly connected to the Internet, you can use the following command to install it:

rpm -Uvh ftp://ftp.redhat.com/pub/redhat/redhat-5.0/i386/RedHat/RPMS/mgetty-1.1.9-3.i386.rpm

Red Hat's FTP server is sometimes quite busy; you may have to run the command several times before a successful download and install occurs. If you don't have a direct Internet connection, you will have to get the file from your installation CD or another source. Then, install the package manually with:

rpm -Uvh mgetty-1.1.9-3.i386.rpm

Once you have installed this package, you may proceed with the modification of /etc/mgetty+sendfax/mgetty.config below.

The binary distribution is still compiled without optimization. If you would like to compile an optimized version, download the source
(<URL:ftp://ftp.redhat.com/pub/redhat/redhat-5.0/SRPMS/mgetty-1.1.9-3.src.rpm >).
End of Update.

Assuming that you are running as root on Red Hat 4.2 and your mgetty distribution is in the current directory, issue the following commands:

mkdir mgetty
cd mgetty
rpm2cpio < ../mgetty-1.1.5-1.src.rpm | cpio -i
tar xvzf mgetty1.1.5-Apr16.tar.gz
cd mgetty-1.1.5
patch < ../mgetty-1.1.5-config.patch
patch < ../mgetty-1.1.5-makekvg.patch
patch < ../mgetty-1.1.5-sendmail.patch

Red Hat 5.0 Update.
If you are running Red Hat 5.0 and you want to build an optimized mgetty binary, use the following command sequence:

mkdir mgetty
cd mgetty
rpm2cpio < ../mgetty-1.1.9-3.src.rpm | cpio -i
tar xvzf mgetty1.1.9-Aug17.tar.gz
cd mgetty-1.1.9
patch < ../mgetty-1.1.5-config.patch
patch < ../mgetty-1.1.5-makekvg.patch
patch < ../mgetty-1.1.5-sendmail.patch

Modify the CFLAGS line in the Makefile on line 111 (add whatever optimization flags you wish). Then issue the “make install” install command as root.
End of Update.

This will prepare a version of the mgetty source with the latest patches.

Next, edit the make command description file (named Makefile), and find the line that begins with the word “CFLAGS” (which should be line 110) and add “-DAUTO_PPP” on the end. The line should now read:

CFLAGS=$(RPM_OPT_FLAGS) -Wall -pipe -DAUTO_PPP

You might also add “s -O2 -fomit-frame-pointer” to the previous command to create a smaller binary image, if you are comfortable with the optimizer.

Now, enter the last command sequence:

make; make install

mgetty will now be installed on your Red Hat system. Makefile will install the directory /etc/mgetty+sendfax (or /usr/local/etc/mgetty+sendfax if you install the unpatched sources and not the RPM).

You should modify the file /etc/mgetty+sendfax/mgetty.config so that the top two lines read:

speed 115200
modem-type data
rings 1

If you want to enable FAX transmissions with mgetty, you might want to use different options in this file. If so, see the documentation.

You should also modify the file /etc/mgetty+sendfax/login.config so that it contains the line:

/AutoPPP/ -     a_ppp   /usr/sbin/pppd 115200

There will be another commented AutoPPP line that passes many more options to pppd. It is more convenient to place these switches in /etc/ppp/options (so “ps aux” listings remain uncluttered), so these options are removed here.

When mgetty is running, it will place log files in /var/log. You may want to either clean them out manually from time to time, or put the log files on automatic rotation.

Compiling pppd

This section addresses pppd version 2.2.0f, which is included in Red Hat 4.2 and 5.0.

This section is optional; you can configure a working dialup system with the standard pppd. However, you might want to consider recompiling pppd so you can make use of shadow passwords. This is not trivial.

The reason that you might want to make use of shadow passwords is simple. When you use Telnet, Rlogin, or Ftp, you transmit your password over the Internet in clear text form. Anyone who has a packet sniffer running on the intermediate network between you and your server can read the password.

On a conventional Unix system, if the party who has stolen your password logs into your server, they can see the DES-encrypted passwords for all the other users on the system in the /etc/passwd file. The intruder would most likely take a copy of the /etc/passwd file and use a program like crack to try to obtain the passwords of other users as well.

If your system supports shadow passwords, there is an /etc/shadow file, readable only by root, that contains the encrypted passwords, whereas the /etc/passwd file contains placeholders in the password (second) field. The shadow file will reduce the danger to other users should an account be penetrated by an intruder.

Shadow passwords are not enabled by default on Red Hat Linux (other distributions may differ). You can find instructions on how to enable them in the shadow documentation at the Red Hat web site.

Red Hat 5.0 Update.
The shadow password implementation has changed for Red Hat Linux 5.0, and there is new documentation on the subject.
End of Update.

If you make the decision to use shadow passwords, you must recompile pppd. The pppd binary included with Red Hat Linux will check passwords against /etc/passwd only.

The current beta of pppd has support for Red Hat's Pluggable Authentication Modules (PAM), which will make pppd shadow-aware out of the box.

An RPM containing the source code for pppd and relevant Red Hat patches is available (<URL:ftp://ftp.redhat.com/pub/redhat/redhat-4.2/SRPMS/ppp-2.2.0f-3.src.rpm>).

Assuming that you have placed the pppd RPM in the current directory, here are the steps to set things up:

mkdir ppp
cd ppp
rpm2cpio < ../ppp-2.2.0f-3.src.rpm | cpio -i
tar xvzf ppp-2.2.0f.tar.gz
patch < ppp-2.20f-glibc.patch
gzip -cd pppd-2.2.0eglibc.patch.gz | \
        sed 's|/usr/src/redhat/BUILD/ppp-2.2.0e|ppp-2.2.0f|' | patch
cd ppp-2.2.0f
./configure
cd pppd

Red Hat 5.0 Update.
If you are using Red Hat Linux 5.0, you have several options. This release was originally shipped with pppd-2.2.0f. Recently, pppd-2.3.3 became available at the Red Hat Linux 5.0 Errata Site. The newer pppd features support for PAM (which means that /etc/shadow is automatically detected and used); however, it does not properly record log-in information in the wtmp file, so the who, finger, last, and related commands will not show the log-in names of the active PPP users (although the correct names will be stored in /var/log/messages).

Future releases of Red Hat Linux might include this daemon by default. You can determine what version of pppd is installed on your system by executing the command:
rpm -q ppp

If you either desire or are forced to use the newer version of pppd, run the following command (or its equivalent) to install it:

rpm -Uvh ftp://ftp.redhat.com/pub/redhat/redhat-5.0/updates/i386/ppp-2.3.3-2.i386.rpm

After you have installed the new daemon, run the following command to configure your /etc/ppp/pap-secrets file to allow PAM logins:

echo '* * "" *' >> /etc/ppp/pap-secrets

After this command is complete, skip to the next section. Caution: Do not remove the /etc/ppp/pap-secrets file as instructed later.

If you would like to use the older daemon, an RPM for Red Hat Linux 5.0 containing the pppd-2.2.0f source and relevant patches is available
(<URL:ftp://ftp.redhat.com/pub/redhat/redhat-5.0/SRPMS/ppp-2.2.0f-5.src.rpm>).

Enter this command sequence to prepare the daemon for compilation:

mkdir ppp
cd ppp
rpm2cpio < ../ppp-2.2.0f-5.src.rpm | cpio -i
tar xvzf ppp-2.2.0f.tar.gz
patch < ppp-2.20f-glibc.patch
gzip -cd pppd-2.2.0eglibc.patch.gz | \
        sed 's|/usr/src/redhat/BUILD/ppp-2.2.0e|ppp-2.2.0f|' | patch
cd ppp-2.2.0f
./configure
cd pppd
End of Update

Now, the following changes have to be made in the pppd directory before a shadow-enabled pppd can be compiled:

  1. In Makefile, change the line beginning with “LIBS” (line 28) to “LIBS = -lbsd”
  2. Then, add the flag “-DHAS_SHADOW -DUSE_MS_DNS” to the line that begins with “CFLAGS” (line 30).
  3. In sys-linux.c, change the include from “net/if_ppp.h” to “linux/if_ppp.h” on line 71.
  4. In auth.c, comment out lines 559-563 and 567 (by placing “//” at the beginning of the lines). If your C compiler doesn't recognize this comment sequence, you can always employ the conventional /* and */ delimiters. The Red Hat Linux C compiler works properly with the newer comment style.
  5. In auth.c, change the “pw_encrypt(” call to “crypt(” on line 564.
  6. In auth.c, comment out or remove the line reading “#include <shadow/pwauth.h>” (line 54).


Red Hat 5.0 Update.
If you have Red Hat Linux 5.0 with the older pppd-2.2.0f, make the following changes:

  1. In Makefile, add the flag “-DHAS_SHADOW -DUSE_MS_DNS” to the line that begins with “CFLAGS” (line 30).
  2. In auth.c, comment out lines 559-563 and 567 (by placing “//” at the beginning of the lines). If your C compiler doesn't recognize this comment sequence, you can always employ the conventional /* and */ delimiters. The Red Hat Linux C compiler works properly with the newer comment style.
  3. In auth.c, change the “pw_encrypt(” call to “crypt(” on line 564.
  4. In auth.c, comment out or remove the line reading “#include <shadow/pwauth.h>” (line 54).
  5. In main.c, comment out or remove lines 590-591 and 319-321.
End of Update

After you have finished patching the daemon, use root to run the following command and your system will be ready:

make; strip pppd; cp pppd /usr/sbin

Please note that, if you install the shadow pppd, you must be running shadow passwords. Don't install the daemon first if you plan to convert to shadow at a later date.

Obviously, this is a great deal of work. Conscientious administrators will of course take all these steps on their own, as pppd runs with root privileges. Less security-conscious users can download a copy of the pppd.gz binary that I have prepared (which should be uncompressed and installed as /usr/sbin/pppd - this is version 2.2.0f, compiled with HAS_SHADOW and USE_MS_DNS). Realize that it's a bad habit to download software from the Internet and run it as root.

Red Hat 5.0 Update.
If you have Red Hat Linux 5, you can download the pppd5.gz binary and install it as /usr/sbin/pppd. (This is version 2.2.0f, compiled with HAS_SHADOW and USE_MS_DNS.) Do not try to use this binary on a Red Hat Linux 4.2 system - it was compiled with a different C library.
End of Update.

Options in /etc/ppp

Before you go any further, you need to assign IP addresses to each of the modem lines that will be providing PPP services. These IP addresses will be recorded in the /etc/ppp/options* files.

Your /etc/ppp/options file contains control parameters for all pppd sessions that run on your system. It should contain the following:

auth
-chap
+pap
login
modem
crtscts
lock
proxyarp
dns-addr x.x.x.x
dns-addr y.y.y.y

All of these options are discussed in the pppd man page, but below is a quick synopsis:

auth
Force the remote PPP system to authenticate.
-chap
Do not use CHAP authentication.
+pap
Use PAP authentication.
login
Authenticate against the system password database (/etc/password or /etc/shadow), and record the session in the wtmp file.
proxyarp
Configure the Ethernet card to respond to ARP requests for the IP address of the remote PPP system.
dns-addr x.x.x.x
Pass the IP address of a DNS server to the client. This only works for Windows clients. You should have no more than two of these entries in the options file. This option won't work unless your pppd was compiled with -DUSE_MS_DNS, but it makes the configuration of the client much easier.

Red Hat 5.0 Update.
If you have Red Hat Linux 5 with the newer pppd-2.3.3, your /etc/ppp/options should contain:

auth
login
modem
crtscts
lock
proxyarp
ms-dns x.x.x.x
ms-dns y.y.y.y

All options are the same as described above with the exception of ms-dns, which is the same as dns-addr in the older version.
End of Update.

You should also remove the file /etc/ppp/pap-secrets, as it sometimes interferes with normal PAP authentication in the pppd server unless you are using pppd-2.3.3 on Red Hat Linux 5.

Now, each serial device that will support PPP must have a unique option file. If you plan to attach a modem to /dev/ttyS0 (DOS COM1:), the file /etc/ppp/options.ttyS0 will contain parameters specific to that modem.

Let's pretend that I have a PPP server at IP address 1.2.3.1, and that I have allocated 1.2.3.4 as the IP address that I want to assign for the PPP dialup. Let's also pretend that I am using a Comtrol Rocketport serial device that is known on my system as /dev/ttyR1.

If this were the case, I would require a file: /etc/ppp/options.ttyR1, and it would contain the single line:

1.2.3.1:1.2.3.4

The first parameter above is the IP address of the dialup server. The second parameter is the IP assigned for that line. Each serial line must have a different IP address.

The “proxyarp” option listed above deserves greater attention. If proxyarp is excluded, the serial devices will be able to transmit network data to the server, but they will not be able to communicate with any other machine. (The proxyarp option configures the Ethernet devices to answer ARP requests for the PPP IP addresses.) If you have some dialup lines that you want to configure for email access only, you might move the proxyarp parameter out of /etc/ppp/options and into the device-specific options files for the lines that will receive total network access.

If you have no IP addresses to allocate for your serial devices, you might consider using bogus IP addresses in the 192.168.x.x range, and proxy software like the free TIS FireWall ToolKit or the old CERN WWW Server . You normally cannot use proxyarp in such a situation. Information on IP Masquerade might also be helpful.

Adding mgetty to /etc/inittab

Each serial line will be controlled by an entry in /etc/inittab. An entry for ttyS0 might look like:

S0:345:respawn:/usr/sbin/mgetty ttyS0

Red Hat 5.0 Update.
Under Red Hat Linux 5.0, the mgetty binary is now in /sbin. A correct /etc/inittab entry would be:

S0:345:respawn:/sbin/mgetty ttyS0
End of Update.

You must add similar lines describing each serial device on your system that is participating in the mgetty/pppd arrangement.

After you have made your changes to /etc/inittab, you will have to either reboot or enter the shell command “init q” while logged in as root. You should see lights flash on all the modems that you have enabled (if you have external modems).

You can recycle all your inactive modems at any time by entering the command “killall mgetty” (be careful of this command on non-Red Hat systems).

Testing

Red Hat 5.0 Update.
If you have Red Hat Linux 5.0, you must enable packet forwarding between the PPP devices and the network card with the following command:

echo 1 > /proc/sys/net/ipv4/ip_forward

This should be inserted into the system startup scripts. One way to do so is with the following command:

echo 'echo 1 > /proc/sys/net/ipv4/ip_forward' >> /etc/rc.d/rc.local

Red Hat does not prefer this method. They suggest that a modification be made to the /etc/sysconfig/network file. If forwarding is disabled, there is a line in the file that reads:

FORWARD_IPV4=no

To enable forwarding in a way that conforms with the Red Hat configuration scripts, change the line to:

FORWARD_IPV4=yes

There is more documentation about the contents of the /etc/sysconfig directories in a document at the Red Hat site.

If you don't enable packet forwarding across the network interfaces, the dialup users will be able to send packets to your Linux host, but not to any other machine on the network. That is, it will appear as if you have forgotten the proxyarp option above.
End of Update.

First, you have to set up a Dial-Up Networking icon on a Windows 95 system that will connect to your server.

I have prepared a Windows 95 document that describes this procedure, and a similar document that describes the connection under Windows 3.1 and Trumpet Winsock. You should change the name “ACME” (and “acme”) in the document to the name of your own organization, the IP addresses of the name servers (1.2.3.4, 5.6.7.8) to your own DNS servers, and the phone number (123-456-7890).

For larger ISPs, Netscape has a kit for Internet connection software and Navigator.

Microsoft also has a kit that creates a custom version of Internet Explorer. It also configures Dial-Up Networking.

To connect a Macintosh to your Dial-Up server, get the FreePPP (www.rockstar.com) package.

Of course, you are running getty so you can use terminal programs (or terminals) with modems for dialup shell access. HyperTerminal works from Windows 95, minicom works from Linux.

To connect another Linux system to your Dial-Up Networking server, you should place the following files on the remote Linux system:

In the /bin/network file:

#!/bin/sh

exec /usr/sbin/pppd -detach lock modem crtscts defaultroute user USERNAME \
	/dev/ttyS0 38400 connect "/usr/sbin/chat -f /bin/network.chat"

And in the /bin/network.chat file:

'ABORT' 'BUSY'
'ABORT' 'ERROR'
'ABORT' 'NO CARRIER'
'ABORT' 'NO DIALTONE'
'ABORT' 'Invalid Login'
'ABORT' 'Login incorrect'
'' 'ATZ'
'OK' 'ATDT 1234567'
'CONNECT' ''
ogin:--ogin: ''

And in the /etc/ppp/pap-secrets file:

# Secrets for authentication using PAP
# client    server              secret              IP addresses
USERNAME    ""                  PASSWORD

The scripts above will require some modifications:

  1. You must set the correct serial port for your modem in /bin/network.
  2. You must insert your own ISP telephone number instead of 1234567 in the /bin/network.chat script.
  3. You must replace the USERNAME and PASSWORD in /etc/ppp/pap-secrets and /bin/network with the Unix account name and password on the Dial-Up server.

When these files are in place and the user execute bit is set for /bin/network, the root user should be able to run the /bin/network shell script and set up the network connection.

Non-root users can also use the script if root runs the command “chmod u+s /usr/sbin/pppd” and changes the permissions of the serial port device in the /dev directory to mode 666. You might also create a ’ppp group“ to permit only trusted users to administer the interface.

Remember to put the IP addresses of your name servers in /etc/resolv.conf on your client system, or you won't be able to resolve Internet host names.

You can find more information on attaching Linux to an ISP in the ISP-Hookup-HOWTO (<URL:ftp://tsx-11.mit.edu/pub/linux/docs/HOWTO/ISP-Hookup-HOWTO>)

Conclusion

For all Microsoft's advertising, a Unix Dial-Up server is much less expensive than RAS under NT. If you consider the added cost of proxy software, should it be necessary, the price gap is even more stark.

Windows NT server costs approximately $1,000 (or more, depending upon user licenses). The GPL release of Red Hat Linux is available from Linux Systems Labs for the cost of the distribution media ($1.95).

Linux also includes an unlimited-seat SMB server, FTP, WWW, Telnet, X Window System, NFS, and electronic mail servers. Some of these items are very pricey on Windows NT.

Network equipment vendors such as Cisco or Livingston also offer products that perform the same function as a Linux Dial-Up server, but they lack the tremendous flexibility of a full Unix operating system.

If you need an inexpensive, reliable Dial-Up Networking solution that offers the flexibility of Unix, Linux is the way to go.

Author Biography

Charles Fisher is a writer and consultant who specializes in Linux. He has a home page that describes his personal and professional interests.


Edited by Becca Thomas / editor at unixworld.com