Сетевик Джонни // Network Admin
5.93K subscribers
513 photos
62 videos
387 links
Я Сетевик Джонни, моя цель в телеграме рассказать все о сетях в доступной форме!

Сотрудничество: @stein_media
Download Telegram
🥷 Джонни вещает: в поисках возможного взлома (ч.3)

Пренеприятнейшая история случилась с одним моим знакомым. Но насколько она оказалась неприятной для Михаила, настолько же занимательной для меня.

Если моя мысль верна и проблема только в переменной ngx_dump_config попробуем установить её c помощью gdb, благо ключик --with-cc-opt -g присутствует и надеемся, что оптимизация -O2 нам не помешает. При этом, раз я не знаю как ngx_dump_config могла быть обработана в case 'T':, не будем вызывать этот блок, а установим её используя case 't':

По шагам:
– устанавливаем точку останова в функции main()
– запускаем программу
– изменяем значение переменной определяющей вывод конфига ngx_dump_config=1
– продолжаем/завершаем программу

Как видим реальный конфиг отличается от нашего, выделяем из него паразитный кусок:

map $http_user_agent $sign_user_agent
{
"~*yandex.com/bots" 1;
"~*www.google.com/bot.html" 1;
default 0;
}

map $uri $sign_uri
{
"~*/wp-" 1;
default 0;
}

map о:$sign_user_agent:$sign_uri $sign_o
{
о:1:0 o;
default о;
}

map а:$sign_user_agent:$sign_uri $sign_a
{
а:1:0 a;
default а;
}

sub_filter_once off;
sub_filter 'о' $sign_o;
sub_filter 'а' $sign_a;


🔍 Рассмотрим по порядку что же здесь происходит.

Определяются User-Agent'ы yandex/google:

map $http_user_agent $sign_user_agent
{
"~*yandex.com/bots" 1;
"~*www.google.com/bot.html" 1;
default 0;
}


Исключаются служебные страницы wordpress:

map $uri $sign_uri
{
"~*/wp-" 1;
default 0;
}


И для тех, кто попал под оба вышеперечисленных условия

map о:$sign_user_agent:$sign_uri $sign_o
{
о:1:0 o;
default о;
}

map а:$sign_user_agent:$sign_uri $sign_a
{
а:1:0 a;
default а;
}


в тексте html-страницы изменяется 'о' на 'o' и 'а' на 'a':

sub_filter_once off;
sub_filter 'о' $sign_o;
sub_filter 'а' $sign_a;


Именно так, тонкость только в том что 'а' != 'a' так же как и 'о' != 'o'

Таким образом боты поисковых систем получают вместо нормального 100%-кириллического текста модифицированный мусор разбавленный латинскими 'a' и 'o'.

#Linux #nginx #unix | @iscode
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥3
Сетевик Джонни // Network Admin
🥷 Джонни вещает: варианты эксплуатации ошибки Получалось, что я могу настроить у себя EIGRP, и включиться в маршрутизацию провайдера. Естественно, меня заинтересовало, как это можно использовать. Чем больше я над этим думал, тем интересней становилось. 🌟
🥷 Джонни вещает: варианты эксплуатации ошибки v.2

1. Украсть трафик: это банально. Подняв у себя EIGRP, я тут же подхватил их таблицу маршрутизации. Имея ее в наличии, легко узнать, какая подсеть свободна, прописать ее на своем маршрутизаторе и получить не лимитированный по трафику или скорости канал. Этим я немного попользовался.

2. Захватить любую из используемых подсетей клиентов: Можно прописать на своем маршрутизаторе любую из присутствующих в таблице маршрутизации подсетей. Если разбить эту подсеть на несколько, с более длинным префиксом, тогда трафик пойдет на вас, а не на клиента провайдера.

— Тут может быть много вариантов использования. К примеру, можно эффективно скрывать следы своей нелегальной деятельности. Для проверки концепции я реально захватывал IP адреса dialup клиентов. Их не жалко, если что, они могут заново подключиться и получить другой IP.
— Другой пример – захватить на время IP адреса DNS серверов провайдера и подменить клиентам провайдера DNS сервер на свой. В этом случае можно даже (о, ужас!!!) красть пароли от одноклассников. Конечно, это сложно сделать так, чтобы вас не вычислили, но сейчас разговор не об этом.

🌟 А давайте задумаемся, какие симптомы сбоя видит клиент, чью сеть захватывают. Для проверки я развернул GNS3. Вот сеть (см. фото 1)

А вот, что происходит при наличии на R1 маршрута с более длинным префиксом до прописанной на его интерфейсе подсети — 192.168.0.0/24, и в случае, когда его нет (см. фото 2)

Клиент просто не видит свой default gateway на третьем уровне. Поэтому, если вы очень злой, то, к примеру, можно устроить красивый, наглый и изощренный DoS сетевым администраторам провайдера, лишив их возможности управлять своей же сетью.

Знаете ли вы, что “true одмины” провайдера любят сидеть в белой подсети, за надежным firewall-ом, который сами же сконфигурировали? При этом возможность доступа на управление устройствами сети есть только из этой подсети. Конечно, не всегда, но так часто делают.


🕹 Чтобы осуществить атаку, надо узнать в какой подсети они сидят. Для этого можно отправить сетевому администратору провайдера ссылку на прикольную картинку на вашем сервере. А когда в ответ придет несколько смайлов, посмотреть IP адрес по логам сервера. Можно использовать и другие подобные методы, социальную инженерию еще никто не отменял.

— Дальше разбить эту подсеть несколько подсетей и прописать их на своем маршрутизаторе. Все, ахтунг обеспечен, у сетевых администраторов провайдера пропал интернет. Со стороны администраторов провайдера покажется, что упал их default gateway. То есть, MAC его виден, но он не пингуется и не доступен на портах управления (telnet, ssh, www). Можно, разве что, подключиться по консоли. Сложно вычислить даже то, что вас атакуют, это больше похоже на аппаратный сбой, или сбой операционной системы на маршрутизаторе. Жестоко, но красиво, правда?

❗️ Мониторинг изменения в маршрутизации не зря считается лучшей практикой. Конечно, не следует давать громкое оповещение, когда в сети меняются маршруты, но IMHO, стоит настроить оповещение о том, что в сети появился новый, участвующий в динамической маршрутизации, маршрутизатор.

#Network #Routing | 😊 @iscode
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥3
🥷 Дыра в щите Cloudflare: как атака на Jabber.ru вскрыла проблему, о которой молчат c 2023

Думаю, многие помнят позапрошлогодний инцидент с Man-in-the-Middle атакой на XMPP-сервис jabber.ru. Эта история наделала много шума, но, как мне кажется, главный вывод из неё так и не был усвоен широкой аудиторией. А зря. Потому что эта атака вскрыла системную уязвимость в процессе выдачи TLS сертификатов, которая напрямую касается миллионов сайтов, особенно тех, кто доверяет свою безопасность Cloudflare.

Разбор полетов: инцидент с jabber.ru

Для тех, кто пропустил или забыл, краткий пересказ:

Что произошло? В течение нескольких месяцев (как минимум с июля по октябрь 2023 года) весь трафик крупнейшего российского XMPP-сервиса jabber.ru перехватывался и расшифровывался. Атакующие смогли получить полностью валидные TLS сертификаты от Let's Encrypt для доменов jabber.ru и xmpp.ru.

Как это сделали? Это не был взлом серверов. Атака была реализована на уровне сети хостинг-провайдеров — Hetzner и Linode. Злоумышленники (предположительно, это была операция в рамках "законного перехвата" государственными акторами) перенастроили маршрутизацию так, что весь трафик, предназначенный серверам jabber.ru, включая запросы на валидацию домена от Let's Encrypt, шёл через их инфраструктуру.

🕹 Перехватив запросы валидации (вероятнее всего, http-01 или tls-alpn-01), они успешно доказали удостоверяющему центру (УЦ) LE, что контролируют домен, и получили легитимные сертификаты. Обнаружили атаку случайно, когда один из мошеннических сертификатов истёк и не был вовремя продлён, что вызвало у пользователей ошибки подключения.

Имхо, ключевой момент здесь — уязвимость не в протоколе XMPP и не в самом УЦ Let's Encrypt. Уязвимость кроется в базовом механизме подтверждения владения доменом (Domain Validation, DV).


В следующем посту начнём с техликбеза по CAA, RFC 8657, накидайте 🔥

#Cloudflare #DNS #MITM | 😊 @iscode
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11🤨2
Сетевик Джонни // Network Admin
🥷 Дыра в щите Cloudflare: как атака на Jabber.ru вскрыла проблему, о которой молчат c 2023 Думаю, многие помнят позапрошлогодний инцидент с Man-in-the-Middle атакой на XMPP-сервис jabber.ru. Эта история наделала много шума, но, как мне кажется, главный вывод…
🌐 Технический ликбез: CAA, RFC 8657 и как это должно нас спасать

Казалось бы, если твой трафик могут перехватить на уровне провайдера, то ты беззащитен. Но это не так. Для защиты от подобных сценариев существует механизм Certification Authority Authorization (CAA), описанный в RFC 8659.

Это простая DNS запись, которая говорит: "Для моего домена сертификаты может выпускать только вот этот УЦ".

# Разрешаем только Let's Encrypt
example.com. IN CAA 0 issue "letsencrypt.org"


Но, как показал случай с jabber.ru, этого недостаточно. Атакующие ведь и использовали разрешённый УЦ, который им и выдал сертификат.

