Elasticsearch: monitoring d’unicité d’aliases

Le moteur de recherche Elasticsearch permet d'utiliser des aliases afin de faire référence à des indexes existants. Cela permet notamment d'ajouter des indexes Elasticsearch différents des indexes en cours et de pouvoir changer rapidement à chaud d'index sans interruption de service.

Exemple d'architecture

Notre application appèle l'index fruit. Grâce à l'alias, on pointe sur la version du 3 août. Nous effectuons une réindexation à chaud mais créons l'alias fruit_20150806, correspondant à la date du jourELS-Alias-BeginA la fin de notre processus, nous pouvons demander à Elasticsearch de migrer cet alias sur le nouvel index

ELS-Alias-EndDans certains processus de mises à jour automatiques il peut être intéressant de vérifier qu'il n'y a pas eu d'échec de suppression de l'ancien alias. Celui-ci peut causer un doublon pouvant poser de gros soucis.

Je vous propose la sonde en python suivante permettant de lister les indexes Elasticsearch présents sur votre cluster et vérifiant qu'ils sont bien uniques. Elle est sous licence BSD 2 clauses

#! /usr/bin/python

import getopt, sys, json
import urllib2

PROG_NAME = "check_els_indexes"

def doELSVerification(url):
        req = urllib2.Request(url)
        response = urllib2.urlopen(req)
        jsonresp = json.loads(response.read())

        # Count all elasticsearch server aliases
        elsAliases = {}
        for index in jsonresp:
            if "aliases" in jsonresp[index]:
                for idx in jsonresp[index]["aliases"]:
                    elsAliases["%s" % idx] = elsAliases["%s" % idx] + 1 if idx in elsAliases else 1

        # Filter aliases to show only problematic aliases
        filteredAliases = []
        for alias in elsAliases:
            if elsAliases[alias] > 1:
                filteredAliases += ["%s (%d occurences)" % (alias, elsAliases[alias]), ]

        # Do error message
        if len(filteredAliases) > 0:
            print "Some aliases are duplicated: %s" % ", ".join(filteredAliases)
            return 2
        else:
            print "No duplicate alias occurence found"
            return 0

if __name__ == "__main__":
    try:
        host = None
        port = None
        index = None
        opts, args = getopt.getopt(sys.argv[1:], "h:p:", ["host=", "port="])
        for o, a in opts:
            if o in ("-h", "--host"):
                host = a
            elif o in ("-p", "--port"):
                port = a
    except getopt.GetoptError:
        print "Invalid options passed to %s" % PROG_NAME
        sys.exit(3)

    if host == None:
        print "No option --host given for %s, aborting" % PROG_NAME
        sys.exit(3)

    if port == None:
        print "No option --port given for %s, aborting" % PROG_NAME
        sys.exit(3)

    els_alias_url = "http://%s:%s/_alias/*" % (host, port)

    elsStatus = doELSVerification(els_alias_url)
    sys.exit(elsStatus)

Vous pourrez la retrouver sur github ici.

Relai DHCP sous Debian

Le relai DHCP permet d'isoler son serveur DHCP autoritaire du réseau de ses clients.

Que le serveur DHCP soit sous UNIX ou sur un OS propriétaire (ce qui est dommage), le relai DHCP va permettre aux clients d'interroger un DHCP en utilisant ce relai comme proxy.

Un relai DHCP est un outil très simple utilisant un système ajoutant le réseau source (connu par le relai DHCP) et un nombre de sauts (utile si vous souhaitez chaîner plusieurs relais DHCP, mais non recommandé en terme de latence).

Installation

Installez le paquet isc-dhcp-relay.

apt-get install isc-dhcp-relay

Configuration

Bien que le prompt isc-dhcp-relay vous offre la possibilité de configurer directement le service, nous allons le configurer manuellement. Ouvrez le fichier /etc/default/isc-dhcp-relay

Editez ensuite la ligne SERVERS afin d'ajouter une liste de serveurs DHCP autoritaires et la ligne INTERFACES afin de spécifier les interfaces sur lesquelles votre DHCP va écouter.

SERVERS="10.1.1.1 10.1.1.2"
INTERFACES="eth0 eth1 eth45 vlan5 bond0"

Relancez ensuite le service isc-dhcp-relay

service isc-dhcp-relay restart

Postfix: blacklist unix-experience

Hello,

Suite à l'augmentation du SPAM dans ma boîte mail, malgré un spamassassin correctement configuré et à jour, du DKIM, du SPF, des vérifications de domaine strictes, etc... le SPAM arrive régulièrement à passer mes filtres standard. J'ai donc commencé à constituer une blacklist des domaines venant polluer mes domaines.

Pourquoi consistuer ma propre blacklist et non utiliser une existante ? Effectivement il serait possible d'utiliser RBL ou une blacklist fournie par une ensemble d'utilisateurs "certifiés", le problème c'est que ce genre de blacklist contient parfois des faux-positifs, que ce soit parce que les domaines ont été émetteurs de SPAM à cause d'une erreur de configuration de la part de l'équipe système ou parce qu'il se sont fait pirater des postes. J'ai préféré repartir de zéro et monter ma propre blacklist, ne recevant pas non plus 500 mails de spam par jour sur mes MX mais plutôt une dizaine grand maximum, ce qui se traite assez facilement.

Je vous proposer donc ci-joint une blacklist non exhaustive de quelques émetteurs de SPAM un peu gênants, qui plus est, directement utilisable avec une postmap postfix

Postfix & OpenDKIM: authentification du domaine émetteur de mails

Le protocole DKIM permet d'authentifier le serveur d'envoi SMTP auprès de différents pairs externes, ainsi que la provenance d'un mail.

Il s'appuie sur un enregistrement DNS de type TXT et deux en-têtes mail:

  • L'enregistrement DNS contient un ensemble d'options DKIM, dont la clef publique du serveur SMTP.
  • L'en-tête DKIM-signature authentifie le mail en lui attribuant une signature et un timestamp
  • L'en-tête DKIM Authentication-Result contient le résultat de la vérification DKIM

OpenDKIM est un démon écrit en C qui s'interface avec les MTAs courants (Postfix, sendmail...). Il offre la possibilité de signer les mails relayés mais également de s'assurer de l'authentification des domaines distants, si ceux-ci l'offrent.

Installation

Nous installerons OpenDKIM sur un serveur FreeBSD 9.3.

Pour les utilisateurs de Linux/Debian voici les paquets à installer:

apt-get install opendkim opendkim-tools

Voici les options que nous avons mis sur notre Poudriere (port mail/opendkim)

opendkim-optionsIl y a ici quelques options intéressantes:

  • query_cache: cela permet d'optimiser le temps de réponse si votre serveur reçoit beaucoup de mail en mettant en cache les réponses DNS des enregistrement TXT consultés pour l'authentification
  • stock_resolver: cela permet d'utiliser le résolveur DNS système au lieux d'utiliser la librairie unbound.

Préparation d'OpenDKIM

Afin de configurer proprement OpenDKIM nous allons créer un répertoire qui permettra de sécuriser une partie des configurations et lui indiquer des droits

mkdir /usr/local/etc/mail/opendkim.d
chmod 700 /usr/local/etc/mail/opendkim.d
touch /usr/local/etc/mail/opendkim.d/InternalHosts
touch /usr/local/etc/mail/opendkim.d/KeyTable
touch /usr/local/etc/mail/opendkim.d/SigningTable
touch /usr/local/etc/mail/opendkim.d/ExternalIgnoreList
chmod 600 /usr/local/etc/mail/opendkim.d/{InternalHosts,KeyTable,SigningTable,ExternalIgnoreList}
chown -R mailnull /usr/local/etc/mail/opendkim.d/

Configuration d'OpenDKIM

Dans un premier temps nous allons modifier la configuration globale d'OpenDKIM afin d'offrir de la scalabilité au démon. Ouvrez le fichier /usr/local/etc/mail/opendkim.conf (/etc/opendkim.conf pour Debian) Dans un premier temps nous allons modifier les options système d'OpenDKIM.

AutoRestart Yes
DNSTimeout 5
Syslog Yes
Socket inet:10025@127.0.0.1
QueryCache Yes
Selector default
  • AutoRestart: OpenDKIM redémarrera les filtres qui planteraient
  • DNSTimeout: modifiez cette valeur si votre DNS répond très rapidement afin qu'une requête DNS en attente ne pénalise pas le temps de traitement du démon
  • Syslog: activez les logs dans le syslog
  • Socket: on demande ici au milter OpenDKIM d'écouter sur le port 10025 de l'interface de loopack afin que Postfix puisse l'interroger
  • QueryCache: active le cache des enregistrements DNS DKIM, évitant d'interroger plusieurs fois les DNS pour le même nom de domaine si le TTL n'a pas expiré
  • Selector: le sélecteur a utiliser par défaut pour signer les mails. Il ne sera pas utilisé dans notre configuration mais il faut quand même décommenter la ligne

Configuration des signatures et clefs

Toujours dans le fichier opendkim.conf, modifiez les lignes suivantes:

ExternalIgnoreList     refile:/usr/local/etc/mail/opendkim.d/ExternalIgnoreList
InternalHosts           refile:/usr/local/etc/mail/opendkim.d/InternalHosts
KeyTable                 refile:/usr/local/etc/mail/opendkim.d/KeyTable
SigningTable            refile:/usr/local/etc/mail/opendkim.d/SigningTable

Chaque fichier a un rôle bien précis:

  • ExternalIgnoreList: il s'agit des noms de domaine que vous ne souhaitez pas vérifier
  • InternalHosts: Les hôtes qui seront signés par OpenDKIM
  • KeyTable: La définition des associations domaine/sélecteur DKIM/clef privée
  • SigningTable: La définition des adresses mails et leurs clefs de signatures associées

Dans un premier temps nous allons créer une clef privée pour notre domaine

opendkim-genkey -b 1024 -d unix-experience.fr -s unixselector

Les options présentées ici sont les suivantes:

  • -b: longueur de la clef privée
  • -d: nom de domaine à signer
  • -s: nom du sélecteur que l'on souhaite créer (par défaut, default)

Cette commande a généré une clef de 1024 bits pour le domaine unix-experience.fr et le sélecteur unixselector. Vous trouverez la clef privée au même endroit dans unixselector.private et l'enregistrement DNS au format named dans le fichier unixselector.txt. Note: si vous souhaitez dire aux vérificateurs DKIM que vous êtes en période de tests et qu'il ne faut pas réagir tout de suite aux négatifs, rajoutez t=y; dans l'enregistrement TXT. Configurez la liste des hôtes qui devront être signés en indiquant des hôtes, réseaux, noms de domaine dans le fichier InternalHosts (un par ligne), puis la définition de notre clef de signature en éditant le fichier KeyTable.

unixkey unix-experience.fr:unixselector:/usr/local/etc/mail/opendkim.d/unixselector.private

Le premier champ est un champ administratif donnant un nom à notre association domaine/sélecteur/clef. Les suivants sont le nom de domaine, le nom du sélecteur et enfin le chemin vers la clef privée. Pour finir ouvrez le fichier SigningTable et ajoutez l'entrée suivante:

*@unix-experience.fr unixkey

Cette dernière définition dira a OpenDKIM d'utiliser les données de la clef d'identifiant unixkey pour signer toutes les adresses en @unix-experience.fr. La configuration est désormais terminée, vous pouvez lancer le service

service milter-opendkim start

Intégration Postfix

Il faut maintenant intégrer le milter avec Postfix. Nous utiliserons donc un milter. Dans le fichier main.cf de Postfix, ajoutez les lignes suivantes:

milter_default_action = accept
milter_protocol = 6
smtpd_milters = inet:127.0.0.1:10025
non_smtpd_milters = inet:127.0.0.1:10025

Si vous avez déjà déclaré des milters, il suffira d'ajouter OpenDKIM à la liste:

smtpd_milters = inet:127.0.0.1:9999, inet:127.0.0.1:10025
non_smtpd_milters = inet:127.0.0.1:9999, inet:127.0.0.1:10025

Redémarrez ensuite Postfix

Test du fonctionnement du mode vérification

Pour tester le fonctionnement du mode vérification, il suffit de recevoir un mail depuis un domaine qui utilise DKIM, comme twitter ou gmail (depuis l'interface web). Regardez ensuite les logs de votre serveur mail (maillog) et l'en-tête du mail reçu:

Authentication-results: smtp.unix-experience.fr; dkim=pass reason="2048-bit key" header.d=twitter.com header.i=@twitter.com header.b=olq1OOXA; dkim-adsp=pass

En ce qui concerne la signature, envoyez simplement un mail vers l'extérieur, OpenDKIM dira dans les logs qu'il l'a signé. Sur le récepteur vérifier que l'en-tête DKIM-signature est présent.

Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=twitter.com; s=dkim-201406; t=1207824973; bh=EUbu+JkDns2Bi4JPLANga1BmZxXRVX4W9RvqRWa1Dss=; h=Date:From:To:Subject:MIME-Version:Content-Type:List-Unsubscribe: Feedback-ID:Message-ID; b=ZMpJ9qh/SYhUzQ9wOovUugK56y1vJ0af/ZbMc4zm/IJrPKiMjqPmbTZ0RqT5aN9PN b98bnb8VI1NjL5ry6uJBAMEzWyLud0Fj6KFV1KPkwxqPrwioJsv/4BDE5o8lGRu//+ 9sSlIcHdHKYxX1cDH1rvnqUKjtCzxFgBFj+ySrNHFxUM0yaoTmGK2fU/uuYTQS1Q8s akZ8MxMmlcOXOM4D96aMH6I50+I8qlaAmGeK3frT0VR4o3vnpmRlVi5UGxiPAPx5jS n8MY5nVYQJHbOUDAgpceguEFPd7AqAqOw5QfkM+aIbfkOR8Di/y8SGi8BYbd3KJaz6 7ag/YEAatKmrQ==

Sources

Linux: authentifier une machine sur un domaine Samba/Windows

Linux peut être vu comme un formidable outil que ce soit en serveur ou en bureautique. Néanmoins l'intégration dans un parc existant, bien souvent avec des contrôleurs de domaine Windows ou samba, n'est pas forcément évidente nativement.

Nous allons étudier ici la mise en place de l'authentification samba sous Linux (Ubuntu/Debian)

Prérequis

Installez tout d'abord les paquets suivants:

  • krb5-user
  • samba
  • winbind
  • libpam-winbind
  • libnss-winbind
apt-get install krb5-user samba winbind libpam-winbind libnss-winbind

Configuration

Kerberos

On va tout d'abord configurer le domaine kerberos. Ouvrez le fichier /etc/krb5.conf et référencez votre domaine et vos contrôleurs de domaine.

[libdefaults]
    default_realm = UNIX-EXPERIENCE.FR
    dns_lookup_realm = true
    dns_lookup_kdc = true

[realms]
    UNIX-EXPERIENCE.FR = {
        kdc = ad1.unix-experience.fr:88
        kdc = ad2.unix-experience.fr:88
        admin_server = ad1.unix-experience.fr
        default_domain = unix-experience.fr
    }
    unix-experience.fr = {
        kdc = ad1.unix-experience.fr:88
        kdc = ad2.unix-experience.fr:88
        admin_server = ad1.unix-experience.fr
        default_domain = unix-experience.fr
    }

[domain_realm]
    .unix-experience.fr = UNIX-EXPERIENCE.FR
    unix-experience.fr = UNIX-EXPERIENCE.FR

[login]
    krb4_convert = true
    krb4_get_tickets = false

Samba

On va maintenant configurer notre service samba local afin de se relier à notre domaine kerberos. Editez le fichier /etc/samba/smb.conf:

[global]
        workgroup = UNIX-EXPERIENCE
        security = ads
        realm = unix-experience.fr
        password server = unix-experience.fr
        idmap uid = 10000-20000
        idmap gid = 10000-20000
        winbind enum users = yes
        winbind enum groups = yes
        winbind use default domain = yes
        domain master = no
        local master = no
        preferred master = no
        template shell = /bin/bash
        template homedir = /home/%U

Lancez maintenant votre service samba et puis activez le au démarrage

service samba start

PAM

Pam permet l'authentification. L'installeur Debian/Ubuntu a déjà préconfiguré les modules PAM pour utiliser winbind. Il reste néanmoins quelques fichiers à modifier. Modifiez tout d'abord le fichier /etc/nsswitch.conf pour ajouter l'authentification winbind:

passwd: files winbind
group: files winbind
shadow: files winbind

hosts:          files myhostname mdns4_minimal [NOTFOUND=return] dns
networks:       files

protocols:      db files
services:       db files
ethers:         db files
rpc:            db files

netgroup: nis

Il faut activer le module pam_mkhomedir qui va créer le répertoire home automatiquement à partir d'un squelette, auquel cas il sera impossible de se loguer avec ces comptes dynamiques. Modifiez le fichier pam common-session (/etc/pam.d/common-session) en ajoutant la ligne suivante après le pam_winbind.so

session optional    pam_mkhomedir.so umask=0022 skel=/etc/skel

Vous devriez avoir un fichier de configuration avec le contenu suivant:

session    [default=1]            pam_permit.so
 session    requisite            pam_deny.so
 session    required            pam_permit.so
 session optional            pam_umask.so
 session    required    pam_unix.so
 session    optional            pam_winbind.so
 session optional    pam_mkhomedir.so umask=0022 skel=/etc/skel
 session    optional    pam_systemd.so

S'enregistrer sur le domaine Pour finir, il faut s'enregistrer sur le domaine. Utilisez de préférence un compte de service dédié à cette tâche.

/usr/bin/net ads join -U ADJoinAccount%"myPassw0rd"

Et enfin lancez winbind:

service winbind start

Si tout est correctement configuré la commande wbinfo -u devrait retourner l'ensemble des utilisateurs de l'annuaire.

Bonus: Script pour joindre automatiquement le domain au démarrage

Lorsque vous redémarrerez votre machine ne sera pas connectée au domaine. Il faut préparer un script de démarrage qui va joindre le domaine et redémarrer winbind. Voici un script à executer en dernier (ou avant votre interface graphique) qui va s'occuper de joindre votre domaine au démarrage (et éventuellement en tâche planifiée).

/usr/bin/net ads join -U ADJoinAccount%"myPassw0rd"
while [ $? != 0 ];
do
    sleep 2
    /usr/bin/net ads join -U ADJoinAccount%"myPassw0rd"
done
service winbind restart
sleep 1;
wbinfo -u > /dev/null

npppd: démon ultime de PPTP/L2TP

npppd est un démon libre apparu dans OpenBSD 5.4. Celui-ci vise à remplacer le vieillissant Poptop en offrant une configuration simple et claire avec un axe réseau et sécurité, comme la plupart des logiciels issus de la communauté OpenBSD.

A l'heure actuelle npppd n'est présent que sur OpenBSD.

Configuration par défaut

La configuration se situe dans /etc/npppd/npppd.conf.

Voici le fichier de configuration de base:

# $OpenBSD: npppd.conf,v 1.1 2012/09/20 12:51:43 yasuoka Exp $
# sample npppd configuration file.  see npppd.conf(5)

authentication LOCAL type local {
        users-file "/etc/npppd/npppd-users"
}
#authentication RADIUS type radius {
#       authentication-server {
#               address 192.168.0.1 secret "hogehoge"
#       }
#       accounting-server {
#               address 192.168.0.1 secret "hogehoge"
#       }
#}

tunnel L2TP_ipv4 protocol l2tp {
        listen on 0.0.0.0
}
tunnel L2TP_ipv6 protocol l2tp {
        listen on ::
}

ipcp IPCP {
        pool-address 10.0.0.2-10.0.0.254
        dns-servers 8.8.8.8
}

# use pppx(4) interface.  use an interface per a ppp session.
interface pppx0 address 10.0.0.1 ipcp IPCP
bind tunnel from L2TP_ipv4 authenticated by LOCAL to pppx0
bind tunnel from L2TP_ipv6 authenticated by LOCAL to pppx0

# use tun(4) interface.  multiple ppp sessions concentrate one interface.
#interface tun0  address 10.0.0.1 ipcp IPCP
#bind tunnel from L2TP_ipv4 authenticated by LOCAL to tun0
#bind tunnel from L2TP_ipv6 authenticated by LOCAL to tun0

Comme vous pouvez le voir il est extrêmement simple et clair.

Configuration d'un serveur PPTP

Nous allons ici créer un service de pptp basé sur deux serveurs RADIUS.

Tout d'abord déclarons nos radius:

authentication RADIUS_UNIX_EXPERIENCE type radius {
       authentication-server {
               address 10.56.10.1 port 1812 secret "myprivatesecret"
               address 10.56.10.2 port 1812 secret "mysecondprivatesecret"
       }
       accounting-server {              
               address 10.56.10.1 port 1812 secret "myprivatesecret"
               address 10.56.10.2 port 1812 secret "mysecondprivatesecret"
       }
}

Note 1: Vous serez obligés d'indiquer l'adresse IP des serveurs.

Note 2: L'authentification par défaut est de type MSCHAPv2

Nous allons ensuite déclarer notre tunnel PPTP:

tunnel PPTP_UNIX_EXPERIENCE protocol pptp {
        listen on 0.0.0.0
}

Note: le protocole PPTP ne fonctionne que sur IPv4.

Nous configurons ensuite un pool d'adresses IP qui sera utilisé par nos clients:

ipcp IPCP_UNIX_EXPERIENCE {
        pool-address 10.75.40.2-10.75.40.100
        dns-servers 194.7.35.6 194.7.36.6
}

Puis nous configurons l'interface associée à ce pool d'adresses:

interface tun0 address 10.75.40.1 ipcp IPCP_UNIX_EXPERIENCE

Pour terminer on déclare un processus de tunneling PPTP authentifié via notre RADIUS sur cette interface:

bind tunnel from PPTP_UNIX_EXPERIENCE authenticated by RADIUS_UNIX_EXPERIENCE to tun0

La partie npppd est terminée.

Passons maintenant à la configuration système.

Configuration d'OpenBSD

Dans un premier temps nous allons autoriser le GRE (PPTP s'appuie sur GRE) et le routage (les paquets seront routés de tun0 vers notre interface de sortie, que nous nommerons ici em0)

sysctl net.inet.ip.forwarding=1
sysctl net.inet.gre.allow=1

Pour rendre ces changements permanents, entrez le couple option/valeur dans /etc/sysctl.conf.

tun0 est une interface virtuelle. Elle n'existe pas par défaut et npppd ne va pas la créer. Nous allons donc l'ajouter

echo "up" > /etc/hostname.tun0
sh /etc/netstart tun0

La partie réseau est désormais terminée. On va maintenant NATer les paquets de tun0 vers em0 afin de rendre notre VPN opérationnel. Editons donc la configuration de PF (/etc/pf.conf) en ajoutant la ligne suivante:

pass out quick on em0 from 10.75.40.0/24 nat-to (em0)

Ce qui nous donnera donc:

block
pass
pass out quick on em0 from 10.75.40.0/24 nat-to (em0)

Chargeons maintenant ces règles

pfctl -f /etc/pf.conf

Il ne nous reste plus qu'à activer et à lancer npppd

echo "npppd_flags=" >> /etc/rc.conf.local
/etc/rc.d/npppd start

Conclusion

Nous avons vu ici comment mettre en place rapidement un serveur PPTP. Je vous suggère de consulter le man de npppd afin de connaître l'ensemble des options (elles sont extrêmement nombreuses !).

NPPPd est une réussite en terme d'administration, il est bien plus intuitif et efficace que poptop et sera un digne successeur.

Shibboleth (IdP): installation et retour d’expérience

Shibboleth est un système de fédération d'identités. Il permet d'authentifier des utilisateurs faisant partie d'établissements/entreprises différentes sur des applications mutualisées.

Peu présent et utile dans le secteur privé, Shibboleth est une référence en terme d'authentification dans le secteur public, au sein du ministère de l'enseignement supérieur et de la recherche. Renater, fournisseur d'accès à Internet réservé aux établissement d'enseignement supérieur et de recherche, est l'un des organismes qui l'utilise le plus.

Shibboleth est composé de plusieurs briques, notamment le Service Provider (SP, fournisseur de services) et dans notre cas le fournisseur d'identité (Identity Provider, IdP)

Installation

Pré-requis

Avant de pouvoir installer et utiliser shibboleth, il vous faudra installer JDK 6 et Tomcat 7.

Si vous utilisez Debian tapez simplement:

apt-get install openjdk-6-jdk tomcat7

Si vous utilisez FreeBSD, compilez le port www/tomcat

cd /usr/ports/www/tomcat7
make install clean

ou installez le package depuis votre repo pkgng préféré

pkg install tomcat

Installation de Shibboleth

Téléchargement de l'archive

On télécharge tout d'abord le dernier Shibboleth puis on l'extrait

wget http://shibboleth.net/downloads/identity-provider/latest/shibboleth-identityprovider-2.4.0-bin.tar.gz
tar xvzf shibboleth-identityprovider-2.4.0-bin.tar.gz

Configuration de la variable JAVA_HOME

Pour pouvoir installer Shibboleth nous allons avoir besoin de spécifier la variable d'environnement JAVA_HOME.

Pour Debian, tapez la commande suivante:

export JAVA_HOME="/usr/lib/jvm/java-6-openjdk-amd64/jre"

Pour FreeBSD:

  • si vous utilisez csh:
setenv JAVA_HOME "/usr/local/openjdk6/jre/"
  • si vous utilisez sh, bash ou encore zsh:
export JAVA_HOME="/usr/local/openjdk6/jre/"

Lancement de l'installeur

Pour finir nous lançons l'installation:

cd shibboleth-identityprovider-2.4.0
./install.sh

Lors de l'installation le chemin d'installation, le nom du serveur (adresse DNS du CAS/SSO) et un mot de passe vous seront demandés:

Where should the Shibboleth Identity Provider software be installed? [/opt/shibboleth-idp]
What is the fully qualified hostname of the Shibboleth Identity Provider server? [idp.example.org]
A keystore is about to be generated for you. Please enter a password that will be used to protect it.

Une fois l'installation terminée, on copie le fichier WAR de l'application java dans le répertoire d'applications tomcat.

Pour Debian:

cp /opt/shibboleth-idp/war/idp.war /usr/share/tomcat7/webapps/

Pour FreeBSD:

cp /opt/shibboleth-idp/war/idp.war /usr/local/apache-tomcat-7.0/webapps/

Il faut ensuite changer les droits des répertoires de logs et de méta-données.

Pour Debian:

chown -R tomcat7 /opt/shibboleth-idp/logs
chown -R tomcat7 /opt/shibboleth-idp/metadata

Pour FreeBSD:

chown -R www /opt/shibboleth-idp/logs
chown -R www /opt/shibboleth-idp/metadata

Pour finir, on va ajouter quelques librairies JAVA à tomcat afin que Shibboleth fonctionne correctement. Vous trouverez ces fichiers dans le répertoire où vous avez extrait l'installeur de Shibboleth.

Pour Debian:

cp endorsed/*.jar /usr/share/tomcat7/endorsed/

Pour FreeBSD:

cp endorsed/*.jar /usr/local/apache-tomcat-7.0/endorsed/

Lancement du service

On peut désormais lancer Tomcat.

Sous Debian:

service tomcat7 start

Sous FreeBSD:

service tomcat start

Pour vérifier que tout fonctionne, connectez vous à l'adresse http://idp.example.org:8080/idp/profile/Status. Si la page affiche ok c'est que l'application est correctement déployée.

Enfin, vérifiez que le portail SSO de Shibboleth fonctionne en allant à l'URL http://idp.example.org:8080/idp/Authn/UserPassword

Designer le SSO

Le premier axe d'amélioration est la personnalisation du design du SSO. Pour cela c'est très simple, il suffit d'aller dans le répertoire webapps/idp/ de votre tomcat et de personnaliser les fichiers login.jsp et login.css, correspondant à la page de login. Vous n'avez pas besoin de redémarrer tomcat à chaque modification, à contrario des fichiers de configuration de Shibboleth.

Conclusion

Nous avons ici fait la partie la plus simple, à savoir l'installation de Shibboleth. Le plus compliqué reste la configuration de l'IdP lui-même. Vous trouverez dans les sources ci-dessous la documentation Renater, extrêmement complète permettant de comprendre les différents éléments à configurer pour Shibboleth (partez de la partie 4)

J'ai également essayé d'installer Shibboleth avec Jetty 8 (Shibboleth ne supporte que Jetty >= 7) mais je n'ai pas réussi, ni sur Debian, ni sur FreeBSD. Jetty nécessite d'intégrer des fichiers de configuration supplémentaires et des librairies Tomcat pour faire fonctionner Shibboleth, il reste donc plus pertinent d'utiliser Tomcat 7.

Par ailleurs, j'ai fortement apprécié le déploiement sur cette version de Tomcat 7. J'utilise peu Tomcat et ma précédente expérience avec Tomcat 6 n'avait pas été convaincante.

Même si vous n'utilisez pas la fédération d'identité, Shibboleth peut très bien être utilisé en tant que serveur CAS/SSO (dans mon cas il est branché sur 2 OpenLDAP). Si vous suivez la documentation Renater vous devriez sans problème arriver à faire fonctionner cette partie et pouvoir commencer à l'intégrer sur vos services web.

Sources

https://wiki.shibboleth.net/confluence/display/SHIB2/IdPInstall https://www.switch.ch/aai/docs/shibboleth/SWITCH/latest/idp/deployment/#shibboleth-idp-configuration https://services.renater.fr/federation/docs/installation/idp_decembre2012

OpenSSL: guide de création de certificats

OpenSSL est un outil très puissant permettant de gérer des certificats, que ce soit leur création, leur signature ou leur révocation.

Création d'une autorité de certification

Dans un environnement d'entreprise, il peut être intéressant de créer une autorité de certification qui sera installée sur tous les postes et ainsi pouvoir signer ses propres certificats sans passer par une autorité de certification racine reconnue (et économiser quelques deniers).

Dans un premier temps on créée la clef privée de notre autorité (minimum 2048 bits, 4096 bits recommandés)

openssl genrsa -out ca.key 4096

Quelque chose de similaire apparaîtra à l'écran:

Generating RSA private key, 4096 bit long modulus
..............++
......................................................................++
e is 65537 (0x10001)

Ensuite on créée le certificat racine à partie de cette clef:

openssl req -new -x509 -days 3650 -key ca.key -out ca.crt

OpenSSL vous demande ensuite quelques informations pour le certificat, remplissez les avec soin si elles sont publiques.

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:FR
State or Province Name (full name) [Some-State]:IDF
Locality Name (eg, city) []:Paris
Organization Name (eg, company) [Internet Widgits Pty Ltd]:UXP
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:*.unix-experience.fr
Email Address []:hostmaster@unix-experience.fr

La valeurs -days indique la validé du certificat. Indiquez au minimum 10 ans (3650 jours) pour plus de confort (une clef plus robuste serait mieux dans 10 ans, afin de rester au maximum sécurisé comparé à la vitesse d'évolution du déchiffrement).

Création d'un certificat et signature par l'autorité

Tout d'abord on génère notre clef privée

openssl genrsa -out mycert.key 4096

Puis on fait fait notre demande:

openssl req -new -key mycert.key -out mycert.csr

Et on remplit les champs administratifs:

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:FR
State or Province Name (full name) [Some-State]:IDF
Locality Name (eg, city) []:Paris
Organization Name (eg, company) [Internet Widgits Pty Ltd]:UNIX-Experience
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:myserver.unix-experience.fr
Email Address []:hostmaster@unix-experience.fr

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Enfin on signe le certificat avec notre autorité:

openssl x509 -req -days 3650 -in mycert.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out mycert.crt

Attention: veillez à ce que l'option -days soit inférieure ou égale à celle du CA. Il faut incrémenter le serial à chaque nouveau certificat généré.

Certificat auto-signé sans autorité

Pour créer un certificat auto-signé sans passer par une autorité tierce, il suffit de taper la commande suivante:

openssl req -x509 -new -out mycert.crt -keyout mycert.key -days 3650 -nodes

Renseignez ensuite les champs demandés par OpenSSL

Spamassassin: antispam pour vos serveurs mails

Spamassasin est un excellent outil de gestion de spams. Il est généralement greffé sur un serveur SMTP comme postfix et permet de faire du whitelisting et du blacklisting.

Il existe en réalité 3 types de filtrages mails:

  • whitelisting: autoriser
  • blacklisting: marquer comme spam
  • graylisting: demander de retenter plus tard

Le graylisting peut être intéressant car il oblige un réseau de bot générant des spams à utiliser des mécaniques moins standard, et souvent moins supportées. postgray permet de répondre à cette problématique, mais nous ne le traiterons pas ici.

Nous allons voir dans cet article comment installer spamassassin et l'interfacer avec postfix.

Installation

Sous FreeBSD:

cd /usr/ports/mail/p5-Mail-Spamassassin
make install clean

Choisissez les options par défaut pour le port et pour toutes ses dépendances (hormis si vous avez des besoins précis).

A la fin de l'installation, vous serez invité à mettre à jour les blacklists. Acceptez.

*******************************************************
* _  _  _ _______  ______ __   _ _____ __   _  ______ *
* |  |  | |_____| |_____/ | \  |   |   | \  | |  ____ *
* |__|__| |     | |    \_ |  \_| __|__ |  \_| |_____| *
*                                                   *
*******************************************************
*  You must install rules before starting spamd!    *
*******************************************************
Do you wish to run sa-update to fetch new rules [N]? y

Enfin activez le service dans /etc/rc.conf

spamd_enable="YES"

Configuration

Configuration de spamassassin

Dans un premier temps, on va activer la mise à jour automatique des listes de spamassassin. Ouvrez le fichier /etc/crontab et ajoutez l'entrée suivante:

00      3       *     *     *     root    /usr/local/bin/sa-update

Allez ensuite dans le répertoire de configuration de spamassassin et copiez le fichier d'exemple

cd /usr/local/etc/mail/spamassassin
cp local.cf.sample local.cf

Par défaut peu d'options sont présentes et elles sont toutes commentées.

  • rewrite_header Subject: permet de définir quelle chaîne ajouter dans l'en-tête du mail par exemple /!\ SPAM /!\
  • trusted_networks: permet de définir des réseaux IP définis comme sûrs, sous la forme 10.2.3 (tout le réseau 10.2.3.0/24)
  • required_score: définit le score minimal avant qu'un mail soit considéré comme spam. Le niveau par défaut 5 est normalement suffisant, il est possible de descendre à 3 ou moins mais il y a des chances que des faux positifs apparaissent.
  • required_hits: définit un score en fonction du nombre de mails identiques. Pour une petite organisation 3 est un bon chiffre, pour une grande 8 est mieux.

Configuration de postfix

Pour terminer on va relier postfix et spamassassin. Ouvrez le fichier /usr/local/etc/postfix/master.cf. Editez tout d'avoir la ligne concernant smtp afin d'ajouter la notion de filtre:

smtp      inet  n       -       n       -       -       smtpd -o content_filter=spamassassin

Ensuite déclarez le filtre spamassassin:

spamassassin unix -    n    n    -    -    pipe
    flags=R user=spamd argv=/usr/local/bin/spamc -e /usr/sbin/sendmail -oi -f ${sender} ${recipient}

Lancement des services

Vous pouvez désormais lancer vos services:

service postfix restart
service sa-spamd restart

Vérification de l'antispam

Envoyez vous un mail. Vous devriez voir apparaître une sortie similaire dans /var/log/maillog

Jun  8 20:15:01 MailServer spamd[57413]: spamd: connection from localhost [127.0.0.1] at port 54641
Jun  8 20:15:01 MailServer spamd[57413]: spamd: setuid to spamd succeeded
Jun  8 20:15:01 MailServer spamd[57413]: spamd: creating default_prefs: /var/spool/spamd/.spamassassin/user_prefs
Jun  8 20:15:01 MailServer spamd[57413]: config: created user preferences file: /var/spool/spamd/.spamassassin/user_prefs
Jun  8 20:15:01 MailServer spamd[57413]: spamd: processing message <1370715664.2282.0.camel@Arch-PC> for spamd:58
Jun  8 20:15:03 MailServer spamd[57413]: spamd: clean message (-0.8/3.0) for spamd:58 in 1.9 seconds, 2248 bytes.
Jun  8 20:15:03 MailServer spamd[57413]: spamd: result: . 0 - DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,HTML_MESSAGE,RCVD_IN_DNSWL_LOW,SPF_PASS scantime=1.9,size=2248,user=spamd,uid=58,required_score=3.0,rhost=localhost,raddr=127.0.0.1,rport=54641,mid=<1370715664.2282.0.camel@Arch-PC>,autolearn=ham
Jun  8 20:15:03 MailServer spamd[57412]: prefork: child states: II

Le score est de 0, le mail passera sans souci.

Maintenant envoyez vous un mail avec pour sujet:

XJSC4JDBQADN1.NSBN32IDNENGTUBE-STANDARD-ANTI-UBE-TEST-EMAILC.34X

Vous devriez voir le mail se faire marquer comme spam:

Jun  8 20:15:56 MailServer spamd[57413]: spamd: connection from localhost [127.0.0.1] at port 39519
Jun  8 20:15:56 MailServer spamd[57413]: spamd: setuid to spamd succeeded
Jun  8 20:15:56 MailServer spamd[57413]: spamd: processing message <1370715720.2282.2.camel@Arch-PC> for spamd:58
Jun  8 20:15:57 MailServer spamd[57413]: spamd: identified spam (999.2/3.0) for spamd:58 in 1.5 seconds, 2437 bytes.
Jun  8 20:15:57 MailServer spamd[57413]: spamd: result: Y 999 - DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,GTUBE,HTML_MESSAGE,RCVD_IN_DNSWL_LOW,SPF_PASS,TVD_SPACE_RATIO scantime=1.5,size=2437,user=spamd,uid=58,required_score=3.0,rhost=localhost,raddr=127.0.0.1,rport=39519,mid=<1370715720.2282.2.camel@Arch-PC>,autolearn=no
Jun  8 20:15:57 MailServer spamd[57412]: prefork: child states: II

Ici le score est de 999. C'est un spam. Notre serveur va donc rajouter l'en-tête que vous avez mentionné plus haut et vous remettre le mail.

Capture d'écran de 2013-06-08 20:31:10Comme vous le voyez le message est tagué.

Aller plus loin

Trier les mails tagués avec dovecot2 et pigeonhole

Pigeonhole est le successeur de l'ancien plugin sieve qui était présent sur la version 1 de dovecot. Il permet de trier les mails en fonction de différents critères.

Installez le port dovecot2-pigeonhole et créez le fichier 90-sieve.conf dans le répertoire conf.d de dovecot.

service managesieve-login {
  inet_listener sieve {
    port = 4190
  }

  # Number of connections to handle before starting a new process. Typically
  # the only useful values are 0 (unlimited) or 1\. 1 is more secure, but 0
  # is faster. <doc/wiki/LoginProcess.txt>
  #service_count = 1

  # Number of processes to always keep waiting for more connections.
  #process_min_avail = 0

  # If you set service_count=0, you probably need to grow this.
  #vsz_limit = 64M
}

service managesieve {
  # Max. number of ManageSieve processes (connections)
  process_limit = 1024
}

# Service configuration

protocol sieve {
  # Maximum ManageSieve command line length in bytes. ManageSieve usually does
  # not involve overly long command lines, so this setting will not normally need
  # adjustment
  #managesieve_max_line_length = 65536

  # Maximum number of ManageSieve connections allowed for a user from each IP address.
  # NOTE: The username is compared case-sensitively.
  #mail_max_userip_connections = 10

  # Space separated list of plugins to load (none known to be useful so far). Do NOT
  # try to load IMAP plugins here.
  #mail_plugins =

  # MANAGESIEVE logout format string:
  #  %i - total number of bytes read from client
  #  %o - total number of bytes sent to client
  #managesieve_logout_format = bytes=%i/%o

  # To fool ManageSieve clients that are focused on CMU's timesieved you can specify
  # the IMPLEMENTATION capability that the dovecot reports to clients.
  # For example: 'Cyrus timsieved v2.2.13'
  #managesieve_implementation_string = Dovecot Pigeonhole

  # Explicitly specify the SIEVE and NOTIFY capability reported by the server before
  # login. If left unassigned these will be reported dynamically according to what
  # the Sieve interpreter supports by default (after login this may differ depending
  # on the user).
  #managesieve_sieve_capability =
  #managesieve_notify_capability =

  # The maximum number of compile errors that are returned to the client upon script
  # upload or script verification.
  #managesieve_max_compile_errors = 5

  # Refer to 90-sieve.conf for script quota configuration and configuration of
  # Sieve execution limits.
}

plugin {
  # Used by both the Sieve plugin and the ManageSieve protocol
  sieve = ~/.dovecot.sieve
  sieve_dir = ~/sieve
  sieve_default = /usr/local/etc/dovecot/conf.d/sieve/default
}

Enfin, créez le fichier /usr/local/etc/dovecot/conf.d/sieve/default contenant le script suivant (remplacez Spam par le répertoire de votre choix. Il peut être idéal d'auto créer la boîte si elle n'existe pas via dovecot).

require "fileinto";

if header :contains "X-Spam-Flag" ["YES"] {
  fileinto "Spam";
  stop;
}

Vous avez désormais un serveur avec spamassassin et un tri automatique des mails !

Sauvegarder son système d’informations avec Bacula

Bacula est un système de sauvegarde libre extrêmement puissant. Le logiciel dispose d'un ensemble de fonctionnalités extrêmement intéressant, et d'une qualité professionnelle telle que certains logiciels propriétaires devraient suivre son exemple.

Le logiciel se découpe en 4 parties:

  • Une ou plusieurs bases de données qui servent de catalogue (tâches, liens vers les fichiers, évènements...)
  • Un ou plusieurs directeurs qui gèrent l'ensemble des stratégies de sauvegarde et référencent les clients
  • Un ou plusieurs services de stockage qui vont gérer un ensemble de volumes virtuels ou physiques
  • Des clients à sauvegarder

Un petit schéma permettra de mieux comprendre l'architecture:

Bacula InfraIl s'agit ici d'une infrastructure pour quelques centaines de serveurs. Vous pouvez vous contenter d'un simple serveur avec du stockage, qui fera office de storage, director et catalogue.

Installation et configuration de la base de données

Nous allons utiliser postgresql pour sa rapidité et sa capacité à gérer de grands volumes de données.

Sous debian (wheezy)

aptitude install postgresql-9.1

On va ensuite se connecter en superutilisateur et créer la base et l'utilisateur bacula

su - postgres
createuser -sdrP bacula
createdb -E SQL_ASCII -T template0 -O bacula bacula

Sur FreeBSD:

cd /usr/ports/databases/postgresql91-server
make install clean
service postgresql initdb
service postgresql start

On se connecte en super utilisateur:

su - pgsql
createuser -sdrP bacula
createdb -E SQL_ASCII -T template0 -O bacula bacula

Installation des services

On installe les différents services nécessaires pour faire fonctionner bacula

Sous Debian:

aptitude install bacula-director-pgsql bacula-console bacula-sd-pgsql

A la fin de l'installation bacula vous demandera les informations sur la base de données PostGreSQL. Indiquez pour chaque élément l'utilisateur et le mot de passe précédémment créé.

Sous FreeBSD:

cd /usr/ports/sysutils/bacula-server
make install clean

Choisissez les options de compilation suivantes:

Capture d'écran de 2013-05-02 18:39:34

Pour terminer on va installer la base:

su - pgsql
/usr/local/share/bacula/make_postgresql_tables

Configuration du service de stockage

En premier lieu nous allons configurer le serveur de stockage. Celui-ci permet d'interagir avec les différents supports de stockage pour la sauvegarde. Bacula supporte le stockage de cartouches virtuelles mais également les lecteurs de bandes (LTO3-4-5...).

Notre configuration utilisera ici des cartouches virtuelles.

On va tout d'abord copier le fichier sample avant de l'éditer.

Sous Debian:

cp /etc/bacula/bacula-sd.conf.sample /etc/bacula/bacula-sd.conf

Sous FreeBSD:

cp /usr/local/etc/bacula/bacula-sd.conf.sample /usr/local/etc/bacula-sd.conf

Nous allons créer un répertoire de stockage pour nos cartouches:

mkdir -p /backup/Volumes

Editons maintenant bacula-sd.conf

La section Storage définit le service de stockage lui même. Chaque Storage doit avoir un nom et un port d'écoute. C'est également à ce niveau qu'on va définir un nombre limite de tâches concurrentes, permettant d'éviter de saturer la capacité des lecteurs physiques/virtuels. L'écoute est configurée sur toutes les interfaces, permettant aux directeurs distants de sauvegarder

Storage {                             # definition of myself
  Name = MY_BACULA_STORAGE
  SDPort = 9103                  # Director's port
  WorkingDirectory = "/var/db/bacula"
  Pid Directory = "/var/run"
  Maximum Concurrent Jobs = 20
  SDAddress = 0.0.0.0
}

Note: les chemins pid et db sont les suivants sur Debian:

WorkingDirectory = "/var/lib/bacula"
Pid Directory = "/var/run/bacula"

La section Director permet de définir les serveurs directeurs pouvant se connecter à ce noeud de stockage afin de stocker leurs données. Chaque directeur possède un mot de passe par SD. Celui-ci doit être long et complexe.

Director {
  Name = MY_BACULA_DIRECTOR
  Password = "mycomplexpasswordover40chars"
}

La section Device permet de définir un périphérique de stockage pour les volumes. Le Media Type définit le type de périphérique, ici des fichiers. On spécifie ensuite un répertoire, Archive Device, où seront stockés les volumes. Enfin on demande à bacula de nommer les volumes, d'écrire aléatoirement sur les volumes (sécurité), de monter automatiquement les volumes et de les laisser ouverts.

Device {
  Name = MY_BACULA_STORAGE_DEVICE
  Media Type = File
  Archive Device = /backup/Volumes/
  LabelMedia = yes;
  Random Access = Yes;
  AutomaticMount = yes;
  RemovableMedia = no;
  AlwaysOpen = yes;
}

Enfin la section Messages permet de définir un ou plusieurs directeurs à qui remonter les informations (logs), et de filtrer le type de logs qu'on envoie à chaque directeur.

Messages {
  Name = Standard
  director = MY_BACULA_DIRECTOR = all

Une fois que vous avez terminé, vous pouvez démarrer le service de stockage.

service bacula-sd start

Configuration du directeur

Premiers pas

Le directeur est celui qui orchestre toute la sauvegarde. Il sait ce qu'on sauvegarde, comment, à quelle période et où.

Dans un premier temps on va copier le fichier de configuration d'example du directeur (et créer un répertoire pour les fichiers de bacula sous FreeBSD

Sous Debian:

cp /etc/bacula/bacula-dir.conf.sample /etc/bacula/bacula-dir.conf

Sous FreeBSD:

cp /usr/local/etc/bacula-dir.conf.sample /usr/local/etc/bacula-dir.confmkdir /usr/local/etc/bacula/

On ouvre maintenant le fichier de configuration.

Director {                            # define myself
  Name = MY_BACULA_DIRECTOR
  DIRport = 9101                # where we listen for UA connections
  QueryFile = "/usr/local/share/bacula/query.sql"
  WorkingDirectory = "/var/db/bacula"
  PidDirectory = "/var/run"
  Maximum Concurrent Jobs = 10
  Password = "mycomplexpasswordover40chars"
  Messages = MailDaemon
  DirAddress = 0.0.0.0
}

On configure ici le nom du directeur et son mot de passe (utilisés sur les storage daemon), les interfaces et le port d'écoute, et les différents répertoires et fichiers de requête. Vous pouvez également spécifier le nombre de tâches que peut faire le service en parallèle.

La directive Messages définit la commande à exécuter et ses paramètres lors de notifications

Note: le QueryFile, le WorkingDirectory et le PidDirectory sont différents sur Debian:

QueryFile = "/etc/bacula/scripts/query.sql"
WorkingDirectory = "/var/lib/bacula"
PidDirectory = "/var/run/bacula"

La configuration de bacula pouvant devenir volumineuse, nous allons découper le fichier de configuration en plusieurs fichiers en ajoutant les lignes suivantes:

@/usr/local/etc/bacula/bacula-dir-storage.conf
@/usr/local/etc/bacula/bacula-dir-pools.conf
@/usr/local/etc/bacula/bacula-dir-catalogs.conf
@/usr/local/etc/bacula/bacula-dir-schedules.conf
@/usr/local/etc/bacula/bacula-dir-jobdefs.conf
@/usr/local/etc/bacula/bacula-dir-jobs.conf
@/usr/local/etc/bacula/bacula-dir-filesets.conf
@/usr/local/etc/bacula/bacula-dir-clients.conf

Note: le chemin est /etc/bacula sur Debian

Enfin on termine par la définition de l'envoi de messages MailDaemon:

Messages {
  Name = MailDaemon
  mailcommand = "/usr/sbin/bsmtp -h localhost -f \"\(Bacula\) \<bacula@mydomain.com\>\" -s \"Bacula daemon message\" mymailbox@mydomain.com"
  mail = root = all, !skipped            
  console = all, !skipped, !saved
  append = "/var/log/bacula/bacula.log" = all, !skipped
}

Console {
  Name = bacula-mon
  Password = "monmotdepassemonitorcomplexe"
  CommandACL = status, .status
}

Définition des noeuds de stockage

La première chose à faire est de donner au directeur des noeuds de stockages sur lesquels stocker ses données (bacula-dir-storage.conf).

Storage {
  Name = MY_BACULA_STORAGE
  Address = storage1.mydomain.com
  SDPort = 9103
  Password = "mycomplexpasswordover40chars"
  Device = MY_BACULA_STORAGE_DEVICE
  Media Type = File
}

Dans l'exemple ci-dessus, on précise le nom du noeud de stockage, son adresse IP et port, mais également le mot de passe à utiliser (identique à celui de la section director renseignée sur le SD), le périphérique et son nom.

Attention: l'adresse ne peut pas être localhost, uniquement une adresse IP routable ou un nom DNS

Définition des pools de cartouches

On va maintenant configurer des pools de cartouches pour la sauvegarde (bacula-dir-pools.conf). Ceux-ci définissent les propriétés des différentes cartouches

Pool {
  Name = MY_BACULA_POOL
  Pool Type = Backup
  Recycle = yes
  AutoPrune = yes
  Volume Retention = 365 days
  Volume Use Duration = 7 days
  Maximum Volume Bytes = 50G
  Maximum Volumes = 100
  LabelFormat = "POOL1_VOL_"
}

Chaque pool dispose d'un identifiant et un type (généralement Backup). On peut définir des propriétés:

  • Recycle: recycler les volumes, s'il n'y a plus d'espace, ou que les cartouches sont trop anciennes
  • AutoPrune: recycle automatiquement les cartouches s'il n'y a plus d'espace disponible
  • Volume Use Duration: la période pendant laquelle le volume peut être utilisé. C'est utile si vous utilisez des cartouches de sauvegarde complète et des cartouches de sauvegarde incrémentale, afin de supprimer les sauvegardes incrémentales à chaque fois que la sauvegarde totale est faite.
  • Volume Retention: la période de rétention des données sur les cartouches
  • Max Volume Bytes: la taille maximale d'une cartouche. Une valeur entre 50 et 300G est raisonnable
  • Maximum Volumes: le nombre maximal de cartouches. Attention à ne pas dépasser l'espace disque total (somme des Max Volume Bytes * Maximum Volumes de chaque pool)
  • LabelFormat: le préfixe de nomage des cartouches

Définition des catalogues

Les catalogue contient l'ensemble des liens entre fichiers, versions et volumes de données. Il s'agit d'un élément extrêmement sensible.

Catalog {
  Name = MyBaculaCatalog
  dbname = "bacula"; DB Address = "192.168.1.1"; dbuser = "bacula"; dbpassword = "bacula"
}

Spécifiez les données correspondant à votre serveur PostGreSQL.

Planification des sauvegardes

L'important dans une sauvegarde est de correctement planifier vos sauvegardes, afin d'éviter de charger le réseau lorsqu'il est utilisé, ou de pouvoir sauvegarder les données dans une période de temps donnée. Si on possède un seul directeur et périphérique de sauvegarde il est important de vérifier qu'il est possible de tout sauvegarder le même soir/jour, autrement il faudra répartir les sauvegardes dans le temps.

De même il est possible de définir des stratégies de sauvegardes avec plusieurs directeurs, par exemple directeur1 sauvegarde les serveurs A,B,C le lundi,mercredi,vendredi,dimanche et directeur 2 les sauvegarde les autres jours.

La configuration des planifications se fait dans bacula-dir-schedule.conf

Schedule {
  Name = "Cycle Hebdo"
  Run = Full sun at 05:00
  Run = Differential 2nd-5th sun at 23:05
  Run = Incremental mon-sat at 23:30
  Run = Incremental wed at 5:30 pool=WED_BACKUP_POOL
  FullPool = POOL_BACKUP_FULL
  IncrementalPool = POOL_BACKUP_INCR
  Pool = MY_BACULA_POOL
  Storage = MY_BACULA_STORAGE
}

Nous avons ici une configuration verbeuse, afin de définir la flexibilité de l'ensemble des paramètres:

  • Run: définit le moment déclenchant la tâche
    • Full: une sauvegarde complète
    • Differential: uniquement les changements depuis la dernière sauvegarde complète
    • Incrémentale: uniquement les changements depuis la dernière sauvegarde réussie
    • Jour et heure: on peut définir tout et n'importe quoi, ici le dimanche à 5h, comme du 2ème au 5ème dimanche du mois, ou encore le premier janvier... et spécifier un pool pour cette tâche spécifique
  • FullPool: si la directive n'est pas outrepassée, le pool de cartouches sur lesquelles faire les sauvegardes totales
  • IncremantalPool: si la directive n'est pas outrepassée le pool de cartouches sur lesquelles faire la sauvegarde incrémentale
  • Pool: le pool par défaut pour tous les types de sauvegarde
  • Storage: le noeud de stockage où sauvegarder

Définir des ensembles de fichiers

Les ensembles de fichiers sont des listes de fichiers à sauvegarder (avec possibilité d'exclusion)

FileSet {
   Name = "WEB_FILESET"
   Include {
     Options {
       signature = MD5
       Compression = GZIP
       wildfile = "*.zip"
       Exclude = yes
     }
     File = /usr/local/www
   }
  Exclude {
    File = /usr/local/www/tmp
 File = /usr/local/www/.git
  }
 }

Pour chaque inclusion de fichiers il est possible de spécifier un ou plusieurs chemins (répertoires/fichiers) ainsi que des options:

  • compression: par défaut désactivée, il est possible de choisir GZIP ou LZO (pour les serveurs chargés en CPU). Elle est recommandée pour les cartouches virtuelles mais pas physiques
  • signature: permet de garder une trace md5 ou sha1 de chaque fichier, garantissant leur intégrité.

On peut exclure des répertoires avec la directive exclude, ou bien encore des fichiers par patern (ici des zip).

Spécifier des définitions de tâches

Les définitions de tâches sont des tâches non appliquées. Elles permettent de créer une arborescence de tâches héritées et ainsi de déployer très rapidement des stratégies de sauvegarde sur un panel de clients très large.

Tâches de sauvegarde

JobDefs {
  Name = "Web_Backup_JD"
  Type = Backup
  Level = Incremental
  Client = WEB1_FD
  FileSet = "WEB_FILESET"
  Schedule = "Cycle Hebdo"
  Storage = MY_BACULA_STORAGE
  Messages = MailDaemon
  Pool = MY_BACULA_POOL
  Priority = 10
  Max Start Delay = 1h
  Max Run Time = 6h
}

Cette définition permet de configurer une tâche de sauvegarde et de l'associer à un client (unique) et à une planification précise. Les directives Storage et Pool sont écrasées par celles définies dans la planification, si elles sont présentes.

Les autres directives définissent

  • FileSet: l'ensemble de fichiers associé à cette tâche
  • Priority: le niveau de priorité de cette tâche. Si d'autres tâches sont à effectuer avec une priorité plus faible elles seront retardées pour effectuer celle-ci
  • Max Start Delay: définit la limite après laquelle la tâche ne sera pas effectuée si elle n'a pas été commencée (à cause d'autres tâches en cours par exemple). Dans notre cas, si on sauvegarde à 23h et qu'à minuit la tâche n'a pas commencé, elle est annulée (optionnel)
  • Max Run Time: après 6h on annule la tâche (par défaut 6 jours)

Il est également possible de lancer des commandes avant et après la tâche sur le système de sauvegarde mais également sur le client, voire des commandes en cas d'échec. Je vous invite à lire la documentation sur les jobs.

Tâches de restauration

Pour pouvoir restaurer des fichiers vous aurez besoin de définir une tâche de restauration. Bacula permet de restaurer dans le répertoire d'origine mais également dans des répertoires différents. Il est même possible de planifier des tâches de restauration, afin de s'assurer qu'une donnée n'est pas altérée sur un serveur. Voici un exemple de tâche:

JobDefs {
  Name = "Web_Restore_JD"
  Type = Restore
  Client = WEB1_FD
  FileSet = "WEB_FILESET"
  Storage = MY_BACULA_STORAGE
  Messages = Standard
  Pool = MY_BACULA_POOL
  Where = "/"
  Add Suffix = .restore
}

La directive Where définit le répertoire dans lequel restaurer le fichier. Ici on définit le répertoire / car bacula restaure en conservant l'arborescence de fichiers.

La directive Add Suffix (optionnelle) permet de rajouter un suffixe aux fichiers restaurés, afin d'éviter de les écraser. D'autres options existent et sont présentes dans la documentation des Jobs.

Définition des tâches

Les tâches se définissent de la même manière que les définitions de tâches (JobDefs).

Afin d'inclure un ensemble de définition, utilisez simplement la directive JobDefs:

Job {
  Name = "Backup_WebServer"
  JobDefs = "Web_Backup_JD"
}

Job {
  Name = "Restore_WebServer"
  JobDefs = "Web_Restore_JD"
}

Vous pouvez ajouter/écraser des attributs ou ne pas utiliser de JobDefs si besoin est. Dans un environnement avec plus d'une dizaine de machines il peut être utile de définir des JobDefs afin de pouvoir créer une tâche avec héritage pour chaque client.

Déclaration des clients

Bacule se connecte lui-même sur les clients. Chaque client dispose d'un service en attente de tâches de sauvegarde. Voici la définition d'un client côté directeur:

Client {
  Name = WEB1_FD
  Address = myclient.domain.com
  FDPort = 9102
  Catalog = MyCatalog
  Password = "motdepasseduclienttrèslong"
  File Retention = 30 days
  Job Retention = 6 months
  AutoPrune = yes
  Maximum Concurrent Jobs = 3
  Maximum Bandwidth Per Job = 10 Mb/s
}

Décrivons les attributs intéressants:

  • Catalog: le catalogue local à utiliser pour ce client
  • Password: le mot de passe commun au directeur et au client
  • File Retention: durée pendant laquelle garder les fichiers pour ce client. Il faut spécifier une valeur inférieure à celle des cartouches et des tâches auquel cas la rétention appliquée sur les 3 sera la plus faible
  • Job Retention: durée pendant laquelle garder les tâches pour ce client. Il faut spécifier une valeur inférieure à celle des cartouches, auquel cas la rétention appliquée sur les 2 sera la plus faible.
  • AutoPrune: supprime les entrées du catalogue une fois la période de rétention expirée. Mettre cette valeur à no implique un catalogue grossissant plus qu'il ne devrait
  • Maximum Concurrent Jobs: si vous effectuez plusieurs tâches de sauvegarde sur des répertoires différents il peut être judicieux de paralléliser la sauvegarde (à éviter si vous sauvegardez les mêmes données)
  • Maximum Bandwith Per Job: permet de limiter la bande passante utilisée, utile dans le cas d'une sauvegarde en journée ou s'il y a beaucoup de tâches en parallèle sur l'ensemble du serveur.

Aller encore plus loin

Bacula dispose d'énormément d'options extrêmement poussées, il est donc possible de faire beaucoup de choses avec cet outil et un simple article ne peut pas tout détailler. Je vous invite à regarder cette page afin de connaître toutes les options de configuration

Sauvegarde incrémentale (logs)

Lors de cette veille, le serveur de test sur lequel je travaillais a effectué une sauvegarde incrémentale. Bacula étant verbeux, il a rédigé un rapport de sauvegarde dans les logs. Vous pourrez voir qu'il gère le décallage horaire de serveurs (le serveur de sauvegarde de test ayant 2h de décallage):

02-mai 23:05 PALA_DIRECTOR JobId 7: Start Backup JobId 7, Job=Backup_AllWebClusters.2013-05-02_23.05.00_02
02-mai 23:05 PALA_DIRECTOR JobId 7: Using Device "PALA_STORAGE_DEV"
02-mai 21:16 WEBCLUSTER1_FD JobId 7: Warning: DIR and FD clocks differ by -6522 seconds, FD automatically compensating.
02-mai 23:05 PALA_STORAGE JobId 7: Volume "PALA_VOL_0001" previously written, moving to end of data.
02-mai 23:05 PALA_STORAGE JobId 7: Ready to append to end of Volume "PALA_VOL_0001" size=12015358632
02-mai 23:06 PALA_STORAGE JobId 7: Job write elapsed time = 00:01:07, Transfer rate = 6.378 M Bytes/second
02-mai 23:06 PALA_DIRECTOR JobId 7: Bacula PALA_DIRECTOR 5.2.6 (21Feb12):
  Build OS:               x86_64-pc-linux-gnu debian 7.0
  JobId:                  7
  Job:                    Backup_AllWebClusters.2013-05-02_23.05.00_02
  Backup Level:           Incremental, since=2013-05-02 17:40:46
  Client:                 "WEBCLUSTER1_FD" 5.2.12 (12Sep12) amd64-portbld-freebsd9.1,freebsd,9.1-RELEASE
  FileSet:                "WebCluster_FILESET" 2013-05-02 17:35:20
  Pool:                   "PALA_POOL" (From Job resource)
  Catalog:                "PalaCatalog" (From Client resource)
  Storage:                "PALA_STORAGE" (From Job resource)
  Scheduled time:         02-mai-2013 23:05:00
  Start time:             02-mai-2013 23:05:03
  End time:               02-mai-2013 23:06:10
  Elapsed time:           1 min 7 secs
  Priority:               10
  FD Files Written:       138
  SD Files Written:       138
  FD Bytes Written:       427,368,697 (427.3 MB)
  SD Bytes Written:       427,389,095 (427.3 MB)
  Rate:                   6378.6 KB/s
  Software Compression:   None
  VSS:                    no
  Encryption:             no
  Accurate:               no
  Volume name(s):         PALA_VOL_0001
  Volume Session Id:      6
  Volume Session Time:    1367509217
  Last Volume Bytes:      12,443,069,451 (12.44 GB)
  Non-fatal FD errors:    0
  SD Errors:              0
  FD termination status:  OK
  SD termination status:  OK
  Termination:            Backup OK

02-mai 23:06 PALA_DIRECTOR JobId 7: Begin pruning Jobs older than 6 months .
02-mai 23:06 PALA_DIRECTOR JobId 7: No Jobs found to prune.
02-mai 23:06 PALA_DIRECTOR JobId 7: Begin pruning Files.
02-mai 23:06 PALA_DIRECTOR JobId 7: No Files found to prune.
02-mai 23:06 PALA_DIRECTOR JobId 7: End auto prune.

Installation du File Daemon

Le File Daemon est l'agent de sauvegarde de bacula.

Pour l'installer sur Debian:

aptitude install bacula-fd

Sur FreeBSD il s'agit du même paquet que pour le serveur, désactivez simplement le support SQL

cd /usr/ports/sysutils/bacula-server
make install clean

Renommez ensuite les fichiers de configuration bacula-fd.conf.sample en bacula-fd.conf et éditez le

FileDaemon {
  Name = WEB1_FD
  DIRport = 9102
  Working Directory = "/var/db/bacula"
  Pid Directory = "/var/run"
  Maximum Concurrent Jobs = 20
}
Director {
  Name = MY_BACULA_DIRECTOR
  Password = "mycomplexpasswordover40chars"
}
Messages {
  Name = Standard
  director = MY_BACULA_DIRECTOR = all, !skipped
}

La section FileDaemon définit l'agent lui-même.

Note: les répertoires sont respectivement /var/lib/bacula et /var/run/bacula sous Debian

La directive Director permet de définir 1 ou plusieurs Directeurs pouvant effectuer la sauvegarde, enfin la directive messages permet de définir les remontées de logs.

Conclusion

Je m'arrête sur cette partie dédiée à la sauvegarde, mais il faudrait bien entendu parler de la restauration et de la gestion quotidienne. Celles-ci sont possibles via le client Bacula (disponible sur Linux, Mac OSX et Windows) et/ou une interface web que vous pouvez installer

Bacula est un système de sauvegarde extrêmement complet, qui reste dans une logique UNIX, en offrant une sauvegarde complète mais ne s'occupant pas du système de fichiers. Il convient d'offrir un bon support de données (ext3/ext4/ufs2) pour votre catalogue et vos cartouches virtuelles. Afin de garantir la sécurité des données sauvegardées, il faut absolument utiliser 2 supports de données, dans l'idéal 2 directeurs avec 2 StorageDaemon, qui font chacun un backup à chaud de leurs catalogues, de manière régulière. Il peut être également intéressant d'utiliser des pools de sauvegarde dédiés à chaque journée, et un pool de sauvegarde pour la sauvegarde hebdomadaire.

Pour finir, Bacula est donc un système de sauvegarde de qualité profesionnelle sous licence libre, qui saura satisfaire tous les besoins (le tout étant de correctement architecturer son infrastructure).

Authentifier une machine Ubuntu (12.10) sur un annuaire OpenLDAP

Suite à la création d'un nouveau projet que j'ai en tête (le projet Icare), visant à créer une sorte de contrôleur de domaine mais avec des outils UNIX (se basant sur un openLDAP local ou existant et puppet, et une interface web), je vais vous exposer ici comment intégrer une machine Ubuntu 12.10 sur un annuaire de type OpenLDAP.

Vous pourrez trouver une ancienne version (2011) plus générique et moins guidée du pam_ldap ici.

Prérequis

Vous devez posséder un annuaire openLDAP opérationnel, avec une ou plusieurs unités d'organisation (OU) contenant vos utilisateurs et groupes. Cet annuaire doit utiliser les schémas inetOrgPerson et posixAccount.

Les utilisateurs et groupes que vous déclarerez sur l'annuaire doivent utiliser un mot de passe de type LDAP (userPassword), et des champs uidNumber et gidNumber peuplés (et > 1000, voire 5000 dans l'idéal).

Installation des paquets

Nous allons installer les paquets associés au pam qui vont nous permettre d'établir un login LDAP sur la machine. Passez en root ou utilisez sudo afin d'installer les paquets.

apt-get install auth-client-config ldap-auth-client ldap-auth-config ldap-utils libnss-ldap libpam-ldap

Maintenant nous allons configurer le lien entre la machine et LDAP dans les fenêtres dialog.

ldap-uri.jpgEntrez tout d'abord l'URI de votre serveur LDAP (dans l'idéal avec SSL). Choisissez ensuite la version du protocole (en général 3).

ldap-change-pwdOn vous demande ici si on peut changer le mot de passe LDAP par le biais de la machine. Refusez, à moins que votre SI n'autorise un utilisateur en écriture sur les mots de passe (ce qui serait étonnant).

ldap-search-loginOn vous demande ensuite s'il faut un login (utilisateur proxy) afin de pouvoir lire l'annuaire. Dans notre cas nous répondons non, sinon il faudrait indiquer le nom d'utilisateur (dn) et son mot de passe.

ldap-search-pathEnfin entrez le chemin principal de recherche des utilisateurs.

Configuration du PAM

Ouvrez maintenant le fichier /etc/ldap.conf et recherchez les lignes nss_base_passwd, et similaires. Nous allons les éditer pour permettre le login via le pam_ldap

nss_base_passwd ou=people,dc=unix-experience,dc=fr
nss_base_shadow ou=people,dc=unix-experience,dc=fr
nss_base_group ou=groups,dc=unix-experience,dc=fr

Vérifiez le lien entre nss et LDAP en allant voir le contenu de /etc/nsswitch.conf. Vous devriez avoir 3 lignes contenant ldap:

passwd: files ldap
group: files ldap
shadow: files ldap

Maintenant on va relier auth-client-config à LDAP. Tapez la commande suivante:

auth-client-config -t nss -p lac_ldap

Afin de vérifier que le lien fonctionne tapez la commande suivante (en remplace myuser par le nom d'un utilisateur dans votre annuaire)

id myuser

Vous devriez voir apparaître l'UID et le GID de votre annuaire LDAP

uid=5000(myuser) gid=5000(ldap-users) groupes=5000(ldap-users)

Attention ! Le GID doit obligatoirement correspondre à un groupe LDAP existant sur l'annuaire (posixGroup), auquel cas l'utilisateur peut avoir des problèmes de connexion à la GUI.

Pour terminer sur la configuration du PAM, nous allons activer la création du répertoire utilisateur à la volée via le module pam_mkhomedir. Ouvrez le fichier /etc/pam.d/common-session et ajoutez la ligne suivante avant la ligne contenant pam_unix.so

session required pam_mkhomedir.so umask=0022 skel=/etc/skel

Il est à noter que le répertoire /etc/skel contient un ensemble de fichiers par défaut à créer lors de la première connexion de l'utilisateur.

Configuration de lightdm

Pour terminer nous allons configurer lightdm afin de pouvoir se connecter à la machine avec des logins autres que locaux. Ouvrez le fichier /etc/lightdm/lightdm.conf et ajoutez la ligne suivante:

greeter-hide-users=true

Vous pouvez également supprimer l'accès aux utilisateurs invités en ajoutant la ligne

allow-guest=false

Attention ! Lightdm étant mal conçu la moindre erreur de frappe fera buguer le gestionnaire de connexion, espérons que Canonical fera quelque chose.

Conclusion

Vous savez désormais relier une machine Ubuntu à un annuaire openLDAP ! D'autres précisions seront ajoutées dans d'autres articles afin de préciser ce que l'on peut faire (montages automatiques, filtrage, etc...) Source 1 Source 2 Source 3

Migrer de Squid 3.1.X à Squid 3.2.X

Squid 3.2 est depuis peu devenu la branche stable de Squid. FreeBSD propose désormais d'utiliser cette version dans les ports à la place de Squid 3.1.20, Debian devrait la faire remonter d'ici quelques semaines dans unstable puis testing et dans le prochain Debian 8.0 d'ici 2 ans.

Ici nous utilisons OpenBSD. Squid est donc fraîchement compilé depuis les sources (en 3.2.5 au moment de la rédaction de l'article). Voici nos options de compilation:

./configure '--enable-pf-transparent' '--enable-follow-x-forwarded-for' '--with-large-files' '--enable-ssl' '--disable-ipv6' '--enable-esi' '--enable-kill-parent-hack' '--disable-snmp' --with-pthreads '--enable-external-acl-helpers=ip_user unix_group wbinfo_group' --enable-auth='ntlm'

Nettoyage de la configuration

Dans un premier temps, il faut nettoyer les définitions des ACL. En effet plusieurs d'entre-elles sont désormais intégrée directement dans le binaire. Supprimez les ACLs suivantes:

  • manager
  • localhost
  • to_localhost

Si vous venez d'une version 2.7 il faut également supprimer

  • all

Configuration de squidGuard dans squid

Quelques options ont changé, notamment pour le nombre de fils squidGuard, qui ne sont plus gérés de manière statique mais dynamique. Editez la lignes url_rewrite_children de la manière suivante (à adapter):

url_rewrite_children 128 startup=16 idle=10 concurrency=0

Le premier nombre est toujours le nombre maximal. startup définit le nombre de fils au démarrage, idle le nombre de fils en spare et concurrency le nombre de requêtes traitées en parallèle via des threads (avec squidGuard il faut mettre 0)

C'est tout !

Si vous n'arrivez pas à démarrer, il se peut que ce soit d'autres options que je n'ai pas activées, dans ce cas tapez:

<path>/squid -k <path>/squid.conf -N -d 10

Cela permettra de charger le service en foreground et de voir ce qui bloque. N'hésitez pas à ajouter des commentaires qui permettent de compléter l'article !