ネームサービススイッチ

最終更新: 2023-06-18 04:35:17 +0800 +0800
tags: Linux | Nss
原文は英語で書かれています。あなたはAI翻訳版を読んでいます。

GNU C ライブラリのネームサービススイッチ(NSS)は、アプリケーションの検索 API と、それに応答するデータソースを分離します。コードは getpwnam(3)、getgrnam(3)、getaddrinfo(3)、または getservbyname(3) を呼び出し、glibc は /etc/nsswitch.conf に従ってサービスを選択し、組み合わせます。したがって、呼び出し元を変更しなくても、ローカルファイル、DNS サーバー、ディレクトリサービス、またはシステムサービスから同じ種類の情報を提供できます。

データベースファミリー #

glibc は、passwd、group、shadow、hosts、networks、protocols、services、rpc、ethers、netgroup、aliases、publickey、initgroups などのデータベースを認識します。それぞれに固有の libc インターフェースとレコード形式があります。

データベース代表的なインターフェース一般的なローカルソース
passwd, group, shadowgetpwnam, getgrnam, getspnam/etc/passwd, /etc/group, /etc/shadow
hosts, networksgetaddrinfo, getnetbyname/etc/hosts, /etc/networks
services, protocols, rpcgetservbyname, getprotobyname, getrpcbyname/etc/services, /etc/protocols, /etc/rpc

列挙インターフェースも同じポリシーに従います。たとえば、setpwent、getpwent、endpwent が列挙するのは実効的な passwd データベースであり、必ずしも /etc/passwd ではありません。したがって、列挙によってディレクトリサーバーへの問い合わせが発生することがあり、ローカルファイルを読み取る場合よりも大きな、または変化する集合が返される可能性があります。

並行処理を行うコードでは、リエントラントなインターフェースを使用してください。getpwnam_r および同種の関数は、呼び出し元が所有する結果用オブジェクトと文字バッファーを受け取り、エラー番号を返します。また、該当なしの場合は、成功したレコードとして扱うのではなく、結果ポインターを null にして通知します。結果に関する厳密な規約はインターフェースごとに異なるため、すべての失敗を errno に集約せず、該当するマニュアルを確認してください。従来の非リエントラントなインターフェースは、後続の呼び出しによって上書きされる記憶領域へのポインターを返すのが一般的です。

検索順序の設定 #

コメント以外の各エントリーには、データベース名、コロン、サービスの順序付きリストを記述します。

conf
passwd:   files systemd sss
group:    files systemd sss
shadow:   files sss
hosts:    files resolve [!UNAVAIL=return] dns
services: files

files は対応するローカルデータベースを読み取ります。dns はホスト検索に使用されます。resolve と mymachines は、それらを提供する環境で利用できる systemd のホストサービスです。sss、ldap、winbind、mdns は、個別にインストールされるプロバイダーによって提供されます。設定されたサービスが利用できない場合も運用時の動作の一部であり、そのライブラリが必ず存在するという宣言ではありません。

各サービスは、次の 4 種類の NSS ステータスのいずれかを返します。

ステータス意味デフォルトのアクション
successレコードが見つかったreturn
notfound検索は完了したがレコードが見つからなかったcontinue
unavailサービスが応答できないcontinue
tryagainサービスが一時的に応答できないcontinue

角括弧で囲んだ条件は、直前のサービスに対するデフォルトを上書きします。

conf
hosts: files [NOTFOUND=return] dns

この設定では、/etc/hosts での否定的な検索結果を意図的に最終結果とします。[!UNAVAIL=return] は unavail 以外のすべてのステータスに一致します。merge のサポート範囲は限定的です。glibc は [SUCCESS=merge] を使用して一致するグループエントリーを統合しますが、任意のデータベースや getgrent による列挙には適用しません。

設定された動作をテストするときは、ローカルファイルを直接読み取るのではなく NSS を使用する getent を実行してください。

sh
getent passwd root
getent hosts example.com
getent services https

モジュール境界 #

SERVICE という名前のサービスに対して、従来の glibc NSS モジュールは libnss_SERVICE.so.2 という名前の共有オブジェクトです。設定されたデータベースが必要とした時点で、動的ローダーを介して読み込まれます。モジュールは _nss_files_getpwnam_r のようなデータベースおよび操作ごとのシンボルをエクスポートします。モジュールが内部 NSS ステータスを返すと、glibc が nsswitch.conf のアクションを適用します。

モジュール ABI は、意図的に公開検索 API より低水準に設計されています。リエントラントな検索エントリーポイントは、呼び出し元が提供したオブジェクトとバッファーに値を格納し、該当なしとバックエンド利用不可を区別し、そのデータベースの規約に従ってエラー出力を設定する必要があります。モジュールの作成者は、対象のリリースおよびアーキテクチャにおける glibc NSS インターフェースに適合させる必要があります。名前が似た公開 libc 関数をエクスポートしても、NSS バックエンドにはなりません。

NSS は汎用の設定言語ではありません。glibc は自身が実装していないデータベース名を無視しますが、アプリケーションが独自の名前を定義して解析する場合があります。sudoers と subid がその例です。したがって、標準外のエントリーを変更する前に、そのコンシューマーとモジュール ABI の両方を特定してください。

リゾルバーとディレクトリサービスの動作 #

ホスト名解決は files、resolve、dns を経由でき、アイデンティティー解決はローカルファイル、systemd の動的ユーザーサービス、SSSD、LDAP、または Active Directory アダプターを経由できます。そのため、検索が IPC やネットワークのラウンドトリップを待ってブロックする可能性があります。サービスの順序、否定的な結果に対するアクション、デーモンの可用性、ディレクトリのタイムアウト、およびキャッシュは、ログインのレイテンシーと障害時の動作に影響するため、一体として設計する必要があります。

glibc NSS のドキュメントと nsswitch.conf(5) では、設定と libc 側から見た動作を定義しています。

コメント

GitHub で閲覧・コメントする(投稿にはログインが必要です)