Implementierung von CloudInit in Proxmox mit GRE-Tunneling und Hetzner Integration: Automatisierte Netzwerkkonfiguration und VM-Bereitstellung

In diesem Beitrag zeige ich, wie man mithilfe von virt-customize und Proxmox ein vollautomatisiertes Skript erstellt, das eine Cloud-Init-basierte Ubuntu-VM generiert, konfiguriert und als Proxmox-Template speichert. Dabei werden spezifische Anpassungen vorgenommen, darunter das Setzen eines Root-Passworts, die Konfiguration von SSH und die Netzwerkumgebung (IPv4 und IPv6).

Skriptübersicht:

  1. Cloud Image-Management:
  • Vorhandene Cloud-Images werden gelöscht, und ein neues Image wird heruntergeladen.
  • Installation des qemu-guest-agent und wichtiger Tools wie htop, curl und traceroute.
  1. SSH-Konfiguration:
  • Setzen des SSH-Ports auf Deiner Wahl alles über 1024.
  • Root-Login und Passwort-Authentifizierung aktiviert.
  • Deaktivierung von SSH-Key-Login und KbdInteractiveAuthentication.
  1. Netzwerk & DNS:
  • Unterstützung für IPv4 ( Gre von Noze) und IPv6 ( von Hetzner ) (IPv4 wird als net0 mit einer MTU von 1476 gesetzt).
  • DNS-Server und Suchdomäne werden konfiguriert.
  1. Zeit- und Hostname-Einstellungen:
  • Zeitzone wird auf Berlin gesetzt.
  • Hostname wird basierend auf der IP-Adresse generiert.
  1. MOTD-Anpassungen:
  • Hinzufügen von benutzerdefinierten Systeminformationen (z.B. CPU, RAM, Netzwerkinformationen) zur MOTD-Anzeige.
  1. Proxmox VM-Erstellung:
  • Das Cloud-Image wird importiert, und eine VM wird mit den gewünschten Konfigurationen erstellt.
  • Die VM wird als Template gespeichert und mit Tags versehen (z.B. Template, ubuntu-2204).
#!/bin/bash

# Bildschirm leeren
clear

# Farben für die Ausgabe
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'  # Kein Farbformat

# Variablen setzen
VMID=9000  # VM-ID für das Template
VM_NAME="ubuntu-2204"
STORAGE="Storage"  # ZFS Speicher
MEMORY=2048
CORES=2
BRIDGE_IPV4="vmbr1"  # Bridge für IPv4 für Gre von Noez
BRIDGE_IPV6="vmbr0"  # Bridge für IPv6 für ---> Hetzner IPV6
DISK_SIZE="20G"  # Festplattengröße in GB
ROOT_PASSWORD="DummyPasswort"  # Root-Passwort
TIMEZONE="Europe/Berlin"  # Zeitzone
MTU_SIZE="1476"  # MTU für Netzwerkschnittstellen für Gre von Noez
SSH_PORT="2222"  # Neuer SSH-Port alles über 1024

# Netzwerkkonfiguration
IP_ADDRESS="127.0.0.1"  # IPv4-Adresse mit Subnetzmaske
GATEWAY="127.0.0.1"  # IPv4-Gateway
IPV6_ADDRESS="0000:000:000:0000::3/64"  # IPv6-Adresse mit Präfix
IPV6_GATEWAY="0000::1"  # IPv6-Gateway ---> Hetzner IPV6 Gateway

# DNS-Konfiguration
DNS="8.8.8.8,8.8.4.4"  # IPv4 DNS-Server
DNS_IPV6="2001:4860:4860::8888,2001:4860:4860::8844"  # IPv6 DNS-Server
SEARCH_DOMAIN="dummy-domain.com"  # DNS-Suchdomäne

# Hostname auf die IP-Adresse setzen
HOSTNAME="${IP_ADDRESS%%/*}.dummy-domain.com"  # Nur die IP ohne Subnetzmaske und .dummy-domain.com

echo -e "${YELLOW}###########################################"
echo -e "# Proxmox VM Template Erstellung Skript"
echo -e "###########################################${NC}"

# Schritt 1: Überprüfen, ob das alte Image vorhanden ist, und es löschen
if [ -f jammy-server-cloudimg-amd64.img ]; then
    echo -e "${YELLOW}Altes Image gefunden. Löschen des alten Images...${NC}"
    rm -f jammy-server-cloudimg-amd64.img
    if [ $? -eq 0 ];then
        echo -e "${GREEN}Altes Image erfolgreich gelöscht.${NC}"
    else
        echo -e "${RED}Fehler beim Löschen des alten Images.${NC}"
        exit 1
    fi
else
    echo -e "${YELLOW}Kein altes Image gefunden. Fortfahren...${NC}"
fi

# Schritt 2: System-Update und Installation der notwendigen Tools
echo -e "${YELLOW}System aktualisieren und libguestfs-tools installieren...${NC}"
sudo apt update -y && sudo apt install libguestfs-tools -y

# Schritt 3: Ubuntu Cloud Image herunterladen
echo -e "${YELLOW}Herunterladen des Ubuntu Cloud Images...${NC}"
wget https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img
if [ $? -eq 0 ];then
    echo -e "${GREEN}Download abgeschlossen.${NC}"
else
    echo -e "${RED}Fehler beim Herunterladen des Ubuntu Cloud Images.${NC}"
    exit 1
fi

# Schritt 4: qemu-guest-agent auf dem Image installieren
echo -e "${YELLOW}Installation des qemu-guest-agent auf dem Image...${NC}"
sudo virt-customize -a jammy-server-cloudimg-amd64.img --install qemu-guest-agent --color
if [ $? -eq 0 ];then
    echo -e "${GREEN}qemu-guest-agent erfolgreich installiert.${NC}"
else
    echo -e "${RED}Fehler bei der Installation des qemu-guest-agent.${NC}"
    exit 1
fi

# Schritt 5: Root-Passwort setzen
echo -e "${YELLOW}Setzen des root-Passworts...${NC}"
sudo virt-customize -a jammy-server-cloudimg-amd64.img --root-password password:${ROOT_PASSWORD} --color
if [ $? -eq 0 ];then
    echo -e "${GREEN}root-Passwort erfolgreich gesetzt.${NC}"
else
    echo -e "${RED}Fehler beim Setzen des root-Passworts.${NC}"
    exit 1
fi

# Schritt 6: Installation von htop, curl, traceroute und sudo
echo -e "${YELLOW}Installation von htop, curl, traceroute und sudo...${NC}"
sudo virt-customize -a jammy-server-cloudimg-amd64.img --install htop,curl,traceroute,sudo --color
if [ $? -eq 0 ];then
    echo -e "${GREEN}Pakete erfolgreich installiert.${NC}"
else
    echo -e "${RED}Fehler bei der Installation der Pakete.${NC}"
    exit 1
fi

# Schritt 7: SSH-Dienste konfigurieren (Port 7862 aktivieren, Root-Login und Passwort-Login aktivieren, SSH-Key-Login und KbdInteractiveAuthentication deaktivieren)
echo -e "${YELLOW}Konfiguration von SSH (Port 7862 aktivieren, Root-Login, Passwort-Login aktivieren, SSH-Key-Login und KbdInteractiveAuthentication deaktivieren)...${NC}"
sudo virt-customize -a jammy-server-cloudimg-amd64.img --run-command "sed -i 's/^#PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config"
sudo virt-customize -a jammy-server-cloudimg-amd64.img --run-command "sed -i 's/^#PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config"
sudo virt-customize -a jammy-server-cloudimg-amd64.img --run-command "sed -i 's/^#Port 22/Port ${SSH_PORT}/' /etc/ssh/sshd_config"
sudo virt-customize -a jammy-server-cloudimg-amd64.img --run-command "sed -i 's/^PubkeyAuthentication.*/PubkeyAuthentication no/' /etc/ssh/sshd_config"
sudo virt-customize -a jammy-server-cloudimg-amd64.img --run-command "sed -i 's/^KbdInteractiveAuthentication.*/#KbdInteractiveAuthentication no/' /etc/ssh/sshd_config" --color
if [ $? -eq 0 ];then
    echo -e "${GREEN}SSH-Konfiguration erfolgreich aktualisiert.${NC}"
else
    echo -e "${RED}Fehler bei der SSH-Konfiguration.${NC}"
    exit 1
fi

# Schritt 8: Zeitzone auf Berlin setzen
echo -e "${YELLOW}Setzen der Zeitzone auf ${TIMEZONE}...${NC}"
sudo virt-customize -a jammy-server-cloudimg-amd64.img --timezone ${TIMEZONE} --color
if [ $? -eq 0 ];then
    echo -e "${GREEN}Zeitzone erfolgreich gesetzt.${NC}"
else
    echo -e "${RED}Fehler beim Setzen der Zeitzone.${NC}"
    exit 1
fi

# Schritt 9: Hostname setzen
echo -e "${YELLOW}Setzen des Hostnamens auf ${HOSTNAME}...${NC}"
sudo virt-customize -a jammy-server-cloudimg-amd64.img --hostname ${HOSTNAME} --color
if [ $? -eq 0 ];then
    echo -e "${GREEN}Hostname erfolgreich gesetzt.${NC}"
else
    echo -e "${RED}Fehler beim Setzen des Hostnamens.${NC}"
    exit 1
fi

# Schritt 10: Aktualisieren aller Pakete im Image
echo -e "${YELLOW}Aktualisieren aller Pakete im Image...${NC}"
sudo virt-customize -a jammy-server-cloudimg-amd64.img --update --color
if [ $? -eq 0 ];then
    echo -e "${GREEN}Pakete erfolgreich aktualisiert.${NC}"
else
    echo -e "${RED}Fehler beim Aktualisieren der Pakete.${NC}"
    exit 1
fi

