Nginx:ReverseProxy
lastmod 2024-11-06created 2020-12-119 edits
This article describes the basic configuration of a proxy server. You will learn how to pass a request from NGINX to proxied servers over different protocols, modify client request headers that are sent to the proxied server, and configure buffering of responses coming from the proxied servers.
Passing a Request to a Proxied Server
When NGINX proxies a request, it sends the request to a specified proxied server, fetches the response, and sends it back to the client. It is possible to proxy requests to an HTTP server (another NGINX server or any other server) or a non-HTTP server (which can run an application developed with a specific framework, such as PHP or Python) using a specified protocol. Supported protocols include FastCGI, uwsgi, SCGI, and memcached.
To pass a request to an HTTP proxied server, the proxy_pass directive is specified inside a location. For example:
nginx-forward script used in opm
server {
listen 80;
server_name "@FRONTEND_HOST@";
# charset utf-8;
# access_log /var/log/nginx/host.access.log main;
# dns resolver used by forward proxying.
resolver 8.8.8.8;
# Sets the maximum allowed size of the client request body.
client_max_body_size 1024m;
# proxy_connect;
# proxy_connect_allow 443 563;
# proxy_connect_connect_timeout 30s;
# proxy_connect_read_timeout 30s;
# proxy_connect_send_timeout 30s;
# [ERROR]
# location / {
# proxy_pass "@BACKEND_SCHEME@://@BACKEND_HOST@$uri$is_args$args";
# [ERROR]
# location ~ ^(/.*) {
# set $query $1;
# proxy_pass "@BACKEND_SCHEME@://@BACKEND_HOST@$query";
# [OK]
location / {
rewrite ^(/.*)$ $1 break;
proxy_pass @BACKEND_SCHEME@://@BACKEND_HOST@;
proxy_ssl_verify off;
proxy_set_header Host @FRONTEND_HOST@;
proxy_set_header X-Real-IP $proxy_protocol_addr;
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
}
}
WebSocket forwarding
Troubleshooting
400 error when passing spaces (%20)
The following is the most common usage, but it does not work properly when the path contains a space (%20). (I haven't verified it, but it seems %20 is turned into a space during normalization, so the argument is not passed correctly.)
So I applied it by adding it to a $query variable as below, and confirmed it worked properly.
However, MediaWiki returned a 300-range status code (I don't remember exactly) and the CSS wouldn't load ... -_-;; So I applied the rewrite engine as below and confirmed it worked properly.
Certificate is not trusted
The situation is as follows.
- The following is integrated via Swarm.
- HTTPS with Lets encript applied via Traefik sits in front,
- and NGINX Reverse Proxy is used to connect to another PC on the same network.
- (The other PC has the same environment as above, but was temporarily taken from where it was serving and connected directly)
- The other PC also has HTTPS with Lets encript applied via Traefik in front, and the service to connect to (GitLab) is inside it.
So the connection order is as follows:
client (browser) --[https]--> Traefik --[https]--> nginx reverse proxy --[https]--> (final PC's) treafik --[https]--> (final PC's) gitlab
At this point, each browser shows the following error. (The red box marks the way to connect in the browser's incognito mode.)
| | |
| For chrome, turning off HSTS is said to work, but it is not a fundamental solution. |
The fix is to add proxy_ssl_verify off;: