透過 kerberos 實現完全無密碼的 nfs

透過 kerberos 實現完全無密碼的 nfs

我有一個包含 NAS 的小型網路。我通過一些努力在其上配置了一個 Kerberos 伺服器。 Kerberos 伺服器允許網路上的 Linux 主機建立安全的 NFS 掛載。在 KDC 上建立的服務金鑰將分發到適當的主機,並且裝載配置有 Kerberos 安全性。不安全的安裝會被 NAS 上設定的策略阻止。

不方便的是,使用者只有在主機上擁有來自 KDC 的活動票證時才可以存取裝載上的檔案。由於不方便,並且透過使用常規用戶權限運行的自動化任務來限制對掛載的訪問,因此該要求是限制性的。

在 NFS 的早期,遠端磁碟區上的文件將顯示為本機文件,從啟動時開始,並在整個系統會話中持續存在。安全性和身分管理是 NFS 中 Kerberos 的重要優勢,但要求使用者取得票證通常是不必要的。由於金鑰分發和對主機的受控訪問可以防止對 NFS 安裝進行不必要的訪問,因此我不需要用戶票證。

理想情況下,我希望使用者能夠存取具有 Kerberos 安全性的安裝,而無需向 KDC 請求票證,甚至不需要在其上註冊主體。任何使用者都可以隨時存取任何文件,前提是存取不受每個文件權限的限制。

透過現有工具,距離這個目標場景有多近?

答案1

簡而言之,目前的 NFS Kerberos 驗證機制 (RPCSEC_GSS) 不支援此功能。撥打電話的委託人是獲得存取權限的人。所以如果你不希望用戶手動取得門票,那麼你需要讓主持人自動取得門票為了他們。

將來,較新的 RPCSEC_GSSv3 協定可能具有允許主機模擬任意使用者的選項,但它尚未完成或實作。


如果您希望允許主機模擬任何 UID,那麼您根本不需要 Kerberos – 切換回sec=sys「過去」使用的安全模式。在這種模式下,主機實際上可以指定使用者的符號識別碼。 (當然,權限檢查仍然會發生。)

最後,允許主機透過 Kerberos 模擬任何使用者(使用主機的 /etc/krb5.keytab 進行驗證)與允許主機透過基本 UID 聲明模擬任何使用者(使用主機的 IPsec 進行驗證)之間沒有功能差異或WireGuard 私鑰匙或)—後者將為您提供比GSSAPI 更高的效能。


在 Kerberos 中,當僅使用現有工具時(沒有徹底實現某種 RPC 主機級身份驗證),您擁有的最接近的東西是協議轉換的約束委託(S4U2Self + S4U2Proxy),其中允許服務以使用者的名義取得特定其他服務的票證。它通常用於 Active Directory 環境,但也受到 MIT Kerberos KDC(以及大概Heimdal KDC – 程式碼就在那裡,感謝 Samba,但我不知道如何在 Heimdal 上啟用它)。

若要在 MIT Kerberos KDC 中啟用此功能,您將需要使用 LDAP 後端;基於檔案的 HDB 後端不支援儲存附加欄位。

  1. 在客戶端的主機主體上設定ok_to_auth_as_delegate主體標誌(可以透過 kadmin 或透過 ORing0x200000krbTicketFlagsLDAP 屬性來完成)。

    kadmin.local modprinc +ok_to_auth_as_delegate host/foo.example.com
    
  2. 將用戶端主體的krbAllowedToDelegateToLDAP 屬性設定為可能為其建立虛假票證的 NFS 服務主體清單。 (每個值一項服務。)

    ldapmodify <<EOF
    dn: krbPrincipalName=host/[email protected],cn=EXAMPLE.COM,ou=Kerberos,o=Example
    add: krbAllowedToDelegateTo
    krbAllowedToDelegateTo: nfs/fs1.example.com
    -
    EOF
    
  3. 以 root 身分測試 S4U 功能是否有效:

    # Acquire host credentials using system keytab
    host_cc=FILE:/tmp/krb5cc_host
    kinit -c $host_cc -k
    klist -c $host_cc
    
    # Acquire NFS tickets on behalf of the user using S4U2Proxy
    kvno -c $host_cc -I $user_name -P nfs/fs1.example.com
    klist -c $host_cc
    
    # Do the same, but put the tickets in that user's cache
    # so that rpc.gssd would be able to find them
    user_cc=FILE:/tmp/krb5cc_$(id -u $user)
    kvno -c $host_cc -I $user -P nfs/fs1.example.com --out-cache $user_cc
    chown $user: $user_cc
    
  4. 安裝gss代理在客戶端上,並編輯其包含內容nfs-client.conf以使用 S4U2Proxy 而不是單一客戶端金鑰表:

    [service/nfs-client]
      mechs = krb5
      cred_store = keytab:/etc/krb5.keytab
      cred_store = ccache:FILE:/var/lib/gssproxy/clients/krb5cc_%U
      impersonate = yes
      allow_any_uid = yes
      trusted = yes
      euid = 0
    

    這個例子是基於https://github.com/gssapi/gssproxy/blob/main/docs/NFS.md#user-impersonation-via-constrained-delegation

  5. 配置客戶端的rpc.gssdGSS_USE_PROXY=1透過加入環境來使用 gss-proxy 的守護程式:

    # systemctl edit rpc-gssd
    
    [Service]
    Environment=GSS_USE_PROXY=1
    
    # systemctl restart rpc-gssd
    

如果 Kerberos 專門用於 NFS,而每個主機只需要有限的使用者集,那麼該主機可以儲存客戶端密鑰表(保存密碼派生金鑰)這些使用者。這大致相當於儲存用戶的密碼,正如密鑰表允許的那樣

相關內容