Serveur et client TFTP

De Wiki info-lab.fr
Aller à : Navigation, rechercher

Sommaire

Présentation

Le service TFTP (Trivial File Transfer Protocol) est en général utilisé pour le téléchargement ou la sauvegarde de fichiers de configuration, firmwares, et systèmes d'exploitation sur des équipements de type routeurs, commutateurs, TV box, Téléphones IP, bornes d'affichage...

Installation sur Ubuntu 10.04 et ultérieur

Les paquets nécessaires sont xinetd (super daemon réseau), tftp (le client) et tftpd (le serveur).

# apt-get install xinetd tftp tftpd

ou

$ sudo apt-get install xinetd tftp tftpd

NOTA : Pour l'amorçage de systèmes d'exploitation via PXE, le paquet tftp-hpa est préférable à tftp.

Configuration du serveur TFTP sur Ubuntu

  • Pour configurer le serveur il faut créer son fichier de configuration et l'éditer :
$ sudo vi /etc/xinetd.d/tftpd
service tftp
{
protocol     = udp
port         = 69
socket_type  = dgram
wait         = yes
user         = nobody
server       = /usr/sbin/in.tftp
server_args  = /tftpboot
disable      = no
interface    = 192.168.0.25     (optionnel : à préciser si plusieurs interfaces existent et qu'on en autorise qu'une)
only_from    = 175.14.19.0/24     (optionnel : plage d'adresse autorisées à se connecter)
}
  • Enregistrer et quitter.
  • Puis créer le répertoire d'accueil et lui attribuer les droits :
$ sudo mkdir /tftpboot
$ sudo chmod -R 777 /tftpboot
$ sudo -R nobody /tftpboot
  • Relire la configuration de xinetd :
$ sudo /etc/init.d/xinetd reload           (variante : service xinetd reload)
  • Vérifier que le service est bien en écoute :
$ sudo netstat -lataupen | grep xinetd
udp  0   0   0.0.0.0:69     0.0.0.0:*    0  numéro-d'inode  PID/xinetd 
  • Pour gérer le fonctionnement de xinetd :
$ sudo /etc/init.d/xinetd [reload,stop,start,restart]
  • Pour désactiver tftp sans le désinstaller, éditer son fichier de configuration (/etc/xinetd.d/tftpd), modifier la ligne disable = no en disable = yes et relire la configuration de xinetd.

Sécurité TFTPD Ubuntu

La sécurité du protocole TFTP étant inexistante (aucune identification/authentification, commandes et transferts en clair, pas de quota...), certaines protections ont été mises en place sur les systèmes *nix, pour le sécuriser à minima :

  • nobody, l'utilisateur propriétaire du dossier /tftpboot est très limité en droits : Il n'a pas de répertoire de connexion, et il appartient à un groupe (nogroup) qui n'a de privilège particulier sur aucun fichier du système.
  • L'envoi d'un fichier dans le dossier /tftpboot nécessite d'abord de le créer puis d'autoriser sa modification :
$ sudo touch /tftpboot/monfichier
$ sudo 777 /tftpboot/monfichier

TFTP bénéficie donc de 2 mécanismes de sécurité : des droits utilisateur réduits et une intervention humaine obligatoire pour pouvoir téléverser des fichiers vers le serveur (sinon rien n'empêche de saturer la partition accueillant /tftpboot en envoyant le maximum de fichiers possibles vers le serveur).

Installation sur Debian 6 Squeeze et ultérieur

L'utilisation de XINETD à la manière d'Ubuntu peut ne pas fonctionner sur Debian 6 et plus. Alternative : utiliser openbsd-ined à la place.

# aptitude install tftp tftpd openbsd-inetd

(openbsd-inetd et xinetd ne peuvent coexister, l'installation de l'un entraine la suppression de l'autre).
Traditionnelement, OPENBSD-INETD considère que si TFTPD est utilisé, son répertoire par défaut est /srv/tftp ; rien n'oblige à respecter cette convention, il suffit de modifier son fichier de configuration pour prendre en compte un autre répertoire.

# mkdir /srv/tftp             (création du répertoire d'accueil traditionnel de TFTPD)
# chown -R nobody /srv/tftp
# chmod -R 777 /srv/tftp       (les mêmes paramètres que l'installation sur Ubuntu)

Modification du fichier de configuration d'OPENBSD-INETD pour ajouter le service TFTPD. Soit la ligne existe déjà et il faut la décommenter, soit elle est à créer (voir ci-dessous la ligne de couleur mauve), dans la section INTERNAL, à la suite des services discard, time ...

# vim /etc/inetd.conf
  ........................................
  #:INTERNAL: Internal services
  #discard stream tcp nowait root internal
  #discard dgram  udp wait   root internal
  #daytime  ..............................
  #time ..................................
  tftp dgram udp wait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd /srv/tftp

Si un autre répertoire que /srv/tftp a été choisi pour accueillir TFTP, le dernier argument de la ligne dans le fichier /etc/inetd.conf doit être modifié en conséquence.
Nota : L'utilisation de la tabulation plutôt que l'espace comme séparateur entre chaque argument de la ligne tftp dgram udp wait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd /srv/tftp peut empêcher le lancement de TFTPD par OPENBSD-INETD.
Redémarrage d'OPENBSD-INETD :

# /etc/init.d/openbsd-inetd restart
[ ok ] Restarting internet superserver: inetd. 

Vérification de l'état du service :

# netstat -laputen | grep inetd
udp     0     0  0.0.0.0:69       0.0.0.0:*        0   212356     9856/inetd

Sécurité TFTPD Debian

TFTPD souffre des mêmes problèmes de sécurité qu'il soit mis en oeuvre par XINETD ou OPENBSD-INETD. A ce titre lire les limitations et recommandations ci-dessus (Sécurité TFTPD Ubuntu).

Client TFTP

Le client TFTP est à exécuter via un shell et contrairement à FTP il n'y a pas moyen ni de naviguer dans l'arborescence, ni de lister ce qui s'y trouve ; tous les fichiers doivent se trouver à la racine du répertoire d'accueil de TFTPD et il faut connaître le nom exact d'un fichier pour le télécharger :

tftp 45.16.20.20
> put fichier1
> get fichier2
> ?                   (afficher une liste de commandes)
> quit                (déconnexion du serveur et fermeture du client)

Variante

tftp
> connect 45.16.20.20
> put fichier1
................

45.16.20.20 est l'adresse IPv4 de notre serveur TFTP, mais bien sûr on peut se connecter à notre serveur à partir d'un client installé sur la même machine en pointant sur 127.0.0.1
En cas d'erreur de type :

> put fichier1
Error code 2 : Access violation

Vérifier que le fichier fichier1 a bien été crée sur le serveur dans le dossier /tftpboot (ou /srv/tftp en fonction de votre installation) et qu'il est modifiable (droits en écriture).


Trafic réseau TFTP

Le port serveur (par défaut) de (x)inetd/TFTP est UDP 69, mais ce port n'est utilisé que lors du premier échange (de type Read Request si la commande du client est GET ou de type Write Request si la commande du client est PUT). Dès la première réponse, le serveur choisit un port UDP libre au delà de 1024 comme port source, le client TFTP comprenant que c'est dorénavant vers ce port destination qu'il devra envoyer les segments UDP suivants. Cette particularité nécessite des règles spéciales au niveau de NETFILTER pour filtrer UDP en autorisant le trafic client et serveur TFTP.
Celui qui émet (client ou serveur en fonction de la commande put ou get) bride en général la taille des segments envoyés à environ 512 octets de données utiles : Cette valeur, bien en deça de 1500 même en ajoutant les en-têtes des couches 4 à 2, permet à TFTP (reposant sur UDP, protocole non connecté et ne possédant pas de système de fenétrage) de s'affranchir des problèmes éventuels de MTU.
Les segements de données utiles sont nommés des Data Packets et sont numérotés par blocks de 1 à n, et celui qui reçoit les aquitte un par un au moyen de segments Acknowledgement. Tout le trafic est émis en clair.

Règles particulières pour NETFILTER / IPTABLES

Tout comme le filtrage de FTP nécessite le module ip_conntrack_ftp, filtrer TFTP réclame le module ip_conntrack_tftp.
Il faut ensuite positionner ces règles sur la machine CLIENTE (Sur un parefeu positionné entre serveurs et clients les règles devront être de type FORWARD) :

# accepter en entrée le premier segment de requête TFTP :
iptables -t filter -A INPUT -m state --state NEW -p UDP --dport 69 -j ACCEPT
# accepter en sortie la réponse à la requête (RELATED) et les segments de données ou d'acquittement (ESTABLISHED): 
iptables -t filter -A OUTPUT -m state --state ESTABLISHED,RELATED -p UDP -j ACCEPT
# accepter en entrée les segments de données ou d'acquittement (ESTABLISHED):
iptables -t filter -A INPUT -m state --state ESTABLISHED -p UDP -j ACCEPT

Côté SERVEUR les règles inverses sont à positionner (Sur un parefeu positionné entre serveurs et clients les règles devront être de type FORWARD) :

# accepter en sortie le premier segment de requête TFTP :
iptables -t filter -A OUTPUT -m state --state NEW -p UDP --dport 69 -j ACCEPT
# accepter en entrée la réponse à la requête (RELATED) et les segments de données ou d'acquittement (ESTABLISHED): 
iptables -t filter -A INTPUT -m state --state ESTABLISHED,RELATED -p UDP -j ACCEPT
# accepter en sortie les segments de données ou d'acquittement (ESTABLISHED):
iptables -t filter -A OUTPUT -m state --state ESTABLISHED -p UDP -j ACCEPT

NOTAS : La même station peut être client et serveur. Les interfaces (-i ou -o) ne sont pas précisées dans cet exemple de règles, mais rien n'empêche de le faire. Si les interfaces sont désignées, ne pas oublier d'ajouter des règles pour l'interface de loopback si l'on veut tester son serveur TFTP à partir du client local.

Outils personnels
Espaces de noms

Variantes
Actions
Navigation
Outils