Install OpenJDK
Or
https://linoxide.com/install-java-ubuntu-20-04/
sudo apt install openjdk-16-jdk
Install mariadb
c.f. https://www.janua.fr/how-to-install-keycloak-with-mariadb/
sudo apt install mariadb-server mariadb-client
(...)
sudo mysql_secure_installation
Add new database and user for keycloak
create database keycloak;
create user keycloak identified by "PASSWORD";
grant all privileges on keycloak.* to 'keycloak'@'localhost' identified by "PASSWORD";
Download and deploy keycloak
Create keycloak user
sudo useradd -r keycloak
Download keycloak.
https://www.keycloak.org/downloads.html
wget https://github.com/keycloak/keycloak/releases/download/15.0.2/keycloak-15.0.2.tar.gz
tar zxvf keycloak-15.0.2.tar.gz
mv keycloak-15.0.2 /opt/
sudo chown -R keycloak:keycloak keycloak-15.0.2
sudo ln -s /opt/keycloak-15.0.2 /opt/keycloak
Prepare Keycloak for mariadb
Official manual
https://www.keycloak.org/docs/latest/server_installation/index.html#_database
c.f.
https://devopstales.github.io/sso/keycloak1/
Download JDBC connector
https://downloads.mariadb.org/connector-java/
Put the connector in keycloak modules folder:
sudo -u keycloak mkdir -p /opt/keycloak/modules/system/layers/keycloak/org/mariadb/main/
sudo -u keycloak cp mariadb-java-client-x.x.x.jar /opt/keycloak/modules/system/layers/keycloak/org/mariadb/main/
Create module.xml in the same folder:
sudo -u keycloak vim /opt/keycloak/modules/system/layers/keycloak/org/mariadb/main/module.xml
with the content:
<?xml version="1.0" ?>
<module xmlns="urn:jboss:module:1.3" name="org.mariadb">
<resources>
<resource-root path="mariadb-java-client-2.7.3.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
</dependencies>
</module>
Make sure /opt/keyalock/ is owned by keycloak:keycloak user:
sudo chown -R keycloak:keycloak /opt/keycloak/
Add admin user
sudo -u keycloak /opt/keycloak/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):
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): c
Username (admin) : admin-user
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)[ ]: admin
About to add user 'admin-user' for realm 'ManagementRealm'
Is this correct yes/no? yes
Added user 'admin-user' to file '/opt/keycloak-15.0.2/standalone/configuration/mgmt-users.properties'
Added user 'admin-user' to file '/opt/keycloak-15.0.2/domain/configuration/mgmt-users.properties'
Added user 'admin-user' with groups admin to file '/opt/keycloak-15.0.2/standalone/configuration/mgmt-groups.properties'
Added user 'admin-user' with groups admin to file '/opt/keycloak-15.0.2/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 Jakarta Enterprise Beans calls.
yes/no? yes
To represent the user add the following to the server-identities definition <secret value="*****SECRET VALUE******" />
Prepare first admin user
sudo -u keycloak /opt/keycloak/bin/add-user-keycloak.sh -u admin
# Configure password for your Keycloak admin user
Configure wildfly for mysql
cd /opt/keycloak/
./bin/jboss-cli.sh -c 'module add --name=org.mysql --dependencies=javax.api,javax.transaction.api --resources=/opt/mysql-connector-java-5.1.47/mysql-connector-java-5.1.47.jar'
./bin/jboss-cli.sh 'embed-server,/subsystem=datasources/jdbc-driver=org.mysql:add(driver-name=org.mysql,driver-module-name=org.mysql,driver-class-name=com.mysql.jdbc.Driver)'
./bin/jboss-cli.sh 'embed-server,/subsystem=datasources/data-source=KeycloakDS:remove'
./bin/jboss-cli.sh 'embed-server,/subsystem=datasources/data-source=KeycloakDS:add(driver-name=org.mysql,enabled=true,use-java-context=true,connection-url="jdbc:mysql://localhost:3306/keycloak?useSSL=false&useLegacyDatetimeCode=false&serverTimezone=Europe/Budapest&characterEncoding=UTF-8",jndi-name="java:/jboss/datasources/KeycloakDS",user-name=keycloak,password="Password1",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)'
./bin/add-user-keycloak.sh -u admin -p Password1 -r master
# for nginx proxy
./bin/jboss-cli.sh 'embed-server,/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=proxy-address-forwarding,value=true)'
./bin/jboss-cli.sh 'embed-server,/socket-binding-group=standard-sockets/socket-binding=proxy-https:add(port=443)'
./bin/jboss-cli.sh 'embed-server,/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=redirect-socket,value=proxy-https)'
# disabla color in log
./bin/jboss-cli.sh -c '/subsystem=logging/console-handler=CONSOLE:write-attribute(name=named-formatter, value=PATTERN)'
Launch keycloak
Make sure your server 8443 port is open to internet as the 8443 port is the default port of Keycloak.
sudo -u keycloak /opt/keycloak/bin/standalone.sh -b 0.0.0.0
Put Keycloak behind Nginx reverse proxy
Install nginx
sudo apt install nginx
Configure nginx for Keycloak. First with HTTP config:
server{
listen 80 default_server;
listen [::]:80 default_server;
server_name DOMAIN-NAME-OR-IP-ADDRESS-OF-SERVER;
location / {
proxy_pass http://0.0.0.0:8080; # keycloak runs on port 8080 by default
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Install certbot and let's encrypt for SSL
YOU NEED DOMAIN TO CONFIGURE SSL. FIRST PREPARE DOMAIN FOR YOUR KEYCLOAK SERVER
Change nginx config (assign domain)
vim /etc/nginx/sites-available/keycloak.conf
server {
server_name keycloaktest.minamirnd.work;
location / {
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port 8443;
add_header Strict-Transport-Security "max-age=15552000";
proxy_set_header X-NginX-Proxy true;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass https://127.0.0.1:8443/;
proxy_redirect off;
}
}
server {
server_name keycloaktest.minamirnd.work;
listen [::]:80;
listen 80;
}
Configure /opt/keycloak/standalone/configuration/standalone.xml so that reverse proxy work.
(c.f. https://gist.github.com/zahash/16405257d1e78ae1435497144eb94333)
# change redirect-socket to "proxy-https" and add proxy-address-forwarding="true"
<http-listener name="default" socket-binding="http" redirect-socket="proxy-https" enable-http2="true" proxy-address-forwarding="true"/>
# add socket-binding "proxy-https"
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
(...)
<socket-binding name="proxy-https" port="443"/>
(...)
sudo apt install snapd
sudo snap install core; sudo snap refresh core
sudo snap install --classic certbot
Install Let's Encrypt certificate:
minami@ip-10-0-38-61:~$ sudo certbot
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: your-keycloak.domain.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel):
Requesting a certificate for keycloaktest.minamirnd.work
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/your-keycloak.domain.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/your-keycloak.domain.com/privkey.pem
This certificate expires on 2021-12-18.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.
Deploying certificate
Successfully deployed certificate for your-keycloak.domain.com to /etc/nginx/sites-enabled/keycloak.conf
Congratulations! You have successfully enabled HTTPS on https://your-keycloak.domain.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
* Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
* Donating to EFF: https://eff.org/donate-le
After successfully configured letsencrypt, re-configure nginx conf file:
server {
server_name keycloaktest.minamirnd.work;
location / {
proxy_pass http://0.0.0.0:8080; # keycloak runs on port 8080 by default
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/your-keycloak.domain.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/your-keycloak.domain.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = keycloaktest.minamirnd.work) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name your-keycloak.domain.com;
listen 80;
return 404; # managed by Certbot
}
Restart nginx:
# Check conf
sudo nginx -t
# Restart nginx
sudo service nginx restart
Make sure keycloak's standalone.sh is running:
cd /opt/keycloak/
sudo -u keycloak ./bin/standalone.sh -b 0.0.0.0
Access https://your.domain.com/ with no :8443 port specified
Configure Keycloak service
Locate wildfly configuration example files in:
ls -l /opt/keycloak/docs/contrib/scripts/init.d/
# wildfly-init-debian.sh
# wildfly-init-redhat.sh
# wildfly.conf
Copy the files
sudo cp /opt/keycloak/docs/contrib/scripts/init.d/wildfly.conf /etc/default/keycloak.conf
sudo cp /opt/keycloak/docs/contrib/scripts/init.d/wildfly-init-redhat.sh /etc/init.d/keycloak # OR wildfly-init-debian.sh
Edit the default configuration
sudo vim /etc/default/keycloak.conf
#################################################
# General configuration for the init.d scripts, #
# not necessarily for WildFly itself. #
# default location: /etc/default/wildfly #
#################################################
## Location of JDK
# JAVA_HOME="/usr/lib/jvm/default-java"
JAVA_HOME="/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.282.b08-1.amzn2.0.1.x86_64/jre"
## Location of WildFly
# JBOSS_HOME="/opt/wildfly"
JBOSS_HOME="/opt/keycloak"
## The username who should own the process.
# JBOSS_USER=wildfly
JBOSS_USER=keycloak
## The mode WildFly should start, standalone or domain
# JBOSS_MODE=standalone
JBOSS_MODE=standalone
## Configuration for standalone mode
# JBOSS_CONFIG=standalone.xml
JBOSS_CONFIG=standalone.xml
## Configuration for domain mode
# JBOSS_DOMAIN_CONFIG=domain.xml
# JBOSS_HOST_CONFIG=host-master.xml
## The amount of time to wait for startup
# STARTUP_WAIT=60
STARTUP_WAIT=60
## The amount of time to wait for shutdown
# SHUTDOWN_WAIT=60
SHUTDOWN_WAIT=60
## Location to keep the console log
# JBOSS_CONSOLE_LOG="/var/log/wildfly/console.log"
JBOSS_CONSOLE_LOG="/var/log/keycloak/console.log"
## Additionals args to include in startup
# JBOSS_OPTS="--admin-only -b 127.0.0.1"
Change "wildfly" in init.d script
sudo vim /etc/init.d/keycloak
# replace "wildfly" to "keycloak"
# e.g.
(...)
# Run as keycloak user
if [ -z "$JBOSS_USER" ]; then
JBOSS_USER=keycloak
fi
(...)
# Location to set the pid file
if [ -z "$JBOSS_PIDFILE" ]; then
JBOSS_PIDFILE=/var/run/keycloak/${NAME}.pid
fi
export JBOSS_PIDFILE
Start init.d
sudo /etc/init.d/keycloak start
Access https://your.domain.com/
Links to other documents / blogs:
-
https://www.keycloak.org/docs/latest/server_installation/#system-requirements
-
https://keycloak.ch/keycloak-tutorials/tutorial-1-installing-and-running-keycloak/
-
https://gist.github.com/zahash/16405257d1e78ae1435497144eb94333
-
https://janikvonrotz.ch/2020/04/21/configure-saml-authentication-for-nextcloud-with-keycloack/
-
http://www.mastertheboss.com/jbossas/jboss-configuration/run-jboss-as-service-howto/