让自己的网站使用免费的https协议——Let’s Encrypt

Let’s Encrypt 简介

Let’s Encrypt 是国外一个公共的免费SSL项目,由 Linux 基金会托管,它的来头不小,由 Mozilla、思科、Akamai、IdenTrust 和 EFF 等组织发起,目的就是向网站自动签发和管理免费证书,以便加速互联网由 HTTP 过渡到 HTTPS,目前 Facebook 等大公司开始加入赞助行列。

Let’s Encrypt 已经得了 IdenTrust 的交叉签名,这意味着其证书现在已经可以被 Mozilla、Google、Microsoft 和 Apple 等主流的浏览器所信任,你只需要在 Web 服务器证书链中配置交叉签名,浏览器客户端会自动处理好其它的一切,Let’s Encrypt 安装简单,使用非常方便。

Certbot 简介

Certbot 为 Let’s Encrypt 项目发布了一个官方的客户端 Certbot ,利用它可以完全自动化的获取、部署和更新安全证书,并且 Certbot 是支持所有 Unix 内核的操作系统。

安装certbot

$ yum install certbot # centos
$ # apt install certbot # ubuntu

Certbot 的两种使用方式

  1. webroot 方式: certbot 会利用既有的 web server,在其 web root 目录下创建隐藏文件,Let’s Encrypt 服务端会通过域名来访问这些隐藏文件,以确认你的确拥有对应域名的控制权。
  2. standalone 方式: Certbot 会自己运行一个 web server 来进行验证。如果我们自己的服务器上已经有 web server 正在运行 (比如 Nginx 或 Apache ),用 standalone 方式的话需要先关掉它,以免冲突。(个人比较喜欢第二种)

获取证书

webroot模式

使用这种模式会在 web root 中创建 .well-known 文件夹,这个文件夹里面包含了一些验证文件,Certbot 会通过访问 example.com/.well-known/acme-challenge 来验证你的域名是否绑定的这个服务器,所以需要编辑 nginx 配置文件确保可以访问刚刚创建的 .well-known 文件夹及里边存放的验证文件,以便在生成证书时进行验证:

# 安装语法如下
$ certbot certonly --email admin@example.com --webroot -w /var/www/example -d example.com -d www.example.com

错误解决

# 我在的时候有报错信息
ImportError: No module named 'requests.packages.urllib3‘

# 解决办法
pip install --upgrade pip

pip install --upgrade --force-reinstall 'requests==2.6.0' urllib3

nginx配置文件

# nginx配置文件
server
    {   
        listen 80; 
        #listen [::]:80;
        server_name certbot.***.cn ;
        index index.html index.htm index.php default.html default.htm default.php;
        root  /home/wwwroot/certbot.***.cn;

        #error_page   404   /404.html;

        # Deny access to PHP files in specific directory
        #location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; }

        include proxy-pass-php.conf;

        location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
        {   
            expires      30d;
        }   

        location ~ .*\.(js|css)?$
        {   
            expires      12h;
        }   

        location ~ /.well-known {
            allow all;
        }   

        location ~ /\. 
        {   
            deny all;
        }   

        access_log  /home/wwwlogs/certbot.***.cn.log;
    }   

正式安装

# 正式安装
# certbot certonly --email 423432@qe.com --webroot -w /home/wwwroot/certbot -d certbot.***.cn

Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/certbot.***.cn/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/certbot.***.cn/privkey.pem
   Your cert will expire on 2020-02-10. 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"

开启https,在原配置文件加上以下内容:

server
    {   
        listen 443 ssl http2;
        #listen [::]:443 ssl http2;
        server_name certbot.***.cn ;
        index index.html index.htm index.php default.html default.htm default.php;
        root  /home/wwwroot/certbot.***.cn;

        ssl_certificate /etc/letsencrypt/live/certbot.***.cn/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/certbot.***.cn/privkey.pem;
        ssl_session_timeout 5m; 

        #error_page   404   /404.html;

        # Deny access to PHP files in specific directory
        #location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; }

        include proxy-pass-php.conf;

        location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
        {   
            expires      30d;
        }   

        location ~ .*\.(js|css)?$
        {   
            expires      12h;
        }   

        location ~ /.well-known {
            allow all;
        }   

        location ~ /\. 
        {   
            deny all;
        }   

        access_log  /home/wwwlogs/certbot.***.cn.log;
    }

standalone模式

但是有些时候我们的一些服务并没有根目录,例如一些微服务,这时候使用 webroot 模式就走不通了。这时可以使用模式 standalone 模式,这种模式不需要指定网站根目录,他会自动启用服务器的443端口,来验证域名的归属。我们有其他服务(例如nginx)占用了443端口,就必须先停止这些服务,在证书生成完毕后,再启用。

# 安装语法
certbot certonly --email admin@example.com --standalone -d example.com -d www.example.com

正式安装

[root@bajiecxg ~]# /etc/init.d/nginx stop
Stoping nginx...  done

# certbot certonly --email admin@example.com --standalone -d blog.***.cn
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for blog.***.cn
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/blog.***.cn/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/blog.***.cn/privkey.pem
   Your cert will expire on 2020-02-10. 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

nginx配置文件

server
     {
        listen          80;
        server_name blog.***.cn;
        return 301 https://$server_name$request_uri;
    }

server
    {   
        listen 443 ssl http2;
        #listen [::]:443 ssl http2;
        server_name blog.***.cn ;
        index index.html index.htm index.php default.html default.htm default.php;
        root  /home/wwwroot/blog.***.cn;

        ssl_certificate /etc/letsencrypt/live/blog.***.cn/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/blog.***.cn/privkey.pem;
        ssl_session_timeout 5m; 

        #error_page   404   /404.html;

        # Deny access to PHP files in specific directory
        #location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; }

        include proxy-pass-php.conf;

        location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
        {   
            expires      30d;
        }   

        location ~ .*\.(js|css)?$
        {   
            expires      12h;
        }   

        location ~ /.well-known {
            allow all;
        }   

        location ~ /\. 
        {   
            deny all;
        }   

        access_log  /home/wwwlogs/blog.***.cn.log;
    }  

重启nginx,查看是否成功。

自动续期

Let’s Encrypt 提供的证书只有90天的有效期,所以我们要在在证书到期之前重新获取这些证书,Certbot 提供了一个方便的命令 certbot renew,我们可以先使用 --dry-run 测试是否可用:

$ certbot renew --dry-run

linux 系统上有 cron 可以来搞定这件事情,使用一下命令新建任务:

$ crontab -e

写入一下任务内容。这段内容的意思就是 每隔 两个月的 凌晨 2:15 执行 更新操作

15 2 * */2 * certbot renew --quiet --renew-hook "/etc/init.d/nginx restart"
参数 表述
–quiet 执行时屏蔽错误以外的所有输出,也可以使用 -q
–pre-hook 执行更新操作之前要做的事情
–pre-hook 执行更新操作之前要做的事情
–post-hook 执行更新操作完成后要做的事情

取消证书

可以使用一下命令取消刚刚生成的密匙,也就是以上的反操作:

$ certbot revoke --cert-path /etc/letsencrypt/live/example.com/cert.pem
$ certbot delete --cert-name example.com