# SSL Troubleshooting Guide

## Common SSL Protocol Errors and Solutions

### 1. SSL Protocol Error Causes

The SSL protocol error on your live server can be caused by several issues:

#### **Certificate Issues:**

- Invalid or corrupted SSL certificate files
- Certificate chain incomplete (missing intermediate certificates)
- Certificate expired or not yet valid
- Wrong certificate format (PEM vs DER)
- Certificate doesn't match the domain name

#### **Configuration Issues:**

- Missing or incorrect environment variables
- Wrong file paths for certificate files
- Incorrect SSL options or cipher suites
- Port binding issues

#### **Server Environment Issues:**

- File permissions on certificate files
- Missing dependencies
- Firewall blocking SSL traffic
- Port already in use

### 2. Environment Variables Setup

Add these environment variables to your `.env` file:

```env
# SSL Configuration (Required for Production)
SSL_KEY_PATH=/path/to/your/private.key
SSL_CERT_PATH=/path/to/your/certificate.crt
SSL_CA_PATH=/path/to/your/ca-bundle.crt  # Optional: for intermediate certificates

# Server Configuration
NODE_ENV=production
PORT=443  # Standard HTTPS port
CLIENT_URL=https://yourdomain.com
```

### 3. Certificate File Requirements

#### **Private Key File (.key):**

```bash
-----BEGIN PRIVATE KEY-----
[Your private key content]
-----END PRIVATE KEY-----
```

#### **Certificate File (.crt):**

```bash
-----BEGIN CERTIFICATE-----
[Your certificate content]
-----END CERTIFICATE-----
```

#### **Certificate Authority Bundle (.crt):**

```bash
-----BEGIN CERTIFICATE-----
[Intermediate certificate 1]
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
[Intermediate certificate 2]
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
[Root certificate]
-----END CERTIFICATE-----
```

### 4. Troubleshooting Steps

#### **Step 1: Check Environment Variables**

```bash
# Verify SSL environment variables are set
echo $SSL_KEY_PATH
echo $SSL_CERT_PATH
echo $SSL_CA_PATH
```

#### **Step 2: Validate Certificate Files**

```bash
# Check if certificate files exist and are readable
ls -la $SSL_KEY_PATH
ls -la $SSL_CERT_PATH
ls -la $SSL_CA_PATH

# Check file permissions (should be 600 for private key)
chmod 600 $SSL_KEY_PATH
chmod 644 $SSL_CERT_PATH
chmod 644 $SSL_CA_PATH
```

#### **Step 3: Test Certificate Validity**

```bash
# Test private key
openssl rsa -in $SSL_KEY_PATH -check -noout

# Test certificate
openssl x509 -in $SSL_CERT_PATH -text -noout

# Test certificate chain
openssl verify -CAfile $SSL_CA_PATH $SSL_CERT_PATH
```

#### **Step 4: Check Port Availability**

```bash
# Check if port 443 is available
netstat -tulpn | grep :443
lsof -i :443

# Check if port 80 is available
netstat -tulpn | grep :80
lsof -i :80
```

### 5. Common Solutions

#### **Solution 1: Fix Certificate Chain**

If you're missing intermediate certificates:

1. Download the full certificate chain from your CA
2. Concatenate intermediate certificates with your certificate
3. Update `SSL_CERT_PATH` to point to the complete chain

#### **Solution 2: Fix File Permissions**

```bash
# Set correct permissions
sudo chown $USER:$USER $SSL_KEY_PATH $SSL_CERT_PATH $SSL_CA_PATH
chmod 600 $SSL_KEY_PATH
chmod 644 $SSL_CERT_PATH
chmod 644 $SSL_CA_PATH
```

#### **Solution 3: Use Let's Encrypt (Recommended)**

```bash
# Install certbot
sudo apt-get update
sudo apt-get install certbot

# Generate certificates
sudo certbot certonly --standalone -d yourdomain.com

# Certificates will be stored in:
# /etc/letsencrypt/live/yourdomain.com/privkey.pem
# /etc/letsencrypt/live/yourdomain.com/fullchain.pem
```

#### **Solution 4: Test with Self-Signed Certificate (Development)**

```bash
# Generate self-signed certificate for testing
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes

# Set environment variables
export SSL_KEY_PATH=./key.pem
export SSL_CERT_PATH=./cert.pem
```

### 6. Server Configuration

#### **For Nginx Reverse Proxy (Recommended)**

Instead of handling SSL in Node.js, use Nginx:

```nginx
server {
    listen 443 ssl http2;
    server_name yourdomain.com;

    ssl_certificate /path/to/certificate.crt;
    ssl_certificate_key /path/to/private.key;
    ssl_trusted_certificate /path/to/ca-bundle.crt;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }
}
```

#### **For Docker Deployment**

```dockerfile
# Copy SSL certificates
COPY ssl/ /app/ssl/

# Set environment variables
ENV SSL_KEY_PATH=/app/ssl/private.key
ENV SSL_CERT_PATH=/app/ssl/certificate.crt
ENV SSL_CA_PATH=/app/ssl/ca-bundle.crt
```

### 7. Debugging Commands

#### **Check SSL Configuration**

```bash
# Test SSL connection
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com

# Check certificate details
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com | openssl x509 -text -noout
```

#### **Monitor Server Logs**

```bash
# Watch server logs for SSL errors
tail -f /var/log/your-app.log | grep -i ssl

# Check system logs
journalctl -u your-app-service -f | grep -i ssl
```

### 8. Fallback Configuration

If SSL continues to fail, the server will automatically fall back to HTTP. To force HTTPS redirects, add this middleware:

```javascript
// Force HTTPS redirect middleware
app.use((req, res, next) => {
  if (req.header('x-forwarded-proto') !== 'https') {
    res.redirect(`https://${req.header('host')}${req.url}`);
  } else {
    next();
  }
});
```

### 9. Testing Your SSL Setup

1. **Test locally:**

   ```bash
   curl -k https://localhost:443/health
   ```

2. **Test with SSL verification:**

   ```bash
   curl https://yourdomain.com/health
   ```

3. **Test with browser:**
   - Visit `https://yourdomain.com`
   - Check for SSL certificate warnings
   - Verify the lock icon in the address bar

### 10. Production Checklist

- [ ] SSL certificates are valid and not expired
- [ ] Certificate chain is complete
- [ ] Private key has correct permissions (600)
- [ ] Environment variables are set correctly
- [ ] Ports 80 and 443 are available
- [ ] Firewall allows HTTPS traffic
- [ ] Domain name matches certificate
- [ ] SSL/TLS version is secure (TLS 1.2+)
- [ ] Cipher suites are secure
- [ ] HTTP to HTTPS redirects are working

## Need Help?

If you're still experiencing SSL issues:

1. Check the server logs for specific error messages
2. Verify your certificate with online SSL checkers
3. Test with a simple HTTPS server first
4. Consider using a reverse proxy (Nginx/Apache) for SSL termination
5. Use a certificate management service like Let's Encrypt

Remember: The improved server configuration now provides detailed logging to help identify the exact cause of SSL protocol errors.
