Sign inSign up

afreisinger/bot-vpn

By afreisinger

•Updated 5 months ago

Buildkit cache
Image
0

1.3K

afreisinger/bot-vpn repository overview

⁠VPN Bot

Build Docker Pulls License

Bot de Telegram para conectar a VPN usando openconnect con soporte completo de OTP, split tunneling y VPN-Slice.

⁠🚀 TL;DR — Docker

# 1. Clonar y configurar
git clone <tu-repo>
cd vpn-bot
cp .env.example .env
# Editar .env con TOKEN, VPN_OTP_SECRET, ALLOWED_USERS

# 2. Instalar udev rule en el HOST para DNS de la VPN
cd resolvectl && sudo ./install.sh && cd ..

# 3. Build y correr
docker compose up -d

# 4. Comandos en Telegram
/connect    # Conectar VPN
/disconnect # Desconectar
/status     # Estado de conexión
/health     # Verificar conectividad + DNS
/logs       # Últimas líneas del log
/system     # Info del sistema
/help       # Ayuda

⁠🎯 Características Principales

⁠🤖 Bot de Telegram
  • Comandos simples: /connect, /disconnect, /status, /system, /logs, /help
  • Control remoto completo de la VPN
  • Formato de duración legible (horas, minutos)
  • Verificación de usuario autorizado
⁠🔐 Sistema OTP (TOTP RFC 6238)
  • Generación automática de códigos de 6 dígitos
  • Secreto centralizado en archivo .env (variable VPN_OTP_SECRET)
  • Compatible con Google Authenticator y similares
  • Clave base32 ejemplo: OKUXVSDFRDK24KNRXQYDPUGSJV5OIB3JQ
⁠🛡️ VPN Completa
  • Conexión via openconnect (Cisco AnyConnect protocol)
  • Binario TNCC incluido (bin/tncc - 8.7MB)
  • Wrapper script (bin/tncc.sh) para portabilidad
⁠🛣️ Split Tunneling con VPN-Slice
  • VPN-Slice integrado: Split tunneling inteligente y configurable
  • Configuración dinámica: Subredes incluidas/excluidas desde YAML
  • Binario optimizado: bin/vpn-slice compilado para rendimiento
  • Wrapper incluido: bin/vpn-slice.sh para fácil ejecución
  • Opciones configurables: route-splits, verbose, host-names, etc.
⁠🔧 Perfiles Configurables
  • Múltiples perfiles: Soporte para diferentes conexiones VPN
  • Configuración YAML: Todo configurable en config/vpn_profiles.yaml
  • Perfil por defecto: Configurable via variable de entorno VPN_DEFAULT_PROFILE

⁠📋 Requisitos

⁠Sistema
  • Linux con kernel moderno
  • openconnect v9.12+
  • Python 3.8+
  • vpnc-scripts instalado
⁠Python Dependencias
  • python-telegram-bot==20.7
  • python-dotenv==1.0.0
  • pyyaml==6.0.1
  • psutil==5.9.8
  • pyotp==2.9.0

⁠🚀 Instalación Rápida en el host sin usar Docker

# 1. Clonar repositorio
git clone <tu-repositorio-vpn-bot>
cd vpn-bot

# 2. Instalar dependencias
./start.sh  # o pip install -r requirements.txt

# 3. Configurar variables de entorno
cp .env.example .env
# Editar .env con:
# - TOKEN (token de Telegram Bot de @BotFather)
# - VPN_OTP_SECRET (clave base32 para OTP)
# - AUTHORIZED_USER_ID (tu ID de Telegram)
# - VPN_DEFAULT_PROFILE (opcional, ej: "arca")

# 4. Iniciar bot
./start.sh

⁠⚙️ Configuración

⁠Archivo .env (CRÍTICO)
# Token del bot de Telegram (obtenido de @BotFather)
TOKEN=******tu_token_aqui******

# Secreto OTP base32 para generación de códigos
VPN_OTP_SECRET=******RXQYDPUGSJV5OI*******

# ID de usuario de Telegram autorizado
AUTHORIZED_USER_ID=123456

