nyroBlog
Ban NyroBlog, by Nyro
Image by Nyro - ?

Tag: Sécurité


Base de données : MySQL (Serveur Web sur Debian Squeeze)

Cette partie n'a pas évolué depuis Lenny. C'est exactement la même procédure.

On installe le serveur :

aptitude install mysql-server

Durant l'installation, il vous sera demandé le mot de passe de l'utilisateur MySQL root.

MySQL vient avec une commande sympathique qui permet de sécurisé le serveur :

mysql_secure_installation
# Current password : VOTRE_MOT_PASSE
# set new password : N
# remove anonymous Users : Y
# Disallow root login remotley : Y
# remove test database and access to it : Y
# reload privileges table now : Y

Si vous utilisez InnoDB comme moteur de stockage de vos tables, l'ensemble des données de chaque table est stockée dans un seul et même fichier pour toutes les tables InnoDB de toutes les bases de données. Cela peut vous embetter, et dans certains cas, causer des lenteurs du serveur. Il est possible de paramétrer MySQL pour créer un fichier de stockage par table. Nous allons aussi optimiser un chouilla la taille des caches. Pour ce faire, on édite le fichier /etc/mysql/my.cnf pour y ajouter dans la section [mysqld] :

innodb_file_per_table=1
innodb_buffer_pool_size=64M
tmp_table_size=32M
table_cache=128


On déplace les fichiers de la base de données dans /home/var en prenant soin d'arrêter le serveur avant : 

/etc/init.d/mysql stop
mv /var/lib/mysql /home/var/
ln -s /home/var/mysql/ /var/lib/mysql
chown mysql:mysql /home/var/mysql
/etc/init.d/mysql start

 

Nous voilà prêt pour installer le serveur DNS.

 

Retour au sommaire du tutorial complet.

nyroFwk, Framework PHP - Présentation

Ceci est un brouillon d'introducion à la documentation de nyroFwk. Toutes remarques, suggestions ou questions pour l'améliorer est la bienvenue !

Vendredi dernier, j'ai mis en ligne l'API et le svn (user : anon / passe : anon) de nyroFwk.

Bon c'est très bien tout ça, mais qu'est-ce que c'est ?

Pour commencer, petit extrai de wikipedia : Un framework est un kit de composants logiciels structurels, qui définissent les fondations ainsi que les grandes lignes de l'organisation de tout ou partie d'un logiciel.

Oui, mais des frameworks PHP, il en existe des tas, non ?
Oui, on peut signaler symfony, Zend Framework et CakePHP ici. J'ai testé ces 3 là plus ou moins fortement. Chacun a ses avantages et ses inconvénients. Mais aucun ne répondait exactement à mes besoins et habitudes de développements. Alors quand quelque chose ne me convient pas, moi, je le refais, tout simplement (comme nyroModal par exemple)

