在python脚本中调用IPtables命令

时间:2013-07-23 19:41:59

标签: python iptables

我试图在我的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

4 个答案:

答案 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)