From 8fcfefc90019bdafd72690c1505095e5699c371e Mon Sep 17 00:00:00 2001 From: GnomeZworc Date: Fri, 9 May 2025 21:31:09 +0200 Subject: [PATCH] add dhcp Signed-off-by: GnomeZworc --- README.md | 41 +++++++++++++++++++++- lib/dhcp.sh | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/subnet.sh | 10 +++++- 3 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 lib/dhcp.sh diff --git a/README.md b/README.md index 68c50b4..2242bc4 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ apt-get install -y \ ``` -ebtables -L --Lc +iv ebtables -D FORWARD -p arp --arp-op Request --arp-ip-dst 240.0.0.1 -j DROP ebtables -A FORWARD -p arp --arp-op Request --arp-ip-dst 240.0.0.1 -j DROP ebtables -L --Lc @@ -29,4 +29,43 @@ ebtables -L --Lc genisoimage -output seed.iso -volid cidata -joliet -rock meta-data user-data network-config socat -,raw,echo=0 unix-connect:/tmp/vm-monitor.sock +``` + +``` +root@lab1:~/vm# cat /etc/systemd/system/dnsmasq@.service +[Unit] +Description=dnsmasq in netns %i +After=network.target + +[Service] +Type=simple +ExecStart=/usr/local/bin/run-dnsmasq-in-netns.sh %i +ExecStopPost=/bin/rm -f /run/dnsmasq-%i.pid + +[Install] +WantedBy=multi-user.target +``` + +``` +#!/bin/bash +set -e + +# Expects one argument: netns_bridge (e.g. vpc-00003_br-00002 or vpc1_br0) +arg="$1" +NETNS="${arg%%_*}" +BRIDGE="${arg#*_}" + +echo "start ${NETNS} ${BRIDGE}" + +exec ip netns exec "$NETNS" \ + dnsmasq \ + --no-daemon \ + --interface="$BRIDGE" \ + --bind-interfaces \ + --pid-file="/run/dnsmasq-$arg.pid" \ + --conf-file="/etc/dnsmasq.d/$arg.conf" \ + --no-hosts \ + --no-resolv \ + --log-facility="/var/log/dnsmasq-$arg.log" \ + --no-daemon -p0 ``` \ No newline at end of file diff --git a/lib/dhcp.sh b/lib/dhcp.sh new file mode 100644 index 0000000..08b4692 --- /dev/null +++ b/lib/dhcp.sh @@ -0,0 +1,94 @@ +#!/bin/bash + +# Fonction pour convertir une adresse IP en entier +function ip_to_int() { + local ip=$1 + local a b c d + IFS=. read -r a b c d <<< "$ip" + echo "$((a * 256 ** 3 + b * 256 ** 2 + c * 256 + d))" +} + +# Fonction pour convertir un entier en adresse IP +function int_to_ip() { + local int=$1 + echo "$((int >> 24 & 255)).$((int >> 16 & 255)).$((int >> 8 & 255)).$((int & 255))" +} + +# Fonction pour générer une adresse MAC unique (incrémenter tous les octets) +function int_to_mac() { + local base_mac="00:22:33" # Préfixe de base pour la MAC (4 premiers octets) + local incr=$1 # Incrément global pour les derniers octets + local byte1=$(( (incr >> 16) & 0xFF )) # Incrémenter le premier octet des 2 derniers octets + local byte2=$(( (incr >> 8) & 0xFF )) # Incrémenter le second octet + local byte3=$(( incr & 0xFF )) # Incrémenter le troisième octet + + printf "%s:%02X:%02X:%02X\n" "$base_mac" "$byte1" "$byte2" "$byte3" +} + +function generate_dhcp_file { + # CIDR de départ (ex: "10.10.10.0/24") + cidr="${1}" + subnet="$(echo "${cidr}" | cut -d\/ -f1)" + output_file="/etc/dnsmasq.d/${2}.conf" + + if [ -z "$cidr" ]; then + echo "Veuillez fournir un CIDR en argument, par exemple '10.10.10.0/24'." + exit 1 + fi + + # Extraire l'adresse de réseau et le masque + IFS='/' read -r network mask <<< "$cidr" + network_int=$(ip_to_int "$network") + + # Calcul du masque + netmask=$(( 0xFFFFFFFF ^ ((1 << (32 - mask)) - 1) )) + + # Calcul de l'adresse de fin + end_ip=$((network_int + ( ( 0xFFFFFFFF ^ netmask )))) + + # Calcul du nombre d'IP dans la plage + num_ips=$((end_ip - network_int + 1)) + + # Vérifier si le nombre d'adresses est correct + if [ "$num_ips" -le 0 ]; then + echo "Erreur dans le calcul de la plage IP. Le CIDR est probablement mal formé." + exit 1 + fi + + # Si trop d'adresses, éviter de les générer toutes à la fois + if [ "$num_ips" -gt 1000000 ]; then + echo "La plage d'adresses est trop grande pour être générée en une seule fois. Essayez avec un plus petit sous-réseau." + exit 1 + fi + + # Vider le fichier de sortie avant d'écrire + > "$output_file" + + echo "no-resolv" >> "$output_file" + echo "dhcp-range=${subnet},static,255.255.255.0,12h" >> "$output_file" + echo "dhcp-option=3,240.0.2.1" >> "$output_file" + echo "dhcp-option=6,1.1.1.1,8.8.8.8" >> "$output_file" + + # Variables pour l'incrémentation des MAC et IP + mac_incr=0 + ip_incr=$network_int + + # Générer les réservations + for i in $(seq 0 $((num_ips - 1))) + do + # Calculer l'adresse IP + ip=$(int_to_ip "$ip_incr") + + # Calculer l'adresse MAC valide (incrémenter tous les octets) + mac=$(int_to_mac $mac_incr) + + # Ajouter la ligne dans le fichier de configuration + echo "dhcp-host=$mac,$ip" >> "$output_file" + + # Incrémenter les variables + mac_incr=$((mac_incr + 1)) # Incrémenter l'adresse MAC + ip_incr=$((ip_incr + 1)) # Incrémenter l'adresse IP + done + + echo "Fichier de réservations DHCP généré à $output_file" +} \ No newline at end of file diff --git a/lib/subnet.sh b/lib/subnet.sh index 596e660..42588f1 100644 --- a/lib/subnet.sh +++ b/lib/subnet.sh @@ -3,6 +3,7 @@ . ./lib/db.sh . ./lib/colors.sh . ./lib/vpc.sh +. ./lib/dhcp.sh function check_subnet_exist { local vpc_name="${1}" @@ -78,7 +79,11 @@ function create_subnet { print_in_color "${COLOR_GREEN}" " - add subnet route" ip -n "${vpc_name}" r add "${subnet}" dev "br-${subnet_id}" scope link print_in_color "${COLOR_GREEN}" " - add subnet firewall" - ebtables -A FORWARD -p arp --arp-op Request --arp-ip-dst "${gateway_ip}" --out-interface "br-${subnet_id}" -j DROP + ebtables -A FORWARD --out-interface "br-${subnet_id}" -p arp --arp-op Request --arp-ip-dst "${gateway_ip}" -j DROP + ebtables -A FORWARD --out-interface "br-${subnet_id}" -p IPv4 --ip-protocol udp --ip-source-port 67:68 --ip-destination-port 67:68 -j DROP + + generate_dhcp_file "${subnet}" "${vpc_name}_br-${subnet_id}" + systemctl start "dnsmasq@${vpc_name}_br-${subnet_id}.service" } return 0 @@ -98,7 +103,10 @@ function delete_subnet { delete_in_db "subnet" "${subnet_name}" ip -n "${vpc_name}" route del "${subnet}" dev "br-${subnet_id}" ip link del dev "vxlan-${vxlan_id}" + systemctl stop "dnsmasq@${vpc_name_br}-br-${subnet_id}.service" + rm /etc/dnsmasq.d/${vpc_name}_br-${subnet_id}.conf ebtables -D FORWARD -p arp --arp-op Request --arp-ip-dst "${gateway_ip}" --out-interface "br-${subnet_id}" -j DROP + ebtables -D FORWARD --out-interface "br-${subnet_id}" -p IPv4 --ip-protocol udp --ip-source-port 67:68 --ip-destination-port 67:68 -j DROP ip link del dev "br-${subnet_id}" ip -n "${vpc_name}" link del dev "br-${subnet_id}" ip link del dev "veth-${subnet_id}-ext"