🚇 Cloudflare Tunnel 家庭服务器上网套件

没有公网 IP 也能把家里的服务挂到自己的域名:安装、临时隧道、正式隧道、多服务 ingress、systemd 常驻。

cloudflaredYAMLsystemd· 8 个文件 · 85 行 · MIT 协议

配套文章:《没有公网 IP,也能把家里的服务发到网上:Cloudflare Tunnel 实操》,配套视频:抖音/B 站 EP01。

文件作用
quick-tunnel.sh起一个本地演示页 + 临时 trycloudflare 链接
install-cloudflared.shDebian/Ubuntu 安装 cloudflared
named-tunnel.sh正式隧道六步,绑定自己的子域名
config.yml / config-multi.yml单服务、多服务 ingress 配置
as-service.sh装成 systemd 服务,开机自启
site/index.html视频里演示用的「我家电脑」页面

只用来暴露你自己的服务;后台类页面建议再加一层 Cloudflare Access 登录。

完整源码

as-service.sh

8 行 · bash
as-service.sh
#!/usr/bin/env bash
# 把隧道装成 systemd 服务,开机自启
set -euo pipefail
sudo cloudflared --config "$HOME/.cloudflared/config.yml" service install
sudo systemctl enable --now cloudflared
systemctl status cloudflared --no-pager
# 排查:cloudflared tail <隧道名>,重点找 connection refused、x509、TLS handshake

config-multi.yml

19 行 · yaml
config-multi.yml
# 多服务:从上往下匹配,第一条命中就停
tunnel: <UUID>
credentials-file: /home/me/.cloudflared/<UUID>.json
ingress:
  - hostname: nas.example.com
    service: http://localhost:5000
  - hostname: blog.example.com
    path: ^/api
    service: http://localhost:3000
  - hostname: blog.example.com
    service: http://localhost:8080
  - hostname: app.example.com                 # 源站本身是 HTTPS 时
    service: https://localhost:443
    originRequest:
      originServerName: app.example.com
  - hostname: "*.example.com"
    service: hello_world
  - service: http_status:404

config.yml

8 行 · yaml
config.yml
# ~/.cloudflared/config.yml —— 单服务示例
tunnel: <UUID>                                # cloudflared tunnel create 输出的 ID
credentials-file: /home/me/.cloudflared/<UUID>.json
ingress:
  - hostname: nas.example.com
    service: http://localhost:5000
  - service: http_status:404                  # 兜底规则,必须放最后

install-cloudflared.sh

9 行 · bash
install-cloudflared.sh
#!/usr/bin/env bash
# Debian / Ubuntu 安装 cloudflared(官方 apt 源)
set -euo pipefail
sudo mkdir -p --mode=0755 /usr/share/keyrings
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared any main" | sudo tee /etc/apt/sources.list.d/cloudflared.list
sudo apt-get update && sudo apt-get install -y cloudflared
cloudflared --version

named-tunnel.sh

13 行 · bash
named-tunnel.sh
#!/usr/bin/env bash
# 正式隧道六步(命令行方式)。前提:域名已接入 Cloudflare。
# 用法:./named-tunnel.sh home-lab nas.example.com
set -euo pipefail
NAME="${1:?隧道名}"; HOST="${2:?要绑定的子域名}"
cloudflared tunnel login                      # 1. 浏览器授权,生成 cert.pem
cloudflared tunnel create "$NAME"             # 2. 创建隧道,得到 UUID 和凭据 json
cloudflared tunnel list
echo "3. 把 config.yml 复制到 ~/.cloudflared/ 并填好 UUID 和 hostname,然后回车继续"; read -r
cloudflared tunnel ingress validate           # 4. 校验规则
cloudflared tunnel route dns "$NAME" "$HOST"  # 5. 自动建 CNAME → UUID.cfargotunnel.com
cloudflared tunnel run "$NAME"                # 6. 跑起来(确认没问题后再装成服务)

quick-tunnel.sh

8 行 · bash
quick-tunnel.sh
#!/usr/bin/env bash
# 一分钟临时隧道:不用注册、不用域名,链接每次重启都会变
set -euo pipefail
cd "$(dirname "$0")/site"
python3 -m http.server 8080 >/dev/null 2>&1 &
trap 'kill $!' EXIT
cloudflared tunnel --url http://localhost:8080   # 终端会打印 https://xxxx.trycloudflare.com

site/index.html

5 行 · html
site/index.html
<!doctype html><html lang="zh"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>我家电脑上的小站</title>
<style>body{font-family:"Noto Sans CJK SC",sans-serif;background:#111827;color:#fff;display:flex;align-items:center;justify-content:center;height:100vh;margin:0}
.c{text-align:center}h1{font-size:56px;margin:0 0 12px}p{color:#F38020;font-size:26px;margin:6px}small{color:#9CA3AF;font-size:18px}</style></head>
<body><div class="c"><h1>👋 你好,这是我家电脑</h1><p>localhost:8080 · 通过 Cloudflare Tunnel 访问</p><small>没有公网 IP,也没开端口</small></div></body></html>