1

I want to configure nginx to act as a reverse proxy that will redirect to two different Kibana hosts depending on the passed URI. / redirect to the standard and /october/ to the october dedicated Kibana. The first part of the configuration (/) works well but I got a Too many redirections error when a try to access /october. I tried to comment out the second part (location /october/) and replace localhost by 10.10.0.3 in the first one and I'm redirected to the october platform. So the problem is on this nginx configuration.

server {
    listen                  80;
    server_name             my.domain.io;
    return                  301 https://$server_name;
}

server {
    listen                  443 ;
    ssl                     on;
    ssl_certificate         /etc/letsencrypt/live/my.domain.io/cert.pem;  
    ssl_certificate_key     /etc/letsencrypt/live/my.domain.io/privkey.pem;  
    server_name             my.domain.io; 
    access_log              /var/log/nginx/kibana.access.log;
    error_log               /var/log/nginx/kibana.error.log;

    location / {
            auth_basic              "Restricted";
            auth_basic_user_file    /etc/nginx/conf.d/kibana.htpasswd;


            location / {
                    proxy_pass              http://localhost:5601;
                    proxy_http_version      1.1;
                    proxy_set_header        Upgrade $http_upgrade;
                    proxy_set_header        Connection 'upgrade';
                    proxy_set_header        Host $host;
                    proxy_cache_bypass      $http_upgrade;
            }

            location /october/ {
                    proxy_pass              http://10.10.0.3:5601;
                    proxy_http_version      1.1;
                    proxy_set_header        Upgrade $http_upgrade;
                    proxy_set_header        Connection 'upgrade';
                    proxy_set_header        Host $host;
                    proxy_cache_bypass      $http_upgrade;
            }
    }
}
Quentin
  • 131

4 Answers4

2

I think you have had your locations nested incorrectly, please try the following:

server {
    listen                  443 ;
    ssl                     on;
    ssl_certificate         /etc/letsencrypt/live/my.domain.io/cert.pem;  
    ssl_certificate_key     /etc/letsencrypt/live/my.domain.io/privkey.pem;  
    server_name             my.domain.io; 
    access_log              /var/log/nginx/kibana.access.log;
    error_log               /var/log/nginx/kibana.error.log;

    auth_basic              "Restricted";
    auth_basic_user_file    /etc/nginx/conf.d/kibana.htpasswd;

    location / {
            proxy_pass              http://localhost:5601;
            proxy_http_version      1.1;
            proxy_set_header        Upgrade $http_upgrade;
            proxy_set_header        Connection 'upgrade';
            proxy_set_header        Host $host;
            proxy_cache_bypass      $http_upgrade;
    }

    location ~ ^/october.*$ {
            proxy_pass              http://10.10.0.3:5601;
            proxy_http_version      1.1;
            proxy_set_header        Upgrade $http_upgrade;
            proxy_set_header        Connection 'upgrade';
            proxy_set_header        Host $host;
            proxy_cache_bypass      $http_upgrade;
    }

}
NarūnasK
  • 408
2

Thanks to the previous responses, I found the solution but don't exactly know "how" and "why" it works...

Here is my new configuration :

server {
    listen                  80;
    server_name             my.domain.io;
    return                  301 https://$server_name;
}

server {
    listen                  443 ;
    ssl                     on;
    ssl_certificate         /etc/letsencrypt/live/my.domain.io/cert.pem;
    ssl_certificate_key     /etc/letsencrypt/live/my.domain.io/privkey.pem;
    server_name             my.domain.io;
    access_log              /var/log/nginx/kibana.access.log;
    error_log               /var/log/nginx/kibana.error.log;

    auth_basic              "Restricted";
    auth_basic_user_file    /etc/nginx/conf.d/kibana.htpasswd;

    location / {
            proxy_pass              http://localhost:5601;
            proxy_http_version      1.1;
            proxy_set_header        Upgrade $http_upgrade;
            proxy_set_header        Connection 'upgrade';
            proxy_set_header        Host $host;
            proxy_cache_bypass      $http_upgrade;
    }

    location = /october {
            return 302 /october/;
    }

    location /october/ {
            proxy_pass              http://10.10.0.3:5601/;
            proxy_http_version      1.1;
            proxy_set_header        Upgrade $http_upgrade;
            proxy_set_header        Connection 'upgrade';
            proxy_set_header        Host $host;
            proxy_cache_bypass      $http_upgrade;
    }
}

