Set limit_req for specific location in Nginx Ingress





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















I'm trying to setup rate limiting option limit_req for specific path in Kubernetes ingress-nginx to prevent brute-forcing authentication.



I've defined limit_req_zone using ConfigMap:



http-snippet: |
limit_req_zone $the_real_ip zone=authentication_ratelimit:10m rate=1r/s;


Next, I'm using annotation to add a custom location block:



nginx.ingress.kubernetes.io/configuration-snippet: |
location ~* "^/authenticate$" {
limit_req zone=authentication_ratelimit nodelay;
more_set_headers "x-test: matched";
}


This produces nginx.conf:



server {
# - - 8< - -

location / {
# - - 8< - -

location ~* "^/authenticate$" {
limit_req zone=authentication_ratelimit nodelay;
more_set_headers "x-test: matched";
}

proxy_pass http://upstream_balancer;

proxy_redirect off;
}


The result is that /authenticate always returns HTTP 503 (with x-test header). Message from ingress access logs:



<ip> - [<ip>] - - [04/Jan/2019:15:22:07 +0000] "POST /authenticate HTTP/2.0" 503 197 "-" "curl/7.54.0" 172 0.000 [-] - - - - 1a63c9825c9795be1378b2547e29992d


I suspect this might be because of conflict between nested location block and proxy_pass (but this is just a wild guess).



What other options have I tried?




  • use server-snippet annotation instead of configuration-snippet - /authenticate returns 404 because proxy_pass is not configured

  • use nginx.ingress.kubernetes.io/limit-rpm annotation - forces ratelimit on whole application which is not what I want.


Question is why custom location block responds with 503? How can I debug this? Will increasing nginx logging level give more details about 503?
Or more general question: can I inject custom location blocks in ingress-nginx?










share|improve this question





























    0















    I'm trying to setup rate limiting option limit_req for specific path in Kubernetes ingress-nginx to prevent brute-forcing authentication.



    I've defined limit_req_zone using ConfigMap:



    http-snippet: |
    limit_req_zone $the_real_ip zone=authentication_ratelimit:10m rate=1r/s;


    Next, I'm using annotation to add a custom location block:



    nginx.ingress.kubernetes.io/configuration-snippet: |
    location ~* "^/authenticate$" {
    limit_req zone=authentication_ratelimit nodelay;
    more_set_headers "x-test: matched";
    }


    This produces nginx.conf:



    server {
    # - - 8< - -

    location / {
    # - - 8< - -

    location ~* "^/authenticate$" {
    limit_req zone=authentication_ratelimit nodelay;
    more_set_headers "x-test: matched";
    }

    proxy_pass http://upstream_balancer;

    proxy_redirect off;
    }


    The result is that /authenticate always returns HTTP 503 (with x-test header). Message from ingress access logs:



    <ip> - [<ip>] - - [04/Jan/2019:15:22:07 +0000] "POST /authenticate HTTP/2.0" 503 197 "-" "curl/7.54.0" 172 0.000 [-] - - - - 1a63c9825c9795be1378b2547e29992d


    I suspect this might be because of conflict between nested location block and proxy_pass (but this is just a wild guess).



    What other options have I tried?




    • use server-snippet annotation instead of configuration-snippet - /authenticate returns 404 because proxy_pass is not configured

    • use nginx.ingress.kubernetes.io/limit-rpm annotation - forces ratelimit on whole application which is not what I want.


    Question is why custom location block responds with 503? How can I debug this? Will increasing nginx logging level give more details about 503?
    Or more general question: can I inject custom location blocks in ingress-nginx?










    share|improve this question

























      0












      0








      0








      I'm trying to setup rate limiting option limit_req for specific path in Kubernetes ingress-nginx to prevent brute-forcing authentication.



      I've defined limit_req_zone using ConfigMap:



      http-snippet: |
      limit_req_zone $the_real_ip zone=authentication_ratelimit:10m rate=1r/s;


      Next, I'm using annotation to add a custom location block:



      nginx.ingress.kubernetes.io/configuration-snippet: |
      location ~* "^/authenticate$" {
      limit_req zone=authentication_ratelimit nodelay;
      more_set_headers "x-test: matched";
      }


      This produces nginx.conf:



      server {
      # - - 8< - -

      location / {
      # - - 8< - -

      location ~* "^/authenticate$" {
      limit_req zone=authentication_ratelimit nodelay;
      more_set_headers "x-test: matched";
      }

      proxy_pass http://upstream_balancer;

      proxy_redirect off;
      }


      The result is that /authenticate always returns HTTP 503 (with x-test header). Message from ingress access logs:



      <ip> - [<ip>] - - [04/Jan/2019:15:22:07 +0000] "POST /authenticate HTTP/2.0" 503 197 "-" "curl/7.54.0" 172 0.000 [-] - - - - 1a63c9825c9795be1378b2547e29992d


      I suspect this might be because of conflict between nested location block and proxy_pass (but this is just a wild guess).



      What other options have I tried?




      • use server-snippet annotation instead of configuration-snippet - /authenticate returns 404 because proxy_pass is not configured

      • use nginx.ingress.kubernetes.io/limit-rpm annotation - forces ratelimit on whole application which is not what I want.


      Question is why custom location block responds with 503? How can I debug this? Will increasing nginx logging level give more details about 503?
      Or more general question: can I inject custom location blocks in ingress-nginx?










      share|improve this question














      I'm trying to setup rate limiting option limit_req for specific path in Kubernetes ingress-nginx to prevent brute-forcing authentication.



      I've defined limit_req_zone using ConfigMap:



      http-snippet: |
      limit_req_zone $the_real_ip zone=authentication_ratelimit:10m rate=1r/s;


      Next, I'm using annotation to add a custom location block:



      nginx.ingress.kubernetes.io/configuration-snippet: |
      location ~* "^/authenticate$" {
      limit_req zone=authentication_ratelimit nodelay;
      more_set_headers "x-test: matched";
      }


      This produces nginx.conf:



      server {
      # - - 8< - -

      location / {
      # - - 8< - -

      location ~* "^/authenticate$" {
      limit_req zone=authentication_ratelimit nodelay;
      more_set_headers "x-test: matched";
      }

      proxy_pass http://upstream_balancer;

      proxy_redirect off;
      }


      The result is that /authenticate always returns HTTP 503 (with x-test header). Message from ingress access logs:



      <ip> - [<ip>] - - [04/Jan/2019:15:22:07 +0000] "POST /authenticate HTTP/2.0" 503 197 "-" "curl/7.54.0" 172 0.000 [-] - - - - 1a63c9825c9795be1378b2547e29992d


      I suspect this might be because of conflict between nested location block and proxy_pass (but this is just a wild guess).



      What other options have I tried?




      • use server-snippet annotation instead of configuration-snippet - /authenticate returns 404 because proxy_pass is not configured

      • use nginx.ingress.kubernetes.io/limit-rpm annotation - forces ratelimit on whole application which is not what I want.


      Question is why custom location block responds with 503? How can I debug this? Will increasing nginx logging level give more details about 503?
      Or more general question: can I inject custom location blocks in ingress-nginx?







      nginx kubernetes kubernetes-ingress nginx-ingress






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Jan 4 at 16:07









      jazgotjazgot

      1,013619




      1,013619
























          2 Answers
          2






          active

          oldest

          votes


















          1














          This can be done by using map and that fact that Requests with an empty key value are not accounted.



          http-snippets: |
          map $uri $with_limit_req {
          default 0;
          "~*^/authenticate$" 1;
          }
          map $with_limit_req $auth_limit_req_key {
          default '';
          '1' $binary_remote_addr; # the limit key
          }
          limit_req_zone $auth_limit_req_key zone=authentication_ratelimit:10m rate=1r/s;



          And use annotation to add a custom location block:



          nginx.ingress.kubernetes.io/configuration-snippet: |
          limit_req zone=authentication_ratelimit nodelay;


          Or if you use ingress from nginxinc



          nginx.org/location-snippets:
          limit_req zone=authentication_ratelimit nodelay;


          in this case check if requests need to be ratelimited processed on map level.



          And my opinion: better to limit requests on app level as if you made rate limit on ingress level, it depends on count of ingress pods.






          share|improve this answer































            0














            It might sound funny, but could you try just to create annotation like this:



            apiVersion: extensions/v1beta1
            kind: Ingress
            metadata:
            name: ingress-with-annotations
            annotations:
            nginx.org/server-snippets: |
            limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
            location ~* "^/authenticate$" {
            limit_req zone=mylimit burst=10 nodelay;
            more_set_headers "x-test: matched";
            }


            Because, it looks like you forgot to define limit_req_zone before you started using it in directive location. I used the official documentation about limit_req






            share|improve this answer


























            • I've defined limit_req_zone using http-snippet annotation because it is not allowed in server block.

              – jazgot
              Jan 8 at 10:10












            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54042445%2fset-limit-req-for-specific-location-in-nginx-ingress%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            This can be done by using map and that fact that Requests with an empty key value are not accounted.



            http-snippets: |
            map $uri $with_limit_req {
            default 0;
            "~*^/authenticate$" 1;
            }
            map $with_limit_req $auth_limit_req_key {
            default '';
            '1' $binary_remote_addr; # the limit key
            }
            limit_req_zone $auth_limit_req_key zone=authentication_ratelimit:10m rate=1r/s;



            And use annotation to add a custom location block:



            nginx.ingress.kubernetes.io/configuration-snippet: |
            limit_req zone=authentication_ratelimit nodelay;


            Or if you use ingress from nginxinc



            nginx.org/location-snippets:
            limit_req zone=authentication_ratelimit nodelay;


            in this case check if requests need to be ratelimited processed on map level.



            And my opinion: better to limit requests on app level as if you made rate limit on ingress level, it depends on count of ingress pods.






            share|improve this answer




























              1














              This can be done by using map and that fact that Requests with an empty key value are not accounted.



              http-snippets: |
              map $uri $with_limit_req {
              default 0;
              "~*^/authenticate$" 1;
              }
              map $with_limit_req $auth_limit_req_key {
              default '';
              '1' $binary_remote_addr; # the limit key
              }
              limit_req_zone $auth_limit_req_key zone=authentication_ratelimit:10m rate=1r/s;



              And use annotation to add a custom location block:



              nginx.ingress.kubernetes.io/configuration-snippet: |
              limit_req zone=authentication_ratelimit nodelay;


              Or if you use ingress from nginxinc



              nginx.org/location-snippets:
              limit_req zone=authentication_ratelimit nodelay;


              in this case check if requests need to be ratelimited processed on map level.



              And my opinion: better to limit requests on app level as if you made rate limit on ingress level, it depends on count of ingress pods.






              share|improve this answer


























                1












                1








                1







                This can be done by using map and that fact that Requests with an empty key value are not accounted.



                http-snippets: |
                map $uri $with_limit_req {
                default 0;
                "~*^/authenticate$" 1;
                }
                map $with_limit_req $auth_limit_req_key {
                default '';
                '1' $binary_remote_addr; # the limit key
                }
                limit_req_zone $auth_limit_req_key zone=authentication_ratelimit:10m rate=1r/s;



                And use annotation to add a custom location block:



                nginx.ingress.kubernetes.io/configuration-snippet: |
                limit_req zone=authentication_ratelimit nodelay;


                Or if you use ingress from nginxinc



                nginx.org/location-snippets:
                limit_req zone=authentication_ratelimit nodelay;


                in this case check if requests need to be ratelimited processed on map level.



                And my opinion: better to limit requests on app level as if you made rate limit on ingress level, it depends on count of ingress pods.






                share|improve this answer













                This can be done by using map and that fact that Requests with an empty key value are not accounted.



                http-snippets: |
                map $uri $with_limit_req {
                default 0;
                "~*^/authenticate$" 1;
                }
                map $with_limit_req $auth_limit_req_key {
                default '';
                '1' $binary_remote_addr; # the limit key
                }
                limit_req_zone $auth_limit_req_key zone=authentication_ratelimit:10m rate=1r/s;



                And use annotation to add a custom location block:



                nginx.ingress.kubernetes.io/configuration-snippet: |
                limit_req zone=authentication_ratelimit nodelay;


                Or if you use ingress from nginxinc



                nginx.org/location-snippets:
                limit_req zone=authentication_ratelimit nodelay;


                in this case check if requests need to be ratelimited processed on map level.



                And my opinion: better to limit requests on app level as if you made rate limit on ingress level, it depends on count of ingress pods.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Feb 28 at 14:00









                DmitryDmitry

                112




                112

























                    0














                    It might sound funny, but could you try just to create annotation like this:



                    apiVersion: extensions/v1beta1
                    kind: Ingress
                    metadata:
                    name: ingress-with-annotations
                    annotations:
                    nginx.org/server-snippets: |
                    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
                    location ~* "^/authenticate$" {
                    limit_req zone=mylimit burst=10 nodelay;
                    more_set_headers "x-test: matched";
                    }


                    Because, it looks like you forgot to define limit_req_zone before you started using it in directive location. I used the official documentation about limit_req






                    share|improve this answer


























                    • I've defined limit_req_zone using http-snippet annotation because it is not allowed in server block.

                      – jazgot
                      Jan 8 at 10:10
















                    0














                    It might sound funny, but could you try just to create annotation like this:



                    apiVersion: extensions/v1beta1
                    kind: Ingress
                    metadata:
                    name: ingress-with-annotations
                    annotations:
                    nginx.org/server-snippets: |
                    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
                    location ~* "^/authenticate$" {
                    limit_req zone=mylimit burst=10 nodelay;
                    more_set_headers "x-test: matched";
                    }


                    Because, it looks like you forgot to define limit_req_zone before you started using it in directive location. I used the official documentation about limit_req






                    share|improve this answer


























                    • I've defined limit_req_zone using http-snippet annotation because it is not allowed in server block.

                      – jazgot
                      Jan 8 at 10:10














                    0












                    0








                    0







                    It might sound funny, but could you try just to create annotation like this:



                    apiVersion: extensions/v1beta1
                    kind: Ingress
                    metadata:
                    name: ingress-with-annotations
                    annotations:
                    nginx.org/server-snippets: |
                    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
                    location ~* "^/authenticate$" {
                    limit_req zone=mylimit burst=10 nodelay;
                    more_set_headers "x-test: matched";
                    }


                    Because, it looks like you forgot to define limit_req_zone before you started using it in directive location. I used the official documentation about limit_req






                    share|improve this answer















                    It might sound funny, but could you try just to create annotation like this:



                    apiVersion: extensions/v1beta1
                    kind: Ingress
                    metadata:
                    name: ingress-with-annotations
                    annotations:
                    nginx.org/server-snippets: |
                    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
                    location ~* "^/authenticate$" {
                    limit_req zone=mylimit burst=10 nodelay;
                    more_set_headers "x-test: matched";
                    }


                    Because, it looks like you forgot to define limit_req_zone before you started using it in directive location. I used the official documentation about limit_req







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Jan 10 at 16:09









                    Black_Bacardi

                    30915




                    30915










                    answered Jan 7 at 11:33









                    Nick RakNick Rak

                    1,439614




                    1,439614













                    • I've defined limit_req_zone using http-snippet annotation because it is not allowed in server block.

                      – jazgot
                      Jan 8 at 10:10



















                    • I've defined limit_req_zone using http-snippet annotation because it is not allowed in server block.

                      – jazgot
                      Jan 8 at 10:10

















                    I've defined limit_req_zone using http-snippet annotation because it is not allowed in server block.

                    – jazgot
                    Jan 8 at 10:10





                    I've defined limit_req_zone using http-snippet annotation because it is not allowed in server block.

                    – jazgot
                    Jan 8 at 10:10


















                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54042445%2fset-limit-req-for-specific-location-in-nginx-ingress%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Monofisismo

                    Angular Downloading a file using contenturl with Basic Authentication

                    Olmecas