在 Python 中删除 Root 权限

2024-11-13 08:36:00
admin
原创
18
摘要:问题描述:我想让 Python 程序开始监听端口 80,但之后以无 root 权限执行。有没有办法放弃 root 权限或获取端口 80?解决方案 1:如果没有 root 权限,您将无法在端口 80 上打开服务器,这是操作系统级别的限制。因此,唯一的解决方案是在打开端口后放弃 root 权限。以下是在 Pyth...

问题描述:

我想让 Python 程序开始监听端口 80,但之后以无 root 权限执行。有没有办法放弃 root 权限或获取端口 80?


解决方案 1:

如果没有 root 权限,您将无法在端口 80 上打开服务器,这是操作系统级别的限制。因此,唯一的解决方案是在打开端口后放弃 root 权限。

以下是在 Python 中删除 root 权限的一种可能解决方案:在 Python 中删除权限。这通常是一个很好的解决方案,但您还必须添加os.setgroups([])函数以确保不保留 root 用户的组成员身份。

我复制并清理了一些代码,删除了日志记录和异常处理程序,因此由您来OSError正确处理(当进程不允许切换其有效 UID 或 GID 时将抛出该异常):

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)

解决方案 2:

我建议使用authbind来启动你的 Python 程序,这样就不需要以 root 身份运行了。

https://en.wikipedia.org/wiki/Authbind

解决方案 3:

  1. systemd 可以为您做到这一点,如果您通过 systemd 启动您的程序,systemd 可以将已经打开的监听套接字交给它,并且它也可以在第一次连接时激活您的程序。您甚至不需要对其进行守护进程化。

  2. 如果您要采用独立方法,则需要 CAP_NET_BIND_SERVICE 功能(检查功能手册页)。这可以在程序中逐个使用正确的命令行工具完成,或者通过让您的应用程序 (1) 成为 suid root (2) 启动 (3) 监听端口 (4) 立即放弃权限/功能。

请记住,suid root 程序带有许多安全注意事项(干净安全的环境、umask、权限、rlimits,所有这些都是您的程序必须正确设置的内容)。如果您可以使用类似 systemd 的东西,那就更好了。

解决方案 4:

每当我需要放弃权限时,要求用户输入其用户名和组并不是一个好主意。这是 Tamás 代码的一个略微修改的版本,它将放弃权限并切换到发起 sudo 命令的用户。我假设您正在使用 sudo(如果不是,请使用 Tamás 的代码)。

#!/usr/bin/env python3

import os, pwd, grp

#Throws OSError exception (it will be thrown when the process is not allowed
#to switch its effective UID or GID):
def drop_privileges():
    if os.getuid() != 0:
        # We're not root so, like, whatever dude
        return

    # Get the uid/gid from the name
    user_name = os.getenv("SUDO_USER")
    pwnam = pwd.getpwnam(user_name)

    # Remove group privileges
    os.setgroups([])

    # Try setting the new uid/gid
    os.setgid(pwnam.pw_gid)
    os.setuid(pwnam.pw_uid)

    #Ensure a reasonable umask
    old_umask = os.umask(0o22)


#Test by running...
#./drop_privileges
#sudo ./drop_privileges
if __name__ == '__main__':
    print(os.getresuid())
    drop_privileges()
    print(os.getresuid())

解决方案 5:

以下是对Tamás 的回答的进一步改编,并进行了以下更改:

  • 使用该python-prctl模块将 Linux 功能放到要保留的指定功能列表中。

  • 可以选择将用户作为参数传递(默认查找运行的用户sudo)。

  • 它设置所有用户的组和HOME

  • 它可选择改变目录。

(但是,我对使用此功能还比较陌生,因此我可能错过了一些东西。它可能无法在较旧的内核(<3.8)或禁用文件系统功能的内核上运行。)

def drop_privileges(user=None, rundir=None, caps=None):
    import os
    import pwd

    if caps:
        import prctl

    if os.getuid() != 0:
        # We're not root
        raise PermissionError('Run with sudo or as root user')

    if user is None:
        user = os.getenv('SUDO_USER')
        if user is None:
            raise ValueError('Username not specified')
    if rundir is None:
        rundir = os.getcwd()

    # Get the uid/gid from the name
    pwnam = pwd.getpwnam(user)

    if caps:
        prctl.securebits.keep_caps=True
        prctl.securebits.no_setuid_fixup=True

    # Set user's group privileges
    os.setgroups(os.getgrouplist(pwnam.pw_name, pwnam.pw_gid))

    # Try setting the new uid/gid
    os.setgid(pwnam.pw_gid)
    os.setuid(pwnam.pw_uid)

    os.environ['HOME'] = pwnam.pw_dir

    os.chdir(os.path.expanduser(rundir))

    if caps:
        prctl.capbset.limit(*caps)
        try:
            prctl.cap_permitted.limit(*caps)
        except PermissionError:
            pass
        prctl.cap_effective.limit(*caps)

    #Ensure a reasonable umask
    old_umask = os.umask(0o22)

其使用方法如下:

drop_privileges(user='www', rundir='~', caps=[prctl.CAP_NET_BIND_SERVICE])

解决方案 6:

除非您在做了一些您不想以超级用户身份执行的事情后需要请求套接字,否则大部分方法都是可行的。

不久前我做了一个叫tradesocket的项目。它允许你在 posix 系统上在进程之间来回传递套接字。我所做的就是在开始时分离一个保持超级用户的进程,其余进程的权限降低,然后从另一个进程请求套接字。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用