跳到主要内容
版本:v1.5.3

插件版接入指南(原生Nginx)

💡   注意:

请确保本文档的所有步骤都完整执行,包括 Nginx 的安装在内(无需卸载原有的 Nginx)。否则可能造成功能异常!

以下内容将以 Debian 发行版的 Linux 操作系统上运行原生 Nginx 为例。非 DebIan 发行版的 Linux 操作系统下运行的原生 Nginx,也可以将该文档作为参考。

目前暂不支持 HTTP 响应头中包含 CSP 策略(Content-Security-Policy)的用户站点。如果此类站点需要接入瑞数云,请先禁用该响应头。(关于插件版接入原理,请参考 接入原理简介

1 环境安装

1.1 备份Nginx配置文件

在开始安装之前,请先将原有 Nginx 配置文件备份到适当的地方,以便在需要的时候使用。

1.2 准备环境

# 更新
apt-get -y update && apt-get -y upgrade

# 安装依赖
apt install -y gcc g++ make perl net-tools

# 创建临时文件夹
mkdir pure-ngx-lua && cd pure-ngx-lua

1.3 下载模块资源库

# nginx
wget -c https://nginx.org/download/nginx-1.22.0.tar.gz -O nginx-1.22.0.tar.gz --no-check-certificate
tar -zxf nginx-1.22.0.tar.gz && rm nginx-1.22.0.tar.gz

# pcre
wget -c https://nchc.dl.sourceforge.net/project/pcre/pcre/8.45/pcre-8.45.tar.bz2 --no-check-certificate
tar -jxf pcre-8.45.tar.bz2 && rm pcre-8.45.tar.bz2

# zlib
wget -c http://www.zlib.net/zlib-1.2.13.tar.gz --no-check-certificate
tar -zxf zlib-1.2.13.tar.gz && rm zlib-1.2.13.tar.gz

# openssl
wget -c https://www.openssl.org/source/openssl-1.1.1q.tar.gz --no-check-certificate
tar -zxf openssl-1.1.1q.tar.gz && rm openssl-1.1.1q.tar.gz

# ngx_devel_kit
wget -c https://github.com/vision5/ngx_devel_kit/archive/refs/tags/v0.3.1.tar.gz -O ngx_devel_kit-v0.3.1.tar.gz --no-check-certificate
tar -zxf ngx_devel_kit-v0.3.1.tar.gz && rm ngx_devel_kit-v0.3.1.tar.gz

# lua-nginx-module
wget -c https://github.com/openresty/lua-nginx-module/archive/refs/tags/v0.10.21.tar.gz -O lua-nginx-module-v0.10.21.tar.gz --no-check-certificate
tar -zxf lua-nginx-module-v0.10.21.tar.gz && rm lua-nginx-module-v0.10.21.tar.gz

# luajit2
wget -c https://github.com/openresty/luajit2/archive/refs/tags/v2.1-20220411.tar.gz -O luajit2-v2.1-20220411.tar.gz --no-check-certificate
tar -zxvf luajit2-v2.1-20220411.tar.gz && rm luajit2-v2.1-20220411.tar.gz

# lua-resty-core
wget -c https://github.com/openresty/lua-resty-core/archive/refs/tags/v0.1.23.tar.gz -O lua-resty-core.tar.gz --no-check-certificate
tar -zxvf lua-resty-core.tar.gz && rm lua-resty-core.tar.gz

# lua-resty-lrucache
wget -c https://github.com/openresty/lua-resty-lrucache/archive/refs/tags/v0.13.tar.gz -O lua-resty-lrucache-v0.13.tar.gz --no-check-certificate
tar -zxvf lua-resty-lrucache-v0.13.tar.gz && rm lua-resty-lrucache-v0.13.tar.gz

# lua-cjson
wget https://www.kyne.com.au/~mark/software/download/lua-cjson-2.1.0.tar.gz --no-check-certificate --no-check-certificate
tar -zxvf lua-cjson-2.1.0.tar.gz && rm lua-cjson-2.1.0.tar.gz

1.4 安装PCRE库

cd pcre-8.45
./configure
make && make install
cd ../

1.5 安装zlib库

cd zlib-1.2.13
./configure
make && make install
cd ../

1.6 安装OpenSSL库

cd openssl-1.1.1q
./config --prefix=/usr/local/openssl
make && make install
cd ../
ln -s /usr/local/openssl/bin/openssl /usr/local/bin/openssl
echo "/usr/local/openssl/lib" >> /etc/ld.so.conf.d/libc.conf
ldconfig

验证 OpenSSL 版本

openssl version

1.7 安装LuaJIT库

cd luajit2-2.1-20220411
make PREFIX=/usr/local/luajit && make install PREFIX=/usr/local/luajit
cd ../
ln -s /usr/local/luajit/bin/luajit /usr/local/bin/luajit
echo "/usr/local/luajit/lib" >> /etc/ld.so.conf.d/libc.conf
ldconfig

验证 LuaJIT 版本

luajit -v

1.8 安装Nginx

cd nginx-1.22.0

# 设置环境变量
export LUAJIT_LIB=/usr/local/luajit/lib
export LUAJIT_INC=/usr/local/luajit/include/luajit-2.1

# 预编译参数设置
./configure \
--prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-pcre=../pcre-8.45 \
--with-zlib=../zlib-1.2.13 \
--with-openssl=../openssl-1.1.1q \
--with-cc-opt='-Os -fomit-frame-pointer -g' \
--with-ld-opt='-Wl,-rpath,/usr/local/luajit/lib,--as-needed,-O1,--sort-common' \
--add-module=../ngx_devel_kit-0.3.1 \
--add-module=../lua-nginx-module-0.10.21 \
--with-http_realip_module \
--with-http_ssl_module

make && make install
cd ../
ln -s /usr/local/nginx/sbin/nginx /usr/local/bin/nginx

1.9 安装lua-resty-core库

  1. 修改 Makefile 文件内容。

    cd lua-resty-core-0.1.23
    vim Makefile

    # 对原有内容进行修改。

    # 原有内容:
    LUA_LIB_DIR ?= $(PREFIX)/lib/lua/$(LUA_VERSION)

    # 修改后的内容:
    LUA_LIB_DIR ?= $(PREFIX)
  2. 开始安装。

    make install PREFIX=/usr/local/luajit/share/luajit-2.1.0-beta3/
  3. 清理残留文件。

    cd ../ && rm -rf lua-resty-core-0.1.23/

1.10 安装lua-resty-lrucache

  1. 修改 Makefile 文件内容。

    cd lua-resty-lrucache-0.13
    vim Makefile

    # 对原有内容进行修改。

    # 原有内容:
    LUA_LIB_DIR ?= $(PREFIX)/lib/lua/$(LUA_VERSION)

    # 修改后的内容:
    LUA_LIB_DIR ?= $(PREFIX)
  2. 开始安装。

    make install PREFIX=/usr/local/luajit/share/luajit-2.1.0-beta3/
  3. 清理残留文件。

    cd ../ && rm -rf lua-resty-lrucache-0.13

1.11 安装cjson

  1. 修改 Makefile 文件内容。

    cd lua-cjson-2.1.0
    vim Makefile

    # 对原有内容进行修改。

    # 原有内容:
    LUA_INCLUDE_DIR = $(PREFIX)/include

    # 修改后的内容:
    LUA_INCLUDE_DIR = $(PREFIX)/include/luajit-2.1/
  2. 修改 lua_cjson.c 文件内容。

    vim lua_cjson.c

    # 对原有内容进行修改。

    # 原有内容:
    static void luaL_setfuncs (lua_State *l, const luaL_Reg *reg, int nup)

    # 修改后的内容:
    void luaL_setfuncs (lua_State *l, const luaL_Reg *reg, int nup)
  3. 开始安装。

    make install PREFIX=/usr/local/luajit/
  4. 清理残留文件。

    cd ../ && rm -rf lua-cjson-2.1.0

2 下载和安装插件

在按照 如何获得瑞数云账号 的内容注册账号并购买服务后,进入 瑞数云管理界面,并通过 配置管理 > 站点配置 页面右上方的 下载插件 按钮(如下图所示),将插件的安装文件 keeper-lua.tar.gz 下载到本地。解压后得到文件名类似 keeper-lua_v1.5.3_amd64_debian.deb 的预编译文件,以及文件名类似 keeper-lua_v1.5.3_source.tar.gz 的源码文件。

将文件 keeper-lua_v1.5.3_source.tar.gz 复制到 Nginx 服务器的 pure-nginx-lua 路径下,然后进入该路径执行以下命令。

tar -zxvf keeper-lua_v1.5.3_source.tar.gz && rm keeper-lua_v1.5.3_source.tar.gz
mv riversec /usr/local/luajit/share/luajit-2.1.0-beta3/

3 修改插件配置文件

  1. 修改插件的初始化配置文件

    vim /usr/local/luajit/share/luajit-2.1.0-beta3/riversec/conf/init.conf

    # 对原有内容进行修改。

    # 原有内容:
    init_worker_by_lua_file /usr/local/openresty/lualib/riversec/handlers/init_worker.ljbc;

    # 修改后的内容:
    init_worker_by_lua_file /usr/local/luajit/share/luajit-2.1.0-beta3/riversec/handlers/init_worker.ljbc;
  2. 修改插件的防护配置文件

    vim /usr/local/luajit/share/luajit-2.1.0-beta3/riversec/conf/guard.conf

    # 对原有内容进行修改。

    # 原有内容:
    access_by_lua_file /usr/local/openresty/lualib/riversec/handlers/access.main.ljbc;
    header_filter_by_lua_file /usr/local/openresty/lualib/riversec/handlers/header_filter.ljbc;
    body_filter_by_lua_file /usr/local/openresty/lualib/riversec/handlers/body_filter.ljbc;
    access_log syslog:server=detector.riveryun.com,tag=revol_keeper revol_syslog_proxy;

    # 修改后的内容:
    access_by_lua_file /usr/local/luajit/share/luajit-2.1.0-beta3/riversec/handlers/access.main.ljbc;
    header_filter_by_lua_file /usr/local/luajit/share/luajit-2.1.0-beta3/riversec/handlers/header_filter.ljbc;
    body_filter_by_lua_file /usr/local/luajit/share/luajit-2.1.0-beta3/riversec/handlers/body_filter.ljbc;
    access_log syslog:server=detector.riveryun.com,tag=revol_keeper revol_syslog_proxy;
  3. 修改插件的通用配置文件

    vim /usr/local/luajit/share/luajit-2.1.0-beta3/riversec/static/config.json
    # 对原有内容进行修改。

    # 原有内容:
    "keeper_id": "keeper_GATEWAY_IP"
    "endpoint_url": "https://detector.riveryun.com/4h2uWW2S/",

    # 修改后的内容:
    "keeper_id": "输入一个字符串作为插件的名称,该名称将在接入成功后显示在瑞数云管理界面中",
    "endpoint_url": "/4h2uWW2S/",
    "config_endpoint_url": "http://localhost:80/4h2uWW2S/",

    💡   注意:

    上方最后一行内,localhost 后面的端口必须和 Nginx 配置文件中添加指令集的 server 所监听的端口相同。例如 4.2小节 中添加指令集的 server 所监听端口为 80,则 locahost 端口应该设置为 80。

4 配置Nginx服务器

配置 Nginx 服务器需要三个步骤:

❶ 创建站点防护配置,并获得配置 ID。

❷ 在配置文件中添加指令集。

❸ 重新加载配置文件。

4.1 获得站点防护配置ID

站点配置是指您在 瑞数云管理界面 中创建的安全防护方案。每个方案都有一个唯一的站点配置 ID 号(例如创建了一个名称为 website_protection 的方案,其 ID 号为 revol_b2rblvr25zo6lrcw), 如下图所示。

💡   提示:

请登录 瑞数云管理界面,并根据 使用手册 > 3.1 站点配置 中的描述新建站点配置。

将站点配置 ID 号复制下来,以便稍后使用。

4.2 在配置文件中添加指令集

首先将之前备份的 Nginx 配置文件名修改为 nginx.conf,然后复制到 /usr/local/nginx/conf/ 路径下覆盖原有文件。

假设原有 Nginx 配置文件如下所示。如果想对站点 website1.com 的路径 location / 进行保护,需要在下面几个配置块中(分别是 http 配置块下、server website1 的 location / 配置块下)分别插入对应的两个指令集,从而实现对该站点指定路径的保护。

# 针对 website1.com 下的根路径进行保护
worker_processes auto;
error_log logs/error.log error;

events {
worker_connections 1024;
}

http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;

###########################
###### 这里插入指令集 1 ######
###########################

server {
listen 80;
server_name website1.com;

###########################
###### 这里插入指令集 2 ######
###########################

location / {

###########################
###### 这里插入指令集 3 ######
###########################

proxy_pass http://10.10.71.143:9090;
}
}

server {
listen 82;
server_name website2.com;
location / {
proxy_pass http://10.10.71.143:8080;
}
}
}

以下展示了插入指令集后的配置文件内容。

💡   注意:

每个指令集中需要修改的指令下方都添加了注释,请务必按照注释进行相应的修改。

worker_processes auto;
error_log logs/error.log error;

events {
worker_connections 1024;
}

http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;


1️⃣ ###### 指令集 1 开始行: 记住测试环境中需要指定一个有效 DNS 地址!!!
resolver 61.139.2.69 ipv6=off;
# 在测试环境中需要为 Nginx 指定一个有效的 DNS 地址,例如电信 DNS 61.139.2.69。如果原配置文件中已经配置了 DNS,则可以注释这一行。

lua_package_path "/usr/local/luajit/share/luajit-2.1.0-beta3/?.ljbc;/usr/local/luajit/share/luajit-2.1.0-beta3/?.lua;;";

include /usr/local/luajit/share/luajit-2.1.0-beta3/riversec/conf/init.conf;​
1️⃣ ###### 指令集 1 结束行


server {
listen 80;
server_name website1.com;


2️⃣ ###### 指令集 2 开始行
set $site_id 'revol_b2rblvr25zo6lrcw';
# 确保该指令最后的字符串是刚才复制的站点配置 ID

location /4h2uWW2S/pluginConfigs {
proxy_pass https://detector.riveryun.com/4h2uWW2S/pluginConfigs;
}

location /4h2uWW2S/ {
access_by_lua_file /usr/local/luajit/share/luajit-2.1.0-beta3/riversec/handlers/access.web.ljbc;
proxy_pass https://detector.riveryun.com/4h2uWW2S/;
} ​
2️⃣ ###### 指令集 2 结束行


location / {


3️⃣ ###### 指令集 3 开始行
include /usr/local/luajit/share/luajit-2.1.0-beta3/riversec/conf/guard.conf; ​
3️⃣ ###### 指令集 3 结束行


proxy_pass http://10.10.71.143:9090;
}
}

