pptp client
 overview
 license
 getting started
 features
 try it
 download
 links
 documentation 
 index
 debian
 fedora core 1
 fedora core 2
 fedora core 3
 fedora core 4
 fedora core 5
 fedora core 6
 gentoo
 knoppix
 mandrake 9.0
 mandrake 10.0
 mandrake 10.1
 netbsd
 red hat 9
 red hat 8.0
 red hat 7.3
 suse 10.0
 suse 9.2
 suse 9.1
 suse 8.2
 ubuntu
 diagnosis
 support faq
 diagrams
 routing
 security
team
 developers
 cvs
 contact us
 

PPTP Client


Routing HOWTO
by Linus McCabe & James Cameron
25th November 2002
Routing

Once your PPTP tunnel connects, you need to make sure you can reach hosts on the other side of the tunnel.


Client to Server

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.


Client to LAN

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:

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.


LAN to LAN

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 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.


LAN to LAN via ADSL

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.


Automatic setup

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:

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
by James Cameron, Denis Vlasenko & Ed Marcotte
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:

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:

ifconfig ppp1 pointopoint 10.0.0.1

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.


All Traffic Through Tunnel
by James Cameron
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.

GUI Note
If you are using the pptpconfig GUI then Stop the tunnel, select it again, then on the Routing tab, click on All to Tunnel, then click Update and try Start again. The remainder of this section covers alternate methods.

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;

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

DateChange
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.