# 🖥️ Own the Whole Stack: One Box = Your VPN, Firewall, Storage and Backups — Full Build

**URL:** <https://onehack.st/t/own-the-whole-stack-one-box-your-vpn-firewall-storage-and-backups-full-build/325064>\
**Category:** Tutorials & Methods\
**Tags:** networking, tips-tricks, self-hosted-tools\
**Created:** [August 25, 2026, 10:29pm UTC](https://onehack.st/t/own-the-whole-stack-one-box-your-vpn-firewall-storage-and-backups-full-build/325064 "2026-08-25T22:29:49Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![BCBC](https://onehack.st/user_avatar/onehack.st/bcbc/32/174133_2.png) [@BCBC](https://onehack.st/u/BCBC)\
**Post date:** [August 25, 2026, 10:29pm UTC](https://onehack.st/t/own-the-whole-stack-one-box-your-vpn-firewall-storage-and-backups-full-build/325064/1 "2026-08-25T22:29:49Z")

</div>

One box in a datacenter. **Your** box.

Your own VPN. Your own firewall. Your own cloud storage. Your own backups. Nothing to cancel you, no monthly bill climbing every year, no “your account has been suspended” email. The stuff everyone else rents by the month, sitting on hardware you control, on a public IP that’s yours.

Two days from bare metal to that. Here’s the whole path — starting with the five errors that ate most of the time, because every one of them **points at the wrong thing** :

| It says | It’s actually |
| --- | --- |
| 🔴 `apt` is broken, every repo fails | The **clock**. Box thought it was April, world was in August. apt refuses “future” metadata |
| 🔴 Network’s down (but ping works!) | **DNS**. Old nameservers still in `/etc/resolv.conf` |
| 🔴 Port 2 is dead | It’s not port 2 to Linux. Labels ≠ `nic2` |
| 🔴 The VM froze mid-setup | The **browser console** froze. VM’s fine — type into it from the host instead |
| 🔴 Backup is corrupt: `wrong magic number` | Backup is perfect. `vma` just can’t read compressed files |

Know those five and you look like you’ve done this a hundred times. 😎

🖥 **Don’t have a rack?** A $5 VPS or the dead laptop in your closet runs the same thing. The box is the cheap part — the order below is what you’re actually here for.

* * *

### 🪜 Do it in this order

```auto
wiring → IP → routing → DNS → clock → patching
→ kernel → reboot → firewall → storage → backup → verify

```

Finish each one with its proof command below. Skip around and you’ll debug the wrong layer for hours.

🖥 **On a VPS?** Start at DNS — everything from there is identical.

> **🧩 Words, in plain English**
>
> | | |
> | --- | --- |
> | **Colo** | Your own server, sitting in someone else’s datacenter |
> | **1U** | Pizza-box shaped server, one rack slot tall |
> | **Proxmox** | Free Debian OS that runs virtual machines |
> | **OPNsense** | Free firewall/router, as a VM instead of a plastic box |
> | **NIC** | Network card. This one has 4 ports |
> | **vmbr0** | A virtual switch inside Proxmox |
> | **/29** | A block of 6 usable public IPs |
> | **RAID10** | 4 drives, mirrored + striped. Fast, survives a dead disk |
> | **vzdump / VMA** | Proxmox’s backup command, and the file it makes |

* * *

### 1️⃣ Wiring

```auto
Patch Port 2 → I350 Port 0 → nic2 → vmbr0
Patch Port 8 → I350 Port 1 → nic3 → vmbr1
Patch Port 9 → I350 Port 2 → nic4 → vmbr2

```

✅ `ip -br a` for carrier state, then ping the gateway for real.

### 2️⃣ Make the IP survive a reboot

Typed `ip addr` commands vanish. Put it in `/etc/network/interfaces`.

> **Bridge config**
>
> ```auto
> auto vmbr0
> iface vmbr0 inet static
> address 203.0.113.2/29
> gateway 203.0.113.1
> bridge-ports nic2
> bridge-stp off
> bridge-fd 0
> dns-nameservers 1.1.1.1 8.8.8.8
> 
> ```
> 
> The other two WAN bridges stay `manual` so the firewall VM can grab them later.  
> IPs are placeholders — use the block your provider gave you.

✅ `ifreload -a` (no reboot) → check `ip -br a` and `ip route`

### 3️⃣ DNS

Gateway answering does **not** mean names resolve. Wipe the stale entries, use `1.1.1.1` + `8.8.8.8`.  
✅ `ping -c 3 google.com`

### 4️⃣ Clock

```auto
timedatectl status
systemctl list-unit-files | grep -Ei 'chrony|ntp|timesync'

```

Proxmox uses **chrony** , not systemd-timesyncd. Add a second source so one dead pool can’t strand you:

```auto
pool time.cloudflare.com iburst
systemctl restart chrony && chronyc tracking
timedatectl set-timezone America/New_York

```

✅ `System clock synchronized: yes` · `RTC in local TZ: no`

### 5️⃣ Patch, then reboot while you’re watching

`apt update && apt full-upgrade` → new kernel → `update-grub` (old kernels stay as fallback) → reboot **now** , not by accident at 3am.

### 6️⃣ Firewall VM + the console trick

OPNsense as VM 100 · 8 GB RAM · 40 GB disk. The web console started swallowing keystrokes and pastes.

Type into the VM from the host instead:

```auto
qm sendkey 100 <key>

```

One character at a time, small delays. No browser in the loop.

✅ Web UI loads → then reboot it and load it again. Three gateways live (WAN\_GW / OPT1\_GW / OPT2\_GW).

### 7️⃣ See what your disks really are

Controller: Broadcom/LSI MegaRAID SAS-3 3108. Install **StorCLI** from Broadcom, check the package signature against their key, then:

```auto
/opt/MegaRAID/storcli/storcli64 /c0 show

```

Two RAID10 arrays, both `Optimal`, 8/8 drives `Onln`. Second one empty → that’s the backup home.

⚠ Deleting the empty **LVM thin-pool** is safe. Touching the **RAID virtual disk** is not — that’s the data.

### 8️⃣ Empty array → backup drive

> **GPT → ext4 → fstab → Proxmox storage**
>
> ```auto
> # new GPT partition on the second array → /dev/sdb1
> mkfs.ext4 -L BCBC-BACKUP /dev/sdb1
> 
> ```
> 
> `/etc/fstab` — `nofail` stops a missing disk from blocking boot:
> 
> ```auto
> UUID=<your-uuid> /mnt/BCBC-BACKUP ext4 defaults,nofail 0 2
> 
> ```
> 
> ```auto
> mount -a && findmnt /mnt/BCBC-BACKUP
> 
> ```
> 
> Proxmox → Add Storage → Type `dir` · Path `/mnt/BCBC-BACKUP` · Content `backup` → `pvesm status`

### 9️⃣ A real backup, not a snapshot

```auto
vzdump 100 --storage BCBC-BACKUP --mode snapshot --compress zstd

```

40 GiB disk, 93% of it empty → **1.2 GB archive in 40 seconds**.

Hash it so you can prove later it never rotted:

```auto
sha256sum /mnt/BCBC-BACKUP/dump/vzdump-qemu-100-*.vma.zst

```

### 🔟 Verify (the fake disaster)

```auto
vma verify backup.vma.zst
→ vma: not a vma file - wrong magic number

```

Nothing is wrong. Uncompress on the fly:

```auto
zstd -dc backup.vma.zst | vma verify -

```

Silence = verified ✅

### 🌳 What you end up with

```auto
                     FRANZA
                       │
              MegaRAID SAS-3 3108
                       │
         ┌─────────────┴─────────────┐
         │ │
   RAID10 #1 RAID10 #2
   4 × 930 GB 4 × 558 GB
   1.817 TB 1.089 TB
   OPTIMAL OPTIMAL
         │ │
   Proxmox / VM 100 BCBC-BACKUP
                                     │
                               /mnt/BCBC-BACKUP
                                     │
                               Proxmox vzdump
                                     │
                               Verified archive

```

One array runs the machines. The other one only ever holds backups — and it’s proven, not assumed.

> **✅ The full known-good list**
>
> Wiring proven · NIC mapping proven · public routing up · persistent network config · DNS fixed · chrony synced · Proxmox patched · kernel + GRUB verified · controlled reboot survived · SSH + GUI reachable · OPNsense installed, configured, reboot-tested · 3 gateways active · MegaRAID identified · StorCLI signature verified · both RAID10s Optimal, 8/8 drives online · second array → dedicated backup filesystem · persistent mount · registered as Proxmox storage · real backup taken · SHA-256 recorded · VMA stream verified

**Left to do:** retention/rotation, an actual restore test, keep this archive. Next build is a small standalone gateway — not straight to Kubernetes.

> A link light is not production. Prove one layer, stand on it, build the next.  
> Do that once and you stop renting your own infrastructure.
