ℹ️ This document describes the architecture of a self-hosted VPN hub built on Oracle Cloud Infrastructure (OCI) Always Free tier.
Internal IPs, credentials, hostnames, and identifying details have been removed.
Companion article:
The Accidental Platform →
🗺️ Network Topology
OCI VPN Hybrid Topology · WireGuard (full tunnel) + L2TP (site-to-site, internal only)
WireGuard provides full-tunnel internet access for roaming devices. L2TP/IPSec connects Site A and Site B
for internal resource access only — no internet traffic routes through OCI for site clients.
Cross-VPN routing between WireGuard and L2TP clients is permitted via the OCI VM.
📋 Overview
A lightweight always-on VPN hub running on a single OCI Always Free VM, providing:
- WireGuard VPN for remote devices (phones, laptops, tablets)
- L2TP/IPSec site-to-site tunnels connecting two locations (Site A and Site B)
- Self-hosted password vault over WebDAV/HTTPS
- Self-hosted accounting on PostgreSQL
- Internal DNS with ad-blocking (AdGuard Home)
- Automated backups to Dropbox via rclone
- Telegram-based monitoring and remote management across all three nodes
All services run at zero cost on OCI Always Free tier.
🖥️ VM Specification
| Item | Value |
| Provider | Oracle Cloud Infrastructure (OCI) Always Free |
| Shape | VM.Standard.E2.1.Micro |
| OS | Ubuntu 24.04.4 LTS |
| Kernel | 6.17.0-oracle (x86_64) |
| vCPUs | 2 (hyperthreaded, 1 OCPU) |
| Typical idle | ~97% |
🌐 Network Architecture
Internet
│
┌────────────┴────────────┐
│ │
Site A ISP (Fixed) Site B ISP (4G)
│ │
Site A Router Site B Router
(MikroTik hEX) (MikroTik hAP lite)
│ │
│ L2TP/IPSec │ L2TP/IPSec
│ (internal only) │ (internal only)
└──────────┬──────────────┘
│
OCI VPN Hub
(Singapore region)
│
┌────┴────┐
│ │
WireGuard Internal
Clients Services
(all traffic (Password vault,
via OCI) Accounting,
Docs, DNS)
- Site A and Site B LAN devices use their own ISP for internet — L2TP tunnels are for internal resource access only
- WireGuard clients route all traffic through OCI (Singapore), giving them a Singapore egress IP
🔒 VPN Stack
⚡ WireGuard — Remote Access
- Full-tunnel configuration (all traffic via OCI)
- Internal DNS (AdGuard Home) pushed to each peer
- Peers created and removed via Telegram bot commands
- QR code generated automatically for mobile onboarding
- Peer handshake monitoring — alert sent if handshake goes stale
🔗 L2TP/IPSec — Site-to-Site
- StrongSwan (OCI) ↔ MikroTik (each site)
- AES-256/SHA-256 encryption
- Per-site LAN routes installed automatically via PPP ip-up hook
- LAN clients reach internal services without any VPN client installed
- Tunnels can be toggled on/off via Telegram command
👥 WireGuard Peers
5 active peers across personal devices. All peers use full-tunnel mode with internal DNS and persistent keepalive.
📱 Smartphone
Android · personal device
📱 Smartphone
Android · personal device
💻 Laptop
Windows · personal device
🖥️ Desktop PC
Windows · home device
📟 Tablet
Android · personal device
| Type | OS | Tunnel Mode | DNS |
| Smartphone (×2) | Android | Full tunnel (0.0.0.0/0) | Internal (AdGuard Home) |
| Laptop | Windows | Full tunnel (0.0.0.0/0) | Internal (AdGuard Home) |
| Desktop PC | Windows | Full tunnel (0.0.0.0/0) | Internal (AdGuard Home) |
| Tablet | Android | Full tunnel (0.0.0.0/0) | Internal (AdGuard Home) |
⚙️ Services
| Service | Technology | Purpose |
| WireGuard VPN | WireGuard | Remote device access — full tunnel |
| Site-to-Site VPN | L2TP/IPSec (StrongSwan + xl2tpd) | Site interconnect — internal only |
| Password Manager | KeePass + Apache WebDAV + HTTPS | Self-hosted vault sync, no device limits |
| Accounting | GnuCash + PostgreSQL 16 | Self-hosted personal finance |
| DNS | AdGuard Home | Internal DNS + ad/tracker blocking |
| Monitoring | Bash scripts + Telegram bots | Real-time alerts, 20+ scripts |
| Documentation | Apache + Marked.js | Internal docs portal |
| Backups | rclone + Dropbox | Offsite backup for all critical data |
🔍 DNS Design
All internal services use a .vpn namespace resolved by AdGuard Home (WireGuard peers) and MikroTik static DNS (site LAN clients). No split DNS required — all clients use the same hostnames regardless of connection method.
| Hostname | Service |
keepass.vpn | Password vault (WebDAV) |
gnucash.vpn | Accounting database (PostgreSQL) |
document.vpn | Internal documentation portal |
monitor.vpn | Monitoring dashboard |
🔐 Security Design
| Layer | Approach |
| WireGuard | Modern cryptography (Curve25519, ChaCha20, Poly1305) — no exposed surface when idle |
| L2TP/IPSec | Encrypted tunnel, PSK authentication |
| Password Vault | Digest authentication + TLS, IP-based access control restricted to VPN subnets |
| PostgreSQL | Bound to VPN interface only — not exposed publicly, subnet restrictions via pg_hba.conf |
| AdGuard Home | Internal interface only — no public exposure |
| Firewall | OCI Security List (cloud layer) + UFW/iptables (VM layer) — double-gated |
| All services | Bound to VPN interface — not reachable from public internet |
| Backups | Encrypted at rest on Dropbox |
💾 Backup Strategy
All backup scripts run via cron. Dropbox sync via rclone. No manual steps required.
| Data | Local Retention | Offsite |
| Accounting database | 30 days (daily dumps) | Dropbox — daily overwrite + biweekly dated archive (~6 months) |
| Password vault | 30 days | Dropbox — latest overwrite |
| WireGuard config | 30 days | Dropbox — latest overwrite |
| Scripts | 30 days | GitHub (versioned history) |
| Infrastructure docs | N/A | GitHub (versioned history) |
🔔 Monitoring & Alerts
All monitoring is Telegram-based — no external monitoring service required.
OCI NODE ALERTS
✅
WireGuard peer up/down
Handshake check every 15s
⚠️
Long VPN session (>2h)
Re-alert every 1 hour
🔓
Password vault opened/saved
Apache access log pipe
🐘
Accounting session opened/closed
PostgreSQL pg_stat_activity polling
🚨
Service health failure
Every 5 minutes
📊
Bandwidth warning / critical
Hourly threshold checks
📅
Daily traffic summary
07:00 UTC — per-interface breakdown
📆
Monthly traffic report
1st of month
SITE ROUTER ALERTS (BOTH SITES)
- L2TP connected / disconnected
- Internet up / down (with downtime duration)
- High CPU / high temperature / low RAM
- New device joined LAN (DHCP)
- Failed login attempts
- RouterOS update available
- Router rebooted
💬 Remote Management (Telegram)
All three nodes are controllable via a shared Telegram group:
| Node | Commands |
| OCI Hub | WireGuard peer add/remove/enable/disable, L2TP control, manual documentation sync |
| Site A | Full system status, L2TP control, per-device internet block/unblock |
| Site B | Full system status, L2TP control, reboot |
🔧 Site Routers (MikroTik)
| Item | Site A | Site B |
| Model | RB750Gr3 hEX | RB941-2nD hAP lite |
| RouterOS | 6.49.19 | 6.49.19 |
| RAM | 256 MB | 32 MB |
| CPU | MIPS 4-core 880MHz | MIPS 1-core 650MHz |
| Internet | Fixed ISP | 4G mobile |
| L2TP status | Always-on | Always-on |
Each router runs a custom RouterOS script suite (scheduler-driven, Telegram-integrated) for monitoring, alerting, and remote management.
💰 Cost
The entire infrastructure runs at zero cost:
| Resource | Cost |
| OCI VM.Standard.E2.1.Micro | Free Always Free |
| 45 GB OCI boot volume | Free Always Free |
| Up to 10 TiB/month outbound | Free Always Free |
| Dropbox backup storage | Free tier (<2 GB/year) |
| GitHub private repository | Free |
| MikroTik routers | One-time hardware cost only |
📋 Changelog
2026-06-06
Public reference published — topology diagram, full service and security documentation