server {
listen 82;
server_name website2.com;
location / {
proxy_pass http://10.10.71.143:8080;
}
}
}

💡   提示:

以上为针对单一路径提供防护的实例配置。目前针对原生 Nginx 环境,暂不支持多路径上的防护。

4.3 重新加载配置文件

完成上面的配置后,执行 /usr/local/nginx/sbin/nginx -s reload -c /usr/local/nginx/conf/nginx.conf 重新加载配置文件,即可实现瑞数云接入。

💡   提示:

如果是全新安装 Nginx 的情况,而不是在已有 Nginx 的服务器上进行安装,则此时 Nginx 进程尚未启动。需要将上面的命令更换为以下命令。

/usr/local/nginx/sbin/nginx

5 验证接入

为了验证站点已经成功接入瑞数云,请先通过浏览器访问该站点的域名。然后按照以下两个方法进行验证,如果看到的现象与以下两个方法的描述都相符,表示站点已成功完成接入。

方法 1. 在浏览器开发者工具中 (按下 F12 打开该工具),确认站点下包含名为 zVZqPpaP 的 Cookie。

方法 2. 登录 瑞数云管理界面,在 配置管理 > 站点配置 页面中,连接的插件 一栏下方,确保插件名称 keeper_GATEWAY_IP 如下图所示,以蓝色背景显示为一个标签(鼠标悬停在名称上方可查看全名)。

