Merge branch 'main' into v2

pull/1/head
Dmitry Ignatiev 2 years ago
commit 68efece713

@ -1,10 +1,11 @@
# Входное тестирование
1. В чем отличие mac-адреса от ip-адреса?
2. В чем разница между протоколами TCP и UDP?
1. В чем разница между протоколами TCP и UDP?
2. Маска подсети /26. Какое количество адресов мы сможем назначить на хосты?
3. Структуры данных: массив, список, дерево, хэш-таблица, очередь, стек. Расскажите о каждой.
4. Как создать файл в ОС Linux? Напишите максимальное количество вариантов.
5. Назовите популярные файловые системы, используемые в ОС Linux.
6. Что такое виртуальная память?
7. Что такое регистр процессора?
8. Напишите число 100 в шестнадцатиричной системе счисления.
8. Напишите число 150 в шестнадцатиричной системе счисления.
9. Компьютер пищит и не включается, что случилось и что делать?

@ -3,33 +3,35 @@
История операционных систем тесно связана с развитием компьютеров.
Основные идеи с 1950 по 1990. Наибольшая активность в 60х и 70х. Эволюция операционных систем прошла через 7 фаз:
- open shop (нужна аналогия)
- batch processing (пакетная обработка)
- multiprogramming (асинхронное выполнение ввода/вывода)
- timesharing (разделения времени)
- concurrent programming
- персональные компьютеры (personal computing)
- распределённые системы (distributed systems)
1. open shop (нужна аналогия)
2. batch processing (пакетная обработка)
3. multiprogramming (асинхронное выполнение ввода/вывода)
4. timesharing (разделения времени)
5. concurrent programming
6. персональные компьютеры (personal computing)
7. распределённые системы (distributed systems)
По Таненбауму 4 поколения:
- 1945 - 1955 Электронные лампы
- 1955 - 1965 Транзисторы и системы пакетной обработки
- 1965 - 1980 Интегральные схемы и многозадачность
- 1980 - сегодня Персональные компьютеры
Системы по фазам Hansen:
- IBM 701 open shop (1954)
- BKS (1961)
- Atlas supervisor (1961), B5000 (1964), Exec II (1966), Egdon (1966)
- CTSS (1962), Multics file system (1965), Titan file system (1972), Unix (1974)
- THE (1968), RC 4000 (1969), Venus (1972), Boss 2 (1975), Solo (1976)
- OS 6 (1972), Alto (1979), Pilot (1980), Star user interface (1982)
- WFS file server (1979), Unix United (1982), Amoeba (1990)
1. 1945-1955 Электронные лампы
2. 1955-1965 Транзисторы и системы пакетной обработки
3. 1965-1980 Интегральные схемы и многозадачность
4. 1980-сегодня Персональные компьютеры
Операционные системы по фазам Hansen:
1. IBM 701 open shop (1954)
2. BKS (1961)
3. Atlas supervisor (1961), B5000 (1964), Exec II (1966), Egdon (1966)
4. CTSS (1962), Multics file system (1965), Titan file system (1972), Unix (1974)
5. THE (1968), RC 4000 (1969), Venus (1972), Boss 2 (1975), Solo (1976)
6. OS 6 (1972), Alto (1979), Pilot (1980), Star user interface (1982)
7. WFS file server (1979), Unix United (1982), Amoeba (1990)
## 1 Open shop
Можно сказать, что история операционных систем начинается в 1954 году, когда у первых серийных компьютеров ещё не было операционных систем. Тогда пользователи управляли ими вручную. Доступ к компьютерам был организован поочереди в стиле open shop.
Операторы первых серийных компьютеров 701 были предшествениками современных системных администраторов. Группа по обмену информацией между ними SHARE существует до сих пор. В эру системных операторов компьютер был инструментом специального назначения, наподобие пилы. Переход от системных операторов к системному администратору начался тогда, когда компьютеры превратились в универсальные инструменты.
Сразу стало очевидным, что open shop организация приводит к большому времени простоя процессора. Джордж Рикман вспомнил о вопиющей неэффективности эксплуатации первого компьютера IBM, знаменитого 701: "Каждому пользователю был выделен 15-минутный интервал, из которых обычно он тратил 10 минут на настройку оборудования для выполнения своих вычислений. К тому времени, когда он начинал свои вычисления, для них оставалось только 5 минут или меньше - трата две трети его временного интервала."
Джон Маккарти (1962) сделал аналогичное замечание о компьютере TX-0, который использовался в режиме открытого магазина в Массачусетском технологическом институте. Он добавил: "Если бы TX-0 был компьютером гораздо большего размера и если бы он работал так же, как сейчас, количество пользователей, которых он обслуживал было бы примерно таким же."
@ -40,9 +42,9 @@
Теперь процессорное время тратилось эффективно, его не нужно был запускать во время подготовки программ. Чем длиннее были ленты, тем меньше простаивал главный компьютер. Но большие серии задач значительно увеличили время выполнения с точки зрения пользователей. Обычно требуется несколько часов (или даже день или два), прежде чем они могли получить результаты одного задания. Если задание включало компиляцию программы, единственным выходом в этот день могло быть сообщение об ошибке, вызванное неуместной точкой с запятой.
## 3 Multiprogramming (асинхронный ввод/вывод)
## 3 Multiprogramming/Многозадачность
В 1960-х годах большая основная память, вторичное хранилище с произвольным доступом, каналы данных и аппаратные прерывания радикально изменили операционные системы. Прерывания позволяли процессору имитировать одновременное выполнение нескольких программ и управлять одновременными операциями ввода/вывода. Эта форма параллелизма стала известна как мультипрограммирование.
В 1960-х годах большая основная память, вторичное хранилище с произвольным доступом, каналы данных и аппаратные прерывания радикально изменили операционные системы. Прерывания позволяли процессору имитировать одновременное выполнение нескольких программ и управлять одновременными операциями ввода/вывода. Эта форма параллелизма стала известна как мультипрограммирование (многозадачность).
Мультипрограммирование и вторичное хранилище сделали возможным создание операционных систем, которые обрабатывали непрерывный поток ввода, вычислений и вывода на одном компьютере, используя барабаны (или диски) для хранения больших буферов. Такая схема называлась спулингом/подкачка (Spooling - это акроним “Simultaneous Peripheral Operation On-Line.). Барабаны были удобнее лент, так как заполнялись с одной стороны устройство чтения перфокарт, а с другой считывались основным процессором. Больше не было накладных расходов на монтирование ленты (если только пользовательские программы не обрабатывали свои собственные ленты данных). Большие буферы произвольного доступа позволили использовать приоритетное планирование заданий, например, «кратчайшее задание — следующее» (вместо «первым пришел — первым обслужен»).
@ -58,9 +60,7 @@
Atlas был организован так, чтобы защитить пользовательские программы и системные вызовы друг от друга.
## 4 Timesharing
Операторы первых серийных компьютеров 701 были предшествениками современных системных администраторов. Группа по обмену информацией между ними SHARE существует до сих пор. В эру системных операторов компьютер был инструментом специального назначения, наподобие пилы. Переход от системных операторов к системному администратору начался тогда, когда компьютеры превратились в универсальные инструменты.
## 4 Timesharing/Разделение времени
В 1962 году Джон МакКарти написал следующее:
@ -68,17 +68,19 @@ Atlas был организован так, чтобы защитить поль
Поскольку программы могут выполнять только относительно короткие фрагменты работы между взаимодействиями с людьми, неэкономично постоянно перемещать их туда и обратно во вторичное хранилище. Следовательно, существует потребность в большой первичной памяти. Последнее требование заключается в том, чтобы вторичное хранилище было достаточно большим для хранения пользовательских файлов, чтобы пользователям не приходилось иметь отдельные карты или ленточные устройства ввода-вывода."
Разделение времени значительно снизило цену предоставления вычислительных мощностей.
CTSS 1965 и Multics 1969 были первыми реализациями этой идеи. Также современным ОС от них досталась технология иерархичной файловой системы для вторичного хранилища.
*Посмотреть MULTICS https://www.youtube.com/watch?v=q0yfhZB7VpA или подключиться к menu@tty.livingcomputers.org*
В 1969 Денис Ритчи И Кен Томпсон начали разработку альтернативы Multics о которой стало известно публично в 1974 году. Проект Multics превысил бюджет, безнадёжной отстал от графика, и был свёрнут. Денис: "Мы были немного подавлены большим менталитетом системы, Кен хотел создать что-то простое... Операционная система Multics больше не существовала для нас, но нам нравилось ощущение интерактивной работаы на компьютере, которые она предлагала пользователю." Такие команды как: as, cal, chmod, chown, cmp, cp, date, dc, du, ed были созданы в 1971 году. В 1973 появились два важных нововведения в UNIX: язык С и реализация каналов. Каналы позволили легко комбинировать существующие программы в конвейры обработки данных. К середине 1980 Unix стала стандартом для систем с разделением времени и была установлена практически во всех крупных университетах мира.
В 1969 Денис Ритчи И Кен Томпсон начали разработку альтернативы Multics о которой стало известно публично в 1974 году. Проект Multics превысил бюджет, безнадёжной отстал от графика, и был свёрнут. Денис: "Мы были немного подавлены большим менталитетом системы, Кен хотел создать что-то простое... Операционная система Multics больше не существовала для нас, но нам нравилось ощущение интерактивной работы на компьютере, которые она предлагала пользователю." Такие команды как: as, cal, chmod, chown, cmp, cp, date, dc, du, ed были созданы в 1971 году. В 1973 появились два важных нововведения в UNIX: язык С и реализация каналов. Каналы позволили легко комбинировать существующие программы в конвейры обработки данных. К середине 1980 Unix стала стандартом для систем с разделением времени и была установлена практически во всех крупных университетах мира.
*Включить AT&T Archives: The UNIX Operating System https://www.youtube.com/watch?v=tc4ROCJYbm0*
Примерно в это время системное администрирование стало формироваться как профессия. Считается что такие учебные заведения, как Университет Пердью, Унивеситет штата Нью-Йорк (SUNY) в г. Буффало, Университет штатов [Колорадо, Юта, Мэриленд] стали рассадниками этих специалистов. Это были как сейчас говорят эникейщики, ангелы-хранители компьютеров и их пользователей, готовые починить лазерный принтер, помочь студенту отладить новый драйвер, записать данные на архивные ленты, уговорить пользователей почистить персональные каталоги, чтобы освободить место, найти запчасти по всей стране.
С ростом популярности профессии возникла потребность в документации знаний об администрировании. "Идя навстречу пожеланиям трудящихся" Тим О'Reilly и его команда в конце 80-х начали публиковать документацию по UNIX. В 1989 коду было опубликовано певое издание книги Эви Немет Unix System Adminstration Handbook (в это время появилось множество директорий `/and so on/passwd`, вместо `/etc/`).
С ростом популярности профессии возникла потребность в документации знаний об администрировании. "Идя навстречу пожеланиям трудящихся" Тим О'Reilly и его команда в конце 80-х начали публиковать документацию по UNIX. В 1989 коду было опубликовано первое издание книги Эви Немет Unix System Adminstration Handbook (в это время появилось множество директорий `/and so on/passwd`, вместо `/etc/`).
## 5 Конкурентное программирование
@ -117,7 +119,7 @@ Amoeba — амбициозная распределенная система,
Спохватившись, AT&T начала судебный процесс, заявив о копировании кода и краже производственных секретов. В результате судебного разбирательства в течение двух лет из кода BSD было удалено три файла из более 18000. К сожалению, это период неопределённости оказал негативное влияние на весь мир UNIX.
В 1987 Танненбаум выпустил небольшой клон системы UNIX - MINIX под лицензией, разрешающий использование только в образовательных целях. Желая получить свободно распространяемую версию UNIX, финский студент Линус Торвальдс написал собтвенную макроядерную систему-клон Linux. Так началась эра Linux.
В 1987 Танненбаум выпустил небольшой клон системы UNIX - MINIX под лицензией, разрешающий использование только в образовательных целях. Желая получить свободно распространяемую версию UNIX, финский студент Линус Торвальдс написал собственную микроядерную систему-клон Linux. Так началась эра Linux.
## Итоги
@ -142,6 +144,7 @@ Amoeba — амбициозная распределенная система,
За это время компьютеры ушли от вида специализированных устройств, проводящих расчёты военного назначения, к универсальным машинам для обработки данных. Это не могло стать возможным без эволюции операционных систем. Администрирование этих систем сформировалось как профессия.
# Архитектура ОС
Наверное к этому моменту у вас уже сложилось представление о том, что такое операционная система. Можно дать два определения ОС. С одной стороны, операционная система - это интерфейс между hardware и software, слой абстракции для прикладных программ и аппаратного обеспечения. С другой стороны, операционная система - это менеджер ресурсов.
@ -151,7 +154,9 @@ Amoeba — амбициозная распределенная система,
- оболочка,
- пользовательские программы.
# Ссылки
- Hansen. The evolution of operating systems
- Таненбаум. Современные операционные системы
- Немет Э. Руководство системного администратора (Краткая история системного администрирования)
@ -159,4 +164,6 @@ Amoeba — амбициозная распределенная система,
- Michael W. Lucas. Absolute FreeBSD, 3rd Edition
- Rebel Code. Linux and the Open Source Revolution
- Петцольд, Чарльз. Код. Тайный язык информатики
- https://elektronika.su/
- https://elektronika.su/
- https://yandex.ru/museum/
- https://computerhistory.org/

@ -4,7 +4,7 @@
Установить Debian на виртуальную машину tabularasaX в Proxmox.
## Задание 2
Найдите и 2-5 предложениями расскажите остальным про одну из следующих машин:
Найдите и 2-5 предложениями расскажите остальным про один из этих вычислительных инструментов:
- аналитическая машина Бэббиджа,
- разностная машина Бэббиджа,
- Comptometer,

