Integracja Active Directory z Linuksem oraz przydzielanie uprawnień administracyjnych na prawach grup

Przeczytasz to w: 8 minut

Akurat to użycie integracji nie daje aż takich korzyści w stosunku do integracji AD na przykład z FortiGate’m, ale nadal można to wykorzystać w ciekawy sposób niespecjalnie pocąc się przy konfiguracji. Założenie jest dosyć proste – umożliwić logowanie się na konta z domeny Active Directory (najnornalniejszej na świecie, żadne udziwnienia w postaci AD na QNAPie czy tym podobne) oraz umożliwić konkretnej grupie w AD korzystanie z uprawnień administracyjnych (aka korzystanie z polecenia sudo).

Moje środowisko składa się z dwóch kontrolerów domeny, ad1.serba.local (192.168.30.2) i ad2.serba.local (192.168.30.3). Do tego są inne hosty w sieci, które są totalnie nieistotne. Jak FQDNy wskazują, moja nazwa domeny to serba.local. Grupa, której damy uprawnienia administracyjne w Linuksach to wbudowana grupa AD Administratorzy domeny. Adres sieci to 192.168.30.0/24 i pierwszy użyteczny adres to adres routera. Przykład integracji opieram na Windowsach Server 2019 v. 1809, Xubuntu 19.10 i Red Hat Enterprise Linux 8.0. Dobrałem takie 2 dystrybucje Linuksa ze względu na to, że one i ich pochodne (przy czym Ubuntu jest pochodną Debiana te podobieństwo działa w drugą stronę) są bardzo podobne w konfiguracji, więc w jednym poradniku będzie można zobaczyć jak zrobić taką integrację na większości dystrybucji. W praktyce powinniśmy być w stanie zintegrować dowolną dystrybucję Linuksa posiadając zainstalowane w systemie odpowiednie pakiety.

Integracja AD na (X)ubuntu

Na początku zaczynamy od instalacji potrzebnych pakietów:

# apt install adcli realmd krb5-user samba-common-bin samba-libs samba-dsdb-modules sssd sssd-tools libnss-sss libpam-sss packagekit policykit-1

Następnie edytujemy plik /etc/samba/smb.conf w sekcji [global] (ta sekcja zaczyna się pod tym nagłówkiem, a kończy się z miejscem kolejnego):

   workgroup = SERBA #tutaj nazwa NETBIOS domeny
   client signing = yes
   client use spnego = yes
   kerberos method = secrets and keytab
   realm = SERBA.LOCAL #koniecznie dużymi literami
   security = ads
   idmap config *: range = 10000-20000 #bez dodania tego parametru nie przechodził test cfg

Po wykonaniu zmian warto przetestować, czy wszystko w tym pliku konfiguracyjnym jest OK, w innym wypadku sługi smbd i nmbd nie uruchomią się po restarcie. Robimy to poleceniem sudo testparm:

Następnie edytujemy /etc/sssd/sssd.conf (ten plik domyślnie nie istnieje, więc nie zdziwcie się, jeśli pliku nie będzie):

[nss]
filter_groups = root
filter_users = root
reconnection_retries = 3

[pam]
reconnection_retries = 3

[sssd]
domains = serba.local #tutaj nazwa domeny małymi literami
config_file_version = 2
services = nss, pam
default_domain_suffix = SERBA.LOCAL #tutaj domena dużymi literami
full_name_format = %1$s #dzięki tej linijce nie musimy wpisywać `użytkownik@domena` tylko wystarczy `użytkownik`

[domain/serba.local] #małymi literami domena
ad_domain = serba.local #ponownie domena małymi literami
krb5_realm = SERBA.LOCAL #tym razem domena dużymi literami
realmd_tags = manages-system joined-with-samba
cache_credentials = True
id_provider = ad
krb5_store_password_if_offline = True
default_shell = /bin/bash #definiujemy shell dla logujących się użytkowników AD, może być inny
ldap_id_mapping = True
use_fully_qualified_names = True
fallback_homedir = /home/%d/%u #składnia: /home/<nazwa-domeny>/<nazwa-uzytkownika>
access_provider = ad

auth_provider = ad
chpass_provider = ad
access_provider = ad
ldap_schema = ad
dyndns_update = true
dyndns_refresh_interval = 43200
dyndns_update_ptr = true
dyndns_ttl = 3600

Po stworzeniu konfiguracji musimy zabezpieczyć plik w ten sposób, by inni poza rootem nie mieli do niego dostępu:

# chown 600 /etc/sssd/sssd.conf
# chown root:root /etc/sssd/sssd.conf

Następnie definiujemy plik /etc/realmd.conf:

[active-directory]
os-name = Linux Ubuntu
os-version = 19.04

[service]
automatic-install = yes

 [users]
default-home = /home/%d/%u
default-shell = /bin/bash

[serba.local]
user-principal = yes
fully-qualified-names = no

[providers]
samba = no #bez tej linijki są problemy z logowaniem ze wskazaniem uprawnień grup do logowania poprzez realm

Mając to zrobione musimy zrestartować usługi, które konfigurowaliśmy:

# systemctl restart smbd nmbd sssd realmd

Następnie możemy sprawdzić, czy mamy połączenie z domeną pobierając „bilecik” z KDC poprzez polecenie kinit określając nazwę użytkownika@domenę, z której się logujemy:

# kinit rserba@SERBA.LOCAL
Password for rserba@SERBA.LOCAL: 
# /etc/sssd > klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: rserba@SERBA.LOCAL

Valid starting       Expires              Service principal
02.04.2020 21:04:52  03.04.2020 07:04:52  krbtgt/SERBA.LOCAL@SERBA.LOCAL
renew until 09.04.2020 21:04:49

Po tym możemy dołączyć naszym Linuksowym hostem do domeny AD. Najpierw sprawdźmy, czy jesteśmy w stanie wykryć domenę w naszej sieci poleceniem realm discover -v NAZWA.DOMENY:

# realm discover -v SERBA.LOCAL
 * Resolving: _ldap._tcp.serba.local
 * Performing LDAP DSE lookup on: 192.168.30.3
 * Performing LDAP DSE lookup on: 192.168.30.2
 * Successfully discovered: serba.local
serba.local
  type: kerberos
  realm-name: SERBA.LOCAL
  domain-name: serba.local
  configured: kerberos-member
  server-software: active-directory
  client-software: sssd
  required-package: sssd-tools
  required-package: sssd
  required-package: libnss-sss
  required-package: libpam-sss
  required-package: adcli
  required-package: samba-common-bin
  login-formats: %U@serba.local
  login-policy: allow-realm-logins

I teraz już na serio dołączamy do domeny poleceniem realm join NAZWA.DOMENY -U konto_admina -v:

# realm join SERBA.LOCAL -U rserba -v
 * Resolving: _ldap._tcp.serba.local
 * Performing LDAP DSE lookup on: 192.168.30.3
 * Performing LDAP DSE lookup on: 192.168.30.2
 * Successfully discovered: serba.local
realm: Już dołączono do tej domeny

Powtarzamy poleceniem net ads join -k:

# net ads join -k
Using short domain name -- SERBA
Joined 'SUPRA-VM' to dns domain 'serba.local'

Następnie musimy ograniczyć logowanie do tego hosta poprzez wskazanie grupy, która może się logować oraz reszty, która tego robić nie może. Pierwszym poleceniem blokujemy dostęp wszystkim użytkownikom, a następnie dodajemy grupę, która może się logować do tego systemu. Wszyscy członkowie tej grupy mogą się zalogować.

# realm deny -a                                            
# realm permit --groups 'serba.local\Administatorzy domeny'

Przed zalogowaniem się musimy też umożliwić automatyczne tworzenie katalogów dla użytkowników (w innym wypadku na dobrą sprawę użytkownicy AD nie będą w stanie normalnie funkcjonować w systemie na własnych prawach):

# pam-auth-update

Po otwarciu okna zaznaczamy Create home directory on login i dajemy OK:

Warto też sprawdzić plik /etc/nsswitch.conf, w sekcjach passwd, group i shadow, netgroup, services i sudoers powinno być dopisane na końcu sss:

Po tym powinniśmy dodać do /etc/pam.d/common-account linijkę na samym dole pliku:

session    required    pam_mkhomedir.so    skel=/etc/skel/    umask=0022

I teraz instalujemy winbind po to, by móc wykorzystać konta AD w ekranie logowania:

# apt install winbind

Usługa winbind.service powinna się uruchomić od razu po instalacji. Sprawdźmy, czy możemy pobrać użytkowników i grupy z AD poleceniami wbinfo -u i wbinfo -g:

# wbinfo -u
SERBA\administrator
SERBA\gość
SERBA\krbtgt
SERBA\fsso
SERBA\rserba
SERBA\smatuszczyk
SERBA\serviceacc
SERBA\mblaszczyk
SERBA\dkania
# wbinfo -g
SERBA\komputery domeny
SERBA\kontrolery domeny
SERBA\administratorzy domeny
SERBA\użytkownicy domeny
SERBA\goście domeny
SERBA\twórcy-właściciele zasad grupy
SERBA\kontrolery domeny tylko do odczytu
SERBA\klonowalne kontrolery domen
SERBA\protected users
SERBA\administratorzy kluczy
SERBA\dnsupdateproxy
SERBA\wydawcy certyfikatów
SERBA\serwery ras i ias
SERBA\grupa z replikacją haseł na kontrolerach rodc
SERBA\grupa bez replikacji haseł na kontrolerach rodc
SERBA\dnsadmins
SERBA\administratorzy schematu
SERBA\administratorzy przedsiębiorstwa
SERBA\kontrolery domeny tylko do odczytu na poziomie organizacji
SERBA\administratorzy kluczy przedsiębiorstwa

Jak widać, działa. Sprawdźmy, czy jesteśmy sprawdzić informacje o użytkowniku rserba:

# sudo getent passwd rserba 
rserba@serba.local:*:599001107:599000513:Radosław Serba:/home/serba.local/rserba:/bin/bash
# id rserba
uid=599001107(rserba@serba.local) gid=599000513(użytkownicy domeny@serba.local) grupy=599000513(użytkownicy domeny@serba.local),599000512(administratorzy domeny@serba.local),599000572(grupa bez replikacji haseł na kontrolerach rodc@serba.local)

Na końcu dodamy grupę Administratorzy domeny do /etc/sudoers i umożliwimy na logowanie poprzez interfejs graficzny (wykorzystując menedżer wyświetlania LightDM). Edytujemy /etc/sudoers (plik określający kto w tym systemie może korzystać z polecenia sudo) poleceniem visudo (jak root) i dodajemy linijkę:

#%SERBA\\administratorzy\ domeny        ALL=(ALL:ALL) ALL #nieadekwatny do przykładu
#%administratorzy\ domeny@serba.local   ALL=(ALL:ALL) ALL #nieadekwatny do przykładu
%administratorzy\ domeny        ALL=(ALL:ALL) ALL

Potem edytujemy plik /usr/share/lightdm/lightdm.conf.d/60-xubuntu.conf (na dobrą sprawę możemy sobie nawet sami utworzyć nowy plik w katalogu /usr/share/lightdm/lightdm.conf.d i upewnić się, że będzie miał prawidłową składnię) i dodajemy:

greeter-show-manual-login=true
greeter-hide-users=true

Dzięki temu trzeba będzie wpisać w pole logowania nazwę użytkownika i hasła i w ten sposób będzie można się logować na pulpit tak samo, jak lokalni użytkownicy. Zmiany są widoczne po restarcie usługi lightdm.service, więc możemy po prostu uruchomić system ponownie i wszystko powinno już wejść w życie.

