13

I'm trying to locate a high level configuration example for my current situation. We have a wildcard SSL certificate for multiple subdomains which are on several internal IIS servers.

site1.example.com (X.X.X.194) -> IISServer01:8081
site2.example.com (X.X.X.194) -> IISServer01:8082
site3.example.com (X.X.X.194) -> IISServer02:8083

I am looking to handle the incoming SSL traffic through one server entry and then pass on the specific domain to the internal IIS application. It seems I have 2 options:

  1. Code a location section for each subdomain (seems messy from the examples I have found)

  2. Forward the unencrypted traffic back to the same nginx server configured with different server entries for each subdomain hostname. (At least this appears to be an option).

My ultimate goal is to consolidate much of our SSL traffic to go through nginx so we can use HAProxy to load balance servers.

Will approach #2 work within nginx if I properly setup the proxy_set_header entries?

I envision something along the lines of this within my final config file (using approach #2):

server {
  listen Y.Y.Y.174:443; #Internally routed IP address
  server_name *.example.com;

  proxy_pass http://Y.Y.Y.174:8081;
}

server {
  listen Y.Y.Y.174:8081;
  server_name site1.example.com;

  -- NORMAL CONFIG ENTRIES --

  proxy_pass http://IISServer01:8081;
}

server {
  listen Y.Y.Y.174:8081;
  server_name site2.example.com;

  -- NORMAL CONFIG ENTRIES --

  proxy_pass http://IISServer01:8082;
}

server {
  listen Y.Y.Y.174:8081;
  server_name site3.example.com;

  -- NORMAL CONFIG ENTRIES --

  proxy_pass http://IISServer02:8083;
}

This seems like a way, but I'm not sure if it's the best way. Am I missing a simpler approach to this?

BrianM
  • 165
  • 1
  • 2
  • 8

2 Answers2

17

I would do something like this (tested with nginx 1.4.2, seems to work):

server {
  listen 127.0.0.1:443 ssl;
  server_name site1.example.com;

  include common.conf;

  location / {
    proxy_pass http://127.0.0.2:8081;
  }
}

server {
  listen 127.0.0.1:443 ssl;
  server_name site2.example.com;

  include common.conf;

  location / {
    proxy_pass http://127.0.0.2:8082;
  }
}

server {
  listen 127.0.0.1:443 ssl;
  server_name site3.example.com;

  include common.conf;

  location / {
    proxy_pass http://127.0.0.3:8083;
  }
}

With at least this in common.conf:

ssl on;
ssl_certificate  /path/to/cert;
ssl_certificate_key  /path/to/key;
Changaco
  • 880
  • 5
  • 10
  • With this approach though it would assume that the nginx instance is only serving one set of wildcard sites, correct? In the event of a site hosting multiple external IP addresses would I have to revert to my approach of processing the SSL first and the re-forwarding back into nginx? I think for my current project this will suffice so I'll upvote the response. I appreciate the example. – BrianM Sep 17 '13 at 16:02
  • No, you would just add more `server` blocks, listening on your other IP address, and create another file like `common.conf` but pointing to the other cert. – Changaco Sep 18 '13 at 08:20
  • 1
    Can you just use `listen 443 ssl` without the local ip? Isn't `127.0.0.1` implied? – jwerre Feb 19 '16 at 18:44
8

Believe it or not, you can do this:

ssl_session_cache shared:SSL:2m;
ssl_session_timeout 5m;

server {
    listen Y.Y.Y.174:443 default_server ssl;
    server_name _;
    ssl_certificate /etc/pki/tls/certs/server.chained.crt;
    ssl_certificate_key /etc/pki/tls/private/server.key;
}

server {
    listen Y.Y.Y.174:443 ssl;
    server_name site1.example.com;
    [...]
    proxy_pass http://IISServer01:8081;
}

server {
    listen Y.Y.Y.174:443 ssl;
    server_name site2.example.com;
    [...]
    proxy_pass http://IISServer01:8082;
}

server {
    listen Y.Y.Y.174:443 ssl;
    server_name site3.example.com;
    [...]
    proxy_pass http://IISServer02:8083;
}

No includes, the certificate is loaded into memory just once, and the session should even stay cached as the user moves from subdomain to subdomain, saving you plenty of handshake horsepower.

I can't find any documentation beyond this Server Fault post to suggest why this works, but I can assure you that it does.

Aaron Adams
  • 333
  • 2
  • 10
  • 1
    As stated by `nginx`' docs here http://nginx.org/en/docs/http/server_names.html `_` is just an illegal domain name that never match any real domain. Any other fake name like `--` or `!#@` can be used here. If `default_server` with illegal name and no served location defined it has no direct effect but unproceeded request is passed to the next `server` directive with `certificate` parameters initialized as side effect. – Kondybas Jul 18 '17 at 22:21
  • if the cert is the same for all domains, put them in the `http` block. in this example that is the same level as `ssl_session_cache` and `ssl_session_timeout`. – minusf Mar 13 '20 at 17:01