静看光阴荏苒
不管不顾不问不说也不念

配置WG-Easy+长亭雷池WAF

简要介绍一下长亭雷池WAFWG-Easy

长亭雷池WAF是一款国产的WAF软件,有免费的社区版本,最近总是看到有人提起,都说这个WAF挺好用的,搞的我心里痒痒的,老想着部署一个试试。。

WG-Easy是一个WireGuard的Web UI,使用WG-Easy可以非常方便的安装和管理WireGuard VPN。

简单说一下为什么要这样搭配使用。。

由于我把长亭雷池WAF部署在单独的服务器上,这个WAF的主要工作原理就是通过反向代理来实现的,如果直接反代源站服务器的公网IP+端口是可以用,但这不就等于把源站IP暴露了嘛,为了保护源站IP不被泄露,我想了个办法就是用WireGuard把部署WAF的这台服务器与源站所在服务器建立一个VPN,然后源站的NGINX只监听在VPN的IP上,WAF这边配置反代VPN的IP+端口即可。

当然保护源站IP不被泄露的方法不止这一种,比如还可以配置源站服务器的防火墙仅允许WAF服务器访问,等等。你可以选择一个合适自己的方案。但说句实话,真要保证源站IP不漏,其实还挺难的,如果你的域名曾经解析过源站IP,这其实大概率就已经漏了,即便现在你做了这些操作,别人扫DNS记录就能扫出来。。还有诸如censys这类网站也是每天全世界到处爬网站证书信息。。

另外刚才说了这个WAF的主要工作原理就是通过反向代理来实现的,即便你不需要它提供的WAF功能,也可以把它当个反向代理的面板来使用,可以说是NPM(Nginx Proxy Manager)等一众软件的绝佳替代品了。(不过现在社区版好像限制只能添加50个站点了)

我已经部署折腾好了,下面记录一下步骤。。

首先部署WG-Easy,我把WG-Easy部署在WAF所在的机器上。安装Docker:

apt -y update
apt -y install curl
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

新建compose文件:

mkdir -p /opt/wg-easy && cd /opt/wg-easy && nano docker-compose.yml

我的配置如下:

volumes:
  etc_wireguard:

services:
  wg-easy:
    image: ghcr.io/wg-easy/wg-easy
    container_name: wg-easy
    environment:
      - LANG=chs
      - WG_HOST=your-server-public-ip
      - PASSWORD_HASH=$$2b$$12$$coPqCsPtcFO.Ab99xylBNOW4.Iu7OOA2/ZIboHN6/oyxca3MWo7fW
      - PORT=51821
      - WG_PORT=51820
      - WG_DEFAULT_ADDRESS=10.8.0.x
      - WG_ALLOWED_IPS=10.8.0.0/24
    volumes:
      - etc_wireguard:/etc/wireguard
    ports:
      - "51820:51820/udp"
      - "51821:51821/tcp"
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    sysctls:
      - net.ipv4.ip_forward=1
      - net.ipv4.conf.all.src_valid_mark=1

有几个非常关键的配置特别说明一下:

1、WG_HOST一定要配置为服务器的公网IP。

2、WG_ALLOWED_IPS务必配置成VPN IP所在网段,WG-Easy在默认情况下会配置成0.0.0.0/0,这样启动会导致服务器直接断网,因为0.0.0.0/0是接管机器所有的流量,这对于有公网IP的服务器来说是致命的,并且我们也不需要它接管所有流量。

3、PASSWORD_HASH需要配置成bcrypt加密后的密码,假设你要设置的密码为:YOUR_PASSWORD,可以使用下面的命令生成:

docker run -it ghcr.io/wg-easy/wg-easy wgpw YOUR_PASSWORD

回显为:

PASSWORD_HASH='$2b$12$coPqCsPtcFO.Ab99xylBNOW4.Iu7OOA2/ZIboHN6/oyxca3MWo7fW'

在配置到compose的环境变量中时,需要去掉单引号,并且将每个$符号替换成两个$$符号:

$$2b$$12$$coPqCsPtcFO.Ab99xylBNOW4.Iu7OOA2/ZIboHN6/oyxca3MWo7fW

启动WG-Easy:

docker compose up -d

WG-Easy的Web UI在51821端口上可用,登录进去后,新建客户端:

将客户端配置文件下载下来,里面的内容类似于:

[Interface]
PrivateKey = hidden
Address = 10.8.0.2/24
DNS = 1.1.1.1

