Прикладной уровень: возможности операционной системы

Поток / датаграмма / whatever получены. Что дальше?

Цели:

Задачи:

Систем запуска и контроля сетевых сервисов в Linux несколько, остановимся на самом «универсальном» — systemd.

https://www.google.com/search?newwindow=1&q=the+design+of+everyday+things&udm=2 Ленарт и юзабилити ☹

Коротко об управлении systemd

Связь с интерпретатором

Пространство имён: /etc/services — только well-known и нет прямой связи с приложением

В роли «служб» мы использовали

Два варианта сетевой службы в Linux:

  1. Полноценный сервис.
    • Делает подсистема запуска:
      • Запуск и останов по расписанию / заспросу
    • Делает сама служба:
      • Создание и обслуживание сокета (bind() + listen() + accept())

      • (одно соединение) Закрытие сокета + respawn при закрытии соединения
      • (несколько соединений) Обработка соединения отдельным процессом accept() + fork()

        • Количество одновременных соединений?
      • Интерпретация потоков В/В
      • Управление сервисом — сигналы или специальный сокет
  2. «Сокет-активация»
    • Делает подсистема запуска:
      • Создание и обслуживание сокета (bind() + listen() + accept())

      • Обслуживание одного соединения
      • Обслуживание нескольких соединений accept() + fork() (в т. ч. общие для прикладного уровня ограничения по ресурсам, конкуренции между соединениями и т. п.)

      • Запуск соответствующего интерпретатора потока (stdin / stdout) и преобразование потока в пакеты

      • Управление сервисом посредством сигналов
    • Делает сама служба:
      • Интерпретация потоков В/В
      • Управление сервисом через специальный сокет / утилиту

Есть ещё сокет-активация для полноценных сервисов с передачей им открытого сокета, (с указанием Accept=no):

Есть и другие аргументы в пользу Accept=no для доступных по сети служб (в спойлере)

<!> Вариант Accept=no встречается повсеместно, когда надо открыть unix domain сокет (обычно для управления сервисом).

Примеры

Запуск собственных служб с помощью systemd

Полноценный сервис

Сокет-активация

Сокет-активация systemd

Пример:

При задании сервиса можно использовать разные динамические значения

Для того, чтобы сервис (или сокет-активация) стартовали автоматом после перезагрузки, необходимо

  1. поставить соответствующий юнит в зависимость от какого-либо этапа загрузки системы, вписав в .service-файл примерно такое:

    [Install]
    WantedBy=multi-user.target
  2. Активировать сервис командой systemctl enable юнит

Перманентная настройка сети с помощью systemd-networkd

Различные дистрибутивы и сообщества Linux пользуются несколькими разными высокоуровневыми системами настройки сети; стандарта или общей договорённости нет. Раз уже мы начали с systemd, рассмотрим, как настраивать сеть с его помощью.

Сам systemd-networkd и его соседи — systemd-udevd и systemd-resolved:

Запустим его:

Настроим IP клиента и маршрутизацию через «внутреннюю» сеть VirtualBox и машину srv (аналогично примеру по ссылке выше):

Перечитаем настройки сети и обновим настройки интерфейса:

Эта настройка перманентна — после перезагрузки должна восстановиться. Надо только не забыть самому networkd сказать systemctl enable systemd-networkd

Леннарт и FrBrGeorge/MyDict/normancoffepot.png ошибки в конфигах. Если в .network-файле есть какая-то ошибка:

Настройка статического маршрута

Тот же файл ….network +

[Route]
Gateway=маршрутизатор
Destination=сеть

Настройка net.ipv6.conf.all.forwarding:

/etc/systemd/networkd.conf:

[Network]
IPv6Forwarding=yes

Из известного нам: ND proxy, Policy routing, …

Настройка автоматической конфигурации

Самый простой вариант — RAdv.

<!> При включённом networkd на интерфейсе параметр net.ipv6.conf.интерфейс.accept_ra всегда выключен — разбором RAdv занимается сам systemd-networkd.

Опция IPv6AcceptRA по умолчанию включена, если мы не роутер.

На клиенте:

[Network]
IPv6AcceptRA=yes

systemd-networkd умеет анонсировать RA! На роутере:

[Network]
IPv6SendRA=yes

[IPv6SendRA]
RouterLifetimeSec=200

[IPv6Prefix]
Prefix=2001:db8:0:c::/64

[Route]
Destination=2001:db8:0:c::/64