@ -1,7 +1,27 @@
# Решения
## 1
Вы в директории `/home/stud/data`. Какая из команд переместит вас в домашнюю директорию?
Повторите структуру директории с помощью команд `mkdir` и `touch`:
```
mkdir project
cd project
mkdir backup
mkdir data
mkdir data/raw/
touch data/raw/2022-07-23-exp1.data
touch data/raw/2022-07-23-exp1.log
touch data/raw/2022-08-03-exp2.calib
touch data/raw/2022-08-03-exp2.data
touch data/raw/2022-08-03-exp2.log
touch data/raw/2022-11-23-exp3.calib
touch data/raw/2022-11-23-exp3.data
touch data/raw/2022-11-23-exp3.log
mkdir shared
mkdir -p this/is/a/long/and/strange/path
```
## 2
Вы в директории `/home/stud/project/`. Какая из команд переместит вас в домашнюю директорию?
```
3 cd /home/stud
5 cd ~
@ -9,8 +29,20 @@
8 cd
9 cd ..
```
## 2
Создайте файл dummy в /tmp. Попробуйте удалить его указав флаг -i для команды rm. В чём отличие удаления файла с этим флагом и без него?
## 3
Перейдите в папку `backup`. Используя команду `cp`, выполните следующие действия одной строкой:
- скопируйте два файла: `.bashrc` и `.bash_profile` в папку `backup`,
- скопируйте файл `.bashrc` в две директории: `/tmp/` и `shared`.
```
cd ~/project/backup/
cp -t ./ ~/.bashrc ~/.bash_profile
cp ~/.bashrc/ /tmp/
cp ~/.bashrc /home/stud/project/shared/
```
## 4
Создайте файл `dummy` в `/tmp`. Попробуйте удалить его указав флаг `-i` для команды `rm`. В чём отличие удаления файла с этим флагом и без него?
```
mkdir /tmp/dummy
@ -21,72 +53,65 @@ rm -r /tmp/dummy
```
Отличие в запросе подтверждения действия.
## 3
Создайте папку backup в домашней директории. Одновременно скопируйте файл .bashrc в /tmp/ и в backup с помощью cp.
```
$ mkdir ~/backup
$ cp .bashrc ~/backup; cp .bashrc /tmp/
```
## 4
Повторите структуру директории:
```
mkdir project
cd project
mkdir .git
mkdir data
mkdir raw
cd raw
touch 2022-07-23-exp1.log
touch 2022-08-03-exp2.log
touch 2022-11-23-exp3.log
touch 2022-07-23-exp1.dat
touch 2022-08-03-exp2.dat
touch 2022-08-03-exp2-calibration.dat
touch 2022-11-23-exp3.dat
touch 2022-11-23-exp3-calibration.dat
cd ../
mkdir backup
mkdir shared
```
## 5
Скопируйте файлы экспериментов в backup, но распределите по папкам разные типы файлов. .data в backup/dataset, dat-calibration в backup/calibration, логи в backup/logs. В shared поместите все файлы, созданные 23 числа в папку 23day. Напишите команды в двух вариантах: с относительными путями и с абсолютными.
Скопируйте файлы экспериментов в `backup`, но распределите их по папкам. Файлы с расширением `.datа` в `backup/data`, файлы с расширением `.calib` в `backup/calibration`, логи `.log` в `backup/logs`. В `shared` поместите все файлы, созданные 23 числа в папку `23day`. Напишите команды в двух вариантах: с относительными путями и с абсолютными и проверьте, что их выполнение даёт одинаковый результат.
```
cd backup
mkdir dataset calibration logs
cp ./raw/*-exp?.dat backup/dataset/
cp ./raw/*-exp?-calibration.dat backup/calibration
cp ./raw/*.log ./backup/logs/
```
```
export PD=/home/stud/project
mkdir $PD/backup/dataset $PD/backup/calibration $PD/backup/logs
cp $PD/raw/*-exp?.dat backup/dataset/
cp $PD/raw/*-exp?-calibration.dat backup/calibration
cp $PD/raw/*.log ./backup/logs/
mkdir data calibration logs 23day
cp ../raw/*.data ./data/
cp /home/stud/project/raw/*.calib /home/stud/project/backup/calibration
cp /home/stud/project/raw/*.log /home/stud/project/backup/logs/
cp /home/stud/project/raw/*-23-* /home/stud/project/backup/23day/
```
## 6
Посчитайте количество строк в файле /var/log/messages.
Посчитайте количество строк, слов и символов в файле `/var/log/dpkg.log`.
```
sudo wc -l /var/log/messages
wc -l /var/log/dpkg.log
cat /var/log/dpkg.log | wc -l
sudo cat /var/log/messages | wc -l
wc -w /var/log/dpkg.log
wc -m /var/log/dpkg.log
```
## 7
Инициализируйте файл head_tail_messages с помощью команды head из строк в /var/log/messages, затем добавьте в head_tail_messages последние 23 строки из /var/log/messages.
Инициализируйте файл `head_tail_messages` с помощью команды `head` из строк в `/var/log/dpkg.log`. Затем добавьте в `head_tail_messages` последние 23 строки из `/var/log/dpkg.log`.
```
sudo head /var/log/messages > head_tail_messages
sudo tail -n 23 /var/log/messages >> head_tail_messages
sudo head /var/log/dpkg.log > head_tail_messages
sudo tail -n 23 /var/log/dpkg.log >> head_tail_messages
```
## 8
Создайте псевдоним "dc", который разрешается в команду "cd" для случаев опечатки.
Постройте конвейр с помощью оператора `|`, который считывает содержимое `/var/log/dpkg.log`, находит только строки содержащие слово `perl`, сохраняет результат в файл `/tmp/perl_pkgs` и одновременно выводит в консоль количество найденных строк.
```
alias dc=”cd”
cat /var/log/dpkg.log | grep perl | tee /tmp/perl_pkgs | wc -l
```
## 9
Выполните две команды: `head /nonexistent; echo Ok` и `head /nonexistent && echo Ok`. В чём отличие в поведении?
В первом случае вторая команда выполнится, несмотря на не нулевой код ошибки. Во втором не выполнится, в консоли не напечатается "Ok".
## 10
Оператор `||` похож на оператор ИЛИ в программировании. Что вы ожидаете увидеть при запуске `mkdir test || echo Ok`? Проверьте так ли это.
Так как первая команда выполнится успешно, значение выражения можно считать истинным даже если другие будут выполнятся с ошибками. Поэтому вторая команда выполняться не будет.
## 11
Создайте псевдонимы: `dc`, `chomd` которые разрешаются в команды: `cd`, `chmod` чтобы наконец решить проблему опечаток.
Создайте псевдоним `ls` для команды `ls -alF` и `cdw` для команды `cd /home/stud/project/`. Проверьте работу псевдонимов.
Удалите псевдоним `ls` командой `unalias`. Проверьте, что выдача соответствует оригинальной команде `ls`.
```
alias dc="cd"
alias chomd="chmod"
alias ls="ls -alF"
alias cdw="cd /home/stud/project/"
unalias ls
```
## 12
Прочитайте мануал `man ls` и напишите `ls` команду, которая выводит список файлов в следующем виде:
* список файлов включает скрытые,
@ -97,16 +122,57 @@ alias dc=”cd”
ls -caht или ls -cahtl
```
## 10
Запишите в переменную среды PATH значение "". Как это повлияло на выполнение команд? Перезайдите по ssh и попробуйте вызывать любую команду заново. Сохранились ли изменения?
## 13
Попробуйте вывести содержимое переменной среды `HOME` с помощью `echo` в одинарных и двойных кавычках. В чём разница?
```
echo "$HOME"
echo '$HOME'
```
Разница в том, что выражения внутри двойных кавычек интерпретируются, а в одинарных нет. В первом случае выведется значение переменной HOME, во втором `$HOME`.
## 14
Запишите в переменную среды `PATH` значение `""`. Как это повлияло на выполнение команд? Перелогиньтесь и попробуйте вызывать любую команду заново. Сохранилиcь ли изменения?
Первое слово в консоли интерпретируется как вызов исполняемого файла, функции или псевдонима. Поиск исполняемых файлов с переданным названием ведётся в директориях, перечисленных через `:` в переменной среды PATH. Поэтому при пустом списке ни один исполняемый файл не будет найден.
```
export PATH=””
следствие: ни один исполняемый файл системой теперь не находится
после переподключения система вернулась в прежнее состояние
```
## 11
Модифицируйте команду так, чтобы у директорий в начале названия присутствовал глобальный индекс idx.
## 15
C помощью bash синтаксиса для арифметических операций выведите результат:
- сложения 10 и 4,
- умножения 10 на 4,
- деления 10 на b, где b это переменная равная 3.
Сохраните результат операции `a % b` в переменную `c`, где `a` и `b` результаты любых предыдущих двух операций. Выведите `с`.
```
echo $((10 + 4))
echo $((10 * 4))
b=3
echo $((10 / b))
a=$((10 * 4))
b=$((10 / b))
c=$((a % b))
echo $c
```
## 16
Выполните в терминале следующую команду в директории `/tmp`:
```
for species in cubane ethane methane;
do
for temperature in 25 30 37 40;
do
mkdir $species-$temperature;
done
done
```
Что в результате вы видите в консоли? Модифицируйте команду так, чтобы у директорий в начале названия присутствовал глобальный индекс `idx`. На каждой итерации внутреннего цикла `idx` должна увеличиваться на единицу.
```
idx=0;
for species in cubane ethane methane;
@ -122,7 +188,36 @@ done
idx=-1; for species in cubane ethane methane; do for temperature in 25 30 37 40; do mkdir $idx-$species-$temperature; ((idx+=1)); done; done
```
## 12
## 17
Напишите цикл, который проходит по списку файлов в текущей директории и выводит полный путь к директории и имя файла.
```
for f in `ls`; do
echo `pwd` $f;
done
```
## 18
Далее поработайте с командой `watch date`. Команда `watch` вызывает периодически переданную ей команду в качестве аргумента. Это удобно для организации простого мониторинга.
Первый раз вызовите команду и отправьте процессу сигнал `SIGINT` комбинацией клавишь `Ctrl+C`.
Второй раз вызовите команду и отправьте процессу сигнал `SIGTSTP` комбинацией клавишь `Ctrl+Z`. Выведите статус процесса командой `jobs`. Переведите процесс в активное состояние командой `fg` и остановите процесс.
Третий раз вызовите команду с добавлением одиночного символа `&`. Остановите процесс командой `kill`.
*man страницы: kill, signal*
Механизм сигналов - примитивный способ общения с процессами. Часть кодов сигналов процесс обязан обработать, часть может обработать исходя из заданной программистом логики.
При запуске процесса в интерактивном режиме его потоки ввода и вывода соединяются с терминалом. Символ & позволяет запустить процесс в фоновом режиме, не делая связывания потока ввода.
## 19
Напишите команду, которая рекурсивно находит все HTML-файлы в папке и запаковывает их в tar.gz архив. Ваша команда должна работать, даже если в файлах есть пробелы.
```
find . -type f -name "*.html" -print0 | xargs -0 tar cfz htmls.tar.gz
```
## 20
(*) Напишите команду или сценарий для рекурсивного поиска самого последнего измененного файла в каталоге. В общем, можете ли вы перечислить все файлы по давности?
Плохое решение
@ -136,28 +231,4 @@ find ./ -type f -printf "%T+ %H%P\n" 2>/dev/null | sort -r
где
%T+ - время последнего изменения в формате 2004-04-28+22:22:05.0,
%H - путь к директории, в которой файл найден,
%P - имя файла.
## 13
Напишите цикл, который проходит по списку файлов в текущей директории и выводит полный путь к директории и имя файла.
```
for f in $(ls); do echo $(pwd)/$f; done
```
## 14
Выведите результат сложения 10 и 4 с помощью bash синтаксиса для арифметических операций.
```
echo $((10 + 4))
```
## 15
Выведите результат умножения двух переменных с помощью bash синтаксиса для арифметических операций.
```
a=1; b=2; echo $((a*b))
```
## 16
Напишите команду, которая рекурсивно находит все HTML-файлы в папке и запаковывает их в tar.gz архив. Ваша команда должна работать, даже если в файлах есть пробелы.
```
find . -type f -name "*.html" -print0 | xargs -0 tar cfz htmls.tar.gz
```
%P - имя файла.

@ -68,7 +68,7 @@ project/
## 11
Создайте псевдонимы: `dc`, `chomd` которые разрешаются в команды: `cd`, `chmod` чтобы наконец решить проблему опечаток.
Создайте псевдоним `ls` для команды `ls -alF` и `cdw` для команды `cd /home/stud/project/`. Проверьте работу псведонимов.
Создайте псевдоним `ls` для команды `ls -alF` и `cdw` для команды `cd /home/stud/project/`. Проверьте работу псевдонимов.
Удалите псевдоним `ls` командой `unalias`. Проверьте, что выдача соответствует оригинальной команде `ls`.

@ -113,5 +113,4 @@ man su
# Ссылки
[Adam D. Command-line Tools can be 235x Faster than your Hadoop Cluster] https://adamdrake.com/command-line-tools-can-be-235x-faster-than-your-hadoop-cluster.html
[Adam D. Command-line Tools can be 235x Faster than your Hadoop Cluster] https://adamdrake.com/command-line-tools-can-be-235x-faster-than-your-hadoop-cluster.html

@ -1,11 +1,6 @@
на основе материалов
- Michael Lucas. Networking for System Administrator
- https://www.youtube.com/playlist?list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW
# Сетевые уровни, модель ОСИ
Сеть содержит физические провода или радиоволны, устройства соединения, такие как коммутаторы, логические протоколы, такие как TCPIP, пользовательские веб-страницы и электронные письма и многое другое. коммутаторы, логические протоколы TCP/IP, видимые пользователем веб-страницы и электронные письма, и многое другое. В каком-то смысле все это перемешано в единое целое, но на самом деле для удобства и простоты они разделены на несколько логических уровней. Каждый слой решает вполне конкретную задачу и обычно взаимодействует только со слоями, расположенными непосредственно над и под ним.
Сеть содержит физические провода или радиоволны, устройства соединения, такие как коммутаторы, логические протоколы, такие как TCP/IP, пользовательские веб-страницы и электронные письма и многое другое. В каком-то смысле все это перемешано в единое целое, но на самом деле для удобства и простоты они разделены на несколько логических уровней. Каждый слой решает вполне конкретную задачу и обычно взаимодействует только со слоями, расположенными непосредственно над и под ним.
Системные администраторы часто используют словосочетания "сетевой" или "прикладной" уровни в совершенно другом смысле. Ваше сложное веб-приложение может иметь уровень базы данных, уровень хранилища и уровень веб-сервера. Это совершенно правильное использование слова "слой" и вполне уместное в вашем контексте, но имейте в виду, что сетевые специалисты имеют в виду нечто совершенно иное.
@ -17,20 +12,24 @@
## Уровни
В учебниках часто рассказывается о семиуровневой модели Open Systems Interconnect (OSI), но это скорее академическая, чем реальная модель. TCP/IP гораздо лучше подходит для современных сетей, но ей не хватает некоторых деталей модели OSI. Мы представим TCP/IP в несколько измененной форме, поскольку полезно рассматривать физическую среду отдельно от протокола передачи данных поверх него.
В учебниках часто рассказывается о семиуровневой модели Open Systems Interconnect (OSI), но это скорее академическая, чем реальная модель. TCP/IP гораздо лучше подходит для современных сетей, но ей не хватает некоторых деталей модели OSI. Мы представим TCP/IP в несколько измененной форме, поскольку полезно рассматривать физическую среду отдельно от протокола передачи данных поверх него.
Для понимания современной сети, подключенной к Интернету, необходимо всего пять уровней: физический, канальный, сетевой, транспортный и прикладной. Сетевые уровни часто обозначаются часто обозначают номерами.
Далее в каждой секции приводятся релевантные ссылки на уроки мини-курса Ben Eater для углубления в тему.
### 1 Физический
Сети должны по чему-то перемещаться. Если об него можно споткнуться, зацепиться, отломить дурацкий язычок от пластикового разъема на его конце или передать по нему статическое электричество, то это физический уровень. Многие из нас называют физический уровень проводом, хотя это могут быть и радиоволны, и коаксиальный кабель, и любые другие вещи, отличные от типичного провода Ethernet. Если ваш провод соответствует стандарту, определенному для данного типа физического уровня, у вас есть сеть. Если нет, то сеть работать не будет.
Данные в сети должны по чему-то перемещаться. Если об это можно споткнуться, зацепиться, отломить дурацкий язычок от пластикового разъема на его конце или передать по нему статическое электричество, то это физический уровень. Многие из нас называют физический уровень проводом, хотя это могут быть и радиоволны, и коаксиальный кабель, и любые другие вещи, отличные от типичного провода Ethernet. Если ваш провод соответствует стандарту, определенному для данного типа физического уровня, у вас есть сеть. Если нет, то сеть работать не будет.
Большинство серверов подключаются к сети с помощью кабеля Ethernet, обычно по кабелю cat5 или cat6, но иногда и по оптическому волокну. Даже если сервер использует протокол, отличный от Ethernet, например Asynchronous Transfer Mode (ATM), Token Ring, FDDI или другой, он, скорее всего, использует кабель cat5, cat6 или оптическое волокно. Очень и очень старайтесь не подключать серверы к локальной сети по беспроводной сети. (Беспроводные сети очень подвержены ошибкам и помехам на канальном уровне и могут быть перегружены силами, не зависящими от вас и даже не осознаваемыми вами.
Большинство серверов подключаются к сети с помощью кабеля Ethernet, обычно по кабелю cat5 или cat6, но иногда и по оптическому волокну. Даже если сервер использует протокол, отличный от Ethernet, например Asynchronous Transfer Mode (ATM), Token Ring, FDDI или другой, он, скорее всего, использует кабель cat5, cat6 или оптическое волокно. Очень и очень старайтесь избегать подключения серверов к локальной сети по беспроводной сети. Беспроводные сети сильно подвержены ошибкам и помехам на канальном уровне и могут быть подвержены явлениям, не зависящими от вас и даже не осознаваемыми вами.
Физический уровень традиционно не имеет никакого интеллекта. Канальный уровень определяет, как он используется.
// притащить осциллограф, чтобы показать канальный уровень манчестерское кодирование https://www.youtube.com/watch?v=i8CmibhvZ0c
[Sending digital information over a wire | Networking tutorial (1 of 13)](https://www.youtube.com/watch?v=XaGXPObx2Gs&list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW&index=1)
[Intro to fiber optics and RF encoding | Networking tutorial (2 of 13)](https://www.youtube.com/watch?v=lUo45NqPyq8&list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW&index=2)
[Clock synchronization and Manchester coding | Networking tutorial (3 of 13)](https://www.youtube.com/watch?v=8BhjXqw9MqI&list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW&index=3)
[Analyzing actual Ethernet encoding | Networking tutorial (4 of 13)](https://www.youtube.com/watch?v=i8CmibhvZ0c&list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW&index=4)
### 2 Канальный
@ -38,14 +37,24 @@
Если вы используете протокол IPv4, то на канальном уровне используются адреса Media Access Control (MAC) и протокол разрешения адресов (ARP). В IPv6 используются MAC-адреса и протокол Neighbor Discovery (ND). Если у вас возникли проблемы с обменом данными с локальной сетью, обратитесь к этим главам и проверьте наличие проблем с ARP или ND.
[The importance of framing | Networking tutorial (5 of 13)](https://www.youtube.com/watch?v=xrVN9jKjIKQ&list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW&index=5)
[Frame formats | Networking tutorial (6 of 13)](https://www.youtube.com/watch?v=1XrRT0CmzYw&list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW&index=6)
[Lower layers of the OSI model | Networking tutorial (7 of 13)](https://www.youtube.com/watch?v=MGAaTqFct_I&list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW&index=7)
### 3 Сетевой
Не является ли все это сетью? Да, но сетевой уровень отображает возможности соединения между хостами. Именно здесь система отвечает на вопросы типа "Как мне добраться до этого другого хоста? Могу ли я попасть на этот другой хост?". Сетевой уровень обеспечивает согласованный интерфейс для сетевых программ, чтобы они могли использовать сеть на любом физическом и канальном уровнях. Отдельный фрагмент сетевых данных называется пакетом.
Не является ли все это сетью? Да, но сетевой уровень отражает возможность соединения между хостами. Именно здесь система отвечает на вопросы типа "Как мне добраться до другого хоста? Могу ли я попасть на другой хост?". Сетевой уровень обеспечивает согласованный интерфейс для сетевых программ, чтобы они могли использовать сеть на любом физическом и канальном уровнях. Отдельный фрагмент сетевых данных называется пакетом.
В Интернете используется протокол Internet Protocol, или IP. Это IP в TCP/IP. Во всех версиях IP каждому узлу присваивается один или несколько уникальных IP-адресов, чтобы любой другой узел в сети мог его найти. Трансляция сетевых адресов (NAT) изменяет правило "уникального адреса", но где-то в вашей сети или в сети вашего провайдера у вас есть глобально уникальный IP-адрес.
Мы рассмотрим подробно далее только версию 4.
[The Internet Protocol | Networking tutorial (8 of 13)](https://www.youtube.com/watch?v=rPoalUa4m8E&list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW&index=8)
[ARP: Mapping between IP and Ethernet | Networking tutorial (9 of 13)](https://www.youtube.com/watch?v=aamG4-tH_m8&list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW&index=9)
[Looking at ARP and ping packets | Networking tutorial (10 of 13)](https://www.youtube.com/watch?v=xNbdeyEI-nE&list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW&index=10)
[Hop-by-hop routing | Networking tutorial (11 of 13)](https://www.youtube.com/watch?v=VWJ8GmYnjTs&list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW&index=11)
### 4 Транспортный
Данные, о которых вы заботитесь, передаются на транспортном уровне. Нижние уровни стека существуют для поддержки транспортного уровня. Фрагмент данных транспортного уровня - это сегмент. Три наиболее распространенных протокола транспортного уровня - это протокол управляющих сообщений Интернета (ICMP), протокол управления передачей (TCP) и протокол пользовательских датаграмм (UDP).
@ -55,47 +64,491 @@ ICMP обрабатывает низкоуровневые сообщения о
UDP и TCP обеспечивают передачу прикладных данных между узлами. Они настолько распространены, что набор протоколов Интернета обычно называют TCP/IP. (UDP/TCP/IP слишком громоздки.) UDP, или User Datagram Protocol, предоставляет минимальные услуги, необходимые для передачи данных по сети. Хотя люди шутят, что U в UDP означает "ненадежный", он предназначен для приложений, где надежность обеспечивается приложением, а не сетью. Протокол TCP, или Transmission Control Protocol, включает в себя проверку ошибок, управление перегрузками и повторную передачу потерянных данных, но ему не хватает гибкости и простоты UDP.
### 5 Прикладной (сессионный, представления, приложения)
В заголовке перечислены их названия согласно теоретической модели ОСИ. Сессионный уровень отвечает за открытие, использование и закрытие соединений транспортного уровня. Уровень представления отвечает за обмен данными между приложениями. На уровне приложения работает протокол передачи данных приложения. На практике всё зависит от поставщика приложения, который может реализовать чёткое разделение ответственности по слоям или смешать всё воедино.
Примерами протоколов высших слоёв являются: HTTP, SMTP, LDAP.
# Ethernet
https://www.youtube.com/watch?v=aamG4-tH_m8&list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW&index=9
[TCP: Transmission control protocol | Networking tutorial (12 of 13)](https://www.youtube.com/watch?v=4IMc3CaMhyY&list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW&index=12)
[TCP connection walkthrough | Networking tutorial (13 of 13)](https://www.youtube.com/watch?v=F27PLin3TV0&list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW&index=13)
# IPv4
https://www.youtube.com/watch?v=VWJ8GmYnjTs&list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW&index=11
### 5 Прикладной (сессионный, представления, приложения)
# TCP/IP
В заголовке перечислены их названия согласно теоретической модели ОСИ. Сессионный уровень отвечает за открытие, использование и закрытие соединений транспортного уровня. Уровень представления отвечает за обмен данными между приложениями. На уровне приложения работает протокол передачи данных приложения. На практике всё зависит от поставщика приложения, который может реализовать чёткое разделение ответственности по слоям или смешать всё воедино.
https://www.youtube.com/watch?v=4IMc3CaMhyY&list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW&index=12
Примерами протоколов высших слоёв являются: `HTTP`, `SMTP`, `LDAP`.
[DNS: Why was Facebook down for five hours?](https://www.youtube.com/watch?v=-wMU8vmfaYo&list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW&index=14)
# Работа сети на примере
В данном примере отследим путь ICMP пакета по сети из точки A в точку B с топологией сети изображённой ниже. Рёбра этого графа - провода, а узлы - компьютеры или роутеры. Это также пример автономной системы, например автономная система провайдера. Автономная система - группа сетей, находящихся под административным или политическим контролем одного юридического лица.
```
68:56:35:8e:2c:2d 04:f1:3e:6c:86:ad
192.168.9.2/24 192.168.20.2/24
│ 10.0.13.2┌───┐ │ ┌───┐
┌───┐ │ ┌─────┤ │ ├────┤ B │
│ A ├────┤ │ └───┘ │ └───┘
└───┘ │ │ Уфа │
│ │ │ ┌───┐
┌───┐ │68:56:35:8e:5b:74 │10.0.13.1 ├────┤ │
│ ├────┤ 192.168.9.1/24 ┌─┴─┐ 10.0.15.2┌───┐ 10.0.21.2┌───┐ │ └───┘
└───┘ ├─────────────────┤ ├──────────────┤ ├─────────────────────────┤ ├───────────────┤
│ └───┘10.0.15.1 └─┬─┘10.0.21.1 └─┬─┘192.168.20.1/24│ ┌───┐
┌───┐ │ Самара │ │ ├────┤ │
│ ├────┤ │ 10.0.16.2 ┌───┐ 10.0.8.2│ │ └───┘
└───┘ │ └────────────┤ ├────────────┘ │
│ 10.0.16.1 └───┘10.0.8.1 │ ┌───┐
│ Москва Рыбинск Питер |────┤ │
| | └───┘
Ethernet сеть 1 (4 хоста) Ethernet network 2 (5 хостов)
```
Как мы можем отправить информацию от хоста A хосту B? Рассмотрим что произойдёт при запуске команды ping.
### Ethernet
При настройке сетевой карты в системе заполняются 3 параметра: ip адрес хоста, ip адрес шлюза, маска сети. Маска сети - общие первые N бит адреса для хостов сети. Когда пакет посылается хосту B хост A видит, что первые N бит этого адреса отличаются от первых N бит его адреса из локальной сети, и отправляет ethernet пакет c ip пакетом внутри шлюзу. Шлюз - это узел, подключенный к нескольким сетям.
Кадр Ethernet начинается со специальной последовательности Preamble/SFD, которая позволяет принимающей стороне однозначно определить с какого бита в канале связи начинается пакет.
Затем следует MAC адрес назначения. В случае если адрес назначения неизвестен, кадр может быть адресован всем устройствам в локальной сети по адресу ffffffffffff.
Пример заголовка Ethernet кадра для широковещательного запроса - поле Destination Address заполняется единицами.
```
| Preamble/SFD | Destination Address | Source Address | Ether Type | Payload | Frame check sequence |
|--------------|---------------------|----------------|-------------------|---------|----------------------|
| 1010....1011 | ffffffffffff | 6856358e2c2d | 0806 (ARP packet) | | |
```
Чтобы отправить ethernet пакет шлюзу, нужно знать его MAC адрес. Для поиска устройства в локальной сети с заданным IP адресом используется ARP (address resolution protocol) протокол. В сети может быть два типа ARP пакетов: широковещательный запрос с просьбой ответить на вопрос "У кого назначен 192.168.9.1?".
Пример заголовка ARP сообщения (помещается в Payload Ethernet кадра) для установки соответствия между Ethernet адресом и IP адресом
```
| HW Address Type | Protocol Addr Type | HW Address Length | Protocol Addr Len | OP Code |
|-----------------|--------------------|-------------------|-------------------|------------------------------------|
| 1 (Ethernet) | 0800 (IP) | 6 (для Ethernet) | 4 (для IP) | 1 (2 для ответа) |
| Hadrware Address of Sender | Protocol Address of Sender | Hardware Address of Target | Protocol Address of Target |
|----------------------------|----------------------------|----------------------------|----------------------------|
| 6856358e2c2d | 192.168.9.2 | 000000000000 | 192.168.9.1 |
```
При запросе поле "Hardware Address of Target" заполняется нулями, а в ARP ответе хост A получит "68:56:35:8e:5b:74". Получив ответ, хост A с этого момента может отправлять ip пакеты шлюзу для его дальнейшей маршрутизации.
Источники:
- https://datatracker.ietf.org/doc/html/rfc894
- https://www.youtube.com/watch?v=aamG4-tH_m8&list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW&index=9
### IP
Хорошо, мы понимаем пакет найдёт путь по локальной Ethernet сети до роутера. Как ему достичь другой Ethernet сети на другом конце интернета?
Для начала подготовим ICMP пакет к отправке. Для этого заполним следующие поля.
ICMP Header (Protocol code = 1)
```
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| unused / Pointer / Gateway Internet Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Internet Header + 64 bits of Original Data Datagram |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
```
ICMP пакет будет вложен в IP пакет, который будет вложен в Ethernet пакет. Однако это не значит, что размер IP пакета должен быть меньше Ethernet пакета. В случае превышения MTU (размера Ethernet пакета), IP пакет будет фрагментирован на несколько Ethernet пакетов.
IP заголовок
```
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL |Type of Service| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
```
Пример заголовка Ethernet кадра для передачи IP пакета.
```
| Preamble/SFD | Destination Address | Source Address | Ether Type | Payload | Frame check sequence |
|--------------|---------------------|----------------|-------------------|---------|----------------------|
| | ffffffffffff | 6856358e2c2d | 0800 (IP packet) | | |
```
Задача сетевого уровня обеспечить маршрутизацию пакета от компьютера одной локальной сети до компьютера другой не зависимо от технологий, используемых в локальных сетях. Для этого компьютерам назначается глобальный IP адрес. Количество хостов в IPv4 2^32. Количество хостов в IPv6 2^128. Чтобы эффективно маршрутизировать пакеты между сетями адресное пространство в начале был разделено на блоки разного разметра, называемые классами. Это означало, что первые N бит характеризовали сеть, а оставшиеся хост в сети. Однако фиксированное разделение приводило к неэффективному расходованию адресов, поэтому вскоре вышел стандарт бесклассовой адресации CIDR, который позволял владельцам уже имеющим большие блоки адресов делить их самостоятельно на подсети с помощью маски подсети, которая состояля из единиц в первых N битах.
Чтобы проложить маршрут роутеры между двумя локальными сетями обмениваются информацией, наподобие того как обнаруживают другу друга компьютеры в локальной сети. После обмена информацией о сетях (ip адреса портов роутера с масками подсетей) каждый роутер формирует таблицу маршрутизации. Протоколы маршрутизации внутри автономных систем:
- RIP,
- OSPF,
- EIGRP.
Существует также возможность внести маршрут в данную таблицу вручную.
Таблица говорит, о том какие сети существуют за каждым подключенным портом. Так что, пакет попавший на роутер Самара на порт 1 слева согласно таблице отправляется на порт 2 справа. Аналогичное действие происходит на каждом роутере в цепи Самара-Москва-Питер, пока пакет не попадёт в целевую локальную Ethernet сеть 192.168.20.0. Hop-by-hop маршрутизация фундаметальная характеристика сетевого слоя и IP протокола.
Глобальная сеть Интернет объединяет множество автономных систем. Специфика масштаба маршрутизации между АС требует использования другого оборудования и других протоколов маршрутизации между автономными системами. В данный момент используется в основном BGP.
ICMP используется не только для проверки доступности хостов командой `ping`. Это все возможные типы сообщений и их коды:
- Destination Unreachable Message (3)
- Source Quench Message (4)
- Redirect Message (5)
- Echo or Echo Reply Message (8)
- Time Exceeded Message (11)
- Parameter Problem Message (12)
- Timestamp or Timestamp Reply Message (14)
- Information Request/Information Reply Message (15/16)
Источники:
- IP RFC https://www.ietf.org/rfc/rfc792.txt
- ICMP RFC https://www.ietf.org/rfc/rfc792.txt
- https://www.youtube.com/watch?v=VWJ8GmYnjTs&list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW&index=11
# Передача данных приложений по сети
Иерархия протоколов
```
+------+ +-----+ +-----+ +-----+
|Telnet| | FTP | |Voice| ... | | Application Level
+------+ +-----+ +-----+ +-----+
| | | |
+-----+ +-----+ +-----+
| TCP | | RTP | ... | | Host Level
+-----+ +-----+ +-----+
| | |
+-------------------------------+
| Internet Protocol & ICMP | Gateway Level
+-------------------------------+
|
+---------------------------+
| Local Network Protocol | Network Level
+---------------------------+
Protocol Relationships
```
Для передачи пользовательских нужно подняться на один уровень выше, на транспортный уровень, до протоколов TCP и UDP.
Протокол TCP является протоколом ориентированным на потоки бит и как следствие требует установки соединения перед передачей данных, разбиение потока бит на пакеты и восстановления потока на принимающей стороне. А это в свою очередь требует от протокола буферизации и сортировки на принимающей стороне, а также детектирования пропущенных пакетов и механизма повторной отправки для таких случаев. Всё это делает протокол более надёжным, но требует дополнительных накладных расходов на контроль за доставкой. Механизм повторной отправки также может привести усугублению ситуации в сети, если пакеты не доставляются из-за перегрузки оборудования большим количеством пакетов.
Протокол UDP является протоколом без гарантии доставки. Используется при доставке аудио и видео данных, так как отдельные потерянные пакеты не сильно влияют на опыт использования, а отстуствие инициализации соединения и контроля за доставкой приводит к меньшим задержкам.
## UDP
Протокол User Datagram Protocol (UDP) определен для обеспечения дейтаграммного режима передачи данных с коммутацией пакетов в наборе взаимосвязанных компьютерных сетей. Протокол предполагает, что в качестве базового протокола используется протокол Internet Protocol (IP).
Этот протокол предоставляет прикладным программам процедуру отправки сообщений другим программам с минимальным использованием протокольного механизма. Протокол ориентирован на транзакции, поэтому доставка и защита от дублирования не гарантируются. Приложения, требующие упорядоченной надежной доставки потоков данных, должны использовать протокол управления передачей (TCP).
UDP header
```
0 7 8 15 16 23 24 31
+--------+--------+--------+--------+
| source address |
+--------+--------+--------+--------+
| destination address |
+--------+--------+--------+--------+
| zero |protocol| UDP length |
+--------+--------+--------+--------+
0 7 8 15 16 23 24 31
+--------+--------+--------+--------+
| Source | Destination |
| Port | Port |
+--------+--------+--------+--------+
| | |
| Length | Checksum |
+--------+--------+--------+--------+
|
| data octets ...
+---------------- ...
```
Второй псевдозаголовок концептуально является префиксом к заголовку UDP и содержит адрес источника, адрес назначения, протокол и длину UDP. Эта информация обеспечивает защиту от ошибочной маршрутизации дейтаграмм. Эта процедура контрольной суммы аналогична той, что используется в TCP.
Источники:
- UDP RFC https://www.ietf.org/rfc/rfc768.txt
## TCP
Приведём подробнее формат заголовка TCP пакета.
TCP header (ethernet protocol code = 6)
```
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Acknowledgment Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data | |U|A|P|R|S|F| |
| Offset| Reserved |R|C|S|S|Y|I| Window |
| | |G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
```
Поддержание TCP-соединения требует запоминания нескольких переменных. Эти переменные хранятся в записи соединения, называемой блоком управления передачей или TCB.
Диаграмма установки соединения
```
+---------+ ---------\ active OPEN
| CLOSED | \ -----------
+---------+<---------\ \ create TCB
| ^ \ \ snd SYN
passive OPEN | | CLOSE \ \
------------ | | ---------- \ \
create TCB | | delete TCB \ \
V | \ \
+---------+ CLOSE | \
| LISTEN | ---------- | |
+---------+ delete TCB | |
rcv SYN | | SEND | |
----------- | | ------- | V
+---------+ snd SYN,ACK / \ snd SYN +---------+
| |<----------------- ------------------>| |
| SYN | rcv SYN | SYN |
| RCVD |<-----------------------------------------------| SENT |
| | snd ACK | |
| |------------------ -------------------| |
+---------+ rcv ACK of SYN \ / rcv SYN,ACK +---------+
| -------------- | | -----------
| x | | snd ACK
| V V
| CLOSE +---------+
| ------- | ESTAB |
| snd FIN +---------+
| CLOSE | | rcv FIN
V ------- | | -------
+---------+ snd FIN / \ snd ACK +---------+
| FIN |<----------------- ------------------>| CLOSE |
| WAIT-1 |------------------ | WAIT |
+---------+ rcv FIN \ +---------+
| rcv ACK of FIN ------- | CLOSE |
| -------------- snd ACK | ------- |
V x V snd FIN V
+---------+ +---------+ +---------+
|FINWAIT-2| | CLOSING | | LAST-ACK|
+---------+ +---------+ +---------+
| rcv ACK of FIN | rcv ACK of FIN |
| rcv FIN -------------- | Timeout=2MSL -------------- |
| ------- x V ------------ x V
\ snd ACK +---------+delete TCB +---------+
------------------------>|TIME WAIT|------------------>| CLOSED |
+---------+ +---------+
```
Временная диаграмма установки соединения, передачи данных и закрытия соединения
```
Клиент Сервер
192.168.9.2:1234 192.168.20.2:80
│ SYN seq=0 │
├──────────────────►│
│ │
│ SYN,ACK=1 seq=0 │ УСТАНОВКА
│◄──────────────────┤ СОЕДИНЕНИЯ
│ │
│ ACK=1 seq=1 │
├──────────────────►│
│ │
│───────────────────┼───────────────
│ │
│ пакет с данными │
│ длиной 22 байта │
│ seq=1 │ ПЕРЕДАЧА
│◄──────────────────┤ ДАННЫХ
│ │
│ ACK=1 seq=23 │
├──────────────────►│
│ │
│───────────────────┼────────────────
│ │
│ FIN,ACK=1 seq=23 │
│◄──────────────────┤
│ │
│ ACK=24 seq=1 │
├──────────────────►│ ЗАКРЫТИЕ
│ │ СОЕДИНЕНИЯ
│ FIN,ACK=24 seq=1 │
│──────────────────►│
│ │
│ ACK=2 seq=24 │
│◄──────────────────┤
│ │
│ │
v v
```
Попробуйте получить похожий лог для любого TCP соединения у себя на хосте с помощью утилит `tcpdump` или `wireshark`.
Источники:
- TCP RFC https://www.ietf.org/rfc/rfc793.txt
- https://www.youtube.com/watch?v=4IMc3CaMhyY&list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW&index=12
# DHCP
Кто назначает IP адреса на сетевые порты?
Администратор может назначить их вручную или автоматически с помощью DHCP.
DHCP предназначен для предоставления DHCP-клиентам параметров конфигурации, определенных в RFC «Требования к хосту». После получения параметров через DHCP клиент DHCP должен иметь возможность обмениваться пакетами с любым другим хостом в Интернете.
DHCP состоит из двух компонентов: протокола для доставки специфичных для хоста параметров конфигурации от DHCP-сервера к хосту и механизма выделения сетевых адресов хостам.
Временная диаграмма автоматического получения IP адреса.
```
Server Client Server
(not selected) (selected)
v v v
| | |
| Begins initialization |
| | |
| _____________/|\____________ |
|/DHCPDISCOVER | DHCPDISCOVER \|
| | |
Determines | Determines
configuration | configuration
| | |
|\ | ____________/|
| \________ | /DHCPOFFER |
| DHCPOFFER\ |/ |
| \ | |
| Collects replies |
| \| |
| Selects configuration |
| | |
| _____________/|\____________ |
|/ DHCPREQUEST | DHCPREQUEST\ |
| | |
| | Commits configuration
| | |
| | _____________/|
| |/ DHCPACK |
| | |
| Initialization complete |
| | |
. . .
. . .
| | |
| Graceful shutdown |
| | |
| |\ ____________ |
| | DHCPRELEASE \|
| | |
| | Discards lease
| | |
v v v
```
Источники:
- https://www.rfc-editor.org/rfc/rfc2131
# DNS
https://www.youtube.com/watch?v=-wMU8vmfaYo&list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW&index=14
Основная функция DNS хранить связь между IP адресом и человеко-читаемым именем. DNS система - это распределённая база данных.
Хост может участвовать в системе доменных имен несколькими способами: в зависимости от того, запускает ли хост программы, извлекающие информацию из доменной системы, серверы имен, отвечающие на запросы других хосты или различные комбинации обеих функций.
Схема работы DNS с точки зрения клиентского хоста:
```
Локальный хост | Хосты сети
|
+---------+ +----------+ | +--------+
| | user queries | |queries | | |
| User |-------------->| |---------|->|Foreign |
| Program | | Resolver | | | Name |
| |<--------------| |<--------|--| Server |
| | user responses| |responses| | |
+---------+ +----------+ | +--------+
| A |
cache additions | | references |
V | |
+----------+ |
| cache | |
+----------+ |
```
Пользовательские программы взаимодействуют с пространством доменных имен через Resolver. Формат пользовательских запросов и ответов зависит от хоста и его операционной системы. Пользовательские запросы обычно представляют собой вызовы операционной системы, а Resolver и его кэш являются частью операционной системы хоста. Resolver отвечают на запросы пользователей информацией, которую они получают посредством запросов к внешним серверам имен и локальному кешу.
Схема работы сервера имён:
```
Локальный хост | Хосты сети
|
+---------+ |
/ /| |
+---------+ | +----------+ | +--------+
| | | | |responses| | |
| | | | Name |---------|->|Foreign |
| Master |-------------->| Server | | |Resolver|
| files | | | |<--------|--| |
| |/ | | queries | +--------+
+---------+ +----------+ |
A |maintenance | +--------+
| +------------|->| |
| queries | |Foreign |
| | | Name |
+------------------|--| Server |
maintenance responses | +--------+
```
Таблица 1. Типы записей сервера имён
|TYPE| value | meaning|
|---|---|----|
|A |1 |a host address|
|NS |2 |an authoritative name server|
|MD |3 |a mail destination (Obsolete - use MX)|
|MF |4 |a mail forwarder (Obsolete - use MX)|
|CNAME |5 |the canonical name for an alias|
|SOA |6 |marks the start of a zone of authority|
|MB |7 |a mailbox domain name (EXPERIMENTAL)|
|MG |8 |a mail group member (EXPERIMENTAL)|
|MR |9 |a mail rename domain name (EXPERIMENTAL)|
|NULL |10| a null RR (EXPERIMENTAL)|
|WKS |11| a well known service description|
|PTR |12| a domain name pointer|
|HINFO |13| host information|
|MINFO |14| mailbox or mail list information|
|MX |15| mail exchange|
|TXT |16| text strings|
Проект, в котором можно поэкспериментировать с DNS https://messwithdns.net/.
Источники:
- https://datatracker.ietf.org/doc/html/rfc1035
- https://www.youtube.com/watch?v=-wMU8vmfaYo&list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW&index=14
# Troubleshooting
Таблица 1. Утилиты
Таблица 1. Утилиты для отладки проблем с сетью
| Уровень | Название утилит |
|---------|-----------------|
| 1 Физический | |
| 2 Канальный | |
| 3 Сетевой | |
| 4 Транспортный | |
| 5 Прикладной (сессионный, представления, приложения) | |
| 1 Физический | лампочка порта, ip/ipconfig/ifconfig, замена кабеля |
| 2 Канальный | arp, ND, tcpdump, arpping |
| 3 Сетевой | ip, traceroute, ping, netstat, nmap, ss, SmokePing, iperf, ipcalc |
| 4 Транспортный | netstat, ss, telnet, ifstat |
| 5 Прикладной (сессионный, представления, приложения) | telnet, nmap, curl, wget, postman |
### 1 Физический
### 2 Канальный
### 3 Сетевой
### 4 Транспортный
### 5 Прикладной (сессионный, представления, приложения)
Источники:
- Michael Lucas. Networking for System Administrator
- https://www.youtube.com/playlist?list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW
- https://www.brendangregg.com/linuxperf.html

@ -1,58 +0,0 @@
# Задание 1
0. Узнайте статус сервиса systemd-networkd.
```
# systemctl status systemd-networkd
```
1. Активируйте systemd-networkd, если он не активирован (disabled).
```
# systemctl enable systemd-networkd
```
2. Запустите systemd-networkd, если он не запущен (inactive, dead).
```
# systemctl start systemd-networkd
```
3. Определите имя настраиваемого интерфейса.
```
# ip link
```
4. Для настройки интерфейса ens18 машин stud1-1v1 и stud1-2v1 создайте
или отредактируйте в каждой /etc/systemd/network/ens18.network.
конфигурация ens18.network машины stud1-1v1
```
[Match]
Name=ens18
[Network]
Address=192.168.1.1/24
```
конфигурация ens18.network машины stud1-2v1
```
[Match]
Name=ens18
[Network]
Address=192.168.1.2/24
```
5. Перечитайте конфигурацию сети на обеих машинах.
```
# networkctl reload
```
6. После конфигурации на обеих машинах проверьте их взаимную доступность по сети.
```
stud@stud1-2v1$ ping 192.168.1.1
stud@stud1-1v1$ ping 192.168.1.2
```
7. В случае проблемы, проверьте, что systemd-networkd запущен и в его логах нет ошибок.
```
# systemctl status systemd-networkd
```

@ -1,64 +0,0 @@
# Задание 2
0. Узнайте статус сервиса systemd-networkd.
```
# systemctl status systemd-networkd
```
1. Активируйте systemd-networkd, если он не активирован (disabled).
```
# systemctl enable systemd-networkd
```
2. Запустите systemd-networkd, если он не запущен (inactive, dead).
```
# systemctl start systemd-networkd
```
3. Определите имя настраиваемого интерфейса (не loopback).
```
# ip link
```
4. Для настройки интерфейса ens18 машин stud1-1v1 и stud1-2v1 создайте
или отредактируйте в каждой /etc/systemd/network/ens18.network.
конфигурация ens18.network машины stud1-1v1 с DHCP сервером.
```
[Match]
Name=ens18
[Network]
Address=192.168.1.1/24
DHCPServer=yes
```
конфигурация ens18.network машины stud1-2v1, которая получает адрес от DHCP сервера.
```
[Match]
Name=ens18
[Network]
DHCP=yes
```
5. Перечитайте конфигурацию сети на обеих машинах.
```
# networkctl reload
```
6. После конфигурации на обеих машинах проверьте их взаимную доступность по сети.
На машине stud1-2v1 определите выданный DHCP сервером ip адрес для интерфейса ens18.
```
ip a
```
```
stud@stud1-2v1$ ping 192.168.1.1
stud@stud1-1v1$ ping 192.168.1.X
```
7. В случае проблемы, проверьте, что systemd-networkd запущен и в его логах нет ошибок.
```
# systemctl status systemd-networkd
```

@ -1,76 +0,0 @@
# Задание 3
0. Узнайте статус сервиса `systemd-networkd` и `systemd-resolved`
```
# systemctl status systemd-networkd
# systemctl status systemd-resolved
```
1. Активируйте `networkd`, если он не активирован (disabled)
```
# systemctl enable systemd-networkd
# systemctl enable systemd-resolved
```
2. Запустите `networkd`, если он не запущен (inactive, dead)
```
# systemctl start systemd-networkd
# systemctl start systemd-resolved
```
3. Определите имя настраиваемого интерфейса (не loopback).
```
# ip link
```
4. Для настройки интерфейса `ens18` машины `stud1-2v1` создайте
или отредактируйте в каждой `/etc/systemd/network/ens18.network`.
Адрес машины взят из такой сети, в которой присутствует шлюз в
интернет `10.160.179.1`.
конфигурация ens18.network машины stud1-2v1
```
[Match]
Name=ens18
[Network]
Address=10.160.179.201/24
Gateway=10.160.179.1
```
5. Перечитайте конфигурацию сети
```
# networkctl reload
```
6. Проверьте доступность ip-адреса в сети internet
```
stud@stud1-2v1$ ping 1.1.1.1
```
7. Для настройки DNS `ens18` машины `stud1-2v1` отредактируйте
/etc/systemd/resolved.conf.
конфигурация `resolved.conf` машины `stud1-2v1`
```
[Resolve]
DNS=1.1.1.1
```
8. Перезагрузите `systemd-resolved`
```
# systemctl restart systemd-resolved
```
9. Проверьте доступность адреса по имени
```
stud@stud1-2v1$ ping yandex.ru
```
10. В случае проблемы, проверьте, что systemd-networkd запущен,
systemd-resolved запущен, DNS настроен.
```
# systemctl status systemd-networkd
# systemctl status systemd-resolved
# resolvectl status
```

@ -0,0 +1,59 @@
# Задание 1
Для виртуальных машин `studX-net1` и `studX-net2` настройте статический адрес в помощью `systemd` в подсети `192.168.0.0/24`. Используйте команду `networkctl` и файлы настроек `/etc/systemd/network/ens18.network`. Проверьте, что машины видят друг друга с помощью команды `ping IP-адрес-соседней-машины`.
0. Узнайте статус сервиса `systemd-networkd`.
```
# systemctl status systemd-networkd
```
1. Активируйте `systemd-networkd`, если он не активирован (disabled).
```
# systemctl enable systemd-networkd
```
2. Запустите `systemd-networkd`, если он не запущен (inactive, dead).
```
# systemctl start systemd-networkd
```
3. Определите имя настраиваемого интерфейса.
```
# ip link
```
4. Для настройки интерфейса `ens18` машин `stud1-net1` и `stud1-net2` создайте или отредактируйте в каждой `/etc/systemd/network/ens18.network`.
конфигурация `ens18.network` машины `stud1-net1`
```
[Match]
Name=ens18
[Network]
Address=192.168.0.2/24
```
конфигурация `ens18.network` машины `stud1-net2`
```
[Match]
Name=ens18
[Network]
Address=192.168.0.3/24
```
5. Перечитайте конфигурацию сети на обеих машинах.
```
# networkctl reload
```
6. После конфигурации на обеих машинах проверьте их взаимную доступность по сети.
```
stud@stud1-net1$ ping 192.168.0.3
stud@stud1-net2$ ping 192.168.0.2
```
7. В случае проблемы, проверьте, что `systemd-networkd` запущен и в его логах нет ошибок.
```
# systemctl status systemd-networkd
```

@ -0,0 +1,92 @@
# Задание 2
На машине `studX-net1` настройте в подсети `192.168.0.0/24` DHCP сервер в файле `/etc/systemd/network/ens18.network`. На другой машине `studX-net2` настройте получение IP адреса по DHCP. Проверьте, что машины видят друг друга.
0. Узнайте статус сервиса `systemd-networkd`.
```
# systemctl status systemd-networkd
```
1. Активируйте `systemd-networkd`, если он не активирован (disabled).
```
# systemctl enable systemd-networkd
```
2. Запустите systemd-networkd, если он не запущен (inactive, dead).
```
# systemctl start systemd-networkd
```
3. Определите имя настраиваемого интерфейса (не loopback).
```
# ip link
```
4. Для настройки интерфейса `ens18` машин `stud1-net1` и `stud1-net2` создайте
или отредактируйте в каждой` /etc/systemd/network/ens18.network`.
конфигурация `ens18.network` машины `stud1-net1` с DHCP сервером.
```
[Match]
Name=ens18
[Network]
Address=192.168.0.2/24
DHCPServer=yes
[DHCPServer]
EmitDNS=yes
DNS=1.1.1.1
EmitRouter=yes
Router=192.168.0.1
PoolOffset=1
PoolSize=252
```
Такой DHCP сервер будет выдавать новым устройствам IP из диапазона 192.168.0.[3-255], адрес шлюза и DNS сервер. При этом, сам машина с DHCP сервером не будет иметь доступ в интернет (у неё не будет шлюза и DNS адреса).
конфигурация `ens18.network` машины `stud1-net2`, которая получает адрес от DHCP сервера.
```
[Match]
Name=ens18
[Network]
DHCP=yes
```
5. Перечитайте конфигурацию сети на обеих машинах.
```
# networkctl reload
```
6. На машине `stud1-net2` определите выданный DHCP сервером ip адрес для интерфейса `ens18`.
```
ip a
```
Срок, на который выдан адрес можно посмотреть командой `ip` в поле `valid_lft`:
```
ip -4 address show ens18
```
а в логах увидеть факт получения адреса
```
journalctl --unit=systemd-networkd
```
После конфигурации на обеих машинах проверьте их взаимную доступность по сети.
```
stud@stud1-net2$ ping 192.168.0.2
stud@stud1-net1$ ping 192.168.0.X
```
7. В случае проблемы, проверьте, что `systemd-networkd` запущен и в его логах нет ошибок на обоих машинах.
```
# systemctl status systemd-networkd
```
Изучите логи модуля `systemd-networkd` на ошибки
```
journalctl --unit=systemd-networkd
```
Обратитесь к секциям `[Network]`, `[DHCPServer]` в странице мануала `systemd.network`. Для быстрого поиска можете использовать `/`, по аналогии с поиском в vim. Проверьте настройки `ens18.network` на ошибки.

@ -0,0 +1,51 @@
# Задание 3
На машине `studX-net1` настройте доступ в интернет. В качестве шлюза используйте адрес `192.168.0.1`.
1. Узнайте статус сервиса `systemd-networkd`
```
# systemctl status systemd-networkd
```
2. Активируйте `system-networkd`, если он не активирован (disabled)
```
# systemctl enable systemd-networkd
```
3. Запустите `system-networkd`, если он не запущен (inactive, dead)
```
# systemctl start systemd-networkd
```
4. Определите имя настраиваемого интерфейса (не loopback).
```
# ip link
```
5. Для настройки интерфейса `ens18` машины `stud1-net1` создайте или отредактируйте в каждой `/etc/systemd/network/ens18.network`.
конфигурация `ens18.network` машины `stud1-net1`
```
[Match]
Name=ens18
[Network]
Address=192.168.0.2/24
Gateway=192.168.0.1
```
6. Перечитайте конфигурацию сети
```
# networkctl reload
```
7. Проверьте доступность ip-адреса в сети internet
```
stud@stud1-net1$ ping 1.1.1.1
```
Наличие маршрута в интернет покажет команда
```
> ip route
default via 192.168.0.1 dev ens18 ...
```

@ -0,0 +1,46 @@
# Задание 4
Настройте DNS сервер на виртуальной машине. Пример адреса DNS - `1.1.1.1`.
1. Узнайте статус сервиса `systemd-resolved`
```
# systemctl status systemd-resolved
```
2. Активируйте `systemd-resolved`, если он не активирован (disabled)
```
# systemctl enable systemd-resolved
```
3. Запустите `systemd-resolved`, если он не запущен (inactive, dead)
```
# systemctl start systemd-resolved
```
4. Для настройки DNS `ens18` машины `stud1-net1` добавьте поле `DNS` в `/etc/systemd/system/ens18.network`.
```
[Match]
Name=ens18
[Network]
Address=192.168.0.2/24
Gateway=192.168.0.1
DNS=1.1.1.1
```
5. Перечитайте конфигурацию сети
```
# networkctl reload
```
6. Проверьте доступность адреса по имени
```
stud@stud1-2v1$ ping yandex.ru
```
7. В случае проблемы, проверьте, что `systemd-networkd` запущен, `systemd-resolved` запущен, DNS настроен.
```
# systemctl status systemd-networkd
# systemctl status systemd-resolved
# resolvectl status
```

@ -1,5 +1,4 @@
# Задание 4
# Задание 5
```
tcpdump arp -i ens18
tcpdump icmp -i ens18

@ -1,23 +1,23 @@
# Задание 1
Для виртуальных машин `studX-1vX` и `studX-2vX` настройте статический адрес в помощью `systemd` в подсети `192.168.Х.0/24`. Используйте команду `networkctl` и файлы настроек `/etc/systemd/network/ens18.network`. Проверьте, что машины видят друг друга с помощью команды `ping IP-адрес-соседней-машины`.
Для виртуальных машин `studX-net1` и `studX-net2` настройте статический адрес в помощью `systemd` в подсети `192.168.0.0/24`. Используйте команду `networkctl` и файлы настроек `/etc/systemd/network/ens18.network`. Проверьте, что машины видят друг друга с помощью команды `ping IP-адрес-соседней-машины`.
# Задание 2
На машине `studX-1vX` настройте в подсети `192.168.X.0/24` DHCP сервер в файле `/etc/systemd/network/ens18.network`. На другой машине `studX-2vX` настройте получение IP адреса по DHCP. Проверьте, что машины видят друг друга.
На машине `studX-net1` настройте в подсети `192.168.0.0/24` DHCP сервер в файле `/etc/systemd/network/ens18.network`. На другой машине `studX-net2` настройте получение IP адреса по DHCP. Проверьте, что машины видят друг друга.
# Задание 3
На машине `studX-1vX` настройте доступ в интернет. В настройках Hardware измените Network Device на `vmbr499`, перейдя таким образом в другую `vlan`. В качестве шлюза используйте адрес `10.160.179.1`. В качестве адреса возьмите `10.160.179.200`, прибавив `X` к последнему октету.
На машине `studX-net1` настройте доступ в интернет. В качестве шлюза используйте адрес `192.168.0.1`.
# Задание 4
Настройте DNS сервер на виртуальной машине `studX-net1`. Пример адреса DNS - `1.1.1.1`.
# Задание 5
Запустите прослушивание пакетов на некоторое время в сети на одной из машин командой tcpdump. Какие типы пакетов вы перехватили? Отфильтруйте ARP пакеты, ICMP пакеты, TCP пакеты.
Связанные с заданием страницы документации man:
- systemd.network
- networkctl
- systemd-networkd
- systemd-resolved
- resolved.conf
- systemctl

@ -1,13 +1,13 @@
# Задание 1
0. Если у вас есть машина с графической оболочкой, в консоли перейдите в уровень запуска multi-user.target без перезагрузки, а затем обратно graphical.target.
1. Если у вас есть машина с графической оболочкой, в консоли перейдите в уровень запуска `multi-user.target` без перезагрузки, а затем обратно `graphical.target`.
```
# systemctl isolate multi-user.target
# systemctl isolate graphical.target
```
1. Если у вас есть машина с графической оболочкой, перейдите в уровень запуска multi-user.target с перезагрузкой, а затем переключитесь в графическую оболочку обратно.
2. Если у вас есть машина с графической оболочкой, перейдите в уровень запуска `multi-user.target` с перезагрузкой, а затем переключитесь в графическую оболочку обратно.
```
# systemctl set-default multi-user.target
# reboot
@ -15,17 +15,17 @@
# reboot
```
2. Выведите модуль, который активируется по-умолчанию.
3. Выведите модуль, который активируется по-умолчанию.
```
# systemctl get-default
```
3. Выведите возможные состояния модулей командой systemctl --state=help.
4. Выведите возможные состояния модулей командой `systemctl --state=help`.
```
# systemctl --state=help
```
4. Найдите в man странице какие типы модулей есть в systemd.
5. Найдите в man странице какие типы модулей есть в `systemd`.
```
# man systemctl
The following unit types are available:
@ -45,72 +45,72 @@
11. Scope units are similar to service units, but manage foreign processes instead of starting them as well. See systemd.scope(5).
```
5. Выведите список установленных модулей.
6. Выведите список установленных модулей.
```
# systemctl list-unit-files
```
6. Деактивируйте сервис timesyncd.
7. Деактивируйте сервис `systemd-timesyncd`.
```
# systemctl disable systemd-timesyncd
```
7. Перезагрузите сервис timesyncd.
8. Перезагрузите сервис `systemd-timesyncd`.
```
# systemctl restart systemd-timesyncd
```
8. Выведите список модулей в памяти.
9. Выведите список модулей в памяти.
```
# systemctl disable systemd-timesyncd
```
9. Проверьте, что сервис timesyncd активирован.
10. Проверьте, что сервис `systemd-timesyncd` активирован.
```
# systemctl is-enabled systemd-timesyncd
```
10. Выведите список зависимых модулей для сервиса timesyncd.
11. Выведите список зависимых модулей для сервиса `systemd-timesyncd`.
```
# systemctl list-dependencies systemd-timesyncd
```
11. Выведите список сокетов в памяти.
12. Выведите список сокетов в памяти.
```
# systemctl list-sockets
```
12. Выведите список таймеров в памяти.
13. Выведите список таймеров в памяти.
```
# systemctl list-timers
```
13. Проверьте статус сервиса timesyncd.
14. Проверьте статус сервиса `systemd-timesyncd`.
```
# systemctl status systemd-timesyncd
```
14. Проверьте, что сервис timesyncd активен.
15. Проверьте, что сервис `systemd-timesyncd` активен.
```
# systemctl is-active systemd-timesyncd
```
15. Выведите список свойств модуля.
16. Выведите список свойств модуля.
```
# systemctl show systemd-timesyncd
```
16. Выведите уровень логирования для сервиса timesyncd.
17. Выведите уровень логирования для сервиса `systemd-timesyncd`.
```
# systemctl service-log-level systemd-timesyncd
```
17. Перезагрузите конфигурацию systemd менеджера: перезапустите генераторы (systemd.generator), все модули и перестройте дерево зависимостей.
18. Перезагрузите конфигурацию systemd менеджера: перезапустите генераторы (systemd.generator), все модули и перестройте дерево зависимостей.
```
# systemctl daemon-reload
```
18. Какие префиксы можно использовать при указании исполняемых файлов в файлах .service.
19. Какие префиксы можно использовать при указании исполняемых файлов в файлах .service.
```
# man systemd.service
Table 1. Special executable prefixes
@ -195,7 +195,7 @@ Table 1. Special executable prefixes
# systemctl edit socksproxy --full --force
```
содержимое /etc/systemd/system/socksproxy.service
содержимое `/etc/systemd/system/socksproxy.service`
```
[Unit]
Description=SocksProxy
@ -221,6 +221,4 @@ WantedBy=multi-user.target
# netstat -tulpn
```
5. Определите свой внешний IP адрес на сайте https://2ip.ru/,
предварительно настроив в firefox плагине foxyproxy прокси сервер socks5
с адресом 193.32.63.170 + X к последнему октету, где X идентификатор stud.
5. Определите свой внешний IP адрес на сайте http://2ip.ru/, предварительно настроив в firefox плагине foxyproxy прокси сервер socks5 с адресом 193.32.63.170 + X к последнему октету, где X ваш идентификатор из studX.

@ -2,37 +2,37 @@
### Задание 1. Команды
0. Если у вас есть машина с графической оболочкой, в консоли перейдите в уровень запуска multi-user.target без перезагрузки, а затем обратно graphical.target.
1. Если у вас есть машина с графической оболочкой, перейдите в уровень запуска multi-user.target с перезагрузкой, а затем переключитесь в графическую оболочку обратно.
2. Выведите модуль, который активируется по-умолчанию.
3. Выведите возможные состояния модулей командой systemctl --state=help.
4. Найдите в man странице какие типы модулей есть в systemd.
5. Выведите список установленных модулей.
6. Деактивируйте сервис timesyncd.
7. Перезагрузите сервис timesyncd.
8. Выведите список модулей в памяти.
9. Проверьте, что сервис timesyncd активирован.
10. Выведите список зависимых модулей для сервиса timesyncd.
11. Выведите список сокетов в памяти.
12. Выведите список таймеров в памяти.
13. Проверьте статус сервиса timesyncd.
14. Проверьте, что сервис timesyncd активен.
15. Выведите список свойств модуля.
16. Выведите уровень логирования для сервиса timesyncd.
17. Перезагрузите конфигурацию systemd менеджера: перезапустите генераторы (systemd.generator), все модули и перестройте дерево зависимостей.
18. Какие префиксы можно использовать при указании исполняемых файлов в файлах .service.
0. Установите Debian с графической оболочкой и загрузитесь в неё.
1. В консоли перейдите в уровень запуска `multi-user.target` без перезагрузки, а затем обратно `graphical.target`.
2. Перейдите в уровень запуска `multi-user.target` с перезагрузкой, а затем переключитесь в графическую оболочку обратно.
3. Выведите модуль, который активируется по-умолчанию.
4. Выведите возможные состояния модулей командой `systemctl --state=help`.
5. Найдите в man странице какие типы модулей есть в `systemd`.
6. Выведите список установленных модулей.
7. Деактивируйте сервис `timesyncd`.
8. Перезагрузите сервис `timesyncd`.
9. Выведите список модулей в памяти.
10. Проверьте, что сервис `timesyncd` активирован.
11. Выведите список зависимых модулей для сервиса `timesyncd`.
12. Выведите список сокетов в памяти.
13. Выведите список таймеров в памяти.
14. Проверьте статус сервиса `timesyncd`.
15. Проверьте, что сервис `timesyncd` активен.
16. Выведите список свойств модуля.
17. Выведите уровень логирования для сервиса `timesyncd`.
18. Перезагрузите конфигурацию systemd менеджера: перезапустите генераторы (`systemd.generator`), все модули и перестройте дерево зависимостей.
19. Какие префиксы можно использовать при указании исполняемых файлов в файлах `.service`.
### Задание 2. Конфигурация сервиса
Сконфигурировать socks прокси сервис, который:
Сконфигурировать `socks` прокси сервис, который:
* вызывает команду 'ssh -N -D 0.0.0.0:80 localhost',
* запускается после network.target,
* вызывает команду `ssh -N -D 0.0.0.0:80 localhost`,
* запускается после `network.target`,
* всегда перезагружается при завершении, но не чаще, чем 1 раз в 5 секунд,
* запуск необходим при уровне multi-user.target.
* запуск проивзодится на уровне `multi-user.target`.
Проверьте работу прокси сервиса из браузера с помощью плагина foxyproxy.
Проверьте работу прокси сервиса из браузера с помощью плагина `foxyproxy`.
Страницы документации man:
- systemctl

@ -225,4 +225,30 @@ Certificate:
07:56:d5:00:e4:09:37:5c:7d:a0:fc:79:f7:ea:fe:67:72:2e:
29:6d:d5:11:e9:bc:8a:63:20:1d:96:af:f9:85:1c:43:22:5e:
01:02:37:28:b1:dd:01:93
```
### 9.
#### 9.1 certbot
Установка certbot
```
apt install certbot
```
Получение сертификата
```
certbot certonly --standalone --email stud@gmail.com --agree-tos --no-eff-email --rsa-key-size 4096 --domain stud12.myoffice.ru --config-dir /var/www/html/certs/
```
#### 9.2 acme.sh
Установка acme.sh (выполняется под root)
```
git clone https://github.com/acmesh-official/acme.sh.git
cd ./acme.sh
./acme.sh --install -m my@example.com
```
Получение сертификата
```
acme.sh --issue -d stud12.myoffice.ru -w /var/www/html/certs/
```

@ -1,7 +1,7 @@
# Задания
### 1.
Скачайте дистрибутив debian debian-11.4.0-amd64-netinst.iso c http://mirror.corbina.net/debian-cd/current/amd64/iso-cd/.
Скачайте дистрибутив `debian-11.4.0-amd64-netinst.iso` по ссылке http://mirror.corbina.net/debian-cd/current/amd64/iso-cd/.
Рассчитайте хэш sha256 командой sha256sum для дистрибутива debian и проверьте целостность данных, сравнив значение
с значением в файле SHA256SUMS.
@ -54,10 +54,13 @@ gpg --output un_encrypted.data --decrypt encrypted.data
Страница документации конфигурационного файла sshd `man sshd_config`.
Попробуйте подключиться ещё раз. Попробуйте подключиться ещё раз по паролю (добавьте флаг -o PubkeyAuthentication=no к ssh команде).
Попробуйте подключиться ещё раз. Попробуйте подключиться ещё раз по паролю (добавьте флаг `-o PubkeyAuthentication=no` к ssh команде).
### 8.
Сгенерируйте сертификат x.509 и ключ с помощью openssl. Посмотрите содержимое сертификата командой `openssl x509`.
Сгенерируйте самоподписанный сертификат x.509 и ключ с помощью `openssl`. Посмотрите содержимое сертификата командой `openssl x509`.
### 9.
Получите сертификат с помощью утилиты `certbot` https://certbot.eff.org/ или скрипта `acme.sh` https://github.com/acmesh-official/acme.sh от центра сертификации https://letsencrypt.org/. Изучите его содержимое командой `openssl`.
# Справка
@ -86,4 +89,9 @@ decrypt(шифрованные данные, закрытый ключ) -> да
sign(данные, закрытый ключ) -> массив<байт> (подпись)
verify(данные, подпись: массив<байт>, открытый ключ) -> bool (является ли подпись действительной или нет)
```
Примеры: RSA, ed25519
Примеры: RSA, ed25519
Релевантные ссылки:
- https://missing.csail.mit.edu/2020/security/
- https://letsencrypt.org/how-it-works/

@ -1,212 +0,0 @@
# Решения
### 1.
Создайте папку `projects` в корне системы с правами `rwx` для владельца, группы и других пользователей. Установите на неё `stickybit`.
```
sudo mkdir /projects -m 1777
```
### 2.
Работая от пользователя `stud` в папке `projects` создайте папку с вашим проектом. Проверьте, что владелец может записать файл в неё. Проверьте, что `mike` или `vera` могут прочитать содержимое, но не могу записать в неё.
```
mike@stud15:/projects$ tree
.
└── project_stud
└── main.c
1 directory, 1 file
mike@stud15:/projects$ cat project_stud/main.c
hello
mike@stud15:/projects$ touch project_stud/test
touch: cannot touch 'project_stud/test': Permission denied
```
### 3.
В `projects` создайте ещё одну папку с проектом `project2`. Дайте к ней доступ на чтение только пользователям из группы `best_project_team`. Создайте группу `best_project_team` в которую входит `mike` и `stud`. Перезайдите в аккаунт, чтоб применить изменения членства в группе. Проверьте, что доступа к папке у пользователя `vera` нет.
```
stud@stud15:~$ sudo groupadd best_project_team
stud@stud15:~$ sudo usermod -aG best_project_team mike
stud@stud15:~$ sudo usermod -aG best_project_team stud
stud@stud15:~$ mkdir /projects/project2
stud@stud15:~$ chmod 770 /projects/project2
stud@stud15:~$ chown stud:best_project_team /projects/project2
vera@stud15:~$ cat /projects/project2/testfile
```
### 4.
Создайте третью и четвёртую папки от пользователя `mike` и `vera` в `/projects` и сделайте их полностью приватными. Добавьте в каждую директорию по одному файлу. Проверьте может ли `mike` или vera посмотреть содержимое чужого приватного проекта.
```
root@stud15:~# su - vera
vera@stud15:/projects$ mkdir /projects/vera_project
vera@stud15:/projects$ chmod 700 /projects/vera_project/
vera@stud15:/projects$ echo "hello from vera" > /projects/vera_project/readme
root@stud15:~# su - mike
mike@stud15:/projects$ mkdir mike_project
mike@stud15:/projects$ chmod 700 mike_project/
mike@stud15:/projects/mike_project$ echo "hello from mike" > readme
mike@stud15:/projects/mike_project$ cat /projects/mike_project/readme
hello from mike
mike@stud15:/projects/mike_project$ cat /projects/vera_project/readme
cat: /projects/vera_project/readme: Permission denied
```
### 5.
Проверьте может ли mike удалить папку с чужим проектом? Может ли он удалить свою папку? Уберите stickybit у папки /projects. А теперь может ли mike удалить папку, созданную vera или stud? Влияет ли на возможность удаления наличие в папке файлов?
```bash
mike@stud15:/projects/mike_project$ rm -rf /projects/vera_project/
rm: cannot remove '/projects/vera_project/': Operation not permitted
mike@stud15:/projects/mike_project$ rm -rf /projects/mike_project/
mike@stud15:/projects$ ls -la
total 20
drwxrwxrwt 5 root root 4096 окт 1 17:59 .
drwxr-xr-x 21 root root 4096 окт 1 12:13 ..
drwxrwx--- 2 stud best_project_team 4096 окт 1 12:24 project2
drwxr-xr-x 2 stud stud 4096 окт 1 12:16 project_stud
drwx------ 2 vera vera 4096 окт 1 17:54 vera_project
# без файлов в директории vera_project
mike@stud15:~$ rm -rf /projects/vera_project/
mike@stud15:~$ ls -l /projects/
total 8
drwxrwx--- 2 stud best_project_team 4096 окт 1 12:24 project2
drwxr-xr-x 2 stud stud 4096 окт 1 12:16 project_stud
mike@stud15:~$ ls -l /projects/
```
### 6.
От `root` cоздайте ещё одну общую директорию `shared` в `/home/`. Создайте группу `shared_files` c большим значением идентификатора, например 70000, в которую входят `mike`, `vera` и `stud`. Поменяйте владельца `/home/shared` на `nobody`, а владельца-группу на `shared_files`. Установите полные права доступа для владельца и группы владельца. Все остальным запретите доступ к папке. Также установите бит `SGID`.
```bash
root@stud15:/home# mkdir /home/shared
root@stud15:/home# groupadd shared_files --gid 70000
root@stud15:/home# usermod -aG shared_files mike
root@stud15:/home# usermod -aG shared_files vera
root@stud15:/home# usermod -aG shared_files stud
root@stud15:/home# cat /etc/group | grep shared
shared_files:x:70000:stud,vera,mike
root@stud15:/home# ls -l | grep shared
drwxrws--- 2 nobody shared_files 4096 сен 9 16:43 shared
```
Создайте несколько файлов под разными аккаунтами в этой папке и проверьте, что они имеют владельца-группу shared_files.
```bash
root@stud15:/home# su --login mike --command "mkdir /home/shared/mike_data"
root@stud15:/home# su --login vera --command "mkdir /home/shared/vera_data"
root@stud15:/home# su --login stud --command "mkdir /home/shared/stud_data"
root@stud15:/home# ls -la shared/
total 20
drwxrws--- 5 nobody shared_files 4096 окт 1 18:26 .
drwxr-xr-x 13 root root 4096 сен 15 11:47 ..
-rw-r--r-- 1 stud shared_files 0 сен 9 16:42 1
-rw-r--r-- 1 mike shared_files 0 сен 9 16:42 2
-rw-rw-r-- 1 stud shared_files 0 сен 9 16:43 3
drwxr-sr-x 2 mike shared_files 4096 окт 1 18:25 mike_data
drwxr-sr-x 2 stud shared_files 4096 окт 1 18:26 stud_data
drwxr-sr-x 2 vera shared_files 4096 окт 1 18:26 vera_data
```
### 7.
Узнайте значение `umask` одноимённой командой. Создайте папку и файл c именем `test_$(umask)`. Выведите атрибуты файла. Измените umask одноимённой командой на `0002`. Повторите создание папки и файла и сравните атрибуты файлов, созданных с разными масками.
```bash
stud@stud15:/home/shared$ umask
0022
stud@stud15:/home/shared$ touch test_$(umask)
stud@stud15:/home/shared$ stat test_0022
File: test_0022
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 801h/2049d Inode: 1177656 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ stud) Gid: ( 1002/shared_files)
Access: 2022-10-01 18:28:21.509800524 +0400
Modify: 2022-10-01 18:28:21.509800524 +0400
Change: 2022-10-01 18:28:21.509800524 +0400
Birth: 2022-10-01 18:28:21.509800524 +0400
stud@stud15:/home/shared$ umask 0002
stud@stud15:/home/shared$ touch test_$(umask)
stud@stud15:/home/shared$ stat test_0002
File: test_0002
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 801h/2049d Inode: 1177657 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/ stud) Gid: ( 1002/shared_files)
Access: 2022-10-01 18:28:45.002074124 +0400
Modify: 2022-10-01 18:28:45.002074124 +0400
Change: 2022-10-01 18:28:45.002074124 +0400
Birth: 2022-10-01 18:28:45.002074124 +0400
```
### 8.
Под `root` скопируйте `bash` `cp /bin/bash /bin/my_unsecure_bash` и установите атрибуты файла в значение `4755`. Значение 4 соответствует биту `SUID`. Посмотрите на результат командой `stat`. Создайте файл-скрипт `gen_file_root.sh` в папке `/tmp` от пользователя `mike` со следующим содержимым:
```bash
#!/bin/my_unsecure_bash -p
touch /tmp/root_$RANDOM
```
Сделайте его исполняемым для всех. Вызовите скрипт от пользователя `stud`. Обратите внимание на владельца созданного файла `/tmp/root_*`. Как на него повлиял `SUID`? Установите `SUID` на `gen_file_root.sh`, сгенерируйте новый файл. Есть ли изменения в поле владельца?
```
root@stud15:/tmp# stat /bin/my_unsecure_bash
File: /bin/my_unsecure_bash
Size: 1234376 Blocks: 2416 IO Block: 4096 regular file
Device: 801h/2049d Inode: 1842926 Links: 1
Access: (4755/-rwsr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2022-09-09 15:07:30.407667000 +0400
Modify: 2022-09-09 15:04:36.207672558 +0400
Change: 2022-09-09 15:04:59.031671752 +0400
Birth: 2022-09-09 15:04:36.171672558 +0400
root@stud15:/tmp# chmod 777 /tmp/gen_file_root.sh
root@stud15:/tmp# su - stud
stud@stud15:~$ cd /tmp/
stud@stud15:/tmp$ ./gen_file_root.sh
stud@stud15:/tmp$ ./gen_file_root.sh
stud@stud15:/tmp$ ./gen_file_root.sh
stud@stud15:/tmp$ ls -l
total 16
-rwxrwxrwx 1 root root 51 окт 1 18:33 gen_file_root.sh
-rw-r--r-- 1 stud stud 33 окт 1 11:34 log
-rw-r--r-- 1 root stud 0 окт 1 18:39 root_29247
-rw-r--r-- 1 root stud 0 окт 1 18:39 root_32039
-rw-r--r-- 1 root stud 0 окт 1 18:39 root_9235
```
### 9.
В каталоге `/projects` создайте файл `test` в папках `1`, `2`, `3`. Поменяйте для папок атрибуты доступа для категории `other`: `r--`, `r-x`, `--x` соответственно. Зайдите под другого пользователя, который входит в категорию `other` и попробуйте найти файл с помощью `find`, начиная с каталога `/projects`. Попробуйте найти слово в содержимом файлов. Как влияют атрибуты на возможность поиска?
```
stud@stud15:/projects$ mkdir 1
stud@stud15:/projects$ mkdir 2
stud@stud15:/projects$ mkdir 3
stud@stud15:/projects$ chmod 704 1
stud@stud15:/projects$ chmod 705 2
You have new mail in /var/mail/stud
stud@stud15:/projects$ chmod 701 3
stud@stud15:/projects$ ls -l
total 20
drwx---r-- 2 stud stud 4096 окт 1 18:42 1
drwx---r-x 2 stud stud 4096 окт 1 18:42 2
drwx-----x 2 stud stud 4096 окт 1 18:42 3
stud@stud15:/projects$ echo "hello" > 1/message
stud@stud15:/projects$ echo "hello" > 2/message
stud@stud15:/projects$ echo "hello" > 3/message
root@stud15:/tmp# su - mike
mike@stud15:~$ cd /projects/
mike@stud15:/projects$ find . -name "message"
find: ./3: Permission denied
./2/message
./1/message
mike@stud15:/projects$ grep -r "hello" .
grep: ./3: Permission denied
./2/message:hello
grep: ./1/message: Permission denied
```
Команда `find` не смогла найти файл только для папки без доступа на чтение для `other`. Команда `grep` смогла найти строку только в папке с правами и на чтение и на исполнение.
# Справка
Конфигурационные файлы:
- /etc/login.defs
Команды:
- stat
- ls -l
- chmod
- chown
- umask

