如何通过SSH端口转发在受限远程Linux设备上安装Python包?
你遇到的核心问题其实是远程设备没有DNS解析能力,加上原命令没处理好域名解析环节,导致pip连索引URL都无法获取。下面给你两种可行的解决方案,一步步来:
方案一:用SSH动态SOCKS代理(推荐,更省心)
这种方式让本地机器帮远程设备完成DNS解析和外网请求,完美避开远程无DNS的限制:
在你的本地机器(能正常访问外网的那台)执行这条SSH命令,建立动态端口转发:
ssh -D 9999 xxxx@XX.XX.XX.XX-D参数会在远程设备的localhost:9999创建一个SOCKS5代理,所有通过这个代理的请求都会通过SSH隧道(走22端口)转到你的本地机器,由本地机器处理DNS解析和外网访问。保持SSH连接打开,在远程设备的终端里执行pip安装命令,指定SOCKS5代理:
pip install pymodbus==1.3.2 --proxy socks5://localhost:9999这样pip会把所有请求通过SOCKS代理发出去,域名解析在本地完成,完全不需要远程设备有DNS。
方案二:指定Pypi的IP地址+反向端口转发
如果你更倾向用反向端口转发,需要先解决DNS解析的问题:
在本地机器上查询Pypi的IP地址:
执行nslookup pypi.python.org或者dig pypi.python.org,得到它的实际IP(比如当前可能是151.101.64.223,注意这个IP可能会变,要查最新的)。在本地机器建立反向端口转发,指向Pypi的IP和443端口:
ssh -R 9999:151.101.64.223:443 xxxx@XX.XX.XX.XX这条命令会把远程设备的
localhost:9999端口的流量,通过SSH隧道转发到本地机器,再由本地机器访问Pypi的IP:443。在远程设备执行pip命令,直接用IP作为索引源,同时指定代理和信任主机:
pip install pymodbus==1.3.2 --index-url https://151.101.64.223/simple/ --proxy http://localhost:9999 --trusted-host 151.101.64.223这里的关键点:
--index-url直接用Pypi的IP地址,避免远程解析域名--trusted-host必须加,因为用IP访问HTTPS站点时,证书域名不匹配,pip会拒绝连接- 代理用
http://localhost:9999,因为我们转发的是目标的HTTPS端口,代理本身是HTTP协议的转发通道
为什么你原来的命令失败?
你之前的反向转发命令本身是对的,但远程设备没有DNS,pip在尝试访问pypi.python.org时,第一步就无法解析域名,直接导致连接中止——根本没用到你建立的端口转发。解决DNS解析问题后,就能正常走隧道访问Pypi了。
内容的提问来源于stack exchange,提问作者Alex Poca

