http://linux-vserver.org/api.php?action=feedcontributions&user=Glenn&feedformat=atomLinux-VServer - User contributions [en]2024-03-19T08:05:16ZUser contributionsMediaWiki 1.20.2http://linux-vserver.org/User_talk:PowerfoxUser talk:Powerfox2011-11-20T10:08:50Z<p>Glenn: more anti-spam</p>
<hr />
<div>Wow, nice work with the spam protection... Keep it up :-) --[[User:Daniel15|<span style="color: darkblue; font-weight: bold;">Daniel15</span>]] <big>(</big><sup>[[User talk:Daniel15|Talk]]</sup>/<sub>[[Special:Contributions/Daniel15|Contribs]]</sub><big>)</big> 13:14, 10 December 2006 (CET)<br />
<br />
Hi Daniel - thank's 4 feedback. --[[User:Powerfox|PowerFox]] 13:16, 10 December 2006 (CET)<br />
<br />
==Anti-spam==<br />
Hi Powerfox<br />
<br />
Please also look at these pages:<br />
*Automatically applies restrictions to Tor exit nodes.:<br />
*http://www.mediawiki.org/wiki/Extension:TorBlock<br />
*http://meta.wikimedia.org/wiki/Category:Open_proxies_blocked_on_all_participating_projects<br />
<br />
*The SpamBlacklist extension prevents edits that contain URLs whose domains match regular expression patterns defined in specified files or wiki pages:<br />
*http://www.mediawiki.org/wiki/Extension:SpamBlacklist<br />
*http://meta.wikimedia.org/wiki/Spam_blacklist<br />
*http://meta.wikimedia.org/wiki/Category:Anti_Spam<br />
--[[User:Glenn|Glenn]] 10:08, 20 November 2011 (UTC)</div>Glennhttp://linux-vserver.org/User_talk:PowerfoxUser talk:Powerfox2011-11-12T13:48:33Z<p>Glenn: Combat web-spam</p>
<hr />
<div>Wow, nice work with the spam protection... Keep it up :-) --[[User:Daniel15|<span style="color: darkblue; font-weight: bold;">Daniel15</span>]] <big>(</big><sup>[[User talk:Daniel15|Talk]]</sup>/<sub>[[Special:Contributions/Daniel15|Contribs]]</sub><big>)</big> 13:14, 10 December 2006 (CET)<br />
<br />
Hi Daniel - thank's 4 feedback. --[[User:Powerfox|PowerFox]] 13:16, 10 December 2006 (CET)<br />
<br />
==Combat web-spam==<br />
Please try to make an account on this wiki to see how they combat webspam:<br />
* http://multicopter.org<br />
--[[User:Glenn|Glenn]] 13:48, 12 November 2011 (UTC)</div>Glennhttp://linux-vserver.org/User_talk:DerjohnUser talk:Derjohn2011-11-12T13:04:59Z<p>Glenn: +Combat web-spam</p>
<hr />
<div><br />
==Combat web-spam==<br />
Please try to make an account on this wiki to see how they combat webspam:<br />
* http://multicopter.org<br />
--[[User:Glenn|Glenn]] 13:04, 12 November 2011 (UTC)</div>Glennhttp://linux-vserver.org/User_talk:HollowUser talk:Hollow2011-11-12T13:04:25Z<p>Glenn: +Combat web-spam</p>
<hr />
<div><br />
== Migrated pages ==<br />
<br />
I have migrated these pages from the old to the new wiki:<br />
* [[Namespaces/fr]]<br />
* [[Namespaces]]<br />
* [[Installation on Slackware]]<br />
* [[Vservers and X]]<br />
--[[User:Jze|Jze]] 13:47, 27 March 2009 (CET)<br />
<br />
== Syntax highlighting ==<br />
It would be nice if you could install this extension in the VServer-Wiki: http://www.mediawiki.org/wiki/Extension:SyntaxHighlight_GeSHi<br />
<br />
Scripts would be much better readable with very little effort. --[[User:Jze|Jze]] 13:47, 27 March 2009 (CET)<br />
<br />
== SVG support ==<br />
Is it possible to activate SVG support for this wiki? I have redrawn the "computer-memory-pyramid" figure from the old wiki. Visualization is always helpfull and much easier to editable with vector graphics. --[[User:Jze|Jze]] 13:47, 27 March 2009 (CET)<br />
<br />
== Extension:ParserFunctions ==<br />
<br />
Can you also install the Extension:ParserFunctions?<br />
http://www.mediawiki.org/wiki/Extension:ParserFunctions<br />
<br />
It can be used to generate language selection boxes like this [[Template:Language]] with the existing languages automatically shown. --[[User:Jze|Jze]] 14:14, 27 March 2009 (CET)<br />
<br />
==Combat web-spam==<br />
Please try to make an account on this wiki to see how they combat webspam:<br />
* http://multicopter.org<br />
--[[User:Glenn|Glenn]] 13:04, 12 November 2011 (UTC)</div>Glennhttp://linux-vserver.org/Paper/frPaper/fr2011-11-12T08:49:31Z<p>Glenn: topsort</p>
<hr />
<div>{{Languages|Paper}}<br />
<br />
==Abstract ==<br />
Concept logiciel basé sur les ''Security Contextes'' permet la création d'une multitude de serveurs virtuels Privés (VPS) tournant simultanément sur un même serveur physique à pleine vitesse, en partageant efficacement les ressources matérielles.<br />
Un VPS offre un environnement quasiment identique à celui d'un serveur Linux conventionnel. Tous les services, comme ssh, mail, Web, bases de données, peuvent être lancés dans un tel VPS, sans aucune modification (ou, dans certains cas, des modifications mineures), exactement comme avec n'importe quel autre serveur réel.<br />
<br />
Chaque serveur virtuel possède sa propre base utilisateurs et son mot de passe root. Il est isolé de tous les autres serveurs virtuels, sauf en ce qui concerne les ressources matérielles, qui sont partagées par tous les serveurs virtuels.<br />
<br />
== Introduction ==<br />
Au fur et à mesure des années, les micro ordinateurs sont devenus suffisemment puissant pour utiliser la virtualisation comme méthode pour donner l'illusion d'avoir une multitude de petites machines virtuelles, chacune d'elle tournant avec une instance différente de n'importe quel système d'exploitation.<br />
<br />
Il existe plusieurs types de Machines Virtuelles (VMs) dont les fonctionnalités sont similaires, mais qui diffèrent dans le degré d'abstraction et les méthodes utilisées pour la virtualisation.<br />
<br />
La plupart d'entre elles "émulent" une ressource matérielle réelle ou fictive, qui, à son tour, fait usage de "vraies" ressources du système Hote (la machine qui fait tourner les VMs). Cette approche, utilisée par la plupart des émulations système (comme QEMU[U1], Bochs[U2], ... permet à l'émulateur d'éxécuter n'importe quel système d'exploitation, même pour une architecture différente (CPU et matérielle). Pas besoin de modifier le système d'exploitation Invité, puisqu'il n'est pas conscient de s'éxécuter sur autre chose qu'un vrai matériel.<br />
<br />
Quelques émulations systèmes ont besoin d'un petit nombre de modifications ou de pilotes de périphériques spécifiques sur le système Hote ou le système Invité pour améliorer les performances, et minimiser le grignotage superflu de ressources système qui passe dans les systèmes de cache et de médiation entre le système Hote et le système Invité. Bien que cela améliore sensiblement l'efficacité de ces solutions, les ressources perdues sont toujours notables (par exemple dans UML[U3] et Xen[U4]).<br />
<br />
Supposez par contre que les systèmes d'exploitation à lancer ne sont pas différents ... La plupart des applications qui tournent sur un serveur n'ont pas besoin d'acceder au matériel ou à du code au niveau noyau, et pourraient donc partager une machine avec les autres, si l'on pouvait les séparer et les isoler ...<br />
<br />
== Le Concept ==<br />
A la base, un serveur Linux est constitué de trois blocs constitutifs: Le matériel, le Noyau, et les Applications. Le Matériel dépend habituellement du fournisseur ou de l'administrateur système, et, bien qu'ayant une grande influence sur les performances globales, ne peut pas être changé facilement, et diffère sensiblement d'une configuration à l'autre.<br />
<br />
Un role de base du noyau consiste à créer une couche d'abstraction au dessus du matériel pour permettre aux processus (Applications) de travailler avec des ressources (Données) sans connaitre les détails du matériel qui se trouve en dessous. Idéalement, ces processus sont complètement agnostiques vis-à-vis du matériel, écrit dans un langage interprété, et ne nécessitant par conséquent aucun savoir faire spécifique au matériel.<br />
<br />
Puisqu'un système possède assez de ressources pour faire tourner environ dix fois plus d'applications que nécessaire sur un serveur Linux traditionnel, pourquoi ne pas placer sur celui-ci une dizaine de serveurs, qui vont partager les ressources d'une manière efficace ?<br />
<br />
La plupart des serveurs d'application (par exemple httpd) considère qu'il est la seule application à fournir un service particulier, et d'habitude, va donc supposer une organisation particulière au niveau du système de fichiers, et de l'environnement. Cela implique que deux services identiques tournant sur un même serveur physique, mais différent simplement au niveau de leur adresse IP, par exemple, doivent être coordonnées. Cela demande typiquement pas mal de boulot pour l'administrateur système, et cela peut conduire à un stabilité réduite du système et de la sécurité.<br />
<br />
Le concept de base de la solution Linux-VServer est de séparer l'environnement en user space (espace utilisateur) en trois unités distinctes (appellées parfois VPS, ou Virtual Private Server), de telle manière que chaque VPS ressemblera à un vrai serveur vis-à-vis des processus qu'il contient.<br />
<br />
Bien que différentes Distributions Linux utilisent des noyaux modifiées (parfois lourdement) pour assurer le support de telle ou telle fonctionnalité, ou matériel, la plupart des distributions Linux ne sont pas liées irrévocablement à un noyau linux particulier.<br />
<br />
Linux-VServer utilise cela pour donner à plusieurs distributions, la possibilité de se lancer au dessus d'un seul noyau, partagé, sans accès direct au matériel, et partager les ressources d'une manière très efficace.<br />
<br />
== Infrastructure Existante ==<br />
Les noyaux Linux récents fournissent déjà de nombreuses fonctions de sécurité qui sont utilisées par Linux-Vserver pour fonctionner, telles que le Système de Privileges Linux, les limites de ressource, les attributs de fichier et l'environnement chroot. Les sections suivantes vous donneront un court aperçu de chacune d'entre elles. <br />
=== Le système de Privileges (Capabilities) Linux ===<br />
En science informatique, un privilege est un jeton utilisé par un processus pour prouver qu'il est autorisé à faire une opération sur un objet. Le Système de privileges Linux est basé sur les "Privileges POSIX", un concept légèrement similaire, conçu pour diviser les privilèges root puissants en un ensemble de privilèges distincts.<br />
<br />
==== Privileges POSIX ====<br />
Un processus possède trois champs de bits appelés les privileges héritables (I - "Inheritable"), permises (P), et effectives (E). Chaque privilege est implémenté dans un bit de chacun de ces champs, bit qui est soit défini soit non-défini.<br />
<br />
Quand un processus essaie de faire une opération privilégiée, le système d'exploitation va vérifier les bits appropriés dans l'ensemble effectif des processus (au lieu de vérifier si l'uid respectif du processus est 0 comme il le fait habituellement).<br />
<br />
Par exemple, quand un processus essaie de modifier l'horloge, le noyau Linux va vérifier que ce processus a le bit CAP_SYS_TIME (actuellement le bit 25) parmi ses privileges effectives.<br />
<br />
L'ensemble permis d'un processus indique les privileges que celui-ci peut utiliser. Le processus peut avoir des privileges définies dans l'ensemble permis qui ne sont pas dans l'ensemble effectif.<br />
<br />
Ceci indique que le processus a temporairement désactivé ce privilege. Un processus n'est autorisé à définir un bit dans son ensemble effectif que si ce bit est disponible dans son ensemble permis.<br />
<br />
La distinction entre privileges effectif et permis existe pour que les processus puissent réaliser des opérations qui nécessitent des privilèges.<br />
<br />
Les privileges héritables sont les privileges du processus courant qui peuvent être hérités par un programme exécuté par ce dernier. L'ensemble permis d'un processus est masqué contre l'ensemble héritable pendant exec().<br />
<br />
Rien de spécial ne se produit durant fork() ou clone().<br />
<br />
Les processus fils ou les threads obtiennent une copie exacte des privileges du processus parent.<br />
<br />
L'implémentation dans Linux s'arrête là, alors que les privileges POSIX[U5] requièrent l'ajout d'un ensemble de privileges aux fichiers, pour remplacer le flag SUID (au moins pour les exécutables).<br />
<br />
==== Vue d'ensemble des privileges ====<br />
La liste des privileges POSIX utilisées avec Linux est longue, et les 32 bits disponibles sont presques tous utilisés. Bien que la liste détaillée de ces privileges puisse être trouvée dans /usr/include/linux/capability.h sur la plupart des systèmes Linux, une vue d'ensemble des privileges importantes est donnée ici.<br />
{|class="wikitablenowrap"<br />
| 0|| CAP_CHOWN || change le propriétaire et le groupe du fichier<br />
|-<br />
| 5|| CAP_KILL|| envoie un signal au processus avec un ID utilisateur différent, réel ou effectif<br />
|-<br />
| 6|| CAP_SETGID|| permet le passage de setgid(2), setgroups(2), et de gids forgés sur les sockets<br />
|-<br />
| 7|| CAP_SETUID|| permet le passage de set*uid(2) et d'uids forgés sur les sockets<br />
|-<br />
| 8|| CAP_SETPCAP|| transfert/déplace tout privilege de l'ensemble permis vers/depuis n'importe quel pid<br />
|-<br />
| 9|| CAP_LINUX_IMMUTABLE|| permet la modification des attributs de fichier S_IMMUTABLE et S_APPEND<br />
|-<br />
| 11|| CAP_NET_BROADCAST|| permet la diffusion et l'écoute en multicast<br />
|-<br />
| 12|| CAP_NET_ADMIN|| permet la configuration de l'interface, le pare-feux IP, le masquerading, l'accounting, le débugage de sockets, les tables de routage, la liaison sur n'importe quelle adresse, l'entrée dans le mode de promiscuité, le multicasting...<br />
|-<br />
| 13|| CAP_NET_RAW|| permet l'utilisation des sockets RAW et PACKET<br />
|-<br />
| 16|| CAP_SYS_MODULE|| ajoute et retire des modules noyau<br />
|-<br />
| 18|| CAP_SYS_CHROOT|| permet chroot(2)<br />
|-<br />
| 19|| CAP_SYS_PTRACE|| permet ptrace() sur n'importe quel processus<br />
|-<br />
| 21|| CAP_SYS_ADMIN|| la liste serait trop longue, ceci permet en gros de faire tout ce qui n'est pas mentionné dans les autres privileges<br />
|-<br />
| 22|| CAP_SYS_BOOT|| permet reboot(2)<br />
|-<br />
| 23|| CAP_SYS_NICE|| permet l'élévation des privilèges et la modification de la priorité des autres processus, en modifiant l'ordonnanceur<br />
|-<br />
| 24|| CAP_SYS_RESOURCE|| passe outre les limites de ressource, de quota, l'espace réservé sur un système de fichier...<br />
|-<br />
| 27|| CAP_MKNOD|| permet les aspects privilégiés de mknod(2)<br />
|}<br />
<br />
Voir également les Exemples [E01],[E02], et [E03].<br />
<br />
=== Limite des Ressources ===<br />
Vous pouvez limiter les ressources de chaque processus en spécifiant une limite pour chaque ressource. A la manière des privileges Linux, il existe deux types de limites, l'une Douce, l'autre Dure.<br />
<br />
La limite Douce est la valeur que le noyau imposera pour cette ressource à un processus. Un utilisateur non privilégié pourra régler la limite Douce n'importe où en dessous de la valeur Dure. Seul l'utilisateur root pourra re-hausser la limite Dure.<br />
<br />
==== Apercu des Ressources Limit-ables ====<br />
La liste des ressources qui peuvent être limitées se trouve dans le fichier /usr/include/asm/resource.h sur la plupart des systèmes Linux.<br />
{|class="wikitablenowrap"<br />
| 0|| RLIMIT_CPU || Temps CPU en secondes. un signal SIGXCPU est envoyé au processus qui a atteind la limite Douce, et un SIGKILL pour la limite Dure.<br />
|-<br />
| 4|| RLIMIT_CORE || Taille maximale d'un fichier core.<br />
|-<br />
| 5|| RLIMIT_RSS || Nombre de pages maximum qu'un processus peut utiliser (en RAM)<br />
|-<br />
| 6|| RLIMIT_NPROC || Nombre maximum de processus autorisés à l'utilisateur réel du processus appelant.<br />
|-<br />
| 7|| RLIMIT_NOFILE || Spécifie la valeur +1 pour le nombre maximum de descripteurs de fichiers ouvert par un processus.<br />
|-<br />
| 8|| RLIMIT_MEMLOCK || Nombre maximum de pages mémoire virtuelle autorisées à être vérouillées en RAM à l'aide des appels mlock() ou mlockall().<br />
|-<br />
| 9|| RLIMIT_AS || Nombre maximum de pages de mémoire virtuelle disponible pour un processus.<br />
|}<br />
<br />
(Limite de l'espace d'adressage) <br />
<br />
Voir aussi les Exemples [E11], et [E12].<br />
<br />
=== Attributs de Fichiers ===<br />
Auparavant, cette fonctionnalité n'était disponible qu'avec ext2, mais maintenant tous les systèmes de fichiers majeurs implémentent un ensemble d'Attributs de fichiers de base, qui permettent le paramétrage de certaines propriétés. Voici de nouveau un bref aperçu des possibilités des attributs, et leur signification.<br />
<br />
{|class="wikitablenowrap"<br />
| s SECRM || Lorsqu'un fichier avec cet attribut est détruit, les blocs qui le composent sont mis à zéro et re-écrit sur le disque.<br />
|-<br />
| u UNRM || Lorsqu'un fichier avec cet attribut est détruit, son contenu est sauvegardé.<br />
|-<br />
| c COMPR || Un fichier marqué avec cet attribut est automatiquement compressé à l'écriture et décompressé à la lecture. (pas encore implémenté)<br />
|-<br />
| i IMMUTABLE || Un fichier avec cet attribut ne pourra pas être modifié: Impossible de le renommer ou de le détruire, impossible de créer un lien vers ce fichier, ni d'écrire une donnée de plus vers ce fichier. <br />
|-<br />
| a APPEND || Un fichier avec cet attribut ne pourra être ouvert qu'en mode ajout.<br />
|-<br />
| d NODUMP || Si cet attribut de fichier est mis, le fichier n'est pas candidat à un backup via l'utilitaire "dump".<br />
|-<br />
| S SYNC || Les mises à jour vers ce fichier se feront de manière synchrone.<br />
|-<br />
| A NOATIME || Empêche la mise à jour de l'enregistrement atime lors d'un accès ou d'une modification de fichier.<br />
|-<br />
| t NOTAIL || Un fichier avec l'attribut t n'aura pas de fragment bloc en fin de fichier fusionné avec un autre fichier.<br />
|-<br />
| D DIRSYNC || Les modifications apportés à ce répertoire seront écrites de manière synchrones. <br />
|}<br />
<br />
Voir aussi les Exemples [E13] et [E14].<br />
<br />
=== La Commande chroot(1) ===<br />
chroot permet de lancer une commande en changeant le répertoire racine dans lequel il va s'éxécuter. Cela signifie que tout parcours du système de fichiers à partir de la racine '/' se fera à partir de la racine substituée et non pas à partir de la racine originelle.<br />
<br />
Bien que le chroot Linux n'est pas très sécurisé, son utilisation augmente l'isolation des processus par rapport au système de fichier, et, à condition de l'utiliser correctement, peut être utilisé pour "emprisonner" un processus, un utilisateur unique, ou un démon (service).<br />
<br />
Voir l'Exemple [E15]<br />
<br />
== Modifications Requises ==<br />
Ce chapitre décrit les modifications à apporter au noyau pour implémenter un mécanisme comme Linux-VServer.<br />
<br />
=== Séparation de Contextes ===<br />
La séparation telle que décrite dans la partie 'Concepts' nécessite quelques modifications au noyau pour permettre la notion de Contexte.<br />
<br />
Le but d'un tel "Contexte" est de cacher à un processus tout ce qui ne doit pas etre à sa portée, et empécher les interractions indésirables entre un processus appartenant à un contexte et un processus appartenant à un autre contexte.<br />
<br />
Cette séparation nécessite l'extension d'un certain nombre de structures de données pour qu'elles prennent en compte les contextes et fassent la différentiation entre deux uids identiques mais utilisés dans deux serveurs virtuels différents.<br />
<br />
De plus, nous avons besoin d'un contexte par defaut qui sera utilisé par le serveur hôte au démarrage, et pour éviter les problèmes liés à des suppositions érronées de certains outils en espace utilisateur (comme pstree) par exemple, l'idée comme quoi init existe toujours et a toujours l'uid 1.<br />
<br />
Pour simplifier l'administration, le Contexte de l'Hôte n'est pas traité différemment d'un autre contexte, en tout cas du point de vue de l'isolation des processus.<br />
<br />
Pour avoir un apercu global de tous les processus, un Spectateur spécial a été mis en place, qui est capable de capturer tous les processus d'un coup.<br />
Voir les Examples [E21],[E22] et [E23]<br />
<br />
=== Séparation Réseau ===<br />
Bien que les Contextes soient suffisant pour isoler un groupe de processus, un autre type d'isolation, ou plutot une limitation, est nécessaire pour confiner les processus dans un sous ensemble d'adresses réseau disponibles.<br />
<br />
Plusieurs problèmes doivent être pris en compte dans ce sens: par exemple, les appels système bind sur IPADDR_ANY doivent être traités d'une manière bien particulière.<br />
<br />
Actuellement, Linux-Vserver n'utilise pas les interfaces virtuelles (et ne les utilisera peut-être jamais), pour minimiser le cout supplémentaire qu'elles engendrent. De ce fait, l'attachement d'une socket et la transmission des packets ont été adaptés.<br />
<br />
Voir Example [E24]<br />
<br />
=== La Barrière Chroot ===<br />
Un problème majeur avec le chroot() de Linux aujourd'hui tient au fait que cette information est volatile, et changera au prochain appel système de chroot().<br />
<br />
Voici une façon simple pour sortir d'un environnement chrooté Créez tout d'abord un fichier, et retenez son descripteur. Puis chrootez dans un répertoire au même niveau ou un niveau au dessous de celui-ci. Cela a pour effet de faire descendre la racine' dans le système de fichiers. Ensuite, faites un appel à fchdir() sur le descripteur de fichiers pour sortir de cette nouvelle racine. Vous sortirez en même temps de l'ancienne racine, qui a été perdue suite au dernier appel système chroot().<br />
<br />
Alors que des méthodes exotiques étaient utilisées dans les anciennes versions de Linux-Vserver pour fixer ce problème, les versions récentes utilisent un marquage spécial, connu sous le nom de Barrière Chroot, placé sur le parent de tous les VPS pour prévenir toute modification non autorisée et sortie du confinement.<br />
<br />
=== Un plafond pour les Privileges ===<br />
L'implémentation actuelle des privileges Linux ne prend pas en compte les privileges POSIX sur les systèmes de fichiers. Si cela était le cas, les executables setuid et setgid seraient sécurisés. Pour conserver donc une bonne sécurité malgré cette contrainte, nous avons défini un plafond pour tous les processus d'un même contexte, et un masque de privileges additionnel pour chaque contexte a été aussi ajouté pour limiter à ce seul masque les processus qui appartiennent à ce contexte.<br />
<br />
La signification des privileges individuels (bits) pour ce masque est exactement identique à celui que permet l'ensemble des privileges.=== Isolation de Ressources ===<br />
<br />
=== Isolation de Ressources ===<br />
La plupart des ressources sont d'une certaine manière partagées à travers les différents contextes; certaines requièrent une isolation plus importante que les autres, soit pour éviter les problèmes de sécurité, ou pour permettre une meilleure comptabilité de l'usage des ressources;<br />
<br />
Ces ressources sont:<br />
* mémoire partagée, IPC<br />
* PID et User ID<br />
* Drapeau xid sur les fichiers<br />
* ptys Unix<br />
* sockets<br />
<br />
=== Drapeau XID pour les Filesystem XID ===<br />
Bien qu'elle puisse être totalement desactivée, cette modification est requise pour une meilleure robustesse au niveau du système de fichiers, et pour isoler les contextes. Le drapeau XID est aussi totalement indispensable pour implémenter le support pour les Limites Disques par Contexte et les Quotas par Contexte sur une partition partagée.<br />
<br />
Ce concept d'ajouter un identifiant de contexte (xid) à chaque fichier pour créer une notion d'appartenance d'un fichier à un contexte parait simple ... Il n'en est rien, car l'implémentation actuelle n'est pas triviale. Elle nécessite soit une modification des représentations du système de fichier, soit des astuces au niveau applicatif.<br />
<br />
Une approche non intrusive pour éviter toute modification du système de fichiers sous-jacent est d'utiliser les bits de poids forts de champs existants, comme ceux des UID ou GID pour stocker le XID additionnel.<br />
<br />
Une fois que les informations de contexte sont disponibles au niveau de chaque inode, l'étape logique suivante est d'étendre la vérification d'accès au contexte en plus du reste.<br />
<br />
Actuellement, tous les acces aux inodes sont vérifiés par rapport à leur contexte ID, à l'exception des contextes "Hôte" et "Spectateur".<br />
<br />
Les fichiers non étiquettés dans le contexte hôte sont simplement traités comme appartenant au contexte courant, et cela est requis pour que l'Unification soit possible. Si un tel fichier est modifié à l'intérieur d'un contexte, elle changera en silence vers son noveau contexte, en changeant son XID.<br />
<br />
Les méthodes suivantes de marquage sont utilisées:<br />
<br />
;UID32/GID32 or EXTERNAL: Ce format utilise l'espace inutilisé dans l'inode disque pour stocker les informations de contexte. Pour l'instant, c'est uniquement défini pour ext3/ext3, mais sera dans le futur aussi défini pour xfs, reiserfs, et jfs, dès que possible.<br />
<br />
Avantage: Valeurs 32bit uid/gid complètes.<br />
<br />
;UID32/GID16: Ce format utilise la moitié haute du GID pour stocker les informations de contexte. Cela est fait de manière transparente, sauf si le format est changé sans conversion préalable.<br />
<br />
Avantage: fonctionne avec tout système de fichiers équipé de UID / GID 32bits<br />
<br />
Désavantage: le GID est réduit a 16 bits.<br />
<br />
;UID24/GID24: Ce format utilise le premier quart haut de l'UID et du GID pour stocker les informations de contexte, une fois encore, d'une manière transparente. Cela permet 16 millions de groupes et utilisateurs, ce qui devrait suffire pour la majorité des applications.<br />
<br />
Avantage: fonctionne sur tout système de fichiers avec des UID/GID 32bits<br />
<br />
Desavantage: les UID et GID sont réduits a 24 bits.<br />
<br />
Voir Examples [E31] et [E32]<br />
<br />
== Modifications Supplémentaires ==<br />
En plus du strict minimum, voici un certain nombre de modifications, non indispensables, mais qui se sont révélées très utiles au fil du temps.<br />
<br />
=== Drapeaux par Contexte ===<br />
Très tôt, le besoin d'activer ou désactiver une fonctionnalité séparement pour l'un ou l'autre des Vserver est apparue. Un champ de bits a donc été ajouté (taille=word).<br />
<br />
Ce champ de bits comprend un bon nombre de drapeaux, un champ masque, qui indique les drapeaux disponibles, et un mécanisme de déclanchement spécial, pour activer un drapeau au démarrage, puis le désactiver en causant un évennement ou une action associée.<br />
<br />
Voici la liste des drapeaux prévus et pour la plupart déjà implémentés. Ils sont disponibles dans la branche de développement de Linux-VServer:<br />
<br />
{|class="wikitablenowrap"<br />
| 0|| VXF_INFO_LOCK (historique, obsolète)<br />
|-<br />
| 1|| VXF_INFO_SCHED (historique, obsolète)|| schedule all processes in a context as if they where one.<br />
|-<br />
| 2|| VXF_INFO_NPROC (historique, obsolète)|| limite le nombre de processus autorisés dans un contexte à la valeur NPROC.<br />
|-<br />
| 3|| VXF_INFO_PRIVATE (historique)|| interdiction d'entrer dans ce contexte depuis l'extérieur.<br />
|-<br />
| 4|| VXF_INFO_INIT (historique) || show the init process with pid '1'<br />
|-<br />
| 5|| VXF_INFO_HIDE (historique, obsolète)||<br />
|-<br />
| 6|| VXF_INFO_ULIMIT (historique, obsolète)||<br />
|-<br />
| 7|| VXF_INFO_NSPACE (historique, obsolète)||<br />
|-<br />
| 8|| VXF_SCHED_HARD || activer l'ordonnancement "Hard CPU"<br />
|-<br />
| 9|| VXF_SCHED_PRIO || calculer les priorités de chaque processus à l'aide du "contexte token bucket".<br />
|-<br />
| 10|| VXF_SCHED_PAUSE || mettre tous les processus de ce contexte dans la file "hold", les empéchant d'être ordonnancés à nouveau.<br />
|-<br />
| 16|| VXF_VIRT_MEM || virtualize the memory information so that the VM and RSS limits are used for meminfo and friends<br />
|-<br />
| 17|| VXF_VIRT_UPTIME || virtualiser l'uptime, en commançant à la date de création du contexte.<br />
|-<br />
| 18|| VXF_VIRT_CPU || <br />
|-<br />
| 24|| VXF_HIDE_MOUNT || afficher les /proc/{pid}/mounts comme vides.<br />
|-<br />
| 25|| VXF_HIDE_NETIF || cache les interfaces réseau et addresses non autorisées dans ce contexte.<br />
|}<br />
<br />
Voir Exemple [XX]<br />
<br />
=== Privileges par Contexte ===<br />
Lorsque nous sommes arrivé au nombre maximum de privileges envisageables sans trop modifier le noyau, l'étape suivante a été, naturellement, d'ajouter un système de privileges par contexte.<br />
<br />
Le mécanisme des privileges par contexte implémenté dans Linux-VServer permet un réglage fin des privileges Linux. Ils ne sont pas visibles aux processus d'un contexte donné, puisque de toute facon le processus n'aurait pas le droit de les vérifier ou de les modifier.<br />
<br />
Généralement, il y a deux facons d'utiliser ces privileges : * Require one or a number of context capabilities to be set in addition to a given Linux capability, each one controlling a distinct part of the functionality. For example the CAP_NET_ADMIN could be split into RAW and PACKET sockets, so you could take away each of them separately by not providing the required context capability.<br />
<br />
Consider the context capability sufficient for a specified functionality, even if the Linux Capability says something different. For example mount() requires CAP_SYS_ADMIN which adds a dozen other things we do not want, so we define a CCAP_MOUNT to allow mounts for certain contexts.<br />
<br />
The difference between the Context Flags and the Context Caps is more an abstract logical separation than a functional one, because they are handled very similar.<br />
Again, a list of the Context Capabilities and their purpose:<br />
<br />
{|class="wikitablenowrap"<br />
|0|| VXC_SET_UTSNAME|| autoriser le contexte à changer le nom de serveur et le nom de domaine en utilisant l'appel système noyau approprié<br />
|-<br />
|1|| VXC_SET_RLIMIT|| allow the context to modify the resource limits (within the vserver limits).<br />
|-<br />
|8|| VXC_RAW_ICMP|| allow raw icmp packets in a secure way (this makes ping work from inside)<br />
|-<br />
|16|| VXC_SECURE_MOUNT|| permit secure mounts, which at the moment means that the nodev mount option is added.<br />
|}<br />
<br />
=== Comptabilité par Contexte ===<br />
Plusieurs propriétés des contextes sont très utiles pour l'administrateur système, que ce soit pour garder un oeil sur les ressources, pour avoir une idée de ce que peut supporter le serveur, ou pour pouvoir facturer d'une manière ou d'une autre au client.<br />
<br />
Deux types de propriétés peuvent être comptabilisées, celles dont la valeur courante représente l'état du système (par analogie, prenez la vitesse d'un véhicule), et celles dont la valeur augmente régulièrement avec le temps (comme le kilométrage).<br />
<br />
La plupart des valeurs d'état sont limitables, et sont donc traitées d'une façon spécifique, comme cela est décrit dans la section qui suit.<br />
<br />
Good candidates for Context Accounting are:<br />
* Temps CPU utilisé<br />
* Nombre de fork() effectués<br />
* Nombre de messages Socket par Type<br />
* Nombre de paquets Transmis et Recus<br />
<br />
Voir Exemple [E41]<br />
<br />
=== Limites par Contexte ===<br />
La plupart des ressources système, que ce soit la consommation mémoire, le nombre de processus utilisés, le nombre de descripteurs de fichiers, la bande passante réseau, doivent pouvoir être limitées.<br />
<br />
Les limites par contexte permettent, pour chaque valeur limitable, de définir trois types de limites: minimum, soft, et hard(maximum).<br />
<br />
A l'heure actuelle, seule les limites hard sont supportées, et seulement une partie d'entre elles sont réellement activées. Voici une liste des limites par contexte actuelles et prévues:<br />
* limites sur les processus<br />
* limites sur l'ordonnanceur<br />
* limites mémoire<br />
* limites disques par contexte<br />
* quotas user/groupe par contexte<br />
<br />
De plus, les limites par contexte gardent trace des valeur maxima atteintes et du nombre de fois ou la limite a été atteinte (hit), pour donner un feedback utile a l'administrateur.<br />
<br />
Voir Exemple [E42]<br />
<br />
=== Virtualisation ===<br />
One major difference between the Linux-VServer approach and Virtual Machines is that you do not have the virtualization part as a side-effect, so you have to do that by hand where it makes sense.<br />
<br />
For example, a Virtual Machine does not need to think about uptime, because naturally the running OS was started somewhere in the past and will not have any problem to tell the time it thinks it began running.<br />
<br />
A context can also store the time when it was created, but that will be different from the systems uptime, so in addition, there has to be some function, which adjusts the values passed from kernel to user-space depending on the context the process belongs to.<br />
<br />
This is what for Linux-VServer is known as Virtualization (actually it's more faking some values passed to and from the kernel to make the processes think that they are on a different machine).<br />
<br />
Currently modified for the purpose of Virtualization are:<br />
* System Uptime<br />
* Host and Domain Name<br />
* Machine Type and Kernel Version<br />
* Context Memory Availability<br />
* Context Disk Space<br />
<br />
Voir Exemple [E43]<br />
<br />
=== Sécurité Renforcée ===<br />
Le mécanisme de sécurité Proc-FS protège les entrées dynamiques du système de fichiers proc, de façon à ce que toutes les entrées ne soient pas vues dans tous les contextes.<br />
<br />
Le système est constitué de trois drapeaux pour chaque entrée du Proc-FS: Admin, Watch, et Hide.<br />
<br />
Le Drapeau Hide active ou désactive entierement une fonctionnalité, donc toute combinaison associée avec un drapeau Hide à 0 aura donc la signification visible.<br />
<br />
Les drapeaux Admin et Watch déterminent ou l'entrée hidden (cachée) reste visible; par exemple, si les drapeaux Admin et Hidden sont mis, seul le Host Contexte (0) sera en mesure de voir cette entrée spécifique.<br />
<br />
Voir Exemple [E44] et Voir Exemple [E45]<br />
<br />
=== Kernel Helper ===<br />
Dans certains cas, il peut être nécessaire de mettre en place un outil en espace utilisateur qui va agir en lieu et place du noyau, lorsque par exemple un processus demande une fonctionnalité disponible sur un serveur réel, mais non disponible dans un contexte.<br />
<br />
Le meilleur exemple d'un tel cas est le "Reboot Helper", qui implémente l'appel système reboot(), invoqué depuis l'intérieur d'un contexte en lieu et place du noyau. L'appel sera éxécuté depuis le contexte hôte, qui lancera l'action adéquate, reboot ou un simple halt du contexte en question.<br />
<br />
Bien que ce "helper" soit concu pour être flexible et gérer un certain nombre de choses de la même facon, il n'est pas utilisé pour l'instant à autre chose, et pourrait être remplacé dans le futur par une interface par evènement.<br />
<br />
Voir Exemple [XX]<br />
<br />
== Fonctionnalités et documentation additionnelle ==<br />
=== Unification ===<br />
L'un des objectifs centraux de Linux-VServer est de réduire l'utilisation des ressources partout ou cela est possible. Une excellente idée a donc germé, celle de partager des fichiers à travers les différents contextes sans interférer avec les taches administratives classiques ou diminuer le niveau de sécurité.<br />
<br />
Les fichiers communs à plusieurs contextes, peu sujet à être modifiés, comme les bibliothèques ou les binaires, peuvent être soudés via un lien dur sur un système de fichier partagé, réduisant d'autant le besoin en espace disque, cache d'inodes, et surtout, l'occupation mémoire, via l'utilisation des bibliothèques partagées.<br />
<br />
Seul inconvénient, si nous ne prenons pas quelques mesures supplémentaires, un contexte malicieux sera en mesure, par accident ou volontairement, de détruire ou modifier un tel fichier partagé, ce qui aurait des conséquences directes sur les autres contextes.<br />
La première étape consiste à placer sur les fichiers partagés un drapeau Immutable (et enlever la caps qui permet de modifier un tel fichier). Il faut toutefois ajouter un attribut supplémentaire à ces fichiers partagés, pour permettre leur suppréssion, lors, par exemple, d'une mise à jour des bibliothèques dans un l'un des contextes.<br />
<br />
Ces fichiers liés, immutables, que l'ont peut toutefois détruire, et appartenant à plus d'un contexte sont appelés unifiés, et l'action qui consiste à les rechercher et les préparer s'appelle Unification.<br />
<br />
Choississez l'unification si vous souhaitez réduire votre usage de ressources. L'inconvénient évident est une administration moins facile. Un Serveur Linux s'installe typiquement sur 500Mo de disque, et 10 serveurs unifiés en consommeront donc seulement 700Mo, et moins de mémoire pour les caches.<br />
<br />
Voir Exemple [XX]<br />
<br />
=== Espaces de nom privés ===<br />
Ajoutés récemment dans Linux-VServer, les espaces de noms privés utilisent la couche VFS du noyau linux et offrent une vue différente du système de fichier pour chaque contexte.<br />
Par rapport au schéma traditionnel, l'avantage principal apparait lorsqu'on modifie quelquechose dans un espace de nommage (par exemple, les points de montage); à cet instant, les autres contextes resteront intact, y compris biensur le contexte Hôte.<br />
Désavantage évident d'une telle approche; entrer dans un tel espace de noms privé n'est pas aussi simple que d'entrer dans un chroot. Toutefois, les choses pourraient changer dans les noyaux futurs, si cette fonctionnalité est par exemple intégrée directement à la fonction chroot().<br />
<br />
=== Le système de fichier Proc-FS de Linux-VServer ===<br />
A structured, dynamically generated subtree of the well-known Proc-FS - actually two of them - has been created to allow for inspecting the different values of Security and Network Contexts.<br />
/proc/virtual<br />
.../info<br />
<br />
/proc/virtual/<pid><br />
.../info<br />
.../status<br />
.../sched<br />
.../cvirt<br />
.../cacct<br />
.../limit<br />
<br />
=== Extensions Token Bucket ===<br />
While the basic idea of Linux-VServer is a peaceful coexistence of all contexts, sharing the common resources in a respectful way, it is sometimes useful to control the resource distribution for resource hungry processes.<br />
<br />
The basic principle of a Token Bucket is not very new. It is given here as an example for the Hard CPU Limit. The same principle also applies to scheduler priorities, network bandwidth limitation and resource control in general.<br />
<br />
The Hard CPU Limit uses this mechanism in the following way: consider a bucket of a certain size S which is filled with a specified amount of tokens R every interval T, until the bucket is "full" - excess tokens are spilled. At each timer tick, a running process consumes exactly one token from the bucket, unless the bucket is empty, in which case the process is put on a hold queue until the bucket has been refilled with a minimum M of tokens. The process is then rescheduled.<br />
<br />
A major advantage of a Token Bucket is that a certain amount of tokens can be accumulated in times of quiescence, which later can be used to burst when resources are required.<br />
<br />
Where a per-process Token Bucket would allow for a CPU resource limitation of a single process, a Context Token Bucket allows to control the CPU usage of all confined processes.<br />
<br />
Another approach, which is also implemented, is to use the current fill level of the bucket to adjust the process priority, thus reducing the priority of processes belonging to excessive contexts.<br />
<br />
Voir Exemple [XX]<br />
<br />
=== Limites Disque par Contexte ===<br />
Pour faire usage de cette fonctionnalité, le support pour les fichiers étiquetés XID doit être présent. Grace aux limites par contexte, vous pouvez alors régler une limite différente pour chaque contexte d'une partition partagée.<br />
<br />
Chaque block et inode d'un système de fichier est comptabilisé, dès lors qu'un hachage XID a été ajouté à ce système de fichier dans ce contexte donné.<br />
Those values, including current usage, maximum and reserved space, will be shown for filesystem queries, creating the illusion that the shared filesystem has a different usage and size, for each context.<br />
<br />
=== Quota par Contexte ===<br />
Similar to the Context Disk Limits, Per-Context Quota uses separate quota hashes for different Contexts on a shared filesystem. This is not required to allow for Linux-VServer quota on separate partitions.<br />
<br />
=== Le périphérique "proxy" VRoot ===<br />
Les opérations sur les Quotas (ioctls) nécessitent un accès aux périphériques de bloc. Ils ne sont donc pas disponible dans un VPS.<br />
<br />
=== Stealth ===<br />
Pour certaines applications, par exemple la préparation d'un "pot de miel" (honey-pot), ou d'une imitation particulièrement réaliste d'un vrai serveur à des fins éducatives, vous aurez peut-être besoin de confondre le contexte du serveur hôte (réel) et celui de votre pot de miel. <br />
Toutefois, certaines alternatives libres comme QEMU ou UML vous permettent de faire la même chose beaucoup mieux et avec moins d'efforts. Ce n'est donc pas une question centrale dans le développement de Linux-VServer.<br />
<br />
== Sécurité Linux-VServer ==<br />
Nous savons maintenant que Linux-VServer implémente quelques principes de sécurité, et comment ils fonctionnent. Il faut tout de même dire quelques mots la dessus, puisqu'il ne suffit pas, bien évidemment, de considérer que Linux-VServer étant une architecture sécurisée, votre système sera sur automatiquement. Comme d'habitude, mieux vaut savoir *exactement* ce que vous faites.<br />
<br />
=== Privileges Sécurisées ===<br />
Actuellement, seules les privileges Linux suivantes sont considérés d'un usage sans risque dans un VPS. Si d'autres privileges sont nécessaires, ils ouvrent probablement des trous de sécurité.<br />
* CAP_CHOWN<br />
* CAP_DAC_OVERRIDE<br />
* CAP_DAC_READ_SEARCH<br />
* CAP_FOWNER<br />
* CAP_FSETID<br />
* CAP_KILL<br />
* CAP_SETGID<br />
* CAP_SETUID<br />
* CAP_NET_BIND_SERVICE<br />
* CAP_SYS_CHROOT<br />
* CAP_SYS_PTRACE<br />
* CAP_SYS_BOOT<br />
* CAP_SYS_TTY_CONFIG<br />
* CAP_LEASE<br />
CAP_NET_RAW par exemple n'est pas considéré comme sur. Bien qu'il soit souvent utilisé pour donner le droit à la commande "ping" (dont le fonctionnement est cassé), il existe de bien meilleures alternatives comme la commande ping "poink[U7]", ou la cap VXC_RAW_ICMP.<br />
<br />
=== La Barrière Chroot ===<br />
Il faut vous assurer que le drapeau barrière est bien mis sur tout répertoire parent de chacun de vos VPS. Cela est indispensable pour prévenir quiconque de sortir du chroot et aller se balader dans le système de fichier de votre vserver hôte.<br />
<br />
<br />
<br />
=== Fichiers de périphériques Sécurisés ===<br />
Le répertoire /dev d'un VPS ne doit pas contenir plus de fichiers qu'indiqué ci-dessous, plus le répertoire pour les pts unix.<br />
* c 1 7 full<br />
* c 1 3 null<br />
* c 5 2 ptmx<br />
* c 1 8 random<br />
* c 5 0 tty<br />
* c 1 9 urandom<br />
* c 1 5 zero<br />
* d pts<br />
Bien entendu, d'autres périphériques comme console, mem, kmem, et même des périphériques en mode block et/ou caractère peuvent être ajoutés, mais une certaine expertise sera nécessaire pour s'assurer que cela n'entraine aucun trou de sécurité.<br />
<br />
=== Entrées Proc-FS Sécurisées ===<br />
Aucun test n'a été fait sur la fiabilité et la sécurité des entrées dans le système de fichiers proc, mais quelques incidents ont été notés lorsqu'on utilise par exemple des entrées proc avec permission d'écriture, et non protégées par une CAP linux.<br />
Par exemple, <tt>/proc/sysrq-trigger</tt> est un fichier qui ne doit en aucun cas être accessible dans un VPS sans une excellente raison.<br />
<br />
== Champ d'Applications ==<br />
Le but premier de ce projet est de permettre la création de serveurs virtuels partageant les ressources d'une même machine physique. Un Serveur Virtuel fonctionne comme un serveur Linux normal, et peut lancer des services traditionnels comme telnet, service de mail, service web, service SQL.<br />
<br />
=== Séparation Administrative ===<br />
Un provider intelligent peut donc vendre un serveur virtuel, qui, en utilisant moins de ressources que d'autres techniques de virtualisation, permet de lancer plus d'instances sur une même machine.<br />
<br />
La liste des providers qui fournissent un tel service est assez longue, et on peut donc considérer que c'est l'application principale de vserver.<br />
<br />
=== Séparation de Services ===<br />
Pour séparer plusieurs services identiques ou de nature différente, qui auraient autrement des interférences entre eux, est une chose facile à mettre en oeuvre avec Vserver. Plusieurs raisons peuvent vous pousser à faire cela; un service mal écrit, ou simplement deux services qui ne savent pas co-exister pour de multiples raisons.<br />
<br />
Même sur une machine à l'ancienne mode, placer un service très exposé ou non sécurisé car inconnu ou propriétaire dans une prison chroot peut améliorer grandement la sécurité et la maintenabilité.<br />
<br />
=== Améliorer la Sécurité ===<br />
Bien que l'idée de lancer plusieurs serveurs sur une seule machine soit en elle même très interessante, d'autres concepts sont encore plus interessants. Imaginez un serveur physique sur lequel tourne un seul vserver. Le but est d'isoler l'environnement principal de n'importe quel service, n'importe quel réseau. Vous démarrerez dans l'environnement principal, lancez très très peu de services, puis continuez dans le serveur virtuel.<br />
<br />
Le service de l'environnement principal sera:<br />
* Injoignable depuis le reseau.<br />
* En mesure de logger tous les messages du virtual serveur, d'une manière sécurisée. Rien dans le serveur virtuel ne permet d'effacer les logs, ou de les modifier. Même un serveur virtuel cracké ne permet pas de changer les logs.<br />
* En mesure de faire tourner un système de détection d'intrusion, qui espionnera l'état du serveur virtuel sans être accessible ou même détecté. Par exemple, vous pouvez installer et faire tourner tripwire depuis l'environnement principal, et impossible de modifier son fonctionnement ou de le tromper.<br />
Une autre option consiste à mettre le firewall dans un serveur virtuel, puis étirer la DMZ sur un ensemble de VPS séparés. Moyennant une configuration bien faite, ce genre d'installation peut réduire substantiellement le nombre de machines requises, sans pour autant impacter les performances.<br />
<br />
=== Maintenance Facilitée ===<br />
Une fonctionnalité clef d'un serveur virtuel est son indépendance vis à vis du matériel. La plupart des problèmes matériels sont inconnus au fonctionnement d'un serveur virtuel.<br />
<br />
Le serveur principal agit comme un système hôte, et s'occupe de tous les détails. Le serveur virtuel est simplement un client, et ignore tous les détails. De cette manière, le client peut être déplacé vers un autre serveur physique avec très peu de manipulations.<br />
<br />
Par exemple, pour déplacer un serveur virtuel depuis un ordinateur physique vers un autre, il suffit de procéder aux étapes suivantes:<br />
* stopper le serveur virtuel<br />
* le copier sur l'autre machine<br />
* copier sa configuration<br />
* lancer le serveur virtuel sur la nouvelle machine<br />
Pas de mise à jour des utilisateurs, pas de configuration matérielle, tant que les machines sont compatibles au niveau de leurs binaires.<br />
<br />
=== Scenarios de Fail-Over ===<br />
En repoussant les limites un peu plus loin, on peut utiliser des technologies de réplication pour conserver une copie identique à la minute près du système de fichier d'un serveur virtuel en fonctionnement. Cela peut servir à un basculement très rapide si le serveur en fonction tombe pour n'importe quelle raison.<br />
<br />
Toutes les methodes connues sont utilisables dans ce but, en commancant par la réplication réseau comme rsync, ou drdb, en passant par NBD (les Network Devices), les disques partagés, ou un système de fichier distribué. Toutes ces méthodes sont utilisables pour réduire le temps d'indisponibilité d'un système et améliorer l'efficacité globale.<br />
<br />
=== Pour test ===<br />
Vous avez besoin de construire un logiciel pour plusieurs versions d'une distribution particulière. (Mandrake 8.2, 9.0, 9.1, 9.2, 10.0), ou bien même pour plusieurs distributions différentes.<br />
<br />
Ce problème est résolu d'une manière très simple par Vserver. Avec pas mal d'espace disque, ces différentes distributions peuvent être installées et lancées en parallèle, simplifiant la tache de passer de l'une à l'autre.<br />
<br />
Biensur, vous pouvez faire cela simplement avec chroot() et rien d'autre, mais Vserver offre une simulation bien plus réaliste.<br />
<br />
== Performance et Stabilité ==<br />
=== Impact de Linux-VServer sur l'hôte ===<br />
=== Overhead dans un Contexte ===<br />
=== Taille du patch noyau ===<br />
<br />
== Matériels Non Intel i386 ==<br />
Linux-VServer est concu pour être indépendant de l'architecture au maximum du coup, seule une toute petite partie, la définition de l'appel système lui-même est spécifique à une architecture. Malgré cela, quelques architectures renfermen des copies de certains codes 'architecture independant', pour une raison ou pou une autre, et nécessitent par conséquent de légères modifications.<br />
<br />
Les architectures suivantes sont supportées, et certaines d'entre elles ont même été testées:<br />
* alpha<br />
* ia32 / ia64 / xbox<br />
* x86_64 (AMD64)<br />
* mips / mips64<br />
* hppa / hppa64<br />
* ppc / ppc64<br />
* sparc / sparc64<br />
* s390<br />
* uml<br />
L'ajout d'une nouvelle architecture est relativement simple, même si de tests extensifs sont nécessaires pour valider le bon fonctionnement d toutes les fonctionnalités telle qu'attendu. (et biensur, du matériel ;).<br />
<br />
<br />
== Intro Noyau Linux ==<br />
Bien que les fonctionnalités décrites plus haut sont codées dans le noyau, quelques outils sont nécessaires en espace utilisateur (userspace) pour les activer et les controler.<br />
<br />
Ces outils en userspace communiquent généralement avec le noyau via des appels système (syscalls).<br />
<br />
Le chapitre qui suit décrit les liens entre espace kernel et espace utilisateur, comment les appels système, méthode simple pour communiquer entre les processus et le noyau, fonctionnent.<br />
<br />
=== Espace Noyau et Espace Utilisateur ===<br />
Sous Linux et les systèmes d'exploitation similaires, l'espace noyau et l'espace utilisateur sont séparés, et l'espace d'adressage est divisé en deux parties. Dans L'espace noyau réside le code noyau, alors que les programmes utilisateur vivent dans l'espace utilisateur. Bien entendu, un programme ne peut écrire dans la mémoire noyau, ni dans la mémoire d'un autre processus.<br />
<br />
Malheureusement, c'est aussi le cas pour le code du noyau. Le code kernel n'a pas le droit d'écrire dans l'espace utilisateur. Qu'est-ce que cela signifie ? Lorsqu'un driver de périphérique a besoin d'écrire ses octets destinés à un programme dans l'espace utilisateur, il ne peut pas le faire directement, mais doit passer par des fonctions noyau spécifiques à la place. De même, lorsque des paramètres sont passés au noyau par référence à une fonction kernel, la fonction kernel ne peut pas lire les paramètres directement. Elle doit utiliser d'autres fonctions noyau pour lire chaque octet des paramètres.<br />
<br />
Bien entendu, il existe des fonctions écrites tout spécialement pour les transfer depuis et vers l'espace utilisateur.<br />
copy_to_user(void *to, const void *from, long n);<br />
copy_from_user(void *to, const void *from, long n);<br />
<br />
get_user() and put_user() Prendre ou placer l'octet, le mot, ou l'entier long depuis l'espace utilisateur ou vers celui-ci. C'est une macro, et elle se fie au type de ses arguments pour évaluer le nombre d'octets à transférer.<br />
<br />
=== Appels système Linux ===<br />
La plupart des appels libc s'appuient sur les appels système, la plus petite forme de fonction qu'un programme peut appeler.<br />
<br />
Ces appels système sont implémentés dans le noyau lui-même, ou dans des modules, parties de code noyau chargeables dynamiquement.<br />
<br />
Ils sont implémentés via un multiplexeur appelé avec un masque d'interruption précis. Sous Linux, ce masque d'interruption est int 0x80. Lorsque l'instruction 'int 0x80' est exécutée, le contrôle est donné au noyau (ou, plus précisément, à la fonction _system_call() ), et le démultipléxage proprement dit prend place.<br />
<br />
Comment fonctionne la fonction _system_call() ?<br />
<br />
Tout d'abord, tous les registres sont sauvegardés, et le contenu du registre %eax est comparé à la table des appels systèmes, qui recense tous les appels systèmes et leur adresse respective.<br />
<br />
On peut acceder à cette table via la variable extern void *sys_call_table[] Il existe un nombre et une adresse mémoire données dans cette table pour chacun des appels système.<br />
<br />
Ceux-ci sont référencés dans le fichier /usr/include/sys/syscall.h.<br />
<br />
Ils sont de la forme SYS_nomappelsysteme. si l'appel système n'est pas implémenté, la cellule correspondante dans la table sys_call_table est à 0, et une erreur est retournée.<br />
<br />
Sinon, l'appel système sort, et l'entrée correspondante dans la table donne l'adresse du code ou se trouve l'appel système.<br />
<br />
<br />
<br />
== Implémentation ==<br />
Ce chapitre est plus particulierement reserve aux developpeurs noyau. Toutefois, les curieux trouveront avantage a tirer le rideau pour decouvrir les entrailles du systeme.<br />
<br />
=== Appel systeme===<br />
Pendant un certain temps, Linux-VServer a utilise different appels systeme pour accomplir les differents aspects de son travail. Tres vite, le nombre des commandes necessaires est devenu important, nous avons donc commence a donner des valeurs magiques aux appels pour choisir le comportement desire.<br />
<br />
Enfin, il y a peu de temps, nous avons obtenu un numero reserve pour les appels systemes Linux-VServer, et malgre l'opinion de certains developpeurs, c'est globalement une bonne decision de garder un seul appel systeme.<br />
<br />
Avoir plusieurs appels systeme peut faciliter les choses pour travailler avec les appels systemes sur plusieurs architectures; toutefois, cela n'a pas constitue un probleme majeur jusqu'ici, les donnees transitant depuis et vers le noyau etant, conformement au standard C99, fortement typees.<br />
<br />
Quoi qu'il en soit, la mise en place d'un appel systeme passe par la creation d'un multiplexeur, qui va decider quelle commande doit etre executee, et quels arguments lui passer. A elle par la suite d'executer effectivement le travail demande.<br />
extern asmlinkage long<br />
sys_vserver(uint32_t cmd, uint32_t id, void __user *data)<br />
L'appel systeme Linux-VServer prend trois arguments dans tous les cas: la commande (cmd), un nombre (id), et une structure de donnee en espace utilisateur d'une taille encore inconnue.<br />
<br />
Pour faciliter le deboggage et la tenue a jour des informations de versionning, la chaine cmd est decomposee en trois parties: les 12 bits de poids faible contiennent le numero de version, puis 4 bits sont reserves. Les 16 bits de poids fort sont divises en 8 bits de commande et 6 pour la categorie, puis les 2 bits restant, reserves pour usage ulterieur.<br />
<br />
Nous avons donc 64 Categories avec chacune 256 commandes, et 4096 revisions possible pour chaque commande, ce qui surpasse largement nos besoins presents et futurs.<br />
<br />
Voici un apercu des categories deja definies, et leur valeur numerique associee:<br />
<br />
Matrice des appels systeme V2.6<br />
<br />
|VERSION|CREATE |MODIFY |MIGRATE|CONTROL|EXPERIM| |SPECIAL|SPECIAL|<br />
|STATS |DESTROY|ALTER |CHANGE |LIMIT |TEST | | | |<br />
|INFO |SETUP | |MOVE | | | | | |<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
SYSTEM |VERSION|VSETUP |VHOST | | | | |DEVICES| |<br />
HOST | 00| 01| 02| 03| 04| 05| | 06| 07|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
CPU | |VPROC |PROCALT|PROCMIG|PROCTRL| | |SCHED. | |<br />
PROCESS| 08| 09| 10| 11| 12| 13| | 14| 15|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
MEMORY | | | | | | | |SWAP | |<br />
| 16| 17| 18| 19| 20| 21| | 22| 23|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
NETWORK| |VNET |NETALT |NETMIG |NETCTL | | |SERIAL | |<br />
| 24| 25| 26| 27| 28| 29| | 30| 31|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
DISK | | | | | | | |INODE | |<br />
VFS | 32| 33| 34| 35| 36| 37| | 38| 39|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
OTHER | | | | | | | |VINFO | |<br />
| 40| 41| 42| 43| 44| 45| | 46| 47|<br />
=======+=======+=======+=======+=======+=======+=======+ +=======+=======+<br />
SPECIAL| | | | |FLAGS | | | | |<br />
| 48| 49| 50| 51| 52| 53| | 54| 55|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
SPECIAL| | | | |RLIMIT |SYSCALL| | |COMPAT |<br />
| 56| 57| 58| 59| 60|TEST 61| | 62| 63|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
<br />
La definition de ces commandes est simplifiee grace a certaines macros, comme par exemple interroger un drapeau ou lui attribuer une valeur:<br />
#define VCMD_get_cflags VC_CMD(FLAGS, 1, 0)<br />
#define VCMD_set_cflags VC_CMD(FLAGS, 2, 0)<br />
<br />
extern int vc_get_cflags(uint32_t, void __user *);<br />
extern int vc_set_cflags(uint32_t, void __user *);<br />
<br />
Notez bien, ce n'est pas la commande elle meme qui est passee en parametre, mais un id et un pointeur vers une structure de donnee en espace utilisateur.<br />
<br />
=== Structures de Donnees Utilisees===<br />
Plusieurs types de structures sont utilisees par les differentes parties de l'implementation; seuls quelques exemples sont donnes ici, l'ensemble complet des structures utilisees se trouve dans le source.<br />
==== La Structure Data Context====<br />
La structure Data Context permet de gerer les contextes, leur destruction, ainsi que les futurs contextes hierarchiques.<br />
<br />
Les sections reservees pour l'ordonanceur ou les limites sont definies dans des structures separees, comme le veut la logique, puis incorporees dans la structure principale.<br />
struct vx_info {<br />
struct list_head vx_list; /* linked list of contexts */<br />
xid_t vx_id; /* context id */<br />
atomic_t vx_refcount; /* refcount */<br />
struct vx_info *vx_parent; /* parent context */<br />
<br />
struct namespace *vx_namespace; /* private namespace */<br />
struct fs_struct *vx_fs; /* private namespace fs */<br />
uint64_t vx_flags; /* context flags */<br />
uint64_t vx_bcaps; /* bounding caps (system) */<br />
uint64_t vx_ccaps; /* context caps (vserver) */<br />
<br />
pid_t vx_initpid; /* PID of fake init process */<br />
<br />
struct _vx_limit limit; /* vserver limits */<br />
struct _vx_sched sched; /* vserver scheduler */<br />
struct _vx_cvirt cvirt; /* virtual/bias stuff */<br />
struct _vx_cacct cacct; /* context accounting */<br />
<br />
char vx_name[65]; /* vserver name */<br />
};<br />
<br />
<br />
Voici un exemple de la sous-structure Ordonanceur:<br />
struct _vx_sched {<br />
spinlock_t tokens_lock; /* lock for this structure */<br />
<br />
int fill_rate; /* Fill rate: add X tokens ... */<br />
int interval; /* Divisor: ... each Y jiffies */<br />
atomic_t tokens; /* current number of tokens */<br />
int tokens_min; /* Limit: minimum for unhold */<br />
int tokens_max; /* Limit: no more than N tokens */<br />
uint32_t jiffies; /* bias: integral multiple of Y */<br />
<br />
uint64_t ticks; /* token tick events */<br />
cpumask_t cpus_allowed; /* cpu mask for context */<br />
};<br />
<br />
L'idee principale derriere ces sous-structures est de faciliter leur maintenabilite, a l'aide, pour chacune d'elles, d'une fonction init et cleanup, d'ou une lecture facilitee et une maintenabilite accrue.<br />
<br />
==== The Scheduler Command Data====<br />
As an example for the data structure used to control a specific part of the context from user-space, here is a scheduler command and the utilized data structure to set the properties:<br />
#define VCMD_set_sched VC_CMD(SCHED, 1, 2)<br />
<br />
struct vcmd_set_sched_v2 {<br />
int32_t fill_rate; /* Fill rate: add X tokens ... */<br />
int32_t interval; /* Divisor: ... each Y jiffies */<br />
int32_t tokens; /* current number of tokens */<br />
int32_t tokens_min; /* Limit: minimum for unhold */<br />
int32_t tokens_max; /* Limit: no more than N tokens */<br />
uint64_t cpu_mask; /* Mask: allowed cpus */<br />
};<br />
<br />
<br />
==== Example Accounting: Sockets====<br />
Basically all the accounting and limit stuff are defined as macros or inline functions capable of handling the different resources, hiding the underlying implementation wherever possible.<br />
#define vx_acc_sock(v,f,p,s) \<br />
__vx_acc_sock((v), (f), (p), (s), __FILE__, __LINE__)<br />
<br />
static inline void __vx_acc_sock(struct vx_info *vxi,<br />
int family, int pos, int size, char *file, int line)<br />
{<br />
if (vxi) {<br />
int type = vx_sock_type(family);<br />
<br />
atomic_inc(&vxi->cacct.sock[type][pos].count);<br />
atomic_add(size, &vxi->cacct.sock[type][pos].total);<br />
}<br />
}<br />
<br />
#define vx_sock_recv(sk,s) \<br />
vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 0, (s))<br />
#define vx_sock_send(sk,s) \<br />
vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 1, (s))<br />
#define vx_sock_fail(sk,s) \<br />
vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 2, (s))<br />
<br />
And this general definition is then used where appropriate, for example in the __sock_sendmsg() function like this:<br />
<br />
len = sock->ops->sendmsg(iocb, sock, msg, size);<br />
if (sock->sk) {<br />
if (len == size)<br />
vx_sock_send(sock->sk, size);<br />
else<br />
vx_sock_fail(sock->sk, size);<br />
}<br />
<br />
==== Example Limits: Virtual Memory====<br />
#define vx_pages_avail(m, p, r) \<br />
__vx_pages_avail((m)->mm_vx_info, (r), (p), __FILE__, __LINE__)<br />
<br />
static inline int __vx_pages_avail(struct vx_info *vxi,<br />
int res, int pages, char *file, int line)<br />
{<br />
if (!vxi)<br />
return 1;<br />
if (vxi->limit.rlim[res] == RLIM_INFINITY)<br />
return 1;<br />
if (atomic_read(&vxi->limit.res[res]) +<br />
pages < vxi->limit.rlim[res])<br />
return 1;<br />
return 0;<br />
}<br />
<br />
#define vx_vmpages_avail(m,p) vx_pages_avail(m, p, RLIMIT_AS)<br />
#define vx_vmlocked_avail(m,p) vx_pages_avail(m, p, RLIMIT_MEMLOCK)<br />
#define vx_rsspages_avail(m,p) vx_pages_avail(m, p, RLIMIT_RSS)<br />
<br />
And again the test against those limits at certain places, for example here in copy_process()<br />
/* check vserver memory */<br />
if (p->mm && !(clone_flags & CLONE_VM)) {<br />
if (vx_vmpages_avail(p->mm, p->mm->total_vm))<br />
vx_pages_add(p->mm->mm_vx_info,<br />
RLIMIT_AS, p->mm->total_vm);<br />
else<br />
goto bad_fork_free;<br />
}<br />
<br />
==== Example Virtualization: Uptime====<br />
void vx_vsi_uptime(struct timespec *uptime)<br />
{<br />
struct vx_info *vxi = current->vx_info;<br />
<br />
set_normalized_timespec(uptime,<br />
uptime->tv_sec - vxi->cvirt.bias_tp.tv_sec,<br />
uptime->tv_nsec - vxi->cvirt.bias_tp.tv_nsec);<br />
return;<br />
}<br />
<br />
if (vx_flags(VXF_VIRT_UPTIME, 0))<br />
vx_vsi_uptime(&uptime, &idle);<br />
<br />
[[Category:Documentation/fr| ]]</div>Glennhttp://linux-vserver.org/Paper/esPaper/es2011-11-12T08:49:11Z<p>Glenn: topsort</p>
<hr />
<div>{{Languages|Paper}}<br />
<br />
== Infraestructura Existente==<br />
Los recientes núcleos de Linux ya proveen muchas prestaciones de seguridad que son utilizadas por Linux-Vserver para hacer su trabajo. Especialmente características tales como el Sistema de Capacidades de Linux, Límite de Recursos, Atributos de archivos y el Cambio del Entorno Raíz. Las siguientes secciones darán una breve reseña acerca de cada una de estas.<br />
<br />
=== Sistema de Capacidades de Linux===<br />
En ciencias de la computación, una capacidad es un signo usado por un proceso para probar que tiene permitido realizar una operación sobre un objeto. El Sistema de Capacidades de Linux se basa en las "Capacidades Posix", un concepto ligeramente, diseñado para fraccionar el privilegio todo poderoso de root en un conjunto de de distintos privilegios.<br />
<br />
==== Capacidades de Linux ====<br />
Un proceso tiene tres conjuntos de mapas de bits llamadas capacidades hereditarios(I), permitidos(P), y efectivos(E). Cada capacidad se implementa como un bit de estos mapas de bits que están activado o desactivados.<br />
<br />
Cuando un proceso intenta hacer una operación privilegiada, el sistema operativo comprobará el bit apropiado en el conjunto efectivo de los procesos (en lugar de comprobar si el uid efectivo del proceso es 0 como se hace normalmente).<br />
<br />
Por ejemplo, cuando un proceso intenta configurar el reloj, el núcleo Linux comprobará que el proceso tiene el bit CAP_SYS_TIME (que es actualmente el bit 25) habilitado en su conjunto efectivo.<br />
<br />
El conjunto pemitido de los procesos indica las capacidades que el proceso puede usar. El proceso puede tener capacidades habilitadas en el conjunto permitido que no están en el conjunto efectivo.<br />
<br />
Esto indica que el proceso tiene temporalmente deshabilitado esta capacidad. Un proceso tiene permitido habilitar un bit en su conjunto permitido solamente si está disponible en el conjunto permitido. La distinción entre efectivo y permitido existe de manera que el proceso puede agrupar operaciones que necesitan privilegios.<br />
<br />
La implementación de en Linux detenida a este punto, mientras que las Capacidades de POSIX requier la adición de conjuntos de capacidades para archivos también para reemplazar la marca SUID (al menos para ejecutables)<br />
<br />
=== Capability Overview ===<br />
Las lista de Capacidades de POSIX que se usan es larga, y se usan casi todos de los 32 bits disponibles. Si bien la lista detalla da de todas las capacidades se puede encontrar en <tt>/usr/include/linux/capability.h</tt> en la matoría de los sistemas Linux, se da aquí un resumen general de las capacidades importantes que se pueden encontrar.<br />
<br />
{|class="wikitablenowrap"<br />
|0 || CAP_CHOWN|| cambia el dueño y grupo del archivo.<br />
|-<br />
|5 || CAP_KILL|| envía una señal a un proceso con un identificador de usuario diferente existente o efectivo<br />
|-<br />
|6 || CAP_SETGID|| permite setgid(2), setgroups(2), y falsos gids en pase de credenciales de socket <br />
|-<br />
|7 || CAP_SETUID|| permite set*uid(2), y falsos uids en pase de credenciales<br />
|-<br />
|8 || CAP_SETPCAP|| transfiere/elimina cualquier capacidad en el conjunto permitido hacia/desde cualquier pid<br />
|-<br />
|9 || CAP_LINUX_IMMUTABLE|| permite la modificación de los atributos de archivo S_IMMUTABLE y S_APPEND <br />
|-<br />
|11 || CAP_NET_BROADCAST|| permite hacer broadcast y escuchar a múltiples direcciones<br />
|-<br />
|12 || CAP_NET_ADMIN|| permite la configuración de una interfaz, firewall de IP, enmascaramiento, cuantificación, depuración de socket, tablas de ruteo, conexión a cualquier dirección, entrar en modo promiscuo, multicasting,...<br />
|-<br />
|13 || CAP_NET_RAW|| permite el uso de sockets crudos y de paquetes<br />
|-<br />
|16 || CAP_SYS_MODULE|| inserta y saca módulos del kernel<br />
|-<br />
|18 || CAP_SYS_CHROOT|| permite chroot(2)<br />
|-<br />
|19 || CAP_SYS_PTRACE|| permite ptrace() de cualquier proceso<br />
|-<br />
|21 || CAP_SYS_ADMIN|| esta lista sería demasiado larga, basicamente permite hacer cualquier otra cosa, no mencionada en otra capacidad.<br />
|-<br />
|22 || CAP_SYS_BOOT|| permite reboot(2)<br />
|-<br />
|23 || CAP_SYS_NICE|| permite aumentar la prioridad<br />
|}<br />
<br />
[[Category:Documentation/es| ]]</div>Glennhttp://linux-vserver.org/PaperPaper2011-11-12T08:48:56Z<p>Glenn: topsort</p>
<hr />
<div>{{Languages|Paper}}<br />
<br />
== Abstract ==<br />
<br />
A soft partitioning concept based on ''Security Contexts'' which permits the creation of many independent Virtual Private Servers (VPS) that run simultaneously on a single physical server at full speed, efficiently sharing hardware resources.<br />
<br />
A VPS provides an almost identical operating environment as a conventional Linux Server. All services, such as ssh, mail, Web and databases, can be started on such a VPS, without (or in special cases with only minimal) modification, just like on any real server.<br />
<br />
Each virtual server has its own user account database and root password and is isolated from other virtual servers, except for the fact that they share the same hardware resources.<br />
<br />
== Introduction ==<br />
<br />
Over the years, computers have become sufficiently powerful to use virtualization to create the illusion of many smaller virtual machines, each running a separate operating system instance.<br />
<br />
There are several kinds of Virtual Machines (VMs) which provide similar features, but differ in the degree of abstraction and the methods used for virtualization.<br />
<br />
Most of them accomplish what they do by ''emulating'' some real or fictional hardware, which in turn requires ''real'' resources from the Host (the machine running the VMs). This approach, used by most System Emulators (like QEMU, Bochs, ...), allows the emulator to run an arbitrary Guest Operating System, even for a different Architecture (CPU and Hardware). No modifications need to be made to the Guest OS because it isn't aware of the fact that it isn't running on real hardware.<br />
<br />
Some System Emulators require small modifications or specialized drivers to be added to Host or Guest to improve performance and minimize the overhead required for the hardware emulation. Although this significantly improves efficiency, there are still large amounts of resources being wasted in caches and mediation between Guest and Host (examples for this approach are UML and Xen).<br />
<br />
But suppose you do not want to run many different Operating Systems simultaneously on a single box? Most applications running on a server do not require hardware access or kernel level code, and could easily share a machine with others, if they could be separated and secured...<br />
<br />
== The Concept ==<br />
<br />
At a basic level, a Linux Server consists of three building blocks: Hardware, Kernel and Applications. The Hardware usually depends on the provider or system maintainer, and, while it has a big influence on the overall performance, it cannot be changed that easily, and will likely differ from one setup to another.<br />
<br />
The main purpose of the Kernel is to build an abstraction layer on top of the hardware to allow processes (Applications) to work with and operate on resources (Data) without knowing the details of the underlying hardware. Ideally, those processes would be completely hardware agnostic, by being written in an interpreted language and therefore not requiring any hardware-specific knowledge.<br />
<br />
Given that a system has enough resources to drive ten times the number of applications a single Linux server would usually require, why not put ten servers on that box, which will then share the available resources in an efficient manner?<br />
<br />
Most server applications (e.g. httpd) will assume that it is the only application providing a particular service, and usually will also assume a certain filesystem layout and environment. This dictates that similar or identical services running on the same physical server, but for example, only differing in their addresses, have to be coordinated. This typically requires a great deal of administrative work which can lead to reduced system stability and security.<br />
<br />
The basic concept of the Linux-VServer solution is to separate the user-space environment into distinct units (sometimes called Virtual Private Servers) in such a way that each VPS looks and feels like a real server to the processes contained within.<br />
<br />
Although different Linux Distributions use (sometimes heavily) patched kernels to provide special support for unusual hardware or extra functionality, most Linux Distributions are not tied to a special kernel.<br />
<br />
Linux-VServer uses this fact to allow several distributions, to be run simultaneously on a single, shared kernel, without direct access to the hardware, and share the resources in a very efficient way.<br />
<br />
== Existing Infrastructure ==<br />
<br />
Recent Linux Kernels already provide many security features that are utilized by Linux-VServer to do its work. Especially features such as the Linux Capability System, Resource Limits, File Attributes and the Change Root Environment. The following sections will give a short overview about each of these.<br />
<br />
=== Linux Capability System ===<br />
<br />
In computer science, a capability is a token used by a process to prove that it is allowed to perform an operation on an object. The Linux Capability System is based on "POSIX Capabilities", a somewhat different concept, designed to split up the all powerful root privilege into a set of distinct privileges.<br />
<br />
==== POSIX Capabilities ====<br />
<br />
A process has three sets of bitmaps called the inheritable(I), permitted(P), and effective(E) capabilities. Each capability is implemented as a bit in each of these bitmaps that is either set or unset.<br />
<br />
When a process tries to do a privileged operation, the operating system will check the appropriate bit in the effective set of the process (instead of checking whether the effective uid of the process is 0 as is normally done).<br />
<br />
For example, when a process tries to set the clock, the Linux kernel will check that the process has the CAP_SYS_TIME bit (which is currently bit 25) set in its effective set.<br />
<br />
The permitted set of the process indicates the capabilities the process can use. The process can have capabilities set in the permitted set that are not in the effective set.<br />
<br />
This indicates that the process has temporarily disabled this capability. A process is allowed to set a bit in its effective set only if it is available in the permitted set. The distinction between effective and permitted exists so that processes can "bracket" operations that need privilege.<br />
<br />
The inheritable capabilities are the capabilities of the current process that should be inherited by a program executed by the current process. The permitted set of a process is masked against the inheritable set during exec(). Nothing special happens during fork() or clone(). Child processes and threads are given an exact copy of the capabilities of the parent process.<br />
<br />
The implementation in Linux stopped at this point, whereas POSIX Capabilities[U5] requires the addition of capability sets to files too, to replace the SUID flag (at least for executables). The pending Linux 2.6.24 kernel supports file POSIX capabilities. (See Serge Hallyn's [http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b53767719b6cd8789392ea3e7e2eb7b8906898f0 git commit] of Wed, 17 Oct 2007.) One userspace tool capable of changing file capabilities is the 2.X version of Andrew Morgan's [http://kernel.org/pub/linux/libs/security/linux-privs/ libcap] library and programs.<br />
<br />
==== Capability Overview ====<br />
<br />
The list of POSIX Capabilities used with Linux is long, and the 32 available bits are almost used up. While the detailed list of all capabilities can be found in /usr/include/linux/capability.h on most Linux systems, an overview of important capabilities is given here.<br />
<br />
{| class="wikitablenowrap"<br />
! [0] CAP_CHOWN<br />
| change file ownership and group.<br />
|-<br />
! [5] CAP_KILL<br />
| send a signal to a process with a different real or effective user ID<br />
|-<br />
! [6] CAP_SETGID<br />
| permit setgid(2), setgroups(2), and forged gids on socket credentials passing<br />
|-<br />
! [7] CAP_SETUID<br />
| permit set*uid(2), and forged uids on socket credentials passing<br />
|-<br />
! [8] CAP_SETPCAP<br />
| transfer/remove any capability in permitted set to/from any pid<br />
|-<br />
! [9] CAP_LINUX_IMMUTABLE<br />
| allow modification of S_IMMUTABLE and S_APPEND file attributes<br />
|-<br />
! [11] CAP_NET_BROADCAST<br />
| permit broadcasting and listening to multicast<br />
|-<br />
! [12] CAP_NET_ADMIN<br />
| permit interface configuration, IP firewall, masquerading, accounting, socket debugging, routing tables, bind to any address, enter promiscuous mode, multicasting, ...<br />
|-<br />
! [13] CAP_NET_RAW<br />
| permit usage of RAW and PACKET sockets<br />
|-<br />
! [16] CAP_SYS_MODULE<br />
| insert and remove kernel modules<br />
|-<br />
! [18] CAP_SYS_CHROOT<br />
| permit chroot(2)<br />
|-<br />
! [19] CAP_SYS_PTRACE<br />
| permit ptrace() of any process<br />
|-<br />
! [21] CAP_SYS_ADMIN<br />
| this list would be too long, it basically allows to do everything else, not mentioned in another capability.<br />
|-<br />
! [22] CAP_SYS_BOOT<br />
| permit reboot(2)<br />
|-<br />
! [23] CAP_SYS_NICE<br />
| allow raising priority and setting priority on other processes, modify scheduling<br />
|-<br />
! [24] CAP_SYS_RESOURCE<br />
| override resource limits, quota, reserved space on fs, ...<br />
|-<br />
! [27] CAP_MKNOD<br />
| permit the privileged aspects of mknod(2)<br />
|}<br />
<br />
=== Resource Limits ===<br />
<br />
Resources for each process can be limited by specifying a Resource Limit. Similar to the Linux Capabilities, there are two different limits, a Soft Limit and a Hard Limit.<br />
<br />
The soft limit is the value that the kernel enforces for the corresponding resource. The hard limit acts as a ceiling for the soft limit: an unprivileged process may only set its soft limit to a value in the range from zero up to the hard limit, and (irreversibly) lower its hard limit. A privileged process may make arbitrary changes to either limit value, as long as the soft limit stays below the hard limit.<br />
<br />
==== Limit-able Resource Overview ====<br />
<br />
The list of all defined resource limits can be found in /usr/include/asm/resource.h on most Linux systems, an overview of relevant resource limits is given here.<br />
<br />
{| class="wikitablenowrap"<br />
|-<br />
! [0] RLIMIT_CPU<br />
| CPU time in seconds. process is sent a SIGXCPU signal after reaching the soft limit, and SIGKILL on hard limit.<br />
|-<br />
! [4] RLIMIT_CORE<br />
| maximum size of core files generated<br />
|-<br />
! [5] RLIMIT_RSS<br />
| number of pages the process's resident set can consume (the number of virtual pages resident in RAM)<br />
|-<br />
! [6] RLIMIT_NPROC<br />
| The maximum number of processes that can be created for the real user ID of the calling process.<br />
|-<br />
! [7] RLIMIT_NOFILE<br />
| Specifies a value one greater than the maximum file descriptor number that can be opened by this process.<br />
|-<br />
! [8] RLIMIT_MEMLOCK<br />
| The maximum number of virtual memory pages that may be locked into RAM using mlock() and mlockall().<br />
|-<br />
! [9] RLIMIT_AS<br />
| The maximum number of virtual memory pages available to the process (address space limit). \<br />
|}<br />
<br />
=== File Attributes ===<br />
<br />
Originally, this feature was only available with ext2, but now all major filesystems implement a basic set of File Attributes that permit certain properties to be changed. Here again is a short overview of the possible attributes, and what they mean.<br />
<br />
{| class="wikitablenowrap"<br />
! <br />
! Macro Name<br />
! Meaning<br />
|-<br />
! s <br />
! SECRM<br />
| When a file with this attribute set is deleted, its blocks are zeroed and written back to the disk.<br />
|-<br />
! u <br />
! UNRM<br />
| When a file with this attribute set is deleted, its contents are saved.<br />
|-<br />
! c <br />
! COMPR<br />
| Files marked with this attribute are automatically compressed on write and uncompressed on read. (not implemented yet)<br />
|-<br />
! i <br />
! IMMUTABLE<br />
| A file with this attribute cannot be modified: it cannot be deleted or renamed, no link can be created to this file and no data can be written to the file.<br />
|-<br />
! a <br />
! APPEND<br />
| Files with this attribute set can only be opened in append mode for writing.<br />
|-<br />
! d <br />
! NODUMP<br />
| If this flag is set, the file is not candidate for backup with the dump utility.<br />
|-<br />
! S <br />
! SYNC<br />
| Updates to the file contents are done synchronously.<br />
|-<br />
! A <br />
! NOATIME<br />
| Prevents updating the atime record on files when they are accessed or modified.<br />
|-<br />
! t <br />
! NOTAIL<br />
| A file with the t attribute will not have a partial block fragment at the end of the file merged with other files.<br />
|-<br />
! D <br />
! DIRSYNC<br />
| Changes to a directory having this attribute set will be done synchronously.<br />
|}<br />
<br />
The first column in the above table denotes command line options one might supply to ''lsattr'' respectively ''chattr''. The below screedump gives a notion about what we are talking:<br />
<pre><br />
max@pc1:~$ cd /tmp/<br />
max@pc1:/tmp$ touch my_file<br />
max@pc1:/tmp$ lsattr my_file<br />
------------------ my_file<br />
max@pc1:/tmp$ chattr +a my_file<br />
chattr: Operation not permitted while setting flags on my_file<br />
max@pc1:/tmp$ su<br />
Password:<br />
pc1:/tmp# chattr +a my_file && lsattr my_file<br />
-----a------------ my_file<br />
pc1:/tmp# exit<br />
exit<br />
max@pc1:/tmp$<br />
</pre><br />
<br />
As you might have noticed, one needs to gain root permissions in the upper showcase (the underlying file system was ext3). For more information just issue ''man 1 chattr'' in your command line interface.<br />
<br />
<br />
Information regarding file attributes can be found in the kernel source code. Every file system uses a subset of all known attributes (which are used depends on the file system). <br />
<br />
One thing can be said for sure -- the file attributes listed in the kernel source code are defined -- those are not listed are not defined and in turn can not be used for a particular file system (e.g. ext3 (Extended File System version 3)). However, many of those file attributes defined and understood by the kernel have no effect. Most file systems define those flags in a specific (specific for a particular file system) header file found within the kernel source tree. They also define a so called '''User Modifiable Mask''' (those are the flags the user can change with the ''ioctls'').<br />
<br />
Those flags have partially different meaning depending on the node type (i.e. dir, inode, fifo, pipe, device) and it is not trivial to say if a filesystem makes use of any user modifiable flag -- things like immutable are easy to verify (from user space) but how to verify e.g. NOTAIL from user space? Usually only source code review will show if it is implemented and used.<br />
<br />
For example, if that didn't change, the COMPR is defined, and well understood by ext2/3 but there is no implementation there, i.e. nothing is compressed.<br />
<br />
=== The chroot(1) Command ===<br />
<br />
chroot allows you to run a command with a different directory acting as the root directory. This means that all filesystem lookups are done with '/' referring to the substitute root directory and not to the original one.<br />
<br />
While the Linux chroot implementation isn't very secure, it increases the isolation of processes with regards to the filesystem, and, if used properly, can create a filesystem "jail" for a single process or a restricted user, daemon or service.<br />
<br />
== Required Modifications ==<br />
<br />
This chapter will describe the essential Kernel modifications to implement something like Linux-VServer.<br />
<br />
=== Context Separation ===<br />
<br />
The separation mentioned in the Concepts section requires some modifications to the kernel to allow for the notion of Contexts.<br />
The purpose of this "Context" is to hide all processes outside of its scope, and prohibit any unwanted interaction between a process inside the context and a process belonging to another context.<br />
<br />
This separation requires the extension of some existing data structures in order for them to become aware of contexts and to differentiate between identical uids used in different virtual servers.<br />
<br />
It also requires the definition of a default context that is used when the host system is booted, and to work around the issues resulting from some false assumptions made by some user-space tools (like pstree) that the init process has to exist and to be running under id '1'.<br />
<br />
To simplify administration, the Host Context isn't treated any differently than any other context as far as process isolation is concerned. To allow for process overview, a special Spectator context has been defined to peek at all processes at once.<br />
<br />
=== Network Separation ===<br />
<br />
While the Context Separation is sufficient to isolate groups of processes, a different kind of separation, or rather a limitation, is required to confine processes to a subset of available network addresses.<br />
<br />
Several issues have to be considered when doing so; for example, the fact that bindings to special addresses like IPADDR_ANY or the local host address have to be handled in a very special way.<br />
<br />
Currently, Linux-VServer doesn't make use of virtual network devices (and maybe never will) to minimize the resulting overhead. Therefore socket binding and packet transmission have been adjusted.<br />
<br />
=== The Chroot Barrier ===<br />
<br />
One major problem of the chroot() system used in Linux lies within the fact that this information is volatile, and will be changed on the next chroot() Syscall.<br />
<br />
One simple method to escape from a chroot-ed environment is as follows: First, create or open a file and retain the file-descriptor, then chroot into a subdirectory at equal or lower level with regards to the file. This causes the root to be moved down in the filesystem. Next, use fchdir() on the file-descriptor to escape from that new root. This will consequently escape from the old root as well, as this was lost in the last chroot() Syscall.<br />
<br />
While early Linux-VServer versions tried to fix this by "funny" methods, recent versions use a special marking, known as the Chroot Barrier, on the parent directory of each VPS to prevent unauthorized modification and escape from confinement.<br />
<br />
=== Upper Bound for Caps ===<br />
<br />
Because the current Linux Capability system does not implement the filesystem related portions of POSIX Capabilities which would make setuid and setgid executables secure, and because it is much safer to have a secure upper bound for all processes within a context, an additional per-context capability mask has been added to limit all processes belonging to that context to this mask.<br />
<br />
The meaning of the individual caps (bits) of the capability bound mask is exactly the same as with the permitted capability set.<br />
<br />
=== Resource Isolation ===<br />
<br />
Most resources are somewhat shared among the different contexts. Some require more additional isolation than others, either to avoid security issues or to allow for improved accounting.<br />
<br />
Those resources are:<br />
<br />
* shared memory, IPC<br />
* user and process IDs<br />
* file xid tagging<br />
* Unix ptys<br />
* sockets<br />
<br />
=== Filesystem XID Tagging ===<br />
<br />
Although it can be disabled completely, this modification is required for more robust filesystem level security and context isolation. It is also mandatory for Context Disk Limits and Per Context Quota Support on a shared partition.<br />
<br />
The concept of adding a context id (xid) to each file to make the context ownership persistent sounds simple, but the actual implementation is non-trivial - mainly because adding this information either requires a change to the on disk representation of the filesystem or the application of some tricks.<br />
<br />
One non-intrusive approach to avoid modification of the underlying filesystem is to use the upper bits of existing fields, like those for UID and GID to store the additional XID.<br />
<br />
Once context information is available for each inode, it is a logical step to extend the access controls to check against context too.<br />
Currently all inode access restrictions have been extended to check for the context id, with special exceptions for the Host Context and the Spectator Context.<br />
<br />
Untagged files belong to the Host Context and are silently treated as if they belong to the current context, which is required for Unification. If such a file is modified from inside a context, it silently migrates to the new one, changing its xid.<br />
<br />
The following Tagging Methods are implemented:<br />
{| class="wikitablenowrap"<br />
! UID32/GID32 or EXTERNAL<br />
| This format uses currently unused space within the disk inode to store the context information. As of now, this is only defined for ext2/ext3 but will be also defined for xfs, reiserfs, and jfs as soon as possible. Advantage: Full 32bit uid/gid values.<br />
|-<br />
! UID32/GID16<br />
| This format uses the upper half of the group id to store the context information. This is done transparently, except if the format is changed without prior file conversion. Advantage: works on all 32bit U/GID FSs. Drawback: GID is reduced to 16 bits.<br />
|-<br />
! UID24/GID24<br />
| This format uses the upper quarter of user and group id to store the context information, again transparently. This allows for about 16 million user and group ids, which should suffice for the majority of all applications. Advantage: works on all 32bit U/GID FSs. Drawback: UID and GID are reduced to 24 bits.<br />
|}<br />
<br />
== Additional Modifications ==<br />
<br />
In addition to the bare minimum, there are a number of modifications that are not mandatory, but have proven extremely useful over time.<br />
<br />
=== Context Flags ===<br />
<br />
It was very soon discovered that some features require a flag, a kind of switch to turn them on and off separately for each Linux-VServer, so a simple flag-word was added.<br />
<br />
This flag-word supports quite a number of flags, a flag-word mask, which allows to tell what flags are available, and a special trigger mechanism, providing one-time flags, set on startup, that can only be cleared once, usually causing a special action or event.<br />
<br />
Here is a list of planned and mostly implemented Context Flags, available in the development branch of Linux-VServer:<br />
<br />
{| class="wikitablenowrap"<br />
! [0] VXF_INFO_LOCK<br />
| (legacy, obsoleted)<br />
|-<br />
! [1] VXF_INFO_SCHED<br />
| schedule all processes in a context as if they where one. (legacy, obsoleted)<br />
|-<br />
! [2] VXF_INFO_NPROC<br />
| limit the number of processes in a context to the initial NPROC value. (legacy, obsoleted)<br />
|-<br />
! [3] VXF_INFO_PRIVATE<br />
| do not allow to join this context from outside. (legacy)<br />
|-<br />
! [4] VXF_INFO_INIT<br />
| show the init process with pid '1' (legacy)<br />
|-<br />
! [5] VXF_INFO_HIDE<br />
| (legacy, obsoleted)<br />
|-<br />
! [6] VXF_INFO_ULIMIT<br />
| (legacy, obsoleted)<br />
|-<br />
! [7] VXF_INFO_NSPACE<br />
| (legacy, obsoleted)<br />
|-<br />
! [8] VXF_SCHED_HARD<br />
| activate the Hard CPU scheduling<br />
|-<br />
! [9] VXF_SCHED_PRIO<br />
| use the context token bucket for calculating the process priorities<br />
|-<br />
! [10] VXF_SCHED_PAUSE<br />
| put all processes in this context on the hold queue, not scheduling them any longer<br />
|-<br />
! [16] VXF_VIRT_MEM<br />
| virtualize the memory information so that the VM and RSS limits are used for meminfo and friends<br />
|-<br />
! [17] VXF_VIRT_UPTIME<br />
| virtualize the uptime, beginning with the time of context creation<br />
|-<br />
! [18] VXF_VIRT_CPU<br />
|<br />
|-<br />
! [24] VXF_HIDE_MOUNT<br />
| show empty proc/{pid}/mounts<br />
|-<br />
! [25] VXF_HIDE_NETIF<br />
| hide network interfaces and addresses not permitted by the network context<br />
|}<br />
<br />
=== Context Capabilities ===<br />
<br />
As the Linux Capabilities have almost reached the maximum number that is possible without heavy modifications to the kernel, it was a natural step to add a context-specific capability system.<br />
<br />
The Linux-VServer context capability set acts as a mechanism to fine tune existing Linux capabilities. It is not visible to the processes within a context, as they would not know how to modify or verify it.<br />
<br />
In general there are two ways to use those capabilities:<br />
<br />
* Require one or a number of context capabilities to be set in addition to a given Linux capability, each one controlling a distinct part of the functionality.For example the CAP_NET_ADMIN could be split into RAW and PACKET sockets, so you could take away each of them separately by not providing the required context capability.<br />
<br />
* Consider the context capability sufficient for a specified functionality, even if the Linux Capability says something different.For example mount() requires CAP_SYS_ADMIN which adds a dozen other things we do not want, so we define a CCAP_MOUNT to allow mounts for certain contexts.<br />
The difference between the Context Flags and the Context Caps is more an abstract logical separation than a functional one, because they are handled very similarly.<br />
<br />
Again, a list of the Context Capabilities and their purpose:<br />
<br />
<br />
{| class="wikitablenowrap"<br />
! [0] VXC_SET_UTSNAME<br />
| allow the context to change the host and domain name with the appropriate kernel Syscall<br />
|-<br />
! [1] VXC_SET_RLIMIT<br />
| allow the context to modify the resource limits (within the vserver limits).<br />
|-<br />
! [8] VXC_RAW_ICMP<br />
| allow raw icmp packets in a secure way (this makes ping work from inside)<br />
|-<br />
! [16] VXC_SECURE_MOUNT<br />
| permit secure mounts, which at the moment means that the nodev mount option is added.<br />
|}<br />
<br />
=== Context Accounting ===<br />
<br />
Some properties of a context are useful to the admin, either for keeping an overview of the resources, to get a feeling for the capacity of the host, or for billing them in some way to a customer.<br />
<br />
There are two different kinds of accountable properties, those having a current value which represents the state of the system (for example the speed of a vehicle), and those which monotonically increase over time (like the mileage).<br />
<br />
Most of the state type of properties also qualify for applying some limits, so they are handled specially. this is described in more detail in the following section.<br />
<br />
Good candidates for Context Accounting are:<br />
<br />
* Amount of CPU Time spent<br />
* Number of Forks done<br />
* Socket Messages by Type<br />
* Network Packets Transmitted and Received<br />
<br />
=== Context Limits ===<br />
<br />
Most properties related to system resources, might it be the memory consumption, the number of processes or file-handles, or the current network bandwidth, qualify for imposing limits on them.<br />
<br />
To provide a general framework for all kinds of limits, Context Limits allow the configuration of three different values for each limit-able resource: the minimum, a soft limit and a hard limit (maximum).<br />
<br />
At the time this is written, only the hard limits are supported and not all of them are actually enforced, but here is a list of current and planned Context Limits:<br />
<br />
* process limits<br />
* scheduler limits<br />
* memory limits<br />
* per-context disk limits<br />
* per-context user/group quota<br />
<br />
Additionally the context limit system keeps track of observed maxima and resource limit hits, to provide some feedback for the administrator.<br />
<br />
=== Virtualization ===<br />
<br />
One major difference between the Linux-VServer approach and Virtual Machines is that you do not have the virtualization part as a side-effect, so you have to do that by hand where it makes sense.<br />
<br />
For example, a Virtual Machine does not need to think about uptime, because naturally the running OS was started somewhere in the past and will not have any problem to tell the time it thinks it began running.<br />
<br />
A context can also store the time when it was created, but that will be different from the systems uptime, so in addition, there has to be some function, which adjusts the values passed from kernel to user-space depending on the context the process belongs to.<br />
<br />
This is what for Linux-VServer is known as Virtualization (actually it's more faking some values passed to and from the kernel to make the processes think that they are on a different machine).<br />
<br />
Currently modified for the purpose of Virtualization are:<br />
<br />
* System Uptime<br />
* Host and Domain Name<br />
* Machine Type and Kernel Version<br />
* Context Memory Availability<br />
* Context Disk Space<br />
<br />
=== Improved Security ===<br />
<br />
Proc-FS Security provides a mechanism to protect dynamic entries in the proc filesystem from being seen in every context.<br />
The system consists of three flags for each Proc-FS entry: Admin, Watch and Hide.<br />
<br />
The Hide flag enables or disables the entire feature, so any combination with the Hide flag cleared will mean total visibility.<br />
The Admin and Watch flags determine where the hidden entry remains visible; so for example if Admin and Hidden are set, the Host Context will be the only one able to see this specific entry.<br />
<br />
=== Kernel Helper ===<br />
<br />
For some purposes, it makes sense to have an user-space tool to act on behalf of the kernel, when a process inside a context requests something usually available on a real server, but naturally not available inside a context.<br />
<br />
The best, and currently only example for this is the Reboot Helper, which handles the reboot() system call, invoked from inside a context on behalf of the Kernel. It is executed, in Host side user-space to take appropriate actions - either reboot or just shutdown (halt) the specified context.<br />
<br />
While the helper is designed to be flexible and handle different things in a similar way there are no other users of this helper at the moment. It might be replaced by an event interface in near future.<br />
<br />
== Features and Bonus Material ==<br />
<br />
=== Unification ===<br />
<br />
Because one of the central objectives for Linux-VServer is to reduce the overall resource usage wherever possible, a truly great idea was born to share files between different contexts without interfering with the usual administrative tasks or reducing the level of security created by the isolation.<br />
<br />
Files common to more than one context, which are not very likely going to change, like libraries or binaries, can be hard linked on a shared filesystem, thus reducing the amount of disk space, inode caches, and even memory mappings for shared libraries.<br />
<br />
The only drawback is that without additional measures, a malicious context would be able to deliberately or accidentally destroy or modify such shared files, which in turn would harm the other contexts.<br />
<br />
One step is to make the shared files immutable by using the Immutable File Attribute (and removing the Linux Capability required to modify this attribute). However an additional attribute is required to allow removal of such immutable shared files, to allow for updates of libraries or executables from inside a context.<br />
<br />
Such hard linked, immutable but unlink-able files belonging to more than one context are called unified and the process of finding common files and preparing them in this way is called Unification.<br />
<br />
The reason for doing this is reduced resource consumption, not simplified administration. While a typical Linux Server install will consume about 500MB of disk space, 10 unified servers will only need about 700MB and as a bonus use less memory for caching.<br />
<br />
=== Private Namespaces ===<br />
<br />
A recent addition to the Linux-VServer branch was the introduction of Private Namespaces. This uses the already existing Virtual Filesystem Layer of the Linux kernel to create a separate view of the filesystem for the processes belonging to a context.<br />
<br />
The major advantage over the shared namespace used by default is that any modifications to the namespace layout (like mounts) do not affect other contexts, not even the Host Context.<br />
<br />
Obviously the drawback of that approach is that entering such a Private Namespace isn't as trivial as changing the root directory, but with proper kernel support this will completely replace the chroot() in the future.<br />
<br />
=== The Linux-VServer Proc-FS ===<br />
<br />
A structured, dynamically generated subtree of the well-known Proc-FS - actually two of them - has been created to allow for inspecting the different values of Security and Network Contexts.<br />
<br />
<pre><br />
/proc/virtual<br />
.../info<br />
<br />
/proc/virtual/<pid><br />
.../info<br />
.../status<br />
.../sched<br />
.../cvirt<br />
.../cacct<br />
.../limit<br />
</pre><br />
<br />
=== Token Bucket Extensions ===<br />
<br />
While the basic idea of Linux-VServer is a peaceful coexistence of all contexts, sharing the common resources in a respectful way, it is sometimes useful to control the resource distribution for resource hungry processes.<br />
<br />
The basic principle of a Token Bucket is not very new. It is given here as an example for the Hard CPU Limit. The same principle also applies to scheduler priorities, network bandwidth limitation and resource control in general.<br />
<br />
The Hard CPU Limit uses this mechanism in the following way: consider a bucket of a certain size S which is filled with a specified amount of tokens R every interval T, until the bucket is "full" - excess tokens are spilled. At each timer tick, a running process consumes exactly one token from the bucket, unless the bucket is empty, in which case the process is put on a hold queue until the bucket has been refilled with a minimum M of tokens. The process is then rescheduled.<br />
<br />
A major advantage of a Token Bucket is that a certain amount of tokens can be accumulated in times of quiescence, which later can be used to burst when resources are required.<br />
<br />
Where a per-process Token Bucket would allow for a CPU resource limitation of a single process, a Context Token Bucket allows to control the CPU usage of all confined processes.<br />
<br />
Another approach, which is also implemented, is to use the current fill level of the bucket to adjust the process priority, thus reducing the priority of processes belonging to excessive contexts.<br />
<br />
=== Context Disk Limits ===<br />
<br />
This Feature requires the use of XID Tagged Files, and allows for independent Disk Limits for different contexts on a shared partition.<br />
The number of inodes and blocks for each filesystem is accounted, if an XID-Hash was added for the Context-Filesystem combo.<br />
<br />
Those values, including current usage, maximum and reserved space, will be shown for filesystem queries, creating the illusion that the shared filesystem has a different usage and size, for each context.<br />
<br />
=== Per-Context Quota ===<br />
<br />
Similar to the Context Disk Limits, Per-Context Quota uses separate quota hashes for different Contexts on a shared filesystem. This is not required to allow for Linux-VServer quota on separate partitions.<br />
<br />
=== The VRoot Proxy Device ===<br />
<br />
Quota operations (ioctls) require some access to the block device, which for security reasons is not available inside a VPS.<br />
<br />
=== Stealth ===<br />
<br />
For some applications, for example the preparation of a honey-pot or an especially realistic imitation of a real server for educational purposes, it can make sense to make the context indistinguishable from a real server.<br />
<br />
However, since other freely available alternatives like QEMU or UML are much better at this, and require much less effort, this is not a central issue in Linux-VServer development.<br />
<br />
== Linux-VServer Security ==<br />
<br />
Now that we know what the Linux-VServer framework provides and how some features work, let's have a word on security, because you should not rely on the framework to be secure per definition. Instead, you should exactly know what you are doing.<br />
<br />
=== Secure Capabilities ===<br />
<br />
Currently the following Linux Capabilities are considered secure for VPS use. If others are added, it will probably open some security hole.<br />
<br />
* CAP_CHOWN<br />
* CAP_DAC_OVERRIDE<br />
* CAP_DAC_READ_SEARCH<br />
* CAP_FOWNER<br />
* CAP_FSETID<br />
* CAP_KILL<br />
* CAP_SETGID<br />
* CAP_SETUID<br />
* CAP_NET_BIND_SERVICE<br />
* CAP_SYS_CHROOT<br />
* CAP_SYS_PTRACE<br />
* CAP_SYS_BOOT<br />
* CAP_SYS_TTY_CONFIG<br />
* CAP_LEASE<br />
<br />
CAP_NET_RAW for example is not considered secure although it is often used to allow the broken ping command to work, although there are better alternatives like the userspace ping command poink[U7] or the VXC_RAW_ICMP Context Capability.<br />
<br />
=== The Chroot Barrier ===<br />
<br />
Ensuring that the Barrier flag is set on the parent directory of each VPS is vital if you do not want VPS root to escape from the confinement and walk your Host's root filesystem.<br />
<br />
=== Secure Device Nodes ===<br />
<br />
The /dev directory of a VPS should not contain more than the following devices and the one directory for the unix pts tree.<br />
<br />
* c 1 7 full<br />
* c 1 3 null<br />
* c 5 2 ptmx<br />
* c 1 8 random<br />
* c 5 0 tty<br />
* c 1 9 urandom<br />
* c 1 5 zero<br />
* d pts<br />
<br />
Of course other device nodes like console, mem and kmem, even block and character devices can be added, but some expertise is required in order to ensure no security holes are opened.<br />
<br />
=== Secure Proc-FS Entries ===<br />
<br />
There has been no detailed evaluation of secure and unsecure entries in the proc filesystem, but there have been some incidents where unprotected (not protected via Linux Capabilities) writable proc entries caused mayhem.<br />
<br />
For example, /proc/sysrq-trigger is something which should not be accessible inside a VPS without a very good reason.<br />
<br />
== Field of Application ==<br />
<br />
The primary goal of this project is to create virtual servers sharing the same machine. A virtual server operates like a normal Linux server. It runs normal services such as telnet, mail servers, web servers, and SQL servers.<br />
<br />
=== Administrative Separation ===<br />
<br />
This allows a clever provider to sell something called Virtual Private Server, which uses less resources than other virtualization techniques, which in turn allows more units on a single machine.<br />
<br />
The list of providers doing so is relatively long, and so this is rightfully considered the main area of application.<br />
<br />
=== Service Separation ===<br />
<br />
Separating different or similar services which otherwise would interfere with each other, either because they are poorly designed or because they are simply incapable of peaceful coexistence for whatever reason, can be easily done with Linux-VServer.<br />
<br />
But even on the old-fashioned real server machines, putting some extremely exposed or untrusted, because unknown or proprietary, services into some kind of jail can improve maintainability and security a lot.<br />
<br />
=== Enhancing Security ===<br />
<br />
While it can be interesting to run several virtual servers in one box, there is one concept potentially more generally useful. Imagine a physical server running a single virtual server. The goal is isolate the main environment from any service, any network. You boot in the main environment, start very few services and then continue in the virtual server.<br />
<br />
The service in the main environment would be:<br />
<br />
* Unreachable from the network.<br />
* Able to log messages from the virtual server in a secure way. The virtual server would be unable to change/erase the logs.\ Even a cracked virtual server would not be able the edit the log.<br />
* Able to run intrusion detection facilities, potentially spying the state of the virtual server without being accessible or noticed.\ For example, tripwire could run there and it would be impossible to circumvent its operation or trick it.<br />
<br />
Another option is to put the firewall in a virtual server, and pull in the DMZ, containing each service in a separate VPS. On proper configuration, this setup can reduce the number of required machines drastically, without impacting performance.<br />
<br />
=== Easy Maintenance ===<br />
<br />
One key feature of a virtual server is the independence from the actual hardware. Most hardware issues are irrelevant for a virtual server installation.<br />
<br />
The main server acts as a host and takes care of all the details. The virtual server is just a client and ignores all the details. As such, the client can be moved to another physical server with very few manipulations.<br />
<br />
For example, to move the virtual server from one physical computer to another, it is sufficient to do the following:<br />
<br />
* shutdown the running server<br />
* copy it over to the other machine<br />
* copy the configuration<br />
* start the virtual server on the new machine<br />
<br />
No adjustments to user setup, password database or hardware configuration are required, as long as both machines are binary compatible.<br />
<br />
=== Fail-over Scenarios ===<br />
<br />
Pushing the limit a little further, replication technology could be used to keep an up-to-the-minute copy of the filesystem of a running Virtual Server. This would permit a very fast fail-over if the running server goes offline for whatever reason.<br />
<br />
All the known methods to accomplish this, starting with network replication via rsync, or drbd, via network devices, or shared disk arrays, to distributed filesystems, can be utilized to reduce the down-time and improve overall efficiency.<br />
<br />
=== For Testing ===<br />
<br />
Consider a software tool or package which should be built for several versions of a specific distribution (Mandrake 8.2, 9.0, 9.1, 9.2, 10.0) or even for different distributions.<br />
<br />
This is easily solved with Linux-VServer. Given plenty of disk space, the different distributions can be installed and running side by side, simplifying the task of switching from one to another.<br />
<br />
Of course this can be accomplished by chroot() alone, but with Linux-VServer it's a much more realistic simulation.<br />
<br />
== Performance and Stability ==<br />
<br />
''(work in progress)''<br />
<br />
=== Impact of Linux-VServer on the Host ===<br />
<br />
seems to be 0% ...<br />
<br />
=== Overhead inside a Context ===<br />
<br />
seems to be less than 2% ...<br />
<br />
=== Size of the Kernel Patch ===<br />
<br />
Comparison of the different patches ...<br />
<br />
{| class="wikitablenowrap"<br />
! patch<br />
! hunks<br />
! +<br />
! -<br />
|-<br />
| patch-2.4.24-vs1.00.diff<br />
| 178<br />
| 1112<br />
| 135 <br />
|-<br />
| patch-2.4.24-vs1.20.diff<br />
| 216<br />
| 2035<br />
| 178 <br />
|-<br />
| patch-2.4.24-vs1.26.diff<br />
| 225<br />
| 2118<br />
| 180 <br />
|-<br />
| patch-2.4.25-vs1.27.diff<br />
| 252<br />
| 2166<br />
| 201 <br />
|-<br />
| patch-2.4.26-vs1.28.diff<br />
| 254<br />
| 2183<br />
| 202 <br />
|-<br />
| patch-2.6.6-vs1.9.0.diff<br />
| 494<br />
| 5699<br />
| 303 <br />
|-<br />
| patch-2.6.6-vs1.9.1.diff<br />
| 497<br />
| 5878<br />
| 307 <br />
|-<br />
| patch-2.6.7-vs1.9.2.diff<br />
| 618<br />
| 6836<br />
| 348 <br />
|-<br />
| uml-patch-2.4.26-1.diff<br />
| 449<br />
| 36885<br />
| 48<br />
|}<br />
<br />
== Non Intel i386 Hardware ==<br />
<br />
Linux-VServer was designed to be mostly architecture agnostic, therefore only a small part, the syscall definition itself, is architecture specific. Nevertheless some architectures have private copies of basically architecture independent code for whatever reason, and therefore small modifications are often required.<br />
<br />
The following architectures are supported and some of them are even tested:<br />
<br />
* alpha<br />
* ia32 / ia64 / xbox<br />
* x86_64 (AMD64)<br />
* mips / mips64<br />
* hppa / hppa64<br />
* ppc / ppc64<br />
* sparc / sparc64<br />
* s390<br />
* uml<br />
<br />
Adding a new architecture is relatively simple although extensive testing is required to make sure that every feature is working as expected (and of course, the hardware ;).<br />
<br />
== Linux Kernel Intro ==<br />
<br />
While almost all of the described features reside in the Linux Kernel, nifty Userspace Tools are required to activate and control the new functionality.<br />
<br />
Those Userspace Tools in general communicate with the Linux Kernel via System Calls (or Syscall for short).<br />
This chapter will give a short overview how Linux Kernel and User Space is organized and how Syscalls, a simple method of communication between processes and kernel, work.<br />
<br />
=== Kernel and User Space ===<br />
<br />
In Linux and similar Operating Systems, User and Kernel Space is separated, and address space is divided into two parts. Kernel space is where the kernel code resides, and user space is where the user programs live. Of course, a given user program can't write to kernel memory or to another program's memory area.<br />
<br />
Unfortunately, this is also the case for kernel code. Kernel code can't write to user space either. What does this mean? Well, when a given hardware driver wants to write data bytes to a program in user memory, it can't do it directly, but rather it must use specific kernel functions instead. Also, when parameters are passed by address to a kernel function, the kernel function can not read the parameters directly. It must use other kernel functions to read each byte of the parameters.<br />
<br />
Of course, there are some helpers which do the transfer to and from user space.<br />
<br />
<pre><br />
copy_to_user(void *to, const void *from, long n);<br />
copy_from_user(void *to, const void *from, long n);<br />
</pre><br />
<br />
get_user() and put_user() Get or put the given byte, word, or long from or to user memory. This is a macro, and it relies on the type of the argument to determine the number of bytes to transfer.<br />
<br />
=== Linux Syscalls ===<br />
<br />
Most libc calls rely on system calls, which are the simplest kernel functions a user program can call.<br />
<br />
These system calls are implemented in the kernel itself or in loadable kernel modules, which are little chunks of dynamically link-able kernel code.<br />
<br />
Linux system calls are implemented through a multiplexor called with a given maskable interrupt. In Linux, this interrupt is int 0x80. When the 'int 0x80' instruction is executed, control is given to the kernel (or, more accurately, to the _system_call() function), and the actual demultiplexing process occurs.<br />
<br />
How does _system_call() work ?<br />
<br />
First, all registers are saved and the content of the %eax register is checked against the global system calls table, which enumerates all system calls and their addresses.<br />
<br />
This table can be accessed with the extern void *sys_call_table[] variable. A given number and memory address in this table corresponds to each system call.<br />
<br />
System call numbers can be found in /usr/include/sys/syscall.h.<br />
<br />
They are of the form SYS_systemcallname. If the system call is not implemented, the corresponding cell in the sys_call_table is 0, and an error is returned.<br />
<br />
Otherwise, the system call actually exists and the corresponding entry in the table is the memory address of the system call code.<br />
<br />
== Kernel Side Implementation ==<br />
<br />
While this chapter is mainly of interest to kernel developers it might be fun to take a small peek behind the curtain to get a glimpse how everything really works.<br />
<br />
=== The Syscall Command Switch ===<br />
<br />
For a long time Linux-VServer used a few different Syscalls to accomplish different aspects of the work, but very soon the number of required commands grew large, and the Syscalls started to have magic values, selecting the desired behavior.<br />
<br />
Not too long ago, a single syscall was reserved for Linux-VServer, and while the opinion on that might differ from developer to developer, it was generally considered a good decision not to have more than one syscall.<br />
<br />
The advantage of different Syscalls would be simpler handling of the Syscalls on different architectures; however, this hasn't been a problem so far, as the data passed to and from the kernel has strong typed fields conforming to the C99 types.<br />
<br />
Regardless, the availability of one system call required the creation of a multiplexor, which decides, based on some selector, what specific command is to be executed, and then passes on the remaining arguments to that command, which does the actual work.<br />
<br />
<pre><br />
extern asmlinkage long<br />
sys_vserver(uint32_t cmd, uint32_t id, void __user *data)<br />
</pre><br />
<br />
The Linux-VServer syscall is passed three arguments regardless of what actual command is specified: a command (cmd), a number (id), and a user-space data-structure of yet unknown size.<br />
<br />
To allow for some structure for debugging purposes and some kind of command versioning, the cmd is split into three parts: the lower 12 bit contain a version number, then 4 bits are reserved, the upper 16 bits are divided into 8 bit command and 6 bit category, again reserving 2 bits for the future.<br />
<br />
There are 64 Categories with up to 256 commands in each category, allowing for 4096 revisions of each command, which is far more than will ever be required.<br />
<br />
Here is an overview of the categories already defined, and their numerical value:<br />
<br />
<pre><br />
Syscall Matrix V2.6<br />
<br />
|VERSION|CREATE |MODIFY |MIGRATE|CONTROL|EXPERIM| |SPECIAL|SPECIAL|<br />
|STATS |DESTROY|ALTER |CHANGE |LIMIT |TEST | | | |<br />
|INFO |SETUP | |MOVE | | | | | |<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
SYSTEM |VERSION|VSETUP |VHOST | | | | |DEVICES| |<br />
HOST | 00| 01| 02| 03| 04| 05| | 06| 07|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
CPU | |VPROC |PROCALT|PROCMIG|PROCTRL| | |SCHED. | |<br />
PROCESS| 08| 09| 10| 11| 12| 13| | 14| 15|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
MEMORY | | | | | | | |SWAP | |<br />
| 16| 17| 18| 19| 20| 21| | 22| 23|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
NETWORK| |VNET |NETALT |NETMIG |NETCTL | | |SERIAL | |<br />
| 24| 25| 26| 27| 28| 29| | 30| 31|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
DISK | | | | | | | |INODE | |<br />
VFS | 32| 33| 34| 35| 36| 37| | 38| 39|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
OTHER | | | | | | | |VINFO | |<br />
| 40| 41| 42| 43| 44| 45| | 46| 47|<br />
=======+=======+=======+=======+=======+=======+=======+ +=======+=======+<br />
SPECIAL| | | | |FLAGS | | | | |<br />
| 48| 49| 50| 51| 52| 53| | 54| 55|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
SPECIAL| | | | |RLIMIT |SYSCALL| | |COMPAT |<br />
| 56| 57| 58| 59| 60|TEST 61| | 62| 63|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
</pre><br />
<br />
The definition of those Commands is simplified by some macros, so for example the commands to get and set the Context Flags are defined like this:<br />
<br />
<pre><br />
#define VCMD_get_cflags VC_CMD(FLAGS, 1, 0)<br />
#define VCMD_set_cflags VC_CMD(FLAGS, 2, 0)<br />
<br />
extern int vc_get_cflags(uint32_t, void __user *);<br />
extern int vc_set_cflags(uint32_t, void __user *);<br />
</pre><br />
<br />
Note that the command itself is not passed to the actual command implementation, only the id and the pointer to user-space data.<br />
<br />
=== Utilized Data Structures ===<br />
<br />
There are many different data structures used by different parts of the implementation; while only a few examples are given here, all utilized structures can be found in the source.<br />
<br />
==== The Context Data Structure ====<br />
<br />
The Context Data Structure consists of a few fields required to manage the contexts, and handle context destruction, as well as future hierarchical contexts.<br />
<br />
Logically separated sections of that structure, like for the scheduler or the context limits are defined in separate structures, and incorporated into the main one.<br />
<br />
<pre><br />
struct vx_info {<br />
struct list_head vx_list; /* linked list of contexts */<br />
xid_t vx_id; /* context id */<br />
atomic_t vx_refcount; /* refcount */<br />
struct vx_info *vx_parent; /* parent context */<br />
<br />
struct namespace *vx_namespace; /* private namespace */<br />
struct fs_struct *vx_fs; /* private namespace fs */<br />
uint64_t vx_flags; /* context flags */<br />
uint64_t vx_bcaps; /* bounding caps (system) */<br />
uint64_t vx_ccaps; /* context caps (vserver) */<br />
<br />
pid_t vx_initpid; /* PID of fake init process */<br />
<br />
struct _vx_limit limit; /* vserver limits */<br />
struct _vx_sched sched; /* vserver scheduler */<br />
struct _vx_cvirt cvirt; /* virtual/bias stuff */<br />
struct _vx_cacct cacct; /* context accounting */<br />
<br />
char vx_name[65]; /* vserver name */<br />
};<br />
</pre><br />
<br />
Here as example the Scheduler Substructure:<br />
<pre><br />
struct _vx_sched {<br />
spinlock_t tokens_lock; /* lock for this structure */<br />
<br />
int fill_rate; /* Fill rate: add X tokens ... */<br />
int interval; /* Divisor: ... each Y jiffies */<br />
atomic_t tokens; /* current number of tokens */<br />
int tokens_min; /* Limit: minimum for unhold */<br />
int tokens_max; /* Limit: no more than N tokens */<br />
uint32_t jiffies; /* bias: integral multiple of Y */<br />
<br />
uint64_t ticks; /* token tick events */<br />
cpumask_t cpus_allowed; /* cpu mask for context */<br />
};<br />
</pre><br />
<br />
The main idea behind this separation is that each substructure belongs to a logically distinct part of the implementation which provides an init and cleanup function for this structure, thus simplifying maintainability and readability of those structures.<br />
<br />
==== The Scheduler Command Data ====<br />
<br />
As an example for the data structure used to control a specific part of the context from user-space, here is a scheduler command and the utilized data structure to set the properties:<br />
<br />
<pre><br />
#define VCMD_set_sched VC_CMD(SCHED, 1, 2)<br />
<br />
struct vcmd_set_sched_v2 {<br />
int32_t fill_rate; /* Fill rate: add X tokens ... */<br />
int32_t interval; /* Divisor: ... each Y jiffies */<br />
int32_t tokens; /* current number of tokens */<br />
int32_t tokens_min; /* Limit: minimum for unhold */<br />
int32_t tokens_max; /* Limit: no more than N tokens */<br />
uint64_t cpu_mask; /* Mask: allowed cpus */<br />
};<br />
</pre><br />
<br />
==== Example Accounting: Sockets ====<br />
<br />
Basically all the accounting and limit stuff are defined as macros or inline functions capable of handling the different resources, hiding the underlying implementation wherever possible.<br />
<br />
<pre><br />
#define vx_acc_sock(v,f,p,s) \<br />
__vx_acc_sock((v), (f), (p), (s), __FILE__, __LINE__)<br />
<br />
static inline void __vx_acc_sock(struct vx_info *vxi,<br />
int family, int pos, int size, char *file, int line)<br />
{<br />
if (vxi) {<br />
int type = vx_sock_type(family);<br />
<br />
atomic_inc(&vxi->cacct.sock[type][pos].count);<br />
atomic_add(size, &vxi->cacct.sock[type][pos].total);<br />
}<br />
}<br />
<br />
#define vx_sock_recv(sk,s) \<br />
vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 0, (s))<br />
#define vx_sock_send(sk,s) \<br />
vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 1, (s))<br />
#define vx_sock_fail(sk,s) \<br />
vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 2, (s))<br />
</pre><br />
<br />
And this general definition is then used where appropriate, for example in the __sock_sendmsg() function like this:<br />
<br />
<pre><br />
len = sock->ops->sendmsg(iocb, sock, msg, size);<br />
if (sock->sk) {<br />
if (len == size)<br />
vx_sock_send(sock->sk, size);<br />
else<br />
vx_sock_fail(sock->sk, size);<br />
}<br />
</pre><br />
<br />
==== Example Limits: Virtual Memory ====<br />
<br />
<pre><br />
#define vx_pages_avail(m, p, r) \<br />
__vx_pages_avail((m)->mm_vx_info, (r), (p), __FILE__, __LINE__)<br />
<br />
static inline int __vx_pages_avail(struct vx_info *vxi,<br />
int res, int pages, char *file, int line)<br />
{<br />
if (!vxi)<br />
return 1;<br />
if (vxi->limit.rlim[res] == RLIM_INFINITY)<br />
return 1;<br />
if (atomic_read(&vxi->limit.res[res]) +<br />
pages < vxi->limit.rlim[res])<br />
return 1;<br />
return 0;<br />
}<br />
<br />
#define vx_vmpages_avail(m,p) vx_pages_avail(m, p, RLIMIT_AS)<br />
#define vx_vmlocked_avail(m,p) vx_pages_avail(m, p, RLIMIT_MEMLOCK)<br />
#define vx_rsspages_avail(m,p) vx_pages_avail(m, p, RLIMIT_RSS)<br />
</pre><br />
<br />
And again the test against those limits at certain places, for example here in copy_process()<br />
<br />
<pre><br />
/* check vserver memory */<br />
if (p->mm && !(clone_flags & CLONE_VM)) {<br />
if (vx_vmpages_avail(p->mm, p->mm->total_vm))<br />
vx_pages_add(p->mm->mm_vx_info,<br />
RLIMIT_AS, p->mm->total_vm);<br />
else<br />
goto bad_fork_free;<br />
}<br />
</pre><br />
<br />
==== Example Virtualization: Uptime ====<br />
<br />
<pre><br />
void vx_vsi_uptime(struct timespec *uptime)<br />
{<br />
struct vx_info *vxi = current->vx_info;<br />
<br />
set_normalized_timespec(uptime,<br />
uptime->tv_sec - vxi->cvirt.bias_tp.tv_sec,<br />
uptime->tv_nsec - vxi->cvirt.bias_tp.tv_nsec);<br />
return;<br />
}<br />
<br />
if (vx_flags(VXF_VIRT_UPTIME, 0))<br />
vx_vsi_uptime(&uptime, &idle);<br />
</pre><br />
<br />
<br />
== Future Directions ==<br />
<br />
''(work in progress)''<br />
<br />
=== Hierarchical Contexts ===<br />
<br />
=== Security Branch ===<br />
<br />
=== Stealth Branch ===<br />
<br />
[[Category:Documentation| ]]</div>Glennhttp://linux-vserver.org/Category:Maturity_levelCategory:Maturity level2011-11-05T12:12:27Z<p>Glenn: +cat</p>
<hr />
<div>[[Category:Community]]<br />
[[Category:Categories]]</div>Glennhttp://linux-vserver.org/Category:TranslationCategory:Translation2011-11-05T12:07:17Z<p>Glenn: {{delete}} - now unused</p>
<hr />
<div>{{delete}}</div>Glennhttp://linux-vserver.org/From_Lenny_kernel_to_Ben_Green_kernel/frFrom Lenny kernel to Ben Green kernel/fr2011-10-23T11:09:34Z<p>Glenn: catspec Category:Migration/fr</p>
<hr />
<div>== Changer de kernel VServer ==<br />
<br />
La Debian Lenny fournit le 2.6.26, qu'il vaut mieux éviter « ''For your own good'' » (« pour votre propre bien »), selon Bertl. (Voyez [[Installation_on_Debian#Issues_with_the_current_2.6.26_Kernel]] pour les problèmes qui l'affectent.)<br />
<br />
== Alternative(s) ==<br />
<br />
Une des possibilités qui s'offre aux debianistes est d'installer le kernel VServer 2.6.31.12 ou 2.6.33.1 de Ben Green.<br />
<br />
C'est un kernel fourni en paquet .deb et ''debianisé'' en ce sens qu'il est compilé à la manière Debian, et à partir d'un '.config' Debian. La plupart des options sont compilées sous forme de modules chargeables (autant que possible) et un paquet .deb source est également fourni pour le cas où une compilation perso s'avérerait nécessaire.<br />
<br />
Ben recommande :<br />
<br />
* d'utiliser le 2.6.31.12 en production, le patch VServer étant trop vieux dans le 2.6.33 ;<br />
* d'installer le méta-paquet 'linux-image-vserver-2.6.31-beng', dépendant toujours du dernier 2.6.31 compilé et dont il déclenchera l'installation lorsqu'il est mis à jour.<br />
<br />
Petit ''disclaimer'' cependant :<br />
<br />
* l'installation se fait, comme d'usage, aux risques et périls exclusifs de l'utilisateur : ce kernel, bien qu'indiscutablement plus indiqué sous l'angle VServer, pourrait ne pas être aussi stable qu'un kernel Debian d'origine ;<br />
* il ne faudra donc pas assigner l'auteur, ou Ben, en cas de problème ;<br />
<br />
Cela étant, ces kernels tournent en prod sur plusieurs serveurs, sans que des problèmes graves n'aient été rapportés.<br />
<br />
== Où trouver un autre kernel convenable ? ==<br />
<br />
Ici : http://kernels.bristolwireless.net/, en ajoutant la ligne suivante dans /etc/apt/source.list, ou dans un source list dédié :<br />
<br />
<pre><br />
~# cat << EOF >> /etc/apt/sources.list.d/psand-vserver.list<br />
deb http://repo.psand.net/ lenny main<br />
EOF<br />
</pre><br />
<br />
Une installation habituelle s'effectura après sélection du paquet.<br />
<br />
== Que faire ensuite ? ==<br />
<br />
Avant de rebooter, il faudrait :<br />
<br />
* installer aussi le paquet util-vserver présent dans le même dépôt. Prendre util-vserver-basic-debian (et non '-basic' tout court) si on upgrade un kernel Debian d'origine ;<br />
<br />
* s'assurer que make est installée sur la machine (le paquet util-vserver dont question ci-dessus ne déclare pas de dépendance sur make, mais il en a besoin au lancement des VServers) ;<br />
<br />
* changer le lien symbolique /etc/vservers/.default/vdirbase : (il pointe sur /var/lib/vservers par défaut) :<br />
<br />
<pre><br />
~# cd /etc/vservers/.default<br />
~# rm vdirbase<br />
~# ln -s /srv/vservers vdirbase<br />
</pre><br />
<br />
On peut ensuite rebooter la machine, qui devrait normalement démarrer les VServers existants.<br />
<br />
Il reste ensuite quelques petites choses à faire pour rendre le système pleinement opérationnel :<br />
<br />
* vérifier et fixer la chroot barrier :<br />
<br />
: 1. vérifier :<br />
<br />
<pre><br />
portalis:~# showattr /srv/<br />
----buic- /srv/<br />
----buic- /srv/kvm<br />
----buic- /srv/lost+found<br />
----Buic- /srv/vservers<br />
</pre><br />
<br />
: 2. fixer, si on n'a pas le « B » (majuscule --- en miniscule, il signifie que la barrière est plaçable, mais actuellement non placée) :<br />
<br />
<pre><br />
~# setattr --barrier /srv/vservers<br />
</pre><br />
<br />
Si tous les VServers sont sous une seule arborescence dédiée (ici /srv/vservers), placer la barrière uniquement sur le parent de leur répertoire est suffisant. Sinon, il faut répéter l'opération.<br />
<br />
* repositionner le flag ''iunlink'' sur les fichiers hashifiés !<br />
<br />
: 1. vérifier :<br />
<br />
<pre><br />
~# find /srv/vservers/.hash -type f<br />
<br />
-----UIC- /srv/vservers/.hash/dd/76 /a83691887d3cd1fddcc6dcab2d5c7b8ee273-00000000<br />
[...]<br />
</pre><br />
<br />
: 2. fixer, si on n'a pas le « U » (majuscule). Il y aura un « u » (miniscule), qui signie flag dispo, mais pas mis :<br />
<br />
<pre><br />
~# find /srv/vservers/.hash -type f -exec setattr --iunlink {} \;<br />
</pre><br />
<br />
(N.B. cette commande est suggérée dans la FAQ sous réserve de vérification. C'est fait, et elle fonctionne).<br />
<br />
* retirer les fichiers hashifiés inutiles (cad. qui n'ont qu'1 seul lien, ce qui signifie qu'ils n'existent que dans le ''hash'', sans être liés à aucun VServer) :<br />
<br />
: 1. commande :<br />
<br />
<pre><br />
~# find /srv/vservers/.hash -type f -print0 | xargs -0 -rm<br />
</pre><br />
<br />
: 2. NB très important : sans repositionner iunlink, il est impossible de faire des mises à jour des VServers : on ne sait pas remplacer les fichiers à modifier car les liens ne "cassent" pas comme ils devraient.<br />
<br />
: C'est un des problèmes qui affectent le 2.6.26 de Lenny.<br />
<br />
* redémarrer les VServers actifs sur la machine :<br />
<br />
~# for vs in $(ls -1 /srv/vservers)<br />
do<br />
vserver $vs restart<br />
done<br />
<br />
(C'est ls -1 (un), pas -l (la lettre « -l »)<br />
<br />
== Merci qui ? ==<br />
<br />
* aux développeurs, pour VServer ;<br />
* à BenG, pour ses kernels ;<br />
* à l'auteur du paquet vserver-util-basic-debian (Ghislain, je crois ?)<br />
<br />
([[User:Jfs|jfs]])<br />
<br />
[[Category:Migration/fr]]</div>Glennhttp://linux-vserver.org/Category:Migration/frCategory:Migration/fr2011-10-23T11:09:09Z<p>Glenn: new</p>
<hr />
<div>{{Languages|:Category:Migration}}<br />
<br />
[[Category:Documentation/fr]]</div>Glennhttp://linux-vserver.org/Category:MigrationCategory:Migration2011-10-23T11:08:55Z<p>Glenn: +languages</p>
<hr />
<div>{{Languages|:Category:Migration}}<br />
<br />
[[Category:Documentation]]</div>Glennhttp://linux-vserver.org/Category:FrenchCategory:French2011-10-23T10:58:38Z<p>Glenn: {{Delete}} - now unused</p>
<hr />
<div>{{Delete}}</div>Glennhttp://linux-vserver.org/From_Lenny_kernel_to_Ben_Green_kernel/frFrom Lenny kernel to Ben Green kernel/fr2011-10-23T10:58:05Z<p>Glenn: -> Category:Documentation/fr</p>
<hr />
<div>== Changer de kernel VServer ==<br />
<br />
La Debian Lenny fournit le 2.6.26, qu'il vaut mieux éviter « ''For your own good'' » (« pour votre propre bien »), selon Bertl. (Voyez [[Installation_on_Debian#Issues_with_the_current_2.6.26_Kernel]] pour les problèmes qui l'affectent.)<br />
<br />
== Alternative(s) ==<br />
<br />
Une des possibilités qui s'offre aux debianistes est d'installer le kernel VServer 2.6.31.12 ou 2.6.33.1 de Ben Green.<br />
<br />
C'est un kernel fourni en paquet .deb et ''debianisé'' en ce sens qu'il est compilé à la manière Debian, et à partir d'un '.config' Debian. La plupart des options sont compilées sous forme de modules chargeables (autant que possible) et un paquet .deb source est également fourni pour le cas où une compilation perso s'avérerait nécessaire.<br />
<br />
Ben recommande :<br />
<br />
* d'utiliser le 2.6.31.12 en production, le patch VServer étant trop vieux dans le 2.6.33 ;<br />
* d'installer le méta-paquet 'linux-image-vserver-2.6.31-beng', dépendant toujours du dernier 2.6.31 compilé et dont il déclenchera l'installation lorsqu'il est mis à jour.<br />
<br />
Petit ''disclaimer'' cependant :<br />
<br />
* l'installation se fait, comme d'usage, aux risques et périls exclusifs de l'utilisateur : ce kernel, bien qu'indiscutablement plus indiqué sous l'angle VServer, pourrait ne pas être aussi stable qu'un kernel Debian d'origine ;<br />
* il ne faudra donc pas assigner l'auteur, ou Ben, en cas de problème ;<br />
<br />
Cela étant, ces kernels tournent en prod sur plusieurs serveurs, sans que des problèmes graves n'aient été rapportés.<br />
<br />
== Où trouver un autre kernel convenable ? ==<br />
<br />
Ici : http://kernels.bristolwireless.net/, en ajoutant la ligne suivante dans /etc/apt/source.list, ou dans un source list dédié :<br />
<br />
<pre><br />
~# cat << EOF >> /etc/apt/sources.list.d/psand-vserver.list<br />
deb http://repo.psand.net/ lenny main<br />
EOF<br />
</pre><br />
<br />
Une installation habituelle s'effectura après sélection du paquet.<br />
<br />
== Que faire ensuite ? ==<br />
<br />
Avant de rebooter, il faudrait :<br />
<br />
* installer aussi le paquet util-vserver présent dans le même dépôt. Prendre util-vserver-basic-debian (et non '-basic' tout court) si on upgrade un kernel Debian d'origine ;<br />
<br />
* s'assurer que make est installée sur la machine (le paquet util-vserver dont question ci-dessus ne déclare pas de dépendance sur make, mais il en a besoin au lancement des VServers) ;<br />
<br />
* changer le lien symbolique /etc/vservers/.default/vdirbase : (il pointe sur /var/lib/vservers par défaut) :<br />
<br />
<pre><br />
~# cd /etc/vservers/.default<br />
~# rm vdirbase<br />
~# ln -s /srv/vservers vdirbase<br />
</pre><br />
<br />
On peut ensuite rebooter la machine, qui devrait normalement démarrer les VServers existants.<br />
<br />
Il reste ensuite quelques petites choses à faire pour rendre le système pleinement opérationnel :<br />
<br />
* vérifier et fixer la chroot barrier :<br />
<br />
: 1. vérifier :<br />
<br />
<pre><br />
portalis:~# showattr /srv/<br />
----buic- /srv/<br />
----buic- /srv/kvm<br />
----buic- /srv/lost+found<br />
----Buic- /srv/vservers<br />
</pre><br />
<br />
: 2. fixer, si on n'a pas le « B » (majuscule --- en miniscule, il signifie que la barrière est plaçable, mais actuellement non placée) :<br />
<br />
<pre><br />
~# setattr --barrier /srv/vservers<br />
</pre><br />
<br />
Si tous les VServers sont sous une seule arborescence dédiée (ici /srv/vservers), placer la barrière uniquement sur le parent de leur répertoire est suffisant. Sinon, il faut répéter l'opération.<br />
<br />
* repositionner le flag ''iunlink'' sur les fichiers hashifiés !<br />
<br />
: 1. vérifier :<br />
<br />
<pre><br />
~# find /srv/vservers/.hash -type f<br />
<br />
-----UIC- /srv/vservers/.hash/dd/76 /a83691887d3cd1fddcc6dcab2d5c7b8ee273-00000000<br />
[...]<br />
</pre><br />
<br />
: 2. fixer, si on n'a pas le « U » (majuscule). Il y aura un « u » (miniscule), qui signie flag dispo, mais pas mis :<br />
<br />
<pre><br />
~# find /srv/vservers/.hash -type f -exec setattr --iunlink {} \;<br />
</pre><br />
<br />
(N.B. cette commande est suggérée dans la FAQ sous réserve de vérification. C'est fait, et elle fonctionne).<br />
<br />
* retirer les fichiers hashifiés inutiles (cad. qui n'ont qu'1 seul lien, ce qui signifie qu'ils n'existent que dans le ''hash'', sans être liés à aucun VServer) :<br />
<br />
: 1. commande :<br />
<br />
<pre><br />
~# find /srv/vservers/.hash -type f -print0 | xargs -0 -rm<br />
</pre><br />
<br />
: 2. NB très important : sans repositionner iunlink, il est impossible de faire des mises à jour des VServers : on ne sait pas remplacer les fichiers à modifier car les liens ne "cassent" pas comme ils devraient.<br />
<br />
: C'est un des problèmes qui affectent le 2.6.26 de Lenny.<br />
<br />
* redémarrer les VServers actifs sur la machine :<br />
<br />
~# for vs in $(ls -1 /srv/vservers)<br />
do<br />
vserver $vs restart<br />
done<br />
<br />
(C'est ls -1 (un), pas -l (la lettre « -l »)<br />
<br />
== Merci qui ? ==<br />
<br />
* aux développeurs, pour VServer ;<br />
* à BenG, pour ses kernels ;<br />
* à l'auteur du paquet vserver-util-basic-debian (Ghislain, je crois ?)<br />
<br />
([[User:Jfs|jfs]])<br />
<br />
[[Category:Documentation/fr]]</div>Glennhttp://linux-vserver.org/Category:ProcFS/frCategory:ProcFS/fr2011-10-23T10:55:38Z<p>Glenn: -Category:French</p>
<hr />
<div>{{Languages|:Category:ProcFS}}<br />
<br />
[[Category:Documentation/fr]]</div>Glennhttp://linux-vserver.org/Category:Documentation/esCategory:Documentation/es2011-10-23T10:54:05Z<p>Glenn: +/es</p>
<hr />
<div>{{Languages|:Category:Documentation}}<br />
<br />
[[Category:Categories/es]]</div>Glennhttp://linux-vserver.org/Category:Categories/esCategory:Categories/es2011-10-23T10:53:47Z<p>Glenn: new</p>
<hr />
<div>{{Languages|:Category:Categories}}</div>Glennhttp://linux-vserver.org/Category:Documentation/frCategory:Documentation/fr2011-10-23T10:53:20Z<p>Glenn: +/fr</p>
<hr />
<div>{{Languages|:Category:Documentation}}<br />
<br />
[[Category:Categories/fr]]</div>Glennhttp://linux-vserver.org/Category:Categories/frCategory:Categories/fr2011-10-23T10:52:51Z<p>Glenn: new</p>
<hr />
<div>{{Languages|:Category:Categories}}</div>Glennhttp://linux-vserver.org/Category:CategoriesCategory:Categories2011-10-23T10:52:40Z<p>Glenn: +{{Languages|:Category:Categories}}</p>
<hr />
<div>{{Languages|:Category:Categories}}<br />
<br />
'''This is the root category''', the starting point to navigate the wiki by browsing.</div>Glennhttp://linux-vserver.org/Category:TheoryCategory:Theory2011-10-23T10:51:28Z<p>Glenn: +{{Languages|:Category:Theory}}</p>
<hr />
<div>{{Languages|:Category:Theory}}<br />
<br />
[[Category:Documentation]]</div>Glennhttp://linux-vserver.org/Category:Theory/frCategory:Theory/fr2011-10-23T10:51:14Z<p>Glenn: spelling</p>
<hr />
<div>{{Languages|:Category:Theory}}<br />
<br />
[[Category:Documentation/fr]]</div>Glennhttp://linux-vserver.org/Category:Theory/frCategory:Theory/fr2011-10-23T10:50:57Z<p>Glenn: new</p>
<hr />
<div>{{Languages|:Category:Theory}}<br />
<br />
[[Category:Documentarion/fr]]</div>Glennhttp://linux-vserver.org/Namespaces/frNamespaces/fr2011-10-23T10:50:08Z<p>Glenn: + Category:Theory/fr</p>
<hr />
<div>{{Languages|Namespaces}}<br />
<br />
Vous avez peut-être entendu parler des "namespaces" (espaces de nom) qu'utilise [[alpha util-vserver]], et vous vous demandez à quoi ca sert, et qu'est-ce que c'est . Le petit qui suit vous donne l'explication.<br />
<br />
== Qu'est ce qu'un namespace ? ==<br />
<br />
Les Namespaces sont une fonctionnalité du noyau Linux, qui permet à différents processus d'avoir chacun une vue différente sur le système de fichier. Normalement, vous n'avez qu'une seule et unique arborescence de fichiers avec des montages par ci, par la. Avec les namespaces, vous pouvez maintenant avoir différentes partitions montées pour chaque ensemble de processus souhaité. <br />
<br />
== Qu'est ce que cela signifie ?==<br />
<br />
En clair, soient A et B deux processus dans différents namespaces, (dé)monter une partition dans l'un des namespace n'affectera pas l'autre namespace. Lorsque vous montez un système de fichier, il va apparaitre uniquement dans le namespace courant, de même lorsque vous le démontez. Les namespaces sont détruits automatiquement lorsque tous les processus utilisant ce namespace sont morts. <br />
<br />
De plus, tous les montages sont automatiquement démontés. Vous n'avez plus à vous occuper des montages orphelins, qui vous empecheraient, par exemple, d'ejecter votre cd-rom, si bien entendu, vous avez tué tous les processus qui en faisaient usage.<br />
<br />
== Comment les outils alpha util-vserver utilisent les namespaces ?==<br />
<br />
Lorsque vous utilisez les paramètres par défaut, les outils alpha util-vserver créent un namespace pour chaque nouveau vserver. Il observer au moins deux choses à cet instant, l'une purement esthétique, l'autre en rapport avec la sécurité.<br />
<br />
=== Esthetique ===<br />
Au niveau esthétique, l'espace de noms (namespace) de votre serveur hôte n'est pas encombré par tous ces montages utilisés par chacun des vservers.<br />
<br />
=== Securite ===<br />
Au niveau sécurité, il y a un gain certain, puisque les outils alpha util-vserver masquent la racine originelle du vserver par la racine du vserver (en utilisant un appel récursif à mount), toute tentative d'échapper au chroot sera donc infructueuse, la racine du vserver étant, de toute manière, elle-même... (même si vous n'utilisez pas les namespaces, vous pouvez aussi sécuriser vos vserver contre les tentatives pour échapper au chroot, voir chroot-barrier-french).<br />
Inconvénients?<br />
<br />
Oui, il y a quelques inconvénients à utiliser les namespace pour vos vserver, mais ils sont mineurs.<br />
<br />
Puisque les espaces de noms sont isolés les uns des autres, vous ne pouvez pas utiliser directement "mount". A la place, vous devez entrer dans l'espace de nom du vserver d'abbord. Heureusement, les outils alpha util-vserver sont fournis avec un outil permettant d'entrer dans le namespace d'un vserver facilement.<br />
<pre><br />
# Pour lancer un bash dans le namespace du vserver "mon_vserver":<br />
vnamespace -e mon_vserver bash<br />
# Même chose pour entrer dans le contexte 123<br />
vnamespace -e 123 bash<br />
<br />
# Pour monter un système de fichier dans le namespace du vserver "mon_vserver":<br />
vnamespace -e mon_vserver mount /dev/peripherique /point/de/montage<br />
<br />
# Pour démonter un système de fichier du contexte 123<br />
vnamespace -e 123 umount /point/de/montage<br />
<br />
# Afficher tous les mounts attaches a l'espace de noms 'mon_vserver'<br />
vnamespace -e mon_vserver cat /proc/mounts<br />
</pre><br />
<br />
Les versions récentes des outils alpha util-vserver traduisent automatiquement le nom d'un vserver en context id, alors que dans les anciennes versions, il fallait utiliser le context id. Souvenez vous que pour monter un système de fichier, sa source doit déjà être visible dans le namespace du contexte en question.<br />
Avec une configuration récente, vous pouvez configurer vos montages pour un vserver donné, de manière à ce qu'il soit automatiquement mis en place au démarrage du vserver.<br />
<br />
Voir pour celà: [http://www.nongnu.org/util-vserver/doc/conf/configuration.html The Great Flower Page].<br />
<br />
[[Category:Theory/fr]]</div>Glennhttp://linux-vserver.org/Paper/frPaper/fr2011-10-23T10:48:57Z<p>Glenn: -Category:French (not needed - other category is used)</p>
<hr />
<div>{{Languages|Paper}}<br />
<br />
==Abstract ==<br />
Concept logiciel basé sur les ''Security Contextes'' permet la création d'une multitude de serveurs virtuels Privés (VPS) tournant simultanément sur un même serveur physique à pleine vitesse, en partageant efficacement les ressources matérielles.<br />
Un VPS offre un environnement quasiment identique à celui d'un serveur Linux conventionnel. Tous les services, comme ssh, mail, Web, bases de données, peuvent être lancés dans un tel VPS, sans aucune modification (ou, dans certains cas, des modifications mineures), exactement comme avec n'importe quel autre serveur réel.<br />
<br />
Chaque serveur virtuel possède sa propre base utilisateurs et son mot de passe root. Il est isolé de tous les autres serveurs virtuels, sauf en ce qui concerne les ressources matérielles, qui sont partagées par tous les serveurs virtuels.<br />
<br />
== Introduction ==<br />
Au fur et à mesure des années, les micro ordinateurs sont devenus suffisemment puissant pour utiliser la virtualisation comme méthode pour donner l'illusion d'avoir une multitude de petites machines virtuelles, chacune d'elle tournant avec une instance différente de n'importe quel système d'exploitation.<br />
<br />
Il existe plusieurs types de Machines Virtuelles (VMs) dont les fonctionnalités sont similaires, mais qui diffèrent dans le degré d'abstraction et les méthodes utilisées pour la virtualisation.<br />
<br />
La plupart d'entre elles "émulent" une ressource matérielle réelle ou fictive, qui, à son tour, fait usage de "vraies" ressources du système Hote (la machine qui fait tourner les VMs). Cette approche, utilisée par la plupart des émulations système (comme QEMU[U1], Bochs[U2], ... permet à l'émulateur d'éxécuter n'importe quel système d'exploitation, même pour une architecture différente (CPU et matérielle). Pas besoin de modifier le système d'exploitation Invité, puisqu'il n'est pas conscient de s'éxécuter sur autre chose qu'un vrai matériel.<br />
<br />
Quelques émulations systèmes ont besoin d'un petit nombre de modifications ou de pilotes de périphériques spécifiques sur le système Hote ou le système Invité pour améliorer les performances, et minimiser le grignotage superflu de ressources système qui passe dans les systèmes de cache et de médiation entre le système Hote et le système Invité. Bien que cela améliore sensiblement l'efficacité de ces solutions, les ressources perdues sont toujours notables (par exemple dans UML[U3] et Xen[U4]).<br />
<br />
Supposez par contre que les systèmes d'exploitation à lancer ne sont pas différents ... La plupart des applications qui tournent sur un serveur n'ont pas besoin d'acceder au matériel ou à du code au niveau noyau, et pourraient donc partager une machine avec les autres, si l'on pouvait les séparer et les isoler ...<br />
<br />
== Le Concept ==<br />
A la base, un serveur Linux est constitué de trois blocs constitutifs: Le matériel, le Noyau, et les Applications. Le Matériel dépend habituellement du fournisseur ou de l'administrateur système, et, bien qu'ayant une grande influence sur les performances globales, ne peut pas être changé facilement, et diffère sensiblement d'une configuration à l'autre.<br />
<br />
Un role de base du noyau consiste à créer une couche d'abstraction au dessus du matériel pour permettre aux processus (Applications) de travailler avec des ressources (Données) sans connaitre les détails du matériel qui se trouve en dessous. Idéalement, ces processus sont complètement agnostiques vis-à-vis du matériel, écrit dans un langage interprété, et ne nécessitant par conséquent aucun savoir faire spécifique au matériel.<br />
<br />
Puisqu'un système possède assez de ressources pour faire tourner environ dix fois plus d'applications que nécessaire sur un serveur Linux traditionnel, pourquoi ne pas placer sur celui-ci une dizaine de serveurs, qui vont partager les ressources d'une manière efficace ?<br />
<br />
La plupart des serveurs d'application (par exemple httpd) considère qu'il est la seule application à fournir un service particulier, et d'habitude, va donc supposer une organisation particulière au niveau du système de fichiers, et de l'environnement. Cela implique que deux services identiques tournant sur un même serveur physique, mais différent simplement au niveau de leur adresse IP, par exemple, doivent être coordonnées. Cela demande typiquement pas mal de boulot pour l'administrateur système, et cela peut conduire à un stabilité réduite du système et de la sécurité.<br />
<br />
Le concept de base de la solution Linux-VServer est de séparer l'environnement en user space (espace utilisateur) en trois unités distinctes (appellées parfois VPS, ou Virtual Private Server), de telle manière que chaque VPS ressemblera à un vrai serveur vis-à-vis des processus qu'il contient.<br />
<br />
Bien que différentes Distributions Linux utilisent des noyaux modifiées (parfois lourdement) pour assurer le support de telle ou telle fonctionnalité, ou matériel, la plupart des distributions Linux ne sont pas liées irrévocablement à un noyau linux particulier.<br />
<br />
Linux-VServer utilise cela pour donner à plusieurs distributions, la possibilité de se lancer au dessus d'un seul noyau, partagé, sans accès direct au matériel, et partager les ressources d'une manière très efficace.<br />
<br />
== Infrastructure Existante ==<br />
Les noyaux Linux récents fournissent déjà de nombreuses fonctions de sécurité qui sont utilisées par Linux-Vserver pour fonctionner, telles que le Système de Privileges Linux, les limites de ressource, les attributs de fichier et l'environnement chroot. Les sections suivantes vous donneront un court aperçu de chacune d'entre elles. <br />
=== Le système de Privileges (Capabilities) Linux ===<br />
En science informatique, un privilege est un jeton utilisé par un processus pour prouver qu'il est autorisé à faire une opération sur un objet. Le Système de privileges Linux est basé sur les "Privileges POSIX", un concept légèrement similaire, conçu pour diviser les privilèges root puissants en un ensemble de privilèges distincts.<br />
<br />
==== Privileges POSIX ====<br />
Un processus possède trois champs de bits appelés les privileges héritables (I - "Inheritable"), permises (P), et effectives (E). Chaque privilege est implémenté dans un bit de chacun de ces champs, bit qui est soit défini soit non-défini.<br />
<br />
Quand un processus essaie de faire une opération privilégiée, le système d'exploitation va vérifier les bits appropriés dans l'ensemble effectif des processus (au lieu de vérifier si l'uid respectif du processus est 0 comme il le fait habituellement).<br />
<br />
Par exemple, quand un processus essaie de modifier l'horloge, le noyau Linux va vérifier que ce processus a le bit CAP_SYS_TIME (actuellement le bit 25) parmi ses privileges effectives.<br />
<br />
L'ensemble permis d'un processus indique les privileges que celui-ci peut utiliser. Le processus peut avoir des privileges définies dans l'ensemble permis qui ne sont pas dans l'ensemble effectif.<br />
<br />
Ceci indique que le processus a temporairement désactivé ce privilege. Un processus n'est autorisé à définir un bit dans son ensemble effectif que si ce bit est disponible dans son ensemble permis.<br />
<br />
La distinction entre privileges effectif et permis existe pour que les processus puissent réaliser des opérations qui nécessitent des privilèges.<br />
<br />
Les privileges héritables sont les privileges du processus courant qui peuvent être hérités par un programme exécuté par ce dernier. L'ensemble permis d'un processus est masqué contre l'ensemble héritable pendant exec().<br />
<br />
Rien de spécial ne se produit durant fork() ou clone().<br />
<br />
Les processus fils ou les threads obtiennent une copie exacte des privileges du processus parent.<br />
<br />
L'implémentation dans Linux s'arrête là, alors que les privileges POSIX[U5] requièrent l'ajout d'un ensemble de privileges aux fichiers, pour remplacer le flag SUID (au moins pour les exécutables).<br />
<br />
==== Vue d'ensemble des privileges ====<br />
La liste des privileges POSIX utilisées avec Linux est longue, et les 32 bits disponibles sont presques tous utilisés. Bien que la liste détaillée de ces privileges puisse être trouvée dans /usr/include/linux/capability.h sur la plupart des systèmes Linux, une vue d'ensemble des privileges importantes est donnée ici.<br />
{|class="wikitablenowrap"<br />
| 0|| CAP_CHOWN || change le propriétaire et le groupe du fichier<br />
|-<br />
| 5|| CAP_KILL|| envoie un signal au processus avec un ID utilisateur différent, réel ou effectif<br />
|-<br />
| 6|| CAP_SETGID|| permet le passage de setgid(2), setgroups(2), et de gids forgés sur les sockets<br />
|-<br />
| 7|| CAP_SETUID|| permet le passage de set*uid(2) et d'uids forgés sur les sockets<br />
|-<br />
| 8|| CAP_SETPCAP|| transfert/déplace tout privilege de l'ensemble permis vers/depuis n'importe quel pid<br />
|-<br />
| 9|| CAP_LINUX_IMMUTABLE|| permet la modification des attributs de fichier S_IMMUTABLE et S_APPEND<br />
|-<br />
| 11|| CAP_NET_BROADCAST|| permet la diffusion et l'écoute en multicast<br />
|-<br />
| 12|| CAP_NET_ADMIN|| permet la configuration de l'interface, le pare-feux IP, le masquerading, l'accounting, le débugage de sockets, les tables de routage, la liaison sur n'importe quelle adresse, l'entrée dans le mode de promiscuité, le multicasting...<br />
|-<br />
| 13|| CAP_NET_RAW|| permet l'utilisation des sockets RAW et PACKET<br />
|-<br />
| 16|| CAP_SYS_MODULE|| ajoute et retire des modules noyau<br />
|-<br />
| 18|| CAP_SYS_CHROOT|| permet chroot(2)<br />
|-<br />
| 19|| CAP_SYS_PTRACE|| permet ptrace() sur n'importe quel processus<br />
|-<br />
| 21|| CAP_SYS_ADMIN|| la liste serait trop longue, ceci permet en gros de faire tout ce qui n'est pas mentionné dans les autres privileges<br />
|-<br />
| 22|| CAP_SYS_BOOT|| permet reboot(2)<br />
|-<br />
| 23|| CAP_SYS_NICE|| permet l'élévation des privilèges et la modification de la priorité des autres processus, en modifiant l'ordonnanceur<br />
|-<br />
| 24|| CAP_SYS_RESOURCE|| passe outre les limites de ressource, de quota, l'espace réservé sur un système de fichier...<br />
|-<br />
| 27|| CAP_MKNOD|| permet les aspects privilégiés de mknod(2)<br />
|}<br />
<br />
Voir également les Exemples [E01],[E02], et [E03].<br />
<br />
=== Limite des Ressources ===<br />
Vous pouvez limiter les ressources de chaque processus en spécifiant une limite pour chaque ressource. A la manière des privileges Linux, il existe deux types de limites, l'une Douce, l'autre Dure.<br />
<br />
La limite Douce est la valeur que le noyau imposera pour cette ressource à un processus. Un utilisateur non privilégié pourra régler la limite Douce n'importe où en dessous de la valeur Dure. Seul l'utilisateur root pourra re-hausser la limite Dure.<br />
<br />
==== Apercu des Ressources Limit-ables ====<br />
La liste des ressources qui peuvent être limitées se trouve dans le fichier /usr/include/asm/resource.h sur la plupart des systèmes Linux.<br />
{|class="wikitablenowrap"<br />
| 0|| RLIMIT_CPU || Temps CPU en secondes. un signal SIGXCPU est envoyé au processus qui a atteind la limite Douce, et un SIGKILL pour la limite Dure.<br />
|-<br />
| 4|| RLIMIT_CORE || Taille maximale d'un fichier core.<br />
|-<br />
| 5|| RLIMIT_RSS || Nombre de pages maximum qu'un processus peut utiliser (en RAM)<br />
|-<br />
| 6|| RLIMIT_NPROC || Nombre maximum de processus autorisés à l'utilisateur réel du processus appelant.<br />
|-<br />
| 7|| RLIMIT_NOFILE || Spécifie la valeur +1 pour le nombre maximum de descripteurs de fichiers ouvert par un processus.<br />
|-<br />
| 8|| RLIMIT_MEMLOCK || Nombre maximum de pages mémoire virtuelle autorisées à être vérouillées en RAM à l'aide des appels mlock() ou mlockall().<br />
|-<br />
| 9|| RLIMIT_AS || Nombre maximum de pages de mémoire virtuelle disponible pour un processus.<br />
|}<br />
<br />
(Limite de l'espace d'adressage) <br />
<br />
Voir aussi les Exemples [E11], et [E12].<br />
<br />
=== Attributs de Fichiers ===<br />
Auparavant, cette fonctionnalité n'était disponible qu'avec ext2, mais maintenant tous les systèmes de fichiers majeurs implémentent un ensemble d'Attributs de fichiers de base, qui permettent le paramétrage de certaines propriétés. Voici de nouveau un bref aperçu des possibilités des attributs, et leur signification.<br />
<br />
{|class="wikitablenowrap"<br />
| s SECRM || Lorsqu'un fichier avec cet attribut est détruit, les blocs qui le composent sont mis à zéro et re-écrit sur le disque.<br />
|-<br />
| u UNRM || Lorsqu'un fichier avec cet attribut est détruit, son contenu est sauvegardé.<br />
|-<br />
| c COMPR || Un fichier marqué avec cet attribut est automatiquement compressé à l'écriture et décompressé à la lecture. (pas encore implémenté)<br />
|-<br />
| i IMMUTABLE || Un fichier avec cet attribut ne pourra pas être modifié: Impossible de le renommer ou de le détruire, impossible de créer un lien vers ce fichier, ni d'écrire une donnée de plus vers ce fichier. <br />
|-<br />
| a APPEND || Un fichier avec cet attribut ne pourra être ouvert qu'en mode ajout.<br />
|-<br />
| d NODUMP || Si cet attribut de fichier est mis, le fichier n'est pas candidat à un backup via l'utilitaire "dump".<br />
|-<br />
| S SYNC || Les mises à jour vers ce fichier se feront de manière synchrone.<br />
|-<br />
| A NOATIME || Empêche la mise à jour de l'enregistrement atime lors d'un accès ou d'une modification de fichier.<br />
|-<br />
| t NOTAIL || Un fichier avec l'attribut t n'aura pas de fragment bloc en fin de fichier fusionné avec un autre fichier.<br />
|-<br />
| D DIRSYNC || Les modifications apportés à ce répertoire seront écrites de manière synchrones. <br />
|}<br />
<br />
Voir aussi les Exemples [E13] et [E14].<br />
<br />
=== La Commande chroot(1) ===<br />
chroot permet de lancer une commande en changeant le répertoire racine dans lequel il va s'éxécuter. Cela signifie que tout parcours du système de fichiers à partir de la racine '/' se fera à partir de la racine substituée et non pas à partir de la racine originelle.<br />
<br />
Bien que le chroot Linux n'est pas très sécurisé, son utilisation augmente l'isolation des processus par rapport au système de fichier, et, à condition de l'utiliser correctement, peut être utilisé pour "emprisonner" un processus, un utilisateur unique, ou un démon (service).<br />
<br />
Voir l'Exemple [E15]<br />
<br />
== Modifications Requises ==<br />
Ce chapitre décrit les modifications à apporter au noyau pour implémenter un mécanisme comme Linux-VServer.<br />
<br />
=== Séparation de Contextes ===<br />
La séparation telle que décrite dans la partie 'Concepts' nécessite quelques modifications au noyau pour permettre la notion de Contexte.<br />
<br />
Le but d'un tel "Contexte" est de cacher à un processus tout ce qui ne doit pas etre à sa portée, et empécher les interractions indésirables entre un processus appartenant à un contexte et un processus appartenant à un autre contexte.<br />
<br />
Cette séparation nécessite l'extension d'un certain nombre de structures de données pour qu'elles prennent en compte les contextes et fassent la différentiation entre deux uids identiques mais utilisés dans deux serveurs virtuels différents.<br />
<br />
De plus, nous avons besoin d'un contexte par defaut qui sera utilisé par le serveur hôte au démarrage, et pour éviter les problèmes liés à des suppositions érronées de certains outils en espace utilisateur (comme pstree) par exemple, l'idée comme quoi init existe toujours et a toujours l'uid 1.<br />
<br />
Pour simplifier l'administration, le Contexte de l'Hôte n'est pas traité différemment d'un autre contexte, en tout cas du point de vue de l'isolation des processus.<br />
<br />
Pour avoir un apercu global de tous les processus, un Spectateur spécial a été mis en place, qui est capable de capturer tous les processus d'un coup.<br />
Voir les Examples [E21],[E22] et [E23]<br />
<br />
=== Séparation Réseau ===<br />
Bien que les Contextes soient suffisant pour isoler un groupe de processus, un autre type d'isolation, ou plutot une limitation, est nécessaire pour confiner les processus dans un sous ensemble d'adresses réseau disponibles.<br />
<br />
Plusieurs problèmes doivent être pris en compte dans ce sens: par exemple, les appels système bind sur IPADDR_ANY doivent être traités d'une manière bien particulière.<br />
<br />
Actuellement, Linux-Vserver n'utilise pas les interfaces virtuelles (et ne les utilisera peut-être jamais), pour minimiser le cout supplémentaire qu'elles engendrent. De ce fait, l'attachement d'une socket et la transmission des packets ont été adaptés.<br />
<br />
Voir Example [E24]<br />
<br />
=== La Barrière Chroot ===<br />
Un problème majeur avec le chroot() de Linux aujourd'hui tient au fait que cette information est volatile, et changera au prochain appel système de chroot().<br />
<br />
Voici une façon simple pour sortir d'un environnement chrooté Créez tout d'abord un fichier, et retenez son descripteur. Puis chrootez dans un répertoire au même niveau ou un niveau au dessous de celui-ci. Cela a pour effet de faire descendre la racine' dans le système de fichiers. Ensuite, faites un appel à fchdir() sur le descripteur de fichiers pour sortir de cette nouvelle racine. Vous sortirez en même temps de l'ancienne racine, qui a été perdue suite au dernier appel système chroot().<br />
<br />
Alors que des méthodes exotiques étaient utilisées dans les anciennes versions de Linux-Vserver pour fixer ce problème, les versions récentes utilisent un marquage spécial, connu sous le nom de Barrière Chroot, placé sur le parent de tous les VPS pour prévenir toute modification non autorisée et sortie du confinement.<br />
<br />
=== Un plafond pour les Privileges ===<br />
L'implémentation actuelle des privileges Linux ne prend pas en compte les privileges POSIX sur les systèmes de fichiers. Si cela était le cas, les executables setuid et setgid seraient sécurisés. Pour conserver donc une bonne sécurité malgré cette contrainte, nous avons défini un plafond pour tous les processus d'un même contexte, et un masque de privileges additionnel pour chaque contexte a été aussi ajouté pour limiter à ce seul masque les processus qui appartiennent à ce contexte.<br />
<br />
La signification des privileges individuels (bits) pour ce masque est exactement identique à celui que permet l'ensemble des privileges.=== Isolation de Ressources ===<br />
<br />
=== Isolation de Ressources ===<br />
La plupart des ressources sont d'une certaine manière partagées à travers les différents contextes; certaines requièrent une isolation plus importante que les autres, soit pour éviter les problèmes de sécurité, ou pour permettre une meilleure comptabilité de l'usage des ressources;<br />
<br />
Ces ressources sont:<br />
* mémoire partagée, IPC<br />
* PID et User ID<br />
* Drapeau xid sur les fichiers<br />
* ptys Unix<br />
* sockets<br />
<br />
=== Drapeau XID pour les Filesystem XID ===<br />
Bien qu'elle puisse être totalement desactivée, cette modification est requise pour une meilleure robustesse au niveau du système de fichiers, et pour isoler les contextes. Le drapeau XID est aussi totalement indispensable pour implémenter le support pour les Limites Disques par Contexte et les Quotas par Contexte sur une partition partagée.<br />
<br />
Ce concept d'ajouter un identifiant de contexte (xid) à chaque fichier pour créer une notion d'appartenance d'un fichier à un contexte parait simple ... Il n'en est rien, car l'implémentation actuelle n'est pas triviale. Elle nécessite soit une modification des représentations du système de fichier, soit des astuces au niveau applicatif.<br />
<br />
Une approche non intrusive pour éviter toute modification du système de fichiers sous-jacent est d'utiliser les bits de poids forts de champs existants, comme ceux des UID ou GID pour stocker le XID additionnel.<br />
<br />
Une fois que les informations de contexte sont disponibles au niveau de chaque inode, l'étape logique suivante est d'étendre la vérification d'accès au contexte en plus du reste.<br />
<br />
Actuellement, tous les acces aux inodes sont vérifiés par rapport à leur contexte ID, à l'exception des contextes "Hôte" et "Spectateur".<br />
<br />
Les fichiers non étiquettés dans le contexte hôte sont simplement traités comme appartenant au contexte courant, et cela est requis pour que l'Unification soit possible. Si un tel fichier est modifié à l'intérieur d'un contexte, elle changera en silence vers son noveau contexte, en changeant son XID.<br />
<br />
Les méthodes suivantes de marquage sont utilisées:<br />
<br />
;UID32/GID32 or EXTERNAL: Ce format utilise l'espace inutilisé dans l'inode disque pour stocker les informations de contexte. Pour l'instant, c'est uniquement défini pour ext3/ext3, mais sera dans le futur aussi défini pour xfs, reiserfs, et jfs, dès que possible.<br />
<br />
Avantage: Valeurs 32bit uid/gid complètes.<br />
<br />
;UID32/GID16: Ce format utilise la moitié haute du GID pour stocker les informations de contexte. Cela est fait de manière transparente, sauf si le format est changé sans conversion préalable.<br />
<br />
Avantage: fonctionne avec tout système de fichiers équipé de UID / GID 32bits<br />
<br />
Désavantage: le GID est réduit a 16 bits.<br />
<br />
;UID24/GID24: Ce format utilise le premier quart haut de l'UID et du GID pour stocker les informations de contexte, une fois encore, d'une manière transparente. Cela permet 16 millions de groupes et utilisateurs, ce qui devrait suffire pour la majorité des applications.<br />
<br />
Avantage: fonctionne sur tout système de fichiers avec des UID/GID 32bits<br />
<br />
Desavantage: les UID et GID sont réduits a 24 bits.<br />
<br />
Voir Examples [E31] et [E32]<br />
<br />
== Modifications Supplémentaires ==<br />
En plus du strict minimum, voici un certain nombre de modifications, non indispensables, mais qui se sont révélées très utiles au fil du temps.<br />
<br />
=== Drapeaux par Contexte ===<br />
Très tôt, le besoin d'activer ou désactiver une fonctionnalité séparement pour l'un ou l'autre des Vserver est apparue. Un champ de bits a donc été ajouté (taille=word).<br />
<br />
Ce champ de bits comprend un bon nombre de drapeaux, un champ masque, qui indique les drapeaux disponibles, et un mécanisme de déclanchement spécial, pour activer un drapeau au démarrage, puis le désactiver en causant un évennement ou une action associée.<br />
<br />
Voici la liste des drapeaux prévus et pour la plupart déjà implémentés. Ils sont disponibles dans la branche de développement de Linux-VServer:<br />
<br />
{|class="wikitablenowrap"<br />
| 0|| VXF_INFO_LOCK (historique, obsolète)<br />
|-<br />
| 1|| VXF_INFO_SCHED (historique, obsolète)|| schedule all processes in a context as if they where one.<br />
|-<br />
| 2|| VXF_INFO_NPROC (historique, obsolète)|| limite le nombre de processus autorisés dans un contexte à la valeur NPROC.<br />
|-<br />
| 3|| VXF_INFO_PRIVATE (historique)|| interdiction d'entrer dans ce contexte depuis l'extérieur.<br />
|-<br />
| 4|| VXF_INFO_INIT (historique) || show the init process with pid '1'<br />
|-<br />
| 5|| VXF_INFO_HIDE (historique, obsolète)||<br />
|-<br />
| 6|| VXF_INFO_ULIMIT (historique, obsolète)||<br />
|-<br />
| 7|| VXF_INFO_NSPACE (historique, obsolète)||<br />
|-<br />
| 8|| VXF_SCHED_HARD || activer l'ordonnancement "Hard CPU"<br />
|-<br />
| 9|| VXF_SCHED_PRIO || calculer les priorités de chaque processus à l'aide du "contexte token bucket".<br />
|-<br />
| 10|| VXF_SCHED_PAUSE || mettre tous les processus de ce contexte dans la file "hold", les empéchant d'être ordonnancés à nouveau.<br />
|-<br />
| 16|| VXF_VIRT_MEM || virtualize the memory information so that the VM and RSS limits are used for meminfo and friends<br />
|-<br />
| 17|| VXF_VIRT_UPTIME || virtualiser l'uptime, en commançant à la date de création du contexte.<br />
|-<br />
| 18|| VXF_VIRT_CPU || <br />
|-<br />
| 24|| VXF_HIDE_MOUNT || afficher les /proc/{pid}/mounts comme vides.<br />
|-<br />
| 25|| VXF_HIDE_NETIF || cache les interfaces réseau et addresses non autorisées dans ce contexte.<br />
|}<br />
<br />
Voir Exemple [XX]<br />
<br />
=== Privileges par Contexte ===<br />
Lorsque nous sommes arrivé au nombre maximum de privileges envisageables sans trop modifier le noyau, l'étape suivante a été, naturellement, d'ajouter un système de privileges par contexte.<br />
<br />
Le mécanisme des privileges par contexte implémenté dans Linux-VServer permet un réglage fin des privileges Linux. Ils ne sont pas visibles aux processus d'un contexte donné, puisque de toute facon le processus n'aurait pas le droit de les vérifier ou de les modifier.<br />
<br />
Généralement, il y a deux facons d'utiliser ces privileges : * Require one or a number of context capabilities to be set in addition to a given Linux capability, each one controlling a distinct part of the functionality. For example the CAP_NET_ADMIN could be split into RAW and PACKET sockets, so you could take away each of them separately by not providing the required context capability.<br />
<br />
Consider the context capability sufficient for a specified functionality, even if the Linux Capability says something different. For example mount() requires CAP_SYS_ADMIN which adds a dozen other things we do not want, so we define a CCAP_MOUNT to allow mounts for certain contexts.<br />
<br />
The difference between the Context Flags and the Context Caps is more an abstract logical separation than a functional one, because they are handled very similar.<br />
Again, a list of the Context Capabilities and their purpose:<br />
<br />
{|class="wikitablenowrap"<br />
|0|| VXC_SET_UTSNAME|| autoriser le contexte à changer le nom de serveur et le nom de domaine en utilisant l'appel système noyau approprié<br />
|-<br />
|1|| VXC_SET_RLIMIT|| allow the context to modify the resource limits (within the vserver limits).<br />
|-<br />
|8|| VXC_RAW_ICMP|| allow raw icmp packets in a secure way (this makes ping work from inside)<br />
|-<br />
|16|| VXC_SECURE_MOUNT|| permit secure mounts, which at the moment means that the nodev mount option is added.<br />
|}<br />
<br />
=== Comptabilité par Contexte ===<br />
Plusieurs propriétés des contextes sont très utiles pour l'administrateur système, que ce soit pour garder un oeil sur les ressources, pour avoir une idée de ce que peut supporter le serveur, ou pour pouvoir facturer d'une manière ou d'une autre au client.<br />
<br />
Deux types de propriétés peuvent être comptabilisées, celles dont la valeur courante représente l'état du système (par analogie, prenez la vitesse d'un véhicule), et celles dont la valeur augmente régulièrement avec le temps (comme le kilométrage).<br />
<br />
La plupart des valeurs d'état sont limitables, et sont donc traitées d'une façon spécifique, comme cela est décrit dans la section qui suit.<br />
<br />
Good candidates for Context Accounting are:<br />
* Temps CPU utilisé<br />
* Nombre de fork() effectués<br />
* Nombre de messages Socket par Type<br />
* Nombre de paquets Transmis et Recus<br />
<br />
Voir Exemple [E41]<br />
<br />
=== Limites par Contexte ===<br />
La plupart des ressources système, que ce soit la consommation mémoire, le nombre de processus utilisés, le nombre de descripteurs de fichiers, la bande passante réseau, doivent pouvoir être limitées.<br />
<br />
Les limites par contexte permettent, pour chaque valeur limitable, de définir trois types de limites: minimum, soft, et hard(maximum).<br />
<br />
A l'heure actuelle, seule les limites hard sont supportées, et seulement une partie d'entre elles sont réellement activées. Voici une liste des limites par contexte actuelles et prévues:<br />
* limites sur les processus<br />
* limites sur l'ordonnanceur<br />
* limites mémoire<br />
* limites disques par contexte<br />
* quotas user/groupe par contexte<br />
<br />
De plus, les limites par contexte gardent trace des valeur maxima atteintes et du nombre de fois ou la limite a été atteinte (hit), pour donner un feedback utile a l'administrateur.<br />
<br />
Voir Exemple [E42]<br />
<br />
=== Virtualisation ===<br />
One major difference between the Linux-VServer approach and Virtual Machines is that you do not have the virtualization part as a side-effect, so you have to do that by hand where it makes sense.<br />
<br />
For example, a Virtual Machine does not need to think about uptime, because naturally the running OS was started somewhere in the past and will not have any problem to tell the time it thinks it began running.<br />
<br />
A context can also store the time when it was created, but that will be different from the systems uptime, so in addition, there has to be some function, which adjusts the values passed from kernel to user-space depending on the context the process belongs to.<br />
<br />
This is what for Linux-VServer is known as Virtualization (actually it's more faking some values passed to and from the kernel to make the processes think that they are on a different machine).<br />
<br />
Currently modified for the purpose of Virtualization are:<br />
* System Uptime<br />
* Host and Domain Name<br />
* Machine Type and Kernel Version<br />
* Context Memory Availability<br />
* Context Disk Space<br />
<br />
Voir Exemple [E43]<br />
<br />
=== Sécurité Renforcée ===<br />
Le mécanisme de sécurité Proc-FS protège les entrées dynamiques du système de fichiers proc, de façon à ce que toutes les entrées ne soient pas vues dans tous les contextes.<br />
<br />
Le système est constitué de trois drapeaux pour chaque entrée du Proc-FS: Admin, Watch, et Hide.<br />
<br />
Le Drapeau Hide active ou désactive entierement une fonctionnalité, donc toute combinaison associée avec un drapeau Hide à 0 aura donc la signification visible.<br />
<br />
Les drapeaux Admin et Watch déterminent ou l'entrée hidden (cachée) reste visible; par exemple, si les drapeaux Admin et Hidden sont mis, seul le Host Contexte (0) sera en mesure de voir cette entrée spécifique.<br />
<br />
Voir Exemple [E44] et Voir Exemple [E45]<br />
<br />
=== Kernel Helper ===<br />
Dans certains cas, il peut être nécessaire de mettre en place un outil en espace utilisateur qui va agir en lieu et place du noyau, lorsque par exemple un processus demande une fonctionnalité disponible sur un serveur réel, mais non disponible dans un contexte.<br />
<br />
Le meilleur exemple d'un tel cas est le "Reboot Helper", qui implémente l'appel système reboot(), invoqué depuis l'intérieur d'un contexte en lieu et place du noyau. L'appel sera éxécuté depuis le contexte hôte, qui lancera l'action adéquate, reboot ou un simple halt du contexte en question.<br />
<br />
Bien que ce "helper" soit concu pour être flexible et gérer un certain nombre de choses de la même facon, il n'est pas utilisé pour l'instant à autre chose, et pourrait être remplacé dans le futur par une interface par evènement.<br />
<br />
Voir Exemple [XX]<br />
<br />
== Fonctionnalités et documentation additionnelle ==<br />
=== Unification ===<br />
L'un des objectifs centraux de Linux-VServer est de réduire l'utilisation des ressources partout ou cela est possible. Une excellente idée a donc germé, celle de partager des fichiers à travers les différents contextes sans interférer avec les taches administratives classiques ou diminuer le niveau de sécurité.<br />
<br />
Les fichiers communs à plusieurs contextes, peu sujet à être modifiés, comme les bibliothèques ou les binaires, peuvent être soudés via un lien dur sur un système de fichier partagé, réduisant d'autant le besoin en espace disque, cache d'inodes, et surtout, l'occupation mémoire, via l'utilisation des bibliothèques partagées.<br />
<br />
Seul inconvénient, si nous ne prenons pas quelques mesures supplémentaires, un contexte malicieux sera en mesure, par accident ou volontairement, de détruire ou modifier un tel fichier partagé, ce qui aurait des conséquences directes sur les autres contextes.<br />
La première étape consiste à placer sur les fichiers partagés un drapeau Immutable (et enlever la caps qui permet de modifier un tel fichier). Il faut toutefois ajouter un attribut supplémentaire à ces fichiers partagés, pour permettre leur suppréssion, lors, par exemple, d'une mise à jour des bibliothèques dans un l'un des contextes.<br />
<br />
Ces fichiers liés, immutables, que l'ont peut toutefois détruire, et appartenant à plus d'un contexte sont appelés unifiés, et l'action qui consiste à les rechercher et les préparer s'appelle Unification.<br />
<br />
Choississez l'unification si vous souhaitez réduire votre usage de ressources. L'inconvénient évident est une administration moins facile. Un Serveur Linux s'installe typiquement sur 500Mo de disque, et 10 serveurs unifiés en consommeront donc seulement 700Mo, et moins de mémoire pour les caches.<br />
<br />
Voir Exemple [XX]<br />
<br />
=== Espaces de nom privés ===<br />
Ajoutés récemment dans Linux-VServer, les espaces de noms privés utilisent la couche VFS du noyau linux et offrent une vue différente du système de fichier pour chaque contexte.<br />
Par rapport au schéma traditionnel, l'avantage principal apparait lorsqu'on modifie quelquechose dans un espace de nommage (par exemple, les points de montage); à cet instant, les autres contextes resteront intact, y compris biensur le contexte Hôte.<br />
Désavantage évident d'une telle approche; entrer dans un tel espace de noms privé n'est pas aussi simple que d'entrer dans un chroot. Toutefois, les choses pourraient changer dans les noyaux futurs, si cette fonctionnalité est par exemple intégrée directement à la fonction chroot().<br />
<br />
=== Le système de fichier Proc-FS de Linux-VServer ===<br />
A structured, dynamically generated subtree of the well-known Proc-FS - actually two of them - has been created to allow for inspecting the different values of Security and Network Contexts.<br />
/proc/virtual<br />
.../info<br />
<br />
/proc/virtual/<pid><br />
.../info<br />
.../status<br />
.../sched<br />
.../cvirt<br />
.../cacct<br />
.../limit<br />
<br />
=== Extensions Token Bucket ===<br />
While the basic idea of Linux-VServer is a peaceful coexistence of all contexts, sharing the common resources in a respectful way, it is sometimes useful to control the resource distribution for resource hungry processes.<br />
<br />
The basic principle of a Token Bucket is not very new. It is given here as an example for the Hard CPU Limit. The same principle also applies to scheduler priorities, network bandwidth limitation and resource control in general.<br />
<br />
The Hard CPU Limit uses this mechanism in the following way: consider a bucket of a certain size S which is filled with a specified amount of tokens R every interval T, until the bucket is "full" - excess tokens are spilled. At each timer tick, a running process consumes exactly one token from the bucket, unless the bucket is empty, in which case the process is put on a hold queue until the bucket has been refilled with a minimum M of tokens. The process is then rescheduled.<br />
<br />
A major advantage of a Token Bucket is that a certain amount of tokens can be accumulated in times of quiescence, which later can be used to burst when resources are required.<br />
<br />
Where a per-process Token Bucket would allow for a CPU resource limitation of a single process, a Context Token Bucket allows to control the CPU usage of all confined processes.<br />
<br />
Another approach, which is also implemented, is to use the current fill level of the bucket to adjust the process priority, thus reducing the priority of processes belonging to excessive contexts.<br />
<br />
Voir Exemple [XX]<br />
<br />
=== Limites Disque par Contexte ===<br />
Pour faire usage de cette fonctionnalité, le support pour les fichiers étiquetés XID doit être présent. Grace aux limites par contexte, vous pouvez alors régler une limite différente pour chaque contexte d'une partition partagée.<br />
<br />
Chaque block et inode d'un système de fichier est comptabilisé, dès lors qu'un hachage XID a été ajouté à ce système de fichier dans ce contexte donné.<br />
Those values, including current usage, maximum and reserved space, will be shown for filesystem queries, creating the illusion that the shared filesystem has a different usage and size, for each context.<br />
<br />
=== Quota par Contexte ===<br />
Similar to the Context Disk Limits, Per-Context Quota uses separate quota hashes for different Contexts on a shared filesystem. This is not required to allow for Linux-VServer quota on separate partitions.<br />
<br />
=== Le périphérique "proxy" VRoot ===<br />
Les opérations sur les Quotas (ioctls) nécessitent un accès aux périphériques de bloc. Ils ne sont donc pas disponible dans un VPS.<br />
<br />
=== Stealth ===<br />
Pour certaines applications, par exemple la préparation d'un "pot de miel" (honey-pot), ou d'une imitation particulièrement réaliste d'un vrai serveur à des fins éducatives, vous aurez peut-être besoin de confondre le contexte du serveur hôte (réel) et celui de votre pot de miel. <br />
Toutefois, certaines alternatives libres comme QEMU ou UML vous permettent de faire la même chose beaucoup mieux et avec moins d'efforts. Ce n'est donc pas une question centrale dans le développement de Linux-VServer.<br />
<br />
== Sécurité Linux-VServer ==<br />
Nous savons maintenant que Linux-VServer implémente quelques principes de sécurité, et comment ils fonctionnent. Il faut tout de même dire quelques mots la dessus, puisqu'il ne suffit pas, bien évidemment, de considérer que Linux-VServer étant une architecture sécurisée, votre système sera sur automatiquement. Comme d'habitude, mieux vaut savoir *exactement* ce que vous faites.<br />
<br />
=== Privileges Sécurisées ===<br />
Actuellement, seules les privileges Linux suivantes sont considérés d'un usage sans risque dans un VPS. Si d'autres privileges sont nécessaires, ils ouvrent probablement des trous de sécurité.<br />
* CAP_CHOWN<br />
* CAP_DAC_OVERRIDE<br />
* CAP_DAC_READ_SEARCH<br />
* CAP_FOWNER<br />
* CAP_FSETID<br />
* CAP_KILL<br />
* CAP_SETGID<br />
* CAP_SETUID<br />
* CAP_NET_BIND_SERVICE<br />
* CAP_SYS_CHROOT<br />
* CAP_SYS_PTRACE<br />
* CAP_SYS_BOOT<br />
* CAP_SYS_TTY_CONFIG<br />
* CAP_LEASE<br />
CAP_NET_RAW par exemple n'est pas considéré comme sur. Bien qu'il soit souvent utilisé pour donner le droit à la commande "ping" (dont le fonctionnement est cassé), il existe de bien meilleures alternatives comme la commande ping "poink[U7]", ou la cap VXC_RAW_ICMP.<br />
<br />
=== La Barrière Chroot ===<br />
Il faut vous assurer que le drapeau barrière est bien mis sur tout répertoire parent de chacun de vos VPS. Cela est indispensable pour prévenir quiconque de sortir du chroot et aller se balader dans le système de fichier de votre vserver hôte.<br />
<br />
<br />
<br />
=== Fichiers de périphériques Sécurisés ===<br />
Le répertoire /dev d'un VPS ne doit pas contenir plus de fichiers qu'indiqué ci-dessous, plus le répertoire pour les pts unix.<br />
* c 1 7 full<br />
* c 1 3 null<br />
* c 5 2 ptmx<br />
* c 1 8 random<br />
* c 5 0 tty<br />
* c 1 9 urandom<br />
* c 1 5 zero<br />
* d pts<br />
Bien entendu, d'autres périphériques comme console, mem, kmem, et même des périphériques en mode block et/ou caractère peuvent être ajoutés, mais une certaine expertise sera nécessaire pour s'assurer que cela n'entraine aucun trou de sécurité.<br />
<br />
=== Entrées Proc-FS Sécurisées ===<br />
Aucun test n'a été fait sur la fiabilité et la sécurité des entrées dans le système de fichiers proc, mais quelques incidents ont été notés lorsqu'on utilise par exemple des entrées proc avec permission d'écriture, et non protégées par une CAP linux.<br />
Par exemple, <tt>/proc/sysrq-trigger</tt> est un fichier qui ne doit en aucun cas être accessible dans un VPS sans une excellente raison.<br />
<br />
== Champ d'Applications ==<br />
Le but premier de ce projet est de permettre la création de serveurs virtuels partageant les ressources d'une même machine physique. Un Serveur Virtuel fonctionne comme un serveur Linux normal, et peut lancer des services traditionnels comme telnet, service de mail, service web, service SQL.<br />
<br />
=== Séparation Administrative ===<br />
Un provider intelligent peut donc vendre un serveur virtuel, qui, en utilisant moins de ressources que d'autres techniques de virtualisation, permet de lancer plus d'instances sur une même machine.<br />
<br />
La liste des providers qui fournissent un tel service est assez longue, et on peut donc considérer que c'est l'application principale de vserver.<br />
<br />
=== Séparation de Services ===<br />
Pour séparer plusieurs services identiques ou de nature différente, qui auraient autrement des interférences entre eux, est une chose facile à mettre en oeuvre avec Vserver. Plusieurs raisons peuvent vous pousser à faire cela; un service mal écrit, ou simplement deux services qui ne savent pas co-exister pour de multiples raisons.<br />
<br />
Même sur une machine à l'ancienne mode, placer un service très exposé ou non sécurisé car inconnu ou propriétaire dans une prison chroot peut améliorer grandement la sécurité et la maintenabilité.<br />
<br />
=== Améliorer la Sécurité ===<br />
Bien que l'idée de lancer plusieurs serveurs sur une seule machine soit en elle même très interessante, d'autres concepts sont encore plus interessants. Imaginez un serveur physique sur lequel tourne un seul vserver. Le but est d'isoler l'environnement principal de n'importe quel service, n'importe quel réseau. Vous démarrerez dans l'environnement principal, lancez très très peu de services, puis continuez dans le serveur virtuel.<br />
<br />
Le service de l'environnement principal sera:<br />
* Injoignable depuis le reseau.<br />
* En mesure de logger tous les messages du virtual serveur, d'une manière sécurisée. Rien dans le serveur virtuel ne permet d'effacer les logs, ou de les modifier. Même un serveur virtuel cracké ne permet pas de changer les logs.<br />
* En mesure de faire tourner un système de détection d'intrusion, qui espionnera l'état du serveur virtuel sans être accessible ou même détecté. Par exemple, vous pouvez installer et faire tourner tripwire depuis l'environnement principal, et impossible de modifier son fonctionnement ou de le tromper.<br />
Une autre option consiste à mettre le firewall dans un serveur virtuel, puis étirer la DMZ sur un ensemble de VPS séparés. Moyennant une configuration bien faite, ce genre d'installation peut réduire substantiellement le nombre de machines requises, sans pour autant impacter les performances.<br />
<br />
=== Maintenance Facilitée ===<br />
Une fonctionnalité clef d'un serveur virtuel est son indépendance vis à vis du matériel. La plupart des problèmes matériels sont inconnus au fonctionnement d'un serveur virtuel.<br />
<br />
Le serveur principal agit comme un système hôte, et s'occupe de tous les détails. Le serveur virtuel est simplement un client, et ignore tous les détails. De cette manière, le client peut être déplacé vers un autre serveur physique avec très peu de manipulations.<br />
<br />
Par exemple, pour déplacer un serveur virtuel depuis un ordinateur physique vers un autre, il suffit de procéder aux étapes suivantes:<br />
* stopper le serveur virtuel<br />
* le copier sur l'autre machine<br />
* copier sa configuration<br />
* lancer le serveur virtuel sur la nouvelle machine<br />
Pas de mise à jour des utilisateurs, pas de configuration matérielle, tant que les machines sont compatibles au niveau de leurs binaires.<br />
<br />
=== Scenarios de Fail-Over ===<br />
En repoussant les limites un peu plus loin, on peut utiliser des technologies de réplication pour conserver une copie identique à la minute près du système de fichier d'un serveur virtuel en fonctionnement. Cela peut servir à un basculement très rapide si le serveur en fonction tombe pour n'importe quelle raison.<br />
<br />
Toutes les methodes connues sont utilisables dans ce but, en commancant par la réplication réseau comme rsync, ou drdb, en passant par NBD (les Network Devices), les disques partagés, ou un système de fichier distribué. Toutes ces méthodes sont utilisables pour réduire le temps d'indisponibilité d'un système et améliorer l'efficacité globale.<br />
<br />
=== Pour test ===<br />
Vous avez besoin de construire un logiciel pour plusieurs versions d'une distribution particulière. (Mandrake 8.2, 9.0, 9.1, 9.2, 10.0), ou bien même pour plusieurs distributions différentes.<br />
<br />
Ce problème est résolu d'une manière très simple par Vserver. Avec pas mal d'espace disque, ces différentes distributions peuvent être installées et lancées en parallèle, simplifiant la tache de passer de l'une à l'autre.<br />
<br />
Biensur, vous pouvez faire cela simplement avec chroot() et rien d'autre, mais Vserver offre une simulation bien plus réaliste.<br />
<br />
== Performance et Stabilité ==<br />
=== Impact de Linux-VServer sur l'hôte ===<br />
=== Overhead dans un Contexte ===<br />
=== Taille du patch noyau ===<br />
<br />
== Matériels Non Intel i386 ==<br />
Linux-VServer est concu pour être indépendant de l'architecture au maximum du coup, seule une toute petite partie, la définition de l'appel système lui-même est spécifique à une architecture. Malgré cela, quelques architectures renfermen des copies de certains codes 'architecture independant', pour une raison ou pou une autre, et nécessitent par conséquent de légères modifications.<br />
<br />
Les architectures suivantes sont supportées, et certaines d'entre elles ont même été testées:<br />
* alpha<br />
* ia32 / ia64 / xbox<br />
* x86_64 (AMD64)<br />
* mips / mips64<br />
* hppa / hppa64<br />
* ppc / ppc64<br />
* sparc / sparc64<br />
* s390<br />
* uml<br />
L'ajout d'une nouvelle architecture est relativement simple, même si de tests extensifs sont nécessaires pour valider le bon fonctionnement d toutes les fonctionnalités telle qu'attendu. (et biensur, du matériel ;).<br />
<br />
<br />
== Intro Noyau Linux ==<br />
Bien que les fonctionnalités décrites plus haut sont codées dans le noyau, quelques outils sont nécessaires en espace utilisateur (userspace) pour les activer et les controler.<br />
<br />
Ces outils en userspace communiquent généralement avec le noyau via des appels système (syscalls).<br />
<br />
Le chapitre qui suit décrit les liens entre espace kernel et espace utilisateur, comment les appels système, méthode simple pour communiquer entre les processus et le noyau, fonctionnent.<br />
<br />
=== Espace Noyau et Espace Utilisateur ===<br />
Sous Linux et les systèmes d'exploitation similaires, l'espace noyau et l'espace utilisateur sont séparés, et l'espace d'adressage est divisé en deux parties. Dans L'espace noyau réside le code noyau, alors que les programmes utilisateur vivent dans l'espace utilisateur. Bien entendu, un programme ne peut écrire dans la mémoire noyau, ni dans la mémoire d'un autre processus.<br />
<br />
Malheureusement, c'est aussi le cas pour le code du noyau. Le code kernel n'a pas le droit d'écrire dans l'espace utilisateur. Qu'est-ce que cela signifie ? Lorsqu'un driver de périphérique a besoin d'écrire ses octets destinés à un programme dans l'espace utilisateur, il ne peut pas le faire directement, mais doit passer par des fonctions noyau spécifiques à la place. De même, lorsque des paramètres sont passés au noyau par référence à une fonction kernel, la fonction kernel ne peut pas lire les paramètres directement. Elle doit utiliser d'autres fonctions noyau pour lire chaque octet des paramètres.<br />
<br />
Bien entendu, il existe des fonctions écrites tout spécialement pour les transfer depuis et vers l'espace utilisateur.<br />
copy_to_user(void *to, const void *from, long n);<br />
copy_from_user(void *to, const void *from, long n);<br />
<br />
get_user() and put_user() Prendre ou placer l'octet, le mot, ou l'entier long depuis l'espace utilisateur ou vers celui-ci. C'est une macro, et elle se fie au type de ses arguments pour évaluer le nombre d'octets à transférer.<br />
<br />
=== Appels système Linux ===<br />
La plupart des appels libc s'appuient sur les appels système, la plus petite forme de fonction qu'un programme peut appeler.<br />
<br />
Ces appels système sont implémentés dans le noyau lui-même, ou dans des modules, parties de code noyau chargeables dynamiquement.<br />
<br />
Ils sont implémentés via un multiplexeur appelé avec un masque d'interruption précis. Sous Linux, ce masque d'interruption est int 0x80. Lorsque l'instruction 'int 0x80' est exécutée, le contrôle est donné au noyau (ou, plus précisément, à la fonction _system_call() ), et le démultipléxage proprement dit prend place.<br />
<br />
Comment fonctionne la fonction _system_call() ?<br />
<br />
Tout d'abord, tous les registres sont sauvegardés, et le contenu du registre %eax est comparé à la table des appels systèmes, qui recense tous les appels systèmes et leur adresse respective.<br />
<br />
On peut acceder à cette table via la variable extern void *sys_call_table[] Il existe un nombre et une adresse mémoire données dans cette table pour chacun des appels système.<br />
<br />
Ceux-ci sont référencés dans le fichier /usr/include/sys/syscall.h.<br />
<br />
Ils sont de la forme SYS_nomappelsysteme. si l'appel système n'est pas implémenté, la cellule correspondante dans la table sys_call_table est à 0, et une erreur est retournée.<br />
<br />
Sinon, l'appel système sort, et l'entrée correspondante dans la table donne l'adresse du code ou se trouve l'appel système.<br />
<br />
<br />
<br />
== Implémentation ==<br />
Ce chapitre est plus particulierement reserve aux developpeurs noyau. Toutefois, les curieux trouveront avantage a tirer le rideau pour decouvrir les entrailles du systeme.<br />
<br />
=== Appel systeme===<br />
Pendant un certain temps, Linux-VServer a utilise different appels systeme pour accomplir les differents aspects de son travail. Tres vite, le nombre des commandes necessaires est devenu important, nous avons donc commence a donner des valeurs magiques aux appels pour choisir le comportement desire.<br />
<br />
Enfin, il y a peu de temps, nous avons obtenu un numero reserve pour les appels systemes Linux-VServer, et malgre l'opinion de certains developpeurs, c'est globalement une bonne decision de garder un seul appel systeme.<br />
<br />
Avoir plusieurs appels systeme peut faciliter les choses pour travailler avec les appels systemes sur plusieurs architectures; toutefois, cela n'a pas constitue un probleme majeur jusqu'ici, les donnees transitant depuis et vers le noyau etant, conformement au standard C99, fortement typees.<br />
<br />
Quoi qu'il en soit, la mise en place d'un appel systeme passe par la creation d'un multiplexeur, qui va decider quelle commande doit etre executee, et quels arguments lui passer. A elle par la suite d'executer effectivement le travail demande.<br />
extern asmlinkage long<br />
sys_vserver(uint32_t cmd, uint32_t id, void __user *data)<br />
L'appel systeme Linux-VServer prend trois arguments dans tous les cas: la commande (cmd), un nombre (id), et une structure de donnee en espace utilisateur d'une taille encore inconnue.<br />
<br />
Pour faciliter le deboggage et la tenue a jour des informations de versionning, la chaine cmd est decomposee en trois parties: les 12 bits de poids faible contiennent le numero de version, puis 4 bits sont reserves. Les 16 bits de poids fort sont divises en 8 bits de commande et 6 pour la categorie, puis les 2 bits restant, reserves pour usage ulterieur.<br />
<br />
Nous avons donc 64 Categories avec chacune 256 commandes, et 4096 revisions possible pour chaque commande, ce qui surpasse largement nos besoins presents et futurs.<br />
<br />
Voici un apercu des categories deja definies, et leur valeur numerique associee:<br />
<br />
Matrice des appels systeme V2.6<br />
<br />
|VERSION|CREATE |MODIFY |MIGRATE|CONTROL|EXPERIM| |SPECIAL|SPECIAL|<br />
|STATS |DESTROY|ALTER |CHANGE |LIMIT |TEST | | | |<br />
|INFO |SETUP | |MOVE | | | | | |<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
SYSTEM |VERSION|VSETUP |VHOST | | | | |DEVICES| |<br />
HOST | 00| 01| 02| 03| 04| 05| | 06| 07|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
CPU | |VPROC |PROCALT|PROCMIG|PROCTRL| | |SCHED. | |<br />
PROCESS| 08| 09| 10| 11| 12| 13| | 14| 15|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
MEMORY | | | | | | | |SWAP | |<br />
| 16| 17| 18| 19| 20| 21| | 22| 23|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
NETWORK| |VNET |NETALT |NETMIG |NETCTL | | |SERIAL | |<br />
| 24| 25| 26| 27| 28| 29| | 30| 31|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
DISK | | | | | | | |INODE | |<br />
VFS | 32| 33| 34| 35| 36| 37| | 38| 39|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
OTHER | | | | | | | |VINFO | |<br />
| 40| 41| 42| 43| 44| 45| | 46| 47|<br />
=======+=======+=======+=======+=======+=======+=======+ +=======+=======+<br />
SPECIAL| | | | |FLAGS | | | | |<br />
| 48| 49| 50| 51| 52| 53| | 54| 55|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
SPECIAL| | | | |RLIMIT |SYSCALL| | |COMPAT |<br />
| 56| 57| 58| 59| 60|TEST 61| | 62| 63|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
<br />
La definition de ces commandes est simplifiee grace a certaines macros, comme par exemple interroger un drapeau ou lui attribuer une valeur:<br />
#define VCMD_get_cflags VC_CMD(FLAGS, 1, 0)<br />
#define VCMD_set_cflags VC_CMD(FLAGS, 2, 0)<br />
<br />
extern int vc_get_cflags(uint32_t, void __user *);<br />
extern int vc_set_cflags(uint32_t, void __user *);<br />
<br />
Notez bien, ce n'est pas la commande elle meme qui est passee en parametre, mais un id et un pointeur vers une structure de donnee en espace utilisateur.<br />
<br />
=== Structures de Donnees Utilisees===<br />
Plusieurs types de structures sont utilisees par les differentes parties de l'implementation; seuls quelques exemples sont donnes ici, l'ensemble complet des structures utilisees se trouve dans le source.<br />
==== La Structure Data Context====<br />
La structure Data Context permet de gerer les contextes, leur destruction, ainsi que les futurs contextes hierarchiques.<br />
<br />
Les sections reservees pour l'ordonanceur ou les limites sont definies dans des structures separees, comme le veut la logique, puis incorporees dans la structure principale.<br />
struct vx_info {<br />
struct list_head vx_list; /* linked list of contexts */<br />
xid_t vx_id; /* context id */<br />
atomic_t vx_refcount; /* refcount */<br />
struct vx_info *vx_parent; /* parent context */<br />
<br />
struct namespace *vx_namespace; /* private namespace */<br />
struct fs_struct *vx_fs; /* private namespace fs */<br />
uint64_t vx_flags; /* context flags */<br />
uint64_t vx_bcaps; /* bounding caps (system) */<br />
uint64_t vx_ccaps; /* context caps (vserver) */<br />
<br />
pid_t vx_initpid; /* PID of fake init process */<br />
<br />
struct _vx_limit limit; /* vserver limits */<br />
struct _vx_sched sched; /* vserver scheduler */<br />
struct _vx_cvirt cvirt; /* virtual/bias stuff */<br />
struct _vx_cacct cacct; /* context accounting */<br />
<br />
char vx_name[65]; /* vserver name */<br />
};<br />
<br />
<br />
Voici un exemple de la sous-structure Ordonanceur:<br />
struct _vx_sched {<br />
spinlock_t tokens_lock; /* lock for this structure */<br />
<br />
int fill_rate; /* Fill rate: add X tokens ... */<br />
int interval; /* Divisor: ... each Y jiffies */<br />
atomic_t tokens; /* current number of tokens */<br />
int tokens_min; /* Limit: minimum for unhold */<br />
int tokens_max; /* Limit: no more than N tokens */<br />
uint32_t jiffies; /* bias: integral multiple of Y */<br />
<br />
uint64_t ticks; /* token tick events */<br />
cpumask_t cpus_allowed; /* cpu mask for context */<br />
};<br />
<br />
L'idee principale derriere ces sous-structures est de faciliter leur maintenabilite, a l'aide, pour chacune d'elles, d'une fonction init et cleanup, d'ou une lecture facilitee et une maintenabilite accrue.<br />
<br />
==== The Scheduler Command Data====<br />
As an example for the data structure used to control a specific part of the context from user-space, here is a scheduler command and the utilized data structure to set the properties:<br />
#define VCMD_set_sched VC_CMD(SCHED, 1, 2)<br />
<br />
struct vcmd_set_sched_v2 {<br />
int32_t fill_rate; /* Fill rate: add X tokens ... */<br />
int32_t interval; /* Divisor: ... each Y jiffies */<br />
int32_t tokens; /* current number of tokens */<br />
int32_t tokens_min; /* Limit: minimum for unhold */<br />
int32_t tokens_max; /* Limit: no more than N tokens */<br />
uint64_t cpu_mask; /* Mask: allowed cpus */<br />
};<br />
<br />
<br />
==== Example Accounting: Sockets====<br />
Basically all the accounting and limit stuff are defined as macros or inline functions capable of handling the different resources, hiding the underlying implementation wherever possible.<br />
#define vx_acc_sock(v,f,p,s) \<br />
__vx_acc_sock((v), (f), (p), (s), __FILE__, __LINE__)<br />
<br />
static inline void __vx_acc_sock(struct vx_info *vxi,<br />
int family, int pos, int size, char *file, int line)<br />
{<br />
if (vxi) {<br />
int type = vx_sock_type(family);<br />
<br />
atomic_inc(&vxi->cacct.sock[type][pos].count);<br />
atomic_add(size, &vxi->cacct.sock[type][pos].total);<br />
}<br />
}<br />
<br />
#define vx_sock_recv(sk,s) \<br />
vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 0, (s))<br />
#define vx_sock_send(sk,s) \<br />
vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 1, (s))<br />
#define vx_sock_fail(sk,s) \<br />
vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 2, (s))<br />
<br />
And this general definition is then used where appropriate, for example in the __sock_sendmsg() function like this:<br />
<br />
len = sock->ops->sendmsg(iocb, sock, msg, size);<br />
if (sock->sk) {<br />
if (len == size)<br />
vx_sock_send(sock->sk, size);<br />
else<br />
vx_sock_fail(sock->sk, size);<br />
}<br />
<br />
==== Example Limits: Virtual Memory====<br />
#define vx_pages_avail(m, p, r) \<br />
__vx_pages_avail((m)->mm_vx_info, (r), (p), __FILE__, __LINE__)<br />
<br />
static inline int __vx_pages_avail(struct vx_info *vxi,<br />
int res, int pages, char *file, int line)<br />
{<br />
if (!vxi)<br />
return 1;<br />
if (vxi->limit.rlim[res] == RLIM_INFINITY)<br />
return 1;<br />
if (atomic_read(&vxi->limit.res[res]) +<br />
pages < vxi->limit.rlim[res])<br />
return 1;<br />
return 0;<br />
}<br />
<br />
#define vx_vmpages_avail(m,p) vx_pages_avail(m, p, RLIMIT_AS)<br />
#define vx_vmlocked_avail(m,p) vx_pages_avail(m, p, RLIMIT_MEMLOCK)<br />
#define vx_rsspages_avail(m,p) vx_pages_avail(m, p, RLIMIT_RSS)<br />
<br />
And again the test against those limits at certain places, for example here in copy_process()<br />
/* check vserver memory */<br />
if (p->mm && !(clone_flags & CLONE_VM)) {<br />
if (vx_vmpages_avail(p->mm, p->mm->total_vm))<br />
vx_pages_add(p->mm->mm_vx_info,<br />
RLIMIT_AS, p->mm->total_vm);<br />
else<br />
goto bad_fork_free;<br />
}<br />
<br />
==== Example Virtualization: Uptime====<br />
void vx_vsi_uptime(struct timespec *uptime)<br />
{<br />
struct vx_info *vxi = current->vx_info;<br />
<br />
set_normalized_timespec(uptime,<br />
uptime->tv_sec - vxi->cvirt.bias_tp.tv_sec,<br />
uptime->tv_nsec - vxi->cvirt.bias_tp.tv_nsec);<br />
return;<br />
}<br />
<br />
if (vx_flags(VXF_VIRT_UPTIME, 0))<br />
vx_vsi_uptime(&uptime, &idle);<br />
<br />
[[Category:Documentation/fr]]</div>Glennhttp://linux-vserver.org/Category:ProcFS/frCategory:ProcFS/fr2011-10-23T10:47:21Z<p>Glenn: +/fr</p>
<hr />
<div>{{Languages|:Category:ProcFS}}<br />
<br />
[[Category:French]]<br />
[[Category:Documentation/fr]]</div>Glennhttp://linux-vserver.org/Category:Documentation/frCategory:Documentation/fr2011-10-23T10:46:51Z<p>Glenn: new</p>
<hr />
<div>{{Languages|:Category:Documentation}}<br />
<br />
[[Category:Categories]]</div>Glennhttp://linux-vserver.org/Paper/frPaper/fr2011-10-23T10:46:18Z<p>Glenn: +Category:Documentation/fr</p>
<hr />
<div>{{Languages|Paper}}<br />
<br />
==Abstract ==<br />
Concept logiciel basé sur les ''Security Contextes'' permet la création d'une multitude de serveurs virtuels Privés (VPS) tournant simultanément sur un même serveur physique à pleine vitesse, en partageant efficacement les ressources matérielles.<br />
Un VPS offre un environnement quasiment identique à celui d'un serveur Linux conventionnel. Tous les services, comme ssh, mail, Web, bases de données, peuvent être lancés dans un tel VPS, sans aucune modification (ou, dans certains cas, des modifications mineures), exactement comme avec n'importe quel autre serveur réel.<br />
<br />
Chaque serveur virtuel possède sa propre base utilisateurs et son mot de passe root. Il est isolé de tous les autres serveurs virtuels, sauf en ce qui concerne les ressources matérielles, qui sont partagées par tous les serveurs virtuels.<br />
<br />
== Introduction ==<br />
Au fur et à mesure des années, les micro ordinateurs sont devenus suffisemment puissant pour utiliser la virtualisation comme méthode pour donner l'illusion d'avoir une multitude de petites machines virtuelles, chacune d'elle tournant avec une instance différente de n'importe quel système d'exploitation.<br />
<br />
Il existe plusieurs types de Machines Virtuelles (VMs) dont les fonctionnalités sont similaires, mais qui diffèrent dans le degré d'abstraction et les méthodes utilisées pour la virtualisation.<br />
<br />
La plupart d'entre elles "émulent" une ressource matérielle réelle ou fictive, qui, à son tour, fait usage de "vraies" ressources du système Hote (la machine qui fait tourner les VMs). Cette approche, utilisée par la plupart des émulations système (comme QEMU[U1], Bochs[U2], ... permet à l'émulateur d'éxécuter n'importe quel système d'exploitation, même pour une architecture différente (CPU et matérielle). Pas besoin de modifier le système d'exploitation Invité, puisqu'il n'est pas conscient de s'éxécuter sur autre chose qu'un vrai matériel.<br />
<br />
Quelques émulations systèmes ont besoin d'un petit nombre de modifications ou de pilotes de périphériques spécifiques sur le système Hote ou le système Invité pour améliorer les performances, et minimiser le grignotage superflu de ressources système qui passe dans les systèmes de cache et de médiation entre le système Hote et le système Invité. Bien que cela améliore sensiblement l'efficacité de ces solutions, les ressources perdues sont toujours notables (par exemple dans UML[U3] et Xen[U4]).<br />
<br />
Supposez par contre que les systèmes d'exploitation à lancer ne sont pas différents ... La plupart des applications qui tournent sur un serveur n'ont pas besoin d'acceder au matériel ou à du code au niveau noyau, et pourraient donc partager une machine avec les autres, si l'on pouvait les séparer et les isoler ...<br />
<br />
== Le Concept ==<br />
A la base, un serveur Linux est constitué de trois blocs constitutifs: Le matériel, le Noyau, et les Applications. Le Matériel dépend habituellement du fournisseur ou de l'administrateur système, et, bien qu'ayant une grande influence sur les performances globales, ne peut pas être changé facilement, et diffère sensiblement d'une configuration à l'autre.<br />
<br />
Un role de base du noyau consiste à créer une couche d'abstraction au dessus du matériel pour permettre aux processus (Applications) de travailler avec des ressources (Données) sans connaitre les détails du matériel qui se trouve en dessous. Idéalement, ces processus sont complètement agnostiques vis-à-vis du matériel, écrit dans un langage interprété, et ne nécessitant par conséquent aucun savoir faire spécifique au matériel.<br />
<br />
Puisqu'un système possède assez de ressources pour faire tourner environ dix fois plus d'applications que nécessaire sur un serveur Linux traditionnel, pourquoi ne pas placer sur celui-ci une dizaine de serveurs, qui vont partager les ressources d'une manière efficace ?<br />
<br />
La plupart des serveurs d'application (par exemple httpd) considère qu'il est la seule application à fournir un service particulier, et d'habitude, va donc supposer une organisation particulière au niveau du système de fichiers, et de l'environnement. Cela implique que deux services identiques tournant sur un même serveur physique, mais différent simplement au niveau de leur adresse IP, par exemple, doivent être coordonnées. Cela demande typiquement pas mal de boulot pour l'administrateur système, et cela peut conduire à un stabilité réduite du système et de la sécurité.<br />
<br />
Le concept de base de la solution Linux-VServer est de séparer l'environnement en user space (espace utilisateur) en trois unités distinctes (appellées parfois VPS, ou Virtual Private Server), de telle manière que chaque VPS ressemblera à un vrai serveur vis-à-vis des processus qu'il contient.<br />
<br />
Bien que différentes Distributions Linux utilisent des noyaux modifiées (parfois lourdement) pour assurer le support de telle ou telle fonctionnalité, ou matériel, la plupart des distributions Linux ne sont pas liées irrévocablement à un noyau linux particulier.<br />
<br />
Linux-VServer utilise cela pour donner à plusieurs distributions, la possibilité de se lancer au dessus d'un seul noyau, partagé, sans accès direct au matériel, et partager les ressources d'une manière très efficace.<br />
<br />
== Infrastructure Existante ==<br />
Les noyaux Linux récents fournissent déjà de nombreuses fonctions de sécurité qui sont utilisées par Linux-Vserver pour fonctionner, telles que le Système de Privileges Linux, les limites de ressource, les attributs de fichier et l'environnement chroot. Les sections suivantes vous donneront un court aperçu de chacune d'entre elles. <br />
=== Le système de Privileges (Capabilities) Linux ===<br />
En science informatique, un privilege est un jeton utilisé par un processus pour prouver qu'il est autorisé à faire une opération sur un objet. Le Système de privileges Linux est basé sur les "Privileges POSIX", un concept légèrement similaire, conçu pour diviser les privilèges root puissants en un ensemble de privilèges distincts.<br />
<br />
==== Privileges POSIX ====<br />
Un processus possède trois champs de bits appelés les privileges héritables (I - "Inheritable"), permises (P), et effectives (E). Chaque privilege est implémenté dans un bit de chacun de ces champs, bit qui est soit défini soit non-défini.<br />
<br />
Quand un processus essaie de faire une opération privilégiée, le système d'exploitation va vérifier les bits appropriés dans l'ensemble effectif des processus (au lieu de vérifier si l'uid respectif du processus est 0 comme il le fait habituellement).<br />
<br />
Par exemple, quand un processus essaie de modifier l'horloge, le noyau Linux va vérifier que ce processus a le bit CAP_SYS_TIME (actuellement le bit 25) parmi ses privileges effectives.<br />
<br />
L'ensemble permis d'un processus indique les privileges que celui-ci peut utiliser. Le processus peut avoir des privileges définies dans l'ensemble permis qui ne sont pas dans l'ensemble effectif.<br />
<br />
Ceci indique que le processus a temporairement désactivé ce privilege. Un processus n'est autorisé à définir un bit dans son ensemble effectif que si ce bit est disponible dans son ensemble permis.<br />
<br />
La distinction entre privileges effectif et permis existe pour que les processus puissent réaliser des opérations qui nécessitent des privilèges.<br />
<br />
Les privileges héritables sont les privileges du processus courant qui peuvent être hérités par un programme exécuté par ce dernier. L'ensemble permis d'un processus est masqué contre l'ensemble héritable pendant exec().<br />
<br />
Rien de spécial ne se produit durant fork() ou clone().<br />
<br />
Les processus fils ou les threads obtiennent une copie exacte des privileges du processus parent.<br />
<br />
L'implémentation dans Linux s'arrête là, alors que les privileges POSIX[U5] requièrent l'ajout d'un ensemble de privileges aux fichiers, pour remplacer le flag SUID (au moins pour les exécutables).<br />
<br />
==== Vue d'ensemble des privileges ====<br />
La liste des privileges POSIX utilisées avec Linux est longue, et les 32 bits disponibles sont presques tous utilisés. Bien que la liste détaillée de ces privileges puisse être trouvée dans /usr/include/linux/capability.h sur la plupart des systèmes Linux, une vue d'ensemble des privileges importantes est donnée ici.<br />
{|class="wikitablenowrap"<br />
| 0|| CAP_CHOWN || change le propriétaire et le groupe du fichier<br />
|-<br />
| 5|| CAP_KILL|| envoie un signal au processus avec un ID utilisateur différent, réel ou effectif<br />
|-<br />
| 6|| CAP_SETGID|| permet le passage de setgid(2), setgroups(2), et de gids forgés sur les sockets<br />
|-<br />
| 7|| CAP_SETUID|| permet le passage de set*uid(2) et d'uids forgés sur les sockets<br />
|-<br />
| 8|| CAP_SETPCAP|| transfert/déplace tout privilege de l'ensemble permis vers/depuis n'importe quel pid<br />
|-<br />
| 9|| CAP_LINUX_IMMUTABLE|| permet la modification des attributs de fichier S_IMMUTABLE et S_APPEND<br />
|-<br />
| 11|| CAP_NET_BROADCAST|| permet la diffusion et l'écoute en multicast<br />
|-<br />
| 12|| CAP_NET_ADMIN|| permet la configuration de l'interface, le pare-feux IP, le masquerading, l'accounting, le débugage de sockets, les tables de routage, la liaison sur n'importe quelle adresse, l'entrée dans le mode de promiscuité, le multicasting...<br />
|-<br />
| 13|| CAP_NET_RAW|| permet l'utilisation des sockets RAW et PACKET<br />
|-<br />
| 16|| CAP_SYS_MODULE|| ajoute et retire des modules noyau<br />
|-<br />
| 18|| CAP_SYS_CHROOT|| permet chroot(2)<br />
|-<br />
| 19|| CAP_SYS_PTRACE|| permet ptrace() sur n'importe quel processus<br />
|-<br />
| 21|| CAP_SYS_ADMIN|| la liste serait trop longue, ceci permet en gros de faire tout ce qui n'est pas mentionné dans les autres privileges<br />
|-<br />
| 22|| CAP_SYS_BOOT|| permet reboot(2)<br />
|-<br />
| 23|| CAP_SYS_NICE|| permet l'élévation des privilèges et la modification de la priorité des autres processus, en modifiant l'ordonnanceur<br />
|-<br />
| 24|| CAP_SYS_RESOURCE|| passe outre les limites de ressource, de quota, l'espace réservé sur un système de fichier...<br />
|-<br />
| 27|| CAP_MKNOD|| permet les aspects privilégiés de mknod(2)<br />
|}<br />
<br />
Voir également les Exemples [E01],[E02], et [E03].<br />
<br />
=== Limite des Ressources ===<br />
Vous pouvez limiter les ressources de chaque processus en spécifiant une limite pour chaque ressource. A la manière des privileges Linux, il existe deux types de limites, l'une Douce, l'autre Dure.<br />
<br />
La limite Douce est la valeur que le noyau imposera pour cette ressource à un processus. Un utilisateur non privilégié pourra régler la limite Douce n'importe où en dessous de la valeur Dure. Seul l'utilisateur root pourra re-hausser la limite Dure.<br />
<br />
==== Apercu des Ressources Limit-ables ====<br />
La liste des ressources qui peuvent être limitées se trouve dans le fichier /usr/include/asm/resource.h sur la plupart des systèmes Linux.<br />
{|class="wikitablenowrap"<br />
| 0|| RLIMIT_CPU || Temps CPU en secondes. un signal SIGXCPU est envoyé au processus qui a atteind la limite Douce, et un SIGKILL pour la limite Dure.<br />
|-<br />
| 4|| RLIMIT_CORE || Taille maximale d'un fichier core.<br />
|-<br />
| 5|| RLIMIT_RSS || Nombre de pages maximum qu'un processus peut utiliser (en RAM)<br />
|-<br />
| 6|| RLIMIT_NPROC || Nombre maximum de processus autorisés à l'utilisateur réel du processus appelant.<br />
|-<br />
| 7|| RLIMIT_NOFILE || Spécifie la valeur +1 pour le nombre maximum de descripteurs de fichiers ouvert par un processus.<br />
|-<br />
| 8|| RLIMIT_MEMLOCK || Nombre maximum de pages mémoire virtuelle autorisées à être vérouillées en RAM à l'aide des appels mlock() ou mlockall().<br />
|-<br />
| 9|| RLIMIT_AS || Nombre maximum de pages de mémoire virtuelle disponible pour un processus.<br />
|}<br />
<br />
(Limite de l'espace d'adressage) <br />
<br />
Voir aussi les Exemples [E11], et [E12].<br />
<br />
=== Attributs de Fichiers ===<br />
Auparavant, cette fonctionnalité n'était disponible qu'avec ext2, mais maintenant tous les systèmes de fichiers majeurs implémentent un ensemble d'Attributs de fichiers de base, qui permettent le paramétrage de certaines propriétés. Voici de nouveau un bref aperçu des possibilités des attributs, et leur signification.<br />
<br />
{|class="wikitablenowrap"<br />
| s SECRM || Lorsqu'un fichier avec cet attribut est détruit, les blocs qui le composent sont mis à zéro et re-écrit sur le disque.<br />
|-<br />
| u UNRM || Lorsqu'un fichier avec cet attribut est détruit, son contenu est sauvegardé.<br />
|-<br />
| c COMPR || Un fichier marqué avec cet attribut est automatiquement compressé à l'écriture et décompressé à la lecture. (pas encore implémenté)<br />
|-<br />
| i IMMUTABLE || Un fichier avec cet attribut ne pourra pas être modifié: Impossible de le renommer ou de le détruire, impossible de créer un lien vers ce fichier, ni d'écrire une donnée de plus vers ce fichier. <br />
|-<br />
| a APPEND || Un fichier avec cet attribut ne pourra être ouvert qu'en mode ajout.<br />
|-<br />
| d NODUMP || Si cet attribut de fichier est mis, le fichier n'est pas candidat à un backup via l'utilitaire "dump".<br />
|-<br />
| S SYNC || Les mises à jour vers ce fichier se feront de manière synchrone.<br />
|-<br />
| A NOATIME || Empêche la mise à jour de l'enregistrement atime lors d'un accès ou d'une modification de fichier.<br />
|-<br />
| t NOTAIL || Un fichier avec l'attribut t n'aura pas de fragment bloc en fin de fichier fusionné avec un autre fichier.<br />
|-<br />
| D DIRSYNC || Les modifications apportés à ce répertoire seront écrites de manière synchrones. <br />
|}<br />
<br />
Voir aussi les Exemples [E13] et [E14].<br />
<br />
=== La Commande chroot(1) ===<br />
chroot permet de lancer une commande en changeant le répertoire racine dans lequel il va s'éxécuter. Cela signifie que tout parcours du système de fichiers à partir de la racine '/' se fera à partir de la racine substituée et non pas à partir de la racine originelle.<br />
<br />
Bien que le chroot Linux n'est pas très sécurisé, son utilisation augmente l'isolation des processus par rapport au système de fichier, et, à condition de l'utiliser correctement, peut être utilisé pour "emprisonner" un processus, un utilisateur unique, ou un démon (service).<br />
<br />
Voir l'Exemple [E15]<br />
<br />
== Modifications Requises ==<br />
Ce chapitre décrit les modifications à apporter au noyau pour implémenter un mécanisme comme Linux-VServer.<br />
<br />
=== Séparation de Contextes ===<br />
La séparation telle que décrite dans la partie 'Concepts' nécessite quelques modifications au noyau pour permettre la notion de Contexte.<br />
<br />
Le but d'un tel "Contexte" est de cacher à un processus tout ce qui ne doit pas etre à sa portée, et empécher les interractions indésirables entre un processus appartenant à un contexte et un processus appartenant à un autre contexte.<br />
<br />
Cette séparation nécessite l'extension d'un certain nombre de structures de données pour qu'elles prennent en compte les contextes et fassent la différentiation entre deux uids identiques mais utilisés dans deux serveurs virtuels différents.<br />
<br />
De plus, nous avons besoin d'un contexte par defaut qui sera utilisé par le serveur hôte au démarrage, et pour éviter les problèmes liés à des suppositions érronées de certains outils en espace utilisateur (comme pstree) par exemple, l'idée comme quoi init existe toujours et a toujours l'uid 1.<br />
<br />
Pour simplifier l'administration, le Contexte de l'Hôte n'est pas traité différemment d'un autre contexte, en tout cas du point de vue de l'isolation des processus.<br />
<br />
Pour avoir un apercu global de tous les processus, un Spectateur spécial a été mis en place, qui est capable de capturer tous les processus d'un coup.<br />
Voir les Examples [E21],[E22] et [E23]<br />
<br />
=== Séparation Réseau ===<br />
Bien que les Contextes soient suffisant pour isoler un groupe de processus, un autre type d'isolation, ou plutot une limitation, est nécessaire pour confiner les processus dans un sous ensemble d'adresses réseau disponibles.<br />
<br />
Plusieurs problèmes doivent être pris en compte dans ce sens: par exemple, les appels système bind sur IPADDR_ANY doivent être traités d'une manière bien particulière.<br />
<br />
Actuellement, Linux-Vserver n'utilise pas les interfaces virtuelles (et ne les utilisera peut-être jamais), pour minimiser le cout supplémentaire qu'elles engendrent. De ce fait, l'attachement d'une socket et la transmission des packets ont été adaptés.<br />
<br />
Voir Example [E24]<br />
<br />
=== La Barrière Chroot ===<br />
Un problème majeur avec le chroot() de Linux aujourd'hui tient au fait que cette information est volatile, et changera au prochain appel système de chroot().<br />
<br />
Voici une façon simple pour sortir d'un environnement chrooté Créez tout d'abord un fichier, et retenez son descripteur. Puis chrootez dans un répertoire au même niveau ou un niveau au dessous de celui-ci. Cela a pour effet de faire descendre la racine' dans le système de fichiers. Ensuite, faites un appel à fchdir() sur le descripteur de fichiers pour sortir de cette nouvelle racine. Vous sortirez en même temps de l'ancienne racine, qui a été perdue suite au dernier appel système chroot().<br />
<br />
Alors que des méthodes exotiques étaient utilisées dans les anciennes versions de Linux-Vserver pour fixer ce problème, les versions récentes utilisent un marquage spécial, connu sous le nom de Barrière Chroot, placé sur le parent de tous les VPS pour prévenir toute modification non autorisée et sortie du confinement.<br />
<br />
=== Un plafond pour les Privileges ===<br />
L'implémentation actuelle des privileges Linux ne prend pas en compte les privileges POSIX sur les systèmes de fichiers. Si cela était le cas, les executables setuid et setgid seraient sécurisés. Pour conserver donc une bonne sécurité malgré cette contrainte, nous avons défini un plafond pour tous les processus d'un même contexte, et un masque de privileges additionnel pour chaque contexte a été aussi ajouté pour limiter à ce seul masque les processus qui appartiennent à ce contexte.<br />
<br />
La signification des privileges individuels (bits) pour ce masque est exactement identique à celui que permet l'ensemble des privileges.=== Isolation de Ressources ===<br />
<br />
=== Isolation de Ressources ===<br />
La plupart des ressources sont d'une certaine manière partagées à travers les différents contextes; certaines requièrent une isolation plus importante que les autres, soit pour éviter les problèmes de sécurité, ou pour permettre une meilleure comptabilité de l'usage des ressources;<br />
<br />
Ces ressources sont:<br />
* mémoire partagée, IPC<br />
* PID et User ID<br />
* Drapeau xid sur les fichiers<br />
* ptys Unix<br />
* sockets<br />
<br />
=== Drapeau XID pour les Filesystem XID ===<br />
Bien qu'elle puisse être totalement desactivée, cette modification est requise pour une meilleure robustesse au niveau du système de fichiers, et pour isoler les contextes. Le drapeau XID est aussi totalement indispensable pour implémenter le support pour les Limites Disques par Contexte et les Quotas par Contexte sur une partition partagée.<br />
<br />
Ce concept d'ajouter un identifiant de contexte (xid) à chaque fichier pour créer une notion d'appartenance d'un fichier à un contexte parait simple ... Il n'en est rien, car l'implémentation actuelle n'est pas triviale. Elle nécessite soit une modification des représentations du système de fichier, soit des astuces au niveau applicatif.<br />
<br />
Une approche non intrusive pour éviter toute modification du système de fichiers sous-jacent est d'utiliser les bits de poids forts de champs existants, comme ceux des UID ou GID pour stocker le XID additionnel.<br />
<br />
Une fois que les informations de contexte sont disponibles au niveau de chaque inode, l'étape logique suivante est d'étendre la vérification d'accès au contexte en plus du reste.<br />
<br />
Actuellement, tous les acces aux inodes sont vérifiés par rapport à leur contexte ID, à l'exception des contextes "Hôte" et "Spectateur".<br />
<br />
Les fichiers non étiquettés dans le contexte hôte sont simplement traités comme appartenant au contexte courant, et cela est requis pour que l'Unification soit possible. Si un tel fichier est modifié à l'intérieur d'un contexte, elle changera en silence vers son noveau contexte, en changeant son XID.<br />
<br />
Les méthodes suivantes de marquage sont utilisées:<br />
<br />
;UID32/GID32 or EXTERNAL: Ce format utilise l'espace inutilisé dans l'inode disque pour stocker les informations de contexte. Pour l'instant, c'est uniquement défini pour ext3/ext3, mais sera dans le futur aussi défini pour xfs, reiserfs, et jfs, dès que possible.<br />
<br />
Avantage: Valeurs 32bit uid/gid complètes.<br />
<br />
;UID32/GID16: Ce format utilise la moitié haute du GID pour stocker les informations de contexte. Cela est fait de manière transparente, sauf si le format est changé sans conversion préalable.<br />
<br />
Avantage: fonctionne avec tout système de fichiers équipé de UID / GID 32bits<br />
<br />
Désavantage: le GID est réduit a 16 bits.<br />
<br />
;UID24/GID24: Ce format utilise le premier quart haut de l'UID et du GID pour stocker les informations de contexte, une fois encore, d'une manière transparente. Cela permet 16 millions de groupes et utilisateurs, ce qui devrait suffire pour la majorité des applications.<br />
<br />
Avantage: fonctionne sur tout système de fichiers avec des UID/GID 32bits<br />
<br />
Desavantage: les UID et GID sont réduits a 24 bits.<br />
<br />
Voir Examples [E31] et [E32]<br />
<br />
== Modifications Supplémentaires ==<br />
En plus du strict minimum, voici un certain nombre de modifications, non indispensables, mais qui se sont révélées très utiles au fil du temps.<br />
<br />
=== Drapeaux par Contexte ===<br />
Très tôt, le besoin d'activer ou désactiver une fonctionnalité séparement pour l'un ou l'autre des Vserver est apparue. Un champ de bits a donc été ajouté (taille=word).<br />
<br />
Ce champ de bits comprend un bon nombre de drapeaux, un champ masque, qui indique les drapeaux disponibles, et un mécanisme de déclanchement spécial, pour activer un drapeau au démarrage, puis le désactiver en causant un évennement ou une action associée.<br />
<br />
Voici la liste des drapeaux prévus et pour la plupart déjà implémentés. Ils sont disponibles dans la branche de développement de Linux-VServer:<br />
<br />
{|class="wikitablenowrap"<br />
| 0|| VXF_INFO_LOCK (historique, obsolète)<br />
|-<br />
| 1|| VXF_INFO_SCHED (historique, obsolète)|| schedule all processes in a context as if they where one.<br />
|-<br />
| 2|| VXF_INFO_NPROC (historique, obsolète)|| limite le nombre de processus autorisés dans un contexte à la valeur NPROC.<br />
|-<br />
| 3|| VXF_INFO_PRIVATE (historique)|| interdiction d'entrer dans ce contexte depuis l'extérieur.<br />
|-<br />
| 4|| VXF_INFO_INIT (historique) || show the init process with pid '1'<br />
|-<br />
| 5|| VXF_INFO_HIDE (historique, obsolète)||<br />
|-<br />
| 6|| VXF_INFO_ULIMIT (historique, obsolète)||<br />
|-<br />
| 7|| VXF_INFO_NSPACE (historique, obsolète)||<br />
|-<br />
| 8|| VXF_SCHED_HARD || activer l'ordonnancement "Hard CPU"<br />
|-<br />
| 9|| VXF_SCHED_PRIO || calculer les priorités de chaque processus à l'aide du "contexte token bucket".<br />
|-<br />
| 10|| VXF_SCHED_PAUSE || mettre tous les processus de ce contexte dans la file "hold", les empéchant d'être ordonnancés à nouveau.<br />
|-<br />
| 16|| VXF_VIRT_MEM || virtualize the memory information so that the VM and RSS limits are used for meminfo and friends<br />
|-<br />
| 17|| VXF_VIRT_UPTIME || virtualiser l'uptime, en commançant à la date de création du contexte.<br />
|-<br />
| 18|| VXF_VIRT_CPU || <br />
|-<br />
| 24|| VXF_HIDE_MOUNT || afficher les /proc/{pid}/mounts comme vides.<br />
|-<br />
| 25|| VXF_HIDE_NETIF || cache les interfaces réseau et addresses non autorisées dans ce contexte.<br />
|}<br />
<br />
Voir Exemple [XX]<br />
<br />
=== Privileges par Contexte ===<br />
Lorsque nous sommes arrivé au nombre maximum de privileges envisageables sans trop modifier le noyau, l'étape suivante a été, naturellement, d'ajouter un système de privileges par contexte.<br />
<br />
Le mécanisme des privileges par contexte implémenté dans Linux-VServer permet un réglage fin des privileges Linux. Ils ne sont pas visibles aux processus d'un contexte donné, puisque de toute facon le processus n'aurait pas le droit de les vérifier ou de les modifier.<br />
<br />
Généralement, il y a deux facons d'utiliser ces privileges : * Require one or a number of context capabilities to be set in addition to a given Linux capability, each one controlling a distinct part of the functionality. For example the CAP_NET_ADMIN could be split into RAW and PACKET sockets, so you could take away each of them separately by not providing the required context capability.<br />
<br />
Consider the context capability sufficient for a specified functionality, even if the Linux Capability says something different. For example mount() requires CAP_SYS_ADMIN which adds a dozen other things we do not want, so we define a CCAP_MOUNT to allow mounts for certain contexts.<br />
<br />
The difference between the Context Flags and the Context Caps is more an abstract logical separation than a functional one, because they are handled very similar.<br />
Again, a list of the Context Capabilities and their purpose:<br />
<br />
{|class="wikitablenowrap"<br />
|0|| VXC_SET_UTSNAME|| autoriser le contexte à changer le nom de serveur et le nom de domaine en utilisant l'appel système noyau approprié<br />
|-<br />
|1|| VXC_SET_RLIMIT|| allow the context to modify the resource limits (within the vserver limits).<br />
|-<br />
|8|| VXC_RAW_ICMP|| allow raw icmp packets in a secure way (this makes ping work from inside)<br />
|-<br />
|16|| VXC_SECURE_MOUNT|| permit secure mounts, which at the moment means that the nodev mount option is added.<br />
|}<br />
<br />
=== Comptabilité par Contexte ===<br />
Plusieurs propriétés des contextes sont très utiles pour l'administrateur système, que ce soit pour garder un oeil sur les ressources, pour avoir une idée de ce que peut supporter le serveur, ou pour pouvoir facturer d'une manière ou d'une autre au client.<br />
<br />
Deux types de propriétés peuvent être comptabilisées, celles dont la valeur courante représente l'état du système (par analogie, prenez la vitesse d'un véhicule), et celles dont la valeur augmente régulièrement avec le temps (comme le kilométrage).<br />
<br />
La plupart des valeurs d'état sont limitables, et sont donc traitées d'une façon spécifique, comme cela est décrit dans la section qui suit.<br />
<br />
Good candidates for Context Accounting are:<br />
* Temps CPU utilisé<br />
* Nombre de fork() effectués<br />
* Nombre de messages Socket par Type<br />
* Nombre de paquets Transmis et Recus<br />
<br />
Voir Exemple [E41]<br />
<br />
=== Limites par Contexte ===<br />
La plupart des ressources système, que ce soit la consommation mémoire, le nombre de processus utilisés, le nombre de descripteurs de fichiers, la bande passante réseau, doivent pouvoir être limitées.<br />
<br />
Les limites par contexte permettent, pour chaque valeur limitable, de définir trois types de limites: minimum, soft, et hard(maximum).<br />
<br />
A l'heure actuelle, seule les limites hard sont supportées, et seulement une partie d'entre elles sont réellement activées. Voici une liste des limites par contexte actuelles et prévues:<br />
* limites sur les processus<br />
* limites sur l'ordonnanceur<br />
* limites mémoire<br />
* limites disques par contexte<br />
* quotas user/groupe par contexte<br />
<br />
De plus, les limites par contexte gardent trace des valeur maxima atteintes et du nombre de fois ou la limite a été atteinte (hit), pour donner un feedback utile a l'administrateur.<br />
<br />
Voir Exemple [E42]<br />
<br />
=== Virtualisation ===<br />
One major difference between the Linux-VServer approach and Virtual Machines is that you do not have the virtualization part as a side-effect, so you have to do that by hand where it makes sense.<br />
<br />
For example, a Virtual Machine does not need to think about uptime, because naturally the running OS was started somewhere in the past and will not have any problem to tell the time it thinks it began running.<br />
<br />
A context can also store the time when it was created, but that will be different from the systems uptime, so in addition, there has to be some function, which adjusts the values passed from kernel to user-space depending on the context the process belongs to.<br />
<br />
This is what for Linux-VServer is known as Virtualization (actually it's more faking some values passed to and from the kernel to make the processes think that they are on a different machine).<br />
<br />
Currently modified for the purpose of Virtualization are:<br />
* System Uptime<br />
* Host and Domain Name<br />
* Machine Type and Kernel Version<br />
* Context Memory Availability<br />
* Context Disk Space<br />
<br />
Voir Exemple [E43]<br />
<br />
=== Sécurité Renforcée ===<br />
Le mécanisme de sécurité Proc-FS protège les entrées dynamiques du système de fichiers proc, de façon à ce que toutes les entrées ne soient pas vues dans tous les contextes.<br />
<br />
Le système est constitué de trois drapeaux pour chaque entrée du Proc-FS: Admin, Watch, et Hide.<br />
<br />
Le Drapeau Hide active ou désactive entierement une fonctionnalité, donc toute combinaison associée avec un drapeau Hide à 0 aura donc la signification visible.<br />
<br />
Les drapeaux Admin et Watch déterminent ou l'entrée hidden (cachée) reste visible; par exemple, si les drapeaux Admin et Hidden sont mis, seul le Host Contexte (0) sera en mesure de voir cette entrée spécifique.<br />
<br />
Voir Exemple [E44] et Voir Exemple [E45]<br />
<br />
=== Kernel Helper ===<br />
Dans certains cas, il peut être nécessaire de mettre en place un outil en espace utilisateur qui va agir en lieu et place du noyau, lorsque par exemple un processus demande une fonctionnalité disponible sur un serveur réel, mais non disponible dans un contexte.<br />
<br />
Le meilleur exemple d'un tel cas est le "Reboot Helper", qui implémente l'appel système reboot(), invoqué depuis l'intérieur d'un contexte en lieu et place du noyau. L'appel sera éxécuté depuis le contexte hôte, qui lancera l'action adéquate, reboot ou un simple halt du contexte en question.<br />
<br />
Bien que ce "helper" soit concu pour être flexible et gérer un certain nombre de choses de la même facon, il n'est pas utilisé pour l'instant à autre chose, et pourrait être remplacé dans le futur par une interface par evènement.<br />
<br />
Voir Exemple [XX]<br />
<br />
== Fonctionnalités et documentation additionnelle ==<br />
=== Unification ===<br />
L'un des objectifs centraux de Linux-VServer est de réduire l'utilisation des ressources partout ou cela est possible. Une excellente idée a donc germé, celle de partager des fichiers à travers les différents contextes sans interférer avec les taches administratives classiques ou diminuer le niveau de sécurité.<br />
<br />
Les fichiers communs à plusieurs contextes, peu sujet à être modifiés, comme les bibliothèques ou les binaires, peuvent être soudés via un lien dur sur un système de fichier partagé, réduisant d'autant le besoin en espace disque, cache d'inodes, et surtout, l'occupation mémoire, via l'utilisation des bibliothèques partagées.<br />
<br />
Seul inconvénient, si nous ne prenons pas quelques mesures supplémentaires, un contexte malicieux sera en mesure, par accident ou volontairement, de détruire ou modifier un tel fichier partagé, ce qui aurait des conséquences directes sur les autres contextes.<br />
La première étape consiste à placer sur les fichiers partagés un drapeau Immutable (et enlever la caps qui permet de modifier un tel fichier). Il faut toutefois ajouter un attribut supplémentaire à ces fichiers partagés, pour permettre leur suppréssion, lors, par exemple, d'une mise à jour des bibliothèques dans un l'un des contextes.<br />
<br />
Ces fichiers liés, immutables, que l'ont peut toutefois détruire, et appartenant à plus d'un contexte sont appelés unifiés, et l'action qui consiste à les rechercher et les préparer s'appelle Unification.<br />
<br />
Choississez l'unification si vous souhaitez réduire votre usage de ressources. L'inconvénient évident est une administration moins facile. Un Serveur Linux s'installe typiquement sur 500Mo de disque, et 10 serveurs unifiés en consommeront donc seulement 700Mo, et moins de mémoire pour les caches.<br />
<br />
Voir Exemple [XX]<br />
<br />
=== Espaces de nom privés ===<br />
Ajoutés récemment dans Linux-VServer, les espaces de noms privés utilisent la couche VFS du noyau linux et offrent une vue différente du système de fichier pour chaque contexte.<br />
Par rapport au schéma traditionnel, l'avantage principal apparait lorsqu'on modifie quelquechose dans un espace de nommage (par exemple, les points de montage); à cet instant, les autres contextes resteront intact, y compris biensur le contexte Hôte.<br />
Désavantage évident d'une telle approche; entrer dans un tel espace de noms privé n'est pas aussi simple que d'entrer dans un chroot. Toutefois, les choses pourraient changer dans les noyaux futurs, si cette fonctionnalité est par exemple intégrée directement à la fonction chroot().<br />
<br />
=== Le système de fichier Proc-FS de Linux-VServer ===<br />
A structured, dynamically generated subtree of the well-known Proc-FS - actually two of them - has been created to allow for inspecting the different values of Security and Network Contexts.<br />
/proc/virtual<br />
.../info<br />
<br />
/proc/virtual/<pid><br />
.../info<br />
.../status<br />
.../sched<br />
.../cvirt<br />
.../cacct<br />
.../limit<br />
<br />
=== Extensions Token Bucket ===<br />
While the basic idea of Linux-VServer is a peaceful coexistence of all contexts, sharing the common resources in a respectful way, it is sometimes useful to control the resource distribution for resource hungry processes.<br />
<br />
The basic principle of a Token Bucket is not very new. It is given here as an example for the Hard CPU Limit. The same principle also applies to scheduler priorities, network bandwidth limitation and resource control in general.<br />
<br />
The Hard CPU Limit uses this mechanism in the following way: consider a bucket of a certain size S which is filled with a specified amount of tokens R every interval T, until the bucket is "full" - excess tokens are spilled. At each timer tick, a running process consumes exactly one token from the bucket, unless the bucket is empty, in which case the process is put on a hold queue until the bucket has been refilled with a minimum M of tokens. The process is then rescheduled.<br />
<br />
A major advantage of a Token Bucket is that a certain amount of tokens can be accumulated in times of quiescence, which later can be used to burst when resources are required.<br />
<br />
Where a per-process Token Bucket would allow for a CPU resource limitation of a single process, a Context Token Bucket allows to control the CPU usage of all confined processes.<br />
<br />
Another approach, which is also implemented, is to use the current fill level of the bucket to adjust the process priority, thus reducing the priority of processes belonging to excessive contexts.<br />
<br />
Voir Exemple [XX]<br />
<br />
=== Limites Disque par Contexte ===<br />
Pour faire usage de cette fonctionnalité, le support pour les fichiers étiquetés XID doit être présent. Grace aux limites par contexte, vous pouvez alors régler une limite différente pour chaque contexte d'une partition partagée.<br />
<br />
Chaque block et inode d'un système de fichier est comptabilisé, dès lors qu'un hachage XID a été ajouté à ce système de fichier dans ce contexte donné.<br />
Those values, including current usage, maximum and reserved space, will be shown for filesystem queries, creating the illusion that the shared filesystem has a different usage and size, for each context.<br />
<br />
=== Quota par Contexte ===<br />
Similar to the Context Disk Limits, Per-Context Quota uses separate quota hashes for different Contexts on a shared filesystem. This is not required to allow for Linux-VServer quota on separate partitions.<br />
<br />
=== Le périphérique "proxy" VRoot ===<br />
Les opérations sur les Quotas (ioctls) nécessitent un accès aux périphériques de bloc. Ils ne sont donc pas disponible dans un VPS.<br />
<br />
=== Stealth ===<br />
Pour certaines applications, par exemple la préparation d'un "pot de miel" (honey-pot), ou d'une imitation particulièrement réaliste d'un vrai serveur à des fins éducatives, vous aurez peut-être besoin de confondre le contexte du serveur hôte (réel) et celui de votre pot de miel. <br />
Toutefois, certaines alternatives libres comme QEMU ou UML vous permettent de faire la même chose beaucoup mieux et avec moins d'efforts. Ce n'est donc pas une question centrale dans le développement de Linux-VServer.<br />
<br />
== Sécurité Linux-VServer ==<br />
Nous savons maintenant que Linux-VServer implémente quelques principes de sécurité, et comment ils fonctionnent. Il faut tout de même dire quelques mots la dessus, puisqu'il ne suffit pas, bien évidemment, de considérer que Linux-VServer étant une architecture sécurisée, votre système sera sur automatiquement. Comme d'habitude, mieux vaut savoir *exactement* ce que vous faites.<br />
<br />
=== Privileges Sécurisées ===<br />
Actuellement, seules les privileges Linux suivantes sont considérés d'un usage sans risque dans un VPS. Si d'autres privileges sont nécessaires, ils ouvrent probablement des trous de sécurité.<br />
* CAP_CHOWN<br />
* CAP_DAC_OVERRIDE<br />
* CAP_DAC_READ_SEARCH<br />
* CAP_FOWNER<br />
* CAP_FSETID<br />
* CAP_KILL<br />
* CAP_SETGID<br />
* CAP_SETUID<br />
* CAP_NET_BIND_SERVICE<br />
* CAP_SYS_CHROOT<br />
* CAP_SYS_PTRACE<br />
* CAP_SYS_BOOT<br />
* CAP_SYS_TTY_CONFIG<br />
* CAP_LEASE<br />
CAP_NET_RAW par exemple n'est pas considéré comme sur. Bien qu'il soit souvent utilisé pour donner le droit à la commande "ping" (dont le fonctionnement est cassé), il existe de bien meilleures alternatives comme la commande ping "poink[U7]", ou la cap VXC_RAW_ICMP.<br />
<br />
=== La Barrière Chroot ===<br />
Il faut vous assurer que le drapeau barrière est bien mis sur tout répertoire parent de chacun de vos VPS. Cela est indispensable pour prévenir quiconque de sortir du chroot et aller se balader dans le système de fichier de votre vserver hôte.<br />
<br />
<br />
<br />
=== Fichiers de périphériques Sécurisés ===<br />
Le répertoire /dev d'un VPS ne doit pas contenir plus de fichiers qu'indiqué ci-dessous, plus le répertoire pour les pts unix.<br />
* c 1 7 full<br />
* c 1 3 null<br />
* c 5 2 ptmx<br />
* c 1 8 random<br />
* c 5 0 tty<br />
* c 1 9 urandom<br />
* c 1 5 zero<br />
* d pts<br />
Bien entendu, d'autres périphériques comme console, mem, kmem, et même des périphériques en mode block et/ou caractère peuvent être ajoutés, mais une certaine expertise sera nécessaire pour s'assurer que cela n'entraine aucun trou de sécurité.<br />
<br />
=== Entrées Proc-FS Sécurisées ===<br />
Aucun test n'a été fait sur la fiabilité et la sécurité des entrées dans le système de fichiers proc, mais quelques incidents ont été notés lorsqu'on utilise par exemple des entrées proc avec permission d'écriture, et non protégées par une CAP linux.<br />
Par exemple, <tt>/proc/sysrq-trigger</tt> est un fichier qui ne doit en aucun cas être accessible dans un VPS sans une excellente raison.<br />
<br />
== Champ d'Applications ==<br />
Le but premier de ce projet est de permettre la création de serveurs virtuels partageant les ressources d'une même machine physique. Un Serveur Virtuel fonctionne comme un serveur Linux normal, et peut lancer des services traditionnels comme telnet, service de mail, service web, service SQL.<br />
<br />
=== Séparation Administrative ===<br />
Un provider intelligent peut donc vendre un serveur virtuel, qui, en utilisant moins de ressources que d'autres techniques de virtualisation, permet de lancer plus d'instances sur une même machine.<br />
<br />
La liste des providers qui fournissent un tel service est assez longue, et on peut donc considérer que c'est l'application principale de vserver.<br />
<br />
=== Séparation de Services ===<br />
Pour séparer plusieurs services identiques ou de nature différente, qui auraient autrement des interférences entre eux, est une chose facile à mettre en oeuvre avec Vserver. Plusieurs raisons peuvent vous pousser à faire cela; un service mal écrit, ou simplement deux services qui ne savent pas co-exister pour de multiples raisons.<br />
<br />
Même sur une machine à l'ancienne mode, placer un service très exposé ou non sécurisé car inconnu ou propriétaire dans une prison chroot peut améliorer grandement la sécurité et la maintenabilité.<br />
<br />
=== Améliorer la Sécurité ===<br />
Bien que l'idée de lancer plusieurs serveurs sur une seule machine soit en elle même très interessante, d'autres concepts sont encore plus interessants. Imaginez un serveur physique sur lequel tourne un seul vserver. Le but est d'isoler l'environnement principal de n'importe quel service, n'importe quel réseau. Vous démarrerez dans l'environnement principal, lancez très très peu de services, puis continuez dans le serveur virtuel.<br />
<br />
Le service de l'environnement principal sera:<br />
* Injoignable depuis le reseau.<br />
* En mesure de logger tous les messages du virtual serveur, d'une manière sécurisée. Rien dans le serveur virtuel ne permet d'effacer les logs, ou de les modifier. Même un serveur virtuel cracké ne permet pas de changer les logs.<br />
* En mesure de faire tourner un système de détection d'intrusion, qui espionnera l'état du serveur virtuel sans être accessible ou même détecté. Par exemple, vous pouvez installer et faire tourner tripwire depuis l'environnement principal, et impossible de modifier son fonctionnement ou de le tromper.<br />
Une autre option consiste à mettre le firewall dans un serveur virtuel, puis étirer la DMZ sur un ensemble de VPS séparés. Moyennant une configuration bien faite, ce genre d'installation peut réduire substantiellement le nombre de machines requises, sans pour autant impacter les performances.<br />
<br />
=== Maintenance Facilitée ===<br />
Une fonctionnalité clef d'un serveur virtuel est son indépendance vis à vis du matériel. La plupart des problèmes matériels sont inconnus au fonctionnement d'un serveur virtuel.<br />
<br />
Le serveur principal agit comme un système hôte, et s'occupe de tous les détails. Le serveur virtuel est simplement un client, et ignore tous les détails. De cette manière, le client peut être déplacé vers un autre serveur physique avec très peu de manipulations.<br />
<br />
Par exemple, pour déplacer un serveur virtuel depuis un ordinateur physique vers un autre, il suffit de procéder aux étapes suivantes:<br />
* stopper le serveur virtuel<br />
* le copier sur l'autre machine<br />
* copier sa configuration<br />
* lancer le serveur virtuel sur la nouvelle machine<br />
Pas de mise à jour des utilisateurs, pas de configuration matérielle, tant que les machines sont compatibles au niveau de leurs binaires.<br />
<br />
=== Scenarios de Fail-Over ===<br />
En repoussant les limites un peu plus loin, on peut utiliser des technologies de réplication pour conserver une copie identique à la minute près du système de fichier d'un serveur virtuel en fonctionnement. Cela peut servir à un basculement très rapide si le serveur en fonction tombe pour n'importe quelle raison.<br />
<br />
Toutes les methodes connues sont utilisables dans ce but, en commancant par la réplication réseau comme rsync, ou drdb, en passant par NBD (les Network Devices), les disques partagés, ou un système de fichier distribué. Toutes ces méthodes sont utilisables pour réduire le temps d'indisponibilité d'un système et améliorer l'efficacité globale.<br />
<br />
=== Pour test ===<br />
Vous avez besoin de construire un logiciel pour plusieurs versions d'une distribution particulière. (Mandrake 8.2, 9.0, 9.1, 9.2, 10.0), ou bien même pour plusieurs distributions différentes.<br />
<br />
Ce problème est résolu d'une manière très simple par Vserver. Avec pas mal d'espace disque, ces différentes distributions peuvent être installées et lancées en parallèle, simplifiant la tache de passer de l'une à l'autre.<br />
<br />
Biensur, vous pouvez faire cela simplement avec chroot() et rien d'autre, mais Vserver offre une simulation bien plus réaliste.<br />
<br />
== Performance et Stabilité ==<br />
=== Impact de Linux-VServer sur l'hôte ===<br />
=== Overhead dans un Contexte ===<br />
=== Taille du patch noyau ===<br />
<br />
== Matériels Non Intel i386 ==<br />
Linux-VServer est concu pour être indépendant de l'architecture au maximum du coup, seule une toute petite partie, la définition de l'appel système lui-même est spécifique à une architecture. Malgré cela, quelques architectures renfermen des copies de certains codes 'architecture independant', pour une raison ou pou une autre, et nécessitent par conséquent de légères modifications.<br />
<br />
Les architectures suivantes sont supportées, et certaines d'entre elles ont même été testées:<br />
* alpha<br />
* ia32 / ia64 / xbox<br />
* x86_64 (AMD64)<br />
* mips / mips64<br />
* hppa / hppa64<br />
* ppc / ppc64<br />
* sparc / sparc64<br />
* s390<br />
* uml<br />
L'ajout d'une nouvelle architecture est relativement simple, même si de tests extensifs sont nécessaires pour valider le bon fonctionnement d toutes les fonctionnalités telle qu'attendu. (et biensur, du matériel ;).<br />
<br />
<br />
== Intro Noyau Linux ==<br />
Bien que les fonctionnalités décrites plus haut sont codées dans le noyau, quelques outils sont nécessaires en espace utilisateur (userspace) pour les activer et les controler.<br />
<br />
Ces outils en userspace communiquent généralement avec le noyau via des appels système (syscalls).<br />
<br />
Le chapitre qui suit décrit les liens entre espace kernel et espace utilisateur, comment les appels système, méthode simple pour communiquer entre les processus et le noyau, fonctionnent.<br />
<br />
=== Espace Noyau et Espace Utilisateur ===<br />
Sous Linux et les systèmes d'exploitation similaires, l'espace noyau et l'espace utilisateur sont séparés, et l'espace d'adressage est divisé en deux parties. Dans L'espace noyau réside le code noyau, alors que les programmes utilisateur vivent dans l'espace utilisateur. Bien entendu, un programme ne peut écrire dans la mémoire noyau, ni dans la mémoire d'un autre processus.<br />
<br />
Malheureusement, c'est aussi le cas pour le code du noyau. Le code kernel n'a pas le droit d'écrire dans l'espace utilisateur. Qu'est-ce que cela signifie ? Lorsqu'un driver de périphérique a besoin d'écrire ses octets destinés à un programme dans l'espace utilisateur, il ne peut pas le faire directement, mais doit passer par des fonctions noyau spécifiques à la place. De même, lorsque des paramètres sont passés au noyau par référence à une fonction kernel, la fonction kernel ne peut pas lire les paramètres directement. Elle doit utiliser d'autres fonctions noyau pour lire chaque octet des paramètres.<br />
<br />
Bien entendu, il existe des fonctions écrites tout spécialement pour les transfer depuis et vers l'espace utilisateur.<br />
copy_to_user(void *to, const void *from, long n);<br />
copy_from_user(void *to, const void *from, long n);<br />
<br />
get_user() and put_user() Prendre ou placer l'octet, le mot, ou l'entier long depuis l'espace utilisateur ou vers celui-ci. C'est une macro, et elle se fie au type de ses arguments pour évaluer le nombre d'octets à transférer.<br />
<br />
=== Appels système Linux ===<br />
La plupart des appels libc s'appuient sur les appels système, la plus petite forme de fonction qu'un programme peut appeler.<br />
<br />
Ces appels système sont implémentés dans le noyau lui-même, ou dans des modules, parties de code noyau chargeables dynamiquement.<br />
<br />
Ils sont implémentés via un multiplexeur appelé avec un masque d'interruption précis. Sous Linux, ce masque d'interruption est int 0x80. Lorsque l'instruction 'int 0x80' est exécutée, le contrôle est donné au noyau (ou, plus précisément, à la fonction _system_call() ), et le démultipléxage proprement dit prend place.<br />
<br />
Comment fonctionne la fonction _system_call() ?<br />
<br />
Tout d'abord, tous les registres sont sauvegardés, et le contenu du registre %eax est comparé à la table des appels systèmes, qui recense tous les appels systèmes et leur adresse respective.<br />
<br />
On peut acceder à cette table via la variable extern void *sys_call_table[] Il existe un nombre et une adresse mémoire données dans cette table pour chacun des appels système.<br />
<br />
Ceux-ci sont référencés dans le fichier /usr/include/sys/syscall.h.<br />
<br />
Ils sont de la forme SYS_nomappelsysteme. si l'appel système n'est pas implémenté, la cellule correspondante dans la table sys_call_table est à 0, et une erreur est retournée.<br />
<br />
Sinon, l'appel système sort, et l'entrée correspondante dans la table donne l'adresse du code ou se trouve l'appel système.<br />
<br />
<br />
<br />
== Implémentation ==<br />
Ce chapitre est plus particulierement reserve aux developpeurs noyau. Toutefois, les curieux trouveront avantage a tirer le rideau pour decouvrir les entrailles du systeme.<br />
<br />
=== Appel systeme===<br />
Pendant un certain temps, Linux-VServer a utilise different appels systeme pour accomplir les differents aspects de son travail. Tres vite, le nombre des commandes necessaires est devenu important, nous avons donc commence a donner des valeurs magiques aux appels pour choisir le comportement desire.<br />
<br />
Enfin, il y a peu de temps, nous avons obtenu un numero reserve pour les appels systemes Linux-VServer, et malgre l'opinion de certains developpeurs, c'est globalement une bonne decision de garder un seul appel systeme.<br />
<br />
Avoir plusieurs appels systeme peut faciliter les choses pour travailler avec les appels systemes sur plusieurs architectures; toutefois, cela n'a pas constitue un probleme majeur jusqu'ici, les donnees transitant depuis et vers le noyau etant, conformement au standard C99, fortement typees.<br />
<br />
Quoi qu'il en soit, la mise en place d'un appel systeme passe par la creation d'un multiplexeur, qui va decider quelle commande doit etre executee, et quels arguments lui passer. A elle par la suite d'executer effectivement le travail demande.<br />
extern asmlinkage long<br />
sys_vserver(uint32_t cmd, uint32_t id, void __user *data)<br />
L'appel systeme Linux-VServer prend trois arguments dans tous les cas: la commande (cmd), un nombre (id), et une structure de donnee en espace utilisateur d'une taille encore inconnue.<br />
<br />
Pour faciliter le deboggage et la tenue a jour des informations de versionning, la chaine cmd est decomposee en trois parties: les 12 bits de poids faible contiennent le numero de version, puis 4 bits sont reserves. Les 16 bits de poids fort sont divises en 8 bits de commande et 6 pour la categorie, puis les 2 bits restant, reserves pour usage ulterieur.<br />
<br />
Nous avons donc 64 Categories avec chacune 256 commandes, et 4096 revisions possible pour chaque commande, ce qui surpasse largement nos besoins presents et futurs.<br />
<br />
Voici un apercu des categories deja definies, et leur valeur numerique associee:<br />
<br />
Matrice des appels systeme V2.6<br />
<br />
|VERSION|CREATE |MODIFY |MIGRATE|CONTROL|EXPERIM| |SPECIAL|SPECIAL|<br />
|STATS |DESTROY|ALTER |CHANGE |LIMIT |TEST | | | |<br />
|INFO |SETUP | |MOVE | | | | | |<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
SYSTEM |VERSION|VSETUP |VHOST | | | | |DEVICES| |<br />
HOST | 00| 01| 02| 03| 04| 05| | 06| 07|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
CPU | |VPROC |PROCALT|PROCMIG|PROCTRL| | |SCHED. | |<br />
PROCESS| 08| 09| 10| 11| 12| 13| | 14| 15|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
MEMORY | | | | | | | |SWAP | |<br />
| 16| 17| 18| 19| 20| 21| | 22| 23|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
NETWORK| |VNET |NETALT |NETMIG |NETCTL | | |SERIAL | |<br />
| 24| 25| 26| 27| 28| 29| | 30| 31|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
DISK | | | | | | | |INODE | |<br />
VFS | 32| 33| 34| 35| 36| 37| | 38| 39|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
OTHER | | | | | | | |VINFO | |<br />
| 40| 41| 42| 43| 44| 45| | 46| 47|<br />
=======+=======+=======+=======+=======+=======+=======+ +=======+=======+<br />
SPECIAL| | | | |FLAGS | | | | |<br />
| 48| 49| 50| 51| 52| 53| | 54| 55|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
SPECIAL| | | | |RLIMIT |SYSCALL| | |COMPAT |<br />
| 56| 57| 58| 59| 60|TEST 61| | 62| 63|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
<br />
La definition de ces commandes est simplifiee grace a certaines macros, comme par exemple interroger un drapeau ou lui attribuer une valeur:<br />
#define VCMD_get_cflags VC_CMD(FLAGS, 1, 0)<br />
#define VCMD_set_cflags VC_CMD(FLAGS, 2, 0)<br />
<br />
extern int vc_get_cflags(uint32_t, void __user *);<br />
extern int vc_set_cflags(uint32_t, void __user *);<br />
<br />
Notez bien, ce n'est pas la commande elle meme qui est passee en parametre, mais un id et un pointeur vers une structure de donnee en espace utilisateur.<br />
<br />
=== Structures de Donnees Utilisees===<br />
Plusieurs types de structures sont utilisees par les differentes parties de l'implementation; seuls quelques exemples sont donnes ici, l'ensemble complet des structures utilisees se trouve dans le source.<br />
==== La Structure Data Context====<br />
La structure Data Context permet de gerer les contextes, leur destruction, ainsi que les futurs contextes hierarchiques.<br />
<br />
Les sections reservees pour l'ordonanceur ou les limites sont definies dans des structures separees, comme le veut la logique, puis incorporees dans la structure principale.<br />
struct vx_info {<br />
struct list_head vx_list; /* linked list of contexts */<br />
xid_t vx_id; /* context id */<br />
atomic_t vx_refcount; /* refcount */<br />
struct vx_info *vx_parent; /* parent context */<br />
<br />
struct namespace *vx_namespace; /* private namespace */<br />
struct fs_struct *vx_fs; /* private namespace fs */<br />
uint64_t vx_flags; /* context flags */<br />
uint64_t vx_bcaps; /* bounding caps (system) */<br />
uint64_t vx_ccaps; /* context caps (vserver) */<br />
<br />
pid_t vx_initpid; /* PID of fake init process */<br />
<br />
struct _vx_limit limit; /* vserver limits */<br />
struct _vx_sched sched; /* vserver scheduler */<br />
struct _vx_cvirt cvirt; /* virtual/bias stuff */<br />
struct _vx_cacct cacct; /* context accounting */<br />
<br />
char vx_name[65]; /* vserver name */<br />
};<br />
<br />
<br />
Voici un exemple de la sous-structure Ordonanceur:<br />
struct _vx_sched {<br />
spinlock_t tokens_lock; /* lock for this structure */<br />
<br />
int fill_rate; /* Fill rate: add X tokens ... */<br />
int interval; /* Divisor: ... each Y jiffies */<br />
atomic_t tokens; /* current number of tokens */<br />
int tokens_min; /* Limit: minimum for unhold */<br />
int tokens_max; /* Limit: no more than N tokens */<br />
uint32_t jiffies; /* bias: integral multiple of Y */<br />
<br />
uint64_t ticks; /* token tick events */<br />
cpumask_t cpus_allowed; /* cpu mask for context */<br />
};<br />
<br />
L'idee principale derriere ces sous-structures est de faciliter leur maintenabilite, a l'aide, pour chacune d'elles, d'une fonction init et cleanup, d'ou une lecture facilitee et une maintenabilite accrue.<br />
<br />
==== The Scheduler Command Data====<br />
As an example for the data structure used to control a specific part of the context from user-space, here is a scheduler command and the utilized data structure to set the properties:<br />
#define VCMD_set_sched VC_CMD(SCHED, 1, 2)<br />
<br />
struct vcmd_set_sched_v2 {<br />
int32_t fill_rate; /* Fill rate: add X tokens ... */<br />
int32_t interval; /* Divisor: ... each Y jiffies */<br />
int32_t tokens; /* current number of tokens */<br />
int32_t tokens_min; /* Limit: minimum for unhold */<br />
int32_t tokens_max; /* Limit: no more than N tokens */<br />
uint64_t cpu_mask; /* Mask: allowed cpus */<br />
};<br />
<br />
<br />
==== Example Accounting: Sockets====<br />
Basically all the accounting and limit stuff are defined as macros or inline functions capable of handling the different resources, hiding the underlying implementation wherever possible.<br />
#define vx_acc_sock(v,f,p,s) \<br />
__vx_acc_sock((v), (f), (p), (s), __FILE__, __LINE__)<br />
<br />
static inline void __vx_acc_sock(struct vx_info *vxi,<br />
int family, int pos, int size, char *file, int line)<br />
{<br />
if (vxi) {<br />
int type = vx_sock_type(family);<br />
<br />
atomic_inc(&vxi->cacct.sock[type][pos].count);<br />
atomic_add(size, &vxi->cacct.sock[type][pos].total);<br />
}<br />
}<br />
<br />
#define vx_sock_recv(sk,s) \<br />
vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 0, (s))<br />
#define vx_sock_send(sk,s) \<br />
vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 1, (s))<br />
#define vx_sock_fail(sk,s) \<br />
vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 2, (s))<br />
<br />
And this general definition is then used where appropriate, for example in the __sock_sendmsg() function like this:<br />
<br />
len = sock->ops->sendmsg(iocb, sock, msg, size);<br />
if (sock->sk) {<br />
if (len == size)<br />
vx_sock_send(sock->sk, size);<br />
else<br />
vx_sock_fail(sock->sk, size);<br />
}<br />
<br />
==== Example Limits: Virtual Memory====<br />
#define vx_pages_avail(m, p, r) \<br />
__vx_pages_avail((m)->mm_vx_info, (r), (p), __FILE__, __LINE__)<br />
<br />
static inline int __vx_pages_avail(struct vx_info *vxi,<br />
int res, int pages, char *file, int line)<br />
{<br />
if (!vxi)<br />
return 1;<br />
if (vxi->limit.rlim[res] == RLIM_INFINITY)<br />
return 1;<br />
if (atomic_read(&vxi->limit.res[res]) +<br />
pages < vxi->limit.rlim[res])<br />
return 1;<br />
return 0;<br />
}<br />
<br />
#define vx_vmpages_avail(m,p) vx_pages_avail(m, p, RLIMIT_AS)<br />
#define vx_vmlocked_avail(m,p) vx_pages_avail(m, p, RLIMIT_MEMLOCK)<br />
#define vx_rsspages_avail(m,p) vx_pages_avail(m, p, RLIMIT_RSS)<br />
<br />
And again the test against those limits at certain places, for example here in copy_process()<br />
/* check vserver memory */<br />
if (p->mm && !(clone_flags & CLONE_VM)) {<br />
if (vx_vmpages_avail(p->mm, p->mm->total_vm))<br />
vx_pages_add(p->mm->mm_vx_info,<br />
RLIMIT_AS, p->mm->total_vm);<br />
else<br />
goto bad_fork_free;<br />
}<br />
<br />
==== Example Virtualization: Uptime====<br />
void vx_vsi_uptime(struct timespec *uptime)<br />
{<br />
struct vx_info *vxi = current->vx_info;<br />
<br />
set_normalized_timespec(uptime,<br />
uptime->tv_sec - vxi->cvirt.bias_tp.tv_sec,<br />
uptime->tv_nsec - vxi->cvirt.bias_tp.tv_nsec);<br />
return;<br />
}<br />
<br />
if (vx_flags(VXF_VIRT_UPTIME, 0))<br />
vx_vsi_uptime(&uptime, &idle);<br />
<br />
[[Category:French]]<br />
[[Category:Documentation/fr]]</div>Glennhttp://linux-vserver.org/Paper/esPaper/es2011-10-23T10:45:46Z<p>Glenn: +/es</p>
<hr />
<div>{{Languages|Paper}}<br />
<br />
== Infraestructura Existente==<br />
Los recientes núcleos de Linux ya proveen muchas prestaciones de seguridad que son utilizadas por Linux-Vserver para hacer su trabajo. Especialmente características tales como el Sistema de Capacidades de Linux, Límite de Recursos, Atributos de archivos y el Cambio del Entorno Raíz. Las siguientes secciones darán una breve reseña acerca de cada una de estas.<br />
<br />
=== Sistema de Capacidades de Linux===<br />
En ciencias de la computación, una capacidad es un signo usado por un proceso para probar que tiene permitido realizar una operación sobre un objeto. El Sistema de Capacidades de Linux se basa en las "Capacidades Posix", un concepto ligeramente, diseñado para fraccionar el privilegio todo poderoso de root en un conjunto de de distintos privilegios.<br />
<br />
==== Capacidades de Linux ====<br />
Un proceso tiene tres conjuntos de mapas de bits llamadas capacidades hereditarios(I), permitidos(P), y efectivos(E). Cada capacidad se implementa como un bit de estos mapas de bits que están activado o desactivados.<br />
<br />
Cuando un proceso intenta hacer una operación privilegiada, el sistema operativo comprobará el bit apropiado en el conjunto efectivo de los procesos (en lugar de comprobar si el uid efectivo del proceso es 0 como se hace normalmente).<br />
<br />
Por ejemplo, cuando un proceso intenta configurar el reloj, el núcleo Linux comprobará que el proceso tiene el bit CAP_SYS_TIME (que es actualmente el bit 25) habilitado en su conjunto efectivo.<br />
<br />
El conjunto pemitido de los procesos indica las capacidades que el proceso puede usar. El proceso puede tener capacidades habilitadas en el conjunto permitido que no están en el conjunto efectivo.<br />
<br />
Esto indica que el proceso tiene temporalmente deshabilitado esta capacidad. Un proceso tiene permitido habilitar un bit en su conjunto permitido solamente si está disponible en el conjunto permitido. La distinción entre efectivo y permitido existe de manera que el proceso puede agrupar operaciones que necesitan privilegios.<br />
<br />
La implementación de en Linux detenida a este punto, mientras que las Capacidades de POSIX requier la adición de conjuntos de capacidades para archivos también para reemplazar la marca SUID (al menos para ejecutables)<br />
<br />
=== Capability Overview ===<br />
Las lista de Capacidades de POSIX que se usan es larga, y se usan casi todos de los 32 bits disponibles. Si bien la lista detalla da de todas las capacidades se puede encontrar en <tt>/usr/include/linux/capability.h</tt> en la matoría de los sistemas Linux, se da aquí un resumen general de las capacidades importantes que se pueden encontrar.<br />
<br />
{|class="wikitablenowrap"<br />
|0 || CAP_CHOWN|| cambia el dueño y grupo del archivo.<br />
|-<br />
|5 || CAP_KILL|| envía una señal a un proceso con un identificador de usuario diferente existente o efectivo<br />
|-<br />
|6 || CAP_SETGID|| permite setgid(2), setgroups(2), y falsos gids en pase de credenciales de socket <br />
|-<br />
|7 || CAP_SETUID|| permite set*uid(2), y falsos uids en pase de credenciales<br />
|-<br />
|8 || CAP_SETPCAP|| transfiere/elimina cualquier capacidad en el conjunto permitido hacia/desde cualquier pid<br />
|-<br />
|9 || CAP_LINUX_IMMUTABLE|| permite la modificación de los atributos de archivo S_IMMUTABLE y S_APPEND <br />
|-<br />
|11 || CAP_NET_BROADCAST|| permite hacer broadcast y escuchar a múltiples direcciones<br />
|-<br />
|12 || CAP_NET_ADMIN|| permite la configuración de una interfaz, firewall de IP, enmascaramiento, cuantificación, depuración de socket, tablas de ruteo, conexión a cualquier dirección, entrar en modo promiscuo, multicasting,...<br />
|-<br />
|13 || CAP_NET_RAW|| permite el uso de sockets crudos y de paquetes<br />
|-<br />
|16 || CAP_SYS_MODULE|| inserta y saca módulos del kernel<br />
|-<br />
|18 || CAP_SYS_CHROOT|| permite chroot(2)<br />
|-<br />
|19 || CAP_SYS_PTRACE|| permite ptrace() de cualquier proceso<br />
|-<br />
|21 || CAP_SYS_ADMIN|| esta lista sería demasiado larga, basicamente permite hacer cualquier otra cosa, no mencionada en otra capacidad.<br />
|-<br />
|22 || CAP_SYS_BOOT|| permite reboot(2)<br />
|-<br />
|23 || CAP_SYS_NICE|| permite aumentar la prioridad<br />
|}<br />
<br />
[[Category:Documentation/es]]</div>Glennhttp://linux-vserver.org/Paper/esPaper/es2011-10-23T10:45:32Z<p>Glenn: + Category:Documentation</p>
<hr />
<div>{{Languages|Paper}}<br />
<br />
== Infraestructura Existente==<br />
Los recientes núcleos de Linux ya proveen muchas prestaciones de seguridad que son utilizadas por Linux-Vserver para hacer su trabajo. Especialmente características tales como el Sistema de Capacidades de Linux, Límite de Recursos, Atributos de archivos y el Cambio del Entorno Raíz. Las siguientes secciones darán una breve reseña acerca de cada una de estas.<br />
<br />
=== Sistema de Capacidades de Linux===<br />
En ciencias de la computación, una capacidad es un signo usado por un proceso para probar que tiene permitido realizar una operación sobre un objeto. El Sistema de Capacidades de Linux se basa en las "Capacidades Posix", un concepto ligeramente, diseñado para fraccionar el privilegio todo poderoso de root en un conjunto de de distintos privilegios.<br />
<br />
==== Capacidades de Linux ====<br />
Un proceso tiene tres conjuntos de mapas de bits llamadas capacidades hereditarios(I), permitidos(P), y efectivos(E). Cada capacidad se implementa como un bit de estos mapas de bits que están activado o desactivados.<br />
<br />
Cuando un proceso intenta hacer una operación privilegiada, el sistema operativo comprobará el bit apropiado en el conjunto efectivo de los procesos (en lugar de comprobar si el uid efectivo del proceso es 0 como se hace normalmente).<br />
<br />
Por ejemplo, cuando un proceso intenta configurar el reloj, el núcleo Linux comprobará que el proceso tiene el bit CAP_SYS_TIME (que es actualmente el bit 25) habilitado en su conjunto efectivo.<br />
<br />
El conjunto pemitido de los procesos indica las capacidades que el proceso puede usar. El proceso puede tener capacidades habilitadas en el conjunto permitido que no están en el conjunto efectivo.<br />
<br />
Esto indica que el proceso tiene temporalmente deshabilitado esta capacidad. Un proceso tiene permitido habilitar un bit en su conjunto permitido solamente si está disponible en el conjunto permitido. La distinción entre efectivo y permitido existe de manera que el proceso puede agrupar operaciones que necesitan privilegios.<br />
<br />
La implementación de en Linux detenida a este punto, mientras que las Capacidades de POSIX requier la adición de conjuntos de capacidades para archivos también para reemplazar la marca SUID (al menos para ejecutables)<br />
<br />
=== Capability Overview ===<br />
Las lista de Capacidades de POSIX que se usan es larga, y se usan casi todos de los 32 bits disponibles. Si bien la lista detalla da de todas las capacidades se puede encontrar en <tt>/usr/include/linux/capability.h</tt> en la matoría de los sistemas Linux, se da aquí un resumen general de las capacidades importantes que se pueden encontrar.<br />
<br />
{|class="wikitablenowrap"<br />
|0 || CAP_CHOWN|| cambia el dueño y grupo del archivo.<br />
|-<br />
|5 || CAP_KILL|| envía una señal a un proceso con un identificador de usuario diferente existente o efectivo<br />
|-<br />
|6 || CAP_SETGID|| permite setgid(2), setgroups(2), y falsos gids en pase de credenciales de socket <br />
|-<br />
|7 || CAP_SETUID|| permite set*uid(2), y falsos uids en pase de credenciales<br />
|-<br />
|8 || CAP_SETPCAP|| transfiere/elimina cualquier capacidad en el conjunto permitido hacia/desde cualquier pid<br />
|-<br />
|9 || CAP_LINUX_IMMUTABLE|| permite la modificación de los atributos de archivo S_IMMUTABLE y S_APPEND <br />
|-<br />
|11 || CAP_NET_BROADCAST|| permite hacer broadcast y escuchar a múltiples direcciones<br />
|-<br />
|12 || CAP_NET_ADMIN|| permite la configuración de una interfaz, firewall de IP, enmascaramiento, cuantificación, depuración de socket, tablas de ruteo, conexión a cualquier dirección, entrar en modo promiscuo, multicasting,...<br />
|-<br />
|13 || CAP_NET_RAW|| permite el uso de sockets crudos y de paquetes<br />
|-<br />
|16 || CAP_SYS_MODULE|| inserta y saca módulos del kernel<br />
|-<br />
|18 || CAP_SYS_CHROOT|| permite chroot(2)<br />
|-<br />
|19 || CAP_SYS_PTRACE|| permite ptrace() de cualquier proceso<br />
|-<br />
|21 || CAP_SYS_ADMIN|| esta lista sería demasiado larga, basicamente permite hacer cualquier otra cosa, no mencionada en otra capacidad.<br />
|-<br />
|22 || CAP_SYS_BOOT|| permite reboot(2)<br />
|-<br />
|23 || CAP_SYS_NICE|| permite aumentar la prioridad<br />
|}<br />
<br />
[[Category:Documentation]]</div>Glennhttp://linux-vserver.org/Category:DocumentationCategory:Documentation2011-10-23T10:44:52Z<p>Glenn: +{{Languages|:Category:Documentation}}</p>
<hr />
<div>{{Languages|:Category:Documentation}}<br />
<br />
[[Category:Categories]]</div>Glennhttp://linux-vserver.org/Category:Documentation/esCategory:Documentation/es2011-10-23T10:44:39Z<p>Glenn: corr</p>
<hr />
<div>{{Languages|:Category:Documentation}}<br />
<br />
[[Category:Categories]]</div>Glennhttp://linux-vserver.org/Category:Documentation/esCategory:Documentation/es2011-10-23T10:44:17Z<p>Glenn: new</p>
<hr />
<div>{{Languages|Paper}}<br />
<br />
[[Category:Categories]]</div>Glennhttp://linux-vserver.org/User_talk:BertlUser talk:Bertl2011-10-23T10:39:42Z<p>Glenn: +== Welcome_to_Linux-VServer.org ==</p>
<hr />
<div>== [[Welcome_to_Linux-VServer.org]] ==<br />
<br />
Hi Hollow and Bertl<br />
<br />
Could you please insert this into the page [[Welcome_to_Linux-VServer.org]]:<br />
<br />
At the top of the page (without nowiki-tags):<br />
* <nowiki>{{Languages|Overview}}</nowiki><br />
<br />
<br />
And at the top of the page:<br />
<br />
*<nowiki>[[Category:Community| ]]</nowiki><br />
*<nowiki>[[Category:Categories| ]]</nowiki><br />
<br />
--[[User:Glenn|Glenn]] 10:39, 23 October 2011 (UTC)</div>Glennhttp://linux-vserver.org/User_talk:HollowUser talk:Hollow2011-10-23T10:39:19Z<p>Glenn: + == Welcome_to_Linux-VServer.org ==</p>
<hr />
<div>Haha, I guess that I'm not the only one deleting spam from this Wiki anymore :P --[[User:Daniel15|Daniel15]] 13:22, 20 October 2006 (CEST)<br />
<br />
== Migrated pages ==<br />
<br />
I have migrated these pages from the old to the new wiki:<br />
* [[Namespaces/fr]]<br />
* [[Namespaces]]<br />
* [[Installation on Slackware]]<br />
* [[Vservers and X]]<br />
--[[User:Jze|Jze]] 13:47, 27 March 2009 (CET)<br />
<br />
== Syntax highlighting ==<br />
It would be nice if you could install this extension in the VServer-Wiki: http://www.mediawiki.org/wiki/Extension:SyntaxHighlight_GeSHi<br />
<br />
Scripts would be much better readable with very little effort. --[[User:Jze|Jze]] 13:47, 27 March 2009 (CET)<br />
<br />
== SVG support ==<br />
Is it possible to activate SVG support for this wiki? I have redrawn the "computer-memory-pyramid" figure from the old wiki. Visualization is always helpfull and much easier to editable with vector graphics. --[[User:Jze|Jze]] 13:47, 27 March 2009 (CET)<br />
<br />
== Extension:ParserFunctions ==<br />
<br />
Can you also install the Extension:ParserFunctions?<br />
http://www.mediawiki.org/wiki/Extension:ParserFunctions<br />
<br />
It can be used to generate language selection boxes like this [[Template:Language]] with the existing languages automatically shown. --[[User:Jze|Jze]] 14:14, 27 March 2009 (CET)<br />
<br />
== [[Welcome_to_Linux-VServer.org]] ==<br />
<br />
Hi Hollow and Bertl<br />
<br />
Could you please insert this into the page [[Welcome_to_Linux-VServer.org]]:<br />
<br />
At the top of the page (without nowiki-tags):<br />
* <nowiki>{{Languages|Overview}}</nowiki><br />
<br />
<br />
And at the top of the page:<br />
<br />
*<nowiki>[[Category:Community| ]]</nowiki><br />
*<nowiki>[[Category:Categories| ]]</nowiki><br />
<br />
--[[User:Glenn|Glenn]] 10:39, 23 October 2011 (UTC)</div>Glennhttp://linux-vserver.org/Feature_MatrixFeature Matrix2011-10-22T08:06:00Z<p>Glenn: -cat</p>
<hr />
<div>=== Feature Comparison ===<br />
<br />
The following table ''tries'' to give an overview of features available in different releases.<br />
(it would be nice if someone would care to edit this page and make each feature a click able link to a new page that gave a full explination about that it meant).<br />
<br />
{| class="wikitablenowrap"<br />
! Feature<br />
! 1.00<br />
! 1.20<br />
! 1.2.10<br />
! 1.3.8<br />
! 0.09<br />
! 1.9.0<br />
! 1.9.2<br />
! 2.0<br />
! 2.1 <br />
! 2.2<br />
! 2.3<br />
|-<br />
! Legacy Kernel API (vs1.2x)<br />
| yes<br />
| yes<br />
| yes<br />
| part<br />
| part<br />
| part<br />
| part<br />
| part<br />
| part <br />
| part<br />
| -<br />
|-<br />
! Legacy Proc Filesystem<br />
| yes<br />
| yes<br />
| yes<br />
| part<br />
| part<br />
| part<br />
| part<br />
| part<br />
| part<br />
| part<br />
| -<br />
|-<br />
! Immutable Link Invert<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
|-<br />
! Initpid and Fakeinit<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
|-<br />
! Syscall Command Switch<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
|-<br />
! Syscall vkill commands<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
|-<br />
! Syscall rlimit commands<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
|-<br />
! Syscall ctx_wait support<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
|-<br />
! Syscall iattr commands<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
|-<br />
! Syscall namespace commands<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
|-<br />
! Syscall context flags<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
| yes<br />
| yes<br />
|-<br />
! Syscall context caps<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! Syscall scheduler tuning<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! Syscall 32bit compat<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes <br />
| yes<br />
| yes<br />
|-<br />
! Next gen. Proc Filesystem<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! Chroot Barrier Flag<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! Proc Security Flags<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! Userspace Reboot Helper<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! Startup/Shutdown Helper<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! VRoot Device<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! Advanced IP Selection<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! Advanced uts_name config<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! Fake Memory Display<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! Hard CPU limits<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! Context File Tagging<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! Context ID Propagation<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
|-<br />
! NFS based File Tagging<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
|-<br />
! Per Context Disk Limits<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! Network Context Support<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! Socket Accounting<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! Advanced Sysctl Debug System<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
|-<br />
! Extended proc/devpts Security<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! Flag: Pause Context<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! Flag: Hide proc/mounts<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! Capability Masking<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
|-<br />
! CCap: Secure Mount<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
|-<br />
! CCap: Change host/domainname<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! CCap: Modify rlimits<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! CCap: Raw ICMP for Ping<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! Bind Mount Extensions<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! Copy on Write Link Breaking<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes <br />
|-<br />
! Quota Hashes<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| -<br />
| yes<br />
|-<br />
! Persistent Context Support<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| yes<br />
| yes<br />
|-<br />
! Device mapping and secure mknod(2)<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
| -<br />
| yes<br />
|-<br />
! IPv6 support<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
|-<br />
! Per-guest isolated loopback address<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| -<br />
| yes<br />
|}<br />
<br />
[[Category:Documentation| ]]<br />
[[Category:Community]]</div>Glennhttp://linux-vserver.org/PaperPaper2011-10-22T08:05:24Z<p>Glenn: catchg</p>
<hr />
<div>{{Languages|Paper}}<br />
<br />
== Abstract ==<br />
<br />
A soft partitioning concept based on ''Security Contexts'' which permits the creation of many independent Virtual Private Servers (VPS) that run simultaneously on a single physical server at full speed, efficiently sharing hardware resources.<br />
<br />
A VPS provides an almost identical operating environment as a conventional Linux Server. All services, such as ssh, mail, Web and databases, can be started on such a VPS, without (or in special cases with only minimal) modification, just like on any real server.<br />
<br />
Each virtual server has its own user account database and root password and is isolated from other virtual servers, except for the fact that they share the same hardware resources.<br />
<br />
== Introduction ==<br />
<br />
Over the years, computers have become sufficiently powerful to use virtualization to create the illusion of many smaller virtual machines, each running a separate operating system instance.<br />
<br />
There are several kinds of Virtual Machines (VMs) which provide similar features, but differ in the degree of abstraction and the methods used for virtualization.<br />
<br />
Most of them accomplish what they do by ''emulating'' some real or fictional hardware, which in turn requires ''real'' resources from the Host (the machine running the VMs). This approach, used by most System Emulators (like QEMU, Bochs, ...), allows the emulator to run an arbitrary Guest Operating System, even for a different Architecture (CPU and Hardware). No modifications need to be made to the Guest OS because it isn't aware of the fact that it isn't running on real hardware.<br />
<br />
Some System Emulators require small modifications or specialized drivers to be added to Host or Guest to improve performance and minimize the overhead required for the hardware emulation. Although this significantly improves efficiency, there are still large amounts of resources being wasted in caches and mediation between Guest and Host (examples for this approach are UML and Xen).<br />
<br />
But suppose you do not want to run many different Operating Systems simultaneously on a single box? Most applications running on a server do not require hardware access or kernel level code, and could easily share a machine with others, if they could be separated and secured...<br />
<br />
== The Concept ==<br />
<br />
At a basic level, a Linux Server consists of three building blocks: Hardware, Kernel and Applications. The Hardware usually depends on the provider or system maintainer, and, while it has a big influence on the overall performance, it cannot be changed that easily, and will likely differ from one setup to another.<br />
<br />
The main purpose of the Kernel is to build an abstraction layer on top of the hardware to allow processes (Applications) to work with and operate on resources (Data) without knowing the details of the underlying hardware. Ideally, those processes would be completely hardware agnostic, by being written in an interpreted language and therefore not requiring any hardware-specific knowledge.<br />
<br />
Given that a system has enough resources to drive ten times the number of applications a single Linux server would usually require, why not put ten servers on that box, which will then share the available resources in an efficient manner?<br />
<br />
Most server applications (e.g. httpd) will assume that it is the only application providing a particular service, and usually will also assume a certain filesystem layout and environment. This dictates that similar or identical services running on the same physical server, but for example, only differing in their addresses, have to be coordinated. This typically requires a great deal of administrative work which can lead to reduced system stability and security.<br />
<br />
The basic concept of the Linux-VServer solution is to separate the user-space environment into distinct units (sometimes called Virtual Private Servers) in such a way that each VPS looks and feels like a real server to the processes contained within.<br />
<br />
Although different Linux Distributions use (sometimes heavily) patched kernels to provide special support for unusual hardware or extra functionality, most Linux Distributions are not tied to a special kernel.<br />
<br />
Linux-VServer uses this fact to allow several distributions, to be run simultaneously on a single, shared kernel, without direct access to the hardware, and share the resources in a very efficient way.<br />
<br />
== Existing Infrastructure ==<br />
<br />
Recent Linux Kernels already provide many security features that are utilized by Linux-VServer to do its work. Especially features such as the Linux Capability System, Resource Limits, File Attributes and the Change Root Environment. The following sections will give a short overview about each of these.<br />
<br />
=== Linux Capability System ===<br />
<br />
In computer science, a capability is a token used by a process to prove that it is allowed to perform an operation on an object. The Linux Capability System is based on "POSIX Capabilities", a somewhat different concept, designed to split up the all powerful root privilege into a set of distinct privileges.<br />
<br />
==== POSIX Capabilities ====<br />
<br />
A process has three sets of bitmaps called the inheritable(I), permitted(P), and effective(E) capabilities. Each capability is implemented as a bit in each of these bitmaps that is either set or unset.<br />
<br />
When a process tries to do a privileged operation, the operating system will check the appropriate bit in the effective set of the process (instead of checking whether the effective uid of the process is 0 as is normally done).<br />
<br />
For example, when a process tries to set the clock, the Linux kernel will check that the process has the CAP_SYS_TIME bit (which is currently bit 25) set in its effective set.<br />
<br />
The permitted set of the process indicates the capabilities the process can use. The process can have capabilities set in the permitted set that are not in the effective set.<br />
<br />
This indicates that the process has temporarily disabled this capability. A process is allowed to set a bit in its effective set only if it is available in the permitted set. The distinction between effective and permitted exists so that processes can "bracket" operations that need privilege.<br />
<br />
The inheritable capabilities are the capabilities of the current process that should be inherited by a program executed by the current process. The permitted set of a process is masked against the inheritable set during exec(). Nothing special happens during fork() or clone(). Child processes and threads are given an exact copy of the capabilities of the parent process.<br />
<br />
The implementation in Linux stopped at this point, whereas POSIX Capabilities[U5] requires the addition of capability sets to files too, to replace the SUID flag (at least for executables). The pending Linux 2.6.24 kernel supports file POSIX capabilities. (See Serge Hallyn's [http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b53767719b6cd8789392ea3e7e2eb7b8906898f0 git commit] of Wed, 17 Oct 2007.) One userspace tool capable of changing file capabilities is the 2.X version of Andrew Morgan's [http://kernel.org/pub/linux/libs/security/linux-privs/ libcap] library and programs.<br />
<br />
==== Capability Overview ====<br />
<br />
The list of POSIX Capabilities used with Linux is long, and the 32 available bits are almost used up. While the detailed list of all capabilities can be found in /usr/include/linux/capability.h on most Linux systems, an overview of important capabilities is given here.<br />
<br />
{| class="wikitablenowrap"<br />
! [0] CAP_CHOWN<br />
| change file ownership and group.<br />
|-<br />
! [5] CAP_KILL<br />
| send a signal to a process with a different real or effective user ID<br />
|-<br />
! [6] CAP_SETGID<br />
| permit setgid(2), setgroups(2), and forged gids on socket credentials passing<br />
|-<br />
! [7] CAP_SETUID<br />
| permit set*uid(2), and forged uids on socket credentials passing<br />
|-<br />
! [8] CAP_SETPCAP<br />
| transfer/remove any capability in permitted set to/from any pid<br />
|-<br />
! [9] CAP_LINUX_IMMUTABLE<br />
| allow modification of S_IMMUTABLE and S_APPEND file attributes<br />
|-<br />
! [11] CAP_NET_BROADCAST<br />
| permit broadcasting and listening to multicast<br />
|-<br />
! [12] CAP_NET_ADMIN<br />
| permit interface configuration, IP firewall, masquerading, accounting, socket debugging, routing tables, bind to any address, enter promiscuous mode, multicasting, ...<br />
|-<br />
! [13] CAP_NET_RAW<br />
| permit usage of RAW and PACKET sockets<br />
|-<br />
! [16] CAP_SYS_MODULE<br />
| insert and remove kernel modules<br />
|-<br />
! [18] CAP_SYS_CHROOT<br />
| permit chroot(2)<br />
|-<br />
! [19] CAP_SYS_PTRACE<br />
| permit ptrace() of any process<br />
|-<br />
! [21] CAP_SYS_ADMIN<br />
| this list would be too long, it basically allows to do everything else, not mentioned in another capability.<br />
|-<br />
! [22] CAP_SYS_BOOT<br />
| permit reboot(2)<br />
|-<br />
! [23] CAP_SYS_NICE<br />
| allow raising priority and setting priority on other processes, modify scheduling<br />
|-<br />
! [24] CAP_SYS_RESOURCE<br />
| override resource limits, quota, reserved space on fs, ...<br />
|-<br />
! [27] CAP_MKNOD<br />
| permit the privileged aspects of mknod(2)<br />
|}<br />
<br />
=== Resource Limits ===<br />
<br />
Resources for each process can be limited by specifying a Resource Limit. Similar to the Linux Capabilities, there are two different limits, a Soft Limit and a Hard Limit.<br />
<br />
The soft limit is the value that the kernel enforces for the corresponding resource. The hard limit acts as a ceiling for the soft limit: an unprivileged process may only set its soft limit to a value in the range from zero up to the hard limit, and (irreversibly) lower its hard limit. A privileged process may make arbitrary changes to either limit value, as long as the soft limit stays below the hard limit.<br />
<br />
==== Limit-able Resource Overview ====<br />
<br />
The list of all defined resource limits can be found in /usr/include/asm/resource.h on most Linux systems, an overview of relevant resource limits is given here.<br />
<br />
{| class="wikitablenowrap"<br />
|-<br />
! [0] RLIMIT_CPU<br />
| CPU time in seconds. process is sent a SIGXCPU signal after reaching the soft limit, and SIGKILL on hard limit.<br />
|-<br />
! [4] RLIMIT_CORE<br />
| maximum size of core files generated<br />
|-<br />
! [5] RLIMIT_RSS<br />
| number of pages the process's resident set can consume (the number of virtual pages resident in RAM)<br />
|-<br />
! [6] RLIMIT_NPROC<br />
| The maximum number of processes that can be created for the real user ID of the calling process.<br />
|-<br />
! [7] RLIMIT_NOFILE<br />
| Specifies a value one greater than the maximum file descriptor number that can be opened by this process.<br />
|-<br />
! [8] RLIMIT_MEMLOCK<br />
| The maximum number of virtual memory pages that may be locked into RAM using mlock() and mlockall().<br />
|-<br />
! [9] RLIMIT_AS<br />
| The maximum number of virtual memory pages available to the process (address space limit). \<br />
|}<br />
<br />
=== File Attributes ===<br />
<br />
Originally, this feature was only available with ext2, but now all major filesystems implement a basic set of File Attributes that permit certain properties to be changed. Here again is a short overview of the possible attributes, and what they mean.<br />
<br />
{| class="wikitablenowrap"<br />
! <br />
! Macro Name<br />
! Meaning<br />
|-<br />
! s <br />
! SECRM<br />
| When a file with this attribute set is deleted, its blocks are zeroed and written back to the disk.<br />
|-<br />
! u <br />
! UNRM<br />
| When a file with this attribute set is deleted, its contents are saved.<br />
|-<br />
! c <br />
! COMPR<br />
| Files marked with this attribute are automatically compressed on write and uncompressed on read. (not implemented yet)<br />
|-<br />
! i <br />
! IMMUTABLE<br />
| A file with this attribute cannot be modified: it cannot be deleted or renamed, no link can be created to this file and no data can be written to the file.<br />
|-<br />
! a <br />
! APPEND<br />
| Files with this attribute set can only be opened in append mode for writing.<br />
|-<br />
! d <br />
! NODUMP<br />
| If this flag is set, the file is not candidate for backup with the dump utility.<br />
|-<br />
! S <br />
! SYNC<br />
| Updates to the file contents are done synchronously.<br />
|-<br />
! A <br />
! NOATIME<br />
| Prevents updating the atime record on files when they are accessed or modified.<br />
|-<br />
! t <br />
! NOTAIL<br />
| A file with the t attribute will not have a partial block fragment at the end of the file merged with other files.<br />
|-<br />
! D <br />
! DIRSYNC<br />
| Changes to a directory having this attribute set will be done synchronously.<br />
|}<br />
<br />
The first column in the above table denotes command line options one might supply to ''lsattr'' respectively ''chattr''. The below screedump gives a notion about what we are talking:<br />
<pre><br />
max@pc1:~$ cd /tmp/<br />
max@pc1:/tmp$ touch my_file<br />
max@pc1:/tmp$ lsattr my_file<br />
------------------ my_file<br />
max@pc1:/tmp$ chattr +a my_file<br />
chattr: Operation not permitted while setting flags on my_file<br />
max@pc1:/tmp$ su<br />
Password:<br />
pc1:/tmp# chattr +a my_file && lsattr my_file<br />
-----a------------ my_file<br />
pc1:/tmp# exit<br />
exit<br />
max@pc1:/tmp$<br />
</pre><br />
<br />
As you might have noticed, one needs to gain root permissions in the upper showcase (the underlying file system was ext3). For more information just issue ''man 1 chattr'' in your command line interface.<br />
<br />
<br />
Information regarding file attributes can be found in the kernel source code. Every file system uses a subset of all known attributes (which are used depends on the file system). <br />
<br />
One thing can be said for sure -- the file attributes listed in the kernel source code are defined -- those are not listed are not defined and in turn can not be used for a particular file system (e.g. ext3 (Extended File System version 3)). However, many of those file attributes defined and understood by the kernel have no effect. Most file systems define those flags in a specific (specific for a particular file system) header file found within the kernel source tree. They also define a so called '''User Modifiable Mask''' (those are the flags the user can change with the ''ioctls'').<br />
<br />
Those flags have partially different meaning depending on the node type (i.e. dir, inode, fifo, pipe, device) and it is not trivial to say if a filesystem makes use of any user modifiable flag -- things like immutable are easy to verify (from user space) but how to verify e.g. NOTAIL from user space? Usually only source code review will show if it is implemented and used.<br />
<br />
For example, if that didn't change, the COMPR is defined, and well understood by ext2/3 but there is no implementation there, i.e. nothing is compressed.<br />
<br />
=== The chroot(1) Command ===<br />
<br />
chroot allows you to run a command with a different directory acting as the root directory. This means that all filesystem lookups are done with '/' referring to the substitute root directory and not to the original one.<br />
<br />
While the Linux chroot implementation isn't very secure, it increases the isolation of processes with regards to the filesystem, and, if used properly, can create a filesystem "jail" for a single process or a restricted user, daemon or service.<br />
<br />
== Required Modifications ==<br />
<br />
This chapter will describe the essential Kernel modifications to implement something like Linux-VServer.<br />
<br />
=== Context Separation ===<br />
<br />
The separation mentioned in the Concepts section requires some modifications to the kernel to allow for the notion of Contexts.<br />
The purpose of this "Context" is to hide all processes outside of its scope, and prohibit any unwanted interaction between a process inside the context and a process belonging to another context.<br />
<br />
This separation requires the extension of some existing data structures in order for them to become aware of contexts and to differentiate between identical uids used in different virtual servers.<br />
<br />
It also requires the definition of a default context that is used when the host system is booted, and to work around the issues resulting from some false assumptions made by some user-space tools (like pstree) that the init process has to exist and to be running under id '1'.<br />
<br />
To simplify administration, the Host Context isn't treated any differently than any other context as far as process isolation is concerned. To allow for process overview, a special Spectator context has been defined to peek at all processes at once.<br />
<br />
=== Network Separation ===<br />
<br />
While the Context Separation is sufficient to isolate groups of processes, a different kind of separation, or rather a limitation, is required to confine processes to a subset of available network addresses.<br />
<br />
Several issues have to be considered when doing so; for example, the fact that bindings to special addresses like IPADDR_ANY or the local host address have to be handled in a very special way.<br />
<br />
Currently, Linux-VServer doesn't make use of virtual network devices (and maybe never will) to minimize the resulting overhead. Therefore socket binding and packet transmission have been adjusted.<br />
<br />
=== The Chroot Barrier ===<br />
<br />
One major problem of the chroot() system used in Linux lies within the fact that this information is volatile, and will be changed on the next chroot() Syscall.<br />
<br />
One simple method to escape from a chroot-ed environment is as follows: First, create or open a file and retain the file-descriptor, then chroot into a subdirectory at equal or lower level with regards to the file. This causes the root to be moved down in the filesystem. Next, use fchdir() on the file-descriptor to escape from that new root. This will consequently escape from the old root as well, as this was lost in the last chroot() Syscall.<br />
<br />
While early Linux-VServer versions tried to fix this by "funny" methods, recent versions use a special marking, known as the Chroot Barrier, on the parent directory of each VPS to prevent unauthorized modification and escape from confinement.<br />
<br />
=== Upper Bound for Caps ===<br />
<br />
Because the current Linux Capability system does not implement the filesystem related portions of POSIX Capabilities which would make setuid and setgid executables secure, and because it is much safer to have a secure upper bound for all processes within a context, an additional per-context capability mask has been added to limit all processes belonging to that context to this mask.<br />
<br />
The meaning of the individual caps (bits) of the capability bound mask is exactly the same as with the permitted capability set.<br />
<br />
=== Resource Isolation ===<br />
<br />
Most resources are somewhat shared among the different contexts. Some require more additional isolation than others, either to avoid security issues or to allow for improved accounting.<br />
<br />
Those resources are:<br />
<br />
* shared memory, IPC<br />
* user and process IDs<br />
* file xid tagging<br />
* Unix ptys<br />
* sockets<br />
<br />
=== Filesystem XID Tagging ===<br />
<br />
Although it can be disabled completely, this modification is required for more robust filesystem level security and context isolation. It is also mandatory for Context Disk Limits and Per Context Quota Support on a shared partition.<br />
<br />
The concept of adding a context id (xid) to each file to make the context ownership persistent sounds simple, but the actual implementation is non-trivial - mainly because adding this information either requires a change to the on disk representation of the filesystem or the application of some tricks.<br />
<br />
One non-intrusive approach to avoid modification of the underlying filesystem is to use the upper bits of existing fields, like those for UID and GID to store the additional XID.<br />
<br />
Once context information is available for each inode, it is a logical step to extend the access controls to check against context too.<br />
Currently all inode access restrictions have been extended to check for the context id, with special exceptions for the Host Context and the Spectator Context.<br />
<br />
Untagged files belong to the Host Context and are silently treated as if they belong to the current context, which is required for Unification. If such a file is modified from inside a context, it silently migrates to the new one, changing its xid.<br />
<br />
The following Tagging Methods are implemented:<br />
{| class="wikitablenowrap"<br />
! UID32/GID32 or EXTERNAL<br />
| This format uses currently unused space within the disk inode to store the context information. As of now, this is only defined for ext2/ext3 but will be also defined for xfs, reiserfs, and jfs as soon as possible. Advantage: Full 32bit uid/gid values.<br />
|-<br />
! UID32/GID16<br />
| This format uses the upper half of the group id to store the context information. This is done transparently, except if the format is changed without prior file conversion. Advantage: works on all 32bit U/GID FSs. Drawback: GID is reduced to 16 bits.<br />
|-<br />
! UID24/GID24<br />
| This format uses the upper quarter of user and group id to store the context information, again transparently. This allows for about 16 million user and group ids, which should suffice for the majority of all applications. Advantage: works on all 32bit U/GID FSs. Drawback: UID and GID are reduced to 24 bits.<br />
|}<br />
<br />
== Additional Modifications ==<br />
<br />
In addition to the bare minimum, there are a number of modifications that are not mandatory, but have proven extremely useful over time.<br />
<br />
=== Context Flags ===<br />
<br />
It was very soon discovered that some features require a flag, a kind of switch to turn them on and off separately for each Linux-VServer, so a simple flag-word was added.<br />
<br />
This flag-word supports quite a number of flags, a flag-word mask, which allows to tell what flags are available, and a special trigger mechanism, providing one-time flags, set on startup, that can only be cleared once, usually causing a special action or event.<br />
<br />
Here is a list of planned and mostly implemented Context Flags, available in the development branch of Linux-VServer:<br />
<br />
{| class="wikitablenowrap"<br />
! [0] VXF_INFO_LOCK<br />
| (legacy, obsoleted)<br />
|-<br />
! [1] VXF_INFO_SCHED<br />
| schedule all processes in a context as if they where one. (legacy, obsoleted)<br />
|-<br />
! [2] VXF_INFO_NPROC<br />
| limit the number of processes in a context to the initial NPROC value. (legacy, obsoleted)<br />
|-<br />
! [3] VXF_INFO_PRIVATE<br />
| do not allow to join this context from outside. (legacy)<br />
|-<br />
! [4] VXF_INFO_INIT<br />
| show the init process with pid '1' (legacy)<br />
|-<br />
! [5] VXF_INFO_HIDE<br />
| (legacy, obsoleted)<br />
|-<br />
! [6] VXF_INFO_ULIMIT<br />
| (legacy, obsoleted)<br />
|-<br />
! [7] VXF_INFO_NSPACE<br />
| (legacy, obsoleted)<br />
|-<br />
! [8] VXF_SCHED_HARD<br />
| activate the Hard CPU scheduling<br />
|-<br />
! [9] VXF_SCHED_PRIO<br />
| use the context token bucket for calculating the process priorities<br />
|-<br />
! [10] VXF_SCHED_PAUSE<br />
| put all processes in this context on the hold queue, not scheduling them any longer<br />
|-<br />
! [16] VXF_VIRT_MEM<br />
| virtualize the memory information so that the VM and RSS limits are used for meminfo and friends<br />
|-<br />
! [17] VXF_VIRT_UPTIME<br />
| virtualize the uptime, beginning with the time of context creation<br />
|-<br />
! [18] VXF_VIRT_CPU<br />
|<br />
|-<br />
! [24] VXF_HIDE_MOUNT<br />
| show empty proc/{pid}/mounts<br />
|-<br />
! [25] VXF_HIDE_NETIF<br />
| hide network interfaces and addresses not permitted by the network context<br />
|}<br />
<br />
=== Context Capabilities ===<br />
<br />
As the Linux Capabilities have almost reached the maximum number that is possible without heavy modifications to the kernel, it was a natural step to add a context-specific capability system.<br />
<br />
The Linux-VServer context capability set acts as a mechanism to fine tune existing Linux capabilities. It is not visible to the processes within a context, as they would not know how to modify or verify it.<br />
<br />
In general there are two ways to use those capabilities:<br />
<br />
* Require one or a number of context capabilities to be set in addition to a given Linux capability, each one controlling a distinct part of the functionality.For example the CAP_NET_ADMIN could be split into RAW and PACKET sockets, so you could take away each of them separately by not providing the required context capability.<br />
<br />
* Consider the context capability sufficient for a specified functionality, even if the Linux Capability says something different.For example mount() requires CAP_SYS_ADMIN which adds a dozen other things we do not want, so we define a CCAP_MOUNT to allow mounts for certain contexts.<br />
The difference between the Context Flags and the Context Caps is more an abstract logical separation than a functional one, because they are handled very similarly.<br />
<br />
Again, a list of the Context Capabilities and their purpose:<br />
<br />
<br />
{| class="wikitablenowrap"<br />
! [0] VXC_SET_UTSNAME<br />
| allow the context to change the host and domain name with the appropriate kernel Syscall<br />
|-<br />
! [1] VXC_SET_RLIMIT<br />
| allow the context to modify the resource limits (within the vserver limits).<br />
|-<br />
! [8] VXC_RAW_ICMP<br />
| allow raw icmp packets in a secure way (this makes ping work from inside)<br />
|-<br />
! [16] VXC_SECURE_MOUNT<br />
| permit secure mounts, which at the moment means that the nodev mount option is added.<br />
|}<br />
<br />
=== Context Accounting ===<br />
<br />
Some properties of a context are useful to the admin, either for keeping an overview of the resources, to get a feeling for the capacity of the host, or for billing them in some way to a customer.<br />
<br />
There are two different kinds of accountable properties, those having a current value which represents the state of the system (for example the speed of a vehicle), and those which monotonically increase over time (like the mileage).<br />
<br />
Most of the state type of properties also qualify for applying some limits, so they are handled specially. this is described in more detail in the following section.<br />
<br />
Good candidates for Context Accounting are:<br />
<br />
* Amount of CPU Time spent<br />
* Number of Forks done<br />
* Socket Messages by Type<br />
* Network Packets Transmitted and Received<br />
<br />
=== Context Limits ===<br />
<br />
Most properties related to system resources, might it be the memory consumption, the number of processes or file-handles, or the current network bandwidth, qualify for imposing limits on them.<br />
<br />
To provide a general framework for all kinds of limits, Context Limits allow the configuration of three different values for each limit-able resource: the minimum, a soft limit and a hard limit (maximum).<br />
<br />
At the time this is written, only the hard limits are supported and not all of them are actually enforced, but here is a list of current and planned Context Limits:<br />
<br />
* process limits<br />
* scheduler limits<br />
* memory limits<br />
* per-context disk limits<br />
* per-context user/group quota<br />
<br />
Additionally the context limit system keeps track of observed maxima and resource limit hits, to provide some feedback for the administrator.<br />
<br />
=== Virtualization ===<br />
<br />
One major difference between the Linux-VServer approach and Virtual Machines is that you do not have the virtualization part as a side-effect, so you have to do that by hand where it makes sense.<br />
<br />
For example, a Virtual Machine does not need to think about uptime, because naturally the running OS was started somewhere in the past and will not have any problem to tell the time it thinks it began running.<br />
<br />
A context can also store the time when it was created, but that will be different from the systems uptime, so in addition, there has to be some function, which adjusts the values passed from kernel to user-space depending on the context the process belongs to.<br />
<br />
This is what for Linux-VServer is known as Virtualization (actually it's more faking some values passed to and from the kernel to make the processes think that they are on a different machine).<br />
<br />
Currently modified for the purpose of Virtualization are:<br />
<br />
* System Uptime<br />
* Host and Domain Name<br />
* Machine Type and Kernel Version<br />
* Context Memory Availability<br />
* Context Disk Space<br />
<br />
=== Improved Security ===<br />
<br />
Proc-FS Security provides a mechanism to protect dynamic entries in the proc filesystem from being seen in every context.<br />
The system consists of three flags for each Proc-FS entry: Admin, Watch and Hide.<br />
<br />
The Hide flag enables or disables the entire feature, so any combination with the Hide flag cleared will mean total visibility.<br />
The Admin and Watch flags determine where the hidden entry remains visible; so for example if Admin and Hidden are set, the Host Context will be the only one able to see this specific entry.<br />
<br />
=== Kernel Helper ===<br />
<br />
For some purposes, it makes sense to have an user-space tool to act on behalf of the kernel, when a process inside a context requests something usually available on a real server, but naturally not available inside a context.<br />
<br />
The best, and currently only example for this is the Reboot Helper, which handles the reboot() system call, invoked from inside a context on behalf of the Kernel. It is executed, in Host side user-space to take appropriate actions - either reboot or just shutdown (halt) the specified context.<br />
<br />
While the helper is designed to be flexible and handle different things in a similar way there are no other users of this helper at the moment. It might be replaced by an event interface in near future.<br />
<br />
== Features and Bonus Material ==<br />
<br />
=== Unification ===<br />
<br />
Because one of the central objectives for Linux-VServer is to reduce the overall resource usage wherever possible, a truly great idea was born to share files between different contexts without interfering with the usual administrative tasks or reducing the level of security created by the isolation.<br />
<br />
Files common to more than one context, which are not very likely going to change, like libraries or binaries, can be hard linked on a shared filesystem, thus reducing the amount of disk space, inode caches, and even memory mappings for shared libraries.<br />
<br />
The only drawback is that without additional measures, a malicious context would be able to deliberately or accidentally destroy or modify such shared files, which in turn would harm the other contexts.<br />
<br />
One step is to make the shared files immutable by using the Immutable File Attribute (and removing the Linux Capability required to modify this attribute). However an additional attribute is required to allow removal of such immutable shared files, to allow for updates of libraries or executables from inside a context.<br />
<br />
Such hard linked, immutable but unlink-able files belonging to more than one context are called unified and the process of finding common files and preparing them in this way is called Unification.<br />
<br />
The reason for doing this is reduced resource consumption, not simplified administration. While a typical Linux Server install will consume about 500MB of disk space, 10 unified servers will only need about 700MB and as a bonus use less memory for caching.<br />
<br />
=== Private Namespaces ===<br />
<br />
A recent addition to the Linux-VServer branch was the introduction of Private Namespaces. This uses the already existing Virtual Filesystem Layer of the Linux kernel to create a separate view of the filesystem for the processes belonging to a context.<br />
<br />
The major advantage over the shared namespace used by default is that any modifications to the namespace layout (like mounts) do not affect other contexts, not even the Host Context.<br />
<br />
Obviously the drawback of that approach is that entering such a Private Namespace isn't as trivial as changing the root directory, but with proper kernel support this will completely replace the chroot() in the future.<br />
<br />
=== The Linux-VServer Proc-FS ===<br />
<br />
A structured, dynamically generated subtree of the well-known Proc-FS - actually two of them - has been created to allow for inspecting the different values of Security and Network Contexts.<br />
<br />
<pre><br />
/proc/virtual<br />
.../info<br />
<br />
/proc/virtual/<pid><br />
.../info<br />
.../status<br />
.../sched<br />
.../cvirt<br />
.../cacct<br />
.../limit<br />
</pre><br />
<br />
=== Token Bucket Extensions ===<br />
<br />
While the basic idea of Linux-VServer is a peaceful coexistence of all contexts, sharing the common resources in a respectful way, it is sometimes useful to control the resource distribution for resource hungry processes.<br />
<br />
The basic principle of a Token Bucket is not very new. It is given here as an example for the Hard CPU Limit. The same principle also applies to scheduler priorities, network bandwidth limitation and resource control in general.<br />
<br />
The Hard CPU Limit uses this mechanism in the following way: consider a bucket of a certain size S which is filled with a specified amount of tokens R every interval T, until the bucket is "full" - excess tokens are spilled. At each timer tick, a running process consumes exactly one token from the bucket, unless the bucket is empty, in which case the process is put on a hold queue until the bucket has been refilled with a minimum M of tokens. The process is then rescheduled.<br />
<br />
A major advantage of a Token Bucket is that a certain amount of tokens can be accumulated in times of quiescence, which later can be used to burst when resources are required.<br />
<br />
Where a per-process Token Bucket would allow for a CPU resource limitation of a single process, a Context Token Bucket allows to control the CPU usage of all confined processes.<br />
<br />
Another approach, which is also implemented, is to use the current fill level of the bucket to adjust the process priority, thus reducing the priority of processes belonging to excessive contexts.<br />
<br />
=== Context Disk Limits ===<br />
<br />
This Feature requires the use of XID Tagged Files, and allows for independent Disk Limits for different contexts on a shared partition.<br />
The number of inodes and blocks for each filesystem is accounted, if an XID-Hash was added for the Context-Filesystem combo.<br />
<br />
Those values, including current usage, maximum and reserved space, will be shown for filesystem queries, creating the illusion that the shared filesystem has a different usage and size, for each context.<br />
<br />
=== Per-Context Quota ===<br />
<br />
Similar to the Context Disk Limits, Per-Context Quota uses separate quota hashes for different Contexts on a shared filesystem. This is not required to allow for Linux-VServer quota on separate partitions.<br />
<br />
=== The VRoot Proxy Device ===<br />
<br />
Quota operations (ioctls) require some access to the block device, which for security reasons is not available inside a VPS.<br />
<br />
=== Stealth ===<br />
<br />
For some applications, for example the preparation of a honey-pot or an especially realistic imitation of a real server for educational purposes, it can make sense to make the context indistinguishable from a real server.<br />
<br />
However, since other freely available alternatives like QEMU or UML are much better at this, and require much less effort, this is not a central issue in Linux-VServer development.<br />
<br />
== Linux-VServer Security ==<br />
<br />
Now that we know what the Linux-VServer framework provides and how some features work, let's have a word on security, because you should not rely on the framework to be secure per definition. Instead, you should exactly know what you are doing.<br />
<br />
=== Secure Capabilities ===<br />
<br />
Currently the following Linux Capabilities are considered secure for VPS use. If others are added, it will probably open some security hole.<br />
<br />
* CAP_CHOWN<br />
* CAP_DAC_OVERRIDE<br />
* CAP_DAC_READ_SEARCH<br />
* CAP_FOWNER<br />
* CAP_FSETID<br />
* CAP_KILL<br />
* CAP_SETGID<br />
* CAP_SETUID<br />
* CAP_NET_BIND_SERVICE<br />
* CAP_SYS_CHROOT<br />
* CAP_SYS_PTRACE<br />
* CAP_SYS_BOOT<br />
* CAP_SYS_TTY_CONFIG<br />
* CAP_LEASE<br />
<br />
CAP_NET_RAW for example is not considered secure although it is often used to allow the broken ping command to work, although there are better alternatives like the userspace ping command poink[U7] or the VXC_RAW_ICMP Context Capability.<br />
<br />
=== The Chroot Barrier ===<br />
<br />
Ensuring that the Barrier flag is set on the parent directory of each VPS is vital if you do not want VPS root to escape from the confinement and walk your Host's root filesystem.<br />
<br />
=== Secure Device Nodes ===<br />
<br />
The /dev directory of a VPS should not contain more than the following devices and the one directory for the unix pts tree.<br />
<br />
* c 1 7 full<br />
* c 1 3 null<br />
* c 5 2 ptmx<br />
* c 1 8 random<br />
* c 5 0 tty<br />
* c 1 9 urandom<br />
* c 1 5 zero<br />
* d pts<br />
<br />
Of course other device nodes like console, mem and kmem, even block and character devices can be added, but some expertise is required in order to ensure no security holes are opened.<br />
<br />
=== Secure Proc-FS Entries ===<br />
<br />
There has been no detailed evaluation of secure and unsecure entries in the proc filesystem, but there have been some incidents where unprotected (not protected via Linux Capabilities) writable proc entries caused mayhem.<br />
<br />
For example, /proc/sysrq-trigger is something which should not be accessible inside a VPS without a very good reason.<br />
<br />
== Field of Application ==<br />
<br />
The primary goal of this project is to create virtual servers sharing the same machine. A virtual server operates like a normal Linux server. It runs normal services such as telnet, mail servers, web servers, and SQL servers.<br />
<br />
=== Administrative Separation ===<br />
<br />
This allows a clever provider to sell something called Virtual Private Server, which uses less resources than other virtualization techniques, which in turn allows more units on a single machine.<br />
<br />
The list of providers doing so is relatively long, and so this is rightfully considered the main area of application.<br />
<br />
=== Service Separation ===<br />
<br />
Separating different or similar services which otherwise would interfere with each other, either because they are poorly designed or because they are simply incapable of peaceful coexistence for whatever reason, can be easily done with Linux-VServer.<br />
<br />
But even on the old-fashioned real server machines, putting some extremely exposed or untrusted, because unknown or proprietary, services into some kind of jail can improve maintainability and security a lot.<br />
<br />
=== Enhancing Security ===<br />
<br />
While it can be interesting to run several virtual servers in one box, there is one concept potentially more generally useful. Imagine a physical server running a single virtual server. The goal is isolate the main environment from any service, any network. You boot in the main environment, start very few services and then continue in the virtual server.<br />
<br />
The service in the main environment would be:<br />
<br />
* Unreachable from the network.<br />
* Able to log messages from the virtual server in a secure way. The virtual server would be unable to change/erase the logs.\ Even a cracked virtual server would not be able the edit the log.<br />
* Able to run intrusion detection facilities, potentially spying the state of the virtual server without being accessible or noticed.\ For example, tripwire could run there and it would be impossible to circumvent its operation or trick it.<br />
<br />
Another option is to put the firewall in a virtual server, and pull in the DMZ, containing each service in a separate VPS. On proper configuration, this setup can reduce the number of required machines drastically, without impacting performance.<br />
<br />
=== Easy Maintenance ===<br />
<br />
One key feature of a virtual server is the independence from the actual hardware. Most hardware issues are irrelevant for a virtual server installation.<br />
<br />
The main server acts as a host and takes care of all the details. The virtual server is just a client and ignores all the details. As such, the client can be moved to another physical server with very few manipulations.<br />
<br />
For example, to move the virtual server from one physical computer to another, it is sufficient to do the following:<br />
<br />
* shutdown the running server<br />
* copy it over to the other machine<br />
* copy the configuration<br />
* start the virtual server on the new machine<br />
<br />
No adjustments to user setup, password database or hardware configuration are required, as long as both machines are binary compatible.<br />
<br />
=== Fail-over Scenarios ===<br />
<br />
Pushing the limit a little further, replication technology could be used to keep an up-to-the-minute copy of the filesystem of a running Virtual Server. This would permit a very fast fail-over if the running server goes offline for whatever reason.<br />
<br />
All the known methods to accomplish this, starting with network replication via rsync, or drbd, via network devices, or shared disk arrays, to distributed filesystems, can be utilized to reduce the down-time and improve overall efficiency.<br />
<br />
=== For Testing ===<br />
<br />
Consider a software tool or package which should be built for several versions of a specific distribution (Mandrake 8.2, 9.0, 9.1, 9.2, 10.0) or even for different distributions.<br />
<br />
This is easily solved with Linux-VServer. Given plenty of disk space, the different distributions can be installed and running side by side, simplifying the task of switching from one to another.<br />
<br />
Of course this can be accomplished by chroot() alone, but with Linux-VServer it's a much more realistic simulation.<br />
<br />
== Performance and Stability ==<br />
<br />
''(work in progress)''<br />
<br />
=== Impact of Linux-VServer on the Host ===<br />
<br />
seems to be 0% ...<br />
<br />
=== Overhead inside a Context ===<br />
<br />
seems to be less than 2% ...<br />
<br />
=== Size of the Kernel Patch ===<br />
<br />
Comparison of the different patches ...<br />
<br />
{| class="wikitablenowrap"<br />
! patch<br />
! hunks<br />
! +<br />
! -<br />
|-<br />
| patch-2.4.24-vs1.00.diff<br />
| 178<br />
| 1112<br />
| 135 <br />
|-<br />
| patch-2.4.24-vs1.20.diff<br />
| 216<br />
| 2035<br />
| 178 <br />
|-<br />
| patch-2.4.24-vs1.26.diff<br />
| 225<br />
| 2118<br />
| 180 <br />
|-<br />
| patch-2.4.25-vs1.27.diff<br />
| 252<br />
| 2166<br />
| 201 <br />
|-<br />
| patch-2.4.26-vs1.28.diff<br />
| 254<br />
| 2183<br />
| 202 <br />
|-<br />
| patch-2.6.6-vs1.9.0.diff<br />
| 494<br />
| 5699<br />
| 303 <br />
|-<br />
| patch-2.6.6-vs1.9.1.diff<br />
| 497<br />
| 5878<br />
| 307 <br />
|-<br />
| patch-2.6.7-vs1.9.2.diff<br />
| 618<br />
| 6836<br />
| 348 <br />
|-<br />
| uml-patch-2.4.26-1.diff<br />
| 449<br />
| 36885<br />
| 48<br />
|}<br />
<br />
== Non Intel i386 Hardware ==<br />
<br />
Linux-VServer was designed to be mostly architecture agnostic, therefore only a small part, the syscall definition itself, is architecture specific. Nevertheless some architectures have private copies of basically architecture independent code for whatever reason, and therefore small modifications are often required.<br />
<br />
The following architectures are supported and some of them are even tested:<br />
<br />
* alpha<br />
* ia32 / ia64 / xbox<br />
* x86_64 (AMD64)<br />
* mips / mips64<br />
* hppa / hppa64<br />
* ppc / ppc64<br />
* sparc / sparc64<br />
* s390<br />
* uml<br />
<br />
Adding a new architecture is relatively simple although extensive testing is required to make sure that every feature is working as expected (and of course, the hardware ;).<br />
<br />
== Linux Kernel Intro ==<br />
<br />
While almost all of the described features reside in the Linux Kernel, nifty Userspace Tools are required to activate and control the new functionality.<br />
<br />
Those Userspace Tools in general communicate with the Linux Kernel via System Calls (or Syscall for short).<br />
This chapter will give a short overview how Linux Kernel and User Space is organized and how Syscalls, a simple method of communication between processes and kernel, work.<br />
<br />
=== Kernel and User Space ===<br />
<br />
In Linux and similar Operating Systems, User and Kernel Space is separated, and address space is divided into two parts. Kernel space is where the kernel code resides, and user space is where the user programs live. Of course, a given user program can't write to kernel memory or to another program's memory area.<br />
<br />
Unfortunately, this is also the case for kernel code. Kernel code can't write to user space either. What does this mean? Well, when a given hardware driver wants to write data bytes to a program in user memory, it can't do it directly, but rather it must use specific kernel functions instead. Also, when parameters are passed by address to a kernel function, the kernel function can not read the parameters directly. It must use other kernel functions to read each byte of the parameters.<br />
<br />
Of course, there are some helpers which do the transfer to and from user space.<br />
<br />
<pre><br />
copy_to_user(void *to, const void *from, long n);<br />
copy_from_user(void *to, const void *from, long n);<br />
</pre><br />
<br />
get_user() and put_user() Get or put the given byte, word, or long from or to user memory. This is a macro, and it relies on the type of the argument to determine the number of bytes to transfer.<br />
<br />
=== Linux Syscalls ===<br />
<br />
Most libc calls rely on system calls, which are the simplest kernel functions a user program can call.<br />
<br />
These system calls are implemented in the kernel itself or in loadable kernel modules, which are little chunks of dynamically link-able kernel code.<br />
<br />
Linux system calls are implemented through a multiplexor called with a given maskable interrupt. In Linux, this interrupt is int 0x80. When the 'int 0x80' instruction is executed, control is given to the kernel (or, more accurately, to the _system_call() function), and the actual demultiplexing process occurs.<br />
<br />
How does _system_call() work ?<br />
<br />
First, all registers are saved and the content of the %eax register is checked against the global system calls table, which enumerates all system calls and their addresses.<br />
<br />
This table can be accessed with the extern void *sys_call_table[] variable. A given number and memory address in this table corresponds to each system call.<br />
<br />
System call numbers can be found in /usr/include/sys/syscall.h.<br />
<br />
They are of the form SYS_systemcallname. If the system call is not implemented, the corresponding cell in the sys_call_table is 0, and an error is returned.<br />
<br />
Otherwise, the system call actually exists and the corresponding entry in the table is the memory address of the system call code.<br />
<br />
== Kernel Side Implementation ==<br />
<br />
While this chapter is mainly of interest to kernel developers it might be fun to take a small peek behind the curtain to get a glimpse how everything really works.<br />
<br />
=== The Syscall Command Switch ===<br />
<br />
For a long time Linux-VServer used a few different Syscalls to accomplish different aspects of the work, but very soon the number of required commands grew large, and the Syscalls started to have magic values, selecting the desired behavior.<br />
<br />
Not too long ago, a single syscall was reserved for Linux-VServer, and while the opinion on that might differ from developer to developer, it was generally considered a good decision not to have more than one syscall.<br />
<br />
The advantage of different Syscalls would be simpler handling of the Syscalls on different architectures; however, this hasn't been a problem so far, as the data passed to and from the kernel has strong typed fields conforming to the C99 types.<br />
<br />
Regardless, the availability of one system call required the creation of a multiplexor, which decides, based on some selector, what specific command is to be executed, and then passes on the remaining arguments to that command, which does the actual work.<br />
<br />
<pre><br />
extern asmlinkage long<br />
sys_vserver(uint32_t cmd, uint32_t id, void __user *data)<br />
</pre><br />
<br />
The Linux-VServer syscall is passed three arguments regardless of what actual command is specified: a command (cmd), a number (id), and a user-space data-structure of yet unknown size.<br />
<br />
To allow for some structure for debugging purposes and some kind of command versioning, the cmd is split into three parts: the lower 12 bit contain a version number, then 4 bits are reserved, the upper 16 bits are divided into 8 bit command and 6 bit category, again reserving 2 bits for the future.<br />
<br />
There are 64 Categories with up to 256 commands in each category, allowing for 4096 revisions of each command, which is far more than will ever be required.<br />
<br />
Here is an overview of the categories already defined, and their numerical value:<br />
<br />
<pre><br />
Syscall Matrix V2.6<br />
<br />
|VERSION|CREATE |MODIFY |MIGRATE|CONTROL|EXPERIM| |SPECIAL|SPECIAL|<br />
|STATS |DESTROY|ALTER |CHANGE |LIMIT |TEST | | | |<br />
|INFO |SETUP | |MOVE | | | | | |<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
SYSTEM |VERSION|VSETUP |VHOST | | | | |DEVICES| |<br />
HOST | 00| 01| 02| 03| 04| 05| | 06| 07|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
CPU | |VPROC |PROCALT|PROCMIG|PROCTRL| | |SCHED. | |<br />
PROCESS| 08| 09| 10| 11| 12| 13| | 14| 15|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
MEMORY | | | | | | | |SWAP | |<br />
| 16| 17| 18| 19| 20| 21| | 22| 23|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
NETWORK| |VNET |NETALT |NETMIG |NETCTL | | |SERIAL | |<br />
| 24| 25| 26| 27| 28| 29| | 30| 31|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
DISK | | | | | | | |INODE | |<br />
VFS | 32| 33| 34| 35| 36| 37| | 38| 39|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
OTHER | | | | | | | |VINFO | |<br />
| 40| 41| 42| 43| 44| 45| | 46| 47|<br />
=======+=======+=======+=======+=======+=======+=======+ +=======+=======+<br />
SPECIAL| | | | |FLAGS | | | | |<br />
| 48| 49| 50| 51| 52| 53| | 54| 55|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
SPECIAL| | | | |RLIMIT |SYSCALL| | |COMPAT |<br />
| 56| 57| 58| 59| 60|TEST 61| | 62| 63|<br />
-------+-------+-------+-------+-------+-------+-------+ +-------+-------+<br />
</pre><br />
<br />
The definition of those Commands is simplified by some macros, so for example the commands to get and set the Context Flags are defined like this:<br />
<br />
<pre><br />
#define VCMD_get_cflags VC_CMD(FLAGS, 1, 0)<br />
#define VCMD_set_cflags VC_CMD(FLAGS, 2, 0)<br />
<br />
extern int vc_get_cflags(uint32_t, void __user *);<br />
extern int vc_set_cflags(uint32_t, void __user *);<br />
</pre><br />
<br />
Note that the command itself is not passed to the actual command implementation, only the id and the pointer to user-space data.<br />
<br />
=== Utilized Data Structures ===<br />
<br />
There are many different data structures used by different parts of the implementation; while only a few examples are given here, all utilized structures can be found in the source.<br />
<br />
==== The Context Data Structure ====<br />
<br />
The Context Data Structure consists of a few fields required to manage the contexts, and handle context destruction, as well as future hierarchical contexts.<br />
<br />
Logically separated sections of that structure, like for the scheduler or the context limits are defined in separate structures, and incorporated into the main one.<br />
<br />
<pre><br />
struct vx_info {<br />
struct list_head vx_list; /* linked list of contexts */<br />
xid_t vx_id; /* context id */<br />
atomic_t vx_refcount; /* refcount */<br />
struct vx_info *vx_parent; /* parent context */<br />
<br />
struct namespace *vx_namespace; /* private namespace */<br />
struct fs_struct *vx_fs; /* private namespace fs */<br />
uint64_t vx_flags; /* context flags */<br />
uint64_t vx_bcaps; /* bounding caps (system) */<br />
uint64_t vx_ccaps; /* context caps (vserver) */<br />
<br />
pid_t vx_initpid; /* PID of fake init process */<br />
<br />
struct _vx_limit limit; /* vserver limits */<br />
struct _vx_sched sched; /* vserver scheduler */<br />
struct _vx_cvirt cvirt; /* virtual/bias stuff */<br />
struct _vx_cacct cacct; /* context accounting */<br />
<br />
char vx_name[65]; /* vserver name */<br />
};<br />
</pre><br />
<br />
Here as example the Scheduler Substructure:<br />
<pre><br />
struct _vx_sched {<br />
spinlock_t tokens_lock; /* lock for this structure */<br />
<br />
int fill_rate; /* Fill rate: add X tokens ... */<br />
int interval; /* Divisor: ... each Y jiffies */<br />
atomic_t tokens; /* current number of tokens */<br />
int tokens_min; /* Limit: minimum for unhold */<br />
int tokens_max; /* Limit: no more than N tokens */<br />
uint32_t jiffies; /* bias: integral multiple of Y */<br />
<br />
uint64_t ticks; /* token tick events */<br />
cpumask_t cpus_allowed; /* cpu mask for context */<br />
};<br />
</pre><br />
<br />
The main idea behind this separation is that each substructure belongs to a logically distinct part of the implementation which provides an init and cleanup function for this structure, thus simplifying maintainability and readability of those structures.<br />
<br />
==== The Scheduler Command Data ====<br />
<br />
As an example for the data structure used to control a specific part of the context from user-space, here is a scheduler command and the utilized data structure to set the properties:<br />
<br />
<pre><br />
#define VCMD_set_sched VC_CMD(SCHED, 1, 2)<br />
<br />
struct vcmd_set_sched_v2 {<br />
int32_t fill_rate; /* Fill rate: add X tokens ... */<br />
int32_t interval; /* Divisor: ... each Y jiffies */<br />
int32_t tokens; /* current number of tokens */<br />
int32_t tokens_min; /* Limit: minimum for unhold */<br />
int32_t tokens_max; /* Limit: no more than N tokens */<br />
uint64_t cpu_mask; /* Mask: allowed cpus */<br />
};<br />
</pre><br />
<br />
==== Example Accounting: Sockets ====<br />
<br />
Basically all the accounting and limit stuff are defined as macros or inline functions capable of handling the different resources, hiding the underlying implementation wherever possible.<br />
<br />
<pre><br />
#define vx_acc_sock(v,f,p,s) \<br />
__vx_acc_sock((v), (f), (p), (s), __FILE__, __LINE__)<br />
<br />
static inline void __vx_acc_sock(struct vx_info *vxi,<br />
int family, int pos, int size, char *file, int line)<br />
{<br />
if (vxi) {<br />
int type = vx_sock_type(family);<br />
<br />
atomic_inc(&vxi->cacct.sock[type][pos].count);<br />
atomic_add(size, &vxi->cacct.sock[type][pos].total);<br />
}<br />
}<br />
<br />
#define vx_sock_recv(sk,s) \<br />
vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 0, (s))<br />
#define vx_sock_send(sk,s) \<br />
vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 1, (s))<br />
#define vx_sock_fail(sk,s) \<br />
vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 2, (s))<br />
</pre><br />
<br />
And this general definition is then used where appropriate, for example in the __sock_sendmsg() function like this:<br />
<br />
<pre><br />
len = sock->ops->sendmsg(iocb, sock, msg, size);<br />
if (sock->sk) {<br />
if (len == size)<br />
vx_sock_send(sock->sk, size);<br />
else<br />
vx_sock_fail(sock->sk, size);<br />
}<br />
</pre><br />
<br />
==== Example Limits: Virtual Memory ====<br />
<br />
<pre><br />
#define vx_pages_avail(m, p, r) \<br />
__vx_pages_avail((m)->mm_vx_info, (r), (p), __FILE__, __LINE__)<br />
<br />
static inline int __vx_pages_avail(struct vx_info *vxi,<br />
int res, int pages, char *file, int line)<br />
{<br />
if (!vxi)<br />
return 1;<br />
if (vxi->limit.rlim[res] == RLIM_INFINITY)<br />
return 1;<br />
if (atomic_read(&vxi->limit.res[res]) +<br />
pages < vxi->limit.rlim[res])<br />
return 1;<br />
return 0;<br />
}<br />
<br />
#define vx_vmpages_avail(m,p) vx_pages_avail(m, p, RLIMIT_AS)<br />
#define vx_vmlocked_avail(m,p) vx_pages_avail(m, p, RLIMIT_MEMLOCK)<br />
#define vx_rsspages_avail(m,p) vx_pages_avail(m, p, RLIMIT_RSS)<br />
</pre><br />
<br />
And again the test against those limits at certain places, for example here in copy_process()<br />
<br />
<pre><br />
/* check vserver memory */<br />
if (p->mm && !(clone_flags & CLONE_VM)) {<br />
if (vx_vmpages_avail(p->mm, p->mm->total_vm))<br />
vx_pages_add(p->mm->mm_vx_info,<br />
RLIMIT_AS, p->mm->total_vm);<br />
else<br />
goto bad_fork_free;<br />
}<br />
</pre><br />
<br />
==== Example Virtualization: Uptime ====<br />
<br />
<pre><br />
void vx_vsi_uptime(struct timespec *uptime)<br />
{<br />
struct vx_info *vxi = current->vx_info;<br />
<br />
set_normalized_timespec(uptime,<br />
uptime->tv_sec - vxi->cvirt.bias_tp.tv_sec,<br />
uptime->tv_nsec - vxi->cvirt.bias_tp.tv_nsec);<br />
return;<br />
}<br />
<br />
if (vx_flags(VXF_VIRT_UPTIME, 0))<br />
vx_vsi_uptime(&uptime, &idle);<br />
</pre><br />
<br />
<br />
== Future Directions ==<br />
<br />
''(work in progress)''<br />
<br />
=== Hierarchical Contexts ===<br />
<br />
=== Security Branch ===<br />
<br />
=== Stealth Branch ===<br />
<br />
[[Category:Documentation]]</div>Glennhttp://linux-vserver.org/Limit_Networking_on_Multihomed_hostsLimit Networking on Multihomed hosts2011-10-21T22:10:21Z<p>Glenn: -cat</p>
<hr />
<div>== Situation ==<br />
You have a multihomed host, e.g. DMZ and LAN or different DMZs and want a single VServer only to be able to send packets over a specific network.<br />
<br />
== Solution ==<br />
I used alternate routing tables:<br />
<br />
Once (tested on Debian):<br />
<pre><br />
echo 100 vservera > /etc/iproute2/rt_tables<br />
echo 101 vserverb > /etc/iproute2/rt_tables<br />
</pre><br />
<br />
After rebooting (write an init script)<br />
<pre><br />
ip route add IP-VServer-A/mask table vservera dev ethA<br />
ip route add default table vservera via Gateway-A<br />
ip route add IP-VServer-B/mask table vserverb dev ethB<br />
ip route add default table vserverb via Gateway-B<br />
<br />
ip rule add from net-VServer-A/mask table 100<br />
ip rule add from net-VServer-B/mask table 101<br />
</pre><br />
<br />
== Issues ==<br />
Traffic between IPs on the same host won't go the routes outside the host, you need to set up iptables here.<br />
<br />
[[Category:Network related]]</div>Glennhttp://linux-vserver.org/Networking_vserver_guestsNetworking vserver guests2011-10-21T22:09:01Z<p>Glenn: -cat</p>
<hr />
<div>Setting up network access to and from your vserver guests.<br />
__TOC__<br />
==Introduction==<br />
<br />
Lets imagine, you have only one external IP -- <code>$EXTIP</code>.<br />
<br />
You want to have several vservers running without worrying about port overlapping.<br />
<br />
Example:<br />
<br />
Two vservers run a default webserver, running on port 80. If each "guest" vserver shares an IP with the host, then the two webservers will conflict.<br />
<br />
One solution is:<br />
<br />
* All vservers are contained in a "virtual lan", say 192.168.1.x<br />
* Each vserver has its own IP<br />
* Control port forwarding on "parent" host. That is, run a router.<br />
<br />
==Configuration==<br />
===Host===<br />
<br />
===Optional: Load 'dummy' device(s)===<br />
<br />
====Why?====<br />
This driver allows you to associate vServer guests with a ''virtual'' network device rather than the host's real network interface, which functions to hide packet counters from vServer guests. '''There is no other use for this step''', so feel free to skip it if you are not worried about sharing packet counters. (Packet counts ''may'' be useful to an attacker with control of a vServer guest who wishes to perform side-channel attacks during cryptanalysis, or network traffic analysis against your host or other vServer guests. If you did not understand the last sentence and your installation is not particularly security sensitive, then the chances that you will encounter a skilled attacker and this will actually matter are slim to none and you should feel free to skip this section.)<br />
<br />
====Process====<br />
First you need to load the dummy interface driver (requires CONFIG_DUMMY=m in your kernel configuration)<br />
# modprobe dummy<br />
<br />
To have it automatically loaded on startup, add<br />
"loopback" to /etc/modules<br />
<br />
Set up <code>dummy0</code> interface on the parent host<br />
# /etc/network/interfaces on a Debian box, <br />
# configure on other distros with your preferred way<br />
auto dummy0<br />
iface dummy0 inet static<br />
address 192.168.1.250<br />
netmask 255.255.255.0<br />
<br />
====Optional Extra Step====<br />
It is possible to facilitate further segregation (such that even dummy packet counters are never shared between guests). To do so, use:<br />
# modprobe dummy numdummies=<number-of-devices-required><br />
... and associate each vServer with a unique dummy device.<br />
<br />
===Guests===<br />
Set up each guest vserver. If you skipped the host configuration above, you will need to replace dummy0 with the name of your host's primary network interface, for example eth0.<br />
<br />
cd /etc/vservers/$VSERVER/interfaces/0<br />
echo dummy0 > dev<br />
echo 192.168.1.1 > ip<br />
echo 1 > name<br />
echo 24 > prefix<br />
<br />
Consider using a value of <code>name</code> equal to the last digit of the IP for easy separation.<br />
<br />
===Host as router===<br />
Configure the host to act as a router.<br />
<br />
For internal packets going outside, pretend each packet came from our external IP (put it in one line without backslash):<br />
# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 \ <br />
! -d 192.168.1.0/24 -j SNAT --to-source $EXTIP<br />
For each service that runs on a vserver, map it to an external port. (For each ?) Vserver local address <code>$VHOST</code> and port <code>$INTPORT</code>, you select one external port <code>$EXTPORT</code> and run the following (put it in one line without backslash):<br />
# iptables -t nat -A PREROUTING ! -s 192.168.1.0/24 \<br />
-m tcp -p tcp --dport $EXTPORT <br />
-j DNAT --to-destination $VHOST:$INTPORT<br />
That's all!<br />
<br />
==Verifying==<br />
Try <code>ping pool.ntp.org</code> from your vserver -- it should ping fine.<br />
<br />
Try to connect to your <code>$EXTIP:$EXTPORT</code> (from another external host) -- you will successfully connect to service running on a guest vserver.<br />
==See also==<br />
* [[Frequently_Asked_Questions#If_my_host_has_only_one_a_single_public_IP.2C_can_I_use_RFC1918_IP_.28e.g._192.168.foo.bar.29_for_the_guest_vservers.3F |FAQ on private networking]]<br />
* [[Frequently_Asked_Questions#When_I_try_to_ssh_to_the_guest.2C_I_log_into_the_host.2C_even_if_I_installed_sshd_on_the_guest._What.27s_wrong_here.3F |Permit guest sshd to bind to its IP address's port 22]]<br />
* [[Networking_vserver_guests_RHEL|Networking_vserver_guests_RHEL]]<br />
<br />
[[Category:HowTo]]<br />
[[Category:Network related]]</div>Glennhttp://linux-vserver.org/NewsNews2011-10-21T22:02:15Z<p>Glenn: Been there Done that...</p>
<hr />
<div>{{News}}<br />
<br />
[[Category:Community| ]]</div>Glennhttp://linux-vserver.org/Todo_ListTodo List2011-10-21T22:01:07Z<p>Glenn: +Category:Maturity level</p>
<hr />
<div>== Community ==<br />
=== Wiki Work ===<br />
<br />
* correct spelling, word order and punctuation on the wiki.<br />
* add ideas related to Linux-VServer to the [Think Tank].<br />
* try to keep a similar layout on newly created pages.<br />
<br />
=== Testing ===<br />
<br />
* test all release candidates<br />
* test the current development version<br />
* provide feedback (including positive)<br />
* report kernels and [Working Configurations] <br />
<br />
== Developers ==<br />
<br />
=== Kernel List ===<br />
<br />
==== pending issues ====<br />
<br />
* {020} http://paste.linux-vserver.org/534 (goblin)<br />
: vrsetup /dev/vroot0 /dev/loop0 && mount -t xfs /dev/vroot0 /mnt<br />
<br />
==== missing stuff ====<br />
<br />
* {010} CPU virtualization<br />
* {015} limits for IPC stuff<br />
* {010} fix the inode sizes inode->i_size = 64;<br />
* {015} sendfile accounting<br />
<br />
==== features & addons ====<br />
<br />
* {005} replace hash locks by rw locks<br />
* {010} add slab cache for vxi/nxi<br />
* {010} fix the inode sizes inode->i_size = 64;<br />
* {010} allow proc_dointvec_bset read without CAP_SYS_MODULE<br />
* {020} lo isolation (2.1.2+)<br />
<br />
==== possible improvements ====<br />
<br />
* {015} look into atomic_inc_return() for resources<br />
: i.e. inc, then check, on over limit dec again ... <br />
* {010} check out vm_stat_account()<br />
* {020} ignore signals to fake init<br />
* {015} in_interrupt() instead of IRQ untagging<br />
* {010} mount type checks instead of magic<br />
<br />
==== to check ====<br />
<br />
* {020} check /proc/sys/fs/overflow{u,g}id and tagging<br />
* {015} check dqhash and quota support on ext3<br />
* {010} check __user annotation for vc_* commands<br />
* {010} revalidate checks in syscall commands<br />
* {015} nfs tagging and mount/interoperability<br />
* {010} maybe move ptrace checks to do_ptrace()<br />
<br />
==== requests ====<br />
<br />
* {Hollow} rlimit_mask syscall for accounted values<br />
* {Hollow} ctx_stat for nx<br />
* {Hollow} move VXC_RAW_ICMP to NXC_RAW_ICMP<br />
<br />
=== Userspace (Tools) ===<br />
<br />
==== requests ====<br />
<br />
* {Bertl} NXF_HIDE_NETIF support (default)<br />
* {Bertl} Support for UTS/IPC/PID spaces in Mainline<br />
<br />
[[Category:Community]]<br />
[[Category:Maturity level]]</div>Glennhttp://linux-vserver.org/Category:Maturity_levelCategory:Maturity level2011-10-21T22:00:43Z<p>Glenn: new</p>
<hr />
<div>[[Category:Categories]]</div>Glennhttp://linux-vserver.org/Category:IdeasCategory:Ideas2011-10-21T22:00:26Z<p>Glenn: catchg</p>
<hr />
<div>[[Category:Maturity level]]</div>Glennhttp://linux-vserver.org/Usage_ScenariosUsage Scenarios2011-10-21T21:56:53Z<p>Glenn: +{{Languages|Usage Scenarios}}</p>
<hr />
<div>{{Languages|Usage Scenarios}}<br />
<br />
For many people, virtual server may look like a great toy: Very high geekness factor. It looks cool, but probably not for everyone. '''Wrong!'''<br />
<br />
The primary goal of this project is to create virtual servers sharing the same machine. A virtual server operates like a normal Linux server. It runs normal services such as ssh, mail, web and database servers.<br />
<br />
== Consolidation and Separation ==<br />
<br />
As the hardware evolves, it is tempting to put more and more tasks on a server. Though Linux could reliably handle it, at some point, you will end up with too much stuff and people fiddling in the same box that you worry about updating things. Additionally, separating different or similar services which otherwise would interfere with each other, either because they are poorly designed or because they are simply incapable of peaceful coexistence for whatever reason, may often be complex or even impossible.<br />
<br />
The Linux-VServer project addresses this issue. The same box is able to run multiple virtual servers and each one does the job it is supposed to do. If you need to upgrade to PHP 5 for a given project, you can do so, and only that one project is affected.<br />
<br />
Also, you can give the root password of a virtual server to an administrator for that virtual server and he/she will be able to perform updates, restart services and so on without having to know about every other project hosted on the same server. This allows a clever provider to sell Virtual Private Servers, which uses less resources than other virtualization techniques, which in turn allows to put more units on a single machine. <br />
<br />
The list of providers doing so is relatively long, and so this is rightfully considered the main area of application. See [[VServer Hosting]] for a (probably incomplete) list of companies providing Virtual Private Servers based on the Linux-VServer technology.<br />
<br />
== Enhancing Security ==<br />
<br />
While it can be interesting to run several virtual servers in one box, there is one concept potentially more generally useful. Imagine a physical server running a single virtual server. The goal is isolate the main environment from any service, any network. You boot in the main environment, start very few services and then continue in the virtual server.<br />
<br />
The service in the main environment would be:<br />
<br />
* Unreachable from the network. <br />
* Able to log messages from the virtual server in a secure way. The virtual server would be unable to change/erase the logs. Even a cracked virtual server would not be able to edit the log.<br />
* Able to run intrusion detection facilities, potentially spying the state of the virtual server without being accessible or noticed. For example, tripwire could run there and it would be impossible to circumvent its operation or trick it.<br />
<br />
Another option is to put the firewall in a virtual server, and pull in the DMZ, containing each service in a separate VPS. On proper configuration, this setup can reduce the number of required machines drastically, without impacting performance.<br />
<br />
== Resource Independence ==<br />
<br />
Since virtual servers are only guests on the hardware they are using, they are not aware of the specifics: they do not contain disk configurations, kernels or network configurations.<br />
<br />
One key feature of a virtual server is the independence from the actual hardware. Most hardware issues are irrelevant for a virtual server installation. <br />
<br />
The main server acts as a host and takes care of all the details. The virtual server is just a client and ignores all the details. As such, the client can be moved to another physical server with very few manipulations.<br />
<br />
For example, to move the virtual server from one physical computer to another, it sufficient to do the following:<br />
<br />
* shutdown the running server <br />
* copy it over to the other machine <br />
* copy the configuration <br />
* start the virtual server on the new machine <br />
<br />
No adjustments to user setup, password database or hardware configuration are required, as long as both machines are binary compatible.<br />
<br />
Thus, once you have found that a project is using more resource than expected, you can easily move it to another box without tinkering around in hardware configuration files. A virtual server is just a directory on the filesystem of host system.<br />
<br />
== Fail-over Scenarios ==<br />
<br />
Pushing the limit a little further, replication technology could be used to keep an up-to-the-minute copy of the filesystem of a running virtual server. This would permit a very fast [[fail-over]] if the running server goes offline for whatever reason. <br />
<br />
All the known methods to accomplish this, starting with network replication via rsync, or drbd, via network devices, or shared disk arrays, to distributed filesystems, can be utilized to reduce the down-time and improve overall efficiency.<br />
<br />
== Experimenting and Upgrading ==<br />
<br />
If you intend to upgrade a system to get new features or security updates, you probably first test the new packages on the development machine, before you are ready to update the production server. Having some experience you do it properly:<br />
<br />
* Doing a backup of the server<br />
* Perform all the upgrades and install the new applications<br />
<br />
Two hours later you realise that something does not work as expected. To make it worse, it works fine on the development machine. We have all experienced this.<br />
<br />
Another solution to this problem would be to install the new production server on new hardware, but this is not as easy, as you have to clone the first server (most people are not comfortable doing this) or you do not have the hardware.<br />
<br />
Using virtual servers, all this is very easy:<br />
<br />
* Stop the virtual server in production<br />
* Make a copy of the virtual server<br />
* Perform the upgrades in the new virtual server<br />
<br />
To get back to our example above, two hours later you realise that something does not work as expected and you cannot immediately fix it.<br />
<br />
Again, using virtual servers, the (temporary) solution to this problem is very easy:<br />
<br />
* Stop the new virtual server and assign it a new IP address<br />
* Start both the old and new virtual server<br />
<br />
Now the old one is still online and you can track down the issues on your new virtual server using a different IP address, fix the problem and reassign the old IP address to the new virtual server.<br />
<br />
<br />
<br />
== Distribution Independence ==<br />
<br />
People are often talking about their preferred distribution. Should one use Fedora, Debian or something else? Should one give a spin to the latest and greatest distribution just for the sake of it?<br />
<br />
With virtual servers, the choice of a distribution is less important. When you select a distribution, you expect it will do the following:<br />
<br />
* Good hardware support/detection<br />
* Good package technology/updates<br />
* Good package selection<br />
* Reliable packages<br />
<br />
The choice is important because every service running on a box will be using the same distribution. Most distributions out there are good and reliable. Still each one has its peculiarities and probably flaws. For example, one distribution is doing a great job on security but is not delivering the latest and greatest PHP. Now because you have decided to use this distribution for some projects, using virtual servers does not prevent you from using another distribution for other projects or even a second virtual server for existing projects.<br />
<br />
== Other considerations ==<br />
<br />
* '''Virtual Private Servers are running on the same kernel as the host:''' Unlike other VM solutions, Linux-VServer does not require additional memory or processing power, in fact it may even reduce used memory due to the fact that multiple virtual servers may share the same files.<br />
<br />
* '''There are no special daemons running:''' A VPS running crond, sshd, httpd and sendmail uses the same resources as a normal Linux server running these services.<br />
<br />
* '''No pre-allocated disk space needed:''' A VPS generally shares the disk space with the host system, so there is no need to pre-allocate disk space for each virtual server to find out later that your disk is full, yet each VPS is using only a tiny portion of their allocated space.<br />
<br />
* '''Resource sharing:''' Since virtual servers can share binaries and libraries without interfering, a second VPS generally costs about 40-100MB of disk space only. Most of this space is a copy of the packaging database.<br />
<br />
* '''32-/64-bit independence:''' You can easily run a 32-bit distribution inside a VPS on a 64-bit host system, but faster, sometimes a lot.<br />
<br />
* '''Admin tools work inside a vserver as usual''': A vserver feels like a real server from within and can be used in the same ways.<br />
<br />
== See Also ==<br />
<br />
* [[Overview]]<br />
<br />
[[Category:Documentation]]<br />
[[Category:Community]]<br />
[[Category:Categories]]</div>Glennhttp://linux-vserver.org/OverviewOverview2011-10-21T21:56:07Z<p>Glenn: +{{Languages|Overview}}</p>
<hr />
<div>{{Languages|Overview}}<br />
<br />
Virtualization is a framework or methodology of dividing the resources of a computer into multiple execution environments. As a perceived "hot term", virtualization has been claimed by IT marketers to refer to everything from virtual machines to systems management software, so as to become nearly meaningless.<br />
<br />
== Types of Virtualization ==<br />
<br />
Some common applications of virtualization are listed below; this list reflects the extreme diversity that the term has come to encapsulate.<br />
<br />
=== Emulation ===<br />
<br />
A software emulator allows computer programs to run on a platform (computer architecture and / or operating system) other than the one for which they were originally written. Unlike simulation, which only attempts to reproduce a program's behavior, emulation attempts to model to various degrees the state of the device being emulated.<br />
The virtual machine simulates the complete hardware, allowing an unmodified OS for a completely different CPU to be run. This is also known as ''Dynamic Recompilation''.<br />
<br />
=== Paravirtualization ===<br />
<br />
Paravirtualization is a virtualization technique that presents a software interface to virtual machines that is similar but not identical to that of the underlying hardware. This requires operating systems to be explicitly ported to run on top of the virtual machine monitor (VMM) but may enable the VMM itself to be simpler and for the virtual machines that run on it to achieve higher performance.<br />
<br />
=== Native Virtualization ===<br />
<br />
Native virtualization is a virtualization technique where the virtual machine monitor or hypervisor only partially simulates enough hardware to allow an unmodified Operating System to be run in isolation, but the guest Operating System must be designed for the same type of CPU.<br />
<br />
=== Operating System-Level Virtualization ===<br />
<br />
Operating System-level Virtualization is a server virtualization technology which virtualizes servers on a operating system (kernel) layer. It can be thought of as partitioning a single physical server into multiple small computational partitions. Each such partition looks and feels like a real server, from the point of view of its owner. On Unix systems, this technology can be thought of as an advanced extension of the standard chroot mechanism.<br />
<br />
== The Linux-VServer approach ==<br />
<br />
=== Abstract ===<br />
<br />
The Linux-VServer technology is a soft partitioning concept based on ''Security Contexts'' which permits the creation of many independent ''Virtual Private Servers'' (VPS) that run simultaneously on a single physical server at full speed, efficiently sharing hardware resources.<br />
<br />
A VPS provides an almost identical operating environment as a conventional Linux server. All services, such as ssh, mail, web and database servers can be started on such a VPS, without (or in special cases with only minimal) modification, just like on any real server.<br />
<br />
Each VPS has its own user account database and root password and is isolated from other virtual servers, except for the fact that they share the same hardware resources.<br />
<br />
=== Introduction ===<br />
<br />
Over the years, computers have become sufficiently powerful to use virtualization to create the illusion of many smaller virtual machines, each running a separate operating system instance.<br />
<br />
There are several kinds of ''Virtual Machines'' (VMs) which provide similar features, but differ in the degree of abstraction and the methods used for virtualization.<br />
<br />
Most of them accomplish what they do by ''emulating'' some real or fictional hardware, which in turn requires ''real'' resources from the ''Host System'' (the machine running the VMs). This approach, used by most ''System Emulators'' (like [http://fabrice.bellard.free.fr/qemu/ QEMU] or [http://bochs.sourceforge.net/ Bochs]), allows the emulator to run an arbitrary ''Guest Operating System'', even for a different architecture (CPU and hardware). No modifications need to be made to the Guest OS because it isn't aware of the fact that it isn't running on real hardware.<br />
<br />
Some System Emulators (including Paravirtualization) require small modifications or specialized drivers to be added to the Host or Guest system to improve performance and minimize the overhead required for the hardware emulation. Although this significantly improves efficiency, there are still large amounts of resources being wasted in caches and mediation between Guest and Host (examples for this approach are [http://user-mode-linux.sourceforge.net/ UML] and [http://www.cl.cam.ac.uk/research/srg/netos/xen/ Xen]).<br />
<br />
But suppose you do not want to run many different Operating Systems simultaneously on a single box? Most applications running on a server do not require hardware access or kernel level code, and could easily share a machine with others, if they could be separated and secured...<br />
<br />
=== Concept ===<br />
<br />
At a basic level, a Linux server consists of three building blocks: hardware, kernel and applications. The hardware usually depends on the provider or system maintainer, and, while it has a big influence on the overall performance, it cannot be changed that easily, and will likely differ from one setup to another.<br />
<br />
The main purpose of the kernel is to build an abstraction layer on top of the hardware to allow processes (applications) to work with and operate on resources (data) without knowing the details of the underlying hardware. Ideally, those processes would be completely hardware agnostic, by being written in an interpreted language and therefore not requiring any hardware-specific knowledge.<br />
<br />
Given that a system has enough resources to drive ten times the number of applications a single Linux server would usually require, why not put ten servers on that box, which will then share the available resources in an efficient manner?<br />
<br />
Most server applications (e.g. httpd) will assume that it is the only application providing a particular service, and usually will also assume a certain filesystem layout and environment. This dictates that similar or identical services running on the same physical server but differing only in their addresses (for example), must be coordinated. This typically requires a great deal of administrative work which can lead to reduced system stability and security.<br />
<br />
The basic concept of the Linux-VServer solution is to separate the user-space environment into distinct units (Virtual Private Servers) in such a way that each VPS looks and feels like a real server to the processes contained within.<br />
<br />
Although different Linux distributions use (sometimes heavily) patched kernels to provide special support for unusual hardware or extra functionality, most Linux distributions are not tied to a special kernel.<br />
<br />
Linux-VServer uses this fact to allow several distributions, to be run simultaneously on a single, shared kernel, without direct access to the hardware, and share the resources in a very efficient way.<br />
<br />
That said, you may have already figured out that Linux-VServer uses Operating System-level virtualization ;-)<br />
<br />
== History ==<br />
<br />
Jacques Gélinas created the VServer project a number of years back (see [http://www.solucorp.qc.ca/miscprj/s_context.hc Jack's Site]). He still does vserver development and the community can be glad to have him. He's a genius, without him, vserver would not exist. Three cheers for Jack.<br />
<br />
But sometime during 2003 it became apparent that Jack didn't have the time to keep vserver development up to pace. So in November, Herbert Pötzl officially took charge of development. He now releases the vserver kernel patches, announcing them on the vserver mailing list and making them available for the public.<br />
<br />
Additionally, Enrico Scholz decided to reimplement Jack's vserver tools in C. These are now distributed as util-vserver (See [[Downloads]]). They are backward compatible to Jack's tools as far as possible, but follow the kernel patch development more closely.<br />
<br />
In 2005, Benedikt Böhm started another reimplementation of the userspace utilities, although with a completely different architecture in mind. This new implementation is known as VServer Control Daemon and is still in heavy development. A first final release was planned for end of 2006, but there are no releases yet. See [[Downloads]].<br />
<br />
== See also ==<br />
<br />
* [[Usage Scenarios]]<br />
* [[Related Projects]]<br />
* [[Paper|Implementation Details]]<br />
<br />
== External Links ==<br />
<br />
* [http://en.wikipedia.org/wiki/Virtualization Wikipedia article about virtualization]<br />
* [http://www.kernelthread.com/publications/virtualization/ An Introduction to Virtualization]<br />
<br />
[[Category:Community| ]]<br />
[[Category:Theory| ]]<br />
[[Category:Categories| ]]</div>Glennhttp://linux-vserver.org/Category:CommunityCategory:Community2011-10-21T21:55:30Z<p>Glenn: +{{Languages|:Category:Community}}</p>
<hr />
<div>{{Languages|:Category:Community}}<br />
<br />
[[Category:Categories]]</div>Glennhttp://linux-vserver.org/Category:ProcFS/frCategory:ProcFS/fr2011-10-21T21:53:32Z<p>Glenn: catchg</p>
<hr />
<div>{{Languages|:Category:ProcFS}}<br />
<br />
[[Category:French]]<br />
[[Category:Documentation]]</div>Glennhttp://linux-vserver.org/Secure_ProcFS_EntriesSecure ProcFS Entries2011-10-21T21:53:10Z<p>Glenn: catchg</p>
<hr />
<div>{{Languages|Secure ProcFS Entries}}<br />
<br />
The Linux-VServer project provides a mechanism to protect entries in the proc filesystem from being seen in every context, this has been introduced in development release 1.3.5 and stable release 1.23. <br />
<br />
The system consists of three flags: admin, watch and hide. To view/set these, a recent version of the util-vserver package, containing setattr and showattr, is required. (There is another tool called vproc, but this won't be discussed here). The logic behind these flags has been changed in experimental release 0.09, and new devel / stable releases that also use this logic, are coming soon, so the old logic won't be explained here (if you're running an older version of Linux-VServer, you probably already figured it out yourself anyways).<br />
<br />
'''Note:''' When referring to the flags, I'll follow the syntax used by the showattr tool of the util-vserver package, where '''a''' means admin, '''w''' means watch and '''h''' means hide, also lower case means disabled and upper case means enabled.<br />
<br />
== Flag logic (Linux-VServer 2.4 branch > 1.3.7 / 2.6 branch > 0.08) ==<br />
The flags have the following meanings:<br />
{|class="wikitablenowrap"<br />
!Flag<br />
!Meaning <br />
|-<br />
|admin<br />
| always visible in context 0 <br />
|-<br />
|watch<br />
| always visible in context 1 <br />
|-<br />
|hide<br />
| hidden<br />
|}<br />
<br />
This means a mapping of flagging to visibility according to this table:<br />
{|class="wikitablenowrap"<br />
!Flags<br />
!Visibility <br />
|-<br />
|<tt>* * h</tt><br />
|Visible everwhere (admin and watch flags don't matter) <br />
|-<br />
|<tt>A w H</tt><br />
|Visible only in context 0 <br />
|-<br />
|<tt>a W H </tt> <br />
|Visible only in context 1 <br />
|-<br />
|<tt>A W H </tt> <br />
|Visible in contexts 0 and 1 <br />
|-<br />
|<tt>a w H</tt> <br />
|Totally invisible (cannot be reverted without rebooting!)<br />
|}<br />
<br />
== Default flagging ==<br />
As of now the stable vs1.2.x (2.4 kernel defaults to all proc entries visible everywhere, stable vs2.0.x (2.6 kernel), development and experimental versions default to all proc entries only visible in context 0 and 1.<br />
<br />
==Setting flags==<br />
To set those flags you'll need the setattr tool from a recent util-vserver package (0.30.193 works), the usage is pretty much self-explanatory from the command-line help. To make the /proc/loadavg entry visible everywhere, you have to unset the hide flag:<br />
setattr --~hide /proc/loadavg<br />
<br />
The admin and watch flag can be in any state as hiding is controlled by the hide flag only.<br />
<br />
To keep vservers from reading the interrupt information, you need to hide the /proc/interrupts entry. If you want this to be accessible in the admin context (0) only use:<br />
setattr --hide --admin --~watch /proc/interrupts<br />
<br />
==vprocunhide ==<br />
With alpha util-vserver comes a tool called vprocunhide that sets reasonable flags for a number of proc entries that are generally needed to be visible. There is also an init script, normally located at /usr/local/etc/init.d/vprocunhide that you can use to include it in your boot process.<br />
<br />
[[Category:ProcFS]]</div>Glennhttp://linux-vserver.org/Secure_ProcFS_Entries/frSecure ProcFS Entries/fr2011-10-21T21:52:41Z<p>Glenn: catchg</p>
<hr />
<div>{{Languages|Secure ProcFS Entries}}<br />
<br />
Depuis les versions stable 1.23 et développement 1.3.5, vous pouvez protéger les entrées du système de fichier /proc, de manière à ce qu'elles ne soient pas visibles dans tous les contextes. Le système est constitué de trois drapeaux: admin, watch et hide (caché). Pour les activer ou les consulter, vous devez utiliser une version récente du paquet util-vserver, qui contient setattr et showattr. (Un autre outil existe, vproc, mais ne sera pas détaillé ici). La logique derrière ces drapeaux a été modifiée dans la release expérimentale 0.09, et les nouvelles releases stable et devel utilisent aussi cette logique. Nous ne parlerons pas de l'ancienne logique.<br />
<br />
'''Note:''' Pour faire allusion aux drapeaux, j'utiliserai la syntaxe de l'outil showattr du paquet util-vserver, ou '''a''' est mis pour admin, '''w''' pour watch et '''h''' pour hide (caché). De plus, une minuscule signifie désactivé alors qu'une majuscule signifie activé.<br />
<br />
== Flag logic (Linux-VServer 2.4 branch > 1.3.7 / 2.6 branch > 0.08) ==<br />
Les drapeaThe flags have the following meanings:<br />
{|class="wikitablenowrap"<br />
!Drapeau<br />
! Signification<br />
|-<br />
|admin<br />
| toujours visible dans le contexte 0<br />
|-<br />
|watch<br />
| toujours visible dans le contexte 1<br />
|-<br />
|hide<br />
| caché<br />
|}<br />
<br />
La correspondance entre drapeaux et visibilité est donnée par la table suivante:<br />
{|class="wikitablenowrap"<br />
!Drapeau<br />
!Signification<br />
|-<br />
|<tt>* * h</tt><br />
|Visible partout (les drapeaux admin et watch n'ont pas d'effet)<br />
|-<br />
|<tt>A w H</tt><br />
|Visible seulement dans le contexte 0<br />
|-<br />
|<tt>a W H </tt> <br />
|Visible seulement dans le contexte 1<br />
|-<br />
|<tt>A W H </tt> <br />
|Visible dans les contextes 0 et 1<br />
|-<br />
|<tt>a w H</tt> <br />
|Totalement invisible (irreversible sans reboot!)<br />
|}<br />
<br />
== Drapeaux par Default ==<br />
Les drapeaux sont mis par défaut à:<br />
*toutes les entrées de /proc sont visibles partout (branche stable)<br />
*toutes les entrées de /proc sont visibles seulement dans le contexte 0 (branches devel et expérimentale)<br />
<br />
==Activation des drapeaux==<br />
Pour activer ces drapeaux vous devez utiliser l'outil setattr (à partir de util-vserver >= 0.30.193), dont l'usage est assez clair d'après l'aide en ligne de commande. Pour faire en sorte que l'entrée /proc/loadavg soit visible partout, désactivez par exemple le drapeau hide (caché):<br />
setattr --~hide /proc/loadavg<br />
<br />
Peu importe la position des drapeaux admin et watch, puisque hide n'est controlé que par le drapeau hide.<br />
Pour éviter aux vservers d'avoir accès aux informations à propos des interruptions, vous devez cacher l'entrée /proc/interrupts. Si vous voulez pouvoir y accéder depuis le context admin uniquement (contexte 0), utilisez simplement:<br />
setattr --hide --admin --~watch /proc/interrupts<br />
<br />
==vprocunhide==<br />
Les outils alpha util-vserver sont livrés avec un outil appelé vprocunhide qui attribue des drapeaux raisonnables pour un certain nombre d'entrées proc, dont on a généralement besoin. Un script d'init est aussi fourni, situé en principe dans <tt>/usr/local/etc/init.d/vprocunhide</tt>, et que vous pouvez include dans votre séquence de démarrage.<br />
<br />
[[Category:ProcFS/fr]]</div>Glennhttp://linux-vserver.org/HowTo_Read_ProcFS/frHowTo Read ProcFS/fr2011-10-21T21:51:46Z<p>Glenn: catchg</p>
<hr />
<div>{{Languages|HowTo Read ProcFS}}<br />
<br />
==Information in /proc/virtual==<br />
/proc/virtual<br />
.../info<br />
<br />
/proc/virtual/<pid><br />
.../info<br />
.../status<br />
.../sched<br />
.../cvirt<br />
.../cacct<br />
.../limit<br />
<br />
===/proc/virtual/info===<br />
===/proc/virtual/<xid>===<br />
Ce répertoire contient plusieurs fichiers qui donnent des informations importantes sur l'état du contexte courant et ses paramètres de fonctionnement.<br />
<br />
==== /proc/virtual/<xid>/info ====<br />
ID: 1001<br />
Info: 83c37000<br />
Init: 0<br />
<br />
Nous avons ici le context id, l'emplacement du vx_info ainsi que le pid d'init<br />
<br />
==== /proc/virtual/<xid>/status ====<br />
UseCnt: 38<br />
Tasks: 16<br />
Flags: 0000000000000000<br />
BCaps: 00000000d46c04ff<br />
CCaps: 0000000000000000<br />
Ticks: 0<br />
<br />
this contains the usage count (references) and task count, as well as the context flags, capability boundary and context capabilities<br />
==== /proc/virtual/<xid>/sched ====<br />
Token: 0<br />
FillRate: 1<br />
Interval: 4<br />
TokensMin: 6<br />
TokensMax: 50<br />
PrioBias: 0<br />
VaVaVoom: 0<br />
cpu 0: 0 0 0<br />
<br />
Nombre de token en cours, parametres de l'ordonanceur (fill rate, interval, min/max), la "priority bias" ainsi que le vavavoom (bonus calcule)<br />
<br />
==== /proc/virtual/<xid>/cacct ====<br />
UNSPEC: 0/0 0/0 0/0 <br />
UNIX: 35/2375 35/2375 0/0 <br />
INET: 12/531 56/1937 57/1705 <br />
INET6: 0/0 0/0 0/0 <br />
OTHER: 0/0 0/0 0/0 <br />
forks: 0<br />
<br />
this accounts socket messages for the listed protocols, as incoming messages/bytes and outgoing messages/bytes<br />
<br />
====/proc/virtual/<xid>/cvirt ====<br />
BiasUptime: 49.73<br />
SysName: Linux<br />
NodeName: XXXX.test.org<br />
Release: 2.6.11-rc5<br />
Version: #12 Sun Feb 27 01:07:29 CET 2005<br />
Machine: i686<br />
DomainName: <br />
nr_threads: 16<br />
nr_running: 0<br />
nr_unintr: 0<br />
nr_onhold: 0<br />
load_updates: 14585<br />
loadavg: 0.00 0.00 0.00<br />
total_forks: 272<br />
<br />
this contains the uptime bias, utsname settings (sys, node, rel, vers, machine, domain), the number of threads, thread stats (running, uninterruptible, on hold), the number of load updates, the load averages (1,5,15) and the number of forks<br />
<br />
==== /proc/virtual/<xid>/limit ====<br />
PROC: 16 17 -1 0<br />
VM: 14440 15331 -1 0<br />
VML: 0 0 -1 0<br />
RSS: 5478 5847 -1 0<br />
ANON: 1516 1516 -1 0<br />
FILES: 140 155 -1 0<br />
OFD: 122 122 -1 0<br />
LOCKS: 1 3 -1 0<br />
SOCK: 9 9 -1 0<br />
MSGQ: 0 0 -1 0<br />
SHM: 0 0 -1 0<br />
<br />
limit columns are: <br />
# current <br />
# max observed <br />
# limit <br />
# number of hits <br />
<br />
limit rows are: <br />
*processes, <br />
*virtual memory, <br />
*locked memory, <br />
*resident set size, <br />
*anonymous memory, <br />
*number of files, <br />
*filedescriptors, <br />
*locks, <br />
*sockets, <br />
*message queues, <br />
*shared memory<br />
<br />
==Debug settings in /proc/sys/vserver==<br />
/proc/sys/vserver<br />
.../debug_switch<br />
.../debug_xid<br />
.../debug_cvirt<br />
.../debug_limit<br />
.../debug_dlim<br />
.../debug_nid<br />
.../debug_net<br />
<br />
===/proc/sys/vserver/debug_switch===<br />
===/proc/sys/vserver/debug_xid===<br />
===/proc/sys/vserver/debug_cvirt===<br />
===/proc/sys/vserver/debug_limit===<br />
===/proc/sys/vserver/debug_dlim===<br />
===/proc/sys/vserver/debug_nid===<br />
===/proc/sys/vserver/debug_net===<br />
<br />
[[Category:ProcFS/fr]]</div>Glennhttp://linux-vserver.org/Category:ProcFSCategory:ProcFS2011-10-21T21:51:21Z<p>Glenn: +{{Languages|:Category:ProcFS}}</p>
<hr />
<div>{{Languages|:Category:ProcFS}}<br />
<br />
[[Category:Documentation]]</div>Glenn