Table of contents

Credits

The original version of this document was based partly on my experience and experimentation, and partly on two earlier guides:

  1. Cables-DHCP-PPTP HOWTO by Amir Tal (Whatsup) and Meir Kriheli (MKsoft Systems).
  2. L3ECH's cable internet connection guide for Israeli Linux users.

My gratitude is extended to those three authors, as well as to others who have helped me with ideas and suggestions for improvement, translation and update of the guide: The members of the Haifa Linux Club mailing list, as well as to Shlomi Loubaton and Orna Agmon, for their help. A special thank-you goes to Barak Korren for many a round of review and discussion of various points.

Introduction

One day I get this e-mail from my 'kind' provider (at that time), Internet Zahav, saying:

Dear client,

(blah blah blah) soon all Internet Zahav clients connected through Matav will be switched over to using dialers (read: connection by VPN) this switch is made for reasons of (hold on to your shorts!) information security and ethical use of the Internet. The dialer will allow you to enjoy a higher level of service and support, and advanced Internet services. To your knowledge, starting at 2003-01-12, it will no longer be possible to connect to the Internet without the use of the dialer (read: other than finding your own way to connect to our VPN/s) blah blah blah, respectfully, blah blah.

At this stage I burst into a series of curses which I will not repeat here. The situation got no better when Tech Support told me that if I had Linux then, well, it's my problem...

Well, since then, a lot of water has been passed under bridges and onto cable network clients, and I have successfully configured PPTP access for connecting to several different ISPs, and what is perhaps more important, have discovered the following:

It is not, in fact, required to use PPTP to access the ISPs over the cable infrastructure. The setting 'VPN access/direct access' is made in some sort of per-client configuration file held by the cable infrastructure provider; the setting cannot be changed by you, but can be changed by your ISP, if they want to.

Some further explanation is in order. During the initial, semi-experimental period of Internet-over-cables in Israel, the cable providers and the ISPs chose to implement a simple scheme for managing end-user connections:

Now, ISPs decided they don't like this way of doing things, for three reasons:

  1. The ISP has no way of knowing whether your connection is up or not, except by sniffing your packets, something which for some reason they aren't really able to do well enough in tech support.
  2. The ISP 'loses' that address block and can't reclaim some of it dynamically when only part of the end-users are connected.
  3. Since the ISP is not the one doing the DHCP serving, it is not able to associate your network traffic with you - yes, boys and girls, your non-VPN connection allows you partial anonimity (at least until the ISP gets the logs from the cable provider, which is possible, but perhaps not all that immediate; it might even require a court order, although experience with the Israeli judicial system would not lead me to bet on that).

The elegant, simple and reasonable solution to these issues was, of course, to have the cable providers' DHCP servers forward a user's DHCP request to the DHCP server of that user's associated provider. But heavens forbid that they should adopt such a solution. Instead they opted for clunky VPNs; alas...

Still, over the past 2 years, I have switched ISPs several times, and have managed to pressure the customer service or sales reps of various ISPs to let me connect using a direct connection rather than a VPN. They simply have to pass a different setting value to the cable provider in their client update file. However, recently it has become difficult to convince ISP to let you connect this way.

PPTP, L2TP, PPPoE

PPTP stands for Point-to-Point Tunneling Protocol. It's a proprietary protocol developed by Microsoft. Some PPTP links:
http://pptpclient.sourceforge.net/
The Linux PPTP client binaries, and a lot of documentation on this client; some of it is a bit confusing like the part on MPPE and what exactly you're supposed to do to get that working. Actually I don't think that MPPE stuff should interest you at all.
http://pptpclient.sourceforge.net/diagrams.phtml
A nice graphical description of what a PPTP connection 'looks' like

L2TP stands for Layer 2 Tunneling Protocol. The protocol is open, but its Linux implementation is still in an early phase. This is a PPTP HOWTO, not an L2TP HOWTO, but if you do want to brave the odds and try setting up a L2TP VPN connection, here are a few words of advice (this is intended for the more knowledgable):

Unlike the available PPTP client, for which you can make the PPP daemon run the PPTP client binary as a helper, this is not yet possible with l2tpd, so you'll be having the L2TP daemon run the PPP daemon. You still need to have a PPP options file and secrets file, on which you'll find useful information below, but there's another, separate, configuration file for l2tpd. Furthermore, l2tpd is multiple-connection-oriented, and thus you cannot connect using just the static configuration – l2tpd is controlled using a named pipe: /var/run/l2tpd-control (you'll see this in the documentation, although it is really cryptic). This means you'll probably have l2tpd running on boot regardless of whether or not you're connected, and then modify the pon and poff scripts to check whether the connection passed to them is an L2TP connection, in which case instead of running pppd they would echo the relevant control message/s to the L2TP daemon control pipe. You should also check whether l2tpd-run pppd also executes the ip-up.d/ scripts on connection (again, see below for details).

