Install Keycloak on CentOS 7 with MySQL backend
Keycloak is an open source Identity and Access Management solution we're going to install on a CentOS 7 machine. The Keycloak application including the MySQL server requires at least 2 CPU cores and 2 GB of memory. It's recommended to have 4 GB memory when you're going to have a lot of traffic to this identity server.
Install Keycloak
Keycloak is based on Wildfly and requires Java 8. We're using the YUM package manager to install all required dependencies.
$ yum install java-1.8.0-openjdkWe're going to run the Keycloak application with user 'keycloak'. Add the user and group to your machine.
$ groupadd -r keycloak
$ useradd -m -d /var/lib/keycloak -s /sbin/nologin -r -g keycloak keycloakKeycloak doesn't provide a RPM so we're going to install it manually. In this blog post I'm using the following paths:
- Base path: /opt/keycloak
- Application path: /opt/keycloak/current
The application path is a symlink to a specific version. This simplifies the upgrade process in the future.
Go to the download page of Keycloak and get the URL of the latest final version. Download the final Keycloak version from the website and extract it into /opt/keycloak/$version. Use a symlink to link Keycloak to /opt/keycloak/current.
$ curl https://downloads.jboss.org/keycloak/4.5.0.Final/keycloak-4.5.0.Final.tar.gz -o keycloak.tar.gz
$ mkdir -p /opt/keycloak/4.5.0
$ ln -s /opt/keycloak/4.5.0 /opt/keycloak/current
$ tar -xzf keycloak.tar.gz -C /opt/keycloak/current --strip-components=1
$ chown keycloak: -R /opt/keycloakLimit access to standalone file because it contains sensitive data.
$ cd /opt/keycloak/current
$ sudo -u keycloak chmod 700 standaloneWe're going to run Keycloak on MySQL instead of the default H2 database. First, install the MySQL Yum repository.
$ yum install -y https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpmThis will install the MySQL repository with the MySQL 8.0 repository enabled by default. Because Keycloak doesn't support MySQL 8.0 yet, disable the MySQL 8.0 repository and enable the MySQL 5.7 repository.
$ yum-config-manager --disable mysql80-community
$ yum-config-manager --enable mysql57-communityInstall and start the MySQL server.
$ yum install mysql-server
$ systemctl start mysqldThe MySQL server generates a temporary password which can be found in the log file located in the /var/log directory. Change this temporary password to something else before proceeding.
$ mysqladmin -p passwordSave the MySQL credentials in the home directory of the root user.
$ cat > /root/.my.cnf <<EOF
[client]
user=root
password="YOURPASS"
EOFCreate a database and user account for Keycloak (change YOURPASS to your something random).
$ mysql
mysql$ CREATE DATABASE keycloak;
mysql$ CREATE USER 'keycloak'@'localhost' IDENTIFIED BY 'YOURPASS';
mysql$ GRANT ALL PRIVILEGES ON keycloak.* TO 'keycloak'@'localhost';
mysql$ FLUSH PRIVILEGES;
mysql$ exit;Configure Keycloak to use MySQL. Download the MySQL connector for Java.
$ curl -L http://central.maven.org/maven2/mysql/mysql-connector-java/5.1.46/mysql-connector-java-5.1.46.jar -o /root/mysql-connector-java-5.1.46.jarOpen the Jboss CLI and add the MySQL module (you don't have to connect with the Jboss websocket).
$ ./bin/jboss-cli.sh
jboss-cli$ module add --name=org.mysql --dependencies=javax.api,javax.transaction.api --resources=/root/mysql-connector-java-5.1.46.jar
jboss-cli$ exitAdd the MySQL driver to the configuration.
$ sudo -u keycloak ./bin/jboss-cli.sh 'embed-server,/subsystem=datasources/jdbc-driver=mysql:add(driver-name=mysql,driver-module-name=org.mysql,driver-class-name=com.mysql.jdbc.Driver)'
Remove the h2 KeycloakDS data source and add the MySQL KeycloakDS data source. (Don't delete the test database and change YOURPASS to something random)
$ sudo -u keycloak ./bin/jboss-cli.sh 'embed-server,/subsystem=datasources/data-source=KeycloakDS:remove'
$ sudo -u keycloak ./bin/jboss-cli.sh 'embed-server,/subsystem=datasources/data-source=KeycloakDS:add(driver-name=mysql,enabled=true,use-java-context=true,connection-url="jdbc:mysql://localhost:3306/keycloak?useSSL=false&useLegacyDatetimeCode=false&serverTimezone=Europe/Amsterdam&characterEncoding=UTF-8",jndi-name="java:/jboss/datasources/KeycloakDS",user-name=keycloak,password="YOURPASS",valid-connection-checker-class-name=org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLValidConnectionChecker,validate-on-match=true,exception-sorter-class-name=org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLValidConnectionChecker)'Add management user to keycloak (change YOURPASS to your something random).
$ sudo -u keycloak ./bin/add-user-keycloak.sh -u admin -p YOURPASS -r master
# output: Added 'admin' to '/opt/keycloak/4.5.0/standalone/configuration/keycloak-add-user.json', restart server to load userWe're going to run Keycloak behind a Nginx reverse proxy. To allow this, change http-listener and socket-binding configurations in Keycloak.
$ sudo -u keycloak ./bin/jboss-cli.sh 'embed-server,/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=proxy-address-forwarding,value=true)'
$ sudo -u keycloak ./bin/jboss-cli.sh 'embed-server,/socket-binding-group=standard-sockets/socket-binding=proxy-https:add(port=443)'
$ sudo -u keycloak ./bin/jboss-cli.sh 'embed-server,/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=redirect-socket,value=proxy-https)'Create a systemd configuration to start and stop keycloak using systemd.
cat > /etc/systemd/system/keycloak.service <<EOF
[Unit]
Description=Keycloak
After=network.target
[Service]
Type=idle
User=keycloak
Group=keycloak
ExecStart=/opt/keycloak/current/bin/standalone.sh -b 0.0.0.0
TimeoutStartSec=600
TimeoutStopSec=600
[Install]
WantedBy=multi-user.target
EOFReload the systemd daemon and start Keycloak.
$ systemctl daemon-reload
$ systemctl enable keycloak
$ systemctl start keycloakNow, we'll install the Nginx server to do SSL termination for our Keycloak application. Install Nginx using the YUM package manager.
$ yum install nginxCopy the SSL certificates to the following paths on the server:
- Certificate: /etc/pki/tls/certs/
- Private key: /etc/pki/tls/private/
Configure Nginx to proxy traffic for Keycloak. (Change my.url.com to your own URL)
cat > /etc/nginx/conf.d/keycloak.conf <<EOF
upstream keycloak {
# Use IP Hash for session persistence
ip_hash;
# List of Keycloak servers
server 127.0.0.1:8080;
}
server {
listen 80;
server_name my.url.com;
# Redirect all HTTP to HTTPS
location / {
return 301 https://\$server_name\$request_uri;
}
}
server {
listen 443 ssl http2;
server_name my.url.com;
ssl_certificate /etc/pki/tls/certs/my-cert.cer;
ssl_certificate_key /etc/pki/tls/private/my-key.key;
ssl_session_cache shared:SSL:1m;
ssl_prefer_server_ciphers on;
location / {
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-Proto $scheme;
proxy_pass http://keycloak;
}
}
EOFEnable and start Nginx.
$ systemctl enable nginx
$ systemctl start nginxOpen port 80 and 443 in your firewall and you're done!