当外部服务器尝试通过端口 443(TCP)连接到我们的网站时,我们遇到了一些奇怪的问题,这是一个 Apache2+Passenger 和一个 Rails 应用程序。这个问题很少发生。我开始通过启用 iptables 日志记录来调查这个问题iptables -I INPUT -m state --state NEW,INVALID -j LOG --log-prefix "iptables [INPUT]: "
(对 FORWARD(通常不使用)和 OUTPUT 也这样做了)。
现在,每个新连接都记录到 syslog 中。现在,我在 syslog 上看到了正常的连接,之后又看到了与 Vhost 的连接(正常工作请求),但有时(在大约 100 个连接中的 1 个中)我只在 iptables 日志中看到新连接,但该连接似乎无法到达 apache2(或乘客实例)(没有 apache 日志条目,也没有连接结果)。当使用 curl 执行此操作时,我们会收到超时或空字符串。我们只是发送了一个启用调试的 curl 请求代码片段,以增强对 curl 错误的记录。
我们正在使用 Debian Squeeze(稳定版),该版本在 VMWare ESXi 环境中运行,该环境使用桥接以太网和 E1000 NIC(虚拟化)。但由于数据包到达 VM-OS 本身,我认为其中任何原因都不会导致问题。
我还检查了 ip_conntrack,它有大约 40 到 50 个连接,而 Squeezes Limit 大约为 65k,所以这不是问题所在。此外,我们在 NIC 本身上没有任何丢弃的软件包。
内核版本:Linux 服务器名称 2.6.32-5-amd64 #1 SMP 星期日 9 月 23 日 10:07:46 UTC 2012 x86_64 GNU/Linux Apache2:服务器版本:Apache/2.2.16 (Debian) - 服务器建立时间:2012 年 11 月 30 日 08:58:38 乘客:Phusion Passenger 版本 3.0.12 红宝石:RVM 1.17.9 + Ruby 1.9.3-p362
iptables -L
链输入(策略接受)目标协议选择源目标
LOG全部--任何地方任何地方状态无效,新日志级别警告前缀'iptables [INPUT]:'链 FORWARD(策略接受)目标 prot opt 源目标
LOG 全部 -- 任何地方任何地方状态 INVALID,NEW LOG 级别警告前缀`iptables [FORWARD]:'链输出(策略接受)目标协议选择源目标
LOG全部--任何地方任何地方状态无效,新LOG级别警告前缀iptables [OUTPUT]: '
答案1
我对此没有真正的“答案”,但也许你可以找到一种方法来进一步追踪它。问题似乎发生在内核空间中,就在 iptables 链接之后,或者在用户空间中,当 apache 接受连接时或之前。
由于数据包捕获会产生负载,内核可以在 nic 和 iptables 之后自行丢弃数据包。您是否曾经构建过没有 iptables 和可在 apache 日志中计数的已定义访问次数的测试环境?
如果您有一些 C 经验,您应该尝试一下 libpcap,这是一个很棒的库,可以做坏事也可以做好事。这里有一篇关于此内容的很好的入门文章:http://recursos.aldabaknocking.com/libpcapHakin9LuisMartinGarcia.pdf
这可能会向您显示通过的数据包和将要丢弃的数据包之间的差异。