Keycloak Installation

HYPR SDK IdP and SP Management

This article explains how to install Keycloak with Elastic Compute Cloud (EC2) server.

Prerequisites

📘

Keycloak Version

Keycloak version 5.0 is required for this deployment. More details on accessing this version may be found here.

Deploying Keycloak on EC2 instances requires all the following ports to be opened:

PortPurpose
8230Wildfly Primary node
8330WildFly Secondary node
8593WildFly w/Undertow
HTTPS w/Undertow
8080JBoss default
9999JBoss remoting
11222Infinispan Hot Rod
55200Infinispan JGroups clustering
9990JBoss management
3306Database
7600-7603TCP ping
22SSH

Introduction

565

Create directory /opt/hypr/ and decompress the Keycloak files into it. Record the IP addresses of your servers (primary and secondary) so you can access them later.

netstat -tulnp

Preparations

To create a cluster, the following must be provisioned:

  • 2 RedHat Enterprise Linux (RHEL) servers
  • 1 mySQL database server
  • 1 load balancer server

The primary RHEL server will contain both a Keycloak server and an Infinispan server.
The secondary RHEL server will contain a both a Keycloak server and an Infinispan server.

The installation and startup order will be as follows:

🚧

User Permissions

Please make sure that you're doing operations with a user who has read/write/create permissions, or use a root user: sudo su.

Create the Database

A database schema must be created. Log into mySQL and follow the steps below:

mysql> CREATE USER 'keycloak'@'%' IDENTIFIED BY 'keycloak';
Query OK, 0 rows affected (0.01 sec)
 
mysql> GRANT ALL PRIVILEGES ON keycloak.* TO 'keycloak'@'%';
Query OK, 0 rows affected (0.00 sec)
 
 
If "keycloak" database is not created during setup, execute below command:
mysql> CREATE DATABASE keycloak CHARACTER SET utf8 COLLATE utf8_unicode_ci;
Query OK, 1 row affected (0.00 sec)

Infinispan Setup

Primary Infinispan Server

  1. Install Java on the AWS EC2 instance:
yum install java-1.8.0-openjdk.x86_64
  1. Decompress infinispan-server-HYPR-configured.tar.gz, then SCP it to the EC2 instance.

  2. Edit the clustered.xml file that you downloaded earlier; change the IP addresses to match those of the primary and secondary nodes. For AWS EC2 instances, change the IP addresses to the private IP addresses of the primary and secondary instances. Save the file.

<property name="initial_hosts">172.31.87.14[7600],172.31.92.12[7600]</property>
  1. Replace the clustered.xml file located on the Infinispan server at /opt/hypr/infinispan-server-9.4.9.Final/standalone/configuration with the one you just edited.

  2. To start the server, run the following command:

nohup ./<InfinispanHome>/bin/standalone.sh -c clustered.xml -Djava.net.preferIPv4Stack=true -Djboss.default.multicast.address=234.56.78.99 -Djboss.node.name=jdg1 -b <PRIVATEIP Address> > /dev/null &

Something similar to this message will display when the server has started:

12:40:20,534 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: Infinispan Server 9.4.9.Final (WildFly Core 6.0.2.Final) started in 15875ms - Started 263 of 298 services (149 services are lazy, passive or on-demand)

Secondary Infinispan Server

  1. Install Java.
yum install java-1.8.0-openjdk.x86_64
  1. Download and decompress the infinispan-server-HYPR-configured.tar.gz file, and secure copy (SCP) it to EC2 instance.

  2. Decompress the Infinispan package into the /opt/hypr directory. The directory structure will be similar to this: /opt/hypr/infinispan-server-9.4.9.Final/standalone/configuration/clustered.xml.

  3. Edit the attached clustered.xml file from this guide.

  • Make the block match the one below, specifically the site1 and site2 values; ensure that the Infinispan Secondary server uses these exact values
  • Ensure the initial_hosts property matches that of the Infinispan Primary server; ideally the same file you edited earlier for the Primary
<relay site="site2">
 <remote-site name="site1" channel="xsite"/>
 <property name="relay_multicasts">false</property>
 </relay>
 </stack>
 <stack name="tcp">
 <transport type="TCP" socket-binding="jgroups-tcp"/>
 <!-- HYPR remove mping -->
 <!--  <protocol type="MPING" socket-binding="jgroups-mping"/> -->
 <!-- HYPR added TCPPING protocol instead of MPING, and add initial_hots element" -->
<transport type="TCP" socket-binding="jgroups-tcp"/>
 <protocol type="TCPPING">
 <property name="initial_hosts">172.31.87.14[7600],172.31.92.12[7600]</property>
 <property name="ergonomics">false</property>
 </protocol>

Ensure that you change the Infinispan Secondary server backup site to site1*, as the server cannot be its own backup

<replicated-cache-configuration name="sessions-cfg" mode="SYNC" start="EAGER" batching="false">
    <locking acquire-timeout="0" />
    <backups>
        <backup site="site1" failure-policy="FAIL" strategy="SYNC" enabled="true">
            <take-offline min-wait="60000" after-failures="3" />
        </backup>
    </backups>
</replicated-cache-configuration>
  • Edit the initial_hosts array to include the IP addresses of the primary and secondary servers' IP addresses
<protocol type="TCPPING">
    <property name="initial_hosts">172.31.87.14-for-jdg1-IP[7600],172.31.92.12-for-jdg2-IP[7600]</property>
    <property name="ergonomics">false</property>
</protocol>
  • For AWS EC2, edit the IP addresses to be the private IP addresses of the instances
  • Save the file
  1. Replace the <INFINISPAN_HOME>/standalone/configuration/clustered.xml with the file you just saved.
  2. To start the server run the following command:
nohup ./<InfinispanHome>/bin/standalone.sh -c clustered.xml -Djava.net.preferIPv4Stack=true -Djboss.default.multicast.address=234.56.78.100 -Djboss.node.name=jdg2 -b <PRIVATEIP Address> > /dev/null &

Keycloak Setup

Edit the Domain.xml file attached to this guide. When it is complete, you will place it in both the Primary and Secondary nodes.

Edit the connection-url, user-name, and password attributes in the datasource block located at line 633. This will allow you to connect to your previously created database source.

<datasource jndi-name="java:/jboss/datasources/KeycloakDS" pool-name="MySQL_KeycloakDS" enabled="true">
    <connection-url>jdbc:mysql://keycloakdb.rds.amazonaws.com:3306/keycloak</connection-url>
    <driver>mysql</driver>
    <pool>
            <min-pool-size>5</min-pool-size>
            <max-pool-size>15</max-pool-size>
    </pool>
    <security>
            <user-name>admin</user-name>
            <password>!!!*password*!!!</password>
    </security>
    <validation>
            <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLValidConnectionChecker"/>
            <validate-on-match>true</validate-on-match>
            <exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLExceptionSorter"/>
    </validation>
</datasource>

Primary Keycloak Server

Download and unzip the keycloak-server-HYPR-configured.tar.gz file.

  1. Copy the domain.xml file from Keycloak Setup, above, into the <KEYCLOAK_HOME>/domain/configuration/ directory.

Create a folder: <KEYCLOAK_HOME>/domain/servers/HYPR1_server/configuration. This will be used to create the LOGIN username and password to the Keycloak instances. Follow the next three instructions for commands.

mkdir<KEYCLOAK_HOME>/domain/servers/HYPR1_server/configuration
cd <KEYCLOAK_HOME> 
./bin/add-user-keycloak.sh --sc <KEYCLOAK_HOME>/domain/servers/HYPR1_server/configuration/ -r master -u admin -p admin

The secret value is the communication mechanism which allows a secondary node to communicate to a primary node. This particular secret is not associated with a user on the Keycloak server, but instead is a user on the JBoss/Wildfly server.

cd .../bin/
./add-user.sh script

Follow the prompt EXACTLY as described below with the following choices.

[[email protected] bin]# ./add-user.sh
 
What type of user do you wish to add?
 a) Management User (mgmt-users.properties)
 b) Application User (application-users.properties)
(a): a
 
Enter the details of the new user to add.
Using realm 'ManagementRealm' as discovered from the existing property files.
Username : admin
User 'admin' already exists and is disabled, would you like to...
 a) Update the existing user password and roles
 b) Enable the existing user
 c) Type a new username
(a): a
Password recommendations are listed below. To modify these restrictions edit the add-user.properties configuration file.
 - The password should be different from the username
 - The password should not be one of the following restricted values (root, admin, administrator)
 - The password should contain at least 8 characters, 1 alphabetic character(s), 1 digit(s), 1 non-alphanumeric symbol(s)
