Продвинутое администрирование Linux и основы DevOps

Курс предназначен для перехода от базового использования Ubuntu к профессиональному администрированию серверов в корпоративной среде. Программа охватывает автоматизацию, безопасность, контейнеризацию и решение сложных технических задач с упором на практические лабораторные работы.

1. Архитектура Linux, управление процессами и правами доступа

Архитектура Linux, управление процессами и правами доступа

Добро пожаловать в мир профессионального администрирования Linux. Чтобы эффективно управлять серверами, контейнерами и облачной инфраструктурой, недостаточно просто знать команды. Необходимо понимать, как операционная система устроена изнутри. Мы начнем с фундамента: архитектуры ядра, жизненного цикла процессов и системы прав доступа.

Архитектура операционной системы Linux

Linux — это не просто программа, которую вы запускаете. Это слоистая структура, обеспечивающая взаимодействие между вашим кодом и физическим железом сервера.

!Слои архитектуры Linux: от аппаратного обеспечения к пользовательским приложениям

1. Аппаратное обеспечение (Hardware)

Это физический уровень: процессор (CPU), оперативная память (RAM), жесткие диски и сетевые карты. Сами по себе эти компоненты не знают, как запустить веб-сервер Nginx или базу данных.

2. Ядро (Kernel)

Сердце системы. Ядро — это программа, которая загружается первой и управляет всем оборудованием. Оно решает, какой процесс получит доступ к процессору прямо сейчас, а какой подождет. Оно выделяет память и обрабатывает запросы от программ.

3. Пространство пользователя (User Space)

Здесь работают все ваши программы: от командной оболочки Bash до Docker-контейнеров. Важно понимать: программы в User Space не имеют прямого доступа к железу. Если Nginx хочет записать лог на диск, он не пишет на диск сам. Он делает системный вызов (syscall) к ядру: «Пожалуйста, запиши эти данные». Ядро проверяет права и выполняет операцию.

Принцип «Всё есть файл»

Одной из ключевых концепций Linux является философия: «Всё есть файл». Это означает, что для системы нет принципиальной разницы между текстовым документом, директорией, жестким диском или сокетом сетевого соединения.

  • /dev/sda — это файл, представляющий ваш жесткий диск.
  • /proc/cpuinfo — это файл (виртуальный), содержащий информацию о процессоре.
  • /dev/null — это файл-«черная дыра», куда можно отправить ненужный вывод.
  • Понимание этого принципа критически важно для DevOps-инженера, так как это позволяет использовать одни и те же инструменты (например, cat, grep, перенаправление потоков) для работы с логами, устройствами и процессами.

    Управление процессами

    Когда вы запускаете программу, она становится процессором. У каждого процесса есть свой уникальный идентификатор — PID (Process ID).

    Жизненный цикл процесса

    В Linux процессы образуют иерархическое дерево. При загрузке системы ядро запускает самый первый процесс. В современных дистрибутивах (Ubuntu, CentOS 7+) это systemd, и он всегда имеет PID 1.

    Все остальные процессы являются «детьми» PID 1 или его потомков. Когда процесс порождает новый процесс, используется механизм fork (копирование родителя) и exec (замена кода копии на новую программу).

    Мониторинг процессов

    Для администратора важно уметь находить «прожорливые» или зависшие процессы.

    #### Команда ps Показывает моментальный снимок текущих процессов.

    Разберем ключи:

  • a — показать процессы всех пользователей.
  • u — вывести подробную информацию (пользователь, время старта, потребление памяти).
  • x — показать процессы, не привязанные к терминалу (демоны).
  • #### Команда top и htop top показывает процессы в реальном времени. htop — более удобный и красочный аналог.

    В top обратите внимание на параметр Load Average (три числа вверху справа). Они показывают среднюю нагрузку на систему за 1, 5 и 15 минут. Если Load Average выше количества ядер вашего процессора, значит, сервер перегружен и процессы стоят в очереди на выполнение.

    Сигналы: управление жизнью процесса

    Как остановить зависший процесс? Мы посылаем ему сигнал.

    Команда kill по умолчанию не «убивает», а отправляет сигнал. Самые важные сигналы:

  • SIGTERM (15) — «Пожалуйста, завершись». Это вежливая просьба. Процесс может перехватить этот сигнал, сохранить данные, закрыть соединения и корректно выйти. Это сигнал по умолчанию для команды kill PID.
  • SIGKILL (9) — «Умри немедленно». Этот сигнал обрабатывается ядром, а не процессом. Процесс уничтожается мгновенно, не успевая сохранить данные. Используйте только в крайнем случае.
  • SIGHUP (1) — Часто используется для перезагрузки конфигурации демонов без остановки процесса (например, nginx -s reload посылает этот сигнал мастер-процессу).
  • Пример жесткого завершения процесса с PID 1234:

    Права доступа и пользователи

    Безопасность Linux строится на разграничении прав доступа. Каждый файл и процесс принадлежит определенному пользователю (User) и группе (Group).

    Чтение, запись, исполнение

    Права доступа определяются для трех категорий:
  • u (user) — владелец файла.
  • g (group) — группа владельца.
  • o (other) — все остальные.
  • Для каждой категории можно установить три типа прав:

  • r (read) — чтение.
  • w (write) — запись (изменение).
  • x (execute) — исполнение (запуск скрипта или вход в директорию).
  • Посмотрим на вывод ls -l:

    Здесь -rwxr-xr-- расшифровывается так:

  • Первый символ - означает, что это файл (если бы было d, это была бы директория).
  • rwx (первая тройка) — владелец admin может читать, писать и исполнять.
  • r-x (вторая тройка) — группа devs может читать и исполнять, но не менять.
  • r-- (третья тройка) — остальные могут только читать.
  • Числовое представление прав (Octal)

    В администрировании часто используют числовую запись. Каждое право имеет свой вес:

    Где:

  • — итоговое значение права доступа (Permission).
  • — право на чтение, равно 4 (если есть) или 0 (если нет).
  • — право на запись, равно 2 (если есть) или 0 (если нет).
  • — право на исполнение, равно 1 (если есть) или 0 (если нет).
  • Например, права rwx (полный доступ) рассчитываются так:

    Где:

  • — итоговое числовое значение для rwx.
  • — чтение.
  • — запись.
  • — исполнение.
  • Права r-x (чтение и исполнение):

    Где:

  • — итоговое значение для r-x.
  • — чтение.
  • — отсутствие записи.
  • — исполнение.
  • Таким образом, права rwxr-xr-- из примера выше записываются как 754.

    Команды управления правами

  • chmod (change mode) — изменение прав доступа.
  • chown (change owner) — смена владельца и группы.
  • Специальные биты: SUID, SGID, Sticky Bit

    Для продвинутого администрирования важно знать специальные права.

  • SUID (Set User ID). Если этот бит установлен на исполняемый файл, то при запуске этот файл будет работать с правами владельца файла, а не того, кто его запустил.
  • Пример:* Утилита /usr/bin/passwd. Она принадлежит root. Когда обычный пользователь меняет свой пароль, программа должна записать его в защищенный файл /etc/shadow. Благодаря SUID, обычный пользователь запускает passwd, и она работает как root. Обозначение:* Буква s вместо x у владельца (rwsr-xr-x).

  • SGID (Set Group ID). Для директорий: все новые файлы, созданные в этой директории, будут наследовать группу этой директории, а не группу создателя. Это полезно для общих папок командной работы.
  • Sticky Bit. Устанавливается на директории. Разрешает удалять файлы внутри директории только их владельцам, даже если у других есть права на запись в саму директорию.
  • Пример:* Директория /tmp. Все могут писать туда, но вы не можете удалить временный файл соседа. Обозначение:* Буква t в конце (rwxrwxrwt).

    Лабораторная работа

    Выполните следующие задания в вашем терминале (локально или на виртуальной машине), чтобы закрепить материал.

    Задание 1: Работа с процессами

  • Запустите процесс, который будет работать долго, в фоновом режиме:
  • Найдите PID этого процесса с помощью ps или pgrep:
  • Посмотрите информацию о процессе в файловой системе /proc (подставьте ваш PID):
  • Завершите процесс мягко (SIGTERM):
  • Задание 2: Права доступа

  • Создайте файл и проверьте его права:
  • Установите права так, чтобы только вы могли читать и писать в него, а остальные не имели никакого доступа (600):
  • Попробуйте сменить владельца файла (потребуется sudo):
  • Попробуйте прочитать файл теперь (вы должны получить отказ в доступе).
  • Итоги

  • Архитектура: Linux состоит из ядра (работа с железом) и пространства пользователя (приложения). Взаимодействие идет через системные вызовы.
  • Процессы: Каждый процесс имеет PID. Systemd (PID 1) — родитель всех процессов. Для мониторинга используем ps и top, для управления — сигналы через kill.
  • Права доступа: Базируются на чтении (4), записи (2) и исполнении (1) для владельца, группы и остальных. Специальные биты (SUID, Sticky Bit) расширяют стандартную модель безопасности.
  • Философия: «Всё есть файл» — универсальный подход к управлению ресурсами системы.
  • 2. Сетевая безопасность, настройка iptables и веб-серверов Nginx

    Сетевая безопасность, настройка iptables и веб-серверов Nginx

    В предыдущей статье мы разобрали, как Linux управляет процессами и правами доступа к файлам. Теперь мы поднимаемся на уровень выше: сетевое взаимодействие. Для DevOps-инженера сеть — это кровеносная система инфраструктуры. Сервер, который не может безопасно общаться с внешним миром или базой данных, бесполезен.

    В этом материале мы разберем, как защитить сервер с помощью iptables, как работает маршрутизация пакетов внутри ядра и как настроить самый популярный веб-сервер Nginx.

    Основы сетевой подсистемы Linux

    Прежде чем блокировать хакеров, нужно понять, как Linux видит сеть. В отличие от Windows, где настройки часто скрыты в графических меню, в Linux сетевые интерфейсы, таблицы маршрутизации и правила фильтрации полностью прозрачны и управляемы.

    Сетевые интерфейсы

    Команда ip a (или устаревшая ifconfig) покажет вам список интерфейсов:

  • lo (loopback) — петлевой интерфейс (обычно 127.0.0.1). Трафик, отправленный сюда, никогда не покидает сервер. Это критически важно для внутренних сервисов, которые не должны быть видны извне.
  • eth0 / ens33 — физические или виртуальные Ethernet-адаптеры, соединяющие сервер с сетью.
  • Iptables: Межсетевой экран Linux

    Iptables — это утилита пользовательского пространства для управления подсистемой фильтрации пакетов в ядре Linux, называемой Netfilter. Когда сетевой пакет прилетает на сетевую карту, он проходит через серию проверок (цепочек), прежде чем попасть к приложению (например, к Nginx).

    !Путь сетевого пакета через таблицы и цепочки iptables

    Цепочки (Chains)

    Существует три основные цепочки в таблице filter (таблица по умолчанию):

  • INPUT — обрабатывает пакеты, адресованные самому серверу. Если вы хотите закрыть порт 22, вы работаете здесь.
  • OUTPUT — обрабатывает пакеты, созданные сервером и уходящие наружу.
  • FORWARD — обрабатывает пакеты, которые проходят через сервер (например, если сервер работает как роутер или шлюз для Docker-контейнеров).
  • Действия (Targets)

    Что делать с пакетом, если он попал под правило?

  • ACCEPT — пропустить пакет.
  • DROP — молча уничтожить пакет. Отправитель будет думать, что пакет потерялся или сервер выключен (таймаут соединения).
  • REJECT — отбросить пакет, но отправить отправителю ICMP-сообщение «Port Unreachable» или «Connection Refused». Это «вежливый» отказ.
  • Синтаксис команд

    Структура команды выглядит так: iptables -<Операция> <Цепочка> -<Параметры> -j <Действие>

    Пример: Разрешить входящий трафик на порт 80 (HTTP).

    Разберем ключи:

  • -A (Append) — добавить правило в конец списка.
  • -p tcp — протокол TCP.
  • --dport 80 — порт назначения (destination port).
  • -j ACCEPT (Jump) — действие.
  • Важность порядка правил

    Iptables проверяет правила сверху вниз. Как только пакет совпадает с правилом, проверка прекращается (кроме специальных случаев логирования).

    Типичная ошибка: Поставить запрещающее правило выше разрешающего.

    Пример ошибочной конфигурации:

  • iptables -A INPUT -j REJECT (Запретить всё)
  • iptables -A INPUT -p tcp --dport 22 -j ACCEPT (Разрешить SSH)
  • В этом случае вы потеряете доступ к серверу по SSH, так как первое правило сразу отклонит пакет. Правило SSH никогда не будет проверено.

    Stateful Inspection (Состояние соединений)

    Современный фаервол должен понимать контекст. Если вы отправили запрос к google.com (OUTPUT), вы ожидаете ответ. Но если входящие (INPUT) заблокированы, ответ не придет.

    Чтобы разрешить входящие ответы на ваши исходящие запросы, используется модуль conntrack:

    Это правило говорит: «Принимать пакеты, которые являются частью уже установленного соединения».

    Веб-сервер Nginx

    Если iptables — это охранник на входе в здание, то Nginx — это администратор на ресепшене, который направляет посетителей в нужные кабинеты. Nginx — это высокопроизводительный веб-сервер и обратный прокси (reverse proxy).

    Установка и управление

    В Ubuntu установка проста:

    Конфигурация

    Главный файл настроек: /etc/nginx/nginx.conf. Однако, хорошей практикой считается создание отдельных файлов для каждого сайта в директории /etc/nginx/sites-available/ и создание символических ссылок на них в /etc/nginx/sites-enabled/.

    Пример базовой конфигурации виртуального хоста:

    Здесь мы видим две роли Nginx:

  • Веб-сервер: Отдает статические файлы из /var/www/html для запросов к корню сайта.
  • Reverse Proxy: Перенаправляет запросы, начинающиеся с /api/, на другое приложение, работающее на порту 8080 (например, Node.js или Python приложение).
  • Оценка производительности

    При настройке Nginx важно понимать, сколько соединений он может обработать. Теоретический максимум одновременных соединений можно рассчитать по формуле:

    Где:

  • — максимальное количество одновременных клиентов (Max Clients).
  • — количество рабочих процессов (worker_processes), обычно равно числу ядер CPU.
  • — лимит соединений на один процесс (worker_connections), задается в конфиге.
  • Например, если у вас 4 ядра и лимит 1024 соединения на воркер, сервер теоретически может держать 4096 соединений. Однако в режиме reverse proxy каждое соединение клиента требует второго соединения к бэкенду, поэтому реальная цифра делится на 2.

    Взаимодействие Docker и Iptables

    Когда вы запускаете Docker, он автоматически создает свои цепочки в iptables (например, DOCKER-USER).

    Важный нюанс: Docker изменяет правила iptables, чтобы пробросить порты (NAT). Если вы опубликовали порт контейнера -p 80:80, Docker добавит правило, разрешающее доступ к этому порту, игнорируя ваши правила в цепочке INPUT (так как Docker использует цепочку FORWARD и PREROUTING).

    Чтобы ограничить доступ к Docker-контейнерам, нужно добавлять правила в специальную цепочку DOCKER-USER, которая создана специально для администраторов.

    Лабораторная работа

    В этой работе мы создадим защищенный веб-сервис. Мы запустим простой сервер на Python, закроем к нему доступ фаерволом, а затем настроим Nginx как единственную точку входа.

    Шаг 1: Запуск тестового сервиса

    Мы будем использовать встроенный модуль Python для создания простого HTTP-сервера, который слушает нестандартный порт.

  • Создайте директорию и индексный файл:
  • Запустите сервер на порту 8666 в фоновом режиме:
  • Проверьте, что он работает:
  • Шаг 2: Настройка Nginx

    Настроим Nginx так, чтобы он принимал запросы на порту 80 и пересылал их на наш сервис (порт 8666).

  • Создайте конфиг /etc/nginx/sites-available/lab-proxy:
  • Активируйте сайт:
  • Шаг 3: Настройка безопасности через iptables

    Теперь самое интересное. Мы хотим, чтобы пользователи могли заходить только через Nginx (порт 80). Прямой доступ к порту 8666 должен быть закрыт извне, но открыт для локального Nginx.

  • Сбросьте текущие правила (осторожно, если вы на удаленном сервере, убедитесь, что политика INPUT по умолчанию ACCEPT):
  • Разрешите установленные соединения (чтобы не разорвать ваш SSH):
  • Разрешите SSH (порт 22):
  • Разрешите HTTP (порт 80) для Nginx:
  • Разрешите локальный трафик (loopback). Это критически важно, так как Nginx общается с Python-сервером через 127.0.0.1:
  • Запретите всё остальное. Включая прямой доступ к порту 8666 извне (так как мы его явно не разрешили, он попадет под это правило):
  • Проверка

    Попробуйте обратиться к серверу с вашей рабочей машины (не с самого сервера):
  • curl http://<IP-SERVERA>:80 -> Должно работать (ответ "Hello...").
  • curl http://<IP-SERVERA>:8666 -> Должно зависнуть (DROP).
  • Итоги

  • Iptables фильтрует трафик на основе цепочек. Порядок правил критичен: первое совпадение выигрывает.
  • Политики: Используйте DROP для скрытия сервисов и REJECT для явного отказа. Всегда разрешайте ESTABLISHED соединения.
  • Nginx работает как эффективный обратный прокси, скрывая реальные приложения (Python, Node.js, Docker) от внешнего мира.
  • Безопасность: Идеальная схема — открыть только 80/443 и 22 порты наружу, а все внутренние коммуникации приложений оставить на localhost или закрыть фаерволом.