JAVA Ping命令心跳探测 InetAddress isRe

2020-01-12  本文已影响0人  ShootHzj

业务需求

当业务上需要使用ping命令对主机进行心跳探测时,首先想到的是利用代码fork进程执行ping命令,如果自己实现,代码量大,处理流容易出错,和使用标准库比起来相当不优雅.于是查阅了一下资料

按资料上的说法,java的InetAddress的isReachable方法在root用户下使用ping命令探测,非root用户下使用端口7探测

书写了demo代码进行了测试,demo地址https://github.com/Shoothzj/heart-beat

package com.github.shoothzj.heartbeat.ping.test;

import lombok.extern.slf4j.Slf4j;

import java.net.InetAddress;

/**
 * @author hezhangjian
 */
@Slf4j
public class PingTestMain {

    public static void main(String[] args) throws Exception {
        String testIp = System.getProperty("TestIp");
        InetAddress inetAddress = InetAddress.getByName(testIp);
        boolean addressReachable = inetAddress.isReachable(500);
        log.info("address is reachable is {}", addressReachable);
    }

}

测试场景

root用户下执行程序

image.png

java程序打印结果也是true

切换到普通用户执行程序

image.png

此时可以看到,我们的客户端程序向目标tcp7端口发送了一个报文,虽然java程序打印结果为true,但是因为收到了RST包导致的.在当今的网络安全要求下,7端口往往不会开放

屏蔽目标网络的7端口执行程序

iptables -A INPUT -p tcp --dport 7 -j DROP

发送的报文没有收到RST包,此时java程序返回false.不是我们预期的结果

普通用户携带特权

通过查阅资料,发现java发送ping命令,需要创建raw socket

只有root权限或者拥有cap_net_raw权限才可以创建raw socket,所以我们赋予java程序创建raw socket的权限再次尝试

setcap cap_net_raw+ep /usr/java/jdk-13.0.1/bin/java

发现如下报错

java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory

使用https://askubuntu.com/questions/334365/how-to-add-a-directory-to-linker-command-line-in-linux规避添加so文件权限

随后抓包,发现还是发送了ping命令,达到了我们预期的效果

总结

root用户会使用ping命令探测. 如果普通用户不携带特权会探测tcp7端口,如果7端口安全组不开启会与预期结果不一致,推荐赋予java程序特权,就会使用ping命令探测

上一篇 下一篇

猜你喜欢

热点阅读