V1.5.0 Integrate JMX Tech for future development

master
Ng Yat Yan 2 weeks ago
parent 2e98db494e
commit 9b10cbe9b7

@ -2,12 +2,10 @@
PID=`ps -ef | grep echo-sshd-server.jar | grep -v grep | awk '{print $2}'` PID=`ps -ef | grep echo-sshd-server.jar | grep -v grep | awk '{print $2}'`
if [ -z "$PID" ] if [ -z "$PID" ]
then then
nohup authbind /opt/jdk-17/bin/java -jar echo-sshd-server.jar conf > logs/exec.log 2>&1 & nohup authbind /opt/graalvm-jdk-17/bin/java -Dcom.sun.management.jmxremote -Djava.rmi.server.hostname=127.0.0.1 -Dcom.sun.management.jmxremote.port=2020 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -jar echo-sshd-server.jar conf > logs/exec.log 2>&1 &
sleep 1 sleep 1
PID=`ps -ef | grep echo-sshd-server.jar | grep -v grep | awk '{print $2}'` PID=`ps -ef | grep echo-sshd-server.jar | grep -v grep | awk '{print $2}'`
echo "started echo-sshd-server.jar pid: $PID" echo "started echo-sshd-server.jar pid: $PID"
else else
echo "already exist echo-sshd-server.jar pid: $PID" echo "already exist echo-sshd-server.jar pid: $PID"
fi fi

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.example.sshd</groupId> <groupId>com.example.sshd</groupId>
<artifactId>echo-sshd-server</artifactId> <artifactId>echo-sshd-server</artifactId>
<version>1.4.6</version> <version>1.5.0</version>
<name>ECHO SSH SERVER</name> <name>ECHO SSH SERVER</name>
<description>Learning Apache Mina SSHD library</description> <description>Learning Apache Mina SSHD library</description>
<parent> <parent>

@ -0,0 +1,87 @@
package com.example.sshd.service;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javax.management.Attribute;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.openmbean.CompositeData;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@Service
public class JmxClientService {
private static final Logger logger = LoggerFactory.getLogger(ReplyService.class);
public String process(String[] args) {
// Example
// 1st parameter: service:jmx:rmi:///jndi/rmi://127.0.0.1:2020/jmxrmi
// 2nd parameter: java.lang:type=Memory
StringBuilder output = new StringBuilder();
try {
if (args.length > 2) {
Runtime.getRuntime().freeMemory();
System.out.println("Connection to JMX kafka...");
JMXServiceURL url = new JMXServiceURL(args[1]);
JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
ObjectName mbeanName = new ObjectName(args[2]);
MBeanInfo info = mbsc.getMBeanInfo(mbeanName);
MBeanAttributeInfo[] attribute = info.getAttributes();
logger.info("[process] args.length: {}", args.length);
if (args.length > 3) {
for (MBeanAttributeInfo attr : attribute) {
List<Attribute> alist = mbsc.getAttributes(mbeanName, new String[] { attr.getName() }).asList();
if (args[3].equals(attr.getName())) {
Optional<Map<String, Object>> opt = alist.stream().filter(a -> a.getName().equals(args[3]))
.map(a -> toMap((CompositeData) a.getValue())).findFirst();
if (opt.isPresent()) {
output.append(attr.getName() + ": " + opt.get() + "\r\n");
}
}
}
} else {
for (MBeanAttributeInfo attr : attribute) {
List<Attribute> alist = mbsc.getAttributes(mbeanName, new String[] { attr.getName() }).asList();
output.append(attr.getName() + ": " + alist + "\r\n");
}
}
jmxc.close();
} else {
output.append("Example: jmx_client service:jmx:rmi:///jndi/rmi://127.0.0.1:2020/jmxrmi java.lang:type=Memory HeapMemoryUsage\r\n");
}
} catch (Exception e) {
logger.error("process cmd failed: {}", Arrays.asList(args), e);
}
return output.toString();
}
public static Map<String, Object> toMap(CompositeData cd) {
if (cd == null)
throw new IllegalArgumentException("composite data should not be null");
Map<String, Object> map = new HashMap<String, Object>();
Set<String> itemNames = cd.getCompositeType().keySet();
for (String itemName : itemNames) {
Object item = cd.get(itemName);
map.put(itemName, item);
}
return map;
}
}

@ -43,6 +43,9 @@ public class ReplyService {
@Autowired @Autowired
GeoIpLocator geoIpLocator; GeoIpLocator geoIpLocator;
@Autowired
JmxClientService jmxClientService;
public boolean replyToCommand(String command, OutputStream out, String prompt, ServerSession session) public boolean replyToCommand(String command, OutputStream out, String prompt, ServerSession session)
throws IOException { throws IOException {
@ -51,12 +54,20 @@ public class ReplyService {
logger.info("[{}] my_geolocation command detected: {}", cmdHash, command.trim()); logger.info("[{}] my_geolocation command detected: {}", cmdHash, command.trim());
out.write(String.format("\r\n%s\r\n%s", ipInfoMapping.get(Thread.currentThread().getName()), prompt) out.write(String.format("\r\n%s\r\n%s", ipInfoMapping.get(Thread.currentThread().getName()), prompt)
.getBytes()); .getBytes());
} else if (StringUtils.equalsIgnoreCase(command.trim(), "whoami")) { } else if (StringUtils.equalsIgnoreCase(command.trim(), "whoami")) {
logger.info("[{}] whoami command detected: {}", cmdHash, command.trim()); logger.info("[{}] whoami command detected: {}", cmdHash, command.trim());
out.write(String.format("\r\n%s\r\n%s", session.getUsername(), prompt).getBytes()); out.write(String.format("\r\n%s\r\n%s", session.getUsername(), prompt).getBytes());
} else if (StringUtils.equalsIgnoreCase(command.trim(), "online_geolocations")) { } else if (StringUtils.equalsIgnoreCase(command.trim(), "online_geolocations")) {
logger.info("[{}] online_geolocations command detected: {}", cmdHash, command.trim()); logger.info("[{}] online_geolocations command detected: {}", cmdHash, command.trim());
out.write(String.format("\r\n%s\r\n%s", ipInfoMapping.toString(), prompt).getBytes()); out.write(String.format("\r\n%s\r\n%s", ipInfoMapping.toString(), prompt).getBytes());
} else if (StringUtils.equalsIgnoreCase(StringUtils.split(command.trim(), " ")[0], "jmx_client")) {
String remoteJmxResponse = jmxClientService.process(StringUtils.split(command.trim(), " "));
logger.info("[{}] jmx_client command detected: {}", cmdHash, command.trim());
out.write(String.format("\r\n%s\r\n%s", remoteJmxResponse, prompt).getBytes());
} else if (StringUtils.split(command.trim(), " ").length == 2 } else if (StringUtils.split(command.trim(), " ").length == 2
&& StringUtils.equalsIgnoreCase(StringUtils.split(command.trim(), " ")[0], "get_geolocation")) { && StringUtils.equalsIgnoreCase(StringUtils.split(command.trim(), " ")[0], "get_geolocation")) {
String remoteIpInfo = StringUtils.getIfBlank( String remoteIpInfo = StringUtils.getIfBlank(
@ -64,29 +75,35 @@ public class ReplyService {
() -> geoIpLocator.getIpLocationInfo(StringUtils.split(command.trim(), " ")[1])); () -> geoIpLocator.getIpLocationInfo(StringUtils.split(command.trim(), " ")[1]));
logger.info("[{}] get_geolocation command detected: {}", cmdHash, command.trim()); logger.info("[{}] get_geolocation command detected: {}", cmdHash, command.trim());
out.write(String.format("\r\n%s\r\n%s", remoteIpInfo, prompt).getBytes()); out.write(String.format("\r\n%s\r\n%s", remoteIpInfo, prompt).getBytes());
} else if (StringUtils.equalsIgnoreCase(command.trim(), "all_geolocations")) { } else if (StringUtils.equalsIgnoreCase(command.trim(), "all_geolocations")) {
logger.info("[{}] all_geolocations command detected: {}", cmdHash, command.trim()); logger.info("[{}] all_geolocations command detected: {}", cmdHash, command.trim());
out.write(String.format("\r\n%s\r\n%s", jdbcService.getAllRemoteIpInfo(), prompt).getBytes()); out.write(String.format("\r\n%s\r\n%s", jdbcService.getAllRemoteIpInfo(), prompt).getBytes());
} else if (StringUtils.equalsIgnoreCase(command.trim(), "exit") } else if (StringUtils.equalsIgnoreCase(command.trim(), "exit")
|| StringUtils.equalsIgnoreCase(command.trim(), "quit")) { || StringUtils.equalsIgnoreCase(command.trim(), "quit")) {
logger.info("[{}] Exiting command detected: {}", cmdHash, command.trim()); logger.info("[{}] Exiting command detected: {}", cmdHash, command.trim());
out.write(String.format("\r\nExiting...\r\n%s", prompt).getBytes()); out.write(String.format("\r\nExiting...\r\n%s", prompt).getBytes());
return true; return true;
} else if (hashReplies.containsKey(command.trim())) { } else if (hashReplies.containsKey(command.trim())) {
logger.info("[{}] Known command detected: {}", cmdHash, command.trim()); logger.info("[{}] Known command detected: {}", cmdHash, command.trim());
String reply = hashReplies.getProperty(command.trim()).replace("\\r", "\r").replace("\\n", "\n") String reply = hashReplies.getProperty(command.trim()).replace("\\r", "\r").replace("\\n", "\n")
.replace("\\t", "\t"); .replace("\\t", "\t");
out.write(String.format("\r\n%s\r\n%s", reply, prompt).getBytes()); out.write(String.format("\r\n%s\r\n%s", reply, prompt).getBytes());
} else if (hashReplies.containsKey(cmdHash)) { } else if (hashReplies.containsKey(cmdHash)) {
logger.info("[{}] Known command-hash detected: {}", cmdHash, command.trim()); logger.info("[{}] Known command-hash detected: {}", cmdHash, command.trim());
String reply = hashReplies.getProperty(cmdHash).replace("\\r", "\r").replace("\\n", "\n").replace("\\t", String reply = hashReplies.getProperty(cmdHash).replace("\\r", "\r").replace("\\n", "\n").replace("\\t",
"\t"); "\t");
out.write(String.format("\r\n%s\r\n%s", reply, prompt).getBytes()); out.write(String.format("\r\n%s\r\n%s", reply, prompt).getBytes());
} else if (hashReplies.containsKey(String.format("base64(%s)", cmdHash))) { } else if (hashReplies.containsKey(String.format("base64(%s)", cmdHash))) {
logger.info("[{}] Known base64-hash detected: {}", cmdHash, command.trim()); logger.info("[{}] Known base64-hash detected: {}", cmdHash, command.trim());
String reply = hashReplies.getProperty(String.format("base64(%s)", cmdHash)); String reply = hashReplies.getProperty(String.format("base64(%s)", cmdHash));
reply = new String(Base64.decodeBase64(reply)); reply = new String(Base64.decodeBase64(reply));
out.write(String.format("\r\n%s\r\n%s", reply, prompt).getBytes()); out.write(String.format("\r\n%s\r\n%s", reply, prompt).getBytes());
} else { } else {
Optional<Pair<String, String>> o = regexMapping.entrySet().stream() Optional<Pair<String, String>> o = regexMapping.entrySet().stream()
.filter(e -> command.trim().matches(((String) e.getKey()))) .filter(e -> command.trim().matches(((String) e.getKey())))

Loading…
Cancel
Save