Мысли программиста / TeaCoder
СтатистикаСвязаться со мной: https://t.me/Vados_torpeda Мой ютуб канал: https://youtube.com/@TeaCoder52 Мой Github: https://github.com/TeaCoder52
- Последний пост
- 26 июл.
- Последнее чтение
- 13 авг.
- Постов за неделю
- 0
- Всего постов
- 20
- Тип
- открытый
- Язык
- русский
- В каталоге с
- 13 авг.
- 1/24сутки в ленте
- 1 179
- 1/48двое суток
- 1 351
- 1/72трое суток
- 1 457
Оценка по просмотрам недавних постов: пост набирает почти всё за первые сутки.
Посты
видео или голосовое, без подписи
видео или голосовое, без подписи
Приветствую всех! Сегодня у меня день рождения! 🎉 Мне исполняется 16 лет, и я решил приобрести себе вот такой вот аппарат. Спасибо всем, кто со мной и поддерживает то, что я делаю! Дальше - больше 🚀
✍️ 10 правил работы с логами 1. Логируйте бизнес-события, а не трассировку кода Логи вида «функция отработала» никому не помогают. Гораздо полезнее фиксировать результат: «создан заказ», «оплата не прошла», «внешний сервис не ответил». 2. Исключите персональные и конфиденциальные данные Пароли, токены и платежные реквизиты не должны попадать в системы агрегации (Sentry, Datadog), к которым есть доступ у широкого круга сотрудников. 3. Соблюдайте семантику уровней логирования Используйте debug для локальной отладки. На уровне info фиксируйте ключевые бизнес-события. Уровень warn применяйте для отклонений от нормы, не остановивших работу, а error - для сбоев, требующих срочной реакции. 4. Используйте только структурированный формат (JSON) Склеивание строк делает невозможной автоматическую фильтрацию. Передача данных объектом позволяет системам аналитики (допустим, Grafana) индексировать поля и находить корреляции. 5. Включайте сквозной контекст (Trace/Request ID) Каждая запись должна содержать идентификаторы пользователя, запроса или операции. Это единственная возможность отследить цепочку событий при сбое. 6. Агрегируйте логи при пакетной обработке Запись каждого элемента в циклах на тысячи итераций переполняет диски и израсходует лимиты сервисов мониторинга. Логируйте итоговый результат пакета: количество обработанных записей и ошибки. 7. Фиксируйте ошибки в месте их возникновения Логирование на верхнем уровне (в глобальных перехватчиках) теряет локальный контекст операции. Перехватывайте и логируйте исключение там, где известны детали выполнения. 8. Удаляйте отладочные логи Временные записи, добавленные в процессе разработки, засоряют продакшен. Они должны вычищаться на этапе самопроверки и код-ревью. 9. Избегайте дублирования одной ошибки Не логируйте одно исключение на каждом слое архитектуры (сервис —> контроллер —> глобальный хендлер). Одно событие должно порождать ровно одну запись в логе. 10. Единый стандарт логов на уровне всей системы Все сервисы и модули проекта должны использовать единую схему (обязательные поля timestamp, level, service, context). Иначе ни одна система агрегации логов не сможет их нормально распарсить и связать в единую картину. #ПолезностиДляКодера
Всем привет! 👋 Недавно я решил провести аудит защищенности и анализ архитектуры в известной open-source платформе Dokploy. Это классный self-hosted инструмент для деплоя, и с недавнего времени в нем есть платные Enterprise-фичи. Доступ к ним закрывается проверкой лицензионного ключа. Мне стало интересно посмотреть, как разработчики спроектировали этот валидатор. В итоге мне удалось полностью обойти проверку и активировать платный функционал исключительно средствами сетевого уровня. ⚡️ В чем фундаментальный провал архитектуры Проблема кроется в слепом доверии бэкенда к внешнему API. В обычном веб-приложении схема с отправкой ключа на внешний сервис выглядит нормально. Но в self-hosted среде пользователь полностью контролирует железо, Docker-сеть и локальный DNS. Логика валидации в Dokploy завязана на пару уязвимых мест: - Бэкенд на Node.js отправляет POST-запрос на licenses-api.dokploy.com (эндпоинты /licenses/activate и /licenses/validate). - Сервер ждет в ответ самый обычный JSON вида {"valid": true}. - Локальное состояние лицензии дополнительно дублируется флагами в PostgreSQL в таблице user (колонки enableEnterpriseFeatures и isValidEnterpriseLicense). ☠️ Как сработала концепция обхода (Network Spoofing + MitM) Вся защита рухнула за счет комбинации подмены сетевого трафика и ослабления TLS-стека: - Bypass TLS Validation: В Swarm-сервис Dokploy прокидывается переменная окружения NODE_TLS_REJECT_UNAUTHORIZED=0. Это заставляет Node.js проглатывать ошибки вадидации кастомного SSL-сертификата. - Mock Infrastructure: В той же Docker-сети поднимается контейнер Nginx с SSL-сертификатом, сгенерированным через OpenSSL под домен licenses-api.dokploy.com. Nginx принимает HTTPS-трафик на 443 порту и перенаправляет его на Python-контроллер, который на любые POST-запросы возвращает HTTP status 200 и payload {"valid": true}. - DNS Poisoning внутри контейнера: В файле /etc/hosts внутри целевого контейнера Dokploy домен licenses-api.dokploy.com перенаправляется на локальный IP-адрес нашего Nginx-прокси внутри Docker-сети. Как только бэкенд совершает очередной запрос к "своему" API, он получает фейковый ответ, принимает его за чистую монету и разблокирует платные фичи. 💡 Как строить такую защиту правильно? Для коммерческого Self-Hosted софта простой fetch() и незащищенный JSON не работают. Ответ сервера лицензий должен быть токеном (например, JWT), подписанным приватным ключом компании. Бэкенд валидирует этот токен зашитым публичным ключом. Без приватного ключа сгенерировать подпись на фейковом сервере просто не получится. Вдобавок внедряйте Certificate Pinning. Если приложение ходит во внешний API, валидируйте отпечаток SSL-сертификата напрямую, а не полагайтесь на системный TLS-стек, который легко глушится переменными окружения. Разбор проведен исключительно в образовательных целях. Всем удачного кодинга и грамотного проектирования! 🚀
Недавно был представлен GitFut. Это бесплатный сервис для генерации карточек футбольной статистики на основе данных из профиля на гитхабе. Кидайте свои результаты в комментариях к посту 👇
видео или голосовое, без подписи
видео или голосовое, без подписи
видео или голосовое, без подписи
видео или голосовое, без подписи
🚀 Полный курс по Next.js App Router! Рад представить вам новый курс по Next.js, в котором мы с нуля разбираем внутреннюю кухню фреймворка. Буду рад вашей поддержке - ставьте лайки и пишите комментарии, это очень поможет продвижению курса и мотивирует делать еще больше крутых проектов! 📱 Приятного просмотра: https://tcdr.cc/nextjs-youtube 📱 Исходники: https://tcdr.cc/nextjs-course
Приветствую! Спустя полтора месяца отсутствия в медиа возвращаюсь с хорошими новостями. Завтра выходит курс по Next.js. И немного о делах насущных: я сдал три предмета на ОГЭ, остался последний рывок на днях
Как похоронить проект под тяжестью собственных амбиций. Всем привет! Давно крутится одна мысль: мы очень любим усложнять себе жизнь и называть это профессионализмом. Я не раз ловил себя на этом - вроде стараешься сделать "как правильно", а в итоге просто делаешь слишком сложно. Речь, конечно, про оверинжиниринг. Самый опасный момент - это чистый репозиторий. Нет ни дедлайнов, ни легаси, ни ограничений. Кажется, что вот сейчас-то ты наконец сделаешь идеальную систему. И именно в этот момент всё обычно идёт не туда. Ты хотел просто проверить идею, но вместо этого начинаешь думать наперёд: А вдруг завтра придет миллион пользователей? Нам нужен нест, причем сразу с микросервисами. Так, здесь будет сервис уведомлений, тут - аутентификация через отдельный инстанс, а общаться они будут через RabbitMQ. И обязательно gRPC, потому что JSON - это слишком медленно для нашего (несуществующего) трафика И вот ты уже не продукт делаешь, а строишь архитектуру ради архитектуры. Самое коварное - это ощущается как полезная работа. Ты не залипаешь в прокрастинацию, ты инженеришь. Только вот это часто способ не сталкиваться с главным вопросом: а нужен ли вообще кому-то твой продукт. Особенно часто этот капкан захлопывается, когда ты единственный разработчик на проекте или полностью отвечаешь за всё направление. В этот момент тебя некому остановить. Нет тимлида, который даст по рукам за лишнюю абстракцию, и нет коллег, которые спросят: "А зачем нам тут gRPC, если у нас десять пользователей?". В итоге вместо проверки гипотез начинаются сложные решения: распределённые базы, продуманные пайплайны, куча интерфейсов. Большая часть времени уходит на обвязку, а не на саму ценность. Во многом это привычки из больших компаний, где такие подходы действительно решают проблемы масштаба и коммуникации сотен людей. Но когда ты один или у тебя маленький проект - это превращается в лишнюю сложность и постоянную боль. В какой-то момент ловишь себя на том, что пишешь "фреймворк внутри проекта", продумываешь всё на годы вперёд и тратишь кучу энергии на эстетически правильный код, хотя задача была куда проще - сделать что-то, что реально работает и кому-то нужно. По сути, оверинжиниринг - это такая дорогая форма безделья. Мы решаем задачи будущего, чтобы не сталкиваться с проблемами настоящего. Но будущее наступает только для тех продуктов, которые выжили в настоящем. А выживают обычно самые простые и адаптивные решения.
Топ 8 паттернов и практик разработки 1. KISS - Keep It Simple, Stupid (Делай проще, тупица) Главный принцип. Пишите код так, чтобы его понял даже стажер после бессонной ночи. Если для понимания структуры папок или логики кода требуются сложные объяснения - вы перемудрили. 2. DRY - Don't Repeat Yourself (Не повторяйся) Не дублируйте логику. Но помните: иногда лучше скопипастить код дважды, чем создать универсальный мега-компонент, который потом страшно трогать. 3. POLA - Principle of Least Astonishment (Принцип наименьшего изумления) Код должен работать именно так, как ожидает другой разработчик. Не называйте функцию getData, если она в процессе еще и чистит базу или отправляет письма. 4. SSoT - Single Source of Truth (Единый источник истины) У каждой порции данных должно быть только одно место хранения. Избегайте дублирования состояний. Если данные можно вычислить на основе других данных - вычисляйте, а не храните их отдельно. 5. YAGNI - You Ain't Gonna Need It (Вам это не понадобится) Не пишите код на вырост. Не стоит внедрять сложную систему микросервисов или поддержку нескольких типов баз данных на будущее, если сейчас достаточно одного монолита. Это экономит ресурсы и не засоряет архитектуру лишним весом. 6. SoC - Separation of Concerns (Разделение ответственности) Каждый модуль должен отвечать за свой аспект системы. Логика обработки платежей не должна пересекаться с логикой формирования PDF-отчетов. Когда задачи разделены, вы можете менять одну часть приложения, не боясь по цепочке сломать совершенно другие модули. 7. Boy Scout Rule (Правило бойскаута) Оставляйте код чище, чем он был до вашего прихода. Если в процессе работы вы заметили неудачное название переменной или лишний мусор в файле - исправьте это. 8. Dependency Inversion (Инверсия зависимостей) Код высокого уровня не должен зависеть от конкретных инструментов. Вашей бизнес-логике должно быть всё равно, какая именно библиотека отправляет SMS или пишет логи. Конечно, эти правила могут пересекаться или даже спорить друг с другом. Например, слишком сложная архитектура ради гибкости может убить простоту (KISS), а фанатичный повтор кода (DRY) может создать лишние абстракции (YAGNI). Главное - не делать из них культ. Используйте эти принципы как подсказки, но всегда доверяйте здравому смыслу. Если паттерн только мешает и усложняет жизнь здесь и сейчас - скорее всего, он в данный момент лишний. #ПолезностиДляКодера
Как получить доступ ко всем курсам на сайте ItProger за несколько секунд? В целом, всё до смешного просто: нужно всего лишь создать куку с названием log и значением gosha_user%40itproger.com и... всё. После этого у вас открывается доступ абсолютно ко всем интенсивам (их там 10 штук), каждый из которых стоит примерно 200 баксов. Ну и к обычным платным курсам доступ тоже появляется автоматически. Там схема огонь: авторизация работает на уровне Google - вы вводите почту и пароль, а если они верные, система просто берет вашу почту и кладет её в куку. Гениально! Данный пост опубликован исключительно в ознакомительных и образовательных целях. UPD: Оперативно! Не прошло и 15 минут, как лавочку прикрыли.
Приветствую! Давненько сюда не писал... Дела обстоят хорошо, я почти подготовил проект для курса по Next.js. Сами съёмке курса сейчас в активной фазе, очень стараюсь сделать его как можно быстрее. Сегодня весь день занимался своим сайтом и успешно завершил технические работы. Перевел проект на другой сервер и дополнительно запустил страницу мониторинга status.teacoder.ru. Также восстановил работу почтового сервера и сменил провайдера, теперь письма снова будут доставляться корректно.
Всем привет! Я подготовил тут набросок текста для резюме. Завтра иду на собес на позицию HTML-верстальщика (стажер). Обещают 30 000 рублей до вычета налогов. Гляньте опыт, не слишком ли мало расписал? Норм шансы, что возьмут? Мой фундамент базируется на экспертном владении Rust, C++, Zig, Go, TypeScript, Elixir, Haskell, OCaml, F#, Clojure, Erlang, Python, Mojo, Carbon и Swift, включая глубокую работу с фреймворками Nest.js, Actix-web, Axum, Gin, Fiber, React, SolidJS, SvelteKit, Qwik, Phoenix и Warp при проектировании распределенных систем с экстремальными нагрузками и реализацией алгоритмов консенсуса Raft, Paxos и Zab. Я обладаю исчерпывающими знаниями в архитектуре баз данных, реализуя схемы шардирования, партиционирования и мульти-мастер репликации в PostgreSQL, MySQL, ScyllaDB, ClickHouse, TiDB, SurrealDB, CockroachDB, RocksDB, MongoDB, Cassandra, InfluxDB, VictoriaMetrics и FoundationDB, а также оптимизируя векторные хранилища Milvus, Faiss, Pinecone и Weaviate для задач генеративного ИИ. В сфере системного инжиниринга я занимаюсь низкоуровневой оптимизацией рантаймов V8 и LLVM, написанием кастомных аллокаторов памяти, реверс-инжинирингом прошивок в IDA Pro, Ghidra и Binary Ninja на уровне анализа ядра, эксплуатации уязвимостей нулевого дня, фаззинга и символьного исполнения кода. Моя экспертиза в DevOps охватывает управление парками Kubernetes-кластеров через GitOps, настройку сервис-мешей Istio и Linkerd, проектирование отказоустойчивых сетей через BGP, OSPF и Anycast, а также разработку eBPF-программ для фильтрации трафика на уровне ядра XDP. В свободное время я ориентируюсь в глобальных исторических процессах XVIII-XX веков, включая детальный разбор геополитических стратегий Наполеона, дипломатических маневров Талейрана, Меттерниха и Горчакова, итогов Венского конгресса, реформ Бисмарка, Витте, Столыпина и Ли Куан Ю, а также анализ Большой игры и геополитики Маккиндера и Хаусхофера. В области теологии и метафизики я оперирую догматикой православия, католицизма и протестантизма, структурой буддизма махаяны и дзен, эзотерикой суфизма, адвайта-ведантой Шанкары в индуизме и каббалистическими моделями иудаизма. Я также отслеживаю и анализирую механизмы влияния банковских династий Ротшильдов, Рокфеллеров, Морганов, Варбургов и Барухов, механизмы эмиссии Федеральной резервной системы, архитектуру Eurodollar системы, принципы Бреттон-Вудского и Ялтинско-Потсдамского соглашений, а также деятельность Бильдербергского клуба, Римского клуба, Трехсторонней комиссии, Совета по международным отношениям и корпорации BlackRock под управлением Ларри Финка. Параллельно владею искусством полифонии, контрапункта и сложной гармонии на уровне композиторов-классиков: от темперированного клавира Баха и симфонизма Бетховена и Малера до атональных экспериментов Шёнберга, спектрализма Гризе и минимализма Райха. Свободно ориентируюсь в партитурах Стравинского, Шостаковича и Вагнера, лейтмотивных системах и драматургии звуковых ландшафтов. В области естественных наук мои знания охватывают биологию на всех уровнях: от квантовой химии и механизмов синтеза АТФ до эпигенетической регуляции экспрессии генов через систему CRISPR/Cas9, нейрохимии синаптической пластичности и этологии. Математический аппарат дополнен пониманием квантовой механики, теории струн, астрофизики черных дыр, макроэкономических моделей австрийской школы и системного анализа сложных динамических структур. Дополняют этот список навыки профессионального 3D-моделирования в Blender, процедурной генерации миров, видеопроизводства в After Effects, киберспортивное доминирование в CS2 и DDNet на уровне мировых топов, а также стратегическое управление венчурными активами и разработка предиктивных моделей для прогнозирования рыночной волатильности. Вроде для стажерской позиции пойдет, как думаете? Только за центрирование дивов переживаю, говорят там жестко спрашивают
видео или голосовое, без подписи
видео или голосовое, без подписи
🔑 Почему вашему проекту (и сотрудникам) нужна единая система аутентификации Когда проект обрастает инфраструктурой вроде Grafana, Gitlab или Sentry, управлять доступами вручную становится невозможно. Создавать и удалять учётки в каждом сервисе по отдельности долго и небезопасно. Про забытые доступы уволенных коллег обычно вспоминают слишком поздно, поэтому авторизацию пора выносить в отдельный слой. Разбирать тему будем на примере Pocket ID. Это легкий self-hosted Identity Provider для тех, кому не нужен монструозный Keycloak, но нужна надежная система одного окна для входа во все ресурсы. 🛡 Что такое Pocket ID и зачем он нам? Это ваш собственный Identity Provider. Вы поднимаете его в докере, заводите туда сотрудников и он становится единственным местом, которое проверяет кто есть кто. Одна из главных фишек Pocket ID в том, что он полностью отказывается от классических паролей в пользу ключей доступа (Passkeys). Это намного безопаснее и удобнее: вместо ввода букв и цифр используется биометрия или аппаратные ключи. ⚡️ Почему именно OIDC, а не старый добрый SAML? Чтобы ваши сервисы понимали Pocket ID, они должны общаться по определенному протоколу. Pocket ID работает на базе OIDC. Но в мире аутентификации есть два основных игрока: - SAML (Security Assertion Markup Language) - это история про большой энтерпрайз и банки. Он надежный, но его больно внедрять в современные веб-приложения. - OIDC (Open ID Connect) - это современный стандарт на базе JSON и JWT. Если вы настраивали вход через Google или Github, вы уже с ним работали. Он легкий, его поддерживают все современные библиотеки, и он из коробки умеет передавать конкретные данные сотрудника (роли, отдел, права) через Claims. ⛏ Как это работает на практике с сотрудниками: 1. Сотрудник заходит в любой внутренний сервис и нажимает "Войти". 2. Сервис перенаправляет его в Pocket ID. 3. Юзер подтверждает личность через Passkey, а далее Pocket ID выдает сервису подписанный JWT-токен. 4. Сервис проверяет подпись токена и на основе данных внутри выдает соответствующие права доступа. Самое важное здесь - безопасность при увольнении или ротации кадров. Вам не нужно заходить в админку каждого сервиса. Вы просто деактивируете одну учетку в Pocket ID и человек моментально теряет доступ ко всей инфраструктуре разом.🔓 В итоге мы получаем прозрачный контроль над доступами и избавляемся от зоопарка паролей. Приложения занимаются своей логикой, а безопасность вынесена в отдельный защищенный слой. 🔥 Хотите ещё больше полезных материалов? Жмите огонёк и следите за новыми постами!