OpenVPN and PF

I use an old HP thinclient, running ArchLinux, as an OpenPVN-server. This has always been running fine, until I replaced the old router, running Gentoo/iptables, with a new router, running FreeBSD9/PF. Since than, the connection with the client is terminated every 20 minutes, or so.

Here are the relevant OpenVPN logs

Client log - connected at 10:11 and terminated at 10:31
Code:
Jun 14 10:11:16: Initialization Sequence Completed
Jun 14 10:31:45: read TCPv4_CLIENT: Operation timed out (code=60)
Jun 14 10:31:45: Connection reset, restarting [0]
Jun 14 10:31:45: SIGUSR1[soft,connection-reset] received, process restarting
Jun 14 10:31:46: WARNING: No server certificate verification method has been enabled. See http://openvpn.net/howto.html#mitm for more info.
Jun 14 10:31:46: NOTE: OpenVPN 2.1 requires '--script-security 2' or higher to call user-defined scripts or executables
Jun 14 10:31:46: Re-using SSL/TLS context
Jun 14 10:31:46: LZO compression initialized
Jun 14 10:31:46: Attempting to establish TCP connection with xxx.xxx.xxx.xxx:1194 [nonblock]
Jun 14 10:31:56: TCP: connect to xxx.xxx.xxx.xxx:1194 failed, will try again in 5 seconds: Operation timed out
Jun 14 10:32:09: TCP connection established with xxx.xxx.xxx.xxx:1194
Jun 14 10:32:09: TCPv4_CLIENT link local: [undef]
Jun 14 10:32:09: TCPv4_CLIENT link remote: xxx.xxx.xxx.xxx:1194
Jun 14 10:32:10: [server] Peer Connection Initiated with xxx.xxx.xxx.xxx:1194
Jun 14 10:32:12: Preserving previous TUN/TAP instance: tap0
Jun 14 10:32:12: Initialization Sequence Completed


Server log
Code:
Thu Jun 14 10:11:20 2012 username/yyy.yyy.yyy.yyy:39685 SENT CONTROL [username]: 'PUSH_REPLY,route-gateway zzz.zzz.zzz.zzz,ping 10,ping-restart 120,ifconfig aaa.aaa.aaa.aaa 255.255.255.0' (status=1)
Thu Jun 14 10:11:20 2012 username/yyy.yyy.yyy.yyy:39685 MULTI: Learn: ca:f0:71:0e:bc:4d -> username/yyy.yyy.yyy.yyy:39685
Thu Jun 14 10:31:09 2012 username/yyy.yyy.yyy.yyy:39685 read TCPv4_SERVER []: No route to host (code=113)
Thu Jun 14 10:31:13 2012 username/yyy.yyy.yyy.yyy:39685 read TCPv4_SERVER []: No route to host (code=113)
Thu Jun 14 10:31:16 2012 username/yyy.yyy.yyy.yyy:39685 read TCPv4_SERVER []: No route to host (code=113)
Thu Jun 14 10:31:20 2012 username/yyy.yyy.yyy.yyy:39685 read TCPv4_SERVER []: No route to host (code=113)
Thu Jun 14 10:31:24 2012 username/yyy.yyy.yyy.yyy:39685 read TCPv4_SERVER []: No route to host (code=113)
Thu Jun 14 10:31:29 2012 username/yyy.yyy.yyy.yyy:39685 read TCPv4_SERVER []: No route to host (code=113)
Thu Jun 14 10:31:34 2012 username/yyy.yyy.yyy.yyy:39685 read TCPv4_SERVER []: No route to host (code=113)
Thu Jun 14 10:31:39 2012 username/yyy.yyy.yyy.yyy:39685 read TCPv4_SERVER []: No route to host (code=113)
Thu Jun 14 10:31:43 2012 username/yyy.yyy.yyy.yyy:39685 read TCPv4_SERVER []: No route to host (code=113)
Thu Jun 14 10:31:48 2012 username/yyy.yyy.yyy.yyy:39685 read TCPv4_SERVER []: No route to host (code=113)
Thu Jun 14 10:32:13 2012 MULTI: multi_create_instance called
Thu Jun 14 10:32:13 2012 Re-using SSL/TLS context
Thu Jun 14 10:32:13 2012 LZO compression initialized
Thu Jun 14 10:32:13 2012 Control Channel MTU parms [ L:1576 D:168 EF:68 EB:0 ET:0 EL:0 ]
Thu Jun 14 10:32:13 2012 Data Channel MTU parms [ L:1576 D:1450 EF:44 EB:135 ET:32 EL:0 AF:3/1 ]
Thu Jun 14 10:32:13 2012 Local Options hash (VER=V4): '3c14feac'
Thu Jun 14 10:32:13 2012 Expected Remote Options hash (VER=V4): 'e39a3273'
Thu Jun 14 10:32:13 2012 TCP connection established with yyy.yyy.yyy.yyy:44082
Thu Jun 14 10:32:13 2012 TCPv4_SERVER link local: [undef]
Thu Jun 14 10:32:13 2012 TCPv4_SERVER link remote: yyy.yyy.yyy.yyy:44082
Thu Jun 14 10:32:13 2012 yyy.yyy.yyy.yyy:44082 TLS: Initial packet from yyy.yyy.yyy.yyy:44082, sid=23f4ac5a 786fe636
Thu Jun 14 10:32:14 2012 yyy.yyy.yyy.yyy:44082 VERIFY OK: depth=1, /C=NL/ST=FL/L=Urk/O=GBU/CN=GBU_CA/emailAddress=user@domain.com
Thu Jun 14 10:32:14 2012 yyy.yyy.yyy.yyy:44082 VERIFY OK: depth=0, /C=NL/ST=FL/L=Urk/O=GBU/CN=username/emailAddress=user@domain.com
Thu Jun 14 10:32:14 2012 yyy.yyy.yyy.yyy:44082 Data Channel Encrypt: Cipher 'BF-CBC' initialized with 128 bit key
Thu Jun 14 10:32:14 2012 yyy.yyy.yyy.yyy:44082 Data Channel Encrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Thu Jun 14 10:32:14 2012 yyy.yyy.yyy.yyy:44082 Data Channel Decrypt: Cipher 'BF-CBC' initialized with 128 bit key
Thu Jun 14 10:32:14 2012 yyy.yyy.yyy.yyy:44082 Data Channel Decrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Thu Jun 14 10:32:14 2012 yyy.yyy.yyy.yyy:44082 Control Channel: TLSv1, cipher TLSv1/SSLv3 DHE-RSA-AES256-SHA, 1024 bit RSA
Thu Jun 14 10:32:14 2012 yyy.yyy.yyy.yyy:44082 [username] Peer Connection Initiated with yyy.yyy.yyy.yyy:44082
Thu Jun 14 10:32:14 2012 username/yyy.yyy.yyy.yyy:44082 TCP/UDP: Closing socket
Thu Jun 14 10:32:14 2012 MULTI: new connection by client 'username' will cause previous active sessions by this client to be dropped.
  Remember to use the --duplicate-cn option if you want multiple clients using the same certificate or username to concurrently connect.
Thu Jun 14 10:32:16 2012 username/yyy.yyy.yyy.yyy:44082 PUSH: Received control message: 'PUSH_REQUEST'
Thu Jun 14 10:32:16 2012 username/yyy.yyy.yyy.yyy:44082 SENT CONTROL [username]: 'PUSH_REPLY,route-gateway zzz.zzz.zzz.zzz,ping 10,ping-restart 120,ifconfig aaa.aaa.aaa.aaa 255.255.255.0' (status=1)
Thu Jun 14 10:32:37 2012 username/yyy.yyy.yyy.yyy:44082 MULTI: Learn: ca:f0:71:0e:bc:4d -> username/yyy.yyy.yyy.yyy:44082


I think the problem is in PF. So my question is, how should I configure PF to make sure OpenVPN works right?

These are the PF-rules involved
Code:
int_if = "em0"
ext_if = "em1"
loc_nw = "127.0.0.0/8"
int_nw = "192.168.1.0/24"
table <int_nw> { $loc_nw, $int_nw, }

rdr pass on $ext_if proto { tcp,udp } from any to any port 1194 -> 192.168.1.8

### Al het uitgaande verkeer vanaf de interne netwerken doorlaten
pass out on $ext_if from <int_nw> to any keep state

### allow all traffic from internal network to internal interface
pass in on $int_if from <int_nw> to any keep state
pass out on $int_if from any to any keep state

### allow all traffic out via external interface
pass out on $ext_if proto tcp all modulate state flags S/SA
pass out on $ext_if proto { udp, icmp } all keep state
Oh, any recommendations regarding the whole passing outgoing traffic are welcome too. ;)
 
OpenVPN uses a tun interface. If you do not have other tun interfaces, it will be tun0. Perhaps you should put something like:

Code:
pass on tun0 inet all

As for the outbound traffic, I do not see the point in stopping something getting out, if I had already let it in. Try to be restrictive with inbound rules, then pass everything out with something like:
Code:
pass out keep state
 
OpenVPN uses a tun interface.
There is no tun interface. Not on the anyway, since the FreeBSD router anyway, since OpenVPN runs on another host. [ What? -- Mod. ]

As for the outbound traffic, I do not see the point in stopping something getting out
I think blocking all outgoing traffic on port 25 for all hosts, except the mailserver, is a very good idea. If one of the hosts get infected and tries to send out loads of spam, it will get nowhere. Not only will I help myself by preventing my IP ending up on lots of blacklists, it will also help others, since they will never get the spam that was send out to them.
 
I would say that the most logical place to put a VPN server is the NAT gateway itself, not another box behind it. I have both OpenVPN and PopTop (PPTP) on my NAT gateway, serving daily up to 30 concurrent sessions. I used to have problems with PPTP when it terminated on Cisco router behind NAT gateway, which disappeared since i moved it.

I think a routed (tun) type of VPN will serve you much better than a bridged (tap) one.

I think you would do better if you blocked port 25 entering the inbound interface:

Code:
block in log on $int_if from !$smtp_server to any
 
There is one other caveat when using OpenVPN and PF. OpenVPN uses UDP (by default, and ideally) for connections, which is stateless. Also, it does not use keepalives (AKA pings, essentially a null, one-way UDP packet in OpenVPN) by default, so if you use stateful UDP, which you are judging from your firewall rules, long periods of an idle connection can cause the state to be removed from the PF state table (as UDP is not inherently stateful).

Two ways around this are to use keepalives (what I do for my OpenVPN tunnels) or to use stateless rules so keepalives are unnecessary. If you do use keepalives/pings in OpenVPN and stateful rules, be aware that they are only sent one-way by default and are not echoed like ICMP pings are, so you may want to configure them on both client and server, especially if you have different stateful UDP timeouts on each end.
 
Back
Top