springboot 使用SSH 通過A服務器跳板機 連接B服務器Mysql(安全策略)

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

地址: springboot-ssh-mysql-demo

如果幫到您了,請幫忙點個star

 

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章