Blog CrtMgr - Zarządzanie Certyfikatami SSL/TLS

Eksperckie wskazówki dotyczące zarządzania certyfikatami SSL/TLS, rodzajów certyfikatów, wdrażania i najlepszych praktyk

Certyfikaty Wildcard SSL/TLS - Najlepsze Praktyki i Pułapki

SSL TLS Wildcard Bezpieczeństwo Certyfikaty DNS

Certyfikaty wildcard to potężne narzędzie w arsenale każdego administratora, ale jak mówi Spider-Man - “z wielką mocą przychodzi wielka odpowiedzialność”. W tym artykule pokażemy, kiedy używać certyfikatów wildcard, jak je bezpiecznie wdrażać i jakich pułapek unikać.

Czym Jest Certyfikat Wildcard?

Certyfikat wildcard to certyfikat SSL/TLS, który zabezpiecza główną domenę oraz wszystkie jej subdomeny pierwszego poziomu. Używa znaku gwiazdki (*) jako wieloznacznika.

Przykład

Certyfikat dla *.example.com zabezpiecza:

  • blog.example.com
  • shop.example.com
  • api.example.com
  • example.com (domena główna - trzeba dodać osobno)
  • admin.api.example.com (subdomena drugiego poziomu)

Multi-Domain Wildcard

Możesz połączyć wildcard z SAN (Subject Alternative Names):

Common Name: *.example.com
SAN:
  - *.example.com
  - example.com
  - *.staging.example.com

To zabezpieczy:

  • example.com
  • blog.example.com
  • shop.example.com
  • api.staging.example.com

Kiedy Używać Certyfikatów Wildcard?

✅ Dobre Przypadki Użycia

1. Środowiska Deweloperskie i Testowe

dev-feature1.staging.example.com
dev-feature2.staging.example.com
dev-feature3.staging.example.com

Certyfikat wildcard dla *.staging.example.com pokrywa wszystkie branch deployments.

2. Aplikacje SaaS z Subdomenami dla Klientów

customer1.app.example.com
customer2.app.example.com
customer3.app.example.com

Jeden certyfikat dla *.app.example.com zamiast setek pojedynczych.

3. Mikroservices z Dynamicznymi Subdomenami

service-auth.internal.example.com
service-api.internal.example.com
service-db.internal.example.com

4. CDN i Load Balancers

cdn1.assets.example.com
cdn2.assets.example.com
cdn3.assets.example.com

❌ Złe Przypadki Użycia

1. Pojedyncze Aplikacje Produkcyjne

Jeśli masz tylko www.example.com i api.example.com, lepiej użyj certyfikatu multi-domain (SAN) niż wildcard.

2. Wysokie Wymagania Bezpieczeństwa

Dla wrażliwych systemów (banking, healthcare) lepiej izolować certyfikaty.

3. Różni Właściciele Subdomen

Jeśli różne zespoły zarządzają różnymi subdomenami, współdzielenie certyfikatu może być problematyczne.

4. Gdy Potrzebujesz EV Certificates

Extended Validation certificates nie są dostępne jako wildcard.

Bezpieczeństwo Certyfikatów Wildcard

Ryzyko Kompromitacji

Problem: Jeśli klucz prywatny zostanie skompromitowany, wszystkie subdomeny są narażone.

Rozwiązanie:

  1. Hardware Security Modules (HSM)
# Przechowuj klucze w HSM
# Nigdy nie eksportuj kluczy w postaci plaintext
  1. Ograniczony Dostęp
# Permissions dla klucza prywatnego
chmod 600 /etc/ssl/private/wildcard.key
chown root:root /etc/ssl/private/wildcard.key
  1. Rotacja Kluczy
# Odnawiaj certyfikat z nowym kluczem co 3-6 miesięcy
# Nie używaj tej samej pary klucz/certyfikat przez lata

Certificate Pinning

Dla aplikacji mobilnych używających wildcard certificates:

