June 26

Linux: Продвинутые навыки DevOps-инженеров

На этом уровне мы уже не говорим о «где мой терминал» — вы уверенно работаете в Linux, и теперь самое время углубиться в темы безопасности, производительности и правильной настройки системных сервисов. Продвинутый уровень — это работа с SELinux, оптимизация конфигураций, диагностика ошибок, настройка SSH и сетевой безопасности.

В этой статье мы шаг за шагом разберём тест продвинутого уровня. Каждый вопрос снабжён объяснением, с акцентом на логике и практическом применении. Покажем, как избежать типичных ошибок при работе с конфигурацией Nginx, cron, SELinux и как диагностировать проблемы после обновления ядра или сетевых служб.

Такие навыки особенно ценны для DevOps-инженеров, системных администраторов, специалистов по информационной безопасности и всех, кто работает с продакшен-серверами.

Вопрос 1:

Вы просматриваете журнал /var/log/syslog и замечаете следующее сообщение ядра: kernel: TCP: Possible SYN flooding on port 80. Как можно интерпретировать это предупреждение?

Варианты ответов:

a)     Сетевой интерфейс перегружен входящими соединениями

b)    Процессор перегружен вычислительными задачами

c)     Система испытывает нехватку дискового пространства

d)    Принтер отправляет большое количество заданий на печать

e)     Служба SSH работает с ошибками авторизации

Обоснование:

  • Сообщение Possible SYN flooding указывает на подозрение в SYN-флуд-атаке — типе DDoS-атаки, когда злоумышленник отправляет большое количество TCP-запросов на установку соединения (SYN) без завершения «рукопожатия».
  • Это приводит к перегрузке очереди полуоткрытых соединений, чаще всего на веб-сервере (порт 80), что может привести к отказу в обслуживании.

Остальные ответы не соответствуют сути:

  • b) Процессор не имеет прямого отношения к SYN flood.
  • c) Дисковое пространство — не связано с TCP SYN.
  • d) Принтер тут ни при чём.
  • e) SSH не упоминается, и порт 80 — это HTTP.

Выбранный ответ: a) Сетевой интерфейс перегружен входящими соединениями

Вопрос 2:

Какой командой в Linux можно отфильтровать в реальном времени только сообщения уровня ERROR из журналов systemd?

Вариантыответов:

a)     journalctl -p 3-f

b)    systemctl list-units

c)     journalctl -p7-f

d)    dmesg I grep ERROR

e)     journalctl -p 5-f

Обоснование:

  • journalctl — команда для просмотра логов systemd.
  • -p 3 — фильтрует только сообщения с приоритетом 3, что соответствует ERROR.
  • -f — реальное время, вывод новых записей по мере их появления (аналог tail -f).

Уровни приоритета systemd:

  • 0 — emergency
  • 1 — alert
  • 2 — critical
  • 3 — error
  • 4 — warning
  • 5 — notice
  • 6 — info
  • 7 — debug

Остальные команды:

  • systemctl list-units — отображает статусы юнитов, а не логи.
  • journalctl -p 7 — покажет всё вплоть до debug, включая spam.
  • dmesg | grep ERROR — не использует systemd, а только dmesg, который выводит сообщения ядра.
  • journalctl -p 5 — покажет notice и выше — слишком широкий охват.

Выбранный ответ: a) journalctl -p 3 -f

Вопрос 3:

Какая ошибка в скрипте приводит к некорректной обработке файлов с пробелами в именах?

Варианты ответов:

a)     Используется неверный тип данных для хранения

b)    Не отключено расширение шаблонов (globbing)

c)     Пробелы не экранированы в списке файлов

d)    Не обёрнуты значения переменной $files в кавычки

e)     Не установлен IFS=quot;\n' перед циклом

Обоснование:
Переменная в скрипте:

files="file1.txt file 2.txt file3.txt file with spaces.txt"

При разбиении по пробелу Bash воспримет это как:

  • file1.txt
  • file
  • 2.txt
  • file3.txt
  • file
  • with
  • spaces.txt

Что вызовет ошибки: файлы с пробелами будут интерпретированы как несколько отдельных аргументов.

Чтобы этого избежать:

1.     Либо использовать массив:

files=("file1.txt" "file 2.txt" "file3.txt" "file with spaces.txt")

2.     Либо заменить пробелы на перенос строки и задать IFS='\n'.

Остальные ответы:

  • a) Тип данных корректен (строка).
  • b) Расширение шаблонов не играет роли — здесь нет * или ?.
  • d) Переменная $f как раз обёрнута в кавычки (в cat "$f").
  • e) Установка IFS — это дополнительно помогает, но корневая проблема — отсутствие кавычек в исходном списке.

Выбранный ответ: c) Пробелы не экранированы в списке файлов

Вопрос 4:

Вы хотите создать скрипт, который выводит по одному имени на строку всех файлов в текущем каталоге, начинающихся на file и заканчивающихся на .txt. Какой фрагмент кода нужно использовать?

Вариантыответов:

a) for file in file*.txt; do echo "$file"; done

b) for file in file.*.txt; do echo "$file"; done

c) for file in file".text; do echo "$file"; done

d) for file in *.txt; do echo "$file"; done

e) for file in file?*.txt; do echo "$file"; done

Обоснование:

Шаблон file*.txt означает:

  • Имя файла начинается с file
  • Затем может быть любое количество символов (*)
  • И заканчивается на .txt

Это идеально соответствует условию задачи.

Остальные:

b) file.*.txt — предполагает, что имя содержит точку после file, что не подходит.

c) file*.text — расширение .text, а не .txt.

d) *.txt — захватит все .txt-файлы, не только начинающиеся на file.

e) file?.*.txt — предполагает, что между file и .txt обязательно один символ и точка.

Выбранныйответ: a) for file in file*.txt; do echo "$file"; done

Вопрос 5:

Какая наиболее существенная проблема безопасности содержится в этой конфигурации Nginx?

server {

listen 80 default_server;

server_name example.com ;

root /var/www/html;

index index.php index.html index.htm;

location / {

autoindex on;

try_files $uri $uri/ =404;

}

location ~ \.php$ {

include snippets/fastcgi-php.conf;

fastcgi_pass unix:/run/php/php8.1-fpm.sock;

}

Варианты ответов:

a)     Сервер обслуживает только example.com, поэтому остальные запросы будут отклонены

b)    Используется Unix-сокет для PHP вместо ТСР-порта, что небезопасно в продакшене

c)     autoindex on раскрывает структуру директорий сервера при отсутствии index-файлов

d)    Отсутствует ограничение доступа к РНР-файлам, что позволяет выполнять произвольный код

e)     Неверно настроена директива try_files, что может вызвать ошибки 500

Обоснование:

Директива autoindex on; означает, что при отсутствии index.php, index.html или index.htm — веб-сервер отобразит список всех файлов в директории.

Это опасно на публичном сервере, так как может раскрыть:

  • конфигурационные файлы,
  • резервные копии,
  • случайно загруженные скрипты или дампы БД.

Остальные варианты:

a) Сервер может обслуживать любой хост, потому что указан default_server.

b) Использование Unix-сокета — это рекомендуемая практика, более безопасна, чем TCP.

d) PHP-файлы обрабатываются через location ~ \.php$, доступ ограничен — нет нарушения.

e) Директива try_files $uri $uri/ =404 написана корректно.

Выбранный ответ: c) autoindex on раскрывает структуру директорий сервера при отсутствии index-файлов

Вопрос 6:

После внесения изменений в файл /etc/nginx/nginx.conf, вы хотите, чтобы новая конфигурация вступила в силу немедленно, но при этом: – не было разрыва активных соединений, – не прерывались запросы в процессе обработки, – и были зарегистрированы возможные ошибки конфигурации. Какое действие следует предпринять?

Варианты ответов:

a)       Выполнить systemctl restart nginx

b)       Выполнить systemctl daemon-reexec nginx

c)       Выполнить nginx-s stop && nginx

d)       Выполнить systemctl reload nginx

e)       Убить процесс master с помощью kill -HUP $(pidof nginx)

Обоснование:

systemctl reload nginx:

  1. перезагружает конфигурацию Nginx без остановки процесса,
  2. не прерывает активные соединения,
  3. и, при наличии ошибок в конфигурации, запишет их в лог и не применит изменения.

