# SshTunnelDemo **Repository Path**: dongliusuo/ssh-tunnel-demo ## Basic Information - **Project Name**: SshTunnelDemo - **Description**: SshTunnelDemo - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-01-26 - **Last Updated**: 2025-01-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # SSH隧道技术 ## 什么是SSH隧道 SSH隧道(SSH Tunnel)是一种通过安全的SSH(Secure Shell)协议在本地计算机与远程服务器之间建立加密连接的技术。它主要用于在不安全的网络环境中安全地传输数据,绕过网络限制或访问受限资源。 ## 主要用途 * 本地端口转发(Local Port Forwarding) > 将本地端口的流量转发到SSH服务器,再由SSH服务器转发到目标服务器。 > 例如要将本地的13306端口流量转发到远程服务器的13306端口上,那么: `127.0.0.1:13306`➡️`远程服务器:13306` * 远程端口转发(Remote Port Forwarding) > 将SSH服务器端口的流量转发到本地计算机,再由本地计算机转发到目标服务器。 > 例如要将远程服务器的3306端口流量转发到本地的3306上,那么: `远程服务器:3306`➡️`本地:3306` * 动态端口转发(Dynamic Port Forwarding) > 创建一个本地 SOCKS 代理服务器,应用程序通过配置使用这个SOCKS代理,而SSH客户端负责把流量通过SSH连接转发出去。 > 例如:访问受限服务 ## 前提条件 1. 必须安装了OPENSSH工具,windows上可以使用putty来替代 2. 远程服务器的SSH配置文件(/etc/ssh/sshd_config)要启用端口转发功能 ```bash # 确保设置为yes,允许TCP转发 AllowTcpForwarding yes # 设置为yes允许远程主机连接到本地转发的端口。如果只希望本地服务器访问,可以设置为no或clientspecified。 GatewayPorts yes ``` 修改后需重启sshd ```bash sudo systemctl restart sshd ``` 3. 检查防火墙相关配置,确保防火墙允许相关端口的流量 ## Linux创建SSH隧道的基本命令 ### 本地端口转发 ##### 命令格式 ```bash ssh -L [本地IP:]本地端口:目标服务器IP:目标端口 用户名@SSH服务器 -N ``` ##### 参数详解 `-L`: 本地端口转发 `[本地IP:]`: 可以不写,通常是localhost/0.0.0.0,一般也不用写 `-N`: 表示不执行远程命令,仅进行端口转发。(不需要打开远程shell的场景会用到) ##### 案例:实现访问localhost:20086 等价于访问148.135.51.31:10086 ```bash ssh -L 20086:localhost:10086 user@148.135.51.31 -N -o ServerAliveInterval=60 # 参数解释: ## 20086: 本地机器上的端口。当访问localhost:20086时,流量将被转发到远程服务器的指定端口。 ## localhost: 指代SSH服务器本身。如果目标服务在远程服务器的其他主机上,需要将 localhost 替换为相应的内网 IP 地址。 ## 10086: 服务的端口号 ## -o ServerAliveInterval=60: 这是可选的,可以不写,防止 SSH 连接因闲置而断开 ``` ### 远程端口转发 ##### 命令格式 ```bash ssh -R [SSH服务器IP:]SSH服务器端口:本地IP:本地端口 用户名@SSH服务器 -N ``` 注意[SSH服务器IP:]如果不想省略 可以写成0.0.0.0,表示远程服务器将监听所有可用的网络接口上的 15173 端口。这样,任何外部请求都可以访问这个端口。 ##### 案例:实现访问148.135.51.31:15173转发到本地的5173端口 ```bash ssh -R 15173:localhost:5173 root@148.135.51.31 -N ``` ### 动态端口转发 #### 基本命令 ```bash ssh -D 本地SOCKS端口 用户名@SSH服务器 -N ``` #### 举例 ```bash ssh -D 1080 root@SSH服务器 -N ``` 设置完成后,还要进入系统设置或浏览器设置socks代理,设置代理地址为 `localhost`,端口为 `1080` ## 使用本项目提供的工具类创建本地端口转发 ### jsch库,是java用来操作ssh连接的 ```xml com.jcraft jsch 0.1.55 ``` 可使用本项目的[SshTunnel.java](src%2Fmain%2Fjava%2Fcom%2Fgithub%2Fdongliusuo%2Fsshtunneldemo%2FSshTunnel.java)来创建SSH Tunnel ### 参考案例 ```java public void testUsePassword() throws IOException { SshTunnelProperties sshTunnelProperties = new SshTunnelProperties( "ssh服务器的地址", "root", "ssh密码", null, 20086, // 本地端口 13306); // 远程服务端口 try (SshTunnel sshTunnel = new SshTunnel(sshTunnelProperties)) { sshTunnel.open(); // 测试jdbc DriverManager.registerDriver(new Driver()); // 下面localhost:20086 等价于 ssh服务器的地址:13306 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:20086/mysql?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai", "root", "mysql_8_0_38_pwd"); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery("select * from User"); while (resultSet.next()) { System.out.println(resultSet.getString("user")); } } catch (SQLException e) { throw new RuntimeException(e); } } ```