Let's Encrypt

最後更新: 2019-11-07

 

目錄

 

介紹

Let’s Encrypt CA issues short lived certificates (90 days).

Make sure you renew the certificates at least once in 3 months.

Homepage: https://letsencrypt.org/

Source: https://github.com/letsencrypt/letsencrypt

 

Automatic Certificate Management Environment (ACME)

The protocol, based on passing JSON-formatted messages over HTTPS ( RFC 8555 )

automatically obtain a browser-trusted certificate, without any human intervention

This is accomplished by running a certificate management agent on the web server.

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.

# Challenges & validation:

A) Agent 建立用來與 Let’s Encrypt CA 溝通的 key pair

1. The agent asks the Let’s Encrypt CA what it needs to do in order to prove that it controls

2. The Let’s Encrypt CA also provides a nonce that the agent must sign with its private key pair

    (to prove that it controls the key pair)

3. Agent creates a file on a specified path on the site.

4. Agent notifies the CA that it’s ready to complete validation

    (Let’s Encrypt call the URL)

5. If the signature over the nonce is valid, and the challenges check out,

    then the agent identified by the public key is authorized to do certificate management for example.com.

B) requesting, renewing, and revoking certificates

Agent send certificate management messages and sign them with the authorized key pair

(asks the Let’s Encrypt CA to issue a certificate for example.com with a specified public key.)

The agent signs the whole CSR with the authorized key for example.com

FAQ

What IP addresses does Let's Encrypt use to validate my web server?

We don't publish a list of IP addresses we use to validate,

because they may change at any time. In the future we may validate from multiple IP addresses at once.

 


安裝

 

Let's Encrypt 是透過 ACME 去認證 Website

certbot 是並中一個 ACME Client

https://certbot.eff.org/

Install on Centos7

  1. yum install python36 augeas-libs
  2. python3 -m venv /opt/certbot/
  3. /opt/certbot/bin/pip install --upgrade pip
  4. /opt/certbot/bin/pip install certbot
  5. ln -s /opt/certbot/bin/certbot /usr/bin/certbot

Check Version

certbot --version

certbot 1.20.0

Help

certbot --help

 


Key 的位置

 

All generated keys and issued certificates can be found in /etc/letsencrypt/live/$domain/

i.e.

ll /etc/letsencrypt/live/datahunter.org/

lrwxrwxrwx 1 root root   38 May 14 22:01 cert.pem -> ../../archive/datahunter.org/cert5.pem
lrwxrwxrwx 1 root root   39 May 14 22:01 chain.pem -> ../../archive/datahunter.org/chain5.pem
lrwxrwxrwx 1 root root   43 May 14 22:01 fullchain.pem -> ../../archive/datahunter.org/fullchain5.pem
lrwxrwxrwx 1 root root   41 May 14 22:01 privkey.pem -> ../../archive/datahunter.org/privkey5.pem

* /etc/letsencrypt/live symlinks to the latest versions

* /etc/letsencrypt/archive and /etc/letsencrypt/keys contain all previous keys and certificates,

 


letsencrypt-auto(舊版)

 

Syntax:

letsencrypt-auto [SUBCOMMAND] [options] [-d domain] [-d domain] ...

SUBCOMMAND:

  •  run (default)              # Obtain & install
  •  certonly                     # Obtain cert, but do not install it
  •  install
  •  revoke
  •  rollback
  •  config_changes

# Sign a single domain

letsencrypt-auto certonly --test-cert --dry-run --standalone  \
                        -d datahunter.org -d www.datahunter.org

* --standalone      # runs its own simple webserver to prove you control a domain)

* --certonly          # 不用 automatic installation

* --dry-run          # Test "renew" or "certonly" without saving any certificates to disk

* --test-cert          # This will get certificates from staging server. (They won’t be valid in browsers)

建立 multiple domains cert.

certbot-auto -d www.datahunter.org -d datahunter.org

# Renewing

letsencrypt renew --cert-path example-cert.pem

i.e.

service nginx stop       # 必須要放返 port 80 出黍先 renew 到

letsencrypt-auto renew --standalone --cert-path /etc/letsencrypt/live/datahunter.org/cert.pem

Auto renew script

/root/scripts/letsencrypt/cron_renew.sh

#!/bin/bash
# for nginx web server

LOGFILE="/var/log/letsencrypt/renew.log"
certbot="/usr/sbin/certbot-auto"

$certbot renew > $LOGFILE 2>&1

crontab -e

1 1 1 */2 *       /root/scripts/letsencrypt/cron_renew.sh > /dev/null

Notes

由於 renew 時會使用 /etc/letsencrypt/renewal/datahunter.org.conf 內的 settings, 所以不用加

--pre-hook "service nginx stop" \
--post-hook "service nginx start" \
--standalone --preferred-challenges http \
--cert-path $CERT \

 

