I would like to do the following in my NGINX configuration: I want to proxy pass the path and query parameters but not include the first path parameter (path1).
Request URL
https://my-domain.com/path1/path2?query1=some-query
I want this to proxy_pass to
http://localhost:8000/path2?query1=some-query
I have tried with the following location block
location /path1/path2/ {
proxy_pass http://localhost:8000$request_uri;
proxy_http_version 1.1;
}
However, this does not go to the correct endpoint because I think it includes the path1 parameter too. I have several different path2 routes and so I want to be able to catch and redirect them all easily - without having to manually define each one like this:
location /path1/path2a/ {
proxy_pass http://localhost:8000/path2a?query1=some-query;
proxy_http_version 1.1;
}
location /path1/path2b/ {
proxy_pass http://localhost:8000/path2b?query1=some-query;
proxy_http_version 1.1;
}
location /path1/path2c/ {
proxy_pass http://localhost:8000/path2c?query1=some-query;
proxy_http_version 1.1;
}
ADDITIONAL EDIT:
I also cannot simply do
location /path1/ {
proxy_pass http://localhost:8000/;
proxy_http_version 1.1;
}
because I already have the location /path1/ block that gets upgraded to a WebSocket connection at a different endpoint:
location /path1/ {
proxy_pass http://localhost:9000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
I have searched a lot online but cannot find a configuration that works for my specific scenario.
This is really simple:
location /path1/ {
proxy_pass http://localhost:8000/;
proxy_http_version 1.1;
}
Read this Q/A for details.
Update
This solution isn't usable after OP clarifies his question.
If all of the additional paths share common suffix path2:
location /path1/path2 {
rewrite ^/path1(.*) $1 break; # remove '/path1' URI prefix
proxy_pass http://localhost:8000;
proxy_http_version 1.1;
}
If they aren't, replace location /path1/path2 with location ~ ^/path1/(?:path2a|path2b|path2c).
If you need to pass to the backend query arguments that are different from those came with the request, use
set $args query1=some-query;
within the location block.
Related
I want to pass different path to the same proxy_pass but I keep getting 502 Bad gateway.
These path use the same port number but different base path. How do I make it work from what I have which returns an error currently.
this is what my current location looks like
worker_processes 4;
# worker_process auto
events { worker_connections 1024; }
http {
server {
listen 80;
charset utf-8;
location ~ ^/api/v1/(wallet|card)/(.*)$ {
proxy_pass http://wallet-service:3007/api/v1/$1/;
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;
}
}
}
If you don't need an URI to be changed at all, don't use anything other than the upstream name:
location ~ ^/api/v1/(wallet|card)/ {
proxy_pass http://wallet-service:3007;
...
}
If an URI needs to be rewritten before being passed to the upstream, check this answer to see how to do it.
I would like to disable access logging for some specific paths but still proxy it to another container. In other words "match multiple locations without returning/exiting" which is not possible as far as I know.
The following config will make nginx cancel the request without entering the proxy pass location.
server {
# ...
# do not log requests for /_nuxt/* and /_ipx/*
location ~ ^/(_ipx|_nuxt) {
access_log off;
}
# still proxy these paths
location ~* ^(\/|\/(foo|bar|_nuxt|_ipx)$ {
proxy_pass http://frontend:3000;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $server_name:$server_port;
}
}
Is there a more clean way of achieving the desired behavior other than duplicating the proxy configuration and adding the access log config line to that second location?
server {
# ...
# proxy pass without _nuxt and _ipx
location ~* ^(\/|\/(foo|bar)$ {
proxy_pass http://frontend:3000;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $server_name:$server_port;
}
# access log + proxy pass
location ~ ^/(_ipx|_nuxt) {
access_log off;
proxy_pass http://frontend:3000;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $server_name:$server_port;
}
}
You're right, location working like switch case taking the first hit and break.
Maybe you can try something like that:
if ($request_uri ~ ^/(_ipx|_nuxt)) {
access_log off;
}
instead of your first location statement.
The access_log directive has the following syntax:
access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]]; ...
...
The if parameter (1.7.0) enables conditional logging. A request will not be logged if the condition evaluates to β0β or an empty string. In the following example, the requests with response codes 2xx and 3xx will not be logged:
map $status $loggable {
~^[23] 0;
default 1;
}
access_log /path/to/access.log combined if=$loggable;
Applied to the asked question, that means the following config should achieve the desired goal:
map $uri $loggable {
~^/_(ips|nuxt) 0;
default 1;
}
server {
...
access_log /path/to/access.log <format> if=$loggable;
}
I'm setting up the content-security-policy for my site , but the script url for my comments system contains a port number i.e http://dev.example.com:8080/client.js.
I have a few other URL's which use ports too and I'd prefer to hide which ports my site uses in case of possible security implications.
How can I hide these URL's containing port numbers so that the CSP considers the URL's as self?
For example instead of http://dev.example.com:8080/client.js I'd like it to be http://dev.example.com/comments/client.js.
I'm on an Nginx server and I've tried playing around with rewriting the URL, but can't get it working.
Here's what I've tried.
This allows me to change the script URL to http://dev.example.com/comments/client.js, but CSP still detects http://dev.example.com:8080/client.js.
location ~ /comments/ {
return 301 http://dev.example.com:8080/client.js;
}
Didn't work
location ~ /comments/ {
rewrite ^/comments/(.*) http://dev.example.com:8080/$1 last;
}
Just to be clear I know I can just throw the URL http://dev.example.com:8080/client.js straight into CSP e.g script-src 'self'
dev.example.com:8080/client.js;, but I want the URL to work with self e.g script-src 'self'.
Returns 502 bad gateway error
location /comments {
proxy_pass http://dev.example.com:8080/;
}
Also returns502 bad gateway.
location = /comments {
return 301 /comments/;
}
location ~ /comments/(?<ndpath>.*) {
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_pass_request_headers on;
proxy_set_header Connection "keep-alive";
proxy_store off;
proxy_pass http://dev.example.com:8080/$ndpath$is_args$args;
gzip on;
gzip_proxied any;
gzip_types *;
}
What you are looking for is the concept of a reverse proxy. Described here.
In your case the simplest example is
location /comments {
proxy_pass http://localhost:8080/;
}
EDIT: To be more clear, this is nginx version 1.13.8.
Take the following as an example nginx.conf file:
http {
upstream portal_backend {
server pc-loc43-01:15080;
}
upstream auth_backend {
server pc-loc43-01:16080;
}
server {
listen 9080 default_server;
server_name my-reverse-proxy;
location / {
auth_basic off;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_pass http://portal_backend/;
}
location /auth {
auth_basic off;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_pass http://auth_backend/auth;
}
}
}
I want to configure nginx to default to location / if it is unable to match the request to any of the locations, but I cannot find how to do this.
I don't see anything wrong with your code.
location / { is already the default location block for "unhandled" locations.
This would match all locations:
location / {
# ...
}
This would match the root only:
location = / {
# ...
}
This will match /auth and sub directories:
location /auth {
# ...
}
It must be related to how nginx does request matching -- somehow auth and authorize are too similar and it causes nginx problems (not a great explanation and maybe someone more experienced with nginx internals can chime in). The "solution" was to duplicate location / into location /authorize, so now the config file looks like:
...
location / {
auth_basic off;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_pass http://portal_backend/;
}
location /authorize {
auth_basic off;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_pass http://portal_backend/;
}
...
All the other routes work as I would have expected, e.g. /users, /customers, /whatever are all handled by location /
I have a reverse nginx proxy where I want to route all request that come in with :
http://dns.com/content/xyz <βtoβ> http://dns.com/content/1.0/xyz
I have an upstream :
upstream backend_api.content.com {
server localhost:8080 max_fails=5 fail_timeout=30;
keepalive 100;
}
and location :
#Content Service
location ~* ^/content/?(.*) {
set $proxy_pass "http://backend_api.content.com";
rewrite ^/content/1.0(/.*)$ /content/1.0$1 break;
proxy_pass $proxy_pass
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host "api.stg.xxx.com";
proxy_set_header X-3scale-proxy-secret-token $secret_token;
proxy_set_header Original-Host $http_host;
proxy_set_header Authorization $outbound_auth_header;
proxy_set_header Original-Uri $scheme://$http_host$uri;
post_action /out_of_band_oauth_authrep_action;
}
but it seems like anything with http://dns/content/xyz fails and only when I give http://dns/content/1.0/xyz does it work.
You seem to be capturing part of the URI on the location ~* ^/content/?(.*) statement, but do nothing with it.
You also have a rewrite ^/content/1.0(/.*)$ /content/1.0$1 break; statement that does nothing, it simply writes the same URI back.
A quick and dirty solution might be to use two rewrite statements like this:
rewrite ^/content/1.0(/.*)$ /content/1.0$1 break;
rewrite ^/content(/.*)$ /content/1.0$1 break;
Which means that anything that does not match the first (non-) rewrite will be processed by the second, and get a /1.0 inserted.
Personally, I do not like it, and would rather use two location blocks:
location /content/1.0 {
set $proxy_pass "http://backend_api.content.com";
proxy_pass $proxy_pass;
proxy_http_version 1.1;
proxy_set_header ...
...
}
location /content {
rewrite ^/content(/.*)$ /content/1.0$1 last;
}
But check the evaluation order of your other location blocks. Note that prefix location blocks and regular expression location blocks have different evaluation rules. See this document for details.