Building an ISP Using Linux and an Intranet
I became the founder of a small ISP for the Baltimore, Maryland area by accident. My wife and I had been having trouble finding a cheap and reliable Internet access provider. After endless frustration with busy signals, we decided to get a dedicated 28.8 line and use it as our connection to the Internet. The connection would always be up and available, and we could both use it to surf the Internet. It seemed natural to take the next step and provide access to others. Beyond helping people get on the Internet and giving me technical experience with Linux, it could provide us with a source of revenue to recoup some of the costs. Before you decide to become an ISP and make lots of money, however, I should warn you competition is fierce and we are not yet profitable.
The Internet server setup we have is a simple one: a Linux machine with four incoming lines for dialup and one outgoing line to maintain the dedicated connection. We currently support about twenty users on the machine. Although simple, this setup could present a problem: if four users dialed in, each would receive (28.8/4) = 7.2Kbps for his or her connection. Most of the time, however, only one user is logged onto our machine, and he receives full bandwidth. In addition, when multiple users are logged on, one may be downloading or composing e-mail, another might be reading a web page and a third may have walked to the bathroom.
One of the first steps you need to take to build a Linux Internet server is to recompile the kernel with networking on, IP forwarding/gatewaying on and any additional drivers selected. We have a network card and a Cyclades Cyclom 16YeP card (a multiport serial card) on the Linux machines, so we have those options turned on. When you turn on the IP forwarding/gatewaying, it enables the Linux machine to forward packets it receives over your network to the Internet.
Another important step during setup is to get an account with your ISP that supports point-to-point protocol (PPP). You can get a dedicated 28.8 connection for about $100/month that will provide you with full access to the Internet for your network. It is also preferable that you sign up for a static IP address or a Class C address and a domain name. A static IP address lets you log on to the Internet with the same IP address all the time. We have a Class C address, so this discussion uses only the Class C address. A class C address gives you a block of addresses (255) you can use to set up your internal network (Intranet). If you don't have a Class C address but rather a static IP address, you'll have to use IP Masquerading to access the Internet from your LAN. [See “IP Masquerading with Linux” by Chris Kostick in the July 1996 issue of Linux Journal—Ed.]
We started building our Internet server by calling our ISP and signing up for a Class C address with a domain name and a dedicated 28.8 line. After we received our Class C address block (206.156.217.*), I picked one of the addresses for our host (184.108.40.206) and proceeded to set up our network using the netconfig utility bundled with Linux.
Your ISP should be able to maintain the Domain Name Server (DNS) entry for your machine. The DNS entry allows Internet surfers to access your IP address using your domain name. IP addresses like ours (220.127.116.11) are hard to remember and non-descriptive; the DNS entry allows surfers and customers to reach our machine using NetBrain.com without knowing the IP address.
In the resolv.conf file, there should be a listing of the domain name servers you'll be accessing. The file should look something like:
#resolv.conf Nameserver 18.104.22.168 nameserver 22.214.171.124
Using the ppp-on script (part of the pppd package), you establish how your want your PPP connection set up. The ppp-on script is shown in Listing 1. You use this list to set up parameters such as the IP address of your machine and the host machine, whether you're running pppd on a modem or through a network, and the device you're using to make the connection. The ppp-on script calls the ppp-on-dialer script which actually dials the modem to connect to your ISP. The ppp-on-dialer uses chat, which dials the modem and also handles getting past the ISP's startup screen (user name, password). (Passing the 0.0.0.0 as a parameter for the remote is another way of saying “we don't care.”) The important parameters in the ppp-on script include:
115200—serial port speed—this doesn't mean your modem is as fast, but with some compression, it might get close.
/dev/ttyC2—your modem'd port default route—specifies this connection is the default route out of the machine, if it can't find the address locally.
Note that the chat has the ogin my_login and assword: my_password lines. This is chat's way of saying, “If you see ogin: then type my_login; then when you see assword type my_password.” You'll have to dial in manually to your ISP using a terminal program to see how this login screen looks.
If you type ppp-on and hear the modem dial and connect, you've taken your first step to running an Internet server. When PPP is running, you should be able to ping one of your ISP's machines from the Linux shell. A good address to ping is your ISP's DNS machine.
If ping is successful, try to see if TELNET works. A simple check is to telnet to one of the MOO sites (telnet baymoo.org 8888). If that works, you are connected and being routed correctly. If you have an account on another machine, you can also test the incoming connection via TELNET. This is more a test to make sure your ISP has the correct DNS entry. If you get the Unknown host error, either your ISP didn't put the entry in or it hasn't made it out—sometimes it takes a few days to make it to all the other machines.
Once your connection to the Internet is stable, it is time to connect your network. Your Linux machine and your other machines should all have network cards installed, and your Linux machine should have the kernel compiled with the appropriate drivers.
Suppose you want to set up Doofus (a Windows 95 client) and hook into your network to give it access to the Internet. Pick an IP address for Doofus of 126.96.36.199 (it can be any number available within your Class C block). To set up the Windows 95 machine to access your Linux server, you must go into the Control Panel and pick Network. Make sure TCP/IP is bound to your network card. The Properties button lets you set up the following items on each of your machines:
IP Address: If you have a Class C address, you can assign an IP address 188.8.131.52 and a subnet mask of 255.255.255.0.
DNS Configuration: Pick Enable DNS and give your machine the name Doofus for the host and NetBrain.com for the domain. This setup provides the Windows machine with the name Doofus.NetBrain.com—or read another way, Doofus is within NetBrain.com. The DNS Server Search Order should have your DNS entries added to be the same as the Linux server's /etc/resolv.conf nameserver entries.
WINS Configuration: Pick Disable WINS Resolution
Bindings: Add a gateway to your Linux machine. The gateway helps your machine find its way out of the network and onto the Internet. We added 184.108.40.206 to the list of installed gateways.
After you've rebooted your Win95 machine, you should be able to ping it from your Linux host using ping 220.127.116.11. If it fails, possible problems could be the cable, Linux drivers, Win95 drivers or your Win95 configuration. Now from the other side... When you're ready to test your Windows 95 client, open an MS-DOS window and ping your server. The command ping 18.104.22.168 should get a response from your server. You should be able to TELNET to your machine (telnet mickeymouse.com) and should also be able to bring up a browser and go to any web site that interests you. It's that easy.
Most personal computers have only two serial ports, and one of those is usually used by the mouse. The best way to provide dial-up access is to purchase a multiport serial card. We use the Cyclades Cyclom 16Yep card, which provides 16 serial ports for modem use. More important, the drivers are built into the Linux kernel.
Before you purchase a specific card, make sure the drivers for the card exist and your machine has the drivers compiled into the kernel. You might have to create the ports your serial card uses with MAKEDEV. Our Cyclades card uses ttyC0-ttyC15 for the serial ports instead of the standard ttyS0 and ttyS1 for the standard serial ports. Fortunately, the Cyclades card came with a makecyc install script that did the work for me.
The program setserial needs to be called to initialize the serial port(s). The /etc/rc.d/rc.serial file may need to be edited to properly set up your server's serial ports. To use com2 for the dial-out modem, put the following line in rc.serial:
#standard serial port - com2: setserial /dev/cua1 spd_vhi auto_irq autoconfig
For the Cyclades card, I configured the ports 3-10 /dev/cub2 - /dev/cub10 (some unused—for expansion) as follows:
#configure Cyclades serial ports setserial -b /dev/cub2 spd_vhi autoirq skip_test setserial -b /dev/cub3 spd_vhi autoirq skip_test setserial -b /dev/cub4 spd_vhi autoirq skip_test setserial -b /dev/cub5 spd_vhi autoirq skip_test setserial -b /dev/cub6 spd_vhi autoirq skip_test setserial -b /dev/cub7 spd_vhi autoirq skip_test setserial -b /dev/cub8 spd_vhi autoirq skip_test setserial -b /dev/cub9 spd_vhi autoirq skip_testMake sure the rc.serial file is called from one of the startup rc files, usually rc.s. This will configure your serial ports automatically during boot.
Next, you need to configure the host to listen to the serial port for incoming connections and to to answer these connections. The /etc/gettydefs file is used to set up the gettys which make connections to the machine. When a standard version of Linux is installed, you find these lines in the /etc/gettydefs file:
c1:1235:respawn:/sbin/agetty 38400 tty1 linux c2:1235:respawn:/sbin/agetty 38400 tty2 linux c3:1235:respawn:/sbin/agetty 38400 tty3 linux c4:1235:respawn:/sbin/agetty 38400 tty4 linux c5:1235:respawn:/sbin/agetty 38400 tty5 linux c6:12345:respawn:/sbin/agetty 38400 tty6 linux
This provides your console (keyboard) with six virtual logins. The fourth item in the line /sbin/agetty is the program polling the console for a login. The following parameters describe the login speed, terminal number and terminal emulation. You add the following lines for dial-up lines after the parameters list.
# Dial-up lines using /sbin/getty # (actually getty_ps) s1:345:respawn:/sbin/getty ttyC2 115200 vt100 s2:345:respawn:/sbin/getty ttyC3 115200 vt100 s3:345:respawn:/sbin/getty ttyC4 115200 vt100We use a different getty (getty_ps) for our dial-up lines because of trouble using agetty on the serial port. We also also heard that getty_ps is more reliable. You can also use mgetty for the dial-up lines, but getty_ps works great for us. The parameters for getty_ps are slightly different, however: parameters following the getty name are the tty, the /etc/gettydef label and the terminal emulation default. The 115200 in the preceding lines refers to the label in /etc/gettydefs file shown here:
#/etc/gettydefs # Modem locked at 115200: Serial port is at # 115200, modem is much less, but should be # able to compress. # # Last line of this file is described in next # comment line as fields separated by # signs. # label # initial-flags # final-flags # login prompt # next label 115200# B115200 CS8 CRTSCTS # B115200 SANE -ISTRIP CRTSCTS #@S login: #115200Now you have to provide the getty_ps with the startup values. In the directory /etc/defaults, place the configuration files for each dial-up line. For the dial-up line /dev/ttyC2, we have a corresponding file called /etc/default/getty.ttyC2 shown in Listing 3.
If everything works as planned, the host should be able accept shell logins. You should be able to dial into your machine and run commands in the shell.
To monitor the dial-up connection, you can set the DEBUG=777 in the /etc/default/getty.tty?? file to create a log file. This will help you identify problems should the modem not answer or not configure properly. The output is dumped to the syslog file usually in /var/adm/syslog.
This confirmation, which provides people with shell dial-up access, can be modified to provide dial-up PPP access to customers. We chose to modify the default login program (in the poeigl package) because we wanted to provide both PPP and shell access (useful when I'm remotely setting up someone's machine). The ppplogin program has a prompt that looks like this:
Username: jsmith Password: Please select PPP or Shell access: 1) PPP 2) Shell Please enter your choice: 1
If the user picks the shell, Linux invokes the standard defined shell for the user. If PPP is selected, a script invokes pppd for the dial-up user and dynamically allocates him an IP address. Part of the C code for invoking the ppp script file looks like this:
/* --- PPP account login --- */ execlp ("/bin/sh", "-sh", "-c", "/etc/ppp/ppplogin", (char *)0); fprintf (stderr, "login: couldn't exec shell script: %s.\n", strerror (errno)); exit(0);The /etc/ppp/ppplogin is shown in Listing 4.
When a user selects ppp, the server looks up the tty the person dialing in is using and assigns the tty an IP address. If the user always calls in on a specific line, he is given the same IP address. A user dialing in on the first line comes in on ttyC6. This is used to assign an IP address of 22.214.171.124 to the user. This creates a PPP link to the dial-up line like the PPP link to my host. The important parameters related to this tty/ppp connection in the ppplogin script are as follows:
Detach—don't run as a background process.
Modem—use the carrier lines to detect things like hanging up
126.96.36.199:188.8.131.52—I am known as 184.108.40.206, and the person on the other end is known as 220.127.116.11.
Early on we found our dedicated connection was frequently dropped by the phone company. I solved this problem by using a program called pppupd which constantly pings our ISP's machine and, if the ping fails, it invokes the ppp-on script to redial the connection.
Most of our customers are Windows 95 users who did not like having to type their name and password in each time they logged on to the server. To remove this source of irritation, we found a different getty package called mgetty, which provides autodetection of PPP dialers for Windows 95 users who want to use the Dial-up Networking dialog box. This has saved us quite a bit of time supporting Windows 95 users. The mgetty package (http://sunsite.unc.edu/pub/Linux/system/Serial/mgetty+sendfax) is difficult to set up, so read the documentation before building. One wonderful feature of this package is the capability to receive faxes on the incoming modem lines without additional hardware or additional lines. We can use the same dial-up lines to receive faxes.
E-mail for us was automatically configured with my Linux installation. You can install pine for shell access and POP v3 for POP server e-mail. If you don't have the POP server installed, you can get a package called pop3d from any of the various sites, such as sunsite.unc.edu, and follow the instructions to install it.
If you want your machine to host web pages, you have to install a web server. We downloaded the Apache web server (http://www.apache.org/) and recompiled and configured it using the available documentation. Compiling the source should create an httpd executable which can be copied into /usr/sbin. In addition, add the line /usr/sbin/httpd in the /etc/rc.d/rc.local configuration file for it to be automatically started during boot up.