Ga naar hoofdinhoud
Probleemoplossing 10 min leestijd

sshd repareren na unattended upgrade op Ubuntu 24.04 (maart 2026)

Hoe openssh-server te repareren na mislukte unattended-upgrades op Ubuntu 24.04. Behandelt de ontbrekende /run/sshd-directory, de half-configured dpkg-status, mislukte ssh.socket en een volledig geautomatiseerd reparatiescript.

sshd repareren na unattended upgrade op Ubuntu 24.04 (maart 2026)

Op 16 maart 2026 brak een foutieve openssh-server upgrade (1:9.6p1-3ubuntu13.14 naar .15) SSH op Ubuntu 24.04-servers die unattended-upgrades draaien. De oorzaak lijkt een ontbrekende /run/sshd-map die ervoor zorgde dat het postinst-script faalde, waardoor dpkg half-geconfigureerd achterbleef en ssh.socket in een mislukte toestand terechtkwam. De oplossing is om de map opnieuw aan te maken, het verweesde sshd-proces te stoppen, systemd te resetten en het pakket opnieuw te configureren.

TL;DR - Snelle oplossing (uitvoeren als root)

mkdir -p /run/sshd && chmod 0755 /run/sshd
systemctl reset-failed ssh.socket ssh.service && systemctl start ssh.socket
dpkg --configure openssh-server

Als het oude sshd-proces de poort blokkeert, stop het dan eerst: kill $(pgrep -f '/usr/sbin/sshd' | xargs -I{} sh -c 'ps -o ppid= -p {} | tr -d " "' | grep '^1$'). Lees verder voor het volledige geautomatiseerde script.

Wat er misging

De openssh-server pakketupgrade van 1:9.6p1-3ubuntu13.14 naar 1:9.6p1-3ubuntu13.15 lijkt te zijn uitgebracht met een foutief postinst-onderhoudersscript. Toen unattended-upgrades 's nachts draaide en probeerde het nieuwe pakket te configureren, mislukte het script. Dit liet dpkg in een half-geconfigureerde toestand achter, zette systemds ssh.socket in een mislukte staat en liet het oude sshd-masterproces verweesd achter -- nog steeds actief, maar niet langer beheerd door systemd.

De server blijft bereikbaar zolang dat verweesde sshd-proces blijft draaien. Als het stopt of de server herstart, gaat SSH-toegang volledig verloren. In Laravel Forge tonen getroffen servers als "Disconnected" omdat Forge ze niet meer via SSH kan bereiken.

Hoe we het diagnosticeerden

Op een van onze getroffen systemen vonden we het volgende bij het onderzoeken.

dpkg: error processing package openssh-server

De pakketstatus controleren:

$ dpkg -s openssh-server | grep Status
Status: install ok half-configured

Dat bevestigt dat het pakket vastzit midden in een upgrade. Kijken wat unattended-upgrades deed:

$ cat /var/log/unattended-upgrades/unattended-upgrades-dpkg.log
...
Setting up openssh-server (1:9.6p1-3ubuntu13.15) ...
dpkg: error processing package openssh-server (--configure):
 installed openssh-server package post-installation script subprocess returned error exit status 1

ssh.socket: Failed with result 'service-start-limit-hit'

Systemd controleren:

$ systemctl status ssh.socket
Active: failed (Result: service-start-limit-hit)

$ journalctl -u ssh.socket
ssh.socket: Failed with result 'service-start-limit-hit'.
Failed to start ssh.socket - OpenBSD Secure Shell server socket.

$ journalctl -u ssh.service
ssh.service: Failed with result 'exit-code'.

Socket-activering is volledig kapot. Maar we konden nog steeds inloggen via SSH, wat betekende dat er nog iets luisterde. Het verweesde proces opsporen:

$ ps -eo pid,ppid,cmd | grep sshd
1234     1  sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups

PPID 1 -- dat is het oude sshd-masterproces, verweesd nadat systemd het kwijtraakte tijdens de mislukte upgrade. Het accepteert nog steeds verbindingen, waardoor SSH nog werkt, maar het draait op geleende tijd.

fatal: Missing privilege separation directory: /run/sshd

Het auth.log onthulde wat waarschijnlijk de oorzaak is:

$ grep sshd /var/log/auth.log
2026-03-18T18:20:19.201354+00:00 sshd[3115043]: fatal: Missing privilege separation directory: /run/sshd

De runtime-map ontbrak inderdaad:

$ ls -la /run/sshd
ls: cannot access '/run/sshd': No such file or directory

Deze ontbrekende map lijkt de oorzaak te zijn geweest van het falen van het postinst-script, omdat sshd het nodig heeft voor privilege-scheiding.

