Total Pageviews

Saturday, 24 October 2020

在linux桌面系统上,使用ss-redir作全局代理

 

首先安装好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":"vps-public-ip",
    "server_port":9443,
    "password":"your_pass",
    "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":"vps-public-ip",
    "server_port":9443,
    "password":"your_pass",
    "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

原理图:

------------------------------------------------------------

ss-redir做透明代理(ipset方式)

详见https://briteming.blogspot.com/2019/08/linuxss-tproxy.html

------------------------------------------------------------

ss-redir+dnsmasq+iptables 透明代理(非ipset方式)

环境: 树莓派一个, 路由器, 境外vps。

原理; 数据发起—-路由器—dns(树莓派)–iptables局域网放行–dnsmasq查询真实并缓存–局域网iptables放行—-路由器—网关(树莓派)—iptables过滤国内直接放行,国外数据打包socks5走本地1080端口外出。 

A。安装shadowsocks

git clone https://github.com/shadowsocks/shadowsocks-libev
cd shadowsocks-libev

安装编译环境

sudo apt-get install build-essential autoconf libtool libssl-dev gawk debhelper dh-systemd init-system-helpers pkg-config

树莓派这里会出问题,没法安装dh-systemd这里直接编译安装

./configure–prefix=/usr/local/shadowsocks
make && make install
ln -s /usr/local/shadowsocks/bin/ss-redir ss-redir

生成deb包

dpkg-buildpackage -us -uc -i

安装刚生成的deb包,在github主页上有介绍。这里是debian安装的过程编译好的deb,及其他配置文件

sudo dpkg -i shadowsocks-libev*.deb

使用ss-redir -c /etc/redir.json   这里local_adress必须写0.0.0.0,127.0.0.1会出问题

{  
“server”:”服务器地址”,  
“server_port”:服务器开放的端口,  
“local_address”:”0.0.0.0″,  
“local_port”:本地端口,  
“password”:”密码”,  
“timeout”:600,  
“method”:”aes-256-cfb”,  
“fast_open”:false  
}

B。iptables及转发

#vim /etc/sysctl.conf

net.ipv4.ip_forward=1

linux做网关要开启数据转发#sysctl -p

编写2个脚本一个启动用一个停止用

启动的iptables.sh 还有flash.sh 清理用的iptables

简单的

#!/bin/bash 
# Create new chain 
iptables -t nat -N SHADOWSOCKS  
iptables -t nat -A PREROUTING -p tcp -j SHADOWSOCKS  
# Ignore your shadowsocks server’s addresses 
# It’s very IMPORTANT, just be careful. 
iptables -t nat -A SHADOWSOCKS -d 服务器ip地址 -j RETURN  
# 这一步非常重要!到服务端的出口数据不要再进行重定向,否则进入死循环 
#去除内网地址 
iptables -t nat -A SHADOWSOCKS -d 0.0.0.0 -j RETURN  
iptables -t nat -A SHADOWSOCKS -d 127.0.0.1 -j RETURN  
iptables -t nat -A SHADOWSOCKS -d 192.168.0.0/16 -j RETURN

iptables -t nat -A SHADOWSOCKS -d 8.8.0.0/16 -j RETURN  
iptables -t nat -A SHADOWSOCKS -d 0.0.0.0/8 -j RETURN  
iptables -t nat -A SHADOWSOCKS -d 10.0.0.0/8 -j RETURN  
iptables -t nat -A SHADOWSOCKS -d 127.0.0.0/8 -j RETURN  
iptables -t nat -A SHADOWSOCKS -d 169.254.0.0/16 -j RETURN  
iptables -t nat -A SHADOWSOCKS -d 172.16.0.0/12 -j RETURN  
iptables -t nat -A SHADOWSOCKS -d 192.168.0.0/16 -j RETURN  
iptables -t nat -A SHADOWSOCKS -d 224.0.0.0/4 -j RETURN  
iptables -t nat -A SHADOWSOCKS -d 240.0.0.0/4 -j RETURN  
iptables -t nat -A SHADOWSOCKS -d 0.0.0.0/254.0.0.0 -j RETURN

