def __init__(self, config): """ Class constructor. :param config: The configuration object """ logger.info("Setting up the tunnel manager...") self.config = config self.max_tunnels = config.getint('broker', 'max_tunnels') self.netlink = NetlinkInterface() self.conntrack = conntrack.ConnectionManager() self.tunnels = {} self.cookies = repoze.lru.LRUCache( config.getint('broker', 'max_cookies')) self.secret = os.urandom(32) id_base = config.getint('broker', 'tunnel_id_base') self.tunnel_ids = range(id_base, id_base + self.max_tunnels + 1) self.port_base = config.getint('broker', 'port_base') self.interface = config.get('broker', 'interface') self.address = config.get('broker', 'address') self.ports = [int(x) for x in config.get('broker', 'port').split(',')] self.namespace = config.get('broker', 'namespace') self.closed = False self.setup_tunnels() self.setup_netfilter() self.setup_hooks() # Log some configuration variables logger.info(" Maximum number of tunnels: %d" % self.max_tunnels) logger.info(" Interface: %s" % self.interface) logger.info(" Address: %s" % self.address) logger.info(" Ports: %s" % self.ports) logger.info(" Namespace: %s" % self.namespace) logger.info("Tunnel manager initialized.")
def initialize(self): """ Sets up netfilter rules so new packets to the same port are redirected into the per-tunnel socket. """ prerouting_chain = "L2TP_PREROUTING_%s" % self.namespace postrouting_chain = "L2TP_POSTROUTING_%s" % self.namespace nat = netfilter.table.Table('nat') self.rule_prerouting_jmp = netfilter.rule.Rule(jump=prerouting_chain) self.rule_postrouting_jmp = netfilter.rule.Rule(jump=postrouting_chain) try: nat.flush_chain(prerouting_chain) nat.delete_chain(prerouting_chain) except netfilter.table.IptablesError: pass try: nat.flush_chain(postrouting_chain) nat.delete_chain(postrouting_chain) except netfilter.table.IptablesError: pass try: nat.create_chain(prerouting_chain) nat.create_chain(postrouting_chain) except netfilter.table.IptablesError: pass try: nat.delete_rule('PREROUTING', self.rule_prerouting_jmp) except netfilter.table.IptablesError: pass nat.prepend_rule('PREROUTING', self.rule_prerouting_jmp) try: nat.delete_rule('POSTROUTING', self.rule_postrouting_jmp) except netfilter.table.IptablesError: pass nat.prepend_rule('POSTROUTING', self.rule_postrouting_jmp) # Initialize connection tracking manager. self.conntrack = conntrack.ConnectionManager() # Initialize netlink. self.netlink = l2tp.NetlinkInterface() # Initialize tunnels. for tunnel_id, session_id in self.netlink.session_list(): if tunnel_id in self.tunnel_ids: logger.warning("Removing existing tunnel %d session %d." % (tunnel_id, session_id)) self.netlink.session_delete(tunnel_id, session_id) for tunnel_id in self.netlink.tunnel_list(): if tunnel_id in self.tunnel_ids: logger.warning("Removing existing tunnel %d." % tunnel_id) self.netlink.tunnel_delete(tunnel_id)