We vonden ook een crashrapport:

$ ls /var/crash/
openssh-server.0.crash

Foutmeldingen die je kunt tegenkomen

Afhankelijk van waar je kijkt, kun je enkele of alle van deze foutmeldingen tegenkomen:

In dpkg / apt uitvoer

dpkg: error processing package openssh-server (--configure):
 installed openssh-server package post-installation script subprocess returned error exit status 1
Errors were encountered while processing:
 openssh-server
E: Sub-process /usr/bin/dpkg returned an error code (1)

Bij het uitvoeren van apt upgrade of apt install

You might want to run 'apt --fix-broken install' to correct these.
The following packages have unmet dependencies:
 openssh-server : Depends: openssh-sftp-server but it is not going to be installed

Pakketstatus

Status: install ok half-configured

Systemd-fouten

ssh.socket: Failed with result 'service-start-limit-hit'.
ssh.service: Failed with result 'exit-code'.

Auth log

sshd[3115043]: fatal: Missing privilege separation directory: /run/sshd

Hoe je het oplost

We hebben een script geschreven dat de volledige oplossing automatiseert. Het is veilig om uit te voeren op servers die NIET getroffen zijn -- het detecteert de kapotte toestand eerst en stopt netjes als alles in orde is. Dit maakt het eenvoudig om het op al je servers uit te voeren zonder je zorgen te maken over welke daadwerkelijk kapot zijn.

Het script:

  1. Leest je SSH-poort uit sshd_config (gaat niet uit van poort 22)
  2. Detecteert of de server getroffen is (kapotte dpkg-toestand en/of mislukte ssh.socket)
  3. Maakt /run/sshd aan als die ontbreekt
  4. Zoekt en stopt het verweesde sshd-masterproces
  5. Wacht tot de poort vrijkomt
  6. Reset en start ssh.socket
  7. Voert dpkg --configure uit om de pakketstatus te herstellen
  8. Verifieert dat alles werkt
  9. Ruimt het crashbestand op

Hier is het volledige script:

#!/usr/bin/env bash
set -euo pipefail

# Fix broken openssh-server upgrade on Ubuntu 24.04
# Safe to run on unaffected servers -- exits cleanly.

if [[ $EUID -ne 0 ]]; then
    echo "ERROR: Must run as root." >&2
    exit 1
fi

echo "=== openssh-server upgrade fix ==="

# -- 0. Determine SSH port from sshd_config --
SSH_PORT=22
if [[ -f /etc/ssh/sshd_config ]]; then
    configured_port=$(grep -Ei '^\s*Port\s+' /etc/ssh/sshd_config | awk '{print $2}' | tail -1)
    if [[ -n "${configured_port:-}" ]]; then
        SSH_PORT="$configured_port"
    fi
fi
echo "[*] Using SSH port: $SSH_PORT"

# -- 1. Detect if affected --
broken_dpkg=false
failed_socket=false

if dpkg -s openssh-server 2>/dev/null | grep -qE 'Status:.*(half-configured|half-installed|unpacked|triggers-awaited|triggers-pending)'; then
    broken_dpkg=true
    echo "[!] openssh-server dpkg state is broken."
fi

if systemctl is-failed --quiet ssh.socket 2>/dev/null; then
    failed_socket=true
    echo "[!] ssh.socket is in failed state."
fi

if ! $broken_dpkg && ! $failed_socket; then
    echo "[OK] Server is not affected. openssh-server package and ssh.socket are healthy."
    exit 0
fi

echo ""
echo "Server is affected. Proceeding with fix..."
echo ""

# -- 2. Create /run/sshd if missing --
if [[ ! -d /run/sshd ]]; then
    echo "[*] Creating /run/sshd ..."
    mkdir -p /run/sshd
    chmod 0755 /run/sshd
else
    echo "[OK] /run/sshd already exists."
fi

# -- 3. Kill orphaned sshd master process --
orphan_pids=()
while IFS= read -r pid; do
    [[ -z "$pid" ]] && continue
    ppid=$(ps -o ppid= -p "$pid" 2>/dev/null | tr -d ' ') || continue
    if [[ "$ppid" == "1" ]]; then
        orphan_pids+=("$pid")
    fi
done < <(pgrep -f '/usr/sbin/sshd' 2>/dev/null || true)

