There are many ways to rewrite www urls to their non-www versions in nginx. Here one that’s Igor-approved and works well on my setup :
WWW to Non-WWW:
#301 redirect www to non-www
server {
listen [::]:80;
server_name www.domain.com;
rewrite ^ http://domain.com$request_uri? permanent;
}
server {
listen [::]:80;
server_name domain.com;
.........................................
.........................................
}
Non-WWW to WWW:
#301 redirect non-www to www
server {
listen [::]:80;
server_name domain.com;
rewrite ^ http://www.domain.com$request_uri? permanent;
}
server {
listen [::]:80;
server_name www.domain.com;
.........................................
.........................................
}
Related posts:

Great post! Thank you for figuring it out. However listen 80 is not needed:
From http://wiki.nginx.org/Pitfalls:
Listen 80
BAD:
server {
listen 80;
[...]
}
You don’t need “listen 80;” It is implied by Nginx. The only time you ever need to add this is if your adding “listen 80 default;” which will make that the default server block if no others are hit. Save the line, just don’t add it.
Yes, I know. Thanks for pointing that out. I wrote this a post around a year back, and I wasn’t aware of those pitfalls then.
However, listening to both IPv4 and IPv6 interfaces will require a
listen [::]:80;directive. That’s what I’m using now; hence I’ll update the code to use that.