2

I'm configuring an OpenVPN gateway to allow a LAN access to the internet through the tunnel. The gateway is running OpenBSD 5.5-stable amd64 on the PC Engines APU platform.

The LAN contains re1, re2, and ral0 interfaces. It also contains vether0 which hosts the local 192.168.2.0/24 network. These interfaces are linked under bridge0 to provide a common gateway, subnet, and DHCP via dhcpd.

The VPN is established and tun0 is opened. The gateway itself can access the VPN just fine.

The problem is that, by default, the hosts access the VPN with their native 192.168.2.0/24 addresses. NAT is needed to translate the local network to the VPN network at 10.0.1.0/24.

I have tried the following pf.conf configurations:

# pf.conf -- 10.0.1.10 is my tun0 gateway set skip on lo block return pass in quick on { vether0 re1 re2 ral0 } from 192.168.2.0/24 to !10.0.0.0/8 nat-to 10.0.1.10 pass 

I had similar results with these rules:

# pf.conf ... pass in from any nat-to 10.0.1.10 pass out from tun0 to any 

This allows LAN traffic to pass through tun0 with a source address of 10.0.1.10, and return traffic is passed back to the respective host. The new problem is that return traffic still does not appear to be routing correctly.

For example, I can ping 8.8.8.8 and google.com from any LAN host, however the first reply is ALWAYS dropped between tun0 and the return interface. Tools like dig, nslookup, traceroute, and ping are generally sluggish and take far longer than they should. Despite some traffic still passing, browsers and other applications are unusable.

tcpdump demonstrating the loss:

# 192.168.2.103 is a LAN host # 74.125.131.139 is google.com # on ral0 20:59:35.668251 192.168.2.103 > 74.125.131.139: icmp: echo request <-- no reply 20:59:40.651184 192.168.2.103 > 74.125.131.139: icmp: echo request 20:59:40.736748 74.125.131.139 > 192.168.2.103: icmp: echo reply 20:59:41.656101 192.168.2.103 > 74.125.131.139: icmp: echo request 20:59:41.741251 74.125.131.139 > 192.168.2.103: icmp: echo reply 20:59:42.661071 192.168.2.103 > 74.125.131.139: icmp: echo request 20:59:42.802410 74.125.131.139 > 192.168.2.103: icmp: echo reply # on tun0 20:59:35.668359 10.0.1.10 > 74.125.131.139: icmp: echo request 20:59:35.764052 74.125.131.139 > 10.0.1.10: icmp: echo reply <-- here's the missing reply, it didn't get to ral0 20:59:40.651221 10.0.1.10 > 74.125.131.139: icmp: echo request 20:59:40.736721 74.125.131.139 > 10.0.1.10: icmp: echo reply <-- but the of the replies rest did 20:59:41.656138 10.0.1.10 > 74.125.131.139: icmp: echo request 20:59:41.741226 74.125.131.139 > 10.0.1.10: icmp: echo reply 20:59:42.661107 10.0.1.10 > 74.125.131.139: icmp: echo request 20:59:42.802372 74.125.131.139 > 10.0.1.10: icmp: echo reply 

I know that this is almost certainly a NAT issue in pf.conf but after so many configuration attempts I'm having trouble finding the correct way to go about passing traffic.

When I was using DD-WRT and iptables, this was my configuration:

iptables -D FORWARD -i tun1 -j logaccept iptables -D FORWARD -o tun1 -j logaccept 

I'm not sure how to "port" this to pf, though. Any suggestions would be greatly appreciated!

1 Answer 1

0

This turned out to be a pf.conf issue. Some extra time spent studying the OpenBSD PF NAT page lead me to the following rule which allowed traffic to pass correctly through the tun0 interface:

# /etc/pf.conf pass out on tun0 inet from 192.168.2.0/24 to any flags S/SA nat-to (tun0) round-robin 

This essentially reads: pass traffic from the local network destined for any address out on tun0, IPv4 specifically, only look at the syn and ack flags, and perform outbound NAT using tun0. The parentheses around (tun0) tell pf to automatically update the rule when the interface changes its address. This may occur if your VPN supports multiple peers and you failover, and thus manually reloading the ruleset becomes unnecessary.

Some time on the OpenBSD PF Filtering page helped me refine the rule:

# /etc/pf.conf pass out on $vpn_if inet proto { $protos } from $lan_net to any flags S/SA modulate state nat-to ($vpn_if) round-robin pass in on $vpn_if inet proto { $protos } from $vpn_gw to any flags S/SA modulate state 

The modulate state flag allows pf to substitute a stronger Initial Sequence Number which may help protect some operating systems on the network.

The gateway is working great now and I'm onto more complex pf.conf configurations.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.