Niveau :
Résumé : tcpwrappers ; hosts.allow ; hosts.deny
Le contrôle d'accès est généralement fourni par l'application qui fournit un service. Pour le contrôle de l'identité cette application utilise en général pam, mais de nombreuses applications effectuent des contrôles sur d'autres éléments que l'identité de la personne et en particulier le réseau. Tout comme pam il existe une bibliothèque qui s'occupe de ceci pour éviter au développeur de mal faire plusieurs choses. Parlons de tcpwrappers.
Les bases
La bibliothèque tcpwrappers permet à une application de disposer d'un contrôle du client à moindre frais. Ses deux fichiers de configuration sont /etc/hosts.allow et /etc/hosts.deny. Sa méthode de fonctionnement est très simple. Si un client a une correspondance dans hosts.allow, il est autorisé à entrer, sinon s'il a une correspondance dans hosts.deny, il est refusé, et enfin s'il ne matche aucune règle, il est accepté.
Le format de ces fichiers est assez simple :
# service : client sshd : 127.0.0.1
Vous pouvez remplacer le nom du service (du démon) par ALL, qui matche tous les services utilisant tcpwrappers, ou par un numéro de port (22).
Pour le nom du client, le système de matching est assez évolué. Vous pouvez donner un nom de machine (machine.toto.fr), un nom de domaine (.toto.fr), un réseau (10.0.0.0/24), un netgroup NIS (@groupe), une IPv6 (1:2:3:4:5:6:7:8/64) ou même une liste en provenance d'un fichier un peu plus complet (/etc/deny). Les wildcards shell fonctionnent aussi dans ces règles (*.toto.fr). Notez que si le serveur dns est indisponible, les règles basées sur les noms ne matchent pas, donc en l'absence de règles sur l'ip, l'accès sera au final autorisé.
Des alias existent aussi pour les clients, les plus importants sont ALL (tout le monde), LOCAL (attention, il ne fait pas exactement ce à quoi on s'attend, il matche les machines dont le nom n'a pas de domaine), et PARANOID (on vérifie que le dns direct et reverse correspondent).
Une configuration un peu plus avancée
Mais je ne vous ai pas tout dit sur ces fichiers. Ils admettent en réalité une syntaxe un peu plus évoluée
# service : [user@]client [ : option [ : option ... ] ] sshd : peck@127.0.0.1 : ALLOW
User permet de vérifier l'utilisateur grâce au protocole ident. Il n'y a plus guère qu'irc qui fasse ce genre de vérifications.
Les options permettent quelques petites astuces sympa : on peut par exemple utiliser allow et deny qui permettent de mettre toutes les règles dans un seul fichier.
On peut aussi lancer un script qui fera une vérification un peu plus poussée.
# autoriser les gens qui répondent au ping sshd : ALL : aclexec /bin/ping -n -W 1 -c 1 %a : ALLOW
La liste des substitutions %<X> possibles se trouve dans le man hosts_access.
Attention tcpwrappers ne gère pas proprement les substitutions d'ip lorsque votre système dispose d'ipv6. C'est pourquoi ce genre de règles risque de vous poser problème, évitez les si vous pouvez, et logguez ce que vous faîtes sinon, un debug risque d'être utile un jour.
Deux autres options avancées permettent de faire bien d'autres choses intéressantes. Vous pouvez lancer un script arbitraire à chaque connexion (vous vouliez recevoir un mail à chaque fois qu'un client se connecte chez vous ? ou faire un compteur ...), ceci grâce à l'option spawn. L'option twist permet quant à elle de remplacer le vrai serveur par une autre commande. Par exemple, vous pouvez écrire un message d'erreur particulier à tous les gens qui tentent de se connecter en http depuis l'ip de votre concurent.
Le man de hosts_options vous donnera un détail complet de ces options étendues.
Lorsque vous voulez tester une de vos règles, vous avez la chance d'avoir une commande qui vous dira tout de suite qui matche et qui ne matche pas :
$ tcpdmatch sshd 127.0.0.1
Malheureusement, tcpdmatch ne fait qu'un match sur les règles et ne lance aucun script des options étendues. Donc si vous avez des règles aclexec, cela ne correspondra pas nécessairement à la réalité.
Comment faire ?
Intéressons nous à un exemple ou deux de configuration.
Si vous voulez être restrictif (par exemple pour un accès ssh), commencez par interdire tout le monde ;
# /etc/hosts.deny sshd : ALL
Puis autorisez au compte goutte dans le hosts.allow :
# /etc/hosts.allow sshd : 127.0.0.1 , .mondomaine.com
S'il s'agit d'un service public, vous préférerez sûrement une solution de type blacklist, mettez dans le hosts.deny la liste des ip que vous voulez interdire. Pour un système de blacklist évolué (le greylist est aussi imaginable en ftp :-) pensez aux options aclexec et twist :
# /etc/hosts.deny ftp : ALL : aclexec /usr/local/bin/greylist %a : twist /usr/local/bin/ftpdeny %a
Mais qui utilise vraiment tcpwrapper ?
Le problème dans le monde libre c'est que tant que le système ne force pas l'utilisation de quelque chose, c'est l'anarchie. Donc vous ne savez pas à l'avance quel service utilise ou n'utilise pas tcpwrappers. Pour le savoir vous avez plusieurs solutions : regarder la doc (bof), regarder la conf (mieux) ou regarder le binaire.
Supposons que votre service soit ssh, dans ce cas, nous allons regarder le binaire ssh :
$ ldd /usr/sbin/sshd | grep libwrap
Et en effet, ssh utilise tcpwrapper.
Pour les services qui ne tournent pas en démon (c'est à dire qu'ils sont lancés par inetd), la réponse est simple : s'ils passent par tcp, ils utilisent tcpwrapper; sinon non. Et cela se lit directement dans la ligne de configuration inetd dans la commande d'exécution :
# /etc/inetd.conf ftp stream tcp nowait root /usr/sbin/tcpd /usr/sbin/proftpd
Comments