0

I have my webapp with Nginx reverse proxy in front acting as LB. The hosted webapp has two components. UI and API. UI is normally accessible, but API needs client certificates for authentication. Both are on the same hostname as they are part of single webapp. Also, client uses same hostname mywebApp.com for UI and API.

I have headers userid and password which will distinguish the API request from other requests. Basically, if valid and matching headers are present in the request, attach proxy_ssl_certificate proxy_ssl_certificate_key proxy_ssl_trusted_certificate to the request, otherwise not.

My idea is to internally route this, request to a new hostname/server_name.

Here is my nginx configuration.

upstream my-webapp {
    hash $remote_addr;
    server my-app-1:8443;
    server my-app-2:8443;
    server my-app-3:8443;
}
map $http_userid $valid_user {
    default 0;
    validUsername 1;
}
map $http_password $valid_pass {
    default 0;
    validPassword 1;
}
map $valid_user$valid_pass $new_host {
    default "mywebApp.com";
    11 "api.mywebApp.com";
}
server {
    listen 80;
    return 301 https://$host_new$request_uri;
}
server {
    listen 443 ssl;
    server_name mywebApp.com;
    #...setting proxy headers
    location / {
        proxy_pass https://my-webapp/;
    }
}
server {
    listen 443 ssl;
    server_name api.mywebApp.com;
    #...setting proxy headers
    #...Additionally attach below certs
    proxy_ssl_certificate /etc/nginx/certs/api-cert.pem;
    proxy_ssl_certificate_key /etc/nginx/certs/api-key.key;
    proxy_ssl_trusted_certificate /etc/nginx/certs/ca-cert.pem;
    location / {
        proxy_pass https://my-webapp/;
    }
}

This configuration behaves wierdly, sometime UI requests get the certificates attached or sometimes API request goes without attaching certificates.

If there is another way to achieve it, without multiple sever blocks, please help.

dkrypt
  • 1
  • 1
  • The API should use its own hostname externally as well. – Michael Hampton Aug 13 '19 at 19:09
  • Thanks @MichaelHampton for your answer. Is it not going to work if that hostname is not externally available? Because my idea was to introduce the new hostname `api.mywebApp.com` only in nginx and not to client. Client uses common `mywebApp.com` for both. Is there other way for conditionally attaching the certs based on headers? – dkrypt Aug 13 '19 at 19:22

1 Answers1

0

Based on the comment from Michael, the approach taken was wrong. Nginx will only listen on server_names which are externally available as hostnames. I was incorrectly inspired by many QnAs which showed mapping www to non-www hostnames. Which was completely different, as the hostname example.com was still available.

Solved my problem by making the desired hostname available externally and then using that as server_name.

dkrypt
  • 1
  • 1