Credits
The original version of this document was based partly on my experience and experimentation, and partly on two earlier guides:
- Cables-DHCP-PPTP HOWTO by Amir Tal (Whatsup) and Meir Kriheli (MKsoft Systems).
- 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:
- Each ISP allocates a block of its addresses to its cable users, and informs the cable providers of this allocation.
- The end-user, upon connection, requests an address from the cable provider via DHCP on its network segment.
- The cable provider's DHCP server looks up the ISP to which the end-user is associated, and assigns it an address within that ISP's allocated cable users address block.
- The end-user starts sending IP packets with its DHCP-obtained address
- The cable provider routes these packets to the relevant ISP based on the IP address' being in the ISP's block
Now, ISPs decided they don't like this way of doing things, for three reasons:
- 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.
- The ISP 'loses' that address block and can't reclaim some of it dynamically when only part of the end-users are connected.
- 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
- 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 |
|---|---|---|
| ActCom | Actcom | pns4.actcom.net.il |
| Aquanet | ? | cable.aquanet.co.il |
| Barak 013 | Barak | pns.barak.net.il |
| Bezeq International | Bezint | cables.bezeqint.net |
| Golden Lines 012 (Kavei Zahav) | Kzahav | aztv.012.net.il |
| Internet Gold (Internet Zahav) | Inzahav | pns.inter.net.il |
| IsraServ | Israserv | surf.israserv.net.il |
| NetVision | Netvision | cable.netvision.net.il |
| Technion | N/A | ccdis3.technion.ac.il |
Notes:
- You may prefer to use the PPTP server's IP address directly. You can obtain it using the command
dig PPTP server name - Some providers would like that users use named PPTP server addresses, for them to have the flexibility of directing different clients to different PPTP servers (by resolving the address differentl). However, tech support at some ISPs say that they don't recommend trusting the cable providers' DNS servers, and that you should use the numeric address rather than the named address. This guide uses a static route to the PPTP server; if you're an advanced user who wants to oblige your ISP by using a named address, you'll have to alter the scripts to create the static route just before bringing the connection up (see below).
- It is sometimes insinuated by ISP Customer/Technical Support staff that there may be different
VPN access servers for the different cable infrastructure providers (Matav, Golden Lines, Tevel); this does not appear to be true – there's only one VPN access server per provider, AFAIK. However, this
server may have different aliases: for example,
pns.inter.net.ilis also known asmatav.inter.net.il.
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 interfaceThe 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:
- You will be using the username and the password your ISP provided you with when you agreed to connect through them.
- Some ISPs (e.g. Internet Zahav in early 2003) require placing a provider code after the username - that's the first alternative above. There's a
@Cafter the actual username, followed by the provider code listed in the providers' table, above. Note the 'C', and usually also the first letter of the provider code, are in upper case, and the rest of the code is in lower case. - Remember also that these values must be synched over more than one file (see below).
- It is possible to replace the PPTP server name with an asterisk ('*'); this means the use of that specified password for authentication to all ISPs to which you connect with that specified username. Doing so has both advantages and disadvantages.
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:
- Since there are no spaces in your username, you don't need to place it within double-quotes.
- Do read the
pppdman page carefully, at least the entries for the settings listed here. - You can have 'yosefcom' as your default provider by naming your file
/etc/ppp/peers/providerinstead of/etc/ppp/peers/yosefcom, or having/etc/ppp/peers/providerbe a symbolic link to/etc/ppp/peers/yosefcom. This way,ponwithout any arguments would do the same thing aspon yosefcom. Luckily for you, this will not affect the operation of linkname-specific scripts (see below). - A note on
usepeerdnsand name resolution after establishing the PPP connection:
The easiest option, which should work for 99% of situations, is to use the fixed addresses of DNS servers specified by your ISP as entries in/etc/resolv.conf(or/etc/bind/named.confif you run your own DNS server). If, for some reason, you can and want to use different DNS servers when not connected to your ISP theusepeerdnsmay be what you need; it is in fact intended mostly for situations where the ISP may give you different DNS servers every time, and/or have DNS servers with changing IP's, which does not happen here AFAIK. To better understand howusepeerdnsworks, see the script which actually does the job; it should be in theip-up.d/directory. - If you're using a password generator to connect, it's useless to have the connection re-established automatically once dropped – you'll need to enter another password manually; so remove the
persistoption in this case.
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_PID | process id on this system of the pppd handling this connection |
PPPLOGNAME | username as which the pppd handling this connection was run |
PPP_IPPARAM | optional value, mostly irrelevant |
IPLOCAL | the IP negotiated for this system on this connection by pppd |
PPP_LOCAL | same as the above |
IPREMOTE | the IP of the remote system on this connection |
PPP_REMOTE | same as the above |
IFNAME | name of the network interface for the ppp connection, e.g. ppp1 or ppp3 |
PPP_IFACE | same as the above |
LINKNAME | value of the linkname option specified in the pppdoptions file for this connection |
PPP_TTYNAME | irrelevant to PPTP connections |
SPEED | irrelevant to PPTP connections |
PPP_SPEED | same as the above |
DNS1 | first DNS server address specified by the peer, if usepeerdns wat set |
DNS2 | second 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:
ipmasqmay have trouble recognizing the fact that you have (at least) 2 external interfaces: the ethernet interface to the cable network, and the PPTP interface. If it considers one of these to be internal, its generated rules are likely to interrupt the PPTP link and causepppdto die with a mysterious SIGHUP.ipmasqbegins its operation by disabling IP forwarding.ipmasq's firstiptablescommands set a DROP policy for everyiptableschain and flush the chains.
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
- Some people use
iptables -m unclean -j DROPto drop malformed IP packets. This matching logic may match the PPTP packets from your ISP and break the connection, so either avoid this rule altogether, or use it only on the PPP interface. - If your Linux machine is a gateway of a LAN, you may want to have some ports forwarded to machines on the LAN which serve them (e.g. an HTTP server); you can add an
ipmasqscript to automate this. ipmasqmakes the kernel spew a whole lot of log data when invalid packets are encountered. This can be really annoying if one of your interfaces goes down and everything you're sending is classified as invalid - your console may end up being flooded with logging info, preventing you from doing any work to get things to work again. Usedmesg -n 1(or another-nvalue) to control the level starting at which kernel messages are dumped to the console.- You should also consider diverting all of that packet logging blurb to some specific log file rather than letting it clog up your
/var/log/messagesand/var/log/syslog; for this purpose you may be interested inulogdand/orsyslog-ng(both available as Debian packages).
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:
- In the output above I've used the names of variables defined in the various scripts we've used so far; what you will actually see, of course, are their values
- The output listings do not include possible additional entries for other definitions you may have, e.g. an extra ethernet interface for your home LAN and its routing definitions, or devices used for traffic shaping, etc.
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/myppplogwill 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:
- the linux-il mailing list
- the IGLU site or its #iglu IRC channel
- the fora at whatsup.co.il, a Hebrew Linux Portal
- the Linux-Israel Net site
- Israeli ISP configuration info a concise summary of configuration data by 'jumpgate'
- Google cannot be overrated as a help tool, especially groups.google.com
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.