NetBSD, le système du futur du subjonctif

Magazine
Marque
GNU/Linux Magazine
HS n°
Numéro
74
Mois de parution
septembre 2014
Domaines


Résumé
« The Original UNIX », c'est pour cette punchline que j'avais voté lorsque le groupe chargé du marketing chez NetBSD cherchait une approche différente du classique « of course it runs NetBSD » ; néanmoins, s'il est l'héritier le plus direct des travaux du CSRG [1] et l'un des plus grands défenseurs de la portabilité du code, le projet NetBSD n'est certainement pas un système d'exploitation du passé, loin s'en faut. Bénéficiant des avancées standards d'autres OS, NetBSD dispose en outre d'avantages uniques dont l'administrateur système aguerri saura faire usage. Dans cet article, nous allons monter un serveur web articulé autour de briques modernes, et allons dans notre périple découvrir l'ensemble des éléments nécessaires au déploiement d'un système aussi réactif que respectueux des standards.

Body

Avant de plonger corps et âme dans les entrailles de cet univers auquel vous ne connaissez peut-être encore rien, je poserai ici les bases de notre travail. Afin de ne pas molester vos installations existantes, je partirai du principe que nous travaillerons dans une machine virtuelle, qu'elle soit Xen, KVM, VirtualBox, ou encore VMware, choisissez l'environnement qui vous sied, NetBSD s'en accommodera parfaitement ; notez cependant que le système au drapeau orange supporte le mode PV (para-virtualisé) de Xen. Une configuration classique pour ce dernier mode ressemble à ceci :

kernel="/var/xen/kernels/netbsd-XEN3_DOMU_6.1.4.gz"
#kernel="/var/xen/kernels/netbsd-INSTALL_XEN3_DOMU_6.1.4.gz"

vcpus = '2'
memory = "2000"
name = "gcuio"

vif = [ 'mac=00:50:56:01:02:03, bridge=xenbr0' ]

sdl=0
vnc=0

disk = [ 'phy:/dev/mapper/vg1-gcuio,hda,w', 'file:/var/xen/isos/NetBSD-6.1.4-amd64.iso,hdc:cdrom,r' ]

boot = 'cd'

on_poweroff = 'destroy'
on_reboot = 'restart'
on_crash = 'restart'

serial='pty'

Observez, dans les premières lignes de ce fichier de configuration, que l'installation du système s'est faite avec le noyau netbsd-INSTALL_XEN3_DOMU_6.1.4.gz, mais que nous avons par la suite commenté cette variable pour laisser place à un noyau NetBSD classique qui démarre désormais le domU.

J'utilise cette méthode sur l'intégralité de mes machines serveur personnelles. Mes dom0 sont généralement des machines Debian GNU/Linux, car c'est le système que l'on trouve sur la quasi totalité des serveurs dédiés, et cela me permet en outre de garder une certaine expérience dans ce système.

Côté réseau, la situation est assez simple, le dom0 est connecté publiquement sur une interface physique, typiquement eth0, et les domU sont bridgés sur une interface xenbr0. Les portions relatives du fichier /etc/network/interfaces sont les suivantes :

auto eth0
iface eth0 inet static
 address 1.2.3.4
 netmask 255.255.255.0
 network 1.2.3.0
 broadcast 1.2.3.255
 gateway 1.2.4.254

auto xenbr0
iface xenbr0 inet static
 address 192.168.0.254
 netmask 255.255.255.0
 network 192.168.0.0
 broadcast 192.168.0.255
 bridge_ports none
 bridge_maxwait 0
 bridge_fd 0

Ce mode de fonctionnement s'active, côté Xen, dans le fichier /etc/xen/xend-config.sxp à l'aide de la directive suivante :

(vif-script vif-bridge)

Ainsi, il suffit de placer quelques règles iptables bien senties pour contrôler l'accès depuis et vers nos domU :

# On autorise le domU à contacter l'Internet
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j MASQUERADE
# On redirige le port 2222 du dom0 (public) vers le port 22 du domU
iptables -t nat -A PREROUTING -i eth0 -p tcp -m tcp --dport 2222 -j DNAT --to-destination 192.168.0.1:22 iptables

Il suffira de configurer nos domU sur le sous-réseau 192.168.0.0/24 et de leur indiquer la passerelle 192.168.0.254 pour qu'ils puissent communiquer avec le reste du monde.

1. Welcome to NetBSD !

L'installation terminée, le fatidique reboot effectué, vous devriez être en mesure de vous connecter pour la première fois sur votre terminal NetBSD. Ce dernier vous souhaite très certainement la bienvenue. Pas d'empressement, nous allons avant toute chose effectuer un tour du propriétaire et nous préparer un environnement digne de ce nom.

Vous êtes très certainement l'administrateur de cette machine (virtuelle ou non), et il sera tôt ou tard nécessaire de vous octroyer temporairement des droits root afin d'effectuer des opérations nécessitant ce niveau de privilège. Connectez-vous donc avec l'utilisateur root, et ajoutez votre utilisateur au groupe wheel, historiquement le groupe associé aux administrateurs sur tous les UNIX BSD :

$ usermod -G wheel foo

Ceci fait, vous pouvez désormais vous connecter avec l'utilisateur que vous avez normalement créé lors de l'installation du système et utiliser la commande su afin de passerroot momentanément.

Il est probable que vous souhaitiez désormais configurer cette nouvelle machine à travers une connexion distante, aussi nous allons faire connaissance avec l'une des pièces maîtresses du système NetBSD : rcNG.

