diff --git a/module1/01_bash/solutions.md b/module1/01_bash/solutions.md deleted file mode 100644 index 90dabfd..0000000 --- a/module1/01_bash/solutions.md +++ /dev/null @@ -1,163 +0,0 @@ -# Решения - -## 1 -Вы в директории `/home/stud/data`. Какая из команд переместит вас в домашнюю директорию? -``` -3 cd /home/stud -5 cd ~ -7 cd ~/data/.. -8 cd -9 cd .. -``` -## 2 -Создайте файл dummy в /tmp. Попробуйте удалить его указав флаг -i для команды rm. В чём отличие удаления файла с этим флагом и без него? -``` -mkdir /tmp/dummy - -rm -r -i /tmp/dummy -rm: remove directory '/tmp/dummy'? y - -rm -r /tmp/dummy -``` -Отличие в запросе подтверждения действия. - -## 3 -Создайте папку backup в домашней директории. Одновременно скопируйте файл .bashrc в /tmp/ и в backup с помощью cp. -``` -$ mkdir ~/backup -$ cp .bashrc ~/backup; cp .bashrc /tmp/ -``` -## 4 -Повторите структуру директории: -``` -mkdir project -cd project -mkdir .git -mkdir data -mkdir raw -cd raw -touch 2022-07-23-exp1.log -touch 2022-08-03-exp2.log -touch 2022-11-23-exp3.log -touch 2022-07-23-exp1.dat -touch 2022-08-03-exp2.dat -touch 2022-08-03-exp2-calibration.dat -touch 2022-11-23-exp3.dat -touch 2022-11-23-exp3-calibration.dat -cd ../ -mkdir backup -mkdir shared -``` - -## 5 -Скопируйте файлы экспериментов в backup, но распределите по папкам разные типы файлов. .data в backup/dataset, dat-calibration в backup/calibration, логи в backup/logs. В shared поместите все файлы, созданные 23 числа в папку 23day. Напишите команды в двух вариантах: с относительными путями и с абсолютными. - -``` -cd backup -mkdir dataset calibration logs -cp ./raw/*-exp?.dat backup/dataset/ -cp ./raw/*-exp?-calibration.dat backup/calibration -cp ./raw/*.log ./backup/logs/ -``` - -``` -export PD=/home/stud/project -mkdir $PD/backup/dataset $PD/backup/calibration $PD/backup/logs -cp $PD/raw/*-exp?.dat backup/dataset/ -cp $PD/raw/*-exp?-calibration.dat backup/calibration -cp $PD/raw/*.log ./backup/logs/ -``` - -## 6 -Посчитайте количество строк в файле /var/log/messages. -``` -sudo wc -l /var/log/messages - -sudo cat /var/log/messages | wc -l -``` -## 7 -Инициализируйте файл head_tail_messages с помощью команды head из строк в /var/log/messages, затем добавьте в head_tail_messages последние 23 строки из /var/log/messages. -``` -sudo head /var/log/messages > head_tail_messages -sudo tail -n 23 /var/log/messages >> head_tail_messages -``` -## 8 -Создайте псевдоним "dc", который разрешается в команду "cd" для случаев опечатки. -``` -alias dc=”cd” -``` -## 9 -Прочитайте мануал `man ls` и напишите `ls` команду, которая выводит список файлов в следующем виде: - -* список файлов включает скрытые, -* размер файла указан с метрическими приставками (e.g. 454M вместо 454279954), -* файлы выводятся в историческом порядке, -* вывод в цвете. -``` -ls -caht или ls -cahtl -``` - -## 10 -Запишите в переменную среды PATH значение "". Как это повлияло на выполнение команд? Перезайдите по ssh и попробуйте вызывать любую команду заново. Сохранились ли изменения? -``` -export PATH=”” -следствие: ни один исполняемый файл системой теперь не находится -после переподключения система вернулась в прежнее состояние -``` - -## 11 -Модифицируйте команду так, чтобы у директорий в начале названия присутствовал глобальный индекс idx. -``` -idx=0; -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 -(*) Напишите команду или сценарий для рекурсивного поиска самого последнего измененного файла в каталоге. В общем, можете ли вы перечислить все файлы по давности? - -Плохое решение -``` -ls -Rlht -``` -Лучше -``` -find ./ -type f -printf "%T+ %H%P\n" 2>/dev/null | sort -r -``` -где -%T+ - время последнего изменения в формате 2004-04-28+22:22:05.0, -%H - путь к директории, в которой файл найден, -%P - имя файла. - -## 13 -Напишите цикл, который проходит по списку файлов в текущей директории и выводит полный путь к директории и имя файла. -``` -for f in $(ls); do echo $(pwd)/$f; done -``` - -## 14 -Выведите результат сложения 10 и 4 с помощью bash синтаксиса для арифметических операций. -``` -echo $((10 + 4)) -``` - -## 15 -Выведите результат умножения двух переменных с помощью bash синтаксиса для арифметических операций. -``` -a=1; b=2; echo $((a*b)) -``` - -## 16 -Напишите команду, которая рекурсивно находит все HTML-файлы в папке и запаковывает их в tar.gz архив. Ваша команда должна работать, даже если в файлах есть пробелы. -``` -find . -type f -name "*.html" -print0 | xargs -0 tar cfz htmls.tar.gz -``` \ No newline at end of file diff --git a/module1/02_data_editing_and_analysis/3_bash_data_processing_solutions.md b/module1/02_data_editing_and_analysis/3_bash_data_processing_solutions.md deleted file mode 100644 index 2706ea3..0000000 --- a/module1/02_data_editing_and_analysis/3_bash_data_processing_solutions.md +++ /dev/null @@ -1,117 +0,0 @@ -# Задания на обработку данных в bash - -## 1 -Вызовите `"for f in `seq 20`; do echo $RANDOM >> rnds; done"` и отсортируйте данные `rnds`, в алфавитном порядке, по возрастанию чисел. -``` -sort rnds -sort -n rnds -``` - -## 2 -Сохраните эти первые 10 записей датасета titanic в файл `titanic.csv` для последующих заданий: -``` -PassengerId,Survived,Pclass,Name,Sex,Age,SibSp,Parch,Ticket,Fare,Cabin,Embarked -1,0,3,"Braund, Mr. Owen Harris",male,22,1,0,A/5 21171,7.25,,S -2,1,1,"Cumings, Mrs. John Bradley (Florence Briggs Thayer)",female,38,1,0,PC 17599,71.2833,C85,C -3,1,3,"Heikkinen, Miss. Laina",female,26,0,0,STON/O2. 3101282,7.925,,S -4,1,1,"Futrelle, Mrs. Jacques Heath (Lily May Peel)",female,35,1,0,113803,53.1,C123,S -5,0,3,"Allen, Mr. William Henry",male,35,0,0,373450,8.05,,S -6,0,3,"Moran, Mr. James",male,,0,0,330877,8.4583,,Q -7,0,1,"McCarthy, Mr. Timothy J",male,54,0,0,17463,51.8625,E46,S -8,0,3,"Palsson, Master. Gosta Leonard",male,2,3,1,349909,21.075,,S -9,1,3,"Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg)",female,27,0,2,347742,11.1333,,S -10,1,2,"Nasser, Mrs. Nicholas (Adele Achem)",female,14,1,0,237736,30.0708,,C -``` - -## 3 -Выведите первую колонку, используя `awk`. -``` -awk -F, '{print $1}' file.csv -``` - -## 4 -Выведите содержимое файла без заголовка. -``` -tail -n +2 file.csv -``` - -## 5 -Выведите первую и третью колонку файла, используя `awk`. -``` -awk -F, '{print $1 "," $3}' file.csv -``` - -## 6 -Выведите только те строки, которые содержат строку `male` или `female`: -``` -grep "female" file.csv -``` - -## 7 -Отсортируйте значения `titanic.csv` по значению `Ticket` (9 колонка): -``` -sort -t, -k2 file.csv -``` - -## 8 -Уберите дублирующиеся строки на основании третьей колонки, используя `awk`. -``` -awk -F, '!seen[$1]++' file.csv -``` - -## 9 -Посчитайте сумму колонки `Fare`, используя `awk`. -``` -awk -F, '{sum+=$3} END {print sum}' file.csv -``` - -## 10 -Сконвертируйте файл из csv в json формат, используя `jq`. -``` -jq -R -r 'split(",") | {name:.[0],age:.[1]}' file.csv -``` - -## 11 -Используя `awk` сконвертируйте строки со значениями из колонок `PassengerId`, `Survived`, `Pclass` файла в набор `SQL INSERT` утверждений, которые можно использовать для импорта в SQL базу данных. Используйте `awk`. -``` -awk -F, '{printf "INSERT INTO table VALUES (\"%s\", \"%s\", \"%s\");\n", $1, $2, $3}' file.csv -``` - -## 12 -Конвейеры Unix позволяли организовывать сложные преобразования данных ещё до фреймворков обработки больших данных и сейчас иногда могут быть даже быстрее [Adam D. Command-line Tools can be 235x Faster than your Hadoop Cluster]. - -Найдите гистограмму слов по методу mapreduce с помощью утилит и операторов конвейера. Гистограмма должна быть отсортирована по частоте встречи слова в тексте. - -MapReduce выполняет следующие действия в первой фазе: разбивает содержимое файла на слова, сортирует их, каждому слову сопоставляет 1. Во второй фазе складывает единицы каждого слова, что даёт конечный результат. Используйте любой набор утилит и конструкций bash. Одно из решений задействует: `uniq`, `sort`, `cat`, `sed`. -``` -cat /var/log/dpkg.log | sed 's/ /\n/g' | sort -k1 | uniq -c | sort -k1 -n -``` - -## 13 -Повысьте права до пользователя root с помощью команды `su - root`. Найдите в системном логе `/var/log/auth.log` события "authentication failure", оставьте в строке только дату и имя пользователя и сохраните их в файл. Следуя правилам хорошего тона, после выполнения операций не забудьте выйти из аккаунта суперпользователя. -``` -cat /var/log/auth.log | grep 'authentication failure' | sed 's/^\(.\{15\}\).*authentication failure; logname=\(\w\+\) .*/\1 \2/g' -``` - -## 14 -Выведите 10 самых больших открытых файлов в системе, используя `lsof` и `awk`. -``` -lsof / | awk '{ if($7 > 1048576) print $7/1048576 "MB" " " $9 " " $1 }' | sort -n -u | tail -``` - -# Man страницы -``` -man awk -man lsof -man sort -man uniq -man cat -man sed -man jq -man su -``` - -# Ссылки - -[Adam D. Command-line Tools can be 235x Faster than your Hadoop Cluster] https://adamdrake.com/command-line-tools-can-be-235x-faster-than-your-hadoop-cluster.html - diff --git a/module1/03_networking/solution_task_1_static.md b/module1/03_networking/solution_task_1_static.md deleted file mode 100644 index 0b91c46..0000000 --- a/module1/03_networking/solution_task_1_static.md +++ /dev/null @@ -1,62 +0,0 @@ -# Задание 1 - -0. Узнайте статус сервиса `systemd-networkd`. -``` -# systemctl status systemd-networkd -``` - -1. Активируйте `systemd-networkd`, если он не активирован (disabled). -``` -# systemctl enable systemd-networkd -``` - -2. Запустите `systemd-networkd`, если он не запущен (inactive, dead). -``` -# systemctl start systemd-networkd -``` - -3. Определите имя настраиваемого интерфейса. -``` -# ip link -``` - -4. Для настройки интерфейса `ens18` машин `stud1-1v1` и `stud1-2v1` создайте -или отредактируйте в каждой `/etc/systemd/network/ens18.network`. - -конфигурация `ens18.network` машины `stud1-1v1` -``` -[Match] -Name=ens18 - -[Network] -Address=192.168.1.1/24 -``` - -конфигурация `ens18.network` машины `stud1-2v1` -``` -[Match] -Name=ens18 - -[Network] -Address=192.168.1.2/24 -``` - -5. Перечитайте конфигурацию сети на обеих машинах. -``` -# networkctl reload -``` - -6. После конфигурации на обеих машинах проверьте их взаимную доступность по сети -``` -stud@stud1-2v1$ ping 192.168.1.1 -stud@stud1-1v1$ ping 192.168.1.2 -``` - -7. В случае проблемы, проверьте, что `systemd-networkd` запущен и в его логах нет ошибок. -``` -# systemctl status systemd-networkd -``` - - -# TODO научить пользоваться ip утилитой, дать расшифровку выдачи ip link, ip addr, -как понять по выдаче ip, что отключен провод, или что отключен интерфейс программно? \ No newline at end of file diff --git a/module1/03_networking/solution_task_2_dhcp.md b/module1/03_networking/solution_task_2_dhcp.md deleted file mode 100644 index 712a04f..0000000 --- a/module1/03_networking/solution_task_2_dhcp.md +++ /dev/null @@ -1,64 +0,0 @@ -# Задание 2 - -0. Узнайте статус сервиса `systemd-networkd`. -``` -# systemctl status systemd-networkd -``` - -1. Активируйте `systemd-networkd`, если он не активирован (disabled). -``` -# systemctl enable systemd-networkd -``` - -2. Запустите `systemd-networkd`, если он не запущен (inactive, dead). -``` -# systemctl start systemd-networkd -``` - -3. Определите имя настраиваемого интерфейса (не loopback). -``` -# ip link -``` - -4. Для настройки интерфейса `ens18` машин `stud1-1v1` и `stud1-2v1` создайте -или отредактируйте в каждой `/etc/systemd/network/ens18.network`. - -конфигурация `ens18.network` машины `stud1-1v1` с DHCP сервером. -``` -[Match] -Name=ens18 - -[Network] -Address=192.168.1.1/24 -DHCPServer=yes -``` - -конфигурация `ens18.network` машины `stud1-2v1`, которая получает адрес от DHCP сервера. -``` -[Match] -Name=ens18 - -[Network] -DHCP=yes -``` - -5. Перечитайте конфигурацию сети на обеих машинах. -``` -# networkctl reload -``` - -6. После конфигурации на обеих машинах проверьте их взаимную доступность по сети. -На машине `stud1-2v1` определите выданный DHCP сервером ip адрес для интерфейса `ens18`. -``` -ip a -``` - -``` -stud@stud1-2v1$ ping 192.168.1.1 -stud@stud1-1v1$ ping 192.168.1.X -``` - -7. В случае проблемы, проверьте, что `systemd-networkd` запущен и в его логах нет ошибок. -``` -# systemctl status systemd-networkd -``` \ No newline at end of file diff --git a/module1/03_networking/solution_task_3_internet.md b/module1/03_networking/solution_task_3_internet.md deleted file mode 100644 index 8b96741..0000000 --- a/module1/03_networking/solution_task_3_internet.md +++ /dev/null @@ -1,76 +0,0 @@ -# Задание 3 - -0. Узнайте статус сервиса `systemd-networkd` и `systemd-resolved` -``` -# systemctl status systemd-networkd -# systemctl status systemd-resolved -``` - -1. Активируйте `networkd`, если он не активирован (disabled) -``` -# systemctl enable systemd-networkd -# systemctl enable systemd-resolved -``` - -2. Запустите `networkd`, если он не запущен (inactive, dead) -``` -# systemctl start systemd-networkd -# systemctl start systemd-resolved -``` - -3. Определите имя настраиваемого интерфейса (не loopback). -``` -# ip link -``` - -4. Для настройки интерфейса `ens18` машины `stud1-2v1` создайте -или отредактируйте в каждой `/etc/systemd/network/ens18.network`. -Адрес машины должен быть взят из такой сети, в которой присутствует шлюз в -интернет `10.160.179.1`. - -конфигурация `ens18.network` машины stud1-2v1 -``` -[Match] -Name=ens18 - -[Network] -Address=10.160.179.201/24 -Gateway=10.160.179.1 -``` - -5. Перечитайте конфигурацию сети -``` -# networkctl reload -``` - -6. Проверьте доступность ip-адреса в сети internet -``` -stud@stud1-2v1$ ping 1.1.1.1 -``` - -7. Для настройки DNS `ens18` машины `stud1-2v1` отредактируйте -/etc/systemd/resolved.conf. - -конфигурация `resolved.conf` машины `stud1-2v1` -``` -[Resolve] -DNS=1.1.1.1 -``` - -8. Перезагрузите `systemd-resolved` -``` -# systemctl restart systemd-resolved -``` - -9. Проверьте доступность адреса по имени -``` -stud@stud1-2v1$ ping yandex.ru -``` - -10. В случае проблемы, проверьте, что `systemd-networkd` запущен, -`systemd-resolved` запущен, DNS настроен. -``` -# systemctl status systemd-networkd -# systemctl status systemd-resolved -# resolvectl status -``` \ No newline at end of file diff --git a/module1/03_networking/solution_task_4_tcpdump.md b/module1/03_networking/solution_task_4_tcpdump.md deleted file mode 100644 index 72310b1..0000000 --- a/module1/03_networking/solution_task_4_tcpdump.md +++ /dev/null @@ -1,7 +0,0 @@ -# Задание 4 - -``` -tcpdump arp -i ens18 -tcpdump icmp -i ens18 -tcpdump tcp -i ens18 -``` \ No newline at end of file diff --git a/module1/04_systemd/solutions.md b/module1/04_systemd/solutions.md deleted file mode 100644 index 71072fd..0000000 --- a/module1/04_systemd/solutions.md +++ /dev/null @@ -1,226 +0,0 @@ - -# Задание 1 - -0. Если у вас есть машина с графической оболочкой, в консоли перейдите в уровень запуска multi-user.target без перезагрузки, а затем обратно graphical.target. -``` -# systemctl isolate multi-user.target -# systemctl isolate graphical.target -``` - -1. Если у вас есть машина с графической оболочкой, перейдите в уровень запуска multi-user.target с перезагрузкой, а затем переключитесь в графическую оболочку обратно. -``` -# systemctl set-default multi-user.target -# reboot -# systemctl set-default graphical.target -# reboot -``` - -2. Выведите модуль, который активируется по-умолчанию. -``` -# systemctl get-default -``` - -3. Выведите возможные состояния модулей командой systemctl --state=help. -``` -# systemctl --state=help -``` - -4. Найдите в man странице какие типы модулей есть в systemd. -``` -# man systemctl - The following unit types are available: - 1. Service units, which start and control daemons and the processes they consist of. For details, see systemd.service(5). - 2. Socket units, which encapsulate local IPC or network sockets in the system, useful for socket-based activation. For details about socket units, see systemd.socket(5), for details on socket-based activation and other forms of activation, see daemon(7). - 3. Target units are useful to group units, or provide well-known synchronization points during boot-up, see systemd.target(5). - 4. Device units expose kernel devices in systemd and may be used to implement device-based activation. For details, see - systemd.device(5). - 5. Mount units control mount points in the file system, for details see systemd.mount(5). - 6. Automount units provide automount capabilities, for on-demand mounting of file systems as well as parallelized boot-up. See - systemd.automount(5). - 7. Timer units are useful for triggering activation of other units based on timers. You may find details in systemd.timer(5). - 8. Swap units are very similar to mount units and encapsulate memory swap partitions or files of the operating system. They are - described in systemd.swap(5). - 9. Path units may be used to activate other services when file system objects change or are modified. See systemd.path(5). - 10. Slice units may be used to group units which manage system processes (such as service and scope units) in a hierarchical tree for resource management purposes. See systemd.slice(5). - 11. Scope units are similar to service units, but manage foreign processes instead of starting them as well. See systemd.scope(5). -``` - -5. Выведите список установленных модулей. -``` -# systemctl list-unit-files -``` - -6. Деактивируйте сервис timesyncd. -``` -# systemctl disable systemd-timesyncd -``` - -7. Перезагрузите сервис timesyncd. -``` -# systemctl restart systemd-timesyncd -``` - -8. Выведите список модулей в памяти. -``` -# systemctl disable systemd-timesyncd -``` - -9. Проверьте, что сервис timesyncd активирован. -``` -# systemctl is-enabled systemd-timesyncd -``` - -10. Выведите список зависимых модулей для сервиса timesyncd. -``` -# systemctl list-dependencies systemd-timesyncd -``` - -11. Выведите список сокетов в памяти. -``` -# systemctl list-sockets -``` - -12. Выведите список таймеров в памяти. -``` -# systemctl list-timers -``` - -13. Проверьте статус сервиса timesyncd. -``` -# systemctl status systemd-timesyncd -``` - -14. Проверьте, что сервис timesyncd активен. -``` -# systemctl is-active systemd-timesyncd -``` - -15. Выведите список свойств модуля. -``` -# systemctl show systemd-timesyncd -``` - -16. Выведите уровень логирования для сервиса timesyncd. -``` -# systemctl service-log-level systemd-timesyncd -``` - -17. Перезагрузите конфигурацию systemd менеджера: перезапустите генераторы (systemd.generator), все модули и перестройте дерево зависимостей. -``` -# systemctl daemon-reload -``` - -18. Какие префиксы можно использовать при указании исполняемых файлов в файлах .service. -``` -# man systemd.service -Table 1. Special executable prefixes - ┌───────┬──────────────────────────────────────────────────┐ - │Prefix │ Effect │ - ├───────┼──────────────────────────────────────────────────┤ - │"@" │ If the executable path is prefixed with "@", the │ - │ │ second specified token will be passed as │ - │ │ "argv[0]" to the executed process (instead of │ - │ │ the actual filename), followed by the further │ - │ │ arguments specified. │ - ├───────┼──────────────────────────────────────────────────┤ - │"-" │ If the executable path is prefixed with "-", an │ - │ │ exit code of the command normally considered a │ - │ │ failure (i.e. non-zero exit status or abnormal │ - │ │ exit due to signal) is recorded, but has no │ - │ │ further effect and is considered equivalent to │ - │ │ success. │ - ├───────┼──────────────────────────────────────────────────┤ - │":" │ If the executable path is prefixed with ":", │ - │ │ environment variable substitution (as described │ - │ │ by the "Command Lines" section below) is not │ - │ │ applied. │ - ├───────┼──────────────────────────────────────────────────┤ - │"+" │ If the executable path is prefixed with "+" then │ - │ │ the process is executed with full privileges. In │ - │ │ this mode privilege restrictions configured with │ - │ │ User=, Group=, CapabilityBoundingSet= or the │ - │ │ various file system namespacing options (such as │ - │ │ PrivateDevices=, PrivateTmp=) are not applied to │ - │ │ the invoked command line (but still affect any │ - │ │ other ExecStart=, ExecStop=, ... lines). │ - ├───────┼──────────────────────────────────────────────────┤ - │"!" │ Similar to the "+" character discussed above │ - │ │ this permits invoking command lines with │ - │ │ elevated privileges. However, unlike "+" the "!" │ - │ │ character exclusively alters the effect of │ - │ │ User=, Group= and SupplementaryGroups=, i.e. │ - │ │ only the stanzas that affect user and group │ - │ │ credentials. Note that this setting may be │ - │ │ combined with DynamicUser=, in which case a │ - │ │ dynamic user/group pair is allocated before the │ - │ │ command is invoked, but credential changing is │ - │ │ left to the executed process itself. │ - ├───────┼──────────────────────────────────────────────────┤ - │"!!" │ This prefix is very similar to "!", however it │ - │ │ only has an effect on systems lacking support │ - │ │ for ambient process capabilities, i.e. without │ - │ │ support for AmbientCapabilities=. It's intended │ - │ │ to be used for unit files that take benefit of │ - │ │ ambient capabilities to run processes with │ - │ │ minimal privileges wherever possible while │ - │ │ remaining compatible with systems that lack │ - │ │ ambient capabilities support. Note that when │ - │ │ "!!" is used, and a system lacking ambient │ - │ │ capability support is detected any configured │ - │ │ SystemCallFilter= and CapabilityBoundingSet= │ - │ │ stanzas are implicitly modified, in order to │ - │ │ permit spawned processes to drop credentials and │ - │ │ capabilities themselves, even if this is │ - │ │ configured to not be allowed. Moreover, if this │ - │ │ prefix is used and a system lacking ambient │ - │ │ capability support is detected │ - │ │ AmbientCapabilities= will be skipped and not be │ - │ │ applied. On systems supporting ambient │ - │ │ capabilities, "!!" has no effect and is │ - │ │ redundant. │ - └───────┴──────────────────────────────────────────────────┘ -``` - -# Задание 2 - -1. Настройте беспарольный доступ по ssh на localhost. Подтвердите добавление хоста в known_hosts. -``` -# ssh-keygen -# cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys -# ssh localhost -``` - -2. Сконфигурируйте сервис для прокси сервиса -``` -# systemctl edit socksproxy --full --force -``` - -содержимое /etc/systemd/system/socksproxy.service -``` -[Unit] -Description=SocksProxy -After=network.target - -[Service] -ExecStart=/usr/bin/ssh -N -D 0.0.0.0:80 localhost -Restart=always -RestartSec=5s - -[Install] -WantedBy=multi-user.target -``` - -3. Активируйте сервис и запустите -``` -# systemctl enable socksproxy -# systemctl start socksproxy -``` - -4. Проверьте, что socks сервер слушает порт 80 -``` -# netstat -tulpn -``` - -5. Определите свой внешний IP адрес на сайте https://2ip.ru/, -предварительно настроив в firefox плагине foxyproxy прокси сервер socks5 -с адресом 193.32.63.170 + X к последнему октету, где X идентификатор stud. \ No newline at end of file diff --git a/module1/05_hash_ciphers_ssh_certs/solutions.md b/module1/05_hash_ciphers_ssh_certs/solutions.md deleted file mode 100644 index 7e2536d..0000000 --- a/module1/05_hash_ciphers_ssh_certs/solutions.md +++ /dev/null @@ -1,228 +0,0 @@ -# Решения - -### 1. -Скачайте дистрибутив debian debian-11.4.0-amd64-netinst.iso c http://mirror.corbina.net/debian-cd/current/amd64/iso-cd/. -Рассчитайте хэш sha256 командой sha256sum для дистрибутива debian и проверьте целостность данных, сравнив значение -с значением в файле SHA256SUMS. -``` -$ sha256sum debian-11.4.0-amd64-netinst.iso -d490a35d36030592839f24e468a5b818c919943967012037d6ab3d65d030ef7f debian-11.4.0-amd64-netinst.iso -$ head -n1 SHA256SUMS -d490a35d36030592839f24e468a5b818c919943967012037d6ab3d65d030ef7f debian-11.4.0-amd64-netinst.iso -``` - -### 2. -Зашифруйте и расшифруйте данные с помощью openssl enc. Используйте команды: -``` -$ cat helloworld.txt -Hello world! -$ openssl enc -in helloworld.txt -out encrypted.data -e -aes256 -k password -$ cat encrypted.data -Salted__I���f���0�Z558�+�߮ -3�5���Urq��T� -$ openssl enc -d -aes-256-cbc -in encrypted.data -out un_encrypted.data -$ cat un_encrypted.data -Hello world! -2022 -``` - -### 3. -Зашифруйте и расшифруйте данные с помощью gpg. Используйте команды: -``` -$ cat helloworld.txt -Hello world! -$ gpg --output encrypted.data --symmetric --cipher-algo AES256 un_encrypted.data -$ cat encrypted_with_gpg.data -� ��Ȥ��P�� - P.W�{�Vu]x|M�C����l�@�s�k��c�N�}��|�Yn�����a}���d!I��_E�����x��I���� -$ gpg --output un_encrypted_with_gpg.data --decrypt encrypted_with_gpg.data -$ $ cat un_encrypted_with_gpg.data -Hello world! -2022 -``` - - -### 4. -Сгенерируйте ed25519 пару ключей `ssh-keygen -o -a 100 -t ed25519`. Перейдите в `~/.ssh/` и проверьте, появилась ли пара SSH-ключей. Настройте возможность беспарольного входа в систему по ssh, добавить содержимое публичного ключа (.pub) в `authorized_keys` в той же директории (создайте файл, если его не существует). -``` -$ ssh-keygen -o -a 100 -t ed25519 -Generating public/private ed25519 key pair. -Enter file in which to save the key (/home/stud/.ssh/id_ed25519): /home/stud/.ssh/4task_id_ed25519 -Enter passphrase (empty for no passphrase): -Enter same passphrase again: -Your identification has been saved in /home/stud/.ssh/4task_id_ed25519 -Your public key has been saved in /home/stud/.ssh/4task_id_ed25519.pub -The key fingerprint is: -SHA256:qzxgVYtYie5em9GC7q8mMX26LNEwEfEgsalIY0v8dEA stud@stud15 -The key's randomart image is: -+--[ED25519 256]--+ -|o.=E . . | -|.+.oo o . | -|o* +.+ o . | -|* B + o . | -|o. B o .S | -| + B = .. | -| B = =. | -| o.=.+. | -| ==++. | -+----[SHA256]-----+ -$ ls -4task_id_ed25519 4task_id_ed25519.pub authorized_keys id_rsa id_rsa.pub known_hosts -$ cat 4task_id_ed25519.pub >> authorized_keys -$ tail -n 1 authorized_keys -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ2O9POMD+URq+UkWUNgU475wvxmhTVPRkjAHq8DDLye stud@stud15 -$ ssh localhost -i /home/stud/.ssh/4task_id_ed25519 -Linux stud15 5.10.0-16-amd64 #1 SMP Debian 5.10.127-1 (2022-06-30) x86_64 - -The programs included with the Debian GNU/Linux system are free software; -the exact distribution terms for each program are described in the -individual files in /usr/share/doc/*/copyright. - -Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent -permitted by applicable law. -Last login: Wed Sep 7 20:02:39 2022 from 87.229.245.190 -``` - -### 5. -Используйте `ssh-copy-id имя-удаленной-машины`, чтобы скопировать ваш ssh-ключ на сервер. Перед установкой попробуйте команду -в тестовом режиме с ключём `-n`. -``` -$ ssh-copy-id -i 4task_id_ed25519 stud@193.32.63.185 -/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "4task_id_ed25519.pub" -/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed -/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys - -Number of key(s) added: 1 - -Now try logging into the machine, with: "ssh 'stud@193.32.63.185'" -and check to make sure that only the key(s) you wanted were added. -``` - -### 6. -Отредактируйте `.ssh/config` на локальной машине, чтобы запись выглядела следующим образом -``` -$ cat config -Host remote - User stud - HostName 193.32.63.185 - IdentityFile ~/.ssh/4task_id_ed25519 -$ ssh remote -Linux stud15 5.10.0-16-amd64 #1 SMP Debian 5.10.127-1 (2022-06-30) x86_64 - -The programs included with the Debian GNU/Linux system are free software; -the exact distribution terms for each program are described in the -individual files in /usr/share/doc/*/copyright. - -Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent -permitted by applicable law. -Last login: Wed Sep 7 20:17:07 2022 from ::1 -``` - -### 7. -Отредактируйте конфигурацию вашего SSH-сервера, выполнив `sudo vi /etc/ssh/sshd_config`. Отключите проверку по паролю, отредактировав значение `PasswordAuthentication`. Отключите вход с правами суперпользователя, отредактировав значение `PermitRootLogin`. Перезапустите службу ssh с помощью `sudo systemctl restart sshd`. - -Попробуйте подключиться ещё раз. Попробуйте подключиться ещё раз по паролю (добавьте флаг -o PubkeyAuthentication=no к ssh команде). -``` -$ cat /etc/ssh/sshd_config | grep -e '^\(PasswordAuthentication\|PermitRootLogin\)' -PermitRootLogin prohibit-password -PasswordAuthentication no -$ sudo systemctl restart sshd -$ ssh remote -o PubkeyAuthentication=no -stud@193.32.63.185: Permission denied (publickey). -``` - -### 8. -Сгенерируйте сертификат x.509 и ключ с помощью openssl. Посмотрите содержимое сертификата командой `openssl x509`. -``` -$ openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -nodes -days 365 -subj '/C=RU/ST=SamaraRegion/L=Samara/O=MyOffice/OU=SamaraDep/CN=myoffice.ru/' -$ openssl x509 -in cert.pem -noout -text -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 2a:f2:3c:06:38:97:cf:62:ac:62:7b:c6:c3:81:2a:47:9f:42:35:2d - Signature Algorithm: sha256WithRSAEncryption - Issuer: C = RU, ST = SamaraRegion, L = Samara, O = MyOffice, OU = SamaraDep, CN = myoffice.ru - Validity - Not Before: Sep 7 14:45:39 2022 GMT - Not After : Sep 7 14:45:39 2023 GMT - Subject: C = RU, ST = SamaraRegion, L = Samara, O = MyOffice, OU = SamaraDep, CN = myoffice.ru - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - RSA Public-Key: (4096 bit) - Modulus: - 00:bf:d8:c2:27:aa:29:70:69:33:c5:59:82:a7:b8: - b2:a3:48:03:04:e2:c8:f9:f3:16:97:cf:9d:f8:12: - a4:81:3f:a4:52:60:e4:ab:5e:4c:c9:85:18:1d:fa: - a7:be:82:f7:db:b4:9e:6b:b2:ab:87:89:44:1f:5e: - 01:b5:6a:4a:37:e3:b2:da:5f:a4:63:80:92:49:36: - f2:dc:f9:75:75:65:56:6c:5d:10:86:32:0b:ee:a0: - b3:83:17:ef:c6:59:19:95:11:47:67:3b:65:96:ee: - 31:52:c3:b3:6e:cf:ee:dc:05:3e:c0:6c:34:e9:3c: - f6:58:95:3c:38:3e:8c:3a:e2:d1:a8:41:a4:e8:85: - 72:29:76:bb:32:1c:b7:3c:0c:f7:4d:e6:ed:31:16: - 9e:61:d1:60:69:1d:2f:f5:cb:f1:a3:f2:ac:b0:91: - a1:6b:16:33:26:cc:83:70:bb:9b:82:43:f8:f9:38: - 81:06:94:8f:ca:2b:b3:5b:77:78:72:f6:d0:c7:3c: - 45:b1:4e:74:bf:b9:68:09:02:f7:4f:d0:4a:3f:39: - 92:40:66:cf:b2:05:24:66:12:ae:ae:9d:1a:91:3c: - ad:78:cd:a8:6b:6e:9f:72:1f:0a:ca:7d:6a:21:09: - 43:2b:48:93:dc:d2:02:d4:2d:e0:8e:47:22:64:47: - 21:af:7c:e4:2b:ec:ed:93:59:c5:38:26:5e:0d:4e: - 5c:4f:58:c1:7f:26:5b:b5:c2:e7:1c:84:c3:15:a7: - 46:28:62:98:65:27:f2:4a:85:61:f0:c7:94:7b:6c: - f1:b6:35:65:9f:7c:d0:bb:8c:26:53:2a:55:01:cd: - 62:7d:bf:39:ac:4d:6b:16:46:59:e4:e1:bb:b1:6e: - 5e:ee:15:07:a1:97:c6:99:99:55:de:7d:6a:5d:f3: - 56:d3:db:41:e5:27:ea:ac:4e:fe:ce:4e:07:76:71: - 31:bd:d7:fe:e7:f1:2d:25:85:d8:ef:29:d6:6b:89: - 43:64:8a:da:38:ac:cb:75:8d:f1:0d:cd:d3:dd:eb: - 2f:f8:39:8b:a0:f0:6d:37:35:cf:96:fb:21:37:ff: - ef:3a:2b:69:d5:00:f4:e0:78:c9:59:01:a9:0b:c2: - 7d:b9:80:ef:59:33:b5:c9:d9:0a:e8:ce:ef:20:61: - dc:a0:f2:ec:ef:23:a0:6b:fe:ae:30:c9:d6:03:cd: - 28:f1:7a:b4:28:40:06:ce:0e:90:83:5b:21:c9:ec: - 51:1f:d3:1a:ef:ab:81:20:de:3d:c6:bc:0c:58:68: - 01:2e:90:6d:47:90:a4:ff:5b:e1:20:02:ba:dc:bf: - 5f:97:db:85:df:d7:03:10:6a:2b:f2:f2:2f:7d:ef: - 25:f2:15 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Subject Key Identifier: - D2:BD:FB:B0:4E:09:4F:99:67:C4:8A:D3:A2:1B:14:78:51:B8:B1:5B - X509v3 Authority Key Identifier: - keyid:D2:BD:FB:B0:4E:09:4F:99:67:C4:8A:D3:A2:1B:14:78:51:B8:B1:5B - - X509v3 Basic Constraints: critical - CA:TRUE - Signature Algorithm: sha256WithRSAEncryption - 44:b0:16:b3:4b:82:1a:5a:35:a1:a9:bd:51:96:2d:b5:24:41: - ec:66:c6:4c:fb:60:c0:f1:8c:8f:e0:c2:82:30:8b:b3:ff:c1: - 47:01:f9:94:a0:ed:05:9e:b3:21:3c:b4:6c:8c:ae:91:c8:d5: - f5:2c:7f:66:74:2d:67:e1:09:05:52:d2:bf:92:b5:b2:17:ec: - 5c:c6:de:4d:36:76:73:38:ad:0a:4d:b7:37:b0:2a:0e:81:cd: - 55:dd:46:d2:44:1d:e0:26:b3:44:bc:c0:15:b7:55:77:b2:16: - 0e:00:db:c4:67:24:aa:ce:c8:10:e3:8a:9c:8c:1a:a1:8d:17: - 0e:df:53:84:bb:88:fe:b6:17:f5:a7:b4:48:f3:71:f9:d0:e9: - e9:fc:0b:88:d2:a8:7b:ac:2b:d1:f6:38:e5:ce:95:54:30:c9: - 25:7b:35:a1:2d:12:f9:97:d1:0e:33:d8:21:19:3e:40:40:ed: - 58:e2:b5:4b:25:f1:f4:d2:26:76:e9:69:c0:9f:28:72:b9:84: - 04:9a:2f:38:b1:89:28:96:f5:03:a1:d3:e7:80:12:87:4b:86: - ac:83:91:47:8b:f7:af:66:92:9b:6d:5d:c4:53:55:5a:f8:04: - 0f:a6:8a:8a:e1:99:8c:8f:6a:ec:c2:48:6e:9b:6a:91:2b:af: - 34:3e:91:3e:ae:7d:94:d5:9a:53:51:2f:ef:d2:45:b9:01:f3: - 13:e3:4e:83:36:2e:a6:15:5b:52:1d:03:5a:f8:cf:27:58:8f: - a4:37:1d:98:d8:4f:20:f0:ac:3b:57:3f:60:a8:35:fc:46:b4: - e1:41:57:47:0f:f7:f3:cb:a9:52:c9:fb:32:c5:39:fb:0c:bf: - 92:1c:71:d5:29:d6:11:e3:97:59:d2:61:72:c4:27:cb:c3:0b: - df:f9:70:10:b2:18:01:76:85:a9:78:df:ad:83:72:64:08:a5: - 71:1f:75:6e:95:6a:39:14:2d:4f:96:1d:ae:55:d0:7f:70:be: - 74:68:e8:9b:0e:0f:76:9d:d5:a5:e8:02:22:ee:7d:19:23:03: - 87:c7:ad:18:60:d4:4d:b8:64:84:ae:51:12:bc:4e:af:81:18: - 74:6f:1d:47:f6:59:52:ab:74:f9:20:be:fc:5e:0c:e9:bd:25: - e7:21:af:a4:69:6a:1e:e3:e4:1e:8c:80:b0:e4:0c:c3:0f:86: - f2:a0:b1:d9:66:3d:30:36:26:31:77:81:c9:e2:ca:2c:ae:f5: - 07:56:d5:00:e4:09:37:5c:7d:a0:fc:79:f7:ea:fe:67:72:2e: - 29:6d:d5:11:e9:bc:8a:63:20:1d:96:af:f9:85:1c:43:22:5e: - 01:02:37:28:b1:dd:01:93 -``` \ No newline at end of file diff --git a/module1/06_user_management/solutions.md b/module1/06_user_management/solutions.md deleted file mode 100644 index e2bddcc..0000000 --- a/module1/06_user_management/solutions.md +++ /dev/null @@ -1,200 +0,0 @@ -# Решения - -### 1. -Создайте пользователя mike. При создании задайте в качестве оболочки `/bin/bash`. Создайте домашнюю директорию вручную для mike, в `/home/mike`. Смените владельца командой `chown mike:mike /home/mike`. -``` -$ sudo useradd mike --shell /bin/bash -$ sudo su - mike -su: warning: cannot change directory to /home/mike: No such file or directory -``` -Зайти под пользователем mike теперь можно. Без домашней директории не будет сохраняться история команд, а также нельзя настроить -оболочку. Например, активировать пользовательские псевдонимы при входе. -``` -$ sudo mkdir /home/mike -$ sudo su - mike -$ touch ~/1 -touch: cannot touch '/home/mike/1': Permission denied -$ sudo chown mike:mike /home/mike -$ touch ~/1 -``` -В этом случае домашняя папка пользователя не будет содержать скрытые конфигурационные файлы, которые копируются из директории -`/etc/skel/` (переменная SKEL в `/etc/default/useradd`) при вызове useradd с флагом `--create-home` . - -### 2. -Деактивируйте аккаунт stud, поменяв оболочку на `/sbin/nologin`. В соседнем окне, проверьте, что залогиниться вы не можете. Попробуйте варианты через `sudo su -`, `su -`, по ssh. Верните оболочку в прежнее значение. -``` -$ sudo usermod --shell /sbin/nologin stud -$ ssh s15 -Linux stud15 5.10.0-16-amd64 #1 SMP Debian 5.10.127-1 (2022-06-30) x86_64 - -The programs included with the Debian GNU/Linux system are free software; -the exact distribution terms for each program are described in the -individual files in /usr/share/doc/*/copyright. - -Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent -permitted by applicable law. -Last login: Thu Sep 8 22:23:46 2022 from 46.0.144.27 -This account is currently not available. -Connection to 193.32.63.185 closed. -$ su --login stud -This account is currently not available. -stud@stud15:~$ sudo su --login stud -This account is currently not available. -``` - -### 3. -Смените пароль пользователя `mike` командой `passwd` из под суперпользователя. Проверьте, что вы можете зайти под этим пользователем с заданным паролем. -``` -$ sudo passwd mike -551e-2022 -$ su - mike -Password: 551e-2022 -mike@stud15:~$ -``` - -### 4. -Измените в `/etc/default/useradd` оболочку по умолчанию на `/bin/bash`. -``` -$ cat /etc/default/useradd | grep ^SHELL -SHELL=/bin/bash -``` - -### 5. -Измените в `/etc/login.defs` `UID_MIN` на `10000`, `UMASK` на `077`. -``` -$ cat /etc/login.defs | grep '^\(UID_MIN\|UMASK\)' -UMASK 077 -UID_MIN 10000 -``` - -### 6. -Создайте пользователя vera с заданным паролем и укажите, что нужно создать домашнюю директорию пользователя. При создании используйте заранее созданный пароль в зашифрованном виде. Для шифрования пароля используйте команду `openssl passwd -5 -stdin`. После создания проверьте номер идентификатора пользователя и путь к оболочке в файле `/etc/passwd`, хэш-пароль в `/etc/shadow`, атрибуты доступа к домашней директории в `/home`. -``` -$ echo 'Vera-@)$-2022' | openssl passwd -5 -stdin -$5$zW1zNyUcDCT86mmZ$khDXsCyzBJ/5WeZN9AaARXBdlQaMnVZUzj/WXRDffo5 -$ sudo useradd vera -p '$5$zW1zNyUcDCT86mmZ$khDXsCyzBJ/5WeZN9AaARXBdlQaMnVZUzj/WXRDffo5' --create-home -$ ls -l /home/ -total 12 -drwxr-xr-x 2 mike mike 4096 сен 8 22:00 mike -drwxr-xr-x 11 stud stud 4096 сен 8 23:33 stud -drwx------ 2 vera vera 4096 сен 8 23:47 vera -$ ls /home/vera -ls: cannot open directory '/home/vera': Permission denied -$ grep vera /etc/passwd -vera:x:10000:10000::/home/vera:/bin/bash -$ grep mike /etc/passwd -mike:x:1001:1001::/home/mike:/bin/bash -$ sudo grep vera /etc/shadow -vera:$5$zW1zNyUcDCT86mmZ$khDXsCyzBJ/5WeZN9AaARXBdlQaMnVZUzj/WXRDffo5:19243:0:99999:7::: -$ su - vera -Password: Vera-@)$-2022 -vera@stud15:~$ -$ ls -la -total 20 -drwx------ 2 vera vera 4096 сен 8 23:47 . -drwxr-xr-x 5 root root 4096 сен 8 23:47 .. --rw-r--r-- 1 vera vera 220 мар 27 22:40 .bash_logout --rw-r--r-- 1 vera vera 3526 мар 27 22:40 .bashrc --rw-r--r-- 1 vera vera 807 мар 27 22:40 .profile -``` - -Мы видим, что никто кроме пользователя vera не имеет доступа к домашней директории. Идентификатор пользователя vera после создания предыдущего пользователя mike увеличился сразу до значения 10000, вместо 1002. Пароль в зашифрованном виде был сохранён в файл `/etc/shadow`. В домашней папке пользователя vera появилось три файла из `/etc/skel`. - -### 7. -Поменяйте оболочку пользователя vera на `/bin/sh`. -``` -$ sudo usermod --shell /bin/sh vera -``` - -### 8. -Сконфигурируйте пользователя `mike` так, чтобы он мог перейти в суперпользователя, зная свой пароль. Справочная документация для этой задачи `man sudoers` и полезная команда `usermod`. -``` -$ sudo usermod -G sudo mike -``` - -### 9. -Смените пароль пользователя `mike` командой `chpasswd`. -``` -$ echo 'mike:Mike-@)$-2022' | sudo chpasswd -$ su - mike -Password: -mike@stud15:~$ -``` - -Обратите внимание на одинарные кавычки. При использовании двойных кавычек bash интерпретирует специальные символы, такие как $, что привело бы к установке неверного пароля. - -### 10. -Создайте и удалите пользователя `dummy`. -``` -$ useradd dummy -$ userdel dummy -$ grep dummy /etc/passwd -``` - -### 11. -Создайте группу `docker` и добавьте в неё пользователей `mike` и `vera`. -``` -$ grep mike /etc/group -sudo:x:27:stud,mike -mike:x:10000: -$ sudo groupadd docker -$ sudo usermod -a -G docker mike -$ sudo gpasswd -a vera docker -$ grep -E 'mike|vera' /etc/group -sudo:x:27:stud,mike -mike:x:10000: -vera:x:10001: -docker:x:10002:vera,mike -``` - -### 12. -Удалите пользователя `mike` из группы `docker`. - -Первый вариант использовать `gpasswd`. -``` -$ gpasswd -d mike docker -``` -Второй вариант в `usermod -G` указать только те группы, в который пользователь должен находиться. -``` -$ sudo usermod -G sudo mike -``` -Третий вариант удалить пользователя на строке группы из списка после последнего `:` в файле `/etc/group`. - -### 13. -Заблокируйте аккаунт пользователя `mike` командой `usermod` или модифицировав файл `/etc/shadow`. -``` -$ sudo usermod -L mike -$ sudo grep mike /etc/shadow -mike:!$y$j9T$gqE0awjHPMO9IqeWOEdVp0$y5KrjzQfqoOyLy5j68kEte16MvKAs1Rl.IMeIohAnHC:19243:0:99999:7::: -$ su - mike -Password: -su: Authentication failure -``` -Знак `!` перед хэшем пароля означает, что аккаунт заморожен. - -### 14. -Настройте пользователя со своим именем на виртуальной машине `stud14`. Зайдите под ним на какое-то время. Посмотрите кто ещё зашёл на машину. Проверьте кто заходил на эту машину ранее командой `last`. -``` -stud@stud14:~$ who -stud pts/1 2022-09-09 00:43 (46.0.124.17) -stud@stud14:~$ last -n 10 -stud pts/1 46.0.124.17 Fri Sep 9 00:43 still logged in -stud pts/4 87.229.245.190 Thu Sep 8 19:04 - 19:05 (00:00) -stud pts/3 87.229.245.190 Thu Sep 8 19:04 - 21:25 (02:20) -stud pts/0 87.229.245.190 Thu Sep 8 19:04 - 19:06 (00:02) -stud pts/3 87.229.245.190 Thu Sep 8 18:59 - 19:04 (00:04) -stud pts/3 87.229.245.190 Thu Sep 8 18:59 - 18:59 (00:00) -stud pts/3 87.229.245.190 Thu Sep 8 18:57 - 18:57 (00:00) -tim pts/3 87.229.245.190 Thu Sep 8 18:42 - 18:49 (00:06) -stud pts/7 87.229.245.190 Thu Sep 8 18:41 - 18:57 (00:16) -stud pts/3 87.229.245.190 Thu Sep 8 18:40 - 18:42 (00:01) -``` - - -### 15. -Сыграйте с коллегой в игру. Сначала зайдите на свои виртуальные машины. Зайдите друг к другу на виртуальную машину по ssh. Попробуйте первым отключить соседа от виртуальной машины. -``` -$ who -u -$ sudo kill -9 -$ sudo usermod -L -``` \ No newline at end of file diff --git a/module1/07_file_permissions/solutions.md b/module1/07_file_permissions/solutions.md deleted file mode 100644 index 4fb3d36..0000000 --- a/module1/07_file_permissions/solutions.md +++ /dev/null @@ -1,212 +0,0 @@ -# Решения - -### 1. -Создайте папку `projects` в корне системы с правами `rwx` для владельца, группы и других пользователей. Установите на неё `stickybit`. -``` -sudo mkdir /projects -m 1777 -``` - -### 2. -Работая от пользователя `stud` в папке `projects` создайте папку с вашим проектом. Проверьте, что владелец может записать файл в неё. Проверьте, что `mike` или `vera` могут прочитать содержимое, но не могу записать в неё. -``` -mike@stud15:/projects$ tree -. -└── project_stud - └── main.c - -1 directory, 1 file -mike@stud15:/projects$ cat project_stud/main.c -hello -mike@stud15:/projects$ touch project_stud/test -touch: cannot touch 'project_stud/test': Permission denied -``` - -### 3. -В `projects` создайте ещё одну папку с проектом `project2`. Дайте к ней доступ на чтение только пользователям из группы `best_project_team`. Создайте группу `best_project_team` в которую входит `mike` и `stud`. Перезайдите в аккаунт, чтоб применить изменения членства в группе. Проверьте, что доступа к папке у пользователя `vera` нет. -``` -stud@stud15:~$ sudo groupadd best_project_team -stud@stud15:~$ sudo usermod -aG best_project_team mike -stud@stud15:~$ sudo usermod -aG best_project_team stud -stud@stud15:~$ mkdir /projects/project2 -stud@stud15:~$ chmod 770 /projects/project2 -stud@stud15:~$ chown stud:best_project_team /projects/project2 -vera@stud15:~$ cat /projects/project2/testfile -``` - -### 4. -Создайте третью и четвёртую папки от пользователя `mike` и `vera` в `/projects` и сделайте их полностью приватными. Добавьте в каждую директорию по одному файлу. Проверьте может ли `mike` или vera посмотреть содержимое чужого приватного проекта. -``` -root@stud15:~# su - vera -vera@stud15:/projects$ mkdir /projects/vera_project -vera@stud15:/projects$ chmod 700 /projects/vera_project/ -vera@stud15:/projects$ echo "hello from vera" > /projects/vera_project/readme - -root@stud15:~# su - mike -mike@stud15:/projects$ mkdir mike_project -mike@stud15:/projects$ chmod 700 mike_project/ -mike@stud15:/projects/mike_project$ echo "hello from mike" > readme - -mike@stud15:/projects/mike_project$ cat /projects/mike_project/readme -hello from mike -mike@stud15:/projects/mike_project$ cat /projects/vera_project/readme -cat: /projects/vera_project/readme: Permission denied -``` - -### 5. -Проверьте может ли mike удалить папку с чужим проектом? Может ли он удалить свою папку? Уберите stickybit у папки /projects. А теперь может ли mike удалить папку, созданную vera или stud? Влияет ли на возможность удаления наличие в папке файлов? -```bash -mike@stud15:/projects/mike_project$ rm -rf /projects/vera_project/ -rm: cannot remove '/projects/vera_project/': Operation not permitted -mike@stud15:/projects/mike_project$ rm -rf /projects/mike_project/ -mike@stud15:/projects$ ls -la -total 20 -drwxrwxrwt 5 root root 4096 окт 1 17:59 . -drwxr-xr-x 21 root root 4096 окт 1 12:13 .. -drwxrwx--- 2 stud best_project_team 4096 окт 1 12:24 project2 -drwxr-xr-x 2 stud stud 4096 окт 1 12:16 project_stud -drwx------ 2 vera vera 4096 окт 1 17:54 vera_project - -# без файлов в директории vera_project -mike@stud15:~$ rm -rf /projects/vera_project/ -mike@stud15:~$ ls -l /projects/ -total 8 -drwxrwx--- 2 stud best_project_team 4096 окт 1 12:24 project2 -drwxr-xr-x 2 stud stud 4096 окт 1 12:16 project_stud -mike@stud15:~$ ls -l /projects/ -``` - -### 6. -От `root` cоздайте ещё одну общую директорию `shared` в `/home/`. Создайте группу `shared_files` c большим значением идентификатора, например 70000, в которую входят `mike`, `vera` и `stud`. Поменяйте владельца `/home/shared` на `nobody`, а владельца-группу на `shared_files`. Установите полные права доступа для владельца и группы владельца. Все остальным запретите доступ к папке. Также установите бит `SGID`. -```bash -root@stud15:/home# mkdir /home/shared -root@stud15:/home# groupadd shared_files --gid 70000 -root@stud15:/home# usermod -aG shared_files mike -root@stud15:/home# usermod -aG shared_files vera -root@stud15:/home# usermod -aG shared_files stud -root@stud15:/home# cat /etc/group | grep shared -shared_files:x:70000:stud,vera,mike -root@stud15:/home# ls -l | grep shared -drwxrws--- 2 nobody shared_files 4096 сен 9 16:43 shared -``` - -Создайте несколько файлов под разными аккаунтами в этой папке и проверьте, что они имеют владельца-группу shared_files. -```bash -root@stud15:/home# su --login mike --command "mkdir /home/shared/mike_data" -root@stud15:/home# su --login vera --command "mkdir /home/shared/vera_data" -root@stud15:/home# su --login stud --command "mkdir /home/shared/stud_data" -root@stud15:/home# ls -la shared/ -total 20 -drwxrws--- 5 nobody shared_files 4096 окт 1 18:26 . -drwxr-xr-x 13 root root 4096 сен 15 11:47 .. --rw-r--r-- 1 stud shared_files 0 сен 9 16:42 1 --rw-r--r-- 1 mike shared_files 0 сен 9 16:42 2 --rw-rw-r-- 1 stud shared_files 0 сен 9 16:43 3 -drwxr-sr-x 2 mike shared_files 4096 окт 1 18:25 mike_data -drwxr-sr-x 2 stud shared_files 4096 окт 1 18:26 stud_data -drwxr-sr-x 2 vera shared_files 4096 окт 1 18:26 vera_data -``` - -### 7. -Узнайте значение `umask` одноимённой командой. Создайте папку и файл c именем `test_$(umask)`. Выведите атрибуты файла. Измените umask одноимённой командой на `0002`. Повторите создание папки и файла и сравните атрибуты файлов, созданных с разными масками. -```bash -stud@stud15:/home/shared$ umask -0022 -stud@stud15:/home/shared$ touch test_$(umask) -stud@stud15:/home/shared$ stat test_0022 - File: test_0022 - Size: 0 Blocks: 0 IO Block: 4096 regular empty file -Device: 801h/2049d Inode: 1177656 Links: 1 -Access: (0644/-rw-r--r--) Uid: ( 1000/ stud) Gid: ( 1002/shared_files) -Access: 2022-10-01 18:28:21.509800524 +0400 -Modify: 2022-10-01 18:28:21.509800524 +0400 -Change: 2022-10-01 18:28:21.509800524 +0400 - Birth: 2022-10-01 18:28:21.509800524 +0400 -stud@stud15:/home/shared$ umask 0002 -stud@stud15:/home/shared$ touch test_$(umask) -stud@stud15:/home/shared$ stat test_0002 - File: test_0002 - Size: 0 Blocks: 0 IO Block: 4096 regular empty file -Device: 801h/2049d Inode: 1177657 Links: 1 -Access: (0664/-rw-rw-r--) Uid: ( 1000/ stud) Gid: ( 1002/shared_files) -Access: 2022-10-01 18:28:45.002074124 +0400 -Modify: 2022-10-01 18:28:45.002074124 +0400 -Change: 2022-10-01 18:28:45.002074124 +0400 - Birth: 2022-10-01 18:28:45.002074124 +0400 -``` - -### 8. -Под `root` скопируйте `bash` `cp /bin/bash /bin/my_unsecure_bash` и установите атрибуты файла в значение `4755`. Значение 4 соответствует биту `SUID`. Посмотрите на результат командой `stat`. Создайте файл-скрипт `gen_file_root.sh` в папке `/tmp` от пользователя `mike` со следующим содержимым: -```bash -#!/bin/my_unsecure_bash -p -touch /tmp/root_$RANDOM -``` -Сделайте его исполняемым для всех. Вызовите скрипт от пользователя `stud`. Обратите внимание на владельца созданного файла `/tmp/root_*`. Как на него повлиял `SUID`? Установите `SUID` на `gen_file_root.sh`, сгенерируйте новый файл. Есть ли изменения в поле владельца? -``` -root@stud15:/tmp# stat /bin/my_unsecure_bash - File: /bin/my_unsecure_bash - Size: 1234376 Blocks: 2416 IO Block: 4096 regular file -Device: 801h/2049d Inode: 1842926 Links: 1 -Access: (4755/-rwsr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root) -Access: 2022-09-09 15:07:30.407667000 +0400 -Modify: 2022-09-09 15:04:36.207672558 +0400 -Change: 2022-09-09 15:04:59.031671752 +0400 - Birth: 2022-09-09 15:04:36.171672558 +0400 -root@stud15:/tmp# chmod 777 /tmp/gen_file_root.sh -root@stud15:/tmp# su - stud - -stud@stud15:~$ cd /tmp/ -stud@stud15:/tmp$ ./gen_file_root.sh -stud@stud15:/tmp$ ./gen_file_root.sh -stud@stud15:/tmp$ ./gen_file_root.sh -stud@stud15:/tmp$ ls -l -total 16 --rwxrwxrwx 1 root root 51 окт 1 18:33 gen_file_root.sh --rw-r--r-- 1 stud stud 33 окт 1 11:34 log --rw-r--r-- 1 root stud 0 окт 1 18:39 root_29247 --rw-r--r-- 1 root stud 0 окт 1 18:39 root_32039 --rw-r--r-- 1 root stud 0 окт 1 18:39 root_9235 -``` - -### 9. -В каталоге `/projects` создайте файл `test` в папках `1`, `2`, `3`. Поменяйте для папок атрибуты доступа для категории `other`: `r--`, `r-x`, `--x` соответственно. Зайдите под другого пользователя, который входит в категорию `other` и попробуйте найти файл с помощью `find`, начиная с каталога `/projects`. Попробуйте найти слово в содержимом файлов. Как влияют атрибуты на возможность поиска? -``` -stud@stud15:/projects$ mkdir 1 -stud@stud15:/projects$ mkdir 2 -stud@stud15:/projects$ mkdir 3 -stud@stud15:/projects$ chmod 704 1 -stud@stud15:/projects$ chmod 705 2 -You have new mail in /var/mail/stud -stud@stud15:/projects$ chmod 701 3 -stud@stud15:/projects$ ls -l -total 20 -drwx---r-- 2 stud stud 4096 окт 1 18:42 1 -drwx---r-x 2 stud stud 4096 окт 1 18:42 2 -drwx-----x 2 stud stud 4096 окт 1 18:42 3 -stud@stud15:/projects$ echo "hello" > 1/message -stud@stud15:/projects$ echo "hello" > 2/message -stud@stud15:/projects$ echo "hello" > 3/message - -root@stud15:/tmp# su - mike -mike@stud15:~$ cd /projects/ -mike@stud15:/projects$ find . -name "message" -find: ‘./3’: Permission denied -./2/message -./1/message -mike@stud15:/projects$ grep -r "hello" . -grep: ./3: Permission denied -./2/message:hello -grep: ./1/message: Permission denied -``` -Команда `find` не смогла найти файл только для папки без доступа на чтение для `other`. Команда `grep` смогла найти строку только в папке с правами и на чтение и на исполнение. - -# Справка - -Конфигурационные файлы: -- /etc/login.defs - -Команды: -- stat -- ls -l -- chmod -- chown -- umask \ No newline at end of file diff --git a/module1/08_debian_package_management/solutions.md b/module1/08_debian_package_management/solutions.md deleted file mode 100644 index 88047ea..0000000 --- a/module1/08_debian_package_management/solutions.md +++ /dev/null @@ -1,114 +0,0 @@ -# Решения - -### 0. -Обновите список пакетов из настроенных репозиториев в /etc/apt/sources.list командой apt. -``` -$ sudo apt update -``` - -### 1. -Установите пакет apt-file с помощью apt. -``` -$ sudo apt install apt-file -``` - -### 2. -Найдите с помощью apt-file пакет, содержащий команду ar. -``` -$ apt-file search ar -``` - -### 3. -Определите с помощью команды `apt search`, какие варианты пакета содержащего команду ar доступны. Установите подходящий для вашей системы. - -### 4. -Скачайте http://ftp.ru.debian.org/debian/pool/main/c/cmake/cmake_3.24.1-1_amd64.deb в отдельную папку. Перейдите в папку с пакетом и распакуйте .deb командой `ar -x путь-к-пакету`. В папке должны появиться: control.tar.xz data.tar.xz debian-binary. - -### 5. -Создайте папку control и распакуйте в неё control.tar.xz с помощью команды `tar xfC путь-к-архиву control`. Изучите содержимое. Сравните с выдачей `dpkg --info ` для .deb файла. - -### 6. -Создайте папку data и распакуйте в неё data.tar.xz с помощью команды `tar xfC путь-к-архиву data`. Изучите data с помощью команды `tree`. Сравните с выдачей `dpkg --contents ` для .deb файла. - -### 7. -Попробуйте вызвать исполняемый файл `usr/bin/cmake` из папки. Сопоставьте информацию в control файле пакета с выдачей команды `ldd usr/bin/cmake`. Если исполняемый файл не работает, найдите и установите зависимости в систему. Воспользуйтесь формой поиска на сайте https://www.debian.org/distrib/packages, если поиск по настроенным репозиториям не даёт результата. Добавьте репозиторий в котором есть нужная библиотека командой `apt edit-sources`. Обновите базу данных пакетов командой `apt update`. Завершите установку зависимостей и проверьте, что cmake работает. - -Поиск на сайте https://www.debian.org/distrib/packages приводит к ссылке https://packages.debian.org/sid/amd64/libjsoncpp25/download, в которой приводится руководство по добавлению экспериментального репозитория. -``` -$ sudo apt update -$ sudo apt install -``` - -### 8. -Утилитой dpkg-query выведите список пакетов, зарегистрированных в dpkg базе данных. Есть ли среди них зависимости cmake, которые вы установили вручную? - -### 9. -Утилитой dpkg-query выведите среди установленных локально пакетов пакет, начинающихся с ‘libc6’. Утилитой apt-cache выполните тот же поиск по кэшу apt. Утилитой apt выполните тот же поиск по кэшу apt. Сравните, чем они отличаются. - -### 10. -Утилитой dpkg-query выведите статус пакета sudo и gcc. Чем выдача отличается от содержимого control файла .deb, скаченного ранее? - -### 11. -Утилитой dpkg-query выведите список установленных файлов пакета sudo (не выводятся файлы созданные скриптами). - -### 12. -Утилитой dpkg-query выведите список файлов с метаданными пакета (control files), установленных в систему. - -### 13. -Утилитой dpkg-query выведите содержимое одного из файлов с метаданными пакета (control files). - -### 14. -Утилитой dpkg-query выведите пути к файлам с метаданными пакета (control files). - -### 15. -Утилитой dpkg-query выполните поиск пакетов, которые установили в систему файл pam.conf. - -### 16. -Утилитой dpkg установите cmake .deb пакет, скачанный ранее. Ещё раз посмотрите на зависимости пакета. Как отреагировал dpkg на отсутствие зависимости cmake-data - установил или выдал ошибку? - -### 17. -Скачайте cmake-data и его транзитивные зависимости https://packages.debian.org/sid/amd64/cmake. Завершите установку cmake, и проверьте, что команда cmake установлена в систему (например, командами `which`, `find`) и работает `cmake --version`. - -### 18. -Проверьте файлы всех установленных пакетов в системе на наличие изменений/повреждений командой dpkg. Какие файлы не прошли проверку (`??5??????`)? - -### 19. -Сохраните список выбранных действий (selections) для пакетов в системе утилитой dpkg в файл. - -### 20. -Измените в сохранённом списке действие для пакета vim c текущего на deinstall (`man dpkg`, “Package selection states”). Перечитайте изменённый список командой `dpkg --set-selections`. - -### 21. -Запустите команду `apt-get dselect-upgrade`. Не подтверждайте изменения. Какие пакеты будут установлены или удалены? - -### 22. -Настройте в `/etc/sudoers` конфигурационном файле для пользователя stud возможность выполнять команды от лица суперпользователя без запроса пароля: -``` -%sudo ALL=(ALL:ALL) NOPASSWD: ALL -``` -Удалите, а затем установите пакет sudo командой `apt remove`. Проверьте содержимое конфигурационного файла на изменения. Проделайте то же самое, но c командой `apt purge`. - -### 23. -Удалите cmake и cmake-data с помощью apt. Найдите в репозиториях, какая версия cmake доступна. Создайте файл в директории `/etc/apt/apt.conf.d/default-release` со следующим содержимым (man apt.conf): -``` -APT::Default-Release "stable"; -``` -Повторите поиск. Установите stable версию. Проверьте работоспособность команды и её версию `cmake --version`. Вы можете узнать значения текущих конфигурационных переменных `apt` командой `apt-config dump`. - -### 24. -Заморозьте версию cmake командой `apt-mark` или с помощью `dpkg --get-selections`, `dpkg --set-selections`. Поменяйте умолчания `/etc/apt/apt.conf.d/default-release` на "unstable". Проведите обновление пакетов в системе. cmake должен сохранить stable версию. - -### 25. -Удалите cmake для следующего упражнения в установке из исходного кода. Выполните `apt autoremove` для удаления ставших ненужными пакетов. - -### 26. -Установите git, если он ещё не установлен. Перейдите в /tmp и вызовите: -``` -git clone --depth=1 https://github.com/Kitware/CMake -``` -Ваша цель установить пакет в директорию /opt. - -Прочитайте README.md секцию "Building CMake from Scratch". Установите компилятор g++, make. Для поддержки openssl - libssl-dev заголовочные файлы. В качестве --prefix используйте `/opt/cmake/`. Выполните 3 этапа: конфигурация компиляции, компиляция проекта, и установка. Для использования многопоточной компиляции используйте флаг `-j` при вызове `make`. - -### 27. -Используйте команду `dpkg-reconfigure`, чтобы перенастроить пакеты, связанные с локализацией `console-setup` и раскладкой клавиатуры `keyboard-configuration`. diff --git a/module1/09_nginx/solutions.md b/module1/09_nginx/solutions.md deleted file mode 100644 index 733f060..0000000 --- a/module1/09_nginx/solutions.md +++ /dev/null @@ -1,187 +0,0 @@ -# Решения - -### 1. -Установите пакет nginx. -``` -$ sudo apt install nginx -``` - -### 2. -Запустите исполняемый файл nginx. Проверьте, что он запустился `ps aux`. -``` -$ sudo ps aux | grep nginx -``` - -### 3. -После запуска nginx им можно управлять, вызывая исполняемый файл с параметром -s. Попробуйте команды: -- stop — быстрое выключение, -- quit — завершение работы с ожиданием завершения обслуживания текущих запросов рабочими процессами, -- reload — перезагрузка файла конфигурации, -- reopen — повторное открытие лог-файлов, -используя следующий синтаксис: -``` -$ nginx -s signal -``` -Команда должна выполняться под тем же пользователем, который запустил nginx. -``` -$ sudo nginx -s reload -$ sudo nginx -s reopen -$ sudo nginx -s stop -$ sudo nginx; sudo ps uax -$ sudo nginx -s quit -``` - -### 4. -Сигнал также может быть отправлен процессам nginx с помощью инструментов Unix, таких как утилита kill. Идентификатор процесса главного процесса nginx по умолчанию записывается в файл `nginx.pid` в каталоге `/usr/local/nginx/logs` или `/var/run`. - -Завершите корректно работу nginx командой `kill -s QUIT`. -``` -$ sudo kill -9 QUIT $(cat /var/run/nginx.pid) -``` - -### 5. -Настройте сервис nginx, установленный вместе с пакетом. Активируйте его и запустите командой `systemctl`. -``` -$ sudo systemctl enable nginx -$ sudo systemctl start nginx -$ sudo systemctl status nginx -``` - -### 6. -```bash -$ cat /etc/nginx/nginx.conf -user www-data; -worker_processes auto; -pid /run/nginx.pid; -include /etc/nginx/modules-enabled/*.conf; - -events { - worker_connections 768; - # multi_accept on; -} - -http { - - ## - # Basic Settings - ## - - sendfile on; - tcp_nopush on; - types_hash_max_size 2048; - # server_tokens off; - - # server_names_hash_bucket_size 64; - # server_name_in_redirect off; - - include /etc/nginx/mime.types; - default_type application/octet-stream; - - ## - # SSL Settings - ## - - ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE - ssl_prefer_server_ciphers on; - - ## - # Logging Settings - ## - - access_log /var/log/nginx/access.log; - error_log /var/log/nginx/error.log; - - ## - # Gzip Settings - ## - - gzip on; - - # gzip_vary on; - # gzip_proxied any; - # gzip_comp_level 6; - # gzip_buffers 16 8k; - # gzip_http_version 1.1; - # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; - - ## - # Virtual Host Configs - ## - - include /etc/nginx/conf.d/*.conf; - include /etc/nginx/sites-enabled/*; -} - - -#mail { -# # See sample authentication script at: -# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript -# -# # auth_http localhost/auth.php; -# # pop3_capabilities "TOP" "USER"; -# # imap_capabilities "IMAP4rev1" "UIDPLUS"; -# -# server { -# listen localhost:110; -# protocol pop3; -# proxy on; -# } -# -# server { -# listen localhost:143; -# protocol imap; -# proxy on; -# } -#} -``` - -### 7. -``` -$ tree /etc/nginx/ -/etc/nginx/ -├── conf.d -├── fastcgi.conf -├── fastcgi_params -├── koi-utf -├── koi-win -├── mime.types -├── modules-available -├── modules-enabled -│ ├── 50-mod-http-geoip.conf -> /usr/share/nginx/modules-available/mod-http-geoip.conf -│ ├── 50-mod-http-image-filter.conf -> /usr/share/nginx/modules-available/mod-http-image-filter.conf -│ ├── 50-mod-http-xslt-filter.conf -> /usr/share/nginx/modules-available/mod-http-xslt-filter.conf -│ ├── 50-mod-mail.conf -> /usr/share/nginx/modules-available/mod-mail.conf -│ ├── 50-mod-stream.conf -> /usr/share/nginx/modules-available/mod-stream.conf -│ └── 70-mod-stream-geoip.conf -> /usr/share/nginx/modules-available/mod-stream-geoip.conf -├── nginx.conf -├── proxy_params -├── scgi_params -├── sites-available -│ └── static-server.conf -├── sites-enabled -│ └── static-server.conf -> /etc/nginx/sites-available/static-server.conf -├── snippets -│ ├── fastcgi-php.conf -│ └── snakeoil.conf -├── uwsgi_params -└── win-utf - -6 directories, 20 files -``` - -### 8,9,10 -Рекомендации по устранению проблем. - -Проверьте, что в конфигурационных файлах указаны абсолютные пути. - -Проверьте порты прослушивания. Проброшенные порты с 193.32.63.170+X на 10.160.179.10+X: 22, 80, 443. - -Проверьте, конфигурации на предмет синтаксических ошибок. Завершения строк `;`. Помочь сделать проверку может команда `nginx -t`. - -Проверьте, что сервис nginx запущен. - -Проверьте, что добавили символическую ссылку в /etc/nginx/sites-enabled на конфигурационный файл в /etc/nginx/sites-available. - -Если не открываются скаченные изображения, проверьте, что вы используете прямые ссылки для скачивания. Проверьте размер файлов изображений. - -Если вы выбрали сложный вариант решения в 10 задании, проверьте, что машины 10.160.179.10+X и 10.160.179.10+20+X находятся в одной vlan vmbr499 с доступом в интернет, друг друга "видят" командой ping. \ No newline at end of file diff --git a/module1/10_bash_scripts/solutions.md b/module1/10_bash_scripts/solutions.md deleted file mode 100644 index 996404f..0000000 --- a/module1/10_bash_scripts/solutions.md +++ /dev/null @@ -1,468 +0,0 @@ -# Решения - -### 1. -Напишите .sh скрипт в котором в переменную date присваивается значение текущей даты, в переменную claim - строка "snow is white". После вызова скрипт должен выводить строку, используя переменные date и claim: -``` -Ср 14 сен 2022 14:50:46 +04: The claim that “snow is white” is true if and only if snow is white. -``` -Сделайте файл исполняемым для владельца и вызовите указанием полного или относительного пути к нему. - -содержимое скрипта 1.sh -``` -date=$(date) -claim='snow is white' -echo "$date: The claim that \"$claim\" is true if and only if $claim." -``` - -### 2. -Напишите функцию в скрипте, которая создает каталог, путь к которому передан в качестве первого аргумента и переходит в него. Проверьте работу функции в этом же файле. Работает ли функция за пределами контекста скрипта? -```bash -$ cat 2.sh -mkdir_cd () { - mkdir -p $1 - cd $1 - echo current dir: $(pwd) -} - -mkdir_cd $1 -stud@stud15:~$ ./2.sh /tmp/1/2/3/4/5 -current dir: /tmp/1/2/3/4/5 -stud@stud15:~$ -``` -После выполнения скрипта текущая директория не изменилась. -```bash -$ mkdir_cd () { - mkdir -p $1 - cd $1 - echo current dir: $(pwd) -} -stud@stud15:~$ mkdir_cd /tmp/a/b/c/d -current dir: /tmp/a/b/c/d -stud@stud15:/tmp/a/b/c/d$ -``` -После определения функции и вызова в оболочке изменилась. - - -### 3. -Менее известной, но полезной может быть подстановка дескриптора файла с результатом выполнения команды. `<( CMD )` выполнит `CMD` и поместит вывод во временный файл и заменит `<()` именем этого файла. Это полезно, когда команды ожидают, что значения будут переданы через файл, а не STDIN. Например, `diff <(ls foo) <(ls bar)` покажет различия между файлами в каталогах foo и bar. -``` -$ diff <(cat buylist) <(cat bought) -1,3c1,5 -< salad -< milk -< bread ---- -> icecream -> cheese -> cake -> lays -> beer -``` - -### 4. -Попробуйте условные выражения в скрипте в if конструкции: -```bash -$ cat 4.sh -if [[ true && true ]] -then - echo "True" -fi - -if [[ true || false ]] -then - echo "True" -fi -stud@stud15:~$ ./4.sh -True -True -``` - -### 5. -Напишите скрипт, который проходит по всем файлам, переданным в качестве аргументов, и ищет в них строку hello. Перенаправьте grep `STDOUT` и `STDERR` в специальный файл `/dev/null`. Для каждого файла в if создайте файл с содержимым `hello`, если `grep` завершился с ошибкой. -```bash -$ cat 5.sh -for f in $@; do - grep hello $f 2> /dev/null 1> /dev/null - if [[ $? -ne 0 ]] - then - echo "hello" > $f - fi -$ ./5.sh /tmp/one /tmp/two /tmp/three -/tmp/one has no hello in it. correcting. -/tmp/two has no hello in it. correcting. -/tmp/three has no hello in it. correcting. -$ grep hello /tmp/* 2> /dev/null -/tmp/one:hello -/tmp/three:hello -/tmp/two:hello -``` - -### 6. -Установите пакет shellcheck и проверьте написанный вами ранее скрипт одноименной командой. -```bash -$ shellcheck 5.sh - -In 5.sh line 1: -for f in $@; do -^-- SC2148 (error): Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive. - ^-- SC2068 (error): Double quote array expansions to avoid re-splitting elements. - - -In 5.sh line 2: - grep hello $f 2> /dev/null 1> /dev/null - ^-- SC2086 (info): Double quote to prevent globbing and word splitting. - -Did you mean: - grep hello "$f" 2> /dev/null 1> /dev/null - - -In 5.sh line 3: - if [[ $? -ne 0 ]] - ^-- SC2181 (style): Check exit code directly with e.g. 'if ! mycmd;', not indirectly with $?. - - -In 5.sh line 5: - echo $f has no hello in it. correcting. - ^-- SC2086 (info): Double quote to prevent globbing and word splitting. - -Did you mean: - echo "$f" has no hello in it. correcting. - - -In 5.sh line 6: - echo "hello" > $f - ^-- SC2086 (info): Double quote to prevent globbing and word splitting. - -Did you mean: - echo "hello" > "$f" - -For more information: - https://www.shellcheck.net/wiki/SC2068 -- Double quote array expansions to ... - https://www.shellcheck.net/wiki/SC2148 -- Tips depend on target shell and y... - https://www.shellcheck.net/wiki/SC2086 -- Double quote to prevent globbing ... -``` - -### 7. -Напишите скрипт, который выполняет следующий код: -```bash -$ cat ./7.sh -#!/usr/bin/env python -import sys -for arg in reversed(sys.argv[1:]): - print(arg) -$ ./7.sh 1 2 3 4 5 -5 -4 -3 -2 -1 -``` - -### 8. -Функции выполняются в текущей среде оболочке, тогда как скрипты выполняются в своем собственном процессе. - -Проверьте, что функции могут изменять переменные среды, например, изменить текущий каталог, тогда как скрипт не может. Напишите скрипт, в котором инициализируются две переменные `A` и `B`. Перед одной из них указывается `export `. Выполните скрипт и посмотрите на выдачу команды `env`. Выполните файл командой source (source --help). Какие переменные экспортировались в оболочку? -```bash -$ cat 8.sh -#!/bin/bash -A=1 -export B=2 -stud@stud15:~$ ./8.sh -stud@stud15:~$ env | grep -E "^A|B" -stud@stud15:~$ source ./8.sh -stud@stud15:~$ env | grep -E "^A|B" -B=2 -``` - -### 9. -Напишите сценарий bash, который запускает следующий сценарий до тех пор, пока он не завершится аварийно, записывает стандартный вывод и потоки ошибок в файлы и печатает все в конце. -```bash -stud@stud15:~$ cat random_bug_script.sh -#!/usr/bin/env bash - -n=$(( RANDOM % 100 )) -echo $n -if [[ n -eq 42 ]]; then - echo "Something went wrong" - >&2 echo "The error was using magic numbers" - exit 1 -fi - -echo "Everything went according to plan" - -stud@stud15:~$ cat repeat_until_error.sh -#!/bin/bash -echo "" > output.log -echo "" > error.log -i=0 -while true; do - bash $1 2>> error.log 1>> output.log - if [[ $? -ne 0 ]]; then - echo Took "$i" iterations to get an error. - echo "\noutput.log" - cat output.log - echo "\nerror.log" - cat error.log - break - fi - i=$((i+1)) -done - -stud@stud15:~$ ./repeat_until_error.sh ./random_bug_script.sh -Took 37 iterations to get an error. - -output.log - -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Everything went according to plan -Something went wrong - -error.log - -The error was using magic numbers -``` - -Бонусный балл, за то, что вы можете сообщить, сколько запусков потребовалось для сбоя сценария. -```bash -stud@stud15:~$ cat mean.sh -#!/bin/bash -script=$1 -iters=$2 -sum=0 -for i in $(seq $iters) -do - failedoniter=$(bash $script | grep 'Took' | awk '{ print $2; }') - sum=$((sum+failedoniter)) -done - -echo Done $iters trials. -echo Mean number of steps until error: $(( sum / iters )) - -$ time ./mean.sh "./repeat_until_error.sh ./random_bug_script.sh" 1000 -Done 1000 trials. -Mean number of steps until error: 99 - -real 2m6,924s -user 1m36,964s -sys 0m29,409s -``` - -### 10. -Напишите скрипт, который: -- создаёт пользователя на двух машинах, -- кроме домашней директории заводит папку для пользователя в `/ceph/` с нужными правами, -- создаёт ссылку в домашней директории на директорию в `/ceph/`, -- ограничивает доступ к домашней папке всем, кроме владельца, -- генерирует пользователям ключи ed25519, рассылает по машинам и регистрирует ключи для беспарольного перемещения пользователя между машинами. - -Настройка беспарольного перехода для суперпользователя между машинами -``` -root@stud15:~# cat .ssh/config -Host w001 - HostName 10.160.179.25 - -Host w002 - HostName 10.160.179.55 - -root@stud15:~# hostname -i -10.160.179.25 -root@stud15-v1:~# hostname -i -10.160.179.55 - -root@stud15-v1:~# cat /etc/ssh/sshd_config | grep PermitRootLogin -PermitRootLogin yes - -root@stud15-v1:~# systemctl restart sshd - -root@stud15:~# ssh-copy-id w002 -/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub" -/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed -/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys -root@10.160.179.55's password: - -Number of key(s) added: 1 - -Now try logging into the machine, with: "ssh 'w002'" -and check to make sure that only the key(s) you wanted were added. - -root@stud15-v1:~# cat /etc/ssh/sshd_config | grep PermitRootLogin -PermitRootLogin prohibit-password - -root@stud15-v1:~# systemctl restart sshd - -root@stud15:~# ssh-copy-id w001 -/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub" -The authenticity of host '10.160.179.25 (10.160.179.25)' can't be established. -ECDSA key fingerprint is SHA256:3K1vZ3p2zlZpJabnqm3ZqwUPkmxxnIHiqYplqRLEku8. -Are you sure you want to continue connecting (yes/no/[fingerprint])? yes -/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed - -/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system. - (if you think this is a mistake, you may want to use -f option) -``` -Скрипт -```bash -root@stud15:~# cat create_user.sh -#!/bin/bash - -help() { - echo "Usage: ./create_user.sh file_with_node_ip_addresses user_name" -} - -if [[ $# < 2 ]] -then - help - exit -fi - - -nodes=$(cat $1) -user=$2 -create_user_and_link_command="useradd $user --create-home --shell=/bin/bash --key HOME_MODE=0700; \ -mkdir -p /ceph/$user -m 0700; \ -chown $user:$user /ceph/$user; \ -ln -s /ceph/$user /home/$user/ceph; \ -chown $user:$user --no-dereference /home/$user/ceph" - -mkdir -p /root/users.ssh/$user/ -ssh-keygen -t ed25519 -N "" -f "/root/users.ssh/$user/id_ed25519" -sed --in-place "s/root/user/" "/root/users.ssh/$user/id_ed25519.pub" -cat /root/users.ssh/$user/id_ed25519.pub > /root/users.ssh/$user/authorized_keys - -echo "" > /root/users.ssh/$user/known_hosts -for node in $nodes; do - ssh-keyscan -H "$node" >> /root/users.ssh/$user/known_hosts -done - -for node in $nodes; do - echo "$node" "$create_user_and_link_command" - ssh "$node" "$create_user_and_link_command" - scp -r /root/users.ssh/$user/ $node:/home/$user/.ssh - ssh "$node" "chown -R $user:$user /home/$user/.ssh && chmod 0700 /home/$user/.ssh/" -done - -root@stud15:~# cat nodes -10.160.179.25 -10.160.179.55 -``` - -Проверка -``` -root@stud15:~# ./create_user.sh nodes user6 -Generating public/private ed25519 key pair. -Your identification has been saved in /root/users.ssh/user6/id_ed25519 -Your public key has been saved in /root/users.ssh/user6/id_ed25519.pub -The key fingerprint is: -SHA256:FdusRTajDoM/7us/Tyf3VCmu/8kAWjWoYkerUGKggzg root@stud15 -The key's randomart image is: -+--[ED25519 256]--+ -| . . = | -|o . . . O.o | -|Eo o..o.+.+o | -| .. . o..=oo. . .| -| . oS+oo . ..| -| o.+.o o . .| -| ... ooo .| -| . ...+oo.| -| .+o.+o..+.| -+----[SHA256]-----+ -# 10.160.179.25:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1 -# 10.160.179.25:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1 -# 10.160.179.25:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1 -# 10.160.179.25:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1 -# 10.160.179.25:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1 -# 10.160.179.55:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1 -# 10.160.179.55:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1 -# 10.160.179.55:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1 -# 10.160.179.55:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1 -# 10.160.179.55:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1 -10.160.179.25 useradd user6 --create-home --shell=/bin/bash --key HOME_MODE=0700; mkdir -p /ceph/user6 -m 0700; chown user6:user6 /ceph/user6; ln -s /ceph/user6 /home/user6/ceph; chown user6:user6 --no-dereference /home/user6/ceph -id_ed25519.pub 100% 93 484.7KB/s 00:00 -id_ed25519 100% 399 2.8MB/s 00:00 -authorized_keys 100% 93 746.1KB/s 00:00 -known_hosts 100% 1957 12.5MB/s 00:00 -10.160.179.55 useradd user6 --create-home --shell=/bin/bash --key HOME_MODE=0700; mkdir -p /ceph/user6 -m 0700; chown user6:user6 /ceph/user6; ln -s /ceph/user6 /home/user6/ceph; chown user6:user6 --no-dereference /home/user6/ceph -id_ed25519.pub 100% 93 434.1KB/s 00:00 -id_ed25519 100% 399 2.4MB/s 00:00 -authorized_keys 100% 93 625.8KB/s 00:00 -known_hosts 100% 1957 10.4MB/s 00:00 -root@stud15:~# - - -user6@stud15:~$ ssh 10.160.179.55 -Linux stud15-1v15 5.10.0-17-amd64 #1 SMP Debian 5.10.136-1 (2022-08-13) x86_64 - -The programs included with the Debian GNU/Linux system are free software; -the exact distribution terms for each program are described in the -individual files in /usr/share/doc/*/copyright. - -Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent -permitted by applicable law. -user6@stud15-1v15:~$ ssh 10.160.179.25 -Linux stud15 5.10.0-16-amd64 #1 SMP Debian 5.10.127-1 (2022-06-30) x86_64 - -The programs included with the Debian GNU/Linux system are free software; -the exact distribution terms for each program are described in the -individual files in /usr/share/doc/*/copyright. - -Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent -permitted by applicable law. -user6@stud15:~$ - - -root@stud15:~# ls -la /home/user6/ -total 28 -drwx------ 3 user6 user6 4096 сен 15 11:49 . -drwxr-xr-x 13 root root 4096 сен 15 11:47 .. --rw------- 1 user6 user6 18 сен 15 11:49 .bash_history --rw-r--r-- 1 user6 user6 220 мар 27 22:40 .bash_logout --rw-r--r-- 1 user6 user6 3526 мар 27 22:40 .bashrc -lrwxrwxrwx 1 user6 user6 11 сен 15 11:47 ceph -> /ceph/user6 --rw-r--r-- 1 user6 user6 807 мар 27 22:40 .profile -drwx------ 2 user6 user6 4096 сен 15 11:47 .ssh -root@stud15:~# ls -la /ceph -total 32 -drwxr-xr-x 8 root root 4096 сен 15 11:47 . -drwxr-xr-x 21 root root 4096 сен 15 11:12 .. -drwx------ 2 user1 user1 4096 сен 15 11:14 user1 -drwx------ 2 user2 user2 4096 сен 15 11:25 user2 -drwx------ 2 user3 user3 4096 сен 15 11:38 user3 -drwx------ 2 user4 user4 4096 сен 15 11:42 user4 -drwx------ 2 user5 user5 4096 сен 15 11:44 user5 -drwx------ 2 user6 user6 4096 сен 15 11:47 user6 -``` \ No newline at end of file diff --git a/module1/11_cron_at/solutions.md b/module1/11_cron_at/solutions.md deleted file mode 100644 index 4a8fd3d..0000000 --- a/module1/11_cron_at/solutions.md +++ /dev/null @@ -1,132 +0,0 @@ -# Решения - -Для проверки расписания вы можете использовать сайт https://crontab.guru/, https://cronheatmap.com и аналоги. - -### 0. -Проверьте наличие команд cron и at в системе. Установите их в случае отсутствия. -```bash -sudo apt install cron at -``` - -### 1. -Выведите документацию crontab и cron. -```bash -man crontab -man cron -``` - -### 2. -Создайте cron расписание для выполнения скрипта или к: -``` bash -# ┌───────────── minute (0 - 59) -# │ ┌───────────── hour (0 - 23) -# │ │ ┌───────────── day of the month (1 - 31) -# │ │ │ ┌───────────── month (1 - 12) -# │ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday; -# │ │ │ │ │ 7 is also Sunday on some systems) -# │ │ │ │ │ -# │ │ │ │ │ -# * * * * * - -# 1. дважды в день: в 5 утра и в 5 вечера, -0 5,17 * * * /sbin/script.sh -# 2. в 3:15 каждый день, -15 15 * * * /sbin/script.sh -# 3. в 8 вечера каждую неделю, -0 20 * * 1 /sbin/script.sh -# 4. по понедельникам в 20:00, -0 20 * * 1 /sbin/script.sh -# 5. в 20:00 по понедельникам и по субботам, -0 20 * * 1,6 /sbin/script.sh -# 6. каждую минуту, -* * * * * /sbin/script.sh -# 7. каждые 10 минут, -*/10 * * * * /sbin/script.sh -# 8. каждые 15 минут по субботам и понедельникам, -*/15 * * * 1,6 /sbin/script.sh -# 9. каждую минуту в марте, июне, сентябре и декабре, -* * * 3,6,9,12 /sbin/script.sh -# 10. 20 января в 8 вечера, -0 20 20 1 * /sbin/script.sh -# 11. ежедневное выполнение скрипта в 8 вечера каждый второй месяц, -0 20 * */2 * /sbin/script.sh -# 12. *в первое воскресенье каждого месяца, -0 0 * * 0 [ $(date +%d) -le 07 ] && /script/script.sh -# 13. каждые три часа, -0 */3 * * * /sbin/script.sh -# 14. дважды, каждую субботу и понедельник, -0 0 * * 1,6 /sbin/script.sh -# 15. *каждые 30 секунд, -* * * * * /sbin/script.sh -* * * * * sleep 30; /sbin/script.sh -# 16. каждый день в летний период, -0 0 * 6,7,8 * /sbin/script.sh -# 17. для рассылки поздравлений с новым годом, -0 0 1 1 * /sbin/happy_new_year_mail.sh -# 18. ежедневного удаления неиспользуемых пакетов в системе, -0 1 * * * apt autoremove -# 19. перезапуска системы в 0 часов 0 минут, -0 0 * * * shutdown -h 0 -# 20. для очистки всех попыток сбоя входа в систему ежедневно в 1:00, -0 1 * * * /sbin/clear_auth_errors.sh -# 21. ежедневной проверки и загрузки новых системных пакетов, -0 0 * * * apt update -# 22. ежедневного обновления пакетов системы, -0 0 * * * apt upgrade -y -# 23. ежедневное резервное копирование всех папок пользователей в 5 утра. -0 5 * * * tar -zcf /var/backups/home.tgz /home/ -``` -### 3. -Создайте задание в котором отчёты cron будут отправляться вам на внешний почтовый ящик. -``` -MAILTO=logs@myoffice.org -``` - -### 4. -Установите пользовательский сrontab. -``` -sudo echo "stud" >> /etc/cron.allow -crontab -e -``` - -### 5. -Настройте выполнение исполняемого файла script.sh из `/usr/sbin/` каждую среду, модифицировав `PATH` в cron задании. -```bash -PATH=/opt/cmake/bin:$PATH -0 0 * * 3 /usr/sbin/script.sh -``` - -### 6. -Пользуясь полномочиями суперпользователя, запретите пользователю mike выполнять команду at. -``` -sudo echo "mike" >> /etc/at.deny -``` - -### 7. -Запланируйте командой at: -``` bash -# 1. выполнение скрипта сегодня в 9 часов, -at 21:00 script.sh -# 2. перезагрузку через 2 часа, -sudo at now + 2 hours reboot -# 3. выполнение команды через 100 лет. -at now + 100 years script.sh -``` - -# Справка - -Релевантные файлы: - - /etc/cron.allow - - /etc/cron.deny - - /var/spool/cron/crontabs - - /var/spool/cron/atjobs - - /var/spool/cron/atspool - - /proc/loadavg - - /var/run/utmp - - /etc/at.allow - - /etc/at.deny - -Релевантные команды: - - cron - - at - - crontab \ No newline at end of file diff --git a/module1/12_troubleshooting/solutions.md b/module1/12_troubleshooting/solutions.md deleted file mode 100644 index 5bad1ee..0000000 --- a/module1/12_troubleshooting/solutions.md +++ /dev/null @@ -1,46 +0,0 @@ -# Решения - -Исправьте проблемы настройки сети в виртуальных машинах `troublesome-X-task[1-5]`. В каждой машине 1 проблема после исправления которой работает команда `ping yandex.com`. Шлюз по умолчанию для машины в каждом задании - 192.168.1.1 в сети 192.168.1.0/24. Всего 5 заданий. Используйте механизм снимков и команду rollback в proxmox интерфейсе, чтобы откатывать машину в первоначальное состояние. - -### 1. Не активирован и не запущен systemd-networkd -``` -sudo systemctl enable systemd-networkd -sudo systemctl start systemd-networkd -``` - -### 2. В настройках не указан шлюз по умолчанию -``` -sudo "echo Gateway=192.168.1.1 >> /etc/systemd/network/ens18.network" -sudo networkctl reload -``` - -### 3. В настройках systemd-resolved не указан DNS -``` -sudo "echo DNS=1.1.1.1 >> /etc/systemd/resolved.conf" -sudo systemctl restart systemd-resolved -``` - -### 4. Машина находится в другой сети по отношению к шлюзу -``` -sudo sed 's/172\.16/192\.168/' -i /etc/systemd/network/ens18.network -sudo networkctl reload -``` - -### 5. На сетевом интерфейсе установлен MAC-дубликат шлюза -Установите родной mac `permaddr`: -``` -sudo "ip link set address $(ip link show ens18 | grep permaddr | awk '{ print $6 }') dev ens18" -``` - -### 6. Неверные права папки .ssh пользователя mike - -В 6ом задании `troublesome-X-task6` вам требуется отладить команду `ssh localhost -l mike`, запущенную от пользователя stud. Команда должна отработать без ввода пароля. - -``` -sudo chmod 0700 /home/mike/.ssh -``` - -Также желательно исправить группу-владельца: -``` -sudo chown mike:mike /home/mike/.ssh -``` \ No newline at end of file