Iptables: How does DROP policy is working with custom chain

iptables

I've been working on iptables for a project. The iptables are implemented for different interfaces via custom rule chains. Due to the declaration of accepting rules the default policy for INPUT is set to DROP.
Now my problem: even if a rule should match it seems the traffic is not passing. If I put the corresponding rule to the INPUT chain it seems to work. So I'm a bit of confused about how the drop is interpreted regarding the custom chains.

Following the example which is not working (I deleted not essential info):

Chain INPUT (policy DROP)
target     prot opt source               destination
LOINPUT    all  --  0.0.0.0/0            0.0.0.0/0
M2M_INPUT  all  --  0.0.0.0/0            0.0.0.0/0
NE_INPUT   all  --  0.0.0.0/0            0.0.0.0/0

Chain NE_INPUT (1 references)
target     prot opt source               destination
ACCEPT     all  --  0.0.0.0/0            10.196.95.208       state RELATED,ESTABLISHED
....
ACCEPT     tcp  --  10.196.95.74         10.196.95.208       tcp dpt:22
....

When ssh is done from 10.196.95.74 towards 10.196.95.208 it is not working.

As further test I added the line from NE_INPUT to INPUT and there it is working.

Chain INPUT (policy DROP)
num  target     prot opt source               destination
LOINPUT    all  --  0.0.0.0/0            0.0.0.0/0
M2M_INPUT  all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     tcp  --  10.196.95.74         10.196.95.208       tcp dpt:22
NE_INPUT   all  --  0.0.0.0/0            0.0.0.0/0

So as far as I thought I understood the DROP policy will be "active" when no rule is matching. So for me I expected iptables will parse through each rule (in each rule chain) und if no rule is matching the DROP policy will be activated.

But regarding my tests the DROP policy is activated without parsing throught each rule chain (in my case NE_INPUT).

Any hints / explanations?
Thanks in advance.

[UPDATE 15/06] : OK after further analysis I confirm DROP is working correctly but the problems seems more related to the custom chains.

[UPDATE 16/06] : It seems that the declaration of the custom chains is thereason for the faulty behavior.
When declaring the chain for the corresponding network interface (-i eth1) it is not working (ping NOK / ssh NOK for NE_INPUT chain)
But if I declare instead of interface the IP address assigned to this interface the ping works better.

NOK:

Chain INPUT (policy DROP 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination
3        0     0 NE_INPUT   all  --  eth1   *       0.0.0.0/0            0.0.0.0/0

OK:

Chain INPUT (policy DROP 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination
3        5   420 NE_INPUT   all  --  *      *       0.0.0.0/0            10.196.95.208

So how does the packets are interpreted via iptables. Normally it should work that packets arriving for interface eth1 are treated by NE_INPUT instead of being dropped. So these packets seem to be treated correctly when being address via destination IP.

[UPDATE 17/06] : Following the output of ip link & ip address

# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:50:56:8e:17:33 brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:50:56:8e:9a:f9 brd ff:ff:ff:ff:ff:ff
4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:50:56:8e:2e:9b brd ff:ff:ff:ff:ff:ff
5: eth3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:50:56:8e:de:03 brd ff:ff:ff:ff:ff:ff

# ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host valid_lft forever preferred_lft forever

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:50:56:8e:17:33 brd ff:ff:ff:ff:ff:ff
inet 10.196.95.207/24 brd 10.196.95.255 scope global eth0
inet6 fe80::250:56ff:fe8e:1733/64 scope link valid_lft forever preferred_lft forever

3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:50:56:8e:9a:f9 brd ff:ff:ff:ff:ff:ff
inet 10.196.95.208/24 brd 10.196.95.255 scope global eth1
inet6 fe80::250:56ff:fe8e:9af9/64 scope link  valid_lft forever preferred_lft forever

4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:50:56:8e:2e:9b brd ff:ff:ff:ff:ff:ff
inet 10.109.197.207/24 brd 10.109.197.255 scope global eth2
inet6 fe80::250:56ff:fe8e:2e9b/64 scope link valid_lft forever preferred_lft forever

5: eth3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:50:56:8e:de:03 brd ff:ff:ff:ff:ff:ff
inet 10.79.105.207/24 brd 10.79.105.255 scope global eth3
inet6 fe80::250:56ff:fe8e:de03/64 scope link valid_lft forever preferred_lft forever

Best Answer

You are reasoning correctly: If a DROP rule is matched in a custom chain the packet is dropped and doesn't traverse back to the built-in chain (INPUT in your case).

I suspect something might be going wrong in the lines you removed as "nonessential".

Try debugging your firewall with iptables -L -v -t filter while trying to ssh to your machine. It will give you counters how many times each rule was matched.

Are your nat and mangle tables empty and having ACCEPT policies in all built-in chains?

Related Topic