OpenHAB

This page is a collection of information around the OpenHAB installation here at ElectricBrain. During the installation process OpenHAB moved from version 2.5.9 to version 3.0.0 just before christmas 2020.  Then updated to OH31M5 (June 2021) with a minor issue. Updated to version 4.0.3 (October 2023)

The latest version now running in the new house (actually it's quite old house circa 1890's in Bendigo) is version 4.0.3. Previously two versions were installed at the Melbourne house and ran in parallel for about a month. However, with the deployment of the new lights, switch and GPOs OH2.5.9 wasn't updated with the new "things" and so was finally decommisioned Feb 2021 leaving only OH3.0.0 running. OH31M5 then running with OH30 decomissioned.

Information Privacy in your home automation system

Before proceeding, a word of explanation as to why Dockerization and Portainer? This question came up on one of the support lists regarding the "overly" complex dockerized implementation (now in 2023 docker is mainstream and no longer considered "overly" complex as it was back then):


Thanks Rich,

Agreed, this is an unusual configuration.

By way of explanation, and at the risk of becoming overly philosophical, the paranoia essentially stems from the discovery that one of the WiFi access points here was (necessarily) sniffing the mac addresses of all devices on the LAN/Wifi. It then set about sending the information along with dates and times etc. etc to Amazon IoT for analysis. The manufacturer Netgear discloses all this in their privacy statement. i.e. Netgear knows where my phone has been and when. OpenWRT and friends are the answer to this issue, but this expensive piece of hardware isn’t supported…

Having a system inside that can listen to such things and report them remotely is a (possibly personal) problem for me. Obviously you trust your software. However, here docker is using the “container” aspect of containers to restrict access to such things. And pretty successfully so far really.

In this case the container will never be allowed to operate in mode=host where it has unfettered access to the network. In my view it is simply not possible to ensure network security and privacy in this scenario otherwise. This is a differentiator between HA and OH. HA appears to go to great lengths to ensure it can spy on its users, either by accident or design.

Thanks for the advice regarding to the network issue being out of scope. It helps a lot knowing that nothing has been done to specifically change how the container operates. It sounds like this is a docker issue.

Thanks again for your help. And please keep up the excellent work. OH is the best and I love it.

If I find the cause I’ll post the solution here too.

See the Netgear RAX40 link for a complete explanation and hack to prevent leakage.

This point is somewhat moot now as the new house has TP-Link Wireless Access Points. One of the newer WAPs is the TP-Link EAP-225 European model (version 5) which now provides an option (which is on by default) to disable centralized reporting.

Clearly Europe is taking privacy seriously, whereas the US model is basically a free-for-all with your personal data, as disclosed in their privacy statement. The unit was purchased at CentreCom in Bendigo. The privacy function meant that OpenWRT (which only works with version 3) was not required.

Docker Swarm Clusterization

The Docker Swarm cluster diagram mainly shows the OpenHAB stack. The DMZ stack (loosely named as it *is not* a firewall thing - but sort of does the something similar) only shows those containers directly connected to OpenHAB_stack so most of the DMZ stack is not shown here. The MQTT server (provided by RabbitMQ - with LDAP authentication enabled) proxies access to the IoT device fleet. (any feedback most welcome - via twitter @electricbrain2).

