在 Django 视图中签名 XML 会为新建的 docker 镜像呈现 Nginx 502 错误网关,但不会为旧镜像呈现

问题描述 投票:0回答:1

我的 Django 应用程序的所有视图都按预期工作,与签名 XML 相关的视图除外。 在新的 Ubuntu docker 映像上运行时,这些视图(特别是我的 SAML 元数据视图)会返回 502 Bad Gateway 错误。

Nginx 错误日志显示:

2024/01/15 16:04:04 [error] 14#14: *219 upstream prematurely closed connection while reading response header from upstream, client: 172.17.0.1, server: [my application].azurewebsites.net, request: "GET /sso/metadata/ HTTP/1.1", upstream: "
http://unix:/code/[my application socket file].sock:/sso/metadata/"
, host: "localhost:801"

上游套接字位置是指运行我的 django 应用程序的gunicorn服务器,这里的错误日志显示:

[2024-01-15 16:04:04 +0000] [10] [WARNING] Worker with pid 25 was terminated due to signal 11

除了信号 7 或 8 之外,其他日志显示相同。

我在 2024 年 1 月之前构建的所有映像(最后一个是 12 月 19 日)使用相同的包,相关视图未更改,但这些(旧的)不会呈现 502 Bad Gateway 错误。

我正在使用

Ubuntu 22.04
Python 3.9.18
nginx version: nginx/1.22.1
gunicorn (version 20.1.0)
Django==3.0.14

所有相关文件在工作和非工作 docker 映像上都保持不变,并且两个映像都运行相同版本的 ubuntu (22.04)、python、nginx 和 Gunicorn。

当我在 Visual Studio 构建的 python 环境中本地运行代码时,相关视图没有问题。但是,当我在 Docker for Windows 中本地构建映像时,问题仍然存在,如果我在 Docker for Windows 上本地运行 12 月 19 日的映像(或任何更早的映像),问题就会再次消失。 这意味着我无法构建不出现此问题的新 docker 映像。

Python 视图返回 502 Bad Gateway 而不是签名元数据

from onelogin.saml2.auth import OneLogin_Saml2_Auth

def meta(request):
    req = {
            'https': 'on' if request.is_secure() else 'off',
            'http_host': request.META['HTTP_HOST'],
            'script_name': request.META['PATH_INFO'],
            'server_port': request.META['SERVER_PORT'],
            'get_data': request.GET.copy(),
            'post_data': request.POST.copy(),
            'query_string': request.META['QUERY_STRING']
        }
    auth = OneLogin_Saml2_Auth(req, custom_base_path=settings.SAML_FOLDER)

    saml_settings = auth.get_settings()
    metadata = saml_settings.get_sp_metadata()
    errors = saml_settings.validate_metadata(metadata)

    if len(errors) == 0:
        return HttpResponse(content=metadata, content_type='text/xml')
    else:
        return HttpResponseServerError(content=', '.join(errors))

这里

settings.SAML_FOLDER
是我的SAML配置文件夹的路径。

解决问题所采取的步骤 我尝试深入研究有问题的视图,沿着视图插入中断,以便准确地弄清楚在创建错误的网关响应之前我可以在 python 代码中走多远。

这样做时,我发现在包含步骤

metadata = saml_settings.get_sp_metadata()
以及从 python3-saml 包导入的此方法中出现问题
onelogin.saml2.auth.OneLogin_Saml2_Auth -> get_settings -> get_sp_metadata
我发现问题出现在来自“https:”的 settings.py 文件的第 740 行: //github.com/SAML-Toolkits/python3-saml/blob/master/src/onelogin/saml2/settings.py':

metadata = self.metadata_class.sign_metadata(metadata, key_metadata, cert_metadata, signature_algorithm, digest_algorithm)

解压它,它只包含

OneLogin_Saml2_Utils.add_sign()
方法,最后解压它,当包含来自“https://github.com/SAML-Toolkits/python3-saml/blob/”的 utils.py 文件的第 738 行时,我遇到了问题master/src/onelogin/saml2/utils.py':

signature = xmlsec.template.create(elem, xmlsec.Transform.EXCL_C14N, sign_algorithm_transform, ns='ds')

在此行之后停止并不总是会呈现网关错误,但如果我在此行之后停止视图,大约 80% 的请求将呈现错误网关错误。 从现在开始,我在视图中包含的行越多,百分比就越高,当我包含从“https://github.com/SAML-Toolkits/python3-saml/blob/master/”到第 777 行的所有行时src/onelogin/saml2/utils.py' 我只在大约 100 个调用中完成了一次,并且包含更多行总是会出现错误的网关错误。

此视图会占用我的 CPU,这可能是问题的根源,但我不知道为什么它只会占用新图像的 CPU。

我进一步尝试使用最新版本的

gunicorn==21.2.0
,但没有效果,即同一行代码出现相同的问题。 我在工作和非工作图像上使用最新版本的
xmlsec
python3-saml
,分别为版本 1.3.13 和 1.16.0。 我尝试在 Ubuntu 20.04 而不是 22.04 上构建映像,同样没有效果,在同一行代码中遇到了相同的问题。

docker lxml gunicorn ubuntu-22.04 xmlsec
1个回答
0
投票

python

lxml
软件包已安装了某些软件包依赖项的最新版本,如果此软件包版本
>=5.0.0
会导致我的gunicorn服务器在使用
xmlsec
生成签名时崩溃,从而导致nginx呈现
502 Bad Gateway
错误.

当基于 Windows 时,使用最新的 lxml 包不会使我的虚拟 python 环境崩溃,但仅当在 Ubuntu 上运行时才会崩溃。

这意味着在我的

lxml==4.9.4
文件底部添加
requirements.txt
解决了问题。

© www.soinside.com 2019 - 2024. All rights reserved.