I run balenaOS 2.84.5 with one container in prevelige mode.
I looked at the iptables rules in host OS and found that the default input rule is accept and after all balena-firewall rules there is a return before reject which means that all inputs are accepted. This is easy fixed by removing that balena-firewall return rule or change default to drop or reject.
My question is, why the firewall is configured like this by default and where is the best place to do the fix to lock it down?
The Iptables look like this:
-P INPUT ACCEPT
-P FORWARD DROP
-P OUTPUT ACCEPT
-N BALENA-FIREWALL
-N DOCKER
-N DOCKER-ISOLATION-STAGE-1
-N DOCKER-ISOLATION-STAGE-2
-N DOCKER-USER
-A INPUT -j BALENA-FIREWALL
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION-STAGE-1
-A FORWARD -o balena0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o balena0 -j DOCKER
-A FORWARD -i balena0 ! -o balena0 -j ACCEPT
-A FORWARD -i balena0 -o balena0 -j ACCEPT
-A FORWARD -o br-b041d7d4f6e2 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o br-b041d7d4f6e2 -j DOCKER
-A FORWARD -i br-b041d7d4f6e2 ! -o br-b041d7d4f6e2 -j ACCEPT
-A FORWARD -i br-b041d7d4f6e2 -o br-b041d7d4f6e2 -j ACCEPT
-A FORWARD -o supervisor0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o supervisor0 -j DOCKER
-A FORWARD -i supervisor0 ! -o supervisor0 -j ACCEPT
-A FORWARD -i supervisor0 -o supervisor0 -j ACCEPT
-A BALENA-FIREWALL -m state --state RELATED,ESTABLISHED -j ACCEPT
-A BALENA-FIREWALL -m addrtype --src-type LOCAL -j ACCEPT
-A BALENA-FIREWALL -i resin-vpn -p tcp -m tcp --dport 48484 -j ACCEPT
-A BALENA-FIREWALL -i tun0 -p tcp -m tcp --dport 48484 -j ACCEPT
-A BALENA-FIREWALL -i docker0 -p tcp -m tcp --dport 48484 -j ACCEPT
-A BALENA-FIREWALL -i lo -p tcp -m tcp --dport 48484 -j ACCEPT
-A BALENA-FIREWALL -i supervisor0 -p tcp -m tcp --dport 48484 -j ACCEPT
-A BALENA-FIREWALL -p tcp -m tcp --dport 48484 -j REJECT --reject-with icmp-port-unreachable
-A BALENA-FIREWALL -p tcp -m tcp --dport 22222 -j ACCEPT
-A BALENA-FIREWALL -p tcp -m tcp --dport 2375 -j ACCEPT
-A BALENA-FIREWALL -m addrtype --dst-type MULTICAST -j ACCEPT
-A BALENA-FIREWALL -p icmp -j ACCEPT
-A BALENA-FIREWALL -i balena0 -p udp -m udp --dport 53 -j ACCEPT
-A BALENA-FIREWALL -j RETURN
-A BALENA-FIREWALL -j REJECT --reject-with icmp-port-unreachable
-A DOCKER-ISOLATION-STAGE-1 -i balena0 ! -o balena0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -i br-b041d7d4f6e2 ! -o br-b041d7d4f6e2 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -i supervisor0 ! -o supervisor0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -j RETURN
-A DOCKER-ISOLATION-STAGE-2 -o balena0 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -o br-b041d7d4f6e2 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -o supervisor0 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -j RETURN
-A DOCKER-USER -j RETURN
Okey, it’s all about the BALENA_HOST_FIREWALL_MODE. It’s off by default.
By setting it to on the BALENA-FIREWALL -j RETURN deletes and it start rejecting incoming traffic that is not allowed.
I added the rules to mangle table instead and changed default to drop. Now supervisor can do whatever it want to the input chain in the filter table. No packages will get there anyway.
Hi, glad you could find a solution to your issue! Would you mind sharing the commands you used to get the firewall to work the way you wanted? This might be useful for some other users experiencing the same problem. Thank you!
The rest is default Balena rules copied from the filter table with a change on the port 22222 and 2375 rule to only accept connection from resin-cpn. The rules on interface wlan0 is to accept dhcp and dns request from local wifi network. (Device is working as a wifi router).
Can I lock it down even more? I’am not so sure about that LOCAL and MULTICAST rules in the beginning.
We’ve merged a fix for the Supervisor firewall bug you may have encountered in this ticket, where the Supervisor was flushing the INPUT chain of the iptables filter table on startup, thereby removing any non-Supervisor-created rules from the INPUT chain. To get the benefits of this fix, please self-serve upgrade the Supervisor on your devices to v14.9.2. See issue and pull request for details. Let us know if there are any questions!