通过 SSH 连接受限数据库
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>${jsch.version}</version>
</dependency>
import org.springframework.boot.context.properties.ConfigurationProperties;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString(exclude="password")
@ConfigurationProperties(prefix="ssh")
public class SshProperties {
private String host;
private Integer port;
private String username;
private String password;
private Forward forward;
@Getter
@Setter
@ToString
public static class Forward {
private String fromHost;
private Integer fromPort;
private String toHost;
private Integer toPort;
}
}
import javax.annotation.PreDestroy;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.weaving.LoadTimeWeaverAware;
import org.springframework.instrument.classloading.LoadTimeWeaver;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import net.saisimon.ssh.config.SshProperties.Forward;
import lombok.extern.slf4j.Slf4j;
@Configuration
@EnableConfigurationProperties(SshProperties.class)
@ConditionalOnProperty(prefix = "ssh", value = "enabled", havingValue = "true", matchIfMissing = false)
@Slf4j
public class SshConfiguration implements LoadTimeWeaverAware {
private final Session session;
public SshConfiguration(SshProperties sshProperties) {
Session session = null;
try {
session = new JSch().getSession(sshProperties.getUsername(), sshProperties.getHost(), sshProperties.getPort());
session.setConfig("StrictHostKeyChecking", "no");
session.setPassword(sshProperties.getPassword());
session.connect();
Forward forward = sshProperties.getForward();
if (forward != null) {
session.setPortForwardingL(forward.getFromHost(), forward.getFromPort(), forward.getToHost(), forward.getToPort());
log.info("{}:{} -> {}:{}", forward.getFromHost(), forward.getFromPort(), forward.getToHost(), forward.getToPort());
}
} catch (JSchException e) {
log.error("ssh " + sshProperties.getHost() + " failed.", e);
}
this.session = session;
}
@PreDestroy
public void disconnect() {
if (session != null) {
session.disconnect();
}
}
@Override
public void setLoadTimeWeaver(LoadTimeWeaver loadTimeWeaver) {
}
}
application.properties
文件中添加 SSH 相关属性值
ssh.enabled=false # 是否启用 SSH 配置
ssh.host=127.0.0.1 # SSH 地址
ssh.port=22 # SSH 端口
ssh.username= # SSH 用户名
ssh.password= # SSH 密码
ssh.forward.from_host= # 绑定的本地地址
ssh.forward.from_port= # 绑定的本地端口
ssh.forward.to_host= # 正向代理的远程地址
ssh.forward.to_port= # 正向代理的远程端口
jdbc.url=jdbc:mysql://<from_host>:<from_port>/your_database_name
SSH 连接失败可能的原因
- 用户名或密码错误
sshd_config
中需要配置 PasswordAuthentication yes
,允许使用密码登陆- 使用
root
用户登陆,需要配置 PermitRootLogin yes
,才能登陆