Why do I get a “SSL error: called a function you s

2019-07-28 23:47发布

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

3条回答
混吃等死
2楼-- · 2019-07-29 00:09

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.

查看更多
3楼-- · 2019-07-29 00:30

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.

查看更多
The star\"
4楼-- · 2019-07-29 00:34

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].

查看更多
登录 后发表回答