greenPadawan
greenPadawan

Reputation: 1571

Nginx subdomain redirection using SSL not working

I have a domain example.com. I'd like to run multiple applications over its subdomains and enable https over them.

I have used certbot to create a certificates for the *.example.com and example.com domains.

There are three applications which handle the requests from different subdomains.

  1. Application app1 handles the request from the subdomain abc.example.com only.
  2. Application app2 handles the request from the subdomains of the form [some_name].example.com.
  3. Application app3 handles the request from the example.com only.

I am facing the following problems.

  1. When I try to access the domain abc.example.com from the browser, it redirects to www.abc.example.com, which then gives an invalid certificate error.
  2. Using the regular expression for server name causes all the requests to be redirected to the app1.
  3. When I try to access the domain example.com from the browser, it redirects to www.www.abc.example.com, which is an invalid domain.

I am not sure what seems to be the problem. Is it the regex for server name? Also, is there any other better way which can be used for this scenario? Any help is appreciated.

Note: The applications are hosted as docker containers in the same docker network.


The following is the nginx conf file.

server {
  listen 80;
  listen [::]:80;
  charset utf-8;
  access_log off;
  server_name example.com;

  location / {
    rewrite ^ https://$host$request_uri? permanent;
  }
}

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name example.com;

  server_tokens off;
  ssl on;

  ssl_certificate /etc/letsencrypt/live/example.com-0001/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com-0001/privkey.pem;

  ssl_buffer_size 8k;

  ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;

  ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
  ssl_prefer_server_ciphers on;

  ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

  ssl_ecdh_curve secp384r1;
  ssl_session_tickets off;

  # OCSP stapling
  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 8.8.8.8;

  return 301 https://www.example.com$request_uri;
}


server {
  server_name www.example.com;
  listen 443 ssl http2;
  listen [::]:443 ssl http2;

  server_tokens off;

  ssl on;

  ssl_buffer_size 8k;
  ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;

  ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
  ssl_prefer_server_ciphers on;
  ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

  ssl_ecdh_curve secp384r1;
  ssl_session_tickets off;

  # OCSP stapling
  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 8.8.8.8 8.8.4.4;

  ssl_certificate /etc/letsencrypt/live/example.com-0001/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com-0001/privkey.pem;

  location / {
    proxy_pass http://app3:80;
    proxy_set_header Host $host:$server_port;
    proxy_set_header X-Forwarded-Host $server_name;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

server {
  listen 80;
  listen [::]:80;
  charset utf-8;
  access_log off;
  server_name abc.example.com;

  location / {
     rewrite ^ https://$host$request_uri? permanent;
  }
}

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name abc.example.com;

  server_tokens off;
  ssl on;

  ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

  ssl_buffer_size 8k;

  ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;

  ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
  ssl_prefer_server_ciphers on;

  ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

  ssl_ecdh_curve secp384r1;
  ssl_session_tickets off;

  # OCSP stapling
  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 8.8.8.8;

  location / {
    proxy_pass http://app1:80;
    proxy_set_header Host $host:$server_port;
    proxy_set_header X-Forwarded-Host $server_name;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

server {
  listen 80;
  listen [::]:80;
  charset utf-8;
  access_log off;
  server_name ~^(?!abc|www).+\.example\.com$ ~^www\.(?!abc|www).+\.example\.com$;

  location / {
    rewrite ^ https://$host$request_uri? permanent;
  }
}

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name ~^(?!abc|www).+\.example\.com$ ~^www\.(?!abc|www).+\.example\.com$;

  server_tokens off;
  ssl on;

  ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

  ssl_buffer_size 8k;

  ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;

  ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
  ssl_prefer_server_ciphers on;

  ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

  ssl_ecdh_curve secp384r1;
  ssl_session_tickets off;

  # OCSP stapling
  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 8.8.8.8;

  location / {
    proxy_pass http://app2:80;
    proxy_set_header Host $host:$server_port;
    proxy_set_header X-Forwarded-Host $server_name;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

Upvotes: 2

Views: 58

Answers (1)

greenPadawan
greenPadawan

Reputation: 1571

Thanks to the clues from @Steffen Ullrich, I finally got this working.

I removed all the redirects to www.example.com and www.*.example.com.

Specifically, the following server block.

server {
  server_name www.example.com;
  listen 443 ssl http2;
  listen [::]:443 ssl http2;

  server_tokens off;

  ssl on;

  ssl_buffer_size 8k;
  ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;

  ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
  ssl_prefer_server_ciphers on;
  ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

  ssl_ecdh_curve secp384r1;
  ssl_session_tickets off;

  # OCSP stapling
  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 8.8.8.8 8.8.4.4;

  ssl_certificate /etc/letsencrypt/live/example.com-0001/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com-0001/privkey.pem;

  location / {
    proxy_pass http://app3:80;
    proxy_set_header Host $host:$server_port;
    proxy_set_header X-Forwarded-Host $server_name;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

Additionally, I changed the regex for wildcard server names from ~^(?!abc|www).+\.example\.com$ ~^www\.(?!abc|www).+\.example\.com$ to ~^(?!api|www)\w+\.example\.com$

Upvotes: 1

Related Questions