Archive

Archive for the ‘nginx’ Category

SPNEGO For nginx - a start, at least

January 17th, 2010 mike 4 comments

I've been posting on the nginx mailing lists for a while that I've had a developer working on SPNEGO (Kerberos/GSSAPI/etc.) module for authentication for nginx. I never produced any code though, because I was constantly waiting for a bit more of a matured module before giving it out.

For now though, it might just be best to throw out there what I have, explain my findings, and let the community start testing it, hacking it, improving it, etc.

Download
http://michaelshadle.com/media/ngx_http_auth_sso_module-0.3.zip

Opens for the developer still

  • He said he'd like to remove the dependency on the bundled spnegohelp library (apparently it's not needed or it can be filled with a system package)
  • Needs some more documentation

My questions, comments

  • Should it be called "mod_auth_sso" or something like "mod_auth_gssapi" - I believe Apache's equivalent has "gssapi" in the title somewhere. It was hard to determine which was the most up to date version - mod_auth_kerb, modgssapache, etc.
  • I cannot verify this still using my corporate domain setup. I did have to make a minor tweak in the source to change the principal name it was using (see below) and I still got access denied. I have no clue if the module is to blame, the machine's setup with the domain, or what.

A possible required tweak... around line 474 or so in ngx_http_auth_sso_module.c

- host_name = r->headers_in.host->value;
+ host_name = alcf->realm;

How to compile - yes, it's a bit messy, mainly due to the spnegohelp library dependency :)

wget http://sysoev.ru/nginx/nginx-0.8.31.tar.gz
tar xvfz nginx-0.8.31.tar.gz
cd nginx-0.8.31
./configure --conf-path=/etc/nginx/nginx.conf --prefix=/usr --user=www-data --group=www-data --error-log-path=/var/log/nginx/error.log --pid-path=/var/run/nginx.pid --lock-path=/var/lock/nginx.lock --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/body --http-proxy-temp-path=/var/lib/nginx/proxy --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --with-http_stub_status_module --with-http_gzip_static_module --without-mail_pop3_module --without-mail_smtp_module --without-mail_imap_module --with-http_flv_module --with-http_ssl_module --with-http_dav_module --with-http_realip_module --with-http_xslt_module --with-debug --add-module=/usr/src/build/ngx_http_auth_sso_module-current --with-ld-opt="-L/usr/src/build/ngx_http_auth_sso_module-current/spnegohelp"
cp -f /usr/src/build/ngx_http_auth_sso_module-0.3/spnegohelp/libspnegohelp.so /usr/lib64/libspnegohelp.so
... make, make install, whatever ...

I copied the libspnegohelp.so into the system so nginx can use it without any special runtime LD_LIBRARY_PATH crap.

How to configure (again, I could not validate this 100%)

location /test {
   auth_gss on;
   auth_gss_realm YOUR.KERBEROS.REALM;
   auth_gss_keytab /etc/krb5.keytab;
   auth_gss_service_name YOURMACHINENAMEIBELIEVE;
}

Conclusion
Your mileage will definitely vary but hopefully some people with more experience with Kerberos, C, nginx modules, or anything else helpful can pick it apart. I will post updates as I get them and I do want to post this on github or something... unless someone else wants to take ownership over it who will actually actively maintain/keep it up to date with nginx internals and maintain the github/whatever repository for it.

This was self-funded personally with no company sponsorship or anything, part of the terms of the project were also to keep it BSD licensed. Feel free to do whatever you want with it. If you want to send me any money to reimburse, I'll never say no to that - paypal AT mike2k.com. Or, pay a developer who can ensure it works end-to-end, if there is something missing.

Sadly, it does require the machine to be on the domain, I was hoping I could get away with it not having to be on the domain. I confirmed with Sam Hartman, who was a chief technologist at the MIT Kerberos Consortium - you can't really get more knowledgeable than that. I would have hired Sam for the project but it would have been too expensive. However if a company is willing to take this initial coding and have Sam add his magic to it, he knows C and was able to give me a real quick estimate and check how nginx modules work. He could possibly do it for cheaper now since the initial work might be done, and he would definitely be able to confirm all the logic is intact.

