There are probably better ways to do this, but I found this to work.

I need to test a Twilio API right now. Whenever I do this, I have to deal with the situation where the Twilio sandbox server has to talk to my development computer. I do not want to constantly deploy my application to some server, so proxying the request is the easier approach.

The first time I did this, I was using Swiftiply and it worked fine. However, I tried to install it today in Xubuntu and it didn’t immediately compile. Since I do not want to spend time working on getting Swiftiply to compile properly, I decided on something else. After some thought, I realized I can effectively do this with Nginx and a SSH reverse proxy.

The man page for ‘ssh’ tells us that:

“Specifies that the given port on the remote (server) host is to be forwarded to the given host and port on the local side. This works by allocating a socket to listen to port on the remote side, and whenever a connection is made to this port, the connection is forwarded over the secure channel, and a connection is made to host port hostport from the local machine.”

It says to use this syntax:

-R [bind_address:]port:host:hostport

So, to start, we want to make sure that we fork a new SSH connection and not execute remote commands (by default, this would be bash, I think.)

ssh -fNR 56789:localhost:3000 user@example.com

56789 is the port that the example.com server would connect to and 3000 is the local web server port, on your computer.

Then, all that is needed on the remote (public) server is an Nginx configuration. Here is a snippet:

upstream test_proxy {
    server 127.0.0.1:56789;
}

Test proxy frontend

server {
    listen 9000;
    server_name _;
    client_max_body_size 4G;
    keepalive_timeout 70;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_buffering on;

    location / {
        proxy_pass http://test_proxy;
    }

    location @test_proxy {
        internal;
        proxy_pass http://test_proxy;
        break;
    }
}

When you turn on Nginx on the public server and turn on your server, then you can hit http://example.com:9000, and you should see the content from your local server.