A site-to-site IPsec tunnel between two Ubuntu 24.04 machines, built with strongSwan and a pre-shared key. The configuration below is mirrored on both ends: what is left on one host is right on the other, and nothing else differs.
The Lab
Install strongSwan
On both hosts:
strongswan-starter is the package that provides the classic ipsec command together with /etc/ipsec.conf and /etc/ipsec.secrets. Without it, Ubuntu 24.04 gives you only the newer swanctl stack and the files below are never read.
Host A Configuration
left is always the local side and right the remote one. The exclamation mark at the end of the ike and esp proposals makes them strict: strongSwan will not silently fall back to a weaker algorithm the peer offers. auto=start brings the tunnel up as soon as the daemon starts and keeps it up.
The pre-shared key is written local first, remote second:
The file holds a plaintext secret, so it should belong to root only:
Host B Configuration
The same file with the two sides swapped:
The connection name, the proposals and the PSK must be identical on both ends. The subnets and the addresses are the only values that mirror.
Open IKE and ESP on the Firewall
IPsec needs UDP 500 for IKE, UDP 4500 when either peer sits behind NAT, and IP protocol 50 for the encrypted ESP traffic itself:
ESP is a protocol, not a port. A firewall that only opens the two UDP ports will show a successfully established IKE session and no traffic through the tunnel at all.
Start the Tunnel
On both hosts:
To survive a reboot, enable the service instead:
After editing ipsec.conf, reload the configuration and bring the connection up again:
Verify the Tunnel
Host A:
Host B:
Two things confirm the tunnel is real. ESTABLISHED on its own only means IKE finished; the line that matters is INSTALLED, TUNNEL, which means a child SA exists and the kernel policy is in place. And the SPIs cross over: the inbound SPI on Host A is the outbound SPI on Host B.
Now send traffic between the two protected addresses:
Only traffic whose source and destination fall inside the configured subnets is encrypted. If the ping leaves with the WAN address as its source it never matches the policy, so force the source when in doubt:
The kernel policies and the negotiated SAs can be inspected directly:
Moving to Real Subnets
Replace the /32 addresses with the actual networks on each side:
Once the hosts route for a network behind them rather than answering for themselves, forwarding has to be enabled:
Any NAT rule that masquerades outbound traffic must also exclude the remote subnet, otherwise packets are rewritten to the WAN address before the IPsec policy sees them and leave the tunnel unencrypted.
When It Does Not Come Up
Watch the negotiation live while forcing the connection:
NO_PROPOSAL_CHOSEN means the ike or esp lines differ between the peers. AUTHENTICATION_FAILED or no matching peer config found points at the PSK or at a leftid that does not match what the other side expects. If the IKE session establishes and traffic still does not pass, ESP is being dropped somewhere in the path.
For the full picture, including the selected proposals and the installed policies: