Какое-то время назад на Хабре была небольшая волна постов на тему «Почему я [не] выбрал Linux». Как порядочный фанатик я стриггерился, однако решил, что продуктивнее что-нибудь рассказать о своей любимой системе, чем ломать копии в комментариях.
У меня сложилось впечатление, что многие пользователи GNU/Linux слабо представляют, из чего сделана эта операционная система, поэтому утверждают, что она сляпана из попавшихся под руку кусков. В то же время, архитектура большинства дистрибутивов является устоявшейся и регламентируется рядом стандартов, включая стандарт графического окружения freedesktop.org и Linux Standard Base, расширяющий стандарты Unix. Мне при знакомстве с GNU/Linux несколько лет назад для погружения не хватало простой анатомической карты типичного дистрибутива, поэтому я попробую рассказать об этом сам.
Загрузчик
Сеанс операционной системы начинается с загрузчика, как театр с вешалки. Дефолтным загрузчиком сегодня является GNU GRUB, известный так же как GRUB 2. По-прежнему доступна первая ветка, называемая теперь «GRUB Legacy». Другой загрузчик с давней историей — Syslinux.
Задача загрузчика — инициализировать ядро Linux. Для этого, в общем случае, нужно знать, где ядро лежит, и уметь прочитать это место (раздел Ext4, скажем). Ядру в помощь загрузчик обычно так же подтягивает начальный образ загрузки, о котором скажем позже. GRUB умеет много прочего, типа построения весьма сложных меню и чейнлоадинга других загрузчиков (Windows Boot Manager например). GRUB имеет конфигурационный синтаксис, отдалённо напоминающий шелл, и расширяется модулями.
GRUB велик и могуч, порой даже слишком, и встраиваемые системы часто используют компактный Das U-Boot.
Ядро
Могучий Linux («не оставляй нас, монолит!»). Ядро операционной системы, созданное, чтобы работать с POSIX-совместимыми окружениями. Обычно лежит в /boot/
и содержит в названии слово vmlinuz
, где «vm» напоминает нам о поддержке виртуальной памяти, а «z» указывает, что файл сжат.
В рамках одного дистрибутива может поддерживаться несколько вариантов ядра, например:
mainline («основное»);
LTS (с расширенной поддержкой);
rt (патченное для поддержки исполнения в режиме реального времени);
с различными патчами для повышения производительности или защищённости (zen, hardened etc);
libre (почищенное от проприетарных блобов ядро, ожидаемо поддерживающее мало оборудования).
совсем экзотичные варианты с не-Linux ядром типа Debian GNU/Hurd (с ядром GNU Hurd) и Debian GNU/kFreeBSD (с ядром FreeBSD соответственно). Это уже, конечно, не GNU/Linux.
Начальный образ загрузки
Начальный образ загрузки известен так же как initrd и initramfs. Представляет собой архив с образом файловой системы, развёртываемой в оперативную память в начале процесса загрузки. Несёт в себе различные драйверы и скрипты, позволяющие инициализировать оборудование и смонтировать файловые системы.
Содержимое начального образа загрузки зависит от версии ядра и потребностей пользователя (кто-то использует ZFS, а у кого-то корень зашифрован LUKS). Поэтому образ не поставляется в дистрибутивах. В дистрибутивах поставляются фреймворки для создания начальных образов по мере необходимости. Так, обычно создание свежего образа инициируется при обновлении ядра. Вот несколько популярных фреймворков:
initramfs-tools — детище Debian.
Dracut (произносится созвучно с сушёной кошкой) — в RHEL и производных (CentOS, Scientific Linux etc.). Наиболее гибкий и современный инструмент из перечисленных, если спросите меня.
mkinitcpio поставляется в Archlinux, хотя мейнтейнеры подумывают о Dracut, который уже включён в репозиторий и установочные образы.
make-initrd — свой путь у замечательного отечественного дистрибутива Alt Linux.
Тут же упомянем Plymouth, размещаемый в начальном образе. Это заставка (сплэш-скрин), позволяющая заменить вывод ядра при загрузке на произвольную анимированную картинку, например логотип дистрибутива, что принято в «дружелюбных к пользователю»™ дистрибутивах типа Ubuntu и Fedora.
Init
Система инициализации — это пастырь процессов. Она стартует раньше всех и имеет PID 1. Она определяет уровень запуска системы и жизненный цикл большинства служб. Независмо от того, что за система инициализации представлена, она предлагает исполняемые файлы /sbin/init
(или /usr/bin/init
, или в том же духе, ну вы поняли).
Холиварный элемент. Много лет с нами была Sysvinit, пришедшая из варианта ОС Unix System V. Sysvinit полагалась в огромной степени на скрипты инициализации. Служил этот инит, в общем, исправно, но постепенно некоторым инженерам стало мозолить глаза последовательное исполнение скриптов и собственно скрипты, известные в жарких спорах за свою распростёртость как «баш-портянки». В конце 00-ых-начале 10-ых как грибы после дождя расплодились альтернативные системы инициализации: OpenRC от Gentoo, Upstart от Canonical, Systemd от Red Hat за авторством Леннарта Поттеринга. В конце концов по причинам техническим и политическим всех сожрала Systemd. Её восхваляют и ненавидят. Восхваляют в основном за простой и лаконичный синтаксис служб. Так, скрипт запуска веб-сервера Apache для классического инита занимает 153 строки включая комментарии, а файл службы из пакета apache в Arch Linux — 15 строк. Недолюбливают в основном за то, что эта система инициализации подрабатывает ещё и резолвером, планировщиком, менеджером сети, менеджером монтирования и Бог весть ещё чем, попирая дзен Unix.
Командная оболочка
Командная оболочка, она же командный интерпретатор или просто шелл. Неискушённый пользователь скажет — «в гробу я этот шелл видал, можно в графическом режиме жить», и будет неправ, поскольку шелл прописан в стандарте POSIX и необходим для работоспособности системы. Есть понятие «оболочка входа» (login shell) — это первый процесс, запускамый при входе пользователя. Он подтягивает опции и переменные окружения из конфигурационных файлов, все последующие процессы запускаются в контексте этого шелла. Что будет запущено в качестве оболочки входа, определяется в /etc/passwd
.
Наиболее распространены сегодня следующие оболочки:
Bourne shell (sh) — «тот самый шелл», сложно найти дистрибутив без него.
Bourne again shell (bash) — принят по умолчанию в качестве пользователькой оболочки в большинстве GNU/Linux дистрибутивов и предлагает ряд удобств по сравнению с sh.
Debian Almquist shell (dash) — компактная облочка, совместимая с sh. Традиционно используется в Debian, где
/usr/bin/sh
на неё ссылается.Z shell (zsh) — похож на bash, но предлагает оригинальные фишечки для интерактивного ввода. Редко идёт из коробки, но обычно поставляется в репозитории.
BusyBox — утилита для встраиваемых систем, которая предоставляет целое пользовательское окружение, в том числе — POSIX-совместимый шелл (вызывается так:
$ busybox sh
).
Графический сервер
Демон, отвечающий за отрисовку окошек. Золотой стандарт графического сервера — X Window System с нами аж с 1984 года. Это именно стандарт, архитектура и набор протоколов. Реализаций за прошедшие годы была уйма, в каждой собственнической Unix-системе была своя. В GNU/Linux (и BSD) долгое время применялся Xfree86. Теперь с нами X.Org Server, или просто Xorg, он отпочковался от XFree86.
X Window System — мощная и богатая система, так, одна из возможностей — сетевая прозрачность. Вы можете запустить на своём хосте графическое приложение с другой машины, даже когда на той машине графический сервер не запущен. При помощи SSH это можно сделать, например, так (может потребоваться небольшая донастройка sshd):
$ ssh -X hostname firefox
Надо сказать, терминология X Window System контринтуитивна: клиентом называется графическое приложение, а сервером — отрисовывающее. На этот счёт прошлись в классической монографии «The UNIX-HATERS Handbook».
Другая возможность X, отрисовка графических примитивов и текстовых глифов, использовалась в старые времена, когда мужчины были мужчинами и рисовали окошки сами, без тулкитов.
В окружениях рабочих столов активно используется X keyboard extension, расширение, отображающее нажатие клавиш на различные раскладки.
«Иксам» пророчат скорую кончину. Именно обширность и сложность стандарта побудила разработчиков СПО начать работу над новым стандартом — протоколом Wayland. Wayland достиг определённой стадии зрелости и с переменным успехом внедряется дистрибутивами как графический сервер по умолчанию. Тем не менее, проект Wayland начат в 2008 году, а стандарт X ещё не спешит уходить с голубых экранов.
На скриншоте Weston — эталонная реализация композитного менеджера Wayland. Умеет крутить окошки. А ещё его можно запустить внутри другого рабочего стола, просто выполнив в терминале weston
.
После старта графический сервер обслуживает иерархию окон. Существует понятие «корневое окно» (root window), оно, в свою очередь, «владеет» окнами панелей, приложений. Окна приложений «владеют» своими модальными окнами. Обычно обои рабочего стола отрисовываются в корневом окне.
Дисплейный менеджер
Не вполне интуитивно названные, дисплейные менеджеры (DM) рисуют для нас приветливое окошко входа в систему. Обычно, помимо ввода логина и пароля, они позволяют выбрать сессию (при наличии выбора в вашей системе) и задать язык сеанса. Дисплейные менеджеры делают плюс-минус одну и ту же нехитрую работу, их многообразие оправдано консистентностью с различными средами рабочего стола (что зависит, по большей части, от графического тулкита и утилит настройки). Можно жить без дисплейного сервера, как в старые добрые времена. Для этого потребуется настроить ваш ~/.xinitrc
на запуск необходимого сеанса рабочего стола. Это позволит входить через ядерную консоль и запускать рабочий стол командой startx
.
Типичные представители дисплейных менеджеров:
GDM из набора GNOME;
SDDM из комплекта KDE;
LightDM — универсальный вариант;
FlyDM — из поставки Astra Linux.
Окружение рабочего стола
Окружения рабочего стола (DE) состоит из ряда стандартных компонентов, таких, как:
диспетчер окон;
файловый менеджер;
панель с треем и меню запуска приложений;
эмулятор терминала;
хранитель экрана, он же блокировщик экрана;
менеджер питания;
браузер, которым никто не пользуется;
почтовый клиент (у зажиточных окружений);
и проч., и проч.
Два могучих окружения, GNOME и KDE, сражаются за сердца простых пользователей, а остальные массовые десктопы им завидуют нередко пользуются их наработками. Некоторые хардкорные пользователи предпочитают собирать окружение рабочего стола самостоятельно на базе оконных менеджеров типа Awesome и i3.
На скриншоте оконный менеджер Window Maker из состава GNUstep. GNUstep воспроизводит окружение NeXTSTEP. Поставляется в репозиториях большинства дистрибутивов.
Графические тулкиты
Графический тулкит — библиотека или фреймворк, упрощающая рисование формочек и кнопочек, причём в едином стиле. То, чем занимается Windows Forms на ОС другого производителя, а так же занимался некогда полулярный Motif на старых юниксах (Open Motif доступен поныне).
Флагманами в этой категории долгое время были и остаются GTK и Qt. GTK родился как тулкит для свободного графического редактора GIMP и позже переполз под крыло GNOME. Написан на чистом C с классами, имеет официальные байндинги к Python и C++, а ещё породил целый язык общего назначения Vala. Qt — изначально коммерческий проприетарный тулкит, сейчас является свободным ПО (но по-прежнему коммерческим). Написан на C++ с размахом, заменяя стандартную библиотеку и кучу других библиотек и предлагая метаобъектный компилятор (кодогенератор). Имеет байндинги к куче языков. KDE гордо зиждется на этом великолепии.
Графическое API
Mesa — это каркас для видеовывода. Меза предоставляет API OpenGL и, с не столь давних пор, Vulkan (и несколько других API типа VDPAU и VAAPI). Можно сказать, что Mesa берёт на себя вопросы графики, которыми обычно занимается DirectX в ОС другого производителя.
Безопасность
Обширная часть системы, и я недостаточно компетентен, чтобы в неё углубляться, тем не менее, обзорно рассмотрим.
PAM — Pluggable Authentication Modules — модульная система авторизации. Отвечает, как понятно из названия, за авторизацию пользователей в системе, причём разными способами. Через PAM авторизуются в том числе доменные пользователи, в таком случае PAM действует в связке с имплементацией Kerberos (обычно MIT'овский krb5), поскольку сам по себе PAM не работает с удалёнными клиентами. Модули представляют собой разделяемые библиотеки (исполняемые файлы с суффиксом so
) и позволяют делать интересные штуки при входе пользователя. Например, можно создавать домашнюю директорию при первом входе (pam_mkhomedir.so
) или монтировать файловые системы (pam_mount.so
).
Классическая утилита su и более молодая sudo предназначены для исполнения комманд от имени другого пользователя (по умолчанию root
). Наиболее значимая разница — su требует пароль пользователя, из-под которого вы хотите работать, а sudo — ваш пароль. sudo гибко настраивается, позволяя запускать только определённые команды определённым пользователям из-под других определённых пользователей, как-то так.
Менеджер авторизации Polkit позволяет непривилегированным процессам взаимодействовать с привилегированными. По сути он похож на sudo, но обладает превосходящей гибкостью и предназначен в первую очередь для приложений, в то время как sudo — утилита для пользователя. Правила пишутся, внезапно, на JavaScript'е.
Linux Security Modules (LSM) — фреймворк внутри ядра Linux, позволяющий накладывать на систему дополнительные моде́ли безопасности. Это достигается при помощи мо́дулей безопасности, не путать с модулями ядра. Наиболее популярные модули безопасности — SELinux и AppArmor. Первый явлен миру АНБ и развивается Red Hat, второй рождён в рамках ОС Immunix и сегодня развивается Canonical Ltd. Соответственно, SELinux поставляется в RHEL и производных, а AppArmor — в Ubuntu. Оба модуля имеют сходное назначение и привносят в систему мандатное управление доступом. Оба модуля повышают безопасность системы, не позволяя приложениям делать то, что от них не ожидается. Так, сконфигурированные модули безопасности не дадут веб-серверу шариться по диску вне нескольких ожидаемых директорий. Обратной стороной является необходимость конфигурировать систему безопасности для каждого мало-мальски нестандартно настроенного приложения. Не у многих на это хватает энтузиазма, так что обычно модуль безопасности просто переключается в разрешающий режим.
Антивирусные программы для GNU/Linux существуют, но мне не встречались дистрибутивы, где бы они шли из коробки, кроме специализированных решений для сканирования системы.
Подсистема печати
CUPS — «общая система печати UNIX», рождённая компанией Apple. Система модульная, поддерживает огромное количество устройств и, насколько мне известно, на сегодня не имеет альтернатив. А ещё CUPS имеет веб-интерфейс (по умолчанию на localhost:631).
CUPS работает только с печатающими устройствами, сканеры поддерживаются фреймворком SANE. К сожалению, спектр поддерживаемых устройств у SANE не очень широк. Некоторые вендорские драйверы для МФУ обеспечивают одновременно работоспособность сканера и работоспособность принтера через CUPS. Так, например, делает HPLIP от HP Inc. Благдаря HPLIP GNU/Linux может похвастаться отличной поддержкой печатающих устройств от HP. В то же время, HPLIP прикручен к CUPS немного сбоку, и часто проблематично настроить устройства HP только утилитами CUPS, как многие другие принтеры. Приходится использовать hp-setup
.
Звуковая подсистема
Продолжительное время основной звуковой подсистемой ядра является ALSA. Некоторые пользователи ошибочно считают, что PulseAudio заменил ALSA. Это не так, PulseAudio — это звуковой сервер, являющийся лишь слоем абстракции, упрощающим управление аудиопотоками. Другим аудиосервером является JACK, который предназначен для профессиональной работы с аудио. Он не столь удобен для пользователя, но обеспечивает низкие задержки и предоставляет гибкую маршрутизацию MIDI-потоков.
Red Hat готовит нам PipeWire на замену PulseAudio и JACK. Следим за событиями.
Межпроцессное взаимодействие
Здесь речь не про низкоуровневые POSIX-штуки типа разделяемой памяти и сокеты. За свой век GNU/Linux повидал несколько подсистем, призванных упростить межпроцессное взаимодействие (IPC) десктоп-приложений. Сейчас правит бал шина сообщений D-Bus, а об остальных позабыли. Для чего это нужно? Например, некая служба посылает в шину сообщение об изменении своего состояния, а апплет панели слушает его и изменяет свой индикатор. Так обычно работают апплеты громкости и клавиатурной раскладки.
Сеть
Традиционно в различных дистрибутивах GNU/Linux сеть настраивалась скриптами (причём различными). NetworkManager — детище Red Hat, созданное, чтобы править всеми интерфейсами. В годы юности NM вызывал приступы фрустрации у пользователей, но потом всё стало неплохо. NetworkManager позволяет управлять проводными и беспроводными интерфейсами, всевозможными тунелями, виртуальными мостами, VLAN'ами и аггрегированными каналами, причём как при помощи графических фронтендов, так и псевдографического nmtui
и текстового nmcli
. Вещь удобная и универсальная, в дистрибутивах Red Hat, ожидаемо идёт по умолчанию, в Debian и производных идёт только с рабочим столом, а в «безголовом исполнении» NM опционален. Есть альтернативы попроще, например — Wicd.
Работоспособность WiFi-устройств, как правило, обеспечивает демон WPA supplicant, у которого есть конкурент iwd, написанный ни много ни мало, компанией Intel.
Тут же хочется упомянуть демон Bluez, обеспечивающий работу с Bluetooth-устройствами.
Межсетевой экран
Слава iptables гремит далеко за узким кругом бородатых админов. Это не фильтр сам по себе, а лишь набор утилит в пространстве пользователя, работающий с подсистемой Linux Netfilter. Недавно (в историческом масштабе) добавилась подсистема ядра nftables и соответствующая пользовательская утилита nft. Это было сделано, в первую очередь, для унификации интерфейсов таблиц маршрутизации IPv4, IPv6, ARP и софтовых L2-коммутаторов. В современных дистрибутивах команды iptables являются лишь обёрткой для nftables и не рекомендуются к использованию. В целом, конфиг nft выглядит опрятнее дампа iptables.
Существует пачка высокоуровневых фаерволлов-обёрток над nftables (в том числе графических), так в RHEL и производых из коробки идёт firewalld, а в Ubuntu — UFW.
Пакетный менеджер
Пакетный менеджер — это сердце дистрибутива. Наиболее именитые и с длинной историей — это RPM из мира Red Hat и dpkg из семества Debian. Пример более современного — pacman из Arch Linux. Старожилы RPM и dpkg работают только с локальными пакетами: они их распаковывают, устанавливают и проверяют, что все зависимости удовлетворены. Работой с репозиториями занимаются другие утилиты, являющиеся как бы фронтендом к самому пакетному менеджеру. В RHEL ранее поставлялась утилита yum, на замену которой пришла dnf, в Debian раньше были apt-get и apt-cache, затем их увязали в одну команду apt. Более молодой pacman не имеет видимого пользователю разделения на несколько утилит и предлагает очень простой формат пакетов, которые можно собирать буквально на коленке. Есть и множество других, со своими особенностями. Например nix, который позволяет иметь в системе несколько версий одного пакета.
Новое в исторических масштабах явление — кросс-дистрибутивные системы поставки приложений. Появились в попытке преодолеть ад зависимостей, облегчить труд разработчиков и мейнтейнеров (избавив их от необходимости создавать десятки пакетов под разные версии и ветки GNU/Linux). Наиболее популярные проекты: Flatpack от Gnome, Snap от Canonical и AppImage сам по себе. Они несколько отличаются подходами, но в общем случае обеспечивают установку приложений со всем рантаймом и некоторой степенью изоляции от системы. Штуки удобные, однако подход несколько напоминает традиции тащить все зависимости с устанавливаемой программой в популярной ОС другого производителя. Простоты и порядка в систему не добавляют.
Для перечисленного добра есть красивые обёртки в виде магазинов приложений, два самых ходовых — GNOME Software и KDE Discover.
Заключение
Краткая результирующая диаграмма:
Если присмотреться к перечисленным составляющим GNU/Linux, можно заметить, что львиная доля технологий привносится несколькими крупными организациями. К ним относятся:
проект GNU под эгидой Free Software Foundation;
Red Hat, производитель коммерческого дистрибутива, недавно вошедший в состав IBM;
сообщество kernel.org при поддержке Linux Foundation.
В интернете ради флейма часто вкидывают, мол, поглядите — эти ваши линуксы делают клятые корпорации, где ваше хвалёное сообщество? Я думаю, не стоит противопоставлять отдельных энтузиастов и организации: все они вращают колесо open source. В конце концов, в больших организациях трудятся обычные люди. В итоге мы имеем очень динамичную систему, в которой не без причины компоненты сменяются один за другим, всё это куда-то движется, и, в общем-то, год от года хорошеет. Я надеюсь, в этом очерке удалось дать представление об анатомии GNU/Linux, а может быть и заинтересовать кого-нибудь закопаться поглубже.
Большое спасибо @ajijiadduh, который отловил огромное количество опечаток сразу после публикации, и всем прочим пользователям, указавшим на ошибки.
Правки и предложения вы можете присылать по адресу https://gitlab.com/bergentroll/gnu-linux-anatomy.
Copyright © 2020 Антон «bergentroll» Карманов.
Это произведение доступно по лицензии «Attribution-ShareAlike» («Атрибуция-СохранениеУсловий») 4.0 Всемирная (CC BY-SA 4.0).