Docker上で認証情報をまとめたい
[以前書いた記事] (https://qiita.com/tosier/items/8342e6d968f64f0f79a9)の延長上のお話。
(ちなみに、GitLab本体の日本語対応がされたものの、日本語化自体はあまり進んでいないので、上記記事のままだったりします)
GitLabだけならいいけど、いろいろサービスを増やすとなると問題となるのがユーザーの登録と管理。
どこか1カ所でまとめたい。ついでに言うと、SSOまで出来ればうれしい。(GitLabでもできるじゃんというのはおいといて)
認証やSSOで検索を行うと...
認証と言えばActiveDirectoryだけど無償でという要件の時は使えないし、LDAPはいろいろなところで使えるけど管理が大変そう。(よくわからない)
あと、SSOで検索すると[OpenAM] (https://www.forgerock.com/platform/access-management/)が出てくるけど、もはや何がオープンなのかわからない上にトライアルのダウンロードの時点で挫折したので使いません。
[Atlassian] (https://ja.atlassian.com/)の[Crowd] (https://ja.atlassian.com/software/crowd)も[Confluence] (https://ja.atlassian.com/software/confluence)を使っているから興味はあるものの、ADとかと一緒で有償なので断念。
そこでKeyCloak
あきらめてしばらくたった頃に、[KeyCloak] (http://www.keycloak.org/)の[記事](http://www.atmarkit.co.jp/ait/articles/1708/31/news011.html)をみつけた。
OSSで見た目もいいし(モチベーション大事!)、要件をかなり満たしてそうなので、試してみようとおもったのが今回の記事のきっかけ。
ちなみにこんな画面。
日本語記事がないため、使ってみたいという人に役立ってくれれば。(未検証で自分に合っているかもまだわからない。。。)
今回の構成
上にも書いたとおり、機能検証はまだなのでKeyCloakのセットアップまで。
下記構成で行います。
- Ubuntu 16.04 LTS
特に苦労したのがMariaDB(JDBC)の構成。(ただし、運用上で問題があるためもう少し調整が必要)
まずはMariaDBの構成
Docker-Composeとは関係のないほうからセットアップ(パスは最終的に配置されるパス)
JDBCドライバのロード準備
- [ここ] (https://downloads.mariadb.org/connector-java/)からJDBCドライバ(mariadb-java-client-x.x.x.jar)をダウンロードします。
- モジュールを読み込むためのXMLファイルを作成します。(nameの中身は後に配置する
layers/keycloak/
配下のファイルパスと合わせる必要があることに注意)
<?xml version="1.0" ?>
<module xmlns="urn:jboss:module:1.3" name="org.mariadb.jdbc">
<resources>
<resource-root path="mariadb-java-client-x.x.x.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
</dependencies>
</module>
KeyCloak本体とJDBCの接続設定
-
ExampleDSは必要ないので消します。
-
jndi-name
はdefault-bindings
のdatasource
とあわせます。 -
datasource
内のdriver
はdrivers
のdriver
と合わせます。 -
drivers
のxa-datasource-class
はJDBC内にあるクラスを設定すること(必要に応じてjarの展開が必要) -
connection-url
はMariaDBのサイトを参考にします。 -
UTF-8の設定は不十分? (あってるか少しあやしい)
...
<subsystem xmlns="urn:jboss:domain:datasources:5.0">
<datasources>
<datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true">
<connection-url>jdbc:mariadb://keycloak-mariadb:3306/keycloak?useUnicode=true&characterEncoding=utf8</connection-url>
<driver>mariadb</driver>
<security>
<user-name>keycloak-db</user-name>
<password>password</password>
</security>
</datasource>
<drivers>
<driver name="mariadb" module="org.mariadb.jdbc">
<xa-datasource-class>org.mariadb.jdbc.MariaDbDataSource</xa-datasource-class>
</driver>
</drivers>
</datasources>
</subsystem>
...
<default-bindings context-service="java:jboss/ee/concurrency/context/default" datasource="java:jboss/datasources/KeycloakDS" managed-executor-service="java:jboss/ee/concurrency/executor/default" managed-scheduled-executor-service="java:jboss/ee/concurrency/scheduler/default" managed-thread-factory="java:jboss/ee/concurrency/factory/default"/>
...
もしサブディレクトリを変更したい場合はweb-content
の中身を書き換えます。
...
<subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
<web-context>keycloak</web-context>
...
運用上の問題点
実はこの設定だけでは何もせずに時間が経過するとConnection Timeoutが発生して再起動しないと認証出来ないという問題がある様子。
タイムアウトを伸ばすか、SQLによるハートビートを行う必要がある?
リバースプロキシの設定
リバースプロキシを使用する場合はリバースプロキシがKeyCloakに情報を渡す必要があります。(サーバー名のkeycloak
はdocker-composeで指定)
...
location /keycloak {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://keycloak:8080/keycloak;
access_log /var/log/nginx/keycloak_access.log;
error_log /var/log/nginx/keycloak_error.log;
}
...
docker-composeの準備
フォルダ構成
docker-compose用のディレクトリ構成は以下(logsの配置を忘れるとパーミッション不足で落ちるかも)
base
│ docker-compose.yml
│
├─keycloak
│ ├─configuration
│ │ standalone.xml
│ │
│ ├─driver
│ │ mariadb-java-client-2.2.0.jar
│ │ module.xml
│ │
│ └─logs
└─nginx
├─conf.d
│ reverseproxy.conf
│
├─html
│ 50x.html
│ index.html
│
└─logs
docker-compose.ymlの準備
version: "2"
services:
# KeyCloak data volume container
keycloak-data:
image: library/busybox:latest
volumes:
- ./keycloak/database:/var/lib/mysql
- ./keycloak/driver:/opt/jboss/keycloak/modules/system/layers/keycloak/org/mariadb/jdbc
- ./keycloak/logs:/opt/jboss/keycloak/standalone/log
- ./keycloak/configuration/standalone.xml:/opt/jboss/keycloak/standalone/configuration/standalone.xml:ro
# MariaDB for KeyCloak
keycloak-mariadb:
image: library/mariadb:10.2
restart: always
volumes_from:
- keycloak-data
expose:
- "3306"
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: keycloak
MYSQL_USER: keycloak-db
MYSQL_PASSWORD: password
# KeyCloak
keycloak:
image: jboss/keycloak:3.4.0.Final
restart: always
volumes_from:
- keycloak-data
links:
- keycloak-mariadb
expose:
- "8080"
environment:
KEYCLOAK_USER: admin
KEYCLOAK_PASSWORD: admin
PROXY_ADDRESS_FORWARDING: "true"
...
ここで重要になるのがkeycloak
コンテナのenvironment
にPROXY_ADDRESS_FORWARDING: "true"
を指定すること。
リバースプロキシを経由する場合はこれを設定しないとリダイレクトに失敗します。(standalone.xmlでも設定可能)
また、ボリュームコンテナのファイルの配置はもちろんのこと、データベースのパスワード等も注意すること。
実行
これで準備は整いました。
sudo docker-compose up -d
-
http://サーバー名/keycloak/admin
にアクセスして、docker-compose.ymlで指定したユーザー名とパスワードでログイン - 新しくユーザーを作成し、パスワード設定とadmin権限の付与(どちらも忘れやすいので注意!)を行う。
- ログアウトした後、作成したユーザーでログインし、2のユーザーを無効化する。
3と4はセキュリティ対策になります。yamlから消してパスワード変更でもいいかと思いますのでお好みで。(試してません)
最後に
JDBCが自由に選べる分、設定に時間が掛かったのが難点でした。
あと、書いているうちに疲れてしまって読みにくくなってしまいました。
ただ、見た目が使いやすそうに見えるし、メール認証とかも出来るので今のところかなり好印象です。
今見つかっている問題はメールドメインのホワイトリストが使えるか微妙なところかな?
AD等の連携も出来るのでSSOとかの為だけにも使用できそう?
あとはSSOが設定できるかな。。。(OpenID Connectはできるみたいだけど)
今回はこちらにコミットしてあります。
参考
[KeyCloak Guide Overview] (http://www.keycloak.org/docs/latest/server_installation/index.html)
[nginx - Configure reverse-proxy for Keycloak docker with custom base URL] (https://stackoverflow.com/questions/44624844/configure-reverse-proxy-for-keycloak-docker-with-custom-base-url)