Last active
July 15, 2025 16:14
-
-
Save cweiland/38c5b62965bcb8b8838f8decdf7a5dbd to your computer and use it in GitHub Desktop.
Keycloak install ready to use on a debian enrolled freeipa server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
if [[ $EUID -ne 0 ]]; then | |
echo "This script must be run as root or sudo" | |
exit 1 | |
fi | |
echo "Caution : this script expect a freeipa/idm joined host." | |
echo "โ ๏ธ Would you want to continue? (y/n)" | |
read -r answer | |
case "$answer" in | |
y|Y ) | |
;; | |
n|N ) | |
echo "๐ Aborted by user." | |
exit 1 | |
;; | |
* ) | |
echo "โ Invalid input. Please answer 'y' or 'n'." | |
exit 2 | |
;; | |
esac | |
# Regex for basic FQDN validation: letters, digits, hyphens, dots | |
fqdn_regex='^([a-zA-Z0-9][-a-zA-Z0-9]*\.)+[a-zA-Z]{2,}$' | |
read -r -p "๐น Keycloak FQDN ($(hostname -f)): " kc_fqdn | |
kc_fqdn=${name:-$(hostname -f)} | |
if [[ ! $kc_fqdn =~ $fqdn_regex ]]; then | |
echo "โ Invalid Keycloak FQDN format: '$kc_fqdn'" >&2 | |
exit 1 | |
fi | |
if ! nslookup "$kc_fqdn" >/dev/null 2>&1 ; then | |
echo "โ '$kc_fqdn' not exists" >&2 | |
exit 2 | |
fi | |
URL_KEYCLOAK=https://${kc_fqdn} | |
KEYCLOAK_DB=mariadb | |
KEYCLOAK_DB_USER=keycloak | |
KEYCLOAK_DB_NAME=keycloak | |
pw_file="/opt/keycloak/conf/keycloak-db-password.txt" | |
tmp_sql_user_file="/tmp/create_user.sql" | |
echo "Install Mariadb..." | |
apt update -y | |
apt install -y mariadb-server | |
systemctl enable mariadb | |
systemctl start mariadb | |
echo "Instructions" | |
echo "Enter current password for root (enter for none): <PRESS ENTER>" | |
echo "Switch to unix_socket authentication [Y/n] <PRESS Y AND ENTER>" | |
echo "Change the root password? [Y/n] <PRESS Y AND ENTER>" | |
echo "New password: <NEW ROOT PASSWORD AND ENTER>" | |
echo "Re-enter new password: <NEW ROOT PASSWORD AND ENTER>" | |
echo "Remove anonymous users? [Y/n] <PRESS Y AND ENTER>" | |
echo "Disallow root login remotely? [Y/n] <PRESS Y AND ENTER>" | |
echo "Remove test database and access to it? [Y/n] <PRESS Y AND ENTER>" | |
echo "Reload privilege tables now? [Y/n] <PRESS Y AND ENTER>" | |
mysql_secure_installation | |
echo "Installing OpenJDK" | |
curl -fsSL "https://packages.adoptium.net/artifactory/api/gpg/key/public" | gpg --dearmor >/etc/apt/trusted.gpg.d/adoptium.gpg | |
echo 'deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/adoptium.gpg] https://packages.adoptium.net/artifactory/deb bookworm main' >/etc/apt/sources.list.d/adoptium.list | |
apt-get update | |
apt-get install -y temurin-21-jre | |
echo "Installing Keycloak" | |
groupadd keycloak | |
useradd -r -g keycloak -d /opt/keycloak -s /sbin/nologin keycloak | |
VERSION=$(curl -fsSL https://api.github.com/repos/keycloak/keycloak/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') | |
tar zxvf <(curl -fsSL "https://github.com/keycloak/keycloak/releases/download/${VERSION}/keycloak-${VERSION}.tar.gz") -C /opt | |
ln -s "/opt/keycloak-${VERSION}" "/opt/keycloak" | |
chown -R keycloak: "/opt/keycloak-${VERSION}" | |
echo "Configure database..." | |
read -r -s -p "Enter DB password for Keycloak user: " dbpass | |
echo | |
echo "$dbpass" > "${pw_file}" | |
chmod 600 "${pw_file}" | |
chown keycloak: "${pw_file}" | |
echo "DROP DATABASE IF EXISTS ${KEYCLOAK_DB_NAME};"> ${tmp_sql_user_file} | |
echo "CREATE DATABASE ${KEYCLOAK_DB_NAME};">> ${tmp_sql_user_file} | |
echo "CREATE OR REPLACE USER '${KEYCLOAK_DB_USER}'@'localhost' IDENTIFIED BY '$(cat ${pw_file})';" >> ${tmp_sql_user_file} | |
echo "GRANT ALL PRIVILEGES ON ${KEYCLOAK_DB_NAME}.* TO '${KEYCLOAK_DB_USER}'@'localhost' WITH GRANT OPTION;" >> ${tmp_sql_user_file} | |
echo "FLUSH PRIVILEGES;" >> ${tmp_sql_user_file} | |
mysql < ${tmp_sql_user_file} | |
rm -f ${tmp_sql_user_file} | |
echo "Configuration file generator..." | |
cp -p "/opt/keycloak/conf/keycloak.conf" "/opt/keycloak/conf/keycloak.conf.backup}" | |
cat <<EOF > "/opt/keycloak/conf/keycloak.conf" | |
features=hostname:v2 | |
db-url-host=localhost | |
health-enabled=true | |
metrics-enabled=true | |
https-certificate-file=/etc/pki/tls/keycloak-ssl.pem | |
https-certificate-key-file=/etc/pki/tls/keycloak-ssl.key | |
hostname=${URL_KEYCLOAK} | |
https-port=443 | |
EOF | |
echo "First start..." | |
PASSWORD=$(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 10) | |
kinit admin | |
cat <<EOF > /usr/local/sbin/set-ssl-permissions | |
#!/bin/bash | |
FILES=(/etc/pki/tls/keycloak-ssl{.key,.pem}) | |
chown keycloak: "\${FILES[@]}" | |
chmod 640 "\${FILES[@]}" | |
systemctl restart keycloak.service | |
EOF | |
chmod a+x /usr/local/sbin/set-ssl-permissions | |
ipa-getcert request -N "${kc_fqdn}" -K "HTTP/${kc_fqdn}" -k /etc/pki/tls/keycloak-ssl.key -f /etc/pki/tls/keycloak-ssl.pem -I keycloak -C /usr/local/sbin/set-ssl-permissions | |
setcap 'CAP_NET_BIND_SERVICE=+eip CAP_NET_RAW=+eip' $(readlink -f /usr/bin/java) | |
su keycloak -s/bin/bash -c "KC_DB_PASSWORD=\"$(cat ${pw_file})\" KC_DB_USERNAME=\"${KEYCLOAK_DB_USER}\" KC_DB=\"${KEYCLOAK_DB}\" KC_DB_SCHEMA=\"${KEYCLOAK_DB_NAME}\" JAVA_OPTS_APPEND=\"-Djava.net.preferIPv4Stack=true -Djava.net.preferIPv6Addresses=false\" /opt/keycloak/bin/kc.sh build" | |
su keycloak -s/bin/bash -c "KC_BOOTSTRAP_ADMIN_PASSWORD=${PASSWORD} KC_DB_PASSWORD=\"$(cat ${pw_file})\" KC_DB_USERNAME=\"${KEYCLOAK_DB_USER}\" KC_DB=\"${KEYCLOAK_DB}\" KC_DB_SCHEMA=\"${KEYCLOAK_DB_NAME}\" JAVA_OPTS_APPEND=\"-Djava.net.preferIPv4Stack=true -Djava.net.preferIPv6Addresses=false\" /opt/keycloak/bin/kc.sh bootstrap-admin user --password:env KC_BOOTSTRAP_ADMIN_PASSWORD --no-prompt --optimized" | |
echo "Creating Service" | |
mkdir /usr/lib/systemd/system/keycloak.service.d | |
cat <<EOF > /usr/lib/systemd/system/keycloak.service.d/config.conf | |
[Service] | |
Environment="KC_DB_PASSWORD=$(cat ${pw_file})" | |
Environment="KC_DB_USERNAME=${KEYCLOAK_DB_USER}" | |
Environment="KC_DB=${KEYCLOAK_DB}" | |
Environment="KC_DB_SCHEMA=${KEYCLOAK_DB_NAME}" | |
Environment="JAVA_OPTS_APPEND=-Djava.net.preferIPv4Stack=true -Djava.net.preferIPv6Addresses=false" | |
Environment="KC_HOSTNAME=${URL_KEYCLOAK}" | |
Environment="KC_FEATURES=hostname:v2" | |
EOF | |
cat <<EOF >/usr/lib/systemd/system/keycloak.service | |
[Unit] | |
Description=Keycloak Service | |
After=network.target | |
[Service] | |
WorkingDirectory=/opt/keycloak | |
ExecStart=/opt/keycloak/bin/kc.sh start --optimized | |
User=keycloak | |
Group=keycloak | |
[Install] | |
WantedBy=multi-user.target | |
EOF | |
systemctl enable --now keycloak.service | |
echo "URL : ${URL_KEYCLOAK}" | |
echo "URL : ${URL_KEYCLOAK}:9000" | |
echo "Username : temp-admin" | |
echo "Password : ${PASSWORD}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment