Пример #1
0
    def add_route(self, virt_address, virt_address6,
            host_address, host_address6):
        virt_address = virt_address.split('/')[0]

        _route_lock.acquire()
        try:
            if virt_address in self.client_routes:
                try:
                    self.client_routes.remove(virt_address)
                    try:
                        utils.check_call_silent([
                            'ip',
                            'route',
                            'del',
                            virt_address,
                        ])
                    except subprocess.CalledProcessError:
                        pass
                except KeyError:
                    pass

            if not host_address or host_address == \
                    settings.local.host.local_addr:
                return

            for i in xrange(3):
                try:
                    utils.check_output_logged([
                        'ip',
                        'route',
                        'add',
                        virt_address,
                        'via',
                        host_address,
                    ])
                    break
                except subprocess.CalledProcessError:
                    if i == 0:
                        try:
                            utils.check_call_silent([
                                'ip',
                                'route',
                                'del',
                                virt_address,
                            ])
                        except subprocess.CalledProcessError:
                            pass
                    elif i == 2:
                        raise
                    time.sleep(0.2)
        except:
            logger.exception('Failed to add route', 'clients',
                virt_address=virt_address,
                virt_address6=virt_address6,
                host_address=host_address,
                host_address6=host_address6,
            )
        finally:
            _route_lock.release()
Пример #2
0
    def build_onc_archive(self):
        temp_path = utils.get_temp_path()
        key_archive_path = os.path.join(temp_path, '%s.zip' % self.id)

        try:
            os.makedirs(temp_path)
            zip_file = zipfile.ZipFile(key_archive_path, 'w')
            try:
                user_cert_path = os.path.join(temp_path, '%s.crt' % self.id)
                user_key_path = os.path.join(temp_path, '%s.key' % self.id)
                user_p12_path = os.path.join(temp_path, '%s.p12' % self.id)

                with open(user_cert_path, 'w') as user_cert:
                    user_cert.write(self.certificate)

                with open(user_key_path, 'w') as user_key:
                    os.chmod(user_key_path, 0600)
                    user_key.write(self.private_key)

                utils.check_output_logged([
                    'openssl',
                    'pkcs12',
                    '-export',
                    '-nodes',
                    '-password', 'pass:'******'-inkey', user_key_path,
                    '-in', user_cert_path,
                    '-out', user_p12_path
                ])

                zip_file.write(user_p12_path, arcname='%s.p12' % self.name)

                os.remove(user_cert_path)
                os.remove(user_key_path)
                os.remove(user_p12_path)

                for svr in self.org.iter_servers():
                    server_conf_path = os.path.join(temp_path,
                        '%s_%s.onc' % (self.id, svr.id))
                    conf_name, client_conf = self._generate_onc(svr)
                    if not client_conf:
                        continue

                    with open(server_conf_path, 'w') as ovpn_conf:
                        ovpn_conf.write(client_conf)
                    zip_file.write(server_conf_path, arcname=conf_name)
                    os.remove(server_conf_path)
            finally:
                zip_file.close()

            with open(key_archive_path, 'r') as archive_file:
                key_archive = archive_file.read()
        finally:
            utils.rmtree(temp_path)

        return key_archive
Пример #3
0
    def add_host(self, host_vxlan_id, vxlan_mac, host_dst):
        if settings.local.host.local_addr == host_dst:
            return

        self.running_lock.acquire()
        try:
            if not self.running:
                return

            for i in xrange(2):
                try:
                    if i == 0:
                        check_func = utils.check_call_silent
                    else:
                        check_func = utils.check_output_logged

                    check_func([
                        'bridge',
                        'fdb',
                        'add',
                        vxlan_mac,
                        'dev',
                        self.iface_name,
                        'dst',
                        host_dst,
                    ])

                    break
                except subprocess.CalledProcessError:
                    if i == 0:
                        utils.check_output_logged([
                            'bridge',
                            'fdb',
                            'del',
                            vxlan_mac,
                            'dev',
                            self.iface_name,
                        ])
                    else:
                        raise

            utils.check_output_logged([
                'arp',
                '-s',
                self.get_host_addr(host_vxlan_id),
                vxlan_mac,
            ])
        except:
            logger.error('Failed to ad vxlan host', 'vxlan',
                vxlan_id=self.vxlan_id,
                server_id=self.server_id,
            )
            raise
        finally:
            self.running_lock.release()
Пример #4
0
    def enable_ip_forwarding(self):
        logger.debug('Enabling ip forwarding', 'server',
            server_id=self.server.id,
        )

        try:
            utils.check_output_logged(
                ['sysctl', '-w', 'net.ipv4.ip_forward=1'])
        except subprocess.CalledProcessError:
            logger.exception('Failed to enable IP forwarding', 'server',
                server_id=self.server.id,
            )
            raise
Пример #5
0
 def set_ip6tables_rule(self, rule):
     for i in xrange(3):
         try:
             utils.check_output_logged(['ip6tables', '-I'] + rule)
             break
         except:
             if i == 2:
                 raise
             logger.error(
                 'Failed to insert ip6tables rule, retrying...',
                 'instance',
                 rule=rule,
             )
         time.sleep(1)
Пример #6
0
def get_mem_usage():
    try:
        free = utils.check_output_logged(['free']).split()
        return float(free[15]) / float(free[7])
    except:
        logger.exception('Failed to get memory usage', 'host')
    return 0
Пример #7
0
def _default_interface_thread():
    global default_interface6

    while True:
        iface6 = None
        iface6_alt = None

        try:
            routes_output = utils.check_output_logged(
                ['route', '-n', '-A', 'inet6'])
        except subprocess.CalledProcessError:
            logger.exception('Failed to get IPv6 routes', 'setup')
            time.sleep(1)
            continue

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

            if len(line_split) < 7:
                continue

            if line_split[0] == '::/0':
                if iface6 or line_split[6] == 'lo':
                    continue
                iface6 = line_split[6]

            if line_split[0] == 'ff00::/8':
                if iface6_alt or line_split[6] == 'lo':
                    continue
                iface6_alt = line_split[6]

        default_interface6 = iface6 or iface6_alt

        time.sleep(10)
