Управлять firewalld в CentOS через модуль dbus Python?

Моя цель — автоматизировать настройку брандмауэров на компьютерах с CentOS 7 с помощью Python.

ОС поставляется с firewalld, так что я использую его. Я изучил его и обнаружил, что он использует dbus (я никогда не слышал об этом и не сталкивался с этим - пожалуйста, поправьте меня, если я скажу что-то неверно).

Я нашел эту документацию о том, как управлять процессами dbus с помощью Python: 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 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»… где может находиться такой файл?


Изменить: найдено несколько "файлов .service" с помощью find / -name *.service. Один из них находится по адресу /usr/lib/systemd/system/firewalld.service... кажется многообещающим, так что я проверю его.

Редактировать 2: Это довольно короткий файл... всего около 10 строк. Один из них говорит BusName=org.fedoraproject.FirewallD1. Поэтому я не уверен, почему он сказал, что имя не было предоставлено никакими файлами .service ... если только он по какой-то причине не использует этот файл?


person ArtOfWarfare    schedule 21.12.2015    source источник


Ответы (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)
person larsks    schedule 21.12.2015
comment
Привет - как я уже упоминал в своем исходном посте (незадолго до редактирования), я тоже пробовал это, но это дало ту же ошибку. Сервисный файл не загружается или что-то по какой-то причине? - person ArtOfWarfare; 21.12.2015
comment
Итак, это только что сработало в моей системе. Служебный файл используется systemd для запуска Firewalld. Работает ли firewalld в вашей системе? Что сообщает systemctl status firewalld? Вы видите запущенный процесс firewalld? - person larsks; 21.12.2015
comment
Он не работал. Я начал это сейчас с systemctl start firewalld.service. Теперь прокси создается и корректно возвращает ответы. Как лучше всего запустить службу из Python? У меня сложилось впечатление, что модуль dbus запустит его в нужное время... или, по крайней мере, предоставит мне функцию для его запуска. Мой лучший выбор будет subprocess.call() или есть что-то, что я упускаю из виду в модуле dbus? - person ArtOfWarfare; 21.12.2015
comment
Правильным будет systemctl enable firewalld, чтобы он запускался systemd при загрузке вашей системы. - person larsks; 21.12.2015
comment
Если у вас есть минутка, не могли бы вы взглянуть на это? Я думаю, что, возможно, нашел ошибку в модуле Python dbus... stackoverflow.com/questions/34424037/ - person ArtOfWarfare; 22.12.2015