MAC-Win11虚拟机双VPN环境内网穿透解决思路
背景
日常工作需要同时在mac上连接两个不同公司的vpn,下文简称:公司A -> vpn1;公司B -> vpn2。
对于公司B,需要在开发工作中,连接内网数据库、redis等服务,其vpn客户端同时支持macos与windows;对于公司A,原本只需要使用一些内网的web资源,其vpn客户端仅支持windows。
所以,我本机工作环境如下:
- macos下安装win11虚拟机,win11通过虚拟机的"共享网络"设置实现联网。
- macos下安装公司B的vpn2,idea等服务可以正常访问公司B内网的数据库等资源。
- win11下安装公司A的vpn1,在虚拟机里可以正常访问公司A的内网资源。
- 虚拟机新建一个HOST-ONLY网络,IP地址设置为192.168.137.3
- win11下安装ccproxy,搭建一个HTTP代理,代理地址为192.168.137.3
如此,可以在macos下既能访问公司B的内网数据库,又能正常访问公司A 的web页面,原本用的十分顺心,直到接到一个mq的开发需求。
新的问题
新项目的开发调试,需要同时连接公司B内网的数据库、zk和redis,以及公司A内网的rocketMQ服务,我原本天真的以为,将HTTP代理改为socks代理,然后通过添加静态路由,把mq的地址路由到代理服务器上就能解决问题,结果不知道是不是由于两个公司的内网都是10网段,导致静态路由无法生效。
解决方案
问题定位
- PD虚拟机的网络共享工作机制,可能导致某些协议的流量无法被正常转发;
- IDEA的工作机制:IDEA 本身不会自动将项目的所有网络请求通过系统的全局代理,尤其是当项目使用的是底层网络库(如 Netty、OkHttp 等)时,这些库有可能不会默认遵循系统的代理设置。
- 项目的架构:由于项目使用的rocketMQ客户端是二次封装的,rocketMQ 默认使用 Netty 进行通信,无法通过简单修改配置的方法设置代理,改底层代码不符合开发规范。
- socks工作机制:SOCKS 代理用于转发应用层的流量(如 HTTP、SSH 等),但并不支持直接转发 ICMP 请求(即 ping),这说明某些更底层的连接,socks可能代理不到。
解决方法
- 在虚拟机中,安装公司B的VPN客户端;
- 在虚拟机中,先拨公司A的vpn1,再拨公司B的vpn2;
- 在虚拟机中,删除造成冲突的vpn2添加的大网段路由,手动添加需要访问的数据库、redis具体IP地址的路由,指向vpn2网关,将命令做成bat脚本。
- 启动ccproxy,配置好socks代理。
- mac中打开idea,设置-> 外观与行为-> 系统设置-> HTTP代理:在右侧选手动配置代理-> socks,填上ccproxy配置好的ip端口。
- 打开项目运行设置,添加虚拟机运行参数(jvm),添加配置:-DsocksProxyHost=192.168.137.3 -DsocksProxyPort=1080
- mac下安装proxychains-ng,配置好代理服务器地址,并排除调127.0.0.1和localhost等本地地址,然后关闭idea,再通过proxychains-ng启动idea
所有问题解决。
其他
- 只打开idea的全局代理,运行项目无法连接到数据库,因为JDBC 数据库连接默认不会通过系统代理进行通信,因此要加上jvm参数。
- 不安装proxychains-ng无法连接mq,rocketMQ 默认情况下并不直接支持通过 JVM 参数配置代理进行连接。RocketMQ 使用的是 TCP 协议,而许多代理服务器(尤其是 HTTP 和 SOCKS 代理)可能无法处理 TCP 连接。这是导致 RocketMQ 不能通过 JVM 参数直接连接代理的原因。
- Proxychains可以在 Linux/MacOS 环境中使用,它能将 TCP 流量强制通过 SOCKS 代理发送。不过这种方式对稳定性和性能可能有一定的影响,仅用于本地开发测试尚可。