8 min read

How to Setup a Secure Ubuntu Home Server: A Complete Guide

Table of Contents

Setting up a home server can seem daunting, but with this blog post, you too can transform an old PC into a secure home server! This blog post will walk you through every step, from basic SSH setup to advanced security hardening.

Prerequisites

Before we begin, ensure you have:

  • A PC with Ubuntu Desktop installed (not Ubuntu Server, though the steps work similarly)
  • Basic command line familiarity
  • Administrative access to your home router
  • Another computer to test SSH connections

Quick Reference: Essential Commands

Here are some handy vim commands you might use throughout this guide. If you’re not familiar with vim, you can use any text editor of your choice.

  • Open remote files: vim scp://user@server//home/user/file.py
  • Open multiple files in tabs: vim -p file1.txt file2.txt (may need :tab all)

Step 1: Setting Up SSH Access

SSH (Secure Shell) is the foundation of remote server management. Let’s get it configured first.

Install and Enable OpenSSH Server

sudo apt install openssh-server
sudo systemctl enable ssh
sudo systemctl status ssh

Find Your Server’s IP Address

hostname -I

This will return something like 10.0.0.207 - note this down as we’ll use it throughout the guide.

Test SSH Connection

From your client computer, try connecting:

ssh user@10.0.0.207

You’ll need to enter your password at this point.

Set Up Key-Based Authentication

For better security and convenience, set up SSH key authentication:

ssh-copy-id user@10.0.0.207

After this, you should be able to SSH without entering a password.

Step 2: Configuring a Static IP Address

Dynamic IP addresses can change, which gets troublesome whenever you need to connect to your server. Let’s set up a static IP to avoid this.

Understanding Netplan

Ubuntu uses Netplan for network configuration. Navigate to the netplan directory:

cd /etc/netplan/
ls

You should see a file like 01-network-manager-all.yaml.

Create a Backup

Always backup before making changes:

sudo cp /etc/netplan/01-network-manager-all.yaml /etc/netplan/01-network-manager-all-BACKUP.yaml

Create Static IP Configuration

Create a new configuration file:

sudo vim /etc/netplan/static.yaml

Use this template (we’ll customize it next):

network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      addresses:
        - 10.10.10.2/24
      routes:
        - to: default
          via: 10.10.10.1
      nameservers:
          addresses: [1.1.1.1, 1.0.0.1]

Get Your Network Interface Information

Find your network interface name:

ifconfig -a

Look for something like enp42s0 (ignore the lo interface). You’ll also note your current IP address.

Customize the Configuration

Update your static.yaml file:

  1. Replace eth0 with your actual interface name (e.g., enp42s0)
  2. Set your desired static IP (e.g., 10.0.0.207/24)
  3. Set your router’s gateway (usually 10.0.0.1 for most home routers)
  4. Use Cloudflare’s DNS servers: [1.1.1.1, 1.0.0.1]

Apply the Configuration

Set proper permissions and apply:

sudo chmod 600 /etc/netplan/static.yaml
sudo netplan apply
sudo reboot

Test the connection from your client:

ssh user@10.0.0.207

Step 3: Hardening with UFW Firewall

UFW (Uncomplicated Firewall) provides an easy way to manage iptables rules.

Install and Enable UFW

sudo apt install ufw
sudo systemctl status ufw
sudo ufw enable

Set Default Policies

Start with a deny-all approach:

sudo ufw default deny incoming
sudo ufw default deny outgoing

Allow Essential Services

Open only the ports you need:

# Web traffic
sudo ufw allow 80,443/tcp
sudo ufw allow out 80,443/tcp

# SSH (we'll change this port later)
sudo ufw allow 22/tcp
sudo ufw allow out 22/tcp

# NTP for time synchronization
sudo ufw allow 123/udp
sudo ufw allow out 123/udp

# DNS resolution
sudo ufw allow in from any to any port 53
sudo ufw allow out from any to any port 53

Check Firewall Status

sudo ufw status numbered

You should see a comprehensive list of rules for both IPv4 and IPv6.

Step 4: Network Time Protocol (NTP) Setup

Accurate time is crucial for security certificates and log correlation.

Backup Current Configuration

sudo cp --archive /etc/systemd/timesyncd.conf /etc/systemd/timesyncd.conf-COPY-$(date +"%Y%m%d%H%M%S")

Configure NTP

Edit the configuration file:

sudo vim /etc/systemd/timesyncd.conf

Add these lines:

[Time]
NTP=0.pool.ntp.org 1.pool.ntp.org
FallbackNTP=ntp.ubuntu.com

Restart and Verify

sudo systemctl restart systemd-timesyncd
sudo systemctl status systemd-timesyncd

Set Your Timezone

Check current timezone:

