1

Согласно launchd Apple документации:

[launchd] Устраняет основную причину запуска демонов от имени пользователя root. Поскольку launchd запускается от имени пользователя root, он может создавать прослушиваемые сокеты TCP/IP с низким номером и передавать их демону.

Это хорошо ... но как?

Я хочу сделать следующее:

  • запустить веб-сервер Nginx во время загрузки
  • прослушать порт 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 от имени пользователя root, nginx запускается от имени пользователя root, и все работает нормально. Но когда я включаю объявление « Username: _www , nginx терпит неудачу и оставляет это сообщение об ошибке в файле журнала:

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

Что мне не хватает?

1 ответ1

2

Демон должен "получить" сокет, связанный с помощью launchd (например: launch_data_get_fd) - он должен быть осведомлен о запуске и реализовать некоторую логику внутри. AFAIK, это не относится к nginx, поэтому я предлагаю один из следующих вариантов:

  • Установите для порта nginx значение> 1024, затем настройте брандмауэр для перенаправления трафика с / на порт 80 на / из порта nginx;
  • Пусть launchd запустит nginx от имени пользователя root и заставит nginx впоследствии отказаться от своих привилегий, изменив user директиву в своем файле конфигурации;

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .