How can I block some ports from external incoming TCP?
I just installed an Azuracast box from the Linode's Marketplace and discovered that some ports (80,443,2022 and others) are open to the outside world. This box uses a preconfigured docker and no matter what I try, I cannot block external incoming TCP connections. It seems that docker always finds a way to expose those ports again.
I want to expose only the SSH port and some others in range 8000-8999 that are used by Azuracast listeners. The 80 and 443 ports (used for administration) I want to access only through ssh tunnels.
Any ideas on how to do that?
2 Replies
@ncfernan --
You write:
This box uses a preconfigured docker and no matter what I try, I cannot block external incoming TCP connections. It seems that docker always finds a way to expose those ports again.
I don't use docker but if it does do this, I would stop using it post haste…or at least update it to a version that has this serious defect repaired. That being said, I did find this:
https://github.com/docker/for-linux/issues/690
It may give you some clues. The defect report only mentions ufw specifically and the solution seems to be "Don't use ufw". This is a YUUUUUGE security breach!
FWIW, ufw is a "friendly-front end" for iptables(8) that exists only in Ubuntu.
Just in case that's what you decide to do, here are some tutorials:
- nftables(8) -- https://linuxx.info/how-to-use-nftables/
- iptables(8) -- https://phoenixnap.com/kb/iptables-tutorial-linux-firewall
nftables(8) is more modern but iptables(8) has been in use longer and so there's more info about it. The kernel backend is the same so either will accomplish your goal.
-- sw
@stevewi thank you for your comments.
After reading those links you posted and tried some of the ideas, I realised that ufw and docker simply don't mix, no way.
So I had to figure out how to teach docker to do what I wanted. I first logged some packets to see the incoming and outgoing interfaces for each exposed port. Then I wrote some iptables rules to interfere with the docker flow.
Now it is running as expected:
Host is up (0.21s latency).
Not shown: 992 closed ports
PORT STATE SERVICE
22/tcp open ssh
25/tcp filtered smtp
80/tcp filtered http
135/tcp filtered msrpc
139/tcp filtered netbios-ssn
443/tcp filtered https
445/tcp filtered microsoft-ds
10000/tcp filtered snet-sensor-mgmt
The iptables rules to filter out the port controlled by docket are:
-A DOCKER-USER -p tcp -m tcp -m multiport -i eth0 -o br-f65e53960b88 -j DROP --dports 80,443
-A DOCKER-USER -p tcp -m tcp -i eth0 -o br-4760b0da1a86 --dport 2022 -j DROP
-A DOCKER-USER -j RETURN
You can see that depending on the destination port the outgoing interface changes.
The iptables rules to filter out ports that are NOT controlled by docker are:
-A INPUT -p tcp -m tcp -i lo --dport 10000 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 10000 -j DROP
-A INPUT -p tcp -m tcp -d linux -i eth0 --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j DROP
The logged packets show the interfaces involved, so I could tell which one was under control of docker.
The ufw.service MUST BE DISABLED to work. I guess that docker is taking care of all iptables rules. You can manage the docker related iptable rules using webmin.
PS: I know that I can config webmin to listen only on the loopback interface, but I used that port to test the new iptables rules.