This repository has been archived by the owner on Sep 9, 2021. It is now read-only.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Инструкция по сборке/установке и использованию
Клиент реализован на языке python, сборка не требуется.
Запуск на Linux :
Права суперпользователя требуются, так как сервер использует 53-ий порт, входящий в число системных портов.
На Windows необходимо открыть терминал от имени администратора, а затем выполнить python3 DNS_Server.py
Адрес и порт DNS сервера, а также путь до файла, в котором будут храниться соответствия доменных имён и IP адресов, указываются в файле NTP_Servert.py:
Описание используемого протокола
Формат DNS-пакета:
Header - заголовок пакета
Question - секция запросов
В общем случае, секция Question может содержать более одного запроса, но, зачастую, запрос всё же один, и данная реализация DNS сервера будет обрабатывать только первый запрос в секции Question, игнорируя остальные, если таковые имеются.
Answer - секция ответов
Секции Authority и Additional в данной реализации DNS сервера не используются.
Структура заголовка:
ID - уникальный идентификатор транзакции. Он указывает на то, что пакеты принадлежат одной и той же сессии “запросов-ответов”. Сервер копирует ID из запроса клиента.
QR - бит, служащий для идентификации того, является ли пакет запросом (QR = 0) или ответом (QR = 1).
Opcode - Тип запроса (0 - стандартный запрос, 1 - инверсный запрос, 2- запрос статуса сервера, 3-15 - зарезервированы)
Данная реализация сервера поддерживает только стандартные запросы.
AA - Authoritative Answer - бит, свидетельствующий о том, является ли сервер ответственным за запрошенное доменное имя
TC - TrunCation - бит, устанавливаемый, если сервер не смог поместить в пакет всю необходимую информацию из-за каких-либо ограничений
RD - Recursion Desired - бит, устанавливаемый клиентом, и копируемый сервером. Сообщает о том, что клиент просит сервер выполнить запрос рекурсивно
RA - Recursion Available - устанавливается сервером и показывает, поддерживает ли сервер рекурсивное выполнение запроса
Z - зарезервированные биты, равные нулю
Rcode - Response code - код ответа (0 - запрос выполнен без ошибок, 1 - ошибка, связанная с тем, что сервер не смог понять запрос, 2 - внутренняя ошибка на сервере, 3 - запрашиваемое имя не существует в рамках данного домена (существенно только для авторитетных серверов), 4 - сервер не может выполнить запрос данного типа, 5 - сервер не может удовлетворить запроса клиента в силу административных ограничений безопасности, 6-15 - зарезервировано)
QDCOUNT - количество записей в секции запросов
ANCOUNT - количество записей в секции ответов
NSCOUNT - количество записей в секции Authority (в нашем случае всегда 0)
ARCOUNT - количество записей в секции Additional (в нашем случае всегда 0)
Структура секции Question:
QNAME - доменное имя, представленное в виде последовательности меток. Возможно два варианта записи этой последовательности:
Если первые два бита метки - 00, то остальные 6 бит определяют длину метки, за которой следует данное количество октетов, затем следует новая длина метки и новое количество октетов, и так пока не будет встречен нулевой байт.
Полученные октеты содержат коды символов запрашиваемого имени, разделённого на части в соответствии с доменными зонами. Например, имя yandex.ru будет разделено на 2 части yandex и ru, в первой части 6 символов, соответственно, нам понадобится 6 октетов для его хранения и первое число в метке будет 6. За ним будут следовать 6 закодированные символов (y, a, n ,d, e, x). Следом будет идти новая длина метки - 2 (так как "ru" содержит 2 символа) и два октета с закодированными символами. Следом будет идти нулевой байт, говорящий о том, что имя закончено.
Если первые два бита метки - 11, то последующие 14 бит определяют ссылку на начальный адрес последовательности меток первого типа. Ссылка представляет собой сдвиг относительно начала DNS пакета.
QTYPE- тип записи (NS, A, TXT и т.д.)
Данная реализация сервера поддерживает только записи типа A.
QCLASS- класс записи (IN для записей класса Internet, самого широко используемого)
Структура секции Answer:
NAME- доменное имя в таком же формате, как и в секции запросов
TYPE- тип ресурсной записи (NS, A, TXT и т.д.)
CLASS- класс ресурсной записи (IN для Internet)
TTL - допустимое время хранения данной ресурсной записи в кэше неответственного DNS-сервера в секундах
RDLENGTH - длина поля RDATA в байтах
RDATA - поле данных. В случае стандартного запроса и типа записи А, содержит 4 октета с IP адресом.
Принцип работы получается следующим:
Пример работы
Сервер был запущен с ip 0.0.0.0 на порте 53:
Содержание файла RR.txt в начале работы сервера:
Запрос на сервер с помощью утилиты dig (имя имеется в RR.txt):
Получаем верный ответ с сервера
Запрос на сервер с помощью утилиты dig (имени нет в RR.txt):
По TTL видно, что ответ не был сконструирован на сервере (TTL != 300)
Содержание файла RR.txt после этого запроса:
Повторим запрос и по увидим, что теперь ответ не перенаправляется откуда-то, а собирается на сервере (TTL = 300):
Результат при отправке пакета с opcode !=0:
Видно, что пришёл пакет со статусом NOIMPL