Payton Flint's Tech Blog
Menu
  • Home
  • Blog
  • Categories
  • Resources
  • About
  • Contact
Menu

Linux – Configure Debian to Authenticate w/ Active Directory

Posted on January 21, 2024 by paytonflint

A unique problem recently presented itself- how to allowing multiple users to access a Linux VM in a secure fashion. Generic user accounts seemed like a poor idea to me, as they would likely end up being mismanaged. And shared accounts are, of course, a terrible idea. So, what to do? Well, I am, of course, already maintaining Active Directory – could I just use that?

The answer is YES. I was able to configure a Debian Linux virtual machine to authenticate against Active Directory. This helps maintain a healthy security posture without incurring additional administrative load. Also, to assist with securing this box, since many users would be using it, I modified the SSH config file /etc/ssh/sshd_config to contain ‘PermitRootLogin no’. This keeps anyone from being able to authenticate as the root user via SSH. However, this can potentially be bypassed by using the SU command. To counteract this, one can modify the file /etc/pam.d/su to contain ‘auth required pam_wheel.so’ this forces users to be a member of the wheel group before they can use SU.

To configure AD authentication, I used a page from the Debian wiki – https://wiki.debian.org/AuthenticatingLinuxWithActiveDirectorySssd. I found some small flaws with the documentation, so I am going to borrow very heavily from it, while making some small adjustments. But, it should be noted that I did not pioneer this method.

Firstly, the host should be named using an FQDN corresponding with the domain you will be joining. The wiki documentation states that you should configure DNS to resolve against the Domain Controller. However, I did not do this. You should make the determination if this makes sense for your use case.

Secondly, you need to synchronize time with your primary domain controller. This is because Kerberos requires time to be in sync. Install NTP and configure your primary DC as your NTP server.

apt-get install ntp
nano /etc/ntp.conf

# remove default NTP pool servers, such as
# 0.debian.pool.ntp.org, and replace w/ your DC or DNS server
# example: server dc01.ad.example.com

NSCD duplicates some of the functionality of sssd, and must be disabled:

systemctl stop unscd
systemctl disable unscd
rm /var/run/nscd/socket

Kerberos is a network authentication protocol designed to provide strong authentication for client/server applications by using secret-key cryptography. It was developed as part of Project Athena at MIT in the 1980s. In Active Directory, Kerberos is used for providing mutual authentication between users and services. It is a critical component for this process to function. Install Kerberos and edit its config file accordingly. Remember that this is case-sensitive.

[libdefaults]
    # This relation identifies the default realm to be used in a client host's
    # Kerberos activity.
    default_realm = AD.EXAMPLE.COM

    # Indicate whether DNS TXT records should be used to determine the Kerberos
    # realm of a host. The default is not to use these records.
    dns_lookup_realm = false

    # Indicate whether DNS SRV records should be used to locate the KDCs
    # and other servers for a realm, if they are not listed in the information
    # for the realm. The default is to use these records.
    # We set this explicitly since we're setting the admin_server anyway.
    dns_lookup_kdc = false

    # The value of this tag is the default lifetime for initial tickets. The
    # default value for the tag is 1 day (1d).
    #ticket_lifetime = 24h

    # The value of this tag is the default renewable lifetime for initial
    # tickets. The default value for the tag is 0.
    renew_lifetime = 7d

    # If this flag is set, initial tickets by default will be forwardable.
    # The default value for this flag is false.
    # See https://web.mit.edu/kerberos/krb5-devel/doc/user/tkt_mgmt.html for details.
    #forwardable = true

    # If this flag is true, reverse name lookup will be used in addition to
    # forward name lookup to canonicalizing hostnames for use in service principal names.
    # If dns_canonicalize_hostname is set to false, this flag has no effect.
    # The default value is true.
    rdns = false

[realms]
    AD.EXAMPLE.COM = {
        # This relation identifies the host where the administration server
        # is running. Typically this is the Master Kerberos server.
        # Required setting - cannot be looked up via DNS.
        admin_server = DC01.AD.EXAMPLE.COM

        # The name or address of a host running a KDC for that realm.
        # This could be looked up via DNS (dns_lookup_kdc) but we must
        # set the admin_server anyway, and this has the same value.
        kdc = DC01.AD.EXAMPLE.COM
    }

