All of lore.kernel.org
 help / color / mirror / Atom feed
* Validating this is the right conntrack ruleset
@ 2022-06-06 13:48 Gio
  2022-06-06 15:30 ` Kerin Millar
  0 siblings, 1 reply; 5+ messages in thread
From: Gio @ 2022-06-06 13:48 UTC (permalink / raw)
  To: netfilter

I need some help understanding the proper way to do conntrack
bidirectionally in a secure way. Could someone help validate my
understanding and indicate if the below ruleset and approach is
correct?

My goal is to allow incoming connections to tcp/80 (input hook) and
all response traffic (output hook) without blindly allowing more ports
than intended for this one service running on tcp/80.

table ip legacy {
        chain root_out {
                type filter hook output priority filter; policy drop;
                tcp sport 80 ct state established,related accept
        }

        chain root_in {
                type filter hook input priority filter; policy drop;
                tcp dport 80 accept
        }
}

I have seen other firewall examples where the input chain just blindly
allows all reply packets via 'ct state established,related accept'
like so :

        chain root_in {
                type filter hook input priority filter; policy drop;
                ct state established,related
                tcp dport 80 accept
        }

I am not sure if my first example is correct and secure; should 'ct
state established,related accept' always be in the input hook for
response packets or only needs to be in the output hook?

Thanks in advance.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Validating this is the right conntrack ruleset
  2022-06-06 13:48 Validating this is the right conntrack ruleset Gio
@ 2022-06-06 15:30 ` Kerin Millar
  2022-06-06 15:51   ` Kerin Millar
  0 siblings, 1 reply; 5+ messages in thread
From: Kerin Millar @ 2022-06-06 15:30 UTC (permalink / raw)
  To: Gio; +Cc: netfilter

On Mon, 6 Jun 2022 09:48:23 -0400
Gio <gioflux@gmail.com> wrote:

> I need some help understanding the proper way to do conntrack
> bidirectionally in a secure way. Could someone help validate my
> understanding and indicate if the below ruleset and approach is
> correct?
> 
> My goal is to allow incoming connections to tcp/80 (input hook) and
> all response traffic (output hook) without blindly allowing more ports
> than intended for this one service running on tcp/80.
> 
> table ip legacy {
>         chain root_out {
>                 type filter hook output priority filter; policy drop;
>                 tcp sport 80 ct state established,related accept
>         }
> 
>         chain root_in {
>                 type filter hook input priority filter; policy drop;
>                 tcp dport 80 accept
>         }
> }
> 
> I have seen other firewall examples where the input chain just blindly
> allows all reply packets via 'ct state established,related accept'
> like so :
> 
>         chain root_in {
>                 type filter hook input priority filter; policy drop;
>                 ct state established,related
>                 tcp dport 80 accept
>         }
> 
> I am not sure if my first example is correct and secure; should 'ct
> state established,related accept' always be in the input hook for
> response packets or only needs to be in the output hook?

I would describe your example as neither correct nor secure. For one thing, both chains would impede traffic traversing "lo", which is normally inadvisable. For another, the rule in the root_in chain does not match on the ctstate, despite being the ruleset being of a stateful design. For instance, you probably don't intend for your rule to match packets in the "invalid" state, but it would. Here is a sample ruleset that might prove instructive.

table inet legacy {
    chain root_in {
        type filter hook input priority filter; policy drop;
        ct state established,related accept
        iifname "lo" accept
        meta l4proto ipv6-icmp accept
        tcp dport 80 fib daddr type local ctstate new accept
    }
}

Note the use of the inet family so as not to inadvertently leave things wide open in the case of IPv6. The conntrack state machine already does a good job of matching essential ICMPv4 packets pertaining to a TCP flow against the "related" ctstate. Filtering ICMPv6 in such a way that does not result in breakage is comparatively difficult, hence the blanket rule there. The fib check will ensure that the destination IP address was specified as one that is actually assigned to your host. The use of "ctstate new" should be self-explanatory. If you set the "net.netfilter.nf_conntrack_tcp_loose" sysctl to a value of "0", it will behave even more strictly in that a packet that would result in a new TCP flow (from the perspective of conntrack) must have only the SYN flag set.

I would advise against hooking output with a drop policy, unless you have a concrete reason to do so. In the event that you do, the "root_out" chain could share some of the characteristics of the "root_in" chain, such as allowing established/related to pass, as well as packets traversing the lo interface. You would not then require any counterpart for the tcp dport 80 rule. However, you would need to consider other matters, such as allowing for the passage of packets destined to nameservers and those required for your package manager to function, to name a few.

-- 
Kerin Millar

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Validating this is the right conntrack ruleset
  2022-06-06 15:30 ` Kerin Millar
