Un protocole réseau permet aux ordinateurs d'échanger des
données dans une sorte de 'langue' commune, indépendante du
système d'exploitation sous-jacent. Cette langue concerne surtout
l'acheminement des données, et non leur signification. IP
(l'Internet Protocol) est donc en quelque sorte l'un
des 'services postaux' utilisables (d'autres protocoles existent, mais IP est
le plus répandu car tout l'Internet repose sur lui). Il permet à
une machine d'expédier des données, mais il appartiendra aux
programmes de les interpréter.
La « pile » IP est un groupe de protocoles interdépendants car chacun d'eux s'appuie sur un ou plusieurs autres, c'est pourquoi on emploie le mot « pile » pour désigner une implantation.
IP crée des tuyaux virtuels entre toutes les interfaces interconnectés. Par 'interface' on entend 'organe grâce auquel une machine se trouve connectée à un réseau', par exemple une carte Ethernet ou un lien PPP reposant sur un modem. Chaque machine peut disposer d'un nombre quelconque d'interfaces. Chaque interface peut correspondre à plusieurs numéros IP.
Chaque interface raccorde l'hôte à au moins un type de support. Il s'agit le plus souvent d'un câble coaxial ou d'une paire torsadée (pour l'Ethernet) mais aussi, de plus en plus souvent, de divers autres types de couches physiques : modem, fibre optique, antenne, émetteur/récepteur infrarouge, laser, réseau électrique ...
Grâce à TCP/IP les développeurs réalisent des programmes exploitant le réseau sans se soucier des caractéristiques de la couche physique car le protocole ajoute des niveaux d'abstraction salvateurs.
TCP/IP propose aux programmes deux modes (principaux) d'acheminement des données : UDP et TCP. Le premier se contente d'acheminer les paquets de données, sans vérifier leur séquencement (ordre d'arrivée correspondant à l'ordre d'émission) ou bonne réception. TCP, lui, est plus sûr, car il garantit le séquencement et la bonne réception, mais aussi plus lourd.
Pour expédier des données via TCP/IP un logiciel utilise des fonctions du système relativement simples auxquelles il précise l'identité de la machine destinatrice (son nom ou numéro IP, cela revient au même), le type de protocole souhaité (TCP ou UDP, le plus souvent) et un numéro de « port » sur lequel la connexion sera établie.
Le système accorde alors au programme une sorte de jeton associé à la connexion ainsi établie. Le programme peut l'utiliser pour y écrire ou lire, presque comme dans un fichier. Unix s'occupe de tout. Ceux qui maîtrisent le langage C pourront lire à ce propos Les sockets - Initiation
Le port s'apparente aux numéros de postes des téléphones affectés aux divers services d'une entreprise, où chacun détermine à qui faire appel en fonction du service attendu.
Un 'service', sous Unix, est un ensemble de fonctions offertes par une machine. Cela peut concerner l'échange de fichiers, le courrier électronique, la mise à l'heure des machines ...
De nombreux services sont offerts « sur » (lire 'via') TCP/IP. Tout programme installé sur une machine du réseau peut donc en bénéficier en contactant le serveur, via le réseau. C'est très exactement ainsi que fonctionne le Web, par exemple : des paquets IP circulent entre le serveur Web et le 'browser' (client).
Même un programme client installé sur le serveur procédera exactement comme s'il se trouvait à distance. Il interagira avec un serveur nommé "localhost", "127.0.0.1" ou bien "le-nom-de-la-machine-locale" (qui désignent tous la machine locale), et les paquets emprunteront donc une interface 'loopback', spécialement chargée de convoyer les paquets entre deux programmes installés sur la même machine. Cela semble étrange mais est en fait élégant car n'oblige pas les programmes clients et serveurs à fonctionner différemment selon que le serveur est ou non local.
Chaque port TCP ou UDP d'une machine donnée peut correspondre
à un service, par exemple FTP ou telnet, offert sur le serveur par un
logiciel adéquat. Chaque service porte un nom, et la liste des
affectations de ports aux divers noms de services se trouve dans le fichier
/etc/services. Une RFC (un document figeant des conventions)
dresse liste des affectations recommandées. Le service
telnet, par exemple, emploie par défaut le port TCP
numéro 23. Rien n'oblige un administrateur de machine à
respecter ces conventions.
Tout cela reste en fait un peu plus compliqué et plus souple, mais un plus détaillé serait inutile ici.
Il existe deux façons d'ajouter un service à une machine donnée.
La première consiste à lancer le logiciel chargé de
l'assurer, en lui permettant de 'se lier' (fonction bind()) au
port puis d'y 'écouter' (fonction listen) les demandes des
clients. Divers
documents traitent de tout cela. Le logiciel serveur ainsi lancé en
mode « démon » fonctionnera tout le temps, ce qui peut
inquiéter (consommation de mémoire vive et de puissance
processeur) mais Unix est bien conçu : les tâches inactives
descendent dans la mémoire virtuelle (et n'occupent donc pas
indûment de la mémoire vive) et ne s'arrogent pas de puissance
processeur car le noyau ne les « réveille » qu'en cas de
détection d'activité sur le port concerné (donc lorsqu'un
client demande quelque chose). Sur la plupart des serveurs ces démons
sont lancés, lors du démarrage de la machine, par le programme
init via les scripts placés sous etc/rc*.
L'autre approche met en scène inetd, le «
superserveur ». Ce démon écoute tous les ports et, en cas
d'activité, lance le programme serveur adéquat, qui servira la
(ou les) requête(s) puis s'interrompra. Grâce à
inetd il n'est donc pas nécessaire de laisser
simultanément actifs tous les programmes serveurs. Le fichier
/etc/inetd.conf abrite ses paramètres.
Passons aux travaux pratiques. Nous allons utiliser un programme capable de
rendre compte des paquets IP échangés. Le plus connu,
livré avec la plupart des systèmes Unix, se nomme
tcpdump. Nous ne pourrons l'utiliser, dans un premier temps, car
il ne semble pas capable de pister les paquets échangés entre
des processus locaux (sur une même machine).
nommachine ~ telnet localhost Trying 127.0.0.1... Connected to nommachine Escape character is '^]'. Connection closed by foreign host.
nommachine ~ telnet localhost Trying 127.0.0.1... telnet: Unable to connect to remote host: Connection refused
montrer comment utiliser des outils de trace : tcpdump et un trafshow (pb avec la v2 de trafshow et PPP ) ou sniffit ou iptraf (chouette, mais bien lire la doc)
telnet localhost
Connexion PPP : invoquer ifconfig durant la session, qui
produit entre autres ceci :
ppp0 Link encap:Point-Point Protocol inet addr:votreIP
tcp votreIP 325 209.239.33.1 16482 40 44 tcp votreIP 323 209.239.33.1 16474 40 44 tcp votreIP 321 209.239.33.1 16460 40 44 tcp votreIP 322 209.239.33.1 16461 40 44
pb de nombreux softs serveurs :
Types de désagréments potentiels :
(EB et Nat) toujours utiliser des binaires (noyaux, outils système ...) à jour et de provenance sûre. S'abonner aux forums et listes (bugtraq, comp.security.announce, www.freshmeat.net) afin de rester informé.
éditer les runlevels de façon à supprimer TOUS les
démons dangereux non employés. En particulier sendmail, INN,
NFS, serveur de noms ... (Red Hat : control-panel puis
run-level editor)
(EB et Nat) Examiner, à partir d'une machine distante connectée au même réseau (cela fonctionne aussi sur l'Internet, y compris en dialup), les ports ouverts. Les outils "strobe" (sous debian, package 'netdiag') et nmap (excellente doc) permettent cela. Interdire l'accès aux ports inutilement exposés.
Vérification : se loger ailleurs et strober (ou demander à un pote sur une autre machine accessible, par exemple via l'Internet, de le faire)
durant les connexions : surveiller avec tcpdump ou l'outil de trace adopté
Mais certains programmes doivent parfois demeurer actifs sur le
système (par exemple sendmail, le serveur NFS, le
démon d'impression lpd). Il faut donc trouver un moyen de
ne pas laisser n'importe qui se connecter et converser avec ces programmes,
donc de ne pas laisser entrer sur le système des paquets
destinés à un certain port TCP ou paquets de provenance douteuse
(via une interface donnée ou bien en général).
Il faut donc pouvoir bloquer les agresseurs.
rôle du code firewalling du noyau (examine les paquets IP, applique des règles). rôle d'ipfwadm (maipulation des règles de firewalling)
Voici noip, un script à invoquer avec, en guise
d'argument, le numéro IP d'un agresseur :
(employer 'deny' à la place de 'reject' pour loger)#!/bin/sh ipfwadm -I -a reject -o -S "$1"/0 -D 0.0.0.0/0 -P all
ipfwadm -I -l -n
ipfwadm -I -f "flush"
il faut préciser la destination pour bloquer un port sur activité entrante !
bien lire ce que donne "ipfwadm -I -l -n"
pas plus de 10 slots (1 slot : 1 port ou 1 intervalle) par instruction ipfwadm (compi par dft)
Le programme 'ipfwadm' permet de configurer le mode de traitement des paquets IP assuré par le noyau.
ipfwadm : toujours compiler un noyau avec CONFIG_IP_ALWAYS_DEFRAG, et SYN COOKIES et "IP: drop source routed frames"
natix root ~ /sbin/ipfwadm -I -i deny -o -P tcp -S exemple.fr 80 natix root ~ /sbin/ipfwadm -I -l -n IP firewall input rules, default policy: accept type prot source destination ports deny tcp 123.123.123.123 0.0.0.0/0 80 -> * natix root ~ /sbin/ipfwadm -I -f natix root ~ /sbin/ipfwadm -I -i deny -o -P tcp -S toto.fr -D natix 80 natix root ~ /sbin/ipfwadm -I -l -n IP firewall input rules, default policy: accept type prot source destination ports deny tcp 192.168.1.6 192.168.1.4 * -> 80
on peut procéder par "ouverture" (tt est par dft interdit : on ferme tout, on dresse liste des besoins et on n'ouvre que les portes nécessaires) ou "fermeture" de portes
attention : tt cela ne tient que si les machines 'autorisées' sont elles-mêmes sûres. s'en assurer : ne pas considérer que celles de l'isp le sont par défaut, par exemple. mieux vaut laisser tourner un tcpdump sans filtrage
protéger par ipfw les hôtes d'un réseau local (par rapport au firewall principal)
satan-netscape.README qui va te permettre de faire fonctionner
ton browser avec Satan.ALL: ALL,PARANOID dans /etc/hosts.deny et
ALL: dans /etc/hosts.allow (si le système
n'est pas isolé, ajouter les systèmes autorisés)Ne fonctionne qu'avec un noyau intégrant le code
firewalling. Compiler un noyau refusant les fragments IP car le
le firewalling ne les traite pas.
Nous utiliserons surtout l'option -I (input), qui permet d'établir des règles de traitement des paquets entrants.
ipfwad suivante (règles
extraites des scripts de boot debian 2.0). Noyau 2.0 :
Noyau 2.1 :# refuser les paquets entrants prétendus issus de notre propre système ipfwadm -I -d deny -o -P all -S 127.0.0.0/0 -W eth0 -D 0/0 ipfwadm -I -i deny -o -P all -S 127.0.0.0/0 -W eth0 -D 0/0 my_ip=le numéro IP de la machine locale (hostname -i) ipfwadm -I -d deny -o -P all -S $my_ip -W eth0 -D 0/0 ipfwadm -I -a deny -o -P all -S $my_ip -W eth0 -D 0/0
Si#my_ip=le numéro IP de la machine locale (hostname -i) ipchains -D input -j DENY -p all -l -s 127.0.0.0/0 -i eth0 -d 0.0.0.0/0 ipchains -I input -j DENY -p all -l -s 127.0.0.0/0 -i eth0 -d 0.0.0.0/0 ipchains -D input -j DENY -p all -l -s $my_ip -i eth0 -d 0.0.0.0/0 ipchains -I input -j DENY -p all -l -s $my_ip -i eth0 -d 0.0.0.0/0
ipfwadm produit un message ipfwadm: setsockopt failed:
Protocol not available le noyau ne contient pas le code de
'firewalling', il faut recompiler.#interdire paquets prétendus issus de notre propre système ipfwadm -F -i deny -o -P all -S 127.0.0.0/0 -W ppp0 -D 0/0 #DEVNAT dialup : faut-il faire de mm avec le numéro IP dyna ? #accepter input vers DNS du serveur de noms ipfwadm -I -W ppp0 -a accept -o -P tcp -S IP-DNS-primaire 53 ipfwadm -I -W ppp0 -a accept -o -P tcp -S IP-DNS-secondaire 53 ipfwadm -I -W ppp0 -a accept -o -P udp -S IP-DNS-primaire 53 ipfwadm -I -W ppp0 -a accept -o -P udp -S IP-DNS-secondaire 53 #interdire accès aux serveurs de noms, de news, et X (6000) #au serveur Web ou mandataire (8080, 8081), mail (25) ipfwadm -I -a reject -o -P tcp -W ppp0 -S 0/0 -D 0/0 25 53 80 113 119 6000 8080 8081 ipfwadm -I -a reject -o -P udp -W ppp0 -S 0/0 -D 0/0 25 53 80 113 119 6000 8080 8081 #et autres services ... ipfwadm -I -a reject -o -P udp -W ppp0 -S 0/0 -D 0/0 13 19 39 ipfwadm -I -a reject -o -P tcp -W ppp0 -S 0/0 -D 0/0 13 19 39 #attention ! de nombreux ports potentiellement dangereux demeurent ainsi #ouverts. vérifier la config, par exemple grâce à un scanner (strobe ...) Attention : ne pas « scanner » une autre machine que la vôtre sans autorisation préalable de son administrateur. Des programmes peuvent détecter ce genre d'activité, ce qui peut alarmer les responsables du site. #accounting ipfwadm -A -f ipfwadm -A in -i -W ppp0traiter des routeurs (tables, capacité de droper des paquets, comme le code de firewalling mais généralement + rapide car matos dédié)
ssh plutôt que telnet et les
commandes 'r' (rcp, rsh, rlogin)/etc/inetd.conf et ne pas laisser inetd
fonctionner (Red Hat : éditer /etc/rc.d/init.d/inet,
ajouter un "exit 0" au début)ssh). ATTENTION :
une autorisation est parfois requise, se renseigner au préalable.tcpdump, durant les connexions à l'Internet,
pour capturer tout paquet issu de domaines inconnus. Par exemple en
plaçant dans le script de démarrage de session PPP (souvent
/etc/ppp/ppp-on) la commande :
xterm -display unix:0.0 -e tcpdump -l -p -i ppp0|grep -v ' Nom-Proxy-Du-Fournisseur\.Numéro-Port[ :]' noter les espaces. ne matchera pas un sous-domaine (mode PARANO !)
x ainsi défini :
alias x='(startx >/dev/null &);clear;logout'
startx. Mais sa
session de travail en mode console demeure accessible à quiconque peut
accéder à son clavier. Elle permet de retrouver la session shell
grâce à laquelle il invoqua X. Un pirate pourra par exemple (ces
manoeuvres ne sont pas dangereuses, les essayer si nécessaire, afin de
bien comprendre) :
Contrôle-Alt-F1 pour retrouver le shell. cela
lui donnera satisfaction même si un programme de verrouillage de la
session X Window fonctionneContrôle-Z et introduire bg. ou
bien le tuer (Contrôle-C suffit)x ici proposé lance X Window puis «
déloge » l'utilisateur afin de ne pas laisser la session en mode
console. On peut aussi modifier startx de sorte qu'il ne laisse
pas de terminal inactif. Autre solution : employer xdm.xauth et
mcookie). (EB) Ne jamais utiliser xhost.xterm (EB) Passer en
mode secure keyboard pour composer un mot de passe. Pour cela :
cliquer sur Contrôle-bouton 1 et sélectionner cette
option. L'affichage du terminal doit passer en vidéo inverse et cela ne
doit pas émettre de son d'alarme. Composer le mot de passe puis
procéder de même pour débrayer le mode
sécurisé.xdmXF86Config afin d'interdire à un mauvais plaisant
d'avorter une session X Window par Contrôle-Alt-BackspaceExplorer les sites de "crackers" (ne pas confondre avec "hackers"). Ne pas y télécharger de logiciel (attention aux chevaux de Troie !).
HOWTO et FAQ Linux pertinents :
Quelques sites intéressants :