Django与根进程
在我的Django项目中,我需要检查局域网中的一个主机是否处于在线状态,这个检查是通过ICMP ping来实现的。我找到了一些相关的问题,比如这个问题,它讲了如何在Python中进行ping操作,还有这个问题,里面提到了一些关于如何使用sodoers文件的资源。
设置情况
我有一个Device
模型,用来存储局域网中主机的IP地址。在通过一个自定义视图(而不是管理后台)向数据库添加一个新的Device
实例后,我想通过AJAX调用一个API来检查这个设备是否能响应ping。
问题
但是(根据第一个问题中提到的一个库的文档说明)“注意,ICMP消息只能由以root身份运行的进程发送。”
我不想以root用户运行Django,因为这样做是不好的实践。然而,这个过程中的一部分(发送ICMP ping)需要以root身份运行。如果我想通过Django视图发送一个ping包来测试主机是否在线,那么Django本身就必须以root身份运行,因为发起ping的就是这个进程。
解决方案
这是我想到的一些解决方案,我的问题是有没有更好的方法来让Django项目的某些部分以root身份执行,除了这些:
- 以root身份运行Django(请不要这样做!)
- 把“ping请求”放入一个队列,让另一个以root身份运行的进程定期检查并处理。也许可以使用celery之类的工具。
难道没有更简单的方法吗?
我想要类似于“以root身份运行Django”的库,这可能吗?
3 个回答
我不知道你用的是什么系统,但在我遇到的任何电脑上,运行命令行的 ping
程序不需要是管理员(root)。这个程序设置了一个特别的权限位,所以在需要的时候它会自动以管理员身份运行。所以你可以直接使用这个命令。虽然这样会稍微增加一些开销,但相比网络延迟来说,这点影响可以忽略不计。
你这里用的是什么操作系统?你可以写一个小程序,根据你给的参数来完成你想要的功能,然后把这个程序放到sudoers文件里,这样就可以给你的django用户权限,让它以管理员身份运行这个程序。
/etc/sudoers
绝对不可以,以 root 用户身份运行 Django 代码!
我建议你可以写一个 Python 的守护进程(daemon),然后让 Django 和这个守护进程通过 进程间通信(IPC) 来交流。只要你确保对传递的数据进行验证,并且妥善处理这些数据(比如使用 subprocess.call
并传入一个数组等),只传递数据而不是执行的命令,这样就没问题了。
这里有一个使用 web.py 的客户端和服务器的例子:
服务器:http://gist.github.com/788639
客户端:http://gist.github.com/788658
你需要安装 webpy.org,但这个工具还是很值得保留的。如果你能把服务器的 IP 地址(或主机名)硬编码进去,并去掉参数,那就更好了。