Some L2TP links:

http://www.l2tpd.org/
The Linux L2TP client/daemon home page
http://sourceforge.net/projects/l2tpd
Sourceforge page for that same client/daemon
ftp://ftp.isi.edu/in-notes/rfc2661.txt
The L2TP RFC (i.e. the official definition of the protocol)
http://mia.ece.uic.edu/~papers/volans/l2tpd.html
Detailed walk-through of setting up a sample L2TP VPN
http://www.l3ech.net/~l3ech/cables_linux_l2tp.php
l3ech's guide for setting up an L2TP VPN connection to your ISP; unelegant, due to the currently poor design of the L2TP client
PPPoE stands for Point to Point Protocol over Ethernet . This is another variety of the VPN concept which combines the two well-established protocols/protocol-sets, PPP and Ethernet. Some PPPoE links:
http://www.suse.de/~bk/PPPoE-project.html
The 'Whole World' of PPPoE on Linux
http://www.carricksolutions.com/pppoe.php
A PPPoE FAQ
www.roaringpenguin.com/pppoe/
The Roaring Penguin PPPoE client
http://www.penguin.org.il/guides/linux-pppoe-rh
A guide in Hebrew for PPPoE using RedHat's graphic interface, by Yariv Graf

VPNs at Israeli ISPs

PPTP is used by all ISPs (AFAIK) to provide access over cable connections; in the past this was also the case for ADSL, but I am told Israeli ISPs are adopting PPPoE these days for their ADSL clients.

http://www.mulix.org/adsl-howto.txt
This is a highly informative HOWTO on ADSL issues, both hardware and software, featuring prominently the issue of PPTP
http://www.adsl.org.il/
A windows-oriented site for ADSL users in Israel

Up until late 2002, connections over the cable infrastructure were done in the normal, tunnel-less, stateless, way – each client's packets were routed to his/her provider's machines, which routed them out into the rest of the internet (also, each client got an IP address by DHCP from a range which matched his/her own provider). In 2003, however, the ISP's have decided to switch their cable clients to connection via VPN.

http://www.cables.org.il/
A windows-oriented site for cable internet users in Israel
http://www.matav.co.il/
Matav cable access provider
http://www.aztv.co.il/
Arutzei Zahav cable access provider
http://www.tevel.co.il/
Tevel cable access provider
http://www.whatsup.org.il/doc/CABLES-DHCP-PPTP-HOWTO.html
Amir Tal's HOWTO, the partial basis for this text

I have thought long and hard about what possible reasons an ISP could have for switching people to VPN, and the only thing I could come up with is the option of quickly and easily disconnecting them from the Internet without having to perform complex manipulations of the routing mechanism: in order to prevent people from staying on-line and providing uninterrupted services or carrying out uninterrupted transactions, or in times of high load, in which the provider wishes to kill the unworthy users and look after the worthy (i.e. high-paying) users, they will now be able to do so and blame you for breaking the (stateful) PPTP connection. As more times passes from my first successful PPTP connection over cables, I experience these 'malfunctions' rather often – and through no fault of my own.

A note: in the past, the official PPTP client did not support some quirks of the Bezeq communications equipment, and a modified version was created by Muli Ben-Yehuda from mulix.org; it is no longer necessary to use this even for ADSL (see the ADSL-HOWTO), and it was probably never necessary where the cable infrastructre is concerned. Just in case you were wondering.

"So which is it, PPTP, L2TP or PPPoE?"

Short answer: As far as Linux users who don't feel like going over the source of l2tpd and trying to grok taps of connections to some L2TP gateway are concerned, it's PPTP.

Long answer: Some providers are using both L2TP and PPTP (Internet Zahav is, anyway); their tech support has suggested that they support PPTP so as to allow people with older operating systems (e.g. Windows 95/98) to connect. Thus their dialers for Win95/98 use PPTP, and the dialers for, say Win2k/XP uses L2TP. I have had some unsuccessful attempts making an L2TP connection; if you are interested in working on this problem – that's great! Post your results somewhere we can see them.

Prerequisites for PPTP over Cables Connection Setup

OK, so you want to get started with setting up your PPTP over cable internet connection... you will first need

Fair knowledge of Linux

Good to have generally. I wouldn't recommend tinkering with network connections until you've messed around with your Linux enough to know what you're doing. Specifically, familiarize yourself with Linux networking and DHCP.

A tame working Linux box

This may seem trivial, but make sure you don't have any weird processes doing network stuff in the background, no unknown cron tasks which have to do with the network and may screw up your connection, etc. Also, your Linux kernel must be compiled with PPP support and without disabling any default networking abilities (well, maybe you could disable some of them, but I can't list which exactly are the bare necessities).

The iproute (a.k.a. iproute2) Package

The scripts in this howto assume you have /bin/ip installed. This is one of the networking control tools that are a part of a package called iproute (a.k.a. iproute2 in some distributions; look ip up). It is not always installed by default, but it does always come with the distribution. So have it installed. If /bin/ip can run, then you're ok.

A PPTP client

Some distributions may have one, others may not; and it is often not installed by default. If you don't have one (consult your distributions package system), get one as a package of your distribution (for Debian, it's pptp-linux; it may not be auto-installed by default, so you have to specifically install it); alternatively, follow one of the links mentioned above. Note it is assumed below the PPTP client binary is /usr/sbin/pptp.

An up-and-running connection to the cable network

You should have an ethernet connection to the cable modem, either using an ethernet NIC (a 'network card'), or using a USB cable, and a virtual ethernet connection over this USB link. Establishing such a connection is not covered in this HOWTO.

Make sure you get an address via DHCP (having trouble? Read the DHCP-HOWTO), have a proper routing table, have the addresses of the cable provider's DNS servers, and can communicate (e.g. ping) with those servers. If you're automating the PPP connection, note where an ifup ethX, an ifconfig ethX or an ip link set ethX up command, or something similar, gets run (for a connection to the cable network on interface ethX). In Amir Tal's HOWTO, the script used goes as far as downing the interface, then re-upping it again (e.g. ifup eth0 ; ifdown eth0) before making the PPTP connection; but don't do this unless you think you really have to.

The address and/or domain name of the PPTP server of your ISP

This table is updated only occassionaly, but the data should be mostly valid:

Provider Name Provider PPTP Code PPTP Server Name
ActComActcompns4.actcom.net.il
Aquanet?cable.aquanet.co.il
Barak 013Barakpns.barak.net.il
Bezeq InternationalBezintcables.bezeqint.net
Golden Lines 012 (Kavei Zahav)Kzahavaztv.012.net.il
Internet Gold (Internet Zahav)Inzahavpns.inter.net.il
IsraServIsraservsurf.israserv.net.il
NetVisionNetvisioncable.netvision.net.il
TechnionN/Accdis3.technion.ac.il

Notes:

Setup

General description

Following are instructions for setting up one PPP connection using PPTP. Advanced users wishing to set up multiple PPP connections, some of them with PPTP, may also use these instructions, but with various necessary modifications of scripts (routing, firewall, etc.). We shall assume our connection is to an ISP called 'Yosefcom Internet Services' (for naming consistency throughout the HOWTO).

The program doing most of the dirty work will be pppd. pppd is the PPP (Point-to-Point Protocol) daemon; it provides a network interface by communicating over a serial 'line'; in our case the 'line' will be the connection (over the cable network interface) to the PPTP server.

What basically happens when you want to connect to your ISP is that you (or some automated process on your system), execute the commmand pon yosefcom; this runs the pon script. This script runs pppd. pppd will use the 'yosefcom' set of options, and will run the command specified for the pty option to set up the 'line'. pppd will then negotiate a PPP connection over this 'line', using the rest of the 'yosefcom' options, as well as a password for your user at Yosefcom Internet Services, which is stored separately from other options. After the connection is set up, pppd will cause all scripts in your distribution's ip-up.d/ directory to run. These might be general-purpose scripts, or scripts which are specific to the connection to Yosefcom.

Sounds complicated? Well, it is, sort of, but would it have been better to have one really long script which is very system-specific and difficult for maintainers and administrators to handle? Probably not. Plus, you only need to set this up once, then it's just pon yosefcom to connect and poff yosefcom to disconnect, and probably not even that if you call these automatically at startup (we'll get to that later on).

Static routes on the cables network segment

Our first task is to make sure that, no matter what happens, the IP packets you're sending to your ISP's PPTP server (and to your cables DHCP server) never get sent by mistake over the PPP interface instead of over its underlying ethernet interface. To ensure this we will set specific routing table entries for these two servers whenever the ethernet interface to the cables LAN network comes up. In Debian 3.0/3.1, edit your /etc/network/interfaces file. The cables ethernet interface (e.g. eth0) should have a block beginning with the lines
iface cables ethernet interface inet dhcp
possibly followed by lines with interface-specific options. To this block of options add the line
        up ip route replace your ISP's PPTP server IP dev cables ethernet interface
        up ip route replace cables DHCP server IP dev cables ethernet interface

With other distributions use whatever scripting mechanism is available to run the following two commands after the cables ethernet interface is up, and before starting the VPN connection to your ISP:

ip route replace your ISP's PPTP server IP dev cables ethernet interface
ip route replace cables DHCP server IP dev cables ethernet interface
The PPTP server IP is the one you located in the table above for your ISP; the cables' DHCP however, is a little trickier. Here's a script called dhcp-server-of-if, which takes as an argument the name of an ethernet interface configured by DHCP (e.g. eth0) and returns the address of the DHCP server:

#!/usr/bin/perl

