Exemplo n.º 1
0
    def generate_iptables_rules(self):
        rules = []
        rules6 = []

        try:
            routes_output = utils.check_output_logged(['route', '-n'])
        except subprocess.CalledProcessError:
            logger.exception('Failed to get IP routes', 'server',
                server_id=self.server.id,
            )
            raise

        routes = []
        default_interface = None
        for line in routes_output.splitlines():
            line_split = line.split()
            if len(line_split) < 8 or not re.match(IP_REGEX, line_split[0]):
                continue
            if line_split[0] not in routes:
                if line_split[0] == '0.0.0.0':
                    default_interface = line_split[7]

                routes.append((
                    ipaddress.IPNetwork('%s/%s' % (line_split[0],
                        utils.subnet_to_cidr(line_split[2]))),
                    line_split[7]
                ))
        routes.reverse()

        if not default_interface:
            raise IptablesError('Failed to find default network interface')

        routes6 = []
        default_interface6 = None
        if self.server.ipv6:
            try:
                routes_output = utils.check_output_logged(
                    ['route', '-n', '-A', 'inet6'])
            except subprocess.CalledProcessError:
                logger.exception('Failed to get IPv6 routes', 'server',
                    server_id=self.server.id,
                )
                raise

            for line in routes_output.splitlines():
                line_split = line.split()

                if len(line_split) < 7:
                    continue

                try:
                    route_network = ipaddress.IPv6Network(line_split[0])
                except (ipaddress.AddressValueError, ValueError):
                    continue

                if not default_interface6 and line_split[0] == '::/0':
                    default_interface6 = line_split[6]

                routes6.append((
                    route_network,
                    line_split[6]
                ))

            if not default_interface6:
                raise IptablesError(
                    'Failed to find default IPv6 network interface')

            if default_interface6 == 'lo':
                logger.error('Failed to find default IPv6 interface',
                    'server',
                    server_id=self.server.id,
                )
        routes6.reverse()

        route_all = self.server.is_route_all()
        if route_all:
            rules.append([
                'INPUT',
                '-i', self.interface,
                '-j', 'ACCEPT',
            ])
            rules.append([
                'OUTPUT',
                '-o', self.interface,
                '-j', 'ACCEPT',
            ])
            rules.append([
                'FORWARD',
                '-i', self.interface,
                '-j', 'ACCEPT',
            ])
            if self.server.ipv6:
                if self.server.ipv6_firewall and \
                        settings.local.host.routed_subnet6:
                    rules6.append([
                        'INPUT',
                        '-d', self.server.network6,
                         '-m', 'conntrack',
                         '--ctstate','RELATED,ESTABLISHED',
                         '-j', 'ACCEPT',
                    ])
                    rules6.append([
                        'INPUT',
                        '-d', self.server.network6,
                        '-p', 'icmpv6',
                         '-m', 'conntrack',
                        '--ctstate', 'NEW',
                        '-j', 'ACCEPT',
                    ])

                    rules6.append([
                        'INPUT',
                        '-d', self.server.network6,
                        '-j', 'DROP',
                    ])

                    rules6.append([
                        'FORWARD',
                        '-d', self.server.network6,
                        '-m', 'conntrack',
                         '--ctstate', 'RELATED,ESTABLISHED',
                        '-j', 'ACCEPT',
                    ])
                    rules6.append([
                        'FORWARD',
                        '-d', self.server.network6,
                        '-p', 'icmpv6',
                         '-m', 'conntrack',
                        '--ctstate', 'NEW',
                        '-j', 'ACCEPT',
                    ])

                    rules6.append([
                        'FORWARD',
                        '-d', self.server.network6,
                        '-j', 'DROP',
                    ])
                else:
                    rules6.append([
                        'INPUT',
                        '-d', self.server.network6,
                        '-j', 'ACCEPT',
                    ])
                    rules6.append([
                        'FORWARD',
                        '-d', self.server.network6,
                        '-j', 'ACCEPT',
                    ])
        elif self.server.restrict_routes:
            if self.server.inter_client:
                rules.append([
                    'INPUT', '-i', self.interface,
                    '-d', self.server.network,
                    '-j', 'ACCEPT',
                ])
                rules6.append([
                    'INPUT', '-i', self.interface,
                    '-d', self.server.network6,
                    '-j', 'ACCEPT',
                ])
                rules.append([
                    'OUTPUT', '-o', self.interface,
                    '-s', self.server.network,
                    '-j', 'ACCEPT',
                ])
                rules6.append([
                    'OUTPUT', '-o', self.interface,
                    '-s', self.server.network6,
                    '-j', 'ACCEPT',
                ])
                rules.append([
                    'FORWARD', '-i', self.interface,
                    '-d', self.server.network,
                    '-j', 'ACCEPT',
                ])
                rules.append([
                    'FORWARD', '-o', self.interface,
                    '-s', self.server.network,
                    '-j', 'ACCEPT',
                ])
                rules6.append([
                    'FORWARD', '-i', self.interface,
                    '-d', self.server.network6,
                    '-j', 'ACCEPT',
                ])
                rules6.append([
                    'FORWARD', '-o', self.interface,
                    '-s', self.server.network6,
                    '-j', 'ACCEPT',
                ])
            else:
                server_addr = utils.get_network_gateway(self.server.network)
                server_addr6 = utils.get_network_gateway(self.server.network6)
                rules.append([
                    'INPUT', '-i', self.interface,
                    '-d', server_addr,
                    '-j', 'ACCEPT',
                ])
                rules6.append([
                    'INPUT', '-i', self.interface,
                    '-d', server_addr6,
                    '-j', 'ACCEPT',
                ])
                rules.append([
                    'OUTPUT', '-o', self.interface,
                    '-s', server_addr,
                    '-j', 'ACCEPT',
                ])
                rules6.append([
                    'OUTPUT', '-o', self.interface,
                    '-s', server_addr6,
                    '-j', 'ACCEPT',
                ])

            for route in self.server.get_routes(
                        include_hidden=True,
                        include_server_links=True,
                        include_default=False,
                    ):
                network_address = route['network']
                is6 = ':' in network_address
                is_nat = route['nat']

                if route['virtual_network']:
                    continue

                if self.server.restrict_routes:
                    if is6:
                        rules6.append([
                            'INPUT',
                            '-i', self.interface,
                            '-d', network_address,
                            '-j', 'ACCEPT',
                        ])
                        rules6.append([
                            'OUTPUT',
                            '-o', self.interface,
                            '-s', network_address,
                            '-j', 'ACCEPT',
                        ])
                        rules6.append([
                            'FORWARD',
                            '-i', self.interface,
                            '-d', network_address,
                            '-j', 'ACCEPT',
                        ])

                        if is_nat:
                            rules6.append([
                                'FORWARD',
                                '-o', self.interface,
                                '-m', 'conntrack',
                                '--ctstate', 'RELATED,ESTABLISHED',
                                '-s', network_address,
                                '-j', 'ACCEPT',
                            ])
                        else:
                            rules6.append([
                                'FORWARD',
                                '-o', self.interface,
                                '-s', network_address,
                                '-j', 'ACCEPT',
                            ])
                    else:
                        rules.append([
                            'INPUT',
                            '-i', self.interface,
                            '-d', network_address,
                            '-j', 'ACCEPT',
                        ])
                        rules.append([
                            'OUTPUT',
                            '-o', self.interface,
                            '-s', network_address,
                            '-j', 'ACCEPT',
                        ])
                        rules.append([
                            'FORWARD',
                            '-i', self.interface,
                            '-d', network_address,
                            '-j', 'ACCEPT',
                        ])

                        if is_nat:
                            rules.append([
                                'FORWARD',
                                '-o', self.interface,
                                '-m', 'conntrack',
                                '--ctstate', 'RELATED,ESTABLISHED',
                                '-s', network_address,
                                '-j', 'ACCEPT',
                            ])
                        else:
                            rules.append([
                                'FORWARD',
                                '-o', self.interface,
                                '-s', network_address,
                                '-j', 'ACCEPT',
                            ])

        interfaces = set()
        interfaces6 = set()

        link_svr_networks = []
        for link_svr in self.server.iter_links(fields=('_id', 'network',
                'network_start', 'network_end', 'organizations', 'routes',
                'links')):
            link_svr_networks.append(link_svr.network)

        for route in self.server.get_routes(include_hidden=True):
            if route['virtual_network'] or not route['nat']:
                continue

            network_address = route['network']

            args_base = ['POSTROUTING', '-t', 'nat']
            is6 = ':' in network_address
            if is6:
                network = network_address
            else:
                network = utils.parse_network(network_address)[0]
            network_obj = ipaddress.IPNetwork(network_address)

            if is6:
                interface = None
                for route_net, route_intf in routes6:
                    if network_obj in route_net:
                        interface = route_intf
                        break

                if not interface:
                    logger.info(
                        'Failed to find interface for local ' + \
                            'IPv6 network route, using default route',
                            'server',
                        server_id=self.server.id,
                        network=network,
                    )
                    interface = default_interface6
                interfaces6.add(interface)
            else:
                interface = None
                for route_net, route_intf in routes:
                    if network_obj in route_net:
                        interface = route_intf
                        break

                if not interface:
                    logger.info(
                        'Failed to find interface for local ' + \
                            'network route, using default route',
                            'server',
                        server_id=self.server.id,
                        network=network,
                    )
                    interface = default_interface
                interfaces.add(interface)

            if network != '0.0.0.0' and network != '::/0':
                args_base += ['-d', network_address]

            args_base += [
                '-o', interface,
                '-j', 'MASQUERADE',
            ]

            if is6:
                rules6.append(args_base + ['-s', self.server.network6])
            else:
                rules.append(args_base + ['-s', self.server.network])

            for link_svr_net in link_svr_networks:
                if ':' in link_svr_net:
                    rules6.append(args_base + ['-s', link_svr_net])
                else:
                    rules.append(args_base + ['-s', link_svr_net])

        if route_all:
            for interface in interfaces:
                rules.append([
                    'FORWARD',
                    '-i', interface,
                    '-o', self.interface,
                    '-m', 'state',
                    '--state', 'ESTABLISHED,RELATED',
                    '-j', 'ACCEPT',
                ])
                rules.append([
                    'FORWARD',
                    '-i', self.interface,
                    '-o', interface,
                    '-m', 'state',
                    '--state', 'ESTABLISHED,RELATED',
                    '-j', 'ACCEPT',
                ])

            for interface in interfaces6:
                if self.server.ipv6 and self.server.ipv6_firewall and \
                        settings.local.host.routed_subnet6 and \
                        interface == default_interface6:
                    continue

                rules6.append([
                    'FORWARD',
                    '-i', interface,
                    '-o', self.interface,
                    '-m', 'state',
                    '--state', 'ESTABLISHED,RELATED',
                    '-j', 'ACCEPT',
                ])
                rules6.append([
                    'FORWARD',
                    '-i', self.interface,
                    '-o', interface,
                    '-m', 'state',
                    '--state', 'ESTABLISHED,RELATED',
                    '-j', 'ACCEPT',
                ])

        extra_args = [
            '-m', 'comment',
            '--comment', 'pritunl_%s' % self.server.id,
        ]

        if settings.local.iptables_wait:
            extra_args.append('--wait')

        rules = [x + extra_args for x in rules]
        rules6 = [x + extra_args for x in rules6]

        return rules, rules6
