keycloakのインストールと常時起動

ここではkeycloakをインストールし，サービスとして常時起動させるまでを記載している．

ただし，OSはubuntu24.04LTS，Webサーバはapache2であるものとしている．

# Javaのインストール

keycloakはJavaを使って動作させるので[Java JDK を Ubuntu にインストールして Hello World する](https://qiita.com/studio_meowtoon/items/4d11e94a2389758759cd)を参考に
```
$ sudo apt -y install openjdk-21-jdk
```
として準備をする．


# keycloakのインストール

2025/02/13現在　最新verは [公式ダウンロードサイト](https://www.keycloak.org/downloads) によると26.1.2である．したがって，パッケージをダウンロードして /opt の下に展開する．なお，wgetを行う際のURLは，都度 [公式ダウンロードサイト](https://www.keycloak.org/downloads) で確認すると良い．

```
# cd /opt
# wget https://github.com/keycloak/keycloak/releases/download/26.1.2/keycloak-26.1.2.tar.gz
# tar xfpz keycloak-26.1.2.tar.gz
# mv keycloak-26.1.2 keycloak
```

# とりあえず動作させてみる
上記，keycloakのパッケージについては binディレクトリのなかにあるシェルファイルで動作が出来るようになっているので，
```
$ sudo /opt/keycloak/bin/kc.sh start-dev
```
と打って動作できるか確認する．うまく動作していれば，
http://localhost:8080/
をブラウザにおいてURL指定すると以下のようにブラウザ表示される．

![スクリーンショット 2025-02-15 124436.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/773471/4f28cf3e-4ac4-4817-840e-c11b26e6850e.png)

この画面が現れたら一時的な管理者の設定（usernameとpasswordとの設定）を行う．ここで設定する一時的な管理者は恒久的なものではないため，後で恒久的な管理者の設定を行う必要がある．

# keycloakの常時起動化
上記のままだと，keycloakの動作はシェルで行っている時だけのため，常時起動するためにサービスとしておく．
[Ubuntuで起動時に自動でShellScriptを実行する方法](https://qiita.com/MAI_onishi/items/74edc40a667dd2dc633e)を参考に，keycloak.serviceを以下のように記述する．
```
$ sudo vi /etc/systemd/system/keycloak.service
```
中身は以下の通りである．
```
[Unit]
Description=Keycloak Service
After=network.target

[Service]
User=root

ExecStart=/bin/bash /opt/keycloak/start-kc.sh

Type=simple

[Install]
WantedBy=multi-user.target
```

このExecStartの行が，keycloakを実行させるコマンドと同じ意味を持っている．もし，一般ユーザが実行する場合においてsudoが必要な場合はUser=rootにすることで動作する．

また，/opt/keycloak/start-kc.sh は8080番ポートを開放する場合は，
```
/opt/keycloak/bin/kc.sh start-dev
```
と記述し，SSLに対応すべく8443番ポートを開放する場合は
```
/opt/keycloak/bin/kc.sh start-dev --https-certificate-file=/etc/certs/hogehoge/srv.hoge.org.cer --https-certificate-key-file=/etc/certs/hogehoge/hogehoge.key  --https-port=8443
```
と記述する．この記述の詳細は後述する．

`/etc/systemd/system/keycloak.service`の記述が終わったらkeycloakを常時起動するためにコンソールから
```
# systemctl daemon-reload
# systemctl enable keycloak
# systemctl restart keycloak
```
とコマンドを打つ．

# keycloak をカスタマイズする

krycloakのカスタマイズには種々あるが，https化，databeseとの接続などある．

## databaseとの接続

[Server Installation and Configuration Guide](https://keycloak-documentation.openstandia.jp/15.1.1/ja_JP/server_installation/index.html)によると，「Keycloakは、リレーショナル・データベース・マネジメント・システム（RDBMS）を使用して、レルム、クライアント、ユーザーなどのメタデータを保持します。詳細については、サーバーインストールガイドのこの章を参照してください。」
と書かれている．緊急にして必要なことはなさそうである．

しかしながら，[Ubuntu 22にKeycloak 22をインストールして、Identity providers=Azure ADでSAML](https://itc-engineering-blog.netlify.app/blogs/keycloak-saml-azuread)を参考に，ubuntuの場合であれば，postgresqlを用いて，以下のようなコマンドを打てば可能である．
```c
# apt install postgresql -y
# su - postgres
$ psql -V
psql (PostgreSQL) 14.9 (Ubuntu 14.9-0ubuntu0.22.04.1)
$ psql -d postgres
postgres=# CREATE USER keycloak WITH PASSWORD 'keycloak' CREATEDB;
CREATE ROLE
postgres=# CREATE DATABASE keycloak OWNER keycloak;
CREATE DATABASE
postgres=# \q
postgres@srv:~$ exit
```
これに伴って， /opt/keycloak/conf/keycloak.conf における以下のような部分をコメントアウトして適宜修正する．
```
# データベースの種類=PostgreSQL
db=postgres
# データベースへの接続に使用するユーザー名=keycloak
db-username=keycloak
# データベースへの接続に使用するパスワード=PASSWORD
db-password=PASSWORD
# データベースへの接続URL
db-url=jdbc:postgresql://localhost/keycloak
# ヘルスチェック（サービスの健康状態を確認する機能）有効
health-enabled=true
# メトリクス（サービスのパフォーマンスを測定するデータ）有効
metrics-enabled=true
```

## keycloakのhttps化

keycloakのWebページはhttp化されておらず8080番ポートからとなっている．このことから，8443番ポートからのhttps化を行う．

ここで，たとえば，/opt/keycloak/start-kc.shに以下のような記述をする．
```
/opt/keycloak/bin/kc.sh start-dev --https-certificate-file=/etc/certs/hogehoge/srv.hoge.org.cer --https-certificate-key-file=/etc/certs/hogehoge/hogehoge.key  --https-port=8443
```

このなかで
```
https-certificate-key-file=/etc/certs/hogehoge/hogehoge.key

https-certificate-chain-file=/etc/certs/hogehoge/certifidate-chain.cer

https-port=8443
```
のようにSSL証明書と開放ポート番号の記述が少なくとも必要である．

また，/opt/keycloak/conf/keycloak.conf に以下を書き込んでおく．
```
hostname=srv.hoge.org

http-relative-path=/auth
```
これらについて，hostnameはSSL接続の有無に関係なくlocalhostや127.0.0.1でなくても接続を可能にする部分である．つぎのhttp-relative-path=/authは `https://srv.hoge.org:8443/auth/`をkeycloakに対するURLとする場合に必要な記述である．もしhttp-relative-pathの記述がない場合はhostmaneがsrv.hoge.orgであればURLを`https://srv.hoge.org:8443/`と指定することによってkeycloakが開くようになる．


## keycloakを8443番ポートではなく443番ポートで開ける

多くの場合，Webサーバは443番ポートしか開放していないケースがある．そこで，8443番ポートではなく443番ポートを開放できるように調整する．上記のkeycloak.confにおいてhttps-port=8443 を https-port=443にすれば良いと思いきや，apacheにおけるmod-sslによる443番ポートが開いていて，keycloakにおけるhttpsとの併存が出来ないため， [keycloak無効なパラメーター：redirect_uri](https://www.web-dev-qa-db-ja.com/ja/keycloak/keycloak%E7%84%A1%E5%8A%B9%E3%81%AA%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%83%BC%EF%BC%9Aredirecturi/833075900/)を参考に， `/etc/httpd/conf.d/keycloak.conf` を以下のように記述する．
```
# 新規作成
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule ssl_module modules/mod_ssl.so
LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
LoadModule ldap_module modules/mod_ldap.so

<IfModule mod_proxy.c>
	  RewriteEngine on

	  #Disable HSTS

	  RewriteCond %{request_uri}\?%{query_string} ^(.*)redirect_uri=https(.*)$
	  RewriteRule . %1redirect_uri=http%2 [NE,R=302]
	  #forward the requests on to keycloak
	  ProxyPreserveHost On
	  ProxyPass /auth/ https://srv.hoge.org:8443/auth/
	  ProxyPassReverse /auth/ https://srv.hoge.org/auth/
	  #RemoteIPHeader X-Forwarded-For
</IfModule>
```
その後，
```
# a2ensite keycloak
# systemctl restart apache2
```
とすることで，`https://srv.hoge.org/auth/`にてkeycloakが見られるようになる．

なお，不要なLoadModuleが存在するかもしれないが，現状はこれで取りあえず動くようだ．

# 参考

1. [Java JDK を Ubuntu にインストールして Hello World する](https://qiita.com/studio_meowtoon/items/4d11e94a2389758759cd)

2. [Keycloak Managing users](https://www.keycloak.org/docs/latest/server_admin/index.html#assembly-managing-users_server_administration_guide)

3. [42.8. nftables を使用したポート転送の設定](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html/configuring_and_managing_networking/configuring-port-forwarding-using-nftables_getting-started-with-nftables#forwarding-incoming-packets-on-a-specific-local-port-to-a-different-host_configuring-port-forwarding-using-nftables
)