# Forwarding PPTP VPN through NAT [RESOLVED]

## nonamey

I'm having a hard time getting PPTP VPN on Microsoft clients to work through my router set up using the 'Home router How to' (http://www.gentoo.org/doc/en/home-router-howto.xml). The connection fails on WinXP with Error 619 (A connection to the remote computer could not be established)

My iptables is configured the as in that guide along with the following additions:

```

iptables -A FORWARD -p GRE -i eth0 -s 192.168.2.0/255.255.0.0 -j ACCEPT

iptables -A FORWARD -p tcp -i eth0 -s 192.168.2.0/255.255.0.0 --dport 1723 -j ACCEPT

iptables -A FORWARD -p GRE -i ppp0 -d 192.168.2.0/255.255.0.0 -j ACCEPT

iptables -A FORWARD -p tcp -i ppp0 -d 192.168.2.0/255.255.0.0 --dport 1723 -j ACCEPT

```

I have compiled GRE connection tracking into the kernel.

To be clear, there are only VPN clients on the LAN (not servers) that want to connect to arbitrary external VPN servers (this works with an SMC router).

Thanks for any help.

The output of iptables -L is below:

```

Chain INPUT (policy ACCEPT)

target     prot opt source               destination         

ACCEPT     all  --  anywhere             anywhere            

ACCEPT     all  --  anywhere             anywhere            

REJECT     udp  --  anywhere             anywhere            udp dpt:bootps reject-with icmp-port-unreachable 

REJECT     udp  --  anywhere             anywhere            udp dpt:domain reject-with icmp-port-unreachable 

DROP       tcp  --  anywhere             anywhere            tcp dpts:0:1023 

DROP       udp  --  anywhere             anywhere            udp dpts:0:1023 

Chain FORWARD (policy ACCEPT)

target     prot opt source               destination         

DROP       all  --  anywhere             192.168.0.0/16      

ACCEPT     gre  --  192.168.0.0/16       anywhere            

ACCEPT     tcp  --  192.168.0.0/16       anywhere            tcp dpt:1723 

ACCEPT     gre  --  anywhere             192.168.0.0/16      

ACCEPT     tcp  --  anywhere             192.168.0.0/16      tcp dpt:1723 

ACCEPT     all  --  192.168.0.0/16       anywhere            

ACCEPT     all  --  anywhere             192.168.0.0/16      

Chain OUTPUT (policy ACCEPT)

target     prot opt source               destination 

```

Last edited by nonamey on Mon Jan 09, 2006 3:33 am; edited 1 time in total

----------

## moocha

In addition to opening port 1723/TCP and forwarding GRE you need to load the pptp-conntrack kernel module. It's in the mainline of 2.6.14 AFAIK - for older kernels you need to locate and apply a kernel patch. Additionally, make sure you're running a recent iptables.

----------

## nonamey

 *moocha wrote:*   

> In addition to opening port 1723/TCP and forwarding GRE you need to load the pptp-conntrack kernel module. It's in the mainline of 2.6.14 AFAIK - for older kernels you need to locate and apply a kernel patch.

 

Thanks, I did not have PPTP in the kernel. I have compiled CONFIG_IP_NF_PPTP AND CONFIG_IP_NF_NAT_PPTP into kernel 2.6.14-r4 but I still have the same problem.

 *moocha wrote:*   

> Additionally, make sure you're running a recent iptables.

 

I have iptables 1.3.4 with the 'extensions' USE flag. Should it be re-emerged after a kernel upgrade (2.4.11->2.4.14)?

The problem may be my rules, simple as they are. Does what I have above for GRE and port 1723 make sense?

----------

## tuxmin

```

iptables -A FORWARD -p GRE -i ppp0 -d 192.168.2.0/255.255.0.0 -j ACCEPT

iptables -A FORWARD -p tcp -i ppp0 -d 192.168.2.0/255.255.0.0 --dport 1723 -j ACCEPT 

```

I assume ppp0 is you WAN interface? In that case shouldn't you put the public IP of the PPTP server in here?

BTW, your network should be 192.168.0.0/16 or 192.168.2.0/24, but 192.168.2.0/16 doesn't make any sense...

Alex!!!

----------

## nonamey

 *tuxmin wrote:*   

> 
> 
> I assume ppp0 is you WAN interface? In that case shouldn't you put the public IP of the PPTP server in here?
> 
> 

 

I do not have a PPTP server. I just want to be able to do PPTP NAT traversal. I have Windows clients behind the firewall that need to connect to arbitrary external (PPTP) VPN servers. 

 *Quote:*   

