On Fri, Aug 11, 2017 at 06:05:09PM +0200, Sebastian Benoit wrote: > Hi, > > this adds a -N option to pfctl that turns of dns resolution for all the > things where a dns entry is a possible thing, i.e. in rules ("pass in from > www.openbsd.org") or table entries. > > Its usefull to make sure the configuration will load when DNS is not > available. >
While I don't like adding knobs I have been convinced of the operational need and the need to not break installed sytems (however fragile they might be). The diff reads OK > ok? > > > diff --git regress/sbin/pfctl/Makefile regress/sbin/pfctl/Makefile > index ff9c38e28a8..80364b8ba14 100644 > --- regress/sbin/pfctl/Makefile > +++ regress/sbin/pfctl/Makefile > @@ -29,6 +29,7 @@ PFOPT=1 2 6 > PFIF2IP=1 2 3 > PFCHKSUM=1 2 3 > PFCMD=1 > +PFCMDFAIL=1 > > MAKEOBJDIRPREFIX= > > @@ -252,6 +253,32 @@ REGRESS_TARGETS+=pfcmd > REGRESS_ROOT_TARGETS+=pfcmd > UPDATE_TARGETS+=pfcmd-update > > +.for n in ${PFCMDFAIL} > +PFCMDFAIL_TARGETS+=pfcmdfail${n} > +PFCMDFAIL_UPDATES+=pfcmdfail${n}-update > + > +pfcmdfail${n}: > + ${SUDO} pfctl `cat ${.CURDIR}/pfcmdfail${n}.opts` \ > + -f - < ${.CURDIR}/pfcmdfail${n}.in 2>&1 | \ > + diff -u ${.CURDIR}/pfcmdfail${n}.ok /dev/stdin > + > +pfcmdfail${n}-update: > + if ${SUDO} pfctl `cat ${.CURDIR}/pfcmdfail${n}.opts` \ > + -f - < ${.CURDIR}/pfcmdfail${n}.in > \ > + ${.CURDIR}/pfcmdfail${n}.ok 2>&1; then \ > + true; \ > + fi; > + > +.endfor > + > +pfcmdfail: ${PFCMDFAIL_TARGETS} > +pfcmdfail-update: ${PFCMDFAIL_UPDATES} > +NODEFAULT_TARGETS+=pfcmdfail > +REGRESS_TARGETS+=pfcmdfail > + > +REGRESS_ROOT_TARGETS+=pfcmd > +UPDATE_TARGETS+=pfcmd-update > + > .for n in ${PFSETUP} > PFSETUP_TARGETS+=pfsetup${n} > PFSETUP_UPDATES+=pfsetup${n}-update > diff --git regress/sbin/pfctl/pfcmd2.out regress/sbin/pfctl/pfcmd2.out > new file mode 100644 > index 00000000000..e991e53a580 > --- /dev/null > +++ regress/sbin/pfctl/pfcmd2.out > @@ -0,0 +1,2 @@ > +no IP address found for localhost > +pfcmd2.in:1: could not parse host specification > diff --git regress/sbin/pfctl/pfcmdfail1.in regress/sbin/pfctl/pfcmdfail1.in > new file mode 100644 > index 00000000000..68d5b071164 > --- /dev/null > +++ regress/sbin/pfctl/pfcmdfail1.in > @@ -0,0 +1 @@ > +pass in from localhost > diff --git regress/sbin/pfctl/pfcmdfail1.ok regress/sbin/pfctl/pfcmdfail1.ok > new file mode 100644 > index 00000000000..011baa3283d > --- /dev/null > +++ regress/sbin/pfctl/pfcmdfail1.ok > @@ -0,0 +1,2 @@ > +no IP address found for localhost > +stdin:1: could not parse host specification > diff --git regress/sbin/pfctl/pfcmdfail1.opts > regress/sbin/pfctl/pfcmdfail1.opts > new file mode 100644 > index 00000000000..b641baefa31 > --- /dev/null > +++ regress/sbin/pfctl/pfcmdfail1.opts > @@ -0,0 +1 @@ > +-nN > diff --git sbin/pfctl/parse.y sbin/pfctl/parse.y > index 5ae134e04a2..0cbb2d651be 100644 > --- sbin/pfctl/parse.y > +++ sbin/pfctl/parse.y > @@ -342,7 +342,7 @@ int disallow_table(struct node_host *, > const char *); > int disallow_urpf_failed(struct node_host *, const char *); > int disallow_alias(struct node_host *, const char *); > int rule_consistent(struct pf_rule *, int); > -int process_tabledef(char *, struct table_opts *); > +int process_tabledef(char *, struct table_opts *, int); > void expand_label_str(char *, size_t, const char *, const char *); > void expand_label_if(const char *, char *, size_t, const char *); > void expand_label_addr(const char *, char *, size_t, u_int8_t, > @@ -1176,7 +1176,7 @@ tabledef : TABLE '<' STRING '>' table_opts { > free($3); > YYERROR; > } > - if (process_tabledef($3, &$5)) { > + if (process_tabledef($3, &$5, pf->opts)) { > free($3); > YYERROR; > } > @@ -2035,7 +2035,7 @@ filter_opt : USER uids { > filter_opts.rtableid = $2; > } > | DIVERTTO STRING PORT portplain { > - if ((filter_opts.divert.addr = host($2)) == NULL) { > + if ((filter_opts.divert.addr = host($2, pf->opts)) == > NULL) { > yyerror("could not parse divert address: %s", > $2); > free($2); > @@ -2670,7 +2670,7 @@ optweight : WEIGHT NUMBER { > ; > > host : STRING { > - if (($$ = host($1)) == NULL) { > + if (($$ = host($1, pf->opts)) == NULL) { > /* error. "any" is handled elsewhere */ > free($1); > yyerror("could not parse host specification"); > @@ -2682,7 +2682,8 @@ host : STRING { > | STRING '-' STRING { > struct node_host *b, *e; > > - if ((b = host($1)) == NULL || (e = host($3)) == NULL) { > + if ((b = host($1, pf->opts)) == NULL || > + (e = host($3, pf->opts)) == NULL) { > free($1); > free($3); > yyerror("could not parse host specification"); > @@ -2718,7 +2719,7 @@ host : STRING { > if (asprintf(&buf, "%s/%lld", $1, $3) == -1) > err(1, "host: asprintf"); > free($1); > - if (($$ = host(buf)) == NULL) { > + if (($$ = host(buf, pf->opts)) == NULL) { > /* error. "any" is handled elsewhere */ > free(buf); > yyerror("could not parse host specification"); > @@ -2732,7 +2733,7 @@ host : STRING { > /* ie. for 10/8 parsing */ > if (asprintf(&buf, "%lld/%lld", $1, $3) == -1) > err(1, "host: asprintf"); > - if (($$ = host(buf)) == NULL) { > + if (($$ = host(buf, pf->opts)) == NULL) { > /* error. "any" is handled elsewhere */ > free(buf); > yyerror("could not parse host specification"); > @@ -3722,7 +3723,7 @@ pool_opt : BITMASK { > route_host : STRING { > /* try to find @if0 address specs */ > if (strrchr($1, '@') != NULL) { > - if (($$ = host($1)) == NULL) { > + if (($$ = host($1, pf->opts)) == NULL) { > yyerror("invalid host for route spec"); > YYERROR; > } > @@ -3744,7 +3745,7 @@ route_host : STRING { > if (asprintf(&buf, "%s/%s", $1, $3) == -1) > err(1, "host: asprintf"); > free($1); > - if (($$ = host(buf)) == NULL) { > + if (($$ = host(buf, pf->opts)) == NULL) { > /* error. "any" is handled elsewhere */ > free(buf); > yyerror("could not parse host specification"); > @@ -4080,7 +4081,7 @@ rule_consistent(struct pf_rule *r, int anchor_call) > } > > int > -process_tabledef(char *name, struct table_opts *opts) > +process_tabledef(char *name, struct table_opts *opts, int popts) > { > struct pfr_buffer ab; > struct node_tinit *ti; > @@ -4089,7 +4090,7 @@ process_tabledef(char *name, struct table_opts *opts) > ab.pfrb_type = PFRB_ADDRS; > SIMPLEQ_FOREACH(ti, &opts->init_nodes, entries) { > if (ti->file) > - if (pfr_buf_load(&ab, ti->file, 0)) { > + if (pfr_buf_load(&ab, ti->file, 0, popts)) { > if (errno) > yyerror("cannot load \"%s\": %s", > ti->file, strerror(errno)); > diff --git sbin/pfctl/pfctl.8 sbin/pfctl/pfctl.8 > index bd9afd75eaa..7ce6521f13e 100644 > --- sbin/pfctl/pfctl.8 > +++ sbin/pfctl/pfctl.8 > @@ -33,7 +33,7 @@ > .Sh SYNOPSIS > .Nm pfctl > .Bk -words > -.Op Fl deghnPqrvz > +.Op Fl deghNnPqrvz > .Op Fl a Ar anchor > .Op Fl D Ar macro Ns = Ns Ar value > .Op Fl F Ar modifier > @@ -282,6 +282,9 @@ firewall with hostid 00000002 use: > .It Fl L Ar statefile > Load pf states from the file specified by > .Ar statefile . > +.It Fl N > +No name resolution will be performed. > +If a name cannot be resolved without DNS, an error will be reported. > .It Fl n > Do not actually load rules, just parse them. > .It Fl o Ar level > diff --git sbin/pfctl/pfctl.c sbin/pfctl/pfctl.c > index 281cd939c6e..122797633bd 100644 > --- sbin/pfctl/pfctl.c > +++ sbin/pfctl/pfctl.c > @@ -2238,7 +2238,7 @@ main(int argc, char *argv[]) > usage(); > > while ((ch = getopt(argc, argv, > - "a:dD:eqf:F:ghi:k:K:L:no:Pp:R:rS:s:t:T:vV:x:z")) != -1) { > + "a:dD:eqf:F:ghi:k:K:L:Nno:Pp:R:rS:s:t:T:vV:x:z")) != -1) { > switch (ch) { > case 'a': > anchoropt = optarg; > @@ -2288,6 +2288,9 @@ main(int argc, char *argv[]) > src_node_kill[src_node_killers++] = optarg; > mode = O_RDWR; > break; > + case 'N': > + opts |= PF_OPT_NODNS; > + break; > case 'n': > opts |= PF_OPT_NOACTION; > break; > diff --git sbin/pfctl/pfctl.h sbin/pfctl/pfctl.h > index 4a276998eb7..1955a7d0f5d 100644 > --- sbin/pfctl/pfctl.h > +++ sbin/pfctl/pfctl.h > @@ -69,7 +69,7 @@ void pfr_buf_clear(struct pfr_buffer *); > int pfr_buf_add(struct pfr_buffer *, const void *); > void *pfr_buf_next(struct pfr_buffer *, const void *); > int pfr_buf_grow(struct pfr_buffer *, int); > -int pfr_buf_load(struct pfr_buffer *, char *, int); > +int pfr_buf_load(struct pfr_buffer *, char *, int, int); > char *pfr_strerror(int); > int pfi_get_ifaces(const char *, struct pfi_kif *, int *); > int pfi_clr_istats(const char *, int *, int); > diff --git sbin/pfctl/pfctl_parser.c sbin/pfctl/pfctl_parser.c > index 6844c29c9fe..33b56f8d785 100644 > --- sbin/pfctl/pfctl_parser.c > +++ sbin/pfctl/pfctl_parser.c > @@ -76,7 +76,7 @@ struct node_host *ifa_grouplookup(const char *, int); > struct node_host *host_if(const char *, int); > struct node_host *host_v4(const char *, int); > struct node_host *host_v6(const char *, int); > -struct node_host *host_dns(const char *, int, int); > +struct node_host *host_dns(const char *, int, int, int); > > const char *tcpflags = "FSRPAUEW"; > > @@ -1609,7 +1609,7 @@ ifa_skip_if(const char *filter, struct node_host *p) > } > > struct node_host * > -host(const char *s) > +host(const char *s, int opts) > { > struct node_host *h = NULL, *n; > int mask = -1, v4mask = 32, v6mask = 128, cont = 1; > @@ -1653,7 +1653,8 @@ host(const char *s) > cont = 0; > > /* dns lookup */ > - if (cont && (h = host_dns(ps, v4mask, v6mask)) != NULL) > + if (cont && (h = host_dns(ps, v4mask, v6mask, > + (opts & PF_OPT_NODNS))) != NULL) > cont = 0; > > if (if_name && if_name[0]) > @@ -1779,7 +1780,7 @@ host_v6(const char *s, int mask) > } > > struct node_host * > -host_dns(const char *s, int v4mask, int v6mask) > +host_dns(const char *s, int v4mask, int v6mask, int numeric) > { > struct addrinfo hints, *res0, *res; > struct node_host *n, *h = NULL; > @@ -1796,6 +1797,8 @@ host_dns(const char *s, int v4mask, int v6mask) > memset(&hints, 0, sizeof(hints)); > hints.ai_family = PF_UNSPEC; > hints.ai_socktype = SOCK_STREAM; /* DUMMY */ > + if (numeric) > + hints.ai_flags = AI_NUMERICHOST; > error = getaddrinfo(ps, NULL, &hints, &res0); > if (error) { > free(ps); > @@ -1859,7 +1862,7 @@ host_dns(const char *s, int v4mask, int v6mask) > * if set to 1, only simple addresses are accepted (no netblock, no "!"). > */ > int > -append_addr(struct pfr_buffer *b, char *s, int test) > +append_addr(struct pfr_buffer *b, char *s, int test, int opts) > { > static int previous = 0; > static int expect = 0; > @@ -1899,7 +1902,7 @@ append_addr(struct pfr_buffer *b, char *s, int test) > > for (r = s; *r == '!'; r++) > not = !not; > - if ((n = host(r)) == NULL) { > + if ((n = host(r, opts)) == NULL) { > errno = 0; > return (-1); > } > diff --git sbin/pfctl/pfctl_parser.h sbin/pfctl/pfctl_parser.h > index 89d9fc4d2d4..803794d5c82 100644 > --- sbin/pfctl/pfctl_parser.h > +++ sbin/pfctl/pfctl_parser.h > @@ -48,6 +48,7 @@ > #define PF_OPT_DEBUG 0x0200 > #define PF_OPT_SHOWALL 0x0400 > #define PF_OPT_OPTIMIZE 0x0800 > +#define PF_OPT_NODNS 0x1000 > #define PF_OPT_RECURSE 0x4000 > #define PF_OPT_PORTNAMES 0x8000 > > @@ -280,9 +281,9 @@ unsigned int ifa_nametoindex(const char *); > char *ifa_indextoname(unsigned int, char *); > struct node_host *ifa_exists(const char *); > struct node_host *ifa_lookup(const char *, int); > -struct node_host *host(const char *); > +struct node_host *host(const char *, int); > > -int append_addr(struct pfr_buffer *, char *, int); > +int append_addr(struct pfr_buffer *, char *, int, int); > int append_addr_host(struct pfr_buffer *, > struct node_host *, int, int); > > diff --git sbin/pfctl/pfctl_radix.c sbin/pfctl/pfctl_radix.c > index a43c469e40f..a07f01bcf78 100644 > --- sbin/pfctl/pfctl_radix.c > +++ sbin/pfctl/pfctl_radix.c > @@ -496,7 +496,7 @@ pfr_buf_clear(struct pfr_buffer *b) > } > > int > -pfr_buf_load(struct pfr_buffer *b, char *file, int nonetwork) > +pfr_buf_load(struct pfr_buffer *b, char *file, int nonetwork, int opts) > { > FILE *fp; > char buf[BUF_SIZE]; > @@ -513,7 +513,7 @@ pfr_buf_load(struct pfr_buffer *b, char *file, int > nonetwork) > return (-1); > } > while ((rv = pfr_next_token(buf, fp)) == 1) > - if ((ev = append_addr(b, buf, nonetwork)) == -1) { > + if ((ev = append_addr(b, buf, nonetwork, opts)) == -1) { > rv = -1; > break; > } > diff --git sbin/pfctl/pfctl_table.c sbin/pfctl/pfctl_table.c > index 0e2f81d888e..9308bbcea9b 100644 > --- sbin/pfctl/pfctl_table.c > +++ sbin/pfctl/pfctl_table.c > @@ -58,7 +58,7 @@ static int pfctl_table(int, char *[], char *, const char > *, char *, > const char *, int); > static void print_table(struct pfr_table *, int, int); > static void print_tstats(struct pfr_tstats *, int); > -static int load_addr(struct pfr_buffer *, int, char *[], char *, int); > +static int load_addr(struct pfr_buffer *, int, char *[], char *, int, int); > static void print_addrx(struct pfr_addr *, struct pfr_addr *, int); > static void print_astats(struct pfr_astats *, int); > static void radix_perror(void); > @@ -199,7 +199,7 @@ pfctl_table(int argc, char *argv[], char *tname, const > char *command, > xprintf(opts, "%d addresses deleted", ndel); > } else if (!strcmp(command, "add")) { > b.pfrb_type = PFRB_ADDRS; > - if (load_addr(&b, argc, argv, file, 0)) > + if (load_addr(&b, argc, argv, file, 0, opts)) > goto _error; > CREATE_TABLE; > if (opts & PF_OPT_VERBOSE) > @@ -214,7 +214,7 @@ pfctl_table(int argc, char *argv[], char *tname, const > char *command, > opts & PF_OPT_USEDNS); > } else if (!strcmp(command, "delete")) { > b.pfrb_type = PFRB_ADDRS; > - if (load_addr(&b, argc, argv, file, 0)) > + if (load_addr(&b, argc, argv, file, 0, opts)) > goto _error; > if (opts & PF_OPT_VERBOSE) > flags |= PFR_FLAG_FEEDBACK; > @@ -228,7 +228,7 @@ pfctl_table(int argc, char *argv[], char *tname, const > char *command, > opts & PF_OPT_USEDNS); > } else if (!strcmp(command, "replace")) { > b.pfrb_type = PFRB_ADDRS; > - if (load_addr(&b, argc, argv, file, 0)) > + if (load_addr(&b, argc, argv, file, 0, opts)) > goto _error; > CREATE_TABLE; > if (opts & PF_OPT_VERBOSE) > @@ -321,7 +321,7 @@ pfctl_table(int argc, char *argv[], char *tname, const > char *command, > b.pfrb_type = PFRB_ADDRS; > b2.pfrb_type = PFRB_ADDRS; > > - if (load_addr(&b, argc, argv, file, 1)) > + if (load_addr(&b, argc, argv, file, 1, opts)) > goto _error; > if (opts & PF_OPT_VERBOSE2) { > flags |= PFR_FLAG_REPLACE; > @@ -413,11 +413,11 @@ print_tstats(struct pfr_tstats *ts, int debug) > > int > load_addr(struct pfr_buffer *b, int argc, char *argv[], char *file, > - int nonetwork) > + int nonetwork, int opts) > { > int ev = 0; > while (argc--) > - if ((ev = append_addr(b, *argv++, nonetwork)) == -1) { > + if ((ev = append_addr(b, *argv++, nonetwork, opts)) == -1) { > if (errno) > warn("cannot decode %s", argv[-1]); > return (-1); > @@ -426,7 +426,7 @@ load_addr(struct pfr_buffer *b, int argc, char *argv[], > char *file, > warnx("failed to decode %s", argv[-1]); > return (-1); > } > - if (pfr_buf_load(b, file, nonetwork)) { > + if (pfr_buf_load(b, file, nonetwork, opts)) { > warn("cannot load %s", file); > return (-1); > } > -- I'm not entirely sure you are real.