Alors qu'est-ce que je n'aime pas ou j'aime dans ces frameworks ?
  • CakePHP : la gestion des bases de données et des objets associés. A l'époque où j'avais testé, on était obligé de modifier les objets lorsqu'on avait des relations entre différents objets. Et puis je n'ai jamais réussi a vraiment faire quelque chose de bien avec. Pas forcément réellement tout testé non plus, je dois bien l'avouer. Là où CakePHP marque des points, c'est dans la génération automatique de l'administration et toutes les fonctionnalités ajax super simple à implémenter.
  • Zend Framework : Je ne l'ai jamais concrètement utilisé car il me paraissait trop énorme. Ce framework a absolument tout ce dont on peut rêver. L'organisation des fichiers, de la documentation et de tout ce qui va autour de ce framework est géniale.
  • Symfony : c'est celui que j'ai le plus utilisé (et que j'utilsie encore). J'aime bien la génération automatique des objets de base de données, même si je trouve cela dommage de devoir regénérer ça à chaque modification de la base de donnée. J'aime pas le grand nombre de fichiers de configuration et encore moins tous les différents formats possibles. Pourquoi s'embetter et donc ralentire le processus avec des fichiers YAML alors qu'un simple tableau PHP fait très bien l'affaire ? La barre de débuggage peut être très utile. La séparation des classes de chaque controller pose problèmes ; dans certains cas, on est obligé de réécrire le code...
Et puis il y a plein d'autres choses qui ne sont pas dans ces frameworks, comme :
  • Gestion simple de formulaire permettant d'ajouter des champs, de vérifier s'il est valide, de le remplir, de récupérer les valeurs, etc...
  • Intégration des règles d'opitimisations de yahoo developper simplement et de base
  • Gestion des images souples, rapide et efficace
  • Intégration d'un éditeur WYSIWYG simple
  • Gestion des fichiers envoyés par les utilsiateurs sécurisée (ie : possibilité de restreindre l'affichage de ces fichiers qu'aux utilsiateurs connectés)
  • Tout est objet
Vous l'aurez compris, ces éléments sont intégrés de base dans nyroFwk.

Dans mon framework, chaque objet a sa propre configuration, qui hérite de toutes la configuration de ses parents. Chaque configuration est définie de base par le framework mais est modifiable pour chaque site très simplement. Suivant les besoins, on peut aussi modifier la configuration de chaque classe suivant le controller (front ou admin). Prenons un exemple, plus parlant. La classe response_http_html gère tout ce qui sera envoyé au navigateur lorsque la page demandée est en HTML. Elle hérite de la classe reponse_http, qui elle hérite de la classe reponse_abstract qui hérite de object. La définition de cette classe est dans le fichier nyro/response/http/html.class.php. Sa configuration est dans le fichier nyro/response/http/html.cfg.php est conteint (extrait) :
$cfg = array(
    'meta'=>array(
        'robots'=>'index, follow',
        'description'=>'nyro project',
        'keywords'=>'nyro, project',
        'language'=>request::get('lang'),
    ),
);
On définit donc les balises meta par défaut de toutes les réponses HTML. A noter que la langue ici est dynamique sera en rapport avec la langue demandée par l'utilisateur (explications plus tard).

Cette configuration est là pour définir des éléments par défaut, mais doit bien évidemment être modifié pour chaque site. Pour ce faire, chaque site aura un dossier personnel dans lequel il doit définir ses classes propres aux sites, mais aussi toutes ces configurations. Ce dossier se nomme par défaut my dans nyroFwk et est placé juste à côté du dossier nyro.

Dans ce dossier propre à chaque site, on peut aussi redéfinir chaque classe de nyroFwk. En effet, à la demande de chaque classe, le framework va vérifier si le fichier correspondant à la classe existe dans le dossier my au bon endroit. Sinon, il cherchera dans le dossier de base du framework. Un mécanisme similaire est utilisé pour les configurations. Au lieu de remplacer la configuration, on va fusionner les configurations successives de la classe, en gardant bien sûr le plus spécifique. Par exemple, pour nyrodev.com, le fichier my/response/http/html.cfg.php ressemble à (extrait) :
$cfg = array(
    'meta'=>array(
        'title'=>'nyroDev, Analyste Développeur Web (PHP, jQuery)',
        'description'=>'Cédric Nirousset, nyroDev : Conception, Analyse et Développement de sites web (PHP, jQuery).',
    ),
);
Je redéfinis les balises meta title et description pour mon site public.

Les configurations sont un point très important pour nyroFwk. C'est pourquoi il est possible de définir encore plus finement ces configurations. Tout d'abord, on peut spécifier le controller de la configuration si on veut être plus précis. Pour mon site, l'administration porte le nom de controller 'admin' et le site public 'front' (par défaut dans nyroFwk). Pour l'administration, on n'a pas besoin des meta description par exemple. C'est la raison pour laquelle le fichier de configuration du site public ne se nomme pas comme je l'ai indiqué plus haut, mais en réalité my/response/http/html.front.cfg.php. Vous avez remarquer le front en plus qui indique que l'on veut l'affciher que pour le site public. Juste à côté, le fichier my/response/http/html.admin.cfg.php existe pour définir les éléments pour l'administration.

Avec ce système, on a déjà quelque chose de tout à fait souple. Mais ce n'est pas fini ! nyroFwk gère les sites multilangues de base. Son fonctionnement est :
  • On définit une langue par défaut
  • On définit les langues disponibles
  • Si l'URL demandé est du type : monsite.com/LANG/maPage avec LANG une langue définit, alors on passe dans la langue demandée.
Bien, et alors, le rapport avec les fichiers de configuration ? Simple, en plus de la spécification par rapport au controller, les fichiers de configuration permettent aussi de spécifier une configuration spécifique pour la langue demandée. Exemple pour mon site qui est aussi disponible en anglais, le fichier my/response/http/html.front.en.cfg.php contient :
$cfg = array(
    'meta'=>array(
        'title'=>'nyroDev, Analyst Developper Web (english) (PHP, jQuery)',
        'description'=>'Cédric Nirousset, nyroDev: Conception, Analysis and Development of websites (PHP, jQuery).',
    ),
);
Ce mécanisme est utilisé à plusieurs endroits dans nyroFwk pour définir des messages à l'utilisateurs. Et comme vous l'avez remarques, ces fichiers sont de vrais fichier PHP. Donc rien ne vous empêchera, quand vous serez plus à l'aise avec le framework, d'utiliser des classes avec des fonctions statiques pour faire d'autres choses comme par exemple utiliser la base de donnée pour modifier ces éléments...

Et n'oubliez pas : les configurations sont successives et n'écrasent pas les autres configurations, aussi bien des classes parentes, mais aussi des configurations du controller et de langue. Ainsi, pour la classe response_http_html, la configuration est le résultat de la fusion des configurations (le plus bas étant le plus prédominant) :
  1. nyro/object.cfg.php
  2. nyro/object.fr.cfg.php
  3. nyro/object.front.cfg.php
  4. nyro/object.front.fr.cfg.php
  5. my/object.cfg.php
  6. my/object.fr.cfg.php
  7. my/object.front.cfg.php
  8. my/object.front.fr.cfg.php
  9. nyro/response_abstract.cfg.php
  10. nyro/response_abstract.fr.cfg.php
  11. nyro/response_abstract.front.cfg.php
  12. nyro/response_abstract.front.fr.cfg.php
  13. my/response_abstract.cfg.php
  14. my/response_abstract.fr.cfg.php
  15. my/response_abstract.front.cfg.php
  16. my/response_abstract.front.fr.cfg.php
  17. nyro/response_http.cfg.php
  18. nyro/response_http.fr.cfg.php
  19. nyro/response_http.front.cfg.php
  20. nyro/response_http.front.fr.cfg.php
  21. my/response_http.cfg.php
  22. my/response_http.fr.cfg.php
  23. my/response_http.front.cfg.php
  24. my/response_http.front.fr.cfg.php
  25. nyro/response_http_html.cfg.php
  26. nyro/response_http_html.fr.cfg.php
  27. nyro/response_http_html.front.cfg.php
  28. nyro/response_http_html.front.fr.cfg.php
  29. my/response_http_html.cfg.php
  30. my/response_http_html.fr.cfg.php
  31. my/response_http_html.front.cfg.php
  32. my/response_http_html.front.fr.cfg.php
Bien sûr, ces fichiers ne sont utilisés que s'ils existent ! Et ceci avec n'importe quelle classe du framework.

Mais je dois créer un fichier pour chaque classe qui en a besoin ? Au début, c'était le cas oui. Mais je me suis aperçu que cela pouvoit devenir très vite long et fastidieux. Ce mécanisme existe toujours et est toujours utilisé car dans certains cas indispensable, mais il existe un autre moyen. En effet, la configuration de la classe nyro permet de modifier la configuration de n'importe quelle classe dans un seul et même fichier de configuration. Par exemple, on aurait pu définir les éléments montrés précédemment dans le fichier my/nyro.front.cfg.php de cette façon :
$cfg = array(
    'response_http_html'=>array(
        'meta'=>array(
            'title'=>'nyroDev, Analyst Developper Web (english) (PHP, jQuery)',
            'description'=>'Cédric Nirousset, nyroDev: Conception, Analysis and Development of websites (PHP, jQuery).',

        ),
    ),
'une_autre_classe'=>array(
'uneAutreConfig'=>'yeah'
),
);
Cette configuration est utilisé en dernier lieu pour créer la configuration de chaque classe.

Vous avez d'ailleurs remarqué la classe object ? Toutes les classes instanciables héritent de cette classe, ce qui permet une gestion centralisée et uniforme des configurations et de la création des objets.

Bon, voilà déjà pour la configuration.

Pour revenir sur les fonctionnalités du framework, voici une liste (sans doute non exhaustive) de ce que gère pour l'instant nyroFwk :
  • Programmation orientée objet
  • Configuration avancée et très souple des classes
  • Gestion des sites multilingues
  • Gestion des bases de données multilingues avec récupération automatique des données propre à la langue
  • Configuration de base de donénes multiples
  • Gestion des utilsiateurs et de leur connexion, vérifications des accès, etc...
  • Gestion des formulaires avancées et souples : validation, affichage, etc...
  • Manipulation des images simplement, avec souplesse et efficacement
  • Création de formulaires directement depuis la structure de la base de données (gestion des données liées et en relation)
  • Création de l'administration automatique
  • Minimisation en un seul fichier compressé des fichiers JavaScript et CSS nécessaire à la page
  • Application d'un maximum de règle d'optimisations données par Yahoo
  • Barre de débogage
  • Editeur WYSIWYG (tinyMce) très simplement intégrable
  • jQuery et jQuery UI intégré
  • Ajax ready : différents templates s'il s'agit d'une requêtes ajax
  • Extensibilité simple et accrue : tout peut être redéfini
  • etc...
Fiou, ça n'a pas été une mince affaire de rédiger tout ça... J'espère que ça vous donne déjà une meilleure idée de ce qu'est nyroFwk et que vous aurez envie d'en savoir plus...

Bilan (Serveur Web sur Debian Lenny)

Voilà, notre serveur est maintenant opérationnel en tout point.

Encore faut-il ajouter des sites internet dessus, transférer les fichiers, faire pointer les DNS dessus, etc...

Voici donc la marche à suivre pour ajouter un nouveau site sur le site :

I : Ajouter un nouvel utilisateur avec la commande :

useradd -m -g www-data DOMUSER
Comme nous avons créer le dossier www dans /etc/skel, la création de l'utilisateur va directement crée le /home de ce dernier avec le dossier pour contenir les fichiers du futur site web.

II : Ajouter le virtualhost dans Apache

Même si les DNS pointent vers notre serveur, Il n'y a encore rien qui indique que le serveur doit répondre à cette requête ; pire encore, on ne sait pas quels fichiers desservir... C'est pourquoi on ajoute dans /etc/apache2/sites-available/domain.dtd :

        ServerName domain.dtd
        ServerAlias www.domain.dtd
        DocumentRoot /home/DOMUSER/www/
       
                Options -Indexes FollowSymLinks MultiViews
                AllowOverride All
       

        ErrorLog /var/log/apache2/DOMUSER_error.log
        CustomLog /var/log/apache2/DOMUSER_access.log combined
Puis on active le site et recharges la configuration d'apache :
a2ensite domain.dtd
/etc/init.d/apache2 force-reload

III : Ajouter la base de données

Vous voudrez probablement utilisez une base de données avec votre site. Il suffit d'exécuter les commandes suivantes :
mysql --user=root --password=PASSROOT --execute="CREATE DATABASE DOMUSER;"
mysql --user=root --password=PASSROOT --execute="GRANT ALL PRIVILEGES ON DOMUSER.* TO 'DOMUSER'@'localhost' IDENTIFIED BY 'PASSDOMUSER';"
mysql --user=root --password=PASSROOT --execute="FLUSH PRIVILEGES;"
De cette façon, on crée la base de donnée MySQL DOMUSER et l'utilisateur du même nom, qui a des droits uniquement sur cette base de données.

IV : Paramétrer les DNS

Pour que tout fonctionne bien, les DNS du serveur doivent être paramétrer pour répondre aux requêtes DNS. Pour ce faire, nous allons simplement ajouter des lignes dans notre base de données serverconf crée plus tôt :
mysql --user=serverconfuser --password=serverconfpass --database=serverconf --execute="INSERT INTO domain (name) VALUES ('domain.dtd');"

# $IDDB = id du domaine dans la table domain
# $SERVERNAME = nom unique de votre serveur (ksNNNNN.kimsufi.com par exemple)
# $SECONDDNS = adresse unique du second DNS (ns6.gandi.net par exemple)
# SERVERIP = adresse IP de votre serveur

mysql --user=serverconfuser --password=serverconfpass --database=serverconf --execute="INSERT INTO domainDNS (domain_id, master) VALUES ($IDDB, 'NATIVE');"
mysql --user=serverconfuser --password=serverconfpass --database=serverconf --execute="INSERT INTO record (domain_id, name, type, content) VALUES ($IDDB, 'domain.dtd', 'SOA', '$SERVERNAME. postmaster.domain.dtd `date +%Y%m%d`01 21600 3600 604800 86400');"
mysql --user=serverconfuser --password=serverconfpass --database=serverconf --execute="INSERT INTO record (domain_id, name, type, content) VALUES ($IDDB, 'domain.dtd', 'NS', '$SERVERNAME');"
mysql --user=serverconfuser --password=serverconfpass --database=serverconf --execute="INSERT INTO record (domain_id, name, type, content) VALUES ($IDDB, 'domain.dtd', 'NS', '$SECONDDNS');"
mysql --user=serverconfuser --password=serverconfpass --database=serverconf --execute="INSERT INTO record (domain_id, name, type, content, prio) VALUES ($IDDB, 'domain.dtd', 'MX', 'mail.domain.dtd', 25);"
mysql --user=serverconfuser --password=serverconfpass --database=serverconf --execute="INSERT INTO record (domain_id, name, type, content) VALUES ($IDDB, 'domain.dtd', 'A', '$SERVERIP');"
mysql --user=serverconfuser --password=serverconfpass --database=serverconf --execute="INSERT INTO record (domain_id, name, type, content) VALUES ($IDDB, 'www.domain.dtd', 'A', '$SERVERIP');"
mysql --user=serverconfuser --password=serverconfpass --database=serverconf --execute="INSERT INTO record (domain_id, name, type, content) VALUES ($IDDB, '*.domain.dtd', 'A', '$SERVERIP');"
La dernière ligne, avec *.domain.dtd, permet de mettre en place catch-all, ce qui veut dire que n'importe quel sous-domaine de domain.dtd sera pris en compte et envoyé vers le serveur. Ceci permet la mise en place beaucoup plus simple et plus rapide pour de nouveaux sous-domaines : il n'y a pas besoin de modifier les DNS !

Et voilà, vous pouvez maintenant envoyer vos fichiers par ftp en utilisant par exemple l'adresse ftp.domain.dtd.

V : Ajouter des adresses email

Avec votre sites, vous voudrez sans doute créer des adresses emails. Tout se fait là aussi en ajoutant des lignes dans la base de données serverconf :
mysql --user=serverconfuser --password=serverconfpass --database=serverconf --execute="INSERT INTO user (domain_id, user, password) VALUES ($IDDB, 'USER', MD5('PASS'));"
On créé ici l'adresse USER@domain.dtd avec le mot de passe PASS.

VI : Ajouter des alias d'adresse email

Mais parfois, les utilisateurs préfèrent garder leurs adresses email avec un alias. Rien de plus simple :
mysql --user=serverconfuser --password=serverconfpass --database=serverconf --execute="INSERT INTO alias (domain_id, source, destination) VALUES ($IDDB, 'USER', 'redir@email.com');"
Vous devriez donc maintenant être capable les éléments de base de votre serveur. Si vous avez quelques questions, utilisez les commentaires !

Pour ma part, mon serveur tourne depuis plus d'un mois maintenant sans aucun problème particulier...

Retour au sommaire.

Autres : ntpdate, apticron, etc... (Serveur Web sur Debian Lenny)

Dans ce dernier billet, je vais recensé tout un tas de petites choses qui améliore la vie du serveur et de l'administrateur.

Tout d'abord, je vous conseille de modifier les heures d'exécution des tâches cron dans /etc/crontab pour mettre des heures de creux de votre serveur ; pensez aux graphes de munin pour définir ces heures !

Ensuite, installons de nouveaux paquets :
apt-get install screen ncftp ntpdate apticron
Screen permet de lancer un nouveau shell dans un shell courant. Si votre connexion coupe ou si vous quittez le shell, il continue à s'exécuter sur le serveur : vous pouvez ensuite le reprendre. Très utile pour des tâches qui prennent énormément de temps.
Ncftp vous permettra d'effectuer des échanges FTP directement en ligne de commande, pour des opérations de sauvegardes par exemple.

A vous de consulter les documentations de ces paquets pour comprendre comment ils fonctionnent.

Ntpdate permet de mettre à l'heure votre serveur grâce au protocole ntp. Nous allons donc créer une tâche cron pour le faire chaque jour dans /etc/cron.daily/ntpdate :
#!/bin/sh
ntpdate cdns.ovh.net
Puis les droits d'éxécution :
chmod +x /etc/cron.daily/ntpdate
Apticron va regarder les mises à jour disponible sur votre serveur avec apt, et envoyer un email de rapport si des nouvelles sont disponibles. Il suffit de paramétrer l'email d'envoi dans /etc/apticron/apticron.conf :
EMAIL="server@domain.tld"
Nous avons mis en place un serveur de mail avec un antispam. Comme la plupart des antispam, DSpam a besoin d'entrâinement pour être efficace. il existe des corpus d'email pour réaliser cet entrâinement. Comme cela peut prendre longtemps, nous utilisons screen :

screen

cd /tmp
wget http://spamassassin.apache.org/publiccorpus/20050311_spam_2.tar.bz2
wget http://spamassassin.apache.org/publiccorpus/20030228_easy_ham_2.tar.bz2
tar xvfj 20050311_spam_2.tar.bz2
tar xvfj 20030228_easy_ham_2.tar.bz2
dspam_train dspam@test.com spam_2/ easy_ham_2/
rm -r 20030228_easy_ham_2.tar.bz2  20050311_spam_2.tar.bz2 easy_ham_2  spam_2 /home/var/vmail/test.com/ /var/spool/dspam/data/* /home/var/log/dovecot-deliver.log
touch /home/var/log/dovecot-deliver.log
chmod 777 /home/var/log/dovecot-deliver.log
exit
Enfin, lorsque nous allons ajouter un site, la 1ère étape sera d'ajouter un utilisateur système sur le serveur. Il est possible de gérer les fichiers et dossier créer dans le /home d'un nouvel utilisateur en les créant dans /etc/skel. Pour nous, supprimons tous les fichiers et dossiers qui y sont, puis ajoutons le dossier www :
rm /etc/skel/.* /etc/skel/*
mkdir /etc/skel/www

Et voilà notre serveur totalement terminé et opérationnel. Place maintenant à un bilan de tout ce que nous avons.

Retour au sommaire.

Monitoring : monit, munin (Serveur Web sur Debian Lenny)

UPDATE : voir la version à jour pour Debian Squeeze pour l'installation de Munin.

UPDATE : voir la version à jour pour Debian Squeeze pour l'installation de Monit.

 

Notre serveur fonctionne bien, avec quelques bans pour différents services. Mais qu'arrive-t-il si un démon tombe en panne ? Et puis comment connait-on la charge du serveur ?
Monit va répondre à la première question en vérifiant à intervalle régulier tous les services et les redémarrer si besoin.
Munin quant à lui va créer de nombreux graphes sur le serveur pour que vous puissiez vous rendre compte de la charge qu'il encaisse.

Munin

Commençons par activer le server-status d'apache, quis era utilisé par munin pour calculé des stats de processus et requêtes d'apache. Ajouter le fichier /etc/apache2/conf.d/server-status.conf :
ExtendedStatus On


    SetHandler server-status

    Order Deny,Allow
    Deny from all
    Allow from 127.0.0.1

Puis on peut passé à l'installation (les différents paquets perl sont utilisé par munin) :

apt-get install munin munin-node libhtml-parser-perl libhtml-tagset-perl libhtml-tree-perl liburi-perl libwww-perl

On ajoute quelques plugins à munin qui ne le sont pas par défaut, en appliquant les bons droits :

ln -s /usr/share/munin/plugins/netstat /etc/munin/plugins/netstat
ln -s /usr/share/munin/plugins/postfix_mailstats /etc/munin/plugins/postfix_mailstats
ln -s /usr/share/munin/plugins/apache_accesses /etc/munin/plugins/apache_accesses
ln -s /usr/share/munin/plugins/apache_processes /etc/munin/plugins/apache_processes
ln -s /usr/share/munin/plugins/apache_volume /etc/munin/plugins/apache_volume
ln -s /usr/share/munin/plugins/uptime /etc/munin/plugins/uptime
chown munin:munin /home/var/www/munin

Avec Lenny, le plugin netstat de munin à un problème de droit. Pour le résoudre, on le paramètre pour qu'il s'éxécute en root avec :

echo "[netstat]" > /etc/munin/plugin-conf.d/netstat
echo "user root" >> /etc/munin/plugin-conf.d/netstat

Avec la configuration actuelle, munin place ces fichiers dans /home/var/www/munin. Avec notre configuration actuelle d'apache, on ne pourrait pas y accéder.
Pour plus de simplicité, on va créer un sous-domaine en accès sécurisé pour voir ses stats. On commence par créer le certificat :

openssl req -new -x509 -days 3650 -nodes -out /etc/ssl/certs/munin.crt -keyout /etc/ssl/private/munin.key

On crée ensuite le .htpasswd pour le protéger :

htpasswd -c /home/var/www/munin/.htpasswd user

Puis on configure apache pour ce sous-domaine dans /etc/apache/sites-available/munin.domain.tld :


    ServerName munin.domain.tld

    # Activation du support SSL
    GnuTLSEnable on
    GnuTLSPriorities NORMAL
    GnuTLSCertificateFile /etc/ssl/certs/munin.crt
    GnuTLSKeyFile /etc/ssl/private/munin.key

   
        AuthUserFile /home/var/www/munin/.htpasswd
        AuthGroupFile /dev/null
        AuthName "Restricted Area"
        AuthType Basic
       
            require valid-user
       
   

    DocumentRoot /home/var/www/munin
    ErrorLog /var/log/apache2/munin_error.log
    CustomLog /var/log/apache2/munin_access.log combined

On active ce site pour apache, et on redémarre les services :

a2ensite munin.domain.tld
/etc/init.d/munin-node force-reload
/etc/init.d/apache2 force-reload

Monit

Monit va nous permettre de vérifier l'état des démons et d'effectuer les opérations nécessaires à son bon fonctionnement, tout en alertant l'administrateur. Dans la plupart des cas, un simple redémarrage sera effectué et tout ira bien.

On l'installe simplement :

apt-get install monit

On conserve la configuration par défaut :

mv /etc/monit/monitrc /etc/monit/monitrc_default

Pui on configure dans /etc/monit/monitrc :

set daemon  600
set logfile syslog facility log_daemon
set mailserver localhost
set mail-format {
        from: me@domain.tld
        subject: [monit] $SERVICE: $EVENT
}
set eventqueue basedir /home/var/monit slots 100
set alert server@domain.tld
set httpd port 9999 and
        allow user:pass

include /etc/monit/conf.d/*

On le configure avec une interface web accessible sur le port 9999 avec comme nom d'utilisateur user et mot de passe pass. S'il s'avère que l'envoi de mail échoue, monit conservera les messages dans /home/var/monit pour les renvoyer dès que possible. La fréquence des tests est toutes les 10 minutes.

Puis, nous allons devoir configurer chacun des démons que l'on veut monitorer. La plupart du temps il s'agira d'un pid et des commandes de démarrage et d'arrêt du démon. Si le pid change entre 2 tests, monit enverra simplement un email.

mkdir /etc/monit/conf.d

Dans /etc/monit/conf.d/apache :

check process apache with pidfile /var/run/apache2.pid
    group www
    start program = "/etc/init.d/apache2 start"
    stop program  = "/etc/init.d/apache2 stop"
    if cpu > 60% for 2 cycles then alert
    if cpu > 90% for 5 cycles then restart
    if totalmem > 500 MB for 5 cycles then restart
    if children > 250 then restart
    if loadavg(5min) greater than 10 for 8 cycles then stop
    if 3 restarts within 5 cycles then timeout

Le fichier de config le plus compliqué, il permet de redémarrer apache s'il prend trop de place en mémoire ou s'il a trop de processus enfant.

Dans /etc/monit/conf.d/clamav :

check process clamav with pidfile /var/run/clamav/clamd.pid
    group virus
    start program = "/etc/init.d/clamav-daemon start"
    stop  program = "/etc/init.d/clamav-daemon stop"
    if failed host localhost port 3310 then restart
    if 5 restarts within 5 cycles then timeout

check process freshclam with pidfile /var/run/clamav/freshclam.pid
    group virus
    start program = "/etc/init.d/clamav-freshclam start"
    stop  program = "/etc/init.d/clamav-freshclam stop"
    if 5 restarts within 5 cycles then timeout

Dans /etc/monit/conf.d/cron :

check process cron with pidfile /var/run/crond.pid
    group system
    start program = "/etc/init.d/cron start"
    stop  program = "/etc/init.d/cron stop"
    if 5 restarts within 5 cycles then timeout

Dans /etc/monit/conf.d/dovecot :

check process dovecot with pidfile /var/run/dovecot/master.pid
    group mail
    start program = "/etc/init.d/dovecot start"
    stop  program = "/etc/init.d/dovecot stop"
    if failed host localhost port 993 type tcpssl sslauto protocol imap then restart
    if failed host localhost port 995 type tcpssl sslauto protocol pop then restart
    if failed host localhost port 143 protocol imap then restart
    if failed host localhost port 110 protocol pop then restart
    if 5 restarts within 5 cycles then timeout

Dans /etc/monit/conf.d/dspam :

check process dspam with pidfile /var/run/dspam/dspam.pid
    group mail
    start program = "/etc/init.d/dspam start"
    stop program = "/etc/init.d/dspam stop"
    if 5 restarts within 5 cycles then timeout

Dans /etc/monit/conf.d/fail2ban :

check process fail2ban with pidfile /var/run/fail2ban/fail2ban.pid
    start program = "/etc/init.d/fail2ban start"
    stop  program = "/etc/init.d/fail2ban stop"
    if failed unixsocket /var/run/fail2ban/fail2ban.sock then restart
    if 5 restarts within 5 cycles then timeout

Dans /etc/monit/conf.d/munin :

check process munin-node with pidfile /var/run/munin/munin-node.pid
    group system
    start program = "/etc/init.d/munin-node start"
    stop program  = "/etc/init.d/munin-node stop"
    if failed host localhost port 4949 then restart
    if 5 restarts within 5 cycles then timeout

Dans /etc/monit/conf.d/mysql :

check process mysql with pidfile /var/run/mysqld/mysqld.pid
    group database
    start program = "/etc/init.d/mysql start"
    stop program = "/etc/init.d/mysql stop"
    if failed unix "/var/run/mysqld/mysqld.sock" then restart
    if failed host 127.0.0.1 port 3306 then restart
    if 5 restarts within 5 cycles then timeout

Dans /etc/monit/conf.d/postfix :

check process postfix with pidfile /var/spool/postfix/pid/master.pid
    group mail
    start program = "/etc/init.d/postfix start"
    stop  program = "/etc/init.d/postfix stop"
    if failed port 25 protocol smtp for 2 times within 2 cycles then restart
    if failed port 465 protocol smtp for 2 times within 2 cycles then restart
    if failed port 10026 protocol smtp for 2 times within 2 cycles then restart
    if 5 restarts within 5 cycles then timeout

Dans /etc/monit/conf.d/powerdns :

check process powerdns with pidfile /var/run/pdns.pid
    start program = "/etc/init.d/pdns start"
    stop program = "/etc/init.d/pdns stop"
    if failed host localhost port 53 then restart
    if 5 restarts within 5 cycles then timeout

check process powerdns-recursor with pidfile /var/run/pdns_recursor.pid
    start program = "/etc/init.d/pdns-recursor start"
    stop program = "/etc/init.d/pdns-recursor stop"
    if failed host localhost port 54 then restart
    if 5 restarts within 5 cycles then timeout

Dans /etc/monit/conf.d/rsyslog :

check process rsyslogd with pidfile /var/run/rsyslogd.pid
    group system
    start program = "/etc/init.d/rsyslog start"
    stop  program = "/etc/init.d/rsyslog stop"
    if 5 restarts within 5 cycles then timeout

Dans /etc/monit/conf.d/sshd :

check process sshd with pidfile /var/run/sshd.pid
    start program  "/etc/init.d/ssh start"
    stop program  "/etc/init.d/ssh stop"
    if failed port 22 protocol ssh then restart
    if 5 restarts within 5 cycles then timeout

Dans /etc/monit/conf.d/vsftpd :

check process vsftpd with pidfile /var/run/vsftpd/vsftpd.pid
    start program = "/etc/init.d/vsftpd start"
    stop program  = "/etc/init.d/vsftpd stop"
    if failed port 21 protocol ftp then restart
    if 5 restarts within 5 cycles then timeout

Enfin, nous devons activé monit dans /etc/default/monit :

startup=1
CHECK_INTERVALS=600

Et on redémarre le démon pour que le monitoring démarre :

/etc/init.d/monit force-reload

Le serveur est tout à fait opérationnel maintenant ! Il ne reste plus qu'un tout petit peu d'éléments à mettre en place.

Retour au sommaire.