Skip to content

Linux Attitude

Le libre est un état d'esprit

Archive

Tag: planet-libre

I'm back ! Pour ceux qui suivent, les vacances c'était sympa. Allez au Vietnam, vous verrez, c'est beau et pas cher.

Aujourd'hui, comme à chaque fois que je sens que je n'avance pas trop, je vais faire une liste de sujets que j'aurais aimé traiter mais dont je sais pour lesquels je ne trouverai pas le temps et le courage d'écrire un article, j'essaie donc de vous fournir un lien intéressant à la place.

Sujet non traités :

Lectures intéressantes :

Pas d'article parce que sujet trop naze :

Niveau : Star Star Star Empty Empty
Résumé : export PS1="> "

Désolé de ne pas écrire plus souvent. Et ca risque de durer encore un peu puisque je pars en vacances ...

PS veut dire prompt string. Les 4 prompt string de bash sont les chaines de caractères affichées par le shell en différentes situations. Nous allons nous intéresser à PS1 mais sachez que la suite vaut pour toutes les autres.

Exemples

Je vais faire simple : des exemples de chaînes ainsi que la capture d'écran associée, il ne vous reste plus qu'a choisir et à copier/coller dans votre .bashrc

Toutes les captures ont été faites avec les settings suivants :

  • user : peck
  • hostname : mamachine.linux-attitude.fr

Exemples unilignes

PS1Fond noir / Fond Blanc
"[\t] \[\e[01;32m\]\u\[\e[01;33m\]@\h\[\e[00m\]:\[\e[01;34m\]\w\[\e[00m\]\$ " black
white
"\[\033[01;32m\]\u@\h \[\033[01;34m\]\W \$ \[\033[00m\]" black
white
"\[\033[0;34m\][\[\033[0;31m\]$(date +%H%M)\[\033[0;34m\]]\[\033[0;34m\][\[\033[1;31m\]\u@\h:\w\[\033[0;34m\]]\[\033[1;37m\]$\[\033[0m\] " black
white
 
 

Exemples multilignes

PS1Fond noir / Fond Blanc
"\[\e]0;\u@\h \w\a\]\[\e[1;31m\]\u\[\e[1;34m\]@\[\e[0;32m\]\h \[\e[0;33m\]\w \[\e[0;31m\]$(uptime|sed -e 's/.*: \([^,]*\), \([^,]*\), \([^,]*\).*/\1 \2 \3/') \[\e[0;34m\]\D{%Y-%m-%d %H:%M:%S} \[\e[0m\]\n\$ " black
white
 
 

Exemples monochromes

PS1Fond noir / Fond Blanc
"[\t][\u@\h:\w]\$ " black
white
"\u@\h \w> " black
white
"\!|\h|$(uname -r)|\$?> " black
white
"\[\e[1;34m\]\u@\h \w>\[\e[0m\] " black
white
"\[\e]2;\u@\H \w\a\e[32;1m\]>\[\e[0m\] " black
white
(Ici tout est dans le titre)

Faites votre choix

Cookbook

Si les exemples ne vous conviennent pas, voici un ensemble de recettes pour créer un prompt qui vous ressemble :

  • load average : "\$(cut -d ' ' -f 1-3 /proc/loadavg)"
  • uptime : "\$(uptime | cut -d, -f1 | sed -e 's/.*up//')"
  • un prompt qu'on peut copier/coller sans provoquer d'erreurs : ": <texte> ;"
  • user@host:/répertoire : "\u@\h:\w"
  • date et heure : "[\d \t]"
  • un bip à chaque ligne : "\[\a\]"
  • changer la couleur du texte (code couleur voir ci dessous) : "\[\e[<code_couleur>m\]"
  • revenir à la couleur originale du shell (en fin de ligne) : "\[\e[0m\]"
  • code de retour de la dernière commande : "-> \$?"
  • nombre de jobs mis en background par le shell : "[\j]"
  • nombre de jobs en pause : "\$(jobs | wc -l | awk '{print $1}')"
  • nombre de processus en cours d'exécution : "\$(ps ax | wc -l | tr -d ' ')"
  • afficher le tty en cours : "$(temp=$(tty) ; echo ${temp:5})"
  • chemin limité à 20 caractères : "\$(a='\w';b=\${a: -20};b=\${b:+..\$b};echo \${b:-\$a})"
  • changer le texte de titre du terminal (xterm, konsole ...) : "\[\e]0;<Texte>\a\]"
  • afficher l'état de la gestion de version en cours (voir ci dessous) : "$(__vcs_dir)"
  • afficher la sortie d'une commande : "\$(<commande>)"

Codes couleur ANSI

Il est possible d'indiquer plusieurs codes simultanément en les séparant par un ';'.

From wikipedia :

Code couleur
Code Effect Note
0 Reset / Normal all attributes off
1 Intensity: Bold
2 Intensity: Faint not widely supported
3 Italic: on not widely supported. Sometimes treated as inverse.
4 Underline: Single
5 Blink: Slow less than 150 per minute
6 Blink: Rapid MS-DOS ANSI.SYS; 150 per minute or more
7 Image: Negative inverse or reverse; swap foreground and background
8 Conceal not widely supported
21 Underline: Double not widely supported
22 Intensity: Normal not bold and not faint
24 Underline: None
25 Blink: off
27 Image: Positive
28 Reveal conceal off
30–39 Set foreground color, normal intensity 3x, where x is from the color table below
40–49 Set background color, normal intensity 4x, where x is from the color table below
90–99 Set foreground color, high intensity aixterm
100–109 set background color, high intensity aixterm
Table des couleurs
Intensité 0 1 2 3 4 5 6 7 9
Normal Black Red Green Yellow[5] Blue Magenta Cyan White reset
Brillant Black Red Green Yellow Blue Magenta Cyan White

Gestion de version

Pour que la méthode de gestion de version fonctionne, il faut ajouter le code suivant dans son .bashrc :

alias svnwdiff="svn diff --diff-cmd /home/spaillar/vimdiff-wrapper.sh"
function cvswdiff { vimdiff $1 <(cvs co -p $2 $(cat $(dirname $1)/CVS/Repository)/$(basename $1)) ;} 

function vlog { 
# cvs
cvs_log() {
   [ -d "CVS" ] || return 1
   cvs log "$@" | vim -
}

# subversion
svn_log() {
    [ -d ".svn" ] || return 1
    svn log -v "$@" | vim -
}
# git
git_log() {
    base_dir=$(git rev-parse --show-cdup 2>/dev/null) || return 1
    git log --name-status "$@" | vim -
}

git_log "$@" || svn_log "$@" || cvs_log "$@"

}

function vwdiff {
vim -c ":VCSVimDiff" $1
}

function vpull { 
# cvs
cvs_pull() {
   [ -d "CVS" ] || return 1
   cvs -q up -d
}

# subversion
svn_pull() {
    [ -d ".svn" ] || return 1
    svn up 
}
# git
git_pull() {
    base_dir=$(git rev-parse --show-cdup 2>/dev/null) || return 1
    git pull 
}

git_pull "$@" || svn_pull "$@" || cvs_pull "$@"

}



_bold=$(tput bold)
_normal=$(tput sgr0)
_yellow=$(tput setaf 3)
_green=$(tput setaf 2)

