diff options
author | Daniel Hartmeier <dhartmei@cvs.openbsd.org> | 2002-12-07 23:15:54 +0000 |
---|---|---|
committer | Daniel Hartmeier <dhartmei@cvs.openbsd.org> | 2002-12-07 23:15:54 +0000 |
commit | 04687a0f2a63058952d297a64ed858f47e599a1b (patch) | |
tree | 087e79fa1ec2f758af287bf5e5102edba20320b0 | |
parent | 9e65e9c7a51ead19884940883947ed2a15905408 (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.y | 65 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_parser.c | 63 | ||||
-rw-r--r-- | share/man/man5/pf.conf.5 | 32 |
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, |