首先,我这里的全局智能代理实现的功能主要有以下几点:

  1. 基于iptables的全局代理,在Linux下可以实现只需设置一次,所有的软件(无论是GUI还是CLI)都可以免设置自动使用这个代理。
  2. 基于ipset,加入所有的国内IP项,对所有tcp流量进行判断,避免对国内的服务进行代理,一方面可以节省服务器流量,另一方面可以享受国内ip的优势,比如国内的版权视频、音乐,最后,避免被国内一些和政府有合作的IT企业发现你使用了代理。
  3. iptables把需要代理的tcp流量交给shadowsocks-libev中的ss-redir,让它与代理服务器通讯。

让我们开始吧,在最开始,首先要说明的是:这份教程只适用于想要让你的Linux设备使用代理的用户,同时,下文的所有内容假设你运行的是Arch Linux。

设置 iptables

首先,在/etc/iptables目录下创建一份新的规则:

# Transparent SOCKS proxy

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:REDSOCKS - [0:0]

# Redirect all output through redsocks
-A OUTPUT -p tcp -j REDSOCKS

# Whitelist LANs and some other reserved addresses.
# https://en.wikipedia.org/wiki/Reserved_IP_addresses#Reserved_IPv4_addresses
-A REDSOCKS -d 0.0.0.0/8 -j RETURN
-A REDSOCKS -d 10.0.0.0/8 -j RETURN
-A REDSOCKS -d 127.0.0.0/8 -j RETURN
-A REDSOCKS -d 169.254.0.0/16 -j RETURN
-A REDSOCKS -d 172.16.0.0/12 -j RETURN
-A REDSOCKS -d 192.168.0.0/16 -j RETURN
-A REDSOCKS -d 224.0.0.0/4 -j RETURN
-A REDSOCKS -d 240.0.0.0/4 -j RETURN

# whitelist China ip.
-A REDSOCKS -p tcp -m set --match-set china dst -j RETURN
# import shadowsocks server ip
-A REDSOCKS -d xxx.xxx.xxx.xxx -j RETURN
# shadowsocks server port
#-A REDSOCKS -p tcp --dport xxxx -j RETURN

# Redirect everything else to redsocks port
-A REDSOCKS -p tcp -j REDIRECT --to-ports 1081

COMMIT

这份配置文件的主要功能是,把所有的tcp流量(不包括一些保留的ip段,包括局域网网段;使用ipset存储的所有中国ip段,关于ipset后文讲;代理服务器自己的ip或端口,这是为了避免代理自己不要再被重定向,端口或ip选择一个就行)

然后把这份规则软链接到/etc/iptables/iptables.rules,启动iptables并设置开机启动。

sudo systemctl start iptables.service
sudo systemctl enable iptables.service

配置ipset

ipset是 Linux 防火墙iptables的一个伴随工具。它允许你建立规则来轻松愉快地屏蔽一组IP地址。 ipset可以把大量ip或ip段存储在一个set中,实际上这个set是一个高效的查询结构,搜索的逻辑依然在iptables本身,iptables会判断IP地址或者哪个别的什么字段在不在这个set中,判断的过程使用二叉树,哈希等算法因此非常高效。

依次执行一下命令。

# Destroy ipset if it already exists
sudo systemctl stop iptables.service 
sudo ipset destroy china

# Create the ipset list
sudo ipset -N china hash:net

# remove any old list that might exist from previous runs of this script
rm cn.zone

# Pull the latest IP set for China
wget -P . http://www.ipdeny.com/ipblocks/data/countries/cn.zone

# Add each IP address from the downloaded list into the ipset 'china'
# for i in $(cat ./cn.zone ); do ipset -A china $i; done

执行完成后,所有中国ip已经通过ipset保存在内存中,可以被iptable调用,参见上文中的iptables规则-A REDSOCKS -p tcp -m set --match-set china dst -j RETURN,一旦遇到tcp包,其目标地址为名为china的ipset中的ip,就直接放行。

目前创建的ipse存在于内存中,重启后将会消失。要使ipset持久化,要这样做:

# ipset save > /etc/ipset.conf

同时把ipset设置为开机启动:

sudo systemctl enable ipset.service

配置 ss-redir

在配置文件中设一个未使用的端口,我使用的是1081,在iptables的规则中与之对应-A REDSOCKS -p tcp -j REDIRECT --to-ports 1081,然后启动ss-redir:

sudo systemctl start [email protected]
sudo systemctl enable [email protected]

这样,就全部完成了。