当 send_mail 落后于 Apache2.4 时,Django 1.10 SSLv2_method 导入错误

Django 1.10 SSLv2_method import error when send_mail behind an Apache2.4

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

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

Django 1.10 在 Ubuntu 16.04 和 python2.7 的 conda 虚拟环境中运行。 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),而之前使用 stock mod_wsgi.so 它实际上指向 anaconda python。我确实在 apache2 mod_wsgi.conf 中用新建的 mod_wsgi.so

将 WSGIPythonHome 指定为 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

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

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

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

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

一个是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