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

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

  •  
  •   AaIT · 242 天前 · 2488 次点击
    这是一个创建于 242 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    如果 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  
       241 天前 via iPhone
    A 只允许 B 的 IP 入站,这个是有状态还是无状态的?或者说 A 主动访问公网,你希望源 ip 是 1.1.1.1 还是 2.2.2.2 ?
    AaIT
        12
    AaIT  
    OP
       241 天前
    @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
       241 天前
    @wangbin526 是为了保护 A 得住宅 IP 哈,B 得 IP 泄露无所谓的,B 是一个机房的 IP ,随便泄露没啥事
    kuanat
        14
    kuanat  
       241 天前
    因为你这个做法很不常见,我猜测可能是 XY 问题导致的偏差,所以特地去看了你的使用场景。

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

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

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

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

    这样做的附加好处是,所有 A 节点都可以用低成本标准化的网络设备完成,无需托管真实主机,至于 B 完全可以利用云服务来提供定制。
    tril
        15
    tril  
       241 天前
    单端口转发我是这么做的,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  
       241 天前
    你这个涉及逻辑都不自洽

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


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

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

    PS:其实把公网 IP 配置到客户主机上也无法证明是独享的,国内家宽的假公网 ip 方案 NAT 4444 了解一下,华为的专利设备。
    snoopygao
        29
    snoopygao  
       241 天前
    上边太多不想翻了,你应该在 A 机上直接做全端口转发,然后 A 上做 MASQURADE ,这样 B 从 A 接受的全部为 A 的地址
    AaIT
        30
    AaIT  
    OP
       241 天前
    @snoopygao 是的,已经查明原因了,我自己写的 iptables 规则是对的没有任何问题
    原因是 ATT 的光猫有连接数限制,25pps 突发 50 带宽没有任何问题,每个源 IP 的连接数一超就被丢弃了
    所以一直没有引起重视,因为这个限制比较隐蔽,压根没往这上面想,已经联系运营商加钱升级套餐更换没有限制的光猫了
    bearwinnie
        31
    bearwinnie  
       240 天前 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   ·   我们的愿景   ·   实用小工具   ·   2874 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 07:16 · PVG 15:16 · LAX 00:16 · JFK 03:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.