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;
}
}
CodePudding user response:
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.