2

Citrix 已确定我们遇到的 TCP 通信问题,原因是客户端和服务器之间的 NetScaler 负载平衡器上的活动TCP 小窗口攻击保护 (TCP-SWAP) 。负载均衡器将间歇性地断开 TCP 连接,Citrix/文章的建议是禁用 TCP-SWAP。由于 NetScaler 用于除我之外的其他系统流量,禁用此设置可能会导致全局事件并使 NetScaler 暴露于潜在的小窗口攻击。

禁用 TCP-SWAP 的替代方法是确保客户端请求不被归类为小窗口攻击。

特定受影响的客户端通过 NetScaler 向服务器发送多部分请求。请求是标头、XML 部分和文件部分,由标准生成的边界分隔。NetScaler 间歇性地将附件大小为 62-66kb 的某些请求标记为小窗口攻击,并阻止服务器接收请求的最后部分。后续相同的请求(包括使用相同的边界)成功;该场景无法按需复制,但可以批量复制。

在请求被视为小窗口攻击的合格场景中,整个客户端请求被传递到负载均衡器,然后客户端等待服务器响应。服务器接收标头、XML 部分和大约 50% 的文件部分,然后等待请求文件部分的其余部分。负载平衡 NetScaler 从不传输文件部分的其余部分。客户端和服务器最终超时等待。

客户端和服务器端的代码审查表明代码没有问题。从通信路径中移除 NetScaler 解决了问题;当不再在客户端和服务器之间时,延长时间跨度没有问题。不幸的是,负载均衡器是必需的。

问题是由于 TCP-SWAP 导致客户端请求被 NetScaler 错误分类为小窗口攻击,这会阻止服务器接收请求的最后部分。除了在 NetScaler 上禁用 TCP-SWAP 之外,客户端可以进行哪些更改以防止请求被归类为小窗口攻击?

客户端是在 Linux (Oracle Linux Server 7.8) 上的 IBM Liberty (WAS Liberty 20.0.0.7) 下运行的 Java 8 (IBM SDK 8.0-6.11-linux-x86_64) 应用程序,它使用正常超时设置进行org.apache.httpcomponents.httpclient通信,PoolingHttpClientConnectionManager安全和连接管理。 是否有适用于 Liberty 或 HttpComponents 的配置设置以防止请求被识别为Small Window Attacks

邮政编码如下;这是非典型的:

public HttpResponse post(URL url, Map<String, Object> parameterMap) throws Exception {
    
    HttpPost httpPost = new HttpPost(url.toString());

    MultipartEntityBuilder builder = MultipartEntityBuilder.create();

    for (Map.Entry<String, Object> entry : parameterMap.entrySet()) {

        if (entry.getValue() instanceof String) {
    
            builder.addTextBody(entry.getKey(), (String)entry.getValue());
                    
        } else {
            
            String partName = getNextPartName();
                
            if (entry.getValue() instanceof File) {

                builder.addBinaryBody(partName, (File)entry.getValue(), ContentType.APPLICATION_OCTET_STREAM, entry.getKey());

                } else 
                if (entry.getValue() instanceof InputStream) {
                    
                    builder.addBinaryBody(partName, (InputStream)entry.getValue(), ContentType.APPLICATION_OCTET_STREAM, entry.getKey());
                    
                } else 
                if (entry.getValue() instanceof byte[]) {
                    
                    builder.addBinaryBody(partName, (byte[])entry.getValue(), ContentType.APPLICATION_OCTET_STREAM, entry.getKey());

                } else {
                    
                    throw new IllegalArgumentException("Cannot attach entry " + entry.getKey() + " with Object of class " + entry.getValue().getClass().getName());
                }
            }
        }
        
        httpPost.setEntity(builder.build());            
    }
    
    return new HttpResponseImpl(getClient().execute(httpPost), httpPost);
}
4

1 回答 1

1

假设您实际上并未受到 TCP 小窗口攻击,那么您的 TCP 窗口大小如此之小这一事实表明最可能的问题是客户端 Linux 内核正在确定它处于压力之下并激活流量控制(即设置一个小窗口)。我建议调查您的客户端网络堆栈是否经过良好调整和不饱和;否则,您可能会尝试不同的拥塞控制算法或其他 cwnd 调整。例如:https ://publib.boulder.ibm.com/httpserv/cookbook/Operating_Systems-Linux.html#Operating_Systems-Linux-Networking-TCP_Congestion_Control

于 2020-09-10T13:36:15.770 回答