# Perfil VPN por defecto (opcional, usa el primero si no se define)
# VPN_DEFAULT_PROFILE=arca
⁠Configuración VPN (config/vpn_profiles.yaml)
profiles:
  # Perfil principal para VPN Arca
  arca:
    display_name: "VPN Arca"
    server: "as.arca.gob.ar/notebookArca"
    host: "as.arca.gob.ar"  # Host para TNCC
    username: "****CUIL****"
    auth_method: "password_otp"
    
    # Configuración de TNCC
    tncc:
      binary: "bin/tncc"
      wrapper: "bin/tncc.sh"
    
    # Configuración de VPN-Slice (split tunneling)
    slice:
      enable: true
      included_subnets:
        - "10.0.0.0/8"
      excluded_subnets:
        - "10.204.147.0/24"
      options:
        dump: false
        verbose: false
    
    # Configuración DNS post-conexión
    # En Docker: lo maneja la udev rule del host
    # En host directo: lo ejecuta resolvectl automáticamente
    dns:
      enabled: true
      interface: "tun0"
      check: "intranet.afip.gob.ar"  # Dominio para test de resolución
      servers:
        - "10.6.25.204"
      domains:
        - "~afip.gob.ar"
        - "~arca.gob.ar"
    
    # Healthcheck post-conexión
    healthcheck:
      enabled: true
      target: "10.30.251.70"  # Host interno a pinguear
      timeout: 10
      retries: 3
      interval: 2
⁠Variables de entorno adicionales
# Perfil VPN por defecto (opcional)
VPN_DEFAULT_PROFILE=arca

⁠🎮 Uso del Bot

⁠Comandos Disponibles
/start       - Iniciar interacción con el bot
/connect     - Conectar a VPN (perfil configurado)
/disconnect  - Desconectar VPN
/status      - Estado actual (con duración legible)
/health      - Verificar conectividad (ping + DNS)
/logs [N]    - Últimas N líneas del log del bot (default 30, max 200)
/system      - Información del sistema y verificación
/help        - Mostrar ayuda
⁠Flujo Normal de Uso
# 1. Iniciar bot (ya debería estar corriendo)
# 2. Conectar VPN
/connect

# 3. VPN-Slice maneja automáticamente el split tunneling
#    - Configura rutas según subredes definidas en YAML
#    - Mantiene internet pública para Telegram

# 4. Verificar estado
/status

# 5. Desconectar cuando termines
/disconnect

⁠🔧 Scripts de Utilidad

⁠bin/vpn-slice.sh

Wrapper para el binario VPN-Slice que configura split tunneling automáticamente:

  • Ejecuta bin/vpn-slice con parámetros de configuración
  • Maneja rutas relativas para portabilidad
⁠bin/vpn-slice

Binario compilado de VPN-Slice para split tunneling inteligente:

  • Configura rutas basadas en subredes incluidas/excluidas
  • Soporta múltiples opciones (route-splits, verbose, etc.)
  • Integrado automáticamente con openconnect
⁠bin/fix_vpn_routes.sh

Script de respaldo para corrección manual de rutas (si VPN-Slice falla):

  • Elimina ruta default por tun0
  • Configura solo 10.0.0.0/8 por VPN
  • Excepción: 10.204.147.0/24 por red local
  • Restaura internet pública (Telegram funciona)
⁠bin/test_routes.sh

Verifica que las rutas estén configuradas correctamente.

⁠bin/tncc.sh

Wrapper para el binario TNCC que asegura rutas relativas.

⁠🐛 Solución de Problemas

⁠Problema: "Bot deja de responder después de /connect"

Solución con VPN-Slice: Normalmente resuelto automáticamente. Solución de respaldo: Ejecutar ./bin/fix_vpn_routes.sh después de conectar.

⁠Problema: "VPN-Slice no configura rutas correctamente"

Verificar:

  1. Configuración de slice.enable: true en YAML
  2. Subredes definidas en included_subnets y excluded_subnets
  3. Permisos de ejecución en bin/vpn-slice y bin/vpn-slice.sh
  4. Logs del bot para mensajes de error
⁠Problema: "No se puede generar OTP"

Verificar:

  1. Variable VPN_OTP_SECRET en .env
  2. Librería pyotp instalada
  3. Secreto en formato base32 válido
⁠Problema: "Usuario no autorizado"

Solución: Configurar AUTHORIZED_USER_ID en .env con tu ID de Telegram.

⁠Problema: "Perfil VPN no encontrado"

Verificar:

  1. Perfil definido en config/vpn_profiles.yaml
  2. Variable VPN_DEFAULT_PROFILE coincide con nombre de perfil
  3. El bot muestra perfiles disponibles en logs de inicio

⁠📁 Estructura del Proyecto

vpn-bot/
├── bin/                    # Binarios y scripts
│   ├── tncc              # Binario TNCC (8.7MB)
│   ├── tncc.sh           # Wrapper para tncc
│   ├── vpn-slice         # Binario VPN-Slice (compilado)
│   ├── vpn-slice.sh      # Wrapper para VPN-Slice
├── config/               # Configuración
│   └── vpn_profiles.yaml # Perfiles VPN (configurables)
├── resolvectl/           # DNS setup para el HOST (via udev)
│   ├── 99-vpn-dns.rules # Regla udev (tun0 aparece → ejecuta script)
│   ├── resolvectl-vpn.sh # Script que ejecuta resolvectl
│   ├── install.sh        # Instalación
│   └── uninstall.sh      # Desinstalación
├── logs/                 # Logs persistentes (volume mount)
├── main.py               # Bot principal de Telegram
├── vpn_manager.py        # Gestor de conexiones VPN
├── start.sh              # Script de inicio (host directo)
├── Dockerfile            # Imagen Docker
├── docker-compose.yml    # Orquestación Docker
├── requirements.txt      # Dependencias Python
├── .env.example          # Plantilla de variables
└── README.md             # Esta documentación

⁠🌐 Resolución DNS para VPN (resolvectl + udev)

Cuando el contenedor usa network_mode: host, comparte la pila de red del host. El contenedor no tiene systemd-resolved adentro, por lo que la resolución DNS para la interfaz VPN se delega al host mediante una regla udev.

Cuando tun0 aparece (conexión VPN), la regla 99-vpn-dns.rules dispara automáticamente resolvectl-vpn.sh que configura systemd-resolved en el host.

⁠Archivos
resolvectl/
├── 99-vpn-dns.rules       # Regla udev (dispara en cada tun0 add)
├── resolvectl-vpn.sh      # Script que ejecuta resolvectl dns + domain
├── install.sh             # Instalación (run con sudo)
└── uninstall.sh           # Desinstalación
⁠Instalación

En el host (no dentro del contenedor):

cd resolvectl
sudo ./install.sh

Esto:

  1. Copia resolvectl-vpn.sh a /usr/local/bin/
  2. Copia 99-vpn-dns.rules a /etc/udev/rules.d/
  3. Recarga las reglas udev
  4. Si tun0 ya existe, corre el script inmediatamente
⁠Configuración

Valores actuales (editables en resolvectl-vpn.sh):

ParámetroValor
Interfaztun0
DNS10.6.25.204
Dominios~afip.gob.ar ~arca.gob.ar
⁠Verificación
# Ver DNS aplicado a tun0
resolvectl status tun0

# Verificar que la regla udev está activa
udevadm info --query=all --name=tun0 2>/dev/null | grep -i rules

# Probar resolución DNS real
resolvectl query intranet.afip.gob.ar

Salida esperada de resolvectl status tun0:

Link XX (tun0)
    Current Scopes: DNS
         Protocols: -DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 10.6.25.204
       DNS Servers: 10.6.25.204
        DNS Domain: ~afip.gob.ar ~arca.gob.ar
⁠Reconexión

Cada vez que la VPN reconecta, tun0 se destruye y recrea. La regla udev detecta cada ACTION=="add" y aplica el DNS automáticamente — no requiere intervención manual.

⁠🔒 Seguridad

  • OTP por variable de entorno (no hardcodeado)
  • Solo usuarios autorizados pueden usar el bot
  • Logs sin credenciales sensibles
  • TNCC con permisos restringidos
  • Scripts en directorio privado

⁠📄 Licencia

MIT License - Ver LICENSE file para detalles.

⁠🤝 Contribuciones

Las contribuciones son bienvenidas. Por favor, abre un issue o pull request.

⁠📞 Soporte

Para problemas o preguntas, abre un issue en GitHub.

Tag summary

Content type

Image

Digest

sha256:b4da27d24…

Size

93.5 MB

Last updated

5 months ago

docker pull afreisinger/bot-vpn