К основному содержанию
скилл CX Codex

ssl-tls-management — скилл для Claude Code: сертификаты и HTTPS

Скилл для работы с SSL/TLS: выпуск сертификатов Let's Encrypt, автопродление, cert-manager в Kubernetes и подбор шифров. Пригодится, когда настраиваешь HTTPS или чинишь истёкший сертификат.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add BagelHole/DevOps-Security-Agent-Skills --skill ssl-tls-management -a claude-code
Открыть на GitHub

Что делает ssl-tls-management

Скилл закрывает весь путь сертификата: от выпуска через certbot до автоматического продления и разбора шифров через openssl. Внутри — готовые команды для nginx, standalone-режима и DNS-челленджа, включая wildcard-сертификаты. Для Kubernetes описан cert-manager через Helm с примерами ClusterIssuer и Certificate.

Продление настраивается через systemd-таймер, который запускает certbot renew дважды в день, плюс deploy-хуки для перезагрузки nginx и haproxy после обновления. Есть отдельный раздел по openssl: генерация ключей RSA и ECDSA, создание CSR с SAN и самоподписанные сертификаты для разработки.

Заранее понадобится домен с доступом к DNS для публичных сертификатов, root на веб-сервере и установленный certbot. Для внутренних сервисов в Kubernetes нужен кластер с Helm. Если DNS-записи нет, HTTP-челлендж не пройдёт — это повод сначала проверить, куда указывает домен.

Какие задачи решает

  • выпустить сертификат Let's Encrypt для нового домена
  • настроить автопродление, чтобы HTTPS не падал
  • развернуть cert-manager и выдать TLS в Kubernetes
  • сгенерировать CSR с SAN для внутреннего центра сертификации
  • проверить шифры и версии TLS перед аудитом

Примеры запросов агенту

  • Настрой HTTPS для example.com через certbot с автопродлением
  • Поставь cert-manager в кластер и выпусти wildcard-сертификат для *.example.com
  • Сгенерируй самоподписанный сертификат для локальной разработки

Как установить ssl-tls-management

1Через Skills CLI (Vercel)

npx skills add BagelHole/DevOps-Security-Agent-Skills --skill ssl-tls-management -a claude-code

2Вручную: положить файлы

~/.claude/skills/ssl-tls-management/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/ssl-tls-management/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о ssl-tls-management

Как установить ssl-tls-management в Claude?

Выполни npx skills add BagelHole/DevOps-Security-Agent-Skills --skill ssl-tls-management -a claude-code. Скилл появится в ~/.claude/skills/ssl-tls-management/SKILL.md.

Что делает ssl-tls-management?

Помогает выпускать и продлевать сертификаты Let's Encrypt, настраивать cert-manager в Kubernetes и разбираться с шифрами через openssl.

Что нужно для работы скилла?

Домен с контролем DNS для публичных сертификатов, root-доступ на веб-сервере и установленный certbot. Для Kubernetes — кластер с Helm.

Исходный текст

SKILL.md · MIT
---
name: ssl-tls-management
description: Manage SSL/TLS certificates with Let's Encrypt and internal PKI. Configure secure HTTPS, certificate renewal, and cipher suites. Use when implementing secure communications.
license: MIT
metadata:
  author: devops-skills
  version: "1.0"
---

# SSL/TLS Management

Manage certificates and secure communications across web servers, Kubernetes clusters, and internal services.

## When to Use This Skill

Use this skill when:
- Setting up HTTPS for a new web application
- Automating certificate renewal with Let's Encrypt
- Deploying cert-manager in Kubernetes
- Configuring TLS for internal service-to-service communication
- Auditing cipher suites and TLS versions for compliance
- Responding to an expiring or compromised certificate

## Prerequisites

- Domain name with DNS control for public certificates
- Root/sudo access on web servers
- `certbot` installed for Let's Encrypt
- `openssl` CLI available (installed by default on most Linux distros)
- Kubernetes cluster with Helm for cert-manager deployment
- Understanding of X.509 certificate chain of trust

## Let's Encrypt with Certbot

### Installation and Certificate Issuance

```bash
# Install certbot (Ubuntu/Debian)
apt update && apt install -y certbot python3-certbot-nginx

# Obtain certificate for nginx (interactive)
certbot --nginx -d example.com -d www.example.com

# Non-interactive mode for automation
certbot certonly --nginx \
  -d example.com \
  -d www.example.com \
  --non-interactive \
  --agree-tos \
  --email [email protected]

# Standalone mode (when no web server is running)
certbot certonly --standalone \
  -d example.com \
  --preferred-challenges http

# DNS challenge (for wildcard certs)
certbot certonly --manual \
  --preferred-challenges dns \
  -d "*.example.com" \
  -d example.com

# Using DNS plugin for automation (Cloudflare example)
pip install certbot-dns-cloudflare
cat > /etc/letsencrypt/cloudflare.ini << 'EOF'
dns_cloudflare_api_token = YOUR_CLOUDFLARE_API_TOKEN
EOF
chmod 600 /etc/letsencrypt/cloudflare.ini

certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
  -d "*.example.com" \
  -d example.com
```

### Renewal Automation

```bash
# Test renewal
certbot renew --dry-run

# Systemd timer (preferred over cron)
cat > /etc/systemd/system/certbot-renewal.service << 'EOF'
[Unit]
Description=Certbot certificate renewal
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew --quiet --deploy-hook "systemctl reload nginx"
EOF

cat > /etc/systemd/system/certbot-renewal.timer << 'EOF'
[Unit]
Description=Run certbot renewal twice daily

[Timer]
OnCalendar=*-*-* 00,12:00:00
RandomizedDelaySec=3600
Persistent=true

[Install]
WantedBy=timers.target
EOF

systemctl enable --now certbot-renewal.timer

# Verify timer is active
systemctl list-timers certbot-renewal.timer

# Renewal hooks for post-renewal actions
mkdir -p /etc/letsencrypt/renewal-hooks/deploy
cat > /etc/letsencrypt/renewal-hooks/deploy/reload-services.sh << 'HOOK'
#!/bin/bash
systemctl reload nginx
# Also reload other services using the cert
systemctl reload haproxy 2>/dev/null || true
HOOK
chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-services.sh
```

## cert-manager for Kubernetes

### Installation

```bash
# Install with Helm
helm repo add jetstack https://charts.jetstack.io
helm repo update

helm install cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --version v1.14.0 \
  --set installCRDs=true \
  --set prometheus.enabled=true

# Verify installation
kubectl get pods -n cert-manager
kubectl get crds | grep cert-manager
```

### ClusterIssuer Configurations

```yaml
# letsencrypt-staging (use for testing first)
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-staging
    solvers:
      - http01:
          ingress:
            class: nginx
---
# letsencrypt-prod
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
      - http01:
          ingress:
            class: nginx
---
# DNS challenge solver (for wildcard certs with Cloudflare)
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod-dns
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-prod-dns
    solvers:
      - dns01:
          cloudflare:
            apiTokenSecretRef:
              name: cloudflare-api-token
              key: api-token
---
# Self-signed CA issuer for internal services
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: selfsigned-ca
spec:
  selfSigned: {}
```

### Certificate Resources

```yaml
# Public-facing certificate
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: example-cert
  namespace: default
spec:
  secretName: example-tls
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  dnsNames:
    - example.com
    - www.example.com
  duration: 2160h    # 90 days
  renewBefore: 720h  # 30 days before expiry
---
# Wildcard certificate
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: wildcard-cert
  namespace: default
spec:
  secretName: wildcard-tls
  issuerRef:
    name: letsencrypt-prod-dns
    kind: ClusterIssuer
  dnsNames:
    - "*.example.com"
    - example.com
---
# Ingress with automatic TLS
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
    - hosts:
        - example.com
      secretName: example-tls
  rules:
    - host: example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web
                port:
                  number: 80
```

## OpenSSL Commands Reference

