Quick-How-Tos

Setting Up a HamCloud WireGuard VPN Gateway on a VM

As a tech or cybersecurity enthusiast, you might be running a homelab to experiment with various technologies and enhance your skills. If you do, or if you are capable of maintaining a 24/7 VM (or even a physical server), this guide will help you set up a HamCloud WireGuard VPN gateway. This setup can even be done on a single-board computer (SBC) like a Raspberry Pi (though I haven’t tested this personally, it should theoretically work).

This gateway will allow you to access HamNet within your entire home network by configuring your home router to route traffic through the VPN tunnel. It’s a great alternative if your local repeaters are not yet part of HamNet, providing you with seamless connectivity to the network.

Prerequisites:

  • A VM running Ubuntu inside your home network (or a physical computer/Raspberry Pi).
  • A static IP configured for the above VM, so you can setup a static route
  • Basic understanding of networking and VPNs.
  • Access to your home router for static route configuration.
  • You must be a licensed radio amateur, so you can obtain a ARRL LOWT Certificate to login to the HamCloud VPN.

Note: For security reasons, this setup should not be done on an internet-facing VM, such as a VM from a cloud provider. Always use a VM within your home network.

Step 1: Update and Install Required Packages

Start by updating your system and installing WireGuard, to do this SSH into your VM and do as such:

sudo apt-get update -y && sudo apt-get upgrade -y
sudo apt-get install wireguard -y

Step 2: Generate WireGuard Keys

wg genkey | tee private.key | wg pubkey > public.key

Step 3: Add your WireGuard key to HamCloud

Now you need to add your public key to your HamCloud account, to do this first you need to actually retrieve it, so do as such:

cat public.key

Your key will print to your console, so now you need to copy this key and go into your HamCloud Panel, and you will go to Wireguard > + (Add Buton) > set public key

Then you will paste the public key you copied previously on the appropriate field and press submit:

You will then go back to the previous page, but it will not show the public key you configured, click on it to get back into the config view page and copy the whole config file as you will need it later.

Step 4: Configure WireGuard

Create the WireGuard configuration file:

sudo nano /etc/wireguard/wg0.conf

Now you will paste the config you copied from before that should look something like this:

[Interface]
PrivateKey = YOUR_PRIVATE_KEY
Address = 44.148.xxx.xxx/32

[Peer]
PublicKey = xxxxxxx
AllowedIPs = 44.128.0.0/10
Endpoint = vpn.hc.r1.ampr.org:50000
PersistentKeepalive = 25

Note the YOUR_PRIVATE_KEY thing? We need to replace it by our real one so lets get it and copy it:

cat private.key

Now edit the file again and replace the key by the real one:

sudo nano /etc/wireguard/wg0.conf

Step 5: Start WireGuard

Bring up the WireGuard interface:

sudo wg-quick up wg0

Verify the interface is up:

ip a

Step 6: Enable IP Forwarding

Edit the sysctl configuration to enable IP forwarding:

sudo nano /etc/sysctl.conf

Uncomment or add the following line:

net.ipv4.ip_forward=1

Apply the changes:

sudo sysctl -p

Step 7: Configure NAT with iptables

Set up NAT to masquerade traffic going out of the WireGuard interface:

sudo iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE

Allow traffic forwarding:

sudo iptables -A FORWARD -i eth0 -o wg0 -j ACCEPT

Step 8: Make iptables Rules Persistent

Install the iptables-persistent package to save the rules:

sudo apt-get install iptables-persistent
sudo netfilter-persistent save

Step 9: Configure Static Route on Your Home Router

To direct AMPRNet traffic through the VM, add a static route on your home router, the exact steps will depend on your Router or Firewall, googling for “Add Static Route” and your router model should do the trick, when you do configure it as such:

Destination Network: 44.128.0.0/10
Gateway: The IP address of your VM on your local network

You can test if its working by seeing if you can ping any HamNet IP form any other device on your network, such as this:

Personally, im running a Sophos (Home) Firewall, for me the setup looks like this:

Bonus: Set Up Port Forwarding (Optional – To host HamNet services)

