Configure SSH access using Samba Active Directory.

Preparations

Ensure that a Fully Qualified Domain Name is defined.

$ sudo hostnamectl --static set-hostname voyager.octocat.lab

Read how to configure persistent DNS resolver to ensure that server is using DNS resolver provided by Samba Active Directory services.

$ cat /etc/resolv.conf 
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
# 127.0.0.53 is the systemd-resolved stub resolver.
# run "resolvectl status" to see details about the actual nameservers.

nameserver 10.10.10.10
search octocat.lab

Configure NTP client

Configure systemd timesyncd service.

$ cat  /etc/systemd/timesyncd.conf 
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.
#
# Entries in this file show the compile time defaults.
# You can change settings by editing this file.
# Defaults can be restored by simply deleting this file.
#
# See timesyncd.conf(5) for details.

[Time]
NTP=10.10.10.10
FallbackNTP=10.10.0.1
#RootDistanceMaxSec=5
#PollIntervalMinSec=32
#PollIntervalMaxSec=2048

Ensure that the NTP client is enabled.

$ sudo timedatectl set-ntp on

Restart service to update configuration.

$ systemctl restart systemd-timesyncd.service 

Ensure that it will start at system boot.

$ sudo systemctl enable systemd-timesyncd.service

Inspect current time.

$ timedatectl
Local time: Thu 2021-09-30 21:16:43 CEST
           Universal time: Thu 2021-09-30 19:16:43 UTC
                 RTC time: Thu 2021-09-30 19:16:44
                Time zone: Europe/Warsaw (CEST, +0200)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
$ timedatectl show-timesync 
SystemNTPServers=10.10.10.10
FallbackNTPServers=0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org 3.debian.pool.ntp.org
ServerName=10.10.10.10
ServerAddress=10.10.10.10
RootDistanceMaxUSec=5s
PollIntervalMinUSec=32s
PollIntervalMaxUSec=34min 8s
PollIntervalUSec=1min 4s
NTPMessage={ Leap=0, Version=4, Mode=4, Stratum=3, Precision=-21, RootDelay=15.594ms, RootDispersion=10.375ms, Reference=9FFDF27B, OriginateTimestamp=Thu 2021-09-30 21:26:23 CEST, ReceiveTimestamp=Thu 2021-09-30 21:26:23 CEST, TransmitTimestamp=Thu 2021-09-30 21:26:23 CEST, DestinationTimestamp=Thu 2021-09-30 21:26:23 CEST, Ignored=no PacketCount=1, Jitter=0 }
Frequency=-427764

System configuration

Install required packages.

$ sudo DEBIAN_FRONTEND=noninteractive apt install sssd sssd-tools realmd samba-common krb5-user sssd-tools oddjob oddjob-mkhomedir packagekit
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  cracklib-runtime dirmngr gnupg gnupg-l10n gnupg-utils gpg gpg-agent gpg-wks-client gpg-wks-server gpgconf gpgsm krb5-config ldap-utils
  libappstream4 libassuan0 libavahi-client3 libavahi-common-data libavahi-common3 libbasicobjects0 libc-ares2 libcollection4 libcrack2 libcups2
  libdhash1 libdw1 libglib2.0-0 libglib2.0-bin libglib2.0-data libgpgme11 libgssrpc4 libgstreamer1.0-0 libini-config5 libipa-hbac0
  libkadm5clnt-mit12 libkadm5srv-mit12 libkdb5-10 libksba8 libldb2 libnfsidmap2 libnl-3-200 libnl-route-3-200 libnpth0 libnss-sss
  libpackagekit-glib2-18 libpam-pwquality libpam-sss libpath-utils1 libpolkit-agent-1-0 libpolkit-gobject-1-0 libpwquality-common libpwquality1
  libpython3.9 libref-array1 libsasl2-modules-gssapi-mit libsmbclient libsss-certmap0 libsss-idmap0 libsss-nss-idmap0 libstemmer0d libtalloc2
  libtdb1 libtevent0 libunwind8 libwbclient0 libyaml-0-2 packagekit-tools pinentry-curses policykit-1 python3-gpg python3-ldb python3-samba
  python3-sss python3-talloc python3-tdb samba-common-bin samba-dsdb-modules samba-libs shared-mime-info sssd-ad sssd-ad-common sssd-common
  sssd-dbus sssd-ipa sssd-krb5 sssd-krb5-common sssd-ldap sssd-proxy xdg-user-dirs
Suggested packages:
  dbus-user-session pinentry-gnome3 tor parcimonie xloadimage scdaemon krb5-k5tls cups-common krb5-doc gstreamer1.0-tools appstream
  pinentry-doc heimdal-clients python3-markdown python3-dnspython adcli libsss-sudo libsasl2-modules-ldap
The following NEW packages will be installed:
  cracklib-runtime dirmngr gnupg gnupg-l10n gnupg-utils gpg gpg-agent gpg-wks-client gpg-wks-server gpgconf gpgsm krb5-config krb5-user
  ldap-utils libappstream4 libassuan0 libavahi-client3 libavahi-common-data libavahi-common3 libbasicobjects0 libc-ares2 libcollection4
  libcrack2 libcups2 libdhash1 libdw1 libglib2.0-0 libglib2.0-bin libglib2.0-data libgpgme11 libgssrpc4 libgstreamer1.0-0 libini-config5
  libipa-hbac0 libkadm5clnt-mit12 libkadm5srv-mit12 libkdb5-10 libksba8 libldb2 libnfsidmap2 libnl-3-200 libnl-route-3-200 libnpth0 libnss-sss
  libpackagekit-glib2-18 libpam-pwquality libpam-sss libpath-utils1 libpolkit-agent-1-0 libpolkit-gobject-1-0 libpwquality-common libpwquality1
  libpython3.9 libref-array1 libsasl2-modules-gssapi-mit libsmbclient libsss-certmap0 libsss-idmap0 libsss-nss-idmap0 libstemmer0d libtalloc2
  libtdb1 libtevent0 libunwind8 libwbclient0 libyaml-0-2 oddjob oddjob-mkhomedir packagekit packagekit-tools pinentry-curses policykit-1
  python3-gpg python3-ldb python3-samba python3-sss python3-talloc python3-tdb realmd samba-common samba-common-bin samba-dsdb-modules
  samba-libs shared-mime-info sssd sssd-ad sssd-ad-common sssd-common sssd-dbus sssd-ipa sssd-krb5 sssd-krb5-common sssd-ldap sssd-proxy
  sssd-tools xdg-user-dirs
0 upgraded, 96 newly installed, 0 to remove and 0 not upgraded.
Need to get 32.5 MB of archives.
After this operation, 124 MB of additional disk space will be used.
[...]

Enable mkhomedir PAM configuration profile.

$ sudo pam-auth-update --enable mkhomedir

Create Kerberos configuration.

$ cat << EOF | tee /etc/krb5.conf
[libdefaults]
        default_realm = OCTOCAT.LAB
        dns_lookup_realm = false
        dns_lookup_kdc = true
        
        forwardable = true
        
        default_ccache_name = KEYRING:persistent:%{uid}

[realms]
OCTOCAT.LAB = {
        default_domain = octocat.lab
}

[domain_realm]
        octocat.lab = OCTOCAT.LAB
        .octocat.lab = OCTOCAT.LAB 
EOF

Discover realm octocat.lab.

$ realm discover octocat.lab
octocat.lab
  type: kerberos
  realm-name: OCTOCAT.LAB
  domain-name: octocat.lab
  configured: no
  server-software: active-directory
  client-software: sssd
  required-package: sssd-tools
  required-package: sssd
  required-package: libnss-sss
  required-package: libpam-sss
  required-package: adcli
  required-package: samba-common-bin

Join the Samba Active Directory domain.

$ sudo realm  join octocat.lab -U Administrator --client-software=sssd --membership-software=samba 
Password for Administrator:  *************

List discovered and configured realms.

$ realm list
octocat.lab
  type: kerberos
  realm-name: OCTOCAT.LAB
  domain-name: octocat.lab
  configured: kerberos-member
  server-software: active-directory
  client-software: sssd
  required-package: sssd-tools
  required-package: sssd
  required-package: libnss-sss
  required-package: libpam-sss
  required-package: adcli
  required-package: samba-common-bin
  login-formats: %U@octocat.lab
  login-policy: allow-realm-logins

Display configuration generated for the System Security Services Daemon.

$ cat /etc/sssd/sssd.conf 
[sssd]
domains = octocat.lab
config_file_version = 2
services = nss, pam

[domain/octocat.lab]
default_shell = /bin/bash
krb5_store_password_if_offline = True
cache_credentials = True
krb5_realm = OCTOCAT.LAB
realmd_tags = manages-system joined-with-samba 
id_provider = ad
fallback_homedir = /home/%u@%d
ad_domain = octocat.lab
use_fully_qualified_names = True
ldap_id_mapping = True
access_provider = ad

Update configuration to set default domain suffix, ensure proper user and group id, allow login to the members of the cat group and disable GPO-based access control.

$ sudo cat /etc/sssd/sssd.conf 
[sssd]
domains = octocat.lab
config_file_version = 2
services = nss, pam

[domain/octocat.lab]
default_shell = /bin/bash
krb5_store_password_if_offline = True
cache_credentials = True
krb5_realm = OCTOCAT.LAB
realmd_tags = manages-system joined-with-samba 
id_provider = ad
fallback_homedir = /home/%u@%d
ad_domain = octocat.lab
ldap_id_mapping = False
access_provider = ad
ad_access_filter = memberOf=CN=cats,CN=Users,DC=octocat,DC=lab
ad_gpo_access_control = disabled

Check configuration.

$ sudo sssctl config-check
Issues identified by validators: 0

Messages generated during configuration merging: 0

Used configuration snippet files: 0

The most common issue is the permissions check.

File ownership and permissions check failed. Expected root:root and 0600.

Restart System Security Services Daemon.

$ sudo systemctl restart sssd

Check Active Directory user.

$ getent passwd octo
octo@octocat.lab:*:10000:10000:Octo Cat:/home/octocat:/bin/bash

Check Active Directory user.

$ id octocat

Get more details to determine that all data is recognized.

uid=10000(octo@octocat.lab) gid=10000(octocat@octocat.lab) groups=10000(octocat@octocat.lab),8000(cats@octocat.lab)

Update OpenSSH server configuration on a workstation.

$ cat /etc/ssh/sshd_config
[...]

# GSSAPI options
GSSAPIAuthentication yes
#GSSAPICleanupCredentials yes
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no

[...]

Update OpenSSH server configuration on an Active Directory server.

$ cat /etc/ssh/sshd_config
[...]

# GSSAPI options
GSSAPIAuthentication yes
#GSSAPICleanupCredentials yes
GSSAPIStrictAcceptorCheck no
#GSSAPIKeyExchange no

[...]

Restart the OpenSSH server.

$ sudo systemctl restart sshd

Update SSH client configuration.

$ cat /etc/ssh/ssh_config
# This is the ssh client system-wide configuration file.  See
# ssh_config(5) for more information.  This file provides defaults for
# users, and the values can be changed in per-user configuration files
# or on the command line.

# Configuration data is parsed as follows:
#  1. command line options
#  2. user-specific file
#  3. system-wide file
# Any configuration value is only changed the first time it is set.
# Thus, host-specific definitions should be at the beginning of the
# configuration file, and defaults at the end.

# Site-wide defaults for some commonly used options.  For a comprehensive
# list of available options, their meanings and defaults, please see the
# ssh_config(5) man page.

Include /etc/ssh/ssh_config.d/*.conf

Host *
#   ForwardAgent no
#   ForwardX11 no
#   ForwardX11Trusted yes
#   PasswordAuthentication yes
#   HostbasedAuthentication no
    GSSAPIAuthentication yes
    GSSAPIDelegateCredentials yes
#   GSSAPIKeyExchange no
#   GSSAPITrustDNS no
#   BatchMode no
#   CheckHostIP yes
#   AddressFamily any
#   ConnectTimeout 0
#   StrictHostKeyChecking ask
#   IdentityFile ~/.ssh/id_rsa
#   IdentityFile ~/.ssh/id_dsa
#   IdentityFile ~/.ssh/id_ecdsa
#   IdentityFile ~/.ssh/id_ed25519
#   Port 22
#   Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc
#   MACs hmac-md5,hmac-sha1,umac-64@openssh.com
#   EscapeChar ~
#   Tunnel no
#   TunnelDevice any:any
#   PermitLocalCommand no
#   VisualHostKey no
#   ProxyCommand ssh -q -W %h:%p gateway.example.com
#   RekeyLimit 1G 1h
#   UserKnownHostsFile ~/.ssh/known_hosts.d/%k
    SendEnv LANG LC_*
    HashKnownHosts yes

Additional notes

Do not set default_domain_suffix = octocat.lab in sssd section as it will interfere with SSH username when initiating connection.