Close ports on local interface with firewalld

Christoffer Reijer asked:

I want to close all ports but 22 on all interfaces, including the one for localhost. I have, on purpose, two services listening on port 25 and 1234 for testing purposes. Here’s where I’m stuck:

$ sudo firewall-cmd --state

$ sudo firewall-cmd --zone=drop --list-all
drop (default, active)
  interfaces: enp0s3 lo
  services: ssh
  masquerade: no
  rich rules: 

$ nmap localhost

Starting Nmap 6.40 ( ) at 2016-02-23 17:07 UTC
Nmap scan report for localhost (
Host is up (0.00069s latency).
Other addresses for localhost (not scanned):
rDNS record for default-centos-72
Not shown: 997 closed ports
22/tcp   open  ssh
25/tcp   open  smtp
1234/tcp open  hotline

As you can see, nmap shows both port 25 and 1234 as open, but I have added both interfaces to the drop zone in firewalld. What have I missed?

My answer:

You’ve tried to do something which is such an amazingly bad idea that firewalld simply will not let you do it.

By default, an input rule allowing all traffic from localhost appears very early in the firewall, and takes priority over all user-defined rules. It is not made visible in firewalld’s CLI tools, and cannot be changed or removed using them.

It’s theoretically possible that you may have a real need to do this, but it’s extraordinarily unlikely (and note well that you may think you have a real need, and actually do not). Firewalling localhost is a great way to break your entire system, as many many programs rely on localhost communications, which is why you can’t easily undo this.

View the full question and answer on Server Fault.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.