/ham

✅ Podman powered home automation. Home Assistant, VPN, Pi-Hole, MQTT, Caddy and more...

HAM (Home Automation Machine)

This is version two of HAM (see version one), the host machine is now running Fedora Silverblue and uses Podman instead of Docker. This allows the containers to run rootless and have a slightly more stable system upon which to build my #homelab. I have also upgraded from a Raspberry Pi to a x86 system with a small footprint and low power demands.

I am mostly just publishing the relevant docker-compose / podman-compose files that are grouped into pods around certain pieces of functionality like home automation or media. I think this makes more sense, especially as more of my Home Assistant config is moved from YAML to the database.

General / OS tweaks

Packages

I layer the following packages:

rpm-ostree install sshfs docker-compose podman-docker podman-compose wireguard-tools cronie

podman-docker allows you to use the Monitor Docker Home Assistant component for automating and monitoring containers.

Podman

Enable the Podman socket and set the DOCKER_HOST environment variable for more Docker like behaviour:

systemctl --user enable podman.socket
systemctl --user start podman.socket
systemctl --user status podman.socket

Add the following to your ~/.bash_profile

export DOCKER_HOST=unix:///run/user/$UID/podman/podman.sock

Reference: Use Docker Compose with Podman

Test the Docker API with:

sudo curl -H "Content-Type: application/json" --unix-socket /run/user/1000/podman/podman.sock http://localhost/_ping

Reference: Using Podman and Docker Compose

Start the Podman restart service (restarts containers set to restart: always) after a reboot:

systemctl --user enable podman-restart.service
systemctl --user start podman-restart.service

With the release of Podman 5 (Fedora 40), there are some breaking changes with the switch from slirp4netns to pasta. This caused two of my containers to break; Caddy and WireGuard. I still need to read more into but for now the fix is to switch back to slirp4netns for container networking by adding the following to ~/.config/containers/containers.conf:

[network]
default_rootless_network_cmd = "slirp4netns"

The system then needed to be rebooted and containers were behaving as before.

Allow long running tasks

As Silverblue is a desktop OS, it tries to shutdown long running tasks (including Podman containers). This can be turned off by running: loginctl enable-linger, check the status with ls /var/lib/systemd/linger, then reboot.

Connectivity check

Fedora has a built in connectivity check that phones home rather frequently. It's probably more useful on a system that uses WiFi, but as this machine is connected via Ethernet I decided to turn it off. sudo nano /etc/NetworkManager/NetworkManager.conf:

[connectivity]
enabled=false
uri=http://fedoraproject.org/static/hotspot.txt
response=OK
interval=300

Then run systemctl restart NetworkManager for the changes to be picked up.

System time

I found that my system time was getting out of sync, so enabled NTP

timedatectl set-ntp yes
timedatectl

Reference: Configuring date and time

SSH

Tweak some SSH settings to restrict access:

PermitRootLogin	no
PermitEmptyPasswords no
X11Forwarding no
PasswordAuthentication no
AllowUsers username@192.168.1.* username@10.80.x.x (example for more IPs)

These tweaks can be added to /etc/ssh/sshd_config.d/50-redhat.conf and applied with sudo systemctl reload sshd.

Cron

cronie is a layered package (rpm-ostree install cronie).

sudo nano /etc/cron.allow
# add your username

systemctl enable crond.service
systemctl start crond.service

crontab -e

Reference: Scheduling tasks with Cron, Automating System Tasks

USB sleep / Auto suspend

To save power Fedora will sleep USB devices. We need to turn this off for Deconz and the Zigbee USB stick (ConBee II):

sudo rpm-ostree kargs --append=usbcore.autosuspend=-1

# check
cat /sys/module/usbcore/parameters/autosuspend

Gnome suspends after 15 minutes

Since Fedora 38 the server started auto suspending after 15 minutes. This was due to a settings change that can be adjusted with:

# check state of power settings
sudo -u gdm dbus-run-session gsettings list-recursively org.gnome.settings-daemon.plugins.power | grep sleep

# set to 0 to disable autosuspend on power
sudo -u gdm dbus-run-session gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-ac-timeout 0

Reference: Gnome suspends after 15 minutes

Containers

Caddy

I am using Caddy as a local reverse proxy. Along with the Pi-hole it allows custom domains like homeassistant.lan for each of the services. Caddy needs access to port 80 and 443 so the firewall needs to be opened:

sudo firewall-cmd --zone=FedoraWorkstation --add-service=http
sudo firewall-cmd --zone=FedoraWorkstation --add-service=http --permanent
sudo firewall-cmd --zone=FedoraWorkstation --add-service=https
sudo firewall-cmd --zone=FedoraWorkstation --add-service=https --permanent

firewall-cmd --get-default-zone will let you know which zone you are currently using.

Pi-hole

Pi-hole also needs a few tweaks (including a hole in the local firewall):

sudo sysctl net.ipv4.ip_unprivileged_port_start=53
sudo nano /etc/sysctl.conf
# add net.ipv4.ip_unprivileged_port_start=53

sudo nano /etc/systemd/resolved.conf
# add DNSStubListener=no

sudo systemctl restart systemd-resolved
sudo systemctl restart NetworkManager

sudo firewall-cmd --zone=FedoraWorkstation --add-port=53/udp
sudo firewall-cmd --zone=FedoraWorkstation --add-port=53/tcp
sudo firewall-cmd --permanent --zone=FedoraWorkstation --add-port=53/udp
sudo firewall-cmd --permanent --zone=FedoraWorkstation --add-port=53/tcp

Reference: Using firewalld, Running Pi-hole in a Podman container

Home Assistant

The nmap scanner has to run in unprivileged mode. To do this modify the Nmap Tracker options in the Home Assistant UI and add --unprivileged to the raw configurable scan options.

The container needs access to USB which is a little tricky using Podman. You need to create a udev rule that changes the group and owner of the USB device when its plugged in so the container can access it.

# set policy for containers to use USB devices in SELinux
setsebool -P container_use_devices on

ls -l /dev/ttyUSB0

# change owner of /dev/ttyUSB0 to your username
lsusb
sudo nano /etc/udev/rules.d/99-skyconnect.rules

# add the following to the rule file (based on what you get from lsusb)
SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", OWNER="username", GROUP="username"

# apply changes
sudo udevadm control --reload-rules
sudo udevadm trigger

Reference: Access USB from rootless container, udev rule tips

Samba

The Samba container requires a hole in the firewall:

sudo dnf install samba
sudo systemctl enable smb --now
firewall-cmd --get-active-zones
sudo firewall-cmd --permanent --zone=FedoraWorkstation --add-service=samba
sudo firewall-cmd --reload

Reference: Setting up Samba on Fedora

VPN / WireGuard

It took some time to get WireGuard running rootless but the docker-compose.yaml file in the vpn folder is now working. I spent a great deal of time experimenting with this and I cannot exactly remember all the steps I took. I think the main thing you will need to do is enable the kernel module for WireGuard if it's not already enabled... and a few others for ip managment:

# see which modules are loaded 
lsmod

# enable required kernel modules
sudo touch /etc/modules-load.d/wireguard.conf

Add the following to wireguard.conf:

# load wireguard at boot
wireguard

# modules for nat
ip_tables
iptable_filter
iptable_nat
xt_MASQUERADE
xt_nat

Reboot and the container should now start.

Useful links