博客系列——网站安全防护之雷池WAF
本文最后更新于 539 天前,如有失效请评论区留言。

前言

由于网站是直接暴露在公网上的,很容易遭受到各种安全攻击,个人网站不像商业网站要使用专业的WAF防火墙、自防护系统、安全蜜罐等安全措施,需要一笔不少的费用,所以开源WAF就引起我的注意了。

WAF就是web应用防火墙,雷池 SafeLine 是众多开源WEB防火墙之一,它也有收费版本,不过对于个人网站,开源版本也足够了。

WAF 部署架构

没有部署WAF前,外部请求经过网络直接传递到网站服务器,如果其中存在恶意的请求,那么这些恶意的攻击请求也会到达网站。

image-20240710130443372

社区版雷池以反向代理方式接入,优先于网站接收请求,对流量进行检测和清洗,过滤后的流量再转发给网站服务器。最终确保外部的攻击流量无法触达网站服务器。

image-20240710130902633

雷池技术架构

对于使用雷池WAF,其实是不需要去关注雷池底层的,因为雷池WAF基于docker容器可以实现一条命令部署,也不需要需要去改动它的底层配置,一切都实现了界面化了,容易理解和操作。

注:示意图较老,参考为主。上半部分虚线框内是业务数据楼,中间实线框内是雷池的各个服务。

image-20240710135442160

各个容器和服务说明:

名称 定义 详情
safeline-mgt 管理容器(管理端) 接收管理后台行为,向其他服务或容器推送消息
safeline-detector 检测容器 执行检测的容器,从 Tengine 进入的流量会转发到该节点检测
safeline-mario 日志容器 记录与统计恶意行为的节点
safeline-tengine 网关 转发网关,有简单的过滤功能,基于nginx实现
safeline-pg 关系型数据库 存储攻击日志、保护站点、黑白名单配置的数据库
safeline-luigi 数据统计服务 统计qps等信息
safeline-fvm 规则处理容器 将规则传递到检测容器
safeline-bridge 支持云托管 通讯的桥接器

可以直接通过 safeline-mgt节点管理服务,该节点负责:

  • Tengine 网关推送自定义配置并利用NGINX命令进行reload热更新;
  • 自定义检测规则(黑白名单等)并向检测引擎safeline-detector推送;
  • 直接读取postgres数据库,在后台展示返回日志、统计、当前配置等内容。

部署SafeLine

实际上部署SafeLine非常简单,但是这里还是需要了解一下涉及到的一些文件,方便在部署过程以及后续运行维护中提供一些排错的思路。

各个配置文件说明

.env 文件:用于设置compose.yml要引用的环境变量

echo "SAFELINE_DIR=$(pwd)" >> .env  # 设置当前路径为雷池社区版的根路径
echo "IMAGE_TAG=latest" >> .env  # 设置镜像的 tag
echo "MGT_PORT=9443" >> .env  # 管理容器服务使用的端口
echo "POSTGRES_PASSWORD=$(LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom | head -c 32)" >> .env  # /dev/urandom是一个很长的随机数文本,tr -dc 命令用于删除非字母、非数字的字符,用于生成随机的 postgres 密码
echo "SUBNET_PREFIX=172.22.222" >> .env  # 定义 docker 虚拟网卡的子网前缀

compose.yml文件:用于配置和启动safeline服务需要用到的容器,这是官方直接下载的,不需要改动任何配置。

# 基于3.10 版本进行说明,最新配置文件可能存在部分变动
networks:
  safeline-ce:
    name: safeline-ce # 定义该子网名称
    driver: bridge # 该子网为网桥模式
    ipam:
      driver: default
      config:
        - gateway: ${SUBNET_PREFIX:?SUBNET_PREFIX required}.1 # 定义网关为 SUBNET_PREFIX.1,若按上文设置,此处为 172.22.222.1
          subnet: ${SUBNET_PREFIX}.0/24
    driver_opts:
      com.docker.network.bridge.name: safeline-ce
services:
  postgres:
    container_name: safeline-postgres
    restart: always # 容器启动失败或崩溃时自动重启
    image: postgres:15.2
    volumes: # 开启的映射文件夹
      - ${SAFELINE_DIR}/resources/postgres/data:/var/lib/postgresql/data
      - /etc/localtime:/etc/localtime:ro
    environment:
      - POSTGRES_USER=safeline-ce
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?postgres password required}
    networks: # 使用上文的 safeline-ce 网络,IP 为 172.22.222.2
      safeline-ce:
        ipv4_address: ${SUBNET_PREFIX}.2
    cap_drop:
      - net_raw
    command: [postgres, -c, max_connections=200] # 设置 postgres 的最大连接数
  management:
    container_name: safeline-mgt-api
    restart: always
    image: chaitin/safeline-mgt-api:${IMAGE_TAG:?image tag required}
    volumes:
      - ${SAFELINE_DIR?safeline dir required}/resources/management:/resources/management
      - ${SAFELINE_DIR}/resources/nginx:/resources/nginx
      - ${SAFELINE_DIR}/logs:/logs
      - /etc/localtime:/etc/localtime:ro
    ports:
      - ${MGT_PORT:-9443}:1443
    environment:
      - MANAGEMENT_RESOURCES_DIR=/resources/management
      - NGINX_RESOURCES_DIR=/resources/nginx
      - DATABASE_URL=postgres://safeline-ce:${POSTGRES_PASSWORD}@127.0.0.1/safeline-ce
      - MANAGEMENT_LOGS_DIR=/logs/management
    networks:
      safeline-ce: # 使用上文的 safeline-ce 网络,IP 为 172.22.222.4
        ipv4_address: ${SUBNET_PREFIX}.4
    cap_drop:
      - net_raw
  detector:
    container_name: safeline-detector
    restart: always
    image: chaitin/safeline-detector:${IMAGE_TAG}
    volumes:
      - ${SAFELINE_DIR}/resources/detector:/resources/detector
      - ${SAFELINE_DIR}/logs/detector:/logs/detector
      - /etc/localtime:/etc/localtime:ro
    environment:
      - LOG_DIR=/logs/detector
    networks:
      safeline-ce: # 使用上文的 safeline-ce 网络,IP 为 172.22.222.5
        ipv4_address: ${SUBNET_PREFIX}.5
    cap_drop:
      - net_raw
  mario:
    container_name: safeline-mario
    restart: always
    image: chaitin/safeline-mario:${IMAGE_TAG}
    volumes:
      - ${SAFELINE_DIR}/resources/mario:/resources/mario
      - ${SAFELINE_DIR}/logs/mario:/logs/mario
      - /etc/localtime:/etc/localtime:ro
    environment:
      - LOG_DIR=/logs/mario
      - GOGC=100
      - DATABASE_URL=postgres://safeline-ce:${POSTGRES_PASSWORD}@safeline-postgres/safeline-ce
    networks:
      safeline-ce: # 使用上文的 safeline-ce 网络,IP 为172.22.222.6
        ipv4_address: ${SUBNET_PREFIX}.6
    cap_drop:
      - net_raw
  tengine:
    container_name: safeline-tengine
    restart: always
    image: chaitin/safeline-tengine:${IMAGE_TAG}
    volumes:
      - ${SAFELINE_DIR}/resources/nginx:/etc/nginx
      - ${SAFELINE_DIR}/resources/management:/resources/management
      - ${SAFELINE_DIR}/resources/detector:/resources/detector
      - ${SAFELINE_DIR}/logs/nginx:/var/log/nginx
      - /etc/localtime:/etc/localtime:ro
      - ${SAFELINE_DIR}/resources/cache:/usr/local/nginx/cache
      - /etc/resolv.conf:/etc/resolv.conf
    environment:
      - MGT_ADDR=${SUBNET_PREFIX}.4:9002 # 配置 mgt-api 的 grpc 服务器地址,用于与 mgt-api 容器通信
    ulimits:
      nofile: 131072
    network_mode: host # Tengine 直接使用宿主机网络

各个服务的运行日志

docker ps  # 查看各容器状态
docker logs -f <comtainer_name>  # 输出容器 std 日志

# 一些服务运行中的持久化也会存储在磁盘上,目录结构如下
root@user:/path/to/safeline-ce/logs# tree
.
├── detector
│   └── snserver.log    #检测容器的输出日志
├── management
│   ├── nginx.log     # Tengine 容器中 NGINX 日志输出
│   └── webserver.log    # safeline-mgt-api 容器的日志输出
├── mario
│   └── mario.log    # 流量日志输出
└── nginx
    ├── error.log  # NGINX 的错误日志
    └── tcd.log  # tcd 是 Tengine 用于与 safeline-mgt-api 通信的网络代理进程,该文件存储了两者的通信日志

安装方式

根据实际情况选择安装方式,安装过程不赘述,官网是中文的,也很详细。

  • 自动安装: 使用一条命令自动化安装,推荐新手使用;
  • [手动安装]() : 如果你熟悉 Linux 和 Docker,可以手动来配置雷池环境;
  • [离线环境安装]() : 如果你的环境无法连接互联网,可以通过这种方式下载离线安装包

具体参考:雷池部署文档

几个注意事项

1、雷池本身支持申请免费域名ssl证书(过期自动续期),采用文件验证的方式,但在申请时会临时启动80端口进行文件验证,所以需要提前在防火墙放行80端口,并且保证80端口不被其他程序占用。同时应提前将域名解析到雷池所在服务器的IP地址。

2、社区版雷池防护能力自然是不够的,但总比没有的好,防护阈值不宜设置得太低,不然连我自己访问频次高了都会受限制。

3、在雷池上勾选https后,证书实际上是部署在雷池上的,此时雷池代理的后端网站入口,也应该是https协议,官方教学视频直接代理了后端的http协议访问,在测试中我发现会造成页面显示错乱等问题,实际上我通过雷池代理了3个网站均存在这个问题,所以雷池中的上游服务器最后均代理了https的链接,并且在网站上也是真实配置了https://domain.com:9443 ,不过在雷池中配置时可以写 https://127.0.0.1:9443, 只要WAF上配置的入口是域名,网站后台就可以接收到正常的请求。

image-20240710155102078

4、当雷池挡在了各个网站的前面,雷池本身也就成为了一个突破口,当恶意用户不断攻击雷池后台时,雷池本身并不会进行流量过滤。所以需要将雷池的 9443 端口限制在内网,并将雷池后台通过雷池安全防护代理,这样,即便是访问雷池后台,也需要经过雷池本身的流量过滤。

5、雷池必然会带来一定的访问速度下降问题,但是为了安全,失去速度的同时获得了安全,是值得的。

版权声明:除特殊说明,博客文章均为cuckooyang原创,依据CC BY-SA 4.0许可证进行授权,转载请附上出处链接及本声明。 | 博客订阅:RSS | 广告招租:留言板 | 博客VPS |
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