From 23f1450cf32f7ab2e20dc1901e9f8e07a097af61 Mon Sep 17 00:00:00 2001 From: Sheldon Warkentin Date: Fri, 17 Feb 2023 10:08:01 -0700 Subject: [PATCH] Support for Keycloak 20.0.3 --- build/keycloak/Dockerfile | 65 +- build/keycloak/cache-ispn-jdbc-ping.xml | 89 +++ build/keycloak/docker-entrypoint.sh | 36 +- build/keycloak/profile.properties | 2 - build/keycloak/standalone-ha.xml | 707 ------------------ modules/keycloak/main.tf | 8 +- .../templates/container_definition.json | 52 +- .../container_definition_datadog.json | 48 +- 8 files changed, 196 insertions(+), 811 deletions(-) create mode 100644 build/keycloak/cache-ispn-jdbc-ping.xml delete mode 100644 build/keycloak/profile.properties delete mode 100644 build/keycloak/standalone-ha.xml diff --git a/build/keycloak/Dockerfile b/build/keycloak/Dockerfile index f2b6b79..7f9da5c 100644 --- a/build/keycloak/Dockerfile +++ b/build/keycloak/Dockerfile @@ -1,41 +1,56 @@ -FROM jboss/keycloak:15.1.1 +################################################## +# Step 1 - Build an optimized image +################################################## +FROM quay.io/keycloak/keycloak:20.0.3 as builder + +# These options can be modified to produce a different +# optimized build. +# +# See https://www.keycloak.org/server/containers +# for more details. +ENV KC_METRICS_ENABLED=true +ENV KC_HEALTH_ENABLED=true +ENV KC_FEATURES=preview +ENV KC_DB=postgres +ENV KC_HTTP_RELATIVE_PATH=/auth + +# # Clustering +# (https://gist.github.com/xgp/768eea11f92806b9c83f95902f7f8f80) +COPY ./cache-ispn-jdbc-ping.xml /opt/keycloak/conf/cache-ispn-jdbc-ping.xml +ENV KC_CACHE_CONFIG_FILE=cache-ispn-jdbc-ping.xml -USER root +# Install custom themes +COPY themes/ /opt/keycloak/themes + +# Create an optimized build +RUN /opt/keycloak/bin/kc.sh build + +################################################## +# Step 2 - Copy optimized build into running image +################################################## +FROM quay.io/keycloak/keycloak:20.0.3 # parses ecs metadata +USER root RUN microdnf update -y && \ microdnf install -y jq && \ microdnf clean all -USER jboss +USER keycloak +COPY --from=builder /opt/keycloak /opt/keycloak -# Setup keystore -RUN /opt/jboss/tools/x509.sh +WORKDIR /opt/keycloak +# Allows server to start in prod mode. Actual certs provided by ALB. +RUN keytool -genkeypair -storepass password -storetype PKCS12 -keyalg RSA -keysize 2048 -dname "CN=server" -alias server -ext "SAN:c=DNS:localhost,IP:127.0.0.1" -keystore conf/server.keystore # Customize entrypoint and config -# NOTE: jboss/keycloak includes JDBC drivers. -COPY docker-entrypoint.sh /opt/jboss/tools/docker-entrypoint.sh -COPY standalone-ha.xml /opt/jboss/keycloak/standalone/configuration/standalone-ha.xml -# https://www.keycloak.org/docs/latest/server_installation/index.html#profiles -COPY profile.properties /opt/jboss/keycloak/standalone/configuration/profile.properties - -# Install custom themes -RUN mkdir -p /opt/jboss/keycloak/themes -COPY themes/ /opt/jboss/keycloak/themes/ - -# Clustering -ENV JGROUPS_DISCOVERY_PROTOCOL JDBC_PING -ENV JGROUPS_DISCOVERY_PROPERTIES datasource_jndi_name=java:jboss/datasources/KeycloakDS -# https://github.com/keycloak/keycloak-containers/blob/master/server/README.md#replication-and-fail-over -ENV CACHE_OWNERS_COUNT 2 -ENV CACHE_OWNERS_AUTH_SESSIONS_COUNT 2 -# https://github.com/keycloak/keycloak-containers/blob/master/server/README.md#enabling-proxy-address-forwarding -ENV PROXY_ADDRESS_FORWARDING true +COPY docker-entrypoint.sh /docker-entrypoint.sh # Paranoia: Keycloak is not vulnerable to CVE-2021-44228 # https://github.com/keycloak/keycloak-containers/issues/344 # https://logging.apache.org/log4j/log4j-2.14.1/manual/configuration.html#SystemProperties ENV FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS true -EXPOSE 7600 -CMD ["-b", "0.0.0.0", "--server-config", "standalone-ha.xml"] +# Port 7800 is used by JDBC_PING by default +EXPOSE 7800 +ENTRYPOINT ["/docker-entrypoint.sh"] diff --git a/build/keycloak/cache-ispn-jdbc-ping.xml b/build/keycloak/cache-ispn-jdbc-ping.xml new file mode 100644 index 0000000..56ad9e3 --- /dev/null +++ b/build/keycloak/cache-ispn-jdbc-ping.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/keycloak/docker-entrypoint.sh b/build/keycloak/docker-entrypoint.sh index f5dc84f..e45ca38 100755 --- a/build/keycloak/docker-entrypoint.sh +++ b/build/keycloak/docker-entrypoint.sh @@ -17,44 +17,10 @@ if [ -z "${EXTERNAL_ADDR}" ]; then fi export EXTERNAL_ADDR -# Add admin user -if [ -n "${KEYCLOAK_USER}" ] && [ -n "${KEYCLOAK_PASSWORD}" ]; then - /opt/jboss/keycloak/bin/add-user-keycloak.sh --user "${KEYCLOAK_USER}" --password "${KEYCLOAK_PASSWORD}" -fi - -# Default to H2 if DB type not detected -if [ -z "${DB_VENDOR}" ]; then - export DB_VENDOR="h2" -fi - -# Set DB name -DB_VENDOR=$(echo "${DB_VENDOR}" | tr '[:upper:]' '[:lower:]') -case "${DB_VENDOR}" in - h2) - DB_NAME="Embedded H2" ;; - mariadb) - DB_NAME="MariaDB" ;; - mysql) - DB_NAME="MySQL" ;; - postgres) - DB_NAME="PostgreSQL" ;; - *) - echo "Unknown DB vendor ${DB_VENDOR}" - exit 1 -esac -echo "Using ${DB_NAME} database" - -if [ "${DB_VENDOR}" != "h2" ]; then - /bin/sh /opt/jboss/tools/databases/change-database.sh "${DB_VENDOR}" -fi if [ -z "${HOSTNAME}" ]; then HOSTNAME="localhost" fi -SYS_PROPS="-Dkeycloak.hostname.provider=fixed \ - -Dkeycloak.hostname.fixed.hostname=${HOSTNAME} \ - -Dkeycloak.hostname.fixed.httpPort=8080" - -exec /opt/jboss/keycloak/bin/standalone.sh "${SYS_PROPS}" "$@" +exec /opt/keycloak/bin/kc.sh start --optimized "$@" exit $? diff --git a/build/keycloak/profile.properties b/build/keycloak/profile.properties deleted file mode 100644 index 174a17f..0000000 --- a/build/keycloak/profile.properties +++ /dev/null @@ -1,2 +0,0 @@ -feature.scripts=enabled -feature.upload=enabled diff --git a/build/keycloak/standalone-ha.xml b/build/keycloak/standalone-ha.xml deleted file mode 100644 index b73b9a4..0000000 --- a/build/keycloak/standalone-ha.xml +++ /dev/null @@ -1,707 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - jdbc:postgresql://${env.DB_ADDR}/keycloak - - true - - - allow - - - 5 - - - 5 - - - 5 - - - 5 - - - true - - - master - - - keycloak - - postgresql - - 40 - 100 - - - ${env.DB_USER} - ${env.DB_PASSWORD} - - - - - org.h2.jdbcx.JdbcDataSource - - - - - - - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - java:jboss/datasources/KeycloakDS - true - 5000 - 2 - CREATE TABLE IF NOT EXISTS JGROUPSPING (own_addr varchar(200) NOT NULL,bind_addr varchar(200) NOT NULL,created timestamp NOT NULL,cluster_name varchar(200) NOT NULL,ping_data BYTEA,constraint PK_JGROUPSPING PRIMARY KEY (own_addr, cluster_name)); - INSERT INTO JGROUPSPING (own_addr, bind_addr, created, cluster_name, ping_data) values (?,'${env.EXTERNAL_ADDR:127.0.0.1}',NOW(), ?, ?); - DELETE FROM JGROUPSPING WHERE own_addr=? AND cluster_name=?; - SELECT ping_data FROM JGROUPSPING WHERE cluster_name=?; - - - - - - - - - - - - - - - - - - - - - - - - auth - - - classpath:${jboss.home.dir}/providers/* - - - master - 900 - - 2592000 - true - true - ${jboss.home.dir}/themes - - - - - - - - - - - - - - - - - - - - jpa - - - basic - - - - - - - - - - - - - - - - - - - default - - - - - - - - ${keycloak.jta.lookup.provider:jboss} - - - - - - - - - - - ${keycloak.x509cert.lookup.provider:default} - - - - default - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/modules/keycloak/main.tf b/modules/keycloak/main.tf index 9c72ed7..fe32202 100644 --- a/modules/keycloak/main.tf +++ b/modules/keycloak/main.tf @@ -52,7 +52,7 @@ module "alb" { certificate_arn = var.alb_certificate_arn deletion_protection_enabled = var.deletion_protection health_check_interval = 60 - health_check_path = "/auth" + health_check_path = "/auth/health" health_check_timeout = 10 http_ingress_cidr_blocks = var.http_ingress_cidr_blocks http_redirect = var.http_redirect @@ -253,10 +253,10 @@ module "ecs" { ] } -resource "aws_security_group_rule" "jgroups" { +resource "aws_security_group_rule" "jdbc_ping" { type = "ingress" - from_port = 7600 - to_port = 7600 + from_port = 7800 + to_port = 7800 protocol = "tcp" cidr_blocks = var.private_subnet_cidrs security_group_id = module.ecs.service_security_group_id diff --git a/modules/keycloak/templates/container_definition.json b/modules/keycloak/templates/container_definition.json index 00a8860..aed66f1 100644 --- a/modules/keycloak/templates/container_definition.json +++ b/modules/keycloak/templates/container_definition.json @@ -15,7 +15,7 @@ }, { "protocol": "tcp", - "containerPort": 7600 + "containerPort": 7800 }, { "protocol": "tcp", @@ -25,25 +25,21 @@ "cpu": ${container_cpu_units}, "environment": [ { - "name": "DB_ADDR", - "value": "${db_addr}" + "name": "KC_DB", + "value": "postgres" }, { - "name": "DB_DATABASE", - "value": "keycloak" + "name": "KC_DB_URL", + "value": "jdbc:postgresql://${db_addr}:5432/keycloak" }, { - "name": "DB_PORT", - "value": "5432" + "name": "KC_DB_ADDR", + "value": "${db_addr}" }, { - "name": "DB_USER", + "name": "KC_DB_USERNAME", "value": "keycloak" }, - { - "name": "DB_VENDOR", - "value": "postgres" - }, { "name": "DNS_NAME", "value": "${dns_name}" @@ -57,16 +53,32 @@ "value": "-XX:+DisableExplicitGC -XX:+UseG1GC -Xms${jvm_heap_min}m -Xmx${jvm_heap_max}m -XX:MetaspaceSize=${jvm_meta_min}m -XX:MaxMetaspaceSize=${jvm_meta_max}m -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv4Addresses -Djava.security.egd=file:/dev/urandom -Dnashorn.args=--no-deprecation-warning" }, { - "name": "KEYCLOAK_DEFAULT_THEME", - "value": "keycloak" + "name": "KEYCLOAK_ADMIN", + "value": "keycloak_admin" }, { - "name": "KEYCLOAK_USER", - "value": "keycloak_admin" + "name": "KC_LOG_LEVEL", + "value": "INFO,org.infinispan:ERROR,org.jgroups:ERROR" + }, + { + "name": "KC_HTTP_ENABLED", + "value": "true" + }, + { + "name": "KC_PROXY", + "value": "edge" + }, + { + "name": "KC_HOSTNAME_STRICT", + "value": "false" + }, + { + "name": "KC_HOSTNAME_PATH", + "value": "/auth" }, { - "name": "KEYCLOAK_LOGLEVEL", - "value": "INFO" + "name": "KC_HTTP_RELATIVE_PATH", + "value": "/auth" }, { "name": "ROOT_LOGLEVEL", @@ -75,11 +87,11 @@ ], "secrets": [ { - "name": "DB_PASSWORD", + "name": "KC_DB_PASSWORD", "valueFrom": "arn:aws:ssm:${region}:${aws_account_id}:parameter/${name}/${environment}/DB_PASSWORD" }, { - "name": "KEYCLOAK_PASSWORD", + "name": "KEYCLOAK_ADMIN_PASSWORD", "valueFrom": "arn:aws:ssm:${region}:${aws_account_id}:parameter/${name}/${environment}/KEYCLOAK_PASSWORD" } ], diff --git a/modules/keycloak/templates/container_definition_datadog.json b/modules/keycloak/templates/container_definition_datadog.json index 40334ad..943ede5 100644 --- a/modules/keycloak/templates/container_definition_datadog.json +++ b/modules/keycloak/templates/container_definition_datadog.json @@ -15,7 +15,7 @@ }, { "protocol": "tcp", - "containerPort": 7600 + "containerPort": 7800 }, { "protocol": "tcp", @@ -25,25 +25,21 @@ "cpu": ${container_cpu_units}, "environment": [ { - "name": "DB_ADDR", - "value": "${db_addr}" + "name": "KC_DB", + "value": "postgres" }, { - "name": "DB_DATABASE", - "value": "keycloak" + "name": "KC_DB_URL", + "value": "jdbc:postgresql://${db_addr}:5432/keycloak" }, { - "name": "DB_PORT", - "value": "5432" + "name": "KC_DB_ADDR", + "value": "${db_addr}" }, { - "name": "DB_USER", + "name": "KC_DB_USERNAME", "value": "keycloak" }, - { - "name": "DB_VENDOR", - "value": "postgres" - }, { "name": "DNS_NAME", "value": "${dns_name}" @@ -57,16 +53,32 @@ "value": "-XX:+DisableExplicitGC -XX:+UseG1GC -Xms${jvm_heap_min}m -Xmx${jvm_heap_max}m -XX:MetaspaceSize=${jvm_meta_min}m -XX:MaxMetaspaceSize=${jvm_meta_max}m -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv4Addresses -Djava.security.egd=file:/dev/urandom -Dnashorn.args=--no-deprecation-warning" }, { - "name": "KEYCLOAK_DEFAULT_THEME", - "value": "keycloak" + "name": "KEYCLOAK_ADMIN", + "value": "keycloak_admin" }, { - "name": "KEYCLOAK_USER", - "value": "keycloak_admin" + "name": "KC_LOG_LEVEL", + "value": "INFO,org.infinispan:ERROR,org.jgroups:ERROR" + }, + { + "name": "KC_HTTP_ENABLED", + "value": "true" + }, + { + "name": "KC_PROXY", + "value": "edge" + }, + { + "name": "KC_HOSTNAME_STRICT", + "value": "false" + }, + { + "name": "KC_HOSTNAME_PATH", + "value": "/auth" }, { - "name": "KEYCLOAK_LOGLEVEL", - "value": "INFO" + "name": "KC_HTTP_RELATIVE_PATH", + "value": "/auth" }, { "name": "ORG_MANAGER_HOST",