普通用户帐户和 root 之间有什么区别吗?
我正在开发一个代表用户管理网络接口的应用程序,它调用几个需要 root 才能进行更改的外部程序(例如 ifconfig)。 (具体来说,更改本地接口的IP地址等)在开发过程中,我一直以root身份运行IDE(呃),并以root身份运行调试器(双呃)。 有没有一种好方法让最终用户在非 root 帐户下运行这些程序? 我非常不喜欢 GTK、wxPython、Python 和我的应用程序以 root 身份运行时所呈现的攻击面大小。
我研究过功能,但它们看起来还不成熟,我不确定是否能够在 Python 中使用它们,特别是如果它们是基于线程的。 我没有探索过的唯一选项是设置了 setuid 位并代表 UI 执行所有根类型操作的守护进程。 我很犹豫是否要在项目的早期引入这种复杂性,因为以 root 身份运行对于用户来说并不是一个破坏性的事情。
I'm developing an application that manages network interfaces on behalf of the user and it calls out to several external programs (such as ifconfig) that requires root to make changes. (Specifically, changing the IP address of a local interface, etc.) During development, I have been running the IDE as root (ugh) and the debugger as root (double-ugh). Is there a nice way for the end-user to run these under a non-root account? I strongly dislike the size of the attack surface presented by GTK, wxPython, Python, and my application when it runs as root.
I have looked into capabilities, but they look half-baked and I'm not sure if I'd be able to use them in Python, especially if they are on a thread basis. The only option I haven't explored is a daemon that has the setuid bit set and does all the root-type stuff on behalf of the UI. I'm hesitant to introduce that complexity this early in the project, as running as root is not a dealbreaker for the users.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您关于守护进程的想法有很多优点,尽管它带来了复杂性。 只要操作不需要以 root 身份进行某些用户界面交互,守护程序就允许您控制允许和禁止哪些操作。
但是,您可以使用 SUDO 在 ROOT 和普通用户之间创建受控的妥协...只需向相关用户授予 SUDO 访问权限即可获取他们所需的特定工具。 通过仅允许“允许的”根启动来减少攻击面。
Your idea about the daemon has much merit, despite the complexity it introduces. As long as the actions don't require some user interface interaction as root, a daemon allows you to control what operations are allowed and disallowed.
However, you can use SUDO to create a controlled compromise between ROOT and normal users... simply grant SUDO access to the users in question for the specific tools they need. That reduces the attack surface by allowing only "permitted" root launches.
您想要的是“组”
您创建一个组,指定想要执行操作的帐户属于该组,然后指定您想要访问的资源是该组的成员。
有时组管理可能有点烦人,但它应该允许您做任何您想做的事情,并且被授权的是用户,而不是您的程序。
(如果您希望程序获得授权,您可以创建一个特定的用户来运行它,并为该用户提供适当的组成员身份,然后 su 到程序中的该组以执行操作,而无需授予运行用户该能力。)
What you want is a "Group"
You create a group, specify that the account wanting to do the action belongs to the group, then you specify that the resource you want access to is a member of that group.
Sometimes group management can be kind of irritating, but it should allow you to do anything you want, and it's the user that is authorized, not your program.
(If you want your program authorized, you can create a specific user to run it as and give that user the proper group membership, then su to that group within your program to execute the operation without giving the running user the ability.)
您可以为您的应用程序创建并分发 selinux 策略。 Selinux 允许您进行所需的细粒度访问。 如果您不能或不会使用 selinux,那么守护进程就是您的最佳选择。
You could create and distribute a selinux policy for your application. Selinux allows the kind of fine-grained access that you need. If you can't or won't use selinux, then the daemon is the way to go.
我不会以 root 身份全职运行该应用程序,但您可能想尝试将应用程序 setuid root 或 setuid 为某个可以使用 sudo 等特定应用程序成为 root 的 id。 您也许可以设置一个无法登录的帐户,使用 setuid 更改程序的 ID(在需要时临时),并将 sudo 设置为不提示输入密码,但始终允许访问该帐户来执行特定任务。
这样,您的程序在正常运行时没有特殊权限,仅在需要时提升其权限,并且受 sudo 限制只能运行某些程序。
我已经有一段时间没有做过很多 Unix 开发了,所以我不太确定是否可以设置 sudo 不提示输入密码(或者即使有一个 API),但作为后备,你可以仅在需要时才启用 setuid 为 root。
[编辑] 看起来 sudo 有一个 NOPASSWD 模式,所以我认为它应该可以工作,因为你将程序作为外部命令运行。
I would not run the application full time as root, but you might want to explore making your application setuid root, or setuid to some id that can become root using something like sudo for particular applications. You might be able to set up an account that cannot login, use setuid to change your program's id (temporarily when needed) and have sudo set up to not prompt for password, but always allow access to that account for specific tasks.
This way your program has no special privileges when running normally, only elevates it's privileges when needed, and is restricted by sudo to only running certain programs.
It's been awhile since I've done much Unix development, so I'm not really sure whether it's possible to set up sudo to not prompt for a password (or even if there is an API for it), but as a fallback you could enable setuid to root only when needed.
[EDIT] Looks like sudo has a NOPASSWD mode so I think it should work since you're running the programs as external commands.
传统的方法是创建并使用 setuid 助手来完成您需要的任何操作。 但请注意,正确编写 setuid 帮助程序很棘手(您必须防范多种攻击媒介)。
现代方法是使用守护进程(以 root 身份运行,在启动时启动)来侦听来自应用程序其余部分的请求。 这样,您的攻击面主要限于您选择的 IPC(我建议使用 d-bus,这似乎是现代方式)。
最后,如果您正在管理网络接口,您所做的事情与网络管理器在现代发行版上所做的非常相似。 尝试以某种方式将您正在做的事情与网络管理器集成(这样它就不会与您的操作发生冲突),或者至少看看它是如何工作的,这将是一个好主意。
The traditional way would be to create and use a setuid helper to do whatever you need. Note that, however, properly writing a setuid helper is tricky (there are several attack vectors you have to protect against).
The modern way would be to use a daemon (running as root, started on boot) which listens to requests from the rest of the application. This way, your attack surface is mostly limited to whichever IPC you chose (I'd suggest d-bus, which seems to be the modern way).
Finally, if you are managing network interfaces, what you doing is very similar to what network-manager does on a modern distribution. It would be a good idea to either try to somehow integrate what you are doing with network-manager (so it will not conflict with your manipulations), or at least looks at how it works.
没有一个用户介于“普通”用户和 root 之间。 你有了root,然后你就有了用户; 用户可以具有不同级别的功能。 如果您想要比“普通”用户更强大但不如 root 强大的东西,您只需创建一个具有您想要的功能的新用户,但不要授予它您不希望它拥有的权限。
There's no single user that is halfway between a "normal" user and root. You have root, and then you have users; users can have differing levels of capabilities. If you want something that's more powerful than a "normal" user but not as powerful as root, you just create a new user with the capabilities you want, but don't give it the privileges you don't want it to have.
我对 Python 不太熟悉,无法告诉您该语言中必要的命令是什么,但您应该能够通过分叉并使用管道在父进程和子进程之间进行通信来完成此任务。 大致如下:
这可能比独立守护进程更容易编写,以及运行起来更方便(因为你不需要担心守护进程是否正在运行),同时还允许 GUI 和其他不需要 root 权限的东西以非 root 身份运行。
I'm not familiar enough with Python to tell you what the necessary commands would be in that language, but you should be able to accomplish this by forking and using a pipe to communicate between the parent and child processes. Something along the lines of:
This is likely to be a bit easier to write than an independent daemon, as well as more convenient to run (since you don't need to worry about whether the daemon is running or not), while also allowing the GUI and other things which don't need root powers to be run as non-root.