My current setup is that I have a server with several IPv4 addresses. Let's ignore the IPv6 part for now, as the symptoms are identical there.

In the firewall rules I'd like to match against HTTP traffic towards a particular IP as well as a couple of other services (allowing them through with -j ACCEPT in my INPUT chain in the filter table).

This is effectively the second to last rule in the INPUT chain:

-A INPUT -m set --match-set public_services dst -j ACCEPT
-A INPUT -j NFLOG --nflog-prefix  "[IPv4:inp/flt] (drop)"
# filter/INPUT chain ends here

but since some logging happens prior to the -j DROP I can see that the traffic ends up being dropped by that last rule instead of being accepted, as desired. The marker used in logging is unique inside my netfilter rules.

My IP set looks like:

# ipset save public_services
create public_services list:set size 8
add public_services public_services4
add public_services public_services6

whereas the IPv4-specific IP set is (actual IP address redacted):

# ipset save public_services4
create public_services4 hash:ip,port family inet hashsize 1024 maxelem 65536 counters
add public_services4,tcp:80 packets 0 bytes 0
add public_services4,tcp:22 packets 0 bytes 0

I enabled the counters in order to see whether the rules in the INPUT chain match or not. However, it appears they don't. Which I find highly odd, because the IP, protocol (tcp) and port match when I compare them from the log file (redacted MAC and IP addresses):

[IPv4:inp/flt] (drop) IN=eth0 OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:00:00 SRC= DST= LEN=40 TOS=00 PREC=0x00 TTL=242 ID=54321 PROTO=TCP SPT=51433 DPT=80 SEQ=2936666534 ACK=0 WINDOW=65535 SYN URGP=0 MARK=0

I also tried to add my rules as IPv4 and IPv6-specific rules respectively in order to reference the IP version-specific IP set. This also does not work and it falls through to the explicit rule added first.

What am I doing wrong in this case while trying to match destination IP, protocol and port?

More information:

Said rule above is number 26, so I decided to insert one explicit rule before it:

-I INPUT 26 -p tcp -d --dport 80 -j ACCEPT

This worked. However, I want to abstract as much of the variable parts out of my netfilter rules and into IP sets.

So I added (just to prove the point that it doesn't work with sets) another rule:

-I INPUT 26 -m set --match-set public_services4 dst -j ACCEPT

and this doesn't work. According to the netfilter and the IP set counters this rule does not match.

Versions of involved packages:

  • ipset: 6.20.1-1
  • iptables: 1.4.21-1ubuntu1
  • Use src,src and dst,dst instead of just src or dst. – user148302 Dec 21 '15 at 9:58
  • 1
    But why?! We're specifying only one address, why doubling "dst,dst" instead of one "dst"? – Groosha Oct 4 '17 at 7:46

Your ipset consist of IP and ports, so you need to tell iptables match for both IP and port. If you want to match with destination port use dst, otherwise use src.

-A INPUT -m set --match-set public_services dst,dst -j ACCEPT
|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.