Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
zeroconf [Le 09/07/2011, 17:51] 212.198.140.184zeroconf [Le 13/05/2026, 19:02] (Version actuelle) – màj lien lecteur vidéo krodelabestiole
Ligne 1: Ligne 1:
-#!/usr/bin/env python+{{tag>réseau Partage}}
  
-""" +====== Zeroconf ======
-Copyright (c) 2010 Timothy J Fontaine <tjfontaine@atxconsulting.com>+
  
-Permission is hereby granted, free of charge, to any person obtaining a copy +**[[wpfr>Zeroconf]]** est un ensemble de protocoles servant à la configuration automatique d'un réseau privé. Cette technologie est appelée //Bonjour// (ou encore //RendezVous//par Apple et est utilisée par macOS et iOSainsi que la plupart des machines réseau modernes (//box/Internetimprimantes[[:NAS]], etc.).
-of this software and associated documentation files (the "Software"), to deal +
-in the Software without restriction, including without limitation the rights +
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +
-copies of the Softwareand to permit persons to whom the Software is +
-furnished to do sosubject to the following conditions:+
  
-The above copyright notice and this permission notice shall be included in +**[[wpfr>Avahi_(logiciel)|Avahi]]** est une collection d'outils propres à Linux, permettant d'y implémenter les protocoles Zeroconf.
-all copies or substantial portions of the Software.+
  
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +Zeroconf offre différentes fonctionnalités utiles au [[:partage]] réseau : 
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +  * Résolution de noms avec [[#mDNS]] (//multicast DNS//) ; 
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +  * Publication de service sur le réseau ; 
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +  * Allocation d'adresses.
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +
-THE SOFTWARE. +
-"""+
  
-import cupsosoptparsereurlparse +Traditionnellementla plupart de ce travail est réalisé par [[wpfr>DHCP]] (et [[wpfr>DNS]] sur Internet). CependantZeroconf est souvent plus pratique pour les réseaux privésdomestiques ou de petite entreprise. De pluscela se fait sans aucune configuration (mise à part celle de l'installation d'Avahi).
-import os.path +
-from StringIO import StringIO+
  
-from xml.dom.minidom import parseString +Avahi s'intègre très bien avec les outils traditionnelsPar exemple, vous pouvez obtenir une adresse IP par DHCP et utiliser le service DNS pour résoudre les adresses sur Internet, tout en utilisant le ''//hostname//.local'' de [[#mDNS]] pour résoudre les adresses des autres ordinateurs sur le LAN.\\ 
-from xml.dom import minidom+Cette solution est donc très pratique avec [[:SMB]] !
  
-import sys+<note> 
 +Si vous souhaitez utiliser Zeroconf sur un réseau qui ne vous appartient pas, il est préférable de contacter au préalable l'administrateur réseau. Bien que Zeroconf soit un protocole performant, l'administrateur peut ne pas vouloir de ce trafic réseau additionnel. Soyez aussi vigilant, car il est aisé d'usurper un nom mDNS (''.local''). 
 +</note>
  
-try+Cette technologie peut actuellement être utilisée pour 
-    import lxml.etree as etree +  * Partager de la musique : [[:Rhythmbox]]iTunes[[:mt-daapd]] 
-    from lxml.etree import ElementElementTreetostring +  * Échanger des fichiers **(//en//)** [[https://linux.softpedia.com/get/Desktop-Environment/Tools/gnome-user-share-11597.shtml|gnome-user-share]] 
-except+  * Découvrir automatiquement les autres clients VoIP [[:Ekiga#avahi|Ekiga]] 
-    try: +  * Discuter par messagerie instantanée sur le réseau local : [[:gajim]][[:pidgin]][[:empathy]] 
-        from xml.etree.ElementTree import Element, ElementTree, tostring +  * Partager des [[:paquet|paquets]] : [[:quid-deb-proxy]] 
-        etree = None +  * [[:tutoriel:installer_imprimante_partage|Partager des imprimantes]] 
-    except: +  * Publier les sites web servis avec [[:Apache2]] : [[:tutoriel:comment_installer_un_paquet|installer le paquet]] ''[[apt>libapache2-mod-dnssd]]'' puis activer le module Apache avec la commande ''[[:apache2#fichiers_de_configuration|a2enmod dnssd]]'' 
-        try+  * Publier un serveur [[:SSH]] (voir discussion sur le [[https://forum.ubuntu-fr.org/viewtopic.php?id=206906|forum]])
-            from elementtree import ElementElementTreetostring +
-            etree = None +
-        except+
-            raise 'Failed to find python libxml or elementtree, please install one of those or use python >= 2.5'+
  
-XML_TEMPLATE """<!DOCTYPE service-group SYSTEM "avahi-service.dtd"> +===== Installation =====
-<service-group> +
-<name replace-wildcards="yes"></name> +
-<service> +
- <type>_ipp._tcp</type> +
- <subtype>_universal._sub._ipp._tcp</subtype> +
- <port>631</port> +
- <txt-record>txtvers=1</txt-record> +
- <txt-record>qtotal=1</txt-record> +
- <txt-record>Transparent=T</txt-record> +
- <txt-record>URF=none</txt-record> +
-</service> +
-</service-group>"""+
  
-#TODO XXX FIXME +Avahi est installé et activé par défaut sur Ubuntu. Vous n'avez donc rien de particulier à faire pour en profiter.
-#<txt-record>ty=AirPrint Ricoh Aficio MP 6000</txt-record> +
-#<txt-record>Binary=T</txt-record> +
-#<txt-record>Duplex=T</txt-record> +
-#<txt-record>Copies=T</txt-record>+
  
 +Si ce n'est pas le cas, il suffit d'[[:tutoriel:comment_installer_un_paquet|installer les paquets]] [[apt>avahi-daemon avahi-autoipd]].
  
-DOCUMENT_TYPES = { +Il se peut que la configuration du pare-feu bloque la communication [[#mDNS]] par défautDans le panneau de configuration du pare-feuon pourra si nécessaire changer le niveau de confiance par défaut (réseau public) pour un niveau plus permissif (réseau domestique ou //home//).
-    These content-types will be at the front of the list +
-    'application/pdf': True, +
-    'application/postscript': True, +
-    'application/vnd.cups-raster': True, +
-    'application/octet-stream': True, +
-    'image/urf': True, +
-    'image/png': True, +
-    'image/tiff': True, +
-    'image/png': True, +
-    'image/jpeg': True, +
-    'image/gif': True, +
-    'text/plain': True, +
-    'text/html': True,+
  
-    # These content-types will never be reported +===== Utilisation =====
-    'image/x-xwindowdump': False, +
-    'image/x-xpixmap': False, +
-    'image/x-xbitmap': False, +
-    'image/x-sun-raster': False, +
-    'image/x-sgi-rgb': False, +
-    'image/x-portable-pixmap': False, +
-    'image/x-portable-graymap': False, +
-    'image/x-portable-bitmap': False, +
-    'image/x-portable-anymap': False, +
-    'application/x-shell': False, +
-    'application/x-perl': False, +
-    'application/x-csource': False, +
-    'application/x-cshell': False, +
-}+
  
-class AirPrintGenerate(object): +==== mDNS ====
-    def __init__(self, host=None, user=None, port=None, verbose=False, +
-        directory=None, prefix='AirPrint-', adminurl=False): +
-        self.host host +
-        self.user = user +
-        self.port = port +
-        self.verbose = verbose +
-        self.directory = directory +
-        self.prefix = prefix +
-        self.adminurl = adminurl +
-         +
-        if self.user: +
-            cups.setUser(self.user) +
-     +
-    def generate(self): +
-        if not self.host: +
-            conn = cups.Connection() +
-        else: +
-            if not self.port: +
-                self.port = 631 +
-            conn = cups.Connection(self.host, self.port) +
-             +
-        printers = conn.getPrinters() +
-         +
-        for p, v in printers.items(): +
-            if v['printer-is-shared']: +
-                attrs = conn.getPrinterAttributes(p) +
-                uri = urlparse.urlparse(v['printer-uri-supported'])+
  
-                tree = ElementTree() +Chaque machine utilisant Zeroconf s'identifie elle-même sur le réseau comme ''//hostname//.local'', où ''//hostname//'' est le nom d'hôte de la machine. Par exemple un ordinateur //banane//s'identifie lui-même comme ''banane.local''.
-                tree.parse(StringIO(XML_TEMPLATE.replace('\n''').replace('\r', '').replace('\t', '')))+
  
-                name = tree.find('name'+<note importante>Si ceci ne fonctionne pas, [[:desinstaller_une_application#methodes_standardspour_deb_snap_et_flatpak|désinstallez le paquet]] ''libdns22''.(([[https://bugs.launchpad.net/ubuntu/+source/bind9/+bug/147731|bug #147731]]))</note>
-                name.text = 'AirPrint %s @ %%h(p)+
  
-                service = tree.find('service')+Dès lors, n'importe quel ordinateur peut utiliser ''//hostname//.local'' à la place d'une adresse IP. Par exemple vous pouvez utiliser ''[[man>ping]]'' 
 +<code>ping banane.local</code> 
 +ou [[:SSH]] 
 +<code>ssh banane.local</code>
  
-                port service.find('port'+==== Découvrir les services ====
-                port_no None +
-                if hasattr(uri, 'port'): +
-                  port_no uri.port +
-                if not port_no: +
-                    port_no self.port +
-                if not port_no: +
-                    port_no cups.getPort() +
-                port.text '%d' % port_no+
  
-                if hasattr(uri'path'): +Sur Ubuntu**[[:nautilus|GNOME Fichiers]]** est généralement le choix le plus simple pour visualiser et explorer les services exposés par **Zeroconf** le panneau //Réseau// (le [[:nautilus#les_signets|signet]] est en haut de la colonne de gauche -- anciennement //Autres emplacements//) utilise certains de ces protocoles pour afficher les partages réseau et les noms des machines qui les proposent.
-                  rp = uri.path +
-                else: +
-                  rp = uri[2] +
-                 +
-                re_match = re.match(r'^//(.*):(\d+)(/.*)', rp) +
-                if re_match: +
-                  rp = re_match.group(3) +
-                 +
-                #Remove leading slashes from path +
-                #TODO XXX FIXME I'm worried this will match broken urlparse +
-                #results as well (for instance if they don't include a port) +
-                #the xml would be malform'd either way +
-                rp = re.sub(r'^/+', '', rp) +
-                 +
-                path = Element('txt-record'+
-                path.text = 'rp=%s' % (rp) +
-                service.append(path)+
  
-                desc = Element('txt-record') +De la même manière certains lecteurs [[:multimédia]] ([[:lecteur_audio|audio]] et [[:lecteur vidéo|vidéo]]), par exemple, utilisent ces protocoles pour accéder à du contenu sur le réseau localC'est généralement transparent pour l'utilisateur, qui n'a pas à se soucier du nom du protocole ou de sa mise en place.
-                desc.text = 'note=%s% (v['printer-info']) +
-                service.append(desc)+
  
-                product Element('txt-record'+==== Utilisation en ligne de commande ===
-                product.text 'product=(GPL Ghostscript)' +
-                service.append(product)+
  
-                state = Element('txt-record'+Depuis un [[:terminal]] on peut procéder à un scan plus exhaustif grâce à la commande ''avahi-browse'', fournie par le [[:paquet]] ''[[apt>avahi-utils]]''
-                state.text = 'printer-state=%s% (v['printer-state']) +  avahi-browse -av 
-                service.append(state)+(''Ctrl''+''C'' pour quitter).
  
-                ptype = Element('txt-record') +Pour résoudre l'adresse IPv4 d'une hypothétique machine //banane// : 
-                ptype.text = 'printer-type=%s' % (hex(v['printer-type'])) +  avahi-resolve -n4 banane.local
-                service.append(ptype)+
  
-                pdl = Element('txt-record') +À l'inverse, pour connaître le nom mDNS d'une machine : 
-                fmts = [] +  avahi-resolve -a IP.de.la.machine 
-                defer = []+en remplaçant ''IP.de.la.machine''.
  
-                for a in attrs['document-format-supported']: +===== Problèmes connus =====
-                    if a in DOCUMENT_TYPES: +
-                        if DOCUMENT_TYPES[a]: +
-                            fmts.append(a) +
-                    else: +
-                        defer.append(a)+
  
-                fmts ','.join(fmts+defer)+==== hostname-2.local ====
  
-                dropped = []+Parfois Avahi n'identifie pas correctement certaines machines et leurs ajoute un ''-2'', qui donne ''//hostname//-2.local''.
  
-                # TODO XXX FIXME all fields should be checked for 255 limit +Pour retrouver un //hostname// correct sous la forme ''//hostname//.local'', nous devons effectuer ces quelques manipulations :
-                while len('pdl=%s% (fmts)) >= 255: +
-                    (fmts, drop) = fmts.rsplit(',', 1) +
-                    dropped.append(drop)+
  
-                if len(dropped) and self.verbose+On modifie le nom d'hôte de l'ordinateur 
-                    sys.stderr.write('%s Losing support for%s%s' % (p, ','.join(dropped), os.linesep))+  sudo hostname HOSTNAME_CORRECT 
 +Puis on redémarre le //daemon// : 
 +  sudo systemctl restart avahi-daemon 
 +Pour finir on s'assure que tout fonctionne correctement : 
 +  ps -ef | grep -i avahi
  
-                pdl.text 'pdl=%s' % (fmts) +==== Aucun trafic Zeroconf ====
-                service.append(pdl)+
  
-                if self.adminurl: +La commande 
-                    admin = Element('txt-record'+  avahi-browse -a 
-                    admin.text = 'adminurl=%s' % (v['printer-uri-supported']) +ne retourne rien par exemple.
-                    service.append(admin) +
-                 +
-                fname = '%s%s.service' % (self.prefix, p) +
-                 +
-                if self.directory: +
-                    fname = os.path.join(self.directory, fname) +
-                 +
-                f = open(fname, 'w')+
  
-                if etree: +Le problème peut venir du [[:pare-feu]]qui bloque ce trafic.
-                    tree.write(f, pretty_print=True, xml_declaration=True, encoding="UTF-8") +
-                else: +
-                    xmlstr = tostring(tree.getroot()) +
-                    doc = parseString(xmlstr) +
-                    dt= minidom.getDOMImplementation('').createDocumentType('service-group', None, 'avahi-service.dtd'+
-                    doc.insertBefore(dt, doc.documentElement) +
-                    doc.writexml(f) +
-                f.close() +
-                 +
-                if self.verbose: +
-                    sys.stderr.write('Created: %s%s' % (fnameos.linesep))+
  
-if __name__ == '__main__'+=== Firewalld === 
-    parser optparse.OptionParser() + 
-    parser.add_option('-H', '--host', action="store", type="string", +Pour l'autoriser, avec **[[wp>Firewalld]]** 
-        dest='hostname'help='Hostname of CUPS server (optional)', metavar='HOSTNAME'+  sudo firewall-cmd --add-service=mdns --permanent 
-    parser.add_option('-P', '--port', action="store", type="int", +  sudo firewall-cmd --reload 
-        dest='port', help='Port number of CUPS server', metavar='PORT'+  sudo systemctl restart avahi-daemon 
-    parser.add_option('-u', '--user', action="store", type="string", + 
-        dest='username', help='Username to authenticate with against CUPS', +=== Guarddog === 
-        metavar='USER') + 
-    parser.add_option('-d', '--directory'action="store", type="string", +Si vous utilisez le pare-feu **[[wpfr>Guarddog]]**vous aurez besoin de créer une nouvelle zone pour le trafic //multicast// et d'ajouter une entrée au fichier ''networkprotocoldb.xml''. 
-        dest='directory', help='Directory to create service files'+ 
-        metavar='DIRECTORY') +Appeler cette nouvelle zone //multicast// et positionner les adresses de la zone ainsi ''224.0.0.0/255.0.0.0''. Ajouter le code XML ci-dessous dans ''/usr/share/apps/guarddog/networkprotocoldb.xml'', juste au-dessus de l'endroit où il est écrit ''<protocol name="domain">''. Relancer **Guarddog** et cocher les cases qui permettent le trafic [[#mDNS]] entre vos zones. 
-    parser.add_option('-v', '--verbose', action="store_true"dest="verbose", + 
-        help="Print debugging information to STDERR") +<file XML> 
-    parser.add_option('-p', '--prefix', action="store", type="string"+<protocol name="mDns"> 
-        dest='prefix', help='Prefix all files with this string', metavar='PREFIX', +  <!-- Protocol information guessed by Greg N <emailgregn@googlemail.com> --
-        default='AirPrint-') +  <longname>mDns,Bonjour,Avahi,Zeroconf</longname> 
-    parser.add_option('-a', '--admin', action="store_true"dest="adminurl"+  <longname lang="nl">mDns</longname> 
-        help="Include the printer specified uri as the adminurl") +  <longname lang="fr">mDns</longname> 
-     +  <longname lang="it">mDns</longname> 
-    (options, args) parser.parse_args() +  <longname lang="es">mDns</longname> 
-     +  <description>Protocols to allow networks to configure themselves. It is called Bonjour (formerly Rendezvous) by Appleand used extensively on macOS.</description> 
-    # TODO XXX FIXME -- if cups login required, need to add +  
-    # air=username,password +  <classification class="net"/> 
-    from getpass import getpass +  <network> 
-    cups.setPasswordCB(getpass) +    <udp source="server" dest="client"> 
-     +      <source><port portnum="nonprivileged"/></source> 
-    if options.directory: +      <dest><port portnum="5353"/></dest> 
-        if not os.path.exists(options.directory): +    </udp> 
-            os.mkdir(options.directory) +    <udp source="client" dest="server"> 
-     +      <source><port portnum="5353"/></source> 
-    apg AirPrintGenerate( +      <dest><port portnum="nonprivileged"/></dest
-        user=options.username, +    </udp> 
-        host=options.hostname, +  </network> 
-        port=options.port, +  <security threat="mediumfalsepos="low"/> 
-        verbose=options.verbose, +</protocol> 
-        directory=options.directory, +</file> 
-        prefix=options.prefix, + 
-        adminurl=options.adminurl, +===== Voir aussi ===== 
-    ) + 
-     +==== Ressources externes ==== 
-    apg.generate()+ 
 +  * **(//en//)** [[http://www.zeroconf.org/|Site officiel]] 
 +  * **(//en//)** [[http://0pointer.de/lennart/projects/nss-mdns/|libnss-mdns]] 
 +  * **(//en//)** [[http://avahi.org/|Avahi mdns responder]] 
 + 
 +==== Pages en rapport ==== 
 + 
 +{{backlinks>.#!utilisateurs:}} 
 + 
 +---- 
 +//Contributeurs : [[:contributeurs|les contributeurs du wiki]], [[:utilisateurs:sbrunner]], Xorios, kanor, [[:utilisateurs:Id2ndR]], [[:utilisateurs:Ner0lph]], [[:utilisateurs:krodelabestiole]].//