Caddy2 踩坑指北
前言
利用这个国庆假期,将威盒网站+服务端迁移到新的服务器上。
全部服务容器化,利用Docker进行部署。
网站
由于多年前网站全部使用php编写,除了不同的网站需要的php版本不同外,没有什么坑。使用webdevops/php-nginx镜像进行部署。
这个镜像有有比较详细的文档
可以直接通过环境变量修改配置文件中的关键内容
主要的环境变量配置:
WEB_DOCUMENT_INDEX 覆盖nginx配置文件中index配置项
WEB_DOCUMENT_ROOT 覆盖nginx配置文件中ROOT配置项
一个容器配置一个网站。使用Docker-compose来管理所有的容器(别问我为啥不用k8s,访问量没这么大)
Caddy2
本次使用Caady2进行反向代理,由Caddy2吧不同的域名转发到不同的容器中。同时Caddy2自动进行ssl证书的申请和续期。
但是!caddy2最低支持TLS1.2协议!这里就为下面留下了坑。
贴一下Caddyfile例子
1 | store.vlabpro.com { |
把全部网站配置部署之后。通过浏览器测试网站以及威盒的api正常。之后就以为结束了。
proxy protocol
问题
过了一天,我查看威盒的统计系统,发现没有任何使用记录。就感觉有一点不对劲,打开威盒,发现全部是无网络连接。于是临时将反代切换成nginx,威盒正常。
然后排查各种问题,初步怀疑到证书和TLS版本的问题。最后排除法确认是TLS版本问题
因为威盒已经停止更新多年了,并不支持TLS1.2。
caddy2删除了对TLS1.2以下版本的支持,强制使用者使用TLS1.2以上的版本。
但是!我们已经不可能为了支持TLS1.2去升级威盒,发布新的版本,只能去找兼容性的方案。
本来使用Caddy2就是为了全自动申请证书的功能(之前自动申请Let’s Encrypt证书的脚本过于不稳定,经常发生证书过期的问题)
只有一个容器可以监听443端口,而且caddy2监听443会拒绝威盒服务器的连接。
Nginx 开启
经过和酱哥讨论通过Nginx的L4的反向代理,在不对https请求解包的情况下,通过sni按照域名区分,把tcp请求直接转发到不同的容器中。
这样就有一个问题,就会导致被转发的容器无法获取到用户真实的ip。再次查询资料后得知nginx支持proxy_protocol协议,通过为tcp添加一个很小的头信息,来方便的传递客户端信息(协议栈、源IP、目的IP、源端口、目的端口等),在网络情况复杂又需要获取用户真实IP时非常有用。其本质是在三次握手结束后由代理在连接中插入了一个携带了原始连接四元组信息的数据包。
proxy protocol 插入配置
1 | stream { |
proxy protocol 接收配置
1 | http { |
最终Nginx配置大概是这样的:
1 | ... |
Caddy2 编译
再次测试,发现威盒服务端正常,但是网站全部打不开。
原因Caddy2并没有打开proxy protocol,caddy2无法解析添加了proxy protocol协议后的tcp请求。
好在caddy2有插件可以支持proxy protocol,但是需要我去手动编译一个caddy2,官方也提供的教程
1 | FROM caddy:builder AS builder |
这样就编译出来带proxy protocol插件的caddy2镜像
在caddyfile 最上面添加全局配置,开启proxy protocol插件
1 | { |
总结
网站
网站的请求的转发顺序是这样
Nginx =》 Caddy2 =》 对应网站的容器
这里的Nginx不会对https请求进行解包,直接把tcp请求转发给caddy2,所有的处理都在caddy上
客户端
客户端请求的顺序是这样
Nginx = 》 服务端容器
这里的nginx会吧https进行解包处理
至此,威盒的服务器迁移成功!
