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) 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.

Reply

Please enter an answer
Tips:

You can mention users to notify them: @username

You can use Markdown to format your question. For more examples see the Markdown Cheatsheet.

> I’m a blockquote.

I’m a blockquote.

[I'm a link] (https://www.google.com)

I'm a link

**I am bold** I am bold

*I am italicized* I am italicized

Community Code of Conduct