def generate_ovpn_file(server_req): '''Generates OVPN files Tier 0(1) = Free Tier 1(2) = Basic Tier 2(3) = Plus Tier 3(4) = Visionary ---------- Feature 1: Secure Core Feature 2: Tor Feature 4: P2P Feature 8: XOR (not in use) Feature 16: IPV6 (not in use) ''' if not server_req: return False if walk_to_file(USER_FOLDER, OVPN_FILE.split("/")[-1]): delete_file(OVPN_FILE) if not create_file(OVPN_FILE, server_req.text): log.warning("Unable to create ovpn file for direct connection.") return False print("An ovpn file has bee created, try to establish a connection now.") return True
def restart_network_manager(self): try: output = subprocess.run(["systemctl", "restart", "NetworkManager"], stdout=subprocess.PIPE) print("\nRestarted network manager\n") log.info(f"Sucessfully restarted Network Manager: \"{output.stdout.decode()}\"") except: log.warning(f"Unable to restart Network Manager.") print("Cant restart network manager")
def fastest_country(self): if self.check_for_running_ovpn_process(): print("VPN already running.") return False server_feature_filter = [1, 2] server_collection = [] self.server_manager.cache_servers() country = input("Which country to connect to: ").strip().upper() file = country+SERVER_FILE_TYPE #load country configurations try: with open(os.path.join(CACHE_FOLDER, file)) as file: server_list = json.load(file) except TypeError: print("Servers are not cached.") log.warning("Servers are not cached.") return False #load user preferences try: user_pref = self.user_manager.read_user_data() except: print("Profile was not initialized.") log.warning("User profile was not initialized.") return False #filter by features and tier for server in server_list['serverList']: if server_list['serverList'][server]['features'] not in server_feature_filter and server_list['serverList'][server]['tier'] <= user_pref['tier']: server_collection.append(server_list['serverList'][server]) if not len(server_collection): print("Nothing") return False server_id, server_score, server_name, server_load = get_fastest_server(server_collection) user_pref['last_conn_server_id'] = server_id user_pref['last_conn_sever_name'] = server_name user_pref['last_conn_sever_protocol'] = user_pref['protocol'] server_req = req_for_ovpn_file(server_id, user_pref['protocol']) if not server_req: return False if not generate_ovpn_file(server_req): return False if not self.openvpn_connect(protocol=user_pref['protocol']): return False if not edit_file(USER_PREF_FILE, json.dumps(user_pref, indent=2), append=False): log.debug("Did not manage to save last connection preferences.") log.info(f"Updated user last connection data: \"{user_pref}\"")
def check_for_running_ovpn_process(self): openvpn_PID = False command_list = [["pgrep", "openvpn"], ["pid", "openvpn"]] #no need to try, since cmd_command already does that try: for command in command_list: return_code, openvpn_PID = cmd_command(command) if openvpn_PID: return openvpn_PID except: log.warning(f"Could not find any openvpn processes running.") return openvpn_PID
def manage_dns(action_type, dns_addr=False): resolv_conf_path = walk_to_file("/etc/", "resolv.conf", is_return_bool=False) if not resolv_conf_path: print("The \"resolv.conf\" file was not found on your system.") log.warning("\"resolv.conf\" file was not found.") return False log.info(f"Path to original resolv.conf: \"{resolv_conf_path}\"") print("Modifying dns...") if action_type == "custom": log.info("Applying custom ProtonVPN DNS...") cmd = f"cat > /etc/resolv.conf <<EOF \n# Generated by openvpn-linux-gui for ProtonVPN\nnameserver {dns_addr}\nEOF" try: shutil.copy(resolv_conf_path, RESOLV_BACKUP_FILE) except: print("Unable to backup DNS configurations.") log.warning("Unable to backup DNS configurations.") return False output = subprocess.run(["sudo", "bash", "-c", cmd], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) if not output.returncode == 0: print("Unable to update DNS configurations") log.warning("Unable to apply custom ProtonVPN DNS configurations.") print("DNS updated with new configurations.") log.debug(f"...custom ProtonVPN DNS applied: {output}") return True elif action_type == "restore": log.info("Restoring original DNS...") try: with open(RESOLV_BACKUP_FILE) as f: content = f.read() cmd = f"cat > /etc/resolv.conf <<EOF \n{content}\nEOF" subprocess.run(["sudo", "bash", "-c", cmd]) print("...DNS configurations were restored.") delete_file(RESOLV_BACKUP_FILE) log.info( f"Original configurations restored from: \"{RESOLV_BACKUP_FILE}\"" ) return True except: print( "Unable to restore original DNS configurations, try restarting the Network Manager." ) log.warning("Unable to restore original DNS configurations.") return False
def is_vpn_running(self): openvpn_PID = self.check_for_running_ovpn_process() cmd = "cat /etc/resolv.conf" res = subprocess.run(["sudo", "bash", "-c", cmd], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) # log.info(f"PID is: {'NONE' if not openvpn_PID else openvpn_PID}") if openvpn_PID and (res.returncode == 0 and ("10.8.8.1" in res.stdout.decode() or "10.7.7.1" in res.stdout.decode())): print("VPN is running with custom DNS.") log.info(f"VPN is running\nOVPN PID:{openvpn_PID}\nDNF conf:\n{res.stdout.decode()}") return True elif openvpn_PID and not (res.returncode == 0 and ("10.8.8.1" in res.stdout.decode() or "10.7.7.1" in res.stdout.decode())): print("VPN is running, but there might be DNS leaks. Try modifying your DNS configurations.") log.warning(f"Resolv conf has original values, custom ProtonVPN DNS configuration not found: {res.stdout.decode()}") return True else: print("VPN is not running.") log.info("Could not find any OpenVPN processes.") return False
def openvpn_disconnect(self): openvpn_PID = self.check_for_running_ovpn_process() is_connected = False print("Disconnecting from vpn server...") log.info(f"PID is: {'NONE' if not openvpn_PID else openvpn_PID}") if not openvpn_PID: print("Unable to disconnect, no OpenVPN process was found.") log.warning("Could not find any OpenVPN processes.") return False try: is_connected = get_ip_info() except: is_connected = False log.info(f"Tested for internet connection: \"{is_connected}\"") if not manage_dns(action_type="restore"): log.critical("Unable to restore DNS prior to disconnecting from VPN, restarting NetworkManager might be needed.") if not manage_ipv6(action_type="restore"): log.warning("Unable to enable IPV6 prior to disconnecting from VPN.") # if not manage_killswitch(action_type="restore"): # return False output = subprocess.run(["sudo","kill", "-9", openvpn_PID], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # SIGTERM - Terminate opevVPN, ref: https://www.poftut.com/what-is-linux-sigterm-signal-and-difference-with-sigkill/ if output.returncode != 0: print("Unable to disconnecto from VPN.") log.critical(f"Unable to disconnecto from VPN, \"{output}\"") return False log.info("Disconnected from VPN.") print("You are disconnected from VPN.") return True
def start_on_boot_manager(self, action): enabled_on_boot = True #load user preferences try: user_pref = self.user_manager.read_user_data() except: print("Profile was not initialized.") log.warning("User profile was not initialized.") return False if action == "enable": success_msg = "\"Launch on boot\" service enabled." fail_msg = "Cant enable \"launch on boot\" service." self.server_manager.cache_servers() server_collection = [] user_inp_country = input("Which country do you want to start on boot ? ").strip().upper() server_list_file = user_inp_country+SERVER_FILE_TYPE #load country configurations try: with open(os.path.join(CACHE_FOLDER, server_list_file)) as file: server_list = json.load(file) except TypeError: print("Servers are not cached.") log.warning("Servers are not cached.") return False print("Server name|\tServer Load|\tFeatures|\tTier") for server in server_list['serverList']: if server_list['serverList'][server]['tier'] <= user_pref['tier']: server_collection.append(server_list['serverList'][server]) print( server_list['serverList'][server]['name']+"|\t\t\t"+str(server_list['serverList'][server]['load'])+"|\t"+ str(server_list['serverList'][server]['features'])+"|\t\t"+str(server_list['serverList'][server]['tier']) ) if len(server_collection) == 0: print("No servers were found") return False user_selected_server = int(input("Which server to connecto on boot: ")) selected_server = [server for server in server_collection if str(user_selected_server) in server['name']][0] user_pref['on_boot_server_id'] = selected_server['id'] user_pref['on_boot_server_name'] = selected_server['name'] user_pref['on_boot_protocol'] = user_pref['protocol'] server_req = req_for_ovpn_file(selected_server['id'], user_pref['protocol']) if not server_req: return False if not generate_ovpn_for_boot(server_req): return False elif action == "kill": openvpn_PID = self.check_for_running_ovpn_process() if not openvpn_PID: print("Not PID was found") log.debug("Attempted to kill \"openvpn start on boot\" process, none found.") return False output = subprocess.run(["sudo","kill", "-9", openvpn_PID], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # SIGTERM - Terminate opevVPN, ref: https://www.poftut.com/what-is-linux-sigterm-signal-and-difference-with-sigkill/ if output.returncode != 0: print(f"Unable to kill PID {openvpn_PID}.") log.critical(f"Unable to disconnecto from VPN, \"{output}\"") return False self.restart_network_manager() return True elif action == "disable": success_msg = "\"Launch on boot\" service is disabled." fail_msg = "Cant disable service \"launch on boot\"." enabled_on_boot = False #here it should kill all openvpn processes and disable service daemon elif action == "restart": success_msg = "\"Launch on boot\" service was restarted." fail_msg = "Cant restart service \"launch on boot\"." try: output = subprocess.run(["sudo", "systemctl", action, ON_BOOT_PROCESS_NAME], stdout=subprocess.PIPE, stderr=subprocess.PIPE) log.debug(f"Start on boot log: {output}") except: print("\n"+fail_msg+"\n") log.critical("Something went wrong, could not enable \"start on boot\"") return False if not delete_folder_recursive(CACHE_FOLDER): log.debug("Unable to delete cache folder recursively.") print("\n"+success_msg+"\n") user_pref['on_boot_enabled'] = enabled_on_boot if not edit_file(USER_PREF_FILE, json.dumps(user_pref, indent=2), append=False): log.debug("Unable to save on boot preferences.") log.info(f"Start on boot created: \"{output.stdout.decode()}\"")
def openvpn_connect(self, protocol=False): openvpn_PID = self.check_for_running_ovpn_process() pre_vpn_conn_ip = False port_types = {"udp": 1194, "tcp": 443} if openvpn_PID: print("Unable to connect, a OpenVPN process is already running.") log.info("Unable to connect, a OpenVPN process is already running.") return False try: pre_vpn_conn_ip, pre_vpn_conn_isp = get_ip_info() except: pre_vpn_conn_ip = False pre_vpn_conn_isp = False log.info(f"Tested for internet connection: \"{pre_vpn_conn_ip}\"") if not pre_vpn_conn_ip: print("There is no internet connection.") log.warning("Unable to connect, check your internet connection.") print("Connecting to vpn server...") if not protocol: protocol = "udp" # Needs to be worked on, new way to connect to VPN, might help with killswitch with open(OVPN_LOG_FILE, "w+") as log_file: subprocess.Popen( [ "sudo", "openvpn", "--config", OVPN_FILE, "--auth-user-pass", USER_CRED_FILE ], stdout=log_file, stderr=log_file ) with open(OVPN_LOG_FILE, "r") as log_file: while True: content = log_file.read() log_file.seek(0) if "Initialization Sequence Completed" in content: print("VPN established") #change DNS dns_dhcp_regex = re.compile( r"(dhcp-option DNS )" r"(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})" ) dns_dhcp = dns_dhcp_regex.search(content) log.debug(f"DNS___RESULT: {dns_dhcp}") if dns_dhcp: dns_server = dns_dhcp.group(2) manage_dns(action_type="custom", dns_addr=dns_server) else: print("Could not apply custom DNS.") log.critical(f"Could not apply custom DNS: {dns_dhcp}") if not manage_ipv6(action_type="disable"): return False # if not manage_killswitch(action_type="enable", protocol=protocol, port=port_types[protocol]): # return False # compare old IP with new IP, if they are different the connection has succeded log.debug("Connected to the VPN.") return True elif "AUTH_FAILED" in content: print("Authentication failed") break