1.A与B配置SSH免密连接
A服务器 192.168.1.141
B服务器 192.168.1.143
1) 生成SSH密钥
ssh-keygen -t rsa
直接回车到结束
回到 ~ 目录下
发现 .ssh 文件夹
生成秘钥成功
2)发送公钥建立连接
ssh-copy-id 192.168.1.143
试登录一下B服务器(第一次连接需要密码)
ssh 192.168.1.143
如果出现 The authenticity of host 'XXX (XXX.XXX.X.XXX)' can't be established 的警告
执行命令(在本机执行即可):
ssh -o StrictHostKeyChecking=no 192.168.1.143
2.在A为B的Mysql创建SSH连接通道
在A服务器的3307端口 绑定B服务器的3306端口
ssh -fN -L3307:192.168.1.143:3306 -p22 [email protected]
ssh -fN -L(要绑定到的本地端口):(服务器B的Host):(服务器B上要访问的端口号) -p(服务器B的SSH端口,默认为22) (服务器B的用户):(服务器B的Host)
3.使用Navicat测试连接
使用A服务器的SSH连接通道
连接3307端口 A服务器通道会自动转发到B服务器的3306端口
4.使用 springboot 远程连接 B服务器的Mysql (通过A服务器)
1)首先创建 test库 user表 并 插入一条user数据
2)创建springboot应用
项目结构
工程文件 pom.xml
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.lionli</groupId>
<artifactId>ssh-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sshDemo</name>
<description>使用SSH通道通过A服务器连接B服务器Mysql</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- mybatis-plus begin -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
<!-- SSH工具 -->
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
配置文件 application.yml (项目数据库查询使用 mybatis-plus 这里不多解释 感兴趣的可以自行百度)
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: root
# SSH连接配置
sshconfig:
# 本地通信端口
local-port: 3306
# 远程连接端口
remote-port: 3307
ssh:
# SSH用户名
user: root
# SSH密码
password: root
# SSH通信端口
remote-port: 22
# 远程A服务器跳板机IP
remote-server: 192.168.1.141
mysql:
# Mysql服务
remote-server: localhost
# MyBatis配置
mybatis-plus:
mapper-locations: classpath*:mapper/**/*Mapper.xml
#实体扫描,多个package用逗号或者分号分隔
typeAliasesPackage: com.lionli
configuration:
map-underscore-to-camel-case: true
cache-enabled: true
global-config:
#刷新mapper 调试神器
refresh: true
db-config:
#主键类型 0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
id-type: auto
#字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
field-strategy: not_empty
#驼峰下划线转换
db-column-underline: true
#数据库大写下划线转换
#capital-mode: true
#序列接口实现类配置
#key-generator: com.baomidou.springboot.xxx
#逻辑删除配置
logic-delete-value: 1
logic-not-delete-value: 0
#数据库类型
db-type: mysql
#自定义SQL注入器
#sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector
#自定义填充策略接口实现
#meta-object-handler: com.baomidou.springboot.xxx
项目启动类 SshDemoApplication.java
@SpringBootApplication
public class SshDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SshDemoApplication.class, args);
}
}
配置 mybatis-plus
@EnableTransactionManagement(proxyTargetClass = true)
@Configuration
@MapperScan("com.lionli.**.mapper*")
public class MybatisPlusConfig {
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}
配置 SSH 工具 SSHConnection.java
@Component
@Configuration
public class SSHConnection {
// 自定义的中转接口,需要和数据源接口设置一样
@Value("${sshconfig.local-port}")
private Integer localPort;
// 服务端的数据库端口
@Value("${sshconfig.remote-port}")
private Integer remotePort;
// 服务器端SSH端口 默认是22
@Value("${sshconfig.ssh.remote-port}")
private Integer sshRemotePort;
// SSH用户名
@Value("${sshconfig.ssh.user}")
private String sshUser;
// SSH使用密码
@Value("${sshconfig.ssh.password}")
private String sshPassword;
// 连接到哪个服务端的SSH
@Value("${sshconfig.ssh.remote-server}")
private String sshRemoteServer;
// 服务端的本地mysql服务
@Value("${sshconfig.mysql.remote-server}")
private String mysqlRemoteServer;
//represents each ssh session
private Session sesion;
/**
* 创建SSH连接
*/
public void createSSH() throws Throwable {
JSch jsch = new JSch();
// 需要用到了开启
sesion = jsch.getSession(sshUser, sshRemoteServer, sshRemotePort);
sesion.setPassword(sshPassword);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
sesion.setConfig(config);
// 去连接
sesion.connect(); //ssh connection established!
// 设置转发
sesion.setPortForwardingL(localPort, mysqlRemoteServer, remotePort);
}
/**
* 关闭SSH连接
*/
public void closeSSH() {
sesion.disconnect();
}
}
监听Servlet事件 MyContextListener.java
@Slf4j
@WebListener
@Component
public class MyContextListener implements ServletContextListener {
@Autowired
private SSHConnection conexionssh;
/**
* 监听Servlet初始化事件
*/
@Override
public void contextInitialized(ServletContextEvent arg0) {
// 建立连接
try {
conexionssh.createSSH();
log.info("成功建立SSH连接!");
} catch (Throwable e) {
log.info("SSH连接失败!");
e.printStackTrace(); // error connecting SSH server
}
}
/**
* 监听Servlet终止事件
*/
@Override
public void contextDestroyed(ServletContextEvent arg0) {
// 断开连接
try {
conexionssh.closeSSH(); // disconnect
log.info("成功断开SSH连接!");
} catch (Exception e) {
e.printStackTrace();
log.info("断开SSH连接出错!");
}
}
}
User.java (这里使用lombok)
@Data
@ToString
@TableName("user")
public class User {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@TableField(value = "user_name")
private String userName;
@TableField(value = "password")
private String password;
}
UserMapper.java (这里为了方便测试直接用Mapper了)
/**
*
* @author Lion Li
* @date 2019-12-09
*/
public interface UserMapper extends BaseMapper<User> {
}
UserController.java (这里为了方便测试直接用Mapper了)
@RestController
public class UserController {
@Autowired
private UserMapper userMapper;
/**
* 获取全部用户列表
*/
@GetMapping("/getUserList")
public List<User> test(){
return userMapper.selectList(new QueryWrapper<>());
}
}
3)启动测试应用
测试成功
项目已上传到gitee
如果帮到您了,请帮忙点个star