使用 CDN 自建中继服务
CDN 实现流量中继
如今,许多中继服务都存在,但它们无法确保你的数据安全。大约 10% 的网站仍在使用 HTTP,发往这些网站的流量对中继提供商来说是透明的。我不信任任何公共中继服务。自建中继服务是一个很好的替代方案。
架构
单服务器。 你可以选择任何你喜欢的中继协议,并将其部署在可信的服务器上。然而,依赖单一源是危险的。例如,你的 ISP 可能会阻断流向未授权服务器的大量流量。此外,当你到不同地区旅行时,体验可能会有所不同。
多服务器。 将你的中继服务部署到不同位置的多个服务器可能是一个解决方案。作为参考,许多公共中继服务在其他地区都有很多服务器。然而,这样的解决方案成本更高。
带 CDN 的单服务器。 幸运的是,CDN 可以提供大量我们可以利用的服务器。我找到了一种在 CDN 帮助下构建自建中继服务的方法。最终,我们将拥有一个受益于 CDN 快速传输的中继服务,并具有其他优势:
- 无阻断
- 成本节约
- 可靠性增强
CDN 如何为我们工作
内容分发网络(CDN)
内容分发网络(CDN)是指地理分布的服务器组,它们协同工作以提供互联网内容的快速传输。
CDN 在邻近服务器(节点)上缓存网站资产,以在不同地区提供更好的网络体验。如果 CDN 节点没有缓存响应资产或缓存已过期,它将返回源站点获取。
作为虫洞。 CDN 在我们的中继服务中扮演虫洞的角色,这意味着它作为设备和我们服务器之间的快捷方式。由于某些原因,流向我们服务器的流量可能会拥塞甚至被阻断。我们希望 CDN 作为具有更好质量和安全性的端到端通道来转发流量。
适合的协议
CDN 不会转发它接收到的每个数据包。许多云服务提供商只允许他们的 CDN 处理 HTTP 和 HTTPS 协议。此外,他们可能还支持 WS(WebSocket)和 WSS(基于 SSL/TLS 的 WebSocket),因为许多网站使用它们作为标准通信协议。
我们应该明智地选择中继协议以实现最大的 CDN 兼容性和安全性。协议必须依赖 HTTP (S)/WS (S)。Trojan和Vmess是两个流行的基于 WS 的协议。在这篇文章中,我将使用它们来演示我们的服务如何工作。
无缓存策略
我们不希望 CDN 缓存任何内容,因为我们中继的是私人流量。换句话说,我们希望每个资产都立即过期,这不是 CDN 应该工作的方式。实际上,我们故意滥用CDN 来帮助我们的中继服务。
由于 WebSocket 是有状态协议,Trojan 和 Vmess 不会受到缓存策略的影响。但如果你选择基于无状态 HTTP/HTTPS 的协议,记住要正确配置缓存策略。
因此,设备上的中继应用程序将流量包装成 Trojan/Vmess 数据包,然后用 WebSocket 打包并发送到 CDN。CDN 将使用回源策略将数据包转发到我们的服务器。
网络质量
许多中继服务受到拥塞线路的困扰。一些 "专业版" 服务使用更好的公共线路来解决拥塞问题。你可能听说过 CN2 GIA、IPLC 或类似的公共线路。但还有更多线路,如 AWS(亚马逊)和 Azure(微软),这些线路不对公众开放。我们使用 CDN 的中继服务可以利用这些私有线路来获得更好的网络质量。
流量可以使用专用 CDN 通道,而不是两个地区之间的公共线路。此外,如果我们选择同一云服务提供的服务器和 CDN,我们可以免费获得专用回源线路。
反阻断。 ISP 不太可能阻断流向邻近 CDN 节点的流量,因为它们是对所有用户的标准服务。模式识别阻断算法不会起作用,因为它们看起来就像带有 TLS 加密的常规 WebSocket 流量。ISP 不会监督邻近 CDN 节点之后的流量。
安全性
我们不信任任何公共中继服务,因为对我们来说它们是黑盒子。在我们的自建中继服务中,安全性是首要目标。
TLS。 为了确保 ISP 无法监控流量,我们使用 TLS 加密来保证 WebSocket 数据包安全地传输到邻近 CDN 节点。CDN 将解密 TLS 流量并获取 WebSocket 数据包。
AEAD。 CDN 可能能够扫描我们数据包中的信息。这就是为什么我们用 AEAD 加密流量。AEAD 是 VMess/Trojan 协议支持的用于加密原始 TCP/UDP 数据包的对称加密算法。
如果这样做,我们将有一个未加密的 WebSocket 数据包,包含 VMess/Trojan 载荷,这是可识别的。所以对整个 WebSocket 数据包进行混淆是必要的。
如果我们信任云服务提供商,AEAD 是不必要的。例如,我使用AWS,它提供CloudFront服务和 EC2 实例。我相信亚马逊不会扫描我的流量,CloudFront 和 EC2 之间的私有链接不容易受到攻击。所以在链接上禁用了 AEAD。此外,我也不需要在私有链接上使用 TLS。
动手实践
如果我们理解其原理,使用 CDN 构建自建中继服务很简单。在开始之前,让我们做最后检查。
在以下步骤中,我将使用:
- AWS EC2 作为远程服务器
- AWS CloudFront 作为 CDN 服务
- Vmess 作为中继协议
- Xray 作为服务器应用
- Clash 作为客户端应用
服务器配置
首先,我们需要配置我们的服务器来开启基于 Vmess-over-WebSocket 的中继服务。我偏好使用xray提供的 docker 镜像。
mkdir ~/xray
vim ~/xray/config.json
docker run -d -v ~/xray:/etc/xray --network=host --restart=always teddysun/xray
配置 JSON 文件应该像这样:
{
"inbounds": [
{
"port": 10090,
"protocol": "vmess",
"settings": {
"clients": [
{
"id": "49dd2152-17af-436b-8539-fe6adff56529",
"alterId": 0
}
]
},
"streamSettings": {
"network": "ws",
"wsSettings": {
"path": "/api/v1"
}
}
}
],
"outbounds": [
{
"protocol": "freedom",
"settings": {}
}
]
}
你应该使用UUID 生成器来生成你的唯一 ID,并将49dd2152-17af-436b-8539-fe6adff56529
替换掉。你也可以将 WS 路径/api/v1
和端口号10090
改为任何你喜欢的。
CDN 配置
获取 SSL 证书。 由于设备和 CDN 之间的通信使用 TLS,我们需要获取 SSL 证书。我使用 AWS Certificate Manager 来获取证书。这很简单,你可以获得一组域名的证书(例如,*.cdn.whexy.com
)而不是一个特定域名。
CDN 设置。 之后,我们可以配置我们的 CDN。使用适当的域名,如gobear.cdn.whexy.com
作为备用 CNAME,并使用我们之前获得的相应证书。将 HTTP 端口更改为 10090,作为我们服务的端口号。你将在后面获得一个 CDN 特定的域名(例如,tkn.cloudfront.net
)。
DNS 设置。 转到你域名的 DNS 设置。添加一个指向 CDN 特定域名的gobear.cdn.whexy.com
的 CNAME 记录。
设备配置
我使用 Clash 作为客户端。使用以下配置作为连接到我们服务器的例子:
- {
name: CDN-relay,
server: gobear.cdn.whexy.com,
port: 443,
type: vmess,
uuid: 49dd2152-17af-436b-8539-fe6adff56529,
alterId: 0,
tls: true,
skip-cert-verify: true,
network: ws,
ws-opts:
{ path: /api/v1, headers: { Host: gobear.cdn.whexy.com } },
udp: true,
}
还有一件事:IP 池
现在我们有了一个带 CDN 的自建中继服务。客户端将在地理域名解析服务(DNS)的帮助下自动连接到最近的CDN 节点。
然而,我们不应该依赖地理 DNS,因为它不会总是回复最快节点的地址。如果我们知道 CDN 节点的 IP 列表,我们可以使用客户端应用来进行速度测试。
为此,在客户端配置文件中将server
字段替换为 CDN 节点的 IP 地址。我不会在这篇文章中解释如何获取地址列表。所以我将把那部分留给你完成。
CDN 实现流量中继
© LICENSED UNDER CC BY-NC-SA 4.0