在我的Windows电脑上,有些网站无法直接访问,所以需要通过Mac来代理。为此,需要创建一个位于Windows和Mac之间的SSH tunnel。
在我的环境中,网络结构如下:
Windows ? Mac ? server ? 网站
首先,如果只是想在Mac上访问网站,则只需在Mac上建立一个到server的SSH tunnel:
ssh -o ExitOnForwardFailure=yes -qTfN -D 8888 <server>
然后在浏览器里配置SOCK5代理 localhost:8888
即可。
如果想要在Windows端访问网站,则需要在Windows和Mac之间再建立一个SSH tunnel。也就是说,把Mac作为请求转发的中继。
如果Windows能ssh登录到Mac(比如通过GitBash、Putty等工具),则只需在Windows端运行如下命令:
ssh -o ExitOnForwardFailure=yes -qTfnN -L 8888:localhost:8888 <Mac>
注意:此处无需添加 -D
选项,而 -L
选项表示local,也就是正向tunnel(tunnel的方向和ssh的方向一致)。
该解决方案可参见我另一篇文档 https://blog.csdn.net/duke_ding2/article/details/106878081
。
问题是,由于一些原因,Mac无法打开SSH服务,所以,只能想办法从Mac登录到Windows,建立一个远程(反向)SSH tunnel。也就是说,ssh的方向是从Mac到Windows,但tunnel的方向是从Windows到Mac。在Mac端运行如下命令:
ssh -o ExitOnForwardFailure=yes -qTfnN -R 8888:localhost:8888 <Windows>
注意:这两条ssh命令里,转发的目标地址都是 localhost
。请注意目标地址是相对于SSH tunnel的server端而言的,由于这两个ssh命令的SSH tunnel server都是Mac,所以,这两个 localhost
都是指Mac,也就是说,都是把tunnel client(即Windows)端的8888端口请求转发到Mac的8888端口。这一点一定要搞清楚。
为此,需要在Windows端开启SSH服务,以便Mac能够ssh登录到Windows端。
首先,点击“开始”按钮,查找“设置”:
打开“设置”窗口,选择“应用” -> “可选功能”:
在“已安装功能”里,确保“OpenSSH客户端”和“OpenSSH服务器”都存在,如下图所示。
在我的机器上,“OpenSSH客户端”默认已安装,而“OpenSSH服务器”不存在,此时需要点击窗口右上角的“查看功能”按钮,然后在弹出对话框里选中“OpenSSH服务器”并安装。安装过程略。
安装好以后,在启动SSH服务之前,还要先配置一下,配置文件为: C:\ProgramData\ssh\sshd_config
。
以下是我修改后的配置:
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options override the
# default value.
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
#HostKey __PROGRAMDATA__/ssh/ssh_host_rsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_dsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_ecdsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_ed25519_key
# Ciphers and keying
#RekeyLimit default none
# Logging
#SyslogFacility AUTH
#LogLevel INFO
# Authentication:
#LoginGraceTime 2m
#PermitRootLogin prohibit-password
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10
PubkeyAuthentication yes
# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile .ssh/authorized_keys
#AuthorizedPrincipalsFile none
# For this to work you will also need host keys in %programData%/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes
# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication yes
PermitEmptyPasswords yes
# GSSAPI options
#GSSAPIAuthentication no
#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
#PermitTTY yes
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
#PermitUserEnvironment no
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS no
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none
# no default banner path
#Banner none
# override default of no subsystems
Subsystem sftp sftp-server.exe
# Example of overriding settings on a per-user basis
#Match User anoncvs
# AllowTcpForwarding no
# PermitTTY no
# ForceCommand cvs server
#Match Group administrators
# AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
有几处需要修改和留意:
PubkeyAuthentication yes
:允许使用ssh key登录(但只配置此处还不够)。AuthorizedKeysFile .ssh/authorized_keys
:存放授权公钥的文件(路径是基于个人的home目录,比如 C:\Users\duke_
)。PasswordAuthentication yes
:是否允许使用密码登录,如果不允许,则只能通过ssh key登录,如果没有配置ssh key,则直接报错。PermitEmptyPasswords yes
:是否允许空密码,在我的环境里,Windows本身没有设置登录密码,但是,此处即使设置为允许空密码,ssh登录时还会提示输入密码,而且无论是直接回车,还是随便输入什么内容再回车,都不能登录。反而是给Windows设置登录密码后,能通过密码登录。有待继续研究。#Match Group administrators
和 # AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
:如果允许使用ssh key登录,则此处必须注释掉。修改完配置以后,需要重启SSH服务。“开始” -> “运行” -> “services.msc”,打开服务窗口:
找到“OpenSSH SSH Server”,点击右键,选择“启动”或者“重新启动”。
注:每次修改完配置以后,别忘了重新启动SSH服务,修改才能生效。
现在,就可以在Mac端,用ssh登录到Windows了。
[ding@192 .ssh]$ ssh admin@192.168.1.4
admin@192.168.1.4's password:
Microsoft Windows [版本 10.0.22000.2538]
(c) Microsoft Corporation。保留所有权利。
admin@DESKTOP-IK7TLA2 C:\Users\duke_>
但是这种方法只限于Windows有登录密码,如果没有密码,在提示输入密码时,无论直接回车还是随便输入什么内容再回车,都不行。不知道是不是哪里配置的有问题,有待继续研究。
还有一种方法是用ssh key登录(无论Windows有没有登录密码)。把Mac的公钥(一般是 ~/.ssh/id_rsa.pub
文件)内容复制到Windows的 c:\Users\duke_\.ssh\authorized_keys
文件里,然后在Mac端用ssh登录,就会直接登录,不再提示输入密码了:
[ding@192 .ssh]$ ssh admin@192.168.1.4
Microsoft Windows [版本 10.0.22000.2538]
(c) Microsoft Corporation。保留所有权利。
admin@DESKTOP-IK7TLA2 C:\Users\duke_>
配置好SSH登录以后,就可以在Mac上建立SSH反向tunnel了。
ssh -o ExitOnForwardFailure=yes -qTfnN -R 8888:localhost:8888 admin@192.168.1.4
注: 192.168.1.4
是Windows的IP地址。
注意:此处使用该命令,是因为Mac也不能直接访问网站,从Mac到server还有一层代理做动态转发(在Mac上):
ssh -o ExitOnForwardFailure=yes -qTfN -D 8888 <server>
如果Mac能够直接访问网站,则应使用如下命令(在Mac上):
ssh -o ExitOnForwardFailure=yes -qTfN -R localhost:8888 <Windows>
注:这种方式亲测有效(使用w3测试)。该方式其实是“反向动态代理”,也就是 -R
和 -D
的组合。之所以只用 -R
,是因为自从OpenSSH 7.6起, -R
已经包含了动态转发的功能,参见 http://openssh.com/txt/release-7.6
。
接下来,在Windows端的浏览器里,配置SOCKS5代理 localhost:8888
即可。
注:如果不建立Windows和Mac之间的SSH tunnel,而直接在Windows端的浏览器里,配置SOCKS5代理 <Mac>:8888
行不行呢?答案是不行,因为Mac的8888端口是nc不通的,无法接收外界的请求(但能接收本地的请求,具体原因我也不是很清楚)。
关于SSH tunnel的代理转发,可参见我另一篇文档( https://blog.csdn.net/duke_ding2/article/details/106878081
)。
https://www.jianshu.com/p/03b04f96eaa8
https://blog.csdn.net/duke_ding2/article/details/106878081
https://unix.stackexchange.com/questions/179270/how-to-create-reverse-dynamic-ssh-port-forwarding