feat: 初步添加 SSH Forwarding 功能.

添加对 SSH 转发功能的支持, 脚本可通过 SSH 会话使用.

注意: 该功能尚未得到足够的测试, 使用时遇到问题请反馈.
This commit is contained in:
LamGC 2021-09-02 18:58:10 +08:00
parent 3641593210
commit 13d90595b7
Signed by: LamGC
GPG Key ID: 6C5AE2A913941E1D
7 changed files with 162 additions and 1 deletions

View File

@ -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) {

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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()));

View File

@ -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 关闭失败时抛出异常,

View File

@ -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();
}
}

View File

@ -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