Прикладной уровень: возможности системы
Цели:
- Активация интерпретатора
- Сопоставление потока данных интерпретатору
- Обеспечение готовности сервиса-интерпретатора
- Интерпретация
- (…)
Задачи:
Связывание порта и интерпретатора
- Запуск и обслуживание интерпретатора
- Анонс прикладных служб по сети и распознавание этого анонса
- Учёт потребления ресурсов прикладными службами: иногда изнутри самого приложения не видно, насколько всё плохо
Связь с интерпретатором
Пространство имён: /etc/services — только well-known и нет прямой связи с приложением
- Делает сама служба:
создание обслуживание сокета (bind() + listen() + accept())
- respawn при закрытии соединения
- обслуживание нескольких соединений (в т. ч. общие и специфичные для прикладного уровня ограничения) —
- Делает служба запуска
Запуск произвольных служб, в том числе сетевых(на примере socat)
- Запуск интерпретаторов с сокет-активацией (на примере чего угодно!)
- Запуск/fork() без ожидания
Примеры
netstat
-ltp (и -lup)
-ntp (и -nup)
socat TCP-LISTEN:1234 EXEC:/usr/bin/cal
TIME_WAIT ⇒ TCP-LISTEN:1234,reuseaddr
Чтобы несколько соединений: TCP-LISTEN:1234,reuseaddr,fork
Службы systemd:
Ленарт и юзабилити ;_;
systemd-edit и его грабельки
Запуск socat как службы
- Сервис должен уметь в транспортный уровень
- Масштабирование с помощью шаблонов
- Сам сервис — только прикладной
TODO
Заготовки
# systemctl edit --force --full socat.service` [root@srv ~]# systemctl cat socat.service # /etc/systemd/system/socat.service [Unit] Description=SOCAT example [Service] ExecStart=/usr/bin/socat TCP-LISTEN:1234 EXEC:/usr/bin/cal # systemctl start socat # статус и ps root@srv ~]# netcat localhost 1234 April 2022 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 [root@srv ~]# systemctl status socat * socat.service - SOCAT example Loaded: loaded (/etc/systemd/system/socat.service; static) Active: inactive (dead) [root@srv ~]# /usr/bin/socat TCP-LISTEN:1234 EXEC:/usr/bin/cal 2022/04/06 18:40:48 socat[1739] E bind(5, {AF=2 0.0.0.0:1234}, 16): Address already in use # статус и ps — нет! [root@srv ~]# netstat -ntp Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:1234 127.0.0.1:51122 TIME_WAIT - # можно TCP-LISTEN:1234,reuseaddr # ещё можно TCP-LISTEN:1234,reuseaddr,fork # Но не нужно! [root@srv ~]# systemctl cat socat.socket # /etc/systemd/system/socat.socket [Unit] Description = Hedxump socket [Socket] ListenStream = 1234 Accept = yes [root@srv ~]# systemctl cat socat@.service # /etc/systemd/system/socat@.service [Unit] Description=Hexdump service [Service] ExecStart=/usr/bin/hexdump -C StandardInput=socket # Это ещё и accept/fork
(если успеем) Связь с отдельными функциями: RPC
Проблема: динамическое выделение входных портов.
- Portmapper (rpcbind, порт 111)
/etc/rpc
Д/З
Новое в образе
systemd и dmidecode (и dnsmasq, но он пока не нужен)
Если пользоваться обновлённым скриптом vbsnap, автоматически настраивается hostname:
- При создании клона его название записывается в поле «Производитель материнской платы» ☺ (см. сценарий)
В системе запущен systemd-сервис sethostname.service, который с помощью dmidecode вынимает из BIOS-а это имя, и если (1) оно не стандартное, и (2) в файлах /etc/hostname и /etc/sysconfig/network содержится разная информация, подменяет hostname
sethostname переписан в соответствие с этим протоколом. Если его вызвать вручную, он подменяет hostname в обоих местах, и потом ничего уже не меняется.
Задание 8
- Суть: написать и запустить три сетевых сервиса: два вырожденных и один простой
Первый сервис получает на вход произвольный файл, и выдаёт на выход hexdump этого файла
я использовал xxd с правильно подобранными ключами
Второй сервис выполняет обратную задачу (я использовал xxd -r)
Третий сервис сложнее. Ему надо на вход передать два параметра: текст-1, который надо заменить, и текст-2, на который его надо заменить; после чего на тот же вход передаётся текст, в котором надо произвести замену. На выходе должен получиться текст, в котором все вхождения текст-1 заменены на текст-2.
Задача: с помощью этих трёх сервисов организовать замену произвольного байта на любой другой произвольный байт (допустимо использовать в качестве параметров любое удобное — например, шестнадцатеричное — представление байтов).
- Настройка сети и запуск служб производятся заранее и в отчёт не входят
Подсказка: почитайте systemd.exec: имеет смысл отделить stderr сервиса от stdout
- Площадка:
srv — хост с двумя вырожденными сервисами (1) и (2)
client — хост с сервисом замены текста (3). для программирования на client доступны (можно пользоваться чем угодно, я выбрал python2):
bash
sed, awk
- … прочие стандартные утилиты linux
python2 (не python3)
perl
- Отчёт:
report 8 srv
Сделать systemctl cat обоим сервисам и их сокетам
Сделать systemctl status обоим сокетам
С помощью netcat проверить, что сервис (2) игнорирует некорректные данные (допустимо преобразовывать корректные или вообще ничего не выводить)
report 8 client
Сделать systemctl cat сервису (3) и его сокету
Если для обработки написан какой-то скрипт на каком-то языке, сделать ему cat
С помощью netcat проверить, что сервис (3) игнорирует некорректные данные (допустимо преобразовывать корректные или вообще ничего не выводить)
Составить командную строку в виде цепочки netcat, объединённых в конвейер с помощью «|», которая заменяет табуляции точками.
(продолжение отчёта srv)
Сделать systemctl status обоим сокетам: должно показать отсутствие соединений в данный момент (Connected:) и увеличить количество обслуженных соединений (Accepted:)
Два отчёта(названия сохранить, должно быть: report.08.srv, report.08.client) переслать одним письмом в качестве приложений на uneexlectures@cs.msu.ru
Пример:
[root@client ~]# cat /etc/crontab.template | { echo " 09"; echo " 2E"; netcat хост-srv порт-1; } | netcat localhost порт-3 | netcat хост-srv порт-2 # # # #minute (0-59), #|.hour (0-23), #|.|.day of the month (1-31), #|.|.|.month of the year (1-12), #|.|.|.|.day of the week (0-6 with 0=Sunday). #|.|.|.|.|.commands
- адреса и порты заменены
- в качестве строк используются куски шестнадцатеричного дампа
Ещё пример:
[root@client ~]# cal | { echo " 20"; echo " 23"; netcat хост-srv порт-1; } | netcat localhost порт-3 | netcat хост-srv порт-2 #####April#2022##### Su#Mo#Tu#We#Th#Fr#Sa ################1##2 #3##4##5##6##7##8##9 10#11#12#13#14#15#16 17#18#19#20#21#22#23 24#25#26#27#28#29#30 ####################
- Обратите внимание на то, что банальная замена в простом xxd 20 на 23 всё бы только испортила (заменились бы части адреса, например)
[root@client ~]# cal | xxd | sed 's/20/23/' | xxd -r # April 2022 # Su Mo Tu We Th Fr Sa xxd: sorry, cannot seek backwards.
Спойлер: