These days I installed a NFS Server to backup my Kubernetes Cluster. Even as I protected the NSF server via the exports file to allow only cluster members to access the server there was still a new security risk. NSF comes together with the Remote Procedure Call Daemon (RPC). And this daemon enables attackers to figure out information about your network. So it is a good idea to protect the RPC which is running on port 111 from abuse.
To test if your server has an open rpc port you can run a telnet from a remote node:
$ telnet myserver.foo.com 111 Trying xxx.xxx.xxx.xxx... Connected to myserver.foo.com.
This indicates that rpc is visible from the internet. You can check the rpc ports on your server also with:
$ rpcinfo -p program vers proto port service 100000 4 tcp 111 portmapper 100000 3 tcp 111 portmapper 100000 2 tcp 111 portmapper 100000 4 udp 111 portmapper 100000 3 udp 111 portmapper 100000 2 udp 111 portmapper
If you run Kubernetes or Docker on a sever you usually have already Iptables installed. You can test this by listing existing firewall rules. With the option -L you can list all existing rules:
$ iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy DROP) target prot opt source destination DOCKER-USER all -- anywhere anywhere DOCKER-ISOLATION-STAGE-1 all -- anywhere anywhere ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED DOCKER all -- anywhere anywhere ACCEPT all -- anywhere anywhere ACCEPT all -- anywhere anywhere Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain DOCKER (1 references) target prot opt source destination ACCEPT tcp -- anywhere 172.17.0.2 tcp dpt:9042 ACCEPT tcp -- anywhere 172.17.0.2 tcp dpt:afs3-callback Chain DOCKER-ISOLATION-STAGE-1 (1 references) target prot opt source destination DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere RETURN all -- anywhere anywhere Chain DOCKER-ISOLATION-STAGE-2 (1 references) target prot opt source destination DROP all -- anywhere anywhere RETURN all -- anywhere anywhere Chain DOCKER-USER (1 references) target prot opt source destination RETURN all -- anywhere anywhere
This is an typical example you will see on a sever with Docker daemon installed. Beside the three default chains ‘INPUT’, ‘FORWARD’ and ‘OUTPUT’ there are also some custom Docker chains describing the rules.
So the goal is to add a new CHAIN containing rules to protect the RPC daemon from abuse.
Backup your Origin iptables
Before you start adding new rules make a backup of your origin rule set:
$ iptables-save > iptables-backup
This file can help you if something goes wrong later…
Adding a RPC Rule
If you want to use RPC in the internal network but prohibit it from the outside, then you can implement the following iptables. In this example I explicitly name the cluster nodes which should be allowed to use RPC port 11. All other request to the PRC port will be dropped.
Replace [SEVER-NODE-IP] with the IP address from your cluster node:
$ iptables -A INPUT -s [SERVER-NODE-IP] -p tcp --dport 111 -j ACCEPT $ iptables -A INPUT -s [SERVER-NODE-IP] -p udp --dport 111 -j ACCEPT $ iptables -A INPUT -p tcp --dport 111 -j DROP $ iptables -A INPUT -p udp --dport 111 -j DROP
This rule explicitly allows SEVER-NODE-IP to access the service and all other clients will be drop. You can easily add additional Nodes before the DROP.
You can verify if the new ruleset was added to your existing rules with:
$ iptables -L
You may write a small bash script with all the iptables commands. This makes it more convenient testing your new ruleset.
Saving the Ruleset
Inserting new rules into the firewall carries some risk by its own. If you do something wrong you can lockout your self from your sever. For example if you block the SSH port 22.
The good thing is, that rules created with the
iptables command are stored in memory. If the system is restarted before saving the
iptables rule set, all rules are lost. So in the worst case you can reboot your server to reset your new rules.
If you have tested your rules than you can persist the new ruleset.
$ iptables-save > iptables-newruleset
After a reboot yor new rules will still be ignored. To tell debian to use the new ruleset you have to store this ruleset into /etc/iptables/rules.v4
$ iptables-save > /etc/iptables/rules.v4
Finally you can restart your server. The new rpc-rules will be applied during boot.