if [[ ${#orphan_pids[@]} -gt 0 ]]; then
    echo "[*] Found orphaned sshd master process(es): ${orphan_pids[*]}"
    for pid in "${orphan_pids[@]}"; do
        echo "    Killing PID $pid ..."
        kill "$pid" 2>/dev/null || true
    done
else
    echo "[OK] No orphaned sshd master processes found."
fi

# -- 4. Wait for port to free --
echo "[*] Waiting for port $SSH_PORT to free ..."
for i in $(seq 1 30); do
    if ! ss -tlnp | grep -q ":${SSH_PORT} "; then
        echo "    Port $SSH_PORT is free."
        break
    fi
    if [[ $i -eq 30 ]]; then
        echo "WARNING: Port $SSH_PORT still in use after 30s. Continuing anyway."
    fi
    sleep 1
done

# -- 5. Reset and start ssh.socket --
echo "[*] Resetting ssh.socket ..."
systemctl reset-failed ssh.socket 2>/dev/null || true
systemctl reset-failed ssh.service 2>/dev/null || true

echo "[*] Starting ssh.socket ..."
systemctl start ssh.socket

# -- 6. Fix dpkg state --
if $broken_dpkg; then
    echo "[*] Running dpkg --configure openssh-server ..."
    dpkg --configure openssh-server
fi

# -- 7. Verify --
echo ""
echo "=== Verification ==="

errors=0

if systemctl is-active --quiet ssh.socket; then
    echo "[OK] ssh.socket is active."
else
    echo "[FAIL] ssh.socket is NOT active."
    errors=$((errors + 1))
fi

if ss -tlnp | grep -q ":${SSH_PORT} "; then
    echo "[OK] Port $SSH_PORT is listening."
else
    echo "[FAIL] Port $SSH_PORT is NOT listening."
    errors=$((errors + 1))
fi

status=$(dpkg -s openssh-server 2>/dev/null | grep '^Status:' || echo "not found")
if echo "$status" | grep -q 'install ok installed'; then
    echo "[OK] dpkg state is clean: $status"
else
    echo "[FAIL] dpkg state is not clean: $status"
    errors=$((errors + 1))
fi

# -- 8. Clean up crash file --
if [[ -f /var/crash/openssh-server.0.crash ]]; then
    echo "[*] Removing /var/crash/openssh-server.0.crash ..."
    rm -f /var/crash/openssh-server.0.crash
fi

echo ""
if [[ $errors -eq 0 ]]; then
    echo "=== All checks passed. Server is fixed. ==="
else
    echo "=== $errors check(s) failed. Manual investigation needed. ==="
    exit 1
fi

Om het op een enkele server uit te voeren:

sudo bash fix-openssh-upgrade.sh

Om het naar meerdere servers te sturen:

for server in server1 server2 server3; do
    echo "--- $server ---"
    ssh root@$server 'bash -s' < fix-openssh-upgrade.sh
done

Dit in de toekomst voorkomen

Als je wilt voorkomen dat unattended-upgrades openssh-server in de toekomst aanraakt, kun je het op een zwarte lijst zetten. Bewerk /etc/apt/apt.conf.d/50unattended-upgrades en voeg toe aan de Package-Blacklist-sectie:

Unattended-Upgrade::Package-Blacklist {
    "openssh-server";
};

Dit zorgt ervoor dat SSH-gerelateerde pakketten alleen worden geupgraded wanneer je dat handmatig doet en het proces kunt bewaken.

Als je volledig buitengesloten bent

Als het verweesde sshd-proces al gestopt is of de server herstart is, kun je niet meer inloggen via SSH. Gebruik in dat geval de consoletoegang van je hostingprovider om de oplossing uit te voeren:

  • DigitalOcean: Droplet Console (webgebaseerd)
  • AWS: EC2 Serial Console of Session Manager
  • Hetzner: VNC-console in de Cloud Console
  • Elke provider: VNC- of KVM-toegang via je controlepaneel

Samenvatting

De openssh-server upgrade van 16 maart 2026 op Ubuntu 24.04 brak SSH op servers die unattended-upgrades draaien. De symptomen zijn een half-geconfigureerde dpkg-toestand, een mislukte ssh.socket, een "fatal: Missing privilege separation directory: /run/sshd" fout in auth.log, een verweesd sshd-proces en servers die als "Disconnected" verschijnen in Laravel Forge. De oplossing omvat het opnieuw aanmaken van /run/sshd, het stoppen van het verweesde proces, het resetten van systemd-units en het herconfigueren van het pakket. Het bovenstaande script automatiseert het volledige proces en is veilig uit te voeren op niet-getroffen servers.

Monitor je eigen servers

Volg CPU, geheugen, schijf en processen op tot 2 servers gratis. Instellen duurt ongeveer 5 minuten.

Gratis beginnen

Gerelateerde artikelen