[domain_realm]
    # The [domain_realm] section provides a translation from a hostname to
    # the Kerberos realm name for the services provided by that host.
    #
    # The tag name can be a hostname, or a domain name, where domain names
    # are indicated by a prefix of a period ('.') character. The value of
    # the relation is the Kerberos realm name for that particular host or
    # domain. Host names and domain names should be in lower case.
    #
    # If no translation entry applies, the host's realm is considered to
    # be the hostname's domain portion converted to upper case.
    .ad.example.com = AD.EXAMPLE.COM

[logging]
    # Log everything to syslog. Default is severity of ERR and facility of AUTH.
    default = SYSLOG

Install Samba SMBD, stopping unused daemons. Then, configure its config file accordingly.

apt-get install samba samba-common
systemctl stop nmbd
systemctl disable nmbd
systemctl disable samba
systemctl disable samba-ad-dc

nano /etc/samba/smb.conf

# Configures Samba suite for AD
# These parameters seem to work on the devtest domain.

[global]
# Netbios name for the AD domain in upper-case
workgroup=ADEX

# This controls whether the client is allowed or required to use SMB
# signing. Possible values are auto, mandatory and disabled.
#
# When set to auto, SMB signing is offered, but not enforced. When
# set to mandatory, SMB signing is required and if set to disabled,
# SMB signing is not offered either.
#
# Default: client signing = auto
client signing = auto

# This variable controls whether Samba clients will try to use Simple
# and Protected NEGOciation (as specified by rfc2478) with supporting
# servers (including WindowsXP, Windows2000 and Samba 3.0) to agree
# upon an authentication mechanism. This enables Kerberos authentication
# in particular.
#
# Default: client use spnego = yes
client use spnego = yes

# This option specifies the kerberos realm to use. The realm is used as the
# ADS equivalent of the NT4 domain. It is usually set to the DNS name of the
# kerberos server. Since it is kerberos it is in capital letters.
realm=AD.EXAMPLE.COM

# In this mode, Samba will act as a domain member in an ADS realm. To operate
# in this mode, the machine running Samba will need to have Kerberos
# installed and configured and Samba will need to be joined to the ADS realm
# using the net utility.
security=ads

# Use the keytab to store secrets for authenticating against kerberos
# and to identify the kerberos server.
kerberos method = secrets and keytab

# Logging settings

# This option allows you to override the name of the Samba log file (also
# known as the debug file).
#
# This option takes the standard substitutions, allowing you to have separate
# log files for each user or machine.
#
# No default
#
# Example: log file = /usr/local/samba/var/log.%m
log file = /var/log/samba/smbd.log

# The value of the parameter (a astring) allows the debug level (logging
# level) to be specified in the smb.conf file.
# Values seem to be 0 to 10.
#
# Default: log level = 0
log level = 10

# This option (an integer in kilobytes) specifies the max size the log file
# should grow to. Samba periodically checks the size and if it is exceeded it
# will rename the file, adding a .old extension.
#
# A size of 0 means no limit.
#
# Default: max log size = 5000
max log size = 500

# Turn off printing to avoid log spam
load printers = no
printing = bsd
printcap name = /dev/null
disable spoolss = yes

# Default ID mapping configuration for local BUILTIN accounts
# and groups on a domain member. The default (*) domain:
# - must not overlap with any domain ID mapping configuration!
# - must use a read-write-enabled back end, such as tdb.
idmap config * : backend = tdb
idmap config * : range = 3000-7999

# - You must set a DOMAIN backend configuration
# idmap config for the SAMDOM domain
idmap config ADEX:backend = ad
idmap config ADEX:schema_mode = rfc2307
idmap config ADEX:range = 10000-50000
idmap config ADEX:unix_nss_info = yes

When you’re done, run testparm and investigate any errors. Then, restart smbd and enable it on startup.

testparm
systemctl restart smbd
systemctl enable smbd

