OSX Mavericks:起動時にWebサーバーを起動し、ルートとしてWebサーバーを実行せずにポート80をリッスンするにはどうすればよいですか?


1

Appleのlaunchdドキュメントによると:

[launchd]デーモンをルートとして実行する主な理由を排除します。launchdはルートとして実行されるため、 小さい番号のTCP / IP待機ソケットを作成し、デーモンに渡すことができます

それは良い...しかし、どのように?

私は次のことをしたい:

  • 起動時にNginx Webサーバーを起動します
  • ポート80をリッスンさせます
  • _wwwユーザーとして実行する

これはまさに上記のドキュメントが話しているシナリオです。しかし、bind() to 0.0.0.0:80 failed (13: Permission denied)エラーメッセージが表示されない方法は見つかりませんでした。

ここに私が持っている.plistファイルがあります/Systems/Library/LaunchDemons/homebrew.mxcl.nginx.plist

<!--
Adapted from the .plist file provided as part of
the Mac Homebrew distribution of nginx.
-->

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>


<!-- 
Here's the problem!!

    <key>Username</key>
    <string>_www</string>

-->

<!--
I thought that Sock(et) declarations would be
the way to tell launchd to hand off a port to the
daemon. So I added these lines, but they don't
appear to make any difference at all.
-->

    <key>SockServiceName</key>
    <string>http</string>

    <key>SockType</key>
    <string>stream</string>

    <key>SockFamily</key>
    <string>IP4</string>

    <key>Label</key>
    <string>homebrew.mxcl.nginx</string>

    <key>RunAtLoad</key>
    <true/>

    <key>KeepAlive</key>
    <false/>

    <key>StandardOutputPath</key>
    <string>/var/log/nginx.log</string>

    <key>StandardErrorPath</key>
    <string>/var/log/nginx.log</string>

    <key>ProgramArguments</key>
    <array>
      <string>/usr/local/opt/nginx/bin/nginx</string>
    </array>

    <key>WorkingDirectory</key>
    <string>/usr/local</string>

  </dict>
</plist>

ご覧のとおり、Username: _wwwはコメント化されています。したがって、launchdをルートとして実行すると、nginxはルートとして実行され、すべてが正常に機能します。しかし、Username: _www宣言を含めると、nginxは失敗し、このエラーメッセージがログファイルに残ります。

nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied)

私は何が欠けていますか?


1
launchdを使用しても、それは機能しないと考えています。AFAICTは、rootとして実行する必要があります。その後、nginx自体に特権をドロップさせることができます。nginx.confで何を変更する必要があるのか​​よくわかりませんが、次のようなものがあるはずですUser-_wwwに変更します。
jweyrich 14年

1
@jweyrich私が間違えない限り、Appleのドキュメントは、私が求めていること可能だとはっきり述べています。質問の冒頭をご覧ください。nginxの「ユーザー」ディレクティブを指摘してくれてありがとう。より良い方法が見つからない場合は、それを使用します。ただし、nginxはこのディレクティブをワーカープロセスにのみ適用します。マスタープロセスは引き続きルートとして実行されます。(確認するためにテストしました。)
ピタロウ14年

1
それが可能であると言うとき、あなたは絶対に正しいです、しかし、launchdは魔法をしません。デーモンは、launchdによってバインドされたソケットを取得する必要があります(例launch_data_get_fd:)。launchdに対応し、内部でロジックを実装する必要があります。私の知る限り、nginxには当てはまりません。
jweyrich

1
@jweyrichなるほど。時間を割いていただきありがとうございます。:-)
ピタロウ14年

1
問題ない。どういたしまして。
jweyrich

回答:


2

デーモンは、launchdによってバインドされたソケットを取得する必要があります(例launch_data_get_fd:)。launchdに対応し、内部でロジックを実装する必要があります。私の知る限り、nginxには当てはまらないので、次のオプションのいずれかをお勧めします。

  • nginxポートを1024以上に調整してから、ファイアウォールをセットアップして、ポート80から/へのトラフィックをnginxポートへ/からリダイレクトします。
  • launchdがrootとしてnginxを実行userし、設定ファイルのディレクティブを変更することにより、nginxにその特権を後でドロップさせます。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.