I have a web server that maintains most of its content in a local database, but needs to query a back-end directory service to retrieve user information. The directory query works fine as a stand-alone operation, but when the web server makes the query, ssl returns an error.
The server is based on 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 uses mod_ssl to serve https: requests from the client (browser), and I'm assuming Python's ssl.py uses the same engine to make https: requests to the directory server. Python SSL says that it's implementation is based on OpenSSL. Yum apparently can't list mod_ssl's dependencies, but I assume it also uses the installed version of openssl.
The following code will take the user's distinguished name (extracted from SSL_CLIENT_CERT) and query the directory server for the user's attributes using a RESTful interface:
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()
When I am running on the server as user apache in the server's WSGI directory the routine correctly returns a dict containing user attributes:
$ python
>>> import auth
>>> dn='cn=Me,o=Company,c=US'
>>> attr = auth.get_user_info(dn)
But when Apache calls the same function with the same DN from it's WSGI script (views.py
), it raises an 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()
I will start researching locking as suggested for OpenSSL (since I can't think of anything else that would be causing these errors) but it's hard to believe that a webserver using SSL for backend queries isn't already a well-traveled path. Questions:
- Is multi-threading / locking / reentrancy barking up the right tree for the cause of these errors?
- Are there already worked examples for using SSL for webserver-backend connections?