在Python中放弃根权限
我想让一个Python程序在80号端口上开始监听,但之后希望它能在没有管理员权限的情况下运行。有没有办法在不需要管理员权限的情况下使用80号端口或者在运行后放弃管理员权限呢?
6 个回答
5
systemd可以帮你处理这个问题。如果你通过systemd启动你的程序,systemd可以把已经打开的监听端口交给它,而且在第一次连接时也可以激活你的程序。你甚至不需要把它变成后台进程。
如果你选择独立的方式,你需要有CAP_NET_BIND_SERVICE这个能力(可以查查相关的手册)。这可以通过正确的命令行工具逐个程序来设置,或者让你的应用程序(1)以suid root的身份运行(2)启动(3)监听端口(4)立即降低权限。
记住,suid root程序有很多安全方面的考虑(比如干净安全的环境、umask、权限、资源限制等等,这些都是你的程序需要正确设置的)。如果你能使用像systemd这样的工具,那就更好了。
13
我建议你使用 authbind
来启动你的Python程序,这样就不需要以管理员身份运行它了。
58
你不能在没有管理员权限的情况下打开80端口,这是操作系统的限制。所以唯一的解决办法就是在打开端口后放弃管理员权限。
这里有一个在Python中放弃管理员权限的可能解决方案:在Python中放弃权限。这个方法总体上是不错的,但你还需要在函数中添加os.setgroups([])
,以确保不会保留根用户的组成员身份。
我稍微整理了一下代码,去掉了日志记录和异常处理,所以处理OSError
的部分就留给你自己来做(这个错误会在进程无法切换有效的用户ID或组ID时抛出):
import os, pwd, grp
def drop_privileges(uid_name='nobody', gid_name='nogroup'):
if os.getuid() != 0:
# We're not root so, like, whatever dude
return
# Get the uid/gid from the name
running_uid = pwd.getpwnam(uid_name).pw_uid
running_gid = grp.getgrnam(gid_name).gr_gid
# Remove group privileges
os.setgroups([])
# Try setting the new uid/gid
os.setgid(running_gid)
os.setuid(running_uid)
# Ensure a very conservative umask
old_umask = os.umask(077)