【IBM Application Gateway】Redisサーバーを使用したセッション保持について

# はじめに
IBM Security Verify にバンドルされている IBM Application GatewayをOpenshiftにデプロイして、フェイルオーバー動作について確認してみました。

フェイルオーバーの設定は大きく3つあります。
https://docs.verify.ibm.com/gateway/docs/tasks-failover

前回の記事で2つご紹介しました。
[【IBM Application Gateway】フェイルオーバー動作について](https://qiita.com/fitz/items/8fa73609ec11224675d5)

今回は3つめのRedisサーバーを使ったセッション管理についてご紹介します。

③Redisサーバーを使用した分散セッション
Redisサーバーにセッション情報を保存し、このセッション情報を他のIAGインスタンスで使用するパターン。
![qiita(1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/e287b7fa-f7a0-bb35-bddd-5fe8872e9ceb.png)



# ③Redisサーバーを使用した分散セッション

動作検証のためRedisサーバーは1台のStandalone構成で動作確認しました。

Redisサーバーは、Kubernetesのマニュアルにあるyamlファイルをもとに、Openshift上にDeployment/Serviceを作成しました。
例: Redisを使用したPHPのゲストブックアプリケーションのデプロイ
https://kubernetes.io/ja/docs/tutorials/stateless-application/guestbook/


サンプルのDeployment.yamlはイメージが「k8s.gcr.io/redis:e2e」となっているため、v6以降のRedisサーバーに変更します。
例）image: redis:latest

プロジェクトにDeployment/Serviceを作成します。

```
> oc create -f redis-master-deployment.yaml
> oc create -f redis-master-service.yaml
> oc get pods |grep redis*
redis-master-f46ff57fd-wg7nw   1/1     Running     0          7h32m
> oc get service |grep redis*
redis-master   ClusterIP   172.xx.xx.xx    <none>        6379/TCP   7h32m
```

IBM Application Gatewayの動作確認で利用したyamlファイルの一部です。
Redisサーバーの設定にあたり、Services/Serversの両方の設定が必要です。

services/redis
https://docs.verify.ibm.com/gateway/docs/yaml-services-redis

server/session
https://docs.verify.ibm.com/gateway/docs/yaml-server-session

```demo-sso.yaml
services:
  redis:
    default_collection: test-collection-session
    key_prefix: iag-test-
    collections:
      - connect_timeout: 20
        health_check_interval: 200
        idle_timeout: 100
        io_timeout: 300
        matching_host: xxxxx.jp-tok.containers.appdomain.cloud
        max_pooled_connections: 200
        name: test-collection-session
        servers:
        - host: redis-master
          name: redis-a
          port:  6379
server:
  ssl:
    front_end:
      certificate: "@secret_files/iag.certkey.pem"
  local_applications:
    cred_viewer:
      path_segment: "cred-viewer"
      enable_html: true
  session:
    cookie_name: sess_cookie
    max_sessions: 20
    timeout: 600
    inactive_timeout: 100
    redis:
      enabled: true
      key_prefix: "iag-test-"
      default_collection: test-collection-session
      client_list_cache_lifetime: 10
      concurrent_sessions:
        enabled: true
        prompt_for_displacement: true
        max_user_sessions: 15
        user_identity_attribute_name: AZN_CRED_PRINCIPAL_NAME
    reauth:
        login_time_window: 10
～～割愛～～
identity:
  oidc:
    discovery_endpoint: https://<tenant>.verify.ibm.com/oidc/endpoint/default/.well-known/openid-configuration
    client_id: <OIDC_CLIENT_ID>
    client_secret: <S_OIDC_CLIENT_SECRET>
～～割愛～～
```

IBM Application Gatewayにアクセス/Security Verifyで認証した後のアプリケーション画面を確認すると、指定した名前（sess_cookie）でセッションCookieが表示されました。
![qiita(3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/8bb25da5-2af6-5278-afd6-2e738508849e.png)


次にRedisサーバーのPodにアクセスしてデータを確認します。
1回のアクセスで、3つのエントリが生成されていました。
|データの例|データの説明|
|---|---|
|"iag-test-user-751xxxxqhv"  |単一ユーザーの同時セッションの数は、Redisの「セット」に保存される。  |
|"iag-test-client-iag-test-session-C7KW2WkiwYwc/x/6yuaXXXXXXpYWZDc="  |セッションのローカルコピーを持つIAGクライアントのリストは、Redisの「セット」に保存される。  |
|"iag-test-session-C7KW2xxxxxZDc="  |セッションデータ自体は、単一のRedisの「ハッシュ」に保存される。|

```
> oc rsh <Redisサーバーのpod名>
> redis-cli keys "*"
1) "iag-test-user-751xxxxqhv"
2) "iag-test-client-iag-test-session-C7KW2WkiwYwc/x/6yuaXXXXXXpYWZDc="
3) "iag-test-session-C7KW2xxxxxZDc="
```
![qiita(4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/bd46f53c-03b6-454e-cf2a-f3d6ea5e7a1a.png)








# JWE FailOverCookieとの比較について
マニュアルに比較があったのでChromeで機械翻訳したものを記載します。

原文はこちらをご確認ください。
Sharing Sessions
https://docs.verify.ibm.com/gateway/docs/tasks-sharing-sessions

|トピック  |JWEフェイルオーバーCookie  |Redisセッションキャッシュ  |
|---|---|---|
|安全  |ID情報は暗号化されたCookieに保存されるため、Redisセッションキャッシュよりも少し安全性が低くなります。  |DMZの背後にあるRedisセッションキャッシュで多層防御を提供します。  |
|IAGインスタンス間のフェイルオーバー  |IAGがフェイルオーバーCookieを復号化するには、より高いCPU使用率が必要です。新しいセッションが確立されます。つまり、タイムアウト情報などのセッションセマンティクスを他のIAGインスタンスと共有しません。  |Redisセッションキャッシュは、シングルサインオンメカニズムを使用するのではなく、セッションを共有します。タイムアウト情報などのセッションセマンティクスは、さまざまなIAGインスタンス間で共有されます。  |
|セッションポリシー  |同時セッションポリシーの適用はありません。セッションの集中管理はありません。  |同時セッションポリシーの実施。RedisCLIツールを使用したセッション終了を含むセッションの集中管理。  |
|メンテナンス  |企業ポリシーに沿ってフェイルオーバーCookieキーを定期的に更新する必要があります。このプロセスは手動です。  |Redisセッションキャッシュは暗号化キーを必要としません。  |
|クッキー  |フェイルオーバーCookieは、RedisセッションキャッシュセッションCookieよりも大きくなっています。フェイルオーバーCookieは、そのサイズを大幅に増加させる可能性のある多くの属性を含むように構成できます。  |Redisセッションキャッシュは、比較的小さい基本的なセッションCookieを使用します。Redisセッションキャッシュ環境のCookieは、通常100バイト未満です。  |
|ログアウト  |ブラウザのシナリオでは、フェールオーバーCookieをオンにした状態で正常にログアウトすることはできません。  |Redisセッションキャッシュを使用すると、ブラウザセッションからログアウトできます。  |

# Redisセッションキャッシュの制限について
マニュアルに制限があったのでChromeで機械翻訳したものを記載します。

原文はこちらをご確認ください。
Sharing Sessions
https://docs.verify.ibm.com/gateway/docs/tasks-sharing-sessions

- IAGインスタンスが再起動されると、そのインスタンスが参照しているセッションの非アクティブタイムアウトがリセットされます。この状況では、セッションが次にIAGインスタンスによって参照されるときに、非アクティブタイムアウトが再び開始されます。または、ライフタイムタイムアウトにより、一定期間後もセッションが期限切れになります。
- IAGは、Redisサーバーに保存されているセッションを管理するための管理インターフェースを提供していません。代わりに、redis-cliなどのネイティブRedisユーティリティを使用して、Redisサーバーに保存されているセッションデータを管理する必要があります。
- Redisクラスターのサポートは利用できません。
- IBMは、Redisサーバー自体を提供またはサポートしていません。サーバーは個別に取得および管理する必要があります。

# 最後に
IBM Applicatio Gatewayで、Redisサーバーを使用したセッション保持についてご紹介しました。
RedisサーバーのサポートはIBM Security Verify/IBM Application Gatewayには含まれていませんのでデリバリーにあたってはご注意ください。