Для обеспечения SSO (Single Sign-On) для web сервисов с поддержкой OpenId или SAML в legacy проектах LDAP. Мы установим и настроим Keycloak с LDAP бэкендом
Keycloak
Устанавливаем keycloak с помощью docker контейнеров. Мы будем использовать Prometheus метрики, для этого напишем Dockerfile в котором загрузим плагин
1 2 3 4 5 |
FROM jboss/keycloak:9.0.3 ENV KEYCLOAK_METRICS_SPI_VERSION 1.0.4 ENV DEPLOYMENTS_DIR /opt/jboss/keycloak/standalone/deployments ADD --chown=jboss:root https://github.com/aerogear/keycloak-metrics-spi/releases/download/$KEYCLOAK_METRICS_SPI_VERSION/keycloak-metrics-spi-$KEYCLOAK_METRICS_SPI_VERSION.jar $DEPLOYMENTS_DIR |
Собираем docker image:
1 |
docker build --pull --rm -t keycloak:sso-workshop . |
Напишем и запустим docker-compose файл.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
version: '2' services: postgres: image: postgres environment: POSTGRES_DB: keycloak POSTGRES_USER: keycloak POSTGRES_PASSWORD: someStrongPasswordHere volumes: - /postgres:/var/lib/postgresql/data keycloak: image: keycloak:sso-workshop environment: DB_VENDOR: POSTGRES DB_ADDR: postgres DB_DATABASE: keycloak DB_USER: keycloak DB_SCHEMA: public DB_PASSWORD: someStrongPasswordHere KEYCLOAK_USER: admin KEYCLOAK_PASSWORD: StrongAdminPassword PROXY_ADDRESS_FORWARDING: "true" ports: - 127.0.0.1:8081:8080 depends_on: - postgres |
1 |
docker-compose up -d |
Напишем конфигурационый файл для nginx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
server { if ($host = sso.example.com) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; server_name sso.example.com; return 404; # managed by Certbot } server { listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/sso.example.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/sso.example.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_name sso.example.com; access_log /var/log/nginx/sso.example.com.access.log main; error_log /var/log/nginx/sso.example.com.error.log; client_max_body_size 2048M; location / { proxy_pass http://127.0.0.1:8081; 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-Host $host; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Forwarded-Port $server_port; proxy_set_header X-Forwarded-Proto $scheme; proxy_buffer_size 64k; proxy_buffers 8 64k; proxy_busy_buffers_size 64k; } location /auth/realms/master/metrics { proxy_pass http://127.0.0.1:8081; 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-Host $host; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Forwarded-Port $server_port; proxy_set_header X-Forwarded-Proto $scheme; allow 8.8.8.8; # Node IP from Kubernetes cluster deny all; } } |
OpenLDAP
OpenLDAP так же установим с помощью docker. Собирать image не будем, возьмем готовый
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
version: '2' services: openldap: image: osixia/openldap:1.3.0 container_name: openldap environment: LDAP_LOG_LEVEL: "256" LDAP_ORGANISATION: "mycompany" LDAP_DOMAIN: "ldap.example.com" LDAP_BASE_DN: "" LDAP_ADMIN_PASSWORD: "StrongPasswordHere" LDAP_CONFIG_PASSWORD: "AnotherStrongPasswordHere" LDAP_READONLY_USER: "false" LDAP_RFC2307BIS_SCHEMA: "false" LDAP_BACKEND: "mdb" LDAP_TLS: "true" LDAP_TLS_CRT_FILENAME: "ldap.crt" LDAP_TLS_KEY_FILENAME: "ldap.key" LDAP_TLS_DH_PARAM_FILENAME: "dhparam.pem" LDAP_TLS_CA_CRT_FILENAME: "ca.crt" LDAP_TLS_ENFORCE: "true" LDAP_TLS_CIPHER_SUITE: "SECURE256:-VERS-SSL3.0" LDAP_TLS_PROTOCOL_MIN: "3.1" LDAP_TLS_VERIFY_CLIENT: "try" LDAP_REPLICATION: "false" #LDAP_REPLICATION_CONFIG_SYNCPROV: "binddn="cn=admin,cn=config" bindmethod=simple credentials=$LDAP_CONFIG_PASSWORD searchbase="cn=config" type=refreshAndPersist retry="60 +" timeout=1 starttls=critical" #LDAP_REPLICATION_DB_SYNCPROV: "binddn="cn=admin,$LDAP_BASE_DN" bindmethod=simple credentials=$LDAP_ADMIN_PASSWORD searchbase="$LDAP_BASE_DN" type=refreshAndPersist interval=00:00:00:10 retry="60 +" timeout=1 starttls=critical" #LDAP_REPLICATION_HOSTS: "#PYTHON2BASH:['ldap://ldap.ldap.example.com','ldap://ldap2.ldap.example.com']" KEEP_EXISTING_CONFIG: "false" LDAP_REMOVE_CONFIG_AFTER_SETUP: "true" LDAP_SSL_HELPER_PREFIX: "ldap" tty: true stdin_open: true volumes: - /ldap/ldap:/var/lib/ldap - /ldap/slapd:/etc/ldap/slapd.d - /ldap/certs:/container/service/slapd/assets/certs/ ports: - "389:389" - "636:636" domainname: "ldap.example.com" # important: same as hostname hostname: "ldap.example.com" phpldapadmin: image: osixia/phpldapadmin:latest container_name: phpldapadmin environment: PHPLDAPADMIN_LDAP_HOSTS: "openldap" PHPLDAPADMIN_HTTPS: "false" ports: - "127.0.0.1:8080:80" depends_on: - openldap |
Запускаем
1 |
docker-compose up -d |
Напишем конфигурационый файл для nginx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
server { listen 80; server_name ldap.example.com; access_log /var/log/nginx/ldap.example.com.access.log main; error_log /var/log/nginx/ldap.example.com.error.log; client_max_body_size 2048M; location / { proxy_set_header Host $host:$server_port; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_pass http://127.0.0.1:8080; proxy_read_timeout 900s; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } |
Настройка LDAP
Перед подключением LDAP к Keycloak нам нужно его настроить
Хэширование паролей
Создадим 2 файла load-ppolicy.ldif и overlay-ppolicy.ldif
1 2 3 4 |
dn: cn=module{0},cn=config changetype: modify add: olcModuleLoad olcModuleLoad: ppolicy |
1 2 3 4 5 |
dn: olcOverlay={2}ppolicy,olcDatabase={1}mdb,cn=config objectClass: olcOverlayConfig objectClass: olcPPolicyConfig olcOverlay: {2}ppolicy olcPPolicyHashCleartext: TRUE |
Применяем
1 |
ldapadd -Q -Y EXTERNAL -H ldapi:/// -f load-ppolicy.ldif |
1 |
ldapadd -Q -Y EXTERNAL -H ldapi:/// -f overlay-ppolicy.ldif |
Organisational Unit
Нужно создать 2 ou
- Users
- Groups
Импортируем 2 ldif, можно в LDAP UI
1 2 3 4 5 6 7 |
version: 1 # Entry 1: ou=users,dc=ldap,dc=example,dc=com dn: ou=users,dc=ldap,dc=example,dc=com objectclass: organizationalUnit objectclass: top ou: users |
1 2 3 4 5 6 7 |
version: 1 # Entry 1: ou=users,dc=ldap,dc=example,dc=com dn: ou=users,dc=ldap,dc=example,dc=com objectclass: organizationalUnit objectclass: top ou: users |
Пользователи
Импортируем пользователя
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
version: 1 dn: cn=roman.pridybailo,ou=users,dc=ldap,dc=examlpe,dc=com cn: roman.pridybailo gidnumber: 500 givenname: Roman homedirectory: /home/users/rpridybailo loginshell: /bin/sh mail: drake0103@gmail.com objectclass: inetOrgPerson objectclass: posixAccount objectclass: top sn: Pridybailo uid: rpridybailo uidnumber: 1001 userpassword: {CRYPT}$6$6aW8lr2RdUaU2VUJNCddQhJ2aIi7IW ab.qanXnvwrqA3XHqEW0Cd448DJmqUra7CuIvsV1pP9/ |
Группы
1 2 3 4 5 6 7 8 |
version: 1 # Entry 1: cn=admins,ou=groups,dc=ldap,dc=example,dc=com dn: cn=admins,ou=groups,dc=ldap,dc=example,dc=com cn: admins member: cn=roman.pridybailo,ou=users,dc=ldap,dc=example,dc=com objectclass: groupOfNames objectclass: top |
Подключение LDAP в Keycloak
Заходим в UI Keycloak в пункт User Federation, создаем новый provider ldap. Вносим значения в поля как на примере:
Для синхронизации Групп переходим в mappers, создаем новый mapper c типом group-ldap-mapper. Заполняем поля как на примере
Синхронизируем и получаем пользователей из OpenLDAP в Keycloak.