Exemplo n.º 2
0
    def generate_iptables_rules(self):
        server_addr = utils.get_network_gateway(self.server.network)
        server_addr6 = utils.get_network_gateway(self.server.network6)
        ipv6_firewall = self.server.ipv6_firewall and \
            settings.local.host.routed_subnet6

        self.iptables.id = self.server.id
        self.iptables.ipv6 = self.server.ipv6
        self.iptables.server_addr = server_addr
        self.iptables.server_addr6 = server_addr6
        self.iptables.virt_interface = self.interface
        self.iptables.virt_network = self.server.network
        self.iptables.virt_network6 = self.server.network6
        self.iptables.ipv6_firewall = ipv6_firewall
        self.iptables.inter_client = self.server.inter_client
        self.iptables.restrict_routes = self.server.restrict_routes

        try:
            routes_output = utils.check_output_logged(['route', '-n'])
        except subprocess.CalledProcessError:
            logger.exception(
                'Failed to get IP routes',
                'server',
                server_id=self.server.id,
            )
            raise

        routes = []
        default_interface = None
        for line in routes_output.splitlines():
            line_split = line.split()
            if len(line_split) < 8 or not re.match(IP_REGEX, line_split[0]):
                continue
            if line_split[0] not in routes:
                if line_split[0] == '0.0.0.0':
                    if default_interface:
                        continue
                    default_interface = line_split[7]

                routes.append((ipaddress.IPNetwork(
                    '%s/%s' %
                    (line_split[0], utils.subnet_to_cidr(line_split[2]))),
                               line_split[7]))
        routes.reverse()

        if not default_interface:
            raise IptablesError('Failed to find default network interface')

        routes6 = []
        default_interface6 = None
        if self.server.ipv6:
            try:
                routes_output = utils.check_output_logged(
                    ['route', '-n', '-A', 'inet6'])
            except subprocess.CalledProcessError:
                logger.exception(
                    'Failed to get IPv6 routes',
                    'server',
                    server_id=self.server.id,
                )
                raise

            for line in routes_output.splitlines():
                line_split = line.split()

                if len(line_split) < 7:
                    continue

                try:
                    route_network = ipaddress.IPv6Network(line_split[0])
                except (ipaddress.AddressValueError, ValueError):
                    continue

                if line_split[0] == '::/0':
                    if default_interface6:
                        continue
                    default_interface6 = line_split[6]

                routes6.append((
                    route_network,
                    line_split[6],
                ))

            if not default_interface6:
                raise IptablesError(
                    'Failed to find default IPv6 network interface')

            if default_interface6 == 'lo':
                logger.error(
                    'Failed to find default IPv6 interface',
                    'server',
                    server_id=self.server.id,
                )
        routes6.reverse()

        interfaces = set()
        interfaces6 = set()

        for route in self.server.get_routes(
                include_hidden=True,
                include_server_links=True,
                include_default=True,
        ):
            if route['virtual_network'] or route['link_virtual_network']:
                self.iptables.add_nat_network(route['network'])

            if route['virtual_network'] or route['net_gateway']:
                continue

            network = route['network']
            is6 = ':' in network
            network_obj = ipaddress.IPNetwork(network)

            interface = route['nat_interface']
            if is6:
                if not interface:
                    for route_net, route_intf in routes6:
                        if network_obj in route_net:
                            interface = route_intf
                            break

                    if not interface:
                        logger.info(
                            'Failed to find interface for local ' + \
                                'IPv6 network route, using default route',
                                'server',
                            server_id=self.server.id,
                            network=network,
                        )
                        interface = default_interface6
                interfaces6.add(interface)
            else:
                if not interface:
                    for route_net, route_intf in routes:
                        if network_obj in route_net:
                            interface = route_intf
                            break

                    if not interface:
                        logger.info(
                            'Failed to find interface for local ' + \
                                'network route, using default route',
                                'server',
                            server_id=self.server.id,
                            network=network,
                        )
                        interface = default_interface
                interfaces.add(interface)

            self.iptables.add_route(
                network,
                nat=route['nat'],
                nat_interface=interface,
            )

        if self.vxlan:
            self.iptables.add_route(self.vxlan.vxlan_net)

        self.iptables.generate()