NetBSD, mais plus généralement les différents systèmes BSD, n'utilisent pas le classique init(8) System V [2] et encore moins des usines Shadock telles que systemd. « Ne faites qu'une chose, mais faites-la bien » : rcNG est un système élégant et portable de démarrage des services, qui lit les ordres inscrits dans le fichier /etc/rc.conf et exécute, ou pas, les services indiqués. Pour démarrer le service OpenSSH, il suffira d'ajouter à ce fichier la variable suivante :

sshd="YES"

Moyennant quoi :

- Vous pourrez démarrer sshd en ligne de commandes de cette façon : /etc/rc.d/sshd start ;

- sshd sera exécuté lors de l'init de la machine.

Il est très probable que vous ayez configuré l'adressage IP de votre futur serveur lors de l'installation de ce dernier, cependant, si quelques remords vous assaillaient et que vous deviez modifier ces paramètres, sachez que les informations relatives à la configuration IP de votre système se trouvent dans le fichier /etc/ifconfig.<iface><iface> représente le nom de votre interface réseau. En effet, les interfaces réseau ne se nomment pas eth[0-9]+, mais portent un nom associé au pilote faisant fonctionner le matériel. Par exemple, dans une machine virtuelle Xen, l'interface réseau se nomme xennet0, l'interface loopback lo0, et la première interface associée à une carte de marque RealTek se nommera re0.

sysinst(8), le programme réalisant l'installation du système, enregistre la valeur correspondant à la passerelle par défaut dans le fichier /etc/rc.conf, dans la variable defaultroute ; je lui préfère le fichier /etc/mygate, qui contient simplement l'adresse de la passerelle. De la même façon, le fichier /etc/myname contient le nom complet de la machine, ou FQDN (Fully Qualified Domain Name).

Le fichier /etc/ifconfig.<iface> est interprété par le script d'init /etc/rc.d/network, et ce dernier est capable de réaliser un certain nombre de tâches. Par exemple, l'interface publique de ma passerelle domestique contient les lignes suivantes :

create
!dhcpcd -i neufbox_NetBSD_gateway-imil@NetBSD.org $int
inet 172.16.10.1 netmask 0xffffffff alias

Ces trois lignes créent l'interface, re1 ici, démarrent le client DHCP qui interrogera le routeur de mon opérateur et associera l'IP obtenue à l'interface $int (re1, donc) et pour finir, j'ajoute un alias IP à cette même interface.

Très classiquement, les informations relatives à la résolution de nom se trouvent dans le fichier /etc/resolv.conf et ont exactement la même syntaxe que sur un système GNU/Linux :

nameserver 109.0.66.10
nameserver 109.0.66.20
search example.com foo.net bar.org

À cette étape, vous devriez être en mesure de contacter le reste de l'Internet, une simple commande ping vous en convaincra :

$ ping -c 1 gcu.io
ksh: ping: not found

Ah, oui, le PATH. Par défaut, le simple utilisateur que vous êtes n'est pas muni d'un accès immédiat aux chemins réservés aux administrateurs ; il vous suffira d'ajouter les répertoires /sbin, /usr/sbin et /usr/pkg/sbin (nous reviendrons sur ce dernier chemin plus tard), afin de pouvoir exécuter les commandes réservées (et cette fois-ci le ping fonctionnera).

Munis de ces capacités, nous allons pouvoir passer à l'étape suivante : l'installation de vos paquets chéris.

2. Logiciels tierce partie

Avant de polluer notre système flambant neuf par une ribambelle d'outils, il est nécessaire de comprendre une notion commune à l'ensemble des systèmes BSD UNIX populaires : NetBSD, FreeBSD, OpenBSD ou DragonFlyBSD ne désignent pas uniquement un noyau, mais bel et bien un système d'exploitation complet ; en effet, à l'issue de l'installation, l'OS est parfaitement utilisable en l'état, sans avoir pour autant installé de paquets contrôlés par un gestionnaire quelconque. Un système NetBSD peut, à l'issue de son installation, faire office de serveur DNS, DHCP, SMTP, HTTP, FTP, ou encore SSH, car ces logiciels font partie d'un système de base (basesystem) contrôlé par les développeurs du projet. Ils sont distribués sous forme d'archives (les sets) qui sont déployées par l'installeur sysinst(8). Ces logiciels sont décompressés à la racine dans les chemins officiels connus que sont /bin, /sbin, /etc, /usr/bin, /usr/sbin, libexec, etc., au moment de l'installation initiale de NetBSD, lorsqu'on choisit les types de services que rendra la machine.

Évidemment, il est très rare que les seuls services de base soient suffisants à vos besoins, rentrent alors en jeu les applications tierce partie, contrôlées, elles, par un gestionnaire de paquets. La singularité des systèmes BSD sur ce point, c'est que les paquets ne polluent pas le basesystem, ces derniers étant localisés dans un répertoire dédié. Dans NetBSD, par défaut, il s'agit du répertoire /usr/pkg. On y retrouvera /usr/pkg/bin, /usr/pkg/sbin, /usr/pkg/, etc., soit une arborescence classique, mais dé-corrélée du basesystem.

2.1 pkgsrc, histoire et concept

Historiquement, les paquets, sous NetBSD, sont gérés par une infrastructure puissante, homogène, portable, mais pourtant simple d'utilisation : pkgsrc [3].