Остальные варианты:

  • a) restart — прерывает соединения, останавливает и заново запускает службу.
  • b) daemon-reexec — перезапускает сам systemd, не относится к конфигурации Nginx.
  • c) nginx -s stop && nginx — это жёсткая перезагрузка, приводит к разрыву соединений.
  • e) kill -HUP — аналог перезагрузки, но менее предпочтителен, чем systemctl reload.

Выбранный ответ: d) Выполнить systemctl reload nginx

Вопрос 7:

Вы анализируете нагрузку на сервер. Команда top показала:

%Cpu(s): 3.0 us, 1.0 sy, 0.0 ni, 85.0 id, 0.0 wa, 0.0 hi, 0.0 si, 11.0 st

Через 10 секунд:

%Cpu(s): 5.0 us, 3.0 sy, 0.0 ni, 25.0 id, 0.0 wa, 0.0 hi, 0.0 si, 67.0 st

Что наиболее вероятно можно заключить по изменению состояния системы?

Варианты ответов:

a)     Происходит утечка памяти, увеличивается использование swap

b)    Виртуальная машина активно вытесняется гипервизором, и вычислительные ресурсы ограничены

c)     Увеличилось количество системных вызовов и процессов, но система стабильна

d)    Растёт нагрузка от пользовательских приложений, но ресурсов всё ещё достаточно

e)     Система простаивает, ресурсов по-прежнему достаточно

Обоснование:

Ключевой показатель здесь — st (steal time):

  • В первом замере: 11.0%
  • Во втором — 67.0%, что очень много

st — это процент времени, когда виртуальная машина (VM) хотела использовать CPU, но не могла, потому что гипервизор отдал его другой VM.
Это типичная ситуация при перегруженном хосте, когда несколько виртуалок конкурируют за CPU.

Остальные ответы:

  • a) SWAP и память не упоминаются.
  • c) Нет индикаторов системных вызовов.
  • d) Да, us/sy вырос, но ключевой показатель — st.
  • e) Система не простаивает — id резко упал до 25%, а st вырос.

Выбранный ответ: b) Виртуальная машина активно вытесняется гипервизором, и вычислительные ресурсы ограничены

Вопрос 8:

На сервере наблюдается замедленная работа приложений. Вам нужно в реальном времени определить, какие процессы загружают процессор и сколько оперативной памяти используется. Какую команду следует применить?

Варианты ответов:

a)     df-h

b)    du -sh

c)     grep cpuinfo

d)    ps aux

e)     top

Обоснование:

top — это интерактивная утилита мониторинга, которая:

  • отображает нагрузку на CPU и память в реальном времени,
  • показывает список процессов, отсортированных по загрузке ресурсов,
  • позволяет обновлять данные по умолчанию каждые 3 секунды.

Остальные команды:

  • df -h — свободное место на дисках, не про память и CPU.
  • du -sh — размер папки, не мониторинг процессов.
  • grep cpuinfo — просто покажет информацию о CPU, а не загрузку.
  • ps aux — даёт срез состояния процессов, но не в реальном времени.

Выбранный ответ: f) top

Вопрос 9:

Вы анализируете задание в crontab:
30 2 * * 1-5 /usr/local/bin/backup.sh
Что выполняет это задание?

Варианты ответов:

a)     Скрипт выполняется каждый час в будние дни

b)    Скрипт выполняется в 2:30 ночи только по будням

c)     Скрипт выполняется каждый понедельник и пятницу

d)    Скрипт выполняется каждую неделю в воскресенье

e)     Скрипт выполняется каждый день в 2:30 ночи

Обоснование: Формат cron:

Минуты Часы День_месяца Месяц День_недели Команда

Разбор строки 30 2 * * 1-5 /usr/local/bin/backup.sh:

  • 30 — в 30 минут
  • 2 — в 2 часа ночи
  • * — каждый день месяца
  • * — каждый месяц
  • 1-5 — по дням недели с понедельника (1) по пятницу (5)
  • Выполняется скрипт /usr/local/bin/backup.sh

Итог: скрипт запускается в 02:30 каждую ночь по будням.

Остальные ответы:

a) "каждый час" — неверно, т.к. указано 2:30.

c) понедельник и пятница — только два дня, а здесь диапазон 1-5.

d) воскресенье — это 0 или 7, здесь его нет.

e) “каждый день” — тоже нет, потому что ограничено буднями.

Выбранный ответ: b) Скрипт выполняется в 2:30 ночи только по будням

