OpenBSD Journal

Creating a PPP dialup server with OpenBSD

Contributed by jose on from the make-your-own-ISP dept.

Chris Cappuccio writes : "Using a Unix or Unix-like system for dialup these days is unheard of. The setup is too obscure for many folks, and now you can buy cheap dialup servers on eBay anyways.

So why do it?

Well, we didn't want a real dialup server. That requires expensive T1 PRI or DSS lines. Those devices also usually require some kind of RADIUS authentication database. A cheap good T1 dialup server on ebay is around $1000 for an Ascend box or a couple hundred bucks for a Livingston Portmaster 3. Personally, I hate the Livingston ComOS. But, more to the point, we don't want to spend $400-$600/mo for a PRI line. We could have gotten a cheap Livingston 2 and plugged in external modems or something. But at that point, I'd rather use an OpenBSD box."

But you lose if you don't have a digital connection!

Sure, that's the downside to a simple group of modems on a PC. Unless you are connecting to a digital line (ISDN BRI, ISDN T1 PRI, or T1 DSS) then you don't get the opportunity to provide 56Kbps service, your limit is 33.6Kbps. Hey, no big deal. The goal for us is to be able to give folks dialup access for FREE with their real internet connection. Our customers started saying, "hey, I had FREE dialups with my last provider, don't you have something?" They aren't using it as their primary Internet connection, it's just to check email from home or on the road.. So, we are willing to live with this limitation. Another limitation is that without a real dialup server, it's hard or impossible to determine what speed people are connecting at.

But I digress..You may want to setup a dialup server just so you can hit your Unix-like shell from a payphone out in the middle of nowhere with the test pad on your lineman's handset... Who knows what us Unix freaks out there want to do...

Down to the nitty-gritty

My configuration is as follows: Four ISA modems. All are USR Sporsters, I tried some Rockwell chipset ISA modems but they were just trash. The TI chipset Sportsters worked every time. The PC is an older Celeron 300A with 64MB of RAM and a 12GB disk.

Here's how I did it. First, I configured the modems to play ball. I went into each modem like this: cu -s 115200 -l /dev/cua00 (or 01, 02, ...)

For those unfamiliar with cu, you can use tilde-dot to exit the session. If you are connecting in through ssh, two tildes are required, one to escape the ssh session, and the second one is then actually passed on to cu. These AT commands set a number of important settings. ATZ sets the modem to factory defaults. AT&W actually saves the settings so the modem always uses them. We want all the modem control, line control, flow control, that way OpenBSD knows when a call starts and stops. The flow control is nice since OpenBSD is talking at 115200 but the modem will connect at variable speeds on the other side. My notes on the actual modem settings are stored in the system's /etc/motd: (Note if your sportster modems have dip switches, make sure they are all set to give you software based control)
Q2 - Result codes only for outgoing (Q1 Disable result codes; Q0 Enable result)
E0 - Disables local character echo
&B1 - Fixed DTE speed (&B0 floating DTE)
&C1 - Modem controls CD (&C0 CD always ON)
&D3 - Reset ON DTR loss (&D2 DTE controls DTR, D1 command mode)
&S1 - Moden controls DSR (&S0 DSR always ON)
&H1 - CTS TX Flow Control (&H0 Disable TX FC, &H2 Xon/Xoff TX FC)
&I0 - Disable RX Flow Control (&I1 Xon/Xoff)
&K1 - Auto Data Compression (&K0 Disable comp, &K2 Enable comp, &K3 Selective)
&R2 - RX to DTE/RTS high (&R1 Ignore RTS)
S0=1 - One ring before answer 
S2=255 - Escape code char 255

Next, I configured /etc/gettytab to lock the serial port at 115200, timeout after 30 seconds of inactivity in the pre-login phase, setup the TTY control flags, TTY input flags, TTY local flags, TTY output flags, do flow control based on carrier signal, use no parity, and start the PPP program of my choice if getty noticed an LCP packet being sent by the calling party.

pppd.115200:   :sp#115200:to#30:c2#0245400:i2#025402:l2#02713:o2#07:
I use pppd because I'm familiar with it. I used it on SunOS for a few years, and later on OpenBSD when I was dialing up from it. Some of you prefer user-land ppp and that's fine too, it should be usable, but I'm going to show you how I used pppd.

These TTY flags in the c2, i2, l2 and o2 settings are supposed to enable RTS/CTS and various modem control features. These were gleaned from the mailing list, and work very well for me. I am unable to locate documentation which explains exactly what they do.

