通过 ProxyChains-NG 实现终端下任意应用代理

对技巧人员shadowsocks应当不生疏,shadowsocks本质上也是一种socks5代理服务,相似于ssh代理。

与vpn的全局代理不同,shadowsocks仅针对阅读器代理,不能代理应用软件,比如curl、wget等一些命令行软件。如果要让终端下的命令行工具都能支撑代理,这时候我们就要用上proxychains-ng这款神器了。

甚么是 proxychains-ng

项目主页:https://github.com/rofl0r/proxychains-ng

proxychains-ng 介绍

proxychains ng (new generation) - a preloader which hooks calls to sockets in dynamically linked programs and redirects it through one or more socks/http proxies. continuation of the unmaintained proxychains project.

proxychains-ng是proxychains的增强版,重要有以下功效和不足:

  • 支撑http/https/socks4/socks5
  • 支撑认证
  • 远端dns查询
  • 多种代理模式
  • 不支撑udp/icmp转发
  • 少部份程序和在后台运行的可能没法代理

proxychains-ng 原理

简略的说就是这个程序 Hook 了 sockets 相干的操作,让普通程序的 sockets 数据走 SOCKS/HTTP 代理。

其核心就是应用了 LD_PRELOAD 这个环境变量(Mac 上是 DYLD_INSERT_LIBRARIES)。

在 Unix 体系中,如果设置了 LD_PRELOAD 环境变量,那末在程序运行时,动态连接器会先加载该环境变量所指定的动态库。也就是说,这个动态库的加载优先于任何其它的库,包含 libc。

ProxyChains 创立了一个叫 libproxychains4.so(Mac 上是 libproxychains4.dylib)的动态库。里面重写了 connect、close 和 sendto 等与 socket 相干的函数,通过这些函数发出的数据将会走代理,详细代码可以参考 libproxychains.c。

在主程序里,它会读取配置文件,查找 libproxychains4 所在地位,把这些信息存入环境变量后履行子程序。这模样程序里对 socket 相干的函数调用就会被 Hook 了,对子程序来讲,跟代理相干的东西都是透明的。

可以用 printenv 程序来查看增长的环境变量,在 Mac 上输出成果相似于:

1
2
3
4
5
6
7
8
9
$ proxychains4 printenv

[proxychains] config file found: /usr/local/Cellar/proxychains-ng/4.11/etc/proxychains.conf
[proxychains] preloading /usr/local/Cellar/proxychains-ng/4.11/lib/libproxychains4.dylib
[proxychains] DLL init: proxychains-ng 4.11
...
PROXYCHAINS_CONF_FILE=/usr/local/Cellar/proxychains-ng/4.11/etc/proxychains.conf
DYLD_FORCE_FLAT_NAMESPACE=1
DYLD_INSERT_LIBRARIES=/usr/local/Cellar/proxychains-ng/4.11/lib/libproxychains4.dylib

一共设置了三个环境变量,其中 PROXYCHAINS_CONF_FILE 保留的是配置文件路径,DYLD_INSERT_LIBRARIES 保留的是动态库路径,在 Mac 中,必需使DYLD_FORCE_FLAT_NAMESPACE 为 1 能力保证 DYLD_INSERT_LIBRARIES 起作用。

安装 proxychains-ng

通过源代码安装

  • 下载源码
1
$ git clone https://github.com/rofl0r/proxychains-ng
  • 编译安装
1
2
3
4
$ ./configure --prefix=/usr --sysconfdir=/etc
$ make
$ make install
$ make install-config (安装proxychains.conf配置文件)

MAC下安装

关闭 SIP

macOS 10.11 后下由于开启了 SIP(System Integrity Protection) 会致使命令行下 proxychains-ng 代理的模式失效,如果你要应用 proxychains-ng 这类简略的办法,就须要先关闭 SIP。

具体的关闭办法以下:

  • 部份关闭 SIP

重启Mac,按住Option键进入启动盘选择模式,再按⌘ + R进入Recovery模式。
适用工具(Utilities)-> 终端(Terminal)。
输入命令csrutil enable --without debug运行。
重启进入体系后,终端里输入 csrutil status,成果中如果有 Debugging Restrictions: disabled 则解释关闭胜利。

  • 完整关闭 SIP

