heroku-buildpack-ssh-tunnel

by quinde

GitHub Readme.md

Heroku buildpack to setup ssh tunnels

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/

Usage

$ 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

Advanced Usage

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.

Setup SSH Keys

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.

Setup SSH 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.