arrow-left

Only this pageAll pages
gitbookPowered by GitBook
1 of 67

OpenRASP Documents (Old)

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

开发插件

本节介绍如何开发并发布一个 JavaScript 检测插件。

hashtag
开发环境准备

  1. 下载并安装 NodeJSarrow-up-right,Ubuntu 系统可使用 sudo apt-get install -y nodejs 命令进行安装

  2. 安装插件开发工具 openraspjs:

hashtag
编写第一个插件

检测插件针对应用的行为进行检测,当应用执行数据库查询、文件读写等操作,OpenRASP 引擎就会调用检测插件,并将相关参数一并传递过来。一个最小的SQL检测插件如下所示:

首先,我们调用 plugin.register 注册了SQL查询的检测函数,并将SQL语句打印到插件日志。其中,

  • params 为检查点提供的参数,如SQL语句、要读取的文件等等

  • context 为请求信息,如请求参数,服务器信息等等

然后,我们在回调函数里,调用 plugin.log 打印了SQL查询语句

最后,我们在回调函数里,返回检测结果,即 "放行"

目前我们支持14个检测点,具体请看 文档。

hashtag
调用插件接口

我们在 RASP 类里提供了一些接口,可以直接在插件里调用。比如,你可以调用 RASP.sql_tokenize 将SQL语句转化为 token:

详细 JS API 说明请看 文档。

hashtag
测试检测插件

现在,我们已经完成了检测插件,下一步是进行测试。测试有两种方法:

  1. 参考 ,编写JSON测试用例并使用 openraspjs 进行测试

  2. 参考 ,将插件放到安装了 OpenRASP 的应用服务器进行测试

若你是初次接触插件开发,我们推荐使用第二种方式,即使用 OpenRASP 单机版调试。具体调试方法请参考上述文档,这里不再赘述。

hashtag
拦截危险操作

现在,我们已经能够编写检测插件,并在客户端运行。接下来就是拦截攻击了,在回调函数里,将返回的 action 字段改为 block 即可拦截请求。比如,当SQL语句包含union注入特征,我们想拦截整个请求的话,可以这样写:

在官方插件里,实际的检测算法要复杂的很多,有兴趣可以参考 的实现。如果不想拦截攻击,只是想记录攻击日志,可将 action 字段设置为 log。

最后, confidence 字段用来标记报警的可信度,官方插件的范围是 90~100,越高报警的可靠性越高。

注意: 当某个插件拦截了攻击,其他插件将不在被调用。

hashtag
FAQ