@ -1,114 +1,615 @@
# Решения
Действия ниже производятся от пользователя `root`.
### 0.
Обновите список пакетов из настроенных репозиториев в /etc/apt/sources.list командой apt.
Обновите список пакетов из настроенных репозиториев в `/etc/apt/sources.list` командой `apt`.
```
# apt update
```
Пример содержимого файла для Debian 12
```
$ sudo apt update
# main состоит из DFSG-compliant пакетов, которым не требуется другое ПО из других зон. Эти пакеты считаются частью дистрибуции Debian
# contrib пакеты содержат DFSG-compliant ПО, но у них зависимостей из зоны main (возможно упакованы в non-free).
# non-free содержит ПО, которое не соответствует DFSG.
# скомпилированные бинарные пакеты
deb http://deb.debian.org/debian/ bookworm main
# оригинальные исходные коды пакетов
deb-src http://deb.debian.org/debian/ bookworm main
# некоторые пакеты для следующего 12.X обнвления доступны только из следующих веток
deb http://deb.debian.org/debian/ bookworm-updates main
deb-src http://deb.debian.org/debian/ bookworm-updates main
# критические обновления пакетов для обнаруженных уязвимостей доступны из репозитория security.debian.org
deb http://security.debian.org/debian-security/ bookworm/updates main
deb-src http://security.debian.org/debian-security/ bookworm/updates main
```
### 1.
Установите пакет apt-file с помощью apt.
Установите пакет `apt-file` с помощью `apt`.
```
$ sudo apt install apt-file
# apt install apt-file
```
### 2.
Найдите с помощью apt-file пакет, содержащий команду ar.
Найдите с помощью `apt-file` пакет, содержащий команду `ar`.
```
$ apt-file search ar
# apt-file search --regexp /bin/ar$
root@stud12:~# apt-file search --regexp /bin/ar$
amdgcn-tools: /usr/amdgcn-amdhsa/bin/ar
binutils: /usr/bin/ar
binutils-aarch64-linux-gnu: /usr/aarch64-linux-gnu/bin/ar
binutils-alpha-linux-gnu: /usr/alpha-linux-gnu/bin/ar
binutils-arc-linux-gnu: /usr/arc-linux-gnu/bin/ar
binutils-arm-linux-gnueabi: /usr/arm-linux-gnueabi/bin/ar
binutils-arm-linux-gnueabihf: /usr/arm-linux-gnueabihf/bin/ar
binutils-arm-none-eabi: /usr/lib/arm-none-eabi/bin/ar
binutils-avr: /usr/lib/avr/bin/ar
binutils-bpf: /usr/lib/bpf/bin/ar
binutils-djgpp: /usr/i386-pc-msdosdjgpp/bin/ar
binutils-h8300-hms: /usr/h8300-hitachi-coff/bin/ar
binutils-hppa-linux-gnu: /usr/hppa-linux-gnu/bin/ar
binutils-hppa64-linux-gnu: /usr/hppa64-linux-gnu/bin/ar
binutils-i686-gnu: /usr/i686-gnu/bin/ar
binutils-i686-kfreebsd-gnu: /usr/i686-kfreebsd-gnu/bin/ar
binutils-i686-linux-gnu: /usr/i686-linux-gnu/bin/ar
binutils-ia64-linux-gnu: /usr/ia64-linux-gnu/bin/ar
binutils-m68hc1x: /usr/m68hc11/bin/ar
binutils-m68k-linux-gnu: /usr/m68k-linux-gnu/bin/ar
binutils-mingw-w64-i686: /usr/i686-w64-mingw32/bin/ar
binutils-mingw-w64-x86-64: /usr/x86_64-w64-mingw32/bin/ar
binutils-mips-linux-gnu: /usr/mips-linux-gnu/bin/ar
binutils-mips64-linux-gnuabi64: /usr/mips64-linux-gnuabi64/bin/ar
binutils-mips64-linux-gnuabin32: /usr/mips64-linux-gnuabin32/bin/ar
binutils-mips64el-linux-gnuabi64: /usr/mips64el-linux-gnuabi64/bin/ar
binutils-mips64el-linux-gnuabin32: /usr/mips64el-linux-gnuabin32/bin/ar
binutils-mipsel-linux-gnu: /usr/mipsel-linux-gnu/bin/ar
binutils-mipsisa32r6-linux-gnu: /usr/mipsisa32r6-linux-gnu/bin/ar
binutils-mipsisa32r6el-linux-gnu: /usr/mipsisa32r6el-linux-gnu/bin/ar
binutils-mipsisa64r6-linux-gnuabi64: /usr/mipsisa64r6-linux-gnuabi64/bin/ar
binutils-mipsisa64r6-linux-gnuabin32: /usr/mipsisa64r6-linux-gnuabin32/bin/ar
binutils-mipsisa64r6el-linux-gnuabi64: /usr/mipsisa64r6el-linux-gnuabi64/bin/ar
binutils-mipsisa64r6el-linux-gnuabin32: /usr/mipsisa64r6el-linux-gnuabin32/bin/ar
binutils-or1k-elf: /usr/or1k-elf/bin/ar
binutils-powerpc-linux-gnu: /usr/powerpc-linux-gnu/bin/ar
binutils-powerpc64-linux-gnu: /usr/powerpc64-linux-gnu/bin/ar
binutils-powerpc64le-linux-gnu: /usr/powerpc64le-linux-gnu/bin/ar
binutils-riscv64-linux-gnu: /usr/riscv64-linux-gnu/bin/ar
binutils-riscv64-unknown-elf: /usr/lib/riscv64-unknown-elf/bin/ar
binutils-s390x-linux-gnu: /usr/s390x-linux-gnu/bin/ar
binutils-sh-elf: /usr/sh-elf/bin/ar
binutils-sh4-linux-gnu: /usr/sh4-linux-gnu/bin/ar
binutils-sparc64-linux-gnu: /usr/sparc64-linux-gnu/bin/ar
binutils-x86-64-kfreebsd-gnu: /usr/x86_64-kfreebsd-gnu/bin/ar
binutils-x86-64-linux-gnux32: /usr/x86_64-linux-gnux32/bin/ar
binutils-xtensa-lx106: /usr/lib/xtensa-lx106-elf/bin/ar
nvptx-tools: /usr/nvptx-none/bin/ar
```
### 3.
Определите с помощью команды `apt search`, какие варианты пакета содержащего команду ar доступны. Установите подходящий для вашей системы.
Определите с помощью команды `apt search`, какие варианты пакета содержащего команду `ar` доступны. Установите подходящий для вашей системы.
```
# apt search binutils
binutils/stable,now 2.40-2 amd64 [installed]
GNU assembler, linker and binary utilities
binutils-aarch64-linux-gnu/stable 2.40-2 amd64
GNU binary utilities, for aarch64-linux-gnu target
binutils-aarch64-linux-gnu-dbg/stable 2.40-2 amd64
GNU binary utilities, for aarch64-linux-gnu target (debug symbols)
binutils-alpha-linux-gnu/stable 2.40-2 amd64
GNU binary utilities, for alpha-linux-gnu target
binutils-alpha-linux-gnu-dbg/stable 2.40-2 amd64
GNU binary utilities, for alpha-linux-gnu target (debug symbols)
...
```
```
# apt install binutils/stable
```
### 4.
Скачайте http://ftp.ru.debian.org/debian/pool/main/c/cmake/cmake_3.24.1-1_amd64.deb в отдельную папку. Перейдите в папку с пакетом и распакуйте .deb командой `ar -x путь-к-пакету`. В папке должны появиться: control.tar.xz data.tar.xz debian-binary.
Скачайте http://ftp.ru.debian.org/debian/pool/main/c/cmake/cmake_3.25.1-1_amd64.deb в отдельную папку. Перейдите в папку с пакетом и распакуйте .deb командой `ar -x путь-к-пакету`. В папке должны появиться: `control.tar.xz`, `data.tar.xz`, `debian-binary`.
### 5.
Создайте папку control и распакуйте в неё control.tar.xz с помощью команды `tar xfC путь-к-архиву control`. Изучите содержимое. Сравните с выдачей `dpkg --info ` для .deb файла.
Создайте папку `control` и распакуйте в неё `control.tar.xz` с помощью команды `tar xfC путь-к-архиву control`. Изучите содержимое. Сравните с выдачей `dpkg --info ` для `.deb` файла.
```
# cat control/control
Package: cmake
Version: 3.25.1-1
Architecture: amd64
Maintainer: Debian CMake Team <pkg-cmake-team@lists.alioth.debian.org>
Installed-Size: 28897
Depends: libarchive13 (>= 3.3.3), libc6 (>= 2.34), libcurl4 (>= 7.16.2), libexpat1 (>= 2.0.1), libgcc-s1 (>= 3.0), libjsoncpp25 (>= 1.9.5), librhash0 (>= 1.2.6), libstdc++6 (>= 12), libuv1 (>= 1.38.0), zlib1g (>= 1:1.1.4), cmake-data (= 3.25.1-1), procps
Recommends: gcc, make
Suggests: cmake-doc, cmake-format, elpa-cmake-mode, ninja-build
Section: devel
Priority: optional
Multi-Arch: foreign
Homepage: https://cmake.org/
Description: cross-platform, open-source make system
CMake is used to control the software compilation process using
simple platform and compiler independent configuration files. CMake
generates native makefiles and workspaces that can be used in the
compiler environment of your choice. CMake is quite sophisticated: it
is possible to support complex environments requiring system
configuration, pre-processor generation, code generation, and template
instantiation.
# cat debian-binary
2.0
```
```
# dpkg --info cmake_3.25.1-1_amd64.deb
new Debian package, version 2.0.
size 8692248 bytes: control archive=1224 bytes.
1045 bytes, 20 lines control
778 bytes, 12 lines md5sums
Package: cmake
Version: 3.25.1-1
Architecture: amd64
Maintainer: Debian CMake Team <pkg-cmake-team@lists.alioth.debian.org>
Installed-Size: 28897
Depends: libarchive13 (>= 3.3.3), libc6 (>= 2.34), libcurl4 (>= 7.16.2), libexpat1 (>= 2.0.1), libgcc-s1 (>= 3.0), libjsoncpp25 (>= 1.9.5), librhash0 (>= 1.2.6), libstdc++6 (>= 12), libuv1 (>= 1.38.0), zlib1g (>= 1:1.1.4), cmake-data (= 3.25.1-1), procps
Recommends: gcc, make
Suggests: cmake-doc, cmake-format, elpa-cmake-mode, ninja-build
Section: devel
Priority: optional
Multi-Arch: foreign
Homepage: https://cmake.org/
Description: cross-platform, open-source make system
CMake is used to control the software compilation process using
simple platform and compiler independent configuration files. CMake
generates native makefiles and workspaces that can be used in the
compiler environment of your choice. CMake is quite sophisticated: it
is possible to support complex environments requiring system
configuration, pre-processor generation, code generation, and template
instantiation.
```
Выдача `dpkg --info` включает содержимое `debian-binary`, файла `control/control` и размеры содержимого `.deb`.
### 6.
Создайте папку data и распакуйте в неё data.tar.xz с помощью команды `tar xfC путь-к-архиву data`. Изучите data с помощью команды `tree`. Сравните с выдачей `dpkg --contents ` для .deb файла.
Создайте папку `data` и распакуйте в неё `data.tar.xz` с помощью команды `tar xfC путь-к-архиву data`. Изучите `data` с помощью команды `tree`. Сравните с выдачей `dpkg --contents ` для `.deb` файла.
```
# dpkg --contents cmake_3.25.1-1_amd64.deb
drwxr-xr-x root/root 0 2022-11-30 14:57 ./
drwxr-xr-x root/root 0 2022-11-30 14:57 ./usr/
drwxr-xr-x root/root 0 2022-11-30 14:57 ./usr/bin/
-rwxr-xr-x root/root 9245840 2022-11-30 14:57 ./usr/bin/cmake
-rwxr-xr-x root/root 9544272 2022-11-30 14:57 ./usr/bin/cpack
-rwxr-xr-x root/root 10697872 2022-11-30 14:57 ./usr/bin/ctest
drwxr-xr-x root/root 0 2022-11-30 14:57 ./usr/share/
drwxr-xr-x root/root 0 2022-11-30 14:57 ./usr/share/bash-completion/
drwxr-xr-x root/root 0 2022-11-30 14:57 ./usr/share/bash-completion/completions/
-rw-r--r-- root/root 6837 2022-11-30 08:57 ./usr/share/bash-completion/completions/cmake
-rw-r--r-- root/root 2870 2022-11-30 08:57 ./usr/share/bash-completion/completions/cpack
-rw-r--r-- root/root 4535 2022-11-30 08:57 ./usr/share/bash-completion/completions/ctest
drwxr-xr-x root/root 0 2022-11-30 14:57 ./usr/share/cmake/
-rwxr-xr-x root/root 2410 2022-02-22 03:29 ./usr/share/cmake/debtoolchainfilegen
drwxr-xr-x root/root 0 2022-11-30 14:57 ./usr/share/doc/
drwxr-xr-x root/root 0 2022-11-30 14:57 ./usr/share/doc/cmake/
-rw-r--r-- root/root 2937 2022-11-30 14:57 ./usr/share/doc/cmake/changelog.Debian.gz
-rw-r--r-- root/root 29578 2022-05-25 14:57 ./usr/share/doc/cmake/copyright
drwxr-xr-x root/root 0 2022-11-30 14:57 ./usr/share/man/
drwxr-xr-x root/root 0 2022-11-30 14:57 ./usr/share/man/man1/
-rw-r--r-- root/root 15175 2022-11-30 14:57 ./usr/share/man/man1/cmake.1.gz
-rw-r--r-- root/root 2819 2022-11-30 14:57 ./usr/share/man/man1/cpack.1.gz
-rw-r--r-- root/root 18116 2022-11-30 14:57 ./usr/share/man/man1/ctest.1.gz
```
```
# tree --metafirst -ugshap data/
[drwxr-xr-x root root 4.0K] data/
[drwxr-xr-x root root 4.0K] └── usr
[drwxr-xr-x root root 4.0K] ├── bin
[-rwxr-xr-x root root 8.8M] │   ├── cmake
[-rwxr-xr-x root root 9.1M] │   ├── cpack
[-rwxr-xr-x root root 10M] │   └── ctest
[drwxr-xr-x root root 4.0K] └── share
[drwxr-xr-x root root 4.0K] ├── bash-completion
[drwxr-xr-x root root 4.0K] │   └── completions
[-rw-r--r-- root root 6.7K] │   ├── cmake
[-rw-r--r-- root root 2.8K] │   ├── cpack
[-rw-r--r-- root root 4.4K] │   └── ctest
[drwxr-xr-x root root 4.0K] ├── cmake
[-rwxr-xr-x root root 2.4K] │   └── debtoolchainfilegen
[drwxr-xr-x root root 4.0K] ├── doc
[drwxr-xr-x root root 4.0K] │   └── cmake
[-rw-r--r-- root root 2.9K] │   ├── changelog.Debian.gz
[-rw-r--r-- root root 29K] │   └── copyright
[drwxr-xr-x root root 4.0K] └── man
[drwxr-xr-x root root 4.0K] └── man1
[-rw-r--r-- root root 15K] ├── cmake.1.gz
[-rw-r--r-- root root 2.8K] ├── cpack.1.gz
[-rw-r--r-- root root 18K] └── ctest.1.gz
```
Содержимое идентично.
### 7.
Попробуйте вызвать исполняемый файл `usr/bin/cmake` из папки. Сопоставьте информацию в control файле пакета с выдачей команды `ldd usr/bin/cmake`. Если исполняемый файл не работает, найдите и установите зависимости в систему. Воспользуйтесь формой поиска на сайте https://www.debian.org/distrib/packages, если поиск по настроенным репозиториям не даёт результата. Добавьте репозиторий в котором есть нужная библиотека командой `apt edit-sources`. Обновите базу данных пакетов командой `apt update`. Завершите установку зависимостей и проверьте, что cmake работает.
Попробуйте вызвать исполняемый файл `usr/bin/cmake` из папки. Сопоставьте информацию в control файле пакета с выдачей команды `ldd usr/bin/cmake`. Если исполняемый файл не работает, найдите и установите зависимости в систему. Воспользуйтесь формой поиска на сайте https://www.debian.org/distrib/packages, если поиск по настроенным репозиториям не даёт результата. Добавьте репозиторий в котором есть нужная библиотека командой `apt edit-sources`. Обновите базу данных пакетов командой `apt update`. Завершите установку зависимостей и проверьте, что `cmake` работает.
Поиск на сайте https://www.debian.org/distrib/packages приводит к ссылке https://packages.debian.org/sid/amd64/libjsoncpp25/download, в которой приводится руководство по добавлению экспериментального репозитория.
Для поиска списка зависимостей можно использовать одну из этих комманд:
```
# ldd data/usr/bin/cmake
# dpkg --info cmake_3.25.1-1_amd64.deb
```
$ sudo apt update
$ sudo apt install
```
# apt-file search libcurl.so.4
# apt install libcurl4
# apt-file search libjsoncpp.so.25
# apt install libjsoncpp25
# apt-file search libarchive.so.13
# apt install libarchive13
# apt-file search librhash.so.0
# apt install librhash0
# ldd data/usr/bin/cmake
# data/usr/bin/cmake
```
### 8.
Утилитой dpkg-query выведите список пакетов, зарегистрированных в dpkg базе данных. Есть ли среди них зависимости cmake, которые вы установили вручную?
Утилитой `dpkg-query` выведите список пакетов, зарегистрированных в `dpkg` базе данных. Есть ли среди них зависимости `cmake`, которые вы установили вручную?
```
# dpkg-query --list
```
Если файлы были вручную разложены по системным папка из папки `data`, то пакет не попадёт в базу данных `dpkg`. Если выполнить
```
# dpkg --install cmake_3.25.1-1_amd64.deb
```
то файлы будут скопированы за вас и пакет зарегистрирован в базе данных `dpkg`.
### 9.
Утилитой dpkg-query выведите среди установленных локально пакетов пакет, начинающихся с libc6. Утилитой apt-cache выполните тот же поиск по кэшу apt. Утилитой apt выполните тот же поиск по кэшу apt. Сравните, чем они отличаются.
Утилитой `dpkg-query` выведите среди установленных локально пакетов пакет, начинающихся с `libc6`. Утилитой `apt-cache` выполните тот же поиск по кэшу `apt`. Утилитой `apt` выполните тот же поиск по кэшу `apt`. Сравните, чем они отличаются.
```
dpkg-query --list libc6*
```
```
apt-cache search ^libc6.*
```
`apt-cache search` - выполняет полнотекстовый поиск по базе данных apt, полученной командой `apt update` из репозиториев, сконфигурированных в `/etc/apt/sources.list`.
`dpkg-query` - выполняет полнотекстовый поиск по базе данных `dpkg`, то есть по базе только установленных пакетов в систему. `apt` является фронтэндом для `dpkg`.
### 10.
Утилитой dpkg-query выведите статус пакета sudo и gcc. Чем выдача отличается от содержимого control файла .deb, скаченного ранее?
Утилитой `dpkg-query` выведите статус пакета `sudo` и `gcc`. Чем выдача отличается от содержимого `control` файла `.deb`, скаченного ранее?
Вывод отличается наличием информации о статусе
```
# diff <(dpkg-query --status cmake | sort) <(cat control/control | sort)
19d18
< Status: install ok unpacked
```
### 11.
Утилитой dpkg-query выведите список установленных файлов пакета sudo (не выводятся файлы созданные скриптами).
Утилитой `dpkg-query` выведите список установленных файлов пакета `sudo` (не выводятся файлы созданные скриптами).
```
# dpkg-query --listfiles sudo
```
### 12.
Утилитой dpkg-query выведите список файлов с метаданными пакета (control files), установленных в систему.
Утилитой `dpkg-query` выведите список файлов с метаданными пакета (control files), установленных в систему.
```
# dpkg-query --control-list sudo
postrm
md5sums
preinst
shlibs
triggers
prerm
postinst
```
### 13.
Утилитой dpkg-query выведите содержимое одного из файлов с метаданными пакета (control files).
```
# dpkg-query --control-show sudo preinst
#!/bin/sh
set -e
case "$1" in
install|upgrade)
if [ -n "$2" ] && dpkg --compare-versions "$2" le "1.7.4p4-4"; then
SUDOERS="/etc/sudoers"
if [ -e "$SUDOERS" ]; then
md5sum="$(md5sum $SUDOERS | sed -e 's/ .*//')"
if [ "$md5sum" = "c310ef4892a00cca8134f6e4fcd64b6d" ] || #lenny
[ "$md5sum" = "c5dab0f2771411ed7e67d6dab60a311f" ] || #squeeze
[ "$md5sum" = "45437b4e86fba2ab890ac81db2ec3606" ]; then #wheezy
# move unchanged sudoers file to avoid conffile question
mv "$SUDOERS" "$SUDOERS.pre-conffile"
fi
fi
fi
;;
esac
# Automatically added by dh_installinit/13.11.4
if [ "$1" = "install" ] && [ -n "$2" ] && [ -e "/etc/init.d/sudo" ] ; then
chmod +x "/etc/init.d/sudo" >/dev/null || true
fi
# End automatically added section
```
### 14.
Утилитой dpkg-query выведите пути к файлам с метаданными пакета (control files).
Утилитой `dpkg-query` выведите пути к файлам с метаданными пакета (control files).
```
# dpkg-query --control-path sudo
/var/lib/dpkg/info/sudo.postrm
/var/lib/dpkg/info/sudo.md5sums
/var/lib/dpkg/info/sudo.preinst
/var/lib/dpkg/info/sudo.shlibs
/var/lib/dpkg/info/sudo.triggers
/var/lib/dpkg/info/sudo.prerm
/var/lib/dpkg/info/sudo.postinst
```
### 15.
Утилитой dpkg-query выполните поиск пакетов, которые установили в систему файл pam.conf.
Утилитой `dpkg-query` выполните поиск пакетов, которые установили в систему файл `pam.conf`.
```
# dpkg-query --search */pam.conf
sudo: /usr/share/doc/sudo/examples/pam.conf
libpam-runtime: /etc/pam.conf
```
### 16.
Утилитой dpkg установите cmake .deb пакет, скачанный ранее. Ещё раз посмотрите на зависимости пакета. Как отреагировал dpkg на отсутствие зависимости cmake-data - установил или выдал ошибку?
Утилитой `dpkg` установите `cmake` `.deb` пакет, скачанный ранее. Ещё раз посмотрите на зависимости пакета. Как отреагировал `dpkg` на отсутствие зависимости `cmake-data` - установил или выдал ошибку?
Пакет установился, но не сконфигурировался.
### 17.
Скачайте cmake-data и его транзитивные зависимости https://packages.debian.org/sid/amd64/cmake. Завершите установку cmake, и проверьте, что команда cmake установлена в систему (например, командами `which`, `find`) и работает `cmake --version`.
Скачайте `cmake-data` и его транзитивные зависимости https://packages.debian.org/sid/amd64/cmake. Завершите установку `cmake`, и проверьте, что команда `cmake` установлена в систему (например, командами `which`, `find`) и работает `cmake --version`.
```
# dpkg --list cmake cmake-data
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==============-============-============-=======================================================
iU cmake 3.25.1-1 amd64 cross-platform, open-source make system
ii cmake-data 3.25.1-1 all CMake data files (modules, templates and documentation)
# cmake --version
cmake version 3.25.1
CMake suite maintained and supported by Kitware (kitware.com/cmake).
# which cmake
/usr/bin/cmake
```
### 18.
Проверьте файлы всех установленных пакетов в системе на наличие изменений/повреждений командой dpkg. Какие файлы не прошли проверку (`??5??????`)?
Проверьте файлы всех установленных пакетов в системе на наличие изменений/повреждений командой `dpkg`. Какие файлы не прошли проверку (`??5??????`)?
```
# dpkg --verify
??5?????? c /etc/sudoers
```
В данном случае файл не прошёл проверку потому, что был изменён в редакторе для обеспечения беспарольного доступа группе `sudo`.
#### 18.1 Справка
В настоящее время поддерживается только формат вывода rpm, который состоит из строки для каждого пути, который не прошел ни одну проверку. Эти строки имеют следующий формат:
```
missing [c] pathname [(error-message)]
??5?????? [c] имя пути
```
Первые 9 символов используются для сообщения о результате проверки. `?` Подразумевает, что проверка не может быть выполнена (отсутствие поддержки, права доступа к файлу и т.д.). `.` Подразумевает, что проверка пройдена. `A-Za-z0-9` Означает, что определенная проверка не прошла. В случае если запись была типа `missing`, и файл фактически отсутствовал в файловой системе, то после строки ставится пробел и сообщение об ошибке, заключенное в круглые скобки.
Формат вывода rpm:
```
SM5DLUGT c <file>
```
- S размер файла (эти проверки в настоящее время не поддерживаются, всегда будет '?'),
- M режим файла (проверка режима файла не удалась (начиная с версии dpkg 1.21.0)),
- 5 MD5 хэш файла (проверка хэшкода не удалась, что означает, что содержимое файла изменилось),
- D мажорная и минорная версии файла (эти проверки в настоящее время не поддерживаются, всегда будет '?'),
- L содержимое символических ссылок файла (эти проверки в настоящее время не поддерживаются, всегда будет '?'),
- U владелец файла (эти проверки в настоящее время не поддерживаются, всегда будет '?'),
- G группа-владелец файла (эти проверки в настоящее время не поддерживаются, всегда будет '?'),
- T время модификации файла (эти проверки в настоящее время не поддерживаются, всегда будет '?'),
- c появляется только, если это конфигурационный файл (как правило именно они меняются и с большей вероятностью не пройдут проверку)
- <file> полный путь к файлу, который не прошёл проверку.
Знак вопроса означает, что файл не может быть проверен по какой-то причине.
Дополнительные комментарии из `man dpkg` для секции `--verify-format` для проверки режима файла (M). Поскольку метаданные имени пути в настоящее время не отслеживаются, эта проверка может быть частично эмулирована только с помощью очень простой эвристики для имен путей, которые имеют известный хэшкод, что подразумевает, что они должны быть обычными файлами. Проверка будет неудачной, если путь указывает не на обычный файл в файловой системе. На текущий момент эта проверка никогда не будет успешной, так как нет достаточной информации.
### 19.
Сохраните список выбранных действий (selections) для пакетов в системе утилитой dpkg в файл.
Сохраните список выбранных действий (selections) для пакетов в системе утилитой `dpkg` в файл.
```
# dpkg --get-selections > /tmp/$(date -I)_selections
```
### 20.
Измените в сохранённом списке действие для пакета vim c текущего на deinstall (`man dpkg`, “Package selection states”). Перечитайте изменённый список командой `dpkg --set-selections`.
Измените в сохранённом списке действие для пакета `vim` c текущего на deinstall (`man dpkg`, “Package selection states”). Перечитайте изменённый список командой `dpkg --set-selections`.
```
# cat /tmp/2023-10-13_selections | dpkg --set-selections
# dpkg --get-selections | grep vim
vim deinstall
vim-common install
vim-runtime install
vim-tiny install
```
### 21.
Запустите команду `apt-get dselect-upgrade`. Не подтверждайте изменения. Какие пакеты будут установлены или удалены?
```
# apt-get dselect-upgrade
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages will be REMOVED:
vim
The following NEW packages will be installed:
linux-image-6.1.0-13-amd64
The following packages will be upgraded:
base-files dbus dbus-bin dbus-daemon dbus-session-bus-common dbus-system-bus-common dbus-user-session
debian-archive-keyring debianutils grub-common grub-pc grub-pc-bin grub2-common inetutils-telnet krb5-locales
libc-bin libc-l10n libc6 libdbus-1-3 libgssapi-krb5-2 libk5crypto3 libkrb5-3 libkrb5support0 libnftables1
libnss-systemd libpam-modules libpam-modules-bin libpam-runtime libpam-systemd libpam0g libssl3
libsystemd-shared libsystemd0 libudev1 libx11-6 libx11-data linux-image-6.1.0-10-amd64 linux-image-amd64
locales nftables openssh-client openssh-server openssh-sftp-server openssl qemu-guest-agent ssh systemd
systemd-sysv systemd-timesyncd udev
50 upgraded, 1 newly installed, 1 to remove and 0 not upgraded.
1 not fully installed or removed.
Need to get 166 MB of archives.
After this operation, 404 MB of additional disk space will be used.
Do you want to continue? [Y/n] n
```
### 22.
Настройте в `/etc/sudoers` конфигурационном файле для пользователя stud возможность выполнять команды от лица суперпользователя без запроса пароля:
Настройте в `/etc/sudoers` конфигурационном файле для пользователя `stud` возможность выполнять команды от лица суперпользователя без запроса пароля:
```
%sudo ALL=(ALL:ALL) NOPASSWD: ALL
```
Удалите, а затем установите пакет sudo командой `apt remove`. Проверьте содержимое конфигурационного файла на изменения. Проделайте то же самое, но c командой `apt purge`.
Удалите, а затем установите пакет `sudo` командой `apt remove`. Проверьте содержимое конфигурационного файла на изменения. Проделайте то же самое, но c командой `apt purge`.
`apt purge` - удалит все конфигурационные файлы, даже если они были изменены администратором.
### 23.
Удалите cmake и cmake-data с помощью apt. Найдите в репозиториях, какая версия cmake доступна. Создайте файл в директории `/etc/apt/apt.conf.d/default-release` со следующим содержимым (man apt.conf):
Удалите `cmake` и `cmake-data` с помощью `apt`. Найдите в репозиториях, какая версия `cmake` доступна. Создайте файл в директории `/etc/apt/apt.conf.d/default-release` со следующим содержимым (`man apt.conf`):
```
APT::Default-Release "stable";
```
Повторите поиск. Установите stable версию. Проверьте работоспособность команды и её версию `cmake --version`. Вы можете узнать значения текущих конфигурационных переменных `apt` командой `apt-config dump`.
Повторите поиск. Установите `stable` версию. Проверьте работоспособность команды и её версию `cmake --version`. Вы можете узнать значения текущих конфигурационных переменных `apt` командой `apt-config dump`.
```
# apt-config dump | grep Default-Release
APT::Default-Release "stable";
# apt search ^cmake$
Sorting... Done
Full Text Search... Done
cmake/stable,now 3.25.1-1 amd64 [installed]
cross-platform, open-source make system
```
### 24.
Заморозьте версию cmake командой `apt-mark` или с помощью `dpkg --get-selections`, `dpkg --set-selections`. Поменяйте умолчания `/etc/apt/apt.conf.d/default-release` на "unstable". Проведите обновление пакетов в системе. cmake должен сохранить stable версию.
Заморозьте версию `cmake` командой `apt-mark` или с помощью `dpkg --get-selections`, `dpkg --set-selections`. Поменяйте умолчания `/etc/apt/apt.conf.d/default-release` на "unstable". Проведите обновление пакетов в системе. `cmake` должен сохранить `stable` версию.
После добавления в `sources.list` строк
```
deb http://deb.debian.org/debian/ unstable main non-free-firmware
deb-src http://deb.debian.org/debian/ unstable main non-free-firmware
```
и запуска `apt update`:
```
# apt-config dump | grep Default-Release
APT::Default-Release "unstable";
root@stud12:~# apt search ^cmake$
Sorting... Done
Full Text Search... Done
cmake/unstable 3.27.7-1 amd64 [upgradable from: 3.25.1-1]
cross-platform, open-source make system
```
доступна более свежая версия `cmake`.
При попытке обновления пакеты отмеченные `hold` не будут обновлены:
```
# apt-mark hold cmake cmake-data
cmake set on hold.
cmake-data set on hold.
# apt upgrade
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
The following packages were automatically installed and are no longer required:
libcbor0.8 libfstrm0 libfuse2 libjemalloc2 liblmdb0 libmaxminddb0 libprotobuf-c1
Use 'apt autoremove' to remove them.
The following NEW packages will be installed:
firmware-ath9k-htc gcc-13-base libcbor0.10 libfuse3-3 libsframe1 libunistring5 linux-image-6.5.0-2-amd64
systemd-dev
The following packages have been kept back:
cmake cmake-data
```
### 25.
Удалите cmake для следующего упражнения в установке из исходного кода. Выполните `apt autoremove` для удаления ставших ненужными пакетов.
Удалите `cmake` для следующего упражнения в установке из исходного кода. Выполните `apt autoremove` для удаления ставших ненужными пакетов.
```
# apt remove cmake cmake-data
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following package was automatically installed and is no longer required:
libuv1
Use 'apt autoremove' to remove it.
The following packages will be REMOVED:
cmake cmake-data
The following held packages will be changed:
cmake cmake-data
0 upgraded, 0 newly installed, 2 to remove and 227 not upgraded.
After this operation, 40.3 MB disk space will be freed.
Do you want to continue? [Y/n]
(Reading database ... 41403 files and directories currently installed.)
Removing cmake (3.25.1-1) ...
Removing cmake-data (3.25.1-1) ...
Processing triggers for man-db (2.11.2-2) ...
root@stud12:~# apt autoremove
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages will be REMOVED:
libuv1
0 upgraded, 0 newly installed, 1 to remove and 227 not upgraded.
After this operation, 305 kB disk space will be freed.
Do you want to continue? [Y/n]
(Reading database ... 38166 files and directories currently installed.)
Removing libuv1:amd64 (1.44.2-1) ...
Processing triggers for libc-bin (2.36-9+deb12u1) ...
# cmake
-bash: /usr/bin/cmake: No such file or directory
```
### 26.
Установите git, если он ещё не установлен. Перейдите в /tmp и вызовите:
Установите `git`, если он ещё не установлен. Перейдите в `/tmp` и вызовите:
```
git clone --depth=1 https://github.com/Kitware/CMake
```
Ваша цель установить пакет в директорию /opt.
Ваша цель установить пакет в директорию `/opt`.
Прочитайте README.md секцию "Building CMake from Scratch". Установите компилятор g++, make. Для поддержки openssl - libssl-dev заголовочные файлы. В качестве --prefix используйте `/opt/cmake/`. Выполните 3 этапа: конфигурация компиляции, компиляция проекта, и установка. Для использования многопоточной компиляции используйте флаг `-j` при вызове `make`.
```
# apt install build-essential -y
# gcc --version
gcc (Debian 13.2.0-5) 13.2.0
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# ./configure
CMake Error at Utilities/cmcurl/CMakeLists.txt:640 (message):
Could not find OpenSSL. Install an OpenSSL development package or
configure CMake with -DCMAKE_USE_OPENSSL=OFF to build without OpenSSL.
# apt install libssl-dev
# ./configure --parallel=4
CMake has bootstrapped. Now run gmake.
# gmake -j
# gmake install
# cmake --version
cmake version 3.28.20231013-gee5f31b
CMake suite maintained and supported by Kitware (kitware.com/cmake).
```
### 27.
Используйте команду `dpkg-reconfigure`, чтобы перенастроить пакеты, связанные с локализацией `console-setup` и раскладкой клавиатуры `keyboard-configuration`.
Используйте команду `dpkg-reconfigure`, чтобы перенастроить пакеты, связанные с локализацией `console-setup` и раскладкой клавиатуры `keyboard-configuration`.

@ -1,66 +1,102 @@
# Задания
### 0.
Обновите список пакетов из настроенных репозиториев в /etc/apt/sources.list командой apt.
Обновите список пакетов из настроенных репозиториев в `/etc/apt/sources.list` командой `apt`.
; TODO как должен выглядеть sources.list
Пример содержимого файла для Debian 12
```
# main состоит из DFSG-compliant пакетов, которым не требуется другое ПО из других зон. Эти пакеты считаются частью дистрибуции Debian
# contrib пакеты содержат DFSG-compliant ПО, но у них зависимостей из зоны main (возможно упакованы в non-free).
# non-free содержит ПО, которое не соответствует DFSG.
# скомпилированные бинарные пакеты
deb http://deb.debian.org/debian/ bookworm main
# оригинальные исходные коды пакетов
deb-src http://deb.debian.org/debian/ bookworm main
# некоторые пакеты для следующего 12.X обнвления доступны только из следующих веток
deb http://deb.debian.org/debian/ bookworm-updates main
deb-src http://deb.debian.org/debian/ bookworm-updates main
# критические обновления пакетов для обнаруженных уязвимостей доступны из репозитория security.debian.org
deb http://security.debian.org/debian-security/ bookworm/updates main
deb-src http://security.debian.org/debian-security/ bookworm/updates main
```
### 1.
Установите пакет apt-file с помощью apt.
Установите пакет `apt-file` с помощью `apt`.
### 2.
Найдите с помощью apt-file пакет, содержащий команду ar.
Найдите с помощью `apt-file` пакет, содержащий команду `ar`.
### 3.
Определите с помощью команды `apt search`, какие варианты пакета содержащего команду ar доступны. Установите подходящий для вашей системы.
Определите с помощью команды `apt search`, какие варианты пакета содержащего команду `ar` доступны. Установите подходящий для вашей системы.
### 4.
Скачайте http://ftp.ru.debian.org/debian/pool/main/c/cmake/cmake_3.24.1-1_amd64.deb в отдельную папку. Перейдите в папку с пакетом и распакуйте .deb командой `ar -x путь-к-пакету`. В папке должны появиться: control.tar.xz data.tar.xz debian-binary.
Скачайте http://ftp.ru.debian.org/debian/pool/main/c/cmake/cmake_3.25.1-1_amd64.deb в отдельную папку. Перейдите в папку с пакетом и распакуйте `.deb` командой `ar -x путь-к-пакету`. В папке должны появиться: `control.tar.xz`, `data.tar.xz`, `debian-binary`.
### 5.
Создайте папку control и распакуйте в неё control.tar.xz с помощью команды `tar xfC путь-к-архиву control`. Изучите содержимое. Сравните с выдачей `dpkg --info ` для .deb файла.
Создайте папку `control` и распакуйте в неё `control.tar.xz` с помощью команды `tar xfC путь-к-архиву control`. Изучите содержимое. Сравните с выдачей `dpkg --info ` для `.deb` файла.
### 6.
Создайте папку data и распакуйте в неё data.tar.xz с помощью команды `tar xfC путь-к-архиву data`. Изучите data с помощью команды `tree`. Сравните с выдачей `dpkg --contents ` для .deb файла.
Создайте папку `data` и распакуйте в неё `data.tar.xz` с помощью команды `tar xfC путь-к-архиву data`. Изучите `data` с помощью команды `tree`. Сравните с выдачей `dpkg --contents ` для `.deb` файла.
### 7.
Попробуйте вызвать исполняемый файл `usr/bin/cmake` из папки. Сопоставьте информацию в control файле пакета с выдачей команды `ldd usr/bin/cmake`. Если исполняемый файл не работает, найдите и установите зависимости в систему. Воспользуйтесь формой поиска на сайте https://www.debian.org/distrib/packages, если поиск по настроенным репозиториям не даёт результата. Добавьте репозиторий в котором есть нужная библиотека командой `apt edit-sources`. Обновите базу данных пакетов командой `apt update`. Завершите установку зависимостей и проверьте, что cmake работает.
Попробуйте вызвать исполняемый файл `usr/bin/cmake` из папки. Сопоставьте информацию в control файле пакета с выдачей команды `ldd usr/bin/cmake`. Если исполняемый файл не работает, найдите и установите зависимости в систему. Воспользуйтесь формой поиска на сайте https://www.debian.org/distrib/packages, если поиск по настроенным репозиториям не даёт результата. Добавьте репозиторий в котором есть нужная библиотека командой `apt edit-sources`. Обновите базу данных пакетов командой `apt update`. Завершите установку зависимостей и проверьте, что `cmake` работает.
### 8.
Утилитой dpkg-query выведите список пакетов, зарегистрированных в dpkg базе данных. Есть ли среди них зависимости cmake, которые вы установили вручную?
Утилитой `dpkg-query` выведите список пакетов, зарегистрированных в `dpkg` базе данных. Есть ли среди них зависимости `cmake`, которые вы установили вручную?
### 9.
Утилитой dpkg-query выведите среди установленных локально пакетов пакет, начинающихся с libc6. Утилитой apt-cache выполните тот же поиск по кэшу apt. Утилитой apt выполните тот же поиск по кэшу apt. Сравните, чем они отличаются.
Утилитой `dpkg-query` выведите среди установленных локально пакетов пакет, начинающихся с `libc6`. Утилитой `apt-cache` выполните тот же поиск по кэшу `apt`. Утилитой `apt` выполните тот же поиск по кэшу `apt`. Сравните, чем они отличаются.
### 10.
Утилитой dpkg-query выведите статус пакета sudo и gcc. Чем выдача отличается от содержимого control файла .deb, скаченного ранее?
Утилитой `dpkg-query` выведите статус пакета `sudo` и `gcc`. Чем выдача отличается от содержимого control файла `.deb`, скаченного ранее?
### 11.
Утилитой dpkg-query выведите список установленных файлов пакета sudo (не выводятся файлы созданные скриптами).
Утилитой `dpkg-query` выведите список установленных файлов пакета `sudo` (не выводятся файлы созданные скриптами).
### 12.
Утилитой dpkg-query выведите список файлов с метаданными пакета (control files), установленных в систему.
Утилитой `dpkg-query` выведите список файлов с метаданными пакета `sudo` (control files).
### 13.
Утилитой dpkg-query выведите содержимое одного из файлов с метаданными пакета (control files).
Утилитой `dpkg-query` выведите содержимое одного из файлов с метаданными пакета `sudo` (control files).
### 14.
Утилитой dpkg-query выведите пути к файлам с метаданными пакета (control files).
Утилитой `dpkg-query` выведите пути к файлам с метаданными пакета `sudo` (control files).
### 15.
Утилитой dpkg-query выполните поиск пакетов, которые установили в систему файл pam.conf.
Утилитой `dpkg-query` выполните поиск пакетов, которые установили в систему файл `pam.conf`.
### 16.
Утилитой dpkg установите cmake .deb пакет, скаченный ранее. Ещё раз посмотрите на зависимости пакета. Как отреагировал dpkg на отсутствие зависимости cmake-data - установил или выдал ошибку?
Утилитой `dpkg` установите `cmake .deb` пакет, скаченный ранее. Ещё раз посмотрите на зависимости пакета. Как отреагировал `dpkg` на отсутствие зависимости `cmake-data` - установил или выдал ошибку?
### 17.
Скачайте cmake-data и его транзитивные зависимости https://packages.debian.org/sid/amd64/cmake. Завершите установку cmake, и проверьте, что команда cmake установлена в систему (например, командами `which`, `find`) и работает `cmake --version`.
Скачайте `cmake-data` и его транзитивные зависимости https://packages.debian.org/sid/amd64/cmake. Завершите установку cmake, и проверьте, что команда cmake установлена в систему (например, командами `which`, `find`) и работает `cmake --version`.
### 18.
Проверьте файлы всех установленных пакетов в системе на наличие изменений/повреждений командой dpkg. Какие файлы не прошли проверку (`??5??????`)?
Проверьте файлы всех установленных пакетов в системе на наличие изменений/повреждений командой `dpkg`. Какие файлы не прошли проверку (`??5??????`)?
Формат выдачи:
```
SM5DLUGT c <file>
```
где
- S размер файла,
- M режим файла,
- 5 MD5 хэш файла,
- D мажорная и минорная версии файла,
- L содержимое символических ссылок файла,
- U владелец файла,
- G группа-владелец файла,
- T время модификации файла,
- c появляется только, если это конфигурационный файл. Как правило именно они меняются и с большей вероятностью не пройдут проверку.
- <file> полный путь к файлу, который не прошёл проверку.
Знак вопроса означает, что файл не может быть проверен по какой-то причине. Подробнее вы можете прочитать в мануале `man dpkg` в секции описывающей ключ `--verify-format`.
### 19.
Сохраните список выбранных действий и состояний (selections) для пакетов в системе утилитой dpkg в файл.
Сохраните список выбранных действий и состояний (selections) для пакетов в системе утилитой `dpkg` в файл.
### 20.
Измените в сохранённом списке действие для пакета vim c текущего на deinstall (`man dpkg`, “Package selection states”).
@ -69,31 +105,31 @@
Запустите команду `apt-get dselect-upgrade`. Какие пакеты будут установлены или удалены?
### 22.
Настройте в `/etc/sudoers` конфигурационном файле для пользователя stud возможность выполнять команды от лица суперпользователя без запроса пароля:
Настройте в `/etc/sudoers` конфигурационном файле для пользователя `stud` возможность выполнять команды от лица суперпользователя без запроса пароля:
```
%sudo ALL=(ALL:ALL) NOPASSWD: ALL
```
Удалите, а затем установите пакет sudo командой `apt remove`. Проверьте содержимое конфигурационного файла на изменения. Проделайте то же самое, но c командой `apt purge`.
### 23.
Удалите cmake и cmake-data с помощью apt. Найдите в репозиториях, какая версия cmake доступна. Создайте файл в директории `/etc/apt/apt.conf.d/default-release` с следующим содержимым (man apt.conf):
Удалите `cmake` и `cmake-data` с помощью `apt`. Найдите в репозиториях, какая версия cmake доступна. Создайте файл в директории `/etc/apt/apt.conf.d/default-release` с следующим содержимым (`man apt.conf`):
```
APT::Default-Release "stable";
```
Повторите поиск. Установите stable версию. Проверьте работоспособность команды и её версию `cmake --version`. Вы можете узнать значения текущих конфигурационных переменных `apt` командой `apt-conf dump`.
Повторите поиск. Установите `stable` версию. Проверьте работоспособность команды и её версию `cmake --version`. Вы можете узнать значения текущих конфигурационных переменных `apt` командой `apt-conf dump`.
### 24.
Заморозьте версию cmake командой `apt-mark` или с помощью `dpkg --get-selections`, `dpkg --set-selections`. Поменяйте умолчания `/etc/apt/apt.conf.d/default-release` на "unstable". Проведите обновление пакетов в системе. cmake не должен сохранить stable версию.
Заморозьте версию cmake командой `apt-mark` или с помощью `dpkg --get-selections`, `dpkg --set-selections`. Поменяйте умолчания `/etc/apt/apt.conf.d/default-release` на `"unstable"`. Проведите обновление пакетов в системе. cmake не должен сохранить stable версию.
### 25.
Удалите cmake для следующего упражнения в установке из исходного кода. Выполните `apt autoremove` для удаления ставших ненужными пакетов.
### 26.
Установите git, если он ещё не установлен. Перейдите в /tmp и вызовите:
Установите `git`, если он ещё не установлен. Перейдите в `/tmp` и вызовите:
```
git clone --depth=1 https://github.com/Kitware/CMake
```
Ваша цель установить пакет в директорию /opt.
Ваша цель установить пакет в директорию `/opt`.
Прочитайте README.md секцию "Building CMake from Scratch". Установите компилятор g++, make. Для поддержки openssl - libssl-dev заголовочные файлы. В качестве --prefix используйте `/opt/cmake/`. Выполните 3 этапа: конфигурация компиляции, компиляция проекта, и установка. Для использования многопоточной компиляции используйте флаг `-j` при вызове `make`.
@ -102,6 +138,9 @@ git clone --depth=1 https://github.com/Kitware/CMake
# Справка
Ссылки:
- web страница со списком пакетов https://www.debian.org/distrib/packages
Релевантные команды:
- apt
- apt-get
@ -116,4 +155,4 @@ git clone --depth=1 https://github.com/Kitware/CMake
- sources.list
- apt.conf
- dpkg.conf
- apt_preferences
- apt_preferences

