NAT for use with OpenVPN

Morgan Wesström freebsd-database at pp.dyndns.biz
Sat Nov 9 19:41:19 UTC 2019


I was hoping someone more experienced than myself would chip in and help 
you but since I run a similar setup I'll show you my configuration. I'm 
not perfectly clear on your physical network layout so you have to adapt 
my suggestions as needed. I run my OpenVPN server on the same physical 
machine as my router/firewall.

Here are the needed parts from /etc/pf.conf

ext_if = "em0"
vpn_if = "tun0"

The following two rules take care of all nat:

nat on $ext_if inet proto udp from !($ext_if) to any -> ($ext_if) 
static-port
nat on $ext_if inet from !($ext_if) to any -> ($ext_if) port 1024:65535

The ! is a logical NOT so the rules will nat from any interface that is 
NOT em0 to my external interface em0. I nat udp separately to force it 
to keep the source and destination ports.

You need to allow inbound traffic on the OpenVPN port:

pass in quick on $ext_if proto udp from any to ($ext_if) port 1194 keep 
state

You also need to pass traffic on the tun interface. I trust my clients 
so I pass everything.

pass quick on $vpn_if all

Those are all the OpenVPN related rules I have in /etc/pf.conf. I don't 
run IPv6 over my OpenVPN so you need to allow for that if needed.

My OpenVPN config is short and pretty standard. I push the default 
gateway to my clients to force all traffic from them to actually go 
through the tunnel. You need to adjust your OpenVPN network address, LAN 
DOMAIN name and your DNS server address.

port 1194
proto udp4
dev tun0
ca ca.crt
cert server.crt
key server.key
dh dh1024.pem
server 192.168.169.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DOMAIN local"
push "dhcp-option DNS 192.168.69.2"
keepalive 10 120
user nobody
group nobody
persist-key
persist-tun
status /dev/null
log-append openvpn.log
verb 3

> This seems to be working, except that I get some warnings in the OpenVPN
> log about "PID_ERR replay-window backtrack occurred [1] [SSL-0]"
> 
> Three questions:
> 
> 1. Is this error something I need to be concerned about?

I have not seen this error. Someone more knowledgable in OpenVPN need to 
help you here.

> 2. Since the router I have between the server machine and the internet has
> a firewall, do I need to worry about any other rules in the pf ruleset?
> (i.e. is it safe to use my modified version of the handbook example?)

Are you running OpenVPN on a separate machine behind your 
router/firewall? Does it too run FreeBSD? Does it have pf enabled?

If your OpenVPN server is on a machine behind the router/firewall you 
need an rdr rule to forward port 1194 from your router to the correct 
machine and the pass rule for traffic on port 1194 would need to refer 
to the OpenVPN server ip instead of ext_if. The pass rule for tun0 would 
not be needed. This is different from how I run my setup and additional 
configuration would be needed on the OpenVPN server itself if you have 
enabled pf on it.

> 3. I don't intend to change the server machine's IP address, so I
> eliminated the "($ext_if)" and replaced it with the server's static
> address. Using the ($ext_if) and running pfctl -vnf /etc/pf.conf results in
> reporting "(em0) round robin" instead of the actual IP of the server. This
> seems to work, but is it really necessary?

As I understand it it's helpful to people who run dynamic ip addresses 
on their external interfaces.

Regards
Morgan


More information about the freebsd-pf mailing list