Lets Encrypt = Free 100% HTTPS

Lets Encrypt = Free 100% HTTPS

Let's Encryptis a certificate authority that provides free X.509 certificates for Transport Layer Security (TLS) encryption via an automated process designed to eliminate the hitherto complex process of manual creation, validation, signing, installation, and renewal of certificates for secure websites.

Let’s Encrypt is a free, automated, and open certificate authority brought to you by the non-profit Internet Security Research Group (ISRG).

1 million March 8, 2016,Milestone: 100 Million Certificates Issued, Jun 28, 2017. ⬆️

Now Wildcard Certificates has supported on March 13, 2018. But Let’s Encrypt will generate an ECDSA root and intermediates which can be used to sign end-entity certificates by Q3 2018. See Also Upcoming Features

ACME: Automatic Certificate Management Environment, ACME v2 API Enabled: March 13, 2018.

Detailed Working Principle can found here How It Works. Core Work is Domain Validation:

About Domain Validation:

Let’s Encrypt identifies the server administrator by public key. The first time the agent software interacts with Let’s Encrypt, it generates a new key pair and proves to the Let’s Encrypt CA that the server controls one or more domains. This is similar to the traditional CA process of creating an account and adding domains to that account.

To kick off the process, the agent asks the Let’s Encrypt CA what it needs to do in order to prove that it controls example.com. The Let’s Encrypt CA will look at the domain name being requested and issue one or more sets of challenges. These are different ways that the agent can prove control of the domain. For example, the CA might give the agent a choice of either:

  • Provisioning a DNS record under example.com, or

  • Provisioning an HTTP resource under a well-known URI on https://example.com/

1. Install Client Tool Certbot

Client Tool Certbot written By Python, is packaged in EPEL (Extra Packages for Enterprise Linux). To use Certbot, you must first enable the EPEL repository. On RHEL or Oracle Linux, you must also enable the optional channel.

$ sudo yum -y install yum-utils
$ yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional

$ sudo yum install certbot-nginx

1.1 Signal Site Certificate

# Running this command will get a certificate for you and have Certbot edit your Nginx configuration automatically to serve it.
$ sudo certbot --nginx

# If you're feeling more conservative and would like to make the changes to your Nginx configuration by hand
$ sudo certbot --nginx certonly

The detailed procedure is as follows:

[root@xxx ~]# certbot --nginx
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): dwh0403@163.com
Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org

-------------------------------------------------------------------------------
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v01.api.letsencrypt.org/directory
-------------------------------------------------------------------------------
(A)gree/(C)ancel: A

-------------------------------------------------------------------------------
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about EFF and
our work to encrypt the web, protect its users and defend digital rights.
-------------------------------------------------------------------------------
(Y)es/(N)o: Y
Starting new HTTPS connection (1): supporters.eff.org

Which names would you like to activate HTTPS for?
-------------------------------------------------------------------------------
1: www.do1618.com
-------------------------------------------------------------------------------
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 1
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for www.do1618.com
Waiting for verification...
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/nginx/global/wordpress.conf

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
-------------------------------------------------------------------------------
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
-------------------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 1

-------------------------------------------------------------------------------
Congratulations! You have successfully enabled https://www.do1618.com

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=www.do1618.com
-------------------------------------------------------------------------------

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/www.do1618.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/www.do1618.com/privkey.pem
   Your cert will expire on 2018-06-17. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

1.2 Managing certificates

$ certbot certificates
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Found the following certs:
  Certificate Name: www.do1618.com
    Domains: www.do1618.com
    Expiry Date: 2018-06-17 02:19:21+00:00 (VALID: 89 days)
    Certificate Path: /etc/letsencrypt/live/www.do1618.com/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/www.do1618.com/privkey.pem
  Certificate Name: do1618.com
    Domains: *.do1618.com do1618.com
    Expiry Date: 2018-06-17 04:26:47+00:00 (VALID: 89 days)
    Certificate Path: /etc/letsencrypt/live/do1618.com/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/do1618.com/privkey.pem
-------------------------------------------------------------------------------

$ certbot delete --cert-name example.com

2. Automating Renewal

Let’s Encrypt CA issues short-lived certificates (90 days). Make sure you renew the certificates at least once in 3 months.

Certbot can be configured to renew your certificates automatically before they expire.Since Let's Encrypt certificates last for 90 days, it's highly advisable to take advantage of this feature. You can test automatic renewal for your certificates by running this command:

sudo certbot renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/www.do1618.com.conf
-------------------------------------------------------------------------------
Cert not due for renewal, but simulating renewal for dry run
Plugins selected: Authenticator nginx, Installer nginx
Starting new HTTPS connection (1): acme-staging.api.letsencrypt.org
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for www.do1618.com
Waiting for verification...
Cleaning up challenges

