Score:0

Endless redirect loop on nginx config

cn flag

I have an nginx config with SSL configured and two redirects to docker container. One of them (edit https://psono.example.com/portal) is working, but the one that forwards the domain itself (edit https://psono.example.com/) is not working and instead leads to an endless redirect (https://psono.example.com/psono.example.com/psono.example.com/psono.example.com/psono.example.com/...)

This is my config.

server {
    listen 80;
    server_name psono.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name psono.example.com;    
    ssl_protocols TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_session_timeout 1d;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
    ssl_ciphers '';

    # Comment this in if you know what you are doing
    # add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";

    add_header Referrer-Policy same-origin;
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";

    # If you have the admin fileserver installed too behind this reverse proxy domain, add your fileserver URL e.g. https://fs01.example.com as connect-src too:
    add_header Content-Security-Policy "default-src 'none';  manifest-src 'self'; connect-src 'self' https://static.psono.com https://api.pwnedpasswords.com https://storage.googleapis.com https://*.digitaloceanspaces.com https://*.blob.core.windows.net https://*.s3.amazonaws.com; font-src 'self'; img-src 'self' data:; script-src 'self'; style-src 'self' 'unsafe-inline'; object-src 'self'";

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

    client_max_body_size 256m;

    gzip on;
    gzip_disable "msie6";
    
gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_min_length 256;
    gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;
    
    root /var/www/html;
    
    location /server {
                rewrite ^/server/(.*) /$1 break;
                proxy_set_header        Host $host;
                proxy_set_header        X-Real-IP $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header        X-Forwarded-Proto $scheme;

        add_header Last-Modified $date_gmt;
        add_header Pragma "no-cache";
        add_header Cache-Control "private, max-age=0, no-cache, no-store";
        if_modified_since off;
        expires off;
        etag off;
    
                proxy_pass          http://localhost:10100;
    }
    
    location ~* ^/portal.*\.(?:ico|css|js|gif|jpe?g|png|eot|woff|woff2|ttf|svg|otf)$ {
        expires 30d;
        add_header Pragma public;
        add_header Cache-Control "public";

        # Remove the leading # from the following lines if you have the admin webclient running in a docker container
        proxy_set_header        Host $host;
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwarded-Proto $scheme;

        proxy_pass          http://localhost:10102;
        proxy_redirect      http://localhost:10102 https://psono.example.com;
    }
 location ~* \.(?:ico|css|js|gif|jpe?g|png|eot|woff|woff2|ttf|svg|otf)$ {
        expires 30d;
        add_header Pragma public;
        add_header Cache-Control "public";
    
        # Remove the leading # from following lines if you have the webclient running in a docker container
        proxy_set_header        Host $host;
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwarded-Proto $scheme;

        proxy_pass          http://localhost:10101;
        proxy_redirect      http://localhost:10101 https://psono.example.com;
    }
    
    # Remove the leading # from following lines if you have the admin webclient running in a docker container
     location /portal {
                proxy_set_header        Host $host;
                proxy_set_header        X-Real-IP $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header        X-Forwarded-Proto $scheme;

                proxy_read_timeout  90;

                proxy_pass          http://localhost:10102;
     }
    
    # Remove the leading # from following lines if you have the admin webclient NOT running in a docker container
    # location /portal {
    #     index  index.html index.htm;
    #     try_files $uri /portal/index.html;  # forward all requests to index.html
    # }
    
    # Remove the leading # from following lines if you have the webclient running in a docker container
    location / {
                proxy_set_header        Host $host;
                proxy_set_header        X-Real-IP $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header        X-Forwarded-Proto $scheme;

                proxy_pass          http://localhost:10101;
                proxy_read_timeout  90;
        #
                proxy_redirect      http://localhost:10101 https://psono.example.com;
    }
}

Edit The output of curl -v is:


*   Trying 5.9.74.183:443...
* TCP_NODELAY set
* Connected to psono.example.com (5.9.74.183) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=psono.example.com
*  start date: Dec  1 14:53:24 2021 GMT
*  expire date: Mar  1 14:53:23 2022 GMT
*  subjectAltName: host "psono.example.com" matched cert's "psono.example.com"
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x557ac8936e10)
> GET / HTTP/2
> Host: psono.example.com
> user-agent: curl/7.68.0
> accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 403
< server: nginx/1.18.0 (Ubuntu)
< date: Thu, 02 Dec 2021 06:53:11 GMT
< content-type: text/html
< content-length: 162
<
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.18.0 (Ubuntu)</center>
</body>
</html>

us flag
What is the URL that triggers the redirect loop? What is the output of `curl -v` for that URL?
cn flag
@TeroKilkanen I updated my question.
us flag
You need to provide the HTTP authentication credentials with the `-u <username>:<password>` option in curl to get useful output.
cn flag
Using authentication I get the same result, also, the main page should not require authentication itself, but display a login page.
us flag
Your example does not have a redirect, so it cannot cause a redirect loop. It displays `403 Forbidden`, which means proper credentials were not passed on the request.
cn flag
I know, in theory this is what I would say if I was in your place. I tried some more and it turns out that this is a problem specific only to this browser on my machine, using a different browser or the same browser on a different machine I can access the homepage without a redirection loop. I tried some more and deleted the cookies from the domain completely and now I can access the homepage, seems to be an application specific problem. Thank you for looking into this.
Score:1
cn flag

It turns out this is not an nginx issue, but instead a psono related problem. I logged in to the /portal page first, this set some cookies and afterwards I was not able to login into the main page / anymore, resulting in the redirect loop. Deleting the cookies for the domain enables me to login to the main page. I opened an issue at psonos for this: https://gitlab.com/psono/psono-server/-/issues/212

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.