lundi, août 23, 2010

Juniper EX-4200 internal PFE routing in stack

During a troubleshooting session on a 10-members Juniper EX-4200 stack, I discovered the use of "show virtual-chassis vc-path source-interface XX destination-interface YY".
This command display the internal path across the EX-4200 PFE chips.
I obtain a result different that the EX-4200 diagram displayed in the O'reilly book "JunOS enterprise Switching" regarding the "Uplink Module".
Here are my results (simplified to a 3-members stack):


The Juniper use an internal routing-protocol for using shortest path between ports (less PFE hop count).
This diagram depends of how you build your stack too: If you use another way for plug your stack-cables, the result will be different.

Here is how to display the path when going from port ge-0/0/0 to ge-2/0/0

user@ex-stack> show virtual-chassis vc-path source-interface ge-0/0/0 destination-interface ge-2/0/0
vc-path from ge-0/0/0 to ge-2/0/0
Hop   Member  PFE-Device  Interface
0       0         1       ge-0/0/0
1       1         4       vcp-1
2       1         5       internal-1/25
3       1         3       internal-2/24
4       2         6       vcp-0
5       2         8       internal-0/24
6       2         7       ge-2/0/0

This means that if only one of the 3 PFE on one of your stack member have a problem, it's all flow that cross this member that will have problem.
You can check internal-PFE communication error with this command:
show virtual-chassis vc-port statistics extensive | match errors

jeudi, août 19, 2010

Réparation des bibliothèques manquantes

Suite à la mise à jour d'une bibliothèque critique sur mon FreeBSD (mise à jour de devel/icu4 qui est passé de 4.3 vers 4.4) et d'une erreur de ma part lors de l'étape de mise à jour:
Je me suis retrouvé avec un FreeBSD dont la base était pleinement fonctionnelle (merci à la séparation de la base et des ports) mais dont la grosse majoritée des applications ne voulaient plus démarrer (dont gnome).
En effet, les applications recherchaient les bibliothèques libicu*.so.43 qui n'existaient plus car remplacées par libicu*.so.44.
Pour retrouver rapidement un système fonctionnel, j'ai en premier lieu ajouté les correspondances «anciennes libs <=> nouvelles libs» dans le fichier /etc/libmap.conf:


libicule.so.43          libicule.so.44
libicui18n.so.43        libicui18n.so.44
libicudata.so.43        libicudata.so.44
libicuuc.so.43          libicuuc.so.44
libicutu.so.43          libicutu.so.44
libiculx.so.43          libiculx.so.44
libicuio.so.43          libicuio.so.44

Ce «bidouillage» ma permis de retrouver un système fonctionnel très rapidement, mais ca ne me plaisait pas d'avoir un système «pas si propre que ça».
Je me suis donc attelé à la rédaction d'un script shell qui
  1. Parcours l'ensemble des dossiers /usr/local/bin, /usr/local/sbin et /usr/local/lib à la recherche de fichier lié à des bibliothèques manquantes
  2. Puis retrouve le port correspondant à ces fichiers (pkg_info)
  3. Puis enfin recompile/réinstalle ces ports (portmaster)
Tout contents de moi, je suis aller le proposer sur #freebsd-fr, pour découvrir que je venais de ré-inventer la roue :-(
Ce script existe déjà en zsh (Reconstruire les paquets cassés) et il existe un port en ruby (sysutils/libchk).
Mais comme la version de mon script:
  1. Est en sh (et donc ni dépendante de zsh ni de ruby… qui sont des ports potentiellement «cassés» au moment ou vous avez besoin de ce script)
  2. Que c'est moi qui l'ai fait tout seul comme un grand, et que ca m'embête de le jeter après les heures (oui c'est très très chiant le sh) passé dessus
Je mes suis décidé à le publier quand même:

#!/bin/sh
# Found file with missing libs, and recompile the related breaked ports
set -e
dirs="/usr/local/lib /usr/local/libexec /usr/local/bin /usr/local/sbin"