#for Debian 3.1:
$lease_file = "/var/run/dhclient.$ARGV[0].leases";
#for Debian 3.0:
#$lease_file = "/var/lib/dhcp/dhclient.leases";

exit 1 unless ( $#ARGV == 0 );
$/ = '}'; # lease records are of the form "lease { etc. etc. }", but with line breaks
open( LEASES, '<', $lease_file ) || exit 1;
while (  ) {
        if ( /$ARGV[0]/ ) {
                # this is a lease for our interface, locate
                # the DHCP server address within it
                /(.|\n)*dhcp-server-identifier (.*);(.|\n)*/;
                $dhcp_server = $2;
        }
}
# we assume the last lease for our interface is the valid one
print "$dhcp_server\n";

This script works on Debian 3.1 systems ; with a different lease file perhaps, it will work for any system using dhclient as the DHCP client. If your system uses the pump DHCP client, try the following dhcp-server-of-if:

#!/bin/sh
pump -i "$1" -s | grep "Boot server" | cut -d ' ' -f 3

The point is to find out where the address is stored - which is usually within the record of the current DHCP lease, and to figure out which field in the lease contains the DHCP server address.

A note to advanced users: You may be asking yourself: "Why not just do all this route-setting in pppd's ip-up.d scripts?" Indeed, in earlier versions of this guide that was my choice , but then it was pointed out to me that in some cases, the peer's IP is the same IP as that of the PPTP server; and since pppd adds a route to that IP through the PPP interface, in the period of time between the addition of this route and the running of the ip-up.d script, the route to the PPTP server is invalid, and the connection may break off. Unfortunately, pppd only has a 'pre-up' script mechanism starting with version 2.4.4. Although you could use a wrapper around the pptp binary to set up these routes, it still makes more sense to just always have them – it's not as though they become invalid at any time.

The PPP daemon's pap-secrets file

pppd supports two types of authentication, called 'PAP' and 'CHAP'. Israeli providers use PAP.

The pppd 'secrets' file for PAP authentication, named /etc/ppp/pap-secrets, should contain (possibly among other entries) either the line:

your ISP-provided username@Cyour ISP's code  your ISP PPTP server IP  "your ISP-provided password"

or the line:

your ISP-provided username  your ISP PPTP server  "your ISP-provided password"

Notes:

The PPP daemon provider-specific options file

pppd's default options are located in a file named /etc/ppp/options. But we won't be using these! pppd also has a options directory – /etc/ppp/peers – with per-peer option files (the 'peer' is the entity you connect to using PPP).

A recommended basic options file, which you can create as /etc/ppp/peers/yosefcom would be:

# Yosefcom Internet Services connection options

linkname yosefcom

user your username
                # you authenticate to the server as this user; this should be
                # the same name as in the pap-secrets file entry (i.e. if
                # you added the ISP code there, add it here also)

pty "/usr/sbin/pptp your ISP PPTP server IP --nolaunchpppd"

nobsdcomp       # 'BSD-compress' will not be used, so let's disable it
nodeflate       # 'Deflate' will not be used, so let's disable it

hide-password   # does not show the password when logging

noauth          # does not require the remote server to authenticate itself
persist         # if link is broken, try to reestablish it rather
                # than exit immediately

usepeerdns      # eventually, cause a modification of /etc/resolv.conf to use 2
                # DNS server whose addresses are provided by the peer.
                # This may or may not be what you want to do, so be careful.

defaultroute
replacedefaultroute
                # Use this PPP connection as the default route,
                # i.e. by default, outgoing packets will be routed through it;
                # also, restore the previous default route when the PPP
                # connection comes down

#debug          # enable this for more verbose logging by pppd
#kdebug 4       # enable this for _yet_more_ verbose logging by pppd

A few notes:

Provider-Specific ip-up.d and ip-down.d scripting

There are various tasks which may need to be performed once the connection is established or dropped, and these depend on your specific configuration. However, most of them are not specific to one or the other ISP (reloading the MTA (Mail Transport Agent), starting or stopping a sniffer for the connection, firewall regeneration, etc.); these are carried out using executables (scripts usually) in the ip-up.d (post connection set-up) and ip-down.d (post connection bring-down) directories.

If you're an ordinary user without a complex setup (multiple PPP connections, need for special routing rules, use of dynamic DNS etc.) you can skip this section entirely and proceed to the next section. Otherwise, this section describes how to have make some tasks run only for a single specific connection, with examples.

Extender scripts for the ip-up.d and ip-down.d mechanisms

The following two scripts extend the ip-up.d and ip-down.d mechanism to run peer-specific scripts from the linkname subdirectory, where linkname is set as a pppd option. When referring to file locations, I will use the conventions for Debian, in which the 2 script directories are /etc/ppp/ip-up.d/ and /etc/ppp/ip-down.d/; in other distributions they will most probably be elsewhere under /etc.

Note that the naming conventions for files in /etc/ppp/ip-up.d/ and /etc/ppp/ip-down.d/ is XXsomething, where XX is a number in the range 00...99 which denotes execution order (00 first, 99 last). On a typical Debian 3.0 system, I would change the name the firewall script (named ipmasq or 0ipmasq) to 10ipmasq, and use a 05 prefix for the extenders. See further discussion of firewall issues below.

Contents of /etc/ppp/ip-up.d/05peer-specific :

#!/bin/sh
#
# run peer-specific (or, rather, linkname-specific) scripts

if [ -n "$LINKNAME" ] ; then
        run-parts /etc/ppp/ip-up.d/$LINKNAME
fi

exit 0

Contents of /etc/ppp/ip-down.d/05peer-specific :

#!/bin/sh
#
# run peer-specific (or, rather, linkname-specific) scripts

if [ -n "$LINKNAME" ] ; then
        run-parts /etc/ppp/ip-down.d/$LINKNAME
fi

exit 0

If, for some reason, your distribution does not use an ip-up.d/ip-down.d mechanism, only a simple ip-up and an ip-down script, you can remedy the situation: download the Debian ppp package, extract the files you need, synch them with the content of your current 2 scripts, and install them into place. You will also need a working run-parts.

When your peer-specific (or any other) ip-up / ip-down scripts are run, some environment variables relating to the connection are available to you. These are:

Name Value
PPPD_PIDprocess id on this system of the pppd handling this connection
PPPLOGNAMEusername as which the pppd handling this connection was run
PPP_IPPARAMoptional value, mostly irrelevant
IPLOCALthe IP negotiated for this system on this connection by pppd
PPP_LOCALsame as the above
IPREMOTEthe IP of the remote system on this connection
PPP_REMOTEsame as the above
IFNAMEname of the network interface for the ppp connection, e.g. ppp1 or ppp3
PPP_IFACEsame as the above
LINKNAMEvalue of the linkname option specified in the pppdoptions file for this connection
PPP_TTYNAMEirrelevant to PPTP connections
SPEEDirrelevant to PPTP connections
PPP_SPEEDsame as the above
DNS1first DNS server address specified by the peer, if usepeerdns wat set
DNS2second DNS server address specified by the peer, if usepeerdns wat set

The reason for redundancies is that some variables are set by pppd itself, while others are set by the main ip-up or ip-down script.

Name resolution

For most users, the usepeerdns peer option (in /etc/ppp/peers/yosefcom), which causes the DNS server your provider specifies to be used, or the use of the fixed DNS specified by your cable provider, should be enough. More complex configurations may require peer-specific scripting, but these are too varied to provide some script here which would be of general use.

Routing

When bringing the connection up, most users can utilize pppd's ability to replace the default route: in the peer option file listed above, we specified defaultroute and replacedefaultroute. If, however, you wish to do something more complex, you may disable them, and add a script to the ip-up.d/yosefcom/ directory instead. Here's a sample script which does what replacedefaultroute would do:

#!/bin/sh
#

# Route through the PPP connection by default
#
ip route replace default via $IPREMOTE dev $PPP_IFACE

If you replace the default route when establishing the PPP connection, and you have not used defaultroute + replacedefaultroute (which restore the original route when the connection comes down) , you need an ip-down.d/yosefcom/ script to restore the default gateway:

#!/bin/sh
#

# The PPTP server IP
#
PPTP_SERVER=your ISP PPTP server's IP

# The underlying interface, on which we connect
# to the PPTP server
#
UNDERLYING_INTERFACE=`ip -o route get to $PPTP_SERVER | cut -d\  -f5`

# The default gateway of the underlying cable connection,
# determined using a helper script. Note: This assumes
# the only entry in the ARP table for the cable connection
# is that of your gateway; this holds AFAIK
#
UNDERLYING_GATEWAY=`ip neighbour show dev $UNDERLYING_INTERFACE | sed "s/^\([0-9\.]\+\).*/\1/"`

# restore the non-PPP default gateway
ip route replace default via $UNDERLYING_GATEWAY dev $UNDERLYING_INTEFFACE

Note this last script assumes the route to the PPTP server is valid, that is, uses the cable connection network interface. This assumption may be partially avoided at the price of specifying the cable network interface name in the script by a static assignment to the UNDERLYING_INTERFACE variable.

Firewall issues

One of the problems which may prevent you from completing a setup the PPTP connection is a firewall. A firewall may, for different reasons, prevent some of the communication between the PPTP client and server (and result in mysterious SIGHUP's logged by pppd. At this time I am not sure which types of firewall rules may interfere with PPTP connection setup, so a crude approach may be adopted: completely dropping the firewall before making the connection, and re-raising it afterwards (actually, the firewall should be re-raised after connection even if it hasn't been dropped), taking into account the new PPTP connection as a new external connection. The dropping and raising of a firewall is also rather distribution-specific. In Debian 3.0/3.1 (and probably 2.2), re-raising is automated with an existing ip-up.d directory script (consider the script running order carefully, you may need to do renamings; see above), but the firewall is not dropped before the PPTP client is run.

Dropping the firewall

Usually, it is not necessary to entirely drop the firewall before or during the establishment of the PPTP connection. If you do need to to drop it, here's a drop-firewall script:

#!/bin/sh

IPFWADM=/sbin/ipfwadm
IPCHAINS=/sbin/ipchains
IPTABLES=/sbin/iptables

# determine rule method
if [ -e /proc/net/ip_tables_names ]; then
   test -x $IPTABLES || exit 1
       MASQMETHOD=netfilter
elif [ -e /proc/net/ip_fwchains ]; then
   test -x $IPCHAINS || exit 1
       MASQMETHOD=ipchains
else
    test -x $IPFWADM || exit 1
        MASQMETHOD=ipfwadm
fi

#: Flush all and set default policy of allow.
case $MASQMETHOD in
ipfwadm)
    $IPFWADM -I -p allow
    $IPFWADM -O -p allow
    $IPFWADM -F -p allow
    $IPFWADM -I -f
    $IPFWADM -O -f
    $IPFWADM -F -f
    ;;