timedatectl | grep Time

If needed, set it correctly:

sudo timedatectl set-timezone America/Vancouver

Step 5: Advanced SSH Security

Now let’s seriously harden SSH security.

Change SSH Port

First, allow the new port through UFW:

sudo ufw allow 2222/tcp
sudo ufw allow out 2222/tcp

Backup SSH Configuration

sudo cp --preserve /etc/ssh/sshd_config /etc/ssh/sshd_config.$(date +"%Y%m%d%H%M%S")

Apply Hardened SSH Configuration

Edit the SSH config:

sudo vim /etc/ssh/sshd_config

Delete everything (:%d in vim) and paste this hardened configuration:

# Supported HostKey algorithms by order of preference
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key

# Cryptographic settings
KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com

# Security settings
Port                            2222
LogLevel                        VERBOSE
Protocol                        2
PermitUserEnvironment           no
PermitRootLogin                 no
PubkeyAuthentication            yes
PasswordAuthentication          no
PermitEmptyPasswords            no
MaxAuthTries                    3
MaxSessions                     2
X11Forwarding                   no
IgnoreRhosts                    yes
UseDNS                          no
ClientAliveCountMax             0
ClientAliveInterval             300
AllowUsers                      YOUR_USERNAME  # CHANGE THIS!

# Disable port forwarding
AllowAgentForwarding            no
AllowTcpForwarding              no
AllowStreamLocalForwarding      no
GatewayPorts                    no
PermitTunnel                    no

# SFTP logging
Subsystem sftp  /usr/lib/openssh/sftp-server

# Additional security
Compression                     no
PrintMotd                       no
TCPKeepAlive                    no
ChallengeResponseAuthentication no
UsePAM                          yes
AcceptEnv LANG LC_*

Important: Replace YOUR_USERNAME with your actual username!

Restart SSH and Verify

sudo systemctl restart sshd
sudo ss -tlpn | grep ssh

You should see SSH listening on port 2222.

Test New SSH Configuration

From your client computer:

ssh -p 2222 user@10.0.0.207

Once you confirm the new port works, delete the old SSH port:

sudo ufw delete allow 22/tcp
sudo ufw delete allow out 22/tcp

Optional: Auto-logout After Inactivity

Add automatic logout after 5 minutes of inactivity:

echo 'TMOUT=300' >> ~/.bashrc

Strengthen SSH Keys

Remove weak moduli:

# Backup existing moduli file
sudo cp --archive /etc/ssh/moduli /etc/ssh/moduli-COPY-$(date +"%Y%m%d%H%M%S")

# Remove keys weaker than 3072 bits
sudo awk '$5 >= 3071' /etc/ssh/moduli | sudo tee /etc/ssh/moduli.tmp
sudo mv /etc/ssh/moduli.tmp /etc/ssh/moduli

Create a warning banner:

sudo vim /etc/issue.net

Add this message:

This system is for the use of authorised users only.

Individuals using this computer system without authority, or in excess of their authority, are subject to having all of their activities on this system monitored and recorded by system personnel.

In the course of monitoring individuals improperly using this system, or in the course of system maintenance, the activities of authorised users may also be monitored.

Anyone using this system expressly consents to such monitoring and is advised that if such monitoring reveals possible evidence of criminal activity, system personnel may provide the evidence of such monitoring to law enforcement officials.

Step 6: Git Configuration for Development

If you plan to use your server for development, configure Git properly.

Allow Git Port (Optional)

sudo ufw allow 9418/tcp

Configure Git for SSH

Instead of the standard GitHub SSH URL, use the HTTPS port for better firewall compatibility:

# Standard approach
git remote add origin git@github.com:username/repository.git

# Firewall-friendly approach
git remote add origin ssh://git@ssh.github.com:443/username/repository.git

Additional Security Considerations

Network-Level Restrictions

For maximum security, consider restricting SSH access to your local network only. You can modify UFW rules to only allow connections from your local subnet:

sudo ufw allow from 10.0.0.0/24 to any port 2222

Regular Maintenance

  • Keep your system updated: sudo apt update && sudo apt upgrade
  • Monitor SSH logs: sudo journalctl -u ssh
  • Review firewall logs: sudo ufw status verbose
  • Check for failed login attempts: sudo grep "Failed password" /var/log/auth.log

Conclusion

You now have a secure Ubuntu home server with:

  • ✅ SSH access with key-based authentication
  • ✅ Static IP configuration
  • ✅ Hardened firewall rules
  • ✅ Network time synchronization
  • ✅ Secure SSH configuration on a non-standard port
  • ✅ Git development capabilities

This setup provides a solid foundation for hosting services, running development environments, or managing home automation systems. Remember to regularly update your system and monitor logs for any suspicious activity.