Zero-Trust Subdomain Security on Linux with Cloudflare Access and OTP
Learn how to protect Linux-hosted subdomains with Cloudflare Access and OTP-based authentication, implementing zero-trust principles without a VPN.
Zero-Trust Subdomain Security on Linux with Cloudflare Access and OTP
Traditional perimeter security assumes everything inside your network is trustworthy. Zero-trust flips that: never trust, always verify. For Linux administrators exposing subdomains (e.g., admin.example.com, grafana.example.com), Cloudflare Access with One-Time PIN (OTP) offers a lightweight way to enforce authentication without a VPN.
Why Cloudflare Access?
Cloudflare Access sits in front of your origin server, intercepting requests before they reach your Linux box. It integrates with identity providers (IdPs) and supports OTP via email—ideal for small teams or personal projects. You define policies (e.g., allow @yourdomain.com emails), and Access handles the rest.
Prerequisites
- A domain managed by Cloudflare (free plan works).
- A Linux server running a web service (e.g., Nginx, Grafana).
- Cloudflare Tunnel (
cloudflared) or a public IP with firewall rules.
Step 1: Install and Configure Cloudflare Tunnel
Using a tunnel avoids opening ports and hides your origin IP. On your Linux server:
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o cloudflared
chmod +x cloudflared
sudo mv cloudflared /usr/local/bin/
cloudflared tunnel login
cloudflared tunnel create my-tunnel
Create a config file (~/.cloudflared/config.yml):
tunnel: my-tunnel
credentials-file: /home/user/.cloudflared/my-tunnel.json
ingress:
- hostname: admin.example.com
service: http://localhost:8080
- service: http_status:404
Run the tunnel as a service:
sudo cloudflared service install
sudo systemctl enable --now cloudflared
Step 2: Set Up Cloudflare Access with OTP
- In Cloudflare dashboard, go to Access > Applications.
- Click Add an application and choose Self-hosted.
- Set the application domain to
admin.example.com. - Under Authentication, enable One-time PIN (this is built-in; no IdP needed).
- Create an Access Policy:
- Action: Allow
- Include: Emails ending in
@yourdomain.com(or specific addresses).
- Save.
Now, when anyone visits admin.example.com, Cloudflare prompts for an email. A one-time PIN is sent; after verification, a JWT cookie grants access.
Step 3: Harden Your Linux Origin
Even with Access, secure the origin:
- Firewall: Allow traffic only from Cloudflare IP ranges (if not using a tunnel).
- Local authentication: Keep services bound to
localhostor useiptablesto restrict. - Audit logs: Monitor Cloudflare Access logs and Linux auth logs.
Example iptables rule to allow only Cloudflare IPs (for non-tunnel setups):
for ip in $(curl -s https://www.cloudflare.com/ips-v4); do
sudo iptables -A INPUT -p tcp --dport 443 -s $ip -j ACCEPT
done
sudo iptables -A INPUT -p tcp --dport 443 -j DROP
Step 4: Test and Monitor
Visit your subdomain in an incognito window. You should see the Cloudflare Access login page. After OTP verification, you reach your service. Check Access > Logs for authentication events.
Benefits and Caveats
- Pros: No VPN, granular policies, OTP simplicity, hides origin.
- Cons: OTP relies on email security; for higher assurance, pair with TOTP or hardware keys via an IdP.
Conclusion
Cloudflare Access with OTP provides a pragmatic zero-trust layer for Linux subdomains. Combined with Cloudflare Tunnel and origin hardening, you get strong authentication without complex infrastructure. Start small, then evolve to stronger MFA as your needs grow.