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-openjdk
We'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 keycloak
Keycloak 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/keycloak
Limit access to standalone file because it contains sensitive data.
$ cd /opt/keycloak/current
$ sudo -u keycloak chmod 700 standalone
We'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.rpm
This 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-community
Install and start the MySQL server.
$ yum install mysql-server
$ systemctl start mysqld
The 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 password
Save the MySQL credentials in the home directory of the root user.
$ cat > /root/.my.cnf <<EOF
[client]
user=root
password="YOURPASS"
EOF
Create 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.jar
Open 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$ exit
Add 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 user
We'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
EOF
Reload the systemd daemon and start Keycloak.
$ systemctl daemon-reload
$ systemctl enable keycloak
$ systemctl start keycloak
Now, we'll install the Nginx server to do SSL termination for our Keycloak application. Install Nginx using the YUM package manager.
$ yum install nginx
Copy 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;
}
}
EOF
Enable and start Nginx.
$ systemctl enable nginx
$ systemctl start nginx
Open port 80 and 443 in your firewall and you're done!