Setup de Parrot Security con bspwm + polybar + kitty + zsh + Neovim. Pensado para pentesting (HTB / THM), rice limpio y productividad en VM. Prompt unificado con dotfiles-windows vía oh-my-posh + tema capr4n.
| Componente | Para qué sirve |
|---|---|
| bspwm | Tiling window manager (binary space partitioning) |
| sxhkd | Daemon de atajos de teclado |
| polybar | Barra de estado modular (múltiples mini-barras flotantes) |
| picom | Compositor (sombras, transparencia, esquinas redondeadas) |
| rofi | Lanzador de aplicaciones y menús (powermenu, drun) |
| kitty | Emulador de terminal con soporte GPU |
| zsh + oh-my-posh (capr4n) | Shell interactiva + prompt cross-platform con git, exit status, etc. |
| Neovim + NvChad | Editor con LSP, autocompletado y formateadores |
| feh | Wallpaper |
| dunst | Notificaciones de escritorio |
| keychain | Reuso del ssh-agent entre sesiones |
Lo que verás al iniciar sesión:
- Paleta Monokai Soda unificada con dotfiles-windows (fondo
#1A1A1A, mismo en kitty, polybar y Windows Terminal). - Barras flotantes en lugar de una sola barra: workspaces (centro-arriba), VPN status (izquierda), Ethernet IP (izquierda), target de pentest (derecha) y botón de power-menu (esquina derecha).
- Workspaces con indicador visual: dot azul si estás ahí, amarillo si tiene ventanas abiertas pero no estás, gris si vacío.
- Esquinas redondeadas, transparencias y sombras a través de picom.
- Prompt oh-my-posh con tema capr4n: indicador de exit status (
✓/✗), rama git con cambios pendientes (✎), commits ahead/behind (↑ N/↓ N). - Aliases para reemplazar
cat/lsconbat/lsd(colores e iconos Nerd Font). - Funciones
settargetycleartargetintegradas con la barra: la IP/nombre del objetivo aparece en polybar mientras estás resolviendo una máquina.
¿Tu Parrot ya tiene bspwm, polybar, kitty, zsh, Neovim y los demás componentes funcionando, y solo quieres aplicar mis configs encima de las tuyas?
Salta los Pre-requisitos y arranca directo en el Paso 1. El install.sh es seguro para este caso porque:
- Detecta cada archivo de config existente (bspwmrc, sxhkdrc, kitty.conf, .zshrc, etc.)
- Le hace backup automático con sufijo
.pre-dotfiles.bakantes de tocarlo - Crea un symlink hacia el archivo del repo
Si después algo no te gusta, revertir es renombrar el .pre-dotfiles.bak de vuelta a su nombre original. No reinstala paquetes ni toca tus herramientas, solo cambia los archivos de configuración.
Si vas desde cero (instalación nueva de Parrot o no tienes el stack todavía), sigue estos pasos. Si ya lo tienes (caso de migración arriba), salta directo al Paso 1.
sudo apt update && sudo apt install -y \
bspwm sxhkd polybar picom rofi kitty zsh feh dunst \
bat lsd tmux git stow keychain \
zsh-autosuggestions zsh-syntax-highlighting \
ufw anonsurf unattended-upgrades pass \
fzfEl de apt suele estar desactualizado. Quitamos el viejo e instalamos el oficial:
sudo apt purge -y neovim
curl -L -o /tmp/nvim-linux-x86_64.tar.gz \
https://github.com/neovim/neovim/releases/latest/download/nvim-linux-x86_64.tar.gz
sudo tar -C /opt -xzf /tmp/nvim-linux-x86_64.tar.gz
sudo ln -sf /opt/nvim-linux-x86_64/bin/nvim /usr/local/bin/nvimEl
.zshrcañade/opt/nvim-linux-x86_64/binal PATH automáticamente.
# Prompt cross-platform (mismo binario y tema en Windows y Parrot)
curl -s https://ohmyposh.dev/install.sh | bash -s
# Fuzzy finder (Ctrl+R en historial)
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install --alloh-my-posh queda en
~/.local/bin/oh-my-posh. El.zshrclo invoca por path absoluto y solo si el binario existe, así que funciona también para root sin reconfiguración.
El tema capr4n usa iconos Nerd Font. Cualquiera de las dos funciona, pero CaskaydiaCove es la usada por dotfiles-windows, así que para mantener match visual recomendado:
wget -P /tmp \
https://github.com/ryanoasis/nerd-fonts/releases/latest/download/CascadiaCode.zip
sudo unzip -o /tmp/CascadiaCode.zip -d /usr/local/share/fonts/
sudo fc-cache -fvLas fuentes de polybar (Iosevka, Hurmit, Helvetica, Montserrat) ya están incluidas en polybar/.config/polybar/fonts/.
Para el atajo Super+Shift+X (bloquear pantalla con blur):
sudo apt install -y i3lock-fancyEl .zshrc incluye una línea condicional que cachea tu llave SSH con keychain (solo se ejecuta si la llave existe). Sirve para no escribir la passphrase en cada git push o ssh remoto.
¿Para qué se usa la llave SSH?
- GitHub / GitLab: clonar repos privados con
git clone git@github.com:..., hacer push sin pedir credenciales cada vez. - Servers remotos: SSH a VPS, máquinas de laboratorio, etc.
Si no tienes una llave todavía, créala con:
ssh-keygen -t ed25519 -C "tu_email@example.com"
# Se guarda en ~/.ssh/id_ed25519 (privada) y ~/.ssh/id_ed25519.pub (pública).
# La pública es la que pegas en GitHub → Settings → SSH and GPG keys.Si tu llave se llama distinto (id_rsa por ejemplo), edita la línea de keychain en zsh/.zshrc con el nombre correcto.
git clone https://github.com/M1gu3l4ngel/dotfiles-parrot.git ~/dotfiles
cd ~/dotfiles./install.shEl script:
- Hace backup automático de tus configs actuales con sufijo
.pre-dotfiles.bak. - Crea symlinks desde
~/.config/y~/hacia los archivos del repo. - Enlaza el wallpaper por defecto del repo a
~/.config/wallpaper.jpgsolo si no tienes ya uno (no pisa wallpapers personales). - Crea
~/.config/bin/targetvacío para que el módulo de target en polybar no falle la primera vez. - Es idempotente: corre N veces sin romper nada.
Si querés el firewall baseline (ufw) y la regla sudoers para el toggle de anonimato (Super+A), corré:
sudo ./system/setup.shEl script:
- Instala
/etc/sudoers.d/anon_togglecon permisos 0440, sustituye el placeholder__USER__por tu usuario actual, y valida convisudo -c. - Aplica reglas baseline de
ufw:default deny incoming,default allow outgoing,allow in on lo,allow in on tun+(para VPNs HTB/THM). - Verifica que
IPV6=yesesté en/etc/default/ufw(lo fuerza si no). - Activa
ufwcon start-on-boot. - Copia
user.jsal profilepentestde Firefox si ya existe (sino, indica cómo crearlo). - Instala
/etc/apt/apt.conf.d/52parrot-hardening.confque limitaunattended-upgradesaparrot-securityy blacklista herramientas críticas (tor, anonsurf, nmap, msf, burp, kernel).
Es idempotente: correrlo varias veces no rompe nada. Detalles en system/README.md.
chsh -s $(which zsh)Cierra sesión y vuelve a entrar para que el cambio tenga efecto. La primera vez que abras zsh, oh-my-posh cargará el tema capr4n directamente desde ~/dotfiles/oh-my-posh/capr4n.omp.json (no requiere wizard ni configuración inicial).
Cierra sesión gráfica, elige bspwm en el login manager, y vuelve a entrar. Atajos clave para empezar:
- Super + Enter → abrir kitty
- Super + D → lanzador de apps (rofi)
- Super + Shift + R → reiniciar bspwm
- Super + Escape → recargar sxhkd (después de editar atajos)
Lista completa en
sxhkd/.config/sxhkd/sxhkdrc.
| Atajo | Acción |
|---|---|
Super + Enter |
Abrir terminal (kitty) |
Super + D |
Lanzador rofi |
Super + A |
Toggle anonimato (Tor + anonsurf) |
Super + Shift + F |
Firefox personal (profile default-esr, intacto) |
Super + Shift + P |
Firefox pentest (profile aislado + user.js hardening) |
Super + Shift + X |
Bloquear pantalla (i3lock-fancy) |
Super + Escape |
Recargar sxhkd |
Super + Shift + R |
Reiniciar bspwm |
Super + Shift + Q |
Salir de bspwm (cierra sesión) |
| Atajo | Acción |
|---|---|
Super + Q |
Cerrar ventana (amable) |
Super + Shift + Q |
Matar ventana (forzado) |
Super + ←/↓/↑/→ |
Mover foco |
Super + Shift + ←/↓/↑/→ |
Mover ventana flotante |
Super + Alt + ←/↓/↑/→ |
Redimensionar ventana |
Super + T |
Modo tiled |
Super + S |
Modo floating |
Super + F |
Fullscreen |
Super + M |
Alternar monocle / tiled |
Super + G |
Intercambiar con la ventana más grande |
| Atajo | Acción |
|---|---|
Super + 1..9, 0 |
Saltar al workspace N |
Super + Shift + 1..9, 0 |
Enviar ventana al workspace N |
Super + [ / Super + ] |
Workspace anterior / siguiente |
Super + Tab |
Último workspace visitado |
| Atajo | Acción |
|---|---|
Ctrl + Shift + Enter |
Nueva ventana en el mismo directorio |
Ctrl + Shift + T |
Nueva pestaña en el mismo directorio |
Ctrl + Shift + Z |
Alternar layout (stack) |
Ctrl + Shift + F5 |
Recargar config de kitty |
El setup tiene integración nativa para tracking del target activo (útil para HTB/THM).
# Establecer máquina como target activo:
settarget 10.10.11.42 Cerberus
# Limpiar el target:
cleartargetsettarget escribe la IP + nombre en ~/.config/bin/target. El script victim_to_hack.sh (corriendo cada 2s vía polybar) lee ese archivo y muestra la info en la barra superior derecha:
🎯 10.10.11.42 - Cerberus
Si no hay target, muestra 🎯 No target.
La barra izquierda muestra el estado de la VPN. Detecta automáticamente la interfaz tun0 (la que crea OpenVPN):
- Conectada:
📡 10.10.14.x - Desconectada:
📡 Disconnected
Si tu VPN usa otra interfaz (WireGuard, varios túneles), ajusta el script en scripts/.config/scripts/vpn_status.sh.
La otra mini-barra de la izquierda muestra la IP de la interfaz Ethernet (por defecto ens33, típica en VMs). Para cambiarla, edita scripts/.config/scripts/ethernet_status.sh.
Super + A activa/desactiva todo el tráfico vía Tor. El script scripts/.config/scripts/toggle_anonymity.sh orquesta:
anonsurf startredirige TCP + DNS a Tor vía iptables.ip6tables -P OUTPUT DROPbloquea IPv6 (anonsurf solo cubre IPv4).iptables OUTPUT -p icmp -j DROPbloquea ping/traceroute leaks.curl https://check.torproject.org/api/ipvalida"IsTor":trueantes de declarar éxito. Si falla, rollback automático completo.
El módulo anon_status en polybar cambia entre power-off gris (OFF) y user-secret verde (ON). Click izquierdo también funciona como toggle.
Pre-requisitos: correr una vez sudo ./system/setup.sh para instalar la regla sudoers que permite al script ejecutar anonsurf/ip6tables/iptables sin password.
Verificación manual:
curl --max-time 15 -s https://check.torproject.org/api/ip
# {"IsTor":true,"IP":"x.x.x.x"} si todo OKPara evitar correlación entre tu identidad personal (Gmail, GitHub personal) y trabajo de pentest hay 2 profiles de Firefox separados:
| Profile | Atajo | Polybar | Cuándo usarlo |
|---|---|---|---|
default-esr |
Super + Shift + F |
zorro rojo | Personal (mail, GitHub, banking, daily) |
pentest |
Super + Shift + P |
bug verde | Targets, OSINT, links sospechosos, lab |
El profile pentest aplica un user.js (en system/firefox/pentest.user.js) con hardening light:
- WebRTC deshabilitado (previene leak de IP vía JS aún con VPN).
- Telemetría de Mozilla off.
- No guarda passwords ni autofill.
- HTTPS-Only mode.
- Limpia cookies, cache e historial al cerrar Firefox.
- Timezone forzado a UTC vía
TZ=UTCen el launcher de sxhkd/polybar. JS reporta UTC ennew Date().getTimezoneOffset()aunque tu sistema esté en hora local, evitando correlación geográfica por timezone. Firefox personal NO se toca (estás logueado con tu identidad real ahí, ocultar TZ rompería Gmail/Calendar sin agregar anonimato).
--no-remote en los lanzadores permite que ambos profiles corran simultáneamente sin que Firefox abra nueva pestaña en la primera instancia.
Setup inicial (correr una vez):
firefox -CreateProfile pentest # crea el profile vacío
sudo ./system/setup.sh # paso 5 copia el user.js al profileLos 2 íconos en la barra launchers de polybar (a la izquierda del target) también disparan los profiles vía click.
Combo full anonimato: Super + A (toggle ON) seguido de Super + Shift + P (Firefox pentest) = tráfico vía Tor + profile aislado + hardening. Es el stack más fuerte sin entrar en Tor Browser.
Para anonimato real (dark web, target nation-state): Tor Browser, no Firefox normal. El profile pentest no resiste fingerprinting agresivo a propósito (resistFingerprinting rompe muchos sitios target).
Super+A no se queda siempre encendido. Tor agrega 3 hops (latencia 500-2000ms), muchos sitios bloquean exit nodes (Cloudflare, bancos, Google), HTB/THM VPN no funciona sobre Tor, y apt update se vuelve glacial. Es una herramienta puntual, no un escudo 24/7. (Para "always-on" la arquitectura correcta es Whonix/Tails, no anonsurf en una VM.)
| Lo que vas a hacer | Anonimato | Profile Firefox | VPN |
|---|---|---|---|
| Gmail, GitHub personal, banking, daily browse | OFF | Personal | — |
| Lab HTB / THM (boxes pedagógicas) | OFF | Personal o Pentest | HTB VPN (tun0) |
| OSINT contra una persona/empresa real | ON | Pentest | — |
| Engagement real con cliente firmado | OFF | Pentest | VPN del cliente si pidieron IP fija |
| Click sospechoso / phishing / malware sandbox-ish | ON | Pentest | — |
| Investigar dark web | ON + Tor Browser | (no Firefox normal) | — |
apt update, descargar herramientas |
OFF | — | — |
Regla simple para activar Super+A:
- El target no debe ver tu IP real, Y
- No tenés VPN específica del engagement, Y
- Lo que vas a hacer no requiere latencia baja o ancho de banda alto.
En todo lo demás: anonimato OFF. El error común es ver Tor como "ON = seguro, OFF = inseguro" — en realidad es "ON = ocultá la IP a costa de velocidad/funcionalidad". Lo elegís en cada momento según el contexto.
Password manager Unix-style. Cada token/credencial se guarda como un archivo individual encriptado con GPG (la misma llave de la firma "Verified" en commits) bajo ~/.password-store/. Convierte ese directorio en repo git automáticamente, así tenés historial de cambios y sync opcional entre máquinas — todo encriptado.
Por qué no en .zshrc: un export GITHUB_TOKEN=ghp_xxx queda en texto plano, en backups del sistema, en el shared folder VMware, y posiblemente en git si commiteás .zshrc sin pensar. Con pass, el token nunca aparece en texto plano fuera del momento exacto de usarlo.
Setup inicial (una sola vez por máquina):
sudo apt install -y pass # ya está en pre-requisitos
pass init <tu-gpg-fingerprint> # del Tier 2 #5 (ver `gpg --list-secret-keys`)
pass git init # versionar el store con historial automáticoComandos diarios:
| Comando | Qué hace |
|---|---|
pass insert <nombre> |
Pide el valor (2 veces), lo encripta y guarda |
pass <nombre> |
Descifra y muestra (gpg-agent te puede pedir passphrase) |
pass -c <nombre> |
Copia al clipboard, auto-clear en 45s |
pass ls |
Lista el árbol completo de secrets |
pass edit <nombre> |
Abre en $EDITOR, re-encripta al guardar |
pass rm <nombre> |
Borra (pide confirmación) |
pass mv <viejo> <nuevo> |
Renombra/mueve |
pass git log |
Historial de cambios al store |
Convención de organización:
~/.password-store/
├── api/ # tokens de servicios externos
│ ├── shodan
│ ├── github-pat
│ └── virustotal
├── htb/ # creds que encontrás en boxes de HackTheBox
├── clients/ # engagements reales con clientes (rotar al cierre)
└── personal/ # uso diario (gmail, github, etc.)
Usar el valor sin pasarlo por texto plano:
# En lugar de:
curl -H "Authorization: Bearer ghp_xxxxxxxxxxxx" ... # token visible en history
# Usás:
curl -H "Authorization: Bearer $(pass api/github-pat)" ... # nunca apareceEl $(pass ...) se evalúa al runtime: el token se descifra, se pasa al comando, y el HISTORY_IGNORE del zshrc (matchea Authorization) lo bloquea del ~/.zsh__history.
Sync opcional con otra máquina: pass git remote add origin <repo> + pass git push. Como todo está encriptado, el repo PUEDE ser público (aunque típicamente se usa privado por costumbre).
Edita ~/dotfiles/oh-my-posh/capr4n.omp.json directamente, o sustituye por otro tema:
# Listar temas built-in:
ls ~/.cache/oh-my-posh/themes/
# Probar un tema sin tocar el repo:
eval "$(oh-my-posh init zsh --config ~/.cache/oh-my-posh/themes/dracula.omp.json)"
# Cambiar permanentemente:
# Edita ~/dotfiles/zsh/.zshrc y cambia la ruta en la línea del eval de oh-my-posh.cp /ruta/a/tu/wallpaper.jpg ~/.config/wallpaper.jpg
# Recargar bspwm:
bspc wm -r# Cambiar a dark:
cp ~/dotfiles/polybar/.config/polybar/colors_dark.ini \
~/dotfiles/polybar/.config/polybar/colors.ini
~/.config/polybar/launch.sh
# Cambiar a light:
cp ~/dotfiles/polybar/.config/polybar/colors_light.ini \
~/dotfiles/polybar/.config/polybar/colors.ini
~/.config/polybar/launch.shHay 25+ temas en rofi/.config/rofi/themes/. Edita rofi/.config/rofi/config.rasi y reemplaza el nombre tras @theme:
@theme "themes/spotlight-dark" // ejemplo
:Telescope themes
" o desde mappings: <leader>thO permanentemente en nvim/.config/nvim/lua/chadrc.lua:
M.base46 = { theme = "monekai" } -- cambia por: tokyonight, gruvbox, etc.Edita kitty/.config/kitty/kitty.conf:
font_family JetBrains Mono Nerd Font
font_size 14Edita sxhkd/.config/sxhkd/sxhkdrc siguiendo el formato:
super + shift + n
notify-send "hola"
Recarga con Super + Escape. No necesitas reiniciar la sesión.
dotfiles/
├── bspwm/ → ~/.config/bspwm/ (bspwmrc + scripts/)
├── sxhkd/ → ~/.config/sxhkd/ (sxhkdrc)
├── polybar/ → ~/.config/polybar/
│ ├── current.ini → bars activos (log, vpn, ethernet, target, launchers, primary)
│ ├── workspace.ini → bar central de workspaces
│ ├── colors.ini → paleta activa (Monokai Soda — sobrescribir con colors_dark/light si quieres)
│ ├── launch.sh → mata y relanza todas las barras
│ ├── scripts/ → launcher, powermenu (no scripts pentest)
│ └── fonts/ → Iosevka, Hurmit, Helvetica, etc.
├── picom/ → ~/.config/picom/
├── rofi/ → ~/.config/rofi/ (config.rasi + themes/)
├── kitty/ → ~/.config/kitty/ (kitty.conf + color.ini)
├── nvim/ → ~/.config/nvim/ (NvChad como base)
├── oh-my-posh/ → ~/dotfiles/oh-my-posh/ (capr4n.omp.json, sincronizado con dotfiles-windows)
├── scripts/ → ~/.config/scripts/
│ ├── ethernet_status.sh → IP Ethernet (polybar)
│ ├── vpn_status.sh → estado VPN (polybar)
│ ├── victim_to_hack.sh → lee target activo (polybar)
│ ├── toggle_anonymity.sh → toggle Tor + anonsurf (Super+A)
│ ├── anon_module.sh → estado anon para polybar
│ ├── firefox_personal_module.sh → icono launcher Firefox personal
│ └── firefox_pentest_module.sh → icono launcher Firefox pentest
├── zsh/.zshrc → ~/.zshrc
├── assets/ → preview.png + wallpaper.jpg default
├── system/ → configs de /etc + hardening Firefox + apt
│ ├── README.md
│ ├── setup.sh → instalador idempotente (sudoers + ufw + Firefox + apt)
│ ├── sudoers.d/
│ │ └── anon_toggle → template con __USER__ placeholder
│ ├── firefox/
│ │ └── pentest.user.js → hardening para profile Firefox "pentest"
│ └── apt/
│ └── 52parrot-hardening.conf → unattended-upgrades para parrot-security
├── install.sh → instalador idempotente
├── CONTRIBUTING.md → convenciones del proyecto (guía para PRs)
├── LICENSE → MIT
└── README.md → este archivo
Verifica que oh-my-posh está instalado y accesible:
ls -la ~/.local/bin/oh-my-posh
oh-my-posh --versionSi no existe, reinstala:
curl -s https://ohmyposh.dev/install.sh | bash -sTu fuente no tiene glyphs Nerd Font. Instala CaskaydiaCove o Hack:
wget -P /tmp \
https://github.com/ryanoasis/nerd-fonts/releases/latest/download/CascadiaCode.zip
sudo unzip -o /tmp/CascadiaCode.zip -d /usr/local/share/fonts/
sudo fc-cache -fvLuego configura kitty para usarla en kitty/.config/kitty/kitty.conf:
font_family CaskaydiaCove Nerd FontVerifica que bspwm esté corriendo (bspc query -W) y reinicia polybar:
~/.config/polybar/launch.shComprueba que el archivo existe y se está actualizando:
cat ~/.config/bin/target
settarget 10.10.10.1 TestMachine
cat ~/.config/bin/target # debe mostrar "10.10.10.1 TestMachine"Si el módulo sigue mostrando "No target", revisa que polybar tiene permisos de lectura (no debería ser un problema en uso normal).
El script asume que la interfaz se llama tun0. Verifica con ip link:
ip link | grep -i 'tun\|wg'Si tu VPN usa otra interfaz (ej. wg0, tun1), edita ~/.config/scripts/vpn_status.sh y reemplaza tun0.
Verifica que la llave existe:
ls ~/.ssh/id_ed25519Si tienes otra llave (id_rsa, etc.), edita el .zshrc:
[ -f "$HOME/.ssh/id_rsa" ] && eval $(keychain --eval --quiet id_rsa)Por defecto root no tiene oh-my-posh instalado (vive en ~/.local/bin/ del usuario, no del root). El .zshrc detecta esto y skipea el init silenciosamente. Para que root también tenga el tema:
# Symlink al binario del usuario:
sudo mkdir -p /root/.local/bin
sudo ln -sfn /home/$USER/.local/bin/oh-my-posh /root/.local/bin/oh-my-posh
# Symlink al repo de dotfiles:
sudo ln -sfn /home/$USER/dotfiles /root/dotfileskitty.conf lo establece a beam (barra), sobrescribiendo el Underline que pone color.ini. Si quieres Underline, comenta la línea cursor_shape beam en kitty.conf.
Verifica que el script existe y tiene permisos de ejecución:
ls -la ~/.config/bspwm/scripts/bspwm_resizeSi no aparece, vuelve a correr ./install.sh (es un symlink al repo).
Tu config previa está respaldada con sufijo .pre-dotfiles.bak:
ls -la ~/.config/bspwm/*.bak ~/.zshrc.pre-dotfiles.bak 2>/dev/nullRenombra el .bak al nombre original si quieres restaurar.
Si vas a contribuir, adaptar el repo o abrir un PR, las reglas de estilo, formato de commits y archivos protegidos están documentadas en CONTRIBUTING.md. El .editorconfig de la raíz hace además que tu editor respete la indentación correcta automáticamente.
Setup originalmente basado en el curso de personalización de Linux de S4vitar. Las configuraciones de bspwm, sxhkd, polybar y picom parten de su estilo y enfoque pedagógico.
El prompt y la paleta visual (Monokai Soda + tema capr4n) están alineados con mi setup paralelo de Windows en dotfiles-windows — mismo prompt cross-platform usando oh-my-posh.
Adaptado y mantenido por M1gu3l4ng3l para flujo personal de pentesting.
MIT — usa, copia, modifica libremente. Si te resulta útil, una ⭐ siempre se agradece.
Hecho con 🦜 por M1gu3l4ng3l