ipchains)
    $IPCHAINS -P input ALLOW
    $IPCHAINS -P output ALLOW
    $IPCHAINS --no-warnings -P forward ALLOW
    $IPCHAINS -F input
    $IPCHAINS -F output
    $IPCHAINS --no-warnings -F forward
    ;;
netfilter)
    $IPTABLES -P INPUT ACCEPT
    $IPTABLES -P OUTPUT ACCEPT
    $IPTABLES -P FORWARD ACCEPT
    $IPTABLES -F INPUT
    $IPTABLES -F OUTPUT
    $IPTABLES -F FORWARD
    $IPTABLES -t mangle -P PREROUTING ACCEPT
    $IPTABLES -t mangle -P OUTPUT ACCEPT
    $IPTABLES -t mangle -F PREROUTING
    $IPTABLES -t mangle -F OUTPUT
    $IPTABLES -t nat -P PREROUTING ACCEPT
    $IPTABLES -t nat -P POSTROUTING ACCEPT
    $IPTABLES -t nat -P OUTPUT ACCEPT
    $IPTABLES -t nat -F PREROUTING
    $IPTABLES -t nat -F POSTROUTING
    $IPTABLES -t nat -F OUTPUT
    ;;
esac

How is this to be used? Instead of immediately calling the PPTP client in the pty option in the peer-specific options file, use something like "/usr/local/sbin/drop-firewall ; /usr/sbin/pptp my_isp_pptp_server --nolaunchpppd", or write a wrapper script for the pptp binary.

