How to add blocking IP rules on each nginx-ingress host - nginx

I have searched a lot and I didn't find the solution. I want to block/allow ip's into each host definition in the nginx-ingress, not per locations.
This is the ingress.yaml:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-nginx
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: test1.test.com
#Blocking rules here, only affecting test1.test.com domain
http:
paths:
- path: /
backend:
serviceName: wordpressA
servicePort: 80
- host: test2.test.com
#Blocking rules here, only affecting test2.test.com domain
http:
paths:
- path: /
backend:
serviceName: wordpressB
servicePort: 80
Many thanks for your time

You need to split those host definitions into separate ingress rules.
Then you can use annotation to whitelist source range using following annotation :
nginx.ingress.kubernetes.io/whitelist-source-range
Something like this:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: app1-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/24"
spec:
rules:
- host: app1.com
http:
paths:
- path: /
backend:
serviceName: app1-service
servicePort: http
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: app2-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/24"
spec:
rules:
- host: app2.com
http:
paths:
- path: /
backend:
serviceName: app2-service
servicePort: http
You can also use server snipper and add nginx config to the yaml.
Something like this:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/server-snippet: |
location / {
# block one workstation
deny 192.168.1.1;
# allow anyone in 192.168.1.0/24
allow 192.168.1.0/24;
# drop rest of the world
deny all;
}

Related

set rate-limits for specific apis in kubernetes nginx

I am currently using nginx-ingress-controller in my eks-cluster.
I want to set rate-limits for only specific apis like /healthz like mentioned here and not only all my APIs.
Is there a way i can do it?
Thanks in advance
For separate specific you can make another ingress resource
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/limit-rps: "15"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
labels:
name: ingress
name: ingress
spec:
rules:
- host: healthz.example.io
http:
paths:
- backend:
serviceName: hello
servicePort: 80
path: /healthz
While you can make one ingress resource for other API, without rate limit setup
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "true"
labels:
name: ingress-2
name: ingress-2
spec:
rules:
- host: healthz.example.io
http:
paths:
- backend:
serviceName: hello
servicePort: 80
path: /data
- backend:
serviceName: hello
servicePort: 80
path: /api

Kubernetes + ingress-nginx - two apps, one of which in / path

I have two apps on a Kubernetes cluster which need to be exposed. One is a OAuth2 based authenticator, the other is the client app using it.
I would like to have the client app on test.mydomain.com and the authenticator on test.mydomain.com/auth
I tried building the following ingress in Kubernetes:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: my-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
nginx.ingress.kubernetes.io/proxy-body-size: "20m"
spec:
rules:
- http:
paths:
- path: /auth
backend:
serviceName: authenticator-service
servicePort: 8080
- path: /
backend:
serviceName: app-service
servicePort: 8080
For some reason, I can't get it to work, and whenever I try and hit test.mydomain.com/auth I end up hitting the main app-service. Am I doing something completely wrong? Is what I want to do even possible?
Try this -
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
kubernetes.io/ingress.class: nginx
name: my-ingress
spec:
rules:
- host: test.mydomain.com
http:
paths:
- path: /(.*)
backend:
serviceName: app-service
servicePort: 8080
- path: /auth/(.*)
backend:
serviceName: authenticator-service
servicePort: 8080

nginx-ingress add custom header for a specific path

I have the following nginx-ingress in a kubernetes environment
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "cache-control: no-store";
more_set_headers "MyCustomHeader: Value";
spec:
rules:
- http:
paths:
- backend:
serviceName: svc1
servicePort: 80
# Want to add the custom headers in this path only
path: /
- backend:
serviceName: svc2
servicePort: 80
path: /cacheable-path
I have a couple of headers that I want to set Cache-Control and MyCustomHeader. But I want these headers to be set only for the root path / and not for other routes (like /cacheable-path).
How to achieve this ? Adding the annotation causes the header to be appended to all the responses. I want the headers to be added to a specific path only.
It is not possible to add headers for a specific path in a single Ingress resource. You will have to create two Ingress resources.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "cache-control: no-store";
more_set_headers "MyCustomHeader: Value";
spec:
rules:
- http:
paths:
- backend:
serviceName: svc1
servicePort: 80
path: /
Without header
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- http:
paths:
- backend:
serviceName: svc2
servicePort: 80
path: /cacheable-path

We hosted a website in AWS Kubernetes Service. niginx-ingress-path issue

