dhach.acme_letsencrypt

acme-letsencrypt

CI release Ansible Galaxy

概要

これは、次の目的を達成するための純粋なAnsibleロールです。

  • ECCまたはRSAの秘密鍵を作成する
  • 証明書署名要求を生成する(複数のドメイン向け)
  • リクエストをLet's Encryptまたは好きなACMEプロバイダーに送信する
  • すべてのファイルを決定論的な場所にインストールする

私はこのロールを、certbotやacme-tiny、acme.shなどのサードパーティツールに頼らずにLet's Encryptの証明書を取得する手段を提供するために作成しました。これにより、何が行われているかをよりコントロールできます。

現在、HTTPチャレンジタイプのみがサポートされています。

これはAnsibleロールだけなので、自動的な証明書更新は処理しません。これを達成するには、CI/CDパイプラインから定期的にこのロールを実行するか、cronタブを使用してAnsibleプルモードで動作させることができます。

Ansibleバージョン

このロールは、リリース2.0.0以降、Ansible >=2.10との互換性が保証されます。

<2.10の互換性が必要な場合(「プレコレクション」)、1.x.xタグのリリースを使用してください。

要件

ターゲットホストで:

  • openssl

使用例プレイブック

SAN証明書(複数のドメイン)用のsecp384r1 ECCキーを使用します。

- name: "webserver01の証明書を取得"
  hosts: webserver01
  become: true
  roles:
    - dhach.acme_letsencrypt
  vars:
    le_base_directory: /etc/letsencrypt
    le_certificates:
      - name: ecc.example.com
        domains:
          - secp.example.com
          - ecc.example.com
        key:
          curve: secp384r1

次に、secp256r1キーを使用し、強制的に再作成し、Let's Encryptの本番検証サーバーに対してリクエストを発行します:

- name: "webserver02の証明書を取得"
  hosts: webserver02
  become: true
  roles:
    - dhach.acme_letsencrypt
  vars:
    le_acme_directory: https://acme-v02.api.letsencrypt.org/directory
    le_certificates:
      - name: another-domain.example.com
        domains:
          - another-domain-abc.example.com
          - another-domain-def.example.com
          - another-domain-ghi.example.com
          - another-domain-jkl.example.com
          - another-domain-mno.example.com
        ssl:
          type: ECC
          curve: secp256r1
          renew: true

または、RSAキーを使用して各ドメインごとに1つの証明書を取得します:

- name: "webserver03の証明書を取得"
  hosts: webserver03
  become: true
  roles:
    - dhach.acme_letsencrypt
  vars:
    le_certificates:
      - name: example.com
        domains:
          - foo.example.com
        key:
          type: RSA
          size: 4096
      - name: more.example.com
        domains:
          - bar.example.com
        key:
           type: RSA
           size: 4096

ファイルの場所

すべての生成された鍵や証明書要求、その後の証明書は、{{ le_base_directory }}/{{ le_certificates['name'] }}の値の下に見つかります。

例えば、nameを'example.com'に設定し、le_base_directoryが'/etc/letsencrypt/'に設定されている場合、結果は次のようになります:

/etc/letsencrypt/example.com/
├── domain.csr
├── domain.key
├── domain.pem
├── fullchain.pem
└── intermediate.pem

ウェブサーバーの設定方法

ACMEサーバーは、特定の名前と内容のファイルをHTTP経由で提供するプリ定義されたパスに入れることによってチャレンジに応じる必要があります。

ウェブサーバーは、* /.well-known/acme-challenge *の位置を{{ le_base_directory }}/.well-known/acme-challenge/の内容で提供する必要があります。

le_base_directoryのデフォルト値を使用している場合の例:

Nginx:

location /.well-known/acme-challenge {
    alias /etc/letsencrypt/.well-known/acme-challenge/;

}

Apache:

Alias /.well-known/acme-challenge/ "/etc/letsencrypt/.well-known/acme-challenge/"
<Directory "/etc/letsencrypt/.well-known/acme-challenge/">
    AllowOverride None
    Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
    Require method GET POST OPTIONS
</Directory>

ロール変数とデフォルト値

以下に定義されているすべての変数がリストされています。それぞれのデフォルト変数も示されています。

証明書要求

証明書を要求するドメインを制御できます。また、鍵生成に関する詳細を指定するオプションもあります。オプションはRSAとECCキーの間でわずかに異なります。

すべての証明書要求はSAN(SubjectAltName)要求として構築されます。

ECC:

