Установка FreeIPA в Docker-контейнере: Опыт на Ubuntu 24.04

Сегодня делюсь своим опытом установки FreeIPA (Identity, Policy, Audit) в контейнере. Было очень много проблем при установке в контейнере, в итоге получил рабочее решение

FreeIPA — это мощный open-source инструмент для управления идентификацией, аутентификацией и авторизацией в Linux-средах, интегрирующий LDAP, Kerberos, DNS и CA. Я пытался запустить его в Podman (как альтернативе Docker), но столкнулся с проблемами сетевой изоляции, конфликтами портов и rootless-режимом. В итоге перешёл на Docker, где всё заработало после активации user namespace remapping. Эта статья — пошаговое руководство для production-ready установки, с акцентом на безопасность и idempotency.

Почему контейнеризация FreeIPA?

В виртуальной машине или на bare-metal установка проще, но контейнеры дают изоляцию, portability и лёгкое масштабирование (например, для реплик). Однако FreeIPA требует privileged-доступа (cap_add, sysctls) и bind на низкие порты (53 для DNS), что вызывает конфликты с хост-системой. Альтернативы вроде Helm-чартов для Kubernetes существуют, но для простоты мы будем использовать Docker Compose.

Предупреждение: FreeIPA хранит чувствительные данные (пароли, ключи). Используйте сильные пароли, шифруйте volumes и не экспонируйте порты в production без firewall (например, ufw или iptables). Если удаляете контейнер, используйте docker compose down -v для полной очистки volumes.


Подготовка окружения

Перед установкой убедитесь в следующем:

  • ОС: Ubuntu 24.04 LTS
  • Docker:
    sudo apt update
    sudo apt install ca-certificates curl
    sudo install -m 0755 -d /etc/apt/keyrings
    sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
    sudo chmod a+r /etc/apt/keyrings/docker.asc
    
    sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
    Types: deb
    URIs: https://download.docker.com/linux/ubuntu
    Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
    Components: stable
    Signed-By: /etc/apt/keyrings/docker.asc
    EOF
    
    sudo apt update
    sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
    
  • Права: Запускайте команды от root или с sudo.
  • Сеть: Хост-IP (в примере 10.0.0.27) должен быть статическим и доступным. Domain (homelab.lan) — локальный, не публичный.

Отключите systemd-resolved для освобождения порта 53 (предотвращение DNS-конфликта):

sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved
sudo sed -i 's/#DNSStubListener=yes/DNSStubListener=no/' /etc/systemd/resolved.conf
sudo rm -f /etc/resolv.conf
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
echo "nameserver 1.1.1.1" | sudo tee -a /etc/resolv.conf
sudo chattr +i /etc/resolv.conf

Почему? Stub listener на 127.0.0.53:53 конфликтует с bind на 0.0.0.0:53 в контейнере. После установки верните resolv.conf на локальный DNS, если это необходимо.

Создайте директорию для volumes:

sudo mkdir -p /opt/freeipa/data

Настройка Docker для User Namespace Remapping

Чтобы избежать проблем с правами в privileged-режиме (особенно для sysctls и cap_add), включите userns-remap. Это изолирует user namespaces контейнера от хоста, предотвращая потенциальные security-риски.

Отредактируйте /etc/docker/daemon.json (создайте файл, если его нет):

{
  "userns-remap": "default"
}

Почему? Без этого Podman (и иногда Docker) падает при попытке bind портов <1024 в rootless-режиме. В Docker это фиксит конфликты с cgroup и сетью.

Перезапустите Docker и проверьте статус:

sudo systemctl restart docker
docker info | grep -i userns

Вывод должен содержать строку “userns”.


Docker Compose Конфигурация

Создайте файл docker-compose.yml в рабочей директории. Вот полный production-ready конфиг на основе моего опыта.

services:
  freeipa:
    image: freeipa/freeipa-server:rocky-9-4.12.2
    hostname: idm.homelab.lan
    container_name: freeipa.homelab
    ports:
      - 80:80
      - 443:443
      - 389:389
      - 636:636
      - 88:88
      - 464:464
      - 88:88/udp
      - 464:464/udp
      - 53:53/udp
      - 53:53/tcp
    restart: unless-stopped
    tty: true
    stdin_open: true
    environment:
      IPA_SERVER_HOSTNAME: idm.homelab.lan
      IPA_SERVER_IP: 10.0.0.27
      IPA_DOMAIN_NAME: homelab.lan
      IPA_REALM_NAME: HOMELAB.LAN
      PASSWORD: Password123
    command:
      - --domain=homelab.lan
      - --realm=HOMELAB.LAN
      - --admin-password=Password123
      - --http-pin=Password123
      - --dirsrv-pin=Password123
      - --ds-password=Password123
      - --setup-dns
      - --forwarder=8.8.8.8
      - --no-ntp
      - --unattended
    cap_add:
      - SYS_TIME
      - NET_ADMIN
    volumes:
      - /opt/freeipa/data:/data
    sysctls:
      - net.ipv6.conf.all.disable_ipv6=0
      - net.ipv6.conf.lo.disable_ipv6=0