[Peer]
PublicKey = hidden
PresharedKey = hidden
AllowedIPs = 10.8.0.0/24
PersistentKeepalive = 0
Endpoint = hidden:51820

请确保AllowedIPs是VPN所在的网段,Endpoint是服务器的公网IP。

接着登录到源站服务器,安装WireGuard:

apt -y update
apt -y install wireguard

新建WireGuard客户端配置文件:

nano /etc/wireguard/wg0.conf

将刚才的客户端配置文件内容写入到wg0.conf内:

[Interface]
PrivateKey = hidden
Address = 10.8.0.2/24
DNS = 1.1.1.1

[Peer]
PublicKey = hidden
PresharedKey = hidden
AllowedIPs = 10.8.0.0/24
PersistentKeepalive = 0
Endpoint = hidden:51820

启动:

systemctl start wg-quick@wg0

使用wg命令检查连接状态:

此时会有一个问题,现在源站服务器是能PING通WAF服务器,但是WAF服务器是PING不通源站服务器的。其实这并不是什么错误,而是预期的行为。

因为WAF服务器上运行的WG-Easy使用的网络是Docker的桥接模式,这就导致WAF服务器里面的WG-Easy容器是能PING通源站服务器的,但WAF服务器主机自身是PING不通的。

要解决这个问题,其实有多种办法,根据这个页面里面的说明,你可以将compose的网络改为host模式,或者仅开放特定端口,但我个人觉得这两方法都不太好。

我个人觉得的最优解是直接把WAF服务器主机也加入到WireGuard网络中,也就是把WAF服务器主机也配置成一个WireGuard客户端。

所以接下来我们需要回到WG-Easy的Web UI,再新建一个客户端,把客户端配置文件下载下来:

然后在部署WG-Easy的这台WAF服务器主机上同样也安装WireGuard:

apt -y update
apt -y install wireguard

新建WireGuard客户端配置文件:

nano /etc/wireguard/wg0.conf

将刚才的客户端配置文件内容写入到wg0.conf内:

[Interface]
PrivateKey = hidden
Address = 10.8.0.3/24
DNS = 1.1.1.1

[Peer]
PublicKey = hidden
PresharedKey = hidden
AllowedIPs = 10.8.0.0/24
PersistentKeepalive = 0
Endpoint = hidden:51820

启动:

systemctl start wg-quick@wg0

这样源站服务器和WAF服务器双方都能互相PING通了,源站服务器的IP是10.8.0.2,WAF服务器的IP就是10.8.0.3,而WG-Easy所在的容器内VPN IP则是10.8.0.1,简单测试一下:

至此,两台服务器的VPN算是建立完成了。别忘了在两台服务器内设置开机自启:

systemctl enable wg-quick@wg0

接下来在WG-Easy所在的这台WAF服务器上部署长亭雷池WAF,准备目录下载compose文件:

mkdir -p /opt/safeline && cd /opt/safeline
wget https://waf.chaitin.com/release/latest/compose.yaml

新建.env配置文件:

nano .env

写入如下内容,注意修改dbpassword:

SAFELINE_DIR=/opt/safeline
IMAGE_TAG=latest
MGT_PORT=9443
POSTGRES_PASSWORD=dbpassword
SUBNET_PREFIX=172.22.222
IMAGE_PREFIX=chaitin

启动:

docker compose up -d

现在长亭雷池WAF的Web UI在9443端口可用,但我们不知道管理员的账号和密码,执行下面的命令获取:

docker exec safeline-mgt resetadmin

至此长亭雷池WAF就安装完成了,在继续配置WAF之前,我们需要先把源站的NGINX配置进行修改以适配WAF。

这边我打算使用WAF保护两个站点:Chevereto、WordPress。需要修改的内容有:

1、修改NGINX监听的IP地址为VPN IP。

2、修改站点运行的端口,Chevereto运行在50000端口,WordPress运行在50001端口,

3、删除有关HTTPS的配置内容,直接用HTTP。

4、源站NGINX具有http_realip_module模块,用于获取客户端真实IP。(Debian11、12官方源里面安装的NGINX自带这个模块不需要自己编译)

编辑源站NGINX的vhost(Chevereto)配置文件:

nano /etc/nginx/sites-available/chevereto

示例配置:

server {
    listen 10.8.0.2:50000;
    server_name img.xxoo.zip;
    root   /var/www/chevereto;
    index  index.html index.htm index.php;
    client_max_body_size 100M;

    set_real_ip_from 0.0.0.0/0;
    real_ip_header X-Forwarded-For;

    # Disable access to sensitive application files
    location ~* (app|content|lib)/.*\.(po|php|lock|sql)$ {
        return 404;
    }
    location ~* composer\.json|composer\.lock|.gitignore$ {
        return 404;
    }
    location ~* /\.ht {
        return 404;
    }

    # Image not found replacement
    location ~* \.(jpe?g|png|gif|webp)$ {
        log_not_found off;
        error_page 404 /content/images/system/default/404.gif;
    }

    # CORS header (avoids font rendering issues)
    location ~* \.(ttf|ttc|otf|eot|woff|woff2|font.css|css|js)$ {
        add_header Access-Control-Allow-Origin "*";
    }

    # PHP front controller
    location / {
        index index.php;
        try_files $uri $uri/ /index.php$is_args$query_string;
    }

    # Single PHP-entrypoint (disables direct access to .php files)
    location ~* \.php$  {
        internal;
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    }
}

编辑源站NGINX的vhost(WordPress)配置文件:

nano /etc/nginx/sites-available/wordpress

示例配置:

server {
    listen 10.8.0.2:50001;
    server_name lala.im;
    root   /var/www/wordpress;
    index  index.html index.htm index.php;
    client_max_body_size 100M;

    set_real_ip_from 0.0.0.0/0;
    real_ip_header X-Forwarded-For;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    }
}

重启NGINX:

systemctl restart nginx

在源站NGINX的配置上面我走了很多弯路,尤其是关于WordPress的配置,一开始我直接去掉了server_name,想着反代也用不上,但是后来发现WordPress依赖这个来生成邮件发信人地址,没有这个会导致WordPress评论邮件通知出错或者评论超时。具体问题见此页面,但这个只影响旧版本,新版的WordPress已经不使用server_name了。

另外由于我使用了Really Simple SSL插件来修复WordPress混合内容,这个插件会导致301重定向循环,我一直忘了这茬,导致我进不去后台了。要解决的话就是先停用这个插件,等反代配置好之后再启用。但问题是现在我已经进不去后台怎么停用呢?此时我想到了用WP-CLI

安装WP-CLI:

curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
mv wp-cli.phar /usr/local/bin/wp

找到插件名,然后停用:

sudo -u www-data wp --path=/var/www/wordpress plugin list
sudo -u www-data wp --path=/var/www/wordpress plugin deactivate really-simple-ssl

至此源站这快的配置就OK了。现在登录到长亭雷池WAF的Web UI,继续配置WAF。(以下步骤仅演示WordPress站点,Chevereto站点的配置步骤与此相同就省略掉了)

首先在全局配置这里,启用如下图所示的这些功能:

申请SSL证书,申请前把域名DNS解析到WAF服务器所在IP:

申请SSL证书可以一次性填写多个域名:

现在就可以添加站点了,这是我添加的三个站点:

我博客的域名是带www的跳转到不带www的,所以添加第一个站点的时候只绑定不带www的域名:

再额外添加一个站点,这个站点绑定带www的域名,并且设置为301重定向:

反之如果你是不带www的域名要跳转到带www的域名,也是可以这样操作的。至此就大功告成了,咱也是用上WAF的人了,233

补充点后续使用过程中遇到的问题,主要是误报,Chevereto这程序还好,WordPress在编写文章的时候,如果文章的内容有些敏感就可能会触发WAF的误报:

好在长亭雷池WAF有一个Customized rules的功能,在这里添加白名单规则即可:

虽然长亭雷池WAF有误报,但比ModSecurity的误报率还是要低的多。。ModSecurity简直就是一个噩梦。。

另外现在国产的WAF产品里面,除了长亭以外,还有南墙WEB应用防火墙(uuWAF)宝塔WAF等等,可选择的空间还是很大的。

最后八卦一下。。我发现长亭的股权结构,阿里是大股东哦= =

赞(1)
未经允许不得转载:荒岛 » 配置WG-Easy+长亭雷池WAF
分享到: 更多 (0)

评论 1

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #1

    可能是我没看明白,这种最终是不是还要解析域名到你得waf服务器地址? 另外 组内网tailsclae也能搞定(用起来实在太方便了),当然 docker自带swarm应该也是可以的

    luguo1天前 Google Chrome 124.0.0.0 Google Chrome 124.0.0.0 Android 10 Android 10回复

分享创造快乐

广告合作资源投稿