Firewalls
1. Introduction
Firewalls make it possible to filter incoming
and outgoing traffic that flows through your system. A firewall can use one or
more sets of “rules” to inspect the network packets as they come in or go out
of your network connections, and either allows the traffic through, or blocks
it. The rules of a firewall can inspect one or more characteristics of the
packets, including, but not limited to, the protocol type, the source or
destination host address, and the source or destination port.
Firewalls can greatly enhance the security of
a host or a network. They can be used to perform one or more of the following
actions:
- To protect and insulate the applications, services and machines of your internal network from unwanted traffic coming in from the public Internet.
- To limit or disable access from hosts of the internal network to services of the public Internet.
- To support Network Address Translation (NAT), which allows your internal network to use private IP addresses and share a single connection to the public Internet (either with a single IP address or by a shared pool of automatically assigned public addresses).
2. Concepts
There are two basic ways to create firewall
rulesets: “inclusive” or “exclusive”. An exclusive firewall allows all traffic
through, except for the traffic matching the ruleset. An inclusive firewall
does the reverse. It only allows traffic matching the rules through, and blocks
everything else.
Inclusive firewalls are generally safer than
exclusive firewalls because they significantly reduce the risk of allowing
unwanted traffic to pass through the firewall.
Security can be further tightened using a
“stateful firewall”. This firewall keeps track of which connections are opened
through the firewall, and will only allow traffic through which either matches
an existing connection, or opens a new one. The disadvantage of a stateful
firewall is that it can be vulnerable to Denial of Service (DoS) attacks if a lot of new connections are opened very
quickly. It is generally possible to use a combination of stateful and
non-stateful behavior to make an optimal firewall for a website.
Many firewall packages are available for
UNIX-flavored systems. IPFW is the easiest and most efficient IP-based firewall
system currently running on FreeBSD OS.
3. IPFIREWALL (IPFW)
The IPFIREWALL (IPFW) is a FreeBSD-sponsored
firewall software application, authored and maintained by FreeBSD volunteer
staff members. It uses the legacy stateless rules and a legacy rule coding
technique to achieve what is referred to as Simple Stateful logic.
The IPFW sample rule set (found in /etc/rc.firewall) in the standard
FreeBSD install is rather simple and it is not expected that it used directly
without modifications. The example does not use stateful filtering, which is
beneficial in most setups, so it will not be used as base for this section.
The IPFW stateless rule syntax is empowered
with technically sophisticated selection capabilities, which far surpass the
knowledge level of the customary firewall installer. IPFW is targeted at
professional users and at advanced technical computer hobbyists who have
advanced packet selection requirements. A high degree of detailed knowledge
into how different protocols use and create their unique packet header
information is a prerequisite. Providing that level of explanation is out of
the scope of this tutorial.
IPFW is composed of seven components:
1.
The
primary component is the kernel firewall filter rule processor and its
integrated packet accounting facility
2.
The
logging facility
3.
The
'divert' rule which triggers the NAT facility
4.
The
advanced special purpose facilities
5.
The
dummynet traffic shaper facilities
6.
The
'fwd rule' forward facility
7.
The
bridge facility
8.
The
ipstealth facility
3.1. Enabling IPFW
IPFW is included in the basic FreeBSD
installation package as a separate run-time loadable module. The system
dynamically loads the kernel module when the rc.conf statement firewall_enable="YES" is used. Do not
compile IPFW into the FreeBSD kernel unless you want the NAT
function enabled.
After rebooting your system with firewall_enable="YES" in rc.conf the following
message, highlighted in white, is displayed on the screen as part of the boot
process:
ipfw2 initialized, divert disabled,
rule-based forwarding disabled, default to deny, logging disabled
The loadable module already has logging
ability compiled in it. To enable logging and set the verbose logging limit,
there is a knob you can set in /etc/sysctl.conf by adding these
statements; logging will be enabled on future reboots:
net.inet.ip.fw.verbose=1
net.inet.ip.fw.verbose_limit=5
|
3.1.1. Kernel Options
It is not a mandatory requirement to enable
IPFW by compiling the following options into the FreeBSD kernel unless you need
the NAT function. It is presented in this tutorial
as background information:
options IPFIREWALL
This option enables IPFW as part of the
kernel.
options IPFIREWALL_VERBOSE
Enables logging of packets that pass through
IPFW and have the 'log' keyword specified in the rule set.
options IPFIREWALL_VERBOSE_LIMIT=5
Limits the number of packets logged through
syslogd on a per-entry basis. Use this option in hostile environments in which
you want to log firewall activity. This will close a possible Denial of Service
(DoS) attack via syslog flooding.
options IPFIREWALL_DEFAULT_TO_ACCEPT
This option will allow everything to pass
through the firewall by default, which is a good idea when you are first
setting up your firewall.
options IPV6FIREWALL
options IPV6FIREWALL_VERBOSE
options IPV6FIREWALL_VERBOSE_LIMIT
options IPV6FIREWALL_DEFAULT_TO_ACCEPT
These options are exactly the same as the
IPv4 options, but they are for IPv6. If you do not use IPv6, you might want to
use IPV6FIREWALL without any rules to block all IPv6.
options IPDIVERT
This
enables the use of the NAT functionality.
Note:
If you do not include IPFIREWALL_DEFAULT_TO_ACCEPT or set your rules to allow
incoming packets, you will block all packets going to, and from, your machine.
3.1.2. /etc/rc.conf Options
If
you do not have IPFW compiled into your kernel, you will need to load it with
the following statement in /etc/rc.conf:
firewall_enable="YES"
Set
the script to run to activate your rules:
firewall_script="/etc/ipfw.rules"
Enable
logging:
The IPFW command is the normal vehicle for
making manual single rule additions or deletions to the firewall’s active
internal rules while it is running. The problem with using this method is, once
your system is shutdown or halted, all the rules you added, changed, or
deleted, are lost. Writing all your rules in a file, and using that file to load
the rules at boot time, or to replace, en
masse, the currently running firewall rules with changes you made to the
file’s content, is the recommended method used here.
The IPFW command is very useful to display
the running firewall rules to the console screen. The IPFW accounting facility
dynamically creates a counter for each rule that counts each packet that
matches the rule. During the process of testing a rule, listing the rule with
its counter is one of the ways of determining if the rule is functioning.
To list all the rules in sequence:
# ipfw list
To list all the rules with a time stamp of
when the last time the rule was matched:
# ipfw
-t list
To list the accounting information,
packet-count the matched rules along with the rules themselves. The first
column is the rule number, followed by the number of outgoing matched packets,
followed by the number of incoming matched packets, and then the rule itself:
# ipfw
-a list
List the dynamic rules in addition to the
static rules:
# ipfw
-d list
Show the expired dynamic rules:
# ipfw
-d -e list
Zero the counters:
# ipfw
zero
Zero the counters for just rule NUM:
# ipfw
zero NUM
3.3. IPFW Rule Sets
A rule set is a group of IPFW rules coded to
allow or deny packets based on the values contained in the packet. The
bi-directional exchange of packets between hosts comprises a session
conversation. The firewall rule set processes the packet twice: once on its
arrival from the public Internet host, and again as it leaves for its return
trip back to the public Internet host. Each TCP/IP service (i.e. Telnet, www,
mail, etc.) is pre-defined by its protocol, and by its port number. This is the
basic selection criteria used to create rules which will allow or deny
services.
When a packet enters the firewall, it is
compared against the first rule in the rule set. It then progresses one rule at
a time, moving from top to bottom of the set in an ascending rule number
sequence order. When the packet matches a rule selection’s parameters, the
rules action field value is executed, and the search of the rule set terminates
for that packet. This is referred to as “the first match wins” search method.
If the packet does not match any of the rules, it gets caught by the mandatory
IPFW default rule, number 65535, which denies all packets, and discards them,
without any reply, back to the originating destination.
The instructions contained here are based on
using rules that contain the stateful 'keep state', 'limit', 'in'/'out', and
‘via’ options. This is the basic framework for coding an inclusive type
firewall rule set.
An inclusive firewall only allows those
services to come through which match the rules. In this way, you can control
which services can originate behind the firewall destined for the public
Internet, and also control the services which can originate from the public
Internet accessing your private network. Everything else is denied by the
default design. Inclusive firewalls are much more secure than exclusive
firewall rule sets, and are the only rule set type covered in this tutorial.
3.3.1. Rule Syntax
The rule syntax presented here has been
simplified to include only that which is necessary to create a standard
inclusive type firewall rule set.
Rules contain keywords; these keywords have
to be coded in a specific order from left to right on the line. Keywords are
identified in bold type. Some keywords have sub-options, which may be keywords
themselves, and also include more sub-options.
# is used to mark the
start of a comment and may appear at the end of a rule line, or on its own
lines. Blank lines are ignored.
CMD RULE_NUMBER ACTION LOGGING SELECTION STATEFUL
Each new rule has to be prefixed with add
to add the rule to the internal table.
RULE_NUMBER
Each
rule has to have a rule number to go with it.
ACTION
ACTION
A rule can be associated with one of the
following actions, which will be executed when the packet matches the selection
criterion of the rule.
allow | accept | pass | permit
All these words mean the same thing, which is
to allow packets that match the rule to exit the firewall rule processing. The
search terminates at this rule.
check-state
It checks the packet against the dynamic
rules table. If a match is found, execute the action associated with the rule
which generated this dynamic rule, otherwise move onto the next rule. The
check-state rule does not have a selection criterion. If no check-state rule is
present in the rule set, the dynamic rules table is checked at the first
keep-state or limit rule.
deny | drop
Both words mean the same thing, which is to
discard packets that match this rule. The search terminates.
LOGGING
log or logamount
When a packet matches a rule with the log
keyword, a message will be logged to syslogd with a facility name of SECURITY.
The logging only occurs if the number of packets logged so far for that
particular rule does not exceed the logamount parameter. If no logamount is
specified, the limit is taken from the sysctl variable
net.inet.ip.fw.verbose_limit. In both cases, a value of zero removes the logging
limit. Once the limit is reached, logging can be re-enabled by clearing the
logging counter or the packet counter for that rule; see the IPFW reset log
command.
The keywords described below are used to
describe the attributes of the packet to be interrogated when determining
whether the rules match the packet or not. The following general-purpose
attributes are provided for matching, and must be used in this order:
udp | tcp | icmp
or any protocol names found in /etc/protocols are recognized and
may be used. The value specified has a protocol to be matched against. This is
a mandatory requirement.
from src to dst
The ‘from’ and ‘to’ keywords are used to
match against IP addresses. Rules must specify both the source and the
destination parameters. ‘any’ is a special keyword
that matches any IP address. ‘me’ is a special keyword
that matches any IP address configured on an interface in your FreeBSD system
to represent the PC the firewall is running on (i.e. this box) as in 'from me
to any' or 'from any to me' or 'from 0.0.0.0/0 to any' or 'from any to
0.0.0.0/0' or 'from 0.0.0.0 to any' or 'from any to 0.0.0.0' or 'from me to
0.0.0.0'. IP addresses are specified as a dotted IP address numeric
form/mask-length, or as a single-dotted IP address numeric form. This is a
mandatory requirement.
port number
For protocols which support port numbers
(such as TCP and UDP). It is mandatory that you code
the port number of the service you want to match it with. Service names (from /etc/services) may be used instead
of numeric port values.
in | out
The keywords ‘in’ and ‘out’ match incoming or
outgoing packets, respectively; it is mandatory that you code one or the other
as part of your rule-matching criterion.
via IF
Matches packets going through an interface
specified by an exact name. The ‘via’ keyword causes the
interface to always be checked as part of the matching process.
setup
This is a mandatory keyword that identifies
the session start request for TCP packets.
keep-state
This is a mandatory keyword. Upon a match,
the firewall will create a dynamic rule, whose default behavior is to match
bi-directional traffic between the source and the destination IP/port using the
same protocol.
limit {src-addr | src-port | dst-addr | dst-port}
The firewall will only allow N connections with the
same set of parameters as specified in the rule. One or more of the source and
destination addresses and ports can be specified. Both 'limit' and 'keep-state'
cannot be used on the same rule. Also, ‘limit’ provides the same stateful
function as 'keep-state', plus its own functions.
STATEFULL Rule Option
Stateful filtering treats traffic as a
bi-directional exchange of packets comprising a session conversation. It has
the interrogation abilities to determine if the session conversation between
the originating sender and the destination are following the valid procedure of
a bi-directional packet exchange. Any packets that improperly fit the session
conversation template are automatically rejected as impostors.
'check-state' is used to identify where, in
the IPFW rules set, the packet is to be tested against the dynamic rules
facility. Upon finding a match, the packet exits the firewall to continue on
its way, and a new rule is dynamically created for the next anticipated packet
being exchanged during this bi-directional session conversation. Upon not
matching, the packet advances to the next rule in the rule set for testing.
The dynamic rules facility is vulnerable to
resource depletion from a SYN-flood attack, which can open a huge number of
dynamic rules. To counter this attack, FreeBSD Version 4.5 has added another
new option known as ‘limit'. This option is used to limit the number of
simultaneous session conversations by interrogating the rules source or destinations
fields as directed by the limit option and using the packet's IP address found
there, in a search of the open dynamic rules counting the number of times this
rule and IP address combination occurred, if this count is greater that the
value specified on the limit option, the packet is discarded.
Logging Firewall
Messages
Logging provides the ability to review, after
the fact, the rules you activated logging on. This provides information such as
which packets had been dropped, which addresses they had come from, and where
they were going. This process provides a significant edge in tracking down
attackers.
Even with the logging facility enabled, IPFW
does not generate any rule-logging on its own. The firewall administrator
decides which rules in the rule set require logging, and adds the log verb to
those rules. Normally only deny rules are logged, like the deny rule for
incoming ICMP pings. It is customary to duplicate
the IPFW default deny everything rule, with the log verb included as the last
rule in the rule set. This way, the administrator gets to see all the packets
that did not match any of the rules in the rule set.
Logging is a two-edged sword; if you are not
careful, you can lose yourself in an over-abundance of log data, and fill up
your disk with growing log files. A DoS attack that fills up disk drives is one
of the oldest attacks around. These log messages are not only written to
syslogd, but are also displayed on the root console screen, and soon become
very annoying.
The IPFIREWALL_VERBOSE_LIMIT=5 kernel option limits
the number of consecutive messages sent to the system logger syslogd concerning
the packet-matching of a given rule. When this option is enabled in the kernel,
the number of consecutive messages concerning a particular rule is capped at
the number specified. There is nothing to be gained from 200 log messages
saying the same thing. Five consecutive messages concerning a particular rule,
for example, will be logged to syslogd, the remaining identical consecutive
messages will be counted, and posted to syslogd with a phrase like this:
last
message repeated 45 times
All logged packets’ messages are written by
default to the /var/log/security file, which is
defined in the /etc/syslog.conf file.
3.4. Building a Rule Script
Most experienced IPFW users create a file
containing the rules, and code them in a manner compatible with running them as
a script. The major benefit of doing this is that the firewall rules can be
refreshed en masse without the need
to reboot the system to activate the new rules. This method is very convenient
in testing new rules, as the procedure can be executed as many times as is
necessary. Being a script, you can use symbolic substitution to code frequently
used values and substitute them in multiple rules.
Consider the following example. The script
syntax used here is compatible with the 'sh', 'csh', 'tcsh' shells. Symbolic
substitution fields are prefixed with a dollar sign $. Symbolic fields do not
have the $ prefix. The value to populate the symbolic field must be enclosed in
"double quotes".
Start your rules’ file like this:
###############
start of example ipfw rules script #############
#
ipfw
-q -f flush # Delete all rules
#
Set defaults
oif="tun0" # out interface
odns="192.0.2.11" # ISP's DNS server IP address
cmd="ipfw
-q add " # build rule prefix
ks="keep-state" # just too lazy to key this each time
$cmd
00500 check-state
$cmd
00502 deny all from any to any frag
$cmd
00501 deny tcp from any to any established
$cmd
00600 allow tcp from any to any 80 out via $oif setup $ks
$cmd
00610 allow tcp from any to $odns 53 out via $oif setup $ks
$cmd
00611 allow udp from any to $odns 53 out via $oif $ks
###################
End of example ipfw rules script ############
|
The rules are not important in this example;
how the symbolic substitution field is populated and used is.
If the above example is in the /etc/ipfw.rules file, you can reload
these rules by typing:
# sh
/etc/ipfw.rules
The /etc/ipfw.rules file can be located
and named according to your preference. This can also be accomplished by
running the following commands:
# ipfw -q
-f flush
# ipfw -q
add check-state
# ipfw -q
add deny all from any to any frag
# ipfw -q
add deny tcp from any to any established
# ipfw -q
add allow tcp from any to any 80 out via tun0 setup keep-state
# ipfw -q
add allow tcp from any to 192.0.2.11 53 out via tun0 setup keep-state
# ipfw -q
add 00611 allow udp from any to 192.0.2.11 53 out via tun0 keep-state
Stateful Ruleset
The
following non-NATed rule set is an example of how to
code a very secure 'inclusive' type of firewall. An inclusive firewall only
allows those services to pass through that match the rules, and blocks all
other by default. All firewalls have a minimum of two interfaces, which have to
have rules to allow the firewall to function.
All
UNIX® flavored operating systems, FreeBSD included, are designed to use the
interface lo0 and the IP address 127.0.0.1 for internal
communication within an operating system. The firewall rules must contain rules
to allow the free movement of these special, internally-used packets.
The interface which faces the public Internet
is the one which you code your rules to authorize and control access out to the
public Internet and access requests arriving from the public Internet. This can
be your ppp tun0 interface, or your NIC that is
connected to your DSL or cable modem.
In cases where one or more than one NIC is
connected to a private LAN behind the firewall, the interfaces must have rules coded
to allow the free movement of packets originating from those LAN interfaces.
The rules should first be organized into
three major sections: all the free interfaces; the public interface outbound,
and the public interface inbound.
The order of the rules in each of the public
interface sections should be in order of the most-used rules being placed
before less often-used rules, with the last rule in the section being a block
log all packets on that interface and direction.
The ‘Outbound’ section in the following rule
set only contains 'allow' rules, which contain selection values that uniquely
identify the service that is authorized for public Internet access. All the
rules have proto, port, in/out, via and keep state option coded. The 'proto
tcp' rules have the 'setup' option included to identify the start session
request as the trigger packet to be posted to the keep state stateful table.
The ‘Inbound’ section contains all the
blocking of unwelcome packets for two different reasons. Firstly, the packets
being blocked may be part of an otherwise valid packet, which may be allowed in
by later authorized service rules. Secondly, this rule explicitly blocks
selected packets that one receives on an infrequent basis, and does not want to
see in the log. This keeps them from being caught by the last rule in the
section, which blocks and logs all packets which have fallen through the rules.
This last rule creates the legal evidence needed to prosecute the people who
are attacking your system.
No response is returned for any unwelcome
material; their packets just get dropped and vanish. This way, the attacker has
no knowledge of whether his or her packets have reached your system. The less
the attackers can learn about your system, the more secure it is. When you log
packets with port numbers you do not recognize, look the numbers up in /etc/services/ or go to http://www.securitystats.com/tools/portsearch.php
and look up a port number to find what its purpose is. Visit http://www.simovits.com/trojans/trojans.html
for port numbers used by Trojans.
3.4.1. A Sample Inclusive Rule set
The following non-NATed
rule set is a completely inclusive type rule set. Comment out any pass rules
for services you do not want. If you see any unwelcome messages in your log,
add a deny rule in the inbound section. Change the 'dc0' interface name in
every rule to the interface name of the NIC that connects your system to the
public Internet. For user ppp it would be 'tun0'.
Observe a pattern in the usage of these
rules:
- All statements that are a request to start a session to the public Internet use ‘keep-state’.
- All the authorized services that originate from the public Internet have the ‘limit’ option to stop flooding.
- All rules use ‘in’ or ‘out’ to clarify direction.
- All rules use the ‘via’ interface name to specify the interface the packet is travelling over.
The following rules go into /etc/ipfw.rules.
################
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="dc0" # public interface name of NIC
# facing the public Internet
#################################################################
#
No restrictions on Inside LAN Interface for private network
#
Not needed unless you have LAN.
#
Change xl0 to your LAN NIC interface name
#################################################################
#$cmd
00005 allow all from any to any via xl0
#################################################################
#
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
#
destine for the public Internet.
#################################################################
#
Allow out access to my ISP's Domain name server.
#
x.x.x.x must be the IP address of your ISP.s DNS
#
Dup these lines if your ISP has more than one DNS server
#
Get the IP addresses from /etc/resolv.conf file
$cmd
00110 allow tcp from any to x.x.x.x 53 out via $pif setup keep-state
$cmd
00111 allow udp from any to x.x.x.x 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 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 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 Time
$cmd
00260 allow tcp from any to any 37 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
#
deny and log everything else that.s trying to get out.
#
This rule enforces the block all by default logic.
$cmd
00299 deny log all from any to any out via $pif
#################################################################
#
Interface facing Public Internet (Inbound Section)
#
Interrogate packets originating from the public Internet
#
destine for this gateway server or the private network.
#################################################################
#
Deny all inbound traffic from non-routable reserved address spaces
$cmd
00300 deny all from 192.168.0.0/16 to any in via $pif #RFC 1918 private IP
$cmd
00301 deny all from 172.16.0.0/12 to any in via $pif #RFC 1918 private IP
$cmd
00302 deny all from 10.0.0.0/8 to any in via $pif #RFC 1918 private IP
$cmd
00303 deny all from 127.0.0.0/8 to any in via $pif #loopback
$cmd
00304 deny all from 0.0.0.0/8 to any in via $pif #loopback
$cmd
00305 deny all from 169.254.0.0/16 to any in via $pif #DHCP auto-config
$cmd
00306 deny all from 192.0.2.0/24 to any in via $pif #reserved for docs
$cmd
00307 deny all from 204.152.64.0/23 to any in via $pif #Sun cluster interconnect
$cmd
00308 deny all from 224.0.0.0/3 to any in via $pif #Class D & E multicast
#
Deny public pings
$cmd
00310 deny icmp from any to any in via $pif
#
Deny ident
$cmd
00315 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
00320 deny tcp from any to any 137 in via $pif
$cmd
00321 deny tcp from any to any 138 in via $pif
$cmd
00322 deny tcp from any to any 139 in via $pif
$cmd
00323 deny tcp from any to any 81 in via $pif
#
Deny any late arriving packets
$cmd
00330 deny all from any to any frag in via $pif
#
Deny ACK packets that did not match the dynamic rule table
$cmd
00332 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
00360 allow udp from any to x.x.x.x 67 in via $pif keep-state
#
Allow in standard www function because I have apache server
$cmd
00400 allow tcp from any to me 80 in via $pif setup limit src-addr 2
#
Allow in secure FTP, Telnet, and SCP from public Internet
$cmd
00410 allow tcp from any to me 22 in via $pif setup limit src-addr 2
#
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
00420 allow tcp from any to me 23 in via $pif setup limit src-addr 2
#
Reject & Log all incoming connections from the outside
$cmd
00499 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 ###############################
|
3.4.2. A Sample NAT and Stateful Rule set
Some additional configuration statements need
to be enabled in order to activate IPFW’s NAT
function. The kernel source needs the 'option divert' statement to be added to
the other IPFIREWALL statements, and compiled into a custom kernel.
In addition to the normal IPFW options in /etc/rc.conf, the following are
required:
natd_enable="YES" # Enable NATD function
natd_interface="rl0" # interface name of public Internet NIC
natd_flags="-dynamic
-m" # -m = preserve port numbers if possible
Utilizing
stateful rules with the ‘divert natd’ rule (Network Address Translation)
greatly complicates the rule set coding logic. The positioning of the
‘check-state’ and 'divert natd' rules in the rule set becomes very critical.
This is no longer a simple fall-through logic flow. A new action type is used,
called 'skipto'. To use the skipto command, it is mandatory that you number
each rule so that you know exactly where the skipto rule number is you are
really jumping to.
The
following is an uncommented example of one coding method, selected here to
explain the sequence of the packet flow through the rule sets.
The
processing flow starts with the first rule from the top of the rule file, and
its progress, one rule at a time, deeper into the file, until the end is
reached, or the packet being tested to the selection criteria matches it, and
the packet is released out of the firewall. It is important to take notice of
the location of rule numbers 100, 101, 450, 500, and 510. These rules control
the translation of the outbound and inbound packets, so their entries in the
keep-state dynamic table always register the private LAN IP address. Allow and
deny rules specify the direction in which the packet is going (outbound or
inbound) and the interface. All the start outbound session requests skip to
rule 500 for the network address translation.
Suppose a LAN user uses his or her web
browser to get a web page. Web pages communicate over port 80. The packet
enters the firewall. It does not match rule 100 because it is headed out, not
in. It passes rule 101 because this is the first packet, so it has not been
posted to the keep-state dynamic table yet. The packet finally comes to rule
125 and matches. It is outbound through the NIC facing the public Internet. The
packet still retains its source IP address as a private LAN IP address. Upon
matching with this rule, two actions take place. The keep-state option posts
this rule into the keep-state dynamic rules table, and the specified action is
executed. The action is part of the information posted to the dynamic table. In
this case it is "skipto rule 500". Rule 500 NATs
the packet IP address, and out it goes. This is very important. This packet
makes its way to the destination and returns and enters the top of the rule
set. This time it matches rule 100, and has its destination IP address mapped
back to its corresponding LAN IP address. It is then processed by the
check-state rule, found in the table as an existing session conversation, and
released to the LAN. It goes to the LAN PC that sent it, and a new packet is
sent, requesting another segment of the data from the remote server. This time
it gets checked by the check-state rule, its outbound entry is found, and the
associated action, 'skipto 500', is executed. The packet jumps to rule 500,
gets NATed and is released on its way out.
On the inbound side, everything coming in
that is part of an existing session conversation is being automatically handled
by the ‘check-state’ rule and the properly placed ‘divert natd’ rules. All you
have to address is deny all the bad packets and only allow in the authorized
services. Let us say there is an Apache server running on the firewall box, and
you want people on the public Internet to be able to access the local website.
The new inbound start request packet matches rule 100, and its IP address is
mapped to the LAN IP for the firewall box. The packet is then matched against
the unwelcome elements you want to check for, and finally matches against rule
425. Upon matching, two things happen. The packet rule is posted to the
keep-state dynamic table, but this time, any new session request originating
from that source IP address is limited to two. This defends against Denial of
Service (DoS) attacks running on the specified port number. The action is
allowed, and the packet is released to the LAN. On returning, the check-state
rule recognizes the packet as belonging to an existing session conversation,
sends it to rule 500 for NATing, and it is released
to an outbound interface.
Example
Ruleset #1:
#!/bin/sh
cmd="ipfw
-q add"
skip="skipto
500"
pif=rl0
ks="keep-state"
good_tcpo="22,25,37,43,53,80,443,110,119"
ipfw
-q -f flush
$cmd
002 allow all from any to any via xl0
# exclude LAN traffic
$cmd
003 allow all from any to any via lo0
# exclude loopback traffic
$cmd
100 divert natd ip from any to any in via $pif
$cmd
101 check-state
#
Authorized outbound packets
$cmd
120 $skip udp from any to xx.168.240.2 53 out via $pif $ks
$cmd
121 $skip udp from any to xx.168.240.5 53 out via $pif $ks
$cmd
125 $skip tcp from any to any $good_tcpo out via $pif setup $ks
$cmd
130 $skip icmp from any to any out via $pif $ks
$cmd
135 $skip udp from any to any 123 out via $pif $ks
#
Deny all inbound traffic from non-routable reserved address spaces
$cmd
300 deny all from 192.168.0.0/16 to
any in via $pif #RFC 1918 private IP
$cmd
301 deny all from 172.16.0.0/12 to
any in via $pif #RFC 1918 private IP
$cmd
302 deny all from 10.0.0.0/8 to
any in via $pif #RFC 1918 private IP
$cmd
303 deny all from 127.0.0.0/8 to
any in via $pif #loopback
$cmd
304 deny all from 0.0.0.0/8 to
any in via $pif #loopback
$cmd
305 deny all from 169.254.0.0/16 to
any in via $pif #DHCP auto-config
$cmd
306 deny all from 192.0.2.0/24 to
any in via $pif #reserved for docs
$cmd
307 deny all from 204.152.64.0/23 to any in via $pif #Sun cluster
$cmd
308 deny all from 224.0.0.0/3 to
any in via $pif #Class D & E
multicast
#
Authorized inbound packets
$cmd
400 allow udp from xx.70.207.54 to any 68 in $ks
$cmd
420 allow tcp from any to me 80 in via $pif setup limit src-addr 1
$cmd
450 deny log ip from any to any
#
This is skipto location for outbound stateful rules
$cmd
500 divert natd ip from any to any out via $pif
$cmd
510 allow ip from any to any
########################
end of rules ##################
|
The
following is pretty much the same as above, but uses a self-documenting coding
style full of description comments to help an inexperienced IPFW rule writer
better understand what the rules are doing.
Example
Ruleset #2:
#!/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"
skip="skipto
800"
pif="rl0" # public interface name of NIC
# facing the public Internet
#################################################################
#
No restrictions on Inside LAN Interface for private network
#
Change xl0 to your LAN NIC interface name
#################################################################
$cmd
005 allow all from any to any via xl0
#################################################################
#
No restrictions on Loopback Interface
#################################################################
$cmd
010 allow all from any to any via lo0
#################################################################
#
check if packet is inbound and nat address if it is
#################################################################
$cmd
014 divert natd ip from any to any in via $pif
#################################################################
#
Allow the packet through if it has previous been added to the
#
the "dynamic" rules table by a allow keep-state statement.
#################################################################
$cmd
015 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
#
destine for the public Internet.
#################################################################
#
Allow out access to my ISP's Domain name server.
#
x.x.x.x must be the IP address of your ISP's DNS
#
Dup these lines if your ISP has more than one DNS server
#
Get the IP addresses from /etc/resolv.conf file
$cmd
020 $skip tcp from any to x.x.x.x 53 out via $pif setup keep-state
#
Allow out access to my ISP's DHCP server for cable/DSL configurations.
$cmd
030 $skip udp from any to x.x.x.x 67 out via $pif keep-state
#
Allow out non-secure standard www function
$cmd
040 $skip tcp from any to any 80 out via $pif setup keep-state
#
Allow out secure www function https over TLS SSL
$cmd
050 $skip tcp from any to any 443 out via $pif setup keep-state
#
Allow out send & get email function
$cmd
060 $skip tcp from any to any 25 out via $pif setup keep-state
$cmd
061 $skip tcp from any to any 110 out via $pif setup keep-state
#
Allow out FreeBSD (make install & CVSUP) functions
#
Basically give user root "GOD" privileges.
$cmd
070 $skip tcp from me to any out via $pif setup keep-state uid root
#
Allow out ping
$cmd
080 $skip icmp from any to any out via $pif keep-state
#
Allow out Time
$cmd
090 $skip tcp from any to any 37 out via $pif setup keep-state
#
Allow out nntp news (i.e. news groups)
$cmd
100 $skip 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
110 $skip tcp from any to any 22 out via $pif setup keep-state
#
Allow out whois
$cmd
120 $skip tcp from any to any 43 out via $pif setup keep-state
#
Allow ntp time server
$cmd
130 $skip udp from any to any 123 out via $pif keep-state
#################################################################
#
Interface facing Public Internet (Inbound Section)
#
Interrogate packets originating from the public Internet
#
destine for this gateway server or the private network.
#################################################################
#
Deny all inbound traffic from non-routable reserved address spaces
$cmd
300 deny all from 192.168.0.0/16 to
any in via $pif #RFC 1918 private IP
$cmd
301 deny all from 172.16.0.0/12 to
any in via $pif #RFC 1918 private IP
$cmd
302 deny all from 10.0.0.0/8 to
any in via $pif #RFC 1918 private IP
$cmd
303 deny all from 127.0.0.0/8 to
any in via $pif #loopback
$cmd
304 deny all from 0.0.0.0/8 to
any in via $pif #loopback
$cmd
305 deny all from 169.254.0.0/16 to
any in via $pif #DHCP auto-config
$cmd
306 deny all from 192.0.2.0/24 to
any in via $pif #reserved for docs
$cmd
307 deny all from 204.152.64.0/23 to any in via $pif #Sun cluster
$cmd
308 deny all from 224.0.0.0/3 to
any in via $pif #Class D & E
multicast
#
Deny ident
$cmd
315 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
320 deny tcp from any to any 137 in via $pif
$cmd
321 deny tcp from any to any 138 in via $pif
$cmd
322 deny tcp from any to any 139 in via $pif
$cmd
323 deny tcp from any to any 81 in via
$pif
#
Deny any late arriving packets
$cmd
330 deny all from any to any frag in via $pif
#
Deny ACK packets that did not match the dynamic rule table
$cmd
332 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
360 allow udp from x.x.x.x to any 68 in via $pif keep-state
#
Allow in standard www function because I have Apache server
$cmd
370 allow tcp from any to me 80 in via $pif setup limit src-addr 2
#
Allow in secure FTP, Telnet, and SCP from public Internet
$cmd
380 allow tcp from any to me 22 in via $pif setup limit src-addr 2
#
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
390 allow tcp from any to me 23 in via $pif setup limit src-addr 2
#
Reject & Log all unauthorized incoming connections from the public
Internet
$cmd
400 deny log all from any to any in via $pif
#
Reject & Log all unauthorized out going connections to the public
Internet
$cmd
450 deny log all from any to any out via $pif
#
This is skipto location for outbound stateful rules
$cmd
800 divert natd ip from any to any out via $pif
$cmd
801 allow ip from any to any
#
Everything else is denied by default
#
deny and log all packets that fell through to see what they are
$cmd
999 deny log all from any to any
################
End of IPFW rules file ###############################
|
No comments:
Post a Comment