Password :
Re-enter Password :
What groups do you want this user to belong to? (Please enter a comma separated list, or leave blank for none)[  ]:
Updated user 'admin' to file '/opt/hypr/keycloak-5.0.0/standalone/configuration/mgmt-users.properties'
Updated user 'admin' to file '/opt/hypr/keycloak-5.0.0/domain/configuration/mgmt-users.properties'
Updated user 'admin' with groups  to file '/opt/hypr/keycloak-5.0.0/standalone/configuration/mgmt-groups.properties'
Updated user 'admin' with groups  to file '/opt/hypr/keycloak-5.0.0/domain/configuration/mgmt-groups.properties'
Is this new user going to be used for one AS process to connect to another AS process?
e.g. for a slave host controller connecting to the master or for a Remoting connection for server to server EJB calls.
yes/no? yes
To represent the user add the following to the server-identities definition <secret value="YWRtaW4xISE=" />

❗️

DON'T FORGET

SAVE THE SECRET!!

This is the for use in the remote secondary node.
Run the Keycloak server from the /bin location:

nohup ./domain.sh --host-config=host-master.xml -Djboss.bind.address=<PRIVATEIP> -Djboss.bind.address.management=<LocalIP> -Djboss.domain.master.address=<PRIVATEIP> -Djboss.node.name=node11 -Djboss.site.name=site1 -Djboss.default.multicast.address=234.56.78.1 -Dremote.cache.host=<PRIVATEIP> > /dev/null &

🚧

On EC2, use the private IP address of the node.

Secondary Keycloak Server

Download and unzip the keycloak-server-HYPR-configured.tar.gz file.

  1. Copy the domain.xml file from Keycloak Setup, above (with the edited DB configs) into the /opt/hypr/<KEYCLOAK_HOME>/domain/configuration/ directory.

  2. Copy host-slave.xml into the <KEYCLOAK_HOME>/domain/configuration/ directory

  3. Add the secret to the host-slave.xml file.

<security-realm name="ManagementRealm">
    <server-identities>
        <!-- Replace this with either a base64 password of your own, or use a vault with a vault expression -->
        <secret value="YWRtaW4xISE="/>
    </server-identities>

Verify that the .xml block below is unaltered:

<servers>
    <server name="HYPR2-server" group="auth-server-group" auto-start="true">
        <!--
          ~  server-two avoids port conflicts by incrementing the ports in
          ~                  the default socket-group declared in the server-group
          -->
        <socket-bindings port-offset="250"/>
    </server>
</servers>

Run the Keycloak server from the <KEYCLOAK-home>/bin location:

./domain.sh --host-config=host-slave.xml -Djboss.bind.address=<PRIVATEIP>  -Djboss.domain.master.address=<MASTER PRIVATE IP> -Djboss.node.name=node21 -Djboss.site.name=site2 -Djboss.default.multicast.address=234.56.78.2 -Dremote.cache.host=<PRIVATE IP>

Add the Keycloak Administrator UI User

  1. Run the following command from the Keycloak Primary server bin directory:
./bin/add-user-keycloak.sh --sc domain/servers/HYPR1-server/configuration -r master -u <username> -p <password>
  1. Kill the processes.
  2. Restart all Keycloak nodes for this to take affect.

If you cannot log in due to an error message that says, HTTPS required, see HTTPS Required below.

📘

NOTE

When running Keycloak behind load balancers and reverse proxies, the following should be added in standalone.xml for standalone deployments and in cluster.xml if deploying in a cluster.

= proxy-address-forwarding=“true”
<http-listener name=“default” socket-binding=“http” redirect-socket=“https” enable-http2=“true” proxy- 
address-forwarding=“true”/>

Load Balancer

For this exercise, an AWS ELB was created and load-balanced on the nodes' ports:

  • Primary: 8223
  • Secondary: 8330

You may use any other kind of load balancer you deem fit.

You can reach the server by going to its URL with the authentication context.

HTTPS Required

Upon loading the server authentication URL, if an HTTPS Required error displays:

  1. Connect to the database and run the following commands:
use keycloak;
update REALM set ssl_required='NONE' where id = 'master';
  1. Restart the Keycloak Primary server.