6 ms·
Show HN: This weird bug is probably present in your Nginx configuration.
- patio11 15y agoThat's interesting and, if accurate, that bug is almost certainly affecting all my sites, PHP and otherwise. I'm writing this comment as a mental note to look into it after I get off the airplane.
- sim0n 15y agoSame here. Fixed on my local environment, just need to alter my production server asap.
- robflynn 15y agoYeah, same here. I'm surprised I had not heard of this before today, but I know for a fact that it affects at least one of my sites. Have a good flight. I'm stuck in a car for another few hours, myself.
- mfjordvald 15y agoIf you ever stopped by #nginx on Freenode you'd be told multiple times per day. :)
- robflynn 15y agoNever thought I had a need to. Now I do. :)
- nbpoole 15y agoAs the blog post points out, this does look to be a consequence of "IfIsEvil" (http://wiki.nginx.org/IfIsEvil http://wiki.nginx.org/IfIsEvil). The behavior of calling the script, not rendering it, and displaying the actual file is very strange though, especially since the if statements appear mutually exclusive. Maybe someone with nginx experience can explain why that would happen.
- mnutt 15y agoYeah, I love nginx and its syntax is great for the most part but it's easy to fall into the trap of thinking that you're writing in a turing-complete language. Something as simple as using multiple conditions in an if statement and redirecting to https if x-forwarded-proto is not set becomes a huge pain: https://gist.github.com/974486 https://gist.github.com/974486
- merlincorey 15y agoFirstly, everyone should read http://nginx.org/en/docs/http/request_processing.html http://nginx.org/en/docs/http/request_processing.html before they go trying to "figure out what NginX is doing". Secondly... because NginX configuration is declarative and ifs are imperative (the opposite paradigm). The imperative ifs are actually compiled into a little mini language and evaluated at runtime, but under the hood, ifs are hacky locations. This is the ultimate reason why If is Evil in NginX, and always will be. In NginX's declarative setup, you declare each separate location and the behavior that should result within that location. In NginX, only one location wins for ultimate processing! Finally, one must consider the order of evaluation of locations. Specifically, it is something like server if, location = (exact match), location ~ (regex match), location, location if --only one location wins, ever... but it may pass through several locations, especially if you add in error_pages and so on and so forth. So, coming full circle and attempting to answer the question of just why "calling the script, not rendering it, and displaying the actual file"; well, if you have not properly setup your locations such that PHP files always are routed to a PHP processing location, then you will in fact serve PHP files just like any other file. NginX's configuration language is much like any language - if you don't really know what it is doing, it is quite easy to make it do something you didn't expect.
- elliottcarlson 15y agoThe best configuration for a frontloader that I have found so far is: server { server_name domainname.com; root /srv/sites/domainname.com/httpdocs; index index.php; access_log /srv/sites/domainname.com/logs/access.log main; error_log /srv/sites/domainname.com/logs/error.log info; try_files $uri $uri/ /index.php?$query_string; location ~ \.php$ { try_files $uri $uri/ /index.php?$query_string =403; include /usr/local/nginx/conf/fastcgi_params; fastcgi_pass phpfpm; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } } This will allow static files to be served appropriately, standalone .php files to be run, and anything requiring a frontloader to be passed on accordingly. This should work with most frontloader based frameworks, however certain ones will fail, e.g. symphony (no not symfony)... EDIT: Added change suggested by nbpoole to fix security vulnerability.
- euroclydon 15y agoMy block has an expires line in there for caching: if (-f $request_filename) { expires 30d; break; } Where would it go in this new scenario?
- elliottcarlson 15y agoPersonally I handle that with Varnish in front of nginx so not really sure.
- mfjordvald 15y agotry_files allow you to use a named location as the final argument as opposed to a file path. This means you can have location /static_files { try_files $uri @fallback; } location @fallback { expires 30d; }
- nbpoole 15y agoThat configuration contains a major security vulnerability, at least if your site allows file uploads (I tested it on my server to be sure). I've written about this issue before: https://nealpoole.com/blog/2011/04/setting-up-php-fastcgi-and-nginx-dont-trust-the-tutorials-check-your-configuration/ https://nealpoole.com/blog/2011/04/setting-up-php-fastcgi-an... Edit: You need to copy the try_files line into the PHP location block. I'd recommend using the following line (I just added =403 to the end of yours, so you return a 403 error rather than a 500 error when try_files fails): try_files $uri $uri/ /index.php?$query_string =403;
- BCM43 15y agoThis is listed on their list of common pitfalls. Apparently there are a huge number of incorrect configurations posted online, with many of these errors in them. http://wiki.nginx.org/Pitfalls http://wiki.nginx.org/Pitfalls
- heyjonboy 15y agoAnother method is to automatically serve certain file extensions as static: location ~* ^.+.(jpg|jpeg|gif|css|png|js|zip|ico|xml|pdf|html)$ { access_log off; expires 30d; break; }
- rojoca 15y agoWhile not an option for everyone, serving static content from a different domain is another way to avoid this bug.
- wulczer 15y agoOfftopic: am I the only one struck by "about 2 hours of WTF'ing"? For a truly elusive bug, one that you stuff and hang over your fireplace after hunting it down, 2 weeks seem more appropriate.