Skip to content

Configure debian server sshd auth with pam, sssd, kerberos

There is a complete tutorial on how to setup openldap, kerberos for unified authentication. You can visit this website.

In this tutorial, we show a scenario light compares to the architecture which shows in the above tutorial. We don't use the SASL/GSSAPI to delegate user password check to kerberos.

It means, in the below tutorial, user has a password in openldap, and a password in kerberos, which are not synchronized automatically. The user id does the link of user between openldap and kerberos.

Suppose we have a ldap and kerberos server running on 10.50.5.200 with url as krb.casd.local.

suppose we have three servers: - krb.casd.local: server hosts openldap and kerberos (can be replaced by AD/kerberos) - ssh-server.casd.local: server runs sshd server which uses pam, sssd, sssd-krb5 to check user authentication - ssh-client.casd.local: a vm runs an ssh client and krb5-client, user can get a kerberos ticket, and use this ticket to ssh into the ssh-server.casd.local

The full authentication process: 1. user get a kerberos ticket (kinit ) (in ssh-client.casd.local) 2. user init an ssh connection with the cached kerberos ticket(ssh uid@ssh-server.casd.local) (in ssh-client.casd.local) 3. ssh-server receives the ssh connection requests (sshd config checks all the possible authentication methods) (in ssh-server.casd.local) 4. sshd delegate the authentication to pam(UsePAM yes in sshd_config), pam delegate to sssd, sssd delegate to sssd-krb5. Because we set auth_provider as krb5 in sssd. (in ssh-server.casd.local) 5. sssd-krb5 sends a request to krb.casd.local to verify the authenticity of the kerberos ticket. This steps requires ssh-server.casd.local has a valid principal in krb.casd.local (in ssh-server.casd.local) 6. krb.casd.local verify the ticket and send the result back to ssh-server.casd.local. (in krb.casd.local) 7. sssd-krb5 in ssh-server.casd.local receives the result, if ok, it will ask the id_provider of the sssd, in our case it's openldap to get uid and gid of the user with the uid of the kerberos ticket. The user uid and gid information will be transfer to nss. sssd tells pam it's ok, pam tells sshd it's ok. Then pam will create a user session in the server after user login. (in ssh-server.casd.local) 8. user will get a terminal on ssh-server.casd.local with uid and gids from the openldap account.

1. Configure and test krb client on ssh-client.casd.local and ssh-server.casd.local

We need to install the kerberos client on both servers: - ssh-client.casd.local - ssh-server.casd.local

1.1 Install the required packages

# krb client package
sudo apt install krb5-user

1.2 Configure the krb client

sudo vim /etc/krb5.conf

# add the below content
[libdefaults]
    default_realm = CASD.LOCAL

# The following krb5.conf variables are only for MIT Kerberos.
    kdc_timesync = 1
    ccache_type = 4
    forwardable = true
    proxiable = true
        rdns = false


# The following libdefaults parameters are only for Heimdal Kerberos.
    fcc-mit-ticketflags = true

[realms]
    CASD.LOCAL = {
        kdc = krb.casd.local
        admin_server = krb.casd.local
    }


[domain_realm]
        casd.local = CASD.LOCAL
        .casd.local = CASD.LOCAL

1.3 Test the client

# generate a ticket, the principal must exist in the krb server
kinit pliu@CASD.LOCAL

# normally, you can view the ticket
klist

# clean the ticket
kdestory

2. Config sshd, pam, sssd on ssh-server.casd.local

2.1 Install required packages

sudo apt install sssd sssd-tools libnss-sss libpam-sss libpam-mkhomedir
  • sssd: package for daemon sssd((System Security Services Daemon))
  • sssd-tools: provides command-line utilities for managing and troubleshooting SSSD
  • nss: NSS (Name Service Switch) is a subsystem in Linux and Unix-like systems that allows applications to retrieve information about users, groups, hosts, networks, services, and more from various sources (like /etc/passwd, LDAP, NIS, or SSSD). By default, this daemon is running on a debian server, no need to install the package. The main config is in /etc/nsswitch.conf
  • libnss-sss: This daemon allows nss to retrieve user information from sssd
  • libpam-sss: This daemon allows pam to use sssd as an authentication mechanism.
  • libpam-mkhomedir: This daemon allows pam to create home dir for newly connected users.

2.2 Configure sshd to use pam as an authentication mechanism

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

#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
#HostKey /etc/ssh/ssh_host_ed25519_key

# Ciphers and keying
#RekeyLimit default none

# Logging
#SyslogFacility AUTH
#LogLevel INFO

# Authentication:

#LoginGraceTime 2m
#PermitRootLogin prohibit-password
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

#PubkeyAuthentication yes

# Expect .ssh/authorized_keys2 to be disregarded by default in future.
#AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2

#AuthorizedPrincipalsFile none

#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody

# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes

# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no

# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no
#AuthenticationMethods gssapi-with-mic,password

# Kerberos options
# KerberosAuthentication yes
# KerberosOrLocalPasswd yes
# KerberosTicketCleanup yes
# KerberosGetAFSToken yes
#UseDNS yes
# GSSAPI options
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes
GSSAPIStrictAcceptorCheck no
#GSSAPIKeyExchange no
AllowTcpForwarding yes
AllowAgentForwarding yes
GssapiKeyExchange yes
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication.  Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
UsePAM yes
UseDNS yes
#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
PrintMotd no
#PrintLastLog yes
#TCPKeepAlive yes
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS no
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none
PermitRootLogin yes
#PasswordAuthentication yes

# no default banner path
#Banner none

# Allow client to pass locale environment variables
AcceptEnv LANG LC_*

# override default of no subsystems
Subsystem   sftp    /usr/lib/openssh/sftp-server

# Example of overriding settings on a per-user basis
#Match User anoncvs
#   X11Forwarding no
#   AllowTcpForwarding no
#   PermitTTY no
#   ForceCommand cvs server

In the above conf, you can notice that I have two authentication methods: GSSAPI and PAM. Here GSSAPI is used to allow user to submit his ticket kerberos to sshd server. The sssd-krb5 can only support user login and password auth via kerberos.

2.3 configure pam to use sssd

pam has a list of configuration files(located in /etc/pam.d/): - common-auth: user authentication - common-account: User account management - common-password: Allow user to modify password. - common-session: user session settings

2.3.1 common-auth

The simplest config example :

auth      sufficient  pam_unix.so
auth      sufficient  pam_sss.so use_first_pass
auth      required    pam_deny.so
pam_unix.so: Uses local account to authenticate users pam_sss.so use_first_pass: Uses SSSD as first method to authenticate users. pam_deny.so: Denies access if all the above authentication method fails. pam_permit.so: Allows authentication if all previous steps succeed.

2.3.2 common-account

This controls how the user account can interact with the system. Below is a simple config example.

account   required    pam_unix.so
account   sufficient  pam_sss.so
account   required    pam_permit.so

don't add account requisite pam_deny.so in the config, otherwise you can no longer become root with sudoers right.

2.3.3 common-password:

Allow user to modify password.

password  sufficient  pam_unix.so nullok md5 shadow use_authtok
password  sufficient  pam_sss.so try_first_pass
password  required    pam_deny.so

This configuration is not enough for user to change password. You need to change sssd, ldap/kerberos config to allow users to change their passwords through sssd, Kerberos/LDAP.

2.3.4 common-session

session   required    pam_unix.so
session   optional    pam_sss.so
session   required    pam_mkhomedir.so skel=/etc/skel/ umask=0022
pam_mkhomedir.so: Create a home directory on first login if it doesn’t exist with umask=0022. pam_sss.so: Ensures SSSD session modules are applied.

2.4 Configure NSS

Ensure SSSD is used for user and group lookup.

The NSS (Name Service Switch) main config is located at /etc/nsswitch.conf:

The following config is a simple example tells Linux to check both local files (/etc/passwd) and SSSD for user information.

sudo vim /etc/nsswitch.conf

passwd:         files sss
group:          files sss
shadow:         files sss

2.5 Configure sssd

The sssd can query ldap/kerberos, AD/kerberos to check user authenticity(auth_provider), query ldap, or AD to get user id, groups, etc(id_provider).

sssd also allows user to change password of the backend(e.g. ldap, krb)

[sssd]
services = nss, pam, ssh
domains = casd.local
config_file_version = 2

[domain/casd.local]
id_provider = ldap
ldap_uri = ldap://krb.casd.local
ldap_search_base = dc=casd,dc=local

auth_provider = krb5
chpass_provider = krb5
krb5_realm = CASD.LOCAL
krb5_server = krb.casd.local
krb5_kpasswd = krb.casd.local
debug_level = 5
krb5_validate = true
krb5_ccachedir = /var/tmp # note that RHEL-7 default to KERNEL ccaches, which are preferred in most cases to FILE
krb5_keytab = /etc/krb5.keytab
cache_credentials = true

override_homedir = /home/%u
default_shell = /bin/bash


[nss]
homedir_substring = /home

[pam]

You need to restart the daemon sssd, after modifying the sssd.conf

sudo systemctl restart sssd

2.5.1 debug sssd by using sssd-tools

You need the admin right to run this command, otherwise you will get command not found error message. You can view the documentation of the tool with sudo sssctl.

Check the validity of the sssd config
sudo sssctl config-check

# output
Issues identified by validators: 0

Messages generated during configuration merging: 0

Used configuration snippet files: 0
list all available domain configured in sssd
sudo sssctl domain-list

# output example
casd.local
check the status of a domain
sudo sssctl domain-status casd.local

# output example
Online status: Online
Active servers:
KPASSWD: krb.casd.local
KERBEROS: krb.casd.local
LDAP: krb.casd.local
Discovered KPASSWD servers:
- krb.casd.local
Discovered KERBEROS servers:
- krb.casd.local
Discovered LDAP servers:
- krb.casd.local
check the status of a user
sudo sssctl user-checks pengfei

# output example
user: pengfei
action: acct
service: system-auth

SSSD nss user lookup result:
 - user name: pengfei
 - user id: 3002
 - group id: 4000
 - gecos: pengfei
 - home directory: /home/pengfei
 - shell: /bin/bash

SSSD InfoPipe user lookup result:
 - name: pengfei
 - uidNumber: 3002
 - gidNumber: 4000
 - gecos: pengfei
 - homeDirectory: /home/pengfei
 - loginShell: /bin/bash

testing pam_acct_mgmt

pam_acct_mgmt: Success

PAM Environment:
 - no env -

2.5.2 Clear sssd cache

Use the below command to clear SSSD cache, if SSSD is using outdated credentials.

sss_cache -E   # Clear all cached entries
sss_cache -u username  # Clear cache for a specific user
sss_cache -g groupname  # Clear cache for a specific group

2.6 Create service principals for kerberos authentication

sssd-krb5 requires a service principal to be able to talk with the kerberos server. So we need to create a service account(principal) for ssh-server.casd.local to be able to access krb.casd.local

In ssh-server.casd.local, run the below command

# connect to krb server via kadmin. The principal which you use to connect to the admin console 
# must has the admin rights in krb server
sudo kadmin -p admin/admin@CASD.LOCAL

# you should see the below terminal
kadmin:

# create a principal with a generated password for the ssh-server
kadmin:  addprinc -randkey auth-agent/sssd-test.casd.local@CASD.LOCAL

# export the principal with encrypted password to the default keytab
kadmin:  ktadd auth-agent/sssd-test.casd.local@CASD.LOCAL

# exit the kadmin shell
quit

# check the principal in the keytab
sudo klist -k /etc/krb5.keytab

# short version
sudo klist -ke

if your principal does not have admin rights, you can edit the /etc/krb5kdc/kadm5.acl file to grant admin rights to certain principals

The below file is an example. One common way to set up Kerberos administration is to allow any principal ending in /admin is given full administrative rights.

# To enable this, uncomment the following line:
*/admin *

2.7 Test ssh connexions

# on the ssh-server, you can already check if the pam, sssd, openldap config
getent passwd username

# on the ssh-client, 
ssh uid@ssh-server.casd.local