<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>flameshikari</title>
        <link>https://hexed.pw/</link>
        <description>shitposting agency</description>
        <lastBuildDate>Wed, 02 Sep 2026 03:48:34 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>flameshikari</title>
            <url>https://hexed.pw/assets/0f380c6c.png</url>
            <link>https://hexed.pw/</link>
        </image>
        <copyright>© flameshikari 2024–2026</copyright>
        <category>huawei</category>
        <category>keepass</category>
        <category>linux</category>
        <category>proxmox</category>
        <category>shell</category>
        <category>ssh</category>
        <category>wsl</category>
        <atom:link href="https://hexed.pw/rss" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[OmniKeePass]]></title>
            <link>https://hexed.pw/logs/2024-01-09-omnikeepass/</link>
            <guid isPermaLink="false">https://hexed.pw/logs/2024-01-09-omnikeepass/</guid>
            <pubDate>Tue, 09 Jan 2024 07:12:12 GMT</pubDate>
            <description><![CDATA[Making KeePassXC to work with both WSL and Windows envs]]></description>
            <content:encoded><![CDATA[<p><img src="https://hexed.pw/logs/2024-01-09-omnikeepass/assets/_header.png" alt=""></p>
<p>Greetings!</p>
<p>A rather strange first post for my blog, but I have to start somewhere. Sorry in advance for any language mistakes.</p>
<p>But first, a short preface.
Please, don&#39;t be that person who doesn&#39;t care about personal data on the Internet.
Use local/self-hosted password managers (not <a href="https://blog.lastpass.com/2022/12/notice-of-recent-security-incident/">the cloud ones</a>), generate different and strong passwords, use 2FA and make backups.
These words are based on my personal expirience; I used to be the person who doesn&#39;t care, but as I grew up, I realized how vulnerable we are on the Internet, and after several data leaks and hacking attempts, I started using all kinds of safe solutions. 
Don&#39;t be indifferent to your data, otherwise you may regret it.</p>
<p>So, let&#39;s get to the topic.</p>
<p>For a long time I used <a href="https://keepass.info/">KeePass</a> with <a href="https://lechnology.com/software/keeagent/">KeeAgent</a> plugin for forwarding SSH keys from the database to an SSH agent, and it was awesome.
What I liked about this combo:</p>
<ul>
<li><p>If the database is closed and you are trying to connect via SSH, <a href="https://lechnology.com/software/keeagent/">KeeAgent</a> calls <a href="https://keepass.info/">KeePass</a> to open a database for unlocking, and after unlocking the keys will be added to <a href="https://lechnology.com/software/keeagent/">KeeAgent</a>;</p>
</li>
<li><p><a href="https://lechnology.com/software/keeagent/">KeeAgent</a> stores credentials in a non-persist way.</p>
</li>
</ul>
<p>Recently I decided to move to <a href="https://keepassxc.org/">KeePassXC</a> as it has better browser integration and a nicer interface. Since it relies on external agents (<a href="https://github.com/PowerShell/Win32-OpenSSH">Windows OpenSSH</a> or <a href="https://www.chiark.greenend.org.uk/~sgtatham/putty/">Pageant</a>), things I liked don&#39;t work here. I&#39;m used to this, I&#39;ll try to replicate the functionality!</p>
<p>First I started looking for a suitable agent, as supported agents have issues:</p>
<ul>
<li><p><a href="https://github.com/PowerShell/Win32-OpenSSH/issues/1487">Windows OpenSSH stores keys in Windows Registry</a>. For example, if you hard reset a computer keys will remain in the registry (sounds insecure, huh?). Using startup scripts for clearing the agent isn&#39;t the way. Also, there&#39;s <a href="https://github.com/HiFiPhile/openssh-cleaned">a fork of Windows OpenSSH</a> that stores credentials in a non-persist way, but I wanna rely on the upstream version.</p>
</li>
<li><p>Recent versions of <a href="https://the.earth.li/%7Esgtatham/putty/0.78/htmldoc/Chapter9.html#pageant-cmdline-openssh">Pageant can integrate with Windows OpenSSH</a>. Unfortunately, the named pipe path changes each reboot. The issue can be solved with bash/pwsh magic, but I&#39;m trying to make as few dirty hacks as possible (it will sound more ironic when you continue reading that article).</p>
</li>
</ul>
<p>I continued my search for the agent that suits my needs. I found <a href="https://github.com/masahide/OmniSSHAgent">OmniSSHAgent</a>, and it turned out that this is the best solution. It stores keys in a non-persist way and supports all communication interfaces:</p>
<p><img src="https://hexed.pw/logs/2024-01-09-omnikeepass/assets/omnisshagent_diagram.svg" alt=""></p>
<p>Isn&#39;t this a dream?</p>
<p>To use the named pipe from Windows in <a href="https://learn.microsoft.com/en-us/windows/wsl/about">WSL2</a> I could use <a href="http://www.dest-unreach.org/socat/">socat</a> utility, but I decided to use <a href="https://github.com/mame/wsl2-ssh-agent">wsl2-ssh-agent</a>, which <a href="https://github.com/mame/wsl2-ssh-agent#how-wsl2-ssh-agent-works">makes a communication bridge between Windows and WSL2 with PowerShell</a>.</p>
<p><img src="https://hexed.pw/logs/2024-01-09-omnikeepass/assets/wsl2-ssh-agent_diagram.svg" alt=""></p>
<!-- > 1. [Microsoft Edge WebView2](https://developer.microsoft.com/en-us/microsoft-edge/webview2/) is needed to work, but it's like it's available out of the box --><p>Alright, I need to place these utilities somewhere.
I thought: what if I put configs and utilities in Windows&#39; <font class="hljs-attribute">%USERPROFILE%/.ssh</font> and just link that path to <a href="https://learn.microsoft.com/en-us/windows/wsl/about">WSL2</a>&#39;s <font class="hljs-attribute">~/.ssh</font> to have the same config for both environments?
Without <a href="https://learn.microsoft.com/en-us/windows/wsl/wsl-config#automount-options">additional WSL2 tuning</a>, it will not work.
The problem is that Windows files inside <a href="https://learn.microsoft.com/en-us/windows/wsl/about">WSL2</a> don&#39;t store Linux permissions by default, so most Windows files will have all <a href="https://en.wikipedia.org/wiki/File-system_permissions#Numeric_notation">rwx</a> bits, and this will cause SSH clients to throw permission errors. To fix that, I edited <font class="hljs-attribute">/etc/wsl.conf</font>:</p>
<pre><code class="highlight highlight-ini"><span class="pl-en">[automount]</span>
<span class="pl-k">options</span> = <span class="pl-s"><span class="pl-pds">"</span>metadata<span class="pl-pds">"</span></span>
</code></pre><p>Before linking directories, I moved <font class="hljs-attribute">%USERPROFILE%\.ssh</font> to <font class="hljs-attribute">%USERPROFILE%\.ssh.bak</font>, created <font class="hljs-attribute">%USERPROFILE%\.ssh</font>, also moved <font class="hljs-attribute">~/.ssh</font> to <font class="hljs-attribute">~/.ssh.bak</font>. 
After that ran this command:</p>
<pre><code class="highlight highlight-bash">ln -sTv /mnt/c/Users/<span class="pl-s"><span class="pl-pds">$(</span>pwsh.exe -c <span class="pl-pds">'</span>$env:USERNAME<span class="pl-pds">'</span> <span class="pl-k">|</span> tr -d <span class="pl-pds">'</span>\r<span class="pl-pds">')</span></span>/.ssh <span class="pl-smi">$HOME</span>/.ssh
</code></pre><p>Downloaded utilities were placed in <font class="hljs-attribute">~/.ssh/bin</font>.
I added <font class="hljs-string">Include aliases/*</font> in <font class="hljs-attribute">~/.ssh/config</font> to separate aliases between files.
It&#39;s very handy thing for me.
For example, <font class="hljs-attribute">~/.ssh/aliases/git</font> contains aliases for different repo-based platforms:</p>
<pre><code class="highlight highlight-yaml"><span class="pl-s">Host github</span>
  <span class="pl-s">Hostname github.com</span>
  <span class="pl-s">User git</span>

<span class="pl-s">Host gitlab</span>
  <span class="pl-s">Hostname gitlab.com</span>
  <span class="pl-s">User git</span>
</code></pre><p>Then I wrote <a href="https://hexed.pw/logs/2024-01-09-omnikeepass/data/ssh/bin/fix-perms.sh">fix-perms.sh</a> for fixing file permissions (mostly needed to run once after linking directories) and placed it in <font class="hljs-attribute">~/.ssh/bin</font>:</p>
<pre><code class="highlight highlight-sh"><span class="pl-c">#!/usr/bin/env bash</span>
<span class="pl-c1">cd</span> <span class="pl-smi">$HOME</span>/.ssh
chmod 600 authorized_keys config known_hosts<span class="pl-k">*</span> aliases/<span class="pl-k">*</span>
chmod 700 bin/<span class="pl-k">*</span>
</code></pre><p>At this moment I have the next file structure:</p>
<pre><code class="highlight highlight-plaintext">~/.ssh
├── authorized_keys
├── bin
│   ├── init.sh
│   ├── middleware.ps1
│   ├── omni-ssh-agent.exe
│   └── wsl2-ssh-agent
├── config
├── hosts
│   ├── git
│   ├── home
│   └── work
├── known_hosts
└── sockets
    ├── cygwin.socket
    ├── unix.socket
    └── wsl.sock
</code></pre><p>Appended the following command to <font class="hljs-attribute">~/.bashrc</font>:</p>
<pre><code class="highlight highlight-bash"><span class="pl-c1">eval</span> <span class="pl-s"><span class="pl-pds">$(</span><span class="pl-smi">$HOME</span>/.ssh/bin/wsl2-ssh-agent -socket /tmp/wsl.sock<span class="pl-pds">)</span></span>
</code></pre><p>Enabled these options in <a href="https://github.com/masahide/OmniSSHAgent">OmniSSHAgent</a>&#39;s settings:</p>
<p><img src="https://hexed.pw/logs/2024-01-09-omnikeepass/assets/omnisshagent_settings.png" alt=""></p>
<p>Made sure that <a href="https://keepassxc.org/">KeePassXC</a> is correctly configured for integration with the agent:</p>
<p><img src="https://hexed.pw/logs/2024-01-09-omnikeepass/assets/kpxc_agent_settings.png" alt=""></p>
<p>And entries with a key are configured for adding to the agent:</p>
<p><img src="https://hexed.pw/logs/2024-01-09-omnikeepass/assets/kpxc_entry_settings.png" alt=""></p>
<p>Amazing, I got almost everything I need and configured all utilities.
At this moment, the named pipe will be accessible by any program that supports it from both environments.</p>
<p>So, how can I replicate the behavior of <a href="https://lechnology.com/software/keeagent/">KeeAgent</a> when the database is locked?</p>
<p>At first, I decided to write a script that would replicate the behavior of <a href="https://lechnology.com/software/keeagent/">KeeAgent</a>.
Remember what I said about the irony? <a href="https://hexed.pw/logs/2024-01-09-omnikeepass/data/ssh/bin/wrapper.ps1">This is it</a>:</p>
<pre><code class="highlight highlight-powershell"><span class="pl-c">#!/usr/bin/env -S pwsh.exe</span>

<span class="pl-smi">$Database</span> <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">"</span>B:\Cloud\Secrets.kdbx<span class="pl-pds">"</span></span>

<span class="pl-smi">$Agent</span> <span class="pl-k">=</span> <span class="pl-c1">Get-ChildItem</span> <span class="pl-s"><span class="pl-pds">"</span><span class="pl-c1">$PSScriptRoot</span>\omni-ssh-agent.exe<span class="pl-pds">"</span></span>
<span class="pl-smi">$Keepass</span> <span class="pl-k">=</span> <span class="pl-c1">Get-ChildItem</span> <span class="pl-s"><span class="pl-pds">"</span>B:\Programs\KeePassXC\KeePassXC.exe<span class="pl-pds">"</span></span>

<span class="pl-smi">$KeepassWidth</span> <span class="pl-k">=</span> <span class="pl-c1">1280</span>
<span class="pl-smi">$KeepassHeight</span> <span class="pl-k">=</span> <span class="pl-c1">720</span>
<span class="pl-smi">$KeepassFocused</span> <span class="pl-k">=</span> <span class="pl-c1">$False</span>
<span class="pl-smi">$AgentHasNoKeys</span> <span class="pl-k">=</span> <span class="pl-c1">$False</span>

<span class="pl-c1">Add-Type</span> <span class="pl-k">-</span>AssemblyName System.Windows.Forms

<span class="pl-c1">Add-Type</span> <span class="pl-s"><span class="pl-pds">@"</span></span>
<span class="pl-s">    using System;</span>
<span class="pl-s">    using System.Runtime.InteropServices;</span>
<span class="pl-s">    public class WinAPI {</span>
<span class="pl-s">        [DllImport("user32.dll")]</span>
<span class="pl-s">        public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);</span>
<span class="pl-s">        [DllImport("user32.dll")]</span>
<span class="pl-s">        public static extern IntPtr GetForegroundWindow();</span>
<span class="pl-s">        [DllImport("user32.dll")]</span>
<span class="pl-s">        [return: MarshalAs(UnmanagedType.Bool)]</span>
<span class="pl-s">        public static extern bool IsIconic(IntPtr hWnd);</span>
<span class="pl-s">    }</span>
<span class="pl-s"><span class="pl-pds">"@</span></span>

<span class="pl-k">Function</span> <span class="pl-en">Agent-Start</span> {
    <span class="pl-c1">Start-Process</span> <span class="pl-k">-</span>PassThru <span class="pl-smi">$Agent</span> <span class="pl-k">|</span> <span class="pl-c1">Out-Null</span>
    <span class="pl-c1">Start-Sleep</span> <span class="pl-c1">0.5</span>
}

<span class="pl-k">Function</span> <span class="pl-en">Agent-Status</span> {
	<span class="pl-smi">$Output</span> <span class="pl-k">=</span> (C:\Windows\System32\OpenSSH\ssh<span class="pl-k">-</span>add <span class="pl-k">-</span>l <span class="pl-k">2>&#x26;1</span> <span class="pl-k">|</span> <span class="pl-c1">Out-Null</span>)
	<span class="pl-k">Return</span> <span class="pl-c1">$LastExitCode</span>
}

<span class="pl-k">Function</span> <span class="pl-en">Agent-Isnt-Running</span> {
    <span class="pl-k">Return</span> <span class="pl-k">-Not</span> (<span class="pl-c1">Get-Process</span> <span class="pl-k">-</span>ErrorAction SilentlyContinue <span class="pl-smi">$Agent.BaseName</span> <span class="pl-k">|</span> Select <span class="pl-k">-</span>Expand ProcessName)
}

<span class="pl-k">Function</span> <span class="pl-en">Keepass-Start</span> {
    <span class="pl-k">Param</span>([<span class="pl-k">String</span>[]]<span class="pl-smi">$ArgumentList</span> <span class="pl-k">=</span> <span class="pl-smi">$Database</span><span class="pl-k">,</span> [<span class="pl-k">Int</span>]<span class="pl-smi">$Width</span> <span class="pl-k">=</span> <span class="pl-smi">$KeepassWidth</span><span class="pl-k">,</span> [<span class="pl-k">Int</span>]<span class="pl-smi">$Height</span> <span class="pl-k">=</span> <span class="pl-smi">$KeepassHeight</span>)
    <span class="pl-c1">Start-Process</span> <span class="pl-k">-</span>PassThru <span class="pl-smi">$Keepass</span> <span class="pl-k">-</span>ArgumentList <span class="pl-smi">$ArgumentList</span> <span class="pl-k">|</span> <span class="pl-c1">Out-Null</span>
    <span class="pl-c1">Start-Sleep</span> <span class="pl-c1">0.1</span>
    <span class="pl-smi">$Process</span> <span class="pl-k">=</span> <span class="pl-c1">Get-Process</span> <span class="pl-k">-</span>Name <span class="pl-smi">$Keepass.BaseName</span> <span class="pl-k">-</span>ErrorAction SilentlyContinue <span class="pl-k">|</span> <span class="pl-c1">Select-Object</span> <span class="pl-k">-</span>First <span class="pl-c1">1</span>
    <span class="pl-k">If</span> (<span class="pl-k">-Not</span> <span class="pl-smi">$Process</span>) { <span class="pl-k">Return</span> <span class="pl-c1">$False</span> }
    <span class="pl-smi">$Handle</span> <span class="pl-k">=</span> <span class="pl-smi">$Process.MainWindowHandle</span>
    <span class="pl-k">If</span> (<span class="pl-smi">$Handle</span> <span class="pl-k">-eq</span> <span class="pl-c1">0</span>) { <span class="pl-k">Return</span> <span class="pl-c1">$False</span> }
    <span class="pl-smi">$ScreenWidth</span> <span class="pl-k">=</span> [<span class="pl-k">System.Windows.Forms.Screen</span>]::PrimaryScreen.WorkingArea.Width
    <span class="pl-smi">$ScreenHeight</span> <span class="pl-k">=</span> [<span class="pl-k">System.Windows.Forms.Screen</span>]::PrimaryScreen.WorkingArea.Height
    <span class="pl-smi">$X</span> <span class="pl-k">=</span> [<span class="pl-k">Math</span>]::Max(<span class="pl-c1">0</span><span class="pl-k">,</span> (<span class="pl-smi">$ScreenWidth</span> <span class="pl-k">-</span> <span class="pl-smi">$Width</span>) <span class="pl-k">/</span> <span class="pl-c1">2</span>)
    <span class="pl-smi">$Y</span> <span class="pl-k">=</span> [<span class="pl-k">Math</span>]::Max(<span class="pl-c1">0</span><span class="pl-k">,</span> (<span class="pl-smi">$ScreenHeight</span> <span class="pl-k">-</span> <span class="pl-smi">$Height</span>) <span class="pl-k">/</span> <span class="pl-c1">2</span>)
    [<span class="pl-k">WinAPI</span>]::MoveWindow(<span class="pl-smi">$Handle</span><span class="pl-k">,</span> [<span class="pl-k">Int</span>]<span class="pl-smi">$X</span><span class="pl-k">,</span> [<span class="pl-k">Int</span>]<span class="pl-smi">$Y</span><span class="pl-k">,</span> <span class="pl-smi">$Width</span><span class="pl-k">,</span> <span class="pl-smi">$Height</span><span class="pl-k">,</span> <span class="pl-c1">$True</span>)
}

<span class="pl-k">Function</span> <span class="pl-en">Keepass-Status</span> {
    <span class="pl-k">If</span> (<span class="pl-smi">$KeepassFocused</span>) { <span class="pl-k">Return</span> <span class="pl-c1">$False</span> }
    <span class="pl-smi">$Title</span> <span class="pl-k">=</span> <span class="pl-c1">Get-Process</span> <span class="pl-k">-</span>Name <span class="pl-smi">$Keepass.BaseName</span> <span class="pl-k">|</span> <span class="pl-c1">ForEach-Object</span> { <span class="pl-c1">$_</span><span class="pl-smi">.MainWindowTitle</span> }
    <span class="pl-smi">$Status</span> <span class="pl-k">=</span> <span class="pl-k">!</span><span class="pl-smi">$Title.Contains</span>(<span class="pl-s"><span class="pl-pds">"</span>[Locked]<span class="pl-pds">"</span></span>) <span class="pl-k">-And</span> <span class="pl-smi">$Title.Contains</span>(<span class="pl-s"><span class="pl-pds">"</span>- KeePassXC<span class="pl-pds">"</span></span>)
    <span class="pl-k">If</span> (<span class="pl-smi">$Status</span>) {
        <span class="pl-smi">$AgentHasNoKeys</span> <span class="pl-k">=</span> <span class="pl-c1">$True</span>
        <span class="pl-k">Return</span> <span class="pl-c1">$True</span>
    } <span class="pl-k">Else</span> {
        <span class="pl-k">Return</span> <span class="pl-c1">$False</span>
    }
}

<span class="pl-k">Function</span> <span class="pl-en">Keepass-Isnt-Running</span> {
    <span class="pl-k">Return</span> <span class="pl-k">-Not</span> (<span class="pl-c1">Get-Process</span> <span class="pl-k">-</span>ErrorAction SilentlyContinue <span class="pl-smi">$Keepass.BaseName</span> <span class="pl-k">|</span> Select <span class="pl-k">-</span>Expand ProcessName)
}

<span class="pl-k">Function</span> <span class="pl-en">Keepass-Isnt-Active</span> {
    <span class="pl-k">If</span> (<span class="pl-smi">$KeepassFocused</span>) { <span class="pl-k">Return</span> <span class="pl-c1">$False</span> }
    <span class="pl-smi">$Window</span> <span class="pl-k">=</span> [<span class="pl-k">WinAPI</span>]::GetForegroundWindow()
    <span class="pl-smi">$Process</span> <span class="pl-k">=</span> <span class="pl-c1">Get-Process</span> <span class="pl-k">-</span>ErrorAction SilentlyContinue <span class="pl-k">-</span>Name <span class="pl-smi">$Keepass.BaseName</span>
    <span class="pl-k">If</span> (<span class="pl-smi">$Process</span> <span class="pl-k">-and</span> <span class="pl-smi">$Process.MainWindowHandle</span> <span class="pl-k">-ne</span> <span class="pl-c1">0</span>) {
        <span class="pl-smi">$IsMinimized</span> <span class="pl-k">=</span> [<span class="pl-k">WinAPI</span>]::IsIconic(<span class="pl-smi">$Process.MainWindowHandle</span>)
        <span class="pl-smi">$IsNotActive</span> <span class="pl-k">=</span> <span class="pl-smi">$Process.MainWindowHandle</span> <span class="pl-k">-ne</span> <span class="pl-smi">$Window</span>
        <span class="pl-smi">$KeepassFocused</span> <span class="pl-k">=</span> <span class="pl-c1">$True</span>
        <span class="pl-k">Return</span> (<span class="pl-smi">$IsMinimized</span> <span class="pl-k">-or</span> <span class="pl-smi">$IsNotActive</span>)
    } <span class="pl-k">Else</span> {
        <span class="pl-smi">$KeepassFocused</span> <span class="pl-k">=</span> <span class="pl-c1">$True</span>
        <span class="pl-k">Return</span> <span class="pl-c1">$True</span>
    }
}

<span class="pl-k">While</span> (<span class="pl-smi">$Status</span> <span class="pl-k">=</span> Agent<span class="pl-k">-</span>Status) {
    <span class="pl-k">Switch</span> (<span class="pl-smi">$Status</span>) {
        <span class="pl-c1">2</span> {
            <span class="pl-k">If</span> (Agent<span class="pl-k">-</span>Isnt<span class="pl-k">-</span>Running) {
                <span class="pl-smi">$KeepassFocused</span> <span class="pl-k">=</span> <span class="pl-c1">$True</span>
                Agent<span class="pl-k">-</span>Start
                <span class="pl-c1">Start-Sleep</span> <span class="pl-c1">0.5</span>
                Keepass<span class="pl-k">-</span>Start <span class="pl-k">-</span>ArgumentList <span class="pl-k">--</span>lock
            }
        }
        <span class="pl-c1">1</span> {
            <span class="pl-k">If</span> (Keepass<span class="pl-k">-</span>Isnt<span class="pl-k">-</span>Running) {
                Keepass<span class="pl-k">-</span>Start
            }
            <span class="pl-k">If</span> (Keepass<span class="pl-k">-</span>Status) {
                <span class="pl-smi">$KeepassFocused</span> <span class="pl-k">=</span> <span class="pl-c1">$True</span>
                <span class="pl-smi">$AgentHasNoKeys</span> <span class="pl-k">=</span> <span class="pl-c1">$True</span>
                Keepass<span class="pl-k">-</span>Start <span class="pl-k">-</span>ArgumentList <span class="pl-k">--</span>lock
            }
            <span class="pl-k">If</span> (Keepass<span class="pl-k">-</span>Isnt<span class="pl-k">-</span>Active) {
                <span class="pl-smi">$KeepassFocused</span> <span class="pl-k">=</span> <span class="pl-c1">$True</span>
                Keepass<span class="pl-k">-</span>Start
            }
        }
        <span class="pl-c1">0</span> {
            <span class="pl-k">Exit</span> <span class="pl-c1">0</span>
        }
    }
	<span class="pl-c1">Start-Sleep</span> <span class="pl-c1">0.5</span>
}
</code></pre><p>I placed that script in <font class="hljs-attribute">~/.ssh/bin/wrapper.ps1</font>.
Logic explanation using pseudocode:</p>
<pre><code class="highlight highlight-python"><span class="pl-k">while</span> omnisshagent <span class="pl-k">is</span> empty:
  <span class="pl-k">if</span> omnisshagent <span class="pl-k">is</span> <span class="pl-k">not</span> running:
    startomnisshagent
  <span class="pl-k">if</span> keepassxc <span class="pl-k">is</span> <span class="pl-k">not</span> running:
    start keepassxc
  <span class="pl-k">if</span> keepassxc <span class="pl-k">is</span> minimized to tray:
    unminize keepassxc
</code></pre><p>Should be easy to understand.
Of course, I made sure that a million copies of programs will not spawn in that loop.</p>
<p>Now I must realize how to run that script before an SSH connection.
A wrapper for <font class="hljs-attribute">/usr/bin/ssh</font> in <font class="hljs-attribute">/usr/local/bin/ssh</font>?
Meh.
It will only work in <a href="https://learn.microsoft.com/en-us/windows/wsl/about">WSL2</a> by running <font class="hljs-built_in">ssh</font>.
I need something to make the wrapper run anytime an SSH connection starts.
It makes sense to set this up somewhere in the SSH config.
<a href="https://man7.org/linux/man-pages/man5/ssh_config.5.html">ProxyCommand</a>?
Ok, let&#39;s try:</p>
<pre><code class="highlight highlight-bash">Host <span class="pl-k">*</span>
  ProxyCommand <span class="pl-s"><span class="pl-pds">"</span>pwsh.exe -c c:/users/%u/.ssh/wrapper.ps1<span class="pl-pds">"</span></span>
</code></pre><p>The command above was selected so that it runs equally well from both environments.</p>
<p>To use that option properly, <a href="https://man.openbsd.org/nc.1">nc</a> must be called at the end of <font class="hljs-attribute">wrapper.ps1</font> with specific arguments to <a href="https://blog.pcarleton.com/post/ssh-proxy/">create a TCP connection between the client and the server</a>.
I rewrote the wrapper a little to be able to get arguments from the SSH config.
The config now:</p>
<pre><code class="highlight highlight-bash">Host <span class="pl-k">*</span>
  ProxyCommand <span class="pl-s"><span class="pl-pds">"</span>pwsh.exe -c c:/users/%u/.ssh/wrapper.ps1 %h %p<span class="pl-pds">"</span></span>
</code></pre><p>Where <font class="hljs-variable">%h</font> is the hostname of the target alias, and <font class="hljs-variable">%p</font> is the port of the target alias.</p>
<p>Sadly, connections end up with a bad length error when I call Windows programs from <font class="hljs-attribute">wrapper.ps1</font>.
I haven&#39;t figured out what the problem is.
I think Windows programs create unwanted output that passes in stdin of the server then an error occurs.
I tried to call programs with output redirection, tried it via shell script, tried <font class="hljs-built_in">nc</font> for <a href="https://nmap.org/ncat/">Windows</a> and <a href="https://man.openbsd.org/nc.1">Linux</a>, feels like I tried everything — no luck, skill issue for sure…</p>
<p>…then <a href="https://man.openbsd.org/ssh_config#Match">Match</a> walks into the bar:</p>
<pre><code class="highlight highlight-bash">Match Host <span class="pl-k">*</span> <span class="pl-c1">exec</span> <span class="pl-s"><span class="pl-pds">"</span>pwsh.exe -c c:/users/%u/.ssh/wrapper.ps1<span class="pl-pds">"</span></span>
</code></pre><p>Yes, <a href="https://en.wikipedia.org/wiki/RTFM">RTFM</a> moment.
Yes, it just runs the command before the connection.
Yes, no more dirty hacking in between.</p>
<p>The final file structure:</p>
<pre><code class="highlight highlight-plaintext">~/.ssh
├── aliases
│   └── git
├── bin
│   ├── fix-perms.sh
│   ├── omni-ssh-agent.exe
│   ├── wrapper.ps1
│   └── wsl2-ssh-agent
└── config
</code></pre><p>And <a href="https://hexed.pw/logs/2024-01-09-omnikeepass/data/ssh/config">the SSH config</a>:</p>
<pre><code class="highlight highlight-bash">Include aliases/<span class="pl-k">*</span>
Match Host <span class="pl-k">*</span> <span class="pl-c1">exec</span> <span class="pl-s"><span class="pl-pds">"</span>pwsh.exe -c c:/users/%u/.ssh/bin/wrapper.ps1<span class="pl-pds">"</span></span>
</code></pre><p>Additionaly I added a handler to connect to aliases via <font class="hljs-string">ssh://</font> handler. It can be called from <a href="https://keepassxc.org/">KeePassXC</a>, Windows Run, a web browser, etc. <a href="https://hexed.pw/logs/2024-01-09-omnikeepass/data/ssh_handler.reg">Source code of the handler</a>:</p>
<pre><code class="highlight highlight-re">Windows Registry Editor Version <span class="pl-c1">5.00</span>

[<span class="pl-c1">HKEY_CLASSES_ROOT</span>\ssh]
@=<span class="pl-s"><span class="pl-pds">"</span>URL:Windows OpenSSH Handler<span class="pl-pds">"</span></span>
<span class="pl-s"><span class="pl-pds">"</span>URL Protocol<span class="pl-pds">"</span></span>=<span class="pl-s"><span class="pl-pds">""</span></span>

[<span class="pl-c1">HKEY_CLASSES_ROOT</span>\ssh\shell]
[<span class="pl-c1">HKEY_CLASSES_ROOT</span>\ssh\shell\open]
[<span class="pl-c1">HKEY_CLASSES_ROOT</span>\ssh\shell\open\command]
@=<span class="pl-s"><span class="pl-pds">"</span>pwsh -wd ~ -c ssh %1<span class="pl-pds">"</span></span>
</code></pre><p>The last line can be replaced with the following option to connect to the alias from <a href="https://learn.microsoft.com/en-us/windows/wsl/about">WSL2</a> or by creating a separate handler with a different name:</p>
<pre><code class="highlight highlight-re">@=<span class="pl-s"><span class="pl-pds">"</span>bash -c 'eval $($HOME/.ssh/wsl2-ssh-agent -socket /tmp/wsl2.sock) ssh %1'<span class="pl-pds">"</span></span>
</code></pre><p>And finally I got what I wanted:</p>
<p><video muted loop controls autoplay src="https://hexed.pw/logs/2024-01-09-omnikeepass/assets/result.mp4"></video></p>
]]></content:encoded>
            <author>mail@hexed.pw (flameshikari)</author>
            <enclosure url="https://hexed.pw/logs/2024-01-09-omnikeepass/assets/_header.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[iBMA in Proxmox]]></title>
            <link>https://hexed.pw/logs/2024-05-09-ibma-proxmox/</link>
            <guid isPermaLink="false">https://hexed.pw/logs/2024-05-09-ibma-proxmox/</guid>
            <pubDate>Thu, 09 May 2024 18:12:11 GMT</pubDate>
            <description><![CDATA[Installing iBMA in Proxmox]]></description>
            <content:encoded><![CDATA[<p><img src="https://hexed.pw/logs/2024-05-09-ibma-proxmox/assets/_header.png" alt=""></p>
<p>I had a little problem at work with a Huawei blade server.
I wanted to see the hardware information and manage things from <a href="https://en.wikipedia.org/wiki/Intelligent_Platform_Management_Interface">IPMI</a> called <a href="https://e.huawei.com/en/products/computing/kunpeng/accessories/ibmc">iBMC</a>, but to do this I needed to install the agent called <a href="https://support.huawei.com/enterprise/en/doc/EDOC1100218100/426cffd9">iBMA</a> on the host system, in my case <a href="https://proxmox.com">Proxmox</a>.</p>
<p>Well, I started digging for the information on the Huawei Enterprise website which is a real headache to interact.
I found that I needed to <a href="https://support.huawei.com/enterprise/en/doc/EDOC1100218100/b5683fc2">compile the driver</a> and <a href="https://support.huawei.com/enterprise/en/doc/EDOC1100218100/667adef0">install the service</a>.
It seems okay, I found the information, it&#39;s probably worth downloading the software to start somehow now.
Tried to download the latest <a href="https://support.huawei.com/enterprise/en/server/ibma-pid-21099187/software/">software</a> and... <em>*sigh*</em></p>
<p><img src="https://hexed.pw/logs/2024-05-09-ibma-proxmox/assets/bruh.png" alt=""></p>
<p>Support replied with a standard excuse that their system is being updated and maintained.
I got the same error when I tried to download something from there a year ago.
Infinite maintainance, unlucky me or sanctions?
Who knows.</p>
<p>I went looking for where I could download the packages.
By some luckily random query in Google I found <a href="https://mysite.zaixia108.com/archives/1708076797558">zaixia108&#39;s article</a> about installing <a href="https://support.huawei.com/enterprise/en/doc/EDOC1100218100/426cffd9">iBMA</a> with more easier instruction and, most importantly, download links.
All kudos to this man.</p>
<p>Judging by the article, some code lines about errors that could confuse the user are commented out in the package.
Also, there are no original packages and checksums, so I installed all this at my own risk.
I hope I won&#39;t be connected to a Chinese botnet.
I&#39;m just living on the edge.</p>
<p>So, I did everything as in <a href="https://mysite.zaixia108.com/archives/1708076797558">zaixia108&#39;s article</a> and it started up fine:</p>
<p><img src="https://hexed.pw/logs/2024-05-09-ibma-proxmox/assets/software_info.png" alt=""></p>
<p>Just in case I bundled everything to a small archive without unnecessary packages for other distros and wrote a script for automatic installation.
If you wanna try it, you can download the bundle <a href="https://hexed.pw/storage/logs/2_ibma_proxmox/">here</a>.
Just unzip it somewhere in your Proxmox and run <code>setup.sh</code>, but beware: <font class="hljs-variable">this is all at your own risk</font>!</p>
<p>To be honest, my simple script doesn&#39;t seem like it should break anything…</p>
<pre><code class="highlight highlight-bash"><span class="pl-c">#!/usr/bin/env bash</span>

<span class="pl-c1">set</span> -e

DEBIAN_FRONTEND=noninteractive

WORK_DIR=<span class="pl-s"><span class="pl-pds">"$(</span>dirname <span class="pl-pds">"$(</span>readlink -f <span class="pl-pds">"</span><span class="pl-smi">${0}</span><span class="pl-pds">")")"</span></span>
DRIVER_DIR=<span class="pl-smi">$WORK_DIR</span>/driver
SERVICE_DIR=<span class="pl-smi">$WORK_DIR</span>/service

KERNEL_VER=<span class="pl-s"><span class="pl-pds">$(</span>uname -r<span class="pl-pds">)</span></span>
DRIVER_VER=<span class="pl-s"><span class="pl-pds">$(</span>cat <span class="pl-smi">$DRIVER_DIR</span>/build_manual.sh <span class="pl-k">|</span> grep -Po <span class="pl-pds">'</span>(?&#x3C;=DRV_VERSION=).*<span class="pl-pds">')</span></span>
SERVICE_VER=<span class="pl-s"><span class="pl-pds">$(</span>cat <span class="pl-smi">$SERVICE_DIR</span>/install.sh <span class="pl-k">|</span> grep -Po <span class="pl-pds">'</span>(?&#x3C;=IBMA_VERSION=).*<span class="pl-pds">')</span></span>


<span class="pl-c1">echo</span> -e <span class="pl-s"><span class="pl-pds">'</span>> Installing dependencies<span class="pl-pds">'</span></span>
sudo apt-get update -q
sudo apt-get install -qy dkms pve-headers-<span class="pl-smi">$KERNEL_VER</span>
cp -vf /usr/src/linux-headers-<span class="pl-smi">$KERNEL_VER</span>/include/linux/stdarg.h <span class="pl-smi">$DRIVER_DIR</span>/edma_drv 


<span class="pl-c1">echo</span> -e <span class="pl-s"><span class="pl-pds">"</span>\n> Building the driver<span class="pl-pds">"</span></span>
bash <span class="pl-smi">$DRIVER_DIR</span>/build_manual.sh linux-headers-<span class="pl-smi">$KERNEL_VER</span>
cp -vf <span class="pl-smi">$DRIVER_DIR</span>/ibmadriver-<span class="pl-smi">$KERNEL_VER</span>-<span class="pl-smi">$DRIVER_VER</span>-linuxheaders.amd64.deb <span class="pl-smi">$SERVICE_DIR</span>/drivers/Debian


<span class="pl-c1">echo</span> -e <span class="pl-s"><span class="pl-pds">"</span>\n> Installing the service<span class="pl-pds">"</span></span>
sudo systemctl stop iBMA.service <span class="pl-k">2></span> /dev/null <span class="pl-k">||</span> <span class="pl-c1">true</span>
bash <span class="pl-smi">$SERVICE_DIR</span>/install.sh -s

<span class="pl-c1">echo</span> -e <span class="pl-s"><span class="pl-pds">"</span>\n> Done! Don't forget to reboot the server.<span class="pl-pds">"</span></span>
<span class="pl-c1">exit</span> 0
</code></pre><p>…but here is a chance that Huawei software will do it.</p>
<p>And another just-in-case moment: I <a href="https://hexed.pw/storage/logs/2_ibma_proxmox/mirror/">mirrored packages</a> from <a href="https://mysite.zaixia108.com/archives/1708076797558">zaixia108&#39;s article</a>.</p>
]]></content:encoded>
            <author>mail@hexed.pw (flameshikari)</author>
            <enclosure url="https://hexed.pw/logs/2024-05-09-ibma-proxmox/assets/_header.png" length="0" type="image/png"/>
        </item>
    </channel>
</rss>