在HomeLab中搭建网站服务的时候,例如博客,网盘等等,我们通常会走非标端口把这些服务暴露出去,然后在外面套一层比如cloudflare端口回源,或者买个大带宽大流量的vps反代。

这样就可以使用域名+https标准端口优雅地访问网站了。暴露外网对自己外出方便,对分享别人也方便。但是对于网盘,镜像站这种流量类业务,外网暴露只是让它可以在外面被访问,有时候我们在内网如果用域名去访问也免不了从外网绕一圈,费流量还减速。

这时候可能你想问:为什么不用内网地址直接访问?

这确实是个解决方案,但是这样就会搞出两个地址,例如一个https://192.168.1.20:8080,一个https://disk.domain.com。

或许你不想把服务暴露出来,这样也就不用看这篇文章了。

缺点

  • 你要想着在不同的网络环境用不同的地址去访问,这一点我是觉得不舒服的。

  • 而且有些web服务,浏览器会根据主机名在本地储存一些数据,换个地址又没了。

  • 如果是镜像站,网盘挂载之类的服务,我们需要在终端配置这些地址,假如我在笔记本上配置了我自己的内网pypi镜像站,我出门后这个地址就无法访问了,我又要重新切换地址,这样也很不优雅和便利。

开始搭建web服务器

我选择了更轻量的Caddy作为内网统一web网关

由于内网k8s和docker运行了一堆容器,启动了无数个nginx containers,再开一个nginx有种在电脑上装一堆chromium based应用程序的感觉。此外,Ubuntu默认安装了Apache2作为web内置的服务器占用了80和443,最好是扬了。

大部分发行版都可以从包管理器获得caddy软件包,比如Ubuntu,直接sudo apt install caddy就行,会帮你安装好caddy并创建服务。

TLS自动化

如果你想自动管理证书,可以使用本方法,或者你自己手动配置证书也可(不方便,不推荐)

Caddy官网下载页找到你域名DNS服务商对应的Caddy模块添加打包下载二进制,然后用这个下载的二进制去替换之前通过包管理器安装的caddy,通常位于/usr/bin/caddy/bin/caddy

我这里是Cloudflare DNS,编辑一下Caddyfile,很简单,一般位于/etc/caddy/Caddyfile

*.domain.com, *.domain2.com {  # 这里可以换成你的域名,支持多个
    tls {
        dns cloudflare api_token {your-api-token}  # 这里填写API token
        resolvers 1.1.1.1
    }
    reverse_proxy 192.168.1.20:8080
}

这个api-token在https://dash.cloudflare.com/profile/api-tokens获取,要有以下两个权限

这个令牌将被用于申请证书DNS Challenge时修改DNS记录用

保存Caddyfile,然后sudo systemctl restart caddy 重启caddy进程,可以使用sudo systemctl status caddy 看一下证书有没有正常申请下来。

其他DNS服务商请参照模块文档进行配置,应该都差不多的

自定义hosts

修改本机/etc/hosts

自定义hosts很简单,方案也很多,最简单的就是修改/etc/hosts (unix和类unix系统可用,Windows自己查阅一下对应的hosts文件即可)在里面添加新的行,像192.168.1.20 disk.domain.com这样,当你在请求https://disk.domain.com的时候,hostname会在本地就解析为192.168.1.20这个地址。这种方式也有缺点,服务多了,不好多设备同步。

内网统一DNS服务器

一般来说路由器DHCP服务器会自动给设备下发DNS服务器,通常是路由器网关地址,它本身也是一个DNS服务器,我们可以在路由器上修改hosts,只要内网设备的主要dns是路由器的话,那就可以通过路由器定义的hosts进行解析,方法和上面修改本机的差不多,有的路由器在luci界面就可以修改,更方便。

代理工具配置hosts

为了方便回家,我在家里搭了一个VPN,连上这个VPN后可以直接使用内网地址访问家里服务器的资源,我们可以配置一下代理工具,让它在连上家里VPN时,在本地起一个DNS服务器,自动解析主机到内网地址。如果你代理工具是mihomo内核,可以在hosts处配置这个,https://wiki.metacubex.one/config/dns/hosts/。然后托管一份yaml文件在云端(可以是GitHub),这样不仅在内网,外网均可生效。而且通过云端托管静态文件,修改之后方便多设备同步,是我目前在用的一个觉得最为优雅的方案

最后

配置好了之后,我们就可以在任何地方通过域名+https直接访问家里的资源了,在内网可以享受内网的速度,也不用使用http+IP+端口号这样不优雅的方式了。且VPN连接时(如果有)还可以通过代理软件的hosts进行解析和访问。