If you want to forward specific ports (e.g., 80 and 443) to an internal IP to expose services on HamNet, use the following iptables rules:

sudo iptables -t nat -A PREROUTING -i wg0 -p tcp --dport 80 -j DNAT --to-destination 10.10.5.1:80
sudo iptables -t nat -A PREROUTING -i wg0 -p tcp --dport 443 -j DNAT --to-destination 10.10.5.1:443
sudo iptables -A FORWARD -i wg0 -p tcp --dport 80 -d 10.10.5.1 -j ACCEPT
sudo iptables -A FORWARD -i wg0 -p tcp --dport 443 -d 10.10.5.1 -j ACCEPT

You might want to set the forward target to your home firewall and manage the access rules and actual forwarding for internal services from there for easier management and better security.

By following these steps, you have set up a WireGuard VPN gateway on your VM, allowing you to route traffic through HamNet from any device on your home network.

73, CR8ACT

Self-Hosting Sentry? Here’s How to Deal with Disk Space Issues

If you’re hosting your own Sentry server for your side projects, you know the advantages it brings in terms of cost and control. However, with the control also comes the responsibility of maintaining the server and keeping an eye on the disk usage.

Here’s a simple solution to tackle disk space issues in Sentry:

Step 1: Cleanup Old Events

As time goes by, the events logged in Sentry accumulate, which may lead to an increase in disk usage. To deal with this, you can run the following command within the Sentry “worker” container:

sentry cleanup --days 30

This command will delete all the events that are older than 30 days, which will free up some space on your disk.

Step 2: Vacuum PostgreSQL

Sentry uses PostgreSQL as its database, and over time, the database can become fragmented, leading to disk space issues. To deal with this, you can vacuum PostgreSQL to reclaim some space.

To vacuum PostgreSQL, you’ll need to enter the PostgreSQL container by running:

docker exec -it <your-postgres-container-name> psql -U postgres

Once inside the container, run the following command to vacuum PostgreSQL:





VACUUM FULL;

This command will remove dead rows from the PostgreSQL database, which will free up some disk space. However, keep in mind that the database will be blocked while the vacuum is running.

By following these two simple steps, you can free up some disk space on your Sentry server and keep it running smoothly.

Self-hosting Sentry comes with its own set of challenges, but with the right solutions, you can keep your server up and running with ease. By following the steps outlined in this article, you can tackle disk space issues in Sentry and keep your server running smoothly.

How to Self-Host Matrix and Element (Docker Compose)

This is a complete guide on setting up Matrix (Synapse) and Element on a fresh Ubuntu 22.04.

Need a server? Try one of this two 🙂
Scaleway
Hetzner (20€ Free Credits)

What is Matrix?

Matrix is an open standard and communication protocol for real-time communication. It aims to make real-time communication work seamlessly between different service providers, just like standard Simple Mail Transfer Protocol email does now for store-and-forward email service, by allowing users with accounts at one communications service provider to communicate with users of a different service provider via online chat, voice over IP, and videotelephony. Such protocols have been around before such as XMPP but Matrix is not based on that or another communication protocol. From a technical perspective, it is an application layer communication protocol for federated real-time communication. It provides HTTP APIs and open source reference implementations for securely distributing and persisting messages in JSON format over an open federation of servers. It can integrate with standard web services via WebRTC, facilitating browser-to-browser applications.

Server Setup

Update your OS and make sure everything is ready

sudo apt update && sudo apt upgrade

UFW Firewall

Lets make sure ports 80 and 443 are open on UFW

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Install Docker & Docker-Compose

curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
apt-get install python3 python3-pip -y
pip3 install docker-compose

Prepare our compose file

Create a matrix folder, in this folder create a docker-compose.yml file with the following contents:

version: '2.3'
services:
  postgres:
    image: postgres:14
    restart: unless-stopped
    volumes:
     - ./postgresdata:/var/lib/postgresql/data

    # These will be used in homeserver.yaml later on
    environment:
     - POSTGRES_DB=synapse
     - POSTGRES_USER=synapse
     - POSTGRES_PASSWORD=STRONGPASSWORD
     
  element:
    image: vectorim/element-web:latest
    restart: unless-stopped
    volumes:
      - ./element-config.json:/app/config.json
        
  synapse:
    image: matrixdotorg/synapse:latest
    restart: unless-stopped
    volumes:
     - ./synapse:/data

