Ejemplo n.º 1
0
def user_post(org_id):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    org = organization.get_by_id(org_id)
    users = []

    if isinstance(flask.request.json, list):
        users_data = flask.request.json
    else:
        users_data = [flask.request.json]

    try:
        for user_data in users_data:
            name = utils.filter_str(user_data['name'])
            email = utils.filter_str(user_data.get('email'))
            pin = utils.filter_str(user_data.get('pin')) or None
            disabled = user_data.get('disabled')
            network_links = user_data.get('network_links')
            bypass_secondary = user_data.get('bypass_secondary')
            dns_servers = user_data.get('dns_servers') or None
            dns_suffix = utils.filter_str(user_data.get('dns_suffix')) or None
            port_forwarding_in = user_data.get('port_forwarding')
            port_forwarding = []

            if pin:
                if not pin.isdigit():
                    return utils.jsonify(
                        {
                            'error': PIN_NOT_DIGITS,
                            'error_msg': PIN_NOT_DIGITS_MSG,
                        }, 400)

                if len(pin) < settings.user.pin_min_length:
                    return utils.jsonify(
                        {
                            'error': PIN_TOO_SHORT,
                            'error_msg': PIN_TOO_SHORT_MSG,
                        }, 400)

                pin = auth.generate_hash_pin_v2(pin)

            if port_forwarding_in:
                for data in port_forwarding_in:
                    port_forwarding.append({
                        'protocol':
                        utils.filter_str(data.get('protocol')),
                        'port':
                        utils.filter_str(data.get('port')),
                        'dport':
                        utils.filter_str(data.get('dport')),
                    })

            user = org.new_user(type=CERT_CLIENT,
                                name=name,
                                email=email,
                                pin=pin,
                                disabled=disabled,
                                bypass_secondary=bypass_secondary,
                                dns_servers=dns_servers,
                                dns_suffix=dns_suffix,
                                port_forwarding=port_forwarding)
            user.audit_event(
                'user_created',
                'User created from web console',
                remote_addr=utils.get_remote_addr(),
            )

            if network_links:
                for network_link in network_links:
                    try:
                        user.add_network_link(network_link)
                    except (ipaddress.AddressValueError, ValueError):
                        return _network_link_invalid()
                    except ServerOnlineError:
                        return utils.jsonify(
                            {
                                'error': NETWORK_LINK_NOT_OFFLINE,
                                'error_msg': NETWORK_LINK_NOT_OFFLINE_MSG,
                            }, 400)

            users.append(user.dict())
    finally:
        event.Event(type=ORGS_UPDATED)
        event.Event(type=USERS_UPDATED, resource_id=org.id)
        event.Event(type=SERVERS_UPDATED)

    if isinstance(flask.request.json, list):
        logger.LogEntry(message='Created %s new users.' %
                        len(flask.request.json))
        return utils.jsonify(users)
    else:
        logger.LogEntry(message='Created new user "%s".' % users[0]['name'])
        return utils.jsonify(users[0])
Ejemplo n.º 2
0
def user_put(org_id, user_id):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    org = organization.get_by_id(org_id)
    user = org.get_user(user_id)
    reset_user = False
    port_forwarding_event = False

    if 'name' in flask.request.json:
        name = utils.filter_str(flask.request.json['name']) or None

        if name != user.name:
            user.audit_event(
                'user_updated',
                'User name changed',
                remote_addr=utils.get_remote_addr(),
            )

        user.name = name

    if 'email' in flask.request.json:
        email = utils.filter_str(flask.request.json['email']) or None

        if email != user.email:
            user.audit_event(
                'user_updated',
                'User email changed',
                remote_addr=utils.get_remote_addr(),
            )

        user.email = email

    if 'pin' in flask.request.json:
        pin = flask.request.json['pin']

        if pin != True:
            if pin:
                if settings.user.pin_mode == PIN_DISABLED:
                    return utils.jsonify(
                        {
                            'error': PIN_IS_DISABLED,
                            'error_msg': PIN_IS_DISABLED_MSG,
                        }, 400)

                if RADIUS_AUTH in user.auth_type:
                    return utils.jsonify(
                        {
                            'error': PIN_RADIUS,
                            'error_msg': PIN_RADIUS_MSG,
                        }, 400)

                if not pin.isdigit():
                    return utils.jsonify(
                        {
                            'error': PIN_NOT_DIGITS,
                            'error_msg': PIN_NOT_DIGITS_MSG,
                        }, 400)

                if len(pin) < settings.user.pin_min_length:
                    return utils.jsonify(
                        {
                            'error': PIN_TOO_SHORT,
                            'error_msg': PIN_TOO_SHORT_MSG,
                        }, 400)

            if user.set_pin(pin):
                user.audit_event(
                    'user_updated',
                    'User pin changed',
                    remote_addr=utils.get_remote_addr(),
                )

    if 'network_links' in flask.request.json:
        network_links_cur = set(user.get_network_links())
        network_links_new = set()

        for network_link in flask.request.json['network_links']:
            try:
                network_link = str(ipaddress.IPNetwork(network_link))
            except (ipaddress.AddressValueError, ValueError):
                return _network_link_invalid()
            network_links_new.add(network_link)

        network_links_add = network_links_new - network_links_cur
        network_links_rem = network_links_cur - network_links_new

        if len(network_links_add) or len(network_links_rem):
            reset_user = True
            user.audit_event(
                'user_updated',
                'User network links updated',
                remote_addr=utils.get_remote_addr(),
            )

        try:
            for network_link in network_links_add:
                user.add_network_link(network_link)
        except ServerOnlineError:
            return utils.jsonify(
                {
                    'error': NETWORK_LINK_NOT_OFFLINE,
                    'error_msg': NETWORK_LINK_NOT_OFFLINE_MSG,
                }, 400)

        for network_link in network_links_rem:
            user.remove_network_link(network_link)

    if 'port_forwarding' in flask.request.json:
        port_forwarding = []
        for data in flask.request.json['port_forwarding'] or []:
            port_forwarding.append({
                'protocol':
                utils.filter_str(data.get('protocol')),
                'port':
                utils.filter_str(data.get('port')),
                'dport':
                utils.filter_str(data.get('dport')),
            })

        if port_forwarding != user.port_forwarding:
            port_forwarding_event = True
            user.audit_event(
                'user_updated',
                'User port forwarding changed',
                remote_addr=utils.get_remote_addr(),
            )

        user.port_forwarding = port_forwarding

    disabled = flask.request.json.get('disabled')
    if disabled is not None:
        if disabled != user.disabled:
            user.audit_event(
                'user_updated',
                'User %s' % ('disabled' if disabled else 'enabled'),
                remote_addr=utils.get_remote_addr(),
            )

        user.disabled = disabled

    bypass_secondary = flask.request.json.get('bypass_secondary')
    if bypass_secondary is not None:
        user.bypass_secondary = bypass_secondary

    if 'dns_servers' in flask.request.json:
        dns_servers = flask.request.json['dns_servers'] or None
        if user.dns_servers != dns_servers:
            user.audit_event(
                'user_updated',
                'User dns servers changed',
                remote_addr=utils.get_remote_addr(),
            )
            reset_user = True
        user.dns_servers = dns_servers

    if 'dns_suffix' in flask.request.json:
        dns_suffix = utils.filter_str(flask.request.json['dns_suffix']) or None
        if user.dns_suffix != dns_suffix:
            user.audit_event(
                'user_updated',
                'User dns suffix changed',
                remote_addr=utils.get_remote_addr(),
            )
            reset_user = True
        user.dns_suffix = dns_suffix

    user.commit()
    event.Event(type=USERS_UPDATED, resource_id=user.org.id)
    if port_forwarding_event:
        messenger.publish('port_forwarding', {
            'org_id': org.id,
            'user_id': user.id,
        })

    if reset_user or disabled:
        user.disconnect()

    if disabled:
        if user.type == CERT_CLIENT:
            logger.LogEntry(message='Disabled user "%s".' % user.name)
    elif disabled == False and user.type == CERT_CLIENT:
        logger.LogEntry(message='Enabled user "%s".' % user.name)

    send_key_email = flask.request.json.get('send_key_email')
    if send_key_email and user.email:
        user.audit_event(
            'user_emailed',
            'User key email sent to "%s"' % user.email,
            remote_addr=utils.get_remote_addr(),
        )

        try:
            user.send_key_email(flask.request.url_root[:-1])
        except EmailNotConfiguredError:
            return utils.jsonify(
                {
                    'error': EMAIL_NOT_CONFIGURED,
                    'error_msg': EMAIL_NOT_CONFIGURED_MSG,
                }, 400)
        except EmailFromInvalid:
            return utils.jsonify(
                {
                    'error': EMAIL_FROM_INVALID,
                    'error_msg': EMAIL_FROM_INVALID_MSG,
                }, 400)
        except EmailAuthInvalid:
            return utils.jsonify(
                {
                    'error': EMAIL_AUTH_INVALID,
                    'error_msg': EMAIL_AUTH_INVALID_MSG,
                }, 400)

    return utils.jsonify(user.dict())