portnames_tmp=""
for dir in ${dirs}; do
    for filename in `find -L ${dir} -type f`; do
    if file ${filename} | grep -q ELF; then
        if ldd ${filename} 2>&1 | grep -q "not found"; then
            portnames_tmp=${portnames_tmp}" "`pkg_info -qoW ${filename}`
        fi
    fi
    done
done

if [ "${portnames_tmp}" = "" ];then
    echo "No missing lib found"
    exit 0
fi

# Filtering duplicate name in $portnames_tmp
portnames=`for port in ${portnames_tmp}; do  echo $port; done |  sort -u | xargs echo`

echo "Detecting missing library for theses ports:"
echo ${portnames}

echo "Start upgrading them…"
portmaster -B ${portnames}

PS (1): le port devel/icu4 étant buggué (il oublie d'installer la bibliothèque libicutest.so.44), à chaque lancement de ce script, il détectera que devel/icu4 à une bibliothèque manquante et voudra donc le ré-installer :-)
PS (2): Ne pas oublier de faire le ménage dans /etc/libmap.conf après avoir corrigé vos problèmes.

jeudi, août 12, 2010

TCP flow analysis with tshark, tcptrace and xplot

Troubleshooting bad TCP performance between old Windows 2003 SP1 servers and a Sun Solaris 8, my only goal was to generate some TCP flow graph with Wireshark :
  1. The TCP Stream Graph: Time sequence grap


  2. The flow graph: TCP flow


But my old desktop computer was not able to opening the 1Go cap file onto Wireshark.
I found another solution using tshark, tcptrace and xplot:
  1. tshark, used with a little shell script, is used for extracting the TCP stream
  2. tcptrace is used for generate all graph files in xplot format (throughput, rtt sample time sequence , owin, segsize)
  3. xplot is used for drawing the graph using the xplot file generated in step 2
Here the shell script used for extracting the TCP stream:

#!/bin/sh
set -e
if [ $# -eq 0 ]; then
        echo "usage:"
        echo '$0 tracefile.cap ["tshark filter"]'
        echo ""
        echo "Example:"
        echo '$0 trace.cap "ip.addr==192.168.10.10 && tcp.port==1290 && ip.addr==192.168.20.20 && tcp.port==20'
        exit 0
fi
if [ ! -f $1 ]; then
    echo "No input trace file found!"
    exit 1
fi
echo "Generating the lists of detected TCP stream (can take a very long time depending of your trace size)..."
echo "If the next table didn't give you enough detail, try to generate more details stats with tshark:"
echo "tshark -n -r $1 -q -z conv,tcp"
echo "Stream    IP src TCP port scr IP dst TCP port dst"

if [ $# -eq 2 ]; then
    tshark -n -r $1 -R "$2" -T fields -e tcp.stream -e ip.src -e tcp.srcport -e ip.dst -e tcp.dstport | sort -un
else
    tshark -n -r $1 -T fields -e tcp.stream -e ip.src -e tcp.srcport -e ip.dst -e tcp.dstport | sort -un
fi

echo "Enter the stream number you want to extract (enter all for all streams):"
read streamid <&1
if [ $streamid != "all" ]; then
    echo "Extracting stream ${streamid} …"
    tshark -r $1 -w stream-${streamid}.cap -R "tcp.stream eq ${streamid}"
    echo "Stream number ${streamid} extracted in file stream-${streamid}.cap"
else
    echo "Extracting All streams"
    for streamid in `tshark -n -r $1 -T fields -e tcp.stream | sort -un`
    do
        echo "Working on stream ${streamid} …"
        tshark -r $1 -w stream-${streamid}.cap -R "tcp.stream eq ${streamid}"
    done
    echo "All streams were extracted in files stream-STREAM-NUMBER.cap"
fi


This script should be run like that:

[[olivier@sparc64]~/>sh extract-stream.sh solaris-slow-TCP.cap
Generating the lists of detected TCP stream (can take a very long time depending of your trace size)...
If the next table didn't give you enough detail, try to generate more details stats with tshark:
tshark -n -r solaris-slow-TCP.cap -q -z conv,tcp
Stream    IP src TCP port scr IP dst TCP port dst
0       10.10.129.254   48001   10.10.142.220   31114
1       10.10.129.254   1004    10.10.142.220   513
2       10.10.142.242   2948    10.10.142.220   1521
3       10.10.142.242   3899    10.10.142.220   1521
4       10.10.142.244   3777    10.10.142.220   1521
5       10.10.142.244   3536    10.10.142.220   1521
6       10.10.142.243   3687    10.10.142.220   1521
7       10.10.142.244   4936    10.10.142.220   1521
8       10.10.142.220   1521    10.10.142.244   3569
9       10.10.142.244   1256    10.10.142.220   21
10      10.10.142.220   20      10.10.142.244   1290
11      10.10.142.158   1433    10.10.142.160   1652
12      10.10.142.245   1591    10.10.142.220   1521
13      10.10.142.158   1433    10.10.142.160   1678
14      10.10.142.244   3732    10.10.142.220   1521
15      10.10.142.158   1433    10.10.142.160   1555
16      10.10.142.158   1433    10.10.142.160   1683
17      10.10.142.158   1433    10.10.142.160   1684
        10.10.142.247           10.10.142.255
Enter the stream number you want to extract (enter all for all streams):
10
Extracting stream 10 …
Stream number 10 extracted in file stream-10.cap



Once you've get the filtered cap file, run tcptrace over it:

tcptrace -n -C -G stream-10.cap

Now, better than with Wireshark (because you can zoom in/out), here are the TCP Time sequence grap:
xplot a2b_tsg.xpl &



 And the TCP flow graph:

 xplot a_b_tline.xpl &


My problem is that packet are lost in the direction Solaris => Windows… I need to found where now :-)

lundi, août 02, 2010

Compilation des ports et proxy HTTP authentifié

Ayant la possibilité de tester un serveur SunFire V480R au bureau, j'en ai profité pour lui installer un FreeBSD 8.1.
Si l'installation n'a posée aucun problème à par la prise en main de l'OpenBoot PROM (OBP pour les intimes), la déclaration du proxy HTTP authentifié qui ma pris plus de temps que prévus.
En effet, il est assez simple de le déclarer le proxy par les commandes suivantes (a adapter dans votre cas):

setenv HTTP_PROXY "10.0.0.10:8080"
setenv HTTP_PROXY_AUTH "basic:*:login:password"
setenv http_proxy 'http://login:password@10.0.0.10:8080/'

On peux désormais faire du «portsnap fetch extract», etc…:

[olivier@sparc64]~>fetch http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/book.html
book.html                                     100% of 5595 kB  370 kBps 00m00s
[olivier@sparc64]~>


Par, contre cela ne suffit pas pour permettre le téléchargement des sources des ports: Le proxy est bien utilisé, mais il ne s'authentifie pas tous seul:

[root@sparc64]/usr/ports/www/shellinabox#make extract
===>  Vulnerability check disabled, database not found
===>  License accepted by the user
=> shellinabox-2.10.tar.gz doesn't seem to exist in /usr/ports/distfiles/.
=> Attempting to fetch from http://shellinabox.googlecode.com/files/.
fetch: http://shellinabox.googlecode.com/files/shellinabox-2.10.tar.gz: Proxy Authentication Required


Avant de s'énerver et de remplacer le FreeBSD par un Ubuntu Server :-) faisons un petit tour du coté des barbus français (freebsd-fr@freenode)… C'était la bonne méthode, car le grand bapt@ était présent et ma fait une réponse aux petits ognons:

echo "FETCH_ARGS=-pRr" >> /etc/make.conf

Et cela à résolus mon problème:

[root@sparc64]/usr/ports/www/shellinabox#make extract
===>  Vulnerability check disabled, database not found
===>  License accepted by the user
=> shellinabox-2.10.tar.gz doesn't seem to exist in /usr/ports/distfiles/.
=> Attempting to fetch from http://shellinabox.googlecode.com/files/.
shellinabox-2.10.tar.gz                       100% of  501 kB 1087 kBps
===>  Extracting for shellinabox-2.10
=> MD5 Checksum OK for shellinabox-2.10.tar.gz.
=> SHA256 Checksum OK for shellinabox-2.10.tar.gz.

On peux même déclarer le proxy dans le fichier make.conf (mais éviter de déclarer votre proxy partout, car en cas de changement cela fait plusieurs fichiers à modifier et votre mot de passe qui traine partout):

echo "FETCH_ENV=http_proxy='http://login:password@10.0.0.10:8080/'" >> /etc/make.conf

dimanche, juillet 25, 2010

make installworld: «touch: not found» lors d'une mise à jour à distance

FreeBSD 8.1-Release étant de sortie, j'en ai profité pour mettre à jour mon kimsufi 250G.
Si la procédure de mise à jour à distance est en général assez risquée pour un changement de version majeure, elle ne ma jamais posée de problème pour un changement de version mineure.
Sauf que cette fois-ci, le «make installworld» se termine mal par le message d'erreur «touch: not found».

La FAQ officielle explique que ce problème est lié un problème d'horloge qui fait que les dates des fichiers à installer sont incorrect suite au redémarrage en mode «single user». La FAQ conseil d'utiliser la  commande «adjkerntz -i» pour résoudre ce problème. Cette proposition n'est pas adaptée à mon cas car je ne redémarre pas en mode single user.
    Un autre utilisateur, barryp, indique que ce problème est du au fichier /usr/src/sys/conf/newvers.sh qui n'a pas la bonne date et qu'un simple «touch» sur ce fichier pour le mettre à la bonne date résous le problème… Pas chance, cela ne résous pas mon problème :-(
     
    La bonne réponse m'a été donné sur le site de so14k: Il faut utiliser la commande «make installworld PATH=$PATH» pour ne plus avoir ce problème de «touch: not found».

    lundi, juillet 12, 2010

    Installation de FreeBSD «headless» (utilisation du port console comme clavier/écran)

    Je souhaitai installer FreeBSD sur une «vieille» unité centrale qui n'avait plus d'écran: Il me fallait utiliser le port série comme console principale.
    Ce n'est pas très compliqué: Il suffit de modifier l'image ISO de FreeBSD pour forcer l'usage du port série.
    Une fois téléchargé l'image, on la monte (l'ensemble des exemples utilisent tcsh comme shell):

    set MD=`mdconfig -a -t vnode -f FreeBSD-8.1-RC2-amd64-disc1.iso`
    mount -t cd9660 /dev/$MD /mnt/

    Vous obtenez une image montée en lecture seule (normal pour un ISO)… Ne reste plus qu'à la modifier et re-générer un fichier ISO.
    Pour cela, on peux vous conseiller de recopier l'intégralité de l'image disque et ensuite de modifier votre copie comme ceci:

    mkdir /tmp/isotmp
    cd /mnt
    tar cf - * | ( cd /tmp/isotmp; tar xfp - )

    Mais comme cette méthode est lente et consomme de la place sur votre disque, voici une méthode plus intelligente utilisant unionfs:

    mkdir /tmp/isotmp
    mount -t unionfs -o noatime /tmp/isotmp/ /mnt/

    Désormais le point de montage original (/mnt) est accessible en écriture :-)
    Modifions le boot/loader.conf pour forcer l'usage du port série:
    J'utilise une vitesse de 38400 baud pour que ca ne soit pas trop désagréable.
    Attention à l'utilisation de unionfs qui ne gère pas la fusion du contenus de deux fichiers identiques, il faut utiliser une copie pour ne pas écraser l'ancien:

    cat /mnt/boot/loader.conf > /mnt/boot/loader.conf.new
    echo 'comconsole_speed="38400"' >> /mnt/boot/loader.conf.new
    echo 'console="comconsole"' >> /mnt/boot/loader.conf.new
    echo 'boot_serial="-h"' >> /mnt/boot/loader.conf.new
    mv /mnt/boot/loader.conf.new /mnt/boot/loader.conf

    Ne reste plus qu'a régénérer une ISO:

    cd /mnt
    mkisofs -R -no-emul-boot -b boot/cdboot -o /tmp/FreeBSD-8.1-headless-.iso .

    Puis à démonter (2 fois) votre image, détruire le md et effacer votre dossier temporaire:

    cd /
    umount /mnt
    umount /mnt
    mdconfig -d -u $MD
    rm -rf /tmp/isotmp

    Mais ne partez pas si vite ! Il reste juste un tout petit détail qui a son importance…
    Une fois l'installation de FreeBSD terminé, et avant de re-démarrer:

    N'oubliez pas de modifier le /etc/ttys en lui déclarant l'usage du port série!
    Dans sysinstall: configure system ttys.
    Il va ouvrir le fichier /etc/ttys dans un éditeur de texte, il faut remplacer la ligne suivante:

    # Serial terminals
    # The 'dialup' keyword identifies dialin lines to login, fingerd etc.
    ttyu0   "/usr/libexec/getty std.9600"   dialup  off secure

    Par ceci:

    # Serial terminals
    # The 'dialup' keyword identifies dialin lines to login, fingerd etc.
    ttyu0   "/usr/libexec/getty std.38400"   vt100  on secure

    Personnellement, avant de graver le CD, je vérifie la procédure par l'excellentissime[1] qemu:

    qemu-img create fbsd-test.img 4G
    kldload kqemu.ko
    kldload aio.ko
    qemu-system-x86_64 -kernel-kqemu -nographic -cdrom FreeBSD-8.1-headless.iso -hda fbsd-test.img -boot d
    qemu-system-x86_64 -kernel-kqemu -nographic -hda fbsd-test.img

    Article original m'ayant fortement inspiré: FreeBSD Headless install
    [1] Essayez d'en faire autant en si peux de lignes de commande avec VirtualBox !

    vendredi, juillet 09, 2010

    Utilisation de nanoBSD sur un WRAP de PC-Engines

    Après avoir passé 2 jours à chercher pourquoi BSDRP (NanoBSD basé sur FreeBSD 8.1-RC2) ne voulais pas démarrer sur mon PC-Engines WRAP.1E-2, voici la liste des pré-requis à respecter…

    Coté WRAP:
    1. Version du BIOS en 1.11
    2. BIOS configuré en mode CHS (et non pas LBA)
    Coté NanoBSD:
      1. Compiler un noyaux i386 avec la ligne "options CPU_GEODE" dans le fichier de configuration
      2. L'image nanoBSD doit utiliser comme console le port série par défaut (cust_comconsole) à la vitesse de 38400 baud si possible (pour respecter la vitesse par défaut du WRAP).
      3. L'image nanoBSD doit absolument utiliser une géométrie disque de 255H 63S/T. Par exemple en utilisant «UsbDevice generic-hdd 256» pour une image finale de 256Mo.
      4. Le bootloader doit être paramétré en mode nopacket, car le mode «packet» par défaut n'est pas compatible avec le BIOS du WRAP

        Si votre séquence de démarrage reste bloqué à l'affichage de nombreux «###» comme ceci:

        PC Engines WRAP.1C/1D/1E v1.11
        640 KB Base Memory
        130048 KB Extended Memory

        01F0 Master 848A SanDisk SDCFB-512                      
        Phys C/H/S 993/16/63 Log C/H/S 993/16/63

        1  FreeBSD
        2  FreeBSD
         
        F6 PXE
        Boot:  1 #############################################################################################################

        Re-vérifiez les point 3 et 4 de vos images nanoBSD.
        Par exemple, une fois la carte flash insérée dans le lecteur CF de votre poste de travail (sous FreeBSD), utilisez la commande «boot0cfg -v /dev/device» pour vérifier le mode:




        [root@d630]#boot0cfg -v /dev/da1
        #   flag     start chs   type       end chs       offset         size
        1   0x80      0:  1: 1   0xa5    111: 63:32           32       229344
        2   0x00    112:  1: 1   0xa5    223: 63:32       229408       229344
        3   0x00    224:  0: 1   0xa5    233: 63:32       458752        20480
        4   0x00    234:  0: 1   0xa5    243: 63:32       479232        20480

        version=2.0  drive=0x80  mask=0x3  ticks=182  bell=# (0x23)
        options=nopacket,update,nosetdrv
        volume serial ID 9090-9090
        default_selection=F1 (Slice 1)

        Puis vérifier que la géométrie de votre image :

        [root@d630]#fdisk /dev/da1
        ******* Working on device /dev/da1 *******
        parameters extracted from in-core disklabel are:
        cylinders=62 heads=255 sectors/track=63 (16065 blks/cyl)

        parameters to be used for BIOS calculations are:
        cylinders=62 heads=255 sectors/track=63 (16065 blks/cyl)

        (etc…)


        lundi, juin 07, 2010

        Online.net : Multiplication par 2,4 de leur tarifs sans prévenir leurs abonnés !!

        En voulant renouveler les noms de domaines que je possède chez online.net, j'ai eu la très mauvaise surprise de découvrir que ma facture avait été plus que doublée !!
        En effet, sans recevoir aucun message de la part d'Online.net, je découvrais qu'ils ont migrés leurs offres.
        Voici les comparaisons tarifaire entre une ancienne et une nouvelle offre:

        • Ancienne offre XS: 5€ HT/an
        • Nouvelle offre pack «basique»: 11,88 € HT/an
        Les tarifs sont multiplié par 2,4 !

        Cela veux dire que si vous aviez 10 noms de domaines chez eux, votre facture passe de 55€ TTC à 131 € pour l'année !!

        Et c'est la même chose pour les offres d'hébergement :
        • Ancienne offre M: 29,90 € HT/an
        • Migré (sans demander mon avis) vers l'offre pack «illimité»: 71,88 € HT/an
        Même ratio pour l'augmentation de tarif: 2,4 !!
        J'ai donc contacté le service client pour, qu'au minimum, ils passent mon hébergement sur l'offre «Pack Pro» (36€/an).
        Leur réponse est désespérante:
        «Pour changer d'offre il faut pour l'instant resilier votre offre d'hebergement actuelle et reprendre une nouvelle offre une fois l effacement terminé»

        Bref, je n'avais jamais eu à me plaindre d'online.net jusqu'à présent, mais là c'est terminé avec eux.
        Après avoir migré mon serveur dédié dedibox v1 vers un Kimsufi 250G d'OVH, je vais donc devoir aussi transférer mes noms de domaine.

        lundi, mars 08, 2010

        Le Trône de Fer: La série TV en préparation !

        Très rare sont les séries TV qui arrivent à justifier une place dans mon emplois du temps (la dernière était Battlestar Galactica). Heureusement il y a du gros en préparation… du très gros même:
        Il ne s'agit ni plus ni moins que de l'adaption de la saga Le Trône de Fer ! (pour ceux qui ne connaisent pas c'est de la fantasy très «réaliste»).

        Les premières diffusions sont prévues pour printemps 2011.

        Plus d'info:


        lundi, janvier 25, 2010

        ACTA: une menace pour Internet !

        Les journalistes ne faisant pas leur boulot, aux internautes de le faire...

        «Les négociations sur l'Accord Commercial Anti-Contrefaçon (ACTA) se tiendront du 26 janvier au 29 janvier à Mexico. Le but de l'ACTA est de contrôler Internet, tout en évitant soigneusement les processus démocratiques. »

        Pour plus d'info: