| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- #!/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}"
|