Grafana Proxy New Domain to old DOmain - nginx

I am currently running a Grafana server with an NGINX server in front of it to server up from my grafana.olddomain.uk:
location / {
proxy_pass http://127.0.0.1:3000;
}
I would like to proxy from my new domain (https://my.newdomain/grafana) to the old domain but have been hitting problems with the config:
location /grafana {
max_ranges 0;
rewrite ^/grafana/(.*)$ /$1 break;
proxy_pass https://grafana.olddomain.uk/;
proxy_ssl_server_name on;
proxy_ssl_trusted_certificate /etc/nginx/conf.d/trusted_ca_cert.pem;
proxy_set_header Host $host;
}
This is throwing an error cleared being served by Grafana:
If you're seeing this Grafana has failed to load its application files
1. This could be caused by your reverse proxy settings.
2. If you host grafana under subpath make sure your grafana.ini root_url setting includes subpath
3. If you have a local dev build make sure you build frontend using: yarn start, yarn start:hot, or yarn build
4. Sometimes restarting grafana-server can help
So that seems pretty clear, I am using a sub folder now and need to change grafana.ini but that will break grafana.olddomain.uk.
What do I need in my newdomain location to get this working?
EDIT: curl response (following redirects) from https://my.newdomain.uk/grafana
> GET /grafana HTTP/1.1
> Host: my.newdomain.uk
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Server: nginx
< Date: Fri, 16 Apr 2021 17:39:13 GMT
< Content-Type: text/html
< Content-Length: 162
< Location: https://my.newdomain.uk/grafana/
< Connection: keep-alive
<
> GET /grafana/ HTTP/1.1
> Host: my.newdomain.uk
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Server: nginx
< Date: Fri, 16 Apr 2021 17:39:13 GMT
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Cache-Control: no-cache
< Expires: -1
< Pragma: no-cache
< X-Frame-Options: deny
<

So after a lot of attempts at getting a sub path working I had to give up and set this up on root. This required splitting all the configurations up into separate sites.
location / {
max_ranges 0;
proxy_pass https://grafana.olddomain.uk/;
proxy_ssl_server_name on;
proxy_ssl_trusted_certificate /etc/nginx/conf.d/trusted_ca_cert.pem;
proxy_set_header Host $host;
}

Related

How to make nginx not return the response body when performing redirection?

An example configuration is as follows:
server {
listen 80;
server_name www.example.com;
rewrite ^/(.*)$ https://www.example.com/$1 permanent;
}
nginx returns a response body when performing a redirect.
$ curl -v http://www.example.com
* Trying 121.5.221.184:80...
* Connected to www.example.com (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: www.example.com
> User-Agent: curl/7.84.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
< Server: nginx
< Date: Tue, 02 Aug 2022 16:13:04 GMT
< Content-Type: text/html
< Content-Length: 162
< Connection: keep-alive
< Location: https://www.example.com/
<
{ [162 bytes data]
* Connection #0 to host www.example.com left intact
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>
I don't think this response body is useful, and instead wastes server bandwidth. Is it possible to make nginx not return any response body when performing redirection?

How do I set Access-Control-Allow-Origin on upstream errors in nginx? [duplicate]

This question already has answers here:
CORS and non 200 statusCode
(2 answers)
Closed last year.
I know there are a million answers to "how to set Access-Control-Allow-Origin in nginx" but unfortunately if there's an answer to my specific question, it's buried with all the basic answers.
I have an Angular app pointing to an nginx server with a rest service upstream - all running on my local laptop inside a docker compose.
The nginx service is configured fairly simply:
upstream REST {
# rest-service is mapped by docker-compose to the correct container
server rest-service:8080;
}
server {
listen 80;
listen [::]:80;
# This is mapped in /etc/hosts on my laptop
server_name rest-api.mylocal.com;
location / {
proxy_hide_header 'Access-Control-Allow-Origin';
# web-ui is also mapped in /etc/hosts on my laptop
add_header "Access-Control-Allow-Origin" "http://web-ui.mylocal.com";
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Max-Age' 1728000; # 20 days
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
add_header Reverse-Proxy true;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://REST;
}
}
If I call a valid URL on the rest service, e.g. http://rest-api.mylocal.com/api/v1/auth/config (this is an unauthenticated endpoint), everything works as expected:
curl -v 'http://rest-api.mylocal.com/api/v1/auth/config'
...
< Access-Control-Allow-Origin: http://web-ui.mylocal.com
< Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
< Access-Control-Max-Age: 1728000
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: Content-Type, Authorization
< Reverse-Proxy: true
<
* Connection #0 to host rest-api.mylocal.com left intact
{"status":"OK","name":"foo",...}* Closing connection 0
However, if I call an invalid URL, say http://rest-api.mylocal.com/api/v1/accounts (which is an authenticated endpoint, and I provide no credentials), I get back the expected error, but there are no CORS headers. In a browser this causes everything to flake out so I don't even get the error message in Angular to display to the user:
curl -v 'http://rest-api.mylocal.com/api/v1/accounts'
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to rest-api.mylocal.com (127.0.0.1) port 80 (#0)
> GET /api/v1/accounts HTTP/1.1
> Host: rest-api.mylocal.com
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 403
< Server: nginx/1.21.6
< Date: Wed, 09 Feb 2022 20:57:49 GMT
< Content-Type: application/json
< Transfer-Encoding: chunked
< Connection: keep-alive
< Set-Cookie: JSESSIONID=F3B21A55841C8E5A6F838F2427A0E22B; Path=/; HttpOnly
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
<
* Connection #0 to host rest-api.mylocal.com left intact
{"timestamp":"2022-02-09T20:57:49.526+00:00","status":403,"error":"Forbidden","message":"Access Denied","path":"/api/v1/accounts"}* Closing connection 0
Browser console:
Access to XMLHttpRequest at 'http://rest-api.mylocal.com/api/v1/accounts' from origin 'http://web-ui.mylocal.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
So... Is there a way to make sure the CORS headers are still added to the response by nginx even if the response from the upstream server is an error (401/403/404/etc)?
You need to add always to each header you want added to error responses. It was added in 1.7.5: https://nginx.org/r/add_header

Nginx proxy return http 400 after connect

I'm trying to make a https proxy on nginx engine. And when I test it on different sites - I always get two HTTP codes - 302 - redirect to https scheme and 400 after connect
proxy config
server {
error_log /var/log/nginx/nginx.err;
access_log /var/log/nginx/nginx.acc;
resolver 127.0.0.53;
listen 80; #default_server;
listen 443 ssl default_server;
server_name proxy;
ssl_certificate /etc/letsencrypt/live/proxy/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/proxy/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/proxy/chain.pem;
proxy_ssl_certificate /etc/letsencrypt/live/proxy/fullchain.pem;
proxy_ssl_certificate_key /etc/letsencrypt/live/proxy/privkey.pem;
proxy_ssl_trusted_certificate /etc/letsencrypt/live/proxy/chain.pem;
large_client_header_buffers 1 128k;
proxy_ssl_verify on;
proxy_ssl_session_reuse off;
ssl_verify_client off;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers RC4:HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Access-Control-Allow-Origin *;
proxy_buffering on;
proxy_buffers 8 16k;
proxy_buffer_size 16k;
proxy_pass http://$host$request_uri;
proxy_read_timeout 1800;
}
}
curl -x localhost:80 goo.gl -I -L output (goo.gl - for example, but I have this issue for every site)
HTTP/1.1 301 Moved Permanently
Server: nginx/1.18.0 (Ubuntu)
Date: Fri, 10 Sep 2021 12:32:42 GMT
Content-Type: application/binary
Content-Length: 0
Connection: keep-alive
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Location: https://goo.gl/
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
HTTP/1.1 400 Bad Request
Server: nginx/1.18.0 (Ubuntu)
Date: Fri, 10 Sep 2021 12:32:42 GMT
Content-Type: text/html
Content-Length: 166
Connection: close
same curl output with -v
* Trying ::1:80...
* TCP_NODELAY set
* connect to ::1 port 80 failed: Connection refused
* Trying 127.0.0.1:80...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 80 (#0)
> HEAD http://goo.gl/ HTTP/1.1
> Host: goo.gl
> User-Agent: curl/7.68.0
> Accept: */*
> Proxy-Connection: Keep-Alive
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
HTTP/1.1 301 Moved Permanently
< Server: nginx/1.18.0 (Ubuntu)
Server: nginx/1.18.0 (Ubuntu)
< Date: Fri, 10 Sep 2021 12:34:02 GMT
Date: Fri, 10 Sep 2021 12:34:02 GMT
< Content-Type: application/binary
Content-Type: application/binary
< Content-Length: 0
Content-Length: 0
< Connection: keep-alive
Connection: keep-alive
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
Pragma: no-cache
< Expires: Mon, 01 Jan 1990 00:00:00 GMT
Expires: Mon, 01 Jan 1990 00:00:00 GMT
< Location: https://goo.gl/
Location: https://goo.gl/
< X-XSS-Protection: 0
X-XSS-Protection: 0
< X-Frame-Options: SAMEORIGIN
X-Frame-Options: SAMEORIGIN
< X-Content-Type-Options: nosniff
X-Content-Type-Options: nosniff
<
* Connection #0 to host localhost left intact
* Issue another request to this URL: 'https://goo.gl/'
* Hostname localhost was found in DNS cache
* Trying ::1:80...
* TCP_NODELAY set
* connect to ::1 port 80 failed: Connection refused
* Trying 127.0.0.1:80...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 80 (#1)
* allocate connect buffer!
* Establish HTTP proxy tunnel to goo.gl:443
> CONNECT goo.gl:443 HTTP/1.1
> Host: goo.gl:443
> User-Agent: curl/7.68.0
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 400 Bad Request
HTTP/1.1 400 Bad Request
< Server: nginx/1.18.0 (Ubuntu)
Server: nginx/1.18.0 (Ubuntu)
< Date: Fri, 10 Sep 2021 12:34:02 GMT
Date: Fri, 10 Sep 2021 12:34:02 GMT
< Content-Type: text/html
Content-Type: text/html
< Content-Length: 166
Content-Length: 166
< Connection: close
Connection: close
<
* Received HTTP code 400 from proxy after CONNECT
* CONNECT phase completed!
* Closing connection 1
curl: (56) Received HTTP code 400 from proxy after CONNECT
If I do curl without a proxy, then it will contain messages with successful TLS handshakes

Localhost Nginx raise no-referrer-when-downgrade in browser

I have HTTP cloud functions running locally and i want to hide them behind a reverse proxy to reproduce the same architecture i have in production.
When i call directly the endpoint, it's fine. But when i use my react application, it's not working. I don't manage to fix the issue.
Can you help me please?
Nginx conf :
server {
listen 9003;
#add_header 'Referrer-Policy' 'no-referrer';
add_header 'Referrer-Policy' 'unsafe-url';
location /api/callImportEvent/ {
add_header 'Referrer-Policy' 'unsafe-url';
if ($request_method = OPTIONS ) {
add_header "Access-Control-Allow-Origin" *;
add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD";
add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
return 200;
}
proxy_pass http://192.168.99.1:8888/;
proxy_redirect off;
proxy_pass_header Authorization;
proxy_pass_header x-api-key;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Cloud function command : 
$(gcloud beta emulators pubsub env-init) && functions-framework --target=callImportEventHttp --signature-type=http --source=./index.js --port=8888
Direct curl (working) :
rbarbu#DESKTOP-7EQNOFM:~$ curl -v 'http://localhost:9003/api/callImport/'
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 9003 (#0)
> GET /api/callImport/ HTTP/1.1
> Host: localhost:9003
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 456 unknown
< Server: nginx/1.14.0 (Ubuntu)
< Date: Mon, 07 Sep 2020 15:37:16 GMT
< Content-Type: application/json; charset=utf-8
< Content-Length: 61
< Connection: keep-alive
< X-Powered-By: Express
< ETag: W/"3d-kbNXdE/Nx2cqqnUsIdQHlgSM74w"
<
* Connection #0 to host localhost left intact
{"status":"Unrecoverable Error","message":"No API KEY given"}r
Call from React APP (not Working):
Direct call to NGINX URL from Browser (working):

How to add cache control on a static file which have a http code 404

I would like to add http header Cache-Control: max-age=4 on non existing static file.
I try to include the following block into my nginx vhost
server {
listen *:80;
server_name local.test.com;
root /vat/www/test;
location ~* \.(js)$ {
expires 4s;
}
}
On an existing asset it work fine
curl -s -I http://local.test.com/index.js | grep Cache-Control
Cache-Control: max-age=4
On a none existing asset it does't work
curl -s -I http://local.test.com/fake.js
HTTP/1.1 404 Not Found
Server: nginx/1.15.8
Date: Thu, 19 Sep 2019 09:10:39 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
Any idea ?

Resources