openhab / openhab-addons

Add-ons for openHAB
https://www.openhab.org/
Eclipse Public License 2.0
1.88k stars 3.59k forks source link

[zoneminder] Allow self-signed SSL/TLS certificate #9909

Open chris922 opened 3 years ago

chris922 commented 3 years ago

In local environments self-signed TLS certificates could be used for ZM. Therefore I think an extra option (maybe flagged as advanced option) could be helpful to allow self-signed TLS certificates.

2021-01-22 10:54:37.361 [DEBUG] [der.internal.handler.ZmBridgeHandler] - Bridge: IOException on GET request, url='https://foo/zm/api/host/getVersion.json': java.util.concurrent.ExecutionException: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Your Environment

mhilbush commented 3 years ago

Hey @cweitkamp. To allow self-signed certificates in my Zoneminder binding, is it as simple as including something like this with my binding. If so, what's the purpose of getHostName and does it matter what I put as the return from that method? Thanks!

https://github.com/openhab/openhab-addons/blob/main/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/AVMFritzTlsTrustManagerProvider.java

mhilbush commented 3 years ago

@chris922 I have a version that includes a ZmTlsTrustManagerProvider. You're more than welcome to try it out while we wait for a more definitive answer. Let me know.

cweitkamp commented 3 years ago

Maybe I am to late, but the getHostName() method should return either the common-name from the certificate to be considered as valid or the peer-host of the ssl-connection.

See https://github.com/openhab/openhab-core/blob/127724c0e31ad8abf0855d87fbf96204267a39be/bundles/org.openhab.core.io.net/src/main/java/org/openhab/core/io/net/http/TlsProvider.java#L30-L39

mhilbush commented 3 years ago

Never too late. Thats exactly what I was looking for. Thanks.

@chris922 I'm not familiar with running Zoneminder using SSL. Is the self-signed cert installed as part of the Zoneminder installation?

mhilbush commented 3 years ago

I see. So the way you get secure access to Zoneminder is to put it behind an Apache web server that's configured for SSL with a self-signed cert installed. Is that the way you're doing it @chris922?

mhilbush commented 3 years ago

If that's the case, the common-name could be anything. The FQDN or IP address of the Zoneminder host is in the Zoneminder bridge config, but how would I get access to that in the ZmTlsTrustManagerProvider. Similarly, I could add the common-name as a bridge config parameter, but there's still the issue of getting access to it from the ZmTlsTrustManagerProvider.

@cweitkamp Am I on the wrong track here? WDYT?

cweitkamp commented 3 years ago

Your TlsTrustManagerProvider will be an OSGi service. In general you could try to implement it as a ThingHandlerService provided by the ZmBridgeHandler. This way you archive the connection you are looking for and you do not need to take care of the framework stuff. Wdyt?

mhilbush commented 3 years ago

Ah yes. So it would work similarly to a discovery service that implements ThingHandlerService, correct?

But, my experience with discovery services that implement ThingHandlerService is that the call to setThingHandler occurs before the bridge thing handler has initialized. Will there be a timing issue if the TlsTrustManagerProvider tries to access the bridge config in getHostName. Or is getHostName only called when the connection to the resource (in this case the Zoneminder server) is attempted?

chris922 commented 3 years ago

I see. So the way you get secure access to Zoneminder is to put it behind an Apache web server that's configured for SSL with a self-signed cert installed. Is that the way you're doing it @chris922?

@mhilbush : Yes, I've got a reverse proxy (NGINX in this case) configured with a self-signed cert proxying requests to my ZM instance. My ZM instance is not available via regular HTTP.

As a workaround I added my own root CA certificate to the truststore of the JVM, this works, but having the additional config as mentioned in my initial post would make it most likely easier (but of course less secure.. but anyway.. everything is running in my local network, not accessible from the outside, so it's okay for me and I guess also for many other people)

If there is a snapshot available I could try it :)

mhilbush commented 3 years ago

Thanks for the info.

If there is a snapshot available I could try it :)

Not yet. But I'll probably have something to try tomorrow.

mhilbush commented 3 years ago

@chris922 I have a version if you would like to try it. It includes a new bridge config parameter where you can put the self-signed certificate's common name. To test, you may need to back out the root CA you added to the JVM trust store.

The new version is here. It would be best to run the binding in DEBUG mode so we can see what's going on.

cweitkamp commented 3 years ago

@mhilbush The implementation is similar to an approach for discovery service.

I have to admit that I cannot tell you much about the timing right now. I have to investigate the order of calls in OHC framework.