Menu

Connexion utilisateur

GrSecurity sur une Debian

Écrit par Jérôme Flesch pour debian-fr.org
Ce document est sous license FDL.

Cet article a été écrit au moment où le dernier noyau Linux stable en date était le 2.4.21 (9/8/2003) et pour GrSecurity 1.0.
Cet article se base essentiellement sur la documentation officielle (http://www.grsecurity.org/gracldoc.htm) ainsi que sur l'aide proposée lors de la configuration du noyau.

Si vous souhaitez installer GrSecurity 2.0, vous pouvez déja jeter un oeil sur cet article qui vous donnera les principaux changements.

I) A quoi ça sert ?

Le principe de GrSecurity, appelé aussi GrSec, est simple: accroître la sécurité d'un système informatique basé sur le noyau Linux.
Vous me direz, GNU/Linux est un système stable, utilisé un peu partout, etc, alors pourquoi chercher à le sécuriser encore plus ? Déjà parce-que GNU/Linux n'a jamais été totalement infaillible, et quoiqu'on en dise, des failles de sécurité sont régulièrement trouvées dans certains serveurs. De plus, les utilisateurs ayant un compte sur une machine GNU/Linux peuvent facilement obtenir des informations en tout genre sur celle-ci, facilitant le récolement d'informations qui est toujours la première phase de l'attaque d'un pirate. Un des autres problèmes de Linux sont les cages "chroot" (cf man chroot), qui laisse un peu trop facilement échapper leurs occupants.
GrSecurity a donc pour but de remédier à tout ces problèmes (ce qui ne rendra sans doute pas votre Linux-Box invulnérable, mais qui y contribuera sûrement).
GrSecurity offre différentes protections, telles que:

  • La protection des espaces d'adressage, en français, ça donne: Une protection contre diverses attaques telles que les buffers overflows qui ont pour but de pousser un programme à écrire hors de son espace mémoire (imaginez la casse)
  • La limitation des possibilités offertes aux programmes se trouvant à l'intérieur d'un chroot, et ceci dans le but de les empêcher de sortir de ce chroot.
  • La possibilité de logguer a peu près n'importe quel évènement.
  • La possibilité de cacher un certains nombre d'informations aux utilisateursautres que root (moins ils en savent, mieux on se porte)
  • Différentes protections réseau telles que l'altération des réponses au ping (rendant la détection de l'os plus difficile)
  • La mise au point d'ACL (Access Control List, comprenez système de limitation d'accès pour admin paranoïaques)
  • etc.

Bref, vous l'avez compris, si vous avez un serveur GNU/Linux (ou même juste un poste de travail), GrSec est ce qu'il vous faut !

II) Comment ça marche ?

Bon, il ne faut pas se leurrer, si vous voulez installer grsec, vous êtes bon pour patcher et recompiler votre noyau (Profitez-en pour mettre le votre à jour ?)

* Préliminaires:
Vous devez avoir les librairies et les exécutables nécessaires à la compilation de votre noyau, et vous devez savoir comment en compiler un. Pour tout ce qui va suivre, vous devrez être en root, donc tacher de prendre vos précautions (genre: alias 'rm -rf /'='echo Arrête de boire')

* 1ère étape: Récupérer les sources du noyau
Contrairement à ce qu'on pourrait penser, apt-get n'est pas vraiment votre ami dans ce cas-là, je m'explique: Il semblerait que les responsables du projet Debian ont choisit de patcher les sources du kernel qu'ils distribuent et ceci depuis la version 2.4.20. Quoiqu'il en soit, le patch GrSec ne marchant pas sur ces versions tatouées Debian (ou sinon c'est que j'ai raté une option quelque part ?), il ne vous reste plus qu'à vous rendre chez notre ami http://kernel.org/ pour y prendre la dernière version en date. Pour me faciliter la vie, je pars du principe que vous avez opté pour un 2.4.21 flambant neuf (évidement, si ce n'est pas le cas, je pense qu'il vous suffira d'ajuster les chiffres).

* 2ème étape: Récupérer GrSecurity
Là par contre, apt-get fait tout à fait l'affaire:

apt-get install kernel-patche-2.4-grsecurity

Il est possible que "gradm", vous serve par la suite, mais pour l'instant on s'en cogne.

* 3ème étape: Installer et patcher tout ça
(Je vais détailler un peu les opérations au cas où vous seriez un peu fatigué)
- Mettre les sources que vous avez téléchargées (normalement "linux-2.4.21.tar.bz2") dans le /usr/src

cd /usr/src ; tar -xjf linux-2.4.21.tar.bz2

Là j'ai eu un petit problème avec le script chargé d'appliquer le patch, donc j'ai choisi d'utiliser la méthodedonnée dans la documentation officielle de grsec pour patcher les sources (maj: personnellement, j'ai plutôt tendance à prendre carrément le dernier patch en date sur http://grsecurity.org et à l'appliquer comme indiquer ci-dessous):

cd /usr/src/kernel-patches/all/grsecurity-2-4

