![如何实现nginx代理的多个服务(例如uwsgi)之间的权限分离?](https://linux22.com/image/664291/%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0nginx%E4%BB%A3%E7%90%86%E7%9A%84%E5%A4%9A%E4%B8%AA%E6%9C%8D%E5%8A%A1%EF%BC%88%E4%BE%8B%E5%A6%82uwsgi%EF%BC%89%E4%B9%8B%E9%97%B4%E7%9A%84%E6%9D%83%E9%99%90%E5%88%86%E7%A6%BB%EF%BC%9F.png)
我维护的一个网站由多个本地应用程序组成,所有应用程序都由同一个代理nginx实例。每个应用程序都在自己的用户下运行,并公开unix套接字可由 Web 服务器组写入www-data
。
所有应用程序用户都是该www-data
组的一部分,因此他们可以chown他们的插座。我如何改进我的设置,以便一个应用程序中的漏洞不再被用来通过直接连接到其他套接字来尝试进一步提升权限?
我以前的解决方案:为每个用户创建一个新组,并将 Web 服务器添加到所有用户组。此解决方案不太可取,因为它使添加/删除应用程序变得复杂,并且需要强制重启 Web 服务器才能更新组。
答案1
类似于服务可以继承特权端口systemd,他们可以访问他们原本无权打开的本地套接字。 系统化创建 unix 套接字并仅将文件描述传递给服务 - 这样,服务不需要套接字文件的访问权限。
使用如下方式设置套接字/etc/systemd/system/example.socket
:(阅读man systemd.socket
)
[Unit]
PartOf=example.service
[Socket]
SocketUser=www-data
SocketMode=0600
ListenStream=%t/example.sock
并像这样使用该套接字/etc/systemd/system/example.service
:(阅读man systemd.unit
)
[Unit]
Requires=example.socket
After=example.socket
[Service]
User=example
WorkingDirectory=~
ExecStart=/usr/bin/uwsgi --uwsgi-socket=fd://3 --opt2 --opt3 ..
请注意,包括 uwsgi 在内的许多程序LISTEN_FDS
在其环境中确实理解,因此硬编码文件描述符 3 通常是不必要的。
使用以下命令应用并启动设备:
systemctl dameon-reload
systemctl start example.service
如果服务帐户随后尝试打开另一个服务的套接字,则他将无法成功 - 因为套接字归其所有并由其独占读取www-data
(即,只有在该用户下运行的 Web 服务器才能访问它们)。