Przeglądaj źródła

'join_unix_ad.local' hinzufügen

yuno admin 4 miesięcy temu
rodzic
commit
2c5bd3f61b
1 zmienionych plików z 240 dodań i 0 usunięć
  1. 240 0
      join_unix_ad.local

+ 240 - 0
join_unix_ad.local

@@ -0,0 +1,240 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+# =========================
+# Konfiguration (ANPASSEN!)
+# =========================
+DOMAIN="DOMAIN.local"
+REALM="DOMAIN.LOCAL"           # i.d.R. DOMAIN in GROSS
+AD_DNS_IP="192.168.178.3"       # Synology AD/DNS IP
+DC_HOST="nas.DOMAIN.local"     # optional für Tests
+ADMIN_USER="Administrator@DOMAIN.LOCAL"
+# Optional: Test-User (nur für getent/id Test nach Join)
+TEST_USER="TESTUSER"
+
+# Optional: Computer OU (leer lassen wenn nicht benötigt)
+COMPUTER_OU=""
+
+# Verhalten
+FORCE_NO_MDNS=true             # hosts: files dns  (empfohlen bei .local)
+DISABLE_AVAHI=true             # avahi-daemon stoppen/deaktivieren
+SET_KRB5_RDNS_FALSE=true       # rdns = false setzen (sehr empfehlenswert)
+
+# =========================
+# Helper
+# =========================
+require_root() {
+  if [[ "${EUID}" -ne 0 ]]; then
+    echo "Bitte als root ausführen: sudo $0"
+    exit 1
+  fi
+}
+
+backup_file() {
+  local f="$1"
+  if [[ -f "$f" ]]; then
+    cp -a "$f" "${f}.bak.$(date +%Y%m%d%H%M%S)"
+  fi
+}
+
+have_cmd() { command -v "$1" >/dev/null 2>&1; }
+
+fail() {
+  echo "FEHLER: $*" >&2
+  exit 1
+}
+
+info() { echo "==> $*"; }
+
+# =========================
+# Install packages (Debian/Ubuntu)
+# =========================
+install_packages() {
+  info "Installiere benötigte Pakete..."
+  export DEBIAN_FRONTEND=noninteractive
+  apt-get update -y
+  apt-get install -y \
+    realmd sssd sssd-tools libnss-sss libpam-sss adcli \
+    krb5-user packagekit samba-common-bin oddjob oddjob-mkhomedir \
+    dnsutils network-manager
+}
+
+# =========================
+# Disable Avahi/mDNS
+# =========================
+disable_mdns() {
+  if [[ "${DISABLE_AVAHI}" == "true" ]] && systemctl list-unit-files | grep -q '^avahi-daemon\.service'; then
+    info "Stoppe/Deaktiviere avahi-daemon (mDNS/.local)..."
+    systemctl stop avahi-daemon || true
+    systemctl disable avahi-daemon || true
+  fi
+
+  if [[ "${FORCE_NO_MDNS}" == "true" ]]; then
+    info "Erzwinge hosts: files dns (mdns raus) in /etc/nsswitch.conf..."
+    backup_file /etc/nsswitch.conf
+    if grep -q '^hosts:' /etc/nsswitch.conf; then
+      # setze hosts-Zeile hart auf "files dns"
+      sed -i -E 's/^hosts:.*/hosts: files dns/' /etc/nsswitch.conf
+    else
+      echo 'hosts: files dns' >> /etc/nsswitch.conf
+    fi
+  else
+    info "Setze nur dns vor mdns in /etc/nsswitch.conf..."
+    backup_file /etc/nsswitch.conf
+    # Best-effort: files dns mdns4_minimal
+    if grep -q '^hosts:' /etc/nsswitch.conf; then
+      sed -i -E 's/^hosts:.*/hosts: files dns mdns4_minimal/' /etc/nsswitch.conf
+    else
+      echo 'hosts: files dns mdns4_minimal' >> /etc/nsswitch.conf
+    fi
+  fi
+}
+
+# =========================
+# Set DNS persistently
+# =========================
+set_dns_persistent() {
+  info "Setze DNS persistent auf ${AD_DNS_IP}..."
+
+  # 1) NetworkManager: DNS fest in Verbindung setzen
+  if systemctl is-active --quiet NetworkManager && have_cmd nmcli; then
+    info "NetworkManager aktiv -> setze DNS via nmcli (persistent)"
+    # aktive Verbindung ermitteln
+    local con
+    con="$(nmcli -t -f NAME,DEVICE con show --active | head -n1 | cut -d: -f1 || true)"
+    if [[ -n "${con}" ]]; then
+      nmcli con mod "${con}" ipv4.ignore-auto-dns yes
+      nmcli con mod "${con}" ipv4.dns "${AD_DNS_IP}"
+      nmcli con mod "${con}" ipv4.dns-search "${DOMAIN}"
+      nmcli con up "${con}" >/dev/null
+      return 0
+    fi
+  fi
+
+  # 2) systemd-resolved: DNS auf Interface setzen (nicht immer persistent, aber oft)
+  if systemctl is-active --quiet systemd-resolved && have_cmd resolvectl; then
+    info "systemd-resolved aktiv -> setze DNS via resolvectl"
+    local iface
+    iface="$(ip -o route show default | awk '{print $5}' | head -n1)"
+    [[ -n "${iface}" ]] || fail "Konnte Default-Interface nicht ermitteln."
+    resolvectl dns "${iface}" "${AD_DNS_IP}"
+    resolvectl domain "${iface}" "~${DOMAIN}"
+    return 0
+  fi
+
+  # 3) Fallback: /etc/resolv.conf (kann überschrieben werden, aber besser als nichts)
+  info "Fallback -> schreibe /etc/resolv.conf (kann überschrieben werden)"
+  backup_file /etc/resolv.conf
+  cat >/etc/resolv.conf <<EOF
+search ${DOMAIN}
+nameserver ${AD_DNS_IP}
+EOF
+}
+
+# =========================
+# Kerberos: rdns=false
+# =========================
+set_krb5_options() {
+  if [[ "${SET_KRB5_RDNS_FALSE}" != "true" ]]; then
+    return 0
+  fi
+
+  info "Setze Kerberos rdns=false in /etc/krb5.conf..."
+  backup_file /etc/krb5.conf
+
+  # Wenn libdefaults existiert, rdns setzen/ersetzen, sonst block hinzufügen
+  if grep -q '^\s*\[libdefaults\]' /etc/krb5.conf; then
+    if grep -q '^\s*rdns\s*=' /etc/krb5.conf; then
+      sed -i -E 's/^\s*rdns\s*=.*/ rdns = false/' /etc/krb5.conf
+    else
+      # rdns nach libdefaults einfügen
+      awk '
+        BEGIN{done=0}
+        /^\s*\[libdefaults\]\s*$/{
+          print
+          if(!done){print " rdns = false"; done=1}
+          next
+        }
+        {print}
+      ' /etc/krb5.conf > /tmp/krb5.conf.new && mv /tmp/krb5.conf.new /etc/krb5.conf
+    fi
+  else
+    cat >>/etc/krb5.conf <<EOF
+
+[libdefaults]
+ rdns = false
+EOF
+  fi
+}
+
+# =========================
+# Preflight checks
+# =========================
+preflight() {
+  info "Prüfe Zeit (Kerberos ist zeitkritisch)..."
+  timedatectl status | sed -n '1,12p' || true
+
+  info "Prüfe DNS-Auflösung (_ldap SRV)..."
+  dig +short _ldap._tcp."${DOMAIN}" SRV | head -n5 || true
+
+  info "Prüfe DC Hostname (optional)..."
+  dig +short "${DC_HOST}" A || true
+
+  info "Realm discovery..."
+  realm discover "${DOMAIN}" || true
+
+  info "Kerberos Test (kinit) mit ${ADMIN_USER}..."
+  # kinit braucht Passwort -> interaktiv
+  # Wichtig: kinit muss funktionieren, sonst Join sinnlos
+  if ! kinit "${ADMIN_USER}"; then
+    fail "kinit fehlgeschlagen. Prüfe DNS/Zeit/Realm. (Ticket kommt nicht.)"
+  fi
+
+  info "klist (Ticket vorhanden?)"
+  klist || true
+}
+
+# =========================
+# Join domain
+# =========================
+join_domain() {
+  info "Domain-Join: ${DOMAIN} (Realm: ${REALM})..."
+  # leave nur best-effort
+  realm leave "${DOMAIN}" >/dev/null 2>&1 || true
+
+  if [[ -n "${COMPUTER_OU}" ]]; then
+    realm join "${DOMAIN}" -U "${ADMIN_USER}" --computer-ou="${COMPUTER_OU}" --verbose
+  else
+    realm join "${DOMAIN}" -U "${ADMIN_USER}" --verbose
+  fi
+
+  info "Aktiviere mkhomedir..."
+  pam-auth-update --enable mkhomedir || true
+
+  info "Starte SSSD neu..."
+  systemctl restart sssd || true
+
+  info "realm list:"
+  realm list || true
+
+  info "Test Benutzerauflösung:"
+  if [[ -n "${TEST_USER}" ]]; then
+    getent passwd "${TEST_USER}@${DOMAIN}" || true
+    id "${TEST_USER}@${DOMAIN}" || true
+  fi
+}
+
+# =========================
+# Main
+# =========================
+require_root
+install_packages
+disable_mdns
+set_dns_persistent
+set_krb5_options
+preflight
+join_domain
+
+info "FERTIG ✅"
+echo "Login-Format: user@${DOMAIN}"
+echo "Tipp: Teste Login: su - ${TEST_USER}@${DOMAIN}"