Thanks to YoctoPetaBorg at RentACoder.com for the initial work (and for hopefully soon finishing up the last bits of this :p) - it will be exciting to be able to use this at work and be able to have a fully functional module out there that people find useful.

Categories: nginx Tags:

Transifex + Django + nginx on Ubuntu

November 1st, 2009 mike No comments

You can probably also use this for just Django + nginx on Ubuntu too, it should work the same for any Django-based package, just change the Transifex-specific stuff (like /site_media and such.)

Dependencies:

  • python-django package from Ubuntu (currently Jaunty's 1.0.2-1ubuntu0.1)
  • Transifex installed to /home/transifex/web/transifex, from source
  • Transifex setup to answer over fastcgi on port 8080
  • Tested on nginx 0.7.x and 0.8.x compiled from source

/etc/nginx/nginx.conf:

server {
   listen 80;
   server_name foo.com;
   include /etc/nginx/confs/defaults.conf;
   location / {
      fastcgi_pass 127.0.0.1:8080;
      include /etc/nginx/confs/django.conf;
   }
   location /site_media {
      root /home/transifex/web/transifex;
      include /etc/nginx/confs/expires.conf;
   }
   location /media {
      root /usr/share/python-support/python-django/django/contrib;
      include /etc/nginx/confs/expires.conf;
   }
}

/etc/nginx/confs/defaults.conf:

location ~ /\.ht {
   deny all;
}

location ~ \.svn {
   deny all;
}

log_not_found off;
server_name_in_redirect off;

/etc/nginx/confs/django.conf:

# http://www.rkblog.rk.edu.pl/w/p/django-nginx/
# http://code.djangoproject.com/wiki/ServerArrangements
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_pass_header Authorization;
fastcgi_intercept_errors off;

/etc/nginx/confs/expires.conf:

location ~* \.(jpg|jpeg|gif|css|png|js|ico|html)$ {
   expires max;
   access_log off;
}
Categories: nginx Tags:

Don't forget the $args!

May 15th, 2009 mike 9 comments

I just realized when trying to use the try_files shortcut that either the behavior has changed or the code I've used it for has never had to take advantage of it, but what happens when you do something like this:

try_files $uri $uri/ /foo/index.php?u=$uri;

Is that the query string is stripped out and the only thing PHP sees is the $_GET['u']

to fix this, it's easy enough:

try_files $uri $uri/ /foo/index.php?u=$uri&$args;

I never noticed this behavior in WordPress (I've been using try_files with it for a while without noticable issue) but it was an issue with Drupal (which uses the Front-Controller Pattern just like WP does) and custom code we've written.

UPDATE: depending on what custom WordPress plugins you may be using that rely on the $_GET params, you should add this. This should be the final recipe from what I can tell. :)

I haven't asked Igor if the behavior has changed slightly with it, but the changelogs have not mentioned any behavior changes, from what I can tell.

Anyway if you notice your pagination or other GET params are being dropped, you might want to take a quick look at that :)

Categories: WordPress, nginx Tags:

Finally using nginx's "try_files" directive

March 19th, 2009 mike 17 comments

OLD:

error_page 404 = /wordpress/index.php?q=$request_uri;

or:

if (!-e $request_filename) {
   rewrite ^/(.*) /wordpress/index.php?uri=$request_uri last;
}

NEW:

try_files $uri $uri/ /wordpress/index.php?q=$uri&$args;

Why make life more complicated if you don't need to?

Also thanks to Igor's patch you can have multiple of these, i.e.:

location /wordpress {
   try_files $uri $uri/ /wordpress/index.php?q=$uri&$args;
}

location /anotherapp {
   try_files $uri $uri/ /anotherapp/controllerfile.php?q=$uri&$args;
}

etc.

This is good, as Drupal, WordPress and many other packages (including anything I develop anymore) use the Front Controller pattern of development, which makes deploying applications a lot simpler and helps support a consistent framework across the entire application.

NOTE: Updated on 1/5/10 to include the $args :)

Categories: WordPress, nginx Tags:

nginx hits #4 on Netcraft

December 31st, 2008 mike 2 comments

Self-explanatory. nginx surpasses Lighttpd and moves up to #4 according to Netcraft. Woohoo!

http://survey.netcraft.com/Reports/200812/

Categories: nginx Tags:

Who ever said open source software was perfect?

