Rootless Podman: Running a Home‑NAS Service Without Privilege Escalation

Why Rootless Containers Matter for a Home‑NAS

When a home‑NAS sits on a single‑user machine, the first instinct is to give the NAS service full root access. That works, but it also opens a door for accidental or malicious privilege escalation. Rootless Podman lets you run containerized services—Nextcloud, Syncthing, or a simple Nginx reverse proxy—inside a user namespace that isolates the container from the host. The container can still read and write to your data directories, but it can’t touch the kernel or system services.

[Read More]

Why my SSH key‑based login keeps timing out after a system reboot – and how to fix it with ssh‑config and ssh‑agent

When you power on a server and hit ssh user@host, the connection dies in a few seconds even though the key works on a fresh machine. The usual suspect is the SSH agent – it’s either not running or not forwarding the key after a reboot. The fix is straightforward: make the agent start automatically, add your key once, and let ssh_config do the rest.

1. Verify the agent is running

ssh-add -l

If you get The agent has no identities, the agent isn’t started or $SSH_AUTH_SOCK isn’t set. On most modern distros the agent is started by the display manager or a systemd‑user unit. Check it with:

[Read More]

Turn /tmp into a tmpfs so you never run out of space during a log surge

Why /tmp on a tmpfs is a lifesaver for log‑heavy workloads

If a service starts spamming logs, a full /tmp can bring the whole system to a halt. On low‑RAM servers or in containers where /tmp lives on a regular disk partition, the problem is even worse. Mounting /tmp as a tmpfs keeps it in memory, guarantees instant cleanup, and stops disk‑space exhaustion. Below is a practical, step‑by‑step guide that covers the trade‑offs and security notes you’ll need to keep in mind.

[Read More]

Avoiding the “Broken Packages” Hang When Upgrading From Ubuntu 22.04 to 24.04 on a Home Server

Why the “Broken Packages” Hang is a Common Pain Point

When I run a fresh upgrade from Ubuntu 22.04 LTS to 24.04 LTS on a home server, the first thing that can bite me is the infamous “Broken Packages” dialog that stalls the upgrade process. It isn’t a bug in the installer; it’s the package manager trying to juggle a huge shift in dependencies between releases. The result is a long pause—sometimes hours—before the system finally moves on. For a server that should stay online, that pause is unacceptable.

[Read More]

Send a Telegram Alert When Your Home Server’s /home Reaches 90% Usage With a Tiny systemd Service and curl

Monitoring /home Usage with a Systemd Timer

A home server rarely needs a full‑blown monitoring stack.
If you just want a quick alert when /home fills up, a tiny systemd service plus curl will do the trick. The example below keeps the footprint minimal, respects security best practices, and uses the official Telegram Bot API.

1. Create a Bot and Grab Credentials

  1. Talk to BotFather on Telegram and create a bot.
  2. Note the bot token (e.g. 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11).
  3. Find your chat ID by sending a message to the bot and querying https://api.telegram.org/bot<token>/getUpdates.
  4. Store both values in a read‑only file:
sudo mkdir -p /etc/telegram-alert
sudo tee /etc/telegram-alert/credentials <<EOF
TOKEN=123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
CHAT_ID=987654321
EOF
sudo chmod 600 /etc/telegram-alert/credentials

2. Service Unit – home-usage-alert.service

# /etc/systemd/system/home-usage-alert.service
[Unit]
Description=Send Telegram alert when /home exceeds 90%% usage
After=network.target

[Service]
Type=oneshot
EnvironmentFile=/etc/telegram-alert/credentials
ExecStart=/usr/bin/bash -c '
  USAGE=$(df --output=pcent /home | tail -1 | tr -d "%")
  if [ "$USAGE" -ge 90 ]; then
    curl -s -X POST https://api.telegram.org/bot$TOKEN/sendMessage \
      -d chat_id=$CHAT_ID \
      -d text="⚠️ /home is at ${USAGE}%% capacity. Free space needed." \
      -H "Content-Type: application/x-www-form-urlencoded"
  fi
'
PrivateTmp=yes
ProtectSystem=full
RestrictAddressFamilies=AF_INET AF_INET6
Restart=no

[Install]
WantedBy=multi-user.target

Security notes

[Read More]

Easily Remove Stale Entries from ~/.ssh/known_hosts When a Host Rebuilds with ssh-keygen ‑R

When a host rebuilds, its SSH key changes

A fresh install or a system rebuild swaps the host’s RSA/ED25519 key pair.
If you still have the old key in ~/.ssh/known_hosts, the next SSH connection will trigger a “WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!” message.
That warning is a safety feature, but it also blocks automation and forces users to manually edit the file.

The quickest, safest way to clean up stale entries is to let OpenSSH do the work with ssh-keygen -R. The command removes every key that matches the supplied hostname or IP, regardless of whether the entry is hashed or plain.

[Read More]

Launch a temporary root process with `systemd‑run` instead of `sudo`

Run a single command as root with systemd‑run

When you just need to fire up one command as root and then drop back, sudo is the go‑to.
But if your distro already runs systemd, systemd‑run can be a leaner, more isolated way to do it—especially for short‑lived tasks.

What systemd‑run actually does

systemd‑run spawns a transient unit (either a scope or a service) that inherits the caller’s privileges and then elevates them to root when you add --user or --scope with --user.
Unlike sudo, the unit vanishes as soon as the command finishes, and you can sprinkle a handful of systemd properties on it to tighten the environment.

[Read More]

How to Get a Systemd Timer Back on Track After a Kernel Upgrade

Systemd timers can fall silent after a kernel upgrade

When a new kernel lands, the kernel‑specific modules and initramfs changes can break the ExecStartPre or ExecStart scripts that a timer relies on.
The result? A timer that never fires, or that fires with the wrong environment.

Below is a step‑by‑step guide to diagnose and restore a broken timer, with security‑aware notes and trade‑offs you’ll run into in a production or homelab setup.

[Read More]

How to Extract a Single File from a Borg Backup Archive Without Recreating the Entire Directory Tree

Extracting a Single File from a Borg Archive Without Recreating the Entire Directory Tree

When a backup archive grows to several terabytes, restoring a single configuration file or a database dump can feel like pulling a needle from a haystack. Borg’s default extract command rebuilds the whole directory tree, which is wasteful when you only need one file. The following guide shows how to pull a single file efficiently, keeps metadata intact, and keeps your system secure.

[Read More]

Taming Duplicate Entries in Your Bash History with a Simple Script

Introduction to Bash History

As a long-time Linux user, I’ve come to rely on the command line to get my work done. The Bash shell is an incredibly powerful tool, and one of its most useful features is its ability to store a history of previously executed commands. This history is stored in the ~/.bash_history file and can be accessed using the history command. However, as our systems see more use, the Bash history can become cluttered with duplicate entries, making it tough to find the commands we need.

[Read More]