Aller au contenu

Installation le gestionnaire d'identité FreeIPA

logo

Dans un environnement DevOps, la sécurisation des outils de développement est une priorité pour garantir l’intégrité des projets. Parmi ces outils, GitLab occupe une place centrale pour la gestion du code source, la collaboration entre équipes et le déploiement. Cependant, pour une gestion centralisée et sécurisée des utilisateurs, il est essentiel d’intégrer une solution robuste comme FreeIPA.

FreeIPA est un outil open source permettant de gérer les identités, les politiques de sécurité et les autorisations au sein d’un réseau d’entreprise. En intégrant FreeIPA à GitLab, on bénéficie d’une authentification centralisée et d’un contrôle granulaire des accès, simplifiant ainsi la gestion des permissions tout en renforçant la sécurité du serveur GitLab.

Démarche d’automatisation de l’installation de FreeIPA

Lorsque l’on aborde l’installation d’un serveur GitLab dans un environnement sécurisé, il est essentiel de mettre en place une démarche d’automatisation qui garantisse la répétabilité et la cohérence de l’installation. L’objectif est d’automatiser deux étapes clés : l’installation du serveur GitLab et la génération de la configuration via un template.

En utilisant Ansible, nous pouvons transposer facilement les procédures manuelles d’installation, tout en intégrant FreeIPA pour une gestion centralisée des utilisateurs.

Les principaux objectifs de cette démarche sont :

  • Automatiser l’installation du serveur GitLab sur une machine cible.
  • Générer la configuration GitLab nécessaire à l’intégration avec FreeIPA, en utilisant un template.

Pourquoi utiliser Vagrant pour l’automatisation ?

Lorsque l’on développe un processus d’automatisation, il est essentiel de disposer d’un environnement de test stable, reproductible et facilement configurable. C’est là qu’intervient Vagrant. En tant qu’outil de gestion d’environnements virtuels, Vagrant permet de créer, configurer et détruire rapidement des machines virtuelles pour tester et valider les scripts d’automatisation.

Le vagrantfile :

# -*- mode: ruby -*-
# vi: set ft=ruby :
ENV['VAGRANT_NO_PARALLEL'] = 'yes'
Vagrant.configure("2") do |config|
config.vm.synced_folder '.', '/vagrant', disabled: true
config.hostmanager.enabled = true
config.hostmanager.manage_host = true
# First machine is ipa
config.vm.define "ipa" do |machine|
machine.vm.box = "generic/rocky9"
machine.vm.hostname = "ipa.robert.local"
machine.vm.provider "libvirt" do |lv|
lv.memory = 3072
lv.cpus = 2
lv.management_network_name = 'my_network'
lv.management_network_address = '192.168.3.0/24'
end
machine.vm.provision "ansible" do |a|
a.verbose = "v"
a.playbook = "deploy_freeipa.yml"
a.host_vars = {
"ipa" => {
"ipaserver_domain"=>"robert.local",
"ipaserver_realm"=>"ROBERT.LOCAL",
"ipaserver_setup_dns"=>"no",
"ipaadmin_password"=>"MySecretPassword123",
"ipadm_password"=>"MySecretPassword234",
}
}
end
end
end

Ce Vagrantfile constitue la base d’un environnement virtualisé idéal pour tester et déployer une configuration FreeIPA sur une machine Rocky Linux, avec Ansible en charge du provisionnement. En désactivant la synchronisation de dossier et en intégrant la gestion du réseau via libvirt, cette configuration garantit que la machine est isolée et que les ressources sont bien gérées (2 CPU et 3 Go de mémoire).

L’automatisation de la configuration via Ansible permet de s’assurer que le serveur FreeIPA est correctement installé et configuré à chaque fois que la machine virtuelle est provisionnée, avec les bons paramètres pour le domaine, le realm et les mots de passe administrateur.

En spécifiant ces variables directement dans le fichier, tu facilites la répétabilité de l’installation, tout en réduisant le risque d’erreur humaine. L’utilisation d’Ansible pour gérer cette étape permet également une flexibilité accrue si jamais tu souhaites modifier la configuration ou adapter les paramètres à d’autres environnements.

Avec cette configuration, la machine virtuelle FreeIPA peut être rapidement déployée pour tester l’intégration avec d’autres services, comme GitLab, tout en conservant un cadre de test sécurisé et reproductible.

Ecriture du playbook pour installer FreeIPA

En explorant la documentation officielle de FreeIPA, j’ai découvert que Red Hat propose, comme souvent, une collection Ansible dédiée à l’installation et à l’exploitation de FreeIPA. Cette collection facilite grandement la mise en place de FreeIPA dans des environnements Red Hat. Cependant, une contrainte s’impose : l’utilisation d’un système d’exploitation basé sur la famille Red Hat. Dans ce cas précis, j’ai opté pour Rocky Linux 9, une distribution communautaire compatible.

Avant de commencer à rédiger notre propre playbook, je vous invite à cloner le projet de cette collection pour bénéficier des bonnes pratiques et des automatisations préexistantes :

Terminal window
git clone https://github.com/freeipa/ansible-freeipa.git

Pour que vagrant puisse trouver les rôles de cette collection, créons un simple fichier ansible.cfg :

[defaults]
roles_path = ansible-freeipa/roles

Voilà le code du playbook, qui transpose ce que j’ai trouvé dans la documentation :

---
- name: Install Freeipa
hosts: ipa
gather_facts: true
become: true
vars:
pre_tasks:
- name: Disable ipv6
ansible.posix.sysctl:
name: net.ipv6.conf.all.disable_ipv6
value: 1
sysctl_file: /etc/sysctl.conf
- name: Enable ipv6 on lo
ansible.posix.sysctl:
name: net.ipv6.conf.lo.disable_ipv6
value: 0
sysctl_file: /etc/sysctl.conf
reload: true
- name: Set TimeZone to Paris
community.general.timezone:
name: Europe/Paris
roles:
- role: ipaserver
state: present

On peut lancer le provisionnement de la machine FreeIPA :

Terminal window
vagrant up ipa

Au bout de quelques minutes votre serveur FreeIPA est up. Une petite vérification :

Terminal window
vagrant ssh ipa
Last login: Sun Sep 17 16:49:49 2023 from 192.168.3.1
[vagrant@ipa ~]$ netstat -tlnp
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:464 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:88 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:749 0.0.0.0:* LISTEN -
tcp6 0 0 :::389 :::* LISTEN -
tcp6 0 0 :::464 :::* LISTEN -
tcp6 0 0 :::8443 :::* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
tcp6 0 0 :::88 :::* LISTEN -
tcp6 0 0 :::111 :::* LISTEN -
tcp6 0 0 :::749 :::* LISTEN -
tcp6 0 0 :::636 :::* LISTEN -
tcp6 0 0 127.0.0.1:8009 :::* LISTEN -
tcp6 0 0 127.0.0.1:8005 :::* LISTEN -
tcp6 0 0 ::1:8009 :::* LISTEN -
tcp6 0 0 :::8080 :::* LISTEN -

Avant de vérifier les utilisateurs présents sur le serveur, nous devons d’abord nous authentifier auprès du serveur Kerberos pour obtenir un token d’authentification. Cela se fait à l’aide de la commande kinit, qui permet d’obtenir un ticket Kerberos pour l’utilisateur spécifié.

Voici la commande à exécuter pour obtenir un token Kerberos :

Terminal window
[vagrant@ipa ~]$ kinit admin
Password for admin@ROBERT.LOCAL:
[vagrant@ipa ~]$ ipa user-find --all
--------------
1 user matched
--------------
dn: uid=admin,cn=users,cn=accounts,dc=robert,dc=local
User login: admin
Last name: Administrator
Full name: Administrator
Home directory: /home/admin
GECOS: Administrator
Login shell: /bin/bash
Principal alias: admin@ROBERT.LOCAL, root@ROBERT.LOCAL
User password expiration: 20231216144606Z
UID: 1251800000
GID: 1251800000
Account disabled: False
Preserved user: False
Member of groups: admins, trust admins
ipantsecurityidentifier: S-1-5-21-150280649-1004467653-323320090-500
ipauniqueid: 0026acac-5568-11ee-a911-525400c0a1d3
krbextradata: AAIuEQdlcm9vdC9hZG1pbkBST0JFUlQuTE9DQUwA
krblastadminunlock: 20230917144606Z
krblastpwdchange: 20230917144606Z
objectclass: top, person, posixaccount, krbprincipalaux, krbticketpolicyaux, inetuser, ipaobject, ipasshuser,
ipaSshGroupOfPubKeys, ipaNTUserAttrs
----------------------------
Number of entries returned 1
----------------------------

Pas mal, nous avons un utilisateur présent, le compte admin bien sûr. Je vais utiliser la CLI ipa pour créer les utilisateurs dans un premier temps. Ajoutons un utilisateur :

Terminal window
ipa user-add steph --first=Stéphane --last=ROBERT --email=steph@robert.local
------------------
Added user "steph"
------------------
User login: steph
First name: Stéphane
Last name: ROBERT
Full name: Stéphane ROBERT
Display name: Stéphane ROBERT
Initials: SR
Home directory: /home/steph
GECOS: Stéphane ROBERT
Login shell: /bin/sh
Principal name: steph@ROBERT.LOCAL
Principal alias: steph@ROBERT.LOCAL
Email address: steph@robert.local
UID: 1251800003
GID: 1251800003
Password: False
Member of groups: ipausers
Kerberos keys available: False

Définissons le mot de passe :

Terminal window
ipa user-mod steph --password

Entrez deux fois le même mot de passe. Vérifions que nous pouvons retrouver les utilisateurs via les commandes ldap :

Terminal window
ldapsearch -H ldaps://ipa.robert.local -D 'uid=admin,cn=users,cn=accounts,dc=robert,dc=local' -w MySecretPassword123 -b 'uid=steph,cn=users,cn=accounts,dc=robert,dc=local'
# extended LDIF
#
# LDAPv3
# base <uid=steph,cn=users,cn=accounts,dc=robert,dc=local> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# steph, users, accounts, robert.local
dn: uid=steph,cn=users,cn=accounts,dc=robert,dc=local
givenName:: U3TDqXBoYW5l
sn: ROBERT
uid: steph
cn:: U3TDqXBoYW5lIFJPQkVSVA==
displayName:: U3TDqXBoYW5lIFJPQkVSVA==
initials: SR
gecos:: U3TDqXBoYW5lIFJPQkVSVA==
krbPrincipalName: steph@ROBERT.LOCAL
mail: steph@robert.local
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
objectClass: inetuser
objectClass: posixaccount
objectClass: krbprincipalaux
objectClass: krbticketpolicyaux
objectClass: ipaobject
objectClass: ipasshuser
objectClass: ipaSshGroupOfPubKeys
objectClass: mepOriginEntry
objectClass: ipantuserattrs
loginShell: /bin/sh
homeDirectory: /home/steph
krbCanonicalName: steph@ROBERT.LOCAL
ipaUniqueID: 3c0bbe66-5571-11ee-8e38-525400c0a1d3
uidNumber: 1251800003
gidNumber: 1251800003
mepManagedEntry: cn=steph,cn=groups,cn=accounts,dc=robert,dc=local
ipaNTSecurityIdentifier: S-1-5-21-150280649-1004467653-323320090-1003
memberOf: cn=ipausers,cn=groups,cn=accounts,dc=robert,dc=local
krbPasswordExpiration: 20230917155005Z
krbLastPwdChange: 20230917155005Z
krbExtraData:: AAItIAdlcm9vdC9hZG1pbkBST0JFUlQuTE9DQUwA
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1

Bon notre serveur LDAP fonctionne comme attendu ! Pour créer les utilisateurs et les groupes, nous allons utiliser les modules ipa.

- name: Install Freeipa
hosts: ipa
gather_facts: true
become: true
vars:
tasks:
- name: Ensure steph is present and always reset password
community.general.ipa_user:
name: Steph
state: present
password: steph123
givenname: Stéphane
ipa_host: ipa.robert.local
ipa_user: admin
ipa_pass: MySecretPassword123

On va pouvoir, configurer notre serveur IPA avec les modules Ansible.

Plus loin

Dans le prochain billet, nous nous attaquerons au provisionnement du serveur GitLab, en intégrant le serveur FreeIPA comme source d’authentification centralisée. En parallèle, je mettrai à jour ce billet avec un code Terraform pour automatiser le déploiement de l’ensemble sur mon homelab dans les prochains jours. Cela permettra d’élargir les options de déploiement en automatisant le processus de bout en bout.

Je vais également approfondir l’aspect exploitation de FreeIPA, car la mise en place d’un tel service ne suffit pas. Il est important de bien comprendre comment le maintenir au quotidien : mises à jour, sauvegardes régulières et stratégies de reprise sur incident seront autant de sujets à explorer pour garantir la continuité et la fiabilité de cet outil essentiel.