機関の方言は対外系で止まる
一言でいうと
外部連携ゲートウェイ(FEP)は、銀行の外にある機関とつながる中継層です。機関ごとに電文規格・証明書・許可アドレスが違い、その違いを内側のシステムが知らなくて済むように1か所(FEP)に閉じ込めることが、この層の存在理由です。内側はLH-STD標準だけを知り、FEPが機関ごとの方言に翻訳し、機関ごとの身元(証明書)でつながります。
なぜ必要なのか
内部システム同士なら、標準を決められます。LabHub銀行の中では、全員がLH-STDヘッダーを使います。ところが他行・信用情報会社・カード会社・保険会社は、それぞれ自分の規格を持っていて、こちらに合わせてはくれません。電文長が自分自身を含む機関もあれば、JSONをHTTPSで受け取る機関もあり、応答コードが2桁の機関もあります。この違いを勘定系が直接扱い始めると、機関が1つ増えるたびに元帳システムを直すことになります。
セキュリティの重みも違います。内部ネットワークは自分たちが管理していますが、外部の区間は他人のネットワークとつながります。そのため外部連携は、ほぼ常に相互認証です。こちらが機関のサーバーを確認するのとまったく同じように、機関もこちらが誰なのかを証明書で確認します。受ける側も同様で、取り決めた機関のアドレスから来た接続だけを受け付けます。証明書は機関ごとに別々に発行を受け、有効期限がまちまちで、更新手順もまちまちです。これらを1か所で管理しないと、ある日1つの機関の証明書が黙って期限切れになり、その機関との取引がすべて止まります。
どう動くのか
相互TLS(mTLS)。TLS 1.3(RFC 8446)では、サーバーがハンドシェイク中にCertificateRequestを送って、クライアント証明書を要求できます。クライアントは、自分の証明書と、その証明書の秘密鍵でハンドシェイクの内容に署名したCertificateVerifyを送ります。サーバーは、その証明書が自分が信頼するCAにつながるかを検証し、つながらなければアラート(alert)を送って切断します。そのため、ガラム銀行のCAが署名した証明書でハヌル信用情報につなぐと、ハンドシェイクの段階で拒否されます。逆にこちらも、機関のサーバー証明書をその機関のCAで検証します。どんな証明書でも信用すると、中間者に取引を渡してしまいます。
CSRとプライベートCA。機関連携用の証明書は、たいていパブリックCAではなく、機関が運営するプライベートCAが発行します。こちらは秘密鍵を作り、その公開鍵を含む証明書署名要求(CSR)を送ります。秘密鍵はこちらの外へ出ません。機関が署名して返した証明書には、拡張キー使用法(extendedKeyUsage)にクライアント認証が書かれます。証明書のパス検証と有効期間(notBefore・notAfter)は、X.509プロファイルであるRFC 5280が定めており、有効期間外の証明書は検証に失敗します。
機関プロファイル。機関ごとに違う値は、コードではなくデータに置きます(モジュール2のルーティング表と同じ考え方です)。アドレス・ポート、形式(固定長/JSON)、エンコーディング、長さの基準、CA・証明書・秘密鍵のパス、許可する送信元アドレスです。コードには機関名が登場せず、プロファイルを読んでアダプターを選びます。新しい機関は、プロファイル1行とアダプター1つでつながります。
規格の翻訳。内側の標準リクエスト(JSON)を受け取って機関の規格に変え、機関のレスポンスをもう一度標準に変えます。このコースのガラム銀行は、電文長が自分自身の4バイトを含みます。LH-STDは含めません。同じ104バイトの電文で、一方は0104、一方は0100を使います。この違いを間違えると、機関のサーバーは長さの分だけ読んで残りの4バイトを次の電文と取り違えるか、足りない4バイトを待ってタイムアウトになります。応答コードも翻訳します。ガラム銀行の14(口座なし)は、内側ではB202です。チャネルは、機関がどこであっても同じコードを見ます。
受ける側の二重の守り。機関がこちらにかけてくる接続は、ファイアウォールが1次で絞り込んでも、アプリケーションがもう一度送信元アドレスを確認します。ファイアウォールのルールは別のチームが変更し、FEPのプロファイルはこちらが管理します。片方が間違えても、もう片方が防げるように二重にするのです。許可リストにないアドレスは、1バイトも読まずに切断し、記録を残します。記録がなければ、誰がノックしたのかわかりません。
期限の監視。証明書のnotAfterを定期的に読み、残り日数が基準より少なければ警告します。機関の証明書の更新には、CSRの送付・署名・反映まで数週間かかることもあるので、警告は更新期間よりも余裕をもって先に鳴らす必要があります。
現場での姿
外部連携の障害の常連は3つです。1つ目は、証明書の期限切れです。1年の証明書を開通時に入れて、誰もカレンダーに書き込みませんでした。明け方に、ある機関との取引がすべてハンドシェイクエラーで止まり、ログには「certificate expired」の1行だけが残ります。2つ目は、証明書の取り違えです。機関が複数あって証明書のファイル名が似ていたため、更新作業で別の機関の証明書を差し込んでしまいました。サーバーは「unknown ca」で拒否します。3つ目は、規格の勘違いです。開発時は自分たちで作った模擬サーバーでテストして通ったのに、開通日に本物の機関は長さの基準が違っていて、最初の電文から形式エラーを返してきます。インターフェース仕様書の1行を、模擬サーバーが違うふうに真似ていたのです。そのため外部連携は、機関が提供するテスト環境で、機関のサーバーで確認します。
次のラボですること
2つの機関(ガラム銀行201、ハヌル信用情報301)のプライベートCAをフィクスチャとして作り、機関ごとに鍵とCSRを作って署名を受けます。機関プロファイルを書き、ガラム銀行と相互TLSで接続を確認し、証明書を取り違えて差し込むと拒否されることを再現します。そのあと、機関ごとに証明書と形式を選んで送るfepgw.py、許可アドレスからだけ受けるinbound.py、期限を監視するcertcheck.pyを作ります。