** 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

Reply via email to