There is no need for proxy_redirect directive. The trick was to add a / at the end of the /october location and redirect /october to /october/whit 302 code. Don't forget that you have to set server.basePath to "/october"in your kibana.yml file.

This post helped me : How to remove the path with an nginx proxy_pass

Hope this will help...

Quentin
  • 131
0

I believe the actual reason was in a single character, note the trailing slash /:

proxy_pass http://10.10.0.3:5601;
proxy_pass http://10.10.0.3:5601/;

Just had the same problem with Nginx URI proxying Kibana too.

TLDR: trailing slashes in Nginx proxy configuration are VERY important (both in location and proxy_pass). Rule of thumb: have them, unless you know, what you do.

P.S. My Nginx and Kibana 8.8.0.0 configuration:

  auth_basic           "Administrator's area";
  auth_basic_user_file /etc/nginx/.htpasswd;

location /kibana/ { proxy_pass http://kibana:5601/kibana/enter code here; proxy_set_header Authorization ""; }

  kibana:
    << : *service_defaults
    image: ${KIBANA_IMAGE}
    profiles: ['ui']
    ports: ["5601:5601"]
    environment:
      - ELASTICSEARCH_URL=http://elasticsearch:9200
      - ELASTICSEARCH_USERNAME=kibana_system
      - ELASTICSEARCH_PASSWORD=${KIBANA_SYSTEM_PASSWORD}
      # https://www.elastic.co/guide/en/kibana/current/settings.html
      - SERVER_BASEPATH=/kibana
      - SERVER_REWRITEBASEPATH=true
    healthcheck:
      << : *healthcheck_defaults
      test: [ "CMD-SHELL", "curl -L -u elastic:$ELASTIC_PASSWORD http://localhost:5601/kibana/api/status | grep 'All services are available'", ]
    depends_on: { elasticsearch: { condition: service_healthy }}
0

With the configuration given, requests to /october/some/path will be passed as-is to your second Kibana host, which is probably not configured to expect requests prefixed with /october.

I don't know Kibana but a quick search brought me to the configuration documentation for 5.1 which has a server.basePath configuration value. Try setting this to "/october".

In addition, as the docs say this value only affects the URLs generated by Kibana you will need to add a proxy_redirect directive to the nginx configuration and modify the proxy_pass nginx directive, appending a / to the backend URL:

server {
    listen                  80;
    server_name             my.domain.io;
    return                  301 https://$server_name;
}

server {
    listen                  443 ;
    ssl                     on;
    ssl_certificate         /etc/letsencrypt/live/my.domain.io/cert.pem;  
    ssl_certificate_key     /etc/letsencrypt/live/my.domain.io/privkey.pem;  
    server_name             my.domain.io; 
    access_log              /var/log/nginx/kibana.access.log;
    error_log               /var/log/nginx/kibana.error.log;

    location / {
            auth_basic              "Restricted";
            auth_basic_user_file    /etc/nginx/conf.d/kibana.htpasswd;


            location / {
                    proxy_pass              http://localhost:5601;
                    proxy_http_version      1.1;
                    proxy_set_header        Upgrade $http_upgrade;
                    proxy_set_header        Connection 'upgrade';
                    proxy_set_header        Host $host;
                    proxy_cache_bypass      $http_upgrade;
            }

            location /october/ {
                    proxy_pass              http://10.10.0.3:5601/;
                    proxy_redirect          /   /october/;
                    proxy_http_version      1.1;
                    proxy_set_header        Upgrade $http_upgrade;
                    proxy_set_header        Connection 'upgrade';
                    proxy_set_header        Host $host;
                    proxy_cache_bypass      $http_upgrade;
            }
    }
}

proxy_redirect rewrites URLs returned in "Location" and "Refresh" headers, and the additional slash causes the proxy module to strip off the path matched by the nginx "location" directive. These effectively compliment each other.