(c'est normalement là que ce trouve les patches)

cp grsecurity-*-2.4.21.patch.gz /usr/src

(on copie le patch dans /usr/src)

cd /usr/src/; gunzip grsecurity-*-2.4.21.patch.gz

(On sort le patch de sa boite)

patch -p0 <grsecurity-*-2.4.21.patch

(On patche: Il faut savoir que le patch considère les sources du noyau comme étant dans ./linux-2.4.21)

* 4ème étape: Configurer et compiler votre kernel

make menuconfig

ou

make xconfig

, au choix

Le paramétrage des 9/10ème de votre kernel n'étant pas du ressort de ce document, je vais directement passer à la section concernant GrSecurity qui a du apparaître si le patch a été correctement appliqué.

Je vais donc tacher de décrire au mieux chacune des options proposées dans cette section (Il est possible que l'aide fournie lors de la configuration du noyau vous donne plus de précisions).

# GrSecurity (Y/N):
Évidemment vous mettez ceci sur Y, sinon je me demande bien pourquoi vous avez fait tout ça

# Security level (Low/Medium/High/Customized):
Comme vous vous en doutez, il s'agit de choisir le niveau de sécurité appliqué par GrSec.
Je vais donc vous décrire les caractéristiques de chaque niveau de sécurité, mais je vous recommande fortement de prendre "Customized" qui vous permettra de choisir dans le détail les options que vous souhaitez.
Si vous choisissez "customized", il faut savoir que certaines options pourront être (dés)activées à partir du /proc (ce qui n'est pas le cas en "low", "medium" ou "high" !): Il s'agit des options dont j'ai fait suivre le nom par leur nom dans le /proc/sys/kernel/grsecurity/.

C'est dans "customized" que j'explique le détail de chaque fonctions.

  Low :
    Linking restrictions
    Fifo restrictions
    Random pids
    Enforcing RLIMIT_NPROC on execve()
    Restricted dmesg
    Random ip ids
    Enforced chdir("/") on chroot
  Medium :
    Random tcp source ports
    Altered Ping ids
    Failed fork logging
    Time change logging
    Signal Logging
    Deny mounts in chroot
    Deny double chrooting
    Deny sysctl writes in chroot
    Deny mknod in chroot
    Deny access to abstract AF_UNIX out of chroot
    Deny pivot_root in chroot
    Denied writes of /dev/kmem, /dev/mem, and /dev/port
    /proc restrictions with special gid set to 10
    address space layout randomization
  High:
    additional /proc restrictions
    chmod restrictions in chroot
    no signals, ptrace, or viewing processes outside of chroot
    capability restrictions in chroot
    deny fchdir out of chroot
    priority restrictions in chroot
    segmentation-based implementation of PaX
    mprotect restrictions
    removal of /proc/<pid>/[maps|mem]
    kernel stack randomization
    mount/unmount/remount logging
    kernel symbol hiding
  Customized:

Il faut savoir que la plus part des options en rapport avec la gestion de la mémoire proviennent du projet PaX qui a été inclus à GrSecurity. Ces options fonctionnent en partie avec 'chpax' (apt-get install chpax) qui n'est pas traité dans cet article, mais qui fera sans doute l'objet d'un prochain article.

    Address Space Protection:
      Enforce non-executable pages:

Il arrive que sur certaines machines, la protection des pages mémoires soit indisponible ou que Linux ne l'utilise tout simplement pas. Cela peut donc laisser la porte ouverte à des attaques du genre buffer overflow, etc. Cette options permet donc de choisir différentes protections pour y remédier.
NDR:<!-- U --> J'utilise une carte vidéo Nvidia GeForce 4 440Mx (avec le pilote fourni par nvidia), et il semblerait que cette option empêche XFree86 et le pilote de fonctionner correctement. Si vous aussi avez ce genre de problèmes avec GrSecurity et votre GeForce, merci de me prévenir pour que je sois sûr que ce n'est pas une spécificité de ma machine)
Re-NDR:<!-- U --> Des possesseurs de GeForce 2 et de carte Ati Rage m'ont signalé avoir eût des problèmes similaires avec cette option. Il semblerait donc que ce soit un problème commun à tout les utilisateurs de XFree (à vérifier). Je me suis aussi rendu compte que cette option rendait impossible la compilation des locales sur les Debian. Dans le cas des locales, ceci est peut-être simplement dû à une des options suivantes dépendantes de celle-ci (étant flemmard par nature, je vous avouerais ne pas trop avoir cherché).

      Paging based non-executable pages:

L'aide du kernel ne décrit pas très clairement en quoi consiste cette option, cependant, d'après les explications que j'ai obtenu (merci Dave` :), cette option aurait pour but d'utiliser de manière plus efficaces les permissions d'accès sur les différentes pages mémoires (ceci grâce au MMU: Memory Management Unit), retirant notament l'attribut exécutable à certaines pages où cet attribut est rarement néccessaire.
L'aide du kernel dit que cela peut avoir des incidences variables sur le CPU et recommande une certaine précaution avec. Cependant je l'ai testé sur un Pentium I et un Pentium III sans que cela semble poser de problème ni de ralentissement majeur.

      Segmentation based non-executable pages:

Encore une fois l'aide du kernel reste assez flou, mais on peut penser qu'elle a une utilité similaire à la précédente. Cependant ils précisent qu'elle a peu d'impactes sur les performances et précisent qu'elle limitera aussi l'espace d'adressage à 1.5Gb au lieu de 3Gb.

      Emulate trampolines:

Certains programmes ont besoin d'exécuter des petits bouts de code dans des pages mémoires rendues non-exécutables par les options précédentes. Celle-ci sert donc à remédier à ce problème (Cette option est même nécessaire sur les Parisc et les ppc). Mais pour faire correctement fonctionner ces programmes, en plus de cette option, il faut utiliser le programme 'chpax' (non traité dans ce document, désolé).
Les concepteurs de grsec précisent cependant que cette option *peut* servir à un attaquant et conseillent donc, plutôt que de l'utiliser, d'éviter les programmes nécessitant cette option (souvent ces programmes sont en rapport avec la libc5).

      Automatically emulate sigreturn trampolines:

Il s'agit d'une option dans la continuité de la précédente. C'est une solution temporaire pour les utilisateurs bloqués avec une libc5, une glibc 2.0 ou je-ne-sais-quoi-encore-de-Mal(tm).
Comme la précédente, elle est nécessaire si vous avez un parisc ou un ppc, et comme la précédente, elle offre une faille pour un attaquant.

      Restrict mprotect()

Cette option empêche les programmes de:
- rendre exécutable une page mémoire qui ne l'était pas
- rendre accessible en écriture une page mémoire exécutable qui était en lecture seule
- créé une page exécutable sur une mémoire quelconque.

      Disallow ELF text relocations (DANGEROUS):

Certains types de librairies ELF sont sujets à des attaques. Ce genre d'attaque peut être empêcher en poussant le système à n'utiliser que des librairies PIC ELF. Cependant cela peut poser problème dans le cas où certains composants de votre OS utiliseraient une de ces librairies non-PIC. Donc à moins d'être sûr de savoir ce que vous faites, il est recommandé de ne pas activer cette option.

      Enforce non-executable kernel pages:

Options équivalente à "Paging based non-executable pages" et à "Restrict mprotect()" rendant plus dur l'injection d'un code étrangé dans la mémoire du noyau.

      Address Space Layout Randomization:

Beaucoup d'attaques se basent sur la connaissance de certaines adresses mémoire dans le programme cible. Cette option permet donc au kernel de choisir les adresses mémoires au hasard, empêchant l'attaquant de les deviner. Or ce genre d'attaques lancées au hasard va plus probablement planter le programme cible que causer de réels dégâts, ce qui permettra au noyau de détecter chaque tentative et de réagir.
PaX précise ne pas fournir de mécanisme de réaction, mais GrSecurity, dans le cadre des ACLs en propose un. Une autre alternative pouvant fournir un mécanisme de réaction est " Nergal's segvguard " ( ftp://ftp.pl.openwall.com/misc/segvguard/ ).

      Randomize kernel stack base:

Cette option utilise le même principe que la précédente, mais l'applique sur chaque mémoire tampon des différentes taches du kernel.
Les concepteurs de grsec mettent en garde sur le fait que le fait de rendre les adresses de ces piles aléatoires peut causer des "stacks overflow" (surcharge de ces mémoires tampons) et recommandent donc de tester très attentivement votre système.

      Randomize mmap() base:

Même principe qu'avant, mais pour les requêtes mmap() (sauf celles qui précisent une adresse). Cela s'appliquera donc notamment au librairies chargées dynamiquement.

      Randomize ET_EXEC base:

Toujours le même principe, mais pour l'adresse de base des exécutables lancés.
Cependant cette option peut causer une dégradation des performances et la détection des attaques peut causer de fausses alertes.

      Deny writing to /dev/kmem, /dev/mem, and /dev/port:

Comme vous vous en doutez, cette option empêche l'écriture dans /dev/kmem, /dev/mem et /dev/port, diminuant ainsi beaucoup les risques d'attaques. Cependant, même si cette protection n'empêche pas le fonctionnement d'XFree, certains pilotes pour les cartes vidéos ont besoin d'écrire dans le BIOS (notamment les cartes Savage), et donc ne peuvent pas marcher avec cette option activé. Cette option empêche aussi le fonctionnement d'applications telles que VMWare.

      Disable privileged I/O:

Cette options rendra les fonctions ioperm() et iopl() inopérantes. Malheureusement, XFree86 a besoin de ces fonctions et ne pourra donc pas fonctionner si cette option est activée (Il est probable que cela soit aussi le cas d'autres programmes).

      Remove addresses from /proc/pid/[maps|stat]:

Cette option a pour but de rendre moins bavard le /proc au sujet des adresses mémoire des processus.

      Hide kernel symbols:

Cette option empêche tout utilisateur n'ayant pas le CAP_SYS_MODULE, d'accéder aux informations sur les modules chargés et d'afficher les symbols du noyau.
(Le CAP_SYS_MODULE est une capacité, ceci étant expliqué ultérieurement dans le chapitre III sur les ACLs)
Cette option n'est réellement efficace que si d'autres fichiers tels que l'image du noyau, le System.map et le /proc/kcore sont inaccessibles aux utilisateurs.

    ACL options

ou

    Role based Access Control Options
      Hide kernel processes:

Cette option permet de cacher aux utilisateurs tout les processus propres au noyau ou ayant le mode "h" (hidden), sauf pour l'utilisateur authentifié en tant qu'admin (pas root, mais administrateur sauce " gradm ") ou pour les processus ayant le droit de les voir (mode "v").
Cette option est à utiliser avec "gradm" qui est traité dans la IIIème partie de ce document.

      Maximum tries before password lockout

Cette option permet de fixer le nombre de fois qu'un utilisateur peut tenter de s'authentifier en temps qu'administrateur avec " gradm " avant de se voir empêcher de se connecter en tant que tel pendant un certains temps.

      Time to wait after max password tries, in seconds

Il s'agit du temps qu'un utilisateur doit attendre avant de pouvoir retenter de se connecter en administrateur par " gradm " après raté le nombre d'essais maximal de connexion.

    Filesystem Protections
      Proc restrictions:

Cette option permet de cacher aux utilisateurs tout les processus ne leur appartenant pas.

      Restrict to user only:

Cette option spécifie que tout les utilisateurs sauf root sont concernés par la précédente option. Cette option les empêche aussi de voir les informations relatives au réseau et de voir les symboles du noyau, ainsi que les informations sur les modules.

      Allow special group:

Permet à un groupe d'utilisateurs en particulier d'échapper à la règle.

      Additional restrictions:

Empêche les utilisateurs normaux de voir les informations du CPU et des périphériques.

      Linking restrictions: (linking_restrictions) 

Ceci empêchera les utilisateurs de suivre des liens symboliques aboutissants sur des fichiers qui ne sont pas les leurs à moins qu'ils possèdent le répertoire contenant le fichier de destination.

      FIFO restrictions: (fifo_restrictions) 

Ceci empêche l'utilisateur d'écrire dans un FIFO qui ne lui appartient pas, à moins que cet utilisateur ne possède le répertoire contenant le FIFO.
Pour ceux qui ne le savent pas (c'était mon cas il y a un peu plus de 30secondes), FIFO signifie First In, First Out. Il s'agit en fait d'un fichier se comportant comme un tube et n'ayant donc pas de véritable existence sur le disque. Il permet notamment à des processus de communiquer entre eux (cf man fifo)

      Chroot jail restrictions:

Permet d'accéder aux différentes options permettant de bloquer un processus dans une cage chroot.

      Deny mount: (chroot_deny_mount) 

Interdiction de monter une partition à l'intérieur du chroot.

      Deny double-chroots: (chroot_deny_chroot) 

Interdiction d'effectuer un chroot à l'intérieur d'un autre chroot, ceci étant le moyen le plus couramment utilisé pour sortir d'un chroot.

      Deny pivot_root in chroot: (chroot_deny_pivot) 

pivot_root() est une fonction similaire à chroot. Cette option permet donc d'interdire cette fonction.

      Enforce chdir("/") on all chroots: (chroot_enforce_dir) 

Le super-utilisateur (root) peut facilement sortir d'une cage chroot avec la simple commande "cd ..". Cette option a pour but d'empêcher le root de descendre de l'arborescence en dessous du chroot().

      Deny (f)chmod +s: (chroot_deny_chmod) 

Empêche tout programme dans un chroot de mettre les bits suid ou sgid à un fichier.

      Deny fchdir out of chroot: (chroot_deny_fchdir) 

Fchdir() fonctionne comme la fonction chdir(), sauf qu'il utilise un pointeur de fichier à la place du path pour savoir où aller. Donc si cette fonction a un pointeur sur un répertoire hors du chroot, elle peut permettre au programme de sortir.
Cette option permet donc d'empêcher cela.

      Deny mknod: (chroot_deny_mknod) 

Mknod permet de créer des entrées de périphériques (comme celle dans le /dev), et peut donc permettre à un programme dans un chroot d'accéder tout de même à certaines périphériques dont les partitions. Cette option permet donc d'interdire l'usage de mknod dans un chroot.

      Deny shmat() out of chroot: (chroot_deny_shmat)

Empêche le processus d'accéder à des segments de mémoire partager qui ont été créé en dehors du chroot.

      Deny access to abstract AF_UNIX sockets out of chroot: (chroot_deny_unix) 

Empêche le processus de ce connecter à des "sockets" de domain Unix.
Il s'agit de sockets servant à la communication entre processus sur une même machine.

      Protect outside processes: (chroot_findtask) 

Empêche le processus enfermé dans le chroot d'envoyer un quelconque signal (par ex un kill) à des processus externes au chroot.

      Restrict priority changes: (chroot_restrict_nice) 

Rend le processus interne au chroot incapable de changer la priorité d'un processus externe au chroot, et incapable d'augmenter la priorité d'un processus interne au chroot (dont lui-même).

      Deny sysctl writes in chroot: (chroot_deny_sysctl) 

Empêche le processus (et donc éventuellement un attaquant) d'écrire sur les entrées sysctl tel que le /proc.

      Capability restrictions within chroot: (chroot_caps) 

Empêche un processus d'insérer des modules dans le noyau, d'avoir des accès e/s "brutes", d'avoir des accès aux taches systèmes et d'administration, de redémarrer le système, changer l'heure du système, etc...

    Kernel Auditing
      Single group for auditing: (audit_group)

Permet de logguer toute activité (chdir, exec, mount) d'un groupe d'utilisateur.

      Exec logging:(exec_logging)

Log toutes les exécutions de commandes. Cependant il ne faut pas perdre de vu que ce genre d'option peut générer beaucoup de logs dans certains cas.

      Ressource logging:

Log toute tentative visant à dépasser les ressources du système.

      Log execs within chroot: (chroot_execlog)

Log toutes les exécutions de commandes faites dans un chroot.

      Chdir logging:(audit_chdir)

Log tout les changements de répertoire.

      (Un)Mount logging:(audit_mount)

Log tout les (dé)montages de partitions.

      IPC logging: (audit_ipc)

Log toutes les créations/destruction de queues de messages, sémaphores et de mémoire partagée.

      Signal logging: (signal_logging)

Log tout les signaux transmis entre les processus.

      Fork failure logging: (forkfail_logging) 

Log toutes les tentatives de fork() échouées, ceci étant souvent du à des forks bombs.

      Time change logging: (timechange_logging) 

Log tout les changements d'heure effectué sur la machine, ceci servant parfois à cacher certaines modifications.

      /proc/<pid>/ipaddr support

Cette option ajoute une nouvelle entrée dans chaque /proc/<pid>:
ipaddr
Ce fichier contiendra toutes les ips des personnes utilisant ce processus.
Cette information peut se révèler utile pour les Détecteur d'Intrusion pour effectuer une réponse distante à une attaque locale (Par exemple indiquer au firewall d'empêcher l'accès à tout les services de telle ip).
Seul le propriétaire du processus (et root si dans les ACLs il a la capacité " CAP_DAC_OVERRIDE " qui peut être retirée par l'intermédiaire du système RBAC) peut lire cette entrée.
J'ai experimenté cette option sans ACL, et il semblerait que le root puisse, par défaut dans ce cas, lire tout de même cette entrée.

    Exécutable protection
      Enforce RLIMIT_NPROC on execs: (execve_limiting) 

Cette options permet de vérifier lors de l'exécution d'une commande, que le nombre de processus lancés par le processus d'origine ne franchi pas une certaine limites en ressources.

      Dmesg restriction: (dmesg)

Empêche tout utilisateur autre que root d'utiliser dmesg.

      Randomized pids: (rand_pids) 

Chaque fois qu'un processus est créé, pour lui attribuer un numéro, Linux se contente de reprendre l'id du dernier processus créé et d'y ajouter 1, ceci a notamment pour effet que même après un redémarrage, les différents daemons tournants sur une machine garde le même pid, les rendant plus facilement repérables et donc vulnérables. Cette option permet donc au noyau de choisir des ids au hasard (enfin il s'agit d'un "pseudo-hasard")

      Trusted path execution: (tpe)

Empêche les utilisateurs faisant partis du groupe spécifié de lancer des commandes qui n'ont pas pour propriétaire root.

      Partially restrict non-root users: (tpe_restrict_all) 

Tout les utilisateurs autre que root et n'appartenant pas au groupe spécifié précédemment n'ont le droit de lancer que des programmes appartenant à root, ou alors des programmes leur appartenant mais étant dans des répertoires non-accessibles aux autres.

    Network Protections
      Larger entropy pools:

Permet d'augmenter la taille du "fond commun d'entropie" servant à générer les nombres aléatoires. En activant cette option, les nombres aléatoires générés et utilisés par GrSecurity (ainsi qu' éventuellement d'autres parties du noyau Linux) seront de meilleurs qualités (moins prévisibles)

      Truly random TCP ISN selection (rand_isns)

Lors de l'initialisation d'une connexion TCP, le serveur doit définir un nombre (ISN) qui sera transmis et incrémenter dans chaque packet de cette même connexion. Ceci permettant notamment d'éviter qu'un client se fasse passer pour un autre et permet aussi de se rendre compte quand un paquet est perdu (corrigé moi si je me trompe ?).
Cette option permet de choisir l'ISN à la manière de Open BSD (nombre aléatoire), rendant ce nombre moins prévisible.

      Randomized IP IDs: (rand_ip_ids)

Si cette option est activé, les champs id de tout les packets ips sortant seront mis au hasard. Linux par défaut se contente d'incrémenter de 1 chaque packets envoyé, laissant la possibilité d'un scan de port intracable.

      Randomized TCP source ports: (rand_tcp_src_ports)

Lorsque vous établissez une connexion TCP, un port est ouvert localement. Pour déterminer ce port, Linux se contente d'incrémenter de 1 par rapport au dernier port ouvert. Cette option permet à Linux de choisir ce port aléatoirement.

      Randomized RPC XIDs: (rand_rpc)

Permet de rendre aléatoires les XIDs des RPCs (appels de fonction à distance)

      Altered Ping IDs: (altered_pings)

L'id que Linux va utiliser pour répondre sera le même que celui contenu dans la requête ping. Ceci rendra plus difficile pour un attaquant de déterminer votre OS.

      Socket restrictions:

Vous permet d'accéder aux options suivantes:

      Deny any sockets to group: (socket_all)

Empêche les utilisateurs faisant partie du groupe spécifié d'ouvrir une socket, quel qu'elle soit: que ce soit ouvrir un port ou se connecter ailleurs

      Deny client sockets to group: (socket_client)

Empêche les utilisateurs faisant partie du groupe spécifié d'ouvrir une connexion sur l'extérieur.

      Deny server sockets to group: (socket_server)

Empêche les utilisateurs faisant partie du groupe spécifié d'ouvrir un port sur la machine.

    Sysctl support
      Sysctl support

Permet de modifier les réglagles de grsec à partir /proc/sys/kernel/grsecurity.
Si vous souhaitez continuer à installer/configurer grsec à l'aide de ce document, je vous recommande fortement de répondre [Y])

    Logging options

Ils s'agit d'options concernant la manière dont grsec loggue les événements, je ne pense pas qu'il soit nécessaire que je détaille.

Après tout ça, il ne vous reste plus qu'à compiler votre noyau:

make dep modules bzImage modules_install install

Vous pouvez déjà ajuster votre configuration de lilo ou grub selon vos besoins, mais ne redémarrer pas tout de suite...

* 5ème étape: Et nan, c'est pas fini ...
Si vous avez activé l'option sysctl comme je vous l'ai recommandé, il vous reste maintenant à vous en servir.
Pour cela nous allons créer un script de démarrage qu'on placera dans /etc/init.d (personnellement je l'ai appelé 'grsec' tout bêtement).

NB:<!-- U --> On m'a fait remarquer qu'il était aussi possible d'utiliser le/etc/sysctl.conf pour ce genre de réglages

On commence par un classique:

#!/bin/sh

ensuite le but du jeu est d'activer les différentes options de grsec dans le /proc grâce à une série de commande du genre:

echo 1 > /proc/sys/kernel/grsecurity/[option]

("echo 0 [...]" pour les désactiver bien entendu)

J'ai précisé dans la précédente description des options leurs noms dans le /proc (cf ce qui est entre parenthèse après les noms des options). Si rien n'est préciser, il est probable que cette option ne soit pas changeable à partir du /proc

Donc par exemple pour activer "Randomized TCP source ports", on utilisera:

echo 1 > /proc/sys/kernel/grsecurity/rand_tcp_src_ports

Je vous recommande de le faire pour chaque options, même celle que vous souhaitez désactiver (echo 0). On est jamais trop prudent...

Une fois que vous avez tout spécifié dans votre script, il ne faut pas oublier de verrouiller GrSecurity et donc mettre en fin de script:

echo 1 > /proc/sys/kernel/grsecurity/grsec_lock

En pratique, ça donne:

#!/bin/sh
echo Mise en place de Grsecurity
echo Ce script a été fait pour l'exemple
echo Si vous décidez de l'utiliser, n'oubliez surtout pas
echo de l'ajuster à vos besoins

# On déverrouille (pas obligatoire mais je recommande quand même de le faire)
echo 0 > /proc/sys/kernel/grsecurity/grsec_lock

# Chroot restrictions ...
echo 1 > /proc/sys/kernel/grsecurity/linking_restrictions
echo 1 > /proc/sys/kernel/grsecurity/fifo_restrictions
echo 1 > /proc/sys/kernel/grsecurity/chroot_deny_mount
echo 1 > /proc/sys/kernel/grsecurity/chroot_deny_chroot
echo 1 > /proc/sys/kernel/grsecurity/chroot_deny_pivot
echo 1 > /proc/sys/kernel/grsecurity/chroot_enforce_chdir
echo 1 > /proc/sys/kernel/grsecurity/chroot_deny_chmod
echo 1 > /proc/sys/kernel/grsecurity/chroot_deny_fchdir
echo 1 > /proc/sys/kernel/grsecurity/chroot_deny_mknod
echo 1 > /proc/sys/kernel/grsecurity/chroot_deny_shmat
echo 1 > /proc/sys/kernel/grsecurity/chroot_deny_unix
echo 1 > /proc/sys/kernel/grsecurity/chroot_findtask
echo 1 > /proc/sys/kernel/grsecurity/chroot_restrict_nice
echo 1 > /proc/sys/kernel/grsecurity/chroot_deny_sysctl
echo 1 > /proc/sys/kernel/grsecurity/chroot_caps


# Audit
echo 0 > /proc/sys/kernel/grsecurity/audit_group
echo 0 > /proc/sys/kernel/grsecurity/exec_logging
echo 0 > /proc/sys/kernel/grsecurity/chroot_execlog
echo 0 > /proc/sys/kernel/grsecurity/audit_chdir
echo 0 > /proc/sys/kernel/grsecurity/audit_mount
echo 0 > /proc/sys/kernel/grsecurity/audit_ipc
echo 0 > /proc/sys/kernel/grsecurity/signal_logging
echo 1 > /proc/sys/kernel/grsecurity/forkfail_logging
echo 1 > /proc/sys/kernel/grsecurity/timechange_logging

# Exécutable protections
echo 1 > /proc/sys/kernel/grsecurity/execve_limiting
echo 1 > /proc/sys/kernel/grsecurity/dmesg
echo 1 > /proc/sys/kernel/grsecurity/rand_pids
echo 0 > /proc/sys/kernel/grsecurity/tpe
echo 0 > /proc/sys/kernel/grsecurity/tpe_restrict_all

# Network Protections
echo 1 > /proc/sys/kernel/grsecurity/rand_ip_ids
echo 1 > /proc/sys/kernel/grsecurity/rand_tcp_src_ports
echo 1 > /proc/sys/kernel/grsecurity/rand_rpc
echo 1 > /proc/sys/kernel/grsecurity/altered_pings
echo 0 > /proc/sys/kernel/grsecurity/socket_all
echo 0 > /proc/sys/kernel/grsecurity/socket_client
echo 0 > /proc/sys/kernel/grsecurity/socket_server

echo Verrouillage...
echo 1 > /proc/sys/kernel/grsecurity/grsec_lock
echo Done

Il faut ensuite penser à rendre le script exécutable et illisible par d'autres utilisateurs que root:

chmod 700 /etc/init.d/grsec

Puis créer un lien dans /etc/rc2.d vers ce script pour qu'il s'exécute automatiquement au démarrage:

cd /etc/rc2.d ; ln -s /etc/init.d/grsec S90grsec

Maintenant il ne vous reste plus qu'à rebooter et voir si tout fonctionne comme vous le souhaitez.

III) L'utilisation de gradm et de l'ACL

L'utilisation de gradm et des ACLs n'est pas obligatoire pour avoir la protection de
grsec, et à moins que vous n'ayez besoin d'une sécurité des plus absolue
sur votre système, il me semble peu probable que vous décidiez de
l'utiliser (d'où le fait qu'il se trouve dans une partie à part).

Le but de l'ACL (Access Control List) est de limiter les droits de tout les utilisateurs autant que possible.

L'ACL permet notamment de préciser pour chaque répertoire, des modes d'accès précis (lecture seule, lecture/écriture, etc...) ainsi que de préciser des exceptions pour certains programmes.
Il permet aussi de spécifier pour chaque programmes des ressources plafonds ainsi que tout un tas d'autres trucs, dont certaines protections pour certaines processus particulier, la limitation de la capacité de certains processus, etc...

En fait, tout ça se résume plutôt bien dans la définition de ACL:
Access Control List.

Je vais être honnête, je ne l'ai pas mis en application (trop long à configurer, et le fait de devoir discuter de l'installation de chaque programme avec GrSec ne m'enchantait pas vraiment)

Ce document n'étant qu'une traduction (plus ou moins partielle) du document http://www.grsecurity.org/gracldoc.htm , je ne peux que vous recommandez d'aller le voir.

* 1ère étape : Apt-get

apt-get install gradm

(notez la difficulté de cette étape)

* 2ème étape : Mettre un mot de passe sur le système ACL de GrSec

gradm -P

(Encore une fois, c'est super dure)

* 3ème étape : Configurer le /etc/grsec/acl
Là par contre, ça rigole déjà moins...
Il faut savoir que le paquetage gradm contient déjà un fichier /etc/grsec/acl. Vous pouvez donc le reprendre et l'adaptez à vos besoins, ceci étant sans doute plus simple, vu que gradm vérifie que ce fichier n'autorise pas tout et n'importe quoi.
Je vous recommande d'ailleurs d'aller voir le /etc/grsec/acl fourni avant de lire la suite de cet article, dans le but d'avoir une meilleure idée de ce que ça donne en pratique.

Le fichier est formé de cette manière:

include <"fichier à inclure">

"chemin du sujet" "modes du sujet (optionnel)"
{

# Commentaire
  "fichier ou répertoire objet" "modes de l'objet"

  [+|-]"capacité"

  "nom de la ressource" "limite basse" "limite haute"

  connect {
    "ip"/"netmask":"port inférieur"-"port supérieur" "type" "protocole"
  }

  bind {
    "ip"/"netmask":"port inférieur"-"port supérieur" "type" "protocole"
  }

}

Il faut savoir que l'ACL applique un principe d'héritage:
Par exemple ce qui s'applique au répertoire "/usr" s'appliquera aussi à ses sous-répertoires comme "/usr/bin", et ceci, à moins que ne soit explicitement donner des règles pour le sous-répertoire en question.

L'ACL supporte aussi les 'wildcards' telles que "?" et "*", par exemple "/dev/tty*". Ces 'wildcards' ne prennent effet que sur les fichiers présent au moment où le système ACL est activé.

Explication morceau par morceau:
Les commentaires:
Mettez simplement une # en début de ligne

"fichier à inclure":
GrAdm permet d'inclure des fichiers contenant eux-mêmes d'autres portions de la config. Cela permet de répartir la configuration sur plusieurs fichiers, la rendant parfois plus lisible. Normalement les "include" peuvent être mis n'importe-où dans le /etc/grsec/acl.

"chemin du sujet":
Le sujet peut être soit "/" et donc dans ce cas-là il s'agira de préciser les accès possible pour les programmes par défaut, soit être un programme, tel que "/sbin/init" par exemple, et il s'agira alors de définir les accès auquel lui a droit.
Vous _devez_ avoir un sujet "/" quelque part dans votre fichier.

"mode du sujet":
Il faut savoir que si vous ne précisez pas de mode (aussi bien pour le sujet que pour l'objet), les accès "FIND" (stat, chdir, filldir, etc...) seront permis, mais aucun autre accès ne sera permis.
h - Ce processus est caché et est seulement visible par les processus ayant le mode v.
v - Ce processus peut voir les processus cachés
p - Ce processus est protégé: Il peut seulement être tuer par un processus avec le mode k
k - Ce processus peut killer les processus protégés
l - Active le mode d'apprentissage pour ce processus
d - Protège les entrées /proc/"pid"/fd et le /proc/"pid"/mem des processus dans ce sujet
b - Active la comptabilité pour les processus dans ce sujet
P - Désactive la fonctionnalité "Paging based non-executable pages" dans ce sujet (voir la configuration de votre kernel)
S - Désactive la fonctionnalité "Segmentation based non-executable pages" dans ce sujet
M - Désactive la fonctionnalité "Restrict mprotect()" dans ce sujet
R - Désactive la fonctionnalité "Randomize mmap() base" dans ce sujet
G - Active la fonctionnalité "Emulate trampolines" dans ce sujet
X - Active la fonctionnalité "Randomize ET_EXEC base" dans ce sujet
O - Outrepasse les restrictions additionnelles de mmap() et ptrace() dans ce sujet
A - Protège la mémoire partagée de ce sujet. Aucun processus hors de ce sujet ne pourra accéder à la mémoire partagée.
K - Quand les processus internes à ce sujet génèrent une alerte, tuer les processus.
C - Quand les processus internes à ce sujet génèrent une alerte, tuer les processus et repérer l'IP de l'attaquant s'il y avait une ip connecté au processus.
T - S'assure qu'un processus ne pourra jamais exécuter un code de troyen
o - Outrepasser le système d'héritage de l'ACL

"fichier ou répertoire objet":
Fichier ou répertoire auxquels le programme spécifier en tant que sujet tentera sans doute d'accéder (les modes suivants définissants ses droits d'accès). Si le sujet est "/", alors il s'agira des accès possible par défaut aux programmes.

"modes de l'objet":
r - Cet objet peut être ouvert en lecture
w - Cet objet peut être ouvert en écriture
x - Cet objet peut être exécuté
a - Cet objet peut être ouvert en mode "ajout"
h - Cet objet est caché
t - Cet objet peut être ptraced (cf ptrace()), mais ne peut pas modifié la tâche en cours. "ptrace read-only" fait référence à ceci.
s - Les accès refusés à cet objet ne seront pas loggués.
i - Ce mode s'applique seulement au binaires: Quand l'objet est exécuté, il hérite des modes du sujet dans lequel il est contenu.
R - Log les accès en lecture réussis sur cet objet
W - Log les accès en écriture réussis sur cet objet
X - Log les exécutions réussi de cet objet
A - Log les ajouts réussi à cet objet
F - Log les "finds" réussi à cet objet
I - Log si l'héritage ACL de cet objet a réussi

Rappel:
Les modes s'appliquant sur "/bin" s'appliquent aussi sur "/bin/su" à moins que vous ayez préciser des modes pour "/bin/su". Pour plus de détails sur le fonctionnement de l'héritage, je vous recommande d'aller voir http://www.grsecurity.org/gracldoc.htm (et oui, c'est en anglais :P)

Note:
Le mode "i" pour les objets aura seulement un effet si l'application fait un fork() puis un execve() ou juste un execve(): Le mode "i" n'a donc aucun effet si l'application utilise la fonction system() (qui d'ailleurs est Mal(tm))

"[+|-] capacité":
Pour obtenir la liste complète des capacités, je vous recommande d'aller voir le document officiel: http://www.grsecurity.org/gracldoc.htm (vous ne pouvez pas les rater, c'est à la fin du document)

"nom de la ressource":
Utilisé pour limiter l'usage des ressources. Voici la liste des ressources limitables:
RES_CPU - Temps CPU en millisecondes
RES_FSIZE - Taille du fichier en octets
RES_DATA - Taille d'une donnée en octets
RES_STACK - Taille du tampon en octets
RES_CORE - Taille du core en octets
RES_RSS - Taille de la mémoire résidente utilisée
RES_NPROC - Nombre de processus
RES_NOFILE - Nombre de fichiers ouverts
RES_MEMLOCK - Taille de la mémoire verrouillée en octets
RES_AS - Espace d'adressage limite en octets
RES_LOCKS - Nombre de fichiers verrouillés
Les concepteurs suggèrent de garder surtout un oeil sur le nombres de fichiers, l'espace d'adressage limite, et le nombre de processus.
RES_CPU est la seule ressource acceptant le temps comme limite, par exemple:
100s = 100 secondes
25m = 25 minutes
65h = 65 heures
2d = 2 jours
Les autres ressources utilisent soit un nombre seul ou une taille en octets:
Tous peuvent être données en K (kilo), M (Méga), ou en G (Giga), que ce soit des octets ou de simple nombres.
Une autre valeur possible est "unlimited".

GrSecurity propose aussi une fausse ressource, dont le but est de limiter le nombre de plantage d'un programme:
RES_CRASH "nombre de crashs" "intervalle de temps"
Par exemple:
RES_CRASH 1 30m
empêchera le programme d'être exécuter pendant 30min après un plantage.
Il faut savoir que si le programme est lancé par un utilisateur normal, tout les processus de cet utilisateur seront killé, et il ne pourra se logguer pendant l'intervalle de temps défini. Si ce programme/processus n'est pas s[u|i|g]id (donc par exemple s'il est lancé par root), alors seul ce programme sera tué, et sera inexécutable pendant l'intervalle de temps.

L'ACL pour l'IP:

[connect|bind] {
    "ip"/"netmask":"port_inférieur"-"port_supérieur" "type" "proto"
    "ip"/"netmask":"port_inférieur"-"port_supérieur" "type" "proto"
    [...]
}

"connect" permet de préciser les ips auxquelles à le droit de se connecter le processus.
"bind" permet de préciser sur quelle ip ont le droit de se connecter d'autres hôtes.

"ip":
Si vous avez choisi connect, alors il s'agit des ips sur lesquels peut se connecter le processus.
Si vous avez choisi bind, alors il s'agit de l'ip sur laquelle le processus est autorisé à écouter (donc l'ip de l'interface).

"netmask":
Il s'agit du masque réseau allant de paire avec l'ip. S'il est omis, la valeur par défaut est 32.

"port_inférieur"-"port_supérieur":
Intervalle de ports sur lesquels la connexion est autorisé. Si port_supérieur est omis, alors "port_inférieur" et "port_supérieur" prendront tout deux la valeur de "port_inférieur". Si les deux sont omis, 0 est utilisé pour "port_inférieur" et 65535 pour "port_supérieur".

"type":
Peut prendre comme valeur: "stream" (Tcp), "dgram" (Udp), "raw_sock" (Raw), ou "any_sock" (n'importe lequel).

"proto":
Peut prendre comme valeur n'importe quel nom de protocole donné dans /etc/protocols, notamment "raw_proto" ou "any_proto".

Si vous voulez empêcher le programme de se connecter (connect) ou d'ouvrir un port (bind), vous pouvez utilisez "disabled".

Quelques exemple:

connect {
  disabled
}

bind {
  192.168.1.2/24:80 stream tcp
}

connect {
  192.168.1.2/24 stream dgram tcp udp
  134.55.22.12/24:1024-65535 any_type any_proto
}

Voici une ACL que ma donné une de mes connaissances pour permettre à apache de fonctionner, bien entendu, si vous décidez de l'utiliser, il faudra l'adapter à vos besoins:

/usr/sbin/apache {
         /dev/log                 rw
         /etc                     h
         /etc/passwd              r
         /etc/group               r
         /etc/apache              rx
         /etc/hosts               r
         /etc/hostname            r
         /etc/nsswitch.conf       r
         /etc/resolv.conf         r
         /etc/php4/apache/php.ini r
         /etc/mime.types          r
         /usr/lib/cgi-bin         rx
         /home                    h
         /var/www                 rx
         /var/log/apache          rwx
         /root                    h
         bind {
                 192.168.3.200:80-80 stream tcp
         }
}

(Merci à asyd :)

Recommandations au sujet de l'ACL:

Il s'agit de recommandations faite par les concepteurs dans la documentation officielle:
- Essayer de retirer autant que possible des droits par rapport à ce que propose l'ACL fourni par défaut avec le paquetage gradm. Le plus vous en retirez, le plus root agira comme un utilisateur courant. Le plus de droits vous retirerez, le plus d'ACLs vous aurez à créer pour les programmes ayant besoin de ces droits.
- Utilisez les ACLs dans le répertoire "debian_secure_acls" de gradm si possible.
- Utilisez le mode apprenant. Il peut créer des ACLs mieux que vous.
- Les programmes administratifs, comme l'arrêt ou le redémarrage, devrait nécessiter une authentification plutôt que de donner à n'importe qui le droit de les lancer. Vous pouvez le faire en créant une ACL pour /sbin/shutdown, et en le rendant caché par tout les processus en mettant /sbin/shutdown h comme un objet dans votre ACL pour "/". Alors la seule manière que vous aurez d'accéder aux privilèges spéciaux de /sbin/shutdown sera d'entrer en mode administratif avec gradm -a (voir plus loin).
- Familiarisez-vous avec les capacités de Linux et et ce qu'elles permettent. Une liste et des descriptions de chacune de ces capacités est présenter à la fin de ce document: http://www.grsecurity.org/gracldoc.htm et aussi dans include/linux/capability.h du code source du noyau Linux.

Si vous souhaitez d'autres exemples d'ACL, sachez que des exemples sont donnés à la fin du document http://www.grsecurity.org/gracldoc.htm.

* 4ème étape: Utilisation de gradm
C'est bien beau d'avoir fait des ACLs à la pelle, maintenant, reste à s'en servir.

Voici une rapide description des options à donner à la ligne de commande à gradm (oui, je sais, vous pouvez facilement l'obtenir en faisant "gradm --help")

-E : Active le système d'ACL
Lorsque que vous utilisez cette option, GrAdm vérifie d'abord vos ACLs pour être sûr qu'il n'y ait pas de faille de sécurité potentielles.
-R : Relance le système ACL (marche seulement en mode d'administration)
-M <nom de fichier|uid> : Enlève une interdiction d'exécution sur un fichier ou sur un utilisateur (cf RES_CRASH)
-L <fichier de log> : Examine les logs d'apprentissage: Accepte un argument optionnel qui spécifie quel fichier log du noyau scanner. Les logs d'apprentissage sont enregistrés via syslog avec un niveau d'INFO. Si aucun argument n'est spécifier, gradm scannera votre /etc/syslog.conf pour trouver des logs à scanner. Cette option doit être utilisé avec -O
-O <nom de fichier|flux> : Spécifie le fichier de sortie pour les ACLs générés grâce au mode d'apprentissage. Les noms possibles sont "stdout", "stderr" ou un nom de fichier. Seulement utilisé avec -L
-D : Désactive le système d'ACL (généralement, quand on a besoin de cette commande, c'est qu'on ne peut déjà plus s'en servir)
-T <sujet> <objet> : Affiche les permissions pour un objet en fonction de son sujet.
-P : Réglage du mot de passe du système ACL (normalement vous l'avez déjà fait).
-a : Permet d'obtenir pour l'utilisateur en cours les pleins droits d'administration (aka admin mode)
-v : Affiche les informations concernant la version de gradm/grsec.

Seul le changement de mot de passe n'est pas possible en mode admin.

* 5ème étape: Le mode "apprenant"

Comme vous avez pu le constater, gradm offre la possibilité de générer des ACLs à partir des logs. Évidemment, c'est comme quand on voit le mot "gratuit", le premier réflexe est de se dire qu'il y a un piège quelque part ... on va voir ça ...

- Pour utiliser le mode apprenant, il suffit d'ajouter le mode "l" au sujet du processus pour lequel vous voulez activer l'apprentissage.
- Activez ensuite le système ACL
- Lancez l'application concernée plusieurs fois (selon la doc officielle le "plusieurs fois" est important).
- Si 4 accès ou plus sont fait dans un seul même répertoire, l'application obtiendra l'accès complet au répertoire.
- Une fois que vous avez lancé l'application et que vous l'avez utilisé de manière habituelle, désactiver le système ACL (gradm -D ou gradm -a, au choix)
- Taper ensuite

gradm -L -O /etc/grsec/acl

Ceci va placer la nouvelle ACLs apprises grâce aux logs à la fin du /etc/grsec/acl.
- Il suffit ensuite de simplement retirer l'ancienne ACL, et c'est fini.

Personnellement, je vous recommanderais tout de même de regarder avant ce qu'à produit le mode d'apprentissage en créant d'abord l'ACL dans un fichier à part.

Bien, maintenant que vous avez tout lu, je pense que je peux vous dire qu'il s'agit en fait de mon tout premier article.
Dans l'éventualité où j'aurais fait une erreur dans cet article, je vous prierais de me contacter par email ( jflesch@nerim.net ), merci d'avance.

IV) Quelques liens utiles

http://www.grsecurity.org/
- Le site officiel

http://pageexec.virtualave.net/
- Le site officiel de PaX (et de chpax). GrSecurity utilise PaX pour toutes les options en rapport avec les pages mémoires non-exécutables, l'adressage aléatoire en mémoire, etc...