Przy okazji próbując zmienić konto poprzez polecenie su - nazwa_usera_ad możemy sprawdzić czy ograniczenia na logowanie działają:

 supra@supra-vm > ~ > su - rserba
Hasło: 
rserba@supra-vm:~$ exit
wylogowanie
 supra@supra-vm > ~ > su - smatuszczyk
Hasło: 
su: Uwierzytelnienie się nie powiodło

W ten sposób wszystko działa poprawnie, przetestujmy sudo:

rserba@supra-vm:~$ sudo apt update
[sudo] hasło użytkownika rserba: 
Niestety, proszę spróbować ponownie.
[sudo] hasło użytkownika rserba: 
Stary:1 http://pl.archive.ubuntu.com/ubuntu eoan InRelease
Pobieranie:2 http://pl.archive.ubuntu.com/ubuntu eoan-updates InRelease [97,5 kB]
Pobieranie:3 http://pl.archive.ubuntu.com/ubuntu eoan-backports InRelease [88,8 kB]
Pobieranie:4 http://pl.archive.ubuntu.com/ubuntu eoan-updates/main i386 Packages [192 kB]
Pobieranie:5 http://security.ubuntu.com/ubuntu eoan-security InRelease [97,5 kB]
Pobieranie:6 http://pl.archive.ubuntu.com/ubuntu eoan-updates/main amd64 Packages [258 kB]
Pobieranie:7 http://pl.archive.ubuntu.com/ubuntu eoan-updates/main Translation-en [95,3 kB]
Pobieranie:8 http://pl.archive.ubuntu.com/ubuntu eoan-updates/main amd64 DEP-11 Metadata [79,0 kB]
Pobieranie:9 http://pl.archive.ubuntu.com/ubuntu eoan-updates/main DEP-11 48x48 Icons [14,6 kB]
Pobieranie:10 http://pl.archive.ubuntu.com/ubuntu eoan-updates/main DEP-11 64x64 Icons [24,7 kB]
Pobieranie:11 http://pl.archive.ubuntu.com/ubuntu eoan-updates/main amd64 c-n-f Metadata [8 184 B]
Pobieranie:12 http://pl.archive.ubuntu.com/ubuntu eoan-updates/restricted amd64 Packages [14,4 kB]
Pobieranie:13 http://pl.archive.ubuntu.com/ubuntu eoan-updates/restricted Translation-en [1 976 B]
Pobieranie:14 http://pl.archive.ubuntu.com/ubuntu eoan-updates/universe Translation-en [74,4 kB]
Pobieranie:15 http://pl.archive.ubuntu.com/ubuntu eoan-updates/universe amd64 DEP-11 Metadata [30,4 kB]
Pobieranie:16 http://pl.archive.ubuntu.com/ubuntu eoan-updates/universe DEP-11 48x48 Icons [20,5 kB]
Pobieranie:17 http://pl.archive.ubuntu.com/ubuntu eoan-updates/universe DEP-11 64x64 Icons [45,7 kB]
Pobieranie:18 http://pl.archive.ubuntu.com/ubuntu eoan-backports/universe amd64 DEP-11 Metadata [7 760 B]
Pobieranie:19 http://security.ubuntu.com/ubuntu eoan-security/main amd64 DEP-11 Metadata [7 388 B]
Pobieranie:20 http://security.ubuntu.com/ubuntu eoan-security/universe amd64 DEP-11 Metadata [4 852 B]
Pobrano 1 163 kB w 1s (1 120 kB/s)                
Czytanie list pakietów... Gotowe
Budowanie drzewa zależności       
Odczyt informacji o stanie... Gotowe
5 packages can be upgraded. Run 'apt list --upgradable' to see them.

Integracja AD na Red Hat Enterprise Linux

Moje instrukcje są inspirowane instrukcją, którą można znaleźć w Bazie Wiedzy Red Hata z drobnymi zmianami. Na początku instalujemy potrzebne pakiety:

# yum install adcli sssd authconfig realmd sssd oddjob oddjob-mkhomedir samba-common samba-common-tools krb5-workstation -y

Tutaj trochę od końca zaczniemy – najpierw wykrywamy domenę poleceniem adcli info nazwa.domeny:

[root@rhel8 ~]# adcli info serba.local
[domain]
domain-name = serba.local
domain-short = SERBA
domain-forest = serba.local
domain-controller = dc2.serba.local
domain-controller-site = Default-First-Site-Name
domain-controller-flags = gc ldap ds kdc timeserv closest writable full-secret ads-web
domain-controller-usable = yes
domain-controllers = dc2.serba.local dc1.serba.local
[computer]
computer-site = Default-First-Site-Name

Następnie dołączamy do domeny za pomocą adcli join nazwa.domeny -U konto_admina:

[root@rhel8 ~]# adcli join serba.local -U rserba
Password for rserba@SERBA.LOCAL: 

Sprawdźmy, czy mamy pobrany „bilecik” z KDC:

[root@rhel8 ~]# klist -kte
Keytab name: FILE:/etc/krb5.keytab
KVNO Timestamp           Principal
---- ------------------- ------------------------------------------------------
   2 06.04.2020 16:36:24 RHEL8$@SERBA.LOCAL (aes128-cts-hmac-sha1-96) 
   2 06.04.2020 16:36:24 RHEL8$@SERBA.LOCAL (aes256-cts-hmac-sha1-96) 
   2 06.04.2020 16:36:24 host/RHEL8@SERBA.LOCAL (aes128-cts-hmac-sha1-96) 
   2 06.04.2020 16:36:24 host/RHEL8@SERBA.LOCAL (aes256-cts-hmac-sha1-96) 
   2 06.04.2020 16:36:24 host/rhel8.serba.local@SERBA.LOCAL (aes128-cts-hmac-sha1-96) 
   2 06.04.2020 16:36:24 host/rhel8.serba.local@SERBA.LOCAL (aes256-cts-hmac-sha1-96) 
   2 06.04.2020 16:36:24 RestrictedKrbHost/RHEL8@SERBA.LOCAL (aes128-cts-hmac-sha1-96) 
   2 06.04.2020 16:36:24 RestrictedKrbHost/RHEL8@SERBA.LOCAL (aes256-cts-hmac-sha1-96) 
   2 06.04.2020 16:36:24 RestrictedKrbHost/rhel8.serba.local@SERBA.LOCAL (aes128-cts-hmac-sha1-96) 
   2 06.04.2020 16:36:24 RestrictedKrbHost/rhel8.serba.local@SERBA.LOCAL (aes256-cts-hmac-sha1-96)

Okej, na tym etapie musimy też edytować plik /etc/krb5.conf:

# To opt out of the system crypto-policies configuration of krb5, remove the
# symlink at /etc/krb5.conf.d/crypto-policies which will not be recreated.
includedir /etc/krb5.conf.d/

[logging]
    default = FILE:/var/log/krb5libs.log
    kdc = FILE:/var/log/krb5kdc.log
    admin_server = FILE:/var/log/kadmind.log

[libdefaults]
    dns_lookup_realm = true
    dns_lookup_kdc = true
    ticket_lifetime = 24h
    renew_lifetime = 7d
    forwardable = true
    udp_preference_limit = 1
    rdns = false
    pkinit_anchors = FILE:/etc/pki/tls/certs/ca-bundle.crt
    spake_preauth_groups = edwards25519
    default_realm = SERBA.LOCAL #tak, domena musi być z dużej litery
    default_ccache_name = KEYRING:persistent:%{uid}

[realms]
SERBA.LOCAL = { #tutaj podobnie
    kdc = serba.local #nie wpisujemy poszczególnych kontrolerów domeny, jeśli discovery działa to nie ma sensu podawać tutaj FQDNa kontrolera
    admin_server = serba.local #podobnie, w obu przypadkach podajemy z małych liter nazwę domeny
}

[domain_realm]
.serba.local = SERBA.LOCAL #w obu przypadkach z dużej litery domena
serba.local = SERBA.LOCAL

Okej, mając to ustawione zastosujmy konfigurację poleceniem authconfig --enablesssd --enablesssdauth --enablelocauthorize --enablemkhomedir --update:

[root@rhel8 ~]# authconfig --enablesssd --enablesssdauth --enablelocauthorize --enablemkhomedir --update
Running authconfig compatibility tool.
The purpose of this tool is to enable authentication against chosen services with authselect and minimum configuration. It does not provide all capabilities of authconfig.

IMPORTANT: authconfig is replaced by authselect, please update your scripts.
See man authselect-migration(7) to help you with migration to authselect
Warning: These options are not supported anymore and have no effect:
  --enablelocauthorize

Executing: /usr/bin/authselect check
Executing: /usr/bin/authselect select sssd with-mkhomedir --force
Executing: /usr/bin/systemctl enable sssd.service
Executing: /usr/bin/systemctl stop sssd.service
Executing: /usr/bin/systemctl start sssd.service
Executing: /usr/bin/systemctl enable oddjobd.service

Executing: /usr/bin/systemctl stop oddjobd.service
Executing: /usr/bin/systemctl start oddjobd.service

Dobra, teraz upewnijmy się, że /etc/sssd/sssd.conf wygląda mniej więcej tak (jeśli nie, warto to nieco skorygować):

[nss]
filter_groups = root
filter_users = root
reconnection_retries = 3

[pam]
reconnection_retries = 3

[sssd]
domains = serba.local
config_file_version = 2
services = nss, pam
default_domain_suffix = SERBA.LOCAL
full_name_format = %1$s

[domain/serba.local]
ad_domain = serba.local
krb5_realm = SERBA.LOCAL
realmd_tags = manages-system joined-with-samba
cache_credentials = True
id_provider = ad
krb5_store_password_if_offline = True
default_shell = /bin/bash
ldap_id_mapping = True
use_fully_qualified_names = True
fallback_homedir = /home/%d/%u
access_provider = ad

auth_provider = ad
chpass_provider = ad
access_provider = ad
ldap_schema = ad
dyndns_update = true
dyndns_refresh_interval = 43200
dyndns_update_ptr = true
dyndns_ttl = 3600

Jeśli zmienimy cokolwiek, restartujemy usługę (od razu sobie warto ustawić ją tak, by uruchamiała się wraz ze startem systemu):

# systemctl start sssd //w dokumentacji jest service sssd start
# systemctl enable sssd //w dokumentacji jest chkconfig sssd on

Po tym zrestartowałbym system. Na końcu musimy zdefiniować kto może faktycznie się logować do swoich kont administracyjnych:

sudo realm deny -a
sudo realm permit --groups 'serba.local\Administratorzy domeny'

Na końcu dodamy grupę Administratorzy domeny do /etc/sudoers za pomocą visudo:

#%SERBA\\administratorzy\ domeny        ALL=(ALL:ALL) ALL #nieadekwatny do przykładu
#%administratorzy\ domeny@serba.local   ALL=(ALL:ALL) ALL #nieadekwatny do przykładu
%administratorzy\ domeny        ALL=(ALL:ALL) ALL

Na dobrą sprawę to tyle. GDM (menedżer wyświetlania w RHEL 8) nie wymaga dodatkowych modyfikacji, by umożliwić użytkownikom z AD logowanie się na swoje konta w interfejsie graficznym. Wspominając o Fortigate – z pewnego powodu agent FSSO nie widzi logowań na hostach z Linuksem, więc jeśli ktoś by wiedział jak to rozwiązać – zostawcie komentarz.