Did you know you can centrally manage Linux systems and user accounts under an Active Directory domain?
For many businesses, Active Directory (AD) is the preferred (if not only) directory service.
If you and your team are in charge of a Linux and Windows hybrid environment, centralising authentication for both systems makes sense.
In this article, I’ll discuss how to include Linux devices in an Active Directory domain.
For many years, Microsoft Active Directory, also referred to as AD, has dominated the market for enterprise access control. It is used by organisations and people all over the world to centrally manage access to organisational resources. You can control who has access to what by managing users, passwords, and resources like computers. Some of you who are reading this article, especially those who work for large organisations, have already dealt with AD. Typically, the interaction involves logging in to all workstations inside the organisation using a single set of login credentials.
Each user in Active Directory is uniquely created as an object with a single set of credentials in a central database. Additionally, every computer system is created as an object. With the same set of credentials, every user has automatic access to every workstation. Any necessary account updates are made once at the centralised database. The same set of credentials can be used by staff members to access the printers. To do that, AD can be connected with the printers’ authentication system.
It is possible to customise and maintain access to different resources using groups and organisational units. This directory can be expanded to include more information in addition to the phone numbers and email addresses of the personnel.
AD is a kind of distributed database, which is accessed using Lightweight Directory Access Protocol (LDAP).
What happens, though, if your organisation leverages AD and you have a few Red Hat systems but do not want to keep track of a distinct set of login credentials for your Linux users? As it turns out – you can join the Red Hat systems to AD using sssd.
The System Security Services Daemon (SSSD) is a system service facilitating access to remote directories and authentication mechanisms.
An SSSD client, on a local system, can be connected to an identity provider.
For instance:
- LDAP directories
- Identity Management (IdM) domain
- Active Directory (AD)
- Kerberos Realm
Prerequisites
- An account in multiple AD Directories with privileges necessary to join a system to the domain
- A Linux server (Red Hat 8 is used in this example)
- Three Domain Controllers
- DNS configuration
In this example we will use the following:
- AD Domains:
- example01.net
- example02.net
- example03.net
- User account to join the domain:
- example_admin
Package Installation
The following packages need to be installed:
# dnf install sssd realmd oddjob oddjob-mkhomedir adcli krb5-workstation samba-common-tools
To ensure that the server can correctly communicate with Active Directory, use the following command:
# update-crypto-policies --set DEFAULT:AD-SUPPORT
Ensure that you can resolve the AD domain controllers using dig:
[root@utility ~]# dig srv _kerberos-master._udp.example01.net
; <<>> DiG 9.11.36-RedHat-9.11.36-3.el8_6.1 <<>> srv _kerberos-master._udp.example01.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 9762
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4000
;; QUESTION SECTION:
;_kerberos-master._udp.example01.net. IN SRV
;; AUTHORITY SECTION:
example01.net. 3600 IN SOA lmigadc01.example01.net. hostmaster.example01.net. 7082 900 600 86400 3600
;; Query time: 1 msec
;; SERVER: 172.16.34.10#53(172.16.34.10)
;; WHEN: Wed Dec 14 13:49:17 AEDT 2022
;; MSG SIZE rcvd: 150
------------------------------------------
[root@utility ~]# dig srv _kerberos-master._udp.example02.net
; <<>> DiG 9.11.36-RedHat-9.11.36-3.el8_6.1 <<>> srv _kerberos-master._udp.example02.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 9762
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4000
;; QUESTION SECTION:
;_kerberos-master._udp.example02.net. IN SRV
;; AUTHORITY SECTION:
example02.net. 3600 IN SOA lmigadc01.example02.net. hostmaster.example02.net. 7082 900 600 86400 3600
;; Query time: 1 msec
;; SERVER: 172.16.34.10#53(172.16.34.10)
;; WHEN: Wed Dec 14 13:49:17 AEDT 2022
;; MSG SIZE rcvd: 150
---------------
[root@utility ~]# dig srv _kerberos-master._udp.example03.net
; <<>> DiG 9.11.36-RedHat-9.11.36-3.el8_6.1 <<>> srv _kerberos-master._udp.example03.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 9762
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4000
;; QUESTION SECTION:
;_kerberos-master._udp.example03.net. IN SRV
;; AUTHORITY SECTION:
example03.net. 3600 IN SOA lmigadc01.example03.net. hostmaster.example03.net. 7082 900 600 86400 3600
;; Query time: 1 msec
;; SERVER: 172.16.34.10#53(172.16.34.10)
;; WHEN: Wed Dec 14 13:49:17 AEDT 2022
;; MSG SIZE rcvd: 150
- Join the first domain from the first forest.
# realm join EXAMPLE01.NET
- Add a second domain from a different forest to the [domain_realm] section of /etc/krb5.conf
domain_realm]
.example01.net = EXAMPLE01.NET
example01.net = EXAMPLE01.NET
.example02.net = EXAMPLE02.NET
example02.net = EXAMPLE02.NET
.example03.net = EXAMPLE03.NET
example03.net = EXAMPLE03.NET
- Join the second domain using adcli command.
# adcli join -–host-keytab=/etc/krb5.keytab.example02.net example02.net
- Define the second domain section which was joined using adcli into a new domain section in /etc/sssd/sssd.conf configuration file.
[sssd]
domains = example01.net,example02.net
config_file_version = 2
services = nss, pam, pac, ssh
[domain/example01.net]
ad_domain = example01.net
ad_server = lmigadc01.example01.net
krb5_realm = example01.net
realmd_tags = manages-system joined-with-adcli
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/%u@%d
access_provider = ad
dyndns_update = true
[domain/example02.net]
ad_domain = example02.net
ad_server = lcolad01.example02.net
krb5_realm = example02.net
realmd_tags = manages-system joined-with-adcli
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/%u@%d
access_provider = ad
krb5_keytab = /etc/krb5.keytab.example02.net
ldap_krb5_keytab = /etc/krb5.keytab.example02.net
dyndns_update = true
- Restart sssd using the following command
# systemctl restart sssd
- Join the third domain using adcli command
# adcli join -–host-keytab=/etc/krb5.keytab.example03.net example03.net
- Define the third domain section which was joined using adcli into a new domain section in /etc/sssd/sssd.conf configuration file. The following configuration file presents all three domains.
[sssd]
domains = example01.net,example02.net,example03.net
config_file_version = 2
services = nss, pam, pac, ssh
[domain/example01.net]
ad_domain = example01.net
ad_server = lmigadc01.example01.net
krb5_realm = example01.net
realmd_tags = manages-system joined-with-adcli
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/%u@%d
access_provider = ad
dyndns_update = true
[domain/example02.net]
ad_domain = example02.net
ad_server = lcolad01.example02.net
krb5_realm = example02.net
realmd_tags = manages-system joined-with-adcli
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/%u@%d
access_provider = ad
krb5_keytab = /etc/krb5.keytab.example02.net
ldap_krb5_keytab = /etc/krb5.keytab.example02.net
dyndns_update = true
[domain/example03.net]
ad_domain = example03.net
ad_server = lavailad02.example03.net
krb5_realm = example03.net
realmd_tags = manages-system joined-with-adcli
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/%u@%d
access_provider = ad
krb5_keytab = /etc/krb5.keytab.example03.net
ldap_krb5_keytab = /etc/krb5.keytab.example03.net
dyndns_update = true
- Restart sssd using the following command.
# systemctl restart sssd
Note: the ad_server option defines the Domain Controller for the given domain. This option is useful to avoid DNS SRV record lookups and if the Linux server can only resolve DNS names from one of the forest domains. If this is your case – add the Domain Controllers’ names to /etc/hosts as well.
172.16.32.10 lcolad01.example02.net lcolad01
172.16.34.10 lmigadc01.example01.net lmigadc01
172.16.36.10 lavailad02.example03.net lavailad02
Testing
- For each domain, execute the following commands.
# id example_admin@example01.net
[root@utility ~]# id example_admin@example01.net
uid=794602228(example_admin@example01.net) gid=794400513(domain users@example01.net) groups=794600513(domain users@example01.net),794600512(domain admins@example01.net)
# id example_admin@example03.net
[root@utility ~]# id example_admin@example03.net
uid=44201110(example_admin@example03.net) gid=44201177(linux_admins@example03.net) groups=44201177(linux_admins@example03.net),44200513(domain users@example03.net),44201605(idm@example03.net)
# id example_admin@example02.net
[root@utility ~]# id example_admin@example02.net
uid=81601158(example_admin@example02.net) gid=81600513(domain users@example02.net) groups=81600513(domain users@example02.net),81600512(domain admins@example02.net)
- Attempt to login to the server using ssh.
root@test ~]# ssh example_admin@example03.net@utility
example_admin@example03.net@utility's password:
Last login: Wed Dec 14 10:44:59 2022 from 10.221.8.5
[example_admin@example03.net@utility ~]$
- Attempt to login to the server using ssh and verify if the KDC grants the Kerberos ticket.
[root@test ~]# ssh example_admin@example01.net@utility
example_admin@example01.net@utility's password:
Last login: Wed Dec 14 10:44:23 2022 from 10.221.8.5
[example_admin@example01.net@utility ~]$ kinit
Password for example_admin@EXAMPLE01.NET:
[example_admin@example01.net@utility ~]$ klist
Ticket cache: KCM:794602128:6396
Default principal: example_admin@EXAMPLE01.NET
Valid starting Expires Service principal
14/12/22 14:19:24 15/12/22 00:19:24 krbtgt/EXAMPLE01.NET@EXAMPLE01.NET
Learn how to simplify the way your team manages both Linux and Windows systems, centrally manage your Linux systems and user accounts, contact us to learn more.