使用Cloudflare系列服务的自建穿透和常见服务部署方案
版本记录
2025-05-07~2025-05-08:初稿
前言
一直以来都想有一台自己的服务器,主因在于期待长时在线和即时自动化服务响应的便利性。
举一个需求,知识库和囤积库为例,我一直深受自己的囤积癖困扰,长期处在一种信息过载的状态中,所以就自然而然的想要一个能够随时记载并归类我的想法的服务,这种服务虽然有一些现成应用选择,但是往往定制度很低,且横向比较下来对自动化流程、AI的支持度也不高。基于这个念头我开始考虑自托管,并且利用开放端口来自己给自己定制托管服务。
综合而言,我对自托管服务,或者说家用自建服务的需求主要聚焦在:
- 个人博客
- 个人科研主页
- 自建存储(用于备份和冷数据存储)
- 密钥管理
- Git服务
- 知识库/事务管理/囤积库/文献管理
- AI助手(与上一项结合,实现长期积累,短期调度+排除事务干扰的效果)
- 包括一些自动化科研工具如 arxiv 论文拉取,自动化论文调研
- 囤积库自动化分类,知识的关联和统合
- 日程管理,定时和智能提醒
以及相对优先级较低的:
- 个人邮箱
- 网络路由
本文目录
自托管方案总览
我使用的自托管方案大体上可以概括为两个部分:局域网异地组网和内网穿透暴露服务。
其中异地组网主要是为了实现局域网内的设备互联互通,方便在不同地点使用各个设备上的服务。内网穿透则是为了将局域网内的服务暴露到公网,以在外网访问,并且同时允许更加细化的访问控制。这是由于直接通过
zerotier
进行异地组网会导致所有设备都共享全部局域网的访问权限,对于一些不需要共享的服务,如团队协作使用git的时候,可能会导致一些不必要的麻烦。
整体的网络框架图如下:
其中异地组网部分负责对我自己完全开放所有服务访问,仅有一台作为公网 Relay
的主机具有公网IP,其他主机均为 Zerotier 的内网IP,以保证除了 Zerotier 的
planet 主机外其他主机都不会被公网访问到。内网穿透部分则是通过 Cloudflare
Tunnel
将局域网内的固定端口服务暴露到公网,并且通过Cloudflare的访问控制来限制访问权限。
基于Zerotier与自建行星服务器的异地组网方案
Zerotier 是一个开源的虚拟局域网软件,允许用户在不同地点的设备之间建立安全的点对点连接,不同设备之间处在同一个虚拟局域网段中,能够像通常家中或者办公场所的局域网一样进行相互访问。Zerotier 的行星服务器是公网上的一个中转服务器,允许用户在其他设备都没有公网IP且处于NAT后面时,仍然能够通过行星服务器进行连接(理想情况下其实行星服务器只应当提供最开始的链接引导,如果打洞成功就是点对点传输,但是在国内网络环境下一般难以成功,所以就只能中转)。Zerotier 的行星服务器有两种选择,一种是使用 Zerotier 官方提供的行星服务器,另一种是自己搭建行星服务器。由于 Zerotier 官方的行星服务器在国内访问速度较慢,所以选择了自己搭建行星服务器。
基于Cloudflare Tunnel的内网穿透方案
Cloudflare Tunnel 是 Cloudflare 提供的一个内网穿透服务,允许用户将局域网内的服务暴露到公网。这个公网服务的权限是可以通过 Cloudflare Zero Trust 的访问控制来限制的。不过需要注意的是,这样做相当于服务来回都是要走到国外 Cloudflare 的流量上的,对于国内访问肯定是会打一个比较大的折扣,自测延迟大概会到 150ms 左右。但是可用性尚且还比较高。
本地服务器设置
本地的服务器使用的是一台利旧的游戏本电脑。覆盖了旧的 Windows 安装了 Fedora 42 Server 版本。直接使用的 Fedora Media Installer 刷到了U盘上来启动安装。安装完了之后不知道为什么 grub 没把隔壁的旧的 Fedora 40 给加到启动项里,但是 os-prober 能读到,估摸着这个问题不太重要就暂且忽略了。
Server版本的Fedora没有图形界面但是自带一个 Web Console 管理界面 Cockpit,使用起来很舒服,可以直接在图形界面上进行资源占用率监测、系统包升级、防火墙配置(且似乎这里的防火墙配置优先级高于直接使用 firewall-cmd 进行的配置),以及日志读取、存储挂载、容器管理、账户权限管理和 SSH 密钥授权、文件浏览、在线终端的功能。以前从来不知道完整开放的服务器系统这么好用…
以下简单记录下一些我在配置本地服务器过程中进行的额外设置。
电源管理
我们使用 TLP 来进行电源管理。这主要是考虑到笔记本服务器长期插电,让电池维持一个充电阈值能够比较有效防止鼓包或者损坏的问题。
安装: 1
sudo dnf install tlp
1
2sudo systemctl enable tlp # 开机自启
sudo tlp start1
2
3
4sudo nano /etc/tlp.conf
# 在配置文件最后加入,请参照TLP的文档,我使用的是联想系列的通常设置。
THINKPAD_BATTERY_MODE=1
STOP_CHARGE_THRESH_BAT0=1
休眠行为
我们需要笔记本在合盖的时候继续运行,所以有必要把合盖休眠关掉。分为两个部分:一个是直接屏蔽掉相关的
systemd target 使得笔记本所有休眠状态失效,另一个是改变 systemd-logind
的配置,以关闭休眠触发。我一开始以为可以只设置前者,但是这会导致
systemd-logind
一直尝试休眠,导致反复触发休眠失败事件,会一直写入日志文件和占用CPU资源,导致不必要的负担。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# 关闭休眠
sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
# 关闭 logind 的休眠触发
# 这里直接修改 /etc/systemd/logind.conf 不会生效,可能是由于系统特定的行为。
cp /usr/lib/systemd/logind.conf /etc/systemd/logind.conf.d/
sudo nano /etc/systemd/logind.conf.d/logind.conf
# 在文件中加入
[Login]
HandleSuspendKey=ignore
HandleHibernateKey=ignore
HandleLidSwitch=ignore
HandleLidSwitchExternalPower=ignore
HandleLidSwitchDocked=ignore
# 重启 systemd-logind 服务
sudo systemctl restart systemd-logind
SSH密钥配置
这里假定我们已经有一个SSH密钥对不再生成了,只要把 SSH 密钥加到
authorized_keys 就好了。 1
2
3
4
5
6
7
8
9
10
11
12
13ssh-copy-id -i ~/.ssh/my_server_key.pub [email protected]
# 输入密码完成认证
# 之后就可以直接使用 ssh [email protected]进行登录。
# 或者细化 ssh -i ~/.ssh/my_server_key [email protected]
# 安全配置:关闭密码登录,开启密钥登录
sudo nano /etc/ssh/sshd_config
# 修改以下配置
PasswordAuthentication no
PubkeyAuthentication yes
PermitRootLogin no
# 重启 sshd 服务
sudo systemctl restart sshd
# 或者sudo systemctl restart ssh 可以两个都试一下
局域网访问:异地组网
Zerotier本地客户端的安装与配置
安装:Linux 版本安装如下,MacOS 和 Windows 版本都是去官网下载。 1
curl -s https://install.zerotier.com | sudo bash
1
2
3
4
5sudo zerotier-cli join <network_id>
# 之后在控制台trust设备
sudo zerotier-cli listnetworks
sudo zerotier-cli listpeers
sudo zerotier-cli info
之后就可以像在普通局域网中那样相互进行访问了。
行星服务器的搭建与配置
首先,我们需要一台具有公网IP的服务器作为自建的行星服务器,同时服务器需要开放3443/tcp, 9994/udp, 9994/tcp端口。在这里我使用了阿里云的VPS。 所使用的服务容器和教程参考docker-zerotier-planet。
以下操作在云服务器上进行
软件依赖:安装git和docker 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#debian/ubuntu等
apt update && apt install git -y
#centos等
yum update && yum install git -y
# 安装docker
curl -fsSL https://get.docker.com |bash
service docker start
# 配置加速镜像
sudo tee /etc/docker/daemon.json <<EOF
{
"registry-mirrors": [
"https://docker.mirrors.aster.edu.pl",
"https://docker.mirrors.imoyuapp.win"
]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker1
git clone https://ghproxy.imoyuapp.win/https://github.com/xubiaolin/docker-zerotier-planet.git
1
2
3cd docker-zerotier-planet
sh deploy.sh
#自动完成安装
新建网络之后,请点击Easy Setup设置你的网络的局域网网段,可以用Generate network address直接生成。
从这里开始,以下是在本地端而非服务器端进行的配置。
随后下载 Planet 配置文件,这是Zerotier用于定义行星的配置文件,在本地客户端替换后即变更为使用我们的 Planet。文件的位置在./data/zerotier/dist下。
本地配置
Linux: 1. 替换/var/lib/zerotier-one/planet 文件为下载的文件 2. 重启
zerotier 服务: 1
sudo service zerotier-one restart
1
sudo zerotier-cli join <network_id>
1
2sudo zerotier-cli listnetworks
sudo zerotier-cli listpeers1
2sudo launchctl unload /Library/LaunchDaemons/com.zerotier.one.plist
sudo launchctl load /Library/LaunchDaemons/com.zerotier.one.plist1
sudo zerotier-cli join <network_id>
1
2sudo zerotier-cli listnetworks
sudo zerotier-cli listpeers
提醒
加入自建行星服务器后要退出旧的官方服务器网络,不然有几率出现网段相同时冲突连不上的问题。
1
sudo zerotier-cli leave <network_id>
1
2
3sudo systemctl stop zerotier-one.service
sudo cp -a /mnt/fedora/root/var/lib/zerotier-one/ /var/lib
sudo systemctl start zerotier-one.service
内网穿透:Cloudflare Tunnel
如果你的服务器通过 Cloudflare Tunnel 连接到了 Cloudflare 网络。你可以在 Cloudflare Zero Trust 仪表盘中配置你的 Tunnel,例如添加 Public Hostnames,将特定的域名或子域名指向你的本地服务(例如你的 Hexo 博客)。这样,用户就可以通过 Cloudflare 的全球网络访问你的服务,而无需知道你服务器的真实 IP 地址,也无需在防火墙中开放端口,大大提高了安全性。
这需要你将自己的域名托管给 Cloudflare,这可以直接通过在你的Dashboard->Account Home中添加域并输入你的域名(选择免费计划)来完成,Cloudflare会自动搜索并保存你已有的DNS Record,并提供给你Cloudflare的nameserver。你只需要在你的域名注册商处把Nameserver改为Cloudflare提供的nameserver并删除原有的nameserver即可。DNS的更新可能需要一点时间。
以上托管域名的步骤需要在配置Cloudflare Tunnel之前完成。
Cloudflare Tunnel 的安装与配置
首先先打开Cloudflare Dashboard,打开Zero Trust工作台。
首次使用的时候会要求你订阅开通。Teamname随意填写,选择免费套餐,绑定支付方式时可以选择直接填银联卡也可以完成绑定(或者不行就使用 PayPal,这一点有点记不清了,但是没有外币卡也是可以解决这一步的)。
之后在 Networks -> Tunnels中创建一个新的隧道,名字任起。
Cloudflare Tunnel
需要在本地服务器上安装一个加密通道连接器(守护进程),称为 Cloudflared。
以下命令以我的Fedora(Red Hat系列)为例。 1
2
3
4
5
6
7
8# Add cloudflared.repo to /etc/yum.repos.d/
curl -fsSl https://pkg.cloudflare.com/cloudflared-ascii.repo | sudo tee /etc/yum.repos.d/cloudflared.repo
#update repo
sudo yum update
# install cloudflared
sudo yum install cloudflared
# bind your token
sudo cloudflared service install <your_tunnel_token>
你可以检查当前的配置是否正确: 1
sudo systemctl status cloudflared
常见服务的部署
目前我在我的服务器上只通过Cloudflare Tunnel 部署了一个 Hexo 博客。同时另外利用Cloudflare Email Routing 实现了自有域名邮件的转发,借由 Gmail 的 SMTP 代发实现了自有域名邮件的发送。
容器化部署博客服务:Hexo
部署的 Hexo 博客使用的是我之前在文章使用Hexo搭建个人博客简记中部署过的。
现在我想要把它容器化的、数据和配置(环境)分离出来的部署到我的服务器上。 总体上来说我们只保留了原有的 Hexo 和主题的配置文件(_config*.yml)与我们的文章源数据,其他的无论是静态文件、主题文件、node_modules还是包管理配置都不需要。
准备好原有的这些内容之后,我们直接使用两阶段的方式构建一个镜像,这个镜像分为两个阶段: - 生成静态文件:安装 Hexo、主题和渲染插件,初始化容器中的博客目录,将源文件复制到容器中,生成博客的静态内容。 - 使用 Nginx 提供静态文件服务:将生成的静态文件复制到 Nginx 的默认目录中,使用 Nginx 提供静态文件服务。
1 |
|
注:考虑到不可用dockerhub,请自行寻找并替换我使用的镜像源。
我使用 Podman 来构建并运行这个镜像,Podman 是一个和 Docker 类似的容器管理工具,使用方法和 Docker 基本一致,基本可以直接替换 Docker 命令,并且由于是 Red Hat 系的工具,在我们的 Fedora Server 上是自带镜像管理和容器管理功能的,非常方便。
将Dockerfile放在博客目录下之后,随后构建镜像并启动容器:
1
2
3
4podman build -t hexo-blog .
podman run -d -p <host_port>:80 --name hexo-prod hexo-blog
# 可以用于清理悬空的(不被依赖的)镜像层
podman image prune
另外还要记得,该端口需要在服务器的防火墙中放行,这个直接在控制面板中操作了,如果用命令行管理就是用firewall-cmd来放行端口。
1 |
|
当然这样手动构建并启动容器无疑过于慢了,需要以后继续优化为使用docker-compose 来进行自动化构建和启动。
邮件服务:Cloudflare Email Routing 收件与 Gmail SMTP 代理发件
随后我发现似乎可以使用 Cloudflare 的 Email Routing 来实现自有域名的邮件转发(仅收件)。这可以通过 Cloudflare 的域名管理页 -> Email -> Email Routing 来快速地配置,Cloudflare 会为你的域名添加若干 MX 记录到 Cloudflare 的 mx.cloudflare.net 路由上。同时添加 DKIM 和 SPF 记录来保证邮件仍然可信。

同时 你需要在 Email Routing 的 Routing Rules
中添加你的自定义地址,并规定这个地址转发到你的 Gmail 地址上。
另外这里有个小插曲,如果你的DNSSEC设置在Cloudflare上配置之后没有正确地配置到你的注册商处,你的 Email Routing 可能会收不到邮件,因为 MX 记录会因为认证不成功失效。
以上是我们的收件配置。
为了能够从我们自定义的地址发出邮件,我们需要一个代理发件的服务器(因为我不打算自建邮件服务器,过于麻烦了)。我们使用Gmail的代发邮件服务来完成这个操作。这个操作需要在 Gmail 设置的 设置 -> 账号和导入 -> 用这个地址发送邮件 -> 添加其他电子邮件地址 中进行配置。首先设置发件人别名和代发的地址:

然后下一步,在 SMTP 服务器中填写 smtp.gmail.com,使用和端口配对的安全链接协议。用户名为你的 Gmail 邮箱地址,密码需要你在开启两步验证以后开启应用专用的16位密码。(这个密码可能会在你更改密码后失效,到时候需要重新配置一次。

除了这个设置以外,为了保证接收方信任你从 Gmail
代发的邮件确实来自于你的域名,还需要在 DNS 设置中添加 SPF 记录和 DMARC
记录。SPF 记录的格式为: 1
2
3
4
5TXT
alicelab.uk
Tv=spf1 include:_spf.google.com ~all
# # 如果你上面已经有了 Cloudflare 为了代收加上的 SPF 记录了,就直接把他改成
# v=spf1 include:_spf.mx.cloudflare.net include:_spf.google.com ~all
DMARC 记录的格式为: 1
2
3TXT
_dmarc.alicelab.uk
v=DMARC1; p=none; rua=mailto:[email protected];
总结
本文记录了我在自建服务器过程中使用的异地组网和内网穿透的方案,以及一些常见服务的部署方法。通过使用 Zerotier 和 Cloudflare Tunnel,我能够在不同地点访问我的服务器,并且将我的服务有选择的、带权限管理地暴露到公网。这对于没有公网IP的家庭用户来说,只需要一个公网云服务器中转便可以实现局域互联互通同时通过其他途径不暴露公网地址地提供服务。同时也以外发现了还有 Email Routing 和 Gmail SMTP 代发的组合可以实现自有域名的邮件收发服务。
参考资料
- Docker-Zerotier-Planet: 一分钟私有部署zerotier-planet服务
- 如何禁用戴尔笔记本电脑的 Ubuntu 或 Red Hat Linux 7 的睡眠和配置盖板电源设置
- Prevent suspend when lid close in Fedora 40
- CloudFlare Tunnel 免费内网穿透的简明教程
- Cloudflare Zero Trust:Cloudflare Tunnel使用教程- 资源荟萃
- Cloudflare Docs: Cloudflare Tunnel
- [Cloudflare]利用Cloudflare的電子郵件路由(Email Routing)功能,使Gmail可以寄送自我網域的郵件