Nginx location /logs 没有代理传递正确到导致 404 的 Kibana

Nginx location /logs doesn't proxy pass correctly to Kibana leading to 404

我们有一个 docker 化的架构。唯一和主要的入口点是我们的 nginx。这使得我们所有服务之间的 link。

访问位置为 / 的域名工作正常。我们的 Angular 前端应用显示正确。

主要问题是在 /logs 位置访问 KIBANA (v5.5)。

例如,尝试访问 https://dev.example.com/logs/ 浏览器会显示 404,因为它尝试访问 https://dev.example.com/login?next=%2Flogs

Kibana 似乎在我们的 Location 端点中代理,试图用 / 的基数 url 重写 url。而不是重写附加在 /logs/ location 之后的 URI。

如何改进我们的配置以: - 允许访问 /logs/ 以正确显示我们的 Kibana 应用程序?

这是我们的 nginx 配置。请注意客户端、后端、kibana 指的是 docker 主机名。

server {
    listen  443;
    ssl     on;
    rdns    on;

    ssl_certificate /etc/ssl/production/certs/example/fullchain.pem;
    ssl_certificate_key /etc/ssl/production/certs/example/privkey.pem;

    server_name dev.example.com;

    # Angular APP
    location / {
        proxy_pass http://client;
        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;
    }

    # Backend proxy
    location /api {
        proxy_pass http://backend:9090;
        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;
    }

    # Logs on Kibana
    location /logs {
        proxy_pass http://kibana:5601;
        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;
    }
}

CURL 请求的结果:

curl -v https://dev.example.com/logs/
* About to connect() to dev.example.com port 443 (#0)
*   Trying xx.xx.xx.xx...
* connected
* Connected to dev.example.com (xx.xx.xx.xx) port 443 (#0)
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using ECDHE-RSA-AES256-GCM-SHA384
* Server certificate:
*        subject: CN=example.com
*        start date: 2017-08-23 17:26:00 GMT
*        expire date: 2017-11-21 17:26:00 GMT
*        subjectAltName: dev.example.com matched
*        issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*        SSL certificate verify ok.
> GET /logs HTTP/1.1
> User-Agent: curl/7.28.1
> Host: dev.example.com
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Server: nginx/1.13.1
< Date: Sat, 26 Aug 2017 15:39:43 GMT
< Content-Type: text/html
< Content-Length: 169
< Connection: keep-alive
<
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.13.1</center>
</body>
</html>
* Connection #0 to host dev.example.com left intact
* Closing connection #0
* SSLv3, TLS alert, Client hello (1):

感谢您对此的帮助。

您需要通过将 SERVER_BASEPATH 环境变量传递给 kibana 容器来将 server.basePath 设置为 /logs

然后,您需要在代理位置使用重写来去除 nginx 中的 /logs 前缀:

location /logs {
    rewrite ^/logs(/.*)$  break;
    proxy_pass http://kibana:5601;
    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;
}

此外,kibana 中显然存在一个错误,只有当我们使用以下 url:

到达 kibana 时,以上配置才有效
http://nginxip/logs/

但如果我们没有结束斜线,则不会,例如:

http://nginxip/logs

为了解决这个问题,我们需要在 nginx 中添加另一个重写以确保总是有一个结束斜杠。在 /logs 位置之外添加以下内容:

rewrite ^/logs$ /logs/;

来源:https://www.elastic.co/guide/en/kibana/current/settings.html