PROJET AUTOBLOG


Planet-Libre

source: Planet-Libre

⇐ retour index

Artisan Numérique : Un serveur musical avec MPD

mardi 12 mai 2015 à 22:28

MPD est finalement assez peu connu et pourtant il répond au besoin récurrent qu'ont les mélomanes qui adorent donner une ambiance musicale à chacune de leurs pièces. L'objectif de ce tutoriel est de vous expliquer ce qu'est MPD, comment l'installer et comment l'utiliser au quotidien

Qu'est-ce que MPD ?

Comme vous le voyez sur le schéma ci-dessus, MPD (Music Player Daemon) est un lecteur audio très complet de type "démon". Entendre par là qu'il s'agit avant tout d'un serveur qui ne dispose d'aucune interface graphique. Pour accéder à ce serveur il vous faudra donc un client capable de lui parler. Et des clients, MPD en a des dizaines pour tous les goûts (client Web, application Android ou iOS, application de bureau pour Gnome ou même Windows, etc.).

Si l'on fait abstraction de l'absence d'interface graphique, MPD dispose de toutes les fonctionnalités que l'on est en droit d'attendre d'un lecteur audio :

  • prise en charge de nombreux formats (MP3, OGG, FLAC, etc.) ainsi que des formats en streaming (ex. web radios)
  • lecture des métadonnées (ex. ID3) des morceaux de votre audiothèque avec possibilité de recherche dans la base de données selon différents critéres,
  • sortie du sont sur ALSO, OSS, Jack ou Pulse, mais aussi en streaming (en mode "shoutcast", via Icecast ),
  • gestion des listes de lectures,

Et si l'on ajoute usage très très faibles des ressources systèmes, MPD devient l'outil idéal dés que vous avez besoin de sonoriser une pièce (salon, bureau, etc.) soit parce que vous y avez un petit serveur multimédia, soit juste pour permettre à tous d'interagir avec les morceaux en cours d'écoute.

Installation et configuration

Installation

MPD est sans aucun doute déjà dans votre distribution. Un coup d'apt-get install mpd (ou brew install mpd sous MacOS) devrait suffire à installer le serveur. Une fois le service installé, jetons un œil à sa configuration en commençant par l'essentiel, la source audio.

Déclaration des fichiers audio

Pour que MPD puisse fonctionner, il lui faut... de la musique et peu importe, ou presque, le format. MPD peut lire les fichier mp3, mp2, ogg, flac, wav, au, aiff, aif, mpc, amf, dsm, far, gdm, imf, it, med, mod, mtm, s3m, stm, stx, ult, uni et xm.

Ces fichiers doivent être accessibles en local par MPD. Si vous avez plusieurs instances, vous la placerez donc dans un dossier partagé, par exemple NFS ou CIFS. Dans la suite du tutoriel, nous partirons du principe que vos morceaux se trouvent dans le dossier /musique.

Commençons donc par éditer le fichier /etc/mpd.conf et repérerons un bloc ressemblant à ceci :

music_directory                 "~/music"
playlist_directory              "~/playlists"
db_file                         "/var/lib/mpd/mpd.db"

Il s'agit de tous les chemins dont a absolument besoin MPD pour fonctionner. La première ligne correspond au dossier des fichiers audio, nous remplaçons donc comme suit :

music_directory                 "/musique"

Déclaration du dossier de playlists

La seconde ligne correspond au dossier dans lequel MPD lit et écrit les listes de lectures (fichiers .m3u au format WinAmp). Comme il est sympa de pouvoir partager ces listes entre tous les serveurs MPD, le plus simple est de créer un sous-dossier /musique/mdp :

playlist_directory                 "/musique/mdp"

Déclaration du dossier de la base de données

Ensuite vient la base de donnée qui contiendra les chemins, les étiquettes, bref, tout ce que MPD découvrira dans le dossier /musique. Là aussi, il est pratique qu'elle soit partagé car ainsi la création et la mis à jour de cette base sur une machine, sera effective sur toutes les autres :

db_file                 "/musique/mdp/mdp.db"

Rendre vos fichiers accessibles à MPD

Maintenant la partie un peu funky. Un peu plus loin dans le fichier vous devez trouvez quelque chose comme cela :

user                            "mpd"

L'idée est que lancer MPD en tant que root, c'est comme croiser les flux, c'est mal. Donc à l'installation du paquet, un gentil utilisateur mpd bien inoffensif a été créé. Et en toute logique cette utilisateur là n'a aucun droit de lecture, et encore moins d'écriture dans votre dossier /musique. Sous Debian, cet utilisateur mpd appartient au groupe audio, de sorte à ce que si vous affectez ce groupe à tous le dossier /musique MPD doit logiquement pouvoir s'y retrouver.

Après selon le cas de figure (dossier musique partagé par exemple), les approches devront varier.Le point important à retenir est que l'utilisateur qui lance MPD puisse lire dans /musique et écrire dans /musique/mpd, et ce sur toutes les machines où il doit être lancé.

Déclaration des sorties Audio

MPD est conçu de sorte à pouvoir gérer en simultané plusieurs sorties audio. Il est donc possible avec plusieurs cartes audio de distribuer la même musique sur plusieurs pièces à partir d'un seul serveur. La majorité des clients MPD permettent d'activer ou de désactiver telle ou telle sortie à distance.

Une sortie MPD peut être une sortie ALSA ou OSS, un serveur Jack ou Pulse, ou encore un serveur de type ShoutCast. Cela laisse tout de même assez de lattitude :-)

Pour l'exemple, nous allons donc utiliser une toute classique périphérique audio en utilisant ALSA. Pour cela il faut aller jeter un oeil un peu plus loin dans le fichier de configuration et chercher les sections nommées audio_output. Si vous en avez aucune ou si elles sont toutes commentées, ajoutez ce qui suit, sinon vérifiez que ça ressemble un peu à cela :

 audio_output {
 type                    "alsa"
 name                    "Sortie vers Chambre"
}

Si je vous avez une deuxième carte audio, vous pouvez donc ajouter une seconde sortie :

audio_output {
  type                    "alsa"
  name                    "Sortie vers Buanderie"
  device                  "hw:0,1"
}

Notez le paramètre device qui indique que le tape sur le deuxième périphérique ALSA (le premier étant sous entendu dans la première sortie comme étant hw:0,0).

