Security, Whitelist & mTLS
The Planovi VPS security model combines Cloudflare perimeter defense, origin SSL encryption, Nginx application-layer IP filtering, and hardware mutual TLS (mTLS) for edge IoT converters.
🛡️ Dynamic IP Whitelist (allowed_ips.conf)
Administrative dashboards—including Supabase Studio and the Docs-as-Code staging portal—are restricted from public internet access via Nginx IP whitelisting.
Whitelist Architecture
- Configuration file:
/opt/vps-stack/proxy/allowed_ips.conf - Mounted read-only into
vps-proxyat/etc/nginx/allowed_ips.conf. - Included inside protected Nginx
location /directives.
# Example allowed_ips.confallow 89.64.12.185; # Dev Office Warsawallow 185.244.214.88; # Core Engineer VPNdeny all;Dynamic IP Update Automation (update-allowed-ip.sh)
When developers change locations or ISP IPs, the allowed list is updated without restarting Nginx using /opt/vps-stack/scripts/update-allowed-ip.sh:
# Add current public IP to whitelist and hot-reload Nginxsudo /opt/vps-stack/scripts/update-allowed-ip.sh add $(curl -s ifconfig.me)
# List all currently authorized IP addressessudo /opt/vps-stack/scripts/update-allowed-ip.sh listThe script verifies IP syntax, appends the rule before the deny all; statement, tests Nginx syntax (docker exec vps-proxy nginx -t), and triggers a zero-downtime reload (docker exec vps-proxy nginx -s reload).
🔒 Cloudflare 15-Year Origin SSL
All web traffic routed to *.planovi.app uses Cloudflare Origin Certificates:
- Certificate:
/opt/vps-stack/cloudflare-ssl/fullchain.pem - Private Key:
/opt/vps-stack/cloudflare-ssl/privkey.pem - Validity: 15 years (expires 2041).
- Cipher Suite: Modern TLS 1.2 / TLS 1.3 with forward secrecy (
ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-RSA-AES128-GCM-SHA256).
In Cloudflare’s DNS Dashboard, encryption mode is set to Full (Strict), guaranteeing end-to-end cryptographic integrity between Cloudflare edge servers and the Hostinger VPS.
📡 Dedicated IoT Telemetry & Hardware mTLS
Edge IoT Converters (planovi-converter) communicate over public cellular and Wi-Fi networks. To prevent packet tampering, replay attacks, or unauthorized data injection, IoT traffic is isolated from regular HTTP traffic:
sequenceDiagram
autonumber
participant Converter as ⚡ IoT Hardware Converter
participant DNS as "🌐 Cloudflare DNS (Grey Cloud)"
participant Nginx as "🛡️ VPS Nginx (mTLS Listener)"
participant Edge as "⚡ Edge Runtime (ingest-telemetry)"
participant DB as 💾 PostgreSQL
Note over DNS: DNS Only Mode (Direct IP pass-through)
Converter->>Nginx: TLS Handshake + Client Certificate (test-device.crt)
Nginx->>Nginx: Verify Client Cert against Root Device CA (planovi-device-ca.pem)
alt Client Certificate Valid
Nginx->>Edge: Proxy POST /functions/v1/ingest-telemetry
Edge->>DB: Store authenticated telemetry payload
Edge-->>Converter: HTTP 200 OK
else Certificate Invalid or Missing
Nginx-->>Converter: HTTP 400 Bad Request (SSL Cert Required)
end
Dedicated Ingress Subdomains
- Production:
https://telemetry.planovi.app/functions/v1/ingest-telemetry - Development:
https://dev-telemetry.planovi.app/functions/v1/ingest-telemetry
Device Root Certificate Authority (CA)
- Device CA Certificate:
/opt/vps-stack/cloudflare-ssl/planovi-device-ca.pem - Distinguished Name:
CN=Planovi Converters Root CA, O=Planovi, C=PL - CA Lifetime: 20 years.
- Grey Cloud Requirement: Cloudflare DNS for
telemetryanddev-telemetryMUST be set to DNS Only (Grey Cloud) so that the mutual TLS handshake reaches the VPS Nginx server directly rather than terminating at Cloudflare.