{"id":532,"date":"2018-05-20T04:11:51","date_gmt":"2018-05-20T03:11:51","guid":{"rendered":"https:\/\/blog.grenzdebiel.dynv6.net\/?p=532"},"modified":"2018-05-20T04:19:48","modified_gmt":"2018-05-20T03:19:48","slug":"lxc-unprivileged-container","status":"publish","type":"post","link":"https:\/\/blog.grenzdebiel.dynv6.net\/?p=532","title":{"rendered":"LXC- unprivileged Container"},"content":{"rendered":"<p>Linux Container aka LXC k\u00f6nnen &#8222;unprivileged&#8220; gestartet werden.<!--more--><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-thumbnail wp-image-534\" src=\"https:\/\/blog.grenzdebiel.dynv6.net\/wordpress\/wp-content\/uploads\/2018\/05\/lxc-user-namespace-150x150.jpg\" alt=\"\" width=\"150\" height=\"150\" \/> Das hei\u00dft das der Container als User-Prozess gestartet werden. Sollte also wirklich jemand aus den Container ausbrechen so verf\u00fcgt der b\u00f6se Benutzer nur \u00fcber die eingeschr\u00e4nkten Rechte des Benutzers der den Container gestartet hat.<\/p>\n<p>Ich nutze Ubuntu-Server bei anderen Distributionen kann es ein wenig abweichen wobei die Prinzipien dieselben sind.<\/p>\n<p>Es wird der user-namespace benutzt. Das hei\u00dft der Container wird mit der user-id des einfachen Benutzers gestartet und der Kernel mapped die user-id zur id 0 in den Conatiner. Vereinfacht gesagt der Benutzer startet ein Container mit der user.id 1001 und die Programme innerhalb des Containers laufen mit der user-id &#8222;root&#8220;(ohne dies wirklich zutun).<\/p>\n<p>Auch hier gibt es wieder einige Stolperfallen bzw. vorraussetzungen:<\/p>\n<p>Damit das mapping funktioniert ben\u00f6tigen wir noch ein paar Programme:<\/p>\n<pre class=\"lang:sh decode:true\">apt install systemd-services uidmap<\/pre>\n<p>1. Der Benutzer muss \u00fcber sub-uid und sub-gid verf\u00fcgen. Diese k\u00f6nnen mit &#8222;usermod&#8220; erstellt werden.<\/p>\n<pre class=\"lang:sh decode:true\">usermod --add-subuids 100000-165536 &lt;lxcuser&gt;\r\nusermod --add-subgids 100000-165536 &lt;lxcuser&gt;<\/pre>\n<p>In den Dateien &#8222;\/etc\/subuid&#8220; und &#8222;\/etc\/subgid&#8220; sollte solch eine Zeile sein:<\/p>\n<pre class=\"lang:default decode:true\">lxcuser:100000:65537<\/pre>\n<p>2. Wenn die Container mit Limits gestartet weden bzw. wenn diese mit cgroups eingeschr\u00e4nkt werden muss der Benutzer dies auch d\u00fcrfen. Dies kann mit einen Blick in der Datei &#8222;etc\/pam.d\/common-session&#8220; und &#8222;\/etc\/pam.d\/common-session-noninteractive&#8220; \u00fcberpr\u00fcft werden. Hier sollte folgende Zeile \u00e4hnlich eingetragen sein:<\/p>\n<pre class=\"lang:ini decode:true\">session optional        pam_cgfs.so -c freezer,memory,cpu,cpuset,name=systemd<\/pre>\n<p>Fehlt diese Zeile und der Container wird mit cgroup-limits gestartet erscheint folgende Fehlermeldung:<\/p>\n<pre class=\"lang:default decode:true\">lxc-start: cgroups\/cgfsng.c: cgfsng_setup_limits: 1971 No such file or directory - Error setting cpuset.cpus to 1 for &lt;containername&gt;\r\nlxc-start: start.c: lxc_spawn: 1205 Failed to setup cgroup limits for container \"&lt;containername&gt;\".\r\nlxc-start: start.c: __lxc_start: 1358 Failed to spawn container \"&lt;containername&gt;\".\r\nlxc-start: tools\/lxc_start.c: main: 366 The container failed to start.\r\nlxc-start: tools\/lxc_start.c: main: 370 Additional information can be obtained by setting the --logfile and --logpriority options.<\/pre>\n<p>3. Da der Benutzer normalerweise nicht Netzwerkeinstellungen \u00e4ndern kann, also erstellen von veth-pairs oder das hinzuf\u00fcgen dieser zu Netzwerkbr\u00fccken, wird dies \u00fcber ein seperaten Prozess gemacht &#8222;lxc-user-nic&#8220;.<\/p>\n<p>Dieser Prozess parst die Konfigurationsdatei erstellt daraufhin das Netzwerkdevice und bindet es an die Netzwerkbr\u00fccke. Konfiguriert wird es in der Datei &#8222;\/etc\/lxc\/lxc-usernet&#8220; typischerweise sieht sie wie folgt aus:<\/p>\n<pre class=\"lang:default decode:true\">#User Type Bridge Anzahl\r\n&lt;lxcuser&gt; veth lxcbr0 100<\/pre>\n<p>Jetzt k\u00f6nnt ihr den Benutzer wechseln und euren Container erstellen:<\/p>\n<pre class=\"lang:sh decode:true \">su - &lt;lxcuser&gt;\r\nlxc-create -n &lt;containername&gt; -t download -- -d ubuntu -r bionic -a amd64<\/pre>\n<p>Wobei ihr auch eine andere Distribution und ein anderes Release w\u00e4hlen k\u00f6nnt. Wenn alles gut gegangen ist startet ihr den Container einfach mittels:<\/p>\n<pre class=\"lang:default decode:true \">lxc-start -n &lt;containername&gt; -d<\/pre>\n<p>Wechselt nun in den Container mit z.b.:<\/p>\n<pre class=\"lang:sh decode:true \">lxc-attach -n &lt;containername&gt;<\/pre>\n<p>Ruft &#8222;top&#8220; auf und ihr seht das die Prozesse innerhalb des Container als Benutzer &#8222;root&#8220; laufen.<\/p>\n<p>Wie ihr den Container konfiguriert und mit cgroup-limits einschr\u00e4nkt wurde ja schon behandelt.<\/p>\n<p>Bestehende Container k\u00f6nnen meist mit einer kleinen Anpassung der Datei &#8222;config&#8220; so ge\u00e4ndert werden das diese auch unprivileged laufen:<\/p>\n<pre class=\"lang:ini decode:true \"># if you use ubuntu in container\r\nlxc.include = \/usr\/share\/lxc\/config\/ubuntu.common.conf\r\nlxc.include = \/usr\/share\/lxc\/config\/ubuntu.userns.conf\r\n\r\nlxc.include = \/etc\/lxc\/default.conf\r\nlxc.id_map = u 0 100000 65537\r\nlxc.id_map = g 0 100000 65537<\/pre>\n<p>F\u00fcr weitere Informationen schaut euch diese Seite an: <a href=\"https:\/\/stgraber.org\/2014\/01\/17\/lxc-1-0-unprivileged-containers\/\">https:\/\/stgraber.org\/2014\/01\/17\/lxc-1-0-unprivileged-containers\/.<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Linux Container aka LXC k\u00f6nnen &#8222;unprivileged&#8220; gestartet werden.<\/p>\n","protected":false},"author":3,"featured_media":534,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,43,27,9,12],"tags":[74,150,148,149],"class_list":["post-532","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-allgemein","category-cubietruck","category-linux","category-raspberry-pi","category-software-pi","tag-lxc","tag-unprivileged","tag-user-namespace","tag-uts"],"_links":{"self":[{"href":"https:\/\/blog.grenzdebiel.dynv6.net\/index.php?rest_route=\/wp\/v2\/posts\/532","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.grenzdebiel.dynv6.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.grenzdebiel.dynv6.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.grenzdebiel.dynv6.net\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.grenzdebiel.dynv6.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=532"}],"version-history":[{"count":0,"href":"https:\/\/blog.grenzdebiel.dynv6.net\/index.php?rest_route=\/wp\/v2\/posts\/532\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.grenzdebiel.dynv6.net\/index.php?rest_route=\/wp\/v2\/media\/534"}],"wp:attachment":[{"href":"https:\/\/blog.grenzdebiel.dynv6.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=532"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.grenzdebiel.dynv6.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=532"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.grenzdebiel.dynv6.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=532"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}