💡   提示:

方法 2 中显示的 “连接的插件” 名称为插件的默认名称,当它显示为蓝色标签时,表示当前 Nginx 上安装的插件已经在正常工作。该名称可以根据需要进行更改,例如修改为当前 Nginx 服务器的 IP 地址,表示该服务器上正在运行插件。请阅读 附录 1 插件配置项 获取修改方法。

6 手动逃生

方法一

如果遇到紧急情况,可以通过插件配置文件 /usr/local/luajit/share/luajit-2.1.0-beta3/riversec/static/config.json 的修改,让访问流量绕过插件直接转发到后端服务器,保证业务流量的持续性。

打开该配置文件,然后将顶层键值对中的 “enable” 设置为 false 并保存,然后通过 /usr/local/nginx/sbin/nginx -s reload -c /usr/local/nginx/conf/nginx.conf 命令重新加载配置即可实现逃生。如下所示:

{
"module": "guard",
"company": "riversec",
"version": "v1.5.3",
"build": "6e6c503",
"endpoint_url": "https://detector.riveryun.com/4h2uWW2S/",
"enable": false, # 修改为 false 实现手动逃生
"keeper_id": "keeper_GATEWAY_IP",
"http": {
"interval_in_seconds": 3,
"max_retry": 3,
"connect_timeout_ms": 1000,
"send_timeout_ms": 100,
"read_timeout_ms": 100
}
}

方法二

除了上面通过修改插件的配置文件实现逃生,还可以通过在 Nginx 的配置文件 /usr/local/nginx/conf/nginx.conf 中注释下方所列出的两行指令,来实现相同的效果。

# 注释掉 Nginx 配置文件中所添加的这两行指令
# include /usr/local/luajit/share/luajit-2.1.0-beta3/riversec/conf/init.conf;
# include /usr/local/luajit/share/luajit-2.1.0-beta3/riversec/conf/guard.conf;

注释后,通过 /usr/local/nginx/sbin/nginx -s reload -c /usr/local/nginx/conf/nginx.conf 命令重新加载配置,即可实现逃生。

附录 1 插件配置项

插件安装后,会生成专门的配置文件 (/usr/local/luajit/share/luajit-2.1.0-beta3/riversec/static/config.json)。通常采用默认配置即可生效,不需要进行更多修改。

但如果需要修改插件的名称、禁用插件实现手动逃生(参考 手动逃生 > 方法一)、以及实现其他操作,则可以通过修改这个 JSON 文件中的配置项来实现。

修改插件名称

当插件成功与瑞数云连接后,插件名称(即下方 keeper_id 的值)会在 瑞数云管理界面配置管理 > 站点配置 页面中 连接的插件 一栏中,以蓝色底纹显示。

因此建议将 /usr/local/luajit/share/luajit-2.1.0-beta3/riversec/static/config.json 文件中的 “keeper_id” 值修改为易于理解的字符串,例如当前 Nginx服务器的名称或 IP 地址 (假设是 10.0.0.1),如下所示:

{
"module": "guard",
"company": "riversec",
"version": "v1.5.3",
"build": "6e6c503",
"endpoint_url": "https://detector.riveryun.com/4h2uWW2S/",
"enable": true,
"keeper_id": "10.0.0.1", # 修改为插件所在服务器的名称或地址,显示在瑞数云管理界面中
"http": {
"interval_in_seconds": 3,
"max_retry": 3,
"connect_timeout_ms": 1000,
"send_timeout_ms": 100,
"read_timeout_ms": 100
}
}

保存后,通过 /usr/local/nginx/sbin/nginx -s reload -c /usr/local/nginx/conf/nginx.conf 命令重新加载配置,然后通过浏览器访问站点,2-3秒后即可生效。这时登录 瑞数云管理界面,进入 配置管理 > 站点配置 页面,即可看到该名称以蓝色底纹显示在 连接的插件 一栏中。

配置项列表

以下列表包含了 config.json 文件中主要配置项的说明。

enable : 是否启用整个模块下的所有功能,可设置为truefalse,默认为true