```bash
# Generate a private key
openssl genrsa -out server.key 4096

# Generate an ECDSA key (preferred for performance)
openssl ecparam -genkey -name prime256v1 -out server-ec.key

# Generate a CSR (Certificate Signing Request)
openssl req -new -key server.key -out server.csr \
  -subj "/C=US/ST=California/L=San Francisco/O=Acme Corp/CN=example.com"

# Generate CSR with SAN (Subject Alternative Names)
openssl req -new -key server.key -out server.csr -config <(cat <<EOF
[req]
default_bits = 4096
distinguished_name = dn
req_extensions = san
prompt = no

[dn]
CN = example.com
O = Acme Corp
C = US

[san]
subjectAltName = DNS:example.com,DNS:www.example.com,DNS:api.example.com
EOF
)

# Generate self-signed certificate (development/testing)
openssl req -x509 -nodes -days 365 -newkey rsa:4096 \
  -keyout selfsigned.key -out selfsigned.crt \
  -subj "/CN=localhost"

# View certificate details
openssl x509 -in cert.pem -noout -text

# Check certificate expiration date
openssl x509 -in cert.pem -noout -dates

# Check remote certificate
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | \
  openssl x509 -noout -dates -subject -issuer

# Verify certificate chain
openssl verify -CAfile ca-bundle.crt server.crt

# Check certificate chain from remote server
openssl s_client -connect example.com:443 -showcerts 2>/dev/null | \
  openssl x509 -noout -text

# Convert PEM to PKCS12
openssl pkcs12 -export -out cert.pfx -inkey server.key -in server.crt -certfile ca.crt

# Convert PKCS12 to PEM
openssl pkcs12 -in cert.pfx -out cert.pem -nodes

# Test TLS connection and cipher negotiation
openssl s_client -connect example.com:443 -tls1_3
openssl s_client -connect example.com:443 -cipher 'ECDHE-RSA-AES256-GCM-SHA384'
```

## Strong TLS Configuration

### Nginx

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

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # Protocol versions
    ssl_protocols TLSv1.2 TLSv1.3;

    # Cipher suites (TLS 1.2)
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    # Session settings
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;

    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;

    # Security headers
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    add_header X-Content-Type-Options nosniff always;
    add_header X-Frame-Options DENY always;

    # HTTP to HTTPS redirect (in separate server block)
}

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}
```

### Apache

```apache
<VirtualHost *:443>
    ServerName example.com

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

    SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
    SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
    SSLHonorCipherOrder off

    SSLUseStapling on
    SSLStaplingCache shmcb:/tmp/stapling_cache(128000)

    Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
</VirtualHost>
```

## Certificate Monitoring

```bash
#!/bin/bash
# cert-monitor.sh - Monitor certificate expiration across hosts

WARN_DAYS=30
CRIT_DAYS=7
HOSTS=(
  "example.com:443"
  "api.example.com:443"
  "admin.example.com:443"
)

for host in "${HOSTS[@]}"; do
  expiry=$(echo | openssl s_client -connect "$host" -servername "${host%%:*}" 2>/dev/null | \
    openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)

  if [ -z "$expiry" ]; then
    echo "ERROR: Cannot connect to $host"
    continue
  fi

  expiry_epoch=$(date -d "$expiry" +%s)
  now_epoch=$(date +%s)
  days_left=$(( (expiry_epoch - now_epoch) / 86400 ))

  if [ "$days_left" -le "$CRIT_DAYS" ]; then
    echo "CRITICAL: $host expires in $days_left days ($expiry)"
  elif [ "$days_left" -le "$WARN_DAYS" ]; then
    echo "WARNING: $host expires in $days_left days ($expiry)"
  else
    echo "OK: $host expires in $days_left days ($expiry)"
  fi
done
```

### Prometheus cert-manager Metrics

```yaml
# Alert on expiring certificates in Kubernetes
groups:
  - name: cert-manager
    rules:
      - alert: CertificateExpiringSoon
        expr: certmanager_certificate_expiration_timestamp_seconds - time() < 7 * 24 * 3600
        for: 1h
        labels:
          severity: critical
        annotations:
          summary: "Certificate {{ $labels.name }} expires in less than 7 days"

      - alert: CertificateNotReady
        expr: certmanager_certificate_ready_status{condition="True"} == 0
        for: 15m
        labels:
          severity: warning
        annotations:
          summary: "Certificate {{ $labels.name }} is not ready"
