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?