什么样的客户端Linux/Liberty/HttpComponents配置可以防止请求被错误识别为小窗口攻击



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);
}

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

最新更新