Instantly share code, notes, and snippets.

Embed
What would you like to do?
SNI Proxy Tutorial

SNI Proxy for sharing an SSL port 443 with Sandstorm

Make Sandstorm and other web server coexist in the same port while keeping HTTPS encryption.

Introduction

The purpose of this tutorial is to set up SNI Proxy so it’s possible to use Sandstorm verified SSL encryption while coexisting with another web server that also uses SSL.

The main reason is to allow other users to connect with your Sandstorm instance in the standard HTTPS port (443) and keep using that port also for any other web apps.

I assume the server is running Debian Linux or one of its derivatives (e.g. Ubuntu). Note that there will be some down time in this process so you might want to do it when there is less activity on your server.

Install SNI Proxy

If you’re lucky the package sniproxy might be present on your linux distro otherwise you’ll hace to install it yourself. In my case (Ubuntu 10.04 I had to do it manually). Follow the instructions on https://github.com/dlundquist/sniproxy to create the Debian package and install it.

In my case I had to do the following:

# Install required packages
sudo apt-get install autotools-dev cdbs debhelper dh-autoreconf dpkg-dev gettext libev-dev libpcre3-dev libudns-dev pkg-config fakeroot git

# Clone SNI Proxy repo from Github 
git clone https://github.com/dlundquist/sniproxy.git

# Compile and create the package
cd sniproxy
./autogen.sh && dpkg-buildpackage

# Install the package
sudo dpkg -i ../sniproxy_<version>_<arch>.deb

Setting it up

We’ ll be using SNI Proxy to listen for the standard HTTPS port (443) and make it process the domain name. If it’s a Sandstorm domain (ends in .sandcats.io) it will forward the request to Sandstorm on port 9687. In any other case it’ll forward the request to the web server you already had which switched from listening on port 443 to port 9686.

The ports for Sandstorm and the web server are arbitrary, you can set the ones that work for you in case you have a collision with another service you’re running. It should work as long as you’re being consistent in replacing my choices over the web server, Sandstorm and SNI Proxy configurations.

Created with Raphaël 2.1.2TLS requestSNI Proxy (port 443)Sandstorm domain?Forward to SandstormSandstorm daemon (port 9687)Forward to web serverHTTPS daemon (port 9686)yesno

Setting up SNI Proxy

We’ll set sniproxy to forward Sandstorm domains to the Sandstorm instance and to send any other request to the web server. We’ll disable HTTP proxy on sniproxy as there is no need for the HTTP requests to go through it.

Configuration

sudo vi /etc/sniproxy.conf

/etc/sniproxy.conf contents:

# sniproxy.conf
# Setup for sharing port 443 with Sandstorm

user daemon
pidfile /var/run/sniproxy.pid

error_log {
    syslog daemon
    priority notice
}

listen 443 {
    proto tls
    table https_hosts
    fallback 127.0.0.1:9686

    access_log {
        filename /var/log/sniproxy/https_access.log
        priority notice
    }
}

table https_hosts {
    .*\.sandcats\.io 127.0.0.1:9687
}

Startup

We’ll have to ensure SNI Proxy starts when rebooted. For that we’ll need to ensure is enabled in /etc/default/sniproxy (ENABLED=1) and also that will automatically start on boot up using the following command:

sudo update-rc.d sniproxy enable

Setting up Sandstorm

Enabling SSL support on Sandstorm is out of the scope of this tutorial. If you don’t have it setup yet head to the official documentation (https://docs.sandstorm.io/en/latest/administering/ssl/).

The only thing we need to tweak is setting the port to the one the SNI Proxy is forwarding the requests to (9687 in these examples) and keep (or make depending on your current setup) the URLs on port 443 (the standard, so no :443 at the end). We’ll assume you have a alias.sandcats.io as your Sandstorm address in the configuration example.

sudo vi /opt/sandstorm/sandstorm.conf

Relevant contents of /opt/sandstorm/sandstorm.conf:

# Bind localhost to avoid anyone connecting directly to Sandstorm
BIND_IP=127.0.0.1
# No ports here, standard HTTPS (port 443)
BASE_URL=https://alias.sandcats.io
WILDCARD_HOST=*.alias.sandcats.io
# This is the port SNI Proxy will connect to
HTTPS_PORT=9687

Setting up your current web server

This will depend on the server you have. Remember the accesable URLs will still use the standard HTTPS port, this change is only made to allow the SNI Proxy to sit in the middle.

I’m using Nginx and I could change all the configuration files using sed to replace 443 for 9686. What I did is:

sudo sed -ri 's/443/9686/g' /etc/nginx/sites-available/*

Keep in mind this might not work for you if you’re using ‘443’ anywhere in the configurarion files that is not to refer the port.

Final steps, put it to work

Now is the time to see if it worked. Shutdown your web server and Sandstorm and start them again. Start sniproxy as well.

sudo service nginx stop
sudo service sandstorm stop
sudo service sniproxy start
sudo service sandstorm start
sudo service nginx start

Now you can test by trying to get to your Sandstorm instance using https://alias.sandcats.io (put your alias) and also test that any other https service you had before works (something like https://service.yourdomain.com).

Written with StackEdit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment