Пример #1
0
def initChain():
  # Is called before threads start, no locking
  print("Initializing mailcow netfilter chain")
  # IPv4
  if not iptc.Chain(iptc.Table(iptc.Table.FILTER), "MAILCOW") in iptc.Table(iptc.Table.FILTER).chains:
    iptc.Table(iptc.Table.FILTER).create_chain("MAILCOW")
  for c in ['FORWARD', 'INPUT']:
    chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), c)
    rule = iptc.Rule()
    rule.src = '0.0.0.0/0'
    rule.dst = '0.0.0.0/0'
    target = iptc.Target(rule, "MAILCOW")
    rule.target = target
    if rule not in chain.rules:
      chain.insert_rule(rule)
  # IPv6
  if not iptc.Chain(iptc.Table6(iptc.Table6.FILTER), "MAILCOW") in iptc.Table6(iptc.Table6.FILTER).chains:
    iptc.Table6(iptc.Table6.FILTER).create_chain("MAILCOW")
  for c in ['FORWARD', 'INPUT']:
    chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), c)
    rule = iptc.Rule6()
    rule.src = '::/0'
    rule.dst = '::/0'
    target = iptc.Target(rule, "MAILCOW")
    rule.target = target
    if rule not in chain.rules:
      chain.insert_rule(rule)
    def set_chain_policy(self, policy_state):
        """
        set input/output chain policy
        """

        accept_policy = iptc.Policy('ACCEPT')
        drop_policy = iptc.Policy('DROP')

        #v4 policy
        input_chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'INPUT')
        output_chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'OUTPUT')

        if policy_state.lower() == JSON_RULE_NETWORK_ACCEPT \
            or policy_state.lower() == JSON_RULE_ALLOW:
            input_chain.set_policy(accept_policy)
            output_chain.set_policy(accept_policy)
        else:
            input_chain.set_policy(drop_policy)
            output_chain.set_policy(drop_policy)

        #v6 policy
        input_chain6 = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), 'INPUT')
        output_chain6 = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), 'OUTPUT')

        if policy_state.lower() == JSON_RULE_NETWORK_ACCEPT \
            or policy_state.lower() == JSON_RULE_ALLOW:
            input_chain6.set_policy(accept_policy)
            output_chain6.set_policy(accept_policy)
        else:
            input_chain6.set_policy(drop_policy)
            output_chain6.set_policy(drop_policy)
    def insert_rule(self, rule, direction, ip, protocol):
        """
        insert rule
        """

        #domain to ip
        resolved_list = []
        it = self.ip_type(ip)
        if it == 'domain':
            resolved_list = self.dns_resolver(ip)
        else:
            resolved_list.append(ip)
        self.logger.debug('resolved_list={}'.format(resolved_list))

        #chains
        input_chain = output_chain = None
        if it == 'v6':
            input_chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), 'INPUT')
            output_chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), 'OUTPUT')
        else:
            input_chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'INPUT')
            output_chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'OUTPUT')

        for resolved in resolved_list:
            if direction == JSON_RULE_NETWORK_INBOUND:
                rule.src = resolved
                self._insert_rule_with_log(input_chain, rule)
            elif direction == JSON_RULE_NETWORK_OUTBOUND:
                rule.dst = resolved 
                self._insert_rule_with_log(output_chain, rule)
            else:
                rule.src = resolved
                self._insert_rule_with_log(input_chain, rule)
                rule.dst = resolved
                self._insert_rule_with_log(output_chain, rule)
Пример #4
0
def unblock(ip=None):
    if ip == None:
        iptc.Chain(iptc.Table(iptc.Table.FILTER), INPUT).flush()
        iptc.Chain(iptc.Table(iptc.Table.FILTER), OUTPUT).flush()
        iptc.Chain(iptc.Table(iptc.Table.FILTER), FORWARD).flush()
        iptc.Chain(iptc.Table6(iptc.Table6.FILTER), INPUT).flush()
        iptc.Chain(iptc.Table6(iptc.Table6.FILTER), OUTPUT).flush()
        iptc.Chain(iptc.Table6(iptc.Table6.FILTER), FORWARD).flush()
    else:
        try:
            src = ipaddress.ip_address(ip)
            if src.version == IPv4:
                table = iptc.Table(iptc.Table.FILTER)
            elif src.version == IPv6:
                table = iptc.Table6(iptc.Table6.FILTER)

            for chain in table.chains:
                for rule in chain.rules:
                    if ipaddress.ip_address(
                            rule.src.split('/')[0]) == src.explode:
                        __logger.debug("Un-Block IP %s", rule.src)
                        chain.delete_rule(rule)
        except ValueError:
            __logger.error('Invalid source ip address to block')
            __logger.warning("Block IP %s", newRule.src)
Пример #5
0
def initChain():
  # Is called before threads start, no locking
  print "Initializing mailcow netfilter chain"
  # IPv4
  if not iptc.Chain(iptc.Table(iptc.Table.FILTER), "MAILCOW") in iptc.Table(iptc.Table.FILTER).chains:
    iptc.Table(iptc.Table.FILTER).create_chain("MAILCOW")
  for c in ['FORWARD', 'INPUT']:
    chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), c)
    rule = iptc.Rule()
    rule.src = '0.0.0.0/0'
    rule.dst = '0.0.0.0/0'
    target = iptc.Target(rule, "MAILCOW")
    rule.target = target
    if rule not in chain.rules:
      chain.insert_rule(rule)
  # IPv6
  if not iptc.Chain(iptc.Table6(iptc.Table6.FILTER), "MAILCOW") in iptc.Table6(iptc.Table6.FILTER).chains:
    iptc.Table6(iptc.Table6.FILTER).create_chain("MAILCOW")
  for c in ['FORWARD', 'INPUT']:
    chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), c)
    rule = iptc.Rule6()
    rule.src = '::/0'
    rule.dst = '::/0'
    target = iptc.Target(rule, "MAILCOW")
    rule.target = target
    if rule not in chain.rules:
      chain.insert_rule(rule)
  # Apply blacklist
  BLACKLIST = r.hgetall('F2B_BLACKLIST')
  if BLACKLIST:
    for bl_key in BLACKLIST:
      if type(ipaddress.ip_network(bl_key.decode('ascii'), strict=False)) is ipaddress.IPv4Network:
        chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'MAILCOW')
        rule = iptc.Rule()
        rule.src = bl_key
        target = iptc.Target(rule, "REJECT")
        rule.target = target
        if rule not in chain.rules:
          log['time'] = int(round(time.time()))
          log['priority'] = 'crit'
          log['message'] = 'Blacklisting host/network %s' % bl_key
          r.lpush('NETFILTER_LOG', json.dumps(log, ensure_ascii=False))
          print log['message']
          chain.insert_rule(rule)
          r.hset('F2B_PERM_BANS', '%s' % bl_key, int(round(time.time())))
      else:
        chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), 'MAILCOW')
        rule = iptc.Rule6()
        rule.src = bl_key
        target = iptc.Target(rule, "REJECT")
        rule.target = target
        if rule not in chain.rules:
          log['time'] = int(round(time.time()))
          log['priority'] = 'crit'
          log['message'] = 'Blacklisting host/network %s' % bl_key
          r.lpush('NETFILTER_LOG', json.dumps(log, ensure_ascii=False))
          print log['message']
          chain.insert_rule(rule)
          r.hset('F2B_PERM_BANS', '%s' % bl_key, int(round(time.time())))
Пример #6
0
    def clear_rules(self):
        if self.cleared:
            return

        self._lock.acquire()
        try:
            if settings.vpn.lib_iptables and LIB_IPTABLES:
                tables = {
                    'nat': iptc.Table(iptc.Table.NAT),
                    'nat6': iptc.Table6(iptc.Table.NAT),
                    'filter': iptc.Table(iptc.Table.FILTER),
                    'filter6': iptc.Table6(iptc.Table.FILTER),
                }
            else:
                tables = None

            # TODO
            # tables['nat'].autocommit = False
            # tables['nat6'].autocommit = False
            # tables['filter'].autocommit = False
            # tables['filter6'].autocommit = False

            self.cleared = True

            for rule in self._accept + self._other:
                self._remove_iptables_rule(rule, tables=tables)

            if self.ipv6:
                for rule in self._accept6 + self._other6:
                    self._remove_iptables_rule(rule, ipv6=True,
                        tables=tables)

            if self.restrict_routes:
                for rule in self._drop:
                    self._remove_iptables_rule(rule, tables=tables)

                if self.ipv6:
                    for rule in self._drop6:
                        self._remove_iptables_rule(rule, ipv6=True,
                            tables=tables)

            self._accept = None
            self._accept6 = None
            self._other = None
            self._other6 = None
            self._drop = None
            self._drop6 = None

            # tables['nat'].commit()
            # tables['nat6'].commit()
            # tables['filter'].commit()
            # tables['filter6'].commit()
        finally:
            self._lock.release()
