如何在宝塔(bt)下搭建 wordpress 网站 + 免费 waf 防火墙

宝塔运维工具[1],配合 wordpress 可以快速创建网站。当我们快速完成网站搭建并且上线后,惊讶的发现,网络上总隐藏着坏人,时时刻刻想害我的网站。此时就需要用到网络应用防火墙 waf,因为宝塔自带 waf 是收费的,作为小网站,用起来并不划算。所以得寻找可用的免费 waf [2],对比之后,最后选择了雷池 waf 社区版 [3],原因很简单,社区版对应的就是商业版,背靠大树好乘凉。

下面是宝塔 bt + 免费 waf 的搭建过程

环境准备

使用腾讯云轻应用服务器[4]创建服务实例,操作系统选择 "WordPress"

image.png

设置腾讯云防火墙开放端口,添加 3 个端口

端口 服务 用途
8888 宝塔面板 进入宝塔的管理界面,管理所有服务,必开
9443 雷池社区面板 管理雷池社区防火墙的后台,必开
8001 业务服务 因为宝塔占用了 80 端口,waf 需要占用其他端口代理业务服务,非必开

注意:8001 端口是为了测试用,正式服务上线后可以使用 https 协议的 443 端口,然后就可以关掉这个测试端口了,并且 8001 也可以更换为其他端口,这里仅测试用。

image.png

安装成功后,在 “应用管理” 面板可以看到应用信息


image.png

根据 宝塔 Linux 应用的提示,ssh 链接到服务器,获取登录宝塔的登录账号密码

image.png

然后登录宝塔管理后端,环境配置成功。

image.png

在宝塔中添加社区版 waf

因为需要用到宝塔的云服务功能,这里推荐登录宝塔账号。

image.png

雷池 waf 使用 docker 运行,并且官网提供了一键安装脚本,但是想要在宝塔中管理,还需要进行一些配置。

宝塔安装 docker

image.png

安装完成

image.png

社区版 waf 是通过 docker compose 运行的,在宝塔中添加 compose 模板

image.png

然后关键的 compose.yaml 文件,下面是手动修改过的 1.10 版本 compose 配置文件

networks:
  safeline-ce:
    name: safeline-ce
    driver: bridge
    ipam:
      driver: default
      config:
      - gateway: 169.254.0.1
        subnet: 169.254.0.0/24
    driver_opts:
      com.docker.network.bridge.name: safeline-ce

services:
  postgres:
    container_name: safeline-postgres
    restart: always
    image: postgres:15.2
    volumes:
    - /srv/safeline-ce/resources/postgres/data:/var/lib/postgresql/data
    - /etc/localtime:/etc/localtime:ro
    environment:
    - POSTGRES_USER=safeline-ce
    - POSTGRES_PASSWORD=SafeLine2023!
    networks:
      safeline-ce:
        ipv4_address: 169.254.0.2
    cap_drop:
    - net_raw
    command: [postgres, -c, max_connections=200]
  redis:
    container_name: safeline-redis
    restart: always
    image: redis:7.0.11
    volumes:
      - /srv/safeline-ce/resources/redis/data:/data
      - /etc/localtime:/etc/localtime:ro
    command: redis-server --appendonly yes --requirepass  SafeLine2023!
    networks:
      safeline-ce:
        ipv4_address: 169.254.0.3
    cap_drop:
      - net_raw
    sysctls:
      net.core.somaxconn: "511"
  management:
    container_name: safeline-mgt-api
    restart: always
    image: chaitin/safeline-mgt-api:1.10.0
    volumes:
    - /srv/safeline-ce/resources/management:/resources/management
    - /srv/safeline-ce/resources/nginx:/resources/nginx
    - /srv/safeline-ce/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:SafeLine2023!@127.0.0.1/safeline-ce
    - MANAGEMENT_LOGS_DIR=/logs/management
    networks:
      safeline-ce:
        ipv4_address: 169.254.0.4
    cap_drop:
    - net_raw
  detector:
    container_name: safeline-detector
    restart: always
    image: chaitin/safeline-detector:1.10.0
    volumes:
    - /srv/safeline-ce/resources/detector:/resources/detector
    - /srv/safeline-ce/logs/detector:/logs/detector
    - /etc/localtime:/etc/localtime:ro
    environment:
    - LOG_DIR=/logs/detector
    networks:
      safeline-ce:
        ipv4_address: 169.254.0.5
    cap_drop:
    - net_raw
  mario:
    container_name: safeline-mario
    restart: always
    image: chaitin/safeline-mario:1.10.0
    volumes:
    - /srv/safeline-ce/resources/mario:/resources/mario
    - /srv/safeline-ce/logs/mario:/logs/mario
    - /etc/localtime:/etc/localtime:ro
    environment:
    - LOG_DIR=/logs/mario
    - GOGC=100
    - DATABASE_URL=postgres://safeline-ce:SafeLine2023!@safeline-postgres/safeline-ce
    - REDIS_URL=redis://:SafeLine2023!@safeline-redis:6379/0
    networks:
      safeline-ce:
        ipv4_address: 169.254.0.6
    cap_drop:
    - net_raw
  tengine:
    container_name: safeline-tengine
    restart: always
    image: chaitin/safeline-tengine:1.10.0
    volumes:
    - /srv/safeline-ce/resources/nginx:/etc/nginx
    - /srv/safeline-ce/resources/management:/resources/management
    - /srv/safeline-ce/resources/detector:/resources/detector
    - /srv/safeline-ce/logs/nginx:/var/log/nginx
    - /etc/localtime:/etc/localtime:ro
    - /srv/safeline-ce/resources/cache:/usr/local/nginx/cache
    - /etc/resolv.conf:/etc/resolv.conf
    environment:
    - MGT_ADDR=169.254.0.4:9002
    ulimits:
      nofile: 131072
    network_mode: host

拷贝文件到 “添加 yaml 模板” 中,并添加模板。

image.png

在宝塔面板中,切换到 compose ,创建新的 compose 项目

image.png

点击“添加”后,需要几分钟时间准备运行。成功后,切换到 “容器” 面板,可以看到 waf 相关的 6 个容器都在运行状态

image.png

此时可以访问 9443 端口,就可以查看 waf 管理后台了。

注意:雷池 waf 使用了自签名证书来支持 https,所以第一次访问时需要手动 “允许” 一次才可以。

image.png

然后可以登录 waf 的登录,雷池社区采取了比较特殊的登录方式: OTP 验证码登录,参考官网文档[5]。绑定完 OTP 后再登录,成功后可以看到这个界面

image.png

配置 waf

那么,服务都准备好了,下面如何给业务服务套上 waf。作为中小网站的维护人员,我并不想学习 waf,只想简单使用,因此我仅仅了解 waf 的几个关键点:

  1. waf 是拦截在 wordpress 网站之前的,waf 如果挂了,网站就挂了
  2. 用户访问的其实是 waf,如果访问没有风险,waf 才会转发给业务服务
  3. waf 也要监听端口,并且不能和网站监听同一个端口,这是操作系统的限制

所以应该是,waf 应该监听 80/443 这样的端口,然后转发给网站监听的 8000/8080 这样的端口。

配置 waf 前,先测试我们的网站原来什么样

image.png

监听 80 端口,可以正常访问。下面配置 waf,打开 waf 后端

image.png

创建成功后,可以看到防护站点列表中出现一条记录,waf 可以配置多个站点,但我们只有一个网站,所以没有设置 “域名”,就表示所以访问都接受,会转发给网站。此时创建的 waf 防护站点运行模式是:防护模式。

image.png

注意:waf 监听了 8001 端口,虽然我们已经在腾讯云的后台防火墙中开放了 8001 端口,但那是云平台的防火墙,在宝塔中添加系统防火墙的允许规则,否则 8001 端口是访问不了的。

image.png

现在可以通过 8001 来访问网站了

image.png

此时我们的网站已经在 waf 的保护之下了,来检测一下效果,访问 /shell.php 路径触发一次 waf 的防护功能

image.png

啧啧啧,这个访问看起来太危险了,被 waf 拦截了。现在回到 waf 管理后台,在 “检测日志” 面板下,可以看到拦截日志列表,其中包含一条刚刚被拦截的日志,点击 “详情” 查看,会看到拦截原因和访问细节,现在是不是有了一种练成金钟罩的感觉。

image.png

优化访问端口

此时的我们已经成功配置了 waf,但访问路径中包含了 8001 这个端口,这可不行。是否可以不显示这个端口号呢?根据 web 访问的规则,有两种情况是不用显示端口号的

  1. http 访问 80 端口
  2. https 访问 443 端口

因为 80 端口已经被宝塔占用,并且出于安全的考虑,网站也不建议使用 http 直接访问。好在宝塔没有占用 443 端口,那么我们可以用 waf 来监听 443 端口并转发给业务服务。443 端口对应的 https 协议需要证书,关于如何获取证书这里不展开解释。我们来继续修改 waf 的配置,将端改为 443 并添加证书。

image.png

这里一定要夸奖一下 waf 非常非常贴心的一个功能:自动生成证书。知道你自己搞证书不方便,反正流程是固定的,waf 直接帮你做了。

image.png

现在重新访问一下我们的网站,看到结果了吗,不再显示端口号了,并且是 https。虽然是红色警告,但换成真证书以后就没问题了, 或者也可以就用自签名证书也问题不大。

image.png

收尾

当前网站已经出于 waf 的保护之下,现在可以把不安全的端口关掉了。

image.png

关于 waf 升级

目前 waf 项目还在不断地更新迭代当中,官方推荐 cli 模式下的手动升级,在宝塔下这是不行的。waf 是通过在宝塔下创建 compose 模板来实现管理的,所以升级时需要编写新的 compose 文件。关于如何而升级 waf ,以后升级时再单独记录一篇文章。


  1. https://www.bt.cn/new/index.html

  2. https://zhuanlan.zhihu.com/p/638489965

  3. https://waf-ce.chaitin.cn/

  4. https://www.tencentcloud.com/zh/products/lighthouse

  5. https://waf-ce.chaitin.cn/posts/guide_login

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容