はじめに
API Connectでは、相互TLS認証(mutual tls , 2way tlsなどとも言います)のための機能が提供されています。
通常のHTTPSのTLS認証では、クライアントがサーバーとTLSネゴシエーションをする際に、サーバーから証明書が送られ、クライアントがサーバーを検証することでなりすましを防ぐことができます。さらに、相互TLS認証では、クライアントから証明書をサーバーに送り、サーバーが検証するプロセスが追加されます。
この記事では、API Connectで相互TLS認証を実装する方法を紹介します(検証環境は、v10.0.4となります)。
API Connectでは、デフォルトでGUI用のサーバー証明書や、コンポーネント間の通信で相互TLS認証が使われているため、そのための各TLSプロファイルが登録されています(Knowledge Center:Deployment overview for endpoints and certificates)。
事前準備
クライアント証明書の作成
相互TLS認証では、クライアントの秘密鍵と、Public証明書が必要となります。今回は、OpenSSLツールを使用して自己署名の証明書を作成します。
詳細は、Knowledge Center: Generating a self-signed certificate using OpenSSLをご参照ください。
$ openssl req -newkey rsa:2048 -nodes -keyout client_key.pem -x509 -days 365 -out client_certificate.pem
Generating a RSA private key
...............+++++
.............................................+++++
writing new private key to 'client_key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:jp
State or Province Name (full name) []:Tokyo
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:client.com
Email Address []:
$ openssl pkcs12 -inkey client_key.pem -in client_certificate.pem -export -out client_certificate.p12
Enter Export Password:
Verifying - Enter Export Password:
上記の結果、秘密鍵(client_key.pem)と、PUblic証明書(client_certificate.pem)と、この2つを組み合わせてパスワードで保護したPKCS12形式ファイル(client_certificate.p12)が作成されました。
サーバー設定
ゲートウェイ・サービスのTLSプロファイル確認
Cloud Managerにログインし、トポロジーメニューからゲートウェイ・サービスに紐づいているTLSプロファイルを確認します。
インストール時に設定していない場合は、製品提供のデフォルトのプロファイルが設定されます。
以下の例では、API呼び出しエンドポイントのTLSサーバー・プロファイルに「デフォルトのTLSサーバー・プロファイル」が設定されていることがわかります。このプロファイルでは、相互認証はなしとなっていますので、クライアント証明書の認証は実施されません。
相互TLS認証用のトラストストアの登録
リソース-TLSメニューからトラストストアの作成をクリックします。
トラストストアは、クライアントから送付された証明書の検証で使用されます。
事前準備で作成したクライアント証明書をこちらに登録します。
相互TLS認証用のTLSサーバー・プロファイルの登録
リソース-TLSメニューからTLSサーバー・プロファイルを新規登録します。
以下のようにタイトルに任意の名前を設定し、相互認証として「必須」を選択します。
トラストストアで先ほど作成した「server-trust-store」を選択して保存します。
以下のように新たにTLSサーバー・プロファイルが作成されました。
ゲートウェイ・サービスのTLSプロファイル変更
トポロジーメニューからゲートウェイ・サービスに紐づいているTLSプロファイルを先ほど作成した「server-profile」に変更します。
以上で設定は完了です。
動作確認
このゲートウェイ・サービスから公開されているAPIを呼び出してみます。
クライアント証明書が認証できないため、以下のようにTLSハンドシェイクエラーとなります。
$ curl -ki https://ademo-***-appdomain.cloud/test-org/sandbox/v1/backend
curl: (35) schannel: next InitializeSecurityContext failed: SEC_E_ILLEGAL_MESSAG
E (0x80090326) - This error usually occurs when a fatal SSL/TLS alert is receive
d (e.g. handshake failed). More detail may be available in the Windows System ev
ent log.
次に、証明書を付与してAPI呼び出しを実施します。
今度は、クライアント証明書が認証され、APIの結果が返っています。
$ curl -ki https://ademo-***-appdomain.cloud/test-org/sandbox/v1/backend -E client_certificate.p12:admin
HTTP/1.1 200 OK
Connection: Keep-Alive
Transfer-Encoding: chunked
User-Agent: curl/7.79.1
Accept: */*
X-Client-IP: 172.30.118.51
X-Global-Transaction-ID: 1deba6ad6227061d005b6960
content-type: application/json
Date: Tue, 08 Mar 2022 07:30:37 GMT
{"mtls for backend":"ok"}
以上となります。