billets

Quelques articles qui décortiquent certains points techniques en administration de système GNU/Linux, de configuration d’hébergements et autres astuces de webdesign.

Il y a 31 articles
  • Dans le cadre d’une installation en dual boot MAC OS / Debian, il peut s’avérer fastidieux de synchroniser ses périphériques bluetooth avec un identifiant commun entre les systèmes.

    La marche à suivre consiste à opérer la synchronisation sous OS X, puis booter sous GNU/Linux, monter la partition OS X, par exemple :
    sudo mount -t hfsplus /dev/sda2 /media/OSX/

    Puis à exécuter ce script [1] :

    1. #!/bin/sh
    2. # sync-bt-os.sh
    3. cd /var/lib/bluetooth
    4. for i in *; do
    5.     cd "$i"
    6.     plutil -i /media/OSX/private/var/root/Library/Preferences/blued.plist -o /dev/stdout |
    7.     perl -0777 -MMIME::Base64 -ne 's|\s||g; $s = $_; while ($s =~ m|<key>(..-..-..-..-..-..)</key><data>(.*?)</data>|g) { $mac = uc($1); $key = uc(unpack("H*",reverse decode_base64($2))); $mac =~ s/-/:/g; $pinlength = 6; $pinlength = 4 if $mac eq "C4:2C:03:A0:C7:20"; print "$mac $key 0 $pinlength\n"; }' |
    8.     tee linkkeys
    9.     cd ..
    10. done
    11. service bluetooth restart

    Télécharger


    placido

    Notes

    [1Il vous faudra probablement installer le paquet plutil, via apt par exemple.

  • Une fonction qui permet de créer/supprimer des liens symboliques facilement vers les répertoires couramment utilisés. Classe non ?

    Il faut rajouter ceci dans son /.bash_aliases :

    1. #Filesystem Markers & Jump
    2. ###########################
    3. export MARKPATH=$HOME/.marks
    4. function jump {
    5.     cd -P $MARKPATH/$1 2>/dev/null || echo "No such mark: $1"
    6. }
    7. function mark {
    8.     mkdir -p $MARKPATH; ln -s $(pwd) $MARKPATH/$1
    9. }
    10. function unmark {
    11.     rm -i $MARKPATH/$1
    12. }
    13. function marks {
    14.     ls -l $MARKPATH | sed 's/  / /g' | cut -d' ' -f9- | sed 's/ -/\t-/g' && echo
    15. }

    Télécharger

    Le code est assez explicite, mais à l’usage voilà ce que cela donne :

    Créer un raccourci

    1. cd chemin/vers/mon/projet1
    2. mark projet1

    Télécharger

    Usage

    1. jump projet1

    Lister les raccourcis déjà créés

    1. marks

    Supprimer le raccourci

    1. unmark projet1

  • Aide mémoire listant toutes les variables # !shell utiles pour l’écriture de # !scripts .

    Manipulation de variables simples

    var=val
    var="a b"
    affectation de la variable "var"
    $var
    ${var}
    contenu de la variable "var"
    ${#var} longueur de la variable "var"
    ${var:-valeur} affectation conditionnelle, si "var" non défini alors var = valeur
    export var
    declare -x var
    exportation de la variable "var" vers les shells fils
    set affichage de l’ensemble des variables définies dans le shell
    unset var suppression de la variable "var"

    Tableaux

    tab[0]=val affectation du premier enregistrement du tableau "tab"
    ${tab[0]}
    $tab
    contenu du premier enregistrement du tableau "tab"
    ${tab[11]} contenu du douzième enregistrement du tableau "tab"
    ${tab[*]} ensemble des enregistrements du tableau "tab"
    ${#tab[11]} longueur du douzième enregistrement du tableau "tab"
    ${#tab[*]} nombre d’enregistrements du tableau "tab"
    ${!tab[@]} liste des clefs ( Index ) du tableau "tab"

    Paramètres positionnels et arguments

    $0 nom du script
    $1 $2 ... ${10} paramètres positionnels (1, 2 et 10)
    $# nombre de paramètres positionnels
    $*
    $@
    ensemble des paramètres positionnels, équivalant à $1 $2 ... $n

    Variables spéciales

    $$ PID du shell courant
    $! PID du dernier travail lancé en arrière plan
    $? code retour de la dernière commande
    ${PIPESTATUS[0]} code retour de la première commande d’un pipe

    Variables d’environnement

    $HOME chemin du répertoire personnel de l’utilisateur
    $OLDPWD chemin du répertoire précédent
    $PATH liste des chemins de recherche des commandes exécutables
    $PPID PID du processus père du shell
    $PS1 invite principale du shell
    $PS2 invite secondaire du shell
    $PS3 invite de la structure shell "select"
    $PS4 invite de l’option shell de débogage "xtrace"
    $PWD chemin du répertoire courant
    $RANDOM nombre entier aléatoire compris entre 0 et 32767
    $REPLY variable par défaut de la commande "read" et de la structure shell "select"
    $SECONDS nombre de secondes écoulées depuis le lancement du shell

  • Quelques commandes bash utiles pour mysql

    1. su -c "mysqldump -u$user-p$password $mydatabase | bzip2 > /$mypath/`date +%F-%H%M`_$output.sql.bz2" $user

    Sauvegarder toute la base en concaténant le nom de l’hostname + la date pour le nom du fichier de sauvegarde :

    1. mysqldump -u$user -p$password --all-database | bzip2 > $(date +%F-%H%M)-$(hostname -A).tar.bz2

    En théorie la commande ci-dessus devrait fonctionner sans problème.
    J’ai eu un bug ? sur ma debian, avec le résultat de la commande de hostname -a qui me renvoyait systématique un espace en fin de chaîne.

    Je vous laisse apprécier la basherie ci-dessous visant a nommer le fichier de sortie en supprimant l’espace indisposant avec la commande sed.

    1. mysqldump -u$user-p$pass --all-databases | bzip2 > $(echo "$(date +%F-%H%M)-$(hostname -A)" | sed 's/ //g').sql.bz2

    Pour importer une sauvegarde Mysql au format bz2 sans faire une décompression préalable.

    1. bunzip2 < dump.sql.bz2 | mysql -uuser -ppass database

  • Charger le contenu depuis un CDN

    Plutôt que de stocker JQuery sur votre serveur, vous pouvez choisir un CDN [1] notoire. Cela devrait réduire le temps de chargement de la page.

    <!--:( -->
    <script src="/vendor/jquery/jquery.min.js"></script>
    <!-- :) -->
    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

    Voici une liste de CDN fournissant un accès à la bibliothèque JQuery :

    Les bonnes pratiques ne concernent pas seuelement JQuery ; les éléments d’affichage - type CSS ou autre - peuvent aussi être chargés parallèlement.

    Prévoir une méthode de chargement alternative en cas de défailllance du CDN

    1. <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    2. <script>window.jQuery || document.write("<script src='/vendor/jquery/jquery.min.js'>\x3C/script>");</script>

    Télécharger

    Préférer les versions compressées

    1. <!-- :( -->
    2. <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.js"></script>
    3. <!-- :) -->
    4. <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

    Télécharger

    Placer l’appel au script en fin de page plutôt qu’en en-tête

    1. <!doctype html>
    2. <head>
    3. ...
    4. <!-- :( -->
    5. <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    6. </head>
    7. <body>
    8. ...
    9. <!-- :) -->
    10. <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    11. </body>
    12. ...

    Télécharger

    Utiliser des URLs en chemins relatif

    Pas besoin de spécifier le protocole http ou https. Le navigateur optera de lui-même pour le protocole https s’il se trouve déjà dans un environemment sécurisé.

    1. <!-- :( -->
    2. <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    3. <!-- :) -->
    4. <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

    Télécharger

    Raccourci pour l’événement ready

    1. // Appel classique
    2. $(document).ready(function() {
    3. ...
    4. });
    5. // Version rapide
    6. $(function() {
    7. });

    Télécharger

    Garder le $ lors de la déclaration d’une variable de type jQuery.

    Grâce à cette convention de nommage, on distingue facilement la nature de l’objet JQuery.

    1. // :(
    2. var form = $('#contactForm');
    3. // :)
    4. var $form = $('#contactForm');

    Télécharger

    Du bon usage de $this

    La variable $this s’utilise avantageusement au début des fonctions non déclarées, par exemple dans une boucle de type each.

    1. // :(
    2. $('li').each(function() {
    3. $(this).on('click', function() {
    4. $(this).addClass('active');
    5. });
    6. });
    7. // :)
    8. $('li').each(function() {
    9. var $this = $(this);
    10. $this.on('click', function() {
    11. $this.addClass('active');
    12. });
    13. });

    Télécharger

    Certains préfèrent utiliser that ou self. Attention de ne pas oublier qu’il s’agit d’un objet jQuery.

    Mettre en cache les objets jQuery

    Si un objet jQuery est utilisé plusieurs fois, le mettre en cache permet d’optimiser les performances.

    1. // :(
    2. $('.menu li').each(function() { ... });
    3. $('.menu li').each(function() { ... });
    4. // :)
    5. var $items = $('.menu li');
    6. $items.each(function() { ... });
    7. // on recycle :)
    8. $items.each(function() { ... });

    Télécharger

    Enchaînement des fonctions

    C’est asssurément l’une des fonctionalités les plus appréciée de jQuery. On peut ainsi appeler une série de méthodes dans la même foulée.

    "Write less, do more", garder en tête le slogan de jQuery
    1. // :(
    2. var $a = $('#about');
    3. $a.hide();
    4. $a.addClass();
    5. $a.fadeIn();
    6. $a.hide();
    7. // :)
    8. $('#about').hide().addClass().fadeIn().hide();
    9. // c'est mieux
    10. // Retour à la ligne et identation améliorent la visibilité
    11. $('#about')
    12. .hide()
    13. .addClass()
    14. .fadeIn()
    15. .hide();

    Télécharger

    Déclarer un nouvel élément

    Lors de la création d’un élément, faîtes en sorte de manipuler les éléments via les méthodes jQuery plutôt que d’insérer du code HTML brut.

    1. // Don't
    2. var $hidden = $('<input class="form-control" type="hidden" name="foo" value="bar" />').appendTo('#form');
    3. // :)
    4. var $hidden = $('<input/>')
    5. .addClass('form-control')
    6. .attr('type', 'hidden')
    7. .attr('name', 'foo')
    8. .val('bar')
    9. .appendTo('#form');
    10. // ou bien
    11. var $hidden = $('<input/>', {
    12. class: 'form-control',
    13. type: 'hidden',
    14. name: 'foo',
    15. value: 'bar'
    16. }).appendTo('#form');

    Télécharger

    Garder le CSS loin des manipulations de jQuery

    Pas la peine de déclarer le style CSS directement à un élément. Le recours aux classes est fait pour ça.

    1. // :(
    2. $('#button').css({
    3. 'background-color': '#5cb85c',
    4. 'border-color': '#4cae4c'
    5. });
    6. // :)
    7. .success {
    8. background-color: #5cb85c;
    9. border-color: #4cae4c;
    10. }
    11. $('#button').addClass('success');

    Télécharger

    Choisir le bon sélecteur

    Le sélecteur désignant l’id est le plus rapide

    Pour retrouver un élément du DOM en fonction de son id, jQuery utilise la méthode native document.getElementById() qui s’avère bien plus efficace que Sizzle.

    Sizzle is a pure-JavaScript CSS selector engine used by jQuery
    1. // :(
    2. $('#wrapper #inner');
    3. $('div#inner');
    4. $('.wrapper #inner');
    5. // :)
    6. $('#inner');

    Télécharger

    Du coup, mieux vaut introduire une recherche sur un id, quitte à enchaîner les recherches.

    1. // :(
    2. $('#container .row');
    3. // + rapide
    4. $('#container').find('.row');

    Télécharger

    Sélecteurs restrictifs

    Il faut être spécifique sur le partie gauche de votre sélecteur, et moins en début.

    1. // pas glup
    2. $('div.data .gonzalez');
    3. // glup glup
    4. $('.data td.gonzalez');

    Télécharger

    Éviter le recours aux sélecteurs universels

    1. // moins rapide
    2. $('div.container > *');
    3. // Plus rapide
    4. $('.container').children();

    Télécharger

    Mieux vaut faire précéder les sélecteurs pseudo-class (ex :before) avec un tag ou un autre sélecteur. Car, si ce n’est pas le cas, le sélecteur universel * est implicitement employé.

    1. // :(
    2. $('.category :radio');
    3. // :)
    4. $('.category input:radio');

    Télécharger

    Privilégiez les méthodes de tri plutôt que les pseudos-sélecteurs.

    Lorsque cele est possible, utiliser la méthode de tri jQuery plutôt que des pseudos-sélecteurs. La méthode querySelectorAll s’avère là encore plus rapide que la méthode Sizzle.

    1. // :(
    2. $('.item:first')
    3. // :)
    4. $('.item').eq(0)

    Télécharger

    Pas de javascript inline sur les élements HTML

    Mieux vaut attacher un écouteur d’événement à l’objet.

    1. <!-- :( -->
    2. <button id="saveButton" onclick="javascript: save();">Save</button>
    3. // :)
    4. $('#saveButton').on('click', function() {
    5. ...
    6. });

    Télécharger

    Choisir un namespace personnalisé pour les événements

    Ainsi il est plus facile de désactiver un événement sans affecter les autres écouteurs d’événements assignés à l’élément.

    1. $('#saveButton').on('click.bv', function() { ... });
    2. //Plus tard, on peut retirer sans crainte l'écouteur l'événement
    3. $('#saveButton').off('click.bv');

    Télécharger

    Ne pas passer les paramètres Ajax "en dur"

    Lorsque d’un requête de type xmlHttpRequest, il faut utiliser le paramètre data, et non concaténer l’information au sein de l’URL.

    1. // :(
    2. $.ajax({
    3. url: '/remote/url?param1=value1&amp;param2=value2...'
    4. }});
    5. // :)
    6. $.ajax({
    7. url: '/remote/url',
    8. data: {
    9. param1: 'value1',
    10. param2: 'value2'
    11. ...
    12. }
    13. });

    Télécharger

    Dans le cas où les paramètres à transmettre sont très long (ex : le contenu intégral d’un article), on privilégiera la méthode POST, à la fois pour Ajax et le traitement côté serveur.

    Internet Explorer 8 (and earlier) limits 2083 characters in URL

    source Best jQuery practices · Programmer Tips


    placido

    Notes

    [1Content Delivery Network : Un content delivery network (CDN) est constitué d’ordinateurs reliés en réseau à travers Internet et qui coopèrent afin de mettre à disposition du contenu ou des données (généralement du contenu multimédia volumineux) à des utilisateurs.

  • Voici comment déployer (presque rapidement) un environnement Ruby pour bénéficier du compilateur css SASS via Compass et rechargement automatique de la page en fonction des modifications enregistrées, grâce à Livereload, le tout chapeauté par Guard.

    Il faut installer gem et bundle au besoin :

    1. sudo apt-get install gem
    2. sudo gem install bundle

    Ensuite dans le dossier parent du projet on crée un Gemfile

    1. #Gemfile
    2. source "http://rubygems.org"
    3.  
    4. group :development do
    5. gem 'sass' # Sass.
    6. gem 'compass' # Framework built on Sass.
    7. gem 'compass-validator' # So you can `compass validate`.
    8. gem 'oily_png' # Faster Compass sprite generation.
    9. gem 'css_parser' # Helps `compass stats` output statistics.
    10. gem 'guard' # Guard event handler.
    11. gem 'guard-compass' # Compile on sass/scss change.
    12. gem 'guard-shell' # Run shell commands.
    13. gem 'guard-livereload' # Browser reload.
    14. gem 'bootstrap-sass'
    15. end

    Télécharger

    Puis on lance coup sur coup Compass et Guard via Bundle pour initier le projet (ici avec l’option bootstrap-sass)

    1. bundle install
    2. bundle exec compass create mon_projet -r bootstrap-sass --using bootstrap

    Je copie ici mes fichiers Guardfile et config.rb pour info :

    1. # ~/.guardfile
    2. # More info at https://github.com/guard/guard#readme
    3.  
    4. notification :off
    5.  
    6. puts "Using default guard file."
    7.  
    8. group :development do
    9.  
    10. if File.exists?("./config.rb")
    11. # Compile on start.
    12. puts `compass compile --time --quiet`
    13. # https://github.com/guard/guard-compass
    14. guard :compass do
    15. watch(%r{(.*)\.s[ac]ss$})
    16. ignore %r{^tmp/}
    17. end
    18. end
    19.  
    20. # Look for specified files in the current and child directories.
    21. # `find` requires Ruby 1.9 or greater.
    22. require 'find'
    23. if Find.find(Dir.pwd).detect{|dir|dir=~/.+\.(css|js|html?|php|inc|theme)$/}
    24. guard :livereload do
    25. watch(%r{.+\.(css|js|html?|php)$})
    26. ignore %r{^tmp/}
    27. end
    28. end
    29.  
    30. end

    Télécharger

    1. #config.rb
    2. require 'bootstrap-sass'
    3. # Sass options:
    4. # http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#options
    5. sass_options = Hash.new
    6. sass_options[:debug_info] = false
    7.  
    8. css_dir         = "dev/css"
    9. sass_dir        = "dev/css/sass"
    10. fonts_dir       = "dev/css/fonts"
    11. javascripts_dir = "dev/js"
    12. images_dir      = "dev/css/img"
    13. relative_assets = true
    14. output_style    = (environment == :production ? :compressed : :expanded)

    Télécharger

    Il reste à installer le module Firefox LiveReload

    Avec ça l’environnement doit être prêt et fonctionnel.

    On lance Guard via Bundle depuis le dossier parent du projet

    1. bundle exec guard start

  • Le but est de faire une boucle sur un #ARRAY ayant comme clé le nom d’un script js, et un booléen en tant que valeur.

    On active ou désactive le script simplement en remplaçant la valeur par 1.

    Dans le cadre d’un design utilisant bootstrap, on souhaite pourvoir activer facilement une ou plusieurs bibliothèques javascript.

    1. <BOUCLE_for(DATA){source table,#ARRAY{
    2.    affix.js,0,
    3.    alert.js,0,
    4.    button.js,0,
    5.    carousel.js,0,
    6.    collapse.js,1,
    7.    dropdown.js,0,
    8.    modal.js,0,
    9.    popover.js,0,
    10.    scrollspy.js,0,
    11.    tab.js,0,
    12.    tooltip.js,0,
    13.    transition.js,0,
    14. }}>
    15. [(#VALEUR|=={1}|oui)
    16. <script src="#CHEMIN{javascript/bootstrap/#CLE}"></script>
    17. ]
    18. </BOUCLE_for>

    Télécharger

    La même chose, mais en mieux, dans le cadre de la création d’un plugin est d’utiliser le pipeline insert_head($flux).

    1. function monPlugin_insert_head($flux){
    2.  
    3.     # Déclarer le array listant les scripts js
    4.    $bstrpJs = array(
    5.         'affix.js'      => 0,
    6.         'alert.js'      => 0,
    7.         'button.js'     => 0,
    8.         'carousel.js'   => 0,
    9.         'collapse.js'   => 1,
    10.         'dropdown.js'   => 1,
    11.         'modal.js,0'    => 0,
    12.         'popover.js'    => 0,
    13.         'scrollspy.js'  => 0,
    14.         'tab.js'        => 0,
    15.         'tooltip.js'    => 0,
    16.         'transition.js' => 0,
    17.     );
    18.  
    19.     # Boucler sur le tableau listant les scripts
    20.    foreach($bstrpJs as $script => $active){
    21.         if($path = find_in_path("javascript/bootstrap/$script") AND $active > 0){
    22.             $flux .= '<script type="text/javascript" src="'. $path .'"></script>';
    23.         }
    24.     }
    25.     return $flux;
    26. }

    Télécharger


  • X-Plane 9 SHOW
    _The best simulation program now has the best graphics_
    Manlezl

    X-Plane 10 est sortie depuis quelque temps, mais La version 9 reste toujours une réfèrence. X-Plane 9 propose une qualité graphique (quasiment) équivalente à la version 10 tout en étant moins gourmande en RAM / CPU / GPU.

    Ayant un Core 2 duo encore dans la force de l’age, je vais détailler l’installation sur la Version Linux Ubuntu 13.10 64bit et faire un point sur les problèmes rencontrés


    Installation des dépendances 32bits

    1. sudo apt-get install libopenal1:i386 libgl1-mesa-dri:i386 libgl1-mesa-glx:i386 libglu1-mesa:i386 libxrandr2:i386

    Créer un répertoire de travail et récupérer les outils d’installation

    Creer un repertoire de travail.

    1. mkdir ~/xplane-install

    Aller dans le répertoire de travail.

    1. cd ~/xplane-install

    Récupérer l’installateur de DVD X-Plane 9 sur la page du wiki officiel X-Plane

    1. wget http://dev.x-plane.com/update/installers9/X-PlaneDVDInstallerLinux.zip

    Récupérer l’outil de mise à jour sur le site officiel d’X-Plane

    1. wget http://www.x-plane.com/update/installers9/X-PlaneUpdaterLinux.zip

    Décompresser les 2 outils

    1. unzip *zip

    Installation d’X-plane 9

    [Inserer DVD-ROM du jeu]

    rendre executable le script d’installation

    1. chmod a+x "X-Plane DVD Installer Linux"

    lancer l’installation

    1. ./"X-Plane DVD Installer Linux"

    Si cette erreur apparaît lors du lancement de l’installation :

    ./"X-Plane DVD Installer Linux" : error while loading shared libraries : libopenal.so.0 : cannot open shared object file : No such file or directory

    Faire un lien symbolique :

    1. ln -s /usr/lib/i386-linux-gnu/libopenal.so.1 /usr/lib/i386-linux-gnu/libopenal.so.0

    Problèmes rencontrés :

    Bizarrement certain de mes DVD (Trés peu utilisés) "plantaient" au cours de l’installation. J’ai résolu le problème en générant des ISO pour ensuite les les monter et lancer l’installeur de DVD.

    1. # Insérer DVD  region Afrique
    2. sudo dd if=/dev/disk/by-label/XPLANE9 of=/home/USER/x-plane9-iso/XPLANE9-AFRICA.iso && eject
    3.  
    4. # Insérer DVD region Europe
    5. sudo dd if=/dev/disk/by-label/XPLANE9 of=/home/USER/x-plane9-iso/XPLANE9-EUROPE.iso && eject
    6.  
    7. # etc.. etc...

    Télécharger

    Monter une ISO de DVD de scène d’ x-plane 9 puis lance l’installeur de DVD.

    1. sudo mount -o loop -t udf XPLANE9-AFRICA.iso /media/cdrom0

    s’assurer qu’aucun autre média d’x-plane et présent, puis lancer l’installeur du DVD

    1. ./"X-Plane DVD Installer Linux"

  • Utiliser le serveur DHCP et les DNS du réseau distant

    Aprés quelques jours de lutte j’ai enfin réussi à configurer proprement mon client pour mettre ma machine sur le réseau distant.

    La configuration du client openvpn fonctionnait bien sur tunnelblick(OSX) et OpenVpnGUI (Windows) mais m’a donnée du fil à retordre sur Debian pour avoir quelque chose d’automatisé. surtout au niveau du serveur DHCP et du serveur de noms du réseau privé.

    1) Configuration du serveur openvpn

    Pour info, voici le fichier de configuration du serveur en mode bridge afin de fournir les infos DHCP et DNS du réseau :

    server.conf

    1. port 1194
    2. proto tcp
    3. dev tap0
    4.  
    5. ca ca.crt
    6. cert server.crt
    7. key server.key
    8. dh dh1024.pem
    9.  
    10. server-bridge
    11.  
    12. ### Envoyer les infos DHCP au clients ###
    13. push "dhcp-option DNS 192.168.122.1"
    14. push "dhcp-option DOMAIN domain.loc"
    15.  
    16. keepalive 10 120
    17. comp-lzo
    18.  
    19. max-clients 8
    20.  
    21. persist-key
    22. persist-tun
    23.  
    24. status openvpn-status.log
    25. log-append /var/log/openvpn.log
    26.  
    27. user openvpn
    28. group openvpn
    29.  
    30. persist-key
    31. persist-tun
    32. status openvpn-status.log
    33. verb 3
    34.  
    35. username-as-common-name

    Télécharger

    2) Configuration du client openvpn

    Ci-dessous la configuration client nommer client.conf. J’insiste sur L’extension, car le script de démarrage d’openvpn va lire les fichiers aux extension *.conf et demarrer autant de tunnel que de fichier .conf

    client.conf

    1. client
    2. dev tap0
    3. proto tcp
    4. remote  xxxxxxx.com 1194 #IP PORT
    5. resolv-retry infinite
    6. nobind
    7. persist-key
    8. persist-tun
    9. ca ca.crt
    10. cert server.crt
    11. key server.key
    12. comp-lzo
    13. auth-user-pass
    14. verb 3
    15. auth-user-pass login.txt
    16. log-append /var/log/openvpn.log
    17.  
    18. #IMPORTANT pour obtenir une adresse IP du serveur réseau dhcp distant
    19. #Installer le paquet resolvconf pour debian
    20.  
    21. script-security 2
    22. up update-resolv-conf
    23. down update-resolv-conf

    Télécharger

    On peux tester la config et suivre les logs :

    3) Obtenir l’adresse IP et le DNS via le DHCP du vpn

    Lorsque le service openvpn se connect il démarre pas l’interface tap0 je devais taper les commandes suivantes :

    4) Automatiser l’obtention de l’IP et du DNS

    Pour utiliser le script ci-dessous il est important d’installer le paquet resolvconf

    1. apt-get install resolvconf

    Pour automatiser toute la procédure de connexion j’ai modifié le script update-resolv-conf dans /etc/openvpn

    /etc/openvpn/update-resolv-conf : L 31 -> 36

    1. ### RESOLVCONF DOIT ETRE INSTALLE ###
    2. [ -x /sbin/resolvconf ] || exit 0
    3.  
    4. case $script_type in
    5.  
    6. up)
    7.         for optionname in ${!foreign_option_*} ; do
    8.                 option="${!optionname}"
    9.                 echo $option
    10.                 part1=$(echo "$option" | cut -d " " -f 1)
    11.                 if [ "$part1" == "dhcp-option" ] ; then
    12.                         part2=$(echo "$option" | cut -d " " -f 2)
    13.                         part3=$(echo "$option" | cut -d " " -f 3)
    14.                         if [ "$part2" == "DNS" ] ; then
    15.                                 IF_DNS_NAMESERVERS="$IF_DNS_NAMESERVERS $part3"
    16.                         fi
    17.                         if [ "$part2" == "DOMAIN" ] ; then
    18.                                 IF_DNS_SEARCH="$IF_DNS_SEARCH $part3"
    19.                         fi
    20.                 fi
    21.         done
    22.         R=""
    23.         for SS in $IF_DNS_SEARCH ; do
    24.                 R="${R}search $SS
    25. "
    26.         done
    27.         for NS in $IF_DNS_NAMESERVERS ; do
    28.                 R="${R}nameserver $NS
    29. "
    30.         done
    31.  
    32.         # Recupere les DNS du VPN
    33.         echo -n "$R" | /sbin/resolvconf -a "${dev}.inet"
    34.  
    35.         # Démarrer l'interface passé en paramètre du script (voir dev tapxx ds cfg)
    36.         /sbin/ifconfig ${dev} up
    37.         sleep 3
    38.  
    39.         # Demander une IP au Serveur DHCP au reseau PV
    40.         (
    41.                 /sbin/dhclient ${dev} &
    42.         )
    43.         ;;
    44. down)
    45.         /sbin/resolvconf -d "${dev}.inet"
    46.         ;;
    47. esac

    Télécharger

    Et voilà, désormais un simple service openvpn start connecte directement la machine au réseau privé et récupère une ip en dhcp.

    A noter que le service démarre automatiquement au boot de la machine.


  • Un noyau LXC sur serveur dédié OVH

    Suite à l’abandon de la technologie openvz dans les dépots officiels de debian wheezy ; Je dois me mettre à la page et utiliser LXC pour virtualiser mes environements linux.
    Le comble c’est que LXC ne nécessite pas de recompilation de noyaux mais malheureusement les kernels livrés par ovh n’ont pas les cgroup d’activés

    Récupérer les sources du noyau, le patch grsec et la config ovh qui va bien

    Se rendre dans un dossier de travail

    1. cd /usr/src

    Téléchargement du kernel

    1. wget ftp://ftp.kernel.org/pub/linux/kernel/v3.x/linux-3.9.6.tar.xz

    Téléchargement du patch grsecurity [1] correspondant à la version du noyau (3.9.6 dans l’article)

    1. wget https://raw.github.com/slashbeast/grsecurity-scrape/master/test/grsecurity-2.9.1-3.9.6-201306182033.patch

    récuperer la config du noyaux ovh sur leur serveur ftp [2]

    1. wget ftp://ftp.ovh.net/made-in-ovh/bzImage/latest-production/config-3.8.13-xxxx-grs-ipv6-64

    Préparer les sources

    décompresser [3] le noyau

    1. tar -Jxf linux-3.9.6.tar.xz

    copier la configuration ovh dans racine du noyau linux décompressé précédemment

    1. cp config-3.8.13-xxxx-grs-ipv6-64 linux-3.9.6

    aller dans le répertoire du noyau fraichement décompressé

    1. cd linux-3.9.6  

    appliquer le patch grsec

    1. patch -p1 < ../grsecurity-2.9.1-3.9.6-201306182033.patch

    Configuration des cgroups

    dans le repertoire du kernel, lancer l’utilitaire de configuration du noyau make menuconfig et configurer lxc cgroup [4] en activant les options suivantes :

    1. -> General setup
    2.         [renommer votre kernel] Local version - append to kernel release
    3.         -> Control Group support
    4.                 [x] Namespace cgroup subsystem
    5.                 [x] Freezer cgroup subsystem
    6.                 [x] Cpuset support
    7.                 [x] Simple CPU accounting cgroup subsystem
    8.                 [x] Resource counters
    9.                 [x] Memory resource controllers for Control Groups
    10.                 -> Group CPU scheduler
    11.                         [x] Basis for grouping tasks (Control Groups) (!)
    12.                         [x] Group scheduling for SCHED_OTHER (NEW)
    13.                         [x] CPU bandwidth provisioning for FAIR_GROUP_SCHED
    14.                         [x] Group scheduling for SCHED_RR/FIFO
    15.                 -> Namespaces support
    16.                         [x] UTS namespace
    17.                         [x] IPC namespace
    18.                         [x] User namespace (!)
    19.                         [x] Pid namespace
    20.                         [x] Network namespace
    21.  -> Device Drivers
    22.         -> Character devices
    23.                 [x] Support multiple instances of devpts
    24.                 [*] Unix98 PTY support
    25.         -> Network device support
    26.                 [x] MAC-VLAN support
    27.                 [x] Virtual ethernet pair device
    28.  -> Networking support
    29.         -> Networking options
    30.                 [x] 802.1d Ethernet Bridging
    31.                 [x] Network priority cgroup
    32.         -> Security options
    33.                 [x] File POSIX Capabilities (!)

    Télécharger

    (!) suivant la version/configuration du kernel certaines options peuvent être déplacées ou inexistantes. Pour activer l’option usernamespace je suis tombé sur un bug pour le noyau 3.8. De plus une contrainte oblige a désactiver le système de fichier XFS [5] pour pouvoir activer cette option. XFS devrait être supporté à partir des versions 3.10 du kernel linux.

    Une fois votre configuration terminée, retourner sur la page d’accueil de menuconfig sélectionner < Exit >, une boite de dialogue vous demande d’enregistrer votre configuration selectionner < yes > avant de quitter.

    Avant de compiler, On va tester la configuration :

    
    CONFIG=/usr/src/linux-3.9.6/.config lxc-checkconfig
    
     --- Namespaces ---
    Namespaces: enabled
    Utsname namespace: enabled
    Ipc namespace: enabled
    Pid namespace: enabled
    User namespace: enabled
    Network namespace: enabled
    Multiple /dev/pts instances: enabled
    
     --- Control groups ---
    Cgroup: enabled
    Cgroup clone_children flag: enabled
    Cgroup device: enabled
    Cgroup sched: enabled
    Cgroup cpu account: enabled
    Cgroup memory controller: missing (!)
    Cgroup cpuset: enabled
    
     --- Misc --- 
    Veth pair device: enabled
    Macvlan: enabled
    Vlan: enabled
    File capabilities: enabled
    
     

    Cgroup memory controller : missing (!) - Debian Wheezy

    Sur Debian wheezy, avec le paquet lxc, la configuration de "memory controller" semble manquante. En installant la dernière version de lxc (0.9) la vérification devient OK

    Youpi ! la configuration est maintenant terminée, il est temps de lancer la compilation avant de boire un café !

    Compilation du noyau

    Penser à installer les outils pour la compilation des noyaux. Sur Debian, le paquet s’appelle build-essential c’est un meta-paquet dédié a l’installation de tous les outils de compilation make, gcc, etc..

    Lancer la compilation, ou -j X (correspond au nombre de core ) :

    1. make -j 8

    Le kernel se retrouve dans le dossier arch/x86/boot. On va Copier/renommer le nouveau kernel dans le dossier /boot du système :

    1. cp arch/x86/boot/bzImage /boot/bzImage-3.9.6-xxxx-grs-ipv6-64-lxc

    Installer le kernel et redémarrer

    Je vous invite à consulter mon article précédent intitulé Installer un nouveau kernel Linux en 5 étapes


  • 1 - Mettre le nouveau kernel linux super optimisé dans le dossier /boot

    1. wget http://mon.super.kernel.com/bzimage-superkernel /boot

    2 - Editer Le fichier de "pré-configuration" personnalisé pour Grub2

    1. nano /etc/grub.d/40_custom

    Et ajouter une entrée en s’inspirant de /boot/grub/grub.cfg (notamment pour les uuid) pour votre tout nouveau kernel

    1. menuentry "Super Kernel" {
    2.         insmod part_msdos
    3.         insmod ext2
    4.         set root='(hd0,msdos1)'
    5.         search --no-floppy --fs-uuid --set 698e9aea-42f5-4c38-adc5-a34a4b7c0c11
    6.         linux   /boot/bzimage-superkernel root=/dev/sda1 ro  quiet
    7. }

    Télécharger

    3 - Forcer Grub à utiliser le Super Kernel par défaut

    1. nano /etc/default/grub

    repérer la ligne GRUB_DEFAULT="1", sinon l’ajouter.

    Modifier par le nom du "menuentry" créé précédemment.

    1. GRUB_DEFAULT="Super Kernel"

    4 - Régénérer le fichier de config de Grub2

    1. grub-mkconfig -o /boot/grub/grub.cfg

    5 - Zen et Confiant on Reboot !


  • 2 Méthodes en php pour recherche des lignes qui correspondent a un pattern.

    Méthode 1 - Rapide & gourmande en mémoire sur de gros fichiers

    1.     $tab = file('/path/fichier.txt');
    2.     $pattern = "/recherche/i";
    3.     $line = preg_grep($pattern, $tab);
    4.     print_r($line);    //affiche les lignes qui contiennent le mot recherche

    Télécharger

    Méthode 2 - Plus lent mais moins gourmand

    1. $fh = fopen('/path/fichier.txt', 'r') or die($php_errormsg);
    2. while (!feof($fh)) {
    3.     $line = fgets($fh, 4096);
    4.     if (preg_match($pattern, $line)) { $result[ ] = $line; }
    5. }
    6. fclose($fh);
    7. print_r($result)

    Télécharger


  • Un petit filtre pour utiliser facilement HeadJs avec Spip

    Headjs est une librairie jquery permettant d’optimiser le chargement des fichiers javascript. Voici comment l’utiliser dans un squelette spip en écrivant une fonction php.

    Headjs [1] est une librairie jquery permettant d’optimiser le chargement des fichiers js.

    Pour spip, une petite fonction pour utiliser headjs sur les scripts ajouter par les plugins dans le

    de vos pages.

    [(#INSERT_HEAD|headjs)]

    1. function headjs($insert_head){
    2.  
    3.     $pattern = "#src=\"(.*)\"#Ui" ; //khkzh
    4.  
    5.     preg_match_all($pattern, $insert_head, $split_content);
    6.     foreach($split_content[1] as $libjs)
    7.         $tabjs[]= '"'. $libjs . '"';
    8.    
    9.     $insert_head = implode(', ',$tabjs);
    10.    
    11.     return $insert_head;
    12. }

    Télécharger