Private Space VPN Connections
Last updated December 03, 2024
Table of Contents
Heroku Private Spaces and Shield Spaces can configure a connection to another private network using IPSec VPN. This lets dynos connect to hosts on your private networks and vice versa. Connections are established over the public Internet, but all traffic is encrypted using IPSec.
Currently, only one VPN connection (with two redundant tunnels) is supported per Private Space.
VPN connections are not yet available for Fir-generation spaces. Subscribe to our changelog to stay informed of when we add this feature to Fir.
Constraints
To use Private Space VPN connections, your private network and VPN hardware or software must conform to the following constraints:
- Your routable IP CIDRs must be one of the RFC 1918 blocks allocated for private internets.
- You cannot use an IP CIDR that is already being used by the Private Space. Currently, Private Spaces default to using
10.0.0.0/16
and172.17.0.0/16
, although different blocks can be specified when spaces are created.10.1.0.0/16
is also reserved if you have added any Heroku data services to your space. - Routes must be statically configured. Heroku does not support BGP.
- Your VPN gateway must be reachable from the public Internet via a static public IP address.
- If you have any firewalls in front of the VPN gateway, you must open UDP
4500
and UDP500
for traffic from Private Space VPN gateway IP addresses. - Your VPN gateway must use IKE v1 or v2 with the pre-shared key (PSK) authentication method.
- Heroku provides the pre-shared key. You must be able to set this key in your VPN gateway. Heroku cannot accept a pre-shared key generated by another party.
- You must configure your VPN gateway to use both IPSec tunnels provided by Heroku. Heroku occasionally takes one tunnel down for short maintenance windows and relies on the second tunnel to ensure uninterrupted network connectivity.
- Your VPN gateway is the initiator of the connection. The connection will not come up until you start transmitting packets to the Private Space VPN gateway.
- Database services, such as Heroku PostgreSQL, are not accessible through the VPN connection. You can use trusted IP allowlists to access data services directly.
Setting up the VPN Connection
You must know the public IP address of your VPN gateway and the desired routable IP CIDR blocks of your private network. After you obtain this information, set up a VPN gateway for the Private Space with the following command:
$ heroku spaces:vpn:connect \
--name office \
--ip PUBLIC_IP_OF_YOUR_VPN_GATEWAY \
--cidrs ROUTABLE_CIDRS_OF_YOUR_PRIVATE_NETWORK \
--space SPACE
Setting up the gateway takes a few minutes. Use the wait
command to wait for the gateway to be ready:
$ heroku spaces:vpn:wait --space SPACE office
When the gateway is ready, get the configuration with:
$ heroku spaces:vpn:info --space SPACE office
This returns a table containing all the details you need to configure your end of the VPN connection. Here is an example response:
$ heroku spaces:vpn:info --space acme-space office
=== acme-space VPNs
VPN Tunnel Customer Gateway VPN Gateway Pre-shared Key Routable Subnets IKE Version
────────── ──────────────── ───────────── ────────────── ──────────────── ───────────
Tunnel 1 52.91.173.226 34.203.187.158 abcdef12345 10.0.0.0/16 1
Tunnel 2 52.91.173.226 34.227.70.143 123456abcdef 10.0.0.0/16 1
How you configure your VPN gateway depends on the software or hardware. Regardless, the table returned by the spaces:vpn:info
command should contain everything you need. There is also a --json
option for the command, should you need more information.
This section below shows how to configure the StrongSwan software VPN gateway using these parameters. An example configuration for connecting to Google Cloud Platform is also available.
Changing IKE pre-shared keys
If you believe the credentials for your VPN tunnel have been compromised or wish to change them for other reasons, you must destroy the VPN Connection and then recreate it:
$ heroku spaces:vpn:destroy --space SPACE office
Follow the instructions above to recreate the VPN connection, which will generate new PSKs and possibly new gateway IP addresses. With the new PSKs and updated IP addresses, update the VPN configuration on the other end of the connection to re-establish connectivity.
Compatibility
Heroku VPN is based on the managed AWS VPN product. Check the AWS docs for details on VPN gateway device compatibility, and check here specifically for AWS gateway device requirements.
Heroku has validated that this VPN feature is compatible with the managed Google Cloud Platform VPN feature. See the VPN Connection to GCP Dev Center article for details.
To setup a site-to-site VPN connection between Heroku and Azure see this community-maintained guide.
StrongSwan configuration example
One example of a VPN gateway is the StrongSwan open-source VPN gateway that runs on most Linux distributions. Below are example configuration files that include indicators of what to fill in from the Heroku VPN configuration shown above.
/etc/ipsec.conf
config setup
strictcrlpolicy=no
uniqueids = no
charondebug=all
conn vpn1
type=tunnel
compress=no
keyexchange=ikev1
esp=aes256-sha2-modp2048!
ike=aes256-sha2-modp2048!
ikelifetime=28800s
lifetime=1h
authby=secret
auto=route
left=<private ip of your VPN host, e.g. 172.16.0.2>
leftid=<private ip of your host, e.g. 172.16.0.2>
leftsubnet=<your routable network, e.g. 172.16.0.0/16>
right=<IP address of Private Space tunnel #1>
rightid=<IP address of Private Space tunnel #1>
rightsubnet=<cidr of private space ("Routable Subnets" from config)>
dpddelay=10
dpdtimeout=30
dpdaction=restart
keyingtries=%forever
conn vpn2
type=tunnel
compress=no
keyexchange=ikev1
esp=aes256-sha2-modp2048!
ike=aes256-sha2-modp2048!
ikelifetime=28800s
lifetime=1h
authby=secret
auto=route
left=<private ip of your host, e.g. 172.16.0.2>
leftid=<private ip of your host, e.g. 172.16.0.2>
leftsubnet=<your routable network, e.g. 172.16.0.0/16>
right=<IP address of Private Space tunnel #2>
rightid=<IP address of Private Space tunnel #2>
rightsubnet=<cidr of private space ("Routable Subnets" from config)>
dpddelay=10
dpdtimeout=30
dpdaction=restart
keyingtries=%forever
/etc/ipsec.secrets
<IP address of Private Space tunnel #1> : <pre-shared key for Private Space tunnel #1>
<IP address of Private Space tunnel #2> : <pre-shared key for Private Space tunnel #2>
Assuming the following sample values:
- VPN gateway configuration from JSON document above
- Your network at
172.16.0.0/16
- Your VPN gateway private IP
172.16.0.2
- Heroku Space network at
10.0.0.0/16
The configuration files look like this:
/etc/ipsec.conf
config setup
strictcrlpolicy=no
uniqueids = no
charondebug=all
conn vpn1
type=tunnel
compress=no
keyexchange=ikev1
esp=aes256-sha2-modp2048!
ike=aes256-sha2-modp2048!
ikelifetime=28800s
lifetime=1h
authby=secret
auto=route
left=172.16.0.2
leftid=172.16.0.2
leftsubnet=172.16.0.0/16
right=34.203.187.158
rightid=34.203.187.158
rightsubnet=10.0.0.0/16
dpddelay=10
dpdtimeout=30
dpdaction=restart
keyingtries=%forever
conn vpn2
type=tunnel
compress=no
keyexchange=ikev1
esp=aes256-sha2-modp2048!
ike=aes256-sha2-modp2048!
ikelifetime=28800s
lifetime=1h
authby=secret
auto=route
left=172.16.0.2
leftid=172.16.0.2
leftsubnet=172.16.0.0/16
right=34.227.70.143
rightid=34.227.70.143
rightsubnet=10.0.0.0/16
dpddelay=10
dpdtimeout=30
dpdaction=restart
keyingtries=%forever
/etc/ipsec.secrets
34.203.187.158 : PSK "abcdef12345"
34.227.70.143 : PSK "123456abcdef"