Skip to content

Latest commit

 

History

History
332 lines (223 loc) · 7.57 KB

README.md

File metadata and controls

332 lines (223 loc) · 7.57 KB

AtHome

A comprehensive home server setup using Docker, designed for running self-hosted services with security and ease of management in mind.

🎯 Overview

AtHome provides a ready-to-deploy home server infrastructure with:

  • 🔒 Secure reverse proxy (Traefik)
  • 🎯 Network-wide ad blocking (Pi-hole)
  • 🐳 Container management UI (Portainer)
  • 🔐 Automated SSL certificate management
  • 🌐 Custom local domain (.at.home)

🚀 Features

  • Security First: Hardened SSH configuration, UFW firewall setup, and SSL encryption
  • Easy Management: Web-based container management through Portainer
  • Ad Blocking: Network-wide ad blocking and custom DNS management with Pi-Hole
  • Automated: Certificate renewal and container updates
  • Customizable: Easy to extend with additional services

📋 Software Stack

  • Ubuntu Server v20.04.3
  • Docker v20.10.12
  • Docker Compose v2.2.3
  • Traefik v2.6.0
  • Portainer CE v2.11.1

System Configuration

Hardware: Asus Chromebox 3 Firmware: MrChromebox.tech Operating System: Ubuntu Server 20.04.3 Networking: Ethernet Admin User: mislam SSH Login Key: ed25519.pub

Local Domains

  • Router: router.at.home
  • Traefik: traefik.at.home
  • Portainer: portainer.at.home

Network Topology

Install

Update

sudo apt update && sudo apt upgrade -y

Network Interface

Make sure you are using ethernet interface with static IP address:

sudo nano /etc/netplan/00-installer-config.yaml

It should look this:

network:
  ethernets:
    eno0:
      addresses:
      - 192.168.0.253/24
      gateway4: 192.168.0.254
      nameservers:
        addresses:
        - 1.1.1.1
  version: 2

Now reboot:

sudo reboot

Configure UFW

Set the defaults to deny incoming and allow outgoing connections.

sudo ufw default deny incoming
sudo ufw default allow outgoing

Configure SSH

SSH into the server and edit the SSH config:

sudo nano /etc/ssh/sshd_config

Add the following line above #Port 22:

Protocol 2

Change the following lines as follows:

Port XXXX
PermitRootLogin no
MaxAuthTries 3
PasswordAuthentication no
PermitEmptyPasswords no
ClientAliveInterval 300

Replace XXXX with a port number that is hard to guess.

And add the following line after #MaxSessions:

AllowUsers mislam

Save and exit the config file, and restart the SSH server:

sudo service sshd reload

Finally set UFW to allow the SSH port:

sudo ufw allow 9022

Disable Terminal Login

Disable automatic spawning of virtual terminals:

sudo nnao /etc/systemd/logind.conf

Change the followings:

NAutoVTs=0
ReserveVT=0

Disable [email protected] and reboot:

systemctl disable [email protected]
sudo reboot

Next time the server boots, it will no longer prompt for login.

Install Docker

sudo apt install ca-certificates curl gnupg lsb-release -y
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io -y

By default, only root and user with sudo privileges can execute Docker commands. To execute Docker commands as non-root user, add your user to the docker group:

sudo usermod -aG docker $USER

Install Docker Compose v2

Download and install the latest release from GitHub:

mkdir -p ~/.docker/cli-plugins/
curl -SL https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose
chmod +x ~/.docker/cli-plugins/docker-compose

Get this Repo

git clone https://gitlab.com/mislam/athome.git ~/.athome && cd $_

SSL Certificate

Generate new root CA and server certificate:

bin/mkcert -new

It will generate a root CA (for 100 years) and server certificate (for 31 days) and sets a cron job to renew the server certificate every month.

Run the following command from a Mac to download the CA certificate, and add it to Mac's keychain:

scp server_hostname:~/.athome/certs/ca.crt . && sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ca.crt && rm ca.crt

Note: Here server_hostname is the hostname of the server machine. And we assume that there is a SSH config file on the Mac at ~/.ssh/config with the following lines:

Host server_hostname
  Hostname xxx.xxx.x.x
  Port xxxx
  User server_admin_username
  IdentityFile ~/.ssh/id_ed25519

If you want to delete the certificate from the keychain, simply run:

sudo security delete-certificate -c "AtHome CA" /Library/Keychains/System.keychain

Basic Auth

Install htpasswd:

sudo apt install apache2-utils

You will not be able to write your password as it is, you first need to generate a hash of your password:

sed -i s#USER:PASSWORD#$(htpasswd -nbB MYUSER MYPASSWORD)# config/traefik/dynamic.yml

Replace MYUSER and MYPASSWORD with your own credentials you would like to use for Traefik Dashboard. This sed command will replace USER:PASSWORD in the dynamic.yml file with something like this:

USER:$apr1$GTSSKUUa$K1XULJfw9tbdikiJPBpQm1

DNS Config

Ubuntu includes systemd-resolved which is configured by default to implement a caching DNS stub resolver. This will prevent pi-hole from listening on port 53. The stub resolver should be disabled with:

sudo sed -r -i.orig 's/#?DNSStubListener=yes/DNSStubListener=no/g' /etc/systemd/resolved.conf

This will not change the nameserver settings, which point to the stub resolver thus preventing DNS resolution. Change the /etc/resolv.conf symlink to point to /run/systemd/resolve/resolv.conf, which is automatically updated to follow the system's netplan:

sudo sh -c 'rm /etc/resolv.conf && ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf'

After making these changes, you should restart systemd-resolved:

sudo systemctl restart systemd-resolved

Install the Full Stack

Run:

docker compose up -d

Configure Pi-Hole

Change Pi-Hole login password:

docker exec -d pihole pihole -a -p MY_PIHOLE_PASSWD

Login to the Pi-Hole Web UI and add the following two domains to the blacklist:

sonx.mediasearch.verizon.com

and

(\.|^)(youtube|googlevideo|ytimg|youtube-ui\.l\.google|ytimg\.l\.google|ytstatic\.l\.google|youtubei\.googleapis)\.com$

Some Helpful Tips

Find all listening TCP ports:

sudo lsof -nP -iTCP -sTCP:LISTEN

Important Tips

After running docker compose up, if you need to make changes in the docker-compose.yml, make sure to run docker compose down before make any change to the YML file. Otherwise it will cause unpredictable issues and headaches.

References

IP Subnet Calculator:

How to generate SSL certificate:

DNS over HTTPS:

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

📝 License

This project is licensed under the MIT License - see the LICENSE file for details.

⚠️ Disclaimer

This project is provided as-is. Please ensure you understand the security implications of running these services on your network.