atelier_automatisation/chapitre01.md

6.1 KiB

Chapitre 0.1

Dernier atelier de mise à niveau avant Ansible

LXD : hyperviseur de conteneurs LXC LXC : technologie de conteneurisation

LXD

Entrer dans un conteneur LXC

  • En root : lxc exec <ct> /bin/bash
  • En user : lxc exex test --sudo --user <user> --login

Demo Bastion ssh et rappel

Rappel :

Génération d'un couple clé publique clé privée ssh :ssh-keygen -t ed25519

la clé en .pub contient la clé publique à déposer sur les conteneur. On ne touche pas à l'autre elle est confidentielle.

Création et configuration du conteneur bastion :

lxc launch images:debian/buster bastion
lxc exec bastion /bin/bash
apt-get update
apt-get install -y openssh-server
echo "ssh_pubkey" >> ~/.ssh/authorized_keys

On doit pouvoir se connecter en ssh depuis notre ordinateur au conteneur bastion mais pas au conteneur test

Sur notre conteneur test (voir 0.0) on configure ssh pour que seul le bastion puisse y accéder (plus tard on ferra ça avec un pare-feu).

PermitRootLogin no

Match Address ipConteneurTest
    PermitRootLogin without-password

Puis on dépose notre clé ssh et on restart sshd

echo "ssh_pubkey" >> ~/.ssh/authorized_keys
systemctl restart sshd

Normalement il n'est plus possible de se connecter au conteneur test depuis notre ordinatateur. Il est accessible uniquement depuis le bastion.

Point réseau :

  • L'adresse 0.0.0.0 représente l'adresse wildcard en IPv4.

Sur notre ordinateur :

~/.ssh/config

Host bastion
    Hostname ipConteneurBastion
    User root

Host test1
    Hostname ipConteneurTest # Correspond à l'ip à laquelle test1 est accessible depuis test (le bastion)
    User root
    ProxyJump bastion

Ce qui change dans la "vrai vie" :

  • On ne se connecte jamais via mot de passe
  • On évite au maximum de se connecter en root, même à un conteneur accessible que à travers le bastion.
  • C'est le pare-feu qui nous empêche de nous connecteur aux conteneurs "backend" (le conteneur test dans notre cas) et non une config sshd.

Il est possible de partager son serveur X avec un conteneur LXC, cela peut permettre de faire tourner un service dans un conteneur et de l'utiliser sur ça machine hôte.

Ansible

  • Beaucoup de tâches répétitive dans l'adminsys (dépôt de clés, configuration récurrente )

L'objectif est d'apprendre à faire tout ça avec Ansible pour gagner beaucoup de temps. En plus de ça c'est un gain de sécurité potentiel car on fait la config une seule fois. Les fois suivantes c'est Ansible qui s'en charge.

Ansible est très modulaire et exécute les tâches de manière intelligente. Si une tâche à déjà été faite (ex. dépôt de clé) il ne la refait pas.

Templating avec Jinja2

Permet de générer dynamiquement un fichier de configuration à partir de variables.

Exemple :

Voici un bout de rôle Ansible et notament un des fichiers de template

auto lo
iface lo inet loopback

{% set ports = [] %}
{% for port in ovs_ports | default([]) %}{{ports.append( port.interface )}}{% endfor %}
{% for interface in interface_list | default([]) %}
{% if interface not in ports | default(false) %}
iface {{interface}} inet manual

{% endif %}
{% endfor %}
{% include 'ovs.j2' %}

Fonctionne à partir des variables suivantes :

interface_list: [eno1,eno2]

ovs_ports:
  - interface: eno1
    bridge: vmbr0

Lien du role : https://github.com/coimbrap/ansible-role-ovs

Notion de rôle

Un rôle regroupe une liste de "task", ce qui revient à une liste de tâche à effectuer.

Ces tasks utilise des variables afin d'être modulaire. Ces variables sont initialisé dans les sources du rôles (dans le dossier defaults)

Avec un rôle bien fait nous n'avons pas à toucher aux sources du rôle, il nous suffit de modifier les valeurs des variables.

Structure d'un projet Ansible

  • Un fichier de configuration : ansible.cfg Défini les variables globale (connexion, inventaire...)

  • Un fichier d'inventaire : inventory.ini Liste toutes les machines ainsi que les groupes de machines.

  • Les playbooks : C'est ce que l'on exécute, exécute un ou plusieurs rôles sur une ou plusieurs machines ou des groupes de machines.

Variables Ansible
  • group_vars: Variables locales à un groupe de machines
    • Des variables globales à tout les conteneurs peuvent être définie dans un dossier all
  • host_vars: Variables locales à une machine

Environnement virtualenv python

Nécessaire pour utiliser Ansible

Initialisation :

apt-get install python3-virtualenv
virtualenv env 
source env/bin/activate

pip install ansible 

Pour rentrer source env/bin/activate, pour sortir deactivate

Exemple

Création d'un conteneur

Le rôle des CT : https://git.elukerio.org/elukerio/ansible-role-create-ct Le rôle sshkeys : https://git.elukerio.org/elukerio/ansible-role-sshkeys

Rédaction de l'inventaire :

Version INI

[krhacken]
test

host_vars/test

ct_name: test
# ID: 100-253
ct_vmid: 231
# Nodes: [zeus,jupiter]
ct_node: zeus
node_bastion: bastion
# Vlans: 
ct_if: vmbr1
ct_vlan: 50
ct_prefix6: "fd2e:9d2b:16eb:30"
proxy_ip: "2001:ab8:1207:1509::f00d"
ct_cpus: 2
ct_ram: 1024
ct_swap: 0
ct_storage: local-zfs 
ct_disk: 16
ct_template: local:vztmpl/debian-10.0-standard_10.0-1_amd64.tar.gz
ct_onboot: 1
ct_unprivileged: 1

On doit définir un mot de passe dans host_vars/test/passwd.yml

On l'encrypte : ansible-vault encrypt passwd.yml

NB : Il faut avoir défini un secret dans un fichier secret (à ajouter dans le .gitignore) dans le dossier racine d'Ansible.

On lance ce rôle à partir d'un playbook du style :

- hosts: krhacken
  connection: ssh
  gather_facts: no
  roles:
    - create-ct
    - sshkeys

On lance le playbook avec ansible-playbook playbooks/create-ct.yml ansible fait le reste.

-- FIN --

Exemple de fichier ansible.cfg

[defaults]
inventory = inventory.ini
stdout_callback = debug
interpreter_python = auto_silent
gathering = smart
gather_timeout = 20
roles_path = roles
host_key_checking = False
callback_whitelist = timer, mail, profile_tasks
timeout = 30
vault_password_file = ./secret

[ssh_connection]
pipelining = True