Diagnosing Forwarding on pptpd

by James Cameron
2007-10-18

Summarising the situation; clients can ping the IP address assigned to their tunnel, but cannot ping anything beyond the server (the target). Presumably also the server can ping the IP address assigned to the client.

If that is the situation, then this is just a Linux routing and packet forwarding problem. It would happen with any network connection, not only a tunnel. Read on.

(note to self, this is the situation)

Here's a simplified diagram, the blue line shows what we are aiming to achieve - bidirectional packet flow between the client and the target:

Assume that eth0 is the network interface that the server uses to get to the target, and ppp0 is the tunnel network device created by the client connection. These are conventions we use to explain, but adjust the instructions if the interface names are different.

Here's a diagram showing the network interfaces as well:

Rewrite This HOWTO
This is a very detailed procedure. It can help if our instructions are tailored to the environment. We give that opportunity here, although only for the text, not the diagrams.

Be cautious. Do not give information that may threaten security. Use an alias.

Client Name :
Client Tunnel Network Interface :
Client Tunnel Network Interface Address :
Server Name :
Server Tunnel Network Interface :
Server Tunnel Network Interface Address :
Server External Network Interface :
Server External Network Interface Address :
Target External Network Interface Address :

We'll list a series of tests that must be completed. These follow the path of the packets. In each test, the diagram will be highlighted:

Here is the legend or key for the symbols used in the diagrams below:


Test 0

Can the client ping the server inside the tunnel?

  1. on client, type the command:
    ping 10.1.1.1
  2. make note of the result, the test passes if replies are seen,
  3. stop the ping if desired,

You've already agreed above that this worked. If the answer is no, then fix the problem before proceeding.

(note to self, test 0 passed, ping showed return packets)

Test 1

Can the server see the packets from the client for the target?

  1. on server type the command:
    tcpdump -n -i ppp0 icmp and src host 10.1.1.2 and dst host 72.14.207.99
    and leave it to run,
  2. on client, type the command:
    ping 72.14.207.99
    but expect no response there,
  3. make note of the result, the test passes if on server the tcpdump has shown packets,
  4. stop the ping and tcpdump if desired,

If there are no packets, the fault is at the client. Stop and address that issue at the client before proceeding.

The most common cause of failure for this test is a lack of route to the target on the client. Other causes are iptables rules on the client or the server.

(There's nothing the server can do to prevent the client from using the tunnel once it is established; routing at the client end is the responsibility of the client.)

(note to self, test 1 passed, tcpdump shows echo requests)

Test 2

Is the server configured to forward packets?

  1. on server, type the command:
    cat /proc/sys/net/ipv4/ip_forward
  2. make note of the result, the test passes if 1 is shown.

If this is "0", it should be changed to "1", using echo or sysctl.

(note to self, test 2 passed, ip_forward is 1)

Test 3

Can the server reach the target?

  1. on server type the command:
    ping 72.14.207.99
  2. make note of the result, the test passes if replies are seen,
  3. stop the ping if desired,

Output from ping must show that packets are returning. If it does do not, then stop and address that issue at the server or the target before proceeding.

Routing table entries on the server are a common cause. Also check iptables OUTPUT rules. If there are no iptables rules then this is not the cause.

(note to self, test 3 passed, ping showed return packets)

Test 4

Can the server forward the requests to the target?

  1. on server type the command:
    tcpdump -n -i eth0 icmp and dst host 72.14.207.99
    and leave it to run,
  2. on client, type the command:
    ping 72.14.207.99
    but expect no response there,
  3. make note of the result, the test passes if on server the tcpdump has shown packets,
  4. leave the ping running, but stop tcpdump if desired,

If this test fails, then stop and address that issue at the server.

The most common cause of failure for this test is iptables FORWARD rules.

Do not proceed until the answer is yes to this test.

(note to self, test 4 passed, tcpdump showed echo requests)

Test 5

Can the target forward the replies back to the server?

  1. on server type the command:
    tcpdump -n -i eth0 icmp and src host 72.14.207.99
    and leave it to run,
  2. if not already running, on client, type the command:
    ping 72.14.207.99
    but expect no response there,
  3. make note of the result, the test passes if on server the tcpdump has shown packets,
  4. leave the ping running, but stop tcpdump if desired,

There must be ICMP echo replies with a source address of the target. If the answer is no, then stop and address that issue.

The most common cause of failure for this test is that the target has no route to the tunnel IP address of the client. Look at the source address on the ICMP echo requests as they leave the server's external network interface. If an unroutable address range is assigned (e.g. 10.x.x.x, or 192.168.x.x) to the client, then ensure the server is configured to do network address translation (NAT) or masquerade.

The most common way to do NAT is to add an iptables rule that affects packets leaving the server:

# iptables --table nat --append POSTROUTING \
  --out-interface eth0 --jump MASQUERADE

(note to self, test 5 passed, tcpdump showed echo replies)

Test 6

Can the server forward the target reply packets back to the client?

  1. on server type the command:
    tcpdump -n -i ppp0 icmp and src host 72.14.207.99 and dst host 10.1.1.2
    and leave it to run,
  2. if not already running, on client, type the command:
    ping 72.14.207.99
    but expect no response there,
  3. make note of the result, the test passes if on server the tcpdump has shown packets,
  4. stop the ping and tcpdump if desired,

If the test fails, then the server is not forwarding the returned packets that were seen in test 5; either they are misaddressed, or iptables rules are configured to prevent it. As usual, fix this.

(note to self, test 6 passed, tcpdump showed echo replies)

Once test 6 passes, the fault must be with the client. For the packets to leave the server and not arrive on the client would normally be a client problem.

(note to self, bugger! [or other expression of dismay])

Passed all tests, but something still doesn't work? If it's Windows share browsing, consider either adding the proxyarp or ms-wins option in /etc/ppp/options.pptpd, or running the bcrelay program.


Comments

If you have comments on this document, please send them to the author at quozl at laptop dot org. But if you need help, use the mailing list (subscribe, archives) so that we can share the load.

ChangeLog

DateChange
2007-10-18 Added most common way to enable NAT from the server to the target. Rework instructions using variables that may be set by the reader. Made tcpdump expressions more exact, in order to reduce the size of the explanations.
2007-01-25 Reworded each test narrative to isolate goal, test, expected result, and possible causes. Made it more clear in the text where each test command was being done.
2006-03-09 Page is reasonably often needed during IRC and e-mail discussions, so the diagrams have been made clearer.
2005-02-09 Second draft, following IRC discussion.
2005-01-25 First draft, used in private mail.