Пример #8
0
def setup_server_cert():
    if not os.path.isfile(settings.conf.server_cert_path) or \
            not os.path.isfile(settings.conf.server_key_path):
        logger.info('Generating server ssl cert', 'setup')
        try:
            utils.check_output_logged([
                'openssl', 'req', '-batch', '-x509', '-nodes', '-sha256',
                '-newkey', 'rsa:4096',
                '-days', '3652',
                '-keyout', settings.conf.server_key_path,
                '-out', settings.conf.server_cert_path,
            ])
        except subprocess.CalledProcessError:
            logger.exception('Failed to generate server ssl cert', 'setup')
            raise
        os.chmod(settings.conf.server_key_path, 0600)
Пример #9
0
    def add_route(self, virt_address, virt_address6,
            host_address, host_address6):
        if not host_address or host_address == \
                settings.local.host.local_address:
            return

        _route_lock.acquire()
        try:
            cur_host_address = self.client_routes.pop(virt_address)
            if cur_host_address:
                try:
                    subprocess.check_output([
                        'ip',
                        'route',
                        'del',
                        virt_address,
                        'via',
                        cur_host_address,
                    ])
                except:
                    pass

            for i in xrange(3):
                try:
                    utils.check_output_logged([
                        'ip',
                        'route',
                        'add',
                        virt_address,
                        'via',
                        host_address,
                    ])
                    break
                except:
                    if i == 2:
                        raise
                    time.sleep(0.2)
        except:
            logger.exception('Failed to add route', 'clients',
                virt_address=virt_address,
                virt_address6=virt_address6,
                host_address=host_address,
                host_address6=host_address6,
            )
        finally:
            _route_lock.release()
Пример #10
0
    def _append_iptables_rule(self, rule, ipv6=False):
        rule = self._parse_rule(rule)

        for i in xrange(3):
            try:
                utils.check_output_logged(
                    ['ip6tables' if ipv6 else 'iptables', '-A'] + rule)
                break
            except:
                if i == 2:
                    raise
                logger.error(
                    'Failed to insert iptables rule, retrying...',
                    'instance',
                    rule=rule,
                )
            time.sleep(1)
Пример #11
0
    def _append_iptables_rule(self, rule, ipv6=False):
        rule = self._parse_rule(rule)

        for i in xrange(3):
            try:
                utils.check_output_logged(
                    ['ip6tables' if ipv6 else 'iptables', '-A'] + rule)
                break
            except:
                if i == 2:
                    raise
                logger.error(
                    'Failed to insert iptables rule, retrying...',
                    'instance',
                    rule=rule,
                )
            time.sleep(1)
Пример #12
0
    def enable_ip_forwarding(self):
        try:
            utils.check_output_logged(
                ['sysctl', '-w', 'net.ipv4.ip_forward=1'])
        except subprocess.CalledProcessError:
            logger.exception(
                'Failed to enable IP forwarding',
                'server',
                server_id=self.server.id,
            )
            raise

        if self.server.ipv6:
            keys = []
            output = utils.check_output_logged(['sysctl', 'net.ipv6.conf'])

            for line in output.split('\n'):
                if '.accept_ra =' in line:
                    keys.append(line.split('=')[0].strip())

            try:
                for key in keys:
                    utils.check_output_logged([
                        'sysctl',
                        '-w',
                        '%s=2' % key,
                    ])
                utils.check_output_logged(
                    ['sysctl', '-w', 'net.ipv6.conf.all.forwarding=1'])
            except subprocess.CalledProcessError:
                logger.exception(
                    'Failed to enable IPv6 forwarding',
                    'server',
                    server_id=self.server.id,
                )
Пример #13
0
    def enable_ip_forwarding(self):
        try:
            utils.check_output_logged(
                ['sysctl', '-w', 'net.ipv4.ip_forward=1'])
        except subprocess.CalledProcessError:
            logger.exception('Failed to enable IP forwarding', 'server',
                server_id=self.server.id,
            )
            raise

        if self.server.ipv6:
            keys = []
            output = utils.check_output_logged(['sysctl', 'net.ipv6.conf'])

            for line in output.split('\n'):
                if '.accept_ra =' in line:
                    keys.append(line.split('=')[0].strip())

            try:
                for key in keys:
                    utils.check_output_logged([
                        'sysctl',
                        '-w',
                        '%s=2' % key,
                    ])
                utils.check_output_logged(
                    ['sysctl', '-w', 'net.ipv6.conf.all.forwarding=1'])
            except subprocess.CalledProcessError:
                logger.exception('Failed to enable IPv6 forwarding', 'server',
                    server_id=self.server.id,
                )
Пример #14
0
    def enable_ip_forwarding(self):
        try:
            utils.check_output_logged(
                ['sysctl', '-w', 'net.ipv4.ip_forward=1'])
        except subprocess.CalledProcessError:
            logger.exception('Failed to enable IP forwarding', 'server',
                server_id=self.server.id,
            )
            raise

        if self.server.ipv6:
            try:
                utils.check_output_logged(
                    ['sysctl', '-w', 'net.ipv6.conf.all.forwarding=1'])
            except subprocess.CalledProcessError:
                logger.exception('Failed to enable IPv6 forwarding', 'server',
                    server_id=self.server.id,
                )
Пример #15
0
    def enable_ip_forwarding(self):
        try:
            utils.check_output_logged(
                ['sysctl', '-w', 'net.ipv4.ip_forward=1'])
        except subprocess.CalledProcessError:
            logger.exception('Failed to enable IP forwarding', 'server',
                server_id=self.server.id,
            )
            raise

        if self.server.ipv6:
            try:
                utils.check_output_logged(
                    ['sysctl', '-w', 'net.ipv6.conf.all.forwarding=1'])
            except subprocess.CalledProcessError:
                logger.exception('Failed to enable IPv6 forwarding', 'server',
                    server_id=self.server.id,
                )
Пример #16
0
    def _insert_iptables_rule_cmd(self, rule, ipv6=False):
        rule = self._parse_rule(rule)

        _global_lock.acquire()
        try:
            for i in xrange(3):
                try:
                    utils.check_output_logged(
                        ['ip6tables' if ipv6 else 'iptables', '-I'] + rule)
                    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()
Пример #17
0
    def _insert_iptables_rule_cmd(self, rule, ipv6=False):
        rule = self._parse_rule(rule)

        _global_lock.acquire()
        try:
            for i in xrange(3):
                try:
                    utils.check_output_logged(
                        ['ip6tables' if ipv6 else 'iptables', '-I'] + rule)
                    break
                except:
                    if i == 2:
                        raise
                    logger.error(
                        'Failed to insert iptables rule, retrying...',
                        'instance',
                        rule=rule,
                    )
                time.sleep(1)
        finally:
            _global_lock.release()
Пример #18
0
def _dns_thread():
    while not settings.local.sub_active or \
            settings.local.sub_plan != 'enterprise':
        time.sleep(1)

    while True:
        try:
            utils.check_output_logged(
                ['pritunl-dns'],
                env=dict(os.environ, **{
                    'DB': settings.conf.mongodb_uri,
                    'DB_PREFIX': settings.conf.mongodb_collection_prefix or '',
                }),
            )
        except GeneratorExit:
            raise
        except:
            logger.exception('Error in dns server', 'setup')

        time.sleep(60)
        yield
Пример #19
0
    def rem_interface(self, interface):
        if interface not in self.interfaces:
            return

        try:
            utils.check_output_logged([
                'ip',
                'link',
                'set',
                'down',
                interface,
            ])
        except subprocess.CalledProcessError:
            pass
        try:
            utils.check_output_logged([
                'brctl',
                'delif',
                self.bridge_interface,
                interface,
            ])
        except subprocess.CalledProcessError:
            pass
        try:
            utils.check_output_logged([
                'openvpn',
                '--rmtun',
                '--dev',
                interface,
            ])
        except subprocess.CalledProcessError:
            pass

        self.interfaces.remove(interface)
Пример #20
0
    def rem_interface(self, interface):
        if interface not in self.interfaces:
            return

        try:
            utils.check_output_logged([
                'ip',
                'link',
                'set',
                'down',
                interface,
            ])
        except subprocess.CalledProcessError:
            pass
        try:
            utils.check_output_logged([
                'brctl',
                'delif',
                self.bridge_interface,
                interface,
            ])
        except subprocess.CalledProcessError:
            pass
        try:
            utils.check_output_logged([
                'openvpn',
                '--rmtun',
                '--dev',
                interface,
            ])
        except subprocess.CalledProcessError:
            pass

        self.interfaces.remove(interface)
Пример #21
0
    def add_interface(self, interface):
        self.interfaces.add(interface)

        utils.check_output_logged([
            'openvpn',
            '--mktun',
            '--dev',
            interface,
        ])
        utils.check_output_logged([
            'ip',
            'link',
            'set',
            interface,
            'master',
            self.bridge_interface,
        ])
        utils.check_output_logged([
            'ip',
            'link',
            'set',
            'dev',
            interface,
            'promisc',
            'on',
        ])
Пример #22
0
def _dns_thread():
    while not settings.local.sub_active and \
            settings.local.sub_plan != 'enterprise':
        time.sleep(1)

    while True:
        try:
            utils.check_output_logged(
                ['pritunl-dns'],
                env=dict(
                    os.environ, **{
                        'DB': settings.conf.mongodb_uri,
                        'DB_PREFIX': settings.conf.mongodb_collection_prefix
                        or '',
                    }),
            )
        except GeneratorExit:
            raise
        except:
            logger.exception('Error in dns server', 'setup')

        time.sleep(1)
        yield
Пример #23
0
    def bridge_stop(self):
        if self.server.network_mode != BRIDGE:
            return

        try:
            utils.check_output_logged([
                'ifconfig',
                self.bridge_interface,
                'down',
            ])
        except subprocess.CalledProcessError:
            pass
        try:
            utils.check_output_logged([
                'brctl',
                'delbr',
                self.bridge_interface,
            ])
        except subprocess.CalledProcessError:
            pass
        try:
            utils.check_output_logged([
                'openvpn',
                '--rmtun',
                '--dev',
                self.interface,
            ])
        except subprocess.CalledProcessError:
            pass

        host_int_data = self.host_interface_data
        host_interface = host_int_data['interface']
        host_address = host_int_data['address']
        host_netmask = host_int_data['netmask']
        host_broadcast = host_int_data['broadcast']

        utils.check_output_logged([
            'ifconfig',
            host_interface,
            host_address,
            'netmask',
            host_netmask,
            'broadcast',
            host_broadcast,
        ])
Пример #24
0
    def rem_interface(self, interface):
        if interface not in self.interfaces:
            return

        try:
            utils.check_output_logged(["ip", "link", "set", "down", interface])
        except subprocess.CalledProcessError:
            pass
        try:
            utils.check_output_logged(["brctl", "delif", self.bridge_interface, interface])
        except subprocess.CalledProcessError:
            pass
        try:
            utils.check_output_logged(["openvpn", "--rmtun", "--dev", interface])
        except subprocess.CalledProcessError:
            pass

        self.interfaces.remove(interface)
Пример #25
0
    def add_interface(self, interface):
        self.interfaces.add(interface)

        utils.check_output_logged([
            'openvpn',
            '--mktun',
            '--dev',
            interface,
        ])
        utils.check_output_logged([
            'brctl',
            'addif',
            self.bridge_interface,
            interface,
        ])
        utils.check_output_logged([
            'ifconfig',
            interface,
            '0.0.0.0',
            'promisc',
            'up',
        ])
Пример #26
0
    def add_interface(self, interface):
        self.interfaces.add(interface)

        utils.check_output_logged([
            'openvpn',
            '--mktun',
            '--dev',
            interface,
        ])
        utils.check_output_logged([
            'brctl',
            'addif',
            self.bridge_interface,
            interface,
        ])
        utils.check_output_logged([
            'ifconfig',
            interface,
            '0.0.0.0',
            'promisc',
            'up',
        ])
Пример #27
0
    def add_route(self, virt_address, virt_address6, host_address,
                  host_address6):
        virt_address = virt_address.split('/')[0]

        _route_lock.acquire()
        try:
            if virt_address in self.client_routes:
                try:
                    self.client_routes.remove(virt_address)
                    try:
                        utils.check_call_silent([
                            'ip',
                            'route',
                            'del',
                            virt_address,
                        ])
                    except subprocess.CalledProcessError:
                        pass
                except KeyError:
                    pass

            if not host_address or host_address == \
                    settings.local.host.local_addr:
                return

            for i in xrange(3):
                try:
                    utils.check_output_logged([
                        'ip',
                        'route',
                        'add',
                        virt_address,
                        'via',
                        host_address,
                    ])
                    break
                except subprocess.CalledProcessError:
                    if i == 0:
                        try:
                            utils.check_call_silent([
                                'ip',
                                'route',
                                'del',
                                virt_address,
                            ])
                        except subprocess.CalledProcessError:
                            pass
                    elif i == 2:
                        raise
                    time.sleep(0.2)
        except:
            logger.exception(
                'Failed to add route',
                'clients',
                virt_address=virt_address,
                virt_address6=virt_address6,
                host_address=host_address,
                host_address6=host_address6,
            )
        finally:
            _route_lock.release()
Пример #28
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()
Пример #29
0
    def generate_iptables_rules(self):
        rules = []

        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 = {}
        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
            routes[line_split[0]] = line_split[7]

        if '0.0.0.0' not in routes:
            raise IptablesError('Failed to find default network interface', {
                'server_id': self.server.id,
            })
        default_interface = routes['0.0.0.0']

        rules.append(['INPUT', '-i', self.interface, '-j', 'ACCEPT'])
        rules.append(['FORWARD', '-i', self.interface, '-j', 'ACCEPT'])

        interfaces = set()
        for network_address in self.server.local_networks or ['0.0.0.0/0']:
            args_base = ['POSTROUTING', '-t', 'nat']
            network = utils.parse_network(network_address)[0]

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

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

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

            rules.append(args_base + ['-s', self.server.network])

            for link_svr in self.server.iter_links(fields=('_id', 'network')):
                rules.append(args_base + ['-s', link_svr.network])

        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',
            ])

        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]

        return rules
Пример #30
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
Пример #31
0
    def start(self):
        host_int_data = self.host_interface_data
        host_interface = host_int_data["interface"]
        host_address = host_int_data["address"]
        host_netmask = host_int_data["netmask"]
        host_broadcast = host_int_data["broadcast"]

        utils.check_output_logged(
            [
                "iptables",
                "-I",
                "FORWARD",
                "-i",
                self.bridge_interface,
                "-j",
                "ACCEPT",
                "-m",
                "comment",
                "--comment",
                "pritunl_%s" % settings.local.host_id,
            ]
            + ["--wait"]
            if settings.local.iptables_wait
            else []
        )
        utils.check_output_logged(
            [
                "iptables",
                "-I",
                "INPUT",
                "-i",
                self.bridge_interface,
                "-j",
                "ACCEPT",
                "-m",
                "comment",
                "--comment",
                "pritunl_%s" % settings.local.host_id,
            ]
            + ["--wait"]
            if settings.local.iptables_wait
            else []
        )
        utils.check_output_logged(["ip", "link", "set", "down", host_interface])
        utils.check_output_logged(["brctl", "addbr", self.bridge_interface])
        utils.check_output_logged(["brctl", "addif", self.bridge_interface, host_interface])
        utils.check_output_logged(["ifconfig", host_interface, "0.0.0.0", "promisc", "up"])
        utils.check_output_logged(
            ["ifconfig", self.bridge_interface, host_address, "netmask", host_netmask, "broadcast", host_broadcast]
        )
Пример #32
0
    def add_host(self, host_vxlan_id, vxlan_mac, host_dst, host_dst6):
        if settings.local.host.local_addr == host_dst:
            return

        self.running_lock.acquire()
        try:
            if not self.running:
                return

            for i in xrange(2):
                try:
                    if i == 0:
                        check_func = utils.check_output
                    else:
                        check_func = utils.check_output_logged

                    check_func([
                        'bridge',
                        'fdb',
                        'add',
                        vxlan_mac,
                        'dev',
                        self.iface_name,
                        'dst',
                        host_dst,
                    ],
                               ignore_states=['File exists'])

                    break
                except subprocess.CalledProcessError:
                    if i == 0:
                        utils.check_output_logged([
                            'bridge',
                            'fdb',
                            'del',
                            vxlan_mac,
                            'dev',
                            self.iface_name,
                        ])
                    else:
                        raise

            utils.check_output_logged([
                'arp',
                '-s',
                self.get_host_addr(host_vxlan_id),
                vxlan_mac,
            ])

            if host_dst6:
                for i in xrange(2):
                    try:
                        if i == 0:
                            check_func = utils.check_output
                        else:
                            check_func = utils.check_output_logged

                        check_func([
                            'ip',
                            '-6',
                            'neighbour',
                            'add',
                            self.get_host_addr6(host_vxlan_id),
                            'lladdr',
                            vxlan_mac,
                            'dev',
                            self.iface_name,
                        ],
                                   ignore_states=['File exists'])

                        break
                    except subprocess.CalledProcessError:
                        if i == 0:
                            utils.check_output_logged([
                                'ip',
                                '-6',
                                'neighbour',
                                'del',
                                self.get_host_addr6(host_vxlan_id),
                                'dev',
                                self.iface_name,
                            ])
                            for j in xrange(30):
                                try:
                                    utils.check_call_silent([
                                        'ip',
                                        '-6',
                                        'neighbour',
                                        'del',
                                        self.get_host_addr6(host_vxlan_id),
                                        'dev',
                                        self.iface_name,
                                    ])
                                except:
                                    break
                                time.sleep(0.5)
                        else:
                            raise
        except:
            logger.error(
                'Failed to add vxlan host',
                'vxlan',
                vxlan_id=self.vxlan_id,
                server_id=self.server_id,
            )
            raise
        finally:
            self.running_lock.release()