Пример #7
0
def initChain():
    print "Initializing mailcow netfilter chain"
    # IPv4
    if not iptc.Chain(iptc.Table(iptc.Table.FILTER), "MAILCOW") in iptc.Table(
            iptc.Table.FILTER).chains:
        iptc.Table(iptc.Table.FILTER).create_chain("MAILCOW")
    for c in ['FORWARD', 'INPUT']:
        chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), c)
        rule = iptc.Rule()
        rule.src = '0.0.0.0/0'
        rule.dst = '0.0.0.0/0'
        target = iptc.Target(rule, "MAILCOW")
        rule.target = target
        if rule not in chain.rules:
            chain.insert_rule(rule)
    # IPv6
    if not iptc.Chain(iptc.Table6(iptc.Table6.FILTER),
                      "MAILCOW") in iptc.Table6(iptc.Table6.FILTER).chains:
        iptc.Table6(iptc.Table6.FILTER).create_chain("MAILCOW")
    for c in ['FORWARD', 'INPUT']:
        chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), c)
        rule = iptc.Rule6()
        rule.src = '::/0'
        rule.dst = '::/0'
        target = iptc.Target(rule, "MAILCOW")
        rule.target = target
        if rule not in chain.rules:
            chain.insert_rule(rule)
    # Apply blacklist
    BLACKLIST = r.hgetall('F2B_BLACKLIST')
    if BLACKLIST:
        for bl_key in BLACKLIST:
            if type(ipaddress.ip_network(
                    bl_key.decode('ascii'),
                    strict=False)) is ipaddress.IPv4Network:
                chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'MAILCOW')
                rule = iptc.Rule()
                rule.src = bl_key
                target = iptc.Target(rule, "REJECT")
                rule.target = target
                if rule not in chain.rules:
                    chain.insert_rule(rule)
            else:
                chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), 'MAILCOW')
                rule = iptc.Rule6()
                rule.src = bl_key
                target = iptc.Target(rule, "REJECT")
                rule.target = target
                if rule not in chain.rules:
                    chain.insert_rule(rule)
Пример #8
0
def unban(net):
    log['time'] = int(round(time.time()))
    log['priority'] = 'info'
    r.lpush('NETFILTER_LOG', json.dumps(log, ensure_ascii=False))
    if not net in bans:
        log['message'] = '%s is not banned, skipping unban and deleting from queue (if any)' % net
        r.lpush('NETFILTER_LOG', json.dumps(log, ensure_ascii=False))
        print '%s is not banned, skipping unban and deleting from queue (if any)' % net
        r.hdel('F2B_QUEUE_UNBAN', '%s' % net)
        return
    log['message'] = 'Unbanning %s' % net
    r.lpush('NETFILTER_LOG', json.dumps(log, ensure_ascii=False))
    print 'Unbanning %s' % net
    if type(ipaddress.ip_network(
            net.decode('ascii'))) is ipaddress.IPv4Network:
        chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'MAILCOW')
        rule = iptc.Rule()
        rule.src = net
        target = iptc.Target(rule, "REJECT")
        rule.target = target
        if rule in chain.rules:
            chain.delete_rule(rule)
    else:
        chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), 'MAILCOW')
        rule = iptc.Rule6()
        rule.src = net
        target = iptc.Target(rule, "REJECT")
        rule.target = target
        if rule in chain.rules:
            chain.delete_rule(rule)
    r.hdel('F2B_ACTIVE_BANS', '%s' % net)
    r.hdel('F2B_QUEUE_UNBAN', '%s' % net)
    if net in bans:
        del bans[net]
Пример #9
0
def permBan(net, unban=False):
  global lock
  if type(ipaddress.ip_network(net, strict=False)) is ipaddress.IPv4Network:
    with lock:
      chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'MAILCOW')
      rule = iptc.Rule()
      rule.src = net
      target = iptc.Target(rule, "REJECT")
      rule.target = target
      if rule not in chain.rules and not unban:
        logCrit('Add host/network %s to blacklist' % net)
        chain.insert_rule(rule)
        r.hset('F2B_PERM_BANS', '%s' % net, int(round(time.time()))) 
      elif rule in chain.rules and unban:
        logCrit('Remove host/network %s from blacklist' % net)
        chain.delete_rule(rule)
        r.hdel('F2B_PERM_BANS', '%s' % net)
  else:
    with lock:
      chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), 'MAILCOW')
      rule = iptc.Rule6()
      rule.src = net
      target = iptc.Target(rule, "REJECT")
      rule.target = target
      if rule not in chain.rules and not unban:
        logCrit('Add host/network %s to blacklist' % net)
        chain.insert_rule(rule)
        r.hset('F2B_PERM_BANS', '%s' % net, int(round(time.time()))) 
      elif rule in chain.rules and unban:
        logCrit('Remove host/network %s from blacklist' % net)
        chain.delete_rule(rule)
        r.hdel('F2B_PERM_BANS', '%s' % net)
    def flush_chain(self):
        """
        flush input/output chain
        """

        #v4 flush
        input_chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'INPUT')
        output_chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'OUTPUT')
        input_chain.flush()
        output_chain.flush()

        #v6 flush
        input_chain6 = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), 'INPUT')
        output_chain6 = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), 'OUTPUT')
        input_chain6.flush()
        output_chain6.flush()
Пример #11
0
def _iptc_gettable(table, ipv6=False):
    """ Return an updated view of an iptc_table """
    iptc_table = iptc.Table6(table) if ipv6 else iptc.Table(table)
    if MODE_BATCH is False:
        iptc_table.commit()
        iptc_table.refresh()
    return iptc_table
Пример #12
0
def clear():
    global lock
    log['time'] = int(round(time.time()))
    log['priority'] = 'info'
    log['message'] = 'Clearing all bans'
    r.lpush('NETFILTER_LOG', json.dumps(log, ensure_ascii=False))
    print 'Clearing all bans'
    for net in bans.copy():
        unban(net)
    with lock:
        filter4_table = iptc.Table(iptc.Table.FILTER)
        filter6_table = iptc.Table6(iptc.Table6.FILTER)
        for filter_table in [filter4_table, filter6_table]:
            filter_table.autocommit = False
            forward_chain = iptc.Chain(filter_table, "FORWARD")
            input_chain = iptc.Chain(filter_table, "INPUT")
            mailcow_chain = iptc.Chain(filter_table, "MAILCOW")
            if mailcow_chain in filter_table.chains:
                for rule in mailcow_chain.rules:
                    mailcow_chain.delete_rule(rule)
                for rule in forward_chain.rules:
                    if rule.target.name == 'MAILCOW':
                        forward_chain.delete_rule(rule)
                for rule in input_chain.rules:
                    if rule.target.name == 'MAILCOW':
                        input_chain.delete_rule(rule)
                filter_table.delete_chain("MAILCOW")
            filter_table.commit()
            filter_table.refresh()
            filter_table.autocommit = True
        r.delete('F2B_ACTIVE_BANS')
        r.delete('F2B_PERM_BANS')
        pubsub.unsubscribe()
Пример #13
0
def snat6(snat_target):
  global lock
  global quit_now

  def get_snat6_rule():
    rule = iptc.Rule6()
    rule.src = os.getenv('IPV6_NETWORK', 'fd4d:6169:6c63:6f77::/64')
    rule.dst = '!' + rule.src
    target = rule.create_target("SNAT")
    target.to_source = snat_target
    return rule

  while not quit_now:
    time.sleep(10)
    with lock:
      try:
        table = iptc.Table6('nat')
        table.refresh()
        chain = iptc.Chain(table, 'POSTROUTING')
        table.autocommit = False
        if get_snat6_rule() not in chain.rules:
          logInfo('Added POSTROUTING rule for source network %s to SNAT target %s' % (get_snat6_rule().src, snat_target))
          chain.insert_rule(get_snat6_rule())
          table.commit()
        else:
          for position, item in enumerate(chain.rules):
            if item == get_snat6_rule():
              if position != 0:
                chain.delete_rule(get_snat6_rule())
          table.commit()
        table.autocommit = True
      except:
        print('Error running SNAT6, retrying...') 
Пример #14
0
def mailcowChainOrder():
  global lock
  global quit_now
  global exit_code
  while not quit_now:
    time.sleep(10)
    with lock:
      filter4_table = iptc.Table(iptc.Table.FILTER)
      filter6_table = iptc.Table6(iptc.Table6.FILTER)
      filter4_table.refresh()
      filter6_table.refresh()
      for f in [filter4_table, filter6_table]:
        forward_chain = iptc.Chain(f, 'FORWARD')
        input_chain = iptc.Chain(f, 'INPUT')
        for chain in [forward_chain, input_chain]:
          target_found = False
          for position, item in enumerate(chain.rules):
            if item.target.name == 'MAILCOW':
              target_found = True
              if position > 2:
                logCrit('Error in %s chain order: MAILCOW on position %d, restarting container' % (chain.name, position))
                quit_now = True
                exit_code = 2
          if not target_found:
            logCrit('Error in %s chain: MAILCOW target not found, restarting container' % (chain.name))
            quit_now = True
            exit_code = 2
Пример #15
0
def update_iptables(table, chain, rules):
    """
    Delete all rules marked by WOTT_COMMENT.
    Then insert new rules from the supplied list.

    :param table: table name
    :param chain: chain name
    :param rules: a list of rules in iptc.easy format
    :return: None
    """
    tbl4 = iptc.Table(table)
    tbl6 = iptc.Table6(table)

    for t in (tbl4, tbl6):
        t.autocommit = False
        ch = iptc.Chain(t, chain)
        for r in ch.rules:
            for m in r.matches:
                if m.comment == WOTT_COMMENT:
                    ch.delete_rule(r)
                    break

    for r, ipv6 in rules:
        iptc_helper.add_rule(table, chain, r, ipv6=ipv6)

    for t in (tbl4, tbl6):
        t.commit()
        t.refresh()
        t.autocommit = True
Пример #16
0
def unban(net):
  global lock
  if not net in bans:
   logInfo('%s is not banned, skipping unban and deleting from queue (if any)' % net)
   r.hdel('F2B_QUEUE_UNBAN', '%s' % net)
   return
  logInfo('Unbanning %s' % net)
  if type(ipaddress.ip_network(net)) is ipaddress.IPv4Network:
    with lock:
      chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'MAILCOW')
      rule = iptc.Rule()
      rule.src = net
      target = iptc.Target(rule, "REJECT")
      rule.target = target
      if rule in chain.rules:
        chain.delete_rule(rule)
  else:
    with lock:
      chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), 'MAILCOW')
      rule = iptc.Rule6()
      rule.src = net
      target = iptc.Target(rule, "REJECT")
      rule.target = target
      if rule in chain.rules:
        chain.delete_rule(rule)
  r.hdel('F2B_ACTIVE_BANS', '%s' % net)
  r.hdel('F2B_QUEUE_UNBAN', '%s' % net)
  if net in bans:
    del bans[net]
Пример #17
0
def openemailChainOrder():
    global lock
    global quit_now
    while not quit_now:
        time.sleep(10)
        with lock:
            filter4_table = iptc.Table(iptc.Table.FILTER)
            filter6_table = iptc.Table6(iptc.Table6.FILTER)
            filter4_table.refresh()
            filter6_table.refresh()
            for f in [filter4_table, filter6_table]:
                forward_chain = iptc.Chain(f, 'FORWARD')
                input_chain = iptc.Chain(f, 'INPUT')
                for chain in [forward_chain, input_chain]:
                    target_found = False
                    for position, item in enumerate(chain.rules):
                        if item.target.name == 'OPENEMAIL':
                            target_found = True
                            if position != 0:
                                logCrit(
                                    'Error in %s chain order, restarting container'
                                    % (chain.name))
                                quit_now = True
                    if not target_found:
                        logCrit(
                            'Error in %s chain: OPENEMAIL target not found, restarting container'
                            % (chain.name))
                        quit_now = True
