- Corregido error cuando el archivo freekeyval.dat no existe - Añadido valor por defecto para el servicio keyvalue - Implementado manejo defensivo para evitar errores de ejecución - Documentado el bloque de código con comentario explicativo 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
690 lines
18 KiB
Bash
690 lines
18 KiB
Bash
#!/bin/bash
|
|
#
|
|
# Library: base.lib
|
|
# Description: Base Developers Library
|
|
# Modified: 2024/11/30 15:27:00
|
|
# Derechos de Autor (C) [2024] [Mauro Rosero P. <mauro@roser.one>]
|
|
#
|
|
# Este programa es software libre: usted puede redistribuirlo y/o modificarlo
|
|
# bajo los términos de la Licencia Pública Affero General de GNU tal como
|
|
# lo publica la Free Software Foundation, ya sea la versión 3 de la licencia,
|
|
# o (a su elección) cualquier versión posterior.
|
|
#
|
|
# Este programa se distribuye con la esperanza de que sea útil,
|
|
# pero SIN NINGUNA GARANTÍA; sin siquiera la garantía implícita de
|
|
# COMERCIABILIDAD o IDONEIDAD PARA UN PROPÓSITO PARTICULAR. Consulte la
|
|
# Licencia Pública Affero General de GNU para obtener más detalles.
|
|
#
|
|
# Debería haber recibido una copia de la Licencia Pública Affero General
|
|
# junto con este programa. Si no la recibió, consulte <https://www.gnu.org/licenses/>.
|
|
|
|
DEVSPATH=${DEVSPATH:=devs}
|
|
CONFPATH=${CONFPATH:=config}
|
|
BIN_BASE=${BIN_BASE:=bin}
|
|
if [ -z "${BIN_HOME}" ]; then
|
|
BIN_HOME=${HOME}/${DEVSPATH}
|
|
fi
|
|
BIN_CONF=${BIN_CONF:=${BIN_BASE}/config}
|
|
BIN_SOPS=${BIN_SOPS:=${BIN_HOME}/sops}
|
|
BIN_MESG=${BIN_MESG:=${BIN_BASE}/msg}
|
|
BIN_LIBS=${BIN_LIBS:=${BIN_BASE}/lib}
|
|
DEVS_NAME=${CONFPATH}/project.head
|
|
GIT_IGNORE=.gitignore
|
|
DEVELOPER_DIR=${HOME}/.developer
|
|
DATENOW="$(date +"%Y-%m-%d %H:%M:%S")"
|
|
DATEBAK="$(date +"%Y%m%d%H%M%S")"
|
|
|
|
# Configuración del servicio de almacenamiento clave-valor
|
|
if [ -f "${BIN_PATH:=${BIN_HOME}}/${CONFPATH}/freekeyval.dat" ]; then
|
|
FREEKV_URL=$(cat < "${BIN_PATH}/${CONFPATH}/freekeyval.dat")
|
|
else
|
|
FREEKV_URL="https://keyvalue.immanuel.co"
|
|
fi
|
|
FREEKV_SOPS_FILE=freekv-sops.devs.yaml
|
|
|
|
DOCKER_LOCAL=dockerfile.local
|
|
DOCKER_BASE=dockerfile.base
|
|
DOCKER_SAAS=dockerfile.saas
|
|
DOCKER_BUILD=build
|
|
DOCKER_FILE=Dockerfile
|
|
DOCKER_ENTRY=entrypoint.sh
|
|
|
|
# Verificar si el script se está ejecutando como usuario root (superusuario)
|
|
function is_root() {
|
|
if [ "$(id -u)" -eq 0 ]; then
|
|
return 0 # Es root
|
|
else
|
|
return 1 # No es root
|
|
fi
|
|
}
|
|
|
|
# Escalar privilegios a superusuario si es necesario
|
|
# Esta función no ejecuta el script con sudo, solo verifica si tenemos privilegios
|
|
function check_root_privileges() {
|
|
if ! is_root; then
|
|
echo -e "\n${head_info}: Se requieren privilegios de administrador para esta operación."
|
|
|
|
# Verificar si sudo está instalado
|
|
command -v sudo >/dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
echo -e "${head_error}: El comando 'sudo' no está instalado. No se pueden escalar privilegios."
|
|
return 1
|
|
fi
|
|
|
|
# Informar que se necesita ejecutar con sudo
|
|
echo -e "${head_error}: Este script debe ejecutarse con sudo."
|
|
echo -e "${head_info}: Por favor, ejecute: sudo $0"
|
|
return 1
|
|
fi
|
|
|
|
# Ya es root, no necesita hacer nada
|
|
return 0
|
|
}
|
|
|
|
# Test library
|
|
function baselib_test() {
|
|
echo "Base Library loaded!"
|
|
exit 1
|
|
}
|
|
|
|
# Load messages
|
|
function load_messages() {
|
|
local BIN_PATH=$1
|
|
local MSG_PATH=$2
|
|
local LANGUAGE=$3
|
|
local MSG_FILE=$4
|
|
|
|
if [ -f $BIN_PATH/$MSG_PATH/$MSG_FILE.$LANGUAGE ]
|
|
then
|
|
source $BIN_PATH/$MSG_PATH/$MSG_FILE.$LANGUAGE
|
|
else
|
|
source $BIN_PATH/$MSG_PATH/$MSG_FILE.es
|
|
fi
|
|
}
|
|
|
|
# Display developers tools header
|
|
function display_devstools_header() {
|
|
local tittle=$1
|
|
|
|
clear
|
|
echo "$head_000 $head_002 $tittle"
|
|
echo "======================================================================"
|
|
}
|
|
|
|
# Display text header for tui dialog
|
|
function display_text_header() {
|
|
local head_text=$1
|
|
local subhead_text=$2
|
|
|
|
clear
|
|
if [ ! -z "${head_text}" ]; then
|
|
echo "${head_text}"
|
|
else
|
|
echo "$head_000 $head_002"
|
|
fi
|
|
if [ ! -z "${subhead_text}" ]; then
|
|
echo "${subhead_text}"
|
|
fi
|
|
echo "======================================================================"
|
|
}
|
|
|
|
# Display text header apps
|
|
function display_project_header() {
|
|
local PROJECT=$1
|
|
local tittle=$2
|
|
|
|
clear
|
|
echo "$(cat < $PROJECT/config/project.head) $tittle"
|
|
echo "======================================================================"
|
|
}
|
|
|
|
# Verify if your program or command is installed
|
|
function command_installed() {
|
|
local PROGRAM=$1
|
|
|
|
if command -v $PROGRAM &> /dev/null; then
|
|
return 0
|
|
fi
|
|
|
|
# No program or command is installed
|
|
return 1
|
|
}
|
|
|
|
# Install os packages
|
|
function os_pkgs_install() {
|
|
|
|
local PACKAGE=$1
|
|
|
|
echo "${pkg_install_begin} ${PACKAGE}"
|
|
if [ "$(uname)" == "Darwin" ]; then
|
|
# En macOS, a través de Homebrew
|
|
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
|
brew install $PACKAGE
|
|
elif [ -f /etc/debian_version ] || [ -f /etc/os-release ]; then
|
|
# En sistemas Debian y derivados, a través de apt
|
|
apt update
|
|
apt install -y $PACKAGE
|
|
elif [ -f /etc/redhat-release ]; then
|
|
# En sistemas Red Hat y derivados, a través de dnf
|
|
dnf install -y $PACKAGE
|
|
elif [ -f /etc/arch-release ]; then
|
|
# En Arch Linux, a través de pacman
|
|
pacman -Sy --noconfirm $PACKAGE
|
|
elif [ -f /etc/rc.conf ]; then
|
|
# En BSD, a través de pkg
|
|
pkg install -y $PACKAGE
|
|
else
|
|
echo "${os_nofound}"
|
|
exit 1
|
|
fi
|
|
echo "${pkg_install_success} ${PACKAGE}"
|
|
|
|
}
|
|
|
|
# Update or upgrade OS Packages
|
|
function os_update() {
|
|
|
|
if [ "$(uname)" == "Darwin" ]; then
|
|
echo "$os_update (BREW)"
|
|
brew upgrade
|
|
elif [ -f /etc/debian_version ] || [ -f /etc/os-release ]; then
|
|
echo "$os_update (APT)"
|
|
apt update && apt upgrade -y
|
|
elif [ -f /etc/redhat-release ]; then
|
|
echo "$os_update (DNF)"
|
|
dnf update -y
|
|
elif [ -f /etc/arch-release ]; then
|
|
echo "$os_update (PACMAN)"
|
|
pacman -Syu
|
|
elif [ -f /etc/rc.conf ]; then
|
|
echo "$os_update (PKG)"
|
|
pkg update && pkg upgrade
|
|
else
|
|
echo "${os_nofound}"
|
|
exit 1
|
|
fi
|
|
|
|
}
|
|
|
|
# Check for container manager installed
|
|
function container_mode() {
|
|
|
|
command_installed "podman"
|
|
if [ $? -eq 0 ]
|
|
then
|
|
return 0
|
|
else
|
|
command_installed "docker"
|
|
if [ $? -eq 0 ]
|
|
then
|
|
return 1
|
|
fi
|
|
fi
|
|
|
|
# Exit with code 255 if not docker or podman installed
|
|
return 255
|
|
|
|
}
|
|
|
|
# Read a file to convert to array
|
|
# Use global var ARRAY, set to empty before to call this function
|
|
function read_file_to_array() {
|
|
|
|
local afile="$1"
|
|
|
|
if [[ ! -f "${afile}" ]]; then
|
|
return 1
|
|
fi
|
|
|
|
while IFS= read -r line; do
|
|
ARRAY+=("${line}")
|
|
done < "${afile}"
|
|
|
|
return 0
|
|
}
|
|
|
|
|
|
# Git init repository
|
|
function git_init() {
|
|
|
|
local REPO_PATH=$1
|
|
local BRANCH=$2
|
|
|
|
git init "$REPO_PATH" -b $BRANCH
|
|
return $?
|
|
|
|
}
|
|
|
|
# Git add tracked files to repository
|
|
function git_add_full() {
|
|
|
|
local REPO_PATH=$1
|
|
|
|
cd $REPO_PATH
|
|
if [ $? -eq 0 ]; then
|
|
git add .
|
|
return $?
|
|
else
|
|
return 255
|
|
fi
|
|
|
|
}
|
|
|
|
# Git add tracked files to repository
|
|
function git_commit() {
|
|
|
|
local REPO_PATH=$1
|
|
local GIT_MESSAGES=$2
|
|
|
|
cd $REPO_PATH
|
|
if [ $? -eq 0 ]; then
|
|
git commit -m "$GIT_MESSAGES"
|
|
return $?
|
|
else
|
|
return 255
|
|
fi
|
|
|
|
}
|
|
|
|
# Git new remote project repository
|
|
function git_new_project() {
|
|
|
|
local REPO_PATH=$1
|
|
local REMOTE_PATH=$2
|
|
local GIT_PROJECT=$3
|
|
local BRANCH=$4
|
|
|
|
local REPO_REMOTE=$(printf "$REMOTE_PATH" "${GIT_PROJECT}")
|
|
echo "$REPO_REMOTE"
|
|
|
|
if [ -d $REPO_PATH ]
|
|
then
|
|
cd $REPO_PATH
|
|
if [ $? -eq 0 ]; then
|
|
git remote add origin $REPO_REMOTE
|
|
if [ $? -eq 0 ]; then
|
|
git checkout $BRANCH
|
|
if [ $? -eq 0 ]; then
|
|
git push --set-upstream origin $BRANCH
|
|
return $?
|
|
else
|
|
return 254
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
return 255
|
|
|
|
}
|
|
|
|
# Git clone repository
|
|
function git_clone_pull() {
|
|
|
|
local REPO_PATH=$1
|
|
local REPO_REMOTE=$2
|
|
local APPS=$3
|
|
local BRANCH=$4
|
|
|
|
if [ ! -d $REPO_PATH/$APPS ]
|
|
then
|
|
cd $REPO_PATH
|
|
if [ $? -eq 0 ]; then
|
|
git clone $REPO_REMOTE -b $BRANCH $APPS
|
|
return $?
|
|
else
|
|
return 255
|
|
fi
|
|
else
|
|
cd $REPO_PATH/$APPS
|
|
if [ $? -eq 0 ]; then
|
|
git pull
|
|
return $?
|
|
else
|
|
return 255
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Check for valid os system
|
|
function get_osname() {
|
|
|
|
if [ "$(uname)" == "Darwin" ]; then
|
|
# En macOS, instalamos o actualizamos a través de Homebrew
|
|
os_name=$(sw_vers -productVersion | awk -F '.' '{print "macOS " $1 "." $2}')
|
|
elif [ -f /etc/debian_version ] || [ -f /etc/os-release ]; then
|
|
# En sistemas Debian y derivados, instalamos o actualizamos a través de apt
|
|
os_name=$(grep "^ID_LIKE=" /etc/os-release | cut -d= -f2)
|
|
if grep -qi "${head_ubuntu}" /etc/os-release
|
|
then
|
|
os_name="${head_ubuntu}"
|
|
fi
|
|
elif [ -f /etc/redhat-release ]; then
|
|
# En sistemas Red Hat, instalamos o actualizamos a través de dnf
|
|
os_name=$(awk '{print $1}' /etc/redhat-release)
|
|
elif [ -f /etc/arch-release ]; then
|
|
# En Arch Linux, instalamos o actualizamos a través de pacman
|
|
os_name=$(grep '^NAME=' /etc/os-release | awk -F '"' '{print $2}')
|
|
elif [ -f /etc/rc.conf ]; then
|
|
# En BSD, instalamos o actualizamos a través de pkg
|
|
os_name=$(awk '{print $2}' /etc/version | awk -F '-' '{print $1}')
|
|
else
|
|
os_name="${head_unknow}"
|
|
fi
|
|
|
|
}
|
|
|
|
# Build container with docker
|
|
function docker_build() {
|
|
|
|
local CONTAINER=$1
|
|
local BASE_IMAGE=$2
|
|
|
|
docker build ./build -t ${CONTAINER} --build-arg BASE_IMAGE=${BASE_IMAGE}
|
|
return $?
|
|
|
|
}
|
|
|
|
# Build container with podman
|
|
function podman_build() {
|
|
|
|
local CONTAINER=$1
|
|
local BASE_IMAGE=$2
|
|
|
|
local registry_path=~/.config/containers
|
|
|
|
if [ ! -d ${registry_path} ]
|
|
then
|
|
mkdir ${registry_path}
|
|
fi
|
|
|
|
echo 'unqualified-search-registries = ["docker.io"]' > "${registry_path}/registries.conf"
|
|
podman build ./build -t ${CONTAINER} --format docker --build-arg BASE_IMAGE=${BASE_IMAGE}
|
|
return $?
|
|
|
|
}
|
|
|
|
# Build container with podman or docker
|
|
function build_container() {
|
|
|
|
local CONTAINER=$1
|
|
local BASE_IMAGE=$2
|
|
|
|
# Verificar si Docker está instalado
|
|
if command -v docker &> /dev/null
|
|
then
|
|
docker_build "$CONTAINER" "$BASE_IMAGE"
|
|
return $?
|
|
fi
|
|
|
|
# Verificar si Podman está instalado
|
|
if command -v podman &> /dev/null
|
|
then
|
|
podman_build "$CONTAINER" "$BASE_IMAGE"
|
|
return $?
|
|
fi
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
# Get sops token for free remote key/value server
|
|
function sops_freekv_token() {
|
|
|
|
local rc=0
|
|
local sops_file="${BIN_SOPS}/${FREEKV_SOPS_FILE}"
|
|
|
|
if [ ! -f "${sops_file}" ]; then
|
|
return 1
|
|
fi
|
|
|
|
token=$(sops -d ${sops_file} | yq .freekv_devs_token)
|
|
rc=$?
|
|
if [ $rc -ne 0 ]; then
|
|
return $rc
|
|
fi
|
|
|
|
if [ -n "${token}" ]; then
|
|
return 2
|
|
fi
|
|
|
|
echo "${token}"
|
|
return 0
|
|
|
|
}
|
|
|
|
# Alias claude code to cortana
|
|
cortana_alias() {
|
|
local alias_nombre="cortana"
|
|
local alias_comando=""
|
|
local shell_config=""
|
|
local title="${head_000} ${head_002}"
|
|
|
|
# Determinar la ruta del comando claude
|
|
if [[ -x "$HOME/.npm-global/bin/claude" ]]; then
|
|
alias_comando="$HOME/.npm-global/bin/claude"
|
|
else
|
|
alias_comando="claude" # Fallback al comando en el PATH
|
|
fi
|
|
|
|
# Detectar el shell actual y seleccionar el archivo de configuración adecuado
|
|
case "$SHELL" in
|
|
*/bash)
|
|
shell_config="$HOME/.bashrc"
|
|
;;
|
|
*/zsh)
|
|
shell_config="$HOME/.zshrc"
|
|
;;
|
|
*)
|
|
dialog --backtitle "${title}" --title "${head_error}" --msgbox "${npm_040}" 7 50
|
|
return 1
|
|
;;
|
|
esac
|
|
|
|
# Verificar si el alias ya existe en el archivo de configuración
|
|
if grep -q "alias $alias_nombre=" "$shell_config"; then
|
|
dialog --backtitle "${title}" --title "${npm_034}" --msgbox "${npm_035} $shell_config" 7 60
|
|
return 2
|
|
else
|
|
# Agregar el alias al final del archivo de configuración
|
|
echo "alias $alias_nombre='$alias_comando'" >> "$shell_config"
|
|
if [[ $? -eq 0 ]]; then
|
|
# Recargar el archivo de configuración
|
|
source "$shell_config" 2>/dev/null || true
|
|
dialog --backtitle "${title}" --title "${npm_036}" --msgbox "${npm_037} $shell_config\n\n${npm_038}" 9 60
|
|
else
|
|
dialog --backtitle "${title}" --title "${head_error}" --msgbox "${npm_039}" 7 50
|
|
return 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Remove cortana alias
|
|
remove_cortana_alias() {
|
|
local alias_nombre="cortana"
|
|
local shell_config=""
|
|
local title="${head_000} ${head_002}"
|
|
|
|
# Detectar el shell actual y seleccionar el archivo de configuración adecuado
|
|
case "$SHELL" in
|
|
*/bash)
|
|
shell_config="$HOME/.bashrc"
|
|
;;
|
|
*/zsh)
|
|
shell_config="$HOME/.zshrc"
|
|
;;
|
|
*)
|
|
dialog --backtitle "${title}" --title "${head_error}" --msgbox "${npm_040}" 7 50
|
|
return 1
|
|
;;
|
|
esac
|
|
|
|
# Verificar si el alias existe en el archivo de configuración
|
|
if grep -q "alias $alias_nombre=" "$shell_config"; then
|
|
# Eliminar el alias del archivo de configuración
|
|
sed -i "/alias $alias_nombre=/d" "$shell_config"
|
|
if [[ $? -eq 0 ]]; then
|
|
dialog --backtitle "${title}" --title "${npm_041}" --msgbox "${npm_042} $shell_config" 7 60
|
|
else
|
|
dialog --backtitle "${title}" --title "${head_error}" --msgbox "${npm_039}" 7 50
|
|
return 1
|
|
fi
|
|
else
|
|
dialog --backtitle "${title}" --title "${npm_043}" --msgbox "${npm_044}" 7 50
|
|
return 2
|
|
fi
|
|
}
|
|
|
|
# Verifica si el sistema está conectado a una VPN
|
|
# Devuelve 0 si está conectado a una VPN, 1 si no lo está
|
|
is_connected_to_vpn() {
|
|
local vpn_interfaces=("tun" "tap" "ppp" "wg" "wireguard" "nordlynx" "mullvad" "proton")
|
|
local found_vpn=0
|
|
|
|
# Verificar si existe alguna interfaz VPN activa
|
|
for vpn_type in "${vpn_interfaces[@]}"; do
|
|
if ip addr | grep -q "${vpn_type}"; then
|
|
found_vpn=1
|
|
break
|
|
fi
|
|
done
|
|
|
|
# Verificar si hay procesos VPN en ejecución
|
|
if [ $found_vpn -eq 0 ]; then
|
|
for proc in "openvpn" "wireguard" "wg" "nordvpn" "protonvpn" "pritunl" "anyconnect" "vpnc"; do
|
|
if pgrep -x "$proc" >/dev/null; then
|
|
found_vpn=1
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Verificar conexiones de red que puedan indicar VPN
|
|
if [ $found_vpn -eq 0 ]; then
|
|
if netstat -rn | grep -q "tun\|tap\|ppp\|wg"; then
|
|
found_vpn=1
|
|
fi
|
|
fi
|
|
|
|
# Verificar reglas de firewall que puedan indicar VPN
|
|
if [ $found_vpn -eq 0 ]; then
|
|
if command -v iptables >/dev/null && iptables -L | grep -qi "vpn\|tunnel"; then
|
|
found_vpn=1
|
|
fi
|
|
fi
|
|
|
|
if [ $found_vpn -eq 1 ]; then
|
|
return 0 # Está conectado a una VPN
|
|
else
|
|
return 1 # No está conectado a una VPN
|
|
fi
|
|
}
|
|
|
|
# Identifica el tipo de VPN al que está conectado el sistema
|
|
# Devuelve el nombre del tipo de VPN o "Unknown" si no se puede determinar
|
|
# Si no está conectado a ninguna VPN, devuelve "Not Connected"
|
|
get_vpn_type() {
|
|
# Primero verificamos si hay una conexión VPN
|
|
is_connected_to_vpn
|
|
if [ $? -ne 0 ]; then
|
|
echo ""
|
|
return 1
|
|
fi
|
|
|
|
# Mapa de procesos VPN y su tipo correspondiente
|
|
declare -A vpn_process_map=(
|
|
["openvpn"]="OpenVPN"
|
|
["pritunl"]="Pritunl"
|
|
["pritunl-client"]="Pritunl"
|
|
["nordvpnd"]="NordVPN"
|
|
["protonvpn"]="ProtonVPN"
|
|
["wg-quick"]="WireGuard"
|
|
["wg"]="WireGuard"
|
|
["mullvad"]="Mullvad"
|
|
["expressvpnd"]="ExpressVPN"
|
|
["anyconnect"]="Cisco AnyConnect"
|
|
["vpnc"]="Cisco VPN"
|
|
["openconnect"]="OpenConnect"
|
|
["pppd"]="PPTP/L2TP"
|
|
["sstp-client"]="SSTP"
|
|
["tailscaled"]="Tailscale"
|
|
["zerotier-one"]="ZeroTier"
|
|
)
|
|
|
|
# Buscar procesos VPN conocidos
|
|
for proc in "${!vpn_process_map[@]}"; do
|
|
if pgrep -x "$proc" >/dev/null; then
|
|
echo "${vpn_process_map[$proc]}"
|
|
return 0
|
|
fi
|
|
done
|
|
|
|
# Si no encontramos procesos específicos, intentamos identificar por interfaces
|
|
if ip addr | grep -q "tun"; then
|
|
# Identificar si es Pritunl (tiene prioridad)
|
|
if systemctl is-active --quiet pritunl-client.service || pgrep -f "pritunl-client" >/dev/null || ps aux | grep -q "[p]ritunl"; then
|
|
echo "Pritunl"
|
|
# Verificar configuración de Pritunl
|
|
elif [ -d "$HOME/.pritunl" ] || [ -d "/etc/pritunl-client" ]; then
|
|
echo "Pritunl"
|
|
# Buscar indicadores adicionales de Pritunl
|
|
elif grep -q "pritunl" /var/log/syslog 2>/dev/null || grep -q "pritunl" /var/log/messages 2>/dev/null; then
|
|
echo "Pritunl"
|
|
# Verificar si es OpenVPN genérico
|
|
elif ps aux | grep -q "[o]penvpn"; then
|
|
echo "OpenVPN"
|
|
else
|
|
echo "TUN-based VPN"
|
|
fi
|
|
return 0
|
|
elif ip addr | grep -q "wg"; then
|
|
echo "WireGuard"
|
|
return 0
|
|
elif ip addr | grep -q "ppp"; then
|
|
echo "PPP-based VPN"
|
|
return 0
|
|
elif ip addr | grep -q "nordlynx"; then
|
|
echo "NordVPN (NordLynx)"
|
|
return 0
|
|
elif ip addr | grep -q "proton"; then
|
|
echo "ProtonVPN"
|
|
return 0
|
|
elif ip addr | grep -q "mullvad"; then
|
|
echo "Mullvad"
|
|
return 0
|
|
elif ip addr | grep -q "tailscale"; then
|
|
echo "Tailscale"
|
|
return 0
|
|
elif ip addr | grep -q "zt"; then
|
|
echo "ZeroTier"
|
|
return 0
|
|
fi
|
|
|
|
# Verificar servicios conocidos de VPN
|
|
if systemctl is-active --quiet nordvpnd; then
|
|
echo "NordVPN"
|
|
return 0
|
|
elif systemctl is-active --quiet protonvpn; then
|
|
echo "ProtonVPN"
|
|
return 0
|
|
elif systemctl is-active --quiet wg-quick@; then
|
|
echo "WireGuard"
|
|
return 0
|
|
elif systemctl is-active --quiet tailscaled; then
|
|
echo "Tailscale"
|
|
return 0
|
|
elif systemctl is-active --quiet zerotier-one; then
|
|
echo "ZeroTier"
|
|
return 0
|
|
fi
|
|
|
|
# Verificar específicamente Pritunl (adicional)
|
|
if systemctl is-active --quiet pritunl-client.service || [ -d "$HOME/.pritunl" ] || [ -d "/etc/pritunl-client" ]; then
|
|
echo "Pritunl"
|
|
return 0
|
|
fi
|
|
|
|
# Si llegamos hasta aquí, no pudimos identificar específicamente el tipo de VPN
|
|
echo "Unknown VPN"
|
|
return 0
|
|
}
|