- CTSS (1962), Multics file system (1965), Titan file system (1972), Unix (1974)
4. CTSS (1962), Multics file system (1965), Titan file system (1972), Unix (1974)
- THE (1968), RC 4000 (1969), Venus (1972), Boss 2 (1975), Solo (1976)
5. THE (1968), RC 4000 (1969), Venus (1972), Boss 2 (1975), Solo (1976)
- OS 6 (1972), Alto (1979), Pilot (1980), Star user interface (1982)
6. OS 6 (1972), Alto (1979), Pilot (1980), Star user interface (1982)
- WFS file server (1979), Unix United (1982), Amoeba (1990)
7. WFS file server (1979), Unix United (1982), Amoeba (1990)
## 1 Open shop
## 1 Open shop
Можно сказать, что история операционных систем начинается в 1954 году, когда у первых серийных компьютеров ещё не было операционных систем. Тогда пользователи управляли ими вручную. Доступ к компьютерам был организован поочереди в стиле open shop.
Можно сказать, что история операционных систем начинается в 1954 году, когда у первых серийных компьютеров ещё не было операционных систем. Тогда пользователи управляли ими вручную. Доступ к компьютерам был организован поочереди в стиле open shop.
Операторы первых серийных компьютеров 701 были предшествениками современных системных администраторов. Группа по обмену информацией между ними SHARE существует до сих пор. В эру системных операторов компьютер был инструментом специального назначения, наподобие пилы. Переход от системных операторов к системному администратору начался тогда, когда компьютеры превратились в универсальные инструменты.
Сразу стало очевидным, что open shop организация приводит к большому времени простоя процессора. Джордж Рикман вспомнил о вопиющей неэффективности эксплуатации первого компьютера IBM, знаменитого 701: "Каждому пользователю был выделен 15-минутный интервал, из которых обычно он тратил 10 минут на настройку оборудования для выполнения своих вычислений. К тому времени, когда он начинал свои вычисления, для них оставалось только 5 минут или меньше - трата две трети его временного интервала."
Сразу стало очевидным, что open shop организация приводит к большому времени простоя процессора. Джордж Рикман вспомнил о вопиющей неэффективности эксплуатации первого компьютера IBM, знаменитого 701: "Каждому пользователю был выделен 15-минутный интервал, из которых обычно он тратил 10 минут на настройку оборудования для выполнения своих вычислений. К тому времени, когда он начинал свои вычисления, для них оставалось только 5 минут или меньше - трата две трети его временного интервала."
Джон Маккарти (1962) сделал аналогичное замечание о компьютере TX-0, который использовался в режиме открытого магазина в Массачусетском технологическом институте. Он добавил: "Если бы TX-0 был компьютером гораздо большего размера и если бы он работал так же, как сейчас, количество пользователей, которых он обслуживал было бы примерно таким же."
Джон Маккарти (1962) сделал аналогичное замечание о компьютере TX-0, который использовался в режиме открытого магазина в Массачусетском технологическом институте. Он добавил: "Если бы TX-0 был компьютером гораздо большего размера и если бы он работал так же, как сейчас, количество пользователей, которых он обслуживал было бы примерно таким же."
@ -40,9 +42,9 @@
Теперь процессорное время тратилось эффективно, его не нужно был запускать во время подготовки программ. Чем длиннее были ленты, тем меньше простаивал главный компьютер. Но большие серии задач значительно увеличили время выполнения с точки зрения пользователей. Обычно требуется несколько часов (или даже день или два), прежде чем они могли получить результаты одного задания. Если задание включало компиляцию программы, единственным выходом в этот день могло быть сообщение об ошибке, вызванное неуместной точкой с запятой.
Теперь процессорное время тратилось эффективно, его не нужно был запускать во время подготовки программ. Чем длиннее были ленты, тем меньше простаивал главный компьютер. Но большие серии задач значительно увеличили время выполнения с точки зрения пользователей. Обычно требуется несколько часов (или даже день или два), прежде чем они могли получить результаты одного задания. Если задание включало компиляцию программы, единственным выходом в этот день могло быть сообщение об ошибке, вызванное неуместной точкой с запятой.
## 3 Multiprogramming (асинхронный ввод/вывод)
## 3 Multiprogramming/Многозадачность
В 1960-х годах большая основная память, вторичное хранилище с произвольным доступом, каналы данных и аппаратные прерывания радикально изменили операционные системы. Прерывания позволяли процессору имитировать одновременное выполнение нескольких программ и управлять одновременными операциями ввода/вывода. Эта форма параллелизма стала известна как мультипрограммирование.
В 1960-х годах большая основная память, вторичное хранилище с произвольным доступом, каналы данных и аппаратные прерывания радикально изменили операционные системы. Прерывания позволяли процессору имитировать одновременное выполнение нескольких программ и управлять одновременными операциями ввода/вывода. Эта форма параллелизма стала известна как мультипрограммирование (многозадачность).
Мультипрограммирование и вторичное хранилище сделали возможным создание операционных систем, которые обрабатывали непрерывный поток ввода, вычислений и вывода на одном компьютере, используя барабаны (или диски) для хранения больших буферов. Такая схема называлась спулингом/подкачка (Spooling - это акроним “Simultaneous Peripheral Operation On-Line.). Барабаны были удобнее лент, так как заполнялись с одной стороны устройство чтения перфокарт, ас другой считывались основным процессором. Больше не было накладных расходов на монтирование ленты (если только пользовательские программы не обрабатывали свои собственные ленты данных). Большие буферы произвольного доступа позволили использовать приоритетное планирование заданий, например, «кратчайшее задание — следующее» (вместо «первым пришел — первым обслужен»).
Мультипрограммирование и вторичное хранилище сделали возможным создание операционных систем, которые обрабатывали непрерывный поток ввода, вычислений и вывода на одном компьютере, используя барабаны (или диски) для хранения больших буферов. Такая схема называлась спулингом/подкачка (Spooling - это акроним “Simultaneous Peripheral Operation On-Line.). Барабаны были удобнее лент, так как заполнялись с одной стороны устройство чтения перфокарт, ас другой считывались основным процессором. Больше не было накладных расходов на монтирование ленты (если только пользовательские программы не обрабатывали свои собственные ленты данных). Большие буферы произвольного доступа позволили использовать приоритетное планирование заданий, например, «кратчайшее задание — следующее» (вместо «первым пришел — первым обслужен»).
@ -58,9 +60,7 @@
Atlas был организован так, чтобы защитить пользовательские программы и системные вызовы друг от друга.
Atlas был организован так, чтобы защитить пользовательские программы и системные вызовы друг от друга.
## 4 Timesharing
## 4 Timesharing/Разделение времени
Операторы первых серийных компьютеров 701 были предшествениками современных системных администраторов. Группа по обмену информацией между ними SHARE существует до сих пор. В эру системных операторов компьютер был инструментом специального назначения, наподобие пилы. Переход от системных операторов к системному администратору начался тогда, когда компьютеры превратились в универсальные инструменты.
В 1962 году Джон МакКарти написал следующее:
В 1962 году Джон МакКарти написал следующее:
@ -68,17 +68,19 @@ Atlas был организован так, чтобы защитить поль
Поскольку программы могут выполнять только относительно короткие фрагменты работы между взаимодействиями с людьми, неэкономично постоянно перемещать их туда и обратно во вторичное хранилище. Следовательно, существует потребность в большой первичной памяти. Последнее требование заключается в том, чтобы вторичное хранилище было достаточно большим для хранения пользовательских файлов, чтобы пользователям не приходилось иметь отдельные карты или ленточные устройства ввода-вывода."
Поскольку программы могут выполнять только относительно короткие фрагменты работы между взаимодействиями с людьми, неэкономично постоянно перемещать их туда и обратно во вторичное хранилище. Следовательно, существует потребность в большой первичной памяти. Последнее требование заключается в том, чтобы вторичное хранилище было достаточно большим для хранения пользовательских файлов, чтобы пользователям не приходилось иметь отдельные карты или ленточные устройства ввода-вывода."
Разделение времени значительно снизило цену предоставления вычислительных мощностей.
CTSS 1965 и Multics 1969 были первыми реализациями этой идеи. Также современным ОС от них досталась технология иерархичной файловой системы для вторичного хранилища.
CTSS 1965 и Multics 1969 были первыми реализациями этой идеи. Также современным ОС от них досталась технология иерархичной файловой системы для вторичного хранилища.
*Посмотреть MULTICS https://www.youtube.com/watch?v=q0yfhZB7VpA или подключиться к menu@tty.livingcomputers.org*
*Посмотреть 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*
*Включить AT&T Archives: The UNIX Operating System https://www.youtube.com/watch?v=tc4ROCJYbm0*
Примерно в это время системное администрирование стало формироваться как профессия. Считается что такие учебные заведения, как Университет Пердью, Унивеситет штата Нью-Йорк (SUNY) в г. Буффало, Университет штатов [Колорадо, Юта, Мэриленд] стали рассадниками этих специалистов. Это были как сейчас говорят эникейщики, ангелы-хранители компьютеров и их пользователей, готовые починить лазерный принтер, помочь студенту отладить новый драйвер, записать данные на архивные ленты, уговорить пользователей почистить персональные каталоги, чтобы освободить место, найти запчасти по всей стране.
Примерно в это время системное администрирование стало формироваться как профессия. Считается что такие учебные заведения, как Университет Пердью, Унивеситет штата Нью-Йорк (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/`).
Спохватившись, AT&T начала судебный процесс, заявив о копировании кода и краже производственных секретов. В результате судебного разбирательства в течение двух лет из кода BSD было удалено три файла из более 18000. К сожалению, это период неопределённости оказал негативное влияние на весь мир UNIX.
Спохватившись, AT&T начала судебный процесс, заявив о копировании кода и краже производственных секретов. В результате судебного разбирательства в течение двух лет из кода BSD было удалено три файла из более 18000. К сожалению, это период неопределённости оказал негативное влияние на весь мир UNIX.
В 1987 Танненбаум выпустил небольшой клон системы UNIX - MINIX под лицензией, разрешающий использование только в образовательных целях. Желая получить свободно распространяемую версию UNIX, финский студент Линус Торвальдс написал собтвенную макроядерную систему-клон Linux. Так началась эра Linux.
В 1987 Танненбаум выпустил небольшой клон системы UNIX - MINIX под лицензией, разрешающий использование только в образовательных целях. Желая получить свободно распространяемую версию UNIX, финский студент Линус Торвальдс написал собственную микроядерную систему-клон Linux. Так началась эра Linux.
За это время компьютеры ушли от вида специализированных устройств, проводящих расчёты военного назначения, к универсальным машинам для обработки данных. Это не могло стать возможным без эволюции операционных систем. Администрирование этих систем сформировалось как профессия.
За это время компьютеры ушли от вида специализированных устройств, проводящих расчёты военного назначения, к универсальным машинам для обработки данных. Это не могло стать возможным без эволюции операционных систем. Администрирование этих систем сформировалось как профессия.
# Архитектура ОС
# Архитектура ОС
Наверное к этому моменту у вас уже сложилось представление о том, что такое операционная система. Можно дать два определения ОС. С одной стороны, операционная система - это интерфейс между hardware и software, слой абстракции для прикладных программ и аппаратного обеспечения. С другой стороны, операционная система - это менеджер ресурсов.
Наверное к этому моменту у вас уже сложилось представление о том, что такое операционная система. Можно дать два определения ОС. С одной стороны, операционная система - это интерфейс между hardware и software, слой абстракции для прикладных программ и аппаратного обеспечения. С другой стороны, операционная система - это менеджер ресурсов.
Вы в директории `/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
3 cd /home/stud
5 cd ~
5 cd ~
@ -9,8 +29,20 @@
8 cd
8 cd
9 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
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
## 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`. Напишите команды в двух вариантах: с относительными путями и с абсолютными и проверьте, что их выполнение даёт одинаковый результат.
Посчитайте количество строк в файле /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
## 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`.
Создайте псевдоним "dc", который разрешается в команду "cd" для случаев опечатки.
Постройте конвейр с помощью оператора `|`, который считывает содержимое `/var/log/dpkg.log`, находит только строки содержащие слово `perl`, сохраняет результат в файл `/tmp/perl_pkgs` и одновременно выводит в консоль количество найденных строк.
Выполните две команды: `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` команду, которая выводит список файлов в следующем виде:
Прочитайте мануал `man ls` и напишите `ls` команду, которая выводит список файлов в следующем виде:
* список файлов включает скрытые,
* список файлов включает скрытые,
@ -97,16 +122,57 @@ alias dc=”cd”
ls -caht или ls -cahtl
ls -caht или ls -cahtl
```
```
## 10
## 13
Запишите в переменную среды PATH значение "". Как это повлияло на выполнение команд? Перезайдите по ssh и попробуйте вызывать любую команду заново. Сохранились ли изменения?
Попробуйте вывести содержимое переменной среды `HOME`с помощью `echo` в одинарных и двойных кавычках. В чём разница?
```
echo "$HOME"
echo '$HOME'
```
Разница в том, что выражения внутри двойных кавычек интерпретируются, а в одинарных нет. В первом случае выведется значение переменной HOME, во втором `$HOME`.
## 14
Запишите в переменную среды `PATH` значение `""`. Как это повлияло на выполнение команд? Перелогиньтесь и попробуйте вызывать любую команду заново. Сохранилиcь ли изменения?
Первое слово в консоли интерпретируется как вызов исполняемого файла, функции или псевдонима. Поиск исполняемых файлов с переданным названием ведётся в директориях, перечисленных через `:` в переменной среды PATH. Поэтому при пустом списке ни один исполняемый файл не будет найден.
```
```
export PATH=””
export PATH=””
следствие: ни один исполняемый файл системой теперь не находится
следствие: ни один исполняемый файл системой теперь не находится
после переподключения система вернулась в прежнее состояние
после переподключения система вернулась в прежнее состояние
```
```
## 11
## 15
Модифицируйте команду так, чтобы у директорий в начале названия присутствовал глобальный индекс idx.
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;
idx=0;
for species in cubane ethane methane;
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
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
(*) Напишите команду или сценарий для рекурсивного поиска самого последнего измененного файла в каталоге. В общем, можете ли вы перечислить все файлы по давности?
(*) Напишите команду или сценарий для рекурсивного поиска самого последнего измененного файла в каталоге. В общем, можете ли вы перечислить все файлы по давности?
%T+ - время последнего изменения в формате 2004-04-28+22:22:05.0,
%T+ - время последнего изменения в формате 2004-04-28+22:22:05.0,
%H - путь к директории, в которой файл найден,
%H - путь к директории, в которой файл найден,
%P - имя файла.
%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
[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
Сеть содержит физические провода или радиоволны, устройства соединения, такие как коммутаторы, логические протоколы, такие как 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 Физический
### 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 Канальный
### 2 Канальный
@ -38,14 +37,24 @@
Если вы используете протокол IPv4, то на канальном уровне используются адреса Media Access Control (MAC) и протокол разрешения адресов (ARP). В IPv6 используются MAC-адреса и протокол Neighbor Discovery (ND). Если у вас возникли проблемы с обменом данными с локальной сетью, обратитесь к этим главам и проверьте наличие проблем с ARP или ND.
Если вы используете протокол 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 Сетевой
### 3 Сетевой
Не является ли все это сетью? Да, но сетевой уровень отображает возможности соединения между хостами. Именно здесь система отвечает на вопросы типа "Как мне добраться до этого другого хоста? Могу ли я попасть на этот другой хост?". Сетевой уровень обеспечивает согласованный интерфейс для сетевых программ, чтобы они могли использовать сеть на любом физическом и канальном уровнях. Отдельный фрагмент сетевых данных называется пакетом.
Не является ли все это сетью? Да, но сетевой уровень отражает возможность соединения между хостами. Именно здесь система отвечает на вопросы типа "Как мне добраться до другого хоста? Могу ли я попасть на другой хост?". Сетевой уровень обеспечивает согласованный интерфейс для сетевых программ, чтобы они могли использовать сеть на любом физическом и канальном уровнях. Отдельный фрагмент сетевых данных называется пакетом.
В Интернете используется протокол Internet Protocol, или IP. Это IP в TCP/IP. Во всех версиях IP каждому узлу присваивается один или несколько уникальных IP-адресов, чтобы любой другой узел в сети мог его найти. Трансляция сетевых адресов (NAT) изменяет правило "уникального адреса", но где-то в вашей сети или в сети вашего провайдера у вас есть глобально уникальный IP-адрес.
В Интернете используется протокол Internet Protocol, или IP. Это IP в TCP/IP. Во всех версиях IP каждому узлу присваивается один или несколько уникальных IP-адресов, чтобы любой другой узел в сети мог его найти. Трансляция сетевых адресов (NAT) изменяет правило "уникального адреса", но где-то в вашей сети или в сети вашего провайдера у вас есть глобально уникальный IP-адрес.
Мы рассмотрим подробно далее только версию 4.
Мы рассмотрим подробно далее только версию 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 Транспортный
### 4 Транспортный
Данные, о которых вы заботитесь, передаются на транспортном уровне. Нижние уровни стека существуют для поддержки транспортного уровня. Фрагмент данных транспортного уровня - это сегмент. Три наиболее распространенных протокола транспортного уровня - это протокол управляющих сообщений Интернета (ICMP), протокол управления передачей (TCP) и протокол пользовательских датаграмм (UDP).
Данные, о которых вы заботитесь, передаются на транспортном уровне. Нижние уровни стека существуют для поддержки транспортного уровня. Фрагмент данных транспортного уровня - это сегмент. Три наиболее распространенных протокола транспортного уровня - это протокол управляющих сообщений Интернета (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.
UDP и TCP обеспечивают передачу прикладных данных между узлами. Они настолько распространены, что набор протоколов Интернета обычно называют TCP/IP. (UDP/TCP/IP слишком громоздки.) UDP, или User Datagram Protocol, предоставляет минимальные услуги, необходимые для передачи данных по сети. Хотя люди шутят, что U в UDP означает "ненадежный", он предназначен для приложений, где надежность обеспечивается приложением, а не сетью. Протокол TCP, или Transmission Control Protocol, включает в себя проверку ошибок, управление перегрузками и повторную передачу потерянных данных, но ему не хватает гибкости и простоты UDP.
[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)
В заголовке перечислены их названия согласно теоретической модели ОСИ. Сессионный уровень отвечает за открытие, использование и закрытие соединений транспортного уровня. Уровень представления отвечает за обмен данными между приложениями. На уровне приложения работает протокол передачи данных приложения. На практике всё зависит от поставщика приложения, который может реализовать чёткое разделение ответственности по слоям или смешать всё воедино.
Примерами протоколов высших слоёв являются: HTTP, SMTP, LDAP.
В заголовке перечислены их названия согласно теоретической модели ОСИ. Сессионный уровень отвечает за открытие, использование и закрытие соединений транспортного уровня. Уровень представления отвечает за обмен данными между приложениями. На уровне приложения работает протокол передачи данных приложения. На практике всё зависит от поставщика приложения, который может реализовать чёткое разделение ответственности по слоям или смешать всё воедино.
Примерами протоколов высших слоёв являются: `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 с топологией сети изображённой ниже. Рёбра этого графа - провода, а узлы - компьютеры или роутеры. Это также пример автономной системы, например автономная система провайдера. Автономная система - группа сетей, находящихся под административным или политическим контролем одного юридического лица.
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 заполняется единицами.
Чтобы отправить 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 |
При запросе поле "Hardware Address of Target" заполняется нулями, а в ARP ответе хост A получит "68:56:35:8e:5b:74". Получив ответ, хост A с этого момента может отправлять ip пакеты шлюзу для его дальнейшей маршрутизации.
ICMP пакет будет вложен в IP пакет, который будет вложен в Ethernet пакет. Однако это не значит, что размер IP пакета должен быть меньше Ethernet пакета. В случае превышения MTU (размера Ethernet пакета), IP пакет будет фрагментирован на несколько Ethernet пакетов.
Задача сетевого уровня обеспечить маршрутизацию пакета от компьютера одной локальной сети до компьютера другой не зависимо от технологий, используемых в локальных сетях. Для этого компьютерам назначается глобальный 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)
Для передачи пользовательских нужно подняться на один уровень выше, на транспортный уровень, до протоколов 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.
Поддержание TCP-соединения требует запоминания нескольких переменных. Эти переменные хранятся в записи соединения, называемой блоком управления передачей или TCB.
Администратор может назначить их вручную или автоматически с помощью DHCP.
DHCP предназначен для предоставления DHCP-клиентам параметров конфигурации, определенных в RFC «Требования к хосту». После получения параметров через DHCP клиент DHCP должен иметь возможность обмениваться пакетами с любым другим хостом в Интернете.
DHCP состоит из двух компонентов: протокола для доставки специфичных для хоста параметров конфигурации от DHCP-сервера к хосту и механизма выделения сетевых адресов хостам.
Временная диаграмма автоматического получения IP адреса.
Основная функция 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/.
Для виртуальных машин `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` запущен и в его логах нет ошибок.
На машине `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` на ошибки.
Для виртуальных машин `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
# Задание 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
# Задание 3
На машине `studX-1vX` настройте доступ в интернет. Внастройках Hardware измените Network Device на `vmbr499`, перейдя таким образом в другую `vlan`. Вкачестве шлюза используйте адрес `10.160.179.1`. В качестве адреса возьмите `10.160.179.200`, прибавив `X` к последнему октету.
На машине `studX-net1` настройте доступ в интернет. В качестве шлюза используйте адрес `192.168.0.1`.
# Задание 4
# Задание 4
Настройте DNS сервер на виртуальной машине `studX-net1`. Пример адреса DNS - `1.1.1.1`.
# Задание 5
Запустите прослушивание пакетов на некоторое время в сети на одной из машин командой tcpdump. Какие типы пакетов вы перехватили? Отфильтруйте ARP пакеты, ICMP пакеты, TCP пакеты.
Запустите прослушивание пакетов на некоторое время в сети на одной из машин командой tcpdump. Какие типы пакетов вы перехватили? Отфильтруйте ARP пакеты, ICMP пакеты, TCP пакеты.
0. Если у вас есть машина с графической оболочкой, в консоли перейдите в уровень запуска multi-user.target без перезагрузки, а затем обратно graphical.target.
1. Если у вас есть машина с графической оболочкой, в консоли перейдите в уровень запуска `multi-user.target` без перезагрузки, а затем обратно `graphical.target`.
```
```
# systemctl isolate multi-user.target
# systemctl isolate multi-user.target
# systemctl isolate graphical.target
# systemctl isolate graphical.target
```
```
1. Если у вас есть машина с графической оболочкой, перейдите в уровень запуска multi-user.target с перезагрузкой, а затем переключитесь в графическую оболочку обратно.
2. Если у вас есть машина с графической оболочкой, перейдите в уровень запуска `multi-user.target`с перезагрузкой, а затем переключитесь в графическую оболочку обратно.
```
```
# systemctl set-default multi-user.target
# systemctl set-default multi-user.target
# reboot
# reboot
@ -15,17 +15,17 @@
# reboot
# reboot
```
```
2. Выведите модуль, который активируется по-умолчанию.
3. Выведите модуль, который активируется по-умолчанию.
```
```
# systemctl get-default
# systemctl get-default
```
```
3. Выведите возможные состояния модулей командой systemctl --state=help.
4. Выведите возможные состояния модулей командой `systemctl --state=help`.
```
```
# systemctl --state=help
# systemctl --state=help
```
```
4. Найдите в man странице какие типы модулей есть в systemd.
5. Найдите в man странице какие типы модулей есть в `systemd`.
```
```
# man systemctl
# man systemctl
The following unit types are available:
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).
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
# systemctl list-unit-files
```
```
6. Деактивируйте сервис timesyncd.
7. Деактивируйте сервис `systemd-timesyncd`.
```
```
# systemctl disable systemd-timesyncd
# systemctl disable systemd-timesyncd
```
```
7. Перезагрузите сервис timesyncd.
8. Перезагрузите сервис `systemd-timesyncd`.
```
```
# systemctl restart systemd-timesyncd
# systemctl restart systemd-timesyncd
```
```
8. Выведите список модулей в памяти.
9. Выведите список модулей в памяти.
```
```
# systemctl disable systemd-timesyncd
# systemctl disable systemd-timesyncd
```
```
9. Проверьте, что сервис timesyncd активирован.
10. Проверьте, что сервис `systemd-timesyncd` активирован.
```
```
# systemctl is-enabled systemd-timesyncd
# systemctl is-enabled systemd-timesyncd
```
```
10. Выведите список зависимых модулей для сервиса timesyncd.
11. Выведите список зависимых модулей для сервиса `systemd-timesyncd`.
```
```
# systemctl list-dependencies systemd-timesyncd
# systemctl list-dependencies systemd-timesyncd
```
```
11. Выведите список сокетов в памяти.
12. Выведите список сокетов в памяти.
```
```
# systemctl list-sockets
# systemctl list-sockets
```
```
12. Выведите список таймеров в памяти.
13. Выведите список таймеров в памяти.
```
```
# systemctl list-timers
# systemctl list-timers
```
```
13. Проверьте статус сервиса timesyncd.
14. Проверьте статус сервиса `systemd-timesyncd`.
```
```
# systemctl status systemd-timesyncd
# systemctl status systemd-timesyncd
```
```
14. Проверьте, что сервис timesyncd активен.
15. Проверьте, что сервис `systemd-timesyncd` активен.
```
```
# systemctl is-active systemd-timesyncd
# systemctl is-active systemd-timesyncd
```
```
15. Выведите список свойств модуля.
16. Выведите список свойств модуля.
```
```
# systemctl show systemd-timesyncd
# systemctl show systemd-timesyncd
```
```
16. Выведите уровень логирования для сервиса timesyncd.
17. Выведите уровень логирования для сервиса `systemd-timesyncd`.
```
```
# systemctl service-log-level systemd-timesyncd
# systemctl service-log-level systemd-timesyncd
```
```
17. Перезагрузите конфигурацию systemd менеджера: перезапустите генераторы (systemd.generator), все модули и перестройте дерево зависимостей.
18. Перезагрузите конфигурацию systemd менеджера: перезапустите генераторы (systemd.generator), все модули и перестройте дерево зависимостей.
```
```
# systemctl daemon-reload
# systemctl daemon-reload
```
```
18. Какие префиксы можно использовать при указании исполняемых файлов в файлах .service.
19. Какие префиксы можно использовать при указании исполняемых файлов в файлах .service.
```
```
# man systemd.service
# man systemd.service
Table 1. Special executable prefixes
Table 1. Special executable prefixes
@ -195,7 +195,7 @@ Table 1. Special executable prefixes
5. Определите свой внешний IP адрес на сайте https://2ip.ru/,
5. Определите свой внешний IP адрес на сайте http://2ip.ru/, предварительно настроив в firefox плагине foxyproxy прокси сервер socks5 с адресом 193.32.63.170 + X к последнему октету, где X ваш идентификатор из studX.
предварительно настроив в firefox плагине foxyproxy прокси сервер socks5
с адресом 193.32.63.170 + X к последнему октету, где X идентификатор stud.
0. Если у вас есть машина с графической оболочкой, в консоли перейдите в уровень запуска multi-user.target без перезагрузки, а затем обратно graphical.target.
0. Установите Debian с графической оболочкой и загрузитесь в неё.
1. Если у вас есть машина с графической оболочкой, перейдите в уровень запуска multi-user.target с перезагрузкой, а затем переключитесь в графическую оболочку обратно.
1. В консоли перейдите в уровень запуска `multi-user.target` без перезагрузки, а затем обратно `graphical.target`.
2. Выведите модуль, который активируется по-умолчанию.
2. Перейдите в уровень запуска `multi-user.target`с перезагрузкой, а затем переключитесь в графическую оболочку обратно.
3. Выведите возможные состояния модулей командой systemctl --state=help.
3. Выведите модуль, который активируется по-умолчанию.
4. Найдите в man странице какие типы модулей есть в systemd.
4. Выведите возможные состояния модулей командой `systemctl --state=help`.
5. Выведите список установленных модулей.
5. Найдите в man странице какие типы модулей есть в `systemd`.
6. Деактивируйте сервис timesyncd.
6. Выведите список установленных модулей.
7. Перезагрузите сервис timesyncd.
7. Деактивируйте сервис `timesyncd`.
8. Выведите список модулей в памяти.
8. Перезагрузите сервис `timesyncd`.
9. Проверьте, что сервис timesyncd активирован.
9. Выведите список модулей в памяти.
10. Выведите список зависимых модулей для сервиса timesyncd.
10. Проверьте, что сервис `timesyncd` активирован.
11. Выведите список сокетов в памяти.
11. Выведите список зависимых модулей для сервиса `timesyncd`.
12. Выведите список таймеров в памяти.
12. Выведите список сокетов в памяти.
13. Проверьте статус сервиса timesyncd.
13. Выведите список таймеров в памяти.
14. Проверьте, что сервис timesyncd активен.
14. Проверьте статус сервиса `timesyncd`.
15. Выведите список свойств модуля.
15. Проверьте, что сервис `timesyncd` активен.
16. Выведите уровень логирования для сервиса timesyncd.
16. Выведите список свойств модуля.
17. Перезагрузите конфигурацию systemd менеджера: перезапустите генераторы (systemd.generator), все модули и перестройте дерево зависимостей.
17. Выведите уровень логирования для сервиса `timesyncd`.
18. Какие префиксы можно использовать при указании исполняемых файлов в файлах .service.
18. Перезагрузите конфигурацию systemd менеджера: перезапустите генераторы (`systemd.generator`), все модули и перестройте дерево зависимостей.
19. Какие префиксы можно использовать при указании исполняемых файлов в файлах `.service`.
### Задание 2. Конфигурация сервиса
### Задание 2. Конфигурация сервиса
Сконфигурировать socks прокси сервис, который:
Сконфигурировать `socks` прокси сервис, который:
* вызывает команду 'ssh -N -D 0.0.0.0:80 localhost',
* вызывает команду `ssh -N -D 0.0.0.0:80 localhost`,
* запускается после network.target,
* запускается после `network.target`,
* всегда перезагружается при завершении, но не чаще, чем 1 раз в 5 секунд,
* всегда перезагружается при завершении, но не чаще, чем 1 раз в 5 секунд,
* запуск необходим при уровне multi-user.target.
* запуск проивзодится на уровне `multi-user.target`.
Проверьте работу прокси сервиса из браузера с помощью плагина foxyproxy.
Проверьте работу прокси сервиса из браузера с помощью плагина `foxyproxy`.
Попробуйте подключиться ещё раз. Попробуйте подключиться ещё раз по паролю (добавьте флаг -o PubkeyAuthentication=no к ssh команде).
Попробуйте подключиться ещё раз. Попробуйте подключиться ещё раз по паролю (добавьте флаг `-o PubkeyAuthentication=no` к ssh команде).
### 8.
### 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`.
Создайте папку `projects` в корне системы с правами `rwx` для владельца, группы и других пользователей. Установите на неё `stickybit`.
```
sudo mkdir /projects -m 1777
```
### 2.
Работая от пользователя `stud` в папке `projects` создайте папку с вашим проектом. Проверьте, что владелец может записать файл в неё. Проверьте, что `mike` или `vera` могут прочитать содержимое, но не могу записать в неё.
В`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
Создайте третью и четвёртую папки от пользователя `mike` и `vera` в `/projects` и сделайте их полностью приватными. Добавьте в каждую директорию по одному файлу. Проверьте может ли `mike` или vera посмотреть содержимое чужого приватного проекта.
Проверьте может ли mike удалить папку с чужим проектом? Может ли он удалить свою папку? Уберите stickybit у папки /projects. А теперь может ли mike удалить папку, созданную vera или stud? Влияет ли на возможность удаления наличие в папке файлов?
От `root` cоздайте ещё одну общую директорию `shared` в `/home/`. Создайте группу `shared_files` c большим значением идентификатора, например 70000, в которую входят `mike`, `vera` и `stud`. Поменяйте владельца `/home/shared` на `nobody`, а владельца-группу на `shared_files`. Установите полные права доступа для владельца и группы владельца. Все остальным запретите доступ к папке. Также установите бит `SGID`.
drwxr-sr-x 2 vera shared_files 4096 окт 1 18:26 vera_data
```
### 7.
Узнайте значение `umask` одноимённой командой. Создайте папку и файл c именем `test_$(umask)`. Выведите атрибуты файла. Измените umask одноимённой командой на `0002`. Повторите создание папки и файла и сравните атрибуты файлов, созданных с разными масками.
Под `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`, сгенерируйте новый файл. Есть ли изменения в поле владельца?
В каталоге `/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` смогла найти строку только в папке с правами и на чтение и на исполнение.
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.
### 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.
### 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>
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.
### 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` файла.
Попробуйте вызвать исполняемый файл `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.
### 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.
### 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.
### 10.
Утилитой dpkg-query выведите статус пакета sudo и gcc. Чем выдача отличается от содержимого control файла .deb, скаченного ранее?
Утилитой `dpkg-query` выведите статус пакета `sudo` и `gcc`. Чем выдача отличается от содержимого `control` файла `.deb`, скаченного ранее?
[ "$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.
### 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.
### 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.
### 16.
Утилитой dpkg установите cmake .deb пакет, скачанный ранее. Ещё раз посмотрите на зависимости пакета. Как отреагировал dpkg на отсутствие зависимости cmake-data - установил или выдал ошибку?
Утилитой `dpkg` установите `cmake``.deb` пакет, скачанный ранее. Ещё раз посмотрите на зависимости пакета. Как отреагировал `dpkg` на отсутствие зависимости `cmake-data` - установил или выдал ошибку?
Пакет установился, но не сконфигурировался.
### 17.
### 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`.
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.
### 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.
### 19.
Сохраните список выбранных действий (selections) для пакетов в системе утилитой dpkg в файл.
Сохраните список выбранных действий (selections) для пакетов в системе утилитой `dpkg` в файл.
Измените в сохранённом списке действие для пакета vim c текущего на deinstall (`man dpkg`, “Package selection states”). Перечитайте изменённый список командой `dpkg --set-selections`.
Измените в сохранённом списке действие для пакета `vim` c текущего на deinstall (`man dpkg`, “Package selection states”). Перечитайте изменённый список командой `dpkg --set-selections`.
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.
### 22.
Настройте в `/etc/sudoers` конфигурационном файле для пользователя stud возможность выполнять команды от лица суперпользователя без запроса пароля:
Настройте в `/etc/sudoers` конфигурационном файле для пользователя `stud` возможность выполнять команды от лица суперпользователя без запроса пароля:
```
```
%sudo ALL=(ALL:ALL) NOPASSWD: ALL
%sudo ALL=(ALL:ALL) NOPASSWD: ALL
```
```
Удалите, а затем установите пакет sudo командой `apt remove`. Проверьте содержимое конфигурационного файла на изменения. Проделайте то же самое, но c командой `apt purge`.
Удалите, а затем установите пакет `sudo` командой `apt remove`. Проверьте содержимое конфигурационного файла на изменения. Проделайте то же самое, но c командой `apt purge`.
`apt purge` - удалит все конфигурационные файлы, даже если они были изменены администратором.
### 23.
### 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";
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.
### 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
Прочитайте README.md секцию "Building CMake from Scratch". Установите компилятор g++, make. Для поддержки openssl - libssl-dev заголовочные файлы. В качестве --prefix используйте `/opt/cmake/`. Выполните 3 этапа: конфигурация компиляции, компиляция проекта, и установка. Для использования многопоточной компиляции используйте флаг `-j` при вызове `make`.
Прочитайте 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.
### 27.
Используйте команду `dpkg-reconfigure`, чтобы перенастроить пакеты, связанные с локализацией `console-setup` и раскладкой клавиатуры `keyboard-configuration`.
Используйте команду `dpkg-reconfigure`, чтобы перенастроить пакеты, связанные с локализацией `console-setup` и раскладкой клавиатуры `keyboard-configuration`.
Обновите список пакетов из настроенных репозиториев в /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.
### 1.
Установите пакет apt-file с помощью apt.
Установите пакет `apt-file`с помощью `apt`.
### 2.
### 2.
Найдите с помощью apt-file пакет, содержащий команду ar.
Найдите с помощью `apt-file` пакет, содержащий команду `ar`.
### 3.
### 3.
Определите с помощью команды `apt search`, какие варианты пакета содержащего команду ar доступны. Установите подходящий для вашей системы.
Определите с помощью команды `apt search`, какие варианты пакета содержащего команду `ar` доступны. Установите подходящий для вашей системы.
### 4.
### 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.
### 5.
Создайте папку control и распакуйте в неё control.tar.xz с помощью команды `tar xfC путь-к-архиву control`. Изучите содержимое. Сравните с выдачей `dpkg --info ` для .deb файла.
Создайте папку `control` и распакуйте в неё `control.tar.xz`с помощью команды `tar xfC путь-к-архиву control`. Изучите содержимое. Сравните с выдачей `dpkg --info ` для `.deb` файла.
### 6.
### 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.
### 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.
### 8.
Утилитой dpkg-query выведите список пакетов, зарегистрированных в dpkg базе данных. Есть ли среди них зависимости cmake, которые вы установили вручную?
Утилитой `dpkg-query` выведите список пакетов, зарегистрированных в `dpkg` базе данных. Есть ли среди них зависимости `cmake`, которые вы установили вручную?
### 9.
### 9.
Утилитой dpkg-query выведите среди установленных локально пакетов пакет, начинающихся с‘libc6’. Утилитой apt-cache выполните тот же поиск по кэшу apt. Утилитой apt выполните тот же поиск по кэшу apt. Сравните, чем они отличаются.
Утилитой `dpkg-query` выведите среди установленных локально пакетов пакет, начинающихся с`‘libc6’`. Утилитой `apt-cache` выполните тот же поиск по кэшу `apt`. Утилитой `apt` выполните тот же поиск по кэшу `apt`. Сравните, чем они отличаются.
### 10.
### 10.
Утилитой dpkg-query выведите статус пакета sudo и gcc. Чем выдача отличается от содержимого control файла .deb, скаченного ранее?
Утилитой `dpkg-query` выведите статус пакета `sudo` и `gcc`. Чем выдача отличается от содержимого control файла `.deb`, скаченного ранее?
### 11.
### 11.
Утилитой dpkg-query выведите список установленных файлов пакета sudo (не выводятся файлы созданные скриптами).
Утилитой `dpkg-query` выведите список установленных файлов пакета `sudo` (не выводятся файлы созданные скриптами).
### 12.
### 12.
Утилитой dpkg-query выведите список файлов с метаданными пакета (control files), установленных в систему.
Утилитой `dpkg-query` выведите список файлов с метаданными пакета `sudo`(control files).
### 13.
### 13.
Утилитой dpkg-query выведите содержимое одного из файлов с метаданными пакета (control files).
Утилитой `dpkg-query` выведите содержимое одного из файлов с метаданными пакета`sudo` (control files).
### 14.
### 14.
Утилитой dpkg-query выведите пути к файлам с метаданными пакета (control files).
Утилитой `dpkg-query` выведите пути к файлам с метаданными пакета`sudo` (control files).
### 15.
### 15.
Утилитой dpkg-query выполните поиск пакетов, которые установили в систему файл pam.conf.
Утилитой `dpkg-query` выполните поиск пакетов, которые установили в систему файл `pam.conf`.
### 16.
### 16.
Утилитой dpkg установите cmake .deb пакет, скаченный ранее. Ещё раз посмотрите на зависимости пакета. Как отреагировал dpkg на отсутствие зависимости cmake-data - установил или выдал ошибку?
Утилитой `dpkg` установите `cmake .deb` пакет, скаченный ранее. Ещё раз посмотрите на зависимости пакета. Как отреагировал `dpkg` на отсутствие зависимости `cmake-data` - установил или выдал ошибку?
### 17.
### 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.
### 18.
Проверьте файлы всех установленных пакетов в системе на наличие изменений/повреждений командой dpkg. Какие файлы не прошли проверку (`??5??????`)?
Проверьте файлы всех установленных пакетов в системе на наличие изменений/повреждений командой `dpkg`. Какие файлы не прошли проверку (`??5??????`)?
Формат выдачи:
```
SM5DLUGT c <file>
```
где
- S размер файла,
- M режим файла,
- 5 MD5 хэш файла,
- D мажорная и минорная версии файла,
- L содержимое символических ссылок файла,
- U владелец файла,
- G группа-владелец файла,
- T время модификации файла,
- c появляется только, если это конфигурационный файл. Как правило именно они меняются и с большей вероятностью не пройдут проверку.
- <file> полный путь к файлу, который не прошёл проверку.
Знак вопроса означает, что файл не может быть проверен по какой-то причине. Подробнее вы можете прочитать в мануале `man dpkg` в секции описывающей ключ `--verify-format`.
### 19.
### 19.
Сохраните список выбранных действий и состояний (selections) для пакетов в системе утилитой dpkg в файл.
Сохраните список выбранных действий и состояний (selections) для пакетов в системе утилитой `dpkg` в файл.
### 20.
### 20.
Измените в сохранённом списке действие для пакета vim c текущего на deinstall (`man dpkg`, “Package selection states”).
Измените в сохранённом списке действие для пакета vim c текущего на deinstall (`man dpkg`, “Package selection states”).
@ -69,31 +105,31 @@
Запустите команду `apt-get dselect-upgrade`. Какие пакеты будут установлены или удалены?
Запустите команду `apt-get dselect-upgrade`. Какие пакеты будут установлены или удалены?
### 22.
### 22.
Настройте в `/etc/sudoers` конфигурационном файле для пользователя stud возможность выполнять команды от лица суперпользователя без запроса пароля:
Настройте в `/etc/sudoers` конфигурационном файле для пользователя `stud` возможность выполнять команды от лица суперпользователя без запроса пароля:
```
```
%sudo ALL=(ALL:ALL) NOPASSWD: ALL
%sudo ALL=(ALL:ALL) NOPASSWD: ALL
```
```
Удалите, а затем установите пакет sudo командой `apt remove`. Проверьте содержимое конфигурационного файла на изменения. Проделайте то же самое, но c командой `apt purge`.
Удалите, а затем установите пакет sudo командой `apt remove`. Проверьте содержимое конфигурационного файла на изменения. Проделайте то же самое, но c командой `apt purge`.
### 23.
### 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";
APT::Default-Release "stable";
```
```
Повторите поиск. Установите stable версию. Проверьте работоспособность команды и её версию `cmake --version`. Вы можете узнать значения текущих конфигурационных переменных `apt` командой `apt-conf dump`.
Повторите поиск. Установите `stable` версию. Проверьте работоспособность команды и её версию `cmake --version`. Вы можете узнать значения текущих конфигурационных переменных `apt` командой `apt-conf dump`.
### 24.
### 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.
### 25.
Удалите cmake для следующего упражнения в установке из исходного кода. Выполните `apt autoremove` для удаления ставших ненужными пакетов.
Удалите cmake для следующего упражнения в установке из исходного кода. Выполните `apt autoremove` для удаления ставших ненужными пакетов.
### 26.
### 26.
Установите git, если он ещё не установлен. Перейдите в /tmp и вызовите:
Установите `git`, если он ещё не установлен. Перейдите в `/tmp` и вызовите:
Прочитайте README.md секцию "Building CMake from Scratch". Установите компилятор g++, make. Для поддержки openssl - libssl-dev заголовочные файлы. В качестве --prefix используйте `/opt/cmake/`. Выполните 3 этапа: конфигурация компиляции, компиляция проекта, и установка. Для использования многопоточной компиляции используйте флаг `-j` при вызове `make`.
Прочитайте README.md секцию "Building CMake from Scratch". Установите компилятор g++, make. Для поддержки openssl - libssl-dev заголовочные файлы. В качестве --prefix используйте `/opt/cmake/`. Выполните 3 этапа: конфигурация компиляции, компиляция проекта, и установка. Для использования многопоточной компиляции используйте флаг `-j` при вызове `make`.
Запустите исполняемый файл nginx. Проверьте, что он запустился `ps aux`.
Запустите исполняемый файл `nginx`. Проверьте, что он запустился `ps aux`.
```
```
$ sudo ps aux | grep nginx
$ sudo ps aux | grep nginx
```
```
### 3.
### 3.
После запуска nginx им можно управлять, вызывая исполняемый файл с параметром -s. Попробуйте команды:
После запуска `nginx` им можно управлять, вызывая исполняемый файл с параметром `-s`. Попробуйте команды:
- stop — быстрое выключение,
- `stop` — быстрое выключение,
- quit — завершение работы с ожиданием завершения обслуживания текущих запросов рабочими процессами,
- `quit` — завершение работы с ожиданием завершения обслуживания текущих запросов рабочими процессами,
- reload — перезагрузка файла конфигурации,
- `reload` — перезагрузка файла конфигурации,
- reopen — повторное открытие лог-файлов,
- `reopen` — повторное открытие лог-файлов,
используя следующий синтаксис:
используя следующий синтаксис:
```
```
$ nginx -s signal
$ nginx -s signal
```
```
Команда должна выполняться под тем же пользователем, который запустил nginx.
Команда должна выполняться под тем же пользователем, который запустил `nginx`.
```
```
$ sudo nginx -s reload
$ sudo nginx -s reload
$ sudo nginx -s reopen
$ sudo nginx -s reopen
@ -32,7 +32,7 @@ $ sudo nginx -s quit
```
```
### 4.
### 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`.
Завершите корректно работу nginx командой `kill -s QUIT`.
Проверьте, конфигурации на предмет синтаксических ошибок. Завершения строк `;`. Помочь сделать проверку может команда `nginx -t`.
Проверьте, конфигурации на предмет синтаксических ошибок. Завершения строк `;`. Помочь сделать проверку может команда `nginx -t`.
Проверьте, что сервис nginx запущен.
Проверьте, что сервис 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`.
Проверьте, что веб-сервер работает по адресу 193.32.63.170+X, где X ваши идентификатор. Если что-то не работает должным образом, вы можете попытаться выяснить причину в файлах `access.log` и `error.log` в каталоге `/usr/local/nginx/logs` или `/var/log/nginx`.
Проверьте, что веб-сервер работает по адресу 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:
Переведите веб-сервер на https. Измените порт прослушивания на `443 ssl`, сгенерируйте сертификаты и ключ командой openssl в директорию `/data/certs/`. Вам понадобятся следующие параметры в блоке server:
- listen,
- listen,
- ssl_certificate,
- ssl_certificate,
@ -115,6 +115,9 @@ server {
}
}
```
```
### 9.2
Переведите веб-сервер на https с сертификатом, полученным утилитой `certbot`` от Letsencrypt.
### 10.1
### 10.1
Одним из частых применений nginx является его настройка в качестве прокси-сервера, что означает сервер, который получает запросы, передает их на проксируемые серверы, получает от них ответы и отправляет их клиентам.
Одним из частых применений nginx является его настройка в качестве прокси-сервера, что означает сервер, который получает запросы, передает их на проксируемые серверы, получает от них ответы и отправляет их клиентам.
@ -135,11 +138,11 @@ server {
Это будет простой сервер, который прослушивает порт 80 ( директиву listen можно не указывать, если используется стандартный порт 80) и отображает все запросы в каталог `/data/www` локальной файловой системе. Создайте этот каталог и поместите в него файл `index.html`с содержимым "Hello from internal server!". Обратите внимание, что корневая директива находится в контексте сервера. Такая корневая директива используется, когда блок местоположения, выбранный для обслуживания запроса, не включает собственную корневую директиву.
Это будет простой сервер, который прослушивает порт 80 ( директиву listen можно не указывать, если используется стандартный порт 80) и отображает все запросы в каталог `/data/www` локальной файловой системе. Создайте этот каталог и поместите в него файл `index.html`с содержимым "Hello from internal server!". Обратите внимание, что корневая директива находится в контексте сервера. Такая корневая директива используется, когда блок местоположения, выбранный для обслуживания запроса, не включает собственную корневую директиву.
### 10.2
### 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):
stud@stud12:~$ (echo red; echo green 1>&2) | echo blue
```
В большинстве случаев эта команда выводит "синий зеленый". Но примерно в 1% случаев она выводит "зеленый синий". А иногда выводится просто "синий". Для большей детерминированности добавим в пример задержки в 100мс. В реальности эта задержка на выполнение инструкций команды будет зависеть от загрузки системы и приоритетов выполнения задач.
```
stud@stud12:~$ (echo red; echo green 1>&2) | echo 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:
Напишите .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.
Ср 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)
date=$(date)
claim='snow is white'
claim='snow is white'
echo "$date: The claim that \"$claim\" is true if and only if $claim."
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
Напишите скрипт, который создает каталог, а затем переходит в него, создаёт в нём файл и записывает в него значения всех специальных переменных. Путь к каталогу должен быть передан в качестве первого аргумента.
Напишите функцию в скрипте, которая создает каталог, путь к которому передан в качестве первого аргумента и переходит в него. Проверьте работу функции в этом же файле. Работает ли функция за пределами контекста скрипта?
Напишите аналогичный предыдущему заданию скрипт, но оберните все действия в функцию, а в конце скрипта выполните эту функцию. Проверьте работу скрипта.
Заметим, что при интерпретации команды в `eval` используются глобальные значения специальных переменных скрипта, а не функции.
stud@stud15:~$
```
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
```bash
$ mkdir_cd () {
stud@stud12:~$ cat 4_2.sh
mkdir -p $1
#!/bin/bash
cd $1
a='global a'
echo current dir: $(pwd)
f () {
local b='local b'
echo a: ${a}, b: ${b}
}
}
stud@stud15:~$ mkdir_cd /tmp/a/b/c/d
echo a: ${a}, b: ${b}
current dir: /tmp/a/b/c/d
f
stud@stud15:/tmp/a/b/c/d$
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.
Проверьте, что функции могут изменять переменные среды, например, изменить текущий каталог, тогда как скрипт не может. Напишите скрипт, в котором инициализируются две переменные A и B. Перед одной из них указывается export. Выполните скрипт и посмотрите на выдачу команды env. Выполните файл командой source (документация в source --help и секции встроенных команд man bash).
Менее известной, но полезной может быть подстановка дескриптора файла с результатом выполнения команды. `<( CMD )` выполнит `CMD` и поместит вывод во временный файл и заменит `<()` именем этого файла. Это полезно, когда команды ожидают, что значения будут переданы через файл, а не STDIN. Например, `diff <(ls foo) <(ls bar)` покажет различия между файлами в каталогах foo и bar.
```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.
## 6.
Попробуйте условные выражения в скрипте в if конструкции:
Попробуйте условные выражения в скрипте в if конструкции.
```bash
```bash
$ cat 4.sh
$ cat 6.sh
if [[ true && true ]]
if [[ true && true ]]
then
then
echo "True"
echo "True"
@ -72,84 +206,207 @@ if [[ true || false ]]
then
then
echo "True"
echo "True"
fi
fi
stud@stud15:~$ ./4.sh
```
```
stud@stud12:~$ ./6.sh
True
True
True
True
```
```
### 5.
## 6.5
Напишите скрипт, который проходит по всем файлам, переданным в качестве аргументов, и ищет в них строку hello. Перенаправьте grep `STDOUT` и `STDERR` в специальный файл `/dev/null`. Для каждого файла в if создайте файл с содержимым `hello`, если `grep` завершился с ошибкой.
## 7.
Напишите скрипт, который проходит по всем файлам, переданным в качестве аргументов, и ищет в них строку `hello`. Перенаправьте `grep``STDOUT` и `STDERR` в специальный файл `/dev/null`. Для каждого файла в `if` создайте файл с содержимым `hello`, если `grep` завершился с ошибкой.
^-- SC2086 (info): Double quote to prevent globbing and word splitting.
^-- SC2086 (info): Double quote to prevent globbing and word splitting.
Did you mean:
Did you mean:
grep hello "$f" 2> /dev/null 1> /dev/null
grep hello "$f" 2> /dev/null 1> /dev/null
In 5.sh line 3:
In 7.sh line 4:
if [[ $? -ne 0 ]]
if [[ $? -ne 0 ]]
^-- SC2181 (style): Check exit code directly with e.g. 'if ! mycmd;', not indirectly with $?.
^-- SC2181 (style): Check exit code directly with e.g. 'if ! mycmd;', not indirectly with $?.
In 5.sh line 5:
In 7.sh line 6:
echo $f has no hello in it. correcting.
echo $f has no hello in it. correcting.
^-- SC2086 (info): Double quote to prevent globbing and word splitting.
^-- SC2086 (info): Double quote to prevent globbing and word splitting.
Did you mean:
Did you mean:
echo "$f" has no hello in it. correcting.
echo "$f" has no hello in it. correcting.
In 5.sh line 6:
In 7.sh line 7:
echo "hello" > $f
echo "hello" > $f
^-- SC2086 (info): Double quote to prevent globbing and word splitting.
^-- SC2086 (info): Double quote to prevent globbing and word splitting.
Did you mean:
Did you mean:
echo "hello" > "$f"
echo "hello" > "$f"
For more information:
For more information:
https://www.shellcheck.net/wiki/SC2068 -- Double quote array expansions to ...
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/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
```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
$ cat ./7.sh
#!/usr/bin/env python
#!/usr/bin/env python
import sys
import sys
for arg in reversed(sys.argv[1:]):
for arg in reversed(sys.argv[1:]):
print(arg)
print(arg)
```
```
$ ./7.sh 1 2 3 4 5
$ ./7.sh 1 2 3 4 5
5
5
4
4
@ -158,30 +415,14 @@ $ ./7.sh 1 2 3 4 5
1
1
```
```
### 8.
## 11.
Функции выполняются в текущей среде оболочке, тогда как скрипты выполняются в своем собственном процессе.
Скажем, у вас есть команда, которая редко дает сбой. Чтобы отладить её, вам нужно зафиксировать её выходные данные, но это может занять много времени, чтобы поймать неудачный запуск. Напишите сценарий bash, который запускает следующий сценарий до тех пор, пока он не завершится аварийно, записывает стандартный вывод и потоки ошибок в файлы и печатает все в конце. Бонусный балл, за то, что вы можете сообщить, сколько запусков потребовалось для сбоя сценария.
Проверьте, что функции могут изменять переменные среды, например, изменить текущий каталог, тогда как скрипт не может. Напишите скрипт, в котором инициализируются две переменные `A` и `B`. Перед одной из них указывается `export `. Выполните скрипт и посмотрите на выдачу команды `env`. Выполните файл командой source (source --help). Какие переменные экспортировались в оболочку?
```bash
```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, поскольку они наиболее распространены.
Масштабируемый подход к управлению системой требует, чтобы административные изменения были структурированы, воспроизводимы и тиражируемы на нескольких компьютерах. В реальном мире это означает, что такие изменения должны быть сделаны программным обеспечением, а не выполняться администраторами по инструкциям или, что еще хуже, по памяти.
Сценарии стандартизируют административную работу и освобождают время администраторов для более важных и интересных задач. Сценарии также служат своеобразной бесплатной документацией, поскольку в них записываются шаги, необходимые для выполнения той или иной задачи. Основной альтернативой сценариям для сисадминов является использование систем управления конфигурацией (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.
### 1.
Кроме результатов в `STDOUT` и ошибок в `STDERR` сценарии возвращают код возврата. Код возврата или статус выхода — это то, как скрипты/команды должны сообщать о том, как прошло выполнение. Значение `0` обычно означает, что все прошло нормально; все, что отличается от `0`, означает, что произошла ошибка.
Коды выхода можно использовать для условного выполнения команд с использованием операторов `&&` (`и`) и `||` (`или`). Команды также можно разделять в пределах одной строки с помощью точки с запятой `;`, если они должны выполниться независимо от возвращаемого кода. Истинная программа всегда будет иметь код возврата `0`, а ложная команда всегда будет иметь код возврата от `1` до `255`.
Выполните следующие примеры:
```
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, используйте синтаксис `foo=bar`. Чтобы получить доступ к значению переменной запишите знак `$` перед её именем `$foo`. Обратите внимание, что `foo = bar` не будет работать, так как интерпретируется как вызов программы `foo`с аргументами `=` и `bar`. Как правило, в сценариях оболочки символ пробела выполняет разделение аргументов. Поначалу такое поведение может сбивать с толку, поэтому всегда проверяйте его.
Чтобы назначить переменные в bash, используйте синтаксис `foo=bar`. Чтобы получить доступ к значению переменной запишите знак `$` перед её именем `$foo`. Обратите внимание, что `foo = bar` не будет работать, так как интерпретируется как вызов программы `foo`с аргументами `=` и `bar`. Как правило, в сценариях оболочки символ пробела выполняет разделение аргументов. Поначалу такое поведение может сбивать с толку, поэтому всегда проверяйте его.
Строки в bash могут быть определены парными символами `'` или `"`, но они не эквивалентны. Строки, разделенные `'`, являются литеральными строками и не интерпретируют bash выражения, тогда как строки с`"` будут. Для экранирования кавычек используется символ обратного слеша `\`.
Стандартных правил именования переменных оболочки не существует, но имена, набранные заглавными буквами, обычно указывают на переменные среды или переменные, считываемые из глобальной конфигурации. Чаще всего локальные переменные обозначаются всеми строчными буквами, а их компоненты отделяются друг от друга разделены символами подчеркивания. Имена переменных чувствительны к регистру.
Напишите .sh скрипт в котором в переменную date присваивается значение текущей даты, в переменную claim - строка "snow is white". После вызова скрипт должен выводить строку, используя переменные date и claim:
Строки в 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.
Ср 14 сен 2022 14:50:46 +04: The claim that “snow is white” is true if and only if snow is white.
```
```
Сделайте файл исполняемым для владельца и вызовите указанием полного или относительного пути к нему.
Сделайте файл исполняемым для владельца и вызовите указанием полного или относительного пути к нему.
### 2.
### 3.
Как и в большинстве языков программирования, bash поддерживает методы управления потоком, включая условные и циклические операторы if, case, while и for. Точно так же в bash есть функции, которые принимают аргументы и могут с ними работать. Вот пример определения функции:
В отличие от других языков сценариев, `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_arguments () {
echo "First three arguments: $0 $1 $2 $3, Argument count: $#, All 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.
### 5.
Менее известной, но полезной может быть подстановка дескриптора файла с результатом выполнения команды. `<( CMD )` выполнит `CMD` и поместит вывод во временный файл и заменит `<()` именем этого файла. Это полезно, когда команды ожидают, что значения будут переданы через файл, а не STDIN. Например, `diff <(ls foo) <(ls bar)` покажет различия между файлами в каталогах foo и bar.
Функции выполняются в текущей среде оболочке, тогда как скрипты выполняются в своем собственном процессе.
### 4.
Команды часто возвращают выходные данные, используя `STDOUT`, ошибки — через `STDERR` и код возврата, чтобы сообщать об ошибках более удобным для сценариев способом. Код возврата или статус выхода — это то, как скрипты/команды должны сообщать о том, как прошло выполнение. Значение 0 обычно означает, что все прошло нормально; все, что отличается от 0, означает, что произошла ошибка.
Коды выхода можно использовать для условного выполнения команд с использованием `&&` (и оператора) и `||` (или оператор), оба из которых являются операторами. Команды также можно разделять в пределах одной строки с помощью точки с запятой `;`. Истинная программа всегда будет иметь код возврата `0`, а ложная команда всегда будет иметь код возврата `1`.
Проверьте, что функции могут изменять переменные среды, например, изменить текущий каталог, тогда как скрипт не может. Напишите скрипт, в котором инициализируются две переменные `A` и `B`. Перед одной из них указывается `export`. Выполните скрипт и посмотрите на выдачу команды `env`. Выполните файл командой `source` (документация в `source --help` и секции встроенных команд `man bash`). Какие переменные экспортировались в оболочку?
Попробуйте выполнить следующие примеры:
### 6.
Попробуйте условные выражения в скрипте в `if` конструкции:
Напишите скрипт, который проходит по всем файлам, переданным в качестве аргументов, и ищет в них строку `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
```bash
echo "True"
#!/usr/bin/env bash
fi
set -e
f() {
mv ./*.txt /tmppp
echo "success!"
}
f || echo "failed!"
```
```
Ответ - во втором случае, оператор `||` деактивирует `set -e`. Это задокументированное поведение.
### 5.
#### 9.1. Почему в этом примере не работает печать?
Напишите скрипт, который проходит по всем файлам, переданным в качестве аргументов, и ищет в них строку hello. Перенаправьте grep `STDOUT` и `STDERR` в специальный файл `/dev/null`. Для каждого файла в if создайте файл с содержимым `hello`, если `grep` завершился с ошибкой.
```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.
Рекомендация проста: не используйте `set -e`. Вместо этого добавьте собственную проверку ошибок.
Установите пакет shellcheck и проверьте написанный вами ранее скрипт одноименной командой.
### 7.
### 10.
Cкрипты не обязательно должны быть написаны на bash для вызова из терминала. Ядро определяет, что сценарий нужно выполнять с помощью другого интерпретатора вместо командой оболочки, если в начало скрипта включена строка shebang. Хорошей практикой является написание строк shebang с помощью команды env, которая будет разрешаться везде, где эта команда находится в системе, что повышает переносимость ваших сценариев. Например, чтобы определить местоположение python, env будет использовать переменную среды `PATH` при записи `#!/usr/bin/env python`.
Cкрипты не обязательно должны быть написаны на `bash` для вызова из терминала. Ядро определяет, что сценарий нужно выполнять с помощью другого интерпретатора вместо командой оболочки, если в начало скрипта включена строка `shebang`. Хорошей практикой является написание строк `shebang`с помощью команды `env`, которая будет разрешаться везде, где эта команда находится в системе, что повышает переносимость ваших сценариев. Например, чтобы определить местоположение `python`, `env` будет использовать переменную среды `PATH` при записи `#!/usr/bin/env python`. Если у вас установлено несколько версий Python, то команда `/usr/bin/env` обеспечит использование интерпретатора, который стоит первым в `$PATH` окружения. Альтернативой может быть жесткая привязка вида `#!/usr/bin/python` что тоже нормально, но менее гибко.
Напишите скрипт, который выполняет следующий код:
Напишите скрипт, который выполняет следующий код:
```
```python
import sys
import sys
for arg in reversed(sys.argv[1:]):
for arg in reversed(sys.argv[1:]):
print(arg)
print(arg)
```
```
### 8.
Функции выполняются в текущей среде оболочке, тогда как скрипты выполняются в своем собственном процессе.
Проверьте, что функции могут изменять переменные среды, например, изменить текущий каталог, тогда как скрипт не может. Напишите скрипт, в котором инициализируются две переменные `A` и `B`. Перед одной из них указывается `export `. Выполните скрипт и посмотрите на выдачу команды `env`. Выполните файл командой source (source --help). Какие переменные экспортировались в оболочку?
### 9.
### 11.
Скажем, у вас есть команда, которая редко дает сбой. Чтобы отладить её, вам нужно зафиксировать её выходные данные, но это может занять много времени, чтобы поймать неудачный запуск. Напишите сценарий bash, который запускает следующий сценарий до тех пор, пока он не завершится аварийно, записывает стандартный вывод и потоки ошибок в файлы и печатает все в конце. Бонусный балл, за то, что вы можете сообщить, сколько запусков потребовалось для сбоя сценария.
Скажем, у вас есть команда, которая редко дает сбой. Чтобы отладить её, вам нужно зафиксировать её выходные данные, но это может занять много времени, чтобы поймать неудачный запуск. Напишите сценарий `bash`, который запускает следующий сценарий до тех пор, пока он не завершится аварийно, записывает стандартный вывод и потоки ошибок в файлы и печатает все в конце. Бонусный балл, за то, что вы можете сообщить, сколько запусков потребовалось для сбоя сценария.
```
```bash
#!/usr/bin/env bash
#!/usr/bin/env bash
n=$(( RANDOM % 100 ))
n=$(( RANDOM % 100 ))
@ -100,11 +232,52 @@ fi
echo "Everything went according to plan"
echo "Everything went according to plan"
```
```
### 10.
### 12.
Напишите скрипт, который:
Выберите любые две машины под вашим контролем, имеющие доступ друг к другу по сети, и создайте на каждой машине папку `/data/`с заданными правами и владельцем `-rwxr-xr-x root root`. Выполните задание в соответствие с лучшими практиками для написания скриптов. В задачи скрипта входят:
- создаёт пользователя на двух машинах,
- создание пользователя на двух машинах с домашними директориями и интерпретатором `bash` по умолчанию,
- кроме домашней директории заводит папку для пользователя в `/ceph/`с нужными правами,
- создание для пользователя папки в `/data/`с доступом только её владельцу,
- создаёт ссылку в домашней директории на директорию в `/ceph/`,
- создание ссылки в домашней директории на директорию в `/data/`,
- ограничивает доступ к домашней папке всем, кроме владельца,
- настройки беспарольного перемещения между машинами:
- генерирует пользователям ключи ed25519, рассылает по машинам и регистрирует ключи для беспарольного перемещения пользователя между машинами.
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`.
- В сообщениях об ошибках указываете какая функция или операция не выполнилась.
- Используйте имена, набранные заглавными буквами, для указания на переменные среды или переменные, считываемые из глобальной конфигурации. В именах локальных переменных используйте строчные буквы, с разделением слов нижним подчёркиванием `_`.
Исправьте проблемы настройки сети в виртуальных машинах `troublesome-X-task[1-5]`. В каждой машине 1 проблема после исправления которой работает команда `ping yandex.com`. Шлюз по умолчанию для машины в каждом задании - 192.168.1.1 в сети 192.168.1.0/24. Всего 5 заданий. Используйте механизм снимков и команду rollback в proxmox интерфейсе, чтобы откатывать машину в первоначальное состояние.
### 1. Не активирован и не запущен systemd-networkd
### 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. Команда должна отработать без ввода пароля.
Исправьте проблемы настройки сети в виртуальных машинах `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`. В чём заключается проблема настройки машины? Исправьте её.
В виртуальную машину examX (здесь и далее X - ваш идентификатор) установите debian из образа `debian-11.4.0-amd64-netinst.iso`. Сохраните в текстовый файл сделанный выбор в меню установки. Создайте пользователя stud во время или после установки.
В виртуальную машину examX (здесь и далее X - ваш идентификатор) установите debian из образа `debian-12.1.0-amd64-netinst.iso`. Сохраните в текстовый файл сделанный выбор в меню установки. Создайте пользователя stud во время или после установки.
### 2.
### 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`.
Примечание: удалите пакет `ifupdown` и установите символическую ссылку `/etc/resolv.conf` на `/run/systemd/resolve/resolv.conf`.
@ -18,4 +18,4 @@
Настройте беспарольный доступ с машины `studX` на новую для пользователя `stud`. Запретите доступ на машину по паролю.
Настройте беспарольный доступ с машины `studX` на новую для пользователя `stud`. Запретите доступ на машину по паролю.
### 6.
### 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` сервис на перезапуск в случае отказа.
# Руководство для преподавателя. Подготовка среды проведения лабораторных работ
## Подготовка среды проведения лабораторных работ
Лабораторные проводятся на виртуальных машинах в системе виртуализации Proxmox. Задания выкладываются в публичный git репозиторий. Для получения новых заданий студенты первоначально скачивают их по ссылке командой `git clone`, а затем в начале каждого урок обновляют их командой `git pull`.
Лабораторные проводятся на виртуальных машинах в системе виртуализации 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 конвертации виртуальной машины в шаблон. Из шаблона копия создаётся на порядки быстрее по времени, чем при полном клонировании. Следуйте следующим шагам:
Для массового создания виртуальных машин рекомендуется использовать возможность Proxmox конвертации виртуальной машины в шаблон. Из шаблона копия создаётся на порядки быстрее по времени, чем при полном клонировании. Следуйте следующим шагам:
1. настройте машину с общими для всех копий настройками,
1. настройте машину с общими для всех копий настройками,
2. преобразуйте её в шаблон (template),
2. преобразуйте её в шаблон (template),
3. создайте клоны из шаблона и донастройте, если необходимо,
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 или медленный тип диска может привести к существенному замедлению работы во время установки ОС или пакетов.
### Основные виртуальные машины
Данные виртуальные машины предназначены для всех заданий, исключая:
## 1. Подготовка виртуальной машины к занятиям `01`, `02`, `04`, `05`, `06`, `07`, `08`, `09`, `10`, `11`.
- 00_os_installation,
- 03_networking,
- 12_troubleshooting,
- final_exam.
Создайте vlan с доступом в интернет. Например, bond0.499 и мост vmbr499 с параметрами:
Создайте vlan с доступом в интернет. Например, `bond0.499` и мост `vmbr499`с параметрами:
- Bridge ports: bond0.499,
- Bridge ports: `bond0.499`,
- VLAN aware: false,
- VLAN aware: `false`,
- IPv4/CIDR: 10.160.179.254/24,
- IPv4/CIDR: `10.160.179.254/24`,
- Gateway (IPv4): 10.160.179.1.
- Gateway (IPv4): `10.160.179.1`.
До начала занятий создайте N виртуальных машин со следующими характеристиками:
До начала занятий создайте N виртуальных машин со следующими характеристиками:
- 1 сокет с 4 ядрами,
- 1 сокет с 4 ядрами,
- 8 Гб оперативной памяти,
- 8 Гб оперативной памяти,
- 16 Гб дискового пространства.
- 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 на каждую. Установите пакеты:
Установите минимальный дистрибутив debian на каждую. Установите пакеты:
- man-db,
```
- ssh,
apt install man-db ssh vim tree jq lsof git mc fail2ban
- vim,
```
- tree,
- jq,
- lsof.
Удалите пакет ifupdown.
Удалите пакет `ifupdown`, так как настройка сети будет производится средствами `systemd-networkd`.
```
apt remove ifupdown
```
Пробросьте порты: 22, 80, 443.
Пробросьте порты: `22`, `80`, `443`.
Организуйте удалённый доступ к машинам по ssh ключу.
Организуйте удалённый доступ к машинам по `ssh` ключу. Запретите доступ по ssh через пароль.
### Подготовка к занятию "История операционных систем. Установка Debian"
## 2. Подготовка виртуальной машины к занятиям `00`.
Данные виртуальные машины предназначены для тренировки в установке debian.
Данные виртуальные машины предназначены для тренировки в установке debian в уроке `00`.
До начала занятий создайте N виртуальных машин со следующими характеристиками:
До начала занятий создайте N виртуальных машин со следующими характеристиками:
- 1 сокет с 4 ядрами,
- 1 сокет с 4 ядрами,
- 8 Гб оперативной памяти,
- 8 Гб оперативной памяти,
- 32 Гб дискового пространства,
- 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 с параметрами:
Создайте `N` vlan без доступа в интернет. Например, `bond0.X` и мост `vmbrX`с параметрами:
- Bridge ports: bond0.X,
- Bridge ports: `bond0.X`,
- VLAN aware: false.
- 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 с параметрами:
Создайте `N` vlan без доступа в интернет: `bond0.N+X` и мост `vmbrN+X`с параметрами:
- Bridge ports: bond0.N+X,
- Bridge ports: `bond0.N+X`,
- VLAN aware: false.
- 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
chmod 777 /home/stud/.ssh
```
```
### Подготовка к экзамену
## 5. Подготовка к экзамену
До начала занятий создайте N виртуальных машин со следующими характеристиками:
До начала занятий создайте N виртуальных машин со следующими характеристиками:
- 1 сокет с 4 ядрами,
- 1 сокет с 4 ядрами,
@ -168,4 +169,4 @@ chmod 777 /home/stud/.ssh
- 6 Гб дискового пространства,
- 6 Гб дискового пространства,
- сетевой интерфейс vmbr499.
- сетевой интерфейс vmbr499.
Подключите cdrom с образом debian-11.4.0-amd64-netinst.iso.
Подключите cdrom с образом `debian-11.4.0-amd64-netinst.iso`.
Подготовьте PXE boot сервер, который позволяет установить Debian по сети. Продемонстрируйте на чистой виртуальной машине, поключенной к той же сети, что установка завершается успешно.
Установите в машину `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
### 1.1 BIOS
Включите машину с названием `bios`. Загрузите debian, загрузите ubuntu.
Перезагрузите машину. Какая ОС загружается по умолчанию? Загрузите Debian с помощью выбора в GRUB меню. Посмотрите на выдачу следующих команд:
```
# lsblk
# fdisk -l /dev/sda
# fdisk -l /dev/sdb
```
Загрузите Ubuntu и также проверьте эти команды.
Изучите директорию `/boot/`.
### 1.2 BIOS
### 1.2 BIOS
Повторите операцию, выбрав в BIOS диск для загрузки в ручную.
Теперь загрузите Debian и Ubuntu, но с помощью выбора в меню BIOS диска для загрузки `scsi0` и `scsi1`. В меню можно попасть при загрузке машины по клавише `Esc`.
### 1.3 BIOS
### 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
### 2.1 UEFI
Включите машину с названием `uefi`. Загрузите debian, загрузите ubuntu.
Перезагрузите машину. Какая ОС загружается по умолчанию? Загрузите Debian с помощью выбора в GRUB меню. Посмотрите на выдачу следующих команд:
```
# lsblk
# fdisk -l /dev/sda
# fdisk -l /dev/sdb
```
Загрузите Ubuntu и также проверьте эти команды.
Изучите директорию `/boot/efi/`.
### 2.2 UEFI
### 2.2 UEFI
Поменяйте порядок загрузки в UEFI графической консоли.
Поменяйте порядок загрузки в UEFI графической консоли`UEFI Firmware settings`.
### 2.3 UEFI
### 2.3 UEFI
Поменяйте порядок загрузки в UEFI терминале `efi shell`. Изучите команды и файловые системы FS0:, FS1:, FS2:.
Поменяйте порядок загрузки в UEFI терминале `EFI Internal Shell`. Изучите команды и файловые системы `FS0:`, `FS1:`, `FS2:`.
### 2.4 UEFI
### 2.4 UEFI
Поменяйте порядок загрузки с помощью команды `efibootmgr` из операционной системы. Изучите директорию `/boot/efi`.
Поменяйте порядок загрузки с помощью команды `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
### 3.1 GRUB
В машине с названием `uefi`. Загрузите debian, загрузите ubuntu.
Поменяйте порядок загрузки операционных систем в `grub.conf`.
### 3.2 GRUB
### 3.2 GRUB
Поменяйте порядок загрузки операционных систем.
### 3.3 GRUB
Настройте GRUB на ожидание 15 секунд перед загрузкой операционной системы по умолчанию, если никакая клавиша не нажата.
Настройте GRUB на ожидание 15 секунд перед загрузкой операционной системы по умолчанию, если никакая клавиша не нажата.
### 3.3 GRUB
### 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
Проверьте работу сервера на другой машине, выбрав `iPXE` в меню загрузки `BIOS`.
Используйте мост vmbrX+ваш id для сетевого интерфейса. Используйте шлюз 192.168.1.1 для доступа в интернет.
В последующих заданиях будет полезной функция Proxmox snapshot, которая позволяет откатить состояние жёстких дисков до момента времени снимка. Если вы будете пользоваться этой функцией, чтобы ускорить процесс создания снимка, предварительно выключайте машину.
### 0.1
### 0.1
Загрузите виртуальную машину `bios` или `uefi`с подключенным диском `gparted-live-*.iso` и загрузите debian с gparted. Зайдите в gparted найдите в интерфейсе все подключенные диски и их разметку.
Загрузите виртуальную машину `bios` или `uefi`с подключенным диском `gparted-live-*.iso` и загрузите debian с gparted. Зайдите в gparted найдите в интерфейсе все подключенные диски и их разметку.
### 0.2
### 0.2
Добавьте к оборудованию виртуальной машины 15 новых дисков по 0.1ГБ, обновите список устройств в интерфейсе gparted. Создайте snapshot виртуальной машины на случай ошибок в конфигурации.
Добавьте к оборудованию виртуальной машины 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 RAID 0
#### 1.1.1
#### 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`.
Примонтируйте файловую систему на `/dev/md0` в папку `/raid0`, предварительно её создав. Проверьте, что запись и чтение работают для этой директории. Проверьте размер диска, общий объем должен составлять 0.2GB.
Примонтируйте файловую систему на `/dev/md0` в папку `/raid0`, предварительно её создав. Проверьте, что запись и чтение работают для этой директории. Проверьте размер диска. Общий объем должен составлять 0.2GB.
#### 1.1.4
#### 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`.
Вызовите команды `mdadm --query` и `mdadm --detail` для `/dev/md0`.
#### 1.1.5
#### 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 RAID 1
#### 1.2.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
### 2.1
Создайте логический диск с чередованием загрузки (striping, аналог raid 0). Примонтируйте в систем, проверьте работу логического тома.
Создайте логический диск с чередованием загрузки (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.
Проинициализируйте на логическом диске файловую систему, примонтируйте и проверьте её работоспособность.
Проинициализируйте на логическом диске файловую систему, примонтируйте и проверьте её работоспособность.
ZFS и Btrfs обычно называют файловыми системами. Но на самом деле они представляют собой вертикально интегрированные подходы к управлению хранилищем, включающие в себя функции файловой системы, менеджера логических томов и RAID-контроллера.
ZFS и Btrfs обычно называют файловыми системами. Но на самом деле они представляют собой вертикально интегрированные подходы к управлению хранилищем, включающие в себя функции файловой системы, менеджера логических томов и RAID-контроллера.
### 3.1
### 3.1
Создайте аналоги RAID-10 (4 диска) и RAID-5 (3 диска) в одной из файловых систем: btrfs или zfs.
Создайте аналоги RAID-10 (4 диска) и RAID-5 (3 диска) в одной из файловых систем: `btrfs` или `zfs`.
Установите пакет:
Установите пакет:
- `btrfs-progs`, если он ещё не установлен для работы с btrfs,
- `btrfs-progs`, если он ещё не установлен для работы с btrfs,
- `zfsutils-linux` (contrib ветка), если он ещё не установлен для работы с zfs.
- `zfsutils-linux` (contrib ветка), если он ещё не установлен для работы с zfs.
# Релевантная литература
# Релевантная литература
1. Nemeth E. et al. UNIX and Linux system administration handbook. Chapter 5, Chapter 20.
1. Nemeth E. et al. UNIX and Linux system administration handbook. Chapter 5, Chapter 20.
Стандартная модель UNIX представляет из себя форму "избирательного контроля доступа" (DAC - Discretionary Access Control), поскольку позволяет владельцам контролируемых объектов устанавливать права на них. Пользователь сам может разрешить другим просмотр содержимого домашнего каталога или написать программу с флагом `setuid`, которая позволит другим пользователям отправлять сигналы его процессам.
Системы мандатного управления доступом (MAC, Mandatory Access Control) позволяют администраторам писать политики контроля доступа, которые переопределяют или дополняют избирательные разрешения традиционной модели. Например, вы можете установить правило, согласно которому домашние каталоги доступны только их владельцам. Это может помочь сохранить конфиденциальные документы, даже если пользователь небрежно относится к его разрешениям. Хотя такие системы разрабатывались для реализации многоуровневой безопасности в государственных организациях с различными грифами секретности, на практике чаще всего вы сталкнётесь с её применением для защиты фоновых служб. Хорошо реализованные политики могут помешать компрометации системы с уязвимым программным обеспечением.
SELinux - одна из старейших реализаций системы MAC для Linux, разработанная в Агентством национальной безопасности США. Система реализует почти все возможности MAC и RBAC (Role Based Access Control). Из-за этого разработка политик является сложной задачей. К счастью, многие общие политики доступны онлайн и имеют разумные значениям по умолчанию. Для упрощения разработки политик могут использоваться специализированные редакторы, например https://seedit.sourceforge.net/.
### 2.1 Изучим установленные контексты безопасности
### 2.1 Изучим установленные контексты безопасности
Для начала давайте проверим контекст файла в домашнем каталоге пользователя `stud`:
Для начала давайте проверим контекст файла в домашнем каталоге пользователя `stud`:
```
```
$ cd
$ cd
$ touch file
$ ls -Z
$ ls -Z
```
```
Флаг `-Z` присутствует в широком спектре распространенных инструментов CLI, включая `ls` и `ps`. При указании этого флага в дополнении к стандартным разрешениям UNIX, информации о пользователе и группе отображается контекст SELinux файла.
Флаг `-Z` присутствует в широком спектре распространенных инструментов CLI, включая `ls` и `ps`. При указании этого флага в дополнении к стандартным разрешениям UNIX, информации о пользователе и группе отображается контекст SELinux файла.
@ -58,14 +65,16 @@ $ ls -Z
Пользователь SELinux отличается от пользователя UNIX и существует исключительно для того, чтобы связать пользователя UNIX с набором ролей. Это позволяет пользователям UNIX быть ограниченными политикой SELinux.
Пользователь SELinux отличается от пользователя UNIX и существует исключительно для того, чтобы связать пользователя UNIX с набором ролей. Это позволяет пользователям UNIX быть ограниченными политикой SELinux.
В нашем случае пользователь `unconfined_u` означает, что пользователь сопоставлен слогином SELinux по умолчанию. Это означает, что пользователю разрешено запускать любое приложение, разрешенное стандартными разрешениями файловой системы. Однако, если приложение может перейти в другой домен, к нему будут применятся ограничения, задаваемые SELinux.
В нашем случае пользователь `unconfined_u` означает, что пользователь сопоставлен спользователем SELinux по умолчанию. Это означает, что пользователю разрешено запускать любое приложение, разрешенное стандартными разрешениями файловой системы. Однако, если приложение может перейти в другой домен, к нему будут применятся ограничения, задаваемые SELinux.
Список пользователей SELinux в системы можно посмотреть командами:
Список пользователей SELinux в системы можно посмотреть командами:
```
```
$ seinfo -u
$ seinfo -u
$ semanage login -l
```
```
Cписок сопоставлений между учетными записями пользователей SELinux и Linux
```
# semanage login -l
```
### 2.2 Переход в другой домен
### 2.2 Переход в другой домен
Чтобы продемонстрировать разницу между процессами c ограничениями и без, давайте запустим приложение, которого переход в другой домен не определён:
Чтобы продемонстрировать разницу между процессами c ограничениями и без, давайте запустим приложение, которого переход в другой домен не определён:
@ -73,7 +82,18 @@ $ semanage login -l
# yes >/dev/null &
# yes >/dev/null &
# ps -Z | grep yes
# 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`:
Мы увидим другую картину для процесса `auditd`:
```
```
@ -81,7 +101,7 @@ $ semanage login -l
```
```
Обратите внимание, что третье поле - `auditd_t`, означающее, что процесс `auditd` был ограничен доменом `auditd_t`.
Обратите внимание, что третье поле - `auditd_t`, означающее, что процесс `auditd` был ограничен доменом `auditd_t`.
Остановим запущенный фоновые процессы`yes` и двинемся дальше.
Остановим запущенный фоновый процесс`yes` и двинемся дальше.
Следующее правило гласит, что когда процесс в домене `initrc_t` запускает файл типа `acct_exec_t`, домен процесса должен быть изменен на `acct_t`, если это разрешено политикой. Чтобы это правило перехода домена работало, нужно также присутствие нескольких разрешений.
Следующее правило гласит, что когда процесс в домене `initrc_t` запускает файл типа `acct_exec_t`, домен процесса должен быть изменен на `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
# Разрешение на запуск файла типа acct_exec_t в исходном домене initrc_t
allow initrc_t acct_t:process transition; # Разрешение процессу на переход в домен целевой acct_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.
Подробнее в документации правила https://selinuxproject.org/page/TypeRules.
Обычно в политиках используют макрос `domtrans_pattern` или `domain_transition_pattern` определённый в `/usr/share/selinux/devel/include/support/misc_patterns.spt` для указания правила перехода и разрешений вместе.
Обычно в политиках используют макрос `domtrans_pattern` или `domain_transition_pattern` определённый в `/usr/share/selinux/devel/include/support/misc_patterns.spt` для указания правила перехода и разрешений вместе.
### 2.3 Полезная утилита - restorecon
### 2.3 Полезная утилита - restorecon
Если и есть, что посоветовать запомнить новому пользователю SELinux, так это `restorecon`. Restorecon приведет контекст SELinux к тому, что определено в базе данных контекста системы.
Если и есть, что посоветовать запомнить новому пользователю SELinux, так это `restorecon`. Restorecon приведет контекст SELinux к тому, который определен в базе данных контекста системы.
Чтобы попробовать, давайте намеренно неправильно установим контекст в примере SELinux AVC log:
Чтобы попробовать, давайте намеренно неправильно установим контекст:
```
```
# touch testaudit
# ls -Z ./testaudit
# ls -Z ./testaudit
system_u:object_r:admin_home_t:s0 ./testaudit
system_u:object_r:admin_home_t:s0 ./testaudit
# chcon -t httpd_sys_content_t ./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`, которой вы можете временного изменить контекст файла.
Выше также применяется `chcon`, которой вы можете временного изменить контекст файла.
Установка контекст на `httpd_sys_content_t` также устранила бы проблему, о которой сообщалось в нашем тестовом AVC.
## 3. Установка тестового сервиса
## 3. Установка тестового сервиса
Подготовим сервис, для которого далее будем писать собственную политику безопасности SELinux.
Подготовим сервис, для которого далее будем писать собственную политику безопасности SELinux.
Скачайте текущий репозиторий и перейдите в папку `linux_tasks/modeul2/test_service`.
Скачайте текущий репозиторий и перейдите в папку `linux_tasks/module2/02_mac_selinux/test_service`.
Настройте окружение разработчика, скачайте необходимые заголовочные файлы и установите сервис `testapp`с помощью `make`:
Настройте окружение разработчика, скачайте необходимые заголовочные файлы и установите сервис `testapp`с помощью `make`:
- `testapp.te` - это базовая политика для приложения. Он устанавливает правила для домена `testapp_t`,
- `testapp.te` - это базовая политика для приложения. Он устанавливает правила для домена `testapp_t`,
- `testapp.if` - это файл интерфейса. Интерфейсы подобны общедоступным функциям в том смысле, что они предоставляют другим модулям SELinux способы взаимодействия с тем, который вы пишете,
- `testapp.if` - это файл интерфейса. Интерфейсы подобны общедоступным функциям в том смысле, что они предоставляют другим модулям SELinux способы взаимодействия с тем, который вы пишете,
- `testapp.fc` - это файл контекстов. Он содержит информацию о маркировке всех объектов файловой системы, на которые ссылается политика,
- `testapp.fc` - это файл контекстов. Он содержит информацию о маркировке всех объектов файловой системы, на которые ссылается политика,
- `testapp.sh` это предоставленный Red Hat скрипт, который компилирует и загружает модуль политики SELinux.
- `testapp.sh` это скрипт, который компилирует и загружает модуль политики SELinux.
### 4.2. Скомпилируйте и загрузите политику
### 4.2. Скомпилируйте и загрузите политику
@ -212,6 +238,8 @@ Created the following files:
$ sudo ./testapp.sh
$ sudo ./testapp.sh
```
```
Примечание. Замените в файле `*.te`слово `pid` на `runtime` в макросах `files_*`.
Первые 9 строк выходных данных показывают компиляцию политики, загрузку политики в память и автоматическое создание справочной страницы для политики:
Первые 9 строк выходных данных показывают компиляцию политики, загрузку политики в память и автоматическое создание справочной страницы для политики:
### 4.4. Как приложение в конечном итоге получает testapp_context?
### 4.4. Как приложение в конечном итоге получает testapp_context?
Это связано с правилами перехода домена SELinux. Служба `testapp` запускается `systemd`, которая запускается с контекстом `init_t`, поскольку это наша служба инициализации. Из-за правил перехода он изменяет контексты при запуске службы.
Это связано с правилами перехода домена SELinux. Служба `testapp` запускается `systemd`, которая запускается с контекстом `init_t`, поскольку это наша служба инициализации. Из-за правил перехода он изменяет контексты при запуске службы.
type_transition init_t testapp_exec_t : process testapp_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 будет генерировать предупреждения при нарушении существующей системной политики, но не будет предпринимать никаких действий.
На данный момент у нас есть общая политика для приложения `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`.
Если мы внимательно посмотрим на них, то увидим, что процессу тестового приложения отказано в открытии в `/proc/meminfo` и в чтении в `/proc` в целом. Итак, нам нужно найти интерфейс, который позволит осуществлять эти доступы, и добавить его в наш файл `testapp.te`.
### 6.2 Найдите правильный интерфейс
### 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
$ cd /usr/share/selinux/devel/include
$ find . -type f -name "*.if" -exec grep -H '/proc' {} \; | grep "system state information"
$ find . -type f -name "*.if" -exec grep -H '/proc' {} \; | grep "system state information"
@ -945,6 +973,7 @@ setsebool –P httpd_enable_homedirs on
Подготовьте демонстрацию работы 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]
- `man keepalived.conf`, https://www.keepalived.org/manpage.html (на данный момент лучшая документация, идеально отражающая и документирующая все доступные функции)
- https://keepalived.readthedocs.io/en/latest/ (эта документация является устаревшей, поскольку является частичной и не отражает полный набор доступных функций)
Настройте почтовый сервер на основе Postfix и Dovecot для своего домена studX.myoffice.ru (или любой другой). Заведите один или несколько почтовых ящиков для новых пользователей. Пользователь должен иметь возможность:
- подключиться из мобильного или десктопного почтового клиента к серверу со своим логином и паролем,
- отправить почту на внешний адрес gmail.com/yandex.ru/mail.ru,
- принять почтовое сообщение с внешнего адреса отправленное как ответ на входное письмо.
Сервер должен пройти проверку c помощью валидатора https://esmtp.email/tools/mta-sts/.
Какое нам дело до классов адресов? Классы адресов опеределяют то, как 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`.
### 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.
Выполните задания по настройке Proxmox на виртуальных машинах и предоставьте доступ к веб-интерфейсу по адресу `https://studX.myoffice.ru/proxmox/`. Заведите тестового пользователя, который обладает правами на:
- запуск/выключение созданной для него виртуальной машины,
- может создавать диски,
- может изменять конфигурацию оборудования виртуальной машины,
- может сохранять бекапы и делать снепшоты системы.
Установите Proxmox на две виртуальные машины Proxmox. Используйте образ диска `proxmox_7.2.1.iso`.
Установите Proxmox на две виртуальные машины Proxmox. Используйте образ диска `proxmox_8.0.2.iso`.
Параметры виртуальных машин:
Параметры виртуальных машин:
- объем памяти RAM 32ГБ,
- объем памяти RAM 16ГБ,
- число ядер 8,
- число ядер 4,
- объем жёсткого диска 32ГБ,
- объем жёсткого диска 32ГБ,
- сетевое устройство в vlan 15+X (подключенное к мосту vmbr15+X, без указания vlan тега),
- сетевое устройство vmbrX.
- IP из сети `192.168.1.0/24`,
- шлюз `192.168.1.1`,
Параметры установки:
- 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,
- любой общедоступный DNS,
- стандартный пароль для пользователя root,
- стандартный пароль для пользователя root,
- доменные имена `n[1-2].studX.myoffice.ru`.
- доменные имена `n[1-2].studX.myoffice.ru`.
Используйте утилиту `pveversion`, чтобы узнать версию Proxmox.
Используйте утилиту `pveversion`, чтобы узнать версию Proxmox.
Для удобства, настройте беспарольный доступ между машинами. Так как ключи уже сгенерированы при установке, достаточно выполнить `ssh-copy-id`. Чтобы использовать доменные имена на данном этапе внесите их в `/etc/hosts` каждой машины.
## 2.
## 2.
Объедините узлы в Proxmox кластер. Используйте утилиту `pvecm` (документация утилиты `man pvecm`). Чтобы использовать доменные имена на данном этапе внесите их в `/etc/hosts` каждой машины.
Настройте доступ к веб-интерфейсу с помощью прокси сервера или туннелей. Прокси-машина должна иметь два сетевых интерфейса, каждый в своей vlan: 499 и 15+X. Первая vlan позволяет подключиться к прокси из сети интернет, вторая позволяет обмениваться данными между прокси и новым кластером Proxmox.
Настройте доступ к веб-интерфейсу с помощью прокси сервера. Прокси-машина должна иметь два сетевых интерфейса, каждый в своей vlan: 499 и X. Первая vlan позволяет подключиться к прокси из сети интернет, вторая позволяет обмениваться данными между прокси и новым кластером Proxmox.
Параметры `-L` и `-R` обозначают точку входа, локальную или на машине, к который подключается ssh. Пакеты отправленные на точку входа будут переданы через туннель, а затем направлены на адрес и порт, указанные после первого порта 8006.
Настроено перенаправление с 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.
## 4.
Создайте виртуальную машину в новом Proxmox. Скачайте образ `Core` проекта `Tiny Core Linux` http://tinycorelinux.net/downloads.html.
Создайте виртуальную машину в новом Proxmox. Скачайте образ `Core` проекта `Tiny Core Linux` http://tinycorelinux.net/downloads.html.
Объем пространства, занимаемый образом, можно определить с помощью команд `qemu-img info` или `ls -ls`;
Объем пространства, занимаемый образом, можно определить с помощью команд `qemu-img info` или `ls -ls`;
Предупреждение: Никогда не используйте `qemu-img` для изменения образов, используемых запущенной виртуальной машиной или любым другим процессом; это может привести к уничтожению образа. Кроме того, имейте в виду, что запрос образа, которое изменяется другим процессом, может привести к несогласованному состоянию.
Предупреждение: Никогда не используйте `qemu-img` для изменения образов, используемых запущенной виртуальной машиной или любым другим процессом; это может привести к уничтожению образа. Кроме того, имейте в виду, что запрос образа, который изменяется другим процессом, может привести к несогласованному состоянию.
## 6.
## 6.
Для восстановления из бекапа используется утилита `qmrestore` (`man qmrestore`). Восстановите из бэкапа виртуальную машину под другим идентификатором.
Для восстановления из бекапа используется утилита `qmrestore` (`man qmrestore`). Восстановите из бэкапа виртуальную машину под другим идентификатором.