Enable use of self-signed certificates with urllib3

Problem: for those of us wishing to manage our own self-signed CA there is no way to both use TLS and check the certificate. TLS can be used in this context but certificate verification must be disabled. Note, I am not discussing the actual HA server here but other servers with which HA integrations communicate (i.e. ZoneMinder).

Proposed solution: somewhere in the UI (Configuration, General?) allow cert.pem text to be pasted into a box (or a list of certs that will be appended, etc, whatever is easiest to implement). The text in this box will be appended to the certifi cert list (i.e., /usr/local/lib/python3.8/site-packages/certifi/cacert.pem). This could be hidden behind the Advanced user flag, with suitable warnings regarding trusting the source of the data.

Optional: update system certificates as well – I’m not sure if anything official would require this but then scripts using curl, for example, could also benefit.

Existing possible workaround:

  • enable SSH access to the host on port 22222 (debugging), login, and access the container bash per these instructions
  • cd /usr/local/lib/python3.8/site-packages/certifi
  • edit cacert.pem and append necessary text
  • at this point it is likely certificate validation will succeed with urllib3

The major downside to this workaround is that I don’t believe it will survive an HA Core update. Thus, when the system restarts after an update authentication won’t work, these steps must be repeated, and then HA restarted again. This wouldn’t be burdensome (and may not be, some day) but with the existing rolling development model and fast and furious updates, this can happen multiple times a month. Thus the request for a simple means to handle this automatically.

Thanks in advance for consideration!

As a work-around, I have created an add-on that updates the HA certificate stores with specified self-signed certificates.

It is not generic at this point, the certificates are included as part of the add-on but it should be possible to use a block of text from the configuration tab instead of a file included in the add-on. Note that the docker and bash commands can just be run from within the homeassistant container to achieve this without the add-on. But here is the add-on script:

if ( docker exec homeassistant ls /usr/local/share/ca-certificates | grep self-signed-certs.pem ); then
	echo "Home Assistant already has certificates added, skipping"
else
	echo "Adding self-signed certificates to Home Assistant"
	docker cp homeassistant:/usr/local/lib/python3.8/site-packages/certifi/cacert.pem /var/certs
	cat /app/self-signed-certs.crt >> /var/certs
	docker cp /var/certs homeassistant:/usr/local/lib/python3.8/site-packages/certifi/cacert.pem
	echo "Self-signed certificates added to Home Assistant certifi"

	docker cp /app/self-signed-certs.crt homeassistant:/usr/local/share/ca-certificates/self-signed-certs.pem
	docker exec homeassistant update-ca-certificates
	echo "Self-signed certificates added to Home Assistant ca-certificates"
	
	echo "NOTE: manually restart Home Assistant!"
fi

[ -f /var/certs ] && {
	echo "Cleaning up"
	rm -f /var/certs
}

echo "Done"

The certificates are added to both certifi and the ca-certificates bundles so both python and curl are satisfied. I’ve tested both curl https: connections and zoneminder with verify_ssl: true.

It would be nice if something like this is incorporated into HA, because the use model for the above is:

  1. Update home assistant. Zoneminder won’t work (because I have verify_ssl: true in my config)
  2. Run the add-on (or manually update certificates)
  3. Restart home assistant

Updating the certificate store prior to starting HA for the first time after an update would save the extra restart. If this issue sticks around I’ll likely update the add-on to automatically detect python version (so “python3.8” isn’t hard-coded in the add-on.

2 Likes

Thank you for the script. I tried to build an AddOn based on your script, but I’m struggeling on how to run the script in the homeassistant container. If I use your script in the run.sh of my add_on there is no docker-command available as you mentioned above.

I guess I’m missing something and I was wondering if you could point me to the right direction on how to execute the script.

Thank you very much in advance,
Stephan

I gave a minimal description just showing what the script portion of my custom add-on does. If you want to create an add-on you need the structure described here: Home Assistant add-ons configuration

I don’t necessarily encourage this, I was demonstrating that a solution to the problem exists and the feature could be added as a built-in to HA as requested or through the addition of a supported add-on.

In the end, you don’t need an add-on. You need access to the host OS (see debugging link in first post). Copy the cert file(s) to a temp location (i.e. /var) using for example scp. From there you can execute the commands shown in the script above – you just need to find the path to your custom cert file from the host OS.

The whole point of the feature request is to prevent the need to do this after every core/supervisor update.

1 Like

Thank you very much for your response.

Unfortunately I’ not familiar with Home Assistant developement and thus I’m not able to support implementing the feature. So my idea was to create an add-on that could be used to automate the process. Especially as I have to repeat the steps with every update, so effectively every month.

I already set up debug access and an add-onable to run the docker commands. But using ssh from the add-on conatiner to execute the script on HassOS could do the trick. As an alternative I could try to use an automation to update the cert stores.

But nevertheless, I totally agree that it would be much more conveniant if this could be configured directly in core.

Thank you very much for your support,
Stephan