Split DNS on UDM Pro

Less than a month ago I wrote about how to split your DNS forwards depending on the domain. Like sending any queries for example.com to allowing you to have an internal resolution for some domain names. A common scenario is for a company with externally published services on its domain. While the user outside will hit a Firewall, WAF, or load balancer as they navigate to the URL users on the inside might not be able to take the same route. There might be issues with firewalls dropping traffic coming from the inside with their public IP as the destination or it’s just not as efficient as routing the traffic internally to the server.

In my last post, I showed how to do this via the config.gateway.json file that applies to USG setups with controllers, either Cloud Keys or self-hosted. Now we will take a look at the Dream Machine which has no support for the config.gateway.json setup but brings a lot of other interesting things to the table.

Read More

Build ElectronJS apps for Rasberry Pi

ElectronJS allows you to more or less build a web application that can be distributed as a native application. The code is written in javascript and uses standard HTML and CSS for the presentation layer. The code is packaged with a chromium browser and distributed as an application. Can you really build powerful applications this way? Yes, among the more popular apps built on ElectronJS is Visual Studio Code, Slack, Discord and Skype. There are a lot more examples! From the same codebase, you can build Windows, macOS and Linux applications. This article will focus on building for Raspberry Pi and its armv7l architecture but this setup can also be used to create build pipelines for other architectures as well.

Read More

Split DNS forwarding from Unifi gateway

When using Traefik, or any other reverse proxy, in front of docker containers you need a proper domain to get an SSL certificate from LetsEncrypt. You also need a proper public DNS for the domain to allow LetsEncrypt to verify ownership via DNS or web requests. If you want to use this for internal systems you either need to add all the private A records to the public DNS or make a split zone. A DNS split means that some requests are forwarded to an internal DNS while all else is resolved by a public DNS on the internet.

Read More

Unit test your Firestore security rules

When developing a Firebase app with a Firestore database layer a lot of tutorials suggest allowing all traffic while developing and then setting the rules. I always do the other way around, I keep the default deny all rule and then open up for each use case I have.

service cloud.firestore {
    match /databases/{database}/documents {
        // Default rule
        match /{document=**} {
            allow read, write: if false;

When writing security rules it’s very important to think about what malicious users might try to get around them. How they would try to access or manipulate other user data. When writing unit tests for the security rules we need to test that users can access data as intended but also focus on what should fail. All the different scenarios that we can think of that shouldn’t be possible to be sure that the user can’t access or create any data that they shouldn’t.

Read More

Export Firestore to dev environment

Sooner or later you need production data in your development environment to test or develop a more rich UI experience based on real life data. There are a few ways of doing this, but this is the easiest especially if your on a windows machine.

You probably already have a persistent data in your dev environment, if not just run the emulators with the following command.

firebase emulators:start --import=./dev_data --export-on-exit

This will import any data you have in the Firestore and Authentication emulators and then import it on the next run. Don’t forget to add ./dev_data to your .gitignore.

Download the data

The data download need to go via a storage bucket. You will probably already have a few buckets if you published your project at any point. I also assume that you have your firebase and gcloud utils installed and authenticated. If not install them and run:

firebase login
gcloud auth login

Then export the data to the default storage bucket. If your on windows do not use the Cloud Firestore Import/Export page in the console. It will add special characters in the filename preventing you from downloading the data. Use the gcloud tool instead.

gcloud firestore export gs://your-project-name.appspot.com/your-choosen-folder-name

Depending on the size of your Firestore this can take some time. When it’s done we can download the data with gsutil.

gsutil -m cp -r gs://your-project-name.appspot.com/your-choosen-folder-name .

The last . means that the data will be downloaded to the current working folder. I put the data in a folder named prod_data inside my project folder. This folder is also added to the .gitignore file to prevent the data from leaving my dev environment. Then I can run my emulators with the downloaded data.

firebase emulators:start --import=./prod_data --export-on-exit


You can easily automate this procedure in a simple powershell script to grab data whenever. Always be careful when working with production data in your dev environment. Make sure that you don’t leak any data via git for example. Also make sure you keep the data encrypted on your workstation and delete it as soon as you don’t need it anymore.

More reading: https://firebase.google.com/docs/firestore/manage-data/export-import

Raspberry Pi pains of the past

Don’t get me wrong, I love my Raspberry Pi’s and I have spent a lot of time on both successful and less successful projects. A lot has happened since 2012 when they first came out, more powerful hardware and much better software support. In the later years I have done everything from home automation projects, VPN gateways and Docker clusters. I totally forgot the pains of reaching to high on the old versions and running straight into a brick wall with limitations for what I tried to do. But now I remember!

Read More

Google Maps only for the city?

Before the Covid-19 pandemic I used to travel a lot. Using Google maps to find the local hotspots and trying to avoid the tourist traps with Google Maps Reviews. So I started writing my own reviews and adding pictures. Besides being a traveler, programmer, tech nut and many other things I’m also a hiker and I hike a lot. I have tons of photos and GPS tracks of official and unofficial hiking trails, shelters and firepits that I would like to share. So a hobby project idea was born.

Read More

OctoScreen on Adafruit PiTFT 320×240

Finally got around to moving my Ender 5 Plus, and it’s load power supply, out of my office. So more then ever I want OctoPrint up and running for remote monitoring of my setup. I had a Raspberry Pi 4 unused and found an old Adafruit PiTFT 320×240 touch screen in the scrap bin. Getting OctoPrint up and running is easier then ever with the pre-built image for Raspberry Pi. The old touch screen was another story so here is my final notes on how to get it up and running. I assume that my audience already have OctoPrint up and running and just want the screen to work.


So first we need to upgrade everything to the latest version. Connect to the OctoPi via SSH, the default usernam/password is pi/raspberry.

sudo apt-get update && sudo apt-get upgrade

Then make sure that OctoPrint is up to date from the OctoPrint web UI. Then we can install the screen with Adafruits automation script. More information here: https://learn.adafruit.com/adafruit-pitft-28-inch-resistive-touchscreen-display-raspberry-pi/easy-install-2

cd ~
sudo apt-get install -y git python3-pip
sudo pip3 install --upgrade adafruit-python-shell click==7.0
git clone https://github.com/adafruit/Raspberry-Pi-Installer-Scripts.git
cd Raspberry-Pi-Installer-Scripts
sudo python3 adafruit-pitft.py

Go for the option with HDMI mirroring not console! When setup is completed correctly you should have the login screen showing after reboot.

OctoScreen installation and setup

Installation of OctoScreen is pretty straight forward. It’s uses an X11 application instead of a web browser like TouchUI and similar. More information on the OctoScreen install: https://github.com/Z-Bolt/OctoScreen

sudo apt-get install libgtk-3-0 xserver-xorg xinit x11-xserver-utils
wget https://github.com/Z-Bolt/OctoScreen/releases/download/v2.7.2/octoscreen_2.7.2_armhf.deb
sudo dpkg -i octoscreen_2.7.2_armhf.deb

After the installation completes and a reboot one arm of the OctoPrint octopus becomes visible on the screen. We need to change the resolution to match the screen. So edit the OctoScreen config file and change the OCTOSCREEN_RESOLUTION value to 320×240.

sudo nano /etc/octoscreen/config

Screen settings

The screen still doesn’t look as expected and need some additional tweaking. First change the resolution settings for the screen in the boot config.

sudo nano /boot/config.txt

Un-comment and set the following values:


At the bottom change the HDMI settings to:

hdmi_cvt=660 390 60 1 0 0

After a reboot the screen should look fine but the touch screen will not be aligned and unusable. Both the X and Y axis seems to be inverted but not in a fully logical way. This also has to do with the change of the resolution. Install xtcal to calibrate the touchscreen for X11 use.

cd ~
sudo apt-get install libxaw7-dev libxxf86vm-dev libxaw7-dev libxft-dev
git clone https://github.com/KurtJacobson/xtcal
cd xtcal

Now we run the calibration with the same values we used for the framebuffer settings to get an accurate calibration.

pi@octopi:~ $ DISPLAY=:0.0 xtcal/xtcal -geometry 660x390
fullscreen not supported
Calibrate by issuing the command below, substituting with the name found using xinput list.
xinput set-prop 'Coordinate Transformation Matrix' -0.003810 -1.123983 1.038378 1.124421 0.006780 -0.076729 0 0 1

The output we get at the bottom is the actual calibration information needed to get it all to work. In this case -0.003810 -1.123983 1.038378 1.124421 0.006780 -0.076729 0 0 1. Then we build an transformation matrix to offset and calibrate the touch screen. Edit sudo nano /usr/share/X11/xorg.conf.d/20-calibration.conf and add the information below. You can see where the calibration output is added into this. Then reboot the Pi again and it should all work just fine. You can read more about the calibration here: https://learn.adafruit.com/adafruit-pitft-28-inch-resistive-touchscreen-display-raspberry-pi/resistive-touchscreen-manual-install-calibrate

Section "InputClass"
        Identifier "STMPE Touchscreen Calibration"
        MatchProduct "stmpe"
        MatchDevicePath "/dev/input/event*"
        Driver "libinput"
        Option "TransformationMatrix" "-0.003810 -1.123983 1.038378 1.124421 0.006780 -0.076729 0 0 1"


This will work just fine and you can use most of the menus. Some of them will not fit properly on the screen and you will not be able to get back to the main screen. If that happens and you don’t want to reboot the Pi you can issue sudo service octoscreen restart over ssh.

So this is somewhat useful but you can see that this isn’t designed for such a small screen. Bur if you ended up on this post you’re probably in the same situation I was and just want it to work!

Firebase: Unit-testing Firestore rules

Developing serverless web applications on Firebase is great. Quick and easy for new project ideas. The most important part of a Firebase deploy is the Firetore rules since the client speaks directly with the database. Todd Kerpelman at Firebase made a couple of really great videos on unit testing the security rules which is really good to get started. Once you have them running you really want to put them into your build chain and make sure they are executed before each deploy.

Read More

GCB Firebase deploy error

Using Google Cloud Build to build and deploy your frontend NodeJS application is well documented in Building Node.js applications and Deploying to Firebase. How ever all these, or at least a majority of them, are based on Linux based development systems. If your on a windows machine you can run into a very specific problem with the firebase build step and docker container.

standard_init_linux.go:211: exec user process caused "no such file or directory"

When built by following the guide on windows you will end up with the error above. This is because windows uses CRLF instead of LF as end of line. The simplest way around this is to use WSL Windows Subsystem for Linux to follow the guide and the build container will work just fine.