Date: Sat, 24 Sep 2022 15:32:50 +0200 From: Kristof Provost <kp@FreeBSD.org> To: FreeBSD pf <freebsd-pf@freebsd.org> Cc: Eirik =?utf-8?q?=C3=98verby?= <eirik.overby@modirum.com> Subject: RFC: enabling pf syncookies by default Message-ID: <BF7E3C1C-CC06-4874-821E-2B3BBDC2F467@FreeBSD.org>
next in thread | raw e-mail | index | archive | help
--=_MailMate_B0ABA760-8B22-4E97-877C-F6677A50B102_= Content-Type: text/plain; charset=UTF-8; format=flowed; markup=markdown Content-Transfer-Encoding: 8bit Hi, During EuroBSDCon 2022 Eirik asked why we don’t enable pf’s syncookie feature (in adaptive mode) by default. I don’t really have a good answer, so I’m inclined to make this change. For those not familiar with it, syncookies are a mechanism to resist syn flood DoS attacks. They’re enabled by default in the IP stack, but if you’re running pf a syn flood would still exhaust pf’s state table, even if the network stack itself could cope. In adaptive mode all pf does is track the number of half-open states (as created when a SYN packet arrives). If that exceeds a set limit the syncookie feature activates. The upside of that is that all we pay for is the counting of the number of half-open states, which has no meaningful performance impact, at least until we exceed the high water mark. Does anyone see a good reason not to do so? Best regards, Kristof Proposed patch: commit 77b5994c89945e52eb23ec6f5810a1186abc6df4 (HEAD -> main) Author: Kristof Provost <kp@FreeBSD.org> Date: Sat Sep 24 14:49:25 2022 +0200 pf: default syncookies to adaptive mode The cost of enabling syncookies in adaptive mode is very low (basically a single atomic add when we create a new half-open state), and the payoff when under SYN flood is huge. So, enable adaptive mode by default. Suggested by: Eirik Øverby diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index 84235031f8e6..4e1eafe016f1 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -311,6 +311,8 @@ pfattach_vnet(void) { u_int32_t *my_timeout = V_pf_default_rule.timeout; + bzero(&V_pf_status, sizeof(V_pf_status)); + pf_initialize(); pfr_initialize(); pfi_initialize_vnet(); @@ -379,7 +381,6 @@ pfattach_vnet(void) my_timeout[PFTM_ADAPTIVE_START] = PFSTATE_ADAPT_START; my_timeout[PFTM_ADAPTIVE_END] = PFSTATE_ADAPT_END; - bzero(&V_pf_status, sizeof(V_pf_status)); V_pf_status.debug = PF_DEBUG_URGENT; V_pf_pfil_hooked = 0; diff --git a/sys/netpfil/pf/pf_syncookies.c b/sys/netpfil/pf/pf_syncookies.c index 6a375411d8ea..c16d9f3509fd 100644 --- a/sys/netpfil/pf/pf_syncookies.c +++ b/sys/netpfil/pf/pf_syncookies.c @@ -126,7 +126,12 @@ pf_syncookies_init(void) { callout_init(&V_pf_syncookie_status.keytimeout, 1); PF_RULES_WLOCK(); - pf_syncookies_setmode(PF_SYNCOOKIES_NEVER); + V_pf_syncookie_status.hiwat = PF_SYNCOOKIES_HIWATPCT * + V_pf_limits[PF_LIMIT_STATES].limit / 100; + V_pf_syncookie_status.lowat = PF_SYNCOOKIES_LOWATPCT * + V_pf_limits[PF_LIMIT_STATES].limit / 100; + pf_syncookies_setmode(PF_SYNCOOKIES_ADAPTIVE); + PF_RULES_WUNLOCK(); } --=_MailMate_B0ABA760-8B22-4E97-877C-F6677A50B102_= Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <!DOCTYPE html> <html> <head> <meta http-equiv=3D"Content-Type" content=3D"text/xhtml; charset=3Dutf-8"= > </head> <body><div style=3D"font-family: sans-serif;"><div class=3D"markdown" sty= le=3D"white-space: normal;"> <p dir=3D"auto">Hi,</p> <p dir=3D"auto">During EuroBSDCon 2022 Eirik asked why we don=E2=80=99t e= nable pf=E2=80=99s syncookie feature (in adaptive mode) by default.</p> <p dir=3D"auto">I don=E2=80=99t really have a good answer, so I=E2=80=99m= inclined to make this change.</p> <p dir=3D"auto">For those not familiar with it, syncookies are a mechanis= m to resist syn flood DoS attacks. They=E2=80=99re enabled by default in = the IP stack, but if you=E2=80=99re running pf a syn flood would still ex= haust pf=E2=80=99s state table, even if the network stack itself could co= pe.</p> <p dir=3D"auto">In adaptive mode all pf does is track the number of half-= open states (as created when a SYN packet arrives). If that exceeds a set= limit the syncookie feature activates.<br> The upside of that is that all we pay for is the counting of the number o= f half-open states, which has no meaningful performance impact, at least = until we exceed the high water mark.</p> <p dir=3D"auto">Does anyone see a good reason not to do so?</p> <p dir=3D"auto">Best regards,<br> Kristof</p> <p dir=3D"auto">Proposed patch:</p> <pre style=3D"margin-left: 15px; margin-right: 15px; padding: 5px; border= : thin solid gray; overflow-x: auto; max-width: 90vw; background-color: #= E4E4E4;"><code>commit 77b5994c89945e52eb23ec6f5810a1186abc6df4 (HEAD ->= ; main) Author: Kristof Provost <kp@FreeBSD.org> Date: Sat Sep 24 14:49:25 2022 +0200 pf: default syncookies to adaptive mode The cost of enabling syncookies in adaptive mode is very low (basical= ly a single atomic add when we create a new half-open state), and the payoff when under SYN flood is huge. So, enable adaptive mode by default. Suggested by: Eirik =C3=98verby diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index 84235031f8e6..4e1eafe016f1 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -311,6 +311,8 @@ pfattach_vnet(void) { u_int32_t *my_timeout =3D V_pf_default_rule.timeout; + bzero(&V_pf_status, sizeof(V_pf_status)); + pf_initialize(); pfr_initialize(); pfi_initialize_vnet(); @@ -379,7 +381,6 @@ pfattach_vnet(void) my_timeout[PFTM_ADAPTIVE_START] =3D PFSTATE_ADAPT_START; my_timeout[PFTM_ADAPTIVE_END] =3D PFSTATE_ADAPT_END; - bzero(&V_pf_status, sizeof(V_pf_status)); V_pf_status.debug =3D PF_DEBUG_URGENT; V_pf_pfil_hooked =3D 0; diff --git a/sys/netpfil/pf/pf_syncookies.c b/sys/netpfil/pf/pf_syncookie= s.c index 6a375411d8ea..c16d9f3509fd 100644 --- a/sys/netpfil/pf/pf_syncookies.c +++ b/sys/netpfil/pf/pf_syncookies.c @@ -126,7 +126,12 @@ pf_syncookies_init(void) { callout_init(&V_pf_syncookie_status.keytimeout, 1); PF_RULES_WLOCK(); - pf_syncookies_setmode(PF_SYNCOOKIES_NEVER); + V_pf_syncookie_status.hiwat =3D PF_SYNCOOKIES_HIWATPCT * + V_pf_limits[PF_LIMIT_STATES].limit / 100; + V_pf_syncookie_status.lowat =3D PF_SYNCOOKIES_LOWATPCT * + V_pf_limits[PF_LIMIT_STATES].limit / 100; + pf_syncookies_setmode(PF_SYNCOOKIES_ADAPTIVE); + PF_RULES_WUNLOCK(); } </code></pre> </div></div></body> </html> --=_MailMate_B0ABA760-8B22-4E97-877C-F6677A50B102_=--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?BF7E3C1C-CC06-4874-821E-2B3BBDC2F467>