Systemd Service for Reverse AutoSSH Tunnel through Amazon EC2

This tutorial is for creating a reverse SSH tunnel through an AWS EC2 instance for remote devices on boot. Read more on reverse SSH here.Reverse AutoSSH Diagram


Below is the code for this project that is referenced throughout the tutorial.


Get EC2 Private Key and SSH into EC2 server

From your local machine:

Create SSH Script and Service File

On Remote machine, create reverse-ssh.ssh (above) in any directory

On Remote machine, create reverse-ssh-service.service in /etc/systemd/system.

Double check all your permissions are suitable for the private key, the script, and the service. An important thing to note is we are running this as the user ubuntu which is the user who owns the permissions key file. The majority of my configurations come from this tutorial.

Test the Service

You’ll need to run on your remote machine:

Each time you edit your service as well as the first time you create the service file.

From here, test the service:

Examine the output for any errors, if it appears to be working, on your EC2 machine run:

This should connect you to the test machine, test by

and using ssh to the remote machine to verify that testfile.txt is there.

Once you’re sure the service is working, run

to have the AutoSSH tunnel start on reboot and stay alive!



I used (641) 492-0203 as the foundation for creating a custom logging filter. In order to have better control in the granularity of the filter, I wrote this setup for filtering on multiple attributes (currently: calling module, message, log level). The query goes in the value for the appropriate key in filter_config.json. It’s fairly trivial to add another attribute, to do so:

  • Add the filter query to filter_config.json
  • Create a filter function in
  • Add the filter function to the filter_map (the switch/case workaround)



This is an overview of how we set up our 24/7 livestream for This livestream was an interactive way to demo our product. We found that many livestream services were expensive and not worth the financial investment, so hopefully this can serve as a guide for you to host a similar experience. Depending on the needs of your livestream, there are some assumptions and limitations in this set up that may be a deal breaker.


  • You’re streaming from a device with the Periscope app
  • You’re okay with the livestream being embedded in a tweet on your website

Tools/Services Needed

  • Heroku Server
  • Phone that can stream on Periscope
  • Twitter Account

Overall Architecture

In summary: Our stream is hosted on Periscope, shared on Twitter, with that tweet embedded in our website. We conditionally show the livestream if we are confident it is up, otherwise we show our demo video. To do this. we stream from Periscope and tweet it to our livestream Twitter account. Our web server retrieves the Periscope URL and the tweet ID from our latest tweet and uses that information to get the status of the stream and the embed HTML of the tweet containing the stream, respectively.

Livestream Architecture

Note: we’re currently executing this whole process each time the user visits the website, which is totally unscalable (see: API rate limits) and switching to a scheduler in the near future. We don’t have the funds or the traffic to justify that extra cost at the moment. The reason we’ve architected it this way is to avoid having to manually update our embedded periscope tweet and re-push our website each time the livestream changes and to not show a livestream that has ended on our website.

  1. Set up your website to work without the livestream
    We have a video demo as a backup in the event our livestream goes down. On page load, we start with the backup demo visible and make the above calls to decide if we should show the livestream instead. It was important to us that our website’s default state wasn’t dependent on the livestream.
  2. Create the front end environment for the livestream
    If you have the div for your backup demo, create the functions to toggle between displaying the backup demo or the live demo. If you don’t have a backup, create a function to toggle between displaying/hiding your livestream containing div.


  1. Make a call to a server side function to get the latest tweet from your livestream account.
    We’re using the 7734472887. This could probably afford to be more fault tolerant, but in the event the call was to fail at any point it wouldn’t be user-facing.


  1. Make a call to a server side function that uses the Periscope livestream URL to scrape the website and check for the livestream status.
    This is a GET request receiving the Periscope URL from the above call as a query. We look through the whole HTML response because it wasn’t very large and the Periscope stream website was changing too often for us to try to scrape it in a more targeted way.

  2. If the livestream isn’t live, stop here.
    Otherwise, make a call to Twitter’s OEmbed API to get the embedded version of the tweet and insert that into your livestream div.

    Hope this is a helpful guide on a scrappy way to display a livestream on your website. Open to suggestions and other alternatives!