我试图在我的python脚本中调用以下命令。我试图将规则插入IP表。我正在使用子进程来调用它并在需要的地方插入变量,但是我遇到了很大的错误。有什么建议吗?
iptables = subprocess.call('iptables -I FORWARD -eth 0 -m '+protocol+' -t'+protocol+'--dport '+port+'-j DNAT --to-destination'+ipAddress)
错误:
Traceback (most recent call last):
File "./port_forward.py", line 42, in <module>
iptables = subprocess.call('iptables -I FORWARD -i eth0 -m '+protocol+' -t'+protocol+'--dport '+port+'-j DNAT --to-destination'+ipAddress)
File "/usr/lib/python2.7/subprocess.py", line 493, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1259, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
答案 0 :(得分:3)
您的问题对于Python初学者来说非常普遍。而不是格式化字符串命令, 您正试图通过连接许多字符串和变量来构建复杂的字符串。相反,使用 它是一种字符串格式,它允许您测试命令并使您的代码更具可读性和灵活性。
您的原始字符串在选项和参数之间缺少空格,例如--to-destination1.2.3.4
。
因此,you should format your string(这也适用于python 2.7):
opts = {'iptables': '/sbin/iptables', 'protocol': 'tcp', 'port': 80, 'ipAddress': '0.0.0.0'}
ipcmd = '{iptables} -I FORWARD -eth 0 -m {protocol} -t {protocol} \
--dport {port} -j DNAT --to-destination {ipAddress}'.format(**opts)
if DEBUG:
print ipcmd
iptables = subprocess.call(ipcmd)
以后更容易修改,而且,当你进行更多的Python编程时,你会发现它更具可读性。
另外,要调用IPTables,您应该是root用户,如评论中所述: 在脚本的开头添加:
import sys
import os
if not os.getuid() == 0:
print "You must be root to change IPTables."
sys.exit(2)
看到错误跟踪后您正在尝试调用命令iptables
,但它不在您的路径中。
您应该调用iptables的完整路径,例如: /sbin/iptables
答案 1 :(得分:1)
我用同样的方式编写了一个简单的防火墙,并意识到“为什么不用bash写它?”。无论如何,我发现了python-iptables库并使用它重写了我的代码。我建议检查一下。我认为它将为您提供更强大,更有条理的编写iptables规则的方法。
答案 2 :(得分:0)
由于缺少空格,您的命令充满了语法错误,如下所示:
iptables = subprocess.call(
'iptables -I FORWARD -eth 0 -m '
+ protocol
+ ' -t'+protocol
^---here
+ '--dport '
^-- here
+ port
+ '-j DNAT --to-destination'
^--here
+ ipAddress)
^---here
生成后,您的iptables行看起来像
-ttcp--dport 80-j DNAT --to-destination1.2.3.4
-ttcp--dport
被解析为SINGLE参数,同上为80-j
和--to-destination1.2.3.4
答案 3 :(得分:0)
只需将参数shell = True与命令一起传递。
iptables = subprocess.call('iptables -I FORWARD -eth 0 -m '+protocol+' -t'+protocol+'--dport '+port+'-j DNAT --to-destination'+ipAddress, shell=True)