Всем привет. В этой статье я хотел бы поделиться своим опытом настройки и использования pass — менеджера паролей для Linux и не только, примечательного своей простотой, использованием уже присутствующих в системе инструментов и возможностью работать исключительно из консоли. Конкретнее, будут затронуты проблемы, связанные с генерацией и хранением секретного ключа gpg, а также с настройкой совместной работы pass, gpg, git, github и браузера. Всё — под Linux, Windows и Android.
Что это такое и как оно работает
Технически pass является очень простой обвязкой над GnuPG и git, написанной на bash. Каждый пароль (и сопутствующая ему информация, например логин) хранится в зашифрованном файле. Поиск нужного пароля осуществляется по имени файла, шифрование — при помощи GnuPG, синхронизация между устройствами — при помощи git.
Кроме оригинального pass есть еще два совместимых с ним популярных проекта, работающих и под Windows:
- QtPass. GUI-приложение, написанное, как нетрудно догадаться, на Qt.
- Gopass. Приложение для командной строки, написанное на go. Под Windows я пользуюсь именно им. Однако, на мой взгляд, разработчики начали добавлять туда слишком много лишних фич, при этом отказываясь от интуитивности.
Разработчик pass — Джейсон Доненфельд, также являющийся автором WireGuard (реализации VPN на основе современных стандартов криптографии, "work of art по сравнению с OpenVPN и IPSec" по мнению Линуса Торвальдса, которая скорее всего появится в ядре Linux 5.6).
Создание секретного ключа
GnuPG — система для шифрования и электронных подписей. Несмотря на недостатки (вот, например, статья с критикой gpg), она уже больше 20 лет остается де-факто стандартом. Даже статья по ссылке затрудняется назвать альтернативный инструмент для шифрования файлов.
Процесс создания секретного ключа в консоли описан например на habr, но почему бы не сделать это в GUI? В проекте KDE сделали фронтенд для GPG под названием Kleopatra. Пользователи Linux найдут его в репозиториях, а в gpg4win Kleopatra есть из коробки.
В меню выбираем File
— New Key Pair
— Create a personal OpenPGP key pair
.
Вводим имя и email. Не нужно беспокоиться, что в будущем вы их смените. GPG позволяет свободно добавлять к ключу новые uid и удалять существующие. Если хотите подписывать создаваемым ключом свои git-коммиты и видеть плашки "Verified" напротив них, то тут нужно указать реальный email, имеющий статус "подтвержденный" в вашем аккаунте на github.
Далее нажимаем Advanced Settings
для настройки параметров ключа.
![](https://habrastorage.org/webt/73/_t/sf/73_tsfmk36_soxx0wybhhpmmlpa.png)
В разделе Key Material
выбираем ECDSA/EdDSA
+ ECDH
. Я предпочитаю использовать не классический алгоритм RSA, а основанные на эллиптических кривых ed25519/cv25519. Их основное преимущество над RSA с точки зрения конечного пользователя — меньший размер ключа при аналогичной криптостойкости. Утверждается, что ключ ed25519 длиной 256 бит примерно такой же стойкий, как ключ RSA длиной 3072 бита. Единственное преимущество последнего — большая распространенность, особенно в аппаратных системах.
В меню еще можно выбрать семейства кривых Brainpool и NIST. Однако вторые подозреваются в наличии бэкдора NSA, и к первым тоже есть небольшие претензии. Поэтому предложенные известным криптографом Даниэлем Бернштейном ed25519 и cv25519 — лучший выбор.
Интересный факт: в активно продвигаемом сейчас стандарте аутентификации FIDO U2F (в разработке которого активно участвовала компания Google) применяются именно кривые NIST. Также, например, в Android Keystore есть их поддержка, но нет поддержки ed25519. Почему так произошло?
В результате будет создано 2 подключа на эллиптических кривых. Один для подписей, другой для шифрования, что нам и нужно. GPG не позволяет использовать один подключ и для того, и для другого, несмотря на то что алгоритмически это возможно (соответствующие функции есть, например, в библиотеке libsodium
).
Если планируете использовать этот ключ для работы с git, то в разделе Certificate Usage
нужно отметить пункты Signing
и Authentication
.
На следующем шаге предлагается придумать пароль, с помощью которого будет защищен ключ. Поскольку ключ будет использоваться для шифрования всех данных в хранилище, этот пароль является мастер-паролем. Стоит подойти к его выбору с особой педантичностью.
Генерация мастер-пароля
Разумеется, всегда можно сгенерировать случайную строку из достаточного (например 20) количества символов. Однако её практически невозможно запомнить и трудно ввести без ошибок, особенно на смартфоне. Поэтому EFF в своем гайде рекомендует вместо этого пользоваться парольными фразами.
Метод работает так: берем достаточно большой словарь (EFF предлагает несколько словарей, например этот) и выбираем из него не менее 6 случайных слов. Выбирать можно как угодно, даже вообще без компьютера при помощи игральной кости или монетки. Такой метод называется diceware. До игральных костей и монеток я еще не дошел, поэтому просто воспользуюсь входящей в состав GNU coreutils утилитой shuf
:
$ shuf --random-source=/dev/random -n 6 ./eff_large_wordlist.txt
51345 rendering
24564 edging
65652 vivacious
31343 footprint
55261 snore
24436 earache
Сохраняем эту парольную фразу в надежном месте за пределами компьютера.
В результате будет создан секретный ключ. При работе в консоли часто придётся указывать его fingerprint, стоит записать это число.
Теперь можно настроить интеграцию gpg и git.
Интеграция gpg, git и github
Строго говоря, этот пункт не обязателен. Хранилище паролей pass — это просто каталог с зашифрованными файлами, а значит, его можно синхронизировать как угодно. Google Drive, Яндекс.Диск, и т.д. и т.п. Если не хотите использовать git, то советую обратить внимание на Syncthing. Это программа с открытым исходным кодом, которая требует минимум настроек и передаёт файлы напрямую между устройствами, не храня их на сторонних серверах.
В качестве git-хостинга никто не мешает поднять свой собственный сервер, поставив туда например Gitea, однако это означает затраты на его поддержку и не обязательно гарантирует большие безопасность и надежность. Поэтому я, не гнушаясь пользоваться продуктами фирмы Microsoft, просто создал приватный репозиторий на github.
Стандартный механизм аутентификации в git — с помощью SSH. Обычно подразумевается, что для этого нужен специальный ключ ssh. Однако есть возможность, не плодя лишние сущности, использовать созданный на предыдущем шаге ключ gpg. Чтобы gpg-ключ (точнее, подключ) мог использоваться ssh, должны быть выполнены два условия:
- у него должен быть установлен флаг
A
— Authenticate; - его keygrip должен быть прописан в файле
~/.gnupg/sshcontrol
.
Первый пункт уже выполнен, а получить keygrip можно командой
gpg --list-secret-keys --with-keygrip 0609C9DFEF1AA2B38DEDBADCC0544B5554068AC7
В выводе gpg нас интересует keygrip подключа ed25519 (05B6641E23D720E87EE6A26020BAB214B842F2B7
).
Теперь можно загрузить публичный ключ на github. Заходим в раздел SSH and GPG keys
в профиле и выбираем New SSH key
. В консоли набираем
$ gpg --export-ssh-key 0609C9DFEF1AA2B38DEDBADCC0544B5554068AC7
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPfj81nennAoujvw1fLzGx9iED34zk5oDMYKuUcBq5wv openpgp:0x54068AC7
и копируем получившийся публичный ssh-ключ.
Git может подписывать коммиты с помощью gpg, и github это поддерживает. Думаю, это полезная для безопасности фича. Экспортируем публичный ключ gpg командой
$ gpg --export --armor 0609C9DFEF1AA2B38DEDBADCC0544B5554068AC7
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEXcrHrBYJKwYBBAHaRw8BAQdA9+PzWd6ecCi6O/DV8vMbH2IQPfjOTmgMxgq5
RwGrnC+0G0hlbGxvIEhhYnIgPGZha2VAZW1haWwuY29tPoiQBBMWCAA4BQsJCAcC
BhUKCQgLAgQWAgMBAh4BAheAFiEEBgnJ3+8aorON7brcwFRLVVQGiscFAl3WO2wC
GyMACgkQwFRLVVQGiscg5AEAkh0a6OQS2CPiXq9bWB+wULHUGT6NYZhwZ3eUQCfH
Zq0A/iFBJQkAZIFdqH84ksFbvv6K/LQy72NRJzK0tho6qFwHuDgEXcrHrBIKKwYB
BAGXVQEFAQEHQEs6UVOtj5yMGxvRcMU577miH/Bh5kZWMJKHxsDBcXV4AwEIB4h4
BBgWCAAgFiEEBgnJ3+8aorON7brcwFRLVVQGiscFAl3Kx6wCGwwACgkQwFRLVVQG
isea8wD/X5JSJW0PMu/KucytUZZo8obHa86/TUwH/8+xQ3+djuEBALugbQRmCIr5
/JYO7x5PNA0QYqhh7LIZ9nKYp0mhqpcO
=dc89
-----END PGP PUBLIC KEY BLOCK-----
и копируем то, что получилось, в форму New GPG key
.
Дальнейшие действия специфичны для используемой операционной системы.
Интеграция gpg и git (linux)
Используемый git клиент OpenSSH может получать ключи двумя способами: из каталога ~/.ssh
и через сокет, созданный демоном ssh-agent
. В качестве последнего может выступать gpg-agent
, чем мы и воспользуемся. В файле ~/.gnupg/gpg-agent.conf
нужно прописать строку enable-ssh-support
.
Перезапускаем gpg-agent командой
gpg-connect-agent reloadagent /bye
После этого он создаст сокет по адресу
${XDG_RUNTIME_DIR}/gnupg/S.gpg-agent.ssh
Этот путь (он может зависеть от дистрибутива) надо прописать в переменной окружения $SSH_AUTH_SOCK
, и ssh его подхватит. Набираем в консоли команду
ssh -T git@github.com
и если все прошло успешно, то после ввода мастер-пароля появится сообщение об успешной аутентификации.
Интеграция gpg и git (Windows)
Относительно недавно Microsoft добавила OpenSSH в число доступных для установки компонентов Windows, а также реализовала поддержку сокетов типа AF_UNIX
, таких как тот самый SSH_AUTH_SOCK
. Тем не менее, Win32-OpenSSH не умеет взаимодействовать с gpg4win, так как до сих пор использует только именованные каналы.
Поэтому придётся установить вечнозелёный Putty. Прописываем в файле
~/AppData/Roaming/gnupg/gpg-agent.conf
строку enable-putty-support
и перезапускаем gpg-agent. После этого он начнет прикидываться Pageant — демоном ключей. В той же папке должен быть расположен и файл sshcontrol
.
Чтобы git-клиент начал использовать putty, нужно создать переменную окружения GIT_SSH
с путем до plink.exe
. Например, у меня это
C:\ProgramData\chocolatey\bin\PLINK.EXE
Кстати насчет git. Обычно устанавливающийся клиент git for windows
содержит много ненужного (по крайней мере, ненужного для работы gopass), например собственную реализацию OpenSSH. Однако его разработчики делают и более легкие версии, которые можно скачать на github. Например, там есть в 2 раза меньший по размеру MinGit, а рисковые люди могут попробовать и MinGit-busybox. Версия busybox возникла из-за стремления разработчиков создать git-клиент, использующий api Win32 без прослоек вроде MSYS2. Однако, по их же отзывам, mingit-busybox пока содержит много багов. Подробнее об этих усилиях можно почитать в тикете.
Убеждаемся, что gpg-agent запущен (gpg-connect-agent /bye
), и проверяем соединение с github:
plink git@github.com
Настройка git
Здесь ничего необычного. Думаю, команды можно привести без комментариев:
git config --global user.name "Hello Habr"
git config --global user.email fake@email.com
git config --global user.signingKey 0609C9DFEF1AA2B38DEDBADCC0544B5554068AC7
git config --global gpg.program /usr/bin/gpg
git config --global commit.gpgSign true
Пункт gpg.program
нужен, если gpg нет в PATH
.
Бэкап секретного ключа
Секретный ключ стоит хранить так же надежно, как и парольную фразу, то есть за пределами компьютера. Можно просто распечатать длинную последовательность чисел, но распознавать её или вводить с клавиатуры — занятие не для слабонервных. Поэтому я предпочитаю генерировать QR-код, который легко отсканировать любым смартфоном. Для этого есть специальная программа qrencode
. Генерация картинки с QR-кодом выполняется так:
gpg --export-secret-key 0609C9DFEF1AA2B38DEDBADCC0544B5554068AC7 | qrencode --8bit --output secret-key.qr.png
Разумеется, чем меньше ненужной информации в бэкапе, тем лучше. Здесь очень кстати приходится небольшой размер ключа ed25519. Спасибо Даниэлю Бернштейну!
Существует специальная утилита paperkey, позволяющая сократить объем данных до предела. Ценой сокращения является то, что секретный ключ из такого бэкапа можно будет восстановить только при наличии публичного. В экосистеме GPG есть специальные сервера для хранения публичных ключей, почитать про них и не только можно в статье https://eax.me/gpg/.
Бэкап paperkey создается следующим образом:
gpg --export-key 0609C9DFEF1AA2B38DEDBADCC0544B5554068AC7 > pubkey.asc
gpg --export-secret-key 0609C9DFEF1AA2B38DEDBADCC0544B5554068AC7 | paperkey --output-type raw | qrencode --8bit --output secret-key.qr.png
Второе правило бэкапера: бэкап не существует, пока не подтверждена возможность восстановить из него данные. Поэтому проводим стресс-тест. Удаляем секретный ключ командой
gpg --delete-secret-key 0609C9DFEF1AA2B38DEDBADCC0544B5554068AC7
Затем сканируем QR-код и импортируем ключ обратно в GPG. В качестве сканера QR-кодов под Android мне нравится BinaryEye, свободная программа с удобным интерфейсом. На картинке ниже — бэкап секретного ключа из этой статьи.
![](https://habrastorage.org/webt/ej/xv/un/ejxvunen3dhkjbktvla6clwajjm.png)
paperkey --pubring pubkey.asc --secrets from_qr.asc > secretkey.asc
gpg --import ./secretkey.asc
Надеюсь, вы нигде не будете использовать этот ключ. Он создан только для иллюстрации.
Если все работает, то можно двигаться дальше.
Использование (go)pass
Теперь, когда у нас есть надежно сохраненный и защищенный секретный ключ, а также работающая интеграция с git, можно начинать пользоваться собственно pass. Я предпочитаю gopass, так как эта альтернативная обвязка работает под Windows.
Инициализируем хранилище паролей командой
gopass init
и выбираем из списка нужный секретный ключ.
Работа с git происходит так же, как в случае с обычным репозиторием, только в командной строке надо дописывать (go)pass
. Инициализируем репозиторий и добавляем туда нужный origin:
gopass git init
gopass git remote add origin git@github.com:xxx/taisho-secrets.git
Адрес можно узнать на странице репозитория на github, нажав кнопку Clone or download
.
В gopass есть специфичная команда
gopass sync
выполняющая и git pull
, и git push
, то есть полную синхронизацию.
Хранилище по умолчанию создается в папке ~/.password-store
, но можно указать и свой путь.
Для работы с паролями в консоли поддерживаются команды ls, cp, mv, search, create, и т.п. Полный список можно получить, набрав gopass --help
, но лично я 95% времени пользуюсь не консолью, а плагином для браузера.
Интеграция с браузером
Плагин для браузера называется gopass bridge, его можно найти в сторах Chrome и Firefox (см. ссылку).
Для связи плагина с собственно gopass понадобятся вспомогательный скрипт и манифест для native messaging. Они создаются командой
gopass jsonapi configure
которая предложит нам выбрать браузер и расположение скрипта.
Проверяем, как все работает. Создаем новый пароль:
gopass new habr
отвечаем на все вопросы и сохраняем. GPG предложит ввести мастер-пароль для работы с секретным ключoм.
Теперь открываем меню плагина с характерным голубым сусликом, и если все прошло успешно, то мы сможем найти там свой пароль.
TOTP-ключи
Лично я пользуюсь FreeOTP, однако с этими ключами можно работать и с помощью pass. Пользователям оригинального pass надо установить расширение pass-otp, а в gopass и APS (см. ниже) нужные функции есть из коробки.
Чтобы добавить TOTP-ключ в хранилище паролей при помощи pass-otp, получаем URL (начинающийся с otpauth://
) и вводим команду
pass otp insert totp-secret
Можно ли будет назвать двухфакторной получившуюся аутентификацию — спорный вопрос. Разработчики KeePassXC рекомендуют хранить TOTP-ключи в отдельной базе данных, защищенной другим паролем. В pass так тоже можно сделать.
Интеграция с Android
Реализация GnuPG под Android называется OpenKeychain. Для её настройки достаточно зайти в меню "управление ключами" и импортировать ранее созданный секретный ключ. Единственный недостаток OpenKeychain лично для меня — нет разблокировки по отпечатку пальца.
Реализация pass под Android называется android-password-store, или просто APS.
Устанавливаем и запускаем APS. Прежде чем синхронизировать хранилище паролей, заходим в меню "Настройки". Там нам понадобятся следующие пункты:
Настройки сервера git
. Получившийся URL должен быть таким же, какой указан на странице репозитория на github. Тип авторизации —OpenKeychain
.Git utils
. В этом разделе указываем username и email из ключа gpg.Провайдер OpenPGP
. ВыбираемOpenKeychain
.Автозаполнение
. Эта совсем недавно появившаяся фича включает заполнение паролей в приложениях на Android 8.0+.
На заметку пользователям смартфонов Huawei, да и всем остальным тоже: OpenKeychain, APS, BinaryEye, FreeOTP, а также Syncthing, Telegram, Tachiyomi, KDE Connect и много чего еще доступны в F-Droid. Пользователи Google Play должны это оценить: каталог ПО, в котором нет рекламы, руткитов, и просто мусорного софта из известной статьи tonsky.
До появления автозаполнения в APS я пользовался keepass2android. Её нет в F-Droid по оригинальной причине: она написана на Xamarin, но мейнтейнеры F-Droid вот уже 9 месяцев как не могут установить этот фреймворк на свой сборочный сервер. Кто-нибудь, сделайте что-нибудь.
Теперь можно клонировать. Выбираем на главном экране "клонировать с сервера", указываем желаемое расположение хранилища, проверяем настройки git.
Если попытка работы с git приведет к ошибке (это было вероятно в предыдущих релизах APS из-за использования устаревшей версии библиотеки jgit
от проекта Eclipse), то по-прежнему есть Syncthing.
Заключение
Конечно, pass не так просто настроить. Однако за эту цену покупается уверенность, что используемые нами (а также людьми вроде Линуса Торвальдса или Эдварда Сноудена) инструменты в один прекрасный момент не будут объявлены устаревшими, не сменят формат данных и не окажутся без поддержки. А если и окажутся, то простая модульная архитектура pass поощряет создание каких угодно альтернативных клиентов и расширений.
Если вы решите не использовать pass, то, надеюсь, некоторые упомянутые в статье программы окажутся вам полезными и сами по себе.