As everyone's awareness of online security increases, and major Internet companies promote the popularization of HTTPS, HTTPS SSL has now basically become the standard for building websites. Thanks to the free SSL certificates provided by Let’s Encrypt, Digicert, TrustAsia, Symantec, etc., the cost of using HTTPS is now negligible whether it is a personal website or a corporate website.

For security, we need to use HTTPS, but turning on SSL will increase the overhead of memory, CPU, and network bandwidth. Compared with http, using TCP three-way handshake to establish a connection, the client and server need to exchange 3 packets. In addition to the three packets of TCP, https also needs 9 packets required for the SSL handshake, for a total of 12 packets. Therefore, if HTTPS is optimized a lot, it is prone to slow performance.

Of course, some people may think that the increased server overhead of HTTPS and SSL is basically not felt. This is because the traffic of the website is relatively small, and the performance configuration of the server is enough to support the current traffic. But for large websites, such as Baidu, Google and popular apps, it is still very useful to optimize HTTPS performance and reduce resource consumption.

Eight tips on how to optimize HTTPS and SSL - reduce waiting time, reduce HTTPS performance loss, and increase SSL caching

This article will share some experience in optimizing the use of HTTPS and SSL. There are more experience tutorials about SSL certificates and HTTPS:

  1. Collection and summary of free SSL certificates - add HTTPS secure encrypted access to the website for free
  2. Ten CloudFlare Free CDN Acceleration Tips You May Not Know-SSLDDOSCache
  3. Enable HSTS and join the HSTS Preload List to make HTTPS access to the website more secure - with a method to delete HSTS

PS: Updated on September 6, 2018, if you want to use a paid DNS resolution service, here are two cheaper DNS services that are more suitable for individuals: Two DNS products suitable for personal use: ClouDNS and DNS Made Easy domain name resolution.

PS: Updated on January 15, 2019, If you want SSL access to get faster speed and higher performance, you can try TLSV1.3 and Brotli compression: Website optimization acceleration-turn on TLSV1.3 and Brotli compression-Oneinstack, LNMP, Pagoda panel.

1. How to choose a free SSL certificate?

It is recommended to choose Let’s Encrypt. Although Let’s Encrypt free SSL certificate is only 90 days, it can be renewed indefinitely and supports manual and automatic renewal. Let’s Encrypt SSL is recognized by all major browsers and is the first choice for free SSL certificates. Tutorial: Let’s Encrypt Wildcard free domain name SSL certificate one-click application and SSL usage tutorial.

Let’s Encrypt is suitable for hosts with independent IPs such as VPS. Otherwise, you can only use some online SSL certificate applications developed using Let’s Encrypt API. Of course, if you have a certain financial strength, it is more feasible to choose a paid SSL certificate. For more SSL certificates, see: Collection and summary of free SSL certificates.

2. Enable HSTS on the server

Websites that use the HSTS protocol will ensure that the browser always connects to the HTTPS version of the website, without requiring users to manually enter an encrypted address containing https:// in the URL address bar. I use the Nginx server. I only need to edit the Nginx configuration file (such as: /usr/local/nginx/conf/nginx.conf) and add the following lines to the server block of the HTTPS configuration:

add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";

For detailed methods of enabling HSTS for Apache, Lighttpd, etc., see: Enable HSTS on the server.

3. Add the domain name to the HSTS preload list plan

Although the HSTS protocol is enabled above to ensure that users always access Https connections, generally users who visit the website for the first time will habitually enter non-https domain names, which leads to the problem of http hijacking when visiting the website for the first time. The HSTS preload list plan is to solve this problem. It is a built-in list in browsers such as chromeFirefoxEdge.

How to join the HSTS Preload List: Enable HSTS and join the HSTS Preload List to make HTTPS access to the website more secure - Attached is the method of deleting HSTS. At present, wzfou.com has been successfully added to the HSTS preload list. If you are using Chrome or Firefox, the first time you visit this site, you will use HTTPS to connect by default.

Enable OCSP Stapling in Nginx. (ssl_trusted_certificate can be omitted if the ssl_certificate directive specifies the complete certificate chain)

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /path/to/certs/chained.pem;

Enable OCSP Stapling in Apache:

In <VirtualHost></VirtualHost> add:

SSLUseStapling on

Outside <VirtualHost></VirtualHost> add:

SSLStaplingCache shmcb:/tmp/stapling_cache(128000)

5. Use ECC and RSA dual certificates

By default, we will all use RSA certificates because RSA certificates have the widest compatibility. However, the ECC certificate has the characteristics of small size, fast computing speed, and high security (256-bit ECC key can provide security equivalent to the 3072-bit RSA key). It can Provides HTTPS performance to a certain extent.

Let’s Encrypt already supports generating ECC certificates. Use acme.sh to issue SSL certificates. Specify --keylength ec-256 to change the certificate type to ECC:

acme.sh --issue -w /data/wwwroot/wzfou.com -d wzfou.com -d www.wzfou.com --keylength ec-256

It should be noted that ECC is not compatible on Windows XP. At this time, we will think of using dual certificates. That is, when the ECC certificate is not supported, Nginx will automatically display the RSA certificate to the user. If the version of nginx is greater than 1.11, you can directly write the paths of ECC and RSA dual certificates in the configuration file. wzfou.com demonstrates as follows:

#ECC
ssl_certificate /root/.acme.sh/wzfou.com_ecc/fullchain.cer;
ssl_certificate_key /root/.acme.sh/wzfou.com_ecc/wzfou.com.key;
#RSA
ssl_certificate /usr/local/nginx/conf/ssl/wzfou.com.crt;
ssl_certificate_key /usr/local/nginx/conf/ssl/wzfou.com.key;

Restart Nginx. When users such as XP who do not support ECC certificates access the website, the RSA certificate is displayed.

Other users prefer to use ECC certificates.

If you find that ECC is not displayed preferentially, check whether ssl_prefer_server_ciphers is enabled, and whether ssl_ciphers is configured properly. The following is the configuration used by wzfou.com:

ssl_prefer_server_ciphers on;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5;

In addition, you can choose any one of the following three (for testing only):

ssl_ciphers 'EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5';

ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';

ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK';

6. Enable DNS CAA

The function of DNS CAA is to only allow the CA listed in the record to issue certificates for the domain name (or subdomain name) to prevent someone from forging SSL certificates. At the same time, the CAA record can control the issuance of single domain name SSL certificates and can also control Wildcard certificate. For detailed methods, see: JD Cloud DNS settings CAA.

Problem:Enabling DNS CAA results in an error: Verify error: CAA record for *.wzfou.comprevents issuance. The solution is to add the issuewild record: 0 issuewild "letsencrypt.org" . In addition, two websites are provided to check whether the CAA configuration is correct:

  1. HTTPS://CAA test.co.UK/
  2. HTTPS://New Year's Eve friends.IO/labs/CAA-validator

7. Automatically update SSL certificates regularly

If you want to update manually:

# RSA
$ acme.sh --renew -d wzfou.com –d www.wzfou.com --force

# ECC
acme.sh --renew -d wzfou.com –d www.wzfou.com --force --ecc

Generally, acme.sh has automatically added scheduled tasks to regularly update the Let’s Encrypt certificate. If you find that the certificate is not updated regularly, check whether your Cron task is correct. You can also try to force an update:

"/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" --force

8. Check SSL certificate configuration

Commonly used testing websites include:

  1. HTTPS://wuwuwu.SSL labs.com/SSL test/analyze.HTML
  2. https://nokill.com/

It is highly recommended to use ssllabs.com. The test results are still very accurate, as follows:

9. Comprehensive

Based on the above optimization strategies, the specific optimization of Nginx configuration file is as follows:

server {

listen 443 ssl http2;
#使用HTTP/2,需要Nginx1.9.7以上版本

add_header Strict-Transport-Security "max-age=6307200; includeSubdomains; preload";
#开启HSTS,并设置有效期为“6307200秒”(6个月),包括子域名(根据情况可删掉),预加载到浏览器缓存(根据情况可删掉)

add_header X-Frame-Options DENY;
#禁止被嵌入框架

add_header X-Content-Type-Options nosniff;
#防止在IE9、Chrome和Safari中的MIME类型混淆攻击

ssl_certificate /usr/local/nginx/conf/vhost/sslkey/www.linpx.com.crt;
ssl_certificate_key /usr/local/nginx/conf/vhost/sslkey/www.linpx.com.key;
#SSL证书文件位置

ssl_trusted_certificate /usr/local/nginx/conf/vhost/sslkey/chaine.pem;
#OCSP Stapling的证书位置

ssl_dhparam /usr/local/nginx/conf/vhost/sslkey/dhparam.pem;
#DH-Key交换密钥文件位置

#SSL优化配置

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#只允许TLS协议

ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
#加密套件,这里用了CloudFlare's Internet facing SSL cipher configuration

ssl_prefer_server_ciphers on;
#由服务器协商最佳的加密算法

ssl_session_cache builtin:1000 shared:SSL:10m;
#Session Cache,将Session缓存到服务器,这可能会占用更多的服务器资源

ssl_session_tickets on;
#开启浏览器的Session Ticket缓存

ssl_session_timeout 10m; 
#SSL session过期时间

ssl_stapling on; 
#OCSP Stapling开启,OCSP是用于在线查询证书吊销情况的服务,使用OCSP Stapling能将证书有效状态的信息缓存到服务器,提高TLS握手速度

ssl_stapling_verify on;
#OCSP Stapling验证开启

resolver 8.8.8.8 8.8.4.4 valid=300s;
#用于查询OCSP服务器的DNS

resolver_timeout 5s;
#查询域名超时时间

···

}

During actual use, it is found that individual "optimizations" must be determined according to one's own needs. The following is the Nginx configuration currently used by wzfou.com, for reference only:

listen 80; 
listen 443 ssl http2;
#ECC
ssl_certificate /root/.acme.sh/wzfou.com_ecc/fullchain.cer;
ssl_certificate_key /root/.acme.sh/wzfou.com_ecc/wzfou.com.key;  
#RSA 
ssl_certificate /usr/local/nginx/conf/ssl/wzfou.com.crt;
ssl_certificate_key /usr/local/nginx/conf/ssl/wzfou.com.key; 
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_timeout 10m;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_buffer_size 1400;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
ssl_stapling on; 
ssl_stapling_verify on;

PS: Updated on August 5, 2018. Thanks to xiaoz for the reminder. Here is a website for generating SSL configuration online, from Mozilla, which is very referenceable:

  1. https://Mozilla.GitHub.IO/server-dead-torres/ratings-config-generator/

Leave a Reply