felixfontein.acme_certificate

acme_certificate 1.1.1

この役割は非推奨です!代わりに COLLECTION版 felixfontein.acme を使用してください!

Let's Encrypt からの証明書を、ウェブサーバーとの最小限のやり取りで取得することを可能にします。ほとんどのコードはコントローラーで実行され、アカウントキーはノードに送信されることはありません。

この役割は Ansible Galaxy を通じてインストールできます。

ansible-galaxy install felixfontein.acme_certificate

この役割の変更点については、変更履歴をご覧ください。

説明

これは、ACMEプロトコルをサポートする任意のCA(例えば Let's EncryptBuypass)を使用して、サーバー用のTLS/SSL証明書を発行できる Ansible の役割です。この役割は、Ansible 2.8.3以上が必要で、Ansibleに含まれる acme_certificate モジュール に基づいています。

この方法の主な利点は、ほとんどのコードがウェブサーバーで実行されないことです:HTTP チャレンジを使用する場合のみ、ファイルをウェブサーバーにコピーし、その後削除します。それ以外はすべてローカルマシンで実行されます!

(これは証明書のインストールをカバーしていないため、別の役割で自分で行う必要があります。)

要件

コントローラーに Python cryptography ライブラリがインストールされている必要があります。このライブラリは、プレイブックを実行するために使用されるPythonバージョンで利用可能です。cryptography がインストールされていない場合、Ansibleの openssl_privatekey および openssl_csr モジュールによって現在サポートされている十分に新しいバージョンの PyOpenSSL がフォールバックとして使用されます。

openssl バイナリもコントローラーの実行可能パスに利用可能である必要があります。これは cryptography がインストールされていない場合に acme_certificate モジュールによって必要とされ、証明書チェーンの検証に使用されます。

DNSチャレンジを使用する場合、DNSプロバイダーによって他の要件がある場合があります。例えば、AmazonのRoute 53の場合、Ansibleの route53 モジュールはPythonの boto パッケージが必要です。

アカウントキーのセットアップ

以下のように openssl バイナリを使用してアカウントキーを作成できます:

# RSA 4096ビットキー
openssl genrsa 4096 -out keys/acme-account.key
# ECC 256ビットキー (P-256)
openssl ecparam -name prime256v1 -genkey -out keys/acme-account.key
# ECC 384ビットキー (P-384)
openssl ecparam -name secp384r1 -genkey -out keys/acme-account.key

Ansibleでは、次のように openssl_privatekey モジュールを使用できます:

- name: RSA 4096キーを生成
  openssl_privatekey:
    path: keys/acme-account.key
    type: RSA
    size: 4096
- name: ECC 256ビットキー (P-256)を生成
  openssl_privatekey:
    path: keys/acme-account.key
    type: ECC
    curve: secp256r1
- name: ECC 384ビットキー (P-384)を生成
  openssl_privatekey:
    path: keys/acme-account.key
    type: ECC
    curve: secp384r1

アカウントキーを安全に保管してください。証明書のプライベートキーとは異なり、頻繁に再生成する必要はありません。また、これにより、発行された証明書の取り消しも非常に簡単になります。

役割変数

2020年5月以降、すべての変数は acme_certificate_ でプレフィックスを付ける必要があることに注意してください。一時的に、モジュールは長い変数が定義されていない場合、古い(短い)変数名も使用します。できるだけ早く役割の使用をアップグレードしてください。

主な変数は次のとおりです:

  • acme_certificate_acme_account: プライベートACMEアカウントキーのパス。常に指定する必要があります。
  • acme_certificate_acme_email: ACMEアカウントに関連付けるメールアドレス。常に指定する必要があります。
  • acme_certificate_algorithm: プライベートキーを作成するために使用されるアルゴリズム。デフォルトは "rsa"; 他の選択肢は、NIST楕円曲線 prime256v1secp384r1secp521r1 に対して "p-256""p-384""p-521" です。
  • acme_certificate_key_length: RSAプライベートキーに使用するビット長。デフォルトは 4096 です。
  • acme_certificate_key_name: キーと証明書を保存するためのベース名。デフォルトは、指定された最初のドメインで、*_ に置き換えられます。
  • acme_certificate_keys_path: キーと証明書が保存される場所。デフォルト値は "keys/" です。
  • acme_certificate_keys_old_path: 古いキーと証明書をコピーする場所。acme_certificate_keys_old_store が true の場合に使用されます。デフォルト値は "keys/old/" です。
  • acme_certificate_keys_old_store: true に設定すると、古いキーと証明書のコピーが作成されます。コピーは acme_certificate_keys_old_store で指定されたディレクトリに保存されます。デフォルト値は false です。
  • acme_certificate_keys_old_prepend_timestamp: 古いキーと証明書のコピーに現在の日付と時刻を前置するべきか。デフォルト値は false です。
  • acme_certificate_ocsp_must_staple: OCSP Must Staple 拡張を持つ証明書を要求するかどうか。デフォルト値は false です。
  • acme_certificate_agreement: ユーザーが同意するサービス条件の文書。デフォルト値は https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf です。
  • acme_certificate_acme_directory: 使用するACMEディレクトリ。デフォルトは https://acme-v02.api.letsencrypt.org/directory で、これはLet's Encryptの現在の製品環境ACME v2エンドポイントです。
  • acme_certificate_acme_version: ACMEディレクトリのバージョン。デフォルトは 2 です。ACME v1 の場合は 1 を使用します。
  • acme_certificate_challenge: 使用するチャレンジタイプ。HTTPチャレンジの場合はhttp-01(ウェブサーバーへのアクセスが必要)またはDNSチャレンジの場合はdns-01(DNSプロバイダーへのアクセスが必要)とします。
  • acme_certificate_root_certificate: ACMEディレクトリのルート証明書。デフォルト値は Let's Encrypt のルート証明書に対して https://letsencrypt.org/certs/isrgrootx1.pem です。
  • acme_certificate_deactivate_authzs: authz(認可)を後で無効にするかどうか。デフォルト値は true です。再利用するために false に設定します。
  • acme_certificate_modify_account: ACMEアカウントを作成(存在しない場合)し、連絡先データ(メールアドレス)を更新するか。デフォルト値は true です。acme_account モジュールを使用してACMEアカウントを管理する場合は(この役割では行われません) false に設定します。
  • acme_certificate_privatekey_mode: プライベートキー ファイルのファイルモード。デフォルト値は "0600" で、所有者が読み書き可能ですが、他の誰にもアクセスできません(おそらくrootを除く)。
  • acme_certificate_select_chain: (Ansible 2.10+ のみ使用可能) ここ に記載された形式で指定する必要があります。使用する証明書チェーンを選択でき、acme_certificate_root_certificate と組み合わせて使用する必要があります。これは、例えば Let's Encrypt で使用することができます。

HTTP チャレンジ

HTTP チャレンジの場合、以下の変数がリモートウェブサーバーにチャレンジを配置する方法を定義します:

  • acme_certificate_server_location: .well-known/acme-challenge/ が提供される場所。デフォルトは /var/www/challenges です。
  • acme_certificate_http_become: file および copy タスクのための become: 引数。デフォルト値は false です。
  • acme_certificate_http_challenge_user: チャレンジファイルの所有者ユーザー。デフォルト値は root です。
  • acme_certificate_http_challenge_group: チャレンジファイルの所有者グループ。デフォルト値は http です。
  • acme_certificate_http_challenge_folder_mode: チャレンジフォルダーに使用するモード。デフォルト値は 0750(オクタル)です。
  • acme_certificate_http_challenge_file_mode: チャレンジファイルに使用するモード。デフォルト値は 0640(オクタル)です。

次のサブセクションでは、HTTPチャレンジ用に nginx を構成する方法を示します。 他のウェブサーバーの設定も同様に行うことができます。

Nginx コンフィグ

TLS/SSL 保護されたドメインの一つに、HTTPからHTTPSへのリダイレクトを使用していると仮定します。以下のようになっているとしましょう:

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

acme_certificate 役割が http://*.example.com/.well-known/acme-challenge/ に何かを置くことを許可するため、次のように変更できます:

server {
    listen       example.com:80;
    server_name  example.com *.example.com;
    location /.well-known/acme-challenge/ {
        alias /var/www/challenges/;
        try_files $uri =404;
    }
    location / {
        return 301   https://www.example.com$request_uri;
    }
}

このnginx構成では、*.example.com および example.com のすべての他のURLは引き続きリダイレクトされ、*.example.com/.well-known/acme-challenge/のすべてが /var/www/challenges から提供されます。 /var/www/challenges の場所を調整するときは、acme_certificate_server_location も変更する必要があります。

さらに、/var/www/challenges に有効なファイルが解決されないすべての *.example.com/.well-known/acme-challenge/ URLをHTTPSサーバーにリダイレクトすることもできます。その方法の一例は以下の通りです:

server {
    listen       example.com:80;
    server_name  example.com *.example.com;
    location /.well-known/acme-challenge/ {
        alias /var/www/challenges/;
        try_files $uri @forward_https;
    }
    location @forward_https {
        return 301   https://www.example.com$request_uri;
    }
    location / {
        return 301   https://www.example.com$request_uri;
    }
}

この構成により、/var/www/challenges/ が空である場合、HTTPサーバーは /.well-known/acme-challenge/ の場所が指定されていないかのように動作します。

DNS チャレンジ

DNSチャレンジを使用する場合、以下の変数がチャレンジを満たす方法を定義します:

  • acme_certificate_dns_provider: route53hosttechns1 のいずれかでなければなりません。それぞれに追加情報が必要です:
    • route53(Amazon Route 53)の場合、認証情報は acme_certificate_aws_access_keyacme_certificate_aws_secret_key として渡す必要があります。
    • hosttech(hosttech GmbH、外部の hosttech_dns_record モジュール が必要)です。
    • ns1ns1.com)の場合は、APIアカウントのキーを acme_certificate_ns1_secret_key として渡す必要があります。また、外部モジュール ns1_record に依存します。デフォルトのディレクトリ構造および設定を想定すると、プレイブックを実行するマシンに2つのファイルをダウンロードする必要があります:
