【问题标题】:Django 1.10 SSLv2_method import error when send_mail behind an Apache2.4当 send_mail 在 Apache2.4 后面时,Django 1.10 SSLv2_method 导入错误
【发布时间】:2017-07-22 19:53:41
【问题描述】:

我正在尝试在 Apache2 mod_wsgi 后面安装一个几乎为空的 django 1.10 项目。在项目设置中,我使用 EMAIL_USE_TLS = True, EMAIL_PORT='587' 从 Web 表单通过 gmail 发送电子邮件。当我在控制台上独立运行 manage.py runserver 时,我可以很好地发送电子邮件。但是当 django 项目位于 Apache2 后面时,我总是遇到这个错误:

/home/wr200m/anaconda2/lib/python2.7/lib-dynload/_ssl.so: undefined symbol: SSLv2_method

Django 1.10 在 conda 虚拟环境中运行在带有 python2.7 的 Ubuntu 16.04 上。 Apache2 可以很好地服务于一些 https 站点。我了解 SSLv2 在很大程度上已被现代系统弃用,并且在我的系统的 openssl 上被禁用。 mod_ssl.conf 具有默认配置(启用除 SSLv3 之外的所有禁用)。为什么这个 SSLv2_method 无论如何都会成为依赖项?

关于我当前解决方法的注意事项:由于我有一个本地后缀可以中继到此服务器上的 gmail,因此在设置中,我只是更改了 EMAIL_HOST = 'localhost' 没有 SSL 或 TLS 和 sans-authentication 但最终结果是相同的: mod_wsgi 后面的 django 显示相同的错误。我最终编写了一个粗略的 _sendmail 帮助程序,它使用 smtplib 让表单邮件查看器通过 postfix 发送,并且有效。当然,我想恢复到标准的 django send_mail。因此,请以任何方式提供建议。

以下是来自 Django 的回溯:

Environment:


Request Method: POST
Request URL: https://wr2opt/contact/

Django Version: 1.10.5
Python Version: 2.7.12
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'home',
 'contact',
 'django.contrib.sites',
 'allauth',
 'allauth.account',
 'allauth.socialaccount',
 'crispy_forms']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "/home/wr200m/anaconda2/lib/python2.7/site-packages/django/core/handlers/exception.py" in inner
  39.             response = get_response(request)

File "/home/wr200m/anaconda2/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "/home/wr200m/anaconda2/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/home/wr200m/workspace/wr200m/optionswww/src/contact/views.py" in contact
  20.         send_mail(subject, message, emailFrom, emailTo, fail_silently=False)

File "/home/wr200m/anaconda2/lib/python2.7/site-packages/django/core/mail/__init__.py" in send_mail
  56.         fail_silently=fail_silently,

File "/home/wr200m/anaconda2/lib/python2.7/site-packages/django/core/mail/__init__.py" in get_connection
  36.     klass = import_string(backend or settings.EMAIL_BACKEND)

File "/home/wr200m/anaconda2/lib/python2.7/site-packages/django/utils/module_loading.py" in import_string
  20.     module = import_module(module_path)

File "/home/wr200m/anaconda2/lib/python2.7/importlib/__init__.py" in import_module
  37.     __import__(name)

File "/home/wr200m/anaconda2/lib/python2.7/site-packages/django/core/mail/backends/smtp.py" in <module>
  3. import ssl

File "/home/wr200m/anaconda2/lib/python2.7/ssl.py" in <module>
  97. import _ssl             # if we can't import it, let the error propagate

Exception Type: ImportError at /contact/
Exception Value: /home/wr200m/anaconda2/lib/python2.7/lib-dynload/_ssl.so: undefined symbol: SSLv2_method

这是 Django 异常 - 请注意,这是在我从源代码构建 mod_wsgi.so 并安装到 apache2 之后,并指定了 LD_RUN_PATH 和 anaconda python。您可以看到 sys.executable 指向 /usr/bin/python(它也运行相同的版本 2.7.12),而之前使用股票 mod_wsgi.so 它实际上指向 anaconda python。我确实在 apache2 mod_wsgi.conf 中将 WSGIPythonHome 指定为使用新建的 mod_wsgi.so 的 anaconda python

ImportError at /contact/
/home/wr200m/anaconda2/lib/python2.7/lib-dynload/_ssl.so: undefined symbol: SSLv2_method
Request Method: POST
Request URL:    https://wr2opt/contact/
Django Version: 1.10.5
Exception Type: ImportError
Exception Value:    
/home/wr200m/anaconda2/lib/python2.7/lib-dynload/_ssl.so: undefined symbol: SSLv2_method
Exception Location: /home/wr200m/anaconda2/lib/python2.7/ssl.py in <module>, line 97
Python Executable:  /usr/bin/python
Python Version: 2.7.12
Python Path:    
['/home/wr200m/workspace/wr200m/optionswww/src',
 '/home/wr200m/anaconda2/lib/python27.zip',
 '/home/wr200m/anaconda2/lib/python2.7',
 '/home/wr200m/anaconda2/lib/python2.7/plat-linux2',
 '/home/wr200m/anaconda2/lib/python2.7/lib-tk',
 '/home/wr200m/anaconda2/lib/python2.7/lib-old',
 '/home/wr200m/anaconda2/lib/python2.7/lib-dynload',
 '/home/wr200m/anaconda2/lib/python2.7/site-packages',
 '/home/wr200m/anaconda2/lib/python2.7/site-packages/Sphinx-1.4.6-py2.7.egg',
 '/home/wr200m/anaconda2/lib/python2.7/site-packages/setuptools-27.2.0-py2.7.egg']
Server time:    Fri, 3 Mar 2017 14:22:18 +0000

这是 anaconda 中所有包含 *ssl.so 形式的 lib 子目录,我还将它们添加到项目 wsgi.py 中的 os.environ['LD_LIBRARY_PATH'] 中,然后再添加(带有 ~ 扩展)

~/anaconda2/envs/pgadmin4/lib
~/anaconda2/envs/pgadmin4/lib/python2.7/lib-dynload
~/anaconda2/envs/pgadmin4/lib/python2.7/site-packages/cryptography/hazmat/bindings
~/anaconda2/lib
~/anaconda2/lib/python2.7/lib-dynload
~/anaconda2/lib/python2.7/site-packages/cryptography/hazmat/bindings
~/anaconda2/pkgs/cryptography-1.5-py27_0/lib/python2.7/site-packages/cryptography/hazmat/bindings
~/anaconda2/pkgs/openssl-1.0.2k-0/lib
~/anaconda2/pkgs/openssl-1.0.2k-0/lib/engines
~/anaconda2/pkgs/python-2.7.13-0/lib/python2.7/lib-dynload

【问题讨论】:

  • mod_wsgi 是为 Anaconda Python 编译的吗?如果 mod_wsgi 是为不同的 Python 发行版编译的,你不能只是尝试强制 mod_wsgi 使用由 Anaconda 构建的 Python 虚拟环境。也就是说,这可能归结为 Anaconda 在某些情况下有点依赖于 LD_LIBRARY_PATH 的设置。
  • 谢谢。我按照您在stackoverflow.com/questions/40151469/… 的回答,使用anaconda2 的python 以及您在anaconda.org/pypi/mod_wsgi 的其他指令在anaconda2 中使用pip install 从源代码构建。我能够毫无问题地使用 mod_wsgi-express start-server(已发送电子邮件)。但是在我安装了从源代码或使用 pip 构建的 mod_wsgi.so 之后,在弹回 apache2 后问题就更加奇怪了。
  • ldd 显示新建的 mod_wsgi.so 有我的 anaconda2/lib/libpython2.7.so.1.0 但 django 上的 python 可执行文件现在显示 /usr/bin/python 而不是以前的 anaconda2/bin /python,而原来的问题仍然存在。股票 mod_wsgi.so 链接到来自发行版的 libpython2.7.so.1.0。你建议我用 LD_LIBRARY_PATH 做什么?我不太关注stackoverflow.com/questions/37690980/…
  • “django 上的 python 可执行文件”是什么意思?如果您正在运行的 Django 应用程序中查看 sys.executeble 的值,那么它是什么并不重要,因为 mod_wsgi 没有通过加载库来执行 python 可执行文件,所以这很重要。
  • 在 Anaconda 发行版中找到 lib 目录,其中包含 Anaconda 版本的 SSL 库。它是什么?尝试在 WSGI 脚本文件的最开始,然后导入 os 并将 os.environ['LD_LIBRARY_PATH'] 设置到该目录。

标签: django apache ssl mod-wsgi tls1.2


【解决方案1】:

我在使用 Apache2 托管 conda 环境时也遇到了这个问题。我的 Apache2 是用 apt-get 安装的。我的系统中实际上安装了两个 openssl。

  1. /usr/lib/x86_64-linux-gnu/libssl.so
  2. /home/vamei/anaconda3/lib/libssl.so

一个属于system,一个属于conda。如果您使用 Apache 来托管站点,Apache 将使用系统的 openssl,这不是 conda 所期望的。我在 /etc/apache2/envvars 中添加了以下行来解决问题:

export LD_LIBRARY_PATH=/home/vamei/anaconda3/lib

注意:我也尝试了各种帖子中建议的其他方法,但都失败了:

  1. 在 Python 中使用 os.environ 添加 LD_LIBRARY_PATH 或 LD_RUN_PATH
  2. 使用 mod_env 添加系统环境 LD_LIBRARY_PATH 或 LD_RUN_PATH

【讨论】:

  • 这意味着 Apache 会使用错误的,所以 mod_ssl 很可能会崩溃。
  • 就我而言,Apache 工作正常。我同意在 Apache 的整个范围内导入变量不是一个好主意,但我没有找到其他解决方案。也许有人可以建议一种仅在 WSGI 中导入的方法。
  • 你不能,因为 mod_wsgi 使用的是从 Apache 继承的进程,它不是一个单独程序的 exec,你有机会引入不同的共享库。唯一安全的解决方案是使用 mod_wsgi-express 以 Apache 或 nginx 作为代理。
  • 谢谢!我决定现在就这样做,而 mod_ssl 仍在工作。因此,总而言之,我将我的 anaconda python 构建的 mod_wsgi 与 apache2 一起安装,并将 apache2 的 LD_LIBRARY_PATH 指向在相同的 anaconda env 中使用 openssl,而不是系统版本。这现在有效!旁注:仍然看到here 报告的问题,解决方案是 2013 年 ubuntu 问题的解决方法!
【解决方案2】:

这不是一个真正的解决方案,但我希望如果其他人遇到类似的问题,我可以演示一个解决方法。

从我的问题下的讨论中可以看出,我的问题似乎与 Apache2 加载较旧的 ssl 库有关,在 anaconda-python 兼容 mod_wsgi 可以拉入正确的 .so 之前。由于这个 Apache2 还通过 https 为其他站点提供服务,而且我没有专业知识也没有时间进一步修补真正的解决方案,因此我选择了以下方法:

【讨论】:

    猜你喜欢
    • 2012-03-14
    • 1970-01-01
    • 2017-07-30
    • 1970-01-01
    • 1970-01-01
    • 2011-02-09
    • 2016-04-01
    • 1970-01-01
    • 2018-03-18
    相关资源
    最近更新 更多