
自動化は、現代の IT にとって不可欠です。このブログ記事では、Hashicorp Vault を介した Ansible 認証情報プラグインの統合について紹介します。Hashicorp Vault とは、シークレット管理および自動化の処理方法を簡単に改善できる、API でアドレス可能なシークレット情報管理のエンジンです。効果的な自動化のために、最新のシステムでは、証明書、データベース認証情報、外部サービスのキー、オペレーティングシステム、ネットワークなどの複数のシークレットが必要とされます。誰がいつシークレット認証情報にアクセスしているのかを把握するのは困難で、プラットフォーム固有であることが多く、キーローテーション、セキュアなストレージ、および詳細な監査ログを異種ツールセットで管理することは、ほぼ不可能です。Red Hat Ansible Tower は、このような問題の多くを単体で解決することができますが、エンタープライズのシークレット管理ソリューションとの統合により、人の手を借りずに、オンデマンドでシークレットを利用できるようになります。
シークレット管理の点から、パスワード認証を SSH 証明書ベースの認証に置き換えることによって、自動化サービスアカウントに関連するリスクをいくらか軽減する方法について説明します。自動化のコンテキストでは、サービスアカウントを使用して、1 つの場所からエンドポイントへのアクセスを許可します。セキュリティに関するベストプラクティスでは、共有アカウントはリスクをもたらす可能性があるとされています。Red Hat Ansible Tower にはパスワードや秘密鍵などを難読化する機能がありますが、オペレーター (人間) が関与するキー生成に伴うリスクには対応していません。Red Hat Ansible Tower を Hashicorp Vault と統合すると、サービス認証情報を定期的にオンデマンドでローテーションできます。
セキュアな認証情報
Kerberos などの手段を用いたシークレットやトークンによってセキュアな認証情報が実装されていますが、Hashicorp Vault は認証方法として SSH 証明書を管理するシームレスなワークフローを提供します。
証明書ベースの認証では、次のようなメリットが得られます。
- 証明書の検証と時間の妥当性が、エンドポイントの CA 証明書によって検証されます。
- 90 日 (またはそれ以下) ごとにアカウントのパスワードをリセットする必要がありません。
- 証明書の使用状況を特定の自動化まで追跡できます。
- 手作業が不要なので、「共有アカウント」が不正ユーザーの手に渡るリスクがありません。
HashiCorp Vaults シークレットエンジンを自動化に活用する
Hashicorp Vault のデプロイ
PKI インフラストラクチャで何をおいても必要なのは、HashiCorp Vault が組み込まれた認証局です。私が使用した Vault 設定の全手順をここに文書化しました。詳細は説明しませんが、SSH クライアント証明書に署名し、自動化アカウントに最大 15 分間のアクセスを許可する PKI インフラストラクチャがビルドされることに注目してください。
Vault はまた、前回認証情報を要求したのはいつかなど、アカウントの監査とログを提供するため、自動化アカウントがいつチェックアウトされ、認証に使用されたか、監査証跡を作成するのに最適です。
Vault では、ロールを使用して Vault からユーザー認証情報にアクセスできるユーザーを管理できるため、ポリシーの実装により、基本ユーザーアクセスとルートレベルアクセスを簡単に分離できます。
私の典型的な LINUX 設定では、Active Directory を使用してユーザーアカウントと POSIX 情報を提供しますが、認証は署名された SSH 証明書を使用して行われます。つまり、アカウントは一元管理され、SSH 証明書ベースの認証は既存のアクセス管理手法と統合されます。
Ansible Tower 認証情報のセットアップ
次に、オンデマンドで認証資格情報を要求する機能を Ansible Tower に付与します。
次の例で、HashiCorp Vault を使用して公開鍵に署名するようにマシン認証情報を構成する方法を示します。
まず、証明書の署名を要求する権限を持つ認証情報を作成する必要があります。これが HashiCorp Vault 認証情報です。私が使用しているトークンは、Vault 内ですでに作成されているユーザー「richard」に属し、Vault インストールドキュメントに記載されているとおり、plain-richard ポリシーによって制限されています。
認証情報 1:「richard-vault」

次に、[TEST] ボタンをクリックすると、Vault の手順で作成済みのパブリック ssh-key の内容を、SSH エージェントの場所、ロール、プリンシパル名と組み合わせて使用して、テストできます。

今度は、SSH アクセスに使用される新しいマシン認証情報が必要になります。
タイプ machine の新しい認証情報を作成し、次のフィールドに入力します。


次のステップに備えて、API コマンドを使用して 2 つの認証情報を組み合わせます。
このステップでは、tower-cli ツールを使用して次のコマンドを発行し、2 つの認証情報の ID を特定しました。
tower-cli credential list
== =========================== ===============
id name credential_type
== =========================== ===============
12 richard-ssh-public-unsigned 1
11 richard-vault 20
== =========================== ===============
次に、この API 呼び出しを使用して、マシン認証情報を HashiCorp Vault 認証情報にリンクします。
curl -sik "https://ansible.bravo.com.au/api/v2/credentials/12/input_sources/" \
--user admin:Fo0B@r \
-H "Content-Type: application/json" \
-X POST \
-d '{"source_credential":11,"input_field_name":"ssh_public_key_data", "metadata": {"public_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8kJkcODjq80ryg6WpKIj+Ytj7z9CP+dtHaeaQ/eFR/69txr1fbbxrsTALVOJKSkcTwlG6JBacKcBXs4jacwfbRjRr7q2K4FRgZ4hygYtM9d/PhG2l7nH5sFzhy4o4sc8kdnXfcWeNdZFH/ySqfvvdexDt+nmeCSlixk5i9wzAhOayDo2EiboN38zbkfC7FiE/gQGlFVeqou4m5dbLXpXz5N/JhwzEbmWTQCckHdlYflro9TLTMVZn1/FN2mjr9ZzuqFzDk4IS8HuBkvbo+9GxcM6qGNGv1h/Af40uetRQcanzEu0AsT98Yo9KSeQ+tsX4dOJq7WEV+LwfactJ3WJj vault@ansible.redhat.local", "secret_path": "ssh", "role": "regular", "valid_principals": "richard"}}'
上記のコマンドによって、[Signed SSH Certificate] フィールドに Vault 認証情報が入力されます。

Ansible Tower の次のステップは、マシン認証情報をジョブテンプレートに関連付けることです。ジョブテンプレートが実行されると、Ansible Tower は、提供された HashiCorp URL とトークンを使用して、HashiCorp Vault SSH Secrets API で未署名の公開鍵データに署名します。Ansible Tower は、id_rsa および id_rsa-cert.pub をその場で生成し、ssh-add を使用してそれらを適用します。

テンプレートを実行すると、Ansible Tower のログから ssh-add プロセスの動作を確認できます。この例では、ログが elasticsearch に送信されているため、検索が簡単になります。

これで、Ansible Tower で richard-ssh-public-unsigned 認証情報を使用すると、裏側ではその都度 Vault によって私の公開鍵に署名されるようになりました。
裏側で何が起こっているのかを、手入力で作業しているものとして説明します。
注:ここでは JSON ペイロードを使用して、キーの内容をカスタマイズしています。
$ export VAULT_ADDR="http://127.0.0.1:8200"
$ vault write \
-field=signed_key \
ssh/sign/regular \
valid_principals="richard" \
public_key=@$HOME/.ssh/id_rsa.pub \
> $HOME/.ssh/cert-signed.pub
これで SSH 証明書が作成されました。内容は次のようになります。
$ ssh-keygen -Lf $HOME/.ssh/cert-signed.pub
Type: ssh-rsa-cert-v01@openssh.com user certificate
Public key: RSA-CERT SHA256:bvXl4AuO8TTPYPoKSLCgQ5BicxU0dSolrz3z4pNGuQ0
Signing CA: RSA SHA256:gZjh7y2CMtE7fmYqnSe0ArkYZdtQ50TW+R8xbs1BxyY
Key ID: "plain-richard"
Serial: 10382493167060316007
Valid: from 2019-10-25T12:10:49 to 2019-10-25T12:25:49
Principals:
richard
Critical Options: (none)
Extensions:
permit-pty
次のような SSH コマンドを発行して、生成したキーでアクセス可能かどうかをテストできます。
ssh -i ~/.ssh/id_rsa -i ~/.ssh/cert-signed.pub richard@3.104.104.20
注:ユーザー richard は、実際には Active Directory ドメイン内に存在するアカウントです。キー検証を実行し、残りの認証プロセスを PAM に渡すのは、SSH デーモンです。
$ id -a
uid=575601162(richard) gid=575600513(domain users) groups=575600513(domain users),575601111(ansible users),575601116(ansible admins
次回のブログ記事では、CyberArk Conjur を使用して同じソリューションを実装します。これは、エンタープライズがセキュアな認証情報を検索および更新するためのもう 1 つの優れたソリューションです。