通过 Python 的 dbus 模块控制 CentOS 中的 firewalld?

Posted

技术标签:

【中文标题】通过 Python 的 dbus 模块控制 CentOS 中的 firewalld?【英文标题】:Control firewalld in CentOS via Python's dbus module? 【发布时间】:2016-03-27 22:54:29 【问题描述】:

我的目标是使用 Python 在 CentOS 7 机器上自动配置防火墙。

操作系统带有firewalld,所以这就是我正在使用的。我查看了它,发现它使用 dbus(我从未听说过或处理过任何这些 - 如果我说的任何内容不正确,请纠正我。)

我找到了有关如何使用 Python 控制 dbus 进程的文档: http://dbus.freedesktop.org/doc/dbus-python/doc/tutorial.txt

我查了一下,操作系统附带的 Python 版本包括 dbus 模块,所以这似乎是一个有希望的开始。

该文档表明我需要了解更多关于 firewalld 通过 dbus 接口公开的内容。所以我做了更多的研究,发现了这个: https://www.mankier.com/5/firewalld.dbus

第一个文件说我需要从一个“知名名称”开始。他们的例子是org.freedesktop.NetworkManager。第二个文档的标题是firewalld.dbus,所以我认为这是一个很好的名称,因为该文档没有在其他任何地方明确给出名称。

第一个文档还说我需要一个对象路径的名称。他们的例子是/org/freedesktop/NetworkManager。第二个文档的对象路径为/org/fedoraproject/FirewallD1

我将它们放在一起并尝试使用第一个文档建议的第一种方法,SystemBus's get_object()

>>> from dbus import SystemBus
>>> bus = SystemBus()
>>> proxy = bus.get_object('firewalld.dbus', '/org/fedoraproject/FirewallD1')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.7/site-packages/dbus/bus.py", line 241, in get_object
    follow_name_owner_changes=follow_name_owner_changes)
  File "/usr/lib64/python2.7/site-packages/dbus/proxies.py", line 248, in __init__
    self._named_service = conn.activate_name_owner(bus_name)
  File "/usr/lib64/python2.7/site-packages/dbus/bus.py", line 180, in activate_name_owner
    self.start_service_by_name(bus_name)
  File "/usr/lib64/python2.7/site-packages/dbus/bus.py", line 278, in start_service_by_name
    'su', (bus_name, flags)))
  File "/usr/lib64/python2.7/site-packages/dbus/connection.py", line 651, in call_blocking
    message, timeout)
dbus.exceptions.DBusException:
    org.freedesktop.DBus.Error.ServiceUnknown:
        The name firewalld.dbus was not provided by any .service files

我还尝试了org.fedoraproject.FirewallD1 作为第一个参数,但最终得到了类似的错误消息。

为什么这些不起作用?有什么方法可以让我发现正确的名称是什么?它在错误消息的末尾提到了“.service files”......这样的文件应该放在哪里?


编辑:使用find / -name *.service 找到多个“.service 文件”。其中之一是/usr/lib/systemd/system/firewalld.service... 看起来很有希望,所以我会检查一下。

编辑 2:这是一个相当短的文件……只有大约 10 行。其中一个说BusName=org.fedoraproject.FirewallD1。所以我不确定为什么它说任何 .service 文件都没有提供该名称...除非出于某种原因它没有使用该文件?

【问题讨论】:

【参考方案1】:

如果单元文件显示:

BusName=org.fedoraproject.FirewallD1

那么也许您应该尝试使用它作为您的巴士名称:

>>> import dbus
>>> bus = dbus.SystemBus()
>>> p = bus.get_object('org.fedoraproject.FirewallD1', '/org/fedoraproject/FirewallD1')
>>> p.getDefaultZone()
dbus.String(u'FedoraWorkstation')

我是根据以下事实得出这个结论的:

>>> help(bus.get_object)

get_object 调用看起来像:

get_object(self, bus_name, object_path, introspect=True, follow_name_owner_changes=False, **kwargs)

【讨论】:

嗨 - 正如我在原始帖子中提到的(就在编辑之前)我也尝试过,但它给出了同样的错误。是服务文件没有加载还是什么原因? 所以,这只是在我的系统上工作。 systemd 使用该服务文件来启动 Firewalld。 firewalld 在你的系统上运行吗? systemctl status firewalld 报告什么?你看到firewalld 进程正在运行吗? 它没有运行。我现在用systemctl start firewalld.service 开始了它。现在正在创建代理并正确返回答案。从 Python 中启动服务的最佳方式是什么?我的印象是dbus 模块会在正确的时间启动它……或者至少为我提供一个启动它的功能。我最好的选择是subprocess.call() 还是我在dbus 模块中忽略了什么? 正确的做法是systemctl enable firewalld,以便在系统启动时由systemd启动。 如果你有时间,你能看看这个吗?我想我可能在 Python dbus 模块中发现了一个错误...***.com/questions/34424037/…

以上是关于通过 Python 的 dbus 模块控制 CentOS 中的 firewalld?的主要内容,如果未能解决你的问题,请参考以下文章

通过 python 和 dbus 启动用户 systemd 服务

从python访问iwd dbus接口

如何让 Python 看到通过 apt 安装的模块?

使用 python 的 dbus 模块,是不是可以更新通知的内容而不会再次弹出?

libvlc 和 dbus 接口

Java 最佳方法(线程、DBus 和 HttpRequest)