zarf-dev / zarf

DevSecOps for Air Gap & Limited-Connection Systems. https://zarf.dev/
Apache License 2.0
1.39k stars 170 forks source link

Guidance on using Zarf / k3s in RHEL 8.4, with a host-based firewall #176

Closed davidnraines closed 2 years ago

davidnraines commented 2 years ago

When we deploy k3s, we are going to be required to block unneeded ports on the host that runs k3s. We’re running into a bit of trouble figuring out exactly how to configure what we need.

Some basic things we’ve concluded:

We’ve written a set of nftables rules that we think should be compatible with the nftables configuration that k3s generates, but it never seems to quite work. One thing I’ve been struggling to understand is if we’re adding the wrong rules (if some other set of nft instructions in the attached .bash file would do the trick), or if there’s some other mismatch between us using nft and whatever k3s itself is doing.

Do you have any thoughts as to how we should go about blocking additional ports on a RHEL 8.4 host that is running k3s?

Attached is a script to add potential firewall rules: add_firewall_rules.txt

RothAndrew commented 2 years ago

@jeff-mccoy I recommended David come here so we could do a thread and get the rest of the team involved in troubleshooting this. This is outside my area of expertise so I need some help tracking down the issue.

jeff-mccoy commented 2 years ago

Copy @RothAndrew I'll dig into this some more, may need to phone a friend from the K3s folks.

jeff-mccoy commented 2 years ago

Back from Thanksgiving, can we setup a zoom or something this week to go through this @davidnraines and then post output back here after we solve it?

davidnraines commented 2 years ago

Based on our conversation yesterday, I have prepared additional documentation of what I have attempted This is relatively long, and we may want to Zoom again to discuss.

I have attached a ZIP file with a handful of artifacts to go along with the below description.

Observation:

My Questions:

What I have tried:

Scenario #1: I try to add nftables rules in a shell script

Scenario #2: I try to add nftables rules by the “/etc/sysconfig/nftables.conf” file

I ran the below commands

My intention (had this worked) was to then modify the /etc/sysconfig/nftables.conf file to add additional port restrictions What I saw was that:

k3s-firewall-issues.zip .

jeff-mccoy commented 2 years ago

So I learned more than I wanted to about iptables/nftables/netfilter/etc. Tl;dr; use iptables in nftables mode not nftables directly. Example ruleset that worked with iptables-restore before launching k3s:

*filter
:INPUT ACCEPT [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -d 127.0.0.0/8 ! -i lo -j DROP
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# SSH
-A INPUT -i eth0 -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
# HTTP
-A INPUT -i eth0 -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
# HTTPS
-A INPUT -i eth0 -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
# Drop everything else
-A INPUT -i eth0 -j DROP
COMMIT

The issue lies here:

https://github.com/k3s-io/k3s/blob/master/pkg/agent/netpol/network_policy_controller.go#L299 https://github.com/coreos/go-iptables/blob/master/iptables/iptables.go#L223

Basically, under the hood it's just a fancy iptables execCommand which is 🤮. I played with a lot of iterations of setting via nft and even iptables-translate, but the root issue is even some basic nftables rulesets seems to break iptables in nftables mode. You can demonstrate this below:

  1. Apply this ruleset (not the interface here is eth0)
    
    # drop any existing nftables ruleset
    flush ruleset

add table ip filter add chain ip filter INPUT { type filter hook input priority 0; policy accept; } add rule ip filter INPUT ct state related,established counter accept add rule ip filter INPUT iifname "eth0" ct state new tcp dport {22, 80, 443} counter accept add rule ip filter INPUT iifname "eth0" counter drop



2. Try to run `iptables -t filter -S INPUT` should produce the same error

<img width="1728" alt="Screen Shot 2021-12-15 at 1 10 28 AM" src="https://user-images.githubusercontent.com/882485/146164892-13f93b46-e63e-4559-a74b-2f624011aea1.png">

Let me know if this moves you in the right direction.
jeff-mccoy commented 2 years ago

This link is also really good for explaining the different variations of the firewall in RHEL now: https://www.redhat.com/en/blog/using-iptables-nft-hybrid-linux-firewall.

jeff-mccoy commented 2 years ago

I think this issue is resolved now, but we should update the docs with an example for someone who wants to do this @RothAndrew