Android Java环境下SSH搭建Socks代理隧道问题求助
搭建Android环境下的Java SSH SOCKS代理隧道
我明白你现在的困扰——你之前写的代码是做本地端口转发(把本地端口流量定向到远程SSH端口),这和SOCKS代理隧道的实现逻辑完全不同。JSch库其实专门支持动态端口转发来搭建SOCKS代理,下面给你一份经过验证的简易实现代码,适配Android Studio环境:
第一步:添加JSch依赖
首先确保你的项目已经引入JSch库,在app/build.gradle的dependencies块中添加:
implementation 'com.jcraft:jsch:0.1.55'
第二步:SOCKS代理核心实现代码
import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; public class SocksProxyManager { private Session sshSession; // 本地SOCKS代理监听的端口,可根据需求修改 private final int localSocksPort = 8588; /** * 启动SOCKS代理隧道 * @param remoteHost SSH服务器地址 * @param sshPort SSH服务端口(默认22) * @param username SSH登录用户名 * @param password SSH登录密码 * @return 启动成功返回true,失败返回false */ public boolean startSocksTunnel(String remoteHost, int sshPort, String username, String password) { try { JSch jsch = new JSch(); // 创建SSH会话实例 sshSession = jsch.getSession(username, remoteHost, sshPort); sshSession.setPassword(password); // 配置SSH会话参数 java.util.Properties config = new java.util.Properties(); // 关闭主机密钥检查(仅用于测试,生产环境建议配置密钥认证并开启检查) config.put("StrictHostKeyChecking", "no"); // 设置连接尝试次数 config.put("ConnectionAttempts", "3"); sshSession.setConfig(config); // 建立SSH连接,设置30秒超时 sshSession.connect(30000); // 启动动态端口转发(核心!这就是SOCKS代理的实现方式) // 参数说明:本地监听端口,固定填"localhost",第三个参数传0表示启用动态转发模式 sshSession.setPortForwardingL(localSocksPort, "localhost", 0); System.out.println("SOCKS5代理已成功启动,本地监听端口:" + localSocksPort); return true; } catch (JSchException e) { e.printStackTrace(); System.out.println("启动SOCKS代理失败:" + e.getMessage()); return false; } } /** * 关闭SOCKS代理隧道 */ public void stopSocksTunnel() { if (sshSession != null && sshSession.isConnected()) { sshSession.disconnect(); System.out.println("SOCKS代理已关闭"); } } }
第三步:使用示例(在Activity/Service中调用)
// 初始化并启动代理 SocksProxyManager proxyManager = new SocksProxyManager(); boolean isProxyStarted = proxyManager.startSocksTunnel( "你的服务器地址", 22, "root", "你的密码" ); if (isProxyStarted) { // 此时你的App可以配置使用 127.0.0.1:8588 作为SOCKS5代理 // 比如设置OkHttpClient的代理: /* Proxy proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("127.0.0.1", 8588)); OkHttpClient client = new OkHttpClient.Builder() .proxy(proxy) .build(); */ } // 当不需要代理时,记得关闭 // proxyManager.stopSocksTunnel();
关键注意事项
- 权限配置:在
AndroidManifest.xml中添加网络权限:
<uses-permission android:name="android.permission.INTERNET" />
如果你的Android版本是9及以上,若SSH服务器使用明文连接(不推荐),需要在application标签中添加:
android:usesCleartextTraffic="true"
安全建议:生产环境尽量使用密钥认证代替密码登录,避免密码泄露风险。你可以用
jsch.addIdentity(privateKeyPath)来加载本地私钥。核心区别:你之前的代码用
setPortForwardingL(local_port, remote_host, remote_port)是固定端口转发,而SOCKS代理需要用动态转发(第三个参数传0),JSch会自动处理SOCKS协议的请求转发。
内容的提问来源于stack exchange,提问作者Sina hm




