Myluzh Blog

K8S ingress-nginx中集成雷池WAF最佳实践

发布时间: 2024-7-24 文章作者: myluzh 分类名称: Kubernetes 朗读文章


0x00 概述
    关于雷池WAF:雷池(SafeLine)是由长亭科技开发的一种专业的 Web 应用防火墙(WAF)。WAF是指Web Application Firewall,工作在应用层,专门用于保护基于HTTP/HTTPS协议的Web系统免受各种网络攻击。雷池WAF利用先进的智能语义分析算法作为其核心检测技术。这种算法不依赖于预先定义的规则集,能够精准地检测恶意攻击,同时减少误报,有效应对未知特征的0day攻击。
    很荣幸雷池社区版-官方手册已引用了该文章 标题:《K8S ingress-nginx中集成雷池WAF最佳实践 - 来自 23 群的 myluzh》 地址:https://docs.waf-ce.chaitin.cn/更多技术文档/K8S-ingress-nginx中集成雷池WAF最佳实践

0x01 手动安装雷池
雷池WAF可以安装在K8S集群或者任意一台与集群网络互通的机器上。
官网手册:手动安装雷池
1、创建雷池目录
mkdir -p "/data/safeline"
2、下载编排脚本
cd "/data/safeline"
wget "https://waf-ce.chaitin.cn/release/latest/compose.yaml"
3、配置变量
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
4、下载镜像包并载入
cd "/data/safeline"
wget https://demo.waf-ce.chaitin.cn/image.tar.gz
# 载入镜像
cat image.tar.gz | gzip -d | docker load
5、启动雷池
cd "/data/safeline"
docker compose up -d
6、初始化管理员账户
docker exec safeline-mgt resetadmin

0x02 修改雷池WAF为tcp方式

社区版雷池的检测引擎默认以 unix socket 的方式提供服务,我们需要把他修改为 tcp 方式,供 t1k 插件调用。
官方手册:参考APISIX联动雷池社区版前面部分修改雷池WAF为tcp方式
1、编辑detector.yml文件
将bind方式从unix socket改为tcp,这样我们就把雷池引擎的服务监听到了 8000 端口,如下:
vi /data/safeline/resources/detector/detector.yml 
bind_addr: 0.0.0.0
listen_port: 8000
2、编辑compose.yaml
为detector容器增加ports字段,暴露其8000端口,把容器内的8000端口映射到宿主机,如下:
vi  /data/safeline/compose.yaml
......
detect:
    ......
    ports:
    - 8000:8000
......
3、启动雷池waf
在雷池安装目录下执行以下命令重启雷池即可生效。
cd "/data/safeline"
docker compose down
docker compose up -d
4、测试是否生效
直接在k8s集群的主机tcping一下雷池机子的8000端口,看看通不通。
tcping 172.30.233.87 8000
172.30.233.87:8000 - Connected - 40.317ms

0x03 在ingress-nginx中进行集成

1、创建一个存储雷池waf引擎地址跟端口的configmap
在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
2、注入环境变量
在 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
3、制作集成了waf的ingress-nginx镜像
由于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、测试
可以看到已经被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"}

0x04 后续离线更新
cd /data/safeline
rm -f image.tar.gz
wget https://demo.waf-ce.chaitin.cn/image.tar.gz
docker compose down --remove-orphans
docker load -i image.tar.gz
docker compose up -d

0x05 一些踩坑经验分享
如果发现拦截没有生效,可以看看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

标签: k8s Ingress waf ingress-nginx 雷池 safeline

发表评论