Dernier aspect, le contrôle du volume. Comme pour les sorties audio, vérifiez que les lignes suivantes existent, ne sont pas commentées et concordent bien :

  mixer_type                      "alsa"
  mixer_device                    "default"
  mixer_control                   "Master"

On utilise ici la table de mixage ALSA du périphérique par défaut (hw:0,0) dont on sélectionne le canal Master.

Paramétrage réseau

Dernière chose à faire : rendre notre serveur visible sur notre réseau local. Imaginons pour cela que notre machine ait pour adresse IP 10.0.0.10, nous modifierons donc la configuration dans ce sens :

  bind_to_address                 "10.0.0.10"
  port                            "6600"

Si vous êtes de grands paranoïaques ou si vous comptez "publier" MPD sur le réseau publique (pas une idée terrible ceci dit), il est aussi possible d'ajouter un mot de passe et des droits associés. Voir pour cela le paramètre password.

Démarrage du service

Reste maintenant à démarrer notre serveur par un /etc/init.d/mpd start et zouh, le lecteur MPD est lancé... dans le plus grand silence :-) Cela tombe bien car il reste encore une petite chose à faire.

Comme indiqué plus haut, MPD est capable de lire tous les attributs contenus dans les fichiers audio (ID3, vorbis, FLAC, etc) de sorte à constituer une base de donnée de recherche de morceaux qui sera utilisée lors de la navigation. A la première utilisation, il nous faut donc initialiser cette base de donnée. Pour cela, lancez la commande suivante :

mpd --create-db

MPD doit alors cracher un flot continu de texte listant les fichiers audio qu'il est en train de disséquer. Tout dépends de votre audiothèque, chez moi cette opération prend prés de 5 minutes. C'est une des raisons qui m'a amené à partager la base de données entre les différentes serveurs...

Notez cependant que cette opération n'est à réaliser qu'une seule fois. Par la suite il suffira d'une simple mise à jour de la base qui se fera par le biais du client MPD.

Les clients MPD

Maintenant que notre serveur est en route, il est temps de lui envoyer des commandes. Pour cela, il nous faut un client et là, le choix est vaste. Mais avant de commencer à en explorer quelques un, regardons de plus prés comment le serveur MPD cause avec ses clients.

Le protocole MPD

MPD est un simple serveur Telnet... Pour s'en convaincre, essayez ceci :

roottelnet mon_serveur_mpd 6600
Trying 10.0.0.10...
Connected to mon_serveur_mpd (10.0.0.10).
Escape character is '^]'.
OK MPD 0.13.0
ping
OK
list album
Album: #51
Album: 7th Ave. Stroll
Album: A Clockwork Orange
Album: A Day Without Rain
...
OK
close
Connection closed by foreign host.

Avec un protocole aussi trivial, on comprend mieux qu'il existe une librairie MPD pour à peu prés tout les langages. Pour ceux que cela intéresse le protocole est complètement documenté ici.

Clients en ligne de commande

Pour les fanatiques de la console (dont je fais parti :-) et du scripting, nous avons mpc qui est un client en ligne de commande. Cet outil est fabuleux pour écrire de nouvelles fonctionnalités.

Par exemple, imaginons que vous entendiez une musique bien sympathique remonter de la chambre où se prépare votre moitié. Vous, dans le salon, vous vous dites Hum, sympa, ce qu'elle écoute, je vais le mettre ici :

#! /bin/sh

  # on définit le nom de la machine où tourne le serveur source
  export MPD_HOST=$1

  # on récupère la piste en cours de lecture


  track=$(mpc | grep playing | awk '{print $2}' | cut -d"/" -f 1 | tr "#" " ")

  # on récupère la position dans la piste
  position=$(mpc | grep playing  | awk '{print $3}' | cut -d "/" -f1)

  # on vire une éventuelle liste de lecture "tmp"
  mpc rm tmp

  # on sauve la liste de lecture en cours dans "tmp"
  mpc save tmp

  # on se place maintenant sur le serveur cible
  export MPD_HOST=$2

  # on vire la liste de lecture en cours
  mpc clear

  # on charge la liste "tmp" créée plus haut
  mpc load tmp

  # on sélectionne le morceau
  mpc play $track

  # et on se déplace sur la position, la lecture démarre...
  mpc seek 00:$position
/usr/bin/synchronize-mpd.sh

Et voilà, il suffit alors de lancer

synchronize-mpd.sh serveur_chambre serveur_salon

Et hop, les deux serveurs sont synchronisés sur la même liste, lisent le même morceau à la même position. Des petits délires de ce genre, vous pouvez en trouver des tonnes ici.

Pour une version plus "graphique", il existe aussi d'excellents clients nCurse (cf. photo)

Clients graphiques

Autant j'aime bien la ligne de commande, autant pour éditer une playlist on a trouvé tout de même mieux depuis. Il existe de nombreux clients graphique mais j'affectionne particulière Sonata conçu pour Gnome/GTK2 et qui est dispo en standard sur toute distribution un peu étoffée.

Avec Sonata, mais c'est vrai pour la majorité des clients, toutes les opérations MPD sont disponibles, de l'exploration des morceaux à la constitution de la liste de lecture courante, son stockage sur le disque, etc. Sonata rivalise avec Rythmbox en téléchargeant les paroles, les pochettes, etc.

La première chose à faire pour utiliser Sonata, et c'est le cas pour tous les clients qui suivent, est de se connecter au serveur MPD. Pour cela, il suffit de faire sur l'interface un click-droit/préférences... pour, dans l'onglet serveurs, ajouter vos différents noms de machines hébergeant une instance de MPD. Ceci fait, il suffit de refaire un click-droit/connexion et de sélectionner le serveur que l'on cherche à contrôler. Le reste est suffisamment proche d'un lecteur audio classique pour que vous vous en sortiez sans problèmes.

Pour plus de clients graphiques, allez ici...

Les clients mobiles

Bien évidemment les applications mobiles ne sont pas en reste et permettent de transformer vos smartphones en télécommande WIFI de luxe. On en trouve pour toutes les plateformes (android, iOS, Windows Phone, etc.) et de tout les styles. Là je n'ai pas de grand conseil à donner, elles se valent toutes plus ou moins. Pour ceux qui ont plusieurs serveurs MPD, vérifiez juste que celle que vous choisissez permet de basculer d'un serveur à l'autre.

Écouter la radio

Il est possible avec MPD d'ajouter des fichiers qui ne sont pas sur le serveur local mais sur un serveur HTTP. C'est typiquement le cas des listes de lecture et flux des webRadios. Prenons l'exemple de Nashville Edge dont l'URL est http://streaming.radionomy.com/NashvilleEdge.

