Kerberos による完全にパスワード不要の NFS

Kerberos による完全にパスワード不要の NFS

私は NAS を含む小規模なネットワークを持っています。少し手間をかけて、そこに Kerberos サーバーをプロビジョニングしました。Kerberos サーバーにより、ネットワーク上の Linux ホストは安全な NFS マウントを作成できます。KDC で作成されたサービス キーは適切なホストに配布され、マウントは Kerberos セキュリティで構成されます。安全でないマウントは、NAS で構成されたポリシーによってブロックされます。

不便なことに、ユーザーは、KDC からホストにアクティブなチケットを持っている場合にのみ、マウント上のファイルにアクセスできます。この要件は、不便さのために制限的であり、通常のユーザー権限で実行される自動タスクによるマウントへのアクセスを制限することでさらに制限的になります。

NFS の初期の頃は、リモート ボリューム上のファイルは、起動時からシステム セッション全体にわたってローカルとして表示されていました。セキュリティと ID 管理は NFS における Kerberos の重要な利点ですが、ユーザーにチケットの付与を要求することは多くの場合不要です。キー配布とホストへのアクセス制御によって NFS マウントへの不要なアクセスが防止されるため、ユーザー チケットは必要ありません。

理想的には、KDC からチケットを要求したり、プリンシパルを登録する必要もなく、ユーザーが Kerberos セキュリティを備えたマウントにアクセスできるようにしたいと思います。ファイルごとの権限によってアクセスが制限されない限り、どのユーザーもいつでもどのファイルにもアクセスできます。

既存のツールを通じて、この目標シナリオにどれだけ近づくことができるでしょうか?

答え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 を介して、または LDAP 属性0x200000にOR 演算することによって実行できますkrbTicketFlags)。

    kadmin.local modprinc +ok_to_auth_as_delegate host/foo.example.com
    
  2. クライアント プリンシパルのkrbAllowedToDelegateToLDAP 属性を、偽のチケットを作成できる NFS サービス プリンシパルのリストに設定します (値ごとに 1 つのサービス)。

    ldapmodify <<EOF
    dn: krbPrincipalName=host/[email protected],cn=EXAMPLE.COM,ou=Kerberos,o=Example
    add: krbAllowedToDelegateTo
    krbAllowedToDelegateTo: nfs/fs1.example.com
    -
    EOF
    
  3. ルートとして 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#ユーザー偽装-via-constrained-delegation

  5. クライアントのrpc.gssdデーモンが gss-proxy を使用するようにするには、GSS_USE_PROXY=1環境に追加します:

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

KerberosがNFS専用に使用され、各ホストが限られたユーザーセットのみを必要とする場合、ホストはクライアントキータブ(パスワードから派生したキーを保持する)ユーザーのキータブを作成します。これは、キータブによってユーザーのパスワードを保存するのとほぼ同じです。

関連情報