Don’t forget to change the Postgres password on this file to a secure password.

Now on the same folder create a config file for the elements clients, named element-config.json.

Copy the example file from Elements.io into your own config file, and adjust the following settings:

Add our own homeserver at the top of the file:

"default_server_config": {
        "m.homeserver": {
            "base_url": "https://matrix.example.com",
            "server_name": "matrix.example.com"
        },
        "m.identity_server": {
            "base_url": "https://vector.im"
        }
    },

Generate Synapse config

Now its time to generate the initial config of our synapse server, run the following command to do so:

sudo docker run -it --rm \
    -v "$HOME/matrix/synapse:/data" \
    -e SYNAPSE_SERVER_NAME=matrix.example.com \
    -e SYNAPSE_REPORT_STATS=yes \
    matrixdotorg/synapse:latest generate

Configuring Synapse

Now lets adjust the freshly generated synapse config to our needs

Edit the synapse/homeserver.yaml file as follows:

Comment-out the SQLite database:

#database:
#  name: sqlite3
#  args:
#    database: /data/homeserver.db

And now add our Postgres database:

database:
  name: psycopg2
  args:
    user: synapse
    password: STRONGPASSWORD
    database: synapse
    host: postgres
    cp_min: 5
    cp_max: 10

Spin it up!

Time to get things moving, spin-up your docker stack:

sudo docker-compose up -d

Create our first (admin) user

sudo docker exec -it matrix_synapse_1 bash
register_new_matrix_user -c /data/homeserver.yaml http://localhost:8008

Follow the on-screen instructions to create your first user

Install Caddy Reverse Proxy

Caddy will be used for the reverse proxy. This will handle incomming HTTPS connections and forward them to the correct docker containers. It a simple setup process and Caddy will automatically fetch and renew Let’s Encrypt certificates for us!

First head over to our user directory

cd ~

Install Caddy:

sudo apt install caddy -y

Create a Caddy file:

sudo nano Caddyfile

Paste the following config:

matrix.example.com {
  reverse_proxy /_matrix/* 10.10.10.4:8008
  reverse_proxy /_synapse/client/* 10.10.10.4:8008
  
  header {
    X-Content-Type-Options nosniff
    Referrer-Policy  strict-origin-when-cross-origin
    Strict-Transport-Security "max-age=63072000; includeSubDomains;"
    Permissions-Policy "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=(), interest-cohort=()"
    X-Frame-Options SAMEORIGIN
    X-XSS-Protection 1
    X-Robots-Tag none
    -server
  }
}

element.example.com {
  encode zstd gzip
  reverse_proxy 10.10.10.3:80

  header {
    X-Content-Type-Options nosniff
    Referrer-Policy  strict-origin-when-cross-origin
    Strict-Transport-Security "max-age=63072000; includeSubDomains;"
    Permissions-Policy "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=(), interest-cohort=()"
    X-Frame-Options SAMEORIGIN
    X-XSS-Protection 1
    X-Robots-Tag none
    -server
  }
}

Don’t forget to adjust the IPs and the domain names!

Reload Caddy

caddy reload

You are done, were you looking for more?

Head to your element domain and login!

Install Kubernetes on Ubuntu

Step 1: Install Docker

curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

Step 2: Make sure containerd dosen’t have CRI disabled

Edit the file /etc/containerd/config.toml and make sure that the disabled_plugins setting is blank

nano /etc/containerd/config.toml

Then restart the containerd service:

service containerd restart

Step 3: Install Kubernetes

You will start by installing the apt-transport-https package which enables working with http and https in Ubuntu’s repositories. Also, install curl as it will be necessary for the next steps. Execute the following command:

sudo apt install apt-transport-https curl

Then, add the Kubernetes signing key to both nodes by executing the command:

echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" >> ~/kubernetes.list
sudo mv ~/kubernetes.list /etc/apt/sources.list.d
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -

After that, update the nodes:

sudo apt update

Once the update completes, we will install Kubernetes. This involves installing the various tools that make up Kubernetes: kubeadm, kubelet, kubectl, and kubernetes-cni

sudo apt-get install -y kubelet kubeadm kubectl kubernetes-cni

Step 4: Disabling Swap Memory

Kubernetes fails to function in a system that is using swap memory. Hence, it must be disabled in the master node and all worker nodes. Execute the following command to disable swap memory:

sudo swapoff -a

Step 5: Setting Unique Hostnames

Your nodes must have unique hostnames for easier identification. If you are deploying a cluster with many nodes, you can set it to identify names for your worker nodes such as node-1, node-2, etc. As we had mentioned earlier, we have named our nodes as kubernetes-master and kubernetes-worker. We have set them at the time of creating the server. However, you can adjust or set yours if you had not already done so from the command line. To adjust the hostname on the master node, run the following command:

sudo hostnamectl set-hostname kubernetes-master

Step 6: Changing Docker Cgroup Driver

On both master and worker nodes, update the cgroupdriver with the following commands:

sudo mkdir /etc/docker
cat <<EOF | sudo tee /etc/docker/daemon.json
{ "exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts":
{ "max-size": "100m" },
"storage-driver": "overlay2"
}
EOF

Then, execute the following commands to restart and enable Docker on system boot-up:

sudo systemctl enable docker
sudo systemctl daemon-reload
sudo systemctl restart docker

Step 7: Initializing the Kubernetes Master Node

The first step in deploying a Kubernetes cluster is to fire up the master node. While on the terminal of your master node, execute the following command to initialize the kubernetes-master:

kubeadm init --pod-network-cidr=10.244.0.0/16 --control-plane-endpoint <EXTERNAL-IP>

In the output, Kubernetes also displays some additional commands that you should run as a regular user on the master node before you start to use the cluster. Let’s run these commands:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

We have now initialized the master node. However, we also have to set up the pod network on the master node before we join the worker nodes.

Step 8: Deploying a Pod Network

A pod network facilitates communication between servers and it’s necessary for the proper functioning of the Kubernetes cluster. You can read more about Kubernetes Cluster Networking from the official docs. We will be using the Flannel pod network for this tutorial. Flannel is a simple overlay network that satisfies the Kubernetes requirements.

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/k8s-manifests/kube-flannel-rbac.yml

Step 9: Joining Worker Nodes to the Kubernetes Cluster

First, log into your worker node on a separate terminal session. You will use your kubeadm join command that was shown in your terminal when we initialized the master node in Step 7, execute the command indicated there, it will look something like the following:

kubeadm join XXXX:6443 --token XXX \
	--discovery-token-ca-cert-hash sha256:XXXX

Once the joining process completes, switch the master node terminal and execute the following command to confirm that your worker node has joined the cluster:

kubectl get nodes

Ender-3 ESteps Calibration

E-steps will means the number of steps a stepper motor takes to extrude one millimeter of filament, incorrectly calibrated e-steps might cause under extrusion and bad bed adhesion too.

The process to calibrate your ESteps is very easy

  1. Heat up the extruder and remove the filament
  2. Remove the bowden tube from the extruder pneumatic fitting, so you can see the filament coming out of it.
  3. Insert filament until it reaches the pneumatic fitting and snip it flush to the whole
  4. Manually on the printer extrude 100mm of filament
  5. When the printer finishes extruding the filament snip it again by the extruder pneumatic fitting
  6. Using calipers measure how much filament was extruded
  7. Go to your printer settings and check what is your current estep value (For Ender-3 Menu > Control > Motion > Steps/mm > Esteps/mm) and note down your current EStep value (for most Ender-3s the default value is 93mm)
  8. Calculate your new esteps using the following formula: OldValue x 100 / MeasuredFilament, this means that if your configured ESteps were 93 mm, and you measured 96.6 mm your new EStep value would be ~96.3mm (93x100/96.6=96,273291925)
  9. Set this new EStep value in your printer settings (For Ender-3 Menu > Control > Motion > Steps/mm > Esteps/mm)
  10. Dont forget to save the settings, of you will wonder why your prints are not sticking again on the next day!