mirror of
https://github.com/He4eT/oddsquat.git
synced 2026-05-04 20:37:22 +00:00
release: 2026-04-03-051115
This commit is contained in:
parent
e1a78fb2f1
commit
1f7f2efb79
75 changed files with 6408 additions and 0 deletions
152
docs/posts/2024/wrapped_bw_ru/index.html
Normal file
152
docs/posts/2024/wrapped_bw_ru/index.html
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0">
|
||||
<link rel="icon" href="/favicon.ico" sizes="32x32">
|
||||
<link rel="icon" href="/icon.svg" type="image/svg+xml">
|
||||
|
||||
|
||||
<title>
|
||||
wrapped bw | oddsquat
|
||||
</title>
|
||||
<meta name="description" content="Превращаем fully-featured Bitwarden command-line interface в удобный.">
|
||||
|
||||
<link rel="preload" href="/fonts/open_sans_condensed-32.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="/fonts/open_sans_condensed-27.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="/fonts/open_sans-25.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="/fonts/open_sans-24.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="/fonts/open_sans-17.woff2" as="font" type="font/woff2" crossorigin>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/css/fonts.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/typography.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/main.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="stripesContainer">
|
||||
<div class="stripes">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<header>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="/">oddsquat</a></li>
|
||||
|
||||
|
||||
<li><a href="/posts/">
|
||||
posts</a></li>
|
||||
|
||||
|
||||
<li><a href="/posts/#2024">
|
||||
2024</a></li>
|
||||
|
||||
|
||||
<li>wrapped bw</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<article>
|
||||
<h1 id="-bitwarden-cli-fzf-">Интеграция Bitwarden CLI с fzf и буфером обмена</h1>
|
||||
<p>Менеджер паролей — это специальное приложение, которое помогает делать вид, что я помню разные пароли для разных аккаунтов, а не ввожу везде один и тот же. Мне нравится Bitwarden: открытый исходный код, возможность поднять собственный сервер, клиенты под разные устройства и расширения под разные браузеры.</p>
|
||||
<p>Самым удобным, внезапно, оказался клиент для Android, который не заставляет меня каждый раз вводить 12+ знаков мастер-пароля (такую длину требуют Bitwarden и здравый смысл), а может быть разблокирован с помощью биометрии. Похожего удобства захотелось достичь и на Linux.</p>
|
||||
<h2 id="-cli">Дикий CLI</h2>
|
||||
<p>На ноутбуке я использую <a href="https://bitwarden.com/help/cli/">Bitwarden CLI</a>. Это powerful, fully-featured tool, которым на практике оказалось не слишком удобно пользоваться, если ты человек.</p>
|
||||
<h3 id="-">Ключи от ключей</h3>
|
||||
<blockquote>
|
||||
<p>You are responsible for maintaining your session key.</p>
|
||||
</blockquote>
|
||||
<p>Bitwarden CLI поддерживает <a href="https://bitwarden.com/help/cli/#using-a-session-key">механизм сессий</a>, который призван избавить пользователя от бесконечного ввода мастер-пароля. Приложение позволяет разблокировать хранилище и получить временный сессионный ключ, который можно либо хранить в беззащитной переменной окружения, либо прикладывать к каждому запросу вручную.</p>
|
||||
<p>По сути своей, сессионный ключ отличается от мастер-пароля тем, что его можно моментально деактивировать, но совершенно невозможно запомнить, а, значит, нужно где-то хранить. Хочется делать это удобно и безопасно, а не в общедоступной переменной окружения.</p>
|
||||
<h3 id="-stdout">Пароли в stdout</h3>
|
||||
<blockquote>
|
||||
<p>The get command can only return one result, so you should use specific search terms. If multiple results are found, the CLI will return an error.</p>
|
||||
</blockquote>
|
||||
<p>Где-то в этот момент чтения документации я окончательно начал подозревать, что официальный CLI предназначен для скриптов: всё строго, никакого автодополнения, никакого интерактивного поиска, а пароли лаконично вываливаются в стандартный вывод терминала, откуда их ещё нужно как-то переправить в место назначения.</p>
|
||||
<h2 id="-cli">Приручение CLI</h2>
|
||||
<p>Может показаться, что я ругаюсь, но отсутствие удобств и излишеств в официальном CLI — это хорошо:</p>
|
||||
<ul>
|
||||
<li>Отсутствие фич всегда приятнее, чем кривые фичи.</li>
|
||||
<li>Минимализм упрощает жизнь мейнтейнерам.</li>
|
||||
<li>Минимализм повышает надёжность.</li>
|
||||
<li>Меньше сторонних зависимостей.</li>
|
||||
<li>Стандартные интерфейсы идеально подходят для автоматизации.</li>
|
||||
</ul>
|
||||
<p>Идея сделать Bitwarden CLI удобнее, разумеется, пришла в голову не только мне, так что на GitHub предсказуемо быстро нашёлся <a href="https://gist.github.com/loeschzwerg/c2b9d0b50f712a026aa6454af3b58598">скрипт-обёртка</a> от <a href="https://github.com/loeschzwerg">@loeschzwerg</a>. Этот ZSH-скрипт менее требователен к пользователю и позволяет в случае, когда под пользовательский поисковый запрос подходит несколько аккаунтов, выбрать нужный из списка с помощью fzf и автоматически скопировать логин, пароль и даже TOTP в буфер обмена.</p>
|
||||
<p>К сожалению, найденный скрипт никак не решал проблему управления сессиями, так что я решил его немного доработать, избавив заодно от избытка многоточий в интерфейсе.</p>
|
||||
<h3 id="-">«Безопасное» хранение сессионного ключа</h3>
|
||||
<p>Как я писал выше, мне нравится подход Android-клиента: нужно один раз ввести свой невероятно длинный мастер-пароль, после чего можно разблокировать хранилище отпечатком пальца. В ходе непродолжительных размышлений я решил, что самое простое и надёжное подобие для приложения в терминале — один раз получить сессионный ключ и сохранить его в файл, который будет доступен для чтения только пользователю <code>root</code> и недоступен любым другим приложениям, запущенным от имени текущего пользователя.</p>
|
||||
<p>Приятный бонус для владельцев биометрических сканеров: они отлично интегрируются с утилитой <code>sudo</code>.</p>
|
||||
<p>В результате скрипт обогатился двумя функциями и одной проверкой:</p>
|
||||
<pre><code class="language-zsh">local sessionfile="$HOME/.bitwarden_session"
|
||||
|
||||
get_saved_sessionkey () {
|
||||
sudo touch $sessionfile
|
||||
echo $(sudo cat $sessionfile)
|
||||
}
|
||||
|
||||
save_sessionkey () {
|
||||
local sessionkey=$1
|
||||
sudo chmod 600 $sessionfile
|
||||
sudo sh -c "echo $sessionkey > $sessionfile"
|
||||
}</code></pre>
|
||||
<pre><code>local sessionkey=$(get_saved_sessionkey)
|
||||
|
||||
if [[ -z $sessionkey ]] ; then
|
||||
# Get and save a new session key
|
||||
sessionkey=$(bw unlock --raw)
|
||||
save_sessionkey $sessionkey
|
||||
else
|
||||
echo "Using the existing session key from '$sessionfile'."
|
||||
fi</code></pre><p>При первом запуске сессионный ключ, полученный после ввода мастер-пароля, записывается в файл, который после выполнения команды <code>chmod 600</code> становится недоступен для чтения никому, кроме суперпользователя:</p>
|
||||
<pre><code>~ » ls -lah
|
||||
...
|
||||
-rw-------. 1 root root 89 Jul 24 22:15 .bitwarden_session
|
||||
...
|
||||
|
||||
~ » less .bitwarden_session
|
||||
.bitwarden_session: Permission denied</code></pre><p>Парольный менеджер и скрипт-обёртка запускаются от имени текущего пользователя, повышение привилегий требуется только в момент записи и чтения сессионного ключа.</p>
|
||||
<p>Деактивировать сохранённый ключ можно с помощью команды <code>bw lock</code>.
|
||||
К сожалению, я так и не понял, как с помощью утилиты <code>bw</code> можно проверить, валиден ли ключ, так что после деактивации придётся удалить файл <code>~/.bitwarden_session</code> вручную, иначе скрипт так и будет подставлять протухший сохранённый ключ, а <code>bw</code> будет каждый раз игнорировать его и настойчиво спрашивать мастер-пароль.</p>
|
||||
<p><strong>Update [2026-03-29]</strong>:
|
||||
Нормального способа проверить валидность сессионного ключа <a href="https://github.com/bitwarden/clients/issues/9254">всё ещё нет</a>,
|
||||
но я научил утилиту удалять файл с протухшим ключом по косвенным признакам.</p>
|
||||
<h2 id="-">Применять с осторожностью</h2>
|
||||
<p>Взаимодействие с менеджером паролей выглядит для меня теперь примерно так:</p>
|
||||
<pre><code>~ » bwc github
|
||||
[sudo] password for $USER:
|
||||
Using the existing session key from '/home/$USER/.bitwarden_session'.
|
||||
Searching for 'github'...
|
||||
|
||||
abcdefgh-ijkl-mnop-qrst-uvwxyz123456
|
||||
github.com
|
||||
|
||||
Username 'username' copied to clipboard.
|
||||
[Press any key to copy the password]
|
||||
Password copied to clipboard.</code></pre><p>Финальный вариант скрипта можно найти в репозитории <a href="https://github.com/He4eT/fuzzy-bitwarden-clipboard">He4eT/fuzzy-bitwarden-clipboard</a>.</p>
|
||||
<p>Настоятельно рекомендую читать любой код перед тем, как запускать его. Особенно в тех случаях, когда речь идёт о настолько чувствительных данных.</p>
|
||||
<p><strong>Важно!</strong> На системах без шифрования диска все эти танцы с правами на доступ к файлу не несут никакой пользы и превращают затею в увлекательный цирк.</p>
|
||||
<p>Нельзя исключать, что я что-то совершенно неправильно понимаю в принципах работы системы прав доступа в Linux и совершил какие-нибудь грубейшие, с точки зрения настоящих специалистов по информационной безопасности, ошибки. Пожалуйста, сообщите, если я где-то неправ.</p>
|
||||
<p>Нужно помнить, что такое упрощение жизни ведёт к новым рискам: теперь любой, кто знает ваш пароль для учётной записи системного пользователя и имеет доступ к компьютеру, будет также иметь доступ и ко всем паролям, сохранённым в Bitwarden.</p>
|
||||
<p>Пользуйтесь с осторожностью и/или храните свои пароли в надёжных местах =)</p>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
2024-07-27
|
||||
</footer>
|
||||
|
||||
<script async
|
||||
data-goatcounter="https://he4et.goatcounter.com/count"
|
||||
src="https://gc.zgo.at/count.js"></script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue