mirror of
https://github.com/LamGC/Oracle-Sentry.git
synced 2025-04-29 22:27:34 +00:00
feat(ssh): 支持设置首次连接认证策略.
支持更改首次连接认证策略, 以减少确认服务器密钥的工作量(尽管这可能导致后续连接不再安全).
This commit is contained in:
parent
dc9c349826
commit
a83c09a787
@ -7,6 +7,8 @@ import org.apache.sshd.client.session.ClientSession;
|
||||
import org.apache.sshd.common.config.keys.KeyUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.security.PublicKey;
|
||||
@ -19,6 +21,10 @@ public class OracleInstanceServerKeyVerifier implements ServerKeyVerifier {
|
||||
|
||||
private final static Logger log = LoggerFactory.getLogger(OracleInstanceServerKeyVerifier.class);
|
||||
|
||||
@Value("${oracle.ssh.firstConnection.authenticationPolicy}")
|
||||
@NonNull
|
||||
private static String firstConnectionPolicy;
|
||||
|
||||
private final ComputeInstance instance;
|
||||
private final SshAuthInfo info;
|
||||
|
||||
@ -34,7 +40,7 @@ public class OracleInstanceServerKeyVerifier implements ServerKeyVerifier {
|
||||
.verifyServerKey(clientSession, remoteAddress, serverKey);
|
||||
} else {
|
||||
log.warn("首次连接实例 SSH, 需要用户确认服务器公钥是否可信...");
|
||||
boolean result = confirm(remoteAddress, serverKey);
|
||||
boolean result = usePolicyConfirm(remoteAddress, serverKey);
|
||||
if (result) {
|
||||
log.info("用户已确认服务器密钥可信, 将该密钥列入该实例下的信任密钥.");
|
||||
info.setServerKey(serverKey);
|
||||
@ -46,12 +52,26 @@ public class OracleInstanceServerKeyVerifier implements ServerKeyVerifier {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean confirm(SocketAddress address, PublicKey key) {
|
||||
String fingerPrint = KeyUtils.getFingerPrint(key);
|
||||
log.warn("开始密钥认证流程... (InstanceId: {}, ServerAddress: {}, KeyFingerPrint: {})",
|
||||
instance.getInstanceId(), address, fingerPrint);
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
log.info("""
|
||||
private boolean usePolicyConfirm(SocketAddress address, PublicKey serverKey) {
|
||||
FirstConnectionPolicy policy;
|
||||
try {
|
||||
policy = FirstConnectionPolicy.valueOf(firstConnectionPolicy.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new IllegalArgumentException("Unsupported policy: " + firstConnectionPolicy);
|
||||
}
|
||||
return policy.confirmFunction.confirm(this.instance, address, serverKey);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private enum FirstConnectionPolicy {
|
||||
ACCEPT((instance, address, key) -> true),
|
||||
REJECT((instance, address, key) -> false),
|
||||
CONFIRM((instance, address, key) -> {
|
||||
String fingerPrint = KeyUtils.getFingerPrint(key);
|
||||
log.warn("开始密钥认证流程... (InstanceId: {}, ServerAddress: {}, KeyFingerPrint: {})",
|
||||
instance.getInstanceId(), address, fingerPrint);
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
log.info("""
|
||||
本次连接 SSH 为首次连接, 为确保 SSH 安全性,请通过可信渠道获取服务器密钥指纹, 并与下列指纹比对:
|
||||
实例 ID:{}
|
||||
实例名称:{}
|
||||
@ -62,18 +82,40 @@ public class OracleInstanceServerKeyVerifier implements ServerKeyVerifier {
|
||||
|
||||
以上密钥指纹是否与服务器密钥指纹相同?如果指纹相同,对该密钥可信,请输入“Yes”,否则输入任意内容拒绝连接。
|
||||
该密钥是否可信?(Yes/No):""",
|
||||
instance.getInstanceId(),
|
||||
instance.getInstanceName(),
|
||||
address,
|
||||
fingerPrint
|
||||
);
|
||||
instance.getInstanceId(),
|
||||
instance.getInstanceName(),
|
||||
address,
|
||||
fingerPrint
|
||||
);
|
||||
|
||||
do {
|
||||
if (scanner.hasNextLine()) {
|
||||
String input = scanner.nextLine();
|
||||
return "yes".trim().equalsIgnoreCase(input);
|
||||
}
|
||||
} while (true);
|
||||
});
|
||||
|
||||
private final PublicKeyConfirm confirmFunction;
|
||||
|
||||
|
||||
FirstConnectionPolicy(PublicKeyConfirm confirmFunction) {
|
||||
this.confirmFunction = confirmFunction;
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
private interface PublicKeyConfirm {
|
||||
|
||||
/**
|
||||
* 确认密钥.
|
||||
* @param instance 待认证的服务器所属计算实例.
|
||||
* @param address 远程地址.
|
||||
* @param serverKey 服务器密钥.
|
||||
* @return 如果通过, 返回 {@code true}.
|
||||
*/
|
||||
boolean confirm(ComputeInstance instance, SocketAddress address, PublicKey serverKey);
|
||||
|
||||
do {
|
||||
if (scanner.hasNextLine()) {
|
||||
String input = scanner.nextLine();
|
||||
return "yes".trim().equalsIgnoreCase(input);
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,8 +1,16 @@
|
||||
oracle:
|
||||
identity:
|
||||
# 身份配置文件的文件名匹配规则.
|
||||
pattern: '.+\.oracle\.ini$'
|
||||
location: "./identity/"
|
||||
# 身份配置文件夹路径.
|
||||
location: './identity/'
|
||||
script:
|
||||
location: "./scripts/"
|
||||
ssh:
|
||||
identityPath: "./config/ssh.config.json"
|
||||
# 脚本文件夹路径.
|
||||
location: './scripts/'
|
||||
ssh:
|
||||
# SSH 认证文件存储路径.
|
||||
identityPath: './config/ssh-auth.json'
|
||||
firstConnection:
|
||||
# 首次连接认证策略
|
||||
# 支持 inquiry(询问) accept(接受) reject(拒绝)
|
||||
authenticationPolicy: 'inquiry'
|
||||
|
Loading…
Reference in New Issue
Block a user