chore: clean .gitignore cache
This commit is contained in:
@@ -1,369 +0,0 @@
|
||||
````markdown
|
||||
# Azure DNS Provider Setup
|
||||
|
||||
## Overview
|
||||
|
||||
Azure DNS is Microsoft's cloud-based DNS hosting service that provides name resolution using Microsoft Azure infrastructure. This guide covers setting up Azure DNS as a provider in Charon for wildcard certificate management.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Azure subscription (pay-as-you-go or Enterprise Agreement)
|
||||
- Azure DNS zone created for your domain
|
||||
- Domain nameservers pointing to Azure DNS
|
||||
- Permissions to create App registrations in Microsoft Entra ID (Azure AD)
|
||||
- Permissions to assign roles in Azure RBAC
|
||||
|
||||
## Step 1: Gather Azure Subscription Information
|
||||
|
||||
1. Log in to the [Azure Portal](https://portal.azure.com/)
|
||||
2. Navigate to **Subscriptions**
|
||||
3. Note your **Subscription ID** (e.g., `12345678-1234-1234-1234-123456789abc`)
|
||||
4. Navigate to **Resource groups**
|
||||
5. Note the **Resource group name** containing your DNS zone
|
||||
|
||||
> **Tip:** You can find this information in the DNS zone overview page as well.
|
||||
|
||||
## Step 2: Verify DNS Zone Configuration
|
||||
|
||||
Ensure your domain is properly configured in Azure DNS:
|
||||
|
||||
1. Navigate to **DNS zones**
|
||||
2. Select your DNS zone
|
||||
3. Note the **Azure nameservers** listed (typically 4 servers like `ns1-01.azure-dns.com`)
|
||||
4. Verify your domain registrar is configured to use these nameservers
|
||||
|
||||
<!-- Screenshot placeholder: Azure DNS zone overview showing nameservers -->
|
||||
|
||||
## Step 3: Create App Registration in Microsoft Entra ID
|
||||
|
||||
Create an application identity for Charon:
|
||||
|
||||
1. Navigate to **Microsoft Entra ID** (formerly Azure Active Directory)
|
||||
2. Select **App registrations** from the left menu
|
||||
3. Click **New registration**
|
||||
4. Configure the application:
|
||||
- **Name:** `charon-dns-challenge`
|
||||
- **Supported account types:** Select **Accounts in this organizational directory only**
|
||||
- **Redirect URI:** Leave blank (not needed for service-to-service auth)
|
||||
5. Click **Register**
|
||||
|
||||
### Note Application Details
|
||||
|
||||
After registration, note the following from the **Overview** page:
|
||||
|
||||
- **Application (client) ID:** `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
|
||||
- **Directory (tenant) ID:** `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
|
||||
|
||||
<!-- Screenshot placeholder: App registration overview showing client and tenant IDs -->
|
||||
|
||||
## Step 4: Create Client Secret
|
||||
|
||||
1. In your app registration, navigate to **Certificates & secrets**
|
||||
2. Click **New client secret**
|
||||
3. Configure the secret:
|
||||
- **Description:** `Charon DNS Challenge`
|
||||
- **Expires:** Choose an expiration period (recommended: 12 months or 24 months)
|
||||
4. Click **Add**
|
||||
5. **Copy the secret value immediately** (shown only once)
|
||||
|
||||
> **Warning:** The client secret value is displayed only once. Copy it now and store it securely. If you lose it, you'll need to create a new secret.
|
||||
|
||||
### Secret Expiration Management
|
||||
|
||||
| Expiration | Use Case |
|
||||
|------------|----------|
|
||||
| 6 months | Development/testing environments |
|
||||
| 12 months | Production with regular rotation schedule |
|
||||
| 24 months | Production with less frequent rotation |
|
||||
| Custom | Enterprise requirements |
|
||||
|
||||
## Step 5: Assign DNS Zone Contributor Role
|
||||
|
||||
Grant the app registration permission to manage DNS records:
|
||||
|
||||
1. Navigate to your **DNS zone**
|
||||
2. Select **Access control (IAM)** from the left menu
|
||||
3. Click **Add** → **Add role assignment**
|
||||
4. In the **Role** tab:
|
||||
- Search for **DNS Zone Contributor**
|
||||
- Select **DNS Zone Contributor**
|
||||
- Click **Next**
|
||||
5. In the **Members** tab:
|
||||
- Select **User, group, or service principal**
|
||||
- Click **Select members**
|
||||
- Search for `charon-dns-challenge`
|
||||
- Select the app registration
|
||||
- Click **Select**
|
||||
6. Click **Review + assign**
|
||||
7. Click **Review + assign** again to confirm
|
||||
|
||||
> **Note:** Role assignments may take a few minutes to propagate.
|
||||
|
||||
### Required Permissions
|
||||
|
||||
The **DNS Zone Contributor** role includes:
|
||||
|
||||
| Permission | Purpose |
|
||||
|------------|---------|
|
||||
| `Microsoft.Network/dnsZones/read` | Read DNS zone configuration |
|
||||
| `Microsoft.Network/dnsZones/TXT/read` | Read TXT records |
|
||||
| `Microsoft.Network/dnsZones/TXT/write` | Create/update TXT records |
|
||||
| `Microsoft.Network/dnsZones/TXT/delete` | Delete TXT records |
|
||||
| `Microsoft.Network/dnsZones/recordsets/read` | List DNS record sets |
|
||||
|
||||
> **Security Note:** For tighter security, you can create a custom role with only the permissions listed above.
|
||||
|
||||
## Step 6: Configure in Charon
|
||||
|
||||
1. Navigate to **DNS Providers** in Charon
|
||||
2. Click **Add Provider**
|
||||
3. Fill in the form:
|
||||
- **Provider Type:** Select `Azure DNS`
|
||||
- **Name:** Enter a descriptive name (e.g., "Azure DNS - Production")
|
||||
- **Tenant ID:** Paste the Directory (tenant) ID from Step 3
|
||||
- **Client ID:** Paste the Application (client) ID from Step 3
|
||||
- **Client Secret:** Paste the secret value from Step 4
|
||||
- **Subscription ID:** Paste the Subscription ID from Step 1
|
||||
- **Resource Group:** Enter the resource group name containing your DNS zone
|
||||
|
||||
### Configuration Fields Summary
|
||||
|
||||
| Field | Description | Example |
|
||||
|-------|-------------|---------|
|
||||
| **Tenant ID** | Microsoft Entra ID tenant identifier | `12345678-1234-5678-9abc-123456789abc` |
|
||||
| **Client ID** | App registration application ID | `abcdef12-3456-7890-abcd-ef1234567890` |
|
||||
| **Client Secret** | App registration secret value | `abc123~XYZ...` |
|
||||
| **Subscription ID** | Azure subscription identifier | `98765432-1234-5678-9abc-987654321abc` |
|
||||
| **Resource Group** | Resource group containing DNS zone | `rg-dns-production` |
|
||||
|
||||
### Advanced Settings (Optional)
|
||||
|
||||
Expand **Advanced Settings** to customize:
|
||||
|
||||
- **Propagation Timeout:** `120` seconds (Azure DNS propagates quickly)
|
||||
- **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:
|
||||
- Credentials are valid
|
||||
- App registration has required permissions
|
||||
- DNS zone is accessible
|
||||
- Azure DNS API is reachable
|
||||
|
||||
If the test fails, see [Troubleshooting](#troubleshooting) below.
|
||||
|
||||
## Step 8: Save Configuration
|
||||
|
||||
Click **Save** to store the DNS provider configuration. All 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 **Azure 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: azure
|
||||
Name: Azure DNS - example.com
|
||||
Tenant ID: 12345678-1234-5678-9abc-123456789abc
|
||||
Client ID: abcdef12-3456-7890-abcd-ef1234567890
|
||||
Client Secret: ****************************************
|
||||
Subscription ID: 98765432-1234-5678-9abc-987654321abc
|
||||
Resource Group: rg-dns-production
|
||||
Propagation Timeout: 120 seconds
|
||||
Polling Interval: 10 seconds
|
||||
Default: Yes
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Connection Test Fails
|
||||
|
||||
**Error:** `Invalid credentials` or `AADSTS7000215: Invalid client secret`
|
||||
|
||||
- Verify the client secret was copied correctly
|
||||
- Check the secret hasn't expired
|
||||
- Ensure no extra whitespace was added
|
||||
- Create a new client secret if necessary
|
||||
|
||||
**Error:** `AADSTS700016: Application not found`
|
||||
|
||||
- Verify the Client ID is correct
|
||||
- Ensure the app registration exists in the correct tenant
|
||||
- Check the Tenant ID matches your organization
|
||||
|
||||
**Error:** `AADSTS90002: Tenant not found`
|
||||
|
||||
- Verify the Tenant ID is correct
|
||||
- Ensure you're using the correct Azure environment (public vs. government)
|
||||
|
||||
**Error:** `Authorization failed` or `Forbidden`
|
||||
|
||||
- Verify the DNS Zone Contributor role is assigned
|
||||
- Check the role is assigned at the DNS zone level
|
||||
- Wait a few minutes for role assignment propagation
|
||||
- Verify the resource group name is correct
|
||||
|
||||
**Error:** `Resource group not found`
|
||||
|
||||
- Check the resource group name spelling (case-sensitive)
|
||||
- Ensure the resource group exists in the specified subscription
|
||||
- Verify the subscription ID is correct
|
||||
|
||||
**Error:** `DNS zone not found`
|
||||
|
||||
- Verify the DNS zone exists in the resource group
|
||||
- Check the domain matches the DNS zone name
|
||||
- Ensure the app has access to the subscription
|
||||
|
||||
### Certificate Issuance Fails
|
||||
|
||||
**Error:** `DNS propagation timeout`
|
||||
|
||||
- Azure DNS typically propagates in 30-60 seconds
|
||||
- Increase Propagation Timeout to 180 seconds
|
||||
- Verify nameservers are correctly configured with your registrar
|
||||
- Check Azure Status page for service issues
|
||||
|
||||
**Error:** `Record creation failed`
|
||||
|
||||
- Verify app registration has DNS Zone Contributor role
|
||||
- Check for existing `_acme-challenge` TXT records that may conflict
|
||||
- Review Charon logs for detailed API errors
|
||||
|
||||
**Error:** `Rate limit exceeded`
|
||||
|
||||
- Azure DNS has API rate limits per subscription
|
||||
- Increase Polling Interval to reduce API calls
|
||||
- Contact Azure support to increase limits if needed
|
||||
|
||||
### Nameserver Propagation
|
||||
|
||||
**Issue:** DNS changes not visible globally
|
||||
|
||||
- Nameserver changes can take 24-48 hours to propagate
|
||||
- Use [DNS Checker](https://dnschecker.org/) to verify global propagation
|
||||
- Verify your registrar shows Azure DNS nameservers
|
||||
- Wait for full propagation before attempting certificate issuance
|
||||
|
||||
### Client Secret Expiration
|
||||
|
||||
**Issue:** Certificates stop renewing
|
||||
|
||||
- Client secrets have expiration dates
|
||||
- Set calendar reminders before expiration
|
||||
- Create new secret and update Charon configuration before expiry
|
||||
- Consider using Managed Identities for Azure-hosted Charon deployments
|
||||
|
||||
## Security Recommendations
|
||||
|
||||
1. **Dedicated App Registration:** Create a separate app registration for Charon
|
||||
2. **Least Privilege:** Use DNS Zone Contributor role (not broader roles)
|
||||
3. **Secret Rotation:** Rotate client secrets before expiration (every 6-12 months)
|
||||
4. **Conditional Access:** Consider conditional access policies for the app
|
||||
5. **Audit Logging:** Enable Azure Activity Log for DNS operations
|
||||
6. **Private Endpoints:** Use private endpoints if Charon runs in Azure
|
||||
7. **Managed Identity:** Use Managed Identity if Charon is hosted in Azure (eliminates secrets)
|
||||
8. **Monitor Sign-ins:** Review app sign-in logs in Microsoft Entra ID
|
||||
|
||||
## Client Secret Rotation
|
||||
|
||||
To rotate the client secret:
|
||||
|
||||
1. Navigate to your app registration → **Certificates & secrets**
|
||||
2. Create a new client secret
|
||||
3. Update the configuration in Charon with the new secret
|
||||
4. Test the connection to verify the new secret works
|
||||
5. Delete the old secret from the Azure portal
|
||||
|
||||
> **Best Practice:** Create the new secret before the old one expires to avoid downtime.
|
||||
|
||||
## Using Azure CLI for Verification (Optional)
|
||||
|
||||
Test configuration before adding to Charon:
|
||||
|
||||
```bash
|
||||
# Login with service principal
|
||||
az login --service-principal \
|
||||
--username CLIENT_ID \
|
||||
--password CLIENT_SECRET \
|
||||
--tenant TENANT_ID
|
||||
|
||||
# Set subscription
|
||||
az account set --subscription SUBSCRIPTION_ID
|
||||
|
||||
# List DNS zones
|
||||
az network dns zone list \
|
||||
--resource-group RESOURCE_GROUP_NAME
|
||||
|
||||
# Test record creation
|
||||
az network dns record-set txt add-record \
|
||||
--resource-group RESOURCE_GROUP_NAME \
|
||||
--zone-name example.com \
|
||||
--record-set-name _acme-challenge-test \
|
||||
--value "test-value"
|
||||
|
||||
# Clean up test record
|
||||
az network dns record-set txt remove-record \
|
||||
--resource-group RESOURCE_GROUP_NAME \
|
||||
--zone-name example.com \
|
||||
--record-set-name _acme-challenge-test \
|
||||
--value "test-value"
|
||||
```
|
||||
|
||||
## Using Managed Identity (Azure-Hosted Charon)
|
||||
|
||||
If Charon runs in Azure (VM, Container Instance, AKS), consider using Managed Identity:
|
||||
|
||||
1. Enable System-assigned managed identity on your Azure resource
|
||||
2. Assign **DNS Zone Contributor** role to the managed identity
|
||||
3. Configure Charon to use managed identity authentication (no secrets needed)
|
||||
|
||||
> **Benefits:** No client secrets to manage, automatic credential rotation, enhanced security.
|
||||
|
||||
## Azure DNS Limitations
|
||||
|
||||
- **Zone-scoped permissions only:** Cannot restrict to specific record types within a zone
|
||||
- **No private DNS support:** Charon requires public DNS for ACME challenges
|
||||
- **Regional availability:** Azure DNS is a global service, no regional selection needed
|
||||
- **Billing:** Azure DNS charges per zone and per million queries
|
||||
|
||||
## Cost Considerations
|
||||
|
||||
Azure DNS pricing (approximate):
|
||||
|
||||
- **Hosted zones:** ~$0.50/month per zone
|
||||
- **DNS queries:** ~$0.40 per million queries
|
||||
|
||||
Certificate challenges generate minimal queries (<100 per certificate issuance).
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [Azure DNS Documentation](https://learn.microsoft.com/en-us/azure/dns/)
|
||||
- [Microsoft Entra ID App Registration](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app)
|
||||
- [Azure RBAC for DNS](https://learn.microsoft.com/en-us/azure/dns/dns-protect-zones-recordsets)
|
||||
- [Caddy Azure DNS Module](https://caddyserver.com/docs/modules/dns.providers.azure)
|
||||
- [Azure Status Page](https://status.azure.com/)
|
||||
- [Azure CLI DNS Commands](https://learn.microsoft.com/en-us/cli/azure/network/dns)
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [DNS Providers Overview](../dns-providers.md)
|
||||
- [Wildcard Certificates Guide](../certificates.md#wildcard-certificates)
|
||||
- [DNS Challenges Troubleshooting](../../troubleshooting/dns-challenges.md)
|
||||
|
||||
````
|
||||
@@ -1,160 +0,0 @@
|
||||
# Cloudflare DNS Provider Setup
|
||||
|
||||
## Overview
|
||||
|
||||
Cloudflare is one of the most popular DNS providers and offers a free tier with API access. This guide walks you through setting up Cloudflare as a DNS provider in Charon for wildcard certificate support.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Active Cloudflare account (free tier is sufficient)
|
||||
- Domain added to Cloudflare with nameservers configured
|
||||
- Domain status: **Active** (not pending nameserver update)
|
||||
|
||||
## Step 1: Generate API Token
|
||||
|
||||
Cloudflare API Tokens provide scoped access and are more secure than Global API Keys.
|
||||
|
||||
1. Log in to [Cloudflare Dashboard](https://dash.cloudflare.com/)
|
||||
2. Click on your profile icon (top right) → **My Profile**
|
||||
3. Select **API Tokens** from the left sidebar
|
||||
4. Click **Create Token**
|
||||
5. Use the **Edit zone DNS** template or create a custom token
|
||||
6. Configure token permissions:
|
||||
- **Permissions:**
|
||||
- Zone → DNS → Edit
|
||||
- **Zone Resources:**
|
||||
- Include → Specific zone → Select your domain
|
||||
- OR Include → All zones (if managing multiple domains)
|
||||
7. (Optional) Set **Client IP Address Filtering** for additional security
|
||||
8. (Optional) Set **TTL** for token expiration
|
||||
9. Click **Continue to summary**
|
||||
10. Review permissions and click **Create Token**
|
||||
11. **Copy the token immediately** (shown only once)
|
||||
|
||||
> **Tip:** Store the API token in a password manager. Cloudflare won't display it again.
|
||||
|
||||
## Step 2: Configure in Charon
|
||||
|
||||
1. Navigate to **DNS Providers** in Charon
|
||||
2. Click **Add Provider**
|
||||
3. Fill in the form:
|
||||
- **Provider Type:** Select `Cloudflare`
|
||||
- **Name:** Enter a descriptive name (e.g., "Cloudflare Production")
|
||||
- **API Token:** Paste the token from Step 1
|
||||
|
||||
### Advanced Settings (Optional)
|
||||
|
||||
Expand **Advanced Settings** to customize:
|
||||
|
||||
- **Propagation Timeout:** `60` seconds (Cloudflare has fast global propagation)
|
||||
- **Polling Interval:** `10` seconds (default)
|
||||
- **Set as Default:** Enable if this is your primary DNS provider
|
||||
|
||||
## Step 3: Test Connection
|
||||
|
||||
1. Click **Test Connection** button
|
||||
2. Wait for validation (usually 2-5 seconds)
|
||||
3. Verify you see: ✅ **Connection successful**
|
||||
|
||||
If the test fails, see [Troubleshooting](#troubleshooting) below.
|
||||
|
||||
## Step 4: Save Configuration
|
||||
|
||||
Click **Save** to store the DNS provider configuration. Credentials are encrypted at rest using AES-256-GCM.
|
||||
|
||||
## Step 5: 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 **Cloudflare** 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: cloudflare
|
||||
Name: Cloudflare - example.com
|
||||
API Token: ********************************
|
||||
Propagation Timeout: 60 seconds
|
||||
Polling Interval: 10 seconds
|
||||
Default: Yes
|
||||
```
|
||||
|
||||
## Required Permissions
|
||||
|
||||
The API token needs the following Cloudflare permissions:
|
||||
|
||||
- **Zone → DNS → Edit:** Create and delete TXT records for ACME challenges
|
||||
|
||||
> **Note:** The token does NOT need Zone → Edit or Account-level permissions.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Connection Test Fails
|
||||
|
||||
**Error:** `Invalid API token`
|
||||
|
||||
- Verify the token was copied correctly (no extra spaces)
|
||||
- Ensure the token has Zone → DNS → Edit permission
|
||||
- Check token hasn't expired (if TTL was set)
|
||||
- Regenerate the token if necessary
|
||||
|
||||
**Error:** `Zone not found`
|
||||
|
||||
- Verify the domain is added to your Cloudflare account
|
||||
- Ensure domain status is **Active** (nameservers updated)
|
||||
- Check API token includes the correct zone in Zone Resources
|
||||
|
||||
### Certificate Issuance Fails
|
||||
|
||||
**Error:** `DNS propagation timeout`
|
||||
|
||||
- Cloudflare typically propagates in <30 seconds
|
||||
- Check Cloudflare Status page for service issues
|
||||
- Verify DNSSEC is configured correctly (if enabled)
|
||||
- Try increasing Propagation Timeout to 120 seconds
|
||||
|
||||
**Error:** `Unauthorized to edit DNS`
|
||||
|
||||
- API token may have been revoked
|
||||
- Regenerate a new token with correct permissions
|
||||
- Update configuration in Charon
|
||||
|
||||
### Rate Limiting
|
||||
|
||||
Cloudflare has generous API rate limits:
|
||||
|
||||
- Free plan: 1,200 requests per 5 minutes
|
||||
- Certificate challenges typically use <10 requests
|
||||
|
||||
If you hit limits:
|
||||
|
||||
- Reduce polling frequency
|
||||
- Avoid unnecessary test connection attempts
|
||||
- Consider upgrading Cloudflare plan
|
||||
|
||||
## Security Recommendations
|
||||
|
||||
1. **Scope Tokens:** Limit to specific zones rather than "All zones"
|
||||
2. **IP Filtering:** Add your server's IP to Client IP Address Filtering
|
||||
3. **Set Expiration:** Use token TTL for automatic expiration (renew before expiry)
|
||||
4. **Rotate Regularly:** Generate new tokens every 90-180 days
|
||||
5. **Monitor Usage:** Review API token activity in Cloudflare dashboard
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [Cloudflare API Documentation](https://developers.cloudflare.com/api/)
|
||||
- [API Token Permissions](https://developers.cloudflare.com/api/tokens/create/)
|
||||
- [Caddy Cloudflare Module](https://caddyserver.com/docs/modules/dns.providers.cloudflare)
|
||||
- [Cloudflare Status Page](https://www.cloudflarestatus.com/)
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [DNS Providers Overview](../dns-providers.md)
|
||||
- [Wildcard Certificates Guide](../certificates.md#wildcard-certificates)
|
||||
- [DNS Challenges Troubleshooting](../../troubleshooting/dns-challenges.md)
|
||||
@@ -1,198 +0,0 @@
|
||||
# DigitalOcean DNS Provider Setup
|
||||
|
||||
## Overview
|
||||
|
||||
DigitalOcean provides DNS hosting for free with any DigitalOcean account. This guide covers setting up DigitalOcean DNS as a provider in Charon for wildcard certificate management.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- DigitalOcean account (free tier is sufficient)
|
||||
- Domain added to DigitalOcean DNS
|
||||
- Domain nameservers pointing to DigitalOcean:
|
||||
- `ns1.digitalocean.com`
|
||||
- `ns2.digitalocean.com`
|
||||
- `ns3.digitalocean.com`
|
||||
|
||||
## Step 1: Generate Personal Access Token
|
||||
|
||||
1. Log in to [DigitalOcean Control Panel](https://cloud.digitalocean.com/)
|
||||
2. Click on **API** in the left sidebar (under Account)
|
||||
3. Navigate to the **Tokens/Keys** tab
|
||||
4. Click **Generate New Token** (in the Personal access tokens section)
|
||||
5. Configure the token:
|
||||
- **Token Name:** `charon-dns-challenge` (or any descriptive name)
|
||||
- **Expiration:** Choose expiration period (90 days, 1 year, or no expiry)
|
||||
- **Scopes:** Select **Write** (this includes Read access)
|
||||
6. Click **Generate Token**
|
||||
7. **Copy the token immediately** (shown only once)
|
||||
|
||||
> **Warning:** DigitalOcean shows the token only once. Store it securely in a password manager.
|
||||
|
||||
## Step 2: Verify DNS Configuration
|
||||
|
||||
Ensure your domain is properly configured in DigitalOcean DNS:
|
||||
|
||||
1. Navigate to **Networking** → **Domains** in the DigitalOcean control panel
|
||||
2. Verify your domain is listed
|
||||
3. Click on the domain to view DNS records
|
||||
4. Ensure at least one A or CNAME record exists (for the domain itself)
|
||||
|
||||
> **Note:** Charon will create and remove TXT records automatically; no manual DNS configuration is needed.
|
||||
|
||||
## Step 3: Configure in Charon
|
||||
|
||||
1. Navigate to **DNS Providers** in Charon
|
||||
2. Click **Add Provider**
|
||||
3. Fill in the form:
|
||||
- **Provider Type:** Select `DigitalOcean`
|
||||
- **Name:** Enter a descriptive name (e.g., "DigitalOcean DNS")
|
||||
- **API Token:** Paste the Personal Access Token from Step 1
|
||||
|
||||
### Advanced Settings (Optional)
|
||||
|
||||
Expand **Advanced Settings** to customize:
|
||||
|
||||
- **Propagation Timeout:** `90` seconds (DigitalOcean propagates quickly)
|
||||
- **Polling Interval:** `10` seconds (default)
|
||||
- **Set as Default:** Enable if this is your primary DNS provider
|
||||
|
||||
## Step 4: Test Connection
|
||||
|
||||
1. Click **Test Connection** button
|
||||
2. Wait for validation (usually 3-5 seconds)
|
||||
3. Verify you see: ✅ **Connection successful**
|
||||
|
||||
The test verifies:
|
||||
|
||||
- Token is valid and active
|
||||
- Account has DNS write permissions
|
||||
- DigitalOcean API is accessible
|
||||
|
||||
If the test fails, see [Troubleshooting](#troubleshooting) below.
|
||||
|
||||
## Step 5: Save Configuration
|
||||
|
||||
Click **Save** to store the DNS provider configuration. The token is encrypted at rest using AES-256-GCM.
|
||||
|
||||
## Step 6: 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 **DigitalOcean** 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: digitalocean
|
||||
Name: DigitalOcean - example.com
|
||||
API Token: dop_v1_********************************
|
||||
Propagation Timeout: 90 seconds
|
||||
Polling Interval: 10 seconds
|
||||
Default: Yes
|
||||
```
|
||||
|
||||
## Required Permissions
|
||||
|
||||
The Personal Access Token needs **Write** scope, which includes:
|
||||
|
||||
- Read access to domains and DNS records
|
||||
- Write access to create/update/delete DNS records
|
||||
|
||||
> **Note:** Token scope is account-wide. You cannot restrict to specific domains in DigitalOcean.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Connection Test Fails
|
||||
|
||||
**Error:** `Invalid token` or `Unauthorized`
|
||||
|
||||
- Verify the token was copied correctly (should start with `dop_v1_`)
|
||||
- Ensure token has **Write** scope (not just Read)
|
||||
- Check token hasn't expired (if expiration was set)
|
||||
- Regenerate the token if necessary
|
||||
|
||||
**Error:** `Domain not found`
|
||||
|
||||
- Verify the domain is added to DigitalOcean DNS
|
||||
- Ensure domain nameservers point to DigitalOcean
|
||||
- Check domain status in the Networking section
|
||||
- Wait 24-48 hours if nameservers were recently changed
|
||||
|
||||
### Certificate Issuance Fails
|
||||
|
||||
**Error:** `DNS propagation timeout`
|
||||
|
||||
- DigitalOcean DNS typically propagates in <60 seconds
|
||||
- Verify nameservers are correctly configured:
|
||||
|
||||
```bash
|
||||
dig NS example.com +short
|
||||
```
|
||||
|
||||
- Check DigitalOcean Status page for service issues
|
||||
- Increase Propagation Timeout to 120 seconds as a workaround
|
||||
|
||||
**Error:** `Record creation failed`
|
||||
|
||||
- Check token permissions (must be Write scope)
|
||||
- Verify domain exists in DigitalOcean DNS
|
||||
- Review Charon logs for detailed API errors
|
||||
- Ensure no conflicting TXT records exist with name `_acme-challenge`
|
||||
|
||||
### Nameserver Propagation
|
||||
|
||||
**Issue:** DNS changes not visible globally
|
||||
|
||||
- Nameserver changes can take 24-48 hours to propagate
|
||||
- Use [DNS Checker](https://dnschecker.org/) to verify global propagation
|
||||
- Ensure your domain registrar shows DigitalOcean nameservers
|
||||
- Wait for full propagation before attempting certificate issuance
|
||||
|
||||
### Rate Limiting
|
||||
|
||||
DigitalOcean API rate limits:
|
||||
|
||||
- 5,000 requests per hour (per account)
|
||||
- Certificate challenges typically use <20 requests
|
||||
|
||||
If you hit limits:
|
||||
|
||||
- Reduce frequency of certificate renewals
|
||||
- Avoid unnecessary test connection attempts
|
||||
- Contact DigitalOcean support if consistently hitting limits
|
||||
|
||||
## Security Recommendations
|
||||
|
||||
1. **Token Expiration:** Set 90-day expiration and rotate regularly
|
||||
2. **Dedicated Token:** Create a separate token for Charon (easier to revoke)
|
||||
3. **Monitor Usage:** Review API logs in DigitalOcean control panel
|
||||
4. **Least Privilege:** Use Write scope (don't grant Full Access)
|
||||
5. **Backup Access:** Keep a backup token in secure storage (offline)
|
||||
6. **Revoke Unused:** Delete tokens that are no longer needed
|
||||
|
||||
## DigitalOcean DNS Limitations
|
||||
|
||||
- **No per-domain token scoping:** Tokens grant access to all domains in the account
|
||||
- **No rate limit customization:** Fixed at 5,000 requests/hour
|
||||
- **Public zones only:** Private DNS not supported
|
||||
- **No DNSSEC:** DigitalOcean does not support DNSSEC at this time
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [DigitalOcean DNS Documentation](https://docs.digitalocean.com/products/networking/dns/)
|
||||
- [DigitalOcean API Documentation](https://docs.digitalocean.com/reference/api/)
|
||||
- [Personal Access Tokens Guide](https://docs.digitalocean.com/reference/api/create-personal-access-token/)
|
||||
- [Caddy DigitalOcean Module](https://caddyserver.com/docs/modules/dns.providers.digitalocean)
|
||||
- [DigitalOcean Status Page](https://status.digitalocean.com/)
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [DNS Providers Overview](../dns-providers.md)
|
||||
- [Wildcard Certificates Guide](../certificates.md#wildcard-certificates)
|
||||
- [DNS Challenges Troubleshooting](../../troubleshooting/dns-challenges.md)
|
||||
@@ -1,327 +0,0 @@
|
||||
````markdown
|
||||
# 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)
|
||||
|
||||
````
|
||||
@@ -1,237 +0,0 @@
|
||||
# AWS Route 53 DNS Provider Setup
|
||||
|
||||
## Overview
|
||||
|
||||
Amazon Route 53 is AWS's scalable DNS service. This guide covers setting up Route 53 as a DNS provider in Charon for wildcard certificate management.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- AWS account with Route 53 access
|
||||
- Domain hosted in Route 53 (public hosted zone)
|
||||
- IAM permissions to create users and policies
|
||||
- AWS CLI (optional, for verification)
|
||||
|
||||
## Step 1: Create IAM Policy
|
||||
|
||||
Create a custom IAM policy with minimum required permissions:
|
||||
|
||||
1. Log in to [AWS Console](https://console.aws.amazon.com/)
|
||||
2. Navigate to **IAM** → **Policies**
|
||||
3. Click **Create Policy**
|
||||
4. Select **JSON** tab
|
||||
5. Paste the following policy:
|
||||
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"route53:ListHostedZones",
|
||||
"route53:GetChange"
|
||||
],
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"route53:ChangeResourceRecordSets"
|
||||
],
|
||||
"Resource": "arn:aws:route53:::hostedzone/*"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
1. Click **Next: Tags** (optional tags)
|
||||
2. Click **Next: Review**
|
||||
3. **Name:** `CharonRoute53DNSChallenge`
|
||||
4. **Description:** `Allows Charon to manage DNS TXT records for ACME challenges`
|
||||
5. Click **Create Policy**
|
||||
|
||||
> **Tip:** For production, scope the policy to specific hosted zones by replacing `*` with your zone ID.
|
||||
|
||||
## Step 2: Create IAM User
|
||||
|
||||
Create a dedicated IAM user for Charon:
|
||||
|
||||
1. Navigate to **IAM** → **Users**
|
||||
2. Click **Add Users**
|
||||
3. **User name:** `charon-dns`
|
||||
4. Select **Access key - Programmatic access**
|
||||
5. Click **Next: Permissions**
|
||||
6. Select **Attach existing policies directly**
|
||||
7. Search for and select `CharonRoute53DNSChallenge`
|
||||
8. Click **Next: Tags** (optional)
|
||||
9. Click **Next: Review**
|
||||
10. Click **Create User**
|
||||
11. **Save the credentials** (shown only once):
|
||||
- Access Key ID
|
||||
- Secret Access Key
|
||||
|
||||
> **Warning:** Download the CSV or copy credentials immediately. AWS won't show the secret again.
|
||||
|
||||
## Step 3: Configure in Charon
|
||||
|
||||
1. Navigate to **DNS Providers** in Charon
|
||||
2. Click **Add Provider**
|
||||
3. Fill in the form:
|
||||
- **Provider Type:** Select `AWS Route 53`
|
||||
- **Name:** Enter a descriptive name (e.g., "AWS Route 53 - Production")
|
||||
- **AWS Access Key ID:** Paste the access key from Step 2
|
||||
- **AWS Secret Access Key:** Paste the secret key from Step 2
|
||||
- **AWS Region:** (Optional) Specify region (default: `us-east-1`)
|
||||
|
||||
### Advanced Settings (Optional)
|
||||
|
||||
Expand **Advanced Settings** to customize:
|
||||
|
||||
- **Propagation Timeout:** `120` seconds (Route 53 propagation can take 60-120 seconds)
|
||||
- **Polling Interval:** `10` seconds (default)
|
||||
- **Set as Default:** Enable if this is your primary DNS provider
|
||||
|
||||
## Step 4: Test Connection
|
||||
|
||||
1. Click **Test Connection** button
|
||||
2. Wait for validation (may take 5-10 seconds)
|
||||
3. Verify you see: ✅ **Connection successful**
|
||||
|
||||
The test verifies:
|
||||
|
||||
- Credentials are valid
|
||||
- IAM user has required permissions
|
||||
- Route 53 hosted zones are accessible
|
||||
|
||||
If the test fails, see [Troubleshooting](#troubleshooting) below.
|
||||
|
||||
## Step 5: Save Configuration
|
||||
|
||||
Click **Save** to store the DNS provider configuration. Credentials are encrypted at rest using AES-256-GCM.
|
||||
|
||||
## Step 6: 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 **AWS Route 53** 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: route53
|
||||
Name: AWS Route 53 - example.com
|
||||
Access Key ID: AKIAIOSFODNN7EXAMPLE
|
||||
Secret Access Key: ****************************************
|
||||
Region: us-east-1
|
||||
Propagation Timeout: 120 seconds
|
||||
Polling Interval: 10 seconds
|
||||
Default: Yes
|
||||
```
|
||||
|
||||
## Required IAM Permissions
|
||||
|
||||
The IAM user needs the following Route 53 permissions:
|
||||
|
||||
| Action | Resource | Purpose |
|
||||
|--------|----------|---------|
|
||||
| `route53:ListHostedZones` | `*` | List available hosted zones |
|
||||
| `route53:GetChange` | `*` | Check status of DNS changes |
|
||||
| `route53:ChangeResourceRecordSets` | `arn:aws:route53:::hostedzone/*` | Create/delete TXT records for challenges |
|
||||
|
||||
> **Security Best Practice:** Scope `ChangeResourceRecordSets` to specific hosted zone ARNs:
|
||||
|
||||
```json
|
||||
"Resource": "arn:aws:route53:::hostedzone/Z1234567890ABC"
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Connection Test Fails
|
||||
|
||||
**Error:** `Invalid credentials`
|
||||
|
||||
- Verify Access Key ID and Secret Access Key were copied correctly
|
||||
- Check IAM user exists and is active
|
||||
- Ensure no extra spaces or characters in credentials
|
||||
|
||||
**Error:** `Access denied`
|
||||
|
||||
- Verify IAM policy is attached to the user
|
||||
- Check policy includes all required permissions
|
||||
- Review CloudTrail logs for denied API calls
|
||||
|
||||
**Error:** `Hosted zone not found`
|
||||
|
||||
- Ensure domain has a public hosted zone in Route 53
|
||||
- Verify hosted zone is in the same AWS account
|
||||
- Check zone is not private (private zones not supported)
|
||||
|
||||
### Certificate Issuance Fails
|
||||
|
||||
**Error:** `DNS propagation timeout`
|
||||
|
||||
- Route 53 propagation typically takes 60-120 seconds
|
||||
- Increase Propagation Timeout to 180 seconds
|
||||
- Verify hosted zone is authoritative for the domain
|
||||
- Check Route 53 name servers match domain registrar settings
|
||||
|
||||
**Error:** `Rate limit exceeded`
|
||||
|
||||
- Route 53 has API rate limits (5 requests/second per account)
|
||||
- Increase Polling Interval to 15-20 seconds
|
||||
- Avoid concurrent certificate requests
|
||||
- Contact AWS support to increase limits
|
||||
|
||||
### Region Configuration
|
||||
|
||||
**Issue:** Specifying the wrong region
|
||||
|
||||
- Route 53 is a global service; region typically doesn't matter
|
||||
- Use `us-east-1` (default) if unsure
|
||||
- Some endpoints may require specific regions
|
||||
- Check Charon logs if region-specific errors occur
|
||||
|
||||
## Security Recommendations
|
||||
|
||||
1. **IAM User:** Create a dedicated user for Charon (don't reuse credentials)
|
||||
2. **Least Privilege:** Use the minimal policy provided above
|
||||
3. **Scope to Zones:** Limit policy to specific hosted zones in production
|
||||
4. **Rotate Keys:** Rotate access keys every 90 days
|
||||
5. **Monitor Usage:** Enable CloudTrail for API activity auditing
|
||||
6. **MFA Protection:** Enable MFA on the AWS account (not the IAM user)
|
||||
7. **Access Advisor:** Review IAM Access Advisor to ensure permissions are used
|
||||
|
||||
## AWS CLI Verification (Optional)
|
||||
|
||||
Test credentials before adding to Charon:
|
||||
|
||||
```bash
|
||||
# Configure AWS CLI with credentials
|
||||
aws configure --profile charon-dns
|
||||
|
||||
# List hosted zones
|
||||
aws route53 list-hosted-zones --profile charon-dns
|
||||
|
||||
# Verify permissions
|
||||
aws iam get-user --profile charon-dns
|
||||
```
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [AWS Route 53 Documentation](https://docs.aws.amazon.com/route53/)
|
||||
- [IAM Best Practices](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html)
|
||||
- [Route 53 API Reference](https://docs.aws.amazon.com/route53/latest/APIReference/)
|
||||
- [Caddy Route 53 Module](https://caddyserver.com/docs/modules/dns.providers.route53)
|
||||
- [AWS CloudTrail](https://console.aws.amazon.com/cloudtrail/)
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [DNS Providers Overview](../dns-providers.md)
|
||||
- [Wildcard Certificates Guide](../certificates.md#wildcard-certificates)
|
||||
- [DNS Challenges Troubleshooting](../../troubleshooting/dns-challenges.md)
|
||||
Reference in New Issue
Block a user