MENU

利用ss和redsocks转发流量思路分析

August 2, 2019 • Read: 47 • 技术笔记

前言

最近做的项目有一个需求:

项目开发的代理工具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 `redirector' 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 `port' 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 Process Flow

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
Archives QR Code
QR Code for this page
Tipping QR Code