{"id":8594,"date":"2026-01-28T19:42:20","date_gmt":"2026-01-28T18:42:20","guid":{"rendered":"https:\/\/speefak.spdns.de\/oss_lifestyle\/?p=8594"},"modified":"2026-03-02T00:13:20","modified_gmt":"2026-03-01T23:13:20","slug":"proxmox-host-verzeichnisse-mit-virtiofs-in-vms-einbinden","status":"publish","type":"post","link":"https:\/\/speefak.spdns.de\/oss_lifestyle\/proxmox-host-verzeichnisse-mit-virtiofs-in-vms-einbinden\/","title":{"rendered":"Proxmox: Host-Verzeichnisse mit Virtiofs in VMs einbinden"},"content":{"rendered":"<p>Virtiofs ist eine moderne und performante Methode, um Verzeichnisse direkt vom Proxmox-Host in virtuelle Maschinen einzubinden. Im Gegensatz zu klassischen Netzwerkdateisystemen wie NFS oder SSHFS erfolgt der Zugriff lokal \u00fcber den Hypervisor, ohne Netzwerk-Stack und ohne zus\u00e4tzliche Dienste. Dadurch eignet sich virtiofs besonders f\u00fcr High-Performance-Dateifreigaben zwischen Host und VM,\u00a0in denen hoher Datendurchsatz, geringe Latenz und eine klare Rechteverwaltung erforderlich sind, etwa bei Videoaufzeichnungen, Datenbanken oder Medienarchiven.<\/p>\n<hr \/>\n<h2>1. Grundprinzip von virtiofs<\/h2>\n<p>Virtiofs arbeitet strikt POSIX-konform:<\/p>\n<ul>\n<li>Benutzer- und Gruppen-IDs (UID\/GID) werden <strong>numerisch 1:1<\/strong> vom Host in die VM durchgereicht<\/li>\n<li>Es findet <strong>kein User- oder ID-Mapping<\/strong> statt<\/li>\n<li>Dateirechte und Benutzer werden <strong>ausschlie\u00dflich auf dem Host<\/strong> definiert und von der VM \u00fcbernommen<\/li>\n<li>Mount-Optionen wie <code>uid=<\/code>, <code>gid=<\/code> oder <code>allow_other<\/code> werden ignoriert<\/li>\n<\/ul>\n<p>Das bedeutet: Stimmen UID\/GID zwischen Host und VM nicht exakt \u00fcberein, ist Schreiben im Gast nicht m\u00f6glich.<\/p>\n<hr \/>\n<h2>2. Host vorbereiten<\/h2>\n<h3>2.1 Host-Verzeichnis<\/h3>\n<p>F\u00fcr die Nutzung von Virtio-FS ist eine eindeutige Trennung zwischen dem Verzeichnis auf dem Proxmox-Host und dem Mountpunkt innerhalb der virtuellen Maschine erforderlich. Das Verzeichnis befindet sich physisch auf dem Host, entweder auf einem lokalen Datentr\u00e4ger oder auf einem eingebundenen Storage, und dient als Quelle der Virtio-FS-Freigabe. S\u00e4mtliche Zugriffsrechte, Eigent\u00fcmer und Gruppen werden ausschlie\u00dflich an diesem Ort definiert und unver\u00e4ndert an die virtuelle Maschine weitergereicht.<\/p>\n<pre class=\"lang:default decode:true\">\/mnt\/proxmox-host-dir<\/pre>\n<hr \/>\n<h3>2.2 Benutzer und Gruppen<\/h3>\n<p data-start=\"40\" data-end=\"672\">Der Benutzer, der innerhalb der virtuellen Maschine Schreibzugriff auf das \u00fcber virtiofs eingebundene Verzeichnis erhalten soll, muss auf dem Proxmox-Host mit identischer Benutzerkennung (UID) und Gruppenzugeh\u00f6rigkeit (GID) vorhanden sein. virtiofs f\u00fchrt keine \u00dcbersetzung oder Abbildung von Benutzer- und Gruppenkennungen durch, sondern reicht diese unver\u00e4ndert vom Gast an den Host weiter. Abweichende UIDs oder GIDs f\u00fchren dazu, dass Zugriffe aus der VM auf Host-Ebene als fremder oder nicht existenter Benutzer interpretiert werden, was in der Praxis zu fehlenden Schreibrechten oder unerwarteten Zugriffsverweigerungen f\u00fchrt.<\/p>\n<p data-start=\"679\" data-end=\"950\" data-is-last-node=\"\">Aus diesem Grund ist sicherzustellen, dass die relevanten Benutzer und Gruppen auf Host und virtueller Maschine identische numerische IDs besitzen und dass das freigegebene Host-Verzeichnis die entsprechenden Zugriffsrechte entsprechend dieser IDs aufweist.<\/p>\n<ul>\n<li>Vorhandene Benutzer und Gruppen k\u00f6nnen \u00fcberpr\u00fcft werden:<\/li>\n<\/ul>\n<pre class=\"lang:default decode:true\">getent passwd vuser\r\ngetent group vuser<\/pre>\n<ul>\n<li>Falls der Benutzer noch nicht existiert, kann er mit den entsprechenden IDs angelegt werden (ohne Login Shell und Home Verzeichnis):<\/li>\n<\/ul>\n<pre class=\"lang:default decode:true\">useradd -u 200 -g 200 -s \/usr\/sbin\/nologin -M vuser\r\ngroupadd -g 200 vuser<\/pre>\n<ul>\n<li>Falls der Benutzer bereits existiert, k\u00f6nnen UID und GID bei Bedarf angepasst werden:<\/li>\n<\/ul>\n<pre class=\"lang:default decode:true\">usermod -u 200 vuser # UID \u00e4ndern\r\ngroupmod -g 200 vuser # GID \u00e4ndern\r\nchown -R vuser:vuser \/home\/vuser # Besitzrechte aktualisieren\r\n\r\n# Berechtigungen korrigieren. Alte UID und GID (33) an neue IDs (301) systemweit anpassen.\r\nsudo find \/ \\( -user 33 -o -group 33 \\) -not -path \"\/proc\/*\" -not -path \"\/sys\/*\" -not -path \"\/dev\/*\" -exec chown -h 301:301 {} + 2&gt;\/dev\/null<\/pre>\n<ul>\n<li>Die UID\/GID m\u00fcssen mit dem Host \u00fcbereinstimmen, damit Virtio-FS die Zugriffsrechte korrekt durchreicht.<\/li>\n<li>Das Home-Verzeichnis und die Shell k\u00f6nnen nach Bedarf angepasst werden; f\u00fcr reine Virtio-FS-Nutzung ist ein Login oder Home Verzeichnis nicht erforderlich.<\/li>\n<\/ul>\n<p style=\"text-align: center;\"><span style=\"text-decoration: underline;\"><strong>Script zum Anlegen eines Systemusers:<\/strong><\/span><\/p>\n<pre class=\"height-set:true height:165 lang:default decode:true\">#!\/usr\/bin\/env bash\r\n#\r\n# Creates a lightweight system user + matching group\r\n# - No home directory (-M)\r\n# - Shell: \/usr\/sbin\/nologin (no login possible)\r\n# - UID and GID are identical\r\n# - Username: vuser + Unix timestamp (seconds)\r\n# - UID range: 300\u2013999 (typical system user range)\r\n# - Scriptname: add-system-user.sh\r\n# - Suppresses useradd warning about UID_MIN\/MAX\r\n#\r\n\r\nset -euo pipefail\r\n\r\n# ==================== CONFIGURATION ====================\r\nMIN_ID=300\r\nMAX_ID=999\r\nDEFAULT_SHELL=\"\/usr\/sbin\/nologin\"\r\nUSER_PREFIX=\"vuser\"\r\nCOMMENT=\"System service user\"\r\n# =========================================================\r\n\r\n# \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n# Check if running as root\r\n# \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nif [ \"$EUID\" -ne 0 ]; then\r\n    echo \"ERROR: This script must be run as root!\"\r\n    echo \"\"\r\n    echo \"Please run the script with sudo:\"\r\n    echo \"  sudo bash $0\"\r\n    echo \"\"\r\n    exit 1\r\nfi\r\n\r\n# \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n# Functions\r\n# \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nfind_next_free_id() {\r\n    local start_id=$1\r\n    local id=$start_id\r\n\r\n    while [ $id -le $MAX_ID ]; do\r\n        if ! getent passwd \"$id\" &gt;\/dev\/null 2&gt;&amp;1 &amp;&amp; \\\r\n           ! getent group  \"$id\" &gt;\/dev\/null 2&gt;&amp;1; then\r\n            echo \"$id\"\r\n            return 0\r\n        fi\r\n        ((id++))\r\n    done\r\n\r\n    echo \"Error: No free UID\/GID found between $MIN_ID and $MAX_ID!\" &gt;&amp;2\r\n    exit 1\r\n}\r\n\r\ngenerate_timestamp_suffix() {\r\n    date +%s\r\n}\r\n\r\n# \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n# Main program\r\n# \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\necho \"\u2192 Searching for next free UID\/GID starting from ${MIN_ID} ...\"\r\n\r\nFREE_ID=$(find_next_free_id \"$MIN_ID\")\r\nTIMESTAMP_SUFFIX=$(generate_timestamp_suffix)\r\nUSERNAME=\"${USER_PREFIX}${TIMESTAMP_SUFFIX}\"\r\n\r\n# \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n# Confirmation &amp; edit loop\r\n# \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nwhile true; do\r\n    echo \"\"\r\n    echo \"Suggested values:\"\r\n    echo \"  Username     : ${USERNAME}\"\r\n    echo \"  UID \/ GID    : ${FREE_ID}\"\r\n    echo \"  Group        : ${USERNAME}\"\r\n    echo \"  Shell        : ${DEFAULT_SHELL}\"\r\n    echo \"  Comment      : ${COMMENT}\"\r\n    echo \"\"\r\n\r\n    read -p \"Proceed with these values?  [y\/n\/c]  \" -n 1 -r choice\r\n    echo\r\n\r\n    case \"$choice\" in\r\n        [Yy])\r\n            echo \"\u2192 Creating user and group ...\"\r\n            break\r\n            ;;\r\n        [Nn])\r\n            echo \"\"\r\n            echo \"Edit values (press Enter to keep current value):\"\r\n            echo \"\"\r\n\r\n            read -e -i \"${USERNAME}\" -p \"Username     [${USERNAME}]: \" input\r\n            [ -n \"$input\" ] &amp;&amp; USERNAME=\"$input\"\r\n\r\n            read -e -i \"${FREE_ID}\" -p \"UID \/ GID    [${FREE_ID}]: \" input\r\n            [ -n \"$input\" ] &amp;&amp; FREE_ID=\"$input\"\r\n\r\n            read -e -i \"${DEFAULT_SHELL}\" -p \"Shell        [${DEFAULT_SHELL}]: \" input\r\n            [ -n \"$input\" ] &amp;&amp; DEFAULT_SHELL=\"$input\"\r\n\r\n            read -e -i \"${COMMENT}\" -p \"Comment      [${COMMENT}]: \" input\r\n            [ -n \"$input\" ] &amp;&amp; COMMENT=\"$input\"\r\n\r\n            continue\r\n            ;;\r\n        [Cc])\r\n            echo \"\u2192 Aborted.\"\r\n            exit 0\r\n            ;;\r\n        *)\r\n            echo \"Invalid input. Please enter y, n or c.\"\r\n            continue\r\n            ;;\r\n    esac\r\ndone\r\n\r\n# \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n# Creation\r\n# \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\necho \"\"\r\necho \"Creating group ${USERNAME} (GID ${FREE_ID}) ...\"\r\n\r\nif ! groupadd -g \"${FREE_ID}\" \"${USERNAME}\"; then\r\n    echo \"Error creating group ${USERNAME} (GID ${FREE_ID})\" &gt;&amp;2\r\n    exit 1\r\nfi\r\n\r\necho \"Creating user ${USERNAME} (UID ${FREE_ID}) ...\"\r\n\r\n# Suppress useradd warning about UID range, but detect real errors\r\nif ! useradd \\\r\n    -u \"${FREE_ID}\" \\\r\n    -g \"${FREE_ID}\" \\\r\n    -s \"${DEFAULT_SHELL}\" \\\r\n    -M \\\r\n    -c \"${COMMENT}\" \\\r\n    \"${USERNAME}\" 2&gt;\/dev\/null; then\r\n\r\n    echo \"\"\r\n    echo \"\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\"\r\n    echo \"\u2502               ERROR CREATING THE USER                        \u2502\"\r\n    echo \"\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\"\r\n    echo \"Username:   ${USERNAME}\"\r\n    echo \"UID\/GID:    ${FREE_ID}\"\r\n    echo \"\"\r\n    echo \"Possible causes:\"\r\n    echo \"  \u2022 Username already exists\"\r\n    echo \"  \u2022 UID or GID already in use\"\r\n    echo \"  \u2022 Invalid characters in username\"\r\n    echo \"\"\r\n    echo \"Try running the command manually for more details:\"\r\n    echo \"  useradd -u ${FREE_ID} -g ${FREE_ID} -s ${DEFAULT_SHELL} -M -c \\\"${COMMENT}\\\" ${USERNAME}\"\r\n    echo \"\"\r\n\r\n    # Cleanup\r\n    groupdel \"${USERNAME}\" 2&gt;\/dev\/null || true\r\n    exit 1\r\nfi\r\n\r\necho \"\"\r\necho \"========================================\"\r\necho \"         Successfully created!          \"\r\necho \"========================================\"\r\necho \"Username     : ${USERNAME}\"\r\necho \"Group        : ${USERNAME}\"\r\necho \"UID \/ GID    : ${FREE_ID}\"\r\necho \"Shell        : ${DEFAULT_SHELL}\"\r\necho \"Comment      : ${COMMENT}\"\r\necho \"========================================\"\r\necho \"\"\r\n\r\nexit 0<\/pre>\n<p style=\"text-align: center;\"><strong>Script zum \u00e4ndern von User und Gruppen IDs und systemweite korrektor der Dateirechte:<\/strong><\/p>\n<pre class=\"height-set:true height:180 lang:default decode:true \">#!\/usr\/bin\/env bash\r\n#\r\n# - Interactive user selection (UID &lt; 1000)\r\n# - UID and GID are set to the same value\r\n# - Automatically updates all matching files\r\n#\r\n# WARNING:\r\n# Can break services \u2013 backup \/etc\/passwd and \/etc\/group first!\r\n# Restart affected services after execution.\r\n# \r\n# Script name: change-uid-gid.sh\r\n#\r\n\r\nset -euo pipefail\r\n\r\n# -------------------------------------------------------\r\n# 1. Root check\r\n# -------------------------------------------------------\r\nif [ \"$EUID\" -ne 0 ]; then\r\n    echo \"ERROR: This script must be run as root!\"\r\n    echo \"       sudo bash $0\"\r\n    exit 1\r\nfi\r\n\r\necho \"\"\r\necho \"=== UID \/ GID Change Script ===\"\r\necho \"WARNING: This operation can break services and applications!\"\r\necho \"         Backup recommended (e.g. cp \/etc\/passwd \/etc\/passwd.bak)\"\r\necho \"\"\r\n\r\n# -------------------------------------------------------\r\n# 2. Select user \u2013 all with UID &lt; 1000\r\n# -------------------------------------------------------\r\necho \"Available users (UID &lt; 1000):\"\r\necho \"------------------------------------------------\"\r\n\r\nPS3=\"Select a user (enter number): \"\r\n\r\n# List all users with UID &lt; 1000 (excluding some special pseudo-accounts)\r\nmapfile -t users &lt; &lt;(awk -F: '$3 &lt; 1000 &amp;&amp; $3 &gt;= 0 &amp;&amp; $7 !~ \/(sync|halt|shutdown)$\/ {print $1}' \/etc\/passwd | sort -u)\r\n\r\nif [ ${#users[@]} -eq 0 ]; then\r\n    echo \"No users with UID &lt; 1000 found.\"\r\n    exit 1\r\nfi\r\n\r\nselect username in \"${users[@]}\"; do\r\n    if [[ -n \"$username\" ]]; then\r\n        break\r\n    fi\r\n    echo \"Invalid selection, please try again.\"\r\ndone\r\n\r\n# Get current UID \/ GID\r\nold_uid=$(id -u \"$username\" 2&gt;\/dev\/null || echo \"not found\")\r\nold_gid=$(id -g \"$username\" 2&gt;\/dev\/null || echo \"not found\")\r\n\r\necho \"\"\r\necho \"Selected user:   $username\"\r\necho \"Current UID:     $old_uid\"\r\necho \"Current GID:     $old_gid\"\r\necho \"\"\r\n\r\n# -------------------------------------------------------\r\n# 3. Ask for new UID\r\n# -------------------------------------------------------\r\nwhile true; do\r\n    read -p \"Enter new UID (GID will be set to the same value): \" new_uid\r\n\r\n    # Check if it's a number\r\n    if ! [[ \"$new_uid\" =~ ^[0-9]+$ ]]; then\r\n        echo \"\u2192 Only numbers allowed!\"\r\n        continue\r\n    fi\r\n\r\n    # Check if already in use (except for the current user itself)\r\n    if getent passwd \"$new_uid\" &gt;\/dev\/null 2&gt;&amp;1 &amp;&amp; [ \"$new_uid\" != \"$old_uid\" ]; then\r\n        echo \"\u2192 UID $new_uid is already in use!\"\r\n        continue\r\n    fi\r\n    if getent group \"$new_uid\" &gt;\/dev\/null 2&gt;&amp;1 &amp;&amp; [ \"$new_uid\" != \"$old_gid\" ]; then\r\n        echo \"\u2192 GID $new_uid is already in use!\"\r\n        continue\r\n    fi\r\n\r\n    # Confirmation\r\n    read -p \"Really change UID and GID of $username to $new_uid? (y\/N): \" -n 1 confirm\r\n    echo\r\n    if [[ \"$confirm\" =~ ^[Yy]$ ]]; then\r\n        break\r\n    else\r\n        echo \"Aborted.\"\r\n        exit 0\r\n    fi\r\ndone\r\n\r\nnew_gid=\"$new_uid\"\r\n\r\n# -------------------------------------------------------\r\n# 4. Perform changes\r\n# -------------------------------------------------------\r\necho \"\"\r\necho \"Performing changes:\"\r\necho \"  User:        $username\"\r\necho \"  Old UID:     $old_uid  \u2192  New UID: $new_uid\"\r\necho \"  Old GID:     $old_gid  \u2192  New GID: $new_gid\"\r\necho \"\"\r\n\r\n# Change UID\r\necho \"\u2192 usermod -u $new_uid $username\"\r\nusermod -u \"$new_uid\" \"$username\" || { echo \"usermod failed\"; exit 1; }\r\n\r\n# Change GID\r\necho \"\u2192 groupmod -g $new_gid $username\"\r\ngroupmod -g \"$new_gid\" \"$username\" || { echo \"groupmod failed\"; exit 1; }\r\n\r\n# Update user's primary group (if needed)\r\nusermod -g \"$new_gid\" \"$username\" 2&gt;\/dev\/null || true\r\n\r\n# -------------------------------------------------------\r\n# 5. Correct file ownership system-wide\r\n# -------------------------------------------------------\r\necho \"\"\r\necho \"\u2192 Searching and correcting files owned by old UID\/GID ($old_uid \/ $old_gid) ...\"\r\necho \"  (this may take a few minutes depending on your system)\"\r\n\r\nfind \/ \\\r\n    \\( -user \"$old_uid\" -o -group \"$old_gid\" \\) \\\r\n    -not -path \"\/proc\/*\" \\\r\n    -not -path \"\/sys\/*\" \\\r\n    -not -path \"\/dev\/*\" \\\r\n    -exec chown -h \"$new_uid:$new_gid\" {} + 2&gt;\/dev\/null\r\n\r\necho \"\"\r\necho \"Done!\"\r\necho \"\"\r\necho \"Verification:\"\r\necho \"  id $username\"\r\necho \"\"\r\necho \"IMPORTANT:\"\r\necho \"  \u2022 Restart any services that use this user (apache2, nginx, php-fpm, docker, etc.)\"\r\necho \"  \u2022 Example:  systemctl restart apache2\"\r\necho \"  \u2022 Check logs if services fail to start\"\r\necho \"\"\r\n\r\nexit 0<\/pre>\n<hr \/>\n<h3>2.3 Benutzer und Rechte setzen<\/h3>\n<pre class=\"lang:default decode:true\">chown -R vuser:vuser \/mnt\/proxmox-host-dir\r\nchmod -R 775 \/mnt\/proxmox-host-dir\r\nchmod g+s \/mnt\/proxmox-host-dir<\/pre>\n<ul>\n<li>775 erlaubt Schreiben f\u00fcr User und Gruppe<\/li>\n<li>g+s stellt sicher, dass neu angelegte Dateien automatisch die Gruppe behalten<\/li>\n<\/ul>\n<p>Alle \u00fcbergeordneten Verzeichnisse m\u00fcssen mindestens das Execute-Bit (<code>x<\/code>) f\u00fcr die jeweilige Gruppe besitzen.<\/p>\n<hr \/>\n<h2>3 Einrichtung eines Virtio-FS-Ger\u00e4ts in Proxmox (Verzeichnis-Mapping)<\/h2>\n<p data-start=\"175\" data-end=\"526\">Bevor in der VM ein virtiofs-Verzeichnis gemountet werden kann, muss in Proxmox zun\u00e4chst das entsprechende Host-Verzeichnis als virtiofs-Ger\u00e4t erstellt werden. Dazu in der Weboberfl\u00e4che zu <strong data-start=\"273\" data-end=\"312\">Rechenzentrum \u2192 Verzeichnis-Mapping<\/strong> navigieren, dort auf <strong data-start=\"334\" data-end=\"360\">Erstellen \/ Hinzuf\u00fcgen<\/strong> klicken und folgende Felder ausf\u00fcllen und anschlie\u00dfend mit\u00a0<strong data-start=\"752\" data-end=\"765\">Erstellen<\/strong> best\u00e4tigen.<\/p>\n<ul data-start=\"402\" data-end=\"746\">\n<li data-start=\"402\" data-end=\"514\"><strong data-start=\"404\" data-end=\"419\">Name \/ Tag:<\/strong> Eindeutiger Bezeichner, z.\u202fB. <code data-start=\"450\" data-end=\"463\">proxmox-host-dir-name<\/code> (wird sp\u00e4ter in der VM als Mount-Name verwendet)<\/li>\n<li data-start=\"515\" data-end=\"609\"><strong data-start=\"517\" data-end=\"526\">Pfad:<\/strong> Host-Verzeichnis, z.\u202fB. <code data-start=\"551\" data-end=\"607\">\/mnt\/proxmox-host-dir<\/code><\/li>\n<li data-start=\"515\" data-end=\"609\"><strong data-start=\"612\" data-end=\"623\">Knoten:<\/strong> Zielknoten ausw\u00e4hlen<\/li>\n<li data-start=\"515\" data-end=\"609\"><strong data-start=\"649\" data-end=\"663\">Kommentar:<\/strong> optional, z.\u202fB. \u201eFreigabe f\u00fcr Ubuntu-VM\u201c<\/li>\n<li data-start=\"515\" data-end=\"609\">\u00a0<strong data-start=\"709\" data-end=\"737\">ACL \/ Sicherheitsmodell:<\/strong> <code data-start=\"738\" data-end=\"744\">none<\/code><\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\"><\/li>\n<\/ul>\n<h4>3.1 Zuweisung des Verzeichnis-Mappings an die VM<\/h4>\n<ul>\n<li>Die gew\u00fcnschte VM ausw\u00e4hlen \u2192 <strong>Hardware \u2192 Hinzuf\u00fcgen \u2192 VirtIO-FS-Ger\u00e4t<\/strong>.<\/li>\n<li>Im Feld <strong>Tag<\/strong> den zuvor definierten Namen des Verzeichnis-Mappings eintragen (<code>proxmox-host-dir-name<\/code>).<\/li>\n<li>Optional: <strong>Nur Lesen<\/strong> aktivieren, falls Schreibzugriff nicht erforderlich ist.<\/li>\n<li>\u00c4nderungen speichern.<\/li>\n<\/ul>\n<p>Dadurch wird das Verzeichnis des Proxmox-Hosts (<code data-start=\"103\" data-end=\"126\">\/mnt\/proxmox-host-dir<\/code>) der virtuellen Maschine unter dem Bezeichner <code data-start=\"173\" data-end=\"196\">proxmox-host-dir-name<\/code> als Mountquelle bereitgestellt.<\/p>\n<hr \/>\n<h2>4. VM vorbereiten<\/h2>\n<h4>4.1 Benutzer anlegen \/ anpassen<\/h4>\n<p>In der virtuellen Maschine muss derselbe Benutzer mit identischer UID und GID wie auf dem Proxmox-Host existieren.<\/p>\n<ul>\n<li>Vorhandene Benutzer und Gruppen k\u00f6nnen \u00fcberpr\u00fcft werden:<\/li>\n<\/ul>\n<pre class=\"lang:default decode:true\">getent passwd vuser\r\ngetent group vuser<\/pre>\n<ul>\n<li>Falls der Benutzer noch nicht existiert, kann er mit den entsprechenden IDs angelegt werden:<\/li>\n<\/ul>\n<pre class=\"lang:default decode:true\">groupadd -g 200 vuser\r\nuseradd -u 200 -g 200 -d \/home\/vuser -s \/bin\/bash vuser<\/pre>\n<ul>\n<li>Falls der Benutzer bereits existiert, k\u00f6nnen UID und GID bei Bedarf angepasst werden:<\/li>\n<\/ul>\n<pre class=\"lang:default decode:true \">usermod -u 200 vuser       # UID \u00e4ndern\r\ngroupmod -g 200 vuser      # GID \u00e4ndern\r\nchown -R vuser:vuser \/home\/vuser  # Besitzrechte aktualisieren<\/pre>\n<p><strong>Hinweise:<\/strong><\/p>\n<ul>\n<li>Die UID\/GID m\u00fcssen mit dem Host \u00fcbereinstimmen, damit Virtio-FS die Zugriffsrechte korrekt durchreicht.<\/li>\n<li>Das Home-Verzeichnis und die Shell k\u00f6nnen nach Bedarf angepasst werden; f\u00fcr reine Virtio-FS-Nutzung ist ein Login nicht zwingend erforderlich.<\/li>\n<\/ul>\n<hr \/>\n<h4>4.2 Mountpunkt in der VM erstellen und \u00fcber fstab beim starten einbinden<\/h4>\n<p>Nachdem der Benutzer mit den entsprechenden UID\/GID in der VM eingerichtet wurde, wird ein Verzeichnis angelegt, das als Ziel f\u00fcr die Virtio-FS-Freigabe vom Host dient. Mit <code data-start=\"285\" data-end=\"295\">mkdir -p<\/code> wird der Mountpunkt einschlie\u00dflich aller \u00fcbergeordneten Verzeichnisse erstellt, falls diese noch nicht existieren<\/p>\n<pre class=\"lang:default decode:true\">mkdir -p \/mnt\/host-dir\r\n<\/pre>\n<p>Vor dem dauerhaften Eintrag kann der Mount manuell getestet werden, um sicherzustellen, dass die Freigabe funktioniert.<\/p>\n<pre class=\"lang:default decode:true\">mount -t virtiofs proxmox-host-dir-name \/mnt\/host-dir<\/pre>\n<p>mount -t virtiofs verbindet das Host-Verzeichnis (\u00fcber den Tag <code>proxmox-host-dir-name<\/code>) mit dem Mountpunkt in der VM. F\u00fcr einen automatischen Mount bei jedem Bootvorgang wird ein Eintrag in <code>\/etc\/fstab<\/code> erstellt.<\/p>\n<pre class=\"lang:default decode:true\">proxmox-host-dir-name \/mnt\/host-dir virtiofs rw,nofail,x-systemd.automount 0 0<\/pre>\n<ul>\n<li><code>rw<\/code> \u2013 Verzeichnis kann gelesen und beschrieben werden<\/li>\n<li><code>nofail<\/code> \u2013 System startet weiter, auch wenn das Mounten fehlschl\u00e4gt<\/li>\n<li><code>x-systemd.automount<\/code> \u2013 Mount erfolgt erst beim ersten Zugriff, beschleunigt den Bootvorgang<\/li>\n<\/ul>\n<hr \/>\n<h2>5. Funktionstest<\/h2>\n<pre class=\"lang:default decode:true\">mount -a\r\nsudo -u vuser touch \/mnt\/host-dir\/testfile\r\nls -l \/mnt\/host-dir\r\n<\/pre>\n<p>Erwartetes Ergebnis:<\/p>\n<pre class=\"lang:default decode:true\">-rw-r--r-- 1 vuser vuser testfile<\/pre>\n<hr \/>\n<h2>6. Typische Fehlerquellen<\/h2>\n<ul>\n<li>UID\/GID zwischen Host und VM stimmen nicht \u00fcberein<\/li>\n<li>Ownership wurde nur im Gast, nicht auf dem Host gesetzt<\/li>\n<li>\u00dcbergeordnete Verzeichnisse blockieren den Zugriff (<code>x<\/code> fehlt)<\/li>\n<li>Mount-Optionen wie <code>uid=<\/code> oder <code>gid=<\/code> werden verwendet (wirkungslos)<\/li>\n<\/ul>\n<p>Debug-Hilfe:<\/p>\n<pre class=\"lang:default decode:true \">sudo namei -l \/mnt\/host-dir\r\nsudo journalctl -b | grep virtiofs<\/pre>\n<hr \/>\n<h2>7. Zusammenfassung<\/h2>\n<p>Virtiofs ist eine performante und saubere L\u00f6sung, um Host-Verzeichnisse direkt in Proxmox-VMs zu nutzen. Entscheidend ist ein konsistentes Benutzer- und Rechtekonzept:<\/p>\n<ul>\n<li>UID\/GID m\u00fcssen identisch sein<\/li>\n<li>Rechte werden ausschlie\u00dflich auf dem Host gepflegt<\/li>\n<li>Der fstab-Eintrag entscheidet \u00fcber Boot-Verhalten und Stabilit\u00e4t<\/li>\n<\/ul>\n<p>Bei korrekter Einrichtung verh\u00e4lt sich virtiofs wie ein lokales Dateisystem \u2013 schnell, zuverl\u00e4ssig und ohne Netzwerkabh\u00e4ngigkeiten.<\/p>\n<hr \/>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-2821 alignleft\" src=\"https:\/\/speefak.spdns.de\/oss_lifestyle\/wp-content\/uploads\/2014\/08\/CC_BY_NC_SA.png\" alt=\"CC_BY_NC_SA\" width=\"65\" height=\"23\" \/>by Speefak<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Virtiofs ist eine moderne und performante Methode, um Verzeichnisse direkt vom Proxmox-Host in virtuelle Maschinen einzubinden. Im Gegensatz zu klassischen Netzwerkdateisystemen wie NFS oder SSHFS erfolgt der Zugriff lokal \u00fcber den Hypervisor, ohne Netzwerk-Stack und ohne zus\u00e4tzliche Dienste. Dadurch eignet sich virtiofs besonders f\u00fcr High-Performance-Dateifreigaben zwischen Host und VM,\u00a0in denen hoher Datendurchsatz, geringe Latenz und [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,99,46],"tags":[],"class_list":["post-8594","post","type-post","status-publish","format-standard","hentry","category-allgemein","category-proxmox-ve","category-virtualisierung"],"rttpg_featured_image_url":null,"rttpg_author":{"display_name":"speefak","author_link":"https:\/\/speefak.spdns.de\/oss_lifestyle\/author\/speefak_oss\/"},"rttpg_comment":0,"rttpg_category":"<a href=\"https:\/\/speefak.spdns.de\/oss_lifestyle\/category\/allgemein\/\" rel=\"category tag\">Allgemein<\/a> <a href=\"https:\/\/speefak.spdns.de\/oss_lifestyle\/category\/proxmox-ve\/\" rel=\"category tag\">Proxmox VE<\/a> <a href=\"https:\/\/speefak.spdns.de\/oss_lifestyle\/category\/virtualisierung\/\" rel=\"category tag\">Virtualisierung<\/a>","rttpg_excerpt":"Virtiofs ist eine moderne und performante Methode, um Verzeichnisse direkt vom Proxmox-Host in virtuelle Maschinen einzubinden. Im Gegensatz zu klassischen Netzwerkdateisystemen wie NFS oder SSHFS erfolgt der Zugriff lokal \u00fcber den Hypervisor, ohne Netzwerk-Stack und ohne zus\u00e4tzliche Dienste. Dadurch eignet sich virtiofs besonders f\u00fcr High-Performance-Dateifreigaben zwischen Host und VM,\u00a0in denen hoher Datendurchsatz, geringe Latenz und&hellip;","_links":{"self":[{"href":"https:\/\/speefak.spdns.de\/oss_lifestyle\/wp-json\/wp\/v2\/posts\/8594","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/speefak.spdns.de\/oss_lifestyle\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/speefak.spdns.de\/oss_lifestyle\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/speefak.spdns.de\/oss_lifestyle\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/speefak.spdns.de\/oss_lifestyle\/wp-json\/wp\/v2\/comments?post=8594"}],"version-history":[{"count":0,"href":"https:\/\/speefak.spdns.de\/oss_lifestyle\/wp-json\/wp\/v2\/posts\/8594\/revisions"}],"wp:attachment":[{"href":"https:\/\/speefak.spdns.de\/oss_lifestyle\/wp-json\/wp\/v2\/media?parent=8594"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/speefak.spdns.de\/oss_lifestyle\/wp-json\/wp\/v2\/categories?post=8594"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/speefak.spdns.de\/oss_lifestyle\/wp-json\/wp\/v2\/tags?post=8594"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}