1.前言
业务中时常会遇到需要部分APP有严格风控如(地域IP限制、IP访问频次限制等)。本次利用redsocks + iptables 来实现安卓全局代{过}{滤}理切换。
2.redsocks 介绍
redsocks 可将任何 TCP 连接重定向到 Socks4、Socks5 或 HTTPS (HTTP/CONNECT) 代{过}{滤}理服务器。
Socks5/HTTPS 连接支持登录/密码身份验证。Socks4仅支持用户名,密码被忽略。对于 HTTPS,目前仅支持 Basic 和 Digest 方案。
3.iptables 介绍
iptables 本质上是定义linux防火墙规则的工具,定义的规则,可以让在内核空间当中的netfilter来读取,并且实现让防火墙工作。
3.1五处控制规则
1.PREROUTING (路由前)
2.INPUT (数据包流入口)
3.FORWARD (转发管卡)
4.OUTPUT(数据包出口)
5.POSTROUTING(路由后)
3.2数据流走向
4.环境准备
# 测试使用版本 redsocks 0.4、iptables v1.4.20
# https://github.com/darkk/redsocks 直接拉取代码进行编译
apt-get install libevent-dev
cd redsocks
make
5.设置代{过}{滤}理
# 启动代{过}{滤}理并配置项,<IP> 代{过}{滤}理IP <PORT>端口
# proxy.sh 一共7个入参,详情查看脚本
/proxy.sh start http <IP> <PORT> false "" ""
# 对代{过}{滤}理ip不再代{过}{滤}理操作,<IP> 代{过}{滤}理IP
/iptables -t nat -A OUTPUT -p tcp -d <IP> -j RETURN
# 添加群控软件不走全局代{过}{滤}理规则,<UID>应用程序,如果你想让安卓上某个进程的网络都不走带可以可以这样设置
/iptables -t nat -m owner --uid-owner <UID> -A OUTPUT -p tcp -j RETURN
# 对应域名不走代{过}{滤}理<xxx1> 不需要走代{过}{滤}理的域名
/iptables -t nat -A OUTPUT -p tcp -d <xxx1> -j RETURN
/iptables -t nat -A OUTPUT -p tcp -d <xxx2> -j RETURN
# 添加http代{过}{滤}理规则,可以按照自己的业务场景进行端口代{过}{滤}理设置
/iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to 8123
/iptables -t nat -A OUTPUT -p tcp --dport 443 -j REDIRECT --to 8124
/iptables -t nat -A OUTPUT -p tcp --dport 5228 -j REDIRECT --to 8124
# 添加socks5代{过}{滤}理规则
/iptables -t nat -A OUTPUT -p tcp -j REDIRECT --to 8123
6.关闭代{过}{滤}理
# 清除所有代{过}{滤}理配置
/iptables -t nat -F OUTPUT
# 清除配置并干掉进程,具体查看proxy.sh 脚本
/proxy.sh stop
7.proxy.sh 代{过}{滤}理脚本
#!/system/bin/sh
DIR=/data/user/0/com.netease.rcs/files
type=$2
host=$3
port=$4
auth=$5
user=$6
pass=$7
PATH=$DIR:$PATH
case $1 in
start)
echo "
base {
log_debug = off;
log_info = off;
log = stderr;
daemon = on;
redirector = iptables;
}
" >$DIR/redsocks.conf
proxy_port=8123
case $type in
http)
proxy_port=8124
case $auth in
true)
echo "
redsocks {
local_ip = 127.0.0.1;
local_port = 8123;
ip = $host;
port = $port;
type = http-relay;
login = \"$user\";
password = \"$pass\";
}
redsocks {
local_ip = 0.0.0.0;
local_port = 8124;
ip = $host;
port = $port;
type = http-connect;
login = \"$user\";
password = \"$pass\";
}
" >>$DIR/redsocks.conf
;;
false)
echo "
redsocks {
local_ip = 127.0.0.1;
local_port = 8123;
ip = $host;
port = $port;
type = http-relay;
}
redsocks {
local_ip = 0.0.0.0;
local_port = 8124;
ip = $host;
port = $port;
type = http-connect;
}
" >>$DIR/redsocks.conf
;;
esac
;;
socks5)
case $auth in
true)
echo "
redsocks {
local_ip = 0.0.0.0;
local_port = 8123;
ip = $host;
port = $port;
type = socks5;
login = \"$user\";
password = \"$pass\";
}
" >>$DIR/redsocks.conf
;;
false)
echo "
redsocks {
local_ip = 0.0.0.0;
local_port = 8123;
ip = $host;
port = $port;
type = socks5;
}
" >>$DIR/redsocks.conf
;;
esac
;;
socks4)
case $auth in
true)
echo "
redsocks {
local_ip = 0.0.0.0;
local_port = 8123;
ip = $host;
port = $port;
type = socks4;
login = \"$user\";
password = \"$pass\";
}
" >>$DIR/redsocks.conf
;;
false)
echo "
redsocks {
local_ip = 0.0.0.0;
local_port = 8123;
ip = $host;
port = $port;
type = socks4;
}
" >>$DIR/redsocks.conf
;;
esac
;;
esac
$DIR/redsocks -p $DIR/redsocks.pid -c $DIR/redsocks.conf
;;
stop)
$DIR/busybox killall -9 redsocks
$DIR/busybox killall -9 cntlm
$DIR/busybox killall -9 stunnel
$DIR/busybox killall -9 tproxy
kill -9 `cat $DIR/redsocks.pid`
rm $DIR/redsocks.pid
rm $DIR/redsocks.conf
esac