7.2 KiB
Cloudflare Tunnel + Certs Setup for rig.fhirworx.io
Architecture
Internet Your Server (rig)
┌──────────────────────────────┐
Users ──→ Cloudflare Edge │ │
(TLS termination) │ cloudflared ←──outbound──→ CF Edge
*.rig.fhirworx.io │ │ │
│ ├─→ rustfs:9000 (S3 API)│
│ └─→ rustfs:9001 (Console)│
│ │
Cloudflare WARP │ warp-svc (DNS/Zero Trust) │
└──────────────────────────────┘
All connections are OUTBOUND from your server. No inbound ports needed except SSH (22) for YubiKey management.
Step 1: Cloudflare Dashboard — DNS
- Log into https://dash.cloudflare.com
- Select fhirworx.io zone
- Go to DNS → Records
- You do NOT need to add A/AAAA records manually — the tunnel creates CNAME records automatically. But verify the zone exists and is active.
Step 2: Create the Tunnel
- Go to https://one.dash.cloudflare.com (Zero Trust dashboard)
- Networks → Tunnels → Create a tunnel
- Tunnel name:
rig - Choose Cloudflared connector
- You'll get a tunnel token — it looks like:
eyJhIjoiNGY4...very-long-base64-string - Copy this token — you'll need it in Step 4
Step 3: Configure Tunnel Routes (Public Hostnames)
Still in the tunnel config, add these public hostnames:
| Public Hostname | Service | Notes |
|---|---|---|
s3.rig.fhirworx.io |
http://rustfs:9000 |
S3 API endpoint |
console.rig.fhirworx.io |
http://rustfs:9001 |
Web console |
rig.fhirworx.io |
http://rustfs:9000 |
Default/root domain → S3 |
For each route:
- Type: HTTP (not HTTPS — cloudflared handles the tunnel encryption, the local connection to the container is plaintext over Docker network)
- TLS → Origin Server Name: leave blank
- No TLS Verify: Yes (local traffic, no cert needed)
Optional: Add SSH access through tunnel
| Public Hostname | Service | Notes |
|---|---|---|
ssh.rig.fhirworx.io |
ssh://localhost:22 |
Browser SSH or cloudflared access |
For SSH through tunnel, on the Access tab:
- Create an Access Application for
ssh.rig.fhirworx.io - Add an Access Policy (e.g., email allowlist, one-time PIN)
- This gives you browser-based SSH as a backup to direct SSH
Step 4: Install the Token on Your Server
After yubikey-unlock, edit the env file:
rw
nano /opt/rustfs/.env
Replace PASTE_YOUR_TOKEN_HERE with the actual token from Step 2:
TUNNEL_TOKEN=eyJhIjoiNGY4...
Save and:
ro
cd /opt/rustfs && docker compose up -d
Verify the tunnel connects:
docker logs cloudflared
# Should show: "Connection registered" and "Tunnel is connected"
Step 5: SSL/TLS Mode
- In Cloudflare dashboard → fhirworx.io → SSL/TLS → Overview
- Set mode to: Full
- NOT "Full (Strict)" — unless you set up an origin cert (see below)
- NOT "Flexible" — that's insecure
- With tunnels, "Full" is fine because the tunnel itself is encrypted
If you want "Full (Strict)" (belt AND suspenders), do Step 6.
Step 6: Origin Certificate (Optional)
Only needed if:
- You want Full (Strict) SSL mode, OR
- You want direct HTTPS access on your LAN to rig.fhirworx.io
Option A: Cloudflare Origin CA (simplest, 15-year validity)
- Dashboard → fhirworx.io → SSL/TLS → Origin Server
- Create Certificate
- Settings:
- Key type: ECDSA
- Hostnames:
rig.fhirworx.io,*.rig.fhirworx.io - Validity: 15 years
- Copy the PEM certificate and private key
On the server:
rw
# Paste the certificate
nano /opt/certs/origin.pem
# Paste the private key
nano /opt/certs/origin-key.pem
chmod 644 /opt/certs/origin.pem
chmod 600 /opt/certs/origin-key.pem
ro
These certs are ONLY trusted by Cloudflare's edge — browsers connecting directly will see a cert warning. That's expected and correct for origin certs.
Option B: Let's Encrypt (trusted everywhere, auto-renews)
Use this if you also want trusted HTTPS directly on your LAN.
-
Create a Cloudflare API token:
- https://dash.cloudflare.com/profile/api-tokens
- Create Token → Edit zone DNS template
- Zone:
fhirworx.io - Copy the token
-
On the server:
rw
# Save the API token
cat > /opt/certs/cf-credentials.ini << EOF
dns_cloudflare_api_token = YOUR_TOKEN_HERE
EOF
chmod 600 /opt/certs/cf-credentials.ini
# Request the cert
apk add certbot-dns-cloudflare
certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /opt/certs/cf-credentials.ini \
-d "rig.fhirworx.io" \
-d "*.rig.fhirworx.io" \
--preferred-challenges dns-01 \
--non-interactive \
--agree-tos \
-m you@fhirworx.io
ro
Certs land at:
/etc/letsencrypt/live/rig.fhirworx.io/fullchain.pem/etc/letsencrypt/live/rig.fhirworx.io/privkey.pem
Auto-renewal cron (add after setup):
rw
echo "0 3 * * * root mount -o remount,rw / && certbot renew --quiet && mount -o remount,ro /" >> /etc/crontabs/root
ro
Step 7: Cloudflare WARP (Zero Trust DNS/VPN)
The WARP container gives you:
- DNS-over-HTTPS for all container traffic
- Option to route through Cloudflare's network
- Zero Trust device posture (if configured)
First run enrollment:
docker exec -it warp-svc warp-cli registration new
docker exec -it warp-svc warp-cli connect
To use WARP as the default DNS for the host:
rw
echo "nameserver 127.0.0.1" > /etc/resolv.conf
ro
Step 8: Verify Everything
# Tunnel status
docker logs cloudflared
# Test S3 endpoint externally
curl -I https://s3.rig.fhirworx.io
# Should return 403 (no auth) or 200 with health check
# Test console
curl -I https://console.rig.fhirworx.io
# Should return 200 or 302 redirect to login
# Test from server locally
curl http://127.0.0.1:9000/minio/health/live
curl http://127.0.0.1:9001
# WARP status
docker exec warp-svc warp-cli status
DNS Records (auto-created by tunnel)
After the tunnel connects, Cloudflare automatically creates:
s3.rig.fhirworx.io CNAME <tunnel-id>.cfargotunnel.com
console.rig.fhirworx.io CNAME <tunnel-id>.cfargotunnel.com
rig.fhirworx.io CNAME <tunnel-id>.cfargotunnel.com
You don't need to create these manually.
Summary: What Needs a Cert and What Doesn't
| Connection | Encrypted By | Cert Needed? |
|---|---|---|
| User → Cloudflare Edge | Cloudflare Universal SSL | No (automatic) |
| Cloudflare Edge → cloudflared | Tunnel encryption (built-in) | No |
| cloudflared → RustFS container | Docker internal network (localhost) | No |
| Direct LAN → RustFS | Nothing (HTTP) or your own cert (HTTPS) | Only if you want LAN HTTPS |
For your setup: you need ZERO certificates. The tunnel handles everything. Origin certs are a nice-to-have for defense in depth or direct LAN access.