使用 CentOS 实现小型网络路由 – 跨过长城

跨长城有很多种方法,这里还是使用比较常用的 Shadowsocks 配合上一篇中使用 CentOS 搭建的软路由来实现透明翻墙。

PS:由于发现访问国外网站速度平均不如使用代理后访问的速度,于是直接使用了暴力的 GeoIP 指定非 CN IP 直接通过本地代理访问。

本篇需用到的组件(解决 DNS 污染问题以及提供代理通道):

  • 上篇中配置 CentOS 中所包含的 Dnsmasq, iptables 等组件
  • pdnsd: 提供 TCP查询 获得可靠清洁的 DNS 记录。这个工具很久没有维护了,然而在  TCP 查询 DNS 时候,自己测试结果要快于 unbound 之类。当然使用 ss-tunnel 来转发 DNS 亦可,只是这边环境对 UDP 不友好,就没采用
  • ChinaDNS: 清洗被污染的 DNS 记录
  • dnsmasq-china-list: 国内域名列表,指定国内域名直接通过国内 DNS 进行解析,缓解 CDN 问题
  • Shadowsocks-libev: 包含多个组件,我们用 ss-redir 来实现重定向

安装配置 pdnsd

于其官方页面获得 x86_64平台的下载地址
使用 curl 下载
1
curl -O http://members.home.nl/p.a.rombouts/pdnsd/releases/pdnsd-1.2.9a-par_sl6.x86_64.rpm
yum 本地安装
1
yum localinstall pdnsd-1.2.9a-par_sl6.x86_64.rpm
编辑其配置文件
1
vi /etc/pdnsd.conf
参考配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
global {
perm_cache=0; #关闭 pdnsd 的缓存
cache_dir="/var/cache/pdnsd";
run_as="pdnsd";
server_ip = 127.0.0.1; #监听本地
server_port = 53535; #监听本地 53535 端口,注意错开 Dnsmasq, ChinaDNS 的端口
status_ctl = on;
query_method=tcp_only; #修改为仅通过 TCP 查询
min_ttl=15m; # Retain cached entries at least 15 minutes.
max_ttl=1w; # One week.
timeout=10; # Global timeout option (10 seconds).
neg_domain_pol=on;
udpbufsize=1024; # Upper limit on the size of UDP messages.
}
server {
label= "opendns";
ip = 208.67.220.220, 208.67.222.222; #上级 DNS 地址,需为国外支持 TCP 查询且无污染投毒的 DNS
reject = 208.69.32.0/24, # You may need to add additional address ranges
208.69.34.0/24, # here if the addresses of their search engines
208.67.219.0/24, # change.
208.67.217.0/24,
208.67.216.0/24;
reject_policy = fail;
port = 443; #上级 DNS 端口,这里使用 tcp 查询配合 443 端口
timeout=4; #查询超时
uptest=ping;
interval=10m;
purge_cache=off;
edns_query=yes;
}
server {
label= "v2ex";
ip = 199.91.73.222; #V2EX 只有這個地址有非標準端口所以單獨放出來
port = 3389; #指定支持的非標準端口
timeout=4;
uptest=ping;
ping_timeout = 100;
interval=10m;
purge_cache=off;
edns_query=off;
}

启动&开机自启
1
2
systemctl start pdnsd
systemctl enable pdnsd
验证 pdnsd 正常工作(可查询且无投毒)
1
dig @127.0.0.1 google.com -p53535

qq%e6%88%aa%e5%9b%be20161126232539

安装配置 ChinaDNS

本示例中 ChinaDNS 路径: /usr/local/other/chinadns-1.3.2

参照其官方 Github 中 Linux/Unix 的安装方法

下载源码到本地,编译
1
2
mkdir -p /usr/local/other/chinadns-1.3.2 && cd /usr/local/other/chinadns-1.3.2
./configure && make
替换 IP 黑名单

其自带一个 IP 黑名单(iplist.txt),以及一个 中国区 IP 列表 (chnroute.txt ),我们这里将其 chnroute 替换为 ipdeny 提供的最新 list

1
curl http://www.ipdeny.com/ipblocks/data/aggregated/cn-aggregated.zone > ipdeny-cn.txt
尝试启动 ChinaDNS

本示例监听了 5353 端口,加载黑名单,国内IP名单,开启压缩指针,并指定 180.76.76.76 (百度 DNS)为国内 DNS,127.0.0.1:53535 (之前配置的pdnsd)为国外 DNS,并且开启 verbose 调试,运行于后台

1
/usr/local/bin/chinadns -l /usr/local/other/chinadns-1.3.2/iplist.txt -p 5353 -c /usr/local/other/chinadns-1.3.2/ipdeny-cn.txt -s 180.76.76.76,127.0.0.1:53535 -d -m -v &
验证其正常工作(正常返回 pass 结果)
1
dig @127.0.0.1 google.com -p5353
结束调试并添加至开机自启
1
2
killall chinadns
echo "nohup /usr/local/bin/chinadns -l /usr/local/other/chinadns-1.3.2/iplist.txt -b 127.0.0.1 -p 5353 -c /usr/local/other/chinadns-1.3.2/ipdeny-cn.txt -s 180.76.76.76,127.0.0.1:53535 -d -m -v > /var/log/user/chinadns 2>&1 &" >> /etc/rc.local

