NELUG, 12/4/2000
Eddy Younger <eddy@shofar.uklinux.net>
Introduction
- Dial-up networking is a special case of TCP/IP (usually…) networking over point-to-point connections.
- Two machines are connected to one another via serial lines
- Complicated by the need initially to establish a connection thru’ a modem
- See also PLIP (parallel-port connection)
PPP
PPP – point-to-point protocol, consists of a scheme for transporting IP packets over a serial line, a protocol to control the establishment of the link and negotiation of link parameters – the Link Control Protocol (LCP), and a set of Network Control Protocols (NCP) which configure different network-layer protocols – Linux ppp supports both IP and IPX at the network level. Includes a variety of data-compression mechanisms, authentication mechanisms, address assignment etc. Earlier mechanism – SLIP (Serial-line IP) – now deprecated: no link control/negotiation scheme meant that the two ends of the link had to have parameters fixed in advance and known to the other end.
There are two parts to the Linux PPP implementation:
- The ppp driver, a kernel module (or compiled-in). Implements the ppp encapsulation and LCP protocols. Sits between the IP layer and the RS-232 data-link layer.
- pppd – the ppp daemon. Responsible for bringing up a ppp instance on specified serial device, and handles negotiation of link parameters with the peer system. In the dial-up case, pppd invokes an external program – typically chat or dip – to initiate the connection. Once the link is up and negotiation is complete, pppd retires into the background until kicked into action by further LCP messages, or to tear down the connection.
Cast of characters
ppp layer appears to the IP layer above like just another network device.
chat
Simple program used by pppd to talk to the modem in order to dial up, and optionally log in to the remote machine, start ppp on the remote machine, etc. Simple expect/response dialog program; a chat script consists of pairs of “expected string”/”response string” lines and a few simple commands:
ABORT BUSY ABORT "NO CARRIER" ABORT VOICE ABORT "NO DIALTONE" ABORT "NO ANSWER" "" ATZ OK ATDT08456621598 CONNECT "" ogin: <user-name> assword: <your-password> % ppp
chat scripts may be used to log in to remote systems which issue “login:” and “password:” prompts, as in this example, but this is unusual for ISP’s and is less secure than CHAP authentication (see later).
dip
More sophisticated chat-like program, with inbuilt simple scripting language, and wider command set. Allows user interaction for example to enter user name and password at appropriate point in the dialogue. Useful for token-card users 🙂
wvdial
More sophisticated still. Can function as a chat or dip replacement (subservient to pppd), or can function as the controlling process – initiating the connection and then invoking pppd. In this role it first dials up via the modem and attempts to analyse the data coming back from the modem in order to decide how to log into the remote system and establish the ppp connection as necessary. Configured by a file (/etc/wvdial.conf) consisting of a number of “sections” containing parameters such as phone number and login name for each of possible several remote connections (ISP’s).
pppd options
The correct pppd options are probably the most important and most troublesome aspect of dial-up networking. Options may be specified in the global options file (/etc/ppp/options unless otherwise specified by file <filename> argument to pppd), the file .ppprc in the user’s home directory. the device-specific options file (/etc/ppp/options.<tty-name>, eg. /etc/ppp/options.ttyS0, …./options.modem, etc), or on the pppd command-line, and are processed in that order. Different distributions provide several configuration programs to insulate the user from the business of writing options files directly, however doing it yourself is very easy, more instructive and arguably more reliable.
Common options
- call <isp>
- read options from the file /etc/ppp/peers/<isp>. This is the simplest way to configure pppd for a number of remote connections. The file /etc/ppp/peers/<isp> will contain options specific to the remote host, /etc/ppp/options will contain options common to all connections. e.g.
pppd call uklinux
- device e.g. /dev/modem
- specify the device to communicate over
- user <username>
- use username to authenticate the local system to the remote
- demand
- enable demand dialing. pppd will configure the ppp device, but will not attempt to dial in to the remote system until it detects traffic trying to use the link. Certain classes of traffic may be ignore by use of the active-filter option (see man page for more details).
- idle <seconds>
- the link will be dropped of there is no traffic across it for the specified number of seconds.
- defaultroute
- add a default route via the remote system to the routing table when the link is established. This is almost always required for a home system using a dial-up link as its only internet connection.
- usepeerdns
- ask the peer to provide up to 2 DNS server addresses when the link is established. These are passed to the ip-up script as environment variables DNS1 and DNS2; ip-up can use these to configure the local resolver to use these nameservers. Usually only essential if your ISP’s nameserver addresses are not fixed.
- ipcp-accept-local
- ipcp-accept-remote
- allow the remote system to set the IP address of both our end and its end of the ppp link. Both are typically required as IP addresses are typically assigned dynamically by ISP’s (unless you have e.g. a Demon account with a static IP address assigned to you). (IPCP is the NCP specific to IP).
- connect <command>
- specify the command to be used to bring up the serial link. Typically this will be a chat or dip command.
- no-chap, no-pap
- refuse to authenticate using chap or pap, respectively.
- novj, noccp
- disable different compression schemes (maybe useful for debugging).
ip-up/ip-down scripts
These live in /etc/ppp also, and are run respectively when the IP connection is established and broken.
Authentication
ppp supports two authentication protocols, CHAP (challenge-handshake authentication protocol) and PAP (password authentication protocol). Each of the two communicating systems may be required to autenticate itself to the peer using either or only one of these protocols.
CHAP
CHAP is the more secure of the two authentication methods, as at no time is the password or secret transmitted over the link. The system demanding authentication sends a challenge string to the peer, which encrypts the challenge string using the secret as a key. The encrypted challenge is then sent back to the first system which decrypts it using its stored copy of the secret. If the decrypted version matches the original challenge then both systems used the same secret as the key and the authentication succeeds.
PAP
PAP is a more simple autentication scheme wherein one system authenticates itself to the other by sending an identifier/password pair, much like a user logging in to a Unix system with a user name and password. It is less secure than CHAP as the password is transmitted unencrypted and hence theoretically open to snooping if the link is compromised.
PAP and CHAP use secrets files in /etc/ppp to store authentication strings (/etc/ppp/pap-secrets and /etc/ppp/chap-secrets respectively). Both of these files have the same format, consisting of lines of the form user-id peer-system-name secret.
In general, systems will agree to authenticate using whichever scheme the peer system tries to use. The no-chap or no-pap options to pppd will cause it to refuse to use those protocols.
Examples
/etc/ppp/options:
# /etc/ppp/options # # Don't escape control chars asyncmap 0 # Enable hardware handshaking crtscts # Enable connect-on-demand demand # Drop link after 2 mins idle idle 120 # No default IP address noipdefault # Don't require remote system to authenticate itself noauth # Use ppp link as default route defaultroute # Accept local/remote IP addresses from remote system ipcp-accept-remote ipcp-accept-local # verbose debugging from ppp driver kdebug 7 # lock the serial device while link is up lock
/etc/ppp/peers/uklinux:
# device and line-speed to use /dev/modem 115200 # user name for authentication user shofar # specify chat script to bring up connection connect 'usr/sbin/chat -v -f /etc/ppp/chat-uklinux' # turn on pppd debug messages to syslogd debug
/etc/ppp/chat-uklinux:
ABORT BUSY ABORT "NO CARRIER" ABORT VOICE ABORT "NO DIALTONE" ABORT "NO ANSWER" "" ATZ OK ATDT08456621598 CONNECT ""
/etc/ppp/chap-secrets:
shofar.freeserve.co.uk * <my-password> shofar * <another-password>
/etc/ip-up:
#!/bin/sh # Pick up my mail from the ISP servers fetchmail -v # send any mail queued on the local system /usr/bin/sendmail -q
N.B. Using kdebug 7
option causes every frame to be logged by the ppp driver (usually to /var/log/debug); this not only generates voluminous log files but also slows down the driver – and hence the whole system. If you set this for debugging purposes, remove it as soon as things are working properly !
Similar chat-freeserve and /etc/ppp/peers/freeserve files exist for my freeserve account. Bringing up the link is simply a matter of
pppd call uklinux (or pppd call freeserve)
The demand option means that dial-up only happens when something actually wants to use the link.
In contrast, linuxconf on a RedHat 6.1 system uses 6 or 7 files and of the order of 100’s of lines of shell to configure a ppp connection – difficult to follow and debug if anything goes wrong.
Dial-up link as an internet gateway
A local-area network might well wish to use a machine with a dial-up connection as an internet gateway. There are (at least) two ways to approach this depending upon the level of access required from the LAN:
- Mail and WWW access only. Disable IP-forwarding on the gateway. Run a web proxy (squid, IJB or similar) on the gateway. All other machines on the LAN have their browsers set up to use the gateway as a proxy. Use fetchmail (run periodically as a cron job) to download mail periodically. Run pop server on the gateway, or mount /var/mail on clients via nfs. Set gateway as SMTP host for client mailers or use nullclient sendmail.cf files on client machines. On gateway run
sendmail -q
under cron periodically to send queued mail. In this scenario, no IP traffic is routed through the gateway machine. - Full internet access. Set up IP-masquerading on the gateway. All clients on LAN have default route set to gateway, and gateway as DNS server. Use defaultroute and usepeerdns pppd options (or run bind) on gateway.
Debugging
- Use debug and kdebug options to pppd and ppp respectively. These cause verbose logging thru’ syslog and klogd, which usually will end up in /var/adm/messages (or possibly /var/log/syslog, depending upon your distribution) and /var/log/debug respectively.
- Run tcpdump on the ppp interface (tcpdump -i ppp0) to look at IP traffic on the link (if you get the link up !).
- Usual networking utilities (netstat, ifconfig) will work on the ppp device once the IP link is up:
# ifconfig -a dummy Link encap:Ethernet HWaddr 00:00:00:00:00:00 BROADCAST NOARP MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 eth0 Link encap:Ethernet HWaddr 00:C0:F0:45:83:C9 inet addr:192.168.200.1 Bcast:192.168.200.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:655 errors:0 dropped:0 overruns:0 frame:0 TX packets:646 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:100 Interrupt:11 Base address:0x6100 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:3924 Metric:1 RX packets:1824 errors:0 dropped:0 overruns:0 frame:0 TX packets:1824 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 ppp0 Link encap:Point-to-Point Protocol inet addr:212.1.156.19 P-t-P:10.112.112.112 Mask:255.255.255.255 POINTOPOINT NOARP MULTICAST MTU:1500 Metric:1 RX packets:42 errors:0 dropped:0 overruns:0 frame:0 TX packets:50 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:10
Sample debug output (from /var/adm/messages):
Apr 11 20:47:15 moriah kernel: registered device ppp0 Apr 11 20:47:15 moriah pppd[410]: pppd 2.3.10 started by root, uid 0 Apr 11 20:47:15 moriah kernel: ppp_ioctl: set dbg flags to 10000 Apr 11 20:47:15 moriah kernel: ppp_tty_ioctl: set xmit asyncmap 0 Apr 11 20:47:15 moriah kernel: ppp_ioctl: set flags to 10000 Apr 11 20:47:15 moriah kernel: ppp_ioctl: set mru to 5dc Apr 11 20:47:15 moriah kernel: ppp_tty_ioctl: set rcv asyncmap 0 Apr 11 20:47:15 moriah pppd[410]: Using interface ppp0 Apr 11 20:47:15 moriah pppd[410]: local IP address 192.168.200.1 Apr 11 20:47:15 moriah pppd[410]: remote IP address 10.112.112.112 Apr 11 20:48:09 moriah pppd[410]: Starting link Apr 11 20:48:10 moriah chat[414]: abort on (BUSY) Apr 11 20:48:10 moriah chat[414]: abort on (NO CARRIER) Apr 11 20:48:10 moriah chat[414]: abort on (VOICE) Apr 11 20:48:10 moriah chat[414]: abort on (NO DIALTONE) Apr 11 20:48:10 moriah chat[414]: abort on (NO ANSWER) Apr 11 20:48:10 moriah chat[414]: send (ATZ^M^M) Apr 11 20:48:10 moriah chat[414]: expect (OK) Apr 11 20:48:10 moriah chat[414]: ATZ^M^M Apr 11 20:48:10 moriah chat[414]: OK Apr 11 20:48:10 moriah chat[414]: -- got it Apr 11 20:48:10 moriah chat[414]: send (ATDT08456621598^M) Apr 11 20:48:10 moriah chat[414]: expect (CONNECT) Apr 11 20:48:10 moriah chat[414]: ^M Apr 11 20:48:28 moriah chat[414]: ATDT08456621598^M^M Apr 11 20:48:28 moriah chat[414]: CONNECT Apr 11 20:48:28 moriah chat[414]: -- got it Apr 11 20:48:28 moriah chat[414]: send (^M) Apr 11 20:48:29 moriah kernel: ppp_ioctl: get unit: 0 Apr 11 20:48:29 moriah kernel: ppp_ioctl: set flags to 10000 Apr 11 20:48:29 moriah kernel: ppp_tty_ioctl: set xasyncmap Apr 11 20:48:29 moriah kernel: ppp_tty_ioctl: set xmit asyncmap ffffffff Apr 11 20:48:29 moriah kernel: ppp_ioctl: set flags to 10000 Apr 11 20:48:29 moriah kernel: ppp_ioctl: set mru to 5dc Apr 11 20:48:29 moriah kernel: ppp_tty_ioctl: set rcv asyncmap ffffffff Apr 11 20:48:29 moriah pppd[410]: Serial connection established. Apr 11 20:48:29 moriah pppd[410]: Connect: ppp0 <--> /dev/modem Apr 11 20:48:30 moriah kernel: ppp_tty_ioctl: set xmit asyncmap a0000 Apr 11 20:48:30 moriah kernel: ppp_ioctl: set flags to f010003 Apr 11 20:48:30 moriah kernel: ppp_ioctl: set mru to 5dc Apr 11 20:48:30 moriah kernel: ppp_tty_ioctl: set rcv asyncmap 0 Apr 11 20:48:30 moriah kernel: ppp_ioctl: set flags to f010043 Apr 11 20:48:30 moriah kernel: PPP Deflate Compression module registered Apr 11 20:48:31 moriah kernel: ppp_ioctl: set maxcid to 16 Apr 11 20:48:31 moriah kernel: ppp_ioctl: set flags to f01004f Apr 11 20:48:31 moriah fetchmail[418]: 5.1.2 querying pop.freeserve.net (protoco l POP3) at Tue, 11 Apr 2000 20:48:31 +0100 (BST)
Recommended Reading
- ppp-HOWTO, ISP-HOWTO, Serial-HOWTO
- /usr/doc/ppp-*/*
- man pages: pppd, chat, dip, wvdial
- The Crab Book – Hunt, Craig: TCP/IP Network Administration, O’Reilly.