Firewall generation alteration

Using a PPTP link over an existing network to virtualize another interface has several implications, perhaps the most important of which are the implications on the nature of your firewall and its generation. Some installations may have no firewall or a firewall with static rules; they should not be affected. But on installations with dynamic firewall generators problems may arise.

Since ipmasq, used in Debian, is the only such system I am familiar with, let me describe what may (and does) go wrong when it's used in conjuction with PPTP:

All of this can be corrected by tinkering with the scripts (see the documentation of ipmasq, sh/bash, and ipfwadm/ipchains/iptables, depending on your kernel version) – but such tinkering has security implications which must be considered by the cautious user and system administrator.

The solution is either to make the PPTP client or the pppd processes more lenient with timeouts (if indeed the lost packets are recent), or to modify the ipmasq firewall (re)generation, which is what I have done.

The changes I employed are in the form of the rule files A01interfaces.rul, A02unkernelforward.rul, A03flush.rul (which are used instead of the respective .def files) and ZZZresetpolicy.rul which has no .def. I also created the new file /etc/ipmasq/internal_ifs.

contents of A01interfaces.rul :

# find interface names
INTERNAL=`egrep -v '^[:space:]*#' /etc/ipmasq/internal_ifs`
EXTERNAL=$(enumerate-if | sort -u | grep -v lo)
if [ -n "$INTERNAL" ]; then
    for i in $INTERNAL; do
        EXTERNAL=$(echo $EXTERNAL | sed -e "s/\(  *\|^\)$i\(  *\|$\)/\1/")
    done
fi

# remove interfaces that don't have networks attached to them
if [ -n "$INTERNAL" ]; then
    for i in $INTERNAL; do
        nm=$(nmofif $i)
        if [ -z "${nm}" ]; then
            INTERNAL=$(echo $INTERNAL | sed -e "s/\(  *\|^\)$i\(  *\|$\)/\1/")
        fi
    done
fi
if [ -n "$EXTERNAL" ]; then
    for i in $EXTERNAL; do
        if [ -z "`enumerate-if | grep $i`" ]; then
            EXTERNAL=$(echo $EXTERNAL | sed -e "s/\(  *\|^\)$i\(  *\|$\)/\1/")
            continue
        fi
        nm=$(nmofif $i)
        if [ -z "${nm}" ]; then
            EXTERNAL=$(echo $EXTERNAL | sed -e "s/\(  *\|^\)$i\(  *\|$\)/\1/")
        fi
    done
fi

contents of A02unkernelforward.rul :

#: DO NOT Turn off forwarding for 2.1 kernels!
#: DO NOT Turn off IP defragmentation

contents of A03flush.rul :

#: Set a default policy of 'accept' and flush all
case $MASQMETHOD in
ipfwadm)
    $IPFWADM -I -p accept
    $IPFWADM -O -p accept
    $IPFWADM -F -p accept
    $IPFWADM -I -f
    $IPFWADM -O -f
    $IPFWADM -F -f
    ;;
ipchains)
    $IPCHAINS -P input ACCEPT
    $IPCHAINS -P output ACCEPT
    $IPCHAINS --no-warnings -P forward ACCEPT
    $IPCHAINS -F input
    $IPCHAINS -F output
    $IPCHAINS --no-warnings -F forward
    ;;
netfilter)
    $IPTABLES -P INPUT ACCEPT
    $IPTABLES -P OUTPUT ACCEPT
    $IPTABLES -P FORWARD ACCEPT
    $IPTABLES -F INPUT
    $IPTABLES -F OUTPUT
    $IPTABLES -F FORWARD
    $IPTABLES -t mangle -P PREROUTING ACCEPT
    $IPTABLES -t mangle -P OUTPUT ACCEPT
    $IPTABLES -t mangle -F PREROUTING
    $IPTABLES -t mangle -F OUTPUT
    $IPTABLES -t nat -P PREROUTING ACCEPT
    $IPTABLES -t nat -P POSTROUTING ACCEPT
    $IPTABLES -t nat -P OUTPUT ACCEPT
    $IPTABLES -t nat -F PREROUTING
    $IPTABLES -t nat -F POSTROUTING
    $IPTABLES -t nat -F OUTPUT
    ;;
esac

contents of ZZZresetpolicy.rul :

#: Reset policies to 'deny' where necessary
case $MASQMETHOD in
ipfwadm)
    $IPFWADM -I -p deny
    $IPFWADM -O -p deny
    $IPFWADM -F -p deny
    ;;
ipchains)
    $IPCHAINS -P input DENY
    $IPCHAINS -P output DENY
    $IPCHAINS --no-warnings -P forward DENY
    $IPCHAINS --no-warnings -F forward
    ;;
netfilter)
    $IPTABLES -P INPUT DROP
    $IPTABLES -P OUTPUT DROP
    $IPTABLES -P FORWARD DROP
    ;;
esac

contents of /etc/ipmasq/internal_ifs (the interfaces listed are just examples; replace them) :

# /etc/ipmasq/internal_ifs
#
# in this file are listed all intefaces which, if they exist,
# are considered to be internal; all other interfaces will be
# considered external.
#
# each word in a non-comment line should be a name of one of
# these interfaces.
#
eth1
eth3

Some more firewall-related notes

What else to run from ip-up.d?

Advanced users may also be interested in running dynamic DNS updates with your newly-gotten IP, and/or setting up traffic shaping, but these subjects are beyond the scope of this HOWTO. If you have a lot of free time on your hands and feel like doing some extensive reading, kernel patching, script-writing etc., try

http://www.technopagan.org/dynamic/
Dynamic DNS - Introduction and DDNS Provider List
http://kem.p.lodz.pl/~peter/qnet/
The QNET Quality-of-Service and NetFilter Linux Kernel Patch-Set
http://lartc.org/
Linux Advanced Routing & Traffic Control
http://lartc.org/wondershaper/
WonderShaper - Simple traffic shaping automation
http://www.digriz.org.uk/jdg-qos-script/
Jim diGriz's QoS Script - WonderShaper's big brother

Note, again, these are advanced subjects which are entirely unncessary for establishing the PPTP connection per se, and may cause you a lot of trouble if you mess your kernel up.

Making the connection