Вопрос 10:

Что произойдёт, если сервер будет выключен в момент времени выполнения задачи (в полночь) и будет включён в 08:00?

Варианты ответов:

a)     Задача будет запущена дважды - сразу и в полночь

b)    Таймер пропустит выполнение и запустится в следующую полночь

c)     Ничего не произойдёт, потому что WantedBy=timers.target неактивен

d)    systemd выдаст ошибку о невозможности вычислить OnCalendar и таймер не запустится

e)     Таймер выполнит задачу сразу после включения сервера

Обоснование:

В конфигурации таймера: Persistent=true

Эта опция означает:

·         Если сервер был выключен в момент планового запуска задачи, она будет выполнена при следующем старте.

Время запуска задано через: OnCalendar=*-*-* 00:00:00

— то есть ежедневно в полночь.

Сервис с Type=oneshot запускает скрипт однократно, без удержания процесса.

Следовательно, если сервер был выключен в полночь, systemd выполнит задачу при загрузке в 08:00, потому что таймер постоянный (Persistent=true) и помнит, что запуск был пропущен.

Остальные ответы — неверны:

a) дважды задача не запустится;

b) Persistent не позволит пропустить;

c) WantedBy=timers.target отвечает за включение при enable, он уже сработал;

d) OnCalendar не вызывает ошибок.

Выбранный ответ: e) Таймер выполнит задачу сразу после включения сервера

Вопрос 11:

После обновления ядра и пакетов служба network перестала запускаться автоматически. При ручном запуске возникает ошибка: Job for network.service failed because the control process exited with error code. systemctl status network.service показывает, что юнит существует, но не стартует. Какова наиболее вероятная причина?

Варианты ответов:

a)     Права доступа к файлам службы network.service были изменены, что препятствует её запуску

b)    Файл конфигурации network.service повреждён или содержит ошибку синтаксиса

c)     Драйвер сетевой карты несовместим с новым ядром и не загружается автоматически

d)    В конфигурации systemd отсутствует корректная зависимость от загрузки модулей ядра

e)     Служба network конфликтует с новым системным менеджером NetworkManager, вызывая ошибку запуска

Обоснование:

После обновлений часто активируется NetworkManager, который конфликтует с классической службой network (обычно используемой в старых дистрибутивах на базе RHEL/CentOS).

При этом:

  • network.service и NetworkManager.service не должны работать одновременно.
  • systemd не выдаёт ошибок синтаксиса, но не запускает юнит, потому что сетевое управление уже осуществляется другим сервисом.
  • В логах (journalctl -xe) можно увидеть ошибки типа "another network service is running".

Остальные варианты:

a) Проблемы с правами маловероятны без ручного вмешательства.

b) Синтаксис юнитов systemd проверяется автоматически.

c) Проблемы с драйверами привели бы к сбоям на более раннем уровне.

d) Зависимости от модулей ядра — редкая причина, и обычно она отображается в dmesg, а не systemctl.

Наиболее правдоподобно: конфликт двух сетевых менеджеров.

Выбранный ответ: e) Служба network конфликтует с новым системным менеджером NetworkManager, вызывая ошибку запуска

Вопрос 12:

Вы хотите проверить, сколько времени заняла активация служб при старте системы. Какую команду следует использовать?

Варианты ответов:

a)     systemctl list-units

b)    top

c)     systemd-analyze blame

d)    journalctl -xe

e)     dmesg

Обоснование:

Команда systemd-analyze blame выводит список юнитов systemd, отсортированный по времени их запуска, начиная с самых "тяжёлых".
Это позволяет оценить, какие службы тормозят загрузку.

Примеры вывода:

5.123s network.service

3.456s mysql.service

2.345s apache2.service

Остальные команды:

  • systemctl list-units — показывает текущие активные юниты, но без времени.
  • top — используется для мониторинга нагрузки, а не анализа старта.
  • journalctl -xe — просмотр последних сообщений логов, не аналитика старта.
  • dmesg — вывод ядра, не связан напрямую с systemd.

systemd-analyze blame — единственный корректный инструмент для этой задачи.

Выбранный ответ: systemd-analyze blame

Вопрос 13:

