V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
herozzm
V2EX  ›  Linux

iptables 层面如何做到判断 header 来做反向代理?

  •  
  •   herozzm · 2021-05-08 21:53:27 +08:00 · 3880 次点击
    这是一个创建于 1281 天前的主题,其中的信息可能已经有所发展或是发生改变。

    正常情况下,可以用 iptables -t nat -A PREROUTING ... 来实现反向代理的,但是这个层面是无法判断 header 的,那么有其他办法吗?

    需求是只允许带有某个 header 的请求反向代理成功,其他一律拒绝

    27 条回复    2021-05-10 11:28:21 +08:00
    AngryPanda
        1
    AngryPanda  
       2021-05-08 21:58:33 +08:00 via iPhone   ❤️ 1
    应用层数据,nginx 就能实现了
    herozzm
        2
    herozzm  
    OP
       2021-05-08 22:00:59 +08:00
    @AngryPanda 就是不想转到 nginx 去处理啊,端口实在太多,有上百千个端口到 nginx? nginx 貌似不能简单绑定多个端口去做处理,都是 listen 单个端口去做判断
    seerhut
        3
    seerhut  
       2021-05-08 22:14:03 +08:00
    很久以前的确有人给 kernel 做 7 层的 filter,但似乎并没有正式并入内核,需要手动 patch,近几年似乎大家对内核空间中做 7 层处理没什么兴趣了,毕竟 dpdk 啥的让上层处理报文效率相当不错了。你这个需求是不是可以让 iptables 把包都扔给本机的 ng 一个端口上,再让 ng 处理 7 层?
    FreeEx
        4
    FreeEx  
       2021-05-08 22:14:28 +08:00 via iPhone
    你需要的或许是一个 API 网关。
    billlee
        5
    billlee  
       2021-05-08 23:18:27 +08:00
    @herozzm 你还要拦截非 80 端口的吗?
    herozzm
        6
    herozzm  
    OP
       2021-05-08 23:24:12 +08:00
    @billlee 是的
    billlee
        7
    billlee  
       2021-05-08 23:36:00 +08:00
    你的需求讲的很不清楚。拦截所有端口,如果拦下来后发现不是 HTTP 协议,那是要放行还是阻断?

    我觉得内核里解析 HTTP 就不要想了,但有很多方案可以在内核把流量重定向到用户空间进程,比如 iptables TPROXY, tun2socks
    herozzm
        8
    herozzm  
    OP
       2021-05-08 23:49:08 +08:00
    @billlee 我要拦截指定端口的 tcp 访问,然后判断其 header 中某个参数,符合条件就放行(反向代理),我现在用 iptables 将指定的几百个端口都转到了 nginx 的某个端口,然后在 nginx 里面去获取 header 来做反向代理,已经实现了,iptables 层面感觉很难做
    dangyuluo
        9
    dangyuluo  
       2021-05-09 00:29:54 +08:00
    自己写一个 Module ?杀鸡用牛刀的感觉
    learningman
        10
    learningman  
       2021-05-09 01:10:39 +08:00 via Android
    我琢磨过这个,答案是可行,但是巨麻烦。
    因为 iptables 操作的是 IP 包,你得拆两层才能拿到应用层数据,而且有可能的网卡分包
    fkdog
        11
    fkdog  
       2021-05-09 02:20:34 +08:00
    iptables 是工作在网络层,怎么可能管的到应用层的 http 协议。
    你需要一个应用层的防火墙
    herozzm
        12
    herozzm  
    OP
       2021-05-09 02:25:11 +08:00 via Android
    @fkdog filter 可以得到的
    tony601818
        13
    tony601818  
       2021-05-09 05:53:36 +08:00
    > 你需要的或许是一个 API 网关。

    +1 可以看看 Netflix 开源的 Zuul
    gam2046
        14
    gam2046  
       2021-05-09 07:04:40 +08:00
    这应该是 7 层干的事情,网络层去搞,非常麻烦,要不你统一在目标应用上加前置代理,由前置代理决定出口,如果目标应用不提供使用代理的功能,就套上 proxychains,这相对来说容易实现,成本也低。

    而你要分析 HTTP 头,那注定不能是 HTTPS,除非客户端信任你的自签证书,也就是说本身你的应用场景应该就是可控的场景,而不是针对任意第三方,所以加代理可能是比较容易的。
    yaxin
        15
    yaxin  
       2021-05-09 07:53:31 +08:00 via iPhone
    iptables 将特定端口数据转发到 nginx 处理就行了吧
    xuanbg
        16
    xuanbg  
       2021-05-09 08:01:41 +08:00   ❤️ 1
    7 层的事情就应该在 7 层处理,无论它有多少问题。你妄图在 4 层处理 7 层的事情,只会导致更多的问题。
    ElmerZhang
        17
    ElmerZhang  
       2021-05-09 10:48:37 +08:00
    iptables 就不是用来干 7 层的事情的,用 haproxy 或者 nginx 吧
    wangritian
        18
    wangritian  
       2021-05-09 13:57:25 +08:00
    赞同很多人提到的网络层不要干应用层的事,我好奇的是为什么一个 http 服务器需要几百个端口?统一到 80 然后通过 Host 分配二级域名做虚拟主机不可以吗
    PolarBears
        19
    PolarBears  
       2021-05-09 14:45:56 +08:00
    @wangritian 可能是想做透明代理?
    herozzm
        20
    herozzm  
    OP
       2021-05-09 17:15:27 +08:00
    @wangritian 没有域名,ip+端口 访问服务这不是正常的操作吗?
    LGA1150
        21
    LGA1150  
       2021-05-09 17:24:52 +08:00 via Android
    iptables nat 表只能匹配到新连接的包,对于 TCP 来说就是 SYN,看不到应用层的数据。

    你可能要找的是 ipvs
    Lemeng
        22
    Lemeng  
       2021-05-09 17:35:26 +08:00
    也是来学习的
    wangritian
        23
    wangritian  
       2021-05-09 17:44:40 +08:00
    @PolarBears 有可能,只允许定制的客户端访问这些端口

    @herozzm 一个服务这样做是正常的,几百个就应该在 7 层管理了,除非是特殊需求
    falcon05
        24
    falcon05  
       2021-05-09 17:53:41 +08:00 via iPhone
    http 明文传输是肯定是可以的,好像以前做过,https 理论上也可以,需要读取私钥或者信任证书,类似 Wireshark 的抓包。但我觉得还是应该在应用层解决比较好
    xenme
        25
    xenme  
       2021-05-09 17:59:19 +08:00 via iPhone
    直接 iptables 接管所有流量转发到 nginx,然后再 nginx 处理呗。透明代理现在都是这种思路
    falcon05
        26
    falcon05  
       2021-05-09 18:07:06 +08:00
    哦,以前做的是拦截某个 header 的 http 请求,比如 X-Forwarded-For

    iptables -I INPUT 1 -p tcp --dport 80 -m string --algo bm --string 'X-Forwarded-For:' -j DROP

    firewall-cmd --direct --add-rule ipv4 filter INPUT_direct 10 -p tcp --dport 80 -m string --algo bm --string 'X-Forwarded-For:' -j DROP
    julyclyde
        27
    julyclyde  
       2021-05-10 11:28:21 +08:00
    你都明知道不存在了还问啥啊
    用-m match 处理并不能保证结果正确
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2612 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 05:41 · PVG 13:41 · LAX 21:41 · JFK 00:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.