2

EDIT: After the comments, more reading and several rounds with good colleagues we've come to the conclusion that as long as we do not have control over the back-end server, the usage of custom SSL ports will be impossible since we cannot instruct the back-end to facilitate it. I'll leave the question here, still, since it may help others in the future to reach the same conclusion and not waste hours of research. And the slight chance that someone may prove us wrong.

We have a chat server where customers can connect directly to our CS representatives. We have several web sites on different domains where an iframe chat box is served from and thus because off the cross-site scripting issue, we need to serve several different SSL certs on the reverse proxy. To solve this without setting up one NGINX reverse proxy per domain (there are many), we would like to serve all domains on custom ports on one NGINX, so it would look like this:

chat.domainA.com:443 -> chat_server:80

chat.domainB.com:2001 -> chat_server:80

chat.domainC.com:2002 -> chat_server:80

This is how I have tried to set then NGINX reverse proxy up:

server {
    listen 443 ssl;
    server_name chat.domainA.com;

    access_log /var/log/nginx/ssl-access.log;
    error_log /var/log/nginx/ssl-error.log;

    ssl_certificate /etc/nginx/ssl/chat.domainAbundle.com.crt.pem; # Cert chain
    ssl_certificate_key /etc/nginx/ssl/chat.domainA.com.key.pem;
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;

    [...]
    SSL Specific information, ciphers, etc
    [...]

    location / {
        proxy_pass http://internal_chat_server/;
        proxy_redirect off;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
server {
    listen 2001 ssl;
    server_name chat.domainB.com;

    access_log /var/log/nginx/ssl-access.log;
    error_log /var/log/nginx/ssl-error.log;

    ssl_certificate /etc/nginx/ssl/chat.domainBbundle.com.crt.pem; # Cert chain
    ssl_certificate_key /etc/nginx/ssl/chat.domainB.com.key.pem;
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;

    [...]
    SSL Specific information, ciphers, etc
    [...]

    location / {
        proxy_pass http://internal_chat_server/;
        proxy_redirect off;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
server {
    listen 2002 ssl;
    server_name chat.domainC.com;

    access_log /var/log/nginx/ssl-access.log;
    error_log /var/log/nginx/ssl-error.log;

    ssl_certificate /etc/nginx/ssl/chat.domainCbundle.com.crt.pem; # Cert chain
    ssl_certificate_key /etc/nginx/ssl/chat.domainC.com.key.pem;
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;

    [...]
    SSL Specific information, ciphers, etc
    [...]

    location / {
        proxy_pass http://internal_chat_server/;
        proxy_redirect off;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

The issue we are having is that if we access for instance https://chat.domainB.com:2001 then we get redirected back to https://chat.domainB.com (on port 443) where obviously we get a certificate error, since it is chat.domainA.com's certificate listening to that port. Connections to https://chat.domainA.com works fine.

We have tried several solutions to force the reverse proxy server to keep the port number, but no matter what we have tried it still reverts to port 443.

We've played with rewrites and sub-folders, redirects (which causes a loop), proxy_set_header Host $host:$server_port, etc. but nothing helps. Please do not regard the above config as our only attempt, this was just the "cleaner" code.

The internal chat server is a Cisco appliance which we cannot do any configuration on ourselves, so any configuration needs to be done on the reverse proxy. Do we really have to set up a reverse proxy per domain, or is there something we've overlooked?

Any help is highly appreciated.

OnkelJ
  • 96
  • 8
  • What is doing the redirect in the first place (it is not in the config you show). Can't you just switch it off? Also it is not clear for me why you don't want to configure one reverse proxy per domain for port 443 but instead have one reverse proxy per domain AND a different port - which is actually more complex and also prone to be blocked by firewalls since you no longer use standard ports. – Steffen Ullrich Nov 05 '19 at 07:33
  • I'm not sure what you ask for? What I want is that when we connect to for instance https://chat.domainB.com:2001/queueB/somepage.jsp that it stays like that and doesn't revert back to https://chat.domainB.com/queueB/somepage.jsp (now the port is gone, it has reverted back to :443). The Cisco appliance does this, but I wonder if there is any way to force NGINX to keep the port also. – OnkelJ Nov 05 '19 at 07:44
  • Check your `internal_chat_server` configuration (not in NGINX, but the chat server code itself). I bet that it is responsible for making the redirect to 443. – Daniel F Nov 05 '19 at 07:47
  • 1
    As I said previously it's a Cisco appliance in the back-end, which we cannot do any configuration on. I also suspect there's some hard coding at play here, but what I wondered about is if there's any way to override that on the reverse proxy, so it'll force the connection to keep the port number also. – OnkelJ Nov 05 '19 at 07:50
  • @OnkelJ: you are basically asking if nginx as reverse proxy can rewrite the response header Location. There is a [proxy_redirect](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect) for this. – Steffen Ullrich Nov 05 '19 at 07:53
  • Possible duplicate of [nginx proxy\_pass rewrite of response header location](https://serverfault.com/questions/678742/nginx-proxy-pass-rewrite-of-response-header-location) – Steffen Ullrich Nov 05 '19 at 07:54
  • I don't think a header rewrite in the response is the solution here. Since the redirection response is the actual response of the chat server. A way needs to be found to make the chat server think that the clients are connecting to NGINX by using port 443. – Daniel F Nov 05 '19 at 07:55
  • @OnkelJ i aint see any `server_name` configuration, how should nginx know about its name on the domain? and also please post `nginx -T` – djdomi Nov 05 '19 at 07:56
  • Have you tried setting `proxy_set_header Port 443;` to each entry? – Daniel F Nov 05 '19 at 07:58
  • @DanielF: I tried setting the proxy_set_header Port 443; and also with port 2001 for good measure. None helped :( – OnkelJ Nov 05 '19 at 08:09
  • @djdomi: the server_name config was edited in. nginx -T is not viable, since it contains a LOT more config than shown. – OnkelJ Nov 05 '19 at 08:11
  • @SteffenUllrich: I checked your link and tried the following redirect: `proxy_redirect $scheme://$host:$server_port/ /;` - but that didn't work, same result. Or did I use it incorrectly? – OnkelJ Nov 05 '19 at 08:13
  • @OnkelJ: It is unknown how exactly the original redirect looks like and what the result was and thus it is hard to tell what you might have done wrong. Make sure that the first argument to proxy_redirect actually matches the location returned by your local chat server. – Steffen Ullrich Nov 05 '19 at 08:27
  • @SteffenUllrich: I had a look at the curl -v output and the redirect was for https://internal_chat_server (note the SSL), so I added that to the proxy_pass directive, `proxy_pass https://internal_chat_server/;` ,but with the same result. – OnkelJ Nov 05 '19 at 08:43

0 Answers0