0

I have a firewalld setup with two zones.

One zone, some-ips-allowed, is used to permit traffic from specific IP networks on some ports:

some-ips-allowed (active)
  target: default
  icmp-block-inversion: no
  interfaces:
  sources: ipset:some-ip-set
  services:
  ports: 22/tcp 80/tcp 443/tcp
  ...

The some-ip-set contains some networks, say, 10.0.0.0/8.

Another zone has some interfaces assigned (whitelisted, due to target: ACCEPT):

something-trusted (active)
  target: ACCEPT
  icmp-block-inversion: no
  interfaces: eth123
  sources:
  services:
  ports:
  ...

The interface, eth123, has IP in the same network: 10.0.0.1.

Now the tricky case: if I try to access the machine via interface eth123 on port ex. 123, I get rejected. This is because of the priorities: firewalld sets up nftables so that ipsets are handled before interfaces, and zone some-ips-allowed doesn't permit port 123.

Here's the excerpt from nft list ruleset, note the goto directive:

chain filter_INPUT_ZONES {
    ip saddr @some-ip-set goto filter_IN_some-ip-set
    iifname "eth123" goto filter_IN_something-trusted
    ...

Shortly speaking, the logic is that if connection's IP matches, the ipset zone is used, and that's it.

What I want to achieve is: If the connection's IP matches, and it isn't explicitly handled, then it would be processed the next matching zone (an interface zone).

Is this doable in firewalld, preferrably without meddling with nft commands directly?

Edit: According to this: https://wiki.nftables.org/wiki-nftables/index.php/Jumping_to_chain, I can see I to have a jump instead of goto in nft rules.

Again, can this be done with firewall-cmd-level commands? If not, is it safe (i.e. will it not cause unpredictable conflicts and side effect) to use nft commands directly, even though the rest of the configuration is managed by firewall-cmd?

rubikonx9
  • 101
  • 3

1 Answers1

0

It seems it's not possible to do just this using firewall-cmd.

However, the desired effect can be obtained using firewalld's Policies instead of Zones.

Consider the following Policy:

some-ips-allowed-policy (active)
  priority: -1
  target: CONTINUE
  ingress-zones: ANY
  egress-zones: HOST
  services:
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
        rule family="ipv4" source ipset="some-ip-set" port port="22" protocol="tcp" accept

It will be applied to all incoming traffic (thanks to ANY and HOST ingress / egress zones), and will accept connections from IPs in the provided ipset.

Now, if the policy doesn't match the IPs, it will simply go on to process the zones (note the CONTINUE target). nft shows that policies generate jump statements - just what was needed.

Additionally, using the priority setting, it can be easily controlled whether a policy is applied before or after processing of the zones.

rubikonx9
  • 101
  • 3