No progress yet sadly.
Let me know if you find something, I’ll update this thread too if I get to a solution!
No progress yet sadly.
Let me know if you find something, I’ll update this thread too if I get to a solution!
Okay, I made some progress. This post got me over the hump, though I don’t understand how to make the change permanent:
The short version is that Home Assistant uses a Python package called Certifi to manage trusted certificate authorities. The trust store is stored separately from the Linux platform trust store. This explains why updating the Linux trust store has no effect. The private CA can be either appended to the Certifi trust store (it’s text only), or you can run the script in the above post. Then restart the HASS services. The problem is that the file is not persistent across boots.
The Certifi trust store is located here: /usr/local/lib/python3.7/site-packages/certifi/cacert.pem
I am no expert on HASS or containers, so I don’t follow how to make this script run on boot so that the change is effectively permanent. That’s the last piece of the puzzle. Right now, I have to log in to the container and run the script manually. Maybe you can advise?
Finally, there needs to be some mechanism for updating or adding to the trust store on Home Assistant without all the above gymnastics. I’ll be digging in to how to make a suggestion for a feature enhancement on this topic.
Ken.
Great lead!
Back then I never searched for the acronyms, didn’t find some relevant topics in another case because of that too…
You’re running hass.io, right?
I’m running HASS on a VM on VMWare ESXi where I simply imported the VMDK file. I don’t think that’s hass.io, but again, I’m a bit of a newb here…
Damn, it didn’t post my reply from about half a week ago, but at least it saved a lot of what I had written:
A short, hopefully helpful rundown of the naming because I was quite confusedtoo when I started a few months ago (take all with a grain of salt though, the understanding is built from the context of many topics I read here):
Hass is just short for HomeAssistant; hass.io is the old term for running hass in Docker, today you’d just call it HomeAssistant or HomeAssistant Supervised if you want to emphasize the dockerization; HassOS is a kind of minimal Linux distro with everything necessary to run Hass by itself.
When you mentioned containers before I thought you were running Hass supervised, but if I got you correctly you’re running HassOS like me.
I used the script from the topic you linked and appended my CA to certifi’s store, but I still can’t connect to the CCU while using the verify_ssl option. A reboot resets the store like you said; calling homematic.reconnect after appending didn’t help either. The verify_ssl option works for you after appending to certifi’s store?
To run the script automatically I would normally use systemd, but I think Alpine uses OpenRC. However, /etc/local.d doesn’t exist and I also can’t run rc-update - so right now I’m not sure how HassOS handles initialization.
A cron service isn’t active either, so I’m running out of options a bit.
I think I found a way to add self-signed certs. Here’s the code I used, the trick was to append a .PEM version of the cert to the certifi CA.
# prep certs, this cannot be done in the Dockerfile because
# we also need to copy them to a mounted volume
cp /usr/local/share/ca-certificates/cert.crt /config/ssl/cert.crt
cp /usr/local/share/ca-certificates/cert.key /config/ssl/cert.key
update-ca-certificates
# create base64 PEM file from cert
openssl x509 -in /config/ssl/cert.crt -out /config/ssl/cert.pem
# add the pem to the certifi Python package certificate authority file
# the Python requests library does not use the system default CA, but uses the CA from the certifi package
# adding the PEM lets HA not spam warnings about insecure connections in the logs
cat /usr/local/lib/python3.8/site-packages/certifi/cacert.pem /config/ssl/cert.pem > /usr/local/lib/python3.8/site-packages/certifi/cacert-updated.pem
mv /usr/local/lib/python3.8/site-packages/certifi/cacert-updated.pem /usr/local/lib/python3.8/site-packages/certifi/cacert.pem
Thank you for the suggestion, but krich11 and I are both on HassOS, not Supervised.
For us, the certifi certificate store resets on every reboot and so far I haven’t found out how HassOS handles initialization so that I could run a script on every boot (You can find what I’ve tried in that matter in my last comment before this one).
We also were already appending in pem format to our certifi store, whereby krich11 seems to have got it running, with the problem that a reboot resets the store, and I have properly appended my certificate but wasn’t able to connect to HomeMatic with the verify_ssl option nonetheless.
I verified the success of my appendix with the following script,
import certifi
import requests
try:
print('Checking connection to RaspberryMatic...')
requests.get('URL_TO_CCU')
print('SSL is fine.')
except requests.exceptions.SSLError as err:
print('SSL Error.')
which printed SSL error before my appendix and SSL is fine afterwards as expected.
Was there any further progress being made? I am facing the same issue and created my own Root CA which of course hass.io does not accept. Because of that I can no longer connect to my QNAP NAS, QVR Pro and the Unifi components for presence detection. All use the certificates created with that Root CA which I would need to add to HA.
Does anyone know if a feature request or something exists to maybe create an “official” way to add it permanently to HA?
Thanks!
Sadly not, I’m still facing the same issue.
I’m not aware of a feature request and hadn’t thought of one before because I expected some mildly-hacky way to accomplish this, even though certifi states that adding certificates is not supported.
I’m not sure how likely it will be for the request to go through, since it seems to me that the certificate store would need to be changed and that very few people are using their own CAs like us, but I can create a request over the next few days!
I think in this case the official way is the best way to do it. I personally created certificates covering the internal domains within my LAN and the externally reachable ones. So while the external part is no biggie with given plugins like Let’s Encrypt, etc. the challenge is always the internal domains. Since I did not want to use things strictly over the internet when I’m at home, I did not want to go all external.
So perhaps with a feature request we can at least get more information on how it can be done manually if there won’t be any “officially” implemented solution.
Maybe you can post the link to the request here as well for upvoting.
Just posted the feature request!
Let me know if I should edit something in that would be better to have on top than in a separate comment!
Ok, I think I’ve got a workaround for homeassistant OS, but this is more like a workaround than a perm solution given you will lose this every time you install a core upgrade.
Adding certs follows the same process you get automated by update-ca-certificates many linux distros:
The process of adding this can be automated rather easily, however my homeassisntant based cert-injector automation needs to wait
Hope that helps,
mb
Wow, that looks promising, thanks a lot! I’ll definitely give it a try as soon as I find the time!
Presumably it’s even more helpful to kurisutian, since he can’t simply turn off verify_ssl like I can as it seems
And luckily, a MITM attack via my RaspberryMatic in my home network is rather unlikely - at least I hope that it is…
Cool!
For the automation piece what I have in mind is:
Should only the last one fail, we need to inject the certs with a shell_command.
And this ideally fixes sensors as well upon the next check. Exceptions would be integrations that kick when initialized and put on an error path when they fail. Worst case: needs a restart.
Yeah, needs some time but nothing significant I imagine.
Hi!, i need help on how to copy the CA file into step 4 ? I’m completely loss on where I’m when seeing the homeassistant /bin/bash. I also can not paste/edit via terminal text editor like nano or vim in there. I’m sorry for my silly question. Thanks anyway.
Edit:
Problem solved, how to resolve:
Done
Manual updates for this are tedious if you try to stay up-to-date with HA Core. I have a thread with a feature request here.
Discuss and more importantly, vote!
I’ve got some nastyhack proto code here that automates this process.
With the included binary sensor used, it constantly checks for losing trust, and re-injects as appropriate; this basically “smooths” you through core updates.
The important bit is that you’ll need to run this inside Core (homeassistant docker container).
While I’m sure there must be easier ways around this, I’ve chosen to live with this until a proper solution emerges.
Let me know if this works for you.
mb
Here my workaround:
Copy your ca files in your favorite directory. For me it is ~/config/my_ssl. Here I can upload my files through the file editor addon.
Connect to the HA core via SSH Addon, copy the files via “docker cp” and update the system ca files via “docker exec”
for f in $(ls ~/config/my_ssl); do docker cp ~/config/my_ssl/$f homeassistant:/usr/local/share/ca-certificates/; done
docker exec -it homeassistant sh -c "update-ca-certificates"
Yes, you have to do this after every core container update .
my_ssl contains the ca certificates:
➜ ~ ll ~/config/my_ssl
total 24K
-rw-r--r-- 1 root root 3.5K Feb 5 14:04 Client.CA.crt
-rw-r--r-- 1 root root 3.5K Feb 5 14:04 DMZ.CA.crt
-rw-r--r-- 1 root root 3.5K Feb 5 14:04 Hausautomation.CA.crt
-rw-r--r-- 1 root root 3.5K Feb 5 14:04 Intra.CA.crt
-rw-r--r-- 1 root root 3.5K Feb 5 14:04 Mgmt.CA.crt
-rw-r--r-- 1 root root 3.5K Feb 5 14:03 Root.CA.crt
This this I can use the checkbox “Check TLS connection” in the homematic integration.
Here is a “solution” that allow you to survive home assistant upgrade, and to avoid any ssh as long as you already have hacs installed.
I made this today to test if this would solve issue with the fullykiosk integration using https.
It didn’t …
https://hacs-pyscript.readthedocs.io/en/latest/installation.html
In config/integrations, click on the configure button on the pyscript integration and check Allow All Imports
Using what ever method you use to add or change file on your home assistant instance, add the following script in your config folder under pyscript/add_custom_ca.py
# ==================================================================================================
# python_scripts/add_custom_ca.py
# ==================================================================================================
# --------------------------------------------------------------------------------------------------
# Add the .pem from the provided path to certifi catalogue
# --------------------------------------------------------------------------------------------------
# from https://community.home-assistant.io/t/let-home-assistant-trust-a-personal-certificate-authority/184917/22?u=vaarlion
import certifi
from os import path as os_path
@service
def add_custom_ca(pem_path):
"""yaml
name: Add Custom ca
description: Add the .pem from the provided path to certifi catalogue.
fields:
pem_path:
name: Pem file(s) path
description: a path or a list of path to .pem file
exemple: ["/ssl/custome_ca.pem", "/config/www/ssl/extra_ca.pem"]
selector:
text:
"""
inputPath = pem_path
listPath = []
if inputPath is None:
log.warning("===== pem_path is required if you want to add something.")
else:
if (
isinstance(inputPath, str)
and inputPath
and task.executor(os_path.isfile, inputPath)
):
listPath.append(inputPath)
elif isinstance(inputPath, list) and inputPath:
for path in inputPath:
if isinstance(path, str) and task.executor(os_path.isfile, path):
listPath.append(path)
else:
log.info(
"===== ignoring '{}' as it's not a path to an existing file".format(
path
)
)
else:
log.warning(
"===== pem_path is required to be a path or a list of path to existing files"
)
cafile = certifi.where()
for pem in listPath:
__append_fileA_to_fileB(pem, cafile)
@pyscript_executor
def __append_fileA_to_fileB(fileA, fileB):
with open(fileA, "rb") as infile:
customca = infile.read()
with open(fileB, "r") as outfile:
cachain = outfile.read()
if customca.decode("utf-8") not in cachain:
with open(fileB, "ab") as outfile:
outfile.write(customca)
Then call the service pyscript.reload
.pem
fileUsing the same way you’ve uploaded the script, upload your CA certificate in a .pem
format where ever you want. I recommend /ssl/
. You can add as many as you want.
Try to run the service and make sure there is no error in the log.
in developer-tools/service
, run something like
service: pyscript.add_custom_ca
data:
pem_path: /ssl/mycert.pem
or
service: pyscript.add_custom_ca
data:
pem_path:
- /ssl/mycert.pem
- /config/some_other_cert.pem
With your own file obviously.
Now check to see if this solve your issue. It may not as not every automation use that certificate catalogue, and other have some hard-coded port or protocol.
If it does, then we need to have it survive an upgrade.
Now juste make an automation who run that services as soon as home assistant start
alias: "Add custom cert on boot"
description: ""
trigger:
- platform: homeassistant
event: start
condition: []
action:
- service: pyscript.add_custom_ca
data:
pem_path: /ssl/MainCA.pem
mode: single
No worry, the python script make sure the cert isn’t already present before adding it, so you won’t append it 500 time before the next release.
I don’t know if there is another way to do it, but this one works flawlessly. Thank you!!
My only concern is whether the automation will run before or after it tries to load the integration that needs to verify the certificate.
I will have to wait for the next update to check. In any case, the failure would only occur on the first boot after updating.