Hello. I am rather new to the firewall of FreeBSD and I am having issues with the in-kernel NAT.
I had configured everything according to the man pages and some internet resources.
My test infrastructure looks like this:
In the production environment the WAN interface will be directly connected to the internet and have a public IP, LAN will be replaced with tap0 interface of the OpenVPN.
I am expecting IPFW to allow local connections on ports 22 (ssh), 8480 (OpenVPN), all outbound traffic. The NAT is expecting to redirect the port 24 to port 22 (ssh) of my ubuntu VM. NAT should also allow all outbound traffic from LAN.
The actual behavior is the following:
- I can ping 8.8.8.8 from the ubuntu, but can't ping google.com. TCPdump shows that during the ping for google.com the dns requests are successfully translated by NAT and sent from vtnet0 with no answer from the internet
- I can ping both 8.8.8.8 and google.com from FreeBSD, but the kernel logs show that the the sendto permission is denied for NTP requests
- I can't connect to ubuntu via ssh from 192.168.10.0/24 (vtnet0). The packets do never get redirected to LAN. They get blocked by the rule 499
- I can't connect from ubuntu to any WAN devices with ssh, the packets are successfully translated by nat, they exit vtnet0 with no response from the internet
What am I doing wrong? I had looked for similar threads here and did some modifications to the firewall config, but had to revert everything as that didn't help me at all
The configs:
/boot/loader.conf
/etc/rc.conf
/etc/sysctl.conf
Kernel config:
/etc/ipfw.rules
I had configured everything according to the man pages and some internet resources.
My test infrastructure looks like this:
In the production environment the WAN interface will be directly connected to the internet and have a public IP, LAN will be replaced with tap0 interface of the OpenVPN.
I am expecting IPFW to allow local connections on ports 22 (ssh), 8480 (OpenVPN), all outbound traffic. The NAT is expecting to redirect the port 24 to port 22 (ssh) of my ubuntu VM. NAT should also allow all outbound traffic from LAN.
The actual behavior is the following:
- I can ping 8.8.8.8 from the ubuntu, but can't ping google.com. TCPdump shows that during the ping for google.com the dns requests are successfully translated by NAT and sent from vtnet0 with no answer from the internet
- I can ping both 8.8.8.8 and google.com from FreeBSD, but the kernel logs show that the the sendto permission is denied for NTP requests
- I can't connect to ubuntu via ssh from 192.168.10.0/24 (vtnet0). The packets do never get redirected to LAN. They get blocked by the rule 499
- I can't connect from ubuntu to any WAN devices with ssh, the packets are successfully translated by nat, they exit vtnet0 with no response from the internet
What am I doing wrong? I had looked for similar threads here and did some modifications to the firewall config, but had to revert everything as that didn't help me at all
The configs:
/boot/loader.conf
Code:
kern.geom.label.disk_ident.enable="0"
kern.geom.label.gptid.enable="0"
cryptodev_load="YES"
zfs_load="YES"
#console="comconsole"
console="video"
ipfw_load="YES"
ipfw_nat_load="YES"
libalias_load="YES"
aesni_load="YES"
net.inet.ip.fw.default_to_accept="0"
/etc/rc.conf
Code:
hostname="BSD-PFTEST"
ifconfig_vtnet0="DHCP"
defaultrouter="192.168.10.1"
ifconfig_vtnet1="192.168.127.1/24"
sshd_enable="YES"
ntpd_enable="YES"
ntpd_sync_on_start="YES"
powerd_enable="YES"
moused_nondefault_enable="NO"
# Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable
dumpdev="AUTO"
zfs_enable="YES"
qemu_guest_agent_enable=YES
ntpd_enable="NO"
ntpdate_enable="YES"
ntpdate_flags="-u"
fsck_y_enable="YES"
background_fsck="NO"
gateway_enable="YES"
firewall_enable="YES"
firewall_script="/etc/ipfw.rules"
firewall_logging="YES"
firewall_nat_enable="YES"
firewall_nat_interface="vtnet0"
firewall_logif="YES"
openvpn_enable="YES"
openvpn_if="tun tap"
/etc/sysctl.conf
Code:
vfs.zfs.min_auto_ashift=12
net.inet.ip.fw.one_pass="0"
net.inet.tcp.tso="0"
Code:
options IPFIREWALL
options IPFIREWALL_VERBOSE
options IPFIREWALL_VERBOSE_LIMIT=50
options IPFIREWALL_NAT
options LIBALIAS
options ROUTETABLES="2"
options IPFIREWALL_NAT64
options IPFIREWALL_NPTV6
options IPFIREWALL_PMOD
options HZ="1000"
Code:
#!/bin/sh
# Flush out the list before we begin.
ipfw -q -f flush
# Set rules command prefix
ipfw="ipfw -q"
add="ipfw -q add"
pif="vtnet0" # interface name of NIC attached to Internet
vpn="tap0" #interface name of OpenVPN
lan="vtnet1"
skip="skipto 1000"
$ipfw disable one_pass
$ipfw nat 1 config log if vtnet0 reset unreg_only same_ports \
redirect_port tcp 192.168.127.20:22 24
# No restrictions on LAN Interface
$add 00005 allow all from any to any via $lan
# No restrictions on OpenVPN Interface <ONLY IN PROD>
#$add 00006 allow all from any to any via $vpn
# No restrictions on Loopback Interface
$add 00010 allow all from any to any via lo0
# Reassemble inbound packets
$add 00099 reass all from any to any in
# NAT any inbound packets
$add 00100 nat 1 all from any to any in via vtnet0
#$add 00101 nat 1 all from any to any out via vtnet0
#Allow the packet through if it has an existing entry in the dynamic rules table
$add 00101 check-state
# Allow access to public DNS
# Repeat for each DNS server in /etc/resolv.conf
$add 00110 $skip tcp from any to 1.1.1.1 53 out via $pif setup keep-state
$add 00111 $skip udp from any to 1.1.1.1 53 out via $pif keep-state
$add 00112 $skip tcp from any to 8.8.8.8 53 out via $pif setup keep-state
$add 00113 $skip udp from any to 8.8.8.8 53 out via $pif keep-state
$add 00114 $skip tcp from any to any 53 out via $pif setup keep-state
$add 00115 $skip udp from any to any 53 out via $pif keep-state
# Allow access to ISP's DHCP server for cable/DSL configurations.
# Use the first rule and check log for IP address.
# Then, uncomment the second rule, input the IP address, and delete the first rule
# THIS IS USED TEMPORARILY
$add 00120 $skip log udp from any to any 67 out via $pif keep-state
# Allow all outbound connections
$add 00200 $skip all from any to any out via $pif setup keep-state
$add 00210 $skip icmp from any to any out via $pif keep-state
# Deny and log all other outbound connections <DISABLED>
#$add 00299 deny log all from any to any out via $pif
# Deny all inbound traffic from non-routable reserved address spaces
#$add 00300 deny all from 192.168.0.0/16 to any in via $pif RFC 1918 private IP
#$add 00301 deny all from 172.16.0.0/12 to any in via $pif RFC 1918 private IP
#$add 00302 deny all from 10.0.0.0/8 to any in via $pif RFC 1918 private IP
$add 00303 deny all from 127.0.0.0/8 to any in via $pif #loopback
$add 00304 deny all from 0.0.0.0/8 to any in via $pif #loopback
$add 00305 deny all from 169.254.0.0/16 to any in via $pif #DHCP auto-config
$add 00306 deny all from 192.0.2.0/24 to any in via $pif #reserved for docs
$add 00307 deny all from 204.152.64.0/23 to any in via $pif #Sun cluster interconnect
$add 00308 deny all from 224.0.0.0/3 to any in via $pif #Class D & E multicast
# Deny public pings <DISABLED>
#$add 00310 deny icmp from any to any in via $pif
# Deny ident
$add 00315 deny tcp from any to any 113 in via $pif
# Deny all Netbios services.
$add 00320 deny tcp from any to any 137 in via $pif
$add 00321 deny tcp from any to any 138 in via $pif
$add 00322 deny tcp from any to any 139 in via $pif
$add 00323 deny tcp from any to any 81 in via $pif
#Deny fragments
$add 00330 deny all from any to any frag in via $pif
#Deny ACK packets that did not match the dynamic rule table
$add 00332 deny tcp from any to any established in via $pif
#Allow traffic from ISP's DHCP server.
#Replace (I won't as the static ip will be used in prod) x.x.x.x with the same IP address used in rule 00120.
$add 00360 allow udp from any to any 67 in via $pif keep-state
#Allow HTTP connections to internal web server <DISABLED>
#$add 00400 allow tcp from any to me 80 in via $pif setup limit src-addr 2
#Allow inbound SSH connections
$add 00410 allow tcp from any to me 22 in via $pif setup limit src-addr 2
#Allow inbound OpenVPN connections
$add 00415 allow udp from any to me 8480 in via $pif keep-state
#Reject and log all other incoming connections
$add 00499 deny log all from any to any in via $pif
#Everything else is denied and logged
$add 00999 deny log all from any to any
# Skipto location for outbound stateful rules
$add 01000 nat 1 log all from any to any out via $pif
$add 01001 allow log all from any to any