Nginx 1.6.0 stable released
nginx.org
nginx.org
I've always preferred the official repository because I didn't want to start compiling nginx just for stuff like SPDY support.
http://nginx.org/packages/ubuntu/dists/trusty/nginx/binary-a...
While distros are usually pretty good about updating critical software, they shouldn't be your only line of defense, except perhaps if you have a SLA or something.
Would highly recommend becoming comfortable making your own packages (with any security updates, misc changes, etc.) over compiling and installing your own stack from source - distro packaging really is mostly your friend.
You will have 6 answers in 3 minutes.
foo.com/index > foo.com foo.com/ > foo.com foo.com/folder/index > foo.com/folder/ foo.com/bar.html > foo.com/bar foo.com/bar.htm > foo.com/bar foo.com/bar.php > foo.com/bar www.foo.com/ANY OF THE ABOVE TESTS > foo.com/*
other rules: Never add trailing slash unless it is an index file of a directory. Order: .PHP,.HTML,.HTM. Use h5bp/server-configs-nginx as a base. PHP-FPM should be fully supported and not exploitable by the foo.com/random.gif.php bug. 403 and 404 send to /404.html.
I am sure I am forgetting something, but that is a start.
# - Remove trailing slashes (except root /)
# e.g. /foo/bar/ -> /foo/bar
# ([^^] matches every character but the start of the string)
rewrite [^^](.*)/$ /$1 permanent;
# - Remove .html and .htm extensions
# e.g. /foo/bar.htm -> /foo/bar
rewrite ^(.*)\.html?$ $1 permanent;
# - Remove index file URLs
# e.g. /foo/bar/index -> /foo/bar/
# (the trailing slash is then removed by the first rewrite)
rewrite ^(.*/)index$ $1 permanent;
Edit: There's a couple extra directives that go along with the above to make it work that I neglected to include: # Try the request URI, and a potential index file in the URI (in the case of a directory).
# This lets you hit the file WEBROOT/foo/bar/index with the URI /foo/bar,
# and hit the file WEBROOT/foo/bar.html with the URI /foo/bar
try_files $uri $uri/index $uri.html =404;
# You need this (or some other way to provide the type information)
# if you don't have extensions on your files.
default_type text/html;
Also, for error pages, you can probably just use the error_page directive: error_page 404 403 /404; # The .html in your spec will be stripped off by the above rewrite rule if ($request_uri ~* "^(.*)\.html?$") {
return 301 $1;
}
The above is a safe use of "if", and can be helpful since it operates on the actual uri, not the internal uri.Also as far as foo.com/ -> foo.com, I was referring to the URL, not the acutal path.
example: https://www.google.com/ redirects to https://www.google.com correct? Maybe I am missing something...
$ curl -I https://www.google.com/
HTTP/1.1 200 OKhttp://www.foo.com/ is the "correct" URL. Remember how HTTP works -- you connect to foo.com port 80, then "GET / HTTP/1.1". You can't just omit the "/" and expect it to work.
HTTP clients will just request "/" if no path is specified, so nginx will never even see a request that matches "^foo.com$". You'll cause an infinite redirect loop if you try to force the issue.
I have a static site served via nginx, but I don't like seeing .html in the URLs.
It's a little tricky serving a static site without the .html extension because you may have a directory and an html page with the same name.
The way to deal with that is to actually use the .html extension in the file system but not URLs.
location / {
if ($uri ~ ^/google) {
break;
}
if ($uri ~ ^/y_key_) {
break;
}
if ($uri ~ \.html$) {
return 404;
}
if ($uri = /index) {
return 404;
}
if (!-f $request_filename) {
rewrite ^/$ /index.html break;
rewrite .* $uri.html break;
}
}Wouldn't something like this accomplish the same thing? (Sorry if I'm totally wrong, I'm not really good)
location /google/ {
}
location /y_key_/ {
}
location ~ \.html$ {
return 404;
}
location = /index {
return 404;
}
location / {
try_files $uri @rewrite
}
location @rewrite {
rewrite ^/$ /index.html break;
rewrite .* $uri.html break;
}Writing clean URLs is much easier with try_files, which allows you to do something like
try_files $uri.html
If you don't want to see file extensions.We've found good people through odesk to take on tasks we weren't good at -- front-end javascript, document translation, audio transcription, to name a few.
nginx seems to be increasingly irreplaceable (with ssl caching,etc.) - so was looking to not having to deal with varnish.
I did some google searches, but was not able to find anything - including nginx configs, etc. Nginx Plus claims to be an accelerator, but again there isnt a lot of info around that.
Also, I've come across benchmarks that say Varnish is faster. I just don't want to deal with a complex setup for something that gets the job done. (Job = lower the load on the app server)
Nginx has been getting better, and I'm excited to see what happens over the next couple of years.
Your opinion is needed for a great future of nginx!
14.04 includes nginx 1.4.6 but I'm sure the phusion guys will package 1.6 soon so I can easily upgrade to that. Is there any killer feature in nginx that I'm missing, staying with apache 2.4?
For example, here are numbers from Apache+mod_passenger on my dev box:
VSW RSS
root 20050 0.0 0.1 416524 21020 ? Ss Apr18 0:13 /usr/sbin/httpd
root 13370 0.0 0.0 217068 1984 ? Ssl Apr21 0:00 \_ PassengerWatchdog
root 13373 0.0 0.0 503104 2324 ? Sl Apr21 0:04 | \_ PassengerHelperAgent
nobody 13381 0.0 0.0 218208 3508 ? Sl Apr21 0:00 | \_ PassengerLoggingAgent
apache 13388 0.0 0.2 500060 33888 ? S Apr21 0:00 \_ /usr/sbin/httpd
apache 13389 0.0 0.2 500060 33888 ? S Apr21 0:00 \_ /usr/sbin/httpd
apache 13390 0.0 0.2 500060 33888 ? S Apr21 0:00 \_ /usr/sbin/httpd
apache 13391 0.0 0.2 500060 34140 ? S Apr21 0:00 \_ /usr/sbin/httpd
apache 13392 0.0 0.2 500132 33924 ? S Apr21 0:00 \_ /usr/sbin/httpd
And those same numbers on one of my production Linode instances, running nginx + passenger: VSW RSS
root 17824 0.0 0.0 7988 328 ? Ss Apr10 0:00 nginx: master process
nobody 31676 0.0 0.5 8732 3248 ? S Apr23 0:08 \_ nginx: worker process
nobody 9103 0.0 0.5 8684 3288 ? S Apr23 0:03 \_ nginx: worker process
nobody 9106 0.0 0.5 8876 3416 ? S Apr23 0:04 \_ nginx: worker process
nobody 22077 0.0 0.4 8400 3004 ? S 01:23 0:02 \_ nginx: worker process
(yes, I know that ps auxf isn't the best measure of memory usage, but it ballparks to make the point)I'm curious about the reverse proxy comment, though; mod_proxy_balancer generally does the job just fine. I do agree that nginx is easier to set up as a reverse proxy, though.
ProxyPass url1 url2
ProxyPassReverse url1 url2
Can it get any simpler than that?Of course, if you need to fine tune it for performance you are in the advanced category and should know what you are doing, but these two lines are all it gets to configure reverse proxy with sensible defaults.
There was a fairly recent comparison between nginx and apache2.2/2.4 (and uwsgi and gunicorn, I believe) driven by jmeter for testing that showed apache was a little lower on throughput -- but more consistent on latency (unfortunately I can't seem to find the link again). So while I think it is generally good advice to "just use nginx", I wouldn't write off apache based on how 1.3 used to behave compared to old versions of nginx.
I would normally advice an architecture where you have a reverse proxy in front of application servers (even if that means php with fastcgi) if you can, and when it makes sense. Possibly with ssl termination and/or caching (varnish) in front of that. I'm not sure that using nginx is actually any better than, say, HAproxy -- unless you need a static webserver in addition to your appserver. As always YMMV -- choose the stack that fits your needs.
My understanding too is that as we containerize more applications (whether this be Jails, Zones or Docker) then for shared-IP addresses (e.g. VirtualHosts) we need a reverse proxy to do the mapping to the correct container.
Do you know anything about this, as my research hasn't found anything?
client sends "host: some.service.example.com" -> proxy (alias for some.service.example.com) routes -> internal-ip:port
If you have enough public ips (be that ipv4 or ipv6) the "proxy" can just be a firewall rule that maps/NATs public-ip:80 to service:80 (or whatever). Not that that is necessarily a good idea.
Virtualhosting and proxying are related to containerizing (containing?) services -- but you could for example set up your reverse proxy in one container, map all traffic there, and then after deciphering host-headers and/or SNI route traffic to different back-ends.
It depends on what your needs are. For low traffic services, simply having the container answer on an external ip might be fine.
If you want to do more sophisticated load-balancing some system needs to take care of that, typically between the client and the back-end server (DNS only allows for round-robin distribution, barring tricks like giving different replies depending on who (from where) is asking).
Personally I'm leaning towards moving my "internal" ip-related stuff to ipv6 and only multihoming my outward facing points to ipv4 -- for simplicity. It does mean I actually have to set up firewall rules again, as most "internal" systems are now technically exposed. I guess it depends on how one draws the line -- does the container manage its own SSL/TLS termination (if applicable)?
http://www.atlanticdynamic.com/web-server-performance-analys...
Use passenger-memory-stats. It measures the Private Dirty RSS which is a more accurate measure of the actual memory usage because it takes shared memory into amount.
Production (nginx + passenger)
17824 1 7.8 MB 0.0 MB nginx: master process /etc/nginx/sbin/nginx -c /etc/nginx/conf/nginx.conf
3247 17824 8.3 MB 1.0 MB nginx: worker process
3685 17824 8.3 MB 1.0 MB nginx: worker process
3696 17824 8.2 MB 0.8 MB nginx: worker process
3699 17824 8.2 MB 1.0 MB nginx: worker process
### Processes: 5
### Total private dirty RSS: 3.71 MB
----- Passenger processes -----
PID VMSize Private Name
-------------------------------
17806 5.5 MB 0.0 MB PassengerWatchdog
17809 36.1 MB 2.1 MB PassengerHelperAgent
17814 10.9 MB 0.0 MB PassengerLoggingAgent
3385 424.6 MB 48.7 MB Passenger ClassicRailsApp
### Processes: 4
### Total private dirty RSS: 50.79 MB
Development (Apache + mod_passenger, no Rails apps running through it at the moment) ---------- Apache processes ----------
PID PPID VMSize Private Name
--------------------------------------
13388 20050 488.3 MB 18.8 MB /usr/sbin/httpd -DFOREGROUND
13389 20050 488.3 MB 18.8 MB /usr/sbin/httpd -DFOREGROUND
13390 20050 488.3 MB 18.8 MB /usr/sbin/httpd -DFOREGROUND
13391 20050 488.3 MB 18.9 MB /usr/sbin/httpd -DFOREGROUND
13392 20050 488.4 MB 18.9 MB /usr/sbin/httpd -DFOREGROUND
20050 1 406.8 MB 1.1 MB /usr/sbin/httpd -DFOREGROUND
### Processes: 6
### Total private dirty RSS: 95.45 MB
----- Passenger processes -----
PID VMSize Private Name
-------------------------------
13370 212.0 MB 0.3 MB PassengerWatchdog
13373 491.3 MB 0.3 MB PassengerHelperAgent
13381 213.1 MB 0.6 MB PassengerLoggingAgent
### Processes: 3
### Total private dirty RSS: 1.18 MBYup. We're working on 14.04 packages too.
Perhaps nginx might instead check all requests for a particular signed cookie, verify the signature, if the signature matches, verify that the cookie isn't too old, and then unpack variables from the cookie that the application server might want, such as REMOTE_USER. It seems nginx would then want to freshen-up the cookie.
If the cookie doesn't exist, signature doesn't match, or the cookie has expired, then, nginx should proxy the request to a delegate... but, it should return the results of that delegation directly to the user agent. It'd be the job of the delegate to set/sign the cookie with the information needed when authentication succeeds.
In this way, the authentication agent has full control over the process (so it doesn't have to be in nginx), and, heavyweight authentication is cached.
EDIT: Thanks mixedbit -- you're correct that nginx will forward 3xx onto the client. However, I recall patches are needed to support headers; and, without 200 going to the client, how do you support LDAP form authentication? Even so, an extra sub-request to authenticate each request is still heavyweight.
That's called session handling, which is something you want to implement in your web application, not your web server.
tl;dr build your authentication into your app, not the web server layer.
That said, even before this, Apache supported a million different mod_auth_* at http://httpd.apache.org/docs/2.4/mod/ including authentication caching http://httpd.apache.org/docs/2.4/mod/mod_authn_socache.html for modules that don't supply their own cache.
But yeah, there are options in Apache-land, my post was more that nginx could eventually gain those options too :)
http://davidjb.com/blog/2013/04/integrating-nginx-and-a-shib...
For some reason, I thought this behaviour made it to the upstream, till I re-read the official ngx_http_auth_request documentation and realized it doesn't pass through 3xx or headers other than WWW-Authenticate:
The ngx_http_auth_request_module module (1.5.4+) implements
client authorization based on the result of a subrequest.
If the subrequest returns a 2xx response code, the access
is allowed. If it returns 401 or 403, the access is
denied with the corresponding error code. Any other
response code returned by the subrequest is considered
an error. For the 401 error, the client also receives
the “WWW-Authenticate” header from the subrequest response.Here is a config that does something like this: https://github.com/wrr/wwwhisper/blob/master/nginx/wwwhisper... (deployed here: https://io-mixedbit.rhcloud.com)
(Sorry for the late reply)
However, the module hasn't been updated in forever, and to build it in recent versions of nginx, I have to turn certain CFLAGS off (i.e. Werror).
Does ngx_http_auth_request_module seem like it could do pubcookie's job? Or perhaps, can I approach this problem using ngx_lua?
They broke some stuff in the past moving to 1.4 from an older release, it would be nice to have a "release notes" so we can check what can possibly go wrong (if anything).
The changelog is huge, congratulations to the nginx team!
EDIT: nginx twitter account confirmed that there's no expected disruption upgrading from 1.4 to 1.6. Excellent!
So far everything works as expected.