Create FreeNAS with Firewall for Jail and Host using ipfw

Status
Not open for further replies.

uutzinger

Dabbler
Joined
Nov 27, 2011
Messages
43
FreeNAS does not include firewall functionality.
Therefore if you want a firewall you will need to build a custom image and update your installation.
(I tried copying kernel modules but that was not successful)
Because there is no GUI for the firewall you will need to be familiar with the shell.

One will need to custom build FreeNAS following posts from Joe Schmuck
Guide: How to Build FreeNAS (Part 1: Install and Build FreeNAS)
Guide: How to Build FreeNAS (Part 2: Install and Build FreeNAS)

If you do not want to build latest version (the instructions above will give you latest beta) you will need to change the command in part 2 with the appropriate source for your build. You can browse the source here http://support.freenas.org/browser and find appropriate directory under branch. Replace the source with that directory. To build FreeNAS you need a machine with FreeBSD. The version of the FreeBSD machine does not need to match the FreeNAS version you are trying to build. In the examples below FreeNAS is built in /usr/local/freebsd/8.2.0/.

Configure FreeNAS build to include firewall module [replace 8.2.0 with what you got after downloading the source]:

Code:
ee /usr/local/freebsd/8.2.0/build/nano_env 
on the line with 
NANO_MODULES="cxgb ... 
NANO_MODULES="libalias ipfw cxgb ...


You can configure your FreeNAS build so that the firewall kernel modules are loaded at startup by editing rc.conf [replace 8.2.0 accordingly]

Code:
ee /usr/local/freebsd/8.2.0/nanobsd/Files/etc/rc.conf 
add lines
firewall_enable="YES"
firewall_type="OPEN" 


If in the text above you replace "open" with "client" or "closed" you will need to use the console to access your system because it will not allow you access once you update your FreeNAS installation. It is better to leave it open and to work on the rule set later.

Create your custom build FreeNAS image with kernel and world [replace 8.2.0 accordingly]

Code:
/usr/local/freebsd/8.2.0/build/do_build.sh -f


After a successful build, my images were here: /usr/local/freebsd/8.2.0/os-base/amd64/
There are two new files in /boot/kernel/ : ipfw.ko and libalias.ko They are small and should not impact your image size. Meaning your image will still fit into 2GB section on your flash drive.

Those images can be installed from the GUI on your existing system or they can be used for a new install (iso).
Please follow instructions about updating your installation. Always backup the configuration from you existing system before upgrading firmware.

For GUI firmware update you will need a sha signature of your build:
Code:
sha256 FreeNASsomething.xz > FreeNASsomething.xz.sha


Once the firewall module is enabled on the host you can experiment with it also in the jail.

To check whether the firewall is loaded correctly you can use the following commands in the shell

Code:
kldstat
ipfw list


The first command should list ipfw.ko and libalias.ko. The second shows the active rule set.

Now you will need to think about how to configure your firewall. The configuration will be different for the Jail and the Host. Below is an example for the Jail where HTTP is allowed from anywhere but most other traffic only from the local network. You will need to update the name of your interface as the name depends on the hardware you are using.
I looked up example ipfw rule sets with Google and found a few good examples for MAC OS. The one below I only modified to work with the jail and my setup.

RULE SET FOR JAIL

I placed my rule set into /etc/ipfw.rules. As you can see it is a shell script, meaning you can easily edit and change it and then test it without a reboot. You need to make the script executable with chmod u+x /etc/ipfw.rules

Code:
#!/bin/sh
################ Start of IPFW rules file ###############################
# Flush out the list before we begin.
ipfw -q -f flush

# Set rules command prefix
cmd="ipfw -q add"
pif="epair0b"     # interface name of Jail NIC

#################################################################
# No restrictions on Inside LAN Interface for private network
# Not needed unless you have LAN.
#################################################################
# LAN
$cmd 00006 allow all from ***.***.***.***/24 to any via $pif
# VPN
$cmd 00007 allow all from ***.***.***.***/27 to any via $pif

#################################################################
# Not needed unless we want to go outside LAN
#################################################################
#Samba rules
#allow tcp from any to any 137,138,139 out via $pif keep-state setup
#allow udp from any to any 137,138,139 out via $pif keep-state
#lpd printing
#allow tcp from any to any 515 out via $pif keep-state setup
#allow udp from any to any 515 out via $pif keep-state
# MS Active Directory
#allow tcp from any to any 3268 out via $pif keep-state setup
#allow udp from any to any 3268 out via $pif keep-state

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

#################################################################
# Allow the packet through if it has previous been added to the
# the "dynamic" rules table by a allow keep-state statement.
#################################################################
$cmd 00015 check-state

#################################################################
# Interface facing Public Internet (Outbound Section)
# Interrogate session start requests originating from behind the
# firewall on the private network or from this gateway server
# destined for the public Internet.
#################################################################

# Allow out access to my ISP's Domain name server.
# Get the IP addresses from /etc/resolv.conf file
$cmd 00110 allow tcp from any to ***.***.***.*** 53 out via $pif setup keep-state
$cmd 00111 allow tcp from any to ***.***.***.*** 53 out via $pif setup keep-state
$cmd 00115 allow udp from any to ***.***.***.*** 53 out via $pif keep-state
$cmd 00116 allow udp from any to ***.***.***.*** 53 out via $pif keep-state

# Allow out access to my ISP's DHCP server for cable/DSL configurations.
# This rule is not needed for .user ppp. connection to the public Internet.
# so you can delete this whole group.
# Use the following rule and check log for IP address.
# Then put IP address in commented out rule & delete first rule
$cmd 00120 allow log udp from any 68 to any 67 out via $pif keep-state
#$cmd 00120 allow udp from any to x.x.x.x 67 out via $pif keep-state
# Allow out non-secure standard www function
$cmd 00200 allow tcp from any to any 80 out via $pif setup keep-state

# Allow out secure www function https over TLS SSL
$cmd 00220 allow tcp from any to any 443 out via $pif setup keep-state

# Allow out secure www function tomcat
$cmd 00225 allow tcp from any to any 8080 out via $pif setup keep-state

# Allow out send & get email function
$cmd 00230 allow tcp from any to any 25 out via $pif setup keep-state
$cmd 00231 allow tcp from any to any 110 out via $pif setup keep-state

# Allow out FBSD (make install & CVSUP) functions
# Basically give user root "GOD" privileges.
$cmd 00240 allow tcp from me to any out via $pif setup keep-state uid root

# Allow out ping
$cmd 00250 allow icmp from any to any out via $pif keep-state

# Allow out tracert
$cmd 00251 allow udp from me to any 33434-33525 out via $pif keep-state
# Allow out time
$cmd 00260 allow tcp from any to any 37 out via $pif setup keep-state

# Allow out ntp, setting time automatically
$cmd 00265 allow udp from any to any 123 out via $pif keep-state
$cmd 00266 allow tcp from any to any 123 out via $pif setup keep-state

# Allow out nntp news (i.e., news groups)
$cmd 00270 allow tcp from any to any 119 out via $pif setup keep-state

# Allow out secure FTP, Telnet, and SCP
# This function is using SSH (secure shell)
$cmd 00280 allow tcp from any to any 22 out via $pif setup keep-state

# Allow out whois
$cmd 00290 allow tcp from any to any 43 out via $pif setup keep-state

# Allow LDAP
$cmd 00300 allow tcp from any to any 389 out via $pif keep-state setup
$cmd 00301 allow udp from any to any 389 out via $pif keep-state

# Allow Kerberos
$cmd 00310 allow tcp from me to any 88 out via $pif keep-state setup
$cmd 00320 allow udp from me to any 88 out via $pif keep-state

# deny and log everything else that.s trying to get out.
# This rule enforces the block all by default logic.
$cmd 00399 deny log all from any to any out via $pif

