This heroku buildpack makes it possible for an application to establish ssh tunnel to reach a remote host. This buildpack must be used with a language-specific buildpack as a supplement.
- Add this buildpack as your initial buildpack. The
-i 1
flag makes sure this buildpack comes before your language specific buildpack.
$ heroku buildpacks:add -i 1 https://github.com/emartech/heroku-buildpack-ssh-tunnel#subprocess --app [app name]
Note: Use the subprocess
branch of this buildpack. The master
branch only exists for backwards-compatibility.
- Make sure your language specific buildpack is also set for your application. Probably there is no need to do anything here, but check it like so:
$ heroku buildpacks --app [app name]
=== [app name] Buildpack URLs
1. https://github.com/emartech/heroku-buildpack-ssh-tunnel#subprocess
2. heroku/php
If you do not see your language specific buildpack, add it (nodejs in this case):
$ heroku buildpacks:add heroku/nodejs --app [app name]
Refer to the buildpack documentation for further help.
- Generate SSH key-pair. Do not set a password for the key.
$ ssh-keygen -t rsa -b 4096 -C "[app name]@heroku.com"
Distribute the public key to the remote party.
-
Configure the environment variables.
-
Edit your
Procfile
, so that the dynos that use SSH tunneling are started with thebin/start-ssh-tunnel
command. Prepend the actual starting command with this executable. If you do not have aProcfile
, create one. For example:
web: bin/start-ssh-tunnel vendor/bin/heroku-php-apache2 web/
or
web: bin/start-ssh-tunnel npm start
- Update your connection strings (e.g.
REDIS_URL
) to go through the specified SSH tunnel. For example if the connection string without SSH tunnel is
REDIS_URL=redis://admin:[password]@aws-eu-west-1-portal.10.dblayer.com:18106
and your tunnel configuration is like
SSHTUNNEL_TUNNEL_CONFIG='127.0.0.1:6379 [REDIS_HA_PROXY_IP]:[REDIS_HA_PROXY_PORT]'
then your connection string becomes
REDIS_URL=redis://admin:[password]@127.0.0.1:6379
Configuration | Value |
---|---|
openssh connect timeout | 10 sec |
keepalive interval | 10 sec |
maximum number of keepalives | 3 |
reconnect after | 5 sec |
The buildpack creates an ssh tunnel on the basis of the environment variables configured for Heroku:
SSHTUNNEL_PRIVATE_KEY
: Private key for connecting to the tunnel hostSSHTUNNEL_TUNNEL_CONFIG
: Tunnel configuration (openssh -L syntax, note the space between the local and remote parts)[LOCAL_HOST]:[LOCAL PORT] [REMOTE_HOST]:[REMOTE_PORT]
SSHTUNNEL_REMOTE_USER
: Username for connecting to the tunnel serverSSHTUNNEL_REMOTE_HOST
: The tunnel server hostnameSSHTUNNEL_REMOTE_PORT
: (optional) Port for connecting the tunnel server. Default is 22.
- It takes time (although very little) to build the SSH tunnel. So there is a chance that your application might try to connect to the remote party before the tunnel is built, in which case it is going to fail. If your library automatically reconnects to the resource, then this is a non-issue. If it does not, however, you need to make sure to retry or wait within your application.
The buildpack logs to the standard output with the 'ssh-tunnel' prefix.
Event | Description |
---|---|
starting | logged on dyno start |
spawned | logged after "tunnel-daemon" starts |
missing-configuration | logged on any missing configuration (tunnel-daemon is not started as variables are not defined properly) |
ssh-connection-init | logged before initiating ssh connection |
ssh-connection-end | logged after the ssh connection ends or there is a connection error |
TBD