前言
换了条宽带,现在我拥有动态的公网IPV4地址了
我打算暴露一些服务出去以便我使用
例如Openlist RDP Gitlab
但是 我并不打算公开 我只打算自己使用
前面我们搭建了Authentik作为SSO单点登录,刚好雷池WAF支持通过单点登录鉴权来允许访问
这样我就可以实现把ESXi挂到公网 但是不登录都过不了防火墙
开始折腾
在K8s上的搭建
雷池官方文档有给到docker compose 但是没有K8s的
我的大部分服务都已经从分开的docker迁移到了K8s内
我是打算搭建到K8s,因为这样WAF可以直接访问集群内部的虚拟地址
也就是
<Service name>.<namespace>.svc.cluster.local
这样的话好处有三
- 数据不会经过局域网 防止局域网抓包
- 直接在集群内部流转 效率更高
- 雷池转发不需要处理Https解密的问题
一开始是想手动转compose 马上就放弃了 他的容器太多而且又相互依赖
那么有没有Helm Chart呢
我一搜 很快啊 确实是有的

这么简单 还好我没古法转Compose
我直接SSH上我们的Master节点
helm repo add yaencn https://helm.yaencn.com/charts
helm install safeline --namespace safeline \
--set global.ingress.enabled=true \
--set global.ingress.hostname="waf.k8s.lan" \
yaencn/safeline
上个厕所回来发现名为tengine的Deployment红红的
一看日志:

?大哥你这对吗
我一看发现这个helm居然是用PVC挂载的conf文件
这就算了 我开busybox一看 /etc/nginx里面居然是空的
这特么能不报错就有鬼了
那不对啊 我以为是我集群有问题,我uninstall重装了之后还是这样
我找了个docker机把镜像pull下来 里面没问题啊 是有东西的
也就是这个helm有问题啊
那我又得手转Compose?不要啊
搞了半天,没辙了
摇人!

我也不知道他是怎么做到的 我猜测可能是init pod忘记写copy命令了

我一个一个大版本试
结果搞笑的是我一路试下去 只有5开头的版本是可以用的
我想起来雷池社区的一个在K3s部署的教程

一时间不知道怎么说 也是有点抽象
简单来说就是我们先装5.2.0版本然后upgrade到最新版应该就没问题了
helm install safeline --namespace safeline \
--set global.ingress.enabled=true \
--set global.ingress.hostname="waf.local" \
--version 5.2.0 \
yaencn/safeline
确保所有容器都没问题之后再跑
helm upgrade safeline --namespace safeline \
--version 10.0.25 \
yaencn/safeline
吐槽一下这个版本号 7.4.0之前WAF版本还和Chart Version同步 突然一下子蹦到10.几
这规范吗兄弟
不管怎么说这样是能跑了
然后的话我们不知道重启了多少次WAF 他输出在控制台的密码我们应该是找不到了
所以进入名为safeline-mgt的Pod 执行resetadmin
用admin 和新密码进入WAF

美滋滋
然后是路由的配置,我们可以选择用Loadbalance或者NodePort暴露tengine反代引擎
也可以选择先用Ingress代理
其实都可以
文档那里有个最佳实践就是直接把WAF注入Ingress 但那个不适用于我
因为我的Ingress还需要管理*.lan局域网的域名
啊可以新建一个Ingress类 那太麻烦了我懒
直接把*.example.com指向WAF 然后路由转发把443转发到公网除80 443以外的端口
这样的话流量路径就是
外部->路由器->Ingress LoadbalanceIP->WAF->内部服务
配置好Ingress的X-Forward IP转发,并信任内网网段,雷池是可以获取到真实IP并透传到后端的
2025.10.26更新:
我是大傻逼
我洗澡的时候突然想到,Nginx反代识别客户端实际访问域名的方式是识别Header里面的Host内容来匹配实际应该访问的地址
也就是说nginx不能在三层上识别访问的地址 这意味着什么呢
这意味着如果把WAF和内网服务挂在同一个ingress上又不设置安全规则的话,别人完全可以通过伪造Header来绕过WAF直接访问我的.lan域名
我手边没有VPS,但是我们可以设置一个代理来测试一下:
export http_proxy="http://10.0.0.233:7890"
export https_proxy="http://10.0.0.233:7890"
curl -vk -H "Host: xxx.k8s.lan" https://我的公网地址/
* Uses proxy env variable https_proxy == 'http://10.0.0.233:7890'
* Trying 10.0.0.233:7890...
* CONNECT tunnel: HTTP/1.1 negotiated
* allocate connect buffer
* Establish HTTP proxy tunnel to 公网地址
> CONNECT 公网地址 HTTP/1.1
> Host: 公网地址
> User-Agent: curl/8.12.0
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 Connection established
<
* CONNECT phase completed
* CONNECT tunnel established, response 200
* ALPN: curl offers http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / X25519 / RSASSA-PSS
* ALPN: server accepted http/1.1
* Server certificate:
* subject: O=Acme Co; CN=Kubernetes Ingress Controller Fake Certificate
* start date: Oct 22 01:48:21 2025 GMT
* expire date: Oct 22 01:48:21 2026 GMT
* issuer: O=Acme Co; CN=Kubernetes Ingress Controller Fake Certificate
* SSL certificate verify result: self-signed certificate (18), continuing anyway.
* Certificate level 0: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
* Connected to 10.0.0.233 (10.0.0.233) port 7890
* using HTTP/1.x
> GET / HTTP/1.1
> Host: xxx.k8s.lan
> User-Agent: curl/8.12.0
> Accept: */*
>
* Request completely sent off
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
< HTTP/1.1 200 OK
< Date: Sat, 25 Oct 2025 21:59:00 GMT
< Content-Type: text/html>
后面是网页内容
我他妈马上把端口转发关了然后给自己两个大臂兜
不管怎么说,这车算是翻了 我决定还是用最佳实践
其实的话直接把tengine加一个443端口然后用LoadBalanceIP暴露出去 转发全部指向tengine就好了
我是大傻逼 不要学
WAF的配置
首先我们先配置统一登陆
去Authentik创建一个新的Provider 类型就是OIDC 然后来雷池这里添加

这里的url填写是Authentik的配置颁发者而不是URL


然后新加一个防护应用,我们就用OpenList做测试

然后打开身份认证功能

我不知道为什么选择统一认证之后无论访问哪个服务他都会跳转到Authentik 应该是我铸币 反正这样配置能用 不管他
然后我们访问一下保护的域名 他就会自动跳转到Authentik认证了
完事
几天后的小更新
我一开始只是防患于未然,挂了几周之后发现是真的有人扫
拦了几百万次请求 就夸张

不管怎么说,能用而且能保护我们的服务安全 足矣