Active Directory Domain Join
Overview
This procedure joins a Linux workstation to the inside.domusdigitalis.dev Active Directory domain using manual configuration of Kerberos, Samba, and SSSD.
|
This is the enterprise-grade method. We do NOT use
|
|
Domain join is REQUIRED for enterprise deployments. AD membership provides:
See Deployment Models for comparison. |
Prerequisites
-
Network connectivity to domain controller (home-dc01.inside.domusdigitalis.dev / 10.50.1.50)
-
DNS resolution working for the domain
-
Domain Admin privileges (your evanusmodestus@inside.domusdigitalis.dev account)
-
Time synchronized with domain (NTP - Kerberos requirement)
-
Required packages already installed
Required Ports
|
Port 464 (kpasswd) is REQUIRED for domain join. This is often missed in firewall/dACL configurations. Field-tested at CHLA (2026-02-06): Domain join failed with "KDC reply did not match expectations" until port 464 was added to the dACL. |
| Port | Protocol | Purpose |
|---|---|---|
88 |
TCP/UDP |
Kerberos authentication |
389 |
TCP |
LDAP (directory queries) |
464 |
TCP |
kpasswd (password operations, REQUIRED for join) |
636 |
TCP |
LDAPS (secure LDAP) |
Architecture
After domain join:
-
Kerberos - Authentication protocol (MIT krb5)
-
Samba - SMB/CIFS and domain join functionality
-
SSSD - System Security Services Daemon (queries AD for users/groups)
-
NSS - Name Service Switch (integrates SSSD with system)
-
PAM - Pluggable Authentication Modules (AD user login)
Step 1: Install Required Packages
# Install from official repos only - NO AUR packages
sudo pacman -S sssd krb5 samba
realmd and adcli are AUR packages - we don’t use them for security reasons.
|
sudo dnf install -y sssd krb5-workstation samba-common-tools
sudo apt install -y sssd krb5-user samba-common-bin
Step 2: Configure Kerberos
Create /etc/krb5.conf with secure settings:
sudo tee /etc/krb5.conf > /dev/null << 'EOF'
[libdefaults]
default_realm = INSIDE.DOMUSDIGITALIS.DEV
dns_lookup_realm = false
dns_lookup_kdc = true
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
# AES encryption required - RC4 rejected by modern DCs
default_tgs_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96
default_tkt_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96
permitted_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96
[realms]
INSIDE.DOMUSDIGITALIS.DEV = {
kdc = dc-01.inside.domusdigitalis.dev
admin_server = dc-01.inside.domusdigitalis.dev
}
[domain_realm]
.inside.domusdigitalis.dev = INSIDE.DOMUSDIGITALIS.DEV
inside.domusdigitalis.dev = INSIDE.DOMUSDIGITALIS.DEV
EOF
Key Settings:
-
dns_lookup_realm = false- Explicitly defined realms (more secure) -
dns_lookup_kdc = true- Discover KDCs via DNS SRV records -
ticket_lifetime = 24h- Balance between security and convenience -
forwardable = true- Required for SSSD -
default_tgs_enctypes/default_tkt_enctypes/permitted_enctypes- AES encryption required
|
AES encryption types are critical. Modern domain controllers reject RC4 (type 23). Without explicit AES configuration, SSSD will fail with "KDC has no support for encryption type." Field-tested at CHLA (2026-02-06): Keytab regeneration with AES fixed SSSD authentication failures. |
Test Kerberos Authentication
# Authenticate with YOUR Domain Admin account
kinit evanusmodestus@INSIDE.DOMUSDIGITALIS.DEV
# Enter password when prompted
# Verify ticket
klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: evanusmodestus@INSIDE.DOMUSDIGITALIS.DEV
Valid starting Expires Service principal
01/27/2026 21:35:24 01/28/2026 07:35:24 krbtgt/INSIDE.DOMUSDIGITALIS.DEV@INSIDE.DOMUSDIGITALIS.DEV
renew until 02/03/2026 21:35:16
|
If
|
Step 3: Configure Samba
Create /etc/samba/smb.conf for AD integration:
sudo tee /etc/samba/smb.conf > /dev/null << 'EOF'
[global]
workgroup = INSIDE
realm = INSIDE.DOMUSDIGITALIS.DEV
security = ads
kerberos method = secrets and keytab
# Disable unnecessary services
disable netbios = yes
dns proxy = no
# Security hardening
client signing = mandatory
client schannel = yes
EOF
Security Settings:
-
security = ads- Active Directory security mode -
kerberos method = secrets and keytab- Use keytab for authentication -
client signing = mandatory- Enforce SMB signing -
client schannel = yes- Secure channel encryption
Step 4: Join the Domain
Use net ads join with YOUR Domain Admin credentials:
# Join using YOUR account (prompts for password - most secure)
sudo net ads join -U evanusmodestus@INSIDE.DOMUSDIGITALIS.DEV
# Enter password when prompted
Using short domain name -- INSIDE
Joined 'MODESTUS-RAZER' to dns domain 'inside.domusdigitalis.dev'
DNS Update for modestus-razer.inside.domusdigitalis.dev failed: ERROR_DNS_GSS_ERROR
DNS update failed: NT_STATUS_UNSUCCESSFUL
|
DNS errors are non-critical. The join succeeded when you see |
Verify Computer Account Created
On your workstation:
ssh home-dc01 'powershell -Command "Get-ADComputer -Filter {Name -eq \"modestus-razer\"} | Select-Object Name, DistinguishedName, Enabled"'
Name DistinguishedName Enabled
---- ----------------- -------
MODESTUS-RAZER CN=MODESTUS-RAZER,CN=Computers,DC=inside,DC=domusdigitalis,DC=dev True
Verify Keytab File
The domain join creates /etc/krb5.keytab with computer account credentials:
# Check keytab exists
ls -la /etc/krb5.keytab
# List keytab entries
sudo klist -kt /etc/krb5.keytab
Keytab name: FILE:/etc/krb5.keytab
KVNO Timestamp Principal
---- ------------------- ------------------------------------------------------
2 01/27/2026 21:37:14 MODESTUS-RAZER$@INSIDE.DOMUSDIGITALIS.DEV
2 01/27/2026 21:37:14 HOST/MODESTUS-RAZER@INSIDE.DOMUSDIGITALIS.DEV
2 01/27/2026 21:37:14 host/modestus-razer.inside.domusdigitalis.dev@INSIDE.DOMUSDIGITALIS.DEV
...
Step 5: Configure SSSD
SSSD queries Active Directory for user and group information.
|
Configuration file must have NO leading spaces! SSSD INI parser is strict - all directives must start at column 0. |
# Create SSSD configuration
sudo bash -c 'cat > /etc/sssd/sssd.conf << "EOF"
[sssd]
domains = inside.domusdigitalis.dev
config_file_version = 2
services = nss, pam
[domain/inside.domusdigitalis.dev]
ad_domain = inside.domusdigitalis.dev
krb5_realm = INSIDE.DOMUSDIGITALIS.DEV
id_provider = ad
auth_provider = ad
access_provider = ad
cache_credentials = false
krb5_store_password_if_offline = false
use_fully_qualified_names = false
fallback_homedir = /home/%u
default_shell = /bin/bash
EOF'
# Set strict permissions (required by SSSD)
sudo chmod 600 /etc/sssd/sssd.conf
Security Settings:
-
cache_credentials = false- Never cache passwords locally -
krb5_store_password_if_offline = false- No offline password storage -
use_fully_qualified_names = false- Allow short names (evanusmodestus vs evanusmodestus@inside.domusdigitalis.dev)
Convenience Settings:
-
fallback_homedir = /home/%u- Create home directory on first login -
default_shell = /bin/bash- Default shell for AD users
Start SSSD
# Enable and start SSSD
sudo systemctl enable --now sssd
# Check status
sudo systemctl status sssd
● sssd.service - System Security Services Daemon
Loaded: loaded (/usr/lib/systemd/system/sssd.service; enabled; preset: disabled)
Active: active (running) since Tue 2026-01-27 21:49:11 PST
Verify SSSD Domain Status
# List configured domains
sudo sssctl domain-list
# Check domain connectivity
sudo sssctl domain-status inside.domusdigitalis.dev
Online status: Online
Active servers:
AD Global Catalog: not connected
AD Domain Controller: home-dc01.inside.domusdigitalis.dev
Discovered AD Domain Controller servers:
- home-dc01.inside.domusdigitalis.dev
Step 6: Configure NSS (Name Service Switch)
NSS tells Linux where to look up users and groups. We need to add SSSD.
# Backup first
sudo cp /etc/nsswitch.conf /etc/nsswitch.conf.bak
# Add sss to passwd, group, and shadow lines
sudo sed -i 's/^passwd: files/passwd: files sss/' /etc/nsswitch.conf
sudo sed -i 's/^group: files/group: files sss/' /etc/nsswitch.conf
sudo sed -i 's/^shadow: files/shadow: files sss/' /etc/nsswitch.conf
# Verify
grep -E '^(passwd|group|shadow):' /etc/nsswitch.conf
passwd: files sss systemd
group: files sss [SUCCESS=merge] systemd
shadow: files sss systemd
Resolution order:
-
files- Check local/etc/passwd,/etc/group,/etc/shadow -
sss- Query SSSD (which queries AD) -
systemd- Systemd dynamic users
Step 7: Verify AD User Resolution
# Test with fully qualified name
id administrator@inside.domusdigitalis.dev
# Test with short name (requires use_fully_qualified_names = false)
id administrator
# Test YOUR account
id evanusmodestus
uid=1291000500(administrator) gid=1291000513(domain users) groups=1291000513(domain users),1291000512(domain admins),...
uid=1291001107(evanusmodestus) gid=1291000513(domain users) groups=1291000513(domain users),1291000512(domain admins),...
|
You should see AD groups! If you see If you only see local groups, check:
|
Step 8: Configure PAM (For AD User Login)
If you want AD users to log in locally via SSH or console:
# Check if pam_sss.so is already configured
grep pam_sss /etc/pam.d/system-auth
If not present, add it manually or use authselect (RHEL/Fedora) or pam-auth-update (Ubuntu).
Enable Automatic Home Directory Creation
|
AD users need home directories. Without this, SSH login fails with "cannot change directory to /home/user@DOMAIN: No such file or directory." Field-tested at CHLA (2026-02-06): First AD user login failed until mkhomedir was enabled. |
sudo pam-auth-update --enable mkhomedir
sudo authselect enable-feature with-mkhomedir
sudo systemctl restart oddjobd
echo "session required pam_mkhomedir.so skel=/etc/skel umask=0077" | sudo tee -a /etc/pam.d/common-session
Optional: Shorter Home Directory Paths
By default, home directories use FQDN format: /home/user@DOMAIN.COM
For shorter paths (/home/user), add to /etc/sssd/sssd.conf:
[domain/your.domain]
use_fully_qualified_names = False
fallback_homedir = /home/%u
Then restart SSSD: sudo systemctl restart sssd
|
For this deployment, we only need AD user/group resolution for ISE authorization. Local login for AD users is optional and not required for 802.1X. |
Step 9: Add Computer to AD Groups
Now that modestus-razer is domain-joined, add it to GRP-Linux-Admin-Workstations:
ssh home-dc01 'powershell -Command "Add-ADGroupMember -Identity \"GRP-Linux-Admin-Workstations\" -Members \"modestus-razer$\"; Get-ADGroupMember -Identity \"GRP-Linux-Admin-Workstations\" | Select-Object Name"'
|
Computer accounts require the Correct: |
Verification Commands
# Test domain membership
sudo net ads testjoin
# Show domain info
sudo net ads info
# List domain controllers
sudo net ads lookup
# Domain list
sudo sssctl domain-list
# Domain status
sudo sssctl domain-status inside.domusdigitalis.dev
# User cache
sudo sssctl user-show administrator
# Test user resolution
id administrator
id evanusmodestus
# Test group membership
groups administrator
# List keytab entries
sudo klist -kt /etc/krb5.keytab
# Test keytab authentication
sudo kinit -kt /etc/krb5.keytab 'MODESTUS-RAZER$@INSIDE.DOMUSDIGITALIS.DEV'
sudo klist
Troubleshooting
SSSD Won’t Start
Error: Can’t read config: 'Error while parsing configuration file'
Cause: Leading spaces in /etc/sssd/sssd.conf
Fix:
# Strip leading spaces
sudo sed -i 's/^ //' /etc/sssd/sssd.conf
# Verify NO spaces at start of lines
sudo cat /etc/sssd/sssd.conf | head -5
# Restart SSSD
sudo systemctl restart sssd
SSSD Online But Users Don’t Resolve
Symptom: sudo sssctl domain-status shows "Online" but id administrator returns "no such user"
Cause: NSS not configured to use SSSD
Fix:
# Check NSS configuration
grep sss /etc/nsswitch.conf
# Should show "sss" in passwd, group, shadow lines
# If not, add it:
sudo sed -i 's/^passwd: files/passwd: files sss/' /etc/nsswitch.conf
sudo sed -i 's/^group: files/group: files sss/' /etc/nsswitch.conf
sudo sed -i 's/^shadow: files/shadow: files sss/' /etc/nsswitch.conf
# Restart SSSD
sudo systemctl restart sssd
Kerberos Ticket Expired
Error: kinit fails with "Ticket expired"
Fix:
# Destroy old ticket
kdestroy
# Get new ticket
kinit evanusmodestus@INSIDE.DOMUSDIGITALIS.DEV
Time Sync Issues
Error: Clock skew too great during kinit
Cause: System time differs from DC by more than 5 minutes
Fix:
# Check time
timedatectl
# Sync with NTP
sudo timedatectl set-ntp true
# Or manually sync
sudo ntpdate dc-01.inside.domusdigitalis.dev
DNS Resolution Failures
Error: net ads join fails with "Failed to lookup DC info"
Fix:
# Test DNS resolution
dig inside.domusdigitalis.dev
dig _ldap._tcp.inside.domusdigitalis.dev SRV
dig _kerberos._tcp.inside.domusdigitalis.dev SRV
# Ping DC directly
ping dc-01.inside.domusdigitalis.dev
# Check /etc/resolv.conf
cat /etc/resolv.conf
Complete Verification Checklist
After domain join, verify ALL of these:
-
sudo net ads testjoinreturns "Join is OK" -
Computer account exists in AD:
Get-ADComputer modestus-razer -
Keytab file exists:
ls -la /etc/krb5.keytab -
SSSD is running:
sudo systemctl status sssd -
SSSD is online:
sudo sssctl domain-status inside.domusdigitalis.dev -
NSS configured:
grep sss /etc/nsswitch.conf -
AD users resolve:
id administrator -
AD groups visible:
groups administratorshows "domain admins" -
Computer in AD group:
Get-ADGroupMember GRP-Linux-Admin-Workstations
Security Hardening
To limit which AD users can log in:
# Add to /etc/sssd/sssd.conf under [domain/inside.domusdigitalis.dev]
ad_access_filter = memberOf=CN=Linux-Users,OU=Groups,DC=inside,DC=domusdigitalis,DC=dev
Already configured in our setup:
cache_credentials = false
krb5_store_password_if_offline = false
# Create sudoers file for Domain Admins
sudo visudo -f /etc/sudoers.d/domain-admins
# Domain Admins have full sudo access
%domain\ admins ALL=(ALL) ALL
Production Deployment Notes
For enterprise/research deployments:
-
Use YOUR Domain Admin account - Don’t create service accounts with static passwords
-
Document the computer OU - Move computers from default Computers container to proper OU
-
Test thoroughly - Verify all checks pass before deploying to production
-
Monitor SSSD logs - Watch
/var/log/sssd/*.logfor issues -
Plan certificate auto-enrollment - Configure GPO for automatic certificate issuance (future)