1

i am running an Nginx ingress controller and wanted to allow only few path for users to connect and rest all I wanted to block or provide an 403 error. how can i do that?

I only wanted users to allow to connect /example and rest all should be blocked.

kind: Ingress
metadata:
  name: ingress1
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: ingress.example.com
    http:
      paths:
      - path: /example
        backend:
          serviceName: ingress-svc
          servicePort: 80

Can i add a nginx server-snippet?

     location path {
       "if the path is not matching then deny"
       deny all;
     }```
akhinair
  • 73
  • 1
  • 7
  • The nginx ingress controller comes with a default backend which responds to every request that doesn' t match your routes. You can customize that to show whatever you want or you can make your own service and use it as a default backend. – Tarun Khosla Jul 25 '20 at 05:04
  • i am not interested to touch my default backend. This is only for a one specific ```/path``` . Can i add a nginx server-snippet? ```nginx.ingress.kubernetes.io/server-snippet: | location path { if the path is not matching then deny. something like that deny all; }``` – akhinair Jul 25 '20 at 13:12
  • Your seem to be contradicting in your statements , are you looking to block everything that doesnt match /example or are you looking to block one specific path. – Tarun Khosla Jul 25 '20 at 13:49
  • sorry for the confusion. yes, am looking to block everything that doesn't match ```/example```. I only want to allow ```/example```. – akhinair Jul 25 '20 at 14:40
  • Considering you don't want to touch your default backend , you can make a custom service that gives 403 when route matches /* and since ingress works on specificity it will work for all routes except /example – Tarun Khosla Jul 25 '20 at 14:44
  • do you have some examples or some documentation i can try? – akhinair Jul 25 '20 at 14:58
  • lets chat here https://chat.stackoverflow.com/rooms/218209/kubernetes – Tarun Khosla Jul 25 '20 at 15:12
  • ok.let me join. – akhinair Jul 25 '20 at 15:33
  • I am not able to enter my messages in chat room. sorry – akhinair Jul 25 '20 at 15:35
  • do you know why am not able to enter the messages? – akhinair Jul 25 '20 at 15:40
  • I think what you need is [here](https://stackoverflow.com/questions/51874503/kubernetes-ingress-network-deny-some-paths), in another stackoverflow question. Take a look and let me know if that answer your question. – Jakub Jul 28 '20 at 09:00

2 Answers2

2

Make a custom backend using below

apiVersion: apps/v1
kind: Deployment
metadata:
  name: custom-http-backend
spec:
  selector:
    matchLabels:
      app: custom-http-backend
  template:
    metadata:
      labels:
        app: custom-http-backend
    spec:
      containers:
      - name: custom-http-backend
        image: inanimate/echo-server
        ports:
        - name: http
          containerPort: 8080
        imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
  name: custom-http-backend
spec:
  selector:
    app: custom-http-backend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080

Then in your ingress add this rule

- host: ingress.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: custom-http-backend
          servicePort: 80
Tarun Khosla
  • 1,274
  • 7
  • 10
  • this will give you some custom output , you can change it to what you what to show as 403. – Tarun Khosla Jul 25 '20 at 15:50
  • thanks. i only wanted to send to ```custom-http-backend``` if the path is not ```/example```. so what is ``` path: /* ``` mean? – akhinair Jul 25 '20 at 16:13
  • It means all path after / , and since you will have a route for /example it will include everything that except example covered with that path. – Tarun Khosla Jul 25 '20 at 16:56
  • It means all path after / , and since you will have a route for /example it will include everything that except example covered with that path. – Tarun Khosla Jul 25 '20 at 16:56
  • just to clarify, can't we achieve same using ```nginx.ingress.kubernetes.io/server-snippet```. if the ```location``` is not matching then ```deny all```.? – akhinair Jul 25 '20 at 17:05
  • i got a similar post ```https://habr.com/ru/company/flant/blog/445596/``` – akhinair Jul 25 '20 at 17:06
  • https://kubernetes.github.io/ingress-nginx/examples/customization/custom-errors/ – Tarun Khosla Jul 25 '20 at 17:57
  • the above link talks about the same approach you mentioned. my point is can we achieve this using ```nginx.ingress.kubernetes.io/server-snippet``` and ```deny''' or the only way you told is the option?. I am trying to understand more. – akhinair Jul 25 '20 at 18:06
1

Additionally to what @Tarun Khosla mentioned which is correct, there is another stackoverflow question with examples which might be helpful. I am posting this as a community wiki answer for better visibility for the community, feel free to expand on it.

There are 2 examples provided by @Nick Rak


I’ve faced the same issue and found the solution on github. To achieve your goal, you need to create two Ingresses first by default without any restriction:

apiVersion: extensions/v1beta1
 kind: Ingress
 metadata:
 name: ingress-test
 spec:
   rules:
   - host: host.host.com
   http:
      paths:
        - path: /service-mapping
      backend:
         serviceName: /service-mapping
         servicePort: 9042

Then, create a secret for auth as described in the doc:

Creating the htpasswd

$ htpasswd -c auth foo
New password: <bar>
New password:
Re-type new password:
Adding password for user foo

Creating the secret:

$ kubectl create secret generic basic-auth --from-file=auth
secret "basic-auth" created

Second Ingress with auth for paths which you need to restrict:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-with-auth
  annotations:
    # type of authentication
    nginx.ingress.kubernetes.io/auth-type: basic
    # name of the secret that contains the user/password definitions
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    # message to display with an appropiate context why the authentication is required
    nginx.ingress.kubernetes.io/auth-realm: "Authentication Required - foo"
spec:
  rules:
  - host: host.host.com
    http:
      paths:
      - path: /admin
        backend:
          serviceName: service_name
          servicePort: 80

According to sedooe answer, his solution may have some issues.


and @sedooe

You can use server-snippet annotation. This seems like exactly what you want to achieve.

Jakub
  • 8,189
  • 1
  • 17
  • 31