28

I've a simple kubernetes ingress network.

I need deny the access some critical paths like /admin or etc.

My ingress network file shown as below.

 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

How I can deny the custom path with kubernetes ingress network, with nginx annonations or another methods .


I handle this issue with annotations shown as below .

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
   name: nginx-configuration-snippet
   annotations:
      nginx.ingress.kubernetes.io/configuration-snippet: |

     server_tokens off;
     location DANGER-PATH {
    deny all;
    return 403;
  }

spec:
  rules:
   - host: api.myhost.com
   http:
  paths:
  - backend:
      serviceName: bookapi-2
      servicePort: 8080
    path: PATH 
ColossusMark1
  • 1,189
  • 4
  • 14
  • 27

3 Answers3

14

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

sedooe
  • 3,100
  • 2
  • 22
  • 27
9

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.

Nick Rak
  • 2,629
  • 13
  • 19
  • I handled path denying with simple configuration for now, but thanks for your detailed answer Http Authentication spec at ingress. I will try it . Thanks again :) – ColossusMark1 Aug 17 '18 at 11:53
9

Copy the official Kubernetes way of doing this and use the defaultbackend container which always returns 404.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: defaultbackend
spec:
  selector:
    matchLabels:
      app: defaultbackend
  template:
    metadata:
      labels:
        app: defaultbackend
    spec:
      containers:
      - name: defaultbackend
        image: k8s.gcr.io/defaultbackend-amd64:1.5
        resources:
          requests:
            memory: 10M
            cpu: 5m
          limits:
            memory: 10M
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: defaultbackend
spec:
  selector:
    app: defaultbackend
  ports:
  - port: 80
    targetPort: 8080

Then in your ingress, add a paths entry:

      paths:
      - path: /
        backend:
          serviceName: my-real-service
          servicePort: 3000
      - path: /admin
        backend:
          serviceName: defaultbackend
          servicePort: 80
Chris Jones
  • 4,815
  • 6
  • 34
  • 28
  • Is it still safe? It looks like the `k8s.gcr.io/defaultbackend` image hasn't been updated for a while – JPFrancoia Mar 11 '23 at 10:52
  • Can you please link to the k8s documentation where this way is declared as "official"? I just wonder if this is really the official way. To me it looks brittle and dangerous. If a new version of the backend service will expose some new internal resources (in addition to `/admin`) and you will forget to update the Ingress accordingly, you will expose the new internal resources to the world. On the other hand, this is true for any "Include all, but exclude some paths" solution. So, this solution is no worse than any other to do this. – Ruslan Stelmachenko Aug 14 '23 at 15:44