Ejemplo n.º 3
0
def server_put_post(server_id=None):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    used_resources = server.get_used_resources(server_id)
    network_used = used_resources['networks']
    port_used = used_resources['ports']

    name = None
    name_def = False
    if 'name' in flask.request.json:
        name_def = True
        name = utils.filter_str(flask.request.json['name'])

    network = None
    network_def = False
    if 'network' in flask.request.json:
        network_def = True
        network = flask.request.json['network']

        try:
            if not _check_network_private(network):
                return _network_invalid()
        except (ipaddress.AddressValueError, ValueError):
            return _network_invalid()

    network_mode = None
    network_mode_def = False
    if 'network_mode' in flask.request.json:
        network_mode_def = True
        network_mode = flask.request.json['network_mode']

    network_start = None
    network_start_def = False
    if 'network_start' in flask.request.json:
        network_start_def = True
        network_start = flask.request.json['network_start']

    network_end = None
    network_end_def = False
    if 'network_end' in flask.request.json:
        network_end_def = True
        network_end = flask.request.json['network_end']

    restrict_routes = None
    restrict_routes_def = False
    if 'restrict_routes' in flask.request.json:
        restrict_routes_def = True
        restrict_routes = True if flask.request.json['restrict_routes'] \
            else False

    ipv6 = None
    ipv6_def = False
    if 'ipv6' in flask.request.json:
        ipv6_def = True
        ipv6 = True if flask.request.json['ipv6'] else False

    ipv6_firewall = None
    ipv6_firewall_def = False
    if 'ipv6_firewall' in flask.request.json:
        ipv6_firewall_def = True
        ipv6_firewall = True if flask.request.json['ipv6_firewall'] else False

    bind_address = None
    bind_address_def = False
    if 'bind_address' in flask.request.json:
        bind_address_def = True
        bind_address = utils.filter_str(flask.request.json['bind_address'])

    protocol = 'udp'
    protocol_def = False
    if 'protocol' in flask.request.json:
        protocol_def = True
        protocol = flask.request.json['protocol'].lower()

        if protocol not in ('udp', 'tcp'):
            return utils.jsonify(
                {
                    'error': PROTOCOL_INVALID,
                    'error_msg': PROTOCOL_INVALID_MSG,
                }, 400)

    port = None
    port_def = False
    if 'port' in flask.request.json:
        port_def = True
        port = flask.request.json['port']

        try:
            port = int(port)
        except ValueError:
            return _port_invalid()

        if port < 1 or port > 65535:
            return _port_invalid()

    dh_param_bits = None
    dh_param_bits_def = False
    if flask.request.json.get('dh_param_bits'):
        dh_param_bits_def = True
        dh_param_bits = flask.request.json['dh_param_bits']

        try:
            dh_param_bits = int(dh_param_bits)
        except ValueError:
            return _dh_param_bits_invalid()

        if dh_param_bits not in VALID_DH_PARAM_BITS:
            return _dh_param_bits_invalid()

    multi_device = False
    multi_device_def = False
    if 'multi_device' in flask.request.json:
        multi_device_def = True
        multi_device = True if flask.request.json['multi_device'] else False

    dns_servers = None
    dns_servers_def = False
    if 'dns_servers' in flask.request.json:
        dns_servers_def = True
        dns_servers = flask.request.json['dns_servers'] or []

        for dns_server in dns_servers:
            try:
                ipaddress.IPAddress(dns_server)
            except (ipaddress.AddressValueError, ValueError):
                return _dns_server_invalid()

    search_domain = None
    search_domain_def = False
    if 'search_domain' in flask.request.json:
        search_domain_def = True
        search_domain = utils.filter_str(flask.request.json['search_domain'])

    inter_client = True
    inter_client_def = False
    if 'inter_client' in flask.request.json:
        inter_client_def = True
        inter_client = True if flask.request.json['inter_client'] else False

    ping_interval = None
    ping_interval_def = False
    if 'ping_interval' in flask.request.json:
        ping_interval_def = True
        ping_interval = flask.request.json['ping_interval']
        if ping_interval:
            ping_interval = int(ping_interval)
        if not ping_interval:
            ping_interval = 10

    ping_timeout = None
    ping_timeout_def = False
    if 'ping_timeout' in flask.request.json:
        ping_timeout_def = True
        ping_timeout = flask.request.json['ping_timeout']
        if ping_timeout:
            ping_timeout = int(ping_timeout)
        if not ping_timeout:
            ping_timeout = 60

    link_ping_interval = None
    link_ping_interval_def = False
    if 'link_ping_interval' in flask.request.json:
        link_ping_interval_def = True
        link_ping_interval = flask.request.json['link_ping_interval']
        if link_ping_interval:
            link_ping_interval = int(link_ping_interval)
        if not link_ping_interval:
            link_ping_interval = 1

    link_ping_timeout = None
    link_ping_timeout_def = False
    if 'link_ping_timeout' in flask.request.json:
        link_ping_timeout_def = True
        link_ping_timeout = flask.request.json['link_ping_timeout']
        if link_ping_timeout:
            link_ping_timeout = int(link_ping_timeout)
        if not link_ping_timeout:
            link_ping_timeout = 5

    max_clients = None
    max_clients_def = False
    if 'max_clients' in flask.request.json:
        max_clients_def = True
        max_clients = flask.request.json['max_clients']
        if max_clients:
            max_clients = int(max_clients)
        if not max_clients:
            max_clients = 4096

    replica_count = None
    replica_count_def = False
    if 'replica_count' in flask.request.json:
        replica_count_def = True
        replica_count = flask.request.json['replica_count']
        if replica_count:
            replica_count = int(replica_count)
        if not replica_count:
            replica_count = 1

    dns_mapping = False
    dns_mapping_def = False
    if 'dns_mapping' in flask.request.json:
        dns_mapping_def = True
        dns_mapping = True if flask.request.json['dns_mapping'] else False

    debug = False
    debug_def = False
    if 'debug' in flask.request.json:
        debug_def = True
        debug = True if flask.request.json['debug'] else False

    otp_auth = False
    otp_auth_def = False
    if 'otp_auth' in flask.request.json:
        otp_auth_def = True
        otp_auth = True if flask.request.json['otp_auth'] else False

    lzo_compression = False
    lzo_compression_def = False
    if 'lzo_compression' in flask.request.json:
        lzo_compression_def = True
        lzo_compression = True if flask.request.json[
            'lzo_compression'] else False

    cipher = None
    cipher_def = False
    if 'cipher' in flask.request.json:
        cipher_def = True
        cipher = flask.request.json['cipher']

        if cipher not in CIPHERS:
            return utils.jsonify(
                {
                    'error': CIPHER_INVALID,
                    'error_msg': CIPHER_INVALID_MSG,
                }, 400)

    hash = None
    hash_def = False
    if 'hash' in flask.request.json:
        hash_def = True
        hash = flask.request.json['hash']

        if hash not in HASHES:
            return utils.jsonify(
                {
                    'error': HASH_INVALID,
                    'error_msg': HASH_INVALID_MSG,
                }, 400)

    jumbo_frames = False
    jumbo_frames_def = False
    if 'jumbo_frames' in flask.request.json:
        jumbo_frames_def = True
        jumbo_frames = True if flask.request.json['jumbo_frames'] else False

    if not server_id:
        if not name_def:
            return utils.jsonify(
                {
                    'error': MISSING_PARAMS,
                    'error_msg': MISSING_PARAMS_MSG,
                }, 400)

        if network_def and network_mode == BRIDGE and \
                (not network_start or not network_end):
            return utils.jsonify(
                {
                    'error': MISSING_PARAMS,
                    'error_msg': MISSING_PARAMS_MSG,
                }, 400)

        if not network_def:
            network_def = True
            rand_range = range(215, 250)
            rand_range_low = range(15, 215)
            random.shuffle(rand_range)
            random.shuffle(rand_range_low)
            rand_range += rand_range_low
            for i in rand_range:
                rand_network = '192.168.%s.0/24' % i
                if not _check_network_overlap(rand_network, network_used):
                    network = rand_network
                    break
            if not network:
                return utils.jsonify(
                    {
                        'error': NETWORK_IN_USE,
                        'error_msg': NETWORK_IN_USE_MSG,
                    }, 400)

        if not port_def:
            port_def = True
            rand_ports = range(10000, 19999)
            random.shuffle(rand_ports)
            for rand_port in rand_ports:
                if '%s%s' % (rand_port, protocol) not in port_used:
                    port = rand_port
                    break
            if not port:
                return utils.jsonify(
                    {
                        'error': PORT_PROTOCOL_IN_USE,
                        'error_msg': PORT_PROTOCOL_IN_USE_MSG,
                    }, 400)

        if not dh_param_bits_def:
            dh_param_bits_def = True
            dh_param_bits = settings.vpn.default_dh_param_bits

    if network_def:
        if _check_network_overlap(network, network_used):
            return utils.jsonify(
                {
                    'error': NETWORK_IN_USE,
                    'error_msg': NETWORK_IN_USE_MSG,
                }, 400)

    if port_def:
        if '%s%s' % (port, protocol) in port_used:
            return utils.jsonify(
                {
                    'error': PORT_PROTOCOL_IN_USE,
                    'error_msg': PORT_PROTOCOL_IN_USE_MSG,
                }, 400)

    if not server_id:
        if network_mode == BRIDGE:
            if not _check_network_range(network, network_start, network_end):
                return utils.jsonify(
                    {
                        'error': BRIDGE_NETWORK_INVALID,
                        'error_msg': BRIDGE_NETWORK_INVALID_MSG,
                    }, 400)

            if ipv6:
                return utils.jsonify(
                    {
                        'error': IPV6_BRIDGED_INVALID,
                        'error_msg': IPV6_BRIDGED_INVALID_MSG,
                    }, 400)

        svr = server.new_server(
            name=name,
            network=network,
            network_mode=network_mode,
            network_start=network_start,
            network_end=network_end,
            restrict_routes=restrict_routes,
            ipv6=ipv6,
            ipv6_firewall=ipv6_firewall,
            bind_address=bind_address,
            port=port,
            protocol=protocol,
            dh_param_bits=dh_param_bits,
            multi_device=multi_device,
            dns_servers=dns_servers,
            search_domain=search_domain,
            otp_auth=otp_auth,
            cipher=cipher,
            hash=hash,
            jumbo_frames=jumbo_frames,
            lzo_compression=lzo_compression,
            inter_client=inter_client,
            ping_interval=ping_interval,
            ping_timeout=ping_timeout,
            link_ping_interval=link_ping_interval,
            link_ping_timeout=link_ping_timeout,
            max_clients=max_clients,
            replica_count=replica_count,
            dns_mapping=dns_mapping,
            debug=debug,
        )
        svr.add_host(settings.local.host_id)
        svr.commit()
    else:
        svr = server.get_by_id(server_id)
        if svr.status == ONLINE:
            return utils.jsonify(
                {
                    'error': SERVER_NOT_OFFLINE,
                    'error_msg': SERVER_NOT_OFFLINE_SETTINGS_MSG,
                }, 400)

        for link_svr in svr.iter_links(fields=('status', )):
            if link_svr.status == ONLINE:
                return utils.jsonify(
                    {
                        'error': SERVER_LINKS_NOT_OFFLINE,
                        'error_msg': SERVER_LINKS_NOT_OFFLINE_SETTINGS_MSG,
                    }, 400)

        if name_def:
            svr.name = name
        if network_def:
            svr.network = network
        if network_start_def:
            svr.network_start = network_start
        if network_end_def:
            svr.network_end = network_end
        if restrict_routes_def:
            svr.restrict_routes = restrict_routes
        if ipv6_def:
            svr.ipv6 = ipv6
        if ipv6_firewall_def:
            svr.ipv6_firewall = ipv6_firewall
        if network_mode_def:
            if network_mode == BRIDGE and (not network_start
                                           or not network_end):
                return utils.jsonify(
                    {
                        'error': MISSING_PARAMS,
                        'error_msg': MISSING_PARAMS_MSG,
                    }, 400)
            svr.network_mode = network_mode
        if bind_address_def:
            svr.bind_address = bind_address
        if port_def:
            svr.port = port
        if protocol_def:
            svr.protocol = protocol
        if dh_param_bits_def and svr.dh_param_bits != dh_param_bits:
            svr.dh_param_bits = dh_param_bits
            svr.generate_dh_param()
        if multi_device_def:
            svr.multi_device = multi_device
        if dns_servers_def:
            svr.dns_servers = dns_servers
        if search_domain_def:
            svr.search_domain = search_domain
        if otp_auth_def:
            svr.otp_auth = otp_auth
        if cipher_def:
            svr.cipher = cipher
        if hash_def:
            svr.hash = hash
        if jumbo_frames_def:
            svr.jumbo_frames = jumbo_frames
        if lzo_compression_def:
            svr.lzo_compression = lzo_compression
        if inter_client_def:
            svr.inter_client = inter_client
        if ping_interval_def:
            svr.ping_interval = ping_interval
        if ping_timeout_def:
            svr.ping_timeout = ping_timeout
        if link_ping_interval_def:
            svr.link_ping_interval = link_ping_interval
        if link_ping_timeout_def:
            svr.link_ping_timeout = link_ping_timeout
        if max_clients_def:
            svr.max_clients = max_clients
        if replica_count_def:
            svr.replica_count = replica_count
        if dns_mapping_def:
            svr.dns_mapping = dns_mapping
        if debug_def:
            svr.debug = debug

        if svr.network_mode == BRIDGE:
            if not _check_network_range(svr.network, svr.network_start,
                                        svr.network_end):
                return utils.jsonify(
                    {
                        'error': BRIDGE_NETWORK_INVALID,
                        'error_msg': BRIDGE_NETWORK_INVALID_MSG,
                    }, 400)

            if svr.ipv6:
                return utils.jsonify(
                    {
                        'error': IPV6_BRIDGED_INVALID,
                        'error_msg': IPV6_BRIDGED_INVALID_MSG,
                    }, 400)

        if svr.links and svr.replica_count > 1:
            return utils.jsonify(
                {
                    'error': SERVER_LINKS_AND_REPLICA,
                    'error_msg': SERVER_LINKS_AND_REPLICA_MSG,
                }, 400)

        svr.commit(svr.changed)

    logger.LogEntry(message='Created server "%s".' % svr.name)
    event.Event(type=SERVERS_UPDATED)
    event.Event(type=SERVER_ROUTES_UPDATED, resource_id=svr.id)
    for org in svr.iter_orgs():
        event.Event(type=USERS_UPDATED, resource_id=org.id)
    return utils.jsonify(svr.dict())
