def add_route(self, virt_address, virt_address6, host_address, host_address6): virt_address = virt_address.split('/')[0] _route_lock.acquire() try: if virt_address in self.client_routes: try: self.client_routes.remove(virt_address) try: utils.check_call_silent([ 'ip', 'route', 'del', virt_address, ]) except subprocess.CalledProcessError: pass except KeyError: pass if not host_address or host_address == \ settings.local.host.local_addr: return for i in xrange(3): try: utils.check_output_logged([ 'ip', 'route', 'add', virt_address, 'via', host_address, ]) break except subprocess.CalledProcessError: if i == 0: try: utils.check_call_silent([ 'ip', 'route', 'del', virt_address, ]) except subprocess.CalledProcessError: pass elif i == 2: raise time.sleep(0.2) except: logger.exception('Failed to add route', 'clients', virt_address=virt_address, virt_address6=virt_address6, host_address=host_address, host_address6=host_address6, ) finally: _route_lock.release()
def build_onc_archive(self): temp_path = utils.get_temp_path() key_archive_path = os.path.join(temp_path, '%s.zip' % self.id) try: os.makedirs(temp_path) zip_file = zipfile.ZipFile(key_archive_path, 'w') try: user_cert_path = os.path.join(temp_path, '%s.crt' % self.id) user_key_path = os.path.join(temp_path, '%s.key' % self.id) user_p12_path = os.path.join(temp_path, '%s.p12' % self.id) with open(user_cert_path, 'w') as user_cert: user_cert.write(self.certificate) with open(user_key_path, 'w') as user_key: os.chmod(user_key_path, 0600) user_key.write(self.private_key) utils.check_output_logged([ 'openssl', 'pkcs12', '-export', '-nodes', '-password', 'pass:'******'-inkey', user_key_path, '-in', user_cert_path, '-out', user_p12_path ]) zip_file.write(user_p12_path, arcname='%s.p12' % self.name) os.remove(user_cert_path) os.remove(user_key_path) os.remove(user_p12_path) for svr in self.org.iter_servers(): server_conf_path = os.path.join(temp_path, '%s_%s.onc' % (self.id, svr.id)) conf_name, client_conf = self._generate_onc(svr) if not client_conf: continue with open(server_conf_path, 'w') as ovpn_conf: ovpn_conf.write(client_conf) zip_file.write(server_conf_path, arcname=conf_name) os.remove(server_conf_path) finally: zip_file.close() with open(key_archive_path, 'r') as archive_file: key_archive = archive_file.read() finally: utils.rmtree(temp_path) return key_archive
def add_host(self, host_vxlan_id, vxlan_mac, host_dst): if settings.local.host.local_addr == host_dst: return self.running_lock.acquire() try: if not self.running: return for i in xrange(2): try: if i == 0: check_func = utils.check_call_silent else: check_func = utils.check_output_logged check_func([ 'bridge', 'fdb', 'add', vxlan_mac, 'dev', self.iface_name, 'dst', host_dst, ]) break except subprocess.CalledProcessError: if i == 0: utils.check_output_logged([ 'bridge', 'fdb', 'del', vxlan_mac, 'dev', self.iface_name, ]) else: raise utils.check_output_logged([ 'arp', '-s', self.get_host_addr(host_vxlan_id), vxlan_mac, ]) except: logger.error('Failed to ad vxlan host', 'vxlan', vxlan_id=self.vxlan_id, server_id=self.server_id, ) raise finally: self.running_lock.release()
def enable_ip_forwarding(self): logger.debug('Enabling ip forwarding', 'server', server_id=self.server.id, ) try: utils.check_output_logged( ['sysctl', '-w', 'net.ipv4.ip_forward=1']) except subprocess.CalledProcessError: logger.exception('Failed to enable IP forwarding', 'server', server_id=self.server.id, ) raise
def set_ip6tables_rule(self, rule): for i in xrange(3): try: utils.check_output_logged(['ip6tables', '-I'] + rule) break except: if i == 2: raise logger.error( 'Failed to insert ip6tables rule, retrying...', 'instance', rule=rule, ) time.sleep(1)
def get_mem_usage(): try: free = utils.check_output_logged(['free']).split() return float(free[15]) / float(free[7]) except: logger.exception('Failed to get memory usage', 'host') return 0
def _default_interface_thread(): global default_interface6 while True: iface6 = None iface6_alt = None try: routes_output = utils.check_output_logged( ['route', '-n', '-A', 'inet6']) except subprocess.CalledProcessError: logger.exception('Failed to get IPv6 routes', 'setup') time.sleep(1) continue for line in routes_output.splitlines(): line_split = line.split() if len(line_split) < 7: continue if line_split[0] == '::/0': if iface6 or line_split[6] == 'lo': continue iface6 = line_split[6] if line_split[0] == 'ff00::/8': if iface6_alt or line_split[6] == 'lo': continue iface6_alt = line_split[6] default_interface6 = iface6 or iface6_alt time.sleep(10)
def setup_server_cert(): if not os.path.isfile(settings.conf.server_cert_path) or \ not os.path.isfile(settings.conf.server_key_path): logger.info('Generating server ssl cert', 'setup') try: utils.check_output_logged([ 'openssl', 'req', '-batch', '-x509', '-nodes', '-sha256', '-newkey', 'rsa:4096', '-days', '3652', '-keyout', settings.conf.server_key_path, '-out', settings.conf.server_cert_path, ]) except subprocess.CalledProcessError: logger.exception('Failed to generate server ssl cert', 'setup') raise os.chmod(settings.conf.server_key_path, 0600)
def add_route(self, virt_address, virt_address6, host_address, host_address6): if not host_address or host_address == \ settings.local.host.local_address: return _route_lock.acquire() try: cur_host_address = self.client_routes.pop(virt_address) if cur_host_address: try: subprocess.check_output([ 'ip', 'route', 'del', virt_address, 'via', cur_host_address, ]) except: pass for i in xrange(3): try: utils.check_output_logged([ 'ip', 'route', 'add', virt_address, 'via', host_address, ]) break except: if i == 2: raise time.sleep(0.2) except: logger.exception('Failed to add route', 'clients', virt_address=virt_address, virt_address6=virt_address6, host_address=host_address, host_address6=host_address6, ) finally: _route_lock.release()
def _append_iptables_rule(self, rule, ipv6=False): rule = self._parse_rule(rule) for i in xrange(3): try: utils.check_output_logged( ['ip6tables' if ipv6 else 'iptables', '-A'] + rule) break except: if i == 2: raise logger.error( 'Failed to insert iptables rule, retrying...', 'instance', rule=rule, ) time.sleep(1)
def enable_ip_forwarding(self): try: utils.check_output_logged( ['sysctl', '-w', 'net.ipv4.ip_forward=1']) except subprocess.CalledProcessError: logger.exception( 'Failed to enable IP forwarding', 'server', server_id=self.server.id, ) raise if self.server.ipv6: keys = [] output = utils.check_output_logged(['sysctl', 'net.ipv6.conf']) for line in output.split('\n'): if '.accept_ra =' in line: keys.append(line.split('=')[0].strip()) try: for key in keys: utils.check_output_logged([ 'sysctl', '-w', '%s=2' % key, ]) utils.check_output_logged( ['sysctl', '-w', 'net.ipv6.conf.all.forwarding=1']) except subprocess.CalledProcessError: logger.exception( 'Failed to enable IPv6 forwarding', 'server', server_id=self.server.id, )
def enable_ip_forwarding(self): try: utils.check_output_logged( ['sysctl', '-w', 'net.ipv4.ip_forward=1']) except subprocess.CalledProcessError: logger.exception('Failed to enable IP forwarding', 'server', server_id=self.server.id, ) raise if self.server.ipv6: keys = [] output = utils.check_output_logged(['sysctl', 'net.ipv6.conf']) for line in output.split('\n'): if '.accept_ra =' in line: keys.append(line.split('=')[0].strip()) try: for key in keys: utils.check_output_logged([ 'sysctl', '-w', '%s=2' % key, ]) utils.check_output_logged( ['sysctl', '-w', 'net.ipv6.conf.all.forwarding=1']) except subprocess.CalledProcessError: logger.exception('Failed to enable IPv6 forwarding', 'server', server_id=self.server.id, )
def enable_ip_forwarding(self): try: utils.check_output_logged( ['sysctl', '-w', 'net.ipv4.ip_forward=1']) except subprocess.CalledProcessError: logger.exception('Failed to enable IP forwarding', 'server', server_id=self.server.id, ) raise if self.server.ipv6: try: utils.check_output_logged( ['sysctl', '-w', 'net.ipv6.conf.all.forwarding=1']) except subprocess.CalledProcessError: logger.exception('Failed to enable IPv6 forwarding', 'server', server_id=self.server.id, )
def _insert_iptables_rule_cmd(self, rule, ipv6=False): rule = self._parse_rule(rule) _global_lock.acquire() try: for i in xrange(3): try: utils.check_output_logged( ['ip6tables' if ipv6 else 'iptables', '-I'] + rule) break except: if i == 2: raise logger.error( 'Failed to insert iptables rule, retrying...', 'instance', rule=rule, ) time.sleep(0.5) finally: _global_lock.release()
def _insert_iptables_rule_cmd(self, rule, ipv6=False): rule = self._parse_rule(rule) _global_lock.acquire() try: for i in xrange(3): try: utils.check_output_logged( ['ip6tables' if ipv6 else 'iptables', '-I'] + rule) break except: if i == 2: raise logger.error( 'Failed to insert iptables rule, retrying...', 'instance', rule=rule, ) time.sleep(1) finally: _global_lock.release()
def _dns_thread(): while not settings.local.sub_active or \ settings.local.sub_plan != 'enterprise': time.sleep(1) while True: try: utils.check_output_logged( ['pritunl-dns'], env=dict(os.environ, **{ 'DB': settings.conf.mongodb_uri, 'DB_PREFIX': settings.conf.mongodb_collection_prefix or '', }), ) except GeneratorExit: raise except: logger.exception('Error in dns server', 'setup') time.sleep(60) yield
def rem_interface(self, interface): if interface not in self.interfaces: return try: utils.check_output_logged([ 'ip', 'link', 'set', 'down', interface, ]) except subprocess.CalledProcessError: pass try: utils.check_output_logged([ 'brctl', 'delif', self.bridge_interface, interface, ]) except subprocess.CalledProcessError: pass try: utils.check_output_logged([ 'openvpn', '--rmtun', '--dev', interface, ]) except subprocess.CalledProcessError: pass self.interfaces.remove(interface)
def add_interface(self, interface): self.interfaces.add(interface) utils.check_output_logged([ 'openvpn', '--mktun', '--dev', interface, ]) utils.check_output_logged([ 'ip', 'link', 'set', interface, 'master', self.bridge_interface, ]) utils.check_output_logged([ 'ip', 'link', 'set', 'dev', interface, 'promisc', 'on', ])
def _dns_thread(): while not settings.local.sub_active and \ settings.local.sub_plan != 'enterprise': time.sleep(1) while True: try: utils.check_output_logged( ['pritunl-dns'], env=dict( os.environ, **{ 'DB': settings.conf.mongodb_uri, 'DB_PREFIX': settings.conf.mongodb_collection_prefix or '', }), ) except GeneratorExit: raise except: logger.exception('Error in dns server', 'setup') time.sleep(1) yield
def bridge_stop(self): if self.server.network_mode != BRIDGE: return try: utils.check_output_logged([ 'ifconfig', self.bridge_interface, 'down', ]) except subprocess.CalledProcessError: pass try: utils.check_output_logged([ 'brctl', 'delbr', self.bridge_interface, ]) except subprocess.CalledProcessError: pass try: utils.check_output_logged([ 'openvpn', '--rmtun', '--dev', self.interface, ]) except subprocess.CalledProcessError: pass host_int_data = self.host_interface_data host_interface = host_int_data['interface'] host_address = host_int_data['address'] host_netmask = host_int_data['netmask'] host_broadcast = host_int_data['broadcast'] utils.check_output_logged([ 'ifconfig', host_interface, host_address, 'netmask', host_netmask, 'broadcast', host_broadcast, ])
def rem_interface(self, interface): if interface not in self.interfaces: return try: utils.check_output_logged(["ip", "link", "set", "down", interface]) except subprocess.CalledProcessError: pass try: utils.check_output_logged(["brctl", "delif", self.bridge_interface, interface]) except subprocess.CalledProcessError: pass try: utils.check_output_logged(["openvpn", "--rmtun", "--dev", interface]) except subprocess.CalledProcessError: pass self.interfaces.remove(interface)
def add_interface(self, interface): self.interfaces.add(interface) utils.check_output_logged([ 'openvpn', '--mktun', '--dev', interface, ]) utils.check_output_logged([ 'brctl', 'addif', self.bridge_interface, interface, ]) utils.check_output_logged([ 'ifconfig', interface, '0.0.0.0', 'promisc', 'up', ])
def add_route(self, virt_address, virt_address6, host_address, host_address6): virt_address = virt_address.split('/')[0] _route_lock.acquire() try: if virt_address in self.client_routes: try: self.client_routes.remove(virt_address) try: utils.check_call_silent([ 'ip', 'route', 'del', virt_address, ]) except subprocess.CalledProcessError: pass except KeyError: pass if not host_address or host_address == \ settings.local.host.local_addr: return for i in xrange(3): try: utils.check_output_logged([ 'ip', 'route', 'add', virt_address, 'via', host_address, ]) break except subprocess.CalledProcessError: if i == 0: try: utils.check_call_silent([ 'ip', 'route', 'del', virt_address, ]) except subprocess.CalledProcessError: pass elif i == 2: raise time.sleep(0.2) except: logger.exception( 'Failed to add route', 'clients', virt_address=virt_address, virt_address6=virt_address6, host_address=host_address, host_address6=host_address6, ) finally: _route_lock.release()
def generate_iptables_rules(self): server_addr = utils.get_network_gateway(self.server.network) server_addr6 = utils.get_network_gateway(self.server.network6) ipv6_firewall = self.server.ipv6_firewall and \ settings.local.host.routed_subnet6 self.iptables.id = self.server.id self.iptables.ipv6 = self.server.ipv6 self.iptables.server_addr = server_addr self.iptables.server_addr6 = server_addr6 self.iptables.virt_interface = self.interface self.iptables.virt_network = self.server.network self.iptables.virt_network6 = self.server.network6 self.iptables.ipv6_firewall = ipv6_firewall self.iptables.inter_client = self.server.inter_client self.iptables.restrict_routes = self.server.restrict_routes try: routes_output = utils.check_output_logged(['route', '-n']) except subprocess.CalledProcessError: logger.exception( 'Failed to get IP routes', 'server', server_id=self.server.id, ) raise routes = [] default_interface = None for line in routes_output.splitlines(): line_split = line.split() if len(line_split) < 8 or not re.match(IP_REGEX, line_split[0]): continue if line_split[0] not in routes: if line_split[0] == '0.0.0.0': if default_interface: continue default_interface = line_split[7] routes.append((ipaddress.IPNetwork( '%s/%s' % (line_split[0], utils.subnet_to_cidr(line_split[2]))), line_split[7])) routes.reverse() if not default_interface: raise IptablesError('Failed to find default network interface') routes6 = [] default_interface6 = None if self.server.ipv6: try: routes_output = utils.check_output_logged( ['route', '-n', '-A', 'inet6']) except subprocess.CalledProcessError: logger.exception( 'Failed to get IPv6 routes', 'server', server_id=self.server.id, ) raise for line in routes_output.splitlines(): line_split = line.split() if len(line_split) < 7: continue try: route_network = ipaddress.IPv6Network(line_split[0]) except (ipaddress.AddressValueError, ValueError): continue if line_split[0] == '::/0': if default_interface6: continue default_interface6 = line_split[6] routes6.append(( route_network, line_split[6], )) if not default_interface6: raise IptablesError( 'Failed to find default IPv6 network interface') if default_interface6 == 'lo': logger.error( 'Failed to find default IPv6 interface', 'server', server_id=self.server.id, ) routes6.reverse() interfaces = set() interfaces6 = set() for route in self.server.get_routes( include_hidden=True, include_server_links=True, include_default=True, ): if route['virtual_network'] or route['link_virtual_network']: self.iptables.add_nat_network(route['network']) if route['virtual_network'] or route['net_gateway']: continue network = route['network'] is6 = ':' in network network_obj = ipaddress.IPNetwork(network) interface = route['nat_interface'] if is6: if not interface: for route_net, route_intf in routes6: if network_obj in route_net: interface = route_intf break if not interface: logger.info( 'Failed to find interface for local ' + \ 'IPv6 network route, using default route', 'server', server_id=self.server.id, network=network, ) interface = default_interface6 interfaces6.add(interface) else: if not interface: for route_net, route_intf in routes: if network_obj in route_net: interface = route_intf break if not interface: logger.info( 'Failed to find interface for local ' + \ 'network route, using default route', 'server', server_id=self.server.id, network=network, ) interface = default_interface interfaces.add(interface) self.iptables.add_route( network, nat=route['nat'], nat_interface=interface, ) if self.vxlan: self.iptables.add_route(self.vxlan.vxlan_net) self.iptables.generate()
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_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 start(self): host_int_data = self.host_interface_data host_interface = host_int_data["interface"] host_address = host_int_data["address"] host_netmask = host_int_data["netmask"] host_broadcast = host_int_data["broadcast"] utils.check_output_logged( [ "iptables", "-I", "FORWARD", "-i", self.bridge_interface, "-j", "ACCEPT", "-m", "comment", "--comment", "pritunl_%s" % settings.local.host_id, ] + ["--wait"] if settings.local.iptables_wait else [] ) utils.check_output_logged( [ "iptables", "-I", "INPUT", "-i", self.bridge_interface, "-j", "ACCEPT", "-m", "comment", "--comment", "pritunl_%s" % settings.local.host_id, ] + ["--wait"] if settings.local.iptables_wait else [] ) utils.check_output_logged(["ip", "link", "set", "down", host_interface]) utils.check_output_logged(["brctl", "addbr", self.bridge_interface]) utils.check_output_logged(["brctl", "addif", self.bridge_interface, host_interface]) utils.check_output_logged(["ifconfig", host_interface, "0.0.0.0", "promisc", "up"]) utils.check_output_logged( ["ifconfig", self.bridge_interface, host_address, "netmask", host_netmask, "broadcast", host_broadcast] )
def add_host(self, host_vxlan_id, vxlan_mac, host_dst, host_dst6): if settings.local.host.local_addr == host_dst: return self.running_lock.acquire() try: if not self.running: return for i in xrange(2): try: if i == 0: check_func = utils.check_output else: check_func = utils.check_output_logged check_func([ 'bridge', 'fdb', 'add', vxlan_mac, 'dev', self.iface_name, 'dst', host_dst, ], ignore_states=['File exists']) break except subprocess.CalledProcessError: if i == 0: utils.check_output_logged([ 'bridge', 'fdb', 'del', vxlan_mac, 'dev', self.iface_name, ]) else: raise utils.check_output_logged([ 'arp', '-s', self.get_host_addr(host_vxlan_id), vxlan_mac, ]) if host_dst6: for i in xrange(2): try: if i == 0: check_func = utils.check_output else: check_func = utils.check_output_logged check_func([ 'ip', '-6', 'neighbour', 'add', self.get_host_addr6(host_vxlan_id), 'lladdr', vxlan_mac, 'dev', self.iface_name, ], ignore_states=['File exists']) break except subprocess.CalledProcessError: if i == 0: utils.check_output_logged([ 'ip', '-6', 'neighbour', 'del', self.get_host_addr6(host_vxlan_id), 'dev', self.iface_name, ]) for j in xrange(30): try: utils.check_call_silent([ 'ip', '-6', 'neighbour', 'del', self.get_host_addr6(host_vxlan_id), 'dev', self.iface_name, ]) except: break time.sleep(0.5) else: raise except: logger.error( 'Failed to add vxlan host', 'vxlan', vxlan_id=self.vxlan_id, server_id=self.server_id, ) raise finally: self.running_lock.release()
def start(self): global _loaded local_iface = settings.local.host.local_iface if not _loaded: _loaded = True try: utils.check_call_silent([ 'modprobe', 'vxlan', ]) except subprocess.CalledProcessError: pass self.remove_iface() if not local_iface: logger.error( 'Failed to find local interface for vxlan', 'vxlan', vxlan_id=self.vxlan_id, server_id=self.server_id, host_id=settings.local.host_id, local_addr=settings.local.host.local_addr, ) raise ValueError('Failed to find local interface for vxlan') utils.check_output_logged([ 'ip', 'link', 'add', self.iface_name, 'type', 'vxlan', 'id', str(settings.vpn.vxlan_id_start + self.vxlan_id), 'dstport', '4789', 'dev', local_iface['interface'], 'nolearning', ], ignore_states=['File exists']) self.vxlan_mac = utils.get_interface_mac_address(self.iface_name) self._init_host() self.vxlan_addr = self.get_host_addr(self.host_vxlan_id) if self.ipv6: self.vxlan_addr6 = utils.ip4to6x64( settings.vpn.ipv6_prefix, self.vxlan_net, self.vxlan_addr, ) utils.check_output_logged([ 'ip', 'address', 'add', self.vxlan_addr + '/24', 'dev', self.iface_name, ], ignore_states=['File exists']) if self.ipv6: utils.check_output_logged([ 'ip', '-6', 'address', 'add', self.vxlan_addr6 + '/64', 'dev', self.iface_name, ], ignore_states=['File exists']) utils.check_output_logged([ 'ip', 'link', 'set', 'up', self.iface_name, ]) self._init_hosts()
def stop(self): try: utils.check_output_logged(["ifconfig", self.bridge_interface, "down"]) except subprocess.CalledProcessError: pass try: utils.check_output_logged(["brctl", "delbr", self.bridge_interface]) except subprocess.CalledProcessError: pass try: utils.check_output_logged( [ "iptables", "-D", "INPUT", "-i", self.bridge_interface, "-j", "ACCEPT", "-m", "comment", "--comment", "pritunl_%s" % settings.local.host_id, ] + ["--wait"] if settings.local.iptables_wait else [] ) except subprocess.CalledProcessError: pass try: utils.check_output_logged( [ "iptables", "-D", "FORWARD", "-i", self.bridge_interface, "-j", "ACCEPT", "-m", "comment", "--comment", "pritunl_%s" % settings.local.host_id, ] + ["--wait"] if settings.local.iptables_wait else [] ) except subprocess.CalledProcessError: pass host_int_data = self.host_interface_data host_interface = host_int_data["interface"] host_address = host_int_data["address"] host_netmask = host_int_data["netmask"] host_broadcast = host_int_data["broadcast"] utils.check_output_logged(["ip", "link", "set", "down", host_interface]) utils.check_output_logged(["ip", "link", "set", "up", host_interface]) utils.check_output_logged( ["ifconfig", host_interface, host_address, "netmask", host_netmask, "broadcast", host_broadcast] )
def generate_iptables_rules(self): server_addr = utils.get_network_gateway(self.server.network) server_addr6 = utils.get_network_gateway(self.server.network6) ipv6_firewall = self.server.ipv6_firewall and \ settings.local.host.routed_subnet6 self.iptables.id = self.server.id self.iptables.ipv6 = self.server.ipv6 self.iptables.server_addr = server_addr self.iptables.server_addr6 = server_addr6 self.iptables.virt_interface = self.interface self.iptables.virt_network = self.server.network self.iptables.virt_network6 = self.server.network6 self.iptables.ipv6_firewall = ipv6_firewall self.iptables.inter_client = self.server.inter_client try: routes_output = utils.check_output_logged(['route', '-n']) except subprocess.CalledProcessError: logger.exception('Failed to get IP routes', 'server', server_id=self.server.id, ) raise routes = [] default_interface = None for line in routes_output.splitlines(): line_split = line.split() if len(line_split) < 8 or not re.match(IP_REGEX, line_split[0]): continue if line_split[0] not in routes: if line_split[0] == '0.0.0.0': if default_interface: continue default_interface = line_split[7] routes.append(( ipaddress.IPNetwork('%s/%s' % (line_split[0], utils.subnet_to_cidr(line_split[2]))), line_split[7] )) routes.reverse() if not default_interface: raise IptablesError('Failed to find default network interface') routes6 = [] default_interface6 = None if self.server.ipv6: try: routes_output = utils.check_output_logged( ['route', '-n', '-A', 'inet6']) except subprocess.CalledProcessError: logger.exception('Failed to get IPv6 routes', 'server', server_id=self.server.id, ) raise for line in routes_output.splitlines(): line_split = line.split() if len(line_split) < 7: continue try: route_network = ipaddress.IPv6Network(line_split[0]) except (ipaddress.AddressValueError, ValueError): continue if line_split[0] == '::/0': if default_interface6: continue default_interface6 = line_split[6] routes6.append(( route_network, line_split[6], )) if not default_interface6: raise IptablesError( 'Failed to find default IPv6 network interface') if default_interface6 == 'lo': logger.error('Failed to find default IPv6 interface', 'server', server_id=self.server.id, ) routes6.reverse() interfaces = set() interfaces6 = set() for route in self.server.get_routes( include_hidden=True, include_server_links=True, include_default=True, ): if route['virtual_network'] or route['link_virtual_network']: self.iptables.add_nat_network(route['network']) if route['virtual_network']: continue network = route['network'] is6 = ':' in network network_obj = ipaddress.IPNetwork(network) interface = route['nat_interface'] if is6: if not interface: for route_net, route_intf in routes6: if network_obj in route_net: interface = route_intf break if not interface: logger.info( 'Failed to find interface for local ' + \ 'IPv6 network route, using default route', 'server', server_id=self.server.id, network=network, ) interface = default_interface6 interfaces6.add(interface) else: if not interface: for route_net, route_intf in routes: if network_obj in route_net: interface = route_intf break if not interface: logger.info( 'Failed to find interface for local ' + \ 'network route, using default route', 'server', server_id=self.server.id, network=network, ) interface = default_interface interfaces.add(interface) self.iptables.add_route( network, nat=route['nat'], nat_interface=interface, ) self.iptables.generate()
def start(self): global _loaded local_iface = settings.local.host.local_iface if not _loaded: _loaded = True try: utils.check_call_silent([ 'modprobe', 'vxlan', ]) except subprocess.CalledProcessError: pass self.remove_iface() if not local_iface: logger.error('Failed to find local interface for vxlan', 'vxlan', vxlan_id=self.vxlan_id, server_id=self.server_id, host_id=settings.local.host_id, local_addr=settings.local.host.local_addr, ) raise ValueError('Failed to find local interface for vxlan') utils.check_output_logged([ 'ip', 'link', 'add', self.iface_name, 'type', 'vxlan', 'id', str(settings.vpn.vxlan_id_start + self.vxlan_id), 'dstport', '4789', 'dev', local_iface['interface'], 'nolearning', ], ignore_states=['File exists']) self.vxlan_mac = utils.get_interface_mac_address(self.iface_name) self._init_host() self.vxlan_addr = self.get_host_addr(self.host_vxlan_id) if self.ipv6: self.vxlan_addr6 = utils.ip4to6x64( settings.vpn.ipv6_prefix, self.vxlan_net, self.vxlan_addr, ) utils.check_output_logged([ 'ip', 'address', 'add', self.vxlan_addr + '/24', 'dev', self.iface_name, ], ignore_states=['File exists']) if self.ipv6: utils.check_output_logged([ 'ip', '-6', 'address', 'add', self.vxlan_addr6 + '/64', 'dev', self.iface_name, ], ignore_states=['File exists']) utils.check_output_logged([ 'ip', 'link', 'set', 'up', self.iface_name, ]) self._init_hosts()
def stop(self): try: utils.check_output_logged([ 'ip', 'link', 'set', 'down', self.bridge_interface, ]) except subprocess.CalledProcessError: pass try: utils.check_output_logged([ 'brctl', 'delbr', self.bridge_interface, ]) except subprocess.CalledProcessError: pass try: utils.check_output_logged([ 'iptables', '-D', 'INPUT', '-i', self.bridge_interface, '-j', 'ACCEPT', '-m', 'comment', '--comment', 'pritunl-%s' % settings.local.host_id, ]) except subprocess.CalledProcessError: pass try: utils.check_output_logged([ 'iptables', '-D', 'FORWARD', '-i', self.bridge_interface, '-j', 'ACCEPT', '-m', 'comment', '--comment', 'pritunl-%s' % settings.local.host_id, ]) except subprocess.CalledProcessError: pass host_int_data = self.host_interface_data host_interface = host_int_data['interface'] host_address = host_int_data['address'] host_netmask = host_int_data['netmask'] host_broadcast = host_int_data['broadcast'] host_gateway = host_int_data['gateway'] utils.check_output_logged([ 'ip', 'link', 'set', 'down', host_interface, ]) utils.check_output_logged([ 'ip', 'link', 'set', 'up', host_interface, ]) utils.check_output_logged([ 'ifconfig', host_interface, host_address, 'netmask', host_netmask, 'broadcast', host_broadcast, ]) if host_gateway: try: utils.check_output_logged([ 'route', 'add', 'default', 'gw', host_gateway, ]) except subprocess.CalledProcessError: pass
def start(self): host_int_data = self.host_interface_data host_interface = host_int_data['interface'] host_address = host_int_data['address'] host_netmask = host_int_data['netmask'] host_broadcast = host_int_data['broadcast'] host_gateway = host_int_data['gateway'] utils.check_output_logged([ 'iptables', '-I', 'FORWARD', '-i', self.bridge_interface, '-j', 'ACCEPT', '-m', 'comment', '--comment', 'pritunl_%s' % settings.local.host_id, ] + ['--wait'] if settings.local.iptables_wait else []) utils.check_output_logged([ 'iptables', '-I', 'INPUT', '-i', self.bridge_interface, '-j', 'ACCEPT', '-m', 'comment', '--comment', 'pritunl_%s' % settings.local.host_id, ] + ['--wait'] if settings.local.iptables_wait else []) utils.check_output_logged([ 'ip', 'link', 'set', 'down', host_interface, ]) utils.check_output_logged([ 'brctl', 'addbr', self.bridge_interface, ]) utils.check_output_logged([ 'brctl', 'addif', self.bridge_interface, host_interface, ]) utils.check_output_logged([ 'ifconfig', host_interface, '0.0.0.0', 'promisc', 'up', ]) utils.check_output_logged([ 'ifconfig', self.bridge_interface, host_address, 'netmask', host_netmask, 'broadcast', host_broadcast, ]) if host_gateway: utils.check_output_logged([ 'route', 'add', 'default', 'gw', host_gateway, ])
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 build_onc(self): temp_path = utils.get_temp_path() try: os.makedirs(temp_path) user_cert_path = os.path.join(temp_path, '%s.crt' % self.id) user_key_path = os.path.join(temp_path, '%s.key' % self.id) user_p12_path = os.path.join(temp_path, '%s.p12' % self.id) with open(user_cert_path, 'w') as user_cert: user_cert.write(self.certificate) with open(user_key_path, 'w') as user_key: os.chmod(user_key_path, 0600) user_key.write(self.private_key) utils.check_output_logged([ 'openssl', 'pkcs12', '-export', '-nodes', '-password', 'pass:'******'-inkey', user_key_path, '-in', user_cert_path, '-out', user_p12_path, ]) with open(user_p12_path, 'r') as user_key_p12: user_key_base64 = base64.b64encode(user_key_p12.read()) user_cert_id = '{%s}' % hashlib.md5( user_key_base64).hexdigest() os.remove(user_cert_path) os.remove(user_key_path) os.remove(user_p12_path) onc_nets = '' onc_certs_store = {} for svr in self.iter_servers(): onc_net, onc_certs = self._generate_onc( svr, user_cert_id) if not onc_net: continue onc_certs_store.update(onc_certs) onc_nets += onc_net + ',\n' onc_nets = onc_nets[:-2] if onc_nets == '': return None onc_certs = '' for cert_id, cert in onc_certs_store.items(): onc_certs += OVPN_ONC_CA_CERT % (cert_id, cert) + ',\n' onc_certs += OVPN_ONC_CLIENT_CERT % ( user_cert_id, user_key_base64) onc_conf = OVPN_ONC_CLIENT_CONF % (onc_nets, onc_certs) finally: utils.rmtree(temp_path) return onc_conf
def bridge_start(self): if self.server.network_mode != BRIDGE: return host_int_data = self.host_interface_data host_interface = host_int_data['interface'] host_address = host_int_data['address'] host_netmask = host_int_data['netmask'] host_broadcast = host_int_data['broadcast'] utils.check_output_logged([ 'ip', 'link', 'set', 'down', host_interface, ]) utils.check_output_logged([ 'openvpn', '--mktun', '--dev', self.interface, ]) utils.check_output_logged([ 'brctl', 'addbr', self.bridge_interface, ]) utils.check_output_logged([ 'brctl', 'addif', self.bridge_interface, host_interface, ]) utils.check_output_logged([ 'brctl', 'addif', self.bridge_interface, self.interface, ]) utils.check_output_logged([ 'ifconfig', self.interface, '0.0.0.0', 'promisc', 'up', ]) utils.check_output_logged([ 'ifconfig', host_interface, '0.0.0.0', 'promisc', 'up', ]) utils.check_output_logged([ 'ifconfig', self.bridge_interface, host_address, 'netmask', host_netmask, 'broadcast', host_broadcast, ])
def add_host(self, host_vxlan_id, vxlan_mac, host_dst, host_dst6): if settings.local.host.local_addr == host_dst: return self.running_lock.acquire() try: if not self.running: return for i in xrange(2): try: if i == 0: check_func = utils.check_output else: check_func = utils.check_output_logged check_func([ 'bridge', 'fdb', 'add', vxlan_mac, 'dev', self.iface_name, 'dst', host_dst, ], ignore_states=['File exists']) break except subprocess.CalledProcessError: if i == 0: utils.check_output_logged([ 'bridge', 'fdb', 'del', vxlan_mac, 'dev', self.iface_name, ]) else: raise utils.check_output_logged([ 'arp', '-s', self.get_host_addr(host_vxlan_id), vxlan_mac, ]) if host_dst6: for i in xrange(2): try: if i == 0: check_func = utils.check_output else: check_func = utils.check_output_logged check_func([ 'ip', '-6', 'neighbour', 'add', self.get_host_addr6(host_vxlan_id), 'lladdr', vxlan_mac, 'dev', self.iface_name, ], ignore_states=['File exists']) break except subprocess.CalledProcessError: if i == 0: utils.check_output_logged([ 'ip', '-6', 'neighbour', 'del', self.get_host_addr6(host_vxlan_id), 'dev', self.iface_name, ]) for j in xrange(30): try: utils.check_call_silent([ 'ip', '-6', 'neighbour', 'del', self.get_host_addr6(host_vxlan_id), 'dev', self.iface_name, ]) except: break time.sleep(0.5) else: raise except: logger.error('Failed to add vxlan host', 'vxlan', vxlan_id=self.vxlan_id, server_id=self.server_id, ) raise finally: self.running_lock.release()
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 build_onc_archive(self): temp_path = utils.get_temp_path() key_archive_path = os.path.join(temp_path, "%s.zip" % self.id) try: os.makedirs(temp_path) zip_file = zipfile.ZipFile(key_archive_path, "w") try: user_cert_path = os.path.join(temp_path, "%s.crt" % self.id) user_key_path = os.path.join(temp_path, "%s.key" % self.id) user_p12_path = os.path.join(temp_path, "%s.p12" % self.id) with open(user_cert_path, "w") as user_cert: user_cert.write(self.certificate) with open(user_key_path, "w") as user_key: os.chmod(user_key_path, 0600) user_key.write(self.private_key) utils.check_output_logged( [ "openssl", "pkcs12", "-export", "-nodes", "-password", "pass:"******"-inkey", user_key_path, "-in", user_cert_path, "-out", user_p12_path, ] ) zip_file.write(user_p12_path, arcname="%s.p12" % self.name) os.remove(user_cert_path) os.remove(user_key_path) os.remove(user_p12_path) for svr in self.org.iter_servers(): server_conf_path = os.path.join(temp_path, "%s_%s.onc" % (self.id, svr.id)) conf_name, client_conf = self._generate_onc(svr) if not client_conf: continue with open(server_conf_path, "w") as ovpn_conf: ovpn_conf.write(client_conf) zip_file.write(server_conf_path, arcname=conf_name) os.remove(server_conf_path) finally: zip_file.close() with open(key_archive_path, "r") as archive_file: key_archive = archive_file.read() finally: utils.rmtree(temp_path) return key_archive
def build_onc(self): temp_path = utils.get_temp_path() try: os.makedirs(temp_path) user_cert_path = os.path.join(temp_path, '%s.crt' % self.id) user_key_path = os.path.join(temp_path, '%s.key' % self.id) user_p12_path = os.path.join(temp_path, '%s.p12' % self.id) with open(user_cert_path, 'w') as user_cert: user_cert.write(self.certificate) with open(user_key_path, 'w') as user_key: os.chmod(user_key_path, 0600) user_key.write(self.private_key) utils.check_output_logged([ 'openssl', 'pkcs12', '-export', '-nodes', '-password', 'pass:'******'-inkey', user_key_path, '-in', user_cert_path, '-out', user_p12_path, ]) with open(user_p12_path, 'r') as user_key_p12: user_key_base64 = base64.b64encode(user_key_p12.read()) user_cert_id = '{%s}' % hashlib.md5( user_key_base64).hexdigest() os.remove(user_cert_path) os.remove(user_key_path) os.remove(user_p12_path) onc_nets = '' onc_certs_store = {} for svr in self.iter_servers(): onc_net, onc_certs = self._generate_onc(svr, user_cert_id) if not onc_net: continue onc_certs_store.update(onc_certs) onc_nets += onc_net + ',\n' onc_nets = onc_nets[:-2] if onc_nets == '': return None onc_certs = '' for cert_id, cert in onc_certs_store.items(): onc_certs += OVPN_ONC_CA_CERT % (cert_id, cert) + ',\n' onc_certs += OVPN_ONC_CLIENT_CERT % (user_cert_id, user_key_base64) onc_conf = OVPN_ONC_CLIENT_CONF % (onc_nets, onc_certs) finally: utils.rmtree(temp_path) return onc_conf
def start(self): host_int_data = self.host_interface_data host_interface = host_int_data['interface'] host_address = host_int_data['address'] host_netmask = host_int_data['netmask'] host_broadcast = host_int_data['broadcast'] host_gateway = host_int_data['gateway'] utils.check_output_logged([ 'iptables', '-I', 'FORWARD', '-i', self.bridge_interface, '-j', 'ACCEPT', '-m', 'comment', '--comment', 'pritunl-%s' % settings.local.host_id, ]) utils.check_output_logged([ 'iptables', '-I', 'INPUT', '-i', self.bridge_interface, '-j', 'ACCEPT', '-m', 'comment', '--comment', 'pritunl-%s' % settings.local.host_id, ]) utils.check_output_logged([ 'ip', 'link', 'set', 'down', host_interface, ]) utils.check_output_logged([ 'brctl', 'addbr', self.bridge_interface, ]) utils.check_output_logged([ 'brctl', 'addif', self.bridge_interface, host_interface, ]) utils.check_output_logged([ 'ifconfig', host_interface, '0.0.0.0', 'promisc', 'up', ]) utils.check_output_logged([ 'ifconfig', self.bridge_interface, host_address, 'netmask', host_netmask, 'broadcast', host_broadcast, ]) if host_gateway: utils.check_output_logged([ 'route', 'add', 'default', 'gw', host_gateway, ])