mirror of
https://github.com/LamGC/Oracle-Sentry.git
synced 2025-04-29 14:17:34 +00:00
feat: 初步添加 SSH Forwarding 功能.
添加对 SSH 转发功能的支持, 脚本可通过 SSH 会话使用. 注意: 该功能尚未得到足够的测试, 使用时遇到问题请反馈.
This commit is contained in:
parent
3641593210
commit
13d90595b7
@ -107,6 +107,7 @@ class ApplicationInitiation {
|
||||
|
||||
@PostConstruct
|
||||
@Order(1)
|
||||
@SuppressWarnings({"MismatchedReadAndWriteOfArray", "RedundantOperationOnEmptyContainer"})
|
||||
private void initialEnvironment() throws IOException {
|
||||
String[] directors = new String[] {
|
||||
"./config",
|
||||
@ -115,7 +116,7 @@ class ApplicationInitiation {
|
||||
};
|
||||
|
||||
String[] files = new String[] {
|
||||
sshIdentityPath
|
||||
|
||||
};
|
||||
|
||||
for (String directory : directors) {
|
||||
|
@ -1,5 +1,7 @@
|
||||
package net.lamgc.oracle.sentry;
|
||||
|
||||
import net.lamgc.oracle.sentry.oci.compute.ssh.ConfiguredForwardingFilter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
@ -23,6 +25,8 @@ public final class Constants {
|
||||
@NonNull
|
||||
private String firstConnectionPolicy;
|
||||
|
||||
@Autowired
|
||||
private ConfiguredForwardingFilter forwardingFilter;
|
||||
|
||||
/**
|
||||
* 获取 SSH 首次连接策略.
|
||||
@ -32,4 +36,12 @@ public final class Constants {
|
||||
public String getFirstConnectionPolicy() {
|
||||
return firstConnectionPolicy;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取已配置的转发过滤器.
|
||||
* @return 返回转发过滤器.
|
||||
*/
|
||||
public ConfiguredForwardingFilter getForwardingFilter() {
|
||||
return forwardingFilter;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,45 @@
|
||||
package net.lamgc.oracle.sentry.oci.compute.ssh;
|
||||
|
||||
import org.apache.sshd.common.session.Session;
|
||||
import org.apache.sshd.common.util.net.SshdSocketAddress;
|
||||
import org.apache.sshd.server.forward.ForwardingFilter;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 已配置转发过滤器.
|
||||
* <p> 根据应用配置, 选择是否允许转发指定类型的流量.
|
||||
* @author LamGC
|
||||
*/
|
||||
@Component("sentry.script.ssh.forwarding.filter")
|
||||
public class ConfiguredForwardingFilter implements ForwardingFilter {
|
||||
|
||||
@Value("oracle.ssh.forwarding.X11.enable")
|
||||
private String x11Enabled;
|
||||
|
||||
@Value("oracle.ssh.forwarding.tcp.enable")
|
||||
private String tcpEnabled;
|
||||
|
||||
@Value("oracle.ssh.forwarding.agent.enable")
|
||||
private String agentEnabled;
|
||||
|
||||
@Override
|
||||
public boolean canForwardAgent(Session session, String requestType) {
|
||||
return Boolean.parseBoolean(agentEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canListen(SshdSocketAddress address, Session session) {
|
||||
return Boolean.parseBoolean(tcpEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canConnect(Type type, SshdSocketAddress address, Session session) {
|
||||
return Boolean.parseBoolean(tcpEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canForwardX11(Session session, String requestType) {
|
||||
return Boolean.parseBoolean(x11Enabled);
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package net.lamgc.oracle.sentry.oci.compute.ssh;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import net.lamgc.oracle.sentry.Constants;
|
||||
import net.lamgc.oracle.sentry.oci.compute.ComputeInstance;
|
||||
import org.apache.sshd.client.SshClient;
|
||||
import org.apache.sshd.client.future.AuthFuture;
|
||||
@ -40,6 +41,7 @@ public class InstanceSsh implements AutoCloseable {
|
||||
this.authInfo = Objects.requireNonNull(authInfo);
|
||||
|
||||
sshClient = SshClient.setUpDefaultClient();
|
||||
sshClient.setForwardingFilter(Constants.instance.getForwardingFilter());
|
||||
sshClient.setServerKeyVerifier(new OracleInstanceServerKeyVerifier(instance, authInfo));
|
||||
if (authInfo instanceof PublicKeyAuthInfo info) {
|
||||
sshClient.setKeyIdentityProvider(new FileKeyPairProvider(info.getPrivateKeyPath().toPath()));
|
||||
|
@ -1,6 +1,8 @@
|
||||
package net.lamgc.oracle.sentry.oci.compute.ssh;
|
||||
|
||||
import org.apache.sshd.client.session.ClientSession;
|
||||
import org.apache.sshd.client.session.forward.ExplicitPortForwardingTracker;
|
||||
import org.apache.sshd.common.util.net.SshdSocketAddress;
|
||||
import org.apache.sshd.sftp.client.SftpClientFactory;
|
||||
|
||||
import java.io.Closeable;
|
||||
@ -45,6 +47,31 @@ public class SshSession implements Closeable {
|
||||
return new SftpSession(factory.createSftpClient(clientSession));
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建本地 TCP 转发隧道.
|
||||
* <p> 该隧道为方向为 "本地->远端" (本地发起连接转发至远端端口).
|
||||
* @return 返回 TCP 转发通道对象, 可获取通道信息和关闭通道.
|
||||
*/
|
||||
public TcpForwardingChannel createLocalTcpForwarding(int localPort, int remotePort) throws IOException {
|
||||
ExplicitPortForwardingTracker tracker = clientSession
|
||||
.createLocalPortForwardingTracker(localPort, new SshdSocketAddress(remotePort));
|
||||
return new TcpForwardingChannel(tracker);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建远端 TCP 转发隧道.
|
||||
* <p> 该隧道为方向为 "本地<-远端" (远端服务器发起连接转发至本地端口).
|
||||
* @param remotePort 远端监听端口号, 该端口为远端服务连接转发的端口号.
|
||||
* @param localPort 本地连接端口号, 该端口为本地服务端的端口号.
|
||||
* @return 返回 Tcp 转发通道对象, 用于管理转发通道.
|
||||
*/
|
||||
public TcpForwardingChannel createRemoteTcpForwarding(int remotePort, int localPort) throws IOException {
|
||||
ExplicitPortForwardingTracker tracker =
|
||||
clientSession.createRemotePortForwardingTracker(
|
||||
new SshdSocketAddress(remotePort), new SshdSocketAddress(localPort));
|
||||
return new TcpForwardingChannel(tracker);
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭 SSH 连接会话, 该连接会话所属的其他会话将会一同被关闭.
|
||||
* @throws IOException 关闭失败时抛出异常,
|
||||
|
@ -0,0 +1,63 @@
|
||||
package net.lamgc.oracle.sentry.oci.compute.ssh;
|
||||
|
||||
import org.apache.sshd.client.session.forward.ExplicitPortForwardingTracker;
|
||||
import org.apache.sshd.common.util.net.SshdSocketAddress;
|
||||
|
||||
/**
|
||||
* TCP 隧道.
|
||||
* <p> 可通过该对象管理隧道.
|
||||
* @author LamGC
|
||||
*/
|
||||
public class TcpForwardingChannel implements AutoCloseable {
|
||||
|
||||
private final ExplicitPortForwardingTracker tracker;
|
||||
|
||||
TcpForwardingChannel(ExplicitPortForwardingTracker tracker) {
|
||||
this.tracker = tracker;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为本地转发.
|
||||
* @return 如果是本地转发, 则为 {@code true}, 否则返回 {@code false}, 代表远端转发.
|
||||
*/
|
||||
public boolean isLocalForwarding() {
|
||||
return tracker.isLocalForwarding();
|
||||
}
|
||||
|
||||
/**
|
||||
* 隧道是否已打开.
|
||||
* @return 如果已经打开, 返回 {@code true}, 否则返回 {@code false} 表示已关闭.
|
||||
*/
|
||||
public boolean isOpen() {
|
||||
return tracker.isOpen();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本地地址.
|
||||
* @return 获取本地连接地址.
|
||||
*/
|
||||
public SshdSocketAddress getLocalAddress() {
|
||||
return tracker.getLocalAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取远端地址.
|
||||
* @return 获取远端地址.
|
||||
*/
|
||||
public SshdSocketAddress getRemoteAddress() {
|
||||
return tracker.getRemoteAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取监听绑定地址.
|
||||
* @return 返回监听绑定地址.
|
||||
*/
|
||||
public SshdSocketAddress getBoundAddress() {
|
||||
return tracker.getBoundAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
tracker.close();
|
||||
}
|
||||
}
|
@ -14,3 +14,14 @@ oracle:
|
||||
# 首次连接认证策略
|
||||
# 支持 confirm(询问) accept(接受) reject(拒绝)
|
||||
authenticationPolicy: 'confirm'
|
||||
# SSH 转发设定
|
||||
forwarding:
|
||||
# X11 转发
|
||||
X11:
|
||||
enable: false
|
||||
# SSH-Agent 转发
|
||||
agent:
|
||||
enable: false
|
||||
# TCP 转发
|
||||
tcp:
|
||||
enable: true
|
||||
|
Loading…
Reference in New Issue
Block a user