Thoughts about routing the domain to the MQTT server IP address #124
Replies: 5 comments 8 replies
-
|
Hi, thanks for your write up. I think private IP in public DNS with ACME DNS-challenge could be a really good thing for minimal setups. Would you validate if this works out? |
Beta Was this translation helpful? Give feedback.
-
|
same here. Working with local-IP set even with cloud on. No issues |
Beta Was this translation helpful? Give feedback.
-
|
Is anyone try to mirror traffic to cloud also to local ip? |
Beta Was this translation helpful? Give feedback.
-
|
@Saentist @criticallimit do you use the Let's Encrypt Addon or how do you get the certificate? |
Beta Was this translation helpful? Give feedback.
-
|
I'm using duckdns add-on in home assistant where the lets encrypt is included. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
EDIT: It turns out it is possible to just set the local private IP address directly in the field
Server domain name/IPof the Growatt device on the ShinePhone app instead of having to use a domain name. See the discussion below in the comments. I incorrectly assumed that wasn't possible. Therefore, most of this post is completely unnecessary and the three options I explain below, for routing the domain to the MQTT server IP address, are useless for setting up GroBro, since the IP address can just be used directly, as far as I know (now).I will leave this post for informational purposes and if it should happen that a device or firmware comes along in the future, which checks that the MQTT broker address and certificate domain match.
The section about the certificate at the end is still useful though, because a valid TLS certificate is required for running GroBro, even if it doesn't matter what domain it is for and what IP that domain resolves to.
A main complication of this project seems to be, that the Growatt device has to address the MQTT server (the setting "Server domain name/IP" in the ShinePhone app) with a proper domain like example.duckdns.org and cannot just use the private IP address like 192.168.1.111. The reason for this is the Growatt devices properly checking the certificates of the TLS connection as explained in the readme.Edit: Turns out that this is not true!As far as I can think of there are three solutions to route the domain to the MQTT server IP address:
All these solutions require, that the device the MQTT broker is running on has a permanent local IP address configured in your router and that the certificate of the domain is renewed regularly (I talk more about automatic certificate renewal in the last section).
Let me preface this by saying that I am in no means an expert and this should be taken with a grain of salt, especially the parts about security.
1. Resolve the domain via public DNS to the external public IP address of the home network
This involves using a DynDNS service, running a DynDNS client on the router or another device (unless the ISP already provides a domain adress) and then setting up port forwarding in the firewall settings of the router for the TLS port of the MQTT broker. The TLS port is then exposed to the internet and can be accessed externally.
However, it is important that people know what they doing, since making a mistake and forwarding the wrong ports to the internet might be a huge security issue. When exposing ports to the internet, it would be also best practice is to have some kind of security software running like CrowdSec to limit the login attemps, which further complicates this setup.
If you have already configured most of the stuff mentioned above anyways (you are accessing sevices from your home network already externally), this solution is very easy, because only the TLS MQTT port forward has to be added. However, there are some security considerations about exposing this port.
I think it would be more secure to use an arbitrarily chosen port number instead of default ones like 1883, 8883, 9001 or 7006. For Growatt the login credentials don't seem to be very secure (username is the serial number and the password is "Growatt"). A mistake you also have to be careful with is configuring another user with a very weak password in the MQTT broker, which is meant for use only by home devices, and not realizing this user can also be used login into the MQTT broker through the internet, unless the Mosquitto option per_listener_settings is enabled. The Home Assistant MQTT add-on actually accepts all user logins, which are configured in Home Assistant. So with the default configuration all Home Assistant users have to have strong passwords, if you want to safely forward the TLS port of the MQTT add-on.
Having said that, I don't think an intruder gaining access to the MQTT broker can actually do any harm in most cases, but it might open the door to other exploits to gain further access to the private network.
2. Resolve the domain via a local DNS server to the local private IP address of the MQTT server
This requires to have some custom configuration on a local DNS server, which runs either on your router or another device on the network. This is mentioned in the readme instructions at step 5.
This is completely secure, because everything stays within the local network. No port forwarding and no DynDNS is required. However, the certificate still has to be renewed somehow.
This is a rather easy and convenient way, if you are already running a DNS server, where manual DNS routing entries can be configured like Pi-Hole, AdGuard Home or you have advanced options on your router. Unfortunately, most ISP provided routers don't have these options and often don't even allow changing the DNS server address, so you can reroute DNS requests to a DNS server on your local network. In this case it would be necessary to upgrade the router, because there doesn't seem to be a way to set a custom DNS address in the Growatt devices.
3. Resolve the domain via public DNS to the local private IP address of the MQTT server
I haven't seen this being discussed here and I can't test this yet, but I think this should also be possible as a third option: Setting the domain record publicly to the private local IP address of the MQTT server.
The advantage is that no port forwarding, no DynDNS and no local DNS server with custom config is required. However, the certificate still has to be renewed somehow.
There are some minor security considerations about this, because you are publicly exposing what local private IP address your device has, as far as I understand it. However, this should be an insignificant concern. Here is a discussion about this.
As an example, this can be achieved by registering a new subdomain at Duck DNS and the just manually entering the local private IP address of the MQTT server (192.168..., 172..., or 10...) in the IPv4 field of the subdomain on the Duck DNS website. Because the IP address stays constant, don't run any kind of DynDNS client for this domain.
Automatic renewal of a certificate without running a web server
If you are running already a web server or are self hosting stuff with external access, you can just use the same certificate your reverse proxy or web hoster provides, if you have easy access to the private key.
The TLS certificate of your domain has to be renewed regularly (typically every 2 months). In order to automatically renew the certificate without exposing a port 80 to the internet or running a webserver elsewhere, it is required to run a ACME client configured to use a DNS challenge (on any device anywhere with internet). A list of compatible DNS host providers and ACME clients can be found here. For example here is the config to use the acme.sh client with DuckDNS.
If you are running Home Assistant OS, the Duck DNS addon is an easy way to get a certificate which is automatically renewed. This addon uses a DNS challenge and does not require forwarding/exposing ports.
I believe after the certificate is renewed, it is necessary to concatenate a full-chain certificate again, as it is outlined in the guide here. The MQTT broker also has to be told to reload the certificate.
As an example, I described how to get a certificate and update it using a DNS challenge, Duck DNS and the acme.sh docker container in this post here.
Beta Was this translation helpful? Give feedback.
All reactions