summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2018-02-06 23:47:48 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2018-02-06 23:47:48 +0000
commit5d2eec1b07dd6e8ecd8634d00b8a2377b1052d7c (patch)
treeb82b1f3717c5b0f1772c368c34f95718689ac6dc
parent59119e8ef80e708ea054d7e292a5382c51b324ee (diff)
allow control over syncookies: set syncookies never/always/adaptive
-rw-r--r--sbin/pfctl/parse.y27
-rw-r--r--sbin/pfctl/pfctl.c64
-rw-r--r--sbin/pfctl/pfctl_parser.h5
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 <v.number> tos not yesno optnodf
%type <v.probability> probability
%type <v.weight> optweight
-%type <v.i> dir af optimizer
+%type <v.i> dir af optimizer syncookie_val
%type <v.i> sourcetrack flush unaryop statelock
%type <v.b> action
%type <v.b> 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);
}
@@ -1900,6 +1915,22 @@ pfctl_load_timeout(struct pfctl *pf, unsigned int timeout, unsigned int seconds)
}
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)
{
pf->reass_set = 1;
@@ -1919,6 +1950,27 @@ pfctl_set_reassembly(struct pfctl *pf, int on, int nodf)
}
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)
{
const struct pf_hint *hint;
@@ -2015,6 +2067,16 @@ pfctl_load_reassembly(struct pfctl *pf, u_int32_t reassembly)
}
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)
{
u_int32_t level;
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 *);