Ejemplo n.º 4
0
    def _run_thread(self, send_events):
        from pritunl.server.utils import get_by_id

        logger.info('Starting vpn server', 'server',
            server_id=self.server.id,
            instance_id=self.id,
            instances=self.server.instances,
            instances_count=self.server.instances_count,
            route_count=len(self.server.routes),
            network=self.server.network,
            network6=self.server.network6,
            host_id=settings.local.host.id,
            host_address=settings.local.host.local_addr,
            host_address6=settings.local.host.local_addr6,
            host_networks=settings.local.host.local_networks,
            cur_timestamp=utils.now(),
            libipt=settings.vpn.lib_iptables,
        )

        def timeout():
            logger.error('Server startup timed out, stopping server',
                'server',
                server_id=self.server.id,
                instance_id=self.id,
                state=self.state,
            )
            self.stop_process()

        startup_keepalive_thread = threading.Thread(
            target=self._startup_keepalive_thread)
        startup_keepalive_thread.daemon = True

        self.state = 'init'
        timer = threading.Timer(settings.vpn.startup_timeout, timeout)
        timer.daemon = True
        timer.start()

        try:
            self.resources_acquire()

            cursor_id = self.get_cursor_id()

            if self.is_interrupted():
                return

            self.state = 'temp_path'
            os.makedirs(self._temp_path)

            if self.is_interrupted():
                return

            self.state = 'ip_forwarding'
            self.enable_ip_forwarding()

            if self.is_interrupted():
                return

            self.state = 'bridge_start'
            self.bridge_start()

            if self.is_interrupted():
                return

            if self.server.replicating and self.server.vxlan:
                try:
                    self.state = 'get_vxlan'
                    self.vxlan = vxlan.get_vxlan(self.server.id, self.id,
                        self.server.ipv6)

                    if self.is_interrupted():
                        return

                    self.state = 'start_vxlan'
                    self.vxlan.start()

                    if self.is_interrupted():
                        return
                except:
                    logger.exception('Failed to setup server vxlan', 'vxlan',
                        server_id=self.server.id,
                        instance_id=self.id,
                    )

            self.state = 'generate_ovpn_conf'
            self.generate_ovpn_conf()

            if self.is_interrupted():
                return

            self.state = 'generate_iptables_rules'
            self.generate_iptables_rules()

            if self.is_interrupted():
                return

            self.state = 'publish'
            self.publish('started')

            if self.is_interrupted():
                return

            self.state = 'startup_keepalive'
            startup_keepalive_thread.start()

            if self.is_interrupted():
                return

            self.state = 'upsert_iptables_rules'
            self.iptables.upsert_rules()

            if self.is_interrupted():
                return

            self.state = 'init_route_advertisements'
            self.init_route_advertisements()

            if self.is_interrupted():
                return

            self.state = 'openvpn_start'
            self.process = self.openvpn_start()
            self.start_threads(cursor_id)

            if self.is_interrupted():
                return

            self.state = 'instance_com_start'
            self.instance_com = ServerInstanceCom(self.server, self)
            self.instance_com.start()

            if self.is_interrupted():
                return

            if send_events:
                self.state = 'events'
                event.Event(type=SERVERS_UPDATED)
                event.Event(type=SERVER_HOSTS_UPDATED,
                    resource_id=self.server.id)
                for org_id in self.server.organizations:
                    event.Event(type=USERS_UPDATED, resource_id=org_id)

                    if self.is_interrupted():
                        return

            for link_doc in self.server.links:
                if self.server.id > link_doc['server_id']:
                    self.state = 'instance_link'
                    instance_link = ServerInstanceLink(
                        server=self.server,
                        linked_server=get_by_id(link_doc['server_id']),
                    )
                    self.server_links.append(instance_link)
                    instance_link.start()

                    if self.is_interrupted():
                        return

            self.state = 'running'
            self.openvpn_output()

            if self.is_interrupted():
                return

            timer.cancel()
            self.startup_interrupt = True

            plugins.caller(
                'server_start',
                host_id=settings.local.host_id,
                host_name=settings.local.host.name,
                server_id=self.server.id,
                server_name=self.server.name,
                port=self.server.port,
                protocol=self.server.protocol,
                ipv6=self.server.ipv6,
                ipv6_firewall=self.server.ipv6_firewall,
                network=self.server.network,
                network6=self.server.network6,
                network_mode=self.server.network_mode,
                network_start=self.server.network_start,
                network_stop=self.server.network_end,
                restrict_routes=self.server.restrict_routes,
                bind_address=self.server.bind_address,
                onc_hostname=None,
                dh_param_bits=self.server.dh_param_bits,
                multi_device=self.server.multi_device,
                dns_servers=self.server.dns_servers,
                search_domain=self.server.search_domain,
                otp_auth=self.server.otp_auth,
                cipher=self.server.cipher,
                hash=self.server.hash,
                inter_client=self.server.inter_client,
                ping_interval=self.server.ping_interval,
                ping_timeout=self.server.ping_timeout,
                link_ping_interval=self.server.link_ping_interval,
                link_ping_timeout=self.server.link_ping_timeout,
                allowed_devices=self.server.allowed_devices,
                max_clients=self.server.max_clients,
                replica_count=self.server.replica_count,
                dns_mapping=self.server.dns_mapping,
                debug=self.server.debug,
                interface=self.interface,
                bridge_interface=self.bridge_interface,
                vxlan=self.vxlan,
            )
            try:
                while True:
                    if self.process.poll() is not None:
                        break
                    if self.is_interrupted():
                        self.stop_process()
                    time.sleep(0.05)
            finally:
                plugins.caller(
                    'server_stop',
                    host_id=settings.local.host_id,
                    host_name=settings.local.host.name,
                    server_id=self.server.id,
                    server_name=self.server.name,
                    port=self.server.port,
                    protocol=self.server.protocol,
                    ipv6=self.server.ipv6,
                    ipv6_firewall=self.server.ipv6_firewall,
                    network=self.server.network,
                    network6=self.server.network6,
                    network_mode=self.server.network_mode,
                    network_start=self.server.network_start,
                    network_stop=self.server.network_end,
                    restrict_routes=self.server.restrict_routes,
                    bind_address=self.server.bind_address,
                    onc_hostname=None,
                    dh_param_bits=self.server.dh_param_bits,
                    multi_device=self.server.multi_device,
                    dns_servers=self.server.dns_servers,
                    search_domain=self.server.search_domain,
                    otp_auth=self.server.otp_auth,
                    cipher=self.server.cipher,
                    hash=self.server.hash,
                    inter_client=self.server.inter_client,
                    ping_interval=self.server.ping_interval,
                    ping_timeout=self.server.ping_timeout,
                    link_ping_interval=self.server.link_ping_interval,
                    link_ping_timeout=self.server.link_ping_timeout,
                    allowed_devices=self.server.allowed_devices,
                    max_clients=self.server.max_clients,
                    replica_count=self.server.replica_count,
                    dns_mapping=self.server.dns_mapping,
                    debug=self.server.debug,
                    interface=self.interface,
                    bridge_interface=self.bridge_interface,
                    vxlan=self.vxlan,
                )

            if not self.clean_exit:
                event.Event(type=SERVERS_UPDATED)
                self.server.send_link_events()
                logger.LogEntry(
                    message='Server stopped unexpectedly "%s".' % (
                        self.server.name))
        except:
            try:
                self.stop_process()
            except:
                logger.exception('Server stop error', 'server',
                    server_id=self.server.id,
                    instance_id=self.id,
                )

            logger.exception('Server error occurred while running', 'server',
                server_id=self.server.id,
                instance_id=self.id,
            )
        finally:
            timer.cancel()
            self.startup_interrupt = True

            self.interrupt = True
            self.sock_interrupt = True

            try:
                self.bridge_stop()
            except:
                logger.exception('Failed to remove server bridge', 'server',
                    server_id=self.server.id,
                    instance_id=self.id,
                )

            try:
                self.iptables.clear_rules()
            except:
                logger.exception('Server iptables clean up error', 'server',
                    server_id=self.server.id,
                    instance_id=self.id,
                )

            if self.vxlan:
                try:
                    self.vxlan.stop()
                except:
                    logger.exception('Failed to stop server vxlan', 'server',
                        server_id=self.server.id,
                        instance_id=self.id,
                    )

            try:
                self.collection.update({
                    '_id': self.server.id,
                    'instances.instance_id': self.id,
                }, {
                    '$pull': {
                        'instances': {
                            'instance_id': self.id,
                        },
                    },
                    '$inc': {
                        'instances_count': -1,
                    },
                })
                utils.rmtree(self._temp_path)
            except:
                logger.exception('Server clean up error', 'server',
                    server_id=self.server.id,
                    instance_id=self.id,
                )

            try:
                self.resources_release()
            except:
                logger.exception('Failed to release resources', 'server',
                    server_id=self.server.id,
                    instance_id=self.id,
                )
