« Keycloak » : différence entre les versions
Ajout d'étape d'installation |
Finalisation de la page |
||
| Ligne 3 : | Ligne 3 : | ||
== Configuration actuelle == | == Configuration actuelle == | ||
Le service [[Nginx | Le service [[Nginx]] transfère les pages web du port '''8127''' (géré par Keycloak) vers le port '''443''' (https) sur le domaine <code>wiki.linarphy.net</code>. Les données sont gérés par [[Postgresql]] via une base de donnée ayant pour nom '''keycloak''' et pour utilisateur '''keycloak'''. Cette instance stocké dans le dossier <code>/usr/share/keycloak/</code> tourne sur la version '''26.0.0''' avec '''openjdk-21.0.2''' (lui-même dans <code>/usr/share/openjdk/21/</code>). | ||
== Installation == | == Installation == | ||
| Ligne 9 : | Ligne 9 : | ||
=== Prérequis === | === Prérequis === | ||
* [[Nginx | * [[Nginx]] | ||
* [[Postgresql]] | * [[Postgresql]] | ||
* [[Certbot]] | * [[Certbot]] | ||
* [[Freeipa-client]] | |||
=== Procédure === | === Procédure === | ||
| Ligne 20 : | Ligne 21 : | ||
Le dossier peut ensuite être déplacé dans son emplacement final (<code>/usr/share/keycloak/</code>) avec la commande <code>mv keycloak-26.0.0 /usr/share/keycloak</code>(toujours en tant que '''root'''). | Le dossier peut ensuite être déplacé dans son emplacement final (<code>/usr/share/keycloak/</code>) avec la commande <code>mv keycloak-26.0.0 /usr/share/keycloak</code>(toujours en tant que '''root'''). | ||
==== Java ==== | |||
Télécharger OpenJDK 21 avec la commande <code>curl -L {lien-targz-openjdk-21} -o openjdk-21.tar.gz</code> en tant que '''root'''. Le lien vers l'archive est disponible [https://jdk.java.net/archive/ ici]. Puis extraire l'archive: <code>tar -xf openjdk-21.tar.gz</code> et supprimer l'archive téléchargée: <code>rm openjdk-21.tar.gz</code>. Si le dossier n'existe pas déjà, crée le dossier <code>/usr/share/openjdk/</code> avec la commande <code>mkdir /usr/share/openjdk</code> puis déplacer le dossier extrait vers son emplacement final: <code>mv jdk-21.0.2 /usr/share/openjdk/21</code>. | |||
Pour se lier au service '''LDAP''' du [[Freeipa-server|serveur FreeIPA]], il est nécessaire d'ajouter les clefs publics des certificats utilisés pour sécuriser la connexion. L’utilisation de la commande <code>/usr/share/openjdk/21/bin/keytool -v -import -file /etc/ipa/ca.crt -alias ipacrt -keystore /usr/share/openjdk/21/lib/security/cacerts</code> permet d'effectuer cette opération (ajouter la clef public du certificat du serveur au stockage de clef public de l'installation de java qui va être utilisé par Keycloak). | |||
==== Permissions ==== | ==== Permissions ==== | ||
| Ligne 25 : | Ligne 31 : | ||
Le service s'exécutera avec un utilisateur particulier (et non '''root''') pour isoler le processus. Il est donc nécessaire de créer l'utilisateur local '''keycloak''' avec la commande <code>adduser --system --no-create-home --group keycloak</code> en tant que '''root'''. La commande <code>chown -R keycloak:keycloak /usr/share/keycloak/</code> pour donner les permissions du dossier à ce nouvel utilisateur. | Le service s'exécutera avec un utilisateur particulier (et non '''root''') pour isoler le processus. Il est donc nécessaire de créer l'utilisateur local '''keycloak''' avec la commande <code>adduser --system --no-create-home --group keycloak</code> en tant que '''root'''. La commande <code>chown -R keycloak:keycloak /usr/share/keycloak/</code> pour donner les permissions du dossier à ce nouvel utilisateur. | ||
Keycloak sera accessible via une connexion chiffré (https), et sa configuration nécessite l'accès à la clef privé et public utilisé pour cette connexion (comme [[Nginx]]). Pour protéger ces clefs et ne pas les rendre accessible à d'autres utilisateur que '''keycloak''', un hook (script) sera mis en place pour être exécuté par [[Certbot]]. Il va donc être nécessaire de créer le dossier <code>/usr/share/keycloak/certs</code> via la commande <code>mkdir /usr/share/keycloak/certs</code> en tant que '''root''' (oui oui, pas '''keycloak''' pour le moment, c'est normal), puis de modifier ces permissions avec les commandes <code>chown keycloak:keycloak /usr/share/keycloak/certs</code> et <code>chmod 500 /usr/share/keycloak/certs</code>. Créer ensuite le fichier <code>/usr/share/keycloak/certs/hook.sh</code> toujours en tant que '''root''' avec l'éditeur de sont choix contenant le script: | |||
<syntaxhighlight lang="bash" line="1"> | |||
#!/usr/bin/env sh | |||
# adapted from https://gist.github.com/Sternerson/file-ssl-deploy-hook-L1 | |||
KEYCLOAK_CERT_DIR=/usr/share/keycloak/certs | |||
umask 077 # the certificate are not world readable during the copying | |||
cp "${RENEWED_LINEAGE}/privkey.pem" "${KEYCLOAK_CERT_DIR}/privkey.pem" | |||
cp "${RENEWED_LINEAGE}/fullchain.pem" "${KEYCLOAK_CERT_DIR}/fullchain.pem" | |||
chown keycloak:keycloak "${KEYCLOAK_CERT_DIR}/privkey.pem" | |||
chown keycloak:keycloak "${KEYCLOAK_CERT_DIR}/fullchain.pem" | |||
chmod 400 "${KEYCLOAK_CERT_DIR}/privkey.pem" | |||
chmod 400 "${KEYCLOAK_CERT_DIR}/fullchain.pem" | |||
</syntaxhighlight> | |||
Exécuter la commande <code>chmod +x /usr/share/keycloak/hook.sh</code> pour permettre l'exécution du script. Les permissions de ce fichier ne vont pas être autrement modifié, le script ne sera exécuté que par l'utilisateur '''root'''. | Exécuter la commande <code>chmod +x /usr/share/keycloak/hook.sh</code> pour permettre l'exécution du script. Les permissions de ce fichier ne vont pas être autrement modifié, le script ne sera exécuté que par l'utilisateur '''root'''. | ||
==== Configuration ==== | ==== Configuration ==== | ||
<syntaxhighlight lang="ini" line="1"> | |||
# Basic settings for running in production. Change accordingly before deploying the server. | |||
# Database | |||
# The database vendor. | |||
#db=postgres | |||
db=postgres | |||
# The username of the database user. | |||
#db-username=keycloak | |||
db-username=keycloak | |||
# The password of the database user. | |||
#db-password=password | |||
db-password={keycloak-postgresql-password} | |||
# The full database JDBC URL. If not provided, a default URL is set based on the selected database vendor. | |||
#db-url=jdbc:postgresql://localhost/keycloak | |||
db-url=jdbc:postgresql://localhost/keycloak | |||
# Observability | |||
# If the server should expose healthcheck endpoints. | |||
#health-enabled=true | |||
health-enabled=true | |||
# If the server should expose metrics endpoints. | |||
#metrics-enabled=true | |||
metrics-enabled=true | |||
# HTTP | |||
# The file path to a server certificate or certificate chain in PEM format. | |||
#https-certificate-file=${kc.home.dir}conf/server.crt.pem | |||
https-certificate-file=${kc.home.dir}/certs/fullchain.pem | |||
# The file path to a private key in PEM format. | |||
#https-certificate-key-file=${kc.home.dir}conf/server.key.pem | |||
https-certificate-key-file=${kc.home.dir}/certs/privkey.pem | |||
# The proxy address forwarding mode if the server is behind a reverse proxy. | |||
#proxy=reencrypt | |||
# Do not attach route to cookies and rely on the session affinity capabilities from reverse proxy | |||
#spi-sticky-session-encoder-infinispan-should-attach-route=false | |||
# Hostname for the Keycloak server. | |||
#hostname=myhostname | |||
hostname=auth.linarphy.net | |||
## Added manually | |||
proxy-headers=xforwarded | |||
https-port=8127 | |||
</syntaxhighlight> | |||
==== Nginx ==== | ==== Nginx ==== | ||
Créer le fichier <code>/etc/nginx/sites-available/auth.linarphy.net</code> contenant la configuration | Créer le fichier <code>/etc/nginx/sites-available/auth.linarphy.net</code> contenant la configuration Nginx suivante: | ||
<syntaxhighlight lang="nginx" line="1"> | |||
server { | |||
server_name auth.linarphy.net; | |||
listen 80; | |||
listen [::]:80; | |||
} | |||
</syntaxhighlight> | |||
Puis créer un lien symbolique avec la commande <code>ln -s /etc/nginx/sites-available/auth.linarphy.net /etc/nginx/sites-enabled/auth.linarphy.net</code> et tester la configuration via <code>nginx -t</code>. Si la configuration est valide, il est nécessaire de recharger le service systemd avec <code>systemctl reload nginx</code> et mettre en place le chiffrement ssl avec <code>certbot --nginx --domain auth.linarphy.net --deploy-hook=/usr/share/keycloak/certs/hook.sh</code>. | Puis créer un lien symbolique avec la commande <code>ln -s /etc/nginx/sites-available/auth.linarphy.net /etc/nginx/sites-enabled/auth.linarphy.net</code> et tester la configuration via <code>nginx -t</code>. Si la configuration est valide, il est nécessaire de recharger le service systemd avec <code>systemctl reload nginx</code> et mettre en place le chiffrement ssl avec <code>certbot --nginx --domain auth.linarphy.net --deploy-hook=/usr/share/keycloak/certs/hook.sh</code>. | ||
Vérifier ensuite sur un navigateur l'accès au service sur le protocole https. | Vérifier ensuite sur un navigateur l'accès au service sur le protocole https. | ||
<syntaxhighlight lang="nginx" line="1"> | |||
server { | |||
# adapted from https://github.com/keycloak/keycloak/discussions/13441 (Igortorrente) | |||
server_name auth.linarphy.net; | |||
listen [::]:443 ssl ipv6only=on; # managed by Certbot | |||
listen 443 ssl; # managed by Certbot | |||
proxy_set_header Host $host; | |||
proxy_set_header X-Real-IP $remote_addr; | |||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
proxy_set_header X-Forwarded-Host $host; | |||
proxy_set_header X-Forwarded-Proto $scheme; | |||
location / { | |||
return 301 https://$host/realms/linarphy.net/account/#/; | |||
} | |||
location / { | |||
proxy_pass https://localhost:8127; | |||
} | |||
location /admin/ { | |||
deny all; | |||
allow {private-ip}; | |||
proxy_pass https://localhost:8127; | |||
} | |||
location /health/ { | |||
deny all; | |||
allow {private-ip}; | |||
proxy_pass https://localhost:8127; | |||
} | |||
location /js/ { | |||
proxy_pass https://localhost:8127; | |||
} | |||
location /metrics/ { | |||
deny all; | |||
allow {private-ip}; | |||
proxy_pass https://localhost:8127; | |||
} | |||
location /realms/ { | |||
proxy_pass https://localhost:8127; | |||
} | |||
location /resources/ { | |||
proxy_pass https://localhost:8127; | |||
} | |||
ssl_certificate /etc/letsencrypt/live/auth.linarphy.net/fullchain.pem; # managed by Certbot | |||
ssl_certificate_key /etc/letsencrypt/live/auth.linarphy.net/privkey.pem; # managed by Certbot | |||
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot | |||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot | |||
} | |||
server { | |||
server_name auth.linarphy.net; | |||
listen 80; | |||
listen [::]:80; | |||
location / { | |||
return 301 https://$host$request_uri; | |||
} | |||
return 404; # managed by Certbot | |||
} | |||
</syntaxhighlight> | |||
==== Base de donnée ==== | |||
En tant qu'utilisateur '''postgres''', lancer la commande <code>psql</code> puis exécuter les commandes suivantes: | |||
* <code>CREATE DATABASE keycloak;</code> | |||
* <code>CREATE USER keycloak WITH ENCRYPTED PASSWORD '{keycloak-postgresql-password}';</code> | |||
* <code>GRANT ALL PRIVILEGES ON DATABASE keycloak TO keycloak;</code> | |||
* <code>\c keycloak</code> | |||
* <code>GRANT ALL ON SCHEMA public TO keycloak;</code> | |||
* <code>\q</code> | |||
==== Systemd ==== | |||
Lancer la commande <code>systemctl edit --full --force keycloak.service</code> pour écrire l'unité systemd suivante avec l'éditeur de votre choix ([[systemd]] utilise la variable d'environnement '''EDITOR'''): | |||
<syntaxhighlight lang="systemd" line="1"> | |||
[Unit] | |||
Description=Keycloak authentication server connected to the FreeIPA LDAP | |||
Documentation=https://keycloak.org/documentation | |||
After=network-online.target | |||
[Service] | |||
User=keycloak | |||
Restart=on-failure | |||
RestartSec=2s | |||
WorkingDirectory=/usr/share/keycloak | |||
ExecStart=/usr/share/keycloak/bin/kc.sh start --optimized | |||
TimeoutStopSec=10s | |||
KillSignal=SIGTERM | |||
KillMode=process | |||
SendSIGKILL=no | |||
SuccessExitStatus=143 | |||
[Install] | |||
WantedBy=multi-user.target | |||
</syntaxhighlight> | |||
Puis crée un second fichier de configuration supplémentaire avec <code>systemctl edit keycloak.service</code> et y écrire: | |||
<syntaxhighlight lang="systemd" line="1"> | |||
[Service] | |||
Environment="JAVA_HOME=/usr/share/openjdk/21" | |||
</syntaxhighlight> | |||
Pour mieux organiser la configuration, modifier le nom du fichier de réécriture avec <code>mv /etc/systemd/system/keycloak.service.d/override.conf /etc/systemd/system/keycloak.service.d/env.conf</code>. | |||
==== Configuration ==== | |||
Toute cette étape sera suivie par l'utilisateur '''keycloak''' dans le dossier <code>/usr/share/keycloak/</code>. | |||
D'abord, construisez la configuration avec la commande <code>./bin/kc.sh build</code> jusqu'à attendre la fin, puis lancer une première fois keycloak avec <code>./bin/kc.sh start</code>. Une fois que le message ''(main) Installed features: [...]'' s'affiche, appuyer sur '''Ctrl+C''' pour arrêter le programme. | |||
Si tout allait bien, il aurait suffit de définir les variables d'environnement '''KC_BOOTSTRAP_ADMIN_USERNAME''' et '''KC_BOOTSTRAP_ADMIN_PASSWORD''' pour définir respectivement le nom d'utilisateur et le mot de passe de l'administrateur du service, puis de lancer les commandes précédentes. Malheureusement, le monde n'est pas parfait. Du coup il est nécessaire d'effectuer la commande <code>./bin/kc.sh bootstrap-admin user</code> puis de définir le nom d'utilisateur et le mot de passe de l'administrateur. | |||
==== Finalisation ==== | |||
Activer et lancer le service [[systemd]] en exécutant <code>systemctl enable keycloak</code> puis <code>systemctl start keycloak</code>. | |||
=== Configuration post-installation === | |||
==== Création du realm ==== | |||
Une fois connecté sur le nouveau site, cliquer sur le menu déroulant en haut à gauche ('''Keycloak''' master) et cliquer sur '''Create realm'''. Et définir son nom. C'est ce ''realm'' qui va relier l'authentification de tous les services. | |||
==== Liaison avec FreeIPA ==== | |||
Dans l'onglet "Fédération utilisateur" du nouveau ''realm'', ajouter un nouveau fournisseur '''LDAP''' et y insérer la configuration suivante (les entrées non définie sur celui-ci sont laissé par défaut): | |||
{| class="wikitable" | |||
|+ | |||
!clef | |||
!valeur | |||
|- | |||
|vendor | |||
|Red Hat Directory Server | |||
|- | |||
|connection URL | |||
|ldaps://admin0.linarphy.net:636 | |||
|- | |||
|enable StartTLS | |||
|Off | |||
|- | |||
|user truststore SPI | |||
|Always | |||
|- | |||
|bind DN | |||
|uid=admin,cn=users,cn=accounts,dc=linarphy,dc=net | |||
|- | |||
|bind credentials | |||
|{password-admin-freeipa} | |||
|- | |||
|edit mode | |||
|READ_ONLY | |||
|- | |||
|users DN | |||
|cn=users,cn=accounts,dc=linarphy,dc=net | |||
|- | |||
|username LDAP attribute | |||
|uid | |||
|- | |||
|RDN LDAP attribute | |||
|uid | |||
|- | |||
|UUID LDAP attribute | |||
|ipaUniqueID | |||
|- | |||
|user object classes | |||
|inetOrgPerson, organizationalPerson | |||
|- | |||
|search scope | |||
|One Level | |||
|- | |||
|import users | |||
|On | |||
|- | |||
|sync Registrations | |||
|On | |||
|} | |||