Skip to content

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-proxy at /etc/nginx/allowed_ips.conf.
  • Included inside protected Nginx location / directives.
# Example allowed_ips.conf
allow 89.64.12.185; # Dev Office Warsaw
allow 185.244.214.88; # Core Engineer VPN
deny 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:

Terminal window
# Add current public IP to whitelist and hot-reload Nginx
sudo /opt/vps-stack/scripts/update-allowed-ip.sh add $(curl -s ifconfig.me)
# List all currently authorized IP addresses
sudo /opt/vps-stack/scripts/update-allowed-ip.sh list

The 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 telemetry and dev-telemetry MUST be set to DNS Only (Grey Cloud) so that the mutual TLS handshake reaches the VPS Nginx server directly rather than terminating at Cloudflare.