Ejemplo n.º 5
0
def server_put_post(server_id=None):
    used_resources = server.get_used_resources(server_id)
    network_used = used_resources['networks']
    port_used = used_resources['ports']

    name = None
    name_def = False
    if 'name' in flask.request.json:
        name_def = True
        name = utils.filter_str(flask.request.json['name'])

    network = None
    network_def = False
    if 'network' in flask.request.json:
        network_def = True
        network = flask.request.json['network']

        if not _check_network_private(network):
            return _network_invalid()

    network_mode = None
    network_mode_def = False
    if 'network_mode' in flask.request.json:
        network_mode_def = True
        network_mode = flask.request.json['network_mode']

    network_start = None
    network_start_def = False
    if 'network_start' in flask.request.json:
        network_start_def = True
        network_start = flask.request.json['network_start']

        # if not _check_network_private(network_start):
        #     return _network_invalid()

    network_end = None
    network_end_def = False
    if 'network_end' in flask.request.json:
        network_end_def = True
        network_end = flask.request.json['network_end']

        # if not _check_network_private(network_end):
        #     return _network_invalid()

    bind_address = None
    bind_address_def = False
    if 'bind_address' in flask.request.json:
        bind_address_def = True
        bind_address = utils.filter_str(flask.request.json['bind_address'])

    protocol = 'udp'
    protocol_def = False
    if 'protocol' in flask.request.json:
        protocol_def = True
        protocol = flask.request.json['protocol'].lower()

        if protocol not in ('udp', 'tcp'):
            return utils.jsonify(
                {
                    'error': PROTOCOL_INVALID,
                    'error_msg': PROTOCOL_INVALID_MSG,
                }, 400)

    port = None
    port_def = False
    if 'port' in flask.request.json:
        port_def = True
        port = flask.request.json['port']

        try:
            port = int(port)
        except ValueError:
            return _port_invalid()

        if port < 1 or port > 65535:
            return _port_invalid()

    dh_param_bits = None
    dh_param_bits_def = False
    if flask.request.json.get('dh_param_bits'):
        dh_param_bits_def = True
        dh_param_bits = flask.request.json['dh_param_bits']

        try:
            dh_param_bits = int(dh_param_bits)
        except ValueError:
            return _dh_param_bits_invalid()

        if dh_param_bits not in VALID_DH_PARAM_BITS:
            return _dh_param_bits_invalid()

    mode = None
    mode_def = False
    if 'mode' in flask.request.json:
        mode_def = True
        mode = flask.request.json['mode']

        if mode not in (ALL_TRAFFIC, LOCAL_TRAFFIC, VPN_TRAFFIC):
            return utils.jsonify(
                {
                    'error': MODE_INVALID,
                    'error_msg': MODE_INVALID_MSG,
                }, 400)

    multi_device = False
    multi_device_def = False
    if 'multi_device' in flask.request.json:
        multi_device_def = True
        multi_device = True if flask.request.json['multi_device'] else False

    local_networks = None
    local_networks_def = False
    if 'local_networks' in flask.request.json:
        local_networks_def = True
        local_networks = flask.request.json['local_networks'] or []

        for local_network in local_networks:
            local_network_split = local_network.split('/')
            if len(local_network_split) != 2:
                return _local_network_invalid()

            address = local_network_split[0].split('.')
            if len(address) != 4:
                return _local_network_invalid()
            for i, value in enumerate(address):
                try:
                    address[i] = int(value)
                except ValueError:
                    return _local_network_invalid()
            if address[0] > 255 or address[0] < 0 or \
                    address[1] > 255 or address[1] < 0 or \
                    address[2] > 255 or address[2] < 0 or \
                    address[3] > 254 or address[3] < 0:
                return _local_network_invalid()

            try:
                subnet = int(local_network_split[1])
            except ValueError:
                return _local_network_invalid()

            if subnet < 1 or subnet > 32:
                return _local_network_invalid()

    dns_servers = None
    dns_servers_def = False
    if 'dns_servers' in flask.request.json:
        dns_servers_def = True
        dns_servers = flask.request.json['dns_servers'] or []

        for dns_server in dns_servers:
            if not re.match(IP_REGEX, dns_server):
                return _dns_server_invalid()

    search_domain = None
    search_domain_def = False
    if 'search_domain' in flask.request.json:
        search_domain_def = True
        search_domain = utils.filter_str(flask.request.json['search_domain'])

    inter_client = True
    inter_client_def = False
    if 'inter_client' in flask.request.json:
        inter_client_def = True
        inter_client = True if flask.request.json['inter_client'] else False

    ping_interval = None
    ping_interval_def = False
    if flask.request.json.get('ping_interval'):
        ping_interval_def = True
        ping_interval = int(flask.request.json['ping_interval'])

    ping_timeout = None
    ping_timeout_def = False
    if flask.request.json.get('ping_timeout'):
        ping_timeout_def = True
        ping_timeout = int(flask.request.json['ping_timeout'])

    max_clients = None
    max_clients_def = False
    if flask.request.json.get('max_clients'):
        max_clients_def = True
        max_clients = int(flask.request.json['max_clients'])
        if max_clients < 1:
            max_clients = 1

    replica_count = None
    replica_count_def = False
    if flask.request.json.get('replica_count'):
        replica_count_def = True
        replica_count = int(flask.request.json['replica_count'])
        if replica_count < 1:
            replica_count = 1

    debug = False
    debug_def = False
    if 'debug' in flask.request.json:
        debug_def = True
        debug = True if flask.request.json['debug'] else False

    otp_auth = False
    otp_auth_def = False
    if 'otp_auth' in flask.request.json:
        otp_auth_def = True
        otp_auth = True if flask.request.json['otp_auth'] else False

    lzo_compression = False
    lzo_compression_def = False
    if 'lzo_compression' in flask.request.json:
        lzo_compression_def = True
        lzo_compression = True if flask.request.json[
            'lzo_compression'] else False

    cipher = None
    cipher_def = False
    if 'cipher' in flask.request.json:
        cipher_def = True
        cipher = flask.request.json['cipher']

        if cipher not in CIPHERS:
            return utils.jsonify(
                {
                    'error': CIPHER_INVALID,
                    'error_msg': CIPHER_INVALID_MSG,
                }, 400)

    jumbo_frames = False
    jumbo_frames_def = False
    if 'jumbo_frames' in flask.request.json:
        jumbo_frames_def = True
        jumbo_frames = True if flask.request.json['jumbo_frames'] else False

    if not server_id:
        if not name_def:
            return utils.jsonify(
                {
                    'error': MISSING_PARAMS,
                    'error_msg': MISSING_PARAMS_MSG,
                }, 400)

        if network_def and network_mode == BRIDGE and \
                (not network_start or not network_end):
            return utils.jsonify(
                {
                    'error': MISSING_PARAMS,
                    'error_msg': MISSING_PARAMS_MSG,
                }, 400)

        if not network_def:
            network_def = True
            rand_range = range(215, 250)
            rand_range_low = range(15, 215)
            random.shuffle(rand_range)
            random.shuffle(rand_range_low)
            rand_range += rand_range_low
            for i in rand_range:
                rand_network = '192.168.%s.0/24' % i
                if not _check_network_overlap(rand_network, network_used):
                    network = rand_network
                    break
            if not network:
                return utils.jsonify(
                    {
                        'error': NETWORK_IN_USE,
                        'error_msg': NETWORK_IN_USE_MSG,
                    }, 400)

        if not port_def:
            port_def = True
            rand_ports = range(10000, 19999)
            random.shuffle(rand_ports)
            for rand_port in rand_ports:
                if '%s%s' % (rand_port, protocol) not in port_used:
                    port = rand_port
                    break
            if not port:
                return utils.jsonify(
                    {
                        'error': PORT_PROTOCOL_IN_USE,
                        'error_msg': PORT_PROTOCOL_IN_USE_MSG,
                    }, 400)

        if not dh_param_bits_def:
            dh_param_bits_def = True
            dh_param_bits = settings.vpn.default_dh_param_bits

        if not mode_def:
            mode_def = True
            if local_networks_def and local_networks:
                mode = LOCAL_TRAFFIC
            else:
                mode = ALL_TRAFFIC

    if network_def:
        if _check_network_overlap(network, network_used):
            return utils.jsonify(
                {
                    'error': NETWORK_IN_USE,
                    'error_msg': NETWORK_IN_USE_MSG,
                }, 400)
    if port_def:
        if '%s%s' % (port, protocol) in port_used:
            return utils.jsonify(
                {
                    'error': PORT_PROTOCOL_IN_USE,
                    'error_msg': PORT_PROTOCOL_IN_USE_MSG,
                }, 400)

    if not server_id:
        svr = server.new_server(
            name=name,
            network=network,
            network_mode=network_mode,
            network_start=network_start,
            network_end=network_end,
            bind_address=bind_address,
            port=port,
            protocol=protocol,
            dh_param_bits=dh_param_bits,
            mode=mode,
            multi_device=multi_device,
            local_networks=local_networks,
            dns_servers=dns_servers,
            search_domain=search_domain,
            otp_auth=otp_auth,
            cipher=cipher,
            jumbo_frames=jumbo_frames,
            lzo_compression=lzo_compression,
            inter_client=inter_client,
            ping_interval=ping_interval,
            ping_timeout=ping_timeout,
            max_clients=max_clients,
            replica_count=replica_count,
            debug=debug,
        )
        svr.add_host(settings.local.host_id)
        svr.commit()
    else:
        svr = server.get_by_id(server_id)
        if svr.status == ONLINE:
            return utils.jsonify(
                {
                    'error': SERVER_NOT_OFFLINE,
                    'error_msg': SERVER_NOT_OFFLINE_SETTINGS_MSG,
                }, 400)

        for link_svr in svr.iter_links(fields=('status', )):
            if link_svr.status == ONLINE:
                return utils.jsonify(
                    {
                        'error': SERVER_LINKS_NOT_OFFLINE,
                        'error_msg': SERVER_LINKS_NOT_OFFLINE_SETTINGS_MSG,
                    }, 400)

        if name_def:
            svr.name = name
        if network_def:
            svr.network = network
        if network_start_def:
            svr.network_start = network_start
        if network_end_def:
            svr.network_end = network_end
        if network_mode_def:
            if network_mode == BRIDGE and (not network_start
                                           or not network_end):
                return utils.jsonify(
                    {
                        'error': MISSING_PARAMS,
                        'error_msg': MISSING_PARAMS_MSG,
                    }, 400)
            svr.network_mode = network_mode
        if bind_address_def:
            svr.bind_address = bind_address
        if port_def:
            svr.port = port
        if protocol_def:
            svr.protocol = protocol
        if dh_param_bits_def and svr.dh_param_bits != dh_param_bits:
            svr.dh_param_bits = dh_param_bits
            svr.generate_dh_param()
        if mode_def:
            svr.mode = mode
        if multi_device_def:
            svr.multi_device = multi_device
        if local_networks_def:
            svr.local_networks = local_networks
        if dns_servers_def:
            svr.dns_servers = dns_servers
        if search_domain_def:
            svr.search_domain = search_domain
        if otp_auth_def:
            svr.otp_auth = otp_auth
        if cipher_def:
            svr.cipher = cipher
        if jumbo_frames_def:
            svr.jumbo_frames = jumbo_frames
        if lzo_compression_def:
            svr.lzo_compression = lzo_compression
        if inter_client_def:
            svr.inter_client = inter_client
        if ping_interval_def:
            svr.ping_interval = ping_interval
        if ping_timeout_def:
            svr.ping_timeout = ping_timeout
        if max_clients_def:
            svr.max_clients = max_clients
        if replica_count_def:
            svr.replica_count = replica_count
        if debug_def:
            svr.debug = debug

        if svr.links and svr.replica_count > 1:
            return utils.jsonify(
                {
                    'error': SERVER_LINKS_AND_REPLICA,
                    'error_msg': SERVER_LINKS_AND_REPLICA_MSG,
                }, 400)

        svr.commit(svr.changed)

    logger.LogEntry(message='Created server "%s".' % svr.name)
    event.Event(type=SERVERS_UPDATED)
    for org in svr.iter_orgs():
        event.Event(type=USERS_UPDATED, resource_id=org.id)
    return utils.jsonify(svr.dict())
Ejemplo n.º 6
0
    def client_connect(self, client):
        try:
            client_id = client['client_id']
            org_id = utils.ObjectId(client['org_id'])
            user_id = utils.ObjectId(client['user_id'])
            device_id = client.get('device_id')
            device_name = client.get('device_name')
            platform = client.get('platform')
            mac_addr = client.get('mac_addr')
            otp_code = client.get('otp_code')
            remote_ip = client.get('remote_ip')
            devices = self.client_devices[user_id]

            if not _limiter.validate(remote_ip):
                self.send_client_deny(client, 'Too many connect requests')
                return

            org = self.server.get_org(org_id, fields=['_id'])
            if not org:
                self.send_client_deny(client, 'Organization is not valid')
                return

            user = org.get_user(user_id, fields=('_id', 'name', 'email',
                'type', 'auth_type', 'disabled', 'otp_secret',
                'link_server_id'))
            if not user:
                self.send_client_deny(client, 'User is not valid')
                return

            if user.disabled:
                logger.LogEntry(message='User failed authentication, ' +
                    'disabled user "%s".' % (user.name))
                self.send_client_deny(client, 'User is disabled')
                return

            if not user.auth_check():
                logger.LogEntry(message='User failed authentication, ' +
                    'Google authentication failed "%s".' % (user.name))
                self.send_client_deny(client, 'User failed authentication')
                return

            if self.server.otp_auth and  user.type == CERT_CLIENT and \
                    not user.verify_otp_code(otp_code, remote_ip):
                logger.LogEntry(message='User failed two-step ' +
                    'authentication "%s".' % user.name)
                self.send_client_deny(client, 'Invalid OTP code')
                return

            client_conf = self.generate_client_conf(user)

            if not self.server.multi_device:
                virt_address = self.server.get_ip_addr(org.id, user_id)

                if virt_address and virt_address in self.client_ips:
                    for i, device in enumerate(devices):
                        if device['virt_address'] == virt_address:
                            self.client_kill(device)
                            if virt_address in self.client_ips:
                                self.client_ips.remove(virt_address)

                            del devices[i]
            else:
                virt_address = None
                if devices and device_id:
                    for i, device in enumerate(devices):
                        if device['device_id'] == device_id:
                            virt_address = device['virt_address']

                            self.client_kill(device)
                            if virt_address in self.client_ips:
                                self.client_ips.remove(virt_address)

                            del devices[i]

                if not virt_address:
                    virt_address = self.server.get_ip_addr(org.id, user_id)

                if virt_address and virt_address in self.client_ips:
                    virt_address = None

            if not virt_address:
                while True:
                    try:
                        ip_addr = self.ip_pool.pop()
                    except IndexError:
                        break

                    ip_addr = '%s/%s' % (
                        ip_addr, self.ip_network.prefixlen)

                    if ip_addr not in self.client_ips:
                        virt_address = ip_addr
                        self.client_dyn_ips.add(virt_address)
                        break

            if virt_address:
                self.client_ips.add(virt_address)
                devices.append({
                    'user_id': user_id,
                    'org_id': org_id,
                    'client_id': client_id,
                    'device_id': device_id,
                    'device_name': device_name,
                    'type': user.type,
                    'platform': platform,
                    'mac_addr': mac_addr,
                    'otp_code': otp_code,
                    'virt_address': virt_address,
                    'real_address': remote_ip,
                })
                client_conf += 'ifconfig-push %s %s\n' % utils.parse_network(
                    virt_address)

                if self.server.debug:
                    self.push_output('Client conf %s:' % user_id)
                    for conf_line in client_conf.split('\n'):
                        if conf_line:
                            self.push_output('  ' + conf_line)

                self.send_client_auth(client, client_conf)
            else:
                self.send_client_deny(client, 'Unable to assign ip address')
        except:
            logger.exception('Error parsing client connect', 'server',
                server_id=self.server.id,
                instance_id=self.instance.id,
            )
            self.send_client_deny(client, 'Error parsing client connect')
Ejemplo n.º 7
0
def org_post():
    name = utils.filter_str(flask.request.json['name'])
    org = organization.new_org(name=name, type=ORG_DEFAULT)
    logger.LogEntry(message='Created new organization "%s".' % org.name)
    event.Event(type=ORGS_UPDATED)
    return utils.jsonify(org.dict())
