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

Цели:

Задачи:

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

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

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

TODO — какие syscall-ы вызывает

Примеры

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

Сам systemd-networkd:

Настроим IP сервера с выходом в Интернет через стандартную «виртуальную» сеть VirtualBox (пример по ссылке выше)

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

[root@srv ~]# networkctl reload 
[root@srv ~]# networkctl reconfigure eth0
[root@srv ~]# networkctl 
IDX LINK TYPE     OPERATIONAL SETUP     
  1 lo   loopback carrier     unmanaged
  2 eth0 ether    routable    configured
  3 eth1 ether    off         unmanaged
  4 eth2 ether    off         unmanaged
  5 eth3 ether    off         unmanaged

5 links listed.
[root@srv ~]# networkctl 
delete       forcerenew   list         reconfigure  renew        up           
down         label        lldp         reload       status       
[root@srv ~]# networkctl status eth0
* 2: eth0                                                              
             Link File: /lib/systemd/network/99-default.link
          Network File: /etc/systemd/network/50-vbox.network
                  Type: ether
                 State: routable (configured)
          Online state: online                                         
     Alternative Names: enp0s3
                  Path: pci-0000:00:03.0
                Driver: pcnet32
                Vendor: Advanced Micro Devices, Inc. [AMD]
                 Model: 79c970 [PCnet32 LANCE] (PCnet - Fast 79C971)
            HW Address: 08:00:27:89:d2:0f (PCS Systemtechnik GmbH)
                   MTU: 1500 (min: 68, max: 1500)
                 QDisc: fq_codel
  Queue Length (Tx/Rx): 1/1
      Auto negotiation: no
                 Speed: 10Mbps
                Duplex: half
                  Port: tp
               Address: 10.0.2.15
               Gateway: 10.0.2.2
     Activation Policy: up
   Required For Online: yes

Apr 14 18:09:47 srv systemd-networkd[1096]: eth0: Re-configuring with /etc/systemd/network/50-vbox.network
Apr 14 18:09:47 srv systemd-networkd[1096]: eth0: Link UP
Apr 14 18:09:47 srv systemd-networkd[1096]: eth0: Gained carrier
Apr 14 18:09:51 srv systemd-networkd[1096]: eth0: Re-configuring with /etc/systemd/network/50-vbox.network

Эта настройка перманентна — после перезагрузки должна восстановиться.

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

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

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

Настройка net.ipv4.ip_forward:

[Network]
IPForward=ipv4

TODO

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


Заготовки


# systemctl edit --force --full cal.service`


[root@srv ~]# systemctl cat cal.service
# /etc/systemd/system/cal.service
[Unit]
Description=SOCAT Example

[Service]
ExecStart=/usr/bin/socat TCP-LISTEN:1234 EXEC:/usr/bin/cal

# systemctl start cal

# systemctl status cal
# ps | grep cal

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 cal
* cal.service - SOCAT Example
     Loaded: loaded (/etc/systemd/system/cal.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 hexdump.socket 
# /etc/systemd/system/hexdump.socket
[Unit]
Description = Hexdump Socket

[Socket]
ListenStream = 1234
Accept = yes

[root@srv ~]# systemctl cat hexdump@.service 
# /etc/systemd/system/hexdump@.service
[Unit]
Description=Hexdump Service

[Service]
ExecStart=/usr/bin/hexdump -C
StandardInput=socket
# если есть предыдущая строка, то по умолчанию:
#StandardOutput=socket

# Это ещё и accept/fork

(не успеем) Связь с отдельными функциями: RPC

Проблема: динамическое выделение входных портов.

Д/З

Задание 8

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

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

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

    • Подсказка: есть соблазн воспользоваться xxd -p / xxd -p -r, но придётся иметь дело с проблемой: xxd -p не вставляет пробелы в поток, и банальная замена двух цифр пожет прийтись не на границу байта. Например в строке из 5 байтов102336495b нет символа с кодом 33

      • Спойлер:

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

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

      • bash

      • sed, awk

      • … прочие стандартные утилиты linux
      • python3

      • perl

  4. Отчёт:
    1. report 8 srv

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

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

      • С помощью netcat проверить, что сервис (2) игнорирует некорректные данные (допустимо преобразовывать корректные или вообще ничего не выводить)

    2. report 8 client

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

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

      • С помощью netcat проверить, что сервис (3) игнорирует некорректные данные (допустимо преобразовывать корректные или вообще ничего не выводить)

      • Составить командную строку в виде цепочки netcat, объединённых в конвейер с помощью «|», которая заменяет табуляции точками.

    3. (продолжение отчёта srv)

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

  5. Два отчёта(названия сохранить, должно быть: 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 всё бы только испортила (заменились бы части адреса, например), так что в моём решении сервису (3) передаётся строка с пробелом.

LecturesCMC/LinuxNetwork2023/08_ApplicationSystem (последним исправлял пользователь FrBrGeorge 2023-04-15 13:13:49)