「在Linux中,配置Shadowsocks系统(全局)代理」

  CREATED BY JENKINSBOT

Shadowsocks使用SOCKS5协议中的客户端。

在Windows中,启动Shadowsocks客户端(shadowsocks-windows)后,应用程序(浏览器等)不需要进行特殊配置,只需要在Shadowsocks客户端中「启动系统代理」,选择「系统代理模式」,就可以实现全局的代理(或PAC模式),即每个应用程序都可以通过代理上网。当然它也可以监听本地端口。

在Linux中,就会麻烦一点。Linux中Shadowsocks客户端(shadwosocks-qt5)并没有系统代理的功能。虽然Linux中由很多Shadowsocks客户端的实现,但是它们都不支持系统代理功能。这就导致了浏览器中需要进行单独的配置,比如需要使用SwitchyOmega插件,或者在浏览器的设置中进行配置PAC或SOCKS;某些应用程序(比如Wget,cURL等等)中需要配置环境变量(HTTP_PROXY,HTTPS_PROXY)来使用代理;还有一些应用程序有自己的配置方式,比如 Git,git config --global http.proxy 'socks5://127.0.0.1:7070

本文主要内容就是围绕Linux,介绍其中Shadowsocks系统代理的配置方式。但是其实根本不敢说是“系统代理”,因为有些方法也算不上系统代理,各种方法都有其局限性。本文也尝试找出一种Once For All的解决方案。本文参考了互联网上的其他博客,并且标注了出处,侵删。

解决方案

顺便说一句,在Linux中,如果需要“全局模式”,则需要自己进行配置,配置方法参考「Shadowsocks + ChnRoute 实现 OpenWRT / LEDE 路由器自动翻墙」一文,思路是类似的。

方法一、依赖于应用程序的支持

该方法需要被代理的应用程序本身支持SOCKS5代理。比如,Git、cUrl。

Git中,如果你要使用SOCKS代理,需要执行:

# git config --global http.proxy 'socks5://127.0.0.1:7070'

其中,127.0.0.1:7070是SOCKS5客户端的套解字。

cURL中,其实cURL本身就支持SOCKS5协议:

# curl -m 30 --retry 3 --socks4 101.255.17.145:1080 http://www.google.com

当然,cURL也支持SOCKS4协议。

但是,Wget就比较惨了,Wget不支持SOCKS5协议。官方的手册里连个“socks”关键字都搜索不到,也不用仔细去看了,基本上可以断定Wget不支持SCOKS5了。如果你想让类似于Wget这种终端应用程序使用SOCKS5代理,可能需要使用TSOCKS,ProxyChains之类的代理程序了,在终端执行tsocks wget http://www.google.com/whatever,后面会介绍到。或者使用SSH到代理服务器上执行命令以取回输出,比如ssh address-of-B ‘wget -O – http://server-C/whatever’ >> whatever,这些用法都太冷门了。

在Chromium和Firefox中,你可以使用SwitchyOmega插件,这里不再展开介绍了。

存在的问题及不足
这种方法过于依赖应用程序,而且非常麻烦,需要应用程序的支持。而且每种程序的使用方式又有所不同,这附带里学习成本。不是很好操作,你要说用在脚本程序里,还可以,毕竟使用脚本只在编写脚本、测试脚本的时候麻烦一次。

方法二、Polipo + Shadowsocks

使用这种方法,除了运行SOCKS5客户端以外,还要运行Polipo服务。Polipo是个什么呢?它是一个Web代理。

该方法就是在被代理程序和SOCKS5客户端中间又加了一个代理中间件,该代理中间件用于把SOCKS5代理转换成HTTP代理。流程如下:

Applications -> Polipo -> SOCKS5 Client -> SCOKS5 Server

简单的说就是上面那么回事。但是,访问Polipo官网后,看到的第一句话就是:Polipo is no longer maintained

反正,我不推荐这种方式。如果你坚持要使用这种方式可以参考「Ubuntu server命令行配置shadowsocks全局代理」这篇文章。

总的来说Polipo配置完之后,在其正常运行后,你只是多了一个HTTP代理。[手动耸肩]

方法三、算是「系统代理」的一种方式

这种方法与GNOME桌面环境有关,其他桌面环境应该也可以使用这种方法。参考了「shadowsocks 实现全局代理」和「set shadowsocks proxy for Ubuntu , desktop and terminal . It’s useful in China」这两篇文章。本部分主要以GNOME桌面环境为主。

