混合云架构下的动态 IPv6 智能加速实践:从家庭网络到全球分发的低成本部署指南
此文也作为本站网络架构分享
图片是架构完全体展示
(图片可点击后放大查看)
- 图片中“阿里云服务器”可以换为其他任意有公网 IPv4 的云服务器
- 灵活参考,实际部署可以仅采取其中部分线路
- 欢迎评论区留言讨论
图像生成源码
@startuml
left to right direction
actor 访客 as visitor
package "互联网" {
note "博客域名" as blog_address #orange
node "DNS服务器" as dns {
component "境内 cname 解析" as cname_cn
component "境外 cname 解析" as cname_intl
}
}
node "境内CDN" as cdn #lightblue {
component "CDN提供的域名" as cdn_address #orange
component "主回源地址\n(填写阿里云服务器IPv4地址)" as primary_origin #lightblue
component "备用回源地址\n(填写CF提供的泛播域名)" as backup_origin #lightblue
}
node "阿里云服务器" as aliyun {
component "FRP服务端" as frps #palegreen {
component "四层转发" as layer4_forwarding #palegreen
}
}
node "家庭网络" as home {
component "FRP客户端" as frpc #palegreen
component "服务器" as home_server_1 {
note "实际部署中,这是一台树莓派3b+" as raspberry_pi_note #yellow
component "Nginx" as home_nginx #pink {
component "SSL证书\nacme自动续期" as ssl_cert #pink
}
component "动态公网IPv6" as ipv6
component "ddnsgo服务" as ddnsgo
}
component "其他内网服务器" as internal_server
}
node "Cloudflare" as cf #skyblue {
note "CF要求: SaaS回源域名(回退源)是一个在 Cloudflare 的 DNS 管理区域中创建的,并且启用了 Cloudflare 的代理功能的域名" as cf_note #yellow
component "CF提供的泛播域名" as anycast_address #orange
component "DNS托管" as cf_dns #skyblue {
component "SaaS回源域名\nAAAA记录" as aaaa_record #skyblue
}
}
note "SaaS回源域名\n已开启CF代理\n(IPv4/IPv6双栈)" as saas_origin_address #orange
visitor --> blog_address : 访问博客
blog_address --> dns : DNS查询
dns --> cname_cn : 境内解析分流
dns --> cname_intl : 境外解析分流
cname_cn --> cdn_address : 境内流量
cdn_address --> primary_origin : 主回源
primary_origin --> frps : HTTPS回源\n(443)
frps --> layer4_forwarding : 四层转发\n(TCP)
layer4_forwarding --> frpc : FRP隧道\n(7000等端口)
frpc --> home_nginx : 本地转发\n(443)
cdn_address --> backup_origin : 备用回源
backup_origin --> anycast_address : 回源请求
anycast_address --> saas_origin_address : 根据Host头,回源到SaaS回源地址
aaaa_record --> home_nginx : HTTPS回源\n(443)
cname_intl --> anycast_address : 境外流量
saas_origin_address -> aaaa_record
ipv6 <-- ddnsgo : 监测变化
ddnsgo --> aaaa_record : 更新AAAA记录
home_nginx --> ssl_cert
ssl_cert --> internal_server : 根据Host头反向代理\nHTTP转发(80)
aliyun -[hidden]-> cf
@enduml
完全体架构优势
-
成本低
- 额外成本
- 第二域名(一年换一个都行,哪个价格低选哪个)
- 非额外成本
- 主域名
- 云服务器(ICP 备案时用的那个服务器即可)(我使用的是阿里云一年 99 元的服务器)
- 国内 CDN(ICP 备案后可以直接免费用,小站免费额度够用)
- 额外成本
-
访问速度快
- 最佳状态:国内 CDN + 回源到自建 frp 服务
- 部分故障:国内 CDN + 回源到 Cloudflare(自建 frp 服务/云服务器出现故障:导致回源速度减慢)
- 严重故障:Cloudflare 直接代理(境内 CDN 被攻击到流量上限/境内 CDN 无法使用:切换 DNS 全走 Cloudflare 路径)
-
隐藏源 IP 防范 DDoS 攻击
- 云服务器源站 IPv4 仅有国内 CDN 知道
- 家里云源 IPv6 仅有 Cloudflare 知道
-
智能分流抗攻击
- 国内流量走国内 CDN
- 国外流量走 Cloudflare:利用 Cloudflare 提供应用防火墙能力
-
稳定性好
- 多路径
-
DNS 国内外分流解析
- 针对性加速国内外流量,加快访问速度。
- 借助免费的 Cloudflare 服务做防火墙抵御境外 DDOS 攻击。
- 配合脚本可保证在国内 CDN 失效情况下自动容灾切换,保证站点可访问性。相关文章:脚本分享:CDN 流量触顶后自动切换至 Cloudflare
-
CDN 主备双回源机制实现在 frp 服务不可用的情况下自动容灾切换。
-
- 即使家里云源头出现故障,也能让站点保持可访问状态
- 可启用 Cloudflare Always Online 功能
- 如果全站缓存进了 CDN(包括页面文档),那即使源出现故障,也可以访问页面
- 多路径
-
家里云实现零成本服务器托管,不受限于云服务器羸弱的性能以及较低的带宽
-
安全合规架构
- 全链路 HTTPS 加密
-
可满足国内备案合规性要求
-
其他优势
- 自动申请/续期 SSL 证书。本地部署到位后,唯一需要同步的地方是国内 CDN。减少运维复杂度,降低泄露风险。(同步到国内 CDN 可以手动/使用工具自动同步)(可自动申请/同步到 CDN 的工具举例:Certimate,CertD)
- 本地新增服务操作简易,仅需要在本地 Nginx 新增反向代理即可。(Nginx 根据主机头(Host 头)区分不同流量,进行反向代理)
建设前需要了解的一些知识
此部分属于知识点同步,并不是部署资源要求。
- 我的目的地为家里的电脑,没有公网 IPv4,但有公网动态 IPv6
- ICP 备案后有免费境内 CDN 可用
- 免费 CDN 支持 IPv4 地址回源,IPv6 地址回源,域名回源(不支持解析到 IPv6 地址的域名)
- 一般来说为了 ICP 备案,会买一台性能羸弱,带宽极小的云服务器
- Cloudflare 启用代理可将 IPv6 only 转换为 IPv4+IPv6 双栈
- 很多人没有 IPv6 只有 IPv4,所以 IPv6 Only 会让很多人无法访问
- 自建免费的 ddnsgo 服务可以自动将家里的公网动态 IPv6 绑定到域名上
- 四层转发(TCP)可以直接转发 HTTPS 流量,无需部署 SSL 证书在用于转发的服务器上
- 阿里云会检测 HTTP 明文流量:host 头域名没 ICP 备案,被阿里云检测到会拦掉然后出现一个页面提醒你备案。
- frps 的状态面板,本地 Nginx 网关的日志,都是用来观察是否成功配置转发的好工具。
- 我没找到好用的直接修改 Host 头的浏览器插件,于是巧用本地 hosts 文件修改测试转发是否正常工作。(hosts 文件填云服务器地址用于测试 frp 转发是否可用。hosts 文件填网关 Nginx 地址测本地转发是否可用)
- 本站文章有目录功能
路线 A
最简单的路线,就是用 ICP 备案时的云服务器自建一个 frp 服务器。
云服务器部署 frps 软件,本地部署 frpc 软件。
通过 ICP 备案后可免费使用的国内 CDN 或者直接 DNS 解析到云服务器即可访问站点。
具体如何建设不多阐述,网上相关教程很多,这并不是本文的重点。
要逐步建设上面“完全体”,请看路线 B。
路线 B 第一步 - 最基础的建设方案
这一步需要的资源:主域名、能访问上 Cloudflare 后台、本地部署 DDNS-GO 服务
- 主域名 CDN 托管到 Cloudflare
- 本地部署 DDNS-GO 绑定域名甲,指向本地动态公网 IPv6(这个 IPv6 可以直接是你部署网站的服务器,也可以是你的网关关 Nginx)
- 域名甲是属于主域名的一个子域名(当然也可以是 @)
- 测试 IPv6 是否可访问方法:直接在浏览器输入 [你的公网 ipv6]:80 进行访问测试
- 相关文章 通过指令过滤出正确的公网 ipv6 地址
- 启用 Cloudflare 代理,将 IPv6 Only 转换为 IPv4+IPv6 双栈
必要步骤:本地部署 SSL 证书
注:你可以自己部署能免费自动申请 SSL 证书的服务,来避免 SSL 证书过期,如:宝塔面板自动申请、1Panel 面板自动申请、acme.sh、CertD、Certimate 等
- 本地动态公网 IPv6 指向的服务器要保证已部署 SSL
- Cloudflare 面板中,SSL/TLS 设置要设置为“完全(严格)”或“完全”。
- 如果你设置为“灵活”,要保证本地动态公网 IPv6 指向的服务器能通过 HTTP 回源(比如相关设置要设定为“HTTP 可直接访问”而不是“HTTP 自动跳转为 HTTPS”,后者会导致“重定向次数过多”错误)
看起来很美好,可惜国内访问速度及其慢(3s+反应速度,传输速率低)
路线 B 第二步 - ICP 备案后用免费国内 CDN 加速
这一步需要的资源:完成域名 ICP 备案
注:域名甲、域名乙均为主域名的子域名(当然也可以是 @)
- 打开多吉云\又拍云(或其他能免费使用的国内 CDN),准备加速域名甲,回源设置为域名乙(上面的 DDNS-GO 绑定也要改成域名乙
- 原本域名甲的 cname 解析设置为 CDN 提供的域名
配置注意点:域名乙一定要启用 Cloudflare 代理,将 IPv6 only 转换为 IPv4+IPv6 双栈。这些 CDN 明确说明设置域名回源时,不支持解析到 IPv6 Only 的域名。
在国内 CDN 加速的效果下:除了第一次访问需要回源,速度较慢,后续访问可以用秒开来形容。
注意:如果你 CDN 配置的合适,全部的资源,包括页面的文档(Chrome DevTools 的 network 中显示为 document)也能被 CDN 缓存分发。那么到这一步你的站点网络访问情况就非常好了。再通过精妙的设置定期回源刷新,或者手动去 CDN 后台管理进行刷新和预热,那体验可以非常棒了。
路线 B 第三步 - 使用闲置的服务器自建 Frp 加速回源
这一步需要的资源:一台有公网 IPv4 的云服务器(能部署 frps 即可)、本地部署 frpc 服务
- 云服务器上部署 frps 服务,本地部署好 frpc 服务
- 云服务器 443 和 80 端口让出来给 frps 用。frpc配置直接选择tcp 转发,本地 x.x.x.x:80 连接到远程端口 80 ,本地 x.x.x.x:443 连接到远程端口 443 。这样访问云服务器的 80 端口的流量就会转到本地 x.x.x.x:80 ,访问云服务器的 443 端口的流量就会转到本地网关 x.x.x.x:443
- 实测 Nginx stream 模块四层转发没成功转发443,实测只成功转发 80,如果你能配置成功,用 Nginx 做转发到 frps 服务也可以,就不需要 frps 服务占用 443 和 80 端口了
- 这个 x.x.x.x 可以直接是你部署网站的服务器,也可以是你的网关关 Nginx(如果 frpc 和网关 Nginx 部署在同一台机子上,直接换成 0.0.0.0 即可)
- CDN 设置 IPv4 回源,填服务器提供的公网 IPv4
- CDN 可以设置备用路线,设置为域名乙
- 本地配置 SSL 中间使用四层转发的好处就体现出来了。因为 CDN 要求主备回源协议一致。除非你是 Cloudflare 企业用户,否则 SSL/TLS 设置无法选择“严格(仅 SSL 源服务器拉取)”,这就要求你必须使用 HTTPS 协议回源
此时你 CDN 回源主要走自建的 frp 服务,反应速度已经相当快了。
同时 CDN 备用源走 Cloudflare 路线,保证在 frp 服务无法正常工作的情况下,站点也能正常回源。
现在唯一的问题是国外流量也会走国内 CDN,抗攻击能力和访问速度上还有待提高。
路线 B 第四步 - 通过自定义主机名(Cloudflare for SaaS)和国内 CDN 实现国内外分流
这一步需要的资源:第二个域名(可以选择非常便宜的域名后缀)、能访问上 Cloudflare 后台、能使用国内 CDN(比如阿里云 DNS、腾讯 DNSPod)
Cloudflare for SaaS 是怎么一回事
简单的说明:自定义主机名(Cloudflare for SaaS)保证你可以让 DNS 不托管在 Cloudflare 的域名能使用 Cloudflare 泛播,代理功能的服务。
情景模拟加深理解:假设这个 DNS 不托管在 Cloudflare 的域名叫域名 A。同时域名 B 的 DNS 托管在 Cloudflare 上。
域名 B 设置为 Cloudflare for SaaS 的回源域名(回退源),通过 a/aaaa 记录解析到实际的家庭服务器,然后启用 Cloudflare 代理功能(这是 Cloudflare 要求,回退源必须是一个在 Cloudflare 的 DNS 管理区域中创建的,并且启用了 Cloudflare 的代理功能的域名)。
域名 A 的 DNS 解析设置 cname 记录为 Cloudflare 泛播域名或 a 记录设置为 Cloudflare 泛播 IP(这就是所谓 Cloudflare 优选 IP 发挥作用的地方)。
当访客访问域名 A,DNS 解析后,实际访问 Cloudflare 泛播 IP/域名。Cloudflare 手动请求后,根据你的 Host 头(此处是域名 A),Cloudflare 就会把访客的流量导到实际的 SaaS 回源域名。再通过 SaaS 回源域名的 DNS 记录解析到实际的家庭服务器。
部署流程
- 购买的第二个域名托管 DNS 到 Cloudflare 上(建议用一个子域名用于回退,方便管理),DDNS-GO 将这个子域名(后用域名 C 指代这个子域名)的 AAAA 解析设定为实际的家庭服务器,并且开启 Cloudflare 代理(Cloudflare 要求)。
- 主域名托管到国内 DNS 上(国内 DNS 基本标配国内外分流功能)。
- 进入 Cloudflare 的管理面板,中你的第二个域名,找到 SSL/TLS(记得调整“概述”中“SSL/TLS 加密”情况,路线B第三步第四小步里已说过要点,不在此处重复叙述),下面的“自定义主机名”,“回退源”输入框下输入域名 C,“回退源状态:有效”就没问题。然后点击“添加自定义主机名”按钮,“自定义主机名”填写你的主域名,后面按需求填写,之后按照 Cloudflare 的要求在主域名 DNS 添加 TXT 记录验证即可。
- 主域名 DNS 设置境内 cname 解析到国内 CDN 提供的 cname 地址,境外解析到设置自定义主机名时 Cloudflare 提供的 cname 地址。
- CDN 设置备用路线设置为域名 C
恭喜你!如果做到这一步就已经完全部署完毕了,享受部署好的网络吧。
2