Nix:一個純粹的函式式包管理器

banq發表於2022-02-20

Nix 既是一個Javascript包管理器:一個可以下載和執行的預構建包的來源,也是一種函式性語言,可以幫助我們以可重現的方式編寫“構建表示式”。Nix 表示式是一個具有一個副作用的函式:建立構建本身的規範。

Nix 方法的主要思想是將軟體元件彼此隔離地儲存在中央元件儲存中,路徑名包含構建元件所涉及的所有輸入的加密雜湊。

 

為什麼?

與包管理器打交道是當今開發人員體驗的核心,但仍然充滿陷阱。我們傾向於將我們的信任外包給包快取,例如 NPM 或 Hex,然後將它們返回的任何內容合併到我們的系統中。大多數情況下,這很好用,因為包管理器有誠實行事的動機。

但是,存在單點故障,作為這個中心故障點變得有問題的一個例子是:攻擊者可以修改一個包以在所謂的數字供應鏈攻擊中包含惡意軟體。

這就是今天現有包管理器所沒有的:可重複性。

可重複性是指在您自己的系統上一點一點地重新建立包的構建的能力。無論以您的方式丟擲什麼包,您都可以在本地重新構建它並檢查您是否具有預期的構建輸出。這類似於通過計算其 sha256 雜湊值來驗證從 Web 下載的二進位制檔案,並將其與二進位制檔案釋出者提供的雜湊值進行比較。

它消除了信任提供商的需要,並使開發人員檢測故障或攻擊的成本大大降低。可重複性意味著您的系統和應用程式的安全性,以及您的開發人員的安心。

達到這種可重現狀態的方法是對本地環境不做任何假設。Nix 中的所有內容都必須由使用者明確宣告。大多數構建工具或環境都依賴於對本地環境的假設,並儘可能地處理它,但如果你想提供一種在任何地方構建任何東西的方法,你就必須放棄對本地環境的任何束縛。Nix 通過強制你宣告你想要的包以及如何將它們組合在一起來做到這一點。因為您的環境或構建的每個部分都是明確的,所以您可以實現隔離和可重現性。

 

如何做到? 

首先,使用 Nix 構建的所有內容都放在一箇中央儲存中,預設情況下是 `/nix/store`,這與您的 Linux FHS(檔案系統層次結構標準)不同。

其次,每個構建的工件都用一個雜湊標識,它是包的完整依賴圖的摘要識別符號,涉及的特定於平臺的構建步驟,以及定義如何構建它的 Nix 表示式。

假設您的公司維護了一個 25 年前使用 C 編譯器構建的工具。它無法安全升級,因為如果升級,整個世界的銀行系統都會崩潰。也許您保留一臺專用膝上型電腦作為數字時間膠囊來維護此工具。相反,您可以使用所需的任何版本的工具建立一個 Nix shell,固定且永不升級。這個環境是孤立的,並且可以與系統上的所有其他 C 版本配合使用,因為它只是另一個 Nix 包。您可以與任何人共享此環境,他們只需一個“nix-shell”命令即可擁有與您相同的環境。

 

相關文章