Монтирование
Монтирование прививает файловую систему в единое дерево каталогов Linux по выбранному пути. Опции монтирования ro, noexec и nosuid добавляют ограничения безопасности. Bind mount открывает доступ к каталогу по второму пути. findmnt и /proc/mounts показывают смонтированное.
Windows назначает каждому диску букву: C:, D:, E:. Ты всегда знаешь, на каком физическом диске находишься. Linux делает противоположное: никаких букв дисков. Каждая файловая система — будь то NVMe-диск, USB-флешка, сетевая шара или RAM-диск — прикрепляется к единому дереву каталогов по пути, который ты сам выбираешь. /data, /mnt/usb, /home — всё это просто каталоги, к которым подключены дополнительные файловые системы.
Такой дизайн позволяет переносить файловые системы (менять расположение /home) без изменения ни одного приложения, читающего из /home. И означает, что нужно освоить ровно одну операцию: mount.
После этого урока ты сможешь монтировать и размонтировать файловую систему вручную, использовать опции монтирования для ограничений безопасности (ro, noexec, nosuid, relatime), создавать bind mount, просматривать все активные монтирования через findmnt и /proc/mounts, и диагностировать ошибку «device is busy» при umount.
mount прикрепляет файловую систему к дереву каталогов в точке монтирования. Точка монтирования — любой существующий каталог. После монтирования его содержимое выглядит как корень смонтированной файловой системы. Прежнее содержимое каталога скрыто (не удалено), пока монтирование активно.
# Базовое монтирование: подключить /dev/sdb1 в /mnt/data
sudo mount /dev/sdb1 /mnt/data
# Точка монтирования должна существовать заранее
sudo mkdir -p /mnt/data
# Проверить монтирование
mount | grep sdb1
# /dev/sdb1 on /mnt/data type ext4 (rw,relatime)
# Или более читаемо:
findmnt /mnt/data
# TARGET SOURCE FSTYPE OPTIONS
# /mnt/data /dev/sdb1 ext4 rw,relatime
# Просмотреть все монтирования в виде дерева
findmnt
# TARGET SOURCE FSTYPE OPTIONS
# / /dev/sda3 ext4 rw,relatime
# ├─/sys sysfs sysfs rw,nosuid,nodev,noexec
# ├─/proc proc proc rw,nosuid,nodev,noexec
# ├─/dev devtmpfs devtmpfs rw,nosuid
# ├─/boot /dev/sda2 ext4 rw,relatime
# ├─/boot/efi /dev/sda1 vfat rw,relatime
# └─/mnt/data /dev/sdb1 ext4 rw,relatimeЯдро хранит таблицу активных монтирований в /proc/mounts (и его псевдоним /etc/mtab на современных системах — это симлинк на него). Каждый вызов mount добавляет строку; каждый umount её удаляет.
Опции монтирования управляют поведением файловой системы. Передаются через -o. Несколько опций разделяются запятыми.
# Монтирование только для чтения (нельзя писать даже от root)
sudo mount -o ro /dev/sdb1 /mnt/data
# Монтирование с noexec (бинарники на этой ФС нельзя выполнять)
sudo mount -o noexec,nosuid /dev/sdc1 /mnt/uploads
# noexec: запрещает выполнение бинарников с этой ФС
# nosuid: игнорирует биты setuid/setgid (защита от повышения привилегий)
# Перемонтирование с другими опциями (без размонтирования)
sudo mount -o remount,rw /mnt/data
sudo mount -o remount,ro /mnt/data
# relatime vs noatime vs strictatime
# relatime: обновлять atime только если atime < mtime (по умолчанию с Linux 2.6.30)
# noatime: никогда не обновлять atime (лучшая производительность, часто для SSD и БД)
# strictatime: всегда обновлять atime при чтении (POSIX-корректно, но медленно)
sudo mount -o noatime /dev/sdb1 /mnt/data
# Типичные безопасные опции для ненадёжных данных (например, каталог загрузок):
sudo mount -o nosuid,nodev,noexec /dev/sdc1 /mnt/untrusted
# nodev: запрещает работу файлов устройств (символьных/блочных) на этой ФСОпции, указанные в findmnt или /proc/mounts, — именно то, что применяет ядро. Если /mnt/uploads смонтирован с noexec и кто-то загрузил shell-скрипт и запустил его, ядро вернёт EACCES. Это реальный рубеж безопасности.
# Посмотреть все опции для конкретного монтирования
cat /proc/mounts | grep '/mnt/data'
# /dev/sdb1 /mnt/data ext4 rw,relatime 0 0
# Поля: устройство, точка монтирования, тип ФС, опции, dump, passumount отсоединяет файловую систему от дерева. Файловая система не должна использоваться.
# Размонтировать по точке монтирования
sudo umount /mnt/data
# Размонтировать по устройству
sudo umount /dev/sdb1
# Классическая ошибка: "target is busy"
sudo umount /mnt/data
# umount: /mnt/data: target is busy.
# Найти, кто использует файловую систему
sudo lsof /mnt/data
# COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
# bash 4821 alice cwd DIR 8,17 4096 2 /mnt/data
# tail 5102 root 3r REG 8,17 102400 983 /mnt/data/app.log
# Процесс bash 4821 использует /mnt/data как текущий каталог
# Процесс tail 5102 держит открытый файловый дескриптор
# Также полезно:
sudo fuser -m /mnt/data
# /mnt/data: 4821 5102
# Исправление: покинуть каталог и завершить или дождаться процессов
cd /
sudo kill 5102 # если безопасно завершить
# Ленивое размонтирование (отсоединяет сразу, очищает когда упадёт последняя ссылка)
sudo umount -l /mnt/data # с осторожностью: новые открытия будут падать, старые fd работаютОшибка «device is busy» почти всегда возникает из-за процесса, у которого точка монтирования является текущим рабочим каталогом, или открытого файлового дескриптора внутри дерева. lsof и fuser раскрывают виновника.
Bind mount открывает существующий каталог по второму пути в дереве. Одно и то же дерево inode видно под двумя путями одновременно. Запись через любой путь затрагивает одни и те же данные.
# Bind mount /var/app/uploads в /srv/uploads (два пути, один каталог)
sudo mount --bind /var/app/uploads /srv/uploads
# Оба пути показывают одно содержимое
ls /var/app/uploads
# report.pdf data.csv
ls /srv/uploads
# report.pdf data.csv <- идентично
# Bind mount применяется для:
# 1. Открытия пути внутри chroot без дублирования данных
# 2. Предоставления каталога по пути, ожидаемому приложением
# 3. Перемонтирования с другими опциями (например, read-only вид rw-каталога)
# Read-only bind mount: открыть /var/app/uploads только для чтения в /srv/ro-uploads
sudo mount --bind /var/app/uploads /srv/ro-uploads
sudo mount -o remount,ro,bind /srv/ro-uploads
# Теперь /srv/ro-uploads только для чтения, хотя /var/app/uploads открыт на запись
# Bind mount виден в /proc/mounts
cat /proc/mounts | grep bind
# /var/app/uploads /srv/uploads ext4 rw,relatime,bind 0 0Среды выполнения контейнеров (Docker, podman) интенсивно используют bind mount — когда ты делаешь docker run -v /host/path:/container/path, это и есть bind mount хостового каталога в файловое пространство имён контейнера.
findmnt удобнее, чем разбор вывода mount или /proc/mounts вручную. Он понимает структуру дерева монтирований и поддерживает фильтрацию.
# Показать монтирования определённого типа ФС
findmnt -t ext4
# TARGET SOURCE FSTYPE OPTIONS
# / /dev/sda3 ext4 rw,relatime
# /boot /dev/sda2 ext4 rw,relatime
# /mnt/data /dev/sdb1 ext4 rw,relatime
# Вывод в JSON (удобно для скриптов)
findmnt -J /mnt/data
# Проверить, является ли путь точкой монтирования (exit 0 = да, exit 1 = нет)
findmnt /mnt/data > /dev/null && echo "смонтировано" || echo "не смонтировано"
# В скриптах — проверить перед монтированием
if ! findmnt /mnt/data > /dev/null 2>&1; then
sudo mount /dev/sdb1 /mnt/data
fiНастройка безопасного каталога загрузок: nosuid, nodev, noexec смонтированный в /srv/uploads.
# Контекст: веб-сервер принимает загрузки от пользователей в /srv/uploads.
# Риск: атакующий загружает setuid-бинарник или файл устройства.
# Защита: монтировать раздел загрузок с nosuid,nodev,noexec.
# Шаг 1: выделенный раздел /dev/sdc1 для загрузок (уже отформатирован ext4)
sudo mkdir -p /srv/uploads
# Шаг 2: монтировать с опциями безопасности
sudo mount -o nosuid,nodev,noexec /dev/sdc1 /srv/uploads
# Шаг 3: убедиться, что опции применены
findmnt /srv/uploads
# TARGET SOURCE FSTYPE OPTIONS
# /srv/uploads /dev/sdc1 ext4 rw,nosuid,nodev,noexec,relatime
# Шаг 4: проверить, что exec действительно заблокирован
cp /bin/ls /srv/uploads/test-exec
/srv/uploads/test-exec
# -bash: /srv/uploads/test-exec: Permission denied <- ядро блокирует
# Шаг 5: проверить, что setuid подавлен
cp /usr/bin/passwd /srv/uploads/
sudo -u nobody /srv/uploads/passwd
# Процесс выполняется с UID nobody, а не root — nosuid подавил setuid
# Шаг 6: сделать постоянным в /etc/fstab (следующий урок)
# /dev/sdc1 /srv/uploads ext4 nosuid,nodev,noexec,relatime 0 2Этот паттерн — выделенный раздел с nosuid,nodev,noexec — стандартное усиление безопасности для любого каталога, принимающего ненадёжные данные. Он не мешает атакующему хранить вредоносные файлы, но не даёт запустить их напрямую или воспользоваться setuid-трюками на сервере загрузок.
▸Почему это работает
На macOS модель файловой системы схожа (единое дерево, точки монтирования), но пользовательский опыт отличается. macOS автоматически монтирует внешние тома в /Volumes/ИмяДиска при подключении. Нет /dev/sda — диски именуются /dev/disk0, /dev/disk1. Команды mount и umount существуют, но редко используются напрямую; diskutil mount и diskutil unmount — macOS-нативные аналоги. macOS использует APFS для SSD (со встроенной поддержкой снимков) и HFS+ для HDD. Опции монтирования noexec и nosuid поддерживаются, но менее востребованы, так как Gatekeeper и SIP (System Integrity Protection) обеспечивают перекрывающиеся механизмы защиты.
▸Частая ошибка
Тонкая ловушка: если ты сделал cd /mnt/data в терминале, а затем запустил umount /mnt/data из того же терминала, umount упадёт с «target is busy» — потому что твой shell-процесс использует точку монтирования как текущий рабочий каталог, даже если у тебя нет открытых файлов. Исправление: всегда делай cd / (или любой путь за пределами монтирования) перед размонтированием. Ещё ловушка: umount принимает либо точку монтирования, либо устройство, но не оба — umount /dev/sdb1 /mnt/data является ошибкой.
Ты выполняешь 'sudo umount /mnt/data' и получаешь 'target is busy'. Какая команда покажет, какие процессы удерживают монтирование занятым?
Linux использует единое дерево каталогов — никаких букв дисков. mount прикрепляет файловую систему к этому дереву в любом существующем каталоге (точка монтирования). Опции монтирования (ro, noexec, nosuid, nodev, noatime) — ограничения безопасности и производительности, применяемые ядром. Bind mount (mount --bind) открывает существующий каталог по второму пути, с опционально другими опциями. umount отсоединяет файловую систему; падает с «target is busy», если процесс имеет открытый файл или cwd внутри монтирования — используй lsof или fuser -m для поиска виновника. findmnt даёт древовидный вид всех активных монтирований с опциями и удобнее, чем разбор /proc/mounts вручную. Активные монтирования живут в ядре и видны через /proc/mounts; они существуют до перезагрузки, если не зафиксированы в /etc/fstab.
Практика
Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.
Что-то непонятно?
Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.