le_certificates:
  - name: example.com  # 実質的には内部識別子で、ファイルを保存する場所
    domains:  # 証明書を発行してほしいドメインのリスト
      - foo.example.com
      - bar.example.com
    key:  # 秘密鍵を生成する場合の詳細
      type: ECC  # (必須)サポートされているタイプ: ECC, RSA
      curve: secp384r1  # (オプション | デフォルト: secp384r1)ECCキーの曲線(RSAキーには影響なし)。
      renew: false  # (オプション | デフォルト: false)キーを強制的に再作成するかどうか。常にバックアップを保持します。

RSA:

le_certificates:
  - name: example.com  # 実質的には内部識別子で、ファイルを保存する場所
    domains:  # 証明書を発行してほしいドメインのリスト
      - foo.example.com
      - bar.example.com
    key:  # 秘密鍵を生成する場合の詳細
      type: RSA  # (必須)サポートされているタイプ: ECC, RSA
      size: 4096  # (オプション | デフォルト: 4096)RSAキーの長さ(ECCキーには影響なし)
      renew: false  # (オプション | デフォルト: false)キーを強制的に再作成するかどうか。常にバックアップを保持します。

ディレクトリと権限

le_base_directory: 生成されたすべてのファイルを置くための基本ディレクトリ(デフォルト: /etc/letsencrypt)

le_files_owner: 生成されたファイルとフォルダーの所有者(デフォルト: root)

le_files_group: 生成されたファイルとフォルダーが属するグループ(デフォルト: root)

Let's Encryptアカウントキー

le_account_key_path: Let's Encryptアカウントキーを置く(または見つける)場所(デフォルト: "{{ le_base_directory }}/account.key")

le_account_key_type: アカウントキーに使用するキータイプ(RSA, ECC)(デフォルト: RSA)

le_account_key_size: キーのサイズ。RSAキーの場合のみ。(デフォルト: 4096)

le_account_key_curve: 使用する曲線。ECCキーの場合のみ、RSAキーには影響なし。(デフォルト: secp384r1)

le_account_key_regenerate: 既存のキーを再生成するかどうか。バックアップを保持します。(デフォルト: false)

残念ながら、Let's EncryptはECCアカウントキーをすぐにはサポートしていません。RSA 4096に設定しておくのがベストです。

Let's Encrypt / ACMEバージョンとディレクトリ

le_acme_version: 使用するACMEバージョンです。他の発行者を選択した場合に必要になることがあります(デフォルト: 2)

le_acme_directory: 証明書をリクエストするためのACMEディレクトリURL。安全上の理由から、デフォルトはLet's Encryptのステージングに設定されています(デフォルト: https://acme-staging-v02.api.letsencrypt.org/directory

Let's Encryptの本番ディレクトリは、https://acme-v02.api.letsencrypt.org/directoryです。

le_renew_if_invalid_after: 有効期限がこの日数未満の場合に証明書を更新しようとします(デフォルト: 30)

le_force_renew: 証明書を強制的に更新しようとします(デフォルト: false)

le_csr_only: プライベートキーとCSRのみ生成する場合は、これをtrueに設定します。デバッグに役立つ場合があります。(デフォルト: false)

貢献と問題

すべての貢献を歓迎します。問題を開いたり、プルリクエストを作成することをためらわないでください。

挙げられた問題について喜んで検討しますし、常にこのロールを改善しようと努めます。

テスト

すべてのテストはMoleculeで行われます。

CIパイプラインはGitHub Actionsで実現されており、マトリックス戦略を使用して、Ubuntu、Debian、CentOSでテストを行います。

ローカルテストを開始するには、ローカルPython venvを設定し、すべての依存関係をインストールしてテストを実行します。このためには、マシンにDockerがインストールされている必要があります(またはDocker-Machineを使用):

python3 -m venv venv
source venv/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install -r test-requirements.txt

molecule test

このロールは基本的にACMEサーバーに対してリクエストを発行する必要があるため、DNSレコードを動的に設定するドメインの管理が必要です。そのため、テストはリント、鍵とCSRが作成されて存在し、期待される内容が含まれているかどうかを確認することに制限されます。

すべての機能を持つ完全なロールをテストするのは、実際にインターネットに接続されたマシンでLet's Encryptのステージングサーバーに対して手動で行います。

ライセンス

GNU一般公衆ライセンスバージョン3.0

プロジェクトについて

Requests certificates from Let's Encrypt (or another ACME server)

インストール
ansible-galaxy install dhach.acme_letsencrypt
ライセンス
gpl-3.0
ダウンロード
103
所有者