Introduction
Recently I got an email from the network department of my provider, letting me know that they had indications that one of my servers was performing netscans on private networks. Certainly I had not initiated any netscan manually. Moreover I don’t have lots of things installed on my server, only a few docker containers. So, where was the problem? And more importantly, how to fix it?
After switching off a couple of containers, the problem went away. I then examined how these containers are configured, and found one that starts with the option --net=host
. Most probably this one was the culprit. By default docker containers don’t have access to the network stack of the host, so they cannot launch a netscan on the private network where the host is located. But if they are started with --net=host
their network is the same as that of the host.
Needless to say that I removed it. However the advice from the network team was to harden the firewall of the server in order to block any outgoing communications to their private networks. In this tutorial I show how I did it. My server is ubuntu-18.04 but I am sure that the same steps can be applied easily to other distros too.
Step 1 – Make sure that ufw is installed
For managing the firewall of the server I use ufw
(uncomplicated firewall).
First make sure that it is installed:
apt install ufw
Then configure it properly by allowing the ports of SSH, HTTP, HTTPS, etc. and enable it:
ufw allow 22
ufw allow 80
ufw allow 443
ufw enable
ufw status
Step 2 – Block any communications to private networks
The private networks are:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
- 100.64.0.0/10
It is quite easy to block outgoing communications to them with ufw
:
ufw deny out from any to 10.0.0.0/8
ufw deny out from any to 172.16.0.0/12
ufw deny out from any to 192.168.0.0/16
ufw deny out from any to 100.64.0.0/10
ufw deny out from any to 198.18.0.0/15
ufw deny out from any to 169.254.0.0/16
Check the status of the firewall with ufw status
and you will see something like this:
Status: active
To Action From
-- ------ ----
[ . . . . . . . . . . ]
10.0.0.0/8 DENY OUT Anywhere
172.16.0.0/12 DENY OUT Anywhere
100.64.0.0/10 DENY OUT Anywhere
192.168.0.0/16 DENY OUT Anywhere
You may also check with iptables-save
, and you should see something like this:
*filter
:OUTPUT ACCEPT [0:0]
:ufw-before-output - [0:0]
:ufw-user-output - [0:0]
-A OUTPUT -j ufw-before-output
-A ufw-before-output -j ufw-user-output
-A ufw-user-output -d 10.0.0.0/8 -j DROP
-A ufw-user-output -d 172.16.0.0/12 -j DROP
-A ufw-user-output -d 192.168.0.0/16 -j DROP
-A ufw-user-output -d 100.64.0.0/10 -j DROP
You can test it with ping
, for example ping 172.16.5.204
, and you should get something like this:
PING 172.16.5.204 (172.16.5.204) 56(84) bytes of data.
ping: sendmsg: Operation not permitted
ping: sendmsg: Operation not permitted
ping: sendmsg: Operation not permitted
ping: sendmsg: Operation not permitted
^C
--- 172.16.5.204 ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 3053ms
The ufw deny out
(OUTPUT) rules from above only block outgoing communication for packets from the host itself. When using containers/virtualization with routing like LXD, traffic will not reach the OUTGOING netfilter table as it passes through FORWARDING.
Additional steps for containers/virtualization (LXD)
ip route add unreachable 10.0.0.0/8
ip route add unreachable 172.16.0.0/12
ip route add unreachable 192.0.0.0/24
ip route add unreachable 192.168.0.0/16
ip route add unreachable 100.64.0.0/10
ip route add unreachable 198.18.0.0/15
ip route add unreachable 169.254.0.0/16
This should not affect existing routes.
Step 3 – Unblock (optional)
If for some reason you need to unblock one of these private networks, you can do it by deleting the corresponding ufw rule, like this:
ufw status numbered
ufw delete <rule-number>
Conclusion
Communication from your server to private networks is not allowed on many providers. Blocking these communications with a firewall is important especially if you don’t have full control over what you install on your server. Doing it with ufw is very easy.