Redirect from www to non www duplicates query params kubernetes - kubernetes

I am trying to redirect from https://example.nl to https://www.example.nl. This works perfectly. However, when I add query params, the query params get duplicated.
For example, whenever I go to example.nl?test=a, it redirects to wwww.example.nl?test=a?test=a.
How do I prevent this duplication of query params?
I use kubernetes and digital ocean. My kubernetes ingress file looks as follows:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
service.beta.kubernetes.io/do-loadbalancer-name: "example"
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/backend-protocol: HTTP
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($host = 'example.nl' ) {
rewrite ^ https://www.example.nl$request_uri permanent;
}
nginx.ingress.kubernetes.io/server-snippet: |
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types
application/atom+xml
application/geo+json
application/javascript
application/x-javascript
application/json
application/ld+json
application/manifest+json
application/rdf+xml
application/rss+xml
application/xhtml+xml
application/xml
font/eot
font/otf
font/ttf
image/svg+xml
text/css
text/javascript
text/plain
text/xml;
spec:
tls:
- hosts:
- www.example.nl
- example.nl
secretName: main-example-tls
rules:
- host: www.example.nl
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: front-end
port:
number: 3000
- path: /api
pathType: Prefix
backend:
service:
name: back-end
port:
number: 8000
- host: example.nl
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: front-end
port:
number: 3000
- path: /api
pathType: Prefix
backend:
service:
name: back-end
port:
number: 8000
If any additional informations is required. Please let me know.

try something like
annotations:
nginx.ingress.kubernetes.io/configuration-snippet: |
rewrite / https://test.app.example.com$uri permanent;
You can also refer my article : https://medium.com/#harsh.manvar111/kubernetes-ingress-domain-redirect-4595e9030a2c

Related

change in manifest file for ingress while upgrading k8s from 1.18 to 1.22 (v1beta1 to v1)using helm

I tried to make changes in menifest to run from k8s version 1.18 to 1.22 and below is how my manifest now look like
Older file (v1beta1)
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-api
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/modsecurity-snippet: |
SecRuleRemoveById 933160
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "X-Content-Type-Options: nosniff"
more_set_headers "Cache-Control: no-cache, no-store"
more_set_headers "X-XSS-Protection: 1; mode=block"
more_set_headers "Content-Security-Policy: default-src 'self';script-src 'self' 'unsafe-inline'; font-src 'self' fonts.gstatic.com fonts.gstatic.com data:;style-src 'self' fonts.googleapis.com fonts.gstatic.com 'unsafe-inline'; img-src 'self' data:; connect-src 'self' login.microsoftonline.com graph.microsoft.com https://{{.Values.instanceApiHost}} https://{{.Values.configurationApiHost}}; frame-src 'self' https://login.microsoftonline.com/;"
more_set_headers "X-RateLimit-Limit: 2500"
more_set_headers "X-Frame-Options: sameorigin"
more_clear_headers "server"
more_clear_headers "Server"
more_clear_headers "X-Powered-By"
more_clear_headers "x-powered-by"
nginx.ingress.kubernetes.io/limit-rps: "100"
nginx.ingress.kubernetes.io/rewrite-target: "/$1"
spec:
tls:
- hosts:
- {{.Values.configurationApiHost}}
secretName: managedservices-configurationapi-tls
- hosts:
- {{.Values.instanceApiHost}}
secretName: managedservices-instanceapi-tls
- hosts:
- {{.Values.host}}
rules:
- host: {{.Values.configurationApiHost}}
http:
paths:
- path: /
backend:
serviceName: configuration-api
servicePort: 8080
- host: {{.Values.instanceApiHost}}
http:
paths:
- path: /
backend:
serviceName: instance-api
servicePort: 8080
...
New file (v1)
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
labels:
app.kubernetes.io/component: controller
name: nginx
annotations:
ingressclass.kubernetes.io/is-default-class: "true"
spec:
controller: k8s.io/ingress-nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-api
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/modsecurity-snippet: |
SecRuleRemoveById 933160
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "X-Content-Type-Options: nosniff"
more_set_headers "Cache-Control: no-cache, no-store"
more_set_headers "X-XSS-Protection: 1; mode=block"
more_set_headers "Content-Security-Policy: default-src 'self';script-src 'self' 'unsafe-inline'; font-src 'self' fonts.gstatic.com fonts.gstatic.com data:;style-src 'self' fonts.googleapis.com fonts.gstatic.com 'unsafe-inline'; img-src 'self' data:; connect-src 'self' login.microsoftonline.com graph.microsoft.com https://{{.Values.instanceApiHost}} https://{{.Values.configurationApiHost}}; frame-src 'self' https://login.microsoftonline.com/;"
more_set_headers "X-RateLimit-Limit: 2500"
more_set_headers "X-Frame-Options: sameorigin"
more_set_headers "Strict-Transport-Security: max-age=31536000; includeSubDomains"
more_clear_headers "server"
more_clear_headers "Server"
more_clear_headers "X-Powered-By"
more_clear_headers "x-powered-by"
nginx.ingress.kubernetes.io/limit-rps: "100"
nginx.ingress.kubernetes.io/rewrite-target: "/$1"
spec:
kubernetes.io/ingress.class: nginx
tls:
- hosts:
- {{.Values.configurationApiHost}}
secretName: managedservices-configurationapi-tls
- hosts:
- {{.Values.instanceApiHost}}
secretName: managedservices-instanceapi-tls
- hosts:
- {{.Values.host}}
rules:
- host: {{.Values.configurationApiHost}}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: configuration-api
port:
number: 8080
- host: {{.Values.instanceApiHost}}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: instance-api
port:
number: 8080
Earlier older file was working with k8s 1.18 but it is now updated to 1.22 and we need to change the ingress manifest accordingly.
Attached above is the newer one having v1 version.
I am doing it via Helm Upgrade and below is the snippet of Azure pipeline task:
- task: HelmDeploy#0
displayName: Helm deploy instance-api
inputs:
connectionType: Kubernetes Service Connection
kubernetesServiceConnection: ${{ parameters.kubernetesServiceEndpointName }}
namespace: ${{ parameters.kubernetesNamespace }}
command: upgrade
chartType: FilePath
chartPath: $(Pipeline.Workspace)/HelmCharts/instance-api
releaseName: instance-api
force: false
Getting below error
Error: UPGRADE FAILED: unable to build kubernetes objects from current release manifest: resource mapping not found for name: "ingress-api" namespace: "" from "": no matches for kind "Ingress" in version "networking.k8s.io/v1beta1"
Still it is picking up the older v1beta1 call and not working. please help in case there are more changes required ?
No clues....

Kubernetes ingres.yml unknown field "service.port.number" in io.k8s.api.networking.v1

I'm running into issues with my ingress.yml. Getting this error:
error: error validating "ingress.yml": error validating data: [ValidationError(Ingress.spec.rules[0].http.paths[0].backend): unknown field "service.name" in io.k8s.api.networking.v1.IngressBackend, ValidationError(Ingress.spec.rules[0].http.paths[0].backend): unknown field "service.port.number" in io.k8s.api.networking.v1.IngressBackend, ValidationError(Ingress.spec.rules[0].http.paths[1].backend): unknown field "service.name" in io.k8s.api.networking.v1.IngressBackend, ValidationError(Ingress.spec.rules[0].http.paths[1].backend): unknown field "service.port.number" in io.k8s.api.networking.v1.IngressBackend];
Based on this documentation serviceName changed to service.name and servicePort changed to service.port and so on. Here is the ingress file:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: bitwarden
namespace: bitwarden
labels:
app: bitwarden
annotations:
# the name of the nginx-ingress-controller class
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "Request-Id: $req_id";
nginx.ingress.kubernetes.io/connection-proxy-header: "keep-alive"
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/limit-connections: "25"
nginx.ingress.kubernetes.io/limit-rps: "15"
nginx.ingress.kubernetes.io/proxy-body-size: 1024m
nginx.ingress.kubernetes.io/proxy-connect-timeout: "10"
nginx.ingress.kubernetes.io/proxy-send-timeout: "1800"
nginx.ingress.kubernetes.io/proxy-read-timeout: "1800"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- kryskanbit.ddns.net
secretName: bitwarden-tls
rules:
- host: kryskanbit.ddns.net
http:
paths:
- path: /
pathType: Prefix
backend:
service.name: bitwarden
service.port.number: 80
- path: /notifications/hub
pathType: Exact
backend:
service.name: bitwarden
service.port.number: 3012
Kubernetes has a special treatment for YAML format, so basically, you just need to extend the properties individually the service.name and service.port.number:
...
paths:
- path: /
pathType: Prefix
backend:
service:
name: bitwarden
port:
number: 80
- path: /notifications/hub
pathType: Exact
backend:
service:
name: bitwarden
port:
number: 3012
It should be as mentioned below:
backend:
serviceName: bitwarden
servicePort: 80

How to deny path in k8S ingress

