歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux管理 >> Linux安全

未來Docker的安全

我在Opensource.com上寫這些有關Docker安全的東西,想闡述的就一點——“紙已經包不住火了(containers do not contain)”

Red Hat和Docker其中一個主要的目標,就是確保這一陳述不是絕對正確的。我在Red Hat的小組仍在努力利用別的安全機制使container更加安全。這些少數的幾個安全特色,我們目前正在攻克,他們未來可能成為影響Docker和container的方式。

用戶namespace
用戶namespace基於內核namespace,可以更好地將主機和容器分離起來。

基本方法就是宿主機創建一系列的UID,例如60000-61000,然後映射到內部的namespace 0-1000,也可以用GID實現。內核會把docker容器內的UID 0 識別、鑒定為外部的UID 60000,任何一個沒有被映射過的進程或者UID在容器內部都會被識別為UID=-1,從而禁止他們訪問容器,包括所有的鏡像都不允許訪問。如果你想使用有用戶namespace認證的鏡像,那麼你就得切換到容器內部root用戶的UID對應的外部ID。另一個問題就是外部UID 0掛載進入容器的卷、硬盤等設備在容器內部是沒有權限訪問的。你必須用`chown`命令將UID切換成內部可以的UID。
chown -R 60000:60000 /var/lib.content
用戶namespace的另一個問題在於,你不許給不同的容器分配不同段的UID進行映射。如果你有成百上千個容器,那麼如何宿主機分配映射的UID就是個問題。

用戶namespace是一個很炫酷的事情,他們可以直接利用namespace的優勢,如果把容器進行如上的操作,那麼我們可以拋棄掉所有的宿主系統提供的功能。也就是說,當用戶namespace生效後,我們可以完全不再需要宿主系統提供的功能。我們也不再需要selinux提供的安全標簽的策略了。

使用案例
三個可以用到用戶namespace的方案如下:
1.只映射UID=0。增加容器之間的隔離度,甚至可以完全拋棄capabilities機制。這樣做無疑可以增強容器和宿主機之間的安全性,但是也不會相對地提升容器之間的隔離度。所以只需要假設所有DOCKER容器的ROOT的外部UID為2,那麼,外部的UID=2映射到容器內部UID=0,外部GID=2映射到內部GID=0,凡是大於2的全部映射到自己。這樣能最大程度的減少從容器內部獲取宿主機的root權限。當然這樣也能減少掛載文件系統時遇到的麻煩。這樣處理之後,內部root用戶mount的磁盤,外部是無法讀取,(也就不會有SUID這個問題)。同樣,其余的關於用戶的namespace的處理也是一樣。

2.openshift式的解決辦法。每個容器都有自己單獨的UID/GID,如同每個用戶都有自己的UID和GID一樣。只有容器用得到內核capabilities時這樣才有必要,用不到的時候意義不大。

3.按照段來映射。每個容器都映射一個UID段,每個容器映射的UID段各不相同。但是復雜性會隨著容器數目增加急劇增加。掛載文件系統可能會成為一個大問題。可以增加一個功能,當容器內部mount的時候便執行對應的chown UID:GID /SRC命令,這樣一定程度上可以解決掛載的問題。

然而我不認為這三個解決方案可以疊加。我也看過對內核“加入容器時,重設mount目錄的UID的提議”,甚至對樂死mount --bind的命令也執行重設UID,但是我覺得這個提議交給那些寫內核的人比較好,我也會繼續參考那些做安全人的意見。

用戶namespace已經並入libcontainer了,也已經打好了能這樣讓docker運行起來的補丁。

Seccomp
有個問題,那就是這裡和別的地方提到的容器隔離措施全都是依賴與內河。空氣和電腦接觸,但是空氣無法和電腦內核交流。但是容器就不一樣,所有的容器都是直接和內核進行交換信息。如果宿主機有個漏洞,那麼這個漏洞就擊垮所有的安全措施,docker容器也會變得無法控制。

X86_64的linux內核有超過600個系統調用。只要其中其中有一個有漏洞,那麼都可以導致容器的權限提升。因此有些系統調用是基本用不到的,所以應該禁止使用這些系統調用。禁止的越多越安全。

