Practica Parte 1 Virtualización:

Vamos a crear una infraestructura con varias máquinas virtuales y contenedores donde vamos a instalar un servidor DHCP para configurar de forma dinámica la configuración de red.

img

1. Creación de las plantillas para las máquinas clientes.

1.1 Crea con virt-install una máquina virtual de Debian 12 con formato qcow2 y un tamaño de 3GiB.

  • La máquina debe tener un usuario debian con contraseña debian que puede utilizar sudo sin contraseña.
  • Instala el servidor ssh en la máquina.
  • En el usuario debian copia tu clave pública para que podamos acceder sin introducir la contraseña por ssh.

Antes de comenzar, hay que tener un bridge br0 ya creado, para saber como hacerlo pincha aquí . Gracias a Jose Domingo por un trabajo excelente.

Para crear la máquina:

virt-install --connect qemu:///system \
                         --virt-type kvm \
                         --name deboriginal \
                         --cdrom ~/Descargas/Sistemas\ Operativos/debian-12.2.0-amd64-netinst.iso\
                         --os-variant debian10 \
                         --disk size=3 \
                         --memory 1024 \
                         --vcpus 1
- name: Nombre que tendrá la máquina.

- cdrom: La ubicación de la imagen ISO para instalar el sistema.

- os-variant: El tipo de sistema.

- disk size: El tamaño que tendrá el disco.

- memory: El tamaño que tendrá la memoria RAM.

- vcpus: El número de núcleos o cores que tendrá la máquina.

Le he puesto el usuario debian, para que no pida contraseña editando el archivo visudo:

sudo visudo

Añadiendo justo como aparece en la imagen de abajo:

debian ALL=(ALL:ALL) NOPASSWD: ALL

img

Luego he utilizado ssh-copy-id para poder copiar mi clave pública a la máquina destino a la cual me quiero conectar (la que he creado más arriba). Al hacer esto como ya sabemos, permite la conexión a la máquina sin utilizar contraseña.

ssh-copy-id usuario@ipdestino

img

1.2 Convierte la máquina virtual en una plantilla llamada plantilla-cliente. El hostname de la máquina debe ser plantilla-cliente. ¿Cuánto ocupa el volumen de la plantilla en disco?.

Lo primero es eliminar la información de mi máquina llamada deboriginal con sysprep, algo necesario ya que permite eliminar la información del sistema para que pueda utilizarse como una plantilla.

sudo virt-sysprep -d deboriginal --hostname plantilla-cliente

img

Con los datos eliminados, hay que quitarle los privilegios de escritura al disco, ya que debe ser solo de lectura para que pueda utilizarse como una plantilla, y no se permita hacer cambios en el. El disco en este caso se llama deboriginal.qcow2. Hecho esto, lo he renombrado a plantilla-cliente, y al intentar arrancarlo, muestra el error de que no puede, por lo que es correcto.

sudo chmod -w /var/lib/libvirt/images/deboriginal.qcow2

virsh -c qemu:///system domrename deboriginal plantilla-cliente

virsh -c qemu:///system start plantilla-cliente

img

  • Nota: el cambio de nombre es del host o nombre de la máquina. El nombre del disco sigue siendo el mismo deboriginal.qcow2.

Ahora hay que utilizar virt-sparsify desde /var/lib/libvirt/images. Esto permite comprimir la imagen ocupando mucho menos espacio en disco, por lo que genera un nuevo disco llamado debcomprimida.qcow2:

virt-sparsify --compress deboriginal.qcow2 debcomprimida.qcow2

img

El siguiente paso es editar la plantilla para que use el nuevo disco comprimido llamado debcomprimido.qcow2:

virsh -c qemu:/// edit plantilla-cliente

Sustituyendo el nombre del disco comprimido, como aparece en la imagen de abajo:

img

Y como se ve ha pasado a ocupar mucho menos espacio, de 3GB, ha pasado a 450MB aproximadamente:

virsh -c qemu:///domblkinfo plantilla-cliente vda --human

img

No hay que olvidar de que a este disco, tambien hay que quitarle los permisos de escritura para que no arranque la máquina.

sudo chmod -w /var/lib/libvirt/images/debcomprimida.qcow2

img

2. Creación del escenario.

El objetivo es crear el escenario que contiene un bridge, una máquina Debian que hará de router, 2 contenedores que harán de servidor WEB y DHCP, y dos máquinas clientes. En la siguiente imagen se ve la estructura:

img

2.1 Crea una red muy aislada, que se llame red-intra que creará el puente br-intra. Esta red se tiene que iniciar cada vez que encendemos el host.

El primer paso es crear el fichero que va a contener los datos de la red:

sudo nano /usr/share/libvirt/networks/red-intra.xml

El archivo debe tener este contenido:

<network>
  <name>red-intra</name>
  <bridge name='br-intra'/>
</network>

Como las anteriores veces, hay que crear un nuevo archivo xml para declarar y crear la red-intra. Hecho esto se define para que se inicie automáticamente y se inicia:

virsh -c qemu:///system net-define red-intra.xml
virsh -c qemu:///system net-autostart red-intra
virsh -c qemu:///system net-start red-intra
root@debian:/usr/share/libvirt/networks# virsh -c qemu:///system net-define red-intra.xml
La red red-intra se encuentra definida desde red-intra.xml

root@debian:/usr/share/libvirt/networks# virsh -c qemu:///system net-autostart red-intra 
La red red-intra ha sido marcada para iniciarse automáticamente

root@debian:/usr/share/libvirt/networks# virsh -c qemu:///system net-start red-intra 
La red red-intra se ha iniciado

img

2.2 Crea con virt-install la máquina router con Debian 12:

  • Está conectada a la red pública (al bridge br0) y la red-intra.
  • Esta máquina utiliza un disco en formato raw de 10 Gb.
  • El hostname de esta máquina debe ser router-tunombre.
  • Se debe poder acceder a ella por ssh con el usuario root sin que te pida contraseña (configura tu clave pública).
  • Debes configurar la segunda interfaz de red con direccionamiento estático para que tenga la dirección 192.168.200.1.
  • Está máquina se debe iniciar cada vez que arrancamos el host.

Para crear el disco raw de 10GB:

virsh -c qemu:///system vol-create-as discos 10gb.raw --format raw 10G
virsh -c qemu:///system vol-list discos --details
root@debian:/usr/share/libvirt/networks# virsh -c qemu:///system vol-create-as discos 10gb.raw --format raw 10G
Se ha creado el volumen 10gb.raw

root@debian:/usr/share/libvirt/networks# virsh -c qemu:///system vol-list discos --details
 Nombre     Ruta                   Tipo      Capacidad   Alojamiento
----------------------------------------------------------------------
 10gb.raw   /var/discos/10gb.raw   archivo   10,00 GiB   10,00 Gi

Para crear la clonación en base de la plantilla:

virt-clone --connect=qemu:///system --original plantilla-cliente --name router-andres --auto-clone --file /var/discos/10gb.raw

Para crear la máquina router-andres:

virt-install --connect qemu:///system \
--virt-type kvm \
--name router-andres \
--os-variant debian10 \
--cdrom /home/debian/Descargas/Sistemas\ Operativos/debian-12.2.0-amd64-netinst.iso \
--disk /var/discos/10gb.raw \
--network bridge=br0,model=virtio \
--network network=red-intra,model=virtio \
--memory 1024 \
--vcpus 1

Para ver que la máquina router-andres tiene un disco raw:

virsh -c qemu:///system dumpxml router-andres
debian@debian:/usr/share/libvirt/networks$ virsh -c qemu:///system dumpxml router-andres 
<domain type='kvm' id='2'>
  <name>router-andres</name>
  <uuid>e1140c30-95b7-497b-ac20-b8cd53091a38</uuid>
  <metadata>
    <libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
      <libosinfo:os id="http://debian.org/debian/10"/>
    </libosinfo:libosinfo>
  </metadata>
  <memory unit='KiB'>1048576</memory>
  <currentMemory unit='KiB'>1048576</currentMemory>
  <vcpu placement='static'>1</vcpu>
  <resource>
    <partition>/machine</partition>
  </resource>
  <os>
    <type arch='x86_64' machine='pc-q35-7.2'>hvm</type>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <vmport state='off'/>
  </features>
  <cpu mode='host-passthrough' check='none' migratable='on'/>
  <clock offset='utc'>
    <timer name='rtc' tickpolicy='catchup'/>
    <timer name='pit' tickpolicy='delay'/>
    <timer name='hpet' present='no'/>
  </clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <pm>
    <suspend-to-mem enabled='no'/>
    <suspend-to-disk enabled='no'/>
  </pm>
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw'/>
      <source file='/var/discos/10gb.raw' index='2'/>
      <backingStore/>
      <target dev='vda' bus='virtio'/>
      <alias name='virtio-disk0'/>

O tambien desde Virt Manager:

<disk type="file" device="disk">
  <driver name="qemu" type="raw"/>
  <source file="/var/discos/10gb.raw" index="2"/>
  <backingStore/>
  <target dev="vda" bus="virtio"/>
  <alias name="virtio-disk0"/>
  <address type="pci" domain="0x0000" bus="0x05" slot="0x00" function="0x0"/>
</disk>

img

Para activar el inicio automático y ver más información de la máquina:

virsh -c qemu:///system autostart router-andres
virsh -c qemu:///system dominfo router-andres
debian@debian:/usr/share/libvirt/networks$ virsh -c qemu:///system autostart router-andres 
Domain 'router-andres' marked as autostarted

debian@debian:/usr/share/libvirt/networks$ virsh -c qemu:///system dominfo router-andres 
Id:             2
Nombre:         router-andres
UUID:           e1140c30-95b7-497b-ac20-b8cd53091a38
Tipo de sistema operatuvo: hvm
Estado:         ejecutando
CPU(s):         1
Hora de la CPU: 24,2s
Memoria máxima: 1048576 KiB
Memoria utilizada: 1048576 KiB
Persistente:    si
Autoinicio:     activar
Guardar administrado: no
Modelo de seguridad: apparmor
DOI de seguridad: 0
Etiqueta de seguridad: libvirt-e1140c30-95b7-497b-ac20-b8cd53091a38 (enforcing)

Hay que permitir que la máquina router haga SNAT con iptables para poder brindarle salida a internet a las máquinas:

iptables -t nat -A POSTROUTING -s 192.168.200.0/24 -o enp1s0 -j MASQUERADE
  • Nota: no esta permanente, si se reinicia la máquina router, hay que volver a introducir la regla, o hacerla permanente usando por ejemplo el paquete iptables-persistent con:
sudo netfilter-persistent save

3. Contenedores:

Crea dos contenedores LXC conectados a la red red-intra.

  • ServidorWeb: Es un contador creado a partir de la plantilla Ubuntu 22.04 Jammy. Configura su red de forma estática. Su dirección IP debe ser la 192.168.200.3

  • ServidorDHCP: Es un contador creado a partir de la plantilla Debian Bookworm. Configura su red de forma estática. Su dirección IP debe ser la 192.168.200.2.

3.1 Servidor Web.

Para crear el contenedor servidorweb e iniciarlo:

sudo lxc-create -n servidorweb -t ubuntu -- -r jammy
lxc-start servidorweb
root@debian:/usr/share/libvirt/networks# sudo lxc-create -n servidorweb -t ubuntu -- -r jammy
Checking cache download in /var/cache/lxc/jammy/rootfs-amd64 ... 
Copy /var/cache/lxc/jammy/rootfs-amd64 to /var/lib/lxc/servidorweb/rootfs ... 
Copying rootfs to /var/lib/lxc/servidorweb/rootfs ...
Generating locales (this might take a while)...
  es_ES.UTF-8... done
Generation complete.
Creating SSH2 RSA key; this may take some time ...
3072 SHA256:N3Zo8cxOjwHliLX6C53FH3xVL1B7ydFxWdRVF6x8zlk root@debian (RSA)
Creating SSH2 ECDSA key; this may take some time ...
256 SHA256:JzIUGFZAhOLGE+dDpLYu8UyPsEoU2ipYPbhEkWKVqLM root@debian (ECDSA)
Creating SSH2 ED25519 key; this may take some time ...
256 SHA256:hPenKINpWVlhueZTk5EQM1jgnYeCvjw9XSQQVE5NOvo root@debian (ED25519)
invoke-rc.d: could not determine current runlevel
invoke-rc.d: policy-rc.d denied execution of start.

Current default time zone: 'Etc/UTC'
Local time is now:      Sun Oct 22 14:27:02 UTC 2023.
Universal Time is now:  Sun Oct 22 14:27:02 UTC 2023.


##
# The default user is 'ubuntu' with password 'ubuntu'!
# Use the 'sudo' command to run tasks as root in the container.
##

root@debian:/usr/share/libvirt/networks# lxc-start servidorweb
root@debian:/usr/share/libvirt/networks# 

Ahora para conectar el contenedor servidorweb a la red-intra , hay que modificar el archivo del contenedor en /var/lib/lxc/servidorweb/config y añadir en la parte de lxc.net.0.link = br-intra ya que corresponde a la red intra.

Quedando así:

# Network configuration
lxc.net.0.type = veth
lxc.net.0.hwaddr = 00:16:3e:ac:a2:7f
lxc.net.0.link = br-intra
lxc.net.0.flags = up

Ahora reinicio el contenedor y ya pertenece a esa red correctamente. Ahora para darle una dirección estática es modificar el archivo /etc/netplan/10-lxc.yaml con lo siguiente:

network:
  ethernets:
    eth0: 
      dhcp4: no
      addresses: [192.168.200.3/24]
      gateway4: 192.168.200.1
  version: 2

Para aplicar los cambios es con:

sudo netplan apply

Para activar que los contenedores se inicien automáticamente es incluyendo en su archivo de configuración en /var/lib/lxc/contenedor/config la línea lxc.start.auto = 1 y reiniciar el equipo.

3.2 Servidor DHCP.

Para crear el contenedor Debian 12 servidordhcp:

lxc-create -n servidordhcp -t debian -- -r bookworm

Con el contenedor creado hay que modificar si archivo de configuración en /var/lib/lxc/servidordhcp/config y activar la limitación de memoria, el autostart y que se conecte a la red intra y para ello hay que añadir las lineas:

lxc.net.0.link = br-intra
lxc.start.auto = 1
lxc.cgroup2.memory.max = 512M

Luego en el archivo /etc/network/interfaces (ya que es Debian) para que tome la direccion 192.168.200.2:

auto eth0
iface eth0 inet static
address 192.168.200.2
netmask 255.255.255.0

Y el resultado final es:

img

Para entrar a la máquina router-andres sin que pida la contraseña he hecho lo mismo que en pasos anteriores:

ssh-copy-id debian@192.168.1.198 (red de casa):
  • Nota: la ip corresponde a la interfaz de entrada que deberia ser 172.22.X.X (la interfaz de la izquierda de la máquina router que se ve en la imagen del escenario al principio, pero ese direccionamiento solo ocurre cuando se realiza conectado al servidor DHCP del instituto.

img

Para conectarme a la máquina router y posteriormente al servidordhcp: (Pasando la clave pública siendo el mismo usuario usando ssh -A):

img

La salida del comando ip a en router:

img

Para hacer SNAT y que los contenedores tengan salida a internet hay que poner una regla de iptables en el router:

iptables -t nat -A POSTROUTING -s 192.168.200.0/24 -o enp1s0 -j MASQUERADE
  • Donde enp1s0 es la interfaz de salida a internet 172.22 (de la que hablé más arriba).

Luego hay que activar el bit forwarding editando /etc/sysctl.conf descomentando la línea:

net.ipv4.ip_forward = 1

Y aplicando el cambio con:

sudo sysctl -p

Una vez hecho eso, desde el contenedor ya se puede salir al exterior, por ejemplo desde el servidor web:

img

Para comprobar la regla de iptables creada antes:

sudo iptables -t nat -L -n

img

4. Creación de las máquinas clientes.

4.1 Crea una nueva máquina virtual llamada cliente1 a partir de la plantilla plantilla-cliente que tenga un volumen de 5G. Tienes que tener en cuenta los siguientes aspectos:

  • Antes de crear la máquina virtual redimensiona su sistema de fichero para que ocupe el espacio completo del disco.
  • La máquina se conecta a la red red-intra.
  • La máquina tiene una configuración estática de red.
  • La máquina debe tener el hostname cliente1-tunombre.

Compruebo de nuevo el espacio que ocupa la plantilla, creo el volumen de 5GB y redimensiono el sistema de ficheros:

virsh -c qemu:///system domblkinfo plantilla-cliente vda --human

virsh -c qemu:///system vol-create-as discos cliente1.qcow2 5G --format qcow2 --backing-vol /var/lib/libvirt/images/debcomprimida.qcow2 --backing-vol-format qcow2

sudo qemu-img resize /var/discos/cliente1.qcow2 5G
root@debian:/var/lib/libvirt/images# virsh -c qemu:///system domblkinfo plantilla-cliente vda --human
Capacidad:      3,000 GiB
Ubicación:     446,457 MiB
Físico:        448,201 MiB

root@debian:/var/lib/libvirt/images# virsh -c qemu:///system vol-create-as discos cliente1.qcow2 5G --format qcow2 --backing-vol /var/lib/libvirt/images/debcomprimida.qcow2 --backing-vol-format qcow2 
Se ha creado el volumen cliente1.qcow2

root@debian:/var/lib/libvirt/images# sudo qemu-img resize /var/discos/cliente1.qcow2 5G
Image resized.

Para crear la máquina:

virt-install --connect qemu:///system \
 --virt-type kvm \
--name cliente1-andres \
--os-variant debian10 \
--disk path=/var/discos/cliente1.qcow2 \
--network network=red-intra,model=virtio \
--memory 1024 \
--vcpus 1 \
--import

Para ver que el disco de la máquina tiene hecho el backing store es viendo si tiene el parámetro backing file con:

sudo qemu-img info /var/discos/cliente1.qcow2
root@debian:/var/lib/libvirt/images# sudo qemu-img info /var/discos/cliente1.qcow2 
image: /var/discos/cliente1.qcow2
file format: qcow2
virtual size: 5 GiB (5368709120 bytes)
disk size: 12.4 MiB
cluster_size: 65536
backing file: /var/lib/libvirt/images/debcomprimida.qcow2
backing file format: qcow2
Format specific information:
    compat: 0.10
    compression type: zlib
    refcount bits: 16

Para redimensionar el sistema de ficheros a 5GB, copio el disco cliente1.qcow2 y creo uno nuevo llamado newcliente1.qcow2, le aplico la redimensión y le vuelvo a cambiar el nombre que tenia el original:

cd /var/discos/
cp cliente1.qcow2 newcliente1.qcow2

virt-resize --expand /dev/sda1 cliente1.qcow2 newcliente1.qcow2

mv newcliente1.qcow2 cliente1.qcow2

Así:

root@debian:/var/lib/libvirt/images# cd /var/discos/
root@debian:/var/discos# ls
10gb.raw  cliente1.qcow2
root@debian:/var/discos# cp cliente1.qcow2 newcliente1.qcow2
root@debian:/var/discos# virt-resize --expand /dev/sda1 cliente1.qcow2 newcliente1.qcow2

root@debian:/var/discos# ls
10gb.raw  cliente1.qcow2  newcliente1.qcow2
root@debian:/var/discos# mv newcliente1.qcow2 cliente1.qcow2 
root@debian:/var/discos# ls
10gb.raw  cliente1.qcow2

img

img

Ahora le he dado una ip estática 192.168.200.5 y le he cambiado el hostname a cliente1-andres:

img

La máquina cliente1 haciendo ping al exterior:

img