DEV Community

Nick Schmidt
Nick Schmidt

Posted on • Originally published at blog.engyak.net on

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 the micro- or sub- service to an NGINX URI
  • rewrite directive: Rewrites the micro- or sub- 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:

  location /builds/ {
    root /var/lib/jenkins/workspace/;
    rewrite ^/builds(.\*)$ $1 break;  
 autoindex on;  
 }

Enter fullscreen mode Exit fullscreen mode

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/)

    server {
        listen 443 ssl http2 default_server;
        listen [::]:443 ssl http2 default_server;
        server_name cicd.lab.engyak.net;

        ssl_certificate "CERT;  
 ssl\_certificate\_key "KEY";  
 ssl\_session\_cache shared:SSL:1m;  
 ssl\_session\_timeout 10m;  
 ssl\_protocols TLSv1.2 TLSv1.3;  
 ssl\_ciphers ALL:!AES:!RC4:!SHA:!MD5;  
 ssl\_prefer\_server\_ciphers on;  

 # Load configuration files for the default server block.  
 include /etc/nginx/default.d/\*.conf;  

 location ~ "^/static/[0-9a-fA-F]{8}\/(.*)$" {  
 #rewrite all static files into requests to the root  
 #E.g /static/12345678/css/something.css will become /css/something.css  
 rewrite "^/static/[0-9a-fA-F]{8}\/(.\*)" /$1 last;
        }

        location /userContent {
            # have nginx handle all the static requests to userContent folder
            #note : This is the $JENKINS\_HOME dir
            root /var/lib/jenkins/;
            if (!-f $request_filename){
            #this file does not exist, might be a directory or a /\*\*view\*\* url
            rewrite (.*) /$1 last;
            break;
            }
            sendfile on;
        }
        location / {
                    sendfile off;
                    proxy_pass http://jenkins/;
            # Required for Jenkins websocket agents
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header Upgrade $http_upgrade;

            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_max_temp_file_size 0;

            #this is the maximum upload size
            client_max_body_size 10m;
            client_body_buffer_size 128k;

            proxy_connect_timeout 90;
            proxy_send_timeout 90;
            proxy_read_timeout 90;
            proxy_buffering off;
            proxy_request_buffering off; # Required for HTTP CLI commands
            proxy_set_header Connection ""; # Clear for keepalive
        }
        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

Enter fullscreen mode Exit fullscreen mode

Set Host Headers

This is quite a bit easier, using the proxy_set_header directive:

  location /builds/ {
    proxy\_pass http://localhost:8080;
    proxy\_set\_header Host cicd.lab.engyak.net
    rewrite ^/fabric-builds(.\*)$ $1 break;
  }

Enter fullscreen mode Exit fullscreen mode

Top comments (0)