All links of one day
in a single page.
<Previous day - Next day>

rss_feedDaily RSS Feed
floral_left The Daily Shaarli floral_right
——————————— Friday 08, February 2019 ———————————

ldapvi(1): LDAP client - Linux man page

Utiliser un éditeur de texte en ligne de commande (vim, nano, emacs, etc.) pour tripoter un serveur LDAP (ajouter / modifier / supprimer des attributs et / ou des objets). Très pratique.

ldapvi peut se reposer sur /etc/ldap/ldap.conf ou des paramètres explicites (-b = branche, -h serveur, -D dn de l'utilisateur avec lequel on s'authentifie) :

ldapvi -h ldaps://monldap.exemple.net:636 -D cn=admin,ou=ldap,dc=exemple,dc=net -b ou=people,dc=exemple,dc=net [ uid=guigui ]

L'éditeur qui sera utilisé par tous les utilisateurs sera celui sélectionné lors de la première utilisation. Apparemment, ça n'utilise pas /usr/bin/editor et update-alternatives. Pour corriger cela, on peut ajouter un alias : alias ldapvi='EDITOR=vim ldapvi' dans la config' de son shell.

ldapvi : « ldap_modify: Undefined attribute type (17) - additional info: entry update failed »

Avec ldapvi, je tente de retirer un attribut sur un objet de notre annuaire LDAP (slapd, OpenLDAP). Au moment d'enregistrer une erreur s'affiche :

ldap_modify: Undefined attribute type (17)
    additional info: entry update failed

Cet attribut est défini dans une classe maison. Cette classe était une classe de test qui a changé de nom depuis, tout comme l'attribut. Et voilà, tout est dit : avant de renommer ou de supprimer une classe ou des attributs, il faut les retirer de tous les objets du LDAP.

Pour réparer après-coup, il existe plusieurs méthodes. Si peu d'objets sont concernés : ldapdelete "uid=guigui,ou=people,dc=exemple,dc=net" Si beaucoup d'objets sont concernés : slapcat + sed + slapadd ou générer un LDIF adapté à coup de script shell. Si l'on a encore l'ancien schéma, on peut le remettre en service le temps du nettoyage.

vzdump(1) [ utiliser parallel gzip avec vzdump @ proxmox ]

Avec les versions récentes de Proxmox (plateforme intégrée de virtualisation libre), il est possible de sauvegarder une machine virtuelle en utilisant l'implémentation parallélisée de gzip, donc d'utiliser plusieurs cœurs du CPU pour effectuer la compression, ce qui réduit grandement le temps de la sauvegarde.

  • vzdump --pigz 1 : utiliser la moitié des cœurs disponibles sur la machine ;

  • vzdump --pigz 8 : utiliser 8 cœurs.

Évidemment, le paquet pigz doit être installé.

isc-dhcpd : « peer holds all free leases » et « not responding (recovering) »

Nous avons deux serveurs DHCP isc-dhcpd configurés pour de la redondance après panne (failover). On nous informe qu'il n'est plus possible d'obtenir une adresse IP sur l'un des réseaux Wi-Fi. Les autres réseaux (sans fil et filaires) ne sont pas impactés.

Nous regardons le journal sur nos deux serveurs. Ils sont remplis (et se remplissent à grande vitesse) de ce message :

dhcpd: DHCPDISCOVER from 00:00:5E:00:53:01 via 192.0.2.1: peer holds all free leases

