pavement

Firewall, Configuring

From FreeBSDwiki
(Difference between revisions)
Jump to: navigation, search
 
(29 intermediate revisions by 8 users not shown)
Line 1: Line 1:
helpful links:
+
==Don't need NAT? don't rebuild the kernel!==
 +
The system will dynamically load the kernel module when the rc.conf statement firewall_enable="YES" is used. You do not need to compile IPFW into the FreeBSD kernel unless you want NAT function enabled. You'll still need a ruleset to deal with the traffic your machine gets, of course.
 +
 
 +
 
 +
== Building an [[ipfw]]-enabled kernel ==
 +
 
 +
You're going to need to rebuild your kernel with the appropriate options for the firewall you want to build.  We've already got an [[Custom Kernel|article]] on building a custom kernel, but to start you off, here are some kernel options you'll almost certainly want and need:
 +
 
 +
options        IPFIREWALL                      # you need this to enable ipfw
 +
options        IPFIREWALL_VERBOSE              # you need this to enable ipfw logging
 +
options        IPFIREWALL_VERBOSE_LIMIT=10    # limit to 10 identical log entries
 +
options        IPDIVERT                        # enable NAT
 +
 
 +
It would be advisable to check out the NOTES files for your particular BSD version and architecture to check out other interesting kernel packet-filtering capabilities that you might or might not want to consider.  For example, some kernels support IPSEC (or FAST_IPSEC) security, TCP_DROP_SYNFIN (to defeat FIN scanning), IPSTEALTH (for "invisible" firewalls that don't show up in traceroutes)... but it varies by both BSD version and architecture, so check [[ /usr/src/sys/conf/NOTES]] for general options and [[ /usr/src/sys/(arch)/conf/NOTES]] for hardware-specific options.
 +
 
 +
== Sample [[ipfw]] firewall ruleset ==
 +
 
 +
This ruleset sets up a firewall on a "bastion" server that both runs publicly accessible services and acts as a NAT-enabled firewall for a protected network running behind it. 
 +
 
 +
'''ipfw''' rulesets are shell scripts that can be run directly from the command line (assuming you have an ipfw-enabled kernel loaded) - but remember, if you're running this on a [[default deny]] system, you will '''lose network connectivity''' on execution of the very first line of this script - meaning that you CANNOT run the script from a remote shell session, or it will stop running before it ever gets past '''deny all from any to any'''.
 +
 
 +
So if you need to restart a firewall remotely, you'll have to use some minor trickery - like scheduling it with the [[at]] scheduler.  THAT will work, since jobs started from [[at]] don't depend on network connectivity to continue running.  However, if you're running untested modifications, you'll probably want to schedule ANOTHER job with [[at]] for 5 minutes later to pull your firewall back to a "known accessible" configuration, just in case there's a really bad bug in your new rules that will deny you access.  NOT leaving yourself a scheduled "oops" to bring you back to a known accessible condition, just in case, could end up costing you a very long drive out to wherever your server is.
 +
 
 +
With no further ado, here's the sample ipfw ruleset script.
 +
 
 +
#!/bin/sh
 +
 +
#Quietly flush out rules
 +
/sbin/ipfw -q -f flush
 +
 +
#Set command prefix (add "-q" option after development to turn on quiet mode)
 +
cmd="/sbin/ipfw add"
 +
 +
# set outside and inside network interfaces
 +
oif="xl0"
 +
iif="ed0"
 +
 +
# set private IP of this server and the netmask of the whole LAN side
 +
server="192.168.0.1"
 +
inside="192.168.0.0/24"
 +
 +
######Localhost stuff
 +
#
 +
#allow the computer to talk to itself
 +
$cmd 00080 allow ip from any to any via lo0
 +
 +
#don't let anything from the "outside" talk to localhost
 +
$cmd 00081 deny ip from any to 127.0.0.0/8
 +
 +
#don't let the computer talk other computers as localhost
 +
$cmd 00082 deny log ip from 127.0.0.0/8 to any
 +
#
 +
#######
 +
 +
####### DHCP stuff
 +
#
 +
# you need this to be able to renew your DHCP lease from your ISP
 +
$cmd 00083 allow udp from any 67 to any 68 in recv rl0
 +
#
 +
#####
 +
 +
######### deny-and-log bogus packets by tcpflags
 +
#
 +
# XMAS tree
 +
        $cmd 00084 deny log tcp from any to any in tcpflags fin,psh,urg recv $oif
 +
# NULL scan (no flag set at all)
 +
        $cmd 00085 deny log tcp from any to any in tcpflags !fin,!syn,!rst,!psh,!ack,!urg recv $oif
 +
# SYN flood (SYN,FIN)
 +
        $cmd 00086 deny log tcp from any to any in tcpflags syn,fin recv $oif
 +
# Stealth FIN scan (FIN,RST)
 +
        $cmd 00087 deny log tcp from any to any in tcpflags fin,rst recv $oif
 +
# forced packet routing
 +
        $cmd 00089 deny log ip from any to any in ipoptions ssrr,lsrr,rr,ts recv $oif
 +
#
 +
#######
 +
 +
 +
 +
######### Things served via this machine directly
 +
######### Any services on this machine should be placed here,
 +
######### before the NAT Divert rule
 +
#
 +
#HTTP
 +
        $cmd 00500 allow tcp from any to any 80 in via $oif
 +
#SSH
 +
        $cmd 00510 allow tcp from any to any 22 in via $oif
 +
#FTP
 +
        $cmd 00570 allow ip from any to any 20 in via $oif
 +
        $cmd 00571 allow ip from any to any 21 in via $oif
 +
        $cmd 00572 allow tcp from any 21 to any out via $oif
 +
#
 +
####
 +
 +
 +
#####NATD stuff
 +
 +
#natd Divert rule
 +
        $cmd 01000 divert natd all from any to any via $oif
 +
 +
######
 +
 +
 +
####All connections originating from my network are allowed
 +
 +
# check to see if a dynamic rule has been created that matches this packet
 +
        $cmd 01100 check-state
 +
# let everything on your internal network talk to the firewall
 +
        $cmd 01101 allow all from any to any via $iif keep-state
 +
# setup a dynamic rule for any connections being started from inside
 +
        $cmd 01102 allow all from any to any out via $oif keep-state
 +
# deny ACK packets that did not match the dynamic rule table - do not log, too many false positives
 +
        $cmd 01103 deny tcp from any to any established in via $oif
 +
#deny fragments as bogus packets
 +
        $cmd 01104 deny log all from any to any frag in via $oif
 +
#####
 +
 +
 +
####### ICMP stuff
 +
 +
#allow path-mtu in both directions
 +
$cmd 01200 allow icmp from any to any icmptypes 3
 +
 +
#allow source quench in and out
 +
$cmd 01201 allow icmp from any to any icmptypes 4
 +
 +
#allow outbound traceroutes
 +
$cmd 01204 allow icmp from any to any icmptypes 11 in
 +
 +
#allow outbound pings and incoming ping responses
 +
$cmd 01202 allow icmp from any to any icmptypes 8 out
 +
$cmd 01203 allow icmp from any to any icmptypes 0 in
 +
 +
########
 +
 +
 +
 +
##### This section is for exposing services to the internet from the LAN
 +
#####  It is placed AFTER the NATD Divert rule, so these services can be
 +
#####  diverted in /etc/natd.conf
 +
 +
#VNC - allow it, but log connection attempts (though DON'T log traffic for established sessions)
 +
        $cmd 01550 allow log tcp from any to any 5900 in setup
 +
        $cmd 01551 allow tcp from any to any 5900 in
 +
#KAZAA
 +
        $cmd 01580 allow ip from any to $inside 1214 in via $oif
 +
#SOULSEEK
 +
        $cmd 01590 allow ip from any to $inside 2234 in via $oif
 +
        $cmd 01591 allow ip from any to $inside 5534 in via $oif
 +
#EMULE
 +
        $cmd 01600 allow tcp from any to $inside 4662 in via $oif
 +
        $cmd 01601 allow udp from any to $inside 4672 in via $oif
 +
#BITTORRENT
 +
        $cmd 01610 allow ip from any to $inside 30000-40000 in via $oif
 +
 +
####
 +
 +
######## SOME THINGS ARE TOO NOISY TO LIVE
 +
######## In this section we deny things that would be denied anyway, but that we just
 +
######## don't want logged.  Be careful with this - in general, you probably want to
 +
######## avoid putting anything in here that doesn't specify a known source address that
 +
######## is relatively trustworthy.  You also want to be very careful about who knows
 +
######## what this section of your firewall configs looks like, because they can then
 +
######## use the info to craft probes and attacks they know you won't see or log.
 +
 +
# Don't bother logging IGMP crap from the ISP
 +
$cmd 9004 deny igmp from 172.16.210.1 to any in via $oif
 +
 +
# Don't bother logging DNS garbage inbound from the ISP's DNS boxes
 +
$cmd 9006 deny udp from 4.31.99.0/24\{100-103\} 53 to any dst-port 50000-65535 in via $oif
 +
 +
#####
 +
 +
######## Stealth scans of closed ports
 +
########  this section is to deny and log stealth scans that we can't really deny
 +
########  on open ports because doing so would disrupt legitimate services.
 +
 +
# ACK scan (ACK,RST)
 +
        $cmd 60000 deny log tcp from any to any in tcpflags ack,rst recv $oif
 +
 +
#####
 +
 +
#############
 +
############# DEFAULT RULE - deny it, and log it, 'cause we're secure like that.
 +
#############
 +
#
 +
$cmd 65000 deny log all from any to any
 +
 
 +
== Sample /etc/natd.conf ==
 +
 
 +
Our bastion firewall/server will also need to handle NAT duties for the boxes it's protecting on the LAN side.  [[ /etc/natd.conf]] is the configuration file for natd, and will allow you to redirect ports from the public side to services on the LAN side, as well as handling standard NATting of connection requests from our protected network to the big bad Internet.  Here's a sample [[ /etc/natd.conf]].
 +
 
 +
(Note that for redirection of services to work, you need matching entries in your IPFW ruleset after the NAT Divert rule to allow those services inbound access as well as entries in this [[ /etc/natd.conf]]!)
 +
 
 +
# "interface" should be the WAN interface
 +
interface xl0
 +
use_sockets yes
 +
same_ports yes
 +
# set "dynamic" if the WAN interface is controlled by DHCP
 +
dynamic yes
 +
 +
#VNC
 +
        redirect_port tcp 192.168.0.10:5900 5900
 +
#KAZAA
 +
        redirect_port tcp 192.168.0.25:1214 1214
 +
#SOULSEEK
 +
        redirect_port tcp 192.168.0.25:2234 2234
 +
        redirect_port tcp 192.168.0.25:5534 5534
 +
#EMULE
 +
        redirect_port tcp 192.168.0.25:4662 4662
 +
        redirect_port udp 192.168.0.25:4672 4672
 +
#BITTORRENT
 +
        redirect_port tcp 192.168.0.25:30000-40000 30000-40000
 +
 
 +
== Sample /usr/local/etc/dhcpd.conf file ==
 +
 
 +
We're also going to want our bastion firewall/server to deliver DHCP leases to the computers on the protected network.  So after installing the dhcp daemon from the '''/usr/ports/net/isc-dhcp3''' port, you'll need to minimally configure it to actually deliver the leases to the clients.  Here's a sample  [[ /usr/local/etc/dhcpd.conf]] file:
 +
 
 +
    # dhcpd.conf
 +
    #
 +
    # Configuration file for ISC dhcpd
 +
    #
 +
    # option definitions common to all supported networks...
 +
    option domain-name "yourdomain.local";
 +
    option domain-name-servers 192.168.0.99;
 +
    default-lease-time 604800;
 +
    max-lease-time 2592000;
 +
 +
    ddns-update-style none;
 +
 +
    # If you have more than one subnet, list them seperately.
 +
    subnet 192.168.0.0 netmask 255.255.255.0 {
 +
    range 192.168.0.200 192.168.100.250;
 +
    option routers 192.168.0.1;
 +
    option broadcast-address 192.168.0.255;
 +
    default-lease-time 4800;
 +
    max-lease-time 7200;
 +
    }
 +
 +
    # This would be for a second subnet, if you had one:
 +
#    subnet 192.168.5.0 netmask 255.255.255.0 {
 +
#    range 192.168.5.200 192.168.5.254;
 +
#    option routers 192.168.5.1;
 +
#    option broadcast-address 192.168.5.255;
 +
#    default-lease-time 4800;
 +
#    max-lease-time 7200;
 +
#    }
 +
 +
# EOF
 +
 
 +
see also: [[Firewall, Monitoring]]
 +
 
 +
 
 +
== Helpful External Links ==
  
 
http://www.freebsddiary.org/ipfw.php
 
http://www.freebsddiary.org/ipfw.php
 +
 
http://www.onlamp.com/pub/a/bsd/2001/05/09/FreeBSD_Basics.html
 
http://www.onlamp.com/pub/a/bsd/2001/05/09/FreeBSD_Basics.html
http://blogs.geekdojo.net/andy/articles/1807.aspx  VERY VERY helpful
+
 
 +
http://blogs.geekdojo.net/andy/articles/1807.aspx  VERY VERY helpful  
 +
 
 +
http://www.acme.com/firewall.html more with the SUPER helpfulness
  
 
http://www.daniweb.com/tutorials/2949.html  for getting dhcpd running
 
http://www.daniweb.com/tutorials/2949.html  for getting dhcpd running
  
 
[[Category:Common Tasks]]
 
[[Category:Common Tasks]]
 +
[[Category:FreeBSD for Servers]]
 +
[[Category:Securing FreeBSD]]
 +
[[Category:Firewall]]

Latest revision as of 17:09, 25 August 2012

Contents

[edit] Don't need NAT? don't rebuild the kernel!

The system will dynamically load the kernel module when the rc.conf statement firewall_enable="YES" is used. You do not need to compile IPFW into the FreeBSD kernel unless you want NAT function enabled. You'll still need a ruleset to deal with the traffic your machine gets, of course.


[edit] Building an ipfw-enabled kernel

You're going to need to rebuild your kernel with the appropriate options for the firewall you want to build. We've already got an article on building a custom kernel, but to start you off, here are some kernel options you'll almost certainly want and need:

options         IPFIREWALL                      # you need this to enable ipfw
options         IPFIREWALL_VERBOSE              # you need this to enable ipfw logging
options         IPFIREWALL_VERBOSE_LIMIT=10     # limit to 10 identical log entries
options         IPDIVERT                        # enable NAT

It would be advisable to check out the NOTES files for your particular BSD version and architecture to check out other interesting kernel packet-filtering capabilities that you might or might not want to consider. For example, some kernels support IPSEC (or FAST_IPSEC) security, TCP_DROP_SYNFIN (to defeat FIN scanning), IPSTEALTH (for "invisible" firewalls that don't show up in traceroutes)... but it varies by both BSD version and architecture, so check /usr/src/sys/conf/NOTES for general options and /usr/src/sys/(arch)/conf/NOTES for hardware-specific options.

[edit] Sample ipfw firewall ruleset

This ruleset sets up a firewall on a "bastion" server that both runs publicly accessible services and acts as a NAT-enabled firewall for a protected network running behind it.

ipfw rulesets are shell scripts that can be run directly from the command line (assuming you have an ipfw-enabled kernel loaded) - but remember, if you're running this on a default deny system, you will lose network connectivity on execution of the very first line of this script - meaning that you CANNOT run the script from a remote shell session, or it will stop running before it ever gets past deny all from any to any.

So if you need to restart a firewall remotely, you'll have to use some minor trickery - like scheduling it with the at scheduler. THAT will work, since jobs started from at don't depend on network connectivity to continue running. However, if you're running untested modifications, you'll probably want to schedule ANOTHER job with at for 5 minutes later to pull your firewall back to a "known accessible" configuration, just in case there's a really bad bug in your new rules that will deny you access. NOT leaving yourself a scheduled "oops" to bring you back to a known accessible condition, just in case, could end up costing you a very long drive out to wherever your server is.

With no further ado, here's the sample ipfw ruleset script.

#!/bin/sh

#Quietly flush out rules
/sbin/ipfw -q -f flush

#Set command prefix (add "-q" option after development to turn on quiet mode)
cmd="/sbin/ipfw add"

# set outside and inside network interfaces
oif="xl0"
iif="ed0"

# set private IP of this server and the netmask of the whole LAN side
server="192.168.0.1"
inside="192.168.0.0/24"

######Localhost stuff
#
#allow the computer to talk to itself
$cmd 00080 allow ip from any to any via lo0

#don't let anything from the "outside" talk to localhost
$cmd 00081 deny ip from any to 127.0.0.0/8

#don't let the computer talk other computers as localhost
$cmd 00082 deny log ip from 127.0.0.0/8 to any
#
#######

####### DHCP stuff
#
# you need this to be able to renew your DHCP lease from your ISP
$cmd 00083 allow udp from any 67 to any 68 in recv rl0
#
#####

######### deny-and-log bogus packets by tcpflags
#
# XMAS tree
        $cmd 00084 deny log tcp from any to any in tcpflags fin,psh,urg recv $oif
# NULL scan (no flag set at all)
        $cmd 00085 deny log tcp from any to any in tcpflags !fin,!syn,!rst,!psh,!ack,!urg recv $oif
# SYN flood (SYN,FIN)
        $cmd 00086 deny log tcp from any to any in tcpflags syn,fin recv $oif
# Stealth FIN scan (FIN,RST)
        $cmd 00087 deny log tcp from any to any in tcpflags fin,rst recv $oif
# forced packet routing
        $cmd 00089 deny log ip from any to any in ipoptions ssrr,lsrr,rr,ts recv $oif
#
#######



######### Things served via this machine directly 
######### Any services on this machine should be placed here,
######### before the NAT Divert rule
#
#HTTP
        $cmd 00500 allow tcp from any to any 80 in via $oif
#SSH
        $cmd 00510 allow tcp from any to any 22 in via $oif
#FTP
        $cmd 00570 allow ip from any to any 20 in via $oif
        $cmd 00571 allow ip from any to any 21 in via $oif
        $cmd 00572 allow tcp from any 21 to any out via $oif
#
####


#####NATD stuff

#natd Divert rule
        $cmd 01000 divert natd all from any to any via $oif

######


####All connections originating from my network are allowed

# check to see if a dynamic rule has been created that matches this packet
        $cmd 01100 check-state
# let everything on your internal network talk to the firewall
        $cmd 01101 allow all from any to any via $iif keep-state 
# setup a dynamic rule for any connections being started from inside
        $cmd 01102 allow all from any to any out via $oif keep-state 
# deny ACK packets that did not match the dynamic rule table - do not log, too many false positives
        $cmd 01103 deny tcp from any to any established in via $oif 
#deny fragments as bogus packets
        $cmd 01104 deny log all from any to any frag in via $oif 
#####


####### ICMP stuff

#allow path-mtu in both directions
$cmd 01200 allow icmp from any to any icmptypes 3

#allow source quench in and out
$cmd 01201 allow icmp from any to any icmptypes 4

#allow outbound traceroutes
$cmd 01204 allow icmp from any to any icmptypes 11 in

#allow outbound pings and incoming ping responses
$cmd 01202 allow icmp from any to any icmptypes 8 out
$cmd 01203 allow icmp from any to any icmptypes 0 in

########



##### This section is for exposing services to the internet from the LAN
#####  It is placed AFTER the NATD Divert rule, so these services can be
#####  diverted in /etc/natd.conf

#VNC - allow it, but log connection attempts (though DON'T log traffic for established sessions)
        $cmd 01550 allow log tcp from any to any 5900 in setup
        $cmd 01551 allow tcp from any to any 5900 in
#KAZAA
        $cmd 01580 allow ip from any to $inside 1214 in via $oif
#SOULSEEK
        $cmd 01590 allow ip from any to $inside 2234 in via $oif
        $cmd 01591 allow ip from any to $inside 5534 in via $oif
#EMULE
        $cmd 01600 allow tcp from any to $inside 4662 in via $oif
        $cmd 01601 allow udp from any to $inside 4672 in via $oif
#BITTORRENT
        $cmd 01610 allow ip from any to $inside 30000-40000 in via $oif

####

######## SOME THINGS ARE TOO NOISY TO LIVE
######## In this section we deny things that would be denied anyway, but that we just
######## don't want logged.  Be careful with this - in general, you probably want to 
######## avoid putting anything in here that doesn't specify a known source address that
######## is relatively trustworthy.  You also want to be very careful about who knows
######## what this section of your firewall configs looks like, because they can then
######## use the info to craft probes and attacks they know you won't see or log.

# Don't bother logging IGMP crap from the ISP
$cmd 9004 deny igmp from 172.16.210.1 to any in via $oif

# Don't bother logging DNS garbage inbound from the ISP's DNS boxes
$cmd 9006 deny udp from 4.31.99.0/24\{100-103\} 53 to any dst-port 50000-65535 in via $oif

#####

######## Stealth scans of closed ports
########  this section is to deny and log stealth scans that we can't really deny 
########  on open ports because doing so would disrupt legitimate services.

# ACK scan (ACK,RST)
        $cmd 60000 deny log tcp from any to any in tcpflags ack,rst recv $oif

#####

#############
############# DEFAULT RULE - deny it, and log it, 'cause we're secure like that.
#############
#
$cmd 65000 deny log all from any to any

[edit] Sample /etc/natd.conf

Our bastion firewall/server will also need to handle NAT duties for the boxes it's protecting on the LAN side. /etc/natd.conf is the configuration file for natd, and will allow you to redirect ports from the public side to services on the LAN side, as well as handling standard NATting of connection requests from our protected network to the big bad Internet. Here's a sample /etc/natd.conf.

(Note that for redirection of services to work, you need matching entries in your IPFW ruleset after the NAT Divert rule to allow those services inbound access as well as entries in this /etc/natd.conf!)

# "interface" should be the WAN interface
interface xl0
use_sockets yes
same_ports yes
# set "dynamic" if the WAN interface is controlled by DHCP
dynamic yes

#VNC
        redirect_port tcp 192.168.0.10:5900 5900
#KAZAA
        redirect_port tcp 192.168.0.25:1214 1214
#SOULSEEK
        redirect_port tcp 192.168.0.25:2234 2234
        redirect_port tcp 192.168.0.25:5534 5534
#EMULE
        redirect_port tcp 192.168.0.25:4662 4662
        redirect_port udp 192.168.0.25:4672 4672
#BITTORRENT
        redirect_port tcp 192.168.0.25:30000-40000 30000-40000

[edit] Sample /usr/local/etc/dhcpd.conf file

We're also going to want our bastion firewall/server to deliver DHCP leases to the computers on the protected network. So after installing the dhcp daemon from the /usr/ports/net/isc-dhcp3 port, you'll need to minimally configure it to actually deliver the leases to the clients. Here's a sample /usr/local/etc/dhcpd.conf file:

   # dhcpd.conf
   #
   # Configuration file for ISC dhcpd
   #
   # option definitions common to all supported networks...
   option domain-name "yourdomain.local";
   option domain-name-servers 192.168.0.99;
   default-lease-time 604800;
   max-lease-time 2592000;

   ddns-update-style none;

   # If you have more than one subnet, list them seperately.
   subnet 192.168.0.0 netmask 255.255.255.0 {
   range 192.168.0.200 192.168.100.250;
   option routers 192.168.0.1;
   option broadcast-address 192.168.0.255;
   default-lease-time 4800;
   max-lease-time 7200;
   }

    # This would be for a second subnet, if you had one:
#    subnet 192.168.5.0 netmask 255.255.255.0 {
#    range 192.168.5.200 192.168.5.254;
#    option routers 192.168.5.1;
#    option broadcast-address 192.168.5.255;
#    default-lease-time 4800;
#    max-lease-time 7200;
#    }

# EOF

see also: Firewall, Monitoring


[edit] Helpful External Links

http://www.freebsddiary.org/ipfw.php

http://www.onlamp.com/pub/a/bsd/2001/05/09/FreeBSD_Basics.html

http://blogs.geekdojo.net/andy/articles/1807.aspx VERY VERY helpful

http://www.acme.com/firewall.html more with the SUPER helpfulness

http://www.daniweb.com/tutorials/2949.html for getting dhcpd running

Personal tools