```

## Troubleshooting

| Problem | Cause | Solution |
|---------|-------|----------|
| Certbot fails with "connection refused" | Port 80 blocked by firewall | Open port 80 for ACME HTTP-01 challenge |
| "Too many certificates already issued" | Let's Encrypt rate limit hit | Use staging endpoint for testing; wait for rate limit reset |
| cert-manager challenge stuck pending | Ingress or DNS misconfigured | Check `kubectl describe challenge`; verify DNS records |
| Mixed content warnings | HTTP resources on HTTPS page | Update all asset URLs to HTTPS; use CSP headers |
| OCSP stapling not working | Resolver not configured | Add `resolver` directive in nginx; verify outbound DNS |
| Intermediate cert missing | Incomplete chain served | Use `fullchain.pem` not `cert.pem`; verify with `openssl s_client -showcerts` |
| TLS handshake failure | Client doesn't support offered ciphers | Add TLS 1.2 support; check cipher suite compatibility |

## Best Practices

- Automate renewal with systemd timers or cert-manager
- Monitor expiration dates with alerting (30-day and 7-day warnings)
- Use only TLS 1.2 and TLS 1.3
- Enable HSTS with long max-age and includeSubDomains
- Enable OCSP stapling to improve handshake performance
- Use ECDSA keys for better performance where possible
- Test configuration with SSL Labs (ssllabs.com/ssltest)
- Keep private keys secure with proper file permissions (0600)
- Rotate certificates before expiry, not after
- Maintain a certificate inventory across all services

## Related Skills

- [hashicorp-vault](../../secrets/hashicorp-vault/) - PKI management
- [waf-setup](../waf-setup/) - Web protection
- [zero-trust](../zero-trust/) - mTLS and identity-based access

© devops-skills · MIT · BagelHole/DevOps-Security-Agent-Skills

Похожие скиллы

Всё по теме «DevOps и инфраструктура» →
secrets-management Seth Hobson Скилл помогает хранить и подключать секреты в CI/CD через Vault, AWS Secrets Manager и платформенные хранилища. Подойдёт для ключей, паролей и ротации. CX Codex 13 122установок akka-net-management Aaronontheweb Скилл подсказывает агенту, как настроить Akka.Management и Cluster Bootstrap: динамическое обнаружение узлов, health-эндпоинты, работа в Kubernetes и Azure. CX Codex +1 409установок github-actions-templates Seth Hobson Скилл создаёт GitHub Actions для тестирования, сборки и деплоя. Подойдёт, когда в проекте нужно настроить CI/CD или reusable workflows. CX Codex 17 420установок kubernetes-specialist https://github.com/Jeffallan Скилл помогает создавать и проверять Kubernetes-манифесты, настраивать безопасность и разбирать сбои подов. Пригодится для деплоя и сопровождения кластерных workloads. CX Codex +1 14 100установок gke-networking официальный google Скилл планирует и настраивает сетевую часть кластеров GKE: приватные узлы, VPC-native, DNS, egress и Dataplane V2. CX Codex 6 551установок gke-app-onboarding официальный google Скилл проводит приложение от оценки и контейнеризации до манифестов и запуска в GKE. Подходит для первого деплоя или переноса приложения. CX Codex 6 489установок

Из того же набора127

windows-server Скилл для администрирования Windows Server: роли и компоненты, сайты IIS, пользователи Active Directory, обновления. Пригодится, когда агент работает с Windows-инфраструктурой. CX Codex +1 449установок container-hardening Настраивает запуск контейнеров без root-прав, монтирует файловую систему только для чтения и формирует манифесты Kubernetes securityContext. CX Codex +1 433установок vulnerability-scanning Скилл для поиска и приоритизации уязвимостей в системах и зависимостях: Nessus, OpenVAS, Qualys, Nuclei. Пригодится при аудите и комплаенсе. CX Codex +1 424установок postgresql Помогает администрировать PostgreSQL: настраивать репликацию, резервные копии и параметры производительности. Пригодится при развёртывании и тюнинге БД. CX Codex +1 419установок hashicorp-vault Скилл для работы с HashiCorp Vault: секретные движки, методы аутентификации, политики и выпуск сертификатов прямо из чата с агентом. CX Codex +1 413установок backup-recovery Скилл настраивает резервное копирование и восстановление через rsync и Restic. Пригодится при настройке бэкапов на диск, в AWS S3 или Backblaze B2 по правилу 3-2-1. CX Codex +1 406установок database-backups Скилл для ИИ-агента: помогает настроить автоматические бэкапы PostgreSQL, MySQL и MongoDB и проверить, что из них реально восстанавливаются данные. CX Codex +1 405установок sops-encryption Скилл учит агента шифровать конфиги и секреты Kubernetes через Mozilla SOPS с ключами AWS KMS, GCP KMS или PGP. Пригодится, когда секреты лежат в Git. CX Codex +1 403установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой