V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
AaIT
V2EX  ›  程序员

有偿找懂路由 iptables tcp udp 的老哥解决一个全端口转发的问题

  •  
  •   AaIT · 2023-08-29 13:38:05 +08:00 · 2853 次点击
    这是一个创建于 450 天前的主题,其中的信息可能已经有所发展或是发生改变。

    机器 A:1.1.1.1
    机器 B:2.2.2.2

    二台都是具有独立公网 IP 的 KVM 虚拟机
    公网 IP 都是静态配置在虚拟机内部也就是经典网络

    A 只允许 B 的 IP 入站,其他 IP 全部屏蔽流量进不来
    这样就导致远程管理 ssh 也进不去了,所以需要 B 把流量转发到 A 上

    B 的 IP 完全为 A 提供服务,希望能实现访问 B 的任意端口就等于访问 A 的对应端口
    需要能转发 TCP 和 UDP 流量,当然 TCP 这个简单些,UDP 这个就比较麻烦了

    A 交付给客户,所以方案尽量不用在 A 的机器上安装什么东西
    B 客户用不了,只是作为透明转发

    方案还是有很多,比如可以组 IP 隧道然后路由到隧道里
    或者直接 A 做内网穿透客户端 B 做内网穿透服务器端
    但这些都需要在 A 上安装程序做对接

    IP 路由的话好像改不了源 IP 这样压根过不了 A 的防火墙
    目前尝试 iptables 端口段转发性能不是太好,另外 UDP 能通但无法传输数据

    有经验的老哥请加我微信,谢谢

    31 条回复    2023-08-31 09:33:17 +08:00
    iqoo
        1
    iqoo  
       2023-08-29 13:47:25 +08:00
    写个 libpcap 程序转发包会不会更简单些~
    yyzh
        2
    yyzh  
       2023-08-29 13:52:17 +08:00 via Android
    你是不是在说 1:1NAT?
    zbinlin
        3
    zbinlin  
       2023-08-29 14:03:17 +08:00
    全部端口都转发了,这样做对于 A 的入站限制不是没意义了?
    AaIT
        4
    AaIT  
    OP
       2023-08-29 14:15:38 +08:00
    @zbinlin 有意义呀,入站限制不是为了保护流量,而是为了保护 A 的 IP 防止外部探测
    360750581
        5
    360750581  
       2023-08-29 17:00:14 +08:00   ❤️ 2
    那这么做了,探测 B 不就是探测 A ?
    zbinlin
        6
    zbinlin  
       2023-08-29 17:32:09 +08:00
    怎么测试的?如果转发可以试试走 OFFLOAD
    kaedeair
        7
    kaedeair  
       2023-08-29 17:38:03 +08:00
    绑个域名 tcp 反代的事
    wangbin526
        8
    wangbin526  
       2023-08-29 17:51:38 +08:00
    没理解,既然 A 的防火墙只允许 B 的 IP 入站,B 的 IP 对外泄露需要更换的话,还得手动修改 A 的防火墙配置啊
    至于配置转发的话,手动配置 IP-Tables 容易出错,建议通过 UFW 的 IP 伪装功能来配置,透明转发或者指定端口转发都行,没接触过这么奇怪的需求,理论上应该可行吧
    开个玩笑,如果 B 单纯做透明转发的话,干脆 B 装个 OpenWrt ,然后将 A 的 IP 设置为 DMZ 主机,完全映射端口不就是了
    kuanat
        9
    kuanat  
       2023-08-29 18:58:58 +08:00
    直接说结论:如果 A 的防火墙
    kuanat
        10
    kuanat  
       2023-08-29 19:13:14 +08:00
    直接说结论:

    如果 A 的防火墙是类似于 `iptables -t nat -A PREROUTING -s 2.2.2.2 -j ACCEPT` 的形式,那就无法通过 NAT 的形式做端口映射。

    做全端口映射的原理就是楼上说的 DMZ ,转换成 iptables 规则就是 B 作为 A 的网关,对出流量做 SNAT ,对入流量做 DNAT 。

    但是 A 的防火墙规则限制了来源只能是 B ,那 B 要对入流量同时做 SNAT ,修改其来源 IP 为 B 2.2.2.2 ,这就导致 A 认为请求来源都是 B ,回复的 DstIP 都是 B 2.2.2.2 ,因而无法正常返回数据。

    解决的办法是:

    1. B 以反向代理( reverse proxy )的形式工作,这样 A 可以保留防火墙规则。但反向代理对于协议有限制,tcp/http 类可以,udp 很难。

    2. A/B 各自增加一个网络接口,两个接口之间建立某种点对点链路,然后走 NAT 映射
    pedh
        11
    pedh  
       2023-08-29 20:05:12 +08:00 via iPhone
    A 只允许 B 的 IP 入站,这个是有状态还是无状态的?或者说 A 主动访问公网,你希望源 ip 是 1.1.1.1 还是 2.2.2.2 ?
    AaIT
        12
    AaIT  
    OP
       2023-08-29 20:32:09 +08:00
    @kuanat #10 感谢细致回复,这里补充下信息,

    A 是交付给客户使用的虚拟机,大多数是 Linux 也有部分客户装 win 系统
    所以最好 A 机器不要装任何东西和做任何调整,所有的操作在 B 机器完成

    二台机器都在美国同一个城市,不涉及跨境也没有网络抖动
    A 机器内部没有防火墙,限制是在安全组上做的,类似阿里云服务器的安全组

    这么做的原因是 A 是住宅 IP 所以不想对外暴露任何端口,并不是为了保护流量或者别的啥
    仅仅是为了保护 A 的 IP 本身,且由于封闭了入站造成管理和远程使用的麻烦

    就想着用另一个机房 IP 也就是 B 来转发所有流量,虽然屏蔽了入站随便弄个 tailscale 组网非常简单
    但对用户来说不简单,或者内网穿透也可以,所以最终的目的就是 A 屏蔽入站的前提下不改变使用习惯

    只要日常使用连接 B 就等于连接 A 透传所有的流量过去,比如 socks5 这种,不仅仅是 TCP 直播还需要用到 UDP 协议

    处理起来都很麻烦,所以感觉有点棘手
    AaIT
        13
    AaIT  
    OP
       2023-08-29 20:33:10 +08:00
    @wangbin526 是为了保护 A 得住宅 IP 哈,B 得 IP 泄露无所谓的,B 是一个机房的 IP ,随便泄露没啥事
    kuanat
        14
    kuanat  
       2023-08-29 22:48:16 +08:00
    因为你这个做法很不常见,我猜测可能是 XY 问题导致的偏差,所以特地去看了你的使用场景。

    这里我引用一下"为什么要搞 IP 保护"的描述:"暴露的端口会被探测",看到这里我就理解你的需求了。

    本质上你是在保护自己的 IP 资产,而不是客户,客户只是租用而已。因为你以虚拟机的形式为客户交付服务,并不能控制客户在虚拟机上的行为,比如客户可以在在这个公网 IP 上开放公开的 http/socks 服务等等。

    怎么向客户描述这个问题不重要,但是你的思路被带偏了,甚至说你的整体产品架构思路都被带偏了。当然这只是我个人的想法,可能理解有偏差。

    如果我来设计的话,向客户交付的部分其实是 B ,而 A 是由自己完全控制的,A 是 B 的路由器。技术层面,B 本身就是云服务,利用 VPC 保证 B 的所有出站流量都一定由 A 路由就可以了。

    这样做的附加好处是,所有 A 节点都可以用低成本标准化的网络设备完成,无需托管真实主机,至于 B 完全可以利用云服务来提供定制。
    tril
        15
    tril  
       2023-08-29 23:29:15 +08:00
    单端口转发我是这么做的,UDP 也可以正常转发。不知道多端口转发可不可以靠复制 65535 遍或者将单端口换成端口段( 443 改成 1:65535 )或者直接删除端口相关参数来实现,仅供参考。

    假设 2.2.2.2 是你 B 机入站网卡上获得的 IP ( B 机的公网 IP 是多少不重要),将 B 的 443/udp 端口转发到 A 的 443/udp 端口:

    # 目的地转换
    iptables -t nat -A PREROUTING -p udp -d 2.2.2.2 --dport 443 -j DNAT --to-destination 1.1.1.1:443
    # 源地址转换
    iptables -t nat -A POSTROUTING -p udp -d 1.1.1.1 --dport 443 -j SNAT --to-source 2.2.2.2

    # 如果 B 机启用了 UFW 则需要放行对应的转发流量
    # ufw route allow to 1.1.1.1 port 443 proto udp
    # 内核需要允许 IPv4 转发
    # echo 'net.ipv4.ip_forward=1' > /etc/sysctl.conf && sysctl --system

    数据进 B 的时候先做目的地转换,改成“客户端-->A”,在数据出 B 之前做源地址转换,进一步改成“B-->A”。回程的时候 B 机会自动反向操作一遍,最终发给客户端的数据是“B-->客户端”。

    TCP 同理,只需要把 udp 改成 tcp 。
    realpg
        16
    realpg  
       2023-08-29 23:31:51 +08:00
    你这个涉及逻辑都不自洽

    如果按照你的设想,任何 tcp udp 包到 B 的 ·任意· 端口都转发给 A 那么 B 就相当于跟互联网断开了……
    AaIT
        17
    AaIT  
    OP
       2023-08-29 23:42:24 +08:00
    @kuanat #14 是的,是这个道理,老哥理解很到位,只是目前刚起步小规模不想把架构弄的太复杂
    就是能用稳定就行,有位 V 站老哥详细帮我查了,后来发现并不是 NAT 转发性能不行
    而是 ATT 宽带的光猫不行对数据包有限制,每秒 25pps ICMP TCP UDP 都这样
    但是走隧道的话好像不会触发限制,这样集中转发,源 IP 都是 B 更容易触发限制
    大概情况情况就是这样,看来只能双向建立隧道,然后走隧道通讯了


    AaIT
        18
    AaIT  
    OP
       2023-08-29 23:44:56 +08:00
    @realpg 是的,这是作为小白的一种直白的表达,不用深究技术细节
    feather12315
        19
    feather12315  
       2023-08-29 23:49:54 +08:00 via Android
    要性能用 xdp ,cllium 项目。
    具体怎么用需要看看。
    1423
        20
    1423  
       2023-08-30 00:08:12 +08:00
    原来你就是博客里喷 AperNet 的那个..
    1423
        21
    1423  
       2023-08-30 00:11:31 +08:00
    op 在博客里喷友商“迷惑路由” https://aait.io/blog/63.html
    结果自己搞不懂技术方案,跑论坛里发帖请教

    真是迷惑行为
    northernsnowx
        22
    northernsnowx  
       2023-08-30 00:35:26 +08:00
    笑死,喷了半天 AperNet ,结果现在又想来复刻人家的架构了 23333
    AaIT
        23
    AaIT  
    OP
       2023-08-30 01:12:02 +08:00
    @northernsnowx 他那个出口住宅 IP 不是独享的,是多人共享变动的,而且并不是所有流量都走住宅 IP 出去
    我说的没错呀,我是详细测试过才说的,如果他确实是独享的住宅 IP 那我没啥好说的
    我们这是独享的 IP ,IP 是静态配置在虚拟机内部的,可以保证是独享
    多人共享的住宅 IP 说白了就是 NAT 嘛,外面套了一个独享的机房 IP
    他的方案就类似上面老哥说的那种思路,你愿意买一个和别人共享的住宅 IP 拿来做业务做直播吗
    花同样甚至更便宜买独享的住宅 IP 不是更香,而且我们还是自己拉的宽带
    Jirajine
        24
    Jirajine  
       2023-08-30 01:12:04 +08:00 via Android
    楼上说的对,这是一个 XY PROBLEM ,你把住宅 IP 分配给交付给客户的虚拟机,已经跑偏了。
    交付给客户的虚拟机本身不需要分配公网 ip ,只有内网 ip 即可。通过内网穿透或 vpn 隧道的方式让客户能够通过 ssh/rdp 访问。
    公网 ip 分配给客户虚拟机的网关,客户虚拟机通过这个网关上网。如果允许客户在这个 ip 上开放服务的话,只需要在网关上做 1:1NAT ,也就是 DMZ 转发。同样的要控制客户能使用哪些端口和防扫描,也只需要在这个网关设备上配置防火墙。
    AaIT
        25
    AaIT  
    OP
       2023-08-30 01:15:12 +08:00
    @1423 #21 AperNet 是迷惑路由我说的没有任何问题
    稍微懂点的都能看得出来本质区别,一个人不可能解决所有问题
    而且我发帖写的很清楚有偿,有愿意说两句愿意指点下的表示感谢
    有能力强的想赚点零花钱,一个需要指导一个有技术,大家你情我愿,这有什么问题
    AaIT
        26
    AaIT  
    OP
       2023-08-30 01:20:53 +08:00
    @northernsnowx 而且我从始至终说的是如何把流量引导到住宅 IP 的虚拟机上
    而不是说如何用机房 IP 做自定义路由搞些花活,你要喷好歹搞清楚重点
    我们自己有资源,IP 不够用就再拉宽带就可以了,没必要用那种方法来糊弄人
    还复刻他的架构,A 那个虚拟机里面配的静态 IP 是机房 IP 出站路由的 IP 才是住宅 IP
    而且还会经常变动,这种一看就不是独享的
    AaIT
        27
    AaIT  
    OP
       2023-08-30 01:24:57 +08:00
    @Jirajine 从技术上讲这种方法不好,但是住宅 IP 静态配置到虚拟机里可以自证是独享的住宅 IP
    这一点很重要,就像很多卖住宅 Socks5 的都说他的是独享的或者说你在用的时候是独享的
    这个怎么证明,那么多端口,一个 IP 可以卖 65535 个人,而且分配的都是高位端口
    或者可以自定义端口,比如可以自定义任何低位端口,这样才能证明是独享吧
    Jirajine
        28
    Jirajine  
       2023-08-30 01:48:13 +08:00 via Android
    @AaIT #27 NAT 可以用来共享,但 NAT 和是否共享没有关系。
    如果你要把公网 ip 分配到交付给客户的主机上,那这个 ip 是公网可达的,无论你是否允许客户在这个 ip 上开放服务、使用哪些端口开放服务,同样可以在网关配置防火墙,那你的需求到底是什么?

    PS:其实把公网 IP 配置到客户主机上也无法证明是独享的,国内家宽的假公网 ip 方案 NAT 4444 了解一下,华为的专利设备。
    snoopygao
        29
    snoopygao  
       2023-08-30 09:48:16 +08:00
    上边太多不想翻了,你应该在 A 机上直接做全端口转发,然后 A 上做 MASQURADE ,这样 B 从 A 接受的全部为 A 的地址
    AaIT
        30
    AaIT  
    OP
       2023-08-30 11:45:02 +08:00
    @snoopygao 是的,已经查明原因了,我自己写的 iptables 规则是对的没有任何问题
    原因是 ATT 的光猫有连接数限制,25pps 突发 50 带宽没有任何问题,每个源 IP 的连接数一超就被丢弃了
    所以一直没有引起重视,因为这个限制比较隐蔽,压根没往这上面想,已经联系运营商加钱升级套餐更换没有限制的光猫了
    bearwinnie
        31
    bearwinnie  
       2023-08-31 09:33:17 +08:00 via Android
    iptables -t nat -A POSTROUTING -p TCP -j MASQUERAD
    iptables -t nat -A POSTROUTING --dst 192.168.10.2 -p tcp --d port 22 -j MASQUERADE
    iptables -t nat -A POSTROUTING -p UDP -j MASQUERADE
    iptables -t nat -A POSTROUTING --dst 192.168.10.2 -p udp --dport 22 -j MASQUERADE
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5641 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 01:39 · PVG 09:39 · LAX 17:39 · JFK 20:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.