【问题标题】:FreeTDS with Django causing Denial of Service on SQL ServerFreeTDS 与 Django 导致 SQL Server 上的拒绝服务
【发布时间】:2017-09-21 17:30:54
【问题描述】:

这是来自应用程序未知部分的相当奇怪的行为。

我的设置:

  • 姜戈
  • 免费TDS
  • Unixodbc
  • django-pyodbc-azure
  • MS SQL

应用程序将在看似随机的一段时间内运行(通常为 2-3 分钟),然后停止响应,SQL Server 也将停止响应。其他应用程序即使使用其他帐户也无法对数据库进行任何请求。

我这边的显式请求数是1在django应用的ready()中获取一些初始数据。

def ready(self):
    from django.conf import settings
    from app.models import SomeModel
    try:
        settings.SomeModel_ID = SomeModel.objects.filter(identifier=settings.SomeIdentifier)[0].pk
    except:
        settings.SomeModel_ID = SomeModel.objects.create(identifier=settings.SomeIdentifier).pk

SQL Server Tracer 会记录一些请求,但没有异常(相当多的 BatchStarted/BatchFinished)。

Wireshark 看到在应用程序和数据库之间移动的数据包数量惊人(我们正在谈论 +250 的简单 SELECT)。这里我以一些 TCP 为例,但 +95% 的数据包是 TDS。

5422 36.248815392  10.10.10.66 -> 10.10.10.103 TDS 183 TLS exchange
5423 36.249013989 10.10.10.103 -> 10.10.10.66  TDS 135 TLS exchange
5424 36.249427950  10.10.10.66 -> 10.10.10.103 TDS 135 TLS exchange
5425 36.250678349 10.10.10.103 -> 10.10.10.66  TCP 1514 [TCP segment of a reassembled PDU]
5426 36.250703683 10.10.10.103 -> 10.10.10.66  TDS 607 TLS exchange
5427 36.250856893  10.10.10.66 -> 10.10.10.103 TCP 66 1433 → 39348 [ACK] 
Seq=2816 Ack=5937 Win=131584 Len=0 TSval=148074754 TSecr=605610420
5428 36.253444263  10.10.10.66 -> 10.10.10.103 TDS 4215 TLS exchange
5429 36.253462203 10.10.10.103 -> 10.10.10.66  TCP 66 39348 → 1433 [ACK] 
Seq=5937 Ack=6965 Win=45440 Len=0 TSval=605610421 TSecr=148074754
5430 36.255551301  10.10.10.66 -> 10.10.10.103 TDS 4215 TLS exchange
5431 36.255572551 10.10.10.103 -> 10.10.10.66  TCP 66 39348 → 1433 [ACK] 

我知道应用程序是 DoS 的原因,因为关闭它会立即恢复每个人对数据库的访问权限。

列出活动连接时使用:

SELECT DB_NAME(dbid) AS DBName,
COUNT(dbid) AS NumberOfConnections, loginame
FROM sys.sysprocesses
GROUP BY dbid, loginame
ORDER BY DB_NAME(dbid)

只列出一个连接。

没有任何类型的循环可以对此提供简单的解释。

【问题讨论】:

  • 一些想法:您是否在 SSMS 中调出 SQL Server 活动监视器来实时查看查询,同时调出应用程序以查看它实际在做什么?您是否尝试过在 SQL Server 运行时在其上使用sp_who2 以查看是否有任何阻塞进程?这将有助于对问题进行三角测量。此外,开发实例中的 Django 调试工具栏可以显示每页生成的查询 - 强烈推荐。

标签: python sql-server django freetds


【解决方案1】:

我们发现问题是在使用Pool时出现的,不管我们在函数内部是否使用db连接,创建多个子进程都会导致问题。要解决它,只需在 fork 进程之前connection.close()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-02
    • 1970-01-01
    • 2016-11-13
    • 2011-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多