Pkgsrc est initialement un fork des ports de FreeBSD qui a eu lieu à la fin des années 90. Ce fork avait un but avoué : rendre portables les ports sur d'autres architectures que FreeBSD et NetBSD ; ainsi, très tôt, pkgsrc fonctionnait déjà sous Solaris. L'un des créateurs de pkgsrc, Alistair G. Crooks, actuel membre du NetBSD Core Group, explique dans une interview [4] qu'il pressentait le potentiel d'un système de paquets basé sur des Makefiles, mais qu'il n'en tira réellement profit qu'en 1999. En effet, cette année-là, dans le cadre de son travail, il dut réfléchir à un système de déploiement de paquets tierce partie pour un réseau relativement important composé de machines sous Solaris 2.6. Ainsi, Solaris fut la première plateforme, après NetBSD, à bénéficier de pkgsrc, suivie de près par Linux, puis Mac OS X.

Pkgsrc, comme les ports de FreeBSD et OpenBSD, est une infrastructure articulée autour du logiciel make(1). Un paquet est en effet représenté par un répertoire dans lequel on trouvera un fichier Makefile indiquant comment on doit compiler le logiciel concerné, car oui, initialement pkgsrc seul ne permet de travailler que sur des paquets sources, mais nous verrons que cette fastidieuse tâche est désormais totalement optionnelle pour l'administrateur pressé.

La mise à disposition de pkgsrc se fait selon une rotation réglée comme une horloge : tous les trois mois, une version à jour de l'arbre des paquets est branchée ; cette nouvelle branche prend pour point d'appui pkgsrc current et se voit figée le temps de corriger les bogues importants. Cette opération prend entre deux et trois semaines. Un communiqué est alors rédigé, relu et complété, puis la version de pkgsrc correspondant au trimestre est alors annoncée. À l'heure où j'écris ces lignes, pkgsrc-2014Q2 a été annoncé il y a deux semaines, et pkgsrc-2014Q3 devrait démarrer son gel en septembre 2014.

Les plus aventureux peuvent évidemment suivre l'arbre current de pkgsrc, mais il faudra garder à l'esprit que les versions de logiciels intégrés sont les plus récentes, et que ces dernières peuvent entraîner une incompatibilité sur un nombre important de paquets qui en dépendent.

Des discussions enflammées embrasent les listes de développeurs NetBSD quant au choix du gestionnaire de sources à utiliser. Pour ma part, j'importe et publie mes modifications dans l'arbre des paquets pkgsrc via l'ancestral CVS, qui ne m'a jamais fait défaut. Il est également possible de télécharger l'arbre complet via le gestionnaire de sources git, et il est à noter que ce dernier ne faisant pas partie du système de base, il sera nécessaire de l'installer avant de poursuivre les opérations... Mais comment l'installer si nous ne disposons pas encore de l'arbre des paquets ? Avec un gestionnaire de paquets binaires bien sûr !

2.2 pkgin

pkgin [5] est un gestionnaire de paquets binaires dont l'utilisation se veut quasiment identique à l'apt de Debian ou au yum de Red Hat. Il s'articule sur un fichier très simple, /usr/pkg/etc/pkgin/repositories.conf, dans lequel vous renseignerez simplement le nom du dépôt que vous souhaitez utiliser. Par exemple :

$ grep -v \# /usr/pkg/etc/pkgin/repositories.conf
http://ftp.fr.netbsd.org/pub/pkgsrc/packages/NetBSD/$arch/6.0/All

Notez que sysinst(8) vous aura déjà proposé l'installation de pkgin, ainsi utilisable immédiatement sur votre système fraîchement installé, mais vous préférerez probablement utiliser un miroir plus proche de chez vous. Une fois l'URL modifiée, lancez simplement la commande :

# pkgin update

Et pkgin sera alors prêt à installer tout paquet disponible dans le dépôt renseigné. Par exemple, puisque nous en parlions précédemment :

# pkgin install git
calculating dependencies... done.

nothing to upgrade.
21 packages to be installed: p5-Net-SSLeay-1.63 p5-Net-LibIDN-0.12nb6
...
git-docs-1.9.4 git-base-1.9.4 git-1.9.4 (14M to download, 213M to install)
...
updating database: 100%
marking git-1.9.4 as non auto-removable

À l'issue de cette commande, git est installé dans ce qu'il convient d'appeler la LOCALBASE, généralement /usr/pkg :

$ which git
/usr/pkg/bin/git

Notez que pkgin ayant été écrit par un paresseux notoire (moi), il dispose de raccourcis permettant de taper le moins de caractères possible :

# pkgin in # install
# pkgin rm # remove
# pkgin up # upgrade
# pkgin fug # full-upgrade

2.3 pkgsrc, installation et utilisation

Nous sommes en mesure d'installer pkgsrc de trois façons différentes :

- en téléchargeant une archive tar.gz, tar.bz2 ou encore tar.xz mise à disposition sur l'un des miroirs du projet,

- via le gestionnaire de sources CVS,

- via le gestionnaire de sources git.

Classiquement, on déploie pkgsrc dans le répertoire /usr/pkgsrc, ainsi :

# cd /usr
# ftp://ftp.netbsd.org/pub/pkgsrc/pkgsrc-2014Q2/pkgsrc.tar.bz2
# tar jxvf pkgsrc.tar.bz2

Ou encore :

# cd /usr
# cvs -d anoncvs@anoncvs.fr.NetBSD.org:/cvsroot co -rpkgsrc-2014Q2 pkgsrc

Ou bien :

# cd /usr
# git clone -b pkgsrc_2014Q2 https://github.com/jsonn/pkgsrc.git

Vous voici désormais en possession d'un arbre pkgsrc prêt à l'emploi. L'arborescence de l'arbre est logique, elle est de la forme pkgsrc/catégorie/application ; ainsi, on trouvera dans www/ les logiciels relatifs au Web (curl, nginx, apache, w3m, webalizer, firefox...), dans graphics, les applications ayant trait au graphisme, et ainsi de suite. Pour retrouver facilement l'emplacement d'un paquet, il est judicieux d'installer l'utilitaire pkgfind qui se trouve dans la section pkgtools/.

