This page looks best with JavaScript enabled

IPFW Port Redirection

 ·  🎃 kr0m

When we have a device behind a NAT and we want to access a service on that device, the most common practice is to redirect the port of that service to the internal device. In this case, we will do it using IPFW on FreeBSD.

We will continue with the example in which we performed NAT and from here we will perform the port redirection. As in NAT, port redirection can be done in two ways, using natd and using the module.


NATD

We enable natd, indicate the WAN interface and the configuration parameters:

sysrc natd_enable="yes"
sysrc natd_interface=“em0”
sysrc natd_flags="-m -f /etc/natd.conf"

In the natd configuration, we indicate which ports and to which device the traffic should be redirected. In this case, the traffic received on port 7777 will end up at 192.168.55.2 port 7777:

vim /etc/natd.conf

redirect_port tcp 192.168.55.2:7777 7777

We modify the firewall script to check the redirections:

vim /etc/ipfw.rules

#!/bin/sh
# Flush out the list before we begin.
ipfw -q -f flush

# Set rules command prefix
cmd="ipfw -q add"

wanif="em0"
lanif="em1"

lannet="192.168.55.0/24"

# No restrictions on Loopback Interface
$cmd 00001 allow all from any to any via lo0

# Allow all LAN traffic
$cmd 00002 allow all from $lannet to any in via $lanif

# Check inbound traffic for redirections
$cmd 00003 divert natd ip from any to me in via $wanif

# Allow dynamic rules table connections
$cmd 00101 check-state

# Allow redirected traffic
$cmd 00200 allow tcp from any to 192.168.55.2 dst-port 7777 out via $lanif

# NAT port redirection answer traffic, without states because its a redirected connections not regular connection
$cmd 00201 skipto 1000 tcp from 192.168.55.2 to any src-port 7777 out via $wanif

# NAT Lan traffic:
$cmd 00300 skipto 1000 tcp from $lannet to any out via $wanif setup keep-state
$cmd 00301 skipto 1000 udp from $lannet to any out via $wanif keep-state
$cmd 00302 skipto 1000 icmp from $lannet to any out via $wanif keep-state

# -- Host Traffic --
# Allow access to public DNS
# DNS TCP
$cmd 00401 allow tcp from me to 8.8.8.8 53 out via $wanif setup keep-state
$cmd 00402 allow tcp from me to 8.8.4.4 53 out via $wanif setup keep-state
# DNS UDP
$cmd 00403 allow udp from me to 8.8.8.8 53 out via $wanif keep-state
$cmd 00404 allow udp from me to 8.8.4.4 53 out via $wanif keep-state

# Allow outbound HTTP and HTTPS connections
$cmd 00405 allow tcp from me to any 80 out via $wanif setup keep-state
$cmd 00406 allow tcp from me to any 443 out via $wanif setup keep-state

# Allow outbound email connections
$cmd 00407 allow tcp from me to any 25 out via $wanif setup keep-state
$cmd 00408 allow tcp from me to any 110 out via $wanif setup keep-state

# Allow outbound ping
$cmd 00409 allow icmp from me to any out via $wanif keep-state

# Allow outbound NTP
$cmd 00410 allow udp from me to any 123 out via $wanif keep-state

# Allow outbound SSH
$cmd 00411 allow tcp from me to any 22 out setup keep-state

# Allow inbound public pings
$cmd 00412 allow icmp from any to me in via $wanif

# Allow inbound SSH
# With stateless rules we dont break our ssh connection each time we restart ipfw service
$cmd 00413 allow tcp from any to me 22 in
$cmd 00414 allow tcp from me 22 to any out
# ------------------

# Deny and log all other outbound connections
$cmd 00900 deny log all from any to any out

# NAT outbound traffiC
$cmd 01000 divert natd ip from any to any out via $wanif
$cmd 01001 allow ip from any to any

KERNEL-SPACE

We enable the kernel firewall module:

sysrc firewall_nat_enable="yes"
sysrc firewall_nat_interface=“em0”

For some reason, to make the redirection work using the kernel, we have to disable fw.one_pass:

sysctl net.inet.ip.fw.one_pass=0

We make it permanent:

vi /etc/sysctl.conf

net.inet.ip.fw.one_pass=0

We adapt our firewall script:

vim /etc/ipfw.rules

#!/bin/sh
# Flush out the list before we begin.
ipfw -q -f flush

# Set rules command prefix
cmd="ipfw -q add"

wanif="em0"
lanif="em1"

lannet="192.168.55.0/24"

# No restrictions on Loopback Interface
$cmd 00001 allow all from any to any via lo0

# Allow all LAN traffic
$cmd 00002 allow all from $lannet to any in via $lanif

# Configure NAT-WAN-PortRedirection
ipfw -q nat 1 config same_ports if $wanif redirect_port tcp 192.168.55.2:7777 7777

# Check inbound traffic for redirections
$cmd 00004 nat 1 ip from any to me in via $wanif

# Allow dynamic rules table connections
$cmd 00101 check-state

# Allow redirected traffic
$cmd 00200 allow tcp from any to 192.168.55.2 dst-port 7777 out via $lanif

# NAT port redirection answer traffic, without states because its a redirected connections not regular connection
$cmd 00201 skipto 1000 tcp from 192.168.55.2 to any src-port 7777 out via $wanif

# NAT Lan traffic:
$cmd 00300 skipto 1000 tcp from $lannet to any out via $wanif setup keep-state
$cmd 00301 skipto 1000 udp from $lannet to any out via $wanif keep-state
$cmd 00302 skipto 1000 icmp from $lannet to any out via $wanif keep-state

# -- Host Traffic --
# Allow access to public DNS
# DNS TCP
$cmd 00400 allow tcp from me to 8.8.8.8 53 out via $wanif setup keep-state
$cmd 00401 allow tcp from me to 8.8.4.4 53 out via $wanif setup keep-state
# DNS UDP
$cmd 00402 allow udp from me to 8.8.8.8 53 out via $wanif keep-state
$cmd 00403 allow udp from me to 8.8.4.4 53 out via $wanif keep-state

# Allow outbound HTTP and HTTPS connections
$cmd 00404 allow tcp from me to any 80 out via $wanif setup keep-state
$cmd 00405 allow tcp from me to any 443 out via $wanif setup keep-state

# Allow outbound email connections
$cmd 00406 allow tcp from me to any 25 out via $wanif setup keep-state
$cmd 00407 allow tcp from me to any 110 out via $wanif setup keep-state

# Allow outbound ping
$cmd 00408 allow icmp from me to any out via $wanif keep-state

# Allow outbound NTP
$cmd 00409 allow udp from me to any 123 out via $wanif keep-state

# Allow outbound SSH
$cmd 00410 allow tcp from me to any 22 out setup keep-state

# Allow inbound public pings
$cmd 00411 allow icmp from any to me in via $wanif

# Allow inbound SSH
# With stateless rules we dont break our ssh connection each time we restart ipfw service
$cmd 00412 allow tcp from any to me 22 in
$cmd 00413 allow tcp from me 22 to any out
# ------------------

# Deny and log all other outbound connections
$cmd 00900 deny log all from any to any out

# NAT outbound traffiC
$cmd 01000 nat 1 ip from any to any out via $wanif
$cmd 01001 allow ip from any to any
If you liked the article, you can treat me to a RedBull here