philtreF opened a new issue, #13512:
URL: https://github.com/apache/cloudstack/issues/13512
### The required feature described as a wish
Support site-to-site VPN customer gateway with dynamic peer IP
(authentication by ID)
##### ISSUE TYPE
* Enhancement Request
##### COMPONENT NAME
~~~
Component:api
Component:UI
Component:systemvm (Virtual Router / strongSwan)
~~~
##### CLOUDSTACK VERSION
~~~
4.22.0.0
~~~
##### SUMMARY
Today a VPN Customer Gateway requires a fixed, resolvable peer IP/FQDN in the
`Gateway` field. This makes it impossible to terminate a site-to-site IPsec
tunnel against a remote endpoint that has a **dynamic public IP** (a very
common
case: branch offices / remote sites behind a consumer or SME ISP link with no
static IP), where the remote peer must instead be identified by an **IKE
identity (ID)** rather than by its source IP.
The underlying engine (strongSwan on the VR) fully supports this scenario via
`right=%any` + `rightid=<peer-id>`. The limitation is purely in the
CloudStack
orchestration layer, which models and identifies the peer by IP only.
It would be valuable to allow a Customer Gateway to be created **without a
fixed
peer IP**, identifying the remote peer by an ID instead, so the VR acts as a
pure
responder for a dynamic-IP peer.
##### CURRENT BEHAVIOUR
When the remote site has no static IP, there is no supported way to configure
the tunnel:
* The `Gateway` field validates the input as an IP/FQDN and rejects anything
that is not a single resolvable address. For example, entering `0.0.0.0/0`
returns:
~~~
The customer gateway ip/Domain 0.0.0.0/0 is invalid!
~~~
* If a Customer Gateway ends up with a null/`0.0.0.0` peer, the VR
(`CsSite2SiteVpn` in `systemvm/debian/opt/cloud/bin/configure.py`)
generates a
broken configuration:
* the strongSwan connection is written with `right=0.0.0.0` and
`auto=route`,
which makes charon try to *initiate/route* toward a null address
(`installing trap failed, remote address unknown` in `charon` log);
* the INPUT firewall rule for IKE/ESP is generated with `-s 0.0.0.0`
(the null host, which matches no real packet) instead of `-s 0.0.0.0/0`
(any), so the remote peer's IKE packets are silently dropped by the
`INPUT DROP` policy before reaching charon.
* There is no field on the Customer Gateway to declare a remote **ID**. When
we manually open the INPUT firewall, the session establishes without identity
verification.
Net result: a dynamic-IP, ID-authenticated remote peer cannot be configured
through the UI/API at all.
##### EXPECTED BEHAVIOUR
Allow a Customer Gateway to represent a **dynamic-IP peer**:
* Make the peer `Gateway` IP optional **when** a remote ID / peer identity is
provided (new field). The remote ID replaces the IP as the peer's
authentication identity (IKE ID types: IPv4/IPv6 address, FQDN,
RFC822/email,
or DN).
* On the VR, when the peer is dynamic, `CsSite2SiteVpn` should generate:
* `right=%any`
* `rightid=<remote-id>`
* `auto=add` (responder only — the VR cannot initiate toward an unknown IP)
* the PSK indexed by the remote **ID** in `ipsec.*.secrets` (not by IP)
* an INPUT firewall rule opening UDP/500, UDP/4500 and ESP (proto 50)
toward
the source-NAT IP, either with `-s 0.0.0.0/0` or restricted to an
operator-supplied source range (possibly a list)
* Reuse the existing **Passive** mode semantics (the VR already supports
waiting
for the remote side to initiate, used today for VPC-to-VPC), since a
dynamic
peer is inherently the initiator.
This has been validated manually on a 4.22 VR (strongSwan 5.9.8): with
`right=%any` / `rightid=<id>` / PSK-by-ID and the INPUT rule opened, an IKEv2
tunnel from a dynamic-IP peer authenticating by ID establishes correctly and
passes traffic both ways (`ESTABLISHED` + `INSTALLED, TUNNEL`, bidirectional
`bytes_i` / `bytes_o`). The only blocker to native support is the
orchestration
layer.
##### PROPOSED IMPLEMENTATION (for discussion)
* **API / DB / UI**: add an optional `remoteid` (peer identity) attribute to
Create/Update VPN Customer Gateway; make `gateway` optional when `remoteid`
is set; expose a clear "dynamic peer IP" indication in the UI.
* **VR (`CsSite2SiteVpn` in `configure.py`)**: branch on dynamic peer to emit
`right=%any`, `rightid`, `auto=add`, PSK-by-ID, and the open INPUT rule.
* **Tests**: extend `test/integration/smoke/test_vpc_vpn.py` with a
dynamic-peer / responder case.
##### SECURITY CONSIDERATIONS
Because a dynamic peer cannot be filtered by source IP, this mode opens
UDP/500 + UDP/4500 + ESP on the public interface. To keep this safe
and explicit:
* the feature should be **opt-in** (an explicit "dynamic peer" flag on the
Customer Gateway), never a silent fallback;
* `rightid` should be **mandatory** in this mode so the peer is constrained
to a
known identity;
* IKEv2 should be used (no PSK-hash exposure, unlike IKEv1 aggressive mode);
* the UI should warn that the PSK becomes the primary authentication barrier
and
must be long and random;
* optionally allow restricting the INPUT rule to an operator-supplied source
CIDR (e.g. the remote ISP's known range) instead of `0.0.0.0/0`. As
operators oftens have multiple CIDR a list of CIDR would be better.
##### ENVIRONMENT (where observed)
~~~
CloudStack 4.22.0.0
System VM template: systemvm-kvm-4.22.0-x86_64
Virtual Router strongSwan: 5.9.8
Tunnel: IKEv2, PSK, remote peer behind NAT with dynamic public IP,
authenticating by RFC822-style ID
~~~
--
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]