Что делать
Интересно, а что же они так из версии в версию меняют, что Монтерей уже даже для brew устаревшим считается?
Сука он мне до сих пор всё говно обновляет
Reminds me of Jeffrey Snover’s remark about problems vs dilemmas: problems can be solved, but dilemmas can only be managed.
Ну и, между делом, убило нахуй голанд. Решило исходить из минимального
Ебать. Сел переписывать ебанутое и непонятное говно, которое я наворотил с кастомными листенерами в аппликейшене. Вкратце - нужен был хттпс, для хттпс нужно повесить тлс листенер на отдельный сокет. И вот я сделал так, чтобы можно было добавлять свои листенеры, и тогда дальше оно у себя там само разберется с тем, чтобы обрабатывать пакеты с них со всех.
Там такие костыли пошли, что просто ужас. Какие-то фабрики, хендлеры, хуй пойми что вообще. Я-то просто хотел сделать так, чтобы можно было указывать версию тлс в объекте запроса, который мы получили по безопасному каналу.
Заодно и узнал, что, оказывается, чтобы прерывать listener.Accept() по таймауту, не нужно городить горутину, канал и селект с time.After, а достаточно просто навесить на него самый обычный дедлайн.
Совершенная мелочь привела меня в результате к тому, что приходится перелопачивать половину приборной панели. А, кстати, там ещё 5 лет как Deprecated: SSLv3 is cryptographically broken, and is no longer supported by this package. See golang.org/issue/32716.
Там такие костыли пошли, что просто ужас. Какие-то фабрики, хендлеры, хуй пойми что вообще. Я-то просто хотел сделать так, чтобы можно было указывать версию тлс в объекте запроса, который мы получили по безопасному каналу.
Заодно и узнал, что, оказывается, чтобы прерывать listener.Accept() по таймауту, не нужно городить горутину, канал и селект с time.After, а достаточно просто навесить на него самый обычный дедлайн.
Совершенная мелочь привела меня в результате к тому, что приходится перелопачивать половину приборной панели. А, кстати, там ещё 5 лет как Deprecated: SSLv3 is cryptographically broken, and is no longer supported by this package. See golang.org/issue/32716.
GitHub
crypto/tls: remove SSLv3 support · Issue #32716 · golang/go
SSLv3 has been irreparably broken since the POODLE attack 5 years ago. RFC 7568 (f.k.a. draft-ietf-tls-sslv3-diediedie) prohibits its use in no uncertain terms, and proceeds to list everything that...
Собственно, по поводу хттпс.
Я посидел, покумекал, понял - мирного решения не будет.
Ну, то есть, вот у меня была такая тема, что я мог вешать индигу на несколько портов. Естественно, добавил на один уровень вглубь больше: можно прокидывать свои листенеры. Листенер просто возвращает имплементацию интерфейса 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 хендлером. Одним словом - хорошо.
Ниже продолжение
Я посидел, покумекал, понял - мирного решения не будет.
Ну, то есть, вот у меня была такая тема, что я мог вешать индигу на несколько портов. Естественно, добавил на один уровень вглубь больше: можно прокидывать свои листенеры. Листенер просто возвращает имплементацию интерфейса 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. Но там блоата многовато (автосерту почтение - всё в одну кнопку делается), придётся для начала говно разгребсти ещё. Но выглядит поинтереснее, честно говоря. За киллерфичу, конечно, хотелось бы выдать, да только кому нынче хттпс в вебфреймворке нужен. Каждый первый дебил дальше нжинкса его и не нюхал. Жаль.
Ну и вот это - есть костыль. Я, например, намеренно упустил возможность того, что туда сунут ипв6, потому что имплементировать банально лень. Да и я без понятия, как оно себя поведёт, если сунуть туда чужой домен. Скорее всего, просто зафейлится tls.NewListener(), и тогда, если немного подождать, завершится и tcp листенер, после чего работа будет завершена. Но это лишь предположение. Проблема лишь в том, что самым выгодным решением будет, убрать нахер все те проверки "а домен ли это" (задача не так проста, как кажется на первый взгляд) и просто пытаться выписать с ACME себе сертификаты на переданный адрес. Не получится - значит, берём mkcert. Собственно, так я сделать и хочу - возможно даже, заменив по пути autocert на lego. Но там блоата многовато (автосерту почтение - всё в одну кнопку делается), придётся для начала говно разгребсти ещё. Но выглядит поинтереснее, честно говоря. За киллерфичу, конечно, хотелось бы выдать, да только кому нынче хттпс в вебфреймворке нужен. Каждый первый дебил дальше нжинкса его и не нюхал. Жаль.
Что делать
Но это лишь затравка (уж простите, нелюбители долгобукв). Сам сок происходит в методе App.AutoHTTPS(), который инициализирует tls листенер, в который прокидывает сертификаты автоматически. Проверяет, вешают автохттпс на домен ли, чтобы сунуть автосерт, а вот…
Но меня сейчас интересует другое. Серты с летсэнкрипта выписываются на 90 дней. То есть, каждые полтора месяца нужно их обновлять. Тут есть 2.5 варианта, как мне это делать:
1) DNS челленджи. Это когда в TXT поле кладёшь специально составленную строку, которая включает в себя токен от летсэнкрипта. Таким образом, сервис может быть уверен, что мы правда владеем доменом.
2) http и alpn челленджи. По сути, оба монофаллические, просто alpn через tls идёт. С http суть проста - открываешь на вебсервере ресурс
Собственно, я люблю циферки. Я на них дрочу, неистово, с неподдельным возбуждением. И мне становится очень грустно, перезагружать вебприложение каждые полтора месяца, чтобы обновлять сертификаты, тем самым теряя месячные аптаймы. Чисто технически, можно совершенно без проблем обновлять их на ходу - на момент обновления, просто делаем доступным такой ресурс на сервере, и кладём туда нужные данные. Получаем сертификаты - перезагружаем тлс листенер (да, клиентам придётся испытать тряску, но разрыв подключения на одну секунду раз в полтора месяца не смертелен; кому смертелен - тот будет использовать днс челленджи). Вуаля! Теперь индига может спокойно работать годами безостановочно. Один лишь недостаток - мне тогда придётся половину ACME самостоятельно имплементировать, чтобы это всё себе интегрировать. И хуже всего как раз таки с днс челленджами тогда придется - но, думается мне, здесь уж можно будет оставить ответственность на пользователе. А вынести метод "App.RenewCertificate()` мне всё равно придется, если я действительно буду это делать. И тогда уж точно можно будет киллерфичей назвать - пускай это и заботы реверс-прокси, зато можно будет теперь индигу саму как реверс-прокси ставить:)
Тогда уж надо будет столько всего интересного добавлять, дабы оно всё работало сносно и удобно. Но это уже тема совершенно иных лонгридов...
1) DNS челленджи. Это когда в TXT поле кладёшь специально составленную строку, которая включает в себя токен от летсэнкрипта. Таким образом, сервис может быть уверен, что мы правда владеем доменом.
2) http и alpn челленджи. По сути, оба монофаллические, просто alpn через tls идёт. С http суть проста - открываешь на вебсервере ресурс
/.well-known/acme-challenge/<token>, где token - как раз таки тот токен, который тебе летсэнкрипт и даст. За этим ресурсом должен лежать файл, в котором будет содержаться инфа по регистрации, и сам токен. Собственно, я люблю циферки. Я на них дрочу, неистово, с неподдельным возбуждением. И мне становится очень грустно, перезагружать вебприложение каждые полтора месяца, чтобы обновлять сертификаты, тем самым теряя месячные аптаймы. Чисто технически, можно совершенно без проблем обновлять их на ходу - на момент обновления, просто делаем доступным такой ресурс на сервере, и кладём туда нужные данные. Получаем сертификаты - перезагружаем тлс листенер (да, клиентам придётся испытать тряску, но разрыв подключения на одну секунду раз в полтора месяца не смертелен; кому смертелен - тот будет использовать днс челленджи). Вуаля! Теперь индига может спокойно работать годами безостановочно. Один лишь недостаток - мне тогда придётся половину ACME самостоятельно имплементировать, чтобы это всё себе интегрировать. И хуже всего как раз таки с днс челленджами тогда придется - но, думается мне, здесь уж можно будет оставить ответственность на пользователе. А вынести метод "App.RenewCertificate()` мне всё равно придется, если я действительно буду это делать. И тогда уж точно можно будет киллерфичей назвать - пускай это и заботы реверс-прокси, зато можно будет теперь индигу саму как реверс-прокси ставить:)
Тогда уж надо будет столько всего интересного добавлять, дабы оно всё работало сносно и удобно. Но это уже тема совершенно иных лонгридов...