Skip to content

Instantly share code, notes, and snippets.

@nakwa
Last active October 28, 2023 17:42
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save nakwa/652daaf5f87c038189eb65b9ac68476c to your computer and use it in GitHub Desktop.
Save nakwa/652daaf5f87c038189eb65b9ac68476c to your computer and use it in GitHub Desktop.
Reverse proxy server for local tunnel / with HTTPS forwarding

Reverse proxy as a local tunnel / with HTTPS forwarding

Using SSH forwarding, NGINX, LetsEncrypt & Docker (Ruby-on-rails & Puma as dev server in current setup)

Stack & config

Gemfile

ruby '2.6.5'
gem 'puma', '4.3.1'
gem 'pg', '1.2.2'
gem 'rails', '~> 6.0.2.1'

Rails config:

config.force_ssl = true

Starting Puma with SSL:

bundle exec rails s -b 'ssl://localhost:3000?key=/path/to/app/private/ssl/proxy.key&cert=/path/to/app/private/ssl/proxy.cert'

OpenSSL

OpenSSL 1.1.1d  10 Sep 2019

Install

  1. Set-up server, and point domain (DNS A) to the its IP (dedicated (sub)domain is required for SSL cert). e.g. proxy.yourdomain.tld

  2. Install docker on the server

  3. Create Dockerfile:

FROM ubuntu:16.04
ARG ROOTPW=rootpassword
RUN apt-get update && apt-get install -y openssh-server
RUN mkdir /var/run/sshd
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN echo "GatewayPorts yes" >> /etc/ssh/sshd_config
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile
RUN echo root:${ROOTPW} | chpasswd
EXPOSE 22 80
CMD ["/usr/sbin/sshd", "-D"]
  1. Build SSH proxy container:
docker build -t ssh-proxy . --build-arg ROOTPW=mypassword
  1. Install and run NGINX proxy and NGINX proxy :
docker run --detach \
       --name nginx-proxy \
       --publish 80:80 \
       --publish 443:443 \
       --volume /etc/nginx/certs \
       --volume /etc/nginx/vhost.d \
       --volume /usr/share/nginx/html \
       --volume /var/run/docker.sock:/tmp/docker.sock:ro \
       jwilder/nginx-proxy
docker run --detach \
--name nginx-proxy-letsencrypt \
       --volumes-from nginx-proxy \
       --volume /var/run/docker.sock:/var/run/docker.sock:ro \
       --env "DEFAULT_EMAIL=contact@yourdomain.tld" \
       jrcs/letsencrypt-nginx-proxy-companion
  1. Run SSH proxy container: It's critical to properly replace all proxy.yourdomain.tld with actual domain used.
docker run --detach \
       --name dev-proxy \
       --publish 2222:22 \
       --env "VIRTUAL_HOST=proxy.yourdomain.tld" \
       --env "LETSENCRYPT_HOST=proxy.yourdomain.tld" \
       --env "VIRTUAL_PROTO=https" \
       ssh-proxy
  1. Run SSH:
ssh -NR :443:localhost:3000 -R :80:localhost:3000 -p 2222 root@proxy.yourdomain.tld -v
  1. That's it! You can now access https://proxy.yourdomain.tld pointing to https://localhost:3000
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment