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 <k...@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();
         }

Reply via email to