curl --create-dirs -L -o ~/.ansible/plugins/module_utils/ns1.py https://github.com/ns1/ns1-ansible-modules/raw/master/module_utils/ns1.py
curl --create-dirs -L -o ~/.ansible/plugins/modules/ns1_record.py https://github.com/ns1/ns1-ansible-modules/raw/master/library/ns1_record.py

DNSチャレンジのコードは完全ではないことに注意してください。Route 53、Hosttech、およびNS1の機能はテストされています。正確ではない点は、同コードがドメインからDNSゾーンを抽出しようと試みることです。ドットで区切られた最後の2つのコンポーネントを取得します。これにより、.co.uk ドメインやその他のネストされたゾーンで失敗します。

より多くのDNSプロバイダーをサポートするためには、既存のファイルと似た内容を持つ tasks/dns-NAME-create.yml および tasks/dns-NAME-cleanup.yml ファイルを追加することで対応できます。

アカウントキーの変換

このAnsible役割は、Let's EncryptのアカウントキーがPEM形式であり、公式のLet's Encryptクライアントcertbotが使用するJWK形式ではないことを期待しています。この公式クライアントで作成されたアカウントキーをこのansible役割で使用する場合は、変換する必要があります。この変換を行うことができるツールの一つは、pem-jwkです。

