Skip to content

Homelab 终极远程访问架构:Cloudflare Tunnel + Nginx 统一接入层

Homelab 异常断电修复实录:从半夜关机到 vCenter 重生示意图

不再为每个服务分配子域名,不再纠结 SSH 如何穿透。一个 Nginx 统一接入层,解决所有内网服务的远程访问问题。

为什么需要这套架构?

如果你已经尝试过 Cloudflare Tunnel,可能会遇到两个很实际的问题:

  1. 子域名泛滥:每新增一个服务(ESXi、vCenter、GitLab、K8s Dashboard),就需要增加一个二级域名,DNS 记录越来越长。
  2. 协议受限cloudflared 原生主要支持 HTTP/HTTPS 流量,当你需要远程 SSH 登录时,会发现并不容易。

这些问题,恰好引出了我们今天的主题——为 Homelab 构建一个统一的远程访问接入层。它不仅能解决上述问题,还能让你的服务架构更清晰、更易于管理。

终级方案整体架构

这套架构的核心思想是:在 Homelab 内部部署一个 Nginx 反向代理,作为所有内网服务的唯一入口。cloudflared 只需要将流量指向这个 Nginx,由 Nginx 根据请求的特征(域名、路径、协议)将流量路由到具体的后端服务。

text
公网用户


Cloudflare 边缘节点 (HTTPS/TLS)
    │  (加密隧道)

cloudflared (Homelab 中的守护进程)
    │  (将流量转发到 Nginx)

Nginx 统一接入层 (核心路由)

    ├── ▶ ESXi (192.168.0.201:443)
    ├── ▶ vCenter (192.168.0.202:443)
    ├── ▶ GitLab (172.16.0.10:80)
    ├── ▶ K8s Dashboard (172.16.0.20:443)
    └── ▶ SSH (192.168.0.203:22)  [通过 TCP 隧道]

在这个架构中,Nginx 负责的是:

  • 路由分发:根据访问的域名或 URL 路径,将请求转发给对应的内网服务。
  • 协议代理:既能处理 HTTP/HTTPS,也能通过 Stream 模块转发 TCP 流量(如 SSH)。
  • 身份前置:可以在 Nginx 这一层配置统一的访问控制(如基本认证)。

部署步骤

第一步:部署 Nginx 统一接入层

你可以选择在任意一台 Linux 虚拟机中部署 Nginx。建议单独部署,与 cloudflared 放在一起,保持结构清晰。

  1. 安装 Nginx

    bash
    sudo apt update
    sudo apt install nginx -y
  2. 创建统一的 SSL 配置目录(用于管理证书):

    bash
    sudo mkdir -p /etc/nginx/ssl
  3. 准备 Nginx 核心配置文件:编辑 /etc/nginx/conf.d/homelab.conf,这个文件将定义所有服务的路由规则。

    nginx
    # HTTP 统一入口(监听所有请求)
    server {
        listen 80;
        server_name homelab.local;
    
        # 强制跳转 HTTPS(推荐)
        return 301 https://$host$request_uri;
    }
    
    # HTTPS 统一入口
    server {
        listen 443 ssl http2;
        server_name homelab.local;
    
        # SSL 证书配置(使用自签名证书或 Let's Encrypt)
        ssl_certificate /etc/nginx/ssl/homelab.crt;
        ssl_certificate_key /etc/nginx/ssl/homelab.key;
    
        # 安全头配置
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    
        # 路由规则:通过主机名(Host)区分服务
        # 访问 esxi.homelab.local 时,转发到 ESXi
        server_name esxi.homelab.local;
        location / {
            proxy_pass https://192.168.0.201:443;
            proxy_ssl_verify off;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    
        # 访问 vcenter.homelab.local 时,转发到 vCenter
        server_name vcenter.homelab.local;
        location / {
            proxy_pass https://192.168.0.202:443;
            proxy_ssl_verify off;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    
        # 访问 gitlab.homelab.local 时,转发到 GitLab
        server_name gitlab.homelab.local;
        location / {
            proxy_pass http://172.16.0.10:80;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    
        # 默认路由规则:未匹配的请求返回 404
        server_name _;
        location / {
            return 404;
        }
    }

第二步:配置 Nginx TCP 转发支持(用于 SSH)

为了支持 SSH,我们需要在 Nginx 中启用 Stream 模块来转发 TCP 流量。

编辑 /etc/nginx/nginx.conf,在 events 模块之后添加:

nginx
stream {
    upstream ssh_backend {
        server 192.168.0.203:22;  # 替换为你的 SSH 服务 IP
    }

    server {
        listen 2222;  # Nginx 监听的 SSH 转发端口
        proxy_pass ssh_backend;
        proxy_connect_timeout 1s;
        proxy_timeout 3s;
    }
}

这样配置后,Nginx 会在 2222 端口接收 TCP 连接,并将其转发到内网的 SSH 服务。

第三步:调整 cloudflared 配置

现在,cloudflared 只需要将流量指向 Nginx,而不再需要为每个服务配置独立的 ingress 规则。

编辑 ~/.cloudflared/config.yml

yaml
tunnel: <你的 Tunnel UUID>
credentials-file: /root/.cloudflared/<Tunnel UUID>.json

ingress:
  # 将所有 HTTP/HTTPS 流量指向 Nginx 的 HTTPS 入口
  - hostname: homelab.your-domain.com
    service: https://nginx.internal:443
    originRequest:
      noTLSVerify: true

  # 将所有 TCP 流量(SSH)指向 Nginx 的 TCP 转发端口
  - hostname: ssh.your-domain.com
    service: tcp://nginx.internal:2222

  # 默认规则
  - service: http_status:404

第四步:配置 DNS 记录

在 Cloudflare DNS 中添加 A 记录或 CNAME 记录,指向你的隧道:

bash
cloudflared tunnel route dns homelab homelab.your-domain.com
cloudflared tunnel route dns homelab ssh.your-domain.com

第五步:启动并验证

  1. 启动 Nginx

    bash
    sudo systemctl start nginx
    sudo systemctl enable nginx
  2. 启动 cloudflared 隧道

    bash
    cloudflared tunnel run homelab
  3. 验证 HTTP/HTTPS 访问:在浏览器中访问 https://homelab.your-domain.com,按照 Nginx 的路由规则,你应该能访问到对应的服务。

  4. 验证 SSH 访问

    bash
    ssh -o ProxyCommand="cloudflared access ssh --hostname %h" [email protected]

架构优势总结

特性说明
子域名收敛只需维护少量 DNS 记录(如 homelab.your-domain.comssh.your-domain.com
协议全覆盖通过 Nginx 的 HTTP 和 TCP(Stream)模块,同时支持 Web 服务和 SSH 等非 HTTP 协议
统一接入层未来添加任何新服务,只需在 Nginx 配置中增加一条 location 规则即可,无需改动 cloudflared 配置
安全可控所有流量在统一层经过,便于集中设置访问控制、日志记录和安全策略

需要注意的细节

  • Nginx SSL 证书:你可以使用自签名证书,或者使用 certbot 结合 DNS 挑战获取 Let's Encrypt 证书。
  • cloudflared 的 TCP 限制:免费版 Cloudflare Tunnel 对 TCP 流量(如 SSH)的连接时间有限制,但用于管理访问完全足够。
  • 访问日志:建议在 Nginx 中启用访问日志,方便排查问题。

测试与验证

  1. 内部测试:在 Homelab 网络中,直接访问 https://nginx.internal,确认 Nginx 能正常路由到各后端服务。
  2. 隧道测试:执行 cloudflared tunnel run homelab,观察日志中是否有请求到达的痕迹。
  3. 外部测试:通过手机开启 5G 网络,关闭 WiFi,访问 https://homelab.your-domain.com,确认能正常访问。

结语

这套架构,本质上是在 Homelab 内部构建了一个企业级的反向代理接入层。它使得你的内网服务不再孤立,而是通过一个统一的入口对外提供访问。

当你未来添加新服务时,不再需要为每个服务单独配置 Cloudflare DNS 和 cloudflared,只需要在 Nginx 中增加一条规则,整个流程变得非常简洁。你的 Homelab 网络架构,也借此向前迈进了一大步。

相关文档


附录:相关 IP 地址参考

  • ESXi 管理地址https://192.168.0.201
  • vCenter 管理地址https://192.168.0.202
  • Nginx 统一接入层https://nginx.internal(Homelab 内部访问)
  • SSH 服务地址192.168.0.203:22
最后更新2026/07/19 16:20
如果你觉得这篇文章有帮助,或者想聊聊技术、工作,欢迎通过下面方式联系我:
contact fishfinal