Разбор конфигурации:

  • ports: Экспортируем только необходимые (HTTP/HTTPS для UI, LDAP, Kerberos, DNS). UDP/TCP для DNS и Kerberos.
  • environment / command: Передаём параметры установки unattended (без интерактива). --setup-dns включает BIND, --forwarder=8.8.8.8 для внешних запросов.
  • cap_add: Для манипуляции временем (SYS_TIME) и сетью (NET_ADMIN).
  • sysctls: Фикс IPv6-ошибок в контейнере (FreeIPA иногда жалуется).
  • volumes: Persistent data в /opt/freeipa/data для сохранения конфига при перезапусках.

Альтернатива: Если не хотите использовать DNS внутри FreeIPA, уберите --setup-dns и используйте ваш внешний DNS.


Запуск Установки

Запустите контейнер в фоновом режиме:

docker compose up -d

Следите за логами:

docker compose logs -f freeipa.homelab

Установка займёт 5-10 минут. Ищите сообщение “Done configuring” для каждого компонента (Directory Server, KDC, CA и т.д.). Если произошла ошибка — проверьте лог /opt/freeipa/data/var/log/ipaserver-install.log.

Проверьте статус внутри контейнера:

docker exec -it freeipa.homelab ipactl status

Все сервисы (Directory, KDC, HTTP, DNS) должны быть в статусе running.

Быстрые примеры использования:

  • Доступ к shell: docker exec -it freeipa.homelab bash
  • Web UI: Откройте https://10.0.0.27/ipa/ui (логин: admin, пароль: ваш). Игнорируйте предупреждение о self-signed сертификате.

Пост-установка и Настройка

После базовой установки нужно донастроить DNS и пользователей. Вот команды, которые помогли мне:

Проверьте текущий DNS-конфиг:

docker exec -it freeipa.homelab ipa dnsconfig-show

Добавьте forwarder (если не указали его в command):

docker exec -it freeipa.homelab ipa dnsconfig-mod --forwarder=8.8.8.8

Почему? Без forwarder локальный DNS не резолвит внешние домены.

Создайте сервисного пользователя (например, для интеграции с Authentik):

docker exec -it freeipa.homelab ipa user-add authentik --first=Authentik --last=Service --password

(Введите пароль при запросе)

Установите бесконечный срок действия пароля:

docker exec -it freeipa.homelab ipa user-mod authentik --password-expiration=20380101000000Z

Почему? Сервисные аккаунты не должны внезапно требовать смены пароля.

Разрешите рекурсию в DNS для внешних запросов:

docker exec -it freeipa.homelab vi /etc/named.conf

Добавьте в секцию options { ... } строку allow-recursion { any; };. Сохраните файл и перезапустите службу:

docker exec -it freeipa.homelab systemctl restart named

Почему? По умолчанию рекурсия ограничена, что ломает DNS для клиентов. any; разрешает запросы всем, но в production лучше ограничить подсетью (например, allow-recursion { 10.0.0.0/24; };).

Тестирование DNS: С хоста выполните dig @10.0.0.27 google.com — команда должна вернуть IP-адрес.


Почему не удалось в podman?

Podman — отличная альтернатива Docker (без daemon, rootless), но в моём случае всплыли следующие проблемы:

  • Rootless-режим не позволял bind на порт 53 без sudo.
  • network_mode: host вызывал конфликты с cgroup и sysctls.
  • Compose в Podman (через podman-compose) менее стабилен для сложных privileged-контейнеров.

Если вы всё же хотите использовать Podman, добавьте network_mode: host и запускайте всё через sudo, но для максимальной простоты я рекомендую остаться на Docker.


Список Полезных Команд для Управления FreeIPA (Cheat-sheet)

Вот небольшая шпаргалка для повседневного администрирования. Все команды выполняются внутри контейнера (docker exec -it freeipa.homelab <command>) или через CLI ipa.

Статус и рестарт

  • ipactl status — Проверить статус всех сервисов.
  • ipactl restart — Перезапустить службы FreeIPA.

Пользователи и группы

  • ipa user-add username --first=First --last=Last --password — Добавить пользователя.
  • ipa user-show username — Просмотреть детали профиля.
  • ipa user-del username — Удалить пользователя (деструктивное действие!).
  • ipa group-add groupname — Создать группу.
  • ipa group-add-member groupname --users=username — Добавить пользователя в группу.

DNS

  • ipa dnszone-show domain.lan — Просмотреть зону.
  • ipa dnsrecord-add domain.lan hostname --a-ip-address=IP — Добавить A-запись.
  • ipa dnsconfig-mod --allow-recursion=any — Разрешить рекурсию (альтернатива ручному редактированию named.conf).

Сертификаты (CA)

  • ipa cert-show serial_number — Просмотреть информацию о сертификате.
  • ipa cert-request csr.pem --principal=host/hostname.domain.lan — Запросить сертификат из CSR.

HBAC и SUDO правила

  • ipa hbacrule-add allow_all — Добавить правило доступа.
  • ipa sudorule-add allow_sudo --hostcat=all --runasusercat=all --usercat=all — Разрешить sudo для всех пользователей.

Бэкап и восстановление

  • ipa-backup — Создать бэкап (сохраняется в /var/lib/ipa/backup).
  • ipa-restore /path/to/backup — Восстановить систему из бэкапа.

Логи и отладка

  • tail -f /var/log/ipaserver-install.log — Просмотр логов установки в реальном времени.
  • kinit admin — Получить Kerberos ticket для администратора.

Оставайтесь на линии. 🚀