summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Hartmeier <dhartmei@cvs.openbsd.org>2002-12-07 23:15:54 +0000
committerDaniel Hartmeier <dhartmei@cvs.openbsd.org>2002-12-07 23:15:54 +0000
commit04687a0f2a63058952d297a64ed858f47e599a1b (patch)
tree087e79fa1ec2f758af287bf5e5102edba20320b0
parent9e65e9c7a51ead19884940883947ed2a15905408 (diff)
Support parameters in anchor rules. Allows conditional evaluation, like:
anchor spews inet proto tcp from any to any port smtp ok deraadt
-rw-r--r--sbin/pfctl/parse.y65
-rw-r--r--sbin/pfctl/pfctl_parser.c63
-rw-r--r--share/man/man5/pf.conf.532
3 files changed, 118 insertions, 42 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 41880db6888..22674667ef0 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.243 2002/12/07 21:20:23 henning Exp $ */
+/* $OpenBSD: parse.y,v 1.244 2002/12/07 23:15:53 dhartmei Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -465,29 +465,68 @@ varset : STRING PORTUNARY string {
}
;
-anchorrule : ANCHOR string {
+anchorrule : ANCHOR string dir interface af proto fromto {
struct pf_rule r;
+ if (check_rulestate(PFCTL_STATE_FILTER))
+ YYERROR;
+
PREPARE_ANCHOR_RULE(r, $2);
- r.nr = pf->rule_nr++;
- pfctl_add_rule(pf, &r);
+
+ r.direction = $3;
+ r.af = $5;
+
+ decide_address_family($7.src.host, &r.af);
+ decide_address_family($7.dst.host, &r.af);
+
+ expand_rule(&r, $4, NULL, $6,
+ $7.src.host, $7.src.port, $7.dst.host, $7.dst.port,
+ 0, 0, 0);
}
- | NATANCHOR string {
+ | NATANCHOR string interface af proto fromto {
struct pf_nat r;
+ if (check_rulestate(PFCTL_STATE_NAT))
+ YYERROR;
+
PREPARE_ANCHOR_RULE(r, $2);
- pfctl_add_nat(pf, &r);
+
+ r.af = $4;
+
+ decide_address_family($6.src.host, &r.af);
+ decide_address_family($6.dst.host, &r.af);
+
+ expand_nat(&r, $3, $5, $6.src.host, $6.src.port,
+ $6.dst.host, $6.dst.port, NULL);
}
- | RDRANCHOR string {
+ | RDRANCHOR string interface af proto fromto {
struct pf_rdr r;
+ if (check_rulestate(PFCTL_STATE_NAT))
+ YYERROR;
+
PREPARE_ANCHOR_RULE(r, $2);
- pfctl_add_rdr(pf, &r);
+
+ r.af = $4;
+
+ decide_address_family($6.src.host, &r.af);
+ decide_address_family($6.dst.host, &r.af);
+
+ expand_rdr(&r, $3, $5, $6.src.host, $6.dst.host, NULL);
}
- | BINATANCHOR string {
+ | BINATANCHOR string interface af proto fromto {
struct pf_binat r;
+ if (check_rulestate(PFCTL_STATE_NAT))
+ YYERROR;
+
PREPARE_ANCHOR_RULE(r, $2);
+
+ r.af = $4;
+
+ decide_address_family($6.src.host, &r.af);
+ decide_address_family($6.dst.host, &r.af);
+
pfctl_add_binat(pf, &r);
}
;
@@ -1133,7 +1172,13 @@ proto_item : STRING {
}
;
-fromto : ALL {
+fromto : /* empty */ {
+ $$.src.host = NULL;
+ $$.src.port = NULL;
+ $$.dst.host = NULL;
+ $$.dst.port = NULL;
+ }
+ | ALL {
$$.src.host = NULL;
$$.src.port = NULL;
$$.dst.host = NULL;
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
index 58b4a7d486a..08eeef41a96 100644
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_parser.c,v 1.119 2002/12/07 20:25:40 henning Exp $ */
+/* $OpenBSD: pfctl_parser.c,v 1.120 2002/12/07 23:15:53 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -471,13 +471,13 @@ print_pool(struct pf_pool *pool, u_int16_t p1, u_int16_t p2,
void
print_nat(struct pf_nat *n)
{
- if (n->anchorname[0]) {
- printf("nat-anchor %s\n", n->anchorname);
- return;
+ if (n->anchorname[0])
+ printf("nat-anchor %s ", n->anchorname);
+ else {
+ if (n->no)
+ printf("no ");
+ printf("nat ");
}
- if (n->no)
- printf("no ");
- printf("nat ");
if (n->ifname[0]) {
printf("on ");
if (n->ifnot)
@@ -499,7 +499,7 @@ print_nat(struct pf_nat *n)
printf("proto %u ", n->proto);
}
print_fromto(&n->src, &n->dst, n->af, n->proto);
- if (!n->no) {
+ if (!n->anchorname[0] && !n->no) {
printf("-> ");
print_pool(&n->rpool, n->proxy_port[0], n->proxy_port[1],
n->af, PF_POOL_NAT_R);
@@ -510,13 +510,13 @@ print_nat(struct pf_nat *n)
void
print_binat(struct pf_binat *b)
{
- if (b->anchorname[0]) {
- printf("binat-anchor %s\n", b->anchorname);
- return;
+ if (b->anchorname[0])
+ printf("binat-anchor %s ", b->anchorname);
+ else {
+ if (b->no)
+ printf("no ");
+ printf("binat ");
}
- if (b->no)
- printf("no ");
- printf("binat ");
if (b->ifname[0]) {
printf("on ");
printf("%s ", b->ifname);
@@ -536,8 +536,12 @@ print_binat(struct pf_binat *b)
printf("proto %u ", b->proto);
}
printf("from ");
- print_addr(&b->saddr, b->af);
- printf(" ");
+ if (!PF_AZERO(&b->saddr.addr, b->af) ||
+ !PF_AZERO(&b->saddr.mask, b->af)) {
+ print_addr(&b->saddr, b->af);
+ printf(" ");
+ } else
+ printf("any ");
printf("to ");
if (!PF_AZERO(&b->daddr.addr, b->af) ||
!PF_AZERO(&b->daddr.mask, b->af)) {
@@ -547,7 +551,7 @@ print_binat(struct pf_binat *b)
printf(" ");
} else
printf("any ");
- if (!b->no) {
+ if (!b->anchorname[0] && !b->no) {
printf("-> ");
print_addr(&b->raddr, b->af);
}
@@ -557,13 +561,13 @@ print_binat(struct pf_binat *b)
void
print_rdr(struct pf_rdr *r)
{
- if (r->anchorname[0]) {
- printf("rdr-anchor %s\n", r->anchorname);
- return;
+ if (r->anchorname[0])
+ printf("rdr-anchor %s ", r->anchorname);
+ else {
+ if (r->no)
+ printf("no ");
+ printf("rdr ");
}
- if (r->no)
- printf("no ");
- printf("rdr ");
if (r->ifname[0]) {
printf("on ");
if (r->ifnot)
@@ -608,7 +612,7 @@ print_rdr(struct pf_rdr *r)
printf(":%u", ntohs(r->dport2));
printf(" ");
}
- if (!r->no) {
+ if (!r->anchorname[0] && !r->no) {
printf("-> ");
print_pool(&r->rpool, r->rport, r->opts, r->af, PF_POOL_RDR_R);
}
@@ -705,11 +709,9 @@ print_rule(struct pf_rule *r, int verbose)
if (verbose)
printf("@%d ", r->nr);
- if (r->anchorname[0]) {
- printf("anchor %s\n", r->anchorname);
- return;
- }
- if (r->action == PF_PASS)
+ if (r->anchorname[0])
+ printf("anchor %s ", r->anchorname);
+ else if (r->action == PF_PASS)
printf("pass ");
else if (r->action == PF_DROP) {
printf("block ");
@@ -757,9 +759,8 @@ print_rule(struct pf_rule *r, int verbose)
}
} else
printf("drop ");
- } else {
+ } else
printf("scrub ");
- }
if (r->direction == PF_IN)
printf("in ");
else if (r->direction == PF_OUT)
diff --git a/share/man/man5/pf.conf.5 b/share/man/man5/pf.conf.5
index 695b0caa933..c623906044e 100644
--- a/share/man/man5/pf.conf.5
+++ b/share/man/man5/pf.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: pf.conf.5,v 1.139 2002/12/07 22:58:40 deraadt Exp $
+.\" $OpenBSD: pf.conf.5,v 1.140 2002/12/07 23:15:53 dhartmei Exp $
.\"
.\" Copyright (c) 2002, Daniel Hartmeier
.\" All rights reserved.
@@ -1344,10 +1344,40 @@ incoming connections to port 25.
Then
.Bd -literal
# echo "block in quick from 1.2.3.4 to any" | pfctl -a spews:manual -f -
+.Ed
.Pp
loads a single rule set containing a single rule into the
.Pa anchor ,
which blocks all packets from a specific address.
+.Pp
+Optionally,
+.Pa anchor
+rules can specify the parameters
+direction, interface, address family, protocol and source/destination
+address/port
+using the same syntax as filter rules.
+When parameters are used, the
+.Pa anchor
+rule is only evaluated for matching packets.
+This allows conditional evaluation of named rule sets, like:
+.Bd -literal
+ block on $ext_if all
+ anchor spews proto tcp from any to any port smtp
+ pass out on $ext_if all keep state
+ pass in on $ext_if proto tcp from any to $ext_if port smtp keep state
+.Ed
+.Pp
+The rules inside
+.Pa anchor
+spews are only evaluated for
+.Pa tcp
+packets with destination port 25.
+Hence,
+.Bd -literal
+ # echo "block in quick from 1.2.3.4 to any" | pfctl -a spews:manual -f -
+.Ed
+.Pp
+will only block connections from 1.2.3.4 to port 25.
.Sh TRANSLATION EXAMPLES
This example maps incoming requests on port 80 to port 8080, on
which Apache Tomcat is running (say Tomcat is not run as root,