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:

  1. Enable packet routing:

    net.ipv4.ip_forward = 1
    
  2. Configure a masquearing rule:

    iptables -t nat -A POSTROUTING -j MASQUERADE
    
  3. Set 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:

  1. Connect to my internal hosts (which will be helpfully masqueraded).
  2. Use my server to masquerade his connections (only on the allowed ports, but still).
  3. 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:

  1. Control the FORWARD chain:

    iptables  -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
    iptables -A FORWARD -i eth1 -j ACCEPT
    iptables -P FORWARD DENY
    
  2. Block the incoming connections in iptables -A INPUT -p tcp -m multiport --dports <ports_here> -j ACCEPT by 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).

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

Leave a Reply