AD autentisering i Linux med SSSD och Kerberos
Planen är att beskriva den nuvarande metod jag använder med Samba, Kerberos och SSSD.
Operativsystem jag testat detta på är Debian 7, CentOS6/7 och RHEL7.
Debian 7 saknar realmd så join måste göras med samba. CentOS6 och uppåt har realmd som är ett mycket smidigare sätt att göra en join på.
Nätverk
AD behöver en väldans massa portar för att fungera rätt, t.ex. är DNS och tidtjänst kritiska. Här är en lista från en tidigare artikel som jag tror stämmer bra.
Paketinstallation
$ sudo yum install sssd sssd-client openldap-clients krb5-workstation samba \
realmd oddjob oddjob-mkhomedir selinux-policy-mls # CentOS/RHEL
$ sudo apt-get install sssd sssd-tools ldap-utils krb5-user samba # Debian
- Lägg till realmd om du kör Debian 8
Windows DC
Installera tillägget Identity Management for UNIX på minst en DC i ditt nätverk.
Denna DC kommer få en extra flik för alla AD-objekt som heter UNIX Attributes. De inställningarna används för att ange ett globalt UID och GID för UNIX-användarkonton.
NSS
På Debian måste man redigera /etc/nsswitch.conf
manuellt, men på RHEL kör man bara authconfig.
sudo authconfig --enablesssd --enablesssdauth --enablemkhomedir --update
Då redigeras följande rader.
passwd: files sss
shadow: files sss
group: files sss
hosts: files dns wins
services: files sss
netgroup: files sss
automount: files sss
sudoers: files sss
Resten av filen kan lämnas orörd.
Authconfig sköter även PAM i RHEL, men i Debian kan detta skötas av pam-auth-update verktyget. Då får man välja i en meny vilka metoder man vill stödja och pam-filerna redigeras åt dig.
sudo pam-auth-update
Oddjobd i CentOS/RHEL
I CentOS och RHEL använder man oddjob för PAM-modulen oddjob-mkhomedir som skapar hemkataloger åt användare vid inloggning.
Då måste oddjob-tjänsten vara startad.
sudo systemctl enable oddjobd
sudo systemctl start oddjobd
DNS
Se till att alla DCs finns inlagda i /etc/resolv.conf
och att sökdomänen är rätt.
Kerberos
Konfigurationsfilen för Kerberos kan se ut så här, för en domän som heter DOMAIN.TLD.
[logging]
default = FILE:/var/log/krb5libs.log
[libdefaults]
default_realm = DOMAIN.TLD
dns_lookup_realm = true
dns_lookup_kdc = true
ticket_lifetime = 24h
renew_lifetime = 7d
rdns = false
forwardable = yes
default_tkt_enctypes = rc4-hmac des-cbc-crc des-cbc-md5
default_tgs_enctypes = rc4-hmac des-cbc-crc
[realms]
DOMAIN.TLD = {
kdc = DC01.DOMAIN.TLD:88
admin_server = DC01.DOMAIN.TLD:464
kdc = DC02.DOMAIN.TLD:88
admin_server = DC02.DOMAIN.TLD:464
default_domain = DOMAIN.TLD
}
[domain_realm]
.domain.tld = DOMAIN.TLD
domain.tld = DOMAIN.TLD
Samba
Tjänsten Samba behövs inte men konfigurationsfilen måste redigeras för att Samba ska användas vid join till AD.
[global]
workgroup = DOMAIN
client signing = yes
client use spnego = yes
kerberos method = secrets and keytab
log file = /var/log/samba/%m.log
realm = DOMAIN.TLD
security = ads
Observera att i CentOS 7 och Debian 8 kan realmd användas istället.
SSSD
Konfigurationsfilen kan se ut så här.
[sssd]
config_file_version = 2
domains = domain.tld
services = nss, pam
debug_level = 4
[nss]
filter_users = root
filter_groups = root
[pam]
pam_pwd_expiration_warning = 14
[domain/domain.tld]
id_provider = ldap
auth_provider = krb5
chpass_provider = krb5
access_provider = ldap
cache_credentials = true
ldap_sasl_mech = GSSAPI
ldap_schema = rfc2307
ldap_search_base = cn=Users,dc=domain,dc=tld?onelevel?(objectClass=group)?ou=Company,ou=Hosting,dc=domain,dc=tld?subtree?(|(objectClass=group)(objectClass=user))
ldap_user_object_class = user
ldap_user_home_directory = unixHomeDirectory
ldap_user_principal = userPrincipalName
ldap_group_object_class = group
ldap_access_order = filter, expire
ldap_access_filter = &(objectClass=user)(sAMAccountName=*)
ldap_account_expire_policy = ad
ldap_force_upper_case_realm = true
krb5_realm = DOMAIN.TLD
ldap_tls_reqcert = allow
override_shell = /bin/bash
override_homedir = /home/%d/%u
override_space = _
filter_users
är bra för att undvika att hämta en lokal administratörsanvändare från AD.
På Debian 8, CentOS 6 och uppåt hade jag hellre använt id_provider = ad
, men jag har inte provat det än.
ldap_search_base
är ett exempel på ett filter som listar grupperna Domain Users och Domain Admins under cn=Users,dc=domain,dc=tld
samtidigt som jag listar användare under ett annat ou.
Alternativet override_shell
fungerar inte heller i Debian 7 versionen av sssd.
Alternativet override_space
betyder att alla grupp eller användarnamn med mellanslag kommer få ett understreck där istället. Det hjälper lite i Linux, t.ex. blir sudoers regler enklare att skriva.
Starta SSSD
sudo systemctl enable sssd
sudo systemctl start sssd
Eller i Debian.
sudo update-rc.d sssd defaults
sudo service sssd start
Sudoers
Jag väljer att låta Domain Admins köra sudo utan lösenord eftersom jag inte konfat sudo att använda SSS ännu.
User_Alias DOMAINADMINS=%Domain_Admins
DOMAINADMINS ALL=NOPASSWD: ALL
Jag har skrivit Domain_Admins för att override_space
i sssd.conf omvandlar namnen. Precis som i gamla artikeln så kan vi ange gruppnamn med mellanslag om vi skriver så här.
%domain\x20admins
Join
Kör man Debian 7 och uppåt kan man använda Samba.
Antingen kör vi med Kerberos ticket.
sudo kinit admin@DOMAIN.TLD
sudo net ads join createupn=host/my-system.domain.tld@DOMAIN.TLD -k
sudo net ads keytab create
sudo net ads keytab add host/my-system.domain.tld@DOMAIN.TLD -k
sudo service sssd stop || sudo systemctl stop sssd
sudo rm /var/lib/sss/db/cache_domain.tld.ldb
sudo service sssd start || sudo systemctl start sssd
Då ska inget lösenord krävas av samba, bara av kerberos.
Eller kör man bara med samba så krävs lösenord direkt.
sudo net ads join -U admin
Password for admin@DOMAIN.TLD: ******
Vad som ska hända nu är att DNS läggs upp i alla DCs för din nya klient, så testa det först.
Testa sedan så man kan slå upp användare och grupper.
id user
getent group Domain_Admins
I Debian 8, CentOS 6 och uppåt kan vi använda realmd.
sudo realm -v discover DOMAIN.TLD
sudo realm -v join -U admin DOMAIN.TLD
OBS problemet med join i AD är att ett Computers OU måste skapas för datorn. Detta verkar inte fungera bra med verktyget realm och vissa har löst det genom att skapa OU med Pythonskripts men
sudo net ads join createupn
fungerar precis lika bra för det syftet.
Re-join
Spara /etc/sssd/sssd.conf
.
sudo cp /etc/sssd/sssd.conf ./
Lämna domänen.
sudo realm leave -v -U admin DOMAIN.TLD
Radera hela [domain/domain.tld]
stycket från /etc/sssd/sssd.conf
.
Gå med i domänen igen, då skapas konfiguration i /etc/sssd/sssd.conf
som inte duger.
sudo realm join -v -U admin DOMAIN.TLD
Återställ /etc/sssd/sssd.conf
så att de gamla alternativen som ldap_search_base
t.ex. återvänder under blocket [domain/domain.tld]
i filen.
Upprepa sedan steg 5-7 här ovan.
Felsökning
Nya grupper/användare syns inte
En ny grupp läggs till, eller en användare läggs till i en ny grupp och du kan varken se den nya gruppen eller att användaren är medlem i den.
Detta kan hända om t.ex. cachet måste rensas. Rensa då både grupp och användarcache så här på CentOS 7.
sss_cache -u användarnamn
sss_cache -g gruppnamn
Se även till att användaren är tillagd via Unix Attributes fliken på AD-servern. Det räcker tyvärr inte att bara lägga till användaren under Member Of fliken som man normalt gör.
När en användare läggs till via Unix Attributes med hjälp av Identity Management for Unix på en Windows Domänkontrollant så läggs memberUid attributet till. Detta kan kontrolleras med följande ldapsearch, om din användare har en kerberos ticket.
ldapsearch -H 'ldap://dc05.domain.local/' -Y GSSAPI -N -b 'dc=domain,dc=local' '(&(objectClass=group)(cn=gruppnamn))'
Sedan kan det även vara så att ldap_search_base
i sssd.conf är för komplex. Jag behövde t.ex. byta ut följande söksträng.
ldap_search_base = cn=Users,dc=domain,dc=local?onelevel?(objectClass=group)?ou=Company,ou=Hosting,dc=domain,dc=local?subtree?(|(objectClass=group)(objectClass=user))
Mot följande mycket enklare söksträng.
ldap_search_base = dc=domain,dc=local?subtree?(|(objectClass=group)(objectClass=user))
Notera
Du kan ersätta -Y GSSAPI
med -D användarnamn -W
för att använda användarnamn och lösenord istället för kerberos
Windows DC
Se till att UNIX Attributes fliken är rätt inställd för alla objekt. T.ex. måste grupper ha sina medlemmar listade där under, och användarkonton måste ha ett UID och en primär grupp.
SSSD
Görs ändringar i sökfilter eller SSSD konfiguration så kan man behöva rensa cachet. Detta kan hjälpa för många konstiga problem där nya användare eller grupper inte syns.
sudo sss_cache -E || sudo sss_cache -UGN
Argumenten skiljer sig mellan RHEL och Debian eftersom paketversionerna skiljer.
Eller radera databasfilen och starta om tjänsten.
sudo rm /var/lib/sss/db/cache_domain.tld.ldb
sudo systemctl restart sssd || sudo service sssd restart
DNS
DNS måste fungera, namn måste vara rättstavade i /etc/krb5.conf
och andra filer. Just /etc/krb5.conf
är noga med versaler och gemener.
Se över alla namnservrar i systemet, prova att skicka frågor till dem och se så att alla DCs kan lösas upp vid namn. I RHEL-baserade system är det lätt hänt att tjänsten NetworkManager tar över och skriver över resolv.conf.
sudo systemctl disable NetworkManager
sudo systemctl stop NetworkManager
Jag ser inget behov för den på servrar.
Kerberos
Felsök kerberos enklast genom att begära en ticket och sedan köra ldapsearch med -Y GSSAPI
argumentet.
kinit user@DOMAIN.TLD
ldapsearch -H 'ldap://dc02.domain.tld/' -Y GSSAPI -N -b 'dc=domain,dc=tld' '(&(objectClass=user)(sAMAccountName=user name))'
Använd även klist för att se vilka tickets som finns tillgängliga. klist -ke visar host-tickets som behövs för att hålla datorn ansluten till AD. Tänk createupn argumentet ovan när man går med i AD, det argumentet ska stämma överens med någon host-ticket i klist -ke.
Join av klient i domän
Detta steget är manuellt eftersom det kan vara lite problematiskt att få igång. Helst ska man göra de här stegen.
Out of memory
Men det fungerar inte alltid, man kan få följande fel.
$ sudo net ads join createupn=host/web02.domain.local@DOMAIN.LOCAL -k
Failed to join domain: failed to set machine spn: Out of memory
Det kan betyda att du felsökt mycket och kört många kerberos-kommandon, för det finns ett cache av nycklar i Linux som kan fyllas och då måste det antingen utökas eller startar du om systemet.
Öka nyckelcache så här.
sudo sysctl kernel.keys.root_maxbytes=60000 # För root
sudo sysctl kernel.keys.maxbytes=60000 # För andra användare
Unable to perform DNS update
Ett annat vanligt fel vid join.
$ sudo net ads join createupn=host/web02.domain.local@DOMAIN.LOCAL -k
Using short domain name -- DOMAIN
Joined 'WEB02' to dns domain 'domain.local'
No DNS domain configured for web02. Unable to perform DNS Update.
DNS update failed: NT_STATUS_INVALID_PARAMETER
Unable to perform DNS update
kan bero på att den nya maskinens hostnamn inte är inlagt i DNS ännu, så redigera /etc/hosts
och lägg till maskinens ip-adress manuellt och prova igen.
Ibland måste man bara upprepa kommandot tills det fungerar. Är det så att DNS redan fungerar kan felet ignoreras, testa det med host-kommandot t.ex..
host web02.domain.tld dc02.domain.tld
Failed to join domain: failed to set machine spn: Constraint violation
I min erfarenhet har detta att göra med att värdnamnet för maskinen saknas i /etc/hosts. Trots att DNS fungerar så måste jag hårdkoda det korrekta namnet för domänen i /etc/hosts
.
Se även RedHat KB artikel om ämnet.
Sammanfattat så beror det antingen på portöppningar, glöm inte UDP! Eller så beror det på att din användare eller AD-användaren du ansluter med inte har tillräckligt med behörighet för att joina en klient i AD.
Failed to join domain: failed to set machine upn: Insufficient access
Användaren du försöker köra join med är inte domänadmin. Den måste också vara root på ad-klienten.
Failed to connect to our DC!
Syns detta felet vid samba join så kan det betyda att du har ett felaktigt hårdkodat värdnamn för maskinen i /etc/hosts
.
$ sudo net ads join createupn=host/web01.domain.tld@DOMAIN.TLD -k
Using short domain name -- DOMAIN
Joined 'WEB01' to realm 'domain.tld'
net_update_dns_internal: Failed to connect to our DC!
Failed to join domain: failed to connect to AD: Cannot read password
Får du det felet från join och sedan kör samma join med argumentet -d4
så ser du kanske följande rad.
ads_krb5_mk_req: smb_krb5_get_credentials failed for ldap/web02.domain.tld@DOMAIN.TLD (No credentials found with supported encryption types)
Så kanske man har inkompatibla krypteringstyper tillåtna i Kerberos, jämfört med Windows DCs. Här är ett exempel på en konfiguration som fungerar med Win2k8r2 DC.
[libdefaults]
default_tkt_enctypes = rc4-hmac des-cbc-crc des-cbc-md5
default_tgs_enctypes = rc4-hmac des-cbc-crc
Se också
- AD Autentisering i RHEL7
- Gammal guide for RHEL6
- Gammal guide for Debian
- Microsoft guide för att installera Identity Management for Unix
- How to setup cifs mounts in autofs using kerberos authentication
- Attempting to join an AD domain fails with "Failed to join domain: failed to set machine spn: Constraint violation"
- SSSD Cache dokumentation från RedHat
- Portar som krävs för Samba