bhouse-nexthop opened a new issue, #14354:
URL: https://github.com/apache/cloudstack/issues/14354

   ### problem
   
   On a VPC virtual router, rules in the egress ACL chain `ACL_OUTBOUND_ethX` 
(mangle table) are not kept in the order the ACL list gives them. The chain's 
own rules can end up behind the ACL's deny.
   
   `CsNetfilters.compare()` inserts each ACL rule ahead of the **last** rule 
already in its ACL chain. That is right for `ACL_INBOUND_ethX`, whose last rule 
is always its `-j DROP`. But `ACL_OUTBOUND_ethX` has no terminal rule, so 
whichever rule happens to be last is pushed behind every ACL rule:
   
   - **Tier with a public network.** The chain starts with two accepts, for 
224.0.0.18 (VRRP) and 225.0.0.50. The 225.0.0.50 accept ends up last, after an 
egress deny:
     ```
     -A ACL_OUTBOUND_eth3 -d 224.0.0.18/32 -j ACCEPT
     -A ACL_OUTBOUND_eth3 -d 10.9.9.9/32 -p tcp -m tcp --dport 443 -j ACCEPT
     -A ACL_OUTBOUND_eth3 -d 8.8.8.8/32 -p udp -m udp --dport 53 -j ACCEPT
     -A ACL_OUTBOUND_eth3 -j DROP
     -A ACL_OUTBOUND_eth3 -d 225.0.0.50/32 -j ACCEPT
     ```
     225.0.0.50 is the multicast group conntrackd uses to sync connection state 
between redundant VPC routers, over the guest interface (`CsRedundant.py`). The 
peer router's sync packets come from inside the tier's CIDR, so the `PREROUTING 
... -j ACL_OUTBOUND_ethX` jump sends them through this chain. With an egress 
deny on that tier (the `default_deny` list has one), they are dropped. This 
part is from reading the code, not observed: redundant routers would stop 
syncing state, and connections would not survive a failover.
   - **Private gateway.** The chain starts empty, so the ACL's **first** rule 
is the one pushed to the end, behind the deny, and never matches:
     ```
     -A ACL_OUTBOUND_eth3 -d 8.8.8.8/32 -p udp -m udp --dport 53 -j ACCEPT
     -A ACL_OUTBOUND_eth3 -j DROP
     -A ACL_OUTBOUND_eth3 -d 10.9.9.9/32 -p tcp -m tcp --dport 443 -j ACCEPT
     ```
     (ACL list: 1 allow tcp 443 to 10.9.9.9/32, 2 allow udp 53 to 8.8.8.8/32, 3 
deny all.)
   
   Ingress is not affected, because `ACL_INBOUND_ethX` always ends with its 
DROP.
   
   ### versions
   
   Present on 4.22 (the insert logic and the chain layout are older than that).
   
   ### The steps to reproduce the bug
   
   1. In a VPC, create an ACL list with egress rules: 1 allow TCP 443 to 
`10.9.9.9/32`, 2 allow UDP 53 to `8.8.8.8/32`, 3 deny all to `0.0.0.0/0`.
   2. Attach it to a tier, and (separately) to a private gateway.
   3. On the VR, run `iptables -t mangle -S ACL_OUTBOUND_ethX` for each 
interface. You get the output above: on the tier the 225.0.0.50 accept is after 
the DROP, and on the private gateway rule 1 is after the DROP.
   
   ### What to do about it?
   
   Close `ACL_OUTBOUND_ethX` with a terminal rule, `-j RETURN`, the way 
`ACL_INBOUND_ethX` is closed with its DROP. RETURN at the end of a user chain 
does what falling off its end does, so it doesn't change how traffic is 
treated, but it gives the insert logic the last rule it assumes.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to