RASP研发踩坑之attach失败
1.创建一个简单的 Java Agent
主动发起 attach 代码
import com.sun.tools.attach.*;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
VirtualMachine vm = null;
try {
vm = VirtualMachine.attach("50447");
// 指定Java Agent的jar包路径
String agentPath = "../agent-1.0-SNAPSHOT-jar-with-dependencies.jar";
vm.loadAgent(agentPath, "agent test");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
vm.detach();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
一个简单的Java Agent 代码
下载下来之后执行 mvn clean package 打包
2.踩坑 /tmp目录下的 .java_pid 文件被删除之后,attach到目标Java 进程错误
1.问题背景
我们在一批次的主机上开启了RASP,灰度完成之后,发现其中有58台主机
Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding
2.初步思路
看上面的告警信息是目标 JVM 进程未响应 socket 连接,没有详细调查问题之前,我对此问题的初步想法(问题
1.attach失败异常在 rasp多个版本中都有出现,不仅仅在 rasp2.8.0,初步排查问题不在rasp2.8.0存在(也就是说不是2.8.0新特性导致 attach 失败)
2.attach 失败的主机总是出现在一些固定主机上(这点可以排除 rasp attach机制的问题,attach代码没毛病),可能与主机上的Java 服务有关
3.接上面的第2点,attach本质是与jvm进行socket通信,attach失败,可能是jvm无法响应到这个socket连接。(问题的
3.我想到了哪些可能会影响 attach?
1.jvm处于过载状态是否会响应socket通信;
2.使用 attach机制的工具还有 jmap,jstack,如果 rasp 不能 attach,这些工具应该也是不能 attach 成功的。
4.申请权限登陆目标主机,手动拉起 rasp
2020-04-10 11:49:51.478 Rasp-Server版本:2.8.0 开始尝试注入到进程pid:542 watcher.go:390:Run
2020-04-10 11:49:56.490 Rasp-Server版本:2.8.0 attach出错 watcher.go:350:Exec
2020-04-10 11:49:56.490 Rasp-Server版本:2.8.0 watcher运行失败:exit status 2 sandbox_process.go:130:func
attach 失败!!
查看 Java 服务的 CPU 和内存
PID USER %CPU %MEM COMMAND
542 sankuai 0.3 23.1 java
Java服务内存和 CPU 都属于正常状态,初步排除 "1.jvm处于过载状态是否会响应socket通信"这个原因
5. 我尝试 使用 jstack -l 542 ,也失败
[sankuai@set-gh-sec-mtscanner-filter-test02 ~]$ jstack 542
542: Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding
6. 但是Java进程重启之后,jstack 工具可以正常使用,rasp 也正常attach
7. 再次熟悉
链接博客的重点:.attach_pid
8. 删除 .java_pid 再次使用 jstack -l
[sankuai@set-yp-logan-open-web-test01 tmp]$ jstack -l 68546
68546: Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding
9.猜测
首次 attach到目标 JVM 后,.java_pid
10.验证
在开启进程出错的主机上,查询 Java 进程看 Djava.io.tmp=dir的目录下是否有 .java_pid
验证主机:set-yp-logan-open-web-test01
结果:没有 .java_pid 文件,符合预期。
11. 出错复现
第一步,启动 java 进程 ,使用jstack 或者 rasp 执行 attach
第二步,删除/tmp 下的 .java_pid
第二步,开启rasp 执行注入,出现attach进程出错。
12. 问题的解决思路
策略1:对于无法开启attach 的 Java 进程只能等待 Java 进程重启之后,生成新的 .java_pid
策略2:Djava.io.tmp 建议指定到 Java进程的运行目录,因为默认的/tmp 容易被清除掉
参考连接:
踩坑2 attach时携带的字符串长度有限制
问题
一般我们会在 attach 时给JVM 传递一些字符串信息,来辅助 Agent 的初始化
vm.loadAgent(agentPath, "agent test");
随着RASP各种需求的增加,需要给 Agent 传输的字符串变的越来越多
这是我们项目中要传递给 jvm 的参数(字符串的长度898):
agentTomcatRule=(DP Server 6|Apache Tomcat/6|Apache Tomcat/7|Apache Tomcat/8|Apache Tomcat/9|6|7|8|9)\..*, classTransLimit=12, confVersion=2.8.0.4_20200512_2, raspHome=/opt/meituan/apps/direwolf/plugin/1004, hookFileWrite=false, pid=30496, hookFileUpload=false, rsDegradeLimit=2, recordTimeSample=50000, offlineLogSize=50, bootClassPath=/opt/meituan/apps/direwolf/plugin/1004/lib/guava-20.0.0.jar:/opt/meituan/apps/direwolf/plugin/1004/lib/mygson-1.0.0.jar, hookFileUploadContent=false, maxFailSize=1, closeWaitTimeInSeconds=6, rsLimitDiskFree=10, agentJettyRule=(8\.1|8\.2|9\.2|9\.3|9\.4)\..*, debug=true, queueSize=500, enableHttpPara=true, rsLimitCpuPid=40, agentJdkRule=1\.(?:7|8)\..*, dumpDir=/tmp/rasp_dump, serverPID=30513, recordTimeThreshold=5, rsLimitMemPid=90, dumpClasses=false, rsCheckEnable=true, rsLimitMemTotal=95, enableHttpReq=true, rsCircuitBreakLimit=129600, agentLogLevel=DEBUG
经过测试,最大可以携带的字符串长度为:938
超过938时,报错如下:
java.io.IOException: Premature EOF
at sun.tools.attach.HotSpotVirtualMachine.readInt(HotSpotVirtualMachine.java:292)
at sun.tools.attach.BsdVirtualMachine.execute(BsdVirtualMachine.java:183)
at sun.tools.attach.HotSpotVirtualMachine.loadAgentLibrary(HotSpotVirtualMachine.java:58)
at sun.tools.attach.HotSpotVirtualMachine.loadAgentLibrary(HotSpotVirtualMachine.java:79)
at sun.tools.attach.HotSpotVirtualMachine.loadAgent(HotSpotVirtualMachine.java:103)
at Main.main(Main.java:23)
疑问
attach 携带的字符串没有超过 String类型的最大长度,为什么会报错呢?我想去看下Java源码?
未完....待续