task3/lab3.html

165 lines
20 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>lab3</title>
<link rel="stylesheet" href="https://stackedit.io/style.css" />
</head>
<body class="stackedit">
<div class="stackedit__html"><h1 id="работа-с-сетевыми-соединениями-в-python">Работа с сетевыми соединениями в Python</h1>
<h2 id="цели-и-задачи">Цели и задачи</h2>
<p>Цель данного занятия — ознакомить студентов с основами работы с сетевыми соединениями в Python, а также научить их анализировать сетевой трафик с помощью Wireshark. В рамках занятия студенты изучат:</p>
<ul>
<li>Принципы работы сетевых протоколов TCP и UDP.</li>
<li>Реализацию клиент-серверного взаимодействия на Python.</li>
<li>Основы анализа сетевого трафика.</li>
<li>Работа с HTTP-запросами через <code>socket</code> и <code>requests</code>.</li>
<li>Взаимодействие с сервисом по протоколу HTTP.</li>
</ul>
<h2 id="подготовительный-этап">Подготовительный этап</h2>
<p>Работу следует выполнять в среде Visual Studio Code, используя установленное расширение для Python. Перед началом необходимо:</p>
<ol>
<li>Создать и активировать виртуальное окружение с помощью <code>venv</code> или <code>conda</code>.</li>
<li>Установить библиотеку <code>requests</code> для работы с HTTP-запросами.</li>
<li>Инициализировать Git-репозиторий, добавить <code>.gitignore</code> и <code>README.md</code>.</li>
<li>Закоммитить изменения. Не выполнять push.</li>
</ol>
<h2 id="создание-простых-программ-для-клиент-серверного-взаимодействия-и-анализ-сетевого-трафика-в-wireshark">Создание простых программ для клиент-серверного взаимодействия и анализ сетевого трафика в Wireshark</h2>
<p>Необходимо реализовать две программы: сервер и клиент. Они должны обмениваться данными по протоколам TCP и UDP. В первом случае клиент отправляет строку, а сервер её модифицирует и возвращает обратно.</p>
<p>Пример TCP-сервера:</p>
<pre class=" language-python"><code class="prism language-python"><span class="token keyword">import</span> socket
server <span class="token operator">=</span> socket<span class="token punctuation">.</span>socket<span class="token punctuation">(</span>socket<span class="token punctuation">.</span>AF_INET<span class="token punctuation">,</span> socket<span class="token punctuation">.</span>SOCK_STREAM<span class="token punctuation">)</span>
server<span class="token punctuation">.</span>bind<span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token string">"0.0.0.0"</span><span class="token punctuation">,</span> <span class="token number">10000</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
server<span class="token punctuation">.</span>listen<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span>
<span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">"TCP сервер запущен"</span><span class="token punctuation">)</span>
<span class="token keyword">while</span> <span class="token boolean">True</span><span class="token punctuation">:</span>
conn<span class="token punctuation">,</span> addr <span class="token operator">=</span> server<span class="token punctuation">.</span>accept<span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">print</span><span class="token punctuation">(</span>f<span class="token string">"Подключение от {addr}"</span><span class="token punctuation">)</span>
data <span class="token operator">=</span> conn<span class="token punctuation">.</span>recv<span class="token punctuation">(</span><span class="token number">1024</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> <span class="token operator">not</span> data<span class="token punctuation">:</span>
<span class="token keyword">break</span>
conn<span class="token punctuation">.</span>sendall<span class="token punctuation">(</span>data<span class="token punctuation">.</span>upper<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
conn<span class="token punctuation">.</span>close<span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> data<span class="token punctuation">.</span>upper<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> b<span class="token string">'EXIT'</span><span class="token punctuation">:</span>
<span class="token keyword">break</span>
</code></pre>
<p>Пример TCP-клиента:</p>
<pre class=" language-python"><code class="prism language-python"><span class="token keyword">import</span> socket
client <span class="token operator">=</span> socket<span class="token punctuation">.</span>socket<span class="token punctuation">(</span>socket<span class="token punctuation">.</span>AF_INET<span class="token punctuation">,</span> socket<span class="token punctuation">.</span>SOCK_STREAM<span class="token punctuation">)</span>
client<span class="token punctuation">.</span>connect<span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token string">'127.0.0.1'</span><span class="token punctuation">,</span> <span class="token number">10000</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
client<span class="token punctuation">.</span>sendall<span class="token punctuation">(</span>b<span class="token string">'hello server'</span><span class="token punctuation">)</span>
data <span class="token operator">=</span> client<span class="token punctuation">.</span>recv<span class="token punctuation">(</span><span class="token number">1024</span><span class="token punctuation">)</span>
<span class="token keyword">print</span><span class="token punctuation">(</span>f<span class="token string">"Ответ от сервера: {data.decode()}"</span><span class="token punctuation">)</span>
client<span class="token punctuation">.</span>close<span class="token punctuation">(</span><span class="token punctuation">)</span>
</code></pre>
<p><strong>Wireshark</strong> — это инструмент для анализа сетевого трафика, который позволяет просматривать отправленные и полученные пакеты. Важным аспектом работы с TCP является <strong>трёхстороннее рукопожатие (three-way handshake)</strong>:</p>
<ul>
<li>Клиент отправляет <strong>SYN</strong>-пакет серверу.</li>
<li>Сервер отвечает <strong>SYN-ACK</strong>.</li>
<li>Клиент отправляет <strong>ACK</strong>, устанавливая соединение.</li>
</ul>
<p><strong>Задание:</strong></p>
<ol>
<li>Запустите Wireshark и начните захват трафика. Вам очень поможет фитльр <code>tcp.port==10000 || udp.port==10001</code>.</li>
<li>Запустите сервер и клиент, зафиксируйте обмен пакетами.</li>
<li>Остановите захват и найдите последовательность <strong>SYN, SYN-ACK, ACK</strong>.</li>
<li>Обратите внимание на <strong>Sequence Number, Sequence Number (raw), Acknowledgment Number, Acknowledgment Number (raw), Flags</strong>. Эти параметры определяют порядок передачи данных и подтверждения приёма.</li>
<li>Зафиксируйте последовательность завершения соединения (<strong>FIN</strong>), которая включает обмен FIN- и ACK-пакетами.</li>
<li>Измените TCP-клиент так, чтобы TCP-сервер завершил работу.</li>
</ol>
<p>Пример UDP-сервера:</p>
<pre class=" language-python"><code class="prism language-python"><span class="token keyword">import</span> socket
server <span class="token operator">=</span> socket<span class="token punctuation">.</span>socket<span class="token punctuation">(</span>socket<span class="token punctuation">.</span>AF_INET<span class="token punctuation">,</span> socket<span class="token punctuation">.</span>SOCK_DGRAM<span class="token punctuation">)</span>
server<span class="token punctuation">.</span>bind<span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token string">'0.0.0.0'</span><span class="token punctuation">,</span> <span class="token number">10001</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">"UDP сервер запущен"</span><span class="token punctuation">)</span>
<span class="token keyword">while</span> <span class="token boolean">True</span><span class="token punctuation">:</span>
data<span class="token punctuation">,</span> addr <span class="token operator">=</span> server<span class="token punctuation">.</span>recvfrom<span class="token punctuation">(</span><span class="token number">1024</span><span class="token punctuation">)</span>
<span class="token keyword">print</span><span class="token punctuation">(</span>f<span class="token string">"Сообщение от {addr}: {data.decode()}"</span><span class="token punctuation">)</span>
server<span class="token punctuation">.</span>sendto<span class="token punctuation">(</span>data<span class="token punctuation">.</span>upper<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> addr<span class="token punctuation">)</span>
</code></pre>
<p>Пример UDP-клиента:</p>
<pre class=" language-python"><code class="prism language-python"><span class="token keyword">import</span> socket
client <span class="token operator">=</span> socket<span class="token punctuation">.</span>socket<span class="token punctuation">(</span>socket<span class="token punctuation">.</span>AF_INET<span class="token punctuation">,</span> socket<span class="token punctuation">.</span>SOCK_DGRAM<span class="token punctuation">)</span>
client<span class="token punctuation">.</span>sendto<span class="token punctuation">(</span>b<span class="token string">'hello server'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'127.0.0.1'</span><span class="token punctuation">,</span> <span class="token number">10001</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
data<span class="token punctuation">,</span> _ <span class="token operator">=</span> client<span class="token punctuation">.</span>recvfrom<span class="token punctuation">(</span><span class="token number">1024</span><span class="token punctuation">)</span>
<span class="token keyword">print</span><span class="token punctuation">(</span>f<span class="token string">"Ответ от сервера: {data.decode()}"</span><span class="token punctuation">)</span>
client<span class="token punctuation">.</span>close<span class="token punctuation">(</span><span class="token punctuation">)</span>
</code></pre>
<p><strong>Задание:</strong></p>
<ol>
<li>Запустите Wireshark и начните захват трафика.</li>
<li>Запустите сервер и клиент, зафиксируйте обмен пакетами.</li>
<li>Проанализируйте разницу в передаче данных между TCP и UDP, сравнив структуру пакетов в Wireshark.</li>
<li>Модифицируйте серверную программу, чтобы изменять входящие данные перед отправкой клиенту. Измените порты для сервера и клиента.</li>
</ol>
<h2 id="подключение-к-веб-серверу-и-работа-с-http-запросами">Подключение к веб-серверу и работа с HTTP-запросами</h2>
<p>Создайте TCP-клиент, который устанавливает соединение с <code>vyatsu.ru</code> по порту 80 и отправляет HTTP-запрос:</p>
<pre class=" language-python"><code class="prism language-python"><span class="token keyword">import</span> socket
client <span class="token operator">=</span> socket<span class="token punctuation">.</span>socket<span class="token punctuation">(</span>socket<span class="token punctuation">.</span>AF_INET<span class="token punctuation">,</span> socket<span class="token punctuation">.</span>SOCK_STREAM<span class="token punctuation">)</span>
client<span class="token punctuation">.</span>connect<span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token string">'vyatsu.ru'</span><span class="token punctuation">,</span> <span class="token number">80</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
request <span class="token operator">=</span> <span class="token string">"GET / HTTP/1.1\r\nHost: vyatsu.ru\r\n\r\n"</span>
client<span class="token punctuation">.</span>sendall<span class="token punctuation">(</span>request<span class="token punctuation">.</span>encode<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
response <span class="token operator">=</span> client<span class="token punctuation">.</span>recv<span class="token punctuation">(</span><span class="token number">4096</span><span class="token punctuation">)</span>
<span class="token keyword">print</span><span class="token punctuation">(</span>response<span class="token punctuation">.</span>decode<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
client<span class="token punctuation">.</span>close<span class="token punctuation">(</span><span class="token punctuation">)</span>
</code></pre>
<p><strong>Задание:</strong></p>
<ol>
<li>Запустите Wireshark, выполните запрос и проанализируйте трафик (фильтр <code>tcp.port==80</code> оставит интересующие нас пакеты видимыми). Определите используемые протоколы. Поясните ответ от сервера.</li>
<li>Повторите запрос с использованием <code>requests</code>:</li>
</ol>
<pre class=" language-python"><code class="prism language-python"><span class="token keyword">import</span> requests
response <span class="token operator">=</span> requests<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"http://vyatsu.ru"</span><span class="token punctuation">)</span>
<span class="token keyword">print</span><span class="token punctuation">(</span>response<span class="token punctuation">.</span>text<span class="token punctuation">[</span><span class="token punctuation">:</span><span class="token number">500</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
</code></pre>
<ol start="3">
<li>Сравните полученные данные с анализом Wireshark и измените код первого примера так, чтобы он выглядел как захваченный трафик при использовании <code>requests</code>.</li>
</ol>
<h2 id="работа-с-api-gitea">Работа с API Gitea</h2>
<p><strong>Задание:</strong></p>
<ol>
<li>Сгенерируйте API-токен в Gitea (<code>https://git.vyatsu.ru/user/settings/applications</code>) с правами только на чтение.</li>
<li><strong>Важно!</strong> Токен не должен попадать в коммиты. Добавьте его в <code>.gitignore</code> и используйте переменные окружения.</li>
<li>Выполните запрос к API Gitea:</li>
</ol>
<pre class=" language-python"><code class="prism language-python"><span class="token keyword">import</span> requests
TOKEN <span class="token operator">=</span> <span class="token string">"ВАШ_ТОКЕН"</span>
headers <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token string">"Authorization"</span><span class="token punctuation">:</span> f<span class="token string">"token {TOKEN}"</span><span class="token punctuation">}</span>
response <span class="token operator">=</span> requests<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://git.vyatsu.ru/api/v1/user"</span><span class="token punctuation">,</span> headers<span class="token operator">=</span>headers<span class="token punctuation">)</span>
<span class="token keyword">print</span><span class="token punctuation">(</span>response<span class="token punctuation">.</span>json<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
</code></pre>
<ol start="4">
<li>Выпустите новый токен с правами на запись и, например, создайте репозиторий, issue или комментарий. У каждого студента должно быть свой вариант.</li>
<li>Закоммитьте весь написанный код и выполните <code>git push</code> из среды Visual Studio Code.</li>
</ol>
<h2 id="критерии-успешного-выполнения">Критерии успешного выполнения</h2>
<ul>
<li>Все программы корректно работают и взаимодействуют друг с другом.</li>
<li>В Wireshark зафиксированы последовательности TCP Handshake и завершения соединения.</li>
<li>Анализ трафика выполнен, найдены отличия между <code>socket</code> и <code>requests</code>.</li>
<li>API-токен не попал в коммиты.</li>
<li>Программа взаимодействия с Gitea <a href="http://Vyatsu.ru">Vyatsu.ru</a> написана, отлажена и работает.</li>
<li>Все изменения зафиксированы в git и запушены в удалённый репозиторий на <a href="https://git.vyatsu.ru/">https://git.vyatsu.ru/</a>. В названии репозитория упомянуть, что это третья работа.</li>
</ul>
</div>
</body>
</html>