Пример #33
0
    def start(self):
        global _loaded

        local_iface = settings.local.host.local_iface

        if not _loaded:
            _loaded = True
            try:
                utils.check_call_silent([
                    'modprobe',
                    'vxlan',
                ])
            except subprocess.CalledProcessError:
                pass

        self.remove_iface()

        if not local_iface:
            logger.error(
                'Failed to find local interface for vxlan',
                'vxlan',
                vxlan_id=self.vxlan_id,
                server_id=self.server_id,
                host_id=settings.local.host_id,
                local_addr=settings.local.host.local_addr,
            )
            raise ValueError('Failed to find local interface for vxlan')

        utils.check_output_logged([
            'ip',
            'link',
            'add',
            self.iface_name,
            'type',
            'vxlan',
            'id',
            str(settings.vpn.vxlan_id_start + self.vxlan_id),
            'dstport',
            '4789',
            'dev',
            local_iface['interface'],
            'nolearning',
        ],
                                  ignore_states=['File exists'])

        self.vxlan_mac = utils.get_interface_mac_address(self.iface_name)
        self._init_host()
        self.vxlan_addr = self.get_host_addr(self.host_vxlan_id)
        if self.ipv6:
            self.vxlan_addr6 = utils.ip4to6x64(
                settings.vpn.ipv6_prefix,
                self.vxlan_net,
                self.vxlan_addr,
            )

        utils.check_output_logged([
            'ip',
            'address',
            'add',
            self.vxlan_addr + '/24',
            'dev',
            self.iface_name,
        ],
                                  ignore_states=['File exists'])

        if self.ipv6:
            utils.check_output_logged([
                'ip',
                '-6',
                'address',
                'add',
                self.vxlan_addr6 + '/64',
                'dev',
                self.iface_name,
            ],
                                      ignore_states=['File exists'])

        utils.check_output_logged([
            'ip',
            'link',
            'set',
            'up',
            self.iface_name,
        ])

        self._init_hosts()
Пример #34
0
    def stop(self):
        try:
            utils.check_output_logged(["ifconfig", self.bridge_interface, "down"])
        except subprocess.CalledProcessError:
            pass
        try:
            utils.check_output_logged(["brctl", "delbr", self.bridge_interface])
        except subprocess.CalledProcessError:
            pass
        try:
            utils.check_output_logged(
                [
                    "iptables",
                    "-D",
                    "INPUT",
                    "-i",
                    self.bridge_interface,
                    "-j",
                    "ACCEPT",
                    "-m",
                    "comment",
                    "--comment",
                    "pritunl_%s" % settings.local.host_id,
                ]
                + ["--wait"]
                if settings.local.iptables_wait
                else []
            )
        except subprocess.CalledProcessError:
            pass
        try:
            utils.check_output_logged(
                [
                    "iptables",
                    "-D",
                    "FORWARD",
                    "-i",
                    self.bridge_interface,
                    "-j",
                    "ACCEPT",
                    "-m",
                    "comment",
                    "--comment",
                    "pritunl_%s" % settings.local.host_id,
                ]
                + ["--wait"]
                if settings.local.iptables_wait
                else []
            )
        except subprocess.CalledProcessError:
            pass

        host_int_data = self.host_interface_data
        host_interface = host_int_data["interface"]
        host_address = host_int_data["address"]
        host_netmask = host_int_data["netmask"]
        host_broadcast = host_int_data["broadcast"]

        utils.check_output_logged(["ip", "link", "set", "down", host_interface])

        utils.check_output_logged(["ip", "link", "set", "up", host_interface])

        utils.check_output_logged(
            ["ifconfig", host_interface, host_address, "netmask", host_netmask, "broadcast", host_broadcast]
        )
Пример #35
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()
Пример #36
0
    def start(self):
        global _loaded

        local_iface = settings.local.host.local_iface

        if not _loaded:
            _loaded = True
            try:
                utils.check_call_silent([
                    'modprobe',
                    'vxlan',
                ])
            except subprocess.CalledProcessError:
                pass

        self.remove_iface()

        if not local_iface:
            logger.error('Failed to find local interface for vxlan', 'vxlan',
                vxlan_id=self.vxlan_id,
                server_id=self.server_id,
                host_id=settings.local.host_id,
                local_addr=settings.local.host.local_addr,
            )
            raise ValueError('Failed to find local interface for vxlan')

        utils.check_output_logged([
            'ip',
            'link',
            'add',
            self.iface_name,
            'type',
            'vxlan',
            'id',
            str(settings.vpn.vxlan_id_start + self.vxlan_id),
            'dstport',
            '4789',
            'dev',
            local_iface['interface'],
            'nolearning',
        ], ignore_states=['File exists'])

        self.vxlan_mac = utils.get_interface_mac_address(self.iface_name)
        self._init_host()
        self.vxlan_addr = self.get_host_addr(self.host_vxlan_id)
        if self.ipv6:
            self.vxlan_addr6 = utils.ip4to6x64(
                settings.vpn.ipv6_prefix,
                self.vxlan_net,
                self.vxlan_addr,
            )

        utils.check_output_logged([
            'ip',
            'address',
            'add',
            self.vxlan_addr + '/24',
            'dev',
            self.iface_name,
        ], ignore_states=['File exists'])

        if self.ipv6:
            utils.check_output_logged([
                'ip',
                '-6',
                'address',
                'add',
                self.vxlan_addr6 + '/64',
                'dev',
                self.iface_name,
            ], ignore_states=['File exists'])

        utils.check_output_logged([
            'ip',
            'link',
            'set',
            'up',
            self.iface_name,
        ])

        self._init_hosts()