Seccomp是google開發的禁止系統調用的沙盒類型的程序。例如Chrome的插件就得管管,畢竟插件都是來自互聯網,沒辦法保證100%的安全。Google在Chrome浏覽器中使用Seccomp執行chrome插件確保系統的安全。

我的同事Paul Moore,決定將Seccomp簡化從而構建一個C庫來管理系統調用庫。現在他的成果Libseccomp也在qemu,lxc,和systemd等軟件中開始使用了。

我們也開始用go封裝這個庫然後再libcontainer中調用,進行過濾系統調用。

一般而言我們認為這些系統調用是可以禁止容器調用的:kexec_load, open_by_handle_at, init_module, finit_module, delete_module, iopl, ioperm, swapon, swapoff, sysfs, sysctl, adjtimex, clock_adjtime, lookup_dcookie, perf_event_open, fanotify_init, kcmp.

我們也在尋求其他可以禁止的系統調用,歡迎給提議。除此之外,我們考慮禁止調用許多舊的網絡調用: Amateur Radio X.25 (3), IPX (4), Appletalk (5), Netrom (6), Bridge (7), ATM VPC (8), X.25 (9), Amateur Radio X.25 PLP (11), DECNet (12), NetBEUI (13), Security (14), PF_KEY key management API (15), 還有所有比AF_NETLINK (16)需求的權限更多的系統調用。

加入系統調用過濾器的另一個方面就是可以過濾掉所有非本架構的調用,例如X86-64的電腦默認情況下是無法使用32位的系統接口的。我們希望這個方案被設置成為seccomp的默認選項。

禁止了其他架構的系統調用,我們可以簡單地認為我們直接縮小了一半被內核提權、內核攻擊的風險。

調整seccomp
類似於系統capabilities和selinux標簽,我們允許使用命令行自己決定自己需要使用/禁止那些系統調用:
docker run -d --security-opt seccomp:allow:clock_adjtime ntpd

這條命令將會允許容器內使用clock_adjtime調用,因為是ntpd服務,所以必須得用來調整時間。
同樣,
docker run -d --security-opt seccomp:deny:getcwd /bin/sh

這條命令將會禁止容器內執行的shell查詢當前自己所在的目錄。redhat的Matt Heon有一個展示這個功能的短片。

視頻地址:https://www.youtube.com/watch?feature=player_embedded&v=sw3NjVMMXz8

我們默認會禁止很多的系統調用,但是仍舊有很多很危險的系統調用沒有被禁止。你可以全部禁止,然後慢慢地加入希望使用的系統調用。

`docker run -d --security-opt seccomp:deny:all --security-opt seccomp:allow:getcwd /bin/sh`
事實上,docker中運行sh需要比getcwd更多的系統調用。被禁止掉的調用都會記錄在`/var/log/autit/audit.log`。如果audit沒有運行的話,那麼將會記錄在`/var/log/messages`中。

未來的docker
 我們將會繼續增強docker的安全功能。如果linux內核中出現新的安全功能,或者linux內核中有安全功能的改進,我們也會去盡量的利用這些功能,加固容器的安全性。

另一個方面是我們開始關注容器的管理。目前的管理方式是,如果你能有權限對docker的socket和端口發送數據的話,那麼你就能對docker做任何事情。(譯注:尤其是端口,docker remote api這種東西目前完全是無法禁止的) 很遺憾的是目前我們的解決辦法只有禁止非root用戶的/run/docker.socket接口的訪問。我們也開始著手增加授權,這樣管理員就能證明自己是管理員,而不是有權力訪問接口的別的用戶。我們也開始增加適當的管理記錄的功能,將管理員對某些容器的是否是特權運行的情況記錄到syslog或者journalctl。除此之外,我們還可能增加基於角色的訪問控制(RBAC),簡單的來說,就是超級管理員控制其他的管理員。例如:
  • 一星級管理員只允許開啟、停止容器。
  • 二星級管理員有權利新建非特權的容器。
  • 三星級管理員有最大的權力運行所有的容器,並且賦予容器最大的權限。

結論
當這些安全措施實施之後,docker容器會更大程度的讓你的宿主機遠離風險。我們的目標就是讓紙也能包下火(the ability for containers to contain,呼應譯文第一段)。
譯文:http://www.oschina.net/translate/docker-security-future
Copyright © Linux教程網 All Rights Reserved