SSL-Zertifikat mit Let’s Encrypt generieren (DNS-01-Challenge)

SSL-Zertifikat mit Let’s Encrypt generieren (DNS-01-Challenge)

Ich versuche, mit Ansible ein SSL-Zertifikat für *.rasp.example.comund zu generieren rasp.example.com.

Ich habe bereits eine „funktionierende“ Lösung (keine Fehler beim Bereitstellen), aber wenn ich versuche, sie mit certbot zu vergleichen, habe ich einige csr, crt, keywährend certbot nur 2 Dateien zurückgibt pem(Schlüssel und Zertifikat).

Beim Browser habe ich ein Problem. Beispielsweise funktioniert https für, rasp.example.comaber nicht für, *.rasp.example.comselbst wenn ich einen alternativen DNS-Namen hinzufüge.

Meine Rolle :

- name: Certificate - set facts
  ansible.builtin.set_fact:
      account_key_path: /etc/ssl/private/account.key
      key_path: /etc/ssl/private/rasp.example.com.key

      crt_path: /etc/ssl/certs/rasp.example.com.crt
      crt_fullchain_path: /etc/ssl/certs/rasp.example.com-fullchain.crt

      csr_path: /etc/ssl/certs/rasp.example.com.csr

      acme_directory: https://acme-v02.api.letsencrypt.org/directory
      acme_challenge_type: dns-01
      acme_version: 2
      acme_email: [email protected]

      zone: example.com
      subdomain: rasp

- name: Generate let's encrypt account key
  community.crypto.openssl_privatekey:
      path: "{{ account_key_path }}"

- name: Create private key (RSA, 4096 bits)
  community.crypto.openssl_privatekey:
      path: "{{ key_path }}"

- name: Generate an OpenSSL Certificate Signing Request
  community.crypto.openssl_csr:
      path: "{{ csr_path }}"
      privatekey_path: "{{ key_path }}"
      common_name: "*.{{ subdomain }}.{{ zone }}"
      subject_alt_name: "DNS:{{ subdomain + '.' + zone }}" # for rasp.example.com

- name: Make sure account exists and has given contacts. We agree to TOS.
  community.crypto.acme_account:
      account_key_src: "{{ account_key_path }}"
      acme_directory: "{{ acme_directory }}"
      acme_version: "{{ acme_version }}"
      state: present
      terms_agreed: true
      contact:
          - mailto:[email protected]

- name: Create a challenge using a account key file.
  community.crypto.acme_certificate:
      account_key_src: "{{ account_key_path }}"
      account_email: "{{ acme_email }}"
      src: "{{ csr_path }}"
      fullchain_dest: "{{ crt_fullchain_path }}"
      challenge: dns-01
      acme_directory: "{{ acme_directory }}"
      acme_version: 2
      terms_agreed: true
      remaining_days: 60
      force: true
  register: challenge

- name: Certificate does not exists or needs to be renewed
  when: challenge["challenge_data"] is defined and (challenge["challenge_data"] | length > 0)
  block:
      - name: Set challenge data
        ansible.builtin.set_fact:
            challenge: "{{ challenge }}"

      - name: Upload OVH credentials
        ansible.builtin.template:
            src: ovh.conf.j2
            dest: /root/.ovh.conf
            owner: root
            group: root
            mode: 0600

      - name: Create DNS challenge record on OVH
        ansible.builtin.script:
            cmd: "dns.py create {{ zone }} TXT -t {{ item.value['dns-01'].resource_value }} -s {{ item.value['dns-01'].resource }}.{{ subdomain }}"
        args:
            executable: python3
            chdir: /root
        with_dict: "{{ challenge['challenge_data'] }}"

      - name: Let the challenge be validated and retrieve the cert and intermediate certificate
        community.crypto.acme_certificate:
            account_key_src: "{{ account_key_path }}"
            account_email: "{{ acme_email }}"
            src: "{{ csr_path }}"
            dest: "{{ crt_path }}"
            fullchain_dest: "{{ crt_fullchain_path }}"
            challenge: dns-01
            acme_directory: "{{ acme_directory }}"
            acme_version: 2
            terms_agreed: true
            remaining_days: 60
            data: "{{ challenge }}"
        notify:
            - Delete DNS challenge record on OVH

Ich verwende OVH als DNS und habe ein einfaches .pySkript erstellt, das einen TXT-Eintrag hinzufügt/löscht.

Außerdem verwende ich NGINX als Webserver:

listen 443 ssl;
    ssl_certificate     /etc/ssl/certs/rasp.example.com.crt;
    ssl_certificate_key /etc/ssl/private/rasp.example.com.key;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;

Mache ich hier etwas falsch?

Antwort1

Sie verwenden das Platzhalterzertifikat für *.rasp.example.com, aber nicht für. rasp.example.comSie sollten sowohl den Platzhalter als auch die Basisdomäne in die alternativen Antragstellernamen aufnehmen.

Aktualisieren Sie openssl_csrdie Aufgabe Ansiblefolgendermaßen:

- name: Generate an OpenSSL Certificate Signing Request
  community.crypto.openssl_csr:
      path: "{{ csr_path }}"
      privatekey_path: "{{ key_path }}"
      common_name: "*.{{ subdomain }}.{{ zone }}"
      subject_alt_name:
        - "DNS:*.{{ subdomain }}.{{ zone }}"
        - "DNS:{{ subdomain }}.{{ zone }}" # for rasp.example.com

dann ist es in Ihrer NginxKonfiguration besser, das Fullchain-Zertifikat statt nur das Zertifikat zu verwenden:

listen 443 ssl;
ssl_certificate     /etc/ssl/certs/rasp.example.com-fullchain.crt;
ssl_certificate_key /etc/ssl/private/rasp.example.com.key;
ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers         HIGH:!aNULL:!MD5;

verwandte Informationen