問題描述
我正在嘗試通過 Python dbus
模塊控制 firewalld
.
I'm attempting to control firewalld
via the Python dbus
module.
我想為我當前的運行時和我的永久配置添加一個 IP 地址到受信任區域.
I'd like to add an ip address to the trusted zone for both my current runtime as well as my permanent configuration.
這是 firewalld
的 dbus 接口的文檔:http://manpages.ubuntu.com/manpages/wily/man5/firewalld.dbus.5.html
Here's the documentation for firewalld
's dbus interface:
http://manpages.ubuntu.com/manpages/wily/man5/firewalld.dbus.5.html
工作原理:運行時配置
我可以將它添加到運行時配置中,這樣就可以了:
I'm able to add it to the runtime configuration just fine with this:
def trustIP(ip):
''' firewalld must already be running '''
from dbus import SystemBus
bus = SystemBus()
runtimeProxy = bus.get_object('org.fedoraproject.FirewallD1',
'/org/fedoraproject/FirewallD1')
runtimeProxy.addSource('trusted', ip)
很簡單.
什么不起作用:永久配置
事實證明,將其添加到永久配置中更加困難.以下是我迄今為止以交互方式嘗試過的方法:
Adding it to the permanent configuration has proved to be more difficult. Here's what I've tried so far interactively:
>>> from dbus import SystemBus
>>> bus = SystemBus()
# First I need to find out which object is for the trusted zone...
>>> config = bus.get_object('org.fedoraproject.FirewallD1',
'/org/fedoraproject/FirewallD1/config')
>>> config.getZoneByName('trusted')
dbus.ObjectPath('/org/fedoraproject/FirewallD1/config/zone/7')
>>> permanentProxy = bus.get_object('org.fedoraproject.FirewallD1',
'/org/fedoraproject/FirewallD1/config/zone/7')
# A quick check to make sure I have the right object:
>>> permanentProxy.getShort()
dbus.String(u'Trusted')
# Exactly what I expected, so move on and...
>>> permanentProxy.addSource('aaa.xxx.yyy.zzz') # Actual ip removed...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.7/site-packages/dbus/proxies.py", line 145, in __call__
**keywords)
File "/usr/lib64/python2.7/site-packages/dbus/connection.py", line 651, in call_blocking
message, timeout)
dbus.exceptions.DBusException:
org.freedesktop.DBus.Python.dbus.exceptions.DBusException:
dbus_to_python() takes exactly 1 argument (2 given)
我還嘗試檢查 permanentProxy.getDescription()
,它返回了應有的描述,我嘗試了 permanentProxy.setDescription('test')
,但失敗了與 permanentProxy.addSource('aaa.xxx.yyy.zzz')
完全相同的堆棧跟蹤.
I also tried checking permanentProxy.getDescription()
, which returned the description as it should have, and I tried permanentProxy.setDescription('test')
which failed with the exact same stack trace as permanentProxy.addSource('aaa.xxx.yyy.zzz')
.
我會得出結論,錯誤在于 python dbus
模塊并假設它以某種方式無法正確處理參數,除了 runtimeProxy.addSource('trusted', ip)
涉及兩個參數并且可以完美運行.config.getZoneByName('trusted')
甚至和permanentProxy.addSource('aaa.xxx.yyy.zzz')`有相同的簽名,正好一個字符串,完美運行.
I would jump to the conclusion that the bug lies in the python dbus
module and assume it somehow doesn't handle arguments properly, except for the fact that runtimeProxy.addSource('trusted', ip)
involved two arguments and works perfectly. config.getZoneByName('trusted')
even has the same signature as permanentProxy.addSource('aaa.xxx.yyy.zzz')`, exactly one string, and works perfectly.
所以也許我錯過了一些奇怪的東西?但我不知道那會是什么......
So maybe there's something weird I'm missing? But I don't know what that would be...
我嘗試了更多但沒有成功的東西
我考慮了可能 addSource
應該在沒有字符串參數的情況下調用的可能性,并且可能以某種方式或某種咖喱,所以我嘗試了這個:
I considered the possibility that maybe addSource
is supposed to be called without the string argument at all and maybe curries somehow or something, so I tried this:
>>> permanentProxy.addSource()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.7/site-packages/dbus/proxies.py", line 145, in __call__
**keywords)
File "/usr/lib64/python2.7/site-packages/dbus/connection.py", line 651, in call_blocking
message, timeout)
dbus.exceptions.DBusException: org.freedesktop.DBus.Python.TypeError: Traceback (most recent call last):
File "/usr/lib/python2.7/site-packages/slip/dbus/service.py", line 123, in reply_handler
result = method(self, *p, **k)
TypeError: addSource() takes at least 2 arguments (2 given)
這現在更奇怪了...我在另一個回溯中有一個回溯堅持我需要傳遞至少 2 個參數,但還說我給了它兩個參數(實際上我只給了它一個,那么如何無論如何它會想出兩個嗎?)
This is just even weirder now... I have one Traceback within another traceback insisting that I need to pass in at least 2 arguments, but also saying I gave it two arguments (and I actually only gave it one, so how'd it come up with two anyways?)
我又嘗試了幾件事但沒有成功:
A few more things I tried without success:
>>> permanentProxy.addSource(dbus_interface='org.fedoraproject.FirewallD1.config.zone')
ERROR:dbus.connection:Unable to set arguments () according to signature u's': <type 'exceptions.TypeError'>: More items found in D-Bus signature than in Python arguments
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.7/site-packages/dbus/proxies.py", line 145, in __call__
**keywords)
File "/usr/lib64/python2.7/site-packages/dbus/connection.py", line 641, in call_blocking
message.append(signature=signature, *args)
TypeError: More items found in D-Bus signature than in Python arguments
>>> permanentProxy.addSource('aaa.xxx.yyy.zzz', dbus_interface='org.fedoraproject.FirewallD1.config.zone')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.7/site-packages/dbus/proxies.py", line 145, in __call__
**keywords)
File "/usr/lib64/python2.7/site-packages/dbus/connection.py", line 651, in call_blocking
message, timeout)
dbus.exceptions.DBusException:
org.freedesktop.DBus.Python.dbus.exceptions.DBusException:
dbus_to_python() takes exactly 1 argument (2 given)
>>> from dbus import Interface
>>> Interface(permanentProxy, 'org.fedoraproject.FirewallD1.config.zone').addSource('aaa.xxx.yyy.zzz')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.7/site-packages/dbus/proxies.py", line 145, in __call__
**keywords)
File "/usr/lib64/python2.7/site-packages/dbus/connection.py", line 651, in call_blocking
message, timeout)
dbus.exceptions.DBusException:
org.freedesktop.DBus.Python.dbus.exceptions.DBusException:
dbus_to_python() takes exactly 1 argument (2 given)
啊!
這確實看起來像 dbus
中的一個錯誤...不知何故,它最初錯誤地解析了 addSource
并認為它需要更少的參數,但如果你給它更少的參數,比如它想要,它會通過那個錯誤的檢查,然后它會正確解決并失敗,因為你的參數不匹配.
This really seems like a bug in dbus
... somehow it's initially resolving addSource
incorrectly and thinking that it needs fewer arguments, but if you give it fewer arguments like it wants, it'll pass that erroneous check, and then it'll properly resolve and fail because your arguments don't match it.
這就是我的理論.有人看到我沒有的東西嗎?如果真的有的話,有什么方法可以解決這個錯誤嗎?IE... 是否有某種我可以在 dbus 上使用的內部方法來強制它調用正確的方法?
That's my theory anyways. Is someone seeing something I'm not? Is there some way I can work around this bug, if there really is one? IE... is there some kind of internal method I can use on dbus that will force it to call the proper method?
推薦答案
以下對我有用:
>>> import dbus
>>> bus = dbus.SystemBus()
>>> config = bus.get_object('org.fedoraproject.FirewallD1',
... '/org/fedoraproject/FirewallD1/config')
>>> path = config.getZoneByName('trusted')
>>> zone = bus.get_object('org.fedoraproject.FirewallD1', path)
>>> zone.addSource('192.168.1.0/24')
此時,如果我查看/etc/firewalld/zones/trusted.xml
,可以看到源地址已按預期添加:
At this point, if I look in /etc/firewalld/zones/trusted.xml
, I can see that the source address has been added as expected:
<?xml version="1.0" encoding="utf-8"?>
<zone target="ACCEPT">
<short>Trusted</short>
<description>All network connections are accepted.</description>
<interface name="docker0"/>
<interface name="virbr0"/>
<source address="192.168.1.0/24"/>
</zone>
...表示我已成功更改持久化配置.
...indicating that I have successfully changed the persistent configuration.
如果我在第二個 get_object
調用中使用文字路徑而不是 config.getZoneByName
的返回值,上述方法也有效.
The above also works if I use a literal path in the second get_object
call, instead of the return value from config.getZoneByName
.
為了它的價值,我正在跑步:
For what it's worth, I'm running:
- Fedora 23
- firewalld-0.3.14.2-4.fc23.noarch
- dbus-1.10.6-1.fc23.x86_64
- dbus-python-1.2.0-12.fc23.x86_64
更新
您沒有看到任何更新,因為您使用的是 CentOS,而不是 Fedora.看起來解決這個特定任務的最簡單方法可能是使用 FirewallD 附帶的 firewall
python 模塊.以下適用于 CentOS 7:
You're not seeing anything newer because you're on CentOS, rather than Fedora. It looks like the easiest way of solving this particular task may be to use the firewall
python module that ships with FirewallD. The following works for me on CentOS 7:
>>> from firewall.client import *
>>> client = FirewallClient()
>>> zone = client.config().getZoneByName('public')
>>> settings = zone.getSettings()
>>> settings.addSource('192.168.1.0/24')
>>> zone.update(settings)
另一個更新
瀏覽 firewall.client
模塊的源代碼,您可以通過直接 dbus 執行此操作,如下所示:
Browsing through the source to the firewall.client
module, you can do this via straight dbus like this:
>>> zone = bus.get_object('org.fedoraproject.FirewallD1', path)
>>> settings = zone.getSettings()
>>> settings[11].append('192.168.20.0/24')
>>> zone.update(settings)
這個也在 CentOS 下工作得很好...但是你最好使用 firewall
模塊.
This also works fine under CentOS...but you're much better off using the firewall
module.
這篇關于dbus_to_python() 只需要 1 個參數?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!