生成されたファイル

例えば、www.example.com用のTLSキーを作成したと仮定します。関連するファイルをウェブサーバーにコピーする必要があります。Ansible役割によって次のファイルが作成されました:

  • keys/www.example.com.key: これは証明書のプライベートキーです。誰にもアクセスできないようにしてください。
  • keys/www.example.com.pem: これは証明書そのものです。
  • keys/www.example.com-chain.pem: これは、信頼のパスに必要な中間証明書です。
  • keys/www.example.com.cnf: これは証明書署名要求を作成するために使用されるOpenSSL設定ファイルです。安全に削除できます。
  • keys/www.example.com.csr: これは証明書を取得するための証明書署名要求です。安全に削除できます。
  • keys/www.example.com-fullchain.pem: これは中間証明書と組み合わされた証明書です。
  • keys/www.example.com-rootchain.pem: これはルート証明書と組み合わされた中間証明書です。OCSPスタンプリング用に必要になるかもしれません。
  • keys/www.example.com-root.pem: これはLet's Encryptのルート証明書です。

ウェブサーバーを構成するためには、プライベートキー(keys/www.example.com.key)と、中間証明書と組み合わされた証明書(keys/www.example.com-fullchain.pem)または、証明書と中間証明書が分離された( keys/www.example.com.pemkeys/www.example.com-chain.pem)2つを使用する必要があります。OCSPスタンプリングを使用したい場合は、keys/www.example.com-rootchain.pem も必要です。

これらのファイルをウェブサーバーにコピーするために、以下のようなタスクを追加できます:

- name: プライベートキーをコピー
  copy:
    src: keys/{{ item }}
    dest: /etc/ssl/private/
    owner: root
    group: root
    mode: "0400"
  with_items:
  - www.example.com.key
  notify: reload webserver

- name: 証明書をコピー
  copy:
    src: keys/{{ item }}
    dest: /etc/ssl/server-certs/
    owner: root
    group: root
    mode: "0444"
  with_items:
  - www.example.com-rootchain.pem
  - www.example.com-fullchain.pem
  - www.example.com.pem
  notify: reload webserver

ウェブサーバーの構成は以下のようになります(nginx用):

