
An nginx configuration for security - plentz
http://tautt.com/best-nginx-configuration-for-security/
======
spindritf

       > add-apt-repository ppa:nginx/stable
    

I don't think this is a good idea. It's a bit unclear on their wiki[1] but
they have an official repository maintained by nginx.org

    
    
        deb http://nginx.org/packages/ubuntu/ lucid nginx
        deb-src http://nginx.org/packages/ubuntu/ lucid nginx
    

(substitute your Ubuntu version for lucid, obviously)

 _and separately_ the PPA you're using but "this PPA is maintained by
volunteers and is not distributed by nginx.org." How committed are those
volunteers? Do you want to find out on your server?

The official repository carries nginx 1.4.2 (I use it with raring) which works
with at least TLS 1.1 (that's what Chrome tells me about the connection).

EDIT: Qualsys gives my setup an A, with a pat on the back for supporting
forward secrecy and a warning that I'm vulnerable to the BEAST attack.
Apparently, I also support TLS 1.2, what do you know.

[1]
[http://wiki.nginx.org/Install#Official_Debian.2FUbuntu_packa...](http://wiki.nginx.org/Install#Official_Debian.2FUbuntu_packages)

~~~
jolan
They actually package both 1.4.x and 1.5.x:

[http://nginx.org/en/linux_packages.html#stable](http://nginx.org/en/linux_packages.html#stable)

[http://nginx.org/en/linux_packages.html#mainline](http://nginx.org/en/linux_packages.html#mainline)

~~~
davidp
Thanks for this. Does "mainline" mean "unstable/development"? I briefly looked
around on nginx.org but couldn't find a description of the difference.

------
sdfjkl
A couple points:

* !RC4 - RC4 is in doubt[1]. The only reason to keep it around was to mitigate the BEAST attack, which is now mitigated[2] client side, so RC4 should be dropped.

* gzip off; - Explicitly disable gzip compression to avoid BREACH[3]

* Ensure TLS deflate is off to mitigate CRIME[4] (this is the default in most, but not all combinations of nginx/OpenSSL).

* openssl ciphers -v is great for testing what ciphers match your settings.

* Comment your nginx config! You will not remember all of this when you next look at it (or someone else does). And some of it will certainly be outdated. Security is not a static game.

[1]
[http://www.theregister.co.uk/2013/09/06/nsa_cryptobreaking_b...](http://www.theregister.co.uk/2013/09/06/nsa_cryptobreaking_bullrun_analysis/)
[2]
[https://community.qualys.com/blogs/securitylabs/2013/09/10/i...](https://community.qualys.com/blogs/securitylabs/2013/09/10/is-
beast-still-a-threat) [3]
[http://en.wikipedia.org/wiki/BREACH_%28security_exploit%29](http://en.wikipedia.org/wiki/BREACH_%28security_exploit%29)
[4]
[http://en.wikipedia.org/wiki/CRIME_%28security_exploit%29](http://en.wikipedia.org/wiki/CRIME_%28security_exploit%29)

~~~
JshWright
> * gzip off; - Explicitly disable gzip compression to avoid BREACH[3]

You don't have to disable gzip entirely. Just on any URLs where an attacker
could influence the contents of the response. If you serve all your static
assets out of their own location block, feel free to enable gzip there.

------
ck2
I guess it is a slow news day but there are better guides out there.

If you are using centos or any redhat related product you will have to build
your own openssl to get 1.0.1 with perfect-forward-secrecy (the IUS repository
does NOT include EC ciphers either). RedHat decided EC ciphers have patents
that are valid (they are not).

The example configuration is missing ocsp stapling.

Their configuration is also including the root certificate in the download for
every connection which is unnecessary.

Using RC4 over AES for beast mitigation is no longer considered optimal, if
anything RC4 is not 100% trustworthy anymore. Lean on elliptic-curve ciphers
with AES over RC4 for modern browsers. As a bonus you get CPU acceleration for
AES on most servers and many newer home computers.

~~~
plentz
Thanks for the heads up ck2. I've updated the config to add ocsp stapling. The
certificate really has a extra(unnecessary) root certificate, I will solve
this later today.

The RC4 part is based on this article
[https://community.qualys.com/blogs/securitylabs/2013/08/05/c...](https://community.qualys.com/blogs/securitylabs/2013/08/05/configuring-
apache-nginx-and-openssl-for-forward-secrecy). But I will do some more
research and update the post.

~~~
ck2
Ivan has already adjusted his views on RC4 as you can read here:

[https://community.qualys.com/blogs/securitylabs/2013/09/17/u...](https://community.qualys.com/blogs/securitylabs/2013/09/17/updated-
ssltls-deployment-best-practices-deprecate-rc4)

And the qualys SSL analyzer no longer penalizes for not mitigating Beast, they
just warn about it in orange but there is no longer a penalty as of a couple
weeks ago.

~~~
plentz
Thanks again ck2. I will read it today and update the post to mitigate BEAST
as well. Better then that, do you have a better setup for chipers?

~~~
ck2
The best thing I did with ciphers is stop just using everyone's "magic list"
without understanding what they are and what they mean.

To start understanding the magic list of ciphers, enter the list into openssl
like this and watch what it produces:

    
    
      openssl ciphers -V 'RC4'
      openssl ciphers -V 'EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW'  

(etc. etc.)

take away some of the adds/exclusions in the list and watch what they
add/remove. Plug in other people's lists and see what they do.

Then learn what ECDHE vs DHE means (and why DHE is slower)

Then learn about RSA vs DSA keys, EC ciphers etc.

Then play around with this tool that shows you what ciphers different browser
support (try it with IE8 vs Firefox vs Chrome, etc) [https://cc.dcsec.uni-
hannover.de/](https://cc.dcsec.uni-hannover.de/)

Then read about AES hardware acceleration in openssl on most modern processors
(not all but many). [http://zombe.es/post/4078724716/openssl-cipher-
selection](http://zombe.es/post/4078724716/openssl-cipher-selection)

and eventually, a few days later, you'll start to understand what is best :-)

It is always much more than a few lines in a configuration file if you really
want to understand.

------
jrochkind1
Why can't get the 'best config for security' be default out of the box on
nginx and apache httpd? That's the only way we're actually going to have a
secure web, ain't it?

~~~
jerf
There's been a lot of recent flux in what the consensus on "best config for
security" even is in the past six months. We went through a phase where RC4
was the recommended cipher, now we're mostly coming around to it being a bad
idea, for instance, and that's still a thing in progress rather than totally
done.

~~~
jrochkind1
Seems like someone should invent a way to easily get automatic updates to your
ssl config in apache and/or nginx.

I know I'm not the only one with half a dozen, a dozen, or dozens of web
servers I am responsible for -- who realistically isn't going to keep track of
what the current consensus is and go updating the ssl configuration even every
six months.

~~~
jerf
That would be Puppet, Chef, etc.

------
throwaway125
The following two headers are also useful:

    
    
        add_header Strict-Transport-Security max-age=31536000;
        add_header X-Frame-Options DENY;
    

The first one tells browsers it should never try to visit the http version of
this site, even if the user clicks on a http link the browser will visit the
https version. This helps prevent ssl stripping attacks.

The second prevents browsers from including this site in an iframe or frame,
which helps prevent clickjacking attacks. If your site depends on those you
can also set the option to SAMEORIGIN.

[https://developer.mozilla.org/en-US/docs/HTTP/X-Frame-
Option...](https://developer.mozilla.org/en-US/docs/HTTP/X-Frame-Options)
[https://developer.mozilla.org/en-
US/docs/Security/HTTP_Stric...](https://developer.mozilla.org/en-
US/docs/Security/HTTP_Strict_Transport_Security)
[https://en.wikipedia.org/wiki/SSL_stripping#SSL_stripping](https://en.wikipedia.org/wiki/SSL_stripping#SSL_stripping)

~~~
plentz
We currently are setting Strict-Transport-Security with rails, but as I said
in the comments of the blog, I think that setting this header inside nginx
could be a better idea.

------
epistasis
I hope this isn't too off topic, but this has to e the very worst mobile theme
I've seen for a site. Everything is blurry! And I can't zoom in, and there are
weird overlays hanging around. I wish people would stop putting in effort to
make their site harder to read. I couldn't even get through the first
paragraph, because I kept on reaching for my glasses on the nightstand, when
they are already on my face.

~~~
plentz
I think it's better now :)

~~~
epistasis
Wow, thanks for the response and the fix!

(I still would like to be able to zoom, but that's like asking for two ponies,
and even getting one pony is far better than I could reasonably expect.
Kudos!)

------
jamespo
It is fairly straightforward to compile nginx against the latest ssl tarball,
rather than the extreme option of distro upgrade (which as pointed out is no
good for Centos / RHEL) for the cipher support.

~~~
ck2
Actually this is speaking to two different issues.

Nginx is indeed one of the easiest programs to compile, very light and fast to
build.

Building the newest openssl from scratch for centos into an rpm is quite a
workout. I had to read two guides and still had to play with it a bit to get
everything just right. Oh and pro-tip from a big "duh" moment - don't try to
remove old openssl on a SSH connection. It doesn't just run from memory, when
it goes away, so does your connection to the server.

~~~
givehimagun
I really wish there was an openssl cookbook that upgraded openssl to 1.0.1 on
centos. Seems like something someone can automate.

------
victorf
This might be a good place to ask; is there a good way to get fail2ban and
nginx to work nicely together? I keep getting shitbirds pecking away at
/wpadmin on my website.

~~~
jlgaddis
A quick search for "fail2ban access.log wp-admin" turns up a few results that
look promising.

------
ChikkaChiChi
Link should be named "A Good Starting Config for Learning nginx Security"

If you don't know what each line of a config that is being spoon-fed to you
off of some website is doing, you're doing it wrong. Research everything!

~~~
plentz
I agree partially. To improve that, I will add comments in each line to
explain why I'm doing that.

------
leeoniya
i believe "ssl on" is redundant. "listen 443 ssl" already does this.

~~~
plentz
You're right, thanks :)

[http://wiki.nginx.org/HttpSslModule#ssl](http://wiki.nginx.org/HttpSslModule#ssl)
Note that since nginx version 0.7.14, the standard way to enable SSL is
through the listen directive

------
dholowiski
> Internal Server Error

There is a good amount of irony here. The most secure system is a system that
you can't access at all.

~~~
plentz
Apparently, Dreamhost isn't holding the traffic peak :(

~~~
antihero
Secure, on shared hosting eh?

~~~
plentz
Forgott.com is hosted @ linode. Our blog runs on Dreamhost.

~~~
JshWright
Secure, on Linode eh?

;)

~~~
plentz
Why do you think that linode can't be secure?

------
nkuttler
Just unplug the server.

Seriously though, any "best for security" article should be taken with a huge
grain of salt as security isn't something static that's the same everywhere.

~~~
nkuttler
The title here was editorialized after this comment. Original title was "Best
nginx configuration for security"

~~~
plentz
Yup. And it wasn't me :(