December 14th, 2008 mike No comments

Typically, updates on the open source packages work without a hitch. However, my upgrade last weekend on my servers from Ubuntu Hardy to Intrepid wound up creating a couple major headaches, and at the same time, I noticed a handful of other snafoos happening to open source packages I use daily.

This wound up in server instability, client annoyance, and 20-30 hours solid of trial-and-error compiling, testing, debugging, etc. Even right now, if I forget to hold back the libgpac-dev package from being updated, all videos being converted lose their sound due to MP4Box crashing.

Categories: PHP, Software, nginx Tags:

nginx + WordPress - redux

August 17th, 2008 mike 1 comment

Note: this has been outdated once again. Now it can be simplified with one simple directive shown here.


There's been a minor tweak required in my original WordPress+nginx rewrite rule post.

I think we've finally got it right now. I've been exchanging emails ad nauseum with Igor and I believe the behavior now works properly (part of the exchange was regarding PHP+basic http auth, there were some bugs around the regexps/nested location blocks or something)

Anyway, here is a perfect working example, running this very website:

server {
   listen 80;
   server_name michaelshadle.com;
   index index.php;
   root /home/mike/web/michaelshadle.com/;
   include /etc/nginx/defaults.conf;
   include /etc/nginx/expires.conf;
   error_page 404 = /wordpress/index.php?q=$request_uri;
   location ^~ /wordpress/wp-admin {
      auth_basic "wordpress";
      auth_basic_user_file /home/mike/web/michaelshadle.com/.htpasswd;
      location ~ \.php$ {
         fastcgi_pass 127.0.0.1:11000;
      }
   }
   location ~ \.php$ {
      fastcgi_pass 127.0.0.1:11000;
   }
}

Likewise, you can also omit the basic HTTP authentication if you don't think you need it:

server {
   listen 80;
   server_name michaelshadle.com;
   index index.php;
   root /home/mike/web/michaelshadle.com/;
   include /etc/nginx/defaults.conf;
   include /etc/nginx/expires.conf;
   error_page 404 = /wordpress/index.php?q=$request_uri;
   location ~ \.php$ {
      fastcgi_pass 127.0.0.1:11000;
   }
}

Note: this does require a patched version of 0.7.10 - I assume he will put these changes into 0.7.11. Some of the changes required include the basic HTTP auth stuff. Also, when using error_page 404, it generated logfile noise in the error log. That was fixed as of 0.7.9 or 0.7.10, so no longer will you receive script-handled 404's in your error log.

This should be the last and final need to run WordPress properly under nginx. This has the approval of Igor, the creator - you cannot get better than that. (Note: this is WordPress 2.6.1, but I have not seen any reason the rewrite rule would be different since even before 2.x)

Let me know if it doesn't work! Or better yet, let the nginx mailing list know :)

Categories: WordPress, nginx Tags:

WordPress+nginx rewrite rules - stop the insanity!

May 1st, 2008 mike 4 comments

Note: this has been outdated now. I have an updated post with the latest and Igor-approved method here.

When I was switching over to nginx, I found a handful of random and overkill config examples to make it work. I thought I had found the simplest solution already, but Igor (the creator of nginx) actually gave me an even "better" solution in nginx.

This is assuming WordPress is physically installed in /wordpress, and pages are served up using friendly URLs, /2008/02/03/post-title/ - just like this site. All the rewrites are off the root. I assume you've already got PHP setup to parse properly and you have a working server {} block. I'll post that info too if people really need it.

1st example (seems like overkill, can't figure out a reason why people are splitting up the rewrite rules - I guess because they assume "wp-anything" is all static?):

if (!-e $request_filename) {
   rewrite ^([_0-9a-zA-Z-]+)?(/wp-.*) $2  break;
   rewrite ^([_0-9a-zA-Z-]+)?(/.*\.php)$ $2 last;
   rewrite ^ /index.php last;
}

2nd example (this was as good as I thought it could be, but I was wrong):

if (!-e $request_filename) {
   rewrite ^(.+)$ /wordpress/index.php?q=$1 last;
}

3rd example (this is the best, according to Igor):

error_page 404 = /wordpress/index.php?q=$uri;

(Ref: http://article.gmane.org/gmane.comp.web.nginx.english/4739)

Open source projects currently taking my interest

April 13th, 2008 mike 4 comments

For a long time I've been using Lighttpd as an alternative to Apache, Ubuntu, MySQL and PHP.

It looks like I might be mixing it up soon, swapping out some and adding a couple extras. Some of these I've been able to mess around with, others I am excited but have not yet had the chance...

PHP-FPM

PHP-FPM is just a patch for PHP, and a well-received one. I consider it important enough to showcase here. It matures the FastCGI SAPI and adds a couple of performance enhancements, graceful reloading, Apache-like process management for adaptive process spawning, and a much needed suexec-ish capability which will save me many headaches. It will hopefully be merged into PHP core when Andrei considers it "feature complete" and changes the license to be compatible. I can't wait. Right now it can still be used, and I've installed it without an issue on all my boxes - some serving up over a million PHP requests per day under different uid/gids. (Note: use Google Translate for the Russian URLs on the site above, the docs have not been translated to English yet. Google does a good job on it and it reads just fine.)

CouchDB

Throwing out all the concepts of structured databases and building a new system from the ground up with interoperability and scalability in mind as a data store? You've got me sold. It seems a lot of people are nervous about scaling MySQL (with good reason) and CouchDB might be a good alternative. Using RESTful URLs for everything and JSON as a lightweight (compared to SOAP/XML/etc.) transport language, it seems like we'll have plenty of options and usage models. I think I heard on a presentation as well that it will support files of any size, which potentially means it could be used not only as a possible RDBMS replacement (even though it says it isn't, I'm sure plenty of apps could use it), but also as a distributed document storage system (which it might already be considered.) Added bonuses: designed for high traffic, supports disconnected computing, self-healing replication, optimistic locking... I can't wait to play with this.

MogileFS

A distributed document storage system. I've thought about trying this out in the past, but I was mainly looking for a drop-in replacement for standard file storage. MogileFS may have some wacky method to do that via FUSE someday, but in the meantime, it can be leveraged for all application-based file storage, which I'd say is 95%+ of the files I deal with. Just like CouchDB, it leverages standards for communication (WebDAV for actual file access) and simple text-based socket communication which can be used from any programming language that supports a socket. Currently I am successfully running it with nginx serving up the WebDAV portion as opposed to the standard Perl-based webserver. It was too easy. I plan on trying to leverage this on xMike for all of the image uploads and other user assets, most definately. I like how it doesn't require any special low level support - it simply spreads files over N number of hosts and uses a tracker to determine which host(s) have which file(s) - and includes replication management so a broken node does not mean a broken file.

nginx

Powering a handful of extremely busy sites, nginx is the tiny webserver you may or may not have heard of. Every account of it I have read has done nothing but rave about it; I'm in the process of converting all the servers I manage over to it. With complaints about memory leaks in Lighttpd and Apache being bloated, I think it's prime time for nginx to get more attention as a viable option. It's still "beta" but what isn't nowadays? It's been running for over 2.5 years in production on the main site it was developed for and I'm sure many others. The configuration file syntax is extremely simple. It has a couple neat little additions, like the built-into-memory 1x1 transparent gif support (for all those webbugs and spacer images) so you no longer have to host it yourself and it serves it directly from memory. While that's a little bit off the basic needs of a webserver, that seems extremely useful as someone who has had to deal with those for years. Anyway, don't let the old "Mother Russia" style logo on the English wiki scare you. It's worth a shot, and could even replace Pound, other reverse proxies and Layer 7 capable load balancing solutions. I'm sure someone might even be able to write a replacement for Squid and Varnish using it too, by enhancing the proxy module to save local cached copies of the content...

I'm sure I might be missing a couple. It's getting late. I'd add memcached to the list, but I'm already using it. It's no longer "taking my interest" as I've been able to fully integrate it now :)

Interesting to note that all these products (especially MogileFS and CouchDB) are capable of being distributed and allow for transparent node failures and were designed to be ran on unreliable/commodity hardware. nginx basically does the same as well, since it is a web node (and I run the FastCGI processes on them too) and can scale horizontally already. It does kind of make me wonder though if I am slowly becoming deprecated by fully automated cloud computing-based solutions (like RightScale, 3Tera, Mosso, Elastra and even DIY Scalr)