Hardening: Securisez vos serveurs 2/2

Hardening: Securisez vos serveurs 2/2

Désactiver les core dump

Un audit sécurité d'une machine à l'aide d'un seul outil ne suffit pas, mais là, on va se baser sur une seule et unique chose : les core dump.

Ce n'est pas parce que les fichiers de conf disent que c'est désactivé, que c'est vrai.

Nous pouvons constater que les core dump ne sont pas configurés, le screen suivant le confirme également, même si cela ne concerne que le user root dans le screen, cela serait pareil pour tous les autres user.

Je m'explique.
Si vous lancez un audit via Lynis par exemple,
Vous pouvez voir qu'il nous demande de les désactiver.

On notera au passage, qu'il ne nous avertit pas sur les services système, mais Red Hat, tout comme d'autres distributions ne déroge pas à la règle.

Nous savons que les core dump sont désactivés mais Lynis, lui, n'ayant pas vu de configuration explicite en ce sens nous dit le contraire.
Est-ce une bonne chose ? À vous d'en juger. À vous de déterminer quelle importance vous donnez à la sécurité.
Personnellement, dans un cas comme celui-ci, je corrige, surtout que cela prend peu de temps au final.

Juste avant nous l'avons fait manuellement concernant Grub, l'automatisation est facile à faire.
Ici, nous allons l'automatiser directement via Ansible/Gitlab pour l'intégrer directement dans notre chaîne de déploiement quand on prépare une machine par exemple.

l'arborescence de ceci est simple.