#################################################################
# Interface facing Public Internet (Inbound Section)
# Check packets originating from the public Internet
# destined for this gateway server or the private network.
#################################################################

# Deny all inbound traffic from non-routable reserved address spaces
$cmd 00400 deny all from 192.168.0.0/16 to any in via $pif  #RFC 1918 private IP
$cmd 00401 deny all from 172.16.0.0/12 to any in via $pif   #RFC 1918 private IP
$cmd 00402 deny all from 10.0.0.0/8 to any in via $pif      #RFC 1918 private IP
$cmd 00403 deny all from 127.0.0.0/8 to any in via $pif     #loopback
$cmd 00404 deny all from 0.0.0.0/8 to any in via $pif       #loopback
$cmd 00405 deny all from 169.254.0.0/16 to any in via $pif  #DHCP auto-config
$cmd 00406 deny all from 192.0.2.0/24 to any in via $pif    #reserved for docs
$cmd 00407 deny all from 204.152.64.0/23 to any in via $pif #Sun cluster interconnect
$cmd 00408 deny all from 224.0.0.0/3 to any in via $pif     #Class D & E multicast

# Allow ping from institution
$cmd 00410 allow log icmp from ***.***.1.1/16 to me icmptype 0,8 in via $pif keep-state
$cmd 00411 allow log icmp from ***.***.1.1/16 to me icmptype 0,8 in via $pif keep-state
# Deny public pings
$cmd 00412 deny icmp from any to any in via $pif

# Allow in tracert
$cmd 00420 allow udp from any to any 33434-33525 in via $pif keep-state
$cmd 00420 allow log icmp from any to me icmptypes 3,11 in via $pif keep-state

# Allow iDENT from institution
$cmd 00430 allow tcp from ***.***.1.1/16 to me 113 in via $pif
$cmd 00431 allow tcp from ***.***.1.1/16 to me 113 in via $pif
# Deny any other ident
$cmd 00432 deny tcp from any to any 113 in via $pif

# Deny all Netbios service. 137=name, 138=datagram, 139=session
# Netbios is MS/Windows sharing services.
# Block MS/Windows hosts2 name server requests 81
$cmd 00440 deny tcp from any to any 137 in via $pif
$cmd 00441 deny tcp from any to any 138 in via $pif
$cmd 00442 deny tcp from any to any 139 in via $pif
$cmd 00443 deny tcp from any to any 81 in via $pif

# Deny any late arriving packets
$cmd 00450 deny all from any to any frag in via $pif

# Deny ACK packets that did not match the dynamic rule table
$cmd 00452 deny tcp from any to any established in via $pif

# Allow traffic in from ISP's DHCP server. This rule must contain
# the IP address of your ISP.s DHCP server as it.s the only
# authorized source to send this packet type.
# Only necessary for cable or DSL configurations.
# This rule is not needed for .user ppp. type connection to
# the public Internet. This is the same IP address you captured
# and used in the outbound section.
$cmd 00460 allow udp from any 67 to any 68 in via $pif keep-state

# Allow in standard www function because I have apache server
$cmd 00470 allow tcp from any to me 80 in via $pif setup limit src-addr 16
# Allow in secure www function https over TLS SSL
$cmd 00471 allow tcp from any to me 443 in via $pif setup limit src-addr 16

# Allow in secure www function tomcat
$cmd 00472 allow tcp from any to me 8080 in via $pif setup limit src-addr 16

# Allow in secure FTP, Telnet, and SCP from public Internet
$cmd 00480 allow tcp from ***.***.***.***/24 to me 22 in via $pif setup limit src-addr 16
$cmd 00481 allow tcp from ***.***.***.***/24 to me 22 in via $pif setup limit src-addr 16

# Allow in non-secure Telnet session from public Internet
# labeled non-secure because ID & PW are passed over public
# Internet as clear text.
# Delete this sample group if you do not have telnet server enabled.
#$cmd 00490 allow tcp from any to me 23 in via $pif setup limit src-addr 16

# Allow in iRODS connections
$cmd 00500 allow all from any to me 1247 in via $pif setup limit src-addr 16
$cmd 00501 allow all from any to me 20000-20199 in via $pif setup limit src-addr 32

# Allow LDAP
#$cmd 00540 allow tcp from any to any 389 in via $pif keep-state setup
#$cmd 00541 allow udp from any to any 389 in via $pif keep-state

# Allow Kerberos
#$cmd 00545 allow tcp from any to me 88 in via $pif keep-state setup
#$cmd 00546 allow udp from any to me 88 in via $pif keep-state

# Reject & Log all incoming connections from the outside
$cmd 00599 deny log all from any to any in via $pif

# Everything else is denied by default
# deny and log all packets that fell through to see what they are
$cmd 00999 deny log all from any to any
################ End of IPFW rules file ###############################


Once you tested the rule set you can change rc.conf to have it automatically load when the jail starts.

Code:
ee /usr/local/freebsd/8.2.0/nanobsd/Files/etc/rc.conf 
add  the lines:
firewall_enable="YES"
firewall_script="/etc/ipfw.rules"
firewall_logging="YES"


For the Host you could start with the example rule set below which is essentially the same as above plus information for the bridge network.
In order to write to system you will need to enable writing to the system drive with
Code:
 mount -rw / 

Later change it back to read only:
Code:
 mount -r / 


RULE SET FOR HOST.

Change ***.***.***.***. Since the rule set is a shell script, you can change and test it anytime. It will delete previous rules as first command.

Code:
#!/bin/sh
################ Start of IPFW rules file ###############################
# Flush out the list before we begin.
ipfw -q -f flush

# Set rules command prefix
cmd="ipfw -q add"
# Define you interface names here
pif="alc0"     # public interface name of NIC
               # facing the public Internet
jif="epair0a"  # jail interface
mif="em0"      # second private interface, if you have one

#################################################################
# No restrictions on LAN Interface for local network
#################################################################
# LAN 
$cmd 00006 allow all from ***.***.***.***/24 to any via $pif
# VPN pool
$cmd 00007 allow all from ***.***.***.***/27 to any via $pif

#################################################################
# Not needed unless we want to go outside LAN
#################################################################
#Samba rules
#allow tcp from any to any 137,138,139 out via $pif keep-state setup
#allow udp from any to any 137,138,139 out via $pif keep-state
#lpd printing
#allow tcp from any to any 515 out via $pif keep-state setup
#allow udp from any to any 515 out via $pif keep-state
# MS Active Directory
#allow tcp from any to any 3268 out via $pif keep-state setup
#allow udp from any to any 3268 out via $pif keep-state

#################################################################
# No restrictions on Loopback Interface
# No restrictions on Jail Interface(s)
# No restrictions on Private Interface
#################################################################
$cmd 00010 allow all from any to any via lo0
$cmd 00011 allow all from any to any via $mif
$cmd 00012 allow all from any to any via $jif
$cmd 00013 allow all from any to any via bridge0
$cmd 00014 allow all from any to any via ipfw0

#################################################################
# Allow the packet through if it has previous been added to the
# the "dynamic" rules table by a allow keep-state statement.
#################################################################
$cmd 00015 check-state

#################################################################
# Interface facing Public Internet (Outbound Section)
# Interrogate session start requests originating from behind the
# firewall on the private network or from this gateway server
# destined for the public Internet.
#################################################################

# Allow out access to my ISP's Domain name server.
# Get the IP addresses from /etc/resolv.conf file
$cmd 00110 allow tcp from any to ***.***.***.*** 53 out via $pif setup keep-state
$cmd 00111 allow tcp from any to ***.***.***.*** 53 out via $pif setup keep-state
$cmd 00115 allow udp from any to ***.***.***.*** 53 out via $pif keep-state
$cmd 00116 allow udp from any to ***.***.***.*** 53 out via $pif keep-state

