One more (hopefully the last one) step in cleaning up the syntax,
following Julian's good suggestion: since you can specify any match pattern as an option, rules now have the following format: [<proto> from <src> to <dst>] [options] i.e. the first part is now entirely optional (and left there just for compatibility with ipfw1 rulesets). Add a "-c" flag to show/list rules in the compact form (i.e. without the "ip from any to any" part) when possible. The default is to include it so that scripts processing ipfw's canonical output will still work. Note that as part of this cleanup (and to remove ambiguity), MAC fields now can only be specified in the options part. Update the manpage to reflect the syntax. Clarify the behaviour when a match is attempted on fields which are not present in the packet, e.g. port numbers on non TCP/UDP packets, and the "not" operator is specified. E.g. ipfw add allow not src-port 80 will match also ICMP packets because they do not have port numbers, so "src-port 80" will fail and "not src-port 80" will succeed. For such cases it is advised to insert further options to prevent undesired results (e.g. in the case above, "ipfw add allow proto tcp not src-port 80"). We definitely need to rewrite the parser using lex and yacc!
This commit is contained in:
parent
cb4abe67ef
commit
5a155b405e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=102098
139
sbin/ipfw/ipfw.8
139
sbin/ipfw/ipfw.8
@ -14,11 +14,11 @@
|
|||||||
.Nd IP firewall and traffic shaper control program
|
.Nd IP firewall and traffic shaper control program
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl q
|
.Op Fl cq
|
||||||
.Cm add
|
.Cm add
|
||||||
.Ar rule
|
.Ar rule
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl adeftNS
|
.Op Fl acdeftNS
|
||||||
.Brq Cm list | show
|
.Brq Cm list | show
|
||||||
.Op Ar number ...
|
.Op Ar number ...
|
||||||
.Nm
|
.Nm
|
||||||
@ -219,6 +219,10 @@ While listing, show counter values.
|
|||||||
The
|
The
|
||||||
.Cm show
|
.Cm show
|
||||||
command just implies this option.
|
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
|
.It Fl d
|
||||||
While listing, show dynamic rules in addition to static ones.
|
While listing, show dynamic rules in addition to static ones.
|
||||||
.It Fl e
|
.It Fl e
|
||||||
@ -372,7 +376,12 @@ to match a MAC header when
|
|||||||
.Nm
|
.Nm
|
||||||
is called from
|
is called from
|
||||||
.Cm ip_input()
|
.Cm ip_input()
|
||||||
) the rule will simply not match. It is thus responsibility of
|
) the match pattern will not match. However, a
|
||||||
|
.Cm not
|
||||||
|
operator in front of such patterns will cause the pattern to
|
||||||
|
.Em always
|
||||||
|
match on those packets, which might cause undesired results.
|
||||||
|
It is thus responsibility of
|
||||||
the programmer, if necessary, to write a suitable ruleset to
|
the programmer, if necessary, to write a suitable ruleset to
|
||||||
differentiate among the possible places.
|
differentiate among the possible places.
|
||||||
.Cm skipto
|
.Cm skipto
|
||||||
@ -648,12 +657,12 @@ specific source and destination addresses or ports,
|
|||||||
protocol options, incoming or outgoing interfaces, etc.)
|
protocol options, incoming or outgoing interfaces, etc.)
|
||||||
that the packet must match in order to be recognised.
|
that the packet must match in order to be recognised.
|
||||||
In general, the patterns are connected by (implicit)
|
In general, the patterns are connected by (implicit)
|
||||||
.Em and
|
.Cm and
|
||||||
connectives -- i.e. all must match in order for the
|
operators -- i.e. all must match in order for the
|
||||||
rule to match.
|
rule to match.
|
||||||
Individual patterns can be prefixed by the
|
Individual patterns can be prefixed by the
|
||||||
.Em not
|
.Cm not
|
||||||
keyword to reverse the result of the match, as in
|
operator to reverse the result of the match, as in
|
||||||
.Pp
|
.Pp
|
||||||
.Dl "ipfw add 100 allow ip from not 1.2.3.4 to any"
|
.Dl "ipfw add 100 allow ip from not 1.2.3.4 to any"
|
||||||
.Pp
|
.Pp
|
||||||
@ -661,15 +670,16 @@ Additionally, sets of alternative match patterns (
|
|||||||
.Em or-blocks
|
.Em or-blocks
|
||||||
) can be constructed by putting the patterns in
|
) can be constructed by putting the patterns in
|
||||||
lists enclosed between parentheses ( ) or braces { }, and
|
lists enclosed between parentheses ( ) or braces { }, and
|
||||||
using
|
using the
|
||||||
.Cm or
|
.Cm or
|
||||||
connectives as follows:
|
operator as follows:
|
||||||
.Pp
|
.Pp
|
||||||
.Dl "ipfw add 100 allow ip from { x or not y or z } to any"
|
.Dl "ipfw add 100 allow ip from { x or not y or z } to any"
|
||||||
.Pp
|
.Pp
|
||||||
Only one level of parentheses is allowed.
|
Only one level of parentheses is allowed.
|
||||||
Beware that most shells have special meanings for parentheses
|
Beware that most shells have special meanings for parentheses
|
||||||
or braces, so it is advisable to put a \\ in front of them.
|
or braces, so it is advisable to put a backslash \\ in front of them
|
||||||
|
to prevent such interpretations.
|
||||||
.Pp
|
.Pp
|
||||||
The body of a rule must in general include a source and destination
|
The body of a rule must in general include a source and destination
|
||||||
addres specifier.
|
addres specifier.
|
||||||
@ -678,35 +688,36 @@ The keyword
|
|||||||
can be used in various places to specify that the content of
|
can be used in various places to specify that the content of
|
||||||
a required field is irrelevant.
|
a required field is irrelevant.
|
||||||
.Pp
|
.Pp
|
||||||
The rule body format is one of the following:
|
The rule body has the following format:
|
||||||
.Bd -ragged -offset indent
|
.Bd -ragged -offset indent
|
||||||
.Ar proto
|
.Op Ar proto Cm from Ar src Cm to Ar dst
|
||||||
.Cm from Ar src
|
|
||||||
.Cm to Ar dst
|
|
||||||
.Op Ar options
|
.Op Ar options
|
||||||
.Pp
|
|
||||||
.Cm MAC Ar dst-mac src-mac Op Cm not
|
|
||||||
.Ar mac-type Op Ar options
|
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
where the second format allows you to specify MAC header fields
|
The first part (protocol from src to dst) is for backward
|
||||||
instead of IPv4 header fields.
|
compatibility with
|
||||||
Note that in practice both formats are equivalent, because the
|
.Nm ipfw1 .
|
||||||
|
In
|
||||||
|
.Nm ipfw2
|
||||||
|
any match pattern (including MAC headers, IPv4 protocols,
|
||||||
|
addresses and ports) can be specified in the
|
||||||
.Ar options
|
.Ar options
|
||||||
let you specify match patterns for all IP and MAC header fields.
|
section.
|
||||||
.Pp
|
.Pp
|
||||||
Rule fields have the following meaning:
|
Rule fields have the following meaning:
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
.It Ar proto
|
.It Ar proto : protocol | Cm { Ar protocol Cm or ... }
|
||||||
An IPv4 protocol specified by number or name (for a complete
|
An IPv4 protocol (or an
|
||||||
list see
|
.Em or-block
|
||||||
|
with multiple protocols) specified by number or name
|
||||||
|
(for a complete list see
|
||||||
.Pa /etc/protocols ) .
|
.Pa /etc/protocols ) .
|
||||||
The
|
The
|
||||||
.Cm ip
|
.Cm ip
|
||||||
or
|
or
|
||||||
.Cm all
|
.Cm all
|
||||||
keywords mean any protocol will match.
|
keywords mean any protocol will match.
|
||||||
.It Ar src No and Ar dst : ip-address | { ip-address Cm or ... } Op Ar ports
|
.It Ar src No and Ar dst : ip-address | Cm { Ar ip-address Cm or ... } Op Ar ports
|
||||||
A single
|
A single
|
||||||
.Ar ip-address
|
.Ar ip-address
|
||||||
, or an
|
, or an
|
||||||
@ -786,7 +797,9 @@ A backslash
|
|||||||
.Pq Ql \e
|
.Pq Ql \e
|
||||||
can be used to escape the dash
|
can be used to escape the dash
|
||||||
.Pq Ql -
|
.Pq Ql -
|
||||||
character in a service name:
|
character in a service name (from a shell, the backslash must be
|
||||||
|
typed twice to avoid that the shell itself uses it as an escape
|
||||||
|
character).
|
||||||
.Pp
|
.Pp
|
||||||
.Dl "ipfw add count tcp from any ftp\e\e-data-ftp to any"
|
.Dl "ipfw add count tcp from any ftp\e\e-data-ftp to any"
|
||||||
.Pp
|
.Pp
|
||||||
@ -796,28 +809,6 @@ specifications.
|
|||||||
See the
|
See the
|
||||||
.Cm frag
|
.Cm frag
|
||||||
option for details on matching fragmented packets.
|
option for details on matching fragmented packets.
|
||||||
.It Ar dst-mac, src-mac
|
|
||||||
Destination and source MAC addresses, specified as
|
|
||||||
groups of hex digits separated by commas, and optionally
|
|
||||||
followed by a mask indicating how many bits are significant:
|
|
||||||
.Pp
|
|
||||||
.Dl "ipfw add allow MAC 10:20:30:40:50:60/30 any 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 Ar mac-type
|
|
||||||
The value of the Ethernet Type field, 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 .
|
|
||||||
The values can be enter as decimal or hexadecimal, but they
|
|
||||||
are always printed as hexadecimal (unless the
|
|
||||||
.Cm -N
|
|
||||||
option is used, in which case symbolic resolution will be
|
|
||||||
attempted).
|
|
||||||
.El
|
.El
|
||||||
.Ss RULE OPTIONS (MATCH PATTERNS)
|
.Ss RULE OPTIONS (MATCH PATTERNS)
|
||||||
Additional match patterns can be used within
|
Additional match patterns can be used within
|
||||||
@ -974,12 +965,36 @@ One or more
|
|||||||
of source and destination addresses and ports can be
|
of source and destination addresses and ports can be
|
||||||
specified.
|
specified.
|
||||||
.It Cm { MAC | mac } Ar dst-mac src-mac
|
.It Cm { MAC | mac } Ar dst-mac src-mac
|
||||||
Match packets with a given dst-mac and src-mac addresses, specified
|
Match packets with a given
|
||||||
in one of the forms described earlier.
|
.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 commas,
|
||||||
|
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
|
.It Cm mac-type Ar mac-type
|
||||||
Matches packets whose
|
Matches packets whose Ethernet Type field
|
||||||
.Ar mac-type
|
|
||||||
corresponds to one of those specified as argument.
|
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 enter 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
|
.It Cm proto Ar protocol
|
||||||
Matches packets with the corresponding IPv4 protocol.
|
Matches packets with the corresponding IPv4 protocol.
|
||||||
.It Cm recv | xmit | via Brq Ar ifX | Ar if Ns Cm * | Ar ipno | Ar any
|
.It Cm recv | xmit | via Brq Ar ifX | Ar if Ns Cm * | Ar ipno | Ar any
|
||||||
@ -1614,8 +1629,17 @@ To achieve the same behaviour as
|
|||||||
.Nm ipfw1
|
.Nm ipfw1
|
||||||
you can use the following as the very first rule in your ruleset:
|
you can use the following as the very first rule in your ruleset:
|
||||||
.Pp
|
.Pp
|
||||||
.Dl "ipfw add 1 allow MAC any any not ip"
|
.Dl "ipfw add 1 allow layer2 not mac-type ip"
|
||||||
.Pp
|
.Pp
|
||||||
|
The
|
||||||
|
.Cm layer2
|
||||||
|
options 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 Address sets
|
.It Address sets
|
||||||
.Nm ipfw1
|
.Nm ipfw1
|
||||||
does not supports address sets (those in the form
|
does not supports address sets (those in the form
|
||||||
@ -1684,11 +1708,16 @@ has no effect there.
|
|||||||
.It Options
|
.It Options
|
||||||
The following options are not supported in
|
The following options are not supported in
|
||||||
.Nm ipfw1
|
.Nm ipfw1
|
||||||
|
.Pp
|
||||||
|
.Cm dst-ip, dst-port, layer2, mac, mac-type, src-ip, src-port.
|
||||||
|
.Pp
|
||||||
|
Additionally, the following options are not supported in
|
||||||
|
.Nm ipfw1
|
||||||
(RELENG_4)
|
(RELENG_4)
|
||||||
rules:
|
rules:
|
||||||
.Pp
|
.Pp
|
||||||
.Cm layer2, ipid, iplen, ipprecedence, iptos, ipttl,
|
.Cm ipid, iplen, ipprecedence, iptos, ipttl,
|
||||||
.Cm ipversion, tcpack, tcpseq, tcpwin .
|
.Cm ipversion, .Cm tcpack, tcpseq, tcpwin .
|
||||||
.It Dummynet options
|
.It Dummynet options
|
||||||
The following option for
|
The following option for
|
||||||
.Nm dummynet
|
.Nm dummynet
|
||||||
|
@ -65,6 +65,7 @@ int s, /* main RAW socket */
|
|||||||
do_sort, /* field to sort results (0 = no) */
|
do_sort, /* field to sort results (0 = no) */
|
||||||
do_dynamic, /* display dynamic rules */
|
do_dynamic, /* display dynamic rules */
|
||||||
do_expired, /* display expired dynamic rules */
|
do_expired, /* display expired dynamic rules */
|
||||||
|
do_compact, /* show rules in compact mode */
|
||||||
show_sets, /* display rule sets */
|
show_sets, /* display rule sets */
|
||||||
verbose;
|
verbose;
|
||||||
|
|
||||||
@ -931,7 +932,8 @@ show_ipfw(struct ip_fw *rule)
|
|||||||
* then print the body.
|
* then print the body.
|
||||||
*/
|
*/
|
||||||
if (rule->_pad & 1) { /* empty rules before options */
|
if (rule->_pad & 1) { /* empty rules before options */
|
||||||
printf (" all from any to any");
|
if (!do_compact)
|
||||||
|
printf(" ip from any to any");
|
||||||
flags |= HAVE_IP | HAVE_OPTIONS;
|
flags |= HAVE_IP | HAVE_OPTIONS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2325,7 +2327,7 @@ add_mac(ipfw_insn *cmd, int ac, char *av[])
|
|||||||
ipfw_insn_mac *mac;
|
ipfw_insn_mac *mac;
|
||||||
|
|
||||||
if (ac < 2)
|
if (ac < 2)
|
||||||
errx(EX_DATAERR, "MAC dst src [not] type");
|
errx(EX_DATAERR, "MAC dst src");
|
||||||
|
|
||||||
cmd->opcode = O_MACADDR2;
|
cmd->opcode = O_MACADDR2;
|
||||||
cmd->len = (cmd->len & (F_NOT | F_OR)) | F_INSN_SIZE(ipfw_insn_mac);
|
cmd->len = (cmd->len & (F_NOT | F_OR)) | F_INSN_SIZE(ipfw_insn_mac);
|
||||||
@ -2362,7 +2364,7 @@ add_proto(ipfw_insn *cmd, char *av)
|
|||||||
else if ((pe = getprotobyname(av)) != NULL)
|
else if ((pe = getprotobyname(av)) != NULL)
|
||||||
proto = pe->p_proto;
|
proto = pe->p_proto;
|
||||||
else
|
else
|
||||||
errx(EX_DATAERR, "invalid protocol ``%s''", av);
|
return NULL;
|
||||||
if (proto != IPPROTO_IP)
|
if (proto != IPPROTO_IP)
|
||||||
fill_cmd(cmd, O_PROTO, 0, proto);
|
fill_cmd(cmd, O_PROTO, 0, proto);
|
||||||
return cmd;
|
return cmd;
|
||||||
@ -2673,6 +2675,8 @@ add(int ac, char *av[])
|
|||||||
CLOSE_PAR;
|
CLOSE_PAR;
|
||||||
|
|
||||||
first_cmd = cmd;
|
first_cmd = cmd;
|
||||||
|
|
||||||
|
#if 0
|
||||||
/*
|
/*
|
||||||
* MAC addresses, optional.
|
* MAC addresses, optional.
|
||||||
* If we have this, we skip the part "proto from src to dst"
|
* If we have this, we skip the part "proto from src to dst"
|
||||||
@ -2693,6 +2697,7 @@ add(int ac, char *av[])
|
|||||||
ac--; av++; /* any or mac-type */
|
ac--; av++; /* any or mac-type */
|
||||||
goto read_options;
|
goto read_options;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* protocol, mandatory
|
* protocol, mandatory
|
||||||
@ -2709,7 +2714,10 @@ add(int ac, char *av[])
|
|||||||
prev = cmd;
|
prev = cmd;
|
||||||
cmd = next_cmd(cmd);
|
cmd = next_cmd(cmd);
|
||||||
}
|
}
|
||||||
}
|
} else if (first_cmd != cmd) {
|
||||||
|
errx(EX_DATAERR, "invalid protocol ``%s''", av);
|
||||||
|
} else
|
||||||
|
goto read_options;
|
||||||
OR_BLOCK(get_proto);
|
OR_BLOCK(get_proto);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3040,7 +3048,8 @@ add(int ac, char *av[])
|
|||||||
if (add_proto(cmd, *av)) {
|
if (add_proto(cmd, *av)) {
|
||||||
proto = cmd->arg1;
|
proto = cmd->arg1;
|
||||||
ac--; av++;
|
ac--; av++;
|
||||||
}
|
} else
|
||||||
|
errx(EX_DATAERR, "invalid protocol ``%s''", av);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_SRCIP:
|
case TOK_SRCIP:
|
||||||
@ -3291,7 +3300,7 @@ ipfw_main(int ac, char **av)
|
|||||||
do_force = !isatty(STDIN_FILENO);
|
do_force = !isatty(STDIN_FILENO);
|
||||||
|
|
||||||
optind = optreset = 1;
|
optind = optreset = 1;
|
||||||
while ((ch = getopt(ac, av, "hs:adefNqStv")) != -1)
|
while ((ch = getopt(ac, av, "hs:acdefNqStv")) != -1)
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'h': /* help */
|
case 'h': /* help */
|
||||||
help();
|
help();
|
||||||
@ -3303,6 +3312,9 @@ ipfw_main(int ac, char **av)
|
|||||||
case 'a':
|
case 'a':
|
||||||
do_acct = 1;
|
do_acct = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'c':
|
||||||
|
do_compact = 1;
|
||||||
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
do_dynamic = 1;
|
do_dynamic = 1;
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user