Ejemplo n.º 8
0
def server_put_post(server_id=None):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    used_resources = server.get_used_resources(server_id)
    network_used = used_resources['networks']
    port_used = used_resources['ports']

    name = None
    name_def = False
    if 'name' in flask.request.json:
        name_def = True
        name = utils.filter_str(flask.request.json['name'])

    network = None
    network_def = False
    if 'network' in flask.request.json and \
            flask.request.json['network'] != '':
        network_def = True
        network = flask.request.json['network']

        try:
            if not _check_network_private(network):
                return _network_invalid()
        except (ipaddress.AddressValueError, ValueError):
            return _network_invalid()

    network_mode = None
    network_mode_def = False
    if 'network_mode' in flask.request.json:
        network_mode_def = True
        network_mode = flask.request.json['network_mode']

    network_start = None
    network_start_def = False
    if 'network_start' in flask.request.json:
        network_start_def = True
        network_start = flask.request.json['network_start']

    network_end = None
    network_end_def = False
    if 'network_end' in flask.request.json:
        network_end_def = True
        network_end = flask.request.json['network_end']

    restrict_routes = None
    restrict_routes_def = False
    if 'restrict_routes' in flask.request.json:
        restrict_routes_def = True
        restrict_routes = True if flask.request.json['restrict_routes'] \
            else False

    ipv6 = None
    ipv6_def = False
    if 'ipv6' in flask.request.json:
        ipv6_def = True
        ipv6 = True if flask.request.json['ipv6'] else False

    ipv6_firewall = None
    ipv6_firewall_def = False
    if 'ipv6_firewall' in flask.request.json:
        ipv6_firewall_def = True
        ipv6_firewall = True if flask.request.json['ipv6_firewall'] else False

    bind_address = None
    bind_address_def = False
    if 'bind_address' in flask.request.json:
        bind_address_def = True
        bind_address = utils.filter_str(flask.request.json['bind_address'])

    protocol = 'udp'
    protocol_def = False
    if 'protocol' in flask.request.json:
        protocol_def = True
        protocol = flask.request.json['protocol'].lower()

        if protocol not in ('udp', 'tcp'):
            return utils.jsonify({
                'error': PROTOCOL_INVALID,
                'error_msg': PROTOCOL_INVALID_MSG,
            }, 400)

    port = None
    port_def = False
    if 'port' in flask.request.json and flask.request.json['port'] != 0:
        port_def = True
        port = flask.request.json['port']

        try:
            port = int(port)
        except ValueError:
            return _port_invalid()

        if port < 1 or port > 65535:
            return _port_invalid()

    dh_param_bits = None
    dh_param_bits_def = False
    if flask.request.json.get('dh_param_bits'):
        dh_param_bits_def = True
        dh_param_bits = flask.request.json['dh_param_bits']

        try:
            dh_param_bits = int(dh_param_bits)
        except ValueError:
            return _dh_param_bits_invalid()

        if dh_param_bits not in VALID_DH_PARAM_BITS:
            return _dh_param_bits_invalid()

    groups = None
    groups_def = False
    if 'groups' in flask.request.json:
        groups_def = True
        groups = flask.request.json['groups'] or []
        for i, group in enumerate(groups):
            groups[i] = utils.filter_str(group)
        groups = list(set(groups))

    multi_device = False
    multi_device_def = False
    if 'multi_device' in flask.request.json:
        multi_device_def = True
        multi_device = True if flask.request.json['multi_device'] else False

    dns_servers = None
    dns_servers_def = False
    if 'dns_servers' in flask.request.json:
        dns_servers_def = True
        dns_servers = flask.request.json['dns_servers'] or []

        for dns_server in dns_servers:
            try:
                ipaddress.IPAddress(dns_server)
            except (ipaddress.AddressValueError, ValueError):
                return _dns_server_invalid()

    search_domain = None
    search_domain_def = False
    if 'search_domain' in flask.request.json:
        search_domain_def = True
        search_domain = flask.request.json['search_domain']
        if search_domain:
            search_domain = ', '.join([utils.filter_str(x.strip()) for x in
                search_domain.split(',')])
        else:
            search_domain = None

    inter_client = True
    inter_client_def = False
    if 'inter_client' in flask.request.json:
        inter_client_def = True
        inter_client = True if flask.request.json['inter_client'] else False

    ping_interval = None
    ping_interval_def = False
    if 'ping_interval' in flask.request.json:
        ping_interval_def = True
        ping_interval = int(flask.request.json['ping_interval'] or 10)

    ping_timeout = None
    ping_timeout_def = False
    if 'ping_timeout' in flask.request.json:
        ping_timeout_def = True
        ping_timeout = int(flask.request.json['ping_timeout'] or 60)

    link_ping_interval = None
    link_ping_interval_def = False
    if 'link_ping_interval' in flask.request.json:
        link_ping_interval_def = True
        link_ping_interval = int(
            flask.request.json['link_ping_interval'] or 1)

    link_ping_timeout = None
    link_ping_timeout_def = False
    if 'link_ping_timeout' in flask.request.json:
        link_ping_timeout_def = True
        link_ping_timeout = int(flask.request.json['link_ping_timeout'] or 5)

    inactive_timeout = None
    inactive_timeout_def = False
    if 'inactive_timeout' in flask.request.json:
        inactive_timeout_def = True
        inactive_timeout = int(
            flask.request.json['inactive_timeout'] or 0) or None

    onc_hostname = None
    onc_hostname_def = False
    if 'onc_hostname' in flask.request.json:
        onc_hostname_def = True
        onc_hostname = utils.filter_str(flask.request.json['onc_hostname'])

    allowed_devices = None
    allowed_devices_def = False
    if 'allowed_devices' in flask.request.json:
        allowed_devices_def = True
        allowed_devices = flask.request.json['allowed_devices'] or None

    max_clients = None
    max_clients_def = False
    if 'max_clients' in flask.request.json:
        max_clients_def = True
        max_clients = flask.request.json['max_clients']
        if max_clients:
            max_clients = int(max_clients)
        if not max_clients:
            max_clients = 2000

    replica_count = None
    replica_count_def = False
    if 'replica_count' in flask.request.json:
        replica_count_def = True
        replica_count = flask.request.json['replica_count']
        if replica_count:
            replica_count = int(replica_count)
        if not replica_count:
            replica_count = 1

    vxlan = True
    vxlan_def = False
    if 'vxlan' in flask.request.json:
        vxlan_def = True
        vxlan = True if flask.request.json['vxlan'] else False

    dns_mapping = False
    dns_mapping_def = False
    if 'dns_mapping' in flask.request.json:
        dns_mapping_def = True
        dns_mapping = True if flask.request.json['dns_mapping'] else False

    debug = False
    debug_def = False
    if 'debug' in flask.request.json:
        debug_def = True
        debug = True if flask.request.json['debug'] else False

    policy = None
    policy_def = False
    if 'policy' in flask.request.json:
        policy_def = True
        if flask.request.json['policy']:
            policy = flask.request.json['policy'].strip()

    otp_auth = False
    otp_auth_def = False
    if 'otp_auth' in flask.request.json:
        otp_auth_def = True
        otp_auth = True if flask.request.json['otp_auth'] else False

    lzo_compression = False
    lzo_compression_def = False
    if 'lzo_compression' in flask.request.json:
        lzo_compression_def = True
        lzo_compression = True if flask.request.json[
            'lzo_compression'] else False

    cipher = None
    cipher_def = False
    if 'cipher' in flask.request.json:
        cipher_def = True
        cipher = flask.request.json['cipher']

        if cipher not in CIPHERS:
            return utils.jsonify({
                'error': CIPHER_INVALID,
                'error_msg': CIPHER_INVALID_MSG,
            }, 400)

    hash = None
    hash_def = False
    if 'hash' in flask.request.json:
        hash_def = True
        hash = flask.request.json['hash']

        if hash not in HASHES:
            return utils.jsonify({
                'error': HASH_INVALID,
                'error_msg': HASH_INVALID_MSG,
            }, 400)

    block_outside_dns = False
    block_outside_dns_def = False
    if 'block_outside_dns' in flask.request.json:
        block_outside_dns_def = True
        block_outside_dns = True if flask.request.json[
            'block_outside_dns'] else False

    jumbo_frames = False
    jumbo_frames_def = False
    if 'jumbo_frames' in flask.request.json:
        jumbo_frames_def = True
        jumbo_frames = True if flask.request.json[
            'jumbo_frames'] else False

    if not server_id:
        if not name_def:
            return utils.jsonify({
                'error': MISSING_PARAMS,
                'error_msg': MISSING_PARAMS_MSG,
            }, 400)

        if not network_def:
            network_def = True
            rand_range = range(215, 250)
            rand_range_low = range(15, 215)
            random.shuffle(rand_range)
            random.shuffle(rand_range_low)
            rand_range += rand_range_low
            for i in rand_range:
                rand_network = '192.168.%s.0/24' % i
                if not _check_network_overlap(rand_network, network_used):
                    network = rand_network
                    break
            if not network:
                return utils.jsonify({
                    'error': NETWORK_IN_USE,
                    'error_msg': NETWORK_IN_USE_MSG,
                }, 400)

        if not port_def:
            port_def = True
            rand_ports = range(10000, 19999)
            random.shuffle(rand_ports)
            for rand_port in rand_ports:
                if '%s%s' % (rand_port, protocol) not in port_used:
                    port = rand_port
                    break
            if not port:
                return utils.jsonify({
                    'error': PORT_PROTOCOL_IN_USE,
                    'error_msg': PORT_PROTOCOL_IN_USE_MSG,
                }, 400)

        if not dh_param_bits_def:
            dh_param_bits_def = True
            dh_param_bits = settings.vpn.default_dh_param_bits

    changed = None

    if not server_id:
        svr = server.new_server(
            name=name,
            network=network,
            groups=groups,
            network_mode=network_mode,
            network_start=network_start,
            network_end=network_end,
            restrict_routes=restrict_routes,
            ipv6=ipv6,
            ipv6_firewall=ipv6_firewall,
            bind_address=bind_address,
            port=port,
            protocol=protocol,
            dh_param_bits=dh_param_bits,
            multi_device=multi_device,
            dns_servers=dns_servers,
            search_domain=search_domain,
            otp_auth=otp_auth,
            cipher=cipher,
            hash=hash,
            block_outside_dns=block_outside_dns,
            jumbo_frames=jumbo_frames,
            lzo_compression=lzo_compression,
            inter_client=inter_client,
            ping_interval=ping_interval,
            ping_timeout=ping_timeout,
            link_ping_interval=link_ping_interval,
            link_ping_timeout=link_ping_timeout,
            inactive_timeout=inactive_timeout,
            onc_hostname=onc_hostname,
            allowed_devices=allowed_devices,
            max_clients=max_clients,
            replica_count=replica_count,
            vxlan=vxlan,
            dns_mapping=dns_mapping,
            debug=debug,
            policy=policy,
        )
        svr.add_host(settings.local.host_id)
    else:
        svr = server.get_by_id(server_id)

        if name_def:
            svr.name = name
        if network_def:
            svr.network = network
        if groups_def:
            svr.groups = groups
        if network_start_def:
            svr.network_start = network_start
        if network_end_def:
            svr.network_end = network_end
        if restrict_routes_def:
            svr.restrict_routes = restrict_routes
        if ipv6_def:
            svr.ipv6 = ipv6
        if ipv6_firewall_def:
            svr.ipv6_firewall = ipv6_firewall
        if network_mode_def:
            svr.network_mode = network_mode
        if bind_address_def:
            svr.bind_address = bind_address
        if port_def:
            svr.port = port
        if protocol_def:
            svr.protocol = protocol
        if dh_param_bits_def and svr.dh_param_bits != dh_param_bits:
            svr.dh_param_bits = dh_param_bits
            svr.generate_dh_param()
        if multi_device_def:
            svr.multi_device = multi_device
        if dns_servers_def:
            svr.dns_servers = dns_servers
        if search_domain_def:
            svr.search_domain = search_domain
        if otp_auth_def:
            svr.otp_auth = otp_auth
        if cipher_def:
            svr.cipher = cipher
        if hash_def:
            svr.hash = hash
        if block_outside_dns_def:
            svr.block_outside_dns = block_outside_dns
        if jumbo_frames_def:
            svr.jumbo_frames = jumbo_frames
        if lzo_compression_def:
            svr.lzo_compression = lzo_compression
        if inter_client_def:
            svr.inter_client = inter_client
        if ping_interval_def:
            svr.ping_interval = ping_interval
        if ping_timeout_def:
            svr.ping_timeout = ping_timeout
        if link_ping_interval_def:
            svr.link_ping_interval = link_ping_interval
        if link_ping_timeout_def:
            svr.link_ping_timeout = link_ping_timeout
        if inactive_timeout_def:
            svr.inactive_timeout = inactive_timeout
        if onc_hostname_def:
            svr.onc_hostname = onc_hostname
        if allowed_devices_def:
            svr.allowed_devices = allowed_devices
        if max_clients_def:
            svr.max_clients = max_clients
        if replica_count_def:
            svr.replica_count = replica_count
        if vxlan_def:
            svr.vxlan = vxlan
        if dns_mapping_def:
            svr.dns_mapping = dns_mapping
        if debug_def:
            svr.debug = debug
        if policy_def:
            svr.policy = policy

        changed = svr.changed

    err, err_msg = svr.validate_conf()
    if err:
        return utils.jsonify({
            'error': err,
            'error_msg': err_msg,
        }, 400)

    svr.commit(changed)

    logger.LogEntry(message='Created server "%s".' % svr.name)
    event.Event(type=SERVERS_UPDATED)
    event.Event(type=SERVER_ROUTES_UPDATED, resource_id=svr.id)
    for org in svr.iter_orgs():
        event.Event(type=USERS_UPDATED, resource_id=org.id)
    return utils.jsonify(svr.dict())
Ejemplo n.º 9
0
    def _run_thread(self, send_events):
        from pritunl.server.utils import get_by_id

        logger.debug(
            'Starting ovpn process',
            'server',
            server_id=self.server.id,
        )

        self.resources_acquire()
        try:
            cursor_id = self.get_cursor_id()

            os.makedirs(self._temp_path)
            self.generate_ovpn_conf()

            self.enable_ip_forwarding()
            self.set_iptables_rules()

            self.process = self.openvpn_start()
            if not self.process:
                return

            self.start_threads(cursor_id)

            self.instance_com = ServerInstanceCom(self.server, self)
            self.instance_com.start()

            self.publish('started')

            if send_events:
                event.Event(type=SERVERS_UPDATED)
                event.Event(type=SERVER_HOSTS_UPDATED,
                            resource_id=self.server.id)
                for org_id in self.server.organizations:
                    event.Event(type=USERS_UPDATED, resource_id=org_id)

            for link_doc in self.server.links:
                if self.server.id > link_doc['server_id']:
                    instance_link = ServerInstanceLink(
                        server=self.server,
                        linked_server=get_by_id(link_doc['server_id']),
                    )
                    self.server_links.append(instance_link)
                    instance_link.start()

            self.openvpn_watch()

            self.interrupt = True
            self.clear_iptables_rules()
            self.resources_release()

            if not self.clean_exit:
                event.Event(type=SERVERS_UPDATED)
                self.server.send_link_events()
                logger.LogEntry(message='Server stopped unexpectedly "%s".' %
                                (self.server.name))
        except:
            self.interrupt = True
            if self.resource_lock:
                self.clear_iptables_rules()
            self.resources_release()

            logger.exception(
                'Server error occurred while running',
                'server',
                server_id=self.server.id,
            )
        finally:
            self.stop_threads()
            self.collection.update(
                {
                    '_id': self.server.id,
                    'instances.instance_id': self.id,
                }, {
                    '$pull': {
                        'instances': {
                            'instance_id': self.id,
                        },
                    },
                    '$inc': {
                        'instances_count': -1,
                    },
                })
            utils.rmtree(self._temp_path)
Ejemplo n.º 10
0
    def connect(self, client):
        client_id = None
        key_id = None
        try:
            client_id = client['client_id']
            key_id = client['key_id']
            org_id = client['org_id']
            user_id = client['user_id']
            otp_code = client.get('otp_code')
            remote_ip = client.get('remote_ip')
            platform = client.get('platform')
            device_name = client.get('device_name')

            if not _limiter.validate(remote_ip):
                self.instance_com.send_client_deny(
                    client_id, key_id, 'Too many connect requests')
                return

            org = self.server.get_org(org_id, fields=['_id', 'name'])
            if not org:
                self.instance_com.send_client_deny(
                    client_id, key_id, 'Organization is not valid')
                return

            user = org.get_user(user_id,
                                fields=('_id', 'name', 'email', 'type',
                                        'auth_type', 'disabled', 'otp_secret',
                                        'link_server_id'))
            if not user:
                self.instance_com.send_client_deny(client_id, key_id,
                                                   'User is not valid')
                return

            if user.disabled:
                logger.LogEntry(message='User failed authentication, ' +
                                'disabled user "%s".' % (user.name))
                self.instance_com.send_client_deny(client_id, key_id,
                                                   'User is disabled')
                return

            if not user.auth_check():
                logger.LogEntry(message='User failed authentication, ' +
                                'Google authentication failed "%s".' %
                                (user.name))
                self.instance_com.send_client_deny(
                    client_id, key_id, 'User failed authentication')
                return

            if self.server.otp_auth and  user.type == CERT_CLIENT and \
                    not user.verify_otp_code(otp_code, remote_ip):
                logger.LogEntry(message='User failed two-step ' +
                                'authentication "%s".' % user.name)
                self.instance_com.send_client_deny(client_id, key_id,
                                                   'Invalid OTP code')
                return

            if settings.app.sso and user.auth_type == DUO_AUTH and \
                    DUO_AUTH in settings.app.sso:

                def duo_auth():
                    info = {
                        'Server': self.server.name,
                    }

                    platform_name = None
                    if platform == 'linux':
                        platform_name = 'Linux'
                    elif platform == 'mac':
                        platform_name = 'Apple'
                    elif platform == 'win':
                        platform_name = 'Windows'
                    elif platform == 'chrome':
                        platform_name = 'Chrome OS'

                    if device_name:
                        info['Device'] = '%s (%s)' % (device_name,
                                                      platform_name)

                    allow = False
                    try:
                        allow, _ = sso.auth_duo(
                            user.name,
                            ipaddr=remote_ip,
                            type='Connection',
                            info=info,
                        )
                    except:
                        logger.exception(
                            'Duo server error',
                            'server',
                            client_id=client_id,
                            user_id=user.id,
                            username=user.name,
                            server_id=self.server.id,
                        )
                        self.instance_com.push_output(
                            'ERROR Duo server error client_id=%s' % client_id)
                    try:
                        if allow:
                            self.allow_client(client, org, user)
                        else:
                            logger.LogEntry(message='User failed duo ' +
                                            'authentication "%s".' % user.name)
                            self.instance_com.send_client_deny(
                                client_id,
                                key_id,
                                'User failed duo authentication',
                            )
                    except:
                        logger.exception(
                            'Duo auth error',
                            'server',
                            client_id=client_id,
                            user_id=user.id,
                            server_id=self.server.id,
                        )
                        self.instance_com.push_output(
                            'ERROR Duo auth error client_id=%s' % client_id)

                thread = threading.Thread(target=duo_auth)
                thread.daemon = True
                thread.start()
            else:
                self.allow_client(client, org, user)
        except:
            logger.exception(
                'Error parsing client connect',
                'server',
                server_id=self.server.id,
            )
            if client_id and key_id:
                self.instance_com.send_client_deny(
                    client_id, key_id, 'Error parsing client connect')
Ejemplo n.º 11
0
def user_put(org_id, user_id):
    org = organization.get_by_id(org_id)
    user = org.get_user(user_id)

    if 'name' in flask.request.json:
        user.name = utils.filter_str(flask.request.json['name']) or None

    if 'email' in flask.request.json:
        user.email = utils.filter_str(flask.request.json['email']) or None

    if 'network_links' in flask.request.json:
        network_links_cur = set(user.get_network_links())
        network_links_new = set()

        for network_link in flask.request.json['network_links']:
            try:
                network_link = str(ipaddress.IPNetwork(network_link))
            except (ipaddress.AddressValueError, ValueError):
                return _network_link_invalid()
            network_links_new.add(network_link)

        network_links_add = network_links_new - network_links_cur
        network_links_rem = network_links_cur - network_links_new

        try:
            for network_link in network_links_add:
                user.add_network_link(network_link)
        except ServerOnlineError:
            return utils.jsonify(
                {
                    'error': NETWORK_LINK_NOT_OFFLINE,
                    'error_msg': NETWORK_LINK_NOT_OFFLINE_MSG,
                }, 400)

        for network_link in network_links_rem:
            user.remove_network_link(network_link)

    disabled = flask.request.json.get('disabled')
    if disabled is not None:
        user.disabled = disabled

    user.commit()
    event.Event(type=USERS_UPDATED, resource_id=user.org.id)

    if disabled:
        user.disconnect()
        if user.type == CERT_CLIENT:
            logger.LogEntry(message='Disabled user "%s".' % user.name)
    elif disabled == False and user.type == CERT_CLIENT:
        logger.LogEntry(message='Enabled user "%s".' % user.name)

    send_key_email = flask.request.json.get('send_key_email')
    if send_key_email and user.email:
        try:
            user.send_key_email(flask.request.url_root[:-1])
        except EmailNotConfiguredError:
            return utils.jsonify(
                {
                    'error': EMAIL_NOT_CONFIGURED,
                    'error_msg': EMAIL_NOT_CONFIGURED_MSG,
                }, 400)
        except EmailFromInvalid:
            return utils.jsonify(
                {
                    'error': EMAIL_FROM_INVALID,
                    'error_msg': EMAIL_FROM_INVALID_MSG,
                }, 400)
        except EmailAuthInvalid:
            return utils.jsonify(
                {
                    'error': EMAIL_AUTH_INVALID,
                    'error_msg': EMAIL_AUTH_INVALID_MSG,
                }, 400)

    return utils.jsonify(user.dict())
Ejemplo n.º 12
0
def _create_users(org_id, users_data, remote_addr, background):
    global _users_background

    org = organization.get_by_id(org_id)
    users = []
    partial_event = len(users_data) <= 100

    if background:
        _users_background_lock.acquire()
        if _users_background:
            return
        _users_background = True
        _users_background_lock.release()

    try:
        for i, user_data in enumerate(users_data):
            name = utils.filter_str(user_data['name'])
            email = utils.filter_str(user_data.get('email'))
            pin = utils.filter_str(user_data.get('pin')) or None
            disabled = True if user_data.get('disabled') else False
            network_links = user_data.get('network_links') or None
            bypass_secondary = True if user_data.get(
                'bypass_secondary') else False
            client_to_client = True if user_data.get(
                'client_to_client') else False
            dns_servers = user_data.get('dns_servers') or None
            dns_suffix = utils.filter_str(user_data.get('dns_suffix')) or None
            port_forwarding_in = user_data.get('port_forwarding')
            port_forwarding = []

            groups = user_data.get('groups') or []
            for i, group in enumerate(groups):
                groups[i] = utils.filter_str(group)
            groups = list(set(groups))

            if pin:
                if not pin.isdigit():
                    return utils.jsonify(
                        {
                            'error': PIN_NOT_DIGITS,
                            'error_msg': PIN_NOT_DIGITS_MSG,
                        }, 400)

                if len(pin) < settings.user.pin_min_length:
                    return utils.jsonify(
                        {
                            'error': PIN_TOO_SHORT,
                            'error_msg': PIN_TOO_SHORT_MSG,
                        }, 400)

                pin = auth.generate_hash_pin_v2(pin)

            if port_forwarding_in:
                for data in port_forwarding_in:
                    port_forwarding.append({
                        'protocol':
                        utils.filter_str(data.get('protocol')),
                        'port':
                        utils.filter_str(data.get('port')),
                        'dport':
                        utils.filter_str(data.get('dport')),
                    })

            user = org.new_user(type=CERT_CLIENT,
                                name=name,
                                email=email,
                                groups=groups,
                                pin=pin,
                                disabled=disabled,
                                bypass_secondary=bypass_secondary,
                                client_to_client=client_to_client,
                                dns_servers=dns_servers,
                                dns_suffix=dns_suffix,
                                port_forwarding=port_forwarding)
            user.audit_event(
                'user_created',
                'User created from web console',
                remote_addr=remote_addr,
            )

            if network_links:
                for network_link in network_links:
                    try:
                        user.add_network_link(network_link)
                    except (ipaddress.AddressValueError, ValueError):
                        return _network_link_invalid()
                    except ServerOnlineError:
                        return utils.jsonify(
                            {
                                'error': NETWORK_LINK_NOT_OFFLINE,
                                'error_msg': NETWORK_LINK_NOT_OFFLINE_MSG,
                            }, 400)

            users.append(user.dict())

            if partial_event and i != 0 and i % 10 == 0:
                event.Event(type=ORGS_UPDATED)
                event.Event(type=USERS_UPDATED, resource_id=org.id)
                event.Event(type=SERVERS_UPDATED)
    except:
        logger.exception('Error creating users', 'users')
        raise
    finally:
        if background:
            _users_background_lock.acquire()
            _users_background = False
            _users_background_lock.release()

        event.Event(type=ORGS_UPDATED)
        event.Event(type=USERS_UPDATED, resource_id=org.id)
        event.Event(type=SERVERS_UPDATED)

    if len(users) > 1:
        logger.LogEntry(message='Created %s new users.' % len(users))
        return utils.jsonify(users)
    else:
        logger.LogEntry(message='Created new user "%s".' % users[0]['name'])
        return utils.jsonify(users[0])
Ejemplo n.º 13
0
    def _run_thread(self, send_events):
        from pritunl.server.utils import get_by_id

        self.resources_acquire()
        try:
            cursor_id = self.get_cursor_id()

            os.makedirs(self._temp_path)

            self.enable_ip_forwarding()
            self.bridge_start()

            if self.server.replicating and self.server.vxlan:
                try:
                    self.vxlan = vxlan.get_vxlan(self.server.id)
                    self.vxlan.start()
                except:
                    logger.exception(
                        'Failed to setup server vxlan',
                        'vxlan',
                        server_id=self.server.id,
                        instance_id=self.id,
                    )

            self.generate_ovpn_conf()

            self.generate_iptables_rules()
            self.iptables.upsert_rules()

            self.init_route_advertisements()

            self.process = self.openvpn_start()
            if not self.process:
                return

            self.start_threads(cursor_id)

            self.instance_com = ServerInstanceCom(self.server, self)
            self.instance_com.start()

            self.publish('started')

            if send_events:
                event.Event(type=SERVERS_UPDATED)
                event.Event(type=SERVER_HOSTS_UPDATED,
                            resource_id=self.server.id)
                for org_id in self.server.organizations:
                    event.Event(type=USERS_UPDATED, resource_id=org_id)

            for link_doc in self.server.links:
                if self.server.id > link_doc['server_id']:
                    instance_link = ServerInstanceLink(
                        server=self.server,
                        linked_server=get_by_id(link_doc['server_id']),
                    )
                    self.server_links.append(instance_link)
                    instance_link.start()

            plugins.caller(
                'server_start',
                host_id=settings.local.host_id,
                host_name=settings.local.host.name,
                server_id=self.server.id,
                server_name=self.server.name,
                port=self.server.port,
                protocol=self.server.protocol,
                ipv6=self.server.ipv6,
                ipv6_firewall=self.server.ipv6_firewall,
                network=self.server.network,
                network6=self.server.network6,
                network_mode=self.server.network_mode,
                network_start=self.server.network_start,
                network_stop=self.server.network_end,
                restrict_routes=self.server.restrict_routes,
                bind_address=self.server.bind_address,
                onc_hostname=self.server.onc_hostname,
                dh_param_bits=self.server.dh_param_bits,
                multi_device=self.server.multi_device,
                dns_servers=self.server.dns_servers,
                search_domain=self.server.search_domain,
                otp_auth=self.server.otp_auth,
                cipher=self.server.cipher,
                hash=self.server.hash,
                inter_client=self.server.inter_client,
                ping_interval=self.server.ping_interval,
                ping_timeout=self.server.ping_timeout,
                link_ping_interval=self.server.link_ping_interval,
                link_ping_timeout=self.server.link_ping_timeout,
                allowed_devices=self.server.allowed_devices,
                max_clients=self.server.max_clients,
                replica_count=self.server.replica_count,
                dns_mapping=self.server.dns_mapping,
                debug=self.server.debug,
                interface=self.interface,
                bridge_interface=self.bridge_interface,
                vxlan=self.vxlan,
            )
            try:
                self.openvpn_watch()
            finally:
                plugins.caller(
                    'server_stop',
                    host_id=settings.local.host_id,
                    host_name=settings.local.host.name,
                    server_id=self.server.id,
                    server_name=self.server.name,
                    port=self.server.port,
                    protocol=self.server.protocol,
                    ipv6=self.server.ipv6,
                    ipv6_firewall=self.server.ipv6_firewall,
                    network=self.server.network,
                    network6=self.server.network6,
                    network_mode=self.server.network_mode,
                    network_start=self.server.network_start,
                    network_stop=self.server.network_end,
                    restrict_routes=self.server.restrict_routes,
                    bind_address=self.server.bind_address,
                    onc_hostname=self.server.onc_hostname,
                    dh_param_bits=self.server.dh_param_bits,
                    multi_device=self.server.multi_device,
                    dns_servers=self.server.dns_servers,
                    search_domain=self.server.search_domain,
                    otp_auth=self.server.otp_auth,
                    cipher=self.server.cipher,
                    hash=self.server.hash,
                    inter_client=self.server.inter_client,
                    ping_interval=self.server.ping_interval,
                    ping_timeout=self.server.ping_timeout,
                    link_ping_interval=self.server.link_ping_interval,
                    link_ping_timeout=self.server.link_ping_timeout,
                    allowed_devices=self.server.allowed_devices,
                    max_clients=self.server.max_clients,
                    replica_count=self.server.replica_count,
                    dns_mapping=self.server.dns_mapping,
                    debug=self.server.debug,
                    interface=self.interface,
                    bridge_interface=self.bridge_interface,
                    vxlan=self.vxlan,
                )

            self.interrupt = True
            self.bridge_stop()
            self.iptables.clear_rules()
            self.resources_release()

            if not self.clean_exit:
                event.Event(type=SERVERS_UPDATED)
                self.server.send_link_events()
                logger.LogEntry(message='Server stopped unexpectedly "%s".' %
                                (self.server.name))
        except:
            self.interrupt = True
            self.stop_process()
            if self.resource_lock:
                self.iptables.clear_rules()
                self.bridge_stop()
            self.resources_release()

            logger.exception(
                'Server error occurred while running',
                'server',
                server_id=self.server.id,
            )
        finally:
            self.stop_threads()
            self.collection.update(
                {
                    '_id': self.server.id,
                    'instances.instance_id': self.id,
                }, {
                    '$pull': {
                        'instances': {
                            'instance_id': self.id,
                        },
                    },
                    '$inc': {
                        'instances_count': -1,
                    },
                })
            utils.rmtree(self._temp_path)