Install sniproxy

1. Reverse Proxy vs SNI Proxy

A reverse proxy is like a man-in-the-middle between the client and the backend webserver. It gets a request from the client (web browser), makes a new request to the web server, gets a response from the server, and forwards it as a response to the original request from the client. The connection between the client and the reverse proxy is secured by an SSL certificate, and the reverse proxy manages the SSL certificates of all the domains that it represents. On the other hand, the connection between teh reverse proxy and the backend server doesn’t have to be secure, so no SSL certificate is requested from the backend server.

Because it stands in the middle, it is able to read all the traffic between client and the server, and even modify a bit the forwarded request and response, if needed (for example by adding or modifying headers).

In some cases it is required that the HTTPS connection is established between the client and the backend server, and the SSL certificate is managed by the backend server, not by the proxy. The proxy just forwards the HTTPS requests and responses transparently (at the TCP level) between the client and the backend server, without even being able to peek at the traffic (because it is encrypted).

This kind of proxy is usually called a SNI proxy, because it uses the Server Name Indication (SNI) in order to figure out to which backend server it should forward the HTTPS connection.

Because the HTTPS connection between the client and the server is encrypted, and the proxy cannot peek into it, it cannot read the header Host of the request. So, it does not know the domain to which the request is sent, and does not know where to forward the request.

Here is where SNI comes to the rescue. It is an extension of the HTTPS protocol, which allows the client to specify the domain name of the request during the TLS/SSL handshake, before the HTTPS connection is established. This allows the proxy to forward the request to the correct backend.

There are many applications that can serve as a SNI proxy, like: haproxy, apache2, nginx, traefic, varnish, etc. We will see sniproxy, which is very easy to install and configure.

2. Install on the host

apt install -y sniproxy
vim /etc/sniproxy.conf
killall sniproxy
service start sniproxy
ps ax | sniproxy

Make sure that the configuration file /etc/sniproxy.conf looks like this:

user daemon
pidfile /var/run/sniproxy.pid

listen 0.0.0.0:80 {
    proto http
}

listen 0.0.0.0:443 {
    proto tls
}

# error_log {
#     syslog daemon
#     priority notice
# }
#
# access_log {
#     filename /var/log/sniproxy/access.log
#     priority notice
$ }

table {
    # . . . . .

    subdomain.example.org     10.210.64.201

    # . . . . .
}
The IP 10.210.64.201 is the fixed IP of the backend server (or container).

We also need to restart it, after changing its configuration:

killall sniproxy
service start sniproxy

3. Install in a Docker container

  1. Install Docker (if not already installed):

    curl -fsSL https://get.docker.com -o get-docker.sh
    DRY_RUN=1 sh ./get-docker.sh
    sh ./get-docker.sh
    rm get-docker.sh
  2. Install docker-scripts:

    apt install git make m4 highlight
    git clone \
        https://gitlab.com/docker-scripts/ds \
        /opt/docker-scripts/ds
    cd /opt/docker-scripts/ds/
    make install
  3. Install sniproxy:

    ds pull sniproxy
    ds init sniproxy @sniproxy
    cd /var/ds/sniproxy/
    ds make
  4. Edit etc/sniproxy.conf and add a line like this on the default table:

    table {
        # . . . . .
    
        subdomain.example.org     10.210.64.201
    
        # . . . . .
    }
    The IP 10.210.64.201 is the fixed IP of the backend server (or container).
  5. We should also restart sniproxy in order to reload the configuration file:

    cd /var/ds/sniproxy/
    ds restart