L'installation d'un paquet source se réalise de cette façon :

# cd /usr/pkgsrc/pkgtools/pkgfind && make install clean clean-depends

Ceci va avoir pour conséquence de télécharger et compiler l'intégralité des dépendances nécessaires au logiciel pkgfind, puis de procéder à la compilation du logiciel lui-même. On ajoute les cibles de make clean et clean-depends afin que pkgsrc nettoie les objets issus de la compilation, tant dans le logiciel cible que dans ses dépendances. On peut lister les dépendances d'un paquet à l'aide le la commande :

$ cd /usr/pkgsrc/x11/xfce4-terminal
$ make show-depends
glib2>=2.34.0:../../devel/glib2
...
xfce4-exo>=0.3.101nb24:../../x11/xfce4-exo

Pkgsrc dispose d'une méthode de personnalisation souple et élégante ; en effet, en éditant le fichier /etc/mk.conf, on peut paramétrer certaines options des logiciels tierce partie. Exemple concret : le paquet nginx, célèbre serveur web et proxy HTTP(S), est par défaut construit avec les options suivantes :

inet6 pcre ssl

Comme nous l'indique la commande suivante :

$ cd /usr/pkgsrc/www/nginx
$ make show-options
Any of the following general options may be selected:
 array-var
 ...
 uwsgi

These options are enabled by default:
 inet6 pcre ssl

Mais comme on peut le découvrir, de nombreuses fonctionnalités pourraient s'avérer intéressantes pour la mise en place d'un serveur web moderne. Ceci est réalisé en ajoutant cette variable au fichier /etc/mk.conf :

PKG_OPTIONS.nginx+=  naxsi dav realip sub spdy luajit echo set-misc headers-more array-var encrypted-session form-input

Lors de sa compilation, le paquet nginx se verra affublé de tous les modules ainsi listés. S'il avait été nécessaire de mettre à jour nginx car ce dernier était déjà installé, on aurait pu utiliser la fonction :

# make update clean clean-depends

Afin de s'épargner d'ajouter clean-depends à chaque construction, nous ajouterons au fichier /etc/mk.conf la variable suivante :

CLEANDEPENDS=yes

2.4 Un peu plus loin avec mk.conf

Jusqu'où exactement pouvons-nous aller dans le fichier mk.conf ? Assez loin en réalité, voyons quelques-uns des paramètres qui rendront vos compilations plus rapides.

Votre machine, virtuelle ou pas, dispose de plusieurs processeurs ? Tirez-en profit !

MAKE_JOBS=4

Cette ligne fera passer l'information à make que vous disposez de 4 (v)CPU et vos compilations C/C++ n'en seront que plus véloces. Toujours dans une optique de rapidité, pkgsrc sait nativement utiliser le logiciel ccache, un système de cache de compilation C/C++. Pour en faire usage, ajoutez au fichier mk.conf :

PKGSRC_COMPILER=ccache gcc

Vous préférez curl au classique ftp qui peine à suivre les codes 302 sur du HTTPS ? Pas de problème :

FETCH_USING=curl

Cette méthode est par ailleurs largement recommandée.

Vous voulez vous assurer que les miroirs français, puis anglais, puis allemands seront utilisés, ajoutez :

MASTER_SORT=.fr .uk .de

Vous êtes un testeur, un développeur, vous souhaitez déboguer un logiciel et avez besoin qu'il soit installé avec ses symboles, il y a une variable pour ça aussi :

INSTALL_UNSTRIPPED=yes

pkgsrc offre beaucoup de possibilités, et dispose de plusieurs versions des langages communément utilisés ; aussi, si votre projet client est articulé autour de la version 5.4 de PHP, placez cette variable :

PHP_VERSION_DEFAULT=54

À tout moment dans pkgsrc vous pouvez vous enquérir de la valeur d'une variable à l'aide de la commande suivante :

$ make show-var VARNAME=X11_TYPE
modular

3. Pour vous servir

Nous sommes désormais équipés pour manipuler plus sereinement les éléments fondateurs d'un serveur articulé autour du système NetBSD, nous nous proposons donc dans la suite de cet article de déployer un service web interagissant avec des briques modernes :

- Nginx

- Elasticsearch [8]

- Gunicorn [9]

- Flask [10]

- Python

Ces 5 piliers sont les fondations du site gcu.io [6], une interface éminemment dynamique relatant en temps réel l'activité du canal IRC du groupe GCU-Squad! [7]. On y trouve les discussions - pas toujours en relation avec le Logiciel Libre - des membres du groupe en « live », les URL mentionnées sur le canal et la pré-visualisation des images pas toujours compatibles avec un environnement de travail. Ces informations sont stockées dans une base de données Elasticsearch.

La première étape de notre setup consiste en l'installation du service Elasticsearch. Très simplement, nous utiliserons pkgin qui se chargera de télécharger le paquet binaire ainsi que ses dépendances. L'utilisateur avancé pourra bien évidemment procéder à l'installation du service via le paquet source, ce dernier se situant dans databases/elasticsearch :

$ sudo pkgin in elasticsearch
calculating dependencies... done.

nothing to upgrade.
6 packages to be installed: ttmkfdir2-20021109nb6 zip-3.0nb2 unzip-6.0nb1 dejavu-ttf-2.34nb1 openjdk7-1.7.60nb1 elasticsearch-1.1.0nb1 (91M to download, 185M to install)

proceed ? [Y/n] y
downloading packages...
...
updating database: 100%
marking elasticsearch-1.1.0nb1 as non auto-removable

