De acordo com a documentação launchd
da Apple :
[launchd] Eliminates the primary reason for running daemons as root.
Because launchd runs as root,
it can create low-numbered TCP/IP listen sockets and hand them off to the daemon.
Isso é bom ... mas como?
Eu quero fazer o seguinte:
- inicie o servidor web Nginx no momento da inicialização
- escuta a porta 80
- execute como
_www
user
qual é exatamente o cenário que a documentação acima está falando. Mas eu não encontrei uma maneira de fazer isso que não me desse uma mensagem de erro bind() to 0.0.0.0:80 failed (13: Permission denied)
.
Aqui está o arquivo .plist que eu tenho em /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>
Como você pode ver, o Username: _www
está comentado. Então, quando eu executo o launchd como root, o nginx roda como root, e tudo funciona bem. Mas quando incluo a declaração Username: _www
, o nginx falha e deixa esta mensagem de erro no arquivo de log:
nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied)
O que estou perdendo?