Docker+ActiveDirectory+nginx(certbot)でKeycloakを使いたい!


Windows Server上に構築したActiveDirectoryの認証情報を使って、OIDCなどを使用したかったのですが、その際Keycloakの構築に結構手間取ったので備忘録として

後から再構築するのを楽にするために、Docker環境を使用しています

サーバーの準備

ConoHaを使います。(学割があるのがいいですよね)

普通に、Docker環境が使えるイメージがあるので、そのまま使います(その場からDocker環境が使えるのいいですよね)

証明書の書き出し

Keycloakは、公式のDockerイメージが提供されています(サクッと構築できるの以下略
ActiveDirectoryは、オンプレで構築していて、イマドキ暗号化されていないとかあり得ない時代なので、接続はLDAPSを使用します(LDAP over SSLです、困ってググってもLDAPSではなくLDAPが引っかかったりするので注意しましょう)

AD側は、証明機関の機能をインストールして、CA証明書を発行してください(その時点で、ADもLDAPS接続が利用可能になるはずです)

本当であれば、ADに使用する証明書も、ちゃんとしたCAから発行されているものが望ましいのですが、個人レベルなので、オレオレ証明書もとい自己署名証明書を使用します

Keycloakで正しくSSL接続できるよう、ルート証明書を書き出して、トラストします

ツール→証明機関→発行した証明書から、一番要求IDが若く、証明書テンプレートが「クロス証明機関(CrossCA)」になっているものをダブルクリック


Base64 encoded X.509でエクスポートします


Dockerfileを書きます
(4行目でADDしているファイルがADを構築しているWindows Serverで書き出したルート証明書です)

Dockerfile
FROM jboss/keycloak

WORKDIR /opt/jboss/keycloak/standalone
ADD cert.pem /usr/share/pki/ca-trust-source/anchors/cert.pem
USER root
RUN keytool -import -noprompt -alias selfsigned -cacerts -file /usr/share/pki/ca-trust-source/anchors/cert.pem  -storepass changeit

JDKがデフォルトで使用している(ので合ってましたっけ、オプションなしのものは)keystoreにインストールしてあげれば大丈夫です
ストアのパスワードは changeit です(変えたほうがいいんでしょうかね)

デプロイします
そういえば、GitLabに実はContainer Registryの機能があったんですね・・・初めて知りました・・・

nginxの設定

Certbot(Let's Encrypt)を使いたいのと、個人的に圧倒的信頼があるのでnginxでリバースプロキシを行い、nginxより外はHTTPS、nginxより内側はHTTPな環境を準備します

この際、注意する点としては、実際にはHTTPSでも、Keycloakから見たらHTTPであるというところです
そのため、リソースがHTTPで埋め込まれ、Chromeなどに怒られるため、対策の設定も加えます

proxy.conf
server{
    listen 80;
    server_name YOUR_DOMAIN_NAME;

    location / {
            # プロキシ先のサーバアドレスとポート番号を指定
            return 301 https://$host$request_uri;
    }
}


# HTTPSの設定
server{
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name    YOUR_DOMAIN_NAME;

    # SSL認証キーの参照先。certbotで自動的に生成されるファイルを指定する。
    ssl_certificate     /etc/letsencrypt/live/YOUR_DOMAIN_NAME/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/YOUR_DOMAIN_NAME/privkey.pem;

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    add_header Access-Control-Allow-Origin *;

    location / {
        # プロキシ先のサーバアドレスとポート番号を指定
        proxy_pass http://localhost:8080;
    }
}