Пример #18
0
 def test_rule_iterate_raw(self):
     if is_table6_available(iptc.Table6.RAW):
         for r in (
                 rule
                 for chain in iptc.Table6(iptc.Table6.RAW).chains.values()
                 for rule in chain.rules if rule):
             pass
Пример #19
0
def clear():
  global lock
  logInfo('Clearing all bans')
  for net in bans.copy():
    unban(net)
  with lock:
    filter4_table = iptc.Table(iptc.Table.FILTER)
    filter6_table = iptc.Table6(iptc.Table6.FILTER)
    for filter_table in [filter4_table, filter6_table]:
      filter_table.autocommit = False
      forward_chain = iptc.Chain(filter_table, "FORWARD")
      input_chain = iptc.Chain(filter_table, "INPUT")
      mailcow_chain = iptc.Chain(filter_table, "MAILCOW")
      if mailcow_chain in filter_table.chains:
        for rule in mailcow_chain.rules:
          mailcow_chain.delete_rule(rule)
        for rule in forward_chain.rules:
          if rule.target.name == 'MAILCOW':
            forward_chain.delete_rule(rule)
        for rule in input_chain.rules:
          if rule.target.name == 'MAILCOW':
            input_chain.delete_rule(rule)
        filter_table.delete_chain("MAILCOW")
      filter_table.commit()
      filter_table.refresh()
      filter_table.autocommit = True
    r.delete('F2B_ACTIVE_BANS')
    r.delete('F2B_PERM_BANS')
    pubsub.unsubscribe()
Пример #20
0
    def __init__(self, conf: dict) -> None:
        log.debug('IPTables plugin initialising with config: %s', conf)

        self._table4 = iptc.Table(
            self._tables[conf['table'] if 'table' in conf else 'filter'])
        self._table6 = iptc.Table6(
            self._tables[conf['table'] if 'table' in conf else 'filter'])
        log.debug('iptables._table4 == %s', self._table4)
        log.debug('iptables._table6 == %s', self._table6)

        chain = conf['chain'] if 'chain' in conf else 'INPUT'

        self._chain4 = iptc.Chain(self._table4, chain)
        self._chain6 = iptc.Chain(self._table6, chain)
        log.debug('iptables._chain4 == %s', chain)
        log.debug('iptables._chain6 == %s', chain)

        if 'target' in conf:
            self._target = self._targets[conf['target']]
        else:
            self._target = None
        log.debug('iptables._target == %s', self._target)

        if 'ports' in conf['match']:
            self._ports = conf['match']['ports']
        else:
            self._ports = None
        log.debug('iptables._ports == %s', self._ports)

        if 'protocol' in conf['match']:
            self._proto = conf['match']['protocol']
        else:
            self._proto = None
        log.debug('iptables._proto == %s', self._proto)

        if 'sources' in conf['match']:
            self._sources = [ip_network(ip) for ip in conf['match']['sources']]
        else:
            self._sources = None
        log.debug('iptables._sources == %s', self._sources)

        if 'destinations' in conf['match']:
            self._dests = [ip_network(ip) for ip in conf['match']['sources']]
        else:
            self._dests = None
        log.debug('iptables._dests == %s', self._dests)

        self._rule4 = iptc.Rule()
        self._rule6 = iptc.Rule6()

        self._uuids: List[str] = []

        try:
            self.rule_builder()
        except ValueError as e:
            log.error(
                'An error was encountered while initialising the IPTables plugin'
            )
            log.debug(e)
            raise e
Пример #21
0
def mailcowChainOrder():
    global lock
    global quit_now
    while not quit_now:
        time.sleep(10)
        with lock:
            filter4_table = iptc.Table(iptc.Table.FILTER)
            filter6_table = iptc.Table6(iptc.Table6.FILTER)
            filter4_table.refresh()
            filter6_table.refresh()
            for f in [filter4_table, filter6_table]:
                forward_chain = iptc.Chain(f, 'FORWARD')
                input_chain = iptc.Chain(f, 'INPUT')
                for chain in [forward_chain, input_chain]:
                    target_found = False
                    for position, item in enumerate(chain.rules):
                        if item.target.name == 'MAILCOW':
                            target_found = True
                            if position != 0:
                                log['time'] = int(round(time.time()))
                                log['priority'] = 'crit'
                                log['message'] = 'Error in ' + chain.name + ' chain order, restarting container'
                                r.lpush('NETFILTER_LOG',
                                        json.dumps(log, ensure_ascii=False))
                                print log['message']
                                quit_now = True
                    if not target_found:
                        log['time'] = int(round(time.time()))
                        log['priority'] = 'crit'
                        log['message'] = 'Error in ' + chain.name + ' chain: MAILCOW target not found, restarting container'
                        r.lpush('NETFILTER_LOG',
                                json.dumps(log, ensure_ascii=False))
                        print log['message']
                        quit_now = True
Пример #22
0
    def _insert_iptables_rule(self, rule, ipv6=False, tables=None):
        if not isinstance(rule, tuple):
            return self._insert_iptables_rule_cmd(rule, ipv6)

        _global_lock.acquire()
        try:
            for i in xrange(3):
                if ipv6:
                    if rule[0] == 'POSTROUTING':
                        if tables:
                            table = tables['nat6']
                        else:
                            table = iptc.Table6(iptc.Table.NAT)
                    else:
                        if tables:
                            table = tables['filter6']
                        else:
                            table = iptc.Table6(iptc.Table.FILTER)
                else:
                    if rule[0] == 'POSTROUTING':
                        if tables:
                            table = tables['nat']
                        else:
                            table = iptc.Table(iptc.Table.NAT)
                    else:
                        if tables:
                            table = tables['filter']
                        else:
                            table = iptc.Table(iptc.Table.FILTER)
                chain = iptc.Chain(table, rule[0])
                try:
                    chain.insert_rule(rule[1])
                    break
                except:
                    if i == 2:
                        raise
                    logger.error(
                        'Failed to insert iptables rule, retrying...',
                        'instance',
                        rule=rule,
                    )
                time.sleep(0.5)
        finally:
            _global_lock.release()
Пример #23
0
def get_table(type, name):
    """
    Gets a table. This is a simple helper method that returns either
    an IP v4 or an IP v6 table according to type.
    """
    if type == IPV4:
        table = iptc.Table(name)
    else:
        table = iptc.Table6(name)

    return table
Пример #24
0
def getIPTablesChainForVersion(ipVersion, chain):
    if ipVersion == IP_VERSION.V4 and iptc.is_table_available(
            iptc.Table.FILTER):
        chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), chain)
    elif ipVersion == IP_VERSION.V6 and iptc.is_table_available(
            iptc.Table6.FILTER):
        chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), chain)
    else:
        LOG.error("Could not find chain \'%s\' for IPv%s IPTables", chain,
                  ipVersion)

    return chain
Пример #25
0
def show(ip=None):
    if ip is IPv4:
        table = iptc.Table(iptc.Table.FILTER)
        __logger.debug("Print IPv4 firewall rules")
        __printrule(table)
    elif ip is IPv6:
        table = iptc.Table6(iptc.Table6.FILTER)
        __logger.debug("Print IPv6 firewall rules")
        __printrule(table)
    else:
        show(IPv4)
        show(IPv6)
Пример #26
0
    def _exists_iptables_rule(self, rule, ipv6=False, tables=None):
        # TODO
        return False

        if not isinstance(rule, tuple):
            return self._exists_iptables_rule_cmd(rule, ipv6)

        _global_lock.acquire()
        try:
            if ipv6:
                if rule[0] == 'POSTROUTING':
                    if tables:
                        table = tables['nat6']
                    else:
                        table = iptc.Table6(iptc.Table.NAT)
                else:
                    if tables:
                        table = tables['filter6']
                    else:
                        table = iptc.Table6(iptc.Table.FILTER)
            else:
                if rule[0] == 'POSTROUTING':
                    if tables:
                        table = tables['nat']
                    else:
                        table = iptc.Table(iptc.Table.NAT)
                else:
                    if tables:
                        table = tables['filter']
                    else:
                        table = iptc.Table(iptc.Table.FILTER)
            chain = iptc.Chain(table, rule[0])

            for rule2 in chain.rules:
                if rule[1] == rule2:
                    return True

            return False
        finally:
            _global_lock.release()