What does it mean to start PPP on an LCP packet? Well, it means that if you dial in with a terminal program, or a terminal itself, you are not going to be thrown into PPP. You are going to get the OpenBSD login prompt. If you dial in with a PPP client, it will send PPP LCP packets, getty will recognize that, and start pppd.

So, the next step after gettytab is configured to your specifications, the next step.... Decide which ttys are part of your dialup. I have four ISA modems, and ISAPNP wasn't working very well, because it was choosing conflicting IRQs to non-PNP devices which it had no way of knowing were already using the IRQ for other purposes. So, I set the modems up manually, using the jumpers, and used config -e to match up the kernel.

pccom0 at isa0 port 0x3f8/8 irq 4: ns16550a, 16 byte fifo
pccom1 at isa0 port 0x2f8/8 irq 3: ns16550a, 16 byte fifo
pccom2 at isa0 port 0x3e8/8 irq 5: ns16550a, 16 byte fifo
pccom3 at isa0 port 0x2e8/8 irq 7: ns16550a, 16 byte fifo
Next, I asked /etc/ttys to play nice:
tty00   "/usr/libexec/getty pppd.115200" vt100 on
tty01   "/usr/libexec/getty pppd.115200" vt100 on
tty02   "/usr/libexec/getty pppd.115200" vt100 on
tty03   "/usr/libexec/getty pppd.115200" vt100 on
See how that tells getty to use the pppd.115200 entry from gettytab? Next, just tell init (always pid 1) to HUP... kill -1 1

Now gettys are listening on the dialup and PPP needs to be configured. Here's how pppd works. It reads /etc/ppp/options.TTYXX when it detects a connect on TTYXX. So I setup several nearly identical /etc/ppp/options.ttyXX files.

pap-timeout 60
deflate 15,15
bsdcomp 15,15
idle 1200
As you can see, pppd takes a relatively free form configuration file. Here we tell pppd to pay attention to modem control signals, RTS/CTS flow control, we tell it to assign dome DNS servers and a domain name, we tell it to timeout if the user doesn't authenticate in 60 seconds, and we turn up compression to the max. We set a session idle time of 1200 seconds... We tell pppd to lock the tty..We tell it to require authentication...And we tell it what IP address to use on this tty.. tells it to use the machine's IP of for one end of the Point-to-Point link and for the client's end. Since pppd doesn't have an address pool option, this is the next best option. Just tell it to use a different address, depending on the tty the user connects into. Obviously, the IP address increases, in options.tty01 it is, in options.tty02 it is, etc...

Next, you'll need to enter the PPP authentication data somewhere. Enter /etc/ppp/pap-secrets:

# client        server  secret                  IP addresses
jimbo * yeehaw *
sourceoflabor * stolenlives *
All I do to add a user and password is put in the username, asterisk, passord, asterisk... This is the closest way I could figure to configure pppd to act like a typical ISP dialup server. Finally, I did rm /etc/ppp/chat-secrets and then ln -s /etc/ppp/pap-secrets /etc/ppp/chat-secrets. That way, if the user uses PAP or CHAP, they will be able to authenticate.

You don't need an /etc/ppp/options file, just /etc/ppp/options.tty00, /etc/ppp/options.tty01, etc... Just make sure you DO have an options file for every device that you are configuring for users to dial into. And each one needs a different IP address.

To wrap it up, you also need to set sysctl -w net.inet.ip.forwarding=1 because after all you ARE using this feature with a PPP client. You set this permanently in /etc/sysctl.conf. If you have questions about any of this, gettytab, tty, and pppd all have manual pages.

