0

Not an NGINX guru but I've made the changes that I believe will work. This is PROD server so don't just want to push to it and hope for the best.

What I'm trying to do is have both subdomains and domains redirect to it's respective pages. For example when someone enters https://example.com I need it to do to https://example.com when someone enters https://learning.example.com I need it to go to https://learning.example.com and finally when someone enters https://www.learning.example.com i need server to redirect to https://learning.example.com. If all that makes sense.

Below code I believe (but could be wrong) should be working, but would appreciate If someone could review it and fix potential issues that might cause.

server {
        listen 80;
        listen [::]:80;
        server_name *.example.com;

        location ~ /.well-known/acme-challenge {
                allow all;
                root /var/www/html;
        }

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

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

        server_tokens off;

        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.3 TLSv1.2;
        ssl_prefer_server_ciphers on;

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

        ssl_ecdh_curve secp384r1;
        ssl_session_tickets off;

        ssl_stapling on;
        ssl_stapling_verify on;
        resolver 8.8.8.8;

        return 301 https://$host$request_uri;
}

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

        gzip on;
        gzip_disable "MSIE [1-6]\.(?!.*SV1)";
        gzip_min_length  500;
        gzip_buffers  4 32k;
        gzip_types  text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml image/svg;
        gzip_vary 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.3 TLSv1.2;
        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;

        ssl_stapling on;
        ssl_stapling_verify on;
        resolver 8.8.8.8;

        location ~*  \.(jpg|jpeg|png|gif|ico)$ {
                expires 365d;
        }

        location / {
                try_files $uri @nodejs;
        }

        location @nodejs {
                proxy_pass http://nodejs:8080;
                add_header X-Frame-Options "SAMEORIGIN" always;
                add_header X-XSS-Protection "1; mode=block" always;
                add_header X-Content-Type-Options "nosniff" always;
                add_header Referrer-Policy "no-referrer-when-downgrade" always;
                add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
                # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
                # enable strict transport security only if you understand the implications
        }

        location /graphql {
                proxy_pass http://nodejs:8080;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_set_header Host $host;
        }

        root /var/www/html;
        index index.html index.htm index.nginx-debian.html;
}
TSlegaitis
  • 101
  • 2

1 Answers1

0

You have an error in your second server block.

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name www.example.com;
    ...
    return 301 https://$host$request_uri;
}

$host in this case would resolve to the server_name, which means this will cause a redirect loop.

To redirect from www. prefix to host without prefix, you need to use a regular expression in the server_name:

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name ~^www\.(?<domain>.+)$;

    ...
    return 301 https://$domain$request_uri;
}

The regular expression is used to capture the bare domain name, and then issue the redirect to the actual domain.

Tero Kilkanen
  • 36,796
  • 3
  • 41
  • 63