<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>Denis Evsyukov</title><link>https://www.juev.org/</link><description>Recent content on Denis Evsyukov</description><generator>Hugo -- gohugo.io</generator><language>ru-RU</language><managingEditor>denis@evsyukov.org (Denis Evsyukov)</managingEditor><webMaster>denis@evsyukov.org (Denis Evsyukov)</webMaster><copyright>This work is licensed under a MIT License.</copyright><lastBuildDate>Thu, 24 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://www.juev.org/atom.xml" rel="self" type="application/rss+xml"/><xhtml:meta content="noindex" name="robots" xmlns:xhtml="http://www.w3.org/1999/xhtml"/><item><title>Как оставить свои AI-модели в VS Code без Copilot</title><link>https://www.juev.org/2026/09/24/copilot/</link><pubDate>Thu, 24 Sep 2026 16:47:53 +0300</pubDate><author>denis@evsyukov.org (Denis Evsyukov)</author><guid>https://www.juev.org/2026/09/24/copilot/</guid><description>&lt;p&gt;Я много лет пользуюсь VS Code и синхронизировал настройки через GitHub. Входишь в аккаунт на новой машине — возвращаются настройки и расширения. Но доступ к Copilot Pro у меня пропал, а сам Copilot продолжал предлагать автодополнение там, где я его не просил. При этом отказываться от AI в редакторе я не хотел: для работы с агентами мне нужны собственные модели, в том числе DeepSeek и Z.ai.&lt;/p&gt;
&lt;p&gt;В VS Code есть настройка &lt;code&gt;chat.disableAIFeatures&lt;/code&gt;, но она отключает и скрывает встроенные AI-функции целиком, включая чат. Мне же нужно было сохранить чат со своими моделями и перестать пользоваться сервисом Copilot.&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id="при-чём-здесь-синхронизация"&gt;&lt;a href="#%d0%bf%d1%80%d0%b8-%d1%87%d1%91%d0%bc-%d0%b7%d0%b4%d0%b5%d1%81%d1%8c-%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f" class="post_hash"&gt;При чём здесь синхронизация&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Для Settings Sync VS Code предлагает вход через GitHub или Microsoft. Я использовал GitHub, поэтому редактор уже имел доступ к моей учётной записи. Copilot тоже использует вход через GitHub. Это разные функции: смена аккаунта для синхронизации сама по себе не означает выход из GitHub во всём редакторе.&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Я вышел из GitHub в редакторе и перенёс синхронизацию на учётную запись Microsoft. Такой вариант сохраняет Settings Sync и позволяет работать в чате с моделями, добавленными через собственные ключи или совместимый endpoint. Для этого не нужен план Copilot.&lt;sup id="fnref:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id="как-я-переключил-синхронизацию"&gt;&lt;a href="#%d0%ba%d0%b0%d0%ba-%d1%8f-%d0%bf%d0%b5%d1%80%d0%b5%d0%ba%d0%bb%d1%8e%d1%87%d0%b8%d0%bb-%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8e" class="post_hash"&gt;Как я переключил синхронизацию&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Открыл меню &lt;code&gt;Accounts&lt;/code&gt; и полностью вышел из учётной записи GitHub через &lt;code&gt;Sign out&lt;/code&gt;. Это выход из GitHub в VS Code, а не только из Copilot; он затрагивает и другие расширения, использующие этот аккаунт.&lt;sup id="fnref1:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;Открыл Command Palette и выполнил &lt;code&gt;Settings Sync: Turn Off&lt;/code&gt;. Удалять синхронизированные данные из облака для смены аккаунта не требуется.&lt;sup id="fnref1:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;Перезапустил Extension Host командой &lt;code&gt;Developer: Restart Extension Host&lt;/code&gt;, затем окно командой &lt;code&gt;Developer: Reload Window&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Выбрал &lt;code&gt;Manage → Backup and Sync Settings...&lt;/code&gt;, указал, что синхронизировать, и вошёл через Microsoft в браузере.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;С первого раза синхронизация у меня выдала ошибку. Повторный запуск &lt;code&gt;Backup and Sync Settings...&lt;/code&gt; завершился успешно. Перезапуск Extension Host и окна — часть моих действий, а не обязательные шаги из документации VS Code: для смены аккаунта она предписывает выключить Settings Sync и включить его с другим аккаунтом.&lt;sup id="fnref2:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;При первом включении синхронизации с другой учётной записью VS Code объединяет локальные данные с данными в облаке. Если там уже есть настройки и редактор показывает конфликт, нужно выбрать нужную версию или сравнить обе; подтверждать замену вслепую не стоит.&lt;sup id="fnref3:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;После переключения Settings Sync работал через Microsoft, а GitHub в редакторе не был авторизован. Проверить это можно в меню &lt;code&gt;Accounts&lt;/code&gt;: если GitHub там всё ещё указан, нужно выйти из него отдельно. Одна только смена аккаунта Settings Sync не гарантирует выхода из GitHub, и Copilot может продолжить использовать этот вход.&lt;sup id="fnref2:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id="что-осталось-работать"&gt;&lt;a href="#%d1%87%d1%82%d0%be-%d0%be%d1%81%d1%82%d0%b0%d0%bb%d0%be%d1%81%d1%8c-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b0%d1%82%d1%8c" class="post_hash"&gt;Что осталось работать&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;После переключения мои модели доступны в чате VS Code, а предложения Copilot при наборе кода больше не появляются. Здесь есть ограничение: модели, добавленные через собственные ключи, работают в чате и связанных с ним задачах, но не заменяют встроенное автодополнение Copilot. Для inline suggestions по-прежнему требуется сервис GitHub Copilot.&lt;sup id="fnref1:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Таким образом, для моей задачи хватило разделить два входа: синхронизировать настройки через Microsoft и не держать GitHub авторизованным в VS Code. Если позже снова войти в GitHub ради другого расширения, стоит проверить, не вернулись ли предложения Copilot.&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;a href="https://code.visualstudio.com/docs/setup/copilot#_remove-ai-features-from-vs-code"&gt;Как отключить встроенные AI-функции VS Code&lt;/a&gt;
.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;&lt;a href="https://code.visualstudio.com/docs/configure/settings-sync"&gt;Settings Sync: включение, смена аккаунта и разрешение конфликтов&lt;/a&gt;
.&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href="#fnref1:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href="#fnref2:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href="#fnref3:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;&lt;a href="https://code.visualstudio.com/docs/setup/copilot"&gt;Вход в GitHub Copilot и выход из учётной записи&lt;/a&gt;
.&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href="#fnref1:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href="#fnref2:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;&lt;a href="https://code.visualstudio.com/docs/agent-customization/language-models"&gt;Добавление собственных AI-моделей и ограничения BYOK&lt;/a&gt;
.&amp;#160;&lt;a href="#fnref:4" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href="#fnref1:4" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;Читайте оригинал на странице: &lt;a href="https://www.juev.org/2026/09/24/copilot/" alt="Как оставить свои AI-модели в VS Code без Copilot"&gt;Как оставить свои AI-модели в VS Code без Copilot&lt;/a&gt; (Denis Evsyukov)&lt;/p&gt;</description></item><item><title>Ссылки #408</title><link>https://www.juev.org/2026/09/19/weblinks-408/</link><pubDate>Sat, 19 Sep 2026 09:22:03 +0300</pubDate><author>denis@evsyukov.org (Denis Evsyukov)</author><guid>https://www.juev.org/2026/09/19/weblinks-408/</guid><description>&lt;p&gt;За прошедшую неделю собрал 45 ссылок.&lt;/p&gt;
&lt;h2 id="-безопасность"&gt;&lt;a href="#-%d0%b1%d0%b5%d0%b7%d0%be%d0%bf%d0%b0%d1%81%d0%bd%d0%be%d1%81%d1%82%d1%8c" class="post_hash"&gt;&#128272; Безопасность&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://blog.trailofbits.com/2026/08/11/how-trail-of-bits-helps-verify-the-integrity-of-your-signal-chats/"&gt;How Trail of Bits helps verify the integrity of your Signal chats&lt;/a&gt;
&lt;/strong&gt;
Как устроена автоматическая проверка публичных ключей в Signal и зачем ей
независимые аудиторы. Trail of Bits рассказывает о своей реализации, которая
помогает обнаружить подмену ключей со стороны сервера.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://rmondello.com/2026/09/07/switching-password-managers-2026/"&gt;Switching Password Managers in 2026&lt;/a&gt;
&lt;/strong&gt;
Рики Монделло показывает, как на iPhone перенести пароли, passkeys и коды
подтверждения напрямую между менеджерами паролей, без промежуточных файлов.
Заодно объясняет, почему после переезда стоит сохранить старое хранилище
как резервную копию.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://blog.ferstar.org/en/posts/zcode-silent-workspace-snapshot-upload/"&gt;Inside ZCode: Silently Uploading Your Entire Git History to the Cloud&lt;/a&gt;
&lt;/strong&gt;
Автор разобрал ZCode и обнаружил фоновую отправку проекта в облако вместе
с полной историей Git. По его наблюдениям, переключатели в настройках управляют
обучением моделей и индексацией, но не отключают саму загрузку.&lt;/p&gt;
&lt;h2 id="-искусственный-интеллект"&gt;&lt;a href="#-%d0%b8%d1%81%d0%ba%d1%83%d1%81%d1%81%d1%82%d0%b2%d0%b5%d0%bd%d0%bd%d1%8b%d0%b9-%d0%b8%d0%bd%d1%82%d0%b5%d0%bb%d0%bb%d0%b5%d0%ba%d1%82" class="post_hash"&gt;&#129302; Искусственный интеллект&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://patrickmccanna.net/notes-on-migrating-large-prompts-away-from-anthropic-openai-to-self-hosted-llms/"&gt;Notes on migrating 35kb prompts away from Anthropic/OpenAI to Self-Hosted Ollama+opencode&lt;/a&gt;
&lt;/strong&gt;
Опыт переноса больших промптов с Anthropic и OpenAI на локальную связку Ollama
и opencode. Автор столкнулся с переполнением контекста и повторяющимися вызовами
инструментов. Предлагает разбивать инструкции на отдельные задачи и сохранять
состояние работы на диск.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://enclave.ai/blog/deepseek-v41-flash-is-now-our-best-hacking-model"&gt;DeepSeek V4.1 Flash is Now Our Best Hacking Model&lt;/a&gt;
&lt;/strong&gt;
В тестах Enclave модель добилась выполнения кода на всех 11 уязвимых стендах.
Разбор показал, что в пяти случаях она использовала неожиданные пути в тестовом
окружении, поэтому авторам пришлось уточнить проверки в benchmark.&lt;/p&gt;
&lt;h2 id="-инфраструктура"&gt;&lt;a href="#-%d0%b8%d0%bd%d1%84%d1%80%d0%b0%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d1%83%d1%80%d0%b0" class="post_hash"&gt;&#128736; Инфраструктура&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://rmoff.net/2026/01/14/alternatives-to-minio-for-single-node-local-s3/"&gt;Alternatives to MinIO for single-node local S3&lt;/a&gt;
&lt;/strong&gt;
Сравнение S3Proxy, RustFS, SeaweedFS и других замен MinIO для локального S3.
Автор проверяет работу с DuckDB и Iceberg, приводит примеры Docker Compose
и разбирает сложность настройки на одном узле.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;На этой неделе в подборке: проверка ключей в Signal, смена менеджера паролей,
скрытая отправка истории Git в ZCode, перенос промптов на локальные модели,
DeepSeek в тестах на взлом и альтернативы MinIO.&lt;/p&gt;
&lt;p&gt;Хорошей вам недели!&lt;/p&gt;
&lt;p&gt;Читайте оригинал на странице: &lt;a href="https://www.juev.org/2026/09/19/weblinks-408/" alt="Ссылки #408"&gt;Ссылки #408&lt;/a&gt; (Denis Evsyukov)&lt;/p&gt;</description></item><item><title>Ссылки #407</title><link>https://www.juev.org/2026/09/12/weblinks-407/</link><pubDate>Sat, 12 Sep 2026 10:22:36 +0300</pubDate><author>denis@evsyukov.org (Denis Evsyukov)</author><guid>https://www.juev.org/2026/09/12/weblinks-407/</guid><description>&lt;p&gt;За прошедшую неделю собрал 85 ссылок.&lt;/p&gt;
&lt;h2 id="-железо"&gt;&lt;a href="#-%d0%b6%d0%b5%d0%bb%d0%b5%d0%b7%d0%be" class="post_hash"&gt;&#128268; Железо&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://blog.jessfraz.com/post/home-hardware-part-two/"&gt;Home Hardware, Part 2: Width Matters&lt;/a&gt;
&lt;/strong&gt;
Джесс Фрейз спорила с коллегой о расчёте импеданса 50 Ом для RF-трассы на четырёхслойной плате Sensor Hub: разница в 0,1164 мм до внутреннего слоя земли вместо 0,2064 мм меняла ширину дорожки с 0,1778 мм до 0,32 мм. Оказалось, KiCad показывал оба внутренних слоя с медью земли, а агент Codex подобрал ближайший стек JLC04161H-2116 и пересчитал ширину, но итоговый файл содержал 0,18 мм — компромисс между вариантами с боковой землёй и без неё. Теперь она переводит платы на два слоя, чтобы сэкономить на серийных заказах.&lt;/p&gt;
&lt;h2 id="-инфраструктура"&gt;&lt;a href="#-%d0%b8%d0%bd%d1%84%d1%80%d0%b0%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d1%83%d1%80%d0%b0" class="post_hash"&gt;&#128737;️ Инфраструктура&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://about.readthedocs.com/blog/2026/09/2026-ddos-attack/"&gt;Understanding the recent DDoS attack against Read the Docs&lt;/a&gt;
&lt;/strong&gt;
В июне 2026 года Read the Docs пережил крупнейшую DDoS-атаку: 5,5 млн запросов в минуту — в 100 раз выше обычного трафика. Атака длилась десять дней, использовала миллионы уникальных IP, рандомизацию TLS и HTTP-заголовков, а также целенаправленно била по некэшируемым URL (404, 302). Команда перенесла часть редиректов на Cloudflare, добавила «штрафные» правила для подозрительных запросов и агрессивнее кэшировала даже короткоживущие ответы, избежав массовых JS-челленджей для пользователей.&lt;/p&gt;
&lt;h2 id="-криптография"&gt;&lt;a href="#-%d0%ba%d1%80%d0%b8%d0%bf%d1%82%d0%be%d0%b3%d1%80%d0%b0%d1%84%d0%b8%d1%8f" class="post_hash"&gt;&#128272; Криптография&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://mcpherrin.ca/2026/09/07/rsa.html"&gt;I’ve factored the RSA keys of a Certificate Authority…&lt;/a&gt;
&lt;/strong&gt;
В 1999 году Netscape 4.51 поставлял корневые сертификаты удостоверяющего центра E-Certify с 512-битными RSA-ключами для SSL и S/MIME — слабыми даже по меркам того времени. Автор нашёл архивы старых браузеров на archive.org, извлёк сертификаты с помощью Claude Code и факторизовал оба ключа на Ryzen 9 5950X за 32 и 29 часов с помощью CADO-NFS, получив приватные ключи. Теперь их можно использовать для выпуска сертификатов в Netscape 4.51 с датой до 16 октября 2003 года или для атаки «человек посередине» на пользователей этого браузера.&lt;/p&gt;
&lt;h2 id="-раст"&gt;&lt;a href="#-%d1%80%d0%b0%d1%81%d1%82" class="post_hash"&gt;&#129408; Раст&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://sofiabelen.github.io/projects/visualizing-rusts-vtables-how-dyn-trait-works-in-memory/"&gt;Visualizing Rust&amp;rsquo;s Vtables: How dyn Trait Works In Memory&lt;/a&gt;
&lt;/strong&gt;
Чтобы понять, как работает &lt;code&gt;dyn Trait&lt;/code&gt; в Rust, автор разбирает в памяти vtable — структуру, которая хранит указатели на реализации методов трейта для конкретного типа. Для &lt;code&gt;&amp;amp;dyn Draw&lt;/code&gt; компилятор генерирует wide pointer из двух указателей: на данные объекта и на vtable, общий для всех объектов одного типа. В отличие от C++, где vtable встраивается в объект, в Rust он создаётся отдельно и подключается только при динамическом диспатче, а выбор между статическим и динамическим диспатчем делается на уровне вызова.&lt;/p&gt;
&lt;h2 id="-агенты"&gt;&lt;a href="#-%d0%b0%d0%b3%d0%b5%d0%bd%d1%82%d1%8b" class="post_hash"&gt;&#129302; Агенты&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://rednafi.com/misc/pi-harness/"&gt;The irrational effectiveness of the Pi harness&lt;/a&gt;
&lt;/strong&gt;
Редактор опробовал минималистичный coding harness Pi на TypeScript, чтобы уйти от раздутых и непрозрачных систем вроде Claude Code и Codex. В Pi всего четыре инструмента — read, write, edit и bash, — а системный промпт занимает около 1000 токенов против 4400 у Codex; за месяц ежедневного использования автор не вернулся к более навороченным альтернативам. Для своих задач он написал несколько расширений: skill:whip для чистки LLM-текстов, extension:web.ts для поиска через DuckDuckGo и extension:subagent для запуска агентов в отдельных процессах.&lt;/p&gt;
&lt;h2 id="-квантизация"&gt;&lt;a href="#-%d0%ba%d0%b2%d0%b0%d0%bd%d1%82%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f" class="post_hash"&gt;⚡ Квантизация&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://quesma.com/blog/qwen38-27b-quantizations-benchmarked/"&gt;Benchmarking Qwen3.8 27B quantizations: 4-bit holds up, 1-bit collapses - Quesma Blog&lt;/a&gt;
&lt;/strong&gt;
Qwen3.8 27B в квантовании Q4_K_M (17 ГБ) на бенчмарках Terminal-Bench 2.1 и GPQA Diamond показывает результаты, неотличимые от полной BF16-модели (55 ГБ), при этом влезает на RTX 4090 с запасом на 64k токенов контекста. Двухбитная UD-Q2_K_XL (10,7 ГБ) проседает на 5–10%, но всё ещё сравнима с Opus 4.7, а однобитные модели падают до уровня случайного угадывания — особенно на длинных рассуждениях. Тесты обошлись в $3000 на аренде GPU через Modal, где 4-битная модель оказалась в 1,6 раза дешевле полной.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;На этой неделе в подборке: 50-омная RF-трасса на четырёхслойной плате, разбор июньской DDoS-атаки на Read the Docs, факторизация 512-битных RSA-ключей CA из Netscape 4.51, устройство vtable у dyn Trait в Rust, минималистичный coding harness Pi и бенчмарки квантований Qwen3.8 27B.&lt;/p&gt;
&lt;p&gt;Хорошей вам недели!&lt;/p&gt;
&lt;p&gt;Читайте оригинал на странице: &lt;a href="https://www.juev.org/2026/09/12/weblinks-407/" alt="Ссылки #407"&gt;Ссылки #407&lt;/a&gt; (Denis Evsyukov)&lt;/p&gt;</description></item><item><title>Почему исправный прокси был недоступен из контейнеров Podman</title><link>https://www.juev.org/2026/09/11/podman-pasta-stale-connections/</link><pubDate>Fri, 11 Sep 2026 19:01:41 +0300</pubDate><author>denis@evsyukov.org (Denis Evsyukov)</author><guid>https://www.juev.org/2026/09/11/podman-pasta-stale-connections/</guid><description>&lt;p&gt;Некоторые сетевые ошибки выглядят как недоступность внешнего сервиса, хотя запрос ещё не покинул локальную машину. Недавно я разбирался с таким случаем: приложения в rootless-контейнерах периодически не могли подключиться к HTTP-прокси. Проверка с хоста проходила, процесс прокси работал, следующие запросы снова выполнялись успешно.&lt;/p&gt;
&lt;p&gt;Причиной оказалась ошибка в pasta, сетевом компоненте, который Podman использовал для связи rootless-сети с хостом. Старые TCP-соединения оставались в его таблице, а новые подключения с теми же адресами и портами попадали в эти записи. Ни смена внешнего прокси, ни увеличение таймаутов приложения эту причину не устраняли.&lt;/p&gt;
&lt;h2 id="почему-долго-искали-не-там"&gt;&lt;a href="#%d0%bf%d0%be%d1%87%d0%b5%d0%bc%d1%83-%d0%b4%d0%be%d0%bb%d0%b3%d0%be-%d0%b8%d1%81%d0%ba%d0%b0%d0%bb%d0%b8-%d0%bd%d0%b5-%d1%82%d0%b0%d0%bc" class="post_hash"&gt;Почему долго искали не там&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Приложение сообщало о таймауте подключения к прокси. Первое предположение было простым: проблема во внешнем выходе, удалённом узле или маршруте до нужного сайта. Такие сбои действительно бывают, а слово «прокси» в ошибке направляло расследование именно туда.&lt;/p&gt;
&lt;p&gt;Проверки с хоста этому противоречили: прокси принимал соединения, внешние адреса отвечали. Но проверка с хоста пропускала часть пути, по которому шёл запрос приложения. Для rootless-контейнера между приложением и хостом находились дополнительные сетевые компоненты.&lt;/p&gt;
&lt;p&gt;В рассматриваемой схеме путь выглядел так:&lt;/p&gt;
&lt;div class="mermaid"&gt;flowchart TB
app[Приложение в контейнере] --&gt; bridge[Bridge и NAT]
bridge --&gt; pasta[pasta]
pasta --&gt; proxy[Прокси на хосте]&lt;/div&gt;&lt;p&gt;Здесь pasta связывает виртуальный сетевой интерфейс namespace с обычными сокетами хоста. У него есть собственная таблица соединений: успешного ответа прокси с хоста недостаточно, чтобы подтвердить исправность всего пути.&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Мешал и непостоянный характер ошибки. Серия подключений могла пройти целиком, следующая давала отдельный timeout, затем всё снова работало. Перезапуск приложения не обеспечивал устойчивого результата. Загрузка машины и число открытых файлов не указывали на исчерпание ресурсов.&lt;/p&gt;
&lt;p&gt;Первую ошибку в расследовании мы допустили именно здесь: приняли успешную проверку соседнего участка за проверку того участка, на котором происходил отказ. Позже пришлось вернуться к исходной ошибке приложения и проследить его запрос по всей локальной цепочке.&lt;/p&gt;
&lt;h2 id="как-нашли-механизм-отказа"&gt;&lt;a href="#%d0%ba%d0%b0%d0%ba-%d0%bd%d0%b0%d1%88%d0%bb%d0%b8-%d0%bc%d0%b5%d1%85%d0%b0%d0%bd%d0%b8%d0%b7%d0%bc-%d0%be%d1%82%d0%ba%d0%b0%d0%b7%d0%b0" class="post_hash"&gt;Как нашли механизм отказа&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="syn-выходит-из-контейнера-но-соединение-на-хосте-не-появляется"&gt;&lt;a href="#syn-%d0%b2%d1%8b%d1%85%d0%be%d0%b4%d0%b8%d1%82-%d0%b8%d0%b7-%d0%ba%d0%be%d0%bd%d1%82%d0%b5%d0%b9%d0%bd%d0%b5%d1%80%d0%b0-%d0%bd%d0%be-%d1%81%d0%be%d0%b5%d0%b4%d0%b8%d0%bd%d0%b5%d0%bd%d0%b8%d0%b5-%d0%bd%d0%b0-%d1%85%d0%be%d1%81%d1%82%d0%b5-%d0%bd%d0%b5-%d0%bf%d0%be%d1%8f%d0%b2%d0%bb%d1%8f%d0%b5%d1%82%d1%81%d1%8f" class="post_hash"&gt;SYN выходит из контейнера, но соединение на хосте не появляется&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Следующим шагом стали одновременные захваты пакетов в rootless namespace и на хосте. В момент отказа со стороны контейнера были видны повторные SYN. Это первые пакеты TCP handshake: клиент просит установить соединение и повторяет попытку, если не получает ответа.&lt;/p&gt;
&lt;p&gt;Пакеты проходили bridge и NAT, но соответствующего соединения к процессу прокси на хосте не возникало. Трассировка системных вызовов pasta не показывала нового &lt;code&gt;connect()&lt;/code&gt; для этой попытки. Значит, искать причину отказа именно этого подключения на внешнем маршруте было преждевременно: оно до него ещё не дошло.&lt;/p&gt;
&lt;p&gt;Это также отделяло проблему от HTTP и TLS. Приложение не успевало отправить запрос или начать защищённое соединение. Проверка ключей доступа и настроек внешнего API ничего не объяснила бы.&lt;/p&gt;
&lt;h3 id="отказ-зависел-от-исходного-порта"&gt;&lt;a href="#%d0%be%d1%82%d0%ba%d0%b0%d0%b7-%d0%b7%d0%b0%d0%b2%d0%b8%d1%81%d0%b5%d0%bb-%d0%be%d1%82-%d0%b8%d1%81%d1%85%d0%be%d0%b4%d0%bd%d0%be%d0%b3%d0%be-%d0%bf%d0%be%d1%80%d1%82%d0%b0" class="post_hash"&gt;Отказ зависел от исходного порта&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Обычно приложение позволяет ядру выбрать свободный source port. Мы стали задавать его явно и повторять подключения к одной и той же цели.&lt;/p&gt;
&lt;p&gt;С одними портами соединение устанавливалось сразу. С другими попытки стабильно заканчивались таймаутом. При этом подключение с проблемным исходным портом к другому порту назначения проходило. Значение имела комбинация адресов и портов.&lt;/p&gt;
&lt;p&gt;Смена контейнера не обязательно меняла эту комбинацию для pasta. После NAT разные адреса контейнеров могли превращаться в один адрес, видимый сетевому компоненту. Поэтому пересоздание контейнера не гарантировало освобождения занятой записи.&lt;/p&gt;
&lt;p&gt;Так у случайного на вид сбоя появился воспроизводимый признак. Теперь можно было сравнить две почти одинаковые попытки, меняя только исходный порт.&lt;/p&gt;
&lt;h3 id="старое-соединение-занимало-место-нового"&gt;&lt;a href="#%d1%81%d1%82%d0%b0%d1%80%d0%be%d0%b5-%d1%81%d0%be%d0%b5%d0%b4%d0%b8%d0%bd%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b7%d0%b0%d0%bd%d0%b8%d0%bc%d0%b0%d0%bb%d0%be-%d0%bc%d0%b5%d1%81%d1%82%d0%be-%d0%bd%d0%be%d0%b2%d0%be%d0%b3%d0%be" class="post_hash"&gt;Старое соединение занимало место нового&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Мы сопоставили сокеты процесса с его внутренней таблицей соединений. Для этого понадобились исходники и отладочные символы именно той сборки, которая работала, а также небольшая программа для чтения нужных структур. Размеры записей проверили по символам отладки, чтобы не принять неверно прочитанную память за доказательство.&lt;/p&gt;
&lt;p&gt;Проблемным подключениям соответствовали старые записи. На стороне хоста сокеты находились в &lt;code&gt;CLOSE_WAIT&lt;/code&gt;: удалённая сторона уже прислала FIN, но локальная сторона ещё не завершила свою половину соединения. Pasta передал FIN клиенту и получил подтверждение, однако запись продолжала существовать без обмена данными гораздо дольше ожидаемого.&lt;/p&gt;
&lt;p&gt;Само состояние &lt;code&gt;CLOSE_WAIT&lt;/code&gt; допустимо. Подозрительным было длительное удержание записей, а решающим стало совпадение их адресов и портов с новыми попытками подключения.&lt;/p&gt;
&lt;p&gt;Получив новый SYN, pasta находил старую запись и передавал пакет обработчику уже установленного соединения. Для исследованного состояния и sequence numbers тот не создавал новое соединение и не формировал ответ. Клиент продолжал повторять SYN до таймаута. Это объясняло и зависимость от source port, и отсутствие &lt;code&gt;connect()&lt;/code&gt; на хосте.&lt;/p&gt;
&lt;h3 id="таймер-который-постоянно-откладывал-очистку"&gt;&lt;a href="#%d1%82%d0%b0%d0%b9%d0%bc%d0%b5%d1%80-%d0%ba%d0%be%d1%82%d0%be%d1%80%d1%8b%d0%b9-%d0%bf%d0%be%d1%81%d1%82%d0%be%d1%8f%d0%bd%d0%bd%d0%be-%d0%be%d1%82%d0%ba%d0%bb%d0%b0%d0%b4%d1%8b%d0%b2%d0%b0%d0%bb-%d0%be%d1%87%d0%b8%d1%81%d1%82%d0%ba%d1%83" class="post_hash"&gt;Таймер, который постоянно откладывал очистку&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Оставалось понять, почему записи не удалялись. В старом коде был таймер очистки после двух часов бездействия. Существенная часть обработчика выглядела так:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;timerfd_settime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;old&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;old&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;it_value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tv_sec&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;ACT_TIMEOUT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nf"&gt;tcp_rst&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;К моменту вызова таймер уже сработал. Код снова заводил его на два часа и проверял, равно ли прежнее значение двум часам. Но &lt;code&gt;timerfd_settime()&lt;/code&gt; возвращает в &lt;code&gt;old.it_value&lt;/code&gt; оставшееся время. У только что истёкшего таймера там ноль, поэтому условие очистки не выполнялось.&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Этот механизм мог повторяться неограниченно: очередное срабатывание переносило очистку ещё на два часа. Описание upstream-исправления подтверждало ту же ошибку.&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Мы отдельно собрали маленькую C-программу и повторили последовательность вызовов &lt;code&gt;timerfd&lt;/code&gt; с коротким начальным ожиданием. После срабатывания прежнее оставшееся время было нулевым, ветка очистки не выбиралась. Это позволило проверить понимание системного вызова, не меняя таймеры работающего процесса.&lt;/p&gt;
&lt;p&gt;При этом исходный эпизод незавершённого закрытия восстановить не удалось: захвата пакетов за тот момент не было. Мы установили причину удержания старых записей и отказа новых SYN. Утверждать, что конкретный FIN потеряла сеть или приложение, оснований не было.&lt;/p&gt;
&lt;h2 id="как-обновляли-и-проверяли-исправление"&gt;&lt;a href="#%d0%ba%d0%b0%d0%ba-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d1%8f%d0%bb%d0%b8-%d0%b8-%d0%bf%d1%80%d0%be%d0%b2%d0%b5%d1%80%d1%8f%d0%bb%d0%b8-%d0%b8%d1%81%d0%bf%d1%80%d0%b0%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5" class="post_hash"&gt;Как обновляли и проверяли исправление&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="что-собирали-а-что-взяли-готовым"&gt;&lt;a href="#%d1%87%d1%82%d0%be-%d1%81%d0%be%d0%b1%d0%b8%d1%80%d0%b0%d0%bb%d0%b8-%d0%b0-%d1%87%d1%82%d0%be-%d0%b2%d0%b7%d1%8f%d0%bb%d0%b8-%d0%b3%d0%be%d1%82%d0%be%d0%b2%d1%8b%d0%bc" class="post_hash"&gt;Что собирали, а что взяли готовым&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Upstream уже удалил неработающий механизм и добавил периодический обход таблицы: соединения без активности удаляются через два–четыре часа. Дополнительно появились TCP keepalive в сторону клиента. Если клиент уже забыл соединение, он отвечает RST, и запись можно убрать раньше.&lt;sup id="fnref:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;sup id="fnref:5"&gt;&lt;a href="#fn:5" class="footnote-ref" role="doc-noteref"&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Эти изменения вошли в релиз &lt;code&gt;2026_05_07.1afd4ed&lt;/code&gt;.&lt;sup id="fnref:6"&gt;&lt;a href="#fn:6" class="footnote-ref" role="doc-noteref"&gt;6&lt;/a&gt;&lt;/sup&gt; Для проверки мы выбрали более свежий официальный Debian-пакет с исправлениями. Из исходников мы собрали диагностические программы. Для самого passt использовали готовый &lt;code&gt;.deb&lt;/code&gt;, полученный через APT с проверкой подписи репозитория и контрольных сумм пакета.&lt;/p&gt;
&lt;p&gt;Свежего пакета не было в подключённом стабильном репозитории. Нужную сборку взяли из Debian sid через отдельные временные индексы, не добавляя sid в постоянные источники системы. До установки проверили зависимости и запустили симуляцию APT. Она должна была показать обновление только passt, без попутной замены системных библиотек.&lt;sup id="fnref:7"&gt;&lt;a href="#fn:7" class="footnote-ref" role="doc-noteref"&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Совместимость такого пакета нужно проверять на конкретной системе. После установки мы сравнили полный список пакетов с исходным и убедились, что изменился только passt. Старый &lt;code&gt;.deb&lt;/code&gt; сохранили для отката.&lt;/p&gt;
&lt;h3 id="сначала-пришлось-исправить-сам-тест"&gt;&lt;a href="#%d1%81%d0%bd%d0%b0%d1%87%d0%b0%d0%bb%d0%b0-%d0%bf%d1%80%d0%b8%d1%88%d0%bb%d0%be%d1%81%d1%8c-%d0%b8%d1%81%d0%bf%d1%80%d0%b0%d0%b2%d0%b8%d1%82%d1%8c-%d1%81%d0%b0%d0%bc-%d1%82%d0%b5%d1%81%d1%82" class="post_hash"&gt;Сначала пришлось исправить сам тест&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Обычный успешный запрос не доказывал исправление: таких запросов хватало и до обновления. Нужен был опыт, в котором старая версия сохраняет забытое соединение, а новая его удаляет.&lt;/p&gt;
&lt;p&gt;Для этого мы создали отдельную rootless-сеть и локальный TCP-сервер с коротким тестовым ответом. Сервер отправлял FIN, клиент подтверждал его, после чего удалял свой сокет через &lt;code&gt;TCP_REPAIR&lt;/code&gt;, не отправляя FIN или RST. Pasta должен был остаться с записью о соединении, которого клиент уже не помнил.&lt;/p&gt;
&lt;p&gt;Первый вариант теста оказался неверным. Клиент удалял сокет слишком быстро, до отправки отложенного ACK на FIN. Получалась проверка повторной передачи неподтверждённого FIN, а не очистки нужного нам состояния. Разницу показал захват пакетов.&lt;/p&gt;
&lt;p&gt;Мы включили &lt;code&gt;TCP_QUICKACK&lt;/code&gt;, добавили небольшое ожидание перед удалением сокета и проверку ACK в захвате. Только после этого сравнение версий стало содержательным. По окончании очистки тест повторно подключался с тем же source port и проверял ответ сервера.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Проверка&lt;/th&gt;
&lt;th&gt;Результат&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Старая версия&lt;/td&gt;
&lt;td&gt;Удерживала соединение всё время наблюдения, больше десяти минут&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Новая версия до установки&lt;/td&gt;
&lt;td&gt;Удалила соединение примерно за 32 секунды; повторное подключение с тем же портом прошло&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Новая версия после установки&lt;/td&gt;
&lt;td&gt;Повторила результат, в том числе с действующим профилем AppArmor&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;В захвате новой версии была видна вся последовательность: keepalive, RST от ядра клиента, затем новый успешный handshake. В выбранном июльском релизе интервал проверки клиента уже сокращён до 30 секунд, что согласуется с результатом опыта.&lt;sup id="fnref:8"&gt;&lt;a href="#fn:8" class="footnote-ref" role="doc-noteref"&gt;8&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Этот тест проверяет обнаружение соединения, забытого клиентом. Он не означает, что любое бездействующее TCP-соединение новая версия закрывает через полминуты.&lt;/p&gt;
&lt;h3 id="обновить-файл-недостаточно"&gt;&lt;a href="#%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%b8%d1%82%d1%8c-%d1%84%d0%b0%d0%b9%d0%bb-%d0%bd%d0%b5%d0%b4%d0%be%d1%81%d1%82%d0%b0%d1%82%d0%be%d1%87%d0%bd%d0%be" class="post_hash"&gt;Обновить файл недостаточно&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;После установки нового пакета старый процесс продолжает исполнять прежний бинарник. Его накопленная таблица тоже никуда не исчезает. Поэтому обновление завершалось заменой работающего pasta.&lt;/p&gt;
&lt;p&gt;В проверенной версии Podman был путь восстановления: при обращении к общей rootless-сети он мог обнаружить остановленный сетевой процесс и запустить новый в существующем namespace. Сначала мы испытали это в отдельной сети и убедились, что namespace, bridge и доступ к хосту сохраняются.&lt;sup id="fnref:9"&gt;&lt;a href="#fn:9" class="footnote-ref" role="doc-noteref"&gt;9&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Затем завершили только нужный процесс pasta, дождались его выхода и вызвали &lt;code&gt;podman unshare --rootless-netns true&lt;/code&gt; от того же пользователя. Podman поднял новый процесс. Пересоздавать контейнеры не понадобилось, но текущие внешние TCP-соединения при такой замене обрываются: состояние старого pasta в новый процесс не переносится.&lt;/p&gt;
&lt;p&gt;Это описание проверенного способа восстановления, а не универсальная команда перезапуска сети для любой версии Podman. Перед применением нужно установить, какой процесс обслуживает нужный namespace и как конкретная версия восстанавливает его после остановки.&lt;/p&gt;
&lt;p&gt;После переключения мы проверили те самые комбинации портов, которые раньше стабильно давали timeout. Соединения устанавливались сразу. Затем проверили SOCKS, HTTP CONNECT, прямые запросы из контейнера, IPv6 и доступ к тестируемым приложениям. Состояния контейнеров и их сетевые адреса сравнили с исходными.&lt;/p&gt;
&lt;p&gt;У установки отдельного пакета осталась эксплуатационная особенность: постоянный источник sid не подключён, поэтому следующие его версии обычный APT сам оттуда не получит. За дальнейшими исправлениями passt придётся следить отдельно.&lt;/p&gt;
&lt;h2 id="что-из-этого-следует"&gt;&lt;a href="#%d1%87%d1%82%d0%be-%d0%b8%d0%b7-%d1%8d%d1%82%d0%be%d0%b3%d0%be-%d1%81%d0%bb%d0%b5%d0%b4%d1%83%d0%b5%d1%82" class="post_hash"&gt;Что из этого следует&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Главный результат расследования — воспроизводимый отказ и проверенное изменение его механизма. До обновления старая запись удерживалась, после обновления pasta обнаруживал, что клиент её забыл, и освобождал комбинацию адресов и портов. Это сильнее, чем серия успешных запросов после перезапуска.&lt;/p&gt;
&lt;p&gt;Для диагностики полезнее всего оказалось сравнение одного и того же пути в исправном и неисправном состоянии. Проверка с хоста отвечала на свой вопрос, но ничего не говорила о прохождении запроса через rootless-сеть. Явно заданный source port превратил случайный симптом в повторяемый опыт, а чтение исходников объяснило результат.&lt;/p&gt;
&lt;p&gt;Есть и архитектурный вывод. Отсутствие общего демона управления контейнерами не означает отсутствия общих зависимостей. В конфигурации с общим pasta сетевой процесс может влиять сразу на несколько независимых приложений. Проверка доступности должна проходить через тот же сетевой путь, которым пользуются эти приложения.&lt;/p&gt;
&lt;p&gt;Менять контейнерную платформу ради этого дефекта мы не стали: ошибку удалось локализовать в отдельном компоненте и проверить его исправление. Длительное наблюдение всё ещё нужно для оценки устойчивости системы, но ждать его, чтобы установить причину конкретного отказа, уже не требуется.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Примечание. Статья написана gpt-6-astra по результатам работы на сервере.&lt;/em&gt;&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;a href="https://passt.top/passt/about/"&gt;passt и pasta: устройство и назначение&lt;/a&gt;
.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;&lt;a href="https://man7.org/linux/man-pages/man2/timerfd_settime.2.html"&gt;timerfd_create, timerfd_settime, timerfd_gettime&lt;/a&gt;
, Linux man-pages. Поле &lt;code&gt;old_value.it_value&lt;/code&gt; содержит оставшееся время.&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;&lt;a href="https://passt.top/passt/commit/?id=e48ce41a1ec2f05846fb66d3847c2c2b6448ca71"&gt;Удаление неработающего inactivity timeout&lt;/a&gt;
, commit upstream.&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;&lt;a href="https://passt.top/passt/commit/?id=1820103fbbf13df98257a3f5c3ba625de624b0b3"&gt;Периодическая очистка неактивных соединений&lt;/a&gt;
, commit upstream.&amp;#160;&lt;a href="#fnref:4" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:5"&gt;
&lt;p&gt;&lt;a href="https://passt.top/passt/commit/?id=d2f7c21cfb949f2b1587b9475917efdd6ac549fd"&gt;Keepalive для обнаружения забытых клиентом соединений&lt;/a&gt;
, commit upstream.&amp;#160;&lt;a href="#fnref:5" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:6"&gt;
&lt;p&gt;&lt;a href="https://bugs.passt.top/show_bug.cgi?id=179#c20"&gt;Bug 179, комментарий о выпуске исправления&lt;/a&gt;
. В исходном обращении обсуждалось состояние &lt;code&gt;FIN_WAIT_2&lt;/code&gt;; сопоставлялся механизм очистки, а не полное совпадение симптомов.&amp;#160;&lt;a href="#fnref:6" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:7"&gt;
&lt;p&gt;&lt;a href="https://packages.debian.org/sid/passt"&gt;Пакет passt в Debian sid&lt;/a&gt;
.&amp;#160;&lt;a href="#fnref:7" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:8"&gt;
&lt;p&gt;&lt;a href="https://passt.top/passt/plain/tcp.c?h=2026_07_28.f8df3f1"&gt;tcp.c в релизе 2026_07_28.f8df3f1&lt;/a&gt;
, &lt;code&gt;KEEPALIVE_INTERVAL&lt;/code&gt; и &lt;code&gt;tcp_keepalive()&lt;/code&gt;.&amp;#160;&lt;a href="#fnref:8" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:9"&gt;
&lt;p&gt;&lt;a href="https://github.com/containers/common/blob/v0.62.3/libnetwork/internal/rootlessnetns/netns_linux.go"&gt;Восстановление общего rootless namespace в containers/common v0.62.3&lt;/a&gt;
, &lt;code&gt;getOrCreateNetns()&lt;/code&gt;.&amp;#160;&lt;a href="#fnref:9" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;Читайте оригинал на странице: &lt;a href="https://www.juev.org/2026/09/11/podman-pasta-stale-connections/" alt="Почему исправный прокси был недоступен из контейнеров Podman"&gt;Почему исправный прокси был недоступен из контейнеров Podman&lt;/a&gt; (Denis Evsyukov)&lt;/p&gt;</description></item><item><title>Ссылки #406</title><link>https://www.juev.org/2026/09/05/weblinks-406/</link><pubDate>Sat, 05 Sep 2026 09:38:54 +0300</pubDate><author>denis@evsyukov.org (Denis Evsyukov)</author><guid>https://www.juev.org/2026/09/05/weblinks-406/</guid><description>&lt;p&gt;За прошедшую неделю собрал 59 ссылок.&lt;/p&gt;
&lt;h2 id="-агенты"&gt;&lt;a href="#-%d0%b0%d0%b3%d0%b5%d0%bd%d1%82%d1%8b" class="post_hash"&gt;&#129302; Агенты&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.agentconnect.md/blog/grep-beat-lsp-harness/"&gt;Grep beats LSP? Why coding agents ignore your fancier tools — AgentConnect Blog&lt;/a&gt;
&lt;/strong&gt;
Автор сравнил поиск через grep и инструменты на основе LSP в небольшом исследовании с тремя моделями Claude. Когда агентам нужно было найти участок кода, они выбирали LSP лишь в 0–6% случаев. Требование сначала использовать LSP снижало долю успешно выполненных задач со 100% до 89%. При поиске всех вызовов функции LSP исключал ложные совпадения, но с обоими инструментами агенты находили лишь около двух третей вызовов. Для переименования grep оказался полезен ещё и потому, что находит упоминания в комментариях и строках, которые &lt;code&gt;find_references&lt;/code&gt; пропускает. На результат влиял и формат ответа инструмента: когда к координатам найденного кода добавили по две строки до и после совпадения, доля успешных переименований с первой попытки выросла с 67% до 83%. После этого агенты реже открывали файлы повторно.&lt;/p&gt;
&lt;h2 id="-безопасность"&gt;&lt;a href="#-%d0%b1%d0%b5%d0%b7%d0%be%d0%bf%d0%b0%d1%81%d0%bd%d0%be%d1%81%d1%82%d1%8c" class="post_hash"&gt;&#128737;️ Безопасность&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://embracethered.com/blog/posts/2026/breaking-claude-code-opus-5-and-automode/"&gt;Breaking Claude Code Opus 5 Auto Mode · Embrace The Red&lt;/a&gt;
&lt;/strong&gt;
Исследователь показал, как просьба кратко пересказать страницу приводит к выполнению вредоносного кода в Claude Code с Opus 5. Защита Auto Mode не остановила атаку: в этом режиме команды вместо пользователя одобряет классификатор безопасности. После ошибки WebFetch агент сам переходит на curl и скачивает ZIP-архив. Он отказывается запускать приложенный декодер и пишет свой на Python, но запускает его из каталога распакованного архива. При импорте &lt;code&gt;base64&lt;/code&gt; Python загружает оттуда подменённый &lt;code&gt;struct.py&lt;/code&gt;, и код атакующего получает управление. В зависимости от варианта атака сработала в трёх или четырёх из пяти запусков. Иногда агент замечал проблему, однако Auto Mode блокировал попытку остановить вредоносный процесс. В Anthropic закрыли отчёт со статусом Informative и пояснили, что защиту должны обеспечивать изоляция средствами ОС и контроль сетевого доступа. Классификатор таких гарантий не даёт.&lt;/p&gt;
&lt;h2 id="-поиск"&gt;&lt;a href="#-%d0%bf%d0%be%d0%b8%d1%81%d0%ba" class="post_hash"&gt;&#128270; Поиск&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://hausresearch.com/reports/perplexity-citation-audit/"&gt;A third of Perplexity&amp;rsquo;s citations don&amp;rsquo;t contain the number they&amp;rsquo;re cited for — Haus Research&lt;/a&gt;
&lt;/strong&gt;
Исследователи из Haus Research проверили ссылки на источники в ответах Perplexity. Моделям sonar и sonar-pro задали 310 вопросов о 210 технологических компаниях, затем открыли указанные страницы и сопоставили числа в них с числами в ответах. Из 1826 ссылок, которыми модели подкрепляли утверждения с числами, 34,7% вели на недоступные страницы или на страницы без единого совпадения. У одного утверждения могло быть несколько источников, и для зачёта хватало хотя бы одного с совпавшим числом. По этому критерию проверку не прошли 14,4% из 872 утверждений. Нередко ссылка открывалась, но нужных сведений на странице не было: например, Perplexity ссылался на Wikipedia, указывая адреса Docker и Substack, которых в этих статьях нет. Sonar-pro в этой проверке показал примерно тот же результат, что и sonar. Даже совпадения года было достаточно, поэтому успешное прохождение ещё не означает, что источник подтверждает всё утверждение.&lt;/p&gt;
&lt;h2 id="-локальные-модели"&gt;&lt;a href="#-%d0%bb%d0%be%d0%ba%d0%b0%d0%bb%d1%8c%d0%bd%d1%8b%d0%b5-%d0%bc%d0%be%d0%b4%d0%b5%d0%bb%d0%b8" class="post_hash"&gt;&#127968; Локальные модели&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://terminalbytes.com/run-qwen-3-8-27b-locally/"&gt;Run Qwen3.8 27B locally: real numbers from my Mac Studio | TerminalBytes&lt;/a&gt;
&lt;/strong&gt;
Автор использует Qwen3.8 27B на Mac Studio для повседневных задач: модель готовит утреннюю сводку из RSS, переименовывает отсканированные PDF и пересказывает длинные обсуждения. Он сравнил её с Qwen3.6 27B на Mac Studio M3 Ultra с 256 ГБ общей памяти, выполнив по пять замеров. В варианте Q4_K_M через Ollama новая модель генерирует 14 токенов в секунду против 28,6 у предыдущей. При этом её ответы заметно короче, поэтому на готовый ответ уходило примерно столько же времени. Однобитная версия от Unsloth размером 6,7 ГБ работала быстрее, но застревала в рассуждениях: выдав правильную команду bash, продолжала перебирать альтернативы и не могла закончить ответ. В статье также есть таблица требований к памяти: для Q4 автор рекомендует 32 ГБ. Для задач с вызовом инструментов он ссылается на рекомендацию Unsloth использовать как минимум Q2_K_XL.&lt;/p&gt;
&lt;h2 id="-сеть"&gt;&lt;a href="#-%d1%81%d0%b5%d1%82%d1%8c" class="post_hash"&gt;&#127760; Сеть&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://dreamstation.systems/personal/ntppost.html"&gt;Internet centralization and the original sin of NAT&lt;/a&gt;
&lt;/strong&gt;
Автор связывает централизацию интернета с распространением NAT. Эту технологию предложили в 1994 году как временный способ экономить IP-адреса: несколько устройств используют один публичный адрес. Однако без дополнительной настройки маршрутизатор не знает, какому устройству передать новое входящее соединение. В статье разобраны способы обойти это ограничение и их недостатки. Проброс портов на домашнем маршрутизаторе не решает проблему NAT у провайдера, STUN помогает не при всех типах NAT, а TURN передаёт трафик через промежуточный сервер и добавляет задержку. IPv6 позволяет обойтись без NAT, но его внедрение затянулось, а ограничения на входящие соединения нередко сохраняются. По мысли автора, эти сложности приучили нас обращаться к облачным сервисам: даже для своего небольшого сервера часто проще арендовать VPS, чем сделать домашний компьютер доступным извне.&lt;/p&gt;
&lt;h2 id="-приватность"&gt;&lt;a href="#-%d0%bf%d1%80%d0%b8%d0%b2%d0%b0%d1%82%d0%bd%d0%be%d1%81%d1%82%d1%8c" class="post_hash"&gt;&#128269; Приватность&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://marius.blog/firefox-155-ai-kill-switch-retest/"&gt;Firefox’s AI Switch Is Off. Telemetry Isn’t.&lt;/a&gt;
&lt;/strong&gt;
Мариус Квабек повторил в Firefox 155 проверку переключателя, отключающего AI-функции. Он создал два новых профиля и сравнил их сетевой трафик в Wireshark: с настройками по умолчанию и после отключения AI. Переключатель теперь охватывает больше функций, включая Smart Window, но отправка телеметрии и обращения к рекламным серверам продолжаются. За две минуты простоя оба профиля отправили по 14 запросов с телеметрией; после перезапуска идентификаторы профиля также сохранились. При первом запуске браузер запросил настройки &lt;code&gt;ai-window-prompts&lt;/code&gt; ещё до того, как пользователь получил доступ к переключателю. Автор отдельно оговаривает: Mozilla не обещает отключать им телеметрию и рекламу. Его претензия в том, что пользователю трудно понять границы этой настройки и разобраться, какие данные браузер продолжает отправлять.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;В этой подборке: выбор между grep и LSP для агентов, обход защиты Auto Mode в Claude Code, проверка источников Perplexity, опыт работы с Qwen3.8 27B на Mac Studio, влияние NAT на централизацию интернета и отправка телеметрии после отключения AI в Firefox.&lt;/p&gt;
&lt;p&gt;Хорошей вам недели!&lt;/p&gt;
&lt;p&gt;Читайте оригинал на странице: &lt;a href="https://www.juev.org/2026/09/05/weblinks-406/" alt="Ссылки #406"&gt;Ссылки #406&lt;/a&gt; (Denis Evsyukov)&lt;/p&gt;</description></item></channel></rss>