我需要一种方法来跟踪和限制 Web 应用程序的 Web 会话。“会话”大致定义为浏览所述 Web 应用程序页面的单个用户。我认为可以将其翻译为:
- 会话被定义为一个元组,或者
<clientIP,vHost>
,取决于层和可用的数据<clientIP,serverIP,serverPort>
<cookie,vHost>
- 用户将身份验证数据发送到定义的登录 URI 后,会话开始
- 用户点击定义的注销 URI 后,会话结束
- 如果客户端请求最后一个对象后指定的超时时间已到,则会话结束
达到指定的会话限制后,下一个用户应被定向到自定义错误页面。我还需要一种方法来跟踪当前的会话数以进行监控,以及将监控服务器(定期向 Web 应用发出查询)列入白名单并免除限制的能力。
我可以做什么:
- RadWare AppDirector其中 Web 应用程序定义了自己的场并以反向代理模式运行
- Apache 2.2
- SLES 11 SP2
我宁愿不涉及额外的代理服务器,但如果没有其他选择,也会考虑它。
所有这些背后的原因是,上述 Web 应用程序很容易超载,并开始不规律地拒绝请求,这激怒了工作用户,他们(通常)在此过程中丢失了表单输入数据。通过指定不太可能出现超载情况的限制,我们希望创建一个定义明确的故障条件,如果负载可能激增,用户将被告知稍后返回。
编辑:该 Web 应用程序采用 3 层实现,第一层(表示层,在 Apache vHost 中以 CGI 代码实现)相当简单,显然仅限于基本错误处理和应用程序服务器之间的请求负载平衡。它不会给运行它的 Web 服务器带来任何重大负载 - 这就是为什么我们在 AppDirector 场中以单纯的故障转移模式(无负载平衡)运行它,这应该会在某种程度上简化事情。
超出这一点的一切对我们来说基本上都是黑匣子——在数据层,我们有一个 MSSQL 数据库,但几乎不可能从供应商那里获得有关表结构的任何有意义的信息。应用服务器是闭源的,供应商使用了相当全面的框架进行实施,但似乎无法回答甚至不太复杂的操作相关问题。
答案1
你最终试图解决的问题是应用程序的容量——这就是你应该解决问题的地方。你提到的组件都没有与会话管理有关对于 HTTP 应用程序。
您可以使用 iptables 中的最新模块或以与其设计目的相反的方式使用 fail2ban 来应用一些技巧 - 但这两者都需要对工具和问题领域有非常详细的了解。您可以在这些组件级别实现访问控制,但驱动通过应用程序发布的有关会话数的状态信息。
我还需要一种方法来跟踪当前会话数以进行监控
暂时假设应用程序是一个黑盒子,没有范围对于修改/检测(这是极不可能的),您可以通过包含会话 cookie 从 apache 日志中获取此信息 - 过滤或尾随日志以维护活动 cookie 列表 - 并且当它们与注销 URL 一致或在 TTL 中未见过时从列表中删除条目。
答案2
这不完全是您想要的,但我已经使用 F5 负载均衡器完成了以下操作:
- 统计登录页面的post请求数量。
- 如果每秒登录次数超过第一个限制,则延迟用户
- 如果每秒登录次数超过限制,则将用户发送到维护页面
由于网站有时负载很重(赛马),所以它有所帮助。
答案3
该问题可以通过使用 RadWare AppDirector 来解决,并且(为了完整性)也可以通过使用 Apache mod_security 来解决,正如您在下面的评论中发现的那样。
对于 AppDirector 解决方案,我相信可以创建两个映射到同一后端服务器的服务器场。这些服务器场可以应用不同的标准和操作条件。一个服务器场将是“默认”服务器场,另一个服务器场将响应您定义为“会话”的 URI:s。后者将限制其在负载平衡器中接受的会话数量。
从现在开始我将用“会话”一词代替“登录”,原因有二:
- 它避免了歧义,因为它明确定义了用户经过身份验证的期望状态。
- AppDirector 用户指南和 GUI 重新定义了术语“连接”,使其在所有实际用途上的含义与“会话”相同,见下文。这会增加混淆,我们试图避免这种情况。
如果“登录”服务器场已达到所选的连接限制,还可能会显示抱歉页面。
在开始操作之前,我必须明确说明,我没有使用过 AppDirector 产品,但确实每天管理一款竞争产品,而且稍微落后一些的负载平衡器。我使用的产品可以立即完成此场景。我通过 AppDirector 用户指南和可用的在线文档找到了信息,这些信息表明 AppDirector 也是如此。然而,虽然概念相似,但术语不同。我只是在措辞方面故作谦虚,希望能够正确理解,但又不会太明显地显得自己是个无知的白痴。
最大的障碍是获取手册,除非是活跃客户,否则无法获得手册。通过谷歌搜索,我找到了一个旧版本,我希望它不是太过时,我还找到了几篇知识库文章和以下链接:Radware AppDirector – 配置:基本应用程序。
以下是解决方案草案,主要通过用户指南进行解释:
客户端通过 VIP 进入负载均衡器,该 VIP 用于连接“默认”会话和“已登录会话”。这是通过 L4 策略实现的,如用户指南第 99 页所述:
"When AppDirector receives the first packet of a session destined to a
Virtual IP address, it searches for a Layer 4 Policy that matches the
Layer 4 Protocol, Destination port, Source IP, etc. Then, based on this
information, AppDirector selects the farm allocated to this service and
the best server for the task from that farm, and forwards the packet to
that server.
L4 策略可以与用于选择合适农场的 L7 策略相关联。L7 策略流程在用户指南第 104 页中描述如下:
"The Layer 7 content aware decision making mechanism allows you to have
a single point of entry to the site, and provides differentiated service
for different user groups.
A Layer 7 decision is made using a mechanism called Delayed Binding.
When Delayed Binding is used, AppDirector first performs a TCP handshake
with the client to receive the HTTP request. AppDirector parses the HTTP
request’s data, usually HTTP headers, and performs the load balancing
decision. Only after that, does AppDirector select a farm and a server.
Lastly, AppDirector initiates a TCP handshake with the server and
forwards the traffic to it
[...]
When Layer 7 Policies are used, farm selection is based on matching the
request data with a list of Layer 7 Policies defining the Layer 7
parameters differentiating the service. The process of server selection
within the farm can also be content-based, using a third Layer 7
parameter."
定义 L7 行为的可用方法在第 106 页进行了描述,您可以选择合适的方法来选择路由到“已登录”的农场而不是“默认”农场:
"Methods are the basic building blocks for Layer 7 service selection.
They define content by which traffic is differentiated. You can use
the same Method to select one or more services. The following Method
Types are available:
- URL: Looks for a specified host name and/or path in the HTTP request.
- File Type: Looks for a specified File Type in the HTTP request.
- Header Field: Looks for a specified Header Field in the HTTP request.
- Cookie: Looks for a specified Cookie in the HTTP request.
- Regular Expression: Looks for a regular expression anywhere in the
HTTP request. AppDirector supports Posix 1002.3 regular expressions;
the string can be up to 80 characters.
- Text: Looks for a text string anywhere in the HTTP request."
正如所见基本应用链接,例如,可以创建一个 L7 策略来评估路由到不同农场的 URI 模式。虚构的 URI 模式 '^/login?=true' 和 '^/loggedin' 可以路由到您的“已登录”农场。虚构的模式 '^/logout'(以及所有其他 URI)可以类似地路由到“默认”农场。
用户指南第 121 页对农场的定义如下:“AppDirector 场是一组提供相同服务的联网服务器[...] 提供多种服务的服务器可在多个场中使用。”
通过将后端服务器的定义分为两层来进一步区分服务器,“物理服务器”对象层表示服务器的 IP 地址,“场服务器”对象层表示在一个或多个物理服务器上运行的服务。
根据《AppDirector 用户指南》,除了物理服务器对象外,农场的会话限制还可以针对农场定义的每个农场服务器对象(以及通过其他方式)进行。第 137 页中的其他地方对此进行了描述:
"The Connection Limit is the maximum number of users that can be directed
to a server for a service provided by the farm. The number of users allowed
depends on the Sessions mode selected because it determines the number of
active entries in the Client Table for sessions destined to the specific server.
When the Entry Per Session or Server Per Session modes are selected, the number
of active entries destined to the same server is higher than in the Regular
mode (see Regular, page 153).
When the Regular mode is selected, all requests from a single client IP destined
to the same server are reflected by a single entry in the Client Table (see
Client Table Views, page 164).
The default value for the Connection Limit parameter is 0. When it is configured
to 0, it is disabled for this server and there is no user number limit."
客户端表及其“常规模式”在第 153 页定义:
"The Layer 3 Client Table is always used when Entry Per Session is used.
AppDirector uses the Layer 3 Client Table to ensure Layer 3 persistency.
This table contains information about the server selected for each client
(Source IP address) in each farm, and it allows AppDirector to select a
server for a new session.
[...]
In the Regular mode, AppDirector maintains Layer 3 persistency. In this mode,
each entry is identified by the following parameters:
• Layer 4 Policy VIP Address
• Client IP Address
• Destination TCP/UDP Port Used from the Client to the Server"
在服务器定义窗口的屏幕截图中基本应用页面中,服务器连接限制框位于带宽限制框的旁边。
因此,这有点取决于配置,但就此答案而言,通过客户端表定义的“连接”和您定义的“会话”本质上是同一件事。并且可以对场中的每个服务器对象施加限制。
由于 AppDirector 区分物理服务器和场服务器,因此可以定义两个场服务器映射到 Apache 物理服务器对象,其中一个具有较低的连接限制。
但是,Apache 还需要响应来自两个场服务器对象的调用,例如通过两个单独的端口或 IP 地址进行调用 - 每个 (场/场服务器) 组合使用一个。那么问题就变成了,您能否定义两个应用服务器入口点?即,您是否能够装备您的 Apache 前端应用程序 (/vhost?) 以在两个端口或 IP 地址(每个场一个)上进行响应?这需要一些猜测,因为我不想花太多时间在手册上,但我相信当您实际查看 AppDirector GUI 和 Apache 时,您可以相当优雅地解决这个问题。
设置连接限制有点奇怪。摘自《物理服务器,连接限制》第 140 页:
"Connection Limit
Maximum number of Client Table entries that can run simultaneously on
the physical server. This depends on the farm’s Sessions mode (see
Sessions Modes, page 150). When the limit is reached, new requests are
no longer directed to this server. All open sessions are continued.
When the Connection Limit parameter is configured to 0 (default), this
mechanism is disabled for this physical server and there is no user
number limit.
Note: When configuring the physical server, ensure that the Connection
Limit in the farm servers with the same Server Name is lower than or
equal to the Connection Limit in the physical server. Total number of
active sessions that run simultaneously on the farm servers must not
be higher than the Connection Limit value defined on the physical server."
因此,您需要为不受限制的“默认”场服务器定义一个非常高的连接限制(与用户群可能的最大数量相差很大),并将“登录”场服务器的连接限制设置为尽可能低。物理服务器定义需要将两者的总和作为其连接限制,这是激活所需会话限制的先决条件。
您的问题中也有这个要求:
After the specified session limit has been reached, the next user should be
directed to a custom error page.
在用户指南第 134 页中,这被称为“无 HTTP 服务页面”:
When all servers belonging to a farm cannot be used for a specific
session, AppDirector can reply to a Web request (destined to port 80)
with a simple Web page, indicating that the service is currently not
available. Servers that cannot be used for a session include servers
in Not In Service or in No New Sessions mode. No HTTP Service Page is
configured for each farm. Each Web page is limited to 1K of HTML code.
对于监控部分,我还没有做过彻底的研究,但我的想法如下:
track the current number of sessions for monitoring purposes
AppDirector 似乎有 MIB。通常情况下,找到正确的 OID 可能比较麻烦,但您可以将其 snmp 到您选择的工具中。
whitelist the monitoring server (which is issuing queries to the webapp
periodically) and exempt it from the limit.
这可能需要一些创造性思维。假设 AppDirector 没有包含现成的模板,那么如何:
- “已登录”服务器场之外的 URI 不会受到会话限制的影响。因此请继续监视,反正它们都是相同的后端服务器。
- 改用 AppDirector 健康检查,它们可能不会计入您施加的会话限制。不过,找到一种方法将警报传递到您的监控服务器 :-)
- 设置第三个农场,通过它进行健康检查。虽然很麻烦,但还是有用的。
答案4
如果 AppDirector 无法帮助您,这里有另一种方法,但需要一点编码。我将按如下方式解决问题:
- 在循环中,继续读取 apache 日志文件(并在 logrotate 上重新打开它)
- 当用户访问任何页面(不仅仅是登录)时,将其添加到 iptables 白名单中
- 当用户注销或处于不活动状态时(因此请保留活动会话的计时器!),将其从白名单中删除
- 如果白名单已满,则将所有非白名单流量重定向到特殊端口
- 在该端口上运行一个简单的 vhost,并附带自定义错误
绘制会话数图表变得和绘制 iptables 链的长度图表一样简单。监控服务器可以简单地始终列入白名单。