Пример #37
0
    def stop(self):
        try:
            utils.check_output_logged([
                'ip',
                'link',
                'set',
                'down',
                self.bridge_interface,
            ])
        except subprocess.CalledProcessError:
            pass
        try:
            utils.check_output_logged([
                'brctl',
                'delbr',
                self.bridge_interface,
            ])
        except subprocess.CalledProcessError:
            pass
        try:
            utils.check_output_logged([
                'iptables',
                '-D',
                'INPUT',
                '-i',
                self.bridge_interface,
                '-j',
                'ACCEPT',
                '-m',
                'comment',
                '--comment',
                'pritunl-%s' % settings.local.host_id,
            ])
        except subprocess.CalledProcessError:
            pass
        try:
            utils.check_output_logged([
                'iptables',
                '-D',
                'FORWARD',
                '-i',
                self.bridge_interface,
                '-j',
                'ACCEPT',
                '-m',
                'comment',
                '--comment',
                'pritunl-%s' % settings.local.host_id,
            ])
        except subprocess.CalledProcessError:
            pass

        host_int_data = self.host_interface_data
        host_interface = host_int_data['interface']
        host_address = host_int_data['address']
        host_netmask = host_int_data['netmask']
        host_broadcast = host_int_data['broadcast']
        host_gateway = host_int_data['gateway']

        utils.check_output_logged([
            'ip',
            'link',
            'set',
            'down',
            host_interface,
        ])

        utils.check_output_logged([
            'ip',
            'link',
            'set',
            'up',
            host_interface,
        ])

        utils.check_output_logged([
            'ifconfig',
            host_interface,
            host_address,
            'netmask',
            host_netmask,
            'broadcast',
            host_broadcast,
        ])
        if host_gateway:
            try:
                utils.check_output_logged([
                    'route',
                    'add',
                    'default',
                    'gw',
                    host_gateway,
                ])
            except subprocess.CalledProcessError:
                pass
Пример #38
0
    def start(self):
        host_int_data = self.host_interface_data
        host_interface = host_int_data['interface']
        host_address = host_int_data['address']
        host_netmask = host_int_data['netmask']
        host_broadcast = host_int_data['broadcast']
        host_gateway = host_int_data['gateway']

        utils.check_output_logged([
            'iptables',
            '-I',
            'FORWARD',
            '-i',
            self.bridge_interface,
            '-j',
            'ACCEPT',
            '-m', 'comment',
            '--comment', 'pritunl_%s' % settings.local.host_id,
        ] + ['--wait'] if settings.local.iptables_wait else [])
        utils.check_output_logged([
            'iptables',
            '-I',
            'INPUT',
            '-i',
            self.bridge_interface,
            '-j',
            'ACCEPT',
            '-m', 'comment',
            '--comment', 'pritunl_%s' % settings.local.host_id,
        ] + ['--wait'] if settings.local.iptables_wait else [])
        utils.check_output_logged([
            'ip',
            'link',
            'set',
            'down',
            host_interface,
        ])
        utils.check_output_logged([
            'brctl',
            'addbr',
            self.bridge_interface,
        ])
        utils.check_output_logged([
            'brctl',
            'addif',
            self.bridge_interface,
            host_interface,
        ])
        utils.check_output_logged([
            'ifconfig',
            host_interface,
            '0.0.0.0',
            'promisc',
            'up',
        ])
        utils.check_output_logged([
            'ifconfig',
            self.bridge_interface,
            host_address,
            'netmask',
            host_netmask,
            'broadcast',
            host_broadcast,
        ])

        if host_gateway:
            utils.check_output_logged([
                'route',
                'add',
                'default',
                'gw',
                host_gateway,
            ])
Пример #39
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 = {}
        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:
                routes[line_split[0]] = line_split[7]

        if '0.0.0.0' not in routes:
            raise IptablesError('Failed to find default network interface')
        default_interface = routes['0.0.0.0']

        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:
                    ipaddress.IPv6Network(line_split[0])
                except (ipaddress.AddressValueError, ValueError):
                    continue

                if line_split[0] not in routes6:
                    routes6[line_split[0]] = line_split[6]

            if '::/0' not in routes6:
                raise IptablesError(
                    'Failed to find default IPv6 network interface')
            default_interface6 = routes6['::/0']

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

        rules.append(['INPUT', '-i', 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, '-j', 'DROP'])
                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(
                    ['FORWARD', '-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'])
            else:
                rules6.append(
                    ['INPUT', '-d', self.server.network6, '-j', 'ACCEPT'])
                rules6.append(
                    ['FORWARD', '-d', self.server.network6, '-j', 'ACCEPT'])

        interfaces = set()
        interfaces6 = set()
        other_networks = []
        if self.server.mode == ALL_TRAFFIC and \
                self.server.network_mode != BRIDGE:
            other_networks = ['0.0.0.0/0']
            if self.server.ipv6 and not settings.local.host.routed_subnet6:
                other_networks.append('::/0')

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

        if settings.vpn.nat_routes:
            for network_address in self.server.local_networks or \
                    other_networks:
                args_base = ['POSTROUTING', '-t', 'nat']
                is6 = ':' in network_address
                if is6:
                    network = network_address
                else:
                    network = utils.parse_network(network_address)[0]

                if is6:
                    if network not in routes6:
                        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
                    else:
                        interface = routes6[network]
                    interfaces6.add(interface)
                else:
                    if network not in routes:
                        logger.info(
                            'Failed to find interface for local ' + \
                            'network route, using default route',
                            'server',
                            server_id=self.server.id,
                            network=network,
                        )
                        interface = default_interface
                    else:
                        interface = routes[network]
                    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])

        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
Пример #40
0
    def build_onc(self):
        temp_path = utils.get_temp_path()

        try:
            os.makedirs(temp_path)

            user_cert_path = os.path.join(temp_path, '%s.crt' % self.id)
            user_key_path = os.path.join(temp_path, '%s.key' % self.id)
            user_p12_path = os.path.join(temp_path, '%s.p12' % self.id)

            with open(user_cert_path, 'w') as user_cert:
                user_cert.write(self.certificate)

            with open(user_key_path, 'w') as user_key:
                os.chmod(user_key_path, 0600)
                user_key.write(self.private_key)

            utils.check_output_logged([
                'openssl',
                'pkcs12',
                '-export',
                '-nodes',
                '-password', 'pass:'******'-inkey', user_key_path,
                '-in', user_cert_path,
                '-out', user_p12_path,
            ])

            with open(user_p12_path, 'r') as user_key_p12:
                user_key_base64 = base64.b64encode(user_key_p12.read())
                user_cert_id = '{%s}' % hashlib.md5(
                    user_key_base64).hexdigest()

            os.remove(user_cert_path)
            os.remove(user_key_path)
            os.remove(user_p12_path)

            onc_nets = ''
            onc_certs_store = {}

            for svr in self.iter_servers():
                onc_net, onc_certs = self._generate_onc(
                    svr, user_cert_id)
                if not onc_net:
                    continue
                onc_certs_store.update(onc_certs)

                onc_nets += onc_net + ',\n'
            onc_nets = onc_nets[:-2]

            if onc_nets == '':
                return None

            onc_certs = ''
            for cert_id, cert in onc_certs_store.items():
                onc_certs += OVPN_ONC_CA_CERT % (cert_id, cert) + ',\n'
            onc_certs += OVPN_ONC_CLIENT_CERT % (
                user_cert_id, user_key_base64)

            onc_conf = OVPN_ONC_CLIENT_CONF % (onc_nets, onc_certs)
        finally:
            utils.rmtree(temp_path)

        return onc_conf
Пример #41
0
    def bridge_start(self):
        if self.server.network_mode != BRIDGE:
            return

        host_int_data = self.host_interface_data
        host_interface = host_int_data['interface']
        host_address = host_int_data['address']
        host_netmask = host_int_data['netmask']
        host_broadcast = host_int_data['broadcast']

        utils.check_output_logged([
            'ip',
            'link',
            'set',
            'down',
            host_interface,
        ])
        utils.check_output_logged([
            'openvpn',
            '--mktun',
            '--dev',
            self.interface,
        ])
        utils.check_output_logged([
            'brctl',
            'addbr',
            self.bridge_interface,
        ])
        utils.check_output_logged([
            'brctl',
            'addif',
            self.bridge_interface,
            host_interface,
        ])
        utils.check_output_logged([
            'brctl',
            'addif',
            self.bridge_interface,
            self.interface,
        ])
        utils.check_output_logged([
            'ifconfig',
            self.interface,
            '0.0.0.0',
            'promisc',
            'up',
        ])
        utils.check_output_logged([
            'ifconfig',
            host_interface,
            '0.0.0.0',
            'promisc',
            'up',
        ])
        utils.check_output_logged([
            'ifconfig',
            self.bridge_interface,
            host_address,
            'netmask',
            host_netmask,
            'broadcast',
            host_broadcast,
        ])
Пример #42
0
    def add_host(self, host_vxlan_id, vxlan_mac, host_dst, host_dst6):
        if settings.local.host.local_addr == host_dst:
            return

        self.running_lock.acquire()
        try:
            if not self.running:
                return

            for i in xrange(2):
                try:
                    if i == 0:
                        check_func = utils.check_output
                    else:
                        check_func = utils.check_output_logged

                    check_func([
                        'bridge',
                        'fdb',
                        'add',
                        vxlan_mac,
                        'dev',
                        self.iface_name,
                        'dst',
                        host_dst,
                    ], ignore_states=['File exists'])

                    break
                except subprocess.CalledProcessError:
                    if i == 0:
                        utils.check_output_logged([
                            'bridge',
                            'fdb',
                            'del',
                            vxlan_mac,
                            'dev',
                            self.iface_name,
                        ])
                    else:
                        raise

            utils.check_output_logged([
                'arp',
                '-s',
                self.get_host_addr(host_vxlan_id),
                vxlan_mac,
            ])

            if host_dst6:
                for i in xrange(2):
                    try:
                        if i == 0:
                            check_func = utils.check_output
                        else:
                            check_func = utils.check_output_logged

                        check_func([
                            'ip',
                            '-6',
                            'neighbour',
                            'add',
                            self.get_host_addr6(host_vxlan_id),
                            'lladdr',
                            vxlan_mac,
                            'dev',
                            self.iface_name,
                        ], ignore_states=['File exists'])

                        break
                    except subprocess.CalledProcessError:
                        if i == 0:
                            utils.check_output_logged([
                                'ip',
                                '-6',
                                'neighbour',
                                'del',
                                self.get_host_addr6(host_vxlan_id),
                                'dev',
                                self.iface_name,
                            ])
                            for j in xrange(30):
                                try:
                                    utils.check_call_silent([
                                        'ip',
                                        '-6',
                                        'neighbour',
                                        'del',
                                        self.get_host_addr6(host_vxlan_id),
                                        'dev',
                                        self.iface_name,
                                    ])
                                except:
                                    break
                                time.sleep(0.5)
                        else:
                            raise
        except:
            logger.error('Failed to add vxlan host', 'vxlan',
                vxlan_id=self.vxlan_id,
                server_id=self.server_id,
            )
            raise
        finally:
            self.running_lock.release()
Пример #43
0
    def generate_iptables_rules(self):
        rules = []

        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 = {}
        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
            routes[line_split[0]] = line_split[7]

        if '0.0.0.0' not in routes:
            raise IptablesError('Failed to find default network interface', {
                'server_id': self.server.id,
            })
        default_interface = routes['0.0.0.0']

        rules.append(['INPUT', '-i', self.interface, '-j', 'ACCEPT'])
        rules.append(['FORWARD', '-i', self.interface, '-j', 'ACCEPT'])

        interfaces = set()
        for network_address in self.server.local_networks or ['0.0.0.0/0']:
            args_base = ['POSTROUTING', '-t', 'nat']
            network = utils.parse_network(network_address)[0]

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

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

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

            rules.append(args_base + ['-s', self.server.network])

            for link_svr in self.server.iter_links(fields=('_id', 'network')):
                rules.append(args_base + ['-s', link_svr.network])

        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',
            ])

        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]

        return rules
