Levi Zitting Logo

Stop Wasting Money on Virtual Servers

Demo 🎉

social.sgf.dev

Networking Basics

  • IP Addresses
  • DNS
  • Ports
  • NAT
  • VPN
  • Reverse Proxies

IP (Internet Protocol) Addresses

Numeric labels used to identify devices on a network. For example 192.168.1.2

  • Anytime data is sent on the network it's to an IP Address
  • Not tightly coupled to the device
    • Can be reassigned to a different device

DNS (Domain Name System)

A system that allows computers to convert human friendly names (e.g. sgf.dev) into an IP address

Essentially the phonebook of a network

Types: A, CNAME

Ports

Used to identify a specific protocol or application to communicate with

Some common protocols
and ports

  • HTTP - 80
  • HTTPS - 443
  • SSH - 20

Senders specify a reply port when sending packets

NAT (Network Address Translation)

Allows a network to share an IP when communicating with another network

Rewrites outgoing packets to use the shared address + a unique port for the reply address

Uses a table of those rewrites to do the inverse for incoming packets

A Naive Approach

Port Forwarding

Allows incoming traffic on a port to be forwarded to a specific device on the network

  • Needs to be supported by your NAT device (router)
  • Your ISP may explicitly block this feature
  • Your ISP may give your NAT device a different IP at any time

Dynamic DNS

Uses an agent on a device in your network to detect public IP changes

When a change is detected, it dynamically updates a DNS record

Why Is This Naive?

  • May be blocked by your ISP
  • Exposes your home IP to the public
    • This can be mitigated with something like Cloudflare
  • Is likely against your ISPs TOS
    • And could be trivially detected

More Networking Concepts

Proxy

A server that forwards traffic from a client on to a destination

Hides the true client from the server

Reverse Proxy

A server that takes incoming traffic and forwards it to another server

Hides the true server from the client

VPN (Virtual Private Network)

Creates a secure tunnel to a VPN server that all traffic flows to first

In practice this means

  • Packets are encrypted on device
  • They are then sent to the VPN server
  • The VPN server decrypts the packets
  • And then forwards them on to real destination

VPN Part 2

Allows machines physically apart to be on the same "virtual" network

A Diagram of a VPN showing multiple physical locations

So What's the Better Way?

Well... you cheat a bit

You pay for a virtual server

A network diagram

What Kind of Server?

  • Physically close with low latency
    • Most hosting companies have a "looking glass" tool for testing
  • Low spec and cheap
  • Includes IPV4

WireGuard

Server Setup


sudo apt install wireguard

# If you have a firewall (which you should)
sudo ufw allow 51820/udp
sudo ufw enable

sudo su
cd /etc/wireguard
wg genkey | tee privatekey | wg pubkey > publickey

vim ./wg0.conf
        

Server Setup Part 2


[Interface]
Address = 10.0.0.x/24
SaveConfig = true
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o enp1s0 -j MASQUERADE; iptables -A FORWARD -o %i -j ACCEPT
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o enp1s0 -j MASQUERADE; iptables -D FORWARD -o %i -j ACCEPT
ListenPort = 51820
PrivateKey = <generated private key>
        

exit # exit super user session
sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0
        

Client Setup


sudo apt install wireguard

sudo su
cd /etc/wireguard
wg genkey | tee privatekey | wg pubkey > publickey

vim ./wg0.conf
        

Client Setup Part 2


[Interface]
PrivateKey = <generated client private key>
Address = 10.0.0.x/24
DNS = 1.1.1.1

[Peer]
PublicKey = <server public key>
AllowedIPs = 0.0.0.0/0
Endpoint = <server ip>:51820
PersistentKeepalive = 10
        

exit # exit super user session
sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0
        

Register Client with Server


sudo systemctl stop wg-quick@wg0
sudo vim /etc/wireguard/wg0.conf
        

[Peer]
PublicKey = <client public key>
AllowedIPs = 10.0.0.x/32
        

sudo systemctl start wg-quick@wg0
        

Docker & Docker Compose

Docker

Essentially provides lightweight virtual machines* called containers

*they're definitely not virtual machines but it's easier to describe that way

**if this description upsets you sorry not sorry 😎

These containers can be easily created and destroyed using the docker cli

Containers also typically have all their dependencies included

Docker Compose

Allows you to spin up many containers at once using a config file
For example creating a web app and it's database at the same time

Caddy

What Is It?

Caddy is a very easy to use reverse proxy server

Has comparable features to others such as Nginx or HaProxy

It can seamlessly generate SSL certificates and keep them updated

Caddy Setup (Docker Compose)


services:
  reverse-proxy:
    image: caddy:latest
    restart: always
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
      - "2019:2019"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
      - caddy_config:/config

volumes:
  caddy_data:
  caddy_config:
        

Caddy Setup (Caddyfile)


https://social.sgf.dev {
	reverse_proxy 10.0.0.3:9000
}
        

Backups

Backblaze

Provides very cheap S3 compatible storage. Excellent for storing backups

Screenshot of Backblaze pricing page

Restic

A tool for creating and uploading backups to a remote location. It supports:

  • Incremental backups with data deduplication
  • Restore to any snapshot
  • Encrypting your backups at rest
  • Several backends to upload backups to

Restic Part 2

Supports a variety of remote locations

  • SFTP
  • REST Server
  • AWS S3
    • And S3 compatible vendors (like Backblaze)
  • Azure Blob Storage
  • Google Cloud Storage
  • Many others using rclone

Restic Usage


sudo apt install restic

export RESTIC_PASSWORD='your_password_here'
export AWS_ACCESS_KEY_ID=''
export AWS_SECRET_ACCESS_KEY=''

restic -r s3:<backblaze url> init

restic -r s3:<backblaze url> backup ./<some folder>

restic -r s3:<backblaze url> restore latest --target ./
        

Demo 2 🎉

github.com/sgfdevs/mastodon

Wrap Up

Things You Probably Shouldn't Self Host

  • Email servers
  • Anything touching payments
  • Game servers
  • Most real world things

Disclaimers

  • This was not legal advice
    • Don't blame me if your ISP shuts you down
  • Putting things on the internet is always risky
    • Plan accordingly
    • E.g. tighten your home networks security

Questions?