@ 2022-06-06 15:51   ` Kerin Millar
  2022-06-07 16:08     ` Gio
  0 siblings, 1 reply; 5+ messages in thread
From: Kerin Millar @ 2022-06-06 15:51 UTC (permalink / raw)
  To: Gio; +Cc: netfilter

On Mon, 6 Jun 2022 16:30:48 +0100
Kerin Millar <kfm@plushkava.net> wrote:

>         tcp dport 80 fib daddr type local ctstate new accept

Please excuse the typo. Of course, I meant to write "ct state" there.

-- 
Kerin Millar

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Validating this is the right conntrack ruleset
  2022-06-06 15:51   ` Kerin Millar
@ 2022-06-07 16:08     ` Gio
  2022-06-07 16:15       ` Kerin Millar
  0 siblings, 1 reply; 5+ messages in thread
From: Gio @ 2022-06-07 16:08 UTC (permalink / raw)
  To: Kerin Millar; +Cc: netfilter

Thank you; I appreciate the help with clarity. The most important
takeaway for me was that there are implicit return packet/replies
rules that don't need to be in the opposite hook (output for input,
etc).

The example was excellent to illustrate this too.

For the sake of completeness; would the 'implicit' return packet rule
be 'ct state established,related ct direction reply' ? Example:

table inet legacy {
    chain root_in {
        type filter hook input priority filter; policy drop;
        ct state established,related accept
        iifname "lo" accept
        meta l4proto ipv6-icmp accept
        tcp dport 80 fib daddr type local ct state new accept
    }
    chain root_out {
        type filter hook output priority filter; policy drop;
        ct state established,related ct direction reply accept
        iifname "lo" accept
    }
}

On Mon, Jun 6, 2022 at 11:51 AM Kerin Millar <kfm@plushkava.net> wrote:
>
> On Mon, 6 Jun 2022 16:30:48 +0100
> Kerin Millar <kfm@plushkava.net> wrote:
>
> >         tcp dport 80 fib daddr type local ctstate new accept
>
> Please excuse the typo. Of course, I meant to write "ct state" there.
>
> --
> Kerin Millar

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Validating this is the right conntrack ruleset
  2022-06-07 16:08     ` Gio
@ 2022-06-07 16:15       ` Kerin Millar
  0 siblings, 0 replies; 5+ messages in thread
From: Kerin Millar @ 2022-06-07 16:15 UTC (permalink / raw)
  To: Gio; +Cc: netfilter

On Tue, 7 Jun 2022 12:08:48 -0400
Gio <gioflux@gmail.com> wrote:

> Thank you; I appreciate the help with clarity. The most important
> takeaway for me was that there are implicit return packet/replies
> rules that don't need to be in the opposite hook (output for input,
> etc).
> 
> The example was excellent to illustrate this too.
> 
> For the sake of completeness; would the 'implicit' return packet rule
> be 'ct state established,related ct direction reply' ? Example:
> 
> table inet legacy {
>     chain root_in {
>         type filter hook input priority filter; policy drop;
>         ct state established,related accept
>         iifname "lo" accept
>         meta l4proto ipv6-icmp accept
>         tcp dport 80 fib daddr type local ct state new accept
>     }
>     chain root_out {
>         type filter hook output priority filter; policy drop;
>         ct state established,related ct direction reply accept
>         iifname "lo" accept
>     }
> }

Yes, I believe it would be. Incidentally, the second rule in the root_out chain should be using oifname, rather than iifname.

-- 
Kerin Millar

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-06-07 16:15 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-06 13:48 Validating this is the right conntrack ruleset Gio
2022-06-06 15:30 ` Kerin Millar
2022-06-06 15:51   ` Kerin Millar
2022-06-07 16:08     ` Gio
2022-06-07 16:15       ` Kerin Millar

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.