Search code examples
kubernetesnginx-reverse-proxynginx-ingress

NGINX Ingress Annotations creates 404


I have an NGINX Ingress sitting in front of a few nodejs services. I want to restrict the path /graphql to only POST and only content-type=application/json

I've added the following annotation, which seems to work in terms of the restriction, but valid requests now return a 404

    nginx.ingress.kubernetes.io/server-snippet: |
      location /graphql {
      limit_except OPTIONS POST {
         deny all;
      }

      if ($http_content_type != "application/json") {
          return 403;
      }
  }

Solution

  • I think the problem is that your location {} block doesn't have an upstream like the regular paths defined in the nginx ingress. Get the nginx ingress configuration from ingress-nginx-controller pod:

    $ kubectl exec -n your-ingress-nginx-namespace ingress-nginx-controller-xxx-xxx -- cat /etc/nginx/nginx.conf
    

    And check some other location {} block to find what you might need for your /graphql location {} configuration.

    The following basic nginx.ingress.kubernetes.io/server-snippet works for me (requests other than POST and content-type=application/json return 403 status code, valid requests are OK):

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: cms-ingress-service
      annotations:
        kubernetes.io/ingress.class: "nginx"
        nginx.ingress.kubernetes.io/server-snippet: |
          location /graphql {
              limit_except OPTIONS POST {
                 deny all;
              }
              if ($http_content_type != "application/json") {
                  return 403;
              }
              set $proxy_upstream_name "default-nginx-80";
              proxy_pass http://upstream_balancer;
          }
    spec:
    ...
    

    Also, be aware of If is Evil... when used in location context.
    So, I advise you to test your final configuration thoroughly before putting it in production.