@ -1,28 +1,28 @@
# Решения
### 1.
Установите пакет nginx.
Установите пакет `nginx`.
```
$ sudo apt install nginx
```
### 2.
Запустите исполняемый файл nginx. Проверьте, что он запустился `ps aux`.
Запустите исполняемый файл `nginx`. Проверьте, что он запустился `ps aux`.
```
$ sudo ps aux | grep nginx
```
### 3.
После запуска nginx им можно управлять, вызывая исполняемый файл с параметром -s. Попробуйте команды:
- stop — быстрое выключение,
- quit — завершение работы с ожиданием завершения обслуживания текущих запросов рабочими процессами,
- reload — перезагрузка файла конфигурации,
- reopen — повторное открытие лог-файлов,
После запуска `nginx` им можно управлять, вызывая исполняемый файл с параметром `-s`. Попробуйте команды:
- `stop` — быстрое выключение,
- `quit` — завершение работы с ожиданием завершения обслуживания текущих запросов рабочими процессами,
- `reload` — перезагрузка файла конфигурации,
- `reopen` — повторное открытие лог-файлов,
используя следующий синтаксис:
```
$ nginx -s signal
```
Команда должна выполняться под тем же пользователем, который запустил nginx.
Команда должна выполняться под тем же пользователем, который запустил `nginx`.
```
$ sudo nginx -s reload
$ sudo nginx -s reopen
@ -32,7 +32,7 @@ $ sudo nginx -s quit
```
### 4.
Сигнал также может быть отправлен процессам nginx с помощью инструментов Unix, таких как утилита kill. Идентификатор процесса главного процесса nginx по умолчанию записывается в файл `nginx.pid` в каталоге `/usr/local/nginx/logs` или `/var/run`.
Сигнал также может быть отправлен процессам `nginx` с помощью инструментов Unix, таких как утилита `kill`. Идентификатор процесса главного процесса `nginx` по умолчанию записывается в файл `nginx.pid` в каталоге `/usr/local/nginx/logs` или `/var/run`.
Завершите корректно работу nginx командой `kill -s QUIT`.
```
@ -40,7 +40,7 @@ $ sudo kill -9 QUIT $(cat /var/run/nginx.pid)
```
### 5.
Настройте сервис nginx, установленный вместе с пакетом. Активируйте его и запустите командой `systemctl`.
Настройте сервис `nginx`, установленный вместе с пакетом. Активируйте его и запустите командой `systemctl`.
```
$ sudo systemctl enable nginx
$ sudo systemctl start nginx
@ -111,28 +111,6 @@ http {
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
#mail {
# # See sample authentication script at:
# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
# # auth_http localhost/auth.php;
# # pop3_capabilities "TOP" "USER";
# # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
# server {
# listen localhost:110;
# protocol pop3;
# proxy on;
# }
#
# server {
# listen localhost:143;
# protocol imap;
# proxy on;
# }
#}
```
### 7.
@ -174,14 +152,14 @@ $ tree /etc/nginx/
Проверьте, что в конфигурационных файлах указаны абсолютные пути.
Проверьте порты прослушивания. Проброшенные порты с 193.32.63.170+X на 10.160.179.10+X: 22, 80, 443.
Проверьте порты прослушивания. Проброшенные порты с `193.32.63.170+X` на `10.160.179.10+X`: `22`, `80`, `443`.
Проверьте, конфигурации на предмет синтаксических ошибок. Завершения строк `;`. Помочь сделать проверку может команда `nginx -t`.
Проверьте, что сервис nginx запущен.
Проверьте, что добавили символическую ссылку в /etc/nginx/sites-enabled на конфигурационный файл в /etc/nginx/sites-available.
Проверьте, что добавили символическую ссылку в `/etc/nginx/sites-enabled` на конфигурационный файл в `/etc/nginx/sites-available`.
Если не открываются скаченные изображения, проверьте, что вы используете прямые ссылки для скачивания. Проверьте размер файлов изображений.
Если вы выбрали сложный вариант решения в 10 задании, проверьте, что машины 10.160.179.10+X и 10.160.179.10+20+X находятся в одной vlan vmbr499 с доступом в интернет, друг друга "видят" командой ping.
Если вы выбрали сложный вариант решения в 10 задании, проверьте, что машины `10.160.179.10+X` и `10.160.179.10+20+X` находятся в одной vlan `vmbr499` с доступом в интернет, друг друга "видят" командой `ping`.

