Sockets代理 之 SSH Sockets

使用SSH来开启Socks代理:

ssh -CN -D 127.0.0.1:7070 root@x.x.x.x -p 22
root@x.x.x.x's password:

这样就可以启动一个Socks,C表示压缩数据传输,N表示不进入Bash。(比如浏览器)设置Socket代理IP为127.0.0.1端口为7070,然后就可以通过x.x.x.x(x.x.x.x可以是本机地址)代理上网了。

SSH可以通过-i指定一个私钥来进行认证(这样就不需要输入密码),这种方式意味在需要在服务器端对应的用户里放置一个公钥:

root@xxx:~/.ssh ls
authorized_keys  known_hosts
root@xxx:~/.ssh# pwd
/root/.ssh
root@xxx:~/.ssh:~/.ssh# ls
authorized_keys  known_hosts
root@xxx:~/.ssh:~/.ssh# cat authorized_keys 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCiaMoJRe..........

公钥放进去后,在客户端就需要指定其对应的私钥:

ssh -CN -D 127.0.0.1:7070 root@x.x.x.x -p 22 -i /roo/is_rsa

这样就不需要输入密码了。Linux中SSH不支持直接输入密码,但是可以使用一个包装工具来完成(sshpass):

yum install sshpass

#运行sshpass
sshpass -p "passwd" ssh -CN -D 127.0.0.1:7070 root@x.x.x.x -p 22 

#查看进程可见:sshpass就是一个包装器
sshpass -p zzzzzzzzzz ssh -CN -D 127.0.0.1:7070 root@127.0.0.1 -p 22
ssh -CN -D 127.0.0.1:7070 root@127.0.0.1 -p 22

注:这里是监听本机的127.0.0.1的7070端口,本机通过SSH把数据传输到远程服务器,把远程服务器设置在本机也是可以的,这样本机和远程都一样的IP。

为了防止进程异常退出,可以定时运行一个SHELL脚本:

#1 使用sshpass包装器

#!/bin/bash

live=`ps -efH | grep 'sshpass' | grep -v 'grep' | wc -l`
if [ $live -eq 0 ]; then
    sshpass -p "passwd" ssh -CN -D 127.0.0.1:7070 root@x.x.x.x -p 22 2>&1 >> /dev/null
fi


#2 不使用sshpass包装器时,需要在远程服务器上设置放置好公钥
#!/bin/bash

live=`ps -efH | grep 'ssh -CN -D' | grep -v 'grep' | wc -l`
if [ $live -eq 0 ]; then
    ssh -CN -D 127.0.0.1:7070 root@x.x.x.x -p 22 2>&1 >> /dev/null
fi

本地和远程之间传输数据实际是经过加密的(走SSH),就算本机和远程是同一条机器时也是如此。本地和客户端建立的TCP是一条持久链接:

netstat -ntp

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name   
tcp        0      0 127.0.0.1:22            127.0.0.1:39426         ESTABLISHED 20575/sshd: root                    
tcp        0      0 127.0.0.1:39426         127.0.0.1:22            ESTABLISHED 20574/ssh  

客户端ssh随机打开了一个端口(39436)和远程22端口进行链接。所有从7070过来的数据,都会转发到39436端口,由它把数据发送到服务端。不过这个本地转发是透明的。到此,我们有两个结论:
一、所有的数据都是通过一条持久链接发送到远程的
二、由SSH开放的端口(这里是7070),需要HOLD住所有的链接,等到服务端返回后,再转发回去。
所以,SSH开启的代理,不适用于高并发场景。对于高并发的场景,代理需要HOLD住大量链接,然后在和服务端链接时应该一一对应,或者开一个池。但是对于一般的代理上网,是够用的。

在Windows下也有对应的工具,下载地址:http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html。这里有一个叫Plink的工具,它类似sshpass的功能:

plink.exe -C -N -D 127.0.0.1:7070 root@x.x.x.x -pw password -P 22 -v

参数C表示启用压缩,N表示不进入终端,-pw来指定密码,-P指定端口(注意这里是大写的P), -v表示实时的输出日志。使用Plink这个工具(或者Putty)也可以通过-i来指定私钥。

监控脚本,在Windows下:

:1
bin\plink.exe -C -N -D 127.0.0.1:7070 root@x.x.x.x -pw password -P 22 -v
goto 1

保存为一个bat文件,需要代理时,双击它,然后弹出一个命令行窗口,由于加了-v参数,可以实时参考输出日志(证明它是工作的),不需要时直接关闭即可。

最后就是浏览器的代理配置了(以火狐为例子):
工具 – 选项
firefox-setting

firefox-agent

看起来,虽然实现了使用SSH Socks来上网,但是还是稍有麻烦:
1 不使用代理时,需要重新进入 工具 – 选项,找到网络,然后点击不使用代理
2 每次要上网代理时,需要运行一个命令行窗口

为了解决第一个麻烦问题,我们可以在firefox中安装一个叫autoproxy的插件(也有其它类似的),安装之后浏览器上会有一个按钮,点击切换是否使用代理:
autoproxy
可以配置多个代理,方便切换:
autoproxy-switch
Autoproxy这个插件看起来从2013年开始就再没有更新了。

至于第二个问题,我们需要找到一个客户端管理工具。目前在使用的工具:
1 http://nemesis2.qx.net/pages/MyEnTunnel (需要翻墙)
下载的是一个exe安装文件,一路安装下来:
myentunnel
其中lng是语言文件,ini是配置文件,可以发现plink.exe,所以这个工具是plink.exe包装器,让使用plink.exe使用更加方便一点而已。双击myentunnel.exe:
myentunnel-setting
这里的配置跟plink.exe的命令使用是对应的。可以设置多个配置,默认的是叫default的配置,可以点击右下角的红锁(或绿锁),添加配置,这个配置实际是对应命令目录下的ini文件。看来,配置无法删除,只能到文件夹里面删除对应的文件。

可以把这个文件夹拷贝下来。

2 另一个可用的工具是Bitvise Tunnelier,它不是plink.exe的包装器,可以互联网搜索看看。