Search code examples
kubernetesseokubernetes-ingressazure-aksnginx-ingress

How to rewrite URLs to lowercase in nginx controller on kubernetes


I have a requirement to rewrite all URLs to lowercase.

E.g. test.com/CHILD to test.com/child

Frontend application is developed on docker on azure kubernetes services. Ingress is controlled on nginx ingress controller.


Solution

  • You can rewrite URLs using Lua as described in the Enforce Lower Case URLs (NGINX) article.

    All we need to do is add the following configuration block to nginx:

    location ~ [A-Z] {
        rewrite_by_lua_block {
            ngx.redirect(string.lower(ngx.var.uri), 301);
        }
    }
    

    I will show you how it works.


    First, I created an Ingress resource with the previously mentioned configuration:

    $ cat test-ingress.yaml
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: test-ingress
      annotations:
        kubernetes.io/ingress.class: nginx
        nginx.ingress.kubernetes.io/rewrite-target: /
        nginx.ingress.kubernetes.io/server-snippet: |
         location ~ [A-Z] {
            rewrite_by_lua_block {
                ngx.redirect(string.lower(ngx.var.uri), 301);
            }
          }
    spec:
      rules:
      - http:
          paths:
          - path: /app-1
            pathType: Prefix
            backend:
              service:
                name: app-1
                port:
                  number: 80
                  
                  
    $ kubectl apply -f test-ingress.yaml
    ingress.networking.k8s.io/test-ingress created
    
    $ kubectl get ing
    NAME           CLASS    HOSTS   ADDRESS          PORTS   AGE
    test-ingress   <none>   *       <PUBLIC_IP>      80      58s
    

    Then I created a sample app-1 Pod and exposed it on port 80:

    $ kubectl run app-1 --image=nginx
    pod/app-1 created
    
    $ kubectl expose pod app-1 --port=80
    service/app-1 exposed
    

    Finally, we can test if rewrite works as expected:

    $ curl -I <PUBLIC_IP>/APP-1
    HTTP/1.1 301 Moved Permanently
    Date: Wed, 06 Oct 2021 13:53:56 GMT
    Content-Type: text/html
    Content-Length: 162
    Connection: keep-alive
    Location: /app-1
    
    $ curl -L <PUBLIC_IP>/APP-1
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    ...
    

    Additionally, in the ingress-nginx-controller logs, we can see the following log entries:

    10.128.15.213 - - [06/Oct/2021:13:54:34 +0000] "GET /APP-1 HTTP/1.1" 301 162 "-" "curl/7.64.0" 83 0.000 [-] [] - - - - c4720e38c06137424f7b951e06c3762b
    10.128.15.213 - - [06/Oct/2021:13:54:34 +0000] "GET /app-1 HTTP/1.1" 200 615 "-" "curl/7.64.0" 83 0.001 [default-app-1-80] [] 10.4.1.13:80 615 0.001 200 f96b5664765035de8832abebefcabccf