背景
随着 Mythos 等一系列网络安全特化模型的发布,人类网络距离赛博朋克中的流窜AI时代又迈进了一步。为了尽可能减少攻击面,我决定,把服务器上所有入站端口都关了,是的,包括 80 和 443 的所有端口。不过既然你还在访问我的博客,就说明我的服务器都还在正常对外服务,主播怎么回事呢?不是都关了吗?
本文主要分享我基于 Cloudflare Zero Trust 构建的方案,可以实现以下效果:
- 阻止所有协议和端口的服务器入站请求(TCP、UDP、ICMP等)
- 所有HTTP服务仍可通过域名正常公网访问
- 免疫针对IP的所有网络层的外部攻击(应用层就是自己的事了)
最终实现的效果是,服务器IP不仅ping不通,通过 nmap 扫描65536个端口一个都访问不了,看起来就像是查无此人。但是服务器内的所有网站均可通过域名正常访问,非标准的TCP、UDP流量也可以通过VPN在可信域之内通信,如果你的数据库需要从不支持VPN的 serverless 服务访问,文后也会提供解决方案。
另外如果你的服务器在国内且没有备案,也可以通过这个方法强开 http 访问。
通过 Cloudflare Tunnel 构建安全信道
这里假设你的域名已经透过 Cloudflare 进行托管,如果你还没有使用 Cloudflare,你将会须要迁移域名至 Cloudflare。
这是关闭所有入站流量最关键的一步,所有的用户流量都通过 Cloudflare 边缘网络转发到服务器,那么只要转换Cloudflare与服务器的连接思路就好了。与其在服务器上开着80、443端口等着 Cloudflare 边缘网络的连接,不如主动向 Cloudflare 边缘网络发起连接,如此便可将入站变成出站,而这就是接下来 Cloudflare Connector 所做的事情。
传统 Full (Strict) 连接
使用 Cloudflare Tunnel 连接
部署 Cloudflare Connector
https://dash.cloudflare.com/one
登录 Cloudflare One,进入 Network → Connectors 页面,点击 Create Connector 创建一个新的 Connector,选择 Cloudflared,名称可以随意设置。
接下来需要在服务器上安装 Cloudflared,根据自己的操作系统选择即可,也可以通过 Docker 安装,直接按照说明的指令在服务器上执行即可。
运行后等待连接完成,即可进入下一步。
配置外部路由
在 Published application routes 中新建一个新的路由,访问配置的子域名时,会自动被转发到下方配置的 Service 中的IP,一般类型选择 HTTP,URL填写 localhost:本地服务端口,使用 traefik 或其他反代时,直接填写 localhost:80 即可。若选择了非 HTTP(s),则无法通过域名公共访问,具体的访问方法后面会详细提到。
注意:这个请求会由服务器端的 cloudflared 程序发起(对于服务端应用而言,源IP会来自服务器本机回环,且可以访问仅绑定到本机127.0.0.1回环的服务),部分应用层的防火墙可能看见源ip来自本机会直接放行,这一点需要留意。同时这里也不需要使用 https,因为这个http流量完全是在服务器本地走的,出服务器会走由 Connector 与边缘网络构建的 TLS 链接,仅在服务端服务仅接受 https 连接时才选择 https。
创建 Published application routes
填写参数
至此已经可以通过配置的域名直接访问服务器上的应用程序,浏览器到Cloudflare,Cloudflare到服务器的链路均为加密链接,且由于不再依赖公网端口,相比 Full (Strict) 加密模式更安全。
关闭所有入站端口
直接在云服务提供商的防火墙中禁止所有入站请求即可,如果云服务提供商不提供防火墙功能,在主机端也可以配置 UFW,不过在关闭之前需要先通过可靠的 VPN 建立 SSH 通道,以避免无法访问主机。
至此你的服务器IP已经免疫了所有来自网络层的外部攻击。(服务器IP已经毫无用处了)
配置其他服务
配置 SSH 连接
TODO
配置任意非 HTTP 服务
TODO
通过 Hyperdrive 配置数据库连接
TODO
