问题描述
Citrix已确定由于客户端和服务器之间NetScaler负载平衡器上的TCP Small Window Attack Protection (TCP-SWAP)处于活动状态而导致的TCP通信问题。负载平衡器将间歇性地断开TCP连接,Citrix /本文的建议是禁用TCP-SWAP。由于NetScaler用于除我的系统之外的其他系统通信,因此禁用此设置可能会导致全局事件,并使NetScaler遭受潜在的小窗口攻击。
禁用TCP-SWAP的另一种方法是确保客户端请求未归类为“小窗口攻击”。
受影响的特定客户端通过NetScaler向服务器发送多部分请求。请求是标头,XML部分和文件部分,由标准生成的边界分隔。 NetScaler间歇性地将具有62-66kb大小的附件的某些请求标记为“小窗口攻击”,并阻止服务器接收请求的最后部分。随后的相同请求(包括使用相同边界)将成功;该方案不可能按需复制,但可以批量复制。
在将请求视为“小窗口攻击”的合格情况下,整个客户端请求将传递到负载平衡器,然后客户端请求服务器响应。服务器接收标头,XML部分和文件部分的〜50%,然后请求请求文件部分的其余部分。负载平衡NetScaler从不传输文件的其余部分。客户端和服务器最终超时等待。
在客户端和服务器端的代码审查均未发现代码问题。从通信路径中删除NetScaler可以解决此问题;在客户端和服务器之间不再存在延长时间的问题。不幸的是,需要负载均衡器。
问题是由于TCP-SWAP,NetScaler将客户端请求错误地分类为“小窗口攻击”,这阻止了服务器接收请求的最后部分。除了在NetScaler上禁用TCP-SWAP之外,客户端可以进行哪些更改以防止将请求分类为“小窗口攻击”?
客户端是一个Java 8(IBM SDK 8.0-6.11-linux-x86_64)应用程序,在Linux(Oracle Linux Server 7.8)的IBM Liberty(WAS Liberty 20.0.0.7)下运行,它使用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(),entry.getKey());
} else
if (entry.getValue() instanceof byte[]) {
builder.addBinaryBody(partName,(byte[])entry.getValue(),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-Networking-TCP_Congestion_Control