Allez dans votre dossier /musiques/playlists et ajoutez un fichier radios.m3u contenant ceci :

#EXTM3U
http://streaming.radionomy.com/NashvilleEdge

Ensuite il ne vous reste plus qu'à vous connecter sur le serveur avec Sonata et à double-clicker sur la liste radios pour y accéder.

Et avec mpc, vous feriez comme ceci :

export MPD_HOST=mon_serveur_mpd
mpc clean
mpc load radios
mpc play

Conclusion

Partant d'une définition très simple de "serveur musicale contrôlable à distance", MPD a permis le développement d'un écosystème d'une rare richesse. Et tant que l'on reste dans le cadre de ce pour quoi ce serveur est fait, il est difficile de ne pas trouver client à son pied, ou de ne pouvoir le scripter pour un comportement particulier. C'est bien simple, aujourd'hui MPD est tellement rentré dans notre quotidien que personne ici ne pourrait plus s'en passer.

Tweet

Gravatar de Artisan Numérique
Original post of Artisan Numérique.Votez pour ce billet sur Planet Libre.

Articles similaires

nIQnutn : Rédiger en Markdown

mardi 12 mai 2015 à 09:14

Markdown est un outil de conversion de texte vers HTML pour la rédaction sur le web. Il permet de rédiger le texte dans un format facile à lire et à écrire, puis de le convertir en XHTML (ou HTML) valide.

L'idée n'est pas de créer une syntaxe permettant d'insérer plus facilement les balises HTML. HTML est un format de publication, Markdown est un format de rédaction.

Markdown permet donc de mettre en forme simplement du texte brut et de manière intelligible. Contrairement au HTML et ses balises, on comprend aisément un document formaté en Markdown. C'est simple, clair et rapide pour rédiger un document à publier sur le web. On ne peut pas tout faire avec Markdown mais ça permet de rédiger un contenu complet et structuré (mais on peut mélanger Markdown et HTML sans problème). L'autre avantage est de privilégier le contenu sans se préoccuper de la mise en forme.
L'utilisation de Markdown est recommandé pour écrire des courriels en texte brut.

Voici donc un petit memo pour utiliser Markdown (j'ai volontairement simplifié certains aspects que l'on peut retrouver dans les liens).

