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

157 lines
7.2 KiB

5 years ago
#!/bin/bash
# Script d'initialisation des interfaces réseau d'un conteneur Systemd-nspawn
if [[ -n "${1}" ]]; then
nom_conteneur="${1}"
else
echo "Erreur: aucun nom de conteneur renseigné."
exit 1
fi
# Fonction exécuté en deuxième. Permet la génération de commandes pour la création d'interfaces réseau
genCmdIntRzo(){
# Création d'une interface non étiqueté (access)
5 years ago
if [[ "${pont_init}" -eq 1 && "${vlan_init}" -eq 1 && "${interface_init}" -eq 1 ]]; then
commandes_a_executer+=( "ip link add ${interface} type veth peer name ${interface}_h" )
commandes_a_executer+=( "ip link set ${interface}_h mtu 1500" )
5 years ago
commandes_a_executer+=( "ip link set ${interface}_h up" )
commandes_a_executer+=( "ip link set ${interface}_h master ${pont}" )
commandes_a_executer+=( "bridge vlan del dev ${interface}_h vid 1 PVID untagged master" )
commandes_a_executer+=( "bridge vlan add dev ${interface}_h vid ${vlan} pvid untagged master" )
# Réinitialisation des variables témoins
pont_init=0
vlan_init=0
interface_init=0
# Création d'une interface étiqueté (trunk)
elif [[ "${pont_init}" -eq 1 && "${ieee8021q_init}" -eq 1 && "${interface_init}" -eq 1 ]]; then
commandes_a_executer+=( "ip link add ${interface} type veth peer name ${interface}_h" )
commandes_a_executer+=( "ip link set ${interface}_h mtu 1500" )
commandes_a_executer+=( "ip link set ${interface}_h up" )
commandes_a_executer+=( "ip link set ${interface}_h master ${pont}" )
commandes_a_executer+=( "bridge vlan del dev ${interface}_h vid 1 PVID untagged master" )
for ((id_label_vlan=0 ; "${nb_params_label}" - "${id_label_vlan}" ; id_label_vlan++)); do
commandes_a_executer+=( "bridge vlan add dev ${interface}_h vid ${label_vlan[${id_label_vlan}]} tagged master" )
done
# Réinitialisation des variables témoins
pont_init=0
ieee8021q_init=0
interface_init=0
# Création d'une interface normale en pont isolé dans un espace de nom réseau
elif [[ "${pont_init}" -eq 1 && "${isole_init}" -eq 1 && "${interface_init}" -eq 1 ]]; then
commandes_a_executer+=( "ip link add ${interface} type veth peer name ${interface}_h" )
commandes_a_executer+=( "ip link set netns ${isole_netns} dev ${interface}_h" )
commandes_a_executer+=( "ip netns exec ${isole_netns} ip link set ${interface}_h master ${pont}" )
commandes_a_executer+=( "ip netns exec ${isole_netns} ip link set dev ${interface}_h type bridge_slave isolated on" )
commandes_a_executer+=( "ip netns exec ${isole_netns} ip link set dev ${interface}_h mtu 1500" )
commandes_a_executer+=( "ip netns exec ${isole_netns} ip link set dev ${interface}_h up" )
5 years ago
fi
}
# Fonction exécuté en premier. Récupère les paramètres du fichier de configuration du conteneur
5 years ago
recupParams(){
declare -a params_int=( $(grep -B 2 "^Interface" /etc/systemd/nspawn/"${nom_conteneur}".nspawn | sed "/^--/d") )
nb_params="${#params_int[*]}"
for ((id_param_fichier=0 ; "${nb_params}" - "${id_param_fichier}" ; id_param_fichier++)); do
nom_param=$(echo "${params_int[${id_param_fichier}]}" | grep -v '#.*Interface' | sed "s/=.*//" | sed "s/#//")
val_param=$(echo "${params_int[${id_param_fichier}]}" | sed "s/.*=//")
5 years ago
# Récupération des données d'après le fichier de configuration
if [ "${nom_param}" == "PONT" ]; then
if [[ $(ip link show "${val_param}" 2> /dev/null || ip netns | cut -d ' ' -f 1 | xargs -I {} ip netns exec {} sh -c "ip link show ${val_param} 2> /dev/null" | grep ${val_param} 2> /dev/null) ]]; then
5 years ago
pont="${val_param}"
pont_init=1
else
echo "Erreur: le pont ${val_param} n'existe pas. Arrêt immédiat du script \"${0}\" sans aucune modification du système."
exit 1
fi
elif [ "${nom_param}" == "VLAN" ]; then
if [[ "${val_param}" =~ ^-?[0-9]+$ && "${val_param}" -ge 1 && "${val_param}" -le 4094 && $(echo -n "${val_param}" | cut -c 1) -ne 0 ]]; then
if [[ "${pont_init}" -eq 1 ]]; then
vlan="${val_param}"
vlan_init=1
else
echo "Erreur: le paramètre \"#PONT=votrePont\" est manquant."
5 years ago
exit 1
fi
else
echo "Erreur: le VLAN \"${val_param}\" n'est pas un entier compris entre 1 et 4094. Arrêt immédiat du script \"${0}\" sans aucune modification du système."
exit 1
fi
elif [ "${nom_param}" == "8021Q" ]; then
declare -a label_vlan=( $(echo ${val_param} | sed 's/,/\n/g') )
nb_params_label="${#label_vlan[*]}"
for ((id_label_vlan=0 ; "${nb_params_label}" - "${id_label_vlan}" ; id_label_vlan++)); do
if [[ "${label_vlan[${id_label_vlan}]}" =~ ^-?[0-9]+$ && "${label_vlan[${id_label_vlan}]}" -ge 1 && "${label_vlan[${id_label_vlan}]}" -le 4094 && $(echo -n "${label_vlan[${id_label_vlan}]}" | cut -c 1) -ne 0 ]]; then
if [[ "${pont_init}" -eq 1 ]]; then
ieee8021q_init=1
else
echo "Erreur: le paramètre \"#PONT=votrePont\" est manquant."
exit 1
fi
else
echo "Erreur: le tronc 802.1Q comporte un identifiant de VLAN (\"${val_param}\") qui n'est pas un entier compris entre 1 et 4094. Arrêt immédiat du script \"${0}\" sans aucune modification du système."
exit 1
fi
done
elif [ "${nom_param}" == "ISOLE" ]; then
if [[ "${val_param}" =~ ^-?[a-zA-Z0-9_\-]+$ ]]; then
if [[ "${pont_init}" -eq 1 ]]; then
isole_netns="${val_param}"
isole_init=1
else
echo "Erreur: le paramètre \"#ISOLE=espacedenomdupont\" mentionne un espace de nom réseau inexistant."
exit 1
fi
else
echo "Erreur: le nom de l'espace de nom réseau (\"${val_param}\") n'est pas valide. Arrêt immédiat du script \"${0}\" sans aucune modification du système."
exit 1
fi
5 years ago
elif [ "${nom_param}" == "Interface" ]; then
if [[ ! $(ip link show "${val_param}" 2> /dev/null || ip netns | cut -d ' ' -f 1 | xargs -I {} ip netns exec {} sh -c "ip link show ${val_param} 2> /dev/null" | grep ${val_param} 2> /dev/null) ]]; then
if [[ "${vlan_init}" -eq 1 || "${ieee8021q_init}" -eq 1 || "${isole_init}" ]]; then
5 years ago
interface="${val_param}"
interface_init=1
else
echo "Erreur: le paramètre \"#VLAN=votreVLAN\" ou \"#ISOLE=espacedenomdupont\" est manquant."
5 years ago
exit 1
fi
elif [[ $(find /sys/class/net/ -type l ! -lname '*/devices/virtual/net/*' -printf '%f ' | grep "${val_param}" 2> /dev/null) ]]; then
pont_init=0
vlan_init=0
ieee8021q_init=0
interface_init=0
5 years ago
else
echo "Erreur: l'interface ${val_param} est déjà existante. Arrêt immédiat du script \"${0}\" sans aucune modification du système."
exit 1
fi
fi
# Génération des commandes de création des interfaces réseau du conteneur
genCmdIntRzo
5 years ago
done
}
# Fonction d'exécution des commandes préparées dans la fonction genCmdIntRzo()
5 years ago
execCmdIntRzo(){
for ((id_commande_rzo=0 ; "${#commandes_a_executer[*]}" - "${id_commande_rzo}"; id_commande_rzo++)); do
# Exécution des commandes préparées
# Pour afficher les commandes sans rien exécuter (dans le cas d'un déboggage/modification du script), il faut précéder la ligne suivante par la commande "echo"
echo ${commandes_a_executer["${id_commande_rzo}"]}
${commandes_a_executer["${id_commande_rzo}"]}
5 years ago
done
}
# Fonction d'exécution du script de création d'interfaces réseau pour le conteneur en cours
5 years ago
principale(){
recupParams
execCmdIntRzo
}
principale