willbennett-devops opened a new issue, #14547:
URL: https://github.com/apache/cloudstack/issues/14547

   ### problem
   
   A remote access VPN (L2TP/IPsec) client on a VPC can reach tier VMs and port 
forwards, but gets no answer from
   anything the VPC router itself terminates on a public address: an LB rule 
(haproxy on the router), or a ping to one of
   the router's public IPs. The request reaches the router. The reply goes out 
of the public NIC to that network's gateway
   instead of into the client's ppp interface.
   
   Example, with CloudStack's default client range (`local_ip` 10.1.2.1, 
clients 10.1.2.2-10.1.2.8), source NAT
   203.0.113.2/28 on eth1, a second public network 198.51.100.128/25 on eth2 
with an LB rule on 198.51.100.131, and a
   tier 192.0.2.0/24 on eth3:
   
   ```
   $ ip rule show
   0:      from all lookup local
   220:    from all lookup 220
   32759:  from 198.51.100.128/25 lookup Table_eth2
   32760:  from all fwmark 0x67 lookup Table_eth3
   32761:  from 203.0.113.0/28 lookup Table_eth1
   32762:  from all fwmark 0x66 lookup Table_eth2
   32763:  from all fwmark 0x65 lookup Table_eth1
   32766:  from all lookup main
   
   $ ip route show table Table_eth2
   default via 198.51.100.129 dev eth2 proto static
   throw 192.0.2.0/24 proto static
   throw 198.51.100.128/25 proto static
   ```
   
   `main` holds the client's host route (`10.1.2.2 dev ppp0`), but the haproxy 
SYN-ACK from 198.51.100.131 to 10.1.2.2
   matches rule 32759 first, and `Table_eth2` has no entry for the client 
range, so it takes the default route out of
   eth2. The same happens to an ICMP echo reply from 198.51.100.130, and from 
203.0.113.2 through `Table_eth1`.
   
   A port forward on the same address works, because the reply leaves the 
backend VM with its tier address as source
   (reverse NAT happens after routing), matches no `from` rule and is routed by 
`main`. Pings to `local_ip` and to the
   tier gateway work for the same reason.
   
   Root cause, line numbers from the 4.22 branch (56306ab52c), same code in 
main:
   
   - `systemvm/debian/opt/cloud/bin/cs/CsAddress.py:848-861` 
(`post_config_change`, VPC branch): for each public NIC, a
     default route in `Table_<dev>`, a `throw` for each tier network 
(`CsRoute.add_network_route`, `cs/CsRoute.py:63-74`),
     a `throw` for the NIC's own network, and `ip rule add from <public 
network> table Table_<dev>`
     (`cs/CsRule.py:33-35`). Nothing is added for the remote access VPN client 
range.
   - `systemvm/debian/opt/cloud/bin/configure.py:1292-1329` 
(`remoteaccessvpn_iptables`) only adds iptables rules; the
     VPN never touches routing.
   
   Impact: on any VPC with a remote access VPN, clients can't use LB rules or 
reach the router's public addresses through
   the tunnel. For CKS clusters this means a Service of type LoadBalancer can't 
be reached over the VPN, while the API
   server through its port forward can. This is not a regression; 4.20 builds 
the same tables. Isolated networks build
   similar per-NIC tables (`CsAddress.py:834-846`) and are probably affected 
too; not tested.
   
   ### versions
   
   Seen on 4.23.0.0 with KVM, VPC with redundant routers, advanced networking. 
The code is the same on the 4.22 branch
   and main.
   
   ### The steps to reproduce the bug
   
   1. Create a VPC with a tier and a VM in it, and enable remote access VPN on 
the source NAT IP. Add a VPN user.
   2. Acquire a public IP, and add an LB rule on port 80 to the VM (an ACL rule 
allowing port 80 to the tier).
   3. Connect an L2TP/IPsec client.
   4. From the client, `curl http://<LB address>/` times out and `ping <router 
public IP>` gets no reply. A port forward
      from the same public IP to the VM works.
   5. On the router, `tcpdump -ni any host <client address>` shows the replies 
leaving the public NIC towards its gateway.
   
   ### What to do about it?
   
   Add a `throw` for each client network to every per-NIC table, the same way 
tier networks are thrown, so a reply to a
   VPN client continues to `main`, where the ppp host routes are. Reconcile 
them on every config pass, since a NIC change
   can flush and rebuild a table, and remove them when the VPN is removed. 
Because those routes would also send replies
   to a spoofed client address into that client's tunnel, drop packets sourced 
from the client range that don't arrive
   on `ppp+`. PR to follow.


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

  • [I] VPC VR: remote access VPN... willbennett-devops (via GitHub) via commits

Reply via email to