Build Your Own Raspberry Pi Homelab
Learn what a homelab is, why Raspberry Pi is perfect for it, and how to set up the OS for future projects.
Introduction
A homelab is basically your own little playground for experimenting with tech. It’s a space where you can run servers, test new tools, and learn without worrying about breaking anything important. It might sound advanced, but the truth is anyone can set one up at home.
That’s where the Raspberry Pi comes in: it’s cheap, tiny, and powerful enough for tons of projects. In this blog, you’ll see why it’s perfect for building your homelab and how to get started by installing the operating system, the first step before running servers, containers, or whatever cool ideas you want to try.
Prerequisites
Before jumping into the setup, let’s go over the essentials you’ll need for your Raspberry Pi homelab. Some items are mandatory, while others are just nice to have but will make your life a lot easier.
Must-have gear:
- A Raspberry Pi board (or multiple, if you want to scale up later)
- A reliable power supply
- microSD cards (at least one per Pi, recommended Class 10 or better)
- Ethernet cables
Optional but highly recommended:
- A stacking case to keep your Pis organized (mine even came with fans for cooling)
- A micro-HDMI to HDMI cable for emergency troubleshooting
- A network switch to connect everything neatly
Installation steps
Flash the SD card
The journey starts with installing an operating system on your Raspberry Pi, and for this we’ll use Raspberry Pi Imager. While many people associate it with flashing Raspbian, the Imager actually gives you more flexibility: you can pick from a variety of official images, including Ubuntu Server 24.04 LTS, which is the one we’ll be using throughout this guide.
One of the nicest features of Raspberry Pi Imager is the advanced options menu. Here you can save yourself a lot of post-install hassle. Here you can set your own username and password, the hostname, and even configure SSH access with your public key right away. This means password logins are disabled from the very first boot, giving you a more secure setup without editing any files manually.
Once the SD card is written and you boot up your Pi from your main computer, just connect with SSH:
ssh username@<address/hostname>Enable your user in sudoers
The account you created with Raspberry Pi Imager is already more secure than the defaults, but right now it doesn’t necessarily have permission to perform administrative tasks. In Ubuntu, those privileges are managed through the sudo group. Any user that belongs to this group can install software, change system settings, and perform updates, all the essential things you’ll need for running your homelab.
To give your account those powers, just add it to the group with:
sudo usermod -aG sudo $USERFrom now on, you’ll be able to run admin commands simply by prefixing them with sudo.
Set up UFW
Ubuntu already comes with UFW (Uncomplicated Firewall), so we don’t need to install it. What we’ll do instead is reset its rules to start from a clean slate and set some sensible defaults:
sudo ufw --force reset
sudo ufw default deny incoming
sudo ufw default allow outgoingNext, allow SSH so you don’t get locked out. We’ll also add a simple rate limit to slow down brute-force attempts:
sudo ufw limit ssh
sudo ufw allow OpenSSHSince we’re sticking with IPv4 in this guide, we’ll disable IPv6 support in UFW’s config:
sudo sed -i 's/IPV6=.*/IPV6=no/' /etc/default/ufwFinally, enable the firewall and check its status:
sudo ufw --force enable
sudo ufw status verboseAt this point, your Raspberry Pi only accepts SSH connections while blocking everything else by default.
Hardening
With your firewall in place, the next step is to harden SSH and add an extra layer of protection with Fail2Ban. This makes sure your Raspberry Pi isn’t left open to brute-force attempts or weak defaults.
Before editing, it’s always a good idea to make a backup of the original configuration file, so you can roll back if something goes wrong:
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%F-%H%M%S)Now update your SSH configuration with stricter rules and some extra limitations to reduce the attack surface:
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
# This sshd was compiled with PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options override the
# default value.
Include /etc/ssh/sshd_config.d/*.conf
+ Protocol 2
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
#HostKey /etc/ssh/ssh_host_ed25519_key
# Ciphers and keying
#RekeyLimit default none
# Logging
#SyslogFacility AUTH
- #LogLevel INFO
+ LogLevel VERBOSE
# Authentication:
#LoginGraceTime 2m
- #PermitRootLogin prohibit-password
+ PermitRootLogin no
#StrictModes yes
- #MaxAuthTries 6
- #MaxSessions 10
+ MaxAuthTries 3
+ MaxSessions 5
- #PubkeyAuthentication yes
+ PubkeyAuthentication yes
# Expect .ssh/authorized_keys2 to be disregarded by default in future.
#AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2
#AuthorizedPrincipalsFile none
#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
- #HostbasedAuthentication no
+ HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes
# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication no
- #PermitEmptyPasswords no
+ PermitEmptyPasswords no
# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
KbdInteractiveAuthentication no
# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the KbdInteractiveAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via KbdInteractiveAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and KbdInteractiveAuthentication to 'no'.
UsePAM yes
#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
- X11Forwarding yes
+ X11Forwarding no
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
PrintMotd no
#PrintLastLog yes
#TCPKeepAlive yes
#PermitUserEnvironment no
#Compression delayed
- #ClientAliveInterval 0
- #ClientAliveCountMax 3
+ ClientAliveInterval 600
+ ClientAliveCountMax 0
#UseDNS no
#PidFile /run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none
# no default banner path
#Banner none
# Allow client to pass locale environment variables
AcceptEnv LANG LC_*
# override default of no subsystems
Subsystem sftp /usr/lib/openssh/sftp-server
# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding no
# PermitTTY no
# ForceCommand cvs server
+ AllowUsers hector
# --- LAN policy: allow password OR public key for hector ---
+ Match Address 192.168.1.0/24 User hector
+ PasswordAuthentication yes
+ PubkeyAuthentication yes
# Note: no AuthenticationMethods here, so either method is accepted on LAN.
# --- External policy: keys only ---
+ Match Address *
+ PasswordAuthentication no
+ PubkeyAuthentication yesAfter saving the file, restart the SSH service so the new settings take effect:
sudo systemctl restart sshNext, let’s configure Fail2Ban. This tool monitors authentication logs and automatically blocks IPs that trigger too many failed login attempts. First, install it:
sudo apt-get install -y fail2banBefore making changes, create a backup of the default configuration file:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.conf.bak.$(date +%F-%H%M%S)Now edit the original jail.conf and update the SSH section to enable it and make it more aggressive:
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
+ bantime = 4w
+ maxretry = 3Finally, enable and restart the service so it runs on every boot:
sudo systemctl enable fail2ban
sudo systemctl restart fail2banAt this point, SSH is locked down to your user and your LAN, external access is key-only, and Fail2Ban will automatically quarantine any brute-force attempts for weeks.
Network configuration
The last step in preparing your Raspberry Pi for homelab use is making sure the network setup is stable and predictable. By default, Ubuntu uses cloud-init to manage things like /etc/hosts and network settings, but for a homelab we’ll want more control. We’ll also disable IPv6 (since we’re sticking with IPv4 here) and give the Pi a static IP so it’s always reachable.
First, tell cloud-init to stop managing the hosts file by changing this line:
- manage_etc_hosts: true
+ manage_etc_hosts: falseNext, disable IPv6 system-wide by adding these lines:
+ net.ipv6.conf.all.disable_ipv6 = 1
+ net.ipv6.conf.default.disable_ipv6 = 1
+ net.ipv6.conf.lo.disable_ipv6 = 1Then reload the settings so they take effect:
sudo sysctl -pNow clean up your hosts file so it reflects your Pi’s static IP and hostname:
sudo nano /etc/hostsReplace the contents with something like this (adjust to your setup):
127.0.0.1 localhost
192.168.1.50 rpi-homelab-01Finally, configure a static IP with Netplan. The file name may vary (e.g., 50-cloud-init.yaml), but here’s an example you can adapt to your setup:
network:
version: 2
renderer: networkd
ethernets:
eth0:
addresses: [192.168.1.50/24]
gateway4: 192.168.1.1
nameservers:
addresses: [1.1.1.1, 8.8.8.8]Apply the changes:
sudo netplan applyConclusion
With these five steps, your Raspberry Pi is no longer just a small single-board computer, it’s now a secure and reliable entry point for your homelab. You’ve installed Ubuntu Server LTS, set up a proper user with admin rights, locked down SSH, added a firewall, hardened the system with Fail2Ban, and configured a static network setup. From here, you have a solid foundation to start experimenting with services like Docker, Kubernetes, or self-hosted apps. The best part is that you built everything yourself, step by step, and now you’re ready to expand your homelab with confidence.
References
- Raspberry Pi Imager – Official documentation
- Ubuntu Server for Raspberry Pi – Ubuntu Docs
- Ubuntu – Sudoers (Community Help Wiki)
- UFW (Uncomplicated Firewall) – Ubuntu Community Help Wiki
- OpenSSH Server Configuration – Ubuntu Docs
- Fail2Ban – Official Documentation
- Cloud-init – Official Documentation
- Netplan – Official Docs