Repository navigation
VPC ACL: match all ports for a tcp/udp rule given without ports - #14364
Open
bhouse-nexthop wants to merge 2 commits into
Open
bhouse-nexthop wants to merge 2 commits into
bhouse-nexthop wants to merge 2 commits into
Conversation
A VPC network ACL rule for tcp or udp without a port range reaches the VR as the range 0:0: TcpAclRule and UdpAclRule hold their ports as ints, so they are always sent. AclRule.init_vpc() only checked that first_port was present and rendered "-m tcp --dport 0", so the rule matched port 0 only: an allow admitted nothing, and a deny blocked nothing, letting the traffic through to the rules after it. The nftables paths (routed IPv4, IPv6) already treat 0 as no ports and match all of them. Treat 0:0 as no ports on the iptables path too. A range starting at 0, such as 0:1024, is still applied as given. Fixes: apache#14363 Signed-off-by: Brad House <bhouse@nexthop.ai>
bhouse-nexthop
requested review from
DaanHoogland,
sureshanaparti,
vladimirpetrov and
weizhouapache
October 8, 2026 12:43
Collaborator
Author
|
@vladimirpetrov @sureshanaparti could you take a look at this one? We'd like this fix to make it into the upcoming 4.22.2 release. |
Signed-off-by: Brad House <bhouse@nexthop.ai>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 4.22 #14364 +/- ##
=========================================
Coverage 18.02% 18.02%
Complexity 16247 16247
=========================================
Files 5936 5936
Lines 535823 535823
Branches 65612 65612
=========================================
Hits 96572 96572
Misses 428252 428252
Partials 10999 10999
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
On a VPC virtual router, a network ACL rule for
tcporudpwith no port range matched only port 0, instead of every port.Fixes #14363
Why it breaks
0:0(NetworkACLTO.getStringPortRange()).SetNetworkAclConfigItembuilds aTcpAclRule/UdpAclRule, whose ports are plainints, so the VR always receives"first_port": 0, "last_port": 0.configure.py'sAclRule.init_vpc()only checked thatfirst_portwas present, and rendered-m tcp --dport 0.What that did:
This is the iptables path: IPv4 on VPC tiers and private gateways that are not in routed mode. The nftables paths (routed IPv4 and IPv6) already treat
0as "no ports" and match every port. So the same rule allowed all TCP on IPv6 and none on IPv4.How it is fixed
AclRule.init_vpc()treats exactly0:0as "no ports" and adds no--dport, the same as the nftables paths do for0:0.0:1024, is still applied as given.startport=0) is also stored as0:0, and the VR can't tell it apart from one without ports. Such a rule is now applied to all ports, as the IPv6 and routed paths already do. See the upgrade note.How to reproduce the old behaviour
10.0.0.0/8, Allow. Attach the list to a tier.iptables -S ACL_INBOUND_ethX:-A ACL_INBOUND_ethX -s 10.0.0.0/8 -p tcp -m tcp --dport 0 -j ACCEPT-A ACL_INBOUND_ethX -s 10.0.0.0/8 -p tcp -j ACCEPTUpgrade note
Once routers run the updated scripts (after a management server upgrade, then recreating the router or
restartVPC livepatch=true), existing tcp/udp ACL rules without ports match every port of that protocol, as they always should have:This also applies to a rule created through the API with port 0 alone, for example a "deny tcp port 0" anti-scan rule. It becomes a deny of all TCP on IPv4, as it already is on IPv6. The UI can't create such a rule; it sends an empty port for 0. To find these rules before upgrading:
The rows with
start_port = 0are the ones set to port 0 on purpose; the rows with no ports are the ones this PR is about.Types of changes
Feature/Enhancement Scale or Bug Severity
Bug Severity
How Has This Been Tested?
systemvm/test/TestCsAclPorts.py:0:0render without--dport; that test fails on the current4.22code;0:1024) are still rendered as before;allrules are unaffected.pycodestyleandpylint(as insystemvm/test/runtests.sh) report nothing new.validateSourceStartAndEndPortsreturns early when both ports are null, and the UI doesn't require ports); I haven't reproduced it on a running VR.How did you try to break this feature and the system with this change?
allrules have nofirst_portand are unaffected.0:1024, as all ports, because they testif first_port:. The iptables path applies it as given. That is an existing, separate difference.