// Android - Certificate Pinning
CertificatePinner certificatePinner = new CertificatePinner.Builder()
    .add("*.example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
    .add("*.example.com", "sha256/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=") // backup
    .build();

OkHttpClient client = new OkHttpClient.Builder()
    .certificatePinner(certificatePinner)
    .build();
// iOS - Certificate Pinning
let evaluator = PinnedCertificatesTrustEvaluator(
    certificates: [Certificates.wildcard],
    acceptSelfSignedCertificates: false,
    performDefaultValidation: true,
    validateHost: true
)

let serverTrustManager = ServerTrustManager(evaluators: ["*.example.com": evaluator])

Monitoring i Auditing

# Monitoring dostępu do klucza prywatnego (auditd)
auditctl -w /etc/ssl/private/wildcard.key -p rwxa -k wildcard_key_access

# Przegląd logów
ausearch -k wildcard_key_access

Uzyskiwanie Certyfikatów Wildcard

Let’s Encrypt z DNS-01 Challenge

Dlaczego DNS-01? HTTP-01 nie działa dla wildcard, ponieważ Let’s Encrypt nie może zweryfikować wszystkich możliwych subdomen.

Z Cloudflare

# Instalacja certbot z pluginem Cloudflare
apt-get install certbot python3-certbot-dns-cloudflare

# Plik z credentials
cat > /root/.cloudflare.ini <<EOF
dns_cloudflare_api_token = your-cloudflare-api-token
EOF

chmod 600 /root/.cloudflare.ini

# Uzyskanie certyfikatu
certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials /root/.cloudflare.ini \
  -d example.com \
  -d *.example.com \
  --email [email protected] \
  --agree-tos \
  --non-interactive

# Automatyczne odnowienie
echo "0 3 * * * certbot renew --quiet" | crontab -

Z Route53 (AWS)

# Instalacja pluginu
apt-get install certbot python3-certbot-dns-route53

# Credentials przez AWS CLI lub IAM role
aws configure

# Uzyskanie certyfikatu
certbot certonly \
  --dns-route53 \
  -d example.com \
  -d *.example.com \
  --email [email protected] \
  --agree-tos \
  --non-interactive

Z acme.sh (Universal)

# Instalacja
curl https://get.acme.sh | sh

# Cloudflare
export CF_Token="your-cloudflare-api-token"
acme.sh --issue --dns dns_cf -d example.com -d *.example.com

# Route53
export AWS_ACCESS_KEY_ID="your-access-key"
export AWS_SECRET_ACCESS_KEY="your-secret-key"
acme.sh --issue --dns dns_aws -d example.com -d *.example.com

# Google Cloud DNS
export GCE_PROJECT="your-project"
export GCE_SERVICE_ACCOUNT_FILE="/path/to/key.json"
acme.sh --issue --dns dns_gcloud -d example.com -d *.example.com

Komercyjne CA

Większość komercyjnych CA oferuje wildcard certificates:

  • DigiCert: $295-2995/rok
  • Sectigo: $99-299/rok
  • GlobalSign: $249-1299/rok
  • GoDaddy: $300-500/rok

Wybór komercyjnego CA ma sens gdy:

  • Potrzebujesz wsparcia 24/7
  • Potrzebujesz ubezpieczenia (warranty)
  • Klient wymaga konkretnego CA
  • Nie możesz używać Let’s Encrypt (np. brak dostępu do DNS API)

Konfiguracja Serwerów Web

Nginx

server {
    listen 443 ssl http2;
    server_name *.example.com example.com;
    
    # Certyfikat wildcard
    ssl_certificate /etc/ssl/certs/wildcard.example.com.crt;
    ssl_certificate_key /etc/ssl/private/wildcard.example.com.key;
    
    # Modern SSL configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    
    # HSTS
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    
    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/ssl/certs/chain.pem;
    
    # Routing based on subdomain
    location / {
        if ($host ~ ^([^.]+)\.example\.com$) {
            set $subdomain $1;
            proxy_pass http://backend-$subdomain;
        }
        
        if ($host = example.com) {
            proxy_pass http://backend-main;
        }
    }
}

Apache

<VirtualHost *:443>
    ServerName example.com
    ServerAlias *.example.com
    
    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/wildcard.example.com.crt
    SSLCertificateKeyFile /etc/ssl/private/wildcard.example.com.key
    SSLCertificateChainFile /etc/ssl/certs/chain.pem
    
    # Modern SSL configuration
    SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
    SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384
    SSLHonorCipherOrder off
    
    # HSTS
    Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
    
    # OCSP Stapling
    SSLUseStapling on
    SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"
    
    # Routing
    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com$ [NC]
    RewriteRule ^(.*)$ http://backend-%1$1 [P]
</VirtualHost>

Traefik (Docker/Kubernetes)

# docker-compose.yml
version: '3.8'

services:
  traefik:
    image: traefik:v2.10
    command:
      - "--providers.docker=true"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.letsencrypt.acme.dnschallenge=true"
      - "--certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare"
      - "[email protected]"
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
    environment:
      - [email protected]
      - CF_API_KEY=your-cloudflare-api-key
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./letsencrypt:/letsencrypt
    ports:
      - "443:443"
  
  app:
    image: myapp:latest
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.app.rule=Host(`*.example.com`)"
      - "traefik.http.routers.app.entrypoints=websecure"
      - "traefik.http.routers.app.tls.certresolver=letsencrypt"
      - "traefik.http.routers.app.tls.domains[0].main=example.com"
      - "traefik.http.routers.app.tls.domains[0].sans=*.example.com"

Najczęstsze Problemy i Rozwiązania

Problem 1: Certyfikat Nie Działa dla Głównej Domeny

Objaw:

✅ https://blog.example.com - działa
✅ https://api.example.com - działa
❌ https://example.com - certyfikat invalid

Rozwiązanie: Wildcard *.example.com nie obejmuje głównej domeny. Musisz dodać obie:

certbot certonly --dns-cloudflare \
  -d example.com \
  -d *.example.com

Problem 2: Subdomena Drugiego Poziomu

Objaw:

✅ https://api.example.com - działa
❌ https://v1.api.example.com - certyfikat invalid

Rozwiązanie: Wildcard działa tylko dla jednego poziomu. Potrzebujesz:

# Opcja 1: Dodaj kolejny wildcard
certbot certonly --dns-cloudflare \
  -d *.example.com \
  -d *.api.example.com

# Opcja 2: Multi-level wildcard (rzadko wspierany)
# Niektóre CA oferują multi-level wildcard

Problem 3: DNS Propagacja

Objaw: DNS-01 challenge fails z timeout

Rozwiązanie:

# Zwiększ timeout dla DNS propagation
certbot certonly --dns-cloudflare \
  --dns-cloudflare-propagation-seconds 60 \
  -d example.com \
  -d *.example.com

# Sprawdź DNS przed próbą
dig _acme-challenge.example.com TXT

Problem 4: API Rate Limits

Objaw: Let’s Encrypt zwraca “too many requests”

Rozwiązanie:

# Testuj na staging
certbot certonly --dns-cloudflare \
  --staging \
  -d example.com \
  -d *.example.com

# Po testach użyj produkcji
certbot certonly --dns-cloudflare \
  -d example.com \
  -d *.example.com

Monitoring Certyfikatów Wildcard

Check Script

#!/bin/bash
# check-wildcard.sh

DOMAIN="*.example.com"
CERT_FILE="/etc/ssl/certs/wildcard.example.com.crt"

# Sprawdź datę wygaśnięcia
EXPIRY=$(openssl x509 -in "$CERT_FILE" -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s)
CURRENT_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $CURRENT_EPOCH) / 86400 ))

