Aller au contenu

Installation le gestionnaire d'identité FreeIPA

logo

Je vais poursuivre mes billets sur la sécurisation de la supply chain. Dans ce billet, je vous propose de monter un IDP pour pouvoir mettre en place le principe de moindre privilège sur notre futur serveur Gitlab.

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

Toujours le même principe. Je pars d’une feuille vierge avec comme objectifs :

  • L’installation du serveur gitlab
  • Génération de la configuration via un template.

Pour écrire le playbook Ansible, j’ai tout simplement transposé la procédure d’installation disponible sur le site de documentation de FreeIPA.

Ecriture du Vagrantfile

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

Je pense que vous avez remarqué que sur le provisionnement du serveur FreeIPA, j’ai ajouté des variables permettant de le configurer.

Ecriture du playbook pour installer FreeIPA

En cherchant dans la documentation de FreeIPA, j’ai remarqué que Red Hat, a comme à son habitude écrit une collection permettant d’installer et d’exploiter FreeIPA. La seule contrainte, il faut utiliser un linux de la famille Red Hat, ici une Rocky Linux 9.

Avant d’écrire le playbook, je vous propose de cloner le projet de cette collection :

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 -

Vérifions que nous pouvons consulter les utilisateurs présents dans le serveur. Avant, il faut obtenir un token Kerberos avec la commande kinit :

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 provisionnerons le serveur Gitlab et nous utiliserons le serveur IPA comme source d’authentification. PAr contre, je mettrais à jour ce billet avec du code Terraform pour le déployer sur mon homelab dans les prochains jours. Je vais aussi étudier la partie exploitation de FreeIPA. Et oui, il faut maintenir ce genre d’outil : mise à jour, sauvegarde, reprise sur incident, …