Пример #27
0
 def collect(self):
     # Metrics
     iptables_rules = GaugeMetricFamily(
         'iptables_rules',
         'Number of rules',
         labels=['ip_version', 'table', 'chain'],
     )
     iptables_packets = CounterMetricFamily(
         'iptables_packets',
         'Number of matched packets',
         labels=['ip_version', 'table', 'chain', 'rule'],
     )
     iptables_bytes = CounterMetricFamily(
         'iptables_bytes',
         'Number of matched bytes',
         labels=['ip_version', 'table', 'chain', 'rule'],
     )
     for ip_version in self.ip_versions:
         labels = dict(ip_version=ip_version)
         for table_name in self.tables:
             if ip_version == '4':
                 table = iptc.Table(TABLES[table_name])
             else:
                 table = iptc.Table6(TABLES[table_name])
             table.refresh()
             labels['table'] = table_name
             for chain in table.chains:
                 labels['chain'] = chain.name.lower()
                 rule_count = 0
                 for rule in chain.rules:
                     rule_count += 1
                     exporter_name = get_exporter_name(rule)
                     if exporter_name:
                         labels['rule'] = exporter_name
                         counter_labels = [
                             labels['ip_version'], labels['table'],
                             labels['chain'], labels['rule']
                         ]
                         packets, bytes = rule.get_counters()
                         iptables_packets.add_metric(
                             counter_labels, packets)
                         iptables_bytes.add_metric(counter_labels, bytes)
                 rules_labels = [
                     labels['ip_version'], labels['table'], labels['chain']
                 ]
                 iptables_rules.add_metric(rules_labels, rule_count)
     yield iptables_rules
     yield iptables_packets
     yield iptables_bytes
Пример #28
0
def update_iptables(policy):
    policies = [p.split() for p in policy]
    for chain in ['INPUT', 'OUTPUT', 'FORWARD']:
        rules = [
            accept_localhost(iptc.Rule6()),
            accept_related_established(iptc.Rule6())
        ]
        rules += [
            create_rule(iptc.Rule(), p[1], p[2], p[3], p[4])
            if len(p) > 2 else create_rule(iptc.Rule(), p[1], None, None, None)
            for p in policies if p[0] == chain
        ]
        write_chain(iptc.Table(iptc.Table.FILTER), chain, rules)
        write_chain(iptc.Table6(iptc.Table6.FILTER), chain,
                    [create_rule(iptc.Rule6(), 'DROP', None, None, None)])
Пример #29
0
    def _remove_iptables_rule(self, rule, ipv6=False, tables=None):
        if not isinstance(rule, tuple):
            return self._remove_iptables_rule_cmd(rule, ipv6)

        _global_lock.acquire()
        try:
            if ipv6:
                if rule[0] == 'POSTROUTING':
                    if tables:
                        table = tables['nat6']
                    else:
                        table = iptc.Table6(iptc.Table.NAT)
                else:
                    if tables:
                        table = tables['filter6']
                    else:
                        table = iptc.Table6(iptc.Table.FILTER)
            else:
                if rule[0] == 'POSTROUTING':
                    if tables:
                        table = tables['nat']
                    else:
                        table = iptc.Table(iptc.Table.NAT)
                else:
                    if tables:
                        table = tables['filter']
                    else:
                        table = iptc.Table(iptc.Table.FILTER)
            chain = iptc.Chain(table, rule[0])
            try:
                chain.delete_rule(rule[1])
            except:
                pass
            return True
        finally:
            _global_lock.release()
Пример #30
0
def dropIPv6(ip6):
    try:
        v = IP(ip6).version()
    except:
        return
    if ip6 not in v6iplist and v == 6:
        try:
            chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), "INPUT")
            rule = iptc.Rule6()
            rule.in_interface = "eth+"
            rule.src = ip6
            rule.target = iptc.Target(rule, "DROP")
            chain.insert_rule(rule)
            v6iplist.append(ip6)
        except Exception as e:
            print("OpenDXL.dropIPv6.Exception(%s): %s" % (ip6, str(e)))