Руководство по директориям бинарных файлов Linux: Полный технический справочник
Бинарные директории Linux — это стандартизированные расположения в файловой системе, где находятся исполняемые программы, инструменты системного администрирования и разделяемые библиотеки. Стандарт иерархии файловой системы (FHS) определяет эти пути для обеспечения единообразного размещения программного обеспечения в различных дистрибутивах, что позволяет предсказуемо разрешать `PATH`, управлять пакетами и надёжно восстанавливать систему — даже когда несущественные файловые системы недоступны.
Для любого администратора, управляющего средой VPS Хостинга или физическим сервером, точное знание того, какой бинарный файл где находится — и почему — является обязательным. Это напрямую влияет на поведение при загрузке, разделение привилегий, стратегию развёртывания программного обеспечения и усиление безопасности.
Почему важна структура бинарных директорий
Прежде чем перейти к отдельным директориям, стоит понять архитектурную логику, лежащую в основе их разделения. FHS делит файловую систему на два фундаментальных измерения:
- Существенные и несущественные: Бинарные файлы, необходимые для однопользовательского режима и аварийного восстановления, должны быть доступны до монтирования `/usr`. Всё остальное может находиться в `/usr`.
- Системный и пользовательский уровень: Бинарные файлы, предназначенные для администрирования на уровне root, отделены от тех, что доступны непривилегированным пользователям, что обеспечивает более строгий контроль доступа через права доступа к файловой системе.
Эта философия проектирования предшествует современным системам инициализации, но остаётся крайне актуальной. Неправильно настроенный `PATH`, бинарный файл, помещённый не в ту директорию, или отсутствующая символическая ссылка на библиотеку могут незаметно нарушить последовательность загрузки, задания cron или скрипты запуска служб.
Основные бинарные директории: краткий обзор
| Директория | Назначение | Требует root? | Доступна до монтирования `/usr`? | Управляется |
|---|
| — | — | — | — | — |
|---|
| `/bin` | Основные пользовательские бинарные файлы | Нет | Да (или символическая ссылка) | Менеджером пакетов |
|---|
| `/sbin` | Основные системные бинарные файлы | Да | Да (или символическая ссылка) | Менеджером пакетов |
|---|
| `/usr/bin` | Стандартные пользовательские бинарные файлы | Нет | Нет | Менеджером пакетов |
|---|
| `/usr/sbin` | Несущественные системные бинарные файлы | Да | Нет | Менеджером пакетов |
|---|
| `/usr/local/bin` | Локально установленные пользовательские бинарные файлы | Нет | Нет | Администратором |
|---|
| `/usr/local/sbin` | Локально установленные системные бинарные файлы | Да | Нет | Администратором |
|---|
| `/opt` | Самодостаточное стороннее программное обеспечение | Зависит от ситуации | Нет | Вендором/Администратором |
|---|
| `/lib`, `/usr/lib` | Разделяемые библиотеки | Н/П | Зависит от ситуации | Менеджером пакетов |
|---|
/bin — Основные пользовательские бинарные файлы
`/bin` содержит минимальный набор исполняемых файлов, необходимых для загрузки системы и выполнения пользователем базовых операций в однопользовательском режиме или режиме восстановления. Эти бинарные файлы должны быть доступны даже тогда, когда смонтирована только корневая файловая система.
Типичные примеры: `ls`, `cp`, `mv`, `cat`, `bash`, `echo`, `grep`, `chmod`, `ln`, `mkdir`, `rm`, `ps`
Важная техническая деталь: В дистрибутивах на основе systemd — включая Debian 10+, Ubuntu 20.04+, Fedora, Arch Linux и RHEL 8+ — `/bin` теперь является символической ссылкой, указывающей на `/usr/bin`. Это часть инициативы UsrMerge, которая объединяет бинарные директории корневого уровня с их аналогами в `/usr` для упрощения проектирования initramfs и обеспечения атомарных обновлений ОС. Вы можете проверить это на любой объединённой системе:
“`bash
ls -la /bin
lrwxrwxrwx 1 root root 7 /bin -> usr/bin
“`
Практическое следствие: Если вы пишете shell-скрипты, предназначенные для запуска в среде восстановления или на ранних этапах загрузки (например, скрипты initramfs), никогда не предполагайте, что `/usr/bin` доступен. Всегда используйте `/bin/sh` в качестве shebang и ссылайтесь только на утилиты, предусмотренные стандартом POSIX.
/sbin — Основные системные бинарные файлы
`/sbin` содержит бинарные файлы, зарезервированные для задач системного администрирования, которые должны выполняться во время загрузки и операций восстановления файловой системы, до того как станет доступно полное дерево файловой системы.
Типичные примеры: `fsck`, `ifconfig`, `ip`, `reboot`, `shutdown`, `mkfs`, `mount`, `umount`, `fdisk`, `modprobe`, `init`
Нюанс привилегий: Хотя бинарные файлы в `/sbin` *предназначены* для использования root, на большинстве дистрибутивов они доступны для выполнения всем пользователям. Ограничение обеспечивается самими операциями — `fsck` требует прямого доступа к устройству, `mount` требует `CAP_SYS_ADMIN` — а не битом выполнения бинарного файла. Это распространённый источник путаницы при проведении аудитов безопасности.
Современный статус: Как и `/bin`, на системах с объединённым usr `/sbin` является символической ссылкой на `/usr/sbin`. Различие между `/sbin` и `/bin` теперь носит преимущественно семантический и исторический, а не структурный характер.
/usr/bin — Основной репозиторий пользовательских бинарных файлов
`/usr/bin` — это наибольшая и наиболее часто используемая бинарная директория в типичной установке Linux. Она содержит все стандартные пользовательские утилиты командной строки и приложения, установленные через системный менеджер пакетов, которые не требуются для аварийных операций.
Типичные примеры: `vim`, `nano`, `git`, `python3`, `perl`, `gcc`, `curl`, `wget`, `ssh`, `tar`, `gzip`, `awk`, `sed`, `find`
Масштаб на практике: При минимальной установке сервера Debian `/usr/bin` может содержать 200–400 бинарных файлов. При полной установке среды рабочего стола это число может превысить 2 000. Эта директория всегда присутствует в стандартном `PATH` для всех пользователей.
Управление менеджером пакетов: Каждый файл здесь отслеживается `dpkg`, `rpm` или эквивалентом вашего дистрибутива. Размещение файлов вручную в `/usr/bin` настоятельно не рекомендуется — обновления пакетов могут незаметно перезаписать их без предупреждения.
/usr/sbin — Несущественные бинарные файлы системного администрирования
`/usr/sbin` содержит инструменты системного администрирования, которые не требуются в процессе загрузки или при восстановлении в однопользовательском режиме, но необходимы для повседневного управления сервером.
Типичные примеры: `apache2`, `nginx`, `sshd`, `useradd`, `userdel`, `usermod`, `groupadd`, `iptables`, `nftables`, `cron`, `logrotate`, `tcpdump`
Архитектурный аспект: Разделение `/sbin` и `/usr/sbin` изначально было разработано для того, чтобы системный администратор мог загрузиться в однопользовательский режим и выполнить восстановление без необходимости монтировать `/usr`. На практике в современных системах с initramfs и ранним пространством пользователя это различие в значительной мере утратило смысл. Однако его понимание остаётся важным при работе со старыми системами RHEL 6/CentOS 6 или встроенными средами Linux, где `/usr` может действительно являться отдельным разделом.
/usr/local/bin — Пользовательские бинарные файлы, установленные администратором
`/usr/local/bin` — это правильное расположение для бинарных файлов, установленных вручную — в обход системного менеджера пакетов — и которые должны быть доступны всем пользователям системы.
Типичные варианты использования:
- Программное обеспечение, скомпилированное из исходного кода (например, пользовательская сборка `nginx` с нестандартными модулями)
- Python-скрипты, установленные через `pip install –prefix=/usr/local`
- Сторонние CLI-инструменты, распространяемые как автономные бинарные файлы (например, `kubectl`, `helm`, `terraform`, `hugo`)
- Пользовательские скрипты автоматизации, которые должны быть доступны на уровне всей системы
Приоритет в PATH: В стандартной FHS-совместимой системе `/usr/local/bin` появляется *раньше* `/usr/bin` в стандартном `PATH`. Это означает, что бинарный файл, помещённый сюда, будет перекрывать одноимённый бинарный файл, управляемый менеджером пакетов. Это сделано намеренно — чтобы локальные настройки могли переопределять значения по умолчанию дистрибутива — однако это также частый источник незаметных ошибок при расхождении версий.
“`bash
echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
“`
Соображения безопасности: Поскольку `/usr/local/bin` не проверяется менеджером пакетов, бинарные файлы, помещённые сюда, не получают автоматических обновлений безопасности. На серверах с производственными нагрузками — включая те, что работают на Выделенных серверах — установите регулярный цикл обновления вручную или используйте инструмент управления конфигурацией (Ansible, Puppet, Chef) для отслеживания и обновления этих бинарных файлов.
/usr/local/sbin — Системные бинарные файлы, установленные администратором
`/usr/local/sbin` отражает взаимосвязь между `/sbin` и `/bin`, но на локальном уровне. Это правильное расположение для вручную установленных инструментов системного администрирования, требующих повышенных привилегий или предназначенных только для root.
Типичные варианты использования:
- Пользовательские скрипты резервного копирования, запускаемые от имени root через cron
- Вручную скомпилированные агенты мониторинга (например, пользовательская сборка `node_exporter`)
- Административные скрипты-обёртки, вызывающие привилегированные системные вызовы
- Утилиты управления от вендора, поставляемые в виде архивов tar, а не пакетов
Операционная дисциплина: Ведите файл `README` или инвентарный файл в `/usr/local/sbin`, документируя происхождение, версию и процедуру обновления каждого бинарного файла. На общей инфраструктуре недокументированные бинарные файлы в этой директории представляют угрозу безопасности и затрудняют аудит.
/opt — Самодостаточные сторонние приложения
`/opt` предназначен для программных пакетов, не соответствующих структуре директорий FHS — как правило, коммерческих или проприетарных приложений, крупных программных пакетов от вендоров и приложений, включающих собственные библиотеки во избежание конфликтов зависимостей.
Типичные примеры:
- `/opt/google/chrome/` — браузер Google Chrome
- `/opt/lampp/` — стек XAMPP
- `/opt/pycharm/` — IDE JetBrains PyCharm
- `/opt/gitlab/` — установка Omnibus GitLab
- `/opt/aws/` — AWS CLI v2 и SSM Agent
Структурное соглашение: Каждое приложение в `/opt` должно занимать собственную поддиректорию по шаблону `/opt/<provider>/` или `/opt/<package>/`. Бинарные файлы приложения обычно находятся в `/opt/<package>/bin/`, и от вендора ожидается установка символической ссылки в `/usr/local/bin` или изменение `/etc/profile.d/` для добавления этого пути.
Когда использовать `/opt` вместо `/usr/local`: Используйте `/opt`, когда программное обеспечение поставляется как самодостаточный пакет с собственными библиотеками, конфигурацией и директориями данных. Используйте `/usr/local/bin` для однофайловых инструментов или скриптов, которые корректно интегрируются с существующим стеком системных библиотек.
Реальный пограничный случай: GitLab Omnibus устанавливается полностью в `/opt/gitlab/` и управляет собственными экземплярами PostgreSQL, Redis и Nginx. Такая изоляция намеренна — она предотвращает конфликты версий с системными службами. Однако это также означает, что системные инструменты мониторинга не будут автоматически обнаруживать эти процессы, если они явно не настроены на поиск в `/opt`.
/lib, /usr/lib, /lib64 и /usr/lib64 — Разделяемые библиотеки
Эти директории содержат файлы разделяемых объектов (файлы `.so`), от которых зависят бинарные файлы в соответствующих бинарных директориях во время выполнения. Они не являются исполняемыми в традиционном смысле, но загружаются в память процесса динамическим компоновщиком (`ld-linux.so`).
Ключевые директории и их роли:
- `/lib` — Разделяемые библиотеки, необходимые бинарным файлам в `/bin` и `/sbin`. На системах с объединённым usr — символическая ссылка на `/usr/lib`.
- `/usr/lib` — Основной репозиторий всех системных разделяемых библиотек. Здесь находятся библиотеки, управляемые менеджером пакетов.
- `/lib64` — 64-битный вариант `/lib` на системах с поддержкой multilib (распространено на x86_64 RHEL/CentOS). Часто является символической ссылкой на `/usr/lib64`.
- `/usr/lib64` — 64-битные разделяемые библиотеки в дистрибутивах на основе RPM.
- `/usr/local/lib` — Библиотеки, установленные вместе с вручную скомпилированным программным обеспечением.
- `/usr/lib/x86_64-linux-gnu/` — Путь к библиотекам multiarch в Debian/Ubuntu, позволяющий 32-битным и 64-битным библиотекам сосуществовать.
Механика компоновщика времени выполнения: При запуске бинарного файла ядро передаёт управление динамическому компоновщику, указанному в заголовке ELF (обычно `/lib64/ld-linux-x86-64.so.2`). Компоновщик разрешает зависимости разделяемых библиотек с помощью кэша, построенного `ldconfig`, который читает `/etc/ld.so.conf` и его включаемую директорию. Если библиотека установлена, но `ldconfig` не был запущен, бинарный файл завершится с ошибкой «shared library not found», даже если файл существует.
“`bash
After installing a library to /usr/local/lib, always run:
ldconfig
Verify library resolution for a specific binary:
ldd /usr/bin/curl
“`
Распространённая ошибка: Установка пользовательской скомпилированной библиотеки в `/usr/local/lib` без последующего запуска `ldconfig` — одна из наиболее частых причин ошибок «cannot open shared object file» на серверах Linux. Это особенно распространено при сборке программного обеспечения из исходного кода на VPS с cPanel или аналогичных управляемых средах, где процесс сборки может не иметь доступа root для запуска `ldconfig`.
UsrMerge: современная консолидация файловой системы
Инициатива UsrMerge (или `usr-merge`) заслуживает отдельного внимания, поскольку она фундаментально меняет ментальную модель, которую многие администраторы сохранили со времён старых систем.
Проблема, которую она решает: Исторически `/bin`, `/sbin`, `/lib` и `/lib64` существовали как независимые директории в корневой файловой системе, отдельно от `/usr`. Это требовало, чтобы initramfs содержал минимальный набор инструментов для монтирования `/usr` до полной инициализации системы. По мере того как initramfs стал универсальным, а `/usr` начал рассматриваться как том только для чтения, потенциально монтируемый по сети или управляемый через снимки, такое разделение стало препятствием для атомарных обновлений и развёртываний на основе образов.
Что изменилось: На объединённых системах директории корневого уровня становятся символическими ссылками:
“`
/bin -> usr/bin
/sbin -> usr/sbin
/lib -> usr/lib
/lib64 -> usr/lib64
“`
Дистрибутивы, завершившие UsrMerge:
- Fedora (начиная с Fedora 17, 2012 г.)
- Arch Linux (начиная с 2013 г.)
- Debian (начиная с Debian 12 Bookworm, 2023 г.)
- Ubuntu (начиная с Ubuntu 21.10)
- RHEL/CentOS (начиная с RHEL 7)
Практическое влияние: Скрипты с жёстко заданным `/bin/bash` по-прежнему работают, поскольку `/bin` является символической ссылкой на `/usr/bin`. Однако скрипты, пытающиеся определить, является ли путь «существенным», проверяя, начинается ли он с `/bin`, а не с `/usr/bin`, будут давать неверные результаты. Обновите соответствующую логику в своих инструментах автоматизации.
Права доступа к бинарным директориям и усиление безопасности
Понимание бинарных директорий неотделимо от понимания их последствий для безопасности. Ряд мер по усилению защиты непосредственно касается этих путей.
Рекомендуемые базовые права доступа:
| Директория | Владелец | Группа | Права доступа |
|---|
| — | — | — | — |
|---|
| `/usr/bin` | root | root | `755` |
|---|
| `/usr/sbin` | root | root | `755` |
|---|
| `/usr/local/bin` | root | root | `755` |
|---|
| `/usr/local/sbin` | root | root | `750` или `755` |
|---|
| `/opt/<package>` | root | root | `755` |
|---|
Бинарные файлы SUID/SGID: Некоторые бинарные файлы в `/usr/bin` и `/usr/sbin` имеют установленный бит SUID, позволяющий им выполняться с повышенными привилегиями независимо от того, кто их вызывает. Примеры включают `passwd`, `sudo`, `su` и `ping`. Регулярно проводите их аудит:
“`bash
find /usr/bin /usr/sbin /bin /sbin -perm /4000 -o -perm /2000 2>/dev/null
“`
Неизменяемые флаги: На системах с высоким уровнем безопасности рассмотрите возможность применения `chattr +i` к критически важным бинарным файлам или монтирования `/usr` в режиме только для чтения. Это предотвращает изменение во время выполнения вредоносным программным обеспечением или скомпрометированным процессом, хотя для легитимных обновлений пакетов потребуется перемонтирование в режиме чтения-записи.
Параметр монтирования `noexec`: Монтирование `/tmp` и `/var/tmp` с параметром `noexec` предотвращает прямое выполнение бинарных файлов, помещённых туда, — распространённый приём в атаках с использованием веб-шеллов. Это не затрагивает сами бинарные директории, но является дополнительной мерой защиты, актуальной для любого сервера с веб-приложениями, включая те, что используют среды Виртуального веб-хостинга.
Переменная окружения PATH и порядок разрешения бинарных файлов
Переменная `PATH` определяет порядок, в котором оболочка ищет исполняемые файлы в директориях. Понимание этого порядка необходимо для отладки ошибок «command not found» и для намеренного перекрытия бинарных файлов.
Типичный PATH для root в системе Debian/Ubuntu:
“`
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
“`
Типичный PATH для непривилегированного пользователя:
“`
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
“`
Ключевые наблюдения:
- `/usr/local/bin` предшествует `/usr/bin`, поэтому локально установленные бинарные файлы перекрывают управляемые менеджером пакетов.
- `/sbin` и `/usr/sbin` отсутствуют в стандартном PATH непривилегированного пользователя в некоторых дистрибутивах, поэтому запуск `ifconfig` от имени не-root пользователя может завершиться ошибкой «command not found», даже если бинарный файл существует.
- Когда служба запускается под учётной записью не-root пользователя (например, пользователь веб-приложения), её PATH может быть ещё более ограниченным. Всегда используйте абсолютные пути в файлах юнитов служб и заданиях cron.
Отладка проблем с PATH:
“`bash
Find all instances of a binary across PATH directories:
which -a python3
Show full PATH resolution including aliases and functions:
type -a python3
Check the effective PATH for a specific service:
systemctl show myservice | grep -i environment
“`
Практическая матрица решений: куда установить бинарный файл
При развёртывании программного обеспечения на сервере Linux — будь то скомпилированный инструмент, загруженный бинарный файл или пользовательский скрипт — используйте следующую схему принятия решений:
Управляется ли оно системным менеджером пакетов?
- Да: менеджер пакетов автоматически помещает его в `/usr/bin` или `/usr/sbin`. Не перемещайте его.
Это отдельный бинарный файл или скрипт, установленный вручную и предназначенный для всех пользователей?
- Инструмент для пользователей: `/usr/local/bin`
- Инструмент для root/администратора: `/usr/local/sbin`
Это самодостаточный пакет приложения с собственными зависимостями?
- Используйте `/opt/<vendor>/<package>/` и создайте символическую ссылку на основной бинарный файл в `/usr/local/bin`
Это временный или пользовательский инструмент?
- Поместите его в `~/bin` (создайте при отсутствии) и добавьте `~/bin` в личный `PATH` в `~/.bashrc` или `~/.profile`
Это разделяемая библиотека для вручную скомпилированного приложения?
- Установите в `/usr/local/lib`, затем запустите `ldconfig`
Эта схема предотвращает наиболее распространённую форму энтропии файловой системы на долго работающих серверах: бинарные файлы, разбросанные по произвольным расположениям, невидимые для менеджера пакетов и забытые установившим их администратором.
Контрольный список ключевых технических выводов
- Проверьте статус UsrMerge в вашей системе с помощью `ls -la /bin /sbin /lib`. Если они являются символическими ссылками, `/bin` и `/usr/bin` — это одно и то же пространство имён.
- Никогда не помещайте файлы непосредственно в `/usr/bin` или `/usr/sbin` — обновления пакетов перезапишут их без предупреждения.
- Всегда запускайте `ldconfig` после установки разделяемых библиотек в `/usr/local/lib` или любой нестандартный путь.
- Используйте абсолютные пути в заданиях cron, файлах юнитов systemd и скриптах инициализации — никогда не полагайтесь на корректную установку `PATH` в неинтерактивных контекстах.
- Ежеквартально проводите аудит бинарных файлов SUID/SGID на производственных серверах: `find /usr /bin /sbin -perm /6000 -type f`
- Документируйте каждый бинарный файл, установленный в `/usr/local/` и `/opt/`, с указанием версии, URL источника и даты установки в системе управления конфигурацией или как минимум в локальном журнале изменений.
- На системах с объединённым usr обновите любую автоматизацию, различающую «существенные» бинарные файлы по префиксу пути — это различие теперь носит исключительно семантический характер.
- При развёртывании приложений на Панелях управления VPS или в управляемых хостинговых средах убедитесь, изменяет ли панель управления `PATH` или устанавливает собственные версии бинарных файлов в `/opt` или `/usr/local`, поскольку это может вызвать конфликты версий с системными инструментами.
- Для инструментов, связанных с SSL (`openssl`, `certbot`), убедитесь, какая версия бинарного файла вызывается — устаревшая вручную установленная версия в `/usr/local/bin` будет перекрывать управляемую менеджером пакетов и может содержать неисправленные уязвимости. Дополните это надлежащим управлением SSL-сертификатами, чтобы обеспечить актуальность всей криптографической цепочки инструментов.
Часто задаваемые вопросы
В чём разница между `/bin` и `/usr/bin` в современном Linux?
В современных дистрибутивах, завершивших UsrMerge, функциональной разницы нет — `/bin` является символической ссылкой на `/usr/bin`. Исторически `/bin` содержал только бинарные файлы, необходимые до монтирования `/usr`, тогда как `/usr/bin` содержал всё остальное. На объединённых системах это различие носит семантический характер, но остаётся архитектурно значимым на старых или встроенных установках Linux.
Почему размещение бинарного файла в `/usr/local/bin` перекрывает одноимённый бинарный файл в `/usr/bin`?
Потому что `/usr/local/bin` появляется раньше в стандартном `PATH`, чем `/usr/bin`. Оболочка разрешает команды, последовательно просматривая директории `PATH` слева направо и выполняя первое найденное совпадение. Такой порядок намеренен — он позволяет администраторам развёртывать локальные переопределения без изменения файлов, управляемых менеджером пакетов.
Что произойдёт, если я забуду запустить `ldconfig` после установки разделяемой библиотеки?
Кэш динамического компоновщика (`/etc/ld.so.cache`) не будет включать новую библиотеку, и любой зависящий от неё бинарный файл завершится с ошибкой во время выполнения, например `error while loading shared libraries: libfoo.so.1: cannot open shared object file: No such file or directory`. Запуск `sudo ldconfig` перестраивает кэш и немедленно устраняет проблему.
Безопасно ли устанавливать программное обеспечение непосредственно в `/usr/bin` вместо `/usr/local/bin`?
Нет. Файлы в `/usr/bin` принадлежат менеджеру пакетов и отслеживаются им. Будущее обновление пакета или системное обновление может перезаписать, переместить или удалить любой файл в этой директории без предупреждения. Всегда используйте `/usr/local/bin` для бинарных файлов, установленных вручную, чтобы поддерживать чёткое разделение между программным обеспечением, управляемым менеджером пакетов, и программным обеспечением, управляемым администратором.
Как узнать, из какой директории выполняется команда?
Используйте `which <command>` для быстрого поиска первого совпадения в `PATH`, или `type -a <command>` для вывода всех совпадений, включая встроенные команды оболочки, псевдонимы и все экземпляры во всех директориях `PATH`. Для однозначного ответа с разрешением символических ссылок используйте `readlink -f $(which <command>)`.
