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 sshFind Your Server’s IP Address
hostname -IThis 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 [email protected]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 [email protected]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/ lsYou 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.yamlCreate Static IP Configuration
Create a new configuration file:
sudo vim /etc/netplan/static.yamlUse 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 -aLook for something like enp42s0 (ignore the lo interface). You’ll also note your current IP address.
Customize the Configuration
Update your static.yaml file:
- Replace eth0 with your actual interface name (e.g., enp42s0)
- Set your desired static IP (e.g., 10.0.0.207/24)
- Set your router’s gateway (usually 10.0.0.1 for most home routers)
- 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 rebootTest the connection from your client:
ssh [email protected]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 enableSet Default Policies
Start with a deny-all approach:
sudo ufw default deny incoming sudo ufw default deny outgoingAllow 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 53Check Firewall Status
sudo ufw status numberedYou 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.confAdd these lines:
[Time] NTP=0.pool.ntp.org 1.pool.ntp.org FallbackNTP=ntp.ubuntu.comRestart and Verify
sudo systemctl restart systemd-timesyncd sudo systemctl status systemd-timesyncdSet Your Timezone
Check current timezone:
timedatectl | grep TimeIf needed, set it correctly:
sudo timedatectl set-timezone America/VancouverStep 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/tcpBackup 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_configDelete 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 [email protected],ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256 Ciphers [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr MACs [email protected],[email protected],[email protected],hmac-sha2-512,hmac-sha2-256,[email protected] # 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 sshYou should see SSH listening on port 2222.
Test New SSH Configuration
From your client computer:
ssh -p 2222 [email protected]Once you confirm the new port works, delete the old SSH port:
sudo ufw delete allow 22/tcp sudo ufw delete allow out 22/tcpOptional: Auto-logout After Inactivity
Add automatic logout after 5 minutes of inactivity:
echo 'TMOUT=300' >> ~/.bashrcStrengthen 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/moduliCreate a warning banner:
sudo vim /etc/issue.netAdd 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/tcpConfigure Git for SSH
Instead of the standard GitHub SSH URL, use the HTTPS port for better firewall compatibility:
# Standard approach git remote add origin [email protected]:username/repository.git # Firewall-friendly approach git remote add origin ssh://[email protected]:443/username/repository.gitAdditional 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 2222Regular 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.