Можно и без явного маршрута, если префикс on-link и роутер берёт в нём себе адрес:

[Network]
IPv6SendRA=yes

[IPv6SendRA]
RouterLifetimeSec=200

[IPv6Prefix]
Prefix=2001:db8:0:c::/64
Assign=yes

Флаги AddressAutoconfiguration= и OnLink= для анонсируемого префикса по умолчанию включены.

Д/З

образ не изменился

Задание 8

08_ApplicationSystem_HW_v2.png

Суть: три виртуалки; на маршрутизаторе выдать двум другим виртуалкам RAdv с помощью systemd-networkd; на client и srv запустить три сетевых сервиса: два вырожденных и один простой

  1. Первый сервис получает на вход произвольный файл, и выдаёт на выход hexdump этого файла в любом удобном для решения задачи формате

  2. Второй сервис выполняет обратную задачу
  3. Третий сервис запускается на client, и он посложнее.

    • На вход подаётся три или более текстовых строк в формате ASCII
      1. Шаблон (первая строка)
      2. Замена (вторая строка)
      3. Текст из одной или более строк
    • На выходе должен получиться «текст», в котором все вхождения «шаблона» заменены на «замену».

Задача:

  1. Настроить на двух интерфейсах router сеть с помощью systemd-networkd (в отчёт не входит)

    • client и srv должны получить глобальные адреса и иметь между собой связность

  2. Перманентно настроить сеть на client и srv (в отчёт не входит)

  3. Оформить все три сервиса как чисто текстовые обработчики с сокет-активацией. С помощью этих сервисов организовать замену произвольного байта на любой другой произвольный байт (каждый байт — это две шестнадцатеричные цифры).

    • Настройка сети и запуск служб производятся заранее и в отчёт не входят
    • Подсказка: почитайте systemd.exec: имеет смысл отделить stderr сервиса от stdout

    • Спойлер: первые два сервиса за нас сделает xxd с ключами -c1 -p и -r -p соответственно.

  4. Площадка:
    • srv — хост с двумя вырожденными сервисами (1) и (2)

    • router — маршрутизатор с двумя интерфейсами в сторону srv и client

    • client — хост с сервисом замены текста (3). Для программирования на client доступны (можно пользоваться чем угодно, что найдёте в образе; я выбрал python3):

      • bash (на bash+sed это три строки), awk, … прочие стандартные утилиты linux, python3, perl

  5. Отчёт:
    1. report 8 client

      • Сделать networkctl status eth1 -n 1

      • Сделать systemctl cat сервису (3) и его сокет-активатору

      • Если для обработки написан какой-то скрипт на каком-то языке, сделать ему cat

      • Подать на вход сервису три строки: 33, 44 и 33, и убедиться, что он возвращает 44:

        • echo -e '33\n44\n33' | netcat localhost порт

      • Сделать systemctl status сокет-активатору: должно показать нулевое количество соединений в данный момент (Connected:) и ненулевое — обслуженных соединений (Accepted:)

    2. report 8 router

      • Сделать networkctl status eth1 -n 1

      • Сделать networkctl status eth2 -n 1

      • Запустить tcpdump -nv на любом из этих двух интерфейсов так, чтобы поймать передаваемые между службами данные

    3. report 8 srv

      • Сделать networkctl status eth1 -n 1

      • Сделать systemctl cat обоим сервисам и их сокет-активаторам

      • Сделать systemctl status обоим сокет-активаторам

      • Проверить, что преобразование в сервисах обратимо:
        • date > d; netcat localhost порт1 < d | netcat localhost порт2 | cmp d -

      • Собрать следующий конвейер из netcat-ов:

        • { echo 09; echo 2d; netcat localhost порт1 < /etc/crontab.template; } | netcat клиент порт | netcat localhost порт2

        • (табуляции должны замениться минуcами)
      • Сделать systemctl status обоим сокет-активаторам: должно показать нулевое количество соединений в данный момент (Connected:) и ненулевое — обслуженных соединений (Accepted:)

  6. Три отчёта (названия сохранить, должно быть: report.08.client, report.08.router, report.08.srv) переслать одним письмом в качестве приложений на uneexlectures@cs.msu.ru

    • В теме письма должно встречаться слово LinuxNetwork2026

LecturesCMC/LinuxNetwork2026/Six/08_ApplicationSystem (последним исправлял пользователь FrBrGeorge 2026-04-27 20:18:13)