当前位置: 代码网 > it编程>数据库>Mysql > 如何利用SSH隧道连接远程MySQL数据库

如何利用SSH隧道连接远程MySQL数据库

2024年11月08日 Mysql 我要评论
一、前言mysql数据库漏洞频出,不适合直接将3306端口开放到公网。而实际情况,可能通过公网访问数据库的需求,可考虑利用ssh隧道连接远程mysql数据库。二、mysql服务端mysql服务端无须额

一、前言

mysql数据库漏洞频出,不适合直接将3306端口开放到公网。

而实际情况,可能通过公网访问数据库的需求,可考虑利用ssh隧道连接远程mysql数据库。

二、mysql服务端

mysql服务端无须额外配置,只需要开放ssh公网端口即可!

为了进一步增加安全性,强烈建议,增加密码重试策略、密码复杂度规则。

另外,确认mysql访问权限,mysql.user表中是否存在host=’%’;的记录,删除并刷新权限。

delete from mysql.user where host='%';
flush privileges;

示例:

  • 服务器ip(公网ip): 192.168.1.200
  • ssh端口:10022
  • ssh用户名:test1
  • ssh密码:flzx3000c
  • mysql端口:3306
  • mysql用户名:root
  • mysql密码:ysyhl9t

三、mysql客户端

1.通过navicat工具利用ssh隧道连接mysql数据库

注意:127.0.0.1为192.168.1.200的本地地址,而非客户端的本地地址,此地址必须在mysql.user表中host里存在。

2.手动建立端口转发规则(以linux为例)

# 端口转发
ssh -ncpf test1@192.168.1.200 -p 10022 -l 3388:127.0.0.1:3306
# 查看端口状态
netstat -ano |grep 3388
# 测试mysql连接
mysql -p 3388 -u root -p
>show databases;

参数解释:

  • c 使用压缩功能,是可选的,加快速度。
  • p 用一个非特权端口进行出去的连接。
  • f ssh完成认证并建立port forwarding后转入后台运行。
  • n 不执行远程命令。该参数在只打开转发端口时很有用(v2版本ssh支持)

3.使用jsch进行端口转发(springboot 代码示例)

<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
         xsi:schemalocation="http://maven.apache.org/pom/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelversion>4.0.0</modelversion>
    <parent>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-starter-parent</artifactid>
        <version>2.4.4</version>
        <relativepath/> <!-- lookup parent from repository -->
    </parent>
    <groupid>com.example</groupid>
    <artifactid>demo</artifactid>
    <version>0.0.1-snapshot</version>
    <name>demo</name>
    <description>demo project for spring boot</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>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-jdbc</artifactid>
        </dependency>

        <dependency>
            <groupid>mysql</groupid>
            <artifactid>mysql-connector-java</artifactid>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupid>com.jcraft</groupid>
            <artifactid>jsch</artifactid>
            <version>0.1.55</version>
        </dependency>

        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-test</artifactid>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupid>org.springframework.boot</groupid>
                <artifactid>spring-boot-maven-plugin</artifactid>
            </plugin>
        </plugins>
    </build>

</project>
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3388/mysql
    username: root
    password: ysyhl9t
    driver-class-name: com.mysql.jdbc.driver
package com.example.demo;

import com.jcraft.jsch.jsch;
import com.jcraft.jsch.session;
import org.springframework.boot.commandlinerunner;
import org.springframework.stereotype.component;

@component
public class runner implements commandlinerunner {

    /**
     * 测试代码变量暂不提取
     * @param args
     */
    @override
    public void run(string... args) throws exception {
        jsch jsch = new jsch();
        session session = null;
        try {
            session = jsch.getsession("test1", "192.168.1.200", 10022);
            session.setpassword("flzx3000c");
            session.setconfig("stricthostkeychecking", "no");
            session.connect();
            // 设置ssh本地端口转发,本地转发到远程
            session.setportforwardingl(3388, "127.0.0.1", 3306);
        } catch (exception e) {
            if (null != session) {
                //关闭ssh连接
                session.disconnect();
            }
            e.printstacktrace();
        }
    }

}
package com.example.demo;

import org.junit.jupiter.api.test;
import org.springframework.boot.test.context.springboottest;
import org.springframework.jdbc.core.jdbctemplate;
import org.springframework.jdbc.core.rowmapper;

import javax.annotation.resource;
import java.sql.resultset;
import java.sql.sqlexception;
import java.util.list;

@springboottest
class demoapplicationtests {

    @resource
    private jdbctemplate jdbctemplate;

    @test
    void contextloads() {
        string sql = "select host from mysql.user";
        final list<string> list = jdbctemplate.query(sql, (resultset, i) -> resultset.getstring("host"));
		system.out.println(list);
    }

}

四、ssh隧道的建立方式

方式1.用户名和密码

方式2.密钥(推荐)

免密登录(客户端):

ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub test1@192.168.1.200

免密登录原理

1.在a上生成公钥私钥。

2.将公钥拷贝给server b,要重命名成authorized_keys(从英文名就知道含义了)

3.server a向server b发送一个连接请求。

4.server b得到server a的信息后,在authorized_key中查找,如果有相应的用户名和ip,则随机生成一个字符串,并用server a的公钥加密,发送给server a。

5.server a得到server b发来的消息后,使用私钥进行解密,然后将解密后的字符串发送给server b。server b进行和生成的对比,如果一致,则允许免登录。

6.得到server b发来的消息后,会使用私钥进行解析,然后将机密后的字符串发给server b。

7.接收到机密后的字符串会跟先前生成的字符串进行对比,如果一致就允许免密登陆。

总之:a要免密码登录到b,b首先要拥有a的公钥,然后b要做一次加密验证。对于非对称加密,公钥加密的密文不能公钥解开,只能私钥解开。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com