Homelab 1: Cloudflare Tunnel
About project
I have been contemplating the idea of setting up a homelab for quite some time now. As my current VPS subscription is about to expire, I am in need of a dedicated space where I can freely experiment, explore different technologies, and host small projects. Coincidentally, I recently came across Cloudflare Tunnel technology, which allows me to establish a home server even with a dynamic IP provided by my ISP.
Hardware
For my hardware selection, I have decided on the HP EliteDesk 800 G2 Mini Desktop. With an Intel Core i5-6500T running at 3.2 GHz, 16GB of RAM, and a 256GB SSD, I believe this setup will adequately meet my exploratory requirements.
OS
After successfully installing Ubuntu Server 22.04 LTS, I found that most of the installation process was straightforward, requiring only a few clicks of the “Next” button. However, there is one crucial step that requires attention. By default, Ubuntu allocates only half of the available storage space, so it is necessary to adjust the “Storage configuration” in order to utilize the entire disk capacity. Here is a quick explanation how to configure
ssh
First I installed ssh server.
sudo apt update
sudo apt install openssh-server
sudo apt install openssh-client
I can check ssh status.
sudo systemctl status ssh
# ● ssh.service - OpenBSD Secure Shell server
# Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
# Active: active (running) since Tue 2023-05-23 09:25:17 UTC; 1 day 3h ago
# Docs: man:sshd(8)
# man:sshd_config(5)
# Process: 737 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
# Main PID: 780 (sshd)
# Tasks: 1 (limit: 18921)
# Memory: 7.5M
# CPU: 365ms
# CGroup: /system.slice/ssh.service
# └─780 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"
Configuring Uncomplicated FireWall (ufw)
sudo ufw allow ssh
sudo ufw enable
sudo ufw status
# Status: active
# To Action From
# -- ------ ----
# 22/tcp ALLOW Anywhere
# 22/tcp (v6) ALLOW Anywhere (v6)
Connect to the server via ssh. First time I will connect from local network.
# ssh [server-username] [ip-address or domain]
ssh [email protected]
Default configuration using username/password. I will use the user public key instead of the username and password. To do so first I will generate ssh key on the remote machine.
ssh-keygen -t ed25519 -C "<comment>"
Do not enter passphrase when prompted. The private and public keys (id_ed25519 and id_ed25519.pub) will be generated in ~/.ssh/
folder.
Next, I will copy the remote machine public key id_ed25519.pub
line to server ~/.ssh/authorized_keys
file.
Test login
# ssh [server-username] [ip-address or domain]
ssh -o PreferredAuthentications=publickey [email protected]
If all ok disabled password authentification. Create configuration file
cd /etc/ssh/sshd_config.d/
sudo touch disable_root_login.conf
sudo nano disable_root_login.conf
Enter and save
ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM yes
PermitRootLogin no
Reload configuration
sudo systemctl reload ssh
sudo systemctl reload sshd
Verify login. This time you should not receive a password prompt.
# ssh [server-username] [ip-address or domain]
ssh [email protected]
Test if you can ssh to localhost. If you receive an error then on the server you have to generate ssh key and add to the servers ~/.ssh/authorized_keys
ssh localhost
Docker
Install docker as per documentation and Doing Linux post-install steps for Docker Engine
To enable docker swarm run the following command.
docker swarm init
Now we ready to proceed with Cloudflare
Cloudflare Tunel
You will need domain name pointed to Cloudflare name servers. Assuming successfully added domain to Cloudflare.
Launch Zero trust dashbard.
Give tunel name
I will use docker Cloudflate Connector
Cloudflate Connector
Create new docker overlay network
docker network create --driver overlay --attachable project
Create docker-compose.tunnel.yml
file with content
version: "3.9"
services:
tunnel:
image: cloudflare/cloudflared:latest
command: tunnel --no-autoupdate run
env_file: tunnel.env
extra_hosts:
- "host.docker.internal:host-gateway"
networks:
- project
deploy:
replicas: 1
placement:
constraints:
- node.role == manager
restart_policy:
condition: any
networks:
project:
external: true
and tunnel.env
TUNNEL_TOKEN=<PASTE_TOKEN_HERE>
Replace token value with token value from Cloudflare page bellow.
Deploy tunnel If the installation is successful you should see the new connector under the connectors list.
Swarmpit
Install first application. In my case tool for basic docker swarm monitoring.
Create docker-compose.swarmpit.yml
file with content
version: "3.3"
services:
app:
image: swarmpit/swarmpit:latest
environment:
- SWARMPIT_DB=http://db:5984
- SWARMPIT_INFLUXDB=http://influxdb:8086
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080"]
interval: 60s
timeout: 10s
retries: 3
networks:
- net
- project
deploy:
resources:
limits:
cpus: "0.50"
memory: 1024M
reservations:
cpus: "0.25"
memory: 512M
placement:
constraints:
- node.role == manager
db:
image: couchdb:2.3.0
volumes:
- db-data:/opt/couchdb/data
networks:
- net
deploy:
resources:
limits:
cpus: "0.30"
memory: 256M
reservations:
cpus: "0.15"
memory: 128M
influxdb:
image: influxdb:1.8
volumes:
- influx-data:/var/lib/influxdb
networks:
- net
deploy:
resources:
limits:
cpus: "0.60"
memory: 512M
reservations:
cpus: "0.30"
memory: 128M
agent:
image: swarmpit/agent:latest
environment:
- DOCKER_API_VERSION=1.35
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- net
deploy:
mode: global
labels:
swarmpit.agent: "true"
resources:
limits:
cpus: "0.10"
memory: 64M
reservations:
cpus: "0.05"
memory: 32M
networks:
net:
driver: overlay
project:
external:
name: project
volumes:
db-data:
driver: local
influx-data:
driver: local
Rout your subdomain to docker swarm service http://swarmpit_app.8080
Check if now you can access swarm pit from https://swarmpit.<your_domain>
. Most likely you want secure access to this service therefore do following steps
ssh access from the internet
Rout your https://ssh.<your_domain>
subdomain to ssh server
Install Cloudflared on remote machine. In my case section Ubuntu 22.04 LTS (Jammy Jellyfish)
Update remote mashine ssh configuration file under ~/.ssh/config
.
Add following values
Host ssh.<your_domain>
ProxyCommand /usr/local/bin/cloudflared access ssh --hostname %h
You can now test the connection by running a command to reach the service.
ssh <username>@ssh.<your_domain>
Now you have the first running service on home server and can access it remotely.