如何利用SSH隧道連接遠程MySQL數(shù)據(jù)庫
一、前言
MySQL數(shù)據(jù)庫漏洞頻出,不適合直接將3306端口開放到公網(wǎng)。
而實際情況,可能通過公網(wǎng)訪問數(shù)據(jù)庫的需求,可考慮利用SSH隧道連接遠程MySQL數(shù)據(jù)庫。
二、MySQL服務端
MySQL服務端無須額外配置,只需要開放ssh公網(wǎng)端口
即可!
為了進一步增加安全性,強烈建議,增加密碼重試策略、密碼復雜度規(guī)則。
另外,確認MySQL訪問權限,mysql.user表中是否存在host=’%’;的記錄,刪除并刷新權限。
delete from mysql.user where host='%'; flush privileges;
示例:
- 服務器IP(公網(wǎng)IP): 192.168.1.200
- SSH端口:10022
- SSH用戶名:test1
- SSH密碼:flzx3000c
- MySQL端口:3306
- MySQL用戶名:root
- MySQL密碼:ysyhl9t
三、MySQL客戶端
1.通過navicat工具利用SSH隧道連接MySQL數(shù)據(jù)庫
注意:127.0.0.1
為192.168.1.200的本地地址,而非客戶端的本地地址,此地址必須在mysql.user表中host里存在。
2.手動建立端口轉發(fā)規(guī)則(以linux為例)
# 端口轉發(fā) ssh -NCPf test1@192.168.1.200 -p 10022 -L 3388:127.0.0.1:3306 # 查看端口狀態(tài) netstat -ano |grep 3388 # 測試MySQL連接 mysql -P 3388 -u root -p >show databases;
參數(shù)解釋:
- C 使用壓縮功能,是可選的,加快速度。
- P 用一個非特權端口進行出去的連接。
- f SSH完成認證并建立port forwarding后轉入后臺運行。
- N 不執(zhí)行遠程命令。該參數(shù)在只打開轉發(fā)端口時很有用(V2版本SSH支持)
3.使用jsch進行端口轉發(fā)(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本地端口轉發(fā),本地轉發(fā)到遠程 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發(fā)送一個連接請求。
4.Server B得到Server A的信息后,在authorized_key中查找,如果有相應的用戶名和IP,則隨機生成一個字符串,并用Server A的公鑰加密,發(fā)送給Server A。
5.Server A得到Server B發(fā)來的消息后,使用私鑰進行解密,然后將解密后的字符串發(fā)送給Server B。Server B進行和生成的對比,如果一致,則允許免登錄。
6.得到server B發(fā)來的消息后,會使用私鑰進行解析,然后將機密后的字符串發(fā)給server B。
7.接收到機密后的字符串會跟先前生成的字符串進行對比,如果一致就允許免密登陸。
總之:A要免密碼登錄到B,B首先要擁有A的公鑰,然后B要做一次加密驗證。對于非對稱加密,公鑰加密的密文不能公鑰解開,只能私鑰解開。
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
MySQL日期ATE、TIME、DATETIME、TIMESTAMP和YEAR的使用語句
本文介紹了MySQL中日期和時間數(shù)據(jù)類型及其常見使用語句,包括DATE、TIME、DATETIME、TIMESTAMP和YEAR等,以及它們的應用場景,如記錄事件發(fā)生時間、查詢特定時間段內(nèi)的數(shù)據(jù)、定期清理過期數(shù)據(jù)和生成報表等2024-11-11MySQL server has gone away的問題解決
本文主要介紹了MySQL server has gone away的問題解決,意思就是指client和MySQL server之間的鏈接斷開了,下面就來介紹一下幾種原因及其解決方法,感興趣的可以了解一下2024-07-07MySQL中的CONCAT()函數(shù):輕松拼接字符串的利器
這篇文章主要介紹了MySQL中的CONCAT()函數(shù):輕松拼接字符串的利器,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04mysql下優(yōu)化表和修復表命令使用說明(REPAIR TABLE和OPTIMIZE TABLE)
隨著mysql的長期使用,肯定會出現(xiàn)一些問題,一般情況下mysql表無法訪問,就可以修復表了,優(yōu)化時減少磁盤占用空間。方便備份。2011-01-01MySQL5.7不停業(yè)務將傳統(tǒng)復制變更為GTID復制的實例
下面小編就為大家?guī)硪黄狹ySQL5.7不停業(yè)務將傳統(tǒng)復制變更為GTID復制的實例。小編覺的挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-03-03MySQL中count(*)、count(1)和count(col)的區(qū)別匯總
count()函數(shù)是用來統(tǒng)計表中記錄的一個函數(shù),返回匹配條件的行數(shù),下面這篇文章主要給大家總結介紹了關于MySQL中count(*)、count(1)和count(col)的區(qū)別,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下。2018-03-03