1. 插件支持 ES6 语法吗?{#faq-1}

  • 插件环境可能不支持某些最新的 JavaScript 语法,请使用 openrasjs 进行语法检查

  • 插件不能使用与平台相关的全局对象,只能使用

  • 插件可以像编写 Node.js 程序一样引入其他模块,然后通过 webpack 或 browserify 等工具打包成一个文件,但是注意不能引入与平台相关的模块,例如: Node.js 的 http 模块

2. 如果检测点没有返回对象,或者返回的对象不合法,会怎么样?{#faq-2}

  • 若检查点没有返回对象,等于 ignore

  • 若检查点返回了对象,但 action 值不存在或者不为 block/log/ignore 之一,等价于 log

参数说明arrow-up-right
接口说明arrow-up-right
单元测试arrow-up-right
安装插件arrow-up-right
official.jsarrow-up-right
JavaScript 标准内建对象arrow-up-right
npm install -g openrasp
const plugin_version = '2018-1000-1000'
const plugin_name    = 'test-plugin'

'use strict'
var plugin  = new RASP(plugin_name)

const clean = {
    action:     'ignore',
    message:    'Looks fine to me',
    confidence: 0
}

// BEGIN ALGORITHM CONFIG //

var algorithmConfig = {}

// END ALGORITHM CONFIG //

plugin.register('sql', function (params, context) {
    plugin.log('SQL query: ' + params.query)
    return clean
})

plugin.log('plugin-demo: plugin loaded')
plugin.register('sql', function (params, context) {
    plugin.log('SQL tokens ', RASP.sql_tokenize(params.query, params.server))
    return clean
})
plugin.register('sql', function (params, context) {
    plugin.log('SQL tokens ', RASP.sql_tokenize(params.query, params.server))
    
    if (/union.*select.*from.*information_schema/.test(params.query)) {
        return {
            action:     'block',
            message:    '拦截SQL查询,因为XXX',
            confidence: 90
        }
    }
    
    return clean
})

RASP 类接口

所有插件需要实例化一个 RASP 对象,并在此对象上注册各检测点对应的检测程序

hashtag
创建实例

创建 RASP 实例需传入插件名,e.g demo

hashtag
获取agent版本号 (v1.2.0 加入)

hashtag
获取JS引擎名称

hashtag
发送HTTP请求 (v1.2.0 加入)

支持发送 GET/POST 请求,其中 data 字段可以是字符串、对象或者 Buffer

hashtag
注册检测程序到对应检测点

检测函数接受两个参数

  • params 对应检测点的参数信息

  • context 请求上下文信息

具体有哪些检测点可以注册,以及 params 的样例,请参考检

注意: 对于同一个检测点,如果你注册了多个检测函数,这些函数会按照注册顺序,依次调用

hashtag
将SQL语句解析为 Token(BETA)

函数接受两个参数

  • query 表示要解析的查询语句

  • server 表示SQL服务器类型

目前本功能还在试验阶段,且暂时不区分SQL服务器类型。

hashtag
将 Bash/CMD 语句解析为 Token(BETA)

函数接受一个参数

  • command 表示要解析的命令

目前本功能还在试验阶段,且暂时不区分操作系统

hashtag
打印调试日志

使用方法与 console.log 一致,只是会同时输出插件的名字,方便你区分不同插件的日志

hashtag
获取插件名

hashtag
手动调用检测方法

在编写单元测试时,可手动调用此方法

这个方法会按照注册顺序,依次调用所有的检测函数,并返回一个检测结果数组

e.g 模拟一个SQL注入请求,请调用插件获取检测结果

var plugin = new RASP('demo')
参数说明
var name = plugin.get_version()
// 返回 1.2.0
var name = plugin.get_jsengine()
// 返回 rhino / v8
var body = {
    "name": "openrasp"
}

var req  = {
    "method":       "post",
    "url":          "http://127.0.0.1/test",
    "data":         data,
    "maxRedirects": 0,
    "timeout":      30,
    "headers": { 
        "content-type": "application/json"
    },    
}
    
RASP.request(req)
plugin.register('sql', function(params, context) {
  // 在这里实现检测逻辑
  // 并返回结果
  return {
     action: 'ignore',
     message: '无风险'
  }
})
RASP.sql_tokenize('SELECT * FROM users WHERE id = -1 union/*!50000select*/1,2,3', 'mysql')
// [
// 	  { text: 'SELECT', start: 0, stop: 5 },
// 	  { text: '*',      start: 7, stop: 7 },
// 	  ...
// ]
RASP.cmd_tokenize('/bin/bash -c ls')
// [ 
//    { text: '/bin/bash', stop: 8,  start: 0  },
//    { text: '-c',        stop: 11, start: 10 },
//    { text: 'ls',        stop: 14, start: 13 } 
// ]
plugin.log('hello', 'openrasp')
// 将会在日志里输出 [demo] hellp openrasp
var name = plugin.name
// => 'demo'
var params = {
  'query': 'select * from users',
  'server': 'mysql'
}
var checkContext = new Context()
RASP.check('sql', params, context)
// => [{
//    'action': 'block',
//    'message': 'attack',
//    'name': 'demo'
// }]

Java 版本

hashtag
简要说明

java 版本使用 javaagent 机制来实现。在服务器启动时,可动态的修改Java字节码,对敏感操作的函数进行挂钩,比如:

  • 数据库操作

  • 文件读取、写入操作

  • 命令执行

  • ...

当服务器发生攻击,就会触发这些Hook点,此时RASP agent就可以获取到函数的参数,比如要读取的文件名、要执行的命令等等。

hashtag
启动流程

  1. 启动时首先会进入 javaagent 的 premain 函数,该函数会在 main 函数之前预先执行,

  2. 当去 hook 像 java.io.File 这样由 BootstrapClassLoader 加载的类的时候,无法从该类调用非 BootstrapClassLoader 加载的类中的接口,所以 agent.jar 会先将自己添加到 BootstrapClassLoader 的ClassPath下,这样 hook 由 BootstrapClassLoader 加载的类的时候就能够成功调用到 agent.jar 中的检测入口

hashtag
Hook Class 流程

  1. 因为启动时候进行了插桩操作,当有类被 ClassLoader 加载时候,所以会把该类的字节码先交给自定义的 Transformer 处理

  2. 自定义 Transformer 会判断该类是否为需要 hook 的类,如果是会将该类交给 javassist 字节码处理框架进行处理,

  3. javassist 框架会将类的字节码依照事件驱动模型逐步解析每个方法,当触发了我们需要 hook 的方法,我们会在方法的开头或者结尾插入进入检测函数的字节码

启动时架构如下图所示:

hashtag
请求处理流程

我们以 tomcat + JDBC + MySQL 为例,简单说明下请求处理的流程

  1. 服务器收到一个请求,从而进入了服务器的请求 hook 点(该 hook 点每个服务器不一样,具体参照源码),该 hook 点标注当前线程为请求线程,开启当前线程的检测开关并把请求对象和响应对象进行缓存,以便后面使用

  2. 服务器发起SQL查询

  3. 进入 SQLStatementHook 点,我们挂钩了 execute、executeUpdate、executeQuery 等方法,从该方法进入检测流程如下:

OpenRASP 中JS引擎执行架构如下图所示:

hashtag
基线检测

我们以 tomcat 启动为例,说明基线检测流程

  1. 进入了基线检测关键函数(tomcat 启动函数)

  2. 进入本地基线检测插件(注:基线检测不进入js插件检测),检测当前环境的关键参数(http-only是否开启,是否为root启动等)

  3. 根据检测结果决定是否拦截,不拦截的情况下只打印日志到 logs/policy_alarm.log

检测架构如下图所示:

释放 log4j 日志配置文件,如果存在则跳过

  • 根据 openrasp.yml 文件初始化相应配置项

  • 初始化 JS 插件模块

    • JS 上下文类初始化

    • 插件文件初始化

  • 初始化字节码转换模块

    • 给 load class 操作进行插桩操作,当类加载的时候会先进入 agent 进行处理

    • 对于在初始化前已加载的类执行 retransform 处理,e.g FileInputStream

  • 输出启动成功日志,开启全局 Hook 开关(启动阶段为关闭状态)

    • 若启动过程中发生错误,记录错误日志

  • 给 openrasp.yml 配置文件和 js 插件目录以及 assets 目录增加文件监控,以便文件内容更改的时候不需要重启就能够实时生效

  • 把 hook 好的字节码返回给 transformer 从而载入虚拟机
    判断当前线程是否为请求线程(第一步标记的),如果是继续下面检测
  • 采集 connection_id(这个字段仅JDBC支持)、SQL 语句以及数据库类型 等信息

  • 构建参数信息,调用本地插件和 JS 插件进行安全检测,JS 插件由 Rhino 引擎执行,Rhino 引擎执行是 mozilla 为 java 提供的 JavaScript引擎,该引擎会将 JS 代码编译为 java 的 class 字节码在 JVM 中运行,Rhino 引擎文档arrow-up-right

  • 根据插件的执行结果决定是拦截请求、放行还是仅打印日志

  • 进入 SQLResultSetHook 点,我们挂钩了 resultSet.next 方法

    • 调用本地插件检查是否发生拖库行为,默认策略为一次查询结果超过500条就报警

  • 若决定拦截攻击

    • 输出报警日志到 logs/alarm.log

    • 如果header还没有发出,默认使用 302 跳转到拦截页面

    • 如果body还没有发出,则重置未发送的body

    • 输出自定义拦截页面跳转js脚本

      • </script><script>location.href='.../?request_id=xxx'</script>

  • javaagent参考文档arrow-up-right
    javassistarrow-up-right
    images/startup.png
    images/js.png
    images/check.png

    Context 类接口

    Context 类包含当前请求信息和服务器信息

    hashtag
    获取请求路径

    绝对路径,不包含 Query String

    hashtag
    获取 Query String

    返回URL参数

    hashtag
    获取请求方法

    字母为小写

    hashtag
    获取请求协议

    hashtag
    获取请求头

    获取当前请求的 headers,其中key的名字均为小写。这个值可能为空,使用前需要判断,e.g if (context.header != null)

    hashtag
    获取请求体

    仅返回请求体原始数据的前4KB,类型为

    因受到服务器限制,插件系统不保证一定能够获取到请求体原始数据。在Java应用下面,只有应用读取了body,插件才能获取到。因此在 request hook 点是拿不到 body 的。

    hashtag
    获取请求 JSON

    获取当前请求的 POST JSON 参数

    hashtag
    获取请求参数

    对于 java 服务器,当用户已经获取过请求参数的情况下, 我们会返回 ServletRequest.getParameterMap() 的结果,也就是 Map<String, String[]>

    当用户还没有获取过任何参数, 我们会返回空对象, 这样做既可以保证用户在获取参数的时候不会产生乱码, 同时在插件中做用户参数匹配检测过程中也可以降低误报率。若要在 request hook 点获取到用户输入,请参考 文档,设置 request.param_encoding 参数。

    hashtag
    获取请求来源地址

    这个参数只是应用服务器看到的请求来源IP。如果是反向代理部署方式,你可能需要获取 X-Forwarded-For、X-Client-IP 等HTTP响应头数据

    hashtag
    获取服务器信息

    当前服务器的属性,包括服务器类型、开发语言等等

    若要判定是否为 Windows 系统,可使用 context.server.os.indexOf('Windows') == 0

    hashtag
    获取Web根目录

    对于java服务器,返回 webapps 目录;对于php服务器,返回 webroot

    hashtag
    自定义实例

    在编写单元测试时,若要同时模拟请求信息,可以通过自定义 Context 实例的方式来实现,e.g

    当然,除了请求方法以外,你可还可以自定义其他参数,

    如果没有定义某个方法,这个方法将返回 undefined

    参数说明

    若要实现检测逻辑,插件需要先注册检测方法,e.g SQL注入检测插件可注册 sql 类型的回调

    具体插件可注册的回调类型 type,以及回调参数 params 的样例如下。另外,所有检测点都可以使用 params.stack 参数,以获取当前堆栈信息。

    hashtag
    数据库查询

    hashtag
    读取目录

    hashtag
    请求参数

    当应用接受到请求时,插件可以对请求进行拦截。(注意: PHP Agent 1.1 开始才支持)

    这里不会传递任何参数,如果需要获取请求相关信息,请使用

    hashtag
    读取文件

    注意:

    1. 对于 PHP 服务器,若实际读取文件以 https://、http://、ftp:// 之一开头,将会调用 服务器端 HTTP 请求 检测点,不会触发 读取文件 检测点

    hashtag
    写入文件

    出于性能考虑,OpenRASP 目前只会提供文件名和绝对路径两个参数

    注意:

    1. tomcat 等应用服务器,在部署war包时,暂时不会触发这个回调

    2. 对于NTFS数据流,e.g abc.php::$DATA,插件看到的 path 可能是 abc.php::$DATA,realpath 可能是 c:\inetpub\wwwroot\abc.php

    hashtag
    删除文件

    hashtag
    文件包含操作

    url 可能是协议(file、http等等),也能是相对路径(/abc/、abc.txt)

    支持的文件包含方式如下,

    1. Java - JSTL import 方式

      • 只有 url 里出现了 :// 且不为 / 开头时,我们才会调用插件

    2. PHP - include/require/include_once/require_once 四种方式

    具体参数

    hashtag
    WebDAV 操作

    目前仅支持 MOVE、COPY 两种方法

    hashtag
    文件上传

    目前,OpenRASP 支持 org.apache.commons.fileupload 上传组件(SpringMVC、Struts 底层使用)

    出于性能考虑,OpenRASP 只会提取文件前 4 KB 的内容,若要获取更多字节,请参考

    hashtag
    文件重命名

    当源是文件,且目标不为文件夹(可以不存在)时才会进入插件

    hashtag
    命令执行

    hashtag
    XML 外部实体引用

    目前,PHP不支持XXE检测

    hashtag
    Struts OGNL 表达式解析

    注意: 为了减少性能影响,仅当表达式长度超过 30 时才会调用插件。可手动 ognl.expression.minlength 选项来进行调整

    hashtag
    RMI 反序列化

    hashtag
    服务器端 HTTP 请求

    支持的请求方式包含如下 (对应 function 字段),

    1. JDK 中的 URL.openConnection 的方式 (url_open_connection)

    2. commons-httpclient 框架请求方式 (commons_http_client)

    3. httpclient 框架请求方式 (http_client)

    hashtag
    服务器端 HTTP 请求 - 重定向之后

    支持的请求方式包含如下 (对应 function 字段),

    1. JDK 中的 URL.openConnection 的方式 (url_open_connection)

    2. httpclient 框架请求方式 (http_client)

    3. PHP stream 请求、cURL 请求

    hashtag
    代码执行

    目前支持 eval/function 两种函数

    hashtag
    类库加载

    目前仅支持 java System.load() 方式

    hashtag
    响应检查

    说明

    1. Java 下面如果 body 过大,会多次分段调用

    2. 当响应类型包含 image、audio、video 字样,不会进入插件

    3. 该检测点不支持拦截

    参数

    PHP 版本

    hashtag
    简要说明

    关于PHP扩展开发,可参考 Extending and Embedding PHParrow-up-right。

    以 cli SAPI 为例,其单个请求生命周期如下图所示:

    ref: Extending and Embedding PHP

    OpenRASP 核心原理为:在 MINIT 阶段,替换全局compiler_globals的function_table与class_table中特定 PHP_FUNCTION 对应的函数指针(封装原有handler,增加前置、后置处理),由此实现对敏感函数的挂钩。通过敏感函数参数结合请求信息判断是否存在攻击行为,进而采取拦截或者放行操作。

    hashtag
    启动流程

    OpenRASP 采用模块化的结构,按照初始化顺序,启动流程如下:

    1. 初始化OpenRASP所需全局变量

    2. 注册INI配置条目,通过ini配置文件初始化全局配置

    3. 日志模块,记录报警、插件、基线等日志,支持FILE/TCP/UDP

    4. V8模块,JS运行环境,负责插件加载与结合运行时上下文的检测能力

    下面针对几个主要的模块进行针对性说明:

    hashtag
    日志模块{#log-module}

    日志模块启动流程如下:

    1. 初始化日志模块所需全局变量

    2. 申请共享内存(针对特定SAPI),用于部分日志的进/线程间同步

    3. 获取本机网卡以及主机信息,用于基线日志记录

    hashtag
    V8模块

    我们将 V8 嵌入到 OpenRASP 中作为 JavaScript 插件的执行引擎

    • MINIT 阶段载入所有插件,生成一份 V8 Startup Snapshot

    • 请求处理线程第一次触发检测时,使用 V8 Startup Snapshot 还原此线程独享的 V8 Isolate

    • 每个请求线程在对应的 V8 Isolate 环境上执行检测逻辑

    hashtag
    HOOK模块

    HOOK流程包含两类:compiler_globals的handler替换和用户自定义opcode_handler,启动流程如下

    1. 在全局compiler_globals对应的hashtable(function_table和class_table)中查找非禁用函数对应zend_function

    2. 封装原有handler,根据需求增加前置、后置处理

    3. 针对指定opcode(如ZEND_INCLUDE_OR_EVAL)通过zend_set_user_opcode_handler自定义处理逻辑

    hashtag
    文件监控模块

    我们使用经过我们优化增强的 libfswatch 实现了跨平台的文件监控

    • MINIT 阶段初始化 fswatch 实例,并开启后台线程进行目标文件目录监控

    • 目标文件目录发生变化时,根据类型,向支持重载的 SAPI 主线程发送重载信号

    • MSHUTDOWN 阶段停止目标文件目录监控,销毁 fswatch 实例和后台线程

    hashtag
    白名单实现

    经过对比,我们最终选择了 Double Array Trie 算法来匹配白名单,具体实现如下:

    1. 白名单存储。白名单放在共享内存里,当云端下发新的配置,通过读写锁更新

    2. 白名单匹配。使用 Double Array Trie 算法在白名单里寻找匹配的项目,并生成检测类型的 bitmask。当进入检测点,根据 bitmask 来决定是否直接放行。

    3. 内存消耗。每个检测类型最多允许10条白名单,URL长度最大200。最坏情况下,PHP 版本内存 400 KB。

    hashtag
    容器支持

    为了适配百度内部的ORP平台,我们特意实现了扩展进程管理模型,以避免再安装一个独立的agent。

    在扩展初始化阶段,我们会 fork 出三个进程,分别用于异步日志发送、远程管理、进程守护等功能;在 PHP-FPM 或者 apache 退出或者重启时,我们会杀死这些进程。具体请参考我们的代码实现。

    hashtag
    请求处理流程

    以PHP(mysqli) + MySQL为例,简要说明请求处理的流程,即 RINIT - RSHUTDOWN 阶段:

    1. 为新请求计算唯一的request-id,设置response header

    2. 初始化不同logger,收集日志相关请求信息

    3. 连接数据库,触发 mysqli_connect HOOK点:enforce_policy为1时,若用高权限用户连接数据库,记录基线日志,中断当前请求;enforce_policy为0时,仅当成功连接数据库后检查是否为高权限用户,若是记录日基线志,并将连接信息存入共享内存防止其他进/线程重复报警

    context.path
    // => '/my/article.jsp'
    plugin.register('sql', function(params, context) { 
        // 实现你的检测逻辑
    })
    type   = sql
    params = {
        "server": "mysql / oracle / pgsql / mssql / sqlite",
        "query":  "select * from users",
    }

    HOOK模块,敏感PHP_FUNCTION挂钩执行检测及检测结果处理

  • INJECT模块,针对特定URL,修改响应内容,注入HTML

  • 安全基线检查模块,检查敏感ini配置项

  • 文件监控模块,监控插件目录,实现运行时检测逻辑修改

  • 执行检测逻辑前向 V8 Platform 添加超时监控后台任务,超时后中断检测
  • GSHUTDOWN 阶段销毁线程对应 V8 Isolate

  • 数据库语句检测,即mysqli_query HOOK点pre检测,收集查询参数调用V8模块执行检测,具体流程如下:

    1. (待添加)

  • 慢查询检测。即mysqli_query HOOK点post检测,通过 call_user_function 检测查询结果数目,超过 openrasp.slowquery_min_rows 配置项则报警

  • RSHUTDOWN阶段:释放请求相关资源,根据 openrasp.inject_urlprefix 配置判断是否注入用户自定义HTML

  • ArrayBufferarrow-up-right
    其他配置arrow-up-right
    • 当 url 里包含 :// 时,调用插件

    • 如果文件以 .php 或者 .inc 结尾,或者真实路径在 webroot 下面,不会进入插件

    • 其他情况进入插件

    PHP stream 请求、cURL 请求

    API接口arrow-up-right
    配置文档arrow-up-right
    context.querystring
    // => 'offset=10&size=10'
    context.method
    // => 'get'
    context.protocol
    // => 'https'
    context.header
    // => {
    //   'user-agent': 'Chrome',
    //   'content-type': 'application/json'
    //   ...
    // }
    context.body
    // => ArrayBuffer
    context.json
    // => {
    //   'field': 'Value',
    //   ...
    // }
    // context.querystring = 'offset=10&size=10'
    // context.body = 'filter=odd'
    context.parameter
    // => {
    //   'offset': ['10'],
    //   'size':   ['10'],
    //   'filter': ['odd']
    // }
    context.remoteAddr
    // => '2.3.3.3'
    context.server
    // {
    //    'name': 'Tomcat / JBoss / Jetty',
    //    'version': '8',
    //    'os': 'Linux',
    //    'language': 'java / php' 
    // }
    context.appBasePath
    // => '/home/tomcat/webapps'
    var context = new Context()
    
    // 自定义 method 参数信息
    var context = new Context({
      getMethod: function() {
        return 'get'
      }
    })
    var context = new Context({
      getPath: function(){},
      getQuerystring: function(){},
      getMethod: function(){},
      getProtocol: function(){},
      getHeader: function(){},
      getParameter: function(){},
      getBody: function(){},
      getRemoteAddr: function(){},
      getServer: function(){}
    })
    type   = directory
    params = {
        "path":     "/home/servers/tomcat/webapps/mywar/../../../../../../../../../etc/",
        "realpath": "/etc/",
        "stack":    [
            "java.lang.ProcessBuilder.start",
            "sun.reflect.NativeMethodAccessorImpl.invoke0",
            "sun.reflect.NativeMethodAccessorImpl.invoke",
            "sun.reflect.DelegatingMethodAccessorImpl.invoke",
            ...
        ]
    }
    type   = request
    params = {}
    type   = readFile
    params = {
        "path":     "/home/servers/tomcat/webapps/mywar/../../../../../../../../../etc/hosts",
        "realpath": "/etc/hosts"
    }
    type   = writeFile
    params = {
        "path":     "abc.jsp",
        "realpath": "/home/tomcat/webapps/ROOT/abc.jsp",
        "stack": [
            ...
        ]
    }
    type   = deleteFile
    params = {
        "path":     "/home/servers/tomcat/webapps/mywar/../../../../../../../../../tmp/testfile",
        "realpath": "/tmp/testfile"
    }
    # Java 示例
    type   = include,
    params = {
        url:      "file:///etc/passwd",
        function: "jstl_import",
        realpath: "/etc/passwd"
    }
    
    # PHP 示例
    type   = include,
    params = {
        url:      "/home/webroot/footer/../../../../../../../../../etc/passwd",
        function: "require_once",
        realpath: "/etc/passwd"
    }
    type   = webdav,
    params = {
        "source": "/home/rsync/apache-tomcat-7.0.78/webapps/webdav/1.txt",
        "dest":   "/home/rsync/apache-tomcat-7.0.78/webapps/webdav/1.jsp"
    }
    type   = fileUpload
    params = {
        "name":          "file",
        "filename":      "a.jsp",
        "content":       "<% ... %>",
        "dest_path":     "upload/a.jpg",           # v1.2 加入
        "dest_realpath": "/home/www/upload/a.jpg"  # v1.2 加入
    }
    type   = rename,
    params = {
        "source": "/var/www/html/uploads/hello.txt",
        "dest":   "/var/www/html/uploads/hello.php"
    }
    type   = command,
    params = {
        "stack":   [
            "java.lang.ProcessBuilder.start",
            "sun.reflect.NativeMethodAccessorImpl.invoke0",
            "sun.reflect.NativeMethodAccessorImpl.invoke",
            "sun.reflect.DelegatingMethodAccessorImpl.invoke",
            ...
        ]
        "command": "/bin/sh -c 'whoami; ls; '"
    }
    type   = xxe
    params = {
    	"entity": "file:///etc/passwd"
    }
    type   = ognl
    params = {
    	"expression": "_memberAccess" //ognl表达式
    }
    type   = deserialization
    params = {
    	"clazz": "InvokerTransformer" //被反序列化对象的类型
    }
    type   = ssrf
    params = {
        "url":      "http://0x7f.0x0.0x0.0x1:8080/v1/api/get",  // http 请求的 url
        "hostname": "0x7f.0x0.0x0.0x1"                          // http 请求的 hostname
        "ip":       ["1.1.1.1", "2.2.2.2"]                      // 无法解析则为空;目前只解析 IPv4 地址
        "port":     "8080",                                     // 未提供端口为空。对于http模式是80,https默认是443的情况,如果没指定也是空
        "function": "commons_http_client"
    }
    type   = ssrfRedirect
    params = {
        "url":       "http://0x7f.0x0.0x0.0x1:8080/v1/api/get",  // 原始请求的 URL
        "hostname":  "0x7f.0x0.0x0.0x1"                          // 原始请求的域名
        "ip":        ["1.1.1.1", "2.2.2.2"]                      // 原始请求目标 IP
        "port":      "8080",                                     // 原始请求的端口,未提供端口为空。对于http模式是80,https默认是443的情况,如果没指定也是空
    
        "url2":      "http://127.0.0.1:8080/v1/api/get",         // 重定向后的 URL
        "hostname2": "0x7f.0x0.0x0.0x1"                          // 重定向后的域名
        "ip2":       ["1.1.1.1", "2.2.2.2"]                      // 重定向后目标 IP
        "port2":     "8080",                                     // 重定向后的端口,说明同上
        "function":  "commons_http_client"
    }
    type   = eval
    params = {
        "function": "eval",
        "code":  "gzuncompress(base64_decode(...));"
        "stack": [
            ...
        ]
    }
    type   = loadlibrary
    params = {
        "function": "System.load",
        "path":     "\\8.8.8.8\test.dll",
        "realpath": "xxxx"
    }
    type   = response
    params = {
        "content_type": "text/html",
        "content":      "<h1>xxxx</h1>"
    }

    管理后台

    hashtag
    业务模型

    云控后台为了将 RASP Agent 分组,引入 APP 的概念,每个 APP 代表一个业务线,每个 APP 有独立的 Secret 用于提供认证,每个 APP 可以管理多个 RASP Agent 的配置和插件。

    hashtag
    技术架构

    目前,Agent 管理后台采用的是 Go 语言编写,数据库采用的是 MongoDB + Elasticsearch,通讯采用 HTTP/HTTPS + JSON 定时通讯的方式。 整体的架构图如下所示:

    如上图所示:

    1. 虚线下方为安装了 RASP 的服务器,上方为云控后台,云控后台分为 Agent Server 和 Panel Server,Agent Server 负责和 RASP Agent 通信,Panel Server 负责用户与前端的交互。Agent Server 可以部署多个实例,Panel Server只可以部署一个。

    2. Secrete 认证:RaspAgent和云控后台之间的认证方式采用 appID + secrete私钥 的形式进行认证。

    Java 版本

    hashtag
    获取源码

    你可以使用 git 命令,也可以直接在 Githubarrow-up-right 下载 ZIP 包

    hashtag
    准备环境

    为了保证最大兼容性,我们建议使用 JDK 6 进行编译

    为编译所依赖的JNI模块,需要安装 c++ 编译器和 cmake 生成器

    以 CentOS 为例,使用如下命令,安装 g++ 5.3.1

    安装完成后,执行如下命令进入编译环境

    安装高版本 cmake

    hashtag
    编译 openrasp-v8 基础库

    以 64位 Linux 系统为例,在OpenRASP仓库根目录执行以下命令

    更多平台的编译细节请参考

    • https://github.com/baidu-security/openrasp-v8/blob/master/.travis.yml

    • https://github.com/baidu-security/openrasp-v8/tree/master/.travis

    hashtag
    开始编译

    1. 方案1 - 使用 IDEA Intellij 进行操作

      导入 maven 工程,目录选 agent/java,正常编译即可

    2. 方案2 - 使用 mvn 命令编译

      进入命令行,

    hashtag
    常见问题

    hashtag
    1. maven 超时

    如果总是出现超时错误,你可以考虑使用阿里云的镜像。

    [ERROR] Plugin org.apache.maven.plugins:maven-resources-plugin:3.0.2 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.apache.maven.plugins:maven-resources-plugin:jar:3.0.2: Could not transfer artifact org.apache.maven.plugins:maven-resources-plugin:pom:3.0.2 from/to central (https://repo.maven.apache.org/maven2): Connect to repo.maven.apache.org:443 [repo.maven.apache.org/151.101.196.215] failed: Operation timed out (Connection timed out) -> [Help 1]

    修改方法是编辑 ~/.m2/settings.xml,并填写如下内容

    hashtag
    2. git-commit-id-plugin 错误

    如果你使用 JDK 1.6 编译,可能会遇到如下错误:

    [ERROR] Plugin pl.project13.maven:git-commit-id-plugin:2.1.5 or one of its dependencies could not be resolved: Failed to read artifact descriptor for pl.project13.maven:git-commit-id-plugin:jar:2.1.5: Could not transfer artifact pl.project13.maven:git-commit-id-plugin:pom:2.1.5 from/to central (https://repo.maven.apache.org/maven2): Received fatal alert: protocol_version -> [Help 1]

    这是一个 https 证书错误,解决方法是替换 maven 仓库地址为 http 版本。可以考虑修改 ~/.m2/settings.xml,并添加如下内容

    hashtag
    3. 缺少 Premain-Class 属性

    如果你使用IDE编译,最终可能出现这样的错误:

    Failed to find Premain-Class manifest attribute in D:\apache-tomcat-7.0.82\rasp\rasp.jar

    这是因为IDE没有修改 META-INF 下面的文件。我们建议你使用 maven 编译,或者直接导入 maven 工程

    git clone https://github.com/baidu/openrasp.git
  • 主机注册:在启动阶段,若 RASP Agent 开启远程管理,每隔 5 分钟尝试向 Agent Server 注册一次,直到成功,注册信息将会存入 MongoDB,用于前端展示。

  • 定时心跳:每隔 3 分钟 RASP Agent与云端通信一次,心跳时间可配置。发送心跳时,同时提交本地配置的版本号。若有更新版本的配置或者插件,云端会通过心跳返回新的配置和插件。

  • 报警日志上传:图中绿色箭头为报警日志的上传流向,Agent Server 采集日志有两种可选模式,第一种模式直接将 RASP Agent 上传的日志存入 ES,这种方式在日志量较大的情况下会有日志丢失的情况,第二种是将日志写入文件,然后由 logstash 采集并传入 ES,这种方式较为复杂,但日志不易丢失,不同语言的 RASP 内部日志上传方式如下:

    • PHP 版本每隔 10s 检查是否有新的日志。若上传成功,会记录文件读取偏移量,并将状态文件落地。

    • Java 版本使用 Log4j 内置的缓冲区,默认大小是 128 条。若未发送的日志量超过缓冲区大小,最早的日志会被抛弃。

  • 插件与配置升级:用户通过 Panel Server 下发配置和插件到 MongoDB,然后由 RASP Agent 通过与 Agent Server 心跳取走新的配置和插件。

  • ref: rasp-cloud image

    最终生成的 JAR 包在 boot/target 和 engine/target 目录下,aka: $openrasp_path/agent/java/boot/target/rasp.jar和$openrasp_path/agent/java/engine/target/rasp.jar

  • 方案3 - 使用 build-java.sh 生成安装包

    如果你使用 Linux 进行编译,可以执行源代码目录下面的 build-java.sh 进行编译和打包操作。这个脚本会在源代码根目录,生成 rasp-java.tar.gz 和 rasp-java.zip 两个文件

  • Java SE Development Kit 6u45arrow-up-right
    apache-maven 3.2.3arrow-up-right
    yum install -y centos-release-scl
    yum install -y devtoolset-4-gcc-c++
    scl enable devtoolset-4 bash
    # 下载并解压到 /tmp,避免与已有 cmake 冲突
    curl -L  https://github.com/Kitware/CMake/releases/download/v3.15.3/cmake-3.15.3-Linux-x86_64.tar.gz | tar zx -C /tmp
    
    # 增加临时 PATH
    export PATH=/tmp/cmake-3.15.3-Linux-x86_64/bin:$PATH
    # 更新 git submodule
    git submodule update --init
    
    # 编译 openrasp-v8
    mkdir -p openrasp-v8/build64 && cd openrasp-v8/build64
    cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_LANGUAGES=java ..
    make
    
    # 复制动态链接库到 resources 目录
    mkdir -p ../java/src/main/resources/natives/linux_64 && cp java/libopenrasp_v8_java.so $_
    
    # 编译 v8-1.0-SNAPSHOT.jar,安装 v8-1.0-SNAPSHOT.jar 到 maven 本地仓库
    cd ../java
    mvn install
    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                       http://maven.apache.org/xsd/settings-1.0.0.xsd">
    <localRepository/>
    <interactiveMode/>
    <usePluginRegistry/>
    <offline/>
    <pluginGroups/>
    <servers/>
    <mirrors>
     <mirror>
      <id>aliyunmaven</id>
      <mirrorOf>central</mirrorOf>
      <name>阿里云公共仓库</name>
      <url>https://maven.aliyun.com/repository/central</url>
     </mirror>
     <mirror>
       <id>repo1</id>
       <mirrorOf>central</mirrorOf>
       <name>central repo</name>
       <url>http://repo1.maven.org/maven2/</url>
     </mirror>
     <mirror>
      <id>aliyunmaven</id>
      <mirrorOf>apache snapshots</mirrorOf>
      <name>阿里云阿帕奇仓库</name>
      <url>https://maven.aliyun.com/repository/apache-snapshots</url>
     </mirror>
    </mirrors>
    <proxies/>
    <activeProfiles/>
    <profiles>
     <profile>
         <repositories>
            <repository>
                 <id>aliyunmaven</id>
                 <name>aliyunmaven</name>
                 <url>https://maven.aliyun.com/repository/public</url>
                 <layout>default</layout>
                 <releases>
                         <enabled>true</enabled>
                 </releases>
                 <snapshots>
                         <enabled>true</enabled>
                 </snapshots>
             </repository>
             <repository>
                 <id>MavenCentral</id>
                 <url>http://repo1.maven.org/maven2/</url>
             </repository>
             <repository>
                 <id>aliyunmavenApache</id>
                 <url>https://maven.aliyun.com/repository/apache-snapshots</url>
             </repository>
         </repositories>
      </profile>
    </profiles>
    </settings>
    <?xml version="1.0"?>
    <settings>
      <mirrors>
        <mirror>
          <id>central-no-ssl</id>
          <name>Central without ssl</name>
          <url>http://repo.maven.apache.org/maven2</url>
          <mirrorOf>central</mirrorOf>
        </mirror>
      </mirrors>
    </settings>
    cd <openrasp_path>/agent/java
    mvn versions:use-latest-releases -Dincludes=com.baidu.openrasp:sqlparser
    mvn clean package

    简介

    OpenRASP 抛弃了传统防火墙依赖请求特征检测攻击的模式,创造性的使用RASP技术(应用运行时自我保护),直接注入到被保护应用的服务中提供函数级别的实时防护,可以在不更新策略以及不升级被保护应用代码的情况下检测/防护未知漏洞,尤其适合大量使用开源组件的互联网应用以及使用第三方集成商开发的金融类应用。

    另外,OpenRASP 提供的IAST解决方案,相比于与传统的DAST方案有着革命性提升。漏洞检测无需动态爬虫或者旁路代理,扫描更全面;结合应用探针准确的识别漏洞类型,通过针对性扫描大幅度提升检测效率;商业版新增的动态污点追踪能力,还可以在不扫描的情况下,预判接口是否存在漏洞。

    OpenRASP 是经过开源社区大规模验证过的产品,目前客户数量已经过百,QQ群人数超过1800人。如果你在使用过程中遇到任何问题,请加入我们的技术讨论QQ群arrow-up-right,联系我们处理。

    hashtag
    常用链接

    安装部署

    检测能力

    安装管理后台

    hashtag
    快速开始

    在开始之前,请先根据 里的说明,下载 rasp-cloud.tar.gz,并解压缩到本地。

    hashtag

    快速接入arrow-up-right
    性能测试arrow-up-right
    检测能力,覆盖场景,以及零规则算法介绍arrow-up-right
    CVE 漏洞覆盖列表arrow-up-right
    安装数据库

    目前,我们使用了 ElasticSearcharrow-up-right 和 MongoDBarrow-up-right 两种数据库。前者用来存储报警和统计信息,后者用来存储应用、账号密码等信息。

    目前我们对数据库的要求是,

    • MongoDB 版本大于等于 3.6

    • ElasticSearch 版本大于等于 5.6,小于 7.0 (ES 7.X 变化较大,暂无计划支持)

    具体如何安装数据库,这里不在赘述。

    hashtag
    启动管理后台

    首先,编辑 conf/app.conf 文件,修正 ElasticSearch 和 MongoDB 两个服务器的地址。如果这两个数据库都安装在了本机,且使用默认端口,请跳过此步骤:

    关于 MongoDB 认证配置,可参考 mongoDB Linux 认证配置、重置密码、远程登录配置详解arrow-up-right 文章操作;如果 MongoDB 有主从,只需要填写主地址。

    然后,在终端里执行如下命令,启动后台服务器:

    最后,在浏览器里打开 http://your-ip:8086,登录管理后台。其中用户名固定为 openrasp,初始密码为 admin@123。如果不能访问,请检查防火墙设置,或者检查 logs/api/agent-cloud.log 下面的错误信息。

    登录成功后,请根据 管理后台 - 添加主机arrow-up-right 文档,了解如何添加第一台主机。

    hashtag
    高级配置

    hashtag
    后台负载均衡

    在实际场景中,我们需要部署多个服务器,才能处理来自数十万主机的连接。因此,我们将管理后台拆分为 Agent 接口服务器 (AgentServer) 和 前端服务器 (PanelServer)。前者用于跟agent通信,比如心跳、日志上传,可以部署多个;后者用于展示数据、定时报警、修改配置,用户可访问这个后台来查看报警。后者用于发送报警邮件,部署多个会有重复报警的问题,所以目前只能部署一个。

    在百度,我们会启动一个前端服务器,

    然后在不同的机房,分别启动一个 agent 服务器(使用同一份 conf/app.conf 配置文件即可)

    服务器部署完成后,请根据 管理后台 - 设置后台信息arrow-up-right 文档,将所有的Agent服务器填入。之后就可以在 添加主机 界面上,生成自动安装命令了。

    容量说明: 目前,在2核4GB的主机上,按照3分钟一个心跳计算,大概单台机器可容纳 1000个 客户端。

    hashtag
    ElasticSearch 负载均衡

    在使用ES集群时,EsAddr 填写一个服务器的地址即可。我们自动会调用 /_nodes/ 接口获取全部服务器信息并轮询,以避免单点问题。

    hashtag
    配置项详细说明

    以下配置均为在 conf/app.conf 中配置

    Beego 相关

    常用 beego 配置项如下,更多设置请参考 beego官网arrow-up-right 文档,

    参数
    说明
    默认值

    appname

    应用名称

    无

    httpaddr

    http 监听IP

    0.0.0.0

    httpport

    http 监听端口

    8086

    runmode

    运行模式,dev 为开发模式,prod 为线上模式

    prod

    OpenRASP 相关

    OpenRASP 可用配置项目如下,

    参数
    说明
    默认值

    EsAddr

    Elasticsearch 服务器地址,多个地址用逗号隔开

    http://127.0.0.1:9200

    EsUser

    Elasticsearch 用户名 (X-Pack)

    空

    EsPwd

    Elasticsearch 密码 (X-Pack)

    空

    EsTTL

    Elasticsearch 数据过期时间,单位/天

    365

    开启 HTTPS

    在 conf/app.conf 中加入以下配置即可,修改后重启后台生效:

    hashtag
    后台运维

    hashtag
    升级后台

    请登录到每一台部署了 rasp-cloud 的主机,并按照如下步骤进行升级:

    如果是 v1.3.0 之前的后台

    1. 备份原来的配置文件,conf/app.conf

    2. 下载新的安装包,解压缩到相同目录

    3. 检查是否需要更新配置文件

    4. 执行命令 ps aux | grep rasp-cloud 找到后台进程 PID

    5. 对上述进程发出 HUP 信号,e.g kill -HUP $PID

    6. 检查后台是否可以正常访问

    如果是 v1.3.0 甚至更高版本的后台

    1. 备份原来的配置文件,conf/app.conf

    2. 下载新的安装包,解压缩到相同目录

    3. 检查是否需要更新配置文件

    4. 执行 /path/to/rasp-cloud -s restart

    5. 检查后台是否可以正常访问

    hashtag
    找回密码

    请登录到后台所在的主机,执行如下命令,根据提示重置密码。目前密码强度要求是 8-50 位,必须包含数字和字母。

    hashtag
    检查后台状态

    请登录到后台所在的主机,执行如下命令即可:

    hashtag
    查看后台版本

    请登录到后台所在的主机,执行如下命令即可:

    hashtag
    定期备份

    在百度,我们以小时级别对 MongoDB 和 ElasticSearch 数据库进行备份。其中,MongoDB 需要备份 openrasp 数据库,可以使用 mongodump + mongorestore 实现;ElasticSearch 需要备份如下索引,可以用 snapshot 方式备份:

    当然,如果公司有DBA团队,可以考虑托管给他们。

    hashtag
    其他说明

    hashtag
    Logstash 配置

    当 AlarmLogMode 设置为 file 时,可使用 Logstash 采集文件日志。Logstash 样例配置如下,使用前请先修正日志路径

    hashtag
    FAQ

    hashtag
    1. 常见启动失败原因

    日志会打印到 logs/api/agent-cloud.log 里。如果启动时没有增加 -d 参数,我们将同时在前台打印错误消息,e.g

    目前定义的错误如下,

    错误码 | 说明 :---- | :--- | :--- 30001 | 日志初始化失败,如文件权限问题 30002 | MongoDB 初始化失败,如 MongoDB 地址无法连接、MongoDB 认证失败等等 30003 | ES 初始化失败,如 ES 地址无法连接 30004 | 配置错误 ,如未配置 Domain 30005 | 启动模式错误,启动使用了 agent, panel 之外的,不支持模式 30006 | 管理员密码初始化失败 30007 | geoip 初始化失败,如 geoip 数据库文件权限问题 30008 | 后台管理员用户名密码重置失败 30009 | 创建默认 app 失败 30010 | -d 参数启动后台失败

    具体错误信息请查看 nohup 控制台输出

    hashtag
    2. 管理后台打开后空白、按钮点不动等问题

    我们目前只兼容 Google Chrome 浏览器。如果页面出现任何问题,请按下 F12 调出开发工具,并检查控制台是否有错误输出。如下图中的红色字样:

    console

    如果发现这种问题,请加入QQ群联系我们处理。

    hashtag
    3. ElasticSearch "Result window is too large" 错误

    如果你搜索的时间范围太大,ES 可能会爆出如下错误:

    Result window is too large, from + size must be less than or equal to: [10000] but was [281280]. See the scroll api for a more efficient way to request large data sets. This limit can be set by changing the [index.max_result_window] index level setting.

    这是因为你搜索的时间范围很大,导致ES需要对大量的数据进行排序。解决方法是打开 config/elasticsearch.yml,修改或者增加 index.max_result_window 配置,将它调整为一个较大的值。当然,修改这个值会消耗更多的内存。

    hashtag
    4. 我的主机名显示为 "im-not-resolvable"

    在 Java 版本里,我们使用了 InetAddress 来获取主机名称,如果这个主机名在 /etc/hosts 下面没有对应的记录,Java 将抛出 Unknown host 异常。在这种情况下,我们会将主机名设置为 im-not-resolvable,并让程序继续运行。

    解决方法是,在 /etc/hosts 下面为你的主机名添加一条记录:

    添加后,重启 Java 服务器生效。再次启动时,我们会注册一个新的agent到后台。

    hashtag
    5. 管理后台打不开,Chrome 浏览器提示 ERR_CONNECTION_REFUSED

    默认情况下,后台监听地址为 0.0.0.0:8086。如果你无法访问服务器,请检查防火墙是否开启对应端口。对于基于 netfilter 的防火墙,你可以执行如下命令开放 8086 端口:

    hashtag
    6. 无法发送邮件报警,提示 5XX 错误

    大部分国内邮箱都不支持密码登录,需要申请授权码进行登录。如果你在使用下列邮箱,请参考他们的 FAQ 文档进行配置:

    • 网易邮箱: 126/163/yeah.netarrow-up-right

    • QQ 邮箱: qq.com/vip.qq.comarrow-up-right

    • Coremail - 请联系销售

    hashtag
    7. ElasticSearch X-Pack 使用说明

    目前,后台使用的索引名称前缀为:

    • real-openrasp-X (alias)

    • openrasp-X

    如果你在使用 X-Pack,且需要按照索引名称前缀进行授权,可以根据上述规则添加认证。若要查看当前 ES 的索引和别名列表,可访问如下URL:

    hashtag
    8. 自己编译的后台,访问前端服务器 8086 端口提示 404 错误

    前端文件在 dist 目录下,如果前端服务器返回 404 则说明这个目录不存在,或者 dist/index.html 不存在。

    hashtag
    9. 误删ES索引,如何处理?{#es-index-reset}

    ES索引里只保存报警信息,误删索引不会导致agent信息丢失。若要完全重置ES,请先删除所有以 real-openrasp-、openrasp- 开头的索引,并重新启动 rasp-cloud 即可。rasp-cloud 会在启动时检查并重新创建索引。

    hashtag
    10. 报警上传成功,后台看不到报警而且 ES 健康状态为 yello

    为了避免阻塞,管理后台是异步将报警日志写入 ElasticSearch,因此 API 接口成功不代表报警保存成功。当 ES 服务器磁盘空间占用超过 95%,ES 会拒绝接受日志并抛出 cluster_block_exception 异常:

    修复方式请参考 Elasticsearch磁盘占用大于95%时将所有索引置为只读arrow-up-right 文章解决。

    hashtag
    11. 我使用 nginx 作为管理后台的反向代理,iast 扫描器无法连接,总是提示400错误

    iast 扫描器使用 websocket upgrade 协议连接管理后台,nginx 需要同时传递 Upgrade 头才能工作:

    否则会在管理后台 api/agent-cloud.log 看到如下错误

    hashtag
    12. 管理后台假死,日志里出现大量 too many open files

    参考 linux 打开文件数 too many open files 解决方法arrow-up-right 修正 limits.conf 里的配置即可,修正后需要重新登录生效。

    最后通过 ulimits -n 命令确认即可。

    hashtag
    13. 离线主机排查

    如果后台出现离线主机,请按照如下步骤排查:

    1. 检查客户端与后台是否连通。使用 curl 命令访问管理后台,检查是否能访问。

    2. 重启 Tomcat/PHP 服务器,检查主机是否上线。

    3. 检查客户端主机名、网卡信息是否有变化。如果有,后台信息会跟着变更,并产生一台新的主机。这个问题会在后续版本修正,即固定 rasp_id 到配置目录。

    4. 检查管理后台系统时间是否正确。

    hashtag
    14. rasp-cloud 启动卡住

    目前已知的情况有

    1. beego自身存在BUG,如果日志目录被链接到 /dev/null,将会卡住。e.g log/access 目录

    软件下载arrow-up-right

    兼容性说明

    hashtag
    Java Agent

    操作系统

    • MacOS 10.10+

    Tomcat 服务器

    hashtag
    自动化安装

    下载 rasp-java.tar.gz 或者 rasp-java.zip 并解压缩。之后进入到解压后的目录中,e.g rasp-20181221

    如果你要开启远程管理,请先参考 文档,找到 app_id/app_secret/backend_url 三个关键参数,然后执行如下命令,

    [prod]
    EsAddr = http://127.0.0.1:9200
    EsUser =
    EsPwd =
    MongoDBAddr = 127.0.0.1:27017
    MongoDBUser =
    MongoDBPwd =
    ./rasp-cloud -d
    ./rasp-cloud -type=panel -d
    ./rasp-cloud -type=agent -d
    EnableHTTPS = true
    EnableHttpTLS = true
    HttpsPort = 443
    HTTPSCertFile = "cert.pem"
    HTTPSKeyFile  = "cert.key"
    ./rasp-cloud -type=reset
    %> ./rasp-cloud -s status
    /rasp-cloud/
    2020/02/11 18:13:39 The rasp-cloud is running!
    %> ./rasp-cloud -version
    /rasp-cloud/
    Version:       1.3
    Build Time:    2020-02-11 17:56:52
    Git Commit ID: d6902d60f8874e7255562544041edbd340e6b676
    real-openrasp-report-data-{appid}
    real-openrasp-attack-alarm-{appid}
    real-openrasp-policy-alarm-{appid}
    real-openrasp-error-alarm-{appid}
    real-openrasp-dependency-data-{appid}
    input{
        file{
            path=>[
                ## 1. 修改该处,将 $cloud-agent-home 替换为部署的 agent 模式后台的根目录
                "$cloud-agent-home/openrasp-logs/attack-alarm/attack.log"
            ]
            start_position => "beginning"
            type => "attack-alarm"
            codec => "json"
        }
      
        file{
            path=>[
                ## 2. 修改该处,将 $cloud-agent-home 替换为部署的 agent 模式后台的根目录
                "$cloud-agent-home/openrasp-logs/policy-alarm/policy.log"
            ]
            start_position => "beginning"
            type => "policy-alarm"
            codec => "json"
       }
    }
    
    output {
    
        if [type] == "attack-alarm" {
            elasticsearch {
                ## 3. 修改 ES 地址
                hosts  => "0.0.0.0:9200"
                index =>  'real-openrasp-%{type}-%{[app_id]}'
                timeout => 30
                document_type => '%{type}'
            }
        }
    
        if [type] == "policy-alarm"{
            elasticsearch {
                ## 4. 修改 ES 地址
                hosts  => "0.0.0.0:8200"
                index =>  'real-openrasp-%{type}-%{[app_id]}'
                timeout => 30
                document_type => '%{type}'
                action => 'update'
                document_id => '%{[upsert_id]}'
                doc_as_upsert => true
            }
        }
    
    }
    2018/12/14 09:55:11.393 [I] [environment.go:62]  ===== start type: default =====
    2018/12/14 09:55:11.408 [E] [mongo.go:54]  [30002] init mongodb failed: no reachable servers
    127.0.0.1 myhostname
    iptables -I INPUT -p tcp --dport 8086 -j ACCEPT
    http://elasticsearch_hostname:port/_cat/indices?v
    http://elasticsearch_hostname:port/_cat/alias?v
    blocked by: [FORBIDDEN/12/index read-only / allow delete (api)]
    server {
        listen 84;
        location / {
            proxy_set_header Host $http_host;
            proxy_pass http://172.17.0.4;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }
    }
    2020/02/07 11:37:47.784 [E] [iast.go:147]  upgrade err: websocket: the client is not using the websocket protocol: 'upgrade' token not found in 'Connection' header
    Windows x64
  • Linux

    • RHEL/CentOS 6 以及更高版本

    • Ubuntu 14 以及更高版本

    • Debian 6 以及更高版本

    • 其他 glibc >= 2.12 的发行版

  • Web 服务器 - 支持 docker 部署

    • Tomcat 5 ~ 10

    • Jetty 7 ~ 9

    • JBoss 4 ~ 8

    • Wildfly 8 ~ 16

    • Resin 3 ~ 4

    • SpringBoot 1 ~ 2 (内置 tomcat/jetty/undertow)

    • WebSphere 7.X 及以上版本

      • 部分版本由于 IBM JDK 自身限制,无法启用文件读写删改相关检测(可自行更换 Oracle JDK)

      • 商业版不受影响,可正常检测漏洞

    • WebLogic 10.3.6 / 12.2

    • 宝兰德BES 9.5.X

    • 中创InforSuiteAS 10.0.X

    JDK 版本

    • Oracle JDK 6~15

    • OpenJDK 6~11

    数据库

    • MySQL

    • SQLServer

    • SQLite3

    • Oracle

    • PostgreSQL

    • DB2

    • HSQLDB (WebGoat 使用的嵌入数据库)

    hashtag
    PHP Agent

    SAPI 支持范围(同时支持TS/非TS版本)

    • PHP-FPM

    • Apache PHP 模块

    操作系统

    Linux

    • PHP 5.3 ~ 5.6,7.0 ~ 7.3

      • Ubuntu 14.04 以及更高版本

      • RHELL/CentOS 6 以及更高版本

      • 其他 glibc >= 2.12 的发行版

    Mac OS

    • Homebrew PHP 5.6,7.0 ~ 7.3 (没有深入测试)

    数据库

    • MySQL (mysql/mysqli/PDO 等连接方式)

    • PostgreSQL

    • SQLite3

    hashtag
    管理后台

    操作系统

    • Linux

      • CentOS 6 以及更高版本

      • Ubuntu 14.04 以及更高版本

      • 后台基于Golang开发,只要不是太老的系统一般都支持

    • Mac OS X

    MongoDBAddr

    MongoDB 连接地址,多个地址用逗号隔开

    127.0.0.1:27017

    MongoDBName

    使用的 MongoDB 的数据库名称

    openrasp

    MongoPoolLimit

    MongoDB 连接池最大限制

    2048

    MongoDBUser

    MongoDB 认证用户名,该用户需要有操作 openrasp 数据库的权限,有认证才需要配置

    空

    MongoDBPwd

    MongoDB 认证密码

    空

    LogMaxSize

    单个日志文件最大大小,超过就rotate当天日志

    104857600

    LogMaxDays

    最多保留多少天的日志

    7

    MaxPlugins

    每个App最多保留多少插件,超过删除最老的

    30

    CookieLifeTime

    登录 cookie 有效期,单位/小时

    168

    AlarmLogMode

    报警日志采集模式,file 模式将日志落地到文件,可配合 logstash 上传到 es;es 模式将日志直接写入到 ES

    es

    AlarmBufferSize

    es 模式下日志缓冲区大小,当日志量过大,缓冲区满的情况下,将会出现日志丢失

    300

    AlarmCheckInterval

    报警检查间隔时间,单位秒 v1.3 开始改为前端配置

    120

    RequestBodyEnable

    access.log中是否包含请求体信息

    false

    DebugModeEnable

    是否开启Debug开关,打印调试信息

    false

    ErrorLogEnable

    是否将错误日志记录到es

    false

    LogMaxSize

    rasp每个日志文件大小(单位:字节)

    104857600

    LogMaxDays

    rasp日志最长保留天数

    10

    LogPath

    rasp日志文件根路径

    /home/openrasp/logs

    OfflineInterval

    rasp主机离线时间判定超时阈值,允许范围为30~31622400(单位:秒)

    180

    RegisterCallbackUrl

    rasp主机注册回调地址,如果失败将不会注册

    空

    安装部署

    目前,OpenRASP 支持 Java 和 PHP 两种开发语言。更多语言支持计划,请查看 baidu/openrasp - 里程碑arrow-up-right。具体开发排期和版本内容,请关注我们置顶的 baidu/openrasp - ISSUEarrow-up-right 页面。

    如果你只是运行单机版,只需要指定 -install 参数,

    这里的 <tomcat_root> 不是 webapps 目录,而是 tomcat 的根目录。没有错误表示安装成功,其他配置请参考 其他配置 文档。安装后,需要重启 Tomcat 服务器生效。

    不重启安装(仅支持 JDK 6-8)

    以上方式安装成功之后需要重启服务器,如果在服务器启动的情况下,不重启安装 OpenRASP,需要在以上命令后面增加 -pid 参数指定运行的服务器进程ID:

    在 Windows 下面请替换 $JAVA_HOME 为 %JAVA_HOME%

    hashtag
    RASP 升级方法

    在 Linux 下面,可以使用 bin/catalina.sh stop 来执行 graceful stop

    你会在日志里看到类似下面的输出,这表明 Tomcat 将在处理完当前的HTTP后退出

    之后参考我们的自动或者手动安装文档,重新安装即可

    hashtag
    手动安装 - Linux

    1. 安装软件

    进入到 tomcat 安装目录(绝对路径包含空格将导致启动失败),e.g /opt/apache-tomcat-8.5.6,将 rasp 目录复制过来

    OpenRASP 需要在 rasp 目录下释放一些动态链接库,所以还需要修改 rasp 目录的权限,e.g

    否则你可能在 catalina.out 里看到类似这样的错误,

    2. 修改 Tomcat 启动脚本

    打开 bin/catalina.sh, 找到如下内容:

    修改为如下(增加 -javaagent 项)

    对于使用 yum 安装的 tomcat,你需要创建 /etc/tomcat/conf.d/rasp.conf,并写入以下内容

    对于JDK9以上版本,还需要增加额外的JDK启动参数,e.g

    3. 开启远程管理

    如果你不需要远程管理功能,请跳过这个步骤。

    首先,请先参考 管理后台 - 添加主机arrow-up-right 文档,找到 openrasp.yml 配置文件内容。然后打开 <tomcat_home>/rasp/conf/openrasp.yml,添加或者修改如下内容:

    4. 验证安装是否成功

    首先重启tomcat服务器。如果安装了管理后台,在管理后台检查主机是否上线即可;如果是单机版,可以按照如下流程检查:

    检查响应的请求头是否包含 X-Protected-By 字样,出现则表示安装成功:

    如果使用了反向代理,可能不会看到上面的请求头。此时可以检查 rasp/logs/rasp/rasp.log 中是否出现 OpenRASP Engine Initialized 字样,出现也表示安装成功:

    如果服务器无法启动,请检查 tomcat 启动日志,看Java是否抛出异常,e.g catalina.out。如果你无法解决问题,请请联系我们arrow-up-right。

    hashtag
    手动安装 - Windows

    1. 安装软件

    进入到 tomcat 安装目录,e.g D:\apache-tomcat-8.5.6,将 rasp 目录复制过来

    2. 修改 tomcat 配置

    2.1 如果是下载的 "32-bit/64-bit Windows Service Installer" 安装包,

    请参考这篇文章arrow-up-right,打开 bin/tomcatXw.exe

    切换到 Java 标签页,

    tomcatw

    在 Java Options 下面增加启动参数,注意替换下绝对路径,e.g

    对于JDK9以上版本,还需要额外增加如下内容

    2.2 如果是下载的 "Windows zip" 安装包

    打开 bin\catalina.bat, 找到 :setArgs 处:

    在 :setArgs 下增加新的 JAVA_OPTS,e.g

    对于JDK9以上版本,还需要额外增加两个JDK启动参数,e.g

    3. 开启远程管理

    方法同 Linux 版本,在 openrasp.yml 里增加相关配置即可。

    4. 验证安装是否成功

    重启 tomcat 服务器,然后检查日志文件,一般是 rasp/logs/rasp/rasp.log,如果出现 OpenRASP Engine Initialized 字样,出现则说明安装成功;或者访问一下服务器,检查是否存在 X-Protected-By: OpenRASP 响应头,存在即表示安装成功。

    安装中出现任何问题,请联系我们arrow-up-right

    hashtag
    常见问题

    1. Tomcat Windows Service Installer 版本,无法自动安装

    服务版本的安装包,没有提供 catalina.sh,只提供了 tomcatX.exe 作为启动工具

    请参考Windows 手动安装文档,打开 bin/tomcatXw.exe 进行配置

    管理后台 - 添加主机arrow-up-right

    快速接入

    hashtag
    快速接入

    OpenRASP 支持私有化部署,包含客户端与服务端两个组件。在接入之前,请先阅读 兼容性说明arrow-up-right 文档,检查客户端是否支持你的应用服务。

    第一步: 下载最新版本的安装包

    常用镜像

    文件说明

    文件名
    说明

    第二步: 安装管理后台 (可选)

    OpenRASP 支持单机防护,也支持远程管理。若要开启远程管理,请先参考 安装管理后台。

    第三步: 安装客户端

    取决于你的服务器类型,请参考不同的子章节进行安装。比如 Tomcat 可以查看 进行操作。

    第四步: 安装测试用例(可选){#step4}

    如果你需要测试漏洞检测效果,请参考 安装漏洞环境。

    第五步: 安装IAST扫描工具(可选){#step5}

    如果你需要安装扫描工具,请参考 页面进行安装和配置。

    hashtag
    其他常用链接

    开发相关

    常见问题

    hashtag
    常见问题

    1. 常见自动安装失败原因

    Java 版本

    错误码
    说明

    关于 java 不重启安装,卸载:由于不支持不重启升级,所以在不重启安装然后不重启卸载之后,想要再次安装需要重启服务器安装。

    PHP 版本

    错误码
    分类说明

    2. OpenRASP 无法拦截攻击

    Java 服务器

    1. 首先,使用浏览器访问网站,检查服务器是否启动成功

      • 若服务器没有启动,可检查启动日志,寻找堆栈信息。对于 tomcat 通常是 catalina.out

    2. 根据子章节的文档,检查 OpenRASP 是否安装成功

    PHP 服务器

    1. 首先,使用浏览器访问网站,检查服务器是否启动成功

      • 若服务器没有启动,可检查 PHP/Apache/Nginx 错误日志

    2. 根据子章节的文章,检查 OpenRASP 扩展是否安装成功

    3. jnotify 无法释放

    有的公司会定制应用启动脚本,比如 catalina.sh,当以root启动tomcat,他会自动切换到低权限用户,再继续启动

    通常,你会看到如下的堆栈错误

    这说明 OpenRASP 在释放 jnotify 动态链接库时出错(用来监控插件目录变更),错误原因是 Permission denied

    所以,你可能需要调整下RASP目录权限,e.g chmod 777 -R rasp,然后再次启动 tomcat

    4. Could not find or load main class com.baidu.rasp.App 错误

    QQ群用户反馈,执行 RaspInstall 时报错,

    经过排查,这是因为当前目录本身没有读取权限导致的,执行 chmod 777 $PWD 后解决。

    5. APM 兼容性说明

    如果你同时使用 OpenRASP 和 APM 产品,比如 ,那你需要增大 -XX:MaxPermSize 参数。否则运行一段时间后可能会出现 java.lang.OutOfMemoryError: PermGen space 错误,产生大量GC,最终导致服务器假死。

    如果原先没有配置过此参数,我们建议你设置为 1024m;如果配置过,我们建议在原先基础上增加至少 512m。

    另外,为了避免APM回滚钩子,请将我们的 -javaagent 参数放在前面。

    6. JDK9 以上安装问题

    由于JDK9以上版本的 Modularity System 属性,需要在手动安装后为服务器添加以下 Java 启动参数:

    7. 常见 v8 加载失败原因

    7.1 java.io.IOException: Permission denied 异常

    如果 /tmp 目录没有写权限,Java 会抛出 java.io.IOException: Permission denied 异常,e.g

    此时请检查 /tmp 是否有写权限,以及是否有安全防护软件对 /tmp 目录增加了写保护。

    7.2 libopenrasp_v8_java.so: failed to map segment from shared object: Permission denied

    对于以下两种场景,

    1. 机器开启了SELinux,不允许Tomcat加载不符合策略的动态链接库

    2. so释放目录没有执行权限,比如使用了 noexec 参数挂载

    Java可能会出现无法加载so的情况,并提示无法创建区段映射:

    解决方法是关闭SELinux(如果开启),并去掉释放目录的noexec挂载(如果有)。如果不是上述两种情况,请加入QQ群联系我们排查。

    7.3 java.io.IOException: Couldn't load library openrasp_v8_java

    如果你在不支持的系统架构上运行OpenRASP(比如aarch64),可能会看到 Couldn't find resource 错误:

    目前我们仅支持x64/x86_64两类架构,其他架构会逐步支持

    7.4 java.lang.UnsatisfiedLinkError 错误

    如果释放的 libopenrasp_v8_java.so 无法加载,Java 会抛出如下异常:

    目前已知的情况有:

    1. JDK是32位的,没有安装32位的glibc运行库。在CentOS系统下可以安装 glibc.i686 软件包。

    2. JDK是64位的,且在 docker alpine 环境里无法启动。这个因为你没有装 libcurl libstdc++ 两个软件包。

    如果是其他情况,请加入联系我们。

    8. libzip.so 崩溃问题

    Java 在运行时可能会产生这个错误:

    OpenRASP会定期读取jar包里的pom信息,获取应用所使用的类库和版本。这个是JDK自身的BUG,与OpenRASP无关。你可以通过如下几种方式解决问题:

    方案1: 升级JDK版本

    根据用户反馈,JDK 1.8 Update 261 没有这个问题。

    方案2: 关掉jar包的内存映射

    这可能因为Java在读取jar包时,对应的文件已经被修改,导致JVM崩溃,具体可以参考。

    通过增加如下JVM启动参数可以解决问题,但可能带来额外的性能损耗:

    方案3: 关闭依赖库采集功能

    参考 文档,将 dependency_check.enable 设置为 false 即可。 另外,也可以在执行RaspInstall安装的时候增加 -nodep 参数,程序会自动将 dependency_check.enable 改为 false。

    方案4: 避免多个Java进程使用相同的业务jar包

    有用户反馈,他们的业务存在多个容器共用jar的问题,将jar打包到容器内部就没有这个错误了。

    PHP 版本

    hashtag
    PHP 版本

    本文档仅适用于基于 glibc2.12 及以上 的 Linux 或 MacOS

    对于 Linux 系统,我们要求使用 g++ 5 或者更高版本进行编译。为了保证最大兼容性,我们建议你使用和生产环境相同的环境进行编译。

    下面,我们以 CentOS 6 为例,讲解如何编译 OpenRASP PHP 扩展。值得注意的是,CentOS 7 的安装方法、要执行的命令完全一样。

    hashtag
    准备环境

    使用如下命令,安装 g++ 5.3.1 以及 xxd 命令

    如果你使用的是发行版自带的 PHP 软件,你还需要安装对应的头文件

    安装完成后,执行如下命令进入编译环境

    安装高版本 cmake

    hashtag
    编译 openrasp-v8 基础库

    在OpenRASP仓库根目录执行以下命令

    hashtag
    编译 OpenRASP PHP 扩展

    进入源代码目录,执行下面的命令即可;如果你的 PHP 是自己编译的,请使用对应路径的 phpize 命令。

    如果 make 命令没有出错,可以继续执行 make install 安装。也可以将生成的扩展 modules/openrasp.so 复制到其它机器安装。对于扩展的具体安装方法,请参考

    WebLogic 服务器

    hashtag
    自动化安装

    解压缩后,进入到解压后的目录中(如rasp-20170721),在终端中执行以下命令,

    如果你要开启远程管理,请先参考 文档,找到 app_id/app_secret/backend_url 三个关键参数,然后执行如下命令,

    如果你只是运行单机版,只需要指定 -install 参数,

    java -jar RaspInstall.jar -install <tomcat_root> -backendurl http://XXX -appsecret XXX -appid XXX
    java -jar RaspInstall.jar -install <tomcat_root>
    # <server_pid> 为 tomcat 进程 id
    # $JAVA_HOME 为 jdk 根目录环境变量,如果未指定该环境变量,替换为 jdk 的完整根目录
    java -Xbootclasspath/a:$JAVA_HOME/lib/tools.jar -jar RaspInstall.jar -install <tomcat_root> -pid <server_pid>
    Jan 12, 2018 6:11:55 PM org.apache.catalina.core.StandardWrapper unload
    INFO: Waiting for 1 instance(s) to be deallocated for Servlet [jsp]
    Jan 12, 2018 6:11:56 PM org.apache.catalina.core.StandardWrapper unload
    INFO: Waiting for 1 instance(s) to be deallocated for Servlet [jsp]
    Jan 12, 2018 6:11:57 PM org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads
    cp -R ~/Downloads/rasp-20170721/rasp .
    chmod 777 -R rasp
    com.baidu.openrasp.exception.ConfigLoadException: Fail to extract rasp-log4j.xml, because of: /usr/share/tomcat8/rasp/conf/rasp-log4j.xml (Permission denied)
    	at com.baidu.openrasp.messaging.LogConfig.extractLogConfigFile(LogConfig.java:153)
    	at com.baidu.openrasp.messaging.LogConfig.completeLogConfig(LogConfig.java:72)
    	at com.baidu.openrasp.Agent.loadConfig(Agent.java:91)
    	at com.baidu.openrasp.Agent.premain(Agent.java:66)
    elif [ "$1" = "start" ] ; then
    	if [ ! -z "$CATALINA_PID" ]; then
    elif [ "$1" = "start" ]; then
    	JAVA_OPTS="-javaagent:${CATALINA_HOME}/rasp/rasp.jar ${JAVA_OPTS}"
    	if [ ! -z "$CATALINA_PID" ]; then
    JAVA_OPTS="-javaagent:${CATALINA_HOME}/rasp/rasp.jar ${JAVA_OPTS}"
    JAVA_OPTS="--add-opens=java.base/jdk.internal.loader=ALL-UNNAMED ${JAVA_OPTS}"
    JAVA_OPTS="--add-opens=java.base/java.net=ALL-UNNAMED ${JAVA_OPTS}"
    JAVA_OPTS="-javaagent:${CATALINA_HOME}/rasp/rasp.jar ${JAVA_OPTS}"
    # 云控配置
    cloud.enable: true
    cloud.backend_url: xxx
    cloud.app_id: xxx
    cloud.app_secret: xxx
    cloud.heartbeat_interval: 180
    %> curl -v 127.0.0.1:8080
    
    ...
    X-Protected-By: OpenRASP
    X-Request-ID: eb3b8e287de8406bb4bdb9d86bd31f99
    ...
    %> grep OpenRASP -ir rasp/logs/
    rasp/logs/rasp/rasp.log:2018-05-22 16:13:25,842 INFO  [main][com.baidu.openrasp.Agent] OpenRASP Engine Initialized [1.0-SNAPSHOT (build: GitCommit=3da661734e3ad7641cd98e83f32950deaefcacac date=2017-08-14T03:34:41Z)]
    -javaagent:C:\Program Files\Apache Software Foundation\Tomcat 7.0\rasp\rasp.jar
    --add-opens=java.base/jdk.internal.loader=ALL-UNNAMED
    --add-opens=java.base/java.net=ALL-UNNAMED
    :setArgs
    if ""%1""=="""" goto doneSetArgs
    set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
    :setArgs
    if "%ACTION%" == "start" set JAVA_OPTS=-javaagent:%CATALINA_HOME%\rasp\rasp.jar %JAVA_OPTS%
    if ""%1""=="""" goto doneSetArgs
    set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
    :setArgs
    if "%ACTION%" == "start" set JAVA_OPTS=-javaagent:%CATALINA_HOME%\rasp\rasp.jar --add-opens=java.base/jdk.internal.loader=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED %JAVA_OPTS%
    if ""%1""=="""" goto doneSetArgs
    set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
  • APM 兼容性说明

  • JDK9 以上安装问题

  • 常见 v8 加载失败原因

  • libzip.so 崩溃问题

  • 方法一: 访问网站,检查响应头里是否有 X-Protected-By: OpenRASP 字样?

  • 方法二: 检查启动日志里是否有 OpenRASP Engine Initialized 字样

  • 检测测试用例是否支持

    • 对于官方测试用例,若无法拦截,则说明存在绕过或者bug

    • 对于其他测试用例,请联系QQ群群主,我们会检查

  • 方法一: 访问网站,检查响应头里是否有 X-Protected-By: OpenRASP 字样?

  • 方法二: 创建内容为 <?php phpinfo(); ?> 的PHP文件并访问,检查页面中是否包含 openrasp 扩展信息?

  • 检测测试用例是否支持

    • 对于官方测试用例,若无法拦截,则说明存在绕过或者bug

    • 对于其他测试用例,请联系QQ群群主,我们会检查

  • rasp-cloud.tar.gz

    管理后台,Linux 版本

    rasp-cloud-mac.tar.gz

    管理后台,Mac 版本

    rasp-java.tar.gz

    JavaAgent,Linux 版本

    rasp-java.zip

    JavaAgent,Windows 版本

    rasp-php-linux.tar.bz2

    PHP Agent,Linux NTS 版本

    rasp-php-linux-ts.tar.bz2

    PHP Agent,Linux TS 版本

    10001

    未找到插入 JAVA_OPTIONS 的标志

    10002

    未找到服务器根目录,e.g 使用了不存在的目录

    10003

    未找到启动脚本,e.g bin/catalina.sh

    10004

    无法识别应用服务器类型

    10005

    命令行参数错误

    10006

    不重启安装,attach 进程失败

    20001

    fswatch 类库初始化失败,比如 rasp 安装目录没有写权限

    20002

    日志记录发生异常,比如日志文件没有写权限

    20003

    申请共享内存失败

    20004

    php.ini 配置不正确,比如缺少 openrasp.root_dir 配置

    20005

    JavaScript 插件加载错误

    国内镜像: packages.baidu.comarrow-up-right
    国外镜像: github.comarrow-up-right
    安装管理后台arrow-up-right
    Tomcat 服务器安装arrow-up-right
    安装测试用例arrow-up-right
    安装灰盒扫描工具arrow-up-right
    发版纪要arrow-up-right
    项目里程碑arrow-up-right
    beta 版本文档arrow-up-right
    常见自动安装失败原因
    OpenRASP 无法拦截攻击
    jnotify 无法释放
    pinpointarrow-up-right
    QQ技术讨论群arrow-up-right
    Oracle 官方博客 - Crashes in ZIP_GetEntryarrow-up-right
    其他配置arrow-up-right
    Could not find or load main class com.baidu.rasp.App 错误
    PHP 服务器安装arrow-up-right
    Unable to extract jnotify library (rasp/libjnotify_64bit.so):
    java.io.FileNotFoundException: /data/w/tomcat/rasp/libjnotify_64bit.so (Permission denied)
    	at java.io.FileOutputStream.open0(Native Method)
    	at java.io.FileOutputStream.open(FileOutputStream.java:270)
    	at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
    	at java.io.FileOutputStream.<init>(FileOutputStream.java:101)
    $ java -jar RaspInstall.jar -install /usr/local/tomcat/
    Error: Could not find or load main class com.baidu.rasp.App
    --add-opens=java.base/jdk.internal.loader=ALL-UNNAMED
    --add-opens=java.base/java.net=ALL-UNNAMED
    java.lang.ExceptionInInitializerError
        at org.scijava.nativelib.NativeLoader.<clinit>(NativeLoader.java:107)
        at com.baidu.openrasp.v8.V8.Load(V8.java:25)
        at com.baidu.openrasp.plugin.js.JS.Initialize(JS.java:44)
        at com.baidu.openrasp.EngineBoot.start(EngineBoot.java:56)
        at com.baidu.openrasp.ModuleContainer.start(ModuleContainer.java:78)
        at com.baidu.openrasp.ModuleLoader.<init>(ModuleLoader.java:74)
        at com.baidu.openrasp.ModuleLoader.load(ModuleLoader.java:103)
        at com.baidu.openrasp.Agent.init(Agent.java:93)
        at com.baidu.openrasp.Agent.premain(Agent.java:70)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:382)
        at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:397)
    Caused by: java.io.IOException: Permission denied
        at java.io.UnixFileSystem.createFileExclusively(Native Method)
        at java.io.File.createTempFile(File.java:2001)
        at java.io.File.createTempFile(File.java:2047)
        at org.scijava.nativelib.BaseJniExtractor.getTempDir(BaseJniExtractor.java:123)
        at org.scijava.nativelib.WebappJniExtractor.<init>(WebappJniExtractor.java:69)
        at org.scijava.nativelib.NativeLoader.<clinit>(NativeLoader.java:103)
        ... 14 more
    java.lang.UnsatisfiedLinkError: /var/cache/tomcat/temp/nativelib-loader_4485267645656510327/Classloader.1658314629304.0/libopenrasp_v8_java.so: /var/cache/tomcat/temp/nativelib-loader_4485267645656510327/Classloader.1658314629304.0/libopenrasp_v8_java.so: failed to map segment from shared object: Permission denied
       at java.lang.ClassLoader$NativeLibrary.load(Native Method)
       at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1934)
       at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1817)
       at java.lang.Runtime.load0(Runtime.java:810)
       at java.lang.System.load(System.java:1088)
       at com.baidu.openrasp.nativelib.NativeLibraryUtil.loadNativeLibrary(NativeLibraryUtil.java:340)
       at com.baidu.openrasp.nativelib.NativeLoader.loadLibrary(NativeLoader.java:136)
       at com.baidu.openrasp.v8.Loader.load(Loader.java:12)
       at com.baidu.openrasp.EngineBoot.start(EngineBoot.java:57)
       at com.baidu.openrasp.ModuleContainer.start(ModuleContainer.java:78)
       at com.baidu.openrasp.ModuleLoader.<init>(ModuleLoader.java:89)
       at com.baidu.openrasp.ModuleLoader.load(ModuleLoader.java:117)
       at com.baidu.openrasp.Agent.init(Agent.java:94)
       at com.baidu.openrasp.Agent.premain(Agent.java:71)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
       at java.lang.reflect.Method.invoke(Method.java:498)
       at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:386)
       at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:401)
    INFO: Couldn't find resource META-INF/lib/linux_arm64/libopenrasp_v8_java.so
    [OpenRASP] Failed to load native library, please refer to https://rasp.baidu.com/doc/install/software.html#faq-v8-load for possible solutions.
    java.io.IOException: Couldn't load library openrasp_v8_java
            at com.baidu.openrasp.nativelib.NativeLoader.loadLibrary(NativeLoader.java:138)
            at com.baidu.openrasp.v8.Loader.load(Loader.java:12)
            at com.baidu.openrasp.EngineBoot.start(EngineBoot.java:57)
            at com.baidu.openrasp.ModuleContainer.start(ModuleContainer.java:78)
            at com.baidu.openrasp.ModuleLoader.<init>(ModuleLoader.java:89)
            at com.baidu.openrasp.ModuleLoader.load(ModuleLoader.java:118)
    ava.io.IOException: Couldn't load library library openrasp_v8_java
        at org.scijava.nativelib.NativeLoader.loadLibrary(NativeLoader.java:141)
        at com.baidu.openrasp.v8.V8.Load(V8.java:25)
        at com.baidu.openrasp.plugin.js.JS.Initialize(JS.java:44)
        at com.baidu.openrasp.EngineBoot.start(EngineBoot.java:56)
        at com.baidu.openrasp.ModuleContainer.start(ModuleContainer.java:78)
        at com.baidu.openrasp.ModuleLoader.<init>(ModuleLoader.java:74)
        at com.baidu.openrasp.ModuleLoader.load(ModuleLoader.java:103)
        at com.baidu.openrasp.Agent.init(Agent.java:93)
        at com.baidu.openrasp.Agent.premain(Agent.java:70)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:382)
        at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:397)
    Caused by: java.lang.UnsatisfiedLinkError: no openrasp_v8_java in java.library.path
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1886)
        at java.lang.Runtime.loadLibrary0(Runtime.java:849)
        at java.lang.System.loadLibrary(System.java:1088)
        at org.scijava.nativelib.NativeLoader.loadLibrary(NativeLoader.java:136)
        ... 14 more
    Stack: [0x00007f3951edb000,0x00007f3951fdc000],  sp=0x00007f3951fda2d8,  free space=1020k
    Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
    C  [libc.so.6+0x15a00b]  __memmove_ssse3_back+0x6cb
    C  [libzip.so+0x12b33]  ZIP_GetNextEntry+0x53
    J 5497  java.util.zip.ZipFile.getNextEntry(JI)J (0 bytes) @ 0x00007f3a15da3c76 [0x00007f3a15da3bc0+0xb6]
    J 5495 C1 java.util.zip.ZipFile$ZipEntryIterator.next()Ljava/util/zip/ZipEntry; (212 bytes) @ 0x00007f3a15daebec [0x00007f3a15dae940+0x2ac]
    -Dsun.zip.disableMemoryMapping=true
    yum install -y centos-release-scl vim-common
    yum install -y devtoolset-4-gcc-c++
    yum install -y php-devel
    scl enable devtoolset-4 bash
    # 下载并解压到 /tmp,避免与已有 cmake 冲突
    curl -L  https://github.com/Kitware/CMake/releases/download/v3.15.3/cmake-3.15.3-Linux-x86_64.tar.gz | tar zx -C /tmp
    
    # 增加临时 PATH
    export PATH=/tmp/cmake-3.15.3-Linux-x86_64/bin:$PATH
    # 更新 git submodule
    git submodule update --init
    
    # 编译 openrasp-v8
    mkdir -p openrasp-v8/build && cd openrasp-v8/build
    cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_LANGUAGES=php ..
    make
    # 如果之前编译过,清理下临时文件
    phpize --clean
    
    # 生成 configure 文件
    phpize
    
    # 生成 makefile
    ./configure --with-openrasp-v8=../../openrasp-v8/ --with-gettext --enable-openrasp-remote-manager
    
    # 编译
    make
    安装后,需要重启 WebLogic 服务器生效。

    不重启安装

    以上方式安装成功之后需要重启服务器,如果在服务器启动的情况下,不重启安装 OpenRASP,需要在以上命令后面增加 -pid 参数指定运行的服务器进程 id,JDK6 - JDK8 样例命令如下,

    ** jdk9 ~ jdk11 不支持不重启安装 **

    hashtag
    手动安装(Linux)

    hashtag
    1. 安装软件

    进入到需要安装插件的domain目录下,如 e.g /opt/wls122212/base_domain

    复制安装包下面的 rasp 目录到当前目录

    OpenRASP 需要在 rasp 目录下释放一些动态链接库,所以还需要修改 rasp 目录的权限,e.g

    hashtag
    2. 配置 WebLogic

    非集群方式

    打开 bin/startWebLogic.sh, 找到 JAVA_OPTIONS="${SAVE_JAVA_OPTIONS}" 这一行,在该行下增加:

    集群方式

    方式一:通过weblogic的console

    • 访问weblogic的console,例如:http://10.115.184.54:8001/console/console.portal

    • 环境->服务器,找到要安装的server(本例为Server-0)

    • 点击进入Server-0,选择服务器启动,在参数框中,添加如下配置,保存退出

    img
    • 重启Server-0之后,服务器生效

    方式二:通过配置weblogic的config.xml文件

    找到<weblogic-home>/user_projects/domains/base_domain/config目录,打开config.xml文件,定位到需要安装rasp的<server>/<server-start>/<arguments>标签,在<arguments>标签内添加javaagent参数。

    如果没有相应的标签可以手动添加,e.g

    重启安装rasp的server,服务器生效

    hashtag
    3. 验证安装是否成功

    访问 WebLogic 服务器,检查HTTP响应里是否包含 X-Protected-By: OpenRASP 字样,若出现则表示安装成功。若没有安装成功,请检查 WebLogic 是否有异常日志:

    hashtag
    手动安装(Windows){#manual-window}

    hashtag
    1. 安装软件

    进入 WebLogic Domain 目录,e.g C:\wls12212\user_projects\domains\base_domain,并将压缩包内的 rasp 目录复制过来

    hashtag
    2. 配置 WebLogic

    非集群模式

    打开 bin/startWebLogic.cmd, 找到 set JAVA_OPTIONS=%SAVE_JAVA_OPTIONS%"这一行,在下面增加:

    集群模式

    同Linux的集群模式

    hashtag
    3. 验证安装是否成功

    访问 WebLogic 服务器,检查HTTP响应里是否包含 X-Protected-By: OpenRASP 字样,若出现则表示安装成功。若没有安装成功,请检查 WebLogic 是否有异常日志:

    hashtag
    FAQ

    hashtag
    1. Weblogic 10.36 无法加载的问题

    Weblogic 10.36版本使用32位的JRockit JDK,若系统缺少32位的glibc,可能无法加载 openrasp.so。解决方法就是安装32位glibc,并再次尝试启动。

    对于 CentOS 系统,你需要安装 libgcc.i686,否则会提示找不到 libgcc_s.so.1 错误:

    若安装过程中出现 libgcc multilib 版本保护问题,e.g

    可尝试先升级 libgcc 到最新版本,再安装32位的 libgcc,e.g

    之后尝试启动即可。

    管理后台 - 添加主机arrow-up-right

    JBoss 服务器

    hashtag
    自动化安装

    解压缩后,首先进入到解压后的目录中,e.g rasp-20170721

    如果你要开启远程管理,请先参考 管理后台 - 添加主机arrow-up-right 文档,找到 app_id/app_secret/backend_url 三个关键参数,然后执行如下命令,

    如果你只是运行单机版,只需要指定 -install 参数,

    安装成功后,需要重启 JBoss 服务器生效。

    不重启安装

    以上方式安装成功之后需要重启服务器,如果在服务器启动的情况下,不重启安装 OpenRASP,需要在以上命令后面增加 -pid 参数指定运行的服务器进程 id,JDK6 - JDK8 样例命令如下,

    ** 由于无法在运行时增加 JbossEAP 对 OpenRASP 的运行时依赖,所以无法支持 JbossEAP 的不重启安装 **

    ** jdk9 ~ jdk11 不支持不重启安装 **

    hashtag
    手动安装 - Linux

    1. 安装软件

    进入到 jboss 安装目录(绝对路径包含空格将导致启动失败),e.g /opt/jboss

    复制安装包内的 rasp 目录到当前目录,

    OpenRASP 需要在 rasp 目录下释放一些动态链接库,所以还需要修改 rasp 目录的权限,e.g

    2. 配置 JBoss

    如果是 JBoss 4-6 (非 EAP 版本),

    打开bin/run.sh, 找到任意以 JAVA_OPTS= 为起始的行,e.g

    在下面增加 JAVA_OPTS="-javaagent:${JBOSS_HOME}/rasp/rasp.jar ${JAVA_OPTS}",最终效果如下:

    如果是 JBoss EAP,

    standalone模式

    打开bin/standalone.sh,找到# Display our environment处,在下面添加:

    domain模式

    server-group方式配置rasp

    如果按照server-group配置rasp,那么此group下面所有的服务器都会安装rasp,打开domain/configuration/domain.xml文件,找到<server-groups>标签,在需要安装rasp的server-group中找到<jvm>标签添加如下配置:

    server方式配置rasp

    如果只对某个server-group的特定的server安装rasp,打开domain/configuration/host.xml文件,找到<servers>标签,在需要安装rasp的server中添加如下配置:

    3. 开启远程管理

    配置方法同 ,不再赘述。

    4. 验证安装是否成功

    重启 JBoss 服务器,观察启动日志中是否出现 OpenRASP Engine Initialized字段,出现则说明安装成功

    hashtag
    手动安装 - Windows

    1. 安装软件

    进入到 jboss 安装目录,e.g D:\\jboss

    复制安装包内的 rasp 目录到当前目录

    2. 配置 JBoss

    如果使用Jboss 4~6 (非 EAP 版本),则打开 bin\run.bat;

    打开脚本后,找到任意以 set JAVA_OPTS 为起始的行,如:

    在下面增加 set JAVA_OPTS=-javaagent:%JBOSS_HOME%\rasp\rasp.jar %JAVA_OPTS%:

    如果使用Jboss EAP,

    standalone模式

    打开 bin\standalone.bat 找到第一次出现rem Setup JBoss specific properties处,在下面添加:

    domain模式

    方法同 Linux 版本

    3. 开启远程管理

    配置方法同 ,不再赘述。

    4. 验证安装是否成功

    重启 JBoss 服务器,观察启动日志(默认输出到终端)中是否出现 OpenRASP Engine Initialized字段,出现则说明安装成功;或者访问一下服务器,检查是否存在 X-Protected-By: OpenRASP 响应头,存在即表示安装成功。

    hashtag
    已知问题

    1. java.io.ObjectInputStream 错误

    这个并不是 OpenRASP 的问题,请尝试更新JDK到最新版本

    参考资料

    2. JDK 9 以上版本兼容性问题

    请参考 手动修改启动参数。我们会尽快修改 RaspInstall 程序,并自动添加这个配置。

    3. org.jboss.logmanager.PropertyConfigurator cannot be cast to org.jboss.as.logging.logmanager.ConfigurationPersistence 异常

    在JBoss EAP 6.1.0上安装OpenRASP后,JBoss可能会无法启动并打印如下错误:

    ,有两种解决方法:

    • 升级到 JBoss EAP 6.1.1

    • 手动修正 JBOSS_MODULES_SYSTEM_PKGS 配置,暴露相关的Jar给javaagent

    Wildfly 服务器

    hashtag
    自动化安装

    解压缩后,首先进入到解压后的目录中,e.g rasp-20181221

    如果你要开启远程管理,请先参考 管理后台 - 添加主机arrow-up-right 文档,找到 app_id/app_secret/backend_url 三个关键参数,然后执行如下命令,

    如果你只是运行单机版,只需要指定 -install 参数,

    这里的 <wildfly_root> 是 wildfly 的根目录。没有错误表示安装成功,其他配置请参考 文档。安装后,需要重启 Wildfly 服务器生效。

    ** 由于无法在运行时增加 Wildfly 对 OpenRASP 的运行时依赖,所以无法支持 Wildfly 的不重启安装 **

    hashtag
    手动安装 - Linux

    1. 安装软件

    进入到 wildfly 安装目录(绝对路径包含空格将导致启动失败),e.g /opt/wildfly-9.0.1.Final,将 rasp 目录复制过来

    OpenRASP 需要在 rasp 目录下释放一些动态链接库,所以还需要修改 rasp 目录的权限,e.g

    2. 修改 Wildfly 启动脚本

    如果是standalone模式

    打开 bin/standalone.sh, 找到如下内容:

    在其下面增加如下内容:

    如果是domain模式

    server-group

    如果按照server-group配置rasp,那么此group下面所有的服务器都会安装rasp,打开domain/configuration/domain.xml文件,找到<server-groups>标签,在需要安装rasp的server-group中找到<jvm>标签添加如下配置:

    server

    如果只对某个server-group的特定的server安装rasp,打开domain/configuration/host.xml文件,找到<servers>标签,在需要安装rasp的server中添加如下配置:

    3. 开启远程管理

    如果你不需要远程管理功能,请跳过这个步骤。

    首先在管理后台找到 app_id、app_secret 两个关键参数,然后打开 <wildfly_home>/rasp/conf/openrasp.yml,添加或者修改如下内容:

    4. 验证安装是否成功

    重启 wildfly 服务器,然后检查 rasp/logs/rasp/rasp.log 中是否出现 OpenRASP Engine Initialized 字样,e.g

    或者检查响应的 Header 是否包含 X-Protected-By 字样,e.g

    出现则表示安装成功

    hashtag
    手动安装 - Windows

    1. 安装软件

    进入到 wildfly 安装目录,e.g D:\wildfly-9.0.1.Final,将 rasp 目录复制过来

    2. 修改 wildfly 配置

    如果是standalone模式

    打开 bin\standalone.bat, 找到 rem Setup JBoss specific properties 处:

    在其下增加如下内容:

    如果是domain模式

    方法同 Linux 版本

    3. 开启远程管理

    方法同 Linux 版本,在 openrasp.yml 里增加相关配置即可。

    4. 验证安装是否成功

    重启 wildfly 服务器,然后检查日志文件,一般是 rasp/logs/rasp/rasp.log,如果出现 OpenRASP Engine Initialized 字样,出现则说明安装成功;或者访问一下服务器,检查是否存在 X-Protected-By: OpenRASP 响应头,存在即表示安装成功。

    PHP 服务器

    OpenRASP 依赖于如下几个扩展。如果你在使用发行版自带的 PHP 环境,可以使用 yum、apt-get 等工具安装下这些扩展;如果是自己编译的 PHP 环境,则需要在编译阶段开启这些功能。

    • pdo

    • pcre

    • json

    对于服务器环境和操作系统的支持情况,可查看,目前 5.3 - 7.3 都是支持的。

    hashtag
    自动化安装

    下载 rasp-php-linux.tar.bz2 或者 rasp-php-linux-ts.tar.bz2(线程安全版本) 并解压缩。之后进入到解压后的目录中,e.g rasp-php-20180320

    如果你要开启远程管理,请先参考 文档,找到 app_id/app_secret/backend_url 三个关键参数,然后执行如下命令,

    如果你只是运行单机版,只需要指定 -d 参数,

    其中 /opt/rasp 为 OpenRASP 安装目录,用于存储检测插件、报警日志等等,可根据实际情况调整。在某些情况下,php cli 和 php-fpm 使用的 ini 不同,自动安装程序可能会失败。

    hashtag
    升级 PHP Agent

    首先,备份老的扩展,e.g

    然后,安装新的扩展,e.g

    最后,通过 graceful reload 方式重新加载服务。

    针对不同的服务器类型,你需要执行不同的命令,e.g

    需要注意的是,请不要直接覆盖 openrasp.so,否则会产生意想不到的内存错误。我们建议使用 重命名方式 来安装新版,以避免出现问题。

    hashtag
    手动安装 - Linux

    hashtag
    1. 确认基本信息

    在 web 目录下面,我们建立一个 info.php,并填写如下内容

    在浏览器里打开这个页面,使用搜索功能,

    1. 定位到 extension_dir 字样,确认PHP扩展安装目录

      • e.g /usr/lib/php/20151012

    2. 搜索 Additional .ini files parsed 字样,

    hashtag
    2. 安装软件

    首先,根据你的 PHP 版本号,复制正确的 openrasp.so 到扩展目录,e.g

    然后,确定 OpenRASP 安装目录,在这里我们使用 /opt/rasp

    这个目录将会用于存储检测插件、报警日志、插件日志等内容,需要手动创建,并保证 PHP 进程可以写入,e.g

    由于报警日志存储在 /opt/rasp/logs,我们建议挑选一个空间较大的分区,以避免将根分区打满

    最后,修改 php.ini,或者创建 z-openrasp.ini 文件,添加如下内容:

    其中,openrasp.root_dir 表示刚才选择的 OpenRASP 安装目录,不填写则无法加载。对于其他配置参数,可参考文档进行调整。

    hashtag
    3. 安装检测插件

    点击这里下载官方插件 ,并放置到 <openrasp.root_dir>/plugins/ 目录,下载后自动加载并生效。

    hashtag
    4. 验证安装是否成功

    访问刚才创建的 info.php,检查 openrasp 模块是否加载成功即可,e.g

    如果你没有看到类似的信息,则说明扩展加载失败。常见原因有

    1. PHP版本和扩展版本不一致,比如 PHP 是 5.3 版本,但你安装了 PHP 5.6 版本的 openrasp.so

    2. INI 配置不正确,请参考 php error.log 里的错误消息

      • 所有的错误消息都以 [OpenRASP] 错误码 开头,方便和其他日志进行区分

    确认安装成功后,请删除 info.php 这个文件,以避免泄露敏感信息。

    hashtag
    手动安装 - MacOS

    我们只支持 Homebrew PHP 5.6 版本,安装过程同 Linux 系统,aka

    1. 复制 dylib 文件到 PHP 扩展目录

    2. 修改 INI 配置文件

    3. 重启 php-fpm 生效

    另外,MacOS 版本不支持远程管理。

    hashtag
    FAQ

    hashtag
    1. include/require hook 点未生效

    OpenRASP 扩展跟 xdebug 模块存在冲突,若同时开启了 xdebug 模块,请先禁用它

    hashtag
    2. 单机版 php-fpm 模式下,插件目录的文件监控功能,有时会失效

    在 openrasp 扩展初始化时,我们创建了文件监控线程,用于插件目录的监控。当我们发现插件目录发生变化,就会通过发送 USR2 信号的方式,通知 php-fpm master process 去重新加载子进程,即 gracefully reload。

    然而,如果你在启动 php-fpm 的时候,没有使用 -F 参数,则意味着 php-fpm 会主动 fork() 到后台。此时,我们创建的文件监控线程就会失效,也就无法监控插件目录了。

    解决方法就是使用 php-fpm -F 这样的方式启动PHP服务器。当然,如果你使用发行版自带的 php-fpm,通常都是这样启动的,无需担心。

    hashtag
    3. OpenRASP正常拦截攻击,但是alarm.log没有日志

    默认情况下,OpenRASP会被安装到/opt/rasp,以下用<openrasp.root_dir>代替。你需要检查<openrasp.root_dir>/rasp/logs目录是否存在,以及是否有写权限。

    常见没有权限的原因有:

    1. 使用了root账号安装OpenRASP,而应用使用低权限账号运行(比如nobody)。

      1. 可以执行chmod 777 -R <openrasp.root_dir>/logs增加权限

      2. 也可以使用chmod修改上述目录的属主(更加安全)

    hashtag
    4. CentOS 7.4 apache 使用 systemd 启动会崩溃的问题

    systemd 会限制应用栈的大小,导致 openrasp 无法启动。你通过修改 /usr/lib/systemd/system/httpd.service,并提高 LimitStack 的值来解决问题。经过测试,我们发现将栈大小限制改为 16MB 可以解决问题,对应的配置为:

    当然,直接使用命令行启动 apache 是没有这个问题的,因为他会继承系统默认的 limit 配置,即 unlimited。

    hashtag
    5. php_json_encode 未定义错误

    OpenRASP 依赖于多个PHP扩展,json、pdo、pcre 等等。由于 PHP 不会严格按照依赖顺序去加载扩展,所以当 openrasp 先于 json 加载,就会产生这个错误,e.g

    解决方法就是让 openrasp 扩展最后加载。常见的做法是调整配置文件的权重,比如将 openrasp 配置文件改为 /etc/php.d/z-openrasp.ini,这样 json 配置文件就会先于 openrasp 配置文件加载,就解决了扩展依赖的问题。

    hashtag
    6. 无法检测到 web 目录下的敏感文件?{#faq-webdir-scan}

    当PHP服务器处理过至少一次请求后,我们才能够检测到 webroot,之后才会启动敏感目录检测功能。为了保证性能,该检测点具有如下限制:

    1. 只会检测根目录,子目录不会处理

    2. 最多在内存里缓存 256 个不同的 webroot 路径,超过这个限制时,只保留已有的路径

    hashtag
    7. alphine 环境无法启动,提示找不到 ld-linux-x86-64.so.2

    根据QQ群用户反馈,增加软连接可以解决问题:

    hashtag
    8. 如何判断PHP是否为线程安全版本

    执行如下命令,如果返回 bool(true) 则是线程安全(TS)版本

    当然也可以编写PHP脚本来测试,如果页面返回 bool(true) 则是线程安全(TS)版本

    Jetty 服务器

    hashtag
    手动安装

    1. 安装软件

    进入到 jetty 安装目录,e.g /opt/jetty

    复制安装包内的 rasp 目录到当前目录,

    OpenRASP 需要在 rasp 目录下释放一些动态链接库,所以还需要修改 rasp 目录的权限,e.g

    2. 配置 Jetty

    这里假设 rasp 目录释放到了 /opt/jetty/rasp/。

    修改 java 启动参数,增加 -javaagent 参数(注意将 -jar 放在命令最末尾):

    需要注意的是,对于Windows服务器,请修正 -javaagent 参数,比如

    3. 开启远程管理

    配置方法同 ,不再赘述。

    4. 检查 Jetty 是否安装成功

    重启 Jetty 服务器,然后检查日志文件,如果出现 OpenRASP Engine Initialized 字样,出现则说明安装成功;或者访问一下服务器,检查是否存在 X-Protected-By: OpenRASP 响应头,存在即表示安装成功。

    hashtag
    FAQ

    1. Jetty / JDK 兼容性问题

    Jetty 在 linux/windows 下存在很多问题,经常会看到以下几种错误

    • PWC6345: There is an error in invoking javac

    • PWC6199: The type java.io.ObjectStream cannot be resolved

    以上这些问题大多是JDK、Jetty自身的问题,可通过更换其他小版本来解决。即使没有安装OpenRASP,Jetty运行也是不正常的。在安装 OpenRASP 前,请先保证Jetty是正常运行的

    当然,如果安装OpenRASP后导致jetty出错,你可以

    宝兰德BES服务器

    hashtag
    手动安装

    hashtag
    1. 安装软件

    复制安装包内的 rasp 目录到 BES 安装目录,比如

    WebSphere 服务器

    hashtag
    手动安装

    hashtag
    1. 安装软件

    复制安装包内的 rasp 目录到 WebSphere 安装目录,比如

    东方通TongWeb服务器

    hashtag
    手动安装

    hashtag
    1. 安装软件

    复制安装包内的 rasp 目录到 TongWeb 安装目录,比如

    中创InforSuiteAS服务器

    hashtag
    手动安装

    hashtag
    1. 安装软件

    复制安装包内的 rasp 目录到 InforSuiteAS 安装目录,比如

    java -jar RaspInstall.jar -install <weblogic_domain_home> -backendurl http://XXX -appsecret XXX -appid XXX
    java -jar RaspInstall.jar -install <weblogic_domain_home>
    # <server_pid> 为 weblogic 进程 id
    # $JAVA_HOME 为 jdk 根目录环境变量,如果未指定该环境变量,替换为 jdk 的完整根目录
    java -Xbootclasspath/a:$JAVA_HOME/lib/tools.jar -jar RaspInstall.jar -install <weblogic_domain_home> -pid <server_pid>
    cp -R ~/Downloads/rasp-20170721/rasp .
    chmod 777 -R rasp
    JAVA_OPTIONS="-javaagent:${DOMAIN_HOME}/rasp/rasp.jar ${JAVA_OPTIONS}"
    -javaagent:<agent_directory_full_path>/rasp/rasp.jar
    <server>
    	<server-start>
    		<arguments>-javaagent:/PATH/TO/DOMAIN_HOME/rasp/rasp.jar</arguments>
    	</server-start>
    </server>
    ${DOMAIN_HOME}/servers/<安装rasp的server名字>/logs
    set JAVA_OPTIONS=-javaagent:%DOMAIN_HOME%\rasp\rasp.jar %JAVA_OPTIONS%
    ${DOMAIN_HOME}/servers/<安装rasp的server名字>/logs
    yum install -y ligbcc.i686
    Error: Multilib version problems found. This often means that the root
           cause is something else and multilib version checking is just
           pointing out that there is a problem. Eg.:
    
    Protected multilib versions: libgcc-4.8.2-8.el6.x86_64 != libgcc-4.4.7-11.el6.i686
    yum install -y libgcc
    yum install -y ligbcc.i686
    java -jar RaspInstall.jar -install <jboss_root> -backendurl http://XXX -appsecret XXX -appid XXX
    java -jar RaspInstall.jar -install <jboss_root>
    java -jar RaspInstall.jar -install <wildfly_root> -backendurl http://XXX -appsecret XXX -appid XXX
    java -jar RaspInstall.jar -install <wildfly_root>
    cp -R ~/Downloads/rasp-20170721/rasp .
    img
    img
    Tomcat 开启远程管理arrow-up-right
    Tomcat 开启远程管理arrow-up-right
    The type java.io.ObjectInputStream cannot be resolved. It is indirectly referenced from required .class filesarrow-up-right
    JDK9 以上安装问题arrow-up-right
    根据Redhat的描述arrow-up-right
    其他配置
    安装中出现任何问题,请联系我们arrow-up-right
    安装中出现任何问题,请联系我们arrow-up-right
  • 如果找到了,我们就在这个目录下面创建一个新的 ini 文件,e.g /etc/php.d/z-openrasp.ini

  • 如果找不到,就定位到 Loaded Configuration File 字样,确认 ini 配置文件路径

    • e.g /etc/php.ini

  • 对于 apache/nginx,可以查看类似 /var/log/nginx/error.log 的路径

    开启了LSM

  • 对于CentOS/RHEL系统,请检查SELinux是否开启。如果开启,可执行setenforce 0关闭

  • 对于Debian/Ubuntu系统,请检查AppArmor是否开启。如果开启,可以修改php-fpm、apache进程的加固配置

  • 开启了open_basedir配置

    1. 我们使用PHP Stream方式写入日志,需要将日志目录加到open_basedir白名单里。如果没有加入,将会看到类似这样的错误

    2. 由于nginx/php-fpm/apache都可以修改php的配置,建议在网站根目录下放置phpinfo来检查该配置项,要比命令行准确

  • 如果依然无法解决问题,请检查 php error_log 是否有 OpenRASP 相关的错误日志

    • 如果没有配置过,请在 php.ini 里开启,e.g error_log = /tmp/php_error.log

  • 兼容性说明 - PHP Agentarrow-up-right
    管理后台 - 添加主机arrow-up-right
    其他配置
    plugins/official/plugin.jsarrow-up-right
    img
    Tomcat 开启远程管理arrow-up-right
    联系我们arrow-up-right
    # <server_pid> 为 jboss 进程 id
    # $JAVA_HOME 为 jdk 根目录环境变量,如果未指定该环境变量,替换为 jdk 的完整根目录
    java -Xbootclasspath/a:$JAVA_HOME/lib/tools.jar -jar RaspInstall.jar -install <jboss_root> -pid <server_pid>
    cp -R ~/Downloads/rasp-20170721/rasp .
    chmod 777 -R rasp
    # Setup JBoss specific properties
    JAVA_OPTS="-Dprogram.name=$PROGNAME $JAVA_OPTS"
    # Setup JBoss specific properties
    JAVA_OPTS="-Dprogram.name=$PROGNAME $JAVA_OPTS"
    JAVA_OPTS="-javaagent:${JBOSS_HOME}/rasp/rasp.jar ${JAVA_OPTS}"
    JAVA_OPTS="${JAVA_OPTS} -javaagent:${JBOSS_HOME}/rasp/rasp.jar"
    <jvm-options>
       <option value="-javaagent:<jboss_root>/rasp/rasp.jar"/>
    </jvm-options>
    <jvm name="default">
        <jvm-options>
       		<option value="-javaagent:<jboss_root>/rasp/rasp.jar"/>
    	</jvm-options>
    </jvm>
    set JAVA_OPTS=%JAVA_OPTS% -Dprogram.name=%PROGNAME%
    set JAVA_OPTS=%JAVA_OPTS% -Dprogram.name=%PROGNAME%
    set JAVA_OPTS=-javaagent:%JBOSS_HOME%\rasp\rasp.jar %JAVA_OPTS%
    set "JAVA_OPTS=%JAVA_OPTS% -javaagent:%JBOSS_HOME%\rasp\rasp.jar"
    14:27:19,691 ERROR [org.jboss.as.controller.management-operation] (ServerService Thread Pool -- 11) JBAS014612: Operation ("add") failed - address: ([
        ("subsystem" => "logging"),
        ("console-handler" => "CONSOLE")
    ]): java.lang.ClassCastException: org.jboss.logmanager.PropertyConfigurator cannot be cast to org.jboss.as.logging.logmanager.ConfigurationPersistence
            at org.jboss.as.logging.logmanager.ConfigurationPersistence.getOrCreateConfigurationPersistence(ConfigurationPersistence.java:93)
            at org.jboss.as.logging.logmanager.ConfigurationPersistence.getOrCreateConfigurationPersistence(ConfigurationPersistence.java:81)
            at org.jboss.as.logging.LoggingOperations$LoggingOperationStepHandler.execute(LoggingOperations.java:154)
            at org.jboss.as.controller.AbstractOperationContext.executeStep(AbstractOperationContext.java:440) [jboss-as-controller-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
            at org.jboss.as.controller.AbstractOperationContext.doCompleteStep(AbstractOperationContext.java:322) [jboss-as-controller-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
            at org.jboss.as.controller.AbstractOperationContext.completeStepInternal(AbstractOperationContext.java:229) [jboss-as-controller-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
            at org.jboss.as.controller.AbstractOperationContext.executeOperation(AbstractOperationContext.java:224) [jboss-as-controller-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
            at org.jboss.as.controller.ParallelBootOperationStepHandler$ParallelBootTask.run(ParallelBootOperationStepHandler.java:334) [jboss-as-controller-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_79]
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_79]
            at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_79]
            at org.jboss.threads.JBossThread.run(JBossThread.java:122) [jboss-threads-2.1.0.Final-redhat-1.jar:2.1.0.Final-redhat-1]
    cp -R ~/Downloads/rasp-20170721/rasp .
    chmod 777 -R rasp
    # Display our environment
    JAVA_OPTS="$JAVA_OPTS -javaagent:$JBOSS_HOME/rasp/rasp.jar"
    <jvm-options>
       <option value="-javaagent:<wildfly_root>/rasp/rasp.jar"/>
    </jvm-options>
    <jvm name="default">
        <jvm-options>
            <option value="-javaagent:<wildfly_root>/rasp/rasp.jar"/>
        </jvm-options>
    </jvm>
    # 云控配置
    cloud.enable=true
    cloud.backend_url=http://XXXX
    cloud.app_id=XXXX
    cloud.app_secret=XXXX
    %> grep OpenRASP -ir rasp/logs/
    rasp/logs/rasp/rasp.log:2018-05-22 16:13:25,842 INFO  [main][com.baidu.openrasp.Agent] OpenRASP Engine Initialized [1.0-SNAPSHOT (build: GitCommit=3da661734e3ad7641cd98e83f32950deaefcacac date=2017-08-14T03:34:41Z)]
    %> curl -v 127.0.0.1:8080
    
    ...
    X-Protected-By: OpenRASP
    X-Request-ID: eb3b8e287de8406bb4bdb9d86bd31f99
    ...
    set JAVA_OPTS=%JAVA_OPTS% -javaagent:%JBOSS_HOME%/rasp/rasp.jar
    PHP Warning:  scandir(): open_basedir restriction in effect. File(/www/rasp/logs/alarm/alarm.log.2018-07-26) is not within the allowed path(s)
    php install.php -d /opt/rasp --backend-url http://myserver:port --app-secret XXX --app-id XXXX
    php install.php -d /opt/rasp
    mv /usr/lib64/php/modules/openrasp.so /usr/lib64/php/modules/openrasp.so.bak
    cp openrasp.so /usr/lib64/php/modules/openrasp.so
    PHP-FPM 服务器
    killall -USR2 php-fpm
    
    Apache HTTPD 服务器
    apachectl -k reload
    <?php phpinfo();?> 
    cp php/linux-php5.4-x86_64/openrasp.so /usr/lib/php/20151012
    chmod 755 /usr/lib/php/20151012/openrasp.so
    mkdir -p /opt/rasp
    chmod 777 -R /opt/rasp
    ; BEGIN OPENRASP
    
    [openrasp]
    extension=openrasp.so
    openrasp.root_dir=/opt/rasp
    
    ; 远程管理配置,不需要不用配置
    ; openrasp.backend_url=
    ; openrasp.app_id=
    ; openrasp.app_secret=
    ; openrasp.remote_management_enable=1
    
    ; END OPENRASP
    LimitStack=163840
    PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/openrasp.so' - /usr/lib64/php/modules/openrasp.so: undefined symbol: php_json_encode in Unknown on line 0
    ln -s /lib64/ld-linux-x64-64.so.2 /lib/
    php -r "var_dump(ZEND_THREAD_SAFE);"
    <?php echo var_dump(ZEND_THREAD_SAFE); ?>
    chmod 777 -R rasp
    java -javaagent:/opt/jetty/rasp/rasp.jar -jar start.jar
    -javaagent:D:\jetty\rasp\rasp.jar
    • D:\bes\rasp

    • /opt/bes/rasp

    OpenRASP 需要在 rasp 目录下释放一些动态链接库,所以在 Linux 下还需要修改 rasp 目录的权限,e.g

    hashtag
    2. 配置 BES 服务器

    2.1 方法一: 通过BES控制台进行配置

    以 BES 9.5 为例,在控制台左侧的导航栏里,选择 实例信息 -> JVM配置,进入JVM配置页面:

    console

    在JVM配置页面向下翻,找到JVM选项,并开始编辑

    server1

    如果是 Windows 系统,请填写:

    如果是 Linux 系统,请填写:

    保存后重启应用生效。

    2.2 方法二: 手动修改BES的server.config文件

    编辑 <bes-home>/conf/server.config 文件,并在 <server>/<java-config>/<jvm-options> 标签下,增加新的 JVM 配置,e.g

    保存后重启应用生效。

    hashtag
    3. 开启远程管理

    配置方法同 Tomcat 开启远程管理arrow-up-right,不再赘述。

    hashtag
    4. 检查安装是否成功

    访问下服务器,检查响应头里是否存在 X-Protected-By: OpenRASP 字样,存在即表示安装成功。当然,如果安装 OpenRASP 后导致 BES 出错,你可以联系我们arrow-up-right

    • D:\IBM

    • /opt/IBM/WebSphere/AppServer

    OpenRASP 需要在 rasp 目录下释放一些动态链接库,所以在 Linux 下还需要修改 rasp 目录的权限,e.g

    hashtag
    2. 配置 WebSphere 服务器

    以 WAS 8.5 为例,在控制台左侧的导航栏里,选择 Servers -> Server Types -> WebSphere Application Server,进入应用列表界面:

    console

    选择你要开启 RASP 的应用(这里是 server1),点击进入管理页面。在新页面向下翻,找到 Server Infrastructure -> Process definition,并点击进入:

    server1

    之后在右侧,点击 Additional Properties -> Java Virtual Machine 进入JVM启动参数编辑界面

    server1

    最后找到 Generic JVM arguments,开始编辑

    server1

    如果是 Windows 系统,请填写:

    如果是 Linux 系统,请填写:

    保存后重启应用生效。

    hashtag
    3. 开启远程管理

    配置方法同 Tomcat 开启远程管理arrow-up-right,不再赘述。

    hashtag
    4. 检查安装是否成功

    • 方法1,检查日志中是否出现 OpenRASP Engine Initialized 字样,出现则说明安装成功。比如 /opt/IBM/WebSphere/AppServer/profiles/AppSrv01/logs/server1

    • 方法2,访问下服务器,检查响应头里是否存在 X-Protected-By: OpenRASP 字样,存在即表示安装成功。

    当然,如果安装 OpenRASP 后导致 WebSphere 出错,你可以联系我们arrow-up-right

    hashtag
    常见问题

    1. 远程管理无法开启,且日志中出现 java.security.AccessControlException 异常

    在 WebSphpere Windows 某些小版本下,比如 8.5.5.0,可能会出现 java 安全异常错误。此时会在 ${WAS_INSTALL_ROOT}/profiles/AppSrv01/logs/native_stderr.log 里看到如下内容:

    解决方案是增加相关权限,打开 ${WAS_INSTALL_ROOT}/java/jre/lib/security/java.policy,增加如下内容:

    修改后,需要重启 WebSphere 服务器生效。

    • D:\tongweb安装目录\rasp

    • /opt/tongweb安装目录/rasp

    OpenRASP 需要在 rasp 目录下释放一些动态链接库,所以在 Linux 下还需要修改 rasp 目录的权限,e.g

    hashtag
    2. 配置 TongWeb 服务器

    2.1 方法一: 手动配置 external.vmoptions 文件

    打开 Tongweb安装目录/bin/external.vmoptions,然后在其中添加javaagent的配置项:

    添加完成后的效果如下图所示(参考红线部分):

    console

    配置完成后,重启TongWeb服务器即可生效。

    2.2 方法二: 通过TongWeb控制台进行配置

    登陆TongWeb的管理控制台,点击左侧 启动参数配置,然后找到 其他jvm参数,添加javagent配置项即可:

    添加完成后的效果如下图所示(参考红线部分):

    console

    添加完成后点击保存按钮,然后重启TongWeb服务器即可生效。

    hashtag
    3. 开启远程管理

    配置方法同 Tomcat 开启远程管理arrow-up-right,不再赘述。

    hashtag
    4. 检查安装是否成功

    访问下服务器,检查响应头里是否存在 X-Protected-By: OpenRASP 字样,存在即表示安装成功。当然,如果安装 OpenRASP 后导致TongWeb出错,你可以联系我们arrow-up-right

    • D:\inforsuiteas\rasp

    • /opt/inforsuiteas/rasp

    OpenRASP 需要在 rasp 目录下释放一些动态链接库,所以在 Linux 下还需要修改 rasp 目录的权限,e.g

    hashtag
    2. 配置 InforSuiteAS 服务器

    2.1 方法一: 通过 InforSuiteAS 控制台进行配置

    以 InforSuiteAS 10.0 为例,在控制台左侧的导航栏里,选择 配置 -> server-config-> JVM设置,进入JVM选项页面:

    jvm

    在JVM选项页面向下翻,找到JVM选项,并开始编辑:

    param

    如果是 Windows 系统,请填写:

    如果是 Linux 系统,请填写:

    保存后重启应用服务生效。

    2.2 方法二: 手动修改InforSuiteAS的domain.xml文件

    编辑 <com.cvicse.loong.las.installRoot>/as/domains/domain1/config/domain.xml 文件,并在 <domain>/<configs>/<config name="server-config">/<java-config>/<jvm-options> 标签下,增加新的 JVM 配置,e.g

    保存后重启应用服务生效。

    hashtag
    3. 开启远程管理

    配置方法同 Tomcat 开启远程管理arrow-up-right,不再赘述。

    hashtag
    4. 检查安装是否成功

    访问下服务器,检查响应头里是否存在 X-Protected-By: OpenRASP 字样,存在即表示安装成功。当然,如果安装 OpenRASP 后导致 InforSuiteAS 出错,你可以联系我们arrow-up-right

    Resin 服务器

    hashtag
    自动化安装

    解压缩后,首先关闭Resin服务器,然后进入到解压后的目录中,e.g rasp-20180522

    如果你要开启远程管理,请先参考 管理后台 - 添加主机arrow-up-right 文档,找到 app_id/app_secret/backend_url 三个关键参数,然后执行如下命令,

    如果你只是运行单机版,只需要指定 -install 参数,

    安装成功后,需要重启 Resin 服务器生效。

    不重启安装

    Resin 目前不支持。

    hashtag
    手动安装

    1. 安装软件

    进入到 resin 安装目录(绝对路径包含空格将导致启动失败),e.g /opt/resin

    复制安装包内的 rasp 目录到当前目录,

    OpenRASP 需要在 rasp 目录下释放一些动态链接库,所以还需要修改 rasp 目录的权限,e.g

    2. 配置 Resin

    注意: 对于集群模式,可能不存在 <server-default> 标签。对于此类情况,请联系研发团队,并确认应该在哪里增加 JVM 启动参数。

    如果是 resin 3,

    打开conf/resin.conf, 找到 <server-default> 下面的 <jvm-arg> 起始行,e.g

    在下面增加:

    如果是 resin 4,

    打开 conf/cluster-default.xml, 找到 <server-default> 下面的 <jvm-arg-line> 起始行,e.g

    在下面增加:

    3. 开启远程管理

    配置方法同 ,不再赘述。

    4. 验证安装是否成功

    重启 Resin 服务器,观察启动日志中是否出现 OpenRASP Engine Initialized 字样,出现则说明安装成功;或者访问一下服务器,检查是否存在 X-Protected-By: OpenRASP 响应头,存在即表示安装成功。

    Splunk

    本文介绍如何通过 Syslog TCP 方式,将日志采集到 Splunk 平台。

    hashtag
    添加日志类型

    在开始之前,我们需要先添加 openrasp 日志类型,否则 Splunk 无法组装超过1KB的日志。

    hashtag
    方法1 - 手动添加

    创建或者编辑 ,添加如下内容,并重启 Splunk 服务器以生效:

    上述配置添加了一个名为 openrasp 的日志类型,格式为 JSON,单行最大长度 320000 字符,足够使用了。

    hashtag
    方法2 - 安装插件

    首先在这里下载控制台插件,安装此插件会自动创建 openrasp 日志类型:

    然后在 Splunk 首页左上角,点击 App -> Manage Apps -> Install app from file,点击浏览文件,选中刚才下载的插件,然后勾选 Upgrade app. Checking this will overwrite the app if it already exists 选项,点击上传:

    安装成功后,会在首页看到 RASP 应用,

    应用界面如图

    hashtag
    配置 Splunk 端口监听

    在 Splunk 首页,点击右上角的 Settings -> DATA -> Data Inputs,然后选择 TCP 类型,并点击 NEW 进入配置界面。在这里,我们输入监听端口,即 514。

    选择日志类型时,依然是 openrasp。接着点击 Review,然后点击 Submit 保存即可。

    当服务器收到日志,就可以在界面上查看了

    其他端口也是可以的,但协议只能是 TCP 类型。

    hashtag
    配置 OpenRASP

    如果是单机版,请根据 的说明,配置至少如下两项:

    • syslog.enable=true

    • syslog.url=tcp://X.X.X.X:514

    修改后应用重启服务器生效。

    如果开启了管理后台,定位到 系统设置 -> 报警设置 -> Syslog 报警设置,在界面上配置即可。

    hashtag
    开启邮件报警

    首先点击右上角 设置 -> 系统 -> 服务器设置 -> 电子邮件设置,输入邮件服务器和账号信息,

    设置好上面邮箱信息后,可定期搜索报警,并通过邮件方式通知。

    打开 Splunk -> 搜索 -> 设置搜索语句 -> 另存为 -> 告警

    hashtag
    已知问题

    hashtag
    1. Syslog UDP 方式日志截断问题

    如果你使用 Syslog UDP 方式采集日志,那么单条日志长度将被限制为 1KB。由于我们的报警日志通常在 2~3 KB,所以会导致报警日志截断

    hashtag
    2. 界面上看不到日志

    请按照如下步骤进行排查

    1. OpenRASP 是否产生报警日志?

      • 检查 <app_home>/rasp/logs/alarm.log 是否有报警?

    2. OpenRASP 是否将日志发给 Syslog 服务器?

    Spring Boot 框架

    我们支持 war 包、jar 包两种部署模式。如果是 war 包的形式,直接参考相应服务器文档即可;如果是内嵌服务器的 jar 包形式,请参考本文档安装。对于 WebGoat 项目,对应的 jar 包通常为 webgoat-XXX.jar。

    hashtag
    半自动安装

    从 v1.2.0 版本开始,我们加入了 SpringBoot 半自动安装支持。之前的版本请参考手动安装章节。

    1. 安装软件

    SpringBoot 没有提供通用的启动脚本,所以我们的半自动安装程序只会释放文件。在解压缩后,首先进入到解压后的目录中,e.g rasp-20181221

    如果你要开启远程管理,请先参考 文档,找到 app_id/app_secret/backend_url 三个关键参数,然后执行如下命令,

    如果你只是运行单机版,只需要指定 -install 参数,

    这里的 <spring_boot_folder> 通常是 XXX.jar 包所在的目录。具体 jar 的名字请咨询业务线。

    2. 配置启动参数

    假设 spring_boot_folder 目录为 /opt/spring-boot/。

    修改 SpringBoot 启动参数,增加 -javaagent 绝对路径参数(注意将 -jar 放到命令最末尾),e.g

    如果JDK版本为6-8,那么启动参数如下配置

    如果JDK版本为11,那么启动参数如下配置

    3. 检查安装是否成功

    访问服务器,检查是否存在 X-Protected-By: OpenRASP 响应头即可。

    hashtag
    手动安装

    1. 安装软件

    进入到 Spring Boot 所在目录,通常是 jar 所在的目录,e.g /opt/spring-boot

    复制安装包内的 rasp 目录到当前目录,

    OpenRASP 需要在 rasp 目录下释放一些动态链接库,所以还需要修改 rasp 目录的权限,e.g

    2. 开启远程管理

    配置方法同 ,不再赘述。

    3. 配置启动参数

    假设 rasp 目录释放到了 /opt/spring-boot/rasp/。

    修改 SpringBoot 启动参数,增加 -javaagent 绝对路径参数(注意将 -jar 放到命令最末尾),e.g

    如果JDK版本为6-8,那么启动参数如下配置

    如果JDK版本为11,那么启动参数如下配置

    4. 检查安装是否成功

    访问服务器,检查是否存在 X-Protected-By: OpenRASP 响应头即可。

    安装测试用例

    为了验证OpenRASP的漏洞检测效果,或者IAST工具的漏洞检测能力,我们提供了多个测试用例,覆盖常见高危漏洞。测试用例的部署也非常简单,复制到 webroot/webapps 目录即可。

    hashtag
    下载测试用例

    常用镜像:

    普元PAS服务器

    hashtag
    手动安装

    hashtag
    1. 安装软件

    复制安装包内的 rasp 目录到 PAS 安装目录,比如

    IAST 高级配置选项

    hashtag
    启动参数

    hashtag
    指定其他配置文件

    在配置阶段,可以使用 -o

    Logstash

    本文讲解如何使用 Logstash 采集报警日志,并发送到 ElasticSearch 保存。

    hashtag
    开始之前

    在开始之前,你需要知道如下信息:

    • ElasticSearch 相关信息

    安装灰盒扫描工具

    openrasp-iast 是一款灰盒扫描工具,能够结合应用内部hook点信息精确的检测漏洞。传统黑盒扫描器依赖于页面响应检测漏洞,不但需要发送大量的请求,还有误报的可能。对于SSRF、文件上传等漏洞,在页面没有回显、主机没有外网权限的情况下,还可能会漏报。openrasp-iast 很好的解决了上述问题,下面我们来看下如何安装它。

    另外,IAST 污点追踪功能已经在开发中,将会跟随商业版本发布。若要了解当前的系统架构,请参考 文档。

    hashtag
    快速体验

    我们提供了一整套的测试环境,包含 IAST 扫描器、OpenRASP 管理后台

    SIEM 系统集成

    无论是自研的,开源的还是商业SIEM产品,OpenRASP 都可以无缝集成。

    hashtag
    Kafka 日志推送

    从 v1.3 开始,管理后台支持直接将报警日志写入 Kafka。为了方便你测试,我们还支持推送测试报警。

    hashtag

    chmod 777 -R /opt/bes/rasp
    -javaagent:${BES_HOME}\rasp\rasp.jar
    -javaagent:${BES_HOME}/rasp/rasp.jar
    <jvm-options>-javaagent:/opt/bes/rasp/rasp.jar</jvm-options>
    chmod 777 -R /opt/IBM/WebSphere/AppServer/rasp
    -javaagent:${WAS_INSTALL_ROOT}\rasp\rasp.jar
    -javaagent:${WAS_INSTALL_ROOT}/rasp/rasp.jar
    ************ Start Display Current Environment ************
    Log file started at: [18-11-13 20:10:08:993 CST]
    ************* End Display Current Environment *************
    Exception in thread "Thread-8" java.security.AccessControlException: Access denied (java.lang.RuntimePermission accessDeclaredMembers)
    	at java.security.AccessController.checkPermission(AccessController.java:132)
    	at java.lang.SecurityManager.checkPermission(SecurityManager.java:544)
    	at java.lang.SecurityManager.checkMemberAccess(SecurityManager.java:1689)
    	at java.lang.Class.checkMemberAccess(Class.java:117)
    	at java.lang.Class.getDeclaredConstructor(Class.java:465)
    	at com.baidu.openrasp.gson.internal.ConstructorConstructor.newDefaultConstructor(ConstructorConstructor.java:82)
    	at com.baidu.openrasp.gson.internal.ConstructorConstructor.get(ConstructorConstructor.java:66)
    	at com.baidu.openrasp.gson.internal.bind.MapTypeAdapterFactory.create(MapTypeAdapterFactory.java:128)
    	at com.baidu.openrasp.gson.Gson.getAdapter(Gson.java:349)
    	at com.baidu.openrasp.gson.Gson.toJson(Gson.java:574)
    	at com.baidu.openrasp.gson.Gson.toJson(Gson.java:561)
    	at com.baidu.openrasp.gson.Gson.toJson(Gson.java:516)
    	at com.baidu.openrasp.gson.Gson.toJson(Gson.java:496)
    	at com.baidu.openrasp.cloud.Register$RegisterThread.run(Register.java:50)
    	at java.lang.Thread.run(Thread.java:773)
    grant codeBase "file:${was.install.root}/rasp/*" {
        permission java.security.AllPermission;
    };
    chmod 777 -R /opt/tongweb安装目录/rasp
    -javaagent:${TongWeb_Home}/rasp/rasp.jar
    -javaagent:${TongWeb_Home}/rasp/rasp.jar
    chmod 777 -R /opt/inforsuiteas/rasp
    -javaagent:${com.cvicse.loong.las.installRoot}\rasp\rasp.jar
    -javaagent:${com.cvicse.loong.las.installRoot}/rasp/rasp.jar
    <jvm-options>-javaagent:${com.cvicse.loong.las.installRoot}/rasp/rasp.jar</jvm-options>
    java -jar RaspInstall.jar -install <resin_root> -backendurl http://XXX -appsecret XXX -appid XXX
    java -jar RaspInstall.jar -install <resin_root>