You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

7.7 KiB

title date draft image categories tags
Ansible: Escenario router-nat 2022-10-18T13:49:56+02:00 false featured.png
documentación
Servicios de Red e Internet
Ansible
Vagrant

Creación del siguiente escenario con un cliente y un router-nat utilizando vagrant y ansible

escenario

Vagrant

Según el esquema de red que tenemos que replicar, vamos a crear una red muy aislada entre las dos máquinas. También, el router tendrá un bridge que será su puerta de enlace predeterminada. En el caso del cliente, esta configuración se hará más adelante. El Vagrantfile queda de la siguiente manera:

{{< highlight ruby "linenos=table">}} config.vm.define :router do |router| router.vm.box = "debian/bullseye64" router.vm.hostname = "router" router.vm.synced_folder ".", "/vagrant", disabled: true router.vm.network :public_network, :dev => "br0", :mode => "bridge", :type => "bridge", use_dhcp_assigned_default_route: true router.vm.network :private_network, :libvirt__network_name => "red-muy-aislada", :libvirt__dhcp_enabled => false, :ip => "192.168.0.1", :libvirt__forward_mode => "veryisolated" end config.vm.define :cliente do |cliente| cliente.vm.box = "debian/bullseye64" cliente.vm.hostname = "cliente" cliente.vm.synced_folder ".", "/vagrant", disabled: true cliente.vm.network :private_network, :libvirt__network_name => "red-muy-aislada", :libvirt__dhcp_enabled => false, :ip => "192.168.0.2", :libvirt__forward_mode => "veryisolated" end end {{< / highlight >}}

Creamos las máquinas virtuales:

vagrant up

Ansible

Ahora nos movemos al directorio donde se va a encontrar el playbook (ansible/). empezamos por el fichero hosts;

hosts

El fichero hosts contiene la información de las máquinas en las que vamos a realizar el despliegue, pero antes de crearlo necesitamos conseguir las direcciones IPs que tienen asignadas en la interfaz eth0 (la de Vagrant). Para ello usamos el siguiente comando:

{{< highlight bash "hl_lines=2" >}} $ vagrant ssh cliente -c "hostname -I | cut -d' ' -f1" 2>/dev/null 192.168.121.77 {{< / highlight >}}

{{< highlight bash "hl_lines=6" >}} $ vagrant ssh router -c "hostname -I | cut -d' ' -f1" 2>/dev/null ==> router: You assigned a static IP ending in ".1" to this machine. ==> router: This is very often used by the router and can cause the ==> router: network to not work properly. If the network doesn't work ==> router: properly, try changing this IP. 192.168.121.146 {{< / highlight >}}

Nos aparece una alerta ya que el router tiene una dirección IP acabada en ".1", Lo ignoramos ya que la máquina es el router de la red. Con la salida de ambos comandos tenemos las IPs de las máquinas y, añadiendo además las rutas de las claves privadas, podemos crear el fichero:

{{< highlight yaml "linenos=table,hl_lines=6 10" >}} all: children: maquinas: hosts: cliente: ansible_ssh_host: 192.168.121.77 ansible_ssh_user: vagrant ansible_ssh_private_key_file: ../.vagrant/machines/cliente/libvirt/private_key router: ansible_ssh_host: 192.168.121.146 ansible_ssh_user: vagrant ansible_ssh_private_key_file: ../.vagrant/machines/router/libvirt/private_key {{< / highlight >}}

Ahora podemos crear las máquinas con vagrant up: vagrant

site.yaml

Tras eso creamos el fichero que contiene la información de asignación de roles, que deben ser de la siguiente manera:

  • common: Estas tareas se deben ejecutar en todos los nodos: actualizar los paquetes y añadir tu clave pública a la máquinas para poder acceder a ellas con ssh. ¿Existe algún módulo de ansible que te permita copiar claves públicas?.
  • router: Todas las tareas necesarias para configurar router cómo router-nat y que salga a internet por eth1. Las configuraciones deben ser permanentes. ¿Existe algún módulo de ansible que te permita ejecutar sysctl?.
  • cliente: Todas las tareas necesarias para que las máquinas conectadas a la red privada salgan a internet por eth1.
  • web: Las tareas necesarias para instalar y configurar un servidor web con una página estática en la máquina cliente.

{{< highlight yaml "linenos=table" >}}

  • hosts: all become: true roles:

    • role: common
  • hosts: router become: true roles:

    • role: router
  • hosts: cliente become: true roles:

    • role: web
    • role: cliente {{< / highlight >}}

Roles

Para realizar el despliegue indicado tenemos que crear los roles. Las tareas de los roles, están contenidas en una estructura de carpetas dentro de la carpeta rol, siendo de la siguiente manera:

rolejemplo
├── defaults
├── files
├── handlers
├── library
├── tasks
├── templates
└── vars

conteniendo las tareas que realizará. Empezaremos por common:

Common

Este rol es bastante sencillo ya que solo cuenta con un fichero tasks/main.yaml que contiene la instrucción para comprobar que el sistema está actualizado:

{{< highlight yaml "linenos=table" >}}

  • name: Comprueba que el sistema esta actualizado apt: update_cache=yes upgrade=yes

  • name: Introduce la clave publica desde un fichero authorized_key: user: vagrant state: present key: "{{ lookup('file', '/home/roberto/.ssh/id_rsa.pub') }}" {{< / highlight >}}

Router

Todas las tareas necesarias para configurar router cómo router-nat y que salga a internet por eth1. Las configuraciones deben ser permanentes. El contenido de tasks/main.yaml es el siguiente:

{{< highlight yaml "linenos=table" >}}

  • name: Cambia el bit de forward a 1 ansible.posix.sysctl: name: net.ipv4.ip_forward value: '1' sysctl_set: yes state: present reload: yes

  • name: Configuracion de DNAT iptables: chain: PREROUTING in_interface: eth1 destination_port: 80 jump: DNAT protocol: tcp table: nat to_destination: 10.0.0.2:80 become: yes

  • name: Configuracion de SNAT iptables: chain: POSTROUTING destination: 10.0.0.0/8 jump: MASQUERADE out_interface: eth1 table: nat become: yes {{< / highlight >}}

Web

Las tareas necesarias para instalar y configurar un servidor web con una página estática en la máquina cliente. El contenido de tasks/main.yaml es el siguiente:

{{< highlight yaml "linenos=table" >}}

  • name: "ensure apache2 is installed" apt: pkg: apache2

  • name: copy template index template: src: index.j2 dest: /var/www/html/index.html owner: www-data group: www-data mode: 0644

  • name: "Copiar fichero al servidor remoto" copy: src: fichero.html dest: /var/www/html/fichero.html owner: www-data group: www-data mode: '0644'

  • name: "Copiar fichero de configuración y reiniciar el servicio" copy: src: etc/apache2/ports.conf dest: /etc/apache2/ports.conf owner: root group: root mode: '0644' notify: restart apache2 {{< / highlight >}}

En esta tarea si que se utilizan otros ficheros, pero al no tener una configuración crucial, no vamos a modificarlos. Su contenido se encuentra en github.

Cliente

Todas las tareas necesarias para que las máquinas conectadas a la red privada salgan a internet por eth1. El contenido de tasks/main.yaml es el siguiente:

{{< highlight yaml "linenos=table" >}}

  • name: cambiar la ruta por defecto shell: ip route delete default && ip route add default via 10.0.0.1 && echo "post-up route add -net 10.0.0.0 netmask 255.0.0.0 gw 10.0.0.0 dev eth1" >> /etc/network/interfaces {{< / highlight >}}

Finalmente, podemos ejecutar el playbook con ansible-playbook site.yaml: ansible