Why am I writing this?
Recently, due to a bunch of factors (NSA,
DPI with advertising and others), I started to wake up paranoia and I thought to completely translate my small site to https. On Habré there were
several articles with technical details of SSL / TLS, however, looking for information on the https-web server settings found the traditional division of articles - either this article "Do like this", which simply gives the settings without any explanations and use cases, or these are large theoretical articles where various schemes of use are discussed, but without practically applicable ready-made options. On Habré there was
an article about setting up, but it does not contain information about DH-coding, and some parameters are not described. I thought that it would be worthwhile to organize the information found in the form of an article that would be useful for those who would like to deploy https on their server, but not get too deep into the SSL jungle.
The narration will be conducted taking into account the fact that the web server is nginx (and in one place there will be a parameter for php-fpm).
Certificate
I already had a certificate from StartSSL. About him already
wrote on Habré, so I will not linger on this step. I can only say that during the first two or three days, browsers checking the certificate on the server can swear at it (this happened to me with Opera 12 and Firefox), apparently StartCom doesn’t update the valid certificate caches so often. About the installation will be discussed below.
About customization options
Nginx out of the box in the new versions offers practically relevant, but still requiring polishing parameters, however, the actual parameters appeared in the standard config not so long ago, so in some cases the standard example HTTPS server in the config will not be relevant.
')
In general, there are two currently relevant configuration options - with and without Forward Secrecy. When setting up, the difference is only in the set of encodings (ssl_ciphers directive), however, it is worth considering what you want from https.
You can read about Forward Secrecy
here . In a nutshell, the bottom line is that for the currently current RC4 algorithm, session keys are generated based on the server's private key. Thus, if the private key is compromised, it will be possible to decrypt all sessions (if they were recorded). In the case of the use of DH encodings, each session has its own set of keys, which the session does not depend on the private key. However, in this case, much more CPU time is spent on the handshake, which increases the load and time of opening the page.
It is worth thinking about why you need https specifically on your site. With a large number of visitors, the use of DH encryption algorithms can significantly increase the load (which in any case will increase during the transition to HTTPS), in some cases it will be necessary to increase the tariff for VDS, etc. In most cases, RC4 is enough, but many want everything to be “on the upper class,” so why not do it if resources allow?
Nginx configuration
As a result of the configuration, I have formed approximately such a config, I will explain the essence of the parameters below.
In the http section you need to add:
ssl_session_cache shared:SSL:10m; ssl_session_timeout 5m; ssl_prefer_server_ciphers on; ssl_stapling on; resolver 8.8.8.8;
The server section will look like this:
server { listen 443 ssl; server_name www.site.ru; ....... keepalive_timeout 60; ssl_certificate certificate_bundled.crt; ssl_certificate_key privatekey.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers "HIGH:!RC4:!aNULL:!MD5:!kEDH"; add_header Strict-Transport-Security 'max-age=604800'; ....... location ~ \.php$ { ....... fastcgi_param HTTPS on;
This example does not use DH algorithms, i.e. No Forward Secrecy. Of the improvements, you can omit support for SSLv3 (removing it from ssl_ciphers), so IE 6 and lower will no longer be supported, because it does not support TLS, and also increase the STS time, but more on that below.
Without SSLv3, this setting gives a score of 100-95-100-90
in the SSL test .
Go through the parameters
ssl_session_cache shared: SSL: 10m;
ssl_session_timeout 5m;“Specifies the type and size of caches for storing session parameters.” (Nginx.org) The cache is necessary to enable the reuse of session keys, so old keys will be used when establishing a new connection, i.e. Handheld will not be re-produced. Especially important when using the DHE encoding (for example, in Opera 12 browser), since the page load time with all elements increases greatly when there is no cache, and DHE also uses more resources and time (relative to EECDH and RC4). The shared parameter sets the total for all workflows nginx cache, 10m - cache size (10 MB, with 1 MB ~ 4000 sessions, so with these settings you can store up to 40 thousand sessions), 5m - session timeout in cache (5 minutes) .
ssl_prefer_server_ciphers on;"Indicates that when using the SSLv3 and TLS protocols, server ciphers have higher priority than client ones." (Nginx.org) - client ciphers (CBC) are vulnerable to certain types of attacks.
ssl_stapling on;Allows the server to attach OCSP responses, thereby reducing the time to load pages from users. Here we mean answers about the validity of the certificate (when checking for revocation). From the point of view of the user's security, it does not matter who sends the answers — the web server or the CA server — after all, the answer is in any case signed and the validity of the answer can also be checked, and the answer includes its validity period.
For this function to work, you need to specify the DNS server, which is done by the resolver directive.
keepalive_timeout - I think the description does not need, you should not turn off or set too small to reduce the load due to re-establishing the connection.
ssl_certificate and
ssl_certificate_key point to the certificate file and the private key file for it. Since I am using the certificate from StartSSL as an example, I will admit a small comment on StartSSL instructions for installing a certificate — you don’t need to add the Root CA certificate to the generic certificate file, since it does not make sense and only increases, though not by much, the size of the transmitted data. It is enough to have a personal certificate and a certificate of an intermediate certification authority in the file. The finished certificate file for nginx (for StartSSL for the network certificate) can be obtained with the following command:
cat certificate.crt sub.class1.server.ca.pem > certificate_bundled.crt
Where your certificate is certificate.crt, and intermediate certificate is
www.startssl.com/certs/sub.class1.server.ca.pemadd_header Strict-Transport-Security 'max-age = 604800';Strict-Transport-Secutiry - a title that indicates to the browser that the site is accessible only by https. This prevents the possibility of switching back to the http version for a subsequent attack via an unencrypted connection. By the way, this parameter is still convenient because if the page has a “forgotten” connection of a resource (image / script / style / ...) from the same site via http, the browser itself will go to the https version and will not swear to partially unencrypted compound. Of course, this will not work for external resources. Time is a week. Many recommend putting 1 year, but if you decide in the future to stop using https this may cause problems for some users. The time is updated each time this header is transmitted, i.e. every time you visit the site.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;Specifies the supported protocols. SSLv2 and v3 have critical vulnerabilities.
ssl_ciphers "HIGH:! RC4:! aNULL:! MD5:! kEDH";Specifies the ciphers used. Actually by changing the set of ciphers and configured Forward Secrecy. It differs from the standard set offered by nginx only by the parameter! KEDH,
Forward secrecy
To enable Forward Secrecy, for example, you can use the following cipher suite:
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS";
In addition, you must configure the OpenSSL cipher priority:
openssl ciphers -V 'EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA256 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EDH+aRSA EECDH !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS'
In this embodiment, it is not prohibited to use RC4 to maintain compatibility with some browsers, however
, vulnerabilities were discovered not so long ago
in it , although it is practically difficult to implement.
To enhance encryption, you can increase the durability of DH ciphers by creating a DH cipher parameters file (creating the file will take some time!), Say 4096 bits long:
openssl dhparam -out dh4096.pem 4096
And adding a directive to the nginx config
ssl_dhparam dh4096.pem;
This can be done for say for web-based server / services management interfaces, but the handshake will take even longer, so you should not do it on a regular website.
About CDN-services
In discussing the
instructions for setting up Forward Secrecy, it was noted that at least CDN Amazon CloudFront does not support sharing with your server in DH encodings, and RC4 is also not that good. It is possible that not everything is perfect with other CDNs either, but I personally have not yet come across them, so I can’t say anything.
useful links
Testing https webserver settingsApache and nginx settings for Forward Secrecy