u1timate
Published on 2024-09-23 / 232 Visits
0

基于socks5实现系统的全局代理

0x01 Linux

想在linux上通过socks5实现对全局流量的代理,主要基于redsocks+iptables实现。socks5服务开源的很多,比如windows上的ccproxy,linux上的go-proxy等。

iptables

图中使用箭头展示了用户访问使用了iptables的机器的过程,其中按照箭头的顺序我们就可以将其梳理为一条大的带有分支的链条,在每个需要进行操作的模块处都标有名称和相应的括号,括号内的就是iptables的四表,而每个模块都可以视为一个链。

iptables的四个表iptable_filteriptable_mangleiptable_natiptable_raw,默认表是filter(没有指定表的时候就是filter表)。

  • filter 表:用来对数据包进行过滤,具体的规则要求决定如何处理一个数据包。
    对应的内核模块为:iptable_filter,其表内包括三个链:inputforwardoutput;

  • nat 表:nat 全称:network address translation 网络地址转换,主要用来修改数据包的 IP 地址、端口号信息。
    对应的内核模块为:iptable_nat,其表内包括三个链:preroutingpostroutingoutput;

  • mangle 表:主要用来修改数据包的服务类型,生存周期,为数据包设置标记,实现流量整形、策略路由等。
    对应的内核模块为:iptable_mangle,其表内包括五个链:preroutingpostroutinginputoutputforward;

  • raw 表:主要用来决定是否对数据包进行状态跟踪。

我们这次主要使用了nat表

NAT表(nat)

  • PREROUTING链:用于在数据包进入本机之前修改目标IP地址(DNAT)或其他特征。

  • POSTROUTING链:用于在数据包离开本机之前修改源IP地址(SNAT)或其他特征。

本次使用不会涉及到这两个链,因为我的目标是处理和重定向从本机发出的流量,而不是处理进入或离开本机的流量。这种设置特别适用于需要对本机产生的流量进行特殊处理的情况

配置DNAT

假设我们想要将所有流向本机(公网IP)80端口的TCP流量,转发到另一台具有公网IP(8.209.1.81)的服务器的80端口。这个需求可以通过配置DNAT来实现:

iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 8.209.1.81:80

配置SNAT

网络地址转换(NAT)可以将私有网络中的私有IP地址转换为公共IP地址,以此连接到互联网。这个过程中,NAT会修改数据包的源IP地址或目标IP地址。当处理出站流量时,使用源网络地址转换(SNAT)。

在处理内网环境时,我们需要SNAT使用内网IP,因为它可以让内网中的计算机通过共享的公网IP访问互联网。如果我们使用公网IP地址作为SNAT的地址,那么内网用户将无法访问SNAT提供的服务,因为他们无法直接访问公网IP地址。因此,SNAT使用内网IP地址是实现内网中转的关键。

例如,我们可以使用以下命令来实现SNAT:

iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 192.168.1.1

在这个命令中:

  • -t nat是说我们要操作的是NAT表。

  • -A POSTROUTING是向POSTROUTING链追加一条新的规则。

  • -o eth0是指定这个规则只对出口为eth0的数据包起作用。

  • -j SNAT是指定我们要执行的动作是源地址转换(SNAT)。

  • --to-source 192.168.1.1是指定新的源IP地址。

重定向本机流量

sudo iptables -t nat -N SSR # 这条命令创建了一个名为 SSR 的新链。在 iptables 中,链是一组规则的集合,可以独立管理。创建自定义链可以帮助组织和模块化规则。
sudo iptables -t nat -A SSR -j REDIRECT -p tcp --to-ports 12345  # 这条命令在 SSR 链中添加了一条规则,用于将所有匹配的 TCP 流量重定向到本地的 12345 端口。-j REDIRECT 表示采取的动作是重定向,--to-ports 指定了目标端口。

注意:在 iptables 命令中,-A 参数用于指定将规则添加到哪个链。如果不指定 -A SSR 参数,iptables 将不知道应该将规则添加到哪个链,因此这是必需的。在 iptables 中,除了用户可以自定义的链(如您提到的 SSR 链)之外,还有几个内置的默认链,INPUT、FORWARD、OUTPUT、PREROUTING、POSTROUTING

redsocks

此工具允许您使用防火墙将任何 TCP 连接重定向到 SOCKS 或 HTTPS 代理.

darkk/redsocks: transparent TCP-to-proxy redirector (github.com)

  • 首先安装redsocks并配置好socks5服务,将socket连接通过iptables重定向到redsocks监听的本地端口上时,redsocks能够实现透明代理

yum gcc cmke git libevent-devel
git clone https://github.com/darkk/redsocks
cd redsocks/
make
mv redsocks /usr/local/bin/
  • 新建配置文件vi /etc/redsocks.conf

base {
        log_debug = off;
        log_info = on;
        log = stderr;
        daemon = off;
        redirector = iptables;
}
redsocks {
        local_ip = 127.0.0.1;
        local_port = 1080;
        ip = 192.168.10.2;
        port = 1080;
        type = socks5;
}
  • 启动

/usr/local/bin/redsocks -c /etc/redsocks.conf

配置

  • 设置iptables,我们需要在nat表上新建一个链

sudo iptables -t nat -F    # 清空nat表规则

sudo iptables -t nat -N SSR    # 新建SSR链
sudo iptables -t nat -A SSR -j REDIRECT -p tcp --to-ports 1080 -m comment --comment 'redsocks全局SSR代理'
sudo iptables -t nat -A OUTPUT -j SSR -p tcp -m comment --comment '跳转到redsocks全局SSR代理'
Chain_SSR="OUTPUT"
sudo iptables -t nat -I $Chain_SSR -j RETURN -m comment --comment '局域网放行' -d 0.0.0.0/8
sudo iptables -t nat -I $Chain_SSR -j RETURN -m comment --comment '局域网放行' -d 127.0.0.0/8
sudo iptables -t nat -I $Chain_SSR -j RETURN -m comment --comment '局域网放行' -d 169.254.0.0/16
sudo iptables -t nat -I $Chain_SSR -j RETURN -m comment --comment '局域网放行' -d 172.16.0.0/12
sudo iptables -t nat -I $Chain_SSR -j RETURN -m comment --comment '局域网放行' -d 172.30.0.0/24
sudo iptables -t nat -I $Chain_SSR -j RETURN -m comment --comment '局域网放行' -d 224.0.0.0/4
sudo iptables -t nat -I $Chain_SSR -j RETURN -m comment --comment '局域网放行' -d 240.0.0.0/4
sudo iptables -t nat -I $Chain_SSR -j RETURN -m comment --comment 'socks5代理服务器放行' -d 172.30.10.2
  • 查看配置

iptables -t nat -nvL --line-number

  • 删除链

iptables -t nat -F SSR
  • 测试

0x02 windows

解决方案:用tun2socks 启一个虚拟网卡,该网卡流量都走制定配置好的socks5服务,然后配置路由,全局或者部分ip段指定该网卡为网关。

tap-windows

TAP-Windows Adapter是一种网络驱动程序,它模拟一个以太网设备,使得VPN软件能够通过这个虚拟的网络接口发送和接收数据包。这样,VPN客户端就可以将你的网络流量通过一个加密的VPN连接发送到VPN服务器,无论这些数据最终是发送到互联网上的哪个位置

首先需要下载Tap-Windows并安装

Index of /downloads/releases/ (openvpn.net)

Wintun

Wintun – Layer 3 TUN Driver for Windows

Wintun是Windows内核的一个非常简单且最小的TUN驱动程序,它为用户空间程序提供了一个简单的网络适配器来读写数据包。它类似于 Linux 的 /dev/net/tun 和 BSD 的 /dev/tun。 Wintun 最初设计用于 WireGuard,旨在广泛用于各种第 3 层网络协议和实验。该驱动程序是开源的,因此任何人都可以检查和构建它。由于 Microsoft 的驱动程序签名要求,我们提供了可以随您的软件一起分发的预编译和签名版本。该项目的目标是尽可能简单,选择以 NDIS 提供的最纯粹、最直接的方式做事。

tun2socks

tun2socks 是一个网络工具,它可以将TCP连接在网络层“socks化”。这意味着它能够将所有进入的TCP连接通过一个SOCKS代理服务器转发,从而实现网络流量的转发。这个工具通常用于在不直接支持SOCKS代理的情况下,通过代理服务器转发网络流量。

eycorsican/go-tun2socks: A tun2socks implementation written in Go. (github.com) 这个长期不维护了, 可以与tap-windows结合使用,也能达成目的

xjasonlyu/tun2socks: tun2socks - powered by gVisor TCP/IP stack (github.com)

xjasonlyu/tun2socks: tun2socks - powered by gVisor TCP/IP stack (github.com)

这里我使用第二个,全平台支持。 在window上我们需要使用wintun。

  • wintun 下载到 tun2socks 文件夹或系统 PATH ,启动程序。

tun2socks -device wintun -proxy socks5://host:port -interface "WIFI" # 创建一个名为wintun的虚拟网卡,WIFI是默认的网络接口名称

-device wintun: 这个选项指定使用 wintun 作为虚拟网络设备的驱动。Wintun 是一个轻量级的虚拟网络接口,常用于Windows系统上的网络虚拟化。

-proxy socks5://host:port: 这个选项设置SOCKS5代理的地址和端口。所有通过这个虚拟网络设备的流量都会被发送到这个SOCKS5代理。在这里,host 和 port 需要替换为实际的代理服务器地址和端口号。

-interface "WIFI": 这个选项指定网络接口的名称,tun2socks 将会监听这个接口上的流量并通过上述指定的SOCKS5代理进行转发。

  • 手动设置ip地址

netsh interface ipv4 set address name="wintun" source=static addr=198.18.247.2 mask=255.255.255.0
  • 手动设置DNS地址

netsh interface ipv4 set dnsservers name="wintun" static address=172.30.10.2 register=none validate=no
  • 最后增加路由

netsh interface ipv4 add route 0.0.0.0/0 "wintun" 198.18.247.1 metric=1
netsh interface ipv4 add route 172.30.0.0/16 "Ethernet0" 172.30.11.1  metric=1

首先,系统会查找目标IP地址最精确匹配的路由条目。例如,对于目标IP 192.168.1.5,路由条目 192.168.1.0/24 比 192.168.0.0/16 更精确。

Metric值:在找到一个或多个匹配的路由条目后,系统会比较它们的metric值。Metric值较低的路由将被优先使用。Metric可以反映连接的成本,其中成本可能基于跳数、连接速度、可靠性等因素

  • 删除路由

netsh interface ipv4 delete route 0.0.0.0/0 "wintun"
netsh interface ipv4 delete route 172.30.10.2/32 "Ethernet"

参考

iptables的四表五链与NAT工作原理 - 知乎 (zhihu.com)

Linux下 redsocks + iptables + socks5 实现全局代理 - develon - 博客园 (cnblogs.com)