首先安装好shadowsocks-libev
Raspbian里,直接通过apt安装即可:
apt install shadowsocks-libev
安装ChinaDNS
wget https://github.com/shadowsocks/ChinaDNS/releases/download/1.3.2/chinadns-1.3.2.tar.gz
tar zxvf chinadns-1.3.2.tar.gz
cd chinadns-1.3.2/
./configure
make && make install
mkdir /etc/chinadns/
cp -af chnroute.txt /etc/chinadns/
安装dnsmasq
apt install dnsmasq
安装ipset
apt install ipset`
安装haveged
也可以安装 rng-utils/rng-tools
可选:保证系统可以提供足够的熵来生成高质量随机数.
否则ss-redir/ss-tunnel 可能无法启动
配置ss-redir
cat > /etc/shadowsocks-libev/config-redir.json <<EOF
{
"server":"at.kuleyang.cn",
"server_port":9443,
"password":"yourserverpass",
"timeout":600,
"method":"aes-256-cfb",
"local_address":"0.0.0.0",
"local_port": "60080",
"no_delay": true,
"fast_open": true,
"reuse_port": true,
"mode": "tcp_and_udp"
}
EOF
ss-redir -c /etc/shadowsocks-libev/config-redir.json
配置ss-tunnel
cat > /etc/shadowsocks-libev/config-tunnel.json <<EOF
{
"server":"at.kuleyang.cn",
"server_port":9443,
"password":"yourserverpass",
"method":"aes-256-cfb",
"local_address": "0.0.0.0",
"local_port": "60053",
"tunnel_address": "8.8.8.8:53",
"no_delay": true,
"reuse_port": true,
"mode": "tcp_and_udp"
}
EOF
ss-tunnel -c /etc/shadowsocks-libev/config-tunnel.json
配置ChinaDNS
chinadns -b '127.0.0.1' -p '65353' -s '114.114.114.114,127.0.0.1:60053' -c /etc/chinadns/chnroute.txt -m
配置dnsmasq
server=127.0.0.1#65353
配置ipset
# 获取大陆地址段
curl -4skL http://f.ip.cn/rt/chnroutes.txt | egrep -v '^\s*$|^\s*#' > chnip.txt
# 添加 chnip 表
ipset -N chnip hash:net
cat chnip.txt | xargs -n1 echo add chnip > chnip.ipset
ipset -R < chnip.ipset
# 持久化 chnip 表
ipset -S chnip > /etc/ipset.chnip
配置iptables
# 新建 mangle/SS-UDP 链,用于透明代理内网 udp 流量
iptables -t mangle -N SS-UDP
# 放行保留地址、环回地址、特殊地址
iptables -t mangle -A SS-UDP -d 0/8 -j RETURN
iptables -t mangle -A SS-UDP -d 10/8 -j RETURN
iptables -t mangle -A SS-UDP -d 127/8 -j RETURN
iptables -t mangle -A SS-UDP -d 169.254/16 -j RETURN
iptables -t mangle -A SS-UDP -d 172.16/12 -j RETURN
iptables -t mangle -A SS-UDP -d 192.168/16 -j RETURN
iptables -t mangle -A SS-UDP -d 224/4 -j RETURN
iptables -t mangle -A SS-UDP -d 240/4 -j RETURN
# 放行发往 ss 服务器的数据包,注意替换为你的服务器IP
iptables -t mangle -A SS-UDP -d 服务器IP -j RETURN
# 放行大陆地址
iptables -t mangle -A SS-UDP -m set --match-set chnip dst -j RETURN
# 重定向 udp 数据包至 60080 监听端口
iptables -t mangle -A SS-UDP -p udp -j TPROXY --tproxy-mark 0x2333/0x2333 --on-ip 127.0.0.1 --on-port 60080
# 内网 udp 数据包流经 SS-UDP 链
iptables -t mangle -A PREROUTING -p udp -s 192.168/16 -j SS-UDP
# 新建 nat/SS-TCP 链,用于透明代理本机/内网 tcp 流量
iptables -t nat -N SS-TCP
# 放行环回地址,保留地址,特殊地址
iptables -t nat -A SS-TCP -d 0/8 -j RETURN
iptables -t nat -A SS-TCP -d 10/8 -j RETURN
iptables -t nat -A SS-TCP -d 127/8 -j RETURN
iptables -t nat -A SS-TCP -d 169.254/16 -j RETURN
iptables -t nat -A SS-TCP -d 172.16/12 -j RETURN
iptables -t nat -A SS-TCP -d 192.168/16 -j RETURN
iptables -t nat -A SS-TCP -d 224/4 -j RETURN
iptables -t nat -A SS-TCP -d 240/4 -j RETURN
# 放行发往 ss 服务器的数据包,注意替换为你的服务器IP
iptables -t nat -A SS-TCP -d 服务器IP -j RETURN
# 放行大陆地址段
iptables -t nat -A SS-TCP -m set --match-set chnip dst -j RETURN
# 重定向 tcp 数据包至 60080 监听端口
iptables -t nat -A SS-TCP -p tcp -j REDIRECT --to-ports 60080
# 本机 tcp 数据包流经 SS-TCP 链
iptables -t nat -A OUTPUT -p tcp -j SS-TCP
# 内网 tcp 数据包流经 SS-TCP 链
iptables -t nat -A PREROUTING -p tcp -s 192.168/16 -j SS-TCP
# 内网数据包源 NAT
iptables -t nat -A POSTROUTING -s 192.168/16 ! -d 192.168/16 -j MASQUERADE
# 持久化 iptables 规则
iptables-save > /etc/iptables.tproxy
本机只基于白名单,内网基于黑名单的国内外分流(TCP_ONLY)
#清空iptables nat表
iptables -F -t nat
iptables -X -t nat
iptables -Z -t nat
iptables -F -t mangle
iptables -X -t mangle
iptables -Z -t mangle
# 新建 mangle/SS-UDP 链,用于透明代理内网 udp 流量
iptables -t mangle -N SS-UDP
# 放行保留地址、环回地址、特殊地址
iptables -t mangle -A SS-UDP -d 0/8 -j RETURN
iptables -t mangle -A SS-UDP -d 10/8 -j RETURN
iptables -t mangle -A SS-UDP -d 127/8 -j RETURN
iptables -t mangle -A SS-UDP -d 169.254/16 -j RETURN
iptables -t mangle -A SS-UDP -d 172.16/12 -j RETURN
iptables -t mangle -A SS-UDP -d 192.168/16 -j RETURN
iptables -t mangle -A SS-UDP -d 224/4 -j RETURN
iptables -t mangle -A SS-UDP -d 240/4 -j RETURN
# 放行发往 ss 服务器的数据包,注意替换为你的服务器IP
iptables -t mangle -A SS-UDP -d 74.120.169.48 -j RETURN
# 放行大陆地址
iptables -t mangle -A SS-UDP -m set --match-set chnip dst -j RETURN
# 重定向 udp 数据包至 60080 监听端口
iptables -t mangle -A SS-UDP -p udp -j TPROXY --tproxy-mark 0x2333/0x2333 --on-ip 127.0.0.1 --on-port 60081
# 内网 udp 数据包流经 SS-UDP 链
iptables -t mangle -A PREROUTING -p udp -s 192.168/16 -j SS-UDP
# 新建 nat/SS-TCP 链,用于透明代理内网 tcp 流量(黑名单+国内外分流)
iptables -t nat -N SS-TCP
# 放行环回地址,保留地址,特殊地址
iptables -t nat -A SS-TCP -d 0/8 -j RETURN
iptables -t nat -A SS-TCP -d 10/8 -j RETURN
iptables -t nat -A SS-TCP -d 127/8 -j RETURN
iptables -t nat -A SS-TCP -d 169.254/16 -j RETURN
iptables -t nat -A SS-TCP -d 172.16/12 -j RETURN
iptables -t nat -A SS-TCP -d 192.168/16 -j RETURN
iptables -t nat -A SS-TCP -d 224/4 -j RETURN
iptables -t nat -A SS-TCP -d 240/4 -j RETURN
# 放行发往 ss 服务器的数据包,注意替换为你的服务器IP
iptables -t nat -A SS-TCP -d 74.120.169.48 -j RETURN
# 放行大陆地址段
iptables -t nat -A SS-TCP -m set --match-set chnip dst -j RETURN
# 重定向 tcp 数据包至 60080 监听端口
iptables -t nat -A SS-TCP -p tcp -j REDIRECT --to-ports 60080
# 将内网数据包流经 SS-TCP 链
iptables -t nat -A PREROUTING -p tcp -j SS-TCP
# 新建 nat/SS-TCP-LOCAL 链,用于透明代理本机 tcp 流量 (白名单)
iptables -t nat -N SS-TCP-LOCAL
# 重定向 tcp 数据包至 60080 监听端口
iptables -t nat -A SS-TCP-LOCAL -p tcp -j REDIRECT --to-ports 60080
# 本机 tcp 数据包流经 SS-TCP 链
iptables -t nat -A OUTPUT -p tcp -d 209.95.56.60/32 -j SS-TCP-LOCAL
iptables -t nat -A OUTPUT -p tcp -d 173.244.217.42/32 -j SS-TCP-LOCAL
iptables -t nat -A OUTPUT -p tcp -m owner --uid-owner 1001 -j SS-TCP
iptables -t nat -A OUTPUT -p tcp -d 8.8.8.8/32 -j SS-TCP-LOCAL
# 内网NAT
iptables -t nat -A POSTROUTING -s 192.168/16 ! -d 192.168/16 -j MASQUERADE
# strongswan VPN
iptables -t nat -A POSTROUTING -o eth0 ! -p esp -s 192.168.2/24 ! -d 192.168.2/24 -j SNAT --to-source 192.168.1.118
iptables-save > /etc/iptables
加条路由
# 新建路由表 100,将所有数据包发往 loopback 网卡
ip route add local 0/0 dev lo table 100
# 添加路由策略,让所有经 TPROXY 标记的 0x2333/0x2333 udp 数据包使用路由表 100
ip rule add fwmark 0x2333/0x2333 table 100
# 立即生效
ip route flush cache
# 删除
ip rule show | grep "fwmark 0x2333/0x2333" | awk -F':' '{print $1}' | xargs -n1 ip rule del pref &> /dev/null
ip route flush table 100
dns-forwarder 通过 TCP 查询 8.8.8.8 作为 ChinaDNS 的 上游 替代 ss-tunnel 使用 UDP 查询 8.8.8.8 的旧方案
GFW 干扰 UDP 丢包较严重
安装配置dnsforwarder
## 获取 dnsforwarder 源码
git clone https://github.com/holmium/dnsforwarder.git
## 编译 dnsforwarder
cd dnsforwarder/
./configure
make && make install
## 初始化 dnsforwarder (仅限"手动部署")
dnsforwarder -p
cp -af default.config ~/.dnsforwarder/config
## ~/.dnsforwarder/config 配置文件
#### 日志相关 ####
LogOn true # 启用日志
LogFileThresholdLength 5120000 # 日志大小临界值,大于该值则将原文件备份,使用新文件记录日志
LogFileFolder /var/log/ # 日志文件所在的文件夹
#### 监听地址 ####
UDPLocal 0.0.0.0:12345 # 可以有多个,使用逗号隔开,默认端口53
#### 上游dns ####
TCPGroup 8.8.8.8 * 127.0.0.1 # google 作为上游 dns 服务器
BlockNegativeResponse true # 过滤上游 dns 未成功的响应
#### hosts文件 ####
Hosts file:///etc/hosts # 本机 hosts 文件路径
HostsUpdateInterval -1 # 运行期间不重载 hosts
#### dns缓存 ####
UseCache true # 启用缓存(文件缓存)
MemoryCache false # 不使用内存缓存
CacheSize 30720000 # 缓存大小,不能小于 102400
IgnoreTTL true # 忽略 TTL 值
CacheControl iok.la nocache # 不缓存以 'iok.la' 结尾的域名
ReloadCache true # 启动时加载已有的文件缓存
OverwriteCache true # 当已有的文件缓存载入失败时,覆盖原文件
++++++++++++++++++ config ++++++++++++++++++
## 后台运行 dnsforwarder
dnsforwarder -d
测试dns解析
dig @127.0.0.1 -p12345 www.twitter.com
dig @127.0.0.1 -p53 www.twitter.com
dig @127.0.0.1 -p65353 www.twitter.com
## 再使用 OpenDNS 443/udp 端口进行 dns 解析
dig @208.67.222.222 -p443 www.twitter.com
开机启动自动加载所有配置
cat >> /etc/rc.local <<EOF
ipset -R < /etc/ipset.chnip
iptables-restore < /etc/iptables
EOF
//手动更新国内IP段
wget -O- 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest' | awk -F\| '/CN\|ipv4/ { printf("%s/%d\n", $4, 32-log($5)/log(2)) }' > /tmp/chinadns_chnroute.txt
//ipv6
wget -O- 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest' | awk -F\| '/CN\|ipv6/ { printf("%s/%d\n", $4, $5) }' > /tmp/chinadns_chnroute6.txt
原理图: