场景描述:

    鉴于适配器与银行通信采用TCP全双工短连接方式,会出现多数连接正常,但是极个别的银行出现TCP连接第二次握手失败的现象;
    如下图:(甘肃光大银行)异常错误—第二次握手失败
    image.png
    正常连接:
    image.png


    原因分析:

    出现这种情况是基于现场在做安全测评的过程中对于linux服务器的系统参数进行了修改(linux内核在处理TCP协议的核心参数理解不明确自行修改),系统配置文件为/etc/sysctl.conf;
    如下图:
    image.png
    上图参数解析:
    l net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
    l net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
    l net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
    l net.ipv4.tcp_fin_timeout 修改系統默认的 TIMEOUT 时间


    错误原因深入分析:

    接收到连接请求的参数后,客户端(光大)处于SYNSENT 状态,等待服务器(适配器)返回响应,服务器接收到SYN请求,开始进行后续处理,此时会涉及到linux服务器的内核net模块下的IPV4协议相关参数的处理重点查询上图修改后的系统参数状态_,其中在进行IPsec安全处理过程中确认TCP连接哈希链表、路由表以及sockets连接队列等数据结构不满足的情况下会执行分支处理,如下:case TCP_TW_RST:
    goto no_tcp_socket;
    no_tcp_socket:
    if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
    goto discard_it;
    discard_it:
    / Discard frame. / 丢帧
    kfree_skb(skb);释放sk缓存区
    return 0;
    从而直接将存储客户端的连接句柄的内存缓存释放掉,造成连接丢失!


    解决方法:

    将如下参数回复为默认设置即可解决第二次握手失败的问题;
    vim /etc/sysctl.conf**
    添加如下代码:
    net.ipv4.tcp_tw_recycle = **0
    执行命令:sysctl -p