機能を提供するための新サービスを得ることができない(7)

機能を提供するための新サービスを得ることができない(7)

upstartセキュリティのために、権限のないユーザーとして実行する必要がありますが、権限のあるポート443をバインドする必要がある(Ubuntu 14.04)で始まったデーモンを開発しています。

setcap実行可能ファイルを設定するために使用する関数CAP_NET_BIND_SERVICEです(スクリプトではありません)。私はこれを「許可された」、「有効な」、「継承された」セット(setcap 'cap_net_bind_service+eip' EXEC)に設定しました。

su権限のないユーザーとして直接実行でき、正しく機能します。ポートを正しくバインドし、/proc/PID/statusビットが設定されている正しい機能マスクを表示します。0x400

ところで、これを介してサービスを開始すると、upstartバイナリで指定された機能で実行されずに失敗しますbind()EPERM)。/proc/PID/status表示機能マスクはすべてゼロです。

どんなアイデアがありますか?

答え1

私はこれがバグだと思い、upstartが「予想デーモン」(つまり起動時に2回分岐するサービス)を使用してサービスを開始する方法に関連していると思います。関数(7)を使用するプロセスでstraceを使用すると、その機能も無視されることがわかりました。私は待機するPIDを決定するためにスタートアップがPIDを取得するのに十分な長さの「expect daemon」として指定されたサービスを追跡し、カーネル機能メカニズムが失敗することを疑います。したがって、バグは関数がプロセストレースと対話する方法と、「expectデーモン」を使用してサービスを開始するときにupstartがプロセストレースを使用するという事実にあります(これは前提です)。

簡単なテストで:

  1. 小さなCを書くプログラムポート443にバインドします(関数(7)ではPythonなどの解釈言語を使用できません)。
  2. root 以外のユーザーとして実行し、権限の不足によりバインディングが失敗することを確認してください。
  3. アプリケーションのCAP_NET_BIND_SERVICE機能を設定します。プログラム(ルートとして実行setcap 'cap_net_bind_service+epi' PROGRAM
  4. root以外のユーザーとして実行し、成功したことを確認してください。
  5. ここでstraceとして実行して失敗することを確認してください。

i(厳密に言えば、ステップ3で継承された機能セット(フラグ)はこのテストのために変更する必要はありませんが、forks()私のデーモンのようなプロセスには必要です。)

feature(7) のマニュアルページにはプロセストレースと一緒に使用してはならないという内容がないので、この問題に関してカーネルにバグを報告します。

答え2

1つの回避策は、Expect ForkまたはExpectデーモンを使用せずにデーモンをフォアグラウンドプロセスにすることです。これにより、Upstartはこれをまったく追跡しません。

関連情報