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