Зачем Kerberos
Решает фундаментальную проблему многосервисной сети: пользователь не должен вводить пароль каждый раз заново; пароль не должен ходить по сети; сервер должен быть уверен, что юзер, именно тот, за кого себя выдаёт. Kerberos с 1988 (MIT, проект Athena) даёт этот SSO. Сегодня:
- Active Directory, Kerberos с самого начала AD; krb5 + LDAP через MS-расширения
- FreeIPA, RHEL'овский SSO-стек: Kerberos + 389-DS + DNS + CA
- NFSv4 sec=krb5p, единственный production-grade auth для NFS в multi-user environment
- SSH GSSAPI, проксирование Kerberos-аутентификации
- Hadoop/Kafka secure mode, krb для service-to-service auth
Не для интернет-сервисов общего пользования (там OIDC/OAuth2 правит), но в корпоративном datacenter, стандарт.
Главные понятия
| Термин | Что |
|---|---|
| Realm | административный домен (типично UPPERCASE имя домена: EXAMPLE.COM) |
| Principal | identity внутри realm: alice@EXAMPLE.COM (user) или host/server.example.com@EXAMPLE.COM (service) |
| KDC | Key Distribution Center, сервер выдаёт тикеты. Состоит из AS + TGS |
| AS (Authentication Service) | первичная аутентификация, выдаёт TGT |
| TGS (Ticket Granting Service) | в обмен на TGT выдаёт service tickets |
| TGT | Ticket Granting Ticket, главный тикет, на ~10 часов |
| Service Ticket | "пропуск" к конкретному сервису, на минуты-часы |
| Keytab | файл с долгосрочными ключами для service-principals (без пароля) |
Все ключи, симметричные. Это и сила (быстрая криптография), и ограничение (KDC должен знать ключи всех принципалов).
Поток аутентификации
Упрощённо:
Client KDC (AS+TGS) Service
│ │ │
│ AS-REQ (I'm alice@EXAMPLE.COM) │ │
├─────────────────────────────────────►│ │
│ AS-REP (TGT, encrypted with │ │
│ alice's password-derived key) │ │
│◄─────────────────────────────────────┤ │
│ [client decrypts → if pw correct] │ │
│ │ │
│ TGS-REQ (TGT + "I want service │ │
│ nfs/file.example.com") │ │
├─────────────────────────────────────►│ │
│ TGS-REP (service ticket, │ │
│ encrypted with service's key) │ │
│◄─────────────────────────────────────┤ │
│ │ │
│ AP-REQ (service ticket) │ │
├─────────────────────────────────────────────────────────►│
│ AP-REP (mutual auth, optional) │
│◄─────────────────────────────────────────────────────────┤
Главное: пароль идёт только в первом сообщении (и то, не пароль напрямую, а ключ из него). Дальше ходят тикеты.
Принципалы
Формат:
primary[/instance]@REALM
alice@EXAMPLE.COM ← user
host/server.example.com@EXAMPLE.COM ← service "host" (для SSH/SCP)
nfs/server.example.com@EXAMPLE.COM ← NFS-сервис
HTTP/web.example.com@EXAMPLE.COM ← Apache/Nginx с SPNEGO
alice/admin@EXAMPLE.COM ← привилегированный alice
Service-принципалы названы по схеме service/fqdn@REALM, где
service, известный тип (host, HTTP, nfs, ldap, ftp).
Установка MIT Kerberos на Linux
# Сервер (KDC)
apt install krb5-kdc krb5-admin-server # Debian/Ubuntu
dnf install krb5-server krb5-server-ldap # RHEL
# Клиенты
apt install krb5-user # Debian/Ubuntu
dnf install krb5-workstation # RHEL
/etc/krb5.conf:
[libdefaults]
default_realm = EXAMPLE.COM
dns_lookup_realm = false
dns_lookup_kdc = true # KDC через SRV-записи
ticket_lifetime = 24h
renew_lifetime = 7d
[realms]
EXAMPLE.COM = {kdc = kdc1.example.com
kdc = kdc2.example.com
admin_server = kdc1.example.com
}
[domain_realm]
.example.com = EXAMPLE.COM
example.com = EXAMPLE.COM
KDC требует точно синхронизированное время (max skew ~5 минут):
без NTP/chrony Kerberos падает с Clock skew too great.
Daily commands
kinit alice # запросить TGT (введёт пароль)
klist # показать тикеты в кэше
klist -e # с типом шифрования
kdestroy # очистить cache
kpasswd # сменить пароль
# Из keytab без интерактива
kinit -k -t /etc/krb5.keytab host/server.example.com
# Renew TGT (если в lifetime)
kinit -R
Cache по дефолту в /tmp/krb5cc_$UID (FILE-based) или Keyring/KCM
на современных дистро.
Keytab, для сервисов
Сервисы (sshd, nfs, http) не могут запрашивать пароль. Их долгосрочные ключи лежат в keytab (binary файл):
# Создать service principal на KDC
kadmin.local -q "addprinc -randkey nfs/server.example.com"
# Экспортировать в keytab
kadmin.local -q "ktadd -k /etc/krb5.keytab nfs/server.example.com"
# На клиенте использовать
ktutil
> read_kt /etc/krb5.keytab
> list -e
# Версия keytab
klist -kt /etc/krb5.keytab
Keytab, секрет. Mode 600, owner = root (или сервисный юзер). Утечка = захват сервиса.
Поддержка ядра: KEYRING / KCM
Раньше тикеты лежали в файле /tmp/krb5cc_$UID. Современные дистро
используют:
- KEYRING, хранение в kernel keyring, изоляция per-namespace
- KCM (Kerberos Cache Manager), daemon, удобно для multi-user
- collection of caches (несколько realm'ов одновременно)
Конфигурируется через default_ccache_name = KEYRING:persistent:%{uid}.
SSH через GSSAPI/Kerberos
Зашёл kinit один раз, ssh server.example.com не спросит пароль:
Сервер:
# /etc/ssh/sshd_config
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes
Клиент:
# ~/.ssh/config
Host *.example.com
GSSAPIAuthentication yes
GSSAPIDelegateCredentials yes # форвардить TGT на сервер
С GSSAPIDelegateCredentials yes, сервер получит копию твоего TGT,
сможет от твоего имени дальше ходить (на NFS/другие SSH).
MIT Kerberos vs Heimdal vs AD
| Признак | MIT | Heimdal | Microsoft AD |
|---|---|---|---|
| Lineage | референс | независимая реализация | проприетарная |
| На Linux default | RHEL/Fedora/Debian | FreeBSD, Samba (старо) | через samba/realmd |
| Active dev | да | замедлилась | да |
| Совместимость с AD | хорошая | хорошая | родной |
Большинство Linux-документации подразумевает MIT.
Когда что-то пошло не так
Clock skew too great, KDC и клиент разошлись по времени больше чем наclockskew(default 5min). Включи [[chrony-and-ntp|chrony]].KDC has no support for encryption type, клиент запрашивает DES/RC4, KDC выключил их (security update). Обновиdefault_tgs_enctypes/default_tkt_enctypesна современные (aes256-cts).Cannot find KDC for requested realm, DNS SRV не настроен, либоdns_lookup_kdc = falseбез явногоkdc =в[realms].Permission denied (gssapi-with-mic)в SSH, нет TGT (klistпуст), либо service-principalhost/server@REALMотсутствует на KDC, либо keytab сервера устарел.KRB_AP_ERR_TKT_EXPIRED, service-ticket истёк по таймауту.kinit -Rобновит TGT, новые service-tickets подтянутся.- Keytab перестал работать после смены пароля принципала
KVNO (key version number) увеличился. Перевыпусти keytab:
ktadd -k /etc/krb5.keytab service/host. Server not found in Kerberos database, service-principal не создан на KDC; либо запрос идёт по неправильному hostname (mismatched DNS vs principalhost/).