[plugin.api.websocket][error] [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)
Yesterday17 opened this issue · 10 comments
The same problem as niess/python-appimage#24 ?
This is not an AppImage packaging issue. Streamlink issues do not belong here. Also no debug log at all, which is useless.
This is not a streamlink issue. In fact it only breaks in appimage release. Please see the issue linked above.
What do you expect anyone to do here if you don't even post anything useful at all, like the exact appimage you were using and the exact command you were running which led to the problem?
The error message you've posted is coming from Streamlink's websocket module, and the issue is a TLS/SSL certificate issue. Streamlink's AppImages bundle a Python install which is built from the official Python manylinux2014 docker images, and all the latest dependencies are bundled as well, including certifi for the necessary root certificates.
The issue you've linked is unrelated.
The exception itself is self-explaining. Python (somehow) failed to get local issuer certificate. It's a CA issue, which does not exists in host environment at all.
Appimage prepared all the dependencies, but the local ca list could not be retrived. Why the issue is unrelated?
It seems the issue is actually unrelated, but the behavior is strange. I'll investigate it later to find out what has happened. Sorry for disturbing.
Streamlink doesn't set any custom paths for the cert
param of any session initialization or specific request made by requests
, which means it defaults to the value which certifi.where()
returns. certify.where()
returns its locally bundled cacert.pem
file. This should work even in cases of AppImages, where the squashfs gets mounted to a temporary location before execution, because certify
uses relative file paths.
requests
however allows you to override this file via the REQUESTS_CA_BUNDLE
or CURL_CA_BUNDLE
env vars.
I tried to add $SSL_CERT_FILE
manually with:
export SSL_CERT_FILE='path-to-cacert.pem'
And everything works now. I believe the issue is related. Shouldn't it be included in appimage like https://github.com/pypa/manylinux/blob/121d0775b4c738b668ede697ed7c07442519603b/docker/build_scripts/build.sh#L138-L146 do?
Let me have a look. I was talking about requests
, but websocket-client
apparently doesn't use the bundled CA file.
So there are two options to avoid having Streamlink use two different CA cert files:
- Set OpenSSL's
SSL_CERT_FILE
env var with a value pointing towards thecacert.pem
file bundled bycertifi
in the AppImage'sAppRun
and only make changes to the AppImage. Optionally also only set it if it's unset on the user's system, so custom values can still be set. - Update Streamlink's
WebsocketClient
and set theca_cert
parameter on the SSL options dict, with a default value of thecacert.pam
file bundled bycertifi
, similar to all HTTP requests made byrequests
.
streamlink/streamlink@9892d3d
Since Streamlink shouldn't be using two different implementations regardless whether an AppImage is used or not, the second solution sounds like a better idea.