systemd的沙盒功能主要有以下幾項。
限制文件讀寫和訪問權限
為進程設置一個新的文件系統名字空間,也就是限制進程可訪問的文件系統范圍。每個選項的值都是一個以空格分隔的絕對路徑列表。注意,這里所說的“絕對路徑”實際上是以主機或容器根目錄(也就是運行systemd的系統根目錄)為基準的絕對路徑。如果路徑是一個軟連接,那么在追蹤軟連接時將以RootDirectory=/RootImage=設置的根目錄為基準。對于ReadWritePaths=中列出的路徑,進程從名字空間內訪問與從外部訪問的權限是一樣的。對于ReadOnlyPaths=中列出的路徑,即使進程從外部訪問時擁有寫入權限,當從名字空間內訪問時,進程也依然只能擁有只讀權限。將ReadWritePaths=嵌套于ReadOnlyPaths=內,可以將可寫子目錄嵌套在只讀目錄內。當ProtectSystem=strict時,可以使用ReadWritePaths=設置可寫入路徑的白名單。對于InaccessiblePaths=中的路徑,進程從名字空間內訪問時沒有任何權限(既不能讀取也不能寫入)。
限制syscall系統調用
設置進程的系統調用過濾器,
SystemCallFilter的值是一個以空格分隔的系統調用名稱列表(默認為白名單)。如果進程使用了列表之外的系統調用,則將會立即被SIGSYS信號殺死,這時可以在列表開頭添加~字符(表示反轉),將其列入黑名單,也就是僅禁止列表中列出的系統調用。如果進程在用戶模式下運行或者在不含CAP_SYS_ADMIN capability的系統模式下(例如設置了User=nobody)運行,那么SystemCallFilter將自動隱含NoNewPrivileges=yes的設置。該選項依賴于內核的Secure Computing Mode 2接口(seccomp filtering),常用于強制建立一個最小化的沙盒環境。注意execve、exit、exit_group、getrlimit、rt_sigreturn、sigreturn以及查詢系統時間與暫停執行(sleep)的系統調用是默認隱含于白名單中的。上述配置可以被多次使用以融合多個過濾器。若將SystemCallFilter選項的值設為空,則表示清空先前所有已設置的過濾器,此選項不影響帶有“+”前綴的命令。限制用戶權限
將PrivateUsers的值設為yes表示為進程設置一個新的用戶名字空間,并僅在其中保留最小化的user/group映射。具體說來就是僅在該名字空間內保留“root”用戶與組,以及單元自身的用戶與組,同時將所有其他用戶與組統一映射到“nobody”用戶與組,這樣就可以安全地將該單元所使用的user/group數據庫從主機系統中剝離出來了,從而為該單元創建一個有效的沙盒環境。所有不屬于“root”或該單元自身用戶的文件、目錄、進程、IPC對象等資源,在該單元內部依然可見,但是它們將會變為全部屬于“nobody”用戶與組的資源。開啟此選項之后,無論單元自身的用戶與組是否為“root”,在主機的名字空間內,該單元內的所有進程都將以非特權用戶身份運行。特別地,這意味著該單元內的進程在主機的名字空間內沒有任何能力(capability),但是在該單元的用戶名字空間內部,仍然擁有全部capability。諸如CapabilityBoundingSet=之類的設置,其默認值是no,意味著其進程僅在該單元的用戶名字空間內部有意義,而不是在整個主機的名字空間內有意義。PrivateUsers選項在與RootDirectory=/RootImage=一起使用時比較有意義,因為在此場景中僅需要映射“root”“nobody”以及單元自身的用戶與組。
限制網絡訪問
將PrivateNetwork的值設為yes,表示為進程設置一個新的網絡名字空間,并在其中僅配置一個“lo”本地回環設備,不配置任何物理網絡設備,這可以有效關閉進程對實際物理網絡的訪問。通過JoinsNamespaceOf=選項可以將多個單元運行在同一個私有的網絡名字空間中。注意,此選項將會從主機斷開所有套接字(包括AF_NETLINK與AF_UNIX),同時,進程也無法訪問那些位于抽象套接字名字空間中的AF_UNIX套接字(不過依然可以訪問位于文件系統上的AF_UNIX套接字)。PrivateNetwork的默認值是no。
systemd的沙盒功能主要有以下這些:
限制文件讀寫和訪問權限:為進程設置一個新的文件系統名字空間,也就是限制進程可訪問的文件系統范圍。每個選項的值都是一個以空格分隔的絕對路徑列表。注意,這里所說的“絕對路徑”實際上是以主機或容器根目錄(也就是運行systemd的系統根目錄)為基準的絕對路徑。如果路徑是一個軟連接,那么在追蹤軟連接時將以RootDirectory=/RootImage=設置的根目錄為基準。對于ReadWritePaths=中列出的路徑,進程從名字空間內訪問與從外部訪問的權限是一樣的。對于ReadOnlyPaths=中列出的路徑,即使進程從外部訪問時擁有寫入權限,當從名字空間內訪問時,進程也依然只能擁有只讀權限。將ReadWritePaths=嵌套于ReadOnlyPaths=內,可以將可寫子目錄嵌套在只讀目錄內。當ProtectSystem=strict時,可以使用ReadWritePaths=設置可寫入路徑的白名單。對于InaccessiblePaths=中的路徑,進程從名字空間內訪問時沒有任何權限(既不能讀取也不能寫入)。
限制syscall系統調用:設置進程的系統調用過濾器,
SystemCallFilter的值是一個以空格分隔的系統調用名稱列表(默認為白名單)。如果進程使用了列表之外的系統調用,則將會立即被SIGSYS信號殺死,這時可以在列表開頭添加~字符(表示反轉),將其列入黑名單,也就是僅禁止列表中列出的系統調用。如果進程在用戶模式下運行或者在不含CAP_SYS_ADMIN capability的系統模式下(例如設置了User=nobody)運行,那么SystemCallFilter將自動隱含NoNewPrivileges=yes的設置。該選項依賴于內核的Secure Computing Mode 2接口(seccomp filtering),常用于強制建立一個最小化的沙盒環境。注意execve、exit、exit_group、getrlimit、rt_sigreturn、sigreturn以及查詢系統時間與暫停執行(sleep)的系統調用是默認隱含于白名單中的。上述配置可以被多次使用以融合多個過濾器。若將SystemCallFilter選項的值設為空,則表示清空先前所有已設置的過濾器,此選項不影響帶有“+”前綴的命令。限制用戶權限:將PrivateUsers的值設為yes表示為進程設置一個新的用戶名字空間,并僅在其中保留最小化的user/group映射。具體說來就是僅在該名字空間內保留“root”用戶與組,以及單元自身的用戶與組,同時將所有其他用戶與組統一映射到“nobody”用戶與組,這樣就可以安全地將該單元所使用的user/group數據庫從主機系統中剝離出來了,從而為該單元創建一個有效的沙盒環境。所有不屬于“root”或該單元自身用戶的文件、目錄、進程、IPC對象等資源,在該單元內部依然可見,但是它們將會變為全部屬于“nobody”用戶與組的資源。開啟此選項之后,無論單元自身的用戶與組是否為“root”,在主機的名字空間內,該單元內的所有進程都將以非特權用戶身份運行。特別地,這意味著該單元內的進程在主機的名字空間內沒有任何能力(capability),但是在該單元的用戶名字空間內部,仍然擁有全部capability。諸如CapabilityBoundingSet=之類的設置,其默認值是no,意味著其進程僅在該單元的用戶名字空間內部有意義,而不是在整個主機的名字空間內有意義。PrivateUsers選項在與RootDirectory=/RootImage=一起使用時比較有意義,因為在此場景中僅需要映射“root”“nobody”以及單元自身的用戶與組。
限制網絡訪問:將PrivateNetwork的值設為yes,表示為進程設置一個新的網絡名字空間,并在其中僅配置一個“lo”本地回環設備,不配置任何物理網絡設備,這可以有效關閉進程對實際物理網絡的訪問。通過JoinsNamespaceOf=選項可以將多個單元運行在同一個私有的網絡名字空間中。注意,此選項將會從主機斷開所有套接字(包括AF_NETLINK與AF_UNIX),同時,進程也無法訪問那些位于抽象套接字名字空間中的AF_UNIX套接字(不過依然可以訪問位于文件系統上的AF_UNIX套接字)。PrivateNetwork的默認值是no。