#还可以加如国内ip段参见 https://gist.github.com/wen-long/8644507 
# Anything else should be redirected to shadowsocks’s local port 
iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT –to-ports 1080

# Apply the rules 
#iptables -t nat -A OUTPUT -p tcp -j SHADOWSOCKS 
# 对于本机全局代理必须是加入到OUTPUT链中,上面这句可以不加,至此脚本结束

清理脚本 flash.sh   因为debian下,iptables不是服务。没有启动停止的概念是实时生效的,清理完规则相当于其实停止了。iptables-save > qqq       恢复 iptables-restore < qqq

#!/bin/bash 
iptables -F  
iptables -X  
iptables -t nat -F  
iptables -t nat -X  
iptables -t mangle -F  
iptables -t mangle -X  
iptables -P INPUT ACCEPT  
iptables -P OUTPUT ACCEPT  
iptables -P FORWARD ACCEPT

C.dnsmasq

apt-get install network-manger dnsmasq

启用本地dns

如果使用了networkmanger要这样设置启用dnsmasq

Set this in /etc/NetworkManager/NetworkManager.conf:

[main]

dns=dnsmasq

如果没有那么

修改默认的dns配置文件

/etc/reslov.conf

nameserver 127.0.0.1

修改/etc/reslov.dnsmasq(需自己创建)

nameserver 8.8.8.8  
nameserver 8.8.4.4

编辑/etc/dnsmasq.conf

在最后加入

conf-dir=/etc/dnsmasq.d/,*.conf  
listen-address=127.0.0.1,192.168.1.104  
bind-interfaces  
cache-size=100000  
domain-needed  
resolv-file=/etc/resolv.dnsmasq

其中cache缓存10000条

resolv-file=/etc/resolv.dnsmasq 上游dns地址

listen-address=127.0.0.1,192.168.1.104   为局域网及本机提供dns服务

conf-dir=/etc/dnsmasq.d/,*.conf        接受目录下的所有配置文件

/etc/dnsmasq.d/t.conf内容,意思是这些地址走208.67.222.222的5353端口查询

#Google and Youtube  
server=/.google.com/208.67.222.222#5353  
server=/.google.com.hk/208.67.222.222#5353  
server=/.gstatic.com/208.67.222.222#5353  
server=/.ggpht.com/208.67.222.222#5353  
server=/.googleusercontent.com/208.67.222.222#5353  
server=/.appspot.com/208.67.222.222#5353  
server=/.googlecode.com/208.67.222.222#5353  
server=/.googleapis.com/208.67.222.222#5353  
server=/.gmail.com/208.67.222.222#5353  
server=/.google-analytics.com/208.67.222.222#535  
server=/.youtube.com/208.67.222.222#5353  
server=/.googlevideo.com/208.67.222.222#5353  
server=/.youtube-nocookie.com/208.67.222.222#5353  
server=/.ytimg.com/208.67.222.222#5353  
server=/.blogspot.com/208.67.222.222#5353  
server=/.blogger.com/208.67.222.222#5353

#FaceBook  
server=/.facebook.com/208.67.222.222#5353  
server=/.thefacebook.com/208.67.222.222#5353  
server=/.facebook.net/208.67.222.222#5353  
server=/.fbcdn.net/208.67.222.222#5353  
server=/.akamaihd.net/208.67.222.222#5353

#Twitter  
server=/.twitter.com/208.67.222.222#5353  
server=/.t.co/208.67.222.222#5353  
server=/.bitly.com/208.67.222.222#5353  
server=/.twimg.com/208.67.222.222#5353  
server=/.tinypic.com/208.67.222.222#5353  
server=/.yfrog.com/208.67.222.222#5353

server=/gist.github.com/208.67.222.222#5353  
server=/.chrome.com/208.67.222.222#5353  
server=/.android.com/208.67.222.222#5353  
server=/.appspot.com/208.67.222.222#5353  
server=/.goo.gl/208.67.222.222#5353  
server=/.feedburner.com/208.67.222.222#5353

update.rc 来开机启动dnsmasq

—————————————————————————————————————————–

扩展知识

启动守护进程

设置为开机启动:

systemctl enable dnsmasq  

立即启动 dnsmashq:

systemctl start dnsmasq

