Home Linux PPP Control Ringlord Technologies: Amiga/Java/Linux
  About     News     Products     Publications     People / Contact us     Links
All

JNI How-to

LaTeX-PDF How-to

Automating PPP

From PGP to GnuPG
 

Automating Linux PPP

Copyright © 2001 RingLord Technologies and Udo K. Schuermann
All rights reserved
Revised: 3-October-2001

Click here for a printer-friendly copy of this document

What's This?

Most ppp dial-out tools shipped with Linux these days require relatively little effort to set up and get running. It's with the fine-tuning and the customization beyond what these tools were designed to do that I have run into limitations. As a result I ``went back to basics'', abandoning the fancy GUI stuff and resorting to the pppd and chat programs to accomplish what I needed.

With this document I hope to explain how you, too, can set up an automated and easily controlled ppp dial-up link. In the process you will come to understand that there is no magic and no mystery to a ppp dial-up link: it's quite simple actually, and even easy to understand!

Based on my own needs, this document demonstrates. . .

  1. How to configure and run pppd and chat to establish a ppp dial-up link,
  2. How to automatically redial/re-establish an unexpectedly terminated connection,
  3. How to schedule (using cron) the automated dialing and shutdown of the link.
  4. How to override the scheduled dialing and especially the shutdown,

The following are worth mentioning:

  • You need to have root access on your machine to be able to modify the system's /etc/crontab file (for scheduling the dialing and shutdown); if you do not have root access then your system administrator must have made it possible for you to run the pppd and chat programs, as well as access the serial port. If that happens to be the case you could use the crontab command to configure your own cron schedule, and use a different set of directories to create the scripts presented here.
  • I duplicate some information from the ``PPP HOWTO'' document, but only enough to serve as a concrete example. It falls to you to be able to figure out whether your ISP uses PAP, CHAP, MSCHAP, or scripting authentication to establish the ppp link.
  • The pppd and chat programs should be available on any Linux system; They are certainly shipped with the Redhat 6 and Redhat 7 distributions, but are so general that I expect them to be widely(!) available. Both programs should be documented in section 8 of the online manual (try ``man 8 pppd'' and ``man 8 chat'', although the ``8'' should not be necessary).
Table of Contents
  1. Standard Stuff: The /etc/ppp/ directory
    1. The /etc/ppp/ppp-myisp.conf file
    2. The /etc/ppp/ppp-on script
    3. The /etc/ppp/options file
    4. The /etc/ppp/ppp-on-dialer script
    5. The /etc/ppp/ppp-off script

  2. Extra Cheese: The Fun Bits
    1. The /usr/local/bin/ppp-up script
    2. The /usr/local/bin/ppp-down script
    3. The /etc/crontab entries
    4. The /etc/ppp/ip-up.local script

  3. Controlling the Beast

Standard Stuff: The /etc/ppp/ directory

The /etc/ppp/ directory contains most (or all, if you choose) our scripts and configuration files for the ppp link. Here is what I have there. The files created, modified, or otherwise of interest are highlighted as well as commented:

chap-secrets   
ioptions   
ip-down   
ip-up   
ip-up.local    Executed each time the link is established
options    The majority of options to configure pppd are stored in this file
pap-secrets   
peers/   
plugins/   
pppoe.conf   
pppoe-server-options   
ppp-off    A script to shutdown the connection (kill pppd)
ppp-on    A script to bring up pppd to dial out and establish the link
ppp-on-dialer    The script to establish the ppp connection with your ISP
ppp-myisp.conf    The ISP-specific information
resolve.conf   

The /etc/ppp/ppp-myisp.conf file

It may be helpful, at least in the future, to separate out the settings that are definitely different from one ISP to another. It's debatable whether this is really necessary at this point, but I'm myself working towards being able to dial out to a choice of more than one ISP. For whatever it's worth this file summarizes the type of information I would need to save if I wanted to get a PPP running on a windoze box, for example:

The /etc/ppp/ppp-myisp.conf File
TELEPHONE=5551212       # The telephone number to dial
ACCOUNT=mylogin         # The account name with your ISP for logon
PASSWORD=mypassword     # The password for this account
You need to alter the text in italics to match your own ISP setup

The above simply sets three shell variables (TELEPHONE, ACCOUNT, and PASSWORD); the ppp-on script sources this config file to cause these variables to be set.

The /etc/ppp/ppp-on script

In order to being the ppp link up, we could simply execute the following script using the command /etc/ppp/ppp-on & but we'll get around to something niftier once we have this script in place:

The /etc/ppp/ppp-on File
#!/bin/sh
#
# Script to initiate a ppp connection. The dialing script creates a temporary
# file into which it writes sensitive information (login name and password) so
# that information cannot be snooped by other system users unless they have
# access to the /etc/ppp/ directory. . .
#
#
# This script must set TELEPHONE, ACCOUNT, and PASSWORD variables
. /etc/ppp/ppp-sprint.conf
if [ -z "$TELEPHONE" -o -z "$ACCOUNT" -o -z "$PASSWORD" ]; then
    echo "ERROR: Some or all of TELEPHONE, ACCOUNT, and PASSWORD are not set"
    exit 0
fi
# These are the parameters. Change as needed.
LOCAL_IP=0.0.0.0        # Local IP address if known. Dynamic = 0.0.0.0
REMOTE_IP=0.0.0.0       # Remote IP address if desired. Normally 0.0.0.0
NETMASK=255.255.255.0   # The proper netmask if needed
#
# Export the stuff needed by the 'ppp-on-dialer' script
export TELEPHONE ACCOUNT PASSWORD
#
# This is the location of the script which dials the phone and logs
# in.  Please use the absolute file name as the $PATH variable is not
# used on the connect option.  (The use of a potentially user-alterable
# $PATH by a root-priviliged program would be a security hole).
#
DIALER_SCRIPT=/etc/ppp/ppp-on-dialer
#
# Initiate the connection
#
# The majority of the options are stored in the /etc/ppp/options file,
# which is the first config file that that pppd looks for.
#
exec /usr/sbin/pppd /dev/modem 115200 \
        $LOCAL_IP:$REMOTE_IP \
        netmask $NETMASK \
        connect $DIALER_SCRIPT

Note: ``115200'' is the connection rate between modem and computer. Even though a connection may be only 31.2k (31200 baud, about 3 kb/sec) plain text can be compressed significantly and could come in at speeds in excess of 5 kb/sec. If I were to configure the serial port to communicate at a speed less than 5 kb/sec I might throttle connections that could otherwise provide me with much higher throughput!

Note 2: /dev/modem is simply a symlink that I made to my /dev/ttyS1 device. Your physical serial port maybe something other than /dev/ttyS1 and you may even find a /dev/modem already configured on your computer.

The /etc/ppp/options file

The /etc/ppp/options file is the configuration for pppd; pppd looks for its configuration in several places and /etc/ppp/options is the first place. What is specified in this file needs not be given on the command line.

The /etc/ppp/options file
# Prevent pppd from forking into the background
-detach
 
# Use the modem control lines
modem
 
# use uucp style locks to ensure exclusive access to the serial device
lock
 
# use hardware flow control
crtscts
 
# ask the ISP to supply us with one or two DNS servers; these values
# will be written to /etc/ppp/resolv.conf and also passed as DNS1 and
# possibly DNS2 to the /etc/ppp/ip-up scripts.
usepeerdns

# create a default route for this connection in the routing table; if you
# have another network (home network, for example) where a default route
# exists then you MUST NOT add another default route! There must not be
# more than one default route.
defaultroute

# do NOT setup any "escaped" control sequences
asyncmap 0
 
# use a maximum transmission packet size of 552 bytes
mtu 552
 
# use a maximum receive packet size of 552 bytes
mru 552
 
# Terminate the connection after it has been idle (no traffic) for some time
#       idle 300
 
# Dial out on demand when the line is down and traffic is looking to go out
#       demand

