** Description changed: + [ Impact ] + + There is a mismatch between what the `portblock` agent expects for + configuring iptables rules and the iptables output on Noble. `portblock` + decides whether an iptables DROP rule already exists by running + `iptables -n -L <chain>` and grepping the output for the protocol by its + string name (`tcp` / `udp`). iptables 1.8.9 introduced a regression + (netfilter bug <LINK>) where the `-n` flag also makes the *protocol* + column numeric — `tcp` is printed as `6` and `udp` as `17` - which is + correct btw. + + As a consequence, two situations may happen: + - everytime the resource starts a new identical blocking rule is added to `iptables`, as it can't detect the rule is still there, and + - when the resource stops (and thus the block should be lifted) the rule is not removed. + + `resource-agents` has a fix for this in version 4.14, and backporting + this fix to Noble is enough to fix this bug. + + [ Test Plan ] + + - Launch a fresh Ubuntu machine. + - Install resource-agents-extra, and make sure iptables is present. + - Start a one-node cluster with corosync+pacemaker + - Create the portblock resource with: + - sudo pcs resource create pb portblock \ + action=block protocol=tcp portno=2049 ip=127.0.0.1 + - Check iptables output, make sure there is no rule for this port: + - sudo iptables -n -L INPUT | grep 2049 + - Start the agent: + - sudo pcs resource debug-start pb + - Check iptables again to check if the rule is present + - Call the start action again + - Check iptables again to check if the rule is present [1] + - Stop the agent: + - sudo pcs resource debug-stop pb + - Check iptables again to check if the rule is present [2] + + Using the version from the Ubuntu release: + [1] will have two lines, and + [2] will still show the two lines + + Using the version from proposed, all works without errors. + + [ Where problems could occur ] + + The fix is applied upstream for quite a while, so we believe it's stable + and tested enough. + + Only the `portblock` agent is changed in the fix, which means other + agents are not affected by this change. + + The regex that checks for the protocol is being relaxed, which means the + risk for false positives when detecting a rule. This is unlikely as it + aims exactly to the protocol field in the `iptables` output. + + What could cause problems here is yet another change to the iptables + output, which is very unlikely in a possible future SRU. + + [ Other Info ] + + - Jammy is not affected as iptables 1.8.7 still has the old output format. + - Releases with resource-agents 4.14 or later already include the fix. + + [ Original Description ] + Ubuntu version: # lsb_release -rd Description: Ubuntu 24.04.4 LTS Release: 24.04 Package version: # apt-cache policy resource-agents-extra resource-agents-extra: - Installed: 1:4.13.0-1ubuntu4 - Candidate: 1:4.13.0-1ubuntu4 - Version table: - *** 1:4.13.0-1ubuntu4 500 - 500 http://archive.ubuntu.com/ubuntu noble/universe amd64 Packages - 100 /var/lib/dpkg/status + Installed: 1:4.13.0-1ubuntu4 + Candidate: 1:4.13.0-1ubuntu4 + Version table: + *** 1:4.13.0-1ubuntu4 500 + 500 http://archive.ubuntu.com/ubuntu noble/universe amd64 Packages + 100 /var/lib/dpkg/status Expected behavior: Portblock blocks the port in question when asked to, and unblocks when asked to. Actual behavior: Portblock blocks the port, but cannot unblock the port, and furthermore duplicates the iptables rule blocking the port. Analysis: In the /usr/lib/ocf/resource.d/heartbeat/portblock script, during port unblocking, iptables output is inspected to determine if the iptables chain needs to be updated. Function chain_isactive() calls `iptables -n -L INPUT` and uses the regex returned by function active_grep_pat() to check if the rule in question is present. If the rule is present, it is removed. If not, no removal attempt is made. Or, in the case of blocking, the rule is added only if found to be absent. The regex uses the "protocol" parameter, among other criteria, to be sure that only the correct rule is matched. This parameter is defined as a string and in all examples string names are used such as "tcp" and "udp". However, iptables no longer prints the stringified protocol name when the `-n` flag is passed: No -n flag: # iptables -L INPUT Chain INPUT (policy ACCEPT) target prot opt source destination DROP tcp -- anywhere k8snfs.scc.net.davepedu.com multiport dports nfs With -n flag: # iptables -n -L INPUT Chain INPUT (policy ACCEPT) target prot opt source destination DROP 6 -- 0.0.0.0/0 10.130.12.151 multiport dports 2049 This causes the portblock script to think that the rule is not present, and thus does not attempt to remove the rule. In my use case, an NFS server, this leaves port 2049 blocked and clients cannot connect. Furthermore, the rule becomes duplicated since this check is also used to determine if the rule is already present when blocking. Since the rule is never found, it is added again. At some point in the past, the `-n` flag in iptables did not cause the protocol to be printed numerically in addition to port numbers, ip rdns, etc. I can infer from this that the script was written for an older version of iptables than what Ubuntu currently ships, but no longer works with the version shipped on my OS version. This bug can be trivially worked around by specifying the protocol number instead of name when creating a portblock resource: # pcs resource create portblock portblock \ - action=block \ - ip=10.0.0.0/8 \ - portno=2049 \ - protocol=6 <---- "6", instead of "tcp" + action=block \ + ip=10.0.0.0/8 \ + portno=2049 \ + protocol=6 <---- "6", instead of "tcp"
-- You received this bug notification because you are a member of Ubuntu Bugs, which is subscribed to Ubuntu. https://bugs.launchpad.net/bugs/2145785 Title: portblock does not work due to iptables changes To manage notifications about this bug go to: https://bugs.launchpad.net/ubuntu/+source/resource-agents/+bug/2145785/+subscriptions -- ubuntu-bugs mailing list [email protected] https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs
