私は、IPC に Unix ドメイン ソケットを使用するアプリケーションに取り組んでいます。私が知る限り、一般的な方法は、ソケット ファイルを 内に配置することです。私は Ubuntu 18.04 を使用しており、が のシンボリック リンクである/var/run
ことがわかります。残念ながら、フォルダーにアクセスできるのは次のユーザーのみです。var/run
/run
root
ls -Al /
drwxr-xr-x 27 root root 800 Apr 12 17:39 run
したがって、このフォルダーへの書き込みアクセス権を持つのは root のみであり、通常のユーザーは Unix ドメイン ソケットを使用できなくなります。
まず、なぜなのか理解できません。非ルート ユーザーが Unix ドメイン ソケットを使用するにはどうすればいいのでしょうか。もちろんホーム フォルダーを使用することもできますが、正しい一般的な方法を使用することをお勧めします。
答え1
ユーザーが特別なシステム ユーザーでない場合は、ユーザーのホーム ディレクトリの dotfile または dotdir にソケットを作成しても問題ありません。唯一の問題は、NFS を介して複数のマシン間で共有されるホーム ディレクトリの場合ですが、ソケット名にホスト名を含めることで簡単に回避できます。
Linux/Ubuntuでは、"抽象的な"Unix ドメイン ソケットは、ファイルシステム内のパスや inode を使用しません。抽象的な Unix ソケットは、アドレス/パスが NUL バイトで始まるソケットです。
抽象的な
sun_path[0]
: 抽象ソケット アドレスは、 がヌル バイト ( ) であるという事実によって (パス名ソケットと) 区別されます\0
。
sun_path
この名前空間のソケットのアドレスは、指定された長さのアドレス構造体でカバーされる の追加バイトによって指定されます。(名前の null バイトには特別な意味はありません。) 名前はファイルシステムのパス名とは関係ありません。抽象ソケットのアドレスが返される場合、返される はaddrlen
よりも大きくsizeof(sa_family_t)
(つまり、2 よりも大きい)、ソケットの名前は(addrlen - sizeof(sa_family_t))
の最初のバイトに含まれますsun_path
。
抽象 Unix ソケット アドレス内の NUL バイトは、ユーザーに表示されるか、ユーザーによって入力されるときに、通常は@
s に置き換えられます。多くのプログラムでは、通常の s をまったくエスケープしなかったり@
、最初のバイトだけが NUL になる可能性があると想定したりするため、この点で大きな誤りを犯します。
通常の Unix ソケット パスとは異なり、抽象 Unix ソケット名はセマンティクスが異なり、誰でもバインドでき (名前がまだ使用されていない場合)、誰でも接続できます。
ファイル/ディレクトリの権限に依存してソケットに接続できるユーザーを制限したり、たとえば root だけがディレクトリ内にソケットを作成できると想定したりするのではなく、ピアの資格情報getsockopt(SO_PEERCRED)
(ピアに接続またはバインドしたユーザーの uid/pid を取得する) またはSCM_CREDENTIALS
補助メッセージ (ソケット経由でメッセージを送信したユーザーの uid/pid を取得する) を確認する必要があります。
これは(通常のファイル権限チェックを置き換えること)また、私の意見では、 SO_PEERCRED
/の唯一の合理的な使用法でもありますSCM_CREDENTIALS
。
答え2
Unix ドメイン ソケットは に直接アクセスするべきではありません/run
。 内にフォルダーを作成し/run
、たとえば/run/my-ipc
ユーザーに適切な権限を与えて、そのフォルダーに書き込む必要があります。
起動時にフォルダを再作成する必要があります。この質問いくつかの代替案を説明します。