So, this is all you need to do if you want dialup on the cheap. It has proven to be ultra-reliable for me. You can dial in with a terminal or a PPP client this way. You could even do SLIP through a scripted login (SLIP doesn't have anything like LCP or PAP to automate the process) or UUCP transfers. Wow, what a throw-back to last century :) There's a lot more depth to what's going on here than I describe, obviously...So you might want to read up on the modem configurations, on serial lines and associated modem and RTS/CTS flow control, pppd, and if you have documentation or a pointer to the right source code to understand those i2, l2, etc TTY control flags, I would be curious to see it...

For the rest of you with fiber to your bathrooms, this at least shows you how it was once done


(Comments are closed)

  1. By Anonymous Coward () on

  2. By Michael van der Westhuizen () on

    I had to do this recently as well, and this kind of documentation was very hard to come by (I also ended up finding a bunch of stuff on the mailing lists).

    Something to be very careful of if you're doing this: don't overdo the modem settings, the defaults are usually sane!

    I'm using an ISA rockwell-based modem (waiting for my ISDN BRI line before I start serving 56k from an external Courier), and my basic AT commands are very similar to those that Chris used.

    What I did find is that I had weird issues with PPP-only clients (and I'm looking for PPP only, no shell) - I don't know if that's because I'm using user-land PPP, not pppd (but I kinda doubt it). What I ended up doing was patching in the pl= option from FreeBSD (treat the line as PPP only, and do not start the login program, but go directly to the PPP program specified by pp=). This has worked very well for me.

    If you're interested in the patch, I did it against 3.4 (will apply cleanly to -current as well), and it's available at:

    Thanks for the documentation Chris - I got close to tearing my hair out with some of this stuff when I first had to set it up :-)

  3. By Hugo Villeneuve () on

    Those c2,i2,l2 and o2 flag are the octal equivalent of the coresponding category of termios(4) flags. So see the man page for explanations and termios.h for the actual hexadecimal values of each flags.

    The thing with those flags is that getty ignores them if you only set one of them. So you end up having to compute the 4 of them even if you didn't need to change anything in most of them.

    But I stoped using those flag a few years ago. Right now, I found that using "rtscts" in the modem line in /etc/ttys is sufficient. (see ttys(5) and if you don're reboot, you need to run "ttyflags -a")

  4. By Anonymous Coward () on

    Suppose I have a cable modem at home and want to be able to dial in to my openbsd server for a PPP internet connection from the road. Is this possible? What I want to know is, does my connection on the PPP server have to be T-1?

    That way, I wouldn't have to pay for dialup access when traveling around (just long distance phone calls--but this is more of a "can it be done?" than "is it cost effective?" question).

    1. By Hugo Villeneuve () on

      You're confused because you think a T1 is only a internet connection. A T1 can also be used as 23-24 individual 56k digital channel that can be use in a maner ressembling a normal voice phone line.

      The article state that in order to offer 56k modem service you need a digital connection from your phone provider (ISDN or T1 and +) (and you need special hardware).

      But if you can be contented with 33.6k service. You can use any regular voice phone line and modem.

      Here I have text and PPP dial-in setup on my regular phone line. So whenever I am outside my place, I can call home. Which can be usefull when my internet connection is down or I need a cheap internet connection.

      But in PPP mode, I give the remote host an local private network IP (and use proxy arp). So I'm accessing the net behind a NATing gateway connected to a modem-cable. Unlike a normal ISP dial-in setup which give you public IP.

      I also subscribe to distinctive ringing service from my phone company which gives me a second phone number that rings differently on the main phone line. Coupled with a ring selector passive device that I put on the modem-wall phone cable, I get my computer to answer only those calls to that second number and leave calls to the main number to be human answered.

      1. By Matt Van Mater () on

        I've often thought of doing this for gee whiz factor just to see if it can be done. Good to see I'm not alone.

        Can you describe the ring selector passive device you mentioned in your last paragraph? I'm not clear on exactly how it works, or where I can get/make one, etc.

        1. By Hugo Villeneuve () on

          This is what I have:

          When needed, it blocks the rings to reach the device attached to it. (It always blocs the first one in order to take a decision). I got it through my local telco company store (the service cost 5$/month here and they sell a device to use it with legacy equipment [new fax machine have this built-in I beleive]).

          But you might not need it. A cheaper solution is to make the modem answer after 10 rings on your main line. This would give you a lot of time to answer the phone when your there. And if you live with people, they might not like to found the line busy, so you'd be better off getting a second line for it. As far as distingtive ringing goes, there is some support in modem for it but I don't know how you could use it. But it might be worth investigating.

          1. By Anonymous Coward () on

            wait... you mean you actually speak on a phone?

            1. By Anonymous Coward () on

              Yes. Good pizza can't be had otherwise.

              1. By Anonymous Coward () on


        2. By Anonymous Coward () on

          this is easy to do with a 486 and just add a modem in addition to the eth0/eth1 and you are the coolest ISP on your block.

  5. By chas () on


Copyright © - Daniel Hartmeier. All rights reserved. Articles and comments are copyright their respective authors, submission implies license to publish on this web site. Contents of the archive prior to as well as images and HTML templates were copied from the fabulous original with Jose's and Jim's kind permission. This journal runs as CGI with httpd(8) on OpenBSD, the source code is BSD licensed. undeadly \Un*dead"ly\, a. Not subject to death; immortal. [Obs.]