Iptables – Block *local* traffic with ‘iptables’ ; but allow *remote* traffic

iptables

Is it possible to use a Linux Firewall to block (or 'drop') all incoming packets to a particular port that originate on the local machine ?

Ideally: I would like to still allow remote traffic access to the port though.

I have tried this (Which I found via google):

sudo iptables -I FORWARD 1 -p tcp -m tcp --dport 9000 -j DROP

But this doesn't work for me; I found that I was still able to 'telnet' (from the same machine) to port 9000 (again on the same machine) without being blocked/dropped.

This is an odd request : but I am trying to put together a diagnostic test – where I need to block communication between two program on the same machine; without actually killing the endpoint service.

BTW: I'm testing whether I can block incoming traffic by running a simple Java program (below):

import java.net.Socket;
import java.net.ServerSocket;

public class listen {

public static void main(String[] args) throws Exception {
        int port=9000;

        System.out.println("Listening on port:"+port);

        ServerSocket ss=new ServerSocket(port);
        while (true) {
                Socket s=ss.accept();
                System.out.println("Incoming !");
                s.close();
        }
}

}

Using this – I can see my incoming request from a 'telnet' (etc) from the 'Incoming!' message.

Best Answer

Firstly you need to use INPUT for dropping incoming connections.

As said by @Ulfy

sudo iptables -I INPUT -p tcp --dport 9000 -i lo -j DROP

To drop IPv4 loopback. Then you might want to drop IPv6 loopback

sudo ip6tables -I INPUT -p tcp --dport 9000 -i lo -j DROP

Then there are the other interfaces which can also "loop back". For example if you have eth0 on ip 192.168.10.10 and you type

telnet 192.168.10.10

Then your telnet client connects from 192.168.10.10 to 192.168.10.10 and has bypassed the firewall on localhost that way.

sudo iptables -I INPUT -p tcp --dport 9000 -i eth0 -s 192.168.10.10 -j DROP

And finally, all your local interfaces likely have IPv6 link local addresses (even if you think your LAN has no IPv6) so you might want to block those too.

EDIT

On a friendly network (and I assume localhost is friendly in this case), it's usually more cooperative to use REJECT rather than DROP as this explicitly rejects the incoming connection, rather than ignoring it. This allows the client to detect straight away that the connection has failed, rather than waiting on a timeout.