在 Python 中删除 Root 权限

2024-11-13 08:36:00
admin
原创
153
摘要:问题描述:我想让 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 系统上在进程之间来回传递套接字。我所做的就是在开始时分离一个保持超级用户的进程,其余进程的权限降低,然后从另一个进程请求套接字。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用