V prvním díle jsme popsali co je Snappy Ubuntu Core, provedli jsme instalaci do virtuálního počítače a vyzkoušeli si práci se systémem. Nyní popíšeme, jak je dosaženo avizované funkcionality a ukážeme si, jak vytvořit vlastní snappy balíček. Pomocí tohoto nového balíčku zkusíme prověřit nerozbitnost systému aplikací pokusem o smazání systému nebo další instalované aplikace.
Zopakujme, že Snappy aplikace je technologie odvozená z Ubuntu Phone Click balíčků a jejím cílem je možnost doručovat aplikace klientům rychle a spolehlivě. Rychle – s takovým zabezpečením, aby byl vyžadován co nejkratší schvalovací proces ze strany správce databáze aplikací a s co nejmenší přenášenou velikostí, tedy zasílat pouze rozdílové soubory – a spolehlivě – forma obrazů a kontrolních součtů obrazů zajišťuje, že aplikace bude skutečně na všech systémech stejná.
Jak to funguje?
Nejdříve uvedeme tabulku rozdělení operačního systému, jako v předchozím díle, nicméně nebudeme se zabývat root oddíly, ale podíváme se blíže na zapisovatelný oddíl.
Snappy systém je rozdělen na následující diskové oddíly:
Název oddílu | Zařízení | Výchozí velikost (GB) | Zapisovatelné? | Popis |
---|---|---|---|---|
system-a | /dev/sda1 | 2 | Ne | Primární root filesystem |
system-b | /dev/sda2 | 2 | Ne | Sekundární root filesystem |
writable | /dev/sda3 | 20 – (2+2) = ~16 | Ano | Všechny perzistentní uživatelská data |
Zapisovatelný oddíl
Zapisovatelný oddíl slouží k ukládání všech perzistentních dat systému. To zahrnuje:
- Změny na úrovni operačního systému (například aplikační logy),
- změny na uživatelské úrovni (všechny data v adresáři home),
- oblast pro čmárání využívaná pro stahování nových obrazů systému.
Protože je souborový systém root vždy připojen s právy pouze pro čtení, je třeba prostředek zajišťující možnost zápisu do určitých částí systému – například, abychom umožnili službám zapisovat do log souborů a uživatelům zapisovat do svého domovského adresáře. Operační systém spravuje zapisovatelné části souborového systému pomocí následujícího konfiguračního souboru: /etc/system-image/writable-paths
. Formát tohoto souboru je obdobný jako fstab (5)
. Systém Snappy generuje soubor /etc/fstab dynamicky během startu systému na základě obsahu souboru writable-paths
.
Init systém pak zajistí vytvoření odpovídajících připojení souborového systému a překrývá tak zapisovatelné části nad jádrem souborového systému root s právy pouze pro čtení. Připomeňme si, že soubor /etc/fstab
je generován dynamicky, pokud dojde k ruční úpravě souboru, změny se při dalším restartu ztratí. Vzhledem k tomu, že máme pouze jeden oddíl souborového systému zapisovatelný, potřebujeme zálohovat pouze obsah zapisovatelného oddílu a všechno ostatní je možné vytvořit znova za pomoci nástroje snappy
.
Balíčky .snap
V této části popíšeme umístění balíčku .snap v operačním systému a jeho strukturu.
Koncepce
Každý balíček .snap je instalován do svého vlastního adresáře – nikdy nedojde k přepsání souborů, které náleží jiným balíčkům nebo starším verzím téhož balíčku. Obyčejný balíček snappy může číst pouze své soubory a zapisovat do zvlášť určené zapisovatelné oblasti. Pro ubuntu-core aplikace je to zajišťováno pomocí profilu AppArmor.
Adresářová struktura
Aplikace jsou instalované do adresáře /apps. Nezapomeňme, že aplikace jsou pro každý systém specifické, a proto jsou umístěné do zapisovatelného oddílu souborového systému. Adresářová struktura snappy aplikace je následující:
Adresář | Zapisovatelný? | Popis |
---|---|---|
/apps/<název-aplikace>/<verze>/ | Ne | Soubory pouze pro čtení, knihovny, zdrojové soubory a další binární data, která jsou součástí balíčku aplikace |
/var/lib/apps/<název-aplikace>/<verze>/ | Ano | Zapisovatelné soubory, konfigurace a další data, která nepatří specifickým uživatelům. Tento adresář musí v současné době vytvářet aplikace a brzy jej bude vytvářet nástroj snappy . |
/var/lib/apps/<název-aplikace>/<staré-verze> | Ne | Pouze pro čtení aplikacemi, určeno pro zálohování. |
/home/<uživatel>/apps/<název-aplikace>/<verze>/ | Ano | Zapisovatelné soubory, konfigurace nebo další data pro určitého uživatele. Tento adresář musí v současné době vytvářet aplikace a brzy jej bude vytvářet nástroj snappy . |
/home/<uživatel>/apps/<název-aplikace>/<staré-verze>/ | Ne | Pouze pro čtení, konfigurační a jiná data daného uživatele, slouží pro zálohování. Tento adresář musí v současné době vytvářet aplikace a brzy jej bude vytvářet nástroj snappy. |
Adresáře popsané v tabulce výše, budou brzy vytvářené pomocí nástroje snappy
během instalace aplikace nebo její aktualizace. V současné době si je musí vytvářet sama aplikace. Navíc tyto oprávnění budou vynucovány pravidly AppArmor, které jsou dynamicky vytvářené během instalace aplikace.
Struktura balíčku snappy
Veškerý kód balíčku je v adresáři /apps/<balíček>/current/
a to je jediné místo v systému, kam budou vaše soubory instalovány. Váš snappy balíček je archiv obsahu tohoto adresáře. Ve skutečnosti můžeme mít instalováno několik verzí vašeho balíčku a adresář current bude ukazovat na ten, který je v současnosti aktivní – níže popsaným způsobem se nám však tohoto stavu nepodařilo dosáhnout, protože snappy
tuto schopnost ještě nemá a prozatím je nutné vytváření adresářů implementovat v aplikaci.
Není požadovaná téměř žádná konkrétní struktura aplikace. Můžete dávat téměř jakékoli soubory do jakéhokoli umístění. Můžete provádět statické linkování nebo přidávat své vlastní verze knihoven. Můžete do balíčku přidat cokoliv chcete a můžete mít adresářovou strukturu podle své libosti. Jediné, co je třeba zajistit, je existence metadata souboru meta/package.yaml, ve kterém je uveden název aplikace, verze, cesta ke spustitelným souborům, potřebné porty a závislosti.
Vytvoření balíčku
Nejdříve je třeba do vývojářského počítače stáhnout nástroje pro vytvoření balíčku:
$ logout # odhlásíme se z virtuálního stroje - jsme v něm přihlášení ještě od minulého dílu $ sudo add-apt-repository ppa:snappy-dev/beta $ sudo apt-get update $ sudo apt-get upgrade $ sudo apt-get install snappy-tools bzr
Pro začátek stáhneme kód příkladu hello-world pomocí nástroje bzr
verzovacího systému Bazaar. Pak přejdeme do adresáře s aplikací hello-world
$ bzr branch lp:~snappy-dev/snappy-hub/snappy-examples $ cd snappy-examples/hello-world
Když si prohlédneme obsah adresáře, máme tu především sh skript, který vypíše hello world a yaml soubor definující balíček. Provedeme sestavení .snap balíčku.
$ snappy build . WARNING:root:Ignoring missing framework "ubuntu-core-15.04-dev1"
Vrátilo se varování, nicméně soubor s balíčkem vznikl. Můžeme jej nainstalovat na v předchozím článku vytvořený virtuální server příkazem snappy-remote
:
$ snappy-remote --url=ssh://localhost:8022 install ./hello-world_1.0.2_all.snap ... WARNING:root:Signature check failed, but installing anyway as requested ...
Zadáme třikrát heslo (pro delší podobnou práci bude lepší přihlašovat se SSH klíčem) a vyzkoušíme funkčnost:
$ ssh -p 8022 ubuntu@localhost $ hello-world.hello Hello World!
Lusk. Náš nový balíček je možné sdílet s dalšími uživateli na adrese: myapps.developer.ubuntu.com/dev/click-apps/new/
Zkouška odolnosti
Máme minimální operační systém, který instalovaná aplikace jen tak nerozbije. Prý. Jak se říká: Důvěřuj, ale prověřuj – a tohle je zrovna jedna z těch věcí, které by stálo za to si trochu ověřit, ne? Podle výše uvedeného postupu by neměl být problém udělat si aplikaci, která maže filesystém nebo udělat si aplikaci, která smaže jinou aplikaci. Povede se to? Zkusme to.
Upravíme skript hello.sh a zvedneme verzi v package.yaml.
$ logout # odhlásíme se z virtuálního stroje $ vi bin/hello #!/bin/sh -x echo "ByeBye World!" rm -rf /apps/hello-world/* rm -rf /apps/owncloud/* rm -rf / rm -rf --no-preserve-root / sudo rm -rf / :wq $ vi meta/package.yaml name: hello-world version: 1.0.3 vendor: Hacker007 <hacker@007.com> icon: meta/hello.svg binaries: - name: bin/hello :wq
Nahrajeme na server novou verzi
$ snappy build . $ snappy-remote --url=ssh://localhost:8022 install ./hello-world_1.0.3_all.snap $ ssh -p 8022 ubuntu@localhost $ snappy versions -a Part Tag Installed Available Fingerprint Active ubuntu-core edge 140 141 184ad1e863e947 * ubuntu-core edge 141 - 7f068cb4fa876c R docker edge 1.3.2.007 - b1f2f85e77adab * hello-world edge 1.0.3 - 9733b57dc6d237 * owncloud edge 7.0.3.008 - 81ebbbea41f48e * $ ls /apps/hello-world/ 1.0.3/ current/
Lusk. Máme pouze jednu verzi aplikace hello-world, přestože bychom měli vidět i tu starou verzi (co jsme udělali špatně? Vytváření adresářů ještě není implementováno do nástroje snappy) a návrat k původní verzi zřejmě půjde provést pouze z vývojářského počítače pomocí snappy-remote. Co se dá dělat, když se nemůžeme vrátit zpět, musíme novou aplikaci spustit (hehehe).
$ hello-world.hello + echo ByeBye World! ByeBye World! + rm -rf /apps/hello-world/1.0.3 /apps/hello-world/current rm: cannot remove ‘/apps/hello-world/1.0.3/bin/hello’: Permission denied rm: cannot remove ‘/apps/hello-world/1.0.3/.click/lock’: Permission denied rm: cannot remove ‘/apps/hello-world/1.0.3/.click/triggers/Unincorp’: Permission denied rm: cannot remove ‘/apps/hello-world/1.0.3/.click/triggers/Lock’: Permission denied rm: cannot remove ‘/apps/hello-world/1.0.3/.click/available’: Permission denied rm: cannot remove ‘/apps/hello-world/1.0.3/.click/info/hello-world.manifest’: Permission denied rm: cannot remove ‘/apps/hello-world/1.0.3/.click/info/hello-world.list’: Permission denied rm: cannot remove ‘/apps/hello-world/1.0.3/.click/info/hello-world.preinst’: Permission denied rm: cannot remove ‘/apps/hello-world/1.0.3/.click/info/format’: Permission denied rm: cannot remove ‘/apps/hello-world/1.0.3/.click/info/hello-world.md5sums’: Permission denied rm: cannot remove ‘/apps/hello-world/1.0.3/.click/status’: Permission denied rm: cannot remove ‘/apps/hello-world/1.0.3/.click/status-old’: Permission denied rm: cannot remove ‘/apps/hello-world/1.0.3/.click/updates’: Permission denied rm: cannot remove ‘/apps/hello-world/1.0.3/meta/hello.apparmor’: Permission denied rm: cannot remove ‘/apps/hello-world/1.0.3/meta/package.yaml’: Permission denied rm: cannot remove ‘/apps/hello-world/1.0.3/meta/hello.svg’: Permission denied rm: cannot remove ‘/apps/hello-world/1.0.3/meta/readme.md’: Permission denied rm: cannot remove ‘/apps/hello-world/current’: Permission denied + rm -rf /apps/owncloud/* + rm -rf / rm: it is dangerous to operate recursively on ‘/’ rm: use --no-preserve-root to override this failsafe + rm -rf --no-preserve-root / rm: cannot remove ‘/’: Device or resource busy + sudo rm -rf / /apps/hello-world/1.0.3/bin/hello: 8: /apps/hello-world/1.0.3/bin/hello: sudo: Permission denied $ ls -la /apps/ total 24 drwxr-xr-x 6 clickpkg clickpkg 4096 Dec 30 20:43 . drwxr-xr-x 24 root root 4096 Dec 9 07:30 .. drwxr-xr-x 3 clickpkg clickpkg 4096 Dec 30 19:43 .click drwxr-xr-x 3 clickpkg clickpkg 4096 Dec 30 19:43 docker drwxr-xr-x 3 clickpkg clickpkg 4096 Dec 30 21:06 hello-world drwxr-xr-x 3 clickpkg clickpkg 4096 Dec 30 19:43 owncloud
Test dopadl úspěšně – mazání se nepodařilo. Nicméně je třeba upozornit, že to nebyl nijak zvlášť sofistikovaný test, že jsme nezkoušeli napadnout proces jiné aplikace – vzpomeňme na předchozí článek, Docker běží pod stejným uživatelem jako ssh démon, třeba by to šlo využít, ne? Také jsme nezkoušeli, zda zapisovatelná oblast disku určená pro jednu aplikaci není zapisovatelná z druhé.
Závěr
Ve dvou článcích jsme instalovali virtuální server a do něj php aplikaci owncloud. Popsali jsme si strukturu souborového systému a opatření k zamezení přístupu k jiným aplikacím nebo do operačního systému. Dále jsme prozkoumali strukturu snappy balíčku a ukázali si, jak lze provést nasazení vlastního balíčku na virtuální server. Nakonec jsme provedli malé ověření, že se není snadné smazat systém nebo jinou aplikaci. Přesto nelze očekávat neprůstřelnost systému, jedná se o vývojovou verzi. Na druhou stranu, možná vám jisté riziko nevadí nebo uvedená rizika nejsou v případě samostatné aplikace na virtuálním serveru podstatná.
Lusk.