Ansible
Documentation de Ansible
Tip
Ressources Essentielles - Ansible Galaxy : Trouvez des rôles et collections communautaires prêts à l'emploi. - Ansible Documentation : La documentation officielle, très complète.
Inventaire
Exemple de fichier d'inventaire (l'extention du fichier doit être en yaml ex: inventory.yaml) :
all:
children:
debian11:
hosts:
VMFSFTADEV01:
ansible_host: 10.68.9.1
alma:
hosts:
VMCENTREON:
ansible_host: 10.255.9.1
On peut ensuite spécifier dans le fichier d'environnement le fichier d'inventaire à cible : /etc/ansible/ansible.cfg
Playbook
Exemple de fichier PLaybook :
- name: SSO linux
hosts: all
become: true
become_method: sudo
vars:
ansible_python_interpreter: /usr/bin/python3
vars_files:
- secret_vars.yml
tasks:
- name: Installer les dépendances nécessaires pour realm et sssd
ansible.builtin.package:
name:
- realmd
- sssd
- sssd-tools
- libnss-sss
- libpam-sss
- adcli
- samba-common-bin
- krb5-user
- packagekit-tools
- python3-apt
- python3-pexpect
state: present
- name: Vérifier si déjà joint au domaine organisation.com
command: realm list
register: realm_list
changed_when: false
- name: Joindre au domaine organisation.com
ansible.builtin.expect:s
command: realm join organisation.com -U "{{ domain_admin_user }}" -v
responses:
Password: "{{ domain_admin_password }}"
no_log: true
when: "'organisation.com' not in realm_list.stdout"
register: realm_join
- name: Configurer /etc/sssd/sssd.conf
ansible.builtin.blockinfile:
path: /etc/sssd/sssd.conf
block: |
[sssd]
domains = organisation.com
config_file_version = 2
services = nss, pam
[domain/organisation.com]
default_shell = /bin/bash
krb5_store_password_if_offline = True
cache_credentials = True
krb5_realm = organisation.com
realmd_tags = manages-system joined-with-adcli
id_provider = ad
fallback_homedir = /home/%u@%d
ad_domain = organisation.com
use_fully_qualified_names = True
ldap_id_mapping = True
access_provider = simple
simple_allow_groups = sec-adm-system-n3
create: yes
marker: "# {mark} ANSIBLE MANAGED BLOCK"
notify: redémarrer sssd
- name: Configurer /etc/pam.d/common-session
ansible.builtin.blockinfile:
path: /etc/pam.d/common-session
block: |
session [default=1] pam_permit.so
session requisite pam_deny.so
session required pam_permit.so
session required pam_unix.so
session optional pam_sss.so
session optional pam_systemd.so
session required pam_mkhomedir.so skel=/etc/skel/ umask=0022
marker: "# {mark} ANSIBLE MANAGED BLOCK"
create: yes
- name: Configurer /etc/sudoers.d/domainadmin
ansible.builtin.blockinfile:
path: /etc/sudoers.d/domainadmin
block: |
%SEC-ADM-System-N3@organisation.com ALL=(ALL:ALL) ALL
marker: "# {mark} ANSIBLE MANAGED BLOCK"
create: yes
handlers:
- name: redémarrer sssd
ansible.builtin.service:
name: sssd
state: restarted
Ce playbook doit activer la SSO sur les instances debian et utilise des mot de passe stocker dans "secret_vars.yml"
Pour éditer ce fichier crypter utiliser la commande :
Voici un autre exemple pour installer la solution defender :
- name: Microsoft Defender pour point de terminaison Linux
hosts: all
become: true
vars_files:
- secret_vars.yml
tasks:
- name: Vérifier si le système est 32 bits
set_fact:
is_32_bit: "{{ ansible_architecture == 'i386' }}"
- name: Marquer le playbook comme étant sauté si le système est 32 bits
meta: end_play
when: is_32_bit
tags: skip_32_bit
- name: Afficher un message si le système est 32 bits
debug:
msg: "Ce playbook ne supporte pas les systèmes 32 bits."
when: is_32_bit
- name: Vérifier si le répertoire 'mdatp' existe
stat:
path: /etc/opt/microsoft/mdatp/
register: managed_dir_mdatp
- name: Créer les répertoires MDATP
file:
path: /etc/opt/microsoft/mdatp/
recurse: true
state: directory
mode: 0755
owner: root
group: root
when: not managed_dir_mdatp.stat.exists
- name: Installer les dépendances nécessaires pour extraire le "Onboarding Package"
ansible.builtin.package:
name:
- unzip
state: present
update_cache: yes
- name: Vérifier si le répertoire 'managed' existe
stat:
path: /etc/opt/microsoft/mdatp/managed/
register: managed_dir
- name: Créer le répertoire managed pour MDATP
file:
path: /etc/opt/microsoft/mdatp/managed/
state: directory
mode: 0600
owner: root
group: root
when: not managed_dir.stat.exists
- name: Copier mde_Onboarding
copy:
src: files/MicrosoftDefenderATPOnboardingLinuxServer.py
dest: /etc/opt/microsoft/mdatp/MicrosoftDefenderATPOnboardingLinuxServer.py
owner: root
group: root
mode: 0600
- name: Copier mde_installer
copy:
src: files/mde_installer.sh
dest: /etc/opt/microsoft/mdatp/mde_installer.sh
owner: root
group: root
mode: 0700
- name: Vérifiez si la commande mdatp existe
command: which mdatp
register: mdatp_command_check
ignore_errors: true
changed_when: false
- name: Vérifiez si mdeattach_managed.json existe
stat:
path: /etc/opt/microsoft/mdatp/managed/mdeattach_managed.json
register: mdeattach_managed_json_stat
- name: Exécutez mde_installer.sh
shell: /etc/opt/microsoft/mdatp/mde_installer.sh -i -y -c prod -o /etc/opt/microsoft/mdatp/MicrosoftDefenderATPOnboardingLinuxServer.py
when: mdatp_command_check.failed or not mdeattach_managed_json_stat.stat.exists
- name: Copiez le fichier du service mdatp-scan dans le répertoire systemd
copy:
src: files/mdatp-scan.service
dest: /etc/systemd/system/mdatp-scan.service
mode: '0644'
register: service_file
- name: Copiez le fichier mdatp-scan timer dans le répertoire systemd
copy:
src: files/mdatp-scan.timer
dest: /etc/systemd/system/mdatp-scan.timer
mode: '0644'
register: timer_file
- name: Recharger systemd pour appliquer de nouveaux fichiers d'unité
command: systemctl daemon-reload
when: service_file.changed or timer_file.changed
- name: Activer mdatp-scan.timer pour démarrer au démarrage
systemd:
name: mdatp-scan.timer
enabled: yes
state: started
when: service_file.changed or timer_file.changed
- name: Démarrez le mdatp-scan.timer dès maintenant
systemd:
name: mdatp-scan.timer
state: started
when: service_file.changed or timer_file.changed
Ce playbook Ansible installe et configure Microsoft Defender pour Endpoint sur des systèmes Linux. Il commence par vérifier l'architecture du système, et s'arrête si celui-ci est en 32 bits. Ensuite, il prépare les répertoires nécessaires, installe des dépendances, et copie les scripts d'installation et d'onboarding requis. Si nécessaire, il exécute le script d'installation et configure des services systemd pour automatiser les scans de sécurité.
Variable
Ce fichier ansible.cfg situer par default dans /etc/ansible/ansible.cfg configure les paramètres par défaut pour Ansible. Il spécifie l'emplacement du fichier de mot de passe pour Vault, l'inventaire des hôtes, et l'interpréteur Python à utiliser. Les vérifications de clé hôte SSH sont désactivées. Il définit également le fichier de clé privée SSH à utiliser, l'utilisateur distant par défaut (it), et optimise les performances avec 10 forks et un timeout de 10 secondes.
[defaults]
vault_password_file = /etc/ansible/vault.txt
inventory = /opt/ansible/inventory.yaml
interpreter_python = /usr/bin/python3
host_key_checking = False
private_key_file = /etc/ansible/ssh_data/id_rsa
remote_user = it
forks = 10
timeout = 10
Lancer des playbook ansible
Pour lancer tous les playbook qui commence par any on peut utiliser la commande suivant su la vm ansible :
Modification du fichier de mot de passe
Le fichier secret_vars.yml contient tout les mots de passe nécessaire au fonctionnement de ansible pour modifier les variables dans ce fichier utiliser la commande suivante la vm ansible :
Résolution de problème
Pour résoudre des problème commun (ex pb de dépendance ext) bien précisé l'intépréteur python dans le playbook:
vars:
ansible_python_interpreter: /usr/bin/python3
```
Pour éditier le vault via l'éditeur nano on peut changer les fichier : "/etc/bash.bashrc"
et rajouter la variable `export EDITOR=nano`
## Agent Ansible
Ce script permet de configurer une machine pour qu'elle puisse être pilotée par Ansible, notamment à travers un tunnel SSH inversé (utile pour les machines derrière un NAT sans IP publique accessible).
Il effectue les actions suivantes :
* Création de l'utilisateur dédié.
* Configuration des privilèges sudo.
* Mise en place des clés SSH (récupération depuis le serveur maître).
* Établissement d'un tunnel SSH inversé vers le serveur Ansible.
```bash
#!/bin/bash
# set -x
# Configuration
REMOTE_SERVER="remote.domaine.org"
BASTION_HOST="bastion.domaine.org"
USERNAME="user"
REMOTE_USER="user"
BASTION_USER="user"
SSH_DIR="/home/$USERNAME/.ssh"
PRIVATE_KEY_PATH="$SSH_DIR/id_rsa"
BASTION_KEY_PATH="$PRIVATE_KEY_PATH" # Par défaut, on utilise la même clé
REMOTE_KEY_PATH="/home/user/.ssh/id_rsa"
LOCAL_PORT="20022"
REMOTE_ANSIBLE_PORT="22"
HOSTNAME=$(hostname)
REMOTE_SCRIPT="infrastructure/script-ansible.sh"
# Fonction de logging unifiée
log() {
local level="$1"
local message="$2"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "$timestamp - $level - $message" | tee -a /tmp/ansible-agent.log
}
# Fonction pour vérifier si l'utilisateur existe
check_user_exists() {
if id "$USERNAME" &>/dev/null; then
log "INFO" "L'utilisateur $USERNAME existe déjà."
return 0
else
log "WARNING" "L'utilisateur $USERNAME n'existe pas."
return 1
fi
}
# Fonction pour vérifier si l'utilisateur est sudoeur
check_sudo_privileges() {
if groups "$USERNAME" | grep -q '\bsudo\b\|\bwheel\b'; then
log "INFO" "L'utilisateur $USERNAME a les privilèges sudo."
return 0
else
log "WARNING" "L'utilisateur $USERNAME n'a pas les privilèges sudo."
return 1
fi
}
# Fonction pour créer l'utilisateur
create_user() {
log "INFO" "Création de l'utilisateur $USERNAME..."
# Créer l'utilisateur avec un répertoire home
if useradd -m -s /bin/bash "$USERNAME"; then
log "INFO" "Utilisateur $USERNAME créé avec succès."
else
log "ERROR" "Échec de la création de l'utilisateur $USERNAME."
exit 1
fi
# Demander et définir le mot de passe
echo "Veuillez définir un mot de passe pour l'utilisateur $USERNAME :"
if passwd "$USERNAME"; then
log "INFO" "Mot de passe défini avec succès."
else
log "ERROR" "Échec de la définition du mot de passe."
exit 1
fi
}
# Fonction pour ajouter l'utilisateur au groupe sudo
add_sudo_privileges() {
log "INFO" "Ajout des privilèges sudo pour l'utilisateur $USERNAME..."
# Déterminer le groupe sudo selon la distribution
if getent group sudo &>/dev/null; then
SUDO_GROUP="sudo"
elif getent group wheel &>/dev/null; then
SUDO_GROUP="wheel"
else
log "ERROR" "Aucun groupe sudo/wheel trouvé sur ce système."
exit 1
fi
if usermod -aG "$SUDO_GROUP" "$USERNAME"; then
log "INFO" "Privilèges sudo ajoutés avec succès."
else
log "ERROR" "Échec de l'ajout des privilèges sudo."
exit 1
fi
}
# Fonction pour créer le répertoire .ssh avec les bonnes permissions
setup_ssh_directory() {
log "INFO" "Configuration du répertoire .ssh..."
# Créer le répertoire .ssh s'il n'existe pas
if [[ ! -d "$SSH_DIR" ]]; then
if sudo -u "$USERNAME" mkdir -p "$SSH_DIR"; then
log "INFO" "Répertoire .ssh créé."
else
log "ERROR" "Échec de la création du répertoire .ssh."
exit 1
fi
fi
# Définir les permissions correctes
sudo chown "$USERNAME:$USERNAME" "$SSH_DIR"
sudo chmod 700 "$SSH_DIR"
log "INFO" "Permissions du répertoire .ssh configurées (700)."
}
# Fonction pour créer le fichier de configuration SSH
create_ssh_allow_config() {
log "INFO" "Création du fichier de configuration SSH pour autoriser l'utilisateur user..."
SSH_CONFIG_DIR="/etc/ssh/sshd_config.d"
CONFIG_FILE="$SSH_CONFIG_DIR/user_allow.conf"
# Créer le répertoire si nécessaire
if [[ ! -d "$SSH_CONFIG_DIR" ]]; then
mkdir -p "$SSH_CONFIG_DIR"
fi
# Écrire le contenu
echo "AllowUsers user@0.0.0.0/0 user@127.0.0.1 user@::1 user@localhost" > "$CONFIG_FILE"
log "INFO" "Fichier de configuration SSH créé : $CONFIG_FILE"
# Recharger la configuration SSH
if systemctl reload ssh 2>/dev/null || service ssh reload 2>/dev/null || systemctl reload sshd 2>/dev/null; then
log "INFO" "Configuration SSH rechargée avec succès."
else
log "WARNING" "Échec du rechargement de la configuration SSH."
fi
}
# Fonction pour vérifier l'accès au bastion et configurer la clé si nécessaire
check_bastion_access() {
log "INFO" "Vérification de l'accès au bastion $BASTION_HOST..."
# Tester l'accès avec la clé actuelle (par défaut id_rsa)
if ssh -i "$BASTION_KEY_PATH" -o BatchMode=yes -o StrictHostKeyChecking=no "${BASTION_USER}@${BASTION_HOST}" exit 2>/dev/null; then
log "INFO" "Accès au bastion réussi avec $BASTION_KEY_PATH."
return 0
fi
log "WARNING" "L'accès au bastion avec $BASTION_KEY_PATH a échoué."
# Si id_rsa_bastion existe, essayer avec celle-là
local CUSTOM_BASTION_KEY="$SSH_DIR/id_rsa_bastion"
if [[ -f "$CUSTOM_BASTION_KEY" ]]; then
if ssh -i "$CUSTOM_BASTION_KEY" -o BatchMode=yes -o StrictHostKeyChecking=no "${BASTION_USER}@${BASTION_HOST}" exit 2>/dev/null; then
log "INFO" "Accès au bastion réussi avec $CUSTOM_BASTION_KEY."
BASTION_KEY_PATH="$CUSTOM_BASTION_KEY"
return 0
fi
fi
# Copier la clé spécifique
cp "$USER_BASTION_KEY" "$CUSTOM_BASTION_KEY"
chown "$USERNAME:$USERNAME" "$CUSTOM_BASTION_KEY"
chmod 600 "$CUSTOM_BASTION_KEY"
BASTION_KEY_PATH="$CUSTOM_BASTION_KEY"
log "INFO" "Clé du bastion configurée : $BASTION_KEY_PATH"
# Vérifier à nouveau
if ssh -i "$BASTION_KEY_PATH" -o BatchMode=yes -o StrictHostKeyChecking=no "${BASTION_USER}@${BASTION_HOST}" exit 2>/dev/null; then
log "INFO" "Accès au bastion confirmé."
else
log "ERROR" "Toujours impossible de se connecter au bastion."
exit 1
fi
}
# Fonction pour récupérer la clé privée depuis le serveur distant
retrieve_private_key() {
# Vérifier si les clés privée et publique existent déjà
if [[ -f "$PRIVATE_KEY_PATH" ]] && [[ -f "$PRIVATE_KEY_PATH.pub" ]]; then
log "INFO" "Les clés privée et publique existent déjà localement. Skipping retrieve_private_key."
return 0
fi
# Demander le chemin de la clé privée locale pour la connexion au serveur distant
echo "Veuillez entrer le chemin complet de la clé privée locale pour la connexion à $REMOTE_SERVER (via $BASTION_HOST) :"
read -r LOCAL_AUTH_KEY_PATH
if [[ -z "$LOCAL_AUTH_KEY_PATH" ]]; then
log "ERROR" "Chemin de la clé privée locale non spécifié."
exit 1
fi
local TEMP_KEY_PATH="/tmp/id_rsa_temp_$(date +%s)"
local TEMP_PUB_KEY_PATH="/tmp/id_rsa.pub_temp_$(date +%s)"
# Récupérer la clé privée via scp en tant qu'utilisateur actuel
log "INFO" "Téléchargement de la clé privée depuis $REMOTE_SERVER vers un fichier temporaire..."
if scp -v -o ProxyCommand="ssh -W %h:%p -i \"$LOCAL_AUTH_KEY_PATH\" -o StrictHostKeyChecking=no \"${BASTION_USER}@${BASTION_HOST}\"" -i "$LOCAL_AUTH_KEY_PATH" "$REMOTE_USER@$REMOTE_SERVER:$REMOTE_KEY_PATH" "$TEMP_KEY_PATH"; then
log "INFO" "Clé privée téléchargée avec succès dans $TEMP_KEY_PATH."
else
log "ERROR" "Échec du téléchargement de la clé privée depuis $REMOTE_SERVER."
exit 1
fi
# Déplacer la clé vers le répertoire de l'utilisateur cible et définir les permissions
log "INFO" "Déplacement de la clé privée vers $PRIVATE_KEY_PATH et configuration des permissions..."
if mv "$TEMP_KEY_PATH" "$PRIVATE_KEY_PATH"; then
log "INFO" "Clé privée déplacée avec succès."
else
log "ERROR" "Échec du déplacement de la clé privée."
exit 1
fi
sudo chown "$USERNAME:$USERNAME" "$PRIVATE_KEY_PATH"
sudo chmod 600 "$PRIVATE_KEY_PATH"
log "INFO" "Permissions de la clé privée configurées (600)."
# Récupérer la clé publique via scp en tant qu'utilisateur actuel
log "INFO" "Téléchargement de la clé publique depuis $REMOTE_SERVER vers un fichier temporaire..."
if scp -v -o ProxyCommand="ssh -W %h:%p -i \"$LOCAL_AUTH_KEY_PATH\" -o StrictHostKeyChecking=no \"${BASTION_USER}@${BASTION_HOST}\"" -i "$LOCAL_AUTH_KEY_PATH" "$REMOTE_USER@$REMOTE_SERVER:$REMOTE_KEY_PATH.pub" "$TEMP_PUB_KEY_PATH"; then
log "INFO" "Clé publique téléchargée avec succès dans $TEMP_PUB_KEY_PATH."
else
log "ERROR" "Échec du téléchargement de la clé publique depuis $REMOTE_SERVER."
exit 1
fi
# Déplacer la clé publique vers le répertoire de l'utilisateur cible et définir les permissions
log "INFO" "Déplacement de la clé publique vers $PRIVATE_KEY_PATH.pub et configuration des permissions..."
if sudo mv "$TEMP_PUB_KEY_PATH" "$PRIVATE_KEY_PATH.pub"; then
log "INFO" "Clé publique déplacée avec succès."
else
log "ERROR" "Échec du déplacement de la clé publique."
exit 1
fi
sudo chown "$USERNAME:$USERNAME" "$PRIVATE_KEY_PATH.pub"
sudo chmod 644 "$PRIVATE_KEY_PATH.pub"
log "INFO" "Permissions de la clé publique configurées (644)."
}
# Fonction pour vérifier et activer le serveur SSH
check_and_enable_ssh() {
log "INFO" "Vérification et activation du serveur SSH..."
if systemctl is-active --quiet ssh; then
log "INFO" "Le service SSH est déjà actif."
else
log "WARNING" "Le service SSH n'est pas actif. Tentative de démarrage..."
if systemctl start ssh; then
log "INFO" "Service SSH démarré avec succès."
else
log "ERROR" "Échec du démarrage du service SSH."
exit 1
fi
fi
}
# Fonction principale
main_setup() {
log "INFO" "Début de la configuration pour l'utilisateur $USERNAME"
# Vérifier si le script est exécuté en tant que root
if [[ $EUID -ne 0 ]]; then
log "ERROR" "Ce script doit être exécuté en tant que root."
exit 1
fi
# Vérifier si l'utilisateur existe
user_exists=false
if check_user_exists; then
user_exists=true
else
create_user
user_exists=true
fi
# Vérifier les privilèges sudo
if ! check_sudo_privileges; then
add_sudo_privileges
fi
# Configurer le répertoire .ssh
setup_ssh_directory
# Créer le fichier de configuration SSH
create_ssh_allow_config
# Récupérer la clé privée
retrieve_private_key
# Vérifier l'accès au bastion (C'est ici qu'on règle BASTION_KEY_PATH si besoin)
check_bastion_access
# Configurer authorized_keys
setup_authorized_keys
# Vérifier et activer le serveur SSH
check_and_enable_ssh
log "INFO" "Configuration terminée avec succès !"
log "INFO" "L'utilisateur $USERNAME est maintenant configuré avec :"
log "INFO" " - Compte utilisateur créé"
log "INFO" " - Privilèges sudo accordés"
log "INFO" " - Répertoire .ssh configuré avec les bonnes permissions"
log "INFO" " - Clé privée installée depuis $REMOTE_SERVER"
log "INFO" " - Accès bastion vérifié (Clé: $BASTION_KEY_PATH)"
log "INFO" " - Serveur SSH vérifié et activé"
}
# Fonction pour configurer authorized_keys
setup_authorized_keys() {
log "INFO" "Configuration du fichier authorized_keys..."
AUTHORIZED_KEYS_FILE="$SSH_DIR/authorized_keys"
# Créer le fichier authorized_keys s'il n'existe pas
if [[ ! -f "$AUTHORIZED_KEYS_FILE" ]]; then
touch "$AUTHORIZED_KEYS_FILE"
fi
# Ajouter la clé publique au fichier authorized_keys si elle n'y est pas déjà
if [[ -f "$PRIVATE_KEY_PATH.pub" ]]; then
if ! grep -q "$(cat "$PRIVATE_KEY_PATH.pub")" "$AUTHORIZED_KEYS_FILE"; then
cat "$PRIVATE_KEY_PATH.pub" >> "$AUTHORIZED_KEYS_FILE"
log "INFO" "Clé publique ajoutée à authorized_keys."
else
log "INFO" "Clé publique déjà présente dans authorized_keys."
fi
else
log "WARNING" "Clé publique non trouvée, skipping setup_authorized_keys."
fi
# Définir les permissions correctes
chown "$USERNAME:$USERNAME" "$AUTHORIZED_KEYS_FILE"
chmod 600 "$AUTHORIZED_KEYS_FILE"
log "INFO" "Permissions de authorized_keys configurées (600)."
# Recharger la configuration SSH
if systemctl reload ssh 2>/dev/null || service ssh reload 2>/dev/null || systemctl reload sshd 2>/dev/null; then
log "INFO" "Configuration SSH rechargée après configuration authorized_keys."
else
log "WARNING" "Échec du rechargement de la configuration SSH."
fi
}
# Établir le tunnel reverse SSH
establish_tunnel() {
log "INFO" "Établissement du tunnel SSH reverse pour $HOSTNAME via $BASTION_HOST"
# Tunnel reverse : le serveur pourra se connecter au poste via le port distant
ssh -o ProxyCommand="ssh -W %h:%p -i \"$BASTION_KEY_PATH\" -o StrictHostKeyChecking=no \"${BASTION_USER}@${BASTION_HOST}\"" \
-i "$PRIVATE_KEY_PATH"\
-o ServerAliveInterval=60 \
-o ServerAliveCountMax=3 \
-o StrictHostKeyChecking=no \
-o ExitOnForwardFailure=yes \
-R ${LOCAL_PORT}:localhost:22 \
-N ${USERNAME}@${REMOTE_SERVER} &
SSH_PID=$!
log "INFO" "Tunnel établi avec PID: $SSH_PID"
# Attendre que le tunnel soit établi
sleep 1
# Nettoyer known_hosts avant la notification Ansible
log "INFO" "Suppression de l'entrée known_hosts sur le serveur ansible"
ssh -o ProxyCommand="ssh -W %h:%p -i \"$BASTION_KEY_PATH\" -o StrictHostKeyChecking=no \"${BASTION_USER}@${BASTION_HOST}\"" \
-i "$PRIVATE_KEY_PATH" ${USERNAME}@${REMOTE_SERVER} "docker exec cronjob /bin/ash -c \"ssh-keygen -f /root/.ssh/known_hosts -R '[127.0.0.1]:20022'\""
# Notifier le serveur Ansible que le poste est disponible
notify_ansible_server
# Maintenir le tunnel pendant 10 minutes
# sleep 600
# Fermer le tunnel
kill $SSH_PID 2>/dev/null
log "INFO" "Tunnel fermé"
}
# Notifier le serveur Ansible
notify_ansible_server(){
log "INFO" "Correction des permissions de /root/.ssh/config sur le conteneur distant..."
ssh -o ProxyCommand="ssh -W %h:%p -i \"$BASTION_KEY_PATH\" -o StrictHostKeyChecking=no \"${BASTION_USER}@${BASTION_HOST}\"" \
-i "$PRIVATE_KEY_PATH" ${USERNAME}@${REMOTE_SERVER} "docker exec -u 0 cronjob /bin/sh -c 'chown root:root /root/.ssh/config && chmod 600 /root/.ssh/config && chmod 700 /root/.ssh'"
log "INFO" "Exécution du script Ansible sur le serveur distant"
# Exécuter le script Ansible sur le serveur distant via SSH
ssh -o ProxyCommand="ssh -W %h:%p -i \"$BASTION_KEY_PATH\" -o StrictHostKeyChecking=no \"${BASTION_USER}@${BASTION_HOST}\"" \
-i "$PRIVATE_KEY_PATH" ${USERNAME}@${REMOTE_SERVER} "$REMOTE_SCRIPT -l desktop" -a
if [ $? -eq 0 ]; then
log "INFO" "Script Ansible exécuté avec succès sur le serveur distant"
else
log "ERROR" "Erreur lors de l'exécution du script Ansible sur le serveur distant"
fi
# Tuer le processus SSH du tunnel après l'exécution du script Ansible sur le serveur distant
# kill $SSH_PID 2>/dev/null
# log "Tunnel fermé par le client."
}
# Vérifier si un tunnel existe déjà
check_existing_tunnel() {
if pgrep -f "ssh.*-R.*${LOCAL_PORT}" > /dev/null; then
log "WARNING" "Un tunnel existe déjà, arrêt du script"
exit 0
fi
}
# Script principal
main_tunnel() {
log "INFO" "Démarrage du script de tunnel reverse"
check_existing_tunnel
establish_tunnel
log "INFO" "Fin du script de tunnel reverse"
stop_ssh_service
}
# Fonction pour arrêter le service SSH
stop_ssh_service() {
if systemctl is-enabled --quiet ssh; then
log "INFO" "Le service SSH est 'enabled', pas d'arrêt du service."
return
fi
log "INFO" "Arrêt du service SSH..."
if systemctl is-active --quiet ssh; then
if systemctl stop ssh ssh.socket; then
log "INFO" "Service SSH et socket arrêtés avec succès."
else
log "ERROR" "Échec de l'arrêt du service SSH."
fi
else
log "INFO" "Le service SSH n'est pas actif, pas besoin de l'arrêter."
fi
}
# Exécution du script principal
main() {
main_setup
main_tunnel
}
# Exécution du script principal
main "$@"
Liens Connexes
- Cronjob Docker : Mise en place d'un conteneur pour l'exécution centralisée des tâches Ansible.