记得如果时第一次启用 rc.local 先

1
chmod +x /etc/rc.local

配置 Dnsmasq

按照上一章配置
添加 dnsmasq-china-list 加速国内解析,并解决部分 CDN 问题
1
2
curl https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/accelerated-domains.china.conf > /etc/dnsmasq.d/accelerated-domains.china.conf
curl https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/bogus-nxdomain.china.conf > /etc/dnsmasq.d/bogus-nxdomain.china.conf
重新加载 Dnsmasq

会自动载入 /etc/dnsmasq.d 目录的配置文件

qq%e6%88%aa%e5%9b%be20161124205634

测试 Dnsmasq
1
dig @127.0.0.1 google.com

qq%e6%88%aa%e5%9b%be20161124204706

安装配置 Shadowsocks-libev

参考其官方 Github 得知,RHEL/CentOS 安装可通过实现
1
2
3
4
curl https://copr.fedorainfracloud.org/coprs/librehat/shadowsocks/repo/epel-7/librehat-shadowsocks-epel-7.repo > /etc/yum.repos.d/librehat-shadowsocks-epel-7.repo
yum update
yum install shadowsocks-libev

使用 ss-redir 监听本地端口
1
nohup /usr/bin/ss-redir -s {SS服务器地址} -p {SS服务器端口} -l {本地监听端口} -k {SS密钥} -m aes-256-cfb -b 0.0.0.0 -v > /var/log/user/ss-redir 2>&1 &
添加至开机自启
1
echo "nohup /usr/bin/ss-redir -s {SS服务器地址} -p {SS服务器端口} -l {本地监听端口} -k {SS密钥} -m {SS加密方式} -b 0.0.0.0 -v > /var/log/user/ss-redir 2>&1 &" > /etc/rc.local

qq%e6%88%aa%e5%9b%be20161124205514

安装 xtables-addons(GeoIP 模块)

先直接使用 yum 安装必要组件
1
2
3
yum install xtables-addons
yum install kernel-devel-`uname -r` iptables-devel kernel-headers-`uname -r`
yum install gcc gcc-c++ make automake unzip zip perl perl-Text-CSV_XS xz
下载 addons 源码包并解压
1
2
3
curl -O http://downloads.sourceforge.net/project/xtables-addons/Xtables-addons/xtables-addons-2.10.tar.xz
tar -xvf xtables-addons-2.10.tar.xz
cd xtables-addons-2.10
由于 CentOS-xtables 兼容性问题,修改编译设置,注释以下两行
1
vi mconfig
1
2
#build_SYSRQ=m
#build_length2=m

qq%e6%88%aa%e5%9b%be20161124205258

编译
1
2
./configure
make && make install
完成后,进入源码包下 geoip 目录,下载地理 IP 包
1
2
3
cd geoip
./xt_geoip_dl
./xt_geoip_build *.csv
完成后复制 BE LE 两个目录至指定路径,GeoIP 模块配置完成
1
2
mkdir -p /usr/share/xt_geoip/
cp -r {BE,LE} /usr/share/xt_geoip/

配置 iptables,实现流量转发

配置示例

若应用 geoip 行时出现找不到 chain 错误,说明 geoip 模块安装不正确

1
2
3
4
5
6
7
8
9
10
11
12
iptables -t nat -N SHADOWSOCKS #新建 iptables NAT链,名为 SHADOWSOCKS
iptables -t nat -A SHADOWSOCKS -d {SS服务器IP地址}/32 -j RETURN #例外 SS 服务器的 IP,不通过代理
iptables -t nat -A SHADOWSOCKS -d 0.0.0.0/8 -j RETURN #保留 IP 地址段
iptables -t nat -A SHADOWSOCKS -d 10.0.0.0/8 -p tcp -j RETURN #A类 IP 地址段
iptables -t nat -A SHADOWSOCKS -d 127.0.0.1/8 -p tcp -j RETURN #保留 IP 地址段
iptables -t nat -A SHADOWSOCKS -d 169.254.0.0/16 -p tcp -j RETURN #保留 IP 地址段
iptables -t nat -A SHADOWSOCKS -d 172.16.0.0/12 -p tcp -j RETURN #B类 IP 地址段
iptables -t nat -A SHADOWSOCKS -d 192.168.0.0/16 -p tcp -j RETURN #C类 IP 地址段
iptables -t nat -A SHADOWSOCKS -d 224.0.0.0/4 -j RETURN #保留 IP 地址段
iptables -t nat -A SHADOWSOCKS -d 240.0.0.0/4 -j RETURN #保留 IP 地址段
iptables -t nat -A SHADOWSOCKS -p tcp -m geoip ! --dst-cc CN -j REDIRECT --to-ports 1080 #指定余下并且非CN的流量 重定向至本地 1080 端口(ss-redir 监听端口)
iptables -t nat -A PREROUTING -p tcp -j SHADOWSOCKS #应用SHADOWSOCKS链

qq%e6%88%aa%e5%9b%be20161124204739

尝试访问墙外网站,成功则 IP 显示为 SS 的出口 IP

qq%e6%88%aa%e5%9b%be20161124204536

保存 iptables 规则
1
iptables-save > /etc/sysconfig/iptables

qq%e6%88%aa%e5%9b%be20161124204640

Done!