Wednesday, May 18, 2011

Setting up a pppd server

Introduction

I tried to clean up my space a little bit and found some old modems and a analogue telephone system. Perfect for playing around, setting up a pppd server and client and remember some old times. And so I decided to create this small workshop. Maybe somebody wants/needs to do the same one day. Currently I am using the following hardware:

Server: Elsa Microlink 56k basic
Client: Toshiba Satellite Pro 4600 internal softmodem
Telephone system: Keil Telecom K 106

And the following software:

Slackware 13.1 (server and client)
ppp 2.4.5 (server and client)
slmodem 2.9.11 20100718 (driver for softmodems, client only)
mgetty 1.1.37 (getty for handling incoming calls, server only)

Setting up the hardware

First make sure you have a working serial port on your PC/Server. Then try to figure out the device(s):                                                                

# dmesg | grep -i tty
serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
00:0a: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
serial8250: ttyS1 at I/O 0x3e8 (irq = 3) is a 16550A
00:0a: ttyS1 at I/O 0x3e8 (irq = 3) is a 16550A

The above output is from my server with two serial ports. ttyS0 is the first serial port and ttyS1 the second one. Pretty obvious. Next connect your hardware to the appropiate serial port you want to use. I will assume that the server side modem is connected to /dev/ttyS0. To test your modem you can use minicom. Once minicom is started you will get a welcome message. In the bottom you should see some information about your current settings:


I suggest you to set your settings for the serial port. Press 'CTRL-A O' and choose 'Serial port setup'. Define your serial port, speed and everything:


If necessary save as default configuration by selecting 'Save setup as dfl'. If you change your serial port in minicom, it is a good idea to restart minicom (after saving your configuration). If everything is setup you can do some tests with at commands now. Start minicom with your settings. You should get the OK prompt. This indicates that minicom is ready to work. Apply now the following at commands:


The first at (atx) command will allow the modem to dial numbers without a dialing tone. The second at (atdt0123456789) command will dial the number 0123456789 with tone as dialtone. While dialing you should hear the typical dialing tones. That's it, your serial connected modem works.

Preparing the client was a little bit tougher, I had to install slmodemd first. See my prior blog entry how to do this: http://karellen.blogspot.com/2011/04/toshiba-satellite-pro-4600-internal.html (if you have a normal serial modem ignore this). The rest is the same as above, just connect your hardware and test it with minicom.

Setting up the server: mgetty

First we need a new user. This user must be created locally on your pppd server:

# groupadd -g 3000 ppplogin
# useradd -d /home/ppplogin -m -g ppplogin -s /bin/false -u 3000 ppplogin
# passwd ppplogin
New password: ppplogin
Re-enter new password: ppplogin

In the example above I create first the group ppplogin with the GID 3000, then the user ppplogin with UID 3000 and GID 3000. We don't need a shel for this user, so it will be set to /bin/false. Finally I create a password for this user (You can use what ever you want, I just set everything to ppplogin for simplicity.

Next we need to install the server software. We need this to make sure that incoming calls will be automatically taken and that a network connection will be established. I use mgetty for taking incoming calls. When you don't have mgetty installed (or as a package for your unix available) then follow these steps to install mgetty. You need first to download the source, extract it and change into the new created directory:

# cd /usr/src
# wget ftp://mgetty.greenie.net/pub/mgetty/source/1.1/mgetty1.1.37-Jun05.tar.gz
# tar xfz mgetty1.1.37-Jun05.tar.gz
# cd mgetty-1.1.37

Then you need to configure the compile options. Copy the shipped policy.h-dist to policy.h and uncomment the line /* #define AUTO_PPP */ to #define AUTO_PPP:

# cp policy.h-dist policy.h
# vi policy.h
...
/* AutoPPP-Support
 *
 * If you want to auto-detect incoming PPP calls (with authorization done
 * by the pppd, i.e. via CHAP or PAP), define AUTO_PPP.                 
 * Not needed if PPP callers want to get a real "login:"
 * prompt first. Don't forget to activate the /AutoPPP/ line in login.config!
 */
#define AUTO_PPP
...

Now compile the source and install the binary:

# make && make install

If everything wents right, you should have mgetty under /usr/local/bin and the directory that holds the configuration files under /usr/local/etc/mgetty+sendfax. First configure the login.config file:

# cd /usr/local/etc/mgetty+sendfax
# vi login.config
/AutoPPP/       -       ppp     /usr/sbin/pppd auth -chap +pap login debug
*       -       -       /bin/login @

Correct the permissions for login.config:

# chown root:root /usr/local/etc/mgetty+sendfax/login.config
# chmod 600 /usr/local/etc/mgetty+sendfax/login.config

The first line will make sure that incoming calls will commited to pppd (I will talk about pppd later). The second line will ensure that every other login request will be commited to /bin/login. Next you need to configure mgetty configuration file itself:

# cd /usr/local/etc/mgetty+sendfax
# vi mgetty.config
debug 9
speed 57600
data-only yes
login-time 30
answer-chat-timeout 60
toggle-dtr yes

The debug option is good for logging the behaviour of mgetty and very useful for the beginning. The logfile will appear in /var/log/mgetty.ttyS1.
The speed option allows you to set the speed for the line itself.
The login-time is needed to force the user to login within 30 seconds.
The answer-chat-timeout is the time to answer each request without hanging up.
The toggle-dtr will keep a constant DTR (Data Terminal Ready) rate.

At least mgetty must be added to inittab to make sure it starts at system boot and will be restarted when it gets terminated (make sure you use a unique ID, in this case S1):

# vi /etc/inittab
...
S1:2345:respawn:/usr/local/sbin/mgetty ttyS1 -D /dev/ttyS1
...

Reload init and check if mgetty is running (don't try to start mgetty manually, it won't work):

# init q
# pgrep -fl mgetty
24134 /usr/local/sbin/mgetty ttyS1 -D /dev/ttyS1

Setting up the server: pppd

Finally we can setup the pppd it self. In most Unix/Linux distribution it is shipped already so I won't explain how to install the software. Instead I will show you directly how to configure pppd server side. Go to the directory /etc/ppp (or wherever your pppd configuration resides) and configure first the file options:

# cd /etc/ppp
# vi options
-detach
asyncmap 0
netmask 255.255.255.255
proxyarp
lock
crtscts
ktune
noauth
usehostname
modem
disconnect /etc/ppp/ip-down
ms-dns 192.168.1.73
usepeerdns
debug
mtu 1500
mru 1500


Next configure options.ttyS1:

# cd /etc/ppp
# vi options.ttyS1
172.16.12.1:172.16.12.2
debug

This will start the ppp server with the IP 172.16.12.1 and give the client the IP 172.16.12.2. For each modem you want to use you can set up a options file with more (or less) specific options. Eg. If you use ttys3 as your second modem for another connection it may look like:

# cd /etc/ppp
# vi options.ttyS3
172.16.12.3:172.16.12.4
debug

Setting up the client: pppsetup

You can use the script ppp-setup to setup the ppp client. Otherwise, just configure the following configuration files (options for the generic options and pap-secrets for the credentials):

# cd /etc/ppp
# vi options
passive
asyncmap 0
usepeerdns
name "ppplogin"

# cd /etc/ppp
# vi pap-secrets
"ppplogin"   *   "ppplogin"

The files above are the same as configured with ppp-setup.

Setting up the client: ppp-go

If everything is set up, you can start your ppp connection with ppp-go:

# ppp-go
Serial connection established.
Using interface ppp0
Connect: ppp0 <--> /dev/modem
Remote message: Session started successfully
PAP authentication succeeded
Deflate (15) compression enabled
local  IP address 172.16.12.2
remote IP address 172.16.12.1
primary   DNS address 192.168.1.73
secondary DNS address 192.168.1.73


Check your link status with ifconfig:

# ifconfig
...
ppp0      Link encap:Point-to-Point Protocol 
          inet addr:172.16.12.2  P-t-P:172.16.12.1  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:5 errors:1 dropped:0 overruns:0 frame:0
          TX packets:5 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:3
          RX bytes:96 (96.0 B)  TX bytes:102 (102.0 B)
...

And check the default route:

# route -N
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
172.16.12.1     0.0.0.0         255.255.255.255 UH    0      0        0 ppp0
127.0.0.0       0.0.0.0         255.0.0.0       U     0      0        0 lo
0.0.0.0         0.0.0.0         0.0.0.0         U     0      0        0 ppp0

Additional: pppstats

To traffic your ppp connection you can use the command ppp-stats:

# ppp-stats
...

Connecting with minicom

If you have trouble connecting to your pppd server then try to connect with minicom from the client:

# minicom
Welcome to minicom 2.1

OPTIONS: History Buffer, F-key Macros, Search History Buffer, I18n
Compiled on May 17 2010, 17:25:13.

Press CTRL-A Z for help on special keys

AT S7=45 S0=0 L1 V1 X4 &c1 E1 Q0
OK
atxdp11
CONNECT

 Welcome to Linux
   

ppp01!login: ppplogin
Password: ppplogin

ppplogin@ppp01:~$ id
uid=3000(pplogin) gid=3000(ppplogin)
ppplogin@ppp01:~$ exit
NO CARRIER

The first at command is the initialisation string for the modem. The second at command dials the number 11 which is my pppd server. After that you should get a normal login prompt and you should be able to login.

That's all, enjoy! 

Updated 10/16/2011: output for ppp-go, ifconfig and route for the client added
Updated 10/23/2011: options file for pppd added, permissions for login.config added
Updated 11/08/2011: changed the options for the server one more time
Updated 11/30/2011: removed an typo inside the options file for the modems
Updated 12/13/2011: added 'Connecting with minicom'