# Schritt 11a: Hinzufügen von benutzerdefinierten MOTD-Dateien für /etc/update-motd.d
echo -e "${YELLOW}Erstellen der benutzerdefinierten MOTD-Dateien...${NC}"
# 00-header
sudo virt-customize -a jammy-server-cloudimg-amd64.img --run-command "cat <<EOT > /etc/update-motd.d/00-header
#!/bin/sh
echo '  __          ________ _      _____ ____  __  __ ______   '
echo '  \ \        / |  ____| |    / ____/ __ \|  \/  |  ____|  '
echo '   \ \  /\  / /| |__  | |   | |   | |  | | \  / | |__     '
echo '    \ \/  \/ / |  __| | |   | |   | |  | | |\/| |  __|    '
echo '     \  /\  /  | |____| |___| |___| |__| | |  | | |____   '
echo '      \/    \/ |______|______\_____\____/|_|  |_|______|  '
echo ' '
echo ' '
echo ' '
echo 'Systeminformationen:'
echo 'CPU: \$(lscpu | grep 'Model name:' | sed 's/Model name:[ \t]*//')'
echo 'RAM: \$(free -h | grep 'Mem:' | awk '{print \$2}')'
echo 'Festplatte: \$(df -h / | grep '/' | awk '{print \$2}')'
echo ' '
echo ' '
echo ' '
echo 'Netzwerk IPv4: \$(ip -4 addr show dev eth0 | grep 'inet ' | head -n1 | awk '{print \$2}')'
echo 'Netzwerk IPv6: \$(ip -6 addr show dev eth1 | grep 'inet6 ' | head -n1 | awk '{print \$2}')'
echo 'Letzter Login: \$(last -2 | grep -v 'wtmp' | head -1)'
EOT" --color

if [ $? -eq 0 ];then
    echo -e "${GREEN}MOTD-Dateien erfolgreich erstellt.${NC}"
else
    echo -e "${RED}Fehler beim Erstellen der MOTD-Dateien.${NC}"
    exit 1
fi

# Schritt 12: Erstellen der Proxmox VM mit IPv4 (net0) und IPv6 (net1)
echo -e "${YELLOW}Erstellen der Proxmox VM ${VM_NAME}...${NC}"
sudo qm create ${VMID} --name "${VM_NAME}" --memory ${MEMORY} --cores ${CORES} --cpu cputype=host \
    --net0 virtio,bridge=${BRIDGE_IPV4},mtu=${MTU_SIZE},firewall=1 \
    --net1 virtio,bridge=${BRIDGE_IPV6},firewall=1  # MTU nur für IPv4
if [ $? -eq 0 ];then
    echo -e "${GREEN}VM ${VM_NAME} erfolgreich erstellt.${NC}"
else
    echo -e "${RED}Fehler beim Erstellen der VM.${NC}"
    exit 1
fi

# Schritt 13: Cloud Image als Disk in den ZFS Speicher importieren
echo -e "${YELLOW}Importieren des Cloud Images in den ZFS Speicher...${NC}"
sudo qm importdisk ${VMID} jammy-server-cloudimg-amd64.img ${STORAGE}
if [ $? -eq 0 ];then
    echo -e "${GREEN}Cloud Image erfolgreich importiert.${NC}"
else
    echo -e "${RED}Fehler beim Importieren des Cloud Images.${NC}"
    exit 1
fi

# Schritt 14: VM konfigurieren (VirtIO SCSI, Bootdisk, CloudInit, discard=on)
echo -e "${YELLOW}Konfigurieren der VM...${NC}"
sudo qm set ${VMID} --scsihw virtio-scsi-pci --scsi0 ${STORAGE}:vm-${VMID}-disk-0,size=${DISK_SIZE},discard=on
sudo qm set ${VMID} --boot c --bootdisk scsi0
sudo qm set ${VMID} --scsi2 ${STORAGE}:cloudinit  # CloudInit als scsi2 konfigurieren
sudo qm set ${VMID} --serial0 socket --vga serial0
sudo qm set ${VMID} --agent enabled=1
if [ $? -eq 0 ];then
    echo -e "${GREEN}VM erfolgreich konfiguriert.${NC}"
else
    echo -e "${RED}Fehler bei der VM-Konfiguration.${NC}"
    exit 1
fi

# Schritt 15: VM in ein Template konvertieren und Tags hinzufügen
echo -e "${YELLOW}Speichern der VM als Template und Hinzufügen der Tags...${NC}"
sudo qm template ${VMID}
sudo qm set ${VMID} --tags "Template, ubuntu-2204"
if [ $? -eq 0 ];then
    echo -e "${GREEN}VM erfolgreich als Template gespeichert und Tags hinzugefügt.${NC}"
else
    echo -e "${RED}Fehler beim Speichern der VM oder Hinzufügen der Tags.${NC}"
    exit 1
fi

echo -e "${YELLOW}###########################################"
echo -e "${GREEN}VM-Template wurde erfolgreich erstellt und konfiguriert mit Tags (Template, ubuntu-2204).${NC}"
echo -e "${YELLOW}###########################################${NC}"