在终端执行gnome-control-center,以打开GNOME的控制中心,或者在菜单里打开系统设置(System Settings),随便你怎么打开。然后选择「Network」,设置「Network Proxy」,在弹出窗口中选择「Automatic」,然后在「Configuration URL」中填入PAC文件的URI地址,下面会介绍到哪里找这个PAC文件地址。这个Configuration URL这个输入框中既可以填写网址(http//:example.com/whatever.pac),也可以填写本地文件地址(file:///etc/whatever.pac)。

去哪里弄这个PAC文件的URL呢?略略略~使用genpac命令自己生成,有个文件叫gwflist.txt,执行下面的命令:

genpac -p "SOCKS5 127.0.0.1:24098" --gfwlist-proxy="SOCKS5 127.0.0.1:24098" \
	--output="autoproxy.pac" --gfwlist-url="https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt"

该命令会在当前目录下生成一个名为autoproxy.pac的PAC文件。本质上讲,PAC文件就是一个JS文件。关于genpac的使用方法本文不展开介绍,国人写的,中文手册。genpac可以通过pip进行安装(pip install genpac)。

然后在Configuration URL中填入这个PAC文件的路径file:///path/to/autoproxy.pac,比如file:///tmp/autoproxy.pac

保存退出就可以了。然后你的火狐浏览器就可以通过代理上网了。

咦?我为什么说火狐浏览器? Chromium 呢?

因为的Chromium压根不吃你这套。在我的环境里无法通过代理上网,我目前的桌面环境不是GNOME,但是你说如果是环境的问题,那Firefox也应该不好用啊。手册的Network Settings部分中说Chromium网络栈使用系统的网络设置。它也提供了一些代理设置的选项,文档中也说了是更具用户的要求加入了这些相关选项。话说如果我需要通过这些选项设置代理,那还用GNOME的网络设置有什么用,还系统代理个什么。可以像下面这种方式直接使用SOCKS5代理,或者使用PAC文件:

# google-chrome –proxy-server=”socks5://127.0.0.1:1080″

# chromium –proxy-pac-url=file:///tmp/autoproxy.pac

即使是Firefox,也要在其设置中选择的「General」->「Network Proxy」->「Settings」->「Configure Proxy Access to the Internet」->「Use system proxy settings」才行。顺便说一句,「Configure Proxy Access to the Internet」->「Automatic proxy configuration URL」也可以使用上面的那个名为autoproxy.pac的PAC文件。

注意事项
如果你的桌面环境不是GNOME,那么在启动gnome-control-center时,界面中可能没有任何选项,执行如下命令来启动gnome-control-center:

# env XDG_CURRENT_DESKTOP=GNOME gnome-control-center

而且,我也不打算使用这种代理方式,因为终端应用程序无法使用这种代理方式,这种代理只能代理一些桌面应用程序。

方法四、iptables + ss-redir

这可以说是一个令人满意的方案了。但依旧存在其他问题。

iptables是防火墙;ss-redir是Shadowsocks软件包中的一个命令,但是这里的“Shadowsocks软件包”指的是使用libev库的C语言实现的Shadowsocks-libev

配置方法参考「tossmilestone/linux-shadows-global.sh」和「Linux Shadowsocks 全局代理

方法五、使用OpenVPN

使用OpenVPN已经脱离了本文的主题,但仍然值得一提。本文不会介绍OpenVPN的搭建方法,但是会对OpenVPN进行简单的说明。

OpenVPN是一个基于SSL加密的纯应用层VPN协议,是SSL VPN的一种,支持UDP与TCP两种通讯方式。UDP和TCP是2种通讯协议,通常UDP的效率会比较高,速度也相对较快,所以尽量使用UDP连接方式,实在UDP没法使用的时候,再使用TCP连接方式。在选择协议时候,需要注意2个加密隧道之间的网络状况,如有高延迟或者丢包较多的情况下,请选择TCP协议作为底层协议,UDP协议由于存在无连接和重传机制,导致要隧道上层的协议进行重传,效率非常低下。

其次,最重要的是由于OpenVPN运行在纯应用层(TCP/IP模型的应用层,或者说OSI模型的会话层),与SOCKS协议的工作层相同,而且两者的载荷都是加密的,无确定性特征。因此可以绕过一些网络的封锁,同时避免出现PPTP和L2TP在某些NAT设备后面不被支持的情况。但也因此从速度上来讲会稍微的慢一些,但也不时绝对的,这里不再展开介绍。

注意事项

不接受任何类似于“你行你上啊”之类的说法。下次你说“鸡蛋不新鲜不好吃”的时候,你一定要自己下一个好吃的。

参考文献

Linux Shell curl 和 wget 使用代理IP
How to invoke a command using specific proxy server?
How to download a file through an SSH server?
Socks5 proxy and wget
Ubuntu server命令行配置shadowsocks全局代理
gnome-control-center-3.26.1-1 is empty !
Network Settings – The Chromium Projects
How to Configure Proxy for Chromium and Google Chrome From Command Line on Linux
ubuntu基于shadowsocks的PAC全局代理:解决方案
shadowsocks/shadowsocks-qt5/使用手册#全局代理
ArchLinux/Proxy settings
Shadowsocks proxy and ssh proxy
Ubuntu下使用shadowsocks-qt5实现全局代理