AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 1130454
Accepted
Derek Edwards
Derek Edwards
Asked: 2023-05-05 23:52:45 +0800 CST2023-05-05 23:52:45 +0800 CST 2023-05-05 23:52:45 +0800 CST

当有多个网络时允许路由到/从网络

  • 772

我这里有一个艰难的人,但似乎无法找出正确的路线。

我有一个位于两个独立网络上的服务器 (serverA): 192.168.200.x/24& 192.168.117.0/26。此服务器有一个主机名 ( serverA.example.com)192.168.117.70和一个单独的连接通过192.168.200.45(这是在此网络上安装存储/等所必需的)。

我没有办法在内部执行 split-DNS,因此我需要将所有内容路由到此 IP/主机名以保证用户的安全。

目前,所有不在网络上的东西192.168.200.x都可以serverA.example.com正常访问。但是 上的所有系统192.168.200.x都无法路由到该IP 地址,但它们可以正常192.168.117.70访问。192.168.200.45

这是我在 serverA 上设置的路由:

0.0.0.0           192.168.117.65    0.0.0.0         UG    0      0        0 onboard-10Gb-1
192.168.117.64    0.0.0.0         255.255.255.192 U     0      0        0 onboard-10Gb-1
192.168.200.0     0.0.0.0         255.255.255.0   U     0      0        0 bond0

我在路由等方面没有太多经验,所以我知道我在这里遗漏了一些东西。

iptables
  • 1 1 个回答
  • 41 Views

1 个回答

  • Voted
  1. Best Answer
    A.B
    2023-05-09T23:39:50+08:002023-05-09T23:39:50+08:00

    长话短说

    ip route add 192.168.117.64/26 dev onboard-10Gb-1 table 1000 
    ip route add default via 192.168.117.65 dev onboard-10Gb-1 table 1000
    ip rule add from 192.168.117.70 lookup 1000
    

    有关详细信息以及正确处理 UDP 服务的信息,请阅读下文。


    注意:在 Linux 上,route和ifconfig是过时的命令。它们不适用于策略路由等高级路由。应该系统地使用iproute2替代品:ip route,ip link和(以及iproute2ip address套件中的所有其他相关命令)。


    策略路由

    当从那里查询时,多宿主服务器默认直接回复连接的 LAN 192.168.200.0/24(下面的示例将使用位于 192.168.200.101 的假设系统),而不是遵循查询来自的路径。这是一个非对称流,可能会因各种原因而失败,其中包括:

    • 服务器本身在配置时将按照严格的反向路径转发rp_filter=1规则丢弃此类不对称流量。
    • 看不到回复的路径中的防火墙可能被配置为丢弃流量(例如,在跟踪 TCP 窗口时)
    • 如果 NAT 发生在某处:直接回复未经过 NAT 处理并被客户端丢弃
    • 服务器在托管不支持多宿主的 UDP 服务时会选择错误的回复地址,从而使客户端丢弃此类回复。

    即使没有前 3 种情况,TCP 也可能工作,UDP 在最后一种情况下更加困难,单独的策略路由对于 UDP 来说通常并不总是足够的(见下面的警告),但仍然是必需的。

    这需要策略路由,以便在进行路由决策以回复时单独考虑每个地址。

    在 Linux 上,这是通过使用带有选择器的路由规则来实现的,以使用备用路由表,这些路由表将只知道选定目标所需的路径:仅是所有可能路由的部分副本。所选择的选择器通常是一个标准,取决于目的地以外的其他事物(已经提供了标准路由条目)。大多数时候它是源地址,但这取决于目标。

    这里的目标是拥有一个不具体了解 192.168.200.0/24 的路由表,以便在从 192.168.117.70 做出回复时使用默认路由onboard-10Gb-1而不是 LAN 路由进行路由。bond0

    只复制路由表 1000 中需要的路由(值 1000 任意选择):

    ip route add 192.168.117.64/26 dev onboard-10Gb-1 table 1000 
    ip route add default via 192.168.117.65 dev onboard-10Gb-1 table 1000
    

    当源地址是192.168.117.70,即是服务器地址时,先查备选路由表1000(查主路由表前:如果查到路由成功,主表就不用了) :

    ip rule add from 192.168.117.70 lookup 1000
    

    可以添加其他 LAN 的等效表和规则,但它已经由主路由表处理。传入流量已首先由本地路由表处理,因此与此设置无关:

    # ip rule
    0:      from all lookup local
    32765:  from 192.168.117.70 lookup 1000
    32766:  from all lookup main
    32767:  from all lookup default
    

    然后在server上,取决于服务的使用方式:

    • TCP 服务绑定或不绑定到特定地址始终有效

      任何accept(2)-ed 套接字都将其源(本地)地址设置为查询使用的目标地址,因此发出的数据包将在需要时匹配路由规则选择器:对于这种情况无需做更多的事情。

    • TCP客户端或UDP客户端在查询/连接时可以绑定源地址,改变路径:

      TCP 和 UDP 示例:

      ssh -b 192.168.117.70 [email protected]
      
      traceroute -n -s 192.168.117.70 192.168.200.101
      

    预期的备用路由表 1000 将根据所选的源地址进行选择:

    # ip route get from 192.168.117.70 to 192.168.200.101
    192.168.200.101 from 192.168.117.70 via 192.168.117.65 dev onboard-10Gb-1 table 1000 uid 0 
        cache 
    

    警告:UDP 服务

    UDP 和 BSD 套接字 API 的工作方式,默认情况下不绑定地址的 UDP 套接字(即使用 0.0.0.0 又名 INADDR_ANY),当它用于回复收到的 UDP 消息时,没有查询的所有上下文,特别是它不会有查询发送到的服务器的本地地址,与 TCP 相反:它只会使用套接字的 0.0.0.0 地址。

    因此,当回复从 192.168.200.101 到 192.168.117.70 的查询时,它将向路由堆栈提供一个 0.0.0.0 的源,以推迟路由堆栈对实际源地址的选择。这不会匹配 192.168.117.70 的路由规则选择器,回复将使用主路由表,选择错误的源回复地址:192.168.200.45。当客户端收到这样的回复(直接来自同一个 LAN)时,它不会将其识别为对其查询的回复:它来自其他地址,并将忽略它。

    有两种方法可以让 UDP 服务器应用程序正确处理此问题:

    • bind(2)到一个特定的地址。

      使用此套接字的任何答复都将使用它绑定到的地址。从而选择路由规则和预期的路由行为。如果服务器必须在它的所有地址上提供服务,它应该多次绑定相同的方式:每个地址一次。

      大多数守护进程中都有设置可以做到这一点。例如,默认情况下,ISC 的 DNS 服务器bind 9绑定到属于该服务器的所有地址并跟随动态变化。当查询到达这样的套接字时,绑定套接字的地址就是查询的目的地地址。它将被重新用作源地址,从而选择正确的路由规则。

    • 否则使用套接字选项IP_PKTINFO

      这使得应用程序能够接收辅助数据,使其知道在哪个地址和哪个接口上接收到数据包,并提供所有信息以进行正确回复。这需要特定的应用程序支持,包括使用附加功能,例如cmsg(3).

      例如,当使用服务器选项时,这就是 NLnet Labs 的 DNS 服务器未绑定的操作模式interface-automatic: yes。

    如果 UDP 服务器应用程序根本无法更改,那么就只剩下糟糕的选择了。

    使用Netfilter的conntrack和iptables将不起作用:可以更改输出挂钩中的目标,但必须更改的是源。可以在postrouting挂钩中更改源,但顾名思义,它是在路由之后:选择备用路由为时已晚。即使它被允许,因为它是关于对现有流的回复的NAT , Netfilter也不会正确处理它并且会更改用于回复的源端口以避免仅假定的冲突而不是重用相同的流.

    在这种情况下,可以使用额外的选择器,根据服务和目的地(在本例中为回复)选择备用源选择器,以强制进行其他选择:源 192.168.117.70 而不是 192.168.200.45 (现在从 192.168.200.101 到 192.168.200.45 的直接查询会因为类似的原因而失败)。

    例如,如果服务器要在端口 5555 上托管一个简单的 UDP 服务,该服务不能配置为绑定到 192.168.117.70 或使用IP_PKTINFO并且永远不应该在 192.168.200.0/24 上直接使用 LAN 到 LAN,可以轻推正确的路由选择(这需要内核 >= 4.17):

    ip rule add from 0.0.0.0/32 ipproto udp sport 5555 to 192.168.200.0/24 lookup 1000
    

    这里 0.0.0.0/32 用于其 INADDR_ANY 角色。路由堆栈最终会用足够的源替换它,但这次选择使用路由表 1000。

    前:

    # ip route get ipproto udp sport 5555  to 192.168.200.101
    192.168.200.101 dev bond0 src 192.168.200.45 uid 0 
        cache 
    

    后:

    # ip route get ipproto udp sport 5555 to 192.168.200.101
    192.168.200.101 via 192.168.117.65 dev onboard-10Gb-1 table 1000 src 192.168.117.70 uid 0 
        cache 
    

    不会影响其他情况(如:源端口5556):

    # ip route get ipproto udp sport 5556 to 192.168.200.101
    192.168.200.101 dev bond0 src 192.168.200.45 uid 0 
        cache 
    

    nftables

    实际上,还存在一个较差的解决方案作为ip rule上面添加的第二个的替代方案,使用nftables代替执行静态 NAT 不依赖于Netfilter的conntrack。这是要加载的规则集nft -f ...:

    table t_statelessnat
    delete table t_statelessnat
    
    table ip t_statelessnat {
            chain c_snat {
                    type route hook output priority raw; policy accept;
                    ip daddr 192.168.200.0/24 ip saddr != 192.168.117.70 udp sport 5555 ip saddr set 192.168.117.70
            }
    }
    
    

    类型路由挂钩将负责重新路由现在将遍历路由表 1000 的数据包。

    ip rule除非需要无法使用的复杂过滤器,否则最好使用路由规则。

    • 1

相关问题

  • OpenVPN 的 Linux IP 转发 - 正确的防火墙设置?

  • iptables 单个规则中的多个源 IP

  • 存储 iptables 规则的规范方法是什么

  • 使用 iptables 和 dhcpd 进行端口转发

  • 根据 Apache 日志数据自动修改 iptables 以阻止行为不良的客户端

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve