Escenario on Premise: Modem Movistar, Proxmox, Mikrotik - perfeccion-ar/infraestructura-clasica-y-avanzada GitHub Wiki

TODO: ordenar

Desde abril de 2025, nuestra comunidad cuenta con un ambiente Dev: un Proxmox ubicado en Fundación Islas Malvinas, Mendoza. Se suma al ambiente Prod, con LXD que ya tenemos en Helsinki, bajo Hetzner

Este Proxmox fue instalado como cualquier Linux. Es de hecho por abajo, un Debian, en una PC con Ryzen 7 5600 y 32 GB de RAM

El propósito es usarlo para cubrir todos los escalones que van desde lo básico hasta el Cloud

image

Algunas notas y aprendizajes dispersos, que dejamos por aquí:

Proxmox Post instalación

Desde el Dashboard, quitar repositorios enterprise, y poner en su lugar los pve-no-suscription

Luego

sudo apt-get update && sudo apt-get dist-upgrade -y

Y reiniciar

Luego, aplicar scripts de aquí - https://community-scripts.github.io/ProxmoxVE/

Cómo tomar consola desde la terminal del Proxmox

  • En containers
    • Desde el shell del Proxmox
      • pct list
      • pct enter <numero de container>
    • Desde el PVE (Proxmox Virtual Environment, el Hypervisor), y para que que el container no pida contraseña (atacharse) - es decir:

... activar Console mode como shell

Cómo tomar consola en VMs

  • Detener VM
  • qm set 102 -serial0 socket - se puede hacer desde el GUI
  • Arrancar VM
  • qm terminal 102
  • Un enter de más - esto a veces confunde.
  • Pedirá usuario y contraseña. Usar los definidos en la plantilla.

Errores conocidos en Proxmox

Si la interface del Proxmox no responde, todos los componentes se ven grisados, con un ?, conectarse y hacer

$ ssh -p 10221 [email protected]

root@bunker4:~# systemctl restart pveproxy
root@bunker4:~# systemctl restart pvedaemon
root@bunker4:~# systemctl restart pvestatd

Armado de la red

Se combinó un Modem Movistar con IP Fija, enlazado a un Mikrotik, y enlazado finalmente al Proxmox. Lautaro Celedon, head de andestech.xyz, nos hizo la configuración inicial. Todo el proceso fue grabado:

  • Como configurar VLANs entre un Mikrotik y las VMs de un Proxmox
  • Como natear lo que entra al Mikrotik hacia las VMs
  • Como natear desde el Mikrotik hacia el Proxmox, completando el ciclo

El objeto, como siempre, es que el alumno pueda llegar independientemente a su container / VM, y que todo se encuentre en su propia VLAN.

Para ver la clase, haga clic en el siguiente enlace

Diagrama de red original creado por Lautaro Celedon

Mantenerlo fresco.

Imágenes cloud para VM

Otro gran aporte de Lautaro Celedon, para las VMs, fue enseñarnos a que en lugar de instalar las pesadas iso de Linux, podemos emplear imágenes "cloud", mas livianas, mejores para crear templates, clonarlas, etc, sin kernels pesados, pensados para operar sobre hardware real que en realidad no van a tener (porque son VMs)

Las imágenes VM son muy útiles cuando necesitamos mucha contención, un escritorio, o un Windows remoto. El mejor ejemplo puede ser el cliente Winbox: necesita Windows, o un Linux con al menos Xorg para levantar. Lo mismo para tener un navegador completo, para configurar por ejemplo, ciertos dashboards como el ngnix-proxy-manager, que no está abierto afuera.

Containers con Ubuntu 24

Se deja una template con Ubuntu 24 actualizada

Tras clonarla, ejecutar

dpkg-reconfigure locales

Elegir en_EN o es_AR por defecto

La hora por defecto está en UTC-0

date 
Sun May  4 22:17:46 UTC 2025

Usar dpkg-reconfigure tzdata si desea otra hora.

Containers con Archlinux

Son muy útiles para tener containers de borde (Nginx, Bastión, etc), que tienen que estar lo más actualizados posible. Tras desplegarlos, correr

  • pacman-key --init
  • pacman-key --populate archlinux
  • pacman -Sy archlinux-keyring
  • pacman -Syyu

Además, para poder acceder al Archlinux User Repository (AUR), por ejemplo mediante el comando yay, necesitamos correr

pacman -S --needed git base-devel && git clone https://aur.archlinux.org/yay-bin.git && cd yay-bin && env EUID=1000 makepkg -si

Para probar yay, instalar algo simple que esté en AUR:

yay ccze

Containers LXC con Archlinux, con Docker adentro

Para contener aún más, conviene que el Proxy Reverse, en este caso provisto por ngnix-proxy-manager, se encuentre también contenido. Lo pondremos bajo Docker, pero entendiendo que esto agrega una capa de dificultad. Esencialmente, estamos poniendo un container (Docker) adentro de otro Container (Linux Containers, LXC)

Para lograrlo, nesting debe estar activado desde el host Proxmox. Luego, en el container con Archlinux:

pacman -S docker
mkdir /etc/docker/
vim /etc/docker/daemon.json

Y adentro

{
  "dns": [
    "8.8.8.8",
    "8.8.4.4"
   ]
}

No es muy elegante poner los DNS así, pero lo sugieren en el wiki de Arch.

El Proxy Reverse

Instrumentado en uno de los containers con Arrchlinux, siguiendo los pasos provisto por Gerónimo, descriptos en https://github.com/perfeccion-ar/infraestructura-clasica-y-avanzada/wiki/Nginx-Proxy-Manager-GUI-con-servicios-bajo-Docker

El Bastión

Se establece para instrumentar túneles hacia los "endpoint" (genéricamente, containers o VM finales de los estudiantes). Son una mejor alternativa a las VPNs.

En mi experiencia, ninguna VPN de ningún cloud es confiable ni estable. Se soluciona poniendo un appliance OpenVPN, pero puede ser costoso para equipos grandes.

El truco consiste esencialmente, en llegar a un puerto ssh compartido por todos, entrar al Bastión, y luego hacer SSH hacia el siguiente destino. Sin embargo, es incómodo. El siguiente paso normalmente es crear un túnel.

Ejemplo de túnel que debería el alumno adaptar a sus necesidades:

https://github.com/perfeccion-ar/infraestructura-clasica-y-avanzada/blob/main/scripts/tunel.sh

Si para generar sus túneles, en lugar de un script desea entrar con un amigable gestionador de túneles, siga este link:

Idea original de los túneles del Bastión

La idea del Bastión la pude ver en una de las empresas para las cuales trabajé. Ellos usaban Gcloud, pero el ejemplo igual nos sirve para nuestro túnel. Los usuarios administradores (Devops, SRE, Infra, etc) se conectan desde ips dinámicas, domiciliarias. Y llegan "solo" hasta sus containers o hasta los servicios contratados (Kubernetes, MySQL, etc)

La secuencia de pasos es, en general, la siguiente:

Obtengo mi ip real

PUBLIC=$(curl ifconfig.me)

Me logueo con mis credenciales al cloud. Todos los clouds tienen algún comando para ello. En el caso de Google Cloud:

gcloud login

Antes de ir al firewall, apunto mi ambiente al proyecto en el que estoy trabajando

gcloud config set project algun_proyecto

Me fijo si en la regla con mi nombre en el firewall de GCloud, aquella que me deja llegar al Bastión, está actualizada mi ip pública actual

gcloud compute firewall-rules describe mi_regla_en_el_firewall | grep $PUBLIC

Puedo atrapar esa salida, por ejemplo

gcloud compute firewall-rules describe mi_regla_en_el_firewall | grep $PUBLIC
RES=$(echo $?)
if [ $RES -eq 0 ]
then
   echo "EL FIREWALL ESTA ACTUALIZADO Y TIENE NUESTRA ACTUAL IP REAL"
else
   echo "SE ACTUALIZA IP DE EQUIPO EN FIREWALL DE PROYECTO"
   gcloud compute firewall-rules update mi_regla_en_el_firewall --source-ranges=$PUBLIC/32
fi

Ahora sí, podemos usar un túnel como el ejemplificado recién, para llegar directamente a los servicios internos: https://github.com/perfeccion-ar/infraestructura-clasica-y-avanzada/blob/main/scripts/tunel.sh

Permisos limitados en el Bastión

El Bastión se supone que es solo un área de trasbordo, una zona desmilitarizada, sin permisos de sudo. Nadie esta en el grupo sudo (Debian, Ubuntu) ni en el wheel (RedHat, Arch)

Esto es un problema si algún estudiante quiere troubleshootear algo que esté ocurriendo en su container: un servicio que no anda, un firewall a nivel container que no lo deja pasar, etc.

Por lo tanto, lo que hice allí fue

  1. Instalar sudo
  2. Crear un grupo padawans
  3. Ponerlos a todos en el grupo padawans
  4. En /etc/sudoers, le puse permitir a todos los padawans, que puedan hacer sudo ping y sudo nmap. Lo hice con el comando visudo, más seguro para editar ese archivo.

image

Visual Studio Code

Se puede acceder al container cómodamente desde un Visual Studio Code

Opción uno: crear un tunel y desplegarse usando el plugin SSH (desarrollar) Opción dos: si tiene una compu con pocos recursos, quizas convenga levantar un Visual Code Server en el container, y consumirlo con un navegador desde su computadora

Para el segundo caso, los pasos consisten en loguearse al container (creando un túnel ssh), o pasando por el bastión, y luego saltando al container.

Una vez adentro del container, invocar estos comandos con un usuario (no usar root):

sudo apt update
sudo apt upgrade -y
curl -fsSL https://code-server.dev/install.sh | sh

Crear el directorio de configuración:

mkdir -p ~/.config/code-server

Crear el archivo de configuración:

vim ~/.config/code-server/config.yaml

Añadir la siguiente configuración al archivo:

bind-addr: 127.0.0.1:8080
auth: password
password: TU_CONTRASEÑA_SEGURA

Ejecutar

sudo systemctl daemon-reload
sudo systemctl enable --now code-server.service
sudo systemctl status code-server

Ahora solo resta hacerse un tunel hacia el puerto 8080 del container, y entrar en el navegador local como http://localhost:Puerto_local

To Do

Como sea, en nuestro ambiente, debemos:

  • Establecer algún mecanismo de Portknocking, o
  • Validación mediante algún formulario, un curl, etc, para que el mkt (o el Bastión) deje pasar solo ips dinámicas autenticadas. Idea: https://www.keycloak.org

Además, nos queda:

  • Prevenir ataques DoS: Fail2ban en el Bastión, una vez que esté terminado, para evitar brute force attacks, y fail2ban también en el ProxyReverse. Aunque quizás aquí debamos agregar algún WAF opensource: Revisar Kali Purple.
  • Experimentar túneles hacia el 443 del Kubernetes, como se hace en los clouds, para que los ingenieros puedan trabajar con los trucos y wrappers sobre kubectl que quieran (ej: meter Kubelens por el túnel). En gcloud esto se soluciona magníficamente mediante algún comando tipo
KUBECONFIG=~/.kube/config gcloud container clusters get-credentials mi_cluster --zone us-central1-a --project miproyecto

Y ahí sí, comenzar a disparar comandos kubectl.

Sergio