<?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&#39;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>Sun, 28 Jun 2026 18:54:00 +0200</lastBuildDate>
        
        <atom:link href="https://krasovs.ky/blog/index.xml" rel="self" type="application/rss+xml" />
        
        <item>
            <title>Using nix-darwin on macOS</title>
            <link>https://krasovs.ky/2026/06/28/darwin-nix.html</link>
            <pubDate>Sun, 28 Jun 2026 18:54:00 +0200</pubDate>
            <author>savely@krasovs.ky (Savely Krasovsky)</author>
            <guid>https://krasovs.ky/2026/06/28/darwin-nix.html</guid>
            <description>&lt;p&gt;I am not a regular macOS user, but I have never liked &lt;code&gt;brew&lt;/code&gt; for some reason. Recently I got a MacBook
for personal projects and occasional work. Almost immediately I needed to use brew, because the built-in OpenSSH
doesn&amp;rsquo;t really work with FIDO2 SSH keys. Installing it from &lt;code&gt;brew&lt;/code&gt; feels wrong to me, I don&amp;rsquo;t really know why;
call it personal preference.&lt;/p&gt;
&lt;p&gt;Then I tried to google the alternatives and found out that there is a &lt;code&gt;nix-darwin&lt;/code&gt; project! Turns out you can enjoy
&lt;code&gt;nixpkgs&lt;/code&gt; repositories on macOS and &lt;code&gt;nix&lt;/code&gt;&amp;rsquo;s declarative way of configuring your system.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t want to describe the pros and cons of that approach, but for me it&amp;rsquo;s much more preferable
to using plain &lt;code&gt;brew&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I still use &lt;code&gt;brew&lt;/code&gt; for all GUI apps as casks, because it&amp;rsquo;s a legitimate case, in my opinion. 90% of packages are part
of my independent Home Manager configuration &lt;em&gt;(so I could use it on the Linux machine as well)&lt;/em&gt;, and the other 10% are
system-wide packages like &lt;code&gt;openssh&lt;/code&gt; and &lt;code&gt;libfido2&lt;/code&gt; and something like &lt;code&gt;podman&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Here is a small guide for someone who has never used &lt;code&gt;nix&lt;/code&gt; and &lt;code&gt;nix-darwin&lt;/code&gt; before. A few years ago &lt;code&gt;nix&lt;/code&gt; installation was
pretty invasive. It was a simple bash script, and if you wanted to remove it later, it was an interesting quest,
I would say.&lt;/p&gt;
&lt;p&gt;Today you can just use &lt;code&gt;nix-installer&lt;/code&gt;; I prefer the one provided by the NixOS community.&lt;/p&gt;
&lt;h2 id=&#34;install-nix-installer&#34;&gt;Install nix-installer&lt;/h2&gt;
&lt;p&gt;Use the following command from their &lt;a href=&#34;https://github.com/NixOS/nix-installer&#34;&gt;README&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -sSfL https://artifacts.nixos.org/nix-installer &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sh -s -- install --enable-flakes
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Follow the instructions, it should be pretty straightforward.&lt;/p&gt;
&lt;h2 id=&#34;install-nix-darwin&#34;&gt;Install nix-darwin&lt;/h2&gt;
&lt;p&gt;We can break down this process into these steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Create the &lt;code&gt;/etc/nix-darwin&lt;/code&gt; directory and set proper permissions&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Initialize a flake using the &lt;code&gt;nix&lt;/code&gt; you installed using &lt;code&gt;nix-installer&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Replace the &lt;code&gt;simple&lt;/code&gt; configuration with your hostname.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Why? Because when you build or switch to the configuration, &lt;code&gt;nix&lt;/code&gt; by default searches for the configuration
for your current machine based on the hostname. It&amp;rsquo;s common for people to use a single config across
a fleet of their machines.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install &lt;code&gt;nix-darwin&lt;/code&gt; using &lt;code&gt;nix&lt;/code&gt; itself.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Edit the configuration to your liking.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Switch your machine to that configuration.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Those steps are described in detail in the &lt;code&gt;nix-darwin&lt;/code&gt; &lt;a href=&#34;https://github.com/nix-darwin/nix-darwin#getting-started&#34;&gt;README&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;example-configuration&#34;&gt;Example configuration&lt;/h2&gt;
&lt;p&gt;Since &lt;code&gt;/etc/nix-darwin&lt;/code&gt; is owned by your user, you can open that directory in your favorite editor and
start building your configuration. You can check my personal configuration &lt;a href=&#34;https://github.com/savely-krasovsky/nix&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As of 2026, it&amp;rsquo;s pretty basic:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;flake.nix&lt;/code&gt; - flake entry point and host outputs.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hosts/&lt;/code&gt; - machine-specific system configurations.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;modules/&lt;/code&gt; - system-level modules grouped by platform.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;home/&lt;/code&gt; - Home Manager user configurations.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;home/common/&lt;/code&gt; - shared Home Manager modules for shell, git, ssh, fzf, starship, and user packages.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can use it as an entry point for your own configuration.&lt;/p&gt;
</description>
        </item><item>
            <title>Nvidia Arch Linux minimal setup</title>
            <link>https://krasovs.ky/2024/10/31/nvidia-arch-linux-minimal-setup.html</link>
            <pubDate>Thu, 31 Oct 2024 09:53:39 +0100</pubDate>
            <author>savely@krasovs.ky (Savely Krasovsky)</author>
            <guid>https://krasovs.ky/2024/10/31/nvidia-arch-linux-minimal-setup.html</guid>
            <description>&lt;p&gt;I was struggling with Nvidia driver a lot on my Arch Linux setup,
but I&amp;rsquo;ve finally resolved most of the problems.&lt;/p&gt;
&lt;p&gt;Basically I had those problems:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Sleep didn&amp;rsquo;t work. I was getting black screen most of the time after trying to wake up the machine.&lt;/li&gt;
&lt;li&gt;HDR was working, but colors were washed out.&lt;/li&gt;
&lt;li&gt;HDMI 2.1 didn&amp;rsquo;t work either. OS was losing monitor signal for some reason.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I&amp;rsquo;ve resolved all the problems after release of the new 565.57.01 beta driver which is
&lt;a href=&#34;https://archlinux.org/packages/extra-testing/x86_64/nvidia/&#34;&gt;already available&lt;/a&gt; in extra-testing repo.&lt;/p&gt;
&lt;h1 id=&#34;key-points&#34;&gt;Key points&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Those points are applicable only for default &lt;code&gt;linux&lt;/code&gt; core, other may require additional tuning.&lt;/li&gt;
&lt;li&gt;Since &lt;code&gt;560.35.03-5&lt;/code&gt; you don&amp;rsquo;t set kernel parameters to use driver. Both &lt;code&gt;nvidia_drm.modeset&lt;/code&gt; and &lt;code&gt;nvidia_drm.fbdev&lt;/code&gt;
are enabled by default, you can remove.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nvidia-suspend.service&lt;/code&gt; is disabled by default while Arch wiki says it&amp;rsquo;s should be enabled by default.
Same with &lt;code&gt;nvidia-hibernate.service&lt;/code&gt;. Please check the status and enable it,
e.g. &lt;code&gt;systemctl enable nvidia-suspend.service&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nvidia-resume.service&lt;/code&gt; is also disabled by default, but you need to enable it only under GDM.&lt;/li&gt;
&lt;li&gt;Without those services your GPU will be &lt;strong&gt;unable&lt;/strong&gt; to use deep S3 sleep and hibernation.&lt;/li&gt;
&lt;li&gt;You don&amp;rsquo;t need to manually enable &lt;code&gt;NVreg_PreserveVideoMemoryAllocations=1&lt;/code&gt; and &lt;code&gt;NVreg_TemporaryFilePath=/var/tmp&lt;/code&gt;
modprobe options. They are already enabled by default.&lt;/li&gt;
&lt;li&gt;HDR was completely disabled for Nvidia GPUs in KDE Plasma 6.2 due to
&lt;a href=&#34;https://invent.kde.org/plasma/kwin/-/wikis/Environment-Variables#kwin_drm_allow_nvidia_colorspace&#34;&gt;bug&lt;/a&gt;.
You need to re-enable it manually using &lt;code&gt;KWIN_DRM_ALLOW_NVIDIA_COLORSPACE=1&lt;/code&gt; environment variable,
e.g. adding it to &lt;code&gt;/etc/environment&lt;/code&gt; and re-logging.&lt;/li&gt;
&lt;li&gt;You &lt;strong&gt;need&lt;/strong&gt; to use version 565 and higher if your colors are washed out and pale after enabling it
(you will notice it if they are, believe me).&lt;/li&gt;
&lt;li&gt;SDDM launched under X11 for some reason broke HDMI 2.1 in my case.
&lt;a href=&#34;https://wiki.archlinux.org/title/SDDM#Wayland&#34;&gt;Switching to Wayland&lt;/a&gt; solved the problem.
As a nice bonus I also now have HDR enabled in SDDM because it now matches the Plasma configuration.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;summary&#34;&gt;Summary&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;You don&amp;rsquo;t need to enable most of the options by hand, it&amp;rsquo;s now enabled by default.&lt;/li&gt;
&lt;li&gt;You still need to enable &lt;code&gt;nvidia-suspend&lt;/code&gt; (and &lt;code&gt;nvidia-hibernate&lt;/code&gt; if you use hibernation) for sleep to work.&lt;/li&gt;
&lt;li&gt;You need to re-enable HDR in KDE Plasma using environment variable.&lt;/li&gt;
&lt;li&gt;Switch SDDM to Wayland if you have problems with HDMI 2.1.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;update-from-21112024&#34;&gt;Update from 21.11.2024&lt;/h1&gt;
&lt;p&gt;Unfortunately it didn&amp;rsquo;t resolve sleep/suspend problems completely. You also need Linux 6.12, it contains
&lt;a href=&#34;https://github.com/NVIDIA/open-gpu-kernel-modules/issues/719#issuecomment-2433119997&#34;&gt;additional suspend patch&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However, I noticed another issue: &lt;code&gt;nvidia-open&lt;/code&gt; suffers from occasional stuttering and various lags across OS interface:
scrolling browser, moving windows, etc. Those symptoms disappear if GPU is under some kind of constant load:
video recoding, large video decoding, gaming, etc. Unfortunately there is no fix for this, because bug is in
GSP firmware which cannot be disabled in open modules. You can switch to proprietary &lt;code&gt;nvidia&lt;/code&gt; and
disable GSP using modprobe option:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;options nvidia NVreg_EnableGpuFirmware=0
&lt;/code&gt;&lt;/pre&gt;</description>
        </item><item>
            <title>Notes about compact and powerful PC and server builds</title>
            <link>https://krasovs.ky/2024/10/13/ultra-compact-builds.html</link>
            <pubDate>Sun, 13 Oct 2024 22:54:27 +0200</pubDate>
            <author>savely@krasovs.ky (Savely Krasovsky)</author>
            <guid>https://krasovs.ky/2024/10/13/ultra-compact-builds.html</guid>
            <description>&lt;p&gt;I wanted to build a decently powerful server for all my self-hosted staff for a long time, but after Russo-Ukrainian
had been started priorities obviously shifted, so I put this idea on hold.&lt;/p&gt;
&lt;p&gt;Since then, I moved to the Serbia, but I am not sure if I will stay here for years,
so both main PC and server should be as compact as it&amp;rsquo;s possible and also as powerful.&lt;/p&gt;
&lt;h1 id=&#34;main-desktop-pc&#34;&gt;Main desktop PC&lt;/h1&gt;
&lt;p&gt;I built my new desktop PC in May, and I am still impressed! Couldn&amp;rsquo;t imagine that 10L case could hold so much power.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;../pc_build/desk_setup.jpg&#34; alt=&#34;&#34; title=&#34;Desk setup&#34;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CPU:&lt;/strong&gt; AMD Ryzen 9 7950X3D&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPU:&lt;/strong&gt; ASUS ProArt GeForce RTX 4080 Super OC&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Motherboard:&lt;/strong&gt; ASUS ROG X670E-I&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RAM:&lt;/strong&gt; CORSAIR Vengeance 96GB DDR5-6000 CL30&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PSU:&lt;/strong&gt; Phanteks Revolt SFX 850W&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cooling:&lt;/strong&gt; Fractal Design Lumen S24 с Noctua NF-A12x25 и SilverStone Air Slimmer 120&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Case:&lt;/strong&gt; FormD T1 v2.1 + Essentials Pack (USB Type-C front panel addon) + Fitting Pack (just for fun)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Storage:&lt;/strong&gt; Crucial T705 4TB&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Additional:&lt;/strong&gt; Noctua NA-FG1-12 fan grill&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;more-photos&#34;&gt;More photos&lt;/h2&gt;
&lt;p&gt;&lt;img src=&#34;../pc_build/pc_front.jpg&#34; alt=&#34;&#34; title=&#34;PC inside front&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;../pc_build/pc_back.jpg&#34; alt=&#34;&#34; title=&#34;PC inside back&#34;&gt;&lt;/p&gt;
&lt;p&gt;I can even put it inside Kanken 2.0:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;../pc_build/in_backpack_open.jpg&#34; alt=&#34;&#34; title=&#34;In the backpack, open&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;../pc_build/in_backpack_closed.jpg&#34; alt=&#34;&#34; title=&#34;In the backpack, closed&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;server&#34;&gt;Server&lt;/h1&gt;
&lt;p&gt;&lt;img src=&#34;../pc_build/server_exterior.jpg&#34; alt=&#34;&#34; title=&#34;Server on the floor&#34;&gt;&lt;/p&gt;
&lt;p&gt;Completed the build in March 2025, server has 5.8L volume. Very small, but powerful!
All disks have Power Loss Protection (PLP). Low draw while in idle (58W in package C2).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CPU:&lt;/strong&gt; Intel Core i9-14900K&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Motherboard:&lt;/strong&gt; &lt;a href=&#34;https://www.asrockrack.com/general/productdetail.asp?Model=W680D4ID-2T/G5/X550&#34;&gt;ASRock Rack W680D4ID-2T/G5/X550&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RAM:&lt;/strong&gt; Kingston Server Premier 96GB DDR5-5600 CL46 (ECC)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPU:&lt;/strong&gt; ASRock Intel Arc A380 Low Profile 6GB&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PSU:&lt;/strong&gt; &lt;a href=&#34;https://hdplex.com/hdplex-fanless-250w-gan-aio-atx-psu.html&#34;&gt;HDPLEX 250W GaN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cooling:&lt;/strong&gt; Noctua NH-L9x65&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Case:&lt;/strong&gt; &lt;a href=&#34;https://www.custom-mod.com/en/sl3&#34;&gt;Custom Mod SL3 modified to fit Deep mini-ITX&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Storage:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;2 x M.2 &lt;em&gt;(Kingston DC2000B 960GB)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;5 x SATA &lt;em&gt;(Samsung SM863 1.96TB)&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;../pc_build/server_interior.jpg&#34; alt=&#34;&#34; title=&#34;Server inside&#34;&gt;&lt;/p&gt;
</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&gt;I&amp;rsquo;ve &lt;a href=&#34;https://github.com/savely-krasovsky/waybar-updates&#34;&gt;released&lt;/a&gt; simple but yet effective module
for the &lt;a href=&#34;https://github.com/Alexays/Waybar&#34;&gt;Waybar&lt;/a&gt; that checks Arch Linux system updates.
There are some features that I think you would like.&lt;/p&gt;
&lt;h2 id=&#34;features&#34;&gt;Features&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Sends notifications about updates.&lt;/li&gt;
&lt;li&gt;Supports GNU gettext localization (contribute new po-files!)&lt;/li&gt;
&lt;li&gt;Checks updates from AUR using Aurweb RPC, so works independently.&lt;/li&gt;
&lt;li&gt;Shows updates in the tooltip.&lt;/li&gt;
&lt;li&gt;Supports two states: &lt;code&gt;pending-updates&lt;/code&gt; and &lt;code&gt;updated&lt;/code&gt; to use different icons or hide module.&lt;/li&gt;
&lt;li&gt;Uses infinite loop to supply Waybar JSON updates.&lt;/li&gt;
&lt;li&gt;Configurable interval between checks.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can easily install it from &lt;a href=&#34;https://aur.archlinux.org/packages/waybar-updates&#34;&gt;AUR&lt;/a&gt;: &lt;code&gt;yay -S waybar-updates&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;I use it with this config:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;custom/pacman&amp;#34;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;format&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;{icon}{}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;return-type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;json&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;format-icons&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;pending-updates&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;updated&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;exec-if&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;which waybar-updates&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;exec&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;waybar-updates&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In that case you will also need Nerd fonts (I personally use &lt;code&gt;ttf-jetbrains-mono-nerd&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve also added lite blinking effect to it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;keyframes&lt;/span&gt; &lt;span class=&#34;nt&#34;&gt;blink-update&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;nt&#34;&gt;to&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;k&#34;&gt;background-color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;dodgerblue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;custom-pacman&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;k&#34;&gt;animation-timing-function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;linear&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;k&#34;&gt;animation-iteration-count&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;infinite&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;k&#34;&gt;animation-direction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;alternate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;custom-pacman&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;pending-updates&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;k&#34;&gt;animation-name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;blink&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;update&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;k&#34;&gt;animation-duration&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;screenshots&#34;&gt;Screenshots&lt;/h2&gt;
&lt;p&gt;&lt;img src=&#34;../waybar-updates-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;video class=&#34;video-shortcode&#34; preload=&#34;auto&#34; controls&gt;
    &lt;source src=&#34;../waybar-updates-2.webm&#34; type=&#34;video/webm&#34;&gt;
    There should have been a video here but your browser does not seem
    to support it.
&lt;/video&gt;
&lt;p&gt;If you like it, please consider to give it a star!&lt;/p&gt;
</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&gt;A while ago I got my own &lt;a href=&#34;https://flipperzero.one/&#34;&gt;Flipper Zero&lt;/a&gt; and immediately tried to write own simple application.
Unfortunately they officially support only one editor — VS Code.&lt;/p&gt;
&lt;p&gt;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&gt;
&lt;p&gt;CLion is a cross-platform IDE for C and C++ from JetBrains. And while it does support some features
for &lt;a href=&#34;https://www.jetbrains.com/help/clion/embedded-overview.html&#34;&gt;embedded development&lt;/a&gt;,
there are still some caveats, especially with debugging.&lt;/p&gt;
&lt;h2 id=&#34;setup-core-functionality&#34;&gt;Setup core functionality&lt;/h2&gt;
&lt;p&gt;CLion syntax highlighting and autocomplete engine works out of the box only with CMake, but it supports
&lt;a href=&#34;https://www.jetbrains.com/help/clion/compilation-database.html&#34;&gt;compilation database&lt;/a&gt;, which &lt;code&gt;fbt&lt;/code&gt; can generate.
So to start:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Clone Flipper Zero firmware repo:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git clone --recursive https://github.com/flipperdevices/flipperzero-firmware.git
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Build firmware, FAPs and create compile database:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./fbt
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./fbt faps
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./fbt firmware_cdb
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Copy &lt;code&gt;compile_commands.json&lt;/code&gt; from &lt;code&gt;build/latest&lt;/code&gt; to the project root.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open this file with CLion.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go and find &lt;code&gt;compile_commands.json&lt;/code&gt; file at &lt;code&gt;build/latest&lt;/code&gt; again, then click right mouse button and choose
&lt;code&gt;Load Compilation Database Project&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Remove &lt;code&gt;compile_commands.json&lt;/code&gt; from the project root.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go to &lt;code&gt;File -&amp;gt; Settings -&amp;gt; Build, Execution, Deployment -&amp;gt; Toolchains&lt;/code&gt; and create toolkit:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;C Compiler: &lt;code&gt;toolchain/x86_64-linux/bin/arm-none-eabi-gcc&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;С++ Compiler: &lt;code&gt;toolchain/x86_64-linux/bin/arm-none-eabi-g++&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Debugger: &lt;code&gt;toolchain/x86_64-linux/bin/arm-none-eabi-gdb-py&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It should try to sync a project at &lt;code&gt;Build&lt;/code&gt; tab successfully.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;possible-problems-and-their-solutions&#34;&gt;Possible problems and their solutions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;CLion does not understand &lt;code&gt;ccache&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution 1:&lt;/strong&gt; remove &lt;code&gt;ccache&lt;/code&gt; from system and regenerate compilation database.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution 2:&lt;/strong&gt; just remove it from file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; built/target
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sed -i &lt;span class=&#34;s1&#34;&gt;&amp;#39;s/ccache\ //g&amp;#39;&lt;/span&gt; compile_commands.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CLion cannot find stdlib.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution 1:&lt;/strong&gt; Launch CLion under &lt;code&gt;fbt&lt;/code&gt; environment:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;source&lt;/span&gt; scripts/toolchain/fbtenv.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;gtk-launch jetbrains-clion.desktop
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Solution 2:&lt;/strong&gt; Replace path to compiler with absolute ones:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; built/target
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sed -i &lt;span class=&#34;s1&#34;&gt;&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&gt; compile_commands.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Solution 3:&lt;/strong&gt; Install the latest &lt;code&gt;arm-none-eabi&lt;/code&gt; toolkit with your system package manager:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo pacman -S arm-none-eabi-gcc arm-none-eabi-gdb arm-none-eabi-newlib  
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After this troubleshooting CLion should work as expected: highlighting and autocompleting your code.&lt;/p&gt;
&lt;h3 id=&#34;setup-debugging&#34;&gt;Setup debugging&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Go to Run Configuration and create your own with type &lt;code&gt;Remote Debug&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pick debugger from toolchain you created before.&lt;/li&gt;
&lt;li&gt;Fill &lt;code&gt;&#39;target remote&#39; args&lt;/code&gt; with content from output of &lt;code&gt;./fbt get_blackmagic&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Point to symbol file: &lt;code&gt;build/latest/firmware.elf&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a &lt;code&gt;.gdbinit&lt;/code&gt; file with this content in the project directory:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;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&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Then create a &lt;code&gt;.gdbinit&lt;/code&gt; file in your home directory:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;set auto-load safe-path /path/to/your/project
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Before first debug session you have to attach Flipper Zero:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;toolchain/x86_64-linux/bin/arm-none-eabi-gdb-py -q -ex &lt;span class=&#34;s2&#34;&gt;&amp;#34;target remote `./fbt get_blackmagic`&amp;#34;&lt;/span&gt; -ex &lt;span class=&#34;s2&#34;&gt;&amp;#34;monitor swdp_scan&amp;#34;&lt;/span&gt; -ex &lt;span class=&#34;s2&#34;&gt;&amp;#34;attach 1&amp;#34;&lt;/span&gt; -ex &lt;span class=&#34;s2&#34;&gt;&amp;#34;quit&amp;#34;&lt;/span&gt; build/latest/firmware.elf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;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&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;(Optionally)&lt;/em&gt; 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&gt;
&lt;p&gt;&lt;img src=&#34;../clion_external_tool.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;UPD: 10 november 2022&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Guide has been updated after patches from Flipper Devices team! Now it should work with fewer tricks.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPD: 25 april 2023&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Roman Beltiukov has pointed out in the comments about &lt;code&gt;fap-set-debug-elf-root build/latest/.extapps&lt;/code&gt; needed
to be added to the project&amp;rsquo;s &lt;code&gt;.gdbinit&lt;/code&gt; to debug fapps.&lt;/p&gt;
</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&gt;С релизом нового обновления Telegram у многих возникли вопросы как правильно наладить общение &lt;code&gt;бот &amp;lt;-&amp;gt; Telegram&lt;/code&gt;,
&lt;code&gt;бот &amp;lt;-&amp;gt; бэкенд&lt;/code&gt; и сделать это безопасно. Для начала давайте проясним какие способы активации Telegram решил
предоставить пользователю:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Через кнопку меню, которую можно настроить у &lt;code&gt;@BotFather&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Через inline-кнопку.&lt;/li&gt;
&lt;li&gt;Через keyboard-кнопку.&lt;/li&gt;
&lt;li&gt;Через меню вложений.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&#34;../telegram_web_app_buttons.jpg&#34; alt=&#34;Виды кнопок&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;кнопка-меню-inline-кнопка&#34;&gt;Кнопка меню, inline-кнопка&lt;/h2&gt;
&lt;p&gt;Первый и второй способ предлагают нам аутентифицировать и авторизовать пользователя через специальный объект &lt;code&gt;initData&lt;/code&gt;,
который можно достать с помощью JavaScript. Объект имеет следующую структуру:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;query_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;str&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;is_bot&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;first_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Pavel&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;last_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Durov&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;username&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;durov&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;language_code&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;ru&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;photo_url&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://telegram.org/durov.jpg&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;auth_date&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1655210062&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;hash&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Проблема в том, что официальная документация хоть и предупреждает, но не особо объясняет зачем валидировать
поле &lt;code&gt;initData&lt;/code&gt; на сервере бота.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Без валидации:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Мэллори:&lt;/strong&gt; Привет Боб, я Алиса, дай мне информацию о балансе и сделай перевод на имя Мэллори.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Боб:&lt;/strong&gt; Пожалуйста, Алиса, всё готово.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;С валидацией:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Мэллори:&lt;/strong&gt; Привет Боб, я Алиса, дай мне информацию о балансе и сделай перевод на имя Мэллори.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Боб:&lt;/strong&gt; Предоставьте, пожалуйста, валидную подпись Алисы.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Мэллори разводит руками&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;То есть нужно это затем, чтобы произвести безопасную аутентификацию (проверку подлинности запроса) и авторизацию
(понять, что к боту пришла именно Алиса, а не Мэллори).&lt;/p&gt;
&lt;p&gt;Без этой валидации бот сможет предоставлять критически важную информацию (например, вы делаете онлайн-банкинг в боте)
просто по ID пользователя Telegram.&lt;/p&gt;
&lt;p&gt;Важно также понимать, что валидация должна происходить &lt;strong&gt;исключительно&lt;/strong&gt; на серверной части.
Валидация на клиентской части мало того, что бессмысленна, так ещё и скомпрометирует токен вашего бота.&lt;/p&gt;
&lt;p&gt;Валидация, к слову, не совсем тривиальная. Разработчики Telegram, как обычно, не поленились и вместо проверенного
стандарта JSON Web Token (JWT), реализовали свой собственный велосипед, да ещё и на базе обычного HMAC-SHA256
(то есть HS256 будь у нас JWT-токен). В результате &lt;code&gt;initData&lt;/code&gt; представляет собой URL-encoded
строку query-параметров. Для корректной валидации которой требуется следующая цепочка шагов:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Декодируем строку, используя URL-encoding (важно, иначе значение с ключом &lt;code&gt;user&lt;/code&gt; останется не декодированным).&lt;/li&gt;
&lt;li&gt;Полученные пары ключ-значения сортируем в алфавитном порядке.&lt;/li&gt;
&lt;li&gt;Исключаем ключ &lt;code&gt;hash&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Из полученных пар составляем тело вида: &lt;code&gt;auth_date=&amp;lt;auth_date&amp;gt;\nquery_id=&amp;lt;query_id&amp;gt;\nuser=&amp;lt;user&amp;gt;&lt;/code&gt;. Важно сохранить значение с ключом &lt;code&gt;user&lt;/code&gt; в чистом JSON.&lt;/li&gt;
&lt;li&gt;Берем хэш от токена вашего бота с помощью алгоритма HMAC-SHA256 с ключом &lt;code&gt;WebAppData&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Берем хэш от полученного в шаге 4 тела с помощью того же алгоритма, а в качестве ключа используем хэш, полученный ранее в виде последовательности &lt;strong&gt;байтов&lt;/strong&gt; (а не hex-репрезентации!).&lt;/li&gt;
&lt;li&gt;Преобразуем полученный хэш в hex-строку и сравниваем со значением ключа &lt;code&gt;hash&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;По аналогии с JWT, если валидация прошла успешно, пользователя можно считать аутентифицированным
и переходить к авторизации с помощью предоставленного payload (в нашем случае это &lt;code&gt;id&lt;/code&gt; в объекте &lt;code&gt;user&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Говоря о &lt;code&gt;query_id&lt;/code&gt;, который мы получаем в &lt;code&gt;initData&lt;/code&gt;. Используя это поле, мы можем создать в чате сообщение с ботом
от имени пользователя с бейджем &lt;code&gt;via @your_bot&lt;/code&gt;. Для этого потребуется вызвать метод &lt;a href=&#34;https://core.telegram.org/bots/api#answerwebappquery&#34;&gt;answerWebAppQuery&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;../telegram_web_app_via.png&#34; alt=&#34;Вид такого сообщения&#34;&gt;&lt;/p&gt;
&lt;div class=&#34;alert alert-success&#34;&gt;
+ может использоваться для приложений любой сложности&lt;br/&gt;
+ &lt;code&gt;initData&lt;/code&gt; по факту является полноценным stateless-токеном по типу JWT&lt;br/&gt;
+ позволяет создавать сообщения от имени пользователя в чате с ботом с бейджем &lt;code&gt;via @your_bot&lt;/code&gt;&lt;br/&gt;
&lt;/div&gt;
&lt;div class=&#34;alert alert-error&#34;&gt;
- требуется собственный бэкенд для веб-части для валидации &lt;code&gt;initData&lt;/code&gt; и работы с пользователем
&lt;/div&gt;
&lt;h2 id=&#34;keyboard-кнопка&#34;&gt;Keyboard-кнопка&lt;/h2&gt;
&lt;p&gt;С первым и вторым способом всё понятно: вы получаете от Telegram подобие готового токена
и поэтому реализация собственной аутентификации и авторизации не требуется, требуется только валидация.&lt;/p&gt;
&lt;p&gt;Но с третьим способом ситуация с одной стороны проще, с другой сложней. Дело в том, что &lt;code&gt;initData&lt;/code&gt; не приходит
и наладить общение с серверной частью не выйдет. Ведь вы не будете знать кто к вам пришёл.&lt;/p&gt;
&lt;p&gt;Однако при использовании этого способа появляется возможность использовать метод &lt;code&gt;Telegram.WebApp.sendData()&lt;/code&gt;,
который позволяет отправить сообщение боту напрямую, а тот предоставит его вам через long-polling или вебхуки.
Стоит учесть, что после успешного выполнения веб-окно автоматически закроется, а бот отрапортует сервисным сообщением
&lt;code&gt;Вы успешно передали данные боту кнопкой «Test button».&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Поэтому Telegram позиционирует этот способ как удобный способ сделать гибкую веб-форму ввода с полями
типа &lt;code&gt;date picker&lt;/code&gt;. Вернуть значения формы можно с помощью метода &lt;code&gt;Telegram.WebApp.sendData()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Нужно понимать, что в JS-файле этот метод является лишь прослойкой,
само значение, переданное в &lt;code&gt;sendData()&lt;/code&gt; отправляются далее через
&lt;a href=&#34;https://github.com/tdlib/td/blob/047246f366d94b55ea7b6b93b3a4baa9a3380154/td/generate/scheme/td_api.tl#L4968&#34;&gt;MTProto-метод&lt;/a&gt;
&lt;code&gt;sendWebAppData&lt;/code&gt;. Методы MTProto невозможно использовать без авторизации в Telegram, поэтому тут мессенджер берет
безопасность полностью на себя.&lt;/p&gt;
&lt;p&gt;В этом заключается плюс этого метода.&lt;/p&gt;
&lt;div class=&#34;alert alert-success&#34;&gt;
+ удобно для заполнения сравнительно простых форм ввода&lt;br/&gt;
+ наличие собственного бэкенда для Web-части не требуется&lt;br/&gt;
&lt;/div&gt;
&lt;div class=&#34;alert alert-error&#34;&gt;
- &lt;code&gt;initData&lt;/code&gt; не приходит, возможность авторизовать пользователя на своём бэкенде (даже если он есть) отсутствует&lt;br/&gt;
- отправить информацию боту можно только 1 раз
&lt;/div&gt;
&lt;h2 id=&#34;кнопка-в-меню-вложений&#34;&gt;Кнопка в меню вложений&lt;/h2&gt;
&lt;p&gt;Есть также четвертый способ, который технически не отличается от первого и второго
(только дополнительными полями в &lt;code&gt;initData&lt;/code&gt;), но в этом случае бот добавляется
в меню вложений.&lt;/p&gt;
&lt;p&gt;К сожалению эта возможность пока что доступна только для тех, кто участвует в рекламной платформе Telegram
и, следовательно, внёс залог 2 миллиона евро. Поэтому пока что говорить тут особо не о чем.
Из известных мне публичных ботов такую интеграцию использует &lt;a href=&#34;https://t.me/wallet&#34;&gt;@wallet&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Основной плюс — возможность использовать бота не только в личной переписке с ботом.
Например, вышеупомянутый @wallet позволяет отправить любому собеседнику сообщение с информацией о переводе,
собеседнику остается лишь нажать и получить свой перевод.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;../telegram_web_app_wallet.png&#34; alt=&#34;Вид такого сообщения&#34;&gt;&lt;/p&gt;
&lt;div class=&#34;alert alert-success&#34;&gt;
+ плюсы первых двух способов&lt;br/&gt;
+ возможность использовать бота в переписке с человеком&lt;br/&gt;
+ новый интуитивный механизм использования ботов Telegram
&lt;/div&gt;
&lt;div class=&#34;alert alert-error&#34;&gt;
- минусы первых двух способов&lt;br/&gt;
- необходимо стать крупным рекламодателем на площадке Telegram
&lt;/div&gt;</description>
        </item><item>
            <title>Wireguard&#39;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&gt;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&gt;
&lt;style&gt;
#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&gt;
&lt;script src=&#34;../wasm_exec.js&#34;&gt;&lt;/script&gt;
&lt;script src=&#34;../wireguard.js&#34;&gt;&lt;/script&gt;
&lt;form id=&#34;calculator&#34;&gt;
    &lt;label for=&#34;allowed-ips&#34;&gt;AllowedIPs:&lt;/label&gt;
    &lt;input id=&#34;allowed-ips&#34; type=&#34;text&#34;/&gt;
    &lt;label for=&#34;disallowed-ips&#34;&gt;DisallowedIPs:&lt;/label&gt;
    &lt;input id=&#34;disallowed-ips&#34; type=&#34;text&#34;/&gt;
    &lt;div id=&#34;use-api-wrapper&#34;&gt;
        &lt;input id=&#34;use-api&#34; type=&#34;checkbox&#34; onclick=&#34;document.getElementById(&#39;calculate-button&#39;).disabled = false;&#34;/&gt;
        &lt;label for=&#34;use-api&#34;&gt;Use API instead of WASM&lt;/label&gt;
    &lt;/div&gt;
    &lt;input type=&#34;submit&#34; id=&#34;calculate-button&#34; value=&#34;Calculate&#34; disabled/&gt;
    &lt;div hidden id=&#34;final-allowed-ips&#34; class=&#34;alert&#34;&gt;AllowedIPs = &lt;/div&gt;
&lt;/form&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; I am using small Golang HTTP-server to quickly calculate results and at first I tried
&lt;a href=&#34;https://github.com/mikioh/ipaddr&#34;&gt;ipaddr&lt;/a&gt; due to its similarity to the Python
&lt;a href=&#34;https://docs.python.org/3/library/ipaddress.html&#34;&gt;ipaddress&lt;/a&gt;. But it has &lt;em&gt;a little problem&lt;/em&gt;,
in my case it caused an infinite loop that led to DoS and finally to panic.
Better use the brilliant &lt;a href=&#34;https://inet.af/netaddr&#34;&gt;netaddr&lt;/a&gt; developed by
&lt;a href=&#34;https://github.com/bradfitz&#34;&gt;Brad Fitzpatrick&lt;/a&gt; and the Tailscale team
(their &lt;a href=&#34;https://tailscale.com/blog/netaddr-new-ip-type-for-go/&#34;&gt;blogpost&lt;/a&gt; with motivation)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update 2:&lt;/strong&gt; I realized that this is a great case to use WASM!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update 3:&lt;/strong&gt; 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=&#34;https://git.sr.ht/~lord/wireguard-allowed-ips&#34;&gt;here&lt;/a&gt;.
HTTP API mini server sources are probably still lost :(&lt;/p&gt;
</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&gt;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&gt;
&lt;p&gt;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&gt;
&lt;p&gt;So create three files:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ca.cnf:&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;req&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;distinguished_name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; req_distinguished_name
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;req_extensions&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; v3_req
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;prompt&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; no
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# You can remove this if you don&amp;#39;t use non-ASCII symbols&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;utf8&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; yes
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;req_distinguished_name&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;C&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; RU
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;CN&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Savely Krasovsky&amp;#39;s CA&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;v3_req&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;keyUsage&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; digitalSignature
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;tls.cnf:&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;req&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;distinguished_name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; req_distinguished_name
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;prompt&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; no
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;utf8&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; yes
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;req_distinguished_name&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;C&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; RU
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;CN&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Savely Krasovsky&amp;#39;s LAN&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;tls.ext:&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;keyUsage&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; digitalSignature, keyEncipherment
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;extendedKeyUsage&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; serverAuth
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;subjectAltName&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; @alt_names
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;alt_names&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;DNS.1 &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; home.local
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;DNS.2 &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; *.home.local
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now execute this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Generate CA cert&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;openssl ecparam -name prime256v1 -genkey -out ca.key
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;openssl req -new -key ca.key -config ca.cnf -out ca.csr
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;openssl x509 -req -days &lt;span class=&#34;m&#34;&gt;3650&lt;/span&gt; -in ca.csr -signkey ca.key -out ca.crt
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Generate TLS cert&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;openssl ecparam -name prime256v1 -genkey -out tls.key
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;openssl req -new -key tls.key -config tls.cnf -out tls.csr
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;openssl x509 -req -in tls.csr -CA ca.crt -CAkey ca.key -out tls.crt -days &lt;span class=&#34;m&#34;&gt;365&lt;/span&gt; -extfile tls.ext
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Of course, you can create not only TLS certs, this is just the simplest case.
Play with the &lt;code&gt;tls.ext&lt;/code&gt; (especially &lt;code&gt;keyUsage&lt;/code&gt; and &lt;code&gt;extendedKeyUsage&lt;/code&gt; parameters)
file to issue another certificate.&lt;/p&gt;
&lt;p&gt;For example this is mTLS compatible client cert:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;personal.cnf:&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;req&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;distinguished_name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; req_distinguished_name
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;prompt&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; no
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;utf8&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; yes
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;req_distinguished_name&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;C&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; RU
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;CN&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Savely Krasovsky&amp;#39;s LAN&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;personal.ext:&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;keyUsage&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; critical,digitalSignature
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;extendedKeyUsage&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; clientAuth
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;subjectKeyIdentifier&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;hash&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Generation:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;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&gt;&lt;/pre&gt;</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&gt;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&gt;
&lt;p&gt;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&gt;
&lt;p&gt;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&gt;
&lt;p&gt;Just read their &lt;a href=&#34;https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&amp;amp;solutionid=sk65210&#34;&gt;support page&lt;/a&gt;.
The distros they consider relevant in 2021: &lt;em&gt;Ubuntu 17.04&lt;/em&gt;, &lt;em&gt;Fedora 18&lt;/em&gt;, &lt;em&gt;openSUSE 12.2&lt;/em&gt;. Okay, cool.&lt;/p&gt;
&lt;p&gt;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&gt;
&lt;p&gt;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&gt;
&lt;p&gt;So I had an idea: it would be nice to just share Checkpoint VPN connection with other computers.&lt;/p&gt;
&lt;p&gt;Particularly I wanted to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Completely isolate Checkpoint SNX inside Linux VM.&lt;/li&gt;
&lt;li&gt;Use WireGuard tunnels to share VPN connection.&lt;/li&gt;
&lt;li&gt;At client-side use only one simple route: &lt;code&gt;10.0.0.0/8&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;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&gt;
&lt;p&gt;Let&amp;rsquo;s get started.&lt;/p&gt;
&lt;h2 id=&#34;install-checkpoint-snx&#34;&gt;Install Checkpoint SNX&lt;/h2&gt;
&lt;p&gt;You can download SNX installer from your company&amp;rsquo;s VPN portal:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ curl https://example.org/SNX/INSTALL/snx_install.sh -o snx_install.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# OR&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ curl https://example.org/sslvpn/SNX/INSTALL/snx_install.sh -o snx_install.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;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&gt;
&lt;p&gt;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&gt;x86&lt;/code&gt; (not &lt;code&gt;x86-64&lt;/code&gt;), so you need to enable multiarch and install dependencies.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 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&gt;&lt;/pre&gt;&lt;p&gt;So you need to install three libraries: &lt;code&gt;libX11&lt;/code&gt;, &lt;code&gt;libpam&lt;/code&gt;, &lt;code&gt;libstdc++&lt;/code&gt;.
In various distros you need to use various names, but you can easily google it.&lt;/p&gt;
&lt;p&gt;Finally, just install it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ chmod +x snx_install.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ sudo ./snx_install.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;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&gt;cshell&lt;/strong&gt;, but not &lt;code&gt;csh&lt;/code&gt;,
you will have to download another script &lt;code&gt;cshell_install.sh&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Before installation install OpenJRE, in my case only the latest 15.0 worked well.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ chmod +x cshell_install.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ sudo ./cshell_install.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In case of any errors probably you have a wrong OpenJRE version.
Fortunately you can test it even after failed installation process:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ java -jar /usr/bin/cshell/CShell.jar
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Scrips are idempotent, so you can run them indefinitely until getting a fix&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;After successful installation of &lt;strong&gt;snx&lt;/strong&gt; and &lt;strong&gt;cshell&lt;/strong&gt; there is another step:
this jar-file runs HTTPS-server at &lt;code&gt;localhost:14186&lt;/code&gt;, but installer fails to make certificate trusted.
There are two ways to fix it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add &lt;code&gt;/usr/bin/cshell/cert/CShell_Certificate.crt&lt;/code&gt; as trusted (preferred)&lt;/li&gt;
&lt;li&gt;Just go to the &lt;code&gt;localhost:14186&lt;/code&gt; in your favourite browser and mark it as trusted.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now try to reconnect again. Everything should now work.&lt;/p&gt;
&lt;h2 id=&#34;wireguard-tunnel&#34;&gt;WireGuard tunnel&lt;/h2&gt;
&lt;p&gt;I don&amp;rsquo;t want to tell here how WireGuard works. I will just provide an example of working configs:&lt;/p&gt;
&lt;p&gt;Peer A (VM with SNX):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;Interface&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PrivateKey&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; ... &lt;span class=&#34;c1&#34;&gt;# ABC&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ListenPort&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;51820&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;Address&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; 192.168.128.1/24
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Host PC&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;Peer&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PublicKey&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; ... &lt;span class=&#34;c1&#34;&gt;# XYZ&amp;#39; public key&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;AllowedIPs&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; 192.168.128.2/32
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# You add here another peers:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Mobile phone&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# [Peer]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# PublicKey = DEF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# AllowedIPs = 192.168.128.3/32&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Peer B (PC with which I want to share):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;Interface&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PrivateKey&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; ... &lt;span class=&#34;c1&#34;&gt;# XYZ&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;Address&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; 192.168.128.2/32
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;DNS&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; DNS1, DNS2 &lt;span class=&#34;c1&#34;&gt;# found out you VPN DNS server and hard code them here&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;Peer&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PublicKey&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; ... &lt;span class=&#34;c1&#34;&gt;# ABC&amp;#39;s public key&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;AllowedIPs&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; 10.0.0.0/8
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;Endpoint&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; 192.168.1.8:51820 &lt;span class=&#34;c1&#34;&gt;# Use an IP of your bridged VM&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On both sides enable peers. You can test tunnel simply pinging thought it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# from device to VM with SNX&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ ping 192.168.128.2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;firewall&#34;&gt;Firewall&lt;/h2&gt;
&lt;p&gt;Of course without proper firewall setup, an SNX connection won&amp;rsquo;t share. I will use modern &lt;strong&gt;nftables&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/etc/nftables.conf:&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/usr/bin/nft -f
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# ipv4/ipv6 Simple &amp;amp; Safe Firewall&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# you can find examples in /usr/share/nftables/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;flush ruleset
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;table inet filter &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	chain input &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; filter hook input priority 0&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; policy drop&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;c1&#34;&gt;# allow established/related connections&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		ct state &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;established, related&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt; accept
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;c1&#34;&gt;# early drop of invalid connections&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		ct state invalid drop
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;c1&#34;&gt;# allow from loopback&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		iifname lo accept
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;c1&#34;&gt;# allow icmp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		ip protocol icmp accept
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		meta l4proto ipv6-icmp accept
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;c1&#34;&gt;# allow wireguard&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		udp dport &lt;span class=&#34;m&#34;&gt;51820&lt;/span&gt; accept
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;c1&#34;&gt;# everything else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		reject with icmpx &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; port-unreachable
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	chain forward &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; filter hook forward priority 0&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; policy drop&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		ct state &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;established, related&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt; accept
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		ct state invalid drop
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;c1&#34;&gt;# allow forwarding from wireguard interface to snx one&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		iifname wg0 oifname tunsnx ct state new accept
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	chain output &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; filter hook output priority 0&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; policy accept&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;table inet nat &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	chain postrouting &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; nat hook postrouting priority srcnat&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t forget to enable IP forwarding:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;net.ipv4.ip_forward=1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;net.ipv6.conf.all.forwarding=1&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;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&gt;
&lt;p&gt;&lt;code&gt;/etc/systemd/system/snx-firewall.service:&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;Unit&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;Description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;Checkpoint SNX firewall tweaker
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;BindsTo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;sys-subsystem-net-devices-tunsnx.device
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;After&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;sys-subsystem-net-devices-tunsnx.device
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;Service&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;Type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;oneshot
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;RemainAfterExit&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;yes
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ExecStart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/root/bin/snx_add_rule.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ExecStop&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/root/bin/snx_flush_chain.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;Install&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;WantedBy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;sys-subsystem-net-devices-tunsnx.device
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The mix of &lt;code&gt;BindsTo&lt;/code&gt; and &lt;code&gt;RemainsAfterExit&lt;/code&gt; allows us to trigger &lt;code&gt;ExecStart&lt;/code&gt; and &lt;code&gt;ExecStop&lt;/code&gt; at the right time,
when connection starts and when connection stops.&lt;/p&gt;
&lt;p&gt;As you could see above, service also requires two scripts:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/root/bin/snx_add_rule.sh:&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;GATEWAY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;ip -o -4 addr show tunsnx &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; awk &lt;span class=&#34;s1&#34;&gt;&amp;#39;{printf $4}&amp;#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nft add rule inet nat postrouting oifname &lt;span class=&#34;s2&#34;&gt;&amp;#34;tunsnx&amp;#34;&lt;/span&gt; ip daddr 10.0.0.0/8 snat ip to &lt;span class=&#34;nv&#34;&gt;$GATEWAY&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;nftables rule added&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;/root/bin/snx_flush_chain.sh:&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nft flush chain inet nat postrouting
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;nftables flushed&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;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&gt;
&lt;p&gt;Feel free to leave comments below the post.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; I can also recommend removing default cshell autostart (from &lt;code&gt;~/.config/autostart/cshell.desktop&lt;/code&gt;)
because it&amp;rsquo;s not reliable and setup &lt;strong&gt;user&lt;/strong&gt; systemd service:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;Unit&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;Description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;Checkpoint SNX CShell
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;Wants&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;network-online.target
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;After&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;network-online.target
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;Service&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;Type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;simple
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;Environment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;DISPLAY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;:0
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;WorkingDirectory&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/usr/bin/cshell
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Should work for JRE 16+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ExecStart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/usr/bin/java --add-exports java.base/sun.net.spi&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;ALL-UNNAMED -jar CShell.jar /tmp/cshell.fifo
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ExecStop&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/bin/kill -15 &lt;span class=&#34;nv&#34;&gt;$MAINPID&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;SuccessExitStatus&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;143&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;Restart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;on-failure
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;Install&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;WantedBy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;default.target
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;UPDATE 2:&lt;/strong&gt; Rui Ribeiro from comments suggested much nicer method using chroot, &lt;a href=&#34;../2021/04/26/checkpoint-snx-adventure.html#remark42__comment-9d1b502f-e4bc-48df-8146-9bacab3c49e1&#34;&gt;check it&lt;/a&gt;!&lt;/p&gt;
</description>
        </item>
    </channel>
</rss>
