I've been able to setup IPSEC successfully between two Hetzner machine, both of which had only public IP addresses. However, I've been unsuccessful in configuring IPSEC between an EC2 instance and a Hetzner machine, because the EC2 instance has a private IP which goes through some form of NAT-ing to get a public IP.
I'm using ipsec-tools + racoon and trying to follow these docs:
- https://www.mad-hacking.net/documentation/linux/networking/ipsec/nat-vpn.xml
- https://www.netbsd.org/docs/network/ipsec/#sample_vpn
To make things simpler, I've tried taking racoon out of the picture and hard-coded the encryption keys.
How do I get this to work? And probably, more importantly, how do I peek under the hood and see what's going on? Where exactly is the "connection breaking"?
/etc/ipsec-tools.conf
on EC2 instance
flush;
spdflush;
# ec2 -> het
spdadd Ec2PvtIP HetznerIP any -P out ipsec esp/tunnel/Ec2PubIP-HetznerIP/require;
# het -> ec2
spdadd HetznerIP Ec2PvtIP any -P in ipsec esp/tunnel/HetznerIP-Ec2PubIP/require;
## Using EC2 Public IP
add Ec2PubIP HetznerIP esp 0x74fce30b -E aes-cbc 0xf46c3187e253e5b25b8f8525da056080 -A hmac-sha256 0x9e7c6f6c7a1ccdd7634bb0a9eeaea5a8ed7bdfed89fd3f7dc86b2e8a522ae6e8 ;
add HetznerIP Ec2PubIP esp 0x74fce30b -E aes-cbc 0xf46c3187e253e5b25b8f8525da056080 -A hmac-sha256 0x9e7c6f6c7a1ccdd7634bb0a9eeaea5a8ed7bdfed89fd3f7dc86b2e8a522ae6e8 ;
## Using EC2 Private IP
# ec2 -> het
add Ec2PvtIP HetznerIP esp 0x74fce30b -E aes-cbc 0xf46c3187e253e5b25b8f8525da056080 -A hmac-sha256 0x9e7c6f6c7a1ccdd7634bb0a9eeaea5a8ed7bdfed89fd3f7dc86b2e8a522ae6e8 ;
# het -> ec2
add HetznerIP Ec2PvtIP esp 0x74fce30b -E aes-cbc 0xf46c3187e253e5b25b8f8525da056080 -A hmac-sha256 0x9e7c6f6c7a1ccdd7634bb0a9eeaea5a8ed7bdfed89fd3f7dc86b2e8a522ae6e8 ;
/etc/ipsec-tools.conf
on Hetzner machine
flush;
spdflush;
# het -> ec2
spdadd HetznerIP Ec2PvtIP any -P out ipsec esp/tunnel/HetznerIP-Ec2PubIP/require;
# ec2 -> het
spdadd Ec2PvtIP HetznerIP any -P in ipsec esp/transport/Ec2PubIP-HetznerIP/require;
### Using EC2 Public IP
add HetznerIP Ec2PubIP esp 0x74fce30b -E aes-cbc 0xf46c3187e253e5b25b8f8525da056080 -A hmac-sha256 0x9e7c6f6c7a1ccdd7634bb0a9eeaea5a8ed7bdfed89fd3f7dc86b2e8a522ae6e8 ;
add Ec2PubIP HetznerIP esp 0x74fce30b -E aes-cbc 0xf46c3187e253e5b25b8f8525da056080 -A hmac-sha256 0x9e7c6f6c7a1ccdd7634bb0a9eeaea5a8ed7bdfed89fd3f7dc86b2e8a522ae6e8 ;
### Using EC2 Private IP
# het -> ec2
add HetznerIP Ec2PvtIP esp 0x74fce30b -E aes-cbc 0xf46c3187e253e5b25b8f8525da056080 -A hmac-sha256 0x9e7c6f6c7a1ccdd7634bb0a9eeaea5a8ed7bdfed89fd3f7dc86b2e8a522ae6e8 ;
# ec2 -> het
add Ec2PvtIP HetznerIP esp 0x74fce30b -E aes-cbc 0xf46c3187e253e5b25b8f8525da056080 -A hmac-sha256 0x9e7c6f6c7a1ccdd7634bb0a9eeaea5a8ed7bdfed89fd3f7dc86b2e8a522ae6e8 ;
More information
- To reduce the number of moving parts for now, I have enabled ALL traffic for my EC2 instance, both, at the iptables-level and Amazon Security Group level.
- Hetzner does NOT have a private IP at all. It only has a public IP.
- My intention is NOT to establish a private network (with private IPs) amongst all servers, given the assumption that once all traffic between servers is encrypted via IPSEC, they may as well communicate via public IPs. However, EC2 is sticking out like a sore-thumb in my multi-cloud setup because it forces public/private IPs on you.
As long as your Security Group and the local firewall on your Linux machine permit access for protocol ESP it should work.
One problem I see in your setup is with the SPDs. The EC2 doesn't know about its Public IP and Hetzner doesn't know about its private IP. Also you've got
transport
in the second SPD on Hetzner. You'll have to get the mix right.On EC2
On Hetzner
On Hetzner you'll then have to add a route to
Ec2PvtIP
viaEc2PubIP
.Also I find it easier and less confusing if the the tunnel internal addresses are completely independent from the endpoint addresses. E.g. I would create
dummy0 = 10.0.1.1/32
on EC2 anddummy0 = 10.0.1.2/32
on Hetzner and configure the tunnels appropriately:Routing is then more explicit too:
Alternatively use LibreSwan / OpenSwan rather than ipsec-tools where a simple config like this should work on an EC2 instance with a public IP, including key exchange and route management:
After years of using ipsec-tools I have now switched to LibreSwan and found it much easier to work with.
Update: Base on your update "My intention is NOT to establish a private network (with private IPs) amongst all servers, given the assumption that once all traffic between servers is encrypted via IPSEC, they may as well communicate via public IPs." you should try with transport more:
esp/transport/.../require
. In any case be consistent - you can't mixtunnel
andtransport
between the SPDs.Hope that helps :)