mirror of
https://github.com/fosrl/docs-v2.git
synced 2026-07-18 03:49:55 +00:00
enhance(wildcard): expand and review current sections
This commit is contained in:
@@ -1,151 +1,115 @@
|
||||
---
|
||||
title: "Wildcard Domains"
|
||||
description: "Configure wildcard SSL certificates for automatic subdomain security with DNS-01 challenge"
|
||||
description: "Configure wildcard TLS certificates with Traefik DNS-01 challenges"
|
||||
---
|
||||
|
||||
import PangolinCloudTocCta from "/snippets/pangolin-cloud-toc-cta.mdx";
|
||||
|
||||
<PangolinCloudTocCta />
|
||||
|
||||
Wildcard certificates let one certificate cover every first-level subdomain of a domain, such as `*.example.com`. They are useful when you create many resources under the same base domain because Traefik does not need to request a new certificate for every resource hostname.
|
||||
|
||||
|
||||
Wildcard certificates allow you to secure unlimited subdomains with a single SSL certificate, eliminating the need to generate individual certificates for each subdomain. Pangolin uses Traefik's built-in Let's Encrypt integration to automatically manage these certificates.
|
||||
Traefik is the reverse proxy in the self-hosted Pangolin stack. It receives HTTPS traffic, requests certificates from Let's Encrypt, and routes requests to Pangolin resources. A Traefik certificate resolver is the named block of Traefik configuration that tells Traefik how to request certificates.
|
||||
|
||||
<Warning>
|
||||
Before setting up wildcard certificates, you must have a domain that you own and control. You must also have access to the DNS records for this domain.
|
||||
Wildcard certificates require a DNS-01 challenge. You must control the domain's DNS records and have API credentials for a DNS provider supported by Traefik.
|
||||
</Warning>
|
||||
|
||||
<Info>
|
||||
Since Pangolin uses Traefik as a reverse proxy, it has built-in support for Let's Encrypt certificates. This allows you to easily secure your Pangolin instance and all proxied resources with HTTPS. Let's Encrypt provides free SSL certificates, which are automatically renewed.
|
||||
</Info>
|
||||
|
||||
If you used the default settings during installation, your Traefik instance should be set up to use `HTTP-01` challenge for certificate generation. This challenge is the easiest to configure and requires that the Traefik instance be accessible from the internet on port 80.
|
||||
|
||||
<Note>
|
||||
It is highly recommended that you read the [official Traefik documentation](https://doc.traefik.io/traefik/https/acme/) on ACME and Let's Encrypt before proceeding.
|
||||
Let's Encrypt only issues wildcard certificates through DNS-01 challenges. See the [Traefik ACME documentation](https://doc.traefik.io/traefik/https/acme/) and [Lego DNS provider list](https://go-acme.github.io/lego/dns/) for provider-specific options.
|
||||
</Note>
|
||||
|
||||
## Benefits of Wildcard Certificates
|
||||
## How Wildcards Work
|
||||
|
||||
- `*.example.com` covers `app.example.com`, `api.example.com`, and `blog.example.com`.
|
||||
- `*.example.com` does not cover `app.internal.example.com`; that needs `*.internal.example.com`.
|
||||
- A wildcard certificate can reduce Let's Encrypt rate limit pressure because many resource hostnames can reuse the same certificate.
|
||||
|
||||
Pangolin can prefer wildcard certificates when it generates Traefik router configuration. For example, if you have resources at `blog.example.com` and `api.example.com`, Pangolin can ask Traefik to request `*.example.com` instead of separate certificates for each hostname.
|
||||
|
||||
## Benefits
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="Single Certificate" icon="certificate">
|
||||
Secure unlimited subdomains with one certificate, reducing management overhead.
|
||||
Secure many subdomains under the same base domain with one certificate.
|
||||
</Card>
|
||||
|
||||
<Card title="Instant Subdomains" icon="bolt">
|
||||
Add new subdomains without waiting for certificate generation (up to a few minutes).
|
||||
New resource subdomains can use the existing wildcard certificate instead of waiting for a new certificate request.
|
||||
</Card>
|
||||
|
||||
<Card title="Rate Limit Friendly" icon="shield">
|
||||
Reduce Let's Encrypt rate limit impact by using fewer certificate requests.
|
||||
Fewer certificate requests can help reduce the chance of hitting Let's Encrypt rate limits.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
### Examples
|
||||
## Choose a Resolver Strategy
|
||||
|
||||
- A wildcard cert `*.example.com` could protect:
|
||||
- `api.example.com`
|
||||
- `blog.example.com`
|
||||
- `dashboard.example.com`
|
||||
- Another wildcard `*.subdomain.example.com` could protect:
|
||||
- `api.subdomain.example.com`
|
||||
- `blog.subdomain.example.com`
|
||||
Most installs start with one Traefik certificate resolver named `letsencrypt` that uses HTTP-01:
|
||||
|
||||
<Info>
|
||||
The [rate limits](https://letsencrypt.org/docs/rate-limits/) for Let's Encrypt are per domain. Using a wildcard certificate reduces the number of domains you have, which can help you avoid hitting these limits.
|
||||
</Info>
|
||||
```yaml title="traefik_config.yml"
|
||||
certificatesResolvers:
|
||||
letsencrypt:
|
||||
acme:
|
||||
httpChallenge:
|
||||
entryPoint: web
|
||||
email: "admin@example.com"
|
||||
storage: "/letsencrypt/acme.json"
|
||||
caServer: "https://acme-v02.api.letsencrypt.org/directory"
|
||||
```
|
||||
|
||||
## Setting Up Wildcard Certificates
|
||||
HTTP-01 proves domain ownership by serving a challenge over port `80`. DNS-01 proves domain ownership by creating a temporary DNS record through your DNS provider. Wildcard certificates require DNS-01.
|
||||
|
||||
For wildcard certificates, you have two good options. Most users should replace the existing `letsencrypt` resolver with DNS-01; add a second resolver only if you know you need both HTTP-01 and DNS-01.
|
||||
|
||||
| Strategy | When to use it |
|
||||
| --- | --- |
|
||||
| Replace `letsencrypt` with DNS-01 | Simplest option. Use this if all certificates can be issued through your DNS provider. |
|
||||
| Add a second resolver | Use this if you want to keep HTTP-01 for some routers and use DNS-01 only for wildcard domains. |
|
||||
|
||||
Traefik does not automatically apply a resolver just because it exists. Each router must reference the resolver with `tls.certResolver`, and Pangolin's `cert_resolver` setting must match the Traefik resolver name.
|
||||
|
||||
<Note>
|
||||
In the Pangolin dashboard, `default` uses Pangolin's configured `traefik.cert_resolver` value. In a standard install, that default value is `letsencrypt`.
|
||||
</Note>
|
||||
|
||||
## Configure DNS-01 Wildcards
|
||||
|
||||
<Steps>
|
||||
<Step title="Stop the stack">
|
||||
Make sure the stack is not running before making configuration changes.
|
||||
</Step>
|
||||
Stop Pangolin before editing Traefik and Pangolin configuration.
|
||||
|
||||
<Step title="Update Traefik configuration">
|
||||
Update the Traefik configuration to use the DNS-01 challenge instead of the HTTP-01 challenge. This tells Traefik to use your DNS provider to create the DNS records needed for the challenge.
|
||||
</Step>
|
||||
|
||||
<Step title="Configure Pangolin">
|
||||
Set the `prefer_wildcard_cert` flag to `true` in the Pangolin configuration file for your domain. This is also configurable in the Pangolin dashboard (once restarted).
|
||||
|
||||
```yaml title="config.yml" highlight={4}
|
||||
domains:
|
||||
domain1:
|
||||
base_domain: "example.com"
|
||||
prefer_wildcard_cert: true
|
||||
```bash
|
||||
sudo docker compose down
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
This setting will try to encourage Traefik to request one wildcard certificate for each level of the domain used by your existing resources.
|
||||
<Step title="Update the Traefik resolver">
|
||||
Replace the default HTTP-01 resolver with a DNS-01 resolver. This example uses Cloudflare.
|
||||
|
||||
**Example**: If you have two resources `blog.example.com` and `blog.subdomain.example.com`, Traefik should try to request a wildcard certificate for `*.example.com` and `*.subdomain.example.com` automatically for you.
|
||||
</Note>
|
||||
|
||||
## Traefik Configuration
|
||||
|
||||
### Default Config for HTTP-01 Challenge
|
||||
|
||||
This is the default config generated by the installer. This is shown here for reference to compare with the wildcard config below.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="1. HTTP Challenge Configuration">
|
||||
Tell Traefik to use the `web` entrypoint for the HTTP challenge.
|
||||
|
||||
```yaml title="traefik_config.yml" highlight={4,5}
|
||||
certificatesResolvers:
|
||||
letsencrypt:
|
||||
acme:
|
||||
httpChallenge:
|
||||
entryPoint: web
|
||||
email: admin@example.com
|
||||
storage: "/letsencrypt/acme.json"
|
||||
caServer: "https://acme-v02.api.letsencrypt.org/directory"
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="2. Dynamic Configuration">
|
||||
Set the cert resolver to `letsencrypt` and the entrypoint to `websecure` in the dynamic config.
|
||||
|
||||
```yaml title="dynamic_config.yml"
|
||||
next-router:
|
||||
rule: "Host(`pangolin.example.com`) && !PathPrefix(`/api/v1`)"
|
||||
service: next-service
|
||||
entryPoints:
|
||||
- websecure
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
### Wildcard Config for DNS-01 Challenge
|
||||
|
||||
<Steps>
|
||||
<Step title="1. Configure DNS Challenge">
|
||||
Tell Traefik to use your DNS provider for the DNS challenge. In this example, we are using Cloudflare.
|
||||
|
||||
```yaml title="traefik_config.yml" highlight={4,5}
|
||||
```yaml title="config/traefik/traefik_config.yml" highlight={4-6}
|
||||
certificatesResolvers:
|
||||
letsencrypt:
|
||||
acme:
|
||||
dnsChallenge:
|
||||
provider: "cloudflare" # your DNS provider
|
||||
# see https://doc.traefik.io/traefik/https/acme/#providers
|
||||
provider: "cloudflare"
|
||||
# See https://doc.traefik.io/traefik/https/acme/#providers
|
||||
email: "admin@example.com"
|
||||
storage: "/letsencrypt/acme.json"
|
||||
caServer: "https://acme-v02.api.letsencrypt.org/directory"
|
||||
```
|
||||
|
||||
<Note>
|
||||
The resolver name is the key under `certificatesResolvers`. In this example it is `letsencrypt`, so Pangolin's `cert_resolver` and any Traefik `tls.certResolver` values must also use `letsencrypt`.
|
||||
</Note>
|
||||
</Step>
|
||||
|
||||
<Step title="2. Add Environment Variables">
|
||||
Add the environment variables for your DNS provider to the Traefik service in the docker compose file. This allows Traefik to authenticate with your DNS provider to create the DNS records needed for the challenge.
|
||||
<Step title="Add DNS provider credentials">
|
||||
Add the environment variables required by your DNS provider to the `traefik` service. Cloudflare requires an API token with `Zone:Read` and `DNS:Edit` permissions for every zone Traefik needs to solve challenges for.
|
||||
|
||||
```yaml title="docker-compose.yml" highlight={11-13}
|
||||
```yaml title="docker-compose.yml" highlight={11-12}
|
||||
traefik:
|
||||
image: traefik:v3.4.0
|
||||
image: docker.io/traefik:v3.6
|
||||
container_name: traefik
|
||||
restart: unless-stopped
|
||||
network_mode: service:gerbil
|
||||
@@ -154,80 +118,136 @@ This is the default config generated by the installer. This is shown here for re
|
||||
condition: service_healthy
|
||||
command:
|
||||
- --configFile=/etc/traefik/traefik_config.yml
|
||||
# Add the environment variables for your DNS provider.
|
||||
environment:
|
||||
CLOUDFLARE_DNS_API_TOKEN: "your-cloudflare-api-token"
|
||||
CLOUDFLARE_DNS_API_TOKEN: "your-cloudflare-api-token" # REPLACE
|
||||
volumes:
|
||||
- ./config/traefik:/etc/traefik:ro
|
||||
- ./config/letsencrypt:/letsencrypt
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="3. Add Wildcard Domains">
|
||||
<Step title="Tell Pangolin to prefer wildcard certificates">
|
||||
Set `prefer_wildcard_cert: true` for the domain in `config/config.yml`.
|
||||
|
||||
This step is optional and only effects the certs generated for the Pangolin dashboard. If you only plan to create wildcard resources and not use the dashboard, you can skip this step.
|
||||
```yaml title="config/config.yml" highlight={4}
|
||||
domains:
|
||||
domain1:
|
||||
base_domain: "example.com"
|
||||
prefer_wildcard_cert: true
|
||||
cert_resolver: "letsencrypt"
|
||||
```
|
||||
|
||||
Add the domain and wildcard domain to the domains section of the next (front end) router in the dynamic config. This tells Traefik to generate a wildcard certificate for the base domain and all subdomains.
|
||||
If you manage domains through the Pangolin dashboard instead, restart Pangolin and enable wildcard preference on the domain there. The dashboard also lets you set the domain's certificate resolver; it must match the resolver name in Traefik.
|
||||
</Step>
|
||||
|
||||
```yaml title="dynamic_config.yml" highlight={8-12}
|
||||
next-router:
|
||||
rule: "Host(`pangolin.example.com`) && !PathPrefix(`/api/v1`)"
|
||||
service: next-service
|
||||
entryPoints:
|
||||
- websecure
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
domains:
|
||||
- main: "example.com"
|
||||
sans:
|
||||
- "*.example.com"
|
||||
<Step title="Restart the stack">
|
||||
Start the stack and watch Traefik logs. You should see Traefik create DNS challenge records through your provider.
|
||||
|
||||
```bash
|
||||
sudo docker compose up -d
|
||||
sudo docker compose logs -f traefik
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Warning>
|
||||
If you're using Cloudflare, make sure your API token has the permissions Zone/Zone/Read and Zone/DNS/Edit and make sure it applies to all zones.
|
||||
</Warning>
|
||||
## Multiple Certificate Resolvers
|
||||
|
||||
<Info>
|
||||
Traefik supports most DNS providers. A full list of supported providers and configuration instructions (environment variables) can be found in the [Lego documentation](https://go-acme.github.io/lego/dns/). Lego (Let's Encrypt Go) is used by Traefik for DNS challenges.
|
||||
</Info>
|
||||
You can define more than one Traefik certificate resolver. This is useful when you want to keep HTTP-01 available as the default resolver, but use a DNS-01 resolver for wildcard domains.
|
||||
|
||||
## Verify it Works
|
||||
```yaml title="config/traefik/traefik_config.yml"
|
||||
certificatesResolvers:
|
||||
letsencrypt:
|
||||
acme:
|
||||
httpChallenge:
|
||||
entryPoint: web
|
||||
email: "admin@example.com"
|
||||
storage: "/letsencrypt/acme-http.json"
|
||||
caServer: "https://acme-v02.api.letsencrypt.org/directory"
|
||||
|
||||
<Tips>
|
||||
<Tip title="Clear Old Certificates">
|
||||
You can ensure Traefik doesn't try to use the old certs by deleting the previously used `acme.json` file. This will force Traefik to generate a new certificate on the next start.
|
||||
letsencrypt-dns:
|
||||
acme:
|
||||
dnsChallenge:
|
||||
provider: "cloudflare"
|
||||
email: "admin@example.com"
|
||||
storage: "/letsencrypt/acme-dns.json"
|
||||
caServer: "https://acme-v02.api.letsencrypt.org/directory"
|
||||
```
|
||||
|
||||
Then point the wildcard domain at the DNS resolver. You can do this in `config/config.yml` for file-managed domains:
|
||||
|
||||
```yaml title="config/config.yml" highlight={5-6}
|
||||
domains:
|
||||
domain1:
|
||||
base_domain: "example.com"
|
||||
prefer_wildcard_cert: true
|
||||
cert_resolver: "letsencrypt-dns"
|
||||
```
|
||||
|
||||
If you want UI-created domains to use the DNS resolver by default, set the Traefik defaults too:
|
||||
|
||||
```yaml title="config/config.yml"
|
||||
traefik:
|
||||
cert_resolver: "letsencrypt-dns"
|
||||
prefer_wildcard_cert: true
|
||||
```
|
||||
|
||||
For dashboard-managed domains, open the domain settings in Pangolin and set the certificate resolver to the custom Traefik resolver name, such as `letsencrypt-dns`. Enable wildcard preference on the same domain if you want Pangolin to request wildcard certificates for resources under that domain.
|
||||
|
||||
<Note>
|
||||
If you split ACME storage across multiple files, configure Pangolin's private `acme.acme_json_path` setting as the directory that contains them, for example `config/letsencrypt`. Pangolin will scan the directory for ACME JSON files, including nested files. See [ACME configuration](/self-host/advanced/private-config-file#acme-configuration).
|
||||
</Note>
|
||||
|
||||
## Dashboard Certificate
|
||||
|
||||
The `prefer_wildcard_cert` setting affects resource routers generated by Pangolin. If you also want Traefik to request a wildcard certificate for the Pangolin dashboard router, add the wildcard domain to the dashboard router's `tls.domains` list in `config/traefik/dynamic_config.yml`.
|
||||
|
||||
```yaml title="config/traefik/dynamic_config.yml" highlight={8-12}
|
||||
next-router:
|
||||
rule: "Host(`pangolin.example.com`) && !PathPrefix(`/api/v1`)"
|
||||
service: next-service
|
||||
entryPoints:
|
||||
- websecure
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
domains:
|
||||
- main: "example.com"
|
||||
sans:
|
||||
- "*.example.com"
|
||||
```
|
||||
|
||||
If you use a second resolver, set `certResolver` to that resolver name, such as `letsencrypt-dns`.
|
||||
|
||||
## Verify It Works
|
||||
|
||||
<Tip>
|
||||
If Traefik already issued certificates with the old resolver, clear the old certificates before testing so Traefik requests them again. Remove the relevant ACME storage file, or use `pangctl clear-certs` if Pangolin has already synced stale certificates.
|
||||
</Tip>
|
||||
</Tips>
|
||||
|
||||
<Steps>
|
||||
<Step title="Start the stack">
|
||||
Start the stack and watch the logs. You should notice that Traefik is making calls to your DNS provider to create the necessary records to complete the challenge.
|
||||
<Step title="Create or open a resource">
|
||||
Create a resource on an unused subdomain such as `test.example.com`, or open an existing resource under the same base domain.
|
||||
</Step>
|
||||
|
||||
<Step title="Check logs">
|
||||
For debugging purposes, you may find it useful to set the log level of Traefik to `debug` in the `traefik_config.yml` file.
|
||||
<Step title="Check Traefik logs">
|
||||
Traefik should use the DNS-01 resolver and should not need a separate certificate for every resource hostname after the wildcard certificate exists.
|
||||
|
||||
```bash
|
||||
sudo docker compose logs traefik
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Test new resource">
|
||||
After Traefik is done waiting for the cert to verify, try to create a new resource with an unused subdomain. Traefik should not try to generate a new certificate, but instead use the wildcard certificate. The domain should also be secured immediately instead of waiting for a new certificate to be generated.
|
||||
</Step>
|
||||
|
||||
<Step title="Verify certificate">
|
||||
You can also check the volume (in the example above at `config/letsencrypt/`) for the correct certificates. In the `acme.json` file you should see something similar to the following. Note the `*.` in the domain.
|
||||
<Step title="Inspect ACME storage">
|
||||
Check the ACME storage file in `config/letsencrypt`. The certificate domain should include a wildcard SAN such as `*.example.com`.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
```json highlight={5}
|
||||
```json highlight={6}
|
||||
{
|
||||
"Certificates": [
|
||||
{
|
||||
"domain": {
|
||||
"main": "example.com",
|
||||
"sans": [
|
||||
"*.example.com"
|
||||
]
|
||||
"sans": ["*.example.com"]
|
||||
},
|
||||
"certificate": "...",
|
||||
"key": "...",
|
||||
@@ -240,31 +260,19 @@ Traefik supports most DNS providers. A full list of supported providers and conf
|
||||
## Troubleshooting
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Certificate not generating">
|
||||
**Problem**: Wildcard certificate not being created.
|
||||
|
||||
**Solutions**:
|
||||
- Verify DNS provider credentials are correct
|
||||
- Check that API token has proper permissions
|
||||
- Ensure domain ownership and DNS access
|
||||
- Review Traefik logs for specific error messages
|
||||
<Accordion title="Wildcard certificate is not created">
|
||||
Confirm the DNS provider is correct, the provider environment variables are present on the `traefik` service, and the API token has permission to edit DNS records for the zone.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="DNS challenge failing">
|
||||
**Problem**: DNS-01 challenge not completing.
|
||||
|
||||
**Solutions**:
|
||||
- Verify DNS provider is supported by Traefik
|
||||
- Check API token permissions and scope
|
||||
- Ensure DNS propagation has completed
|
||||
- Review provider-specific configuration
|
||||
- If your DNS provider has a firewall in place, ensure it allows incoming DNS traffic (typically UDP on port **53**). Adding an ingress rule to permit such traffic may help resolve the issue, especially if the firewall is stateless.
|
||||
|
||||
<Accordion title="Traefik still uses HTTP-01">
|
||||
Check the resolver name. The router's `tls.certResolver` and Pangolin's `cert_resolver` must match the DNS-01 resolver name exactly.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Old certificates still being used">
|
||||
**Problem**: Traefik using old HTTP-01 certificates.
|
||||
|
||||
**Solution**: Delete the `acme.json` file to force new certificate generation.
|
||||
<Accordion title="Old certificates are still served">
|
||||
Clear old certificates so Traefik can request them again. You can remove the relevant ACME storage file, or use `pangctl clear-certs` if Pangolin has already synced stale certificates.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="DNS challenge times out">
|
||||
Review Traefik debug logs, confirm DNS propagation is working, and check whether your DNS provider requires additional propagation delay or custom resolvers. If your DNS provider has a firewall, make sure it allows DNS traffic, typically UDP on port `53`.
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
Reference in New Issue
Block a user