Python-iptables如何优化代码

9

我正在学习Python,并使用python-iptables库编写了一些设置iptables的代码。我遇到的问题是,我不得不反复重写很多相同的代码行。我有点了解函数,但并不懂面向对象编程。我认为有更好的面向对象编程方式来编写这段代码,但我无法理解它。任何指针将不胜感激。以下是代码。

import iptc

def dropAllInbound():
    chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'INPUT')
    rule = iptc.Rule()
    rule.in_interface = 'eth+'
    rule.target = iptc.Target(rule, 'DROP')
    chain.insert_rule(rule)

def allowLoopback():
    chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'INPUT')
    rule = iptc.Rule()
    rule.in_interface = 'lo'
    rule.target = iptc.Target(rule, 'ACCEPT')
    chain.insert_rule(rule)

def allowEstablishedInbound():
    chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'INPUT')
    rule = iptc.Rule()
    match = rule.create_match('state')
    match.state = 'RELATED,ESTABLISHED'
    rule.target = iptc.Target(rule, 'ACCEPT')
    chain.insert_rule(rule)

def allowHTTP():
    chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'INPUT')
    rule = iptc.Rule()
    rule.in_interface = 'eth+'
    rule.protocol = 'tcp'
    match = rule.create_match('tcp')
    match.dport = '80'
    rule.target = iptc.Target(rule, 'ACCEPT')
    chain.insert_rule(rule)

def allowHTTPS():
    chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'INPUT')
    rule = iptc.Rule()
    rule.in_interface = 'eth+'
    rule.protocol = 'tcp'
    match = rule.create_match('tcp')
    match.dport = '443'
    rule.target = iptc.Target(rule, 'ACCEPT')
    chain.insert_rule(rule)

def allowSSH():
    chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'INPUT')
    rule = iptc.Rule()
    rule.in_interface = 'eth+'
    rule.protocol = 'tcp'
    match = rule.create_match('tcp')
    match.dport = '22'
    rule.target = iptc.Target(rule, 'ACCEPT')
    chain.insert_rule(rule)

def allowEstablishedOutbound():
    chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'OUTPUT')
    rule = iptc.Rule()
    match = rule.create_match('state')
    match.state = 'RELATED,ESTABLISHED'
    rule.target = iptc.Target(rule, 'ACCEPT')
    chain.insert_rule(rule)

def dropAllOutbound():
    chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'OUTPUT')
    rule = iptc.Rule()
    rule.in_interface = 'eth+'
    rule.target = iptc.Target(rule, 'DROP')
    chain.insert_rule(rule)

def defaultAction():
    dropAllOutbound()
    dropAllInbound()
    allowLoopback()
    allowEstablishedInbound()
    allowEstablishedOutbound()

def getInput():
        print 'Default action (1) is most secure '
        print 'Default  -  1'
        print 'HTTP     -  2'
        print 'HTTPS    -  3'
        print 'SSH      -  4'
        print 'Exit     -  5'
        choices = raw_input('Enter choices (comma Separated) ').split(',')
        for action in choices:
            if action == "1":
                defaultAction()
                break
            if action == "2":
                allowHTTP()
                break
            if action == "3":
                allowHTTPS()
                break
            if action == "4":
                allowSSH()
                break
            else:
                break
getInput()

注意所有规则都有相似的代码行。是否有一种方法可以创建一个规则生成器对象或类似的东西来最小化重复编写代码的工作?
我添加了以下函数,并在每次运行脚本时调用它,以便清除规则。
def startClean():
    chainIn = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'INPUT')
    chainIn.flush()
    chainOut = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'OUTPUT')
    chainOut.flush()

1
如果在这里添加任何抽象,你会让你的代码对于未来的自己和其他人更难维护,因为他们必须重新学习你的抽象。当防火墙配置中存在严重和紧急的错误时,这可能是一个巨大的痛苦。在评估你的选项时,请考虑这一点。 - pts
谢谢您的见解。所以您基本上认为我现在的做法很好,很有意义? - h33th3n
1
如果没有其他答案,我会保留现在的状态,并在1年后重新考虑,具备更多的Python经验和更好的维护成本理解。 - pts
2
还有一个注释:请在开始时清除所有链和表,这样如果您多次运行脚本,您总是会得到相同的结果,并且规则不会累积。 - pts
2
更适合于 CodeReview 网站。 - FallenAngel
1个回答

4

OOP(面向对象编程)是用于维护某个内容的状态的编程方法。OOP是指具有属性和可以操作这些属性的方法的对象。

class Chair(object):

    MAX_WEIGHT = 300

    def __init__(self):
        super().__init__()

        self.weight = 5
        self.currentWeight = self.weight
        self.holding = None
        self.broken = False

    def hold(self, item):
        self.holding = item
        self.currentWeight = self.weight + item.weight
        self.checkWeight()

    def checkWeight(self):
        if self.holding.weight > self.MAX_WEIGHT:
            self.broken = True
            ...

你的代码看起来很好,仅为了面向对象编程而重写代码可能会比它值得的更多。如果你真的想使用面向对象编程,可以尝试以下方法:

class Table(object):
    def __init__(self):
        self.chain = None
        self.rule = None
        self.match = None

    def setInput(self):
        self.chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'INPUT')

    def setOutput(self):
        self.chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'OUTPUT')

    ...

table = Table()
table.setInput()
...

谢谢您的评论。看起来运行共识是代码本身很好。不过,为了学习,我可能会尝试以面向对象的方式构建它。 - h33th3n

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接