0. 前言
最近做的项目有一个需求:
项目开发的代理工具 A,需要开发一个相应的代理客户端接收用户的
HTTP/SOCKS5
流量并转发给服务器上的 A 服务端
由于时间因素,开发客户端太过麻烦,所以我思考了一种迂回实现用户代理的思路
用户通过 ss 客户端将流量传送到 ss 服务端,然后通过
redsocks+iptables
将流量转发给 A 服务端
具体过程流程图如下:
1. 配置 redsocks
注:ss 配置略
1.1 安装
sudo apt-get update
sudo apt-get install redsocks
1.2 编辑配置
vim /etc/redsocks.conf
base
中的配置基本保持默认即可,注意下系统中是否有iptables
base {
// debug: connection progress & client list on SIGUSR1
log_debug = on;
// info: start and end of client session
log_info = on;
/* possible log' values are:
* stderr
* "file:/path/to/file"
* syslog:FACILITY facility is any of "daemon", "local0"..."local7"
*/
log = "syslog:daemon";
// detach from console
daemon = on;
/* Change uid, gid and root directory, these options require root
* privilegies on startup.
* Note, your chroot may requre /etc/localtime if you write log to syslog.
* Log is opened before chroot & uid changing.
*/
user = redsocks;
group = redsocks;
// chroot = "/var/chroot";
/* possible
' values are:
* iptables - for Linux
* ipf - for FreeBSD
* pf - for OpenBSD
* generic - some generic redirector that MAY work
*/
redirector = iptables;
}
redsocks {
/* 这里填写redsocks需要监听的端口
* 如果需要监听全网卡,local_ip需要填写0.0.0.0
*/
local_ip = 0.0.0.0;
local_port = 36895;
// ip' and
' are IP and tcp-port of proxy-server
// You can also use hostname instead of IP, only one (random)
// address of multihomed host will be used.
// 这里填写代理A本机的监听端口即可
ip = 127.0.0.1;
port = 9050;
// known types: socks4, socks5, http-connect, http-relay
type = socks5;
}
接下来启动redsocks
redsocks -c /etc/redsocks.conf &
root@localhost:~# ps -ef | grep redsocks
root 20976 20955 0 01:22 pts/2 00:00:00 grep --color=auto redsocks
redsocks 24425 1 0 Jul31 ? 00:00:07 redsocks -c /etc/redsocks.conf
2. 配置 iptables 规则
iptables 可以基于黑名单或白名单配置,黑名单表示出了指定数据包之外,所有数据包通过 redsocks 转发;白名单则是只有指定的数据包才经过 redsocks 转发。
我们执行黑名单策略
# 在iptables上配置 "REDSOCKS" chain
iptables -t nat -N REDSOCKS
# 忽略本地地址 -A表示在某chain的规则表最后追加,-I表示在开头插入
iptables -t nat -A REDSOCKS -d 0.0.0.0/8 -j RETURN
iptables -t nat -A REDSOCKS -d 10.0.0.0/8 -j RETURN
iptables -t nat -A REDSOCKS -d 127.0.0.0/8 -j RETURN
iptables -t nat -A REDSOCKS -d 169.254.0.0/16 -j RETURN
iptables -t nat -A REDSOCKS -d 172.16.0.0/12 -j RETURN
iptables -t nat -A REDSOCKS -d 192.168.0.0/16 -j RETURN
iptables -t nat -A REDSOCKS -d 224.0.0.0/4 -j RETURN
iptables -t nat -A REDSOCKS -d 240.0.0.0/4 -j RETURN
# 添加转发规则,转发到redsocks的监听端口36895
iptables -t nat -A REDSOCKS -p tcp -j REDIRECT --to-ports 36895
# 添加OUTPUT链的规则
iptables -t nat -A OUTPUT -j REDSOCKS
2.1 排除 Proxy A 构建代理所发出的流量
这样配置其实有一个很严重的问题,这里的规则是黑名单,就是除了以本地地址为 destination 的数据包,其他所有数据包在经过
OUTPUT
链的时候都会被转发至 redsocks,然后由 redsocks 转发给Proxy A
,这里面就包括了Proxy A
本身的数据包,如果Proxy A
代理的构建需要与外部地址的通信(例如TOR
),流量最终又会被导入没有开启代理的Proxy A
。
我想到的办法是利用 iptables 里的某条规则:可以根据发出流量的用户和用户组来筛选流量
所以我没有让Proxy A
跑在root
账户下,而是跑在新建用户下,我们称之为proxya
,假设其uid=1000
之后我们添加规则:
iptables -t nat -I REDSOCKS -p all -m owner --uid-owner proxya -j RETURN
这个时候的 iptables 转发表如下:
proxya@localhost:~# iptables -L -n -t nat
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
REDSOCKS all -- 0.0.0.0/0 0.0.0.0/0
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
Chain REDSOCKS (1 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0 owner UID match 1000
RETURN all -- 0.0.0.0/0 172.105.196.169
RETURN all -- 0.0.0.0/0 0.0.0.0/8
RETURN all -- 0.0.0.0/0 10.0.0.0/8
RETURN all -- 0.0.0.0/0 127.0.0.0/8
RETURN all -- 0.0.0.0/0 169.254.0.0/16
RETURN all -- 0.0.0.0/0 172.16.0.0/12
RETURN all -- 0.0.0.0/0 192.168.0.0/16
RETURN all -- 0.0.0.0/0 224.0.0.0/4
RETURN all -- 0.0.0.0/0 240.0.0.0/4
REDIRECT tcp -- 0.0.0.0/0 0.0.0.0/0 redir ports 36895
发表评论