Edit:
If you are concerned about the connection between your reverse proxy (that terminates the SSL tunnel) and the content server being unsecured, although this does work and is secure, you might be better off configuring upstream SSL or a secure tunnel like SSH or IPSEC between the content server and your reverse proxy.
I got it working:
File structure:
ngnix/
config/
nginx.conf
http_server_name.js
docker-compose.yml
nginx.conf
load_module modules/ngx_stream_js_module.so;
events {}
stream {
js_import main from http_server_name.js;
js_set $preread_server_name main.get_server_name;
map $preread_server_name $http {
1.example.com server1_backend_http;
2.example.com server2_backend_http;
}
map $ssl_preread_server_name $https {
1.example.com server1_backend_https;
2.example.com server2_backend_https;
}
upstream server1_backend_http {
server 192.168.178.8:80;
}
upstream server1_backend_https {
server 192.168.178.8:443;
}
upstream server2_backend_http {
server 192.168.178.7:80;
}
server {
listen 443;
ssl_preread on;
proxy_pass $https;
}
server {
listen 80;
js_preread main.read_server_name;
proxy_pass $http;
}
}
docker-compose.yml
version: '3'
services:
ngnix:
image: nginx
container_name: ngnix
restart: unless-stopped
volumes:
- ./config/ngnix.conf:/etc/nginx/nginx.conf:ro
- ./config/http_server_name.js:/etc/nginx/http_server_name.js:ro
ports:
- "192.168.178.4:80:80"
- "192.168.178.4:443:443"
http_server_name.js
var server_name = '-';
/**
* Read the server name from the HTTP stream.
*
* @param s
* Stream.
*/
function read_server_name(s) {
s.on('upload', function (data, flags) {
if (data.length || flags.last) {
s.done();
}
// If we can find the Host header.
var n = data.indexOf('\r\nHost: ');
if (n != -1) {
// Determine the start of the Host header value and of the next header.
var start_host = n + 8;
var next_header = data.indexOf('\r\n', start_host);
// Extract the Host header value.
server_name = data.substr(start_host, next_header - start_host);
// Remove the port if given.
var port_start = server_name.indexOf(':');
if (port_start != -1) {
server_name = server_name.substr(0, port_start);
}
}
});
}
function get_server_name(s) {
return server_name;
}
export default {read_server_name, get_server_name}
Documentation:
ngx_http_upstream_module
ngx_http_map_module
ngx_stream_proxy_module
Edit:
Read this blog post for more info