在 Openwrt 路由上使用 Geph ,配置透明代理

透明代理:应该是需要翻墙的设备连接代理服务器,并不需要分别对设备上的软件或者系统级代理进行设置,就好像没有代理一样。

按照 Getting the latest Geph4 and usage / 最新二進制版下載 + 簡易使用教學
的教程,可以只使用 geph4-client 的代理模式,但是 如果运行 geph4-vpn-helper 会提示 未发现 geph4-vpn-helper
原因似乎是由于 openwrt /lib64/ 下只有 ld-musl-x86_64.so.1 而不是ld-linux-86-64.so.2 (是c库不同引起的?)
如果 vpn 模式不能使用,那么 geph 客户端 本身是 socks5或者https 代理客户端,那么需要将透明代理数据转换为socksv5 协议。

1 Like

简介

我后来选择用 openwrt 官方软件库里的 redsocks 作为透明代理软件 将tcp 转换 geph4-client socksv5 协议

并用 dnscrypt-proxy 了解决 dns 污染问题


准备工作

可以直接在 openwrt 终端中,通过以下命令安装:

opkg update
opkg install redsocks
opkg install dnscrypt-proxy2

配置 redsocks

接着,需要修改 /etc/redsocks.conf 文件
配置文件有几个部分

base  {
       XXXXX
}

如下修改配置

redsocks  {
          ......

          local_ip = 0.0.0.0;
          local_port = 12345;

          ......

          ip = 127.0.0.1;
          port = 9909;

          .......
          type = socks5;
}


redudp {
       .......
       local_ip = 0.0.0.0;
       local_port = 10053;
       
       .......
       
       ip = 127.0.0.1;
       port = 9909;

       ......

      dest_ip = 1.1.1.1;
      dest_port = 53;
      
      udp_timeout = 30;
      udp_timeout_stream = 180;
}

注:其他部分都是 用 “//” 注释掉

//dnstc {
      //local_ip = 127.0.0.1;
      //local_port = 5300;
//}

配置iptables (redirect 方案)

openwrt默认 redsocks 开机自启动,除了修改 redsocks 配置文件,还需要配合 iptables

#全局TCP代理规则    iptables+REDIRECT  
iptables -t nat -N REDTCP
iptables -t nat -A REDTCP -d 0.0.0.0/8 -j RETURN
iptables -t nat -A REDTCP -d 10.0.0.0/8 -j RETURN
iptables -t nat -A REDTCP -d 100.64.0.0/10 -j RETURN
iptables -t nat -A REDTCP -d 127.0.0.0/8 -j RETURN
iptables -t nat -A REDTCP -d 169.254.0.0/16 -j RETURN
iptables -t nat -A REDTCP -d 172.16.0.0/12 -j RETURN
iptables -t nat -A REDTCP -d 192.168.0.0/16 -p tcp ! --dport 53 -j RETURN
iptables -t nat -A REDTCP -d 198.18.0.0/15 -j RETURN
iptables -t nat -A REDTCP -d 224.0.0.0/4 -j RETURN
iptables -t nat -A REDTCP -d 240.0.0.0/4 -j RETURN
iptables -t nat -A REDTCP -p tcp -j REDIRECT --to-ports 12345
iptables -t nat -A PREROUTING -p tcp -j REDTCP

局部UDP代理规则 (开启全局UDP 这部分要注释掉) 手动指定IP端口 可解决DNS污染
iptables -t nat -N REDDNS
iptables -t nat -A REDDNS -p udp --dport 53 -j REDIRECT --to-ports 10053
iptables -t nat -A PREROUTING -p udp -j REDDNS

以上是我抄来的,可能存在错误。
复制之后保存到一个 shell 脚本中(openwrt 可以配置开机自动运行脚本),或者使用其他方法(因为iptables 规则会在重启之后恢复原状,所以要每次启动运行该 shell 脚本,也其他可持续性改变规则的方法)


下载并使用 geph4-client

下载地址
x64 https://f001.backblazeb2.com/file/geph-dl/geph4-binaries/v4.4.20/geph4-client-linux-amd64
armv7(32bit) https://f001.backblazeb2.com/file/geph-dl/geph4-binaries/v4.4.20/geph4-client-linux-armv7

可以使用 openwrt 自带 wget 或者 Curl 进行下载
运行脚本请参考 Getting the latest Geph4 and usage / 最新二進制版下載 + 簡易使用教學


通过 Dnscrypt-proxy 解决 dns 污染问题

但是通过验证,会发现一些问题,无法正常翻墙
原因是 dns 污染没有解决。那么该如何解决这个问题呢?
按照 dnscrypt-proxy 官网提供 openwrt 配置文档 进行配置:


至此就可以正常使用了。

2 Likes

如果redsocks已经成功了,可以考虑下dns over tcp,通过tcp模式查询dns。相关话题: dns-over-tcp · GitHub Topics · GitHub

感谢回复,我不了解该如何处理。但我做了一些尝试。
从论坛搜索信息来看 ,Geph 代理本身是能够理dns 请求的。
先尝试用 redsocks 本身功能 dnstc 和 dnsutp 我也不明白如何处理。
之后,我从 openwrt 官方软件库入手,找到一款软件 DNSCrypt-proxy2

看介绍 DNSCrypt 是可以解决 dns 投毒问题的,我就按照https://github.com/DNSCrypt/dnscrypt-proxy/wiki/Installation-on-OpenWrt
文档进行安装,并按推荐调整进行了设置

