AD : intégration Linux
Description des opérations
Le but est d'intégrer un serveur Linux à un domaine AD. Nous avons:
- Un serveur DC: Un Domain Controller sous Windows Server 2016. Le domaine a été créé en suivant l'assistant qui s'affiche au premier démarrage et est un domaine AD tout ce qu'il y a de plus classique...
- Domaine : INNERTECH.LOCAL
- DC : DC.INNERTECH.LOCAL
- On a pris le soin de créer un OU avec des utilisateurs : connor et ripley
- On a un groupe nommé "Linux Admins" dont sont membres les utilisateurs et qui sera utilisé pour les droits sudo
- Un serveur sous Debian 10.
Procédure suivie : Documentation Debian
Opérations
Toutes les opérations décrites sont faites sur Debian.
Préparatifs
Je commence par mettre mes deux serveurs dans le même réseau IP avec des adresses fixes.
Je commence par configurer le réseau en donnant comme DNS au serveur Linux mon ADDC. Je lui donne aussi le bon hostname:
hostnamectl set-hostname deb.innertech.local reboot now
Configuration de NTP
apt update && apt install ntp
Configuration de NTP:
<source lang="bash">
- /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help
driftfile /var/lib/ntp/ntp.drift
- Leap seconds definition provided by tzdata
leapfile /usr/share/zoneinfo/leap-seconds.list
- Enable this if you want statistics to be logged.
- statsdir /var/log/ntpstats/
statistics loopstats peerstats clockstats filegen loopstats file loopstats type day enable filegen peerstats file peerstats type day enable filegen clockstats file clockstats type day enable
- You do need to talk to an NTP server or two (or three).
- server ntp.your-provider.example
- pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will
- pick a different set every time it starts up. Please consider joining the
- pool: <http://www.pool.ntp.org/join.html>
server dc.innertech.local
- Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for
- details. The web page <http://support.ntp.org/bin/view/Support/AccessRestrictions>
- might also be helpful.
- Note that "restrict" applies to both servers and clients, so a configuration
- that might be intended to block requests from certain clients could also end
- up blocking replies from your own upstream servers.
- By default, exchange time with everybody, but don't allow configuration.
restrict -4 default kod notrap nomodify nopeer noquery limited restrict -6 default kod notrap nomodify nopeer noquery limited
- Local users may interrogate the ntp server more closely.
restrict 127.0.0.1 restrict ::1
- Needed for adding pool entries
restrict source notrap nomodify noquery
- Clients from this (example!) subnet have unlimited access, but only if
- cryptographically authenticated.
- restrict 192.168.123.0 mask 255.255.255.0 notrust
- If you want to provide time to your local subnet, change the next line.
- (Again, the address is an example only.)
- broadcast 192.168.123.255
- If you want to listen to time broadcasts on your local subnet, de-comment the
- next lines. Please do this only if you trust everybody on the network!
- disable auth
- broadcastclient
</source> Suivi d'un restart du service ntp.
NSCD
NSCD fait doublon avec SSSD, on s'en débarasse: <source lang="bash"> systemctl stop unscd systemctl disable unscd rm /var/run/nscd/socket </source>
Configuration
Kerberos
On installe krb et on le configure:
apt install krb5-client cp /etc/krb5.conf /etc/krb5.conf.bkp vim /etc/krb5.conf
<source lang="bash"> [libdefaults]
# Royaume Kerberos default_realm = INNERTECH.LOCAL
# 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
[realms]
INNERTECH.LOCAL = { # 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 = DC.INNERTECH.LOCAL
# 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 = DC.INNERTECH.LOCAL }
[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 .innertech.local = INNERTECH.LOCAL
[logging]
# Log everything to syslog. Default is severity of ERR and facility of AUTH. default = SYSLOG
</source>
Samba
On commence par gérer les daemons inutiles:
<source lang="bash">
- apt-get install samba samba-common
- systemctl stop nmbd #NetBIOS name server to provide NetBIOS over IP naming services to clients
- systemctl disable nmbd
- systemctl disable samba #Partage de dossiers avec le protocole smb
- systemctl disable samba-ad-dc #Définir le serveur comme contrôleur de domaine
</source>
Puis on édite le /etc/samba/smb.conf après en avoir fait un backup:
<source lang="bash">
- 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=INNERTECH
- 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=INNERTECH.LOCAL
- 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
</source>
Ensuite, on peut tester la configuration avec testparm. Voici ce que me renvoie une config fonctionnelle: <source> rlimit_max: increasing rlimit_max (1024) to minimum Windows limit (16384) Registered MSG_REQ_POOL_USAGE Registered MSG_REQ_DMALLOC_MARK and LOG_CHANGED Load smb config files from /etc/samba/smb.conf rlimit_max: increasing rlimit_max (1024) to minimum Windows limit (16384) Loaded services file OK. idmap range not specified for domain '*' ERROR: Invalid idmap range for domain *!
Server role: ROLE_DOMAIN_MEMBER
Press enter to see a dump of your service definitions
- Global parameters
[global] client signing = if_required disable spoolss = Yes kerberos method = secrets and keytab load printers = No log file = /var/log/samba/smbd.log max log size = 500 printcap name = /dev/null realm = INNERTECH.LOCAL security = ADS workgroup = INNERTECH idmap config * : backend = tdb printing = bsd </source>
Plus qu'a activer le daemon:
<source lang="bash"> systemctl restart smbd systemctl enable smbd </source>
Un autre exemple, avec wsdd2 d'installé pour la découverte sous Windows (la partie "nas" fonctionne même sans ça). J'ai simplement activé l'utilisatrice "justine" avec un "smbpasswd -a justine". <source lang="bash"> [global] workgroup = WORKGROUP log file = /var/log/samba/log.%m max log size = 1000 logging = file panic action = /usr/share/samba/panic-action %d server role = standalone server obey pam restrictions = yes unix password sync = yes passwd program = /usr/bin/passwd %u passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* . pam password change = yes map to guest = bad user usershare allow guests = yes
#Wsdd2, openly share to windows
netbios name = NASSQLAN
wins support = yes local master = yes preferred master = yes lanman auth = no ntlm auth = yes client lanman auth = no
[nas]
comment = home share path = /data browsable = yes create mask = 0644 directory mask = 0775 writable = yes guest ok = no public = no available = yes read only = no valid users = justine
</source>
Et la ligne de fstab qui va avec pour le monter sur le client.
//192.168.1.200/nas /home/justine/Storage cifs _netdev,users,noauto,users,credentials=/home/justine/.smb 0 0
Celui-ci a dans son home un fichier .smb qui contient user et password:
user=justine password=prout
Ouvrir simplement un partage samba en ligne de commande
apt-get install cifs-utils mount -t cifs //FILE-SERVER-IP-ADDRESS/public /local/mountpoint -o user=utilisateur
SSSD
Le démon SSSD (de l'anglais, « System Security Services Daemon ») offre accès aux mécanismes d'identité et d'authentification distants, aussi dénommés fournisseurs. Il permet à ces fournisseurs d'être connectés en tant que serveurs SSSD, faisant abstraction de l'identité locale et réseau et des sources d'authentification, et permettant à tout type de fournisseur de données d'identité d'être connecté. Un domaine est une base de données contenant des informations sur l'utilisateur, qui peut servir de source pour les informations sur l'identité d'un fournisseur. De multiples fournisseurs d'identité sont pris en charge, permettant à deux serveurs d'identité, ou plus, d'agir en tant qu'espaces de noms d'utilisateurs séparés. Les informations rassemblées sont disponibles à toutes les applications de serveur frontal avec les interfaces PAM et NSS. SSSD est exécuté en tant qu'ensemble de services, indépendamment des applications qui l'utilisent. Ainsi, ces applications n'ont plus besoin de créer leurs propres connexions à des domaines distants, ou même de savoir lequel (lesquels) est (sont) utilisé(s). La mise en cache locale robuste des informations d'identité et d'adhérence à un (des) groupe(s) permet d'effectuer des opérations peu importe d'où provient cette identité (par exemple, LDAP, NIS, IPA, DB, Samba, etc.), elle offre une performance améliorée, et permet à l'authentification d'être effectuée même lors d'opérations hors-ligne, et lorsque l'authentification en ligne est indisponible. SSSD permet aussi l'utilisation de multiples fournisseurs de même type (par exemple avec de multiples fournisseurs LDAP), ainsi qu'aux requêtes d'identité de domaines qualifiés d'être résolues par ces différents fournisseurs. De plus amples détails se trouvent dans le guide de déploiement Red Hat Enterprise Linux 6. https://access.redhat.com/documentation/fr-fr/red_hat_enterprise_linux/6/html/migration_planning_guide/ch07s02
On commence par installer le daemon:
apt install sssd
Il va commencer par balancer des erreurs; en effet, il n'as pas de fichier de config et n'as pas non plus de domaine configuré.
On créée le fichier suivant (appartient à root avec les droits 600) dans /etc/sssd/sssd.conf: <source lang="bash"> [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 = INNERTECH.LOCAL
- Configuration for the AD domain
[domain/INNERTECH.LOCAL]
- 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 </source>
Nssswitch
Quelques explications issues du man: <source> Le fichier de configuration du service de noms (« Name Service Switch » ou NSS),
/etc/nsswitch.conf, est utilisé par la bibliothèque C de GNU pour déterminer les sources desquelles obtenir les renseignements de service de noms en fonction des catégories, et dans quel ordre. Chaque catégorie de renseignements est identifiée par un nom de base de données.
Le fichier est en texte ASCII, avec les colonnes séparées par des espaces ou des tabulations. La première colonne indique le nom de la base de données. Les autres colonnes décrivent les sources, dans l'ordre des requêtes à réaliser, et un ensemble limité d'actions possibles en fonction du résultat de la résolution.
</source>
On vérifie le fichier /etc/nsswitch.conf pour que cela corresponde à:
<source> Ligne: Doit avoir "sss": passwd yes group yes netgroup yes sudoers no </source>
La ligne sudoers sera à modifier. On utilise pas le gestionnaire de sudo offert par sssd : on créée nous-mêmes un fichier dans sudoers.d.
PAM
On créée le fichier suivant dans /usr/share/pam-configs/my-ad: <source> 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
</source>
Puis:
pam-auth-update --package
Explications : PAM est le gestionnaire d'authentification sous Linux. Ici, on lui fournit un nouveau moyen d'ouvrir une session. pam_mkhomedir signifie que l'on créera un dossier home pour les utilisateurs. /etc/skel (pour skeleton) contient le "squelette" de tous les nouveaux comptes.
Sudo
Rappellons-nous, nous avons créé un groupe AD nommé "Linux Admins". Les membres de ce groupe fdoivent avoir les droits sudo. Pour cela, on crée le fichier suivant dans /etc/sudoers.d/ad-linux-admins:
%Linux\ Admins ALL = (ALL) ALL
Fin de la configuration
La configuration est terminée; cependant, pour rejoindre le domaine, il faut effectuer plusieurs opérations. Le plus simple est de passer par un script:
<source lang="bash">
- 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 </source>
Il suffit de lancer le script en lui donnant un nom d'utilisateur:
join.sh connor
Alternative : partager un dossier avec un groupe AD
La procédure ci-dessus semble effective et semble aussi plus "propre" (même si je ne l'ai pas testée depuis longtemps); mais après quelques arrachages de cheveux, voici une autre configuration établie dans le but de partager un dossier, dans lequel les seules personnes ayant accès seraient celles positionnées dans un groupe Active Directory (ici, groupe_allowed situé dans domaine.tld, pour l'exemple).
Configuration de Samba, basée sur winbind. Pourquoi Winbind ? Je ne sais pas, si ce n'est que ça fonctionne.
<source>
- See smb.conf.example for a more detailed config file or
- read the smb.conf manpage.
- Run 'testparm' to verify the config is correct after
- you modified it.
[global] log file = /var/log/samba/%m.log security = ads realm = DOMAINE.TLD workgroup = AUTH preferred master = no
idmap uid = 10000-20000 idmap gid = 10000-20000 winbind enum users = yes winbind enum groups = yes template homedir = /home/%D/%U template shell = /bin/bash client use spnego = yes client ntlmv2 auth = yes encrypt passwords = yes winbind use default domain = yes
winbind separator = +
restrict anonymous = 2
[partagepourmongroupe] comment = Espace de partage path = /chemin/du/dossier browsable = yes writable = yes public=yes valid users = @"DOMAINE+groupe_allowed" guest ok = yes read only = no create mask = 0766 create directory mask = 0755 </source>
Après cela, il faut rejoindre le domaine : regarder la configuration plus haut dans cet article, ainsi que le contenu du script utilisé pour rejoindre le domaine.
Une fois le domaine joint, samba redémarré et en place, il subsiste un problème : les utilisateurs n'ont quand même pas accès au partage. En effet, si samba les laisse entrer, leur nom et leur groupe sont inconnus au bataillon, et un "chmod 777" ni changera rien. J'imagine que cela pourrait se régler par une ligne "force user = root" dans la configuration Samba, mais on peut faire mieux que ça.
On va positionner une acl sur le dossier partagé pour que celui-ci accepte de laisser les utilisateurs du groupe agir sur le dossier.
<source> setfacl -Rm d:g:"DOMAIN+groupe_allowed":rwx /chemin/du/dossier </source>
Cette commande sert, donc, à positionner des acls (qui ne sont pas une notion couramment utilisée sur Linux...). Pour le détail:
- -R : récursif
- -m : mask : recalculer les droits (je crois)
- d:g:groupe:rwx : default (d) groupe (g) gid/nom du groupe suivi des permissions (rwx)