On the perils of masquerading with Linux
I recently discovered a potential security problem with the configuration of Linux-based masquerading firewalls, which (I must admit I fell prey of).
Suppose I a server with one outgoing IP address, which has two network cards (eth0 – outgoing link and eth1 – internal link). I want to set up masquerading of the internal network 192.168.0.0/24.
The way I would proceed is:
Enable packet routing:
net.ipv4.ip_forward = 1Configure a masquearing rule:
iptables -t nat -A POSTROUTING -j MASQUERADESet up a firewall rules:
iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -i eth1 -j ACCEPT iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -p tcp -m multiport --dports <ports_here> -j ACCEPT iptables -P INPUT DROP
Does it work and is it secure? Yes… well… not really. Suppose the atacker is on the same network as I am and sets my host as his router. He will then be able to:
- Connect to my internal hosts (which will be helpfully masqueraded).
- Use my server to masquerade his connections (only on the allowed ports, but still).
- If the server has another interface (e.g. running an IPsec tunnel to a restricted network, it’s getting really scary.
What can I do:
Control the FORWARD chain:
iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT iptables -A FORWARD -i eth1 -j ACCEPT iptables -P FORWARD DENYBlock the incoming connections in
iptables -A INPUT -p tcp -m multiport --dports <ports_here> -j ACCEPTby specifying the destination IP address. However, this may be tricky, if the server uses a DHCP address (otherwise you wouldn’t be using MASQUERADE in the first place).Change masquerade so that it has an interface specified:
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE. This only partially solves the problem, as the packets will still be forwarded to internal networks.