LOADING

加载过慢请开启缓存 浏览器默认开启

开源WAF 雷池在K8s上的搭建

前言

换了条宽带,现在我拥有动态的公网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呢

我一搜 很快啊 确实是有的

chrome_cRnKg0gTTt.png

这么简单 还好我没古法转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红红的

一看日志:

QQ_jM4NmDIkBE.png

?大哥你这对吗

我一看发现这个helm居然是用PVC挂载的conf文件

这就算了 我开busybox一看 /etc/nginx里面居然是空的

这特么能不报错就有鬼了

那不对啊 我以为是我集群有问题,我uninstall重装了之后还是这样

我找了个docker机把镜像pull下来 里面没问题啊 是有东西的

也就是这个helm有问题啊

那我又得手转Compose?不要啊

搞了半天,没辙了

摇人!

QQ_H6Fyg7Jh2q.png

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

MobaXterm_13XRWMaaPT.png

我一个一个大版本试

结果搞笑的是我一路试下去 只有5开头的版本是可以用的

我想起来雷池社区的一个在K3s部署的教程

chrome_zoCJrQf7x3.png

一时间不知道怎么说 也是有点抽象

简单来说就是我们先装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

chrome_tTJ6CGOIws.png

美滋滋

然后是路由的配置,我们可以选择用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 然后来雷池这里添加

chrome_9n0sqTOy86.png

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

chrome_fY8Aldy975.png

chrome_yU0YzQXtDW.png

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

chrome_26LDH4jSfq.png

然后打开身份认证功能

chrome_75CJnrqlqI.png

我不知道为什么选择统一认证之后无论访问哪个服务他都会跳转到Authentik 应该是我铸币 反正这样配置能用 不管他

然后我们访问一下保护的域名 他就会自动跳转到Authentik认证了

完事

几天后的小更新

我一开始只是防患于未然,挂了几周之后发现是真的有人扫

拦了几百万次请求 就夸张

chrome_MHLl2rK3s1.png

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