Juniper防火墙,LVS DR mode 与 HTTP keepalive 丢包问题追查

最近业务上新上了 Juniper 的防火墙。在防火墙上线后发现,原先业务上的调用同网段内 LVS VIP 的 HTTP 长连接在使用一段时间后频繁出现丢包重传现象,而其它网段连接此 LVS IP 则没有丢包。

概要

Juniper SRX 防火墙默认规则关于 TCP 连接建立的判定方法以及相关配置。

同网段中向DR模式 LVS 发出的TCP包,其回包不通过网关而是直接返回到发起机器。

使用python3 + urllib3 模拟 HTTP keepalive 长时间保持连接情况

症状

应用服务器上向 LVS IP 发的 HTTPS 请求丢包非常之惨烈。

网络拓扑

先上一张网络拓扑,方便说明问题。

LVS IP 是公网IP

Juniper 防火墙设备同时充当默认网关。

复现、调查与分析过程复现

为了能够在不影响业务的情况下方便调查,稳定复现问题是关键。

在复现的方法上想了很多办法,耗费了最多时间。

第一种方法,也是直接想到的方法,尝试用 curl。

但是连接丢包是在长连接建立一段时间后才发生的,所以使用 curl 需要 1) 模拟长连接 2) 长连接需要保持一段时间。

查阅手册,发现使用 curl 保持长连接不难,但是由于内网请求速度非常快,因此要保持长连接一段时间难以做到。

第二种方法,使用 python 的urllib3。

查了下urllib3的手册,写出下面代码。

import urllib3, certifiimport time#http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED', ca_certs=certifi.where())http = urllib3.PoolManager()for i in range(1000):        r = http.request("GET", "http://xxx.xiaomi.com")        print(i, r.status)        time.sleep(1)

运行该代码约20秒后,输出卡住了。重复多次稳定复现。

调查

先在业务机器上和 Real Server 上抓包,发现连接建立一段时间后一定会出现丢包,然后整个连接被关闭。

后尝试在 LVS 机器上和业务机器上抓包分析。

LVS 上抓包图:

业务机器上抓包图:

蓝色的行为同一个包在 LVS 和业务机器上的同一个包。

通过在 LVS 机器和业务机器上抓包,确定是防火墙硬件将包丢弃。

至此,将调查重点放在防火墙配置上。

可疑的防火墙配置

现在问题已经明确为:

因为某个原因或者配置,防火墙将超过20秒的长连接的包丢弃了。

检查防火墙的配置,找找与 “20″ 相关的项目,在其默认配置中有所发现

set security screen ids-option untrust-screen tcp syn-flood alarm-threshold 1024set security screen ids-option untrust-screen tcp syn-flood attack-threshold 200set security screen ids-option untrust-screen tcp syn-flood source-threshold 1024set security screen ids-option untrust-screen tcp syn-flood destination-threshold 2048set security screen ids-option untrust-screen tcp syn-flood timeout 20set security screen ids-option untrust-screen tcp land

其中

set security screen ids-option untrust-screen tcp syn-flood timeout 20

这一条其意义是:TCP 连接的建立必须在20秒内完成,否则该连接请求将被丢弃。链接

至此,已大致可以确定问题所在了:防火墙将超过20秒的连接强行关闭了。

LVS DR模式

在 LVS DR 模式下,请求方向 LVS 发起 TCP 请求,但是 TCP 请求的回包并不从 LVS 返回,而是由 Real Server 直接返回给请求方。

如果请求方与 LVS 不在同网段,则返回的 TCP 包需要通过网关转发给请求方。但是如果请求方与 LVS 是同网段且网关是防火墙设备,那情况要稍微复杂些。

如图:

TCP包流向图

注意到经过防火墙的 TCP 包是单方向的。防火墙一直认为 TCP 连接没有建立。

解决方法

根据之前的分析,想到的解决方法有两个:

    调整防火墙配置和应用程序的配置,让 HTTP 长连接保持一个合适的时间。在该网段搭建内网 LVS,流量不经由防火墙。
Juniper防火墙,LVS DR mode 与 HTTP keepalive 丢包问题追查

相关文章:

你感兴趣的文章:

标签云: