http-tester
Недавно я переносил часть своего сайта на отдельный поддомен. После того, как новый домен был настроен я всё проверил и всё работало. Спустя некоторое время я столкнулся со странным поведением на своей машине. Я заходил на сайт на поддомене и тут же оказывался на основном сайте. На компьютере рядом такой проблемы не было. Я начал грешить на то, что поймал перманентный редирект, пока настраивал всё. Но оказалось, что нет. Однако я заметил, что первый запрос на домен идёт по HTTP/3, и именно оттуда идёт редирект. Проблема оказалась в том, что сайт то я настроил, но не указал ему слушать по HTTP/3. В результате те, кто заходил по этому протоколу попадали на сайт по умолчанию, где и стояло правило редиректа на мой основной сайт. Поискав способы всё быстро протестировать, я столкнулся с тем, что не нашёл подходящих инструментов, поэтому решил реализовать свой.
Начнём с постановки задачи. У нас есть веб-сервер, который должен быть доступен в интернете по нескольким протоколам разного уровня.
Первая проблема — два протокола IP: IPv4 и IPv6
Меня очень расстраивает такой медленный переход интернета на IPv6, который решает множество проблем и позволяет сделать интернет быстрее и дешевле. Но до сих пор многие провайдеры упираются и продолжают «втюхивать IPv4 своим клиентом за оверпрайс». И я ещё понимаю, что дефицитные штуки, вроде IPv4 адресов, стоят дорого, то зачем расходовать средства на обеспечение его работы. Провайдеры натурально закупают оборудование просто для того, чтобы продлить жизнь IPv4, вместо того, чтобы закупать оборудование, которое будет делать примерно тоже самое, но его можно будет постепенно выкинуть, потому что IPv4 будет никому не нужен по мере его внедрения.
Так или иначе, мне нужно обеспечить доступ на свой сайт для прогрессивных провайдеров с IPv6 и для тех, кто плетётся в хосте с IPv4. Мне нужно учитывать, что клиенты могут пользоваться IPv4 или IPv6. Всё это должна учитывать моя утилита.
Вторая проблема — HTTP часто перенаправляет на HTTPS
Пользователь вбивает в адресной строке мой сайт tavda.org и некоторые браузеры до сих пор пытаются зайти на HTTP его версию. Да, это не запрещено. Контентные сайты могут себе это позволить. Но тогда все те, кто перехватывает ваш трафик может видеть, что вы читаете и даже подменять содержимое, например, добавляя к контенту свои рекламные баннеры. Поэтому самым лучшим вариантом будет переадресовывать своих клиентов на безопасную HTTPS версию сайта, с котрой весь обмен трафиком идёт в зашифрованном виде через TLS соединение. Кроме того, пользователь также может убедиться, что работает с настоящим сайтом, а не его вредоносной копией.
Третья проблема — производительность
Обычный протокол HTTP/1, который чаще обозначают как HTTP/1.1, т.е. его доработанная версия, пришёл в мир шифрования со всеми своими проблемами. Для каждого файла нужно было устанавливать своё соединение. С учётом того, что у вас есть шифрование, каждое соединение требует установления защищённого туннеля для передачи данных. Когда файлов много, особенно мелких, возникают слишком большие накладные расходы, т.е. увеличивается объём трафика. В этот момент на сцену выходит протокол HTTP/2, который позволяет мультиплексировать запросы внутри одного соединения. Теперь достаточно один раз соединиться с веб-сервером, и он отдаст вам по одному соединению всё, что вы попросите.
Но и это ещё не всё. Обычные запросы http и https - это стандартные TCP соединения для протокола IP. Если у вас стабильный канал связи, например, оптика+медный кабель, то у вас практически нет ошибок и всё доставляется моментально. Однако если вы пользуетесь своим сотовым телефоном, то возможны часто потери пакетов. В этом случае ваша операционная система пытается перезапросить те данные, которая она не смогла получить. Но делает это она по определённому алгоритму, возможно, не самому оптимальному, на который браузер не может повлиять. И от тут на сцену выходит новый протокол QUIC, который работает по UDP. UDP подразумевает, что все пакеты, которые передаются между клиентом и сервером могут по пути потеряться и сами стороны должны договариваться о потерянных частях. Это такая вариация TCP поверх UDP, которая позволяет решить те проблемы с медленной загрузкой, что не могут решить алгоритмы операционной системы. QUIC лёг в основу нового протокола HTTP/3, главное отличает которого в необходимости использовать UDP протокол, а не TCP, как было раньше.
Четвёртая проблема — а куда мне, собственно, подключаться?
Теперь у браузера вопрос: а куда ему, собственно, нужно подключаться? Обычный алгоритм становится сложным:
- спроси DNS куда тебе;
- IP адрес знаешь, теперь попробуй подключиться по HTTP;
- по HTTP сказали, что нужно перейти на HTTPS версию сайта;
- HTTPS версия сайта сказала, что у них есть возможность подключиться через QUIC;
- круто, теперь все запросы делаем через QUIC.
Вам не кажется, что схема слишком сложная? На каждый этап уходит довольно много времени, особенно если у вас не очень быстрое соединение.
Как будем решать наш ворох проблем?
Всё ускорить. Для этого в DNS появился новый тип записей HTTPS. Они просто указывают браузеру куда нужно пойти в первую очередь. Любой современный браузер может просто сначала запросить запись для нужного домена, узнать о том, что этот домен работает с HTTPS протоколом. Узнать о том, какие конкретно протоколы он поддерживает: HTTP/2 или HTTP/3. Более того, он может сразу узнать, на какие IP адреса ему нужно стучаться, чтобы получить содержимое сайта. Даже если ему не сказали, он также, как раньше, запросит A и AAAA записи и пойдёт туда, уже владея всей информацией о том, куда ему следует обратиться.
Для чего моя утилита
Как вы понимаете, сам алгоритм этого выбора довольно сложный. Я пробовал использовать разные сервисы в интернете. Некоторые работали, некоторые нет. Но, самая главная проблема — они напрочь игнорировали то, что клиенты могут подключаться как по IPv4, так и по IPv6. Эта утилита реализует все мои идеи по тестированию.
Возможно, кто-то скажет, что зачем тебе маяться, просто используй только IPv4 и максимум только HTTP/2. Да, вариант, конечно, рабочий. Но я хочу, чтобы мой сайт использовал все возможные современные технологии. Эта утилита позволяет быстро оценить на сколько всё правильно настроено и на что нужно обратить внимание.
Ложечка дёгтя
Я не на столько крутой кодер, чтобы всё это реализовать на Go. Более того, я больше программирую на PHP и TypeScript. Но меня не могла заинтересовать идея реализовать мой сервис в виде утилиты через ИИ. Я пытался объяснить, что я хочу ИИ в течении нескольких часов. В результате он смастерил утилиту, которая, вроде бы работает.
А зачем всё это?
Эта заметка о том, что я так и не нашёл нормального способа быстро проверить всё то, что я рассказал в это заметке. Даже ИИ отказывались дать мне готовое решение. Поэтому я просто взял и с помощью ИИ сделал то, что мне было нужно. Я надеюсь, найдутся, те, кому это тоже нужно. И найдутся те, кто или перепишут то, что написал ИИ или помогут в улучшении этого кода. Я не специалист в Go, но код довольно понятный.
Кого заинтересовало, вот код проекта на Github.
Обратите внимание, что заметки могут обновляться со временем. Информация об изменениях доступна в репозитории на github. Там же вы можете оставить в Issue ваши замечания по данной заметке.
Если данная заметка оказалась вам полезной, можете поблагодарить автора финансово.