OK. Mais qu'est-ce que cela va faire ?

  • Un job va regarder le statut actif ou inactif.
  • Un job va mettre en place, proprement, dans /etc/security/limits.d/ (parce que c'est fait pour cela), une configuration de départ qui désactive les core dump.
  • Un job va permettre de les activer avec visualisation avant/après en sortie console.
  • Un job va permettre de les désactiver avec visualisation avant/après en sortie console.

Bien commençons par le playbook, simple, basique.

---
- name: Core dump management ...
  hosts:
   - rhel8
  become: true
  become_user: root
  roles:
   - { role: coredump }

Puis les variables dans group_vars.
Au niveau domain, on va toucher tout le monde sur le serveur, mais je pourrais très bien, pour un utilisateur nommer tonton, lui attribuer des droits ou un groupe entier ou des règles dédiées à une application.
Je vous met un exemple dans la variable pamlimit_on avec un user/group commenté ainsi que d'autre possibilité car les core dump ne se limitent pas à deux simple lignes.

pamlimit_off:
  - { domain: '*', limit_type: "hard", limit_item: core, value: 0, dest: /etc/security/limits.d/10-pamlimit.conf }
  - { domain: '*', limit_type: "soft", limit_item: core, value: 0, dest: /etc/security/limits.d/10-pamlimit.conf }

pamlimit_on:
  - { domain: '*', limit_type: "hard", limit_item: core, value: unlimited, dest: /etc/security/limits.d/10-pamlimit.conf }
  - { domain: '*', limit_type: "soft", limit_item: core, value: unlimited, dest: /etc/security/limits.d/10-pamlimit.conf }

#  - { domain: 'etienne', limit_type: "hard", limit_item: core, value: unlimited, dest: /etc/security/limits.d/10-pamlimit.conf }
#  - { domain: 'etienne', limit_type: "soft", limit_item: core, value: unlimited, dest: /etc/security/limits.d/10-pamlimit.conf }

#  - { domain: 'etienne', limit_type: hard, limit_item: nofile, value: 765312, dest: /etc/security/limits.d/10-pamlimit.conf }
#  - { domain: 'etienne', limit_type: soft, limit_item: nofile, value: 765312, dest: /etc/security/limits.d/10-pamlimit.conf }
#  - { domain: 'etienne', limit_type: hard, limit_item: nproc, value: 9203, dest: /etc/security/limits.d/10-pamlimit.conf }
#  - { domain: 'etienne', limit_type: soft, limit_item: nproc, value: 9203, dest: /etc/security/limits.d/10-pamlimit.conf }

Ensuite les tâches:

---
- name: Core dump Status all user...
  ansible.builtin.shell: ulimit -a | grep "core file size" | cut -d ')' -f2
  become: true
  become_user: root
  register: coredump_status
  tags:
    - status

- name: Show result core dump status all user ...
  ansible.builtin.debug:
    var: coredump_status.stdout
  tags:
    - status

- name: Core dump Status Before Action ...
  ansible.builtin.shell: ulimit -a | grep "core file size" | cut -d ')' -f2
  become: true
  become_user: root
  register: coredump_before
  tags:
    - hardening
    - activate
    - deactivate

- name: Show result core dump status ...
  ansible.builtin.debug:
    var: coredump_before.stdout
  tags:
    - hardening
    - activate
    - deactivate

- name: Check if /etc/security/limits.d/10-pamlimit.conf exist ...
  ansible.builtin.stat:
    dest: /etc/security/limits.d/10-pamlimit.conf
  register: pamlimit_file
  tags:
    - hardening

- name: Create /etc/security/limits.d/10-pamlimit.conf file if not exist ...
  ansible.builtin.file:
    path: /etc/security/limits.d/10-pamlimit.conf
    state: touch
    owner: root
    group: root
    mode: '0644'
  register: pamlimit_create
  when: not pamlimit_file.stat.exists
  tags:
    - hardening

- name: Insert security limits ...
  community.general.pam_limits:
    domain: "{{ item.domain }}"
    limit_type: "{{ item.limit_type }}"
    limit_item: "{{ item.limit_item }}"
    value: "{{ item.value }}"
    dest: "{{ item.dest }}"
  with_items: "{{ pamlimit_off }}"
  when: pamlimit_off is defined and pamlimit_create.changed
  tags:
    - hardening

- name: Activate core dump ...
  community.general.pam_limits:
    domain: "{{ item.domain }}"
    limit_type: "{{ item.limit_type }}"
    limit_item: "{{ item.limit_item }}"
    value: "{{ item.value }}"
    dest: "{{ item.dest }}"
  with_items: "{{ pamlimit_on }}"
  when: pamlimit_on is defined
  tags:
    - activate

- name: Deactivate core dump ...
  community.general.pam_limits:
    domain: "{{ item.domain }}"
    limit_type: "{{ item.limit_type }}"
    limit_item: "{{ item.limit_item }}"
    value: "{{ item.value }}"
    dest: "{{ item.dest }}"
  with_items: "{{ pamlimit_off }}"
  when: pamlimit_off is defined
  tags:
    - deactivate

- name: Core dump Status all user after Action ...
  ansible.builtin.shell: ulimit -a | grep "core file size" | cut -d ')' -f2
  become: true
  become_user: root
  register: coredump_after
  tags:
    - hardening
    - activate
    - deactivate

- name: Show result core dump status ...
  ansible.builtin.debug:
    var: coredump_after.stdout
  tags:
    - hardening
    - activate
    - deactivate

Le fichier .gitlab-ci.yml.

variables:
  LIMIT: "--limit all"

stages:
  - coredump_hardening
  - coredump_management

include:
  - job-ci/coredump.yml

Et enfin, les jobs Gitlab.
(vous noterez que je les ai conditionnés par un need)

coredump_status:
  stage: coredump_hardening
  script: |
    export ANSIBLE_FORCE_COLOR=true
    ansible-playbook -i env/inventory $LIMIT --tags status coredump.yml
  when: manual

coredump_hardening:
  stage: coredump_hardening
  needs:
    - coredump_status
  script: |
    export ANSIBLE_FORCE_COLOR=true
    ansible-playbook -i env/inventory $LIMIT --tags hardening coredump.yml
  when: manual

coredump_activate:
  stage: coredump_management
  needs:
    - coredump_status
  script: |
    export ANSIBLE_FORCE_COLOR=true
    ansible-playbook -i env/inventory $LIMIT --tags activate coredump.yml
  when: manual

coredump_deactivate:
  stage: coredump_management
  needs:
    - coredump_status
  script: |
    export ANSIBLE_FORCE_COLOR=true
    ansible-playbook -i env/inventory $LIMIT --tags deactivate coredump.yml
  when: manual

Avant la mise en place, le premier job:
(Le fichier de conf custom n'est pas encore en place)

Initialisons cela avec le job coredump_hardening.

Voilà, nous n'avons pas changer le statut des core dump, mais nous les avons fixés officiellement. en tout cas, pour Lynis. Vérifions cela.

Nous sommes passés de 40 suggestions à 38 et plus de mentions des core dump également.
(Pourquoi 2 ? Bonne question. Je ne sais pas, on verra un semblant d'explication un peu plus bas)

Maintenant, imaginons que nous devions activer les core dump, pour x raison.

Bien sur Lynis nous rappelle à l'ordre:

On peut constater dans la sortie console que la valeur est passée de 0 à unlimited.
C'est exactement ce que l'on voulait.
Vous remarquez que l'on remonte pas à 40 suggestions, mais seulement à 39.
On peut en conclure que d'avoir mis un fichier de conf dans limit.d fait partie des bonnes pratiques.

Je vous rappelle que là, c'est pour tous les users.
Maintenant, nous n'en avons plus besoin, désactivons les core dump.

Et voilà, nous sommes revenus à l'état initial voulu.

Conclusion:

Nous venons de voir comment durcir (très légèrement) notre machine.
Durcir un serveur, un PC, n'est pas une chose qui se fait dans la demi-heure.

La sécurité coûte cher. Cela prend du temps. Et le temps, c'est de l'argent aussi.
Une question à se poser, parmi tant d'autres, est :
Que suis-je prêt à accepter ?


Si un outil d'audit de sécurité vous dit de faire une chose, avant de le faire, soyez sur est certains que ce n'est une fonctionnalité, comme les core dump, dont vous avez/aurez besoin.
La sécurité est, en partie, un compromis sur l'acceptable, le maîtrisé, et l'impératif à corriger.
Bien entendu, plus vous pouvez appliquer de règles de bonne pratique, plus vos machines seront sûrs.
En amont de cela, il y a aussi, des pare-feu, des routeurs, etc ...
Vous ne pouvez, vous ne devez, en aucun cas tout miser sur un seul et unique outils, mode de durcissement.
C'est l'empilement de différentes briques, tout au long de votre SI, que vous obtiendrez quelque chose de durcit et acceptable.
Tout miser sur le même type d'audit, de durcissement, revient pour un artisan à n'avoir qu'un seul gros client, qui le fait vivre, et plusieurs autres de moindre importance.