1758 lines
57 KiB
TeX
1758 lines
57 KiB
TeX
\PassOptionsToPackage{unicode=true}{hyperref} % options for packages loaded elsewhere
|
||
\PassOptionsToPackage{hyphens}{url}
|
||
\PassOptionsToPackage{dvipsnames,svgnames*,x11names*}{xcolor}
|
||
%
|
||
\documentclass[12pt,english,a4paperpaper,]{article}
|
||
\usepackage{lmodern}
|
||
\usepackage{amssymb,amsmath}
|
||
\usepackage{ifxetex,ifluatex}
|
||
\usepackage{fixltx2e} % provides \textsubscript
|
||
\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
|
||
\usepackage[T1]{fontenc}
|
||
\usepackage[utf8]{inputenc}
|
||
\usepackage{textcomp} % provides euro and other symbols
|
||
\else % if luatex or xelatex
|
||
\usepackage{unicode-math}
|
||
\defaultfontfeatures{Ligatures=TeX,Scale=MatchLowercase}
|
||
\setmainfont[]{Linux Libertine O}
|
||
\setsansfont[]{Linux Biolinum O}
|
||
\setmonofont[Mapping=tex-ansi]{FantasqueSansMono-Regular}
|
||
\fi
|
||
% use upquote if available, for straight quotes in verbatim environments
|
||
\IfFileExists{upquote.sty}{\usepackage{upquote}}{}
|
||
% use microtype if available
|
||
\IfFileExists{microtype.sty}{%
|
||
\usepackage[]{microtype}
|
||
\UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts
|
||
}{}
|
||
\usepackage{xcolor}
|
||
\usepackage{hyperref}
|
||
\hypersetup{
|
||
pdftitle={Virtualisation légère -- TP no 3},
|
||
pdfauthor={Pierre-Olivier nemunaire Mercier},
|
||
colorlinks=true,
|
||
linkcolor=black,
|
||
filecolor=Maroon,
|
||
citecolor=Blue,
|
||
urlcolor=ForestGreen,
|
||
breaklinks=true}
|
||
\urlstyle{same} % don't use monospace font for urls
|
||
\usepackage{color}
|
||
\usepackage{fancyvrb}
|
||
\newcommand{\VerbBar}{|}
|
||
\newcommand{\VERB}{\Verb[commandchars=\\\{\}]}
|
||
\DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}}
|
||
% Add ',fontsize=\small' for more characters per line
|
||
\newenvironment{Shaded}{}{}
|
||
\newcommand{\AlertTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{#1}}}
|
||
\newcommand{\AnnotationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}}
|
||
\newcommand{\AttributeTok}[1]{\textcolor[rgb]{0.49,0.56,0.16}{#1}}
|
||
\newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{#1}}
|
||
\newcommand{\BuiltInTok}[1]{#1}
|
||
\newcommand{\CharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}}
|
||
\newcommand{\CommentTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textit{#1}}}
|
||
\newcommand{\CommentVarTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}}
|
||
\newcommand{\ConstantTok}[1]{\textcolor[rgb]{0.53,0.00,0.00}{#1}}
|
||
\newcommand{\ControlFlowTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{#1}}}
|
||
\newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.56,0.13,0.00}{#1}}
|
||
\newcommand{\DecValTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{#1}}
|
||
\newcommand{\DocumentationTok}[1]{\textcolor[rgb]{0.73,0.13,0.13}{\textit{#1}}}
|
||
\newcommand{\ErrorTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{#1}}}
|
||
\newcommand{\ExtensionTok}[1]{#1}
|
||
\newcommand{\FloatTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{#1}}
|
||
\newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.02,0.16,0.49}{#1}}
|
||
\newcommand{\ImportTok}[1]{#1}
|
||
\newcommand{\InformationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}}
|
||
\newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{#1}}}
|
||
\newcommand{\NormalTok}[1]{#1}
|
||
\newcommand{\OperatorTok}[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}}
|
||
\newcommand{\OtherTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{#1}}
|
||
\newcommand{\PreprocessorTok}[1]{\textcolor[rgb]{0.74,0.48,0.00}{#1}}
|
||
\newcommand{\RegionMarkerTok}[1]{#1}
|
||
\newcommand{\SpecialCharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}}
|
||
\newcommand{\SpecialStringTok}[1]{\textcolor[rgb]{0.73,0.40,0.53}{#1}}
|
||
\newcommand{\StringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}}
|
||
\newcommand{\VariableTok}[1]{\textcolor[rgb]{0.10,0.09,0.49}{#1}}
|
||
\newcommand{\VerbatimStringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}}
|
||
\newcommand{\WarningTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}}
|
||
\setlength{\emergencystretch}{3em} % prevent overfull lines
|
||
\providecommand{\tightlist}{%
|
||
\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
|
||
\setcounter{secnumdepth}{5}
|
||
% Redefines (sub)paragraphs to behave more like sections
|
||
\ifx\paragraph\undefined\else
|
||
\let\oldparagraph\paragraph
|
||
\renewcommand{\paragraph}[1]{\oldparagraph{#1}\mbox{}}
|
||
\fi
|
||
\ifx\subparagraph\undefined\else
|
||
\let\oldsubparagraph\subparagraph
|
||
\renewcommand{\subparagraph}[1]{\oldsubparagraph{#1}\mbox{}}
|
||
\fi
|
||
|
||
% set default figure placement to htbp
|
||
\makeatletter
|
||
\def\fps@figure{htbp}
|
||
\makeatother
|
||
|
||
% Decent marging...
|
||
\usepackage[cm]{fullpage}
|
||
|
||
% Indentation for all paragraph (even the first one) + ventilate
|
||
\usepackage{indentfirst}
|
||
\setlength{\parskip}{6pt plus 2pt minus 1pt}
|
||
|
||
% Avoid vertical space before/after itemize
|
||
\usepackage{enumitem}
|
||
\setlist{nosep}
|
||
|
||
% Use sans-serif font for section' titles
|
||
\usepackage{sectsty}
|
||
\allsectionsfont{\sffamily \bfseries}
|
||
|
||
% Use sans-serif font for title page
|
||
\usepackage{titling}
|
||
\renewcommand{\maketitlehooka}{\sffamily}
|
||
|
||
% Use monospaced font for URLs
|
||
\urlstyle{tt}
|
||
|
||
% In french, list item starts with dash, not bullet
|
||
\renewcommand\labelitemi{---}
|
||
|
||
\usepackage{etoolbox}
|
||
|
||
\makeatletter
|
||
\pretocmd{\subsection}{\addtocontents{toc}{\protect\addvspace{-5\p@}}}{}{}
|
||
\pretocmd{\subsubsection}{\addtocontents{toc}{\protect\addvspace{-6\p@}}}{}{}
|
||
\makeatother
|
||
\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
|
||
\usepackage[shorthands=off,american,main=english]{babel}
|
||
\newcommand{\textenglish}[2][]{\foreignlanguage{american}{#2}}
|
||
\newenvironment{english}[2][]{\begin{otherlanguage}{american}}{\end{otherlanguage}}
|
||
\else
|
||
% load polyglossia as late as possible as it *could* call bidi if RTL lang (e.g. Hebrew or Arabic)
|
||
\usepackage{polyglossia}
|
||
\setmainlanguage[]{english}
|
||
\setotherlanguage[variant=american]{english}
|
||
\fi
|
||
|
||
\title{Virtualisation légère -- TP n\textsuperscript{o} 3}
|
||
\providecommand{\subtitle}[1]{}
|
||
\subtitle{Linux Internals partie 1}
|
||
\author{Pierre-Olivier \emph{nemunaire} \textsc{Mercier}}
|
||
\providecommand{\institute}[1]{}
|
||
\institute{EPITA}
|
||
\date{Mercredi 24 octobre 2018}
|
||
|
||
\begin{document}
|
||
\maketitle
|
||
\begin{abstract}
|
||
Ce premier TP consacré aux Linux Internals va nous permettre
|
||
d'appréhender les notions de pseudos systèmes de fichiers, de cgroups
|
||
ainsi que de capabilities.
|
||
|
||
\vspace{1em}
|
||
|
||
Certains éléments de ce TP sont à rendre à
|
||
\href{mailto:virli@nemunai.re}{\nolinkurl{virli@nemunai.re}} au plus
|
||
tard le mercredi 7 novembre 2018 à 12 h 42. Consultez la dernière
|
||
section de chaque partie pour plus d'information sur les éléments à
|
||
rendre.
|
||
|
||
En tant que personnes sensibilisées à la sécurité des échanges
|
||
électroniques, vous devrez m'envoyer vos rendus signés avec votre clef
|
||
PGP. Pensez à
|
||
\href{https://pgp.mit.edu/pks/lookup?op=vindex\&search=0x842807A84573CC96}{me}
|
||
faire signer votre clef et n'hésitez pas à
|
||
\href{https://www.meetup.com/fr/Paris-certification-de-cles-PGP-et-CAcert/}{faire
|
||
signer votre clef}.
|
||
\end{abstract}
|
||
|
||
\renewcommand*\contentsname{Sommaire}
|
||
{
|
||
\hypersetup{linkcolor=}
|
||
\setcounter{tocdepth}{3}
|
||
\tableofcontents
|
||
}
|
||
\newpage
|
||
|
||
\hypertarget{pruxe9requis}{%
|
||
\section{Prérequis}\label{pruxe9requis}}
|
||
|
||
\hypertarget{noyau-linux}{%
|
||
\subsection{Noyau Linux}\label{noyau-linux}}
|
||
|
||
Ce TP requiert un noyau Linux, dans sa version 3.8 au minimum. Il doit
|
||
de plus être compilé avec les options suivantes (lorsqu'elles sont
|
||
disponibles pour votre version) :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{verbatim}
|
||
General setup --->
|
||
[*] Control Group support --->
|
||
[*] Freezer cgroup subsystem
|
||
[*] PIDs cgroup subsystem
|
||
[*] Device controller for cgroups
|
||
[*] Cpuset support
|
||
[*] Simple CPU accounting cgroup subsystem
|
||
[*] Memory Resource Controller for Control Groups
|
||
[*] Group CPU scheduler --->
|
||
[*] Group scheduling for SCHED_OTHER
|
||
[*] Group scheduling for SCHED_RR/FIFO
|
||
<*> Block IO controller
|
||
[*] Networking support --->
|
||
Networking options --->
|
||
[*] Network priority cgroup
|
||
[*] Network classid cgroup
|
||
\end{verbatim}
|
||
|
||
\end{english}
|
||
|
||
\hypertarget{vuxe9rification-via-menuconfig}{%
|
||
\subsubsection{\texorpdfstring{Vérification via
|
||
\texttt{menuconfig}}{Vérification via menuconfig}}\label{vuxe9rification-via-menuconfig}}
|
||
|
||
L'arbre ci-dessous correspond aux options qui seront \emph{built-in}
|
||
(signalées par une \texttt{*}) ou installées en tant que module
|
||
(signalées par un \texttt{M}). En effet, chaque noyau Linux peut être
|
||
entièrement personnalisé en fonction des options et des pilotes que l'on
|
||
voudra utiliser.
|
||
|
||
Pour parcourir l'arbre des options du noyau, il est nécessaire d'avoir
|
||
les sources de celui-ci. Les dernières versions stables et encore
|
||
maintenues sont disponibles sur la page d'accueil de
|
||
\url{https://kernel.org}.
|
||
|
||
Dans les sources, on affiche la liste des options avec la commande :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\FunctionTok{make}\NormalTok{ menuconfig}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
\hypertarget{vuxe9rification-via-bootconfig-xxx}{%
|
||
\subsubsection{\texorpdfstring{Vérification via
|
||
\texttt{/boot/config-xxx}}{Vérification via /boot/config-xxx}}\label{vuxe9rification-via-bootconfig-xxx}}
|
||
|
||
Les distributions basées sur Debian ont pour habitude de placer le
|
||
fichier de configuration ayant servi à compiler le noyau et ses modules
|
||
dans le dossier \texttt{/boot}, aux côtés de l'image du noyau
|
||
\texttt{vmlinuz-xxx}, de l'éventuel système de fichiers initial
|
||
(\texttt{initramfs-xxx}) et des symboles de débogage
|
||
\texttt{System.map-xxx}.
|
||
|
||
Ce fichier répertorie toutes les options qui ont été activées. Par
|
||
rapport à l'arbre présenté ci-dessus, vous devriez trouver :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{verbatim}
|
||
CONFIG_CGROUPS=y
|
||
CONFIG_CGROUP_FREEZER=y
|
||
CONFIG_CGROUP_PIDS=y
|
||
CONFIG_CGROUP_DEVICE=y
|
||
CONFIG_CPUSETS=y
|
||
CONFIG_CGROUP_CPUACCT=y
|
||
CONFIG_CGROUP_MEMCG=y
|
||
CONFIG_CGROUP_SCHED=y
|
||
CONFIG_BLK_CGROUP=y
|
||
|
||
CONFIG_NET=y
|
||
CONFIG_CGROUP_NET_PRIO=y
|
||
CONFIG_CGROUP_NET_CLASSID=y
|
||
\end{verbatim}
|
||
|
||
\end{english}
|
||
|
||
\hypertarget{vuxe9rification-via-procconfig.gz}{%
|
||
\subsubsection{\texorpdfstring{Vérification via
|
||
\texttt{/proc/config.gz}}{Vérification via /proc/config.gz}}\label{vuxe9rification-via-procconfig.gz}}
|
||
|
||
Dans la plupart des autres distributions, la configuration est
|
||
accessible à travers le fichier \texttt{/proc/config.gz}. Comme vous ne
|
||
pouvez pas écrire dans \texttt{/proc} pour décompresser le fichier,
|
||
utilisez les outils \texttt{zcat}, \texttt{zgrep}, \ldots{}
|
||
|
||
Vous devez retrouver les mêmes options que celles de la section
|
||
précédente.
|
||
|
||
\hypertarget{pruxe9sence-des-en-tuxeates}{%
|
||
\subsection{Présence des en-têtes}\label{pruxe9sence-des-en-tuxeates}}
|
||
|
||
Si vous utilisez un noyau standard fourni par votre distribution, les
|
||
options requises seront a priori déjà sélectionnées et vous n'aurez donc
|
||
pas à compiler votre propre noyau. Néanmoins, durant ce TP, nous allons
|
||
nous interfacer avec le noyau, il est donc nécessaire d'avoir les
|
||
en-têtes de votre noyau.
|
||
|
||
Sous Debian, vous pouvez les installer via le paquet au nom semblable à
|
||
\texttt{linux-headers}.
|
||
|
||
\newpage
|
||
|
||
\hypertarget{lisolation-du-pauvre}{%
|
||
\section{L'isolation \ldots{} du pauvre}\label{lisolation-du-pauvre}}
|
||
|
||
Depuis les premières versions d'Unix, il est possible de changer le
|
||
répertoire vu comme étant la racine du système de fichiers. En anglais :
|
||
\emph{change root}: \texttt{chroot}. Le processus effectuant cette
|
||
action ainsi que tous ses fils, verront donc une racine différente du
|
||
reste du système.
|
||
|
||
\hypertarget{mise-en-place-de-lenvironnement}{%
|
||
\subsection{Mise en place de
|
||
l'environnement}\label{mise-en-place-de-lenvironnement}}
|
||
|
||
Pour se créer un environnement afin de changer notre racine, il va
|
||
falloir commencer par créer le dossier de notre nouvelle racine :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\FunctionTok{mkdir}\NormalTok{ newroot}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
\hypertarget{busybox}{%
|
||
\subsubsection{\texorpdfstring{\texttt{busybox}}{busybox}}\label{busybox}}
|
||
|
||
Queques mots, pour commencer, à propos du projet Busybox : c'est un
|
||
programme \emph{linké} statiquement, c'est-à-dire qu'il ne va pas
|
||
chercher ni charger de bibliothèque dynamique à son lancement. Il se
|
||
suffit donc à lui-même dans un \emph{chroot}, car il n'a pas de
|
||
dépendances. Nous pouvons donc tester notre première isolation~:
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\FunctionTok{cp} \VariableTok{$(}\FunctionTok{which}\NormalTok{ busybox}\VariableTok{)}\NormalTok{ newroot/}
|
||
\FunctionTok{chroot}\NormalTok{ newroot /busybox ash}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
Jusque là \ldots{} ça fonctionne, rien de surprenant ! Mais qu'en est-il
|
||
pour \texttt{bash} :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\ExtensionTok{42sh}\NormalTok{$ cp }\VariableTok{$(}\FunctionTok{which}\NormalTok{ bash}\VariableTok{)}\NormalTok{ newroot/}
|
||
\ExtensionTok{42sh}\NormalTok{# chroot newroot /bash}
|
||
\ExtensionTok{chroot}\NormalTok{: failed to run command ‘bash’: No such file or directory}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
De quel fichier est-il question ici ?
|
||
|
||
\hypertarget{debootstrap}{%
|
||
\subsubsection{\texorpdfstring{\texttt{debootstrap}}{debootstrap}}\label{debootstrap}}
|
||
|
||
\texttt{debootstrap} est le programme utilisé par l'installeur des
|
||
distributions Debian et ses dérivées. Il permet d'installer dans un
|
||
dossier (en général, ce dossier correspond au point de montage de la
|
||
nouvelle racine choisie par l'utilisateur lors de l'installation) le
|
||
système de base.
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\ExtensionTok{debootstrap}\NormalTok{ jessie newroot/ http://httpredir.debian.org/debian/}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
\texttt{pacstrap} est le programme équivalent pour Archlinux.
|
||
|
||
\hypertarget{stage3}{%
|
||
\subsubsection{\texorpdfstring{\emph{stage3}}{stage3}}\label{stage3}}
|
||
|
||
Les distributions \emph{à l'ancienne} proposent encore de télécharger
|
||
leur système de base sous forme de tarball~:
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\FunctionTok{wget}\NormalTok{ http://gentoo.mirrors.ovh.net/gentoo-distfiles/releases/amd64/autobuilds/current-stage3-amd64/stage3-amd64-20181021T214502Z.tar.xz}
|
||
\FunctionTok{tar}\NormalTok{ xpf stage3-amd64-*.tar.xz -C newroot/}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
L'avantage de télécharger l'archive de Gentoo est que l'on a déjà
|
||
\texttt{gcc} dans un environnement qui tient dans 300 MB.
|
||
|
||
\hypertarget{exercice}{%
|
||
\subsection*{Exercice}\label{exercice}}
|
||
\addcontentsline{toc}{subsection}{Exercice}
|
||
|
||
Écrivons maintenant un programme dont le seul but est de s'échapper du
|
||
\texttt{chroot} :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\FunctionTok{make}\NormalTok{ escape}
|
||
\BuiltInTok{echo}\NormalTok{ bar }\OperatorTok{>}\NormalTok{ ../foo}
|
||
\FunctionTok{chroot}\NormalTok{ .}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
Dans le nouvel environnement, vous ne devriez pas pouvoir faire :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\FunctionTok{cat}\NormalTok{ ../foo}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
Mais une fois votre programme \texttt{escape} exécuté, vous devriez
|
||
pouvoir !
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{verbatim}
|
||
(chroot) 42sh# ./escape
|
||
bash# cat /path/to/foo
|
||
\end{verbatim}
|
||
|
||
\end{english}
|
||
|
||
\newpage
|
||
|
||
\hypertarget{pseudos-systuxe8mes-de-fichiers}{%
|
||
\section{Pseudos systèmes de
|
||
fichiers}\label{pseudos-systuxe8mes-de-fichiers}}
|
||
|
||
\hypertarget{rappels-sur-les-points-de-montage}{%
|
||
\subsection{Rappels sur les points de
|
||
montage}\label{rappels-sur-les-points-de-montage}}
|
||
|
||
Les systèmes Unix définissent le système de fichiers comme étant un
|
||
arbre unique partant d'une racine\footnote{Consultez
|
||
\url{https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard} pour
|
||
plus de détails sur l'arboresence.} et où l'on peut placer au sein de
|
||
son arborescence des points de montage. Ainsi, l'utilisateur définit
|
||
généralement deux points de montage :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{verbatim}
|
||
/dev/sda1 on / type ext4 (rw,relatime,data=ordered)
|
||
/dev/sda3 on /home type ext4 (rw,relatime,data=ordered)
|
||
\end{verbatim}
|
||
|
||
\end{english}
|
||
|
||
Dans ce schéma, la racine correspond à la première partition du premier
|
||
disque, et les fichiers des utilisateurs sont sur la troisième partition
|
||
du premier disque.
|
||
|
||
\hypertarget{pruxe9sentation-des-pseudos-systuxe8mes-de-fichiers}{%
|
||
\subsection{Présentation des pseudos systèmes de
|
||
fichiers}\label{pruxe9sentation-des-pseudos-systuxe8mes-de-fichiers}}
|
||
|
||
D'autres points de montage sont utilisés par le système : \texttt{/dev},
|
||
\texttt{/proc}, \texttt{/tmp}, \ldots{} Ces points de montage vont, la
|
||
plupart du temps, être montés par le programme d'initialisation en
|
||
utilisant des systèmes de fichiers virtuels, mis à disposition par le
|
||
noyau.
|
||
|
||
Ces systèmes sont virtuels, car ils ne correspondent à aucune partition
|
||
d'aucun disque : l'arborescence est créée de toute pièce par le noyau
|
||
pour trier les informations mises à disposition, mais il n'est pas
|
||
toujours possible d'y apporter des modifications.
|
||
|
||
Linux emploie de nombreux systèmes de fichiers virtuels :
|
||
|
||
\begin{itemize}
|
||
\tightlist
|
||
\item
|
||
\texttt{/proc} : contient, principalement, la liste des processus
|
||
(\texttt{top} et ses dérivés se contentent de lire les fichiers de ce
|
||
point de montage) ;
|
||
\item
|
||
\texttt{/proc/sys} : contient la configuration du noyau ;
|
||
\item
|
||
\texttt{/sys} : contient des informations à propos du matériel
|
||
(utilisées notamment par \texttt{udev} pour peupler \texttt{/dev}) et
|
||
des périphériques (taille des tampons, clignottement des DELs,
|
||
\ldots{}) ;
|
||
\item
|
||
\texttt{/sys/firmware/efi/efivars} : pour accéder et modifier les
|
||
variables de l'UEFI ;
|
||
\item
|
||
\ldots{}
|
||
\end{itemize}
|
||
|
||
Tous ces systèmes de fichiers sont généralement exclusivement stockés en
|
||
RAM. Pour rendre une modification persistante, il est nécessaire de
|
||
modifier un fichier de configuration qui sera chargé par le programme
|
||
d'initialisation. Par exemple, pour modifier les paramètres du noyau, on
|
||
passe par le fichier \texttt{/etc/sysctl.conf} et du programme
|
||
\texttt{sysctl}.
|
||
|
||
\hypertarget{consultation-et-modification}{%
|
||
\subsubsection{Consultation et
|
||
modification}\label{consultation-et-modification}}
|
||
|
||
La consultation d'un élément se fait généralement à l'aide d'un simple
|
||
\texttt{cat} :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{verbatim}
|
||
42sh$ cat /sys/power/state
|
||
freeze mem
|
||
\end{verbatim}
|
||
|
||
\end{english}
|
||
|
||
La modification d'un élément se fait avec \texttt{echo}, comme ceci :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\ExtensionTok{42sh}\NormalTok{# echo mem }\OperatorTok{>}\NormalTok{ /sys/power/state}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
Vous devriez constater l'effet de cette commande sans plus attendre !
|
||
|
||
\hypertarget{exercices}{%
|
||
\subsection{Exercices}\label{exercices}}
|
||
|
||
\hypertarget{procinfo}{%
|
||
\subsubsection{\texorpdfstring{\texttt{procinfo}}{procinfo}}\label{procinfo}}
|
||
|
||
Explorons le pseudo système de fichiers \texttt{/proc} pour écrire un
|
||
script qui va afficher des informations sur un processus donné :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{verbatim}
|
||
42sh$ ./procinfo $$
|
||
PID: 4242
|
||
Path: /bin/bash
|
||
Command line: bash
|
||
Working directory: /home/nemunaire/virli/
|
||
Root: /
|
||
State: S (sleeping)
|
||
Threads: 1
|
||
|
||
CGroups
|
||
=======
|
||
12:pids:/
|
||
11:net_prio:/
|
||
10:perf_event:/
|
||
9:net_cls:/
|
||
8:freezer:/
|
||
7:devices:/
|
||
6:memory:/
|
||
5:blkio:/
|
||
4:cpuacct:/
|
||
3:cpu:/
|
||
2:cpuset:/
|
||
1:name=openrc:/
|
||
|
||
Namespaces
|
||
==========
|
||
cgroup:[4026531835]
|
||
ipc:[4026531839]
|
||
mnt:[4026531840]
|
||
net:[4026531969]
|
||
pid:[4026531836]
|
||
user:[4026531837]
|
||
uts:[4026531838]
|
||
\end{verbatim}
|
||
|
||
\end{english}
|
||
|
||
\hypertarget{rev_kdb_leds.sh-batinfo.sh-cpuinfo.sh}{%
|
||
\subsubsection{\texorpdfstring{\texttt{rev\_kdb\_leds.sh},
|
||
\texttt{batinfo.sh},
|
||
\texttt{cpuinfo.sh}}{rev\_kdb\_leds.sh, batinfo.sh, cpuinfo.sh}}\label{rev_kdb_leds.sh-batinfo.sh-cpuinfo.sh}}
|
||
|
||
Explorons le pseudo système de fichiers \texttt{/sys} pour écrire un
|
||
script qui va, en fonction de ce que vous avez de disponible :
|
||
|
||
\begin{itemize}
|
||
\tightlist
|
||
\item
|
||
inverser l'état des diodes de notre clavier ;
|
||
\item
|
||
nous afficher des statistiques sur notre batterie ;
|
||
\item
|
||
nous afficher des statistiques la fréquence de notre CPU.
|
||
\end{itemize}
|
||
|
||
\hypertarget{rev_kdb_leds.sh}{%
|
||
\paragraph{\texorpdfstring{\texttt{rev\_kdb\_leds.sh}}{rev\_kdb\_leds.sh}}\label{rev_kdb_leds.sh}}
|
||
|
||
Si vous avez :
|
||
|
||
\begin{itemize}
|
||
\tightlist
|
||
\item
|
||
numlock On,
|
||
\item
|
||
capslock Off,
|
||
\item
|
||
scrolllock Off ;
|
||
\end{itemize}
|
||
|
||
Après avoir exécuté le script, nous devrions avoir :
|
||
|
||
\begin{itemize}
|
||
\tightlist
|
||
\item
|
||
numlock Off,
|
||
\item
|
||
capslock On,
|
||
\item
|
||
scrolllock On.
|
||
\end{itemize}
|
||
|
||
Voici un exemple d'utilisation :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{verbatim}
|
||
42sh$ ./rev_kdb_leds.sh input20
|
||
\end{verbatim}
|
||
|
||
\end{english}
|
||
|
||
\hypertarget{batinfo.sh}{%
|
||
\paragraph{\texorpdfstring{\texttt{batinfo.sh}}{batinfo.sh}}\label{batinfo.sh}}
|
||
|
||
Voici un exemple d'utilisation :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{verbatim}
|
||
42sh$ ./batinfo.sh
|
||
BAT0 Discharging
|
||
====
|
||
Capacity: 83% (Normal)
|
||
Voltage: 11.972000 V (minimal: 11.400000 V)
|
||
Energy: 18.290000/21.830000 Wh
|
||
Power: 7.937000 W
|
||
Remaining time: 2.304 h
|
||
|
||
BAT1 Unknown
|
||
====
|
||
Capacity: 83% (Normal)
|
||
Voltage: 11.972000 V (minimal: 11.400000 V)
|
||
Energy: 18.290000/21.830000 Wh
|
||
Power: 0.0 W
|
||
Remaining time: N/A
|
||
\end{verbatim}
|
||
|
||
\end{english}
|
||
|
||
\hypertarget{cpuinfo.sh}{%
|
||
\paragraph{\texorpdfstring{\texttt{cpuinfo.sh}}{cpuinfo.sh}}\label{cpuinfo.sh}}
|
||
|
||
Voici un exemple d'utilisation :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{verbatim}
|
||
42sh$ ./cpuinfo.sh
|
||
cpu0
|
||
====
|
||
Current frequency: 2100384 Hz
|
||
Current governor: powersave
|
||
Allowed frequencies: between 500000 - 2100000 Hz
|
||
Thermal throttle count: 0
|
||
|
||
cpu1
|
||
====
|
||
Current frequency: 2099871 Hz
|
||
Current governor: powersave
|
||
Allowed frequencies: between 500000 - 2100000 Hz
|
||
Thermal throttle count: 0
|
||
\end{verbatim}
|
||
|
||
\end{english}
|
||
|
||
N'hésitez pas à rajouter toute sorte d'information intéressantes !
|
||
|
||
\newpage
|
||
|
||
\hypertarget{les-capabilities}{%
|
||
\section{\texorpdfstring{Les
|
||
\emph{capabilities}}{Les capabilities}}\label{les-capabilities}}
|
||
|
||
\hypertarget{pruxe9sentation}{%
|
||
\subsection{Présentation}\label{pruxe9sentation}}
|
||
|
||
Historiquement, dans la tradition UNIX, on distinguait deux catégories
|
||
de processus :
|
||
|
||
\begin{itemize}
|
||
\tightlist
|
||
\item
|
||
les processus \emph{privilégiés} : dont l'identifiant de son
|
||
utilisateur est 0 ;
|
||
\item
|
||
les processus \emph{non-privilégiés} : dont l'identifiant de son
|
||
utilisateur n'est pas 0.
|
||
\end{itemize}
|
||
|
||
Lors des différents tests de permission fait par le noyau, les processus
|
||
privilégiés outrepassaient ces tests, tandis que les autres devaient
|
||
passer les tests de l'effective UID, effective GID, et autres groupes
|
||
supplémentaires\ldots{}
|
||
|
||
Depuis Linux 2.2 (en 1998), les processus privilégiés peuvent activer ou
|
||
désactiver des \emph{capabilities}, chacune donnant accès à un groupe
|
||
d'actions privilégiées au sein du noyau.
|
||
|
||
On trouve par exemple :
|
||
|
||
\begin{itemize}
|
||
\tightlist
|
||
\item
|
||
\texttt{CAP\_CHOWN} : permet de modifier le propriétaire d'un fichier
|
||
de manière arbitraire ;
|
||
\item
|
||
\texttt{CAP\_KILL} : permet de tuer n'importe quel processus ;
|
||
\item
|
||
\texttt{CAP\_SYS\_BOOT} : permet d'arrêter ou de redémarrer la machine
|
||
;
|
||
\item
|
||
\texttt{CAP\_SYS\_MODULE} : permet de charger et décharger des modules
|
||
;
|
||
\item
|
||
et beaucoup d'autres, il y en a environ 39 en tout (ça dépend de la
|
||
version du noyau) !
|
||
\end{itemize}
|
||
|
||
\hypertarget{ping}{%
|
||
\subsubsection{\texorpdfstring{\texttt{ping}}{ping}}\label{ping}}
|
||
|
||
Pour émettre un ping, il est nécessaire d'envoyer des paquets ICMP. À la
|
||
différence des datagrammes UDP ou des segments TCP, il n'existe pas
|
||
d'interface exposée par le noyau aux utilisateurs pour envoyer des
|
||
paquets ICMP. Pour le faire, il est nécessaire de pouvoir écrire
|
||
directement sur l'interface ; ça, seul le super-utilisateur peut le
|
||
faire.
|
||
|
||
Pour permettre à tous les utilisateurs de pouvoir envoyer des ping, le
|
||
programme est donc généralement \emph{Setuid root}. Cela permet à
|
||
n'importe quel utilisateur de prendre les droits du super-utilisateur,
|
||
le temps de l'exécution du programme.
|
||
|
||
Les problèmes surviennent lorsque l'on découvre des vulnérabilités dans
|
||
les programmes \emph{Setuid root}. En effet, s'il devient possible pour
|
||
un utilisateur d'exécuter du code arbitraire, ce code sera exécuté avec
|
||
les privilèges de l'utilisateur \emph{root} ! Dans le cas de
|
||
\texttt{ping}, on se retrouverait alors à pouvoir lire l'intégralité de
|
||
la mémoire, alors que l'on avait juste besoin d'écrire sur une interface
|
||
réseau.
|
||
|
||
C'est donc à ce moment que les \emph{capabilities} entrent en jeu : un
|
||
processus (ou même un thread) privilégié peut décider, généralement à
|
||
son lancement, de réduire ses \emph{capabilities}, pour ne garder que
|
||
celles dont il a réellement besoin. Ainsi, \texttt{ping} pourrait se
|
||
contenter de \texttt{CAP\_NET\_RAW}.
|
||
|
||
\hypertarget{les-attributs-de-fichier-uxe9tendus}{%
|
||
\subsection{Les attributs de fichier
|
||
étendus}\label{les-attributs-de-fichier-uxe9tendus}}
|
||
|
||
Une grosse majorité des systèmes de fichiers (ext{[}234{]}, XFS, btrfs,
|
||
\ldots{}) permet d'enregistrer, pour chaque fichier, des attributs (dits
|
||
attributs \emph{étendus}, par opposition aux attributs \emph{réguliers}
|
||
qui sont réservés à l'usage du système de fichiers).
|
||
|
||
Sous Linux, les attributs sont regroupés dans des espaces de noms :
|
||
|
||
\begin{itemize}
|
||
\tightlist
|
||
\item
|
||
\emph{security} : espace utilisé par les modules de sécurité du noyau,
|
||
tel que SELinux, \ldots{} ;
|
||
\item
|
||
\emph{system} : espace utilisé par le noyau pour stocker des objets
|
||
système, tels que les ACL POSIX ;
|
||
\item
|
||
\emph{trusted}: espace dont la lecture et l'écriture est limité au
|
||
super-utilisateur ;
|
||
\item
|
||
\emph{user} : modifiable sans restriction, à partir du moment où l'on
|
||
est le propriétaire du fichier.
|
||
\end{itemize}
|
||
|
||
Par exemple, on peut définir un attribut sur un fichier comme cela :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\ExtensionTok{42sh}\NormalTok{$ echo }\StringTok{'Hello World!'} \OperatorTok{>}\NormalTok{ toto}
|
||
\ExtensionTok{42sh}\NormalTok{$ setfattr -n user.foo -v bar toto}
|
||
\ExtensionTok{42sh}\NormalTok{$ getfattr -d toto}
|
||
\CommentTok{# file: toto}
|
||
\ExtensionTok{user.foo}\NormalTok{=}\StringTok{"bar"}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
Encore plus fort, vous pouvez utiliser les ACL POSIX :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\ExtensionTok{42sh}\NormalTok{$ sudo chown root:root toto }\KeywordTok{&&} \FunctionTok{sudo}\NormalTok{ chmod o-r toto}
|
||
\ExtensionTok{42sh}\NormalTok{$ cat toto}
|
||
\ExtensionTok{cat}\NormalTok{: toto: Permission denied}
|
||
\ExtensionTok{42sh}\NormalTok{$ sudo setfattr -m u:}\VariableTok{$USER}\NormalTok{:r toto}
|
||
\ExtensionTok{42sh}\NormalTok{$ cat toto}
|
||
\ExtensionTok{Hello}\NormalTok{ World!}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
Bien que les droits UNIX traditionnels ne vous donnent pas accès au
|
||
fichier, les ACL POSIX vous autorisent à le lire.
|
||
|
||
Vous pouvez voir ces attributs avec la commande :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\ExtensionTok{42sh}\NormalTok{$ getfattr -d -m }\StringTok{"^system"}\NormalTok{ toto}
|
||
\CommentTok{# file: toto}
|
||
\ExtensionTok{system.posix_acl_access}\NormalTok{=0sgAAEAD/////AgAEOgDAEAA/////xAABAD////8=}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
\hypertarget{ping-1}{%
|
||
\subsubsection{\texorpdfstring{\texttt{ping}}{ping}}\label{ping-1}}
|
||
|
||
De la même manière que l'on peut définir de façon plus fine les droits
|
||
d'accès par utilisateur, un attribut de l'espace de nom \emph{security}
|
||
peut être défini pour accroître les \emph{capabilities} d'un processus
|
||
lorsqu'il est lancé par un utilisateur non-privilégié. On peut alors
|
||
voir le Setuid root comme l'utilisation de cet attribut auquel on
|
||
accroîtrait l'ensemble des \emph{capabilities}.
|
||
|
||
Si votre distribution profite de ces attributs étendus, vous devriez
|
||
obtenir :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\ExtensionTok{42sh}\NormalTok{$ getfattr -d -m }\StringTok{"^security"} \VariableTok{$(}\FunctionTok{which}\NormalTok{ ping}\VariableTok{)}
|
||
\CommentTok{# file: bin/ping}
|
||
\ExtensionTok{security.capability}\NormalTok{=0sAQAAAgAgAAAAAAAAAAAAAAAAAAA=}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
Ou, dans sa version plus lisible :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\ExtensionTok{42sh}\NormalTok{$ getcap }\VariableTok{$(}\FunctionTok{which}\NormalTok{ ping}\VariableTok{)}
|
||
\ExtensionTok{/bin/ping}\NormalTok{ = cap_net_raw+ep}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
\hypertarget{exercice-visualisateur-de-capabilities-dun-processus}{%
|
||
\subsection{Exercice : visualisateur de capabilities d'un
|
||
processus}\label{exercice-visualisateur-de-capabilities-dun-processus}}
|
||
|
||
Écrivons maintenant un programme permettant de voir les
|
||
\emph{capabilities} d'un processus :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{verbatim}
|
||
42sh$ ./view_caps 1
|
||
cap_user_header_t
|
||
-----------------
|
||
Version: 20080522
|
||
PID: 1
|
||
|
||
cap_user_data_t
|
||
---------------
|
||
effective: 0x3fffffffff
|
||
CAP_AUDIT_CONTROL
|
||
CAP_AUDIT_READ
|
||
[...]
|
||
CAP_SYS_TIME
|
||
CAP_SYS_TTY_CONFIG
|
||
CAP_SYSLOG
|
||
CAP_WAKE_ALARM
|
||
permitted: 0x3fffffffff
|
||
CAP_AUDIT_CONTROL
|
||
CAP_AUDIT_READ
|
||
[...]
|
||
CAP_SYS_TIME
|
||
CAP_SYS_TTY_CONFIG
|
||
CAP_SYSLOG
|
||
CAP_WAKE_ALARM
|
||
inheritable: 0x0
|
||
\end{verbatim}
|
||
|
||
\end{english}
|
||
|
||
Astuces : \texttt{capget(2)}, X-macros, \ldots{}
|
||
|
||
\hypertarget{pour-aller-plus-loin}{%
|
||
\subsection*{Pour aller plus loin}\label{pour-aller-plus-loin}}
|
||
\addcontentsline{toc}{subsection}{Pour aller plus loin}
|
||
|
||
Je vous recommande la lecture des \emph{man} suivants :
|
||
|
||
\begin{itemize}
|
||
\tightlist
|
||
\item
|
||
\texttt{capabilities(7)} : énumérant tous les capabilities, leur
|
||
utilisation, etc. ;
|
||
\item
|
||
\texttt{xattrs(7)} : à propos des attributs étendus.
|
||
\end{itemize}
|
||
|
||
Et de ces quelques articles :
|
||
|
||
\begin{itemize}
|
||
\tightlist
|
||
\item
|
||
\href{https://rhelblog.redhat.com/2016/10/17/secure-your-containers-with-this-one-weird-trick/}{Secure
|
||
Your Containers with this One Weird Trick}
|
||
\item
|
||
\href{https://www.freedesktop.org/wiki/CommonExtendedAttributes/}{Guidelines
|
||
for extended attributes}
|
||
\item
|
||
\href{https://lwn.net/Articles/211883/}{File-based capabilities}
|
||
\item
|
||
\href{https://lwn.net/Articles/199004/}{A bid to resurrect Linux
|
||
capabilities}
|
||
\item
|
||
\href{https://forums.grsecurity.net/viewtopic.php?f=7\&t=2522\&sid=c6fbcf62fd5d3472562540a7e608ce4e\#p10271}{False
|
||
Boundaries and Arbitrary Code Execution}
|
||
\end{itemize}
|
||
|
||
Pour revenir à Docker, par défaut, un certain nombre de
|
||
\emph{capabilities} sont désactivées par défaut ; vous pouvez en ajouter
|
||
et en retirer via les arguments \texttt{-\/-cap-add} et
|
||
\texttt{-\/-cap-drop} du \texttt{docker\ container\ run}.
|
||
|
||
\newpage
|
||
|
||
\hypertarget{utiliser-les-cgroups}{%
|
||
\section{\texorpdfstring{Utiliser les
|
||
\emph{cgroup}s}{Utiliser les cgroups}}\label{utiliser-les-cgroups}}
|
||
|
||
Les \emph{cgroup}s (pour \emph{Control Group}s) permettent de collecter
|
||
des statistiques sur des groupes de processus (appelés tâches) et de
|
||
leur attribuer des propriétés. Par exemple, il est possible leur imposer
|
||
des limites d'utilisation de ressources ou d'altérer leur comportement.
|
||
|
||
\hypertarget{premiers-tests}{%
|
||
\subsection{Premiers tests}\label{premiers-tests}}
|
||
|
||
Nous allons commencer par faire quelques tests avec le \emph{cgroup}
|
||
\emph{freezer}, qui permet d'interrompre l'exécution d'un groupe de
|
||
processus et de la reprendre.
|
||
|
||
\hypertarget{montage-du-cgroup}{%
|
||
\subsubsection{\texorpdfstring{Montage du
|
||
\emph{cgroup}}{Montage du cgroup}}\label{montage-du-cgroup}}
|
||
|
||
En fonction de la configuration de votre système, il est possible que
|
||
les \emph{cgroup}s ne soient pas montés au démarrage dans
|
||
\texttt{/sys/fs/cgroup/}. Si vous n'avez pas de dossier \texttt{freezer}
|
||
ou si celui-ci est vide, montez-le en suivant la procédure suivante :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\FunctionTok{mkdir}\NormalTok{ /sys/fs/cgroup/freezer/}
|
||
\FunctionTok{mount}\NormalTok{ -t cgroup -o freezer none /sys/fs/cgroup/freezer/}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
Cette dernière commande monte l'arborescence de groupes relative à ce
|
||
\emph{cgroup} \emph{freezer}. Tous les dossiers contenus dans cette
|
||
racine sont donc des sous-groupes.
|
||
|
||
\hypertarget{cruxe9ation-dun-nouveau-groupe}{%
|
||
\subsubsection{Création d'un nouveau
|
||
groupe}\label{cruxe9ation-dun-nouveau-groupe}}
|
||
|
||
La première étape dans l'utilisation d'un \emph{cgroup} est de créer un
|
||
groupe.
|
||
|
||
Pour ce faire, il suffit de créer un nouveau dossier dans un groupe
|
||
existant, par exemple la racine :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\FunctionTok{mkdir}\NormalTok{ /sys/fs/cgroup/freezer/virli/}
|
||
\FunctionTok{ls}\NormalTok{ /sys/fs/cgroup/freezer/virli/}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
Nous avons maintenant un nouveau groupe de processus \texttt{virli} dans
|
||
le \emph{cgroup} \emph{Freezer}. Comme il s'agit d'une hiérarchie, le
|
||
groupe \texttt{virli} hérite des propriétés de son (ses) père(s).
|
||
|
||
\hypertarget{rattachement-de-processus}{%
|
||
\subsubsection{Rattachement de
|
||
processus}\label{rattachement-de-processus}}
|
||
|
||
Pour le moment, ce nouveau groupe ne contient aucune tâche.
|
||
|
||
Ouvrons un nouveau terminal (c'est lui que l'on va geler), et récupérons
|
||
son PID : \texttt{echo\ \$\$}.
|
||
|
||
La liste des processus rattachés à un \emph{cgroup} se trouve dans le
|
||
fichier \texttt{task} du groupe. Pour ajouter une tâche à ce groupe,
|
||
cela se passe de cette manière :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\BuiltInTok{echo} \VariableTok{$PID} \OperatorTok{>}\NormalTok{ /sys/fs/cgroup/freezer/virli/tasks}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
Il faut ici remplacer \texttt{\$PID} par le PID du shell que l'on a
|
||
relevé juste avant.
|
||
|
||
En validant cette commande, nous avons déplacé le processus dans ce
|
||
groupe, il n'est alors plus dans aucun autre groupe (pour ce
|
||
\emph{cgroup}, il ne bouge pas dans les autres \emph{cgroup}s).
|
||
|
||
Malgré l'utilisation de la redirection \texttt{\textgreater{}} (et non
|
||
\texttt{\textgreater{}\textgreater{}}), il s'agit belle et bien d'un
|
||
ajout au fichier et non d'un écrasement. Il faut garder en tête que le
|
||
système de fichier est entièrement simulé et que certains comportements
|
||
sont adaptés.
|
||
|
||
\hypertarget{consultation-de-luxe9tat}{%
|
||
\subsubsection{Consultation de l'état}\label{consultation-de-luxe9tat}}
|
||
|
||
En affichant le contenu du dossier \texttt{virli}, nous pouvions
|
||
constater que celui-ci contenait déjà un certain nombre de fichiers.
|
||
Certain d'entre-eux sont en lecture seule et permettent de lire des
|
||
statistiques instantanées sur le groupe ; tandis que d'autres sont des
|
||
propriétés que nous pouvons modifier.
|
||
|
||
Nous pouvons consulter l'état de gel du groupe en affichant le contenu
|
||
du fichier\newline \texttt{/sys/fs/cgroup/freezer/virli/freezer.state}.
|
||
|
||
Pour plus d'information sur les différents fichiers présents dans ce
|
||
\emph{cgroup}, consultez
|
||
\href{https://www.kernel.org/doc/Documentation/cgroup-v1/freezer-subsystem.txt}{la
|
||
documentation associée}.
|
||
|
||
\hypertarget{changement-duxe9tat}{%
|
||
\subsubsection{Changement d'état}\label{changement-duxe9tat}}
|
||
|
||
Faisons exécuter à notre interpréteur une commande pour voir
|
||
effectivement l'exécution s'arrêter. Si vous manquez d'inspiration,
|
||
utilisez :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\KeywordTok{for} \ExtensionTok{i}\NormalTok{ in }\VariableTok{$(}\FunctionTok{seq}\NormalTok{ 9999}\VariableTok{)}\KeywordTok{;} \KeywordTok{do} \BuiltInTok{echo}\NormalTok{ -n }\VariableTok{$i}\KeywordTok{;} \FunctionTok{sleep}\NormalTok{ .1}\KeywordTok{;} \BuiltInTok{echo}\NormalTok{ -n }\StringTok{" - "}\KeywordTok{;} \FunctionTok{sleep}\NormalTok{ .1}\KeywordTok{;} \KeywordTok{done}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
Maintenant, nous avons donné l'ordre au noyau de ne plus allouer de
|
||
temps de calcul à notre shell et ses fils :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\BuiltInTok{echo}\NormalTok{ FROZEN }\OperatorTok{>}\NormalTok{ /sys/fs/cgroup/freezer/virli/freezer.state}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
À cet instant, vous devriez voir votre compteur s'arrêter. Pour
|
||
reprendre l'exécution :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\BuiltInTok{echo}\NormalTok{ THAWED }\OperatorTok{>}\NormalTok{ /sys/fs/cgroup/freezer/virli/freezer.state}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
\hypertarget{exercice-script-de-monitoring}{%
|
||
\subsection{Exercice : script de
|
||
monitoring}\label{exercice-script-de-monitoring}}
|
||
|
||
À nous maintenant de concevoir un script qui va enregistrer vers une
|
||
base de données des statistiques issues des \emph{cgroup}s.
|
||
|
||
\hypertarget{rappel-dinfluxdb}{%
|
||
\subsubsection{Rappel d'InfluxDB}\label{rappel-dinfluxdb}}
|
||
|
||
Commençons par lancer le conteneur Docker d'InfluxDB (pour éviter de
|
||
l'installer sur notre machine) :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\ExtensionTok{docker}\NormalTok{ container run --name mytsdb -d -p 8086:8086 influxdb}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
Il nous faut ensuite créer une base de données pour y stocker nos
|
||
métriques. Voici comment on s'était débrouillé dans un précédent TP pour
|
||
interagir avec InfluxDB :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\ExtensionTok{docker}\NormalTok{ container exec -i mytsdb influxdb }\OperatorTok{<<EOF}
|
||
\NormalTok{CREATE DATABASE metrics;}
|
||
\NormalTok{SHOW DATABASES;}
|
||
\OperatorTok{EOF}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
Vérifiez que la base de données \texttt{metrics} a bien été créée.
|
||
|
||
\hypertarget{monitoring-instantanuxe9-vers-la-console}{%
|
||
\subsubsection{Monitoring instantané vers la
|
||
console}\label{monitoring-instantanuxe9-vers-la-console}}
|
||
|
||
Dans un premier temps, commençons par afficher dans la console, la
|
||
quantité de mémoire utilisée par le groupe monitoré.
|
||
|
||
Vous pouvez utiliser un programme comme \texttt{memhog} pour remplir
|
||
rapidement votre mémoire.
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{verbatim}
|
||
42sh# mkdir /sys/fs/cgroup...
|
||
42sh$ echo $$ | sudo tee /sys/fs/cgroup.../tasks
|
||
42sh# ./monitor group_name memhog 500
|
||
~~~ 13595 ~~~ Current memory usage: 75194368/550502400 (13%)
|
||
~~~ 13595 ~~~ Current memory usage: 150290432/550502400 (27%)
|
||
~~~ 13595 ~~~ Current memory usage: 223690752/550502400 (40%)
|
||
~~~ 13595 ~~~ Current memory usage: 296828928/550502400 (53%)
|
||
~~~ 13595 ~~~ Current memory usage: 368001024/550502400 (66%)
|
||
~~~ 13595 ~~~ Current memory usage: 438517760/550502400 (79%)
|
||
~~~ 13595 ~~~ Current memory usage: 480329728/550502400 (87%)
|
||
~~~ 13595 ~~~ Current memory usage: 155648/550502400 (0%)
|
||
\end{verbatim}
|
||
|
||
\end{english}
|
||
|
||
Si vous n'avez pas le \emph{cgroup} \emph{memory}, il est possible qu'il
|
||
ne soit pas activé par défaut par votre système. Si vous êtes dans ce
|
||
cas, essayez d'ajouter \texttt{cgroup\_enable=memory} à la ligne de
|
||
commande de votre noyau.
|
||
|
||
\hypertarget{monitoring-vers-influxdb}{%
|
||
\subsubsection{Monitoring vers
|
||
InfluxDB}\label{monitoring-vers-influxdb}}
|
||
|
||
Maintenant, envoyons nos données vers la base
|
||
\url{https://docs.influxdata.com/influxdb/v1.6/guides/writing_data/} :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\ExtensionTok{curl}\NormalTok{ -i -XPOST }\StringTok{'http://localhost:8086/write?db=metrics'}\NormalTok{ --data-binary \textbackslash{}}
|
||
\StringTok{"}\VariableTok{$my_cgroup_name}\StringTok{ memory.usage_in_bytes=}\VariableTok{$(}\FunctionTok{cat}\NormalTok{ .../my_cgroup_name/memory.usage_in_bytes}\VariableTok{)}\StringTok{"}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
Pour vérifier que les données ont bien été ajoutées, nous pouvons
|
||
effectuer la requête suivante dans notre client \texttt{influx} :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\KeywordTok{SELECT} \OperatorTok{*} \KeywordTok{from} \OtherTok{"$my_cgroup_name"}\NormalTok{;}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
\hypertarget{monitorer-davantage-de-donnuxe9es}{%
|
||
\subsubsection{Monitorer davantage de
|
||
données}\label{monitorer-davantage-de-donnuxe9es}}
|
||
|
||
Liste non exhaustive de données à monitorer :
|
||
|
||
\begin{itemize}
|
||
\tightlist
|
||
\item
|
||
Nombre d'IOs effectué ;
|
||
\item
|
||
nombre d'octets lu/écrit sur les disques ;
|
||
\item
|
||
temps de calcul utilisé ;
|
||
\item
|
||
trafic réseau généré ;
|
||
\item
|
||
\ldots{}
|
||
\end{itemize}
|
||
|
||
Tous les cgroups existants dans le dernier noyau publié ont leur
|
||
documentation accessible ici :
|
||
\url{https://www.kernel.org/doc/Documentation/cgroup-v1/}
|
||
|
||
\hypertarget{permettre-uxe0-lutilisateur-de-monitorer-des-processus}{%
|
||
\subsubsection{Permettre à l'utilisateur de monitorer des
|
||
processus}\label{permettre-uxe0-lutilisateur-de-monitorer-des-processus}}
|
||
|
||
Maintenant, séparons notre script en deux parties afin qu'un utilisateur
|
||
normal (non-root) puisse utiliser la partie monitoring de notre script.
|
||
|
||
Un premier script doit s'occuper de créer le(s) \emph{cgroup}s et lui
|
||
attribuer les bons droits, tandis que le deuxième va effectuer le
|
||
monitoring, sans privilèges particuliers.
|
||
|
||
\hypertarget{exemple}{%
|
||
\paragraph{Exemple}\label{exemple}}
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{verbatim}
|
||
42sh$ sudo ./monitor_init my_cgroup_name
|
||
42sh$ ./monitor my_cgroup_name memhog 500
|
||
\end{verbatim}
|
||
|
||
\end{english}
|
||
|
||
\hypertarget{fixer-des-limites}{%
|
||
\subsection{Fixer des limites}\label{fixer-des-limites}}
|
||
|
||
Au delà de la simple consultation, les \emph{cgroup}s peuvent servir à
|
||
limiter la quantité de ressources mise à disposition à un groupe de
|
||
processus.
|
||
|
||
Pour définir une limite, nous allons écrire la valeur dans le fichier
|
||
correspondant à une valeur limite, comme par exemple
|
||
\texttt{memory.max\_usage\_in\_bytes}, qui limite le nombre d'octets que
|
||
notre groupe de processus va pouvoir allouer au maximum :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{verbatim}
|
||
42sh$ cat /sys/fs/cgroup/memory/virli/memory.max_usage_in_bytes
|
||
0
|
||
# 0 = Aucune limite
|
||
42sh$ echo 4M > /sys/fs/cgroup/memory/virli/memory.max_usage_in_bytes
|
||
# Maintenant, la limite est à 4MB, vérifions...
|
||
42sh$ cat /sys/fs/cgroup/memory/virli/memory.max_usage_in_bytes
|
||
4194304
|
||
\end{verbatim}
|
||
|
||
\end{english}
|
||
|
||
Chaque \emph{cgroup}s défini de nombreux indicateurs et possède de
|
||
nombreux limiteurs, n'hésitez pas à consulter la documentation associée
|
||
à chaque \emph{cgroup}.
|
||
|
||
\hypertarget{pour-aller-plus-loin-1}{%
|
||
\subsection*{Pour aller plus loin}\label{pour-aller-plus-loin-1}}
|
||
\addcontentsline{toc}{subsection}{Pour aller plus loin}
|
||
|
||
Pour tout connaître en détails,
|
||
\href{https://lwn.net/Articles/604609/}{la série d'articles de Neil
|
||
Brown sur les Control groups} est excellente !
|
||
|
||
Depuis les noyaux 4.5, il est possible d'utiliser la nouvelle version du
|
||
pseudo système de fichiers des \emph{CGroup}s. Le principal changement
|
||
vient du regroupement au sein d'une seule hiérarchie des différents
|
||
\emph{CGroup}s que l'on avait dans la v1. Davantage d'informations sont
|
||
disponibles :
|
||
|
||
\begin{itemize}
|
||
\tightlist
|
||
\item
|
||
\href{https://lwn.net/Articles/679786/}{Understanding the new control
|
||
groups API} ;
|
||
\item
|
||
\href{https://www.kernel.org/doc/Documentation/cgroup-v2.txt}{Kernel
|
||
Document about Control Group v2}.
|
||
\end{itemize}
|
||
|
||
\newpage
|
||
|
||
\hypertarget{gestion-de-la-muxe9moire}{%
|
||
\section{Gestion de la mémoire}\label{gestion-de-la-muxe9moire}}
|
||
|
||
Linux a une gestion de la mémoire bien particulière\footnote{Dépendant
|
||
de la valeur de \texttt{/proc/sys/vm/overcommit\_memory}, généralement
|
||
0. Voir
|
||
\url{https://www.kernel.org/doc/Documentation/vm/overcommit-accounting}.}
|
||
: par défaut, \texttt{malloc(3)} ne retournera jamais \texttt{NULL}. En
|
||
se basant sur l'euristique qu'un bloc mémoire demandé ne sera pas
|
||
utilisé directement et que de nombreux process ne feront pas un usage
|
||
total des blocks qu'ils ont alloués, le noyau permet d'allouer plus de
|
||
mémoire qu'il n'y en a réellement disponible. La mémoire est donc
|
||
utilisée de manière plus efficace.
|
||
|
||
Mais évidemment, cela peut donner lieu à des situations où le noyau
|
||
n'est plus en mesure de trouver de bloc physiquement disponible, alors
|
||
qu'ils avaient effectivement été alloués au processus. Pour autant, ce
|
||
n'est pas une raison pour tuer ce processus, car il est peut-être vital
|
||
pour le système (peut-être est-ce \texttt{init} qui est en train de
|
||
gérer le lancement d'un nouveau daemon). On dit alors que le noyau est
|
||
\emph{Out-Of-Memory}.
|
||
|
||
Pour se sortir d'une telle situation, et après avoir tenté de vider les
|
||
caches, il lance son arme ultime, pour retrouver au plus vite de la
|
||
mémoire : l'\emph{Out-Of-Memory killer}.
|
||
|
||
\hypertarget{oom-killer}{%
|
||
\subsection{OOM killer}\label{oom-killer}}
|
||
|
||
Selon un algorithme dont on raconte qu'il ne serait pas basé entièrement
|
||
sur l'aléatoire\footnote{\url{https://linux-mm.org/OOM_Killer}}, un
|
||
processus est tiré au sort (plus un processus occupe de mémoire et plus
|
||
il a de chance d'être tiré au sort) par l'OOM killer. Le sort qui lui
|
||
est réservé est tout simplement une mort brutale. Pour permettre au
|
||
système de disposer à nouveau de mémoire disponible. Si cela n'est pas
|
||
suffisant, un ou plusieurs autres processus peuvent être tués à tour de
|
||
rôle, jusqu'à ce que le système retrouve sa sérénité.
|
||
|
||
\hypertarget{esquiver-loom-killer}{%
|
||
\subsection{Esquiver l'OOM killer}\label{esquiver-loom-killer}}
|
||
|
||
Au sein d'un \emph{cgroup} \emph{memory}, le fichier
|
||
\texttt{memory.oom\_control} peut être utilisé afin de recevoir une
|
||
notification du noyau avant que l'OOM-killer ne s'attaque à un processus
|
||
de ce groupe.
|
||
|
||
Grâce à cette notification, il est possible de figer le processus pour
|
||
l'envoyer sur une autre machine. Et ainsi libérer la mémoire avant que
|
||
l'OOM killer ne passe.
|
||
|
||
Jetez un œil à \href{https://lwn.net/Articles/590960/}{cet article parru
|
||
sur LVM} à ce sujet.
|
||
|
||
\newpage
|
||
|
||
\hypertarget{secure-computing-mode}{%
|
||
\section{Secure Computing Mode}\label{secure-computing-mode}}
|
||
|
||
Plus connue sous l'acronyme \emph{seccomp}, cette fonctionnalité du
|
||
noyau Linux permet de restreindre les appels systèmes qu'un processus
|
||
est autorisé à utiliser. En cas d'appel non autorisé, le processus
|
||
fautif est directement tué (\texttt{SIGKILL}) par le noyau, ou, lorsque
|
||
c'est précisé, un code \texttt{errno} particulier peut être renvoyé au
|
||
programme.
|
||
|
||
Depuis la version 3.17 du noyau, l'appel système \texttt{seccomp(2)}
|
||
permet de faire entrer le processus courant dans ce mode. En effet,
|
||
c'est le processus lui-même qui déclare au noyau qu'il peut désormais se
|
||
contenter d'une liste réduite d'appel système ; à l'inverse des
|
||
politiques de sécurité comme SELinux ou AppArmor, qui encapsulent les
|
||
programmes pour toute la durée de leur exécution.
|
||
|
||
\emph{Seccomp} est particulièrement utile lorsqu'un processus a terminé
|
||
son initialisation (ne dépendant en général pas de données sujettes à
|
||
l'exploitation de vulnérabilité) et doit commencer à entrer dans des
|
||
portions de code promptes aux vulnérabilités : c'est notamment le cas
|
||
des moteurs de rendus des navigateurs Firefox et Chrome.
|
||
|
||
\hypertarget{pruxe9requis-1}{%
|
||
\subsection{Prérequis}\label{pruxe9requis-1}}
|
||
|
||
L'utilisation de \texttt{seccomp} nécessite d'avoir un noyau compilé
|
||
avec l'option \texttt{CONFIG\_SECCOMP}.
|
||
|
||
Vous aurez également besoin de la bibliothèque \texttt{libseccomp} car
|
||
l'appel système \texttt{seccomp(2)} n'a pas de \emph{wrapper} dans la
|
||
libc, vous devrez donc passer par cette bibliothèque.
|
||
|
||
\hypertarget{mode_strict}{%
|
||
\subsection{\texorpdfstring{\texttt{MODE\_STRICT}}{MODE\_STRICT}}\label{mode_strict}}
|
||
|
||
Le mode traditionnel de \emph{seccomp} est de ne permettre uniquement
|
||
l'utilisation des appels système \texttt{read(2)}, \texttt{write(2)}
|
||
(sur les descripteurs de fichier déjà ouvert), \texttt{\_exit(2)} et
|
||
\texttt{sigreturn(2)}.
|
||
|
||
Historiquement, avant la création de l'appel système
|
||
\texttt{seccomp(2)}, on activait ce mode via :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\NormalTok{prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT);}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
Une fois passé cet appel système, toute entrée dans un appel système non
|
||
autorisé conduit à un \texttt{SIGKILL} du processus.
|
||
|
||
\hypertarget{mode_filter}{%
|
||
\subsection{\texorpdfstring{\texttt{MODE\_FILTER}}{MODE\_FILTER}}\label{mode_filter}}
|
||
|
||
Plus modulable que le mode strict, le mode de filtrage permet une grande
|
||
amplitude en permettant au programmeur de définir finement quels appels
|
||
systèmes le programme est autorisé à faire ou non, et quel sentence est
|
||
exécutée en cas de faute.
|
||
|
||
Notons que les processus fils issus (\texttt{fork(2)} ou
|
||
\texttt{clone(2)}) d'un processus auquel est appliqué un filtre
|
||
\texttt{seccomp}, héritent également de ce filtre.
|
||
|
||
La construction de ce filtre est faite de manière programatique, via des
|
||
règles BPF (\texttt{Berkeley\ Packet\ Filter}). On passe ensuite ce
|
||
filtre BPF en argument de l'appel système :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{Shaded}
|
||
\begin{Highlighting}[]
|
||
\KeywordTok{struct}\NormalTok{ sock_filter filter[];}
|
||
\KeywordTok{struct}\NormalTok{ sock_fprog prog = \{}
|
||
\NormalTok{ .len = (}\DataTypeTok{unsigned} \DataTypeTok{short}\NormalTok{) (}\KeywordTok{sizeof}\NormalTok{(filter) / }\KeywordTok{sizeof}\NormalTok{(filter[}\DecValTok{0}\NormalTok{])),}
|
||
\NormalTok{ .filter = filter,}
|
||
\NormalTok{\};}
|
||
\NormalTok{seccomp(SECCOMP_SET_MODE_FILTER, }\DecValTok{0}\NormalTok{, &prog);}
|
||
\end{Highlighting}
|
||
\end{Shaded}
|
||
|
||
\end{english}
|
||
|
||
\hypertarget{exercice-1}{%
|
||
\subsubsection*{Exercice}\label{exercice-1}}
|
||
\addcontentsline{toc}{subsubsection}{Exercice}
|
||
|
||
Écrivez un programme filtrant un appel système, à l'aide de
|
||
\texttt{seccomp} :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{verbatim}
|
||
42sh$ ./syscall_filter sleep 5
|
||
sleep: cannot read realtime clock: Operation not permitted
|
||
42sh$
|
||
\end{verbatim}
|
||
|
||
\end{english}
|
||
|
||
Dans cet exemple, l'appel système filtré est \texttt{nanosleep(2)}.
|
||
|
||
\newpage
|
||
|
||
\hypertarget{projet-et-rendu}{%
|
||
\section{Projet et rendu}\label{projet-et-rendu}}
|
||
|
||
\hypertarget{sujet}{%
|
||
\subsection{Sujet}\label{sujet}}
|
||
|
||
Vous allez commencer aujourd'hui un projet qui s'étendra au prochain TP
|
||
et qui consistera à réaliser la partie d'isolation de la moulinette des
|
||
ACUs !
|
||
|
||
Cette semaine, il faudra faire en sorte de restreindre un groupe de
|
||
processus pour qu'il ne puisse pas faire de déni de service sur notre
|
||
machine.
|
||
|
||
Il n'y a pas de restriction sur le langage utilisé, vous pouvez tout
|
||
aussi bien utiliser du C, du C++, du Python, etc.
|
||
|
||
L'usage de bibliothèques \textbf{non relatives} au projet est autorisé :
|
||
le but de ce sujet est d'évaluer votre compréhension et votre
|
||
utilisation de la tuyauterie bas-niveau du noyau liée à la
|
||
virtualisation légère. À partir du moment où vous n'utilisez pas une
|
||
bibliothèque qui abstrait complètement cette plomberie, n'hésitez pas à
|
||
l'utiliser !
|
||
|
||
Gardez en tête que ce projet sera à continuer au prochain TP, où il sera
|
||
principalement question de faire des appels systèmes.
|
||
|
||
\hypertarget{palier-1-restreindre-lenvironnement-2-points}{%
|
||
\subsection*{Palier 1 : Restreindre l'environnement (2
|
||
points)}\label{palier-1-restreindre-lenvironnement-2-points}}
|
||
\addcontentsline{toc}{subsection}{Palier 1 : Restreindre l'environnement
|
||
(2 points)}
|
||
|
||
Après avoir mis en place les bases de votre programme, commencez par
|
||
créer les différentes hiérarchies (si vous avez un noyau récent, vous
|
||
pouvez utiliser les cgroups-v2) dont vous allez avoir besoin pour
|
||
limiter l'utilisation de ressources.
|
||
|
||
Puis, mettez en place ces limites :
|
||
|
||
\begin{itemize}
|
||
\tightlist
|
||
\item
|
||
pas plus d'1 GB de mémoire utilisée ;
|
||
\item
|
||
1 seul CPU au maximum ;
|
||
\item
|
||
100 PIDs ;
|
||
\item
|
||
\ldots{}
|
||
\end{itemize}
|
||
|
||
En bonus, vous pouvez gérer les cas où le noyau sur lequel s'exécute
|
||
votre moulinette ne possède pas tous ces \emph{CGroup}s, au lieu de
|
||
planter, ne rien faire n'est pas forcément une mauvaise solution.
|
||
|
||
\hypertarget{palier-2-ruxe9duire-les-capabilities-2-points}{%
|
||
\subsection*{\texorpdfstring{Palier 2 : Réduire les
|
||
\texttt{capabilities} (2
|
||
points)}{Palier 2 : Réduire les capabilities (2 points)}}\label{palier-2-ruxe9duire-les-capabilities-2-points}}
|
||
\addcontentsline{toc}{subsection}{Palier 2 : Réduire les
|
||
\texttt{capabilities} (2 points)}
|
||
|
||
Réduisez au maximum les \emph{capabilities}, de telle sorte qu'il ne
|
||
soit pas possible de faire un ping dans l'environnement restreint :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{verbatim}
|
||
42sh# ping 9.9.9.9
|
||
PING 9.9.9.9 (9.9.9.9) 56(84) bytes of data.
|
||
64 bytes from 9.9.9.9: icmp_seq=1 ttl=56 time=3.93 ms
|
||
64 bytes from 9.9.9.9: icmp_seq=2 ttl=56 time=3.97 ms
|
||
^C
|
||
--- 9.9.9.9 ping statistics ---
|
||
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
|
||
rtt min/avg/max/mdev = 3.931/3.954/3.978/0.067 ms
|
||
|
||
42sh# ./mymoulette /bin/bash
|
||
bash# curl http://www.linuxcontainers.org/ | md5sum
|
||
c7d68d1cb4737125a84cd69f55add202
|
||
|
||
bash# ping 9.9.9.9
|
||
ping: icmp open socket: Permission denied
|
||
\end{verbatim}
|
||
|
||
\end{english}
|
||
|
||
\textbf{Astuces~:} \texttt{prctl(2)}, \texttt{capabilities(7)},
|
||
\texttt{capget(2)}, \texttt{capset(2)}, \ldots{}
|
||
|
||
Aidez-vous du visualisateur de \emph{capabilities} de la partie 4 du TP,
|
||
pour voir si vous êtes sur la bonne voie.
|
||
|
||
\hypertarget{palier-3-utilisable-par-un-utilisateur-1-point}{%
|
||
\subsection*{Palier 3 : Utilisable par un utilisateur (1
|
||
point)}\label{palier-3-utilisable-par-un-utilisateur-1-point}}
|
||
\addcontentsline{toc}{subsection}{Palier 3 : Utilisable par un
|
||
utilisateur (1 point)}
|
||
|
||
Jouez avec les attributs étendus pour qu'un utilisateur non-privilégié
|
||
puisse exécuter votre moulinette. Ajoutez la/les commande(s) à votre
|
||
Makefile ou script d'installation.
|
||
|
||
\hypertarget{cruxe9ation-dun-environnement-dexuxe9cution-minimal}{%
|
||
\subsection*{Création d'un environnement d'exécution
|
||
minimal}\label{cruxe9ation-dun-environnement-dexuxe9cution-minimal}}
|
||
\addcontentsline{toc}{subsection}{Création d'un environnement
|
||
d'exécution minimal}
|
||
|
||
Plutôt que d'utiliser votre système hôte au complet, avec tous ses
|
||
programmes et toutes ses bibliothèques, il faudrait utiliser un système
|
||
contenant le strict minimum. Recréez un environnement minimaliste, comme
|
||
on a pu en voir dans la partie sur les \texttt{chroot}.
|
||
|
||
\textbf{Ne mettez pas cet environnement dans votre tarball de rendu, il
|
||
vous sera seulement utile pour faire des tests.}
|
||
|
||
\hypertarget{palier-4-isolation-du-pauvre-1-point}{%
|
||
\subsection*{Palier 4 : Isolation du pauvre (1
|
||
point)}\label{palier-4-isolation-du-pauvre-1-point}}
|
||
\addcontentsline{toc}{subsection}{Palier 4 : Isolation du pauvre (1
|
||
point)}
|
||
|
||
Nous n'avons pas encore vu de meilleure méthode pour mieux isoler
|
||
l'environnement que de faire un \texttt{chroot}, ajoutez à votre
|
||
programme cette isolation rudimentaire. Et rendez-vous au prochain cours
|
||
pour avoir une meilleure isolation !
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{verbatim}
|
||
42sh$ which firefox
|
||
/usr/bin/firefox
|
||
42sh# ./mymoulette ./newrootfs/ /bin/bash
|
||
bash# which firefox
|
||
which: no firefox in (/usr/bin:/usr/local/bin:/bin:/opt/bin)
|
||
\end{verbatim}
|
||
|
||
\end{english}
|
||
|
||
\hypertarget{palier-5-seccomp-2-points}{%
|
||
\subsection*{Palier 5 : seccomp (2
|
||
points)}\label{palier-5-seccomp-2-points}}
|
||
\addcontentsline{toc}{subsection}{Palier 5 : seccomp (2 points)}
|
||
|
||
Filtrez les appels systèmes de telle sorte qu'aucun programme exécuté
|
||
dans votre bac à sable ne puisse plus lancer les appels systèmes
|
||
suivants :
|
||
|
||
\begin{itemize}
|
||
\tightlist
|
||
\item
|
||
\texttt{nfsservctl(2)} ;
|
||
\item
|
||
\texttt{personality(2)} ;
|
||
\item
|
||
\texttt{pivot\_root(2)} ;
|
||
\item
|
||
\ldots{}
|
||
\end{itemize}
|
||
|
||
N'hésitez pas à en utiliser d'autres pour vos tests ;)
|
||
|
||
\textbf{Astuces~:} \texttt{seccomp(2)}, \texttt{seccomp\_init(3)},
|
||
\texttt{seccomp\_load(3)}, \ldots{}
|
||
|
||
\hypertarget{palier-bonus-automatisation-de-la-cruxe9ation-de-lenvironnement-5-points}{%
|
||
\subsection*{Palier bonus : Automatisation de la création de
|
||
l'environnement (5
|
||
points)}\label{palier-bonus-automatisation-de-la-cruxe9ation-de-lenvironnement-5-points}}
|
||
\addcontentsline{toc}{subsection}{Palier bonus : Automatisation de la
|
||
création de l'environnement (5 points)}
|
||
|
||
Pour \emph{moulinéter} plusieurs étudiants en parallèle, vous allez
|
||
avoir besoin de plusieurs environnements identiques. Plutôt que de
|
||
recopier cet environnement, de le nettoyer, de le recréer, pour chaque
|
||
étudiant, ajoutez à votre moulinette un support pour LVM : utilisez des
|
||
\emph{snapshots} pour figer votre environnement et le dupliquer
|
||
facilement pour chaque étudiant.
|
||
|
||
L'usage est laissé à votre discrétion : vous pouvez ajouter un/des
|
||
paramètres à votre \emph{moulette} pour indiquer le volume LVM à
|
||
utiliser ou le définir en dur ou encore séparer la création de
|
||
l'environnement et de la snapshot initiale dans un programme distinct.
|
||
|
||
Si votre noyau dispose d'un UnionFS (AUFS ou OverlayFS par exemple), ou
|
||
que vous disposez d'une partition \texttt{btrfs}, vous pouvez utiliser
|
||
l'une de ces méthodes pour ajouter une couche en écriture, à la place de
|
||
LVM.
|
||
|
||
\hypertarget{modalituxe9-de-rendu}{%
|
||
\subsection{Modalité de rendu}\label{modalituxe9-de-rendu}}
|
||
|
||
Un service automatique s'occupe de réceptionner vos rendus, de faire les
|
||
vérifications nécessaires et de vous envoyer un accusé de réception (ou
|
||
de rejet).
|
||
|
||
Ce service écoute sur l'adresse
|
||
\href{mailto:virli@nemunai.re}{\nolinkurl{virli@nemunai.re}}, c'est donc
|
||
à cette adresse et exclusivement à celle-ci que vous devez envoyer vos
|
||
rendus. Tout rendu envoyé à une autre adresse et/ou non signé et/ou reçu
|
||
après la correction ne sera pas pris en compte.
|
||
|
||
Par ailleurs, n'oubliez pas de répondre à
|
||
\href{https://www.epitaf.fr/moodle/mod/quiz/view.php?id=40}{l'évaluation
|
||
du cours}.
|
||
|
||
\hypertarget{tarball}{%
|
||
\subsection{Tarball}\label{tarball}}
|
||
|
||
Tous les fichiers identifiés comme étant à rendre pour ce TP sont à
|
||
placer dans une tarball (pas d'archive ZIP, RAR, \ldots{}).
|
||
|
||
Voici une arborescence type (adaptez les extensions et les éventuels
|
||
fichiers supplémentaires associés au langage que vous aurez choisi pour
|
||
chaque exercice) :
|
||
|
||
\begin{english}[variant=american]
|
||
|
||
\begin{verbatim}
|
||
login_x-TP3/escape.c
|
||
login_x-TP3/procinfo.sh
|
||
login_x-TP3/rev_kdb_leds.sh
|
||
login_x-TP3/view_caps.c
|
||
login_x-TP3/monitor.sh
|
||
login_x-TP3/monitor_init.sh
|
||
login_x-TP3/syscall_filter.c
|
||
\end{verbatim}
|
||
|
||
\end{english}
|
||
|
||
Les premières étapes du projet ne sont pas à rendre et feront l'objet
|
||
d'un rendu à part.
|
||
|
||
\end{document}
|