4

搭配 nginx、cloudflare 和 acme.sh 让网站走 https 协议

 2 years ago
source link: https://xujinzh.github.io/2022/04/08/nginx-cloudflare-https/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

依靠 cloudflare 我们能够把域名解析指向到云服务器的 ip 地址,借助 acme.sh 我们能为域名申请 SSL 证书,通过 nginx 反向解析服务器,让我们的网站访问走 https 协议。https 协议经由 http 进行通信,但利用 SSL/TLS 来加密数据包,比单纯的 http 协议(明文传输)更安全。本篇以 Debian 10 为例来演示如何搭建网站,并为网站申请证书并配置网站,让网站都走 https 协议。所有命令以 root 身份运行。

cloudflare 域名解析

首先,我们需要申请一个域名和购买云服务器,如:mathscv.com,然后在 cloudflare 注册一个账号,并用申请的域名添加域名站点。其次,进入 DNS 配置域名解析,具体的,我们需要添加记录,类型选择 A,名称填入域名:mathscv.com,内容填入云服务器的公网 IP 地址,代理状态可选仅限 DNS,也可开启代理 CND 加速。再添加记录,类型选择 A,名称填入 www (依据个人情况,填写三级域名,我这里配置的三级域名是:www.mathscv.com),内容和代理同上即可。

点击概述,在页码右下角部分有 API 选项,里面有区域 ID (CF_Zone_ID) 和账户 ID (CF_Account_ID),申请证书还需要一个 token,获取方法如下,还是在 API 选项里有个 获取您的 API 令牌,点进去后出现 API 令牌页面。点击创建令牌,选择变价区域 DNS,点击使用模板,在区域资源最后一栏中选择你的域名,然后点击继续以显示摘要,最后点击创建令牌,会显示创建成功的令牌码,我们需要谨慎保存好该令牌(CF_Token),因为该令牌近出现这一次。将我们获得的三个信息:CF_Zone_ID,CF_Account_ID,CF_Token 写入到我们的云服务器的环境变量中:

cd
echo 'export CF_Token="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"' >> .bashrc
echo 'export CF_Account_ID="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"' >> .bashrc
echo 'export CF_Zone_ID="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"' >> .bashrc
source .bashrc

nginx 安装

在 Debian 系统上安装 nginx 非常方便,命令如下:

apt update
apt install nginx -y

安装成功后,默认 nginx 服务是打开的,可以通过如下命令设置开机自启:

systemctl enable nginx.service

然后,我们配置 nginx

# 存放证书
mkdir -p /etc/nginx/cert/
# 配置证书和路由指向
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
vim /etc/nginx/nginx.conf

添加如下内容:

user  root;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 120;
client_max_body_size 20m;
#gzip on;
server {
listen 80;
listen [::]:80;
server_name www.mathscv.com;
return 301 https://$server_name$request_uri; # 强制走 HTTPS
}
server {
listen 443 ssl;
server_name www.mathscv.com;
ssl_certificate /etc/nginx/cert/fullchain.cer;
ssl_certificate_key /etc/nginx/cert/private.key;
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 TLSv1.3;
ssl_prefer_server_ciphers on;
#location / { # 静态网页,存放在 /usr/share/nginx/html 下
# root /usr/share/nginx/html;
# index index.php index.html index.htm;
#}
location / { # 将 https://www.mathscv.com 跳转为 https://www.mathscv.com/power/
#root /usr/share/nginx/html;
#index index.php index.html index.htm;
proxy_pass http://127.0.0.1:1234/power/;
}
location /power { # 通过访问 http://www.mathscv.com/power 来访问 http://127.0.0.1:1234/power
proxy_pass http://127.0.0.1:1234;
proxy_set_header Host $host;
proxy_set_header X-Real-Scheme $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_read_timeout 120s;
proxy_next_upstream error;
}
}
}

测试配置是否通过

nginx -t

通过结果如下

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

如果使用命令systemctl status nginx.service查看状态出现错误: “nginx.service: Failed to read PID from file /run/nginx.pid: Invalid argument”,可使用如下方法

mkdir -p /etc/systemd/system/nginx.service.d
printf "[Service]\nExecStartPost=/bin/sleep 0.1\n" > /etc/systemd/system/nginx.service.d/override.conf
systemctl daemon-reload
systemctl restart nginx.service

acme.sh 申请证书

申请证书我们采用命令行的方式,假设上面的 CF_Zone_ID,CF_Account_ID,CF_Token 已经按要求正确配置到环境变量中,且 /etc/nginx/nginx.conf 也已经配置成功并通过。那么证书申请配置放入如下命令:

# 安装程序,邮箱写自己申请 cloudflare 时使用的
curl https://get.acme.sh | sh -s [email protected]

# 使用 DNS 方式申请证书
~/.acme.sh/acme.sh --issue --dns dns_cf -d www.mathscv.com -k ec-256 --ecc

# 安装证书
~/.acme.sh/acme.sh --installcert -d www.mathscv.com --ecc \
--key-file /etc/nginx/cert/private.key \
--fullchain-file /etc/nginx/cert/fullchain.cer \
--reloadcmd "systemctl force-reload nginx.service"

或者按照如下方式申请证书,不需要上面的 CF_Zone_ID,CF_Account_ID,CF_Token,只需要服务器的 80 端口打开,并将域名指向服务器 IP 地址。它的原理是证书颁发机构向您的服务器发送一个字符串,并通过域名解析的80端口看是否能够正确显示并获取,如果信息相同,说明证明是您拥有该域名,那么颁发证书。

# 按照程序
curl https://get.acme.sh | sh -s [email protected]

# 使用 standalone 方式申请证书
~/.acme.sh/acme.sh --issue --standalone -d www.mathscv.com -k ec-256 --ecc

# 安装证书
~/.acme.sh/acme.sh --installcert -d www.mathscv.com --ecc \
--key-file /etc/nginx/cert/private.key \
--fullchain-file /etc/nginx/cert/fullchain.cer

如果申请中出现等待时间过长或失败,可尝试切换证书颁发机构:

# 切换证书认证机构
# 切换为 Let's Encrypt
~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
# 切换为 Buypass
~/.acme.sh/acme.sh --set-default-ca --server buypass
# 切换为 ZeroSSL
~/.acme.sh/acme.sh --set-default-ca --server zerossl

其实,上面申请证书成功后,在 ~/.acme.sh 下会出现一个 www.mathscv.com_ecc 文件夹,里面有申请的证书信息,但不建议直接在 nginx 中指定该路径。

  • 证书有效期默认是 60 天 (通过命令 ~/.acme.sh/acme.sh --list 查看),但安装时自动会创建 crontab 定时任务,每日 0 晨左右会自动运行更新,你无需任何操作;

  • acme.sh 脚本默认的 ZeroSSL.com 存在着频率上限,尽量不要反复多次申请。

  • acme 更新比较活跃,你可以安装如下方法手动更新或设置自动更新软件:

    # 手动更新
    ~/.acme.sh/acme.sh --upgrade

    # 设置自动更新
    ~/.acme.sh/acme.sh --upgrade --auto-upgrade

    # 关闭自动更新
    ~/.acme.sh/acme.sh --upgrade --auto-upgrade 0

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK