--- discourse: 13114 relatedlinks: https://www.youtube.com/watch?v=6O0q3rSWr8A --- # リモートAPI認証 LXDデーモンとのリモート通信は、HTTPS上のJSONを使って行われます。 リモートAPIにアクセスするためには、クライアントはLXDサーバとの間で認証を行う必要があります。 以下の認証方法がサポートされています。 - {ref}`authentication-tls-certs` - {ref}`authentication-candid` - {ref}`authentication-rbac` (authentication-tls-certs)= ## TLSクライアント証明書 ```{youtube} https://www.youtube.com/watch?v=4iNpiL-lrXU ``` 認証に{abbr}`TLS(Transport Layer Security)`クライアント証明書を使用する場合、クライアントとサーバーの両方が最初に起動したときにキーペアを生成します。 サーバはそのキーペアをLXDソケットへの全てのHTTPS接続に使用します。 クライアントは、その証明書をクライアント証明書として、あらゆるクライアント・サーバ間の通信に使用します。 証明書を再生成させるには、単に古いものを削除します。 次の接続時には、新しい証明書が生成されます。 ### 通信プロトコル 通信プロトコルは TLS1.2 以上に対応しています。 すべての通信には完全な前方秘匿を使用し、暗号は強力な楕円曲線(ECDHE-RSA や ECDHE-ECDSA など)に限定してください。 生成される鍵は最低でも4096ビットのRSA、できれば384ビットのECDSAが望ましいです。 署名を使用する場合は、SHA-2署名のみを信頼すべきです。 我々はクライアントとサーバーの両方を管理しているので、壊れたプロトコルや暗号の下位互換をサポートする理由はありません。 (authentication-trusted-clients)= ### 信頼できるTLSクライアント LXDサーバが信頼するTLS証明書のリストは、`lxc config trust list`で取得できます。 信頼できるクライアントは以下のいずれかの方法で追加できます。 - {ref}`authentication-add-certs` - {ref}`authentication-trust-pw` - {ref}`authentication-token` サーバーとの認証を行うワークフローは、SSHの場合と同様で、未知のサーバーへの初回接続時にプロンプトが表示されます。 1. ユーザーが `lxc remote add` でサーバーを追加すると、HTTPS でサーバーに接続され、その証明書がダウンロードされ、フィンガープリントがユーザーに表示されます。 1. ユーザーは、これが本当にサーバーのフィンガープリントであることを確認するよう求められます。これは、サーバーに接続して手動で確認するか、サーバーにアクセスできる人に info コマンドを実行してフィンガープリントを比較してもらうことで確認できます。 1. サーバーはクライアントの認証を試みます。 - クライアント証明書がサーバーのトラストストアにある場合は、接続が許可されます。 - クライアント証明書がサーバーのトラストストアにない場合、サーバーはユーザーにトークンまたはトラストパスワードの入力を求めます。 提供されたトークンまたはトラストパスワードが一致した場合、クライアント証明書はサーバーのトラストストアに追加され、接続が許可されます。 そうでない場合は、接続が拒否されます。 クライアントへの信頼を取り消すには、`lxc config trust remove FINGERPRINT`でそのクライアント証明書をサーバーから削除します。 TLSクライアントを1つまたは複数のプロジェクトに制限することが可能です。 この場合、クライアントは、グローバルな構成変更の実行や、アクセスを許可されたプロジェクトの構成(制限、制約)の変更もできなくなります。 アクセスを制限するには、`lxc config trust edit FINGERPRINT`を使用します。 restricted`キーを`true`に設定し、クライアントのアクセスを制限するプロジェクトのリストを指定します。 プロジェクトのリストが空の場合、クライアントはどのプロジェクトへのアクセスも許可されません。 (authentication-add-certs)= #### 信頼できる証明書をサーバーに追加する 信頼できるクライアントを追加するには、そのクライアント証明書をサーバーのトラストストアに直接追加するのが望ましい方法です。 これを行うには、クライアント証明書をサーバーにコピーし、`lxc config trust add `で登録します。 (authentication-trust-pw)= #### トラストパスワードを使ったクライアント証明書の追加 クライアント側から新しい信頼関係を確立できるようにするには、サーバーに信頼パスワード(`core.trust_password`、{doc}`server`参照)を設定する必要があります。クライアントは、プロンプト時にトラストパスワードを入力することで、自分の証明書をサーバのトラストストアに追加することができます。 本番環境では、すべてのクライアントが追加された後に、`core.trust_password`の設定を解除してください。 これにより、パスワードを推測しようとするブルートフォース攻撃を防ぐことができます。 (authentication-token)= #### トークンを使ったクライアント証明書の追加 トークンを使って新しいクライアントを追加することもできます。トークンは一度使用すると無効になるため、トラストパスワードを使用するよりも安全な方法です。 この方法を使用するには,クライアント名の入力を促す `lxc config trust add` を呼び出して,各クライアント用のトークンを生成します。 その後,クライアントは,トラストパスワードの入力を求められたときに生成されたトークンを提供することで,自分の証明書をサーバのトラストストアに追加することができます。 あるいは、クライアントはリモートの追加時にトークンを直接提供することもできます。`lxc remote add `. ### PKI システムの使用 {abbr}`PKI (Public key infrastructure)`の設定では、システム管理者が中央のPKIを管理し、すべてのlxcクライアント用のクライアント証明書とすべてのLXDデーモン用のサーバー証明書を発行します。 PKIモードを有効にするには、以下の手順を実行します。 1. すべてのマシンに{abbr}`CA(認証局)`の証明書を追加します。 - クライアントの設定ディレクトリ(`~/.config/lxc`)に`client.ca`ファイルを配置する。 - `server.ca`ファイルをサーバの設定ディレクトリ(`/var/lib/lxd`またはsnapユーザの場合は`/var/snap/lxd/common/lxd`)に置く。 1. CAから発行された証明書をクライアントとサーバーに配置し、自動生成された証明書を置き換える。 1. サーバーを再起動します。 このモードでは、LXDデーモンへの接続はすべて、事前に発行されたCA証明書を使って行われます。 もしサーバ証明書がCAによって署名されていなければ、接続は単に通常の認証メカニズムを通過します。 サーバ証明書が有効でCAによって署名されていれば、ユーザに証明書を求めるプロンプトを出さずに接続を続行します。 生成された証明書は自動的には信頼されないことに注意してください。そのため、{ref}`authentication-trusted-clients`で説明している方法のいずれかで、サーバーに追加する必要があります。 (authentication-candid)= ## Candidベースの認証 ```{youtube} https://www.youtube.com/watch?v=FebTipM1jJk ``` LXDが[Candid](https://github.com/canonical/candid)認証を使用するように設定されている場合、サーバーで認証を行おうとするクライアントは、`candid.api.url`設定({doc}`server`参照)で指定された認証サーバーからディスチャージトークンを取得しなければなりません。 認証サーバーの証明書は、LXDサーバーから信頼されていなければなりません。 Candid/Macaroon認証を設定したLXDサーバにリモートポインティングを追加するには、`lxc remote add REMOTE ENDPOINT --auth-type=candid`を実行します。 ユーザーを確認するために、クライアントは認証サーバーが要求する認証情報の入力を求められます。 認証が成功した場合、クライアントはLXDサーバに接続し、認証サーバから受け取ったトークンを提示します。 LXDサーバはトークンを検証し、リクエストを認証します。 トークンはクッキーとして保存され、クライアントがLXDにリクエストするたびに提示されます。 Candidベースの認証を設定する方法については、チュートリアルの[Candid authentication for LXD](https://ubuntu.com/tutorials/candid-authentication-lxd)を参照してください。 (authentication-rbac)= ## 役割ベースのアクセスコントロール(RBAC) ```{youtube} https://www.youtube.com/watch?v=VE60AbJHT6E ``` LXDはCanonicalのRBACサービスとの連携をサポートしています。 Candidベースの認証と組み合わせることで、{abbr}`RBAC (Role Based Access Control)`は、APIクライアントがLXD上でできることを制限するために使うことができます。 このような設定では、認証はCandidを通して行われ、RBACサービスはユーザー/グループの関係に役割を維持します。 ロールは個々のプロジェクトにも、すべてのプロジェクトにも、あるいはLXDインスタンス全体にも割り当てることができます。 プロジェクトに適用された場合のロールの意味は以下の通りです。 - 監査役: プロジェクトへの読み取り専用のアクセス権 - ユーザー: 通常のライフサイクルアクション(開始、停止、...)を実行する能力。 インスタンスでのコマンド実行、コンソールへのアタッチ、スナップショットの管理など。 - オペレーター: 上記のすべての機能に加え、インスタンスやイメージの作成、再設定、削除を行う機能 インスタンスとイメージの作成、再設定、削除 - 管理者: 上記の機能に加えて、プロジェクト自体を再構成する機能を持つ ```{important} 制限のないプロジェクトでは、`auditor`と`user`のロールだけが、ホストへのルートアクセスを任せられないユーザーに適しています。 また、{ref}`制限付きプロジェクト ` では、適切に設定されていれば、`operator` ロールも安全に使用することができます。 ``` ## 失敗のシナリオ 以下のようなシナリオでは、認証に失敗することが予想されます。 ### サーバー証明書の変更 以下のような場合、サーバーの証明書が変更されている可能性があります。 * サーバを完全に再インストールしたため、新しい証明書が発行された。 * 接続が傍受されている({abbr}`MITM (Man in the middle)`)。 このような場合、クライアントは、証明書のフィンガープリントが、このリモート用の設定にあるフィンガープリントと一致しないため、サーバーへの接続を拒否します。 この場合、ユーザーはサーバー管理者に連絡して、証明書が実際に変更されたかどうかを確認する必要があります。 証明書が変更された場合は、証明書を新しいものに置き換えるか、リモートを完全に削除して再度追加することができます。 ### サーバーの信頼関係が取り消された(revokeされた)場合 信頼されている他のクライアントや、ローカルのサーバー管理者が、サーバー上のクライアントの信頼エントリを削除すると、そのクライアントに対するサーバーの信頼関係は失効します。 この場合、サーバーは引き続き同じ証明書を使用しますが、すべての API 呼び出しは、クライアントが信頼されていないことを示すエラーである 403 コードを返します。