<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>@zloytapochek</title><author><name>@zloytapochek</name></author><id>https://teletype.in/atom/zloytapochek</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/zloytapochek?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@zloytapochek?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=zloytapochek"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/zloytapochek?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-04-22T12:26:40.848Z</updated><entry><id>zloytapochek:PRaGYtoS1Vc</id><link rel="alternate" type="text/html" href="https://teletype.in/@zloytapochek/PRaGYtoS1Vc?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=zloytapochek"></link><title>Создание systemd сервиса</title><published>2026-02-28T14:56:29.749Z</published><updated>2026-02-28T14:56:29.749Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img1.teletype.in/files/8f/cb/8fcb2ed6-7444-4dd7-9936-2870ec14c00d.png"></media:thumbnail><category term="devops" label="devops"></category><summary type="html">&lt;img src=&quot;https://img3.teletype.in/files/ae/27/ae27efff-1039-49f1-91bc-c951591b6026.jpeg&quot;&gt;TL;DR
Создание &quot;сервисного&quot; пользователя
Создание systemd-сервиса</summary><content type="html">
  &lt;blockquote id=&quot;zpru&quot;&gt;TL;DR&lt;br /&gt;Создание &amp;quot;сервисного&amp;quot; пользователя&lt;br /&gt;Создание systemd-сервиса&lt;/blockquote&gt;
  &lt;h3 id=&quot;7Jov&quot;&gt;Создание пользователя&lt;/h3&gt;
  &lt;p id=&quot;3Mzn&quot;&gt;Создание пользователя обычно чем-то подкрепляется. В моем случае нужно было создать &amp;quot;сервисного&amp;quot; юзера. У которого не будет домашней директории и через него нельзя будет залогиниться. А нужен он будет для запуска веб-сервера&lt;br /&gt; Поэтому входные данные такие:&lt;/p&gt;
  &lt;ul id=&quot;MmBj&quot;&gt;
    &lt;li id=&quot;dPVb&quot;&gt;Имя группы&lt;/li&gt;
    &lt;li id=&quot;dhN0&quot;&gt;Имя пользователя&lt;/li&gt;
    &lt;li id=&quot;Aq7M&quot;&gt;Путь до исполняемого файла&lt;/li&gt;
    &lt;li id=&quot;bMGD&quot;&gt;Путь до директорий, к которым нужен будет доступ&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;AIcV&quot;&gt;Создаем группу&lt;/p&gt;
  &lt;pre id=&quot;t05v&quot; data-lang=&quot;shell&quot;&gt;sudo groupadd &amp;lt;имя_группы&amp;gt;&lt;/pre&gt;
  &lt;p id=&quot;8jpj&quot;&gt;Создаем самого пользователя&lt;/p&gt;
  &lt;pre id=&quot;rXuO&quot; data-lang=&quot;shell&quot;&gt;sudo useradd -r -s /usr/sbin/nologin -g &amp;lt;имя_группы&amp;gt; &amp;lt;имя_пользователя&amp;gt;&lt;/pre&gt;
  &lt;p id=&quot;Gt7c&quot;&gt;&lt;code&gt;-r&lt;/code&gt; - создает системного пользователя без домашней директории&lt;br /&gt;&lt;code&gt;-s /usr/sbin/nologin&lt;/code&gt; - запрещает авторизацию пользователя через терминал&lt;br /&gt;&lt;code&gt;-g &amp;lt;имя_группы&amp;gt;&lt;/code&gt; - добавляет пользователя в определенную группу&lt;/p&gt;
  &lt;p id=&quot;oVyu&quot;&gt;&lt;em&gt;Полный список флагов &lt;a href=&quot;https://man7.org/linux/man-pages/man8/useradd.8.html&quot; target=&quot;_blank&quot;&gt;здесь&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
  &lt;p id=&quot;U1kv&quot;&gt;Назначаем права доступа&lt;/p&gt;
  &lt;pre id=&quot;UTmb&quot; data-lang=&quot;shell&quot;&gt;sudo chown -R &amp;lt;пользователь&amp;gt;:&amp;lt;группа&amp;gt; &amp;lt;путь_до_исполняемого_файла&amp;gt;

sudo chown -R &amp;lt;пользователь&amp;gt;:&amp;lt;группа&amp;gt; &amp;lt;дополнительные_директории&amp;gt;
...&lt;/pre&gt;
  &lt;h3 id=&quot;Tyf2&quot;&gt;Управление systemd-сервисом&lt;/h3&gt;
  &lt;p id=&quot;bGeI&quot;&gt;Чтобы создать сервис, нужно описать его в конфигурационном файле. Располагаться он должен в &lt;code&gt;/etc/systemd/system/&amp;lt;имя_сервиса&amp;gt;.service&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;TtH7&quot;&gt;Ниже приведен пример шаблона с пояснениями. Данный шаблон был использован для настройки &lt;a href=&quot;https://github.com/9001/copyparty&quot; target=&quot;_blank&quot;&gt;Copyparty&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;nRhQ&quot;&gt;Шаблон:&lt;/p&gt;
  &lt;pre id=&quot;CURJ&quot; data-lang=&quot;toml&quot;&gt;[Unit]
Description=CopyParty File Server # Описание
After=network.target # запуск после успешного поднятия сети

[Service]
Type=simple

User=copyparty # Пользователь, которого создали ранее
Group=copyparty # Группа, которую создали ранее

WorkingDirectory=/opt/copyparty # Директория, где лежит исполняемый файл

ExecStart=/usr/bin/python3 /opt/copyparty/copyparty-sfx.py -c /opt/copyparty/copyparty.conf # Команда запуска. На всякий случай пишем пути полностью

# Настройки перезапуска при сбоях
Restart=on-failure
RestartSec=5

# Базовые настройки безопасности
NoNewPrivileges=yes # Запрет процессу и его дочерним повышать привелегии
ProtectSystem=full # Делает системноважные папки неприкосаемыми

Environment=&amp;quot;HOME=/opt/copyparty&amp;quot; # Т.к. пользователь copyparty был создан без домашней директории, то укажем ее вручную

AmbientCapabilities=CAP_NET_BIND_SERVICE # Дает разрешение на откртые системных портов(0-1023)
[Install]
WantedBy=multi-user.target # Устанавливает условие для запуска: система должна полностью загрузиться и быть готовой к работе&lt;/pre&gt;
  &lt;p id=&quot;Oc2V&quot;&gt;Изначально шабон не завелся из-за двух ошибок:&lt;/p&gt;
  &lt;ol id=&quot;bItW&quot;&gt;
    &lt;li id=&quot;aOFf&quot;&gt;&lt;code&gt;srv.bind((ip, port)) -&amp;gt; [Errno 13] Permission denied&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;dYUY&quot;&gt;&lt;code&gt;Unable to store config in ~/.config&lt;/code&gt;&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;aeIC&quot;&gt;Чтобы их исправить были добавлены строчки:&lt;/p&gt;
  &lt;pre id=&quot;XLJ5&quot; data-lang=&quot;toml&quot;&gt;Environment=&amp;quot;HOME=/opt/copyparty&amp;quot; # Т.к. пользователь copyparty был создан без домашней директории, то укажем ее вручную

AmbientCapabilities=CAP_NET_BIND_SERVICE # Дает разрешение на откртые системных портов(0-1023)&lt;/pre&gt;
  &lt;p id=&quot;kOYg&quot;&gt;&lt;em&gt;Кстати список всех Capabilities лежит &lt;a href=&quot;https://man7.org/linux/man-pages/man7/capabilities.7.html&quot; target=&quot;_blank&quot;&gt;здесь&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(170, 33%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;gMKo&quot;&gt;🔥Hint&lt;/p&gt;
    &lt;p id=&quot;i4YV&quot;&gt;Если заполняли файл на winodws, то на всякий случай наш его преобразовать с dos на unix командой &lt;code&gt;dos2unix /etc/systemd/system/copyparty.service&lt;/code&gt;&lt;/p&gt;
  &lt;/section&gt;
  &lt;p id=&quot;t7RO&quot;&gt;Теперь запустим наш сервис:&lt;/p&gt;
  &lt;p id=&quot;K965&quot;&gt;Перезагружаем конфиг systemd&lt;/p&gt;
  &lt;pre id=&quot;a2Bp&quot; data-lang=&quot;shell&quot;&gt;sudo systemctl daemon-reload&lt;/pre&gt;
  &lt;p id=&quot;GbUd&quot;&gt;Включаем наш сервис, тем самым добавляем его в автозагрузку&lt;/p&gt;
  &lt;pre id=&quot;wqM2&quot; data-lang=&quot;shell&quot;&gt;sudo systemctl enable copyparty&lt;/pre&gt;
  &lt;p id=&quot;bNRh&quot;&gt;Запускаем наш сервис&lt;/p&gt;
  &lt;pre id=&quot;4pN7&quot; data-lang=&quot;shell&quot;&gt;sudo systemctl start copyparty&lt;/pre&gt;
  &lt;p id=&quot;yf18&quot;&gt;Проверяем статус сервиса&lt;/p&gt;
  &lt;pre id=&quot;k2gF&quot; data-lang=&quot;shell&quot;&gt;sudo systemctl status copyparty&lt;/pre&gt;
  &lt;p id=&quot;NZtg&quot;&gt;Просмотр логов сервиса&lt;/p&gt;
  &lt;pre id=&quot;vM06&quot; data-lang=&quot;shell&quot;&gt;sudo journalctl -u copyparty.service&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;ryVw&quot; data-align=&quot;center&quot;&gt;На этом создание нашего сервиса завершено :)&lt;/p&gt;
  &lt;blockquote id=&quot;NATA&quot; data-align=&quot;center&quot;&gt;Всем добра!&lt;/blockquote&gt;

</content></entry><entry><id>zloytapochek:zbcgfThaFLZ</id><link rel="alternate" type="text/html" href="https://teletype.in/@zloytapochek/zbcgfThaFLZ?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=zloytapochek"></link><title>&quot;Домашний&quot; Compute Cloud | Или как создавать машинки в Hyper-V без ошибок и с Cloud-Init</title><published>2025-11-03T21:27:50.509Z</published><updated>2025-11-03T21:27:50.509Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/54/d7/54d74643-0ef3-4660-b2ba-5cc74fdf2752.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/48/08/48088b14-c4be-4c81-80b8-b97f914336b9.jpeg&quot;&gt;Небольшое предисловие. Я не нашел хороших гайдов или рабочих решений для моей задачи. А она следующая: как только я начал увлекаться всевозможными виртуализациями, кластерами и т.д. и т.п., возникла потребность быстро создавать машинки и настраивать их. Может быть, я плохо искал, но повторюсь, ничего не нашел. Поэтому спустя какое-то время я был вынужден написать Ansible Role для автоматического и легкого создания большого количества виртуальных машин.</summary><content type="html">
  &lt;h2 id=&quot;y3m4&quot;&gt;Мотивация сделать это&lt;/h2&gt;
  &lt;p id=&quot;zewZ&quot;&gt;Небольшое предисловие. Я не нашел хороших гайдов или рабочих решений для моей задачи. А она следующая: как только я начал увлекаться всевозможными виртуализациями, кластерами и т.д. и т.п., возникла потребность быстро создавать машинки и настраивать их. Может быть, я плохо искал, но повторюсь, ничего не нашел. Поэтому спустя какое-то время я был вынужден написать Ansible Role для автоматического и легкого создания большого количества виртуальных машин.&lt;/p&gt;
  &lt;p id=&quot;GVk3&quot;&gt;&lt;strong&gt;Почему Ansible?&lt;/strong&gt;&lt;br /&gt;Изначально я думал написать связку Ansible и Terraform, а запускать их через Powershell скрипт, но из-за проблем провайдера Terraform я не смог этого сделать. И как мне кажется, так даже лучше, ибо Ansible можно запустить на любой системе, в отличие от того же Powershell.&lt;/p&gt;
  &lt;p id=&quot;UWJi&quot;&gt;&lt;strong&gt;А как же Proxmox и другие средства виртуализации + Terraform?&lt;/strong&gt;&lt;br /&gt;Для этого нужны дополнительные ресурсы. А мое решение подходит для тех, у кого есть ПК + ноутбук, или 2 ПК, или 2 ноутбука. &lt;/p&gt;
  &lt;h2 id=&quot;kOgE&quot;&gt;Как это сделать&lt;/h2&gt;
  &lt;p id=&quot;5qdR&quot;&gt;Итак, вот мой репозиторий: &lt;a href=&quot;https://github.com/ZloyTapochek/HyperV-VMs-Ansible-Role&quot; target=&quot;_blank&quot;&gt;https://github.com/ZloyTapochek/HyperV-VMs-Ansible-Role&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;RH1Z&quot;&gt;Вам нужно его склонировать и перейти в директорию&lt;/p&gt;
  &lt;pre id=&quot;QeIV&quot; data-lang=&quot;shell&quot;&gt;git clone https://github.com/ZloyTapochek/HyperV-VMs-Ansible-Role.git
cd HyperV-VMs-Ansible-Role&lt;/pre&gt;
  &lt;p id=&quot;lmti&quot;&gt;Самое главное, с чем я боролся 2 дня - выполнение конвертации диска .img в .vhdx &lt;strong&gt;в WSL&lt;/strong&gt;. Сейчас это звучит непонятно, но поймете, когда перейдете в репозиторий и прочитаете Readme.&lt;/p&gt;
  &lt;p id=&quot;c30L&quot;&gt;Далее следуйте инструкции в Readme, заполняйте переменки. Я в свободное время буду дополнять ее и совершенствовать.&lt;/p&gt;
  &lt;p id=&quot;9tt9&quot;&gt;После всем подготовительных действий, запускайте эту команду и отдыхайте, пока программа все сделает за Вас.&lt;/p&gt;
  &lt;pre id=&quot;gKvx&quot; data-lang=&quot;shell&quot;&gt;ansible-playbook ./playbook.yml -i ./hosts.ini&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;blockquote id=&quot;E98j&quot; data-align=&quot;center&quot;&gt;Всем добра!&lt;/blockquote&gt;

</content></entry><entry><id>zloytapochek:JvcW4PcFmps</id><link rel="alternate" type="text/html" href="https://teletype.in/@zloytapochek/JvcW4PcFmps?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=zloytapochek"></link><title>Поговорим про Templates для Ansible Roles</title><published>2025-06-05T13:52:36.955Z</published><updated>2025-06-05T15:19:02.277Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img3.teletype.in/files/2a/d4/2ad422ac-8ce4-4c3a-9b09-87ca70fa5f31.png"></media:thumbnail><category term="devops" label="devops"></category><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/f0/7f/f07f6477-f87a-4761-aff7-6d6bf7f320c2.jpeg&quot;&gt;Сейчас пришлось окунуться в изучение Roles для Ansible. Поэтому пока знания свежие спешу поделиться ими и легко объяснить то, с чем у меня возникли трудности.</summary><content type="html">
  &lt;p id=&quot;j33c&quot;&gt;Сейчас пришлось окунуться в изучение Roles для Ansible. Поэтому пока знания свежие спешу поделиться ими и легко объяснить то, с чем у меня возникли трудности. &lt;/p&gt;
  &lt;nav&gt;
    &lt;ul&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#oxNK&quot;&gt;Ликбез&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#Kz4x&quot;&gt;Роли&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#lzWc&quot;&gt;Роли с чувствительной информацией: как прятать пароли с помощью templates&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_2&quot;&gt;&lt;a href=&quot;#bsXl&quot;&gt;Пример&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/nav&gt;
  &lt;h2 id=&quot;oxNK&quot;&gt;Ликбез&lt;/h2&gt;
  &lt;section style=&quot;background-color:hsl(hsl(170, 33%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;6FIk&quot;&gt;Статья расчитана на базовые знания Ansible, поэтому слишком глубоко уходить в теорию мы не будем. Лишь поверхностно пробежимся по основным терминам.&lt;/p&gt;
  &lt;/section&gt;
  &lt;p id=&quot;ZhIK&quot;&gt;&lt;strong&gt;Ansible &lt;/strong&gt;— инструмент, который помогает конфигурировать удаленные хосты, разворачивать на них приложения и т. д. и т. п. Для этого используются либо обычные команды:&lt;/p&gt;
  &lt;pre id=&quot;04oY&quot; data-lang=&quot;bash&quot;&gt;ansible localhost -m ansible.builtin.apt -a &amp;quot;name=apache2 state=present&amp;quot; -b -K&lt;/pre&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;h1n8&quot;&gt;Данная команда запускает &lt;strong&gt;ansible localhost-&lt;/strong&gt; на вашей локальной системе. — &lt;strong&gt;name=apache2 state=present&lt;/strong&gt; — устанавливает пакет apache2 на систему на базе Debian. &lt;strong&gt;-b&lt;/strong&gt; — использует become для выполнения с повышенными привилегиями. &lt;strong&gt;-m&lt;/strong&gt; — указывает имя модуля. &lt;strong&gt;-K&lt;/strong&gt; — запрашивает пароль для повышения привилегий.&lt;/p&gt;
  &lt;/section&gt;
  &lt;p id=&quot;AGXD&quot;&gt;Либо же можно использовать Playbook (далее просто «Плейбук&amp;quot;/&amp;quot;Плейбуки»).&lt;/p&gt;
  &lt;p id=&quot;Ro1S&quot;&gt;&lt;strong&gt;Ansible Playbooks&lt;/strong&gt; — основная конфигурация, которой будет следовать Ansible при настройке удаленных хостов. Плейбуки хороши своей легкостью, повторяемостью и изменяемостью.&lt;br /&gt;&lt;strong&gt;Ansible Roles&lt;/strong&gt; — вот переведенное определение из &lt;a href=&quot;https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_reuse_roles.html#roles&quot; target=&quot;_blank&quot;&gt;документации&lt;/a&gt;: «Роли позволяют автоматически загружать связанные с ними vars, файлы, задачи, обработчики и другие артефакты Ansible на основе известной структуры файлов. Сгруппировав содержимое по ролям, вы сможете легко использовать их повторно и делиться ими с другими пользователями.»&lt;br /&gt;Если говорить проще, то Roles (в дальнейшем просто «Роли») помогают разделять задачи на контексты.&lt;br /&gt;Также я упоминал «…указывает имя &lt;strong&gt;модуля&lt;/strong&gt;…».&lt;br /&gt;&lt;strong&gt;Ansible Module&lt;/strong&gt; (далее просто «Модуль») — основной параметр, с помощью которого Ansible будет знать, что делать в конкретной задаче. Для примера:&lt;/p&gt;
  &lt;ul id=&quot;TI2S&quot;&gt;
    &lt;li id=&quot;j9mh&quot;&gt;ansible.builtin.copy — может копировать файлы&lt;/li&gt;
    &lt;li id=&quot;z66P&quot;&gt;community.docker.docker_compose — работает с файлами докера, тем самым может запускать контейнеры, проверять запущены ли они уже и многое другое.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;eki1&quot;&gt;На этом ликбез окончен и мы переходим к нашему сегодняшнему гостю — ролям для Ansible.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;Kz4x&quot;&gt;Роли&lt;/h2&gt;
  &lt;p id=&quot;ig5j&quot;&gt;Вообще сами по себе роли не сложны. По сути, если мы используем роли, то наш каталог, где находится плейбук, дополняется директорией roles:&lt;/p&gt;
  &lt;pre id=&quot;gQS8&quot;&gt;roles/
└── role_name/  
    ├── defaults/       # Переменные по умолчанию (низкий приоритет)  
    ├── vars/           # Переменные роли (высокий приоритет)  
    ├── tasks/          # Основные задачи  
    ├── handlers/       # Обработчики  
    ├── templates/      # Jinja2-шаблоны  
    ├── files/          # Статические файлы  
    ├── meta/           # Информация о роли (зависимости и т. д.)  
    └── tests/          # Тесты  &lt;/pre&gt;
  &lt;p id=&quot;yeZZ&quot;&gt;Роль может иметь любое название, чтобы запустить роль в главном .yml файле плейбука нужно указать:&lt;/p&gt;
  &lt;pre id=&quot;vU7n&quot; data-lang=&quot;yaml&quot;&gt;--- 
- hosts: all  
  roles:    
    - &amp;lt;имя_вашей_роли&amp;gt;&lt;/pre&gt;
  &lt;p id=&quot;Fxlp&quot;&gt;Потом в директории &lt;strong&gt;tasks &lt;/strong&gt;создаете файл, например main.yml, в котором пишете:&lt;/p&gt;
  &lt;pre id=&quot;0apM&quot; data-lang=&quot;yaml&quot;&gt;--- 
- name: Creates docker directory
  become: true  ansible.builtin.file:
    path: /home/ubuntu/docker
    state: directory&lt;/pre&gt;
  &lt;p id=&quot;QwpE&quot;&gt;Это пример задачи, которая создаст директорию &lt;strong&gt;docker.&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;j2Kf&quot;&gt;Можно еще использовать файлы, с которыми нужно будет взаимодействовать. Их требуется расположить в каталоге &lt;strong&gt;files&lt;/strong&gt; внутри каталога с ролью.&lt;/p&gt;
  &lt;pre id=&quot;P24V&quot; data-lang=&quot;yaml&quot;&gt;---
- name: Copying backup_db
  become: true
  ansible.builtin.copy:
    dest: /home/ubuntu/docker/scripts/
    src: files/backup.sh&lt;/pre&gt;
  &lt;p id=&quot;pBUT&quot;&gt;Данная задача копирует файл на удаленный хост. &lt;/p&gt;
  &lt;p id=&quot;HavF&quot;&gt;Казалось бы, обычные роли, но в файлах, которые используются, есть чувствительная информация, например пароли для базы данных или для админа сервиса, которые разворачивается в контейнере. Тут уже могут возникнуть трудности.&lt;/p&gt;
  &lt;h2 id=&quot;lzWc&quot;&gt;Роли с чувствительной информацией: как прятать пароли с помощью templates&lt;/h2&gt;
  &lt;p id=&quot;1tZF&quot;&gt;Для нашего случая возьмем простейший docker compose файл:&lt;/p&gt;
  &lt;pre id=&quot;H1Ba&quot; data-lang=&quot;yaml&quot;&gt;version: &amp;#x27;3.8&amp;#x27;

services:
  postgres:
    image: postgres:latest
    environment:
      POSTGRES_PASSWORD: &amp;quot;mysecretpassword&amp;quot;  # Пароль для PostgreSQL
    ports:
      - &amp;quot;5432:5432&amp;quot;
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:&lt;/pre&gt;
  &lt;p id=&quot;puPz&quot;&gt;А теперь легенда:&lt;br /&gt;Мы разработчики, которые разворачивают контейнер с базой данных PostgreSQL у себя на удаленном хосте. Весь свой код мы храним в каком-нибудь хранилище кода, например GitLab. Также у нас настроен CI, который сам будет выполнять плейбуки для Ansible.&lt;br /&gt;Получается такой алгоритм:&lt;/p&gt;
  &lt;ol id=&quot;iSfy&quot;&gt;
    &lt;li id=&quot;3ZR3&quot;&gt;Написали код.&lt;/li&gt;
    &lt;li id=&quot;V3nh&quot;&gt;Запушили в хранилище.&lt;/li&gt;
    &lt;li id=&quot;Eiqc&quot;&gt;CI начинает выполняться.&lt;/li&gt;
    &lt;li id=&quot;gELN&quot;&gt;Наша БД готова.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;JfQ5&quot;&gt;Но все не так просто. Для CI нужны переменные паролей, а в открытом виде их держать нельзя. Вот тут и выходят на сцену Templates. И вот их я постараюсь объяснить максимально легко.&lt;/p&gt;
  &lt;p id=&quot;qpyD&quot;&gt;Итак, Template — это файл с расширением .j2, ссылаясь на который Ansible будет генерировать другой файл. Звучит сложно, понимаю, поэтому вот пример:&lt;/p&gt;
  &lt;p id=&quot;jwEF&quot;&gt;Наш docker compose файл называется docker-compose.yml. Его template будет называться docker-compose.yml.j2. Выглядеть template будет так:&lt;/p&gt;
  &lt;pre id=&quot;foOJ&quot;&gt;version: &amp;#x27;3.8&amp;#x27;

services:
  postgres:
    image: postgres:latest
    environment:
      POSTGRES_PASSWORD: {{ postgres_password }}  # Пароль для PostgreSQL
    ports:
      - &amp;quot;5432:5432&amp;quot;
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:&lt;/pre&gt;
  &lt;section style=&quot;background-color:hsl(hsl(323, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;V6nX&quot;&gt;Мне кажется, что теперь все должно проясниться. Наш CI будет иметь переменную, которую передаст Ansible. Ansible возьмет template и сгенерирует на его основе исходный файл, заменяя переменные в {{ … }} переменными, которые получили из CI.&lt;/p&gt;
  &lt;/section&gt;
  &lt;p id=&quot;AJl6&quot;&gt;А теперь как это все провернуть.&lt;/p&gt;
  &lt;p id=&quot;zqXG&quot;&gt;Во первых, создайте переменные в своем хранилище кода. Например в GitLab это делается так:&lt;/p&gt;
  &lt;p id=&quot;ndNz&quot; data-align=&quot;center&quot;&gt;Settings → CI/CD → Variables → Add Variable&lt;/p&gt;
  &lt;p id=&quot;tHsp&quot;&gt;Отталкиваясь от нашего примера в переменной мы укажем следующее:&lt;/p&gt;
  &lt;p id=&quot;ftME&quot; data-align=&quot;center&quot;&gt;KEY: POSTGRES_PASSWORD&lt;br /&gt;VALUE: mysecretpassword&lt;/p&gt;
  &lt;p id=&quot;Scfc&quot;&gt;Во вторых, нам нужно &lt;strong&gt;&lt;u&gt;изменить&lt;/u&gt;&lt;/strong&gt; (не скопировать, не добавить, а именно изменить) файл, где находится чувствительная информация, а затем переместить его по пути &lt;strong&gt;/roles/&amp;lt;имя_вашей_роли&amp;gt;/templates&lt;/strong&gt;. Изменяем мы его следующим образом:&lt;/p&gt;
  &lt;ul id=&quot;oYLy&quot;&gt;
    &lt;li id=&quot;cRjm&quot;&gt;Чувствительная информация заменяется на &lt;strong&gt;{{ &amp;lt;имя_переменной&amp;gt; }}&lt;/strong&gt;. Тут смотрите внимательно: имя переменной, которая НЕ В ХРАНИЛИЩЕ. Это важно.&lt;/li&gt;
    &lt;li id=&quot;hb86&quot;&gt;К имени файла добавляется .j2&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;kugL&quot;&gt;В третьих, нужно создать задачу, которая сгенерирует нам исходный файл.&lt;/p&gt;
  &lt;pre id=&quot;tREe&quot; data-lang=&quot;yaml&quot;&gt;- name: Rendering docker-compose file
  become: true
  ansible.builtin.template:    
    src: templates/docker-compose.yml.j2    
    dest: /home/ubuntu/docker/docker-compose.yml    
    owner: ubuntu    
    group: ubuntu  
    mode: &amp;#x27;0644&amp;#x27;  &lt;/pre&gt;
  &lt;p id=&quot;5fSV&quot;&gt;И наконец построим «мост», по которому наши переменные будут передаваться от хранилища кода и сопоставляться с переменными Ansible. Для этого создаем директорию, которая находится на &lt;strong&gt;одном уровне&lt;/strong&gt; с &lt;strong&gt;roles/. &lt;/strong&gt;Называем ее&lt;strong&gt; group_vars&lt;/strong&gt;, внутри добавляем файл, например &lt;strong&gt;all.yml&lt;/strong&gt; с содержимым:&lt;/p&gt;
  &lt;pre id=&quot;hTyk&quot; data-lang=&quot;yaml&quot;&gt;&amp;lt;имя_вашей_переменной_которую_вы_указали_в_файле_.j2&amp;gt;: &amp;quot;{{ lookup(&amp;#x27;ansible.builtin.env&amp;#x27;, &amp;#x27;&amp;lt;имя_вашей_переменной_в_хранилище_кода&amp;gt;&amp;#x27; }}&amp;quot;&lt;/pre&gt;
  &lt;p id=&quot;kPun&quot;&gt;И на этом все. Ansible будет работать. И для полноты картины покажу полный пример с нашим Docker Compose.&lt;/p&gt;
  &lt;h3 id=&quot;bsXl&quot;&gt;Пример&lt;/h3&gt;
  &lt;p id=&quot;eGne&quot;&gt;Исходный &lt;strong&gt;docker-compose.yml&lt;/strong&gt;:&lt;/p&gt;
  &lt;pre id=&quot;30k2&quot; data-lang=&quot;yaml&quot;&gt;version: &amp;#x27;3.8&amp;#x27;

services:
  postgres:
    image: postgres:latest
    environment:
      POSTGRES_PASSWORD: &amp;quot;mysecretpassword&amp;quot;  # Пароль для PostgreSQL
    ports:
      - &amp;quot;5432:5432&amp;quot;
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:&lt;/pre&gt;
  &lt;p id=&quot;kexw&quot;&gt;Измененный ./roles/postgre_install/templates/&lt;strong&gt;docker-compose.yml.j2:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;0P2O&quot;&gt;version: &amp;#x27;3.8&amp;#x27;

services:
  postgres:
    image: postgres:latest
    environment:
      POSTGRES_PASSWORD: {{ postgres_password }}  # Пароль для PostgreSQL
    ports:
      - &amp;quot;5432:5432&amp;quot;
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:&lt;/pre&gt;
  &lt;p id=&quot;59N2&quot;&gt;Переменная внутри хранилища кода:&lt;/p&gt;
  &lt;p id=&quot;VsGL&quot; data-align=&quot;center&quot;&gt;KEY: POSTGRES_PASSWORD&lt;br /&gt;VALUE: mysecretpassword&lt;/p&gt;
  &lt;p id=&quot;70AF&quot;&gt;Файл с переменными ./group_vars/all.yml:&lt;/p&gt;
  &lt;pre id=&quot;PnXW&quot; data-lang=&quot;yaml&quot;&gt;postgres_password: &amp;quot;{{ lookup(&amp;#x27;ansible.builtin.env&amp;#x27;, &amp;#x27;POSTGRES_PASSWORD&amp;#x27; }}&amp;quot;&lt;/pre&gt;
  &lt;p id=&quot;BSAX&quot;&gt;Основной файл ./roles/postgre_install/tasks/&lt;strong&gt;main.yml&lt;/strong&gt;:&lt;/p&gt;
  &lt;pre id=&quot;7qEH&quot; data-lang=&quot;yaml&quot;&gt;---
- name: Rendering docker-compose file  
  become: true   
    ansible.builtin.template:    
    src: templates/docker-compose.yml.j2    
    dest: /home/ubuntu/docker/docker-compose.yml    
    owner: ubuntu    
    group: ubuntu
    mode: &amp;#x27;0644&amp;#x27;
- name: starting docker-compose  
  become: true  
  community.docker.docker_compose:    
    project_src: &amp;quot;/home/ubuntu/docker&amp;quot;    
    state: present&lt;/pre&gt;
  &lt;p id=&quot;KzyR&quot;&gt;Самый главный файл ./&lt;strong&gt;playbook.yml:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;xLsN&quot; data-lang=&quot;yaml&quot;&gt;---
- hosts: all  
  roles:    
    - postgre_instal&lt;/pre&gt;
  &lt;p id=&quot;kZHv&quot;&gt;После этого ваша роль заработает на нужных хостах. &lt;/p&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;joCu&quot;&gt;Спасибо большое за прочтение статьи, я надеюсь, что хоть кому-то помог и сэкономил его время.&lt;/p&gt;
  &lt;blockquote id=&quot;9J2R&quot; data-align=&quot;center&quot;&gt;Всем добра!&lt;/blockquote&gt;

</content></entry><entry><id>zloytapochek:8Iu0putujT5</id><link rel="alternate" type="text/html" href="https://teletype.in/@zloytapochek/8Iu0putujT5?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=zloytapochek"></link><title>Поговорим про DevSecOps. Jenkins with Bandit</title><published>2025-02-04T18:57:06.973Z</published><updated>2025-02-04T19:02:42.695Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img4.teletype.in/files/bc/6e/bc6e3471-30fd-4d01-bb83-4a148be07b41.png"></media:thumbnail><category term="informacionnaya-bezopasnost-ib" label="Информационная безопасность (ИБ)"></category><summary type="html">&lt;img src=&quot;https://img3.teletype.in/files/ef/f7/eff71a38-f128-48a3-a58c-fafe3d0ea5e6.jpeg&quot;&gt;В прошлой статье мы разобрали инструмент Bandit. Если вкратце, этот инструмент сканирует исходный код. Мы применили его на практике, но в нестандартной для DevSecOps форме, запустив его в обычной ОС. Но на практике подобные инструменты встраиваются в CI/CD пайплайн.</summary><content type="html">
  &lt;p id=&quot;dvmZ&quot;&gt;В &lt;a href=&quot;https://teletype.in/@zloytapochek/6TINAD4sbTh&quot; target=&quot;_blank&quot;&gt;прошлой статье&lt;/a&gt; мы разобрали инструмент Bandit. Если вкратце, этот инструмент сканирует исходный код. Мы применили его на практике, но в нестандартной для DevSecOps форме, запустив его в обычной ОС. Но на практике подобные инструменты встраиваются в &lt;strong&gt;CI/CD пайплайн&lt;/strong&gt;.&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;VOCk&quot;&gt;&lt;strong&gt;CI/CD пайплайн &lt;/strong&gt;— набор практик и методов, которые позволяют автоматизировать процесс разработки. То бишь, мы просто вносим изменения в код, а этот код автоматически собирается, тестируется, встает на облачные сервера ну и т. д.&lt;/p&gt;
  &lt;/section&gt;
  &lt;p id=&quot;gD2L&quot;&gt;В этой статье мы интегрируем запуск Bandit для нашего кода на GitHub в &lt;strong&gt;Jenkins.&lt;/strong&gt;&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;44Qd&quot;&gt;&lt;strong&gt;Jenkins &lt;/strong&gt;— инструмент для автоматизации процесса разработки, который поддерживает практики CI/CD&lt;/p&gt;
  &lt;/section&gt;
  &lt;h2 id=&quot;fXLU&quot;&gt;Содержание:&lt;/h2&gt;
  &lt;ul id=&quot;unJi&quot;&gt;
    &lt;li id=&quot;yE1R&quot;&gt;&lt;a href=&quot;#m2jW&quot;&gt;Устанавливаем Jenkins&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;Fm3N&quot;&gt;&lt;a href=&quot;#fvO1&quot;&gt;Начало работы с Jenkins&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;iiSj&quot;&gt;&lt;a href=&quot;#bBmf&quot;&gt;Настройка Bandit&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;ivmP&quot;&gt;&lt;a href=&quot;#epqG&quot;&gt;Настройка агента Jenkins&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;k5yR&quot;&gt;&lt;a href=&quot;#nUSR&quot;&gt;Собираем проект через агента&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h3 id=&quot;m2jW&quot;&gt;Устанавливаем Jenkins&lt;/h3&gt;
  &lt;p id=&quot;Qqb9&quot;&gt;Итак, все это безобразие будет сделано с помощью &lt;strong&gt;Docker.&lt;/strong&gt;&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;z3hb&quot;&gt;&lt;strong&gt;Docker &lt;/strong&gt;— инструмент для контейнеризации приложений.&lt;/p&gt;
  &lt;/section&gt;
  &lt;p id=&quot;fgQ8&quot;&gt;Процесс установки Docker я оставлю за кадром, но приложу ссылку на &lt;a href=&quot;https://docs.docker.com/desktop/&quot; target=&quot;_blank&quot;&gt;иструкцию&lt;/a&gt;.&lt;/p&gt;
  &lt;p id=&quot;KNZi&quot;&gt;Итак, сначала напишем &lt;strong&gt;Dockerfile.&lt;/strong&gt;&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;x3Yh&quot;&gt;&lt;strong&gt;Dockerfile &lt;/strong&gt;— это текстовый файл, содержащий набор инструкций, которые Docker использует для автоматической сборки образа контейнера.&lt;/p&gt;
  &lt;/section&gt;
  &lt;pre id=&quot;lHas&quot; data-lang=&quot;dockerfile&quot;&gt;FROM jenkins/jenkins:lts
# Устанавливаем необходимые пакеты и Bandit
USER root
RUN apt-get update 
RUN apt-get upgrade -y 
RUN apt-get install virtualenv  -y
RUN virtualenv bandit-env 
RUN . bandit-env/bin/activate 
RUN apt-get install python3 -y
RUN apt-get install python3-pip -y
RUN apt install python3-bandit -y
RUN apt-get install ssh -y

USER jenkins&lt;/pre&gt;
  &lt;p id=&quot;WwD8&quot;&gt;Сначала запустим Bandit в том же контейнере, что и Jenkins. А потом сделаем все по уму и добавим агента Jenkins, который сделает все в отдельном контейнере.&lt;/p&gt;
  &lt;p id=&quot;bMbo&quot;&gt;Итак, сформировали Dockerfile. Теперь сформируем &lt;strong&gt;Docker-compose.yml&lt;/strong&gt;&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;0UQ8&quot;&gt;Docker-compose.yml — файл конфигурации для многоконтейнерных приложений&lt;/p&gt;
  &lt;/section&gt;
  &lt;pre id=&quot;c20i&quot; data-lang=&quot;yaml&quot;&gt;version: &amp;#x27;3.8&amp;#x27;

services:  
  jenkins:    
    build: .    
    ports:      
      - &amp;quot;8080:8080&amp;quot;      
      - &amp;quot;50000:50000&amp;quot;    
    volumes:      
      - jenkins_home:/var/jenkins_home    
    networks:      
      - jenkins

volumes:  
  jenkins_home:  

networks:  
  jenkins:
&lt;/pre&gt;
  &lt;p id=&quot;cGme&quot;&gt;Быстро разберем данный файл:&lt;/p&gt;
  &lt;ul id=&quot;LG8h&quot;&gt;
    &lt;li id=&quot;AUEk&quot;&gt;version — версия файла Docker-compose&lt;/li&gt;
    &lt;li id=&quot;SayT&quot;&gt;services — контейнеры нашего приложения&lt;/li&gt;
    &lt;li id=&quot;7Iho&quot;&gt;build — пусть к Dockerfile данного сервиса&lt;/li&gt;
    &lt;li id=&quot;Jqie&quot;&gt;volumes — томы. Иными словами: постоянная память для контейнеров, которая не будет стираться после каждого перезапуска&lt;/li&gt;
    &lt;li id=&quot;kK0u&quot;&gt;networks — сети для контейнеров, которые позволяют изолировать трафик между контейнерами&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;ANnd&quot;&gt;Запустим наше приложение командой Docker-compose up -d. Флаг -d означает работу в фоновом режиме. Таким образом мы не будем видеть логи контейнера в терминале. &lt;/p&gt;
  &lt;p id=&quot;HEpb&quot;&gt;Наша рабочая директория должна выглядеть так:&lt;/p&gt;
  &lt;pre id=&quot;kUal&quot;&gt;|-workspace
 |--docker-compose.yml
 |--Dockerfile &lt;/pre&gt;
  &lt;p id=&quot;YZSP&quot;&gt;Когда пропишем команду, наш терминал будет выглядеть следующим образом (Название может отличаться):&lt;/p&gt;
  &lt;figure id=&quot;phjX&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/91/8f/918fd29c-770d-4060-82c4-fa67005e9325.png&quot; width=&quot;1834&quot; /&gt;
    &lt;figcaption&gt;Результат успешного запуска нашего приложения&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;p4pO&quot;&gt;Надписи CACHED означают, что изображение, по которому строится контейнер уже имеется в памяти ПК, поэтому и время построение очень маленькое. У Вас может быть больше.&lt;/p&gt;
  &lt;p id=&quot;Ai8q&quot;&gt;Итак, что мы видим в приложении Docker Desktop:&lt;/p&gt;
  &lt;figure id=&quot;tEHK&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/54/16/5416d981-508b-4e5a-a917-ef0b7da1b915.png&quot; width=&quot;2026&quot; /&gt;
    &lt;figcaption&gt;Как выглядит Docker Desktop&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;sGUj&quot;&gt;Workspace — многоконтейнерное приложение. Имя этого приложения подтягивается от нашей рабочей директории.&lt;br /&gt;Jenkins-1 — наш контейнер.&lt;/p&gt;
  &lt;p id=&quot;bKtT&quot;&gt;Перейдем по двум портам, которые у нас открыты. Порт 5000 нас пока что не интересует, поэтому перейдем по 8080.&lt;/p&gt;
  &lt;figure id=&quot;hRok&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/4d/ae/4dae3068-522f-4db8-980a-cce7dfcad238.png&quot; width=&quot;1488&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;n2MN&quot;&gt;Нам нужно ввести пароль, который лежит внутри контейнера.&lt;/p&gt;
  &lt;p id=&quot;GG41&quot;&gt;Кликнув по имени контейнера мы можем посмотреть его логи:&lt;/p&gt;
  &lt;figure id=&quot;HvjP&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/a2/40/a240f6c1-3268-44ae-ab54-8f906aa20f1f.png&quot; width=&quot;2024&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;p4S6&quot;&gt;c7e456fbad25460190ff7d2ec416734d — наш пароль. Введем его.&lt;/p&gt;
  &lt;figure id=&quot;C73L&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/b7/ab/b7ab0eac-f21c-41cb-ae72-644471fafd94.png&quot; width=&quot;1486&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;laVT&quot;&gt;Теперь нас спрашивают, какие плагины мы хотим установить. Устанавливаем те, которые сообщество Jenkins использует больше всего.&lt;/p&gt;
  &lt;figure id=&quot;Gf1F&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/d6/c9/d6c94471-2e36-4355-a3ee-06237fe68a2e.png&quot; width=&quot;1486&quot; /&gt;
    &lt;figcaption&gt;Процесс установки плагинов&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Xkh0&quot;&gt;После установки нас просят создать Админа&lt;/p&gt;
  &lt;figure id=&quot;rQW7&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/0d/4c/0d4cae85-9bd5-497f-a285-a76a162d56cc.png&quot; width=&quot;1486&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;3S7q&quot;&gt;Потом предлагают поменять ссылку, по которой доступен Jenkins. Мы же не будем ничего менять&lt;/p&gt;
  &lt;figure id=&quot;Rz4Z&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/8b/a8/8ba8c1d1-9afc-4fcf-a609-4fcf9349d959.png&quot; width=&quot;1487&quot; /&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;D4Rw&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/0f/c7/0fc72ee3-b389-4090-9214-d378dd6608d9.png&quot; width=&quot;1488&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;03wJ&quot;&gt;Наш Jenkins готов к использованию!&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h3 id=&quot;fvO1&quot;&gt;Начало работы с Jenkins&lt;/h3&gt;
  &lt;p id=&quot;XELA&quot;&gt;Главная страница Jenkins выглядит так:&lt;/p&gt;
  &lt;figure id=&quot;qM0n&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/f5/5f/f55f2e5e-ef17-4170-a0df-040a6c49c720.png&quot; width=&quot;1717&quot; /&gt;
    &lt;figcaption&gt;Jenkins dashboard&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;ToRL&quot;&gt;Давайте создадим item (job). &lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;ZIZq&quot;&gt;Job (Джоба) — в контексте DevOps — единица работы&lt;/p&gt;
  &lt;/section&gt;
  &lt;figure id=&quot;MVo6&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/4b/dc/4bdceaf3-672d-4772-95ff-4acc5513eeb7.png&quot; width=&quot;1717&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;W122&quot;&gt;Мы выберем свободную конфигурацию и имя BanditWithJenkins.&lt;/p&gt;
  &lt;p id=&quot;hNEE&quot;&gt;Настройка нашей джобы выглядет так:&lt;/p&gt;
  &lt;figure id=&quot;q4r3&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/0a/f9/0af9c3d7-143d-48c6-9be5-119809745861.png&quot; width=&quot;1692&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;ono8&quot;&gt;Для нашей статьи хватит флажка GitHub project. &lt;/p&gt;
  &lt;p id=&quot;2KNn&quot;&gt;Теперь вставим ссылку на репозиторий GitHub из прошлой статьи:&lt;/p&gt;
  &lt;figure id=&quot;7NM1&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/22/c4/22c493a0-fc03-4e98-b07e-a1240128e994.png&quot; width=&quot;1143&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;HBkk&quot;&gt;Теперь внизу страницы добавим шаг сборки, а именно выполнение команды Shell. Для проверки работоспособности введем обычный Hello, world! И сохраним изменения.&lt;/p&gt;
  &lt;figure id=&quot;s6dI&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/35/da/35dacd4b-8459-4d83-9db2-bf5d464c7edd.png&quot; width=&quot;1155&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;6XbB&quot;&gt;Теперь попробуем собрать наш проект&lt;/p&gt;
  &lt;figure id=&quot;dlRi&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/ec/f4/ecf41c00-a8bf-4059-a9b3-f2b2ca7f72e7.png&quot; width=&quot;1717&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;aeTK&quot;&gt;Во вкладке Build у нас появилась сборка и она успешна&lt;/p&gt;
  &lt;figure id=&quot;ZzZy&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/41/39/41394c34-2466-4097-9fca-1984e2f4fb7d.png&quot; width=&quot;500&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;fHv4&quot;&gt;Заглянем внутрь данной сборки:&lt;/p&gt;
  &lt;figure id=&quot;LKqV&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/69/4f/694f736f-fc7b-4b25-8acd-446d8ed2de51.png&quot; width=&quot;1708&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;bxGh&quot;&gt;Здесь мы видим краткую информацию, такую как: время выполнения, создателя и т. д.&lt;/p&gt;
  &lt;p id=&quot;1G8W&quot;&gt;Но нас интересует вывод консоли&lt;/p&gt;
  &lt;figure id=&quot;ZsmV&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/3a/49/3a494e8f-1c06-4f2f-879f-72d7ef5b0556.png&quot; width=&quot;1191&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;YYZA&quot;&gt;Результат нас устраивает. Теперь перейдем к Bandit.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h3 id=&quot;bBmf&quot;&gt;Настройка Bandit&lt;/h3&gt;
  &lt;p id=&quot;EHt1&quot;&gt;Нам нужно добавить новые команды в наш проект:&lt;/p&gt;
  &lt;figure id=&quot;AB49&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/af/cf/afcfb1f3-1c0b-4e1b-8ea0-c80037652811.png&quot; width=&quot;1145&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;tQCE&quot;&gt;После запуска Jenkins проведет сканирование нашего кода, создаст уникальный текстовый файл и выведет его содержимое в консоль.&lt;/p&gt;
  &lt;p id=&quot;2UF8&quot;&gt;Текущий вывод выглядит так:&lt;/p&gt;
  &lt;figure id=&quot;maMJ&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/74/26/74269bb9-4534-4d81-a2a8-176ed0b948e9.png&quot; width=&quot;1699&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;AIXQ&quot;&gt;Bandit запустился, но ничего не просканировал. Потому что мы забыли добавить управление исходным кодом. Исправим это в настройках проекта. Репозиторий открытый, так что данные (Credentials) для доступа к нему можно не настраивать.&lt;/p&gt;
  &lt;figure id=&quot;qyjt&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/6f/28/6f2873d2-1d61-4991-b3ee-f67c6db03a49.png&quot; width=&quot;1216&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;DMBT&quot;&gt;А вот это уже интересно:&lt;/p&gt;
  &lt;figure id=&quot;Shdz&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/9b/f4/9bf41bf0-db6f-4ddf-9849-c5ad68935c74.png&quot; width=&quot;454&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Z9Qo&quot;&gt;Ошибка сборки, давайте посмотрим, что случилось.&lt;/p&gt;
  &lt;figure id=&quot;4weq&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/fc/a1/fca1d9a9-2583-41f3-b822-16a3102c6c46.png&quot; width=&quot;1165&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;qnPZ&quot;&gt;Первое выделение говорит нам о том, что мы правильно поменяли настройки и теперь наш проект клонирует репозиторий GitHub. А вот второе выделение по началу непонятно, но сейчас все объясню.&lt;br /&gt;Когда Bandit находит угрозу, он возвращает &lt;em&gt;false&lt;/em&gt;. Jenkins воспринимает &lt;em&gt;false &lt;/em&gt;как ошибку, поэтому, делаем следующее:&lt;br /&gt;Меняем команду, чтобы текущий шаг всегда возвращал &lt;em&gt;true&lt;/em&gt;.&lt;/p&gt;
  &lt;figure id=&quot;ilmw&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/f7/4f/f74f93c0-ff19-4ae2-a1d7-97de476eddb2.png&quot; width=&quot;1164&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;KRDa&quot;&gt;Сохранив изменения и запустив сборку видим следующее (#5 потому что 4-ую из-за человеческого фактора пришлось удалить, не обращайте внимания):&lt;/p&gt;
  &lt;figure id=&quot;R48I&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/ec/a6/eca65dc1-66d7-44c6-88a6-007cb26ab398.png&quot; width=&quot;514&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;dRT5&quot;&gt;Вывод следующий:&lt;/p&gt;
  &lt;figure id=&quot;ojv3&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/d4/68/d46845ae-fb9c-438c-bc84-450cb9fb882a.png&quot; width=&quot;1108&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;91Jx&quot;&gt;Прекрасно! Все работает.&lt;/p&gt;
  &lt;p id=&quot;Tj6d&quot;&gt;Все наши файлы доступны внутри контейнера по пути var/jenkins_home/workspace/BanditWithJenkins. (Метка Volume подтверждает, что все мы настроили правильно и при перезапуске контейнера эти файлы не пропадут)&lt;/p&gt;
  &lt;figure id=&quot;YKF5&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/d1/72/d1721f57-c060-4461-8923-e5aa5cc3a702.png&quot; width=&quot;1255&quot; /&gt;
  &lt;/figure&gt;
  &lt;hr /&gt;
  &lt;h3 id=&quot;epqG&quot;&gt;Настройка агента Jenkins&lt;/h3&gt;
  &lt;p id=&quot;0xj6&quot;&gt;Теперь настало время сделать все по уму. Небезопасно выполнять тесты на машине, где установлен Jenkins. Поэтому создадим Jenkins agent.&lt;/p&gt;
  &lt;p id=&quot;LAKj&quot;&gt;Итак, изменим наш Docker-compose файл:&lt;/p&gt;
  &lt;pre id=&quot;xL9K&quot; data-lang=&quot;yaml&quot;&gt;version: &amp;#x27;3.8&amp;#x27;

services:
  jenkins:
    build: .
    ports:
      - &amp;quot;8080:8080&amp;quot;
      - &amp;quot;50000:50000&amp;quot;
    volumes:
      - jenkins_home:/var/jenkins_home
    networks:
      - jenkins

  agent:
    build: /for_ubuntu
    ports:
      - &amp;quot;2673:2673&amp;quot;
    volumes:
      - agent_home:/var/agent_home
    networks:
      - jenkins

volumes:
  jenkins_home:
  agent_home:

networks:
  jenkins:&lt;/pre&gt;
  &lt;p id=&quot;qJJ9&quot;&gt;В папке for_ubuntu создадим еще один Dockerfile:&lt;/p&gt;
  &lt;pre id=&quot;NMw6&quot; data-lang=&quot;dockerfile&quot;&gt;FROM ubuntu:latest

# Устанавливаем необходимые пакеты и Bandit
RUN apt-get update 
RUN apt-get upgrade -y 
RUN apt-get install virtualenv -y 
RUN virtualenv bandit-env 
RUN . bandit-env/bin/activate 
RUN apt-get install python3 -y 
RUN apt-get install python3-pip -y 
RUN apt install python3-bandit -y 
RUN apt-get install ssh -y 
RUN apt-get install curl -y
RUN apt-get install -y openjdk-17-jdk

CMD [&amp;quot;sleep&amp;quot;, &amp;quot;infinity&amp;quot;]&lt;/pre&gt;
  &lt;p id=&quot;LX4o&quot;&gt;Теперь наша рабочая директория должна выглядеть так:&lt;/p&gt;
  &lt;pre id=&quot;hVFy&quot;&gt;|-workspace
 |--for_ubuntu
  |--Dockerfile
 |--docker-compose.yml
 |--Dockerfile &lt;/pre&gt;
  &lt;p id=&quot;1vQ5&quot;&gt;Команда Docker-compose up -d запустит наше приложение. В этот раз никаких команд не было кэшировано, отсюда и долгий запуск (703 секунды).&lt;/p&gt;
  &lt;figure id=&quot;KJRj&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/bb/53/bb538c16-2c14-40ce-90b7-f2f62fb5ea98.png&quot; width=&quot;1195&quot; /&gt;
    &lt;figcaption&gt;Пример успешного запуска приложения&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;m9P0&quot;&gt;Итак, зайдя на &lt;a href=&quot;http://localhost:8080&quot; target=&quot;_blank&quot;&gt;http://localhost:8080&lt;/a&gt; нас встречает окно логина в Jenkins. Что подтверждает правильность наших настроек, ведь если бы у Jenkins были удаленны все данные, то регистрация началась бы заново.&lt;/p&gt;
  &lt;figure id=&quot;KjCh&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/cc/ef/ccef79f6-4208-4fa0-89aa-eb95bae0d313.png&quot; width=&quot;1717&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Ozz8&quot;&gt;Приступим к созданию &lt;strong&gt;агента&lt;/strong&gt;. &lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;WTTQ&quot;&gt;&lt;strong&gt;Jenkins Agent&lt;/strong&gt; — компонент системы Jenkins на другой машине. Он будет выполнять команды, которые дал ему наш основной сервис.&lt;/p&gt;
  &lt;/section&gt;
  &lt;p id=&quot;Jy2s&quot;&gt;Кстати, даже сам Jenkins говорит нам настроить агента:&lt;/p&gt;
  &lt;figure id=&quot;B6gH&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/c0/f0/c0f068fc-10d7-4606-b135-8bf5b7801b98.png&quot; width=&quot;1718&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;r5Na&quot;&gt;Мы пойдем по длинному пути через кнопку «Настроить Jenkins».&lt;/p&gt;
  &lt;figure id=&quot;dF1u&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/48/27/48274179-07be-4212-a31a-bc8de4dd89d0.png&quot; width=&quot;1683&quot; /&gt;
    &lt;figcaption&gt;Настройки Jenkins&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;r0jC&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/38/0f/380f436c-eb16-4a00-aecb-d1f05fc06307.png&quot; width=&quot;1692&quot; /&gt;
    &lt;figcaption&gt;Ноды или Узлы Jenkins и их настройки&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;reD4&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/64/af/64af28ad-9284-4b83-ac53-582dd4195241.png&quot; width=&quot;954&quot; /&gt;
    &lt;figcaption&gt;Создание новой Ноды или Узла&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;JKXG&quot;&gt;Итак, остановимся подробнее на этом скриншоте:&lt;/p&gt;
  &lt;figure id=&quot;noKc&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/15/e9/15e935ca-ef88-40ed-88d6-6bc85930c145.png&quot; width=&quot;1693&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Jtuf&quot;&gt;Нас просят указать удаленные корневую директорию. Мы укажем наш Volume, который прописывали в Docker-compose «/var/agent_home»&lt;/p&gt;
  &lt;p id=&quot;20JA&quot;&gt;В способе запуска выбираем «Запустить агент, подключив его к контроллеру», затем сохраняем изменения.&lt;/p&gt;
  &lt;figure id=&quot;SSoU&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/9f/c6/9fc6d716-9950-4987-adda-6dcf10a8a391.png&quot; width=&quot;1680&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;8ofs&quot;&gt;Нас перенаправит на страницу настройки нод\узлов. Нажимаем на наш недавно созданный агент.&lt;/p&gt;
  &lt;figure id=&quot;8tqt&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/fc/07/fc07143f-4075-47ff-b21e-9b527e51eb9b.png&quot; width=&quot;1682&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;4qlf&quot;&gt;И нам сразу же дают команды, которые мы должны выполнить внутри Docker контейнера:&lt;/p&gt;
  &lt;figure id=&quot;JVX6&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/7c/dc/7cdc00fa-9ad4-4ffe-b73b-bc33701fd733.png&quot; width=&quot;1688&quot; /&gt;
  &lt;/figure&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;jJzS&quot;&gt;Важное уточнение:&lt;br /&gt;Нам нужен IP сервера. И именно на этот IP мы меняем localhost в командах, которые нам дали. &lt;/p&gt;
  &lt;p id=&quot;EotG&quot; data-align=&quot;center&quot;&gt;Пример:&lt;br /&gt;Была команда &lt;strong&gt;&lt;em&gt;curl -sO &lt;a href=&quot;http://localhost:8080/jnlpJars/agent.jar&quot; target=&quot;_blank&quot;&gt;http://localhost:8080/jnlpJars/agent.jar&lt;/a&gt;&lt;/em&gt;&lt;br /&gt;&lt;/strong&gt;Стала&lt;strong&gt; &lt;em&gt;curl -sO &lt;a href=&quot;http://172.18.0.2:8080/jnlpJars/agent.jar&quot; target=&quot;_blank&quot;&gt;http://172.18.0.3:8080/jnlpJars/agent.jar&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;QXv2&quot; data-align=&quot;center&quot;&gt;IP контейнера можно посмотреть через команду docker container inspect &amp;lt;container_name_or_id&amp;gt;&lt;/p&gt;
  &lt;figure id=&quot;fLTb&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/f1/46/f1463dd9-7f66-45c1-a74e-cd27bd38b535.png&quot; width=&quot;447&quot; /&gt;
  &lt;/figure&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;YQpC&quot;&gt;Заходим в Docker и выполняем эти команды. &lt;/p&gt;
  &lt;p id=&quot;hiqe&quot;&gt;Если не менять localhost, ответ следующий:&lt;/p&gt;
  &lt;figure id=&quot;JWwu&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/8c/11/8c1155cb-4572-41fb-a647-ab3cf80d3331.png&quot; width=&quot;1768&quot; /&gt;
    &lt;figcaption&gt;Отрицательный ответ&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;POXS&quot;&gt;Если поменяем:&lt;/p&gt;
  &lt;figure id=&quot;KFGK&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/40/32/403261a6-3cfa-43a4-aba1-9d1aa073a4e4.png&quot; width=&quot;1093&quot; /&gt;
    &lt;figcaption&gt;Положительный ответ&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;42ym&quot;&gt;Также пропал крестик на иконке нашего агента&lt;/p&gt;
  &lt;figure id=&quot;6K1Y&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/09/a1/09a108bd-577a-4b13-8392-4fe2e63bd64c.png&quot; width=&quot;253&quot; /&gt;
  &lt;/figure&gt;
  &lt;hr /&gt;
  &lt;h3 id=&quot;nUSR&quot;&gt;Собираем проект через агента&lt;/h3&gt;
  &lt;p id=&quot;R7LB&quot;&gt;Все что осталось, так это перейти в настройки нашей джобы, поставить вот такой флажок:&lt;/p&gt;
  &lt;figure id=&quot;fSMH&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/1b/14/1b146b25-8181-4ec9-b007-08fa29943b15.png&quot; width=&quot;861&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;4f4v&quot;&gt;А в его поле выбрать нашего агента:&lt;/p&gt;
  &lt;figure id=&quot;gURU&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/32/e7/32e77ef4-1213-4b21-ab04-1f01cfda13aa.png&quot; width=&quot;1144&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;dWaa&quot;&gt;Все, сохраняем и запускаем.&lt;/p&gt;
  &lt;p id=&quot;aXKF&quot;&gt;Сборка успешна:&lt;/p&gt;
  &lt;figure id=&quot;210g&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/93/75/937558ec-1c64-4a9b-b5c7-ba91e1baaa4d.png&quot; width=&quot;497&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;M8kF&quot;&gt;Вывод такой же:&lt;/p&gt;
  &lt;figure id=&quot;oo76&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/b2/ee/b2ee69d9-a6f3-4b72-a9e9-a4422f47d0ef.png&quot; width=&quot;1107&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;hRW4&quot;&gt;Дабы доказать, что сканирование проводил агент, мы найдем файл с результатами именно в нем. И да, файл находится в томе нашего агента:&lt;/p&gt;
  &lt;figure id=&quot;RKcs&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/33/7e/337ee67c-43a0-4d1b-bb3d-a8afdc8965ca.png&quot; width=&quot;1475&quot; /&gt;
  &lt;/figure&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;dupK&quot;&gt;Что же, в этой статье мы поверхностно затронули Jenkins, научились настраивать и коннектить агентов внутри многоконтейнерного приложения и запускать джобы на агентах. &lt;/p&gt;
  &lt;p id=&quot;8jD0&quot;&gt;Критику, желательно конструктивную, жду в комментариях.&lt;/p&gt;
  &lt;p id=&quot;JHPD&quot;&gt;В следующих статьях, как и обещал, продолжим разговаривать про инструменты DevSecOps.&lt;/p&gt;
  &lt;blockquote id=&quot;J9dH&quot; data-align=&quot;center&quot;&gt;Всем добра!&lt;/blockquote&gt;

</content></entry><entry><id>zloytapochek:6TINAD4sbTh</id><link rel="alternate" type="text/html" href="https://teletype.in/@zloytapochek/6TINAD4sbTh?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=zloytapochek"></link><title>Поговорим про DevSecOps. Bandit</title><published>2025-01-01T10:37:40.483Z</published><updated>2025-01-01T10:47:42.754Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/d1/28/d1287abb-6f99-4db1-a568-a9824006462c.png"></media:thumbnail><category term="informacionnaya-bezopasnost-ib" label="Информационная безопасность (ИБ)"></category><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/47/4c/474c102a-10d5-4105-a485-212bad8b1003.png&quot;&gt;Вы когда-нибудь задумывались о безопасности кода, который вы пишите? Глупый вопрос, знаю. Конечно задумывались, но насколько глубоко погружались в эту тему? Сегодня я помогу вам. Я начинаю цикл небольших статей на тему инструментов DevSecOps. Будет интересно, давайте начнем.</summary><content type="html">
  &lt;p id=&quot;JGcC&quot;&gt;Вы когда-нибудь задумывались о безопасности кода, который вы пишите? Глупый вопрос, знаю. Конечно задумывались, но насколько глубоко погружались в эту тему? Сегодня я помогу вам. Я начинаю цикл небольших статей на тему инструментов DevSecOps. Будет интересно, давайте начнем.&lt;/p&gt;
  &lt;p id=&quot;XDP2&quot;&gt;Т.к. эта статья первая, было бы неправильно не рассказать о главной теме наших разговоров. Что такое DevSecOps? При запросе в поисковиках вы получите скучный, но верный ответ «DevSecOps — методология безопасной разработки». Предлагаю перевести это в более читабельный вид. Для этого немного истории. Раньше разработка приложений шла примерно так:&lt;/p&gt;
  &lt;p id=&quot;v0L3&quot;&gt;Команда разработки получает заказ на определенную тему. Далее они планируют, как всё это реализовать. В конце концов, через определённый промежуток времени реализовывают, а потом приходит отдел безопасности и говорит, что у них найдена критическая уязвимость (вставить шутку про дыру в безопасности). И цикл разработки уходит на очередной круг.&lt;/p&gt;
  &lt;figure id=&quot;fyF3&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/79/eb/79eb11b2-4270-4a98-9d0c-ea5289675d7f.jpeg&quot; width=&quot;640&quot; /&gt;
    &lt;figcaption&gt;Та самая шутка про дыру в безопасности&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;xyMS&quot;&gt;DevSecOps старается внедрить отдел безопасности как можно раньше в процесс разработки.&lt;/p&gt;
  &lt;p id=&quot;axLT&quot;&gt;Есть несколько типов инструментов DevSecOps:&lt;/p&gt;
  &lt;ul id=&quot;sBGj&quot;&gt;
    &lt;li id=&quot;xDDA&quot;&gt;&lt;strong&gt;SAST (Static Application Security Testing)&lt;/strong&gt;: такие как SonarQube, Checkmarx и Fortify, анализируют исходный код на наличие уязвимостей до его выполнения.&lt;/li&gt;
    &lt;li id=&quot;AXmf&quot;&gt;&lt;strong&gt;DAST (DynamicApplicationSecurityTesting)&lt;/strong&gt;: OWASP ZAP, Burp Suite и подобные инструменты тестируют приложение в работающем состоянии, выявляя уязвимости. &lt;/li&gt;
    &lt;li id=&quot;Ees8&quot;&gt;&lt;strong&gt;Сканеры уязвимостей&lt;/strong&gt;: например, Nessus, Qualys и OpenVAS, которые помогают находить уязвимости в инфраструктуре и приложениях.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;huIr&quot;&gt;Наш сегодняшний гость — &lt;a href=&quot;https://github.com/PyCQA/bandit&quot; target=&quot;_blank&quot;&gt;Bandit&lt;/a&gt;. Не в прямом смысле этого слова конечно же. Bandit относится к первой группе инструментов. Давайте поближе его рассмотрим.&lt;/p&gt;
  &lt;p id=&quot;4PoT&quot;&gt;Этот инструмент специализируется на Python, что весьма актуально. Вот краткое описание из официальной документации:&lt;/p&gt;
  &lt;blockquote id=&quot;WeVJ&quot;&gt;Bandit — это инструмент, предназначенный для поиска распространенных проблем безопасности в коде Python. Для этого Bandit обрабатывает каждый файл, строит из него AST и запускает соответствующие плагины к узлам AST. Как только Bandit завершит сканирование всех файлов, он создаст отчет.&lt;/blockquote&gt;
  &lt;p id=&quot;vhJq&quot;&gt;Что же, давайте посмотрим на него в деле.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;qxGY&quot;&gt;Далее будет использоваться &lt;a href=&quot;https://github.com/simple-login/app&quot; target=&quot;_blank&quot;&gt;открытый репозиторий с GitHub&lt;/a&gt;, поэтому стоит сделать небольшое отступление.Данная статье не несет цели в каком-либо виде оскорбить авторов данного репозитория или ущемить их права. Данная статья — исследование, производимое в учебных целях. Спасибо, за понимание.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;ftsR&quot;&gt;Итак, начнем. Предварительно я установил Bandit, прописав следующую команду:&lt;/p&gt;
  &lt;pre id=&quot;y3Cg&quot; data-lang=&quot;shell&quot;&gt;pip install bandit&lt;/pre&gt;
  &lt;p id=&quot;TcJ6&quot;&gt;Теперь, распаковав скачанный репозиторий начнем сканирование. Для этого стоит перейти в нужный нам каталок, у меня это «F:\Education\Examples\app-master» и ввести команду&lt;/p&gt;
  &lt;pre id=&quot;mnwl&quot; data-lang=&quot;bash&quot;&gt;bandit -r .&lt;/pre&gt;
  &lt;ul id=&quot;gmPK&quot;&gt;
    &lt;li id=&quot;Bawl&quot;&gt;bandit — наименование нашего инструмента&lt;/li&gt;
    &lt;li id=&quot;8vj1&quot;&gt;-r — флаг, обозначающий сканирование директории&lt;/li&gt;
    &lt;li id=&quot;qohz&quot;&gt;. — путь к директории. В данном случае к той, в которой находимся&lt;/li&gt;
  &lt;/ul&gt;
  &lt;figure id=&quot;xaZc&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/ad/78/ad7841dd-0423-4ca4-b76b-ebef1b863dcb.png&quot; width=&quot;648&quot; /&gt;
    &lt;figcaption&gt;Первый вывод после запуска&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;bTrH&quot;&gt;Запустив программу нам выведет информацию о текущей конфигурации, но это не совсем то, что мы ищем. &lt;/p&gt;
  &lt;p id=&quot;9EXQ&quot;&gt;Подождав, мы видим следующее:&lt;/p&gt;
  &lt;figure id=&quot;9ZlV&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/d4/7b/d47b2fab-9a34-46e6-9218-fb2ce1b68690.png&quot; width=&quot;742&quot; /&gt;
    &lt;figcaption&gt;Итоговый отчет&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;vT1p&quot;&gt;Bandit выдал нам отчет, давайте разберем его. &lt;/p&gt;
  &lt;p id=&quot;n7uB&quot;&gt;Мы видим три основных раздела:&lt;/p&gt;
  &lt;ul id=&quot;LG8b&quot;&gt;
    &lt;li id=&quot;C6eE&quot;&gt;Code scanned&lt;/li&gt;
    &lt;li id=&quot;dEXt&quot;&gt;Run metrics&lt;/li&gt;
    &lt;li id=&quot;42Ki&quot;&gt;Files skipped&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;zobO&quot;&gt;В первом разделе нам сообщается об общем количестве сканированных строчек кода.&lt;br /&gt;Во втором разделе мы видим самое главное — общее количество уязвимостей, разделенных на угрозы по уровню &lt;strong&gt;серьезности (severity)&lt;/strong&gt; и по уровню &lt;strong&gt;доверия (confidence)&lt;/strong&gt;. Помимо этого все угрозы подразделяются по уровням риска: неопределенный (Undifined), низкий (Low), средний (Medium), высокий (High).&lt;/p&gt;
  &lt;p id=&quot;jm9N&quot;&gt;Общее количество посмотрели, хорошо. Но что насчет конкретных угроз? И эту потребность Bandit закрывает. Между первым и вторым скриншотами у нас выводятся конкретные проблемы с номерами строчек кода и файлами, где эта проблема находится:&lt;/p&gt;
  &lt;figure id=&quot;4xOs&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/07/6c/076c56b9-6ee5-48f8-9a2f-8bb06afe8771.png&quot; width=&quot;1689&quot; /&gt;
    &lt;figcaption&gt;Вывод конкретной уязвимости&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;UfDS&quot;&gt;Но есть одна проблема. У нас уязвимостей около 2х тысяч. и на каждую приходится около 10 строк в командной строке. И она просто будет удалять историю. Предлагаю вывести все отчеты в один отдельный файл. Сделаем это командой&lt;/p&gt;
  &lt;pre id=&quot;O6ec&quot; data-lang=&quot;bash&quot;&gt;bandit -r . -o result.json&lt;/pre&gt;
  &lt;p id=&quot;4T6c&quot;&gt;Где флаг -o означает путь к файлу, в который будет выведен отчет.&lt;/p&gt;
  &lt;p id=&quot;G4yf&quot;&gt;И нам выведет ошибку. Bandit’у нужно сказать, чтобы он переформатировал выходные данные в txt. Финальная команда выглядит так:&lt;/p&gt;
  &lt;pre id=&quot;7DJ6&quot; data-lang=&quot;bash&quot;&gt;bandit -r . -o result.json -f txt&lt;/pre&gt;
  &lt;p id=&quot;fle2&quot;&gt;Ну или &lt;/p&gt;
  &lt;pre id=&quot;QHG7&quot; data-lang=&quot;bash&quot;&gt;bandit -r . -o result.txt -f txt&lt;/pre&gt;
  &lt;p id=&quot;8vQw&quot;&gt;Давайте посмотрим что получилось.&lt;/p&gt;
  &lt;figure id=&quot;QuYI&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/08/16/081625af-3e40-4e43-88e2-cb072e0be701.png&quot; width=&quot;1805&quot; /&gt;
    &lt;figcaption&gt;Отчет в формате текстового файла, открытый в Notepad++&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;pxTb&quot;&gt;И все работает! У нас есть отчет на 21507 строк. Передаем его программистам и пусть трудятся😁&lt;/p&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;JLAK&quot;&gt;В целом, Bandit — прекрасный, &lt;u&gt;бесплатный&lt;/u&gt; инструмент и определенно заслуживает внимания.&lt;br /&gt;В следующих статьях рассмотрим и другие инструменты DevSecOps.&lt;/p&gt;
  &lt;blockquote id=&quot;5Akv&quot; data-align=&quot;center&quot;&gt;Всем добра!&lt;/blockquote&gt;

</content></entry><entry><id>zloytapochek:HnpdNW3cW8D</id><link rel="alternate" type="text/html" href="https://teletype.in/@zloytapochek/HnpdNW3cW8D?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=zloytapochek"></link><title>Поговорим про терминал</title><published>2024-12-30T15:10:06.023Z</published><updated>2025-01-01T10:09:16.579Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/1e/0e/1e0efe46-9c7c-4342-8dff-ad38b4653d25.png"></media:thumbnail><category term="soft-soft" label="Софт / Soft"></category><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/01/d8/01d8b2b7-d433-4098-84d4-3a341f63a2c8.png&quot;&gt;Ежедневно каждый из нас использует компьютер. Это может быть смартфон, ноутбук или полноценная рабочая станция, ну или другие представители семейства вычислительных машин. Сейчас, если попросить человека представить компьютер или какую-нибудь программу, то он начнет описывать ее графический интерфейс. Но раньше графических интерфейсов не было. Людям приходилось прописывать все команды через терминал, который, по сути, был экраном с клавиатурой.</summary><content type="html">
  &lt;p id=&quot;xBPZ&quot;&gt;Ежедневно каждый из нас использует компьютер. Это может быть смартфон, ноутбук или полноценная рабочая станция, ну или другие представители семейства вычислительных машин. Сейчас, если попросить человека представить компьютер или какую-нибудь программу, то он начнет описывать ее графический интерфейс. Но раньше графических интерфейсов не было. Людям приходилось прописывать все команды через терминал, который, по сути, был экраном с клавиатурой.&lt;/p&gt;
  &lt;figure id=&quot;jiNC&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/80/74/8074964d-cf3e-438b-92e7-61bc6692fe7a.png&quot; width=&quot;1600&quot; /&gt;
    &lt;figcaption&gt;Терминал операционной системы&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;kuu9&quot;&gt;Но для людей, увлеченных миром компьютеров, которые проводят за ними много времени, разрабатывая различные проекты и решая задачи, терминал представляется как-то так:&lt;/p&gt;
  &lt;figure id=&quot;tk2v&quot; class=&quot;m_column&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://external-content.duckduckgo.com/iu/?u=http%3A%2F%2F1.bp.blogspot.com%2F-MRZev59T3zA%2FVPm04nVrGzI%2FAAAAAAAACgA%2F5d02jspcnbE%2Fs1600%2F%25D0%25A1%25D0%25BD%25D0%25B8%25D0%25BC%25D0%25BE%25D0%25BA%252B%25D1%258D%25D0%25BA%25D1%2580%25D0%25B0%25D0%25BD%25D0%25B0%252B%25D0%25BE%25D1%2582%252B2015-03-06%252B14%3A37%3A08.png&amp;f=1&amp;nofb=1&amp;ipt=1057a233177c9472498aed5006ce49d83f7fb4b1e26678ac4377bd53166f550c&amp;ipo=images&quot; width=&quot;1598&quot; /&gt;
    &lt;figcaption&gt;Скриншот QTerminal для Linux&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;imfh&quot;&gt;Вот о функционале подобных терминалов мы и поговорим.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;section style=&quot;background-color:hsl(hsl(170, 33%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;h3 id=&quot;Gnvm&quot;&gt;Интересный факт&lt;/h3&gt;
    &lt;p id=&quot;CMZJ&quot;&gt;Как уже упоминалось, терминал изначально представлял собой простое устройство, состоящее из экрана и клавиатуры. В современном мире, когда мы говорим о «терминале», на самом деле мы имеем в виду эмулятор терминала. Однако, с учетом стремительного прогресса и уменьшения использования устаревших технологий, мы все реже задумываемся о различиях. Честно говоря, это упрощает нашу жизнь, и поэтому мы предпочитаем называть его просто «терминалом».&lt;/p&gt;
  &lt;/section&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;R6KY&quot;&gt;Итак, в качестве примера мы возьмем оболочку Bash. В этой статье мы познакомимся с основными командами, которые могут быть вам незнакомы, а также с интересными возможностями, которые она предлагает.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;PqC1&quot;&gt;В своей жизни, когда мне нужно посчитать что-то сложное, я захожу в Windows Terminal и выполняю команду «python». И уже в нем высчитываю то, что мне нужно. А знали ли вы, что можно Bash может считать выражения тоже? Для этого нужно выполнить команду &lt;strong&gt;expr.&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;Hna3&quot; data-lang=&quot;bash&quot;&gt;$ expr 123 + 945 * 2 + 45
2058&lt;/pre&gt;
  &lt;p id=&quot;wQGV&quot;&gt;Да и вообще на оболочках можно писать программы. Они имеют свой синтаксис для объявления переменных:&lt;/p&gt;
  &lt;pre id=&quot;b1BR&quot; data-lang=&quot;bash&quot;&gt;$ first=&amp;quot;Hello&amp;quot;
$ second=&amp;quot;World!&amp;quot;
$ mid=&amp;quot;,&amp;quot;
$ echo $first$mid $second
Hello, World!&lt;/pre&gt;
  &lt;p id=&quot;fV5G&quot;&gt;Для создания циклов:&lt;/p&gt;
  &lt;pre id=&quot;0I2O&quot; data-lang=&quot;bash&quot;&gt;$ for i in {1..10}; do   echo $i; done
1
2
3
4
5
6
7
8
9
10&lt;/pre&gt;
  &lt;p id=&quot;v9YZ&quot;&gt;И т. д.&lt;br /&gt;В этих примерах используется команда «echo», надеюсь, что все с ней знакомы.&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(170, 33%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;XXWZ&quot;&gt;Только не пишите полноценные программы на оболочках. Они для этого не оптимизированы👀&lt;/p&gt;
  &lt;/section&gt;
  &lt;p id=&quot;uo4x&quot;&gt;Также, оболочка умеет хранить историю выполненных команд. Вывести их список мы можем путем ввода следующей команды:&lt;/p&gt;
  &lt;pre id=&quot;8bda&quot; data-lang=&quot;bash&quot;&gt;$ history&lt;/pre&gt;
  &lt;p id=&quot;wNtk&quot;&gt;Впору упомянуть, что переменные оболочка тоже хранит. И чтобы удалить переменную нужно ввести:&lt;/p&gt;
  &lt;pre id=&quot;wpJK&quot; data-lang=&quot;bash&quot;&gt;$ unset имя_файла&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;qmNU&quot;&gt; Что там по работе с файлами?&lt;/p&gt;
  &lt;p id=&quot;eSkh&quot;&gt;Команда cat поможет прочитать содержимое файл, это мы знаем. А если нам нужно вывести только первые или последние n строк?&lt;/p&gt;
  &lt;p id=&quot;k1po&quot;&gt;В первом случае нам поможет следующая команда:&lt;/p&gt;
  &lt;pre id=&quot;qudR&quot; data-lang=&quot;bash&quot;&gt;$ head -n 10 имя_файла&lt;/pre&gt;
  &lt;p id=&quot;tWLi&quot;&gt;Во втором случае:&lt;/p&gt;
  &lt;pre id=&quot;Qp0i&quot; data-lang=&quot;bash&quot;&gt;$ tail -n 10 имя_файла&lt;/pre&gt;
  &lt;p id=&quot;SIZQ&quot;&gt;Ах да, чтобы прочитать файл, сначала нужно его создать. Что же, команда touch спешит на помощь&lt;/p&gt;
  &lt;pre id=&quot;VmZh&quot; data-lang=&quot;bash&quot;&gt;$ touch имя_файла&lt;/pre&gt;
  &lt;p id=&quot;APsv&quot;&gt;В качестве аналога ctrl+f используется команда grep&lt;/p&gt;
  &lt;pre id=&quot;rWEy&quot; data-lang=&quot;bash&quot;&gt;$ grep &amp;quot;то что нужно найти&amp;quot; имя_файла&lt;/pre&gt;
  &lt;p id=&quot;CK8Z&quot;&gt;Если нужно найти файл по имени, то пишем следующее&lt;/p&gt;
  &lt;pre id=&quot;l2Z8&quot; data-lang=&quot;bash&quot;&gt;$ find имя_директории -name имя_файла&lt;/pre&gt;
  &lt;p id=&quot;LIsX&quot;&gt;В предыдущей команде поддерживается знак «*», который означает что угодно, являясь неким регулярным выражением&lt;/p&gt;
  &lt;pre id=&quot;SY1S&quot; data-lang=&quot;bash&quot;&gt;find имя_директории -name &amp;quot;*.txt&amp;quot;
# Найдет все файлы с расширением .txt&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;Zieb&quot;&gt;Сейчас очень важно знать основы работы с терминалом. Конечно, во многие приложения всё больше и больше добавляют собственный &lt;strong&gt;GUI&lt;/strong&gt;(Graphical User Interface). Но у него есть недостатки:&lt;/p&gt;
  &lt;ul id=&quot;4jfL&quot;&gt;
    &lt;li id=&quot;q04Z&quot;&gt;GUI медленные&lt;/li&gt;
    &lt;li id=&quot;HXK5&quot;&gt;GUI подстраивается под каждого пользователя&lt;br /&gt;То бишь, если у одного сотрудника монитор 1920×1080, а у другого меньше или больше, то на каждом из рабочих мест GUI будет смотреться по-разному&lt;/li&gt;
    &lt;li id=&quot;9LXZ&quot;&gt;GUI нельзя автоматизировать&lt;/li&gt;
    &lt;li id=&quot;Rn9m&quot;&gt;И т. д.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;XaWU&quot;&gt;Если испытываете сложность с работой в терминале, то вот &lt;a href=&quot;https://www.boot.dev/courses/learn-shells-and-terminals&quot; target=&quot;_blank&quot;&gt;здесь&lt;/a&gt; можете пройти бесплатный курс и стать мастером своего дела.&lt;/p&gt;
  &lt;blockquote id=&quot;SePy&quot; data-align=&quot;center&quot;&gt;Всем добра!&lt;/blockquote&gt;

</content></entry><entry><id>zloytapochek:4zXG8dVQfgs</id><link rel="alternate" type="text/html" href="https://teletype.in/@zloytapochek/4zXG8dVQfgs?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=zloytapochek"></link><title>Поговорим про IPsec</title><published>2024-12-22T14:42:10.601Z</published><updated>2024-12-30T15:10:23.911Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img1.teletype.in/files/02/b7/02b7ddd5-431e-4789-a716-56049e998181.png"></media:thumbnail><category term="seti" label="Сети"></category><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/43/1d/431d852f-9589-4e0a-bba0-7ac54e9da029.png&quot;&gt;Сейчас невозможно представить наш мир без компьютерных сетей: проводных, беспроводных, виртуальных и т. д. Мы ежедневно используем сети в самых разных формах. Однако с ростом использования сетей увеличивается и риск атак со стороны злоумышленников. Для защиты наших данных был разработан протокол IPsec.</summary><content type="html">
  &lt;p id=&quot;xm1H&quot;&gt;Сейчас невозможно представить наш мир без компьютерных сетей: проводных, беспроводных, виртуальных и т. д. Мы ежедневно используем сети в самых разных формах. Однако с ростом использования сетей увеличивается и риск атак со стороны злоумышленников. Для защиты наших данных был разработан протокол IPsec, который обеспечивает шифрование и аутентификацию данных на уровне сетевого протокола и часто используется для создания виртуальных частных сетей (VPN).&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(199, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;LZxt&quot;&gt;Итак, &lt;strong&gt;IPsec&lt;/strong&gt; — набор протоколов для обеспечения защиты данных, передаваемых по межсетевому протоколу IP (Internet Protocol).&lt;/p&gt;
  &lt;/section&gt;
  &lt;p id=&quot;I0g1&quot;&gt;Защита наших данных может быть реализована на разных протоколах. IPsec же реализован на &lt;strong&gt;сетевом уровне (network layer).&lt;/strong&gt;&lt;/p&gt;
  &lt;h3 id=&quot;heeQ&quot;&gt;Ядро нашего сегодняшнего гостя состоит из трех протоколов:&lt;/h3&gt;
  &lt;section style=&quot;background-color:hsl(hsl(199, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;ol id=&quot;qrOf&quot;&gt;
      &lt;li id=&quot;7vA4&quot;&gt;Authentication Header (АН) — гарантирует, что данные не были изменены во время передачи, проверяет, откуда пришла информация, и защищает от повторной отправки одних и тех же данных.&lt;/li&gt;
      &lt;li id=&quot;ug0E&quot;&gt;Encapsulating Security Payload (ESP) — обеспечивает конфиденциальность передаваемой информации с помощью шифрования и контролирует поток конфиденциальных данных. Кроме того, он может выполнять функции AH. При использовании ESP обязательно указывать, какие именно функции безопасности будут применяться, так как их можно включать по желанию.&lt;/li&gt;
      &lt;li id=&quot;xpU7&quot;&gt;Internet Security Association and Key Management Protocol (ISAKMP) — протокол, который используется для первоначальной настройки соединения, взаимной проверки подлинности между конечными устройствами и обмена секретными ключами.&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/section&gt;
  &lt;p id=&quot;nllZ&quot;&gt;Теперь, когда мы знаем о «внутрянке» IPsec, давайте рассмотрим режимы его работы. Их, к слову, два: транспортный и туннельный.&lt;/p&gt;
  &lt;p id=&quot;Vv2j&quot;&gt;Транспортный, как правило, используется для установления соединения между хостами. В этом режиме шифруются или подписываются только данные IP-пакета. Другими словами, шифруется только полезная нагрузка, а заголовок остается неизменным&lt;/p&gt;
  &lt;p id=&quot;6sBl&quot;&gt;В туннельном же режиме шифруется весь пакет. Такой режим может использоваться для задач, требующих максимальной защищенности, например для передачи защищенных данных, через открытые каналы связи (Интернет).&lt;/p&gt;
  &lt;p id=&quot;zHSl&quot;&gt;Далее мы рассмотрим режим работы IPsec, но перед этим нужно знать, что такое IKE.&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(199, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;9qBU&quot;&gt;&lt;strong&gt;IKE (Internet Key Exchange)&lt;/strong&gt; — протокол, связывающий все компоненты IPsec в работающее целое. В частности, IKE обеспечивает первоначальную аутентификацию сторон, а также их обмен общими секретными ключами. Он работает через порт 500 UDP и имеет две фазы.&lt;/p&gt;
  &lt;/section&gt;
  &lt;p id=&quot;bWvr&quot;&gt;&lt;strong&gt;Первая фаза:&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;6GtR&quot;&gt;Создание безопасного канала (IKE SA) и согласование сессионного ключа с использованием алгоритма Диффи-Хеллмана. В это фазе есть два режима:&lt;/p&gt;
  &lt;ol id=&quot;JNlR&quot;&gt;
    &lt;li id=&quot;Ri7T&quot;&gt;Основной режим: три двусторонних обмена для согласования алгоритмов и проверки идентификации.&lt;/li&gt;
    &lt;li id=&quot;74ZC&quot;&gt;Агрессивный режим: меньше обменов, но менее безопасен, так как информация передается до установления безопасного канала.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;RHtJ&quot;&gt;&lt;strong&gt;Вторая фаза:&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;bmdh&quot;&gt;Выполняется только в одном быстром режиме после создания безопасного канала. Он согласует политику IPsec, устанавливает IPsec SA и обновляет секретные ключи, используя алгоритм Диффи-Хеллмана.&lt;/p&gt;
  &lt;h2 id=&quot;brif&quot;&gt;&lt;strong&gt;Наконец, как работает IPsec:&lt;/strong&gt;&lt;/h2&gt;
  &lt;section style=&quot;background-color:hsl(hsl(199, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;ol id=&quot;kkqw&quot;&gt;
      &lt;li id=&quot;1PIK&quot;&gt;На первом этапе создаются политики безопасности на каждом узле, поддерживающем стандарт IPsec.&lt;/li&gt;
      &lt;li id=&quot;LrKW&quot;&gt;Второй этап, по сути, является первой фазой IKE. Здесь организовывается безопасный канал между сторонами.&lt;/li&gt;
      &lt;li id=&quot;2M7j&quot;&gt;Третий этап является второй фазой IKE. Его задачей является создание IPsec-туннеля.&lt;/li&gt;
      &lt;li id=&quot;i8pB&quot;&gt;Четвертый этап — рабочий этап. Все настроено, начинается процесс передачи данных.&lt;/li&gt;
      &lt;li id=&quot;8QQ2&quot;&gt;На пятом этапе IPsec SA прекращают действовать. Их либо удаляют, либо истекает время жизни. При надобности продолжить передачу данных запускается вторая фаза IKE (если требуется, то и первая)&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/section&gt;
  &lt;p id=&quot;5IwZ&quot;&gt;Внимательный читатель заметил, что мы не говорили об IPsec SA… Исправим это!&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(199, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;iBqD&quot;&gt;&lt;strong&gt;IPsec SA&lt;/strong&gt; — это база IPsec. Без SA не существовало бы и IPsec. &lt;/p&gt;
    &lt;p id=&quot;Kj4W&quot;&gt;&lt;strong&gt;SA (Security Association)&lt;/strong&gt; — симплексный набор правил по отношению к трафику: что шифровать и как шифровать.&lt;/p&gt;
  &lt;/section&gt;
  &lt;p id=&quot;VFEU&quot;&gt;Теперь самый главный вопрос «Для чего и где это используется?», ответ на который нетривиальный.&lt;/p&gt;
  &lt;p id=&quot;syUf&quot;&gt;IPsec в большей степени используется для организации VPN-туннелей, которые, к слову, сейчас на каждом шагу. Помимо туннелей, при правильной настройке, IPsec можно использовать для создания межсетевого экрана. &lt;/p&gt;
  &lt;p id=&quot;E1pa&quot; data-align=&quot;center&quot;&gt;А под конец вопрос. &lt;/p&gt;
  &lt;blockquote id=&quot;tTdD&quot; data-align=&quot;center&quot;&gt;Сколько раз в статье было использовано «IPsec»?&lt;br /&gt;Всем добра!&lt;/blockquote&gt;

</content></entry></feed>