内网服务的自动分流,让内网走内网,公网走公网
序
因为轻量应用服务器开始承受不了immich的需求,上传图片的时候开始频繁卡顿。正好又是许久之前就有了组一台Nas的想法。在部署immich服务的内网和公网访问的时候遇到了一些问题。考虑到杂碎且后续可能频繁遇到,故在此记录。
现状与目标
现状
这是当前服务的访问情况,用户在公网发起请求,流量由nginx接管后按照域名规则,转发到本地的指定端口。在nginx上部署ssl和强制https。
展望
- 域名访问
- 全程HTTPS
- 内网环境自动走内网地址
因为部署immich的nas所处的网络环境没有公网ip,所以对于公网访问的情况,我们还需要部署frp来做流量转发。
这意味这内网访问和公网访问所走的链路是完全不同的。nginx、frp需要在内外网都部署。
画个图吧
从图看,实现分流的重要一步就是DNS解析。我们只需要在家中的路由器中设置别名或者直接劫持就行了。
接下来展一下其中可能会遇到的各种问题~
公网链路
Frp服务
我们先看公网链路,DNS之前就解析着这个服务器,不用修改,nginx的反向代理也不用修改,我们只需要撤下之前的immich服务,上线一个同样监听2283端口的frp服务即可。
最新的frp默认用了toml作为配置文件,不太常见。
frps
从github下载tar.gz,解压后编辑frps.toml
文件
1 |
|
修改token后面的值为随机字符串!记得加上双引号。
服务端的配置文件确实没啥好配置的,声明用于frp传输数据的端口和认证方式即可,注意在云服务器后台放行我们声明的7827端口。
然后我们可以启动frp服务,记得用tmux或者screen让它可以后台运行
1 |
|
frpc
我们重点编辑frp客户端的配置文件
1 |
|
修改token后面的值为frps.toml中设定的值!记得加上双引号。
修改serverAddr
字段为部署了服务器端的服务器的ip或者域名。
如果需要配置多个代理,只需要重复[[proxies]]
部分即可,比如我们再加一个Minecraft的转发,那么完整的toml配置为:
1 |
|
注册为systemd服务
考虑到未来需要的修改配置,重启frpc需求。我们还需要将其注册为systemd服务。
1 |
|
可以编辑为:
1 |
|
修改ExecStart
字段和ExecReload
字段的值为具体的文件路径。
记得给frpc文件赋予执行权限
1 |
|
重新加载systemd的配置文件
1 |
|
OK!让我们使用systemctl启动frpc服务。
1 |
|
至此,公网访问链路所有流程已完成部署。尝试直接在浏览中输入https://immich.coooolfan.com访问即可。
如果访问出现5**错误,或许是frp服务启动没有成功。
查看frpc服务状态
1 |
|
查看frpc服务实时日志
1 |
|
内网链路
内网DNS劫持
实现内网DNS劫持的方法有很多,这里采用的是主机名映射,直接在OpenWrt中配置对应的域名和ip即可。
公网环境下的DNS解析无须修改,因为我们本来就还要用这个服务器做流量转发。
获取SSL证书
因为我们需要全程HTTPS,所以内网访问还需要部署SSL证书。因为之前用的lnmp脚本,所以这还是第一次用acme相关的东西。
安装ACME
1 |
|
一键脚本安装就行了,如果有提示需要提前安装cron,那就先装上cron再重新安装acme。
刷新一下环境变量,不然用不了acme.sh命令
1 |
|
设置默认CA为Let’s Encrypt
1 |
|
从DNS服务商申请API并配置ACME
因为我们是在内网环境下申请SSL证书,所以只能使用DNS验证的方式验证域名的所有权。acme支持调用DNS服务商的API来自动化执行所有步骤。
acme支持超级多的DNS服务商,不同服务商需要配置的字段和其标志都不同,详情见https://github.com/acmesh-official/acme.sh/wiki/dnsapi
我们的DNS服务商是DNSPod,需要从其后台申请https://console.dnspod.cn/account/token/token
注意:DNSPod分cn和com;DNSPod的API和腾讯云API不一样,不要申请错了。
拿到ID和Token后,我们编辑acme的account.conf
文件
1 |
|
对于DNSPod,对应的字段为
1 |
|
然后尝试向证书服务商申请一个证书
1 |
|
如果证书申请成功,你会看到acme打印的各种东西。我们只会用到证书链fullchain.cer
和密钥immich.coooolfan.com.key
。
如果申请失败,查看日志,不要盲目重试,证书服务商一般会显示失败次数,过多的失败次数会出发rateLimited。
生成ssl_dhparam(可选)
这是一种用于密钥交换的加密算法。
我们直接生成一个
1 |
|
这个过程超级无敌慢!其实不生成也没事,后面的nginx删掉对应的一行就行了。
配置Nginx服务
新服务器,啥都没装,装一下
1 |
|
创建一个用于配置这个站点的配置文件
1 |
|
这东西好像也没啥要改的,公式化。
需要修改
- 两个server块的
server_name
字段为要监听的域名 ssl_certificate
、ssl_certificate_key
为之前acme输出的路径ssl_dhparam
为之前生成的dhparam文件的文字,如果没生成那就删掉这行location
块中的proxy_pass
为反向代理的目标地址
1 |
|
nginx默认并不会读取文件夹sites-available下的配置文件,我们需要对其创建一个软链接,让文件夹sites-enabled下也有一个一样的文件。
1 |
|
OK!让我们检查一下nginx的配置文件有没有出错
1 |
|
如果没有出错,重启nginx即可
1 |
|
至此,内网访问链路所有流程已完成部署。尝试直接在浏览中输入https://immich.coooolfan.com访问即可。
碎碎念
同一个域名解析得到不同的证书或许不是最佳实践,集中式的证书管理获取是更好的选择,有机会再说吧。