Un fichier d'init a été placé dans /usr/pkg/share/examples/rc.d/elasticsearch et pkg_add, l'outil qui se charge de l'installation effective des paquets binaires à l'instar de dpkg pour apt, nous informe qu'il faudra copier ce dernier dans le répertoire /etc/rc.d.

Cette étape aurait pu être évitée si nous avions renseigné la variable PKG_RCD_SCRIPTS=yes dans /etc/mk.conf, qui indique à pkg_add ainsi qu'à pkgsrc de copier automatiquement le script dans le répertoire prévu à cet effet.

Le répertoire rc.d, comme nous l'avons vu au début de cet article, contient les scripts de démarrage des services, et ces derniers s'activent dans le fichier /etc/rc.conf, ainsi nous ajoutons :

elasticsearch=YES

Et nous pouvons alors démarrer le service comme suit :

# /etc/rc.d/elasticsearch start
Starting elasticsearch.

Nous nous assurons que le service fonctionne et répond sur le port 9200 :

$ ps axuww|grep elastic
elasticsearch 11168 7.6 31.8 1313740 166632 pts/1 Sl 3:39PM 0:04.03 /usr/pkg/java/openjdk7/bin/java -Delasticsearch -Des.pidfile=/var/run/elasticsearch.pid
...
$ telnet localhost 9200
Trying ::1...
Connected to localhost.
Escape character is '^]'.
^]

Tout semble correct. Afin de communiquer avec le service REST [11] elasticsearch, nous utiliserons le logiciel curl que nous installons avec pkgin :

$ curl -XGET http://localhost:9200
{
 "status" : 200,
 "name" : "Airborne",
 "version" : {
 "number" : "1.1.0",
 "build_hash" : "2181e113dea80b4a9e31e58e9686658a2d46e363",
 "build_timestamp" : "2014-03-25T15:59:51Z",
 "build_snapshot" : false,
 "lucene_version" : "4.7"
 },
 "tagline" : "You Know, for Search"
}

elasticsearch répond bien en JSON son en-tête habituelle.

3.1 Entracte : Python et pkgsrc

Faisons une petite pause dans le travail de mise en œuvre de notre serveur d'applications pour découvrir un peu plus la puissance de pkgsrc.

J'ai découvert sur Twitter l'existence d'un outil aussi puissant que simple d'utilisation : HTTPie [12], un programme en ligne de commandes permettant d'interroger un service HTTP de façon très intuitive. Ce programme a en outre la capacité d'interagir avec le langage JSON de façon native. Cerise sur le gâteau, HTTPie affiche le résultat en couleurs, suivant un thème configurable ; les amateurs de molokai ou solarize apprécieront, car ces deux thèmes sont disponibles par défaut.

J'ai empaqueté cet outil au mois de juillet 2014, cela m'a pris environ quinze minutes. En effet, HTTPie est un outil écrit avec le langage Python, et pkgsrc dispose d'une infrastructure particulièrement bien pensée pour les applications articulées autour de systèmes de distribution ; ainsi, pour Python, on abstrait complètement l'intégration du logiciel dans pkgsrc à l'aide de simples include.

On démarre la création d'un paquet toujours de la même façon :

$ cd pkgsrc/www/
$ mkdir py-httpie
$ url2pkg https://pypi.python.org/packages/source/h/httpie/httpie-0.8.0.tar.gz

url2pkg est un logiciel destiné à la préparation d'un paquet qui réalise les premières tâches fastidieuses : téléchargement, mise en place des premières variables dans le fichier Makefile décrivant le paquet, création des fichiers nécessaires, et conseils quant au futur contenu de ces derniers.

On nomme un paquet Python avec le préfixe py-, le nom du paquet installé prendra le numéro de version du langage duquel il est dépendant. Par exemple, dans mon fichier /etc/mk.conf, j'ai spécifié :

PYTHON_VERSION_DEFAULT= 33

Ce qui signifie que le paquet finalement installé sera py33-httpie. Cette normalisation prend son origine dans le Makefile, initié par url2pkg, que nous allons passablement modifier :

DISTNAME= httpie-0.8.0
PKGNAME= ${PYPKGPREFIX}-${DISTNAME}
CATEGORIES= www
MASTER_SITES= https://pypi.python.org/packages/source/h/httpie/

On déclare que le paquet à télécharger est httpie-0.8.0.tar.gz, l'extension est ajoutée automatiquement et sa valeur par défaut est tar.gz ; on peut bien évidemment surcharger cette valeur à l'aide de la variable EXTRACT_SUFX. Pour un paquet standard, on se contente de spécifier le DISTNAME, PKGNAME prendra alors la même valeur. Dans le cas de paquets dont le nom du logiciel doit être modifié pour s'adapter aux standards de pkgsrc, on change la valeur de PKGNAME ; ici, on préfixe le DISTNAME avec la variable PYPKGPREFIX qui dans notre exemple prendra la valeur py33.

Il est également nécessaire, pour le le bon fonctionnement du programme, de déclarer les dépendances de ce dernier. httpie nécessite les paquets Python pygments et requests :

DEPENDS+= ${PYPKGPREFIX}-pygments>=1.6:../../textproc/py-pygments
DEPENDS+= ${PYPKGPREFIX}-requests>=2.2.0:../../devel/py-requests

Pour finir, nous déclarons à pkgsrc le type d'application Python que nous empaquetons : httpie est un programme exécutable, au contraire d'une bibliothèque et respecte le format egg, nous ajoutons donc les lignes suivantes avant l'inclusion de bsd.pkg.mk :

.include "../../lang/python/application.mk"
.include "../../lang/python/egg.mk"

Et croyez-le ou non : le paquet est pratiquement terminé ! Il suffira pour parfaire notre travail de se fendre d'une belle description dans le fichier DESCR, de s'assurer que le paquet répond aux exigences de pkgsrc à l'aide de la commande pkglint, et il ne reste plus qu'à publier.

Lorsque vous lirez ces lignes, il est fort probable que pkgsrc-2014Q3 soit disponible sous sa forme binaire, aussi il ne vous restera plus qu'à installer httpie grâce à la commande :

# pkgin in py33-httpie # ou py26, ou py27, ou py34 !

3.2 Fin de l'interlude musical

La partie backend étant en place, nous devons maintenant mettre en place le frontend, ou plus précisément la chaîne qui communiquera avec notre serveur Elasticsearch. Parce que cela m'a semblé pratique et que j'affectionne ce langage, les communications entre les processus responsables du site se font à l'aide du langage Python, qui propose tous les modules nécessaires. Dans l'ordre :

- La requête HTTP de l'utilisateur parvient sur le port 80 de Nginx,

- Ce dernier, à l'aide d'une directive proxy_pass, la transmet à gunicorn,

- gunicorn, le serveur UWSGI [13], fait appel à Flask pour traiter la requête,

- Flask est interconnecté à ElasticSearch via py-elasticsearch [14].

Une particularité de mon installation réside dans le fait que le serveur Nginx est placé sur le dom0 ; en effet, ne disposant que d'une IP publique, je redirige le trafic sur l'un ou l'autre des domU en fonction de l'hôte souhaité, par exemple ici :

server {
 server_name gcu.io www.gcu.io;
 listen 80;
 listen [::]:80;

access_log /var/log/nginx/gcuio-access.log;
 error_log /var/log/nginx/gcuio-error.log;

location / {
 proxy_pass http://gcuio:8000/;
 proxy_redirect off;
 proxy_pass_header Set-Cookie;
 proxy_cache koros;
 proxy_cache_key $scheme$host$request_method$request_uri;
 proxy_cache_valid 200 8s;
 # Serve from cache if currently refreshing
 proxy_cache_use_stale updating;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 }
}

Pour la location /, gcuio est un hôte renseigné dans le fichier /etc/hosts, on instruit Nginx d'interroger le port 8000 de la machine gcuio via le mécanisme de proxy_pass et on tire au passage profit des capacités de caching. On utilise pour ce site la technique dite de micro-caching, qui consiste à n'aller interroger le serveur réel que toutes les N secondes, ici N vaut 8.

Côté domU, nous avons installé flask et gunicorn. Ces logiciels sont tous deux disponibles dans pkgsrc sous quatre moutures différentes :

$ pkgin se 'py[0-9]+-(gunicorn|flask)$'
py34-gunicorn-18.0 Python WSGI HTTP server
py34-flask-0.10.1 Python web microframework
py33-gunicorn-18.0 Python WSGI HTTP server
py33-flask-0.10.1 Python web microframework
py27-gunicorn-18.0 Python WSGI HTTP server
py27-flask-0.10.1 Python web microframework
py26-gunicorn-18.0 Python WSGI HTTP server
py26-flask-0.10.1 Python web microframework

Ah, oui, je ne vous l'avais pas dit : pkgin permet de chercher des noms de paquets à l'aide d'expressions régulières ;) Au moment de la création du site, seul Python 3.3 était disponible, aussi me suis-je fendu des commandes suivantes :

# pkgin in py33-flask py33-gunicorn

Comme on peut s'y attendre, pkgin installera toutes les dépendances nécessaires au fonctionnement de ces deux applications. La configuration de gunicorn a le bon goût d'être elle-même en Python, son format est le suivant :

$ cat /home/gcu/etc/gunicorn.conf
import multiprocessing

gcu = "/home/gcu"

bind = ":8000"
workers = multiprocessing.cpu_count() * 2 + 1
daemon = True
pidfile = "{0}/run/gcuio.pid".format(gcu)
accesslog = "{0}/log/gcuioapp-access.log".format(gcu)
errorlog = "{0}/log/gcuioapp-error.log".format(gcu)
user = "gcu"
group = "gcu"
chdir = "{0}/gcuio/www".format(gcu)
forwarded_allow_ips = "192.168.0.254"

La documentation officielle de gunicorn suggère que le nombre de workers, ou démons en écoute, doit être égal à deux fois le nombre de cœurs plus un. Plutôt que de spécifier une valeur fixe, nous utiliserons le module multiprocessing de Python afin d'associer à cette variable une valeur dynamique.

Comme on l'aura compris, le code source, interprété par Python et Flask, se trouve dans le répertoire /home/gcu/gcuio/www, gunicorn se lancera dans le répertoire désigné par la variable chdir, puis appellera l'objet passé en ligne de commandes. On démarre gunicorn de cette façon :

$ /usr/pkg/bin/gunicorn -c /home/gcu/etc/gunicorn.conf gcu:app

De façon à s'assurer que le service soit toujours disponible, nous installons l'utilitaire monit [15], un petit logiciel capable de monitorer le bon fonctionnement d'une application, capable d'exécuter des scripts pour redémarrer ce dernier. Il faudra se fendre d'un minuscule script de la forme suivante (dans gcu/bin/gcuio) :

#!/bin/sh

gcu="/home/gcu"
pidfile="${gcu}/run/gcuio.pid"

case $1 in
 start)
 /usr/pkg/bin/gunicorn -c ${gcu}/etc/gunicorn.conf gcu:app
 ;;
 stop)
 kill `cat ${pidfile}`
 ;;
 reload)
 kill -HUP `cat ${pidfile}`
 ;;
 *)
 echo "Usage: ${0} {start|stop}"
 ;;
