How to add trusted root ca to coreelec

trying to use a self hosted piped instance with kodi addon. Instance is configured with an internal cert.
I just cant get kodi to trust or ignore the cert.

  • tried | verifypeer=false
  • tried create /storage/.config/cacert.pem. tried adding root-ca/server cert only and both
  • tried adding to /etc/ssl/cacert.pem

could someone point me in the right direction pls.
thx

requests.exceptions.SSLError: HTTPSConnectionPool(host=‘pipedapi.bok.local’, port=443): Max retries exceeded with url: /trending?region=US (Caused by SSLError(SSLCertVerificationError(1, ‘[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1006)’)))

–>End of Python script error report<–

First and second option should work (but don’t use space after pipe character).

Look again your log file for more clues. From this one line nothing can be concluded.

thx for reply first off all.

had another look at log, the set url in piped plugin gui is
https://pipedapi.bok.local | verifypeer=false
(without spaces)

in /storage/.config/cacert.pem i have only the root-ca like this
-----BEGIN CERTIFICATE-----
x
x
x
-----END CERTIFICATE-----

in logs however
pipedapi.bok.local%7cverifypeer=false

2024-12-26 16:05:39.853 T:14848   error <general>: EXCEPTION Thrown (PythonToCppException) : -->Python callback/script returned the following error<--
                                                    - NOTE: IGNORING THIS CAN LEAD TO MEMORY LEAKS!
                                                   Error Type: <class 'requests.exceptions.ConnectionError'>
                                                   Error Contents: HTTPSConnectionPool(host='pipedapi.bok.local%7cverifypeer=false', port=443): Max retries exceeded with url: /trending?region=US (Caused by NameResolutionError("<urllib3.connection.HTTPSConnection object at 0xcd92bc28>: Failed to resolve 'pipedapi.bok.local%7cverifypeer=false' ([Errno -2] Name or service not known)"))
                                                   Traceback (most recent call last):
                                                     File "/storage/.kodi/addons/script.module.urllib3/lib/urllib3/connection.py", line 203, in _new_conn
                                                       sock = connection.create_connection(
                                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                                     File "/storage/.kodi/addons/script.module.urllib3/lib/urllib3/util/connection.py", line 60, in create_connection
                                                       for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
                                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                                     File "/usr/lib/python3.11/socket.py", line 962, in getaddrinfo
                                                   socket.gaierror: [Errno -2] Name or service not known
                                                   
                                                   The above exception was the direct cause of the following exception:

when i try with plain url its

2024-12-26 16:14:56.277 T:15306   error <general>: EXCEPTION Thrown (PythonToCppException) : -->Python callback/script returned the following error<--
                                                    - NOTE: IGNORING THIS CAN LEAD TO MEMORY LEAKS!
                                                   Error Type: <class 'requests.exceptions.SSLError'>
                                                   Error Contents: HTTPSConnectionPool(host='pipedapi.bok.local', port=443): Max retries exceeded with url: /trending?region=US (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1006)')))
                                                   Traceback (most recent call last):
                                                     File "/storage/.kodi/addons/script.module.urllib3/lib/urllib3/connectionpool.py", line 467, in _make_request
                                                       self._validate_conn(conn)
                                                     File "/storage/.kodi/addons/script.module.urllib3/lib/urllib3/connectionpool.py", line 1096, in _validate_conn
                                                       conn.connect()
                                                     File "/storage/.kodi/addons/script.module.urllib3/lib/urllib3/connection.py", line 642, in connect
                                                       sock_and_verified = _ssl_wrap_socket_and_match_hostname(
                                                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                                     File "/storage/.kodi/addons/script.module.urllib3/lib/urllib3/connection.py", line 782, in _ssl_wrap_socket_and_match_hostname
                                                       ssl_sock = ssl_wrap_socket(
                                                                  ^^^^^^^^^^^^^^^^
                                                     File "/storage/.kodi/addons/script.module.urllib3/lib/urllib3/util/ssl_.py", line 470, in ssl_wrap_socket
                                                       ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname)
                                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                                     File "/storage/.kodi/addons/script.module.urllib3/lib/urllib3/util/ssl_.py", line 514, in _ssl_wrap_socket_impl
                                                       return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
                                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                                     File "/usr/lib/python3.11/ssl.py", line 517, in wrap_socket
                                                     File "/usr/lib/python3.11/ssl.py", line 1104, in _create
                                                     File "/usr/lib/python3.11/ssl.py", line 1382, in do_handshake
                                                   ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1006)
                                                   
                                                   During handling of the above exception, another exception occurred:
                                                   
                                                   Traceback (most recent call last):
                                                     File "/storage/.kodi/addons/script.module.urllib3/lib/urllib3/connectionpool.py", line 790, in urlopen
                                                       response = self._make_request(
                                                                  ^^^^^^^^^^^^^^^^^^^
                                                     File "/storage/.kodi/addons/script.module.urllib3/lib/urllib3/connectionpool.py", line 491, in _make_request
                                                       raise new_e
                                                   urllib3.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1006)
                                                   
                                                   The above exception was the direct cause of the following exception:
                                                   
                                                   Traceback (most recent call last):
                                                     File "/storage/.kodi/addons/script.module.requests/lib/requests/adapters.py", line 486, in send
                                                       resp = conn.urlopen(
                                                              ^^^^^^^^^^^^^
                                                     File "/storage/.kodi/addons/script.module.urllib3/lib/urllib3/connectionpool.py", line 844, in urlopen
                                                       retries = retries.increment(
                                                                 ^^^^^^^^^^^^^^^^^^
                                                     File "/storage/.kodi/addons/script.module.urllib3/lib/urllib3/util/retry.py", line 515, in increment
                                                       raise MaxRetryError(_pool, url, reason) from reason  # type: ignore[arg-type]
                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                                   urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='pipedapi.bok.local', port=443): Max retries exceeded with url: /trending?region=US (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1006)')))

Does pipedapi.bok.local even resolve?

yes it does. :smiley:

i setup dns overrides and alias in unbound on opnsense router.
also works perfectly fine in browser.

to verify

u22jx:~ # nslookup pipedapi.bok.local
Server:    192.168.6.1
Address 1: 192.168.6.1 bok-dns01.bok.local

Name:      pipedapi.bok.local
Address 1: 192.168.6.146 piped.bok.local

This doesn’t sounds right:

Failed to resolve 'pipedapi.bok.local%7cverifypeer=false' ([Errno -2] Name or service not known)

Looks like verifypeer is part of hostname. Can you show how this pipedapi.bok.local is even used in Kodi?

yeah noticed that too.
config.xml from plugin looks right though

still, i added the internal root ca to /storage/.config/cacert.pem which doesnt work either when i just use url without |verifypeer

  GNU nano 7.2                                                   .kodi/userdata/addon_data/plugin.video.piped/settings.xml                                                              
<settings version="2">
    <setting id="instance">https://pipedapi.bok.local|verifypeer=false</setting>
    <setting id="use_login" default="true">false</setting>
    <setting id="username" default="true" />
    <setting id="password" default="true" />
    <setting id="auth_token" default="true" />
    <setting id="watch_history_enable" default="true">false</setting>
    <setting id="watch_history_playlist" default="true" />
    <setting id="watch_history_hide_watched_feed" default="true">false</setting>
    <setting id="watch_history_hide_watched_channels" default="true">false</setting>
    <setting id="watch_history_hide_watched_playlists" default="true">false</setting>
    <setting id="watch_history_hide_watched_trending" default="true">false</setting>
    <setting id="watch_history_hide_watched_search" default="true">false</setting>
    <setting id="watch_history_refresh" default="true">30</setting>
    <setting id="http_port_random" default="true">true</setting>
    <setting id="http_port">50099</setting>
    <setting id="audio_prefer_original_lang" default="true">true</setting>
    <setting id="audio_prefer_kodi_lang" default="true">true</setting>
    <setting id="audio_custom_lang" default="true">en</setting>
    <setting id="subtitles_load" default="true">true</setting>
    <setting id="video_codec_priority" default="true">_</setting>
</settings>

You obviously can’t use verifypeer in this configuration.

Did you reboot after adding root ca cert in cacert.pem?

yep, million times.
quite lost now tbh

is there a way to verify if the ca cert has been added?

This user file is added to the end of /etc/ssl/cacert.pem.

mh, i think the plugin is not honoring that.
I would say cert is trusted and adding ca worked.
at least coreelec is trusting it, does this include kodi trusting it also?

echo "GET /" | openssl s_client -connect pipedapi.bok.local:443 | openssl x509 -text | openssl verify
Connecting to 192.168.6.146
depth=1 C=XX, ST=by, L=XXX, O=bok, emailAddress=nobody@nowhere CN=internal-ca
verify return:1
depth=0 C=XX, ST=by, L=XXX, O=bok, emailAddress=nobody@nowhere, CN=piped.bok.local
verify return:1
DONE
stdin: OK

plugin fyi
https://kodi.wiki/view/Add-on:Piped

edit

dude… I looked at the plugin dependencies and just added my ca to kodi/addons/script.module.certifi/lib/certifi/cacert.pem and plugin works!!
Finally… private selfhosted youtube front end with kodi plugin that has WORKING login/subscription feature.
I am quite sure though i shouldnt modify that file and it will break sooner than later. Not sure if it even survives a reboot.
Got any suggestions?

Yes, script.module.certifi has it’s own certs but don’t know why.
But I think for using self-signed certs this is the solution. And it will berak after this addon update.

I will have to give this some thought now.
Maybe I can create / fork my own cert plugin or modify/butcher the piped plugin and/or its dependencies somehow. Would be a good reason to finally start learning python.

For now, will this at least survive reboot?

Thx for assistance!

edit:
the plugin itself is amazing.
you can manage subscriptions, playlists, groups anything on your private frontend in browser. kodi plugin picks it up instantly.
the piped containers i send through a wireguard tunnel using mullvad. Only a matter of time until the ips get blacklisted by google, but usually you only need to switch every couple of months.
Quite happy now :smiley:

You could just adjust this file kodi/addons/script.module.certifi/lib/certifi/cacert.pem from autostart.sh or something like that. Maybe symbolic linked to /run/libreelec/cacert.pem which is CE final file.

good idea, i will look into that.
just to clarify, you mean to create /storage/.config/autostart.sh ?

It depends if your addon is using Python built in urllib.request or external module such as requests
urllib.request will look for certs in /storage/.config/cacert.pem
requests will look for certs in kodi/addons/script.module.certifi/lib/certifi/cacert.pem