__vcs_dir() {
  local vcs base_dir sub_dir ref
  sub_dir() {
  local sub_dir
  sub_dir=$(readlink -f "${PWD}")
  sub_dir=${sub_dir#$1}
  echo ${sub_dir#/}
  }

  # git
  git_dir() {
      base_dir=$(git rev-parse --show-cdup 2>/dev/null) || return 1
      if [ -n "$base_dir" ]; then
        base_dir=`cd $base_dir; pwd`
      else
        base_dir=$PWD
      fi
      sub_dir=$(git rev-parse --show-prefix)
      sub_dir="/${sub_dir%/}"
      ref=$(git symbolic-ref -q HEAD || git name-rev --name-only HEAD 2>/dev/null)
      ref=${ref#refs/heads/}
      vcs="git"
      alias pull="git pull"
      alias commit="git commit"
      alias push="git push"
#     alias revert="svn revert"
    }

  # subversion
  svn_dir() {
      [ -d ".svn" ] || return 1
      base_dir="."
      while [ -d "$base_dir/../.svn" ]; do base_dir="$base_dir/.."; done
      base_dir=`cd $base_dir; pwd`
      sub_dir="/$(sub_dir "${base_dir}")"
      ref=$(svn info "$base_dir" | awk '/^URL/ { sub(".*/","",$0); r=$0 } /^Revision/ { sub("[^0-9]*","",$0); print r":"$0 }')
      vcs="svn"
      alias pull="svn up"
      alias commit="svn commit"
      alias push="svn ci"
      alias revert="svn revert"
    }

  # mercurial
  hg_dir() {
      base_dir="."
      while [ ! -d "$base_dir/.hg" ]; do base_dir="$base_dir/.."; [ $(readlink -f "${base_dir}") = "/" ] && return 1; done
      base_dir=$(readlink -f "$base_dir")
      sub_dir="/$(sub_dir "${base_dir}")"
      ref=$(< "${base_dir}/.hg/branch")
      hgqtop=$(hg qtop)
      if [[ $hgqtop == 'No patches applied' ]]; then 
        extra="";
      else 
        extra=" >> $hgqtop"
      fi
      vcs="hg"
  }

  # cvs
  cvs_dir() {
      [ -d "CVS" ] || return 1
      base_dir="."
      while [ -d "$base_dir/../CVS" ]; do base_dir="$base_dir/.."; done
      base_dir=`cd $base_dir; pwd`
      sub_dir="/$(sub_dir "${base_dir}")"
      vcs="cvs"
      alias pull="cvs -q up -d"
      alias commit="cvs commit"
      alias push="cvs ci"
      alias revert="cvs revert"


  }

  # hg_dir || git_dir || svn_dir || cvs_dir || base_dir="$PWD"
  git_dir || svn_dir || cvs_dir || base_dir="$PWD"
  echo "${_green}${_bold}${vcs:+($vcs)}${_yellow}${_bold}${vcs:+[$ref]}${_normal}${base_dir/$HOME/~}${_yellow}${_bold}${vcs:+${_bold}${sub_dir}${_normal}$extra}"
}

PS1='${debian_chroot:+($debian_chroot)}\u@\h:$(__vcs_dir)${_normal}\$ '

Et vous quel prompt utilisez vous ?

Niveau : Star Star Empty Empty Empty
Résumé :

Aujourd'hui nous allons mettre en valeur deux articles précédents. J'espère que vous avez déjà mis votre home sous un système de suivi de version pour suivre ses évolutions. J'ai déjà décrit à dans un article précédent. En résumé :

$ cd
$ git init
$ git add .bashrc # et tout ce que vous voulez
$ git commit

Le but étant de propager tout cela automatiquement sur différentes machines. Il est difficile de toujours penser à mettre a jour lorsqu'on fait une modification. C'est pourquoi nous allons mettre à profit l'article précédent et intercepter ssh. Grâce à cela le home de toutes nos machines seront à jour sans qu'on ait à s'en préoccuper.

Mise en place

Cette fois nous allons modifier le script en question pour lancer automatiquement une mise à jour de git de façon furtive à chaque connexion ssh. La méthode run était prévue pour :

# test permettant de savoir qu'on est bien sur le bon dépôt git pour les mises à jour (id du premier commit)
MASTER=11edf02e95ceac1fa58d4444f82f8cd4ae9c1cf5
# command tu run via the ssh socket
run()
{
    # no test if running init
    if [ "$MASTER" != "" ]
    then
        # test if distant has OUR git
        ssh -S "$1" XXX '[ -e /usr/bin/git ] && [ -d .git ] && git rev-list --reverse master 2>/dev/null | head -1' | grep "$MASTER" > /dev/null
    else
        ssh -S "$1" XXX '[ -e /usr/bin/git ]'
    fi
    if [ $? -eq 0 ]
    then
        # if yes push updates
        tmp=$(mktemp ~/.sshgit.XXXXXX)
        echo "#!/bin/sh" > $tmp
        echo "exec ssh -S $1 \"\$@\"" >> $tmp
        chmod +x $tmp
        GIT_SSH=$tmp git push --all ssh://XXX/~ > /dev/null 2> /dev/null
        rm -f $tmp
        ssh -S "$1" XXX 'git checkout -f > /dev/null'
    fi
}

De plus j'ai ajouté un paramètre spécial permettant d'initialiser le dépôt de la machine en face. En effet, on ne va pas forcer la mise à jour si le home en face n'a pas de dépôt, il se peut que l'utilisateur ne le veuille pas. C'est aussi pour ce qu'on vérifie que le dépôt git utilisé contient bien le bon commit initial.

            ssh -S "$2" XXX '[ -e /usr/bin/git ] && [ ! -d .git ] && git init > /dev/null'

Le script complet.

Usage

Pour que ça fonctionne on ajoute un alias et tant qu'à faire, on ajoute le script au dépôt :

$ alias ssh='~/.sshgit' # à mettre aussi dans le .bashrc
$ git add .sshgit
$ git commit

Et maintenant on initialise la machine en face :

$ ssh -= autremachine.net

Et voila, tout ssh ultérieur résultera en un git push suivi d'un git checkout, plus besoin de réfléchir. Ce qui veut dire qu'au fur et à mesure de vos ssh votre home se propagera un peu partout, que le réseau où vous êtes soit privé ou non car c'est la connexion normale du ssh qui est empruntée. Reste juste à faire un ssh de temps en temps un peu partout pour mettre à jour :-)

Autre

Si vous n'avez pas git sur toutes les machines, vous pouvez aussi utiliser autre chose pour synchroniser automatiquement vos home. rsync par exemple (regardez l'option -u pour les mises à jour) ou scp.

Mais pour le coup je vous laisse écrire la méthode :)

^--- billet invité

Niveau : Star Star Star Empty Empty
Résumé : proxy ndp

Aujourd'hui nous allons parler d'IPv6. Pas du troll sur son arrivée imminente (ou pas), mais de situations qui nécessitent l'utilisation d'une fonctionnalité du noyau linux appelée proxy NDP.

Rappels sur IPv6 et NDP (les habitués d'IPv6 peuvent passer)

En IPv4, on dispose du protocole ARP pour trouver, à partir de l'adresse IP, l'adresse MAC à laquelle envoyer le paquet Ethernet sur le même réseau. Si c'est sur un autre réseau, il suffit d'avoir une table de routage et de connaître le routeur (la passerelle) pour cette destination, à qui on envoie le paquet.

En IPv6, on fait fi d'ARP pour utiliser ICMPv6. Vous me direz, on ne fait que reporter le problème, on n'a toujours pas l'adresse MAC : c'est là qu'intervient la notion de lien local. En effet vous avez déjà du remarquer qu'à peine votre interface réseau montée, vous disposez d'une adresse de lien local (obtenue à partir de votre adresse MAC).

# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 00:19:66:8c:b0:d9
          inet6 addr: fe80::219:66ff:fe8c:b0d9/64 Scope:Link
[...]

De la même manière, vos voisins sur le même lien Ethernet ont leur adresse de lien local, et c'est en utilisant celle-ci combinée au protocole ICMPv6 qu'on voit passer les requêtes NDP (Neighbor Discovery Protocol) de découverte de voisinage. On y retrouve exactement le principe de l'ARP d'IPv4 (who has/target is at), avec un nouveau vocabulaire (neighbor solicitation/neighbor advertisement).

# tcpdump -ni eth0 ip6
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes

16:06:29.756895 IP6 2a01:e35:3e93:68c0:4d0a:f82b:3678:aaac &gt; ff02::1:ff8c:b0d9: ICMP6, neighbor solicitation, who has 2a01:e35:3e93:68c0:219:66ff:fe8c:b0d9, length 32

16:06:29.757294 IP6 2a01:e35:3e93:68c0:219:66ff:fe8c:b0d9 &gt; 2a01:e35:3e93:68c0:4d0a:f82b:3678:aaac: ICMP6, neighbor advertisement, tgt is 2a01:e35:3e93:68c0:219:66ff:fe8c:b0d9, length 32
Position du problème

Ce petit rappel étant fait, voici le problème que l'on peut rencontrer en IPv6 : un fournisseur de connectivité IPv6 vous donne (annonce) depuis son routeur un /N sur lequel vous pouvez utiliser des adresses IPv6. Là où le bât blesse, c'est que son routeur désire voir à plat (sur le même lien local) toutes les IPv6. Impossible donc à première vue de placer votre routeur juste après celui du fournisseur et d'organiser les IPv6 en réseaux comme bon vous semble. A noter qu'on rencontre le même problème en IPv4 avec un fournisseur qui donne un /N et qui veut le voir à plat. Dans ce cas de figure, on peut utiliser le proxy ARP (dans le noyau). La méthode pour l'IPv6 présentée plus bas est ni plus moins son homologue en IPv6.

On rencontre cette situation par exemple chez Free, où la Freebox annonce un /64 (l'abonné dispose même d'un /60), ou encore chez OVH lorsque vous possédez un serveur dédié, où le routeur d'OVH vous annonce un /56 rien que pour vous (même si dans le manager c'est indiqué un /64, vous pouvez utiliser ce /56). Je présume que c'est le cas pour d'autres opérateurs, ou d'autres hébergeurs comme Dedibox.

Que l'on veuille organiser son réseau domestique avec son propre routeur IPv6 derrière sa freebox, ou que l'on veuille répartir en sous-réseaux le /56 de son serveur dédié dans des machines virtuelles ou des containers, le routeur veut voir le réseau à plat (sur le même lien) c'est ce qui pose problème. La solution évidente serait de pouvoir faire du routage : si on pouvait intervenir sur la table de routage de ce routeur (via le manager d'OVH, via la console de gestion de Free, ou via le protocole DHCPv6 s'il est implémenté me dit peck (NDM(note de moi): rechercher prefix delegation)), il suffirait de dire que pour joindre tel sous-réseau il faut contacter le routeur à l'adresse donnée. Malheureusement, on ne peut pas pour l'instant, il faut donc trouver autre chose.

La solution que je vais vous proposer et détailler est un proxy NDP : il s'agit de faire croire au routeur (la freebox ou le routeur OVH) qu'il voit votre réseau à plat (sur le même lien), en transférant les messages NDP d'un côté et de l'autre. Cette solution n'est pas nouvelle : Thierry Fournier propose depuis maintenant 1 an et demi un excellent tutorial rapportant son expérience avec l'IPv6 chez Free et comment il a organisé son réseau domestique. Le Wiki Gentoo dispose lui aussi d'un excellent article à ce sujet.

Une autre solution, plus ancienne, est d'utiliser le brouting ou switch filtrant (on route l'IPv4 et on laisse passer l'IPv6), mais je ne la détaillerai pas.

Solution à base de proxy NDP

Pour résumer, il va s'agir de :

  • posséder un noyau linux supérieur à 2.6.19, à partir duquel le proxy NDP a été implémenté
  • activer le routage IPv6 et le proxy NDP dans le noyau
  • organiser son réseau (côté routeur) en sous-réseaux (côté LAN)
  • router ces sous-réseaux du routeur vers les LANs
  • configurer les hôtes
  • configurer le proxy NDP côté LAN pour que les hôtes aient connaissance du routeur
  • configurer le proxy NDP côté routeur pour que le routeur ait connaissance des hôtes

Pour la suite, comme les explications pour Free ont déjà été données sur Internet, je vous propose d'expliquer le proxy NDP dans le contexte d'un serveur dédié chez OVH avec des machines virtuelles (VM). Notez bien que c'est le même principe, juste le contexte de l'explication qui diffère.

Voyons comment ce réseau IPv6 s'organise :


.----------. 2001:2:3:4500::/56   .---------------.
| routeur  |______________________|    serveur    |
|   IPv6   |                  eth0|     dédié     |
*----------*                      *---------------*
                                veth1 |        | veth2
                                      |        |
                   2001:2:3:4501::/64 |        | 2001:2:3:4502::/64
                                      |        |
                                 eth0 |        | eth0
                                    [VM 1]   [VM 2]

Comme vous le voyez, le routeur fournit à ce serveur le préfixe 2001:2:3:4500::/56 :

2001:0002:0003:45 00::
\_______________/ \_..._/
 partie réseau     partie pour le serveur
    (56)            (72)

Que l'on va diviser en deux /64 pour chaque VM :

  • 2001:2:3:4501::/64 pour la VM1
  • 2001:2:3:4502::/64 pour la VM2

A noter que chez OVH, votre routeur est joignable sur le /56 suivi de 5*FF. Supposons alors que dans notre cas, le routeur soit à l'adresse 2001:2:3:45FF:FF:FF:FF:FF.

Sur le serveur, on route ces sous-réseaux vers les VM :

# ip route add 2001:2:3:4501::/64 dev veth1
# ip route add 2001:2:3:4502::/64 dev veth2
# ip -6 route list
2001:2:3:4501::/64 dev veth1  metric 1024  mtu 1500 advmss 1440 hoplimit 4294967295
2001:2:3:4502::/64 dev veth2  metric 1024  mtu 1500 advmss 1440 hoplimit 4294967295
2001:2:3:45FF:FF:FF:FF:FF dev eth0  metric 1024  mtu 1500 advmss 1440 hoplimit 4294967295
2001:2:3:4500::/56 dev eth0  proto kernel  metric 256  expires 2427074sec mtu 1500 advmss 1440 hoplimit 4294967295
fe80::/64 dev eth0  metric 256  mtu 1500 advmss 1440 hoplimit 4294967295
fe80::/64 dev veth1  metric 256  mtu 1500 advmss 1440 hoplimit 4294967295
fe80::/64 dev veth2  metric 256  mtu 1500 advmss 1440 hoplimit 4294967295
default via 2001:2:3:45ff:ff:ff:ff:ff dev eth0  metric 1024  mtu 1500 advmss 1440 hoplimit 4294967295

Avant d'aller plus loin, n'oubliez pas d'activer le routage IPv6 ainsi que le proxy NDP. Par exemple avec les directives suivantes dans /etc/sysctl.conf suivi d'un sysctl -p pour appliquer :

net.ipv6.conf.default.forwarding=1
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.default.proxy_ndp=1
net.ipv6.conf.all.proxy_ndp=1

Bien entendu, vous pouvez activer cela plus finement uniquement sur les interfaces concernées.

Pour la configuration des hôtes, il s'agit juste de leur indiquer qui est leur routeur, la route par défaut vers ce routeur, et enfin d'ajouter une ou plusieurs adresses dans le préfixe alloué. Par exemple, on configure la VM1 avec l'adresse 2001:2:3:4501::1/64 :

# ip route add 2001:2:3:45ff:ff:ff:ff:ff/128 dev eth0
# ip route add default via 2001:2:3:45ff:ff:ff:ff:ff
# ip address add 2001:2:3:4501::1/64 dev eth0
# ip -6 route list
2001:2:3:4501::/64 dev eth0  metric 256  mtu 1500 advmss 1440 hoplimit 4294967295
2001:2:3:45ff:ff:ff:ff:ff dev eth0  metric 1024  mtu 1500 advmss 1440 hoplimit 4294967295
fe80::/64 dev eth0  metric 256  mtu 1500 advmss 1440 hoplimit 4294967295
default via 2001:2:3:45ff:ff:ff:ff:ff dev eth0  metric 1024  mtu 1500 advmss 1440 hoplimit 4294967295
# ip -6 address list
1: lo:  mtu 16436
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0:  mtu 1500
    inet6 2001:2:3:4501::/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::218:51ff:fede:aca9/64 scope link
       valid_lft forever preferred_lft forever

La même chose pour la VM2 avec l'adresse 2001:2:3:4502::1/64.

Il faut maintenant configurer le proxy NDP côté LAN pour que les hôtes (VM) aient connaissance du routeur. Sur le serveur et pour chaque interface où il faut faire apparaître le routeur avec le proxy NDP, procéder comme suit :

# ip neigh add proxy 2001:2:3:45ff:ff:ff:ff:ff dev veth1
# ip neigh add proxy 2001:2:3:45ff:ff:ff:ff:ff dev veth2

La même chose de l'autre côté pour que le routeur ait connaissance des VM. Pour chaque adresse IPv6 utilisée par les hôtes (VM), il faut explicitement la faire apparaître avec le proxy NDP. Par exemple pour les 2 VM où on a configuré l'adresse ::1 :

# ip neigh add proxy 2001:2:3:4501::1 dev eth0
# ip neigh add proxy 2001:2:3:4502::1 dev eth0

Enfin, il faut mettre l'interface côté routeur en mode promiscuous, afin de pouvoir prendre les paquets qui ne lui sont pas destinés mais destinés aux VM :

# ifconfig eth0 promisc

Les interfaces vers les VM n'en ont pas besoin car elles sont virtuelles. Dans le cas de Free avec des hôtes réels connectés à une interface réelle, il sera nécessaire de mettre l'interface côté hôtes en mode promiscuous aussi.

Maintenant, vous devriez avoir l'IPv6 disponible sur vos VM, et organisé comme il vous plaît. Si cela ne fonctionne pas, vous pouvez analyser le réseau en différents points (eth0, veth1, veth2, eth0 des VM) pour voir (ou ne pas voir justement) les paquets IPv6 qui passent :

tcpdump -ni <interface> ip6

Enfin, comme le fait remarquer l'article sur le wiki Gentoo, on peut procéder à la configuration automatique des VM en faisant tourner un démon radvd sur le serveur pour annoncer le préfixe utilisable ainsi que l'adresse du routeur. Cela ne vous affranchira cependant pas d'ajouter manuellement le proxy NDP pour chaque IPv6 utilisée, et c'est l'inconvénient majeur de cette technique. Mais après tout, dans le cas de serveurs les IPv6 utilisées sont choisies à l'avance, et pour les postes clients le plus souvent l'adresse IPv6 est obtenue à partir de l'adresse MAC, alors on s'en sort.

Si vous trouvez un moyen de voir les IPv6 utilisées dans les sous-réseaux et d'automatiquement ajouter le proxy NDP, faites-le savoir ! Ça doit être faisable à coup de tcpdump sur les neighbor solicitation, mais c'est moche...

J'espère avoir été clair et vous souhaite de bien vous amuser avec l'IPv6 ! Si vous avez des questions, n'hésitez pas.

NDM: il y a moyen de faire sans promisc et avec du proxy NDP d'un coté seulement, mais reste a retrouver les bonne conditions pour que ça marche.

Niveau : Star Star Star Star Empty
Résumé :alias ssh='ssh macommande && ssh'

Aujourd'hui interceptons les commandes ssh. Alors ne commencez pas à penser que je suis passé du côté obscur de la force. Il y a des usage bien pratique ce script et je vous en proposerai un dans le prochain article.

Tout d'abord le problème : on veut pouvoir intercepter une commande ssh de façon silencieuse pour pouvoir utiliser la connexion qui va s'établir et lancer les commandes qu'on veut sur la machine distante. Cela implique une acceptation implicite de l'utilisateur puisqu'on va utiliser un simple alias pour "intercepter" la commande. Bien sûr rien ne vous empêche de modifier l'alias d'un ami selon les moyens qui sont à votre disposition ;-)

Principe de fonctionnement

Vous vous dites qu'il suffit de reprendre les paramètres de la commande et de la relancer. Non, habitués que vous êtes à l'agent ssh, vous avez oublié qu'en son absence l'utilisateur devra taper un mot de passe pour que la commande passe.

Pour récupérer la connexion ssh, openssh met à notre disposition tout ce qu'il faut. L'option s'appelle ControlMaster, elle crée une socket sur laquelle ssh peut ensuite se connecter pour ouvrir un nouveau terminal sans repasser toute la chaine de connexion au serveur.

La méthode est donc fait simple :

  • on intercepte la commande ssh (alias)
  • on lance notre script en background ($0 &)
  • on ajoute un option -M et -S si besoin à la commande ssh pour créer la socket
  • on garde les options originales et le processus original (exec ssh -M -S "$@")
  • dans le script en background on peut ensuite utiliser directement la socket en question pour faire ce qu'on veut

Résultat

Donc résumons : un alias

alias ssh='~/.sshalias'

Et un script nommé ~/.sshalias (commentaires en anglais par habitude). Modifiez la commande run pour metre ce que vous voulez dedans

#!/bin/sh

# GPLv2 
# author : peck

#  command tu run via the ssh socket
run()
{
        # example ssh command
        ssh -S "$1" XXX 'hostname'
}

# test if we are the child which can connect via the master
if [ "$1" == "-=0" ]
then
    go=0
    # limit to 60 retries x 1s
    for i in $(seq 1 60)
    do
        sleep 1
        # try to connect via master
        ssh -S "$2" -O check xxx 2>/dev/null
        if [ $? -eq 0 ]
        then
            go=1
            break
        fi
    done
    # run the stealth command
    if [ $go -eq 1 ]
    then
        sleep 1 # bug if we go too fast
        run "$2"
    fi
    # remove master socket if we created it
    if [ "$3" == "0" ]
    then
        rm -f "$2"
    fi
    exit 0
fi

# we are in a real ssh command
master=0
sock=""
for i in "$@"
do
    # test if master is already provided
    if [ "$i" == "-M" ]
    then
        master=1
    fi
    # retrieve socket if provided
    if [ "$i" == "-S" ]
    then
        sock=".";
    fi
    if [ "$i" == "." ]
    then
        sock="$i"
    fi
done

# create socket name if needed
if [ "$sock" == "" ]
then
    sock=$(mktemp -u -t sshx.XXXXXX)
fi

# launch child which will use our master socket
$0 -=0 "$sock" "$master" &

# run original command adding a master socket
if [ $master -eq 1 ]
then
    exec ssh "$@"
else
    exec ssh -S "$sock" -M "$@"
fi

Ceci est un article invité, regardez en haut à gauche le nom de l'auteur ...

Niveau : Star Star Star Empty Empty
Résumé :

Peut-être avez-vous déjà rêvé, lors de vos soirées d'été, de contrôler votre musique à distance avec votre téléphone portable dernière génération, ou tout simplement en étant gentiment assis dans votre chaise longue ? MPD peut être la solution.

Music Player Daemon (MPD)

MPD fait partie de cette famille de lecteurs de musique basés sur un modèle client/serveur (dans la même catégorie se trouve xmms2 par exemple). Globalement, le serveur lit les fichiers audio sur la machine hôte, et vous pouvez contrôler à distance (et bien sûr localement) la musique à diffuser. Ainsi, il faut bien comprendre que les seuls messages qui transitent sur le réseau sont des messages de contrôle, et qu'aucun streaming audio n'est mis en jeu.

Les intérêts d'un tel modèle sont :

  • bien sûr, le contrôle à distance par plusieurs machines
  • la lecture de musique indépendante de tout lecteur nécessitant un serveur X
  • le logiciel de contrôle (qu'on pourrait à tord appeler "lecteur") n'a pas à se soucier des divers plugins nécessaires à la lecture des fichiers audio ou encore de gérer la bibliothèque. MPD le fait déjà pour lui.

L'un des principaux désavantages est que cela rajoute un poil de complexité lorsqu'un simple "play music.mp3" peut lire un fichier audio, mais les avantage sus-cités méritent de s'y essayer.

Installation

Sous Debian et dérivés, tout simplement faire en tant que root :

$ aptitude install mpd

Il va ensuite falloir configurer votre nouveau joujou. On se basera pour l'exemple sur la configuration par défaut du paquet Debian, mais le tout peut être adapté pour d'autres distributions. Le fichier de configuration /etc/mpd.conf contient des informations sur, entre autres, :

  • le répertoire où se trouve toute votre musique. Par défaut, sous Debian, il se trouve dans /var/lib/mpd/music
  • l'utilisateur sous lequel tourne le daemon (mpd par défaut, toujours sous Debian). Je conseillerai de laisser cet utilisateur crée par le paquet, et de ne pas mettre root...
  • l'adresse de bind du serveur. "127.0.0.1" par défaut, à adapter si vous voulez contrôler votre daemon à distance ("0.0.0.0" par exemple)
  • contrôle d'accès sur la gestion de la playlist, la lecture de la bilbiothèque, etc... par mot de passe (se référer au man pour plus d'infos.)

Certains d'entre vous se demandent peut être comment faire si sa musique est répartie entre deux disques durs, ou plusieurs montages NFS, que sais-je... MPD supporte les liens symboliques lors de la recherche de fichiers audios (comportement contrôlable grâce aux variables follow_outside_symlinks et follow_inside_symlinks du fichier de configuration). Donc, imaginons que vous ayez de la musique en local sur votre machine, et sur votre disque dur externe USB. Vous pouvez donc faire quelque chose comme :

$ sudo -u mpd ln -s /mnt/files/Musique /var/lib/mpd/music/local
$ sudo -u mpd ln -s /mnt/dd_externe/Musique /var/lib/mpd/music/dd

Il faut ensuite générer la base de données initiale. Vous pouvez définir dans le fichier de configuration les tags à extraire de vos fichiers audio pour constituer la bibliothèque finale de MPD, grâce à la variable metadata_to_use. Ensuite, le script d'init du paquet debian a été prévu pour lancer la génération. Il suffit donc de faire, en tant que root :

# S'assurer que mpd soit arrêté
$ invoke-rc.d mpd stop
# Et c'est parti
$ invoke-rc.d mpd start-create-db

Pour information, cette base de données est stockée par défaut (sous Debian) dans /var/lib/mpd/tag_cache, chemin modifiable dans /etc/mpd.conf.

Vous pouvez ensuite suivre l'avancement de la recherche en regardant le fichier de log de mpd :

# Les logs de mpd sont en 0644, donc pas forcément besoin d'être root
$ tail -f /var/log/mpd.log
Alsa et ses amis qui font du bruit

Une autre option de MPD est qu'il peut diffuser votre musique sur plusieurs systèmes. Le tout se passe toujours dans /etc/mpd.conf, dans la rubrique "Audio Output".

Si vous utilisez Alsa, il faut faire attention à la configuration de ce dernier et permettre à plusieurs utilisateur d'accéder au mixeur d'alsa. En effet, le daemon MPD tourne sous l'user mpd, et, par exemple, votre navigateur web sous votre user habituel. Alors, si vous voulez toujours entendre le doux son de deezer, il faut que votre /etc/asound.conf (ou ~/.asound.conf suivant votre configuration) ressemble à ceci :

$ cat /etc/asound.conf
pcm.mixeur {
   type dmix
   ipc_key 1024    # must be unique!
   ipc_key_add_uid false  # do not add uid to unique IPC key :: cette ligne est importante
   ipc_perm 0660  # allow multiple users to use the same IPC :: et celle-ci aussi
   slave {
       pcm "hw:0,0"
       period_time 0
       period_size 1024
       buffer_size 16384
       rate 44100
   }
}
pcm.!default {
   type plug
   slave.pcm "mixeur"
}

Il faut aussi bien vérifier que votre utilisateur appartienne au groupe audio. Pour cela :

$ id
# devrait afficher "audio" dans la liste des groupes

Le cas échéant, faire en tant que root un :

$ adduser votre_login audio

et vous reloguer.

Vous pouvez aussi diffuser la sortie de MPD en streaming. Le fichier de configuration donne un exemple assez parlant.

Les clients MPD

Le wiki officiel de MPD nous donne une liste plus ou moins exhaustive des clients MPD disponibles. Il y en a pour tous les goûts, de l'adepte du curseur clignotant au fan des interfaces graphiques Qt. Il y a même des clients pour Windows Mobile, pour pouvoir contrôler votre musique depuis votre transat grâce à votre Smartphone ou PDA en Wifi (ou en IPv6 over 3G, un jour, peut-être).

Pour ma part, j'ai essayé pympd. À part le manque de contrôle du volume interne de MPD, il s'en sort pas trop mal : recherche dans la bibliothèque par tags, affichage de l'arborescence initiale (ce qui peut être pratique si comme moi votre musique est déjà rangée par genre/artiste/album/année) et bien sûr contrôle de la playlist. La playlist est bien sûr gérée par le serveur, et modifier la playlist grâce à un client MPD fera que les autres client éventuellement connectés verront la modification.

Niveau Windows Mobile, mobilempd.net, bien qu'un peu lent au démarrage, fait bien son travail.

Par exemple, vous pouvez aussi utiliser le client en ligne de commande mpc pour contrôler MPD grâce à des raccourcis claviers :

# Play/pause
$ mpc toggle
# Chanson suivante
$ mpc next
# Stop
$ mpc stop

Je vous laisse ici donner vos impressions sur les clients que vous avez pu tester.

Conclusion

Cette article se veut comme une introduction à MPD, avec les quelques problèmes que j'ai pu rencontrer notamment au niveau d'ALSA. Je ne peux que vous conseiller de regarder plus en profondeur en n'hésitant pas à regarder le fichier de configuration de Debian assez bien commenté, ainsi que son man (man mpd.conf).

Je tiens à remercier peck pour son beau travail sur ce site et pour m'avoir laisser m'exprimer.

Cet article continue prochainement avec l'ajout de Jack dans le lot, pour un contrôle plus fin du son de vos enceintes. Parce que vos oreilles le valent bien.

Niveau : Star Star Star Star Empty
Résumé :accton ; ac ; sa ; lastcomm

Le noyau linux fournit une fonctionnalité ancienne, mais parfois bien utile nommée process accounting. Pour ceux qui compilent leur noyau elle est disponible dans les options générales sous le nom "BSD process accounting".

Pour pouvoir en profiter sur votre système, il faut aussi disposer des commandes disponibles dans le paquet acct. Ces commandes sont peu nombreuses. La première est accton qui active ou désactive l'accounting sur le système. La plupart des distributions incluent un fichier dans init.d appelant cette commande au démarrage.

Une fois l'accounting activé, les données liées aux processus sont stockées dans /var/log/account/pacct (ou équivalent). Les autres commandes du paquets servent à lire ces données.

Les plus importantes sont sa et lastcomm. Notons tout de même ac qui donne le temps de connexion total des utilisateurs et last (en provenance d'un autre paquet) indiquant les dates de connexion des utilisateurs. Un système non GNU vous proposerait des commandes supplémentaires.

sa permet d'obtenir des statistiques sur le lancement des processus.

lastcomm permet d'obtenir une liste de commandes lancées par utilisateur.

Usage

lastcomm permet de surveiller l'activité utilisateur sur le système. On peut ainsi retrouver qui a fait quoi en cas de problème (si vous pouvez garantir le fichier de log bien sûr :-). Un BOFH peut même s'amuser à espionner en temps réel ses utilisateurs avec un watch -d.

Quelques exemples :

# lister les commandes lancées récemment par un utilisateur
$ lastcomm user
# rechercher dans l'historique qui a lancé une commande donnée et quand
$ lastcomm apachectl
# savoir quelles commandes ont été lancées directement depuis le terminal physique de la machine 
$ lastcomm --tty tty1

sa de son côté permet de faire des statistiques et ainsi de savoir qui ou quoi consomme les ressources de la machine. Notez que le résultat inclue toujours une ligne sans nom, il s'agit du total. D'autre part il y a souvent une ligne ***other* contenant tout ce qui n'a été appelé qu'une fois résumé sur cette ligne.

Quelques exemples :

 
# lister commandes qui ont tourné le plus longtemps
$ sa --sort-real-time | head

# lister les commandes qui consomment le plus d'io
$ sa -d | head

# lister toutes les commandes avec l'utilisateur qui les a lancées
$ sa -u

# consommation par utilisateur
$ sa -m

La sortie contient en sortie le nombre d'appels, le temps passé, (re) la quantité de cpu consommé (cp en secondes), le nombre d'io moyen (avio, très pratique pour diagnostiquer quel processus utilise le disque), la mémoire consommée par seconde (k, cette valeur n'est pas très intuitive)

sa inclue aussi un système de summary des données que je n'ai jamais compris. Il est très mal documenté et n'a pas l'air de fonctionner sur GNU que sur les autres unix. La lecture du source ne m'a pas d'ailleurs convaincu sur son utilité. Si quelqu'un a une explication plus complète, je suis preneur.

Le manuel est un peu cryptique mais avec quelques essais on s'en sort. Si ces options ne vous conviennent pas, vous pouvez lire directement le fichier acct avec la commande dump-acct. Vous pouvez ainsi faire tout ce que vous voulez du contenu et scripter la récupération des résultats et le stockage pour des statistiques, par exemple dans rrdtool.