# 使用Let's Encrypt实现网站https化

作者:IT王小二

博客:https://itwxe.com (opens new window)

使用 Let's Encrypt 证书和搭配 Nginx 实现网站 https 化。

# 一、SSL证书获取

由于 Let's Encrypy 申请的 SSL 证书只有三个月的有效期,为了实现自动续期,使用 acme.sh (opens new window) 脚本来获取且自动续期。

使用过程中如有问题参考 acme官方文档 (opens new window) ,文档有中文说明,下面记录我自己的操作。

# 1. 下载脚本并安装

下载脚本并安装,将邮箱设置成自己的。

wget -O -  https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh | sh -s -- --install-online -m  itwxe@qq.com

刷新用户变量,任意目录可以使用 acme.sh。

source /root/.bashrc

这里除了安装了脚本,同时还自动配置了个定时任务,这个定时任务每天会检查你的证书是否需要自动续期,可以使用 crontab -l 查看。

# 2. 生成证书

为了自动验证并更新证书,使用 DNS 验证需要往文件添加自己的 DNS 授权码,个人认为不太安全,这里使用了 http 方式验证域名所有权,此处结合了 nginx。

nginx 配置你想要申请域名的路径,我这里统一使用 /itwxe/blogSite/public 来验证,如果还有不知道 nginx 怎么安装的可以查看 Linux(CentOS7)下Nginx安装 (opens new window)

修改 nginx.conf 文件,nginx 配置如下,修改后记得验证 nginx -t 是否正确,nginx -s reload 重启 nginx。

server {
        listen       80;
        server_name  www.itwxe.com img.itwxe.com;

        location / {
            root /itwxe/blogSite/public;
        }
} 

执行命令申请证书。

# www.itwxe.com SSL申请
acme.sh --issue -d www.itwxe.com -w /itwxe/blogSite/public

# img.itwxe.com SSL申请
acme.sh --issue -d img.itwxe.com -w /itwxe/blogSite/public

申请过程非常快的,打印的日志也很简单,成功了就会提示 sucess,有错误也会提示 error。

生成成功之后的文件在 /root/.acme.sh/ 目录下,以域名为文件夹,SSL 证书就在这个目录下。

证书目录

# 二、Nginx配置https

首先把生成的 SSL 证书复制到自己的目录,我是在 nginx 目录下创建了一个 ssl 目录专门用来存放证书。

cp /root/.acme.sh/www.itwxe.com/{fullchain.cer,www.itwxe.com.key} /usr/local/nginx/ssl/www/

cp /root/.acme.sh/img.itwxe.com/{fullchain.cer,img.itwxe.com.key} /usr/local/nginx/ssl/img/

配置 https,这里我把实现 http 重定向 https,同时 itwxe.com 重定向 www.itwxe.com ,贴出自己的部分配置。

    server {
        listen       80;
        server_name *.itwxe.com;
        # 将http请求转变为https
        rewrite ^(.*) https://$host$1 permanent;
        charset utf-8;
    }
    
    server {
        listen 443 ssl;
        server_name itwxe.com;
        ssl_certificate /usr/local/nginx/ssl/www/fullchain.cer;
        ssl_certificate_key /usr/local/nginx/ssl/www/www.itwxe.com.key;
        return 301 https://www.itwxe.com$request_uri;
    }

    server {
        listen 443 ssl;
        server_name www.itwxe.com;
        ssl_certificate /usr/local/nginx/ssl/www/fullchain.cer;
        ssl_certificate_key /usr/local/nginx/ssl/www/www.itwxe.com.key;
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout 30m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers HIGH:!aNULL:!MD5:!EXPORT56:!EXP;
        ssl_prefer_server_ciphers on;
        proxy_connect_timeout 500;
        proxy_send_timeout 500;
        proxy_read_timeout 500;
        client_max_body_size 200m;
        location / {
            root /itwxe/blogSite/public;
            index index.html;
        }
    }

    server {
        listen 443 ssl;
        server_name img.itwxe.com;
        ssl_certificate /usr/local/nginx/ssl/img/fullchain.cer;
        ssl_certificate_key /usr/local/nginx/ssl/img/img.itwxe.com.key;
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout 30m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers HIGH:!aNULL:!MD5:!EXPORT56:!EXP;
        ssl_prefer_server_ciphers on;
        proxy_connect_timeout 500;
        proxy_send_timeout 500;
        proxy_read_timeout 500;
        client_max_body_size 200m;
        location /blog {
            root /itwxe/dockerData/minio/data;
            autoindex on;
        }
    }

验证配置和重启 nginx。

nginx -t

nginx -s reload

验证之后可以看到网站小绿标已经加上了,证书查看也可以看到确实是三个月有效期。

ssl

# 三、自动续期

前面说了正常情况下脚本配置了定时任务每天都会检查证书是否过期,超过两个月就认为证书要过期了,重新续签证书。

但是这种情况下并不会将重新生成的证书并不会复制到 nginx 的 ssl 目录下,并重启nginx,那么就自己写个脚本管理,同时将定时任务修改为每 10 天的凌晨 00:28 分检查 证书是否要过期了。

我在 /itwxe/cron/ssl/ 目录下创建 checkSSL.sh 执行脚本,添加下面内容。

#!/bin/bash

echo "================================开始执行时间:$(date +%Y-%m-%d\ %H:%M:%S)"

echo "================================检查证书是否过期:"
"/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh"

echo "================================复制www证书到nginx ssl目录"
cp -r /root/.acme.sh/www.itwxe.com/{fullchain.cer,www.itwxe.com.key} /usr/local/nginx/ssl/www/
echo "================================复制img证书到nginx ssl目录"
cp -r /root/.acme.sh/img.itwxe.com/{fullchain.cer,img.itwxe.com.key} /usr/local/nginx/ssl/img/

echo "================================重启nginx"
nginx -s reload

echo -e "================================结束执行时间:$(date +%Y-%m-%d\ %H:%M:%S)\n"

赋予可执行权限。

chmod +x checkSSL.sh

crontab -e 删除原来的定时任务,添加定时任务。

28 0 */10 * * /itwxe/cron/ssl/checkSSL.sh >> /itwxe/cron/ssl/checkSSL.log 2>&1

重启定时任务

systemctl restart crond

当然为了检验效果可以,设置最近的时间进行校验是否可以正常执行,例如设置每天18:03执行定时任务。

3 18 * * * /itwxe/cron/ssl/checkSSL.sh >> /itwxe/cron/ssl/checkSSL.log 2>&1

到这里,就实现了网站的 https 化。

都读到这里了,来个 点赞、评论、关注、收藏 吧!