# Allow out access to my ISP's DHCP server for cable/DSL configurations.
# This rule is not needed for .user ppp. connection to the public Internet.
# so you can delete this whole group.
# Use the following rule and check log for IP address.
# Then put IP address in commented out rule & delete first rule
$cmd 00120 allow log udp from any 68 to any 67 out via $pif keep-state
#$cmd 00120 allow udp from any to x.x.x.x 67 out via $pif keep-state

# Allow out non-secure standard www function
$cmd 00200 allow tcp from any to any 80 out via $pif setup keep-state

# Allow out secure www function https over TLS SSL
$cmd 00220 allow tcp from any to any 443 out via $pif setup keep-state

# Allow out secure www function tomcat
$cmd 00225 allow tcp from any to any 8080 out via $pif setup keep-state

# Allow out send & get email function
$cmd 00230 allow tcp from any to any 25 out via $pif setup keep-state
$cmd 00231 allow tcp from any to any 110 out via $pif setup keep-state

# Allow out FBSD (make install & CVSUP) functions
# Basically give user root "GOD" privileges.
$cmd 00240 allow tcp from me to any out via $pif setup keep-state uid root

# Allow out ping
$cmd 00250 allow icmp from any to any out via $pif keep-state

# Allow out tracert
$cmd 00251 allow udp from me to any 33434-33525 out via $pif keep-state

# Allow out time
$cmd 00260 allow tcp from any to any 37 out via $pif setup keep-state

# Allow out ntp, setting time automatically
$cmd 00265 allow udp from any to any 123 out via $pif keep-state
$cmd 00266 allow tcp from any to any 123 out via $pif setup keep-state

# Allow out nntp news (i.e., news groups)
$cmd 00270 allow tcp from any to any 119 out via $pif setup keep-state

# Allow out secure FTP, Telnet, and SCP
# This function is using SSH (secure shell)
$cmd 00280 allow tcp from any to any 22 out via $pif setup keep-state

# Allow out whois
$cmd 00290 allow tcp from any to any 43 out via $pif setup keep-state

# Allow LDAP
$cmd 00300 allow tcp from any to any 389 out via $pif keep-state setup
$cmd 00301 allow udp from any to any 389 out via $pif keep-state

# Allow Kerberos
$cmd 00310 allow tcp from me to any 88 out via $pif keep-state setup
$cmd 00320 allow udp from me to any 88 out via $pif keep-state

# deny and log everything else that.s trying to get out.
# This rule enforces the block all by default logic.
$cmd 00399 deny log all from any to any out via $pif

#################################################################
# Interface facing Public Internet (Inbound Section)
# Check packets originating from the public Internet
# destined for this gateway server or the private network.
#################################################################

# Deny all inbound traffic from non-routable reserved address spaces
$cmd 00400 deny all from 192.168.0.0/16 to any in via $pif  #RFC 1918 private IP
$cmd 00401 deny all from 172.16.0.0/12 to any in via $pif   #RFC 1918 private IP
$cmd 00402 deny all from 10.0.0.0/8 to any in via $pif      #RFC 1918 private IP
$cmd 00403 deny all from 127.0.0.0/8 to any in via $pif     #loopback
$cmd 00404 deny all from 0.0.0.0/8 to any in via $pif       #loopback
$cmd 00405 deny all from 169.254.0.0/16 to any in via $pif  #DHCP auto-config
$cmd 00406 deny all from 192.0.2.0/24 to any in via $pif    #reserved for docs
$cmd 00407 deny all from 204.152.64.0/23 to any in via $pif #Sun cluster interconnect
$cmd 00408 deny all from 224.0.0.0/3 to any in via $pif     #Class D & E multicast

# Allow ping from institution
$cmd 00410 allow log icmp from ***.***.1.1/16 to me icmptype 0,8 in via $pif keep-state
$cmd 00411 allow log icmp from ***.***.1.1/16 to me icmptype 0,8 in via $pif keep-state
# Deny public pings
$cmd 00412 deny icmp from any to any in via $pif

# Allow in tracert
$cmd 00420 allow udp from any to any 33434-33525 in via $pif keep-state
$cmd 00420 allow log icmp from any to me icmptypes 3,11 in via $pif keep-state

# Allow iDENT from institution
$cmd 00430 allow tcp from ***.***.1.1/16 to me 113 in via $pif
$cmd 00431 allow tcp from ***.***.1.1/16 to me 113 in via $pif
# Deny any other ident
$cmd 00432 deny tcp from any to any 113 in via $pif

# Deny all Netbios service. 137=name, 138=datagram, 139=session
# Netbios is MS/Windows sharing services.
# Block MS/Windows hosts2 name server requests 81
$cmd 00440 deny tcp from any to any 137 in via $pif
$cmd 00441 deny tcp from any to any 138 in via $pif
$cmd 00442 deny tcp from any to any 139 in via $pif
$cmd 00443 deny tcp from any to any 81 in via $pif

# Deny any late arriving packets
$cmd 00450 deny all from any to any frag in via $pif

# Deny ACK packets that did not match the dynamic rule table
$cmd 00452 deny tcp from any to any established in via $pif

# Allow traffic in from ISP's DHCP server. This rule must contain
# the IP address of your ISP.s DHCP server as it.s the only
# authorized source to send this packet type.
# Only necessary for cable or DSL configurations.
# This rule is not needed for .user ppp. type connection to
# the public Internet. This is the same IP address you captured
# and used in the outbound section.
$cmd 00460 allow udp from any 67 to any 68 in via $pif keep-state

# Allow in standard www function because I have apache server
$cmd 00470 allow tcp from any to me 80 in via $pif setup limit src-addr 16

# Allow in secure www function https over TLS SSL
$cmd 00471 allow tcp from any to me 443 in via $pif setup limit src-addr 16

# Allow in secure www function tomcat
$cmd 00472 allow tcp from any to me 8080 in via $pif setup limit src-addr 16

# Allow in secure FTP, Telnet, and SCP  from local network and VPN poool
$cmd 00480 allow tcp from ***.***.***.***/24 to me 22 in via $pif setup limit src-addr 16
$cmd 00481 allow tcp from ***.***.***.***/24 to me 22 in via $pif setup limit src-addr 16

# Allow in non-secure Telnet session from public Internet
# labeled non-secure because ID & PW are passed over public
# Internet as clear text.

# Delete this sample group if you do not have telnet server enabled.
#$cmd 00490 allow tcp from any to me 23 in via $pif setup limit src-addr 16

# Allow in iRODS connections
$cmd 00500 allow all from any to me 1247 in via $pif setup limit src-addr 16
$cmd 00501 allow all from any to me 20000-20199 in via $pif setup limit src-addr 32

# Allow LDAP
#$cmd 00540 allow tcp from any to any 389 in via $pif keep-state setup
#$cmd 00541 allow udp from any to any 389 in via $pif keep-state

# Allow Kerberos
#$cmd 00545 allow tcp from any to me 88 in via $pif keep-state setup
#$cmd 00546 allow udp from any to me 88 in via $pif keep-state

# Reject & Log all incoming connections from the outside
$cmd 00599 deny log all from any to any in via $pif

# Everything else is denied by default
# deny and log all packets that fell through to see what they are
$cmd 00999 deny log all from any to any
################ End of IPFW rules file ###############################


Since your firewall is working now you should consider loading the rule set each time your OS loads:

Code:
ee /usr/local/freebsd/8.2.0/nanobsd/Files/etc/rc.conf 
add lines
# IP firewall enable
firewall_enable="YES"
firewall_script="/etc/ipfw.rules"
firewall_logging="YES"
 
Status
Not open for further replies.
Top