Au total, deux-trois réseaux subissent ce désagrément. En creusant, on s'aperçoit que ces erreurs se produisent depuis 4 à 6 jours, mais que c'est récent (moins d'un jour) pour le réseau Wi-Fi qui fait l'objet de l'investigation.

Cela peut signifier que nos plages d'IP dynamiques (range) sont sous-dimensionnées par rapport à notre nombre d'utilisateurs (ce qui explique que nos réseaux Wi-Fi sont les premiers visés : de nos jours, tout le monde a 20 objets sur lui qui veulent se connecter à du réseau sans fil) ou que nos baux DHCP ne sont pas libérés / rendus (peut-être car nous octroyons une durée trop longue et que les clients ne les rendent pas explicitement, ce qui fait que les IP ne sont pas remises dans le pot commun ?).

Je fais cette réflexion à froid, mais, lors de cet incident, nous avons décidé de stopper le service sur chacun de nos serveurs DHCP, de supprimer le journal des baux octroyés (/var/lib/dhcp/dhcpd.leases) puis de démarrer le service DHCP. Évidemment, je ne recommande pas cette méthode, car elle peut mettre la grouille dans un réseau puisqu'on se repose exclusivement sur la capacité d'un système connecté au réseau de tester l'IP que lui a octroyée le DHCP et de la refuser (DHCPNAK) si elle est déjà utilisée (ce qui va être en grande majorité le cas), ce qui constitue une perte de la maîtrise de ton réseau.

Les journaux sont désormais saturés d'un autre message d'erreur :

dhcpd: DHCPDISCOVER from 00:00:5E:00:53:01 via 192.0.2.1: not responding (recovering)

Au début, nous ne nous inquiétions pas : ce message peut signifier que le serveur DHCP ne répond pas aux requêtes le temps de construire sa base de données suite à un failover. Rien de dramatique si ça dure moins de 30 secondes - 1 minute. Mais ce problème perdure.

Je décide de revenir sur le message d'erreur initial (« peer holds all free leases »). Cela ne signifierait-il pas que nos deux serveurs DHCP ne communiquent plus entre eux pour s'informer mutellement des adresses IPs distribuées ?

Je regarde la configuration : nos serveurs sont configurés pour échanger leur état sur le port TCP/519. Un petit ss -taupen | grep ":519" met en évidence que nos deux serveurs écoutent sur ce port, mais qu'il y a aucune connexion d'un serveur vers l'autre.

Je regarde la configuration (/etc/dhcp/dhcpd.conf) de chaque serveur : suite à une erreur récente (moins d'un jour) dans la modification d'un script de mise en production de ce fichier à partir d'une base de donnée maison, l'entête de chaque fichier de conf' est identique. Donc les deux serveurs croient avoir le rôle de primaire, la même IP et croient devoir contacter un autre serveur qu'eux sur une autre IP afin d'effectuer de la redondance en cas de panne.

Je corrige, je redémarre les services et… la distribution d'adresses IP reprend quasi instantanément son cours. \o/

Note : les adresses MACs citées ci-dessus sont des adresses MAC réservées et destinées à la documentation. Même chose pour les adresses IP.

LDAP : ajouter des droits sur des attributs ou sur tous les attributs d'une classe

Dans un annuaire LDAP (slapd, OpenLDAP), on peut attribuer des droits différents à plusieurs utilisateurs.

On peut octroyer des droits de lecture et / ou d'écriture sur toute l'arborescence ou sur une partie (une ou plusieurs branche / unité organisationnelle) :

dn: olcDatabase={1}mdb,cn=config
changetype: modify
delete: olcAccess
-
add: olcAccess
olcAccess: {0}to dn.subtree="ou=test,dc=exemple,dc=net" by dn="cn=test,ou=ldap,dc=exemple,dc=net" write by dn="cn=admin,ou=ldap,dc=exemple,dc=net" write by * none
-
[ autres règles ici ]
-
add: olcAccess
olcAccess: {1}to * by dn="cn=admin,ou=ldap,dc=exemple,dc=net" write by * none

Dans cet exemple, l'utilisateur « cn=test,ou=ldap,dc=exemple,dc=net » pourra ajouter des objets dans la branche « ou=test,dc=exemple,dc=net », modifier et supprimer tout objet existant dans cette branche.

On peut aussi octroyer des droits de lecture et / ou d'écriture sur des attributs précis sur tous les objets de toutes les branches (sauf règle contraire ;)) : olcAccess: to attrs=attr1,attr2,attr2,attr3 […]. Il n'est pas possible d'utiliser un joker. Exemple : il n'est pas possible d'écrire « attrs=person* » dans l'intention d'accorder des droits sur tous les attributs dont le nom commence par « person ». Attention : avec le droit d'écriture, il sera possible d'ajouter et de supprimer des attributs sur des objets sur lesquels l'utilisateur n'a pas les droits d'écriture. Même chose avec les droits de lecture : il sera possible de lire uniquement ces attributs-là sur un objet sur lequel l'utilisateur n'a pas de droits plus larges.

Dans la continuité du point précédent, il est possible d'octroyer des droits pour tous les attributs d'une classe. olcAccess: to attrs=@maClasse […]. Toutes les remarques précédentes s'appliquent aussi ici.

Attention : lorsque l'on octroie des droits "fins" (sur des branches, des attributs, etc.), il faut spécifier les droits des autres utilisateurs. Exemple : si, dans le premier exemple ci-dessus, dans la première règle, je ne précise pas que l'utilisateur « cn=admin,ou=ldap,dc=exemple,dc=net » a aussi des droits sur cette branche, il aura aucun droit, la deuxième règle ne s'appliquant pas.

Riser card - Wikipedia

Une carte riser PCI est un circuit imprimé qui permet de déporter une carte d'extension, qui n'est ainsi plus branchée sur un port de la carte mère, mais sur le riser.

Parfois, les cartes d'extension (réseau, contrôleur RAID, etc.) proposées par un équipementier ne peuvent pas être branchées perpendiculairement à la carte mère sur un serveur au format 1U, car elles sont plus hautes que ce format et empêchent donc la fermeture du châssis. Un riser permet de positionner la carte d'extension parallèlement à la carte mère, et ainsi de résoudre ce manque de hauteur.

ldapvi : « ldap_modify: Inappropriate matching (18) - additional info: modify/delete: monAttribut: no equality matching rule »

Dans notre annuaire LDAP (slapd, OpenLDAP), nous avons créé une classe auxiliaire (oui, il y existe différents types de classe LDAP). Avec ldapvi, on ajoute des attributs de cette classe sur des objets qui existent déjà. Cela fonctionne. On modifie la valeur d'un attribut sur ce même objet : cela fonctionne. On tente de supprimer les attributs ajoutés (sans supprimer l'attribut « objectClass »), ça échoue pour l'un d'eux:

ldap_modify: Inappropriate matching (18)
    additional info: modify/delete: monAttribut: no equality matching rule

Dans la définition d'un attribut, il est possible de définir des règles de comparaison. Un peu comme la surcharge des opérateurs de comparaison permettant de comparer des objets maison dans les langages de programmation orienté objet. Par exemple, pour une chaîne de caractères, on utilise souvent la règle « caseIgnoreMatch » (mais on peut aussi utiliser « telephoneNumberMatch », « caseExactMatch », etc., toutes définies dans le RFC 4517).

Dans mon cas, l'attribut est de type booléen (si, c'est possible, le RFC 4517 en normalise la définition) :

attributetype ( 1.3.6.1.4.1.7135.1.3.39.2.1.23
        NAME 'monAttribut'
        DESC 'Attribut de test'
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.7)

Et, en effet, comme il s'agit d'un booléen, je n'ai pas précisé de règle de comparaison, en pensant que c'est évident (alors que cet exemple illustre qu'il n'y a pas de règle de comparaison par défaut). Il existe la règle de comparaison « booleanMatch », qu'il suffit d'ajouter à la définition de notre attribut pour résoudre le problème :

attributetype ( 1.3.6.1.4.1.7135.1.3.39.2.1.23
        NAME 'monAttribut'
        DESC 'Attribut de test'
        EQUALITY booleanMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.7)

Migrer un projet SVN vers GIT [ avec conservation de l'historique ] - yterium.net

Migrer un dépôt SVN vers un dépôt git avec conservation de l'historique :

  • Installer l'outil : aptitude install git-svn

  • Créer un fichier de correspondance entre les noms d'auteur / login svn et les noms d'auteurs git :

    authors=$(svn log -q svn://login@monserveursvn.exemple/mondepot | grep -e '^r' | awk 'BEGIN { FS = "|" } ; { print $2 }' | sort | uniq)
    for author in ${authors}; do
        echo "${author} = ${author%@*} <${author}>";
    done



    Dans la partie gauche : le nom d'auteur SVN. Dans la partie droite, son équivalent git. Attention : l'équivalent git doit vraiment être de la forme « texte », sinon une erreur se produira. Dans mon cas, j'utilise un gitlab. Dans la partie droite, j'ai mis les infos (name et email) de mon fichier .gitconfig. Gitlab a parfaitement associé cela à mon login gitlab, comme avec un dépôt git nouvellement créé \o/ ;

  • Convertir le dépôt : git svn --authors-file=authors clonesvn://login@monserveursvn.exemple/mondepot dossier_destination. Attention : la conversion prend beaucoup de temps : 45 minutes pour 12500 commits dans un dépôt svn contenant 120 fichiers qui représentent cumulativement 13700 lignes ;

  • Dans les message de commit, supprimer les références au dépôt SVN ajoutées automatiquement par git-svn (je vais détruire le dépôt svn, donc inutile d'y faire référence) :

    cd mondepot
    git filter-branch --msg-filter '
        sed -e "/git-svn-id:/d"
    '


  • Créer le dépôt git distant (sur gitlab, gogs, etc.) et ajouter sa référence dans les paramètres du dépôt local :

    cd mondepot
    git remote add origin user@monservergit.exemple:mondepotgit


  • Synchroniser le dépôt distant avec notre exemplaire local : git push -u origin master.
-