Una vez más aquí. Hoy vengo a dejar algo que un usuario me pidió hace unas semanas, y que por falta de tiempo no he podido colgar antes. Además, como quizás a otros usuarios también les pueda servir, pues aquí vengo a colgarlo. Este usuario ha contratado ExpressVPN y lo está utilizando en un sistema Ubuntu, como hago yo también. Pero el caso es que me ha dicho, si eres capaz, crea una GUI para ExpressVPN y así poder utilizarla desde el escritorio, sin necesidad de utilizar el navegador web y la terminal. Y como me gustan este tipo de «retos», y que como todos los usuarios que utilizamos esta VPN sabemos, el mayor «problema» que se le puede encontrar, es la falta de un cliente para el escritorio Gnu/Linux. Y bueno, después de pensarlo un poco, me puse manos a la obra, y aquí vengo a dejar este pequeño cliente «básico» para conectarse y administrar una suscripción de esta VPN desde el escritorio gracias a Python3 y TKinter.
Antes de pasar al turrón del artículo, hay que recordar que en la actualidad, la seguridad y la privacidad en línea son de vital importancia. Sobre todo si utilizas Kodi para ver tus series o películas favoritas y no quieres que tu ISP esté al tanto de a qué servicios te conectas. Una de las formas más efectivas de proteger nuestra conexión a Internet es a través del uso de VPNs (Redes Privadas Virtuales). Sin embargo, conectar y desconectar una VPN puede ser un proceso tedioso. Es por eso, en este artículo vamos a cer cómo crear una aplicación de escritorio utilizando Python y Tkinter que permite hacer este proceso de conexión y desconexión más sencillo, utilizando ExpressVPN.
Crea una GUI para ExpressVPN que puedes utilizar en GNOME
Esta aplicación que vamos a crear, necesita que el usuario disponga de una suscripción activa e instalada en Ubuntu (que es el sistema en el que he creado la aplicación). Si alguien quiere suscribirse y probar durante 30 días gratis esta VPN, solo necesita dirigirse a su página web utilizando el siguiente enlace.
ExpressVPN claramente ofrece mucho más que velocidad, la realidad es que esta VPN es famosa por su red ultra-rápida, la cual tiene 3.000+ servidores en 160+ ubicaciones. Aun que las VPNs suelen ralentizar las conexiones bastante, bien debido a sus potentes medidas de seguridad o bien por dirigir demasiado tráfico a través de servidores muy concurridos, este no es el caso que nos ocupa. Y esto es un puntazo, por que las velocidades más rápidas en la red de servidores, implica una experiencia de streaming sin buffering.
Y bueno, una vez instalada esta VPN en nuestro sistema, vamos a ver las cuatro «cosillas» que le he puesto en el código a esta GUI para utilizar ExpressVPN.
Funcionalidades de la Aplicación
- Una interfaz gráfica sencilla de utilizar: La aplicación presenta una interfaz gráfica limpia y fácil de usar que permite a los usuarios interactuar con la aplicación de manera intuitiva y rápida.
- Lista de servidores disponibles: La aplicación obtiene una lista de servidores disponibles utilizando la aplicación ExpressVPN instalada en el sistema. Esto proporciona a los usuarios una amplia gama de opciones para elegir. El listado de nombres son las abreviaturas que ofrece ExpressVPN.
- Estado de la conexión en tiempo real: La aplicación monitorea constantemente el estado de la conexión VPN. Esto se refleja en un círculo de estado visual, que cambia de color según el estado de la conexión (rojo para desconectado y verde para conectado).
- Conexión y desconexión con un clic: Los usuarios pueden conectar y desconectar la VPN con un solo clic en los botones «Conectar» y «Desconectar». Si el usuario intenta conectarse sin seleccionar un servidor, se muestra un mensaje de advertencia. Aun que en la última versión, cuando el sistema está conectado, el botón «Conectar» se dehabilita, y cuando está desconectado el sistema, el botón «Desconectar» se deshabilita.
- Actualización automática de la Interfaz: La aplicación actualiza dinámicamente la interfaz para reflejar el estado actual de la conexión y el servidor seleccionado.
Detalles del Código
El código se ha organizado en funciones que manejan tareas específicas. Esto facilita la comprensión y el mantenimiento del código en el futuro. A continuación, se describimos algunas partes clave del código:
- Obtención de la Lista de Servidores: La función
get_server_list()
utiliza la bibliotecasubprocess
para ejecutar el comandoexpressvpn list all
y obtener una lista de servidores disponibles.
- Obtención del Estado de Conexión: La función
get_connection_status()
verifica si el sistema está actualmente conectado a una VPN Express y devuelve el estado y el servidor al que está conectado. - Conexión y Desconexión de la VPN: Las funciones
connect_vpn(selected_server)
ydisconnect_vpn()
utilizansubprocess
para ejecutar los comandos de conexión y desconexión respectivamente. También actualizan el estado de la conexión y el servidor en la interfaz. - Actualización de la Interfaz Gráfica: Las funciones
update_status_and_server(server)
yupdate_circle_status()
actualizan las etiquetas y el círculo de estado en la interfaz gráfica según el estado de la conexión.
El código fuente. Crea una GUI para ExpressVPN
El código de la interfaz gráfica que vamos a crear es el siguiente:
import tkinter as tk from tkinter import ttk, messagebox import subprocess import re # Variable global para el estado de la conexión connected = False # Variable global para el color del círculo circle_color = "red" # Inicialmente, el círculo está en rojo (desconectado) # Obtener el listado de servidores def get_server_list(): try: result = subprocess.run(["expressvpn", "list", "all"], capture_output=True, text=True) output = result.stdout.strip().splitlines() # Obtener el primer grupo de letras de cada fila, omitiendo los dos primeros resultados locations = [line.split(None, 1)[0] for line in output[2:] if line.strip()] return locations except subprocess.CalledProcessError as e: print(f"Error al obtener la lista de servidores: {e}") return [] # Lista de servidores obtenidos de la aplicación ExpressVPN instalada en el sistema server_list = get_server_list() # Obtener el estado (Conectado o Desconectado) def get_connection_status(): try: result = subprocess.run(["expressvpn", "status"], capture_output=True, text=True) output = result.stdout.strip() if "Not connected" in output: return "Desconectado", "" else: server_line = re.search(r"Connected to (.*?)\n", output) server = server_line.group(1) if server_line else "" return "Conectado", server except subprocess.CalledProcessError as e: print(f"Error al obtener el estado de la conexión: {e}") return "Desconectado", "" # Función para conectar la VPN def connect_vpn(selected_server): global connected if not selected_server: messagebox.showwarning("Advertencia", "Primero debes seleccionar un servidor al que conectarte.") else: if connected: # Si ya estamos conectado, no se permite reconectar. También se deshabilita el botón conectar en otra parte del código messagebox.showinfo("Conexión VPN", "Ya estás conectado a un servidor.") else: try: subprocess.run(["expressvpn", "connect", selected_server]) connected = True # Actualiza el estado de la conexión update_status_and_server(selected_server) messagebox.showinfo("Conexión VPN", f"Conectado a {selected_server}.") except subprocess.CalledProcessError: messagebox.showerror("Error", "No se pudo conectar a ExpressVPN.") # Función para desconectar def disconnect_vpn(): global connected try: subprocess.run(["expressvpn", "disconnect"]) connected = False # Actualiza el estado de la conexión messagebox.showinfo("Conexión VPN", "Desconectado de ExpressVPN.") update_status_and_server("") except subprocess.CalledProcessError: messagebox.showerror("Error", "No se pudo desconectar de ExpressVPN.") # Función para actualizar el servidor y el estado def update_status_and_server(server): global status_label global server_label global connect_button global disconnect_button global circle_color # Añade una referencia al color del círculo # Etiquetas a mostrar en la aplicación status, _ = get_connection_status() status_label.config(text=f"Estado: {status}") server_label.config(text=f"Servidor: {server}" if server else "Servidor: ") # Cambia el texto y el color de fondo del botón según el estado de la conexión if connected: connect_button.config(state=tk.DISABLED) # Deshabilita el botón "Conectar" disconnect_button.config(state=tk.NORMAL) # Habilita el botón "Desconectar" circle_color = "green" # Cambia el color del círculo a verde cuando estás conectado else: connect_button.config(state=tk.NORMAL) # Habilita el botón "Conectar" disconnect_button.config(state=tk.DISABLED) # Deshabilita el botón "Desconectar" circle_color = "red" # Cambia el color del círculo a rojo cuando estás desconectado # Actualiza el círculo de estado update_circle_status() # Función para actualizar el color de círculo def update_circle_status(): status, _ = get_connection_status() if status == "Conectado": circle.config(bg="green") else: circle.config(bg="red") def create_vpn_window(): global status_label global server_label global connect_button global disconnect_button global circle # Añade una referencia al widget del círculo global connected # Añade esta línea para indicar que estás utilizando la variable global 'connected' global server_combobox connected = False # Añadimos esta línea para asegurarnos de que 'connected' se inicialice correctamente window = tk.Tk() window.title("Conexión - ExpressVPN") # El tooltip no funciona correctamente en todos los sistemas window.resizable(False, False) # Esta línea deshabilita el redimensionamiento de la ventana # Título dentro de la ventana label = tk.Label(window, text="Conexión a ExpressVPN", font=("Arial", 14)) label.grid(columnspan=2, pady=10) # Cargar la imagen img = tk.PhotoImage(file="ExpressVPN-logo.png") # Asignar la imagen como ícono de la ventana window.tk.call('wm', 'iconphoto', window._w, img) # Mostrar la imagen en un widget Label img_label = tk.Label(window, image=img) img_label.grid(columnspan=2, pady=(10, 10)) server_combobox = ttk.Combobox(window, values=server_list, state="readonly") server_combobox.grid(columnspan=2, pady=5) connect_button = tk.Button(window, text="Conectar", command=lambda: connect_vpn(server_combobox.get())) connect_button.grid(columnspan=2, pady=10) # Añade una etiqueta para el círculo junto a la etiqueta "Estado" circle = tk.Label(window, text="●", bg=circle_color, font=("Arial", 12)) circle.grid(row=5, column=0, padx=(5, 0), pady=10, sticky="e") # Coloca el círculo junto a la etiqueta "Estado" status_label = tk.Label(window, text="Estado: ") status_label.grid(row=5, column=1, pady=10, sticky="w") # Asegura que esté en la fila 5 disconnect_button = tk.Button(window, text="Desconectar", command=disconnect_vpn, state=tk.DISABLED) disconnect_button.grid(columnspan=2, pady=(10, 10)) # Aumenta el espacio inferior y superior a 10 píxeles server_label = tk.Label(window, text="Servidor: ") server_label.grid(columnspan=2, pady=(10, 10)) # Intenta obtener el estado de la conexión cuando se inicia la aplicación initial_status, initial_server = get_connection_status() if initial_status == "Conectado": connected = True update_status_and_server(initial_server) server_combobox.set(initial_server) window.mainloop() if __name__ == "__main__": create_vpn_window()
Dependencias
Para ejecutar este script, necesitarás tener instalado Python 3.11 y las bibliotecas tkinter y ttk en tu sistema. Estas bibliotecas están incluidas en la instalación estándar de Python, así que normalmente no debería ser necesario instalar nada adicional.
Nota: Después de probar esta GUI en Mint, he tenido que instalar tkinter con el siguiente comando:
sudo apt install python3-tk
Sin embargo, este script también depende de la herramienta expressvpn. Por eso, es necesario asegurarse de tener esta herramienta instalada y configurada correctamente en tu sistema. Si no la tienes, deberás instalarla antes de ejecutar el script.
Crea el script
El código que acabamos de ver, lo vamos a guardar dentro de un archivo llamado expressvpn.py, y asegurarnos de que este archivo tenga permisos de ejecución. Para esto, solo será necesario abrir una terminal (Ctrl+Alt+T) y movernos al directorio donde se encuentra este script. Después bastará con ejecutar el comando:
sudo chmod +x expressvpn.py
Crea un enlace directo desde el Dash
Si quieres poder abrir esta aplicación desde el Dash de Ubuntu, abre un editor de texto y crea un nuevo archivo. Puedes usar el siguiente comando en la terminal (Ctrl+Alt+T) para abrir el editor de texto Gedit:
gedit ~/.local/share/applications/tu_script.desktop
Esto abrirá Gedit y te permitirá crear un nuevo archivo de escritorio. Si prefieres otro editor, puedes usarlo en su lugar.
Llegados a este punto, adjunta el siguiente contenido al archivo (asegúrate de actualizar la ruta del script):
[Desktop Entry] Type=Application Name=Express-VPN Icon=/ruta/hasta/la/carpeta/de/la/imagen/ExpressVPN-logo.png Exec=python3 /ruta/hasta/el/script/expressvpn.py Version=1.0 Comment=Inicia la conexión VPN Terminal=false Path=/ruta/a/la/carpeta/donde/guardamos/el/script/expressvpn
Exec: Debes reemplazar /ruta/hasta/el/script/expressvpn.py con la ruta completa de tu script.
Name: Es el nombre que aparecerá en el acceso directo.
Comment: Es una descripción opcional.
Path: Indica solo la ruta. No es necesario añadir al final el nombre del archivo.
Icon: Indica la ruta de la imagen que queramos utilizar como icono.
Haz que el archivo sea ejecutable
Debes asegurarte de que el archivo .desktop sea ejecutable. Para hacerlo, ejecuta el siguiente comando:
sudo chmod +x ~/.local/share/applications/tu_script.desktop
Encuentra el Acceso Directo en tu Menú
Ahora deberías poder buscar y encontrar tu script en el menú de aplicaciones.
Esta aplicación de escritorio proporciona a los usuarios una forma rápida y sencilla de gestionar su conexión VPN utilizando ExpressVPN. La combinación de Python y Tkinter facilita la creación de una interfaz gráfica intuitiva y funcionalidades de automatización eficaces. Con esta herramienta, la seguridad en línea está al alcance de un clic.
Además de en esta página, el código con el que cualquiera crea una GUI para ExpressVPN, también se puede encontrar disponible en el repositorio de GitHub en el que lo he subido.
Se me olvidaba aclarar algo. Esta interfaz gráfica no tiene absolutamente nada que ver con la empresa propietaria de ExpressVPN, tan solo es una pequeña solución gráfica que he creado para mi uso personal, por lo que esto es algo que cada usuario debe utilizar bajo su propia responsabilidad.