Постфактум, благодаря анализу инцидента инженером по имени Хьюго Ландау (Hugo Landau), он пришёл к выводу, что предложенный им стандарт ещё в далеком 2019 году под номером RFC 8657 мог бы предотвратить подобный инцидент. Этот стандарт расширяет CAA двумя критически важными параметрами:

1. accounturi: Это «второй фактор» для выдачи сертификата. Этот параметр привязывает выдачу сертификатов к конкретному аккаунту в УЦ. URI вашего аккаунта в Let's Encrypt — это уникальный идентификатор.

# Разрешаем Let's Encrypt, но ТОЛЬКО с аккаунта с ID 12345678

example.com. IN CAA 0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/12345678"

Даже если злоумышленник перехватит ваш трафик, он не сможет получить сертификат, потому что его запрос придёт с другого аккаунта Let's Encrypt, а LE поддерживает этот стандарт ещё с января 2021 года. УЦ сверит accounturi из запроса с тем, что указан в вашей CAA-записи, увидит несоответствие и откажет в выпуске.

2. validationmethods: Этот параметр позволяет ограничить методы, которыми УЦ может проверять владение доменом.

# Разрешаем Let's Encrypt, но только через DNS-валидацию

example.com. IN CAA 0 issue "letsencrypt.org; validationmethods=dns-01"

Поскольку атака на jabber.ru была возможна из-за перехвата сетевого трафика, ограничение валидации методом dns-01 (который требует внесения изменений в DNS-зону, а не контроля над трафиком) сделало бы атаку значительно сложнее, а использование DNSSEC доменом могло бы сделать её вовсе невозможной.

3. Комбо

# Максимальная защита

example.com. IN CAA 0 issue "letsencrypt.org; validationmethods=dns-01;
accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/12345678"

Хьюго Ландау, автор RFC 8657, заявлял в своём анализе инцидента, что основываясь на том, что мы знаем об этой атаке, она была бы предотвращена развёртыванием этого расширения.

#Cloudflare #DNS #MITM #CAA #RFC | 😊 @iscode
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👍5
Сетевик Джонни // Network Admin
Дыра в щите Cloudflare: как атака на Jabber.ru вскрыла проблему, о которой молчат c 2023
🥷 Слон в посудной лавке: при чём тут Cloudflare?

А теперь самое главное. Cloudflare, будучи лидером в области интернет-инфраструктуры и безопасности, для своего безальтернативного для бесплатных аккаунтов сервиса Universal SSL делает очень странную вещь - когда он включен, Cloudflare автоматически добавляет в вашу DNS-зону CAA-записи для своих партнёрских УЦ (Let's Encrypt, Google Trust Services и др.).

Вот как выглядит эта запись:

# Записи для обычных сертификатов (issue)
example.com. IN CAA 0 issue "letsencrypt.org"
example.com. IN CAA 0 issue "pki.goog; cansignhttpexchanges=yes"
example.com. IN CAA 0 issue "digicert.com; cansignhttpexchanges=yes"
example.com. IN CAA 0 issue "comodoca.com"
example.com. IN CAA 0 issue "ssl.com"

# Записи для wildcard-сертификатов (issuewild)
example.com. IN CAA 0 issuewild "letsencrypt.org"
example.com. IN CAA 0 issuewild "pki.goog; cansignhttpexchanges=yes"
example.com. IN CAA 0 issuewild "digicert.com; cansignhttpexchanges=yes"
example.com. IN CAA 0 issuewild "comodoca.com"
example.com. IN CAA 0 issuewild "ssl.com"

Видите проблему? Они до сих пор не используют accounturi и не дают переписать записи!

Это оставляет ту же самую дыру в безопасности, от которой пострадал jabber.ru . Cloudflare, по сути, говорит: "Любой аккаунт в Let's Encrypt может получить сертификат для этого домена, если пройдёт валидацию".

Ваша собственная, более строгая CAA-запись с accounturi для вашего сервера, не спрятанного за прокси, становится практически бесполезной. Потому что по правилам обработки CAA, если есть хотя бы одна разрешающая запись без accounturi, УЦ имеет право выпустить сертификат для любого аккаунта. А если вы решите вручную прописать в CF записи с accounturi , то CF заботливо их не применит и оставит свои. А чтобы отказаться от Universal SSL, придётся заплатить чеканную монету.

— Таким образом, Cloudflare не просто не использует современные стандарты безопасности для своих клиентов, но и активно мешает им делать это самостоятельно, сводя на нет всю идею RFC 8657.

Выводы и что делать?
Ситуация на данный момент патовая. С одной стороны, у нас есть рабочий и поддерживаемый ведущими УЦ (Let's Encrypt внедрил это ещё в 2021 году) стандарт, который решает реальную и доказанную проблему. С другой - крупнейший инфраструктурный провайдер, который не только игнорирует этот стандарт, игнорирует сообщения об этом стандарте, но и своей реализацией создаёт риски для миллионов пользователей.

Для пользователей:

1. Проведите аудит. Проверьте свои CAA-записи. Если вы используете Universal SSL от Cloudflare, знайте, что вы уязвимы для атак типа jabber.ru.
2. Требуйте перемен. Если вам небезразлична безопасность вашего проекта, поддержите мою тему на форуме Cloudflare. Чем больше будет резонанс, тем выше вероятность, что нас услышат. Это не первый такой запрос, но предыдущие были попросту проигнорированы.
3. Рассмотрите альтернативы. Для критически важных проектов, возможно, стоит отказаться от Universal SSL в пользу ручного управления сертификатами и полного контроля над CAA-записями либо в Cloudflare, либо в другом сервисе.

Что должен сделать Cloudflare:
1. Начать использовать accounturi и validationmethods для всех сертификатов, которые они выпускают в рамках Universal SSL. Это немедленно и по умолчанию повысит безопасность для всех их клиентов. Они же точно знают ID своих профилей, который запрашивают выпуск сертификатов?
2. Обеспечить полное управление CAA-записями для пользователей, чтобы они могли добавлять свои собственные записи с accounturi и validationmethods, и чтобы эти записи корректно сосуществовали с записями Cloudflare.
3. Обновить документацию и честно рассказать пользователям о текущих рисках и о том, как они обрабатывают CAA.

Да, белый пушистый лис не объявит себя до некоторого времени, но, как показывает практика, он гарантированно придёт. И лучше закрыть эту дыру сейчас, чем потом разгребать последствия, как это пришлось делать администраторам jabber.ru.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14👍4🤨2
Please open Telegram to view this post
VIEW IN TELEGRAM
🤣11
🥷 Глубокий разбор российских СЗИ: антивирусы, НСД, виртуализация

Коллеги, выбор отечественных средств защиты информации (СЗИ) — критически важен для ИБ-инфраструктуры. Где искать актуальные исследования и глубокий анализ? И почему же это важно? об этом речь пойдёт ниже:

Во-первых, если криво выбрать СЗИ, оно запросто может тормозить всю сеть – представим, что антивирус начнет грузить канал до упора или агент контроля доступа положит сервер. И безопасность сегментов тоже станет под ударом: слабое звено в одном месте – угроза для всех.
Во-вторых, защита виртуализации – это прямая связка с сетевым разделением! VLAN'ы, микросегментация – они должны идеально работать с тем, как СЗИ изолирует виртуалки и контролирует трафик между ними. Без этого толку – ноль.

🕹 Ну и не забудем про централизованное управление: все эти консоли для СЗИ жрут сеть как не в себя. Если инфраструктура кривая – лаги, потеря событий безопасности, администрирование превратится в кошмар. Короче, без нормальной сети – никак. Вот почему стоит всегда быть в курсе фишек и подводных камней российских СЗИ.

🔍 Основной упор — канал CORTEL: @Cortel_cloud

Именно там регулярно публикуют:
Детальные сравнительные обзоры российских СЗИ по всем указанным направлениям.
8 кругов ада на пути отказа от зарубежных виртуальных платформ
4 кейса успешной замены иностранных гипервизоров
Как энергетики перевели ИТ-инфраструктуру на российский софт

Ещё больше полезного про ИБ и не только в канале CORTEL

➡️ Подписаться

Реклама ООО "Кортэл"
ИНН: 7816246925
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍2👎1
🤨 С Днём Сисадмина! А кто его сегодня отмечает?

Профессию сисадмина пытались забыть несколько раз: когда появились облака, когда рынок захватила автоматизация, когда страшно модным стал DevOps. 2020-2021 годы показали, что слухи об исчезновении системных администраторов в компаниях всего мира слишко преувеличены, а вот переход на удалёнку без них — вполне себе масштабная беда.

🤷 Мы не знаем, откуда берутся слухи, но уверены, что сисадминам ещё придётся администрировать роботов, разруливать проблемы с каналом до Луны и Марса и вообще как-то разгребать эту суету, наведённую неуёмными инженерами и программистами.

В общем, без сисадминов — никуда.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
24👍11
🥷 Джонни вещает: проброс авторизации

OpenSSH позволяет использовать сервера в качестве плацдарма для подключения к другим серверам, даже если эти сервера недоверенные и могут злоупотреблять чем хотят.

🆘 Для понимания ситуации, пример ниже будет ссылаться на вот эту схему (click)

Допустим, мы хотим подключиться к серверу 10.1.1.2, который готов принять наш ключ. Но копировать его на 8.8.8.8 мы не хотим, ибо там проходной двор и половина людей имеет sudo и может шариться по чужим каталогам.

— Компромиссным вариантом было бы иметь «другой» SSH-ключ, который бы авторизовывал user@8.8.8.8 на 10.1.1.2, но если мы не хотим пускать кого попало с 8.8.8.8 на 10.1.1.2, то это не вариант (тем паче, что ключ могут не только поюзать, но и скопировать себе «на чёрный день»).

⚙️ SSH предлагает возможность форварда SSH-агента (это такой сервис, который запрашивает пароль к ключу). Опция ssh -A пробрасывает авторизацию на удалённый сервер.

Вызов выглядит так: ssh -A user@8.8.8.8 ssh user2@10.1.1.2

Удалённый SSH-клиент (на 8.8.8.8) может доказать 10.1.1.2, что мы это мы только если мы к этому серверу подключены и дали SSH-клиенту доступ к своему агенту авторизации (но не ключу!).

#SSH #Authorization | 😊 @iscode
Please open Telegram to view this post
VIEW IN TELEGRAM
👍184
📊 Статистика DDoS продолжает бить рекорды

1 сентября была зафиксирована крупнейшая атака этого года: 5,76 млн задействованных устройств из разных регионов.
Инцидент успешно отражён специалистами Curator, и это уже третий рекорд в 2025 году.

Подробный разбор атаки и методов защиты — в посте
🔥9
Media is too big
VIEW IN TELEGRAM
🥷 Джонни вещает: установка и настройка Sysmon

Установка и настройка простой и эффективной системы мониторинга за событиями на компьютере, в том числе и нарушения безопасности. На основе этой системы можно вытроить надежную и бесплатную систему защиты от хакерских атак и вирусного заражения. Так же она может служить источником данных для комплексных систем безопасности EDR и SIEM.

Установка системы занимает считанные секунды и может быть полностью автоматизирована.

EDR (Endpoint Detection & Response) - система обнаружения вредоносной активности на конечных точках
SIEM (Security information and event management) - система анализа в реальном времени событий безопасности


#sysmon #EDR #SIEM | 😏 @iscode
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12
🥷 Джонни вещает: как провести стресс-тестирование вашей системы Linux

Стресс-тестирование Linux — ключевой этап подготовки серверов к реальной работе.

Оно позволяет выявить слабые места системы, проверить её устойчивость под высокой нагрузкой и подготовиться к неожиданным пиковым ситуациям. Разберем простые методы и мощные инструменты, которые помогут нагрузить систему и оценить её поведение.

Методы стресс-тестирования Linux

1. Нагрузка через циклы

Создание бесконечных циклов нагружает процессор. Это простой способ проверить систему.

Запуск нагрузки:

for i in 1 2 3 4; do while : ; do : ; done & done

Каждый цикл запускается в фоновом режиме и увеличивает нагрузку на ЦП.

Мониторинг нагрузки:
Запускайте команду uptime каждые 30 секунд, чтобы наблюдать за изменением средней загрузки:

while true; do uptime; sleep 30; done

Остановка нагрузки:
Чтобы завершить циклы, используйте kill, указав номера заданий:

kill %1 %2 %3 %4

2. Использование утилиты stress

stress — мощный инструмент, который позволяет создавать нагрузку на различные ресурсы системы: ЦП; память; ввод/вывод

Примеры использования stress:
Нагрузка на процессор:
stress --cpu 4

Чем больше указано ядер (--cpu), тем выше нагрузка на систему.

Нагрузка на память:
stress --vm 2

Нагрузка на ввод/вывод (I/O):
stress --io 4

Для анализа работы ввода/вывода используйте iotop:
sudo iotop

3.
Написание скриптов для мониторинга

Для удобного отслеживания нагрузки вы можете написать скрипт. Например, для мониторинга использования памяти:

#!/bin/bash
while true
do
free
sleep 30
done

Скрипт отображает использование памяти каждые 30 секунд. Вы можете адаптировать его под свои задачи.

Проведение стресс-тестов помогает: подготовиться к реальным пиковым нагрузкам; улучшить производительность системы; найти и устранить возможные проблемы на этапе разработки.

#Stress | @iscode
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8👍6
🥷 Как работает DNS в Linux. Часть 1: от getaddrinfo до resolv.conf

Когда ты вводишь в браузере имя сервера или доменное имя сайта, pingуешь или запускаешь любое удаленное приложение, операционная система должна преобразовать указанные имена в IP-адреса. Этот процесс называется разрешением доменного имени. На первый взгляд он может показаться весьма прозрачным, однако за ним скрывается многослойный механизм.

Данный пост — начало серии, посвященной низкоуровневой архитектуре разрешения имен. Поговорим о том, как устроен этот процесс в Linux на уровне ядра, различных библиотек C и системных вызовов.

— Многие знают, что процесс разрешения имен в Linux — это не просто «вызов DNS», а цепочка из библиотек, конфигурационных записей и вызовов, зависящих от реализации конкретного приложения, используемых типов библиотек и системных настроек.

В этой части постараемся разобрать все по слоям и собрать некую фундаментальную базу в кратком и доступном виде.

Вершина айсберга: почти все современные приложения в Linux, от curl до systemd, используют функцию getaddrinfo() из стандартной библиотеки C (glibc или musl). Именно она выполняет основную работу по переводу доменного имени в IP-адрес (A, AAAA-записи) в зависимости от настроек и запроса.

При этом она не только выполняет DNS-запросы, но и обрабатывает другие типы данных, такие как имена сервисов, например, преобразует имя сетевого сервиса “http” в порт 80, используя /etc/services. Это делает ее универсальным инструментом для сетевых приложений.

Функция getaddrinfo() возвращает список структур addrinfo, каждая из которых содержит IP-адрес, тип сокета, протокол и другие параметры. Это позволяет приложениям выбирать наиболее подходящий адрес для подключения.

Пример использования getaddrinfo() в псевдокоде:

```
struct addrinfo hints, *res;
zero_memory(hints);
hints.ai_family = ANY_FAMILY;
hints.ai_socktype = TCP;

err = getaddrinfo("example.com", "http", hints, &res);
if (err == 0) {
for each addr in res:
use(addr)
freeaddrinfo(res);
} else {
print(gai_strerror(err));
}


```

При этом getaddrinfo() — это вершина айсберга. Для получения IP-адреса она вызывает цепочку внутренних механизмов, прописанную в конфигурационных данных системы. Один из этих механизмов — NSS (Name Service Switch), о нём мы поговорим в следующем посте.

#DNS #Linux | 😏 @iscode
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥5🤣1
🥷 Как работает DNS в Linux. Часть 1: NSS

NSS реализован на основе подгружаемых модулей — динамических библиотек, соответствующих API glibc, таких как libnss_dns.so, libnss_files.so, libnss_myhostname.so и других. Они функционируют как плагины и подгружаются библиотекой glibc во время выполнения, отвечая за конкретные методы разрешения IP-адресов. Порядок и набор источников, используемых для разрешения имен, задается в конфигурационном файле /etc/nsswitch.conf.

Пример содержания nsswitch.conf:

# /etc/nsswitch.conf

passwd: files systemd
group: files systemd
shadow: files
gshadow: files

hosts: files dns myhostname
networks: files

protocols: db files
services: db files
ethers: db files
rpc: db files

netgroup: nis


Например, строка в модулях с содержанием ``hosts: files dns`` говорит, что сначала ищется соответствие в локальном файле /etc/hosts, и если модуль files возвращает результат, то последующие модули, такие как dns (делающий DNS-запрос) не будут вызваны.

Соответственно, если в nsswitch.conf строка hosts не включает упоминание модуля dns, то конфигурационный файл resolv.conf, содержащий настройки обращения к DNS-источникам, проигнорируется, и DNS-запрос не будет сформирован.


🕹 Также в NSS могут задействоваться модули mdns (для Zeroconf/Avahi), nis (в старых системах) и myhostname.

Модуль myhostname является частью systemd и используется для разрешения локального имени хоста. Он не всегда присутствует в минималистичных системах, таких как Alpine Linux.

В следующем посте расскажу о библиотеках экосистемы Linux, ожидайте, сегодня продолжение 🪳

#DNS #Linux | 😏 @iscode | YouFast VPN — сильнейший из всех
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11
Сетевик Джонни // Network Admin
В следующем посте расскажу о библиотеках экосистемы Linux, ожидайте, сегодня продолжение
🥷 Как работает DNS в Linux. Часть 1: Библиотеки

Нижеперечисленные библиотеки экосистемы Linux являются ключевыми и предоставляют приложениям определенный набор функций, включая разрешение доменных имен.

1. Glibc — наиболее распространённая реализация стандартной библиотеки языка C, реализует высокоуровневые функции, такие как getaddrinfo(). Она взаимодействует с NSS (Name Service Switch) для определения источников разрешения имён (например, /etc/hosts, DNS) и использует библиотеку libresolv для выполнения DNS-запросов.

- Glibc может использовать системные вызовы, такие как sendto и recvfrom для отправки и получения DNS-запросов по UDP или TCP. Широко распространена в большинстве дистрибутивов Linux (Ubuntu, Debian, Fedora и др.)

2. Musl — альтернативная стандартная библиотека C, разработанная с упором на минимализм, производительность и совместимость со стандартами POSIX. Она используется в легковесных дистрибутивах, таких как Alpine Linux.

- Musl реализует разрешение доменных имён напрямую, без использования NSS, самостоятельно читает /etc/hosts и /etc/resolv.conf и отправляет DNS-запросы, не используя внешние библиотеки вроде libresolv. Однако musl имеет ограничения в поддержке некоторых параметров resolv.conf, таких как rotate или сложные search.

3. Libresolv.so — является частью glibc, реализующая низкоуровневую работу с DNS, выполняя такие запросы, как res_query() и res_send(), но может использоваться независимо в некоторых приложениях вроде nslookup (что позволяет выполнять DNS-запросы напрямую, минуя стандартные механизмы разрешения имен).

- Libresolv используется glibc для выполнения DNS-запросов, когда NSS указывает, что нужно обратиться к DNS. Она читает /etc/resolv.conf, формирует DNS-пакеты и отправляет их на указанные серверы по UDP или TCP.

Стоит отметить, что некоторые приложения, например, написанные на Go, могут полностью обходить glibc/musl и использовать собственные DNS-резолверы.

#DNS #Linux | 😏 @iscode | YouFast VPN — сильнейший из всех
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
🥷 Как работает DNS в Linux. Часть 1: обработка resolv.conf и что делает res_query()

Файл /etc/resolv.conf содержит основные настройки клиента DNS, а именно: список серверов, параметры, search-домены. Например:

nameserver 192.168.1.1
search dev.local
options timeout:2 attempts:3


— Glibc и libresolv парсят его вручную при необходимости.

Важные моменты и ограничения:

- опции вроде rotate, ndots, timeout и attempts влияют на поведение запроса;

- опция rotate используется для циклического выбора серверов из списка nameserver, но она не поддерживается в musl;

- search используется для автодополнения, например, если имя db01 не является FQDN, к нему будут по очереди подставляться домены из директивы search.

Важно отметить, что файл resolv.conf может быть динамически изменён DHCP-клиентом, NetworkManager или утилитой resolvconf, что может вызывать путаницу при решении проблем с DNS. Об этом мы поговорим в одной из следующих частей.


Касательно res_query(), это функция из libresolv, вызываемая внутренне в процессе разрешения имени. Она формирует DNS-пакет вручную и отправляет его на указанные в resolv.conf DNS-серверы. Её используют утилиты вроде nslookup, а также некоторые программы, которые обходят getaddrinfo().

Функция отправляет DNS-запросы с помощью res_send() по UDP, а при необходимости, например, при получении ответов, превышающих 512 байт, переключается на TCP.

🕹 Важно: при использовании res_query() вы не получите информацию из /etc/hosts, NSS или других источников. Это DNS-запрос в чистом виде. Поэтому dig или nslookup могут получить один результат, а, например, ping или curl — совсем другой.

1. res_query() считается устаревшей функцией, использовать ее не рекомендуется. Для более удобной и безопасной работы с DNS лучше отдать предпочтение getaddrinfo() или таким библиотекам, как c-ares или libdns.

2. c-ares — легковесная библиотека для асинхронных DNS-запросов, часто используется в высоконагруженных приложениях (например, curl и Node.js)

3. libunbound (из проекта Unbound) — более мощная библиотека с поддержкой DNSSEC и гибкой настройкой запросов.

В следующем посте расскажу о порядке реализации запросов и приоритетов, ожидайте, сегодня продолжение 🪳

#DNS #Linux | 😏 @iscode | YouFast VPN — сильнейший из всех
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍3
🥷 Как работает DNS в Linux. Часть 1: порядок реализации запросов и приоритеты

Вот типичный порядок разрешения имени в Linux при использовании glibc и NSS:

1. Приложение вызывает getaddrinfo();

2. getaddrinfo() обращается к системе NSS и следует заданному в nsswitch.conf порядку;

3. Если первым указан модуль files, имя ищется в файле /etc/hosts;

4. Если включён модуль dns, NSS вызывает libnss_dns.so, которая обращается к функциям из libresolv;

5. libresolv формирует DNS-запрос через res_query() и отправляет его с помощью res_send() на указанные в resolv.conf адреса DNS-серверов, затем получает и возвращает IP-адрес.

#DNS #Linux | 😏 @iscode | YouFast VPN — сильнейший из всех
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16
Сетевик Джонни // Network Admin
🥷 Как работает DNS в Linux. Часть 1: порядок реализации запросов и приоритеты
🥷 Как работает DNS в Linux. Часть 1: порядок реализации запросов и приоритеты

Важно: если имя найдено на одном из шагов, например, в hosts, последующие источники не используются.

В минималистичных системах, таких как Alpine Linux с musl, порядок может отличаться, так как musl не использует NSS и реализует DNS-запросы напрямую, читая /etc/hosts и resolv.conf самостоятельно.

Некоторые приложения и языки (например, Go, Java, Node.js) могут использовать собственные DNS-резолверы, полностью игнорируя системные настройки.

Для примера проанализируем работу утилиты curl.

Команда:

strace -f -e trace=network curl -s download.astralinux.ru > /dev/null
Вывод strace:
socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP) = 3
socketpair(AF_UNIX, SOCK_STREAM, 0, [3, 4]) = 0
socketpair(AF_UNIX, SOCK_STREAM, 0, [5, 6]) = 0
strace: Process 283163 attached
[pid 283163] socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 7
[pid 283163] connect(7, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (Нет такого файла или каталога)
[pid 283163] socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 7
[pid 283163] connect(7, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (Нет такого файла или каталога)
[pid 283163] socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, IPPROTO_IP) = 7
[pid 283163] connect(7, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("172.24.31.107")}, 16) = 0
[pid 283163] sendmmsg(7, [{msg_hdr={msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="\250\207\1\0\0\1\0\0\0\0\0\0\10download\nastralinux"..., iov_len=40}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, msg_len=40}, {msg_hdr={msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="\240\215\1\0\0\1\0\0\0\0\0\0\10download\nastralinux"..., iov_len=40}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, msg_len=40}], 2, MSG_NOSIGNAL) = 2
[pid 283163] recvfrom(7, "\250\207\201\200\0\1\0\1\0\0\0\0\10download\nastralinux"..., 2048, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("172.24.31.107")}, [28->16]) = 56
[pid 283163] recvfrom(7, "\240\215\201\200\0\1\0\0\0\1\0\0\10download\nastralinux"..., 65536, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("172.24.31.107")}, [28->16]) = 114
[pid 283163] sendto(6, "\1", 1, MSG_NOSIGNAL, NULL, 0) = 1
[pid 283163] +++ exited with 0 +++
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 5
setsockopt(5, SOL_TCP, TCP_NODELAY, [1], 4) = 0
setsockopt(5, SOL_SOCKET, SO_KEEPALIVE, [1], 4) = 0
setsockopt(5, SOL_TCP, TCP_KEEPIDLE, [60], 4) = 0
setsockopt(5, SOL_TCP, TCP_KEEPINTVL, [60], 4) = 0
connect(5, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("130.193.50.59")}, 16) = -1 EINPROGRESS (Операция выполняется в данный момент)
getsockopt(5, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
getpeername(5, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("130.193.50.59")}, [128->16]) = 0
getsockname(5, {sa_family=AF_INET, sin_port=htons(48488), sin_addr=inet_addr("172.24.31.241")}, [128->16]) = 0
sendto(5, "GET / HTTP/1.1\r\nHost: download.a"..., 86, MSG_NOSIGNAL, NULL, 0) = 86
recvfrom(5, "HTTP/1.1 200 OK\r\nServer: nginx/1"..., 102400, 0, NULL, NULL) = 1617

