This is a Heroku buildpack that adds autossh to your heroku build and uses it to start an ssh tunnel from your dyno.
autossh is a program to start a copy of ssh and monitor it, restarting it as necessary should it die or stop passing traffic. More information about autossh can be found here: http://www.harding.motd.ca/autossh/
$ heroku create --buildpack https://github.com/quinde/heroku-buildpack-ssh-tunnel
$ git push heroku master
...
-----> Fetching custom git buildpack... done
-----> autossh app detected
-----> Installing autossh
Downloading autossh version 1.4e...
Building autossh...
Cleaning up...
Installation successful!
-----> Discovering process types
Procfile declares types -> (none)
-----> Compressing... done, 28K
-----> Launching... done, v3
When the build is complete you will be able to use autossh. It can be tested by doing the following:
$ heroku run bash
$ autossh
usage: autossh [-V] [-M monitor_port[:echo_port]] [-f] [SSH_OPTIONS]
-M specifies monitor port. May be overridden by environment
variable AUTOSSH_PORT. 0 turns monitoring loop off.
Alternatively, a port for an echo service on the remote
machine may be specified. (Normally port 7.)
-f run in background (autossh handles this, and does not
pass it to ssh.)
-V print autossh version and exit.
Environment variables are:
AUTOSSH_GATETIME - how long must an ssh session be established
before we decide it really was established
(in seconds). Default is 30 seconds; use of -f
flag sets this to 0.
AUTOSSH_LOGFILE - file to log to (default is to use the syslog
facility)
AUTOSSH_LOGLEVEL - level of log verbosity
AUTOSSH_MAXLIFETIME - set the maximum time to live (seconds)
AUTOSSH_MAXSTART - max times to restart (default is no limit)
AUTOSSH_MESSAGE - message to append to echo string (max 64 bytes)
AUTOSSH_PATH - path to ssh if not default
AUTOSSH_PIDFILE - write pid to this file
AUTOSSH_POLL - how often to check the connection (seconds)
AUTOSSH_FIRST_POLL - time before first connection check (seconds)
AUTOSSH_PORT - port to use for monitor connection
AUTOSSH_DEBUG - turn logging to maximum verbosity and log to
stderr
We will now go through setting up a persistant SSH tunnel from a Heroku build to a service provided on a remote server.
Most probably, you would like a Heroku build with more than just autossh. In this example we will use both the autossh and ruby buildpacks by leveraging Heroku's multi buildpack (https://github.com/heroku/heroku-buildpack-multi).
$ heroku create --buildpack https://github.com/heroku/heroku-buildpack-multi.git
In your project add a .buildpacks
file.
# .buildpacks
https://github.com/kollegorna/heroku-buildpack-autossh.git
https://github.com/heroku/heroku-buildpack-ruby.git#v138
This file informs Heroku to build the project using each of these buildpacks respectively. When pushing up your project you should see the following:
$ git push heroku master
...
-----> Fetching custom git buildpack... done
-----> Multipack app detected
=====> Downloading Buildpack: https://github.com/kollegorna/heroku-buildpack-autossh.git
=====> Detected Framework: autossh
-----> Installing autossh
Downloading autossh version 1.4e...
Building autossh...
Cleaning up...
Installation successful!
=====> Downloading Buildpack: https://github.com/heroku/heroku-buildpack-ruby.git
=====> Detected Framework: Ruby
-----> Compiling Ruby/Rails
-----> Using Ruby version: ruby-2.0.0
...
Note: The building and making of autossh can be time consuming. However the binary is then cached. Consecutive builds will skip the download, build and make steps of autossh.
Initialization of a SSH tunnel will require that you have the SSH keys that will grant you password free access to the remote server.
Add the keys to heroku as ENV variables:
$ heroku config:set SSH_PUBLIC_KEY="`cat path/to/public/key`"
$ heroku config:set SSH_PRIVATE_KEY="`cat path/to/private/key`"
Great! Now we have the necessary keys in place. Time to setup the tunnel.
To setup a SSH tunnel, you just need to set a $SSH_TUNNELS
ENV
variable with the details about the tunnel.
e.g:
$ herou config:set SSH_TUNNELS="user@ssh-server:ssh-port|127.0.0.1:local-port:target-host:remote-port"
If you want to set more than one tunnel, you can just add more
declarations to $SSH_TUNNELS
separating the values with commas.