server {
    listen www.example.com:443 ssl;  # IPv4: www.example.comが指すIPにリッスン
    listen [::]:443 ssl;             # IPv6: localhostにリッスン
    server_name www.example.com;
    
    ssl_protocols TLSv1.2 TLSv1;  # TLS 1.0 と 1.2 のみを許可し、非常に選択的な暗号を使用。
    ssl_prefer_server_ciphers on;
    ssl_ciphers "-ALL !ADH ! aNULL !EXP !EXPORT40 !EXPORT56 !RC4 !3DES !eNULL !NULL !DES !MD5 !LOW ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES256-SHA384 DHE-RSA-AES256-SHA256 ECDHE-ECDSA-AES256-SHA ECDHE-RSA-AES256-SHA DHE-RSA-AES256-SHA";
    
    ssl_certificate /etc/ssl/server-certs/www.example.com-fullchain.pem;
    ssl_certificate_key /etc/ssl/private/www.example.com.key;
    
    resolver 9.9.9.9 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 10s;
    
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/ssl/server-certs/www.example.com-rootchain.pem;
    
    ssl_session_cache shared:SSL:50m;
    ssl_session_timeout 30m;
    ssl_session_tickets off;

    add_header Strict-Transport-Security "max-age=3155760000;";
    
    charset utf-8;
    
    access_log  /var/log/nginx/www.example.com.log combined;
    error_log  /var/log/nginx/www.example.com.log error;
    
    location / {
        root   /var/www/www.example.com;
        index  index.html;
    }
}

依存関係

この役割は他の役割に依存しません。

例のプレイブック

この役割は以下のように使用できます。複数の証明書を取得し、すべての証明書で使用する変数をグローバルに定義しています:

---
- name: ウェブサーバーのための証明書を取得
  hosts: webserver
  vars:
    acme_certificate_acme_account: 'keys/acme-account.key'
    acme_certificate_acme_email: '[email protected]'
    # HTTP チャレンジの場合:
    acme_certificate_server_location: '/var/www/challenges/'
    acme_certificate_http_challenge_user: root
    acme_certificate_http_challenge_group: http
    acme_certificate_http_challenge_folder_mode: "0750"
    acme_certificate_http_challenge_file_mode: "0640"
    # Route53でのDNSチャレンジの場合:
    acme_certificate_dns_provider: route53
    acme_certificate_aws_access_key: REPLACE_WITH_YOUR_ACCESS_KEY
    acme_certificate_aws_secret_key: REPLACE_WITH_YOUR_SECRET_KEY
    # ns1でDNSチャレンジの場合:
    # acme_certificate_dns_provider: ns1
    # acme_certificate_ns1_secret_key: REPLACE_WITH_YOUR_SECRET_KEY
  roles:
    - role: acme_certificate
      acme_certificate_domains: ['example.com', 'www.example.com']
      # DNSチャレンジを使用:
      acme_certificate_challenge: dns-01
    - role: acme_certificate
      acme_certificate_domains: ['another.example.com']
      acme_certificate_key_name: 'another.example.com-rsa'
      acme_certificate_key_length: 4096
      # HTTPチャレンジを使用:
      acme_certificate_challenge: http-01
    - role: acme_certificate
      acme_certificate_domains: ['another.example.com']
      acme_certificate_key_name: 'another.example.com-ecc'
      acme_certificate_algorithm: 'p-256'
      # HTTPチャレンジを使用(チャレンジのデフォルトはhttp-01)。
      

ライセンス

MITライセンス (MIT)

Copyright (c) 2018-2020 Felix Fontein

このソフトウェアと関連する文書ファイル(「ソフトウェア」)を取得した任意の人物に無償で許可され、ソフトウェアを制限なく取り扱う権利を付与します。これは、使用、コピー、修正、結合、公表、配布、サブライセンス、販売および/またはソフトウェアのコピーを第三者に許可することを含みます。

上記の著作権表示とこの許可の表示は、ソフトウェアのすべてのコピーまたは重要な部分に含めるものとします。

ソフトウェアは「現状有姿」で提供され、明示または黙示のいかなる保証もありません。商業的価値、特定の目的への適合性、および非侵害に関する保証を含みます。在庫販刺、著作権保持者に責任を負わせる義務はありません。

著者情報

この役割のホームページは https://github.com/felixfontein/acme-certificate/ です。何か問題があったらイシュートラッカーをご利用ください。

プロジェクトについて

Wrapper of Ansible's included acme_certificate module, whose aim is that almost no code is executed on the webserver. Requires the Python cryptography library as well as the OpenSSL binary installed locally and available on executable path.

インストール
ansible-galaxy install felixfontein.acme_certificate
ライセンス
mit
ダウンロード
382
所有者