Note: The ``idle'' and ``demand'' options are commented out: demand dialing requires that you have an IP address that is known before you dial out (which also implies that the route is already setup so that the proper interface (ppp0) is ``woken up'' to start the redialing. Unless you have demand dialing enabled you probably want automatic shutdown of the connection disabled (the ``idle'' option).

The /etc/ppp/ppp-on-dialer script

This script is invoked by pppd to control the actual dialing and authentication. Notice that it is essentially all one long command line (conveniently broken up over multiple display lines using the \-escape symbol at the end of each display line to prevent the line terminator from being interpreted as a command terminator.

The script will react to BUSY, NO ANSWER, and to multiple RINGING indicators (the latter one would be caused by someone calling you on your dedicated(?) computer line, so you don't necessary want your modem to answer that call (quite yet).

Also, the shell variables TELEPHONE, ACCOUNT, and PASSWORD are used herein:

The /etc/ppp/ppp-on-dialer script
#!/bin/sh
#
# This script performs the login authentication with your ISP. Notice that we're
# creating the file /etc/ppp/ppp-chat on the fly; if we passed account/password
# parameters on the command line (which is certainly possible) a savvy user on
# our network could snoop ps(1) to view the chat program's command line parameters
# and discover the login/password at our ISP's. Use of a script avoids that risk.
#
cat >/etc/ppp/ppp-chat <<EOF
        TIMEOUT         3
        ABORT           '\nBUSY\r'
        ABORT           '\nNO ANSWER\r'
        ABORT           '\nRINGING\r\n\r\nRINGING\r'
        ''              \rAT
        'OK-+++\c-OK'   ATH0
        TIMEOUT         30
        OK              ATDT$TELEPHONE
        CONNECT         ''
        ogin:--ogin:    $ACCOUNT
        assword:        $PASSWORD
EOF
exec /usr/sbin/chat -f /etc/ppp/ppp-chat

The /etc/ppp/ppp-off script

The /etc/ppp-off script
#!/bin/sh
######################################################################
#
# Determine the device to be terminated.
#
if [ "$1" = "" ]; then
        DEVICE=ppp0
else
        DEVICE=$1
fi
 
######################################################################
#
# If the ppp0 pid file is present then the program is running. Stop it.
if [ -r /var/run/$DEVICE.pid ]; then
        kill -INT `cat /var/run/$DEVICE.pid`
#
# If the kill did not work then there is no process running for this
# pid. It may also mean that the lock file will be left. You may wish
# to delete the lock file at the same time.
        if [ ! "$?" = "0" ]; then
                rm -f /var/run/$DEVICE.pid
                echo "ERROR: Removed stale pid file"
                exit 1
        fi
#
# Success. Let pppd clean up its own junk.
        echo "PPP link to $DEVICE terminated."
        exit 0
fi
#
# The ppp process is not running for ppp0
echo "ERROR: PPP link is not active on $DEVICE"
exit 1

Before continuing with the next section, please ensure that the following command establishes a connection with your ISP (and sets the correct default route; see /sbin/route):

/etc/ppp/ppp-on &

and that this command shutsdown the link, causing the previous command to terminate:

/etc/ppp/ppp-off

If these aren't working, please refer to the ``Linux PPP-HOWTO'' (Redhat maintains a copy of it) and work out the problems until these scripts are working. The preceding is entirely based on that document; the stuff below requires that the above is working.

Extra Cheese: The Fun Bits

You now have a way of bringing up and shutting down a ppp link with a script, but that's nothing more than what most GUI tools offer. The real fun starts below, where we'll construct interrelated scripts to. . .

  1. Bring up the link and cause it to redial immediately if pppd terminates (because the line was dropped),
  2. Bring the link up and shut it down according to a certain schedule,
  3. Override the scheduled manipulation of the ppp link,
  4. Execute some commands as soon as a connection is established.

The /usr/local/bin/ppp-up script

This script enhances the functionality of the /etc/ppp/ppp-on script that we constructed in the preceding section. We rely on the fact that /etc/ppp/ppp-on will not exit (because pppd won't exit) until the connection with the ISP is broken. At that point the /usr/local/bin/ppp-up script regains control and we can decide whether the termination was a scheduled activity or an unscheduled interruption of communications:

The /usr/local/bin/ppp-up script
#!/bin/sh
 
# REDIAL_DELAY should be 0 to redial immediately or a number of seconds
# before redialing is initiated to re-establish the broken connection
REDIAL_DELAY=0

while [ 1 ]; do
    if [ -e /etc/ppp/.nwstaydown ]; then
        echo "ERROR: ppp link stays down so long as /etc/ppp/.nwstaydown exists"
        exit 1
    elif [ `/sbin/route -n | grep ppp0 | wc -l` -gt 0 ]; then
        echo "NOTE: ppp link is already up according to router table"
        exit 0
    fi
 
    # bring the ppp link up as requested
    /etc/ppp/ppp-on
    if [ -e /etc/ppp/.nwforcedown ]; then
        echo "ppp link forced down"
        rm -f /etc/ppp/.nwforcedown
        exit 0
    else
        echo "WARNING: ppp link terminated unexpectedly; trying to re-establish"
        if [ ! "$REDIAL_DELAY" -eq 0 ]; then sleep $REDIAL_DELAY; fi
    fi
done

You will notice that the script checks at different times for the presence of two files: /etc/ppp/.nwstaydown and /etc/ppp/.nwforcedown; When invoked as part of a scheduled operation to establish a connection (we'll get to the scheduling part below) we could force the network connection not to be established if we create the file /etc/ppp/.nwstaydown.

The /etc/ppp/.nwforcedown file is created by the next script, the one that we use to bring the link down. That file's existence signals us that the shutdown of pppd was intended rather than accidental. We'll just clean up that file and exit.

The /usr/local/bin/ppp-down script

This script enhances the functionality of the /etc/ppp/ppp-off script that we constructed earlier. This script acts in concert with /usr/local/bin/ppp-up by creating the /etc/ppp/.nwforcedown file so that /usr/local/bin/ppp-up knows that the shutdown of pppd was intentional:

The /usr/local/bin/ppp-down script
#!/bin/sh
 
if [ -e /etc/ppp/.nwstayup ]; then
    echo "WARNING: ppp link stays up so long as /etc/ppp/.nwstayup exists"
    exit 0
elif [ `/sbin/route -n | grep ppp0 | wc -l` -eq 0 ]; then
    echo "ERROR: ppp link is already down according to router table"
fi
 
# the /root/ppp-up script stops the redialing and exits when pppd exits
# and it sees this file
touch /etc/ppp/.nwforcedown
# kill the pppd
/etc/ppp/ppp-off

The presence of the file /etc/ppp/.nwstayup effectively prevents this script from shutting down the link. This is useful to me when I know that the scheduler will take down the link in a few minutes but I still have a download running that I do not want interrupted, or if I want to keep the link up indefinitely for some reason.

The /etc/crontab entries

As mentioned on numerous occasions above, I like to ensure that my home network is connected to the internet during certain hours of the day. Some in our family get up earlier than I, so this ensures that they don't need to wake me up to connect them. It also ensures that email that has been waiting in their mailbox at our ISP's is delivered by the time they get to the computer. No long delays, no inconveniences. It also means that I can go on vacation and don't have to worry that the bloody spammers fill up my mailbox and cause legitimate and important email to bounce:

The /etc/crontab entries
30 0 * * 1,2,3,4,5 root /usr/local/bin/ppp-down
30 7 * * 1,2,3,4,5 root /usr/local/bin/ppp-up
30 1 * * 6,7       root /usr/local/bin/ppp-down
0  9 * * 6,7       root /usr/local/bin/ppp-up
Only root can alter the /etc/crontab file

Unless you're familiar with cron(1) you will probably wonder what the heck you are looking at with those four cryptic lines. Let me explain: There are seven (7) fields on each line. The first five refer to a time, the 6th is a uid, and the 7th (and everything else beyond it) is a command to execute. The five time fields are: minute (0-59), hour (0-23), day of month (1-31), month (1-12), and day of week (0-7; 0 or 7 is Sunday). And asterisk (*) means everything.

  1. On Monday, Tuesday, Wednesday, Thursday, and Friday early morning (12:30 AM) the link is shutdown.
  2. On Monday, Tuesday, Wednesday, Thursday, and Friday mornings (7:30 AM) the link is established.
  3. On Saturday and Sunday the link is shutdown at 1:30 AM.
  4. On Saturday and Sunday the link is established at 9:00 AM.

This translates to the following pattern:

  • The link is established on working day mornings at 7:30 AM and shutdown again at 12:30 AM if it's not a working day (late Friday night, past midnight, it's actually Saturday already, so don't let the days confuse you).
  • The link is established on weekend mornings at 9:00 AM and shutdown again at 1:30 AM if it's not a working day.

The recipe above is easy to adjust if you shutdown the link after midnight (in the wee hours), otherwise you'll have to work out your own scheduling. It doesn't know about holidays or days off from work. :-)

The /etc/ppp/ip-up.local script

The /etc/ppp/ip-up.local script is executed once the link is established. Since I dial out approximately once a day and redials are relatively rare, I run rdate(1) against a time server to synchronize my system's clock. All the machines on my network then synchronize against my router/gateway. In addition to that I update a static name with my dynamic address so that I can easily find my network at home from anywhere on the internet.

It should go without saying that a firewall setup (ipchains or iptables) is a basic precaution that any networked computer should have installed. Further, telnet and ftp should be replaced with ssh (which also supplies scp for secure file copying). Leaving a network unprotected is risky. But this is not the place to teach you about basic network security. Suffice to have made you aware of it if you weren't already.

Here is an example /etc/ppp/ip-up.local script that may serve you. Of special note is the fact that I'm manipulating the existing /etc/resolv.conf file that primarily supplies to the network subsystem a list of DNS (Domain Name Server) hosts. The script below presumes that you've two name servers operating within your own network (perhaps passive caching servers); it keeps all lines from the existing /etc/resolv.conf file that are not nameserver entries, then adds the name servers obtained from your ISP and then a list of your local name servers. It then ensures that the file is world readable and its permissions and ownership are correct. Just in case. . . can't hurt, right? And finally I trigger sendmail to retry all pending transmissions.

The /etc/ppp/ip-up.local script
#!/bin/bash

### create the resolv.conf
grep -v 'nameserver' /etc/resolv.conf >/tmp/new-resolv.conf
cat /etc/ppp/resolv.conf >>/tmp/new-resolv.conf
cat >>/tmp/new-resolv.conf <<EOF
nameserver 10.1.8.17
nameserver 10.1.0.24
EOF
/bin/chmod go=r /tmp/new-resolv.conf
/bin/chown root:root /tmp/new-resolv.conf
### make it current:
mv /tmp/new-resolv.conf /etc/resolv.conf
/bin/chmod go=r /etc/resolv.conf
/bin/chown root:root /etc/resolv.conf

### Process email that's been waiting (overnight) in the queue
/usr/sbin/sendmail -q &

exit 0

Controlling the Beast

Once you have created the various scripts and added the appropriate entries into /etc/crontab (try man 5 crontab for more details on the file's format) your internet connection should be quite persistent while still giving you some control over the whole thing:

Keeping the link up despite the scheduler's attempt to shut it down:
touch /etc/ppp/.nwstayup
The /usr/local/bin/ppp-down script will detect the presence of that file and exit without killing pppd.

Restoring normal scheduled shutdowns
rm -f /etc/ppp/.nwstayup
The next attempt by the scheduler to shutdown the link will once again check for that file and, if it has not been re-created the link will be shutdown.

Shutdown the link immediately
rm -f /etc/ppp/.nwstayup ; /usr/local/bin/ppp-down
See (2) above.

Keep the link from coming up in the morning
touch /etc/ppp/.nwstaydown
The /usr/local/bin/ppp-up script will detect the presence of that file and not bother starting the link. If the link is currently up then it is shutdown the next time the connection is broken for any reason (even an accidental disconnect).

Disable the redialing capability but keep the link up for now
touch /etc/ppp/.nwstaydown The next time that the link terminates (perhaps an unforeseen disconnect) the /usr/local/bin/ppp-up script will exit upon seeing this file and not initiate a redial.

Bring up the link immediately (also resumes redialing capability)
rm -f /etc/ppp/.nwstaydown ; /usr/local/bin/ppp-up &
See (3) above.

The stuff above works for me. I don't know if it will work for you. It's simple enough that the failure points are few and debugging should be fairly straight-forward; to me it seems that this should certainly be easier to figure out than how to make some other tool work whose inner workings I do not understand and which isn't even geared towards automated operations.

  Made With WebLordCopyright © 1997,1998,1999,2000,2001,2002,2003 Ringlord Technologies
The alteration of any part of this content by manual or automated means (adding, removing, or in any other way altering links, text, or images) constitutes misrepresentation of our content in violation of United States copyright law. For more details, please see our content ownership details page for elaboration.