依靠 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: 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
|