Apache / mod_ssl可以支持双层操作吗?

时间:2016-04-05 22:35:39

标签: python django apache centos mod-ssl

我有一个Web服务器,它将大部分内容保存在本地数据库中,但需要查询后端目录服务以检索用户信息。目录查询可以作为独立操作正常工作,但是当Web服务器进行查询时,ssl会返回错误。

服务器基于CentOS 7-2.1511 / Django 1.9.3 / PostgreSQL 9.2.15 / Apache 2.4.6-40 / mod_ssl 1:2.4.6-40 / OpenSSL 1:1.0.1 / Python 3.4.3。 Apache使用mod_ssl来提供来自客户端(浏览器)的https:请求,我假设Python的ssl.py使用相同的引擎向目录服务器发出https:请求。 Python SSL表示它的实施基于OpenSSL。 Yum显然无法列出mod_ssl的依赖项,但我认为它还使用了已安装的openssl版本。

以下代码将使用用户的专有名称(从SSL_CLIENT_CERT中提取)并使用RESTful接口查询目录服务器以获取用户的属性:

import requests, urllib

URL = 'https://example.com/rest/user_info/'

def get_user_info(dn)
    query = URL + urllib.parse.quote(dn)
    return requests.get(query, cert=('server.crt', 'server.key'),
                        verify='ca_bundle.crt').json()

当我在服务器的WSGI目录中作为用户apache在服务器上运行时,例程正确返回包含用户属性的dict:

$ python
>>> import auth
>>> dn='cn=Me,o=Company,c=US'
>>> attr = auth.get_user_info(dn)

但是当Apache从它的WSGI脚本(views.py)调用具有相同DN的相同函数时,它会引发一个OSError:

OSError(0, 'Error')
Line 810, /lib64/python3.4/ssl.py

803  def do_handshake(self, block=False):
804      """Perform a TLS/SSL handshake."""
805      self._check_connected()
806      timeout = self.gettimeout()
807      try:
808          if timeout == 0.0 and block:
809              self.settimeout(None)
810          self._sslobj.do_handshake()   

我将按照OpenSSL的建议开始研究锁定(因为我无法想到会导致这些错误的任何其他因素),但很难相信使用SSL的网络服务器后端查询已经不是一个很好的旅行路径。问题:

  1. 多线程/锁定/重入是否因为这些错误而在正确的树上咆哮?
  2. 是否已经有将SSL用于网络服务器后端连接的示例?

1 个答案:

答案 0 :(得分:0)

我放弃了。以下工作可靠,牺牲了美观和效率。它首先尝试requests查询,如果爆炸,它会在子流程中调用并调用wget。它返回一个元项$method,让页面视图知道内联请求是否失败。

def get_user_info(dn, sub=True, ttl=300):
    query = URL + urllib.parse.quote(dn)
    try:
        info = requests.get(query, cert=(SERVER_CERT, SERVER_KEY),
                            verify=CA_CERT).json()
        info['$method'] = 'requests'
        return info
    except OSError:
        if sub:
            args = ['wget', '-O', '-',
                '--certificate=' + SERVER_CERT,
                '--private-key=' + SERVER_KEY,
                query]
            bytes = subprocess.check_output(args, timeout=5)
            info = json.loads(bytes.decode(encoding='utf-8'))
            info['$method'] = 'subprocess'
            return info
        else:
            raise

如果OpenSSL使用上下文而不是全局变量,那肯定会很好。