@ -97,7 +97,7 @@ ln -s /etc/nginx/sites-available/static-server.conf /etc/nginx/sites-enabled/sta
Проверьте, что веб-сервер работает по адресу 193.32.63.170+X, где X ваши идентификатор. Если что-то не работает должным образом, вы можете попытаться выяснить причину в файлах `access.log` и `error.log` в каталоге `/usr/local/nginx/logs` или `/var/log/nginx`.
### 9.
### 9.1
Переведите веб-сервер на https. Измените порт прослушивания на `443 ssl`, сгенерируйте сертификаты и ключ командой openssl в директорию `/data/certs/`. Вам понадобятся следующие параметры в блоке server:
- listen,
- ssl_certificate,
@ -115,6 +115,9 @@ server {
}
```
### 9.2
Переведите веб-сервер на https с сертификатом, полученным утилитой `certbot`` от Letsencrypt.
### 10.1
Одним из частых применений nginx является его настройка в качестве прокси-сервера, что означает сервер, который получает запросы, передает их на проксируемые серверы, получает от них ответы и отправляет их клиентам.
@ -135,11 +138,11 @@ server {
Это будет простой сервер, который прослушивает порт 80 ( директиву listen можно не указывать, если используется стандартный порт 80) и отображает все запросы в каталог `/data/www` локальной файловой системе. Создайте этот каталог и поместите в него файл `index.html` с содержимым "Hello from internal server!". Обратите внимание, что корневая директива находится в контексте сервера. Такая корневая директива используется, когда блок местоположения, выбранный для обслуживания запроса, не включает собственную корневую директиву.
### 10.2
Используйте конфигурацию сервера из предыдущего задания 7 в качестве основы конфигурации прокси-сервера. В первый блок location поместите директиву `proxy_pass` с указанным в параметре протоколом, именем и портом проксируемого сервера (в вашем случае это http://10.160.179.10+X:80):
Используйте конфигурацию сервера из предыдущего задания 7 в качестве основы конфигурации прокси-сервера. В первый блок location поместите директиву `proxy_pass` с указанным в параметре протоколом, именем и портом проксируемого сервера (в вашем случае это http://10.160.179.10+20+X:80):
```
server {
location / {
proxy_pass http://10.160.179.10+X:80;
proxy_pass http://10.160.179.10+20+X:80;
}
location /images/ {

@ -1,68 +1,202 @@
# Решения
### 1.
## 0.
Например, diff <(ls foo) <(ls bar) покажет различия между файлами в каталогах foo и bar.
```
stud@stud12:~$ mkdir v1 v2
stud@stud12:~$ touch v1/a.txt v1/b.txt v2/b.txt v2/c.txt
stud@stud12:~$ diff <(ls v1) <(ls v2)
1d0
< a.txt
2a2
> c.txt
```
## 1.
Выполните следующие примеры:
```
stud@stud12:~$ false || echo "Opps, fail"
Opps, fail
stud@stud12:~$ true || echo "Opps, fail"
```
```
stud@stud12:~$ true && echo "Things went well"
Things went well
stud@stud12:~$ false && echo "Things went well"
```
```
stud@stud12:~$ true; echo "Always"
Always
stud@stud12:~$ false; echo "Always"
Always
```
*Что произойдёт в данном случае?
```
stud@stud12:~$ (echo red; echo green 1>&2) | echo blue
```
В большинстве случаев эта команда выводит "синий зеленый". Но примерно в 1% случаев она выводит "зеленый синий". А иногда выводится просто "синий". Для большей детерминированности добавим в пример задержки в 100мс. В реальности эта задержка на выполнение инструкций команды будет зависеть от загрузки системы и приоритетов выполнения задач.
```
stud@stud12:~$ (echo red; echo green 1>&2) | echo blue
blue
green
stud@stud12:~$ (echo red; echo green 1>&2) | (sleep 0.1; echo blue)
green
blue
stud@stud12:~$ (sleep 0.1; echo red; echo green 1>&2) | echo blue
blue
```
Мы имеем три порядка выполнения:
- `echo` красного цвета происходит до выхода `echo` синего цвета, поэтому левая сторона не получает сигнал SIGPIPE, но после этого происходит `echo` зеленого цвета. На выходе получается `"blue green"`.
- Оболочка слева успевает выполнить оба своих `echo` до того, как выполнится `echo blue`. На выходе получается `"green blue"`.
- Выполняется `echo blue` и выходит, закрывая pipe, до того, как завершится `echo red`. Оболочка в левой части конвейера записывает вывод в закрытый pipe, получает SIGPIPE и выходит из неё, не продолжая выполнять `echo green`. На выходе получается `"blue"`.
Команда `echo red` выполняется благодаря наличию буферизации. Так как ничто не читает её вывод `STDOUT`, то при заполнении буфера процесс `echo red` заблокируется. В случае отстуствия буфера `echo red; echo green 1>&2` бы не выполнился.
Из `man pipe`: "since Linux 2.6.11, the pipe capacity has been increased to 16 pages, which translates to 65,536 bytes on systems with a page size of 4096 bytes."
```
(i=1; while true; do echo red; echo $i 1>&2; ((i+=1)); done) | sleep 1
```
Вывод остановится на значении 16384 = 65536 / 4, т.к. "red\n" равен 4 байта. Вызвав `echo` только с переносом строки вместо `echo red` мы получим значение `65536`.
Таким образом, всё сводится к трём основным аспектам работы конвейров:
- Обе стороны выполняются одновременно в собственных процессах.
- Благодаря буферизации запись в pipe не блокируется мгновенно.
- Когда правая часть конвейра завершается, оболочка убивает левую часть.
## 2
Напишите .sh скрипт в котором в переменную date присваивается значение текущей даты, в переменную claim - строка "snow is white". После вызова скрипт должен выводить строку, используя переменные date и claim:
```
Ср 14 сен 2022 14:50:46 +04: The claim that “snow is white” is true if and only if snow is white.
```
Сделайте файл исполняемым для владельца и вызовите указанием полного или относительного пути к нему.
содержимое скрипта 1.sh
```
содержимое скрипта 2.sh
```bash
#!/bin/bash
date=$(date)
claim='snow is white'
echo "$date: The claim that \"$claim\" is true if and only if $claim."
```
```
stud@stud12:~$ chmod u+x 2.sh
stud@stud12:~$ ./2.sh
Tue Oct 31 08:19:58 AM EDT 2023: The claim that "snow is white" is true if and only if snow is white.
```
## 3
Напишите скрипт, который создает каталог, а затем переходит в него, создаёт в нём файл и записывает в него значения всех специальных переменных. Путь к каталогу должен быть передан в качестве первого аргумента.
```bash
stud@stud12:~$ cat 3.sh
#!/bin/bash
path_to_dir=$1
vars=('$0' '$1' '$2' '$#' '$?' '$$' '$_' '$@' '$RANDOM' '$HOME' '$USER')
mkdir $path_to_dir
cd $path_to_dir
for cmd in ${vars[@]}; do
echo ${cmd}: $(eval echo $cmd) | tee -a all_vars;
done
```
```
stud@stud12:~$ ./3.sh test
$0: ./3.sh
$1: test
$2:
$#: 1
$?: 0
$$: 89872
$_: test
$@: test
$RANDOM: 29923
$HOME: /home/stud/
$USER: stud
```
### 2.
Напишите функцию в скрипте, которая создает каталог, путь к которому передан в качестве первого аргумента и переходит в него. Проверьте работу функции в этом же файле. Работает ли функция за пределами контекста скрипта?
## 4
Напишите аналогичный предыдущему заданию скрипт, но оберните все действия в функцию, а в конце скрипта выполните эту функцию. Проверьте работу скрипта.
```bash
$ cat 2.sh
mkdir_cd () {
mkdir -p $1
cd $1
echo current dir: $(pwd)
stud@stud12:~$ cat 4.sh
#!/bin/bash
f () {
path_to_dir=$1
vars=('$0' '$1' '$2' '$#' '$?' '$$' '$_' '$@' '$RANDOM' '$HOME' '$USER')
mkdir $path_to_dir
cd $path_to_dir
for cmd in ${vars[@]}; do
echo ${cmd}: $(eval echo $cmd) >> all_vars;
done
}
mkdir_cd $1
stud@stud15:~$ ./2.sh /tmp/1/2/3/4/5
current dir: /tmp/1/2/3/4/5
stud@stud15:~$
f $1
```
Заметим, что при интерпретации команды в `eval` используются глобальные значения специальных переменных скрипта, а не функции.
```
stud@stud12:~$ cat test2/all_vars
$0: ./4.sh
$1: test2
$2:
$#: 1
$?: 0
$$: 90118
$_: 90118
$@: test2
$RANDOM: 14079
$HOME: /home/stud/
$USER: stud
```
После выполнения скрипта текущая директория не изменилась.
Доступна ли функция за пределами контекста скрипта?
```
stud@stud12:~$ f
-bash: f: command not found
```
Заведите внутри функции глобальную `a` и локальную переменную `local b`. Вызовите функцию в скрипте. Выведите обе переменные на экран внутри функции после присвоения значений переменным и после вызова функции.
```bash
$ mkdir_cd () {
mkdir -p $1
cd $1
echo current dir: $(pwd)
stud@stud12:~$ cat 4_2.sh
#!/bin/bash
a='global a'
f () {
local b='local b'
echo a: ${a}, b: ${b}
}
stud@stud15:~$ mkdir_cd /tmp/a/b/c/d
current dir: /tmp/a/b/c/d
stud@stud15:/tmp/a/b/c/d$
echo a: ${a}, b: ${b}
f
echo a: ${a}, b: ${b}
```
```
stud@stud12:~$ ./4_2.sh
a: global a, b:
a: global a, b: local b
a: global a, b:
```
После определения функции и вызова в оболочке изменилась.
## 5.
Функции выполняются в текущей среде оболочке, тогда как скрипты выполняются в своем собственном процессе.
### 3.
Менее известной, но полезной может быть подстановка дескриптора файла с результатом выполнения команды. `<( CMD )` выполнит `CMD` и поместит вывод во временный файл и заменит `<()` именем этого файла. Это полезно, когда команды ожидают, что значения будут переданы через файл, а не STDIN. Например, `diff <(ls foo) <(ls bar)` покажет различия между файлами в каталогах foo и bar.
Проверьте, что функции могут изменять переменные среды, например, изменить текущий каталог, тогда как скрипт не может. Напишите скрипт, в котором инициализируются две переменные A и B. Перед одной из них указывается export. Выполните скрипт и посмотрите на выдачу команды env. Выполните файл командой source (документация в source --help и секции встроенных команд man bash).
```bash
$ cat 8.sh
#!/bin/bash
A=1
export B=2
```
Какие переменные экспортировались в оболочку?
```
$ diff <(cat buylist) <(cat bought)
1,3c1,5
< salad
< milk
< bread
---
> icecream
> cheese
> cake
> lays
> beer
stud@stud12:~$ ./8.sh
stud@stud12:~$ env | grep -E "^A|B"
stud@stud12:~$ source ./8.sh
stud@stud12:~$ env | grep -E "^A|B"
B=2
```
Экспортировалась `B`.
### 4.
Попробуйте условные выражения в скрипте в if конструкции:
## 6.
Попробуйте условные выражения в скрипте в if конструкции.
```bash
$ cat 4.sh
$ cat 6.sh
if [[ true && true ]]
then
echo "True"
@ -72,84 +206,207 @@ if [[ true || false ]]
then
echo "True"
fi
stud@stud15:~$ ./4.sh
```
```
stud@stud12:~$ ./6.sh
True
True
```
### 5.
Напишите скрипт, который проходит по всем файлам, переданным в качестве аргументов, и ищет в них строку hello. Перенаправьте grep `STDOUT` и `STDERR` в специальный файл `/dev/null`. Для каждого файла в if создайте файл с содержимым `hello`, если `grep` завершился с ошибкой.
## 6.5
## 7.
Напишите скрипт, который проходит по всем файлам, переданным в качестве аргументов, и ищет в них строку `hello`. Перенаправьте `grep` `STDOUT` и `STDERR` в специальный файл `/dev/null`. Для каждого файла в `if` создайте файл с содержимым `hello`, если `grep` завершился с ошибкой.
```bash
$ cat 5.sh
$ cat 7.sh
#!/bin/bash
for f in $@; do
grep hello $f 2> /dev/null 1> /dev/null
if [[ $? -ne 0 ]]
then
echo "hello" > $f
fi
$ ./5.sh /tmp/one /tmp/two /tmp/three
grep hello $f 2> /dev/null 1> /dev/null
if [[ $? -ne 0 ]]
then
echo $f has no hello in it. correcting.
echo "hello" > $f
fi
done
```
```
stud@stud12:/home/stud$ ./7.sh /tmp/one /tmp/two /tmp/three
/tmp/one has no hello in it. correcting.
/tmp/two has no hello in it. correcting.
/tmp/three has no hello in it. correcting.
$ grep hello /tmp/* 2> /dev/null
stud@stud12:/home/stud$ ./7.sh /tmp/one /tmp/two /tmp/three
stud@stud12:/home/stud$ grep hello /tmp/* 2> /dev/null
/tmp/one:hello
/tmp/three:hello
/tmp/two:hello
```
### 6.
## 8.
Установите пакет shellcheck и проверьте написанный вами ранее скрипт одноименной командой.
```bash
$ shellcheck 5.sh
stud@stud12:/home/stud$ shellcheck 7.sh
In 5.sh line 1:
In 7.sh line 2:
for f in $@; do
^-- SC2148 (error): Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive.
^-- SC2068 (error): Double quote array expansions to avoid re-splitting elements.
In 5.sh line 2:
grep hello $f 2> /dev/null 1> /dev/null
^-- SC2086 (info): Double quote to prevent globbing and word splitting.
In 7.sh line 3:
grep hello $f 2> /dev/null 1> /dev/null
^-- SC2086 (info): Double quote to prevent globbing and word splitting.
Did you mean:
grep hello "$f" 2> /dev/null 1> /dev/null
Did you mean:
grep hello "$f" 2> /dev/null 1> /dev/null
In 5.sh line 3:
if [[ $? -ne 0 ]]
^-- SC2181 (style): Check exit code directly with e.g. 'if ! mycmd;', not indirectly with $?.
In 7.sh line 4:
if [[ $? -ne 0 ]]
^-- SC2181 (style): Check exit code directly with e.g. 'if ! mycmd;', not indirectly with $?.
In 5.sh line 5:
echo $f has no hello in it. correcting.
^-- SC2086 (info): Double quote to prevent globbing and word splitting.
In 7.sh line 6:
echo $f has no hello in it. correcting.
^-- SC2086 (info): Double quote to prevent globbing and word splitting.
Did you mean:
echo "$f" has no hello in it. correcting.
Did you mean:
echo "$f" has no hello in it. correcting.
In 5.sh line 6:
echo "hello" > $f
^-- SC2086 (info): Double quote to prevent globbing and word splitting.
In 7.sh line 7:
echo "hello" > $f
^-- SC2086 (info): Double quote to prevent globbing and word splitting.
Did you mean:
echo "hello" > "$f"
Did you mean:
echo "hello" > "$f"
For more information:
https://www.shellcheck.net/wiki/SC2068 -- Double quote array expansions to ...
https://www.shellcheck.net/wiki/SC2148 -- Tips depend on target shell and y...
https://www.shellcheck.net/wiki/SC2086 -- Double quote to prevent globbing ...
https://www.shellcheck.net/wiki/SC2181 -- Check exit code directly with e.g...
```
### 7.
Напишите скрипт, который выполняет следующий код:
## 9.
### 9.1
Почему в этом примере не работает печать?
```bash
#!/usr/bin/env bash
set -e
i=0
let i++
echo "i is $i"
```
```
stud@stud12:/home/stud$ bash 9_1.sh
```
Согласно руководству, `set -e` завершает работу, если простая команда завершается с ненулевым статусом. Оболочка не завершает работу, если команда, которая завершилась неудачей, является частью списка команд, следующего сразу за ключевым словом `while` или `until`, частью проверки в операторе `if`, частью списка `&&` или `||`, или если возвращаемое значение команды инвертируется через `!`.
Команда `let` - это простая команда, и она не попадает ни под одно из исключений из приведенного выше списка. Более того, `help let` сообщает нам: "Если последний ARG вычисляется в `0`, `let` возвращает `1`; в противном случае возвращается `0`". `i++` равен `0`, поэтому `let i++` возвращает `1` и срабатывает `set -e`. Скрипт прерывается. Потому что мы добавили `1` в переменную.
### 9.2
Почему этот вариант иногда работает? В каких версиях bash он работает, а в каких - нет?
```bash
#!/usr/bin/env bash
set -e
i=0
((i++))
echo "i is $i"
```
`((...))` не является простой командой в соответствии с грамматикой оболочки (`man --pager='less -p ^SHELL GRAMMAR' bash`). Поэтому она не может вызвать прерывание `set -e`, даже если в данном конкретном случае возвращает `1` (поскольку при установке `i` в `1` командой `i++` кодом возврата считается `0`, а `0` в математическом контексте считается ложью).
Однако в bash 4.1 это поведение изменилось. Упражнение 2 работает только в bash 4.0 и более ранних версиях! В bash 4.1 `((...))` квалифицируется как `set -e abortion`, и это упражнение ничего не выведет, как и упражнение 1.
Вы не можете рассчитывать на то, что он будет вести себя последовательно в разных выпусках оболочки.
### 9.3
Почему эти два сценария не идентичны?
```bash
#!/usr/bin/env bash
set -e
test -d nosuchdir && echo no dir
echo survived
```
```bash
#!/usr/bin/env bash
set -e
f() { test -d nosuchdir && echo no dir; }
f
echo survived
```
```
stud@stud12:/home/stud$ bash 9_3_a.sh
survived
stud@stud12:/home/stud$ bash 9_3_b.sh
stud@stud12:/home/stud$
```
В первом скрипте тестовая команда является частью любой команды, выполняемой в списке `&&` или `||`, кроме команды, следующей за последней `&&` или `||` (man page Bash 4.2), поэтому она не приводит к выходу оболочки.
Во втором сценарии это также верно, поэтому оболочка не выходит сразу после команды `test ... &&`. Однако функция `fn` возвращает `1` (отказ), поскольку таков был статус выхода последней команды, выполненной в функции. Поэтому простая команда `fn` в основном теле скрипта возвращает `1` (отказ), что приводит к выходу оболочки.
## 9.4
Почему эти два сценария не идентичны?
```bash
#!/usr/bin/env bash
set -e
f() { test -d nosuchdir && echo no dir; }
f
echo survived
```
```bash
#!/usr/bin/env bash
set -e
f() { if test -d nosuchdir; then echo no dir; fi; }
f
echo survived
```
```
stud@stud12:/home/stud$ bash 9_4_a.sh
stud@stud12:/home/stud$ bash 9_4_b.sh
survived
```
Первый скрипт, приведенный выше, аналогичен второму скрипту из упражнения 3.
Во втором скрипте мы наблюдаем один из вариантов, в котором `if` и `&&` не являются одним и тем же. В руководстве, в разделе Compound Commands, мы находим это предложение в определении `if`:
Статус выхода - это статус выхода последней выполненной команды или ноль, если ни одно условие не было выполнено.
Поскольку термины "команда" и "условие" в man-странице особо не различаются, то, следуя первой части этого объяснения из `man bash`, может показаться, что статус выхода из структуры `if` должен быть статусом выхода тестовой команды, однако в данном случае тестовая команда является условием логической структуры `if`, поэтому применима вторая часть приведенного выше объяснения. Если `test` или любой список команд в условной позиции логической структуры возвращает код выхода, не равный `0`, и при этом нет ветвей `elif` или `else`, то код выхода всей структуры `if` по-прежнему равен `0`.
В более ясной формулировке, поскольку тест не является истинным и никакие последующие команды не выполняются, `if` должна возвращать `0`. Это означает, что `fn` возвращает `0`, и оболочка не завершается.
### 9.5
```bash
#!/usr/bin/env bash
set -e
read -r foo < configfile
```
```
stud@stud12:/home/stud$ bash 9_5.sh
9_5.sh: line 3: configfile: No such file or directory
```
Очевидно, что в случае отсутствия или нечитаемости файла `configfile` работа будет прервана. Он также прервется (возможно, неожиданно), если в файле отсутствует завершающая новая строка. Это происходит потому, что `read` возвращает код ошибки, если он достиг конца файла до прочтения ожидаемой новой строки. Однако содержимое файла все равно будет прочитано, и переменная будет заполнена.
Если бы не было `set -e`, скрипт правильно заполнил бы переменную и пошел дальше, и тот факт, что файл "неполный", не стал бы проблемой. Заметим, что использование списка `while` или `if` с `read` приведет к заполнению переменной в любом случае, поскольку оба варианта являются исключениями из правил `set -e`.
Рекомендация проста: не используйте `set -e`. Вместо этого добавьте собственную проверку ошибок.
## 10.
Напишите скрипт, который выполняет следующий код:
```python
$ cat ./7.sh
#!/usr/bin/env python
import sys
for arg in reversed(sys.argv[1:]):
print(arg)
```
```
$ ./7.sh 1 2 3 4 5
5
4
@ -158,30 +415,14 @@ $ ./7.sh 1 2 3 4 5
1
```
### 8.
Функции выполняются в текущей среде оболочке, тогда как скрипты выполняются в своем собственном процессе.
## 11.
Скажем, у вас есть команда, которая редко дает сбой. Чтобы отладить её, вам нужно зафиксировать её выходные данные, но это может занять много времени, чтобы поймать неудачный запуск. Напишите сценарий bash, который запускает следующий сценарий до тех пор, пока он не завершится аварийно, записывает стандартный вывод и потоки ошибок в файлы и печатает все в конце. Бонусный балл, за то, что вы можете сообщить, сколько запусков потребовалось для сбоя сценария.
Проверьте, что функции могут изменять переменные среды, например, изменить текущий каталог, тогда как скрипт не может. Напишите скрипт, в котором инициализируются две переменные `A` и `B`. Перед одной из них указывается `export `. Выполните скрипт и посмотрите на выдачу команды `env`. Выполните файл командой source (source --help). Какие переменные экспортировались в оболочку?
```bash
$ cat 8.sh
#!/bin/bash
A=1
export B=2
stud@stud15:~$ ./8.sh
stud@stud15:~$ env | grep -E "^A|B"
stud@stud15:~$ source ./8.sh
stud@stud15:~$ env | grep -E "^A|B"
B=2
```
### 9.
Напишите сценарий bash, который запускает следующий сценарий до тех пор, пока он не завершится аварийно, записывает стандартный вывод и потоки ошибок в файлы и печатает все в конце.
```bash
stud@stud15:~$ cat random_bug_script.sh
```bash
#!/usr/bin/env bash
n=$(( RANDOM % 100 ))
echo $n
if [[ n -eq 42 ]]; then
echo "Something went wrong"
>&2 echo "The error was using magic numbers"
@ -189,8 +430,10 @@ if [[ n -eq 42 ]]; then
fi
echo "Everything went according to plan"
```
stud@stud15:~$ cat repeat_until_error.sh
```bash
stud@stud12:~$ cat repeat_until_error.sh
#!/bin/bash
echo "" > output.log
echo "" > error.log
@ -207,42 +450,12 @@ while true; do
fi
i=$((i+1))
done
```
```
stud@stud12:~$ ./repeat_until_error.sh ./random_bug_script.sh
Took 7 iterations to get an error.
\noutput.log
stud@stud15:~$ ./repeat_until_error.sh ./random_bug_script.sh
Took 37 iterations to get an error.
output.log
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
Everything went according to plan
@ -251,93 +464,56 @@ Everything went according to plan
Everything went according to plan
Everything went according to plan
Something went wrong
error.log
\nerror.log
The error was using magic numbers
```
Бонусный балл, за то, что вы можете сообщить, сколько запусков потребовалось для сбоя сценария.
```bash
stud@stud15:~$ cat mean.sh
#!/bin/bash
script=$1
iters=$2
sum=0
for i in $(seq $iters)
do
failedoniter=$(bash $script | grep 'Took' | awk '{ print $2; }')
sum=$((sum+failedoniter))
done
echo Done $iters trials.
echo Mean number of steps until error: $(( sum / iters ))
$ time ./mean.sh "./repeat_until_error.sh ./random_bug_script.sh" 1000
Done 1000 trials.
Mean number of steps until error: 99
real 2m6,924s
user 1m36,964s
sys 0m29,409s
```
### 10.
Напишите скрипт, который:
- создаёт пользователя на двух машинах,
- кроме домашней директории заводит папку для пользователя в `/ceph/` с нужными правами,
- создаёт ссылку в домашней директории на директорию в `/ceph/`,
- ограничивает доступ к домашней папке всем, кроме владельца,
- генерирует пользователям ключи ed25519, рассылает по машинам и регистрирует ключи для беспарольного перемещения пользователя между машинами.
## 12.
Настройка беспарольного перехода для суперпользователя между машинами
Настройка беспарольного перехода для суперпользователя между машинами.
```
root@stud15:~# cat .ssh/config
root@stud12:~# cat ./.ssh/config
Host w001
HostName 10.160.179.25
HostName 10.160.179.22
Host w002
HostName 10.160.179.55
HostName 10.160.179.42
root@stud15:~# hostname -i
10.160.179.25
root@stud15-v1:~# hostname -i
10.160.179.55
root@stud12:~# ip a show ens18 | grep inet
inet 10.160.179.22/24 brd 10.160.179.255 scope global ens18
inet6 fe80::5871:c6ff:fe12:f553/64 scope link
root@stud15-v1:~# cat /etc/ssh/sshd_config | grep PermitRootLogin
PermitRootLogin yes
root@stud12:~# ssh w002 "ip a show ens18 | grep inet"
root@10.160.179.42's password:
inet 10.160.179.42/24 brd 10.160.179.255 scope global ens18
inet6 fe80::28d4:acff:fe73:5b9/64 scope link
root@stud15-v1:~# systemctl restart sshd
root@stud12:~# ssh w002 "cat /etc/ssh/sshd_config | grep PermitRootLogin "
root@10.160.179.42's password:
# PermitRootLogin prohibit-password
PermitRootLogin yes
# the setting of "PermitRootLogin prohibit-password".
root@stud15:~# ssh-copy-id w002
root@stud12:~# ssh-copy-id w002
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@10.160.179.55's password:
root@10.160.179.42's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'w002'"
and check to make sure that only the key(s) you wanted were added.
root@stud15-v1:~# cat /etc/ssh/sshd_config | grep PermitRootLogin
PermitRootLogin prohibit-password
root@stud15-v1:~# systemctl restart sshd
root@stud15:~# ssh-copy-id w001
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '10.160.179.25 (10.160.179.25)' can't be established.
ECDSA key fingerprint is SHA256:3K1vZ3p2zlZpJabnqm3ZqwUPkmxxnIHiqYplqRLEku8.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.
(if you think this is a mistake, you may want to use -f option)
root@stud12:~# ssh w002 "cat /etc/ssh/sshd_config | egrep '^PasswordAuthentication|^PermitRootLogin'"
PermitRootLogin prohibit-password
PasswordAuthentication no
```
Скрипт
```bash
root@stud15:~# cat create_user.sh
root@stud12:~# cat create_user.sh
#!/bin/bash
help() {
@ -375,57 +551,67 @@ for node in $nodes; do
scp -r /root/users.ssh/$user/ $node:/home/$user/.ssh
ssh "$node" "chown -R $user:$user /home/$user/.ssh && chmod 0700 /home/$user/.ssh/"
done
```
root@stud15:~# cat nodes
10.160.179.25
10.160.179.55
```
root@stud12:~# cat nodes
10.160.179.22
10.160.179.42
```
Проверка
```
root@stud15:~# ./create_user.sh nodes user6
root@stud12:~# ./create_user.sh nodes user22
Generating public/private ed25519 key pair.
Your identification has been saved in /root/users.ssh/user6/id_ed25519
Your public key has been saved in /root/users.ssh/user6/id_ed25519.pub
Your identification has been saved in /root/users.ssh/user22/id_ed25519
Your public key has been saved in /root/users.ssh/user22/id_ed25519.pub
The key fingerprint is:
SHA256:FdusRTajDoM/7us/Tyf3VCmu/8kAWjWoYkerUGKggzg root@stud15
SHA256:qz7py+1prq6iQ2YO2pmSoXBiujCVVKhnmqi6LvuA/gM root@stud12
The key's randomart image is:
+--[ED25519 256]--+
| . . = |
|o . . . O.o |
|Eo o..o.+.+o |
| .. . o..=oo. . .|
| . oS+oo . ..|
| o.+.o o . .|
| ... ooo .|
| . ...+oo.|
| .+o.+o..+.|
| .. |
| .. |
| .. |
|..o. |
|.=o S |
|XE. . |
|^*.o .. |
|%+=. .oo.. |
|X@ooo=OB= |
+----[SHA256]-----+
# 10.160.179.25:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1
# 10.160.179.25:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1
# 10.160.179.25:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1
# 10.160.179.25:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1
# 10.160.179.25:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1
# 10.160.179.55:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1
# 10.160.179.55:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1
# 10.160.179.55:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1
# 10.160.179.55:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1
# 10.160.179.55:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1
10.160.179.25 useradd user6 --create-home --shell=/bin/bash --key HOME_MODE=0700; mkdir -p /ceph/user6 -m 0700; chown user6:user6 /ceph/user6; ln -s /ceph/user6 /home/user6/ceph; chown user6:user6 --no-dereference /home/user6/ceph
id_ed25519.pub 100% 93 484.7KB/s 00:00
id_ed25519 100% 399 2.8MB/s 00:00
authorized_keys 100% 93 746.1KB/s 00:00
known_hosts 100% 1957 12.5MB/s 00:00
10.160.179.55 useradd user6 --create-home --shell=/bin/bash --key HOME_MODE=0700; mkdir -p /ceph/user6 -m 0700; chown user6:user6 /ceph/user6; ln -s /ceph/user6 /home/user6/ceph; chown user6:user6 --no-dereference /home/user6/ceph
id_ed25519.pub 100% 93 434.1KB/s 00:00
id_ed25519 100% 399 2.4MB/s 00:00
authorized_keys 100% 93 625.8KB/s 00:00
known_hosts 100% 1957 10.4MB/s 00:00
root@stud15:~#
user6@stud15:~$ ssh 10.160.179.55
Linux stud15-1v15 5.10.0-17-amd64 #1 SMP Debian 5.10.136-1 (2022-08-13) x86_64
# 10.160.179.22:22 SSH-2.0-OpenSSH_9.2p1 Debian-2
# 10.160.179.22:22 SSH-2.0-OpenSSH_9.2p1 Debian-2
# 10.160.179.22:22 SSH-2.0-OpenSSH_9.2p1 Debian-2
# 10.160.179.22:22 SSH-2.0-OpenSSH_9.2p1 Debian-2
# 10.160.179.22:22 SSH-2.0-OpenSSH_9.2p1 Debian-2
# 10.160.179.42:22 SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u1
# 10.160.179.42:22 SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u1
# 10.160.179.42:22 SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u1
# 10.160.179.42:22 SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u1
# 10.160.179.42:22 SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u1
10.160.179.22 useradd user22 --create-home --shell=/bin/bash --key HOME_MODE=0700; mkdir -p /ceph/user22 -m 0700; chown user22:user22 /ceph/user22; ln -s /ceph/user22 /home/user22/ceph; chown user22:user22 --no-dereference /home/user22/ceph
useradd: user 'user22' already exists
known_hosts 100% 1957 6.2MB/s 00:00
id_ed25519.pub 100% 93 431.8KB/s 00:00
id_ed25519 100% 399 1.6MB/s 00:00
authorized_keys 100% 93 503.8KB/s 00:00
10.160.179.42 useradd user22 --create-home --shell=/bin/bash --key HOME_MODE=0700; mkdir -p /ceph/user22 -m 0700; chown user22:user22 /ceph/user22; ln -s /ceph/user22 /home/user22/ceph; chown user22:user22 --no-dereference /home/user22/ceph
useradd: user 'user22' already exists
known_hosts 100% 1957 4.9MB/s 00:00
id_ed25519.pub 100% 93 356.6KB/s 00:00
id_ed25519 100% 399 1.4MB/s 00:00
authorized_keys 100% 93 384.4KB/s 00:00
```
```
root@stud12:~# su - user22
user22@stud12:~$ ssh 10.160.179.42
The authenticity of host '10.160.179.42 (10.160.179.42)' can't be established.
ED25519 key fingerprint is SHA256:u9oSjb/BWxCt6BmjdCGf57l9Fp1wvSl8X6Ip3nHYCSU.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.160.179.42' (ED25519) to the list of known hosts.
Linux debian 6.1.0-13-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.55-1 (2023-09-29) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
@ -433,8 +619,13 @@ individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
user6@stud15-1v15:~$ ssh 10.160.179.25
Linux stud15 5.10.0-16-amd64 #1 SMP Debian 5.10.127-1 (2022-06-30) x86_64
user22@debian:~$ ssh 10.160.179.22
The authenticity of host '10.160.179.22 (10.160.179.22)' can't be established.
ED25519 key fingerprint is SHA256:rqN99l7uB8lGIeqGb4wEa/BIhlZBUPMF2pGLYQem9qI.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.160.179.22' (ED25519) to the list of known hosts.
Linux stud12 6.1.0-12-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.52-1 (2023-09-07) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
@ -442,27 +633,10 @@ individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
user6@stud15:~$
root@stud15:~# ls -la /home/user6/
total 28
drwx------ 3 user6 user6 4096 сен 15 11:49 .
drwxr-xr-x 13 root root 4096 сен 15 11:47 ..
-rw------- 1 user6 user6 18 сен 15 11:49 .bash_history
-rw-r--r-- 1 user6 user6 220 мар 27 22:40 .bash_logout
-rw-r--r-- 1 user6 user6 3526 мар 27 22:40 .bashrc
lrwxrwxrwx 1 user6 user6 11 сен 15 11:47 ceph -> /ceph/user6
-rw-r--r-- 1 user6 user6 807 мар 27 22:40 .profile
drwx------ 2 user6 user6 4096 сен 15 11:47 .ssh
root@stud15:~# ls -la /ceph
total 32
drwxr-xr-x 8 root root 4096 сен 15 11:47 .
drwxr-xr-x 21 root root 4096 сен 15 11:12 ..
drwx------ 2 user1 user1 4096 сен 15 11:14 user1
drwx------ 2 user2 user2 4096 сен 15 11:25 user2
drwx------ 2 user3 user3 4096 сен 15 11:38 user3
drwx------ 2 user4 user4 4096 сен 15 11:42 user4
drwx------ 2 user5 user5 4096 сен 15 11:44 user5
drwx------ 2 user6 user6 4096 сен 15 11:47 user6
user22@stud12:~$
logout
Connection to 10.160.179.22 closed.
user22@debian:~$
logout
Connection to 10.160.179.42 closed.
```

@ -1,92 +1,224 @@
# Задания
Сценарии оболочки — это следующий шаг в сложности комбинирования команд после конвейеров. Большинство оболочек имеют собственный язык сценариев с переменными, потоком управления и собственным синтаксисом. Сценарии оболочки отличаются от других языков программирования сценариев тем, что они оптимизированы для выполнения задач, связанных с оболочкой. Таким образом, создание конвейеров команд, сохранение результатов в файлы и чтение из стандартного ввода являются примитивами в сценариях оболочки, что делает их более простыми в использовании, чем языки сценариев общего назначения. Далее задания посвящены сценариям bash, поскольку они наиболее распространены.
Масштабируемый подход к управлению системой требует, чтобы административные изменения были структурированы, воспроизводимы и тиражируемы на нескольких компьютерах. В реальном мире это означает, что такие изменения должны быть сделаны программным обеспечением, а не выполняться администраторами по инструкциям или, что еще хуже, по памяти.
Сценарии стандартизируют административную работу и освобождают время администраторов для более важных и интересных задач. Сценарии также служат своеобразной бесплатной документацией, поскольку в них записываются шаги, необходимые для выполнения той или иной задачи. Основной альтернативой сценариям для сисадминов является использование систем управления конфигурацией (Ansible, Puppet, Chef). На практике большинство администраторов используют комбинацию сценариев и управления конфигурациями. Каждый из этих подходов имеет свои преимущества, и они хорошо сочетаются друг с другом.
Сценарии оболочки — это также следующий шаг в сложности комбинирования команд после конвейеров для обработки данных. Большинство оболочек имеют собственный язык сценариев с переменными, потоком управления и собственным синтаксисом. Сценарии оболочки отличаются от других языков программирования сценариев тем, что они оптимизированы для выполнения задач, связанных с оболочкой. Таким образом, создание конвейеров команд, сохранение результатов в файлы и чтение из стандартного ввода являются примитивами в сценариях оболочки, что делает их более простыми в использовании, чем языки сценариев общего назначения.
Далее задания посвящены сценариям `bash`, поскольку они наиболее распространены.
При написании скриптов используйте https://www.shellcheck.net/, чтобы проверить их на ошибки до запуска.
### 0.
Каждый процесс имеет как минимум три канала связи: стандартный ввод `STDIN`, стандартный вывод `STDOUT` и стандартный вывод ошибок `STDERR`. Процессы изначально наследуют эти каналы от своих родителей, поэтому они не обязательно знают, куда они ведут. Они могут подключаться к окну терминала, файлу, сетевому соединению или каналу, принадлежащему компьютеру, или каналу, принадлежащему другому процессу, и т.д.
В UNIX и Linux реализована унифицированная модель ввода-вывода, в которой каждый канал именуется небольшим целым числом, называемым дескриптором файла. Точный номер, присвоенный каналу, обычно не имеет значения, но `STDIN`, `STDOUT` и `STDERR` гарантированно соответствуют файловым дескрипторам `0`, `1` и `2`, поэтому можно смело называть эти каналы по номерам. В контексте интерактивного окна терминала `STDIN` обычно считывает данные с клавиатуры, а `STDOUT` и `STDERR` записывают вывод на экран.
Многие традиционные команды UNIX принимают входные данные из `STDIN` и записывают их в `STDOUT`. Сообщения об ошибках они записывают в `STDERR`. Это соглашение позволяет объединять команды, как строительные блоки, для создания конвейеров.
Оболочка интерпретирует символы `<`, `>` и `>>` как инструкции по перенаправлению входных или выходных данных команды в файл или из файла. Символ `<` соединяет `STDIN` команды с содержимым существующего файла. Символы `>` и `>>` перенаправляют `STDOUT`. Символ `>` заменяет существующее содержимое файла, а `>>` добавляет в конец файла.
Чтобы перенаправить и `STDOUT`, и `STDERR` в одно и то же место, используйте символ `>&` или `2>&1`. Чтобы перенаправить только `STDERR`, используйте `2>`.
```
# find / -name core
# find / -name core 2> /dev/null
```
Следующий синтаксис `<( CMD )` выполнит `CMD`, поместит вывод во временный файл и заменит `<()` именем этого файла. Это полезно, когда команды ожидают, что значения будут переданы через файл, а не `STDIN`. Например, `diff <(ls foo) <(ls bar)` покажет различия между файлами в каталогах foo и bar.
### 1.
Чтобы назначить переменные в bash, используйте синтаксис `foo=bar`. Чтобы получить доступ к значению переменной запишите знак `$` перед её именем `$foo`. Обратите внимание, что `foo = bar` не будет работать, так как интерпретируется как вызов программы `foo` с аргументами `=` и `bar`. Как правило, в сценариях оболочки символ пробела выполняет разделение аргументов. Поначалу такое поведение может сбивать с толку, поэтому всегда проверяйте его.
Кроме результатов в `STDOUT` и ошибок в `STDERR` сценарии возвращают код возврата. Код возврата или статус выхода — это то, как скрипты/команды должны сообщать о том, как прошло выполнение. Значение `0` обычно означает, что все прошло нормально; все, что отличается от `0`, означает, что произошла ошибка.
Строки в bash могут быть определены парными символами `'` или `"`, но они не эквивалентны. Строки, разделенные `'`, являются литеральными строками и не интерпретируют bash выражения, тогда как строки с `"` будут. Для экранирования кавычек используется символ обратного слеша `\`.
Коды выхода можно использовать для условного выполнения команд с использованием операторов `&&` (`и`) и `||` (`или`). Команды также можно разделять в пределах одной строки с помощью точки с запятой `;`, если они должны выполниться независимо от возвращаемого кода. Истинная программа всегда будет иметь код возврата `0`, а ложная команда всегда будет иметь код возврата от `1` до `255`.
Напишите .sh скрипт в котором в переменную date присваивается значение текущей даты, в переменную claim - строка "snow is white". После вызова скрипт должен выводить строку, используя переменные date и claim:
Выполните следующие примеры:
```
Ср 14 сен 2022 14:50:46 +04: The claim that “snow is white” is true if and only if snow is white.
false || echo "Oops, fail"
true || echo "Will not be printed"
true && echo "Things went well"
false && echo "Will not be printed"
true ; echo "This will always run"
false ; echo "This will always run"
```
Сделайте файл исполняемым для владельца и вызовите указанием полного или относительного пути к нему.
`*`Что произойдёт в данном случае?
```
(echo red; echo green 1>&2) | echo blue
```
Ответ в [1-2].
### 2.
Как и в большинстве языков программирования, bash поддерживает методы управления потоком, включая условные и циклические операторы if, case, while и for. Точно так же в bash есть функции, которые принимают аргументы и могут с ними работать. Вот пример определения функции:
Чтобы назначить переменные в bash, используйте синтаксис `foo=bar`. Чтобы получить доступ к значению переменной запишите знак `$` перед её именем `$foo`. Обратите внимание, что `foo = bar` не будет работать, так как интерпретируется как вызов программы `foo` с аргументами `=` и `bar`. Как правило, в сценариях оболочки символ пробела выполняет разделение аргументов. Поначалу такое поведение может сбивать с толку, поэтому всегда проверяйте его.
Стандартных правил именования переменных оболочки не существует, но имена, набранные заглавными буквами, обычно указывают на переменные среды или переменные, считываемые из глобальной конфигурации. Чаще всего локальные переменные обозначаются всеми строчными буквами, а их компоненты отделяются друг от друга разделены символами подчеркивания. Имена переменных чувствительны к регистру.
Строки в bash могут быть определены парными символами `'` или `"`, но они не эквивалентны. Строки, разделенные `'`, являются литеральными строками и не интерпретируют `bash` выражения, тогда как строки с `"` будут. Для экранирования кавычек используется символ обратного слеша `\`.
Напишите `.sh` скрипт в котором в переменную `date` присваивается значение текущей даты, в переменную `claim` - строка `"snow is white"`. После вызова скрипт должен выводить строку, используя переменные `date` и `claim`:
```
Ср 14 сен 2022 14:50:46 +04: The claim that “snow is white” is true if and only if snow is white.
```
Сделайте файл исполняемым для владельца и вызовите указанием полного или относительного пути к нему.
### 3.
В отличие от других языков сценариев, `bash` использует множество специальных переменных для ссылки на аргументы, коды ошибок и другие важные переменные. Ниже приведен список некоторых из них. Более полный список можно найти здесь (https://tldp.org/LDP/abs/html/special-chars.html или в переводе на русский здесь https://www.opennet.ru/docs/RUS/bash_scripting_guide/c301.html.
Используйте следующие специальные переменные в скрипте:
- `$0` - имя скрипта,
- `$1` до `$9` - аргументы скрипта,
- `$@` - все аргументы,
- `$#` - количество аргументов,
- `$?` - возвращаемый код предыдущей команды,
- `$$` - идентификатор процесса текущего скрипта,
- `$_` - последний аргумент последней команды (в терминале попробуйте нажать `Esc .` или `Alt+`).
В терминале также доступна команда `!!`. Попробуйте `sudo !!`, если забыли, что команде требуются права суперпользователя). Команда `!!` будет работать в скрипте только, если в начале присутствует `set -H`, включающая работу с историей. По умолчанию это возможность включена для интерактивного взаимодействия.
Напишите скрипт, который создает каталог, а затем переходит в него, создаёт в нём файл и записывает в него значения всех специальных переменных. Путь к каталогу должен быть передан в качестве первого аргумента.
### 4.
Как и в большинстве языков программирования, `bash` поддерживает методы управления потоком, включая условные и циклические операторы `if`, `case`, `while` и `for`. Точно так же в `bash` есть функции, которые принимают аргументы и могут с ними работать. Вот пример определения функции:
```bash
echo_arguments () {
echo "First three arguments: $0 $1 $2 $3, Argument count: $#, All arguments: $@"
}
```
В отличие от других языков сценариев, bash использует множество специальных переменных для ссылки на аргументы, коды ошибок и другие важные переменные. Ниже приведен список некоторых из них. Более полный список можно найти здесь (https://tldp.org/LDP/abs/html/special-chars.html или https://www.opennet.ru/docs/RUS/bash_scripting_guide/c301.html.
По умолчанию переменная глобальна для скрипта, даже если определена внутри функции. Чтобы сделать переменную локальной, используйте синтаксис `local variable` внутри функции.
`$0` - имя скрипта, `$1` до `$9` - аргументы скрипта, `$@` - все аргументы, `$#` - количество аргументов,`$?` - возвращаемый код предыдущей команды, `$$` - идентификатор процесса текущего скрипта, `!!` - вся команда, включая аргументы (попробуйте `sudo !!`, если забыли, что команде требуются права суперпользователя), `$_` - последний аргумент последней команды (в терминале попробуйте нажать `Esc .` или `Alt+`).
Напишите аналогичный предыдущему заданию скрипт, но оберните все действия в функцию, а в конце скрипта выполните эту функцию. Проверьте работу скрипта. Доступна ли функция за пределами контекста скрипта?
Напишите функцию в скрипте, которая создает каталог, путь к которому передан в качестве первого аргумента и переходит в него. Проверьте работу функции в этом же файле. Работает ли функция за пределами контекста скрипта?
Заведите внутри функции глобальную `a` и локальную переменную `local b`. Вызовите функцию в скрипте. Выведите обе переменные на экран внутри функции после присвоения значений переменным и после вызова функции.
### 3.
Менее известной, но полезной может быть подстановка дескриптора файла с результатом выполнения команды. `<( CMD )` выполнит `CMD` и поместит вывод во временный файл и заменит `<()` именем этого файла. Это полезно, когда команды ожидают, что значения будут переданы через файл, а не STDIN. Например, `diff <(ls foo) <(ls bar)` покажет различия между файлами в каталогах foo и bar.
### 4.
Команды часто возвращают выходные данные, используя `STDOUT`, ошибки — через `STDERR` и код возврата, чтобы сообщать об ошибках более удобным для сценариев способом. Код возврата или статус выхода — это то, как скрипты/команды должны сообщать о том, как прошло выполнение. Значение 0 обычно означает, что все прошло нормально; все, что отличается от 0, означает, что произошла ошибка.
### 5.
Функции выполняются в текущей среде оболочке, тогда как скрипты выполняются в своем собственном процессе.
Коды выхода можно использовать для условного выполнения команд с использованием `&&` (и оператора) и `||` (или оператор), оба из которых являются операторами. Команды также можно разделять в пределах одной строки с помощью точки с запятой `;`. Истинная программа всегда будет иметь код возврата `0`, а ложная команда всегда будет иметь код возврата `1`.
Проверьте, что функции могут изменять переменные среды, например, изменить текущий каталог, тогда как скрипт не может. Напишите скрипт, в котором инициализируются две переменные `A` и `B`. Перед одной из них указывается `export`. Выполните скрипт и посмотрите на выдачу команды `env`. Выполните файл командой `source` (документация в `source --help` и секции встроенных команд `man bash`). Какие переменные экспортировались в оболочку?
Попробуйте выполнить следующие примеры:
### 6.
Попробуйте условные выражения в скрипте в `if` конструкции:
```bash
if [[ условное выражение ]]; then
echo "True"
fi
```
false || echo "Oops, fail"
# Oops, fail
true || echo "Will not be printed"
#
## 6.5 Пропущенные задания
true && echo "Things went well"
# Things went well
https://ryanstutorials.net/bash-scripting-tutorial/bash-if-statements.php
http://mywiki.wooledge.org/BashFAQ/031
false && echo "Will not be printed"
#
https://ryanstutorials.net/bash-scripting-tutorial/bash-loops.php
true ; echo "This will always run"
# This will always run
https://ryanstutorials.net/bash-scripting-tutorial/bash-functions.php
false ; echo "This will always run"
# This will always run
### 7.
Напишите скрипт, который проходит по всем файлам, переданным в качестве аргументов, и ищет в них строку `hello`. Перенаправьте grep `STDOUT` и `STDERR` в специальный файл `/dev/null`. Для каждого файла в `if` создайте файл с содержимым `hello`, если `grep` завершился с ошибкой.
### 8.
Установите пакет `shellcheck` и проверьте написанный вами ранее скрипт одноименной командой.
### 9.
Bash отличается от других языков программирования в следующем примере.
```bash
#!/usr/bin/env bash
mv ./*.txt /tmppp
echo "success!"
```
Как правило, если происходит ошибка, то программа останавливается. Но в данном случае скрипт продолжит работу, несмотря на ошибку в `mv`.
`set -e` был попыткой добавить в оболочку "автоматическое обнаружение ошибок" [6]. Его целью было заставить оболочку прерываться при возникновении ошибки, чтобы не приходилось ставить `|| exit 1` после каждой важной команды. Однако на практике это всё равно работает не очень хорошо.
Попробуйте выполнить следующие скрипты. Воспользуйтесь `shellcheck`, чтобы узнать в чём проблема с этими примерами.
Попробуйте условные выражения в скрипте в if конструкции:
#### 9.0 Почему в первой исправленной версии скрипт останавливается, а во второй нет?
```bash
#!/usr/bin/env bash
set -e
mv ./*.txt /tmppp
echo "success!"
```
if [[ условное выражение ]]; then
echo "True"
fi
```bash
#!/usr/bin/env bash
set -e
f() {
mv ./*.txt /tmppp
echo "success!"
}
f || echo "failed!"
```
Ответ - во втором случае, оператор `||` деактивирует `set -e`. Это задокументированное поведение.
### 5.
Напишите скрипт, который проходит по всем файлам, переданным в качестве аргументов, и ищет в них строку hello. Перенаправьте grep `STDOUT` и `STDERR` в специальный файл `/dev/null`. Для каждого файла в if создайте файл с содержимым `hello`, если `grep` завершился с ошибкой.
#### 9.1. Почему в этом примере не работает печать?
```bash
#!/usr/bin/env bash
set -e
i=0
let i++
echo "i is $i"
```
#### 9.2. Почему этот вариант иногда работает? В каких версиях bash он работает, а в каких - нет?
```bash
#!/usr/bin/env bash
set -e
i=0
((i++))
echo "i is $i"
```
#### 9.3. Почему эти два сценария не идентичны?
```bash
#!/usr/bin/env bash
set -e
test -d nosuchdir && echo no dir
echo survived
```
```bash
#!/usr/bin/env bash
set -e
f() { test -d nosuchdir && echo no dir; }
f
echo survived
```
#### 9.4. Почему эти два сценария не идентичны?
```bash
#!/usr/bin/env bash
set -e
f() { test -d nosuchdir && echo no dir; }
f
echo survived
```
```bash
#!/usr/bin/env bash
set -e
f() { if test -d nosuchdir; then echo no dir; fi; }
f
echo survived
```
#### 9.5. При каких условиях это приведет к отказу?
```bash
#!/usr/bin/env bash
set -e
read -r foo < configfile
```
### 6.
Установите пакет shellcheck и проверьте написанный вами ранее скрипт одноименной командой.
Рекомендация проста: не используйте `set -e`. Вместо этого добавьте собственную проверку ошибок.
### 7.
рипты не обязательно должны быть написаны на bash для вызова из терминала. Ядро определяет, что сценарий нужно выполнять с помощью другого интерпретатора вместо командой оболочки, если в начало скрипта включена строка shebang. Хорошей практикой является написание строк shebang с помощью команды env, которая будет разрешаться везде, где эта команда находится в системе, что повышает переносимость ваших сценариев. Например, чтобы определить местоположение python, env будет использовать переменную среды `PATH` при записи `#!/usr/bin/env python`.
### 10.
рипты не обязательно должны быть написаны на `bash` для вызова из терминала. Ядро определяет, что сценарий нужно выполнять с помощью другого интерпретатора вместо командой оболочки, если в начало скрипта включена строка `shebang`. Хорошей практикой является написание строк `shebang` с помощью команды `env`, которая будет разрешаться везде, где эта команда находится в системе, что повышает переносимость ваших сценариев. Например, чтобы определить местоположение `python`, `env` будет использовать переменную среды `PATH` при записи `#!/usr/bin/env python`. Если у вас установлено несколько версий Python, то команда `/usr/bin/env` обеспечит использование интерпретатора, который стоит первым в `$PATH` окружения. Альтернативой может быть жесткая привязка вида `#!/usr/bin/python` что тоже нормально, но менее гибко.
Напишите скрипт, который выполняет следующий код:
```
```python
import sys
for arg in reversed(sys.argv[1:]):
print(arg)
```
### 8.
Функции выполняются в текущей среде оболочке, тогда как скрипты выполняются в своем собственном процессе.
Проверьте, что функции могут изменять переменные среды, например, изменить текущий каталог, тогда как скрипт не может. Напишите скрипт, в котором инициализируются две переменные `A` и `B`. Перед одной из них указывается `export `. Выполните скрипт и посмотрите на выдачу команды `env`. Выполните файл командой source (source --help). Какие переменные экспортировались в оболочку?
### 9.
Скажем, у вас есть команда, которая редко дает сбой. Чтобы отладить её, вам нужно зафиксировать её выходные данные, но это может занять много времени, чтобы поймать неудачный запуск. Напишите сценарий bash, который запускает следующий сценарий до тех пор, пока он не завершится аварийно, записывает стандартный вывод и потоки ошибок в файлы и печатает все в конце. Бонусный балл, за то, что вы можете сообщить, сколько запусков потребовалось для сбоя сценария.
```
### 11.
Скажем, у вас есть команда, которая редко дает сбой. Чтобы отладить её, вам нужно зафиксировать её выходные данные, но это может занять много времени, чтобы поймать неудачный запуск. Напишите сценарий `bash`, который запускает следующий сценарий до тех пор, пока он не завершится аварийно, записывает стандартный вывод и потоки ошибок в файлы и печатает все в конце. Бонусный балл, за то, что вы можете сообщить, сколько запусков потребовалось для сбоя сценария.
```bash
#!/usr/bin/env bash
n=$(( RANDOM % 100 ))
@ -100,11 +232,52 @@ fi
echo "Everything went according to plan"
```
### 10.
Напишите скрипт, который:
- создаёт пользователя на двух машинах,
- кроме домашней директории заводит папку для пользователя в `/ceph/` с нужными правами,
- создаёт ссылку в домашней директории на директорию в `/ceph/`,
- ограничивает доступ к домашней папке всем, кроме владельца,
- генерирует пользователям ключи ed25519, рассылает по машинам и регистрирует ключи для беспарольного перемещения пользователя между машинами.
### 12.
Выберите любые две машины под вашим контролем, имеющие доступ друг к другу по сети, и создайте на каждой машине папку `/data/` с заданными правами и владельцем `-rwxr-xr-x root root`. Выполните задание в соответствие с лучшими практиками для написания скриптов. В задачи скрипта входят:
- создание пользователя на двух машинах с домашними директориями и интерпретатором `bash` по умолчанию,
- создание для пользователя папки в `/data/` с доступом только её владельцу,
- создание ссылки в домашней директории на директорию в `/data/`,
- настройки беспарольного перемещения между машинами:
1. генерация пользователю ключа `ed25519`,
2. рассылка по машинам,
3. регистрация ключа в списке авторизованных.
## Лучшие практики написания скриптов
- При запуске с несоответствующими аргументами скрипты должны выводить сообщение об использовании и завершать работу. Реализуйте таким же образом и `--help`.
- Производите валидацию входных данных и проверку правильности полученных значений. Например, перед выполнением команды `rm -rf` по вычисленному пути можно попросить скрипт дважды проверить, что путь соответствует ожидаемому шаблону.
- Возвращайте значимый код выхода: `0` в случае успеха и больше нуля `1-255` в случае неудачи. Не обязательно давать каждому режиму отказа уникальный код выхода; подумайте, что именно захотят узнать пользователи скрипта.
- Использовать соответствующие соглашения об именовании переменных, скриптов и процедур. Они должны соответствовать принятым в языке, остальной кодовой базе и, что особенно важно, другим переменным и функциям, определенным в текущем проекте. Используйте смешанный регистр или подчеркивание, чтобы сделать длинные имена читаемыми.
- Имена переменных должны отражать хранимые в них значения, но старайтесь делать их короткими. `number_of_lines_of_input` - слишком длинно, попробуйте `n_lines`.
- Важным является именование самих скриптов. В этом контексте для имитации пробелов чаще используются тире, чем подчеркивание (`system-config-printer`).
- Рассмотрите возможность разработки руководства по стилю, чтобы вы и ваши коллеги могли писать код в соответствии с едиными правилами. С помощью руководства вам будет легче читать чужой код, а им - ваш.
- Начинайте каждый скрипт с блока комментариев, в котором указывается, что делает скрипт и какие параметры он принимает. Укажите свое имя и дату. Если сценарий требует установки в системе нестандартных инструментов, библиотек или модулей, укажите и их.
- Комментируйте на том уровне, который будет полезен вам самим, когда вы вернетесь к сценарию через месяц или два. Полезно прокомментировать следующие моменты: выбор алгоритма, используемые веб-ссылки, причины, по которым не удалось сделать что-то более очевидным способом, необычные пути в коде, все, что вызвало затруднения в процессе разработки.
- Не загромождайте код бесполезными комментариями; предполагайте наличие интеллекта и знание языка у читателя.
- Можно запускать скрипты от имени `root`, но не делайте их `setuid`; очень сложно сделать setuid-скрипты полностью безопасными. Вместо этого используйте `sudo` для реализации соответствующих политик управления доступом.
- Не пишите сценарии, которые вы не понимаете. Администраторы часто рассматривают скрипты как авторитетную документацию о том, как должна выполняться та или иная процедура. Не стоит подавать ложный пример, распространяя "половинчатые" сценарии.
- Не стесняйтесь адаптировать код из существующих скриптов для своих нужд. Но не занимайтесь программированием по принципу "копируй, вставляй и молись", если вы не понимаете кода. Потратьте время на то, чтобы разобраться в нем. Это время никогда не бывает потрачено впустую.
- В `bash` используйте опцию `-x` для вывода команд на экран перед их выполнением и `-n` для проверки команд на синтаксис без их выполнения.
- Помните, что в Python вы находитесь в режиме отладки, если явно не отключите его с помощью аргумента `-0` в командной строке. Перед выводом диагностического вывода можно проверить специальную переменную `__debug__`.
- Сообщения об ошибках должны идти в `STDERR`, а не `STDOUT`.
- В сообщениях об ошибках указываете какая функция или операция не выполнилась.
- Используйте имена, набранные заглавными буквами, для указания на переменные среды или переменные, считываемые из глобальной конфигурации. В именах локальных переменных используйте строчные буквы, с разделением слов нижним подчёркиванием `_`.
## Ссылки:
1. https://utcc.utoronto.ca/~cks/space/blog/unix/ShellPipelineIndeterminate
2. https://www.gibney.org/the_output_of_linux_pipes_can_be_indeter
3. https://tldp.org/LDP/abs/html/special-chars.html
4. https://www.opennet.ru/docs/RUS/bash_scripting_guide/c301.html
5. https://www.shellcheck.net/
6. http://mywiki.wooledge.org/BashFAQ/105
7. http://mywiki.wooledge.org/BashFAQ/031
## Релевантные мануалы:
- man bash
- source (man bash, SHELL BUILTIN COMMANDS)
- man shellcheck
- man test
## Литература
- Эви Немет и др. — Unix и Linux. Руководство системного администратора. 5-e издание [Глава 7]

@ -1,132 +0,0 @@
# Решения
Для проверки расписания вы можете использовать сайт https://crontab.guru/, https://cronheatmap.com и аналоги.
### 0.
Проверьте наличие команд cron и at в системе. Установите их в случае отсутствия.
```bash
sudo apt install cron at
```
### 1.
Выведите документацию crontab и cron.
```bash
man crontab
man cron
```
### 2.
Создайте cron расписание для выполнения скрипта или к:
``` bash
# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12)
# │ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday;
# │ │ │ │ │ 7 is also Sunday on some systems)
# │ │ │ │ │
# │ │ │ │ │
# * * * * * <command to execute>
# 1. дважды в день: в 5 утра и в 5 вечера,
0 5,17 * * * /sbin/script.sh
# 2. в 3:15 каждый день,
15 15 * * * /sbin/script.sh
# 3. в 8 вечера каждую неделю,
0 20 * * 1 /sbin/script.sh
# 4. по понедельникам в 20:00,
0 20 * * 1 /sbin/script.sh
# 5. в 20:00 по понедельникам и по субботам,
0 20 * * 1,6 /sbin/script.sh
# 6. каждую минуту,
* * * * * /sbin/script.sh
# 7. каждые 10 минут,
*/10 * * * * /sbin/script.sh
# 8. каждые 15 минут по субботам и понедельникам,
*/15 * * * 1,6 /sbin/script.sh
# 9. каждую минуту в марте, июне, сентябре и декабре,
* * * 3,6,9,12 /sbin/script.sh
# 10. 20 января в 8 вечера,
0 20 20 1 * /sbin/script.sh
# 11. ежедневное выполнение скрипта в 8 вечера каждый второй месяц,
0 20 * */2 * /sbin/script.sh
# 12. *в первое воскресенье каждого месяца,
0 0 * * 0 [ $(date +%d) -le 07 ] && /script/script.sh
# 13. каждые три часа,
0 */3 * * * /sbin/script.sh
# 14. дважды, каждую субботу и понедельник,
0 0 * * 1,6 /sbin/script.sh
# 15. *каждые 30 секунд,
* * * * * /sbin/script.sh
* * * * * sleep 30; /sbin/script.sh
# 16. каждый день в летний период,
0 0 * 6,7,8 * /sbin/script.sh
# 17. для рассылки поздравлений с новым годом,
0 0 1 1 * /sbin/happy_new_year_mail.sh
# 18. ежедневного удаления неиспользуемых пакетов в системе,
0 1 * * * apt autoremove
# 19. перезапуска системы в 0 часов 0 минут,
0 0 * * * shutdown -h 0
# 20. для очистки всех попыток сбоя входа в систему ежедневно в 1:00,
0 1 * * * /sbin/clear_auth_errors.sh
# 21. ежедневной проверки и загрузки новых системных пакетов,
0 0 * * * apt update
# 22. ежедневного обновления пакетов системы,
0 0 * * * apt upgrade -y
# 23. ежедневное резервное копирование всех папок пользователей в 5 утра.
0 5 * * * tar -zcf /var/backups/home.tgz /home/
```
### 3.
Создайте задание в котором отчёты cron будут отправляться вам на внешний почтовый ящик.
```
MAILTO=logs@myoffice.org
```
### 4.
Установите пользовательский сrontab.
```
sudo echo "stud" >> /etc/cron.allow
crontab -e
```
### 5.
Настройте выполнение исполняемого файла script.sh из `/usr/sbin/` каждую среду, модифицировав `PATH` в cron задании.
```bash
PATH=/opt/cmake/bin:$PATH
0 0 * * 3 /usr/sbin/script.sh
```
### 6.
Пользуясь полномочиями суперпользователя, запретите пользователю mike выполнять команду at.
```
sudo echo "mike" >> /etc/at.deny
```
### 7.
Запланируйте командой at:
``` bash
# 1. выполнение скрипта сегодня в 9 часов,
at 21:00 script.sh
# 2. перезагрузку через 2 часа,
sudo at now + 2 hours reboot
# 3. выполнение команды через 100 лет.
at now + 100 years script.sh
```
# Справка
Релевантные файлы:
- /etc/cron.allow
- /etc/cron.deny
- /var/spool/cron/crontabs
- /var/spool/cron/atjobs
- /var/spool/cron/atspool
- /proc/loadavg
- /var/run/utmp
- /etc/at.allow
- /etc/at.deny
Релевантные команды:
- cron
- at
- crontab

@ -167,6 +167,13 @@ $ host -t Веб-сайт.com
$ dig +trace веб-сайт.com
```
Рисунок 1. Утилиты для отладки в среде Linux
![Linux observability tools (https://www.brendangregg.com/Perf/linux_perf_tools_full.svg)](https://www.brendangregg.com/Perf/linux_perf_tools_full.svg)
Источники:
- https://www.brendangregg.com/linuxperf.html
Литература

@ -1,46 +0,0 @@
# Решения
Исправьте проблемы настройки сети в виртуальных машинах `troublesome-X-task[1-5]`. В каждой машине 1 проблема после исправления которой работает команда `ping yandex.com`. Шлюз по умолчанию для машины в каждом задании - 192.168.1.1 в сети 192.168.1.0/24. Всего 5 заданий. Используйте механизм снимков и команду rollback в proxmox интерфейсе, чтобы откатывать машину в первоначальное состояние.
### 1. Не активирован и не запущен systemd-networkd
```
sudo systemctl enable systemd-networkd
sudo systemctl start systemd-networkd
```
### 2. В настройках не указан шлюз по умолчанию
```
sudo "echo Gateway=192.168.1.1 >> /etc/systemd/network/ens18.network"
sudo networkctl reload
```
### 3. В настройках systemd-resolved не указан DNS
```
sudo "echo DNS=1.1.1.1 >> /etc/systemd/resolved.conf"
sudo systemctl restart systemd-resolved
```
### 4. Машина находится в другой сети по отношению к шлюзу
```
sudo sed 's/172\.16/192\.168/' -i /etc/systemd/network/ens18.network
sudo networkctl reload
```
### 5. На сетевом интерфейсе установлен MAC-дубликат шлюза
Установите родной mac `permaddr`:
```
sudo "ip link set address $(ip link show ens18 | grep permaddr | awk '{ print $6 }') dev ens18"
```
### 6. Неверные права папки .ssh пользователя mike
В 6ом задании `troublesome-X-task6` вам требуется отладить команду `ssh localhost -l mike`, запущенную от пользователя stud. Команда должна отработать без ввода пароля.
```
sudo chmod 0700 /home/mike/.ssh
```
Также желательно исправить группу-владельца:
```
sudo chown mike:mike /home/mike/.ssh
```

@ -1,5 +1,18 @@
# Задания
Исправьте проблемы настройки сети в виртуальных машинах `troublesome-X-task[1-5]`. В каждой машине 1 проблема после исправления которой работает команда `ping yandex.com`. Шлюз по умолчанию для машины в каждом задании - 192.168.1.1 в сети 192.168.1.0/24.
#### studX-troublesome-1 - studX-troublesome-5
Исправьте проблемы настройки сети в виртуальных машинах. Команда `ping ya.ru` должна работать.
В 6ом задании `troublesome-X-task6` вам требуется отладить команду `ssh localhost -l mike`, запущенную от пользователя stud. Команда должна отработать без ввода пароля.
#### studX-troublesome-6
Выполните на машине studX-net1 следующие команды
```
ssh-keygen
ssh-copy-id stud@192.168.0.106
```
Почему даже после добавления публичного ключа на `studX-troublesome-6` авторизация по публичному ключу не работает? Найдите и исправьте проблему на `studX-troublesome-6`.
#### studX-troublesome-7
После логина стрелки не работают и выводят странные символы. Исправьте проблему.
#### studX-troublesome-8
Залогиньтесь сначала в `stud` потом в `root`. Посмотрите логи командой `journalctl -o short-iso`. В чём заключается проблема настройки машины? Исправьте её.

@ -1,10 +1,10 @@
# Экзаменационное задание
### 1.
В виртуальную машину examX (здесь и далее X - ваш идентификатор) установите debian из образа `debian-11.4.0-amd64-netinst.iso`. Сохраните в текстовый файл сделанный выбор в меню установки. Создайте пользователя stud во время или после установки.
В виртуальную машину examX (здесь и далее X - ваш идентификатор) установите debian из образа `debian-12.1.0-amd64-netinst.iso`. Сохраните в текстовый файл сделанный выбор в меню установки. Создайте пользователя stud во время или после установки.
### 2.
Настройте подключение к сети интернет с помощью systemd. В качестве адреса установите `10.160.179.150+X/24`, в качестве шлюза `10.160.179.1`.
Настройте подключение к сети интернет с помощью systemd. В качестве адреса установите `10.160.179.120+X/24`, в качестве шлюза `10.160.179.1`.
Примечание: удалите пакет `ifupdown` и установите символическую ссылку `/etc/resolv.conf` на `/run/systemd/resolve/resolv.conf`.
@ -18,4 +18,4 @@
Настройте беспарольный доступ с машины `studX` на новую для пользователя `stud`. Запретите доступ на машину по паролю.
### 6.
Установите и настройте `nginx`. Поместите index.html в `/var/www/cv` с краткой информацией о себе. Настройте сайт в `nginx` конфигурации, который возвращает эту страницу по запросу `https://10.160.179.150+X:443`. Для проверки используйте команду `curl --insecure` с машины `studX`. Сайт должен использовать самоподписанный сертификат выданный на 90 дней с ключом, сгенерированным по алгоритму rsa размером 2048 бит, параметрами: C=RU, ST=Samara, L=Samara, O=MyOffice, OU=IT, CN=studX.cv.myoffice.ru. Настройте `nginx` сервис на перезапуск в случае отказа.
Установите и настройте `nginx`. Поместите index.html в `/var/www/cv` с краткой информацией о себе. Настройте сайт в `nginx` конфигурации, который возвращает эту страницу по запросу `https://10.160.179.120+X:443`. Для проверки используйте команду `curl --insecure` с машины `studX`. Сайт должен использовать самоподписанный сертификат выданный на 90 дней с ключом, сгенерированным по алгоритму rsa размером 2048 бит, параметрами: C=RU, ST=Samara, L=Samara, O=MyOffice, OU=IT, CN=studX.cv.myoffice.ru. Настройте `nginx` сервис на перезапуск в случае отказа.

@ -1,98 +1,99 @@
# Руководство для преподавателя
## Подготовка среды проведения лабораторных работ
# Руководство для преподавателя. Подготовка среды проведения лабораторных работ
Лабораторные проводятся на виртуальных машинах в системе виртуализации Proxmox. Задания выкладываются в публичный git репозиторий. Для получения новых заданий студенты первоначально скачивают их по ссылке командой `git clone`, а затем в начале каждого урок обновляют их командой `git pull`.
Будем считать, что N - количество студентов умноженное на 1.5, округлённое в большую сторону. X - идентификатор студента от 1 до N.
Будем считать, что `N` - количество студентов умноженное на `1.5`, округлённое в большую сторону. X - идентификатор студента от `1` до `N`.
Создайте N пользователей в Proxmox с именами studX (stud1, stud2, ...). Используйте Realm "Proxmox VE authentication server".
Создайте `N` пользователей в Proxmox с именами `studX` (`stud1`, `stud2`, ...). Используйте Realm "Proxmox VE authentication server".
Загрузите образ debian-11.4.0-amd64-netinst.iso в Proxmox хранилище.
Загрузите образ `debian-11.4.0-amd64-netinst.iso` в Proxmox хранилище.
Для массового создания виртуальных машин рекомендуется использовать возможность Proxmox конвертации виртуальной машины в шаблон. Из шаблона копия создаётся на порядки быстрее по времени, чем при полном клонировании. Следуйте следующим шагам:
1. настройте машину с общими для всех копий настройками,
2. преобразуйте её в шаблон (template),
3. создайте клоны из шаблона и донастройте, если необходимо,
4. сделайте snapshot основных машин, чтобы вы и студенты имели возможность отката до рабочего состояния.
4. сделайте snapshot с именем `initial` основных машин, чтобы вы и студенты имели возможность отката до рабочего состояния.
При наличии нескольких дисков рекомендуется RAID оптимизирующий производительность. Неправильный raid или медленный тип диска может привести к существенному замедлению работы во время установки ОС или пакетов.
Список шаблонов виртуальных машин:
- `stud0-tabularasa-template`
- `stud0-template`
- `stud0-net-[1-2]-template`
- `stud0-troublesome-[1-6]-template`
(TODO Написать скрипт для создания шаблонов.)
(TODO Написать скрипт для создания учётки и виртуалок для студента на основе шаблонов.)
При наличии нескольких дисков рекомендуется RAID оптимизирующий производительность. Неправильный raid или медленный тип диска может привести к существенному замедлению работы во время установки ОС или пакетов.
### Основные виртуальные машины
Данные виртуальные машины предназначены для всех заданий, исключая:
- 00_os_installation,
- 03_networking,
- 12_troubleshooting,
- final_exam.
## 1. Подготовка виртуальной машины к занятиям `01`, `02`, `04`, `05`, `06`, `07`, `08`, `09`, `10`, `11`.
Создайте vlan с доступом в интернет. Например, bond0.499 и мост vmbr499 с параметрами:
- Bridge ports: bond0.499,
- VLAN aware: false,
- IPv4/CIDR: 10.160.179.254/24,
- Gateway (IPv4): 10.160.179.1.
Создайте vlan с доступом в интернет. Например, `bond0.499` и мост `vmbr499` с параметрами:
- Bridge ports: `bond0.499`,
- VLAN aware: `false`,
- IPv4/CIDR: `10.160.179.254/24`,
- Gateway (IPv4): `10.160.179.1`.
До начала занятий создайте N виртуальных машин со следующими характеристиками:
- 1 сокет с 4 ядрами,
- 8 Гб оперативной памяти,
- 16 Гб дискового пространства.
Каждой виртуальной машине назначьте статический IPv4 адрес 10.160.179.10 + X (10.160.179.11, 10.160.179.12, ...). Используйте инструкцию из задания про настройку сети данного учебного модуля.
Каждой виртуальной машине назначьте статический IPv4 адрес `10.160.179.10 + X` (`10.160.179.11`, `10.160.179.12`, ...). Используйте инструкцию из задания про настройку сети данного учебного модуля.
Установите минимальный дистрибутив debian на каждую. Установите пакеты:
- man-db,
- ssh,
- vim,
- tree,
- jq,
- lsof.
```
apt install man-db ssh vim tree jq lsof git mc fail2ban
```
Удалите пакет ifupdown.
Удалите пакет `ifupdown`, так как настройка сети будет производится средствами `systemd-networkd`.
```
apt remove ifupdown
```
Пробросьте порты: 22, 80, 443.
Пробросьте порты: `22`, `80`, `443`.
Организуйте удалённый доступ к машинам по ssh ключу.
Организуйте удалённый доступ к машинам по `ssh` ключу. Запретите доступ по ssh через пароль.
### Подготовка к занятию "История операционных систем. Установка Debian"
## 2. Подготовка виртуальной машины к занятиям `00`.
Данные виртуальные машины предназначены для тренировки в установке debian.
Данные виртуальные машины предназначены для тренировки в установке debian в уроке `00`.
До начала занятий создайте N виртуальных машин со следующими характеристиками:
- 1 сокет с 4 ядрами,
- 8 Гб оперативной памяти,
- 32 Гб дискового пространства,
- сетевой интерфейс vmbr499 с доступом в интернет.
- сетевой интерфейс `vmbr499` с доступом в интернет.
Студенты могут назначить статический IPv4: 10.160.179.10 + N + X, Gateway (IPv4): 10.160.179.1.
Студенты могут назначить статический IPv4: `10.160.179.10 + N + X`, Gateway (IPv4): `10.160.179.1`.
Подключите cdrom с образом debian-11.4.0-amd64-netinst.iso.
Подключите cdrom с образом `debian-11.4.0-amd64-netinst.iso`.
### Подготовка к занятию "Настройка сетевого подключения"
## 3. Подготовка виртуальной машины к занятиям `03`.
Данные виртуальные машины предназначены для настройки сетевого интерфейса в конфигурациях systemd. Студентам необходимо работать в индивидуальных vlan для настройки по DHCP и снижению вероятности ошибок при назначении статического адреса.
Данные виртуальные машины предназначены для настройки сетевого интерфейса в конфигурациях `systemd` в уроке `03`. Студентам необходимо работать в индивидуальных vlan для настройки по DHCP и снижению вероятности ошибок при назначении статического адреса.
Создайте N vlan без доступа в интернет. Например, bond0.X и мост vmbrX с параметрами:
- Bridge ports: bond0.X,
- VLAN aware: false.
Создайте `N` vlan без доступа в интернет. Например, `bond0.X` и мост `vmbrX` с параметрами:
- Bridge ports: `bond0.X`,
- VLAN aware: `false`.
Создайте N виртуальных машин studX-net1 и N виртуальных машин studX-net2 для vmbrX. Удалите пакет ifupdown.
Создайте `N` виртуальных машин `studX-net1` и `N` виртуальных машин `studX-net2` для `vmbrX`. Удалите пакет `ifupdown`.
### Подготовка к занятию "Поиск и устранение неисправностей"
## 4. Подготовка виртуальной машины к занятиям `12`.
Данные виртуальные
Создайте N vlan без доступа в интернет: bond0.N+X и мост vmbrN+X с параметрами:
- Bridge ports: bond0.N+X,
- VLAN aware: false.
Создайте `N` vlan без доступа в интернет: `bond0.N+X` и мост `vmbrN+X` с параметрами:
- Bridge ports: `bond0.N+X`,
- VLAN aware: `false`.
Создайте N виртуальных машин troublesome-gwX, играющих роль шлюза для vmbrN+X. Установите минимальный образ debian. Удалите пакет ifupdown. Каждой виртуальной машине назначьте добавьте два сетевых интерфейса. Для первого интерфейса назначьте IPv4 адрес 10.160.179.100 + X (10.160.179.101, 10.160.179.102, ...). Для второго интерфейса назначьте IPv4 адрес 192.168.0.1.
Создайте `N` виртуальных машин `troublesome-gwX`, играющих роль шлюза для `vmbrN+X`. Установите минимальный образ debian. Удалите пакет `ifupdown`. Каждой виртуальной машине назначьте добавьте два сетевых интерфейса. Для первого интерфейса назначьте IPv4 адрес `10.160.179.100 + X` (`10.160.179.101`, `10.160.179.102`, ...). Для второго интерфейса назначьте IPv4 адрес `192.168.0.1`.
Создайте виртуальную машину troublesome. Установите минимальный образ debian. Скопируйте скрипты, приведенные ниже в /sbin/. Превратите машину в шаблон Proxmox.
Создайте виртуальную машину `troublesome`. Установите минимальный образ debian. Скопируйте скрипты, приведенные ниже в `/sbin/`. Превратите машину в шаблон Proxmox.
Для каждого из 6 заданий создайте виртуальную машину из шаблона troublesome: troublesomeX-task1, troublesomeX-task2, ..., troublesomeX-task6. Каждой виртуальной машине назначьте статический IPv4 адрес 192.168.0.1 + номер задания. Для 6 задания настройте беспарольный доступ по ssh от пользователя stud к пользователю mike. Команда `ssh localhost -l mike` должна отработать без ввода пароля. Внесите неисправности, активируя скрипты. Превратите машины в шаблоны.
Для каждого из 6 заданий создайте виртуальную машину из шаблона `troublesome`: `troublesomeX-task1`, `troublesomeX-task2`, ..., `troublesomeX-task6`. Каждой виртуальной машине назначьте статический IPv4 адрес `192.168.0.1 + номер задания`. Для 6 задания настройте беспарольный доступ по ssh от пользователя stud к пользователю mike. Команда `ssh localhost -l mike` должна отработать без ввода пароля. Внесите неисправности, активируя скрипты. Превратите машины в шаблоны.
Создайте N виртуальных машин для каждого задания из шаблонов: troublesomeX-task1, troublesomeX-task2, ..., troublesomeX-task6.
Создайте N виртуальных машин для каждого задания из шаблонов: `troublesomeX-task1`, `troublesomeX-task2`, ..., `troublesomeX-task6`.
Скрипты для внесения неисправностей для заданий.
@ -160,7 +161,7 @@ WantedBy=multi-user.target
chmod 777 /home/stud/.ssh
```
### Подготовка к экзамену
## 5. Подготовка к экзамену
До начала занятий создайте N виртуальных машин со следующими характеристиками:
- 1 сокет с 4 ядрами,
@ -168,4 +169,4 @@ chmod 777 /home/stud/.ssh
- 6 Гб дискового пространства,
- сетевой интерфейс vmbr499.
Подключите cdrom с образом debian-11.4.0-amd64-netinst.iso.
Подключите cdrom с образом `debian-11.4.0-amd64-netinst.iso`.

@ -0,0 +1,3 @@
# Экзаменационное задание для портфолио 1
Подготовьте PXE boot сервер, который позволяет установить Debian по сети. Продемонстрируйте на чистой виртуальной машине, поключенной к той же сети, что установка завершается успешно.

@ -1,41 +1,105 @@
# Задания
# 1. BIOS
Установите в машину `studX-bios` две операционные системы. Перед началом проверьте вкладку `Hardware` в Proxmox. В качестве `BIOS` должен быть выбран `SeaBIOS`. В наличии должно быть два диска `scsi0` и `scsi1`. Сетевой интерфейс должен быть `vmbrX`, а ip адреса из сети `192.168.0.0/24` (та же сеть, что и в занятиях 03 и 12 первого модуля) для доступа к сети интернет через шлюз `192.168.0.1`. Настройка сети не обязательна, кроме последнего задания.
Сначала установите Debian из образа `debian-12.1.0-amd64-netinst.iso` на диск `scsi0`. Затем установите Ubuntu Server (minimized) на второй диск `scsi1` `ubuntu-22.04.3-live-server-amd64.iso`. При установке Ubuntu выберите ручную разметку диска (3ий пункт `Something Else`). Создайте на неразмеченном диске следующие разделы:
- `Reserved BIOS boot area` размером 1MB,
- `Ext4 journaling file system` размером 512MB с точкой монтирования `/boot`,
- `swap area` размером 1024MB,
- `Ext4 journaling file system` размером оставшегося свободного пространства с точкой монтирования `/`.
Установите GRUB на тот диск, для которого вы произвели разметку. Игнорируйте предупреждение, об отсутствии `EFI` раздела.
В Proxmox изменить порядок загрузки, в отличие от реального железа, возможно во вкладке виртуальной машины `Options`. В реальном железе в подобное меню можно зайти при старте машины по специальной клавише, заданной производителем материнской платы, например: `Del`, `F12`.
### 1.1 BIOS
Включите машину с названием `bios`. Загрузите debian, загрузите ubuntu.
Перезагрузите машину. Какая ОС загружается по умолчанию? Загрузите Debian с помощью выбора в GRUB меню. Посмотрите на выдачу следующих команд:
```
# lsblk
# fdisk -l /dev/sda
# fdisk -l /dev/sdb
```
Загрузите Ubuntu и также проверьте эти команды.
Изучите директорию `/boot/`.
### 1.2 BIOS
Повторите операцию, выбрав в BIOS диск для загрузки в ручную.
Теперь загрузите Debian и Ubuntu, но с помощью выбора в меню BIOS диска для загрузки `scsi0` и `scsi1`. В меню можно попасть при загрузке машины по клавише `Esc`.
### 1.3 BIOS
Поменяйте порядок загрузки в BIOS.
Поменяйте порядок дисков загрузки в BIOS.
# 2. UEFI
Установите в машину `studX-uefi` две операционные системы. Перед началом проверьте вкладку `Hardware` в Proxmox. В качестве `BIOS` должен быть выбран `OVMF (UEFI)`. В наличии должно быть два диска `scsi0` и `scsi1`.
Сначала установите Debian из образа `debian-12.1.0-amd64-netinst.iso` на диск `scsi0`. Затем установите Ubuntu Server (minimized) на второй диск `scsi1` `ubuntu-22.04.3-live-server-amd64.iso`. При установке Ubuntu выберите ручную разметку диска (3ий пункт `Something Else`). Создайте на неразмеченном диске следующие разделы:
- `swap area` размером 1024MB,
- `Ext4 journaling file system` размером оставшегося свободного пространства с точкой монтирования `/`.
Установите GRUB на тот диск, для которого вы произвели разметку.
### 2.1 UEFI
Включите машину с названием `uefi`. Загрузите debian, загрузите ubuntu.
Перезагрузите машину. Какая ОС загружается по умолчанию? Загрузите Debian с помощью выбора в GRUB меню. Посмотрите на выдачу следующих команд:
```
# lsblk
# fdisk -l /dev/sda
# fdisk -l /dev/sdb
```
Загрузите Ubuntu и также проверьте эти команды.
Изучите директорию `/boot/efi/`.
### 2.2 UEFI
Поменяйте порядок загрузки в UEFI графической консоли.
Поменяйте порядок загрузки в UEFI графической консоли `UEFI Firmware settings`.
### 2.3 UEFI
Поменяйте порядок загрузки в UEFI терминале `efi shell`. Изучите команды и файловые системы FS0:, FS1:, FS2:.
Поменяйте порядок загрузки в UEFI терминале `EFI Internal Shell`. Изучите команды и файловые системы `FS0:`, `FS1:`, `FS2:`.
### 2.4 UEFI
Поменяйте порядок загрузки с помощью команды `efibootmgr` из операционной системы. Изучите директорию `/boot/efi`.
# 3. GRUB
### 3.0 GRUB
Зайдите в GRUB меню в shell во время загрузки машины клавишей `c`. Попробуйте следующие команды:
```
grub> ls
grub> ls (hd0, gpt1)/
grub> ls (hd0, gpt2)/
grub> ls (hd0, gpt3)/
```
Найдите диск с директорией `/efi` и найдите в ней папку `/efi/debian`. Выполните следующие команды:
```
set prefix=(hd0,1)/efi/debian
set root=(hd0,1)
insmod linux
insmod normal
normal
```
Вы должны попасть в GRUB, установленный Debian.
### 3.1 GRUB
В машине с названием `uefi`. Загрузите debian, загрузите ubuntu.
Поменяйте порядок загрузки операционных систем в `grub.conf`.
### 3.2 GRUB
Поменяйте порядок загрузки операционных систем.
### 3.3 GRUB
Настройте GRUB на ожидание 15 секунд перед загрузкой операционной системы по умолчанию, если никакая клавиша не нажата.
### 3.3 GRUB
Добавьте опцию в меню, которая загружает ОС в single-user mode (с параметром single).
Добавьте опцию в меню, которая загружает ОС в single-user mode (с параметром `single`).
# *Настройте PXE boot сервер
PXE — это протокол, используемый для загрузки операционных систем по сети https://ru.wikipedia.org/wiki/PXE.
Возьмите любые две машины в сети `192.168.0.1/24` подключенные к интерфейсу `vmbrX`. Следуя руководству https://linuxhint.com/pxe_boot_ubuntu_server/ настройте PXE загрузочный север.
### Доп. задание - Настроить PXE boot
Используйте мост vmbrX+ваш id для сетевого интерфейса. Используйте шлюз 192.168.1.1 для доступа в интернет.
Проверьте работу сервера на другой машине, выбрав `iPXE` в меню загрузки `BIOS`.
# Источники
@ -53,6 +117,7 @@
8. https://linuxhint.com/use-uefi-interactive-shell-and-its-common-commands/
9. https://docs.nvidia.com/networking/m/view-rendered-page.action?abstractPageId=25139424
10. https://help.ubuntu.com/community/Grub2
11. https://www.itzgeek.com/how-tos/linux/ubuntu-how-tos/how-to-install-ubuntu-22-04-lts.html
## Релевантные главы в книгах

@ -1,35 +1,56 @@
# Задания
## 0. Подготовка виртуальной машины
В последующих заданиях будет полезной функция Proxmox snapshot, которая позволяет откатить состояние жёстких дисков до момента времени снимка. Если вы будете пользоваться этой функцией, чтобы ускорить процесс создания снимка, предварительно выключайте машину.
### 0.1
Загрузите виртуальную машину `bios` или `uefi` с подключенным диском `gparted-live-*.iso` и загрузите debian с gparted. Зайдите в gparted найдите в интерфейсе все подключенные диски и их разметку.
### 0.2
Добавьте к оборудованию виртуальной машины 15 новых дисков по 0.1ГБ, обновите список устройств в интерфейсе gparted. Создайте snapshot виртуальной машины на случай ошибок в конфигурации.
Далее создадим несколько RAID массивов и логических томов LVM. Обе техники, RAID и LVM, абстрагируют примонтированные дисковые устройства от физических дисков. В обоих случаях в системе появляются новые блочные устройства в `/dev/`, которые можно использовать для создания файловых систем. В последнем задании попробуем современный подход к организации хранения данных с помощью ZFS или btrfs.
Далее создадим несколько `RAID` массивов и логических томов `LVM`. Обе техники, `RAID` и `LVM`, абстрагируют примонтированные дисковые устройства от физических дисков. В обоих случаях в системе появляются новые блочные устройства в `/dev/`, которые можно использовать для создания файловых систем. Решение `mdadm` является более специализированным для создания массивов дисков, в отличие от `LVM`. В последнем задании попробуем современный подход к организации хранения данных с помощью `ZFS` или `btrfs`.
## 1. Программный RAID
### Таблица 1. Типы RAID массивов
|Тип| Описание| Количество дисков | Выдерживает потерю |
|---|---------|-----------| ------ |
| RAID0 | Дисковый массив из двух или более жёстких дисков без резервирования (striping — «чередование»). | от 2 | 0 дисков |
| RAID1 | Массив из двух дисков являющихся полными копиями друг друга (mirroring — «зеркалирование»). | от 2 | N-1 дисков |
| RAID2 | Данные распределяются по дискам, предназначенным для хранения информации, так же, как и в RAID 0, но требуются выделенные диски в массиве для хранения кодов Хэмминга для коррекции ошибок. | от 3 | 1 диска |
| RAID3 | В массиве RAID 3 из N дисков данные разбиваются на куски размером меньше сектора и распределяются по N-1 дискам. Ещё один диск используется для хранения блоков чётности. Коррекция ошибок проще, чем в RAID 2, коды коррекции занимают 1 диск, вместо log2(N) дисков. | от 4 | 1 диска |
| RAID4 | RAID 4 похож на RAID 3, но отличается от него тем, что данные разбиваются на блоки, а не на байты. Отчасти это решает проблему низкой скорости чтения данных небольшого объёма. | от 4 | 1 диска |
| RAID5 | Основным недостатком уровней RAID от 2-го до 4-го является невозможность производить параллельные операции записи, так как для хранения информации о чётности используется отдельный контрольный диск. RAID 5 не имеет этого недостатка. Дисковый массив с чередует блоки данных и блоки контроля чётности. | от 3 | 1 диска |
| RAID6 | Массив из четырёх или более дисков с проверкой чётности `P+Q` (двумя томами чётности) или `DP` (разработанный для защиты от потери данных при выходе из строя сразу двух жестких дисков в массиве). | от 4 | 2 дисков |
| RAID01 | Массив типа RAID 1, состоящий из двух вложенных массивов типа RAID 0. | от 4, чётное | от 1 до N/2 дисков |
| RAID10 | Массив типа RAID 0, составленный из двух и более RAID 1 (зеркалированных пар). | от 4, чётное | от 1 до N/2 дисков |
| RAID51 | Массив типа RAID 1, зеркалирующий два RAID 5. | от 6, чётное | 2 до N/2+1 дисков |
https://ru.wikipedia.org/wiki/RAID
## 1. Программный RAID `mdadm`
### 1.1 RAID 0
#### 1.1.1
Зайдите в терминал. Изучите документацию `mdadm`: `man mdadm` и `mdadm --help`. Создайте программный raid массив типа 0 (чередование записи разбитого на блоки потока данных) на основе первых 2 созданных дисков по 0.1ГБ. Используйте сырые диски, например `/dev/sdc /dev/sdd`.
Зайдите в терминал. Изучите документацию `mdadm`: `man mdadm` и `mdadm --help`. Создайте программный raid массив типа 0 (чередование записи разбитого на блоки потока данных) на основе первых 2 созданных дисков по 0.1GB. Используйте сырые диски, например `/dev/sdc /dev/sdd`.
#### 1.1.2
Изучите документацию `mkfs.ext4`. Отформатируйте raid `/dev/md0` командой `mkfs.ext4` с опцией указания метки `-L raid0`.
#### 1.1.3
Примонтируйте файловую систему на `/dev/md0` в папку `/raid0`, предварительно её создав. Проверьте, что запись и чтение работают для этой директории. Проверьте размер диска, общий объем должен составлять 0.2GB.
Примонтируйте файловую систему на `/dev/md0` в папку `/raid0`, предварительно её создав. Проверьте, что запись и чтение работают для этой директории. Проверьте размер диска. Общий объем должен составлять 0.2GB.
#### 1.1.4
Отключите live диск с gparted, перезагрузите машину и зайдите в одну из ОС. Настройте сеть, если она ещё не настроена (используйте gateway 192.168.1.1), установите mdadm, если пакет ещё не установлен.
Отключите live диск с gparted, перезагрузите машину и зайдите в одну из ОС. Настройте сеть, если она ещё не настроена, установите `mdadm`, если пакет ещё не установлен.
Выведите список устройств в директории `/dev`, среди которых должно присутствовать устройство `/dev/md0`. Если его нет, после установки mdadm перезагрузите систему.
Выведите список устройств в директории `/dev`, среди которых должно присутствовать устройство `/dev/md0`. Если его нет, после установки `mdadm` перезагрузите систему.
Вызовите команды `mdadm --query` и `mdadm --detail` для `/dev/md0`.
#### 1.1.5
Изучите документацию fstab `man fstab`. Добавьте запись в `/etc/fstab` для автоматического монтирования raid при загрузке ОС в ту же директорию `/raid0`. Используйте UUID для указания на `/dev/md0` (вывести таблицу uuid можно командой `blkid`). Последние два значения установите в `0 2`. После перезагрузки системы, проверьте, что директория примонтировалась, доступна для записи и чтения.
Изучите документацию fstab `man fstab`. Добавьте запись в `/etc/fstab` для автоматического монтирования raid при загрузке ОС в ту же директорию `/raid0`. Используйте `UUID` для указания на `/dev/md0` (вывести таблицу `UUID` можно командой `blkid`). Последние два значения установите в `0 2`. После перезагрузки системы, проверьте, что директория примонтировалась, доступна для записи и чтения.
### 1.2 RAID 1
#### 1.2.1
@ -50,7 +71,7 @@ mdadm /dev/md1 --fail /dev/sdd
Добавьте диск обратно:
```
mdadm /dev/md0 --re-add /dev/sdd
mdadm /dev/md1 --re-add /dev/sdd
```
Повторите проверки.
@ -78,7 +99,7 @@ mdadm /dev/md0 --re-add /dev/sdd
### 2.1
Создайте логический диск с чередованием загрузки (striping, аналог raid 0). Примонтируйте в систем, проверьте работу логического тома.
В начале разметьте диски в gparted, создайте по одному разделу GPT. Затем установите метки lvm каждом диске командой `pvcreate`. Добавьте диски в группу (Volume group) с названием RAID0 командой `vgcreate`. Посмотрите на свойства группы командой `vgdisplay`. И создайте логический том командой `lvcreate`. Задайте ему название raid0, размер 0.2ГБ и количеством полосок для чередования записи равным 2.
В начале разметьте диски в gparted, создайте по одному разделу GPT. Затем установите метки lvm каждом диске командой `pvcreate`. Добавьте диски в группу (Volume group) с названием `RAID0` командой `vgcreate`. Посмотрите на свойства группы командой `vgdisplay`. И создайте логический том командой `lvcreate`. Задайте ему название raid0, размер 0.2ГБ и количеством полосок для чередования записи равным 2.
Проинициализируйте на логическом диске файловую систему, примонтируйте и проверьте её работоспособность.
@ -92,13 +113,14 @@ mdadm /dev/md0 --re-add /dev/sdd
ZFS и Btrfs обычно называют файловыми системами. Но на самом деле они представляют собой вертикально интегрированные подходы к управлению хранилищем, включающие в себя функции файловой системы, менеджера логических томов и RAID-контроллера.
### 3.1
Создайте аналоги RAID-10 (4 диска) и RAID-5 (3 диска) в одной из файловых систем: btrfs или zfs.
Создайте аналоги RAID-10 (4 диска) и RAID-5 (3 диска) в одной из файловых систем: `btrfs` или `zfs`.
Установите пакет:
- `btrfs-progs`, если он ещё не установлен для работы с btrfs,
- `zfsutils-linux` (contrib ветка), если он ещё не установлен для работы с zfs.
# Релевантная литература
1. Nemeth E. et al. UNIX and Linux system administration handbook. Chapter 5, Chapter 20.
2. Lukas, Jude. FreeBSD Mastery: ZFS

@ -1,5 +1,11 @@
# Задания
Стандартная модель UNIX представляет из себя форму "избирательного контроля доступа" (DAC - Discretionary Access Control), поскольку позволяет владельцам контролируемых объектов устанавливать права на них. Пользователь сам может разрешить другим просмотр содержимого домашнего каталога или написать программу с флагом `setuid`, которая позволит другим пользователям отправлять сигналы его процессам.
Системы мандатного управления доступом (MAC, Mandatory Access Control) позволяют администраторам писать политики контроля доступа, которые переопределяют или дополняют избирательные разрешения традиционной модели. Например, вы можете установить правило, согласно которому домашние каталоги доступны только их владельцам. Это может помочь сохранить конфиденциальные документы, даже если пользователь небрежно относится к его разрешениям. Хотя такие системы разрабатывались для реализации многоуровневой безопасности в государственных организациях с различными грифами секретности, на практике чаще всего вы сталкнётесь с её применением для защиты фоновых служб. Хорошо реализованные политики могут помешать компрометации системы с уязвимым программным обеспечением.
SELinux - одна из старейших реализаций системы MAC для Linux, разработанная в Агентством национальной безопасности США. Система реализует почти все возможности MAC и RBAC (Role Based Access Control). Из-за этого разработка политик является сложной задачей. К счастью, многие общие политики доступны онлайн и имеют разумные значениям по умолчанию. Для упрощения разработки политик могут использоваться специализированные редакторы, например https://seedit.sourceforge.net/.
## 0. Инициализация SELinux
Источник: https://wiki.debian.org/SELinux/Setup
@ -39,13 +45,14 @@ $ sudo apt install selinux-policy-doc
## 2. Базовые команды и определения
Потренируемся далее с базовыми командами.
Далее потренируемся с базовыми командами.
### 2.1 Изучим установленные контексты безопасности
Для начала давайте проверим контекст файла в домашнем каталоге пользователя `stud`:
```
$ cd
$ touch file
$ ls -Z
```
Флаг `-Z` присутствует в широком спектре распространенных инструментов CLI, включая `ls` и `ps`. При указании этого флага в дополнении к стандартным разрешениям UNIX, информации о пользователе и группе отображается контекст SELinux файла.
@ -58,14 +65,16 @@ $ ls -Z
Пользователь SELinux отличается от пользователя UNIX и существует исключительно для того, чтобы связать пользователя UNIX с набором ролей. Это позволяет пользователям UNIX быть ограниченными политикой SELinux.
В нашем случае пользователь `unconfined_u` означает, что пользователь сопоставлен с логином SELinux по умолчанию. Это означает, что пользователю разрешено запускать любое приложение, разрешенное стандартными разрешениями файловой системы. Однако, если приложение может перейти в другой домен, к нему будут применятся ограничения, задаваемые SELinux.
В нашем случае пользователь `unconfined_u` означает, что пользователь сопоставлен с пользователем SELinux по умолчанию. Это означает, что пользователю разрешено запускать любое приложение, разрешенное стандартными разрешениями файловой системы. Однако, если приложение может перейти в другой домен, к нему будут применятся ограничения, задаваемые SELinux.
Список пользователей SELinux в системы можно посмотреть командами:
```
$ seinfo -u
$ semanage login -l
```
Cписок сопоставлений между учетными записями пользователей SELinux и Linux
```
# semanage login -l
```
### 2.2 Переход в другой домен
Чтобы продемонстрировать разницу между процессами c ограничениями и без, давайте запустим приложение, которого переход в другой домен не определён:
@ -73,7 +82,18 @@ $ semanage login -l
# yes >/dev/null &
# ps -Z | grep yes
```
Процесс `yes` помечен доменом `unconfined_t`, что указывает на то, что он по-прежнему обладает полными привилегиями `root` и может делать всё, что пожелает.
Дадим расшифровку вывода selinux метки процесса.
```
<user>:<role>:<type>:<secrecy_level>:optional
```
- Вначале выводится идентификатор пользователя SELinux `unconfined_u`.
- Частью SELinux является модель безопасности управления доступом на основе ролей (RBAC). Пользователи SELinux авторизованы для ролей, а роли авторизованы для доменов. Роль служит посредником между доменами и пользователями SELinux. Роли, которые можно ввести, определяют, в какие домены можно войти; в конечном итоге это определяет, к каким типам объектов можно получить доступ. Модель ролей помогает лучше отразить требования к безопасности и тем самым снизить уязвимость к атакам. В данном случае выводится роль `unconfined_r`.
- Метка типа `unconfined_t` является атрибутом Type Enforcement. Тип определяет домен для процессов и тип для файлов. Правила политики SELinux определяют, как типы могут получать доступ друг к другу, будь то домен, обращающийся к типу, или домен, обращающийся к другому домену. Доступ разрешен только в том случае, если существует определенное правило политики SELinux, которое разрешает это.
- Уровень (секретности) является атрибутом MLS (Multi-Level Security, модель Bell-La Padula) и MCS (Multi-Category Security). Диапазон MLS представляет собой пару уровней, записываемую как `lowlevel-highlevel`, если уровни различаются. Если уровни идентичны `s0-s0` может записываться одним значением `s0`.
- В опциональном поле отображаются категории, которые не являются обязательными. Если есть категории, уровень записывается как `уровень: набор категорий`. Если категорий нет, пишется как `уровень`. Если набор категорий представляет собой непрерывную серию, его можно сократить. Например, `c0.c3`— это то же самое, что `c0,c1,c2,c3`. Файл `/etc/selinux/default/setrans.conf` отображает уровни (`s0:c0`) в удобочитаемую форму (то есть `CompanyConfidential`).
Итак, процесс `yes` помечен доменом `unconfined_t`, что указывает на то, что он по-прежнему обладает полными привилегиями `root` и может делать всё, что пожелает.
Мы увидим другую картину для процесса `auditd`:
```
@ -81,7 +101,7 @@ $ semanage login -l
```
Обратите внимание, что третье поле - `auditd_t`, означающее, что процесс `auditd` был ограничен доменом `auditd_t`.
Остановим запущенный фоновые процессы `yes` и двинемся дальше.
Остановим запущенный фоновый процесс `yes` и двинемся дальше.
```
# jobs
# kill %1
@ -92,23 +112,29 @@ $ semanage login -l
```
type_transition <текущий_домен> <тип_программы>: <class> <целевой_домен>
```
Следующее правило гласит, что когда процесс в домене `initrc_t` запускает файл типа `acct_exec_t`, домен процесса должен быть изменен на `acct_t`, если это разрешено политикой. Чтобы это правило перехода домена работало, нужно также присутствие нескольких разрешений.
```
type_transition initrc_t acct_exec_t:process acct_t;
allow initrc_t acct_exec_t:file execute; # Разрешение на запуск файла типа acct_exec_t в исходном домене initrc_t
allow acct_t acct_exec_t:file entrypoint; # Разрешение на наличие точки входа файла типа acct_exec_t в домен целевой домен acct_t
allow initrc_t acct_t:process transition; # Разрешение процессу на переход в домен целевой acct_t
# Разрешение на запуск файла типа acct_exec_t в исходном домене initrc_t
allow initrc_t acct_exec_t:file execute;
# Разрешение процессу на переход в домен целевой acct_t
allow initrc_t acct_t:process transition;
# Разрешение на наличие точки входа файла типа acct_exec_t в домен целевой домен acct_t
allow acct_t acct_exec_t:file entrypoint;
```
Подробнее в документации правила https://selinuxproject.org/page/TypeRules.
Обычно в политиках используют макрос `domtrans_pattern` или `domain_transition_pattern` определённый в `/usr/share/selinux/devel/include/support/misc_patterns.spt` для указания правила перехода и разрешений вместе.
### 2.3 Полезная утилита - restorecon
Если и есть, что посоветовать запомнить новому пользователю SELinux, так это `restorecon`. Restorecon приведет контекст SELinux к тому, что определено в базе данных контекста системы.
Если и есть, что посоветовать запомнить новому пользователю SELinux, так это `restorecon`. Restorecon приведет контекст SELinux к тому, который определен в базе данных контекста системы.
Чтобы попробовать, давайте намеренно неправильно установим контекст в примере SELinux AVC log:
Чтобы попробовать, давайте намеренно неправильно установим контекст:
```
# touch testaudit
# ls -Z ./testaudit
system_u:object_r:admin_home_t:s0 ./testaudit
# chcon -t httpd_sys_content_t ./testaudit
@ -125,17 +151,17 @@ Relabeled /root/testaudit from system_u:object_r:httpd_sys_content_t:s0 to syste
```
Выше также применяется `chcon`, которой вы можете временного изменить контекст файла.
Установка контекст на `httpd_sys_content_t` также устранила бы проблему, о которой сообщалось в нашем тестовом AVC.
## 3. Установка тестового сервиса
Подготовим сервис, для которого далее будем писать собственную политику безопасности SELinux.
Скачайте текущий репозиторий и перейдите в папку `linux_tasks/modeul2/test_service`.
Скачайте текущий репозиторий и перейдите в папку `linux_tasks/module2/02_mac_selinux/test_service`.
Настройте окружение разработчика, скачайте необходимые заголовочные файлы и установите сервис `testapp` с помощью `make`:
```
$ sudo apt install build-essential libcurl4-openssl-dev
$ make
$ cat Makefile
$ sudo make install
```
@ -184,8 +210,8 @@ system_u:system_r:testapp_t:s0 root 5792 1 0 10:27 ? 00:00
### 4.1 Сгенерируйте шаблон политики SELinux
Создайте каталог-проект политики и сгенерируйте в нём шаблонные файлы политики с помощью команды `sepolicy generate`.
```
$ mkdir policy
$ cd policy
$ mkdir testapp_policy
$ cd testapp_policy
$ sepolicy generate --init /usr/local/sbin/testapp
```
@ -203,7 +229,7 @@ Created the following files:
- `testapp.te` - это базовая политика для приложения. Он устанавливает правила для домена `testapp_t`,
- `testapp.if` - это файл интерфейса. Интерфейсы подобны общедоступным функциям в том смысле, что они предоставляют другим модулям SELinux способы взаимодействия с тем, который вы пишете,
- `testapp.fc` - это файл контекстов. Он содержит информацию о маркировке всех объектов файловой системы, на которые ссылается политика,
- `testapp.sh` это предоставленный Red Hat скрипт, который компилирует и загружает модуль политики SELinux.
- `testapp.sh` это скрипт, который компилирует и загружает модуль политики SELinux.
### 4.2. Скомпилируйте и загрузите политику
@ -212,6 +238,8 @@ Created the following files:
$ sudo ./testapp.sh
```
Примечание. Замените в файле `*.te`слово `pid` на `runtime` в макросах `files_*`.
Первые 9 строк выходных данных показывают компиляцию политики, загрузку политики в память и автоматическое создание справочной страницы для политики:
```bash
Building and Loading Policy
@ -241,6 +269,7 @@ system_u:system_r:testapp_t:s0 root 8737 1 0 20:51 ? 00:00:00
```
### 4.4. Как приложение в конечном итоге получает testapp_context?
Это связано с правилами перехода домена SELinux. Служба `testapp` запускается `systemd`, которая запускается с контекстом `init_t`, поскольку это наша служба инициализации. Из-за правил перехода он изменяет контексты при запуске службы.
Чтобы просмотреть эти правила, введите:
@ -249,8 +278,7 @@ $ sesearch -T -s init_t -t testapp_exec_t
type_transition init_t testapp_exec_t : process testapp_t;
```
Правило гласит, что когда любой процесс, помеченный как `init_t`, выполняет любой двоичный файл, помеченный как `testapp_exec_t`, вновь созданный процесс будет помечен как `testapp_t`.
Правило гласит, что когда любой процесс, помеченный как `init_t`, выполняет любой ,исполняемый файл, помеченный как `testapp_exec_t`, вновь созданный процесс будет помечен как `testapp_t`.
На данный момент у нас есть общая политика для приложения `testapp`, которая настроена на разрешающий режим. Таким образом, приложение может запускаться, и SELinux будет генерировать предупреждения при нарушении существующей системной политики, но не будет предпринимать никаких действий.
@ -308,7 +336,7 @@ type=AVC msg=audit(1552588580.764:25971): avc: denied { read } for pid=1022 c
Если мы внимательно посмотрим на них, то увидим, что процессу тестового приложения отказано в открытии в `/proc/meminfo` и в чтении в `/proc` в целом. Итак, нам нужно найти интерфейс, который позволит осуществлять эти доступы, и добавить его в наш файл `testapp.te`.
### 6.2 Найдите правильный интерфейс
Определения интерфейса SELinux находятся в `/usr/share/selinux/devel/include`, если вы устанавливаете пакет `selinux-policy-devel`. Если мы ищем `/proc`, в файлах с именем `*.if` (определения интерфейса):
Определения интерфейса SELinux находятся в `/usr/share/selinux/devel/include`, если вы установили пакет `selinux-policy-devel`. Если мы ищем `/proc`, в файлах с именем `*.if` (определения интерфейса):
```
$ cd /usr/share/selinux/devel/include
$ find . -type f -name "*.if" -exec grep -H '/proc' {} \; | grep "system state information"
@ -945,6 +973,7 @@ setsebool P httpd_enable_homedirs on
# Релевантные ссылки
- https://security.stackexchange.com/questions/63518/mac-vs-dac-vs-rbac,
- https://wiki.debian.org/SELinux/Setup
- https://github.com/SELinuxProject/refpolicy/wiki/GettingStarted,
- https://debian-handbook.info/browse/en-US/stable/sect.selinux.html,

@ -0,0 +1,44 @@
# Экзаменационное задание для портфолио 2
Подготовьте демонстрацию работы nginx сервиса в режиме высокой доступности. Согласно схеме, сделайте так, что nginx на studX проксирует:
- все запросы по адресу `/ha/1/` узлу `gwX` для демонстрации работы сайта в режиме высокой доступности настроенном с помощью модуля `ngx_http_upstream_module`,
- все запросы по адресу `/ha/2/` узлу `10.160.179.140+X` для демонстрации работы сайта в режиме высокой доступности настроенном с помощью `keepalived`.
```
________
| |
| клиент | (ноутбук)
|________|
|
роутер public IP 193.32.63.170+X:[22,80,443] -> private IP 10.160.179.10+X:[22,80,443]
|
_______|_______
| | /ha/2/
| studX |---------------------------+-------------------+
|_______________| | | 10.160.179.140+X/24 в роли virtual IP
| /ha/1/ | ens18 | ens18
| ens18 в vlan499 ___________ ___________
_______|_______ | | | |
| | | nginx 3 | | nginx 4 |
| gwX | |___________| |___________|
|_______________| | ens19 в vlan X | ens19 в vlan X
| ens19 в vlan X | 192.168.0.11/24 | 192.168.0.12/24
| IP 192.168.0.1/24 +-------------------+
+---------+--------+
| 192.168.0.2/24 | 192.168.0.3/24
___________ ___________
| | | |
| nginx 1 | | nginx 2 |
|___________| |___________|
```
На узлах ngix1 - nginx4 с помощью таймеров systemd каждую минуту должны происходить перезагрузки в определённый момент времени.
Схема доступности сайта для узлов nginx1 и nginx2:
| Время (сек) | nginx1/nginx3 | nginx 2/nginx4|
|-------|--------|--------|
|0-10|True|True|
|10-25||True|
|25-35|True|True|
|35-50|True||
|50-60|True|True|

@ -9,4 +9,34 @@
7. Где можно посмотреть документацию keepalived?
8. Требуется ли прокси-сервер для работы виртуального IP адреса?
9. В каком файле хранится конфигурация keepalived?
10. В каком конфигурационном файле nginx можно прописать блок upstream?
10. В каком конфигурационном файле nginx можно прописать блок upstream?
11. В чём назначение sorry_server?
12. Какую задачу позволяет решить Linux Virtual Server?
13. В чём отличие LVS от VRRP?
14. Что настраивает параметр `virtual_server -> real_server -> CHECKER_TYPE`?
15. Приведите несколько возможных типов проверок доступности узла LVS.
16. Как связаны команда `ipvsadm` и `keepalived`?
17. Для чего может быть полезен расширенный синтаксис конфигурации `keepalived.conf`?
18. Какие три класса скриптов могут быть сконфигурированы в `keepalived.conf`?
19. По умолчанию от имени какого пользователя будут выполняться скрипты?
20. Какие 4 типа конфигурационных блоков доступны в `keepalived.conf`?
21. Какую задачу решает протокол BFD?
22. Опишите работу алгоритма BFS.
23. Как связаны VRRP приоритеты и состояние BFD инстанса?
24. Что хранится в параметре `bfd_instance -> multiplier`?
25. Чем отличаются активный и пассивный режимы BFD?
26. Для чего нужны параметры `rise` и `fall` в блоке `vrrp_script`?
27. Для чего с практической точки зрения могут понадобиться vrrp группы синхронизации?
28. Какая связь между `vrrp_instance` и сетевым интерфейсом: 1 к 1, многие к 1, 1 ко многим, многие к многим?
29. Как определяется начальное состоянием vrrp инстанса и как оно меняется со временем в зависимости от приоритета?
30. Содержат ли vrrp пакеты оповещения приоритет и идентификатор роутера?
31. Как часто передаются пакеты оповещения?
32. Что происходит, если оба `keepalived vrrp_instance` на разных узлах заявляют в пакетах оповещения об одинаковом приоритете?
33. Каковы последствия появления ситуации split-brain для сервиса высокой доступности `keepalived`?
34. Передаёт ли vrrp инстанс в состоянии BACKUP пакеты оповещения?
35. Для чего нужны параметры: track_process, track_file, track_bfd?
36. В каком блоке можно сконфигурировать маршруты, удаляемые из таблицы маршрутизации при переходе в состояние BACKUP?
37. Можно ли добавить/удалить правила сетевого фильтра при смене состояний: MASTER->BACKUP,BACKUP->MASTER?
38. Можно ли настроить `keepalived` для балансировки трафика?
39. Для чего нужен планировщик LVS?
40. Из чего состоит кворум LVS? Может ли размер кворума меняться во времени?

@ -165,6 +165,7 @@ fi
# Релевантные источники
- https://nginx.org/ru/docs/http/ngx_http_upstream_module.html
- https://ru.wikipedia.org/wiki/VRRP
- https://keepalived.readthedocs.io/en/latest/
- `man keepalived.conf`, https://www.keepalived.org/manpage.html (на данный момент лучшая документация, идеально отражающая и документирующая все доступные функции)
- https://keepalived.readthedocs.io/en/latest/ (эта документация является устаревшей, поскольку является частичной и не отражает полный набор доступных функций)
- https://datatracker.ietf.org/doc/html/rfc2338
- http://www.austintek.com/LVS/LVS-HOWTO/mini-HOWTO/LVS-mini-HOWTO.html

@ -0,0 +1,8 @@
# Экзаменационное задание для портфолио 3
Настройте почтовый сервер на основе Postfix и Dovecot для своего домена studX.myoffice.ru (или любой другой). Заведите один или несколько почтовых ящиков для новых пользователей. Пользователь должен иметь возможность:
- подключиться из мобильного или десктопного почтового клиента к серверу со своим логином и паролем,
- отправить почту на внешний адрес gmail.com/yandex.ru/mail.ru,
- принять почтовое сообщение с внешнего адреса отправленное как ответ на входное письмо.
Сервер должен пройти проверку c помощью валидатора https://esmtp.email/tools/mta-sts/.

@ -0,0 +1,119 @@
Какое нам дело до классов адресов? Классы адресов опеределяют то, как Postfix принимает решения какие письма принимать и куда их доставлять. Класс адреса определяется тремя вещами:
- список доменов,
- список действительных адресов получателей,
- транспорт доставки по умолчанию.
Можно считать, что класс адресов - это правило, применяемое к полю `Кому:` конверта элекронного письма. Правило имеет вид:
```
user@domain -> agent(user, domain),
```
которое применяется, если истинно, что:
```
user ∈ USERS,
domain ∈ DOMAINS,
agent ∈ AGENTS.
```
По умолчанию определён следующий список классов адресов:
- local domain class (локальные почтовые ящики),
- virtual mailbox domain class (виртуальные почтовые ящики),
- virtual alias domain class (виртуальные псевдонимы),
- relay domain class (адреса транзитных smtp серверов),
- default domain class (адреса по умолчанию).
Для локальных (local domain class) и виртуальных (virtual mailbox class) почтовых ящиков пустое множество в `USER = {}` означает, что проверка пользователей отключена, то есть подходит любое имя пользователя.
Для разрешения псевдонимов в адреса в классе virtual alias domain class (виртуальные псевдонимы) агент не используется `AGENTS = {}`.
### 1. local domain class (`domain ∈ mydestination inet_interfaces proxy_interfaces`)
Доставка последней мили до почтовых ящиков пользователей в `canonical` доменах, имеющих аккаунты в UNIX системе. Имена `user` определяются параметром `local_recipient_maps`. По умолчанию заничение равно `proxy:unix:passwd.byname $alias_maps`, то есть `/etc/passwd` и `/etc/aliases`.
Адрес получателя локальный, если его домен совпадает с `mydestination`, `inet_interfaces` или `proxy_interfaces`.
```
agent = local из local_transport
USERS = /etc/passwd /etc/aliases
DOMAINS = mydestination inet_interfaces proxy_interfaces
AGENTS = service names ∈ /etc/postfix/master.cf
```
### 2. virtual mailbox domain class (`domain ∈ virtual_mailbox_domains`)
Доставка последней мили до почтовых ящиков пользователей в `hosted` доменах, чьи пользователи не имеют аккаунтов в UNIX системе. Адреса почтовых ящиков вида `user@domain` ищутся в одной или нескольких таблицах указанных в параметре `virtual_mailbox_maps`.
```
agent = virtual из virtual_transport
USERS = virtual_mailbox_maps
DOMAINS = virtual_mailbox_domains
AGENTS = service names ∈ /etc/postfix/master.cf
```
### 3. virtual alias domain class (виртуальные псевдонимы)
* Назначение: хостинговые домены, в которых каждый адрес получателя псевдонимом привязан к учётной записи локальной UNIX-системы или к удаленному адресу. Пример виртуального псевдонима приведен в файле VIRTUAL_README.
* Доменные имена перечисляются в virtual_alias_domains. Для совместимости с Postfix 1.1 по умолчанию используется значение $virtual_alias_maps.
* Действительные адреса получателей перечисляются в параметре virtual_alias_maps. SMTP-сервер Postfix отклоняет недействительных получателей с сообщением "Пользователь неизвестен в таблице виртуальных псевдонимов". Для совместимости с Postfix 1.1 по умолчанию используется значение $virtual_maps.
* Транспортный параметр доставки почты отсутствует. Каждый адрес должен быть псевдонимом для какого-либо другого адреса.
```
agent =
USERS = virtual_alias_maps
DOMAINS = virtual_alias_domains
AGENTS = {}
```
### 4. relay domain class (адреса транзитных smtp серверов)
* Назначение: переадресация почты на удаленные адреса, в которых ваша система указана в качестве основного или резервного MX-хоста. Для обсуждения основных деталей конфигурации см. документ BASIC_CONFIGURATION_README. Обсуждение различий между каноническими доменами, размещенными доменами и другими доменами см. в файле VIRTUAL_README.
* Доменные имена перечисляются с помощью параметра relay_domains.
* Действительные адреса получателей перечисляются с помощью параметра relay_recipient_maps. SMTP-сервер Postfix отклоняет недействительных получателей с сообщением "User unknown in relay recipient table". Если значение этого параметра пустое, то SMTP-сервер Postfix принимает всех получателей для доменов, перечисленных в параметре relay_domains.
* Транспорт доставки почты задается параметром relay_transport. По умолчанию используется значение relay, которое является клоном агента доставки smtp(8).
```
agent = relay из relay_transport
USERS = relay_recipient_maps
DOMAINS = relay_domains
AGENTS = service names ∈ /etc/postfix/master.cf
```
### 5. default domain class (адреса по умолчанию)
* Назначение: пересылка почты в Интернет от имени авторизованных клиентов. Для обсуждения основных деталей конфигурации см. файл BASIC_CONFIGURATION_README. О различиях между каноническими доменами, размещенными доменами и другими доменами см. файл VIRTUAL_README.
* У этого класса нет таблицы доменов назначения.
* Этот класс не имеет таблицы действительных адресов получателей.
* Транспорт доставки почты задается параметром default_transport. По умолчанию используется значение smtp для доставки с помощью агента доставки smtp(8).
```
agent = smtp из default_transport
USERS = relay_recipient_maps
DOMAINS = relay_domains
AGENTS = service names ∈ /etc/postfix/master.cf
```
Анекдот про выбор протокола шифрования в STARTTLS:
```
А: Давай по SSL 2.0.
Б: Могу только по SSL 3.0.
А: Тогда предлагаю по TLS 1.0.
Б: У меня TLS 1.1.
А: А TSL 1.2 нет?
Б: Могу без шифрования
А: Договорились
```
Возможные структуры почтовой системы:
- Postfix, Dovecot имеют доступ к списку пользователей и работают параллельно, разделяя доступ к почтовым ящикам пользователей.
- Dovecot является «бэкендом» для доступа к почтовым ящикам пользователей. При этом подходе, расположение почтовых ящиков, список пользователей, известен только Dovecot.
Источники:
1. https://habr.com/ru/articles/258279/
2.

@ -165,7 +165,7 @@ INNER JOIN departments d ON (e.department_id = d.department_id);
| Колонка | Связь с |
|-------------|---------------------------------------------|
| employee_id | |
| dependent_id | |
| first_name | |
| last_name | |
| employee_id | таблицей `employees` колонкой `employee_id` |
@ -598,4 +598,6 @@ FROM pg_stat_user_tables;
- Мартин Грабер — Понимание SQL
- https://www.postgresql.org/docs/
- https://theartofpostgresql.com
- https://www.crunchydata.com/developers/tutorials
- https://www.crunchydata.com/developers/tutorials
- https://www.sql-ex.ru/
- https://sqlbolt.com/

@ -0,0 +1,7 @@
# Экзаменационное задание для портфолио 4
Выполните задания по настройке Proxmox на виртуальных машинах и предоставьте доступ к веб-интерфейсу по адресу `https://studX.myoffice.ru/proxmox/`. Заведите тестового пользователя, который обладает правами на:
- запуск/выключение созданной для него виртуальной машины,
- может создавать диски,
- может изменять конфигурацию оборудования виртуальной машины,
- может сохранять бекапы и делать снепшоты системы.

@ -1,79 +1,112 @@
# Задания
## 1.
Установите Proxmox на две виртуальные машины Proxmox. Используйте образ диска `proxmox_7.2.1.iso`.
Установите Proxmox на две виртуальные машины Proxmox. Используйте образ диска `proxmox_8.0.2.iso`.
Параметры виртуальных машин:
- объем памяти RAM 32ГБ,
- число ядер 8,
- объем памяти RAM 16ГБ,
- число ядер 4,
- объем жёсткого диска 32ГБ,
- сетевое устройство в vlan 15+X (подключенное к мосту vmbr15+X, без указания vlan тега),
- IP из сети `192.168.1.0/24`,
- шлюз `192.168.1.1`,
- сетевое устройство vmbrX.
Параметры установки:
- IP из сети `192.168.0.0/24` (192.168.0.[201-202]) или из сети 10.160.179.0/24,
- шлюз `192.168.0.1` или 10.160.179.1,
- любой общедоступный DNS,
- стандартный пароль для пользователя root,
- доменные имена `n[1-2].studX.myoffice.ru`.
Используйте утилиту `pveversion`, чтобы узнать версию Proxmox.
Для удобства, настройте беспарольный доступ между машинами. Так как ключи уже сгенерированы при установке, достаточно выполнить `ssh-copy-id`. Чтобы использовать доменные имена на данном этапе внесите их в `/etc/hosts` каждой машины.
## 2.
Объедините узлы в Proxmox кластер. Используйте утилиту `pvecm` (документация утилиты `man pvecm`). Чтобы использовать доменные имена на данном этапе внесите их в `/etc/hosts` каждой машины.
Объедините узлы в Proxmox кластер. Используйте утилиту `pvecm` (документация утилиты `man pvecm`).
```
root@n1 # pvecm create stud15-cluster
root@n1 # pvecm create studX-cluster
root@n1 # systemctl restart corosync
root@n1 # pvecm status
```
```
root@n2 # pvecm add n1.stud15.myoffice.ru
root@n2 # pvecm add n1.studX.myoffice.ru
root@n2 # pvecm status
```
## 3.
Настройте доступ к веб-интерфейсу с помощью прокси сервера или туннелей. Прокси-машина должна иметь два сетевых интерфейса, каждый в своей vlan: 499 и 15+X. Первая vlan позволяет подключиться к прокси из сети интернет, вторая позволяет обмениваться данными между прокси и новым кластером Proxmox.
Схема с 2 туннелями
```
Ноутбук --туннель--> (vmbr499) ens18 studX.myoffice.ru ens19 (vmbr30) <--туннель-- ens18 (vmbr30) n1.studX.myoffice.ru[192.168.1.200] (vlan 15+X)
n1 $ ssh -R 8006:localhost:8006 stud@studX.myoffice.ru
notebook $ ssh -L 8006:localhost:8006 stud@studX.myoffice.ru
```
Параметры `-L` и `-R` обозначают точку входа, локальную или на машине, к который подключается ssh. Пакеты отправленные на точку входа будут переданы через туннель, а затем направлены на адрес и порт, указанные после первого порта 8006.
Возможен более простой вариант с одним туннелем:
```
Ноутбук --туннель--> (vmbr499) ens18 studX.myoffice.ru ens19 (vmbr30) ------> ens18 (vmbr30) n1.studX.myoffice.ru[192.168.1.200]
notebook $ ssh -L 8006:192.168.1.200:8006 stud@studX.myoffice.ru
```
Настройте доступ к веб-интерфейсу с помощью прокси сервера. Прокси-машина должна иметь два сетевых интерфейса, каждый в своей vlan: 499 и X. Первая vlan позволяет подключиться к прокси из сети интернет, вторая позволяет обмениваться данными между прокси и новым кластером Proxmox.
Пример настройки прокси сервера nginx.
```
server {
listen 80 default_server;
listen [::]:80 default_server;
return 301 https://$host$request_uri;
listen 80 default_server;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/stud15.myoffice.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/stud15.myoffice.ru/privkey.pem;
ssl_verify_client off;
server_name _;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass https://192.168.1.200:8006;
}
location /nginx_ha {
rewrite ^/nginx_ha(.*)$ $1 break;
proxy_pass http://10.160.179.183:80;
}
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/stud15.myoffice.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/stud15.myoffice.ru/privkey.pem;
ssl_verify_client off;
server_name _;
location / {
if ($args ~ ^console) {
proxy_pass https://192.168.0.201:8006;
}
try_files $uri $uri/ =404;
}
location /ha/1 {
return 302 https://stud12.myoffice.ru/ha/1/;
}
location /ha/1/ {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
#try_files $uri $uri/ =404;
proxy_pass http://backend/;
}
location /ha/2 {
return 302 https://stud12.myoffice.ru/ha/2/;
}
location /ha/2/ {
proxy_pass http://192.168.0.4/;
}
location /proxmox {
return 302 https://stud12.myoffice.ru/proxmox/;
}
location /proxmox/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Accept-Encoding "";
# Standard proxying headers (why do we need this?)
proxy_set_header Host stud12.myoffice.ru;
proxy_set_header X-Real-IP 193.32.63.182;
# You need to set this manually since we include this file inside a server block on a main config
proxy_set_header X-Forwarded-Host stud12.myoffice.ru;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# SSL proxying headers
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Ssl on;
# hack
sub_filter_once off;
sub_filter 'stud12.myoffice.ru/' 'stud12.myoffice.ru/proxmox/';
sub_filter 'src="' 'src="/proxmox';
sub_filter 'href="' 'href="/proxmox';
sub_filter_types "text/html" "text/javascript" "application/json";
proxy_pass https://192.168.0.201:8006/;
}
location ~ ^\/(pve2|api2|novnc|xtermjs|pve-doc|pwt) {
rewrite ^/(.+) /proxmox/$1;
proxy_pass https://192.168.0.201:8006/$request_uri;
}
}
```
Настроено перенаправление с 80 порта на 443, letsencrypt сертификаты, отключена проверка сертификатов для проксируемого сервера (в новом proxmox используются самоподписанные сертификаты на текущий момент). В локации `/` настроено проксирование на `n1.stud15.myoffice.ru`, а также добавление заголовков `Upgrade` и `Connection` для переключения с протокола http на websocket при необходимости (http://nginx.org/en/docs/http/websocket.html). Таким образом узел нового Proxmox кластера доступен по адресу `https://stud15.myoffice.ru/`. Сервер из задания `03_nginx_ha` доступен при обращении к адресу `https://stud15.myoffice.ru/nginx_ha`.
## 4.
Создайте виртуальную машину в новом Proxmox. Скачайте образ `Core` проекта `Tiny Core Linux` http://tinycorelinux.net/downloads.html.
@ -91,7 +124,7 @@ $ qemu-img convert -f raw -O vdi /tmp/exported_vm_100_archive/disk-drive-scsi0.r
Объем пространства, занимаемый образом, можно определить с помощью команд `qemu-img info` или `ls -ls`;
Предупреждение: Никогда не используйте `qemu-img` для изменения образов, используемых запущенной виртуальной машиной или любым другим процессом; это может привести к уничтожению образа. Кроме того, имейте в виду, что запрос образа, которое изменяется другим процессом, может привести к несогласованному состоянию.
Предупреждение: Никогда не используйте `qemu-img` для изменения образов, используемых запущенной виртуальной машиной или любым другим процессом; это может привести к уничтожению образа. Кроме того, имейте в виду, что запрос образа, который изменяется другим процессом, может привести к несогласованному состоянию.
## 6.
Для восстановления из бекапа используется утилита `qmrestore` (`man qmrestore`). Восстановите из бэкапа виртуальную машину под другим идентификатором.

@ -4,46 +4,46 @@
Расписание занятий в офисе: 5 раз в неделю --- пн - пт
Время начала занятий: 17:00
| Темя занятия | Количество рабочих часов в офисе | Количество рабочих часов вне офиса |
|--------------------------------------------------|----------------------------------|------------------------------------|
| [00_os_installation](./module1/00_os_installation/) | 4 | 0 |
| [01_bash](./module1/01_bash/) | 4 | 0 |
| [02_data_editing_and_analysis](./module1/02_data_editing_and_analysis/) | 4 | 0 |
| [03_networking](./module1/03_networking/) | 4 | 0 |
| [04_systemd](./module1/04_systemd/) | 4 | 0 |
| [05_hash_ciphers_ssh_certs](./module1/05_hash_ciphers_ssh_certs/) | 4 | 0 |
| [06_user_management](./module1/06_user_management/) | 4 | 0 |
| [07_file_permissions](./module1/07_file_permissions/) | 4 | 0 |
| [08_debian_package_management](./module1/08_debian_package_management/) | 4 | 0 |
| [09_nginx](./module1/09_nginx/) | 4 | 0 |
| [10_bash_scripts](./module1/10_bash_scripts/) | 4 | 0 |
| [11_cron_at](./module1/11_cron_at/) | 4 | 0 |
| [12_troubleshooting](./module1/12_troubleshooting/) | 4 | 0 |
| Обсуждение результатов тестов, ответы на вопросы | 4 | 0 |
| [final_exam](./module1/final_exam/) | 4 | 4 |
Время начала занятий: 18:00
| Дата | Темя занятия | Количество рабочих часов в офисе | Количество рабочих часов вне офиса |
|------|--------------------------------------------------|----------------------------------|------------------------------------|
| 2.10.2023 | [00_os_installation](./module1/00_os_installation/) | 4 | 0 |
| 3.10.2023 | [01_bash](./module1/01_bash/) | 4 | 0 |
| 4.10.2023 | [02_data_editing_and_analysis](./module1/02_data_editing_and_analysis/) | 4 | 0 |
| 5.10.2023 | [03_networking](./module1/03_networking/) | 4 | 0 |
| 6.10.2023 | [04_systemd](./module1/04_systemd/) | 4 | 0 |
| 9.10.2023 | [05_hash_ciphers_ssh_certs](./module1/05_hash_ciphers_ssh_certs/) | 4 | 0 |
| 10.10.2023 | [06_user_management](./module1/06_user_management/) | 4 | 0 |
| 11.10.2023 | [07_file_permissions](./module1/07_file_permissions/) | 4 | 0 |
| 12.10.2023 | [08_debian_package_management](./module1/08_debian_package_management/) | 4 | 0 |
| 13.10.2023 | [09_nginx](./module1/09_nginx/) | 4 | 0 |
| 16.10.2023 | [10_bash_scripts](./module1/10_bash_scripts/) | 4 | 0 |
| 17.10.2023 | [11_cron_at](./module1/11_cron_at/) | 4 | 0 |
| 18.10.2023 | [12_troubleshooting](./module1/12_troubleshooting/) | 4 | 0 |
| 19.10.2023 | Обсуждение результатов тестов, ответы на вопросы | 4 | 0 |
| 20.10.2023 | [final_exam](./module1/final_exam/) | 4 | 4 |
## Модуль 2
Расписание занятий в офисе: 3 раза в неделю --- пн, ср, пт
Время начала занятий: 17:00
| Темя занятия | Количество рабочих часов в офисе | Количество рабочих часов вне офиса |
|--------------------------------------------------|----------------------------------|------------------------------------|
| [00_bootloader](./module2/00_bootloader/) | 4 | 0 |
| [01_partitions_raid_lvm_fs](./module2/01_partitions_raid_lvm_fs/) | 4 | 4 |
| [02_mac_selinux](./module2/02_mac_selinux/) | 4 | 16 |
| [03_nginx_ha](./module2/03_nginx_ha/) | 4 | 16 |
| [04_postfix_dovecot](./module2/04_postfix_dovecot/) | 4 | 16 |
| [05_sql_postgresql](./module2/05_sql_postgresql/) | 4 | 0 |
| [06_virtualization](./module2/06_virtualization/) | 4 | 16 |
| [07_docker_containerization_basics](./module2/07_docker_containerization_basics/) | 4 | 8 |
| [08_docker_containerization_advanced](./module2/08_docker_containerization_advanced/) | 4 | 16 |
| [09_ansible](./module2/09_ansible/) | 4 | 8 |
| [10_monitoring_basics](./module2/10_monitoring_basics/) | 4 | 8 |
| Обсуждение результатов тестов, ответы на вопросы | 4 | 0 |
| [final_exam](./module2/final_exam/) | 4 | 8 |
Расписание занятий в офисе: 3 раза в неделю --- пн, ср, пт
Время начала занятий: 18:00
| Дата | Темя занятия | Количество рабочих часов в офисе | Количество рабочих часов вне офиса |
|------|--------------------------------------------------|----------------------------------|------------------------------------|
| 25.10.2023 | [00_bootloader](./module2/00_bootloader/) | 4 | 0 |
| 27.10.2023 | [01_partitions_raid_lvm_fs](./module2/01_partitions_raid_lvm_fs/) | 4 | 4 |
| 30.10.2023 | [02_mac_selinux](./module2/02_mac_selinux/) | 4 | 16 |
| 1.11.2023 | [03_nginx_ha](./module2/03_nginx_ha/) | 4 | 16 |
| 3.11.2023 | [04_postfix_dovecot](./module2/04_postfix_dovecot/) | 4 | 16 |
| 8.11.2023 | [05_sql_postgresql](./module2/05_sql_postgresql/) | 4 | 0 |
| 10.11.2023 | [06_virtualization](./module2/06_virtualization/) | 4 | 16 |
| 13.11.2023 | [07_docker_containerization_basics](./module2/07_docker_containerization_basics/) | 4 | 8 |
| 15.11.2023 | [08_docker_containerization_advanced](./module2/08_docker_containerization_advanced/) | 4 | 16 |
| 17.11.2023 | [09_ansible](./module2/09_ansible/) | 4 | 8 |
| 20.11.2023 | [10_monitoring_basics](./module2/10_monitoring_basics/) | 4 | 8 |
| 22.11.2023 | Обсуждение результатов тестов, ответы на вопросы | 4 | 0 |
| 24.11.2023 | [final_exam](./module2/final_exam/) | 4 | 8 |
Loading…
Cancel
Save