# Let's Encrypt Certificate for RPC-01 (VMID 2500)

**Date**: $(date)  
**Container**: besu-rpc-1 (Core RPC Node)  
**VMID**: 2500  
**IP**: 192.168.11.250

---

## ⚠️ Important: Domain Requirements

Let's Encrypt **requires a publicly accessible domain name**. The current Nginx configuration uses `.local` domains which **will not work** with Let's Encrypt:

- ❌ `rpc-core.besu.local` - Not publicly accessible
- ❌ `rpc-core.chainid138.local` - Not publicly accessible
- ❌ `rpc-core-ws.besu.local` - Not publicly accessible

**Required**: A public domain that:
1. Resolves to the server's IP (or is accessible via Cloudflare Tunnel)
2. Is accessible from the internet (for HTTP-01 challenge)
3. Or has DNS API access (for DNS-01 challenge)

---

## 🔧 Setup Options

### Option 1: Use Public Domain (Recommended)

If you have a public domain (e.g., `d-bis.org` or similar):

1. **Configure DNS**:
   - Create A record: `rpc-core.yourdomain.com` → `192.168.11.250`
   - Or use Cloudflare Tunnel (CNAME to tunnel)

2. **Update Nginx config** to include public domain:
   ```bash
   pct exec 2500 -- sed -i 's/server_name.*;/server_name rpc-core.yourdomain.com rpc-core.besu.local 192.168.11.250;/' /etc/nginx/sites-available/rpc-core
   ```

3. **Obtain certificate**:
   ```bash
   pct exec 2500 -- certbot --nginx -d rpc-core.yourdomain.com
   ```

### Option 2: Use Cloudflare Tunnel (If Using Cloudflare)

If using Cloudflare Tunnel (VMID 102), you can:

1. **Use Cloudflare's SSL** (handled by Cloudflare)
2. **Or use DNS-01 challenge** with Cloudflare API:
   ```bash
   pct exec 2500 -- certbot certonly --dns-cloudflare \
     --dns-cloudflare-credentials /etc/cloudflare/credentials.ini \
     -d rpc-core.yourdomain.com
   ```

### Option 3: Keep Self-Signed (For Internal Use)

If this is **internal-only** and doesn't need public validation:
- ✅ Keep self-signed certificate
- ✅ Works for internal network
- ✅ No external dependencies
- ❌ Browser warnings (acceptable for internal use)

---

## 📋 Step-by-Step: Public Domain Setup

### Prerequisites

1. **Public domain** (e.g., `yourdomain.com`)
2. **DNS access** to create A record or CNAME
3. **Port 80 accessible** from internet (for HTTP-01 challenge)

### Step 1: Install Certbot

```bash
pct exec 2500 -- apt-get update
pct exec 2500 -- apt-get install -y certbot python3-certbot-nginx
```

### Step 2: Configure DNS

**Option A: Direct A Record**
```
Type: A
Name: rpc-core
Target: 192.168.11.250
TTL: Auto
```

**Option B: Cloudflare Tunnel (CNAME)**
```
Type: CNAME
Name: rpc-core
Target: <tunnel-id>.cfargotunnel.com
Proxy: 🟠 Proxied
```

### Step 3: Update Nginx Configuration

Add public domain to server_name:

```bash
pct exec 2500 -- sed -i 's/server_name.*rpc-core.besu.local.*;/server_name rpc-core.yourdomain.com rpc-core.besu.local 192.168.11.250;/' /etc/nginx/sites-available/rpc-core
```

### Step 4: Obtain Certificate

**For HTTP-01 challenge** (requires port 80 accessible):
```bash
pct exec 2500 -- certbot --nginx \
  --non-interactive \
  --agree-tos \
  --email admin@yourdomain.com \
  -d rpc-core.yourdomain.com
```

**For DNS-01 challenge** (if HTTP-01 fails):
```bash
# Install DNS plugin
pct exec 2500 -- apt-get install -y python3-certbot-dns-cloudflare

# Create credentials file
pct exec 2500 -- bash -c 'cat > /etc/cloudflare/credentials.ini <<EOF
dns_cloudflare_api_token = YOUR_CLOUDFLARE_API_TOKEN
EOF
chmod 600 /etc/cloudflare/credentials.ini'

# Obtain certificate
pct exec 2500 -- certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /etc/cloudflare/credentials.ini \
  --non-interactive \
  --agree-tos \
  --email admin@yourdomain.com \
  -d rpc-core.yourdomain.com
```

### Step 5: Update Nginx to Use Certificate

Certbot should automatically update Nginx configuration. Verify:

```bash
pct exec 2500 -- cat /etc/nginx/sites-available/rpc-core | grep ssl_certificate
```

Should show:
```
ssl_certificate /etc/letsencrypt/live/rpc-core.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/rpc-core.yourdomain.com/privkey.pem;
```

### Step 6: Test Configuration

```bash
# Test Nginx config
pct exec 2500 -- nginx -t

# Reload Nginx
pct exec 2500 -- systemctl reload nginx

# Test HTTPS
curl -X POST https://rpc-core.yourdomain.com \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
```

### Step 7: Verify Auto-Renewal

```bash
# Check certbot timer
pct exec 2500 -- systemctl status certbot.timer

# Test renewal
pct exec 2500 -- certbot renew --dry-run
```

---

## 🔄 Using the Automated Script

If you have a public domain, use the automated script:

```bash
cd /home/intlc/projects/proxmox
./scripts/setup-letsencrypt-rpc-2500.sh rpc-core.yourdomain.com
```

The script will:
1. Install Certbot
2. Verify domain accessibility
3. Obtain certificate
4. Update Nginx configuration
5. Set up auto-renewal
6. Test configuration

---

## 📋 DNS-01 Challenge Setup (Cloudflare)

If you need to use DNS-01 challenge:

### 1. Get Cloudflare API Token

1. Go to Cloudflare Dashboard
2. My Profile → API Tokens
3. Create Token with:
   - Zone: DNS:Edit
   - Zone Resources: Include → Specific zone → yourdomain.com

### 2. Create Credentials File

```bash
pct exec 2500 -- bash -c 'cat > /etc/cloudflare/credentials.ini <<EOF
dns_cloudflare_api_token = YOUR_API_TOKEN_HERE
EOF
chmod 600 /etc/cloudflare/credentials.ini'
```

### 3. Install DNS Plugin

```bash
pct exec 2500 -- apt-get install -y python3-certbot-dns-cloudflare
```

### 4. Obtain Certificate

```bash
pct exec 2500 -- certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /etc/cloudflare/credentials.ini \
  --non-interactive \
  --agree-tos \
  --email admin@yourdomain.com \
  -d rpc-core.yourdomain.com \
  --preferred-challenges dns
```

### 5. Update Nginx Manually

Since DNS-01 doesn't auto-update Nginx:

```bash
pct exec 2500 -- sed -i 's|ssl_certificate /etc/nginx/ssl/rpc.crt;|ssl_certificate /etc/letsencrypt/live/rpc-core.yourdomain.com/fullchain.pem;|' /etc/nginx/sites-available/rpc-core
pct exec 2500 -- sed -i 's|ssl_certificate_key /etc/nginx/ssl/rpc.key;|ssl_certificate_key /etc/letsencrypt/live/rpc-core.yourdomain.com/privkey.pem;|' /etc/nginx/sites-available/rpc-core

pct exec 2500 -- nginx -t
pct exec 2500 -- systemctl reload nginx
```

---

## 🔍 Verification

### Check Certificate

```bash
# List certificates
pct exec 2500 -- certbot certificates

# View certificate details
pct exec 2500 -- openssl x509 -in /etc/letsencrypt/live/rpc-core.yourdomain.com/fullchain.pem -noout -subject -issuer -dates
```

### Test HTTPS

```bash
# Test from container
pct exec 2500 -- curl -X POST https://rpc-core.yourdomain.com \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'

# Test from external
curl -X POST https://rpc-core.yourdomain.com \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
```

### Check Auto-Renewal

```bash
# Check timer status
pct exec 2500 -- systemctl status certbot.timer

# Test renewal
pct exec 2500 -- certbot renew --dry-run
```

---

## 🐛 Troubleshooting

### Domain Not Accessible

**Error**: `Failed to obtain certificate`

**Solutions**:
1. Verify DNS: `dig rpc-core.yourdomain.com`
2. Check port 80: Ensure accessible from internet
3. Use DNS-01 challenge instead

### Port 80 Not Accessible

**Error**: `Connection refused` or timeout

**Solutions**:
1. Check firewall: `pct exec 2500 -- iptables -L -n`
2. Check NAT/router configuration
3. Use DNS-01 challenge instead

### Certificate Already Exists

**Error**: `Certificate already exists`

**Solutions**:
```bash
# Force renewal
pct exec 2500 -- certbot --nginx --force-renewal -d rpc-core.yourdomain.com

# Or delete and recreate
pct exec 2500 -- certbot delete --cert-name rpc-core.yourdomain.com
pct exec 2500 -- certbot --nginx -d rpc-core.yourdomain.com
```

---

## 📚 Related Documentation

- [Nginx RPC 2500 Configuration](/docs/09-troubleshooting/NGINX_RPC_2500_CONFIGURATION.md)
- [Cloudflare DNS Configuration](./04-configuration/CLOUDFLARE_DNS_SPECIFIC_SERVICES.md)
- [Cloudflare Tunnel Setup](./04-configuration/CLOUDFLARE_TUNNEL_RPC_SETUP.md)

---

**Note**: For internal-only use, the self-signed certificate is sufficient and doesn't require external dependencies.

---

**Last Updated**: $(date)

