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.
241 lines
7.7 KiB
Markdown
241 lines
7.7 KiB
Markdown
1 year ago
|
---
|
||
|
title: "Ansible: Escenario router-nat"
|
||
|
date: 2022-10-18T13:49:56+02:00
|
||
|
draft: false
|
||
1 year ago
|
image: featured.png
|
||
|
categories:
|
||
|
- documentación
|
||
|
- Servicios de Red e Internet
|
||
|
tags:
|
||
|
- Ansible
|
||
|
- Vagrant
|
||
1 year ago
|
---
|
||
|
|
||
|
Creación del siguiente escenario con un cliente y un router-nat utilizando **vagrant** y **ansible**
|
||
|
|
||
|
|
||
|
![escenario](escenario.png)
|
||
|
|
||
|
## 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:
|
||
|
|
||
|
```bash
|
||
|
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](vagrant.png)
|
||
|
|
||
|
### 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:
|
||
|
|
||
|
```bash
|
||
|
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](ansible.png)
|