Making MaxEcho listen to web requests. With proper DNS. With TLS. With IPv6.

 

Problem statement

Our MaxEcho voice assistant does work great (apart from wit.ai outages or updates). But we also want some level of web/api access.

MaxEcho runs on a raspberry pi in a WLAN connecting to an AVM Fritz!Box 7490.
MaxEcho runs a node process which also listens to an https custom-port to have secure data transfer.

After using self-signed certificates, we wanted to connect to MaxEcho from the internet. Therefore the FritzBox was setup to forward a custom-port for its public facing IPv4 to the raspberry’s interface. We used the FritzBox’s DHCP server to provide a fixed IPv4 for the FritzBox.

To get a decent DNS name we utilized the MyFritz feature with provides .myfritz.net addresses with a generated prefix (myprefix). I wanted to use an own DNS name (max.mydomain.com), so I setup the DNS setting of max.mydomain.com to have the CNAME pointed to myprefix.myfritz.net. This was working fine and I used Let’s Encrypt and the certbot tool to get a SSL certficate for max.mydomain.com.

To allow the certbot tool to validate the website, I configured port 80 to be forwarded by the FritzBox to the raspberry pi and on nightly certificate renewal cron job runs, the certbot tool would open a local webserver on port 80 serving an ACME http challenge to prove DNS ownership.

So we got: https://max.mydomain.com:custom-port and all was good.

The issue

This worked well for some time. But then there was an update to certbot which preferred IPv6 over IPv4. So while the DNS ownership was validated using the http challenge it tried to connect to the IPv6 address resolved from the setup of max.mydomain.com and hence myprefix.myfritz.net. As the FritzBox runs both IPv4 and IPv6, the DNS entry contained a valid AAAA entry, pointing to the actual FritzBox, but not the raspberry pi. So connection timed out and certbot did not fallback to IPv4 (this is intented behaviour) and the SSL certificate was not renewed.

At first I disabled IPv4 all together, but this bugged me and I used some time during winter holiday to get IPv6 back.

Current solution

Preamble

A note of caution: I am a network noob. I do not have great insight into IPv6 (I am glad I understood IPv4 stuff). So my solution may be flawed, not optimal or rated inefficient by others. Consider this and use the information on your own risk.

Reaching IPv6 server behind FritzBox

AVM provides a great feature with myfritz.net services. You can actually configure “MyFRITZ! accesses”, which will create a DNS name for the device you want to reach behind your FritzBox. So you will have a DNS name pi.myprefix.myfritz.net. This comes in handy for IPv6.

When setting up the access (german: MyFritz Freigabe) via the FritzBox user interface to configure the access, I did NOT use a port-based access, but selected to create a MyFRITZ access. Only this will provide the DNS support required.

So I setup two access configurations for MaxEcho: One for port 80 and one for the custom-port and finally ended up with four entries: Two IPv4 port-forwardings/NAT and two IPv6 port-openings with the name pi.myprefix.myfritz.net.

Now I used that name as CNAME target on max.mydomain.com >> pi.myprefix.myfritz.net.

The final issue to overcome was, that the raspberry pi did have a “scope: link” address for IPv6 which was used for the access configuration, but not working for internet access, as this is a non-routable address. There was also a “scope: global” IPv6 address, but I could not use this in the FritzBox configuration, as it was changing (I do not even know how that address is created.).

So I played around with the settings and tried to understand IPv6 address creation and read about Stateless Address Autoconfiguration (SLAAC) and ICMPv6 Router Advertisements (RAs) and DHCPv6. Finally I setup DHCPv6 within the FritzBox to provide dynamic IPv6 addresses to the devices and now my pi got a routable, global scope IPv6 which was also used in FritzBox MyFritz accesses. That global IPv6 address is used for the AAAA record of pi.myprefix.myfritz.net and also updated whenever the FritzBox gets a new IP from the ISP.

Now MaxEcho can be reached via IPv4 and IPv6, using max.mydomain.com powered by auto-renewed certificates from Let’s Encrypt.

Mission accomplished.

Advertisements