echo "Certificate for $DOMAIN expires in $DAYS_LEFT days"

if [ $DAYS_LEFT -lt 30 ]; then
    echo "WARNING: Certificate expires soon!"
    # Wyślij alert
    curl -X POST https://your-webhook.com/alert \
      -d "Certificate $DOMAIN expires in $DAYS_LEFT days"
fi

# Sprawdź czy certyfikat jest wildcard
SUBJECT=$(openssl x509 -in "$CERT_FILE" -noout -subject)
if [[ $SUBJECT == *"CN = *.example.com"* ]]; then
    echo "✓ Valid wildcard certificate"
else
    echo "✗ Not a wildcard certificate!"
fi

# Sprawdź czy obejmuje główną domenę
SAN=$(openssl x509 -in "$CERT_FILE" -noout -text | grep -A1 "Subject Alternative Name")
if [[ $SAN == *"DNS:example.com"* ]]; then
    echo "✓ Main domain included in SAN"
else
    echo "✗ Main domain NOT in certificate"
fi

Prometheus Monitoring

# prometheus-rules.yaml
groups:
- name: wildcard-certificates
  rules:
  - alert: WildcardCertificateExpiring
    expr: (ssl_certificate_expiry_seconds{cn="*.example.com"} - time()) / 86400 < 30
    for: 24h
    labels:
      severity: warning
    annotations:
      summary: "Wildcard certificate expiring soon"
      description: "Certificate for *.example.com expires in {{ $value }} days"
  
  - alert: WildcardCertificateExpired
    expr: (ssl_certificate_expiry_seconds{cn="*.example.com"} - time()) < 0
    labels:
      severity: critical
    annotations:
      summary: "Wildcard certificate EXPIRED"
      description: "Certificate for *.example.com has expired!"

