Unclassified
Neon ↔ Cloudflare Tunnel Configuration
Overview
Secure, encrypted tunnels connect Cloudflare Workers to Neon PostgreSQL databases across all 3 deployment profiles.
Dev Profile Tunnel
Endpoint Configuration
profile: dev
endpoint: neon.dev.integratewise.internal:5432
type: tcp
encryption: TLS 1.2
auth_method: JWT
Setup Steps
- Create Neon branch for dev:
neon branches create --project-id dev-project --branch dev-branch
- Get connection string:
neon connection-string --project-id dev-project --branch dev-branch
# postgresql://user:pass@neon.dev.integratewise.internal/dev_db
- Configure in Wrangler:
[env.dev.vars]
NEON_DATABASE_URL = "postgresql://user:pass@neon.dev.integratewise.internal/dev_db"
NEON_TUNNEL_ENDPOINT = "neon.dev.integratewise.internal"
- Generate JWT token:
openssl genrsa -out dev_key.pem 2048
openssl rsa -in dev_key.pem -pubout -out dev_pub.pem
# Create JWT payload
cat > dev_jwt_payload.json <<EOF
{
"aud": "neon-tunnel-dev",
"iss": "integratewise-dev",
"sub": "dev-worker",
"iat": $(date +%s),
"exp": $(($(date +%s) + 86400))
}
EOF
# Sign JWT (using offline tool or service)
# Store in: NEON_TUNNEL_AUTH_TOKEN
- Test connection from Worker:
// services/gateway/src/index.ts
const client = new postgres.Client({
connectionString: env.NEON_DATABASE_URL,
ssl: {
rejectUnauthorized: true,
ca: env.NEON_TUNNEL_CERT, // If using mTLS
},
});
await client.connect();
Monitoring
# Check tunnel status
curl https://neon.dev.integratewise.internal/health
# Monitor latency
neon telemetry --project-id dev-project
# View connection pool
SELECT count(*) FROM pg_stat_activity;
Customer Zero Profile Tunnel
Endpoint Configuration
profile: customer-zero
endpoint: neon.customer-zero.integratewise.internal:5432
type: tcp
encryption: TLS 1.3
auth_method: mTLS (certificate pinning)
certificate_rotation: every 60 days
backup_certificates: 2
Setup Steps
- Create dedicated Neon project for Customer Zero:
neon projects create --name "IntegrateWise Customer Zero"
neon branches create --project-id customer-zero-project --branch production
- Get connection string:
neon connection-string \
--project-id customer-zero-project \
--branch production
# postgresql://user:pass@neon.customer-zero.integratewise.internal/customer_zero_db
- Generate mTLS certificates (Let's Encrypt):
# Primary certificate (rotate every 60 days)
certbot certonly \
--standalone \
--domain neon.customer-zero.integratewise.internal \
--email ops@integratewise.com
# Private key
openssl pkcs8 -in /etc/letsencrypt/live/neon.customer-zero.integratewise.internal/privkey.pem \
-topk8 -nocrypt -out customer_zero_private.key
# Public cert
cp /etc/letsencrypt/live/neon.customer-zero.integratewise.internal/fullchain.pem \
customer_zero_cert.pem
# CA bundle
curl https://letsencrypt.org/certs/isrgrootx1.pem > ca_bundle.pem
- Configure in Wrangler:
[env.customer-zero.vars]
NEON_DATABASE_URL = "postgresql://user:pass@neon.customer-zero.integratewise.internal/customer_zero_db"
NEON_TUNNEL_ENDPOINT = "neon.customer-zero.integratewise.internal"
NEON_TUNNEL_REGIONS = "us-east"
NEON_CONNECTION_POOL_MIN = "10"
NEON_CONNECTION_POOL_MAX = "100"
- Store certificates in Cloudflare Secrets:
wrangler secret put NEON_TUNNEL_CERT --env customer-zero < customer_zero_cert.pem
wrangler secret put NEON_TUNNEL_KEY --env customer-zero < customer_zero_private.key
wrangler secret put NEON_TUNNEL_AUTH_TOKEN --env customer-zero "jwt_token_here"
- Enable Connection Pool (Neon):
neon connection-pooling enable \
--project-id customer-zero-project \
--branch production \
--pool-size 25
Connection Pool Configuration
-- pgBouncer pooling on Neon
SET client_encoding = 'UTF-8';
-- Create pool connection
SELECT create_pool_connection(
'customer_zero_pool',
'transaction',
25,
300
);
Monitoring
# Check tunnel certificate expiration
openssl x509 -in customer_zero_cert.pem -noout -dates
# notBefore=Dec 15 10:00:00 2024 GMT
# notAfter=Mar 15 10:00:00 2025 GMT
# Monitor connection pool
SELECT
database,
user,
state,
count(*) as connections
FROM pg_stat_activity
GROUP BY database, user, state;
# Health check
curl -X GET https://neon.customer-zero.integratewise.internal/health \
--cert customer_zero_cert.pem \
--key customer_zero_private.key
Backup Certificate Rotation
# Day 1: Create backup cert 1
certbot certonly \
--standalone \
--domain neon.customer-zero.integratewise.internal-backup-1 \
--email ops@integratewise.com
# Day 30: Create backup cert 2
certbot certonly \
--standalone \
--domain neon.customer-zero.integratewise.internal-backup-2 \
--email ops@integratewise.com
# Day 60: Rotate primary cert
certbot renew --force-renewal
# Update secrets
wrangler secret put NEON_TUNNEL_CERT_BACKUP_1 --env customer-zero < backup1_cert.pem
wrangler secret put NEON_TUNNEL_CERT_BACKUP_2 --env customer-zero < backup2_cert.pem
External Users Profile Tunnel
Endpoint Configuration
profile: external-users
endpoints:
- us-east.neon.integratewise.io:5432
- eu-west.neon.integratewise.io:5432
- ap-south.neon.integratewise.io:5432
type: tcp
encryption: TLS 1.3 + TLS 1.2 fallback
auth_method: mTLS with certificate pinning
certificate_rotation: every 330 days (before expiry)
backup_certificates: 3
circuit_breaker:
failure_threshold: 50%
timeout: 60s
half_open_requests: 3
Setup Steps
- Create multi-tenant Neon project:
neon projects create --name "IntegrateWise External Users"
neon branches create --project-id external-users-project --branch production
# Enable read replicas for each region
neon replicas create \
--project-id external-users-project \
--branch production \
--region us-east-1
neon replicas create \
--project-id external-users-project \
--branch production \
--region eu-west-1
neon replicas create \
--project-id external-users-project \
--branch production \
--region ap-south-1
- Get connection strings for each region:
# US East
neon connection-string \
--project-id external-users-project \
--branch production \
--replica us-east
# postgresql://user:pass@us-east.neon.integratewise.io/multi_tenant_db
# EU West
neon connection-string \
--project-id external-users-project \
--branch production \
--replica eu-west
# postgresql://user:pass@eu-west.neon.integratewise.io/multi_tenant_db
# AP South
neon connection-string \
--project-id external-users-project \
--branch production \
--replica ap-south
# postgresql://user:pass@ap-south.neon.integratewise.io/multi_tenant_db
- Generate DigiCert EV certificates (1-year validity):
# Primary certificate
certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
--domain neon.integratewise.io \
--domain "*.neon.integratewise.io" \
--preferred-chain "DigiCert Global Root CA" \
--email ops@integratewise.com
# Extract keys for each region
openssl pkcs8 -in /etc/letsencrypt/live/neon.integratewise.io/privkey.pem \
-topk8 -nocrypt -out external_users_private.key
openssl x509 -in /etc/letsencrypt/live/neon.integratewise.io/fullchain.pem \
-out external_users_cert.pem
# Create region-specific cert aliases (SANs already included)
cp external_users_cert.pem us_east_cert.pem
cp external_users_cert.pem eu_west_cert.pem
cp external_users_cert.pem ap_south_cert.pem
- Configure in Wrangler:
[env.external-users.vars]
NEON_TUNNEL_ENDPOINT = "neon.integratewise.io"
NEON_TUNNEL_REGIONS = "us-east,eu-west,ap-south"
NEON_CONNECTION_POOL_MIN = "50"
NEON_CONNECTION_POOL_MAX = "500"
NEON_POOL_IDLE_TIMEOUT = "30s"
NEON_POOL_STATEMENT_CACHE_SIZE = "50"
NEON_CIRCUIT_BREAKER_ENABLED = "true"
NEON_CIRCUIT_BREAKER_FAILURE_THRESHOLD = "50"
NEON_CIRCUIT_BREAKER_TIMEOUT = "60000"
- Store certificates in Cloudflare Secrets (with backup rotation):
# Primary
wrangler secret put NEON_TUNNEL_CERT --env external-users < external_users_cert.pem
wrangler secret put NEON_TUNNEL_KEY --env external-users < external_users_private.key
# Backup 1 (created day 1)
wrangler secret put NEON_TUNNEL_CERT_BACKUP_1 --env external-users < backup1_cert.pem
# Backup 2 (created day 180)
wrangler secret put NEON_TUNNEL_CERT_BACKUP_2 --env external-users < backup2_cert.pem
# Backup 3 (created day 300, before primary expires)
wrangler secret put NEON_TUNNEL_CERT_BACKUP_3 --env external-users < backup3_cert.pem
- Enable advanced pooling:
neon connection-pooling enable \
--project-id external-users-project \
--branch production \
--pool-size 100 \
--pool-mode transaction \
--idle-timeout 30
# Per-region pooling
for region in us-east eu-west ap-south; do
neon connection-pooling enable \
--project-id external-users-project \
--replica $region \
--pool-size 100 \
--pool-mode transaction \
--idle-timeout 30
done
- Enable Row-Level Security (RLS) on all tables:
-- Enable RLS on tables
ALTER TABLE tenants ENABLE ROW LEVEL SECURITY;
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
ALTER TABLE connectors ENABLE ROW LEVEL SECURITY;
-- ... etc
-- Create policy for tenant isolation
CREATE POLICY tenant_isolation_policy ON users
USING (tenant_id = current_setting('app.current_tenant_id')::uuid);
CREATE POLICY tenant_isolation_policy ON connectors
USING (tenant_id = current_setting('app.current_tenant_id')::uuid);
-- ... etc for all multi-tenant tables
Connection Pool Configuration
-- Configure pgBouncer for multi-region
SET client_encoding = 'UTF-8';
-- US East
SELECT create_pool_connection(
'us_east_pool',
'transaction',
100,
30
);
-- EU West
SELECT create_pool_connection(
'eu_west_pool',
'transaction',
100,
30
);
-- AP South
SELECT create_pool_connection(
'ap_south_pool',
'transaction',
100,
30
);
Monitoring
# Certificate expiration check (automated weekly)
for cert in us_east_cert.pem eu_west_cert.pem ap_south_cert.pem; do
echo "=== $cert ==="
openssl x509 -in $cert -noout -dates -subject
# Alert if expires in < 30 days
done
# Multi-region connection pool status
for region in us-east eu-west ap-south; do
echo "=== $region region ==="
curl -X GET "https://$region.neon.integratewise.io/health" \
--cert external_users_cert.pem \
--key external_users_private.key \
--insecure # In prod, verify cert
done
# Circuit breaker metrics
SELECT
endpoint,
failures,
successes,
failure_rate,
circuit_state
FROM circuit_breaker_metrics
WHERE profile = 'external-users'
ORDER BY endpoint;
# Connection pool status per tenant
SELECT
tenant_id,
active_connections,
idle_connections,
total_connections,
region
FROM pg_stat_activity
GROUP BY tenant_id, region;
Automatic Certificate Rotation
#!/bin/bash
# certificate-rotation.sh - Run weekly
PROFILE="external-users"
CERT_EXPIRY_WARNING_DAYS=30
check_certificate_expiry() {
local cert_file=$1
local expiry_date=$(openssl x509 -in $cert_file -noout -dates | grep notAfter | cut -d= -f2)
local expiry_epoch=$(date -d "$expiry_date" +%s)
local now_epoch=$(date +%s)
local days_until_expiry=$(( ($expiry_epoch - $now_epoch) / 86400 ))
echo "Certificate expires in: $days_until_expiry days"
if [ $days_until_expiry -lt $CERT_EXPIRY_WARNING_DAYS ]; then
echo "ALERT: Certificate expiring in $days_until_expiry days"
# Rotate certificates
certbot renew --force-renewal \
--dns-cloudflare \
--domain neon.integratewise.io
# Update backups (shift them)
mv backup2_cert.pem backup3_cert.pem
mv backup1_cert.pem backup2_cert.pem
cp external_users_cert.pem backup1_cert.pem
# Update secrets
wrangler secret put NEON_TUNNEL_CERT --env $PROFILE < external_users_cert.pem
wrangler secret put NEON_TUNNEL_CERT_BACKUP_1 --env $PROFILE < backup1_cert.pem
wrangler secret put NEON_TUNNEL_CERT_BACKUP_2 --env $PROFILE < backup2_cert.pem
wrangler secret put NEON_TUNNEL_CERT_BACKUP_3 --env $PROFILE < backup3_cert.pem
# Redeploy workers
wrangler deploy --env $PROFILE
echo "Certificate rotation completed"
fi
}
check_certificate_expiry "external_users_cert.pem"
Testing Tunnels
Test Dev Tunnel
# Connect directly
psql "postgresql://user:pass@neon.dev.integratewise.internal/dev_db"
# Test from Worker
curl -X POST https://api.dev.integratewise.internal/test-db \
-H "Content-Type: application/json" \
-d '{"query": "SELECT 1"}'
Test Customer Zero Tunnel
# Verify certificate
openssl s_client -connect neon.customer-zero.integratewise.internal:5432 \
-cert customer_zero_cert.pem \
-key customer_zero_private.key \
-CAfile ca_bundle.pem
# Test from Worker
curl -X POST https://api.customer-zero.integratewise.com/test-db \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $JWT_TOKEN" \
-d '{"query": "SELECT 1"}'
Test External Users Tunnel (Multi-region)
# Test each region
for region in us-east eu-west ap-south; do
echo "Testing $region.neon.integratewise.io..."
curl -X POST "https://api.integratewise.com/test-db" \
-H "Content-Type: application/json" \
-H "X-Region: $region" \
-d '{"query": "SELECT 1"}' \
--cert external_users_cert.pem \
--key external_users_private.key
done
Troubleshooting
Certificate Issues
# Verify certificate is valid
openssl x509 -in cert.pem -noout -text
# Check certificate chain
openssl verify -CAfile ca_bundle.pem cert.pem
# Extract certificate from running connection
echo | openssl s_client -connect neon.integratewise.io:5432 2>/dev/null | openssl x509
Connection Pool Issues
# Check pool statistics
neon telemetry --project-id external-users-project | grep pool
# Monitor active connections
SELECT pid, usename, application_name, state, query
FROM pg_stat_activity
WHERE state != 'idle'
LIMIT 10;
Latency Issues
# Measure tunnel latency
time psql "postgresql://user:pass@neon.integratewise.io/multi_tenant_db" \
-c "SELECT 1"
# Check network latency
ping neon.integratewise.io
# Trace network path
traceroute neon.integratewise.io