# PIV/CAC/スマートカード

<figure><img src="https://4041518992-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FZ7s6LQJaKa1G17O787JG%2Fuploads%2FcYDEGbsFTksVdYsVZreQ%2Fimage.png?alt=media&#x26;token=2f7ed33e-d3b9-455b-bddb-81c83ca2fbf3" alt=""><figcaption></figcaption></figure>

KCMでは、DoDの共通アクセスカード (Common Access Card、CAC) を使用したウェブアプリケーションによる認証だけでなく、個人識別確認 (Personal Identity Verification、PIV) などのSSLクライアント認証用にブラウザでサポートされている任意のスマートカードによる認証も可能です。

{% hint style="info" %}
この機能を使用すると、ユーザーはCACを使用してKeeper Connection Managerに対して認証できますが、CACを使用したリモートデスクトップへのパススルー認証はできません。
{% endhint %}

このサポートは、KCMバージョン2.12.0に追加された機能である、[SSL/TLS認証を提供するSSLターミネーションインスタンス](https://docs.keeper.io/keeper-connection-manager/authentication/ssl-tls-client-authentication)を必要とします。

PIV/CACの一般的な設定は以下のようになります。

1. [2つのホスト名](https://docs.keeper.io/keeper-connection-manager/authentication/multiple-hostnames)が設定されたSSLターミネーションインスタンス。1つは通常のアクセス用 (`kcm.example.net`など) で、もう1つは[SSLクライアント認証](https://docs.keeper.io/keeper-connection-manager/authentication/ssl-tls-client-authentication)の処理専用で、ワイルドカードドメイン (`*.login.kcm.example.net`など) が望ましいでしょう。SSLクライアント認証設定には、PIV/CACカードを提供するCAの証明書が含まれます。
2. PIV/CACサポートのインストールと設定。`*.login.kcm.example.net`に対してユーザーを認証し、準備ができたら`kcm.example.net`にリダイレクトするように設定します。
3. SSOを利用したユーザーのユーザーアカウントを自動的に作成するように設定されたデータベースバックエンド。
4. PIV/CACからシングルサインオンするユーザーの承認を要求するように[設定されたユーザー作成ワークフロー](#configuring-the-kcm-user-creation-workflow)。

### PIV/CACの設定オプション <a href="#guacamole-configuration-options-for-piv-cac" id="guacamole-configuration-options-for-piv-cac"></a>

PIV/CACのサポートは、SSL/TLSクライアント認証に対するKeeperの新しいサポートを使用して設定します。このサポートは、`kcm-guacamole-auth-sso-ssl`としてパッケージ化されている「guacamole-auth-sso-ssl」拡張機能によって提供されます。どの`SSL_*`変数を設定しても、`kcm-guacamole-auth-sso-ssl`パッケージが暗黙的に含まれます。

以下のオプションは、[keeper/guacamole](https://docs.keeper.io/keeper-connection-manager/installation/docker-compose-install/keeper-guacamole)のDockerコンテナ定義（または、Linuxディストリビューションの場合はguacamole.properties）で設定する必要があります。

| プロパティ                            | 環境変数                             | 説明                                                                                                                                                         |
| -------------------------------- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ssl-client-auth-uri`            | `SSL_CLIENT_AUTH_URI`            | **必須**。このGuacamoleインスタンスを指し、SSL/TLSクライアント認証を要求するワイルドカードURI。                                                                                                |
| `ssl-primary-uri`                | `SSL_PRIMARY_URI`                | **必須**。このGuacamoleインスタンスを指し、SSL/TLSクライアント認証を要求「しない」ワイルドカードを使用しないURI。                                                                                       |
| `ssl-subject-base-dn`            | `SSL_SUBJECT_BASE_DN`            | <p>有効なサブジェクトDNをすべて含むベースDN。指定した場合、このベースDNの下にあるサブジェクトDNを明示する証明書のみが受け入れられます。</p><p><strong>デフォルトでは、すべてのDNが受け入れられます。</strong></p>                              |
| `ssl-subject-username-attribute` | `SSL_SUBJECT_USERNAME_ATTRIBUTE` | <p>ユーザーのX .509証明書のサブジェクトDN内でユーザー名を表示すために使用できる1つまたは複数のLDAP属性。サブジェクトDNの最下位属性がこれらの属性のいずれでもない場合、証明書は拒否されます。</p><p><strong>デフォルトでは、任意の属性が受け入れられます。</strong></p> |

以下のオプションも使用できますが、設定が必要になることはめったにないでしょう。

| プロパティ                           | 環境変数                            | 説明                                                                                                                                                                                                                                                                                                                                                                                             | デフォルト値                 |
| ------------------------------- | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- |
| `ssl-client-certificate-header` | `SSL_CLIENT_CERTIFICATE_HEADER` | <p>SSL/TLSクライアント認証を提供するSSLターミネーションサービスから受信したHTTPリクエストから取得した、URLエンコードされたクライアント証明書を取得するために使用するヘッダーの名前。</p><p><code>keeper/guacamole-ssl-nginx</code>イメージのデフォルト値はこのオプションのデフォルト値と一致するため、通常は設定する必要はないはずです。</p>                                                                                                                                                                                      | `X-Client-Certificate` |
| `ssl-client-verified-header`    | `SSL_CLIENT_VERIFIED_HEADER`    | <p>SSL/TLSクライアント認証を提供するSSLターミネーションサービスからHTTPリクエストが受信した証明書の検証ステータスを取得するために使用するヘッダーの名前。証明書が正常に検証された場合、このヘッダーの値は「SUCCESS」（すべて大文字）である必要があります。</p><p><code>keeper/guacamole-ssl-nginx</code>イメージのデフォルト値はこのオプションのデフォルト値と一致するため、通常は設定する必要はないはずです。</p>                                                                                                                                                 | `X-Client-Verified`    |
| `ssl-max-domain-validity`       | `SSL_MAX_DOMAIN_VALIDITY`       | <p>SSL/TLS認証のために一時的に生成された一意のサブドメインの有効時間（分単位）。</p><p>このサブドメインは、各SSL/TLS認証が新たな試行であり、ブラウザやOSがキャッシュした過去の認証試行を再利用するおそれがないようにするために使用されます。この間隔は、SSL/TLSクライアント認証を強制するSSLターミネーションサービスでユーザーを認証する際のネットワーク遅延を計算に入れた十分な長さであることが必要ですが、使用されていないドメインが不要なサーバーリソースを消費することなく、そのサブドメインがまだ有効であるか推測できないかもしれないほど十分短い必要があります。これらのサブドメインは、128ビットのセキュアなランダム値です。</p><p>これは通常は設定する必要はないはずですが、管理者はこの値を減らしたいと考えるかもしれません。</p> | 5                      |
| `ssl-max-token-validity`        | `SSL_MAX_TOKEN_VALIDITY`        | <p>SSL/TLS認証のために一時的な認証トークンの有効時間（分単位）。</p><p>このトークンは、SSLターミネーションサービスによって検証された後、ユーザーの明示されたIDを示すために使用されます。この間隔は、トークンを受信する際のネットワーク遅延を計算に入れた十分な長さであることが必要ですが、使用されていないトークンが不要なサーバーリソースを消費することなく、そのトークンがまだ有効であるか推測できないかもしれないほど十分短い必要があります。これらのトークンは、256ビットのセキュアなランダム値です。</p><p>これは通常は設定する必要はないはずですが、管理者はこの値を減らしたいと考えるかもしれません。</p>                                                                     | 5                      |

### PIV/CACのSSL (NGINX) 設定オプション <a href="#ssl-nginx-configuration-options-for-piv-cac" id="ssl-nginx-configuration-options-for-piv-cac"></a>

ブラウザを使用したPIV/CAC（または任意のスマートカード）による認証では、[SSL/TLSクライアント認証](https://docs.keeper.io/keeper-connection-manager/authentication/ssl-tls-client-authentication)を使用しています。この機能をPIV/CAC用にさらに強化するために、証明書がOCSPまたはCRLを使用して取り消されたかどうかをテストするための便利な設定オプションが追加されました。参考までに、[keeper/guacamole-ssl-nginx](https://docs.keeper.io/keeper-connection-manager/installation/docker-compose-install/ssl-termination/keeper-guacamole-ssl-nginx)のDockerイメージで現在サポートされているSSL/TLSクライアント認証に関連するすべてのオプションを以下に示します。

| 環境変数                      | 説明                                                                                                                                                                                                                                                                                                                                                           | デフォルト値 |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------ |
| `ADDITIONAL_PROXY_CONFIG` | NGINXがGuacamoleのプロキシとして機能するように設定する`location`ブロック内に含める必要のある、任意の追加のNGINX設定ステートメント。                                                                                                                                                                                                                                                                             |        |
| `CLIENT_CERTIFICATE_FILE` | SSL/TLSクライアントが提示した証明書をNGINXが検証するために使用する必要のある証明書。                                                                                                                                                                                                                                                                                                             |        |
| `CLIENT_CRL_FILE`         | <p>NGINXがクライアントの証明書が失効しているかどうかを確認するために使用する証明書失効リスト (Certificate Revocation List、CRL) ファイルを管理します。NGINXの<code>ssl\_crl</code>ディレクティブで設定します。このファイルはPEM形式であることが必要で、複数のCRLを指定できます。省略した場合、CRLファイルは使用されません。<br></p><p><code>CLIENT\_CERTIFICATE\_FILE</code><strong>が指定されていない場合、この変数は無視されます。</strong><br></p><p>使用可能な場合は、CRLファイルを使用するよりもOCSPを使用する方が望ましい場合が多いです。</p> |        |
| `CLIENT_OCSP`             | <p>NGINXがOCSPを使用してクライアントの証明書が失効しているかどうかを確認するか否かを管理します。NGINXの<code>ssl\_ocsp</code>ディレクティブで設定します。この変数を<code>on</code>に設定すると、OCSPを使用してクライアント証明書がチェックされます。<br></p><p><code>CLIENT\_CERTIFICATE\_FILE</code><strong>が指定されていない場合、この変数は無視されます。</strong><br></p><p>有効な場合、<code>RESOLVER</code>も指定する必要があります。</p>                                                     | off    |
| `RESOLVER`                | NGINXがドメイン名を解決するために使用するDNSサーバー。これは、OCSPが有効な場合にのみ必要です。                                                                                                                                                                                                                                                                                                        |        |
| `SSL_VERIFY_CLIENT`       | NGINXがクライアント（ブラウザ）が提示する証明書を要求および検証する方法とその要否を管理します。NGINXの`ssl_verify_client`ディレクティブで設定します。                                                                                                                                                                                                                                                                    | on     |
| `SSL_VERIFY_DEPTH`        | NGINXがクライアントの証明書を検証しようとするときに、クライアントの証明書チェーンを確認する深さを管理します。NGINXの`ssl_verify_depth`ディレクティブで設定します。                                                                                                                                                                                                                                                              | 1      |

### PIV/CACの設定例 <a href="#example-piv-cac-configuration" id="example-piv-cac-configuration"></a>

以下の`docker-compose.yml`の例では、次のプレースホルダーを使用しています。

| **プレースホルダー**                                | **説明**                                                                                                                                                         |
| ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PasswordForPostgresAdmin`                  | PostgreSQLの`postgres`ユーザー (PostgreSQLデータベースの一般的なルートユーザー) に割り当てるのに適したパスワード。このアカウントは、管理者が`psql`などのツールを使用して手動でデータベースに接続する必要がある場合にのみ使用されます。                        |
| `guacamole_db`                              | PostgreSQL内のGuacamoleデータベースの名前。この値は`kcm-setup.run`によって自動的に使用され、Keeperのドキュメントとアップストリームの両方で適切な値として記載されているため、ここで他の値を使用することはほとんどありません。                             |
| `guacamole_user`                            | Guacamoleがデータベースに対してクエリを実行するために使用する、権限が制限されたPostgreSQLユーザー。この値は`kcm-setup.run`によって自動的に使用され、Keeperのドキュメントとアップストリームの両方で適切な値として記載されているため、ここで他の値を使用することはほとんどありません。 |
| `PasswordForGuacamole`                      | Guacamoleが権限が制限された`guacamole_user`アカウントとしてデータベースで認証し、クエリを実行するために使用するPostgreSQLユーザーに割り当てる適切なパスワード。                                                              |
| `ou=test department,o=u.s. government,c=us` | SSL/TLSクライアント認証（ブラウザを使用したスマートカード認証）を使用して提示された場合に受け入れる必要があるサブジェクトDNのベースDN。                                                                                      |
| `kcm.example.net`                           | ユーザーがKCMを使用するためにブラウザでアクセスするドメイン。                                                                                                                               |
| `/path/to/pki`                              | クライアント認証などのSSLに使用される証明書と秘密鍵を格納するDockerホスト上のパス。                                                                                                                 |
| `/pki`                                      | NGINXがコンテナのファイルにアクセスできるように、`/path/to/pki`をマウントする必要のあるDockerコンテナ内のパス。                                                                                           |
| `cac-certificate.pem`                       | ユーザーがスマートカードで認証しようとするときに、NGINXがユーザーから受け取る証明書を検証するために使用するPEM形式の証明書のファイル名。                                                                                       |

実際には、これらの値はユーザーがMySQLとPostgreSQLのどちらを選択するかによって異なります。以下は、PostgreSQLを使用して作成した例です。

```
version:"3"
services:

    guacamole:
        image: keeper/guacamole:2
        restart: unless-stopped
        environment:
            ACCEPT_EULA:"Y"
            GUACD_HOSTNAME: "guacd"
            POSTGRES_HOSTNAME: "db"
            POSTGRES_DATABASE: "guacamole_db"
            POSTGRES_USERNAME: "guacamole_user"
            POSTGRES_PASSWORD:"PasswordForGuacamole"
            SSL_PRIMARY_URI: "https://kcm.example.net"
            SSL_CLIENT_AUTH_URI: "https://*.kcm.example.net"
            SSL_SUBJECT_BASE_DN: "ou=test department,o=u.s. government,c=us"
            POSTGRESQL_AUTO_CREATE_ACCOUNTS: "true"
            REQUIRE_ACCOUNT_APPROVAL: "ssl"
        volumes:
            - "common-storage:/var/lib/guacamole:rw"

    db:
        image: keeper/guacamole-db-postgres:2
        restart: unless-stopped
        environment:
            ACCEPT_EULA:"Y"
            GUACAMOLE_DATABASE: "guacamole_db"
            GUACAMOLE_USERNAME: "guacamole_user"
            GUACAMOLE_PASSWORD:"PasswordForGuacamole"
            GUACAMOLE_ADMIN_PASSWORD: "guacadmin"
            POSTGRES_PASSWORD:"PasswordForPostgresAdmin"

    guacd:
        image: keeper/guacd:2
        restart: unless-stopped
        environment:
            ACCEPT_EULA:"Y"
        volumes:
            - "common-storage:/var/lib/guacamole:rw"

    ssl:
        image: keeper/guacamole-ssl-nginx:2
        restart: unless-stopped
        ports:
            - "80:80"
            - "443:443"
        volumes:
            - "/path/to/pki:/pki:ro"
        environment:

            ACCEPT_EULA:"Y"
            GUACAMOLE_HOSTNAME: "guacamole"

            SERVERS: |

              # Main hostname, referenced by SSL_PRIMARY_URI
              - SSL_HOSTNAME: "kcm.example.net"
                CERTIFICATE_FILE: "/pki/kcm.example.net.crt"
                PRIVATE_KEY_FILE: "/pki/kcm.example.net.key"

                # The default CSP must be overridden for the main URI to allow
                # it to issue requests to its SSL/TLS-authenticating
                # counterpart.The only change from the default CSP here is to
                # add an the wildcard URI (including https://) to connect-src.
                CONTENT_SECURITY_POLICY: "default-src 'none'; script-src 'self' 'unsafe-eval'; connect-src 'self' wss://kcm.example.net https://*.kcm.example.net; object-src 'self'; frame-src 'self' https:; img-src 'self' data: blob:; style-src 'self' 'unsafe-inline'; font-src 'self' data:; form-action 'self'; base-uri 'self'; frame-ancestors 'self';"

              # Hostname requiring client auth, referenced by SSL_CLIENT_AUTH_URI
              - SSL_HOSTNAME: "*.kcm.example.net"
                CERTIFICATE_FILE: "/pki/_.kcm.example.net.crt"
                PRIVATE_KEY_FILE: "/pki/_.kcm.example.net.key"
                CLIENT_CERTIFICATE_FILE: "/pki/cac-certificate.pem"
                SSL_VERIFY_CLIENT: "optional" # This is necessary to allow the webapp to receive
                                              # verification failures.Without this, Nginx would
                                              # respond directly to any verification failures and
                                              # will not include the CORS headers necessary to
                                              # allow the webapp to actually see that failure.This
                                              # also allows the webapp to see the nature of the
                                              # failure by investigating the headers Nginx sends.
                                              # There are no such headers (and no such request) if
                                              # this is set to "required" and Nginx aborts
                                              # processing due to an invalid certificate.

volumes:
    common-storage:

```

### KCMのユーザー作成ワークフローを設定 <a href="#configuring-the-kcm-user-creation-workflow" id="configuring-the-kcm-user-creation-workflow"></a>

ユーザーワークフローを設定する前に、必ず`REQUIRE_ACCOUNT_APPROVAL`キーを適切な認証メソッドに設定してください。

PIV/CACの場合は、以下のように`ssl`に設定してください。

```yaml
 guacamole:
        image: keeper/guacamole:2
        restart: unless-stopped
        environment:
            ACCEPT_EULA:"Y"
            GUACD_HOSTNAME: "guacd"
            SSL_PRIMARY_URI: "https://kcm.example.net"
            SSL_CLIENT_AUTH_URI: "https://*.kcm.example.net"
            SSL_SUBJECT_BASE_DN: "ou=test department,o=u.s. government,c=us"
            POSTGRESQL_AUTO_CREATE_ACCOUNTS: "true"
            REQUIRE_ACCOUNT_APPROVAL: "ssl"
```

設定が正常に完了すると、以下に示すように、アプリケーションのログイン画面に「Use Certificate or Smart Card」 (証明書またはスマートカードを使用する) リンクが新たに表示されるようになります。

<figure><img src="https://4041518992-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FZ7s6LQJaKa1G17O787JG%2Fuploads%2FWegFyjvzsuuLJclmqKAY%2Fimage.png?alt=media&#x26;token=e7c6e2db-4f28-4abd-9996-576fed3b26ee" alt=""><figcaption><p>SSL認証メソッドを有効にしたログイン画面</p></figcaption></figure>

ユーザー作成ワークフローの詳細は、この[ページ](https://docs.keeper.io/keeper-connection-manager/authentication/account-approve-deny-workflow)をご参照ください。

### 認証局のインストール

Keeper Connection Managerにアクセスする必要があるエンドユーザーのクライアントデバイスごとに、信頼できる認証局として内部CAをユーザーのブラウザにインストールすることが必要な場合があります。信頼された認証局のインストールは、プラットフォームによって異なります。
