How to connect securely (LDAPs) your Linux server to windows Active Directory

David (Dudu) Zbeda
14 min readDec 23, 2023

--

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.

  1. 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.
  2. Access Control: AD integration allows administrators to apply AD-based access controls and group policies to Linux systems, ensuring security and compliance.
  3. 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.
  4. Resource Access: Linux systems can access resources hosted on Windows servers or share resources with Windows systems on the same domain more easily.
  5. 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.
  6. Logging and Auditing: Integration with AD allows Linux systems to log authentication events, aiding in security monitoring and auditing.
  7. Policy Enforcement: Group policies can be enforced on Linux systems, ensuring compliance with organizational policies and security standards.
  8. 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

  1. Create the required prerequisites and run verification.
  2. Add a Linux server to the domain using 2 methods, secure and non-secure.
  3. In the case of a secure method, an Active Directory public certificate should be created (refer to the linked blog for details).
  4. Configure krb5.conf
  5. Configure SSSD
  6. Run verification test.

Prerequisites and Ingredients

Below are all the prerequisites required to run this exercise:

Required prerequisites.

  1. 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:

  1. 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

/etc/resolv.conf is set with nameserver (DNS) and search (Domain name)

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)
Ping test — Because search is defined with domain name so it will actually look for dc.zbeda.local

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.

Verify 389port is reachable on Active Directory server using NC command.

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.

Verify 636 port is reachable on Active Directory server using NC command.

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.

testuser1 user and ldap security group are part of zbeda.local domain
testuser1 user is 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.
adcli join command.

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.

Active Directory User and Computer — Linux server was added

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

Search for a domain user

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.

  1. 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

  1. 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
id command that fetches user data

2. Try to login to the server with testuser1.

Login with domain user

3. Run whoami command

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.

In the below link, you can find a HOW TO guide that describes in a very detailed steps how to configure RootCA on the Active Directory server and how to generate a 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

  1. Generate RootCA public certificate. In our example file name is certnew.cer
  2. Copy the RootCA public certificate to /etc/pki/ca-trust/source/anchors/ folder in the Linux server
  3. Run the command update-ca-trust
Upload RootCA public certificate

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
adcli join command with secure ldap flag

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.

Active Directory User and Computer — Linux server was added

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

Search for a domain user

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.

  1. 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

  1. 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
id command that fetches user data

2. Try to login to the server with testuser1.

Login with domain user

3. Run whoami command

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

  1. 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
Create folder and set owner and permission commands.

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
Switch user, list and create file command.

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
Create folder and set owner and permission commands.

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
Switch user, list and create file command.

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.

  1. Create a server that includes ansible service.
  2. Download the playbooks from my Git Repository: https://github.com/dzbeda/linux-server-join-to-windows-domain.git
  3. Update the “input-join-to-domain.yml” file with your environment configuration. Instruction can be found inside the file.
  4. Update the hosts file with your Linux server IP
  5. 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”
  6. 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

  1. This error usually indicates that your Linux server clock is not synced with the Active Directory server
adcli error because of clock sync

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

adcli error because of public certificate issue

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:

  1. 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.
  2. 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

www.linkedin.com/in/davidzbeda

--

--

David (Dudu) Zbeda
David (Dudu) Zbeda

Written by David (Dudu) Zbeda

DevOps | Infrastructure Architect | System Integration | Professional Services | Leading Teams & Training Future Experts | Linkedin: linkedin.com/in/davidzbeda

No responses yet