Reputation: 43096
I have a Python 3.5
/Django 1.10
app served by Apache
/mod_wsgi
over SSL. It is connected to a Postgres 9.5.2
database (with psycopg2==2.6.2
) and is running on a server at AlwaysData
It works fine most of time but I have sometimes an error that I don't understand.
(SSL error: called a function you should not call)
If I put the following database settings : The error seems to happen every time
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'db',
'USER': 'user',
'PASSWORD': 'password',
'HOST': 'host',
'PORT': '',
'OPTIONS': {
'sslmode': 'require',
},
}
}
It seems to occur while querying the database.
# django/db/backends/utils.py line 64
return self.cursor.execute(sql, params)
The problem occurs when REST api (made using django-rest-framework) is called by a Angular2 app.
I have activated the following settings:
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
Why does it happen? How to fix this problem in my Django project.
Note : This question looks similar but I don't manage the OpenSSL layer directly so it is not very helpful.
EDIT : here is the full traceback
File "proj/env/lib/python3.5/site-packages/django/core/handlers/exception.py" in inner
39. response = get_response(request)
File "proj/env/lib/python3.5/site-packages/django/core/handlers/base.py" in _legacy_get_response
249. response = self._get_response(request)
File "proj/env/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
187. response = self.process_exception_by_middleware(e, request)
File "proj/env/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "proj/env/lib/python3.5/site-packages/django/views/decorators/csrf.py" in wrapped_view
58. return view_func(*args, **kwargs)
File "proj/env/lib/python3.5/site-packages/django/views/generic/base.py" in view
68. return self.dispatch(request, *args, **kwargs)
File "proj/env/lib/python3.5/site-packages/rest_framework/views.py" in dispatch
474. response = self.handle_exception(exc)
File "proj/env/lib/python3.5/site-packages/rest_framework/views.py" in handle_exception
434. self.raise_uncaught_exception(exc)
File "proj/env/lib/python3.5/site-packages/rest_framework/views.py" in dispatch
471. response = handler(request, *args, **kwargs)
File "proj/apps/costs/apis.py" in get
296. data = self.get_spends_stats(cost_items, perimeter, start_date, end_date)
File "proj/apps/costs/apis.py" in get_spends_stats
306. for building in buildings:
File "proj/env/lib/python3.5/site-packages/django/db/models/query.py" in __iter__
256. self._fetch_all()
File "proj/env/lib/python3.5/site-packages/django/db/models/query.py" in _fetch_all
1087. self._result_cache = list(self.iterator())
File "proj/env/lib/python3.5/site-packages/django/db/models/query.py" in __iter__
54. results = compiler.execute_sql()
File "proj/env/lib/python3.5/site-packages/django/db/models/sql/compiler.py" in execute_sql
835. cursor.execute(sql, params)
File "proj/env/lib/python3.5/site-packages/django/db/backends/utils.py" in execute
64. return self.cursor.execute(sql, params)
File "proj/env/lib/python3.5/site-packages/django/db/utils.py" in __exit__
94. six.reraise(dj_exc_type, dj_exc_value, traceback)
File "proj/env/lib/python3.5/site-packages/django/utils/six.py" in reraise
685. raise value.with_traceback(tb)
File "proj/env/lib/python3.5/site-packages/django/db/backends/utils.py" in execute
64. return self.cursor.execute(sql, params)
Exception Type: OperationalError at /costs/api/benchmark/cost-center/3/38/2016-01/2017-12/
Exception Value: SSL error: called a function you should not call
Upvotes: 1
Views: 1632
Reputation: 15548
There was a related bug #58956 in Apache + OpenSSL in SSL_shutdown handshake, ending with exactly the same error message, that has been fixed by OpenSSL in February 2016. Try to upgrade to 1.0.2g or 1.1.0 or newer.
EDIT: If you have some 1.0.2 version (maybe more versions, but your package of interest is linked to 1.0.2) then the upgrade of SSL is worth considering. The version 1.1.0 is here written only for completeness to anybody can easily check a version later, whether is related to this bug. Nobody have now a 1.1 probably on a production hosting and a self-made upgrade to it would be probably a bad idea.
Upvotes: 1
Reputation: 43096
The problem seems to be solved by changing the database settings
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'name',
'USER': 'user',
'PASSWORD': 'password',
'HOST': 'host',
'PORT': '',
'OPTIONS': {
'sslmode': 'disable',
},
}
}
If not set the option is using prefer
as default (see https://www.postgresql.org/docs/9.5/static/libpq-ssl.html) which seems to have unpredicted behavior.
I guess that the root cause is an OpenSSL mismatch between Apache and Postgres. It has to be investigated.
The current fix makes the database connection not secured but this is another story.
Upvotes: 0
Reputation: 35986
Looks like a psycopg2
bug (or rather, as piro pointed out, the underlying libpq
's bug). It appears to be violating the required call order - likely not waiting for some event. Since this occurs irregularly, it can be a race condition.
It even provides incomplete information about the error which is another bug. It should use ERR_print_errors()
to get the full message which has the format [pid]:error:[error code]:[library name]:[function name]:[reason string]:[file name]:[line]:[optional text message]
.
Upvotes: 1