2182 lines
62 KiB
Groff
2182 lines
62 KiB
Groff
.\"
|
|
.\" $FreeBSD$
|
|
.\"
|
|
.Dd August 13, 2002
|
|
.Dt IPFW 8
|
|
.Os
|
|
.Sh NAME
|
|
.Nm ipfw
|
|
.Nd IP firewall and traffic shaper control program
|
|
.Sh SYNOPSIS
|
|
.Nm
|
|
.Op Fl cq
|
|
.Cm add
|
|
.Ar rule
|
|
.Nm
|
|
.Op Fl acdefnNStT
|
|
.Brq Cm list | show
|
|
.Op Ar rule | first-last ...
|
|
.Nm
|
|
.Op Fl f | q
|
|
.Cm flush
|
|
.Nm
|
|
.Op Fl q
|
|
.Brq Cm delete | zero | resetlog
|
|
.Op Cm set
|
|
.Op Ar number ...
|
|
.Nm
|
|
.Cm enable
|
|
.Brq Cm firewall | one_pass | debug | verbose | dyn_keepalive
|
|
.Nm
|
|
.Cm disable
|
|
.Brq Cm firewall | one_pass | debug | verbose | dyn_keepalive
|
|
.Pp
|
|
.Nm
|
|
.Cm set Oo Cm disable Ar number ... Oc Op Cm enable Ar number ...
|
|
.Nm
|
|
.Cm set move
|
|
.Op Cm rule
|
|
.Ar number Cm to Ar number
|
|
.Nm
|
|
.Cm set swap Ar number number
|
|
.Nm
|
|
.Cm set show
|
|
.Pp
|
|
.Nm
|
|
.Brq Cm pipe | queue
|
|
.Ar number
|
|
.Cm config
|
|
.Ar config-options
|
|
.Nm
|
|
.Op Fl s Op Ar field
|
|
.Brq Cm pipe | queue
|
|
.Brq Cm delete | list | show
|
|
.Op Ar number ...
|
|
.Pp
|
|
.Nm
|
|
.Op Fl cnNqS
|
|
.Oo
|
|
.Fl p Ar preproc
|
|
.Oo
|
|
.Ar preproc-flags
|
|
.Oc
|
|
.Oc
|
|
.Ar pathname
|
|
.Sh DESCRIPTION
|
|
The
|
|
.Nm
|
|
utility is the user interface for controlling the
|
|
.Xr ipfw 4
|
|
firewall and the
|
|
.Xr dummynet 4
|
|
traffic shaper in
|
|
.Fx .
|
|
.Pp
|
|
.Bd -ragged -offset XXXX
|
|
.Em NOTE:
|
|
this manual page documents the newer version of
|
|
.Nm
|
|
introduced in
|
|
.Fx
|
|
CURRENT in July 2002, also known as
|
|
.Nm ipfw2 .
|
|
.Nm ipfw2
|
|
is a superset of the old firewall,
|
|
.Nm ipfw1 .
|
|
The differences between the two are listed in Section
|
|
.Sx IPFW2 ENHANCEMENTS ,
|
|
which you are encouraged to read to revise older rulesets and possibly
|
|
write them more efficiently.
|
|
See Section
|
|
.Sx USING IPFW2 IN FreeBSD-STABLE
|
|
for instructions on how to run
|
|
.Nm ipfw2
|
|
on
|
|
.Fx
|
|
STABLE.
|
|
.Ed
|
|
.Pp
|
|
An
|
|
.Nm
|
|
configuration, or
|
|
.Em ruleset ,
|
|
is made of a list of
|
|
.Em rules
|
|
numbered from 1 to 65535.
|
|
Packets are passed to
|
|
.Nm
|
|
from a number of different places in the protocol stack
|
|
(depending on the source and destination of the packet,
|
|
it is possible that
|
|
.Nm
|
|
is invoked multiple times on the same packet).
|
|
The packet passed to the firewall is compared
|
|
against each of the rules in the firewall
|
|
.Em ruleset .
|
|
When a match is found, the action corresponding to the
|
|
matching rule is performed.
|
|
.Pp
|
|
Depending on the action and certain system settings, packets
|
|
can be reinjected into the firewall at some rule after the
|
|
matching one for further processing.
|
|
.Pp
|
|
An
|
|
.Nm
|
|
ruleset always includes a
|
|
.Em default
|
|
rule (numbered 65535) which cannot be modified or deleted,
|
|
and matches all packets.
|
|
The action associated with the
|
|
.Em default
|
|
rule can be either
|
|
.Cm deny
|
|
or
|
|
.Cm allow
|
|
depending on how the kernel is configured.
|
|
.Pp
|
|
If the ruleset includes one or more rules with the
|
|
.Cm keep-state
|
|
or
|
|
.Cm limit
|
|
option, then
|
|
.Nm
|
|
assumes a
|
|
.Em stateful
|
|
behaviour, i.e. upon a match it will create dynamic rules matching
|
|
the exact parameters (addresses and ports) of the matching packet.
|
|
.Pp
|
|
These dynamic rules, which have a limited lifetime, are checked
|
|
at the first occurrence of a
|
|
.Cm check-state ,
|
|
.Cm keep-state
|
|
or
|
|
.Cm limit
|
|
rule, and are typically used to open the firewall on-demand to
|
|
legitimate traffic only.
|
|
See the
|
|
.Sx STATEFUL FIREWALL
|
|
and
|
|
.Sx EXAMPLES
|
|
Sections below for more information on the stateful behaviour of
|
|
.Nm .
|
|
.Pp
|
|
All rules (including dynamic ones) have a few associated counters:
|
|
a packet count, a byte count, a log count and a timestamp
|
|
indicating the time of the last match.
|
|
Counters can be displayed or reset with
|
|
.Nm
|
|
commands.
|
|
.Pp
|
|
Rules can be added with the
|
|
.Cm add
|
|
command; deleted individually or in groups with the
|
|
.Cm delete
|
|
command, and globally (except those in set 31) with the
|
|
.Cm flush
|
|
command; displayed, optionally with the content of the
|
|
counters, using the
|
|
.Cm show
|
|
and
|
|
.Cm list
|
|
commands.
|
|
Finally, counters can be reset with the
|
|
.Cm zero
|
|
and
|
|
.Cm resetlog
|
|
commands.
|
|
.Pp
|
|
Also, each rule belongs to one of 32 different
|
|
.Em sets
|
|
, and there are
|
|
.Nm
|
|
commands to atomically manipulate sets, such as enable,
|
|
disable, swap sets, move all rules in a set to another
|
|
one, delete all rules in a set. These can be useful to
|
|
install temporary configurations, or to test them.
|
|
See Section
|
|
.Sx SETS OF RULES
|
|
for more information on
|
|
.Em sets .
|
|
.Pp
|
|
The following options are available:
|
|
.Bl -tag -width indent
|
|
.It Fl a
|
|
While listing, show counter values.
|
|
The
|
|
.Cm show
|
|
command just implies this option.
|
|
.It Fl c
|
|
When entering or showing rules, print them in compact form,
|
|
i.e. without the optional "ip from any to any" string
|
|
when this does not carry any additional information.
|
|
.It Fl d
|
|
While listing, show dynamic rules in addition to static ones.
|
|
.It Fl e
|
|
While listing, if the
|
|
.Fl d
|
|
option was specified, also show expired dynamic rules.
|
|
.It Fl f
|
|
Don't ask for confirmation for commands that can cause problems
|
|
if misused,
|
|
.No i.e. Cm flush .
|
|
If there is no tty associated with the process, this is implied.
|
|
.It Fl n
|
|
Only check syntax of the command strings, without actually passing
|
|
them to the kernel.
|
|
.It Fl N
|
|
Try to resolve addresses and service names in output.
|
|
.It Fl q
|
|
While
|
|
.Cm add Ns ing ,
|
|
.Cm zero Ns ing ,
|
|
.Cm resetlog Ns ging
|
|
or
|
|
.Cm flush Ns ing ,
|
|
be quiet about actions
|
|
(implies
|
|
.Fl f ) .
|
|
This is useful for adjusting rules by executing multiple
|
|
.Nm
|
|
commands in a script
|
|
(e.g.,
|
|
.Ql sh\ /etc/rc.firewall ) ,
|
|
or by processing a file of many
|
|
.Nm
|
|
rules across a remote login session.
|
|
If a
|
|
.Cm flush
|
|
is performed in normal (verbose) mode (with the default kernel
|
|
configuration), it prints a message.
|
|
Because all rules are flushed, the message might not be delivered
|
|
to the login session, causing the remote login session to be closed
|
|
and the remainder of the ruleset to not be processed.
|
|
Access to the console would then be required to recover.
|
|
.It Fl S
|
|
While listing rules, show the
|
|
.Em set
|
|
each rule belongs to.
|
|
If this flag is not specified, disabled rules will not be
|
|
listed.
|
|
.It Fl s Op Ar field
|
|
While listing pipes, sort according to one of the four
|
|
counters (total or current packets or bytes).
|
|
.It Fl t
|
|
While listing, show last match timestamp (converted with ctime()).
|
|
.It Fl T
|
|
While listing, show last match timestamp (as seconds from the epoch).
|
|
This form can be more convenient for postprocessing by scripts.
|
|
.El
|
|
.Pp
|
|
To ease configuration, rules can be put into a file which is
|
|
processed using
|
|
.Nm
|
|
as shown in the last synopsis line.
|
|
An absolute
|
|
.Ar pathname
|
|
must be used.
|
|
The file will be read line by line and applied as arguments to the
|
|
.Nm
|
|
utility.
|
|
.Pp
|
|
Optionally, a preprocessor can be specified using
|
|
.Fl p Ar preproc
|
|
where
|
|
.Ar pathname
|
|
is to be piped through.
|
|
Useful preprocessors include
|
|
.Xr cpp 1
|
|
and
|
|
.Xr m4 1 .
|
|
If
|
|
.Ar preproc
|
|
doesn't start with a slash
|
|
.Pq Ql /
|
|
as its first character, the usual
|
|
.Ev PATH
|
|
name search is performed.
|
|
Care should be taken with this in environments where not all
|
|
file systems are mounted (yet) by the time
|
|
.Nm
|
|
is being run (e.g. when they are mounted over NFS).
|
|
Once
|
|
.Fl p
|
|
has been specified, any additional arguments as passed on to the preprocessor
|
|
for interpretation.
|
|
This allows for flexible configuration files (like conditionalizing
|
|
them on the local hostname) and the use of macros to centralize
|
|
frequently required arguments like IP addresses.
|
|
.Pp
|
|
The
|
|
.Nm
|
|
.Cm pipe
|
|
and
|
|
.Cm queue
|
|
commands are used to configure the traffic shaper, as shown in the
|
|
.Sx TRAFFIC SHAPER (DUMMYNET) CONFIGURATION
|
|
Section below.
|
|
.Pp
|
|
If the world and the kernel get out of sync the
|
|
.Nm
|
|
ABI may break, preventing you from being able to add any rules. This can
|
|
adversely effect the booting process. You can use
|
|
.Nm
|
|
.Cm disable
|
|
.Cm firewall
|
|
to temporarily disable the firewall to regain access to the network,
|
|
allowing you to fix the problem.
|
|
.Sh PACKET FLOW
|
|
A packet is checked against the active ruleset in multiple places
|
|
in the protocol stack, under control of several sysctl variables.
|
|
These places and variables are shown below, and it is important to
|
|
have this picture in mind in order to design a correct ruleset.
|
|
.Bd -literal -offset indent
|
|
^ to upper layers V
|
|
| |
|
|
+----------->-----------+
|
|
^ V
|
|
[ip_input] [ip_output] net.inet.ip.fw.enable=1
|
|
| |
|
|
^ V
|
|
[ether_demux] [ether_output_frame] net.link.ether.ipfw=1
|
|
| |
|
|
+-->--[bdg_forward]-->--+ net.link.ether.bridge_ipfw=1
|
|
^ V
|
|
| to devices |
|
|
.Ed
|
|
.Pp
|
|
As can be noted from the above picture, the number of
|
|
times the same packet goes through the firewall can
|
|
vary between 0 and 4 depending on packet source and
|
|
destination, and system configuration.
|
|
.Pp
|
|
Note that as packets flow through the stack, headers can be
|
|
stripped or added to it, and so they may or may not be available
|
|
for inspection.
|
|
E.g., incoming packets will include the MAC header when
|
|
.Nm
|
|
is invoked from
|
|
.Cm ether_demux() ,
|
|
but the same packets will have the MAC header stripped off when
|
|
.Nm
|
|
is invoked from
|
|
.Cm ip_input() .
|
|
.Pp
|
|
Also note that each packet is always checked against the complete ruleset,
|
|
irrespective of the place where the check occurs, or the source of the packet.
|
|
If a rule contains some match patterns or actions which are not valid
|
|
for the place of invocation (e.g. trying to match a MAC header within
|
|
.Cm ip_input()
|
|
), the match pattern will not match, but a
|
|
.Cm not
|
|
operator in front of such patterns
|
|
.Em will
|
|
cause the pattern to
|
|
.Em always
|
|
match on those packets.
|
|
It is thus the responsibility of
|
|
the programmer, if necessary, to write a suitable ruleset to
|
|
differentiate among the possible places.
|
|
.Cm skipto
|
|
rules can be useful here, as an example:
|
|
.Bd -literal -offset indent
|
|
# packets from ether_demux or bdg_forward
|
|
ipfw add 10 skipto 1000 all from any to any layer2 in
|
|
# packets from ip_input
|
|
ipfw add 10 skipto 2000 all from any to any not layer2 in
|
|
# packets from ip_output
|
|
ipfw add 10 skipto 3000 all from any to any not layer2 out
|
|
# packets from ether_output_frame
|
|
ipfw add 10 skipto 4000 all from any to any layer2 out
|
|
.Ed
|
|
.Pp
|
|
(yes, at the moment there is no way to differentiate between
|
|
ether_demux and bdg_forward).
|
|
.Sh SYNTAX
|
|
In general, each keyword or argument must be provided as
|
|
a separate command line argument, with no leading or trailing
|
|
spaces. Keywords are case-sensitive, whereas arguments may
|
|
or may not be case-sensitive depending on their nature
|
|
(e.g. uid's are, hostnames are not).
|
|
.Pp
|
|
In
|
|
.Nm ipfw2
|
|
you can introduce spaces after commas ',' to make
|
|
the line more readable. You can also put the entire
|
|
command (including flags) into a single argument.
|
|
E.g. the following forms are equivalent:
|
|
.Bd -literal -offset indent
|
|
ipfw -q add deny src-ip 10.0.0.0/24,127.0.0.1/8
|
|
ipfw -q add deny src-ip 10.0.0.0/24, 127.0.0.1/8
|
|
ipfw "-q add deny src-ip 10.0.0.0/24, 127.0.0.1/8"
|
|
.Ed
|
|
.Sh RULE FORMAT
|
|
The format of
|
|
.Nm
|
|
rules is the following:
|
|
.Bd -ragged -offset indent
|
|
.Op Ar rule_number
|
|
.Op Cm set Ar set_number
|
|
.Op Cm prob Ar match_probability
|
|
.br
|
|
.Ar " " action
|
|
.Op Cm log Op Cm logamount Ar number
|
|
.Ar body
|
|
.Ed
|
|
.Pp
|
|
where the body of the rule specifies which information is used
|
|
for filtering packets, among the following:
|
|
.Pp
|
|
.Bl -tag -width "Source and dest. addresses and ports" -offset XXX -compact
|
|
.It Layer-2 header fields
|
|
When available
|
|
.It IPv4 Protocol
|
|
TCP, UDP, ICMP, etc.
|
|
.It Source and dest. addresses and ports
|
|
.It Direction
|
|
See Section
|
|
.Sx PACKET FLOW
|
|
.It Transmit and receive interface
|
|
By name or address
|
|
.It Misc. IP header fields
|
|
Version, type of service, datagram length, identification,
|
|
fragment flag (non-zero IP offset),
|
|
Time To Live
|
|
.It IP options
|
|
.It Misc. TCP header fields
|
|
TCP flags (SYN, FIN, ACK, RST, etc.),
|
|
sequence number, acknowledgment number,
|
|
window
|
|
.It TCP options
|
|
.It ICMP types
|
|
for ICMP packets
|
|
.It User/group ID
|
|
When the packet can be associated with a local socket.
|
|
.El
|
|
.Pp
|
|
Note that some of the above information, e.g. source MAC or IP addresses and
|
|
TCP/UDP ports, could easily be spoofed, so filtering on those fields
|
|
alone might not guarantee the desired results.
|
|
.Bl -tag -width indent
|
|
.It Ar rule_number
|
|
Each rule is associated with a
|
|
.Ar rule_number
|
|
in the range 1..65535, with the latter reserved for the
|
|
.Em default
|
|
rule.
|
|
Rules are checked sequentially by rule number.
|
|
Multiple rules can have the same number, in which case they are
|
|
checked (and listed) according to the order in which they have
|
|
been added.
|
|
If a rule is entered without specifying a number, the kernel will
|
|
assign one in such a way that the rule becomes the last one
|
|
before the
|
|
.Em default
|
|
rule.
|
|
Automatic rule numbers are assigned by incrementing the last
|
|
non-default rule number by the value of the sysctl variable
|
|
.Ar net.inet.ip.fw.autoinc_step
|
|
which defaults to 100.
|
|
If this is not possible (e.g. because we would go beyond the
|
|
maximum allowed rule number), the number of the last
|
|
non-default value is used instead.
|
|
.It Cm set Ar set_number
|
|
Each rule is associated with a
|
|
.Ar set_number
|
|
in the range 0..31.
|
|
Sets can be individually disabled and enabled, so this parameter
|
|
is of fundamental importance for atomic ruleset manipulation.
|
|
It can be also used to simplify deletion of groups of rules.
|
|
If a rule is entered without specifying a set number,
|
|
set 0 will be used.
|
|
.br
|
|
Set 31 is special in that it cannot be disabled,
|
|
and rules in set 31 are not deleted by the
|
|
.Nm ipfw flush
|
|
command (but you can delete them with the
|
|
.Nm ipfw delete set 31
|
|
command).
|
|
Set 31 is also used for the
|
|
.Em default
|
|
rule.
|
|
.It Cm prob Ar match_probability
|
|
A match is only declared with the specified probability
|
|
(floating point number between 0 and 1).
|
|
This can be useful for a number of applications such as
|
|
random packet drop or
|
|
(in conjunction with
|
|
.Xr dummynet 4 )
|
|
to simulate the effect of multiple paths leading to out-of-order
|
|
packet delivery.
|
|
.Pp
|
|
Note: this condition is checked before any other condition, including
|
|
ones such as keep-state or check-state which might have side effects.
|
|
.It Cm log Op Cm logamount Ar number
|
|
When a packet matches a rule with the
|
|
.Cm log
|
|
keyword, a message will be
|
|
logged to
|
|
.Xr syslogd 8
|
|
with a
|
|
.Dv LOG_SECURITY
|
|
facility.
|
|
The logging only occurs if the sysctl variable
|
|
.Em net.inet.ip.fw.verbose
|
|
is set to 1
|
|
(which is the default when the kernel is compiled with
|
|
.Dv IPFIREWALL_VERBOSE
|
|
) and the number of packets logged so far for that
|
|
particular rule does not exceed the
|
|
.Cm logamount
|
|
parameter.
|
|
If no
|
|
.Cm logamount
|
|
is specified, the limit is taken from the sysctl variable
|
|
.Em net.inet.ip.fw.verbose_limit .
|
|
In both cases, a value of 0 removes the logging limit.
|
|
.Pp
|
|
Once the limit is reached, logging can be re-enabled by
|
|
clearing the logging counter or the packet counter for that entry, see the
|
|
.Cm resetlog
|
|
command.
|
|
.Pp
|
|
Note: logging is done after all other packet matching conditions
|
|
have been successfully verified, and before performing the final
|
|
action (accept, deny, etc.) on the packet.
|
|
.El
|
|
.Ss RULE ACTIONS
|
|
A rule can be associated with one of the following actions, which
|
|
will be executed when the packet matches the body of the rule.
|
|
.Bl -tag -width indent
|
|
.It Cm allow | accept | pass | permit
|
|
Allow packets that match rule.
|
|
The search terminates.
|
|
.It Cm check-state
|
|
Checks the packet against the dynamic ruleset.
|
|
If a match is found, execute the action associated with
|
|
the rule which generated this dynamic rule, otherwise
|
|
move to the next rule.
|
|
.br
|
|
.Cm Check-state
|
|
rules do not have a body.
|
|
If no
|
|
.Cm check-state
|
|
rule is found, the dynamic ruleset is checked at the first
|
|
.Cm keep-state
|
|
or
|
|
.Cm limit
|
|
rule.
|
|
.It Cm count
|
|
Update counters for all packets that match rule.
|
|
The search continues with the next rule.
|
|
.It Cm deny | drop
|
|
Discard packets that match this rule.
|
|
The search terminates.
|
|
.It Cm divert Ar port
|
|
Divert packets that match this rule to the
|
|
.Xr divert 4
|
|
socket bound to port
|
|
.Ar port .
|
|
The search terminates.
|
|
.It Cm fwd | forward Ar ipaddr Ns Op , Ns Ar port
|
|
Change the next-hop on matching packets to
|
|
.Ar ipaddr ,
|
|
which can be an IP address in dotted quad format or a host name.
|
|
The search terminates if this rule matches.
|
|
.Pp
|
|
If
|
|
.Ar ipaddr
|
|
is a local address, then matching packets will be forwarded to
|
|
.Ar port
|
|
(or the port number in the packet if one is not specified in the rule)
|
|
on the local machine.
|
|
.br
|
|
If
|
|
.Ar ipaddr
|
|
is not a local address, then the port number
|
|
(if specified) is ignored, and the packet will be
|
|
forwarded to the remote address, using the route as found in
|
|
the local routing table for that IP.
|
|
.br
|
|
A
|
|
.Ar fwd
|
|
rule will not match layer-2 packets (those received
|
|
on ether_input, ether_output, or bridged).
|
|
.br
|
|
The
|
|
.Cm fwd
|
|
action does not change the contents of the packet at all.
|
|
In particular, the destination address remains unmodified, so
|
|
packets forwarded to another system will usually be rejected by that system
|
|
unless there is a matching rule on that system to capture them.
|
|
For packets forwarded locally,
|
|
the local address of the socket will be
|
|
set to the original destination address of the packet.
|
|
This makes the
|
|
.Xr netstat 1
|
|
entry look rather weird but is intended for
|
|
use with transparent proxy servers.
|
|
.It Cm pipe Ar pipe_nr
|
|
Pass packet to a
|
|
.Xr dummynet 4
|
|
.Dq pipe
|
|
(for bandwidth limitation, delay, etc.).
|
|
See the
|
|
.Sx TRAFFIC SHAPER (DUMMYNET) CONFIGURATION
|
|
Section for further information.
|
|
The search terminates; however, on exit from the pipe and if
|
|
the
|
|
.Xr sysctl 8
|
|
variable
|
|
.Em net.inet.ip.fw.one_pass
|
|
is not set, the packet is passed again to the firewall code
|
|
starting from the next rule.
|
|
.It Cm queue Ar queue_nr
|
|
Pass packet to a
|
|
.Xr dummynet 4
|
|
.Dq queue
|
|
(for bandwidth limitation using WF2Q+).
|
|
.It Cm reject
|
|
(Deprecated).
|
|
Synonym for
|
|
.Cm unreach host .
|
|
.It Cm reset
|
|
Discard packets that match this rule, and if the
|
|
packet is a TCP packet, try to send a TCP reset (RST) notice.
|
|
The search terminates.
|
|
.It Cm skipto Ar number
|
|
Skip all subsequent rules numbered less than
|
|
.Ar number .
|
|
The search continues with the first rule numbered
|
|
.Ar number
|
|
or higher.
|
|
.It Cm tee Ar port
|
|
Send a copy of packets matching this rule to the
|
|
.Xr divert 4
|
|
socket bound to port
|
|
.Ar port .
|
|
The search terminates and the original packet is accepted
|
|
(but see Section
|
|
.Sx BUGS
|
|
below).
|
|
.It Cm unreach Ar code
|
|
Discard packets that match this rule, and try to send an ICMP
|
|
unreachable notice with code
|
|
.Ar code ,
|
|
where
|
|
.Ar code
|
|
is a number from 0 to 255, or one of these aliases:
|
|
.Cm net , host , protocol , port ,
|
|
.Cm needfrag , srcfail , net-unknown , host-unknown ,
|
|
.Cm isolated , net-prohib , host-prohib , tosnet ,
|
|
.Cm toshost , filter-prohib , host-precedence
|
|
or
|
|
.Cm precedence-cutoff .
|
|
The search terminates.
|
|
.El
|
|
.Ss RULE BODY
|
|
The body of a rule contains zero or more patterns (such as
|
|
specific source and destination addresses or ports,
|
|
protocol options, incoming or outgoing interfaces, etc.)
|
|
that the packet must match in order to be recognised.
|
|
In general, the patterns are connected by (implicit)
|
|
.Cm and
|
|
operators -- i.e. all must match in order for the
|
|
rule to match.
|
|
Individual patterns can be prefixed by the
|
|
.Cm not
|
|
operator to reverse the result of the match, as in
|
|
.Pp
|
|
.Dl "ipfw add 100 allow ip from not 1.2.3.4 to any"
|
|
.Pp
|
|
Additionally, sets of alternative match patterns (
|
|
.Em or-blocks
|
|
) can be constructed by putting the patterns in
|
|
lists enclosed between parentheses ( ) or braces { }, and
|
|
using the
|
|
.Cm or
|
|
operator as follows:
|
|
.Pp
|
|
.Dl "ipfw add 100 allow ip from { x or not y or z } to any"
|
|
.Pp
|
|
Only one level of parentheses is allowed.
|
|
Beware that most shells have special meanings for parentheses
|
|
or braces, so it is advisable to put a backslash \\ in front of them
|
|
to prevent such interpretations.
|
|
.Pp
|
|
The body of a rule must in general include a source and destination
|
|
address specifier.
|
|
The keyword
|
|
.Ar any
|
|
can be used in various places to specify that the content of
|
|
a required field is irrelevant.
|
|
.Pp
|
|
The rule body has the following format:
|
|
.Bd -ragged -offset indent
|
|
.Op Ar proto Cm from Ar src Cm to Ar dst
|
|
.Op Ar options
|
|
.Ed
|
|
.Pp
|
|
The first part (proto from src to dst) is for backward
|
|
compatibility with
|
|
.Nm ipfw1 .
|
|
In
|
|
.Nm ipfw2
|
|
any match pattern (including MAC headers, IPv4 protocols,
|
|
addresses and ports) can be specified in the
|
|
.Ar options
|
|
section.
|
|
.Pp
|
|
Rule fields have the following meaning:
|
|
.Bl -tag -width indent
|
|
.It Ar proto : protocol | Cm { Ar protocol Cm or ... }
|
|
.It Ar protocol : Oo Cm not Oc Ar protocol-name | protocol-number
|
|
An IPv4 protocol specified by number or name
|
|
(for a complete list see
|
|
.Pa /etc/protocols ) .
|
|
The
|
|
.Cm ip
|
|
or
|
|
.Cm all
|
|
keywords mean any protocol will match.
|
|
.Pp
|
|
The
|
|
.Cm { Ar protocol Cm or ... }
|
|
format (an
|
|
.Em or-block )
|
|
is provided for convenience only but its use is deprecated.
|
|
.It Ar src No and Ar dst : Bro Cm addr | Cm { Ar addr Cm or ... } Brc Op Oo Cm not Oc Ar ports
|
|
An address (or a list, see below)
|
|
optionally followed by
|
|
.Ar ports
|
|
specifiers.
|
|
.Pp
|
|
The second format (
|
|
.Em or-block
|
|
with multiple addresses) is provided for convenience only and
|
|
its use is discouraged.
|
|
.It Ar addr : Oo Cm not Oc Brq Cm any | me | Ar addr-list | Ar addr-set
|
|
.It Cm any
|
|
matches any IP address.
|
|
.It Cm me
|
|
matches any IP address configured on an interface in the system.
|
|
The address list is evaluated at the time the packet is
|
|
analysed.
|
|
.It Ar addr-list : ip-addr Ns Op Ns , Ns Ar addr-list
|
|
.It Ar ip-addr :
|
|
A host or subnet address specified in one of the following ways:
|
|
.Bl -tag -width indent
|
|
.It Ar numeric-ip | hostname
|
|
Matches a single IPv4 address, specified as dotted-quad or a hostname.
|
|
Hostnames are resolved at the time the rule is added to the firewall list.
|
|
.It Ar addr Ns / Ns Ar masklen
|
|
Matches all addresses with base
|
|
.Ar addr
|
|
(specified as a dotted quad or a hostname)
|
|
and mask width of
|
|
.Cm masklen
|
|
bits.
|
|
As an example, 1.2.3.4/25 will match
|
|
all IP numbers from 1.2.3.0 to 1.2.3.127 .
|
|
.It Ar addr Ns : Ns Ar mask
|
|
Matches all addresses with base
|
|
.Ar addr
|
|
(specified as a dotted quad or a hostname)
|
|
and the mask of
|
|
.Ar mask ,
|
|
specified as a dotted quad.
|
|
As an example, 1.2.3.4/255.0.255.0 will match
|
|
1.*.3.*.
|
|
We suggest to use this form only for non-contiguous
|
|
masks, and resort to the
|
|
.Ar addr Ns / Ns Ar masklen
|
|
format for contiguous masks, which is more compact and less
|
|
error-prone.
|
|
.El
|
|
.It Ar addr-set : addr Ns Oo Ns / Ns Ar masklen Oc Ns Cm { Ns Ar list Ns Cm }
|
|
.It Ar list : Bro Ar num | num-num Brc Ns Op Ns , Ns Ar list
|
|
Matches all addresses with base address
|
|
.Ar addr
|
|
(specified as a dotted quad or a hostname)
|
|
and whose last byte is in the list between braces { } .
|
|
Note that there must be no spaces between braces and
|
|
numbers (spaces after commas are allowed).
|
|
Elements of the list can be specified as single entries
|
|
or ranges.
|
|
The
|
|
.Ar masklen
|
|
field is used to limit the size of the set of addresses,
|
|
and can have any value between 24 and 32. If not specified,
|
|
it will be assumed as 24.
|
|
.br
|
|
This format is particularly useful to handle sparse address sets
|
|
within a single rule. Because the matching occurs using a
|
|
bitmask, it takes constant time and dramatically reduces
|
|
the complexity of rulesets.
|
|
.br
|
|
As an example, an address specified as 1.2.3.4/24{128,35-55,89}
|
|
will match the following IP addresses:
|
|
.br
|
|
1.2.3.128, 1.2.3.35 to 1.2.3.55, 1.2.3.89 .
|
|
.It Ar ports : Bro Ar port | port Ns \&- Ns Ar port Ns Brc Ns Op , Ns Ar ports
|
|
For protocols which support port numbers (such as TCP and UDP), optional
|
|
.Cm ports
|
|
may be specified as one or more ports or port ranges, separated
|
|
by commas but no spaces, and an optional
|
|
.Cm not
|
|
operator.
|
|
The
|
|
.Ql \&-
|
|
notation specifies a range of ports (including boundaries).
|
|
.Pp
|
|
Service names (from
|
|
.Pa /etc/services )
|
|
may be used instead of numeric port values.
|
|
The length of the port list is limited to 30 ports or ranges,
|
|
though one can specify larger ranges by using an
|
|
.Em or-block
|
|
in the
|
|
.Cm options
|
|
section of the rule.
|
|
.Pp
|
|
A backslash
|
|
.Pq Ql \e
|
|
can be used to escape the dash
|
|
.Pq Ql -
|
|
character in a service name (from a shell, the backslash must be
|
|
typed twice to avoid the shell itself interpreting it as an escape
|
|
character).
|
|
.Pp
|
|
.Dl "ipfw add count tcp from any ftp\e\e-data-ftp to any"
|
|
.Pp
|
|
Fragmented packets which have a non-zero offset (i.e. not the first
|
|
fragment) will never match a rule which has one or more port
|
|
specifications.
|
|
See the
|
|
.Cm frag
|
|
option for details on matching fragmented packets.
|
|
.El
|
|
.Ss RULE OPTIONS (MATCH PATTERNS)
|
|
Additional match patterns can be used within
|
|
rules. Zero or more of these so-called
|
|
.Em options
|
|
can be present in a rule, optionally prefixed by the
|
|
.Cm not
|
|
operand, and possibly grouped into
|
|
.Em or-blocks .
|
|
.Pp
|
|
The following match patterns can be used (listed in alphabetical order):
|
|
.Bl -tag -width indent
|
|
.It Cm // this is a comment.
|
|
Inserts the specified text as a comment in the rule.
|
|
Everything following // is considered as a comment and stored in the rule.
|
|
You can have comment-only rules, which are listed as having a
|
|
.Cm count
|
|
action followed by the comment.
|
|
.It Cm bridged
|
|
Matches only bridged packets.
|
|
.It Cm dst-ip Ar ip-address
|
|
Matches IP packets whose destination IP is one of the address(es)
|
|
specified as argument.
|
|
.It Cm dst-port Ar ports
|
|
Matches IP packets whose destination port is one of the port(s)
|
|
specified as argument.
|
|
.It Cm established
|
|
Matches TCP packets that have the RST or ACK bits set.
|
|
.It Cm frag
|
|
Matches packets that are fragments and not the first
|
|
fragment of an IP datagram. Note that these packets will not have
|
|
the next protocol header (e.g. TCP, UDP) so options that look into
|
|
these headers cannot match.
|
|
.It Cm gid Ar group
|
|
Matches all TCP or UDP packets sent by or received for a
|
|
.Ar group .
|
|
A
|
|
.Ar group
|
|
may be specified by name or number.
|
|
.It Cm icmptypes Ar types
|
|
Matches ICMP packets whose ICMP type is in the list
|
|
.Ar types .
|
|
The list may be specified as any combination of
|
|
individual types (numeric) separated by commas.
|
|
.Em Ranges are not allowed.
|
|
The supported ICMP types are:
|
|
.Pp
|
|
echo reply
|
|
.Pq Cm 0 ,
|
|
destination unreachable
|
|
.Pq Cm 3 ,
|
|
source quench
|
|
.Pq Cm 4 ,
|
|
redirect
|
|
.Pq Cm 5 ,
|
|
echo request
|
|
.Pq Cm 8 ,
|
|
router advertisement
|
|
.Pq Cm 9 ,
|
|
router solicitation
|
|
.Pq Cm 10 ,
|
|
time-to-live exceeded
|
|
.Pq Cm 11 ,
|
|
IP header bad
|
|
.Pq Cm 12 ,
|
|
timestamp request
|
|
.Pq Cm 13 ,
|
|
timestamp reply
|
|
.Pq Cm 14 ,
|
|
information request
|
|
.Pq Cm 15 ,
|
|
information reply
|
|
.Pq Cm 16 ,
|
|
address mask request
|
|
.Pq Cm 17
|
|
and address mask reply
|
|
.Pq Cm 18 .
|
|
.It Cm in | out
|
|
Matches incoming or outgoing packets, respectively.
|
|
.Cm in
|
|
and
|
|
.Cm out
|
|
are mutually exclusive (in fact,
|
|
.Cm out
|
|
is implemented as
|
|
.Cm not in Ns No ).
|
|
.It Cm ipid Ar id-list
|
|
Matches IP packets whose
|
|
.Cm ip_id
|
|
field has value included in
|
|
.Ar id-list ,
|
|
which is either a single value or a list of values or ranges
|
|
specified in the same way as
|
|
.Ar ports .
|
|
.It Cm iplen Ar len-list
|
|
Matches IP packets whose total length, including header and data, is
|
|
in the set
|
|
.Ar len-list ,
|
|
which is either a single value or a list of values or ranges
|
|
specified in the same way as
|
|
.Ar ports .
|
|
.It Cm ipoptions Ar spec
|
|
Matches packets whose IP header contains the comma separated list of
|
|
options specified in
|
|
.Ar spec .
|
|
The supported IP options are:
|
|
.Pp
|
|
.Cm ssrr
|
|
(strict source route),
|
|
.Cm lsrr
|
|
(loose source route),
|
|
.Cm rr
|
|
(record packet route) and
|
|
.Cm ts
|
|
(timestamp).
|
|
The absence of a particular option may be denoted
|
|
with a
|
|
.Ql \&! .
|
|
.It Cm ipprecedence Ar precedence
|
|
Matches IP packets whose precedence field is equal to
|
|
.Ar precedence .
|
|
.It Cm ipsec
|
|
Matches packets that have IPSEC history associated with them
|
|
(i.e. the packet comes encapsulated in IPSEC, the kernel
|
|
has IPSEC support and IPSEC_FILTERGIF option, and can correctly
|
|
decapsulate it).
|
|
.Pp
|
|
Note that specifying
|
|
.Cm ipsec
|
|
is different from specifying
|
|
.Cm proto Ar ipsec
|
|
as the latter will only look at the specific IP protocol field,
|
|
irrespective of IPSEC kernel support and the validity of the IPSEC data.
|
|
.It Cm iptos Ar spec
|
|
Matches IP packets whose
|
|
.Cm tos
|
|
field contains the comma separated list of
|
|
service types specified in
|
|
.Ar spec .
|
|
The supported IP types of service are:
|
|
.Pp
|
|
.Cm lowdelay
|
|
.Pq Dv IPTOS_LOWDELAY ,
|
|
.Cm throughput
|
|
.Pq Dv IPTOS_THROUGHPUT ,
|
|
.Cm reliability
|
|
.Pq Dv IPTOS_RELIABILITY ,
|
|
.Cm mincost
|
|
.Pq Dv IPTOS_MINCOST ,
|
|
.Cm congestion
|
|
.Pq Dv IPTOS_CE .
|
|
The absence of a particular type may be denoted
|
|
with a
|
|
.Ql \&! .
|
|
.It Cm ipttl Ar ttl-list
|
|
Matches IP packets whose time to live is included in
|
|
.Ar ttl-list ,
|
|
which is either a single value or a list of values or ranges
|
|
specified in the same way as
|
|
.Ar ports .
|
|
.It Cm ipversion Ar ver
|
|
Matches IP packets whose IP version field is
|
|
.Ar ver .
|
|
.It Cm keep-state
|
|
Upon a match, the firewall will create a dynamic rule, whose
|
|
default behaviour is to match bidirectional traffic between
|
|
source and destination IP/port using the same protocol.
|
|
The rule has a limited lifetime (controlled by a set of
|
|
.Xr sysctl 8
|
|
variables), and the lifetime is refreshed every time a matching
|
|
packet is found.
|
|
.It Cm layer2
|
|
Matches only layer2 packets, i.e. those passed to
|
|
.Nm
|
|
from ether_demux() and ether_output_frame().
|
|
.It Cm limit Bro Cm src-addr | src-port | dst-addr | dst-port Brc Ar N
|
|
The firewall will only allow
|
|
.Ar N
|
|
connections with the same
|
|
set of parameters as specified in the rule.
|
|
One or more
|
|
of source and destination addresses and ports can be
|
|
specified.
|
|
.It Cm { MAC | mac } Ar dst-mac src-mac
|
|
Match packets with a given
|
|
.Ar dst-mac
|
|
and
|
|
.Ar src-mac
|
|
addresses, specified as the
|
|
.Cm any
|
|
keyword (matching any MAC address), or six groups of hex digits
|
|
separated by colons,
|
|
and optionally followed by a mask indicating how many bits are
|
|
significant, as in
|
|
.Pp
|
|
.Dl "MAC 10:20:30:40:50:60/33 any"
|
|
.Pp
|
|
Note that the order of MAC addresses (destination first,
|
|
source second) is
|
|
the same as on the wire, but the opposite of the one used for
|
|
IP addresses.
|
|
.It Cm mac-type Ar mac-type
|
|
Matches packets whose Ethernet Type field
|
|
corresponds to one of those specified as argument.
|
|
.Ar mac-type
|
|
is specified in the same way as
|
|
.Cm port numbers
|
|
(i.e. one or more comma-separated single values or ranges).
|
|
You can use symbolic names for known values such as
|
|
.Em vlan , ipv4, ipv6 .
|
|
Values can be entered as decimal or hexadecimal (if prefixed by 0x),
|
|
and they are always printed as hexadecimal (unless the
|
|
.Cm -N
|
|
option is used, in which case symbolic resolution will be attempted).
|
|
.It Cm proto Ar protocol
|
|
Matches packets with the corresponding IPv4 protocol.
|
|
.It Cm recv | xmit | via Brq Ar ifX | Ar if Ns Cm * | Ar ipno | Ar any
|
|
Matches packets received, transmitted or going through,
|
|
respectively, the interface specified by exact name
|
|
.Ns No ( Ar ifX Ns No ),
|
|
by device name
|
|
.Ns No ( Ar if Ns Ar * Ns No ),
|
|
by IP address, or through some interface.
|
|
.Pp
|
|
The
|
|
.Cm via
|
|
keyword causes the interface to always be checked.
|
|
If
|
|
.Cm recv
|
|
or
|
|
.Cm xmit
|
|
is used instead of
|
|
.Cm via ,
|
|
then only the receive or transmit interface (respectively)
|
|
is checked.
|
|
By specifying both, it is possible to match packets based on
|
|
both receive and transmit interface, e.g.:
|
|
.Pp
|
|
.Dl "ipfw add deny ip from any to any out recv ed0 xmit ed1"
|
|
.Pp
|
|
The
|
|
.Cm recv
|
|
interface can be tested on either incoming or outgoing packets,
|
|
while the
|
|
.Cm xmit
|
|
interface can only be tested on outgoing packets.
|
|
So
|
|
.Cm out
|
|
is required (and
|
|
.Cm in
|
|
is invalid) whenever
|
|
.Cm xmit
|
|
is used.
|
|
.Pp
|
|
A packet may not have a receive or transmit interface: packets
|
|
originating from the local host have no receive interface,
|
|
while packets destined for the local host have no transmit
|
|
interface.
|
|
.It Cm setup
|
|
Matches TCP packets that have the SYN bit set but no ACK bit.
|
|
This is the short form of
|
|
.Dq Li tcpflags\ syn,!ack .
|
|
.It Cm src-ip Ar ip-address
|
|
Matches IP packets whose source IP is one of the address(es)
|
|
specified as argument.
|
|
.It Cm src-port Ar ports
|
|
Matches IP packets whose source port is one of the port(s)
|
|
specified as argument.
|
|
.It Cm tcpack Ar ack
|
|
TCP packets only.
|
|
Match if the TCP header acknowledgment number field is set to
|
|
.Ar ack .
|
|
.It Cm tcpflags Ar spec
|
|
TCP packets only.
|
|
Match if the TCP header contains the comma separated list of
|
|
flags specified in
|
|
.Ar spec .
|
|
The supported TCP flags are:
|
|
.Pp
|
|
.Cm fin ,
|
|
.Cm syn ,
|
|
.Cm rst ,
|
|
.Cm psh ,
|
|
.Cm ack
|
|
and
|
|
.Cm urg .
|
|
The absence of a particular flag may be denoted
|
|
with a
|
|
.Ql \&! .
|
|
A rule which contains a
|
|
.Cm tcpflags
|
|
specification can never match a fragmented packet which has
|
|
a non-zero offset.
|
|
See the
|
|
.Cm frag
|
|
option for details on matching fragmented packets.
|
|
.It Cm tcpseq Ar seq
|
|
TCP packets only.
|
|
Match if the TCP header sequence number field is set to
|
|
.Ar seq .
|
|
.It Cm tcpwin Ar win
|
|
TCP packets only.
|
|
Match if the TCP header window field is set to
|
|
.Ar win .
|
|
.It Cm tcpoptions Ar spec
|
|
TCP packets only.
|
|
Match if the TCP header contains the comma separated list of
|
|
options specified in
|
|
.Ar spec .
|
|
The supported TCP options are:
|
|
.Pp
|
|
.Cm mss
|
|
(maximum segment size),
|
|
.Cm window
|
|
(tcp window advertisement),
|
|
.Cm sack
|
|
(selective ack),
|
|
.Cm ts
|
|
(rfc1323 timestamp) and
|
|
.Cm cc
|
|
(rfc1644 t/tcp connection count).
|
|
The absence of a particular option may be denoted
|
|
with a
|
|
.Ql \&! .
|
|
.It Cm uid Ar user
|
|
Match all TCP or UDP packets sent by or received for a
|
|
.Ar user .
|
|
A
|
|
.Ar user
|
|
may be matched by name or identification number.
|
|
.It Cm verrevpath
|
|
For incoming packets,
|
|
a routing table lookup is done on the packet's source address.
|
|
If the interface on which the packet entered the system matches the
|
|
outgoing interface for the route,
|
|
the packet matches.
|
|
If the interfaces do not match up,
|
|
the packet does not match.
|
|
All outgoing packets or packets with no incoming interface match.
|
|
.Pp
|
|
The name and functionality of the option is intentionally similar to
|
|
the Cisco IOS command:
|
|
.Pp
|
|
.Dl ip verify unicast reverse-path
|
|
.Pp
|
|
This option can be used to make anti-spoofing rules.
|
|
.El
|
|
.Sh SETS OF RULES
|
|
Each rule belongs to one of 32 different
|
|
.Em sets
|
|
, numbered 0 to 31.
|
|
Set 31 is reserved for the default rule.
|
|
.Pp
|
|
By default, rules are put in set 0, unless you use the
|
|
.Cm set N
|
|
attribute when entering a new rule.
|
|
Sets can be individually and atomically enabled or disabled,
|
|
so this mechanism permits an easy way to store multiple configurations
|
|
of the firewall and quickly (and atomically) switch between them.
|
|
The command to enable/disable sets is
|
|
.Bd -ragged -offset indent
|
|
.Nm
|
|
.Cm set Oo Cm disable Ar number ... Oc Op Cm enable Ar number ...
|
|
.Ed
|
|
.Pp
|
|
where multiple
|
|
.Cm enable
|
|
or
|
|
.Cm disable
|
|
sections can be specified.
|
|
Command execution is atomic on all the sets specified in the command.
|
|
By default, all sets are enabled.
|
|
.Pp
|
|
When you disable a set, its rules behave as if they do not exist
|
|
in the firewall configuration, with only one exception:
|
|
.Bd -ragged -offset indent
|
|
dynamic rules created from a rule before it had been disabled
|
|
will still be active until they expire. In order to delete
|
|
dynamic rules you have to explicitly delete the parent rule
|
|
which generated them.
|
|
.Ed
|
|
.Pp
|
|
The set number of rules can be changed with the command
|
|
.Bd -ragged -offset indent
|
|
.Nm
|
|
.Cm set move
|
|
.Brq Cm rule Ar rule-number | old-set
|
|
.Cm to Ar new-set
|
|
.Ed
|
|
.Pp
|
|
Also, you can atomically swap two rulesets with the command
|
|
.Bd -ragged -offset indent
|
|
.Nm
|
|
.Cm set swap Ar first-set second-set
|
|
.Ed
|
|
.Pp
|
|
See the
|
|
.Sx EXAMPLES
|
|
Section on some possible uses of sets of rules.
|
|
.Sh STATEFUL FIREWALL
|
|
Stateful operation is a way for the firewall to dynamically
|
|
create rules for specific flows when packets that
|
|
match a given pattern are detected. Support for stateful
|
|
operation comes through the
|
|
.Cm check-state , keep-state
|
|
and
|
|
.Cm limit
|
|
options of
|
|
.Nm rules.
|
|
.Pp
|
|
Dynamic rules are created when a packet matches a
|
|
.Cm keep-state
|
|
or
|
|
.Cm limit
|
|
rule, causing the creation of a
|
|
.Em dynamic
|
|
rule which will match all and only packets with
|
|
a given
|
|
.Em protocol
|
|
between a
|
|
.Em src-ip/src-port dst-ip/dst-port
|
|
pair of addresses (
|
|
.Em src
|
|
and
|
|
.Em dst
|
|
are used here only to denote the initial match addresses, but they
|
|
are completely equivalent afterwards).
|
|
Dynamic rules will be checked at the first
|
|
.Cm check-state, keep-state
|
|
or
|
|
.Cm limit
|
|
occurrence, and the action performed upon a match will be the same
|
|
as in the parent rule.
|
|
.Pp
|
|
Note that no additional attributes other than protocol and IP addresses
|
|
and ports are checked on dynamic rules.
|
|
.Pp
|
|
The typical use of dynamic rules is to keep a closed firewall configuration,
|
|
but let the first TCP SYN packet from the inside network install a
|
|
dynamic rule for the flow so that packets belonging to that session
|
|
will be allowed through the firewall:
|
|
.Pp
|
|
.Dl "ipfw add check-state"
|
|
.Dl "ipfw add allow tcp from my-subnet to any setup keep-state"
|
|
.Dl "ipfw add deny tcp from any to any"
|
|
.Pp
|
|
A similar approach can be used for UDP, where an UDP packet coming
|
|
from the inside will install a dynamic rule to let the response through
|
|
the firewall:
|
|
.Pp
|
|
.Dl "ipfw add check-state"
|
|
.Dl "ipfw add allow udp from my-subnet to any keep-state"
|
|
.Dl "ipfw add deny udp from any to any"
|
|
.Pp
|
|
Dynamic rules expire after some time, which depends on the status
|
|
of the flow and the setting of some
|
|
.Cm sysctl
|
|
variables.
|
|
See Section
|
|
.Sx SYSCTL VARIABLES
|
|
for more details.
|
|
For TCP sessions, dynamic rules can be instructed to periodically
|
|
send keepalive packets to refresh the state of the rule when it is
|
|
about to expire.
|
|
.Pp
|
|
See Section
|
|
.Sx EXAMPLES
|
|
for more examples on how to use dynamic rules.
|
|
.Sh TRAFFIC SHAPER (DUMMYNET) CONFIGURATION
|
|
.Nm
|
|
is also the user interface for the
|
|
.Xr dummynet 4
|
|
traffic shaper.
|
|
.Pp
|
|
.Nm dummynet
|
|
operates by first using the firewall to classify packets and divide them into
|
|
.Em flows ,
|
|
using any match pattern that can be used in
|
|
.Nm
|
|
rules.
|
|
Depending on local policies, a flow can contain packets for a single
|
|
TCP connection, or from/to a given host, or entire subnet, or a
|
|
protocol type, etc.
|
|
.Pp
|
|
Packets belonging to the same flow are then passed to either of two
|
|
different objects, which implement the traffic regulation:
|
|
.Bl -hang -offset XXXX
|
|
.It Em pipe
|
|
A pipe emulates a link with given bandwidth, propagation delay,
|
|
queue size and packet loss rate.
|
|
Packets are queued in front of the pipe as they come out from the classifier,
|
|
and then transferred to the pipe according to the pipe's parameters.
|
|
.Pp
|
|
.It Em queue
|
|
A queue
|
|
is an abstraction used to implement the WF2Q+
|
|
(Worst-case Fair Weighted Fair Queueing) policy, which is
|
|
an efficient variant of the WFQ policy.
|
|
.br
|
|
The queue associates a
|
|
.Em weight
|
|
and a reference pipe to each flow, and then all backlogged (i.e.,
|
|
with packets queued) flows linked to the same pipe share the pipe's
|
|
bandwidth proportionally to their weights.
|
|
Note that weights are not priorities; a flow with a lower weight
|
|
is still guaranteed to get its fraction of the bandwidth even if a
|
|
flow with a higher weight is permanently backlogged.
|
|
.Pp
|
|
.El
|
|
In practice,
|
|
.Em pipes
|
|
can be used to set hard limits to the bandwidth that a flow can use, whereas
|
|
.Em queues
|
|
can be used to determine how different flow share the available bandwidth.
|
|
.Pp
|
|
The
|
|
.Em pipe
|
|
and
|
|
.Em queue
|
|
configuration commands are the following:
|
|
.Bd -ragged -offset indent
|
|
.Cm pipe Ar number Cm config Ar pipe-configuration
|
|
.Pp
|
|
.Cm queue Ar number Cm config Ar queue-configuration
|
|
.Ed
|
|
.Pp
|
|
The following parameters can be configured for a pipe:
|
|
.Pp
|
|
.Bl -tag -width indent -compact
|
|
.It Cm bw Ar bandwidth | device
|
|
Bandwidth, measured in
|
|
.Sm off
|
|
.Op Cm K | M
|
|
.Brq Cm bit/s | Byte/s .
|
|
.Sm on
|
|
.Pp
|
|
A value of 0 (default) means unlimited bandwidth.
|
|
The unit must immediately follow the number, as in
|
|
.Pp
|
|
.Dl "ipfw pipe 1 config bw 300Kbit/s"
|
|
.Pp
|
|
If a device name is specified instead of a numeric value, as in
|
|
.Pp
|
|
.Dl "ipfw pipe 1 config bw tun0"
|
|
.Pp
|
|
then the transmit clock is supplied by the specified device.
|
|
At the moment only the
|
|
.Xr tun 4
|
|
device supports this
|
|
functionality, for use in conjunction with
|
|
.Xr ppp 8 .
|
|
.Pp
|
|
.It Cm delay Ar ms-delay
|
|
Propagation delay, measured in milliseconds.
|
|
The value is rounded to the next multiple of the clock tick
|
|
(typically 10ms, but it is a good practice to run kernels
|
|
with
|
|
.Dq "options HZ=1000"
|
|
to reduce
|
|
the granularity to 1ms or less).
|
|
Default value is 0, meaning no delay.
|
|
.El
|
|
.Pp
|
|
The following parameters can be configured for a queue:
|
|
.Pp
|
|
.Bl -tag -width indent -compact
|
|
.It Cm pipe Ar pipe_nr
|
|
Connects a queue to the specified pipe.
|
|
Multiple queues (with the same or different weights) can be connected to
|
|
the same pipe, which specifies the aggregate rate for the set of queues.
|
|
.Pp
|
|
.It Cm weight Ar weight
|
|
Specifies the weight to be used for flows matching this queue.
|
|
The weight must be in the range 1..100, and defaults to 1.
|
|
.El
|
|
.Pp
|
|
Finally, the following parameters can be configured for both
|
|
pipes and queues:
|
|
.Pp
|
|
.Bl -tag -width XXXX -compact
|
|
.Pp
|
|
.It Cm buckets Ar hash-table-size
|
|
Specifies the size of the hash table used for storing the
|
|
various queues.
|
|
Default value is 64 controlled by the
|
|
.Xr sysctl 8
|
|
variable
|
|
.Em net.inet.ip.dummynet.hash_size ,
|
|
allowed range is 16 to 65536.
|
|
.Pp
|
|
.It Cm mask Ar mask-specifier
|
|
Packets sent to a given pipe or queue by an
|
|
.Nm
|
|
rule can be further classified into multiple flows, each of which is then
|
|
sent to a different
|
|
.Em dynamic
|
|
pipe or queue.
|
|
A flow identifier is constructed by masking the IP addresses,
|
|
ports and protocol types as specified with the
|
|
.Cm mask
|
|
options in the configuration of the pipe or queue.
|
|
For each different flow identifier, a new pipe or queue is created
|
|
with the same parameters as the original object, and matching packets
|
|
are sent to it.
|
|
.Pp
|
|
Thus, when
|
|
.Em dynamic pipes
|
|
are used, each flow will get the same bandwidth as defined by the pipe,
|
|
whereas when
|
|
.Em dynamic queues
|
|
are used, each flow will share the parent's pipe bandwidth evenly
|
|
with other flows generated by the same queue (note that other queues
|
|
with different weights might be connected to the same pipe).
|
|
.br
|
|
Available mask specifiers are a combination of one or more of the following:
|
|
.Pp
|
|
.Cm dst-ip Ar mask ,
|
|
.Cm src-ip Ar mask ,
|
|
.Cm dst-port Ar mask ,
|
|
.Cm src-port Ar mask ,
|
|
.Cm proto Ar mask
|
|
or
|
|
.Cm all ,
|
|
.Pp
|
|
where the latter means all bits in all fields are significant.
|
|
.Pp
|
|
.It Cm noerror
|
|
When a packet is dropped by a dummynet queue or pipe, the error
|
|
is normally reported to the caller routine in the kernel, in the
|
|
same way as it happens when a device queue fills up. Setting this
|
|
option reports the packet as successfully delivered, which can be
|
|
needed for some experimental setups where you want to simulate
|
|
loss or congestion at a remote router.
|
|
.Pp
|
|
.It Cm plr Ar packet-loss-rate
|
|
Packet loss rate.
|
|
Argument
|
|
.Ar packet-loss-rate
|
|
is a floating-point number between 0 and 1, with 0 meaning no
|
|
loss, 1 meaning 100% loss.
|
|
The loss rate is internally represented on 31 bits.
|
|
.Pp
|
|
.It Cm queue Brq Ar slots | size Ns Cm Kbytes
|
|
Queue size, in
|
|
.Ar slots
|
|
or
|
|
.Cm KBytes .
|
|
Default value is 50 slots, which
|
|
is the typical queue size for Ethernet devices.
|
|
Note that for slow speed links you should keep the queue
|
|
size short or your traffic might be affected by a significant
|
|
queueing delay.
|
|
E.g., 50 max-sized ethernet packets (1500 bytes) mean 600Kbit
|
|
or 20s of queue on a 30Kbit/s pipe.
|
|
Even worse effect can result if you get packets from an
|
|
interface with a much larger MTU, e.g. the loopback interface
|
|
with its 16KB packets.
|
|
.Pp
|
|
.It Cm red | gred Ar w_q Ns / Ns Ar min_th Ns / Ns Ar max_th Ns / Ns Ar max_p
|
|
Make use of the RED (Random Early Detection) queue management algorithm.
|
|
.Ar w_q
|
|
and
|
|
.Ar max_p
|
|
are floating
|
|
point numbers between 0 and 1 (0 not included), while
|
|
.Ar min_th
|
|
and
|
|
.Ar max_th
|
|
are integer numbers specifying thresholds for queue management
|
|
(thresholds are computed in bytes if the queue has been defined
|
|
in bytes, in slots otherwise).
|
|
The
|
|
.Xr dummynet 4
|
|
also supports the gentle RED variant (gred).
|
|
Three
|
|
.Xr sysctl 8
|
|
variables can be used to control the RED behaviour:
|
|
.Bl -tag -width indent
|
|
.It Em net.inet.ip.dummynet.red_lookup_depth
|
|
specifies the accuracy in computing the average queue
|
|
when the link is idle (defaults to 256, must be greater than zero)
|
|
.It Em net.inet.ip.dummynet.red_avg_pkt_size
|
|
specifies the expected average packet size (defaults to 512, must be
|
|
greater than zero)
|
|
.It Em net.inet.ip.dummynet.red_max_pkt_size
|
|
specifies the expected maximum packet size, only used when queue
|
|
thresholds are in bytes (defaults to 1500, must be greater than zero).
|
|
.El
|
|
.El
|
|
.Sh CHECKLIST
|
|
Here are some important points to consider when designing your
|
|
rules:
|
|
.Bl -bullet
|
|
.It
|
|
Remember that you filter both packets going
|
|
.Cm in
|
|
and
|
|
.Cm out .
|
|
Most connections need packets going in both directions.
|
|
.It
|
|
Remember to test very carefully.
|
|
It is a good idea to be near the console when doing this.
|
|
If you cannot be near the console,
|
|
use an auto-recovery script such as the one in
|
|
.Pa /usr/share/examples/ipfw/change_rules.sh .
|
|
.It
|
|
Don't forget the loopback interface.
|
|
.El
|
|
.Sh FINE POINTS
|
|
.Bl -bullet
|
|
.It
|
|
There are circumstances where fragmented datagrams are unconditionally
|
|
dropped.
|
|
TCP packets are dropped if they do not contain at least 20 bytes of
|
|
TCP header, UDP packets are dropped if they do not contain a full 8
|
|
byte UDP header, and ICMP packets are dropped if they do not contain
|
|
4 bytes of ICMP header, enough to specify the ICMP type, code, and
|
|
checksum.
|
|
These packets are simply logged as
|
|
.Dq pullup failed
|
|
since there may not be enough good data in the packet to produce a
|
|
meaningful log entry.
|
|
.It
|
|
Another type of packet is unconditionally dropped, a TCP packet with a
|
|
fragment offset of one.
|
|
This is a valid packet, but it only has one use, to try
|
|
to circumvent firewalls.
|
|
When logging is enabled, these packets are
|
|
reported as being dropped by rule -1.
|
|
.It
|
|
If you are logged in over a network, loading the
|
|
.Xr kld 4
|
|
version of
|
|
.Nm
|
|
is probably not as straightforward as you would think.
|
|
I recommend the following command line:
|
|
.Bd -literal -offset indent
|
|
kldload ipfw && \e
|
|
ipfw add 32000 allow ip from any to any
|
|
.Ed
|
|
.Pp
|
|
Along the same lines, doing an
|
|
.Bd -literal -offset indent
|
|
ipfw flush
|
|
.Ed
|
|
.Pp
|
|
in similar surroundings is also a bad idea.
|
|
.It
|
|
The
|
|
.Nm
|
|
filter list may not be modified if the system security level
|
|
is set to 3 or higher
|
|
(see
|
|
.Xr init 8
|
|
for information on system security levels).
|
|
.El
|
|
.Sh PACKET DIVERSION
|
|
A
|
|
.Xr divert 4
|
|
socket bound to the specified port will receive all packets
|
|
diverted to that port.
|
|
If no socket is bound to the destination port, or if the kernel
|
|
wasn't compiled with divert socket support, the packets are
|
|
dropped.
|
|
.Sh SYSCTL VARIABLES
|
|
A set of
|
|
.Xr sysctl 8
|
|
variables controls the behaviour of the firewall and
|
|
associated modules (
|
|
.Nm dummynet, bridge
|
|
).
|
|
These are shown below together with their default value
|
|
(but always check with the
|
|
.Xr sysctl 8
|
|
command what value is actually in use) and meaning:
|
|
.Bl -tag -width indent
|
|
.It Em net.inet.ip.dummynet.expire : No 1
|
|
Lazily delete dynamic pipes/queue once they have no pending traffic.
|
|
You can disable this by setting the variable to 0, in which case
|
|
the pipes/queues will only be deleted when the threshold is reached.
|
|
.It Em net.inet.ip.dummynet.hash_size : No 64
|
|
Default size of the hash table used for dynamic pipes/queues.
|
|
This value is used when no
|
|
.Cm buckets
|
|
option is specified when configuring a pipe/queue.
|
|
.It Em net.inet.ip.dummynet.max_chain_len : No 16
|
|
Target value for the maximum number of pipes/queues in a hash bucket.
|
|
The product
|
|
.Cm max_chain_len*hash_size
|
|
is used to determine the threshold over which empty pipes/queues
|
|
will be expired even when
|
|
.Cm net.inet.ip.dummynet.expire=0 .
|
|
.It Em net.inet.ip.dummynet.red_lookup_depth : No 256
|
|
.It Em net.inet.ip.dummynet.red_avg_pkt_size : No 512
|
|
.It Em net.inet.ip.dummynet.red_max_pkt_size : No 1500
|
|
Parameters used in the computations of the drop probability
|
|
for the RED algorithm.
|
|
.It Em net.inet.ip.fw.autoinc_step : No 100
|
|
Delta between rule numbers when auto-generating them.
|
|
The value must be in the range 1..1000.
|
|
This variable is only present in
|
|
.Nm ipfw2 ,
|
|
the delta is hardwired to 100 in
|
|
.Nm ipfw1 .
|
|
.It Em net.inet.ip.fw.curr_dyn_buckets : Em net.inet.ip.fw.dyn_buckets
|
|
The current number of buckets in the hash table for dynamic rules
|
|
(readonly).
|
|
.It Em net.inet.ip.fw.debug : No 1
|
|
Controls debugging messages produced by
|
|
.Nm .
|
|
.It Em net.inet.ip.fw.dyn_buckets : No 256
|
|
The number of buckets in the hash table for dynamic rules.
|
|
Must be a power of 2, up to 65536.
|
|
It only takes effect when all dynamic rules have expired, so you
|
|
are advised to use a
|
|
.Cm flush
|
|
command to make sure that the hash table is resized.
|
|
.It Em net.inet.ip.fw.dyn_count : No 3
|
|
Current number of dynamic rules
|
|
(read-only).
|
|
.It Em net.inet.ip.fw.dyn_keepalive : No 1
|
|
Enables generation of keepalive packets for
|
|
.Cm keep-state
|
|
rules on TCP sessions. A keepalive is generated to both
|
|
sides of the connection every 5 seconds for the last 20
|
|
seconds of the lifetime of the rule.
|
|
.It Em net.inet.ip.fw.dyn_max : No 8192
|
|
Maximum number of dynamic rules.
|
|
When you hit this limit, no more dynamic rules can be
|
|
installed until old ones expire.
|
|
.It Em net.inet.ip.fw.dyn_ack_lifetime : No 300
|
|
.It Em net.inet.ip.fw.dyn_syn_lifetime : No 20
|
|
.It Em net.inet.ip.fw.dyn_fin_lifetime : No 1
|
|
.It Em net.inet.ip.fw.dyn_rst_lifetime : No 1
|
|
.It Em net.inet.ip.fw.dyn_udp_lifetime : No 5
|
|
.It Em net.inet.ip.fw.dyn_short_lifetime : No 30
|
|
These variables control the lifetime, in seconds, of dynamic
|
|
rules.
|
|
Upon the initial SYN exchange the lifetime is kept short,
|
|
then increased after both SYN have been seen, then decreased
|
|
again during the final FIN exchange or when a RST is received.
|
|
Both
|
|
.Em dyn_fin_lifetime
|
|
and
|
|
.Em dyn_rst_lifetime
|
|
must be strictly lower than 5 seconds, the period of
|
|
repetition of keepalives. The firewall enforces that.
|
|
.It Em net.inet.ip.fw.enable : No 1
|
|
Enables the firewall.
|
|
Setting this variable to 0 lets you run your machine without
|
|
firewall even if compiled in.
|
|
.It Em net.inet.ip.fw.one_pass : No 1
|
|
When set, the packet exiting from the
|
|
.Xr dummynet 4
|
|
pipe is not passed though the firewall again.
|
|
Otherwise, after a pipe action, the packet is
|
|
reinjected into the firewall at the next rule.
|
|
.It Em net.inet.ip.fw.verbose : No 1
|
|
Enables verbose messages.
|
|
.It Em net.inet.ip.fw.verbose_limit : No 0
|
|
Limits the number of messages produced by a verbose firewall.
|
|
.It Em net.link.ether.ipfw : No 0
|
|
Controls whether layer-2 packets are passed to
|
|
.Nm .
|
|
Default is no.
|
|
.It Em net.link.ether.bridge_ipfw : No 0
|
|
Controls whether bridged packets are passed to
|
|
.Nm .
|
|
Default is no.
|
|
.El
|
|
.Sh USING IPFW2 IN FreeBSD-STABLE
|
|
.Nm ipfw2
|
|
is standard in
|
|
.Fx
|
|
CURRENT, whereas
|
|
.Fx
|
|
STABLE still uses
|
|
.Nm ipfw1
|
|
unless the kernel is compiled with
|
|
.Cm options IPFW2 ,
|
|
and
|
|
.Nm /sbin/ipfw
|
|
and
|
|
.Nm /usr/lib/libalias
|
|
are recompiled with
|
|
.Cm -DIPFW2
|
|
and reinstalled (the same effect can be achieved by adding
|
|
.Cm IPFW2=TRUE
|
|
to
|
|
.Nm /etc/make.conf
|
|
before a buildworld).
|
|
.Pp
|
|
.Sh IPFW2 ENHANCEMENTS
|
|
This Section lists the features that have been introduced in
|
|
.Nm ipfw2
|
|
which were not present in
|
|
.Nm ipfw1 .
|
|
We list them in order of the potential impact that they can
|
|
have in writing your rulesets.
|
|
You might want to consider using these features in order to
|
|
write your rulesets in a more efficient way.
|
|
.Bl -tag -width indent
|
|
.It Syntax and flags
|
|
.Nm ipfw1
|
|
does not support the -n flag (only test syntax),
|
|
nor it allows spaces after commas or supports all
|
|
rule fields in a single argument.
|
|
.It Handling of non-IPv4 packets
|
|
.Nm ipfw1
|
|
will silently accept all non-IPv4 packets (which
|
|
.Nm ipfw1
|
|
will only see when
|
|
.Em net.link.ether.bridge_ipfw=1 Ns
|
|
).
|
|
.Nm ipfw2
|
|
will filter all packets (including non-IPv4 ones) according to the ruleset.
|
|
To achieve the same behaviour as
|
|
.Nm ipfw1
|
|
you can use the following as the very first rule in your ruleset:
|
|
.Pp
|
|
.Dl "ipfw add 1 allow layer2 not mac-type ip"
|
|
.Pp
|
|
The
|
|
.Cm layer2
|
|
option might seem redundant, but it is necessary -- packets
|
|
passed to the firewall from layer3 will not have a MAC header,
|
|
so the
|
|
.Cm mac-type ip
|
|
pattern will always fail on them, and the
|
|
.Cm not
|
|
operator will make this rule into a pass-all.
|
|
.It Addresses
|
|
.Nm ipfw1
|
|
does not supports address sets or lists of addresses.
|
|
.Pp
|
|
.It Port specifications
|
|
.Nm ipfw1
|
|
only allows one port range when specifying TCP and UDP ports, and
|
|
is limited to 10 entries instead of the 15 allowed by
|
|
.Nm ipfw2 .
|
|
Also, in
|
|
.Nm ipfw1
|
|
you can only specify ports when the rule is requesting
|
|
.Cm tcp
|
|
or
|
|
.Cm udp
|
|
packets. With
|
|
.Nm ipfw2
|
|
you can put port specifications in rules matching all packets,
|
|
and the match will be attempted only on those packets carrying
|
|
protocols which include port identifiers.
|
|
.Pp
|
|
Finally,
|
|
.Nm ipfw1
|
|
allowed the first port entry to be specified as
|
|
.Ar port:mask
|
|
where
|
|
.Ar mask
|
|
can be an arbitrary 16-bit mask.
|
|
This syntax is of questionable usefulness and it is not
|
|
supported anymore in
|
|
.Nm ipfw2 .
|
|
.It Or-blocks
|
|
.Nm ipfw1
|
|
does not support Or-blocks.
|
|
.It keepalives
|
|
.Nm ipfw1
|
|
does not generate keepalives for stateful sessions.
|
|
As a consequence, it might cause idle sessions to drop because
|
|
the lifetime of the dynamic rules expires.
|
|
.It Sets of rules
|
|
.Nm ipfw1
|
|
does not implement sets of rules.
|
|
.It MAC header filtering and Layer-2 firewalling.
|
|
.Nm ipfw1
|
|
does not implement filtering on MAC header fields, nor is it
|
|
invoked on packets from
|
|
.Cm ether_demux()
|
|
and
|
|
.Cm ether_output_frame().
|
|
The sysctl variable
|
|
.Em net.link.ether.ipfw
|
|
has no effect there.
|
|
.It Options
|
|
In
|
|
.Nm ipfw1 ,
|
|
the following options only accept a single value as an argument:
|
|
.Pp
|
|
.Cm ipid, iplen, ipttl
|
|
.Pp
|
|
The following options are not implemented by
|
|
.Nm ipfw1 :
|
|
.Pp
|
|
.Cm dst-ip, dst-port, layer2, mac, mac-type, src-ip, src-port.
|
|
.Pp
|
|
Additionally, the RELENG_4 version of
|
|
.Nm ipfw1
|
|
does not implement the following options:
|
|
.Pp
|
|
.Cm ipid, iplen, ipprecedence, iptos, ipttl,
|
|
.Cm ipversion, tcpack, tcpseq, tcpwin .
|
|
.It Dummynet options
|
|
The following option for
|
|
.Nm dummynet
|
|
pipes/queues is not supported:
|
|
.Cm noerror .
|
|
.El
|
|
.Sh EXAMPLES
|
|
There are far too many possible uses of
|
|
.Nm
|
|
so this Section will only give a small set of examples.
|
|
.Pp
|
|
.Ss BASIC PACKET FILTERING
|
|
This command adds an entry which denies all tcp packets from
|
|
.Em cracker.evil.org
|
|
to the telnet port of
|
|
.Em wolf.tambov.su
|
|
from being forwarded by the host:
|
|
.Pp
|
|
.Dl "ipfw add deny tcp from cracker.evil.org to wolf.tambov.su telnet"
|
|
.Pp
|
|
This one disallows any connection from the entire cracker's
|
|
network to my host:
|
|
.Pp
|
|
.Dl "ipfw add deny ip from 123.45.67.0/24 to my.host.org"
|
|
.Pp
|
|
A first and efficient way to limit access (not using dynamic rules)
|
|
is the use of the following rules:
|
|
.Pp
|
|
.Dl "ipfw add allow tcp from any to any established"
|
|
.Dl "ipfw add allow tcp from net1 portlist1 to net2 portlist2 setup"
|
|
.Dl "ipfw add allow tcp from net3 portlist3 to net3 portlist3 setup"
|
|
.Dl "..."
|
|
.Dl "ipfw add deny tcp from any to any"
|
|
.Pp
|
|
The first rule will be a quick match for normal TCP packets,
|
|
but it will not match the initial SYN packet, which will be
|
|
matched by the
|
|
.Cm setup
|
|
rules only for selected source/destination pairs.
|
|
All other SYN packets will be rejected by the final
|
|
.Cm deny
|
|
rule.
|
|
.Pp
|
|
If you administer one or more subnets, you can take advantage of the
|
|
.Nm ipfw2
|
|
syntax to specify address sets and or-blocks and write extremely
|
|
compact rulesets which selectively enable services to blocks
|
|
of clients, as below:
|
|
.Pp
|
|
.Dl "goodguys=\*q{ 10.1.2.0/24{20,35,66,18} or 10.2.3.0/28{6,3,11} }\*q"
|
|
.Dl "badguys=\*q10.1.2.0/24{8,38,60}\*q"
|
|
.Dl ""
|
|
.Dl "ipfw add allow ip from ${goodguys} to any"
|
|
.Dl "ipfw add deny ip from ${badguys} to any"
|
|
.Dl "... normal policies ..."
|
|
.Pp
|
|
The
|
|
.Nm ipfw1
|
|
syntax would require a separate rule for each IP in the above
|
|
example.
|
|
.Pp
|
|
The
|
|
.Cm verrevpath
|
|
option could be used to do automated anti-spoofing by adding the
|
|
following to the top of a ruleset:
|
|
.Pp
|
|
.Dl "ipfw add deny ip from any to any not verrevpath in"
|
|
.Pp
|
|
This rule drops all incoming packets that appear to be coming to the
|
|
sytem on the wrong interface. For example, a packet with a source
|
|
address belonging to a host on a protected internal network would be
|
|
dropped if it tried to enter the system from an external interface.
|
|
.Ss DYNAMIC RULES
|
|
In order to protect a site from flood attacks involving fake
|
|
TCP packets, it is safer to use dynamic rules:
|
|
.Pp
|
|
.Dl "ipfw add check-state"
|
|
.Dl "ipfw add deny tcp from any to any established"
|
|
.Dl "ipfw add allow tcp from my-net to any setup keep-state"
|
|
.Pp
|
|
This will let the firewall install dynamic rules only for
|
|
those connection which start with a regular SYN packet coming
|
|
from the inside of our network.
|
|
Dynamic rules are checked when encountering the first
|
|
.Cm check-state
|
|
or
|
|
.Cm keep-state
|
|
rule.
|
|
A
|
|
.Cm check-state
|
|
rule should usually be placed near the beginning of the
|
|
ruleset to minimize the amount of work scanning the ruleset.
|
|
Your mileage may vary.
|
|
.Pp
|
|
To limit the number of connections a user can open
|
|
you can use the following type of rules:
|
|
.Pp
|
|
.Dl "ipfw add allow tcp from my-net/24 to any setup limit src-addr 10"
|
|
.Dl "ipfw add allow tcp from any to me setup limit src-addr 4"
|
|
.Pp
|
|
The former (assuming it runs on a gateway) will allow each host
|
|
on a /24 network to open at most 10 TCP connections.
|
|
The latter can be placed on a server to make sure that a single
|
|
client does not use more than 4 simultaneous connections.
|
|
.Pp
|
|
.Em BEWARE :
|
|
stateful rules can be subject to denial-of-service attacks
|
|
by a SYN-flood which opens a huge number of dynamic rules.
|
|
The effects of such attacks can be partially limited by
|
|
acting on a set of
|
|
.Xr sysctl 8
|
|
variables which control the operation of the firewall.
|
|
.Pp
|
|
Here is a good usage of the
|
|
.Cm list
|
|
command to see accounting records and timestamp information:
|
|
.Pp
|
|
.Dl ipfw -at list
|
|
.Pp
|
|
or in short form without timestamps:
|
|
.Pp
|
|
.Dl ipfw -a list
|
|
.Pp
|
|
which is equivalent to:
|
|
.Pp
|
|
.Dl ipfw show
|
|
.Pp
|
|
Next rule diverts all incoming packets from 192.168.2.0/24
|
|
to divert port 5000:
|
|
.Pp
|
|
.Dl ipfw divert 5000 ip from 192.168.2.0/24 to any in
|
|
.Pp
|
|
.Ss TRAFFIC SHAPING
|
|
The following rules show some of the applications of
|
|
.Nm
|
|
and
|
|
.Xr dummynet 4
|
|
for simulations and the like.
|
|
.Pp
|
|
This rule drops random incoming packets with a probability
|
|
of 5%:
|
|
.Pp
|
|
.Dl "ipfw add prob 0.05 deny ip from any to any in"
|
|
.Pp
|
|
A similar effect can be achieved making use of dummynet pipes:
|
|
.Pp
|
|
.Dl "ipfw add pipe 10 ip from any to any"
|
|
.Dl "ipfw pipe 10 config plr 0.05"
|
|
.Pp
|
|
We can use pipes to artificially limit bandwidth, e.g. on a
|
|
machine acting as a router, if we want to limit traffic from
|
|
local clients on 192.168.2.0/24 we do:
|
|
.Pp
|
|
.Dl "ipfw add pipe 1 ip from 192.168.2.0/24 to any out"
|
|
.Dl "ipfw pipe 1 config bw 300Kbit/s queue 50KBytes"
|
|
.Pp
|
|
note that we use the
|
|
.Cm out
|
|
modifier so that the rule is not used twice.
|
|
Remember in fact that
|
|
.Nm
|
|
rules are checked both on incoming and outgoing packets.
|
|
.Pp
|
|
Should we want to simulate a bidirectional link with bandwidth
|
|
limitations, the correct way is the following:
|
|
.Pp
|
|
.Dl "ipfw add pipe 1 ip from any to any out"
|
|
.Dl "ipfw add pipe 2 ip from any to any in"
|
|
.Dl "ipfw pipe 1 config bw 64Kbit/s queue 10Kbytes"
|
|
.Dl "ipfw pipe 2 config bw 64Kbit/s queue 10Kbytes"
|
|
.Pp
|
|
The above can be very useful, e.g. if you want to see how
|
|
your fancy Web page will look for a residential user who
|
|
is connected only through a slow link.
|
|
You should not use only one pipe for both directions, unless
|
|
you want to simulate a half-duplex medium (e.g. AppleTalk,
|
|
Ethernet, IRDA).
|
|
It is not necessary that both pipes have the same configuration,
|
|
so we can also simulate asymmetric links.
|
|
.Pp
|
|
Should we want to verify network performance with the RED queue
|
|
management algorithm:
|
|
.Pp
|
|
.Dl "ipfw add pipe 1 ip from any to any"
|
|
.Dl "ipfw pipe 1 config bw 500Kbit/s queue 100 red 0.002/30/80/0.1"
|
|
.Pp
|
|
Another typical application of the traffic shaper is to
|
|
introduce some delay in the communication.
|
|
This can significantly affect applications which do a lot of Remote
|
|
Procedure Calls, and where the round-trip-time of the
|
|
connection often becomes a limiting factor much more than
|
|
bandwidth:
|
|
.Pp
|
|
.Dl "ipfw add pipe 1 ip from any to any out"
|
|
.Dl "ipfw add pipe 2 ip from any to any in"
|
|
.Dl "ipfw pipe 1 config delay 250ms bw 1Mbit/s"
|
|
.Dl "ipfw pipe 2 config delay 250ms bw 1Mbit/s"
|
|
.Pp
|
|
Per-flow queueing can be useful for a variety of purposes.
|
|
A very simple one is counting traffic:
|
|
.Pp
|
|
.Dl "ipfw add pipe 1 tcp from any to any"
|
|
.Dl "ipfw add pipe 1 udp from any to any"
|
|
.Dl "ipfw add pipe 1 ip from any to any"
|
|
.Dl "ipfw pipe 1 config mask all"
|
|
.Pp
|
|
The above set of rules will create queues (and collect
|
|
statistics) for all traffic.
|
|
Because the pipes have no limitations, the only effect is
|
|
collecting statistics.
|
|
Note that we need 3 rules, not just the last one, because
|
|
when
|
|
.Nm
|
|
tries to match IP packets it will not consider ports, so we
|
|
would not see connections on separate ports as different
|
|
ones.
|
|
.Pp
|
|
A more sophisticated example is limiting the outbound traffic
|
|
on a net with per-host limits, rather than per-network limits:
|
|
.Pp
|
|
.Dl "ipfw add pipe 1 ip from 192.168.2.0/24 to any out"
|
|
.Dl "ipfw add pipe 2 ip from any to 192.168.2.0/24 in"
|
|
.Dl "ipfw pipe 1 config mask src-ip 0x000000ff bw 200Kbit/s queue 20Kbytes"
|
|
.Dl "ipfw pipe 2 config mask dst-ip 0x000000ff bw 200Kbit/s queue 20Kbytes"
|
|
.Ss SETS OF RULES
|
|
To add a set of rules atomically, e.g. set 18:
|
|
.Pp
|
|
.Dl "ipfw set disable 18"
|
|
.Dl "ipfw add NN set 18 ... # repeat as needed"
|
|
.Dl "ipfw set enable 18"
|
|
.Pp
|
|
To delete a set of rules atomically the command is simply:
|
|
.Pp
|
|
.Dl "ipfw delete set 18"
|
|
.Pp
|
|
To test a ruleset and disable it and regain control if something goes wrong:
|
|
.Pp
|
|
.Dl "ipfw set disable 18"
|
|
.Dl "ipfw add NN set 18 ... # repeat as needed"
|
|
.Dl "ipfw set enable 18; echo done; sleep 30 && ipfw set disable 18"
|
|
.Pp
|
|
Here if everything goes well, you press control-C before the "sleep"
|
|
terminates, and your ruleset will be left active. Otherwise, e.g. if
|
|
you cannot access your box, the ruleset will be disabled after
|
|
the sleep terminates thus restoring the previous situation.
|
|
.Sh SEE ALSO
|
|
.Xr cpp 1 ,
|
|
.Xr m4 1 ,
|
|
.Xr bridge 4 ,
|
|
.Xr divert 4 ,
|
|
.Xr dummynet 4 ,
|
|
.Xr ip 4 ,
|
|
.Xr ipfirewall 4 ,
|
|
.Xr protocols 5 ,
|
|
.Xr services 5 ,
|
|
.Xr init 8 ,
|
|
.Xr kldload 8 ,
|
|
.Xr reboot 8 ,
|
|
.Xr sysctl 8 ,
|
|
.Xr syslogd 8
|
|
.Sh BUGS
|
|
The syntax has grown over the years and sometimes it might be confusing.
|
|
Unfortunately, backward compatibility prevents cleaning up mistakes
|
|
made in the definition of the syntax.
|
|
.Pp
|
|
.Em !!! WARNING !!!
|
|
.Pp
|
|
Misconfiguring the firewall can put your computer in an unusable state,
|
|
possibly shutting down network services and requiring console access to
|
|
regain control of it.
|
|
.Pp
|
|
Incoming packet fragments diverted by
|
|
.Cm divert
|
|
or
|
|
.Cm tee
|
|
are reassembled before delivery to the socket.
|
|
The action used on those packet is the one from the
|
|
rule which matches the first fragment of the packet.
|
|
.Pp
|
|
Packets that match a
|
|
.Cm tee
|
|
rule should not be immediately accepted, but should continue
|
|
going through the rule list.
|
|
This may be fixed in a later version.
|
|
.Pp
|
|
Packets diverted to userland, and then reinserted by a userland process
|
|
may lose various packet attributes.
|
|
The packet source interface name
|
|
will be preserved if it is shorter than 8 bytes and the userland process
|
|
saves and reuses the sockaddr_in
|
|
(as does
|
|
.Xr natd 8 ) ;
|
|
otherwise, it may be lost.
|
|
If a packet is reinserted in this manner, later rules may be incorrectly
|
|
applied, making the order of
|
|
.Cm divert
|
|
rules in the rule sequence very important.
|
|
.Sh AUTHORS
|
|
.An Ugen J. S. Antsilevich ,
|
|
.An Poul-Henning Kamp ,
|
|
.An Alex Nash ,
|
|
.An Archie Cobbs ,
|
|
.An Luigi Rizzo .
|
|
.Pp
|
|
.An -nosplit
|
|
API based upon code written by
|
|
.An Daniel Boulet
|
|
for BSDI.
|
|
.Pp
|
|
Work on
|
|
.Xr dummynet 4
|
|
traffic shaper supported by Akamba Corp.
|
|
.Sh HISTORY
|
|
The
|
|
.Nm
|
|
utility first appeared in
|
|
.Fx 2.0 .
|
|
.Xr dummynet 4
|
|
was introduced in
|
|
.Fx 2.2.8 .
|
|
Stateful extensions were introduced in
|
|
.Fx 4.0 .
|
|
.Nm ipfw2
|
|
was introduced in Summer 2002.
|