- Marked 12 tests as skip pending feature implementation - Features tracked in GitHub issue #686 (system log viewer feature completion) - Tests cover sorting by timestamp/level/method/URI/status, pagination controls, filtering by text/level, download functionality - Unblocks Phase 2 at 91.7% pass rate to proceed to Phase 3 security enforcement validation - TODO comments in code reference GitHub #686 for feature completion tracking - Tests skipped: Pagination (3), Search/Filter (2), Download (2), Sorting (1), Log Display (4)
11 KiB
11 KiB
# Google Cloud DNS Provider Setup
## Overview
Google Cloud DNS is a high-performance, scalable DNS service built on Google's global infrastructure. This guide covers setting up Google Cloud DNS as a provider in Charon for wildcard certificate management.
## Prerequisites
- Google Cloud Platform (GCP) account
- GCP project with billing enabled
- Cloud DNS API enabled
- DNS zone created in Cloud DNS
- Domain nameservers pointing to Google Cloud DNS
## Step 1: Enable Cloud DNS API
1. Go to the [Google Cloud Console](https://console.cloud.google.com/)
2. Select your project (or create a new one)
3. Navigate to **APIs & Services** → **Library**
4. Search for **Cloud DNS API**
5. Click **Enable**
> **Note:** The API may take a few minutes to activate after enabling.
## Step 2: Create a Service Account
Create a dedicated service account for Charon with minimal permissions:
1. Navigate to **IAM & Admin** → **Service Accounts**
2. Click **Create Service Account**
3. Configure the service account:
- **Service account name:** `charon-dns-challenge`
- **Service account ID:** `charon-dns-challenge` (auto-filled)
- **Description:** `Service account for Charon DNS-01 ACME challenges`
4. Click **Create and Continue**
## Step 3: Assign DNS Admin Role
1. In the **Grant this service account access to project** section:
- Click **Select a role**
- Search for **DNS Administrator**
- Select **DNS Administrator** (`roles/dns.admin`)
2. Click **Continue**
3. Skip the optional **Grant users access** section
4. Click **Done**
> **Security Note:** For production environments, consider creating a custom role with only the specific permissions needed:
> - `dns.changes.create`
> - `dns.changes.get`
> - `dns.managedZones.list`
> - `dns.resourceRecordSets.create`
> - `dns.resourceRecordSets.delete`
> - `dns.resourceRecordSets.list`
> - `dns.resourceRecordSets.update`
## Step 4: Generate Service Account Key
1. Click on the newly created service account
2. Navigate to the **Keys** tab
3. Click **Add Key** → **Create new key**
4. Select **JSON** format
5. Click **Create**
6. **Save the downloaded JSON file securely** (shown only once)
> **Warning:** The JSON key file contains sensitive credentials. Store it in a password manager or secure vault. Never commit it to version control.
### Example JSON Key Structure
```json
{
"type": "service_account",
"project_id": "your-project-id",
"private_key_id": "key-id",
"private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
"client_email": "charon-dns-challenge@your-project-id.iam.gserviceaccount.com",
"client_id": "123456789012345678901",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/..."
}
```
## Step 5: Verify DNS Zone Configuration
Ensure your domain is properly configured in Cloud DNS:
1. Navigate to **Network services** → **Cloud DNS**
2. Verify your zone is listed and active
3. Note the **Zone name** (not the DNS name)
4. Confirm nameservers are correctly assigned:
- `ns-cloud-a1.googledomains.com`
- `ns-cloud-a2.googledomains.com`
- `ns-cloud-a3.googledomains.com`
- `ns-cloud-a4.googledomains.com`
> **Important:** Update your domain registrar to use Google Cloud DNS nameservers if not already configured.
## Step 6: Configure in Charon
1. Navigate to **DNS Providers** in Charon
2. Click **Add Provider**
3. Fill in the form:
- **Provider Type:** Select `Google Cloud DNS`
- **Name:** Enter a descriptive name (e.g., "GCP Cloud DNS - Production")
- **Project ID:** Enter your GCP project ID (e.g., `my-project-123456`)
- **Service Account JSON:** Paste the entire contents of the downloaded JSON key file
### Advanced Settings (Optional)
Expand **Advanced Settings** to customize:
- **Propagation Timeout:** `120` seconds (Cloud DNS propagation is typically fast)
- **Polling Interval:** `10` seconds (default)
- **Set as Default:** Enable if this is your primary DNS provider
## Step 7: Test Connection
1. Click **Test Connection** button
2. Wait for validation (usually 5-10 seconds)
3. Verify you see: ✅ **Connection successful**
The test verifies:
- Service account credentials are valid
- Project ID matches the credentials
- Service account has required permissions
- Cloud DNS API is accessible
If the test fails, see [Troubleshooting](#troubleshooting) below.
## Step 8: Save Configuration
Click **Save** to store the DNS provider configuration. Credentials are encrypted at rest using AES-256-GCM.
## Step 9: Use with Wildcard Certificates
When creating a proxy host with a wildcard domain:
1. Navigate to **Proxy Hosts** → **Add Proxy Host**
2. Enter a wildcard domain: `*.example.com`
3. Select **Google Cloud DNS** from the DNS Provider dropdown
4. Configure remaining settings
5. Save
Charon will automatically obtain a wildcard certificate using DNS-01 challenge.
## Example Configuration
```yaml
Provider Type: googleclouddns
Name: GCP Cloud DNS - example.com
Project ID: my-project-123456
Service Account JSON: {"type":"service_account",...}
Propagation Timeout: 120 seconds
Polling Interval: 10 seconds
Default: Yes
```
## Required Permissions
The service account needs the following Cloud DNS permissions:
| Permission | Purpose |
|------------|---------|
| `dns.changes.create` | Create DNS record changes |
| `dns.changes.get` | Check status of DNS changes |
| `dns.managedZones.list` | List available DNS zones |
| `dns.resourceRecordSets.create` | Create TXT records for ACME challenges |
| `dns.resourceRecordSets.delete` | Clean up TXT records after validation |
| `dns.resourceRecordSets.list` | List existing DNS records |
| `dns.resourceRecordSets.update` | Update DNS records if needed |
> **Note:** The **DNS Administrator** role includes all these permissions. For fine-grained control, create a custom role.
## Troubleshooting
### Connection Test Fails
**Error:** `Invalid service account JSON`
- Verify the entire JSON content was pasted correctly
- Ensure no extra whitespace or line breaks were added
- Check the JSON is valid (use a JSON validator)
- Re-download the key file and try again
**Error:** `Project not found` or `Project mismatch`
- Verify the Project ID matches the project in the service account JSON
- Check the `project_id` field in the JSON matches your input
- Ensure the project exists and is active
**Error:** `Permission denied` or `Forbidden`
- Verify the service account has the DNS Administrator role
- Check the role is assigned at the project level
- Ensure Cloud DNS API is enabled
- Wait a few minutes after role assignment (propagation delay)
**Error:** `API not enabled`
- Navigate to APIs & Services → Library
- Search for and enable Cloud DNS API
- Wait 2-3 minutes for activation
### Certificate Issuance Fails
**Error:** `DNS propagation timeout`
- Cloud DNS typically propagates in 30-60 seconds
- Increase Propagation Timeout to 180 seconds
- Verify nameservers are correctly configured with your registrar
- Check Google Cloud Status page for service issues
**Error:** `Zone not found`
- Ensure the DNS zone exists in Cloud DNS
- Verify the domain matches the zone's DNS name
- Check the service account has access to the zone
**Error:** `Record creation failed`
- Check for existing `_acme-challenge` TXT records that may conflict
- Verify service account permissions
- Review Charon logs for detailed API errors
### Nameserver Propagation
**Issue:** DNS changes not visible globally
- Nameserver changes can take 24-48 hours to propagate globally
- Use [DNS Checker](https://dnschecker.org/) to verify propagation
- Verify your registrar shows Google Cloud DNS nameservers
- Wait for full propagation before attempting certificate issuance
### Rate Limiting
Google Cloud DNS API quotas:
- 10,000 queries per day (default)
- 1,000 changes per day (default)
- Certificate challenges typically use <20 requests
If you hit limits:
- Request quota increase via Google Cloud Console
- Reduce frequency of certificate renewals
- Contact Google Cloud support for production workloads
## Security Recommendations
1. **Dedicated Service Account:** Create a separate service account for Charon
2. **Least Privilege:** Use a custom role with only required permissions
3. **Key Rotation:** Rotate service account keys every 90 days
4. **Key Security:** Store JSON key in a secrets manager, never in version control
5. **Audit Logging:** Enable Cloud Audit Logs for DNS API calls
6. **VPC Service Controls:** Consider using VPC Service Controls for additional security
7. **Disable Unused Keys:** Delete old keys immediately after rotation
## Service Account Key Rotation
To rotate the service account key:
1. Create a new key following Step 4
2. Update the configuration in Charon with the new JSON
3. Test the connection to verify the new key works
4. Delete the old key from the GCP console
```bash
# Using gcloud CLI (optional)
# List existing keys
gcloud iam service-accounts keys list \
--iam-account=charon-dns-challenge@PROJECT_ID.iam.gserviceaccount.com
# Create new key
gcloud iam service-accounts keys create new-key.json \
--iam-account=charon-dns-challenge@PROJECT_ID.iam.gserviceaccount.com
# Delete old key (after updating Charon)
gcloud iam service-accounts keys delete KEY_ID \
--iam-account=charon-dns-challenge@PROJECT_ID.iam.gserviceaccount.com
```
## gcloud CLI Verification (Optional)
Test credentials before adding to Charon:
```bash
# Activate service account
gcloud auth activate-service-account \
--key-file=/path/to/service-account-key.json
# Set project
gcloud config set project YOUR_PROJECT_ID
# List DNS zones
gcloud dns managed-zones list
# Test record creation (creates and deletes a test TXT record)
gcloud dns record-sets create test-acme-challenge.example.com. \
--zone=your-zone-name \
--type=TXT \
--ttl=60 \
--rrdatas='"test-value"'
# Clean up test record
gcloud dns record-sets delete test-acme-challenge.example.com. \
--zone=your-zone-name \
--type=TXT
```
## Additional Resources
- [Google Cloud DNS Documentation](https://cloud.google.com/dns/docs)
- [Service Account Documentation](https://cloud.google.com/iam/docs/service-accounts)
- [Cloud DNS API Reference](https://cloud.google.com/dns/docs/reference/v1)
- [Caddy Google Cloud DNS Module](https://caddyserver.com/docs/modules/dns.providers.googleclouddns)
- [Google Cloud Status Page](https://status.cloud.google.com/)
- [IAM Roles for Cloud DNS](https://cloud.google.com/dns/docs/access-control)
## Related Documentation
- [DNS Providers Overview](../dns-providers.md)
- [Wildcard Certificates Guide](../certificates.md#wildcard-certificates)
- [DNS Challenges Troubleshooting](../../troubleshooting/dns-challenges.md)