Change the syntax of ipfw's named states.
Since the state name is an optional argument, it often can conflict with other options. To avoid ambiguity now the state name must be prefixed with a colon. Obtained from: Yandex LLC MFC after: 2 week Sponsored by: Yandex LLC
This commit is contained in:
parent
776c68249b
commit
6ed1473867
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=315305
6
UPDATING
6
UPDATING
@ -51,6 +51,12 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW:
|
|||||||
|
|
||||||
****************************** SPECIAL WARNING: ******************************
|
****************************** SPECIAL WARNING: ******************************
|
||||||
|
|
||||||
|
20170315:
|
||||||
|
The syntax of ipfw(8) named states was changed to avoid ambiguity.
|
||||||
|
If you have used named states in the firewall rules, you need to modify
|
||||||
|
them after installworld and before rebooting. Now named states must
|
||||||
|
be prefixed with colon.
|
||||||
|
|
||||||
20170311:
|
20170311:
|
||||||
The old drm (sys/dev/drm/) drivers for i915 and radeon have been
|
The old drm (sys/dev/drm/) drivers for i915 and radeon have been
|
||||||
removed as the userland we provide cannot use them. The KMS version
|
removed as the userland we provide cannot use them. The KMS version
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd October 18, 2016
|
.Dd March 15, 2017
|
||||||
.Dt IPFW 8
|
.Dt IPFW 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -781,7 +781,7 @@ will be executed when the packet matches the body of the rule.
|
|||||||
.It Cm allow | accept | pass | permit
|
.It Cm allow | accept | pass | permit
|
||||||
Allow packets that match rule.
|
Allow packets that match rule.
|
||||||
The search terminates.
|
The search terminates.
|
||||||
.It Cm check-state Op Ar flowname | Cm any
|
.It Cm check-state Op Ar :flowname | Cm :any
|
||||||
Checks the packet against the dynamic ruleset.
|
Checks the packet against the dynamic ruleset.
|
||||||
If a match is found, execute the action associated with
|
If a match is found, execute the action associated with
|
||||||
the rule which generated this dynamic rule, otherwise
|
the rule which generated this dynamic rule, otherwise
|
||||||
@ -797,15 +797,15 @@ or
|
|||||||
.Cm limit
|
.Cm limit
|
||||||
rule.
|
rule.
|
||||||
The
|
The
|
||||||
.Ar flowname
|
.Ar :flowname
|
||||||
is symbolic name assigned to dynamic rule by
|
is symbolic name assigned to dynamic rule by
|
||||||
.Cm keep-state
|
.Cm keep-state
|
||||||
opcode.
|
opcode.
|
||||||
The special flowname
|
The special flowname
|
||||||
.Cm any
|
.Cm :any
|
||||||
can be used to ignore states flowname when matching.
|
can be used to ignore states flowname when matching.
|
||||||
The
|
The
|
||||||
.Cm default
|
.Cm :default
|
||||||
keyword is special name used for compatibility with old rulesets.
|
keyword is special name used for compatibility with old rulesets.
|
||||||
.It Cm count
|
.It Cm count
|
||||||
Update counters for all packets that match rule.
|
Update counters for all packets that match rule.
|
||||||
@ -1662,7 +1662,7 @@ specified in the same way as
|
|||||||
.It Cm ipversion Ar ver
|
.It Cm ipversion Ar ver
|
||||||
Matches IP packets whose IP version field is
|
Matches IP packets whose IP version field is
|
||||||
.Ar ver .
|
.Ar ver .
|
||||||
.It Cm keep-state Op Ar flowname
|
.It Cm keep-state Op Ar :flowname
|
||||||
Upon a match, the firewall will create a dynamic rule, whose
|
Upon a match, the firewall will create a dynamic rule, whose
|
||||||
default behaviour is to match bidirectional traffic between
|
default behaviour is to match bidirectional traffic between
|
||||||
source and destination IP/port using the same protocol.
|
source and destination IP/port using the same protocol.
|
||||||
@ -1671,19 +1671,19 @@ The rule has a limited lifetime (controlled by a set of
|
|||||||
variables), and the lifetime is refreshed every time a matching
|
variables), and the lifetime is refreshed every time a matching
|
||||||
packet is found.
|
packet is found.
|
||||||
The
|
The
|
||||||
.Ar flowname
|
.Ar :flowname
|
||||||
is used to assign additional to addresses, ports and protocol parameter
|
is used to assign additional to addresses, ports and protocol parameter
|
||||||
to dynamic rule. It can be used for more accurate matching by
|
to dynamic rule. It can be used for more accurate matching by
|
||||||
.Cm check-state
|
.Cm check-state
|
||||||
rule.
|
rule.
|
||||||
The
|
The
|
||||||
.Cm default
|
.Cm :default
|
||||||
keyword is special name used for compatibility with old rulesets.
|
keyword is special name used for compatibility with old rulesets.
|
||||||
.It Cm layer2
|
.It Cm layer2
|
||||||
Matches only layer2 packets, i.e., those passed to
|
Matches only layer2 packets, i.e., those passed to
|
||||||
.Nm
|
.Nm
|
||||||
from ether_demux() and ether_output_frame().
|
from ether_demux() and ether_output_frame().
|
||||||
.It Cm limit Bro Cm src-addr | src-port | dst-addr | dst-port Brc Ar N Op Ar flowname
|
.It Cm limit Bro Cm src-addr | src-port | dst-addr | dst-port Brc Ar N Op Ar :flowname
|
||||||
The firewall will only allow
|
The firewall will only allow
|
||||||
.Ar N
|
.Ar N
|
||||||
connections with the same
|
connections with the same
|
||||||
@ -2286,7 +2286,7 @@ are completely equivalent afterwards).
|
|||||||
Rules created by
|
Rules created by
|
||||||
.Cm keep-state
|
.Cm keep-state
|
||||||
option also have a
|
option also have a
|
||||||
.Ar flowname
|
.Ar :flowname
|
||||||
taken from it.
|
taken from it.
|
||||||
This name is used in matching together with addresses, ports and protocol.
|
This name is used in matching together with addresses, ports and protocol.
|
||||||
Dynamic rules will be checked at the first
|
Dynamic rules will be checked at the first
|
||||||
@ -2297,23 +2297,23 @@ occurrence, and the action performed upon a match will be the same
|
|||||||
as in the parent rule.
|
as in the parent rule.
|
||||||
.Pp
|
.Pp
|
||||||
Note that no additional attributes other than protocol and IP addresses
|
Note that no additional attributes other than protocol and IP addresses
|
||||||
and ports and flowname are checked on dynamic rules.
|
and ports and :flowname are checked on dynamic rules.
|
||||||
.Pp
|
.Pp
|
||||||
The typical use of dynamic rules is to keep a closed firewall configuration,
|
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
|
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
|
dynamic rule for the flow so that packets belonging to that session
|
||||||
will be allowed through the firewall:
|
will be allowed through the firewall:
|
||||||
.Pp
|
.Pp
|
||||||
.Dl "ipfw add check-state OUTBOUND"
|
.Dl "ipfw add check-state :OUTBOUND"
|
||||||
.Dl "ipfw add allow tcp from my-subnet to any setup keep-state OUTBOUND"
|
.Dl "ipfw add allow tcp from my-subnet to any setup keep-state :OUTBOUND"
|
||||||
.Dl "ipfw add deny tcp from any to any"
|
.Dl "ipfw add deny tcp from any to any"
|
||||||
.Pp
|
.Pp
|
||||||
A similar approach can be used for UDP, where an UDP packet coming
|
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
|
from the inside will install a dynamic rule to let the response through
|
||||||
the firewall:
|
the firewall:
|
||||||
.Pp
|
.Pp
|
||||||
.Dl "ipfw add check-state OUTBOUND"
|
.Dl "ipfw add check-state :OUTBOUND"
|
||||||
.Dl "ipfw add allow udp from my-subnet to any keep-state OUTBOUND"
|
.Dl "ipfw add allow udp from my-subnet to any keep-state :OUTBOUND"
|
||||||
.Dl "ipfw add deny udp from any to any"
|
.Dl "ipfw add deny udp from any to any"
|
||||||
.Pp
|
.Pp
|
||||||
Dynamic rules expire after some time, which depends on the status
|
Dynamic rules expire after some time, which depends on the status
|
||||||
|
@ -1483,7 +1483,7 @@ show_static_rule(struct cmdline_opts *co, struct format_opts *fo,
|
|||||||
cmd->arg1, IPFW_TLV_STATE_NAME);
|
cmd->arg1, IPFW_TLV_STATE_NAME);
|
||||||
else
|
else
|
||||||
ename = NULL;
|
ename = NULL;
|
||||||
bprintf(bp, " %s", ename ? ename: "any");
|
bprintf(bp, " :%s", ename ? ename: "any");
|
||||||
/* avoid printing anything else */
|
/* avoid printing anything else */
|
||||||
flags = HAVE_PROTO | HAVE_SRCIP |
|
flags = HAVE_PROTO | HAVE_SRCIP |
|
||||||
HAVE_DSTIP | HAVE_IP;
|
HAVE_DSTIP | HAVE_IP;
|
||||||
@ -2076,7 +2076,7 @@ show_static_rule(struct cmdline_opts *co, struct format_opts *fo,
|
|||||||
|
|
||||||
case O_KEEP_STATE:
|
case O_KEEP_STATE:
|
||||||
bprintf(bp, " keep-state");
|
bprintf(bp, " keep-state");
|
||||||
bprintf(bp, " %s",
|
bprintf(bp, " :%s",
|
||||||
object_search_ctlv(fo->tstate, cmd->arg1,
|
object_search_ctlv(fo->tstate, cmd->arg1,
|
||||||
IPFW_TLV_STATE_NAME));
|
IPFW_TLV_STATE_NAME));
|
||||||
break;
|
break;
|
||||||
@ -2095,7 +2095,7 @@ show_static_rule(struct cmdline_opts *co, struct format_opts *fo,
|
|||||||
comma = ",";
|
comma = ",";
|
||||||
}
|
}
|
||||||
bprint_uint_arg(bp, " ", c->conn_limit);
|
bprint_uint_arg(bp, " ", c->conn_limit);
|
||||||
bprintf(bp, " %s",
|
bprintf(bp, " :%s",
|
||||||
object_search_ctlv(fo->tstate, cmd->arg1,
|
object_search_ctlv(fo->tstate, cmd->arg1,
|
||||||
IPFW_TLV_STATE_NAME));
|
IPFW_TLV_STATE_NAME));
|
||||||
break;
|
break;
|
||||||
@ -2198,7 +2198,7 @@ show_dyn_state(struct cmdline_opts *co, struct format_opts *fo,
|
|||||||
} else
|
} else
|
||||||
bprintf(bp, " UNKNOWN <-> UNKNOWN");
|
bprintf(bp, " UNKNOWN <-> UNKNOWN");
|
||||||
if (d->kidx != 0)
|
if (d->kidx != 0)
|
||||||
bprintf(bp, " %s", object_search_ctlv(fo->tstate,
|
bprintf(bp, " :%s", object_search_ctlv(fo->tstate,
|
||||||
d->kidx, IPFW_TLV_STATE_NAME));
|
d->kidx, IPFW_TLV_STATE_NAME));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3714,27 +3714,25 @@ compile_rule(char *av[], uint32_t *rbuf, int *rbufsize, struct tidx *tstate)
|
|||||||
case TOK_CHECKSTATE:
|
case TOK_CHECKSTATE:
|
||||||
have_state = action;
|
have_state = action;
|
||||||
action->opcode = O_CHECK_STATE;
|
action->opcode = O_CHECK_STATE;
|
||||||
if (*av == NULL) {
|
if (*av == NULL ||
|
||||||
|
match_token(rule_options, *av) == TOK_COMMENT) {
|
||||||
action->arg1 = pack_object(tstate,
|
action->arg1 = pack_object(tstate,
|
||||||
default_state_name, IPFW_TLV_STATE_NAME);
|
default_state_name, IPFW_TLV_STATE_NAME);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (strcmp(*av, "any") == 0)
|
if (*av[0] == ':') {
|
||||||
action->arg1 = 0;
|
if (strcmp(*av + 1, "any") == 0)
|
||||||
else if ((i = match_token(rule_options, *av)) != -1) {
|
action->arg1 = 0;
|
||||||
action->arg1 = pack_object(tstate,
|
else if (state_check_name(*av + 1) == 0)
|
||||||
default_state_name, IPFW_TLV_STATE_NAME);
|
action->arg1 = pack_object(tstate, *av + 1,
|
||||||
if (i != TOK_COMMENT)
|
IPFW_TLV_STATE_NAME);
|
||||||
warn("Ambiguous state name '%s', '%s'"
|
else
|
||||||
" used instead.\n", *av,
|
errx(EX_DATAERR, "Invalid state name %s",
|
||||||
default_state_name);
|
*av);
|
||||||
|
av++;
|
||||||
break;
|
break;
|
||||||
} else if (state_check_name(*av) == 0)
|
}
|
||||||
action->arg1 = pack_object(tstate, *av,
|
errx(EX_DATAERR, "Invalid state name %s", *av);
|
||||||
IPFW_TLV_STATE_NAME);
|
|
||||||
else
|
|
||||||
errx(EX_DATAERR, "Invalid state name %s", *av);
|
|
||||||
av++;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_ACCEPT:
|
case TOK_ACCEPT:
|
||||||
@ -4577,22 +4575,16 @@ compile_rule(char *av[], uint32_t *rbuf, int *rbufsize, struct tidx *tstate)
|
|||||||
if (have_state)
|
if (have_state)
|
||||||
errx(EX_USAGE, "only one of keep-state "
|
errx(EX_USAGE, "only one of keep-state "
|
||||||
"and limit is allowed");
|
"and limit is allowed");
|
||||||
if (*av == NULL ||
|
if (*av != NULL && *av[0] == ':') {
|
||||||
(i = match_token(rule_options, *av)) != -1) {
|
if (state_check_name(*av + 1) != 0)
|
||||||
if (*av != NULL && i != TOK_COMMENT)
|
|
||||||
warn("Ambiguous state name '%s',"
|
|
||||||
" '%s' used instead.\n", *av,
|
|
||||||
default_state_name);
|
|
||||||
uidx = pack_object(tstate, default_state_name,
|
|
||||||
IPFW_TLV_STATE_NAME);
|
|
||||||
} else {
|
|
||||||
if (state_check_name(*av) != 0)
|
|
||||||
errx(EX_DATAERR,
|
errx(EX_DATAERR,
|
||||||
"Invalid state name %s", *av);
|
"Invalid state name %s", *av);
|
||||||
uidx = pack_object(tstate, *av,
|
uidx = pack_object(tstate, *av + 1,
|
||||||
IPFW_TLV_STATE_NAME);
|
IPFW_TLV_STATE_NAME);
|
||||||
av++;
|
av++;
|
||||||
}
|
} else
|
||||||
|
uidx = pack_object(tstate, default_state_name,
|
||||||
|
IPFW_TLV_STATE_NAME);
|
||||||
have_state = cmd;
|
have_state = cmd;
|
||||||
fill_cmd(cmd, O_KEEP_STATE, 0, uidx);
|
fill_cmd(cmd, O_KEEP_STATE, 0, uidx);
|
||||||
break;
|
break;
|
||||||
@ -4629,22 +4621,16 @@ compile_rule(char *av[], uint32_t *rbuf, int *rbufsize, struct tidx *tstate)
|
|||||||
TOK_LIMIT, rule_options);
|
TOK_LIMIT, rule_options);
|
||||||
av++;
|
av++;
|
||||||
|
|
||||||
if (*av == NULL ||
|
if (*av != NULL && *av[0] == ':') {
|
||||||
(i = match_token(rule_options, *av)) != -1) {
|
if (state_check_name(*av + 1) != 0)
|
||||||
if (*av != NULL && i != TOK_COMMENT)
|
|
||||||
warn("Ambiguous state name '%s',"
|
|
||||||
" '%s' used instead.\n", *av,
|
|
||||||
default_state_name);
|
|
||||||
cmd->arg1 = pack_object(tstate,
|
|
||||||
default_state_name, IPFW_TLV_STATE_NAME);
|
|
||||||
} else {
|
|
||||||
if (state_check_name(*av) != 0)
|
|
||||||
errx(EX_DATAERR,
|
errx(EX_DATAERR,
|
||||||
"Invalid state name %s", *av);
|
"Invalid state name %s", *av);
|
||||||
cmd->arg1 = pack_object(tstate, *av,
|
cmd->arg1 = pack_object(tstate, *av + 1,
|
||||||
IPFW_TLV_STATE_NAME);
|
IPFW_TLV_STATE_NAME);
|
||||||
av++;
|
av++;
|
||||||
}
|
} else
|
||||||
|
cmd->arg1 = pack_object(tstate,
|
||||||
|
default_state_name, IPFW_TLV_STATE_NAME);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user