Closed zw963 closed 7 years ago
For use with router.
@madeye , I see two guides, one is from README.md#advanced-usage, one is from ss-redir.asciidoc#example, I don't know which better.
And what difference about following command
# ip rule add fwmark 0x01/0x01 table 100
# ip route add local 0.0.0.0/0 dev lo table 100
# ip rule add fwmark 1 lookup 100
# ip route add local default dev lo table 100
which is the correct choice for a asus router transparent proxy?
Maybe show my problem is better than just ask why.
https://github.com/zw963/asuswrt-merlin-transparent-proxy/blob/master/route/opt/etc/iptables.sh
this is my iptables.sh rule for my AC5300, UDP rule is added recent days. I am not sure those UDP is worked as execpt, could anyone point out some improper/wrong usage? Or, maybe I missing some rule?
Thanks
@chenhw2, @madeye , 谁有时间, 麻烦给解释一下, 先谢啦.
Try PREROUTING
chain instead of OUTPUT
chain.
Try PREROUTING chain instead of OUTPUT chain.
What does you means?
https://github.com/zw963/asuswrt-merlin-transparent-proxy/blob/master/route/opt/etc/iptables.sh
I am not use OUTPUT chain, tcp and udp all apply with PREROUTING
chains
看了你的规则, 谈一些看法, 抛砖引玉吧
# 这行代码为什么要开启?
# $ipt -I OUTPUT 1 -p tcp -j SHADOWSOCKS
这条开启后, 路由器自身也可以通过 ss 代理上网了, 不开启的话只有路由器下的设备能通过代理.
$ipt -A SHADOWSOCKS -p udp --dport 53 -j TPROXY --on-port 1082 --tproxy-mark 0x01/0x01
关于udp, 你就只有这条规则. 但是只对 53端口的 udp 才有效果. 如果你只想转发 DNS 查询到远端服务器, 还不如用 ss-tunnel
呢
@icymind
这条开启后, 路由器自身也可以通过 ss 代理上网了, 不开启的话只有路由器下的设备能通过代理.
谢, 这个和我理解一致.
关于udp, 你就只有这条规则. 但是只对 53端口的 udp 才有效果. 如果你只想转发 DNS 查询到远端服务器, 还不如用 ss-tunnel 呢
我有用 ss-tunnel, 我这里的 1082 的确就是 ss-tunnel 的端口, ss-redir 是 1080, 而且 ss-redir 没有开启 -u .
你的意思: 这条规则如果用 ss-tunnel, 是无用的吗?
如果你已经设置了 dnsmasq 将 dns 转发到 1082, 那么这条规则就是无用的.
@icymind , 搞错啦, 我完全搞错啦, 谢谢提示, 难怪别人跟我反馈, 加了 UDP rule 之后, 反而 DNS 不能用了.
但是只对 53端口的 udp 才有效果.
这句话不是很明白.
假设我使用 ss-redir(不用 ss-tunnel 了), 并且开启了 dup relay, 也应用了这些 UDP rule,
我还需要配置 dnsmasq 的默认 DNS 吗? 例如: server=/#/8.8.4.4#53
$ipt -A SHADOWSOCKS -p udp -m set --match-set FREEWEB dst -j RETURN
$ipt -A SHADOWSOCKS -p udp --dport 53 -j TPROXY --on-port 1080 --tproxy-mark 0x01/0x01
我的本意: 如果是白名单(FREEWEB)中的域名, 直接返回, 不是白名单的(国外的)域名, 走 ss-redir (1080 端口)
但是只对 53端口的 udp 才有效果.
我的意思是你的这条规则$ipt -A SHADOWSOCKS -p udp --dport 53 -j TPROXY --on-port 1080 --tproxy-mark 0x01/0x01
只匹配 53 端口的 udp (-p udp --dport 53
), 对匹配到的包打标记.
如果 udp 能转发成功, 那就不需要了. 但是你确定要所有的 dns 查询都发送给服务器查询吗? 那样的话国内的网站可能会解析到一个比较慢的地址.
如果你想转发 53 端口之外的 UDP, 那就需要.
@icymind ,
对匹配到的包打标记.
这里打了标记, 怎么用呢? 是不是和下面的两行一起工作?
# ip rule add fwmark 0x01/0x01 table 100
# ip route add local 0.0.0.0/0 dev lo table 100
是的. 按我的理解, 大概意思是:
ip route add local 0.0.0.0/0 dev lo table 100
添加一个 id 是 100 的路由表, 该表的数据默认从 lo
回环设备发送出去
ip rule add fwmark 0x01/0x01 table 100
对标记是 0x01/0x01
的数据包, 查询 id 是 100 的路由表, 根据路由表的内容决定他的路径.
至于路由表100里是什么内容, 我就不知道了. 我没看到有任何规则往里面添加内容呢
@icymind , 标记那个懂了, 谢谢.
不过, 有关 ss-redir 现在已经完全晕了.
下面是手动启动 ss-redir, 开启 udp relay 支持, 和另一个 ss-tunnel.
# ss-redir -u -c /opt/etc/shadowsocks.json -vvv
2017-09-05 10:57:26 INFO: initializing ciphers... aes-256-cfb
2017-09-05 10:57:26 INFO: UDP relay enabled
2017-09-05 10:57:26 INFO: listening at 192.168.50.1:1080
2017-09-05 10:57:26 INFO: running from root user
# ss-tunnel -c /opt/etc/shadowsocks.json -b 127.0.0.1 -l 1082 -L 8.8.4.4:53 -u
2017-09-05 11:04:43 INFO: initializing ciphers... aes-256-cfb
2017-09-05 11:04:43 INFO: UDP relay enabled
2017-09-05 11:04:43 INFO: listening at 127.0.0.1:1082
2017-09-05 11:04:43 INFO: running from root user
然后, 在路由器里面, dig -p 1082 www.google.de
返回正确结果 (ss-tunnel)
dig -p 1080 www.google.de
就没有结果.(ss-redir)
这是不是不正常啊?
事实上 , 1080 端口(ss-redir) 日志一点反应都没有, 仿佛没有收到 udp 请求.
admin@RT-AC5300-5E70:/tmp/home/root# dig www.google.de -p 1080
; <<>> DiG 9.10.5 <<>> www.google.de -p 1080
;; global options: +cmd
;; connection timed out; no servers could be reached
@icymind , 看样子就没有监听 udp 的端口, 請指教.
admin@RT-AC5300-5E70:/tmp/mnt/sda1/entware/etc# netstat -an |grep 1080
tcp 0 0 192.168.50.1:1080 0.0.0.0:* LISTEN
udp 0 0 192.168.50.1:1080 0.0.0.0:*
监听了. 只不过 udp 没有 LISTEN
字样罢了.
另外你监听的是 192.168.50.1:1080, 并没有监听 127.0.0.1, 建议监听 0.0.0.0
即使你监听了 127.0.0.1, dig -p 1080 www.google.de
也不会有预期的结果. 我的理解是这样(可能是错的):
dig
时, 产生一个目标地址是127.0.0.1:1080
的UDP包, ss-redir 拿到了这个包, 然后用ss协议封装后发送到了服务器. 服务器打开封包, 发现地址是 127.0.0.1:1080
, 然后就发送到了服务器的 1080 端口, 并不会解析. 如果你只想看 ss-redir
日志有没有变化, 那倒是一个可行的办法.
如果你想验证 ss-redir 能不能查询 dns, 应该:
dig @8.8.8.8 google.com
8.8.8.8:53
的 udp 并把它发送到服务器一篇, 希望能帮助你理解. 没问题就关闭 issues 吧
@icymind, 那篇文章链接有错. :smile:
好吧, 我发现我刚刚收藏了你的文章! 哈哈. https://icymind.com/learn-from-gfw/
而且下午我还推荐给 issue #1667 看, 如果是这篇的话, 我已经拜读过了!
即使你监听了 127.0.0.1, dig -p 1080 www.google.de 也不会有预期的结果. 好像是的, 重启后, 验证了下. (如果没错的话)
参照你那篇文章的例子:
server=/#/8.8.8.8#53
iptables -t nat -A OUTPUT -p tcp --dport 53 -d 8.8.8.8 -j REDIRECT --to-port 1080
iptables -t nat -A OUTPUT -p udp --dport 53 -d 8.8.8.8 -j REDIRECT --to-port 1080
; <<>> DiG 9.10.5 <<>> @8.8.8.8 www.google.de
; (1 server found)
;; global options: +cmd
;; connection timed out; no servers could be reached
@icymind, 你在 https://icymind.com/learn-from-gfw/ 中的测试结果, 是在路由器上吗?
真是奇了怪了.
哎, 不做死了, 我还是 ss-redir + ss-tunnel 凑合着用吧.
真的是 : 不懂原理出了问题简直就像傻逼似的, 根本就没法解决。
...
@icymind, 最后一个问题, 一切根源的始作俑者是因为这个 issue.
https://github.com/shadowsocks/shadowsocks-libev/issues/1632
当时看 Youtube 速度超级慢, 然后, @madeye 答复说, 可能是 udp relay 的问题,
答复如下:
As mentioned above, it's caused by QUIC and UDP relay. Two possible solutions:
Disable QUIC in Chrome. (Search the issue tracker for more details)
Follow the script of OpenWRT (TPROXY kernel module is required) or flash your router to OpenWRT instead.
好吧, 麻烦 @madeye 再回答一下, 当时你说的 udp relay 问题, 是指的 ss-redir 的 udp relay + iptables 问题, 还是说 ss-tunnel
的 udp relay 问题?
是不是我这种 ss-redir + ss-tunnel 的方案就没有你说的问题?
@icymind, 有空也指教下. 哈
ss-tunnel 只转发 DNS, Youtube 的 QUIC协议不关 ss-tunnel 的事. 关掉 Chrome 的 QUIC 最省事.
不想折腾这些原理的话, 不妨试试 😄
确认下是否quic的问题,y2be时检查是否走了udp443,也就是通常所说的直连,没有经过ss。
是的话简单解决即可(不用mangle用nat也应该可以,10800为随意未使用的端口): iptables -t mangle -A PREROUTING -p udp -m set --match-set youtube dst -j TPROXY --on-port 10800 --tproxy-mark 0x01/0x01
dnsmasq.d中加入ipset文件youtube.conf ipset=/.googlevideo.com/youtube
@baggiogogo ,
是的话简单解决即可(不用mangle用nat也应该可以,10800为随意未使用的端口): iptables -t mangle -A PREROUTING -p udp -m set --match-set youtube dst -j TPROXY --on-port 10800 --tproxy-mark 0x01/0x01
这里 10800 是 ss-tunnel 端口还是 ss-redir 端口呢?
不想折腾这些原理的话, 不妨试试 VRouter 😄
Cool, 我不用 Mac, 不过 Linux 是不是应该更简单了, 连 VirtualBox 都不要了?
@chenhw2, @madeye , 劳烦, 你们谁在有空的时候, 能讲一下 $ipt -A SHADOWSOCKS -p udp --dport 53 -j TPROXY --on-port 1082 --tproxy-mark 0x01/0x01
从前面的讨论来看, 这行代码是对匹配的包打了一些标记, 这个应该是没有问题的, 但是打了标记, 我们又能干啥? 这行代码的真实用意到底是做什么的?
似乎整个 shadowsocks 缺乏对这个的讨论, 每个人提到这个, 都讳莫如深
的感觉, 或者给一些完全看不懂变量名啥意思的代码供参考, 没有头绪啊, 我想要解释, 五句话以内应该能讲清楚吧 ...
@chenhw2 , 请问, 这里面的哪一条 rule, 跟之前打标记的那个 UDP rule 有关?
include_ac_rules() {
local protocol=$([ "$1" = "mangle" ] && echo udp || echo tcp)
iptables-restore -n <<-EOF
*$1
:SS_SPEC_LAN_DG - [0:0]
:SS_SPEC_LAN_AC - [0:0]
:SS_SPEC_WAN_AC - [0:0]
:SS_SPEC_WAN_FW - [0:0]
-A SS_SPEC_LAN_DG -m set --match-set ss_spec_dst_sp dst -j RETURN
-A SS_SPEC_LAN_DG -p $protocol $EXT_ARGS -j SS_SPEC_LAN_AC
-A SS_SPEC_LAN_AC -m set --match-set ss_spec_src_bp src -j RETURN
-A SS_SPEC_LAN_AC -m set --match-set ss_spec_src_fw src -j SS_SPEC_WAN_FW
-A SS_SPEC_LAN_AC -m set --match-set ss_spec_src_ac src -j SS_SPEC_WAN_AC
-A SS_SPEC_LAN_AC -j ${LAN_TARGET:=SS_SPEC_WAN_AC}
-A SS_SPEC_WAN_AC -m set --match-set ss_spec_dst_fw dst -j SS_SPEC_WAN_FW
-A SS_SPEC_WAN_AC -m set --match-set ss_spec_dst_bp dst -j RETURN
-A SS_SPEC_WAN_AC -j SS_SPEC_WAN_FW
$(gen_prerouting_rules $protocol)
COMMIT
EOF
}
@zw963 To use ss-redir udp relay with ASUS, you have to change 1 rule,
ss-redir.json
{
"server":"VPS IP",
"server_port":VPS PORT,
"local_address":"192.168.1.1",
"local_port":1080,
"password":"password",
"method":"chacha20-ietf-poly1305",
"timeout":60
}
iptables rule
iptables -t mangle -A SHADOWSOCKS -p udp -m set --match-set gfwlist dst -j TPROXY --on-ip 192.168.1.1 --on-port 1080 --tproxy-mark 0x01/0x01
--on-ip 192.168.1.1 is a point.
@odkrys, Hi, Your example use a black list (gfwlist), But, I use a white list.
Following is my rule, FREEWEB is whitelist which can access directly from china.
ipset -N FREEWEB iphash
iptables -t mangle -A SHADOWSOCKS -p udp -m set --match-set FREEWEB dst -j RETURN
iptables -t mangle -A SHADOWSOCKS -p udp --dport 53 -j TPROXY --on-port 1082 --tproxy-mark 0x01/0x01
What I expect is: if DNS match FREEWEB, use default DNS, othersize, redirect DNS to 1082(ss-tunnel) But, I don't know above rule if work as expect.
Thanks
----------- Update -------- if change your's rule to white list, how to do that?
I have no idea about whitelist. I just use countable sites on list. When you test the rules, you must add --on-ip 192.168.1.1 in rule.
let's check, https://ly798.github.io/2016/01/02/%E5%B0%8F%E7%B1%B3mini-%E7%A7%91%E5%AD%A6%E4%B8%8A%E7%BD%91/
@zw963 不是任何使用中的端口,任何随意无用的端口即可,当YouTube走quic时,走得通它会走,走不通会回到tcp去,这样就不用费力处理udp部分了,另外是方便kcptun之类的加速,如果走了quic,就享受不到了,app之类的不能关闭quic的也可以正常使用。
另外一定要用udp转发的话,分情况的,游戏这些的话你上面这些iptables就可以了,涉及到dns还要处理OUTPUT链。
这样或许直观一点
UDP在 表: Mangle
中处理
具体 TPROXY 的用法可以参考 http://itoedr.blog.163.com/blog/static/1202842972013631258540/
不是任何使用中的端口,任何随意无用的端口即可
@baggiogogo , 晕哦, 难道我又完全错了.
iptables -t mangle -A PREROUTING -p udp -m set --match-set youtube dst -j TPROXY --on-port 10800 --tproxy-mark 0x01/0x01
这条 rule 的 --on-port 竟然指定到一个完全没有被监听的端口, 是这样的意思吗? 我一直以为这个端口必须是 ss-redir 监听的那个端口.
好吧, 如果上面 --on-port 10800 理解没错的话, 请问, 这条语句到底在做什么事情?
@chenhw2 , 请教几个在我的理解范围内的问题:
tcp dpt 80 match-set koolproxy dst
, 这里的 koolproxy
是白名单还是黑名单? 还望解答. 谢谢.
@zw963 这两个是我自己另外的处理,与SS无关,可以忽略
@chenhw2 , 为了节省你宝贵的时间, 我创建了一个我的脚本的新的分支, 并加了很多注释, 麻烦你看一下, 直接就问题来解决问题.
@zw963 没有梅林设备,只搞过LEDE/OpenWRT
@chenhw2 , 我只是想找到只使用 ss-redir 实现透明代理的路子, 这点 merlin 和 openwrt 是相同的吧?
你可以指导下我那个脚本该如何编写吗?
@zw963 这两个是我自己另外的处理,与SS无关,可以忽略
你截的那个图里面, 有那个和 ss-redir 做透明代理(udp relay)有关呢?
你可以告诉我哪一行, 或者再截个部分图, 或者你可以直接指导下 我那个 iptables.sh 文件该如何编写这块的 rule 呢?
@zw963 带SS字样(不区分大小写)的都是和ss-redir 做透明代理(udp relay)有关
@chenhw2 , 好吧, 能看出一点儿眉目的, 貌似只有下面两条, 有些疑问
tproxy redirect 0.0.0.0:1234 mark 0x1 0x1
, 里面的那个 1234 端口, 是什么端口呢?@zw963 您搞混了,关键不知您到底想解决的是什么问题,是quic的问题,还是一定要做udp转发。
解决quic有三个办法,1关闭浏览器quic(这样对于app就无解了),2使quic走不通重新回到SS tcp去(任何简单的iptables只要能达到这个效果,那都可以),3做udp转发(这样会涉及到dns问题,除非dns做tcp查询),复杂程度依次递增1<2<3
如果一定要做udp转发,那思路和ss-redir透明转发tcp是一样的,假设采用tcp查询dns,只处理PREROUTING肯定是不够的,还要处理OUTPUT。 至少要加上以下(中间应该也需要加内网地址防止回环,仅供参考), iptables -t mangle -N SHADOWSOCKS_MARK iptables -t mangle -A SHADOWSOCKS_MARK -d 8.8.8.8 -p udp --dport 53 -j MARK --set-mark 1 iptables -t mangle -A OUTPUT -p udp -j SHADOWSOCKS_MARK
以上都是在不开ss-tunnel只用ss-redir的情况下,另外如果做udp转发,ss-redir肯定要加-u的,不加它只处理tcp,相应ss-server也必须加-u。
@icymind , 为什么我参照你的下面配置, 在路由器上从来不工作 ...
先配置dnsmasq用4个8查询Evil-Domain: 把127.0.0.1#1080改为8.8.8.8#53
然后再用iptables把发往8.8.8.8的数据包转发给ss-redir:
iptables -t nat -A OUTPUT -p udp --dport 53 -d 8.8.8.8 -j REDIRECT --to-port 1080
然而通过观察,虽然ss-server收到了udp数据,但是udp的目标地址仍然是127.0.0.1#1080。这个方法并不奏效。
添加一条规则,试试如果使用TCP查询DNS,ss-server能不能进行正常的DNS解析:
iptables -t nat -A OUTPUT -p tcp --dport 53 -d 8.8.8.8 -j REDIRECT --to-port 1080
再次通过nslookup发起查询,结果观察到ss-server收到数据后成功向8.8.8.8发送请求,并将响应发回了ss-redir。
@baggiogogo
您搞混了,
是的, 完全搞乱了.
关键不知您到底想解决的是什么问题,是quic的问题,还是一定要做udp转发。
这里有描述我的精确问题. 谢谢, 看了你的答复, 看样子我少了 SHADOWSOCKS_MARK 之类的代码??
@baggiogogo, 能否直接针对那个 iptables.sh, 指点一二?
@baggiogogo , 且不论我是否理解具体含义 我根据你最近的回复, 我改写了 udp rule,
你看下, 给点指导意见, 例如哪些地方写的部队, 或者根本没有必要. 我的目的暂时先定为一个, 让 ss-redir 可以支持 DNS 查询.
ip rule add fwmark 0x01/0x01 table 100
ip route add local 0.0.0.0/0 dev lo table 100
ipt="$iptables -t mangle"
$ipt -N SHADOWSOCKS
$ipt -N SHADOWSOCKS_MARK
# 本地回环 ip 集合.
for i in $localips; do
$ipt -A SHADOWSOCKS -d "$i" -j RETURN
done
$ipt -A SHADOWSOCKS -p udp -m set --match-set FREEWEB dst -j RETURN
$ipt -A SHADOWSOCKS -p udp --dport 53 -j TPROXY --on-port 1080 --tproxy-mark 0x01/0x01
$ipt -A SHADOWSOCKS_MARK -d 8.8.8.8 -p udp --dport 53 -j MARK --set-mark 1
# 应用规则, 注释这行代码, 重启后会让 UDP rules 失效.
$ipt -I PREROUTING 1 -p udp -j SHADOWSOCKS
$ipt -A OUTPUT -p udp -j SHADOWSOCKS_MARK
抱歉,不是太懂脚本,但看大意是差不多了,您能否实际尝试一下能否正常工作,如还是不行晚点我用树莓派试验。
很好理解的,PREROUTING是针对局域网进入路由的请求(比如DNS),如果以这个路由作为一个dns服务器,那局域网的请求进入以后,路由自身还要出去真正的dns服务器查询随后反馈,路由器这个请求就需要用OUTPUT。
麻烦就麻烦在tproxy用法上,确实有点云里雾里的,处理tcp链的nat就很容易理解。
I found two version UDP rule for ss-redir, I have no idea which version to choose.
version1: From ss-redir.asciidoc#example
version2: From README.md#advanced-usage
Thanks