google / nftables

This repository contains a Go module to interact with Linux nftables (the iptables successor).
Apache License 2.0
1.12k stars 140 forks source link

[FR] Simplified Method for Determining if IP+Port is Whitelisted or Blacklisted #262

Closed the-hotmann closed 5 months ago

the-hotmann commented 7 months ago

I'm curious if there's a straightforward or recommended method to, for instance, verify the status of the IP address 123.123.123.123 on port 22. I've been considering something along these lines:

func GetStatus(ip ipv4, port int) bool {
  //... performs some magic ...//
  return status
}

This would allow for a simple way to determine whether any given IP or IP with a specific port is whitelisted. Perhaps I'm overcomplicating things?

Essentially, my goal is to ascertain from within a docker-container whether any given IP and port combination is whitelisted on the host according to the IPtables rules on the host. Any guidance on how to achieve this, or whether it's presently feasible, would be greatly appreciated.

I am open for discussion and hints :)

stapelberg commented 7 months ago

Hey! Unfortunately, nftables is really complex and your seemingly simple question is not simple to answer. For example, while an IP address might be blocked specifically (easy case), maybe entire networks are blocked (harder case) or maybe the packets are filtered by some other criterion entirely (impossible to figure out in general by just looking at nftables rules — you’d need to evaluate the rules).

I think the only way to determine whether an IP address is blocked or not is to do such a check with detailed knowledge of the nftables configuration. Meaning, if you control (or know) the entire nftables configuration, you can then come up with a working check.

Which software sets up the nftables rules on your host?

the-hotmann commented 7 months ago

Greetings and thanks for taking your time to reply. Regarding the version:

$ iptables -V
iptables v1.8.7 (nf_tables)

Although it presents itself as "iptables," it operates on the nftables framework underneath, at least as far as I understand.

I employ a script that scans the directory /etc/iptables/ for files with the extension *.conf and loads them. These files adhere to the older format. For instance:

/usr/sbin/iptables -A INPUT -i ens160 -p tcp -s 123.123.123.123/24 -m multiport --dports 22,2222 -j ACCEPT

Given that this rule permits all IPs from 123.123.123.0 to 123.123.123.255, I am interested in determining whether the IP 123.123.123.25 is whitelisted for Port 22. As you mentioned, there are some challenges:

In my opinion, determining if an IP is whitelisted or blacklisted is a fundamental function of any firewall tool. It also proves useful for conducting A/B testing on applications to verify their functionality.

Parsing the configuration wasn't initially my focus. However, it could potentially serve the purpose - assuming no modifications have been made to the configuration and it hasn't been reloaded. A better approach would involve working with the data/config currently active in nftables/iptables, as this at any times would be right.

Perhaps suggesting this as a feature request directly to nftables could be beneficial. A command like nftables-status, which allows users to check the status of a specific IP address and port combination, would indeed be quite useful.

For instance:

nftables-status 123.123.123.25 22

IP             PORT STATUS
123.123.123.25 22   BLOCKED

What do you think about this idea? Have you encountered others who have expressed a need for this functionality, or is it primarily something i solely find valuable?

stapelberg commented 7 months ago

Hello again. Based on your reply, I think there might be a misunderstanding.

You are reporting an issue in the google/nftables package, which is a module for the Go programming language to interact with the Linux nftables subsystem at a low level.

You are not in the right place for feature requests for nftables itself, or for tooling that works with nftables (such as your suggested nftables-status).

Before we continue the discussion, are you even using the Go programming language, or did you end up in the wrong repository? :)

the-hotmann commented 5 months ago

@stapelberg sorry for the late reply.

Before we continue the discussion, are you even using the Go programming language, or did you end up in the wrong repository? :)

Yes indeed I am using Golang. And with Golang.

You are not in the right place for feature requests for nftables itself, or for tooling that works with nftables (such as your suggested nftables-status).

I understand that. For such thing I would need to rise a Feature Request at nftables directly.

Besides this, is there any chance this module can help me to determinate whcih allow lists do exist? For example I want to know all allow rules (chain INPUT). Can this module help me and provide me with an array/list of all subnets/ips which are in there?

for example:

123.123.123.123 port 26,27
123.123.123.0/24 port 20-24

I then would check if the IP in question (123.123.123.123) is contained in any of them and select the Ports of these rules.

So for the IP 123.123.123.121 the ports 20,21,22,23,24 are allowed. So for the IP 123.123.123.123 the ports 20,21,22,23,24,26,27 are allowed

Thank you in advance! :)

stapelberg commented 5 months ago

Yes, you can use this module to obtain all installed nftables rules. See the ListTables, ListChains and GetRules methods.

As I tried to explain before, programmatically understanding nftables rules in general is really hard. As I said, the only way this can work is if you control the program that generates the nftables rules, because then you can make assumptions about the structure of the rules.

For your situation, it sounds like you should:

  1. Translate the iptables configuration to nftables first (because then there is one less layer in the mix)
  2. Inspect the rules using the nft command-line tool (e.g. nft list ruleset). The --debug=all flag is useful to break down what’s happening at lower levels.
  3. Use this knowledge to write your program.
the-hotmann commented 5 months ago

Thanks @stapelberg this is exactly what I did. I used nft list ruleset and processed the output :)

I appreciate the help!