> 
> 
> BTW, your network should be 192.168.0.0/16 or 192.168.2.0/24, but 192.168.2.0/16 doesn't make any sense...
> 
> 

 

Thanks for pointing that out, I fixed it to 192.168.2.0/24 but still no luck.

----------

## tuxmin

I have understood that you don't run a server, that's why you should define the public IP address of the server you want to contact in you rules with the -d (destiniation) option.

Alex!!!

----------

## unclecharlie

nonamey,

iptables allow for stateful packet filtering. Most of what you have there is superfluous. (i.e. overkill) And the last line is definitely broken If the traffic is coming in then it should be --sport 1723 NOT --dport 1723

You do need to make sure that your -j ACCEPT rules are above any -j DENY or REJECT rules in the list that would block VPN traffic

My advice- Delete all of those rules and do-

```

iptables -A FORWARD -p tcp -i eth0 -o ppp0 -j ACCEPT

iptables -A FORWARD -p GRE -i eth0 -o ppp0 -j ACCEPT

```

to allow all outbound traffic(unless you don't trust your local users...)

then doing-

```

iptables -A FORWARD -p tcp -i ppp0 -m state --state RELATED,ESTABLISHED -j ACCEPT

iptables -A FORWARD -p GRE -i ppp0 -d 192.168.2.0/255.255.255.0 -j ACCEPT

```

should allow the VPN server to respond to the clients.

Should definitely work. And in fact you could probably do it in just two rules-

```

iptables -A FORWARD -i eth0 -o ppp0 -j ACCEPT

iptables -A FORWARD -i ppp0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT

```

I doubt you need the GRE tracking at all. I run VPN servers through linux firewalls without it all the time just by specifying the protocol as  -p 47 (I know, you're not running a server. But the connection tracking modules ARE for networks running servers. they aren't needed for client side connections.) NAT should take care of it on it's own.

it should work to connect to any VPN server outside your LAN.

And again, make sure these rules are first before your DENY and REJECT targets in your FORWARD chain!

If in doubt, do iptables --list

Charlie

----------

## nonamey

 *unclecharlie wrote:*   

> 
> 
> Delete all of those rules and do-
> 
> ```
> ...

 

Thanks for your help. I did as you said but I still cannot get it working.

 *Quote:*   

> 
> 
> If in doubt, do iptables --list
> 
> 

 

This is the output of iptables --list with your suggestion

```

Chain INPUT (policy ACCEPT)

target     prot opt source               destination         

ACCEPT     all  --  anywhere             anywhere            

ACCEPT     all  --  anywhere             anywhere            

REJECT     udp  --  anywhere             anywhere            udp dpt:bootps reject-with icmp-port-unreachable 

REJECT     udp  --  anywhere             anywhere            udp dpt:domain reject-with icmp-port-unreachable 

DROP       tcp  --  anywhere             anywhere            tcp dpts:0:1023 

DROP       udp  --  anywhere             anywhere            udp dpts:0:1023 

Chain FORWARD (policy ACCEPT)

target     prot opt source               destination         

ACCEPT     tcp  --  anywhere             anywhere            

ACCEPT     gre  --  anywhere             anywhere            

ACCEPT     tcp  --  anywhere             anywhere            state RELATED,ESTABLISHED 

ACCEPT     gre  --  anywhere             192.168.2.0/24      

ACCEPT     all  --  192.168.2.0/24       anywhere            

ACCEPT     all  --  anywhere             192.168.2.0/24      

Chain OUTPUT (policy ACCEPT)

target     prot opt source               destination   

```

----------

## unclecharlie

o.k. then try the second option-

remove your rules and just do

```

iptables -A FORWARD -i eth0 -o ppp0 -j ACCEPT

iptables -A FORWARD -i ppp0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT 

```

Really, that's all you should need anyway. GRE connection tracking is for firewalls in front of VPN servers...

If that still doesn't work, try connecting a windows box directly to the ppp connection without the firewall. Some (not many, but I've seen it) ISP's block GRE...

Charlie

----------

## nonamey

Thanks for all your help. Unfortunately I still cannot get it working.

 *unclecharlie wrote:*   

> o.k. then try the second option-
> 
> remove your rules and just do
> 
> ```
> ...

 

Tried it and it doesn't work. (I have removed all REJECT, DENY, DROP rules entirely).

 *Quote:*   

> 
> 
> If that still doesn't work, try connecting a windows box directly to the ppp connection without the firewall. Some (not many, but I've seen it) ISP's block GRE...
> 
> 

 

VPN connections through a SOHO router do in fact work (i.e. without the linux firewall).

If anybody has any tips on how I can go about debugging this I would be grateful.

----------

## unclecharlie

nonamey,

One more thing you can try... Use the protocol number (47)instead of the name(GRE) i.e.-

```

iptables -A FORWARD -p 47 -i ppp0 -d 192.168.2.0/255.255.255.0 -j ACCEPT

iptables -A FORWARD -p 47 -i eth0  -s 192.168.2.0/255.255.255.0 -j ACCEPT

```

See if this makes a difference. 

Also, doublecheck your postrouting rules to make sure that the GRE and PPTP packets are both handled

```

iptables -A POSTROUTING -o eth0 -s 192.168.2.0/255.255.255.0 -j SNAT --to-source <EXTERNAL_IP_ADDRESS>

```

putting a protocol flag (like --p tcp) in the above line will break GRE forwarding...  

Otherwise, instead of the -j ACCEPT target, one can use the -j LOG target to troubleshoot. Or you could use ethereal to watch the packets go by. 

Hope this helps,

Charlie

----------

## nonamey

Thanks for your help. Here is what I've done.

 *unclecharlie wrote:*   

> 
> 
> One more thing you can try... Use the protocol number (47)instead of the name(GRE) i.e.-
> 
> ```
> ...

 

Doesn't work

 *Quote:*   

> 
> 
> Or you could use ethereal to watch the packets go by. 
> 
> 

 

Here are the first couple of lines of output of  tcpdump -v proto 47 -i any (while trying to connect to vpn server)

```

20:56:06.138111 IP (tos 0x0, ttl 115, id 38908, offset 0, flags [none], length: 45) vpn_server > ext_ip: [KS] call 32768 seq 1 gre-ppp-payload

20:56:06.148624 IP (tos 0x0, ttl 128, id 40245, offset 0, flags [none], length: 57) 192.168.2.18 > vpn_server: [KS] call 54424 seq 0 gre-ppp-payload

20:56:06.148756 IP (tos 0x0, ttl 127, id 40245, offset 0, flags [none], length: 57) ext_ip > vpn_server: [KS] call 54424 seq 0 gre-ppp-payload

20:56:08.150780 IP (tos 0x0, ttl 128, id 40246, offset 0, flags [none], length: 57) 192.168.2.18 > vpn_server: [KS] call 54424 seq 1 gre-ppp-payload

20:56:08.150902 IP (tos 0x0, ttl 127, id 40246, offset 0, flags [none], length: 57) ext_ip > vpn_server: [KS] call 54424 seq 1 gre-ppp-payload

20:56:08.875515 IP (tos 0x0, ttl 115, id 39555, offset 0, flags [none], length: 51) vpn_server > ext_ip: [KSA] call 32768 seq 2 ack 1 gre-ppp-payload

20:56:09.456809 IP (tos 0x0, ttl 115, id 39591, offset 0, flags [none], length: 45) vpn_server > ext_ip: [KS] call 32768 seq 3 gre-ppp-payload

```

I'm a novice when it comes to deciphering this kind of stuff but it seems to me the packets are being received by the firewall but aren't being forwarded to the internal network.

 *Quote:*   

> 
> 
> Otherwise, instead of the -j ACCEPT target, one can use the -j LOG target to troubleshoot. Or you could use ethereal to watch the packets go by. 
> 
> 

 

I put the following rules in (these should match any incoming GRE packets right?) 

```

iptables -I FORWARD -i ppp0 -p 47 -d 192.168.2.0/255.255.255.0 -j LOG --log-pref

ix "GRE packets" --log-level debug

iptables -t nat -I PREROUTING -i ppp0 -p 47 -d 192.168.2.0/255.255.255.0 -j LOG 

--log-prefix "GRE packets" --log-level debug

iptables -I FORWARD -i ppp0 -p gre -d 192.168.2.0/255.255.255.0 -j LOG --log-pre

fix "GRE packets" --log-level debug

iptables -t nat -I PREROUTING -i ppp0 -p gre -d 192.168.2.0/255.255.255.0 -j LOG

 --log-prefix "GRE packets" --log-level debug

```

But they generate no log output (Logging itself works, tested on other matches).

This is the output of iptables --list

```

Chain INPUT (policy ACCEPT)

target     prot opt source               destination         

ACCEPT     all  --  anywhere             anywhere            

ACCEPT     all  --  anywhere             anywhere            REJECT     udp  --  anywhere             anywhere            udp dpt:bootps reject-with icmp-port-unreachable REJECT     udp  --  anywhere             anywhere            udp dpt:domain reject-with icmp-port-unreachable ACCEPT     tcp  --  anywhere             anywhere            multiport dports 6881:6889 ACCEPT     udp  --  anywhere             anywhere            multiport dports 6881:6889 

DROP       tcp  --  anywhere             anywhere            tcp dpts:0:1023 

DROP       udp  --  anywhere             anywhere            udp dpts:0:1023 

Chain FORWARD (policy ACCEPT)

target     prot opt source               destination         LOG        gre  --  anywhere             192.168.2.0/24      LOG level debug prefix `GRE packets' LOG        gre  --  anywhere             192.168.2.0/24      LOG level debug prefix `GRE packets' 

ACCEPT     tcp  --  anywhere             anywhere            

ACCEPT     gre  --  anywhere             anywhere            

ACCEPT     all  --  192.168.2.0/24       anywhere            

ACCEPT     all  --  anywhere             192.168.2.0/24      

Chain OUTPUT (policy ACCEPT)

target     prot opt source               destination

```

----------

## unclecharlie

nonamey,

remove the prerouting rules and focus on postrouting. That is your issue.

To somewhat oversimplify, Prerouting helps punch holes in your firewall from the outside in. If you have an internal web, mail or VPN server you would use prerouting rules to allow access to them from the Internet. It changes the destination address of each packet so that packets coming from the Internet end up on the Internal server. As long as you are accepting RELATED,ESTABLISHED packets from the outside then your client packets will be handled by NAT. Meaning, you don't need any prerouting rules.

Postrouting allows multiple clients INSIDE the loocal network to access the Internet.

you need a posrouting rule like-

/sbin/iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

if you are using a non-static IP (pppoE, dial-up, etc...)

This changes the source address of each packet on the way out to the External IP address of the firewall so that return packets will be received. (Which is what you need.)

Hope this helps,

Charlie

p.s.- the LOG target only logs packets... If you want them to go through you still need to ACCEPT them with a separate rule

----------

## nonamey

 *unclecharlie wrote:*   

> nonamey,
> 
> you need a posrouting rule like-
> 
> /sbin/iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
> ...

 

Yes, sorry I was maybe a little bit unclear about what I was doing. I do in fact have that exact rule and indeed regular (i.e. non-vpn) connections work fine. I have the prerouting rules for logging (I'm trying to match/log the GRE packets as soon as they hit iptables).

 *Quote:*   

> 
> 
> p.s.- the LOG target only logs packets... If you want them to go through you still need to ACCEPT them with a separate rule

 

The LOG rules I showed were in addition to  the ACCEPT and MASQUERADE rules.

What I was trying to illustrate with my previous post was that it looks to me like the packets are getting recieved by the kernel but are not being passed to iptables.

----------

## nonamey

The problem is now resolved although I'm not sure exactly how.

I recompiled the kernel (removed some l7-filter patches), put compiled CONFIG_NET_IPGRE, CONFIG_IP_NF_PPTP and CONFIG_IP_NF_NAT_PPTP as modules instead of directly into the kernel. 

Not sure if one of the above was the problem or something else that sorted itself out through kernel recompiles and reboots. I don't really have the will to track down the exact cause.

----------

## unclecharlie

nonamey,

just glad it's working... (Isn't linux FUN?)

 :Wink: 

Charlie

----------

## nonamey

 *unclecharlie wrote:*   

> nonamey,
> 
> (Isn't linux FUN?)
> 
> Charlie

 

Yes it is  :Smile: 

Thanks for your help by the way.

----------

## nonamey

As luck would have it I stumbled upon the following:

http://patchwork.netfilter.org/netfilter-devel/patch.pl?id=3175

Apparently pptp_conntrack is broken when not compiled as a module.

I guess this was my problem.

----------

## gagsdsuro

 *nonamey wrote:*   

> As luck would have it I stumbled upon the following:
> 
> http://patchwork.netfilter.org/netfilter-devel/patch.pl?id=3175
> 
> Apparently pptp_conntrack is broken when not compiled as a module.
> ...

 

FYI: I had a similar problem to you until I rebuild the kernel version 2.6.15.

thanks!

-gaetan

----------

## MrZoltan00

I have the same problem, but I don't know how to fix it (linux newbie)

So could someone summarize which rules for iptables I need and what exactly I have to change in the kernel (2.6.13) ??

Would be a great help

----------