From a state in which your cable connection is up-and-running, execute pon yosefcom (if your distribution doesn't have a pon script, execute pppd call yosefcom). Wait a few seconds. Now use ip link to check the existance of the PPP connection. Typical output should look something like this:

1: eth0:  mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether your ethernet MAC address brd ff:ff:ff:ff:ff:ff
2: lo:  mtu 16436 qdisc noqueue
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
3: ppp0:  mtu 1400 qdisc pfifo_fast qlen 3
    link/ppp

Now use ip route list to check the routing table. Typical output:

PPTP_SERVER via UNDERLYING_GATEWAY dev UNDERLYING_INTERFACE src your address on the cables network segment
DHCP_SERVER via UNDERLYING_GATEWAY dev UNDERLYING_INTERFACE  src your address on the cables network segment
cables network segment dev UNDERLYING_INTERFACE proto kernel  scope link  src your address on the cables network segment
default via PPP_LOCAL dev PPP_IFACE

Notes:

Now ping some machine you know, or traceroute or lynx to some popular site, to make sure the connection is working. If any of the above checks don't turn out as exepected – check the logs (/var/log/messages , /var/log/syslog), or execute plog which shows you the latest pppd-related bits of the logs. You can also try enabling the debugging options in the pppd peer options file. Specifically, make sure you don't have two default gateways; if this is the case, alter your routing configuration script. Remember you too can generate output for debugging purposes from within ip-up.d scripts, either to the system logs or to a log of your own; thus

echo `date` [ `cat /proc/self/stat | cut "-d " -f 1` ] some text > /tmp/myppplog
will add a timestamped, pid-stamped line saying "some text" to the log at /tmp/myppplog.

Don't be too surprised if after a few hours of connection you find yourself mysteriously disconnected:

pptp[22731]: log[pptp_conn_close:pptp_ctrl.c:307]: Closing PPTP connection
pptp[22731]: log[call_callback:pptp_callmgr.c:88]: Closing connection
pppd[22745]: Hangup (SIGHUP)
pppd[22745]: Modem hangup
pppd[22745]: Script /etc/ppp/ip-down started (pid 24347)
pppd[22745]: Connection terminated.
pppd[22745]: Connect time 1342.6 minutes.
pppd[22745]: Sent 991866306 bytes, received 1231829177 bytes.
pppd[22745]: Waiting for 1 child processes...
pppd[22745]:   script /etc/ppp/ip-down, pid 24347
pppd[22745]: Script /etc/ppp/ip-down finished (pid 24347), status = 0x0

... it's probably those evil ISP goblins at work. The PPTP client folks have written a HOWTO for interpreting its error messages (and the related pppd errors as well), so you may want to use that.

Restarting the connection in case of failure

VPN is a stateful mode of connecting to a network, and thus rather unstable compared to normal ethernet (and other similar) stateless connections. As mentioned above, you may experience periodic disconnections, for a host of possible reasons. An obvious remedy is to monitor your connection's state and reconnect if it fails.

The simplest way to do this is using the cron mechanism for performing periodic tasks on a system. Add the following line to your /etc/crontab:

* * * * * root /usr/local/bin/check-ppp-connection yosefcom

This will check the connection's state every minute; you can instead use

*/5 * * * * root /usr/local/bin/check-ppp-connection yosefcom

for checks every five minutes, etc. The contents of the check script, /usr/local/bin/check-ppp-connection, will be:

#!/bin/sh
#
# ensure specified PPP connection link is up; otherwise start it
#
# note: this script assumes the linkname is the same as the name of the options file in /etc/ppp/peers

LINKNAME=$1

if [ -z "$LINKNAME" ]; then
        echo "Usage: check-ppp-connection <linkname>"
        exit 1
fi

if [ -f /var/run/ppp-$LINKNAME.pid ]; then
        PPP_IFACE=`tail -1 /var/run/ppp-$LINKNAME.pid`
        if [ "$PPP_IFACE" ] && [ "`ip -o link show $PPP_IFACE`" ]; then
                exit 0
        fi
fi
# if you don't have pon, use "pppd call" instead
exec pon $LINKNAME

This simple solution has the disadvantage of trying to bring up the connection repeatedly even if previous attempts have failed. To avoid this you may wish to create a timestamp when attempting to restart the connection, and not make another attempt unless enough time has passed since the last attempt. It may also be necessary to try and kill dangling pppd's, but this requires discretion, since there may theoretically be other PPP connections running.

Having the connection established automatically at boot time

Different distributions have to be told in different ways which interfaces should be brought up at boot time, and how. With Debian 3.1 and later (possibly with 3.0 also), add the following lines to your /etc/network/interfaces file:

iface ppp0 inet ppp
    provider yosefcom

(This assumes yosefcom is the first PPP interface you're bringing up, otherwise use another index instead of 0).

Now add to the interfaces file's 'auto' line the ppp0 interface, e.g. replace

auto lo eth0

with

auto lo eth0 ppp0

to indicate you want that interface you've just defined to be brought up on boot.

With other distributions, you'll have to use whatever scripting mechanism is available; if you can't find anything simpler, you can always add an rc.d script for your chosen runlevel.

Additional information and help

You can try:

For firewall-related issues, it is a good idea, just as the ADSL HOWTO recommends, to read up on the (newer) Linux IP filtering mechanism, iptables, in the NAT HOWTO and the Packet-Filtering HOWTO.

Debian users might also do well to acquaint themselves with the resolvconf package, which helps with the coordination of name-resolution-related information of the hosts file, the DHCP lease and your local DNS server.

Please contact me if you have any comments, corrections, or suggested additions.