We hosted a website in AWS Kubernetes Service. We are having following issue.
issue1.css not working
issue2:Redirection also not working
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: myapp1-alerts-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/rewrite-target: "/"
spec:
tls:
- hosts:
- dev-api.myapp1.solutions
secretName: myapp1-alerts-tls
rules:
- host: dev-api.myapp1.solutions
http:
paths:
- path: /alerts
backend:
serviceName: myapp1-alerts
servicePort: 80
enter image description here
Take a look at the official documentation. There you will find an example below:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: rewrite
namespace: default
spec:
rules:
- host: rewrite.bar.com
http:
paths:
- backend:
serviceName: http-svc
servicePort: 80
path: /something(/|$)(.*)
| kubectl create -f -
In this ingress definition, any characters captured by (.*) will be
assigned to the placeholder $2, which is then used as a parameter in
the rewrite-target annotation.
For example, the ingress definition above will result in the following
rewrites:
rewrite.bar.com/something rewrites to rewrite.bar.com/
rewrite.bar.com/something/ rewrites to rewrite.bar.com/
rewrite.bar.com/something/new rewrites to rewrite.bar.com/new
Adjust your config accordingly and please let me know if that helped.

nginx ingress sub path redirection

I have an ingress controller and ingress resource running with all /devops mapped to devopsservice in the backend. When I try to hit "http://hostname/devops" things work and I get a page (although without CSS and styles) with a set of hyperlinks for e.g one of them is "logs".
When I click on the "logs" hyperlink, it is redirecting me to http://hostname/logs whereas I need it to be http://hostname/devops/logs.
Any idea what I can do?
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
namespace: ingress-nginx
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/add-base-url : "true"
spec:
rules:
- host: master1.dev.local
http:
paths:
- backend:
serviceName: devops1
servicePort: 10311
path: /devops
Looks like your ingress is not serving anything /devops/*. Try adding another path /devops/* with the same backend. Basically this:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
namespace: ingress-nginx
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/add-base-url : "true"
spec:
rules:
- host: master1.dev.local
http:
paths:
- backend:
serviceName: devops1
servicePort: 10311
path: /devops/*
- backend:
serviceName: devops1
servicePort: 10311
path: /devops
Update: the above has been deprecated in favor of something like this:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: rewrite
namespace: default
spec:
rules:
- host: master1.dev.local
http:
paths:
- backend:
serviceName: devops1
servicePort: 10311
path: /devops(/|$)(.*)
If you access http://hostname/devops/logs directly from your browser, certainly you will get what you want. But since you click the hyperlink in the homepage, then you can only get http://hostname/logs, which will be certainly failed.
So, you need /logs backend configured in your ingress yaml to get it processed, and configure nginx.ingress.kubernetes.io/configuration-snippet to ensure /logs not get rewrote, like this:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
namespace: ingress-nginx
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/add-base-url : "true"
nginx.ingress.kubernetes.io/configuration-snippet: |
rewrite ^/logs /logs break;
spec:
rules:
- host: master1.dev.local
http:
paths:
- backend:
serviceName: devops1
servicePort: 10311
path: /logs
- backend:
serviceName: devops1
servicePort: 10311
path: /devops
I met the similar issue recently.
Assuming the "logs" hyperlink in your html uses a relative path, which means the hyperlink doesn't start with '/', then I think you can try to hit the page at http://hostname/devops/ instead of http://hostname/devops. (Note a / suffix in the first url.).
Then the "logs" hyperlink will be formed as http://hostname/devops/logs.
I think it's about how the browser identifies the 'base' url. With accessing 'http://hostname/devops/, if there is no 'base' tag in the html header, the 'base' url will be figured out to be http://hostname/devops; while with 'http://hostname/devops', the base url will be http://hostname.
If it's not the case, there is discussion at https://github.com/kubernetes/ingress-nginx/issues/4149. It's suggested a workaround to use the nginx directive subs_filter with a configuration-snippet to make the href attributes relative and also add the base tag in the html header.
The ingress used is as below,
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: rewrite
namespace: default
spec:
rules:
- host: master1.dev.local
http:
paths:
- backend:
serviceName: devops1
servicePort: 10311
path: /devops(/|$)(.*)
The nginx.ingress.kubernetes.io/x-forwarded-prefix annotation can be used for this purpose.
It adds x-forwarded-prefix header to http request with a value from this annotation. You can use it, if your backend support such header.
For example, Spring Boot application can handle it by using property:
server.forward-headers-strategy=framework
In your case ingress would look like the following:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
namespace: ingress-nginx
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/x-forwarded-prefix: /devops
spec:
rules:
- host: master1.dev.local
http:
paths:
- backend:
serviceName: devops1
servicePort: 10311
path: /devops
This solution has its downsides. It forces you to declare each service in separate ingress.

Resources