How to match properly against an IP set of type 'hash:ip,port'?

6,279

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
Share:
6,279

Related videos on Youtube

0xC0000022L
Author by

0xC0000022L

human father bibliophile geek & ~nerd misanthropic philanthropist skeptic code necromancer programmer reverse engineer (RCE) / software archaeologist / grayhat hacker moderator on reverseengineering system administrator FLOSS enthusiast Debian, FreeBSD and Ubuntu aficionado

Updated on September 18, 2022

Comments

  • 0xC0000022L
    0xC0000022L over 1 year

    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)"
    -A INPUT -j 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 192.168.0.1,tcp:80 packets 0 bytes 0
    add public_services4 192.168.0.1,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=1.2.3.4 DST=192.168.0.1 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 192.168.0.1 --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
    • Admin
      Admin over 8 years
      Use src,src and dst,dst instead of just src or dst.
    • Groosha
      Groosha over 6 years
      But why?! We're specifying only one address, why doubling "dst,dst" instead of one "dst"?