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

一个很诡异的网络问题,我完全没有排查思路了

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

    环境(在 window server 上用 vmware 虚拟了 3 台服务器):

    • 1.服务器 A ( linux ,部署了 nginx 监听 80 端口,并关闭了防火墙)
    • 2.服务器 B ( linux )
    • 3.服务器 C ( window server )

    问题:

    B 服务器可以正常访问 A 服务器上的 ningx 服务,宿主机也可以正常访问; C 服务器上虽可以 ping 通服务器 A ,但是 telnet A 服务器的 80 及所有已监听的端口都不通,在 A 服务器上通过 tcpdump 抓包也发现一直没有响应 C 服务器的 tcp 握手请求,C 服务器重试两次后放弃, 诡异的是在 A 服务器上可以正常访问 C 服务器上的服务,而且 A 服务器在重启后有几分钟是可以被 C 服务器访问的。

    请问上面的问题如何排查原因,我想要知道为什么 A 服务器偏偏不响应 C 服务器的 tcp 握手请求,系统日志也没有异常,但是宿主机和 B 服务器是可以正常访问的,而且防火墙也关了。请各位大佬帮我分析分析大概是什么原因,并给出排查方法,谢谢了。

    以下是 gpt4 给出的回复:

    在这种情况下,我们需要检查多个可能导致此问题的因素。以下是一些建议:
    
    1. **虚拟网络设置**: 检查 VMware 中的网络设置,确保服务器 C 的网络接口设置与服务器 A 和 B 的设置相同。VMware 有几种不同的网络选项,如 NAT ,桥接和主机模式,它们可能会导致不同的行为。
    
    2. **IP 配置**: 检查服务器 A 、B 和 C 的 IP 地址设置,包括 IP 地址、子网掩码和网关,确保它们在同一网络段中。
    
    3. **网络路由**: 在服务器 C 上运行`tracert`或`tracepath`命令( Windows 下为`tracert`,Linux 下为`tracepath`),看看数据包是如何从服务器 C 到服务器 A 的。这可能会揭示网络路由问题。
    
    4. **防火墙设置**: 尽管你提到服务器 A 的防火墙已关闭,但还需要检查服务器 C 的防火墙设置,以及任何可能存在的网络级别的防火墙或安全组设置。
    
    5. **服务监听**: 确认 Nginx 确实在监听来自所有 IP 地址的连接,而不仅仅是来自特定 IP 地址或网络接口的连接。你可以在服务器 A 上运行`netstat -tuln | grep 80`命令来查看。
    
    6. **操作系统安全策略**: 检查服务器 A 和 C 的操作系统级别的安全策略,如 SELinux 或 AppArmor 等,确保它们没有阻止这种类型的连接。
    
    7. **VMware 的安全策略**: VMware 也可能有一些安全策略可能阻止虚拟机之间的某些连接,这个也可以检查。
    
    8. **网络硬件问题**: 虽然这种可能性较小,但也不能完全排除网络硬件或驱动问题。
    
    希望这些步骤能帮助你诊断问题。如果上述所有步骤都无法解决问题,可能需要进一步深入研究网络配置和虚拟机设置。
    
    
    第 1 条附言  ·  321 天前
    问题解决了,是我手贱设置了 linux 参数优化,改了默认配置:
    ```
    cat /etc/sysctl.conf
    sysctl -a | grep net.ipv4.tcp_fin_timeout

    vim /etc/sysctl.conf



    net.ipv4.tcp_fin_timeout = 2 #保持在 FIN-WAIT-2 状态的时间,使系统可以处理更多的连接。此参数值为整数,单位为秒。
    net.ipv4.tcp_tw_reuse = 1 #开启重用,允许将 TIME_WAIT socket 用于新的 TCP 连接。默认为 0 ,表示关闭。
    net.ipv4.tcp_tw_recycle = 1 #开启 TCP 连接中 TIME_WAIT socket 的快速回收。默认值为 0 ,表示关闭。
    net.ipv4.tcp_syncookies = 1 #开启 SYN cookie ,出现 SYN 等待队列溢出时启用 cookie 处理,防范少量的 SYN 攻击。默认为 0 ,表示关闭。
    net.ipv4.tcp_keepalive_time = 600 #keepalived 启用时 TCP 发送 keepalived 消息的拼度。默认位 2 小时。
    net.ipv4.tcp_keepalive_probes = 5 #TCP 发送 keepalive 探测以确定该连接已经断开的次数。根据情形也可以适当地缩短此值。
    net.ipv4.tcp_keepalive_intvl = 15 #探测消息发送的频率,乘以 tcp_keepalive_probes 就得到对于从开始探测以来没有响应的连接杀除的时间。默认值为 75 秒,也就是没有活动的连接将在大约 11 分钟以后将被丢弃。对于普通应用来说,这个值有一些偏大,可以根据需要改小.特别是 web 类服务器需要改小该值。
    net.ipv4.ip_local_port_range = 1024 65000 #指定外部连接的端口范围。默认值为 32768 61000 。
    net.ipv4.tcp_max_syn_backlog = 262144 #表示 SYN 队列的长度,预设为 1024 ,这里设置队列长度为 262 144 ,以容纳更多的等待连接。
    net.ipv4.tcp_max_tw_buckets =5000 #系统同时保持 TIME_WAIT 套接字的最大数量,如果超过这个数值将立刻被清楚并输出警告信息。默认值为 180000 。对于 squid 来说效果不是很大,但可以控制 TIME_WAIT 套接字最大值,避免 squid 服务器被拖死。
    net.ipv4.tcp_syn_retries = 1 #表示在内核放弃建立连接之前发送 SYN 包的数量。
    net.ipv4.tcp_synack_retries = 1 #设置内核放弃连接之前发送 SYN+ACK 包的数量。
    net.core.somaxconn = 16384 #定义了系统中每一个端口最大的监听队列的长度, 对于一个经常处理新连接的高负载 web 服务环境来说,默认值为 128 ,偏小。
    net.core.netdev_max_backlog = 16384 #表示当在每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许发送到队列的数据包的最大数量。
    net.ipv4.tcp_max_orphans = 16384 #表示系统中最多有多少 TCP 套接字不被关联到任何一个用户文件句柄上。如果超过这里设置的数字,连接就会复位并输出警告信息。这个限制仅仅是为了防止简单的 DoS 攻击。此值不能太小。

    /sbin/sysctl -p #生效
    ```
    35 条回复    2023-05-14 01:11:47 +08:00
    cdoe
        1
    cdoe  
       321 天前 via Android
    网卡 ip 有没有冲突
    Pil0tXia
        2
    Pil0tXia  
       321 天前
    是 NAT 模式就换桥接模式试试,是桥接模式就换 NAT 模式试试。通过把服务器 A 复制成服务器 D 再测试的方式排除网关因素。
    问题应该出在“A 服务器在重启后有几分钟是可以被 C 服务器访问的”,如果你不清楚具体原因,直接重新部署一个服务器 D 试试。
    tony1016
        3
    tony1016  
       321 天前
    那就去 C 服务器抓包啊
    fuis
        4
    fuis  
       321 天前
    @jack778

    看看是不是 A 的半连接队列满了

    ```
    netstat -s | grep -i "listen"
    ```

    另外请回帖打出来这两个参数的值

    ```
    sysctl net.ipv4.tcp_max_syn_backlog
    sysctl net.ipv4.tcp_syncookies
    ```
    jack778
        5
    jack778  
    OP
       321 天前
    @tony1016 c 服务器抓包也是显示没有响应握手链接
    jack778
        6
    jack778  
    OP
       321 天前
    @cdoe 如果 ip 冲突了为啥其他服务器能正常访问,感觉应该不是
    JamesR
        7
    JamesR  
       321 天前
    需要楼主贴出宿主机,A ,B ,C 的 IP 地址,子网掩码,网关。
    1.可能 A 或 C 的 IP 地址配置不正确。
    2.可能宿主机有专门防火墙,需要配置宿主机上的防火墙,对虚拟机所有的 IP 地址放行。
    3.C 有防火墙没有关闭或配置不正确。
    MrGba2z
        8
    MrGba2z  
       321 天前
    > A 服务器偏偏不响应 C 服务器的 tcp 握手请求,系统日志也没有异常

    Nginx 有 C 无法访问时的 log 吗?
    fuis
        9
    fuis  
       321 天前
    然后还需要检查 Windows Server 上的这个值

    HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

    https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-2000-server/cc938202(v=technet.10)
    jack778
        10
    jack778  
    OP
       321 天前
    @fuis
    执行:netstat -s | grep -i "listen"
    输出:187 SYNs to LISTEN sockets dropped

    [root@localhost ~]# sysctl net.ipv4.tcp_max_syn_backlog
    net.ipv4.tcp_max_syn_backlog = 262144
    [root@localhost ~]# sysctl net.ipv4.tcp_syncookies
    net.ipv4.tcp_syncookies = 1
    jack778
        11
    jack778  
    OP
       321 天前
    @MrGba2z 没有,还没有到 nginx
    fuis
        12
    fuis  
       321 天前
    还有就是没开 tcp_tw_recycle 吧?
    A 上运行 sysctl net.ipv4.tcp_tw_recycle 看看
    MrGba2z
        13
    MrGba2z  
       321 天前
    @jack778

    > 宿主机和 B 服务器是可以正常访问的

    也是用 telnet 的方式么?
    iminto
        14
    iminto  
       321 天前   ❤️ 1
    看下两台服务器时间是否一致,不一致的话会受 tcp_tw_recycle 影响
    jack778
        15
    jack778  
    OP
       321 天前
    @fuis
    SyncDomainWithMembership = 1
    ForwardBroadcasts = 0
    IPEnableRouter = 0
    UseDomainNameDevolution = 1
    EnableICMPRedirect = 1
    DeadGWDetectDefault = 1
    DontAddDefaultGatewayDefault = 0
    jack778
        16
    jack778  
    OP
       321 天前
    @MrGba2z 是的,用 postman 可以联通接口
    jack778
        17
    jack778  
    OP
       321 天前
    @fuis net.ipv4.tcp_tw_recycle = 1 开了
    B 服务器的时间比 A 服务器慢了 1 分钟,这个有影响吗
    @iminto
    xyjincan
        18
    xyjincan  
       321 天前
    A 的 MAC 地址,IP 和网络内其他设备有冲突吧,检查一些这些设备 MAC,地址,扫描一下局域网
    jack778
        19
    jack778  
    OP
       321 天前
    @JamesR 如果是防火墙或者 ip 问题就很奇怪,就偏偏 C 服务器不能访问 A 服务器,其他一切都正常呀。我也没有设置黑名单,防火墙都关了。
    iminto
        20
    iminto  
       321 天前   ❤️ 1
    @jack778 有影响,要么关了 tcp_tw_recycle ,要么保证时间一致。
    zhangsanfeng2012
        21
    zhangsanfeng2012  
       321 天前
    ip 和路由表贴出来,网络问题不能靠猜
    fuis
        22
    fuis  
       321 天前   ❤️ 1
    @jack778 那你应该把 net.ipv4.tcp_tw_recycle 关掉
    jack778
        23
    jack778  
    OP
       321 天前
    @xyjincan 怎么检查 A 服务器的 mac 地址和 ip 地址是否有冲突呢,如果是这个问题的话,为什么偏偏就是 C 不能访问 A ,其他一切正常,感觉还是有点想不通,因为 tcp 握手请求已经到达 A 服务器了,只是没有响应而已。
    zbinlin
        24
    zbinlin  
       321 天前   ❤️ 1
    你都没列出它们的网络设置是怎样的
    jack778
        25
    jack778  
    OP
       321 天前
    @fuis 关掉就好了,当初手贱设置了 linux 优化参数将其设置 1 了,哈哈
    jack778
        26
    jack778  
    OP
       321 天前
    @iminto 谢谢,问题解决了
    jack778
        27
    jack778  
    OP
       321 天前
    @zhangsanfeng2012 谢谢,解决了
    jack778
        28
    jack778  
    OP
       321 天前   ❤️ 2
    下面是 gpt 的回复:
    ```
    是的,将 `net.ipv4.tcp_tw_recycle` 设置为 1 可能会导致一些问题,尤其是在网络地址转换( NAT )环境中。这主要是因为`net.ipv4.tcp_tw_recycle`选项会启用一种快速 TIME-WAIT 套接字回收策略,这会影响 TCP 的时间戳。

    当服务器和客户端之间的时间戳(这是 TCP 连接中的一部分)差距过大时(比如你提到的客户端时间慢了),如果开启了`net.ipv4.tcp_tw_recycle`,新的连接可能会被服务器错误地识别为旧的、已经关闭的连接的一部分,导致连接失败。

    另外,对于来自同一 NAT 设备的多个客户端,由于它们从服务器看来都拥有相同的 IP 地址,所以在`net.ipv4.tcp_tw_recycle`启用的情况下,这些客户端可能会面临连接问题。这是因为这个设置会使服务器对同一 IP 地址的多个连接产生混淆,可能导致一些连接被提前关闭。

    因此,尽管`net.ipv4.tcp_tw_recycle`可以提高服务器的性能,但在很多情况下,都不建议启用这个选项,以免引发上述的问题。
    ```
    cxxlxx
        29
    cxxlxx  
       321 天前
    和我之前遇到的一样,tcp_tw_recycle
    jack778
        31
    jack778  
    OP
       321 天前
    @fuis 谢谢
    yinmin
        32
    yinmin  
       321 天前
    大概率:mac 地址冲突,或者局域网有 arp 欺骗。vmware 的虚拟机网卡配置里能看到 mac 地址。
    liu1297528606
        33
    liu1297528606  
       320 天前 via Android
    把机器的防火墙之类都卸载掉,分别去机器上抓包,对比正常和不正常的报文,所有网络问题,报文肯定会有差异,网络不通无非就是数据包在某个环节丢掉了
    bjfane
        34
    bjfane  
       320 天前
    @fuis 高手啊,牛 x
    jack778
        35
    jack778  
    OP
       320 天前
    @liu1297528606 抓包可以,但是要查出原因还是有点麻烦
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4122 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 01:00 · PVG 09:00 · LAX 18:00 · JFK 21:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.