然后似乎 dns投毒 问题就解决了,但和我安装的 DNSCrypt-proxy2 有无直接关系并不清楚。
还是因为我杜绝使用路由网关的上游 dns 解析服务,所以自然可以解决这个问题?

1 Like

能解决就好呀!~

原因应该是你默认的dns为192.168.1.1,所以dns请求被上面ignore lan的规则给跳过没走geph4了。我手动把本地dns改为8.8.8.8即可上网。
想问一下你有没有研究出更好的iptables规则。我现在在看如何用ipset只转发gfwlist,这样geph4下线了还能访问国内网

1 Like

谢谢解答,我到现在才搞明白这里出现的问题:
首先, redirect 对 udp 信息包无效(原因是 redirect 就是 dnat,所以 会吧 destation ip 给变成 127.0.0.1 ipv4)。 而 redsocks 本身大概考虑到了这一点配置文件 redudp 有专门重修改 dest_ip 为 dns 地址。需要配合 iptables 规则 将 53端口 的udp 包重定向到代理软件端口。

TPROXY版 iptables 规则 替代之前REDIRCT版本(tproxy 比redirect 支持udp 和 ipv6)

#全局UDP代理规则 iptables+TPROXY
ip route add local 0.0.0.0/0 dev lo table 100
ip rule add fwmark 1 table 100
iptables -t mangle -N REDUDP
iptables -t mangle -A REDUDP -d 0.0.0.0/8 -j RETURN
iptables -t mangle -A REDUDP -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A REDUDP -d 100.64.0.0/10 -j RETURN
iptables -t mangle -A REDUDP -d 127.0.0.0/8 -j RETURN
iptables -t mangle -A REDUDP -d 169.254.0.0/16 -j RETURN
iptables -t mangle -A REDUDP -d 172.16.0.0/12 -j RETURN
iptables -t mangle -A REDUDP -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN
iptables -t mangle -A REDUDP -d 192.168.0.0/16 -p tcp ! --dport 53 -j RETURN
iptables -t mangle -A REDUDP -d 198.18.0.0/15 -j RETURN
iptables -t mangle -A REDUDP -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A REDUDP -d 240.0.0.0/4 -j RETURN
iptables -t mangle -A REDUDP -p udp -j TPROXY --on-port 10053 --tproxy-mark 0x1/0x1
iptables -t mangle -A REDUDP -p tcp -j TPROXY --on-port 12345 --tproxy-mark 0x1/0x1
iptables -t mangle -A PREROUTING -p udp -j REDUDP

# 新建 DIVERT 规则,避免已有连接的包二次通过 TPROXY,理论上有一定的性能提升
iptables -t mangle -N DIVERT
iptables -t mangle -I PREROUTING -p tcp -m socket -j DIVERT
iptables -t mangle -A DIVERT -j MARK --set-mark 1
iptables -t mangle -A DIVERT -j ACCEPT

参考于 V2Ray 透明代理(TPROXY)
第一篇万字长文:围绕透明代理的又一次探究
参考于 Iptables+Tproxy+RedSocks(TCP/UDP)透明代理原理淺析
参考于redsocks 文档收录 http://www.balabit.com/download/files/tproxy/
Powerdns 关于 tproxy的文档
www.kernel.org 关于 tproxy 的文档

此方案未经测试

2 Likes

如果 要在通用 linux 发行版上部署,
还需要开启路由转发功能:
/etc/sysctl.conf
net.ipv4.ip_forward=1
net.ipv6.ip_forward=1

迷雾通用户分享的 nftables 规则:

/etc/nftables.conf

#!/usr/sbin/nft -f

#flush ruleset

define RESERVED_IP = {
    10.0.0.0/8,
    100.64.0.0/10,
    127.0.0.0/8,
    169.254.0.0/16,
    172.16.0.0/12,
    192.0.0.0/24,
    224.0.0.0/4,
    240.0.0.0/4,
    255.255.255.255/32
}

table ip nat {
  chain output {
    type nat hook output priority filter; policy accept;
    ip daddr $RESERVED_IP return
    ip protocol tcp redirect to :12345
  }
  chain prerouting {
    type nat hook prerouting priority dstnat; policy accept;
    ip protocol tcp redirect to :12345
    ip protocol udp redirect to :10053
  }
}

tproxy 方案(未经测试

#!/usr/sbin/nft -f

#flush ruleset

define RESERVED_IP = {
    10.0.0.0/8,
    100.64.0.0/10,
    127.0.0.0/8,
    169.254.0.0/16,
    172.16.0.0/12,
    192.0.0.0/24,
    224.0.0.0/4,
    240.0.0.0/4,
    255.255.255.255/32
}

table ip geph {
        chain prerouting {
                type filter hook prerouting priority mangle; policy accept;
                ip daddr $RESERVED_IP return
                ip daddr 192.168.0.0/16 tcp dport != 53 return
                ip daddr 192.168.0.0/16 udp dport != 53 return
                ip protocol tcp tproxy to 127.0.0.1:10053 meta mark set 1
                ip protocol udp tproxy to 127.0.0.1:10053 meta mark set 1
        }
        chain output {
                type route hook output priority mangle; policy accept;
                ip daddr $RESERVED_IP return
                ip daddr 192.168.0.0/16 tcp dport != 53 return
                ip daddr 192.168.0.0/16 udp dport != 53 return
                ip protocol tcp meta mark set 1
                ip protocol udp meta mark set 1
        }
}