Homelab - Installation de FreeIPA comme IDP
Publié le : 17 septembre 2023 | Mis à jour le : 18 septembre 2023Table des matières
Introduction
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 :
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
:
vagrant up ipa
Au bout de quelques minutes votre serveur FreeIPA est up. Une petite vérification :
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
:
[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 :
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 :
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 :
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, …