Install SSSD, which allows you to access remote directories and authentication mechanisms. It won’t start correctly because its config file doesn’t currently exist, and it hasn’t been joined to the domain. I have modified the order of events slightly. First, create the config file /etc/sssd/sssd.conf.

apt-get install sssd

nano /etc/sssd/sssd.conf

# Configuration for the System Security Services Daemon (SSSD)
[sssd]

# Syntax of the config file; always 2
config_file_version = 2

# Services that are started when sssd starts
services = nss, pam

# List of domains in the order they will be queried
domains = AD.EXAMPLE.COM

# Configuration for the AD domain
[domain/AD.EXAMPLE.COM]

# Use the Active Directory Provider
id_provider = ad

# Use Active Directory for access control
access_provider = ad

# Turn off sudo support in sssd - we're doing it directly in /etc/sudoers.d/
# and leaving this enabled results in spurious emails being sent to root
sudo_provider = none

# UNIX and Windows use different mechanisms to identify groups and users.
# UNIX uses integers for both; the challenge is to generate these consistently
# across all machines from the objectSID.
#
# Active Directory provides an objectSID for every user and group object in
# the directory. This objectSID can be broken up into components that represent
# the Active Directory domain identity and the relative identifier (RID) of the
# user or group object.
#
# The SSSD ID-mapping algorithm takes a range of available UIDs and divides it into
# equally-sized component sections - called "slices"-. Each slice represents
# the space available to an Active Directory domain.
#
# The default configuration results in configuring 10,000 slices, each capable
# of holding up to 200,000 IDs, starting from 10,001 and going up to
# 2,000,100,000. This should be sufficient for most deployments.
ldap_id_mapping = true

# Define some defaults for accounts that are not already on this box.
# We appear to need these settings as well as the PAM configuration.
fallback_homedir = /home/%d/%u
default_shell = /bin/bash
skel_dir = /etc/skel

# When running in an unprivileged Linux container these settings
# should be uncommented.
#ldap_idmap_range_min = 10000
#ldap_idmap_range_max = 50000
#ldap_idmap_range_size = 1000

Then, modify the permissions of your config file. Then, modify /etc/nsswitch.conf and ensure the below are contained within.

chmod 0600 /etc/sssd/sssd.conf

passwd:        compat sss
group:         compat sss
netgroup:      nis sss
sudoers:       files

PAM provides a central place for managing authentication. Create the file /usr/share/pam-configs/my-ad and ensure it contains the following:

Name: Guestline AD user home management
Default: yes
Priority: 127

Session-Type: Additional
Session-Interactive-Only: yes
Session:
        required pam_mkhomedir.so skel=/etc/skel/ umask=0022

Update PAM to use this config file with the following:

/usr/sbin/pam-auth-update --package

For my use case, I did not want to grant any users sudo privileges, but that can be managed by creating the following file at /etc/sudoers.d/ad-linux-admins. This assumes there exists a Linux Admins security group in AD.

%Linux\ Admins ALL = (ALL) ALL

To join the domain, the Debian wiki provides a script. It must be executed with the SAMAccountName of a Domain Admin as an argument. Here is the script:

# Script to handle the process of joining the domain.
# Run with username where:
# username is the SAM name for the domain admins account - e.g. brownm for martin.brown
#
# The script produces lots of output to help with debugging any issues. See
# https://www.redhat.com/en/files/resources/en-rhel-intergrating-rhel-6-active-directory.pdf
# for a full description of the process (albeit RedHat rather than Debian).
#
# Note that it is very important that the hostname of the machine is set up correctly!

if [ "$#" != 1 ]
then
  echo "Usage: join-ad.sh username"
  exit 1
fi

username=$1
domain=$(hostname --domain)
echo "Using account ${username} to join domain ${domain}..."
echo ""

# Quit on error
set -e

# Uncomment to debug
#set -x

# Upper-case version of the domain name
upper_domain=$(echo ${domain} | tr [a-z] [A-Z])

# Find the short hostname and get an upper-case version of it
short_hostname=$(hostname --short)
upper_short_hostname=$(echo ${short_hostname} | tr [a-z] [A-Z])

# Log into the domain as the administrator, asking user for password
# The domain part must be in upper-case
echo "Logging into domain as the administrator"
/usr/bin/kinit "${username}@${upper_domain}"
echo ""

# List what kerberos sent back
echo "Listing kerberos tickets for the domain administrator:"
echo "------------------------------------------------------------------------"
klist
echo ""

# Join AD and put the machine credentials in the krb5.keytab
echo "Requesting domain join using administrator kerberos ticket"
net ads join -k

# List the machine credentials
echo "Listing kerberos tickets for the machine:"
echo "------------------------------------------------------------------------"
klist -k
echo ""

# Wait for 5s to allow everything to catch up - sometimes 5s isn't enough
echo "Waiting for everything to catch up..."
sleep 5
echo ""

# Sign in using the machine credentials
echo "Signing in using machine credentials ${upper_short_hostname}$"
kinit -k ${upper_short_hostname}$
echo ""

# Did it work?
joinedAd=$?

if [ $joinedAd -ne 0 ]
then
    echo "Error: could not join the domain with machine credentials ${upper_short_hostname}$"
    exit 1
else
    echo "Joined the domain using machine credentials ${upper_short_hostname}$"
    echo ""
    echo "Listing kerberos machine ticket:"
    echo "------------------------------------------------------------------------"
    klist
    echo ""

    # Now restart SSSD and everything should be happy :-)
    echo "Enabling and restarting sssd"
    systemctl enable sssd
    systemctl restart sssd
    if [ $? -ne 0 ]
    then
      echo "Error: could not start the System Security Services Daemon (SSSD)"
      exit 1
    else
      echo "System Security Services Daemon (SSSD) restarted and enabled."
      echo "AD should now be working!"
    fi
fi

exit 0

If you install applications using snap after this process, you will have a problem because the user home directory will (by default) be /home/AD.EXAMPLE.COM/<user>. To allow snap to locate users’ home directory correctly, make the following configuration change. Modify the file /etc/apparmor.d/tunables/home.d/ubuntu with the following, and be sure to include the trailing slash.

@{HOMEDIRS}+=/home/AD.EXAMPLE.COM/

Then, restart the following services:

systemctl restart apparmor.service snapd.apparmor.service snapd.service snapd.socket

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

About The Author

Author's Portrait

In my journey as a technologist and 11 years of experience as an IT professional, I have found my niche as Director of Infrastructure Services; developing my skillsets in management, scripting, cloud infrastructure, identity management, and networking.

I have experience as a Systems Administrator and Engineer for large enterprises including the DoD, government agencies, and a nuclear-generation site.

I've been blessed to collaborate with engineers at esteemed Fortune 50 corporations, and one of Africa's largest, to ensure successful implementation of my work.

GitHub Button

Credentials

M365 Endpoint Administrator Associate
M365 Fundamentals
Microsoft AZ-900
CompTIA CSIS
CompTIA CIOS
CompTIA Security+
CompTIA Network+
CompTIA A+
  • April 2025
  • December 2024
  • November 2024
  • October 2024
  • September 2024
  • August 2024
  • May 2024
  • April 2024
  • March 2024
  • February 2024
  • January 2024
  • December 2023
  • November 2023
  • October 2023
  • September 2023
  • August 2023
  • July 2023
  • June 2023
  • May 2023
  • April 2023
  • March 2023
  • February 2023
  • January 2023
  • December 2022
  • November 2022
  • October 2022
  • September 2022
  • August 2022
© 2022 Payton Flint | The views and opinions expressed on this website belong solely to the author/owner and do not represent the perspectives of any individuals, institutions, or organizations, whether affiliated personally or professionally, unless explicitly stated otherwise. The content and products on this website are provided as-is with no warranties or guaranties, are for informational/demonstrative purposes only, do not constitute professional advice, and are not to be used maliciously. The author/owner is not responsible for any consequences arising from actions taken based on information provided on this website, nor from the use/misuse of products from this site. All trademarks are the property of their respective owners.