java Jsch实现跳板机操作远程数据库

java Jsch实现跳板机操作远程数据库

2018年05月04日 11:07:20 一念落叶 阅读数:823

jsch是一个纯java实现的ssh,作用有很多,比如实现一个sftp或者ftp,java执行shell命令等等,今天用做于模拟登陆跳板机然后操作数据库和redis,原理为通过本机的端口进行本地端口转发到跳板机再进行连接mysql,相当于如下命令:

ssh -L 1234:localhost:3306 mysql.server.remote

ssh本地端口转发远程端口转发可参考如下博客:

实战 SSH 端口转发

SSH端口转发(本地端口转发、远程端口转发、动态端口转发)工作原理、应用详解

首先导入maven依赖,数据库用的是mysql

 
  1. <dependency>

  2. <groupId>com.jcraft</groupId>

  3. <artifactId>jsch</artifactId>

  4. <version>0.1.53</version>

  5. </dependency>

  6. <dependency>

  7. <groupId>mysql</groupId>

  8. <artifactId>mysql-connector-java</artifactId>

  9. <version>5.1.36</version>

  10. </dependency>

然后建立一个ssh通道模拟登陆到跳板机

 
  1. public class JDBCSSHChannel {

  2. private Session session;

  3. private Channel channel;

  4.  
  5. /**

  6. *

  7. * @param localPort 本地host 建议mysql 3306 redis 6379

  8. * @param sshHost ssh host

  9. * @param sshPort ssh port

  10. * @param sshUserName ssh 用户名

  11. * @param sshPassWord ssh密码

  12. * @param remotoHost 远程机器地址

  13. * @param remotoPort 远程机器端口

  14. */

  15. public void goSSH(int localPort, String sshHost, int sshPort,

  16. String sshUserName, String sshPassWord,

  17. String remotoHost, int remotoPort) {

  18. try {

  19. JSch jsch = new JSch();

  20. //登陆跳板机

  21. session = jsch.getSession(sshUserName, sshHost, sshPort);

  22. session.setPassword(sshPassWord);

  23. session.setConfig("StrictHostKeyChecking", "no");

  24. session.connect();

  25. //建立通道

  26. channel = session.openChannel("session");

  27. channel.connect();

  28. //通过ssh连接到mysql机器

  29. int assinged_port = session.setPortForwardingL(localPort, remotoHost, remotoPort);

  30. } catch (Exception e) {

  31. e.printStackTrace();

  32. }

  33. }

  34.  
  35. /**

  36. * 关闭

  37. */

  38. public void close() {

  39. if (session != null && session.isConnected() ) {

  40. session.disconnect();

  41. }

  42.  
  43. if (channel != null && session.isConnected() ) {

  44. channel.disconnect();

  45. }

  46. }

  47. }

如果跳板机是用的秘钥文件的话,可以直接在jsch中add

jsch.addIdentity(sshPrvkey);

其中session中的StrictHostKeyChecking是对public_key的检查等级设置,默认值StrictHostKeyChecking=ask

 
  1. //最不安全的级别,相对安全的内网测试时建议使用。如果连接server的key在本地不存在,那么就自动添加到文件中(默认是known_hosts),并且给出一个警告。

  2. session.setConfig("StrictHostKeyChecking", "no");

  3.  
  4. //默认的级别,如果连接和key不匹配,给出提示,并拒绝登录

  5. session.setConfig("StrictHostKeyChecking", "ask");

  6.  
  7. //最安全的级别,如果连接与key不匹配,就拒绝连接,不会提示详细信息

  8. session.setConfig("StrictHostKeyChecking", "yes");

 

然后连接mysql,在连接mysql前调用下goSSH方法建立跳板机通道即可,另外,连接数据库的时候ip要用localhost或者127.0.0.1

,相当于连接本地mysql数据库一样。

 
  1. public static Connection connDB() {

  2. // 声明Connection对象

  3. Connection con = null;

  4. // 驱动程序名

  5. String driver = "com.mysql.jdbc.Driver";

  6. // URL指向要访问的数据库名mydata

  7. String url = "jdbc:mysql://localhost:3306/TEST";

  8. // MySQL配置时的用户名

  9. String user = "root";

  10. // MySQL配置时的密码

  11. String password = "123456";

  12. // 遍历查询结果集

  13. try {

  14. // 加载驱动程序

  15. try {

  16. Class.forName(driver);

  17. } catch (ClassNotFoundException e) {

  18. // TODO Auto-generated catch block

  19. e.printStackTrace();

  20. }

  21. // 1.建立跳板机通道

  22. JDBCSSHChannel channel = new JDBCSSHChannel();

  23. channel.goSSH(localPort, sshHost, sshPort, sshUserName, sshPassWord,

  24. remotoHost,remotoPort);

  25.  
  26. // 2.getConnection()方法,连接MySQL数据库!!

  27. con = DriverManager.getConnection(url, user, password);

  28. } catch (SQLException e) {

  29. // TODO: handle exception

  30. e.printStackTrace();

  31. }

  32. return con;

  33. }

 

至于连接redis同样的原理:

 
  1. public static void main(String[] args) throws JSchException {

  2. JDBCSSHChannel channel = new JDBCSSHChannel();

  3. channel.goSSH(localPort, sshHost, sshPort, sshUserName, sshPassWord,

  4. remotoHost,remotoPort);

  5.  
  6. // 1.建立跳板机通道

  7. channel.goSSH(localPort, sshHost, sshPort, sshUserName, sshPassWord, remotoHost,

  8. remotoPort);

  9.  
  10. JedisPool jedisPool = new JedisPool(new JedisPoolConfig(), redisHost, redisPort, redisTimeout, redisPassword);

  11.  
  12. JedisCommands jedis = jedisPool.getResource();

  13. jedis.get(key);

  14.  
  15. channel.close();

但是redis连接cluster有点问题,只能已alone的模式单个连接cluster,直接连接redis cluster会报错:

java.net.SocketTimeoutException: connect timed out

socket连接超时,可能是我姿势不对,目前cluster模式暂未解决,只能用alone模式代理cluster。

另外用完ssh通道记得关闭。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值