Keycloak Installation
Prerequisites for Deploying Keycloak
Keycloak Version
Keycloak version 5.0 is required for this deployment. More details on accessing this version may be found here:
https://www.keycloak.org/archive/downloads-5.0.0.html
Deploying Keycloak on EC2 instances requires all the following ports to be opened.
8230 - Master node Wildfly
8330 - Slave node Wildfly
8593 - Wildfly Undertow HTTPs undertow
8080 - jboss default
9999 - jboss remoting
11222 - Infinispan Hotrod
55200 - Infinispan jgroup clustering
9990 - jboss management
3306 - Database
7600-7603 - TCP Ping
22 - ssh
Introduction
This section covers a step-by-step guide for installing KeyCloak in EC2 server.
Create directory /opt/hypr/ and unzip the files. The directory structure will look like the below:
Get the IP of your servers and save them.
netstat -tulnp
Prerequisites
2 RHEL servers, 1 MYSQL DB server, and a load-balancer server all need to be provisioned in order to create a cluster.
Master RHEL server will contain a Keycloak server and an Infinispan server
Slave RHEL will contain a Keycloak server and an Infinispan server
The Installation and startup order will be as follows:
- Database
- Master Infinispan
- Slave Infinispan
- Master Keycloak
- Slave Keycloak
- Load balancer
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
Database
A DB schema needs to 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)
Master Infinispan
on AWS EC2 instance, install java
yum install java-1.8.0-openjdk.x86_64
Untar the infinispan-server-HYPR-configured.tar.gz file
SCP the tar.gz file to EC2 instance
Edit the clustered.xml that you downloaded eariler.
On EC2, use the private IP instead of the local IP
<property name="initial_hosts">172.31.87.14[7600],172.31.92.12[7600]</property>
Change the IP array to the IP of the master and slave nodes.
For AWS EC2 instances, change the IP to the private IP of the master and slave instances
Replace the clustered.xml file located on the infinispan server at /opt/hypr/infinispan-server-9.4.9.Final/standalone/configuration
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 &
Below message should be displayed 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)
Slave Infinispan
Install java
yum install java-1.8.0-openjdk.x86_64
Download and untar the infinispan-server-HYPR-configured.tar.gz file.
Secure copy the tar.gz file to EC2 instance
Untar the infinispan server in the /opt/hypr directory: /opt/hypr/infinispan-server-9.4.9.Final/standalone/configuration/clustered.xml
Edit the attached clustered.xml file that is in this guide so that the block matches the one below, specifically the site1 and site2 values. Ensure that the Infinispan Slave has these exact values.
Ensure that the initial_hosts property matches that of the master. This would ideally be the same file you edited earlier for the master.
<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 slave backup site to "site1" because 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 the IP of the master and slave nodes' IP.
<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 to be the private IP of the instances.
Once all these changes are complete, replace the <INFINISPAN_HOME>/standalone/configuration/clustered.xml with the edited one.
To start the server fun 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 &
On EC2, use the private IP of the LOCAL node
Keycloak Setup
Edit the Domain.xml file attached to this guide. When it is complete, you will place it in both the Master and Slave 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>
Master Keycloak
Download and unzip the keycloak-server-HYPR-configured.tar.gz file.
- Copy the domain.xml file from above into the <KEYCLOAK_HOME>/domain/configuration/ directory.
Create a 'configuration' folder at the following location. 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 slave node to communicate to a master 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.
[root@localhost 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=" />
SAVE THE SECRET!!
This is the for use in the remote slave 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 of the node
Slave Keycloak
Download and unzip the keycloak-server-HYPR-configured.tar.gz file.
-
Copy the domain.xml file from above (with the edited DB configs) into the /opt/hypr/<KEYCLOAK_HOME>/domain/configuration/ directory.
-
Copy host-slave.xml into <KEYCLOAK_HOME>/domain/configuration/ directory
-
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 /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 Keycloak Admin UI User
Run the following command from the keycloak master bin directory.
./bin/add-user-keycloak.sh --sc domain/servers/HYPR1-server/configuration -r master -u <username> -p <password>
kill the processes
restart keycloak nodes for this to take affect.
If you cannot log in due to an error message that says 'HTTPS required', see the troubleshooting guide below.
Note that when running KeyCloak behind Loadbalaceners and reverse proxies, the following should be added in stanalone.xml for standalone deployments and in cluster.xml if deploying in a cluster.
= proxy-address-forwarding=“true”
Loadbalancer
For this exercise, an AWS ELB was created and loadbalanced on the nodes' ports. (MASTERIP:8223, SLAVEIP:8330)
You may use any other kind of load-balancer you deem fit.
You can reach the server by going to its url w/ the /auth context.
Troubleshooting Guide:
On hitting server/auth url, if HTTPS required error is displayed then connect to DB and run the following commands and restart the master Keycloak server
use keycloak;
update REALM set ssl_required='NONE' where id = 'master';
Updated over 3 years ago