<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Savely Krasovsky's blog</title><link>https://krasovs.ky</link><description>Recent content in Blogs on Savely Krasovsky's blog</description><generator>Hugo -- gohugo.io</generator><language>en</language><managingEditor>savely@krasovs.ky (Savely Krasovsky)</managingEditor><webMaster>savely@krasovs.ky (Savely Krasovsky)</webMaster><lastBuildDate>Mon, 05 Aug 2024 14:49:27 +0200</lastBuildDate><atom:link href="https://krasovs.ky/blog/index.xml" rel="self" type="application/rss+xml"/><item><title>Конфиг для выборочного обхода блокировок на базе sing-box</title><link>https://krasovs.ky/2024/08/05/sing-box-bypass.html</link><pubDate>Mon, 05 Aug 2024 14:49:27 +0200</pubDate><author>savely@krasovs.ky (Savely Krasovsky)</author><guid>https://krasovs.ky/2024/08/05/sing-box-bypass.html</guid><description>&lt;p>Заметил, что большинство людей использует L2/L3 TAP/TUN-решения, которые в подавляющем количестве случаев являются
перебором. Они часто вызывают проблемы с корпоративными VPN и заставляют постоянно переподключаться, потому что как
правило роутят весь трафик через туннель. Обычно для обхода блокировок достаточно обыкновенных SOCKS/HTTP-прокси.
Их умеют использовать браузеры и большинство популярных приложений и они обычно не конфликтуют с другими
VPN-приложениями, например корпоративными.&lt;/p>
&lt;p>Поэтому решил набросать достаточно простой конфиг для популярного прокси-движка &lt;code>sing-box&lt;/code>.&lt;/p>
&lt;h2 id="подразумевается-что">Подразумевается, что:&lt;/h2>
&lt;ol>
&lt;li>У вас уже есть настроенный сервер, например, с установленным Outline или голым Shadowsocks.&lt;/li>
&lt;li>Вы установили &lt;code>sing-box&lt;/code> с &lt;a href="https://sing-box.sagernet.org/">официального сайта&lt;/a>,
&lt;a href="https://github.com/SagerNet/sing-box/releases">GitHub&lt;/a> или &lt;a href="https://sing-box.sagernet.org/clients/">магазина приложений&lt;/a>.&lt;/li>
&lt;li>Вы можете работать с консолью и в состоянии запустить команду вида &lt;code>sing-box run -c config.json&lt;/code>.&lt;/li>
&lt;/ol>
&lt;h2 id="особенности-конфига">Особенности конфига&lt;/h2>
&lt;ol>
&lt;li>
&lt;p>По умолчанию DNS-запросы уходят на ваш системный DNS-ресолвер, если не определено обратное.&lt;/p>
&lt;p>Это достигается за счёт параметров &lt;code>&amp;quot;sniff&amp;quot;: true&lt;/code> &lt;em>(позволяет сниффить SNI из запросов к прокси)&lt;/em>
и &lt;code>&amp;quot;domain_strategy&amp;quot;: &amp;quot;prefer_ipv4&amp;quot;&lt;/code> &lt;em>(позволяет ресолвить IP заранее, через правила, определенные в конфигурации,
иначе ресолвинг будет происходить на удаленном сервере)&lt;/em>.&lt;/p>
&lt;p>Если для подключения к прокси-серверу, вы используете домен, то добавьте для него отдельное правило,
отправляющее DNS-запрос на системный ресолвер:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;domain&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;your.server.example.com&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;local-dns&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>В качестве основного входящего транспорта данный конфиг использует &lt;code>mixed&lt;/code>. Это SOCKS/HTTP прокси,
который автоматически проставляется в настройки ОС при запуске &lt;code>sing-box&lt;/code>. Это поведение можно переопределить,
но тогда браузер и другие приложения придется настраивать на работу с прокси вручную, что зачастую может быть
полезно.&lt;/p>
&lt;p>Этот вход может быть заменён на любой другой, например, на TUN (полезно для работы на мобильных устройствах):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;type&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;tun&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;inet4_address&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;172.16.0.1/30&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;auto_route&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;strict_route&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;sniff&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;domain_strategy&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;prefer_ipv4&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>В качестве исходящих транспортов этот конфиг использует &lt;code>direct&lt;/code> &lt;em>(прямое интернет-соединение)&lt;/em> и &lt;code>shadowsocks&lt;/code>.&lt;/p>
&lt;p>Порядок важен: если правилами не определено обратное, то &lt;code>sing-box&lt;/code> пойдет по транспортам сверху вниз, то есть
в нашем случае сначала он пойдет напрямую в интернет и лишь затем через Shadowsocks.&lt;/p>
&lt;p>Shadowsocks можно заменить на что угодно. Например, на XTLS-Reality:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;type&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;vless&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;tag&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;vless-out&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;your.server.example.com&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server_port&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">443&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;uuid&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;REDACTED&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;flow&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;xtls-rprx-vision&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;tls&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;enabled&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server_name&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;ya.ru&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;utls&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;enabled&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;reality&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;enabled&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;public_key&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;REDACTED&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;short_id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;REDACTED&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Или WireGuard:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;type&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;wireguard&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;tag&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;wireguard-out&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;REDACTED&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server_port&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">51820&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;system_interface&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;local_address&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;10.252.0.1/32&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;2600:xxxx:xxxx:cafe::1/128&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;private_key&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;REDACTED&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;peer_public_key&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;REDACTED&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;pre_shared_key&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;REDACTED&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>Наконец блок с правилами. На базе правил &lt;a href="https://antizapret.prostovpn.org/">проекта Antizapret&lt;/a> я создал
&lt;a href="https://github.com/savely-krasovsky/antizapret-sing-box">небольшую утилиту&lt;/a>, которая генерирует
&lt;code>sing-box&lt;/code>-совместимые списки в формате &lt;code>.srs&lt;/code> и выкладывает новые версии раз в сутки.&lt;/p>
&lt;p>С помощью этого &lt;code>rule_set&lt;/code> можно добавить два правила: одно в DNS, другое в роутинг.
Первое позволяет ресолвить через шифрованный DNS только заблокированные домены.
Второе позволяет роутить через Shadowsocks (или другой транспорт) только заблокированные домены и IP.&lt;/p>
&lt;p>Кэш, включенный в блоке &lt;code>&amp;quot;experimental&amp;quot;&lt;/code>, позволяет не загружать новый &lt;code>.srs&lt;/code>-файл при каждом подключении,
если он не изменился.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>Таким образом, в большинстве случаев вам совершенно не придется включать-выключать то, что мы называем VPN.&lt;/p>
&lt;h2 id="полный-конфиг">Полный конфиг&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;log&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;level&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;info&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;timestamp&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;dns&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;servers&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;tag&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;local-dns&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;address&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;local&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;detour&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;direct-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;tag&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;cloudflare-dns&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;address&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;https://1.1.1.1/dns-query&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;address_resolver&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;local-dns&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;detour&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;shadowsocks-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;rules&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;domain&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;your.server.example.com&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;local-dns&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;rule_set&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;antizapret&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;cloudflare-dns&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;inbounds&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;type&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;mixed&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;tag&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;mixed-in&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;listen&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;127.0.0.1&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;listen_port&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">1080&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;set_system_proxy&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;sniff&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;domain_strategy&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;prefer_ipv4&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;outbounds&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;type&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;direct&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;tag&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;direct-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;type&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;shadowsocks&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;tag&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;shadowsocks-out&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;your.server.example.com&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server_port&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">8443&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;method&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;YOUR-METHOD&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;password&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;YOUR-PASSWORD&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;type&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;dns&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;tag&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;dns-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;route&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;rules&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;rule_set&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;antizapret&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;outbound&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;shadowsocks-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;protocol&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;dns&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;outbound&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;dns-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;rule_set&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;tag&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;antizapret&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;type&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;remote&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;format&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;binary&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;url&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;https://github.com/savely-krasovsky/antizapret-sing-box/releases/latest/download/antizapret.srs&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;download_detour&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;shadowsocks-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;auto_detect_interface&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;experimental&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;cache_file&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;enabled&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h1 id="пример-конфига-vless--reality--сервера-youtube">Пример конфига VLESS + Reality + сервера Youtube&lt;/h1>
&lt;details>
&lt;summary>Полный конфиг&lt;/summary>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;log&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;level&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;info&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;timestamp&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;dns&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;servers&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;tag&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;local-dns&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;address&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;local&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;detour&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;direct-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;tag&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;cloudflare-dns&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;address&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;https://1.1.1.1/dns-query&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;address_resolver&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;local-dns&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;detour&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;vless-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;rules&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;domain&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;your.server.example.com&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;local-dns&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;rule_set&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;antizapret&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;cloudflare-dns&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;inbounds&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;type&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;tun&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;inet4_address&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;172.16.0.1/30&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;auto_route&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;strict_route&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;sniff&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;domain_strategy&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;prefer_ipv4&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;outbounds&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;type&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;direct&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;tag&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;direct-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;type&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;vless&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;tag&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;vless-out&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;your.server.example.com&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server_port&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">443&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;uuid&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;YOUR_UUID&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;flow&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;xtls-rprx-vision&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;tls&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;enabled&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server_name&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;ya.ru&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;utls&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;enabled&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;reality&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;enabled&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;public_key&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;YOUR_PUBLIC_KEY&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;short_id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;YOUR_SHORT_ID&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;type&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;dns&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;tag&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;dns-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;route&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;rules&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;rule_set&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;antizapret&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;outbound&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;vless-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;domain_suffix&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;.youtube.com&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;outbound&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;vless-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;domain_suffix&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;.googlevideo.com&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;outbound&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;vless-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;domain_suffix&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;.nhacmp3youtube.com&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;outbound&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;vless-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;domain_suffix&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;.1e100.net&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;outbound&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;vless-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;domain_suffix&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;.ytimg.com&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;outbound&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;vless-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;domain_suffix&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;.youtu.be&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;outbound&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;vless-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;domain_suffix&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;.google.com&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;outbound&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;vless-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;domain_suffix&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;.gvt1.com&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;outbound&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;vless-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;domain_suffix&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;.googleusercontent.com&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;outbound&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;vless-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;domain_suffix&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;.googleapis.com&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;outbound&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;vless-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;domain_suffix&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;.gstatic.com&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;outbound&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;vless-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;protocol&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;dns&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;outbound&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;dns-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;rule_set&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;type&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;remote&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;tag&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;antizapret&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;format&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;binary&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;url&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;https://github.com/savely-krasovsky/antizapret-sing-box/releases/latest/download/antizapret.srs&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;download_detour&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;vless-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;auto_detect_interface&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;experimental&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;cache_file&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;enabled&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/details></description></item><item><title>Simple Waybar module that checks Arch Linux system updates</title><link>https://krasovs.ky/2023/05/07/waybar-updates.html</link><pubDate>Sun, 07 May 2023 11:45:20 +0300</pubDate><author>savely@krasovs.ky (Savely Krasovsky)</author><guid>https://krasovs.ky/2023/05/07/waybar-updates.html</guid><description>&lt;p>I&amp;rsquo;ve &lt;a href="https://github.com/savely-krasovsky/waybar-updates">released&lt;/a> simple but yet effective module
for the &lt;a href="https://github.com/Alexays/Waybar">Waybar&lt;/a> that checks Arch Linux system updates.
There are some features that I think you would like.&lt;/p>
&lt;h2 id="features">Features&lt;/h2>
&lt;ul>
&lt;li>Sends notifications about updates.&lt;/li>
&lt;li>Supports GNU gettext localization (contribute new po-files!)&lt;/li>
&lt;li>Checks updates from AUR using Aurweb RPC, so works independently.&lt;/li>
&lt;li>Shows updates in the tooltip.&lt;/li>
&lt;li>Supports two states: &lt;code>pending-updates&lt;/code> and &lt;code>updated&lt;/code> to use different icons or hide module.&lt;/li>
&lt;li>Uses infinite loop to supply Waybar JSON updates.&lt;/li>
&lt;li>Configurable interval between checks.&lt;/li>
&lt;/ul>
&lt;p>You can easily install it from &lt;a href="https://aur.archlinux.org/packages/waybar-updates">AUR&lt;/a>: &lt;code>yay -S waybar-updates&lt;/code>&lt;/p>
&lt;p>I use it with this config:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&amp;#34;custom/pacman&amp;#34;&lt;/span>&lt;span class="err">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;format&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;{icon}{}&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;return-type&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;json&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;format-icons&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;pending-updates&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34; &amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;updated&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;exec-if&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;which waybar-updates&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;exec&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;waybar-updates&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In that case you will also need Nerd fonts (I personally use &lt;code>ttf-jetbrains-mono-nerd&lt;/code>).&lt;/p>
&lt;p>I&amp;rsquo;ve also added lite blinking effect to it:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-css" data-lang="css">&lt;span class="line">&lt;span class="cl">&lt;span class="p">@&lt;/span>&lt;span class="k">keyframes&lt;/span> &lt;span class="nt">blink-update&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">to&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">background-color&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">dodgerblue&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">#&lt;/span>&lt;span class="nn">custom-pacman&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">animation-timing-function&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">linear&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">animation-iteration-count&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">infinite&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">animation-direction&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">alternate&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">#&lt;/span>&lt;span class="nn">custom-pacman&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nc">pending-updates&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">animation-name&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">blink&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">update&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">animation-duration&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="kt">s&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="screenshots">Screenshots&lt;/h2>
&lt;p>&lt;img src="../waybar-updates-1.png" alt="">&lt;/p>
&lt;video class="video-shortcode" preload="auto" controls>
&lt;source src="../waybar-updates-2.webm" type="video/webm">
There should have been a video here but your browser does not seem
to support it.
&lt;/video>
&lt;p>If you like it, please consider to give it a star!&lt;/p></description></item><item><title>Flipper Zero: writing and debugging in CLion</title><link>https://krasovs.ky/2022/11/01/flipper-zero-clion.html</link><pubDate>Tue, 01 Nov 2022 00:00:00 +0000</pubDate><author>savely@krasovs.ky (Savely Krasovsky)</author><guid>https://krasovs.ky/2022/11/01/flipper-zero-clion.html</guid><description>&lt;p>A while ago I got my own &lt;a href="https://flipperzero.one/">Flipper Zero&lt;/a> and immediately tried to write own simple application.
Unfortunately they officially support only one editor — VS Code.&lt;/p>
&lt;p>I like JetBrains products and use them every day: from GoLand and PhpStorm to Rider and PyCharm. So why would I don&amp;rsquo;t
use CLion to write and debug Flipper Zero&amp;rsquo;s apps?&lt;/p>
&lt;p>CLion is a cross-platform IDE for C and C++ from JetBrains. And while it does support some features
for &lt;a href="https://www.jetbrains.com/help/clion/embedded-overview.html">embedded development&lt;/a>,
there are still some caveats, especially with debugging.&lt;/p>
&lt;h2 id="setup-core-functionality">Setup core functionality&lt;/h2>
&lt;p>CLion syntax highlighting and autocomplete engine works out of the box only with CMake, but it supports
&lt;a href="https://www.jetbrains.com/help/clion/compilation-database.html">compilation database&lt;/a>, which &lt;code>fbt&lt;/code> can generate.
So to start:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Clone Flipper Zero firmware repo:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git clone --recursive https://github.com/flipperdevices/flipperzero-firmware.git
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>Build firmware, FAPs and create compile database:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">./fbt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">./fbt faps
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">./fbt firmware_cdb
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>Copy &lt;code>compile_commands.json&lt;/code> from &lt;code>build/latest&lt;/code> to the project root.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Open this file with CLion.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Go and find &lt;code>compile_commands.json&lt;/code> file at &lt;code>build/latest&lt;/code> again, then click right mouse button and choose
&lt;code>Load Compilation Database Project&lt;/code>.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Remove &lt;code>compile_commands.json&lt;/code> from the project root.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Go to &lt;code>File -&amp;gt; Settings -&amp;gt; Build, Execution, Deployment -&amp;gt; Toolchains&lt;/code> and create toolkit:&lt;/p>
&lt;ul>
&lt;li>C Compiler: &lt;code>toolchain/x86_64-linux/bin/arm-none-eabi-gcc&lt;/code>&lt;/li>
&lt;li>С++ Compiler: &lt;code>toolchain/x86_64-linux/bin/arm-none-eabi-g++&lt;/code>&lt;/li>
&lt;li>Debugger: &lt;code>toolchain/x86_64-linux/bin/arm-none-eabi-gdb-py&lt;/code>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>It should try to sync a project at &lt;code>Build&lt;/code> tab successfully.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h3 id="possible-problems-and-their-solutions">Possible problems and their solutions&lt;/h3>
&lt;ul>
&lt;li>
&lt;p>CLion does not understand &lt;code>ccache&lt;/code>.&lt;/p>
&lt;p>&lt;strong>Solution 1:&lt;/strong> remove &lt;code>ccache&lt;/code> from system and regenerate compilation database.&lt;/p>
&lt;p>&lt;strong>Solution 2:&lt;/strong> just remove it from file:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd&lt;/span> built/target
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sed -i &lt;span class="s1">&amp;#39;s/ccache\ //g&amp;#39;&lt;/span> compile_commands.json
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>CLion cannot find stdlib.&lt;/p>
&lt;p>&lt;strong>Solution 1:&lt;/strong> Launch CLion under &lt;code>fbt&lt;/code> environment:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">source&lt;/span> scripts/toolchain/fbtenv.sh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">gtk-launch jetbrains-clion.desktop
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Solution 2:&lt;/strong> Replace path to compiler with absolute ones:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd&lt;/span> built/target
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sed -i &lt;span class="s1">&amp;#39;s/arm-none-eabi-gcc/\/home\/user\/documents\/flipperzero-firmware\/toolchain\/x86_64-linux\/bin\/arm-none-eabi-gсс/g&amp;#39;&lt;/span> compile_commands.json
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Solution 3:&lt;/strong> Install the latest &lt;code>arm-none-eabi&lt;/code> toolkit with your system package manager:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">sudo pacman -S arm-none-eabi-gcc arm-none-eabi-gdb arm-none-eabi-newlib
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ul>
&lt;p>After this troubleshooting CLion should work as expected: highlighting and autocompleting your code.&lt;/p>
&lt;h3 id="setup-debugging">Setup debugging&lt;/h3>
&lt;ol>
&lt;li>
&lt;p>Go to Run Configuration and create your own with type &lt;code>Remote Debug&lt;/code>:&lt;/p>
&lt;ul>
&lt;li>Pick debugger from toolchain you created before.&lt;/li>
&lt;li>Fill &lt;code>'target remote' args&lt;/code> with content from output of &lt;code>./fbt get_blackmagic&lt;/code>&lt;/li>
&lt;li>Point to symbol file: &lt;code>build/latest/firmware.elf&lt;/code>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Create a &lt;code>.gdbinit&lt;/code> file with this content in the project directory:&lt;/p>
&lt;pre tabindex="0">&lt;code>set confirm off
set trace-commands on
define target remote
target extended-remote $arg0
set mem inaccessible-by-default off
source debug/flipperapps.py
fap-set-debug-elf-root build/latest/.extapps
end
&lt;/code>&lt;/pre>&lt;/li>
&lt;li>
&lt;p>Then create a &lt;code>.gdbinit&lt;/code> file in your home directory:&lt;/p>
&lt;pre tabindex="0">&lt;code>set auto-load safe-path /path/to/your/project
&lt;/code>&lt;/pre>&lt;/li>
&lt;li>
&lt;p>Before first debug session you have to attach Flipper Zero:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">toolchain/x86_64-linux/bin/arm-none-eabi-gdb-py -q -ex &lt;span class="s2">&amp;#34;target remote `./fbt get_blackmagic`&amp;#34;&lt;/span> -ex &lt;span class="s2">&amp;#34;monitor swdp_scan&amp;#34;&lt;/span> -ex &lt;span class="s2">&amp;#34;attach 1&amp;#34;&lt;/span> -ex &lt;span class="s2">&amp;#34;quit&amp;#34;&lt;/span> build/latest/firmware.elf
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>Now you can set breakpoints and try to debug using the configuration you create. Ensure that your debugger
connects successfully, otherwise try to reboot Flipper and start again from step 4.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;em>(Optionally)&lt;/em> After successful session of debug you can edit your debug configuration and add in &amp;ldquo;Before launch&amp;rdquo;
block &amp;ldquo;External tool&amp;rdquo; to automate step 4.&lt;/p>
&lt;p>&lt;img src="../clion_external_tool.png" alt="">&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>UPD: 10 november 2022&lt;/strong>&lt;/p>
&lt;p>Guide has been updated after patches from Flipper Devices team! Now it should work with fewer tricks.&lt;/p>
&lt;p>&lt;strong>UPD: 25 april 2023&lt;/strong>&lt;/p>
&lt;p>Roman Beltiukov has pointed out in the comments about &lt;code>fap-set-debug-elf-root build/latest/.extapps&lt;/code> needed
to be added to the project&amp;rsquo;s &lt;code>.gdbinit&lt;/code> to debug fapps.&lt;/p></description></item><item><title>Telegram Web App bot: разбор и аспекты безопасности</title><link>https://krasovs.ky/2022/06/14/telegram-web-apps.html</link><pubDate>Tue, 14 Jun 2022 15:01:43 +0300</pubDate><author>savely@krasovs.ky (Savely Krasovsky)</author><guid>https://krasovs.ky/2022/06/14/telegram-web-apps.html</guid><description>&lt;p>С релизом нового обновления Telegram у многих возникли вопросы как правильно наладить общение &lt;code>бот &amp;lt;-&amp;gt; Telegram&lt;/code>,
&lt;code>бот &amp;lt;-&amp;gt; бэкенд&lt;/code> и сделать это безопасно. Для начала давайте проясним какие способы активации Telegram решил
предоставить пользователю:&lt;/p>
&lt;ol>
&lt;li>Через кнопку меню, которую можно настроить у &lt;code>@BotFather&lt;/code>.&lt;/li>
&lt;li>Через inline-кнопку.&lt;/li>
&lt;li>Через keyboard-кнопку.&lt;/li>
&lt;li>Через меню вложений.&lt;/li>
&lt;/ol>
&lt;p>&lt;img src="../telegram_web_app_buttons.jpg" alt="Виды кнопок">&lt;/p>
&lt;h2 id="кнопка-меню-inline-кнопка">Кнопка меню, inline-кнопка&lt;/h2>
&lt;p>Первый и второй способ предлагают нам аутентифицировать и авторизовать пользователя через специальный объект &lt;code>initData&lt;/code>,
который можно достать с помощью JavaScript. Объект имеет следующую структуру:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;query_id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;str&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;user&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;is_bot&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">false&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;first_name&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Pavel&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;last_name&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Durov&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;username&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;durov&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;language_code&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;ru&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;photo_url&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;https://telegram.org/durov.jpg&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;auth_date&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">1655210062&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;hash&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Проблема в том, что официальная документация хоть и предупреждает, но не особо объясняет зачем валидировать
поле &lt;code>initData&lt;/code> на сервере бота.&lt;/p>
&lt;p>&lt;strong>TL;DR&lt;/strong>&lt;/p>
&lt;p>Без валидации:&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>Мэллори:&lt;/strong> Привет Боб, я Алиса, дай мне информацию о балансе и сделай перевод на имя Мэллори.&lt;/p>
&lt;p>&lt;strong>Боб:&lt;/strong> Пожалуйста, Алиса, всё готово.&lt;/p>
&lt;/blockquote>
&lt;p>С валидацией:&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>Мэллори:&lt;/strong> Привет Боб, я Алиса, дай мне информацию о балансе и сделай перевод на имя Мэллори.&lt;/p>
&lt;p>&lt;strong>Боб:&lt;/strong> Предоставьте, пожалуйста, валидную подпись Алисы.&lt;/p>
&lt;p>&lt;em>Мэллори разводит руками&lt;/em>&lt;/p>
&lt;/blockquote>
&lt;p>То есть нужно это затем, чтобы произвести безопасную аутентификацию (проверку подлинности запроса) и авторизацию
(понять, что к боту пришла именно Алиса, а не Мэллори).&lt;/p>
&lt;p>Без этой валидации бот сможет предоставлять критически важную информацию (например, вы делаете онлайн-банкинг в боте)
просто по ID пользователя Telegram.&lt;/p>
&lt;p>Важно также понимать, что валидация должна происходить &lt;strong>исключительно&lt;/strong> на серверной части.
Валидация на клиентской части мало того, что бессмысленна, так ещё и скомпрометирует токен вашего бота.&lt;/p>
&lt;p>Валидация, к слову, не совсем тривиальная. Разработчики Telegram, как обычно, не поленились и вместо проверенного
стандарта JSON Web Token (JWT), реализовали свой собственный велосипед, да ещё и на базе обычного HMAC-SHA256
(то есть HS256 будь у нас JWT-токен). В результате &lt;code>initData&lt;/code> представляет собой URL-encoded
строку query-параметров. Для корректной валидации которой требуется следующая цепочка шагов:&lt;/p>
&lt;ol>
&lt;li>Декодируем строку, используя URL-encoding (важно, иначе значение с ключом &lt;code>user&lt;/code> останется не декодированным).&lt;/li>
&lt;li>Полученные пары ключ-значения сортируем в алфавитном порядке.&lt;/li>
&lt;li>Исключаем ключ &lt;code>hash&lt;/code>&lt;/li>
&lt;li>Из полученных пар составляем тело вида: &lt;code>auth_date=&amp;lt;auth_date&amp;gt;\nquery_id=&amp;lt;query_id&amp;gt;\nuser=&amp;lt;user&amp;gt;&lt;/code>. Важно сохранить значение с ключом &lt;code>user&lt;/code> в чистом JSON.&lt;/li>
&lt;li>Берем хэш от токена вашего бота с помощью алгоритма HMAC-SHA256 с ключом &lt;code>WebAppData&lt;/code>.&lt;/li>
&lt;li>Берем хэш от полученного в шаге 4 тела с помощью того же алгоритма, а в качестве ключа используем хэш, полученный ранее в виде последовательности &lt;strong>байтов&lt;/strong> (а не hex-репрезентации!).&lt;/li>
&lt;li>Преобразуем полученный хэш в hex-строку и сравниваем со значением ключа &lt;code>hash&lt;/code>.&lt;/li>
&lt;/ol>
&lt;p>По аналогии с JWT, если валидация прошла успешно, пользователя можно считать аутентифицированным
и переходить к авторизации с помощью предоставленного payload (в нашем случае это &lt;code>id&lt;/code> в объекте &lt;code>user&lt;/code>).&lt;/p>
&lt;p>Говоря о &lt;code>query_id&lt;/code>, который мы получаем в &lt;code>initData&lt;/code>. Используя это поле, мы можем создать в чате сообщение с ботом
от имени пользователя с бейджем &lt;code>via @your_bot&lt;/code>. Для этого потребуется вызвать метод &lt;a href="https://core.telegram.org/bots/api#answerwebappquery">answerWebAppQuery&lt;/a>.&lt;/p>
&lt;p>&lt;img src="../telegram_web_app_via.png" alt="Вид такого сообщения">&lt;/p>
&lt;div class="alert alert-success">
+ может использоваться для приложений любой сложности&lt;br/>
+ &lt;code>initData&lt;/code> по факту является полноценным stateless-токеном по типу JWT&lt;br/>
+ позволяет создавать сообщения от имени пользователя в чате с ботом с бейджем &lt;code>via @your_bot&lt;/code>&lt;br/>
&lt;/div>
&lt;div class="alert alert-error">
- требуется собственный бэкенд для веб-части для валидации &lt;code>initData&lt;/code> и работы с пользователем
&lt;/div>
&lt;h2 id="keyboard-кнопка">Keyboard-кнопка&lt;/h2>
&lt;p>С первым и вторым способом всё понятно: вы получаете от Telegram подобие готового токена
и поэтому реализация собственной аутентификации и авторизации не требуется, требуется только валидация.&lt;/p>
&lt;p>Но с третьим способом ситуация с одной стороны проще, с другой сложней. Дело в том, что &lt;code>initData&lt;/code> не приходит
и наладить общение с серверной частью не выйдет. Ведь вы не будете знать кто к вам пришёл.&lt;/p>
&lt;p>Однако при использовании этого способа появляется возможность использовать метод &lt;code>Telegram.WebApp.sendData()&lt;/code>,
который позволяет отправить сообщение боту напрямую, а тот предоставит его вам через long-polling или вебхуки.
Стоит учесть, что после успешного выполнения веб-окно автоматически закроется, а бот отрапортует сервисным сообщением
&lt;code>Вы успешно передали данные боту кнопкой «Test button».&lt;/code>&lt;/p>
&lt;p>Поэтому Telegram позиционирует этот способ как удобный способ сделать гибкую веб-форму ввода с полями
типа &lt;code>date picker&lt;/code>. Вернуть значения формы можно с помощью метода &lt;code>Telegram.WebApp.sendData()&lt;/code>.&lt;/p>
&lt;p>Нужно понимать, что в JS-файле этот метод является лишь прослойкой,
само значение, переданное в &lt;code>sendData()&lt;/code> отправляются далее через
&lt;a href="https://github.com/tdlib/td/blob/047246f366d94b55ea7b6b93b3a4baa9a3380154/td/generate/scheme/td_api.tl#L4968">MTProto-метод&lt;/a>
&lt;code>sendWebAppData&lt;/code>. Методы MTProto невозможно использовать без авторизации в Telegram, поэтому тут мессенджер берет
безопасность полностью на себя.&lt;/p>
&lt;p>В этом заключается плюс этого метода.&lt;/p>
&lt;div class="alert alert-success">
+ удобно для заполнения сравнительно простых форм ввода&lt;br/>
+ наличие собственного бэкенда для Web-части не требуется&lt;br/>
&lt;/div>
&lt;div class="alert alert-error">
- &lt;code>initData&lt;/code> не приходит, возможность авторизовать пользователя на своём бэкенде (даже если он есть) отсутствует&lt;br/>
- отправить информацию боту можно только 1 раз
&lt;/div>
&lt;h2 id="кнопка-в-меню-вложений">Кнопка в меню вложений&lt;/h2>
&lt;p>Есть также четвертый способ, который технически не отличается от первого и второго
(только дополнительными полями в &lt;code>initData&lt;/code>), но в этом случае бот добавляется
в меню вложений.&lt;/p>
&lt;p>К сожалению эта возможность пока что доступна только для тех, кто участвует в рекламной платформе Telegram
и, следовательно, внёс залог 2 миллиона евро. Поэтому пока что говорить тут особо не о чем.
Из известных мне публичных ботов такую интеграцию использует &lt;a href="https://t.me/wallet">@wallet&lt;/a>.&lt;/p>
&lt;p>Основной плюс — возможность использовать бота не только в личной переписке с ботом.
Например, вышеупомянутый @wallet позволяет отправить любому собеседнику сообщение с информацией о переводе,
собеседнику остается лишь нажать и получить свой перевод.&lt;/p>
&lt;p>&lt;img src="../telegram_web_app_wallet.png" alt="Вид такого сообщения">&lt;/p>
&lt;div class="alert alert-success">
+ плюсы первых двух способов&lt;br/>
+ возможность использовать бота в переписке с человеком&lt;br/>
+ новый интуитивный механизм использования ботов Telegram
&lt;/div>
&lt;div class="alert alert-error">
- минусы первых двух способов&lt;br/>
- необходимо стать крупным рекламодателем на площадке Telegram
&lt;/div></description></item><item><title>Ещё более изощренный обход блокировок с помощью Shadowsocks + V2Ray + Cloudflare</title><link>https://krasovs.ky/2022/03/19/shadowsocks-and-v2ray-and-cloudflare.html</link><pubDate>Sat, 19 Mar 2022 00:00:00 +0000</pubDate><author>savely@krasovs.ky (Savely Krasovsky)</author><guid>https://krasovs.ky/2022/03/19/shadowsocks-and-v2ray-and-cloudflare.html</guid><description>&lt;p>В прошлой статье я разобрал вариант с Cloak, однако меня не устроила умеренная сложность конфигурации
клиентской части, а также меньшая популярность и, следовательно, развитие проекта по сравнению с V2Ray.&lt;/p>
&lt;p>Использование Cloudflare в описанном ниже способе позволило повысить пропускную способность канала.
На Нидерландском сервере я получил в районе 450 мегабит через Cloudflare, вместо 250-300 напрямую с Cloak.&lt;/p>
&lt;h1 id="план">План&lt;/h1>
&lt;p>Весь трафик завернуть на Cloudflare, который отправит его к нам на VPS. Сдобрить обфускацией от V2Ray и сам сервер
спрятать под видом совершенно безобидного ресурса.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th style="text-align:center">&lt;img src="../ss_v2ray_cf.png" alt="">&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td style="text-align:center">&lt;em>На практике это будет выглядеть как-то так&lt;/em>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2 id="ингредиенты">Ингредиенты&lt;/h2>
&lt;ol>
&lt;li>VPS в Европе.&lt;/li>
&lt;li>Домен в любой зоне (желательно не &lt;code>.ru&lt;/code>/&lt;code>.su&lt;/code>/&lt;code>.рф&lt;/code>)&lt;/li>
&lt;li>Аккаунт на Cloudflare.&lt;/li>
&lt;li>&lt;a href="https://github.com/shadowsocks/shadowsocks-rust">shadowsocks-rust&lt;/a>.&lt;/li>
&lt;li>&lt;a href="https://github.com/teddysun/v2ray-plugin">v2ray-plugin&lt;/a> (лучше использовать форк, там свежий &lt;code>v2ray-core&lt;/code>).&lt;/li>
&lt;li>HTTP-сервер, nginx в нашем случае.&lt;/li>
&lt;li>SSL-сертификат полученный от Let&amp;rsquo;s Encrypt или непосредственно Cloudflare.&lt;/li>
&lt;/ol>
&lt;h2 id="рецепт">Рецепт&lt;/h2>
&lt;ol>
&lt;li>Ставим в систему shadowsocks-rust и v2ray-plugin, сконфигурировать их легко вот таким конфигом в
&lt;code>/etc/shadowsocks-rust/v2ray.json&lt;/code>:&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;localhost&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server_port&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">8443&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;method&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;chacha20-ietf-poly1305&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;password&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;yourpass&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;plugin&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;v2ray-plugin&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;plugin_opts&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;server&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="2">
&lt;li>Создаём для Shadowsocks systemd-сервис по аналогии с &lt;a href="../2022/03/08/shadowsocks-and-cloak.html">прошлой статьёй&lt;/a>
(пункты 5-7).&lt;/li>
&lt;li>Получаем сертификат через &lt;code>certbot&lt;/code> или &lt;a href="https://developers.cloudflare.com/ssl/origin-configuration/origin-ca/">через Cloudflare&lt;/a>.
Детально расписывать не буду, инструкций в интернете масса.&lt;/li>
&lt;li>Ставим nginx, заводим следующий конфиг в &lt;code>/etc/nginx/sites-available/v2ray&lt;/code>:&lt;/li>
&lt;/ol>
&lt;pre tabindex="0">&lt;code>server {
listen 80;
server_name _;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name yourdomain.wtf;
ssl_certificate /etc/letsencrypt/live/yourdomain.wtf/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.wtf/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/yourdomain.wtf/chain.pem;
# Здесь можно проксировать запросы на какой-нибудь весёлый сайт
location / {
proxy_pass https://innocent.domain.lol;
}
# Локацию можно сделать длинной, чтобы её никто не смог угадать.
location /v2ray {
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection &amp;#34;upgrade&amp;#34;;
proxy_http_version 1.1;
proxy_buffering off;
proxy_redirect off;
proxy_pass http://localhost:8443/;
}
}
&lt;/code>&lt;/pre>&lt;p>Не забудьте сделать symlink и перезагрузить nginx:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># ln -s /etc/nginx/sites-available/v2ray /etc/nginx/sites-enabled/v2ray&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># systemctl reload nginx&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="5">
&lt;li>Заходим в Cloudflare в раздел DNS, создаём A-запись, указывающую на ваш сервер, оставляем Proxy &lt;strong>включенным&lt;/strong>.&lt;/li>
&lt;li>В разделе SSL/TLS включаем режим &lt;code>Full (strict)&lt;/code>, минимальную версию TLS можно повысить до 1.2/1.3
в зависимости от поддержки актуальных протоколов вашими устройствами.&lt;/li>
&lt;li>Наконец настроим клиент:&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;yourdomain.wtf&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server_port&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">443&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;method&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;chacha20-ietf-poly1305&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;password&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;yourpass&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;plugin&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;v2ray-plugin&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;plugin_opts&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;tls;host=yourdomain.wtf;path=/v2ray&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;local_address&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;localhost&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;local_port&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">1080&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="рекомендации">Рекомендации&lt;/h2>
&lt;p>Опционально можно прокачать производительность, и увеличить безопасность. Максимальное количество файлов рассчитано
по формуле 1 ядро = 65536 файловых дескриптора.&lt;/p>
&lt;details>
&lt;summary>/etc/sysctl.d/20-shadowsocks.conf&lt;/summary>
&lt;pre tabindex="0">&lt;code># options for shadowsocks
fs.file-max = 262144
net.core.rmem_max = 8388608
net.core.wmem_max = 8388608
net.core.rmem_default = 8388608
net.core.wmem_default = 8388608
net.core.optmem_max = 8388608
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 262144
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_mem = 25600 51200 102400
net.ipv4.tcp_rmem = 4096 1048576 4194304
net.ipv4.tcp_wmem = 4096 1048576 4194304
net.ipv4.tcp_fastopen=3
net.ipv4.tcp_low_latency = 1
net.ipv4.tcp_no_metrics_save = 1
net.ipv4.tcp_adv_win_scale = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_keepalive_time = 150
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_slow_start_after_idle=0
net.ipv4.tcp_max_syn_backlog = 65536
net.ipv4.tcp_max_tw_buckets = 720000
net.ipv4.tcp_mtu_probing = 1
&lt;/code>&lt;/pre>&lt;/details>
&lt;details>
&lt;summary>/etc/nginx/nginx.conf&lt;/summary>
&lt;pre tabindex="0">&lt;code>user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 4096;
multi_accept on;
use epoll;
epoll_events 512;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 60;
client_body_timeout 12;
client_header_timeout 12;
send_timeout 30;
keepalive_requests 2000;
reset_timedout_connection on;
types_hash_max_size 2048;
server_tokens off;
server_names_hash_max_size 4096;
client_body_buffer_size 128K;
client_header_buffer_size 3m;
client_body_in_single_buffer on;
client_max_body_size 8m;
large_client_header_buffers 4 256k;
open_file_cache max=200000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
include /etc/nginx/whitelist.conf;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_stapling on;
ssl_stapling_verify on;
##
# Logging Settings
##
#access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log crit;
##
# Gzip Settings
##
gzip off;
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
&lt;/code>&lt;/pre>&lt;/details>
&lt;details>
&lt;summary>/etc/nginx/whitelist.conf&lt;/summary>
&lt;pre tabindex="0">&lt;code>allow 173.245.48.0/20;
allow 103.21.244.0/22;
allow 103.22.200.0/22;
allow 103.31.4.0/22;
allow 141.101.64.0/18;
allow 108.162.192.0/18;
allow 190.93.240.0/20;
allow 188.114.96.0/20;
allow 197.234.240.0/22;
allow 198.41.128.0/17;
allow 162.158.0.0/15;
allow 104.16.0.0/13;
allow 104.24.0.0/14;
allow 172.64.0.0/13;
allow 131.0.72.0/22;
allow 2400:cb00::/32;
allow 2606:4700::/32;
allow 2803:f800::/32;
allow 2405:b500::/32;
allow 2405:8100::/32;
allow 2a06:98c0::/29;
allow 2c0f:f248::/32;
deny all;
&lt;/code>&lt;/pre>&lt;/details>
&lt;details>
&lt;summary>/etc/security/limits.conf&lt;/summary>
&lt;p>Добавляем:&lt;/p>
&lt;pre tabindex="0">&lt;code>session required pam_limits.so
&lt;/code>&lt;/pre>&lt;/details>
&lt;details>
&lt;summary>/etc/security/limits.conf&lt;/summary>
&lt;p>Добавляем:&lt;/p>
&lt;pre tabindex="0">&lt;code>* soft nofile 262144
* hard nofile 262144
&lt;/code>&lt;/pre>&lt;/details>
&lt;details>
&lt;summary>/etc/shadowsocks-rust/v2ray.json&lt;/summary>
&lt;p>Конфигурацию v2ray можно привести к следующему виду:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;localhost&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server_port&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">8443&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;password&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;yourpass&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;method&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;chacha20-ietf-poly1305&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;timeout&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">7200&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;no_delay&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;nofile&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">262144&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;fast_open&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;plugin&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;v2ray-plugin&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;plugin_opts&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;server&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/details></description></item><item><title>Обход блокировок с помощью Shadowsocks + Cloak</title><link>https://krasovs.ky/2022/03/08/shadowsocks-and-cloak.html</link><pubDate>Tue, 08 Mar 2022 00:00:00 +0000</pubDate><author>savely@krasovs.ky (Savely Krasovsky)</author><guid>https://krasovs.ky/2022/03/08/shadowsocks-and-cloak.html</guid><description>&lt;p>В свете последних событий и угрозы наступления пресловутого Чебурнета нам видимо придётся прибегнуть к китайскому опыту
обхода блокировок. На мой взгляд связка Shadowsocks + Cloak позволяет довольно элегантно замаскировать весь трафик под
обычные HTTPS-соединения к ресурсу, который не заблокирован в стране (например Яндекс).&lt;/p>
&lt;p>Используя Raspberry Pi 4B, заказанную у известного хостера, я получил около 450 мегабит на загрузку и 550 на отдачу.
Эта скорость вероятно ограничена производительностью непосредственно Raspberry, с нормальным x86-сервером результаты
должны быть даже лучше.&lt;/p>
&lt;h2 id="собственно-инструкция">Собственно инструкция&lt;/h2>
&lt;ol>
&lt;li>Скачиваем последние версии
&lt;a href="https://github.com/shadowsocks/shadowsocks-rust">shadowsocks-rust&lt;/a> и &lt;a href="https://github.com/cbeuw/Cloak">Cloak&lt;/a>
из раздела релизов. Кладём их, например, в &lt;code>/usr/local/bin&lt;/code>. Ниже лишь пример, ваш сервер может иметь другую архитектуру.&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ curl -LO https://github.com/shadowsocks/shadowsocks-rust/releases/download/v1.14.1/shadowsocks-v1.14.1.x86_64-unknown-linux-gnu.tar.xz
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ curl -LO https://github.com/cbeuw/Cloak/releases/download/v2.5.5/ck-client-linux-amd64-v2.5.5
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ tar -xvf shadowsocks-v1.14.1.x86_64-unknown-linux-gnu.tar.xz
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ sudo mv ss* /usr/local/bin
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ sudo mv ck-client-linux-amd64-v2.5.5 /usr/local/bin/ck-client
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="2">
&lt;li>Конфигурируем сервер shadowsocks примерно следующим образом:&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># nano /etc/shadowsocks-rust/cloak.json&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;localhost&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server_port&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">8388&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;method&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;chacha20-ietf-poly1305&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;password&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;yourpass&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;timeout&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">7200&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;nofile&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">10240&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;plugin&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;ck-server&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;plugin_opts&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;/etc/shadowsocks-rust/ckserver.json&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="3">
&lt;li>Генерируем с помощью &lt;code>ck-server&lt;/code> UID и пару ключей, записываем их куда-нибудь:&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ ck-server -u
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ ck-server -key
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="4">
&lt;li>Конфигурируем сервер Cloak примерно следующим образом, используем значения, полученные ранее:&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># nano /etc/shadowsocks-rust/ckserver.json&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;RedirAddr&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;www.yandex.ru&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;BindAddr&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;:443&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="s2">&amp;#34;:80&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;ProxyBook&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;shadowsocks&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;tcp&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;localhost:8388&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;PrivateKey&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;privkey_from_previous_step&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;BypassUID&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;uid_from_previous_step&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="5">
&lt;li>В качестве меры безопасности режем права. К сожалению на &lt;code>ckserver.json&lt;/code> нельзя накинуть 0600,
иначе процесс не сможет прочитать файл, однако основной пароль будет надёжно защищён.&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># chmod 0644 /etc/shadowsocks-rust/ckserver.json&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># chmod 0600 /etc/shadowsocks-rust/cloak.json&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="6">
&lt;li>Создаём безопасный systemd-сервис для Shadowsocks (Cloak будет запускаться сам, как плагин):&lt;/li>
&lt;/ol>
&lt;pre tabindex="0">&lt;code># nano /etc/systemd/system/shadowsocks-rust-server@.service
&lt;/code>&lt;/pre>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>Unit&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">Description&lt;/span>&lt;span class="o">=&lt;/span>Shadowsocks-Rust Server Service
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">After&lt;/span>&lt;span class="o">=&lt;/span>network.target
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">Wants&lt;/span>&lt;span class="o">=&lt;/span>network-online.target
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>Service&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">Type&lt;/span>&lt;span class="o">=&lt;/span>simple
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">DynamicUser&lt;/span>&lt;span class="o">=&lt;/span>yes
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">CapabilityBoundingSet&lt;/span>&lt;span class="o">=&lt;/span>CAP_NET_BIND_SERVICE
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">AmbientCapabilities&lt;/span>&lt;span class="o">=&lt;/span>CAP_NET_BIND_SERVICE
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">LoadCredential&lt;/span>&lt;span class="o">=&lt;/span>%i.json:/etc/shadowsocks-rust/%i.json
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">ExecStart&lt;/span>&lt;span class="o">=&lt;/span>/usr/local/bin/ssservice server --log-without-time -c &lt;span class="si">${&lt;/span>&lt;span class="nv">CREDENTIALS_DIRECTORY&lt;/span>&lt;span class="si">}&lt;/span>/%i.json
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>Install&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">WantedBy&lt;/span>&lt;span class="o">=&lt;/span>multi-user.target
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="7">
&lt;li>Включаем и запускаем сервис shadowsocks:&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># systemctl daemon-reload&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># systemctl enable shadowsocks-rust-server@cloak.service&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># systemctl start shadowsocks-rust-server@cloak.service&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="8">
&lt;li>Наконец конфигурируем клиент Cloak на хосте (им может быть ПК, Мак, смартфон):&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;yourdomain.wtf&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server_port&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">443&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;method&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;chacha20-ietf-poly1305&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;password&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;yourpass&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;plugin&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;ck-client&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;plugin_opts&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;UID=uid_from_previous_step;ProxyMethod=shadowsocks;PublicKey=pubkey_from_previous_step;EncryptionMethod=plain;ServerName=www.yandex.ru;AlternativeNames=mail.ru,vk.com&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;local_address&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;localhost&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;local_port&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">1080&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="дополнительные-советы">Дополнительные советы&lt;/h2>
&lt;h3 id="firewall">Firewall&lt;/h3>
&lt;p>Если есть файрволл, то необходимо открыть на нём два порта: 80 и 443.&lt;/p>
&lt;h3 id="удобный-uri-для-передачи-настроек">Удобный URI для передачи настроек&lt;/h3>
&lt;p>Также для удобства можно сделать URI, который позволяет передавать быстро всю конфигурацию в виде одной строчки:&lt;/p>
&lt;pre tabindex="0">&lt;code>ss:// + base64encode(&amp;#34;chacha20-ietf-poly1305:yourpass&amp;#34;) + @yourdomain.org:443?plugin= + urlencode(&amp;#34;ck-client;UID=uid_from_previous_step;ProxyMethod=shadowsocks;PublicKey=pubkey_from_previous_step;EncryptionMethod=plain;ServerName=www.yandex.ru;AlternativeNames=mail.ru,vk.com&amp;#34;)
&lt;/code>&lt;/pre>&lt;p>Другими словами финальный URI будет выглядеть так:&lt;/p>
&lt;pre tabindex="0">&lt;code>ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTp5b3VycGFzcw@yourdomain.org:443?plugin=ck-client%3BUID%3Duid_from_previous_step%3BProxyMethod%3Dshadowsocks%3BPublicKey%3Dpubkey_from_previous_step%3BEncryptionMethod%3Dplain%3BServerName%3Dwww.yandex.ru%3BAlternativeNames%3Dmail.ru%2Cvk.com
&lt;/code>&lt;/pre>&lt;p>Этот URI поддерживается многими приложениями, включая &lt;a href="https://apps.apple.com/ru/app/shadowrocket/id932747118">Shadowrocket на iOS&lt;/a>.
Покупайте, кстати, пока ещё можно.&lt;/p>
&lt;h3 id="хостинг-настроек">Хостинг настроек&lt;/h3>
&lt;p>Сообществом был принят стандарт &lt;a href="https://shadowsocks.org/en/wiki/SIP008-Online-Configuration-Delivery.html">SIP008&lt;/a>,
который позволяет автоматически скачивать настройки с помощью JSON-файла, размещённого на веб-сервере. Структура файла
выглядит примерно так:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;version&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;servers&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;27b8a625-4f4b-4428-9f0f-8a2317db7c79&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;remarks&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Name of the server&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;yourdomain.wtf&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;server_port&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">443&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;method&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;chacha20-ietf-poly1305&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;password&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;yourpass&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;plugin&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;ck-client&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;plugin_opts&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;UID=uid_from_previous_step;ProxyMethod=shadowsocks;PublicKey=pubkey_from_previous_step;EncryptionMethod=plain;ServerName=www.yandex.ru;AlternativeNames=mail.ru,vk.com&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Серверов, очевидно, может быть несколько. Многие приложения поддерживают данный способ конфигурации.&lt;/p></description></item><item><title>Wireguard's AllowedIPs calculator</title><link>https://krasovs.ky/2021/07/04/wireguard-allowed-ips.html</link><pubDate>Sun, 04 Jul 2021 00:00:00 +0000</pubDate><author>savely@krasovs.ky (Savely Krasovsky)</author><guid>https://krasovs.ky/2021/07/04/wireguard-allowed-ips.html</guid><description>&lt;p>As you possibly know Wireguard hasn&amp;rsquo;t something like &amp;ldquo;DisallowedIPs&amp;rdquo; parameter
to exclude some networks from allowed ones. Of course technically AllowedIPs is enough,
but I am tired to calculate it by hand, so created this simple calculator:&lt;/p>
&lt;style>
#calculator {
display: grid;
grid-template-columns: fit-content(0) auto;
gap: .5rem
}
#calculate-button {
grid-column: 2;
}
#use-api-wrapper {
grid-column: 2;
}
#final-allowed-ips {
grid-column: 1 / 3;
margin-top: .5rem;
margin-bottom: 0;
}
&lt;/style>
&lt;script src="../wasm_exec.js">&lt;/script>
&lt;script src="../wireguard.js">&lt;/script>
&lt;form id="calculator">
&lt;label for="allowed-ips">AllowedIPs:&lt;/label>
&lt;input id="allowed-ips" type="text"/>
&lt;label for="disallowed-ips">DisallowedIPs:&lt;/label>
&lt;input id="disallowed-ips" type="text"/>
&lt;div id="use-api-wrapper">
&lt;input id="use-api" type="checkbox" onclick="document.getElementById('calculate-button').disabled = false;"/>
&lt;label for="use-api">Use API instead of WASM&lt;/label>
&lt;/div>
&lt;input type="submit" id="calculate-button" value="Calculate" disabled/>
&lt;div hidden id="final-allowed-ips" class="alert">AllowedIPs = &lt;/div>
&lt;/form>
&lt;p>&lt;strong>Update:&lt;/strong> I am using small Golang HTTP-server to quickly calculate results and at first I tried
&lt;a href="https://github.com/mikioh/ipaddr">ipaddr&lt;/a> due to its similarity to the Python
&lt;a href="https://docs.python.org/3/library/ipaddress.html">ipaddress&lt;/a>. But it has &lt;em>a little problem&lt;/em>,
in my case it caused an infinite loop that led to DoS and finally to panic.
Better use the brilliant &lt;a href="https://inet.af/netaddr">netaddr&lt;/a> developed by
&lt;a href="https://github.com/bradfitz">Brad Fitzpatrick&lt;/a> and the Tailscale team
(their &lt;a href="https://tailscale.com/blog/netaddr-new-ip-type-for-go/">blogpost&lt;/a> with motivation)&lt;/p>
&lt;p>&lt;strong>Update 2:&lt;/strong> I realized that this is a great case to use WASM!&lt;/p>
&lt;p>&lt;strong>Update 3:&lt;/strong> For some reason I didn&amp;rsquo;t publish source code right after this blog post was written.
In 2023, I thought I lost it forever, but randomly found it in my backup files.
WASM sources &lt;a href="https://git.sr.ht/~lord/wireguard-allowed-ips">here&lt;/a>.
HTTP API mini server sources are probably still lost :(&lt;/p></description></item><item><title>Simple Certificate Authority: how-to</title><link>https://krasovs.ky/2021/05/11/certificate-authority-how-to.html</link><pubDate>Tue, 11 May 2021 00:00:00 +0000</pubDate><author>savely@krasovs.ky (Savely Krasovsky)</author><guid>https://krasovs.ky/2021/05/11/certificate-authority-how-to.html</guid><description>&lt;p>This post is just an example of how to create a simple CA and issue a TLS certificate.
I will deliberately not give any explanations, because the Internet has been full of them for a long time.&lt;/p>
&lt;p>It also frustrates me that people like to just copy and paste configurations and
don&amp;rsquo;t realize that tons of parameters are just not needed for their needs.
In my case I tried to keep it as simple as possible.&lt;/p>
&lt;p>So create three files:&lt;/p>
&lt;p>&lt;code>ca.cnf:&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>req&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">distinguished_name&lt;/span> &lt;span class="o">=&lt;/span> req_distinguished_name
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">req_extensions&lt;/span> &lt;span class="o">=&lt;/span> v3_req
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">prompt&lt;/span> &lt;span class="o">=&lt;/span> no
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># You can remove this if you don&amp;#39;t use non-ASCII symbols&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">utf8&lt;/span> &lt;span class="o">=&lt;/span> yes
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>req_distinguished_name&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">C&lt;/span> &lt;span class="o">=&lt;/span> RU
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">CN&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;Savely Krasovsky&amp;#39;s CA&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>v3_req&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">keyUsage&lt;/span> &lt;span class="o">=&lt;/span> digitalSignature
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>tls.cnf:&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>req&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">distinguished_name&lt;/span> &lt;span class="o">=&lt;/span> req_distinguished_name
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">prompt&lt;/span> &lt;span class="o">=&lt;/span> no
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">utf8&lt;/span> &lt;span class="o">=&lt;/span> yes
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>req_distinguished_name&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">C&lt;/span> &lt;span class="o">=&lt;/span> RU
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">CN&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;Savely Krasovsky&amp;#39;s LAN&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>tls.ext:&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="nv">keyUsage&lt;/span> &lt;span class="o">=&lt;/span> digitalSignature, keyEncipherment
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">extendedKeyUsage&lt;/span> &lt;span class="o">=&lt;/span> serverAuth
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">subjectAltName&lt;/span> &lt;span class="o">=&lt;/span> @alt_names
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>alt_names&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">DNS.1 &lt;span class="o">=&lt;/span> home.local
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">DNS.2 &lt;span class="o">=&lt;/span> *.home.local
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now execute this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Generate CA cert&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">openssl ecparam -name prime256v1 -genkey -out ca.key
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">openssl req -new -key ca.key -config ca.cnf -out ca.csr
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">openssl x509 -req -days &lt;span class="m">3650&lt;/span> -in ca.csr -signkey ca.key -out ca.crt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Generate TLS cert&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">openssl ecparam -name prime256v1 -genkey -out tls.key
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">openssl req -new -key tls.key -config tls.cnf -out tls.csr
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">openssl x509 -req -in tls.csr -CA ca.crt -CAkey ca.key -out tls.crt -days &lt;span class="m">365&lt;/span> -extfile tls.ext
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Of course, you can create not only TLS certs, this is just the simplest case.
Play with the &lt;code>tls.ext&lt;/code> (especially &lt;code>keyUsage&lt;/code> and &lt;code>extendedKeyUsage&lt;/code> parameters)
file to issue another certificate.&lt;/p>
&lt;p>For example this is mTLS compatible client cert:&lt;/p>
&lt;p>&lt;code>personal.cnf:&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>req&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">distinguished_name&lt;/span> &lt;span class="o">=&lt;/span> req_distinguished_name
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">prompt&lt;/span> &lt;span class="o">=&lt;/span> no
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">utf8&lt;/span> &lt;span class="o">=&lt;/span> yes
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>req_distinguished_name&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">C&lt;/span> &lt;span class="o">=&lt;/span> RU
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">CN&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;Savely Krasovsky&amp;#39;s LAN&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>personal.ext:&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="nv">keyUsage&lt;/span> &lt;span class="o">=&lt;/span> critical,digitalSignature
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">extendedKeyUsage&lt;/span> &lt;span class="o">=&lt;/span> clientAuth
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">subjectKeyIdentifier&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">hash&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Generation:&lt;/p>
&lt;pre tabindex="0">&lt;code>openssl ecparam -name prime256v1 -genkey -out personal.key
openssl req -new -key personal.key -config personal.cnf -out personal.csr
openssl x509 -req -in personal.csr -CA ca.crt -CAkey ca.key -out personal.crt -days 365 -extfile personal.ext
# Convert to convenient PKCS#12 certificate there key and cert itself are combined
openssl pkcs12 -export -out personal.pfx -inkey personal.key -in personal.crt
&lt;/code>&lt;/pre></description></item><item><title>Checkpoint SNX adventure: isolating the proprietary in it own box</title><link>https://krasovs.ky/2021/04/26/checkpoint-snx-adventure.html</link><pubDate>Mon, 26 Apr 2021 00:00:00 +0000</pubDate><author>savely@krasovs.ky (Savely Krasovsky)</author><guid>https://krasovs.ky/2021/04/26/checkpoint-snx-adventure.html</guid><description>&lt;p>My company uses Checkpoint products as a VPN solution. In case of Windows and macOS
there is Checkpoint Endpoint Security. In case of Linux we have to use whatever
called Checkpoint SSL Network Extender or just Checkpoint SNX.&lt;/p>
&lt;p>As far as I got, it encapsulates traffic into HTTPS connection between you and
VPN gateway and provides TUN interface. Sounds okay on paper, right?&lt;/p>
&lt;p>But as you know, proprietary software has something in common: the quality of Linux support generally sucks.
Checkpoint SNX is not an exception.&lt;/p>
&lt;p>Just read their &lt;a href="https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&amp;amp;solutionid=sk65210">support page&lt;/a>.
The distros they consider relevant in 2021: &lt;em>Ubuntu 17.04&lt;/em>, &lt;em>Fedora 18&lt;/em>, &lt;em>openSUSE 12.2&lt;/em>. Okay, cool.&lt;/p>
&lt;p>The shitty quality of Linux solution itself wasn&amp;rsquo;t the main reason to isolate it.
Gateways like this are pushing settings from the server including routes, usually
there is no way to somehow reconfigure this.&lt;/p>
&lt;p>In my case, the company decided that split tunneling isn&amp;rsquo;t secure. It means while I am connected and
trying to reach corporate resources, I cannot reach the Internet without corporate proxy and vice versa.&lt;/p>
&lt;p>So I had an idea: it would be nice to just share Checkpoint VPN connection with other computers.&lt;/p>
&lt;p>Particularly I wanted to:&lt;/p>
&lt;ol>
&lt;li>Completely isolate Checkpoint SNX inside Linux VM.&lt;/li>
&lt;li>Use WireGuard tunnels to share VPN connection.&lt;/li>
&lt;li>At client-side use only one simple route: &lt;code>10.0.0.0/8&lt;/code>.&lt;/li>
&lt;/ol>
&lt;p>Why WireGuard? I could just use IP forwarding and NAT tweaks, but it would only work
within a particular LAN and I would have to create and delete route
and change DNS servers every time manually.&lt;/p>
&lt;p>Let&amp;rsquo;s get started.&lt;/p>
&lt;h2 id="install-checkpoint-snx">Install Checkpoint SNX&lt;/h2>
&lt;p>You can download SNX installer from your company&amp;rsquo;s VPN portal:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ curl https://example.org/SNX/INSTALL/snx_install.sh -o snx_install.sh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># OR&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ curl https://example.org/sslvpn/SNX/INSTALL/snx_install.sh -o snx_install.sh
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>There is also a way to install the latest version from Checkpoint site, but I don&amp;rsquo;t recommend it,
your company could use different version.&lt;/p>
&lt;p>While the first part of script is just a bash script, the second part contains an archive with the binaries.
The binaries are &lt;code>x86&lt;/code> (not &lt;code>x86-64&lt;/code>), so you need to enable multiarch and install dependencies.&lt;/p>
&lt;pre tabindex="0">&lt;code># ldd /usr/bin/snx
...
libX11.so.6 =&amp;gt; /usr/lib32/libX11.so.6
libpam.so.0 =&amp;gt; /usr/lib32/libpam.so.0 (0xf7d3d000)
libstdc++.so.5 =&amp;gt; /usr/lib32/libstdc++.so.5 (0xf7c5c000)
...
&lt;/code>&lt;/pre>&lt;p>So you need to install three libraries: &lt;code>libX11&lt;/code>, &lt;code>libpam&lt;/code>, &lt;code>libstdc++&lt;/code>.
In various distros you need to use various names, but you can easily google it.&lt;/p>
&lt;p>Finally, just install it:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ chmod +x snx_install.sh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ sudo ./snx_install.sh
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Back to your browser and try to connect using the portal.
A while back you needed a browser that supports NPAPI to launch Java-applet,
but currently it seems like Checkpoint SNX uses the new mechanism.
That&amp;rsquo;s why most probably a webpage will ask you to install whatever called &lt;strong>cshell&lt;/strong>, but not &lt;code>csh&lt;/code>,
you will have to download another script &lt;code>cshell_install.sh&lt;/code>.&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>Important&lt;/strong>&lt;/p>
&lt;p>Before installation install OpenJRE, in my case only the latest 15.0 worked well.&lt;/p>
&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ chmod +x cshell_install.sh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ sudo ./cshell_install.sh
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In case of any errors probably you have a wrong OpenJRE version.
Fortunately you can test it even after failed installation process:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ java -jar /usr/bin/cshell/CShell.jar
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>&lt;strong>Note&lt;/strong>&lt;/p>
&lt;p>Scrips are idempotent, so you can run them indefinitely until getting a fix&lt;/p>
&lt;/blockquote>
&lt;p>After successful installation of &lt;strong>snx&lt;/strong> and &lt;strong>cshell&lt;/strong> there is another step:
this jar-file runs HTTPS-server at &lt;code>localhost:14186&lt;/code>, but installer fails to make certificate trusted.
There are two ways to fix it:&lt;/p>
&lt;ul>
&lt;li>Add &lt;code>/usr/bin/cshell/cert/CShell_Certificate.crt&lt;/code> as trusted (preferred)&lt;/li>
&lt;li>Just go to the &lt;code>localhost:14186&lt;/code> in your favourite browser and mark it as trusted.&lt;/li>
&lt;/ul>
&lt;p>Now try to reconnect again. Everything should now work.&lt;/p>
&lt;h2 id="wireguard-tunnel">WireGuard tunnel&lt;/h2>
&lt;p>I don&amp;rsquo;t want to tell here how WireGuard works. I will just provide an example of working configs:&lt;/p>
&lt;p>Peer A (VM with SNX):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>Interface&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">PrivateKey&lt;/span> &lt;span class="o">=&lt;/span> ... &lt;span class="c1"># ABC&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">ListenPort&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="m">51820&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">Address&lt;/span> &lt;span class="o">=&lt;/span> 192.168.128.1/24
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Host PC&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>Peer&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">PublicKey&lt;/span> &lt;span class="o">=&lt;/span> ... &lt;span class="c1"># XYZ&amp;#39; public key&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">AllowedIPs&lt;/span> &lt;span class="o">=&lt;/span> 192.168.128.2/32
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># You add here another peers:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">#&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Mobile phone&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># [Peer]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># PublicKey = DEF&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># AllowedIPs = 192.168.128.3/32&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Peer B (PC with which I want to share):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>Interface&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">PrivateKey&lt;/span> &lt;span class="o">=&lt;/span> ... &lt;span class="c1"># XYZ&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">Address&lt;/span> &lt;span class="o">=&lt;/span> 192.168.128.2/32
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">DNS&lt;/span> &lt;span class="o">=&lt;/span> DNS1, DNS2 &lt;span class="c1"># found out you VPN DNS server and hard code them here&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>Peer&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">PublicKey&lt;/span> &lt;span class="o">=&lt;/span> ... &lt;span class="c1"># ABC&amp;#39;s public key&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">AllowedIPs&lt;/span> &lt;span class="o">=&lt;/span> 10.0.0.0/8
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">Endpoint&lt;/span> &lt;span class="o">=&lt;/span> 192.168.1.8:51820 &lt;span class="c1"># Use an IP of your bridged VM&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>On both sides enable peers. You can test tunnel simply pinging thought it:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># from device to VM with SNX&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ ping 192.168.128.2
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="firewall">Firewall&lt;/h2>
&lt;p>Of course without proper firewall setup, an SNX connection won&amp;rsquo;t share. I will use modern &lt;strong>nftables&lt;/strong>.&lt;/p>
&lt;p>&lt;code>/etc/nftables.conf:&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#!/usr/bin/nft -f
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>&lt;span class="c1"># ipv4/ipv6 Simple &amp;amp; Safe Firewall&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># you can find examples in /usr/share/nftables/&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">flush ruleset
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">table inet filter &lt;span class="o">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> chain input &lt;span class="o">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">type&lt;/span> filter hook input priority 0&lt;span class="p">;&lt;/span> policy drop&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># allow established/related connections&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ct state &lt;span class="o">{&lt;/span>established, related&lt;span class="o">}&lt;/span> accept
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># early drop of invalid connections&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ct state invalid drop
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># allow from loopback&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> iifname lo accept
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># allow icmp&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ip protocol icmp accept
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> meta l4proto ipv6-icmp accept
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># allow wireguard&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> udp dport &lt;span class="m">51820&lt;/span> accept
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># everything else&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> reject with icmpx &lt;span class="nb">type&lt;/span> port-unreachable
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> chain forward &lt;span class="o">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">type&lt;/span> filter hook forward priority 0&lt;span class="p">;&lt;/span> policy drop&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ct state &lt;span class="o">{&lt;/span>established, related&lt;span class="o">}&lt;/span> accept
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ct state invalid drop
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># allow forwarding from wireguard interface to snx one&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> iifname wg0 oifname tunsnx ct state new accept
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> chain output &lt;span class="o">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">type&lt;/span> filter hook output priority 0&lt;span class="p">;&lt;/span> policy accept&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">table inet nat &lt;span class="o">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> chain postrouting &lt;span class="o">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">type&lt;/span> nat hook postrouting priority srcnat&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>&lt;strong>Note&lt;/strong>&lt;/p>
&lt;p>Don&amp;rsquo;t forget to enable IP forwarding:&lt;/p>
&lt;p>&lt;code>net.ipv4.ip_forward=1&lt;/code>&lt;/p>
&lt;p>&lt;code>net.ipv6.conf.all.forwarding=1&lt;/code>&lt;/p>
&lt;/blockquote>
&lt;p>To share SNX connection you will have to configure SNAT dynamically after connection (and disconnection).
I will use systemd oneshot-service to do this.&lt;/p>
&lt;p>&lt;code>/etc/systemd/system/snx-firewall.service:&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>Unit&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">Description&lt;/span>&lt;span class="o">=&lt;/span>Checkpoint SNX firewall tweaker
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">BindsTo&lt;/span>&lt;span class="o">=&lt;/span>sys-subsystem-net-devices-tunsnx.device
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">After&lt;/span>&lt;span class="o">=&lt;/span>sys-subsystem-net-devices-tunsnx.device
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>Service&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">Type&lt;/span>&lt;span class="o">=&lt;/span>oneshot
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">RemainAfterExit&lt;/span>&lt;span class="o">=&lt;/span>yes
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">ExecStart&lt;/span>&lt;span class="o">=&lt;/span>/root/bin/snx_add_rule.sh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">ExecStop&lt;/span>&lt;span class="o">=&lt;/span>/root/bin/snx_flush_chain.sh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>Install&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">WantedBy&lt;/span>&lt;span class="o">=&lt;/span>sys-subsystem-net-devices-tunsnx.device
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The mix of &lt;code>BindsTo&lt;/code> and &lt;code>RemainsAfterExit&lt;/code> allows us to trigger &lt;code>ExecStart&lt;/code> and &lt;code>ExecStop&lt;/code> at the right time,
when connection starts and when connection stops.&lt;/p>
&lt;p>As you could see above, service also requires two scripts:&lt;/p>
&lt;p>&lt;code>/root/bin/snx_add_rule.sh:&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#!/bin/bash
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">GATEWAY&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="k">$(&lt;/span>ip -o -4 addr show tunsnx &lt;span class="p">|&lt;/span> awk &lt;span class="s1">&amp;#39;{printf $4}&amp;#39;&lt;/span>&lt;span class="k">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">nft add rule inet nat postrouting oifname &lt;span class="s2">&amp;#34;tunsnx&amp;#34;&lt;/span> ip daddr 10.0.0.0/8 snat ip to &lt;span class="nv">$GATEWAY&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">echo&lt;/span> &lt;span class="s2">&amp;#34;nftables rule added&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>/root/bin/snx_flush_chain.sh:&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#!/bin/bash
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">nft flush chain inet nat postrouting
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">echo&lt;/span> &lt;span class="s2">&amp;#34;nftables flushed&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This is where all the magic is going on. Simple masquerading doesn&amp;rsquo;t help in this case.
Reconnect you SNX and try to open corporate resource. Works? Cool!&lt;/p>
&lt;p>Feel free to leave comments below the post.&lt;/p>
&lt;p>&lt;strong>UPDATE:&lt;/strong> I can also recommend removing default cshell autostart (from &lt;code>~/.config/autostart/cshell.desktop&lt;/code>)
because it&amp;rsquo;s not reliable and setup &lt;strong>user&lt;/strong> systemd service:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>Unit&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">Description&lt;/span>&lt;span class="o">=&lt;/span>Checkpoint SNX CShell
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">Wants&lt;/span>&lt;span class="o">=&lt;/span>network-online.target
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">After&lt;/span>&lt;span class="o">=&lt;/span>network-online.target
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>Service&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">Type&lt;/span>&lt;span class="o">=&lt;/span>simple
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">Environment&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="nv">DISPLAY&lt;/span>&lt;span class="o">=&lt;/span>:0
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">WorkingDirectory&lt;/span>&lt;span class="o">=&lt;/span>/usr/bin/cshell
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Should work for JRE 16+&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">ExecStart&lt;/span>&lt;span class="o">=&lt;/span>/usr/bin/java --add-exports java.base/sun.net.spi&lt;span class="o">=&lt;/span>ALL-UNNAMED -jar CShell.jar /tmp/cshell.fifo
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">ExecStop&lt;/span>&lt;span class="o">=&lt;/span>/bin/kill -15 &lt;span class="nv">$MAINPID&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">SuccessExitStatus&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">143&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">Restart&lt;/span>&lt;span class="o">=&lt;/span>on-failure
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>Install&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">WantedBy&lt;/span>&lt;span class="o">=&lt;/span>default.target
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>UPDATE 2:&lt;/strong> Rui Ribeiro from comments suggested much nicer method using chroot, &lt;a href="../2021/04/26/checkpoint-snx-adventure.html#remark42__comment-9d1b502f-e4bc-48df-8146-9bacab3c49e1">check it&lt;/a>!&lt;/p></description></item></channel></rss>