Nginx reverse proxy with rewrite and app/kibana#/discover

I've got Kibana running in docker-compose with nginx as a reverse proxy. It's working great, generally. Here are the relevant peices:

  upstream docker-kibana {
    server kibana:5601;
  }
  ...
location /kibana {
  proxy_pass http://docker-kibana;
  proxy_redirect off;
  proxy_set_header Host kibana.malcolm.local;
}

Also, I have this in my kibana.yml:

server.basePath: "/kibana"
server.rewriteBasePath: true

So basically everything is fine, there, I go to https://localhost/kibana and I am redirected to https://localhost/kibana/app/kibana and my default dashboards, etc.

I'm trying to make a rule that takes a specific URL from another part of my project and rewrite it to open up that particular document in the Discover app. The URL looks like this: https://localhost/idmol2kib/_id=190906-zRrtl-PKhhJO7ILAEOLwN80W

So, the idea is that I would end up with that being rewritten to Kibana like this: https://localhost/kibana/app/kibana#/discover?_g=()&_a=(columns:!(_source),filters:!((meta:(alias:!n,disabled:!f,index:'sessions2-*',key:_id,negate:!f,params:(query:'190906-zRrtl-PKhhJO7ILAEOLwN80W',type:phrase),type:phrase,value:'190906-zRrtl-PKhhJO7ILAEOLwN80W'),query:(match:(_id:(query:'190906-zRrtl-PKhhJO7ILAEOLwN80W',type:phrase))))),index:'sessions2-*',interval:auto,query:(language:lucene,query:''),sort:!(firstPacket,desc))

I'm trying to get my new location rule added in. My rule of thumb is always start simple, then work up from there. So, I did this first (basically just take me to Kibana, no additional parameters):

location ~* ^/idmol2kib\b(.*) {
  rewrite ^/idmol2kib(.*) /kibana/app/kibana;
  proxy_pass http://docker-kibana;
  proxy_redirect off;
  proxy_set_header Host kibana.malcolm.local;
}

And, that works perfectly. The link https://localhost/idmol2kib/_id=190906-zRrtl-PKhhJO7ILAEOLwN80W actually takes me to https://localhost/kibana/app/kibana which loads up my default dashboard.

But, that's not what I really want, I want to go to the #discover page. Again, let's not get too complicated. I'm going to just change my working config and add the discover bit in (eg., to get me to https://localhost/kibana/app/kibana#/discover):

location ~* ^/idmol2kib\b(.*) {
  rewrite ^/idmol2kib(.*) /kibana/app/kibana#/discover;
  proxy_pass http://docker-kibana;
  proxy_redirect off;
  proxy_set_header Host kibana.malcolm.local;
}

However, it doesn't work. I end up with this:

{"statusCode":404,"error":"Not Found","message":"Not Found"}

Looking at my logs, I see:

nginx-proxy_1    | nginx.1    | 192.168.160.1 - seth [06/Sep/2019:17:32:36 +0000] "GET /idmol2kib/_id=190906-WSB9hsThC1VHH5StaJttzpDd HTTP/1.1" 404 60 "https://localhost/sessions?graphType=lpHisto&seriesType=bars" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36"
kibana_1         | {"type":"response","@timestamp":"2019-09-06T17:32:36Z","tags":[],"pid":83,"method":"get","statusCode":404,"req":{"url":"/app/kibana%23/discover","method":"get","headers":{"host":"kibana.malcolm.local","connection":"close","upgrade-insecure-requests":"1","user-agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36","sec-fetch-mode":"navigate","sec-fetch-user":"?1","accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3","sec-fetch-site":"same-origin","referer":"https://localhost/sessions?graphType=lpHisto&seriesType=bars","accept-encoding":"gzip, deflate, br","accept-language":"en-US,en;q=0.9"},"remoteAddress":"192.168.160.12","userAgent":"192.168.160.12","referer":"https://localhost/sessions?graphType=lpHisto&seriesType=bars"},"res":{"statusCode":404,"responseTime":1,"contentLength":9},"message":"GET /app/kibana%23/discover 404 1ms - 9.0B"}

Basically, we see Kibana is seeing "url":"/app/kibana%23/discover" and giving a 404. I tried doing the encoding of the # to %23 myself, but then Kibana just sees "url":"/app/kibana%2523/discover" and the same 404. Escaping the # with a \ in nginx.conf doesn't work either.

So it boils down to that #. I can't get nginx to pass the # to Kibana in the URL in a way it wants. Any tips?

I should mention, I am running Kibana 6.8.2.

@Bargs can we get some help here please?

Thanks,
Bhavya

Actually, I think I've figured it out!

The issue is that the fragment identifier portion of the URL (after the #) is only usable by the browser, not the server itself.

So I had to add redirect after the nginx rewrite directive to indicate that this is a web browser redirect (302).

The working block looks like this:

# Kibana shortcut
location ~* ^/idmol2kib(.*) {
  rewrite ^/idmol2kib/(.*?)=(.*) /kibana/app/kibana#/discover?_g=()&_a=(columns:!(_source),filters:!((meta:(alias:!n,disabled:!f,index:'sessions2-*',key:$1,negate:!f,params:(query:'$2',type:phrase),type:phrase,value:'$2'),query:(match:($1:(query:'$2',type:phrase))))),index:'sessions2-*',interval:auto,query:(language:lucene,query:''),sort:!(firstPacket,desc)) redirect;
  proxy_pass http://docker-kibana;
  proxy_redirect off;
  proxy_set_header Host kibana.malcolm.local;
}

And it seems to work like a champ. Hopefully this will help someone else who is trying to do this someday.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.