springboot使用ssh公钥连接mysql(含账号密码连接)
创始人
2024-05-28 20:42:04
0

引言

在项目开发过程中,遇到了连接数据库时需要使用ssh公钥的情况。在本地使用navicat可以直接通过可视化界面去进行ssh的连接,但是在java中无法直接去进行连接。

后来经过查询资料,发现必须要在java中编写相关配置文件后才可以正常连接。

问题解决

原理:程序在本机创建ssh连接,连接到ssh server,然后再发送数据库操作指令,指令会被转发到目标数据库服务器上,返回操作结果

**前提:**项目已经配置好mysql连接所需要参数

**注意:**我演示的是使用ssh的公钥模式进行连接,如果需要使用密码模式进行连接,需要打开和关闭某些注释

  1. 引入依赖

    com.jcraftjsch0.1.55
    
    
  2. 编写ssh连接配置类

    package com.lzj.config;import com.jcraft.jsch.JSch;
    import com.jcraft.jsch.JSchException;
    import com.jcraft.jsch.Session;import java.util.Properties;/*** 

    * SSH连接配置类*

    ** @author:雷子杰* @date:2023/3/4*/ public class SSHConnectionConfig {//本地的ssh中的knownhost文件路径private String SSH_PATH_FILE_KNOWN_HOSTS = "C:\\Users\\86158\\.ssh\\known_hosts";//本地的ssh密钥路径private String SSH_PATH_FILE_PRIVATE_KEY = "**********************************";//ssh连接的用户名private String SSH_USER = "******";//ssh远程连接的ip地址private String SSH_REMOTE_SERVER = "65.115.26.30";//ssh连接的端口号,一般默认为22private Integer SSH_REMOTE_PORT = 22;//SSH使用密码//private String sshPassword;//本地mysql发起连接的IP地址private String MYSQL_REMOTE_SERVER = "127.0.0.1";//本地数据库连接时用的端口号(不能填3306)private Integer LOCAl_PORT = 3307;//远程数据库端口用的端口号private Integer REMOTE_PORT = 3309;//com.jcraft.jsch.Session;private Session session;/*** 关闭ssh连接*/public void closeSSH() {session.disconnect();}/*** 创建ssh连接*/public void createSSH() throws JSchException {JSch jSch = new JSch();//下面这两个设置是在公钥模式需要设置的,非公钥模式不需要进行设置//设置known_hosts文件路径,如:~/.ssh/known_hosts(known_hosts中存储是已认证的远程主机host key)jSch.setKnownHosts(SSH_PATH_FILE_KNOWN_HOSTS);//设置私钥jSch.addIdentity(SSH_PATH_FILE_PRIVATE_KEY);session = jSch.getSession(SSH_USER, SSH_REMOTE_SERVER, SSH_REMOTE_PORT);//如果是密码模式需要设置密码//session.setPassword(sshPassword);//设置连接过程不校验known_hosts文件中的信息Properties config = new Properties();config.put("StrictHostKeyChecking", "no");session.setConfig(config);//ssh 建立连接!session.connect();//根据安全策略,您必须通过转发端口进行连接session.setPortForwardingL(LOCAl_PORT, MYSQL_REMOTE_SERVER, REMOTE_PORT);} }
  3. 编写监听器

    注意:

    1. Listener类使用@WebListener注解;
    2. SpringBoot的启动类需要增加@ServletComponentScan用于扫描加载Listener类;

    经过我的尝试,发现如果使用了@Component注解,就算不使用@WebListener也同样可以完成监听功能

    package com.lzj.config;import org.springframework.stereotype.Component;import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    import javax.servlet.annotation.WebListener;/*** 

    **

    ** @author:雷子杰* @date:2023/3/4*/ @Component//尽量加上这个 @WebListener//声明为监听器 public class MyContextListener implements ServletContextListener {private SSHConnectionConfig sshConnectionConfig;public MyContextListener() {super();}@Overridepublic void contextInitialized(ServletContextEvent sce) {System.out.println("Context initialized ... !");try {sshConnectionConfig = new SSHConnectionConfig();sshConnectionConfig.createSSH();} catch (Throwable e) {e.printStackTrace(); // 连接失败}}@Overridepublic void contextDestroyed(ServletContextEvent sce) {System.out.println("Context destroyed ... !");sshConnectionConfig.closeSSH();//断开ssh连接} }
  4. 注意可能需要修改你的mysql连接配置

    可以看见我的的url中的localhost:3307,这个ip和端口号是根据你编写的ssh配置类MYSQL_REMOTE_SERVERLOCAl_PORT来的,你可能需要进行修改

    spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driverusername: rootpassword: ******url: jdbc:mysql://localhost:3307/leopard-vendor_cloud?autoReconnect=true&useUnicode=true&useSSL=false
    
  5. 测试

    编写一个测试类测试数据库的连接

    package com.lzj;import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;import javax.sql.DataSource;
    import java.sql.SQLException;/*** 

    **

    ** @author:雷子杰* @date:2023/3/3*/ @SpringBootTest(classes = SpringbootDetabaseApplication.class) @RunWith(SpringRunner.class) public class InitTest {@Autowiredprivate DataSource dataSource;@Testpublic void testDataSource() throws SQLException {System.out.println(dataSource.getConnection());} }

    测试结果如下:

    image-20230304155236024

    可以发现控制台正常输出了连接相关信息

总结

image-20230304160003390

**注意:**数据库连接地址由原来的123.mysql.com:3306改为127.0.0.1:3307,这样子,ssh连接会为每一个127.0.0.1:3307上的操作转发到123.mysql.com:3306上去,便可以正常操作数据库了。ssh连接的创建,可以采用私钥的方式,亦可以采用用户名密码的方式。

参考文章

  • 参考文章1
  • 参考文章2
  • 参考文章3

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...