用树莓派托管个人博客网站(二):将Web应用通过内网穿透隧道部署到公网

使用在阿里云注册的域名(以下以 hoigin.cn 为例),通过 Cloudflare Tunnel 安全地将公网流量转发到家庭内网中的树莓派服务,无需公网 IP、无需端口映射,享受 Cloudflare 免费提供的 SSL/TLS 证书、DDoS 防护和 WAF 能力。本方案适合个人博客、NAS、Home Assistant、私有 API 等场景。


🌐 购买域名并托管域名DNS解析服务

购买域名

登录阿里云官网,进入域名注册控制台,搜索并购买一个合适的域名。一般来说后缀为 .xyz 或者 .top 这样的域名会比较便宜。购买成功之后需要实名认证,通常10分钟内就会生效(以下内容以 hoigin.cn 域名为例)。接着,在域名列表中找到 hoigin.cn,点击右侧「管理」进入详情页。找到注册信息中的DNS服务器这一栏,这里可以看到阿里云提供的两个DNS服务器网址。

查询DNS服务器网址

访问Cloudflare官网并注册账号,登录后点击 Add a site,输入 hoigin.cn,点击 Add site,然后选择免费套餐(足够个人博客网站使用了)。然后可以看到,Cloudflare 会显示两个 Nameserver,例如:

1
                2
lara.ns.cloudflare.com
                rick.ns.cloudflare.com

设置托管服务

回到阿里云域名控制台,选择 hoigin.cn 域名,点击「DNS修改」,将阿里云提供的两个DNS服务器网址删除,改为 Cloudflare 提供的 Nameserver 地址。点击确认修改之后,等待 Cloudflare 邮件通知DNS解析托管服务生效即可。接着,在「Cloudflare 控制台 - DNS - 记录」中可以看到类似这样的内容:

1
                2
NS         hoigin.cn        lara.ns.cloudflare.com
                NS         hoigin.cn        rick.ns.cloudflare.com

这表示域名 hoigin.cn 的 Name Server 就是这两台服务器,该域名的 DNS 解析权已经交给 Cloudflare 的这两台服务器了。所有对该域名的 DNS 查询,都会被导向 lara.ns.cloudflare.comrick.ns.cloudflare.com 这两台 Cloudflare 的 DNS 解析服务器,这两台服务器拥有 hoigin.cn 这个域名的权威解释权。

Tip

DNS(Domain Name System)解析服务是是一种将人类可读的域名(如 www.example.com)转换为计算机可识别的IP地址(如 93.184.216.34)的网络服务。其主要作用包括:

  • 域名到IP地址的映射:用户在浏览器中输入域名后,DNS服务器负责查找对应的IP地址,使设备能够连接到目标服务器。
  • 提高访问效率:通过缓存机制,DNS可以减少重复查询,加快网页加载速度。
  • 负载均衡与高可用:DNS可将一个域名解析到多个IP地址,实现流量分发和故障转移。
  • 支持多种记录类型:如A记录(IPv4地址)、AAAA记录(IPv6地址)、CNAME(Canornical Name别名)、MX(邮件服务器)等,满足不同网络服务需求。

把在阿里云购买的域名托管至 Cloudflare,就要把阿里云提供的DNS解析服务器网址更换为 Cloudflare 提供的,目的是为了使用 Cloudflare 的内网穿透服务 Cloudflare Tunnel,并享受 Cloudflare 免费提供的 SSL/TLS 证书、DDoS 防护和 WAF 能力(这三项服务在 Cloudflare 的 Free Plan 中都是默认启用的,不用额外调整设置)。


🔧部署本地 Web 服务(参见上一篇文章)

确保树莓派上已运行一个 Web 服务,例如:

  • Nginx 监听 localhost:80
  • Flask/Gunicorn 监听 localhost:8000

可以用以下命令来测试本地访问是否正常,在树莓派终端中输入:

bash
1
                2
curl http://localhost
                # 应返回网页内容

🚇配置内网穿透隧道

内网穿透技术简介

内网穿透(NAT Traversal,即 Network Address Translation Traversal)是一种用于突破局域网限制、实现公网访问私有网络中服务的技术。在典型的家庭或办公网络环境中,设备(比如树莓派)往往仅拥有私有 IP 地址(如 192.168.x.x),且受 NAT(网络地址转换)和防火墙策略保护,设备的 Web 服务(比如在树莓派上部署的个人博客网站)只能被局域网内的用户访问,而无法被公网上的用户直接访问。

内网穿透技术就是解决这个问题的一种解决方案。其核心原理是,在内网设备与一台具备公网 IP 地址的中继服务器之间建立一条持久、加密的通信通道,即内网穿透「隧道」(Tunnel),然后内网设备主动连接该服务器并持续维持连接,之后所有发往该服务器特定地址或端口的公网请求,都会通过这条隧道被转发到内网设备上的对应服务。

目前主流的内网穿透工具包括 frp(Fast Reverse Proxy)、ngrok(Next Generation Reverse Open-tunneling Gateway)、ZeroTier、Tailscale 等。接下来,我们将使用 Cloudflare 提供的工具,在树莓派上搭建隧道,使其运行的 Web 服务能够被全球用户访问。

安装 cloudflared

为了使用 Cloudflare 提供的内网穿透服务,首先要在树莓派上安装可以向内网穿透隧道收发数据的客户端 Cloudflared。

bash
1
                2
                3
                4
                5
                6
                7
                8
                9
                10
                11
                12
                13
# 进入用户目录
                cd ~
                
                # 下载适用于树莓派 64 位系统的 .deb 包
                wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm64.deb
                
                # 安装
                # -i 参数表示 install
                sudo dpkg -i cloudflared-linux-arm64.deb
                
                # 验证安装
                cloudflared --version
                # 输出类似:cloudflared version 2025.x.x

安装成功后,用以下命令在 Cloudflared 客户端登录账号。

bash
1
cloudflared tunnel login
  • 若树莓派有图形界面:自动打开浏览器,登录 Cloudflare
  • 若无图形界面:复制终端给出的 URL 到电脑浏览器完成授权
  • 成功后会在以下路径生成认证文件:~/.cloudflared/cert.pem

创建并配置隧道

使用以下命令创建一条名为 raspberrypi-tunnel 的隧道。

bash
1
cloudflared tunnel create raspberrypi-tunnel

创建成功后,此隧道的凭据文件将保存为 ~/.cloudflared/<UUID>.json ,记住此 <UUID> ,配置文件中需要用到。接下来创建配置文件:

bash
1
                2
# 创建配置文件
                nano ~/.cloudflared/config.yml

在配置文件中填入以下内容(假设 Web 服务运行在 localhost:80):

yaml
1
                2
                3
                4
                5
                6
                7
tunnel: your-actual-uuid-here  # 替换为实际 UUID(不含 .json 后缀)
                credentials-file: /home/pi/.cloudflared/your-actual-uuid-here.json # 替换为实际 UUID
                
                ingress:
                  - hostname: hoigin.cn          # 你的主域名
                    service: http://localhost:80 # 树莓派本地服务地址
                  - service: http_status:404     # 未匹配请求返回 404

写好配置文件后,把 hoigin.cn 域名关联到创建好的隧道上。route dns 表示要为某个隧道配置 DNS 路由规则,即告诉 Cloudflare 的 DNS 解析服务器「当用户访问 hoigin.cn 这个域名时,请把流量通过指定的隧道转发到内网服务」。

bash
1
cloudflared tunnel route dns raspberrypi-tunnel hoigin.cn

此命令自动在 Cloudflare DNS 中添加 CNAME 记录,可以登录Cloudflare官网后在「Cloudflare 控制台 - DNS - 记录」中查看,大概形式如下所示:

1
hoigin.cn     CNAME     <UUID>.cfargotunnel.com.

在标准 DNS 语义中,这表示 hoigin.cn 这个域名的别名是另一个域名 <UUID>.cfargotunnel.com ,当有用户查询 hoigin.cn 这个域名的时候,DNS 解析服务器就会去查询 <UUID>.cfargotunnel.com 这个域名的 IP 地址。但是,虽然这两个域名的关系在形式上是 CNAME,但 <UUID>.cfargotunnel.com 并不真的存在于公共 DNS 中,它只是 Cloudflare 内部用于标识隧道的一个逻辑端点名称。Cloudflare 看到它 CNAME 指向一个 .cfargotunnel.com 域名,就不会继续向外递归查询这个 CNAME 的 IP,而是直接返回 Cloudflare 自己的边缘 IP 地址,同时在内部标记这个请求属于隧道 <UUID> ,并查找是否有活跃的 Cloudflared 连接(来自树莓派),查询到有之后就通过已建立的加密隧道将 Web 服务转发至用户端。

