Repository navigation
VR: route replies to remote access VPN clients through the tunnel - #14548
Open
willbennett-devops wants to merge 1 commit into
Open
willbennett-devops wants to merge 1 commit into
willbennett-devops wants to merge 1 commit into
Conversation
On a router with more than one public NIC, anything the router answers itself from an address on a non-source-NAT public NIC (an LB address, ICMP) matched "from <public subnet> lookup Table_ethN" and left through that NIC's gateway instead of the client's ppp interface, so VPN clients could not reach a load balancer on such an address. Add a throw route for each VPN client network to every Table_ethN, so the lookup falls through to main and its ppp host routes. The routes carry their own protocol number and are reconciled on every pass from the active VPN entries, so they follow NIC changes and VPN deletion. Client networks that overlap a router subnet, a static route or a site-to-site peer network are skipped. Packets from a client network that arrive on any interface other than ppp are dropped, so a spoofed source can't have the reply sent into a client's tunnel.
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
This PR fixes replies from the VPC router to remote access VPN clients leaving by a public NIC's gateway instead of
the client's ppp interface, which makes LB rules and the router's public addresses unreachable over the VPN.
A reply the router sends from a public address (haproxy for an LB rule, an ICMP echo reply) matches
from <public network> lookup Table_ethX, and those tables have no route for the client range. Changes, all insystemvm/debian/opt/cloud/bin/configure.py:CsRemoteAccessVpn.client_routes()addsthrow <client network> table Table_ethN proto 147for each clientnetwork (the client range summarized into CIDRs, plus
local_ip/32) to everyTable_ethNthat anip rulelooksup. The lookup then continues in
main, which holds the per-session ppp routes. This is how tier networks are alreadykept out of these tables. No policy rule is added, so rule order doesn't matter.
present and runs nothing when they match. If
ip rule showreturns nothing it leaves the routes alone.main()on every pass, right after address processing, not fromCsRemoteAccessVpn.process(). Anip_associationspass can flush and rebuild a per-NIC table without running the iptables executors. A removed VPNis already gone from the data bag, so its routes are removed on the next pass.
client_networks()leaves out, and logs, a client network that overlaps a subnet on the router, a site-to-sitepeer network, or a static route that equals or lies inside it. CloudStack only checks the range against the VPC
CIDR, and taking those addresses over would break that traffic.
remoteaccessvpn_iptables()adds-A PREROUTING -s <client network> ! -i ppp+ -j DROPin mangle for each clientnetwork. With the throws in place, a packet arriving on a public NIC with a client's address as source would get its
reply sent into that client's tunnel; this drops it. The rules are written in
iptables-saveform so CsNetfilterfinds them on the next pass and removes them with the VPN.
Fixes: #14547
Types of changes
Feature/Enhancement Scale or Bug Severity
Bug Severity
How Has This Been Tested?
Unit tests: new
systemvm/test/TestCsRemoteAccessVpnClientRoutes.pyrunsclient_routes()against a fakeip rule/ip routewithCsHelper.executemocked: throws in every per-NIC table and none on a repeated pass, aflushed table and a new NIC table get theirs back, VPN removed or
create: false, client range changed,ip rule showempty, an unreadable entry, overlaps with a router subnet, a site-to-site peer and a static route (and a containing
route, a revoked route and a removed peer that don't count), routes it doesn't own left alone, and the spoofing rules.
On a 4.23.0.0 KVM lab (the changed code is identical in 4.22 and main), VPC with redundant routers, both routers
patched, an L2TP/IPsec client connected:
without the change). Port forwards still work.
nothing stale on the backup. VPN created again: routes back.
configured.
host on that public network are dropped (counter matches), no reply goes into the client's tunnel. With the drop
rule taken out, the replies went into the tunnel.
Failover, failback, VPN removal and the reboots were run on an earlier revision that put the spoofing rules in a
separate chain; the final version was checked again for LB, rule churn and spoofing on both routers.
How did you try to break this feature and the system with this change?
Overlaps (unit tests, not on the lab): a site-to-site peer network that overlaps the client range turns the routes
off for that network rather than dropping the peer's traffic, and table 220 and its rule are never touched. A static
route through a private gateway that contains the client range keeps the routes, since the ppp host route in
mainismore specific. Client ranges that overlap a public or tier subnet are logged and skipped. The spoofing rules leave IPsec itself alone: the outer packets
carry the client's public address, and only the decapsulated PPP payload, which arrives on
pppN, has a client rangesource. The pool must not be used by hosts reached through a private gateway or static route; their packets would
arrive on that NIC and be dropped.