CrtMgr Integration

CrtMgr może monitorować certyfikaty wildcard:

  1. Dodaj domenę z wildcard: *.example.com
  2. CrtMgr automatycznie wykryje wildcard
  3. Monitoruje datę wygaśnięcia
  4. Wysyła alerty 30/14/7/1 dni przed wygaśnięciem
  5. API integration dla automatyzacji

Best Practices - Podsumowanie

✅ DO

  1. Używaj DNS-01 Challenge dla wildcard certificates
  2. Dodawaj główną domenę do SAN
  3. Rotuj klucze regularnie (co 3-6 miesięcy)
  4. Monitoruj wygaśnięcie z alertami
  5. Ograniczaj dostęp do klucza prywatnego
  6. Testuj na staging przed produkcją
  7. Dokumentuj gdzie certyfikat jest używany
  8. Backup certyfikatów i kluczy (zaszyfrowane!)

❌ DON’T

  1. Nie używaj wildcard dla pojedynczych domen
  2. Nie współdziel kluczy między środowiskami
  3. Nie przechowuj kluczy w plaintext w repo
  4. Nie ignoruj alertów o wygasających certyfikatach
  5. Nie używaj tego samego klucza latami
  6. Nie daj dostępu do klucza wszystkim
  7. Nie zapomnij o odnowieniu przed wygaśnięciem
  8. Nie zakładaj że wildcard obejmuje wszystkie poziomy subdomen

Checklist Wdrożeniowa

Przed wdrożeniem certyfikatu wildcard:

  • Zweryfikuj czy wildcard jest potrzebny (vs multi-domain)
  • Wybierz metodę challenge (DNS-01 dla wildcard)
  • Skonfiguruj DNS API access
  • Przetestuj na staging environment
  • Dodaj główną domenę do SAN
  • Skonfiguruj automatyczne odnowienie
  • Ustaw monitoring i alerty
  • Ograniczysz permissions na kluczu prywatnym
  • Stwórz backup klucza (zaszyfrowany)
  • Zdokumentuj konfigurację
  • Przetestuj wszystkie subdomeny
  • Skonfiguruj HSTS i OCSP stapling

Podsumowanie

Certyfikaty wildcard to potężne narzędzie, które może znacznie uprościć zarządzanie SSL/TLS dla wielu subdomen. Kluczowe punkty:

  • Używaj rozsądnie - nie dla wszystkiego, ale tam gdzie ma sens
  • Bezpieczeństwo przede wszystkim - wildcard zwiększa ryzyko kompromitacji
  • Automatyzuj - DNS-01 challenge z automatycznym odnowieniem
  • Monitoruj - jeden wygasły wildcard = wszystkie subdomeny w dół
  • Dokumentuj - wiedz gdzie certyfikat jest używany

Potrzebujesz prostego narzędzia do monitorowania certyfikatów wildcard? Sprawdź CrtMgr - automatycznie wykrywa i monitoruje certyfikaty wildcard z alertami przed wygaśnięciem.


Wildcard certificates - używaj mądrze, monitoruj pilnie, śpij spokojnie.

Related Articles