How Shorewall Can Break OpenVPN
I’ve been administering OpenVPN for years now, and I’ve been quite happy with it. For the most part it’s given me very little grief. The only frequent problem comes from users with a personal firewall who unwittingly block all VPN traffic.
I’ve recently upgraded to version 2.0.9, without memorable incident. It has caused me, however, to revisit the problem I had with the old installation concerning MTUs. I had found — as have many others out there — that the only way to get a reliable tunnel over UDP was to fiddle with the various MTU and fragmentation parameters, settling on a configuration that apparently worked but without the satisfaction of understanding why.
This time round I left all that mssfix and fragment guff out of the configuration to see what would happen. Maybe it’s not necessary any more? Well apparently it won’t go away that easily. Once again I find that an OpenVPN client can connect reliably but cannot necessarily get any traffic through the tunnel. In fact it depends on the client: most users don’t have a problem, but one usually does. The distinguishing features of this client is that it’s across the pond in the US and that it’s connecting through a cable router (PPPoE). The evidence of the problem appears in the OpenVPN log like this:
Wed Oct 1 17:25:49 2008 22.214.171.124:33041 [fred] Peer Connection Initiated with 126.96.36.199:33041
Wed Oct 1 17:25:50 2008 fred/188.8.131.52:33041 PUSH: Received control message: 'PUSH_REQUEST'
Wed Oct 1 17:25:50 2008 fred/184.108.40.206:33041 SENT CONTROL [fred] 'PUSH_REPLY,route-gateway 10.0.10.254 255.255.255.0,route 192.168.0.0 255.255.255.0,route 192.168.10.0 255.255.255.0,route 192.168.150.1 255.255.255.255,route 172.16.0.0 255.255.255.0,route 172.17.0.0 255.255.255.0,ping 10,ping-restart 120' (status=1)
Wed Oct 1 17:31:21 2008 read UDPv4 [ECONNREFUSED]: Connection refused (code=61)
Wed Oct 1 17:31:31 2008 read UDPv4 [ECONNREFUSED]: Connection refused (code=61)
Wed Oct 1 17:31:41 2008 read UDPv4 [ECONNREFUSED]: Connection refused (code=61)
Wed Oct 1 17:34:15 2008 read UDPv4 [ECONNREFUSED]: Connection refused (code=61)
Wed Oct 1 17:34:26 2008 read UDPv4 [ECONNREFUSED]: Connection refused (code=61)
Wed Oct 1 17:34:35 2008 read UDPv4 [ECONNREFUSED]: Connection refused (code=61)
Wed Oct 1 17:34:45 2008 NOTE: --mute triggered...
Wed Oct 1 17:35:11 2008 fred/220.127.116.11:33041 3 variation(s) on previous 20 message(s) suppressed by --mute
Wed Oct 1 17:35:11 2008 fred/18.104.22.168:33041 [fred] Inactivity timeout (--ping-restart), restarting
Wed Oct 1 17:35:11 2008 fred/22.214.171.124:33041 SIGUSR1[soft,ping-restart] received, client-instance restarting
After some fresh research I now have a better grasp of what might be going on. Surprisingly, it would appear to be my Shorewall set-up that’s to blame.
Here’s the theory: the path between the client and the server has a reduced MTU (at the cable modem at the least) and that the path MTU discovery is not effective, causing the OpenVPN server to be unaware that its packets are not reaching the client. Why? Because the path MTU discovery is effected by sending an ICMP type 3 datagram from the node with the reduced MTU back to the sending server, and the example Shorewall configuration that I started from blocks all incoming ICMP except ping!
The example configuration I started from is in examples/three-interfaces/ in the distribution. The relevant section is as follows.
Ping/ACCEPT loc $FW
Ping/ACCEPT dmz $FW
Ping/ACCEPT loc dmz
Ping/ACCEPT dmz loc
Ping/ACCEPT dmz net
ACCEPT $FW net icmp
ACCEPT $FW loc icmp
ACCEPT $FW dmz icmp
The default policy for net->$FW is DROP, so the configuration above does not permit any incoming ICMP packets except PING. Unless there’s some back-door exception for ICMP type 3 that I can’t see, the path MTU discovery will be broken by this configuration.
 – PMTU (Path MTU) Discovery – http://www.netheaven.com/pmtu.html
 – OpenVPN FAQ – http://openvpn.net/index.php/documentation/faq.html#mtu