<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>@zloytapochek</title><generator>teletype.in</generator><description><![CDATA[@zloytapochek]]></description><link>https://teletype.in/@zloytapochek?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zloytapochek</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/zloytapochek?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/zloytapochek?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Wed, 22 Apr 2026 16:16:23 GMT</pubDate><lastBuildDate>Wed, 22 Apr 2026 16:16:23 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@zloytapochek/PRaGYtoS1Vc</guid><link>https://teletype.in/@zloytapochek/PRaGYtoS1Vc?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zloytapochek</link><comments>https://teletype.in/@zloytapochek/PRaGYtoS1Vc?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zloytapochek#comments</comments><dc:creator>zloytapochek</dc:creator><title>Создание systemd сервиса</title><pubDate>Sat, 28 Feb 2026 14:56:29 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/8f/cb/8fcb2ed6-7444-4dd7-9936-2870ec14c00d.png"></media:content><category>devops</category><description><![CDATA[<img src="https://img3.teletype.in/files/ae/27/ae27efff-1039-49f1-91bc-c951591b6026.jpeg"></img>TL;DR
Создание &quot;сервисного&quot; пользователя
Создание systemd-сервиса]]></description><content:encoded><![CDATA[
  <blockquote id="zpru">TL;DR<br />Создание &quot;сервисного&quot; пользователя<br />Создание systemd-сервиса</blockquote>
  <h3 id="7Jov">Создание пользователя</h3>
  <p id="3Mzn">Создание пользователя обычно чем-то подкрепляется. В моем случае нужно было создать &quot;сервисного&quot; юзера. У которого не будет домашней директории и через него нельзя будет залогиниться. А нужен он будет для запуска веб-сервера<br /> Поэтому входные данные такие:</p>
  <ul id="MmBj">
    <li id="dPVb">Имя группы</li>
    <li id="dhN0">Имя пользователя</li>
    <li id="Aq7M">Путь до исполняемого файла</li>
    <li id="bMGD">Путь до директорий, к которым нужен будет доступ</li>
  </ul>
  <p id="AIcV">Создаем группу</p>
  <pre id="t05v" data-lang="shell">sudo groupadd &lt;имя_группы&gt;</pre>
  <p id="8jpj">Создаем самого пользователя</p>
  <pre id="rXuO" data-lang="shell">sudo useradd -r -s /usr/sbin/nologin -g &lt;имя_группы&gt; &lt;имя_пользователя&gt;</pre>
  <p id="Gt7c"><code>-r</code> - создает системного пользователя без домашней директории<br /><code>-s /usr/sbin/nologin</code> - запрещает авторизацию пользователя через терминал<br /><code>-g &lt;имя_группы&gt;</code> - добавляет пользователя в определенную группу</p>
  <p id="oVyu"><em>Полный список флагов <a href="https://man7.org/linux/man-pages/man8/useradd.8.html" target="_blank">здесь</a>.</em></p>
  <p id="U1kv">Назначаем права доступа</p>
  <pre id="UTmb" data-lang="shell">sudo chown -R &lt;пользователь&gt;:&lt;группа&gt; &lt;путь_до_исполняемого_файла&gt;

sudo chown -R &lt;пользователь&gt;:&lt;группа&gt; &lt;дополнительные_директории&gt;
...</pre>
  <h3 id="Tyf2">Управление systemd-сервисом</h3>
  <p id="bGeI">Чтобы создать сервис, нужно описать его в конфигурационном файле. Располагаться он должен в <code>/etc/systemd/system/&lt;имя_сервиса&gt;.service</code></p>
  <p id="TtH7">Ниже приведен пример шаблона с пояснениями. Данный шаблон был использован для настройки <a href="https://github.com/9001/copyparty" target="_blank">Copyparty</a></p>
  <p id="nRhQ">Шаблон:</p>
  <pre id="CURJ" data-lang="toml">[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=&quot;HOME=/opt/copyparty&quot; # Т.к. пользователь copyparty был создан без домашней директории, то укажем ее вручную

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

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

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@zloytapochek/zbcgfThaFLZ</guid><link>https://teletype.in/@zloytapochek/zbcgfThaFLZ?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zloytapochek</link><comments>https://teletype.in/@zloytapochek/zbcgfThaFLZ?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zloytapochek#comments</comments><dc:creator>zloytapochek</dc:creator><title>&quot;Домашний&quot; Compute Cloud | Или как создавать машинки в Hyper-V без ошибок и с Cloud-Init</title><pubDate>Mon, 03 Nov 2025 21:27:50 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/54/d7/54d74643-0ef3-4660-b2ba-5cc74fdf2752.png"></media:content><description><![CDATA[<img src="https://img1.teletype.in/files/48/08/48088b14-c4be-4c81-80b8-b97f914336b9.jpeg"></img>Небольшое предисловие. Я не нашел хороших гайдов или рабочих решений для моей задачи. А она следующая: как только я начал увлекаться всевозможными виртуализациями, кластерами и т.д. и т.п., возникла потребность быстро создавать машинки и настраивать их. Может быть, я плохо искал, но повторюсь, ничего не нашел. Поэтому спустя какое-то время я был вынужден написать Ansible Role для автоматического и легкого создания большого количества виртуальных машин.]]></description><content:encoded><![CDATA[
  <h2 id="y3m4">Мотивация сделать это</h2>
  <p id="zewZ">Небольшое предисловие. Я не нашел хороших гайдов или рабочих решений для моей задачи. А она следующая: как только я начал увлекаться всевозможными виртуализациями, кластерами и т.д. и т.п., возникла потребность быстро создавать машинки и настраивать их. Может быть, я плохо искал, но повторюсь, ничего не нашел. Поэтому спустя какое-то время я был вынужден написать Ansible Role для автоматического и легкого создания большого количества виртуальных машин.</p>
  <p id="GVk3"><strong>Почему Ansible?</strong><br />Изначально я думал написать связку Ansible и Terraform, а запускать их через Powershell скрипт, но из-за проблем провайдера Terraform я не смог этого сделать. И как мне кажется, так даже лучше, ибо Ansible можно запустить на любой системе, в отличие от того же Powershell.</p>
  <p id="UWJi"><strong>А как же Proxmox и другие средства виртуализации + Terraform?</strong><br />Для этого нужны дополнительные ресурсы. А мое решение подходит для тех, у кого есть ПК + ноутбук, или 2 ПК, или 2 ноутбука. </p>
  <h2 id="kOgE">Как это сделать</h2>
  <p id="5qdR">Итак, вот мой репозиторий: <a href="https://github.com/ZloyTapochek/HyperV-VMs-Ansible-Role" target="_blank">https://github.com/ZloyTapochek/HyperV-VMs-Ansible-Role</a></p>
  <p id="RH1Z">Вам нужно его склонировать и перейти в директорию</p>
  <pre id="QeIV" data-lang="shell">git clone https://github.com/ZloyTapochek/HyperV-VMs-Ansible-Role.git
cd HyperV-VMs-Ansible-Role</pre>
  <p id="lmti">Самое главное, с чем я боролся 2 дня - выполнение конвертации диска .img в .vhdx <strong>в WSL</strong>. Сейчас это звучит непонятно, но поймете, когда перейдете в репозиторий и прочитаете Readme.</p>
  <p id="c30L">Далее следуйте инструкции в Readme, заполняйте переменки. Я в свободное время буду дополнять ее и совершенствовать.</p>
  <p id="9tt9">После всем подготовительных действий, запускайте эту команду и отдыхайте, пока программа все сделает за Вас.</p>
  <pre id="gKvx" data-lang="shell">ansible-playbook ./playbook.yml -i ./hosts.ini</pre>
  <hr />
  <blockquote id="E98j" data-align="center">Всем добра!</blockquote>

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

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

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

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

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

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

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

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

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

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@zloytapochek/8Iu0putujT5</guid><link>https://teletype.in/@zloytapochek/8Iu0putujT5?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zloytapochek</link><comments>https://teletype.in/@zloytapochek/8Iu0putujT5?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zloytapochek#comments</comments><dc:creator>zloytapochek</dc:creator><title>Поговорим про DevSecOps. Jenkins with Bandit</title><pubDate>Tue, 04 Feb 2025 18:57:06 GMT</pubDate><media:content medium="image" url="https://img4.teletype.in/files/bc/6e/bc6e3471-30fd-4d01-bb83-4a148be07b41.png"></media:content><category>Информационная безопасность (ИБ)</category><description><![CDATA[<img src="https://img3.teletype.in/files/ef/f7/eff71a38-f128-48a3-a58c-fafe3d0ea5e6.jpeg"></img>В прошлой статье мы разобрали инструмент Bandit. Если вкратце, этот инструмент сканирует исходный код. Мы применили его на практике, но в нестандартной для DevSecOps форме, запустив его в обычной ОС. Но на практике подобные инструменты встраиваются в CI/CD пайплайн.]]></description><content:encoded><![CDATA[
  <p id="dvmZ">В <a href="https://teletype.in/@zloytapochek/6TINAD4sbTh" target="_blank">прошлой статье</a> мы разобрали инструмент Bandit. Если вкратце, этот инструмент сканирует исходный код. Мы применили его на практике, но в нестандартной для DevSecOps форме, запустив его в обычной ОС. Но на практике подобные инструменты встраиваются в <strong>CI/CD пайплайн</strong>.</p>
  <section style="background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="VOCk"><strong>CI/CD пайплайн </strong>— набор практик и методов, которые позволяют автоматизировать процесс разработки. То бишь, мы просто вносим изменения в код, а этот код автоматически собирается, тестируется, встает на облачные сервера ну и т. д.</p>
  </section>
  <p id="gD2L">В этой статье мы интегрируем запуск Bandit для нашего кода на GitHub в <strong>Jenkins.</strong></p>
  <section style="background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="44Qd"><strong>Jenkins </strong>— инструмент для автоматизации процесса разработки, который поддерживает практики CI/CD</p>
  </section>
  <h2 id="fXLU">Содержание:</h2>
  <ul id="unJi">
    <li id="yE1R"><a href="#m2jW">Устанавливаем Jenkins</a></li>
    <li id="Fm3N"><a href="#fvO1">Начало работы с Jenkins</a></li>
    <li id="iiSj"><a href="#bBmf">Настройка Bandit</a></li>
    <li id="ivmP"><a href="#epqG">Настройка агента Jenkins</a></li>
    <li id="k5yR"><a href="#nUSR">Собираем проект через агента</a></li>
  </ul>
  <hr />
  <h3 id="m2jW">Устанавливаем Jenkins</h3>
  <p id="Qqb9">Итак, все это безобразие будет сделано с помощью <strong>Docker.</strong></p>
  <section style="background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="z3hb"><strong>Docker </strong>— инструмент для контейнеризации приложений.</p>
  </section>
  <p id="fgQ8">Процесс установки Docker я оставлю за кадром, но приложу ссылку на <a href="https://docs.docker.com/desktop/" target="_blank">иструкцию</a>.</p>
  <p id="KNZi">Итак, сначала напишем <strong>Dockerfile.</strong></p>
  <section style="background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="x3Yh"><strong>Dockerfile </strong>— это текстовый файл, содержащий набор инструкций, которые Docker использует для автоматической сборки образа контейнера.</p>
  </section>
  <pre id="lHas" data-lang="dockerfile">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</pre>
  <p id="WwD8">Сначала запустим Bandit в том же контейнере, что и Jenkins. А потом сделаем все по уму и добавим агента Jenkins, который сделает все в отдельном контейнере.</p>
  <p id="bMbo">Итак, сформировали Dockerfile. Теперь сформируем <strong>Docker-compose.yml</strong></p>
  <section style="background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="0UQ8">Docker-compose.yml — файл конфигурации для многоконтейнерных приложений</p>
  </section>
  <pre id="c20i" data-lang="yaml">version: &#x27;3.8&#x27;

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

volumes:  
  jenkins_home:  

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

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

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

volumes:
  jenkins_home:
  agent_home:

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

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

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@zloytapochek/HnpdNW3cW8D</guid><link>https://teletype.in/@zloytapochek/HnpdNW3cW8D?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zloytapochek</link><comments>https://teletype.in/@zloytapochek/HnpdNW3cW8D?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zloytapochek#comments</comments><dc:creator>zloytapochek</dc:creator><title>Поговорим про терминал</title><pubDate>Mon, 30 Dec 2024 15:10:06 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/1e/0e/1e0efe46-9c7c-4342-8dff-ad38b4653d25.png"></media:content><category>Софт / Soft</category><description><![CDATA[<img src="https://img1.teletype.in/files/01/d8/01d8b2b7-d433-4098-84d4-3a341f63a2c8.png"></img>Ежедневно каждый из нас использует компьютер. Это может быть смартфон, ноутбук или полноценная рабочая станция, ну или другие представители семейства вычислительных машин. Сейчас, если попросить человека представить компьютер или какую-нибудь программу, то он начнет описывать ее графический интерфейс. Но раньше графических интерфейсов не было. Людям приходилось прописывать все команды через терминал, который, по сути, был экраном с клавиатурой.]]></description><content:encoded><![CDATA[
  <p id="xBPZ">Ежедневно каждый из нас использует компьютер. Это может быть смартфон, ноутбук или полноценная рабочая станция, ну или другие представители семейства вычислительных машин. Сейчас, если попросить человека представить компьютер или какую-нибудь программу, то он начнет описывать ее графический интерфейс. Но раньше графических интерфейсов не было. Людям приходилось прописывать все команды через терминал, который, по сути, был экраном с клавиатурой.</p>
  <figure id="jiNC" class="m_column" data-caption-align="center">
    <img src="https://img1.teletype.in/files/80/74/8074964d-cf3e-438b-92e7-61bc6692fe7a.png" width="1600" />
    <figcaption>Терминал операционной системы</figcaption>
  </figure>
  <p id="kuu9">Но для людей, увлеченных миром компьютеров, которые проводят за ними много времени, разрабатывая различные проекты и решая задачи, терминал представляется как-то так:</p>
  <figure id="tk2v" class="m_column" data-caption-align="center">
    <img src="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&f=1&nofb=1&ipt=1057a233177c9472498aed5006ce49d83f7fb4b1e26678ac4377bd53166f550c&ipo=images" width="1598" />
    <figcaption>Скриншот QTerminal для Linux</figcaption>
  </figure>
  <p id="imfh">Вот о функционале подобных терминалов мы и поговорим.</p>
  <hr />
  <section style="background-color:hsl(hsl(170, 33%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="Gnvm">Интересный факт</h3>
    <p id="CMZJ">Как уже упоминалось, терминал изначально представлял собой простое устройство, состоящее из экрана и клавиатуры. В современном мире, когда мы говорим о «терминале», на самом деле мы имеем в виду эмулятор терминала. Однако, с учетом стремительного прогресса и уменьшения использования устаревших технологий, мы все реже задумываемся о различиях. Честно говоря, это упрощает нашу жизнь, и поэтому мы предпочитаем называть его просто «терминалом».</p>
  </section>
  <hr />
  <p id="R6KY">Итак, в качестве примера мы возьмем оболочку Bash. В этой статье мы познакомимся с основными командами, которые могут быть вам незнакомы, а также с интересными возможностями, которые она предлагает.</p>
  <hr />
  <p id="PqC1">В своей жизни, когда мне нужно посчитать что-то сложное, я захожу в Windows Terminal и выполняю команду «python». И уже в нем высчитываю то, что мне нужно. А знали ли вы, что можно Bash может считать выражения тоже? Для этого нужно выполнить команду <strong>expr.</strong></p>
  <pre id="Hna3" data-lang="bash">$ expr 123 + 945 * 2 + 45
2058</pre>
  <p id="wQGV">Да и вообще на оболочках можно писать программы. Они имеют свой синтаксис для объявления переменных:</p>
  <pre id="b1BR" data-lang="bash">$ first=&quot;Hello&quot;
$ second=&quot;World!&quot;
$ mid=&quot;,&quot;
$ echo $first$mid $second
Hello, World!</pre>
  <p id="fV5G">Для создания циклов:</p>
  <pre id="0I2O" data-lang="bash">$ for i in {1..10}; do   echo $i; done
1
2
3
4
5
6
7
8
9
10</pre>
  <p id="v9YZ">И т. д.<br />В этих примерах используется команда «echo», надеюсь, что все с ней знакомы.</p>
  <section style="background-color:hsl(hsl(170, 33%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="XXWZ">Только не пишите полноценные программы на оболочках. Они для этого не оптимизированы👀</p>
  </section>
  <p id="uo4x">Также, оболочка умеет хранить историю выполненных команд. Вывести их список мы можем путем ввода следующей команды:</p>
  <pre id="8bda" data-lang="bash">$ history</pre>
  <p id="wNtk">Впору упомянуть, что переменные оболочка тоже хранит. И чтобы удалить переменную нужно ввести:</p>
  <pre id="wpJK" data-lang="bash">$ unset имя_файла</pre>
  <hr />
  <p id="qmNU"> Что там по работе с файлами?</p>
  <p id="eSkh">Команда cat поможет прочитать содержимое файл, это мы знаем. А если нам нужно вывести только первые или последние n строк?</p>
  <p id="k1po">В первом случае нам поможет следующая команда:</p>
  <pre id="qudR" data-lang="bash">$ head -n 10 имя_файла</pre>
  <p id="tWLi">Во втором случае:</p>
  <pre id="Qp0i" data-lang="bash">$ tail -n 10 имя_файла</pre>
  <p id="SIZQ">Ах да, чтобы прочитать файл, сначала нужно его создать. Что же, команда touch спешит на помощь</p>
  <pre id="VmZh" data-lang="bash">$ touch имя_файла</pre>
  <p id="APsv">В качестве аналога ctrl+f используется команда grep</p>
  <pre id="rWEy" data-lang="bash">$ grep &quot;то что нужно найти&quot; имя_файла</pre>
  <p id="CK8Z">Если нужно найти файл по имени, то пишем следующее</p>
  <pre id="l2Z8" data-lang="bash">$ find имя_директории -name имя_файла</pre>
  <p id="LIsX">В предыдущей команде поддерживается знак «*», который означает что угодно, являясь неким регулярным выражением</p>
  <pre id="SY1S" data-lang="bash">find имя_директории -name &quot;*.txt&quot;
# Найдет все файлы с расширением .txt</pre>
  <hr />
  <p id="Zieb">Сейчас очень важно знать основы работы с терминалом. Конечно, во многие приложения всё больше и больше добавляют собственный <strong>GUI</strong>(Graphical User Interface). Но у него есть недостатки:</p>
  <ul id="4jfL">
    <li id="q04Z">GUI медленные</li>
    <li id="HXK5">GUI подстраивается под каждого пользователя<br />То бишь, если у одного сотрудника монитор 1920×1080, а у другого меньше или больше, то на каждом из рабочих мест GUI будет смотреться по-разному</li>
    <li id="9LXZ">GUI нельзя автоматизировать</li>
    <li id="Rn9m">И т. д.</li>
  </ul>
  <p id="XaWU">Если испытываете сложность с работой в терминале, то вот <a href="https://www.boot.dev/courses/learn-shells-and-terminals" target="_blank">здесь</a> можете пройти бесплатный курс и стать мастером своего дела.</p>
  <blockquote id="SePy" data-align="center">Всем добра!</blockquote>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@zloytapochek/4zXG8dVQfgs</guid><link>https://teletype.in/@zloytapochek/4zXG8dVQfgs?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zloytapochek</link><comments>https://teletype.in/@zloytapochek/4zXG8dVQfgs?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zloytapochek#comments</comments><dc:creator>zloytapochek</dc:creator><title>Поговорим про IPsec</title><pubDate>Sun, 22 Dec 2024 14:42:10 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/02/b7/02b7ddd5-431e-4789-a716-56049e998181.png"></media:content><category>Сети</category><description><![CDATA[<img src="https://img1.teletype.in/files/43/1d/431d852f-9589-4e0a-bba0-7ac54e9da029.png"></img>Сейчас невозможно представить наш мир без компьютерных сетей: проводных, беспроводных, виртуальных и т. д. Мы ежедневно используем сети в самых разных формах. Однако с ростом использования сетей увеличивается и риск атак со стороны злоумышленников. Для защиты наших данных был разработан протокол IPsec.]]></description><content:encoded><![CDATA[
  <p id="xm1H">Сейчас невозможно представить наш мир без компьютерных сетей: проводных, беспроводных, виртуальных и т. д. Мы ежедневно используем сети в самых разных формах. Однако с ростом использования сетей увеличивается и риск атак со стороны злоумышленников. Для защиты наших данных был разработан протокол IPsec, который обеспечивает шифрование и аутентификацию данных на уровне сетевого протокола и часто используется для создания виртуальных частных сетей (VPN).</p>
  <section style="background-color:hsl(hsl(199, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="LZxt">Итак, <strong>IPsec</strong> — набор протоколов для обеспечения защиты данных, передаваемых по межсетевому протоколу IP (Internet Protocol).</p>
  </section>
  <p id="I0g1">Защита наших данных может быть реализована на разных протоколах. IPsec же реализован на <strong>сетевом уровне (network layer).</strong></p>
  <h3 id="heeQ">Ядро нашего сегодняшнего гостя состоит из трех протоколов:</h3>
  <section style="background-color:hsl(hsl(199, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <ol id="qrOf">
      <li id="7vA4">Authentication Header (АН) — гарантирует, что данные не были изменены во время передачи, проверяет, откуда пришла информация, и защищает от повторной отправки одних и тех же данных.</li>
      <li id="ug0E">Encapsulating Security Payload (ESP) — обеспечивает конфиденциальность передаваемой информации с помощью шифрования и контролирует поток конфиденциальных данных. Кроме того, он может выполнять функции AH. При использовании ESP обязательно указывать, какие именно функции безопасности будут применяться, так как их можно включать по желанию.</li>
      <li id="xpU7">Internet Security Association and Key Management Protocol (ISAKMP) — протокол, который используется для первоначальной настройки соединения, взаимной проверки подлинности между конечными устройствами и обмена секретными ключами.</li>
    </ol>
  </section>
  <p id="nllZ">Теперь, когда мы знаем о «внутрянке» IPsec, давайте рассмотрим режимы его работы. Их, к слову, два: транспортный и туннельный.</p>
  <p id="Vv2j">Транспортный, как правило, используется для установления соединения между хостами. В этом режиме шифруются или подписываются только данные IP-пакета. Другими словами, шифруется только полезная нагрузка, а заголовок остается неизменным</p>
  <p id="6sBl">В туннельном же режиме шифруется весь пакет. Такой режим может использоваться для задач, требующих максимальной защищенности, например для передачи защищенных данных, через открытые каналы связи (Интернет).</p>
  <p id="zHSl">Далее мы рассмотрим режим работы IPsec, но перед этим нужно знать, что такое IKE.</p>
  <section style="background-color:hsl(hsl(199, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="9qBU"><strong>IKE (Internet Key Exchange)</strong> — протокол, связывающий все компоненты IPsec в работающее целое. В частности, IKE обеспечивает первоначальную аутентификацию сторон, а также их обмен общими секретными ключами. Он работает через порт 500 UDP и имеет две фазы.</p>
  </section>
  <p id="bWvr"><strong>Первая фаза:</strong></p>
  <p id="6GtR">Создание безопасного канала (IKE SA) и согласование сессионного ключа с использованием алгоритма Диффи-Хеллмана. В это фазе есть два режима:</p>
  <ol id="JNlR">
    <li id="Ri7T">Основной режим: три двусторонних обмена для согласования алгоритмов и проверки идентификации.</li>
    <li id="74ZC">Агрессивный режим: меньше обменов, но менее безопасен, так как информация передается до установления безопасного канала.</li>
  </ol>
  <p id="RHtJ"><strong>Вторая фаза:</strong></p>
  <p id="bmdh">Выполняется только в одном быстром режиме после создания безопасного канала. Он согласует политику IPsec, устанавливает IPsec SA и обновляет секретные ключи, используя алгоритм Диффи-Хеллмана.</p>
  <h2 id="brif"><strong>Наконец, как работает IPsec:</strong></h2>
  <section style="background-color:hsl(hsl(199, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <ol id="kkqw">
      <li id="1PIK">На первом этапе создаются политики безопасности на каждом узле, поддерживающем стандарт IPsec.</li>
      <li id="LrKW">Второй этап, по сути, является первой фазой IKE. Здесь организовывается безопасный канал между сторонами.</li>
      <li id="2M7j">Третий этап является второй фазой IKE. Его задачей является создание IPsec-туннеля.</li>
      <li id="i8pB">Четвертый этап — рабочий этап. Все настроено, начинается процесс передачи данных.</li>
      <li id="8QQ2">На пятом этапе IPsec SA прекращают действовать. Их либо удаляют, либо истекает время жизни. При надобности продолжить передачу данных запускается вторая фаза IKE (если требуется, то и первая)</li>
    </ol>
  </section>
  <p id="5IwZ">Внимательный читатель заметил, что мы не говорили об IPsec SA… Исправим это!</p>
  <section style="background-color:hsl(hsl(199, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="iBqD"><strong>IPsec SA</strong> — это база IPsec. Без SA не существовало бы и IPsec. </p>
    <p id="Kj4W"><strong>SA (Security Association)</strong> — симплексный набор правил по отношению к трафику: что шифровать и как шифровать.</p>
  </section>
  <p id="VFEU">Теперь самый главный вопрос «Для чего и где это используется?», ответ на который нетривиальный.</p>
  <p id="syUf">IPsec в большей степени используется для организации VPN-туннелей, которые, к слову, сейчас на каждом шагу. Помимо туннелей, при правильной настройке, IPsec можно использовать для создания межсетевого экрана. </p>
  <p id="E1pa" data-align="center">А под конец вопрос. </p>
  <blockquote id="tTdD" data-align="center">Сколько раз в статье было использовано «IPsec»?<br />Всем добра!</blockquote>

]]></content:encoded></item></channel></rss>