keeper_id : 用来标识站点配置在哪个插件上被使用,默认为revol_keeper_default

http.interval_in_seconds : 设置针对瑞数检测服务的健康检查间隔时间(单位: 秒), 默认为3。(请同时参考 使用手册 > 附录3 已知问题 中的问题1)

http.max_retry : 设置针对瑞数检测服务的健康检查重试次数,检测服务无正常响应的次数连续超过该数字,则认为检测服务不可用,会立刻禁用本插件功能,默认为3

http.connect_timeout_ms : 健康检查的连接超时设置,默认值为100ms,详见 openresty lua sock

http.send_timeout_ms : 健康检查的发送超时设置,默认值为100ms

http.read_timeout_ms : 健康检查的接收超时设置,默认值为100ms

附录 2 默认站点配置ID

登录 瑞数云管理界面 后进入 配置管理 > 站点配置 页面,可以看到一个以 “default” 结尾的默认站点配置 ID,例如 "revol93791579_config_default"。

默认站点配置 ID 将会作为其他自定义配置 ID 的备用 ID。如果某个正在使用的配置 ID 由于某些原因失效(例如配置 ID 被误删除),那么插件会自动尝试连接默认的站点配置 ID,并在连接成功后应用其中的安全配置。

插件通过 /usr/local/luajit/share/luajit-2.1.0-beta3/riversec/static/default.json 文件中的 uid 键值来读取和连接默认的站点配置 ID。请将 uid 键值改为您的默认站点配置 ID,如下方例子所示。

{
"uid": "revol_config_default", # 将 "revol_config_default" 改为 "revol93791579_config_default"
"mode": "0",
"hide_server_version": true,
"token": {
"action": {
"block_page": "<html><body>BLOCKED</body></html>",
"reload_page": "<html><meta id=\"TiQn\" content=\"AQ\"><body></body></html>",
"block_status_code": 400,
"reload_status_code": 412
}
},
"mobile": {
"enable": false,
"shakehdr": "X-Revol-Shake",
"sechdr": "Eoh8Woo5",
"block_response": "{\"title\":\"Forbidden\", \"description\": \"You are not allowed to do this.\"}",
"reload_response": "{\"title\":\"Unauthorized\", \"description\": \"Please send me a valid token.\"}",
"block_status_code": 400,
"reload_status_code": 412
},
"list": {
"mode": "all",
"ips": "disabled",
"paths": "disabled"
}
}

💡   注意:

默认站点配置 ID 默认为透传模式。

保存修改后,执行 /usr/local/nginx/sbin/nginx -s reload -c /usr/local/nginx/conf/nginx.conf,重新加载使其生效。

附录 3 卸载插件

方法一:

在 Nginx 服务器上执行 rm 命令,删除 riversec 目录来实现卸载。

  1. 执行 rm 命令来卸载插件

    rm -rf /usr/local/luajit/share/luajit-2.1.0-beta3/riversec/
  2. 用之前备份的 Nginx 配置文件覆盖当前配置文件。

  3. 然后执行以下命令重新加载 Nginx 配置文件。

    /usr/local/nginx/sbin/nginx -s reload -c /usr/local/nginx/conf/nginx.conf
  4. 登录 瑞数云管理界面配置管理 > 站点配置 页面中 连接的插件 一栏下的插件标签变成灰色,表示插件已断开连接。如果通过浏览器能够打开站点页面,表示已成功完成卸载,站点已恢复到安装之前的状态。

方法二:

在 Nginx 服务器上执行 dpkg 命令来卸载服务器上安装的插件。

  1. 执行 dpkg 命令来卸载插件。

    dpkg -r keeper-lua
  2. 用之前备份的 Nginx 配置文件覆盖当前配置文件。

  3. 然后执行以下命令重新加载 Nginx 配置文件。

    /usr/local/nginx/sbin/nginx -s reload -c /usr/local/nginx/conf/nginx.conf
  4. 登录 瑞数云管理界面配置管理 > 站点配置 页面中 连接的插件 一栏下的插件标签变成灰色,表示插件已断开连接。如果通过浏览器能够打开站点页面,表示已成功完成卸载,站点已恢复到安装之前的状态。