重启Mac,按住Option键进入启动盘选择模式,再按⌘ + R进入Recovery模式。
适用工具(Utilities)-> 终端(Terminal)。
输入命令csrutil disable运行。
重启进入体系后,终端里输入 csrutil status,成果中如果有 System Integrity Protection status:disabled. 则解释关闭胜利。

安装 Proxychains-ng

安装好 Homebrew 后,终端中输入

1
$ brew install proxychains-ng

配置 proxychains-ng

proxychains-ng默许配置文件名为proxychains.conf

  • 通过源代码编译安装的默许为/etc/proxychains.conf
  • Mac下用Homebrew安装的默许为/usr/local/etc/proxychains.conf

proxychains-ng的配置非常简略,只需将代理参加[ProxyList]中便可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ vim proxychains.conf

quiet_mode
dynamic_chain
chain_len = 1 #round_robin_chain和random_chain应用
proxy_dns
remote_dns_subnet 224
tcp_read_time_out 15000
tcp_connect_time_out 8000
localnet 127.0.0.0/255.0.0.0
localnet 10.0.0.0/255.0.0.0
localnet 172.16.0.0/255.240.0.0
localnet 192.168.0.0/255.255.0.0

[ProxyList]
socks5 127.0.0.1 1086
http 127.0.0.1 1087

proxychains-ng支撑多种代理模式,默许是选择 strict_chain。

  • dynamic_chain :动态模式,依照代理列表次序主动选取可用代理
  • strict_chain :严厉模式,严厉依照代理列表次序应用代理,所有代理必需可用
  • round_robin_chain :轮询模式,主动跳过不可用代理
  • random_chain :随机模式,随机应用代理

proxychains-ng 应用

proxychains-ng 语法

proxychains-ng用法非常简略,应用格局以下:

1
$ proxychains4 程序 参数

proxychains-ng 测试

1
$ proxychains4 curl ip.cn

proxychains-ng 优化

alias

给proxychains4增长一个别号,在 /.zshrc或/.bashrc末尾参加以下行:

1
2
3
4
#   ---------------------------------------
# proxychain-ng config
# ---------------------------------------
alias pc="proxychains4"

以后便可以够相似$ pc curl http://www.google.com这样调用proxychains4,简化了输入。

主动补全

你输了很长一段命令,然后你突然想应用代理功效,怎样办?

  • iTerm中前缀补全

iTerm -> Preferences -> Profiles -> Keys 中,新建一个快捷键,例如 ⌥ + p ,Action 选择 Send Hex Code,键值为 0x1 0x70 0x63 0x20 0xd,保留生效。

以后命令要代理就直接敲命令,然后 ⌥ + p 便可,这样命令补全也能保留了。

附上 Hex Code 对应表,获得工具为keycodes(http://manytricks.com/keycodes/)

Hex CodeKey
0x1⌃ + a
0x70p
0x63c
0x20[space]
0xd↩︎
  • oh-my-zsh中前缀补全
1
2
$ git clone [email protected]:six-ddc/zsh-proxychains-ng.git ~/.oh-my-zsh/custom/plugins/zsh-proxychains-ng
$ echo "plugins+=(zsh-proxychains-ng)" >> ~/.zshrc

应用时按[ESC]-P ,主动添加(去除)proxychains4 -q命令前缀,支撑 emacs 和 vi mode 。

  • 通过代理SHELL实现全局代理

如果你还是认为每次应用都要输入proxychains4或其别号,比拟麻烦。你还可以用proxychains-ng代理一个shell,在shell中履行的命令就会主动应用代理了。

办法一

手动设置环境变量

1
2
3
$ export PROXYCHAINS_CONF_FILE=/usr/local/Cellar/proxychains-ng/4.11/etc/proxychains.conf
$ export DYLD_INSERT_LIBRARIES=/usr/local/Cellar/proxychains-ng/4.11/lib/libproxychains4.dylib
$ export DYLD_FORCE_FLAT_NAMESPACE=1

办法二

proxychains-ng直接调用SHELL

BASH

1
$ proxychains4  -q /bin/bash

ZSH

1
$ proxychains4  -q /bin/zsh

这样在当前 shell 中运行的所有程序的网络要求都会走代理了。可以把上面的命令参加到用户目录的.bashrc或.zshrc中,用户登录后主动代理一个shell,这就相似一个全局代理了。在这个SHELL下的所有命令都可以应用代理了。

参考文档

http://www.google.com
http://t.cn/R4tiUB1
http://t.cn/Rxg7oJR
http://t.cn/RG1Hbs3