How to connect securely (LDAPs) your Linux server to windows Active Directory
Introduction
Your first question will be, "Why do we need to connect a Linux server to Microsoft Active Directory?"
As a DevOps, SRE, or IT personnel, you might face a situation where you need to connect your Linux servers that are part of a solution, project, or organization to a Microsoft Active Directory for the following reasons.
- Centralized Authentication: Users can log in using their AD credentials by joining a Linux machine to an AD domain. This streamlines user management and ensures consistent authentication across Windows and Linux systems.
- Access Control: AD integration allows administrators to apply AD-based access controls and group policies to Linux systems, ensuring security and compliance.
- Single Sign-On (SSO): Users can enjoy the benefits of single sign-on, meaning they only need to log in once to access both Windows and Linux resources, improving user experience and security.
- Resource Access: Linux systems can access resources hosted on Windows servers or share resources with Windows systems on the same domain more easily.
- Simplified User Management: User and group management can be centralized within the AD, making it easier to add, modify, or remove user accounts and permissions.
- Logging and Auditing: Integration with AD allows Linux systems to log authentication events, aiding in security monitoring and auditing.
- Policy Enforcement: Group policies can be enforced on Linux systems, ensuring compliance with organizational policies and security standards.
- Integration with Other Services: Linux systems on the AD domain can integrate with other services like DNS, NTP, and even file-sharing services to ensure consistent and secure operation within the network.
Overall, integrating Linux computers with an Active Directory domain can enhance security, streamline user management, and improve interoperability within a mixed Windows-Linux environment.
Blog objective
This blog provides a detailed guide on connecting a Linux server to a Microsoft Active Directory server via Secure LDAP (Port 636) and non-secure LDAP (port 389). The exercise includes creating an Active Directory public certificate using RootCA, joining the Linux server to the Microsoft Active Directory server, configuring SSSD, and conducting a real test scenario to demonstrate access and permissions using a domain user.
Additionally, a link to an Ansible playbook that automates the process — Details can be found under the “Ansible playbook — Join to domain” section.
Link To Git Repository: https://github.com/dzbeda/linux-server-join-to-windows-domain.git
While the blog outlines steps for establishing a connection via a non-secure LDAP connection, it strongly recommends, based on experience and customer requirements, utilizing a secure LDAP connection for environment safety.
Steps to run — High Level
- Create the required prerequisites and run verification.
- Add a Linux server to the domain using 2 methods, secure and non-secure.
- In the case of a secure method, an Active Directory public certificate should be created (refer to the linked blog for details).
- Configure krb5.conf
- Configure SSSD
- Run verification test.
Prerequisites and Ingredients
Below are all the prerequisites required to run this exercise:
Required prerequisites.
- Microsoft Active Directory (Domain) —
- In our exercise, the Active Directory server name named DC, the domain name named zbeda.local and the server IP is 10.100.102.200
- Enable DNS server role.
- Enable Active Directory Domain Services role.
- Enable Active Directory Certificate Services role.
2. Create a domain user & security group
- User: testuser1
- Group: ldap (Assign testuser1 to this group)
3. Linux server
- Based on CentOS 8 operating system
- The server is named linux-client and the server IP is 10.100.102.210
- Install the necessary packages using yum install command (sssd, krb5-workstation , krb5-libs , adcli , mkhomedir , openldap , openldap-clients)
Note: The same procedure is relevant for Ubuntu operating system as well. However, part of packages and configuration file name might be different.
4. Network connectivity
- Ensure connectivity between the Linux server and Active Directory.
- Verify the Linux server can resolve the Active Directory server name.
5. Clock synchronization
- Verify clock sync between the Active Directory server and the Linux server.
Note: in domain environment it is mandatory to sync all environment servers to the same NTP server, otherwise you will face different issue
Prerequisites verification
Before running the exercise, verify prerequisites:
- Verify DNS resolve configuration.
Verify that your Linux server is configured with the relevant nameserver (Active directory server IP) and domain.
In my setup, the configuration is done under /etc/resolv.conf file
2. Verify Hostname resolve & Connectivity to the Active directory server.
Verify that you can find the Active Directory server using hostname.
- Login to the Linux server
- Run: ping dc (This is the Active directory server name)
3. Verify connectivity to the Active Directory server via port 389.
Verify that the Linux server can connect to the Active Directory server via port 389 — This port is used for connecting the Linux server to the domain using Nonsecure LDAP connection.
4. Verify connectivity to the Active Directory server via port 636.
Verify that the Linux server can connect to the Active Directory server via port 636 — This port is used for connecting the Linux server to the domain using a secure LDAP connection.
5. Verify user and group in Active Directory
Verify that domain user testuser1 & security group ldap were created and that testuser1 is a member of ldap security group.
Add Linux server to the domain — Procedure for Non-Secure LDAP Connection
This section will explain how to connect the Linux server to the Active Directory server using a Non-secure LDAP connection via port 389.
These are the steps that need to be performed on the Linux server to connect the Linux server to the Active Directory
- Configure /etc/krb5.conf file.
- Add the Linux server to the domain using adcli command.
- Configure /etc/sssd/sssd.conf file.
- Run verification steps.
Update /etc/krb5.conf file
The /etc/krb5.conf file is used to configure the Kerberos authentication system on a Unix-like operating system. Below you can find the krb5.conf file based on my environment.
[libdefaults]
default_realm = ZBEDA.LOCAL
dns_lookup_kdc = false
dns_lookup_realm = false
ticket_lifetime = 86400
renew_lifetime = 604800
forwardable = true
default_tgs_enctypes = aes256-cts-hmac-sha1-96
default_tkt_enctypes = aes256-cts-hmac-sha1-96
permitted_enctypes = aes256-cts-hmac-sha1-96
udp_preference_limit = 1
kdc_timeout = 3000
[realms]
ZBEDA.LOCAL = {
kdc = dc.zbeda.local
admin_server = dc.zbeda.local
}
[domain_realm]
.dc.zbeda.local = ZBEDA.LOCAL
dc.zbeda.local = ZBEDA.LOCAL
Note: Replace zbeda.local with your domain name and dc.zbeda.local with your active directory FQDN name. Please make sure to keep the convention of upper and lower case
Connect the Linux server to the Active Directory server.
The connection is done using the adcli command.
Please note that at this stage, Connecting the server to the domain using adcli will not let you perform LDAP queries or login with Active Directory users on the Linux server.
Command structure: adcli join -S <Active Directory server name> -D <Domain name> -U <Domain user> -O <DN organization Unit>
- Domain user — Make sure that you have a user with permission to add servers to the domain — The Active Directory administrator user can be used.
- In our exercise, I used the Active Directory login user which is the Administrator user
- When running the command, you should fill in the Administrator user password.
If no errors, the computer is added to the domain and can be found in the Active Directory User and Computer application under the defined organization unit.
Even though the Linux server was added to the Active Directory, if you try to search for a domain user you will fail since SSSD is not yet configured. In the below example using id command, I’m trying to fetch data on domain user testuser1 and I’m failing to do so because sssd is not yet configured
Configure SSSD
The System Security Services Daemon — SSSD, is a service commonly used for integration and management of user and authentication data, particularly in enterprise and identity management environments.
- Add the below configuration to your /etc/sssd/sssd.conf file.
Important — If the file is not located, create it and set the permission to 700.
[sssd]
config_file_version = 2
reconnection_retries = 3
sbus_timeout = 30
services = nss, pam
domains = zbeda.local
[nss]
reconnection_retries = 3
[pam]
reconnection_retries = 3
[domain/zbeda.local]
debug_level = 3
ad_enable_gc = false
cache_credentials = true
ldap_id_mapping = true
use_fully_qualified_names = false
full_name_format = %1$s
fallback_homedir = /home/%u
default_shell = /bin/bash
ignore_group_members = true
krb5_realm = ZBEDA.LOCAL
ad_domain = zbeda.local
id_provider = ad
chpass_provider = ad
auth_provider = ad
access_provider = ad
case_sensitive = false
enumerate = false
ldap_schema = ad
ldap_user_principal = nosuchattr
ldap_force_upper_case_realm = true
ldap_purge_cache_timeout = 0
ldap_account_expire_policy = ad
ldap_use_tokengroups = false
krb5_validate = false
Note : Replace zbeda.local with your domain name. Please make sure to keep the convention of upper and lower case
2. Restart the SSSD service by running systemctl restart sssd command. If the service fails to start, check the debuggability section for suggestions.
3. Enable the SSSD service to start on server startup by running the command systemctl enable sssd
4. If you wish to create a home dir for Active Directory users run the following command: authconfig --update --enablesssd --enablesssdauth --enablemkhomedir
Verification
- Run the id <domain user> command and verify that you can fetch the user data. The output contains to which group the user is assigned to the user uid and gid. in our example we will run id testuser1
2. Try to login to the server with testuser1.
3. Run whoami command
Add Linux server to the domain — Procedure for Secure LDAP Connection
This section will explain how to connect the Linux server to the Active Directory server using a secure LDAP connection via port 636.
These are the steps that need to be performed on the Linux server to connect the Linux server in a proper way to the Active Directory
- Generate RootCA public certificate.
- Configure /etc/krb5.conf file.
- Configure /etc/openldap/ldap.conf file.
- Upload the rootCA public certificate to the Linux server.
- Add the Linux clint to the domain using adcli command.
- Configure /etc/sssd/sssd.conf file.
- Run verification steps.
Generate RootCA public certificate.
Update /etc/krb5.conf file
The /etc/krb5.conf file is used to configure the Kerberos authentication system on a Unix-like operating system. Below you can find the krb5.conf file based on my environment.
[libdefaults]
default_realm = ZBEDA.LOCAL
dns_lookup_kdc = false
dns_lookup_realm = false
ticket_lifetime = 86400
renew_lifetime = 604800
forwardable = true
default_tgs_enctypes = aes256-cts-hmac-sha1-96
default_tkt_enctypes = aes256-cts-hmac-sha1-96
permitted_enctypes = aes256-cts-hmac-sha1-96
udp_preference_limit = 1
kdc_timeout = 3000
[realms]
ZBEDA.LOCAL = {
kdc = dc.zbeda.local
admin_server = dc.zbeda.local
}
[domain_realm]
.dc.zbeda.local = ZBEDA.LOCAL
dc.zbeda.local = ZBEDA.LOCAL
Note: Replace zbeda.local with your domain name and dc.zbeda.local with your active directory FQDN name. Please make sure to keep the convention of upper and lower case.
Update /etc/openldap/ldap.conf file
On November 2022 a security update was released to Active Directory that required adding the following line to the /etc/openldap/ldap.conf file.
Add the following line to /etc/openldap/ldap.conf file.
SASL_CBINDING tls-endpoint
Upload RootCA public certificate
Since we are trying to connect to Secure LDAP, the Linux server should trust the Active Directory server by uploading the RootCA public certificate to the box
- Generate RootCA public certificate. In our example file name is certnew.cer
- Copy the RootCA public certificate to /etc/pki/ca-trust/source/anchors/ folder in the Linux server
- Run the command update-ca-trust
Connect the Linux server to the Active Directory server.
The connection is done using the adcli command.
Please note that at this stage, Connecting the server to the domain using adcli will not let you perform LDAP queries or login with Active Directory users on the Linux server.
Command structure: adcli join - -use-ldaps -S <Active Directory server name> -D <Domain name> -U <Domain user> -O <DN organization Unit>
- Domain user — Make sure that you have a user with permission to add servers to the domain — The Active Directory administrator user can be used
- In our exercise, I used the Active Directory login user which is the Administrator user
- the use-ldap flag requires two dashes. For some reason, the text editor cannot manage it.
- In case of a failure, you can add -vvv to the command to see the log
If no errors, the computer is added to the domain and can be found in the Active Directory User and Computer application under the defined organization unit.
Even though the Linux server was added to the Active Directory, if you try to search for a domain user you will fail since SSSD is not yet configured. In the below example using id command I’m trying to fetch data on domain user testuser1 and I’m failing to do so because SSSD is not yet configured
Configure SSSD
The System Security Services Daemon — SSSD, is a service commonly used for integration and management of user and authentication data, particularly in enterprise and identity management environments.
- Add the below configuration to your /etc/sssd/sssd.conf file. The configuration is based on my environment.
Important — If the file is not located, create it and set the permission to 700.
[sssd]
config_file_version = 2
reconnection_retries = 3
sbus_timeout = 30
services = nss, pam
domains = zbeda.local
[nss]
reconnection_retries = 3
[pam]
reconnection_retries = 3
[domain/zbeda.local]
debug_level = 3
ad_enable_gc = false
cache_credentials = true
ldap_id_mapping = true
use_fully_qualified_names = false
full_name_format = %1$s
fallback_homedir = /home/%u
default_shell = /bin/bash
ignore_group_members = true
krb5_realm = ZBEDA.LOCAL
ad_domain = zbeda.local
id_provider = ad
chpass_provider = ad
auth_provider = ad
access_provider = ad
case_sensitive = false
enumerate = false
ldap_schema = ad
ldap_user_principal = nosuchattr
ldap_force_upper_case_realm = true
ldap_purge_cache_timeout = 0
ldap_account_expire_policy = ad
ldap_use_tokengroups = false
krb5_validate = false
##Secure LDAP support
ad_use_ldaps = True
Note : Replace zbeda.local with your domain name. Please make sure to keep the convention of upper and lower case
2. Restart the SSSD service by running systemctl restart sssd command. If the service fails to start, check the debuggability section for suggestions.
3. Enable the SSSDservice to start on server startup by running the command systemctl enable sssd
4. If you wish to create a home dir. for Active Directory users, run the following command : authconfig --update --enablesssd --enablesssdauth --enablemkhomedir
Verification
- Run the id <domain user> command and verify that you can fetch the user data. The output contains to which group the user is assigned to the user uid and gid. in our example we will run id testuser1
2. Try to login to the server with testuser1.
3. Run whoami command
Exercise Verification
In this verification test, I will demonstrate how only the domain user will have read and write permission to a specific folder. We will create a folder on the Linux server and give read and write permission to the ldap group that was created on the Active Directory. Reminder, the domain user testuser1 is assigned to this group
- Login to the Linux server and create a new folder named “test_folder” , set the owner to root (both user and group), and update the permission to 770 — this will set the access to the folder to owner and group only. Commands to run:
- mkdir -p /opt/test_folder
- chown roor:root /opt/test_folder
- chmod 770 /opt/test_folder
2. Switch to testuser1 and verify that the user doesn't have permission to list files under /opt/test_folder folder or to create a file under /opt/test_folder folder. Commands to run:
- su testuser1
- whoami
- ls /opt/test_folder
- touch /opt/test_folder/test.txt
3. Switch to root user and update the /opt/test_folder folder group owner to ldap. Commands to run:
Reminder, in active directory user testuser1 is assigned to the ldap security group.
- su root
- whoami
- chown roor:ldap /opt/test_folder
4. Switch to thestuser1 and verify that you have permission to list files under /opt/test_folder folder and create a file under /opt/test_folder folder. Commands to run
- su testuser1
- whoami
- ls /opt/test_folder
- touch /opt/test_folder/test.txt
If you liked this blog don’t forget to clap and follow me on both Medium and Linkedin
www.linkedin.com/in/davidzbeda
Join to domain — Ansible playbook.
In the section, you can find the instructions for running an ansible role that I have created for joining Centos\Redhat Linux server to the Active Directory.
Link To Git Repository: https://github.com/dzbeda/linux-server-join-to-windows-domain.git
To run the ansible playbook, flow these steps.
- Create a server that includes ansible service.
- Download the playbooks from my Git Repository: https://github.com/dzbeda/linux-server-join-to-windows-domain.git
- Update the “input-join-to-domain.yml” file with your environment configuration. Instruction can be found inside the file.
- Update the hosts file with your Linux server IP
- In case you want to use a secure connection, generate a public certificate and copy it to the server from where you are running the Ansible playbook. File name and path need to be defined in “input-join-to-domain.yml”
- To execute the playbook, run “ansible-playbook -i hosts run-join-to-domain.yml”
- Once executed, you will need to enter the password for the domain user that you have defined in the “input-join-to-domain.yml” file.
If you liked this blog don’t forget to clap and follow me on both Medium and Linkedin
www.linkedin.com/in/davidzbeda
Debuggability
In this section, I have listed a few commands and errors that can help you to debug the exercise in case of errors
NC command
Using the NC command, you can check if you can reach a destination port on the remote server.
Command structure: nc -zv <remote-server> <port>
adcli commands
adcli logs
adcli doesn't have logs, instead, you can run the adcli command with -vvv flag which will show you some logs that can explain the issues you are facing.
Adcli errors
- This error usually indicates that your Linux server clock is not synced with the Active Directory server
2. This error indicates that you have an issue with the RootCA public certificate. Either you didn't import the public certificate to the server or you might have an issue with the public certificate
SSSD Logs
SSSD logs can be found under /var/log/sssd folder.
In the folder you can find the different log, the main logs are:
- sssd.log ; This is the log created by the SSSD service. If you have an issue with the service, the answer can be found in this log.
- sssd_<domain-name>.log ; This log includes the connection with the domain. The SSSD service can be run but if the connection to the domain was not established you can find the details in this log.
If you liked this blog don’t forget to clap and follow me on both Medium and Linkedin