Having a bit of a time getting stateful firewall with OpenVPN and in-kernel NAT to work, which is a few lines of iptables rules on Linux:
Idea is to allow clients to connect to a server on its public IP running VPN on port 1194. OpenVPN routes its traffic on 10.8.0.0/24 through tun0. Then, that traffic goes out the same interface (vmx0) of the initial incoming connection.
/etc/sysctl.conf additions are:
Relevant additions in /etc/rc.conf are:
I can see packets getting NAT'd, then denied, in /var/log/security:
Had another version of the firewall setup without the check-state and skipto rules, which allowed clients to get an IP from the OpenVPN server. However, those clients couldn't have traffic routed through it nor ping any of the IPs on the 10.8.0.0/24 network. With this setup, connections to the server on port 1194 time out.
All the other services on this machine (SSH, squid, NRPE) work fine. It must be something small and stupid that's missing and can't see what it is. This is FreeBSD 10.2-RELEASE-p9/amd64. If any further information is required, just ask.
Code:
*nat
:pREROUTING ACCEPT [0:0]
:pOSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
-A POSTROUTING -s 10.8.0.0/24 -j SNAT --to-source $WAN_IP
COMMIT
Idea is to allow clients to connect to a server on its public IP running VPN on port 1194. OpenVPN routes its traffic on 10.8.0.0/24 through tun0. Then, that traffic goes out the same interface (vmx0) of the initial incoming connection.
/etc/sysctl.conf additions are:
Code:
net.inet.tcp.blackhole=2
net.inet.udp.blackhole=1
net.inet.ip.portrange.hifirst=25000
net.inet.ip.portrange.hilast=49151
net.inet.ip.redirect=0
net.inet.icmp.drop_redirect=1
net.inet.tcp.sendspace: 65536
net.inet.tcp.recvspace: 65536
net.local.stream.sendspace=65536
net.local.stream.recvspace=65536
net.inet.icmp.maskrepl=0
net.inet.tcp.path_mtu_discovery=1
net.inet.tcp.sack.enable=1
net.inet.icmp.icmplim=1000
net.inet.tcp.syncookies=1
net.inet.ip.fw.dyn_buckets=65536
net.inet.ip.fw.dyn_max=65536
kern.ipc.soacceptqueue=20480
net.inet.tcp.fast_finwait2_recycle=1
net.inet.tcp.finwait2_timeout=10000
kern.ipc.shmmax=68719476736
kern.ipc.shmall=16777216
kern.ipc.shm_use_phys=1
kern.threads.max_threads_per_proc=16384
net.inet.ip.fastforwarding=1
net.inet.ip.forwarding=1
net.inet.ip.fw.one_pass=0
net.inet.ip.fw.verbose=1
net.inet.ip.sourceroute=1
Relevant additions in /etc/rc.conf are:
Code:
firewall_nat_enable="YES"
firewall_nat_interface="vmx0"
firewall_nat_flags="unreg_only reset"
# ipfw nat show config
Code:
ipfw nat 1 config if vmx0 log unreg_only reset
# ipfw -a list
Code:
00100 0 0 allow ip from any to any via lo0
00200 0 0 allow log ip from any to any via tun0
00400 7 420 nat 1 log ip from any to any dst-port 1194 in via vmx0
00500 0 0 check-state
00600 7 420 skipto 65000 tcp from any to any dst-port 1194 in via vmx0 setup keep-state
00700 0 0 skipto 65000 udp from any to any dst-port 1194 in via vmx0 keep-state
00800 0 0 deny ip from 0.0.0.0/8 to any via vmx0
01000 0 0 deny ip from 127.0.0.0/8 to any via vmx0
01100 0 0 deny ip from 169.254.0.0/16 to any via vmx0
01200 0 0 deny ip from 172.16.0.0/12 to any via vmx0
01300 0 0 deny ip from 192.0.2.0/24 to any via vmx0
01400 0 0 deny ip from 192.168.0.0/16 to any via vmx0
01500 0 0 deny ip from 204.152.64.0/23 to any via vmx0
01600 0 0 deny ip from 224.0.0.0/3 to any via vmx0
01700 25 1498 allow ip from me to any dst-port 20,21,22,25,53,80,123,443,465,587,1194,2401,3128,8443,9418 out via vmx0 keep-state
01800 0 0 skipto 65000 tcp from any to any out via vmx0 setup keep-state
01900 0 0 skipto 65000 udp from any to any out via vmx0 keep-state
02000 0 0 allow tcp from any 20-21 to me dst-port 25000-49151 in via vmx0 setup keep-state
02100 54 6224 allow tcp from any to me dst-port 22 in via vmx0 setup keep-state
02200 0 0 allow log tcp from any to me dst-port 1194 in via vmx0 setup keep-state
02250 0 0 allow log udp from any to me dst-port 1194 in via vmx0 keep-state
02300 67 3723 allow tcp from any to me dst-port 3128 in via vmx0 setup keep-state
02400 0 0 allow tcp from $NAGIOS_SERVER to me dst-port 5666 in via vmx0 keep-state
02500 0 0 allow icmp from $NAGIOS_SERVER to me in via vmx0 keep-state
65000 0 0 nat 1 ip from any to any out via vmx0
65100 0 0 deny log ip from me to any out via vmx1
65200 0 0 deny log ip from any to me in via vmx1
65300 0 0 deny log ip from me to any out via vmx2
65400 0 0 deny log ip from any to me in via vmx2
65500 12 712 deny log ip from any to any
65535 0 0 deny ip from any to any
I can see packets getting NAT'd, then denied, in /var/log/security:
Code:
Apr 22 22:39:06 $HOST kernel: ipfw: 400 Nat TCP $MY_IP:56640 $SERVER_IP:1194 in via vmx0
Apr 22 22:39:06 $HOST kernel: ipfw: 65500 Deny TCP $MY_IP:56640 $SERVER_IP:1194 in via vmx0
Had another version of the firewall setup without the check-state and skipto rules, which allowed clients to get an IP from the OpenVPN server. However, those clients couldn't have traffic routed through it nor ping any of the IPs on the 10.8.0.0/24 network. With this setup, connections to the server on port 1194 time out.
All the other services on this machine (SSH, squid, NRPE) work fine. It must be something small and stupid that's missing and can't see what it is. This is FreeBSD 10.2-RELEASE-p9/amd64. If any further information is required, just ask.
Last edited by a moderator: