Kubernetes ingress rewrite-target and the rewrite regex/capture group (?i)

4/12/2021

Based on this guide.

I have created this ingress:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/enable-rewrite-log: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  name: ing-something
  namespace: samples
spec:
  rules:
  - host: myhost.internal
    http:
      paths:
      - backend:
          serviceName: my-app
          servicePort: 8080
        path: /api(/|$)(.*)
  tls:
  - hosts:
    - myhost.internal
    secretName: lets
status:
  loadBalancer:
    ingress:
    - {}

When I take a look at the bottom of the generated nginx.config it contains:

## start server myhost.internal
server {
	server_name myhost.internal ;
	
	listen 80;
	
	set $proxy_upstream_name "-";
	set $pass_access_scheme $scheme;
	set $pass_server_port $server_port;
	set $best_http_host $http_host;
	set $pass_port $pass_server_port;
	
	listen 443  ssl http2;
    ...
	location ~* "^/api(/|$)(.*)" {
		
		set $namespace      "samples";
		set $ingress_name   "ing-something";
		set $service_name   "my-app";
		set $service_port   "8080";
	set $location_path  "/api(/|${literal_dollar})(.*)";
		
        ...
		

		
		rewrite "(?i)/api(/|$)(.*)" /$2 break;
		proxy_pass http://upstream_balancer;
		
		proxy_redirect                          off;
		
	}
	
	location ~* "^/" {
		
		set $namespace      "";
		set $ingress_name   "";
		set $service_name   "";
        ...
    }

I don't understand where this part (?i) is coming from in:

		rewrite "(?i)/api(/|$)(.*)" /$2 break;

and what it means.

Any ideas?

-- u123
kubernetes
nginx
regex

1 Answer

4/19/2021

This is a community wiki answer based on the info from the comments and posted for better visibility. Feel free to expand it.

As already pointed out in the comments, the path matching is case-insensitive by default:

Using the nginx.ingress.kubernetes.io/use-regex annotation will indicate whether or not the paths defined on an Ingress use regular expressions. The default value is false.

The following will indicate that regular expression paths are being used:

nginx.ingress.kubernetes.io/use-regex: "true"

The following will indicate that regular expression paths are not being used:

nginx.ingress.kubernetes.io/use-regex: "false"

When this annotation is set to true, the case insensitive regular expression location modifier will be enforced on ALL paths for a given host regardless of what Ingress they are defined on.

Additionally, if the rewrite-target annotation is used on any Ingress for a given host, then the case insensitive regular expression location modifier will be enforced on ALL paths for a given host regardless of what Ingress they are defined on.

Please read about ingress path matching before using this modifier.

And all the specifics regarding the Mode Modifiers can be found here:

Mode modifier syntax consists of two elements that differ among regex flavors. Parentheses and a question mark are used to add the modifier to the regex. Depending on its position in the regex and the regex flavor it may affect the whole regex or part of it. If a flavor supports at least one modifier syntax, then it will also support one or more letters that can be used inside the modifier to toggle specific modes. If it doesn’t, “n/a” is indicated for all letters for that flavors.

Notice the Specifying Modes Inside The Regular Expression for case-insensitivity:

(?i)	Turn on case insensitivity.	(?i)a matches a and A.
-- Wytrzymały Wiktor
Source: StackOverflow