How To Reject Requests With Too Long Urls In NGINX (HTTP 414)

by Oliver 26. November 2015 12:28

There are lots of posts out there on the topic of fixing the Request-URI Too Large error in NGINX, but this post is about how to generate such a response in order to avoid proxying requests with too long urls to a backend server. The Problem We recently had some really long request URLs coming through NGINX, with over 2000 characters! Those requests triggered an error response on our IIS hosted ASP.NET application – at first, on one backend server, then on the second one. This lead NGINX to believe that currently no backend servers are available for processing request which resulted in requests being dropped. Ouch! Hence, our motivation to avoid passing requests with too long urls down to our backend/upstream servers. Some Background Since we don't have any URLs in our application whose path segment exceed the default limit of 260 characters, there is no need to change the respective maxUrlLength attribute on the <httpRuntime> element. There's also a default value of 2048 characters for the length of the query string, defined in the maxQueryStringLength attribute, that might be of interest. So I set out to tell NGINX to drop requests with path segments longer than 260 chars or query strings longer than 2048 chars. The Solution We'll be looking at the $request_filename and $query_string variables and verify their length is less than or equal to the limits implemented in our application server. At first, I tried to find a way to return the length of these variables' values but I couldn't find any way to that inside the NGINX configuration file. So I was left with testing those variables against some value or… a regular expression. That's right, a regular expression will tell us if our variables exceed our length limits: if ( $request_filename ~* "^.{261,}$" ) {     return 414; } if ( $query_string ~* "^.{2049,}$" ) {     return 414; } We use the regex quantifier {n,} to match n or more occurrences of the previous expression, which in our case is a . (dot) meaning any character. Roundup We've put these two if directives at the server level of our configuration. We now successfully avoid to pass requests with too long urls to our application servers.

enjoyed the post?



SSL Certificate Jungle – Multiple Domains, Wildcards, and Both

by Oliver 10. September 2014 22:05

Recently, we've decided to add https:// support to Camping.Info. Since we've been running our application servers behind an NGINX reverse proxy for a while now, the natural choice in our setup was to terminate the secured connections at the NGINX server which has CPU usage values somewhere between 1% and 5%. This is also call SSL offloading and will allow us to keep all the SSL setup and potential runtime overhead off of our application servers. Certificate Options On Camping.Info, we serve almost all static content from the domain Since we want to secure the whole site, we need to have valid ssl certificates for and all subdomains of Using Separate Certificates The first solution to the problem would be using one SSL certificate for and one (wildcard) certificate for * that would secure all subdomains of If we wanted to secure itself as well, we would need a third certificate just for that one domain, because wildcard certificates do not cover the parent domain without a subdomain. Using a SAN (or UCC) Certificate Subject Alternative Names (SAN) can help in this situation. The subjectAltName field of an SSL certificate can contain many domain names that will be secured by that certificate. In our scenario we could have put,,,, and the other over 25 subdomains in there. Unfortunately, that would complicate things for the use of new subdomains in the future which would be missing from the list. A wildcard certificate really seems like the natural choice when you have more than 5 subdomains to secure or are expecting to have more of them in the near future. Using a Wildcard Certificate with SANs It turns out that wildcard certificates can well be combined with the usage of the subjectAltName field. Most CAs make you pay quite a lot for this combination, but we've also found a quite affordable offer on Multiple SSL Certificates on a Single NGINX Instance – Beware Choosing the first certificate option, i.e. using at least two certificates we now need to install both of them on our NGINX reverse proxy server. This blog post on how to install multiple SSL certificates on NGINX is a very good read – but be sure to read the comments as well. It turns out that the Server Name Indication (SNI) extension to the TLS protocol that allows you to do so will lock out clients that don't support SNI. The most prominent example of such a client is any version of Internet Explorer running on Windows XP, and even though Microsoft has ended support of XP almost half a year ago, we're still seeing 11% of our Windows users running XP accounting for 6% of our total traffic – a number we cannot ignore. Wanting to use separate SSL certificates on one NGINX instance we would need two different IP addresses pointing to that same server so that each certificate could respond to requests on one of those addresses. This would both complicate our setup and incur higher monthly infrastructural costs that we'd gladly avoid. Installing a Single SSL Certificate on NGINX The option we finally chose is to use a wildcard SAN certificate where we'd enter, and * as the different subject alternative names. Installing that into NGINX is straight-forward if you know how. Happy SSL'ing!

Setting up NGINX as Reverse Proxy for Camping.Info

by Oliver 24. June 2013 23:08

worker_processes 1; # Thanks to for helping me find out how many processor cores our VPS is using. Fixing the painful "24: Too many open files" error in NGINX When this error appears in your /var/etc/nginx/error.log file, you really want to do something about it. It basically tells you that some of your users are not being served content but instead receiving HTTP 500 errors generated by NGINX. Not a good thing! To investigate the open file descriptors on your linux (we're running NGINX on Ubuntu 12.04), I followed advice from this post: Linux: Find Out How Many File Descriptors Are Being Used. Then, to fix the low limits I found, 1024 and 4096 for the soft and hard limits, respectively, the post Set ulimit parameters on ubuntu provided a good walkthrough to changing those limits persistently, i.e. even after a reboot. But I somehow had the feeling that in case of NGINX there had to be a simpler solution. Turns out, there is. Let me introduce you to: worker_rlimit_nofile This thread in the NGINX forums contained the hint I needed: Re: Handling nginx's too many open files even I have the correct ulimit. I had actually posted to that thread before and received the helpful answer over a month ago, but I somehow hadn't got around to implementing it. Until today. So here's what you need to do: Set the worker_rlimit_nofile (in the main context) to something significant (I used 65536 = 2^16) instead of the default 1024 as soft and 4096 as the hard limit. Also set worker_connections to the same number to allow for a lot of parallel connections, both from clients and to upstream servers. Your nginx.conf file should now contain these lines: 1: user www-data; 2: worker_processes 1; 3: worker_rlimit_nofile 65536; 4: pid /var/run/; 5:  6: events { 7:     worker_connections 65536; ## default: 1024 8: # multi_accept on; 9: } Reload NGINX after configuration change In a shell, tell NGINX to reload the configuration. You don't need to restart the whole process to get a configuration change live. Just run: /usr/sbin/nginx -s reload or service nginx reload Now enjoy thousands and thousands of parallel connections to your proxy server :-)

About Oliver code blog logo I build web applications using ASP.NET and have a passion for jQuery. Enjoy MVC 4 and Orchard CMS, and I do TDD whenever I can. I like clean code. Love to spend time with my wife and our daughter. My profile on Stack Exchange, a network of free, community-driven Q&A sites

About Anton code blog logo I'm a software developer at teamaton. I code in C# and work with MVC, Orchard, SpecFlow, Coypu and NHibernate. I enjoy beach volleyball, board games and Coke.