Skip to content

Homelab Server Setup

This page describes how I setup my personal webserver

I'm hosting a website, wiki, caldav using Radicale, git using cgit and Gitolite, and webdav support

Linux Distribution Used

Debian 12 Bookworm.

Update the system.

# apt update
# apt upgrade

SSH

Generate ssh keys

ssh-keygen -t [keytype]

Add ssh keys to ~/.ssh/authorized_keys

ssh-copy-id -i /path/to/pubkey [user@]machine

Optional security enhancements

Change the port in /etc/sshd_config to a nonstandard port to harden security.

Port 1234

Disable password login in /etc/sshd_config/

PubkeyAuthentication yes
ChallengeResponseAuthentication no
PasswordAuthentication no
KbdInteractiveAuthentication no
UsePAM no

Disable XForwarding

X11Forwarding no

Disable remote root login

PermitRootLogin no

Disable root account

$ sudo chsh -s /sbin/nologin root

DDNS

Setup Dyanmic DNS (ddns) with Porkbun and ddns-updater.

Caddy

Install the Caddy package from Caddy directly.

Cgit & gitolite

Setup cgit with gitolite and caddy.

Radicale

Install the Radicale package.

Start the Radicale service.

systemctl enable radicale.service
systemctl start radicale.service

Generate secure passwords using htpasswd.

# Create a new htpasswd file with the user "user1"
$ htpasswd -c /path/to/users user1
New password:
Re-type new password:
# Add another user
$ htpasswd /path/to/users user2
New password:
Re-type new password:

Edit configuration to add users

[auth]
type = htpasswd
htpasswd_filename = /path/to/users
# encryption method used in the htpasswd file
htpasswd_encryption = md5

Add configuration to caddy.

caldav.joshuayun.com {
    handle_path /* {
        reverse_proxy localhost:5232 {
        header_up X-Script-Name /radicale
        }
    }
    handle_path /radicale/* {
        reverse_proxy localhost:5232 {
            header_up X-Script-Name /radicale
        }
    }
}

Webdav

Add the Webdav module to Caddy.

sudo caddy add-package github.com/mholt/caddy-webdav
sudo systemctl restart caddy

Add Webdav to the Caddy configuration

Example configuration with protected file browsing, see the github for more configurations.

webdav.joshuayun.com {
    @get method GET
    root * WEBDAV_PATH
    route {
        basicauth {
            joshua CADDY_HASH
        }
        file_server @get browse
        webdav
    }
}

To generate the hash:

caddy hash-password