家庭宽带环境下使用 caddy 反代内网中的服务
在家庭宽带环境下,如果拥有一个公网 ip 地址,可以使用 caddy 反代内网中的服务,并绑定不同的域名,暴露在公网上。
此处使用的是 caddy 和 CloudFlare,如果使用 nginx 或者其他 DNS 服务商,可以参考原理。
- 必要的
- 使用 nginx 或者 caddy 搭建一个 web 服务器
- 配置 web 服务器反向代理内网中的服务
- 可选的
- 动态 dns(ddns)是可选的,ddns 的目的是为了监测公网 ip 的变化,并通知 DNS 服务商更新域名解析。这个步骤可以手动完成,只是有点麻烦。
- 自动申请证书是可选的。nginx 或者 caddy 都支持配置自定义证书。
问题情景
假设内网里有两台服务器,ip 分别是 192.168.1.2 和 192.168.1.3。
- 192.168.1.2,此服务器上运行的是 web 服务 (caddy 或者 nginx),监听 443 端口。
- 192.168.1.3 上跑了两个服务:
- movie 服务,监听的端口是 8001
- music 服务,监听的端口是 8002
配置 caddy 反向代理
caddy 的配置文件通常在 /etc/caddy/Caddyfile
,需要增加如下配置:
配置 SSL 证书
如果已有 SSl 证书,caddy 和 nginx 都提供了自定义证书的功能。此处使用的是 caddy 自动申请 SSL 证书。
caddy 使用 Let’s Encrypt 或 ZeroSSL 来申请免费的证书,需要 443 端口能够正常访问。如果 443 端口不能访问,就需要用 API 的方式。需要在安装 caddy 的时候,附加上 caddy-dns/cloudflare 模块。
配置域名解析
在域名服务商管理面板中,设置两个 A 记录,把 movie.example.com 和 music.example.com 都解析到家庭公网 ip。
配置路由器端口转发
由于家庭宽带公网 ip 通常被绑定在路由器上,所以需要做一个端口映射。打开路由器的管理页面(以电信天翼的为例),找到高级设置→端口映射。
当 https://movie.example.com:8080
或者 https://music.example.com:8080
被访问时(本质访问的是路由器),路由器会把流量转发到 192.168.1.2(caddy 服务器)上,由 caddy 统一接管流量。由于 caddy 服务器中配置了反向代理规则,caddy 会根据不同的域名找到对应的服务,即 https://movie.example.com:8080
对应 http://192.168.1.3:8001
,https://music.example.com:8080
对应 http://192.168.1.3:8002
。
到此为止,流程已经结束。
额外事项
安装带有 cloudflare-dns 的 caddy
有些步骤需要用户具备一定的 linux 知识,涉及 linux 相关的内容,不一一赘述。
方法一,官网下载
打开 caddy 下载页面,搜索 dns,并勾选 caddy-dns/cluodflare
模块(如果使用的是其他 DNS 服务商,则需要选择别的模块),点击下载即可
方法二,使用 xcaddy 构建
此步骤参考:https://caddyserver.com/docs/build#xcaddy
- 先下载 xcaddy
- 执行
xcaddy build --with github.com/caddy-dns/cloudflare
编译带有caddy-dns/cloudflare
的 caddy
把得到的二进制文件放到服务器上,并赋予可执行的权限,执行 caddy
即可。也可以使用 systemd
、pm2
或者 supervisor
等,来管理 caddy 服务。
caddy-dns/cluodflare 模块的作用
默认情况下,caddy 自带的 Let’s Encrypt 或 ZeroSSL 申请证书,需要 caddy web 服务器的 443 端口能够正常访问。此模块可以在 443 端口不可用的情况下,让 caddy 自带的 Let’s Encrypt 或 ZeroSSL 与 CloudFlare 建立通信,从而能够成功申请 SSL 证书。
如果使用自定义证书,则可以忽略 addy-dns/cluodflare 模块
caddy 配置文件
在配置文件中增加 TLS 配置,参考:https://caddyserver.com/docs/caddyfile/directives/tls#examples
{{token}}
需要替换为真实的 token,如何申请 token,参考 CloudFlare 官方文档。在使用 acme.sh 给群晖申请 SSL 证书笔记中,也提到了如何使用 CloudFlare 的 token 申请证书。
如何重启 caddy
- 更新了 Caddyfile 之后,需要执行
caddy adapt --config /path/to/Caddyfile
,让 caddy 重新加载配置文件 - 如果使用
systemd
管理 caddy,则执行systemctl restart caddy
。如果pm2
或者supervisor
管理 caddy,则需要执行别的命令
动态 dns
市面上的 ddns 工具比较多,也可以自己写个脚本来处理。此处推荐几个:
- 路由器自带
- ddns-go
- mholt/caddy-dynamicdns,此模块可以自动扫描 caddy 配置中的域名,并给域名添加解析记录