关于雷池WAF:雷池(SafeLine)是由长亭科技开发的一种专业的 Web 应用防火墙(WAF)。WAF是指Web Application Firewall,工作在应用层,专门用于保护基于HTTP/HTTPS协议的Web系统免受各种网络攻击。雷池WAF利用先进的智能语义分析算法作为其核心检测技术。这种算法不依赖于预先定义的规则集,能够精准地检测恶意攻击,同时减少误报,有效应对未知特征的0day攻击。
雷池WAF可以安装在K8S集群或者任意一台与集群网络互通的机器上。
官网手册: 手动安装雷池
mkdir -p "/data/safeline"
cd "/data/safeline"
wget "https://waf-ce.chaitin.cn/release/latest/compose.yaml"
cd "/data/safeline"
touch ".env"
## 使用文本编辑器打开 .env 文件,写入下方的内容。根据你的实际情况修改配置文件中的 {safeline-dir} 和 {postgres-password} 字段
SAFELINE_DIR=/data/safeline
IMAGE_TAG=latest
MGT_PORT=9443
POSTGRES_PASSWORD=Aa87654321
SUBNET_PREFIX=172.22.222
IMAGE_PREFIX=swr.cn-east-3.myhuaweicloud.com/chaitin-safeline
cd "/data/safeline"
wget https://demo.waf-ce.chaitin.cn/image.tar.gz
# 载入镜像
cat image.tar.gz | gzip -d | docker load
cd "/data/safeline"
docker compose up -d
docker exec safeline-mgt resetadmin
社区版雷池的检测引擎默认以 unix socket 的方式提供服务,我们需要把他修改为 tcp 方式,供 t1k 插件调用。
官方手册:参考APISIX联动雷池社区版前面部分修改雷池WAF为tcp方式
将bind方式从unix socket改为tcp,这样我们就把雷池引擎的服务监听到了 8000 端口,如下:
vi /data/safeline/resources/detector/detector.yml
bind_addr: 0.0.0.0
listen_port: 8000
为detector容器增加ports字段,暴露其8000端口,把容器内的8000端口映射到宿主机,如下:
vi /data/safeline/compose.yaml
......
detect:
......
ports:
- 8000:8000
......
在雷池安装目录下执行以下命令重启雷池即可生效。
cd "/data/safeline"
docker compose down
docker compose up -d
直接在k8s集群的主机tcping一下雷池机子的8000端口,看看通不通。
tcping 172.30.233.87 8000
172.30.233.87:8000 - Connected - 40.317ms
在ingress-nginx命名空间中添加一个ConfigMap,使用 ConfigMap配置Safeline插件需要的检测引擎 host 和 port,内容如下:
# safeline.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: safeline
namespace: ingress-nginx
data:
host: "172.30.233.87" # 雷池检测引擎的地址
port: "8000" #检测引擎的端口
# 创建ConfigMap
kubectl create namespace ingress-nginx
kubectl apply -f safeline.yaml
在 Ingress-Nginx的DaemonSet中添加环境变量便于插件读取到引擎的地址跟端口:
# ingress-nginx-controller-deployment.yaml
...
env:
- name: SAFELINE_HOST
valueFrom:
configMapKeyRef:
name: safeline
key: host
- name: SAFELINE_PORT
valueFrom:
configMapKeyRef:
name: safeline
key: port
由于k8s环境中已经有了ingress-nginx,我们需要使用dockerfile把Safeline插件安装到nginx的默认插件目录。我这边原先的ingress镜像是rancher/nginx-ingress-controller:nginx-0.49.3-rancher1,所以我这个FROM是基于现在运行的镜像,dockerfile如下:
FROM rancher/nginx-ingress-controller:nginx-0.49.3-rancher1
USER root
RUN apk add --no-cache make gcc unzip wget
RUN wget https://luarocks.org/releases/luarocks-3.11.0.tar.gz && \
tar zxpf luarocks-3.11.0.tar.gz && \
cd luarocks-3.11.0 && \
./configure && \
make && \
make install && \
cd .. && \
rm -rf luarocks-3.11.0 luarocks-3.11.0.tar.gz
RUN luarocks install ingress-nginx-safeline && \
ln -s /usr/local/share/lua/5.1/safeline /etc/nginx/lua/plugins/safeline
USER www-data
根据上面的dockerfile 构建带有waf插件的镜像
docker build -t nginx-ingress-controller-waf:nginx-1.1.0-rancher1 .
4、替换原来的镜像
把原来ingress-nginx的daemonset中的镜像更新成带有waf插件的镜像即可。
# kubectl edit daemonset nginx-ingress-controller -n ingress-nginx
...
image: nginx-ingress-controller-waf:nginx-1.1.0-rancher1
...
5、在 Ingress-Nginx 的插件配置中启用 Safeline :
apiVersion: v1
kind: ConfigMap
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
data:
plugins: "safeline"
6、测试
可以看到已经被waf拦截了,登录waf的9433也可以看到拦截详情。
# curl "http://xxxxx.com/login?user=admin%27or%201%3D1"
{"code": 403, "success":false, "message": "blocked by Chaitin SafeLine Web Application Firewall", "event_id": "cd4642c861834b58991f883916ffe73e"}
如果发现拦截没有生效,可以看看nginx-ingress-controller的日志:
# kubectl logs nginx-ingress-controller-rhvnl -n ingress-nginx
或者直接进入nginx-ingress-controller 输出下环境变量看看有没有读取到检测引擎的地址跟端口:
# kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-rhvnl 1/1 Running 0 4d17h
nginx-ingress-controller-wkc4j 1/1 Running 1 4d17h
# kubectl exec -it nginx-ingress-controller-rhvnl -n ingress-nginx -- bash
bash-5.1$ echo $SAFELINE_HOST
172.30.233.87
bash-5.1$ echo $SAFELINE_PORT
8000