Cloudflare + Nginx + Halo 子域名接入指南
Cloudflare + Nginx + Halo 子域名接入指南
记录 Oracle Ubuntu 服务器上的域名接入、HTTPS、反向代理与 Cloudflare CDN 配置。适用于同一台机器上的其他 Web 服务。
1. 最终访问架构
| 域名 | Nginx 上游 | 服务 |
|---|---|---|
halo.zuoan88.top | 127.0.0.1:7745 | Halo,Docker 容器内端口为 8090 |
filecode.zuoan88.top | 127.0.0.1:12345 | FileCodeBox |
litepan.zuoan88.top | 127.0.0.1:15211 | LitePan 网页服务 |
sub2api.zuoan88.top | 127.0.0.1:57866 | Sub2API |
80 与 443 由 Nginx 监听,按域名转发;7745 是 Halo 的直接 Docker 发布端口。
重点:日常不要再使用 IP:7745 访问 Halo。应使用 https://halo.zuoan88.top,才能经过 HTTPS、Cloudflare 防护与 Nginx 的正确转发。
2. Cloudflare DNS 设置
2.1 将根域名交给 Cloudflare
- 在 Cloudflare 添加根域名
zuoan88.top。 - 在 Cloudflare 概览页查看它为该域名分配的两条 NS。
- 进入阿里云域名注册控制台,在“DNS 修改 / 修改 DNS 服务器”中,替换默认的
dns*.hichina.com。 - 等待 Cloudflare 状态变为
Active。名称服务器变更可能需要数分钟到 24-48 小时。
重点:Cloudflare 的 NS 每个域名不同,不要复用、猜测或照抄其他域名的 NS。必须填写 Cloudflare 当前概览页显示的那两条。
阿里云“云解析 DNS”页面只能管理解析记录,不能修改注册商层面的名称服务器;应从阿里云域名注册控制台进入“DNS 修改”。
2.2 添加子域名 A 记录
在 Cloudflare 的 DNS -> Records 中添加以下 A 记录:
| 类型 | 名称 | IPv4 地址 | 代理状态 |
|---|---|---|---|
| A | halo | 158.101.16.169 | 已代理,橙色云朵 |
| A | filecode | 158.101.16.169 | 已代理,橙色云朵 |
| A | litepan | 158.101.16.169 | 已代理,橙色云朵 |
| A | sub2api | 158.101.16.169 | 已代理,橙色云朵 |
重点:DNS 记录中不填写端口。用户访问 https://子域名.zuoan88.top,端口由服务器内部的 Nginx 转发。
dig +short NS zuoan88.top @1.1.1.1
dig +short A halo.zuoan88.top @1.1.1.1刚新增域名时,部分公共 DNS 可能暂时缓存 NXDOMAIN。应结合 Cloudflare 权威 NS、多个公共解析器与最终 HTTPS 探测判断。
3. Oracle 与主机防火墙
Cloudflare 必须能访问源站 TCP 80 与 443:
- 在 Oracle Cloud 的安全列表或 NSG 添加入站规则:
0.0.0.0/0,TCP,目标端口80。 - 同样添加 TCP
443。 - Ubuntu 主机防火墙也必须在最终 REJECT 规则之前允许这两个端口,并保存规则。
sudo iptables -L INPUT -n --line-numbers
sudo netfilter-persistent save
sudo grep -nE 'dport (80|443)|REJECT' /etc/iptables/rules.v4522 排查:当 Nginx 本机已监听、主机防火墙也已放行时,522 通常是 Oracle 安全列表或 NSG 没放行,或规则尚未生效。若服务器抓包没有看到 Cloudflare 的 SYN,也说明请求在云侧被拦截。
4. 宝塔 Nginx 配置
4.1 确认真正运行的 Nginx
本机有效 Nginx 由宝塔管理,虚拟主机配置目录为:
/www/server/panel/vhost/nginx/sudo /www/server/nginx/sbin/nginx -t
sudo /www/server/nginx/sbin/nginx -s reload
sudo nginx -T重点:不要使用 systemctl restart nginx。该 systemd 单元并不管理当前正在使用的宝塔 Nginx;使用上面的宝塔路径检查并 reload。
4.2 HTTP 阶段:ACME 验证与回源
以下示例将 example.zuoan88.top 转发到 127.0.0.1:PORT。证书申请前先使用 HTTP 配置:
server {
listen 80;
server_name example.zuoan88.top;
location ^~ /.well-known/acme-challenge/ {
root /www/wwwroot/example.zuoan88.top;
default_type text/plain;
}
location / {
proxy_pass http://127.0.0.1:PORT;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}sudo mkdir -p /www/wwwroot/example.zuoan88.top/.well-known/acme-challenge
sudo /www/server/nginx/sbin/nginx -t
sudo /www/server/nginx/sbin/nginx -s reload
curl -sS -o /dev/null -w 'http=%{http_code}\n' \
-H 'Host: example.zuoan88.top' http://127.0.0.1/先验证上游服务,再继续申请证书,避免在端口或服务未确认时盲目排查 DNS。
5. HTTPS 与证书续期
5.1 签发 Let's Encrypt 证书
sudo certbot certonly --webroot \
-w /www/wwwroot/example.zuoan88.top \
-d example.zuoan88.top \
--agree-tos --register-unsafely-without-email --non-interactive证书文件:
/etc/letsencrypt/live/example.zuoan88.top/fullchain.pem
/etc/letsencrypt/live/example.zuoan88.top/privkey.pem5.2 HTTPS 反代配置
server {
listen 80;
server_name example.zuoan88.top;
location ^~ /.well-known/acme-challenge/ {
root /www/wwwroot/example.zuoan88.top;
default_type text/plain;
}
location / { return 301 https://$host$request_uri; }
}
server {
listen 443 ssl;
http2 on;
server_name example.zuoan88.top;
ssl_certificate /etc/letsencrypt/live/example.zuoan88.top/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.zuoan88.top/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
proxy_pass http://127.0.0.1:PORT;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}listen 443 ssl http2; 在当前 Nginx 会产生弃用警告,因此使用 listen 443 ssl; 与独立的 http2 on;。每次改配置前备份目标文件,执行 nginx -t 成功后再 reload。
5.3 自动续期
Certbot 定时器已启用;续期后 Nginx 必须 reload 才会读取新证书。部署钩子:
/etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
#!/bin/sh
/www/server/nginx/sbin/nginx -t && /www/server/nginx/sbin/nginx -s reloadsudo certbot renew --dry-run --no-random-sleep-on-renew6. 验证清单
6.1 本机服务与 TLS
sudo ss -lntp | awk 'NR==1 || /:(80|443|7745|12345|15211|57866) /'
printf '' | openssl s_client -connect 127.0.0.1:443 \
-servername halo.zuoan88.top 2>/dev/null \
| openssl x509 -noout -subject -ext subjectAltName6.2 公网和 Cloudflare
curl --noproxy '*' -I https://halo.zuoan88.top/
curl --noproxy '*' -I https://filecode.zuoan88.top/
curl --noproxy '*' -I https://litepan.zuoan88.top/
curl --noproxy '*' -I https://sub2api.zuoan88.top/成功响应应包含 server: cloudflare。页面的 cf-cache-status: DYNAMIC 正常,表示 Cloudflare 在代理,但没有缓存动态 HTML。
7. CDN 缓存原则
- Cloudflare DNS 记录保持橙色云朵代理。
- Halo 首页、文章动态页、
/console、登录路径与 API 绝对不要使用 “Cache Everything”。 否则可能缓存用户 Cookie、后台页面或过期内容。 - 带哈希名的静态 JS/CSS,例如
/ui-assets/...,由应用提供的长缓存头和浏览器/Cloudflare 缓存处理即可。 - LitePan 网页端可通过普通 Cloudflare HTTP(S) 代理;本机
42069/udp的 UDP/P2P 端口不能通过普通橙云代理。 它需要单独直连,或使用支持 UDP 的专用方案。
8. 已修复的 Halo 页面中断问题
访问 /archives/hello-halo 曾出现“加载很慢”,实际是主题渲染页脚时中断响应:
Cannot convert from null to boolean原因是主题 halo-theme-cosolar 的 legalLinks 未配置,但页脚把可能为空的开关直接作为三元表达式条件。
修复文件:
/www/dk_project/dk_app/halo/halo_XGrG/data/halo2/themes/halo-theme-cosolar/templates/fragments/footer.html将四个条件改为严格布尔判断,例如:
privacyUrl=${legalLinks?.privacy_enabled == true ? legalLinks?.privacy_url : null}同样处理 terms_enabled、links_enabled、about_enabled。修改前先备份文件,再重启对应 Halo 容器并验证完整响应;旧故障会先返回 200,随后在约 16 KB 处断开,因此不能只看状态码。
9. 后续安全收口
旧直连端口仍可能公开:Halo 7745、FileCodeBox 12345、LitePan 15211、Sub2API 57866。
- 将 Docker 端口改为仅绑定
127.0.0.1,或让 Nginx 通过 Docker 内网访问。 - 从 Oracle 安全列表与主机防火墙移除不再需要的公网业务端口。
- 仅保留 SSH 管理端口与 Web 的
80/443。
重点:不要在未验证域名回源、HTTPS、证书自动续期和业务协议前,直接关闭旧端口。特别是 LitePan 的独立 UDP/P2P 端口,错误关闭会导致其对应功能不可用。