PPTP Client
Routing HOWTO
by Linus McCabe & James Cameron Routing 25th November 2002 Once your PPTP tunnel connects, you need to make sure you can reach hosts on the other side of the tunnel. |
If you only wish communication to work between the PPTP connected hosts (server and client), it's easy. Both sides of the tunnel have an IP and you should be able to reach the other side when you are connected.
For example:
# ifconfig ppp0 | grep inet inet addr:192.168.10.102 P-t-P:192.168.10.114 Mask:255.255.255.255 # ping 192.168.10.114 PING 192.168.10.114 (192.168.10.114): 56 data bytes 64 bytes from 192.168.10.114: icmp_seq=0 ttl=128 time=51.6 ms 64 bytes from 192.168.10.114: icmp_seq=1 ttl=128 time=50.6 ms ... |
The first line will tell you the IP's of the client and server, "inet addr" is the client side IP and "P-t-P" is the IP of the server.
Slightly more advanced is if you have one computer connected to a server and want to reach computers on the server's LAN. If this is the case, you will have to set up a route to the other network after the tunnel starts.
In the figure above:
-
- the tunnel from the client to the server is ppp0,
- the remote network uses addresses starting with 192.168.10.
So after the tunnel starts, add this route:
# route add -net 192.168.10.0 netmask 255.255.255.0 dev ppp0 |
Then to test:
# traceroute 192.168.10.127 traceroute to 192.168.10.127 (192.168.10.127), 30 hops max, 38 byte packets 1 192.168.10.114 (192.168.10.114) 48.176 ms 48.115 ms 93.816 ms 2 192.168.10.127 (192.168.10.127) 46.554 ms 48.138 ms 48.443 ms |
Packets for the mail and web server will be sent into the tunnel. Packets addressed to the tunnel server itself will still use the interface route created when the tunnel started.
If you have other computers connected to your computer, in a local area netowork (LAN), you may want them to be able to connect to the remote network. Like this:
If you wish to reach any computer on the other side of the tunnel, from any computer on your LAN, you will also need to set up a routing on the foreign LAN, or use ipchains or iptable to do address translation.
In the figure above, the important information is:
-
- the remote network is 192.168.0.0/16,
- the tunnel interface is ppp0.
The solution depends on the kernel version.
Iptables (kernel 2.4.x):
# route add -net 192.168.0.0 netmask 255.255.0.0 dev ppp0 # iptables --insert OUTPUT 1 --source 0.0.0.0/0.0.0.0 / --destination 192.168.0.0/16 --jump ACCEPT --out-interface ppp0 # iptables --insert INPUT 1 --source 192.168.0.0/16 / --destination 0.0.0.0/0.0.0.0 --jump ACCEPT --in-interface ppp0 # iptables --insert FORWARD 1 --source 0.0.0.0/0.0.0.0 / --destination 192.168.0.0/16 --jump ACCEPT --out-interface ppp0 # iptables --insert FORWARD 1 --source 192.168.0.0/16 / --destination 0.0.0.0/0.0.0.0 --jump ACCEPT # iptables --table nat --append POSTROUTING --out-interface ppp0 / --jump MASQUERADE # iptables --append FORWARD --protocol tcp / --tcp-flags SYN,RST SYN --jump TCPMSS --clamp-mss-to-pmtu |
(the last line fixes the path MTU discovery problem as described in the Diagnosis HOWTO.)
Ipchains (kernel 2.2.x):
# route add -net 192.168.0.0 netmask 255.255.0.0 dev ppp0 # ipchains -I output 1 -s 0.0.0.0/0.0.0.0 -d 192.168.0.0/16 / -i ppp0 -j ACCEPT # ipchains -I forward 1 -s 192.168.0.0/16 -d 0.0.0.0/0.0.0.0 / -i ppp0 -j MASQ -b # ipchains -I input 1 -s 192.168.0.0/16 -d 0.0.0.0/0.0.0.0 / -i ppp0 -j ACCEPT |
From another computer on your LAN you should now be able to test with
# traceroute mail traceroute to mail (192.168.0.7), 30 hops max, 38 byte packets 1 client (10.0.1.1) 0.980 ms 0.312 ms 0.225 ms 2 server (10.20.0.1) 48.079 ms 48.758 ms 47.708 ms 3 mail (192.168.0.7) 50.250 ms 46.662 ms 48.299 ms |
The red arrows in the figure below show the progress of the traceroute probes.
See Nicolas Crovatti's LAN to LAN over ADSL document. This is a special case when you are running a workplace tunnel within an ADSL service provider's tunnel.
Adding routes and typing iptables/ipchains rules will be tedious if you have to do it everytime you connect your tunnel, of course you want to automate this. Different distributions have different ways of handling this:
-
- if you use Debian, you can write a script in /etc/ppp/ip-up.d/ which will be executed by /etc/ppp/ip-up,
- if you use Red Hat, you can write a script that does pptp-command start tunnel and then add routes or iptables/ipchains rules,
- if you use Red Hat, you can use Yury Zotov's ifup scripts; post 1 post 1 post 2 post 2), or;
- you can always use updetach as an option to pppd, and then based on the exit status add routes.
The following works with Debian and should be put in /etc/ppp/ip-up.d/
#!/bin/sh if [ "${PPP_IPPARAM}" = "tunnel" ]; then /sbin/route add -net 192.168.10.0/24 dev ${IFNAME} /sbin/iptables --insert OUTPUT 1 / --source 0.0.0.0/0.0.0.0 / --destination 192.168.10.0/24 / --jump ACCEPT --out-interface ${IFNAME} /sbin/iptables --insert INPUT 1 / --source 192.168.10.0/24 / --destination 0.0.0.0/0.0.0.0 / --jump ACCEPT --in-interface ${IFNAME} /sbin/iptables --insert FORWARD 1 / --source 0.0.0.0/0.0.0.0 / --destination 192.168.10.0/24 / --jump ACCEPT --out-interface ${IFNAME} /sbin/iptables --insert FORWARD 1 / --source 192.168.10.0/24 / --destination 0.0.0.0/0.0.0.0 --jump ACCEPT /sbin/iptables --table nat --append POSTROUTING / --out-interface ${IFNAME} --jump MASQUERADE /sbin/iptables --append FORWARD --protocol tcp --tcp-flags SYN,RST SYN / --jump TCPMSS --clamp-mss-to-pmtu fi |
${IFNAME} and ${PPP_IPPARAM} are environment variables provided by pppd when the script is run, and correspond to the interface name and tunnel name respectively. Don't forget to alter the ${PPP_IPPARAM} comparison and the network addresses to suite your needs. Also, the file should be executable!
# chmod +x /etc/ppp/ip-up.d/tunnel |
Remote IP of tunnel is the same as IP of server
30th May 2003
Some sites configure their PPTP server to give to the server end of tunnel the same IP address that is used to contact the public interface of the server. When this happens, it isn't practical to use simple routing.
In the figure above:
-
- the link from the client to the internet is ppp0, and has an IP address (at the client) of 203.0.0.55,
- the link from the server to the internet has an IP address of 22.0.0.22, called the public interface, and;
- the tunnel from the client to the server is ppp1, has a local IP address (at the client) of 22.0.0.80, and a remote IP address (at the server) of 22.0.0.22
Change the destination address of the PPP interface to be the internal address of the PPTP server. If your tunnel is on ppp1, as in the diagram above, then:
where 10.0.0.1 is the internal address. The manual page for ifconfig suggests we use the option pointopoint rather than the older dstaddr. Both appear to work.
2004-04-06
| ![]() |
or, using the ip command, execute this ip-up script:
# 1: interface-name # 4: local-IP-address ip addr del $4 dev $1 ip addr add $4 peer 10.0.0.1/32 dev $1 |
where (again) 10.0.0.1 is the internal address.
30th December 2002
Some sites ask that you route all your traffic through the tunnel. This is also the default behaviour of the Microsoft VPN client. You may not want to do this, as it can slow your internet performance.
2006-08-16
| ![]() |
To do this, change the default route to use the tunnel interface, and add a host route to the PPTP Server. The kernel will prefer the host route over the default route for tunnel data packets addressed to the PPTP Server.
The following ip-up scripts can be used. They will need to be edited by you to contain;
-
- PRIMARY, the name of the network interface through which the PPTP Server is initially contacted. This is usually the interface used as the default route before the tunnel is started.
- SERVER, the IP address or fully qualified domain name of the PPTP Server.
- PRIMARY, the name of the network interface through which the PPTP Server is initially contacted. This is usually the interface used as the default route before the tunnel is started.
The scripts use the pppd option ipparam to determine if they should act for the PPP connection that is in progress. So you will need to add ipparam tunnel to the pppd options for the tunnel.
#!/bin/sh # pppd ip-up script for all-to-tunnel routing # name of primary network interface (before tunnel) PRIMARY=eth0 # address of tunnel server SERVER=tunnel.example.com # provided by pppd: string to identify connection aka ipparam option CONNECTION=$6 if [ "${CONNECTION}" = "" ]; then CONNECTION=${PPP_IPPARAM}; fi # provided by pppd: interface name TUNNEL=$1 if [ "${TUNNEL}" = "" ]; then TUNNEL=${PPP_IFACE}; fi # if we are being called as part of the tunnel startup if [ "${CONNECTION}" = "tunnel" ] ; then # direct tunnelled packets to the tunnel server route add -host ${SERVER} dev ${PRIMARY} # direct all other packets into the tunnel route del default ${PRIMARY} route add default dev ${TUNNEL} fi |
Note: if you need the network connection to work again after the tunnel is taken down but before the main connection is terminated, you will need to restore the default route. Use an ip-down script for the tunnel, as follows:
#!/bin/sh # pppd ip-down script for all-to-tunnel routing # name of primary network interface (before tunnel) PRIMARY=eth0 # provided by pppd: string to identify connection aka ipparam option CONNECTION=$6 if [ "${CONNECTION}" = "" ]; then CONNECTION=${PPP_IPPARAM}; fi # provided by pppd: interface name TUNNEL=$1 if [ "${TUNNEL}" = "" ]; then TUNNEL=${PPP_IFACE}; fi # if we are being called as part of the tunnel shutdown if [ "${CONNECTION}" = "tunnel" ] ; then # direct packets back to the original interface route del default ${TUNNEL} route add default dev ${PRIMARY} fi |
(How the diagrams were produced.)
ChangeLog
Date | Change |
---|---|
2008-07-17 | Added /sbin/ to Debian ip-up.d script, contributed by an IRC user.
|
2005-12-28 | Replaced primary interface name in ip-up.d and ip-down.d example scripts. Reported by Jeff Nelson.
|
2004-04-06 | Adjust pointopoint description.
|
2004-01-28 | Change netmask format to CIDR format for a few commands, thanks to Andrew Elwell via #pptp.
|
2003-12-13 | Reference the GUI method in the all to tunnel section.
|
2003-05-30 | Add Denis Vlasenko's solution to the duplicate IP address problem.
|
2003-02-15 | Add hint from Ed to change the remote IP of the tunnel.
|
2002-12-30 | Adjust all to tunnel scripts for compatibility with Debian's ip-up, thanks to James Stone.
|
2002-12-27 | Add all to tunnel routing.
|
2002-11-25 | Add Nicolas' LAN to LAN via ADSL document. Add use of updetach. Add table of contents.
|