Sommaire

  • Convertir un document Markdown
  • Aller plus loin avec Markdown
  • Ressources
  • Les outils pour rédiger en Markdown

    Pour rédiger simplement en Markdown et visualiser en temps réel son contenu, on peut utiliser Geany et son extension Markdown. Pour convertir en HTML on installe simplement le paquet Markdown.

    en root
    apt-get install geany geany-plugin-markdown markdown
    

    On démarre Geany depuis le menu: Développement > Geany
    ou directement depuis le terminal:

    en utilisateur
    geany &
    

    Il faut d'abord activer l'extension dans Geany. Dans le menu: Outils > Gestionnaire de plugin. Ensuite, activer l'extension Markdown. Il est possible de modifier les préférences d'affichage.

    Au cours de la rédaction, on pré-visualise le contenu dans l'onglet Aperçu Markdown.
    Les fichiers Markdown portent l'extension .md, .mdml ou .markdown.

    Si le formatage n'est pas pris en compte, pensez à vérifier que votre texte est bien structuré.
    Le nombre d'espace, l'ajout d'une ligne vide ou un caractère spécial peut empêcher le bon fonctionnement de la conversion vers HTML.

    La syntaxe Markdown

    On va voir la syntaxe utilisée par Markdown et tout ce qu'il est possible de faire avec. J'ai simplifié certains éléments et il est parfois possible d'utiliser plusieurs syntaxes différentes.

    La gestion des titres

    Pour mettre en forme un texte, on commence par ajouter des titres pour structurer son texte. Le symbole # permet de définir les niveaux de titres. Le titre de niveau 1 (considéré comme le plus élevé) doit être précédé de #. D'une manière générale, on ajoute autant de # que le niveau du titre voulu.

    Markdown
    # Titre de niveau 1     
    ## Titre de niveau 2    
    ### Titre de niveau 3   
    #### Titre de niveau 4
    
    HTML

    Titre de niveau 1

    Titre de niveau 2

    Titre de niveau 3

    Titre de niveau 4

    Le rendu final:

    Titre de niveau 1

    Titre de niveau 2

    Titre de niveau 3

    Titre de niveau 4

    La gestion des listes

    On peut également ajouter des listes ordonnées (comme la liste des distributions GNU/Linux à tester) ou non ordonnées (comme la liste des OS à ne pas utiliser).

    Pour les listes non ordonnées, on utilise * suivi d'un espace.

    Markdown
    * HTML
    * CSS
    * PHP
    * ...
    
    HTML
    • HTML
    • CSS
    • PHP
    • ...

    Le rendu final:

    • HTML
    • CSS
    • PHP
    • ...

    Pour les listes non ordonnées, on utilise un nombre suivi d'un point (ex: 1.).

    Markdown
    1. Premier
    2. Deuxième
    3. Troisième
    
    HTML
    1. Premier
    2. Deuxième
    3. Troisième

    Le rendu final:

    1. Premier
    2. Deuxième
    3. Troisième
    Les nombres utilisés n'ont pas d'importances et ne sont pas interprétés.

    La gestion des liens

    Il n'est pas rare de faire référence à différents sites. Pour générer des liens, on a besoin de trois éléments.
    Un élément qui sera le texte affiché (ex: nIQnutn), un autre qui sera l'URL (ex: http://blog.niqnutn.com) et optionnellement une description (affiché dans l'info-bulle au survol du lien).

    Markdown
    [nIQnutn](http://blog.niqnutn.com/ "nIQnutn's blog")
    
    HTML
    nIQnutn
    

    Le rendu final:

    nIQnutn

    On peut aussi l'utiliser pour faire des références internes (comme des sommaires, retour vers le haut de la page, etc.) ou utiliser les chemins relatifs pour accéder à une ressource sur le même serveur.

    Markdown
    Retour vers le [Haut de page](#top "Top") ou se voir les [Actualités](/index.php?static5).
    
    HTML
      

    Retour vers le Haut de page ou voir les Actualités.

    Le rendu final:

    Retour vers le Haut de page ou voir les Actualités.

    Encore plus simple, il est possible de créer des liens automatiquement à partir d'URL.

    Markdown
    
    
    HTML
    http://blog.niqnutn.com/
    

    Le rendu final:

    http://blog.niqnutn.com/

    La même chose est valable pour les adresses mail (avec un encodage de l'adresse mail supplémentaire).

    Markdown
    
    
    HTML
     dontSpam@niqnutn.wolrd
    

    Le rendu final:

    dontSpam@niqnutn.wolrd

    La gestion des images

    Pour faire joli, on peut également ajouter des images. La syntaxe est similaire aux liens. On ajoute au début !, puis [Texte à afficher si l'image n'apparait pas], suivi de l'URL de l'image (ex: /path/to/img.jpg) et optionnellement une description (affiché dans l'info-bulle au survol de l'image).

    Markdown
    ![Logo Markdown](/path/to/img.jpg "Markdown")
    
    HTML
    Logo Markdown
    

    Le rendu final:

    Logo Markdown
    et si l'image n'existe pas:
    Logo Markdown
    Markdown ne permet pas de définir la taille des images. Dans ce cas, il est possible d'utiliser les tags HTML .

    La mise en forme

    Pour faciliter la lecture on peut utiliser la mise en forme du texte avec l'utilisation du gras, italique, etc.

    Pour mettre le texte en italique, on encadre le texte avec *.

    Markdown
    *Texte en italique*
    
    HTML
    Texte en italique
    

    Le rendu final:

    Texte en italique

    Pour mettre le texte en gras on encadre le texte avec **.

    Markdown
    **Texte en gras**
    
    HTML
    Texte en gras
    

    Le rendu final:

    Texte en gras

    Pour insérer un retour à la ligne au sein d'un paragraphe (
    ), on ajoute deux espaces suivi d'un retour à la ligne.

    Markdown
    War is peace.  
    Freedom is slavery.  
    Ignorance is strength.
    
    HTML

    War is peace.
    Freedom is slavery.
    Ignorance is strength.

    Le rendu final:

    War is peace.
    Freedom is slavery.
    Ignorance is strength.

    Pour ajouter une ligne horizontale, on utilise ***.

    Markdown
    ***
    
    HTML

    Le rendu final:


    Insérer une citation

    Pour les citations il suffit d'ajouter > en début de ligne.

    Markdown
    > He who controls the past controls the future. He who controls the present controls the past.  
    > The best books... are those that tell you what you know already.  
    > __George Orwell__, _1984_
    
    HTML

    He who controls the past controls the future. He who controls the present controls the past.
    The best books... are those that tell you what you know already.
    George Orwell, 1984

    Le rendu final:

    He who controls the past controls the future. He who controls the present controls the past.
    The best books... are those that tell you what you know already.
    George Orwell, 1984

    Pour plus de lisibilité on ajoute > à chaque nouvelle ligne.

    Insérer du code

    Pour insérer du code (le texte est alors interprété littéralement), on ajoute quatre espaces avant le texte.

    Markdown
        apt-get install niqnutn
    
    HTML
    apt-get install niqnutn

    Le rendu final:

    apt-get install niqnutn

    Note: tous les caractères seront échappés.

    Et un peu de html

    Dans le cas ou la syntaxe Markdown ne couvre pas vos besoins, il est possible d'ajouter directement du code HTML. Il sera interprété automatiquement et il n'est pas nécessaire d'indiquer qu'on change de langage.

    Markdown
    Distribution Nom Version
    Debian Jessie 8.0
    HTML
    Distribution Nom Version
    Debian Jessie 8.0

    Le rendu final:

    Distribution Nom Version
    Debian Jessie 8.0

    Caractères d'échappement

    Tous les caractères spéciaux sont automatiquement convertis (ex: & devient &). Il faut ajouter \\ pour éviter que certains caractères soient interprétés lors de la conversion.

    \\   backslash
    `   backtick
    *   asterisk
    _   underscore
    {}  curly braces
    []  square brackets
    ()  parentheses
    #   hash mark
    +   plus sign
    -   minus sign (hyphen)
    .   dot
    !   exclamation mark
    

    Convertir un document Markdown

    Une fois le document rédigé, on peut le convertir au format HTML.

    en utilisateur
    markdown /path/to/file/comment-rediger-en-mardown.md
    

    On peut envoyer directement le résultat dans un fichier .html.

    en utilisateur
    markdown /path/to/file/comment-rediger-en-mardown.md > /tmp/comment-rediger-en-mardown.html
    

    Geany dispose d'un terminal intégré. Il n'est donc pas nécessaire de changer de fenêtre.

    Aller plus loin avec Markdown

    Il est possible d'utiliser des références lorsque l'on utilise de nombreux liens dans un document. L'utilisation des références permet d'avoir un aperçu final proche de celui d'un navigateur web.
    On définit d'une part le texte à afficher: DuckDuckGo est le texte qui sera lisible suivi de 1 qui servira d'identifiant.
    D'autre part, on définit les liens: On reprend son identifiant 1, suivi de son URL https://duckduckgo.com/ et optionnellement DuckDuckGo qui sera utilisé comme titre.

    Markdown
    Il existe de nombreux moteurs de recherches tels que [DuckDuckGo][1], [Qwant][qwant] ou [ixquick][].
    [1]: https://duckduckgo.com/ "Moteur de recherche DuckDuckGo"
    [qwant]: https://www.qwant.com/ "Moteur de recherche Qwant"
    [ixquick]: https://ixquick.com "Moteur de recherche ixquick"
    
    HTML
    Il existe de nombreux moteurs de recherches tels que DuckDuckGo, Qwant ou ixquick.
    

    Le rendu final:

    Il existe de nombreux moteurs de recherches tels que DuckDuckGo, Qwant ou ixquick.

    Il est aussi possible d'utiliser une image comme lien.
    Markdown
    [![alt](data/img/alien.png "logo")](http://blog.niqnutn.com "nIQnutn's blog")
    
    HTML

    alt

    Le rendu final:

    alt

    Il est conseillé de lire la documentation concernant la syntaxe si on souhaite utiliser Markdown plus profondément.
    L'imbrication des différents éléments nécessite parfois quelques connaissances et astuces.

    Ressources


    © 2015 nIQnutn - Tous droits réservés.

    Gravatar de nIQnutn
    Original post of nIQnutn.Votez pour ce billet sur Planet Libre.

    genma : Vulgarisation sur https et TOR

    mardi 12 mai 2015 à 09:00

    Une petite histoire

    Imaginer une zone pavillonnaire avec différentes maisons dont celle de votre ami.

    Cas 1 : Sa maison a des murs aux transparents. On vous voit aller chez lui, on peut entendre ce que vous dites et voir ce que vous faîtes.

    Cas 2 : Maintenant, sa maison a des murs pleins. On vous voit aller chez lui, mais on peut plus entendre ce que vous dites et voir ce que vous faites (on met de côté l'aspect micro/caméra). Mais on sait à quelle heure vous êtes venu le voir et quand vous repartez.

    Cas 3 :
    Si en arrivant en extérieur de la zone pavillonnaire, vous entrez dans une première maison, et en ressortez avec un déguisement, puis vous entrez dans une seconde maison au hasard et en ressortez avec un autre déguisement, et entrez enfin dans une troisième maison au hasard et en ressortez avec un autre déguisement, pour enfin entrez chez votre ami. On sait que quelqu'un est entré chez lui, de quelle heure à quelle heure, mais on ne sait pas que c'est vous. A moins de surveiller toutes les maisons, de surveiller toutes les personnes qui entrent et sortes de chaque maison (sachant que chacun en ressort déguisé), ce qui est très compliqué...

    Cas 4 : Si en arrivant en extérieur de la zone pavillonnaire, vous entrez dans une première maison, et en ressortez avec un déguisement, puis vous entrez dans une seconde maison au hasard et en ressortez avec un autre déguisement, et entrez enfin dans une troisième maison au hasard et en ressortez avec un autre déguisement, pour enfin entrez chez votre ami. Mais cette fois, vous passez par la porte arrière de la maison, côté jardin. On ne sait même pas qu'une personne est venue dans la maison de votre ami.

    Transposons ça à Internet

    Cas 1 : Dans le premier cas, il s'agit d'une connexion Http classique. Vous utilisez votre navigateur, allez sur un site. Un observateur extérieur peut savoir que vous allez sur le site et quelles pages vous consultez.

    Cas 2 : Dans le deuxième cas, il s'agit d'une connexion Https. Vous utilisez votre navigateur, allez sur un site en mode sécurisé. Un observateur extérieur peut savoir que vous allez sur le site mais ne voit pas quelles pages vous consultez (seul le site le sait et enregistre les traces dans le journal de logs, tout comme votre ami chez qui vous êtes saura ce dont vous lui avez parlé).

    Cas 3 : Dans le troisième cas, il s'agit d'une connexion qui se fait via le réseau Tor. La connexion passe par trois proxys intermédiaires avant d'arriver sur le site web. Je ne détaillerai pas plus le fonctionnement de Tor.

    Cas 4 : Dans le quatrième et dernier cas, il s'agit d'une connexion à un service caché dans Tor, les fameux Hidden services. On ne ressort pas du réseau Tor, on entre par une porte particulière sur le site web. Tout comme on entre par une porte dissimulé de la vue de tous chez son ami.

    Conclusion

    Merci de laisser dans les commentaires vaut remarques/critiques quand à cette analogie/vulgarisation

    Gravatar de genma
    Original post of genma.Votez pour ce billet sur Planet Libre.

    Artisan Numérique : Comment mettre en place sa téléphonie grâce à Asterisk

    lundi 11 mai 2015 à 21:59

    De la ligne téléphonique d'une freebox (et sûrement des autres "box") à Skype en passant par les très nombreuses offres disponibles sur le Net, la VoIP (Voice over IP) est partout. Pris dans le contexte d'une architecture domestique ou d'entreprise, la VoIP (Voice over IP ou Voix sur IP) est un nouveau faisceau de service, comme la messagerie, qu'il est possible d'intégrer à un degré professionnel grâce à un outil libre souvent considéré, à tord, comme complexe, Asterisk.

    Pour quoi faire ?

    Comme toujours il est important avant de se lancer, de comprendre ce que peut apporter une intégration VoIP domestique ou professionnelle. Et pour cela, il est nécessaire d'avoir en tête ce que permet Asterisk.

    Asterisk est un projet qui démarré il y a plus de 10 ans (1999) par Mark Spencer. Son objectif était alors de fournir à Linux un commutateur téléphonique complet et totalement libre. Aujourd'hui Asterisk est un PABX (Private Automatic Branch eXchange) d'une rare puissance et souplesse, capable de gérer la téléphonie analogique, mais surtout, et c'est ce qui nous intéresse, la voix sur IP (VoIP).

    La VoIP sur Asterisk passe entre autre par la prise en charge d'un protocole standard, ouvert et très largement utilisé, le SIP (Session Initiation Protocol). SIP qui est un protocole très proche d'HTTP qui n'est pas limité à la seule voix mais qui prend aussi en charge la vidéo et la messagerie instantanée.

    D'un point de vue fonctionnalité, Asterisk permet tout ce que l'on peut attendre d'un PABX moderne, et plus particulièrement dans notre contexte :

    • La prise en charge de tous vos comptes SIP (et pas seulement, Skype et Gtalk aussi).
    • La gestion des postes téléphonique sur IP locaux. Il peut s'agir de téléphones physiques (tout en un ou via un adaptateur ATA - Analog Telephone Adapter), mais aussi logiciels (ou SoftPhone) comme Ekiga ou csipsimple.
    • La téléphonie de poste à poste en local, comme le permettent les téléphones DECT (mais sans vous bourrez la tête d'onde).
    • Un nombre illimité de boites vocales, et en français s'il vous plait !
    • La mise en attente et le transfert d'un appel, d'un poste local à l'autre.

    Asterisk est un beau joujou qui reste, nous allons le voir, très simple à mettre en œuvre. Mais comme toute chose cela demande du temps. Il faut donc bien se poser l'intérêt de cette technologie dans votre configuration. Si vous désirez que votre ligne Freebox (ou autre fournisseur SIP) fasse sonner tous les téléphone sur IP (ce qui est impossible avec freephonie sans PABX), si vous désirez irriguer en téléphonie une petite entreprise à moindre frais (les grosses préférerons sûrement passer par un prestataire plutôt que bricoler cela eux-mêmes ;-), ou si, comme moi, vous êtes une famille d'indépendants qui reçoivent finalement des appels perso, comme pro, Asterisk est sans aucun doute une option à envisager sérieusement.

    Installation d'asterisk

    Avant de partir dans l'installation de paquets, sachez qu'il existe de nombreuses distribution Asterisk toutes faites (allez sur la page wikipedia d'asterisk pour en savoir plus), ainsi que des configurateur sensés être user-friendly (par exemple freePBX). Mais si vous êtes ici, c'est que vous aimez savoir ce qui se passe, en direct. Nous allons donc voir comment monter tout cela à la mano, sur une debian de base.

    La première chose à faire est évidement d'installer Asterisk. Cela se fait sans douleur sur la grande majorité des distribution modernes, par exemple debian :

    aptitude install asterisk asterisk-config asterisk-prompt-fr-proformatique
    
    Installation d'asterisk

    Ici nous avons installé l'outil, sa configuration, ainsi que, en prévision de la suite, une séries de messages en français de haute qualité pour la boite vocale.

    Ceci fait, Asterisk est prêt à être lancé avec sa configuration par défaut dans le dossier /etc/asterisk. Nous allons cependant nous en garder pour faire d'abord un peu de paramétrage.

    Paramétrage SIP

    Pour commencer nous n'allons pas faire aussi compliqué. Notre configuration va consister à déclarer deux softphones Ekiga et ainsi permettre de passer des appels internes de l'un à l'autre.

    Pour cela nous allons créer la configuration de la partie SIP en écrasant /etc/asterisk/sip.conf avec la configuration suivante :

    [general]
    defaultexpirey=1800
    dtmfmode=auto
    qualify=yes
    
    configuration de base pour le SIP

    Dans cette section [general] sont placés les paramétrages communs à tous les éléments connectés au moteur SIP d'asterisk.

    Ajout des deux postes

    A la suite de sections, nous allons en ajouter deux nouvelles, correspondant aux deux téléphones :

    [salon]
    type=friend
    username=salon
    qualify=no
    secret=salon_password
    host=dynamic
    context=maison
    language=fr
    
    [bureau]
    type=friend
    username=bureau
    qualify=no
    secret=bureau_password
    host=dynamic
    context=maison
    language=fr
    
    configuration du softphone

    Bien évidement, vous pouvez remplacer salon|bureau par les noms de votre choix, de même pour xxx_password. Ces identifiants et mots de passe seront à reporter, ainsi que l'adresse IP de la machine sur laquelle tourne asterisk, dans la configuration du softphone. Le host est dynamique car on ne connaît pas à l'avance l'IP des téléphones (ce qui est faux dans mon cas, mais bon ;-). La variable language sera utilisé par la boîte vocale. Enfin notez le context=maison commun aux deux téléphones qui vont nous permettre de programmer les extensions.

    Paramétrage des extensions

    Les extensions d'Asterisk sont un peu le plan d'adressage des numéros composés en fonction du contexte. De manière grossière, il s'agit d'associer un motif de numéro de téléphone à une commande Asterisk. En réalité, il est possible d'aller très loin et de définir de véritables scripts (avec des fonctions, des goto, etc...).

    Pour l'heure nous allons nous contenter de faire correspondre le numéro 11 à salon et 12 pour bureau. Cela se fait en écrasant le contenu de /etc/asterisk/extensions.conf par les informations suivantes :

    [maison]
    exten => 11,1,Dial(SIP/salon)
    exten => 12,1,Dial(SIP/bureau)
    
    Paramétrage du mode talkie-walkie

    Nous avons ici déclaré deux extensions dans le contexte maison (celui là même que nous avons défini pour nos téléphones). Chaque extension commence par une série de chiffre à composer sur l'un des cadrant pour déclencher l'extension. Le second paramètre est une priorité car une extension peut être un véritable script composé de plusieurs lignes. Enfin le dernier paramètre est une macro Asterisk, ici Dial, qui va composer le numéro SIP d'un des deux téléphones.

    Paramétrage du routeur

    Ceci ne vaut évidement que si votre serveur est derrière un routeur NAT. Dans ce cas, pour qu'Asterisk puisse correctement fonctionner il est nécessaire de le configurer pour permettre la redirection du port 5060, en UDP, vers le port 5060 de la machine Asterisk sur votre réseau local.

    Premier lancement d'Asterisk

    Nous pouvons maintenant faire nos premiers tests. Pour cela, nous allons arrêter Asterisk qui a sûrement été lancé automatiquement lors de l'installations (/etc/init.d/asterisk stop), puis le relancer à la main en mode "console debug" par la commande asterisk -cvvv.

    /etc/init.d/asterisk stop
    Stopping Asterisk PBX: asterisk.
    asterisk -cvvv
    ....
    [Aug 17 13:39:32] NOTICE[13575]: chan_sip.c:18223 handle_response_peerpoke: Peer 'salon' is now Reachable. (108ms / 2000ms
    [Aug 17 13:49:10] NOTICE[13575]: chan_sip.c:18223 handle_response_peerpoke: Peer 'bureau' is now Reachable. (108ms / 2000ms
    
    Lancement d'asterisk

    Ok asterisk est lancé en mode console. Il ne reste qu'à paramétrer les Ekiga's.

    Paramétrage des softphones

    Un softphone (ou téléphone SIP) est un terme générique désignant aussi bien une application SIP sur votre ordinateur (ex. ekiga) ou un terminal mobile (ex. android), qu'un téléphone physique sur IP ou encore un ATA (Analog Telephone Adapters) transformant un téléphone standard en téléphone sur IP. Pour ma part j'utilise deux ATA Linksys (PAP2T), un terminal Android avec le logiciel libre CSIPSimple et deux Ekiga sous Windows et sous Linux.

    Pour paramétrer Ekiga, rien de plus simple. Lancez la bête, allez dans Édition → Comptes puis Comptes → Ajouter un compte SIP. Pour le Nom, mettez ce qui vous fait plaisir.

    Registrar qui doit contenir l'adresse IP ou le nom de la machine sur laquelle est lancée Asterisk. Pour utilisateur et Identifiant d'authentification, utilisez la même valeur username qui nous avons saisi dans la configuration SIP d'asterisk pour ce poste. Et enfin le mot de passe provenant lui aussi de sip.conf Asterisk. Validez et normalement Ekiga devrait indiquer que le compte est en état Inscrit. Faire de même avec le second post.

    Si Ekiga pose problème, une option utile est de le lancer en mode debuggage par la commande ekiga -d4. Cela devrait produire suffisamment de traces en console pour permettre de trouver la solution.

    Lorsque le compte passe en état Inscrit, cela devrait provoquer du côté d'Asterisk un message du genre Peer 'salon' is now Reachable. (117ms / 2000ms). Lorsque les deux téléphones sont actifs, vous pouvez vérifier leur rattachement à asterisk en tapant la commande sip show peers

    *CLI>sip show peers
    Name/username              Host            Dyn Nat ACL Port     Status
    salon/salon              192.168.154.11   D          5060     OK (48 ms)
    bureau/bureau                  192.168.154.22   D          5060     OK (108 ms)
    2 sip peers [Monitored: 2 online, 0 offline Unmonitored: 0 online, 0 offline]
    *CLI>#
    
    Lancement d'asterisk

    Maintenant le test, aller dans l'application SIP du téléphone salon et taper le numéro 12, ce qui doit faire sonner le second téléphone et permettre une communication entre les deux appareils. Dans la console Asterisk, nous voyons la trace de l'appel apparaître : Qui as dit qu'asterisk était compliqué ? Enfin si, c'est super compliqué, mais pour l'instant, il reste magnifiquement simple à mettre en œuvre.

    Connexion à un fournisseur SIP

    Pour l'instant nous avons surtout réussi à fabriquer deux talkie-walkie de luxe. Il est temps de connecter tout cela au vrai monde. Free, à travers son service Freephonie, propose la téléphone SIP en standard à tous ses abonnés. Il est donc possible de connecter ce service à notre PBX. De même vous avez sur internet de très nombreux fournisseurs SIP plus ou moins sympa ou compétitifs. Comme j'ai mon activité professionnelle dans mon garage, et que le numéro de notre freebox est dédiée depuis longtemps à notre famille, j'ai eu besoin d'un autre numéro pour mon boulot. Plutôt que de faire tirer une ligne, j'ai simplement créé un compte chez un fournisseur SIP et le tour était joué. Après pour le choix du fournisseur, c'est question de goût, mais pour l'instant je suis très content d'IPPI qui propose gratuitement un numéro local (en 01, 02, etc..) et permet de recharge par Paypal son compte pour les appels sortants.

    Bref, quel que soit votre fournisseur SIP, vous allez pouvoir le connecter à votre PBX. Du coup vous allez pouvoir avoir notre propre boîte vocale (en prenant soin de déconnecter celle du fournisseur), faire sonner tous les téléphones lorsque l'on est appelé de l'extérieur, et aussi passer jusqu'à des appels simultanés (2 pour freephonie, 3 sur IPPI, variable d'un fournisseur à l'autre).

    La première chose à faire est d'ajouter un nouveau partenaire de jeu à sip.conf comme pour le téléphone. Mais à la différence du téléphone, il faut en plus ajouter un enregistrement du fournisseur dans la section general pour prendre en charge les appels entrant. Cela nous donne pour freephonie :

    [general]
    ...
    register => 09XXXXXX:freephonie_password@freephonie.net
    
    [freephonie]
    type=peer
    insecure=port,invite
    host=freephonie.net
    username=09XXXXXXXX
    secret=freephonie_password
    context=from-freephonie
    language=fr
    
    configuration de freephonie

    Ici il vous faut remplacer 09XXXXXX et freephonie_password respectivement pas l'identifiant et le mot de passe freephonie. Dans la section [general], ajoutez la commande register permettant à Asterisk de s'enregistrer sur FreePhonie. Ensuite nous créeons une section [freephonie] pour déclarer le nouveau partenaire. Le paramètre insecure est spécifique à se service. Ce paramétrage est le même pour IPPI mais il faudra peut-être le modifier pour un autre fournisseur. Enfin, point important, on définit un contexte from-freephonie qui nous servira pour de nouvelles extension spécifiques aux appels entrant de ce partenaire SIP.

    Si vous n'avez pas défini de mot de passe, vous n'avez sûrement pas activé le SIP non plus. Il vous faut donc aller dans la console de votre freebox, section Téléphone puis Gestion de mon compte SIP. Vous y trouverez un rappel de votre identifiant/numéro de téléphone, la possibilité de définir un mot de passe une case à cocher pour activer le service SIP et enfin, un bouton radio à placer sur Rediriger les appels entrants vers le compte SIP de sorte à ce que les appels soient redirigés sur asterisk et non plus sur le téléphone branché à la freebox. Ceci fait, terminez en cliquant sur Enregistrer.

    Nous allons maintenant rajouter deux nouvelles extensions.

    [default]
    exten => 11,1,Dial(SIP/salon)
    exten => 12,1,Dial(SIP/bureau, 10)
    exten => 12,2,Voicemail(maison)
    exten => 600,1,VoiceMailMain(maison)
    exten => _0.,1,Dial(SIP/freephonie/${EXTEN})
    
    [from-freephonie]
    exten => s,1,Dial(SIP/salon&SIP/bureau,10)
    exten => s,2,Voicemail(maison)
    
    Configuration des boîtes vocales

    La première commune à tous les téléphones du groupe maison, va nous permettre de passer des appels en utilisant les tarifs de free. Comme vous le voyez, il s'agit d'une expression régulière indiquant "tous les numéros commençant par un 0". La variable ${EXTEN} permet de composer ce numéro en passant par le partenaire freephonie (défini dans sip.conf).

    En réalité La variable EXTEN est ici la variable correspondant au numéro effectivement tapé. ${...} est quant à elle une fonction permettant d'en récupérer le contenu et qui peut prendre deux paramètres optionnels. Le début de la chaîne à retourner (ex. ${1234:3} renverra 34). Et la taille de la chaîne à retourner (${1234:3:1} renverra 3). Ainsi un SIP/ippi/33${EXTEN:1} renverra pour le numéro 0102030405 la chaîne /SIP/ippi/33102030405.

    La deuxième extension, cette fois spécifique au contexte from-freephonie nous permet de gérer les appels entrant. Ici nous indiquons à Asterisk de faire sonner nos deux téléphones simultanément pendant 10 secondes. L'appel sera transféré au premier qui décrochera. Dans le cas contraire (priorité 2 sur la même extension), nous basculons sur la boite vocale.

    Nous pouvons maintenant relancer asterisk et déjà vérifier que FreePhonie est bien connecté en utilisant la commande sip show peers, puis en tentant de s'appeler avec un portable par exemple.

    Conclusion

    J'espère avoir au moins démontré qu'Asterisk est un monstre gentil dont il ne faut vraiment pas avoir peur. Personnellement la simplicité de mis en œuvre et la qualité du résultat obtenu m'a bluffé au regard de tout ce que cet outil sait faire. Chapeau bas donc pour ce très beau soft et bonne téléphonie à vous.

    Tweet

    Gravatar de Artisan Numérique
    Original post of Artisan Numérique.Votez pour ce billet sur Planet Libre.

    Jeyg : ownCloud + Transmission

    lundi 11 mai 2015 à 14:17

    Transmission est un client Bittorrent disponible sur Linux et Mac. Il a la particularité de proposer une base commune pour différentes interfaces: Qt, GTK, console ou client web.

    Cela rend donc possible l'installation du démon Transmission ainsi que son interface web sur un serveur. Via une simple page web, il devient ainsi possible de gérer vos torrents:

    Clutch-LargeS'il est un excellent client Bittorrent, l’absence de quelques fonctionnalités se fait cruellement sentir sur cette interface web. Il est notamment impossible de récupérer vos fichiers téléchargés sur votre machine (direct download du serveur vers le client). Impossible également de déplacer les fichiers reçus dans autre dossier de votre serveur.

    Ça tombe bien, tout cela, ownCloud sait parfaitement le faire. Il peut donc être intéressant de coupler ces deux logiciels. Les téléchargements seront toujours a gérer depuis Transmission, mais les fichiers téléchargés pourront être gérés depuis ownCloud. En bonus, nous verrons aussi qu'il est possible d’accéder a l'interface de Transmission directement depuis celle d'ownCloud.

    Installez ownCloud, via les dépôts par exemple:
    http://software.opensuse.org/download/package?project=isv:ownCloud:community&package=owncloud

    Une fois ownCloud installé et votre compte configuré, créez un dossier Downloads. Puis, trouvez l'emplacement de ce dossier nouvellement créé dans votre système de fichier. Par exemple, /var/www/owncloud/data/user/Downloads. L'emplacement dépend de votre configuration ownCloud.
    Installez transmission-daemon, par exemple via les dépôts Debian:

    # aptitude install transmission-cli transmission-common transmission-daemon

    Maintenant, il ne vous reste plus qu’à attribuer les droits nécessaires au dossier qui va être partagé entre transmission et apache (owncloud).

    Direction le fichier de configuration de transmission:

    /etc/transmission-daemon/settings.json

    Modifiez le paramètre "download-dir" pour le faire pointer vers le dossier Downloads que vous avez créé plus tôt sur ownCloud. Vous pouvez également (je trouve que c'est mieux) ne pas modifier le paramètre par défaut (qui est "/home/debian-transmission") et simplement supprimer ce dossier, puis créer un lien symbolique pointant vers le dossier Downloads. Comme ceci:

    # rm -r /home/debian-transmission
    # ln -l /var/www/owncloud/data/user/Downloads /home/debian-transmission

    Ensuite, nous allons SGID le dossier Downloads.

    # chmod 2774 /var/www/owncloud/data/user/Downloads

    Pour ceux qui se disent:

    "chmod 2774 ?! Pardon ? Je croyais qu'il n'y avait que 3 chiffres (user, group, other) ! On m'aurait menti ?!"

    Il fallait lire le manuel:

    La valeur pour le mode numérique est constituée de 1 à 4 chiffres en octal (0 à 7), calculés en additionnant les bits de valeurs 4, 2 et 1, tout bit non mentionné étant considéré comme des zéros en début de chaîne. Le premier chiffre correspond aux attributs identifiant de l'utilisateur (4), identifiant du groupe (2) et suppression restreinte ou bit sticky (1). Le second chiffre correspond aux autorisations de lecture (4), écriture (2) et exécution (1) pour l'utilisateur propriétaire du fichier. Les troisième et quatrième chiffres correspondent respectivement aux autorisations d'accès pour les membres du groupe du fichier, et pour les autres utilisateurs. Les valeurs ont les mêmes significations que pour le deuxième chiffre.

    Ici, l'identifiant de groupe (SGID) appliqué au dossier permet de s'assurer que tous les fichiers crées au sein de ce dossier auront pour groupe propriétaire le groupe du dossier parent. C'est extrêmement utile dans notre cas, car l'utilisateur debian-transmission va créer des fichiers. Par défaut, ces fichiers appartiendraient a debian-transmission:debian-transmission (user:group). Grâce au SGID, les fichiers appartiendront a debian-transmission:www-data (en supposant que www-data est le groupe propriétaire de Downloads). Ceci permet donc à la fois à Apache et Transmission de posséder les fichiers.

    Il n'y a plus qu'à modifier le umask de transmission dans son fichier de configuration (/etc/transmission-daemon/settings.json). Habituellement, les umask sont représentés en octal (base 8). Malheureusement, json ne supporte pas cela, donc nous devons le convertir en décimal (base 10).

    Ici nous avons de la chance, vu que nous souhaitons donner tous les droits a l'utilisateur et groupe propriétaire, cela nous donne un umask de 002. Le chiffre 2 s'écrit de la même façon en base 8 et 10... C'est à dire, 2.

    Juste pour la culture, il est possible d'effectuer ce genre de conversion via bash:

    $ echo $(( 8#002 ))
    2
    $ echo $(( 8#022 ))
    18

    Bref, on change le paramètre "umask" à 2. On reload transmission-daemon pour appliquer tous les changements.

    # service transmission-daemon reload

    Dernière étape, optionnelle, à effectuer seulement si vous aviez déjà des fichiers présents dans Downloads. On va juste s'assurer que les permissions sont bonnes, et actualiser l'index d'ownCloud, afin qu'il actualise les permissions à son niveau. En effet, malgré tous mes efforts, j'obtenais toujours le message "You don’t have permission to upload or create files here". C'était tout simplement dû à cet index qu'il fallait rafraichir.

    # cd /var/www/owncloud/data/user/Downloads
    # chmod -R g+w *
    # usermod -s /bin/bash www-data
    # su - www-data
    $ cd /var/www/owncloud/
    $ php console.php files:scan --all
    $ logout
    # usermod -s /usr/sbin/nologin www-data

    Et voilà ! Vous pouvez à présent télécharger un iso de la toute fraiche Debian Jessie sur votre serveur Bittorrent, puis le récupérer sur votre client via ownCloud.

    transmission-dl-debian

    owncloud-debian-jessie

    Credit:
    Upload/Download picture by John Trainor, under Creative Commons BY 2.0.

    Gravatar de Jeyg
    Original post of Jeyg.Votez pour ce billet sur Planet Libre.