Exemplo n.º 3
0
    def generate_iptables_rules(self):
        server_addr = utils.get_network_gateway(self.server.network)
        server_addr6 = utils.get_network_gateway(self.server.network6)
        ipv6_firewall = self.server.ipv6_firewall and \
            settings.local.host.routed_subnet6

        self.iptables.id = self.server.id
        self.iptables.ipv6 = self.server.ipv6
        self.iptables.server_addr = server_addr
        self.iptables.server_addr6 = server_addr6
        self.iptables.virt_interface = self.interface
        self.iptables.virt_network = self.server.network
        self.iptables.virt_network6 = self.server.network6
        self.iptables.ipv6_firewall = ipv6_firewall
        self.iptables.inter_client = self.server.inter_client

        try:
            routes_output = utils.check_output_logged(['route', '-n'])
        except subprocess.CalledProcessError:
            logger.exception('Failed to get IP routes', 'server',
                server_id=self.server.id,
            )
            raise

        routes = []
        default_interface = None
        for line in routes_output.splitlines():
            line_split = line.split()
            if len(line_split) < 8 or not re.match(IP_REGEX, line_split[0]):
                continue
            if line_split[0] not in routes:
                if line_split[0] == '0.0.0.0':
                    if default_interface:
                        continue
                    default_interface = line_split[7]

                routes.append((
                    ipaddress.IPNetwork('%s/%s' % (line_split[0],
                        utils.subnet_to_cidr(line_split[2]))),
                    line_split[7]
                ))
        routes.reverse()

        if not default_interface:
            raise IptablesError('Failed to find default network interface')

        routes6 = []
        default_interface6 = None
        if self.server.ipv6:
            try:
                routes_output = utils.check_output_logged(
                    ['route', '-n', '-A', 'inet6'])
            except subprocess.CalledProcessError:
                logger.exception('Failed to get IPv6 routes', 'server',
                    server_id=self.server.id,
                )
                raise

            for line in routes_output.splitlines():
                line_split = line.split()

                if len(line_split) < 7:
                    continue

                try:
                    route_network = ipaddress.IPv6Network(line_split[0])
                except (ipaddress.AddressValueError, ValueError):
                    continue

                if line_split[0] == '::/0':
                    if default_interface6:
                        continue
                    default_interface6 = line_split[6]

                routes6.append((
                    route_network,
                    line_split[6],
                ))

            if not default_interface6:
                raise IptablesError(
                    'Failed to find default IPv6 network interface')

            if default_interface6 == 'lo':
                logger.error('Failed to find default IPv6 interface',
                    'server',
                    server_id=self.server.id,
                )
        routes6.reverse()

        interfaces = set()
        interfaces6 = set()

        for route in self.server.get_routes(
                    include_hidden=True,
                    include_server_links=True,
                    include_default=True,
                ):
            if route['virtual_network'] or route['link_virtual_network']:
                self.iptables.add_nat_network(route['network'])

            if route['virtual_network']:
                continue

            network = route['network']
            is6 = ':' in network
            network_obj = ipaddress.IPNetwork(network)

            interface = route['nat_interface']
            if is6:
                if not interface:
                    for route_net, route_intf in routes6:
                        if network_obj in route_net:
                            interface = route_intf
                            break

                    if not interface:
                        logger.info(
                            'Failed to find interface for local ' + \
                                'IPv6 network route, using default route',
                                'server',
                            server_id=self.server.id,
                            network=network,
                        )
                        interface = default_interface6
                interfaces6.add(interface)
            else:
                if not interface:
                    for route_net, route_intf in routes:
                        if network_obj in route_net:
                            interface = route_intf
                            break

                    if not interface:
                        logger.info(
                            'Failed to find interface for local ' + \
                                'network route, using default route',
                                'server',
                            server_id=self.server.id,
                            network=network,
                        )
                        interface = default_interface
                interfaces.add(interface)

            self.iptables.add_route(
                network,
                nat=route['nat'],
                nat_interface=interface,
            )

        self.iptables.generate()