graph TD A[用户访问 hoigin.cn] A -->|DNS查询| B[请求到达Cloudflare<br/>权威DNS服务器] B -->|DNS服务器返回边缘节点IP地址|C[请求到达Cloudflare<br/>边缘节点] C --> D[边缘节点发现<br/>hoigin.cn对应<br/>&ltUUID&gt.cfargotunnel.com] D --> E[内部查表发现<br/>&ltUUID&gt.cfargotunnel.com<br/>对应隧道UUID</br>接着查找该UUID是否有<br/>活跃的cloudflared连接<br/>] E -->|有!来自树莓派!</br>通过已建立的加密隧道转发请求| F[请求到达树莓派上的<br/>cloudflared] F --> G[转发树莓派的<br/>本地 Web 服务] style A fill:#d7f3e3,stroke:#000,color:black style B fill:#d7f3e3,stroke:#000,color:black style C fill:#d7f3e3,stroke:#000,color:black style D fill:#d7f3e3,stroke:#000,color:black style E fill:#d7f3e3,stroke:#000,color:black style F fill:#d7f3e3,stroke:#000,color:black style G fill:#d7f3e3,stroke:#000,color:black

总之,到这一步就把内网穿透隧道和域名关联好了。

Tip

边缘节点(Edge Node),也称为接入点(Point of Presence,PoP),是在全球部署的服务器节点,用于就近处理用户请求。在现代互联网架构中是提升网站性能与安全的关键基础设施。截至 2025 年,Cloudflare 在超过 120 个国家和地区运营着 300 多个边缘节点,构成一个分布式的安全与加速网络。当用户访问使用 Cloudflare 的网站或通过 Tunnel 暴露的内网服务时,流量首先到达离用户最近的边缘节点,再由它负责安全过滤、缓存或通过加密隧道转发至源站。这种架构既提升了访问速度,又隐藏了真实服务器位置,增强了安全性。


🔄部署隧道服务至树莓派后台

前台测试

在终端中输入以下命令启动隧道服务。

bash
1
cloudflared tunnel run raspberrypi-tunnel
  • 日志中可能会出现一些 警告(WARN)和重试(Retrying),但日志中只要出现 Registered tunnel connection 表明隧道已建立并注册成功。这些重试警告往往是因为某些 Cloudflare 边缘 IP 节点暂时不可达或网络波动,只要cloudflared 自动重试并最终连上了其他可用节点就不会有问题,是正常容错行为。此时可以在手机或者电脑中输入 https://hoigin.cn 验证是否能从公网连接到网站。
  • 验证一切正常后,按 Ctrl+C 退出即可。

创建 systemd 服务

在终端输入以下命令,在 systemd/system 路径下创建一项名为 cloudflared.service 的后台服务。

bash
1
sudo nano /etc/systemd/system/cloudflared.service

打开 cloudflared.service 文件,写入这项后台服务的配置,如下所示:

ini
1
                2
                3
                4
                5
                6
                7
                8
                9
                10
                11
                12
                13
                14
                15
                16
                17
                18
                19
                20
                21
                22
                23
                24
                25
                26
                27
                28
                29
                30
[Unit]
                ; 服务的简要描述,显示在 systemctl status 等命令中
                Description=Cloudflare Tunnel for hoigin.cn
                
                ; 指定该服务在网络已就绪后再启动,确保 cloudflared 能正常联网
                After=network.target
                
                [Service]
                ; Type=exec 表示主进程就是 ExecStart 启动的程序(推荐用于 cloudflared)
                Type=exec
                
                ; 以普通用户 'pi' 身份运行服务,避免使用 root 提高安全性
                User=pi
                
                ; 启动命令:运行名为 raspberrypi-tunnel 的 Cloudflare 隧道
                ; 注意:cloudflared 会自动读取 ~/.cloudflared/ 下的配置和凭据
                ExecStart=/usr/bin/cloudflared tunnel run raspberrypi-tunnel
                
                ; 若服务异常退出(非零状态),则自动重启
                Restart=on-failure
                
                ; 重启前等待 5 秒,避免频繁崩溃导致资源浪费
                RestartSec=5
                
                ; 终止服务时仅杀死主进程(cloudflared),不杀其子进程(实际无子进程,此设置更安全)
                KillMode=process
                
                [Install]
                ; 设置服务启用(systemctl enable)后,在 multi-user.target(即常规多用户模式)下自动启动
                WantedBy=multi-user.target

写入保存好之后,在终端启用服务即可。

bash
1
                2
                3
                4
                5
                6
                7
                8
                9
                10
                11
# 重新加载 systemd 配置文件
                sudo systemctl daemon-reload
                
                # 设置服务开机自启动
                sudo systemctl enable cloudflared
                
                # 启动服务
                sudo systemctl start cloudflared
                
                # 检查服务是否正常运行
                systemctl status cloudflared

验证访问效果

在任意设备浏览器中访问 https://hoigin.cn,不仅可以看到树莓派上部署的网站内容,而且地址栏显示绿色锁图标(HTTPS 由 Cloudflare 自动签发)。本项目的部署方案无需公网 IP,无需路由器设置(特别在企业级局域网中,普通用户一般没有路由器设置权限),还能享受 Cloudflare 免费提供的附加优势:

功能 说明
自动 HTTPS 免费 SSL/TLS 证书,强制加密
DDoS 防护 自动过滤大规模流量攻击
WAF(Web Application Firewall) 阻止常见 Web 攻击(SQL 注入、XSS 等)
全球 CDN (Content Delivery Network)加速 用户就近接入 Cloudflare 节点
隐私保护 真实 IP 对外完全隐藏

Tip

DDoS 全称为「分布式拒绝服务攻击」(Distributed Denial of Service)。这种攻击通过控制大量被感染的设备(即「僵尸网络」)向目标服务器发送海量请求,导致服务器资源耗尽,无法正常响应合法用户的访问。Cloudflare 的 DDoS 防护 能够自动识别并过滤异常流量,在攻击到达源服务器之前将其拦截,从而保障网站的持续可用性。

Tip

HTTPS(HyperText Transfer Protocol Secure,超文本传输安全协议)是 HTTP 的安全版本,它通过加密机制确保用户与网站之间的数据传输不被窃听或篡改。简单地说,HTTPS 就是在标准 HTTP 协议的基础上,叠加了 SSL/TLS 加密层,从而实现安全通信。因此,部署 HTTPS 必须依赖有效的 SSL/TLS 证书。实现 HTTPS 的核心技术是 SSL/TLS 协议:

  • SSL(Secure Sockets Layer,安全套接层)是早期的加密协议,现已基本被弃用。
  • TLS(Transport Layer Security,传输层安全协议)是 SSL 的继任者,目前广泛用于现代网络通信中。

尽管 SSL 已经基本弃用,但大家总是习惯把 HTTPS 的加密协议叫做 SSL/TLS 协议。当用户访问一个启用 HTTPS 的网站时,浏览器会与服务器进行 TLS 握手,验证服务器提供的 SSL/TLS 证书(由可信的证书颁发机构签发),然后建立加密通道。这样,即使数据在传输过程中被截获,攻击者也无法读取其内容。


❓常见问题排查

访问 hoigin.cn 显示 404?

  • 检查 config.ymlhostname 是否拼写正确(区分大小写)
  • 确保本地服务正在运行:sudo systemctl status nginx

隧道无法连接?

  • 检查树莓派能否访问公网:ping 8.8.8.8
  • 确保防火墙未阻止出站 UDP(Cloudflare Tunnel 使用 QUIC/UDP)

想绑定子域名(如 blog.hoigin.cn)?

config.yml 中添加新规则:

yaml
1
                2
  hostname: blog.hoigin.cn
                  service: http://localhost:8000

然后执行:

bash
1
cloudflared tunnel route dns raspberrypi-tunnel blog.hoigin.cn

浏览器访问不跳转 HTTPS ?

实测发现 Chrome 浏览器会自动跳转 HTTPS,而 Safari 浏览器仍访问 HTTP,其根本原因在于浏览器行为差异。Chrome 浏览器采用了 HSTS(HTTP Strict Transport Security)机制,默认启用了自动将 HTTP 升级为 HTTPS的试探性功能,而 Safari 浏览器并没有此功能。由于 SSL/TLS 证书是由 Cloudflare 签发,所以可以在 Cloudflare 的边缘节点处将 HTTP 请求重定向至 HTTPS。具体操作是,登录进入 Cloudflare 仪表盘,选择 hoigin.cn 域名,选择 SSL/TLS 并点击「边缘节点」,然后选择「始终启用HTTPS」即可。