На сервере с включённым SELinux приложение webapp запущено под собственным доменом webapp_t. В конфигурации SELinux для webapp_t разрешён доступ только к определённым файлам в каталоге /var/www/webapps, а также ограничены сетевые подключения. При этом в системе назначены Linux capabilities CAP_NET_BIND_SERVICE и CAP_DAC_OVERRIDE для бинарника webapp.

При текущей конфигурации существует риск нарушения изоляции и несанкционированного доступа к критическим файлам вне разрешённого каталога.

Что из нижеперечисленного наиболее вероятно объясняет причину уязвимости?

Варианты ответов:

a)     SELinux политика по умолчанию игнорирует права сар abilities, поэтому назначение CAP_DAC_OVERRIDE не влияет на безопасность

b)    Разрешение CAP_NET_BIND_SERVICE позволяет приложению прослушивать сетевые порты ниже 1024, что создаёт прямую уязвимость в SELinux политике

c)     SELinux ограничивает только доступ к файлам, а саpabilities управляют только сетевыми ресурсами, следовательно риск нарушения изоляции исключён

d)    Назначение CAP_DAC_OVERRIDE позволяет приложению обходить стандартные проверки прав доступа файловой системы, игнорируя ограничения SELinux на уровне DAC, что приводит к возможному доступу к файлам вне /var/www/webapps

e)     Использование собственного домена webapp_t полностью изолирует приложение, но назначение любых capabilities приводит к отключению SELinux для данного процесса

Обоснование:
Возможность обхода стандартных проверок DAC (Discretionary Access Control) с помощью CAP_DAC_OVERRIDE приводит к тому, что даже при наличии строгих SELinux политик, приложение может получить доступ к файлам за пределами разрешённой зоны. Это создаёт риск нарушения изоляции и утечки данных.

Выбранный ответ: Назначение CAP_DAC_OVERRIDE позволяет приложению обходить стандартные проверки прав доступа файловой системы, игнорируя ограничения SELinux на уровне DAC, что приводит к возможному доступу к файлам вне /var/www/webapp

Вопрос 14:

Вы анализируете запись в /etc/fstab:

/dev/sdb1/backup ext4 defaults 0 0

Что означает эта запись для проверки файловой системы при загрузке?

Варианты ответов:

a)     Проверка ограничится главной файловой системой

b)    Проверка файловой системы будет отключена

c)     Будет выполнена автоматическая проверка после загрузки

d)    Файловая система будет проверяться каждый раз

e)     Файловая система будет проверяться при сбоях

Обоснование:
Запись 0 0 в последних двух полях /etc/fstab означает следующее:

  • Первое 0 — файловая система не будет включена в резервное копирование командой dump.
  • Второе 0 — fsck (проверка файловой системы при загрузке) отключена для этого раздела.

Таким образом, файловая система /dev/sdb1 монтируется без автоматической проверки при загрузке.

Выбранный ответ: Проверка файловой системы будет отключена

Вопрос 15:

После монтирования новой файловой системы в /data ранее созданные файлы и каталоги в этом каталоге стали недоступны. Перед монтированием структура выглядела так:

1 /data/

2 /dde

3 config.yaml

Затем была выполнена команда:

mount /dev/sdb1 /data

После монтирования содержимое /data полностью изменилось.

Какой из следующих вариантов наилучшим образом объясняет ситуацию?

Варианты ответов:

a)     Каталог /data перекрыт точкой монтирования

b)    mount автоматически переместил файлы из /data на новое устройство

c)     Данные из /data были удалены после монтирования

d)    Старые данные были перенесены в /lost+found

e)     Без флага --preserve mount стирает старое содержимое

Объяснение:
В файле /etc/fstab последние две цифры в строке монтирования управляют проверкой файловой системы:

  • Пятое поле (0) означает не выполнять дамп (backup).
  • Шестое поле (0) означает не выполнять проверку fsck при загрузке.
    Таким образом, файловая система не будет проверяться автоматически при загрузке.

Выбранный ответ: Проверка файловой системы будет отключена

Заключение:

Пройдя этот тест и изучив разбор, вы научитесь анализировать тонкие проблемы конфигурации, понимать безопасность в Linux не только на уровне теории, но и на практике. Это знания, которые позволяют не просто выполнять задачи, а отвечать за надёжность, безопасность и стабильность IT-инфраструктуры. Это уже уровень, с которого можно строить профессиональную карьеру в системном администрировании, DevOps или безопасности.