I would like to block /public/configs in my k8s ingress.
My current settings doesnt work.
- host: example.com
http:
paths:
- path: /*
pathType: ImplementationSpecific
backend:
service:
name: service-myapp
port:
number: 80
- path: /public/configs
pathType: ImplementationSpecific
backend:
service:
name: service-myapp
port:
number: 88 // fake port
Is there any better (easy) way?
1- Create a dummy service and send it to that:
- path: /public/configs
pathType: ImplementationSpecific
backend:
service:
name: dummy-service
port:
number: 80
2- use server-snippets as bellow to return 403 or any error you want:
a) for k8s nginx ingress:
annotations:
nginx.ingress.kubernetes.io/server-snippet: |
location ~* "^/public/configs" {
deny all;
return 403;
}
b) for nginx ingress:
annotations:
nginx.org/server-snippet: |
location ~* "^/public/configs" {
deny all;
return 403;
}

Setting up kubernets Ingress proxy-body-size based on request method

I've been trying to set up a max body size in the Ingress controller based on the HTTP method of a given path.
Basically the POST method should allow 3m as max size and all the other methods should allow 1m.
Right now my main idea was to do something like:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-custom-service
namespace: development
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
kubernetes.io/ingress.class: "nginx-dev"
nginx.ingress.kubernetes.io/configuration-snippet: |
internal;
rewrite ^ $original_uri break;
nginx.ingress.kubernetes.io/server-snippet: |
location /api/v1/my-endpoint {
if ( $request_method = POST) {
set $target_destination '/_post';
client_max_body_size 3M;
}
if ( $request_method != POST) {
set $target_destination '/_not_post';
client_max_body_size 1M;
}
set $original_uri $uri;
rewrite ^ $target_destination last;
}
spec:
tls:
rules:
- host: my-host.com
http:
paths:
- path: /_post
backend:
serviceName: my-service
servicePort: 8080
- path: /_not_post
backend:
serviceName: my-service
servicePort: 8080
But then I'm getting the following error in the pod:
Is there any way I can correctly set-up the max body size via the ingress controller?
Try changing your annotations with the configuration-snippet
nginx.ingress.kubernetes.io/configuration-snippet: |
location /upload-path {
client_max_body_size 8M;
}
Read more at : https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/annotations.md#configuration-snippet

can ingress rewrite 405 to the origin url and change the http-errors 405 to 200?

Can ingress rewrite 405 to the origin url and change the http-errors 405 to 200?
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: frontend-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- http:
paths:
- path: /page/user/(.*)
pathType: Prefix
backend:
serviceName: front-user
servicePort: 80
- path: /page/manager/(.*)
pathType: Prefix
backend:
serviceName: front-admin
servicePort: 80
Ngnix can realize that visit a html page by a post method but I want to know how to realize by ingress.
server {
listen 80;
# ...
error_page 405 =200 #405;
location #405 {
root /srv/http;
proxy_method GET;
proxy_pass http://static_backend;
}
}
This is an e.g. that ngnix realize that visit a html page by a post method to change 405 to 200 and change the method to get
You can use server snippet annotation to achieve it.
Also I rewrote your ingress from extensions/v1beta1 apiVersion to networking.k8s.io/v1, because starting kubernetes v1.22 previous apiVersion is be removed:
$ kubectl apply -f ingress-snippit.yaml
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
Ingress-snippet-v1.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: frontend-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$1
nginx.ingress.kubernetes.io/server-snippet: | # adds this block to server
error_page 405 =200 #405;
location #405 {
root /srv/http;
proxy_method GET;
proxy_pass http://static_backend; # tested with IP since I don't have this upstream
}
spec:
rules:
- http:
paths:
- path: /page/user/(.*)
pathType: Prefix
backend:
service:
name: front-user
port:
number: 80
- path: /page/manager/(.*)
pathType: Prefix
backend:
service:
name: front-admin
port:
number: 80
Applying manifest above and verifying /etc/nginx/nginx.conf in ingress-nginx-controller pod:
$ kubectl exec -it ingress-nginx-controller-xxxxxxxxx-yyyy -n ingress-nginx -- cat /etc/nginx/nginx.conf | less
...
## start server _
server {
server_name _ ;
listen 80 default_server reuseport backlog=4096 ;
listen 443 default_server reuseport backlog=4096 ssl http2 ;
set $proxy_upstream_name "-";
ssl_certificate_by_lua_block {
certificate.call()
}
# Custom code snippet configured for host _
error_page 405 =200 #405;
location #405 {
root /srv/http;
proxy_method GET;
proxy_pass http://127.0.0.1; # IP for testing purposes
}
location ~* "^/page/manager/(.*)" {
set $namespace "default";
set $ingress_name "frontend-ingress";
set $service_name "front-admin";
set $service_port "80";
set $location_path "/page/manager/(.*)";
set $global_rate_limit_exceeding n;
...