menu

Passwall

一个 tcp 请求的生命周期:

Domain -> dnsmasq(route#53)-不匹配任何名单-> 本地 dns -> ip <
               |_> 匹配代理名单 -> tproxy -> 远程 dns -> ip -> 写入相应 ipset nameset <
               |_> 匹配直连名单 -> 本地 dns -> ip -> 写入相应 ipset nameset <

ip -> iptables
        |_> 匹配代理 nameset -> rediect -> tproxy
        |_> 直接转发

名单

passwall 预配置有多个名单和支持自定义名单,也包括未匹配名单的数据。当中总体上可分为两种:

  1. 代理名单
  2. 直连名单

按名单项的类型又可分为

  1. ip
  2. 域名

ip 直接导入 ipset 对应的集合中,配合 iptables 实现各个代理策略。

域名,需要通过 dnsmasq 查询后,由 dnsmasq 添加到对应的 ipset 集合中。

dnsmasq 又通过域名所在名单的不同,选择不同的上游 ns 服务器。

ns 服务器也分为两种:

  1. 本地 ns
  2. 远程 ns

名单

DNS

对域名进行分流解析,也就是白名单用一个 dns,黑名单用一个 dns。

DNS 端口是写死的。DOH 端口是 7912,本地 DNS 是 7913, other(china_ng_gfw) 是 7914

dnsmasq

https://stackoverflow.com/a/37449551/851344

dnsmasq 是路由默认的 dns 服务。也是 dhcp 下发的默认 dns 地址。

dnsmasq 的上游有两个 dns,一个是本地 dns,一个是远程 dns。

配合黑白名单, dnsmasq 将黑名单里的域名通过远程 dns 查询。白名单的域名通过本地 dns 查询。

当然实际 passwall 的名单不只两个。但总的来说就是黑白名单两类。

最后 dnsmasq 再将查询到的地址,根据对应名单的性质添加进相应的 ipset 中。

Local Dns

用来解析白名单的 dns,默认是 DEFAULT_DNS,是指在 /tmp/resolv.conf.d/resolv.conf.auto/tmp/resolv.conf.auto 配置的 dns,

若未配置则取 119.29.29.29

openwrt-passwall/app.sh at main · xiaorouji/openwrt-passwall

DOH

用了 aarond10/https_dns_proxy: A lightweight DNS-over-HTTPS proxy. ,将 udp 的请求转发到 doh 服务器。

但是 https_dns_proxy 配置成只接受本地链接(127.0.0.1),其他主机的 dns 请求是如何转发的?

新版用 [xray-doh],来实现转发 doh,还支持通过 socks 代理。直接 tcp 链接是通过:

"streamSettings": {
         "sockopt": {
           "mark": 255
         }

然后在 iptables 控制 mark 0xff 不走代理。

Socks5

https://tools.ietf.org/html/rfc1928

iptables

Nat 表 , Prerouting 链创建一条子链 PSW:

Pkts.	Traffic	Target	Prot.	In	Out	Source	Destination	Options	Comment
16.95 K	1.08 MB	RETURN	all	*	*	0.0.0.0/0	0.0.0.0/0	match-set laniplist dst	-
0 	0 B	RETURN	all	*	*	0.0.0.0/0	0.0.0.0/0	match-set vpsiplist dst	-
474 	33.11 KB	RETURN	all	*	*	0.0.0.0/0	0.0.0.0/0	match-set whitelist dst	-
0 	0 B	REDIRECT	tcp	*	*	0.0.0.0/0	0.0.0.0/0	multiport dports 22,25,53,143,465,587,993,995,80,443 match-set shuntlist dst redir ports 1041	'默认'
427 	26.02 KB	REDIRECT	tcp	*	*	0.0.0.0/0	0.0.0.0/0	multiport dports 22,25,53,143,465,587,993,995,80,443 match-set blacklist dst redir ports 1041	'默认'
18.34 K	1.11 MB	REDIRECT	tcp	*	*	0.0.0.0/0	0.0.0.0/0	multiport dports 22,25,53,143,465,587,993,995,80,443 ! match-set chnroute dst redir ports 1041	'默认'
4.93 K	344.18 KB	RETURN	tcp	*	*	0.0.0.0/0	0.0.0.0/0	-	'默认'

haproxy 负载均衡

passwall 生成的负载均衡配置文件:

global
    log         127.0.0.1 local2
    chroot      /usr/bin
    maxconn     60000
    stats socket  /var/etc/passwall/haproxy/haproxy.sock
    user        root
    daemon

defaults
    mode                    tcp
    log                     global
    option                  tcplog
    option                  dontlognull
    option http-server-close
    #option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 2
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000

listen 1181
    mode tcp
    bind 0.0.0.0:1181
    server g1.dourok.info:443 g1.dourok.info:443 weight 5 check inter 1500 rise 1 fall 3
    server g2.dourok.info:443 g2.dourok.info:443 weight 5 check inter 1500 rise 1 fall 3
listen console
    bind 0.0.0.0:1188
    mode http
    stats refresh 30s
    stats uri /
    stats admin if TRUE
    stats auth

我以为 backend 是本地的 tcp 端口,比如多个本地 xray 服务监听不同短空,一个 haproxy frontend。 结果是 backend 是 xray 服务端的地址,与域名无关的可以用这种方式(tcp mode),与域名有关的,比如 xless 估计用不了,另外 xray 配置文件也没有涉及 haproxy 对应的端口,不清楚这样做的目的是什么。

Rule list

/usr/bin/lua/luci/model/cbi/passwall/client/rule_list.lua

重点在这个函数

function m.on_apply(self)
luci.sys.call("/etc/init.d/passwall reload > /dev/null 2>&1 &")
end

reload 未实现,所以每次保存列表都会重启服务

Fake Ip

Socks5 是支持将整个请求打包给代理服务器。

TUN/TAP

Redirect 与 TProxy 的区别

keyboard_arrow_up