Utiliser des fichiers templates, paquets, services et règles de pare-feu

Maître ou conteneur : <files> ou <containers>

Creole propose un système de conteneurs permettant d'isoler certains services du reste du système.

C'est dans le dictionnaire que les conteneurs sont définis et associés à des services.

Si le conteneur n'est pas spécifié, les services seront installés sur le serveur hôte, le maître.

Pour distinguer les fichiers templates, les paquets et les services de l'hôte de ceux mis dans le conteneur, il faut utiliser deux balises différentes.

Sur le serveur hôte, les fichiers templates, les paquets et les services sont dans une balise <files>.

Dans le cas des conteneurs, il faut spécifier un ensemble de balises <container> à l'intérieur d'une balise <containers>. L'utilisation de la balise <all> permet d'appliquer des balises à tous les <container>. En mode non conteneur cette balise s'applique sur le maître. Pour inhiber ce comportement il faut rajouter l'attribut instance_mode='when_container'.

La balise <container> doit obligatoirement contenir l'attribut name pour renseigner le nom du conteneur.

Lors de la première déclaration d'un conteneur l'attribution d'un identifiant unique (attribut id) est obligatoire.

La valeur de cet identifiant permettra de calculer l'adresse IP du conteneur.

Les groupes de conteneurs permettent de réunir des services afin de limiter le nombre de conteneurs.

Ils se déclarent de la même manière que les autres conteneurs. L'affectation d'un conteneur existant à un groupe de conteneurs s'effectue en utilisant l'attribut group.

Les ID de groupes de conteneurs de 50 à 99 sont réservés pour les groupes de conteneurs EOLE.

ID

Nom du groupe conteneur

Conteneurs inclus (AmonEcole/Eclair)

50

bdd

annuaire, mysql

51

reseau

web, mail

52

partage

fichier, dhcp, ftp

53

internet

proxy, dns

54

ltspserver

dhcp, ltsp

55

ltspapps

application

Les identifiants de conteneur supérieurs à 100 sont utilisables par les contributeurs.

Remarque

La liste des identifiants des conteneurs et des groupes de conteneurs déjà affectés est actuellement maintenue sur le wiki EOLE à l'adresse :

http://dev-eole.ac-dijon.fr/projects/creole/wiki/ContainersID

Exemple

1
<creole>
2
    <files>
3
    </files>
4
    <containers>
5
        <all>
6
            <host hostlist='web' name='web_url' ip='adresse_ip_br0' instance_mode='when_container' comment="Serveur web sur l'IP de l'interface 0" />
7
            <file filename='/etc/fichier_cible' instance_mode='when_container' />
8
        </all>
9
        <container name='web' id='15'>
10
            [...]
11
        </container>
12
        <container name='reseau' id='51'/>
13
        <!-- affectation du conteneur web au groupe de conteneurs reseau -->
14
        <container name='web' group='reseau'/>
15
    </containers>
16
    [...]

Paquets : <package>

Creole permet de spécifier les paquets à installer pour profiter d'un nouveau service.

A l'instanciation de la machine, les paquets spécifiés seront installés.

Pour cela, il faut utiliser la balise <package> avec comme contenu le nom du paquet.

Les attributs de la balise <package>

  • l'attribut instance_mode permet de définir un comportement en fonction de la présence du mode conteneur ou non : when_container, when_no_container, always (par défaut).

Attention

Pour spécifier plusieurs paquets, il faut obligatoirement écrire une balise <package> par paquet.

Fichiers templates : <file>

Les fichiers templates sont définis dans la balise <file>.

Les attributs de la balise <file>

  • l'attribut name (obligatoire) indique l'emplacement où sera copié le fichier ;
  • l'attribut source permet d'indiquer un nom de fichier source différent de celui de destination ;
  • l'attribut mode permet de spécifier des droits à appliquer au fichier de destination ;
  • l'attribut owner permet de forcer le propriétaire du fichier ;
  • l'attribut group permet de forcer le groupe propriétaire du fichier ;
  • l'attribut filelist permet de conditionner la génération du fichier suivant des contraintes ;
  • si l'attribut rm vaut True, le fichier de destination sera supprimé si il est désactivé via une filelist ;
  • si l'attribut mkdir vaut True, le répertoire destination sera créé si il n'existe pas ;
  • l'attribut instance_mode permet de définir un comportement en fonction de la présence du mode conteneur ou non : when_container, when_no_container, always (par défaut) ;
  • l'attribut del_comment engendre la suppression des lignes vides et des commentaires dans le fichier cible afin d'optimiser sa templatisation (exemple : del_comment='#').

Truc & astuceRenommage d'un template

L'attribut name contient toujours le chemin complet du fichier de destination (par exemple /etc/hosts).

Par défaut, le fichier template doit s'appeller de la même façon que le fichier de destination (ici : hosts).

Si deux templates ont le même nom, il faudra spécifier le nom du template renommé avec l'attribut source.

Services : <service>

Les dictionnaires Creole intègrent un système de gestion de services GNU/Linux (scripts d'init) qu'il est possible d'utiliser pour activer/désactiver des services non gérés par le module EOLE installé.

Services non gérés : services non référencés dans le système de gestion des services de Creole. Ils ne sont jamais modifiés. Ils restent dans l'état dans lequel Ubuntu les a installés ou dans celui que leur a donné l'utilisateur. Les services non gérés sont généralement les services de base Ubuntu (rc.local, gpm, ...) et tous ceux pour lesquels le module ne fournit pas de configuration spécifique (mdadm, ...).

Services désactivés : services systématiquement arrêtés et désactivés lors des phases d'instance et de reconfigure. Les services concernés sont généralement liés à une réponse à "non" dans l'interface de configuration du module.

Services activés : services systématiquement activés et (re)démarrés lors des phases d'instance et de reconfigure. Les services concernés sont ceux nécessaires au fonctionnement du module.

Les services à activer/désactiver se définissent dans le dictionnaire grâce à la balise <service>.

Les attributs de la balise <service>

  • l'attribut servicelist (chaîne de caractères alphanumériques) permet de conditionner le démarrage ou l'arrêt d'un service suivant des contraintes ;
  • l'attribut method permet de définir la façon de gérer les services : systemd (par défaut), apache et restartonly ;
  • l'attribut hidden (booléen) indique si le service doit être activé ou non, cet attribut est particulièrement utile lors de la redéfinition d'un service, en particulier pour forcer sa désactivation ;
  • si l'attribut redefine vaut True, cela permet de redéfinir un service déjà défini dans un autre dictionnaire ;
  • l'attribut instance_mode permet de définir un comportement en fonction de la présence ou non du mode conteneur : when_container, when_no_container, always (par défaut).

RemarqueGestion des services

systemd est, dorénavant, la seule méthode valide pour la gestion des services Linux.

Sur EOLE 2.7.2, la méthode restartonly a été introduite afin de redémarrer les services de base qui nécessitent une continuité, tels que networkd, rsyslog, ssh, cron...

La balise service peut également être utilisée pour activer/désactiver des configurations de site web apache2 (commandes : a2ensite/a2dissite).

Comme pour les services système, l'activation d'un site peut être conditionnée par une servicelist.

On peut ainsi gérer le lien symbolique suivant : /etc/apache2/sites-enabled/monsite avec :

<service method='apache' servicelist='siteperso'>monsite</service>

Le fichier de configuration monsite étant stocké dans /etc/apache2/sites-available/.

Attention

Pour spécifier plusieurs services, il faut obligatoirement écrire une balise <service> par service.

Truc & astuce

Une règle eole-firewall peut être liée à un service, ainsi quand un service sera désactivé la règle le sera également.

Hôtes : <host>

La balise <host> permet de déclarer des hôtes à ajouter dans le fichier /etc/hosts du maître et/ou des conteneurs.

Les attributs de la balise <host>

  • l'attribut name contient le nom d'une variable contenant des noms d'hôtes (FQDN), simple ou multi, obligatoire ;
  • l'attribut ip contient le nom d'une variable contenant les adresses IPs associées aux noms, obligatoire ;
  • l'attribut hostlist permet d'exclure cette entrée suivant des contraintes, optionnel ;
  • l'attribut crossed combine toutes les adresses avec tous les noms d'hôtes. L'utilisation de False génère une association 1 nom d'hôte/1 adresse IP. Doit être False dans le cas d'utilisation de variables ayant une relation maître/esclave, False, True (par défaut) ;
  • l'attribut instance_mode permet de définir un comportement en fonction de la présence du mode conteneur ou non : when_container, when_no_container, always (par défaut) ;
  • l'attribut comment permet l'ajout d'une ligne de commentaire avant la(les) entrée(s), optionnel.

Exemple

1
<containers> 
2
    <container name="proxy" id='20'>
3
        <package>eole-proxy-pkg</package> 
4
        <service>squid</service>
5
        <host hostlist='auth_smb' name='nom_serveur_smb' ip='ip_serveur_smb' instance_mode='when_container' crossed='False' comment="serveurs d'authentification SMB"/>
6
    </container>
7
</containers>

Montage d'une partition <disknod>

La balise <disknod> permet de le montage d'une partition du maître à l'intérieur d'un conteneur.

Par exemple, le montage de la partition /home dans le conteneur fichier.

Les attributs de la balise <disknod>

La balise <disknod> ne possède pas d'attribut spécifique.

Exemple

1
<containers>
2
    <container name='fichier' id='12'>
3
        <disknod>/home</disknod>
4
    </container>
5
</containers>

Attention

Pour être pris en compte il faut nécessairement arrêter le conteneur avec la commande CreoleService lxc stop avant de faire un gen_conteneurs.

Montage d'un répertoire <fstab>

La balise <fstab> sert à déclarer le montage d'un répertoire (qui n'est pas une partition) à l'intérieur d'un conteneur.

Par exemple, le montage du répertoire /home/mail/ du maître dans le conteneur mail.

Les attributs de la balise <fstab>

  • l'attribut name contient le chemin du répertoire à monter ou le nom d'une variable fournissant cette information ;
  • si l'attribut name_type vaut SymLinkOption cela indique que le chemin sera défini dans la variable indiquée dans l'attribut name ;
  • l’attribut optionnel mount_point permet de définir le point de montage à l’intérieur du conteneur, par défaut c’est la valeur de l’attribut name ;
  • si l’attribut mount_point_type vaut SymLinkOption cela indique que le chemin sera défini dans la variable indiquée dans l'attribut mount_point ;
  • l’attribut optionnel options permet de définir les options de montage ;
  • l'attribut fstablist (chaîne de caractères alphanumériques) permet de conditionner le montage du répertoire suivant des contraintes.

Exemple

1
<containers>
2
    <container name='mail' id='13'>
3
        <fstab name='/home/mail'/>
4
    </container>
5
</containers>

Attention

Pour être pris en compte il faut nécessairement arrêter le conteneur avec la commande CreoleService lxc stop avant de faire un gen_conteneurs.

Autorisations pour le pare-feu eole-firewall : <service_access> et <service_restriction>

eole-firewall est conçu pour gérer les flux réseau d'un module EOLE.

Il permet d'autoriser des connexions :

  • de l'extérieur vers le maître ;
  • de l'extérieur vers un conteneur.

Techniquement, ces autorisations se traduisent par des règles iptables et, si nécessaire, des connexions TCP Wrapper[1] et l'activation de modules noyau.

Attentioneole-firewall et ERA

Pour les modules Amon et AmonEcole, les règles d'eole-firewall ne s'appliquent pas. Seules les règles ERA du modèle choisi s'appliquent.

Les doublons

S'il y a plusieurs règles sur une interface/port, c'est la dernière règle qui est appliquée .

Par exemple, dans le dictionnaire 20_apache.xml, on redirige le port 80 dans le conteneur mais dans 25_nginx.xml, on ouvre le port 80. Si ces deux dictionnaires sont installés simultanément, c'est l'ouverture du port qui est appliquée.

L'activation des règles

Si le nom du service correspond a un service déclaré dans le conteneur et que celui-ci est désactivé, alors les accès/restrictions ne s'appliquent pas.

Si ip est une variable et que cette variable n'existe pas ou qu'elle est désactivée, la règle ne s'applique pas.

De la même façon pour un port/tcpwrapper avec une variable qui n'existe pas, aucune règle ne s'applique.

Remarque

Malgré son nom, l'attribut service des balises service_access et service_restriction doit être renseigné avec le nom de la servicelist associée au service et non avec le nom du service lui-même.

Si aucune servicelist permettant de désactiver le service n'existe, l'attribut peut être rempli librement.

Autoriser un port (XXX) pour un service donné (YYY) :

<service_access service='YYY'>

  <port>XXX</port>

</service_access>

Dans la balise port il est également possible de spécifier le protocole (par défaut c'est TCP).

Par exemple :

<service_access service='ntp'>

  <port protocol='udp'>123</port>

</service_access>

Avec tcpwrapper :

<tcpwrapper>YYY</tcpwrapper>

Port avec variable (ZZZ) :

<port port_type="SymLinkOption">ZZZ</port>

List (WWW) pour port/tcpwrapper :

<port service_accesslist="WWW">XXX</port>

<tcpwrapper service_accesslist="WWW">YYY</tcpwrapper>

ExempleRègles eole-firewall extraites du dictionnaire /usr/share/eole/creole/dicos/01_network.xml. pour le service sshd

1
<service_access service='sshd'>
2
    <port>22</port>
3
    <tcpwrapper>sshd</tcpwrapper>
4
</service_access>
5
<service_restriction service='sshd'>
6
    <ip interface='eth0' netmask='netmask_ssh_eth0' netmask_type='SymLinkOption' ip_type='SymLinkOption'>ip_ssh_eth0</ip>
7
    <ip interface='eth1' netmask='netmask_ssh_eth1' netmask_type='SymLinkOption' ip_type='SymLinkOption'>ip_ssh_eth1</ip>
8
    <ip interface='eth2' netmask='netmask_ssh_eth2' netmask_type='SymLinkOption' ip_type='SymLinkOption'>ip_ssh_eth2</ip>
9
    <ip interface='eth3' netmask='netmask_ssh_eth3' netmask_type='SymLinkOption' ip_type='SymLinkOption'>ip_ssh_eth3</ip>
10
    <ip interface='eth4' netmask='netmask_ssh_eth4' netmask_type='SymLinkOption' ip_type='SymLinkOption'>ip_ssh_eth4</ip>
11
</service_restriction>

Si on ne définit que les service_access, le port est ouvert pour tout le monde sur toutes les interfaces.

Pour ajouter des restrictions il faut mettre :

<service_restriction service='YYY'>

  <ip interface='eth0'>1.1.1.1</ip>

<service_restriction>

Dans ce cas, seule l'adresse IP 1.1.1.1 peut accéder à ce service.

Il est possible d'utiliser des variables :

<ip interface='auto' ip_type='SymLinkOption'>variable</ip>

Il est possible d'utiliser un netmask :

<ip interface='eth0' netmask="255.255.255.0" ip_type='SymLinkOption'>variable</ip>

<ip interface='eth1' netmask="variable_netmask" netmask_type='SymlinkOption' ip_type='SymLinkOption'>variable</ip>

Le paramètre interface peut être :

  • ethX (pour une interface donnée) ;

  • all (pour toutes les interfaces) ;

  • auto (calcule de l'interface via la route) ;

  • une variable (avec l'ajout de interface_type="SymlinkOption").

Il est aussi possible d'ajouter une service_restrictionlist aux balises ip.

ExempleRègles eole-firewall extraites du dictionnaire /usr/share/eole/creole/dicos/01_network.xml pour le service genconfig

1
<service_access service='genconfig'>
2
    <port>7000</port>
3
</service_access>
4
<service_restriction service='genconfig'>
5
    <ip interface='eth0' netmask='netmask_ssh_eth0' netmask_type='SymLinkOption' ip_type='SymLinkOption'>ip_ssh_eth0</ip>
6
    <ip interface='eth1' netmask='netmask_ssh_eth1' netmask_type='SymLinkOption' ip_type='SymLinkOption'>ip_ssh_eth1</ip>
7
    <ip interface='eth2' netmask='netmask_ssh_eth2' netmask_type='SymLinkOption' ip_type='SymLinkOption'>ip_ssh_eth2</ip>
8
    <ip interface='eth3' netmask='netmask_ssh_eth3' netmask_type='SymLinkOption' ip_type='SymLinkOption'>ip_ssh_eth3</ip>
9
    <ip interface='eth4' netmask='netmask_ssh_eth4' netmask_type='SymLinkOption' ip_type='SymLinkOption'>ip_ssh_eth4</ip>
10
</service_restriction>
11

Complément sur les attributs

instance_mode

L'attribut instance_mode remplace les anciens attributs in_container et container_only.

Une ressource, qu'elle soit sur le maître ou dans un conteneur, peut n'être à générer que si le mode conteneur est activé ou désactivé :

instance_mode

mode conteneur

mode non conteneur

when_container

when_no_container

always (default)

Les balises acceptant l’attribut instance_mode sont actuellement :

  • package ;
  • file ;
  • service ;
  • host ;
  • fstab.

Exemple récapitulatif

ExempleFichiers templates, paquets et services locaux ou dans un conteneur

1
<containers>
2
<!-- dans le conteneur mon_reverseproxy -->
3
<container name="mon_reverseproxy" id='101'>
4
    <package>nginx</package>
5
    <service servicelist="myrevprox">nginx</service>
6
    <file filelist='myrevprox' name='/etc/nginx/sites-enabled/default' source='nginx.default'/>
7
    <file filelist='myrevprox' name='/var/www/nginx-default/nginx.html' rm='True'/>
8
</container>
9
</containers>
10
<files>
11
<!-- sur le maître-->
12
<service>ntp</service>
13
<file name='/etc/ntp.conf/>
14
<file name='/etc/default/ntpdate' owner='ntp' group='ntp' mode='600'/>
15
<file name='/etc/strange/host' source='strangehost.conf' mkdir='True'/>
16
</files>