🔍 Что мы видим в этом strace?

1. Попытка использовать NSCD (Name Service Cache Daemon)

connect(..., "/var/run/nscd/socket", ...) = -1 ENOENT
- Это означает, что glibc сначала пытается использовать кеш имён из NSCD, если он запущен. В системе его нет, и запрос идёт дальше.

2. Вызов socket() и connect() к DNS-серверу

socket(AF_INET, SOCK_DGRAM|..., IPPROTO_IP) = 7
connect(7, ..., sin_addr=inet_addr("172.24.31.107")...)

- Здесь создаётся UDP-сокет для обращения к DNS-серверу, указанному в /etc/resolv.conf.

3. Вызов sendmmsg() — отправка DNS-запросов

sendmmsg(7, [ { "download.astralinux.ru" }, { "download.astralinux.ru" } ], ...)
Здесь отправляются запросы на резолв имени.

4. Ответ от DNS

recvfrom(...) = 56
recvfrom(...) = 114

Теперь IP-адрес известен.

56 - это размер DNS-ответа в байтах, содержащего А-запись (IPv4-адрес)
Please open Telegram to view this post
VIEW IN TELEGRAM
👍61
Сетевик Джонни // Network Admin
🥷 Как работает DNS в Linux. Часть 1: порядок реализации запросов и приоритеты
114 - размер дополнительных данных, например CNAME, или авторитетные серверы в случае рекурсивного запроса.

5. TCP-соединение по IP

connect(5, ..., sin_addr=inet_addr("130.193.50.59"))
Здесь уже сам curl устанавливает TCP-соединение по IP-адресу, который ему вернула getaddrinfo().

‼️ Таким образом, когда мы вызываем curl, мы не видим DNS-запросов напрямую — их делает библиотека glibc внутри вызова getaddrinfo(). Но strace позволяет увидеть косвенные признаки:

Среди вызовов будет попытка подключиться к nscd, вызов connect() к DNS-серверу, отправка UDP-пакета через sendmmsg(), а затем — стандартное TCP-соединение по IP:


connect(7, {AF_INET, 172.24.31.107:53}) = 0
sendmmsg(7, [{ "download.astralinux.ru" }]) = 2
recvfrom(7, ...) = ...
connect(5, {130.193.50.59:80}) = 0


Важно отметить, что поведение getaddrinfo() может зависеть от реализации libc. Например, в glibc результаты могут кэшироваться, что влияет на производительность и актуальность данных.

#DNS #Linux | 😏 @iscode | YouFast VPN — сильнейший из всех
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9