前言

家宽的端口不可能给你80和443,当然其他端口也够自己用了,但是没有ssl是不是不够高级安全,这里就简单搞一下。

安装Certbot

Ubuntu下安装certbot很简单,使用snap安装即可:

sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

申请SSL证书

接下来进入主题,开始SSL证书的申请。

运行Certbot命令
首先是运行certbot的证书申请命令,需要注意的点是验证模式要用DNS-TXT的方式,-d后面跟要申请的域名,我这里申请的是泛域名。
命令如下:

sudo certbot certonly --preferred-challenges dns -d "*.你的域名.com" --manual

这时certbot会提醒你在域名DNS解析记录中添加记录,登录阿里云DNS解析,点击添加记录,记录类型选择TXT,将域名和值填进去。添加记录条目后,点击终端中提供的Dig网址,如果解析结果和certbot提供的值相同,则表示添加记录成功。

返回到终端,回车继续验证,没问题的话,certbot会提示这个证书不会自动更新(因为是手动申请的)。此时证书已经申请成功了,存放在/etc/letsencrypt/live/你的域名.com中。

配置Nginx

找到Nginx中https server的配置代码块,添加如下字段:


# SSL
ssl_certificate         /etc/letsencrypt/live/你的域名.com/fullchain.pem;
ssl_certificate_key     /etc/letsencrypt/live/你的域名.com/privkey.pem;

# SSL config
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;

重新加载Nginx配置:

sudo service nginx reload

刷新一下随便那个网站,就能看到已经是安全的HTTPS连接了。

方便加域名的脚本

这里nginx路径可以自定义

touch add_nginx_conf.sh

chmod +x add_nginx_conf.sh

vim add_nginx_conf.sh

输入:set paste进入粘贴模式,粘贴以下内容。

#!/usr/bin/env bash

nginx_conf_dir="/etc/nginx/conf/conf.d"
GreenBG="\033[42;37m"
Font="\033[0m"
# 提示用户输入域名变量
read -p "请输入域名: " domain

# 检查是否输入为空
if [ -z "$domain" ]; then
    echo "域名不能为空,请重新运行脚本并输入有效的域名。"
    exit 1
fi
read -p "请输入证书路径: " ssl_dir

if [ -z "$ssl_dir" ]; then
    echo "请输入证书路径,请重新运行脚本并输入有效的证书路径。"
    exit 1
fi

# 提示用户输入域名变量
read -p "请输入反代端口(你本地项目服务端口): " proxy_port

# 检查是否输入为空
if [ -z "$proxy_port" ]; then
    echo "请输入端口(你本地项目服务端口),请重新运行脚本并输入有效的端口。"
    exit 1
fi

read -p "请输入反代ip(你本地项目服务ip): " proxy_ip

if [ -z "$proxy_ip" ]; then
    echo "请输入反代ip(你本地项目服务ip),请重新运行脚本并输入有效的ip。"
    exit 1
fi
judge() {
    echo -e "${OK} ${GreenBG} $1 完成 ${Font}"
            sleep 1
}

nginx_conf_add() {
    touch ${nginx_conf_dir}/${domain}.conf
    cat >${nginx_conf_dir}/${domain}.conf <<EOF
    server {
    	      listen 9999 ssl http2;
    	      listen [::]:9999 http2;
            ssl_certificate       ${ssl_dir}/fullchain.pem;
            ssl_certificate_key   ${ssl_dir}/privkey.pem;
            ssl_protocols         TLSv1.1 TLSv1.2 TLSv1.3;
            ssl_ciphers           TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5;
    	      server_name ${domain};
            index index.html index.htm;
            # 无brotli可以删掉下面brotli相关
            brotli on;              #启用
            brotli_comp_level 6;    #压缩等级,默认6,最高11,太高的压缩水平可能需要更多的CPU
            brotli_buffers 16 8k;   #请求缓冲区的数量和大小
            brotli_min_length 20;   #指定压缩数据的最小长度,只有大于或等于最小长度才会对其压缩。这里指定20字节
            brotli_static always;   #是否允许查找预处理好的、以.br结尾的压缩文件,可选值为on、off、always
            brotli_window 512k;     #窗口值,默认值为512k
            # Config for 0-RTT in TLSv1.3
            ssl_early_data on;
            ssl_stapling on;
            ssl_stapling_verify on;
            add_header Strict-Transport-Security "max-age=31536000";

            location /
                  {
                  proxy_redirect off;
                  proxy_read_timeout 1200s;
                  proxy_pass http://${proxy_ip}:${proxy_port};
                  proxy_http_version 1.1;
                  proxy_set_header X-Real-IP \$remote_addr;
                  proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
                  proxy_set_header Upgrade \$http_upgrade;
                  proxy_set_header Connection "upgrade";
                  proxy_set_header Host \$http_host;

                  # Config for 0-RTT in TLSv1.3
                  proxy_set_header Early-Data \$ssl_early_data;
                  }
        }
        server {
            listen 80;
            listen [::]:80;
    	    server_name ${domain};
    	    return 301 https://${domain}\$request_uri;
        }
EOF
    judge "Nginx 配置新增成功"

}

nginx_conf_add


再执行,按照提示填写
QQ_1731917389755

sh add_nginx_conf.sh

托管脚本

安装 aliyun cli 工具

wget https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-amd64.tgz
tar xzvf aliyun-cli-linux-latest-amd64.tgz
sudo cp aliyun /usr/local/bin
rm aliyun

将拥有 DNS 权限的角色配置到云服务器中

cd aliyun /usr/local/bin
aliyun configure --profile akProfile

配置会进入交互式内容,如下输入完成配置:

Configuring profile 'akProfile' in '' authenticate mode...

Access Key Id []: 在这里输入阿里云里的 Access Key 然后回车进入下一项
Access Key Secret []: 在这里输入阿里云里的 Access Key Secret 然后回车进入下一项

Default Region Id []: cn-hangzhou 
Default Output Format [json]: json (Only support json))
Default Language [zh|en] en:
Saving profile[akProfile] ...Done.

出现如下界面,配置完成:
QQ_1741076894128

安装 certbot-dns-aliyun 插件

wget http://cdn.jsdelivr.net/gh/justjavac/certbot-dns-aliyun@main/alidns.sh
sudo cp alidns.sh /usr/local/bin
sudo chmod +x /usr/local/bin/alidns.sh
sudo ln -s /usr/local/bin/alidns.sh /usr/local/bin/alidns
rm alidns.sh

测试是否能正确申请

certbot certonly -d *.替换自己的域名.com --manual --preferred-challenges dns --manual-auth-hook "alidns" --manual-cleanup-hook "alidns clean" --dry-run

出现The dry run was successful. 即为成功。

自动续期,添加定时任务 crontab

crontab -e

输入
这里表示每月1号的晚上2点执行续期

0 02 1 * * root certbot renew --manual --preferred-challenges dns --manual-auth-hook "alidns" --manual-cleanup-hook "alidns clean" --deploy-hook "service nginx restart"


Q.E.D.


味无味处求吾乐,材不材间过此生。