查看dnsmasq是否启动正常,查看系统日志:

journalctl -u dnsmasq

—————————————————————————————————————————–

D。使用

systemctl enable dnsmasq

systemctl start dnsmasq

ss-redir -c /etc/redir.json

./iptables.sh

前提,设置静态ip

auto eth0  
allow-hotplug eth0  
iface eth0 inet static  
address 192.168.1.104  
netmask 255.255.255.0  
gateway 192.168.1.1

路由器修改dncp里面的dns为192.168.1.104.网关也是192.168.1.104

---------------------------

Linux全局智能分流方案


Github 地址:Linux 和 MacOS 设备智能分流方案

本来我是决定不再写这样的文章了的。但是呢,最近连续配置了两次 ArchLinux,在配置这种东西的时候连续撞到了同样的坑,加上这段时间经常有人问我关于 Linux 下的 shadowsocks 的问题,所以我想了想还是写一篇记录一下吧,也免得自己以后再忘记了。


这里有两种方案,都可以实现全局智能分流。第一种方案的思路是使用 ipset 载入 chnroute 的 IP 列表并使用 iptables 实现带自动分流国内外流量的全局代理。为什么不用 PAC 呢?因为 PAC 这种东西只对浏览器有用。难道你在浏览器之外就不需要科学上网了吗?反正我是不信的……

本教程所用系统为 Archlinux,其他发型版类似,请自行参考相关资料。

1. 通过 iptables 实现智能分流


安装相关软件

  • shadowsocks-libev
  • ipset
$ pacman -S shadowsocks-libev ipset

配置shadowsocks-libev(略过)

假设shadowsocks配置文件为/etc/shadowsocks.json

获取中国IP段

将以下命令写入脚本保存执行(假设保存在/home/yang/bin/路由表/目录下):

#!/bin/sh
wget -c http://ftp.apnic.net/stats/apnic/delegated-apnic-latest
cat delegated-apnic-latest | awk -F '|' '/CN/&&/ipv4/ {print $4 "/" 32-log($5)/log(2)}' | cat > /home/yang/bin/路由表/cn_rules.conf

创建启动和关闭脚本

$ vim /home/yang/bin/shadowsocks/ss-up.sh
#!/bin/bash

SOCKS_SERVER=$SERVER_IP # SOCKS 服务器的 IP 地址
# Setup the ipset
ipset -N chnroute hash:net maxelem 65536

for ip in $(cat '/home/yang/bin/路由表/cn_rules.conf'); do
  ipset add chnroute $ip
done

# 在nat表中新增一个链,名叫:SHADOWSOCKS
iptables -t nat -N SHADOWSOCKS

# Allow connection to the server
iptables -t nat -A SHADOWSOCKS -d $SOCKS_SERVER -j RETURN

# Allow connection to reserved networks
iptables -t nat -A SHADOWSOCKS -d 0.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 10.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 127.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 169.254.0.0/16 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 172.16.0.0/12 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 192.168.0.0/16 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 224.0.0.0/4 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 240.0.0.0/4 -j RETURN

# Allow connection to chinese IPs
iptables -t nat -A SHADOWSOCKS -p tcp -m set --match-set chnroute dst -j RETURN
# 如果你想对 icmp 协议也实现智能分流,可以加上下面这一条
# iptables -t nat -A SHADOWSOCKS -p icmp -m set --match-set chnroute dst -j RETURN

# Redirect to Shadowsocks
# 把1081改成你的shadowsocks本地端口
iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT --to-port 1081
# 如果你想对 icmp 协议也实现智能分流,可以加上下面这一条
# iptables -t nat -A SHADOWSOCKS -p icmp -j REDIRECT --to-port 1081

# 将SHADOWSOCKS链中所有的规则追加到OUTPUT链中
iptables -t nat -A OUTPUT -p tcp -j SHADOWSOCKS
# 如果你想对 icmp 协议也实现智能分流,可以加上下面这一条
# iptables -t nat -A OUTPUT -p icmp -j SHADOWSOCKS

# 内网流量流经 shadowsocks 规则链
iptables -t nat -A PREROUTING -s 192.168/16 -j SHADOWSOCKS
# 内网流量源NAT
iptables -t nat -A POSTROUTING -s 192.168/16 -j MASQUERADE

这是在启动 shadowsocks 之前执行的脚本,用来设置 iptables 规则,对全局应用代理并将 chnroute 导入 ipset 来实现自动分流。注意要把服务器 IP 和本地端口相关的代码全部替换成你自己的。

这里就有一个坑了,就是在把 chnroute.txt 加入 ipset 的时候。因为 chnroute.txt 是一个 IP 段列表,而中国持有的 IP 数量上还是比较大的,所以如果使用 hash:ip 来导入的话会使内存溢出。我在第二次重新配置的时候就撞进了这个大坑……

但是你也不能尝试把整个列表导入 iptables。虽然导入 iptables 不会导致内存溢出,但是 iptables 是线性查表,即使你全部导入进去,也会因为低下的性能而抓狂。

然后再创建 /home/yang/bin/shadowsocks/ss-down.sh, 这是用来清除上述规则的脚本,比较简单

#!/bin/bash

# iptables -t nat -D OUTPUT -p icmp -j SHADOWSOCKS
iptables -t nat -D OUTPUT -p tcp -j SHADOWSOCKS
iptables -t nat -F SHADOWSOCKS
iptables -t nat -X SHADOWSOCKS
ipset destroy chnroute

接着执行

$ chmod +x ss-up.sh
$ chmod +x ss-down.sh

配置ss-redir服务

首先,默认的 ss-local 并不能用来作为 iptables 流量转发的目标,因为它是 socks5 代理而非透明代理。我们至少要把 systemd 执行的程序改成 ss-redir。其次,上述两个脚本还不能自动执行,必须让 systemd 分别在启动 shadowsocks 之前和关闭之后将脚本执行,这样才能自动配置好 iptables 规则。

$ vim /usr/lib/systemd/system/shadowsocks-libev@.service
[Unit]
Description=Shadowsocks-Libev Client Service
After=network.target

[Service]
User=root
CapabilityBoundingSet=~CAP_SYS_ADMIN
ExecStart=
ExecStartPre=/home/yang/bin/shadowsocks/ss-up.sh
ExecStart=/usr/bin/ss-redir -u -c /etc/%i.json
ExecStopPost=/home/yang/bin/shadowsocks/ss-down.sh

[Install]
WantedBy=multi-user.target

然后启动服务

$ systemctl start shadowsocks-libev@shadowsocks

开机自启

$ systemctl enable shadowsocks-libev@shadowsocks

配置智能 DNS 服务

完成了以上工作之后是不是就可以实现全局科学上网了呢?答案是否定的,我们还有最后一项工作需要完成,那就是解决 DNS 污染问题。如果你不知道什么是 DNS 污染,我可以简单地给你普及一下:

DNS 污染是一种让一般用户由于得到虚假目标主机 IP 而不能与其通信的方法,是一种 DNS 缓存投毒攻击(DNS cache poisoning)。其工作方式是:由于通常的 DNS 查询没有任何认证机制,而且 DNS 查询通常基于的 UDP 是无连接不可靠的协议,因此 DNS 的查询非常容易被篡改,通过对 UDP 端口 53 上的 DNS 查询进行入侵检测,一经发现与关键词相匹配的请求则立即伪装成目标域名的解析服务器(NS,Name Server)给查询者返回虚假结果。

DNS 污染症状:目前一些被禁止访问的网站很多就是通过 DNS 污染来实现的,例如 YouTubeFacebook 等网站。

应对dns污染的方法

  • 对于 DNS 污染,可以说,个人用户很难单单靠设置解决,通常可以使用 VPN 或者域名远程解析的方法解决,但这大多需要购买付费的 VPN 或 SSH 等
  • 修改 Hosts 的方法,手动设置域名正确的 IP 地址
  • dns 加密解析:DNSCrypt
  • 忽略 DNS 投毒污染小工具:Pcap_DNSProxy

我们选择用 Pcap_DNSProxy 来解决这个问题,以前用的是 Pdnsd + Dnsmasq 组合, 后来发现 TCP 请求效率太低加上家里网络与那些国外的 DNS 丢包实在是严重, 所以打算用 Pcap_DNSProxy 代替 Pdnsd

关于 Pcap_DNSProxy 的详细介绍,可以参考:
https://github.com/chengr28/Pcap_DNSProxy

安装过程可以参考:
https://github.com/chengr28/Pcap_DNSProxy/blob/master/Documents/ReadMe_Linux.zh-Hans.txt

更详细的使用说明可以参考:
https://github.com/chengr28/Pcap_DNSProxy/blob/master/Documents/ReadMe.zh-Hans.txt

这里主要重点强调一些需要注意的配置项:

  • DNS - 境外域名解析参数区域(这是最关键的一项配置)
[DNS]
# 这里一定要填 IPv4 + TCP!!!表示只使用 TCP 协议向境外远程 DNS 服务器发出请求
Outgoing Protocol = IPv4 + TCP
# 建议当系统使用全局代理功能时启用,程序将除境内服务器外的所有请求直接交给系统而不作任何过滤等处理,系统会将请求自动发往远程服务器进行解析
Direct Request = IPv4
...
...
  • Local DNS - 境内域名解析参数区域
[Local DNS]
# 发送请求到境内 DNS 服务器时所使用的协议
Local Protocol = IPv4 + UDP
...
...
  • Addresses - 普通模式地址区域
[Addresses]
...
...
# IPv4 主要境外 DNS 服务器地址
IPv4 Main DNS Address = 8.8.4.4:53
# IPv4 备用境外 DNS 服务器地址
IPv4 Alternate DNS Address = 8.8.8.8:53|208.67.220.220:443|208.67.222.222:5353
# IPv4 主要境内 DNS 服务器地址,用于境内域名解析,推荐使用 onedns
IPv4 Local Main DNS Address = 112.124.47.27:53
# IPv4 备用境内 DNS 服务器地址,用于境内域名解析
IPv4 Local Alternate DNS Address = 114.215.126.16:53
...
...

配置系统 DNS 服务器设置

  • 可参见 https://developers.google.com/speed/public-dns/docs/using 中 Changing your DNS servers settings 中 Linux 一节

  • 图形界面以 GNOME 3 为例:

  • 打开所有程序列表,并 -> 设置 – 硬件分类 – 网络

  • 如果要对当前的网络配置进行编辑 -> 单击齿轮按钮

  • 选中 IPv4

  • DNS 栏目中,将自动拨向关闭

  • 在服务器中填入 127.0.0.1 (或103.214.195.99:7300)并应用

  • 选中 IPv6

  • DNS 栏目中,将自动拨向关闭

  • 在服务器中填入 ::1 并应用

  • 请务必确保只填入这两个地址,填入其它地址可能会导致系统选择其它 DNS 服务器绕过程序的代理

  • 重启网络连接

  • 直接修改系统文件修改 DNS 服务器设置:

  • 自动获取地址(DHCP)时:

  • 以 root 权限进入 /etc/dhcp 或 /etc/dhcp3 目录(视乎 dhclient.conf 文件位置)

  • 直接修改 dhclient.conf 文件,修改或添加 prepend domain-name-servers 一项即可

  • 如果 prepend domain-name-servers 一项被 # 注释则需要把注释去掉以使配置生效,不需要添加新的条目

  • dhclient.conf 文件可能存在多个 prepend domain-name-servers 项,是各个网络接口的配置项目,直接修改总的配置项目即可

  • 使用 service network(/networking) restart 或 ifdown/ifup 或 ifconfig stop/start 重启网络服务/网络端口

  • 非自动获取地址(DHCP)时:

  • 以 root 权限进入 /etc 目录

  • 直接修改 resolv.conf 文件里的 nameserver 即可

  • 如果重启后配置被覆盖,则需要修改或新建 /etc/resolvconf/resolv.conf.d 文件,内容和 resolv.conf 一样

  • 使用 service network(/networking) restart 或 ifdown/ifup 或 ifconfig stop/start 重启网络服务/网络端口

打开流量转发

$ cat /etc/sysctl.d/30-ipforward.conf
net.ipv4.ip_forward=1

net.ipv6.conf.all.forwarding = 1

net.ipv4.tcp_congestion_control=westwood

net.ipv4.tcp_syn_retries = 5

net.ipv4.tcp_synack_retries = 5

编辑完成后,执行以下命令使变动立即生效

$ sysctl -p

2. 通过 nftables 实现智能分流


安装相关软件

  • shadowsocks-libev
  • nftables
$ pacman -S shadowsocks-libev nftables

配置shadowsocks-libev(略过)

假设shadowsocks配置文件为/etc/shadowsocks.json

获取中国IP段

将以下命令写入脚本保存执行(假设保存在/home/yang/bin/路由表/目录下):

#!/bin/sh
wget -c http://ftp.apnic.net/stats/apnic/delegated-apnic-latest
cat delegated-apnic-latest | awk -F '|' '/CN/&&/ipv4/ {print $4 "/" 32-log($5)/log(2)}' | cat > /home/yang/bin/路由表/cn_rules.conf
cat cn_rules.conf|sed ':label;N;s/\n/, /;b label'|sed 's/$/& }/g'|sed 's/^/{ &/g' > /home/yang/bin/路由表/cn_rules1.conf

创建启动和关闭脚本

$ vim /home/yang/bin/shadowsocks/nftables-up.sh
#! /bin/bash

nft_pre="/usr/sbin/nft add rule nat prerouting"
nft_out="/usr/sbin/nft add rule nat output"
chnroute=$(cat '/home/yang/bin/路由表/cn_rules1.conf')

/usr/bin/nft -f /etc/nftables.conf

${nft_pre} tcp dport 8385 return
${nft_pre} ip daddr 139.162.87.98 return
${nft_pre} ip daddr { 0.0.0.0/8, 10.0.0.0/8, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0/12, 192.168.0.0/16, 224.0.0.0/4, 240.0.0.0/4, 172.16.39.0/24} return
${nft_pre} ip daddr $chnroute return
${nft_pre} tcp sport { 32768-61000} redirect to 1081
#${nft_pre} ip protocol icmp redirect to 1081
# 内网流量源NAT
nft add rule nat postrouting ip saddr 192.168.0.0/12 masquerade

${nft_out} tcp dport 8385 return
${nft_out} ip daddr 139.162.87.98 return
${nft_out} ip daddr { 0.0.0.0/8, 10.0.0.0/8, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0/12, 192.168.0.0/16, 224.0.0.0/4, 240.0.0.0/4, 172.16.39.0/24} return
${nft_out} ip daddr $chnroute return
# /proc/sys/net/ipv4/ip_local_port_range,本地发起的连接的端口范围
${nft_out} tcp sport { 32768-61000} redirect to 1081
${nft_out} ip protocol icmp redirect to 1081

  这是在启动 shadowsocks 之前执行的脚本,用来设置 nftables 规则。
然后再创建 /home/yang/bin/shadowsocks/nftables-down.sh, 这是用来清除上述规则的脚本,比较简单

#!/bin/bash

sudo nft flush table nat
#sudo nft flush table filter

接着执行

$ chmod +x nftables-up.sh
$ chmod +x nftables-down.sh

配置ss-redir服务

首先,默认的 ss-local 并不能用来作为 nftables 流量转发的目标,因为它是 socks5 代理而非透明代理。我们至少要把 systemd 执行的程序改成 ss-redir。其次,上述两个脚本还不能自动执行,必须让 systemd 分别在启动 shadowsocks 之前和关闭之后将脚本执行,这样才能自动配置好 nftables 规则。

$ vim /usr/lib/systemd/system/shadowsocks-libev@.service
[Unit]
Description=Shadowsocks-Libev Client Service
After=network.target

[Service]
User=root
CapabilityBoundingSet=~CAP_SYS_ADMIN
ExecStart=
ExecStartPre=/home/yang/bin/shadowsocks/nftables-up.sh
ExecStart=/usr/bin/ss-redir -u -c /etc/%i.json
ExecStopPost=/home/yang/bin/shadowsocks/nftables-down.sh

[Install]
WantedBy=multi-user.target

然后启动服务

$ systemctl start nftables
$ systemctl start shadowsocks-libev@shadowsocks

开机自启

$ systemctl enable nftables
$ systemctl enable shadowsocks-libev@shadowsocks

