9/10 NGINX Use Cases, URI and Host rewrites
NGINX Rewrite Directives, The 9/10 Solutions
When doing ADC/Load Balancer work, nearly all requests fit into two categories:
- Please rewrite part of the URL/URI
- Please change the host header for this reverse proxy
These are fairly simple to implement in NGINX, so I'm creating a couple of cheat-sheet code snippets here.
"Strip Part of the URL Out"
URI stripping is fairly common, and the primary motivation for this blog post. As enterprises move to Kubernetes, they're more likely to use proxy_pass
directives (among other things) to multi-plex multiple discrete services into one endpoint.
With URI stripping, an engineer can set an arbitrary URI prefix and then remove it before the web application becomes aware. URI stripping is a useful function to stitch multiple web services together into one coherent endpoint for customer use.
NGINX comes to the rescue here, with a relatively simple solution:
location
directive: Anchors themicro-
orsub-
service to an NGINX URIrewrite
directive: Rewrites themicro-
orsub-
service to a new directory, allowing for minimal backend modifications
The below example achieves this by rewriting the URI /build*
to /
, ensuring that the build service (Jenkins) doesn't need to be re-tooled to work behind a proxy:
1 location /builds/ {
2 root /var/lib/jenkins/workspace/;
3 rewrite ^/builds(.\*)$ $1 break;
4 autoindex on;
5 }
As you can see, this example is an obvious security risk, as the autoindex
directive lets clients browse through the build service without authentication and potentially access secrets, and is intended as an illustration and not a direct recommendation for production practice. Here's a little bit more production-appropriate example providing Jenkins over TLS (source: https://www.jenkins.io/doc/book/system-administration/reverse-proxy-configuration-nginx/)
1 server {
2 listen 443 ssl http2 default\_server;
3 listen \[::\]:443 ssl http2 default\_server;
4 server\_name cicd.lab.engyak.net;
5
6 ssl\_certificate "CERT;
7 ssl\_certificate\_key "KEY";
8 ssl\_session\_cache shared:SSL:1m;
9 ssl\_session\_timeout 10m;
10 ssl\_protocols TLSv1.2 TLSv1.3;
11 ssl\_ciphers ALL:!AES:!RC4:!SHA:!MD5;
12 ssl\_prefer\_server\_ciphers on;
13
14 # Load configuration files for the default server block.
15 include /etc/nginx/default.d/\*.conf;
16
17 location ~ "^/static/\[0\-9a-fA-F\]{8}\\/(.\*)$" {
18 #rewrite all static files into requests to the root
19 #E.g /static/12345678/css/something.css will become /css/something.css
20 rewrite "^/static/\[0\-9a-fA-F\]{8}\\/(.\*)" /$1 last;
21 }
22
23 location /userContent {
24 \# have nginx handle all the static requests to userContent folder
25 #note : This is the $JENKINS\_HOME dir
26 root /var/lib/jenkins/;
27 if (!-f $request\_filename){
28 #this file does not exist, might be a directory or a /\*\*view\*\* url
29 rewrite (.\*) /$1 last;
30 break;
31 }
32 sendfile on;
33 }
34 location / {
35 sendfile off;
36 proxy\_pass http://jenkins/;
37 \# Required for Jenkins websocket agents
38 proxy\_set\_header Connection $connection\_upgrade;
39 proxy\_set\_header Upgrade $http\_upgrade;
40
41 proxy\_set\_header Host $host;
42 proxy\_set\_header X-Real-IP $remote\_addr;
43 proxy\_set\_header X-Forwarded-For $proxy\_add\_x\_forwarded\_for;
44 proxy\_set\_header X-Forwarded-Proto $scheme;
45 proxy\_max\_temp\_file\_size 0;
46
47 #this is the maximum upload size
48 client\_max\_body\_size 10m;
49 client\_body\_buffer\_size 128k;
50
51 proxy\_connect\_timeout 90;
52 proxy\_send\_timeout 90;
53 proxy\_read\_timeout 90;
54 proxy\_buffering off;
55 proxy\_request\_buffering off; \# Required for HTTP CLI commands
56 proxy\_set\_header Connection ""; \# Clear for keepalive
57 }
58 error\_page 404 /404.html;
59 location = /40x.html {
60 }
61
62 error\_page 500 502 503 504 /50x.html;
63 location = /50x.html {
64 }
65 }
Set Host Headers
This is quite a bit easier, using the proxy_set_header
directive:
1 location /builds/ {
2 proxy\_pass http://localhost:8080;
3 proxy\_set\_header Host cicd.lab.engyak.net
4 rewrite ^/fabric-builds(.\*)$ $1 break;
5 }