-------------------------------------------------------------------------------
new certificate deployed with reload of nginx server; fullchain is
/etc/letsencrypt/live/www.do1618.com/fullchain.pem
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/www.do1618.com/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
-------------------------------------------------------------------------------

IMPORTANT NOTES:
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.

If that appears to be working correctly, you can arrange for automatic renewal by adding a cron job or systemd timer which runs the following:

An example cron job might look like this, which will run at noon and midnight every day:

0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew 

##3. Advanced: Wildcard Certificat

3.1 Built-in Supported DNS Manager

Wildcard certificate support is live.

Wildcard Certificates Coming January 2018 Update, March 13, 2018,

Supported Certbot's DNS plugins.

Wildcard certificates will be offered free of charge via our upcoming ACME v2 API endpoint. We will initially only support base domain validation via DNS for wildcard certificates, but may explore additional validation options over time.

If you want to obtain a wildcard certificate using Let's Encrypt's new ACMEv2 server, you'll also need to use one of Certbot's DNS plugins. To do this, make sure the plugin for your DNS provider is installed using the instructions above and run a command like the following:

$ sudo certbot -a dns-plugin -i nginx -d "*.example.com" -d example.com --server https://acme-v02.api.letsencrypt.org/directory

# Update certbot-dns-cloudxns setting infos and run the command like the following:
# sudo certbot -a certbot-dns-cloudxns -i nginx -d "*.example.com" -d example.com --server https://acme-v02.api.letsencrypt.org/directory

Certbot's DNS plugins are also available for your system which can be used to automate obtaining a wildcard certificate from Let's Encrypt's ACMEv2 server. To use one of these plugins, you must have configured DNS for the domain you want to obtain a certificate for with a DNS provider that Certbot has a plugin for.

3.2 Manually For Aliyun DNS (Just For Study)

$ certbot certonly -d "*.do1618.com" -d do1618.com --server https://acme-v02.api.letsencrypt.org/directory --manual --preferred-challenges dns
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for do1618.com
dns-01 challenge for do1618.com

-------------------------------------------------------------------------------
NOTE: The IP of this machine will be publicly logged as having requested this
certificate. If you're running certbot in manual mode on a machine that is not
your server, please ensure you're okay with that.

Are you OK with your IP being logged?
-------------------------------------------------------------------------------
(Y)es/(N)o: Y

-------------------------------------------------------------------------------
Please deploy a DNS TXT record under the name
_acme-challenge.do1618.com with the following value:

t-DcEVPfmn71-gmQ4st_Vwed-aF6uyz_1wa2SGCh-ZA    See ①

Before continuing, verify the record is deployed.
-------------------------------------------------------------------------------
Press Enter to Continue

-------------------------------------------------------------------------------
Please deploy a DNS TXT record under the name
_acme-challenge.do1618.com with the following value:

WWO3AYhzqWwp71oFtNAD0Yio6KxuGaCBbXPdnsuCw1k    See ②

Before continuing, verify the record is deployed.
-------------------------------------------------------------------------------
Press Enter to Continue
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/do1618.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/do1618.com/privkey.pem
   Your cert will expire on 2018-06-17. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Certbot's DNS plugins don't include Aliyun implement, so we need do the work of challenges manually. However, there will be a problem when renewing the certificates. Not recommended for production environments.

① Set Value of txt _acme-challenge.do1618.com to "t-DcEVPfmn71-gmQ4st_Vwed-aF6uyz_1wa2SGCh-ZA"

Open New Terminal to confirm:

$ dig -t txt _acme-challenge.do1618.com

....

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;_acme-challenge.do1618.com.    IN  TXT

;; ANSWER SECTION:
_acme-challenge.do1618.com. 600 IN  TXT "t-DcEVPfmn71-gmQ4st_Vwed-aF6uyz_1wa2SGCh-ZA"

....

② Change Value of txt _acme-challenge.do1618.com to "WWO3AYhzqWwp71oFtNAD0Yio6KxuGaCBbXPdnsuCw1k"

$ dig -t txt _acme-challenge.do1618.com

; <<>> DiG 9.9.4-RedHat-9.9.4-51.el7_4.2 <<>> -t txt _acme-challenge.do1618.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18042
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 17

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;_acme-challenge.do1618.com.    IN  TXT

;; ANSWER SECTION:
_acme-challenge.do1618.com. 600 IN  TXT "WWO3AYhzqWwp71oFtNAD0Yio6KxuGaCBbXPdnsuCw1k"

;; AUTHORITY SECTION:
do1618.com.     131555  IN  NS  dns9.hichina.com.
do1618.com.     131555  IN  NS  dns10.hichina.com.

;; ADDITIONAL SECTION:
dns9.hichina.com.   1119    IN  A   106.11.141.115
.....

;; Query time: 6 msec
;; SERVER: 10.202.72.118#53(10.202.72.118)
;; WHEN: Mon Mar 19 13:24:47 CST 2018
;; MSG SIZE  rcvd: 414

3.3 Acme.sh Helper For Aliyun DNS

Use Aliyun DNS

  1. Install acme.sh

    Acme.sh Installs Crontab Task to renew Certs which is almost expired automaticly。

    # install scripts
    $ curl  https://get.acme.sh | sh
    $ souce ~/.bash_profile
    
  2. Generate AccessKey and Token. Install the seceret to dnsapi/dns_ali.sh.

  3. Apply for wildcard cert

    $ acme.sh  --issue -d do1618.com  -d '*.do1618.com'  --dns dns_ali
    [Mon Mar 19 15:33:06 CST 2018] Registering account
    [Mon Mar 19 15:33:08 CST 2018] Registered
    [Mon Mar 19 15:33:08 CST 2018] ACCOUNT_THUMBPRINT='Yu5XZCWdGhzbskMps8D_HtUhTat6oBT6WonDCFQlnOo'
    [Mon Mar 19 15:33:08 CST 2018] Multi domain='DNS:do1618.com,DNS:*.do1618.com'
    [Mon Mar 19 15:33:08 CST 2018] Getting domain auth token for each domain
    [Mon Mar 19 15:33:10 CST 2018] Getting webroot for domain='do1618.com'
    [Mon Mar 19 15:33:10 CST 2018] Getting webroot for domain='*.do1618.com'
    [Mon Mar 19 15:33:10 CST 2018] Found domain api file: /root/.acme.sh/dnsapi/dns_ali.sh
    [Mon Mar 19 15:33:12 CST 2018] Found domain api file: /root/.acme.sh/dnsapi/dns_ali.sh
    [Mon Mar 19 15:33:14 CST 2018] Sleep 120 seconds for the txt records to take effect
    [Mon Mar 19 15:35:16 CST 2018] Verifying:do1618.com
    [Mon Mar 19 15:35:19 CST 2018] Pending
    [Mon Mar 19 15:35:21 CST 2018] Success
    [Mon Mar 19 15:35:21 CST 2018] Verifying:*.do1618.com
    [Mon Mar 19 15:35:25 CST 2018] Pending
    [Mon Mar 19 15:35:27 CST 2018] Success
    [Mon Mar 19 15:35:27 CST 2018] Removing DNS records.
    [Mon Mar 19 15:35:33 CST 2018] Verify finished, start to sign.
    [Mon Mar 19 15:35:35 CST 2018] Cert success.
    -----BEGIN CERTIFICATE-----
    .....
    -----END CERTIFICATE-----
    [Mon Mar 19 15:35:35 CST 2018] Your cert is in  /root/.acme.sh/do1618.com/do1618.com.cer
    [Mon Mar 19 15:35:35 CST 2018] Your cert key is in  /root/.acme.sh/do1618.com/do1618.com.key
    [Mon Mar 19 15:35:35 CST 2018] The intermediate CA cert is in  /root/.acme.sh/do1618.com/ca.cer
    [Mon Mar 19 15:35:35 CST 2018] And the full chain certs is there:  /root/.acme.sh/do1618.com/fullchain.cer
    

  4. Install the cert to Nginx

    After the cert is generated, you probably want to install/copy the cert to your Apache/Nginx or other servers. You MUSTuse this command to copy the certs to the target files, DO NOT use the certs files in ~/.acme.sh/ folder, they are for internal use only, the folder structure may change in the future.

    $ acme.sh --install-cert -d do1618.com \
    --key-file       /xxx/do1618.com.key  \
    --fullchain-file /xxxx/do1618.com.cer \
    --reloadcmd     "service nginx force-reload"
    

    Sample Setting we add to Nginx manually.

    server {
       listen 443 ssl http2 default deferred;
       server_name *.do1618.com;
    
       #ssl on;
       ssl_certificate /xxxx/fullchain.cer;
       ssl_certificate_key /xxxx/do1618.com.key;
       // ...
    }
    

4. Serving Wildcard to Domains

# configure multi-ssl domains
#  server {
#    listen 443 ssl http2;
#    server_name blog.xxxx.com;
#   }
#
#      server {
#    listen 443 ssl http2;
#    server_name hexo.xxxx.com;
#   }
$ nginx -t
nginx: [emerg] duplicate listen options for 0.0.0.0:443 in /etc/nginx/global/wordpress.conf:94
nginx: configuration file /etc/nginx/nginx.conf test failed

A more generic solution for running several HTTPS servers on a single IP address is TLS Server Name Indication extension (SNI, RFC 6066), which allows a browser to pass a requested server name during the SSL handshake and, therefore, the server will know which certificate it should use for the connection. SNI is currently supported by most modern browsers, though may not be used by some old or special clients.

In order to use SNI in nginx, it must be supported in both the OpenSSL library with which the nginx binary has been built as well as the library to which it is being dynamically linked at run time. OpenSSL supports SNI since 0.9.8f version if it was built with config option “--enable-tlsext”. Since OpenSSL 0.9.8j this option is enabled by default. If nginx was built with SNI support, then nginx will show this when run with the “-V” switch:

bash
$ nginx -V
...
TLS SNI support enabled
...

$ wget http://nginx.org/download/nginx-1.13.10.tar.gz
$ tar xzvf nginx-1.13.10.tar.gz
$ cd nginx-1.13.10/
$ ./configure --prefix=/usr --with-http_ssl_module  --with-http_v2_module --with-openssl-opt="enable-tlsext"
$ make
$./objs/nginx -V
nginx version: nginx/1.13.10
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC)
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr --with-http_ssl_module --with-openssl-opt=enable-tlsext
$ systemctl stop nginx
$ mv /usr/sbin/nginx /usr/sbin/nginx.bk
$ make install
$ systemctl start nginx

Notice:

The default config of Nginx installed by Centos7.0 is "/etc/nginx/nginx.conf". However, Nginx we compiled uses the config "/usr/nginx/nginx.conf". We can customize file of Nginx service "/usr/lib/systemd/system/nginx.service" to correct this behavior.

ExecStartPre=/usr/sbin/nginx -t -c /etc/nginx/nginx.conf
ExecStart=/usr/sbin/nginx  -c /etc/nginx/nginx.conf

Rerun the cmd again with the same tls setting, no warnings should occur.

$ nginx -t -c /etc/nginx/nginx.conf
nginx: the configuration file /usr/conf/nginx.conf syntax is ok
nginx: configuration file /usr/conf/nginx.conf test is successful

5. Issues

5.1 X509 object has no attribute '_x509'

5.2 The manual plugin is not working

[root@iZ23xxwlyliZ ~]# certbot renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/www.do1618.com.conf
-------------------------------------------------------------------------------
Cert not due for renewal, but simulating renewal for dry run
Plugins selected: Authenticator nginx, Installer nginx
Starting new HTTPS connection (1): acme-staging.api.letsencrypt.org
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for www.do1618.com
Waiting for verification...
Cleaning up challenges
▽
▽
        ## This should be in your http block and if it is, it's not needed here.
-------------------------------------------------------------------------------
new certificate deployed with reload of nginx server; fullchain is
/etc/letsencrypt/live/www.do1618.com/fullchain.pem
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/do1618.com.conf
-------------------------------------------------------------------------------
Cert not due for renewal, but simulating renewal for dry run
Could not choose appropriate plugin: The manual plugin is not working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.',)
Attempting to renew cert (do1618.com) from /etc/letsencrypt/renewal/do1618.com.conf produced an unexpected error: The manual plugin is not working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.',). Skipping.
The following certs could not be renewed:
  /etc/letsencrypt/live/do1618.com/fullchain.pem (failure)

-------------------------------------------------------------------------------
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

The following certs were successfully renewed:
  /etc/letsencrypt/live/www.do1618.com/fullchain.pem (success)

The following certs could not be renewed:
  /etc/letsencrypt/live/do1618.com/fullchain.pem (failure)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
-------------------------------------------------------------------------------

Three Ways to go:

  1. We need to choose build-in supported DNS manager, For example transfer the Manager of DNS from Aliyun to CloudXNS.

  2. Or Find another Tools supported ACME v2 protocal and our DNS manager such as Acme.sh, which is a pure Unix shell script implementing ACME client protocol.

  3. Or We implement a DNS plugin ourselves.

6. Resource

  1. Let's Encrypt on GitHub
  2. Wildcard Certificates Coming January 2018
  3. Let's Encrypt 宣布支持通配符证书,所有子域名可轻松开启 HTTPS
  4. A pure Unix shell script implementing ACME client protocol Recommend for aliyun DNS
  5. 通过阿里云 DNS 为 Let's Encrypt 签发 SSL 证书提供验证的脚本工具
  6. A pure Unix shell script implementing ACME client protocol Github
  7. 利用acme.sh申请 Letsencrypt 免费 SSL 证书
  8. Let's Encrypt,免费好用的 HTTPS 证书
  9. 阿里云OSS绑定letsencrypt证书
  10. Let's Encrypt 终于支持通配符证书了

发表评论

电子邮件地址不会被公开。 必填项已用*标注