I have a virtual interface eth1:3
with IP address 222.192.124.3
, I have set up an iptables rule to log packets coming on that interface using the interface's IP (I know iptables doesn't care about virtual interfaces labels), like this:
iptables -A INPUT -d 222.192.124.3 -j LOG --log-level warning --log-prefix "VIP3-IN: "
When I run tcpdump and send packets on this IP from another machine, I see them, so I assume they are received and handled properly by the kernel, but iptables never logs these packets, and when I run iptables -nvL
, the packets count for that rule isn't incremented, like if they never hit the rule (or like if iptables doesn't even see packets coming on that interface).
I first thought of another rule matching the packet, and thus handling it before it hits the LOG rule, so I removed every iptables rule and added only the logging rule, with no more success.
Server is running on RHEL 6.2, with a 2.6.32 kernel, virtualized on VMware ESX.
Here is the full output of iptables -nvL
:
Chain INPUT (policy ACCEPT 40 packets, 2891 bytes)
pkts bytes target prot opt in out source destination
0 0 LOG all -- * * 0.0.0.0/0 222.192.124.3 LOG flags 0 level 4 prefix `VIP3-IN: '
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 34 packets, 3816 bytes)
pkts bytes target prot opt in out source destination
And here is a sample of the tcpdump's output showing the incoming packets (tcpdump -n -nn -vvv -i eth1 "host 203.0.59.135"
):
10:26:01.259409 IP (tos 0x50, ttl 121, id 26746, offset 0, flags [DF], proto TCP (6), length 52)
203.0.59.135.62332 > 222.192.124.3.8888: Flags [S], cksum 0x8da8 (correct), seq 3373891789, win 8192, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
And finally, the ifconfig eth1:3
output:
eth1:3 Link encap:Ethernet HWaddr 00:50:56:AC:35:35
inet addr:222.192.124.3 Bcast:222.192.127.255 Mask:255.255.252.0
UP BROADCAST RUNNING PROMISC MULTICAST MTU:1500 Metric:1
UPDATE:
(source: austintek.com)
Helped by the above diagram, I've setup iptables rules in different tables to see where the packets are going. I've come up with the following script:
IPT_FILTER="iptables -t filter"
IPT_MANGLE="iptables -t mangle"
IPT_NAT="iptables -t nat"
$IPT_FILTER -F
$IPT_FILTER -X
$IPT_FILTER -A INPUT -d 222.192.124.0/22 -j LOG --log-prefix "DEBUG filter: "
$IPT_FILTER -Z
$IPT_MANGLE -F
$IPT_MANGLE -X
$IPT_MANGLE -A PREROUTING -d 222.192.124.0/22 -j LOG --log-prefix "DEBUG mangle/prerouting: "
$IPT_MANGLE -A INPUT -d 222.192.124.0/22 -j LOG --log-prefix "DEBUG mangle/input: "
$IPT_MANGLE -Z
$IPT_NAT -F
$IPT_NAT -X
$IPT_NAT -A PREROUTING -d 222.192.124.0/22 -j LOG --log-prefix "DEBUG nat/prerouting: "
$IPT_NAT -Z
And it appears that packets go through the mangle/PREROUTING
and nat/PREROUTING
tables, but don't hit the mangle/INPUT
table, so I guess it takes the "No" branch on the "Data for the firewall". And being by no means a network or system expert (at most a power-user), this is where I get lost and don't understand what's going on...
FINAL EDIT (solution)
As suggested by @nodens in their answer, the problem was caused by RPF being in "Strict" mode... So much headaches for such a simple setting...
Are you sure there is no matching rule in other tables, like mangle or nat ? You could also try to log every paquet coming in INPUT, or even better, try the TRACE target in raw table (PREROUTING chain), if that is available on RHEL 6
Edit (I can't add a comment yet) :
OK, so the packet hit the interface, but it's not considered as a one the should be treated locally. Check your routing table, maybe you don't have a scope link route to this network, or the packet is dropped by the kernel because of RPF filters (this could happen depending of the network topology) : check https://access.redhat.com/site/solutions/53031
Virtual interface don't exist at the kernel level. They are aliases put on addresses by ifconfig. They should not be used since the end of the previous millennium.
Regarding iptables. As this is not an interface at kernel level you have to filter with the real interface name. In your case eth1. If you wish to be strict you will need to filter by source network if possible to mimic what you were trying to do by using the virtual interface name.