配置智能 DNS 服务

同上

配置系统 DNS 服务器设置

同上

打开流量转发

同上

3. 通过策略路由实现智能分流


安装相关软件

  • badvpn
  • shadowsocks
$ pacman -S badvpn shadowsocks

配置shadowsocks(略过)

假设shadowsocks配置文件为/etc/shadowsocks.json

获取中国IP段

将以下命令写入脚本保存执行(假设保存在/home/yang/bin/路由表/目录下):

#!/bin/sh
wget -c http://ftp.apnic.net/stats/apnic/delegated-apnic-latest
cat delegated-apnic-latest | awk -F '|' '/CN/&&/ipv4/ {print $4 "/" 32-log($5)/log(2)}' | cat > /home/yang/bin/路由表/cn_rules.conf

配置智能 DNS 服务

同上

配置系统 DNS 服务器设置

同上

编写路由表启动和终止脚本

$ vim /usr/local/bin/socksfwd
#!/bin/bash
SOCKS_SERVER=$SERVER_IP # SOCKS 服务器的 IP 地址
SOCKS_PORT=1081 # 本地SOCKS 服务器的端口
GATEWAY_IP=$(ip route|grep "default"|awk '{print $3}') # 家用网关(路由器)的 IP 地址,你也可以手动指定
TUN_NETWORK_DEV=tun0 # 选一个不冲突的 tun 设备号
TUN_NETWORK_PREFIX=10.0.0 # 选一个不冲突的内网 IP 段的前缀


start_fwd() {
ip tuntap del dev "$TUN_NETWORK_DEV" mode tun
# 添加虚拟网卡
ip tuntap add dev "$TUN_NETWORK_DEV" mode tun
# 给虚拟网卡绑定IP地址
ip addr add "$TUN_NETWORK_PREFIX.1/24" dev "$TUN_NETWORK_DEV"
# 启动虚拟网卡
ip link set "$TUN_NETWORK_DEV" up
ip route del default via "$GATEWAY_IP"
ip route add "$SOCKS_SERVER" via "$GATEWAY_IP"
# 特殊ip段走家用网关(路由器)的 IP 地址(如局域网联机)
# ip route add "172.16.39.0/24" via "$GATEWAY_IP"
# 国内网段走家用网关(路由器)的 IP 地址
for i in $(cat /home/yang/bin/路由表/cn_rules.conf)
do
ip route add "$i" via "$GATEWAY_IP"
done
# 将默认网关设为虚拟网卡的IP地址
ip route add 0.0.0.0/1 via "$TUN_NETWORK_PREFIX.1"
ip route add 128.0.0.0/1 via "$TUN_NETWORK_PREFIX.1"
# 将socks5转为vpn
badvpn-tun2socks --tundev "$TUN_NETWORK_DEV" --netif-ipaddr "$TUN_NETWORK_PREFIX.2" --netif-netmask 255.255.255.0 --socks-server-addr "127.0.0.1:$SOCKS_PORT"
TUN2SOCKS_PID="$!"
}


stop_fwd() {
ip route del 128.0.0.0/1 via "$TUN_NETWORK_PREFIX.1"
ip route del 0.0.0.0/1 via "$TUN_NETWORK_PREFIX.1"
for i in $(cat /home/yang/bin/路由表/cn_rules.conf)
do
ip route del "$i" via "$GATEWAY_IP"
done
ip route del "172.16.39.0/24" via "$GATEWAY_IP"
ip route del "$SOCKS_SERVER" via "$GATEWAY_IP"
ip route add default via "$GATEWAY_IP"
ip link set "$TUN_NETWORK_DEV" down
ip addr del "$TUN_NETWORK_PREFIX.1/24" dev "$TUN_NETWORK_DEV"
ip tuntap del dev "$TUN_NETWORK_DEV" mode tun
}



start_fwd
trap stop_fwd INT TERM
wait "$TUN2SOCKS_PID"
$ vim /etc/systemd/system/socksfwd.service
[Unit]

Description=Transparent SOCKS5 forwarding

After=network-online.target

[Service]

Type=simple

ExecStart=/usr/local/bin/socksfwd

