Aller au contenu principal

FreeIPA un gestionnaire d'identité pour Gitlab

· 7 minutes de lecture
Stéphane ROBERT
Consultant DevOps

On continue l'exploration de la sécurisation de notre serveur Gitlab. Maintenant que notre IDP, FreeIPA en l'occurrence, fonctionne, voyons comment installer Gitlab et comment le connecter à l'IDP.

Installation de Gitlab

Modification du Vagrantfile

Je vais continuer à travailler sur le [fichier Vagrantfile du serveur d'IDP FreeIPA(/post/gitlab-secure-server-freeipa)]. Je lui ajoute un serveur pour héberger Gitlab. En analysant les docs sur le site de Gitlab, l'installation est assurée par un seul package. Une fois le repo de package de Gitlab, ajouté au serveur, l'installation se fait automatiquement. Nous avons donc juste à gérer la configuration de Gitlab.

Le Vagrantfile modifié :

---
- name: Install Gitlab
  hosts: gitlab
  gather_facts: true
  become: true
  tasks:
    - name: Read vaulted file
      ansible.builtin.include_vars:
        file: gitlab_password.yml
    - name: Read vars
      ansible.builtin.include_vars:
        file: vars.yml
    - name: Install prerequisites
      ansible.builtin.apt:
        name: "{{ gitlab_dependencies }}"
        state: present
        update_cache: true
      notify: Start services
    - name: Create folder
      ansible.builtin.file:
        path: /etc/gitlab/ssl
        owner: root
        group: root
        mode: "0644"
        state: directory
    - name: Copy GitLab configuration file.
      ansible.builtin.template:
        src: gitlab.rb.j2
        dest: /etc/gitlab/gitlab.rb
        owner: root
        group: root
        mode: "0600"
    - name: Copy certificats
      ansible.builtin.copy:
        dest: /etc/gitlab/ssl
        src: "{{ item }}"
        owner: root
        group: root
        mode: "0600"
      with_items:
        - gitlab.key
        - gitlab.crt
    - name: Test repo file exist
      ansible.builtin.stat:
        path: "/etc/apt/sources.list.d/gitlab_{{ gitlab_version }}.list"
      register: file_exist
    - name: Install gitlab if repo not exist
      when: not file_exist.stat.exists
      block:
        - name: Download gitlab file
          ansible.builtin.get_url:
            mode: "0755"
            url: "https://packages.gitlab.com/install/repositories/gitlab/{{ gitlab_version }}/script.deb.sh"
            dest: /tmp/gitlab_install_repository.sh
        - name: Create repo files
          ansible.builtin.command:
            cmd: bash /tmp/gitlab_install_repository.sh
            creates: "/etc/apt/sources.list.d/gitlab_{{ gitlab_version }}.list"
    - name: Install gitlab
      ansible.builtin.apt:
        name: "{{ gitlab_version }}"
      environment:
        EXTERNAL_URL: "https://{{ gitlab_host }}.gitlab_domain"
        GITLAB_ROOT_PASSWORD: "{{ vault_gitlab_root_password }}"

Ce playbook ne gère pas le cas où le fichier de configuration est simplement modifié. Pour appliquer les modifications :

vagrant ssh gitlab

Last login: Thu Sep 21 13:40:56 2023 from 192.168.3.1
-bash: warning: setlocale: LC_ALL: cannot change locale (fr_FR.UTF-8)
vagrant@gitlab:~$ sudo gitlab-ctl reconfigure

Comme d'habitude le certificat a été généré avec mkcert.

Voici le template de la config de gitlab :

# The URL through which GitLab will be accessed.
external_url "{{ gitlab_external_url }}"

# gitlab.yml configuration
gitlab_rails['time_zone'] = "{{ gitlab_time_zone }}"
gitlab_rails['backup_keep_time'] = {{ gitlab_backup_keep_time }}
gitlab_rails['gitlab_email_enabled'] = {{ gitlab_email_enabled | lower }}
{% if gitlab_email_enabled %}
gitlab_rails['gitlab_email_from'] = "{{ gitlab_email_from }}"
gitlab_rails['gitlab_email_display_name'] = "{{ gitlab_email_display_name }}"
gitlab_rails['gitlab_email_reply_to'] = "{{ gitlab_email_reply_to }}"
{% endif %}

# Default Theme
gitlab_rails['gitlab_default_theme'] = "{{ gitlab_default_theme }}"

# Whether to redirect http to https.
nginx['redirect_http_to_https'] = {{ gitlab_redirect_http_to_https | lower }}
nginx['ssl_certificate'] = "{{ gitlab_ssl_certificate }}"
nginx['ssl_certificate_key'] = "{{ gitlab_ssl_certificate_key }}"


letsencrypt['enable'] = {{ gitlab_letsencrypt_enable | lower }}
{% if gitlab_letsencrypt_enable %}
letsencrypt['contact_emails'] = {{ gitlab_letsencrypt_contact_emails | to_json }}
letsencrypt['auto_renew_hour'] = "{{ gitlab_letsencrypt_auto_renew_hour }}"
letsencrypt['auto_renew_minute'] = "{{ gitlab_letsencrypt_auto_renew_minute }}"
letsencrypt['auto_renew_day_of_month'] = "{{ gitlab_letsencrypt_auto_renew_day_of_month }}"
letsencrypt['auto_renew'] = {{ gitlab_letsencrypt_auto_renew | lower }}
{% endif %}

# The directory where Git repositories will be stored.
git_data_dirs({"default" => {"path" => "{{ gitlab_git_data_dir }}"} })

# The directory where Gitlab backups will be stored
gitlab_rails['backup_path'] = "{{ gitlab_backup_path }}"

# These settings are documented in more detail at
# https://gitlab.com/gitlab-org/gitlab-ce/blob/master/config/gitlab.yml.example#L118
gitlab_rails['ldap_enabled'] = {{ gitlab_ldap_enabled | lower }}
{% if gitlab_ldap_enabled %}
gitlab_rails['prevent_ldap_sign_in'] = false
# LDAP Configuration
gitlab_rails['ldap_servers'] = {
  'main' => {
    'label' => 'LDAP',
    'host' =>  '{{ gitlab_ldap_host }}',
    'port' => {{ gitlab_ldap_port }},
    'uid' => '{{ gitlab_ldap_uid }}',
    'bind_dn' => '{{ gitlab_ldap_bind_dn }}',
    'password' => '{{ gitlab_ldap_password }}',
    'encryption' => '{{ gitlab_ldap_method}}',
    'verify_certificates' => false,
    'smartcard_auth' => false,
    'active_directory' => false,
    'allow_username_or_email_login' => false,
    'base' => '{{ gitlab_ldap_base }}',
    'user_filter' => '',
    'lowercase_usernames' => 'false',
    'allow_username_or_email_login' => false,
    'block_auto_created_users' => false,
    'group_base' => 'cn=groups,cn=accounts,dc={{ sld }},dc={{ tld }}',
    'admin_group' => 'admin',
  }
}

gitlab_rails['ldap_host'] = '{{ gitlab_ldap_host }}'
gitlab_rails['ldap_port'] = {{ gitlab_ldap_port }}
gitlab_rails['ldap_uid'] = '{{ gitlab_ldap_uid }}'
gitlab_rails['ldap_method'] = '{{ gitlab_ldap_method}}' # 'ssl' or 'plain'
gitlab_rails['ldap_bind_dn'] = '{{ gitlab_ldap_bind_dn }}'
gitlab_rails['ldap_password'] = '{{ gitlab_ldap_password }}'
gitlab_rails['ldap_allow_username_or_email_login'] = true
gitlab_rails['ldap_base'] = '{{ gitlab_ldap_base }}'
{% endif %}

# GitLab Nginx
## See https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/nginx.md
{% if gitlab_nginx_listen_port is defined %}
nginx['listen_port'] = "{{ gitlab_nginx_listen_port }}"
{% endif %}
{% if gitlab_nginx_listen_https is defined %}
nginx['listen_https'] = {{ gitlab_nginx_listen_https | lower }}
{% endif %}

# Use smtp instead of sendmail/postfix
# More details and example configuration at
# https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/smtp.md
gitlab_rails['smtp_enable'] = {{ gitlab_smtp_enable | lower }}
{% if gitlab_smtp_enable %}
gitlab_rails['smtp_address'] = '{{ gitlab_smtp_address }}'
gitlab_rails['smtp_port'] = {{ gitlab_smtp_port }}
{% if gitlab_smtp_user_name %}
gitlab_rails['smtp_user_name'] = '{{ gitlab_smtp_user_name }}'
{% endif %}
{% if gitlab_smtp_password %}
gitlab_rails['smtp_password'] = '{{ gitlab_smtp_password }}'
{% endif %}
gitlab_rails['smtp_domain'] = '{{ gitlab_smtp_domain }}'
{% if gitlab_smtp_authentication %}
gitlab_rails['smtp_authentication'] = '{{ gitlab_smtp_authentication }}'
{% endif %}
gitlab_rails['smtp_enable_starttls_auto'] = {{ gitlab_smtp_enable_starttls_auto | lower }}
gitlab_rails['smtp_tls'] = {{ gitlab_smtp_tls | lower }}
gitlab_rails['smtp_openssl_verify_mode'] = '{{ gitlab_smtp_openssl_verify_mode }}'
gitlab_rails['smtp_ca_path'] = '{{ gitlab_smtp_ca_path }}'
gitlab_rails['smtp_ca_file'] = '{{ gitlab_smtp_ca_file }}'
{% endif %}

# 2-way SSL Client Authentication.
{% if gitlab_nginx_ssl_verify_client %}
nginx['ssl_verify_client'] = "{{ gitlab_nginx_ssl_verify_client }}"
{% endif %}
{% if gitlab_nginx_ssl_client_certificate %}
nginx['ssl_client_certificate'] = "{{ gitlab_nginx_ssl_client_certificate }}"
{% endif %}

# GitLab registry.
registry['enable'] = {{ gitlab_registry_enable | lower }}
{% if gitlab_registry_enable %}
registry_external_url "{{ gitlab_registry_external_url }}"
registry_nginx['ssl_certificate'] = "{{ gitlab_registry_nginx_ssl_certificate }}"
registry_nginx['ssl_certificate_key'] = "{{ gitlab_registry_nginx_ssl_certificate_key }}"
{% endif %}

{% if gitlab_extra_settings is defined %}
# Extra configuration
{% for extra in gitlab_extra_settings %}
{% for setting in extra %}
{% for kv in extra[setting] %}
{% if (kv.type is defined and kv.type == 'plain') or (kv.value is not string) %}
{{ setting }}['{{ kv.key }}'] = {{ kv.value }}
{% else %}
{{ setting }}['{{ kv.key }}'] = '{{ kv.value }}'
{% endif %}
{% endfor %}
{% endfor %}

{% endfor %}
{% endif %}

# To change other settings, see:
# https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md#changing-gitlab-yml-settings

Le fichier de variables :

---
# General config.
gitlab_domain: gitlab
gitlab_version: gitlab-ee
gitlab_external_url: "https://{{ gitlab_domain }}.robert.local/"
gitlab_git_data_dir: "/var/opt/gitlab/git-data"
gitlab_backup_path: "/var/opt/gitlab/backups"

# SSL Configuration.
gitlab_redirect_http_to_https: true
gitlab_ssl_certificate: "/etc/gitlab/ssl/{{ gitlab_domain }}.crt"
gitlab_ssl_certificate_key: "/etc/gitlab/ssl/{{ gitlab_domain }}.key"

# SSL Self-signed Certificate Configuration.
gitlab_create_self_signed_cert: true
gitlab_self_signed_cert_subj: "/C=US/ST=Missouri/L=Saint Louis/O=IT/CN={{ gitlab_domain }}"

# LDAP Configuration.
gitlab_ldap_enabled: true
gitlab_ldap_host: "ipa.robert.local"
gitlab_ldap_port: "636"
gitlab_ldap_uid: "uid"
gitlab_ldap_method: "simple_tls"
gitlab_ldap_bind_dn: "uid=admin,cn=users,cn=accounts,dc=robert,dc=local"
gitlab_ldap_password: "MySecretPassword123"
gitlab_ldap_base: "cn=users,cn=accounts,dc=robert,dc=local"

# SMTP Configuration
gitlab_smtp_enable: false
gitlab_smtp_address: "smtp.server"
gitlab_smtp_port: "465"
gitlab_smtp_user_name: "smtp user"
gitlab_smtp_password: "smtp password"
gitlab_smtp_domain: "robert.local"
gitlab_smtp_authentication: "login"
gitlab_smtp_enable_starttls_auto: true
gitlab_smtp_tls: false
gitlab_smtp_openssl_verify_mode: "none"
gitlab_smtp_ca_path: "/etc/ssl/certs"
gitlab_smtp_ca_file: "/etc/ssl/certs/ca-certificates.crt"

# 2-way SSL Client Authentication support.
gitlab_nginx_ssl_verify_client: ""
gitlab_nginx_ssl_client_certificate: ""

# Probably best to leave this as the default, unless doing testing.
gitlab_restart_handler_failed_when: 'gitlab_restart.rc != 0'

# Dependencies.
gitlab_dependencies:
  - openssh-server
  - postfix
  - curl
  - openssl
  - tzdata

# Optional settings.
gitlab_time_zone: "UTC"
gitlab_backup_keep_time: "604800"
gitlab_download_validate_certs: true
gitlab_default_theme: '2'

# Email configuration.
gitlab_email_enabled: false
gitlab_email_from: "gitlab@robert.local"
gitlab_email_display_name: "Gitlab"
gitlab_email_reply_to: "gitlab@robert.local"

# Registry configuration.
gitlab_registry_enable: false
gitlab_registry_external_url: "https://gitlab.robert.local:4567"
gitlab_registry_nginx_ssl_certificate: "/etc/gitlab/ssl/gitlab.crt"
gitlab_registry_nginx_ssl_certificate_key: "/etc/gitlab/ssl/gitlab.key"

# LetsEncrypt configuration.
gitlab_letsencrypt_enable: false
gitlab_letsencrypt_contact_emails: ["gitlab@robert.local"]
gitlab_letsencrypt_auto_renew_hour: 1
gitlab_letsencrypt_auto_renew_minute: 30
gitlab_letsencrypt_auto_renew_day_of_month: "*/7"
gitlab_letsencrypt_auto_renew: true

La partie qui permet de définir la connexion à FreeIPA se trouve dans la section # LDAP Configuration du template et du fichier de valeurs. Les valeurs fonctionnent avec ce que j'ai défini dans le précédent billet.

Ah oui le mot de passe est stocké dans un vault ansible:

echo -n 'vault_gitlab_root_password: "n3xux#R8DUkGWG8M"' > gitlab_password.yml

ansible-vault encrypt gitlab_password.yml

On crée un fichier contenant le mot de passe vault :

echo 'passwd123' > ./vault_pass

On ajoute à la configuration d'ansible le chemin du fichier contenant le password :

[defaults]
roles_path = ansible-freeipa/roles
vault_password_file = .vault_pass

On peut passer au déploiement. Attention la taille du package gitlab dépasse les 1Gb, donc cela prend du temps.

vagrant up

Test de la connexion à gitlab avec le compte créé

Au bout de quelques minutes, gitlab devrait être disponible.

Et super cela fonctionne, j'ai pu m'authentifier !

Content du boulot.

Plus loin

Voilà ce second épisode de l'installation de Gitlab avec une connexion à l'IDP FreeIPA touche à sa fin. Dans le prochain épisode, nous verrons quelques actions pour sécuriser Gitlab.

attention

Info importante: Pour que la synchronisation des groupes entre l'IDP et Gitlab fonctionne, il faut avoir une licence Premium au minimum.