# For testing

--force-renewal            # that will force a renewal even if your cert isn’t close to expiry.

--dry-run                     # will fetch a certificate from staging server.

P.S.

它會根據 /etc/letsencrypt/renewal/datahunter.org.conf 去 renew

# renew_before_expiry = 30 days
cert = /etc/letsencrypt/live/datahunter.org/cert.pem
privkey = /etc/letsencrypt/live/datahunter.org/privkey.pem
chain = /etc/letsencrypt/live/datahunter.org/chain.pem
fullchain = /etc/letsencrypt/live/datahunter.org/fullchain.pem
version = 0.8.1

# Options and defaults used in the renewal process
[renewalparams]
installer = None
authenticator = standalone
account = ???

# Revoking a Certificate

# menu of all your managed certificates

letsencrypt revoke

# You may also revoke a particular certificate

letsencrypt revoke --cert-path example-cert.pem

# revoke all certificates with a particular key.

letsencrypt revoke --key-path example-key.pem

 


cli.ini

 

/etc/letsencrypt/cli.ini

letsencrypt-auto --config cli.ini

# Use a 4096 bit RSA key instead of 2048

rsa-key-size = 4096

# Uncomment and update to register with the specified e-mail address

# email = [email protected]

log file

/var/log/letsencrypt/letsencrypt.log

 


nginx ssl configure

 

server {
        listen                     443 ssl http2;
        ssi                        on;
        ssl_certificate            /etc/letsencrypt/live/datahunter.org/fullchain.pem;
        ssl_certificate_key        /etc/letsencrypt/live/datahunter.org/privkey.pem;
        ssl_protocols              TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers  on;
        ssl_session_cache          shared:SSL:10m;
        ssl_session_timeout        15m;
        ...
}

 


Certbot

 

新版由 letsencrypt command 改成了 certbot command

Help

certbot-auto --help

certbot-auto --help all

Plugins Type (一共有兩類)

certonly - obtain a cert

install - install a cert (modify your webserver’s configuration)

Usage: renew

renew

attempts to renew any previously-obtained certificates that expire in less than 30 days.

它會 read /etc/letsencrypt/renewal/*.conf 內的設定再去 renew domain

--cert-path CERT_PATH                     # Path to where cert is saved (with auth --csr), installed from, or revoked.
(default: None)

--standalone                                    # To obtain a cert using a “standalone” webserver

--preferred-challenges http/tls-sni     # Port 80 / 443

--force-renewal                        # msg: "The following certs are not due for renewal yet:"

                                              # If a certificate already exists for the requested domains,

                                              # renew it now, regardless of whether it is near expiry.

i.e.

certbot-auto renew

hook

The renew command includes hooks for running commands or scripts before or after a certificate is renewed.

certbot renew --pre-hook "service nginx stop" --post-hook "service nginx start"

--pre-hook

only be called if a certificate is actually to be obtained/renewed.

--post-hook

to restart any servers that were stopped by --pre-hook.

  * the certonly command attempts to renew that specific(-d) certificate.

  * certbot renew exit status will only be 1 if a renewal attempt failed.

Checking

# view a list of the certificates Certbot knows

certbot-auto certificates

Found the following certs:
  Certificate Name: datahunter.org
    Domains: datahunter.org mail.datahunter.org
    Expiry Date: 2017-07-02 04:21:00+00:00 (VALID: 87 days)
    Certificate Path: /etc/letsencrypt/live/datahunter.org/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/datahunter.org/privkey.pem

Toubleshoot

T1: “Error: couldn’t get currently installed version for letsencrypt”

S1: mv /root/.local/share /root/.local/share.bak

Scripts

create cert (certonly)

create-cert.sh

#!/bin/sh

certbot="/usr/sbin/certbot-auto"

$certbot certonly --pre-hook "service nginx stop" \
                --post-hook "service nginx start" \
                --standalone --preferred-challenges http \
                -d datahunter.org \
                -d www.datahunter.org

renew by cron job

cron_renew.sh

#!/bin/sh

LOGFILE="/var/log/letsencrypt/renew.log"
certbot="/usr/sbin/certbot-auto"
CERT="/etc/letsencrypt/live/datahunter.org/cert.pem"

$certbot renew --pre-hook "service nginx stop" \
               --post-hook "service nginx start" \
               --standalone --preferred-challenges http \
               --cert-path $CERT > $LOGFILE 2>&1

# cron job

1 1 1 * *       /root/scripts/letsencrypt/cron_renew.sh

P.S.

重新建立 Certificate

Step1: backup 以下 Folder 內的 Folder

  • archive  
  • live  
  • renewal

Verify

certbot-auto certificates

沒有 output 再重新申請

 


certbot example(簡易)

 

# certonly: make the changes to your Apache configuration by hand

# --apache: Apache plugin

# (get a certificate for you and edit your Apache configuration automatically to serve it)

certbot-auto certonly --apache -d datahunter.org

會 renew 以下 file

/etc/letsencrypt/live/datahunter.org/cert.pem
/etc/letsencrypt/live/datahunter.org/chain.pem
/etc/letsencrypt/live/datahunter.org/privkey.pem
/etc/letsencrypt/live/datahunter.org/fullchain.pem

設定 renew cron jobs

# 測試 renew

certbot-auto renew --dry-run

# cron jobs

# Monthly
1 1 1 * * certbot-auto renew &> /dev/null

 


Letsencrypt validate server IP

 

letsencrypt don't publish a list of IP addresses we use to validate, because they may change at any time.

outbound1.letsencrypt.org    66.133.109.36

outbound2.letsencrypt.org    64.78.149.164

 


Wildcard SSL Certificate

 

申請

1. 執行 CLi

certbot-auto certonly --manual \
--preferred-challenges=dns \
-d "datahunter.org" -d "*.datahunter.org"

2. 填資料

然後跟著指示輸入電郵及回答一些問題.

3. 建立 txt record

最後會 Certbot 會顯示一個 TXT Record

i.e.

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

nbjrc1zj8gXXLgmbw-zc-7mD-iRXghlodenJ_dx00bo

Before continuing, verify the record is deployed.

dig -t txt _acme-challenge.datahunter.org

Remark

Only the dns-01 challenge is accepted for wildcard certificates

(webroot and standalone authenticators don't support this method)

 


Windows acme client

 

Tools: win-acme (https://pkisharp.github.io/win-acme/)

功能

  • A very simple text interface to create
  • DNS, HTTP and TLS validation
  • Completely unattended operation from the command line

Package

if you want to download or develop extra plugins,

you should get the pluggable version instead of the trimmed one.

Validation

The validation request is always made to port 80, that cannot be changed.

The ACME server does follow 301/302 redirects.

The client has to make sure that when the ACME server makes a request to

http://sub.example.com/.well-known/acme-challenge/x

the content of the HTTP response will be y with some specific headers set as well.

Config

Apache

Alias /.well-known/ "C:/vhosts/ssl/.well-known/"

<Directory "C:/vhosts/ssl/">
    Options -FollowSymlinks -Includes -ExecCGI
    Order allow,deny
    Allow from all
    DirectoryIndex index.php index.html index.htm
</Directory>

Win-acme.exe

Question

Enter the path we created in step 4. In my case: C:\xampp\htdocs

Note

actual root and not the path to "/.well-known/acme-challenge".

Win-acme is assuming you haven't got this far and will attempt to create these folders if they don't exist.

 

Command line arguments

--renew   # Renew any certificates that are due.

--force    # Force renewal on all scheduled certificates when used together with --renew.

--list       # List all created renewals in unattended mode.

 


Path For Verify(Nginx)

 

.well-known/pki-validation/

location ^~ "/.well-known/pki-validation" {
    alias C:/nginx/root/well-known/pki-validation/;
    default_type "text/plain";
    allow all;
}

 


Manual get Cert

 

# obtain a certificate running certbot on a machine other than your target webserver

certbot-auto certonly --manual --preferred-challenges http -d datahunter.org

 


Verfiy By File(Nginx)

 

Plugin: webroot

Obtains a cert by writing to the webroot directory of an already running webserver.

The webroot plugin works by creating a temporary file for each of your requested domains in

${webroot-path}/.well-known/{acme-challenge}

“web root” = website top-level directory

設定

mkdir /var/www/letsencrypt/.well-known/acme-challenge -p

mkdir /etc/nginx/snippets; cd /etc/nginx/snippets

letsencrypt-acme-challenge.conf

location ^~ /.well-known/acme-challenge/ {
    default_type  "text/plain";
    root          /var/www/letsencrypt;
    allow         all;
}

# Hide /acme-challenge subdirectory and return 404 on all requests.
# It is somewhat more secure than letting Nginx return 403.
# Ending slash is important!
location = /.well-known/acme-challenge/ {
    return 404;
}

nginx.conf

server {
    listen       80;
    
    # Include location directive for Let's Encrypt ACME Challenge
    include snippets/letsencrypt-acme-challenge.conf;
    
    ...
}

nginx -s reload

測試

touch /var/www/letsencrypt/.well-known/acme-challenge/test.txt

curl -I http://URL/.well-known/acme-challenge/test.txt

certbot-auto renew --test-cert --dry-run --webroot -w /var/www/letsencrypt

Renew Certificate without Config

certbot-auto certonly \
  --webroot -w /var/www/letsencrypt

nginx -s reload

 

Creative Commons license icon Creative Commons license icon