The system is somewhat updated compared to this diagram. The Fronius solar inverter is no longer present in the current setup (it's still installed in the Melbourne house). Instead we inherited a bottom of the line Solax X1 system in the new house (which has been fully compromised and is providing data, via a Raspberry Pi Zero W, directly to the MQTT server - no more Chinese cloud servers are involved). The entire inverter now looks like another IoT device as far as OpenHAB is concerned.

As previously stated (and I can't say it enough), none of the containers (i.e. pretty much virtual computers) has access to the physical network. Essentially whatever nasty software is compiled in to those applications they can't talk ouside their container boundaries except under very tight supervision.

A couple of the containers have fixed locations within the cluster (pins shown). Most are free to move about wherever Portainer/Docker-Swarm thinks they should go.

Portainerized installation

The main OpenHAB stack:

Right click and view for more detail

Another stack (the DMZ) is also involved in brokering access on and off the OpenHAB private virtual network (PVN) to resources such as

  • the network LDAP authentication servers in RO mode (RabbitMQ - full LDAP authentication for all devices)

  • an externally directed proxy (which can be one of TOR, VPN or Direct to wire)
  • an authenticated inbound proxy controlling who can see PVN resources (i.e. OH web interface).
  • Amazingly all this works and, I believe, provides unparallel security/privacy both from the app itself (we trust it right ?) and external/internal attackers.

 

Container OpenHAB

  • EXTRA_JAVA_OPTS:
    • -Duser.timezone=Australia/Melbourne
    • -Dhttp.proxyHost=httpdproxy
    • -Dhttp.proxyPort=80
    • -Dhttps.proxyHost=httpdproxy
    • -Dhttps.proxyPort=80
    • -Dftp.proxyHost=httpdproxy
    • -Dftp.proxyPort=80"
  • A container healthcheck was added in version OH31M5 . This needs to be disabled when proxies are used (check compose 3+ syntax):
    • healthcheck:
        disable:true
    • Ultimately the new healthcheck needs to have curl --no-proxy localhost added to make it work in all cases.
  • Internet access via
    • httpd proxy dmz-external-network
    • ftp proxy dmz-openhab-network
    • Additional environment variables to get various internal container utilities to work via a proxy
      • http_proxy: "http://httpdproxy:80/"
      • https_proxy: "http://httpdproxy:80/"
      • ftp_proxy: "http://httpdproxy:80/"
  • AddOn
    • JSONPath Transformation
    • RegEx Transformation
  • Bindings
    • Fronius Binding
      • Link each Fronius Inverter channel to an item using the auto-naming. Again via a proxy isolating OH from directly talking to the inverter or other devices on that segment.
         
    • MQTT Binding
      • Talks to RabbitMQ which has two interfaces, PVN and Tasmota VLAN. This isolates OH from the possiblity of directly communicating with any device.
    • BOM Binding
      • Enhanced by the author to allow external proxying. There is no direct access to the outside world for OH or its plugins.

  • Persistence
# the database url like 'jdbc:mysql://<host>:<port>/<database>' (without quotes)
#url=
url=jdbc:mysql://db.dmz-openhab-network:3306/openhab?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Australia/Melbourne

# the database user
#user=
user=openhab

# the database password
#password=
password=xxxxxxxxxxxxxxxx

# the reconnection counter
#reconnectCnt=

# the connection timeout (in seconds)
#waitTimeout=

# Use MySQL Server time to store item values (=false) or use openHAB Server time (=true).
# For new installations,
 its recommend to set "localtime=true".
# (optional,
 defaults to false)
#localtime=true

Container MySQL

 

Container phpMyAdmin

Container RabbitMQ

  • enabled_plugins
    • advanced.config
[{rabbitmq_auth_backend_ldap,[
     {ssl_options, [
       {cacertfile,"/etc/rabbitmq/certs/ca-certs.crt"}
     ]},
     {tag_queries, [
       {administrator, {in_group, "cn=Administrators,ou=RabbitMQ,dc=lan,dc=localdomain"}},
       {management,    {in_group, "cn=Managers,ou=RabbitMQ,dc=lan,dc=localdomain"}}
     ]}
]}].

 
  • rabbitmq.conf
loopback_users.guest                  = false
total_memory_available_override_value = 536870912
listeners.tcp.default                 = 5672
management.tcp.port                   = 15672
auth_backends.1                       = ldap
auth_backends.2                       = internal
auth_ldap.servers.1                   = ldapproxy.dmz-openhab-network
auth_ldap.port                        = 636
auth_ldap.user_dn_pattern             = cn=${username},ou=People,dc=lan,dc=localdomain
auth_ldap.dn_lookup_bind.user_dn      = cn=bind_ro_rabbitmq,dc=lan,dc=localdomain
auth_ldap.dn_lookup_bind.password     = RabbitMQsPassword
auth_ldap.use_ssl                     = true
auth_ldap.port                        = 636
auth_ldap.log                         = false
#
# auth_ldap.log                       = network_unsafe

 
 
[rabbitmq_management,rabbitmq_prometheus,rabbitmq_mqtt,rabbitmq_auth_backend_ldap].

Tasmota

  • Set TZ:
    Backlog TimeZone +11; timeDST 1,1,10,1,2,660; timeSTD 1,1,4,1,2,600
  • WiFi - choose strongest on reboot:
    SetOption56 On
  • Power on always:
    PowerOnState 4
    SetOption0 On (default)
    SetOption63 Off (default)