一般来说要搭建一个本地的 socks 代理只需要简单的 ssh -D
, 就可以生成一个代理了. 这样作为零时方案挺不错的, 工作上服务器一般会被反向代理, 通过 ssh 就可以隐射到本地通过浏览器进行调试了, 但如果需要长期使用的话. 这样的方案也有不少的麻烦.
通过 ssh -D 他和服务器之间只会有一个连接, 这样网络性能上并不是最好的.
必须使用 openssh 才可以 -D, 一般路由器常用的 dropbear ssh 客户端不能使用 -D.
需要通过 autossh 自动重连, 但如果网络频繁切换(诸如 3G 和 wifi) 还需要辅助脚本来重启 autossh.
也不能提供例如用户名密码交验这样的安全认证功能.
基于以上这么多问题, 有条件的前提下还是自己在服务器端搭 socks 代理, 再通过 stunnel 或者 ssh -L 映射到本地是比较好的解决方案.
安装 socks 代理
方案上是在服务器搭建一个只能本地使用的代理, 再通过其他服务映射到本地. (这里用 danted 来搭 socks 代理. 服务器用的是 ubuntu)
apt-get install -y dante-server
安装完以后将 /etc/danted.conf
开启或加入如下配置
logoutput: syslog internal: 127.0.0.1 port = 1080 external: eth0 clientmethod: none method: none user.privileged: proxy user.notprivileged: nobody user.libwrap: nobody extension: bind connecttimeout: 30 iotimeout: 86400 client pass { from: 127.0.0.1/8 to: 127.0.0.1/8 log: connect error method: none } client block { from: 0.0.0.0/0 to: 0.0.0.0/0 method: none } pass { from: 127.0.0.1/8 to: 0.0.0.0/0 command: bind connect udpassociate log: connect error method: none } pass { from: 0.0.0.0/0 to: 127.0.0.1/8 command: bindreply udpreply log: connect error method: none } block { from: 0.0.0.0/0 to: 0.0.0.0/0 log: connect error }
按上述配置就可以搭出一个只能本地使用的 socks 代理, 接着用 service danted start
启动代理
如果出现:
Sep 17 11:15:01 (1347851701) danted[8245]: symbolfunction(): compiletime configuration error? Failed to open "libc.so": libc.so: cannot open shared object file: No such file or directory Sep 17 11:15:01 (1347851701) danted[8245]: sockdexit() Sep 17 11:15:01 (1347851701) danted[8245]: sockdexit(): terminating这样的错误还需要将 libc.so 做个软链接
ln -s /lib/x86_64-linux-gnu/libc.so.6 /lib/x86_64-linux-gnu/libc.so
服务端 stunnel 配置
stunnel 用来和客户端之间建立一条加密的链接, 这里还需要对客户端做认证, 确保只有拥有证书的客户端才可以链接. 终端输入:
apt-get install stunnel
安装好 stunnel 后还需要生成一个服务器的证书. 这里由于只用来加密通讯, 所以证书可以不用很复杂和正规.
cd /etc/stunnel mkdir -p /var/lib/stunnel4/certs ln -s /var/lib/stunnel4/certs /etc/stunnel/certs openssl req -new -x509 -days 3650 -nodes -config /usr/share/doc/stunnel4/examples/stunnel.cnf -out stunnel.pem -keyout stunnel.pem
然后再编辑 /etc/stunnel/stunnel.conf
chroot = /var/lib/stunnel4/ setuid = stunnel4 setgid = stunnel4 pid = /stunnel4.pid cert = /etc/stunnel/stunnel.pem ;key = /etc/stunnel/stunnel.pem verify = 3 CApath = /certs ; performance socket = l:TCP_NODELAY=1 [danted] accept = 1081 connect = 1080
把本地的 1080
端口映射成 1081
, 接着编辑 /etc/default/stunnel4
将其中的 ENABLED=0
修改成 ENABLED=1
然后再输入 service stunnel4 start
启动服务.
客户端 stunnel 配置
之前已经把服务器端配置完成了, 接下来需要在客户端配置 stunnel 好将端口映射到本地. 还是以 ubuntu 为例, 输入:
apt-get install stunnel
然后生成一个客户端的证书
cd /etc/stunnel openssl req -new -x509 -days 3650 -nodes -out client.pem -keyout client.pem
这里需要注意的是为了区分证书, 每个证书都需要输入对应不同的信息, 然后将生成的 client.pem
复制到服务器的 /etc/stunnel/certs
目录下, 接着需要在 服务器 输入:
cd /etc/stunnel/certs $(/usr/lib/ssl/misc/c_hash p.wido.me.pem | awk '{print "ln -s " $3 " " $1}')
stunnel 需要通过 c_hash
才能找到对应的证书.
然后在 客户端 加入配置文件 /etc/stunnel/client.conf
chroot = /var/lib/stunnel4/ setuid = stunnel4 setgid = stunnel4 pid = /stunnel4-client.pid cert = /etc/stunnel/client.pem client = yes ; performance socket = r:TCP_NODELAY=1 [danted] accept = 127.0.0.1:1080 connect = [HOST]:1081
其中的 [HOST]
为服务器的域名或者IP. 接着还是将 /etc/default/stunnel4
的 ENABLED=0
设置成 1
, 接着启动 service stunnel4 start
就可以在客户端建立出一个端口为 1080 的 socks 代理了.
最后
由于服务器配了客户端证书认证, 所以只有添加证书的用户可以连上这台服务器. 同样的方法也可以映射其他的服务, 比如 polipo
.
对于有些对 stunnel
支持不好的设备, 也可以用 ssh -L
来映射这个 1080 的端口而不用 -D 参数.