玖玖资源站亚洲av_日本乱偷中文字幕一二三区_久久这里只有精品98_亚洲特级黄片视频_男女很舒服爽视频免费_国产一二三四2021精字窝_国产高潮白浆一区_自拍日本高清三级_秘书高跟黑色丝袜国产在线_亚洲A v永久无码精品网站色欲

NEWS

新聞

了解優(yōu)麒麟最新資訊,關注社區(qū)和產品動態(tài)。

NEWS

Learn about the latest news.

震驚!沒想到你是這樣的flatpak...

2017-07-14 14:46:08

wKiom1fttFDyDC8bAADMI5-DKJ0214.jpg-wh_651x-s_3287731442.jpg

引言

之前我們介紹過如何在優(yōu)麒麟和銀河麒麟社區(qū)版上構建snap/flatpak包(傳送門),今天我們來更深入的認識下flatpak:

 

Flatpak(前世為xdg-app) 是一種用于構建,分發(fā),安裝和運行應用程序的技術。它主要針對的是Linux桌面,通過在沙箱中隔離應用程序來提高Linux桌面的安全性,允許應用程序安裝在任何Linux發(fā)行版上。

 

歷史:

2013: 在GNOME Developer Experience hackfest, Brussels大會后,萌生在GNOME中使用應用程序容器技術的念頭,次年開始開發(fā)。

2016年5月: 第一個主版本xdg-app發(fā)布。

    6月:重命名為flatpak。

    8月:endless OS 3.0, 第一個默認支持Flatpak的發(fā)行版。

          11月:ClearLinux聲明采用flatpak。

2017年2月: 最新的flatpak已經可以在Arch, Debian, Fedora, Gentoo, Mageia, openSUSE, Ubuntu等的最新版本上運行。

 

基本概念:

運行時(runtimes)

“運行時”提供應用程序所需的基本依賴。有各種各樣的“運行時”,比如“Freedesktop運行時”,“GNOME運行時”?!癋reedesktop運行時”包含一系列必要的庫和服務,包括D-Bus, GLib, PulseAudio, X11和Wayland等?!癎NOME運行時”基于“FreeDesktop運行時”,增加了一些GNOME平臺相關的庫,比如GStreamer, GTK+, GVFS等。必須針對運行時構建每個應用程序,并且必須在主機系統(tǒng)上安裝此運行時才能運行應用程序。用戶可以同時安裝多個不同的運行時,包括不同版本的同一個運行時。KDE runtime正在開發(fā)中。

每一個運行時可以看做一個’/usr’ 文件系統(tǒng),當程序運行時,它的運行時掛載在‘/usr’上。

 

捆綁庫(Bundled libraries)

當一個程序需要的依賴不在運行時中,使用捆綁庫來綁定這些依賴到程序上。

 

SDK(軟件開發(fā)套件)

SDK也是一個“運行時”,是用于構建應用程序的特殊類型的運行時,它包含了構建和打包工具(‘devel’ parts),如頭文件,編譯器和調試器。通常,SDK與“運行時”配對,由應用程序使用。

 

擴展(Extensions)

一個擴展是對于運行時或程序的可選插件,一般用于把translations和debug信息從運行時分離出來,比如, org.freedesktop.Platform.Locale 可以追加到org.freedesktop.Platform運行時上用來添加翻譯。

 

沙箱(Sandbox)

使用Flatpak,每個應用程序都是在孤立的環(huán)境中構建和運行的。默認情況下,應用程序只能“查看”自身及其“運行時”,訪問用戶文件,網絡,graphics sockets,總線和設備上的子系統(tǒng)必須明確授予權限,訪問其他內容(如其他進程)是不允許的。(可以通過Portals機制在沙箱內訪問外面系統(tǒng),比如打印,截圖等)

 

原理:

Flatpak主要使用了如下技術:

1. bubblewrap:依賴它作為沙箱的底層實現(xiàn)限制了應用程序訪問操作系統(tǒng)或用戶數據的能力,并且提供了非特權用戶使用容器的能力。

2. Systemd將各個subsystem和cgroup樹關聯(lián)并掛載好,為沙箱創(chuàng)建 cgroups。

3. D-Bus, 為應用程序提供高層APIs

4. 使用Open Container InitiativeOCI格式作為單文件的傳輸格式,方便傳輸。

5. 使用OSTree系統(tǒng)用于版本化和分發(fā)文件系統(tǒng)樹。

6. 使用Appstream 元數據,使得Flatpak應用程序在軟件中心可以完美呈現(xiàn)出來。

而其中最重要的當屬bubblewrap,它是整個應用沙箱構建的關鍵,主要利用了如下內核特性: 

Namespaces:

命名空間是對全局系統(tǒng)資源的一個封裝隔離,使得處于不同namespace的進程擁有獨立的全局系統(tǒng)資源,改變一個namespace中的系統(tǒng)資源只會影響當前namespace里的進程,對其他namespace中的進程沒有影響。它控制了進程的可見范圍,例如網絡、掛載點、進程等等。同時使得非特權用戶可以創(chuàng)建沙箱。它有以下幾類:

     Mount namespace (CLONE_NEWNS): 

用來隔離文件系統(tǒng)的掛載點, 使得不同的mount namespace擁有自己獨立的掛載點信息,不同的namespace之間不會相互影響,這對于構建用戶或者容器自己的文件系統(tǒng)目錄非常有用。bubblewrap 總是創(chuàng)建一個新的mount namespace, root掛載在tmpfs上,用戶可以明確指定文件系統(tǒng)的哪個部分在沙盒中是可見的。

     User namespaces (CLONE_NEWUSER): 

用來隔離用戶權限相關的Linux資源,包括用戶ID 和組ID, 在不同的user namespace中,同樣一個用戶的user ID 和group ID可以不一樣,換句話說,一個用戶可以在父user namespace中是普通用戶,在子user namespace中是超級用戶(超級用戶只相對于子user namespace所擁有的資源,無法訪問其他user namespace中需要超級用戶才能訪問資源)。

 IPC namespaces (CLONE_NEWIPC): 

沙箱會得到所有不同形式的IPCs的一份拷貝,比如SysV 共享內存和信號量等。

 PID namespaces (CLONE_NEWPID): 

用來隔離進程的ID空間,沙箱內的程序看不見任何沙箱外的進程,此外, bubblewrap 會運行一個pid為1的程序在容器中,用來處理回收子進程的需求。

 Network namespaces (CLONE_NEWNET): 

用來隔絕網絡,在它自己的network namespace中只有一個回環(huán)設備。 

 UTS namespace (CLONE_NEWUTS):

允許沙箱擁有自己獨立的hostname和domain name.

Cgroups:

cgroup和namespace類似,也是將進程進行分組,但它的目的和namespace不一樣,namespace是為了隔離進程組之間的資源,而cgroup是為了對一組進程進行統(tǒng)一的資源監(jiān)控和限制。

Bind Mount:

將一個目錄(或文件)中的內容掛載到另一個目錄(或文件)上.

Seccomp rules:

Linux kernel 所支持的一種簡潔的sandboxing機制。它能使一個進程進入到一種“安全”運行模式,該模式下的進程只能調用4種系統(tǒng)調用(system calls),即read(), write(), exit()和sigreturn(),否則進程便會被終止。

同時,bubblewrap 使用PR_SET_NO_NEW_PRIVS 關閉 setuid 二進制程序。

當一個進程或其子進程設置了PR_SET_NO_NEW_PRIVS 屬性,則其不能訪問一些無法share的操作,如setuid, 和chroot。

 

實驗:

接下來,我們通過如下方式進入到一個flatpak創(chuàng)建的沙箱中:

安裝程序所需的“運行時”和Sdk:

$ flatpak remote-add --from gnome https://sdk.gnome.org/gnome.flatpakrepo

$ flatpak install gnome org.gnome.Platform//3.24 org.gnome.Sdk//3.24

安裝gedit:

$ flatpak remote-add --from gnome-apps https://sdk.gnome.org/gnome-apps.flatpakrepo

$ flatpak install gnome-apps org.gnome.gedit

創(chuàng)建一個‘devel sandbox’中的shell:

$ flatpak run --devel --command=bash org.gnome.gedit

可以看到此沙箱中有3個進程,且flatpak-bwrap pid為1。

$ ps

  PID TTY          TIME CMD

   1 ?        00:00:00 flatpak-bwrap

   2 ?        00:00:00 bash

   5 ?        00:00:00 ps

查看當前進程所屬的namespace,括號里的數字標識不同的namespace:

$ ls -l /proc/&&/ns

total 0

 15:48 cgroup -> cgroup:[4026531835]

 15:48 ipc -> ipc:[4026531839]

 15:48 mnt -> mnt:[4026532241]

 15:48 net -> net:[4026532244]

 15:48 pid -> pid:[4026532242]

 15:48 user -> user:[4026532371]

 15:48 uts -> uts:[4026531838]

然后在主機中打開另一個終端,查看主機中當前進程的namespace:

$ ls /proc/&&/ns

total 0

 15:56 cgroup -> cgroup:[4026531835]

 15:56 ipc -> ipc:[4026531839]

 15:56 mnt -> mnt:[4026531840]

 15:56 net -> net:[4026531957]

 15:56 pid -> pid:[4026531836]

 15:56 user -> user:[4026531837]

 15:56 uts -> uts:[4026531838]

可以看到沙箱中的進程所屬的namespace與主機環(huán)境下進程的namespace相比,它們的mount ,net, pid, user namespace不同,這時我們在主機環(huán)境下把ping文件拷貝進主目錄(gedit聲明了對’/home’的訪問權限),然后在sandbox shell中執(zhí)行ping 192.168.0.1,會發(fā)現(xiàn)報錯:

$ ./ping 192.168.0.1

ping: socket: Operation not permitted

因為gedit沒有申請網絡權限,它和主機在不同的network namespaces中。

 

怎么樣,是不是很有趣,你還能在這個沙箱中做更多有趣的探索,行動起來,一起來flatpak吧!