OSX Mavericks:如何使 Web 服务器在启动时启动并监听端口 80,而无需以 root 身份运行 Web 服务器?

OSX Mavericks:如何使 Web 服务器在启动时启动并监听端口 80,而无需以 root 身份运行 Web 服务器?

根据Apple 的launchd文档

[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被注释掉了。因此,当我以 root 身份运行 launchd 时,nginx 以 root 身份运行,一切正常。但是当我包含声明时Username: _www,nginx 失败并在日志文件中留下此错误消息:

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

我错过了什么?

答案1

守护进程需要“获取”由 launchd 绑定的套接字(例如launch_data_get_fd:) - 它需要能够识别 launchd 并在内部实现一些逻辑。据我所知,nginx 并非如此,因此我建议使用以下选项之一:

  • 将 nginx 端口调整为 > 1024,然后设置防火墙以将来自/到端口 80 的流量重定向到/从 nginx 端口;
  • 让 launchd 以 root 身份运行 nginx,然后通过更改user其配置文件中的指令让 nginx 放弃​​其权限;

相关内容