IPFW digital ocean vpn works for IPFW "open", now trying to do a secure firewall

Searching the forums, I can't seem to find a definitive solution to what IPFW rules are needed for openvpn. (I've found many solutions I can't get to work.)

The obligatory uname:
Code:
# uname -a
FreeBSD peets 11.0-RELEASE-p9 FreeBSD 11.0-RELEASE-p9 #0: Tue Apr 11 08:48:40 UTC 2017     root@amd64-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC  amd64

I verified the openvpn setup works using the "open" rules for IPFW. For completeness, this is the output of ipfw list when "open" is selected. I suspect the "allow ip for any to any" is what makes openvpn work under the "open" rules.

Rules when "open" is selected.
Code:
# ipfw list
00050 divert 8668 ip4 from any to any via vtnet0
00100 allow ip from any to any via lo0
00200 deny ip from any to 127.0.0.0/8
00300 deny ip from 127.0.0.0/8 to any
00400 deny ip from any to ::1
00500 deny ip from ::1 to any
00600 allow ipv6-icmp from :: to ff02::/16
00700 allow ipv6-icmp from fe80::/10 to fe80::/10
00800 allow ipv6-icmp from fe80::/10 to ff02::/16
00900 allow ipv6-icmp from any to any ip6 icmp6types 1                         01000 allow ipv6-icmp from any to any ip6 icmp6types 2,135,136                 65000 allow ip from any to any                                                 65535 deny ip from any to any

This is my current firewall. I added some rules for port 1194. The openvpn "connects". The tunnel is built on 10.8.0.6. However I can't shall we say dial out. That is chrome won't connect. (yeah I see IPsec ports. To be removed.)

Code:
00100 allow ip from any to any via lo0
00200 deny ip from any to 127.0.0.0/8
00300 deny ip from 127.0.0.0/8 to any
00400 deny ip from any to ::1
00444 allow log udp from any to any dst-port 1194 keep-state
00445 allow log udp from any 1194 to any keep-state
00500 deny ip from ::1 to any
<snip>
various ssh and email port blocks
<snip>
00600 allow ipv6-icmp from :: to ff02::/16
00700 allow ipv6-icmp from fe80::/10 to fe80::/10
00800 allow ipv6-icmp from fe80::/10 to ff02::/16
00900 allow ipv6-icmp from any to any ip6 icmp6types 1
01000 allow ipv6-icmp from any to any ip6 icmp6types 2,135,136
01100 check-state
01200 allow tcp from me to any established
01300 allow tcp from me to any setup keep-state
01400 allow udp from me to any keep-state
01500 allow icmp from me to any keep-state
01600 allow ipv6-icmp from me to any keep-state
01700 allow udp from 0.0.0.0 68 to 255.255.255.255 dst-port 67 out
01800 allow udp from any 67 to me dst-port 68 in
01900 allow udp from any 67 to 255.255.255.255 dst-port 68 in
02000 allow udp from fe80::/10 to me dst-port 546 in
02100 allow icmp from any to any icmptypes 8
02200 allow ipv6-icmp from any to any ip6 icmp6types 128,129
02300 allow icmp from any to any icmptypes 3,4,11
02400 allow ipv6-icmp from any to any ip6 icmp6types 3
02500 allow tcp from any to me dst-port 22
02600 allow tcp from any to me dst-port 443
02700 allow tcp from any to me dst-port 500
02800 allow tcp from any to me dst-port 143
02900 allow tcp from any to me dst-port 993
03000 allow tcp from any to me dst-port 995
03100 allow tcp from any to me dst-port 25
03200 allow tcp from any to me dst-port 465
03300 allow tcp from any to me dst-port 587
03400 allow tcp from any to me dst-port 4500
03500 allow udp from any to any dst-port 123
05004 allow tcp from any to me dst-port 8000 setup limit src-addr 3
05005 allow tcp from any to me dst-port 80 setup limit src-addr 10
65000 count ip from any to any
65100 deny { tcp or udp } from any to any dst-port 135-139,445 in
65200 deny { tcp or udp } from any to any dst-port 1026,1027 in
65300 deny { tcp or udp } from any to any dst-port 1433,1434 in
65400 deny ip from any to 255.255.255.255
65500 deny ip from any to 224.0.0.0/24 in
65500 deny udp from any to any dst-port 520 in
65500 deny tcp from any 80,443 to any dst-port 1024-65535 in
65500 deny log logamount 500 ip from any to any
65535 deny ip from any to any

Here is rc.conf.
Code:
sshd_enable="YES"
digitaloceanpre="YES"
cloudinit_enable="YES"
digitalocean="YES"
syslogd_enable="YES"            # Run syslog daemon (or NO).
syslogd_program="/usr/sbin/syslogd" # path to syslogd, if you want a different one.
syslogd_flags="-s -c -c"           # Flags to syslogd (if enabled).
#sshd_enable="YES"
php_fpm_enable="NO"
nginx_enable="YES"
sshguard_enable="YES"
firewall_enable="YES"
firewall_quiet="YES"
#firewall_type="open"
firewall_type="workstation"
firewall_myservices="22    443   500 imap imaps  pop3s smtp smtps submission 4500 "
#firewall_myservices="22  80  443   500 imap imaps  pop3s smtp smtps submission 4500 "
#firewall_myservices="22  80  443   500 imap  imaps pop3 pop3s  submission 4500 "
firewall_allowservices="any"
firewall_logdeny="YES"
postfix_enable="YES"
dovecot_enable="YES"
milteropendkim_enable="YES"
milteropendkim_uid="opendkim"
# If you not need sendmail anymore, please add these 4 lines in your rc.conf:
sendmail_enable="NO"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"
gateway_enable="YES"
natd_enable="YES"
natd_interface="vtnet0"
natd_flags="-dynamic -m"
openvpn_enable="YES"
openvpn_configfile="/usr/local/etc/openvpn/server.conf"
hostname="peets"

# DigitalOcean Dynamic Configuration lines and the immediate line below it,
# are removed each boot. Hostname is set each boot.

# DigitalOcean Dynamic Configuration
defaultrouter="138.68.40.1"
# DigitalOcean Dynamic Configuration
ifconfig_vtnet0="inet 138.68.45.241 netmask 255.255.248.0"
# DigitalOcean Dynamic Configuration
ifconfig_vtnet0_alias0="inet 10.46.0.5 netmask 255.255.0.0"
# DigitalOcean Dynamic Configuration
ifconfig_vtnet1="inet 10.138.144.133 netmask 255.255.0.0"
# DigitalOcean Dynamic Configuration
ifconfig_vtnet0_ipv6="inet6  prefixlen 0"
# DigitalOcean Dynamic Configuration
ipv6_defaultrouter=""
# DigitalOcean Dynamic Configuration
ipv6_activate_all_interfaces="yes"

Output from ifconfig. Note nothing is connected to openvpn at the moment. When it is used, the tunnel uses 10.8.0.6.
Code:
# ifconfig
vtnet0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=6c07bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
        ether 26:d6:00:ec:8f:0a
        inet6 fe80::24d6:ff:feec:8f0a%vtnet0 prefixlen 64 scopeid 0x1 
        inet 138.68.45.241 netmask 0xfffff800 broadcast 138.68.47.255 
        inet 10.46.0.5 netmask 0xffff0000 broadcast 10.46.255.255 
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
        media: Ethernet 10Gbase-T <full-duplex>
        status: active
vtnet1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=6c07bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
        ether e6:47:f0:9d:29:c6
        inet6 fe80::e447:f0ff:fe9d:29c6%vtnet1 prefixlen 64 scopeid 0x2 
        inet 10.138.144.133 netmask 0xffff0000 broadcast 10.138.255.255 
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
        media: Ethernet 10Gbase-T <full-duplex>
        status: active
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
        options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
        inet6 ::1 prefixlen 128 
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x3 
        inet 127.0.0.1 netmask 0xff000000 
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
        groups: lo 
tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1500
        options=80000<LINKSTATE>
        inet6 fe80::2866:24cc:2d85:1478%tun0 prefixlen 64 scopeid 0x4 
        inet 10.8.0.1 --> 10.8.0.2  netmask 0xffffffff 
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
        groups: tun 
        Opened by PID 894

Some threads suggest these lines should be added.
Code:
# cat loader.conf
ipfw_nat_load=YES
libalias_load=YES
 
Can you post the output of netstat -rn before and after the VPN has come up? I have a feeling it's routing related. Firewalling OpenVPN really doesn't involve much more than allowing UDP to/from port 1194 (we have several OpenVPN instances going through a hardware firewall). Apparently that's working correctly because you are able to get a connection.
 
Weird I never got an email about your reply. Tell you what I did, and you can say good idea, are you nuts, etc.

I spent some time observing the security log of the open configuration, adding "log" to the rules. I believe the following lines are what you need to make openvpn work, and it doesn't use NAT so I may be doing this wrong.

First of all, the default rule number 50 is required. I should point out I'm using an awful hacked up version of the FreeBSD default firewall with server selected. On my bucket list is to do better, but probably it would make more sense to learn pfsense if I was to do anything from scratch.

This line would be used in the "open" case, which is case Oo. I just copied and pasted it above the case statement so that it would be used in the "server" case. (Yes this is lame.)

Code:
${fwcmd} add 50 divert natd ip4 from any to any via ${natd_interface}
case ${firewall_type} in
[Oo][Pp][Ee][Nn]|[Cc][Ll][Ii][Ee][Nn][Tt])

Looking at what was denied in /var/log/security, I wrote rules to allow those states.
Code:
#adding these lines for openvpn

${fwcmd} add  430 allow log udp from any to any dst-port 1194 keep-state
${fwcmd} add  435 allow log tcp from 10.8.0.0/24  to any keep-state
${fwcmd} add  436 allow log tcp from any  to 10.8.0.0/24 keep-state
${fwcmd} add  436 allow log udp from 10.8.0.0/24 to 8.8.8.8
${fwcmd} add  437 allow log udp from 10.8.0.0/24 to 8.8.8.4
${fwcmd} add  438 allow log udp from 8.8.8.8 to 10.8.0.0/24
${fwcmd} add  439 allow log udp from 8.8.8.4 to 10.8.0.0/24

So I don't use the "tun" explicitly except in the divert statement. But implicitly I use the tunnel since I use the local network created at CIDR 10.8.0.0/24.

I'll be the first to admit this isn't kosher. I'm just trying to do something a little bit better than just running the firewall on open. I'm willing to try other ideas. I'm using a test VPN, so hacking it is no big deal.

Here is the netstat.

Code:
# netstat -rn
Routing tables

Internet:
Destination        Gateway            Flags     Netif Expire
default            138.68.40.1        UGS      vtnet0
10.8.0.0/24        10.8.0.2           UGS        tun0
10.8.0.2           link#4             UH         tun0
10.46.0.0/16       link#1             U        vtnet0
10.46.0.5          link#1             UHS         lo0
10.138.0.0/16      link#2             U        vtnet1
10.138.144.133     link#2             UHS         lo0
127.0.0.1          link#3             UH          lo0
138.68.40.0/21     link#1             U        vtnet0
138.68.45.241      link#1             UHS         lo0

Internet6:
Destination                       Gateway                       Flags     Netif Expire
::/96                             ::1                           UGRS        lo0
::1                               link#3                        UH          lo0
::ffff:0.0.0.0/96                 ::1                           UGRS        lo0
fe80::/10                         ::1                           UGRS        lo0
fe80::%vtnet0/64                  link#1                        U        vtnet0
fe80::24d6:ff:feec:8f0a%vtnet0    link#1                        UHS         lo0
fe80::%vtnet1/64                  link#2                        U        vtnet1
fe80::e447:f0ff:fe9d:29c6%vtnet1  link#2                        UHS         lo0
fe80::%lo0/64                     link#3                        U           lo0
fe80::1%lo0                       link#3                        UHS         lo0
fe80::%tun0/64                    link#4                        U          tun0
fe80::2866:24cc:2d85:1478%tun0    link#4                        UHS         lo0
ff02::/16                         ::1                           UGRS        lo0
 
Back
Top