├── Dockerfile ├── LICENSE.txt ├── README.md ├── init ├── ssh-config └── supervisord.conf /Dockerfile: -------------------------------------------------------------------------------- 1 | # Tunneled reverse proxy using SSH and nginx. 2 | 3 | FROM hansd/nginx 4 | MAINTAINER Nicolas Cadou 5 | 6 | ENV DEBIAN_FRONTEND noninteractive 7 | 8 | RUN apt-get install -y autossh supervisor && \ 9 | apt-get clean 10 | 11 | RUN mkdir /root/.ssh/ 12 | ADD ssh-config /root/.ssh/config 13 | RUN chown -R root:root /root/.ssh && \ 14 | chmod 700 /root/.ssh 15 | 16 | ADD supervisord.conf /etc/supervisor/ 17 | ADD init /usr/local/sbin/init.ssh-reverse-proxy 18 | 19 | ENTRYPOINT ["/usr/local/sbin/init.ssh-reverse-proxy"] 20 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Nicolas Cadou 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Nginx reverse proxy docker environment 2 | ====================================== 3 | 4 | Uses Hans Donner's nginx docker container as a base: 5 | https://raw.github.com/hans-d/docker-nginx/ 6 | 7 | Allows serving up HTTP content (e.g. from your dev box) to the internet at 8 | large despite being otherwise unaccessible behind a firewalled home router, 9 | without having to open any ports on said router. The trick consists of using 10 | SSH's remote forwards on a publicly accessible server. 11 | 12 | Uses the default nginx configuration, and will include everything in 13 | `/data/nginx`. 14 | 15 | SSH HTTP tunnel 16 | --------------- 17 | 18 | In addition to running nginx, the container will connect to the SSH server of 19 | your choice to tunnel HTTP traffic back to itself. Parameters are configurable 20 | through environment variables given to `docker run`. 21 | 22 | Those variables are: 23 | - `HTTP_TUNNEL_HOST` (hostname of the SSH server to connect to) 24 | - `HTTP_TUNNEL_PORT` (SSH server port) 25 | - `HTTP_TUNNEL_USER` (SSH username) 26 | - `HTTP_TUNNEL_IDENTITY` (name of the SSH private key in `/data/ssh`) 27 | 28 | As an example, you could use a WebFaction account to pipe all HTTP traffic to 29 | your development computer at home. 30 | 31 | To accomplish this you would add a website in your WebFaction control panel 32 | using the domain name of your choice, with a single `Custom app (listening on 33 | port)` application mounted on `/`. WebFaction will assign a port to your app 34 | which you will reuse like so (assuming you neatly place all your docker 35 | volumes in some location like `/srv/docker/volumes`): 36 | 37 | ``` 38 | export VOLUMES=/srv/docker/volumes/ssh-reverse-proxy 39 | sudo mkdir -p $VOLUMES/data/ssh 40 | sudo ssh-keygen -f $VOLUMES/data/ssh/tunnel-key 41 | docker run -d --name ssh-reverse-proxy \ 42 | -v $VOLUMES/data:/data \ 43 | -v $VOLUMES/log:/var/log \ 44 | -e HTTP_TUNNEL_HOST=.webfactional.com \ 45 | -e HTTP_TUNNEL_PORT= \ 46 | -e HTTP_TUNNEL_USER= \ 47 | -e HTTP_TUNNEL_IDENTITY=tunnel-key ncadou/ssh-reverse-proxy 48 | ``` 49 | 50 | You would also need to add `tunnel-key.pub` to your WebFaction shell account's 51 | `~/.ssh/authorized_keys` file. Because the private key you just created can't 52 | have a passphrase (so that the container can use it unattended) it's probably a 53 | good idea to make it useless for anything but port forwarding, by prepending 54 | something like this to it: 55 | 56 | `command="/bin/true",no-X11-forwarding,no-agent-forwarding,no-pty` 57 | 58 | Once the container has been created with `docker run`, it can be controlled 59 | with `docker (stop|start|restart) ssh-reverse-proxy`. If left running at system 60 | shutdown, the docker daemon will automatically restart it at the next boot. 61 | 62 | What nginx is going to serve, and under which domain(s), is left an exercise to 63 | you, the user. Just add whatever is needed in `/data/nginx` and have at it. 64 | 65 | Note: if you want to access the nginx server locally, just add `-p 80:80` to 66 | the `docker run` command above, and fire up a browser to http://localhost. 67 | 68 | Volumes 69 | ------- 70 | 71 | - `/data`: website 72 | - `/data/nginx`: additional configuration for nginx 73 | - `/data/ssh`: SSH keys for the HTTP tunnel 74 | - `/var/log`: logging 75 | - `/var/log/nginx`: output of nginx (as per default configuration) 76 | -------------------------------------------------------------------------------- /init: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | test -d /data/ssh || mkdir /data/ssh; 4 | chmod 700 /data/ssh 5 | test "$(ls -A /data/ssh)" || echo "Add SSH identity to /data/ssh, and restart" 6 | 7 | test -n "$HTTP_TUNNEL_HOST" && \ 8 | sed -i "s/HTTP_TUNNEL_HOST/$HTTP_TUNNEL_HOST/" /root/.ssh/config 9 | test -n "$HTTP_TUNNEL_PORT" && \ 10 | sed -i "s/HTTP_TUNNEL_PORT/$HTTP_TUNNEL_PORT/" /root/.ssh/config 11 | test -n "$HTTP_TUNNEL_USER" && \ 12 | sed -i "s/HTTP_TUNNEL_USER/$HTTP_TUNNEL_USER/" /root/.ssh/config 13 | if [ -n "$HTTP_TUNNEL_IDENTITY" ] 14 | then 15 | test -f /data/ssh/$HTTP_TUNNEL_IDENTITY && \ 16 | cp -a /data/ssh/$HTTP_TUNNEL_IDENTITY /root/.ssh/identity && \ 17 | chmod 600 /root/.ssh/identity 18 | fi 19 | 20 | exec supervisord 21 | -------------------------------------------------------------------------------- /ssh-config: -------------------------------------------------------------------------------- 1 | Host * 2 | ServerAliveInterval 10 3 | StrictHostKeyChecking no 4 | 5 | Host http-tunnel 6 | HostName HTTP_TUNNEL_HOST 7 | User HTTP_TUNNEL_USER 8 | RemoteForward HTTP_TUNNEL_PORT localhost:80 9 | IdentityFile ~/.ssh/identity 10 | -------------------------------------------------------------------------------- /supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | nodaemon=true 3 | 4 | [program:http-tunnel] 5 | command=/usr/bin/autossh -qN http-tunnel 6 | 7 | [program:nginx] 8 | command=/docker/scripts/nginx-start 9 | --------------------------------------------------------------------------------