社内にクライアント証明書認証を導入した話
はじめまして、株式会社ラキールの LaKeel DX Engine Group に所属する海老と申します。
近年では、サイバー攻撃による個人情報の流出が大きな話題になるなど、
企業のセキュリティ強化の重要度が高まっています。
ラキールでは、企業のユーザ管理、認証・認可、シングルサインオンを統合的に提供する「 LaKeel Passport 」というサービスを通じて、セキュリティの課題に対応しています。
今回、私たちのチームは LaKeel Passport と連携したクライアント証明書認証システムを社内に導入しました。
本記事では、その導入事例について詳しくご紹介させていただきます。
前提知識
認証局
認証局(CA)とは、デジタル証明書の発行を行うサービスです。
デジタル証明書とはウェブサイトやオンラインサービスが本物であることを証明するデジタルの「身分証明書」のようなものです。
認証局は、このデジタル証明書を発行して、ウェブサイトやサービスが安全で信頼できることを保証します。これにより、情報が盗まれたり、改ざんされたりするリスクを減らします。
デジタル証明書には、サーバ証明書、メール証明書、クライアント証明書などが存在します。
クライアント証明書認証
クライアント証明書認証とは、クライアント証明書を用いてユーザやデバイスの身元を確認するセキュリティプロセスです。
クライアント証明書の発行
認証局(CA)と呼ばれる証明書発行サービスがクライアント証明書を発行します。
発行された証明書は端末に保存されます。
Webサービスでのクライアント証明書認証
Webサービスは端末のアクセス時に、クライアント証明書を使った認証を行います。
証明書発行済み端末からは、Webサービスにアクセスできます。
証明書が未発行の端末からは、Webサービスにアクセスできません。
導入の経緯
当社では以前から OpenSSL で構築した認証局 ( CA )によるクライアント証明書認証を導入していましたが、それには以下のような問題がありました。
社内端末に関わらず、どの端末からでも証明書が発行できてしまう。
クライアント証明書を管理者が失効させる仕組みがない。
これらの問題を解決するため、よりセキュアなクライアント証明書サービスを新たに導入することにしました。
機能概要
本サービスは以下の機能で構成されます。
クライアント証明書の発行機能
デバイスIDベースの証明書発行申請と承認を行います。
承認した端末のみ証明書をインストールするよう制御を行います。
クライアント証明書による認証機能
発行した証明書を用いたログイン認証制御を行います。
クライアント証明書の管理
発行した証明書の一元管理と失効制御を行います。
クライアント証明書の発行
クライアント証明書の発行は、「ユーザがクライアント証明書の発行を証明書発行サイトに依頼し、承認後、発行された証明書を端末にインストールする機能」です。
クライアント証明書発行のプロセスを「証明書プロファイルの適用」「証明書発行の承認」「証明書の発行」の3つに分けて見ていきます。
① 証明書プロファイルの適用
証明書発行プロトコルを実行するには、事前に証明書プロファイルを端末にダウンロードし、適用する必要があります。
証明書プロファイルにはデバイスの設定情報や、証明書の取得に必要な情報が含まれており、端末にこれらの設定を導入するために使われます。
証明書プロファイルのダウンロード方法は端末のOSの種類によって異なります。
Windowsの場合
証明書発行サイトから証明書発行アプリを取得し、アプリ経由で証明書プロファイルをダウンロードします。
証明書発行アプリの取得
証明書発行アプリを証明書発行サイトから取得します。
証明書プロファイルのダウンロード
証明書発行アプリを介して、証明書発行サイトから証明書プロファイルをダウンロードします。
ダウンロードされた証明書プロファイルは端末に自動的に適用されます。
Android の場合
証明書発行アプリのダウンロード元が Google Play Store である点のみWindows のフローと異なります。
iOS の場合
iOSではネイティブに証明書プロファイルを取り込む機能があるため
証明発行サイトから直接、証明書プロファイルをダウンロードし、「設定」画面から手動で適用します。
② 証明書発行の承認
不正な端末からの証明書発行申請を防ぐため、以下のどれかの条件を満たす場合のみ、証明書の発行プロセスに進めるよう制御しました。
社内 Active Directory ( AD ) にデバイス ID が登録されている端末
申請システム ( LaKeel Workflow ) において承認された端末
※ Active Directory : ネットワークに接続された端末、サーバー、プリンター、アプリケーションなどの情報を収集し、一元管理するためのディレクトリサービス。
Windows PCの場合
社内 PC の情報は社内 AD に登録されています。
そのため、Windows PC からの申請の場合は、社内 AD のデバイス ID と照合して承認を出します。
iOS、Android の場合
社内モバイル端末は、社内 AD に情報が登録されていないため、
申請システム ( LaKeel Workflow ) 経由で承認を出します。
③ 証明書の発行
SCEP サーバ ( 証明書自動発行サーバ ) を介して証明書を発行し、発行された証明書を端末にインストールします。
SCEPサーバへの証明書署名リクエスト(CSR)
ユーザ端末から、SCEP サーバ に、デバイス情報や認証情報を含む証明書署名リクエスト ( CSR ) を送ります。
リクエストの検証
Issuing CAサーバへの証明書署名リクエスト(CSR)
SCEP サーバはユーザ端末からのリクエストの認証情報を検証します。
検証が成功すると、SCEP サーバは Issuning CAサーバに、ユーザ端末からの証明書発行リクエスト(CSR)を転送します。
Issuing CAサーバでの証明書発行
Issuing CA サーバはリクエストの内容を検証し、証明書を発行します。
リスポンスとして証明書の返却
発行された証明書はSCEPサーバを介してユーザ端末に送信され、その端末にインストールされます。
システムのまとめと補足
証明書発行サイト
証明書発行アプリや証明書プロファイルの配布、SCEP サーバへの誘導、デバイスIDによる証明書発行の制御 を行います。
証明書発行サイトへのアクセスには LaKeel Passport でのログイン認証が必要です。
SCEPサーバ (証明書自動発行サーバ)
SCEP (Simple Certificate Enrollment Protocol) のプロセスに沿って自動的に証明書の発行を行います。
デバイスからのCSR(証明書署名リクエスト)を事前に共有されたワンタイムパスワードをもとに検証します。
Issuing CA サーバ(発行認証局)
実際に証明書を発行するサーバです。
Issuing CA サーバは、SCEP サーバを通じて、証明書署名リクエスト ( CSR ) を受け取り、それを検証した後、証明書を発行します。
発行した証明書は Issuing CA サーバで管理されます。
Issuing CA サーバはRoot CAサーバによって信頼性を担保しています。
Root CA サーバ(ルート認証局)
証明書の信頼性の基盤となるサーバです。
実際には証明書を発行せず、Issuing CAで発行される証明書の信頼性を担保するために存在しています。
通常はオフラインで保持され、Issuing CA サーバの証明書の発行や更新以外では使用されません。
クライアント証明書の認証
クライアント証明書の認証は、「Webサービスが、ユーザ端末のクライアント証明書を用いて、アクセスの正当性の検証するプロセス」です。
証明書を用いた認証プロセス
Webサービスは、ユーザ端末から送信されたクライアント証明書をサーバに連携し、証明書の有効性を検証します。
Web サービスへのアクセス
LaKeel Passport へのリダイレクト
ユーザが LaKeel Passport と連携している Web サービスにアクセスします。
ユーザが未認証の場合、Web サービスはユーザを LaKeel Passportにリダイレクトさせます。
OCSPサーバにおいて証明書のステータスを検証する。
LaKeel Passport はリクエストの証明書の情報をもとに、OCSP サーバに証明書検証リクエストを送信します。
OCSP サーバは Issuning CA サーバから連携された証明書失効リスト(CRL) をもとに、証明書のステータスを確認します。
検証の結果を返却
検証がOKの場合、Webサービスへリダイレクト
証明書のステータスが有効であった場合、ユーザは Web サービスにリダイレクトされます。
システムのまとめと補足
OCSPサーバ(証明書検証サーバ)
OCSP (Online Certificate Status Protocol) のプロセスに沿って証明書が失効していないか検証するサーバです。
OCSP サーバーは、Issuing CA サーバと定期的に証明書失効リスト ( CRL ) を連携します。
OCSP サーバーは証明書失効リストをもとに、証明書の有効検証を行います。
プロキシサーバ ( Nginx )
LaKeel Passport とユーザの間での通信を中継するサーバです。
ユーザから送られてきた証明書を LaKeel Passportに連携します。
LaKeel Passport
送られてきた証明書をもとに、OCSP サーバに証明書検証リクエストを送り、証明書を検証します。
LaKeel Passport は Keycloak というオープンソースの認証認可のサービスを内包しており、それを利用してユーザの認証を行います。
クライアント証明書の管理
クライアント証明書の管理は、「管理者が発行されたクライアント証明書の確認や失効を行う」プロセスです。
ここでは、証明書の失効のプロセスについて説明します。
証明書の失効
管理者からの操作を受けて、管理画面は Issuning CA サーバに証明書失効リクエストを送信し、証明書の失効を行います。
LaKeel Passport 管理画面 にアクセス
管理者が LaKeel Passport 管理画面にアクセスします。
管理画面には管理者ユーザしかアクセスできないように LaKeel Passport で権限を設定しています。
証明書失効リクエスト
管理者はLaKeel Passport 管理画面の証明書一覧から失効したい証明書を選び、失効ボタンを押します。
証明書失効リクエストが Issuing CAサーバに送信されます。
証明書失効
結果を返却
Issuing CAサーバは該当証明書が存在した場合、失効処理を行います。
処理の結果をLaKeel Passport 管理画面に返却します。
プロキシサーバの設定
LaKeel Passport はプロキシサーバである Nginx を経由してアクセスされるため、Nginx とLaKeel Passport に内包している Keycloak 間でクライアント証明書の受け渡し設定が必要です。
Nginx の設定
proxy_set_header ssl-client-cert $ssl_client_escaped_cert;
proxy_set_header : クライアント証明書と関連情報を LaKeel Passport ( Keycloak ) に渡すための HTTP ヘッダを設定します。
Keycloak の設定
導入当時は JBoss ベースの Keycloak を使用していたため、JBossのコマンドラインツールを使用して、Keycloak に設定を加えました。
※ 最新バージョンの Keycloak では JBoss のコマンドラインは使えないので注意してください。
/subsystem=keycloak-server/spi=x509cert-lookup/provider=nginx:add(enabled=true)
/subsystem=keycloak-server/spi=x509cert-lookup/provider=nginx:write-attribute(name=properties.sslClientCert,value=SSL-CLIENT-CERT)
/subsystem=keycloak-server/spi=x509cert-lookup/provider=nginx:write-attribute(name=properties.sslCertChainPrefix,value=USELESS)
/subsystem=keycloak-server/spi=x509cert-lookup/provider=nginx:write-attribute(name=properties.certificateChainLength,value=2)
/subsystem=keycloak-server/spi=x509cert-lookup:write-attribute(name=default-provider,value=nginx)
/subsystem=keycloak-server/spi=truststore:add
/subsystem=keycloak-server/spi=truststore/provider=file:add(enabled=true)
/subsystem=keycloak-server/spi=truststore/provider=file:write-attribute(name=properties.file,value=/path/to/truststore/jks/cacerts)
/subsystem=keycloak-server/spi=truststore/provider=file:write-attribute(name=properties.password,value=[YOUR_TRUSTSTORE_PASSWORD])
/subsystem=keycloak-server/spi=truststore/provider=file:write-attribute(name=properties.hostname-verification-policy,value=WILDCARD)
/subsystem=keycloak-server/spi=truststore/provider=file:write-attribute(name=properties.disabled,value=false)
/subsystem=keycloak-server/spi=truststore:write-attribute(name=default-provider,value=file)
x509cert-lookup SPIの設定
クライアント証明書を探索するための設定です。
Nginx用x509cert-lookupプロバイダが追加されています。
これは、Nginx からのクライアント証明書情報をKeycloakが取得するためプロバイダです。
証明書情報の取得
sslClientCert は、クライアント証明書を格納する HTTP ヘッダの名前です。
certificateChainLength では、Keycloakがチェックする証明書チェーン内の証明書の数を指定します。
証明書チェーンとは、複数の証明書が互いに信頼関係を持ち、安全な通信を保証する仕組みです。Keycloakでは、このチェーン内に特定の数の証明書があることを期待し、それによって通信の安全性を確認します。
Truststore SPIの設定
Truststore は信頼できるIssuing CA サーバの証明書を保持するための設定です。
ここでは、 Truststore ファイルの場所、パスワード、ホスト名の検証ポリシーが設定されています。
導入で得られた業務改革点
クライアント証明書のインストールを端末ごとに制御できるようになり、証明書を用いた社内のシステムへのアクセスのセキュリティ性が向上しました。
証明書を管理者が強制的に失効させることができるようになり、証明書の不正利用を未然に防ぐことが可能になりました。
証明書がどの端末によって発行されたかを追跡・確認できるようになりました。これにより、証明書の管理が容易になり、セキュリティの維持がより効果的に行えます。
苦労した点
端末のOSごとにクライアント証明書の発行プロセスが異なるため、それぞれに固有の発行手順を用意する必要がありました。
Root CA サーバとIssuing CAサーバ間での証明書チェーン検証の設定。機関情報アクセス ( AIA) や証明書失効リスト ( CRL ) など、認証局特有の設定が多く、理解に苦労しました。
Nginx とLaKeel Passport ( Keycloak )間のクライアント証明書の受け渡しの設定。(「プロキシサーバの設定」の項を参照 )
Node.jsによるiOS証明書発行プロトコルに必要なPKCS7パッケージの生成と検証実装。
最後に
今回、セキュアなクライアント証明書認証を社内に導入することで、ユーザの利便性とセキュリティの強化を達成することができました。
クライアント証明書認証はパスワード認証と併用することを前提に実装を進めてきましたが、現在 LaKeel Passport チームでは、パスワードを使わないパスキーなどのパスワードレス認証への対応を進めています。
将来的には、パスワードなしで社内サービスにログインできる未来が訪れるかもしれません。
セキュリティは絶えず進化する分野です。これからも、最適な認証方法を常に追求し、機能開発を進めていこうと思います。
最後までお読みいただき、ありがとうございました。