一台云服务器Ubuntu篇:6、Linux + Nginx 的 SSL 免费 Let’s Encrypt 证书签发与自动续签

SSL证书很重要,没有,现代浏览器都会提示不安全。

Certbot官网已经没有apt安装方式,但在Ubuntu 24.04 apt里仍可以搜索到certbot (2.9.0-1),所以直接apt安装就是了。

还是使用单域名 SSL 证书,比较简单,泛域名要操作DNS记录验证。

注册单域名 SSL 证书

Bash
 sudo apt install certbot python3-certbot-nginx
 sudo certbot --nginx -d blog.t725.cn # 有多少个域名时,就拼上多少个 -d youDomainName 

如果没有安装 python3-certbot-nginx 插件,执行sudo certbot --nginx -d blog.t725.cn,报错:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
The requested nginx plugin does not appear to be installed

没有报错的话,进入三步注册流程:输入邮箱地址,同意服务协议,是否邮件订阅。成功后,证书文件保存在/etc/letsencrypt/live/{youDomainName}/,且自动处理了Nginx站点配置文件/etc/nginx/sites-enabled/{youDomainName}

lat@vps-251018:~$ sudo certbot –nginx -d blog.t725.cn
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
(Enter ‘c’ to cancel): youname@t725.cn


Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.5-February-24-2025.pdf. You must
agree in order to register with the ACME server. Do you agree?


(Y)es/(N)o: Y


Would you be willing, once your first certificate is successfully issued, 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 our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.


(Y)es/(N)o: N
Account registered.
Requesting a certificate for blog.t725.cn

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/blog.t725.cn/fullchain.pem
Key is saved at: /etc/letsencrypt/live/blog.t725.cn/privkey.pem
This certificate expires on 2026-01-24.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

Deploying certificate
Successfully deployed certificatefor blog.t725.cn to /etc/nginx/sites-enabled/blog.t725.cn
Congratulations! You have successfully enabled HTTPS on https://blog.t725.cn


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

/etc/nginx/sites-enabled/blog.t725.cn 后面附加了以下内容:

Nginx
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/blog.t725.cn/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/blog.t725.cn/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = blog.t725.cn) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen       80;
    server_name  blog.t725.cn;
    return 404; # managed by Certbot
}

自动续定

续定验证测试

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

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/blog.t725.cn.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Account registered.
Simulating renewal of an existing certificate for blog.t725.cn

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all simulated renewals succeeded:
  /etc/letsencrypt/live/blog.t725.cn/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

没有报错,配置定时任务sudo crontab -e,证书有效期是90天

crontab安装与使用说明

Bash
$ sudo crontab -e
sudo: crontab: command not found

OCI上镜像没有crontab,太离谱了,需要手工安装。

Bash
sudo apt install cron
sudo systemctl status cron # sudo systemctl enable cron

编辑 crontab -e ,第一次运行需要选择编辑器,选择 vim 就可以了。

# 分钟 小时 日期 月份 星期 command
*/5 * * * * command 每 5 分钟执行一次
10 1-5 * * * command 1点10~5点10每小时执行1次,共执行5次
10 1,5 * * * command 1点10,5点10各执行1次,共执行2次

#
# 标准:[*]代表每1分/时/日/月/年执行一次;[*/30]是每30执行一次;[1,5,10]是在第1/5/10各执行一次;[1-5]是第1~5之间,每1执行一次;
# 特殊:月未最后一天的实现 < 0 0 * * * [ $(date -d tomorrow +\%d) -eq 1 ] && /your/command > 在每天午夜检查,如果明天是 1 号,那么今天就一定是最后一天。同理,星期几也是这个思路。
#
# [* */6 * * *]会在每隔6小时后,在一个小时里,每一分钟执行一次,共执行60次。并不是每6个小时执行一次!!!
#

查看用户的定时任务 crontab -l | grep ^[^#]

清空用户的定时任务 crontab -r

配置root用户的定时任务

sudo crontab -e
输入以下内容:

# 每月10号与20号的2点,执行定时任务。--quiet 参数表示静默模式,不会输出非错误信息。
0 2 10,20 * * /usr/bin/certbot renew --quiet

修改Nginx配置

OpenSSL ≥ 1.0.2:支持 HTTP/2 所需的加密协议。

Nginx ≥ 1.9.5:支持 HTTP/2 的最低版本。

Bash
$ nginx -v
nginx version: nginx/1.24.0 (Ubuntu)
$ openssl version
OpenSSL 3.0.13 30 Jan 2024 (Library: OpenSSL 3.0.13 30 Jan 2024)

blog.t725.cn配置文件

Bash
sudo cp /etc/nginx/sites-enabled/blog.t725.cn /data/blog.t725.cn.251026bak
sudo vim /etc/nginx/sites-enabled/blog.t725.cn

输入ggdG清空所有内容(gg移到第一行,d删除,G最后一行)

输入:1,$d删除第1~最后一行

输入u撤消删除

Nginx
server {
    listen       80 http2;
    server_name  blog.t725.cn;
    access_log off;
    return 301 https://$host$request_uri;
}
server {
    # managed by Certbot
    listen 443 ssl http2;
    server_name  blog.t725.cn;
    ssl_certificate /etc/letsencrypt/live/blog.t725.cn/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/blog.t725.cn/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    # access_log 按月+域名生成文件
    if ($time_iso8601 ~ "^\d{2}(\d{2})-(\d{2})") {
        set $year $1;
        set $month $2;
    }
    access_log  /data/www/log/nginx_${year}${month}_${host}.log;

    # 禁止特定bot,if中 ~*:与正则表达式匹配为真,不区分大小写;!~*:为不匹配;=:为精确匹配;!=:为精确不匹配。
    if ($http_user_agent ~* (python|perl|Go-http-client|fasthttp|Apache|zgrab|Custom-AsyncHttpClient|CMS-Checker|Amazonbot|MJ12bot|AhrefsBot)) {
        return 444;
    }
    if ($http_user_agent = -) {
        return 444;
    }
    if ($http_user_agent = "") {
        return 444;
    }

    root   /data/www/wordPress;
    index  index.php index.html;
    client_max_body_size 5m; # 上传文件大小上限
    add_header X-Frame-Options SAMEORIGIN; # 只允许同源域名下 frame 来嵌套
    add_header X-XSS-Protection "1; mode=block"; # 防止 XSS
    add_header X-Content-Type-Options nosniff; # 禁止嗅探 MIME 类型

    # xmlrpc.php、phpinfo.php,只有allow ip可访问用(IP段:192.168.13.0/24),其他403;如果所有人不可用,使用 return 403。
    # 由于是.php结尾,要在【location ~ \.php$ {】前面,才有效。
    location ~ ^/(xmlrpc|phpInfo)\.php {
        allow 10.0.0.103;
        deny  all;
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }
    location ^~ /wp-content/uploads/20 { # 防盗链,valid_referers none blocked 可允许无引用访问,PDF.js View插件是有引用访问。
        valid_referers t725.cn *.t725.cn *.google.com *.bing.com *.baidu.com;
        if ($invalid_referer) {
            return 302 $scheme://$host/additional/anti-theft.png;
        }
    }
    location ^~ /dl/ {
        alias /data/downloads/;
        try_files $uri $uri/ =404;
    }
    location ~ \.php$ { # php-fpm [~ 区分大小写 ~* 不区分大小写]
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }        
    location / { # WordPress 固定链接功能支持
        try_files $uri $uri/ /index.php?$args;
    }
}

配置生效:sudo nginx -t && sudo nginx -s reload

测试续定:sudo certbot renew --dry-run

默认配置文件

sudo vim /etc/nginx/sites-enabled/default

Nginx
server {
    listen 80 http2 default_server;
    listen [::]:80 http2 default_server;
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    server_name _;

    ssl_certificate /etc/letsencrypt/live/blog.t725.cn/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/blog.t725.cn/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    access_log off;
    return 301 https://blog.t725.cn$request_uri;
    #return 301 $scheme://$host$request_uri;
}

浏览器中验证是否开启http/2

在浏览器控制台输入以下代码,检查是否启用了 HTTP/2:

(function() {
   if (window.chrome && typeof chrome.loadTimes === 'function') {
       var info = window.chrome.loadTimes().npnNegotiatedProtocol;
       if (/^h2/i.test(info)) {
           console.info('本站点使用了HTTP/2');
       } else {
           console.warn('本站点没有使用HTTP/2');
       }
   }
})();

定时任务配置 wp-cron.php

先验证:sudo /usr/bin/curl https://blog.t725.cn/wp-cron.php?doing_wp_cron -I
成功后,再配置:sudo crontab -e

# 每隔30分钟,执行一次
*/30 * * * * /usr/bin/curl https://blog.t725.cn/wp-cron.php?doing_wp_cron

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注