def generate_client_conf(self, user): from pritunl.server.utils import get_by_id client_conf = '' if user.link_server_id: link_usr_svr = get_by_id(user.link_server_id, fields=('_id', 'network', 'local_networks')) client_conf += 'iroute %s %s\n' % utils.parse_network( link_usr_svr.network) for local_network in link_usr_svr.local_networks: client_conf += 'iroute %s %s\n' % utils.parse_network( local_network) else: if self.server.mode == ALL_TRAFFIC: client_conf += 'push "redirect-gateway"\n' for dns_server in self.server.dns_servers: client_conf += 'push "dhcp-option DNS %s"\n' % dns_server if self.server.search_domain: client_conf += 'push "dhcp-option DOMAIN %s"\n' % ( self.server.search_domain) for link_svr in self.server.iter_links(fields=( '_id', 'network', 'local_networks')): client_conf += 'push "route %s %s"\n' % utils.parse_network( link_svr.network) for local_network in link_svr.local_networks: client_conf += 'push "route %s %s"\n' % ( utils.parse_network(local_network)) return client_conf
def generate_client_conf(self, user): from pritunl.server.utils import get_by_id client_conf = '' if user.link_server_id: link_usr_svr = get_by_id(user.link_server_id, fields=('_id', 'network', 'local_networks')) client_conf += 'iroute %s %s\n' % utils.parse_network( link_usr_svr.network) for local_network in link_usr_svr.local_networks: client_conf += 'iroute %s %s\n' % utils.parse_network( local_network) else: if self.server.mode == ALL_TRAFFIC: client_conf += 'push "redirect-gateway"\n' for dns_server in self.server.dns_servers: client_conf += 'push "dhcp-option DNS %s"\n' % dns_server if self.server.search_domain: client_conf += 'push "dhcp-option DOMAIN %s"\n' % ( self.server.search_domain) for link_svr in self.server.iter_links(fields=('_id', 'network', 'local_networks')): client_conf += 'push "route %s %s"\n' % utils.parse_network( link_svr.network) for local_network in link_svr.local_networks: client_conf += 'push "route %s %s"\n' % ( utils.parse_network(local_network)) return client_conf
def server_client_connect_post(server_id): org_id = bson.ObjectId(flask.request.json['org_id']) user_id = bson.ObjectId(flask.request.json['user_id']) svr = server.get_by_id(server_id, fields=['_id', 'name', 'network', 'links', 'organizations']) if not svr: return utils.jsonify({ 'error': SERVER_INVALID, 'error_msg': SERVER_INVALID_MSG, }, 401) org = svr.get_org(org_id, fields=['_id']) if not org: return utils.jsonify({ 'error': ORG_INVALID, 'error_msg': ORG_INVALID_MSG, }, 401) user = org.get_user(user_id, fields=['_id', 'name', 'disabled']) if not user: return utils.jsonify({ 'error': USER_INVALID, 'error_msg': USER_INVALID_MSG, }, 401) client_conf = '' link_svr_id = None for link_doc in svr.links: if link_doc['user_id'] == user.id: link_svr_id = link_doc['server_id'] break if link_svr_id: link_svr = server.get_by_id(link_svr_id, fields=['_id', 'network', 'local_networks']) client_conf += 'iroute %s %s\n' % utils.parse_network( link_svr.network) for local_network in link_svr.local_networks: push += 'iroute %s %s\n' % utils.parse_network( local_network) remote_ip_addr = svr.get_ip_addr(org.id, user_id) if remote_ip_addr: client_conf += 'ifconfig-push %s %s\n' % utils.parse_network( remote_ip_addr) return utils.jsonify({ 'client_conf': client_conf, })
def generate_client_conf(self, user): from pritunl.server.utils import get_by_id client_conf = '' if user.link_server_id: link_usr_svr = get_by_id(user.link_server_id, fields=('_id', 'network', 'network_start', 'network_end', 'local_networks')) client_conf += 'iroute %s %s\n' % utils.parse_network( link_usr_svr.network) for local_network in link_usr_svr.local_networks: client_conf += 'iroute %s %s\n' % utils.parse_network( local_network) else: if self.server.mode == ALL_TRAFFIC: client_conf += 'push "redirect-gateway def1"\n' if self.server.ipv6: client_conf += 'push "redirect-gateway-ipv6 def1"\n' client_conf += 'push "route-ipv6 2000::/3"\n' for dns_server in self.server.dns_servers: client_conf += 'push "dhcp-option DNS %s"\n' % dns_server if self.server.search_domain: client_conf += 'push "dhcp-option DOMAIN %s"\n' % ( self.server.search_domain) client_conf += 'push "ip-win32 dynamic 0 3600"\n' for link_svr in self.server.iter_links(fields=('_id', 'network', 'local_networks', 'network_start', 'network_end')): client_conf += 'push "route %s %s"\n' % utils.parse_network( link_svr.network) for local_network in link_svr.local_networks: if ':' in local_network: client_conf += 'push "route-ipv6 %s"\n' % local_network else: client_conf += 'push "route %s %s"\n' % ( utils.parse_network(local_network)) return client_conf
def generate_client_conf(self, user): from pritunl.server.utils import get_by_id client_conf = '' if user.link_server_id: link_usr_svr = get_by_id(user.link_server_id, fields=('_id', 'network', 'network_start', 'network_end', 'local_networks')) client_conf += 'iroute %s %s\n' % utils.parse_network( link_usr_svr.network) for local_network in link_usr_svr.local_networks: client_conf += 'iroute %s %s\n' % utils.parse_network( local_network) else: if self.server.mode == ALL_TRAFFIC: client_conf += 'push "redirect-gateway def1"\n' if self.server.ipv6: client_conf += 'push "redirect-gateway-ipv6 def1"\n' client_conf += 'push "route-ipv6 2000::/3"\n' for dns_server in self.server.dns_servers: client_conf += 'push "dhcp-option DNS %s"\n' % dns_server if self.server.search_domain: client_conf += 'push "dhcp-option DOMAIN %s"\n' % ( self.server.search_domain) client_conf += 'push "ip-win32 dynamic 0 3600"\n' for link_svr in self.server.iter_links(fields=( '_id', 'network', 'local_networks', 'network_start', 'network_end')): client_conf += 'push "route %s %s"\n' % utils.parse_network( link_svr.network) for local_network in link_svr.local_networks: if ':' in local_network: client_conf += 'push "route-ipv6 %s"\n' % local_network else: client_conf += 'push "route %s %s"\n' % ( utils.parse_network(local_network)) return client_conf
def generate_iptables_rules(self): rules = [] rules6 = [] try: routes_output = utils.check_output_logged(['route', '-n']) except subprocess.CalledProcessError: logger.exception('Failed to get IP routes', 'server', server_id=self.server.id, ) raise routes = [] default_interface = None for line in routes_output.splitlines(): line_split = line.split() if len(line_split) < 8 or not re.match(IP_REGEX, line_split[0]): continue if line_split[0] not in routes: if line_split[0] == '0.0.0.0': default_interface = line_split[7] routes.append(( ipaddress.IPNetwork('%s/%s' % (line_split[0], utils.subnet_to_cidr(line_split[2]))), line_split[7] )) routes.reverse() if not default_interface: raise IptablesError('Failed to find default network interface') routes6 = [] default_interface6 = None if self.server.ipv6: try: routes_output = utils.check_output_logged( ['route', '-n', '-A', 'inet6']) except subprocess.CalledProcessError: logger.exception('Failed to get IPv6 routes', 'server', server_id=self.server.id, ) raise for line in routes_output.splitlines(): line_split = line.split() if len(line_split) < 7: continue try: route_network = ipaddress.IPv6Network(line_split[0]) except (ipaddress.AddressValueError, ValueError): continue if not default_interface6 and line_split[0] == '::/0': default_interface6 = line_split[6] routes6.append(( route_network, line_split[6] )) if not default_interface6: raise IptablesError( 'Failed to find default IPv6 network interface') if default_interface6 == 'lo': logger.error('Failed to find default IPv6 interface', 'server', server_id=self.server.id, ) routes6.reverse() route_all = self.server.is_route_all() if route_all: rules.append([ 'INPUT', '-i', self.interface, '-j', 'ACCEPT', ]) rules.append([ 'OUTPUT', '-o', self.interface, '-j', 'ACCEPT', ]) rules.append([ 'FORWARD', '-i', self.interface, '-j', 'ACCEPT', ]) if self.server.ipv6: if self.server.ipv6_firewall and \ settings.local.host.routed_subnet6: rules6.append([ 'INPUT', '-d', self.server.network6, '-m', 'conntrack', '--ctstate','RELATED,ESTABLISHED', '-j', 'ACCEPT', ]) rules6.append([ 'INPUT', '-d', self.server.network6, '-p', 'icmpv6', '-m', 'conntrack', '--ctstate', 'NEW', '-j', 'ACCEPT', ]) rules6.append([ 'INPUT', '-d', self.server.network6, '-j', 'DROP', ]) rules6.append([ 'FORWARD', '-d', self.server.network6, '-m', 'conntrack', '--ctstate', 'RELATED,ESTABLISHED', '-j', 'ACCEPT', ]) rules6.append([ 'FORWARD', '-d', self.server.network6, '-p', 'icmpv6', '-m', 'conntrack', '--ctstate', 'NEW', '-j', 'ACCEPT', ]) rules6.append([ 'FORWARD', '-d', self.server.network6, '-j', 'DROP', ]) else: rules6.append([ 'INPUT', '-d', self.server.network6, '-j', 'ACCEPT', ]) rules6.append([ 'FORWARD', '-d', self.server.network6, '-j', 'ACCEPT', ]) elif self.server.restrict_routes: if self.server.inter_client: rules.append([ 'INPUT', '-i', self.interface, '-d', self.server.network, '-j', 'ACCEPT', ]) rules6.append([ 'INPUT', '-i', self.interface, '-d', self.server.network6, '-j', 'ACCEPT', ]) rules.append([ 'OUTPUT', '-o', self.interface, '-s', self.server.network, '-j', 'ACCEPT', ]) rules6.append([ 'OUTPUT', '-o', self.interface, '-s', self.server.network6, '-j', 'ACCEPT', ]) rules.append([ 'FORWARD', '-i', self.interface, '-d', self.server.network, '-j', 'ACCEPT', ]) rules.append([ 'FORWARD', '-o', self.interface, '-s', self.server.network, '-j', 'ACCEPT', ]) rules6.append([ 'FORWARD', '-i', self.interface, '-d', self.server.network6, '-j', 'ACCEPT', ]) rules6.append([ 'FORWARD', '-o', self.interface, '-s', self.server.network6, '-j', 'ACCEPT', ]) else: server_addr = utils.get_network_gateway(self.server.network) server_addr6 = utils.get_network_gateway(self.server.network6) rules.append([ 'INPUT', '-i', self.interface, '-d', server_addr, '-j', 'ACCEPT', ]) rules6.append([ 'INPUT', '-i', self.interface, '-d', server_addr6, '-j', 'ACCEPT', ]) rules.append([ 'OUTPUT', '-o', self.interface, '-s', server_addr, '-j', 'ACCEPT', ]) rules6.append([ 'OUTPUT', '-o', self.interface, '-s', server_addr6, '-j', 'ACCEPT', ]) for route in self.server.get_routes( include_hidden=True, include_server_links=True, include_default=False, ): network_address = route['network'] is6 = ':' in network_address is_nat = route['nat'] if route['virtual_network']: continue if self.server.restrict_routes: if is6: rules6.append([ 'INPUT', '-i', self.interface, '-d', network_address, '-j', 'ACCEPT', ]) rules6.append([ 'OUTPUT', '-o', self.interface, '-s', network_address, '-j', 'ACCEPT', ]) rules6.append([ 'FORWARD', '-i', self.interface, '-d', network_address, '-j', 'ACCEPT', ]) if is_nat: rules6.append([ 'FORWARD', '-o', self.interface, '-m', 'conntrack', '--ctstate', 'RELATED,ESTABLISHED', '-s', network_address, '-j', 'ACCEPT', ]) else: rules6.append([ 'FORWARD', '-o', self.interface, '-s', network_address, '-j', 'ACCEPT', ]) else: rules.append([ 'INPUT', '-i', self.interface, '-d', network_address, '-j', 'ACCEPT', ]) rules.append([ 'OUTPUT', '-o', self.interface, '-s', network_address, '-j', 'ACCEPT', ]) rules.append([ 'FORWARD', '-i', self.interface, '-d', network_address, '-j', 'ACCEPT', ]) if is_nat: rules.append([ 'FORWARD', '-o', self.interface, '-m', 'conntrack', '--ctstate', 'RELATED,ESTABLISHED', '-s', network_address, '-j', 'ACCEPT', ]) else: rules.append([ 'FORWARD', '-o', self.interface, '-s', network_address, '-j', 'ACCEPT', ]) interfaces = set() interfaces6 = set() link_svr_networks = [] for link_svr in self.server.iter_links(fields=('_id', 'network', 'network_start', 'network_end', 'organizations', 'routes', 'links')): link_svr_networks.append(link_svr.network) for route in self.server.get_routes(include_hidden=True): if route['virtual_network'] or not route['nat']: continue network_address = route['network'] args_base = ['POSTROUTING', '-t', 'nat'] is6 = ':' in network_address if is6: network = network_address else: network = utils.parse_network(network_address)[0] network_obj = ipaddress.IPNetwork(network_address) if is6: interface = None for route_net, route_intf in routes6: if network_obj in route_net: interface = route_intf break if not interface: logger.info( 'Failed to find interface for local ' + \ 'IPv6 network route, using default route', 'server', server_id=self.server.id, network=network, ) interface = default_interface6 interfaces6.add(interface) else: interface = None for route_net, route_intf in routes: if network_obj in route_net: interface = route_intf break if not interface: logger.info( 'Failed to find interface for local ' + \ 'network route, using default route', 'server', server_id=self.server.id, network=network, ) interface = default_interface interfaces.add(interface) if network != '0.0.0.0' and network != '::/0': args_base += ['-d', network_address] args_base += [ '-o', interface, '-j', 'MASQUERADE', ] if is6: rules6.append(args_base + ['-s', self.server.network6]) else: rules.append(args_base + ['-s', self.server.network]) for link_svr_net in link_svr_networks: if ':' in link_svr_net: rules6.append(args_base + ['-s', link_svr_net]) else: rules.append(args_base + ['-s', link_svr_net]) if route_all: for interface in interfaces: rules.append([ 'FORWARD', '-i', interface, '-o', self.interface, '-m', 'state', '--state', 'ESTABLISHED,RELATED', '-j', 'ACCEPT', ]) rules.append([ 'FORWARD', '-i', self.interface, '-o', interface, '-m', 'state', '--state', 'ESTABLISHED,RELATED', '-j', 'ACCEPT', ]) for interface in interfaces6: if self.server.ipv6 and self.server.ipv6_firewall and \ settings.local.host.routed_subnet6 and \ interface == default_interface6: continue rules6.append([ 'FORWARD', '-i', interface, '-o', self.interface, '-m', 'state', '--state', 'ESTABLISHED,RELATED', '-j', 'ACCEPT', ]) rules6.append([ 'FORWARD', '-i', self.interface, '-o', interface, '-m', 'state', '--state', 'ESTABLISHED,RELATED', '-j', 'ACCEPT', ]) extra_args = [ '-m', 'comment', '--comment', 'pritunl_%s' % self.server.id, ] if settings.local.iptables_wait: extra_args.append('--wait') rules = [x + extra_args for x in rules] rules6 = [x + extra_args for x in rules6] return rules, rules6
def generate_ovpn_conf(self): logger.debug('Generating server ovpn conf', 'server', server_id=self.server.id, ) if not self.server.primary_organization or \ not self.server.primary_user: self.server.create_primary_user() if self.server.primary_organization not in self.server.organizations: self.server.remove_primary_user() self.server.create_primary_user() primary_org = organization.get_by_id(self.server.primary_organization) if not primary_org: self.server.create_primary_user() primary_org = organization.get_by_id( id=self.server.primary_organization) self.primary_user = primary_org.get_user(self.server.primary_user) if not self.primary_user: self.server.create_primary_user() primary_org = organization.get_by_id( id=self.server.primary_organization) self.primary_user = primary_org.get_user(self.server.primary_user) gateway = utils.get_network_gateway(self.server.network) gateway6 = utils.get_network_gateway(self.server.network6) push = '' for route in self.server.get_routes(include_default=False): if route['virtual_network']: continue network = route['network'] if not route.get('network_link'): if ':' in network: push += 'push "route-ipv6 %s "\n' % network else: push += 'push "route %s %s"\n' % utils.parse_network( network) else: if ':' in network: push += 'route-ipv6 %s %s\n' % (network, gateway6) else: push += 'route %s %s %s\n' % (utils.parse_network( network) + (gateway,)) for link_svr in self.server.iter_links(fields=( '_id', 'network', 'local_networks', 'network_start', 'network_end', 'organizations', 'routes', 'links')): if self.server.id < link_svr.id: for route in link_svr.get_routes(include_default=False): network = route['network'] if ':' in network: push += 'route-ipv6 %s %s\n' % ( network, gateway6) else: push += 'route %s %s %s\n' % (utils.parse_network( network) + (gateway,)) if self.server.network_mode == BRIDGE: host_int_data = self.host_interface_data host_address = host_int_data['address'] host_netmask = host_int_data['netmask'] server_line = 'server-bridge %s %s %s %s' % ( host_address, host_netmask, self.server.network_start, self.server.network_end, ) else: server_line = 'server %s %s' % utils.parse_network( self.server.network) if self.server.ipv6: server_line += '\nserver-ipv6 ' + self.server.network6 server_conf = OVPN_INLINE_SERVER_CONF % ( self.server.port, self.server.protocol + ('6' if self.server.ipv6 else ''), self.interface, server_line, self.management_socket_path, self.server.max_clients, self.server.ping_interval, self.server.ping_timeout + 20, self.server.ping_interval, self.server.ping_timeout, CIPHERS[self.server.cipher], HASHES[self.server.hash], 4 if self.server.debug else 1, 8 if self.server.debug else 3, ) if self.server.bind_address: server_conf += 'local %s\n' % self.server.bind_address if self.server.inter_client: server_conf += 'client-to-client\n' if self.server.multi_device: server_conf += 'duplicate-cn\n' if self.server.protocol == 'udp': server_conf += 'replay-window 128\n' # Pritunl v0.10.x did not include comp-lzo in client conf # if lzo_compression is adaptive dont include comp-lzo in server conf if self.server.lzo_compression == ADAPTIVE: pass elif self.server.lzo_compression: server_conf += 'comp-lzo yes\npush "comp-lzo yes"\n' else: server_conf += 'comp-lzo no\npush "comp-lzo no"\n' server_conf += JUMBO_FRAMES[self.server.jumbo_frames] if push: server_conf += push if self.server.debug: self.server.output.push_message('Server conf:') for conf_line in server_conf.split('\n'): if conf_line: self.server.output.push_message(' ' + conf_line) server_conf += '<ca>\n%s\n</ca>\n' % self.server.ca_certificate if self.server.tls_auth: server_conf += 'key-direction 0\n<tls-auth>\n%s\n</tls-auth>\n' % ( self.server.tls_auth_key) server_conf += '<cert>\n%s\n</cert>\n' % utils.get_cert_block( self.primary_user.certificate) server_conf += '<key>\n%s\n</key>\n' % self.primary_user.private_key server_conf += '<dh>\n%s\n</dh>\n' % self.server.dh_params with open(self.ovpn_conf_path, 'w') as ovpn_conf: os.chmod(self.ovpn_conf_path, 0600) ovpn_conf.write(server_conf)
def generate_iptables_rules(self): rules = [] rules6 = [] try: routes_output = utils.check_output_logged(['route', '-n']) except subprocess.CalledProcessError: logger.exception('Failed to get IP routes', 'server', server_id=self.server.id, ) raise routes = {} for line in routes_output.splitlines(): line_split = line.split() if len(line_split) < 8 or not re.match(IP_REGEX, line_split[0]): continue if line_split[0] not in routes: routes[line_split[0]] = line_split[7] if '0.0.0.0' not in routes: raise IptablesError('Failed to find default network interface') default_interface = routes['0.0.0.0'] routes6 = {} default_interface6 = None if self.server.ipv6: try: routes_output = utils.check_output_logged( ['route', '-n', '-A', 'inet6']) except subprocess.CalledProcessError: logger.exception('Failed to get IPv6 routes', 'server', server_id=self.server.id, ) raise for line in routes_output.splitlines(): line_split = line.split() if len(line_split) < 7: continue try: ipaddress.IPv6Network(line_split[0]) except (ipaddress.AddressValueError, ValueError): continue if line_split[0] not in routes6: routes6[line_split[0]] = line_split[6] if '::/0' not in routes6: raise IptablesError( 'Failed to find default IPv6 network interface') default_interface6 = routes6['::/0'] if default_interface6 == 'lo': logger.error('Failed to find default IPv6 interface', 'server', server_id=self.server.id, ) rules.append(['INPUT', '-i', self.interface, '-j', 'ACCEPT']) rules.append(['FORWARD', '-i', self.interface, '-j', 'ACCEPT']) if self.server.ipv6: if self.server.ipv6_firewall and \ settings.local.host.routed_subnet6: rules6.append( ['INPUT', '-d', self.server.network6, '-j', 'DROP']) rules6.append( ['INPUT', '-d', self.server.network6, '-m', 'conntrack', '--ctstate','RELATED,ESTABLISHED', '-j', 'ACCEPT']) rules6.append( ['INPUT', '-d', self.server.network6, '-p', 'icmpv6', '-m', 'conntrack', '--ctstate', 'NEW', '-j', 'ACCEPT']) rules6.append( ['FORWARD', '-d', self.server.network6, '-j', 'DROP']) rules6.append( ['FORWARD', '-d', self.server.network6, '-m', 'conntrack', '--ctstate', 'RELATED,ESTABLISHED', '-j', 'ACCEPT']) rules6.append( ['FORWARD', '-d', self.server.network6, '-p', 'icmpv6', '-m', 'conntrack', '--ctstate', 'NEW', '-j', 'ACCEPT']) else: rules6.append( ['INPUT', '-d', self.server.network6, '-j', 'ACCEPT']) rules6.append( ['FORWARD', '-d', self.server.network6, '-j', 'ACCEPT']) interfaces = set() interfaces6 = set() other_networks = [] if self.server.mode == ALL_TRAFFIC and \ self.server.network_mode != BRIDGE: other_networks = ['0.0.0.0/0'] if self.server.ipv6 and not settings.local.host.routed_subnet6: other_networks.append('::/0') link_svr_networks = [] for link_svr in self.server.iter_links(fields=( '_id', 'network', 'network_start', 'network_end')): link_svr_networks.append(link_svr.network) if settings.vpn.nat_routes: for network_address in self.server.local_networks or \ other_networks: args_base = ['POSTROUTING', '-t', 'nat'] is6 = ':' in network_address if is6: network = network_address else: network = utils.parse_network(network_address)[0] if is6: if network not in routes6: logger.info( 'Failed to find interface for local ' + \ 'IPv6 network route, using default route', 'server', server_id=self.server.id, network=network, ) interface = default_interface6 else: interface = routes6[network] interfaces6.add(interface) else: if network not in routes: logger.info( 'Failed to find interface for local ' + \ 'network route, using default route', 'server', server_id=self.server.id, network=network, ) interface = default_interface else: interface = routes[network] interfaces.add(interface) if network != '0.0.0.0' and network != '::/0': args_base += ['-d', network_address] args_base += [ '-o', interface, '-j', 'MASQUERADE', ] if is6: rules6.append(args_base + ['-s', self.server.network6]) else: rules.append(args_base + ['-s', self.server.network]) for link_svr_net in link_svr_networks: if ':' in link_svr_net: rules6.append(args_base + ['-s', link_svr_net]) else: rules.append(args_base + ['-s', link_svr_net]) for interface in interfaces: rules.append([ 'FORWARD', '-i', interface, '-o', self.interface, '-m', 'state', '--state', 'ESTABLISHED,RELATED', '-j', 'ACCEPT', ]) rules.append([ 'FORWARD', '-i', self.interface, '-o', interface, '-m', 'state', '--state', 'ESTABLISHED,RELATED', '-j', 'ACCEPT', ]) for interface in interfaces6: if self.server.ipv6 and self.server.ipv6_firewall and \ settings.local.host.routed_subnet6 and \ interface == default_interface6: continue rules6.append([ 'FORWARD', '-i', interface, '-o', self.interface, '-m', 'state', '--state', 'ESTABLISHED,RELATED', '-j', 'ACCEPT', ]) rules6.append([ 'FORWARD', '-i', self.interface, '-o', interface, '-m', 'state', '--state', 'ESTABLISHED,RELATED', '-j', 'ACCEPT', ]) extra_args = [ '-m', 'comment', '--comment', 'pritunl_%s' % self.server.id, ] if settings.local.iptables_wait: extra_args.append('--wait') rules = [x + extra_args for x in rules] rules6 = [x + extra_args for x in rules6] return rules, rules6
def generate_ovpn_conf(self): from pritunl.server.utils import get_by_id logger.debug('Generating server ovpn conf. %r' % { 'server_id': self.server.id, }) if not self.server.primary_organization or \ not self.server.primary_user: self.server.create_primary_user() primary_org = organization.get_by_id(self.server.primary_organization) if not primary_org: self.server.create_primary_user() primary_org = organization.get_by_id( id=self.server.primary_organization) self.primary_user = primary_org.get_user(self.server.primary_user) if not self.primary_user: self.server.create_primary_user() primary_org = organization.get_by_id( id=self.server.primary_organization) self.primary_user = primary_org.get_user(self.server.primary_user) with open(self.auth_log_path, 'w') as auth_log: os.chmod(self.auth_log_path, 0600) auth_host = settings.conf.bind_addr if auth_host == '0.0.0.0': auth_host = 'localhost' for script, script_path in ( (TLS_VERIFY_SCRIPT, self.tls_verify_path), (USER_PASS_VERIFY_SCRIPT, self.user_pass_verify_path), (CLIENT_CONNECT_SCRIPT, self.client_connect_path), (CLIENT_DISCONNECT_SCRIPT, self.client_disconnect_path), ): with open(script_path, 'w') as script_file: os.chmod(script_path, 0755) # TODO script_file.write(script % ( settings.app.server_api_key, self.auth_log_path, 'https' if settings.conf.ssl else 'http', auth_host, settings.conf.port, self.server.id, )) push = '' if self.server.mode == LOCAL_TRAFFIC: for network in self.server.local_networks: push += 'push "route %s %s"\n' % utils.parse_network(network) elif self.server.mode == VPN_TRAFFIC: pass else: push += 'push "redirect-gateway"\n' for dns_server in self.server.dns_servers: push += 'push "dhcp-option DNS %s"\n' % dns_server if self.server.search_domain: push += 'push "dhcp-option DOMAIN %s"\n' % ( self.server.search_domain) for link_doc in self.server.links: link_svr = get_by_id(link_doc['server_id']) push += 'push "route %s %s"\n' % utils.parse_network( link_svr.network) for local_network in link_svr.local_networks: push += 'push "route %s %s"\n' % utils.parse_network( local_network) server_conf = OVPN_INLINE_SERVER_CONF % ( self.server.port, self.server.protocol, self.interface, self.tls_verify_path, self.client_connect_path, self.client_disconnect_path, '%s %s' % utils.parse_network(self.server.network), CIPHERS[self.server.cipher], self.ovpn_status_path, 4 if self.server.debug else 1, 8 if self.server.debug else 3, ) if self.server.bind_address: server_conf += 'local %s\n' % self.server.bind_address if self.server.otp_auth: server_conf += 'auth-user-pass-verify %s via-file\n' % ( self.user_pass_verify_path) # Pritunl v0.10.x did not include comp-lzo in client conf # if lzo_compression is adaptive dont include comp-lzo in server conf if self.server.lzo_compression == ADAPTIVE: pass elif self.server.lzo_compression: server_conf += 'comp-lzo yes\npush "comp-lzo yes"\n' else: server_conf += 'comp-lzo no\npush "comp-lzo no"\n' if self.server.mode in (LOCAL_TRAFFIC, VPN_TRAFFIC): server_conf += 'client-to-client\n' server_conf += JUMBO_FRAMES[self.server.jumbo_frames] if push: server_conf += push server_conf += '<ca>\n%s\n</ca>\n' % utils.get_cert_block( self.server.ca_certificate) server_conf += '<cert>\n%s\n</cert>\n' % utils.get_cert_block( self.primary_user.certificate) server_conf += '<key>\n%s\n</key>\n' % self.primary_user.private_key server_conf += '<dh>\n%s\n</dh>\n' % self.server.dh_params with open(self.ovpn_conf_path, 'w') as ovpn_conf: os.chmod(self.ovpn_conf_path, 0600) ovpn_conf.write(server_conf)
def allow_client(self, client, org, user): client_id = client['client_id'] key_id = client['key_id'] org_id = client['org_id'] user_id = 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') remote_ip = client.get('remote_ip') address_dynamic = False client_conf = self.generate_client_conf(user) virt_address = self.server.get_ip_addr(org_id, user_id) if not self.server.multi_device: for client in self.clients.find({'user_id': user_id}): self.instance_com.client_kill(client['id']) elif virt_address and self.clients.find({'virt_address': virt_address }): 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 not self.clients.find({'virt_address': ip_addr}): virt_address = ip_addr address_dynamic = True break if not virt_address: self.instance_com.send_client_deny(client_id, key_id, 'Unable to assign ip address') return virt_address6 = self.server.ip4to6(virt_address) self.clients.insert({ 'id': client_id, 'org_id': org_id, 'org_name': org.name, 'user_id': user_id, 'user_name': user.name, 'user_type': user.type, 'device_id': device_id, 'device_name': device_name, 'platform': platform, 'mac_addr': mac_addr, 'otp_code': None, 'virt_address': virt_address, 'virt_address6': virt_address6, 'real_address': remote_ip, 'address_dynamic': address_dynamic, }) client_conf += 'ifconfig-push %s %s\n' % utils.parse_network( virt_address) if self.server.ipv6: client_conf += 'ifconfig-ipv6-push %s\n' % virt_address6 if self.server.debug: self.instance_com.push_output('Client conf %s:' % user_id) for conf_line in client_conf.split('\n'): if conf_line: self.instance_com.push_output(' ' + conf_line) self.instance_com.send_client_auth(client_id, key_id, client_conf)
def client_connect(self, client): from pritunl.server.utils import get_by_id try: client_id = client['client_id'] org_id = bson.ObjectId(client['org_id']) user_id = bson.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', 'type', 'disabled', 'otp_secret']) if not user: self.send_client_deny(client, 'User is not valid') 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 = '' link_svr_id = None for link_doc in self.server.links: if link_doc['user_id'] == user.id: link_svr_id = link_doc['server_id'] break if link_svr_id: link_svr = get_by_id(link_svr_id, fields=['_id', 'network', 'local_networks']) client_conf += 'iroute %s %s\n' % utils.parse_network( link_svr.network) for local_network in link_svr.local_networks: client_conf += 'iroute %s %s\n' % utils.parse_network( local_network) 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) 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')
def allow_client(self, client_data, org, user, reauth=False): client_id = client_data['client_id'] key_id = client_data['key_id'] org_id = client_data['org_id'] user_id = client_data['user_id'] device_id = client_data.get('device_id') device_name = client_data.get('device_name') platform = client_data.get('platform') mac_addr = client_data.get('mac_addr') remote_ip = client_data.get('remote_ip') address_dynamic = False if reauth: doc = self.clients.find_id(client_id) if not doc: self.instance_com.send_client_deny( client_id, key_id, 'Client connection info timed out') return virt_address = doc['virt_address'] virt_address6 = doc['virt_address6'] else: user.audit_event( 'user_connection', 'User connected to "%s"' % self.server.name, remote_addr=remote_ip, ) virt_address = self.server.get_ip_addr(org_id, user_id) if not virt_address: logger.error( 'User missing ip address', 'clients', server_id=self.server.id, instance_id=self.instance.id, user_id=user.id, multi_device=self.server.multi_device, network=self.server.network, user_count=self.server.user_count, ) if not self.server.multi_device: for clnt in self.clients.find({'user_id': user_id}): time.sleep(3) self.instance_com.client_kill(clnt['id']) elif virt_address: if mac_addr: for clnt in self.clients.find({ 'user_id': user_id, 'mac_addr': mac_addr, }): self.instance_com.client_kill(clnt['id']) if self.clients.find({'virt_address': virt_address}): 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 not self.clients.find({'virt_address': ip_addr}): virt_address = ip_addr address_dynamic = True break if not virt_address: logger.error( 'Unable to assign ip address, pool full', 'clients', server_id=self.server.id, instance_id=self.instance.id, user_id=user.id, multi_device=self.server.multi_device, network=self.server.network, user_count=self.server.user_count, ) if not virt_address: self.instance_com.send_client_deny( client_id, key_id, 'Unable to assign ip address') return virt_address6 = self.server.ip4to6(virt_address) dns_servers = [] if user.dns_servers: for dns_server in user.dns_servers: if dns_server == '127.0.0.1': dns_server = virt_address dns_servers.append(dns_server) rules, rules6 = self.generate_iptables_rules( user, virt_address, virt_address6) self.clients.insert({ 'id': client_id, 'org_id': org_id, 'org_name': org.name, 'user_id': user_id, 'user_name': user.name, 'user_type': user.type, 'dns_servers': dns_servers, 'dns_suffix': user.dns_suffix, 'device_id': device_id, 'device_name': device_name, 'platform': platform, 'mac_addr': mac_addr, 'virt_address': virt_address, 'virt_address6': virt_address6, 'real_address': remote_ip, 'address_dynamic': address_dynamic, 'iptables_rules': rules, 'ip6tables_rules': rules6, }) if user.type == CERT_CLIENT: host.global_clients.insert({ 'instance_id': self.instance.id, 'client_id': client_id, }) client_conf = self.generate_client_conf(platform, client_id, virt_address, user, reauth) client_conf += 'ifconfig-push %s %s\n' % utils.parse_network( virt_address) if self.server.ipv6: client_conf += 'ifconfig-ipv6-push %s\n' % virt_address6 if self.server.debug: self.instance_com.push_output('Client conf %s:' % user_id) for conf_line in client_conf.split('\n'): if conf_line: self.instance_com.push_output(' ' + conf_line) self.instance_com.send_client_auth(client_id, key_id, client_conf)
def allow_client(self, client_data, org, user, reauth=False): client_id = client_data['client_id'] key_id = client_data['key_id'] org_id = client_data['org_id'] user_id = client_data['user_id'] device_id = client_data.get('device_id') device_name = client_data.get('device_name') platform = client_data.get('platform') mac_addr = client_data.get('mac_addr') remote_ip = client_data.get('remote_ip') address_dynamic = False if reauth: doc = self.clients.find_id(client_id) if not doc: self.instance_com.send_client_deny(client_id, key_id, 'Client connection info timed out') return virt_address = doc['virt_address'] virt_address6 = doc['virt_address6'] else: user.audit_event( 'user_connection', 'User connected to "%s"' % self.server.name, remote_addr=remote_ip, ) monitoring.insert_point('user_connections', { 'host': settings.local.host.name, 'server': self.server.name, }, { 'user': user.name, 'platform': platform, 'remote_ip': remote_ip, }) virt_address = self.server.get_ip_addr(org_id, user_id) if not virt_address: logger.error('User missing ip address', 'clients', server_id=self.server.id, instance_id=self.instance.id, user_id=user.id, multi_device=self.server.multi_device, network=self.server.network, user_count=self.server.user_count, ) if not self.server.multi_device: for clnt in self.clients.find({'user_id': user_id}): time.sleep(3) self.instance_com.client_kill(clnt['id']) elif virt_address: if mac_addr: for clnt in self.clients.find({ 'user_id': user_id, 'mac_addr': mac_addr, }): self.instance_com.client_kill(clnt['id']) if self.clients.find({'virt_address': virt_address}): 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 not self.clients.find({'virt_address': ip_addr}): virt_address = ip_addr address_dynamic = True break if not virt_address: logger.error('Unable to assign ip address, pool full', 'clients', server_id=self.server.id, instance_id=self.instance.id, user_id=user.id, multi_device=self.server.multi_device, network=self.server.network, user_count=self.server.user_count, ) if not virt_address: self.instance_com.send_client_deny(client_id, key_id, 'Unable to assign ip address') return virt_address6 = self.server.ip4to6(virt_address) dns_servers = [] if user.dns_servers: for dns_server in user.dns_servers: if dns_server == '127.0.0.1': dns_server = virt_address dns_servers.append(dns_server) rules, rules6 = self.generate_iptables_rules( user, virt_address, virt_address6) self.clients.insert({ 'id': client_id, 'org_id': org_id, 'org_name': org.name, 'user_id': user_id, 'user_name': user.name, 'user_type': user.type, 'dns_servers': dns_servers, 'dns_suffix': user.dns_suffix, 'device_id': device_id, 'device_name': device_name, 'platform': platform, 'mac_addr': mac_addr, 'virt_address': virt_address, 'virt_address6': virt_address6, 'real_address': remote_ip, 'address_dynamic': address_dynamic, 'iptables_rules': rules, 'ip6tables_rules': rules6, }) if user.type == CERT_CLIENT: plugins.event( 'user_connected', host_id=settings.local.host_id, server_id=self.server.id, org_id=org.id, user_id=user.id, host_name=settings.local.host.name, server_name=self.server.name, org_name=org.name, user_name=user.name, platform=platform, device_id=device_id, device_name=device_name, virtual_ip=virt_address, virtual_ip6=virt_address6, remote_ip=remote_ip, mac_addr=mac_addr, ) host.global_clients.insert({ 'instance_id': self.instance.id, 'client_id': client_id, }) client_conf = self.generate_client_conf(platform, client_id, virt_address, user, reauth) client_conf += 'ifconfig-push %s %s\n' % utils.parse_network( virt_address) if self.server.ipv6: client_conf += 'ifconfig-ipv6-push %s\n' % virt_address6 if self.server.debug: self.instance_com.push_output('Client conf %s:' % user_id) for conf_line in client_conf.split('\n'): if conf_line: self.instance_com.push_output(' ' + conf_line) self.instance_com.send_client_auth(client_id, key_id, client_conf)
def generate_ovpn_conf(self): logger.debug('Generating server ovpn conf', 'server', server_id=self.server.id, ) if not self.server.primary_organization or \ not self.server.primary_user: self.server.create_primary_user() if self.server.primary_organization not in self.server.organizations: self.server.remove_primary_user() self.server.create_primary_user() primary_org = organization.get_by_id(self.server.primary_organization) if not primary_org: self.server.create_primary_user() primary_org = organization.get_by_id( id=self.server.primary_organization) self.primary_user = primary_org.get_user(self.server.primary_user) if not self.primary_user: self.server.create_primary_user() primary_org = organization.get_by_id( id=self.server.primary_organization) self.primary_user = primary_org.get_user(self.server.primary_user) gateway = utils.get_network_gateway(self.server.network) gateway6 = utils.get_network_gateway(self.server.network6) push = '' routes = [] for route in self.server.get_routes(include_default=False): routes.append(route['network']) if route['virtual_network']: continue network = route['network'] if not route.get('network_link'): if ':' in network: push += 'push "route-ipv6 %s "\n' % network else: push += 'push "route %s %s"\n' % utils.parse_network( network) else: if ':' in network: push += 'route-ipv6 %s %s\n' % (network, gateway6) else: push += 'route %s %s %s\n' % (utils.parse_network( network) + (gateway,)) for link_svr in self.server.iter_links(fields=( '_id', 'network', 'local_networks', 'network_start', 'network_end', 'organizations', 'routes', 'links', 'ipv6')): if self.server.id < link_svr.id: for route in link_svr.get_routes(include_default=False): network = route['network'] if ':' in network: push += 'route-ipv6 %s %s\n' % ( network, gateway6) else: push += 'route %s %s %s\n' % (utils.parse_network( network) + (gateway,)) if self.server.network_mode == BRIDGE: host_int_data = self.host_interface_data host_address = host_int_data['address'] host_netmask = host_int_data['netmask'] server_line = 'server-bridge %s %s %s %s' % ( host_address, host_netmask, self.server.network_start, self.server.network_end, ) else: server_line = 'server %s %s' % utils.parse_network( self.server.network) if self.server.ipv6: server_line += '\nserver-ipv6 ' + self.server.network6 if self.server.protocol == 'tcp': if self.server.ipv6 or settings.vpn.ipv6: protocol = 'tcp6-server' else: protocol = 'tcp-server' elif self.server.protocol == 'udp': if self.server.ipv6 or settings.vpn.ipv6: protocol = 'udp6' else: protocol = 'udp' else: raise ValueError('Unknown protocol') server_conf = OVPN_INLINE_SERVER_CONF % ( self.server.port, protocol, self.interface, server_line, self.management_socket_path, self.server.max_clients, self.server.ping_interval, self.server.ping_timeout + 20, self.server.ping_interval, self.server.ping_timeout, CIPHERS[self.server.cipher], HASHES[self.server.hash], 4 if self.server.debug else 1, 8 if self.server.debug else 3, ) if self.server.bind_address: server_conf += 'local %s\n' % self.server.bind_address if self.server.inter_client: server_conf += 'client-to-client\n' if self.server.multi_device: server_conf += 'duplicate-cn\n' if self.server.protocol == 'udp': server_conf += 'replay-window 128\n' # Pritunl v0.10.x did not include comp-lzo in client conf # if lzo_compression is adaptive dont include comp-lzo in server conf if self.server.lzo_compression == ADAPTIVE: pass elif self.server.lzo_compression: server_conf += 'comp-lzo yes\npush "comp-lzo yes"\n' else: server_conf += 'comp-lzo no\npush "comp-lzo no"\n' server_conf += JUMBO_FRAMES[self.server.jumbo_frames] if push: server_conf += push if self.server.debug: self.server.output.push_message('Server conf:') for conf_line in server_conf.split('\n'): if conf_line: self.server.output.push_message(' ' + conf_line) if settings.local.sub_plan == 'enterprise': returns = plugins.caller( 'server_config', 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, max_clients=self.server.max_clients, replica_count=self.server.replica_count, dns_mapping=self.server.dns_mapping, debug=self.server.debug, routes=routes, ) if returns: for return_val in returns: if not return_val: continue server_conf += return_val.strip() + '/n' server_conf += '<ca>\n%s\n</ca>\n' % self.server.ca_certificate if self.server.tls_auth: server_conf += 'key-direction 0\n<tls-auth>\n%s\n</tls-auth>\n' % ( self.server.tls_auth_key) server_conf += '<cert>\n%s\n</cert>\n' % utils.get_cert_block( self.primary_user.certificate) server_conf += '<key>\n%s\n</key>\n' % self.primary_user.private_key server_conf += '<dh>\n%s\n</dh>\n' % self.server.dh_params with open(self.ovpn_conf_path, 'w') as ovpn_conf: os.chmod(self.ovpn_conf_path, 0600) ovpn_conf.write(server_conf)
def generate_ovpn_conf(self): logger.debug( 'Generating server ovpn conf', 'server', server_id=self.server.id, ) if not self.server.primary_organization or \ not self.server.primary_user: self.server.create_primary_user() if self.server.primary_organization not in self.server.organizations: self.server.remove_primary_user() self.server.create_primary_user() primary_org = organization.get_by_id(self.server.primary_organization) if not primary_org: self.server.create_primary_user() primary_org = organization.get_by_id( id=self.server.primary_organization) self.primary_user = primary_org.get_user(self.server.primary_user) if not self.primary_user: self.server.create_primary_user() primary_org = organization.get_by_id( id=self.server.primary_organization) self.primary_user = primary_org.get_user(self.server.primary_user) push = '' if self.server.mode == LOCAL_TRAFFIC: for network in self.server.local_networks: push += 'push "route %s %s"\n' % utils.parse_network(network) elif self.server.mode == VPN_TRAFFIC: pass for link_svr in self.server.iter_links(fields=('_id', 'network', 'local_networks')): if self.server.id < link_svr.id: gateway = utils.get_network_gateway(self.server.network) push += 'route %s %s %s\n' % ( utils.parse_network(link_svr.network) + (gateway, )) for local_network in link_svr.local_networks: push += 'route %s %s %s\n' % ( utils.parse_network(local_network) + (gateway, )) server_conf = OVPN_INLINE_SERVER_CONF % ( self.server.port, self.server.protocol, self.interface, '%s %s' % utils.parse_network(self.server.network), self.management_socket_path, CIPHERS[self.server.cipher], 4 if self.server.debug else 1, 8 if self.server.debug else 3, ) if self.server.bind_address: server_conf += 'local %s\n' % self.server.bind_address if self.server.multi_device: server_conf += 'duplicate-cn\n' # Pritunl v0.10.x did not include comp-lzo in client conf # if lzo_compression is adaptive dont include comp-lzo in server conf if self.server.lzo_compression == ADAPTIVE: pass elif self.server.lzo_compression: server_conf += 'comp-lzo yes\npush "comp-lzo yes"\n' else: server_conf += 'comp-lzo no\npush "comp-lzo no"\n' server_conf += JUMBO_FRAMES[self.server.jumbo_frames] if push: server_conf += push if self.server.debug: self.server.output.push_message('Server conf:') for conf_line in server_conf.split('\n'): if conf_line: self.server.output.push_message(' ' + conf_line) server_conf += '<ca>\n%s\n</ca>\n' % self.server.ca_certificate if self.server.tls_auth: server_conf += 'key-direction 0\n<tls-auth>\n%s\n</tls-auth>\n' % ( self.server.tls_auth_key) server_conf += '<cert>\n%s\n</cert>\n' % utils.get_cert_block( self.primary_user.certificate) server_conf += '<key>\n%s\n</key>\n' % self.primary_user.private_key server_conf += '<dh>\n%s\n</dh>\n' % self.server.dh_params with open(self.ovpn_conf_path, 'w') as ovpn_conf: os.chmod(self.ovpn_conf_path, 0600) ovpn_conf.write(server_conf)
def generate_client_conf(self, platform, client_id, virt_address, user, reauth): from pritunl.server.utils import get_by_id client_conf = '' if user.link_server_id: link_usr_svr = get_by_id(user.link_server_id, fields=('_id', 'network', 'network_start', 'network_end', 'local_networks')) client_conf += 'iroute %s %s\n' % utils.parse_network( link_usr_svr.network) for local_network in link_usr_svr.local_networks: if ':' in local_network: client_conf += 'iroute-ipv6 %s\n' % local_network else: client_conf += 'iroute %s %s\n' % utils.parse_network( local_network) else: if self.server.mode == ALL_TRAFFIC: if platform == 'ios': client_conf += 'push "route 0.0.0.0 128.0.0.0"\n' client_conf += 'push "route 128.0.0.0 128.0.0.0"\n' else: client_conf += 'push "redirect-gateway def1"\n' if self.server.ipv6: if platform != 'ios': client_conf += 'push "redirect-gateway-ipv6 def1"\n' client_conf += 'push "route-ipv6 2000::/3"\n' if self.server.dns_mapping: client_conf += 'push "dhcp-option DNS %s"\n' % ( utils.get_network_gateway(self.server.network)) for dns_server in self.server.dns_servers: client_conf += 'push "dhcp-option DNS %s"\n' % dns_server if self.server.search_domain: client_conf += 'push "dhcp-option DOMAIN %s"\n' % ( self.server.search_domain) client_conf += 'push "ip-win32 dynamic 0 3600"\n' network_links = user.get_network_links() for network_link in network_links: if self.reserve_iroute(client_id, network_link, True): if ':' in network_link: client_conf += 'iroute-ipv6 %s\n' % network_link else: client_conf += 'iroute %s %s\n' % \ utils.parse_network(network_link) if network_links and not reauth: thread = threading.Thread(target=self.iroute_ping_thread, args=(client_id, virt_address.split('/')[0])) thread.daemon = True thread.start() for network_link in self.server.network_links: if ':' in network_link: client_conf += 'push "route-ipv6 %s"\n' % network_link else: client_conf += 'push "route %s %s"\n' % ( utils.parse_network(network_link)) for link_svr in self.server.iter_links(fields=( '_id', 'network', 'local_networks', 'network_start', 'network_end')): client_conf += 'push "route %s %s"\n' % utils.parse_network( link_svr.network) for local_network in link_svr.local_networks: if ':' in local_network: client_conf += 'push "route-ipv6 %s"\n' % ( local_network) else: client_conf += 'push "route %s %s"\n' % ( utils.parse_network(local_network)) return client_conf
def allow_client(self, client, org, user, reauth=False): client_id = client['client_id'] key_id = client['key_id'] org_id = client['org_id'] user_id = 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') remote_ip = client.get('remote_ip') address_dynamic = False if reauth: doc = self.clients.find_id(client_id) if not doc: self.instance_com.send_client_deny(client_id, key_id, 'Client connection info timed out') return virt_address = doc['virt_address'] virt_address6 = doc['virt_address6'] else: user.audit_event('user_connection', 'User connected to "%s"' % self.server.name, remote_addr=remote_ip, ) virt_address = self.server.get_ip_addr(org_id, user_id) if not self.server.multi_device: for client in self.clients.find({'user_id': user_id}): self.instance_com.client_kill(client['id']) elif virt_address: if mac_addr: for client in self.clients.find({'mac_addr': mac_addr}): self.instance_com.client_kill(client['id']) if self.clients.find({'virt_address': virt_address}): 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 not self.clients.find({'virt_address': ip_addr}): virt_address = ip_addr address_dynamic = True break if not virt_address: self.instance_com.send_client_deny(client_id, key_id, 'Unable to assign ip address') return virt_address6 = self.server.ip4to6(virt_address) dns_servers = [] if user.dns_servers: for dns_server in user.dns_servers: if dns_server == '127.0.0.1': dns_server = virt_address dns_servers.append(dns_server) self.clients.insert({ 'id': client_id, 'org_id': org_id, 'org_name': org.name, 'user_id': user_id, 'user_name': user.name, 'user_type': user.type, 'dns_servers': dns_servers, 'dns_suffix': user.dns_suffix, 'device_id': device_id, 'device_name': device_name, 'platform': platform, 'mac_addr': mac_addr, 'otp_code': None, 'virt_address': virt_address, 'virt_address6': virt_address6, 'real_address': remote_ip, 'address_dynamic': address_dynamic, }) client_conf = self.generate_client_conf(platform, client_id, virt_address, user, reauth) client_conf += 'ifconfig-push %s %s\n' % utils.parse_network( virt_address) if self.server.ipv6: client_conf += 'ifconfig-ipv6-push %s\n' % virt_address6 if self.server.debug: self.instance_com.push_output('Client conf %s:' % user_id) for conf_line in client_conf.split('\n'): if conf_line: self.instance_com.push_output(' ' + conf_line) self.instance_com.send_client_auth(client_id, key_id, client_conf)
def generate_ovpn_conf(self): from pritunl.server.utils import get_by_id logger.debug( 'Generating server ovpn conf', 'server', server_id=self.server.id, ) if not self.server.primary_organization or \ not self.server.primary_user: self.server.create_primary_user() if self.server.primary_organization not in self.server.organizations: self.server.remove_primary_user() self.server.create_primary_user() primary_org = organization.get_by_id(self.server.primary_organization) if not primary_org: self.server.create_primary_user() primary_org = organization.get_by_id( id=self.server.primary_organization) self.primary_user = primary_org.get_user(self.server.primary_user) if not self.primary_user: self.server.create_primary_user() primary_org = organization.get_by_id( id=self.server.primary_organization) self.primary_user = primary_org.get_user(self.server.primary_user) push = '' if self.server.mode == LOCAL_TRAFFIC: for network in self.server.local_networks: push += 'push "route %s %s"\n' % utils.parse_network(network) elif self.server.mode == VPN_TRAFFIC: pass else: push += 'push "redirect-gateway"\n' for dns_server in self.server.dns_servers: push += 'push "dhcp-option DNS %s"\n' % dns_server if self.server.search_domain: push += 'push "dhcp-option DOMAIN %s"\n' % ( self.server.search_domain) for link_doc in self.server.links: link_svr = get_by_id(link_doc['server_id']) push += 'push "route %s %s"\n' % utils.parse_network( link_svr.network) for local_network in link_svr.local_networks: push += 'push "route %s %s"\n' % utils.parse_network( local_network) server_conf = OVPN_INLINE_SERVER_CONF % ( self.server.port, self.server.protocol, self.interface, '%s %s' % utils.parse_network(self.server.network), self.management_socket_path, CIPHERS[self.server.cipher], 4 if self.server.debug else 1, 8 if self.server.debug else 3, ) if self.server.bind_address: server_conf += 'local %s\n' % self.server.bind_address if self.server.multi_device: server_conf += 'duplicate-cn\n' if self.server.otp_auth: server_conf += 'auth-user-pass-verify %s via-file\n' % ( self.user_pass_verify_path) # Pritunl v0.10.x did not include comp-lzo in client conf # if lzo_compression is adaptive dont include comp-lzo in server conf if self.server.lzo_compression == ADAPTIVE: pass elif self.server.lzo_compression: server_conf += 'comp-lzo yes\npush "comp-lzo yes"\n' else: server_conf += 'comp-lzo no\npush "comp-lzo no"\n' server_conf += JUMBO_FRAMES[self.server.jumbo_frames] if push: server_conf += push server_conf += '<ca>\n%s\n</ca>\n' % self.server.ca_certificate if self.server.tls_auth: server_conf += '<tls-auth>\n%s\n</tls-auth>\n' % ( self.server.tls_auth_key) server_conf += '<cert>\n%s\n</cert>\n' % utils.get_cert_block( self.primary_user.certificate) server_conf += '<key>\n%s\n</key>\n' % self.primary_user.private_key server_conf += '<dh>\n%s\n</dh>\n' % self.server.dh_params with open(self.ovpn_conf_path, 'w') as ovpn_conf: os.chmod(self.ovpn_conf_path, 0600) ovpn_conf.write(server_conf)
def 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.devices[user_id] if not _limiter.validate(remote_ip): self.instance_com.send_client_deny( client, '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, '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, '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, '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, '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, '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.ips: for cid, device in devices.items(): if device['virt_address'] == virt_address: self.instance_com.client_kill(device) else: virt_address = None if devices and device_id: for cid, device in devices.items(): if device['device_id'] == device_id: self.instance_com.client_kill(device) virt_address = device['virt_address'] if not virt_address: virt_address = self.server.get_ip_addr(org.id, user_id) if virt_address and virt_address in self.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.ips: virt_address = ip_addr self.dyn_ips.add(virt_address) break if virt_address: self.ips[virt_address] = client_id devices[client_id] = { 'user': user.name, 'user_id': user_id, 'org': org.name, '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, '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.instance_com.push_output('Client conf %s:' % user_id) for conf_line in client_conf.split('\n'): if conf_line: self.instance_com.push_output(' ' + conf_line) self.instance_com.send_client_auth(client, client_conf) else: self.instance_com.send_client_deny( client, 'Unable to assign ip address') except: logger.exception('Error parsing client connect', 'server', server_id=self.server.id, ) self.instance_com.send_client_deny( client, 'Error parsing client connect')
def generate_iptables_rules(self): rules = [] try: routes_output = utils.check_output_logged(['route', '-n']) except subprocess.CalledProcessError: logger.exception('Failed to get IP routes', 'server', server_id=self.server.id, ) raise routes = {} for line in routes_output.splitlines(): line_split = line.split() if len(line_split) < 8 or not re.match(IP_REGEX, line_split[0]): continue routes[line_split[0]] = line_split[7] if '0.0.0.0' not in routes: raise IptablesError('Failed to find default network interface', { 'server_id': self.server.id, }) default_interface = routes['0.0.0.0'] rules.append(['INPUT', '-i', self.interface, '-j', 'ACCEPT']) rules.append(['FORWARD', '-i', self.interface, '-j', 'ACCEPT']) interfaces = set() for network_address in self.server.local_networks or ['0.0.0.0/0']: args_base = ['POSTROUTING', '-t', 'nat'] network = utils.parse_network(network_address)[0] if network not in routes: logger.warning('Failed to find interface for local ' + \ 'network route, using default route', 'server', server_id=self.server.id, ) interface = default_interface else: interface = routes[network] interfaces.add(interface) if network != '0.0.0.0': args_base += ['-d', network_address] args_base += [ '-o', interface, '-j', 'MASQUERADE', ] rules.append(args_base + ['-s', self.server.network]) for link_svr in self.server.iter_links(fields=('_id', 'network')): rules.append(args_base + ['-s', link_svr.network]) for interface in interfaces: rules.append([ 'FORWARD', '-i', interface, '-o', self.interface, '-m', 'state', '--state', 'ESTABLISHED,RELATED', '-j', 'ACCEPT', ]) rules.append([ 'FORWARD', '-i', self.interface, '-o', interface, '-m', 'state', '--state', 'ESTABLISHED,RELATED', '-j', 'ACCEPT', ]) extra_args = [ '-m', 'comment', '--comment', 'pritunl_%s' % self.server.id, ] if settings.local.iptables_wait: extra_args.append('--wait') rules = [x + extra_args for x in rules] return rules
def generate_ovpn_conf(self): if not self.server.primary_organization or \ not self.server.primary_user: self.server.create_primary_user() if self.server.primary_organization not in self.server.organizations: self.server.remove_primary_user() self.server.create_primary_user() primary_org = organization.get_by_id(self.server.primary_organization) if not primary_org: self.server.create_primary_user() primary_org = organization.get_by_id( id=self.server.primary_organization) self.primary_user = primary_org.get_user(self.server.primary_user) if not self.primary_user: self.server.create_primary_user() primary_org = organization.get_by_id( id=self.server.primary_organization) self.primary_user = primary_org.get_user(self.server.primary_user) gateway = utils.get_network_gateway(self.server.network) gateway6 = utils.get_network_gateway(self.server.network6) push = '' routes = [] for route in self.server.get_routes(include_default=False): routes.append(route['network']) if route['virtual_network']: continue network = route['network'] if route['net_gateway']: if ':' in network: push += 'push "route-ipv6 %s net_gateway"\n' % network else: push += 'push "route %s %s net_gateway"\n' % \ utils.parse_network(network) elif not route.get('network_link'): if ':' in network: push += 'push "route-ipv6 %s"\n' % network else: push += 'push "route %s %s"\n' % utils.parse_network( network) else: if ':' in network: push += 'route-ipv6 %s %s\n' % (network, gateway6) else: push += 'route %s %s %s\n' % ( utils.parse_network(network) + (gateway, )) for link_svr in self.server.iter_links( fields=('_id', 'network', 'local_networks', 'network_start', 'network_end', 'organizations', 'routes', 'links', 'ipv6', 'replica_count', 'network_mode')): if self.server.id < link_svr.id: for route in link_svr.get_routes(include_default=False): network = route['network'] if route['net_gateway']: continue if ':' in network: push += 'route-ipv6 %s %s\n' % (network, gateway6) else: push += 'route %s %s %s\n' % ( utils.parse_network(network) + (gateway, )) if self.vxlan: push += 'push "route %s %s"\n' % utils.parse_network( self.vxlan.vxlan_net) if self.server.network_mode == BRIDGE: host_int_data = self.host_interface_data host_address = host_int_data['address'] host_netmask = host_int_data['netmask'] server_line = 'server-bridge %s %s %s %s' % ( host_address, host_netmask, self.server.network_start, self.server.network_end, ) else: server_line = 'server %s %s' % utils.parse_network( self.server.network) if self.server.ipv6: server_line += '\nserver-ipv6 ' + self.server.network6 if self.server.protocol == 'tcp': if (self.server.ipv6 or settings.vpn.ipv6) and \ not self.server.bind_address: protocol = 'tcp6-server' else: protocol = 'tcp-server' elif self.server.protocol == 'udp': if (self.server.ipv6 or settings.vpn.ipv6) and \ not self.server.bind_address: protocol = 'udp6' else: protocol = 'udp' else: raise ValueError('Unknown protocol') server_conf = OVPN_INLINE_SERVER_CONF % ( self.server.port, protocol, self.interface, server_line, self.management_socket_path, self.server.max_clients, self.server.ping_interval, self.server.ping_timeout + 20, self.server.ping_interval, self.server.ping_timeout, SERVER_CIPHERS[self.server.cipher], HASHES[self.server.hash], 4 if self.server.debug else 1, 8 if self.server.debug else 3, ) if self.server.bind_address: server_conf += 'local %s\n' % self.server.bind_address if self.server.inter_client: server_conf += 'client-to-client\n' if self.server.multi_device: server_conf += 'duplicate-cn\n' if self.server.protocol == 'udp': server_conf += 'replay-window 128\n' # Pritunl v0.10.x did not include comp-lzo in client conf # if lzo_compression is adaptive dont include comp-lzo in server conf if self.server.lzo_compression == ADAPTIVE: pass elif self.server.lzo_compression: server_conf += 'comp-lzo yes\npush "comp-lzo yes"\n' else: server_conf += 'comp-lzo no\npush "comp-lzo no"\n' server_conf += JUMBO_FRAMES[self.server.jumbo_frames] if push: server_conf += push if self.server.debug: self.server.output.push_message('Server conf:') for conf_line in server_conf.split('\n'): if conf_line: self.server.output.push_message(' ' + conf_line) if settings.local.sub_plan and \ 'enterprise' in settings.local.sub_plan: returns = plugins.caller( 'server_config', 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, routes=routes, interface=self.interface, bridge_interface=self.bridge_interface, vxlan=self.vxlan, ) if returns: for return_val in returns: if not return_val: continue server_conf += return_val.strip() + '/n' server_conf += '<ca>\n%s\n</ca>\n' % self.server.ca_certificate if self.server.tls_auth: server_conf += 'key-direction 0\n<tls-auth>\n%s\n</tls-auth>\n' % ( self.server.tls_auth_key) server_conf += '<cert>\n%s\n</cert>\n' % utils.get_cert_block( self.primary_user.certificate) server_conf += '<key>\n%s\n</key>\n' % self.primary_user.private_key server_conf += '<dh>\n%s\n</dh>\n' % self.server.dh_params with open(self.ovpn_conf_path, 'w') as ovpn_conf: os.chmod(self.ovpn_conf_path, 0600) ovpn_conf.write(server_conf)
def client_connect(self, client): from pritunl.server.utils import get_by_id try: client_id = client['client_id'] org_id = bson.ObjectId(client['org_id']) user_id = bson.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') password = client.get('password') remote_ip = client.get('remote_ip') devices = self.client_devices[user_id] 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', 'type', 'disabled']) if not user: self.send_client_deny(client, 'User is not valid') return client_conf = '' link_svr_id = None for link_doc in self.server.links: if link_doc['user_id'] == user.id: link_svr_id = link_doc['server_id'] break if link_svr_id: link_svr = get_by_id( link_svr_id, fields=['_id', 'network', 'local_networks']) client_conf += 'iroute %s %s\n' % utils.parse_network( link_svr.network) for local_network in link_svr.local_networks: push += 'iroute %s %s\n' % utils.parse_network( local_network) 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, 'password': password, 'virt_address': virt_address, 'real_address': remote_ip, }) client_conf += 'ifconfig-push %s %s\n' % utils.parse_network( virt_address) 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')
def generate_client_conf(self, platform, client_id, virt_address, user, reauth): client_conf = '' if user.link_server_id: link_usr_svr = self.server.get_link_server(user.link_server_id, fields=('_id', 'network', 'network_start', 'network_end', 'local_networks', 'organizations', 'routes', 'links', 'ipv6')) for route in link_usr_svr.get_routes( include_default=False): network = route['network'] if ':' in network: client_conf += 'iroute-ipv6 %s\n' % network else: client_conf += 'iroute %s %s\n' % utils.parse_network( network) else: if self.server.is_route_all(): if platform == 'ios': client_conf += 'push "route 0.0.0.0 128.0.0.0"\n' client_conf += 'push "route 128.0.0.0 128.0.0.0"\n' else: client_conf += 'push "redirect-gateway def1"\n' if self.server.ipv6: if platform != 'ios': client_conf += 'push "redirect-gateway-ipv6 def1"\n' client_conf += 'push "route-ipv6 2000::/3"\n' if self.server.dns_mapping: client_conf += 'push "dhcp-option DNS %s"\n' % ( utils.get_network_gateway(self.server.network)) for dns_server in self.server.dns_servers: client_conf += 'push "dhcp-option DNS %s"\n' % dns_server if self.server.search_domain: client_conf += 'push "dhcp-option DOMAIN %s"\n' % ( self.server.search_domain) network_links = user.get_network_links() for network_link in network_links: if self.reserve_iroute(client_id, network_link, True): if ':' in network_link: client_conf += 'iroute-ipv6 %s\n' % network_link else: client_conf += 'iroute %s %s\n' % \ utils.parse_network(network_link) if network_links and not reauth: thread = threading.Thread(target=self.iroute_ping_thread, args=(client_id, virt_address.split('/')[0])) thread.daemon = True thread.start() for network_link in self.server.network_links: if ':' in network_link: client_conf += 'push "route-ipv6 %s"\n' % network_link else: client_conf += 'push "route %s %s"\n' % ( utils.parse_network(network_link)) for link_svr in self.server.iter_links(fields=( '_id', 'network', 'local_networks', 'network_start', 'network_end', 'organizations', 'routes', 'links', 'ipv6')): for route in link_svr.get_routes( include_default=False): network = route['network'] if ':' in network: client_conf += 'push "route-ipv6 %s"\n' % (network) else: client_conf += 'push "route %s %s"\n' % ( utils.parse_network(network)) return client_conf
def allow_client(self, client_data, org, user, reauth=False): client_id = client_data['client_id'] key_id = client_data['key_id'] org_id = client_data['org_id'] user_id = client_data['user_id'] device_id = client_data.get('device_id') device_name = client_data.get('device_name') platform = client_data.get('platform') mac_addr = client_data.get('mac_addr') remote_ip = client_data.get('remote_ip') doc_id = utils.ObjectId() if reauth: doc = self.clients.find_id(client_id) if not doc: self.instance_com.send_client_deny(client_id, key_id, 'Client connection info timed out') return virt_address = doc['virt_address'] virt_address6 = doc['virt_address6'] else: user.audit_event( 'user_connection', 'User connected to "%s"' % self.server.name, remote_addr=remote_ip, ) monitoring.insert_point('user_connections', { 'host': settings.local.host.name, 'server': self.server.name, }, { 'user': user.name, 'platform': platform, 'remote_ip': remote_ip, }) virt_address, address_dynamic = self.get_virt_addr( org_id, user_id, mac_addr, doc_id) if not self.server.multi_device: if self.server.replicating: # if self.server.route_clients: # docs = self.collection.find({ # 'user_id': user_id, # 'server_id': self.server.id, # }) # # for doc in docs: # messenger.publish('client', { # 'state': False, # 'server_id': self.server.id, # 'virt_address': doc['virt_address'], # 'virt_address6': doc['virt_address6'], # 'host_address': doc['host_address'], # 'host_address6': doc['host_address6'], # }) messenger.publish('instance', [ 'user_reconnect', user_id, settings.local.host_id, ]) for clnt in self.clients.find({'user_id': user_id}): time.sleep(2) self.instance_com.client_kill(clnt['id']) if not virt_address: self.instance_com.send_client_deny(client_id, key_id, 'Unable to assign ip address') return virt_address6 = self.server.ip4to6(virt_address) dns_servers = [] if user.dns_servers: for dns_server in user.dns_servers: if dns_server == '127.0.0.1': dns_server = virt_address dns_servers.append(dns_server) rules, rules6 = self.generate_iptables_rules( user, virt_address, virt_address6) self.clients.insert({ 'id': client_id, 'doc_id': doc_id, 'org_id': org_id, 'org_name': org.name, 'user_id': user_id, 'user_name': user.name, 'user_type': user.type, 'dns_servers': dns_servers, 'dns_suffix': user.dns_suffix, 'device_id': device_id, 'device_name': device_name, 'platform': platform, 'mac_addr': mac_addr, 'virt_address': virt_address, 'virt_address6': virt_address6, 'real_address': remote_ip, 'address_dynamic': address_dynamic, 'iptables_rules': rules, 'ip6tables_rules': rules6, }) if user.type == CERT_CLIENT: plugins.event( 'user_connected', host_id=settings.local.host_id, server_id=self.server.id, org_id=org.id, user_id=user.id, host_name=settings.local.host.name, server_name=self.server.name, org_name=org.name, user_name=user.name, platform=platform, device_id=device_id, device_name=device_name, virtual_ip=virt_address, virtual_ip6=virt_address6, remote_ip=remote_ip, mac_addr=mac_addr, ) host.global_clients.insert({ 'instance_id': self.instance.id, 'client_id': client_id, }) client_conf = self.generate_client_conf(platform, client_id, virt_address, user, reauth) client_conf += 'ifconfig-push %s %s\n' % utils.parse_network( virt_address) if self.server.ipv6: client_conf += 'ifconfig-ipv6-push %s\n' % virt_address6 if self.server.debug: self.instance_com.push_output('Client conf %s:' % user_id) for conf_line in client_conf.split('\n'): if conf_line: self.instance_com.push_output(' ' + conf_line) self.instance_com.send_client_auth(client_id, key_id, client_conf)
def generate_iptables_rules(self): rules = [] try: routes_output = utils.check_output_logged(['route', '-n']) except subprocess.CalledProcessError: logger.exception( 'Failed to get IP routes', 'server', server_id=self.server.id, ) raise routes = {} for line in routes_output.splitlines(): line_split = line.split() if len(line_split) < 8 or not re.match(IP_REGEX, line_split[0]): continue routes[line_split[0]] = line_split[7] if '0.0.0.0' not in routes: raise IptablesError('Failed to find default network interface', { 'server_id': self.server.id, }) default_interface = routes['0.0.0.0'] rules.append(['INPUT', '-i', self.interface, '-j', 'ACCEPT']) rules.append(['FORWARD', '-i', self.interface, '-j', 'ACCEPT']) interfaces = set() for network_address in self.server.local_networks or ['0.0.0.0/0']: args_base = ['POSTROUTING', '-t', 'nat'] network = utils.parse_network(network_address)[0] if network not in routes: logger.warning('Failed to find interface for local ' + \ 'network route, using default route', 'server', server_id=self.server.id, ) interface = default_interface else: interface = routes[network] interfaces.add(interface) if network != '0.0.0.0': args_base += ['-d', network_address] args_base += [ '-o', interface, '-j', 'MASQUERADE', ] rules.append(args_base + ['-s', self.server.network]) for link_svr in self.server.iter_links(fields=('_id', 'network')): rules.append(args_base + ['-s', link_svr.network]) for interface in interfaces: rules.append([ 'FORWARD', '-i', interface, '-o', self.interface, '-m', 'state', '--state', 'ESTABLISHED,RELATED', '-j', 'ACCEPT', ]) rules.append([ 'FORWARD', '-i', self.interface, '-o', interface, '-m', 'state', '--state', 'ESTABLISHED,RELATED', '-j', 'ACCEPT', ]) extra_args = [ '-m', 'comment', '--comment', 'pritunl_%s' % self.server.id, ] if settings.local.iptables_wait: extra_args.append('--wait') rules = [x + extra_args for x in rules] return rules
def client_connect(self, client): try: client_id = client['client_id'] org_id = bson.ObjectId(client['org_id']) user_id = bson.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', 'type', 'disabled', 'otp_secret', 'link_server_id')) if not user: self.send_client_deny(client, 'User is not valid') 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')
def generate_client_conf(self, platform, client_id, virt_address, user, reauth): client_conf = '' if user.link_server_id: link_usr_svr = self.server.get_link_server( user.link_server_id, fields=('_id', 'network', 'network_start', 'network_end', 'local_networks', 'organizations', 'routes', 'links', 'ipv6')) for route in link_usr_svr.get_routes(include_default=False): network = route['network'] if ':' in network: client_conf += 'iroute-ipv6 %s\n' % network else: client_conf += 'iroute %s %s\n' % utils.parse_network( network) else: if self.server.is_route_all(): if platform == 'ios': client_conf += 'push "route 0.0.0.0 128.0.0.0"\n' client_conf += 'push "route 128.0.0.0 128.0.0.0"\n' else: client_conf += 'push "redirect-gateway def1"\n' if self.server.ipv6: if platform != 'ios': client_conf += 'push "redirect-gateway-ipv6 def1"\n' client_conf += 'push "route-ipv6 2000::/3"\n' if self.server.dns_mapping: client_conf += 'push "dhcp-option DNS %s"\n' % ( utils.get_network_gateway(self.server.network)) for dns_server in self.server.dns_servers: client_conf += 'push "dhcp-option DNS %s"\n' % dns_server if self.server.search_domain: client_conf += 'push "dhcp-option DOMAIN %s"\n' % ( self.server.search_domain) network_links = user.get_network_links() for network_link in network_links: if self.reserve_iroute(client_id, network_link, True): if ':' in network_link: client_conf += 'iroute-ipv6 %s\n' % network_link else: client_conf += 'iroute %s %s\n' % \ utils.parse_network(network_link) if network_links and not reauth: thread = threading.Thread(target=self.iroute_ping_thread, args=(client_id, virt_address.split('/')[0])) thread.daemon = True thread.start() for network_link in self.server.network_links: if ':' in network_link: client_conf += 'push "route-ipv6 %s"\n' % network_link else: client_conf += 'push "route %s %s"\n' % ( utils.parse_network(network_link)) for link_svr in self.server.iter_links( fields=('_id', 'network', 'local_networks', 'network_start', 'network_end', 'organizations', 'routes', 'links', 'ipv6')): for route in link_svr.get_routes(include_default=False): network = route['network'] if ':' in network: client_conf += 'push "route-ipv6 %s"\n' % (network) else: client_conf += 'push "route %s %s"\n' % ( utils.parse_network(network)) return client_conf
def allow_client(self, client, org, user): client_id = client['client_id'] key_id = client['key_id'] org_id = client['org_id'] user_id = 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') remote_ip = client.get('remote_ip') address_dynamic = False client_conf = self.generate_client_conf(user) virt_address = self.server.get_ip_addr(org_id, user_id) if not self.server.multi_device: for client in self.clients.find({'user_id': user_id}): self.instance_com.client_kill(client['id']) elif virt_address and self.clients.find( {'virt_address': virt_address}): 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 not self.clients.find({'virt_address': ip_addr}): virt_address = ip_addr address_dynamic = True break if not virt_address: self.instance_com.send_client_deny(client_id, key_id, 'Unable to assign ip address') return virt_address6 = self.server.ip4to6(virt_address) self.clients.insert({ 'id': client_id, 'org_id': org_id, 'org_name': org.name, 'user_id': user_id, 'user_name': user.name, 'user_type': user.type, 'device_id': device_id, 'device_name': device_name, 'platform': platform, 'mac_addr': mac_addr, 'otp_code': None, 'virt_address': virt_address, 'virt_address6': virt_address6, 'real_address': remote_ip, 'address_dynamic': address_dynamic, }) client_conf += 'ifconfig-push %s %s\n' % utils.parse_network( virt_address) if self.server.ipv6: client_conf += 'ifconfig-ipv6-push %s\n' % virt_address6 if self.server.debug: self.instance_com.push_output('Client conf %s:' % user_id) for conf_line in client_conf.split('\n'): if conf_line: self.instance_com.push_output(' ' + conf_line) self.instance_com.send_client_auth(client_id, key_id, client_conf)
def generate_ovpn_conf(self): logger.debug('Generating server ovpn conf', 'server', server_id=self.server.id, ) if not self.server.primary_organization or \ not self.server.primary_user: self.server.create_primary_user() if self.server.primary_organization not in self.server.organizations: self.server.remove_primary_user() self.server.create_primary_user() primary_org = organization.get_by_id(self.server.primary_organization) if not primary_org: self.server.create_primary_user() primary_org = organization.get_by_id( id=self.server.primary_organization) self.primary_user = primary_org.get_user(self.server.primary_user) if not self.primary_user: self.server.create_primary_user() primary_org = organization.get_by_id( id=self.server.primary_organization) self.primary_user = primary_org.get_user(self.server.primary_user) push = '' if self.server.mode == LOCAL_TRAFFIC: for network in self.server.local_networks: push += 'push "route %s %s"\n' % utils.parse_network(network) elif self.server.mode == VPN_TRAFFIC: pass for link_svr in self.server.iter_links(fields=( '_id', 'network', 'local_networks')): if self.server.id < link_svr.id: gateway = utils.get_network_gateway(self.server.network) push += 'route %s %s %s\n' % (utils.parse_network( link_svr.network) + (gateway,)) for local_network in link_svr.local_networks: push += 'route %s %s %s\n' % (utils.parse_network( local_network) + (gateway,)) server_conf = OVPN_INLINE_SERVER_CONF % ( self.server.port, self.server.protocol, self.interface, '%s %s' % utils.parse_network(self.server.network), self.management_socket_path, self.server.max_clients, self.server.ping_interval, self.server.ping_timeout + 20, self.server.ping_interval, self.server.ping_timeout, CIPHERS[self.server.cipher], 4 if self.server.debug else 1, 8 if self.server.debug else 3, ) if self.server.bind_address: server_conf += 'local %s\n' % self.server.bind_address if self.server.inter_client: server_conf += 'client-to-client\n' if self.server.multi_device: server_conf += 'duplicate-cn\n' # Pritunl v0.10.x did not include comp-lzo in client conf # if lzo_compression is adaptive dont include comp-lzo in server conf if self.server.lzo_compression == ADAPTIVE: pass elif self.server.lzo_compression: server_conf += 'comp-lzo yes\npush "comp-lzo yes"\n' else: server_conf += 'comp-lzo no\npush "comp-lzo no"\n' server_conf += JUMBO_FRAMES[self.server.jumbo_frames] if push: server_conf += push if self.server.debug: self.server.output.push_message('Server conf:') for conf_line in server_conf.split('\n'): if conf_line: self.server.output.push_message(' ' + conf_line) server_conf += '<ca>\n%s\n</ca>\n' % self.server.ca_certificate if self.server.tls_auth: server_conf += 'key-direction 0\n<tls-auth>\n%s\n</tls-auth>\n' % ( self.server.tls_auth_key) server_conf += '<cert>\n%s\n</cert>\n' % utils.get_cert_block( self.primary_user.certificate) server_conf += '<key>\n%s\n</key>\n' % self.primary_user.private_key server_conf += '<dh>\n%s\n</dh>\n' % self.server.dh_params with open(self.ovpn_conf_path, 'w') as ovpn_conf: os.chmod(self.ovpn_conf_path, 0600) ovpn_conf.write(server_conf)
def generate_ovpn_conf(self): from pritunl.server.utils import get_by_id logger.debug('Generating server ovpn conf', 'server', server_id=self.server.id, ) if not self.server.primary_organization or \ not self.server.primary_user: self.server.create_primary_user() if self.server.primary_organization not in self.server.organizations: self.server.remove_primary_user() self.server.create_primary_user() primary_org = organization.get_by_id(self.server.primary_organization) if not primary_org: self.server.create_primary_user() primary_org = organization.get_by_id( id=self.server.primary_organization) self.primary_user = primary_org.get_user(self.server.primary_user) if not self.primary_user: self.server.create_primary_user() primary_org = organization.get_by_id( id=self.server.primary_organization) self.primary_user = primary_org.get_user(self.server.primary_user) push = '' if self.server.mode == LOCAL_TRAFFIC: for network in self.server.local_networks: push += 'push "route %s %s"\n' % utils.parse_network(network) elif self.server.mode == VPN_TRAFFIC: pass else: push += 'push "redirect-gateway"\n' for dns_server in self.server.dns_servers: push += 'push "dhcp-option DNS %s"\n' % dns_server if self.server.search_domain: push += 'push "dhcp-option DOMAIN %s"\n' % ( self.server.search_domain) for link_doc in self.server.links: link_svr = get_by_id(link_doc['server_id']) push += 'push "route %s %s"\n' % utils.parse_network( link_svr.network) for local_network in link_svr.local_networks: push += 'push "route %s %s"\n' % utils.parse_network( local_network) server_conf = OVPN_INLINE_SERVER_CONF % ( self.server.port, self.server.protocol, self.interface, '%s %s' % utils.parse_network(self.server.network), self.management_socket_path, CIPHERS[self.server.cipher], 4 if self.server.debug else 1, 8 if self.server.debug else 3, ) if self.server.bind_address: server_conf += 'local %s\n' % self.server.bind_address if self.server.multi_device: server_conf += 'duplicate-cn\n' if self.server.otp_auth: server_conf += 'auth-user-pass-verify %s via-file\n' % ( self.user_pass_verify_path) # Pritunl v0.10.x did not include comp-lzo in client conf # if lzo_compression is adaptive dont include comp-lzo in server conf if self.server.lzo_compression == ADAPTIVE: pass elif self.server.lzo_compression: server_conf += 'comp-lzo yes\npush "comp-lzo yes"\n' else: server_conf += 'comp-lzo no\npush "comp-lzo no"\n' server_conf += JUMBO_FRAMES[self.server.jumbo_frames] if push: server_conf += push server_conf += '<ca>\n%s\n</ca>\n' % self.server.ca_certificate if self.server.tls_auth: server_conf += '<tls-auth>\n%s\n</tls-auth>\n' % ( self.server.tls_auth_key) server_conf += '<cert>\n%s\n</cert>\n' % utils.get_cert_block( self.primary_user.certificate) server_conf += '<key>\n%s\n</key>\n' % self.primary_user.private_key server_conf += '<dh>\n%s\n</dh>\n' % self.server.dh_params with open(self.ovpn_conf_path, 'w') as ovpn_conf: os.chmod(self.ovpn_conf_path, 0600) ovpn_conf.write(server_conf)