Пример #44
0
    def build_onc_archive(self):
        temp_path = utils.get_temp_path()
        key_archive_path = os.path.join(temp_path, "%s.zip" % self.id)

        try:
            os.makedirs(temp_path)
            zip_file = zipfile.ZipFile(key_archive_path, "w")
            try:
                user_cert_path = os.path.join(temp_path, "%s.crt" % self.id)
                user_key_path = os.path.join(temp_path, "%s.key" % self.id)
                user_p12_path = os.path.join(temp_path, "%s.p12" % self.id)

                with open(user_cert_path, "w") as user_cert:
                    user_cert.write(self.certificate)

                with open(user_key_path, "w") as user_key:
                    os.chmod(user_key_path, 0600)
                    user_key.write(self.private_key)

                utils.check_output_logged(
                    [
                        "openssl",
                        "pkcs12",
                        "-export",
                        "-nodes",
                        "-password",
                        "pass:"******"-inkey",
                        user_key_path,
                        "-in",
                        user_cert_path,
                        "-out",
                        user_p12_path,
                    ]
                )

                zip_file.write(user_p12_path, arcname="%s.p12" % self.name)

                os.remove(user_cert_path)
                os.remove(user_key_path)
                os.remove(user_p12_path)

                for svr in self.org.iter_servers():
                    server_conf_path = os.path.join(temp_path, "%s_%s.onc" % (self.id, svr.id))
                    conf_name, client_conf = self._generate_onc(svr)
                    if not client_conf:
                        continue

                    with open(server_conf_path, "w") as ovpn_conf:
                        ovpn_conf.write(client_conf)
                    zip_file.write(server_conf_path, arcname=conf_name)
                    os.remove(server_conf_path)
            finally:
                zip_file.close()

            with open(key_archive_path, "r") as archive_file:
                key_archive = archive_file.read()
        finally:
            utils.rmtree(temp_path)

        return key_archive
Пример #45
0
    def build_onc(self):
        temp_path = utils.get_temp_path()

        try:
            os.makedirs(temp_path)

            user_cert_path = os.path.join(temp_path, '%s.crt' % self.id)
            user_key_path = os.path.join(temp_path, '%s.key' % self.id)
            user_p12_path = os.path.join(temp_path, '%s.p12' % self.id)

            with open(user_cert_path, 'w') as user_cert:
                user_cert.write(self.certificate)

            with open(user_key_path, 'w') as user_key:
                os.chmod(user_key_path, 0600)
                user_key.write(self.private_key)

            utils.check_output_logged([
                'openssl',
                'pkcs12',
                '-export',
                '-nodes',
                '-password',
                'pass:'******'-inkey',
                user_key_path,
                '-in',
                user_cert_path,
                '-out',
                user_p12_path,
            ])

            with open(user_p12_path, 'r') as user_key_p12:
                user_key_base64 = base64.b64encode(user_key_p12.read())
                user_cert_id = '{%s}' % hashlib.md5(
                    user_key_base64).hexdigest()

            os.remove(user_cert_path)
            os.remove(user_key_path)
            os.remove(user_p12_path)

            onc_nets = ''
            onc_certs_store = {}

            for svr in self.iter_servers():
                onc_net, onc_certs = self._generate_onc(svr, user_cert_id)
                if not onc_net:
                    continue
                onc_certs_store.update(onc_certs)

                onc_nets += onc_net + ',\n'
            onc_nets = onc_nets[:-2]

            if onc_nets == '':
                return None

            onc_certs = ''
            for cert_id, cert in onc_certs_store.items():
                onc_certs += OVPN_ONC_CA_CERT % (cert_id, cert) + ',\n'
            onc_certs += OVPN_ONC_CLIENT_CERT % (user_cert_id, user_key_base64)

            onc_conf = OVPN_ONC_CLIENT_CONF % (onc_nets, onc_certs)
        finally:
            utils.rmtree(temp_path)

        return onc_conf
Пример #46
0
    def start(self):
        host_int_data = self.host_interface_data
        host_interface = host_int_data['interface']
        host_address = host_int_data['address']
        host_netmask = host_int_data['netmask']
        host_broadcast = host_int_data['broadcast']
        host_gateway = host_int_data['gateway']

        utils.check_output_logged([
            'iptables',
            '-I',
            'FORWARD',
            '-i',
            self.bridge_interface,
            '-j',
            'ACCEPT',
            '-m',
            'comment',
            '--comment',
            'pritunl-%s' % settings.local.host_id,
        ])
        utils.check_output_logged([
            'iptables',
            '-I',
            'INPUT',
            '-i',
            self.bridge_interface,
            '-j',
            'ACCEPT',
            '-m',
            'comment',
            '--comment',
            'pritunl-%s' % settings.local.host_id,
        ])
        utils.check_output_logged([
            'ip',
            'link',
            'set',
            'down',
            host_interface,
        ])
        utils.check_output_logged([
            'brctl',
            'addbr',
            self.bridge_interface,
        ])
        utils.check_output_logged([
            'brctl',
            'addif',
            self.bridge_interface,
            host_interface,
        ])
        utils.check_output_logged([
            'ifconfig',
            host_interface,
            '0.0.0.0',
            'promisc',
            'up',
        ])
        utils.check_output_logged([
            'ifconfig',
            self.bridge_interface,
            host_address,
            'netmask',
            host_netmask,
            'broadcast',
            host_broadcast,
        ])

        if host_gateway:
            utils.check_output_logged([
                'route',
                'add',
                'default',
                'gw',
                host_gateway,
            ])