From 6dce935d778a69e00f7a0b19748c7682336dc325 Mon Sep 17 00:00:00 2001 From: henning Date: Tue, 6 Feb 2018 23:47:47 +0000 Subject: [PATCH] allow control over syncookies: set syncookies never/always/adaptive --- sbin/pfctl/parse.y | 27 +++++++++++++++-- sbin/pfctl/pfctl.c | 64 ++++++++++++++++++++++++++++++++++++++- sbin/pfctl/pfctl_parser.h | 5 ++- 3 files changed, 91 insertions(+), 5 deletions(-) diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index 06615c985ce..6e20794156e 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.668 2017/11/28 16:05:46 bluhm Exp $ */ +/* $OpenBSD: parse.y,v 1.669 2018/02/06 23:47:47 henning Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -468,7 +468,7 @@ int parseport(char *, struct range *r, int); %token ICMP6TYPE CODE KEEP MODULATE STATE PORT BINATTO NODF %token MINTTL ERROR ALLOWOPTS FILENAME ROUTETO DUPTO REPLYTO NO LABEL %token NOROUTE URPFFAILED FRAGMENT USER GROUP MAXMSS MAXIMUM TTL TOS DROP TABLE -%token REASSEMBLE ANCHOR +%token REASSEMBLE ANCHOR SYNCOOKIES %token SET OPTIMIZATION TIMEOUT LIMIT LOGINTERFACE BLOCKPOLICY RANDOMID %token SYNPROXY FINGERPRINTS NOSYNC DEBUG SKIP HOSTID %token ANTISPOOF FOR INCLUDE MATCHES @@ -488,7 +488,7 @@ int parseport(char *, struct range *r, int); %type tos not yesno optnodf %type probability %type optweight -%type dir af optimizer +%type dir af optimizer syncookie_val %type sourcetrack flush unaryop statelock %type action %type flags flag blockspec prio @@ -686,6 +686,26 @@ option : SET REASSEMBLE yesno optnodf { } keep_state_defaults = $3; } + | SET SYNCOOKIES syncookie_val { + if (pfctl_set_syncookies(pf, $3)) { + yyerror("error setting syncookies"); + YYERROR; + } + } + ; + +syncookie_val : STRING { + if (!strcmp($1, "never")) + $$ = PF_SYNCOOKIES_NEVER; + else if (!strcmp($1, "adaptive")) + $$ = PF_SYNCOOKIES_ADAPTIVE; + else if (!strcmp($1, "always")) + $$ = PF_SYNCOOKIES_ALWAYS; + else { + yyerror("illegal value for syncookies"); + YYERROR; + } + } ; stringall : STRING { $$ = $1; } @@ -5148,6 +5168,7 @@ lookup(char *s) { "state-policy", STATEPOLICY}, { "static-port", STATICPORT}, { "sticky-address", STICKYADDRESS}, + { "syncookies", SYNCOOKIES}, { "synproxy", SYNPROXY}, { "table", TABLE}, { "tag", TAG}, diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c index 6c66aa5bb25..20df20f91b8 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl.c,v 1.351 2017/11/25 22:26:25 sashan Exp $ */ +/* $OpenBSD: pfctl.c,v 1.352 2018/02/06 23:47:47 henning Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -81,6 +81,8 @@ int pfctl_load_debug(struct pfctl *, unsigned int); int pfctl_load_logif(struct pfctl *, char *); int pfctl_load_hostid(struct pfctl *, unsigned int); int pfctl_load_reassembly(struct pfctl *, u_int32_t); +int pfctl_load_syncookies(struct pfctl *, u_int8_t); +int pfctl_set_synflwats(struct pfctl *, u_int32_t, u_int32_t); void pfctl_print_rule_counters(struct pf_rule *, int); int pfctl_show_rules(int, char *, int, enum pfctl_show, char *, int, int, long); @@ -1791,6 +1793,15 @@ pfctl_load_options(struct pfctl *pf) pf->timeout_set[PFTM_ADAPTIVE_END] = 1; } + /* + * if the states limit has been set adjust the synflood detection + * hiwat and lowat. Eventually they should be tunables. + */ + if (pf->limit_set[PF_LIMIT_STATES]) + if (pfctl_set_synflwats(pf, pf->limit[PF_LIMIT_STATES] / 8, + pf->limit[PF_LIMIT_STATES] / 4)) + error = 1; + /* load timeouts */ for (i = 0; i < PFTM_MAX; i++) if (pfctl_load_timeout(pf, i, pf->timeout[i])) @@ -1812,6 +1823,10 @@ pfctl_load_options(struct pfctl *pf) if (pf->reass_set && pfctl_load_reassembly(pf, pf->reassemble)) error = 1; + /* load syncookies settings */ + if (pf->syncookies_set && pfctl_load_syncookies(pf, pf->syncookies)) + error = 1; + return (error); } @@ -1899,6 +1914,22 @@ pfctl_load_timeout(struct pfctl *pf, unsigned int timeout, unsigned int seconds) return (0); } +int +pfctl_set_synflwats(struct pfctl *pf, u_int32_t lowat, u_int32_t hiwat) +{ + struct pfioc_synflwats ps; + + memset(&ps, 0, sizeof(ps)); + ps.hiwat = hiwat; + ps.lowat = lowat; + + if (ioctl(pf->dev, DIOCSETSYNFLWATS, &ps)) { + warnx("Cannot set synflood detection watermarks"); + return (1); + } + return (0); +} + int pfctl_set_reassembly(struct pfctl *pf, int on, int nodf) { @@ -1918,6 +1949,27 @@ pfctl_set_reassembly(struct pfctl *pf, int on, int nodf) return (0); } +int +pfctl_set_syncookies(struct pfctl *pf, u_int8_t val) +{ + if (pf->opts & PF_OPT_VERBOSE) { + if (val == PF_SYNCOOKIES_NEVER) + printf("set syncookies never\n"); + else if (val == PF_SYNCOOKIES_ALWAYS) + printf("set syncookies always\n"); + else if (val == PF_SYNCOOKIES_ADAPTIVE) + printf("set syncookies adaptive\n"); + else { /* cannot happen */ + warnx("king bula ate all syncookies"); + return (1); + } + } + + pf->syncookies_set = 1; + pf->syncookies = val; + return (0); +} + int pfctl_set_optimization(struct pfctl *pf, const char *opt) { @@ -2014,6 +2066,16 @@ pfctl_load_reassembly(struct pfctl *pf, u_int32_t reassembly) return (0); } +int +pfctl_load_syncookies(struct pfctl *pf, u_int8_t val) +{ + if (ioctl(dev, DIOCSETSYNCOOKIES, &val)) { + warnx("DIOCSETSYNCOOKIES"); + return (1); + } + return (0); +} + int pfctl_set_debug(struct pfctl *pf, char *d) { diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h index 08539b1f9ed..9c301841160 100644 --- a/sbin/pfctl/pfctl_parser.h +++ b/sbin/pfctl/pfctl_parser.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_parser.h,v 1.107 2017/11/25 22:20:06 sashan Exp $ */ +/* $OpenBSD: pfctl_parser.h,v 1.108 2018/02/06 23:47:47 henning Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -91,6 +91,7 @@ struct pfctl { u_int32_t debug; u_int32_t hostid; u_int32_t reassemble; + u_int8_t syncookies; char *ifname; u_int8_t timeout_set[PFTM_MAX]; @@ -99,6 +100,7 @@ struct pfctl { u_int8_t hostid_set; u_int8_t ifname_set; u_int8_t reass_set; + u_int8_t syncookies_set; }; struct node_if { @@ -215,6 +217,7 @@ void pfctl_clear_pool(struct pf_pool *); int pfctl_set_timeout(struct pfctl *, const char *, int, int); int pfctl_set_reassembly(struct pfctl *, int, int); +int pfctl_set_syncookies(struct pfctl *, u_int8_t); int pfctl_set_optimization(struct pfctl *, const char *); int pfctl_set_limit(struct pfctl *, const char *, unsigned int); int pfctl_set_logif(struct pfctl *, char *); -- 2.20.1