LimitNOFILE=1048576


[Install]

WantedBy=multi-user.target

启动服务

$ systemctl start socksfwd

开机自启

$ systemctl enable socksfwd

打开流量转发

$ cat /etc/sysctl.d/30-ipforward.conf
net.ipv4.ip_forward=1

net.ipv6.conf.all.forwarding = 1

net.ipv4.tcp_congestion_control=westwood

net.ipv4.tcp_syn_retries = 5

net.ipv4.tcp_synack_retries = 5

编辑完成后,执行以下命令使变动立即生效

$ sysctl -p
from https://fuckcloudnative.io/posts/linux-circumvent/
-----------------------------------------------

使用由shadowsocks-libev所生成的ss-redir做全局代理

首先我们在自己的VPS以及网关机器(linux桌面系统)上都安装shadowsocks-libev,注意是libev这个版本,其他的版本例如python版本是没有ss-redir这个透明代理工具的。

这里我用的是Debian9和Ubuntu18.04,所以只需要使用包管理器即可简单安装:

apt -y update
apt -y install shadowsocks-libev libsodium-dev


首先来配置服务端,在VPS上编辑如下配置文件:

nano /etc/shadowsocks-libev/config.json

类似我的配置如下:

{
    "server":"0.0.0.0",
    "server_port":23333,
    "local_port":1080,
    "password":"你的SS连接密码",
    "timeout":60,
    "method":"chacha20-ietf-poly1305"
}

保存配置之后重启shadowsocks-libev以及设置开机自启:

systemctl restart shadowsocks-libev
systemctl enable shadowsocks-libev


接下来配置网关机器,在网关上首先停止shadowsocks-libev运行:

systemctl stop shadowsocks-libev

然后新建一个用于透明代理的配置文件:

nano /etc/shadowsocks-libev/config-redir.json

类似我的配置如下:

{
    "server":"VPS公网IP",
    "mode":"tcp_and_udp",
    "server_port":23333,
    "local_address": "0.0.0.0",
    "local_port":10801,
    "password":"你的SS连接密码",
    "timeout":60,
    "method":"chacha20-ietf-poly1305"
}

接着新建一个systemd服务文件:

nano /lib/systemd/system/shadowsocks-redir.service

写入如下配置:

[Unit]
Description=Shadowsocks-libev Redir Service
After=network-online.target

[Service]
Type=simple
User=nobody
Group=nogroup
LimitNOFILE=32768
ExecStart=/usr/bin/ss-redir -c /etc/shadowsocks-libev/config-redir.json

[Install]
WantedBy=multi-user.target

启动ss-redir:

systemctl start shadowsocks-redir
systemctl enable shadowsocks-redir

现在ss-redir这块的配置就完成了,让我们在网关机器上做一点善后工作。

开启IPv4转发:

echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf && sysctl -p

安装ipset/创建ipset链/将中国ip加入到链:

apt -y install ipset
wget https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt
ipset -N cn hash:net
for i in $(cat china_ip_list.txt); do ipset -A cn $i; done

使用iptables处理流量/中国IP直连:

iptables -t nat -N SHADOWSOCKS
iptables -t nat -A SHADOWSOCKS -d 192.168.0.0/16 -j RETURN
iptables -t nat -A SHADOWSOCKS -p tcp -m set --match-set cn dst -j RETURN
iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT --to-ports 10801
iptables -t nat -A PREROUTING -p tcp -j SHADOWSOCKS

如果有一些应用,例如BT你不想让它走代理可以将上面的最后一条命令改为下面这样,即自己指定端口,设置让哪些端口走代理:

iptables -t nat -A PREROUTING -p tcp --dport 22 -j SHADOWSOCKS
iptables -t nat -A PREROUTING -p tcp --dport 80 -j SHADOWSOCKS
iptables -t nat -A PREROUTING -p tcp --dport 443 -j SHADOWSOCKS

最后,局域网内的其他机器(比如windows机器),配置网关的ip地址和DNS服务器的IP地址均为这台网关机器的IP即可:

------------------------------------------------------------------------

相关帖子:

https://briteming.blogspot.com/2013/05/shadowsocks-libev.html

No comments:

Post a Comment