Что делать – Telegram
Что делать
102 subscribers
209 photos
3 videos
4 files
130 links
Не смешно
Download Telegram
Forwarded from Kir
Ну нихуя себе, спасибо блять

Надо будет сделать это говно более информативным, что ли
Некрасивое чиселко
Reminds me of Jeffrey Snover’s remark about problems vs dilemmas: problems can be solved, but dilemmas can only be managed.
Opennet at its best
🥰1
Ахуеть мне щас автотест тела запроса чуть систему не повесил
Ну и, между делом, убило нахуй голанд. Решило исходить из минимального
Таки починил. Даже advanced security layer ни разу не сработал
👻2
Ебать. Сел переписывать ебанутое и непонятное говно, которое я наворотил с кастомными листенерами в аппликейшене. Вкратце - нужен был хттпс, для хттпс нужно повесить тлс листенер на отдельный сокет. И вот я сделал так, чтобы можно было добавлять свои листенеры, и тогда дальше оно у себя там само разберется с тем, чтобы обрабатывать пакеты с них со всех.

Там такие костыли пошли, что просто ужас. Какие-то фабрики, хендлеры, хуй пойми что вообще. Я-то просто хотел сделать так, чтобы можно было указывать версию тлс в объекте запроса, который мы получили по безопасному каналу.

Заодно и узнал, что, оказывается, чтобы прерывать listener.Accept() по таймауту, не нужно городить горутину, канал и селект с time.After, а достаточно просто навесить на него самый обычный дедлайн.

Совершенная мелочь привела меня в результате к тому, что приходится перелопачивать половину приборной панели. А, кстати, там ещё 5 лет как Deprecated: SSLv3 is cryptographically broken, and is no longer supported by this package. See golang.org/issue/32716.
Собственно, по поводу хттпс.

Я посидел, покумекал, понял - мирного решения не будет.

Ну, то есть, вот у меня была такая тема, что я мог вешать индигу на несколько портов. Естественно, добавил на один уровень вглубь больше: можно прокидывать свои листенеры. Листенер просто возвращает имплементацию интерфейса net.Listener, и дальше уже индига сама с этим разбирается. Минус - нельзя прокидывать через запрос инфу о том, запрос прилетел по зашифрованному каналу, или нет, а это важно - иначе даже нельзя автоматический редирект на хттпс сделать, помимо как прибегать к HSTS правилам. А это, мягко говоря, не совсем то, чего я ожидаю от проекта.

Поэтому расширяем функционал - теперь можно прокидывать ещё и кастомные хендлеры вместе с листенерами. Под хендлерами подразумевается функция, которая будет отрабатывать каждый раз, как мы имеем новое подключение. Обычно, оно просто тыкает serve.HTTP1(). То есть - ручками зафурычивает хттп движок. Вот где-то на этом этапе я и кладу в объект запроса инфу о том, по защищённому ли каналу был получен запрос. В этом у меня ещё состоялся потенциал добавления хттп2, но о нём попозже.

А вот как это реализовано - ну просто страшная ебака - задействованы фабрики, хуябрики, и господь-упаси-какие-ещё-сущности-из-джавы. Встала проблема - на этом механизме у меня построен хттпс, в гибкости терять нельзя, а привести в порядок - хочется. Решение, кажется, вполне очевидное - вообще убрать из скоупа ответственности net.Listener. Пусть у нас будет просто хендлер - только теперь он ещё и за accept-loop отвечает (accept-loop'ом обычно называют цикл приёма новых подключений). То есть, он у нас теперь суперсолдат - подключения прими, хттп ядро ткни, так ещё и следи за тем, когда тебе скажут остановиться (через *atomic.Bool, кстати; нужно для graceful shutdown). Становится хорошо: код становится проще, избавляемся от довольно ёмких сущностей, оставляя лишь супервизор, который будет следить за тем, чтобы если ошибка произошла в одном хендлере - остановить все остальные. Теперь можно написать хендлер чисто для tcp, а в net.TCPListener есть возможность устанавливать таймаут на accept - это очень хорошо, раньше я оперировал с net.Listener, и должен был проверять низлежащую реализацию на наличие такого метода, что не есть очень приятно. А здесь спокойненько себе. Да и с тлс попроще стало - tls.Listener() просто оборачивает низлежащий листенер. Спокойно могу проинициализировать самостоятельно net.TCPListener для него, и повторить фокус с обычным tcp хендлером. Одним словом - хорошо.

Ниже продолжение
Что делать
Собственно, по поводу хттпс. Я посидел, покумекал, понял - мирного решения не будет. Ну, то есть, вот у меня была такая тема, что я мог вешать индигу на несколько портов. Естественно, добавил на один уровень вглубь больше: можно прокидывать свои листенеры.…
Но это лишь затравка (уж простите, нелюбители долгобукв). Сам сок происходит в методе App.AutoHTTPS(), который инициализирует tls листенер, в который прокидывает сертификаты автоматически. Проверяет, вешают автохттпс на домен ли, чтобы сунуть автосерт, а вот если вешают на ip адрес - ну, с летсэнкриптом (дефолтным провайдером у автосерта) сертификаты не выпишешь. Нет домена - нет сертификата. Вроде логично. На IP адреса я самостоятельно серты выписываю. Спойлер - идея плохая, для этого есть mkcert, который юзает локальный CA, чтобы браузеры меньше на говно исходили.

Ну и вот это - есть костыль. Я, например, намеренно упустил возможность того, что туда сунут ипв6, потому что имплементировать банально лень. Да и я без понятия, как оно себя поведёт, если сунуть туда чужой домен. Скорее всего, просто зафейлится tls.NewListener(), и тогда, если немного подождать, завершится и tcp листенер, после чего работа будет завершена. Но это лишь предположение. Проблема лишь в том, что самым выгодным решением будет, убрать нахер все те проверки "а домен ли это" (задача не так проста, как кажется на первый взгляд) и просто пытаться выписать с ACME себе сертификаты на переданный адрес. Не получится - значит, берём mkcert. Собственно, так я сделать и хочу - возможно даже, заменив по пути autocert на lego. Но там блоата многовато (автосерту почтение - всё в одну кнопку делается), придётся для начала говно разгребсти ещё. Но выглядит поинтереснее, честно говоря. За киллерфичу, конечно, хотелось бы выдать, да только кому нынче хттпс в вебфреймворке нужен. Каждый первый дебил дальше нжинкса его и не нюхал. Жаль.
Что делать
Но это лишь затравка (уж простите, нелюбители долгобукв). Сам сок происходит в методе App.AutoHTTPS(), который инициализирует tls листенер, в который прокидывает сертификаты автоматически. Проверяет, вешают автохттпс на домен ли, чтобы сунуть автосерт, а вот…
Но меня сейчас интересует другое. Серты с летсэнкрипта выписываются на 90 дней. То есть, каждые полтора месяца нужно их обновлять. Тут есть 2.5 варианта, как мне это делать:
1) DNS челленджи. Это когда в TXT поле кладёшь специально составленную строку, которая включает в себя токен от летсэнкрипта. Таким образом, сервис может быть уверен, что мы правда владеем доменом.
2) http и alpn челленджи. По сути, оба монофаллические, просто alpn через tls идёт. С http суть проста - открываешь на вебсервере ресурс /.well-known/acme-challenge/<token>, где token - как раз таки тот токен, который тебе летсэнкрипт и даст. За этим ресурсом должен лежать файл, в котором будет содержаться инфа по регистрации, и сам токен.

Собственно, я люблю циферки. Я на них дрочу, неистово, с неподдельным возбуждением. И мне становится очень грустно, перезагружать вебприложение каждые полтора месяца, чтобы обновлять сертификаты, тем самым теряя месячные аптаймы. Чисто технически, можно совершенно без проблем обновлять их на ходу - на момент обновления, просто делаем доступным такой ресурс на сервере, и кладём туда нужные данные. Получаем сертификаты - перезагружаем тлс листенер (да, клиентам придётся испытать тряску, но разрыв подключения на одну секунду раз в полтора месяца не смертелен; кому смертелен - тот будет использовать днс челленджи). Вуаля! Теперь индига может спокойно работать годами безостановочно. Один лишь недостаток - мне тогда придётся половину ACME самостоятельно имплементировать, чтобы это всё себе интегрировать. И хуже всего как раз таки с днс челленджами тогда придется - но, думается мне, здесь уж можно будет оставить ответственность на пользователе. А вынести метод "App.RenewCertificate()` мне всё равно придется, если я действительно буду это делать. И тогда уж точно можно будет киллерфичей назвать - пускай это и заботы реверс-прокси, зато можно будет теперь индигу саму как реверс-прокси ставить:)

Тогда уж надо будет столько всего интересного добавлять, дабы оно всё работало сносно и удобно. Но это уже тема совершенно иных лонгридов...
Forwarded from Павλо
bro writing a text for school
Forwarded from Павλо
This media is not supported in your browser
VIEW IN TELEGRAM
Bro writing about the most unnecessary feature of his pet-project with 46 likes:
🔥1💩1
Та ебать
Вот у меня сущность приложения (indigo.App) довольно тупая, и принимает роутер только когда жмакают app.Serve(). Поэтому, на сколько портов индигу не вешай, роутер будет один и тот же использоваться. Из-за этого и появился virtual.Router, который берёт запрос, и перенаправляет его в соответствующий роутер. Но мне вот какая мысль пришла: это ведь можно и более элегантно реализовать!

Вот я навешиваю аппу на разные порты через App.Bind(addr). Я могу сюда же роутер и прокидывать! Всё равно на каждом порту свой листенер (каждый в своей горутине), тогда ещё и косты на виртуальный роутинг сводятся к нулю (сейчас там перебор массива на каждый запрос, в надежде, что доменов будет немного - если меньше 7, тогда норм). Но и прокидывать в прям каждый App.Bind() роутер отдельно не хочется (например, аргумент пришлось бы дублировать в ситуациях, когда я хочу навесить аппу на хттп и хттпс). Есть вариант - если в бинде не указан роутер, будет использован роутер, указанный в предыдущем бинде. Либо дефолтный (который будет передаваться так, как передается и сейчас - через App.Serve(r)). Сохраняется обратная совместимость, но общий Developer Experience ухудшается - какая-то магия, везде вариадики.

Но, сука, фича-то сладкая, так и манит гадина. Я сейчас и так тот единственный переданный роутер в аппу передаю каждому листенеру по отдельности, а листенер у меня - замыкание, поэтому, возможно, можно будет добавить какую-нибудь заглушку а-ля App.Bind(":8081", Virtual(TCP, r2)), где r2 - это роутер для какого-нибудь другого домена от переданного в последующий App.Serve(r). Не без дизайнерских проблем, но и с TLS тоже зафурыкает.

Но меня всё равно не покидает чувство, словно это можно разрешить более элегантным способом.
🌭3
Что делать
Вот у меня сущность приложения (indigo.App) довольно тупая, и принимает роутер только когда жмакают app.Serve(). Поэтому, на сколько портов индигу не вешай, роутер будет один и тот же использоваться. Из-за этого и появился virtual.Router, который берёт запрос…
За хотдоги спасибо, но у меня тут забавная ситуация. Я начал тыкать напрямую net.ListenTCP, чтобы иметь не-виртуальный метод SetDeadline() на листенере. Нюанс в том, что конструктор принимает *net.TCPAddr, который сначала надо ещё получить. Получаешь через net.ResolveTCPAddr(). А в него нельзя засунуть 0.0.0.0 - заглушка, которая слушает на всех интерфейсах - в отличии от net.Listen. Там, почему-то, всё работает нормально. И я всё никак вдуплить не могу, где именно здесь происходит эта магия