Why is the firewall disabled by default?

Hello everyone,

I recently looked into securing linux servers because I do not know much about this topic. Which is when I noticed that at least my instance of CoreOS does not come with its firewall setup by default.

It was neither configured by default nor was the nftables.service enabled by default either. To me personally, it just seems very odd. Because reading a bit in the nftables wiki, no rules is equivalent to accepting any traffic. Plus they offer a simple example rule set for servers.

So my question is, if this is just an issue with my instance or the actual default in CoreOS? Or maybe there is another program responsible for that job?

1 Like

I think this has to do with the usecase for which CoreOS was designed: as a base OS that can be spun up quickly for container workloads, e.g., in a Kubernetes cluster. In this case, you know exactly what services you deploy on a node. And if you deploy a service, you want it to be accessible, otherwise you wouldn’t have deployed it.

In this scenario, if you need to perform some kind of firewalling/packet filtering, you would probably do this on a dedicated machine for your entire cluster.

Yes, by default there is no host-based packet filter active on Fedora CoreOS. You can set up an nftables ruleset if you want.

Personally, I don’t consider host-based firewalls particularly effective. Usually, they allow all outgoing traffic so there is no filtering there. And for incoming packets, you could simply not start a service that listens on a port instead of filtering traffic to that port.

2 Likes

In addition to the previous post, see:

2 Likes

That mirrors what I expressed as my opinion about host-based filtering at the end of my post: If you don’t want people connecting to a service on your machine, do not have that service listen (=open a port, pretty much the same thing) on an external interface. The same is true for containers, if you do not want people connecting to your containerized application, do not publish its port(s) to an external interface.

As a more concrete example for the original question, on my Fedora CoreOS installation, I have a reverse proxy running, which handles incoming connections on ports 80 and 443 on all network interface. When a connection is made to ā€˜hs.mydomain.invalid:443’, the reverse proxy passes it on to localhost:8443, which is my Headscale server instance.
There is no firewall on this machine: I need connect to the reverse proxy, so I would not filter these ports anyway, and there is nothing listening on other ports (apart from the CoreOS defaults like SSH and DNS resolution). The Headscale container itself is only listening on localhost.

At one point, I thought about filtering the ports for some origin IPs of countries that I don’t plan on visiting in the near future and that have a reputation as origins of cyber attacks. Just to cut down on some of the background noise of people running network scans and trying automated exploits. But then I decided against it, for two reasons: a) setting it up and keeping it updated with a list of country-specific IP addresses appeared to be a major pain in the neck, and b) randomly excluding countries from access and assuming there are no bad actors in other countries gives a false sense of security IMO, better to just keep the application up-to-date and to rely on strong authentication.

2 Likes

Additionally, you can run firewalld from a privileged container to protect the host. I tried it and it works.

3 Likes

Thank you both for taking the time to help me. The discussion on the other post was also very helpful. I hope you do not mind me to much, bombarding you with more questions on the topic (^^;)

So port blocking is only useful, if I cannot control what services/open ports are running on my host, because if there is nothing listening on a port, the firewall makes no difference in theory?

That should then still be true when my host is connected directly to the internet? And disabling LLMNR for systemd-resolved would probably be a good idea too (maybe even in general)?

And how about using a firewall for rate limiting traffic, or is that also better left to the active services?

I recently disabled a firewall because it was unexpectedly blocking DoT with DNS on a local resolver. I enabled it a few weeks ago and it was fine until I decided to look into DoT :stuck_out_tongue:


I wouldn’t expect CoreOS as the OS itself having a firewall in container envs; the above posts explain it better, but (imo) with the containers isolated to themselves, they’re firewall’d from each other, and with containers only running specific services, there’s no need for a general-purpose firewall with the isolated scope.

I’d do the firewall at something outside the PC (like a router) and only allow ports to the container machine for the specific services.

I’d do firewall for ssh, but app-side for something like webservers

In general, yes. Any incoming packet goes from the physical interface to the network stack. If you have any kind of filtering (iptables, nftables, …) it will determine the packet’s fate. If it is accepted, it is then passed on to the process associated with the port, if it is not, then it is dropped. However, without packet filtering, if there is no process associated with the port, it is also dropped. Because there simply is no process to pass the packet to.

There are finer details, such as if there is an ICMP ā€œDestination unreachableā€ response sent back, which doesn’t happen if the incoming packet is dropped by a packet filter. But in terms of vulnerability, the packet is in the network stack in both cases. And it only makes it to an application if there is one.

This depends on what you want to achieve with the rate limiter. There is no such thing as ā€œabsoluteā€ security (even though that’s how a lot of people talk about it). You need to specify what the scenario is that you want to defend against. Then you can develop a strategy. As an analogy, seat belts in a car are great for a collision, but not so great if your fuel tank explodes.

If your scenario is some kind of distributed denial of service (DDoS), there really isn’t a point, whether you do it in the packet filter or the application. The traffic has already made it onto the machine and will overwhelm it. Filtering in the kernel instead of passing it to userspace/the application may save you some ressources and thus you might last a little longer, but any finite ressource (your server’s processing power) can be exhausted.

If your scenario is a brute force authention attempt that you want to slow down, you can do it in the application. In fact, the application actually knows when an authentication failure has occured and as a result when to slow down subsequent authentication attempts.

1 Like

Would you care to elaborate? What is the filtering criteria for the SSH server? And why do you treat SSH and HTTP(S) differently?

Thanks again for the help. Your and the other’s answers really helped me understand everything I wanted to know about firewalls.