esac
exit 0

Un élément important à remarquer : l'appel à l'interpréteur bash est totalement proscrit ! NetBSD, système d'exploitation pour lequel la portabilité est LE leitmotiv, utilise l'interpréteur de commandes /bin/sh qui tente de se conformer le plus possible aux normes POSIX 1003.2 et 1003.2a. L'utilisateur, quant à lui, pourra utiliser le shell de son choix, ces derniers sont disposés dans pkgsrc/shells/, le changement s'effectuera à l'aide des commandes chsh(1) ou encore usermod(8) :

$ chsh

ou :

# usermod -s /usr/pkg/bin/bash utilisateur

Il est intéressant de noter que grâce à cet impératif, le système d'init de NetBSD a pu être adapté à plusieurs autres plateformes sans effort.

Notre script créé, nous installons monit de la façon la plus simple qui soit, puis nous nous assurons qu'il sera exécuté au démarrage de la machine :

# pkgin in monit
# cp /usr/pkg/share/examples/rc.d/monit /etc/rc.d/monit
# echo "monit=YES" >> /etc/rc.conf

Comme tous les fichiers de configuration des paquets tiers, la configuration du logiciel monit se situe dans le répertoire /usr/pkg/etc, plus particulièrement dans /usr/pkg/etc/monit. Un fichier monitrc minimal ressemble à ceci :

set daemon 60 # on verifie les services toutes les 60 secondes
set logfile /var/log/monit.log
set mailserver smtp.monserveur.com
set mail-format { from: monit@monserveur.com }
set alert user@monserveur.com # recevra toutes les alertes
set httpd port 2812 and # port de l'interface HTTP
 use address 0.0.0.0
 allow 0.0.0.0/0.0.0.0
 allow admin:MotDePasseBalaise
 allow @monit
 allow @users readonly

include /usr/pkg/etc/monit/monit.d/*

C'est cette dernière ligne qui nous intéresse au plus haut point : les fichiers présents dans le répertoire /usr/pkg/etc/monit/monit.d seront inclus et interprétés comme composants du fichier de configuration original, c'est là que nous poserons notre check relatif à gunicorn :

check process gcuio with pidfile /home/gcu/run/gcuio.pid
 start program = "/home/gcu/bin/gcuio start"
 stop program = "/home/gcu/bin/gcuio stop"

Ici, bien évidemment, /home/gcu/bin/gcuio est le script écrit précédemment. Il ne reste plus qu'à démarrer le service monit et attendre que ce dernier démarre gunicorn :

# /etc/rc.d/monit start

Dès lors, sur moins de 5 Go, nous disposons d'un serveur d'applications moderne, tolérant aux pannes, connecté à une base Elasticsearch, totalement modulable et montant à l'échelle de façon quasiment automatique.

4. Peaufinage

Pour parfaire notre domU, assurons-nous qu'il est correctement monitoré, et qu'en cas de danger, ce dernier puisse envoyer un e-mail à l'administrateur.

La gestion des paquets n'ayant plus de secret pour vous, vous savez désormais que vous pouvez rechercher l'outil qui vous sied à l'aide des commandes pkgin si vous travaillez essentiellement sur des paquets binaires, ou pkgfind si vous disposez de l'arbre pkgsrc. Une recherche rapide avec le terme « monitor » nous indique que, comme on pouvait s'y attendre, l'ancestral nagios fait bien entendu partie des paquets disponibles. Comme à l'accoutumée, nous installons le paquet :

# pkgin in nagios-nrpe

Nous modifions ensuite sa configuration, localisée dans le fichier /usr/pkg/etc/nagios/nrpe.cfg. nrpe est un service, il doit être démarré par init avec les autres démons désignés, on copie donc le fichier /usr/pkg/share/examples/rc.d/nrpe dans /etc/rc.d et on ajoute au fichier /etc/rc.conf la ligne :

nrpe=YES

On installera de la même façon le logiciel de visualisation de ressources, munin. Le processus et les chemins sont identiques, mais munin se décline en mode client et serveur ; aussi, le mot-clé identifiant son démarrage n'est pas simplement munin, mais munin_node. Comment savoir cela ? Rien de plus simple, le script de démarrage d'un outil contrôlé par /etc/rc.conf expose de façon évidente le nom de variable du service :

$ grep ^name= /etc/rc.d/munin-node
name="munin_node"

Il faudra donc ajouter au fichier /etc/rc.conf la ligne :

munin_node=YES

Pour finir, notre serveur d'applications devra être en mesure d'envoyer des e-mails, entre autres pour communiquer en cas de panne, ou encore pour diffuser l'état de retour de possibles tâches planifiées. Par défaut, le système NetBSD est livré avec le MTA Postfix, et sauf si vous souhaitez remplacer ce dernier par un autre MTA, il est inutile d'installer un quelconque paquet supplémentaire.

Si toutefois l'utilisation de Postfix ne vous convenait pas, les serveurs Sendmail, Qmail, Exim ou encore OpenSMTPd sont disponibles sous forme de paquets, il vous suffira alors de modifier le fichier /etc/mailer.conf afin d'y remplacer le chemin des différents outils par ceux proposés par le mailer de votre choix. Par exemple, à l'issue de l'installation du serveur Sendmail, le fichier /etc/mailer.conf aura cette forme :

sendmail /usr/pkg/libexec/sendmail/sendmail
send-mail /usr/pkg/libexec/sendmail/sendmail
mailq /usr/pkg/libexec/sendmail/sendmail
newaliases /usr/pkg/libexec/sendmail/sendmail
hoststat /usr/pkg/libexec/sendmail/sendmail
purgestat /usr/pkg/libexec/sendmail/sendmail

Aucune modification profonde ne sera nécessaire si vous choisissez le serveur Postfix livré par défaut. Pour invoquer Postfix au démarrage de votre machine, ajoutez simplement la ligne suivante au fichier /etc/rc.conf en ayant préalablement correctement configuré /etc/postfix/main.cf :

postfix=YES

Le plus souvent, pour un serveur basique, les valeurs par défaut sont fonctionnelles ; il sera toutefois judicieux de vérifier les valeurs de myhostname et mynetworks. Et puisqu'on parle des services disponibles par défaut, ajoutons que sans aucun paquet tierce partie, NetBSD peut également servir de serveur DNS, DHCP, NFS, Syslog, FTP, HTTP basique et j'en passe...

Conclusion

Nous avons exploré dans ce tour d'horizon une seule facette du système d'exploitation NetBSD, mais j'utilise cet OS pour mes besoins personnels dans bien d'autres contextes ; en effet, NetBSD revêt parfaitement bien le rôle de passerelle grâce au pare-feu pf(4), donne des résultats épatants comme serveur NAMP (NetBSD Apache MySQL PHP) ou encore 3NMP [16], et se transforme aisément en point d'accès Wi-Fi grâce au démon hostapd(8). Le système est sûr et stable, mais paradoxalement, alors que ses fondateurs ont posé les bases de la collaboration sur un Logiciel Libre d'envergure, il fait aujourd'hui figure de challenger. La communauté du projet NetBSD est vivante et accueillante, et vous trouverez dans son émanation francophone bon nombre de commiters prompts à vous mettre le pied à l'étrier. Aussi, n'hésitez pas à nous rendre visite sur le canal #NetBSDfr / freenode afin de découvrir d'autres facettes de l'UNIX Libre originel ;)

Références

[1] Le groupe de recherche CSRG : http://en.wikipedia.org/wiki/Computer_Systems_Research_Group

[2] Le démon init :http://fr.wikipedia.org/wiki/Init

[3] Le gestionnaire de paquets pkgsrc : http://www.pkgsrc.org/

[4] Interview de Alistair G. Crooks : http://www.netbsd.org/gallery/10years.html#alcrooks

[5] Le gestionnaire de paquets pkgin :http://pkgin.net/

[6] Activité du canal IRC du groupe GCU-Squad! : http://gcu.io/

[7] Site du groupe GCU-Squad! : http://gcu.info/

[8] Site officiel de Elasticsearch : http://www.elasticsearch.org/

[9] Site officiel de Gunicorn : http://gunicorn.org/

[10] Site officiel de Flask : http://flask.pocoo.org/

[11] Architecture REST : http://fr.wikipedia.org/wiki/Representational_State_Transfer

[12] Dépôt du projet HTTPie : https://github.com/jakubroztocil/httpie

[13] WSGI : http://fr.wikipedia.org/wiki/Web_Server_Gateway_Interface

[14] Client Python pour Elasticsearch : http://www.elasticsearch.org/guide/en/elasticsearch/client/python-api/current/

[15] Site officiel du projet Monit : http://mmonit.com/monit/

[16] Heitor E., « NetBSD + Nginx + Naxsi + MySQL + PHP == 3NMP », GNU/Linux Magazine n°159, avril 2013.




Articles qui pourraient vous intéresser...

Automatiser intégralement la mise en place de Wildfly avec Ansible

Magazine
Marque
Linux Pratique
HS n°
Numéro
49
Mois de parution
novembre 2020
Domaines
Résumé

Si les outils comme Ansible permettent d’aller très loin dans l’automatisation d’un déploiement logiciel, ils sont souvent limités dans leurs capacités de réglage fin d’un outil aussi complexe et avancé qu’un serveur Java EE tel que Wildfly (ou son pendant commercial, JBoss EAP). Afin de résoudre cette problématique, l’outil JCliff a été développé pour permettre à Puppet (un concurrent d’Ansible) de s’intégrer sans difficulté avec ce serveur applicatif. Cet outil est maintenant aussi intégré avec Ansible sous la forme d’une collection et cet article propose un tour exhaustif des capacités d’automatisation du déploiement et de la configuration des sous-systèmes de Wildfly à l’aide de cette nouvelle extension.

Recherchez efficacement des fichiers ou du texte avec find et grep

Magazine
Marque
Linux Pratique
HS n°
Numéro
49
Mois de parution
novembre 2020
Domaines
Résumé

Dans la vie de tous les jours, lorsque l'on perd un objet, on se retrouve la plupart du temps seul face à sa mémoire, sans personne pour vous indiquer où vous avez bien pu poser ces #$*!@& de clés ! Sous Linux, il existe des outils bien pratiques qui vous permettront de gagner un temps appréciable...

Installer et administrer un serveur d’impression CUPS

Magazine
Marque
Linux Pratique
Numéro
122
Mois de parution
novembre 2020
Domaines
Résumé

Lorsqu’on travaille sur un réseau ou en local, il est très pratique de pouvoir imprimer depuis son poste de travail en toute transparence. Qu’une imprimante soit directement connectée à un ordinateur ou bien soit partagée par un serveur dédié, l’utilisateur doit en effet être en mesure d’envoyer ses documents dans une file d’attente (spooler) qui sera en charge de traiter les impressions. Par le passé, c’était le serveur LPRng (via LPD) qui monopolisait l’impression sur les systèmes de type Unix. Mais l’arrivée de CUPS a changé la donne.