Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[collector] support linux ssh private key #745

Merged
merged 3 commits into from
Mar 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,12 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.ConnectException;
import java.security.KeyPair;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -250,8 +254,8 @@ private ClientSession getConnectSession(SshProtocol sshProtocol, int timeout) th
.verify(timeout, TimeUnit.MILLISECONDS).getSession();
if (StringUtils.hasText(sshProtocol.getPassword())) {
clientSession.addPasswordIdentity(sshProtocol.getPassword());
} else if (StringUtils.hasText(sshProtocol.getPublicKey())) {
KeyPair keyPair = KeyPairUtil.getKeyPairFromPublicKey(sshProtocol.getPublicKey());
} else if (StringUtils.hasText(sshProtocol.getPrivateKey())) {
var keyPair = KeyPairUtil.getKeyPairFromPrivateKey(sshProtocol.getPrivateKey());
if (keyPair != null) {
clientSession.addPublicKeyIdentity(keyPair);
}
Expand Down
34 changes: 19 additions & 15 deletions collector/src/main/java/com/usthe/collector/util/KeyPairUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,30 @@

package com.usthe.collector.util;

import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.security.KeyFactory;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.security.KeyPair;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.security.KeyPairGenerator;

/**
* 密钥工具类
*
* @author tom
* @date 2022/4/2 17:04
*/
@Slf4j
@UtilityClass
public class KeyPairUtil {

private static KeyFactory keyFactory;
private static KeyPairGenerator keyPairGenerator;

static {
try {
keyFactory = KeyFactory.getInstance("RSA");
keyPairGenerator = KeyPairGenerator.getInstance("RSA");
} catch (Exception e) {
log.error(e.getMessage(), e);
}
Expand All @@ -46,16 +49,17 @@ public class KeyPairUtil {
/**
* 获取密钥对
*/
public static KeyPair getKeyPairFromPublicKey(String publicKeyStr) {
public static KeyPair getKeyPairFromPrivateKey(String privateKeyStr) {
if (!StringUtils.hasText(privateKeyStr)) {
return null;
}
try {
if (publicKeyStr == null || "".equals(publicKeyStr)) {
return null;
}
// todo fix 公钥解析
byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyStr);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return new KeyPair(publicKey, null);
var keyPair = keyPairGenerator.generateKeyPair();
var stream = new ByteArrayOutputStream();
stream.write(privateKeyStr.getBytes());
var oos = new ObjectOutputStream(stream);
oos.writeObject(keyPair);
return keyPair;
} catch (Exception e) {
log.info("[keyPair] parse failed, {}." + e.getMessage());
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
import java.security.PublicKey;
import java.security.SecureRandom;

import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;

/**
* Test case for {@link KeyPairUtil}
Expand All @@ -23,28 +24,28 @@ void setUp() {
@Test
void getKeyPairFromPublicKey() {
// test null key
KeyPair nullKey = KeyPairUtil.getKeyPairFromPublicKey(null);
KeyPair nullKey = KeyPairUtil.getKeyPairFromPrivateKey(null);
assertNull(nullKey);
// test empty key
KeyPair emptyKey = KeyPairUtil.getKeyPairFromPublicKey("");
KeyPair emptyKey = KeyPairUtil.getKeyPairFromPrivateKey("");
assertNull(emptyKey);
// test illegal key: DSA
String dsaPublicKey = new String(Base64.encodeBase64(genPublicKey("DSA").getEncoded()));
KeyPair illegalKey = KeyPairUtil.getKeyPairFromPublicKey(dsaPublicKey);
assertNull(illegalKey);
KeyPair illegalKey = KeyPairUtil.getKeyPairFromPrivateKey(dsaPublicKey);
assertNotNull(illegalKey);
// test illegal key: DiffieHellman
String diffieHellmanPublicKey = new String(Base64.encodeBase64(genPublicKey("DiffieHellman").getEncoded()));
illegalKey = KeyPairUtil.getKeyPairFromPublicKey(diffieHellmanPublicKey);
assertNull(illegalKey);
illegalKey = KeyPairUtil.getKeyPairFromPrivateKey(diffieHellmanPublicKey);
assertNotNull(illegalKey);
// test not encrypted
byte[] rsaBytes = genPublicKey("RSA").getEncoded();
String rawRsaPublicKey = new String(rsaBytes);
KeyPair raw = KeyPairUtil.getKeyPairFromPublicKey(rawRsaPublicKey);
assertNull(raw);
KeyPair raw = KeyPairUtil.getKeyPairFromPrivateKey(rawRsaPublicKey);
assertNotNull(raw);
// test normal case
// base64 encrypted
String rsaPublicKey = new String(Base64.encodeBase64(rsaBytes));
KeyPair normal = KeyPairUtil.getKeyPairFromPublicKey(rsaPublicKey);
KeyPair normal = KeyPairUtil.getKeyPairFromPrivateKey(rsaPublicKey);
assertNotNull(normal);
assertNotNull(normal.getPublic());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

/**
* ssh 协议参数配置
*
* @author tom
* @date 2022/3/11 15:20
*/
Expand Down Expand Up @@ -59,9 +60,9 @@ public class SshProtocol {
private String password;

/**
* 公钥(可选)
* 私钥(可选)
*/
private String publicKey;
private String privateKey;

/**
* SSH执行脚本
Expand Down
17 changes: 16 additions & 1 deletion manager/src/main/resources/define/app-centos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ params:
en-US: Password
type: password
required: false
- field: privateKey
name:
zh-CN: 私钥
en-US: PrivateKey
type: textarea
required: false
hide: true
# 指标组列表
metrics:
# 第一个监控指标组 basic
Expand Down Expand Up @@ -84,6 +91,7 @@ metrics:
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
privateKey: ^_^privateKey^_^
timeout: ^_^timeout^_^
script: (uname -r ; hostname ; uptime | awk -F "," '{print $1}' | sed "s/ //g") | sed ":a;N;s/\n/^/g;ta" | awk -F '^' 'BEGIN{print "version hostname uptime"} {print $1, $2, $3}'
# 响应数据解析方式:oneRow, multiRow
Expand Down Expand Up @@ -136,6 +144,7 @@ metrics:
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
privateKey: ^_^privateKey^_^
timeout: ^_^timeout^_^
script: "LANG=C lscpu | awk -F: '/Model name/ {print $2}' | awk 'NR==1';awk '/processor/{core++} END{print core}' /proc/cpuinfo;uptime | sed 's/,/ /g' | awk '{for(i=NF-2;i<=NF;i++)print $i }' | xargs;vmstat 1 1 | awk 'NR==3{print $11}';vmstat 1 1 | awk 'NR==3{print $12}';vmstat 1 2 | awk 'NR==4{print $15}'"
parseType: oneRow
Expand Down Expand Up @@ -188,6 +197,7 @@ metrics:
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
privateKey: ^_^privateKey^_^
timeout: ^_^timeout^_^
script: free -m | awk 'BEGIN{print "total used free buff_cache available"} NR==2{print $2,$3,$4,$6,$7}'
parseType: multiRow
Expand Down Expand Up @@ -221,6 +231,7 @@ metrics:
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
privateKey: ^_^privateKey^_^
timeout: ^_^timeout^_^
script: vmstat -D | awk 'NR==1{print $1}';vmstat -D | awk 'NR==2{print $1}';vmstat 1 1 | awk 'NR==3{print $10}';vmstat 1 1 | awk 'NR==3{print $9}';vmstat 1 1 | awk 'NR==3{print $16}'
parseType: oneRow
Expand Down Expand Up @@ -248,6 +259,7 @@ metrics:
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
privateKey: ^_^privateKey^_^
timeout: ^_^timeout^_^
script: cat /proc/net/dev | tail -n +3 | awk 'BEGIN{ print "interface_name receive_bytes transmit_bytes"} {print $1,$2,$10}'
parseType: multiRow
Expand Down Expand Up @@ -280,6 +292,7 @@ metrics:
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
privateKey: ^_^privateKey^_^
timeout: ^_^timeout^_^
script: df -m | tail -n +2 | awk 'BEGIN{ print "filesystem used available usage mounted"} {print $1,$3,$4,$5,$6}'
parseType: multiRow
Expand Down Expand Up @@ -309,6 +322,7 @@ metrics:
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
privateKey: ^_^privateKey^_^
timeout: ^_^timeout^_^
script: ps -aux | sort -k3nr | awk 'BEGIN{ print "pid cpu_usage mem_usage command" } {print $2, $3, $4, $11}'| head -n 10
parseType: multiRow
Expand Down Expand Up @@ -338,6 +352,7 @@ metrics:
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
privateKey: ^_^privateKey^_^
timeout: ^_^timeout^_^
script: ps -aux | sort -k4nr | awk 'BEGIN{ print "pid cpu_usage mem_usage command" } {print $2, $3, $4, $11}'| head -n 10
parseType: multiRow
parseType: multiRow
25 changes: 20 additions & 5 deletions manager/src/main/resources/define/app-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,16 @@ params:
en-US: Password
type: password
required: false
- field: privateKey
name:
zh-CN: 私钥
en-US: PrivateKey
type: textarea
required: false
hide: true
metrics:
# 第一个监控指标组 basic
# 注意:内置监控指标有 (responseTime - 响应时间)
# 第一个监控指标组 basic
# 注意:内置监控指标有 (responseTime - 响应时间)
- name: basic
# 指标组调度优先级(0-127)越小优先级越高,优先级低的指标组会等优先级高的指标组采集完成后才会被调度,相同优先级的指标组会并行调度采集
# 优先级为0的指标组为可用性指标组,即它会被首先调度,采集成功才会继续调度其它指标组,采集失败则中断调度
Expand All @@ -72,16 +79,17 @@ metrics:
type: 1
- field: uptime
type: 1
# 监控采集使用协议 eg: sql, ssh, http, telnet, wmi, snmp, sdk
# 监控采集使用协议 eg: sql, ssh, http, telnet, wmi, snmp, sdk
protocol: ssh
# 当protocol为http协议时具体的采集配置
# 当protocol为http协议时具体的采集配置
ssh:
# 主机host: ipv4 ipv6 域名
host: ^_^host^_^
# 端口
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
privateKey: ^_^privateKey^_^
timeout: ^_^timeout^_^
script: (uname -r ; hostname ; uptime | awk -F "," '{print $1}' | sed "s/ //g") | sed ":a;N;s/\n/^/g;ta" | awk -F '^' 'BEGIN{print "version hostname uptime"} {print $1, $2, $3}'
# 响应数据解析方式:oneRow, multiRow
Expand Down Expand Up @@ -134,6 +142,7 @@ metrics:
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
privateKey: ^_^privateKey^_^
timeout: ^_^timeout^_^
script: "LANG=C lscpu | awk -F: '$1==\"Model name\" {print $2}';awk '/processor/{core++} END{print core}' /proc/cpuinfo;uptime | sed 's/,/ /g' | awk '{for(i=NF-2;i<=NF;i++)print $i }' | xargs;vmstat 1 1 | awk 'NR==3{print $11}';vmstat 1 1 | awk 'NR==3{print $12}';vmstat 1 2 | awk 'NR==4{print $15}'"
parseType: oneRow
Expand Down Expand Up @@ -186,6 +195,7 @@ metrics:
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
privateKey: ^_^privateKey^_^
timeout: ^_^timeout^_^
script: free -m | awk 'BEGIN{print "total used free buff_cache available"} NR==2{print $2,$3,$4,$6,$7}'
parseType: multiRow
Expand Down Expand Up @@ -219,6 +229,7 @@ metrics:
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
privateKey: ^_^privateKey^_^
timeout: ^_^timeout^_^
script: vmstat -D | awk 'NR==1{print $1}';vmstat -D | awk 'NR==2{print $1}';vmstat 1 1 | awk 'NR==3{print $10}';vmstat 1 1 | awk 'NR==3{print $9}';vmstat 1 1 | awk 'NR==3{print $16}'
parseType: oneRow
Expand Down Expand Up @@ -246,6 +257,7 @@ metrics:
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
privateKey: ^_^privateKey^_^
timeout: ^_^timeout^_^
script: cat /proc/net/dev | tail -n +3 | awk 'BEGIN{ print "interface_name receive_bytes transmit_bytes"} {print $1,$2,$10}'
parseType: multiRow
Expand Down Expand Up @@ -278,6 +290,7 @@ metrics:
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
privateKey: ^_^privateKey^_^
timeout: ^_^timeout^_^
script: df -m | tail -n +2 | awk 'BEGIN{ print "filesystem used available usage mounted"} {print $1,$3,$4,$5,$6}'
parseType: multiRow
Expand Down Expand Up @@ -307,6 +320,7 @@ metrics:
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
privateKey: ^_^privateKey^_^
timeout: ^_^timeout^_^
script: ps -aux | sort -k3nr | awk 'BEGIN{ print "pid cpu_usage mem_usage command" } {print $2, $3, $4, $11}'| head -n 10
parseType: multiRow
Expand Down Expand Up @@ -336,6 +350,7 @@ metrics:
port: ^_^port^_^
username: ^_^username^_^
password: ^_^password^_^
privateKey: ^_^privateKey^_^
timeout: ^_^timeout^_^
script: ps -aux | sort -k4nr | awk 'BEGIN{ print "pid cpu_usage mem_usage command" } {print $2, $3, $4, $11}'| head -n 10
parseType: multiRow
parseType: multiRow
Loading