I spend a lot of the summer at my parents house in Hamar. They have finally gotten a proper internet connection after many years of dodgy radio wan. 1G/1G fiber all the way! I asked an old friend if he had a old cheap NUC or Raspberry Pi laying around. I lucked out, and was soon on my way with a old Intel Nuc. I bought a 2TB ssd and got to thinking.. What is the best way to set this up?

Connecting home

Som quick facts:

  • The NUC is connected directly to the router with cable.
  • WAN connection is dynamic IP address.
  • They got a WAN IP address, no carrier grade NAT shenanigans.
  • Port forwarding is possible on the router.

I have to options in mind:

  1. A wireguard tunnel back to my server.
  2. Portforwarding and dyndns.

pro's and cons.

OptionProsCons
Option 1No need to portforward.If I lose my Wireguard, I'm not able to get in.
Resilient to changing routers.All hosts that want to back up have to be connected with Wireguard.
Better security.
Option 2Can reach from everywhere.Loose connection if they swap routers.
Not relying on Wireguard setup at my place.Less security.

Optimal route

The optimal way of doing this might be to use ssh with ssh keys and TFA on ddns, and use wireguard for the backups. This would have given the option to login to the server, even if Wireguard for some reason went down. I want to be able to backup from everywhere without setting up VPN, so I went with just the port-forwarding. YOLO, right?

Set up

I went with Alma linux 9, but this should work on all rpm based distros.

DDNS

I want to use podman with ddclient and cloudflare. Create a Cloudflare API token for the zone here. You should also create a subdomain for your host. Remember to change out fyksen.me with your domain, and YourTokenCode with the token you got from cloudflare.

# Enable linger:
sudo loginctl enable-linger $USER

# Create folder structure:
cd
mkdir -p .config/systemd/user/
mkdir -p container_files/ddclient/

# Add config to ddclient.conf:
cat <<EOL > $HOME/container_files/ddclient/ddclient.conf

daemon=300 # check every 300 seconds
pid=/var/run/ddclient.pid # record PID in file
ssl=yes # use TLS
use=web # get IP with website below
web='https://cloudflare.com/cdn-cgi/trace'
web-skip='ip=' # IP address above is after 'ip='

protocol=cloudflare, \
zone=fyksen.me, \
ttl=1,
password='<YourTokenCode>',
subdomain.fyksen.me, subdomain2.fyksen.me, subdomain3.fyksen.me
EOL

# Create the .service file for ddclient:
cat <<EOL > $HOME/.config/systemd/user/container-ddclient.service
# container-ddclient.service
# autogenerated by Podman 4.4.1
# Thu Jul 20 21:44:23 CEST 2023

[Unit]
Description=Podman container-ddclient.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=%t/containers

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=always
TimeoutStopSec=70
ExecStart=/usr/bin/podman run \\
	--cidfile=%t/%n.ctr-id \\
	--cgroups=no-conmon \\
	--rm \\
	--sdnotify=conmon \\
	-d \\
	--replace \\
	--name=ddclient \\
	-e TZ=Europe/Oslo \\
	-e PUID=0 \\
	-e PGID=0 \\
	-v /home/$USER/container_files/ddclient:/config:Z lscr.io/linuxserver/ddclient:latest
ExecStop=/usr/bin/podman stop \\
	--ignore -t 10 \\
	--cidfile=%t/%n.ctr-id
ExecStopPost=/usr/bin/podman rm \\
	-f \\
	--ignore -t 10 \\
	--cidfile=%t/%n.ctr-id
Type=notify
NotifyAccess=all

[Install]
WantedBy=default.target
EOL

# daemon reload, start and enable service
systemctl --user enable --now container-ddclient.service 

Fail2ban ssh

This will install epel-release, and fail2ban. Then configure and start fail2ban.

# Install packages
sudo dnf install -y epel-release
sudo dnf install -y fail2ban

sudo cat <<EOL > /etc/fail2ban/jail.local
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 600
bantime = 3600
EOL

sudo systemctl restart fail2ban.service
sudo systemctl enable fail2ban.service

Check the setup with.

sudo fail2ban-client status

and

sudo fail2ban-client status sshd

Borgmatic

  • Server = this box
  • Client = the client that you are backing up.

Host:

# Create the user borg, and set directory for it's home
# This wil also set the correct selinux properties on the dir.
sudo useradd -m -d /var/backup/borg borg
# Install borg backup
sudo dnf install  -y borgbackup
# Create ssh dir
sudo su - borg
mkdir .ssh
chmod 700 .ssh
touch .ssh/authorized_keys

Now you are reade to add you public keys from the client in the .ssh/authorized_keys. You should also create directories inside /var/backup/borg that corresponds to your borgmatic config.

sudo su - borg
mkdir all-the-things