Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm troubleshooting an OpenVPN Server setup on OS X Mavericks. Prior to the 10.9 upgrade, this all worked, and I'm trying to isolate the problem to something fundamental or my server/client setup.

VPN clients are able to make TCP connections to the entire Internet and every box on the LAN except for the VPN server itself. Furthermore, VPN clients are able to successfully ping and traceroute the server, which is one hop away.

I'm at a loss and would appreciate any pointers.

My server is 10.0.1.3 on 10.0.1/24 interface en0. My VPN is on 10.8.0/24 on tun0. The firewall is disabled, but it is necessary to enable NAT on the pf-based firewall for client access to the Internet, which is done using the pfctl pf.conf lines,

nat on en0 from { 10.8.0.0/24 10.0.1.0/24 } to any -> (en0)
pass all

The broken TCP return link observed between the server and client exists whether or not the firewall is enabled, causing me to rule out the firewall as the cause. Packet forwarding is enabled with the BSD commands:

/usr/sbin/sysctl -w net.inet.ip.fw.enable=1
/usr/sbin/sysctl -w net.inet.ip.forwarding=1

It appears that the VPN is not returning [SYN,ACK] packets correctly from the server to the VPN client over tun0. What would prevent packets from VPN clients reaching the LAN through the tun0 interface? Packets to the VPN client are being returned on en0, not tun0, and this is breaking the connection. This illustrated with this example below using wireshark to capture port 22 packets on tun0 and en0. Here's what I see on wireshark:

server [10.0.1.3]$ ssh mobile@10.8.0.10   # Successful

tun0:

10.8.0.1 -> 10.8.0.10 ssh [SYN]
10.8.0.10 ssh -> 10.8.0.1 [SYN,ACK]
10.8.0.1 -> 10.8.0.10 ssh [ACK]
...

en0:

<No packets>


iPhone [10.8.0.10]$ ssh user@10.0.1.3   # Unsuccessful

tun0:

10.8.0.10 -> 10.0.1.3 ssh [SYN]
10.8.0.10 [TCP Retransmission] -> 10.0.1.3 ssh [SYN]
10.8.0.10 [TCP Retransmission] -> 10.0.1.3 ssh [SYN]
10.8.0.10 [TCP Retransmission] -> 10.0.1.3 ssh [SYN]
10.8.0.10 [TCP Retransmission] -> 10.0.1.3 ssh [SYN]
...

en0:

10.0.1.3 ssh -> 10.8.0.10 [SYN,ACK]
10.0.1.3 [TCP Retransmission] ssh -> 10.8.0.10 [SYN,ACK]
10.0.1.3 [TCP Retransmission] ssh -> 10.8.0.10 [SYN,ACK]
10.0.1.3 [TCP Retransmission] ssh -> 10.8.0.10 [SYN,ACK]
10.0.1.3 [TCP Retransmission] ssh -> 10.8.0.10 [SYN,ACK]
10.0.1.3 [TCP Retransmission] ssh -> 10.8.0.10 [SYN,ACK]
...

I'm working through the book Network Troubleshooting Tools trying to track this down. Its first example using netstat shows a routing table that looks like this, with explicit resolution for the 172.16.2.1 and 172.16.2.255 addresses.

bsd1# netstat -rn
Routing tables
Internet:
Destination
…
172.16.1/24 172.16.2.1 xl1
172.16.2/24 link#2 xl1
172.16.2.1 0:10:7b:66:f7:62 xl1
172.16.2.255 ff:ff:ff:ff:ff:ff xl1

But my actual routing table for tun0 looks like this:

server$ netstat -rn
default 10.0.1.1 UGSc 157 21721 en0
…
10.8/24 10.8.0.2 UGSc 1 6 tun0
10.8.0.2 10.8.0.1 UH 2 0 tun0

There's nothing explicit for 10.8.0.1 or 10.8.0.255 on the tun0 interface—should there be? If so, how do add I this route? Could this be why return packets from the server are being sent back on the default en0 interface?

Any pointers would be greatly appreciated.

share|improve this question

migrated from networkengineering.stackexchange.com Nov 17 '13 at 19:00

This question came from our site for network engineers.

    
Why are you NATting? Shouldn't that be done further upstream toward the edge? –  Michael Hampton Nov 17 '13 at 19:36
    
This is tangential, but I'm NATing because that's the standard way to get OpenVPN clients internet access on a server behind a router NAT. It used to be using natd/ipfw, but those are deprecated on Mavericks, so you use pfctl. I mention it above only to say that the VPN client has access to EVERYTHING EXCEPT the VPN server. The NAT and firewall don't have an impact on this problem—it persists if the firewall and NAT are completely disabled. I should be able to access TCP services on the server from the client NAT or no NAT. –  stvs Nov 17 '13 at 20:45
    
It's the router NAT that needs to do the NATting. Generally it shouldn't be necessary to double NAT. –  Michael Hampton Nov 17 '13 at 20:46
    
NAT isn't the issue. If there's a way to provide OpenVPN clients internet access from a server behind a router NAT, I'm not aware of it, but this doesn't have anything to do with the client not being able to access the server's TCP services. –  stvs Nov 17 '13 at 20:50
    
Thanks to this thread, <serverfault.com/questions/478058/…;, I'm closer to a solution. The server's TCP services ARE all available via the VPN Server's IP, e.g. "ssh user@10.8.0.1" works, as does hitting 10.8.0.1. The remaining trick is to set up the routing tables (somewhere—client? server? both?) so that TCP access like "ssh user@10.0.1.3" will work. –  stvs Nov 17 '13 at 21:31

1 Answer 1

As you rightly indicated in your last comment, this is a routing issue. I had a similar situation where I wanted all my OpenVPN clients (in my case network 10.8.0.0/24 on tun0) to be NAT-ed (or masqueraded) with the en0 interface (in my case 172.16.172.2/24) address of my OpenVPN server when accessing the local network 172.16.172.0/24

The symptom was that I could access all hosts on the 172.16.172.0/24 network, but not 172.16.172.2 itself and I had to revert to reaching the OpenVPN server through its tun0 interface address but the problem bugged me.

After a lot of try and error, I found the solution. The pass line below in pf.conf will ensure that packets arriving on the VPN interface from the VPN network addressed to the OpenVPN server's internal interface are routed back out on the VPN interface. Note also my nat lines - I am essentially preventing NAT if traffic is destined for the internal interface.

int_if="en0"
vpn_if="tun0"
vpnnet="10.8.0.0/24"
no nat on ! $vpn_if from $vpnnet to ($int_if)
nat on ! $vpn_if from $vpnnet to any -> ($int_if)
pass in log quick on $vpn_if reply-to $vpn_if from $vpnnet to $int_if
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.