Table of Contents
Хранение паролей с GPG, Pass и GIT
Делаем личную хранилку паролей на своих мощностях, сервисам не доверяем.
Получится не так удобно, но спокойнее.
Компоненты:
- GPG (GNU Privacy Guard) - программа для шифрования различных файлов.
Так же gpg может быть использован для подписи файлов, программ или почты. - Pass (https://www.passwordstore.org/) - собственно сама программа для хранения паролей, которая для шифрования использует GPG.
- GIT - используется для синхронизации хранилища с паролями между несколькими машинами.
- USB flash drive - пару физических флешек в разных квартирах для бэкапа gpg-ключей.
Работа с GPG
Установка
root@e97a5e2d9c78:/# apt install gpg
Генерим ключ
Проверям, что никаких других gpg-ключей нет, смотрим список публичных и приватных ключей.
root@74b608401f03:~# gpg -k gpg: directory '/root/.gnupg' created gpg: keybox '/root/.gnupg/pubring.kbx' created gpg: /root/.gnupg/trustdb.gpg: trustdb created root@74b608401f03:~# gpg -K
Генерим первый ключ.
root@e97a5e2d9c78:/# gpg --full-gen-key gpg (GnuPG) 2.2.40; Copyright (C) 2022 g10 Code GmbH This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. gpg: directory '/root/.gnupg' created gpg: keybox '/root/.gnupg/pubring.kbx' created Please select what kind of key you want: (1) RSA and RSA (default) (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) (14) Existing key from card Your selection? 1 RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (3072) 4096 Requested keysize is 4096 bits Please specify how long the key should be valid. 0 = key does not expire <n> = key expires in n days <n>w = key expires in n weeks <n>m = key expires in n months <n>y = key expires in n years Key is valid for? (0) Key does not expire at all Is this correct? (y/N) y GnuPG needs to construct a user ID to identify your key. Real name: Ivan Fadin Email address: if@nomail.if Comment: GPG_for_Ivan You selected this USER-ID: "Ivan Fadin (GPG_for_Ivan) <if@nomail.if>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
Дальше попросит два раза ввести пароль от нового ключа и сделать немного энтропии для генерации.
We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. nvnlzd oosdfpsodfmncxscWe need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. poogpg: /root/.gnupg/trustdb.gpg: trustdb created gpg: directory '/root/.gnupg/openpgp-revocs.d' created pagpg: revocation certificate stored as '/root/.gnupg/openpgp-revocs.d/6952D134B31D02DDFDFA87E80BD9EBD6A01F0C63.rev'
Ключи будут лежать в “.gnupg”.
root@e97a5e2d9c78:/# ls -la ~/.gnupg/ total 12 drwx------ 4 root root 207 Oct 14 15:39 . drwx------ 1 root root 20 Oct 14 15:33 .. srwx------ 1 root root 0 Oct 14 15:35 S.gpg-agent srwx------ 1 root root 0 Oct 14 15:35 S.gpg-agent.browser srwx------ 1 root root 0 Oct 14 15:35 S.gpg-agent.extra srwx------ 1 root root 0 Oct 14 15:35 S.gpg-agent.ssh drwx------ 2 root root 58 Oct 14 15:35 openpgp-revocs.d drwx------ 2 root root 110 Oct 14 15:35 private-keys-v1.d -rw-r--r-- 1 root root 2482 Oct 14 15:35 pubring.kbx -rw------- 1 root root 32 Oct 14 15:33 pubring.kbx~ -rw------- 1 root root 1280 Oct 14 15:39 trustdb.gpg
Поднастроить gpg: показывать id ключа.
root@74b608401f03:~# joe ~/.gnupg/gpg.conf ... keyid-format 0xlong ...
Посмотреть публичный и приватный ключи.
Номер ключа другой, т.к. вывод комманд брался из нового контейнера.
root@74b608401f03:~# gpg -k /root/.gnupg/pubring.kbx ------------------------ pub rsa4096/0xF6D1FBD02D3BD3E4 2023-10-15 [SC] F3E3A9AAACE05FE9AF91B760F6D1FBD02D3BD3E4 uid [ultimate] Ivan Fadin (GPG_for_Ivan) <if@nomail.if> sub rsa4096/0xE7827AEBA3BB846D 2023-10-15 [E]
root@74b608401f03:~# gpg -K /root/.gnupg/pubring.kbx ------------------------ sec rsa4096/0xF6D1FBD02D3BD3E4 2023-10-15 [SC] F3E3A9AAACE05FE9AF91B760F6D1FBD02D3BD3E4 uid [ultimate] Ivan Fadin (GPG_for_Ivan) <if@nomail.if> ssb rsa4096/0xE7827AEBA3BB846D 2023-10-15 [E]
Зашифровать файл
Есть файл f1.txt с текстом.
root@e97a5e2d9c78:~/test_area# ll total 8 -rw-r--r-- 1 root root 10 Oct 14 15:48 f1.txt root@e97a5e2d9c78:~/test_area# cat f1.txt Some Text
Шифруем файл командой “gpg -e -a -r”, где:
- -e - зашифровать.
- -a - на выходе аски текст.
- -к - ключ, с помощью которого шифровать.
В данном примере ключ указывается через “комментарий”, так же можно через id или через почту.
root@e97a5e2d9c78:~/test_area# gpg -e -a -r GPG_for_Ivan f1.txt root@e97a5e2d9c78:~/test_area# ll total 8 -rw-r--r-- 1 root root 10 Oct 14 15:48 f1.txt -rw-r--r-- 1 root root 882 Oct 14 15:54 f1.txt.asc root@e97a5e2d9c78:~/test_area# cat f1.txt.asc -----BEGIN PGP MESSAGE----- hQIMA21KbFqg3TnaAQ//as6/JKBOPVqJWTmb54nsdonR3z2o+MbWWs0EpW3rjTw6 iRensJac297n9n1rVdwpOMOBU1d3bOdM/EXbzcTtcldmx26jylSKUXNpOTPnktiE kK2ZXgdCxdcSzt+DcuRw7+MchgrdHysPUpt3rL6ic54EZPvp3oPTADsVMapr4YoM OwyIqIv76xa30aUgvf85gBCiyWrRcMI0zM5oA9e3sUN7UVAfdydiuRwbPhoqF3+s 5XVQPbDM6J2i86ttqIqDhVp21werhBdbnIvWDJ3ilnLQEq8eBX72KZK6Xlu8Macb 0AIkjkC4uu4M0VYMTTd1l/tkb2Ok9M1ZIB09CxUIkVU61YA0ox/aeHC3GR8cczaq gYVnpG64Dk6Fq4x5u5QU3zLWw/VkveBqaLiQTC4cLocSUxH2ueq385XQXNZbZoRG tLma0sMX+InMOSixRS5hZe/Ur9hVgC1DVlILppTUBiWeR7xq3V7hugrJPIdYX6qf kg7io/wQmYT2R+1mz4D8V50f4WDzOTOjpLNlo06iCVTfhyaDZ7AgaVgdMQxfMcev Jv9Bra7+MDq18fs3kuhzwbSyExoPN4cB09U8QLS7otph2WHXqpTUQayfy0mcxEIq ND50SEOr3OY0m1UtezmbKci3aL4tqvUkwNAQB9oLrgqUGjjSnIu7diG4lFTCReLS SwFEWJ2N8iQyA/JQ0c+HmMSEzFUEn04gW/J/xx6cZRZbzTRciojmoc0NIqwyUYtp r0tQRp6BZnFzt0t+IUSYJ/uEfZYRgzOsC6BH7g== =N58t -----END PGP MESSAGE----- root@e97a5e2d9c78:~/test_area#
Расшифровать файл
Расшифруем файл командой “gpg -d -o”, где:
- -d - расшифровать.
- -o - выходной файл.
root@e97a5e2d9c78:~/test_area# gpg -d -o f2.txt f1.txt.asc gpg: encrypted with 4096-bit RSA key, ID 0x6D4A6C5AA0DD39DA, created 2023-10-14 "Ivan Fadin (GPG_for_Ivan) <if@nomail.if>" root@e97a5e2d9c78:~/test_area# ll total 8 -rw-r--r-- 1 root root 882 Oct 14 15:54 f1.txt.asc -rw-r--r-- 1 root root 10 Oct 14 15:58 f2.txt root@e97a5e2d9c78:~/test_area# cat f2.txt Some Text root@e97a5e2d9c78:~/test_area#
Работы с ключами
Экспорт ключей
root@74b608401f03:~/gpg_bup# gpg --export -a if@nomail.if > ivan_main_gpg_public_20231015.pgp root@74b608401f03:~/gpg_bup# gpg --export-secret-key -a if@nomail.if > ivan_main_gpg_secret_20231015.pgp root@74b608401f03:~/gpg_bup# ll total 12 -rw-r--r-- 1 root root 3143 Oct 15 08:17 ivan_main_gpg_public_20231015.pgp -rw-r--r-- 1 root root 6764 Oct 15 08:18 ivan_main_gpg_secret_20231015.pgp
Эти ключи надо сохранить в пару безопасных мест.
Так же есть мнение, что хранить приватный ключ на компе (особенно если диск не шифрован) не очень хорошо.
Надо создать саб-ключи от приватного и их использоавать.
Приватный бэкапим и удаляем с компа.
Вчитаться.
Удалить ключи
root@74b608401f03:~# gpg --delete-secret-key if@nomail.if root@74b608401f03:~# gpg --delete-keys if@nomail.if
При удалении приватного ключа, спрашивает аж три раза.
Ипортировать ключи
root@74b608401f03:~/gpg_bup# ll total 12 -rw-r--r-- 1 root root 3143 Oct 15 08:17 ivan_main_gpg_public_20231015.pgp -rw-r--r-- 1 root root 6764 Oct 15 08:18 ivan_main_gpg_secret_20231015.pgp root@74b608401f03:~/gpg_bup# gpg --import ivan_main_gpg_public_20231015.pgp gpg: key 0xF6D1FBD02D3BD3E4: public key "Ivan Fadin (GPG_for_Ivan) <if@nomail.if>" imported gpg: Total number processed: 1 gpg: imported: 1 root@74b608401f03:~/gpg_bup# gpg --import ivan_main_gpg_secret_20231015.pgp gpg: key 0xF6D1FBD02D3BD3E4: "Ivan Fadin (GPG_for_Ivan) <if@nomail.if>" not changed gpg: key 0xF6D1FBD02D3BD3E4: secret key imported gpg: Total number processed: 1 gpg: unchanged: 1 gpg: secret keys read: 1 gpg: secret keys imported: 1
При импорте приватного ключа спросит пароль.
Поменять пароль на ключе
root@e97a5e2d9c78:~/test_area# gpg --edit-key GPG_for_Ivan gpg (GnuPG) 2.2.40; Copyright (C) 2022 g10 Code GmbH This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Secret key is available. sec rsa4096/0BD9EBD6A01F0C63 created: 2023-10-14 expires: never usage: SC trust: ultimate validity: ultimate ssb rsa4096/6D4A6C5AA0DD39DA created: 2023-10-14 expires: never usage: E [ultimate] (1). Ivan Fadin (GPG_for_Ivan) <if@nomail.if> gpg> passwd gpg> save Key not changed so no update needed.
После команды passwd спросят текущий пароль и два раза новый пароль.
Действия после импорта ключей
После импорта на новую машину, gpg будет сомневаться, что ключ принадлежит пользователю от имени которого сделали импорт.
root@74b608401f03:~/test_area# gpg -e -a -r GPG_for_Ivan f1.txt gpg: 0xE7827AEBA3BB846D: There is no assurance this key belongs to the named user sub rsa4096/0xE7827AEBA3BB846D 2023-10-15 Ivan Fadin (GPG_for_Ivan) <if@nomail.if> Primary key fingerprint: F3E3 A9AA ACE0 5FE9 AF91 B760 F6D1 FBD0 2D3B D3E4 Subkey fingerprint: 7AFC 4254 BA3D 6F1F 8A5A A177 E782 7AEB A3BB 846D It is NOT certain that the key belongs to the person named in the user ID. If you *really* know what you are doing, you may answer the next question with yes. Use this key anyway? (y/N) y
Надо пометить ключ как trust.
root@74b608401f03:~/test_area# gpg --edit-key F6D1FBD02D3BD3E4 gpg (GnuPG) 2.2.40; Copyright (C) 2022 g10 Code GmbH This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Secret key is available. sec rsa4096/0xF6D1FBD02D3BD3E4 created: 2023-10-15 expires: never usage: SC trust: unknown validity: unknown ssb rsa4096/0xE7827AEBA3BB846D created: 2023-10-15 expires: never usage: E [ unknown] (1). Ivan Fadin (GPG_for_Ivan) <if@nomail.if> gpg> trust sec rsa4096/0xF6D1FBD02D3BD3E4 created: 2023-10-15 expires: never usage: SC trust: unknown validity: unknown ssb rsa4096/0xE7827AEBA3BB846D created: 2023-10-15 expires: never usage: E [ unknown] (1). Ivan Fadin (GPG_for_Ivan) <if@nomail.if> Please decide how far you trust this user to correctly verify other users' keys (by looking at passports, checking fingerprints from different sources, etc.) 1 = I don't know or won't say 2 = I do NOT trust 3 = I trust marginally 4 = I trust fully 5 = I trust ultimately m = back to the main menu Your decision? 5 Do you really want to set this key to ultimate trust? (y/N) y sec rsa4096/0xF6D1FBD02D3BD3E4 created: 2023-10-15 expires: never usage: SC trust: ultimate validity: unknown ssb rsa4096/0xE7827AEBA3BB846D created: 2023-10-15 expires: never usage: E [ unknown] (1). Ivan Fadin (GPG_for_Ivan) <if@nomail.if> Please note that the shown key validity is not necessarily correct unless you restart the program. gpg> save Key not changed so no update needed.
Работа с pass
Установка
root@84abb3771ecc:~# apt install pass root@84abb3771ecc:~# which pass /usr/bin/pass
Инициализация хранилища pass
Хранилище создается с привязкой к id gpg-ключа (id, почта или коммент).
root@84abb3771ecc:~# pass init GPG_for_Ivan mkdir: created directory '/root/.password-store/' Password store initialized for GPG_for_Ivan
По дефолту хранилище создаётся в домашней папке пользователя в скрытой папке “.password-store”.
В файле “~/..password-store/.gpg-id” список id привязанных к хранилищу ключей.
Работа с паролями
Записать пароль в одну строку
root@84abb3771ecc:~# pass insert work/one-password Enter password for work/one-password: Retype password for work/one-password:
Записать пароль в несколько строк
root@84abb3771ecc:~# pass insert another-work/m-lines-password -m mkdir: created directory '/root/.password-store/another-work' Enter contents of another-work/m-lines-password and press Ctrl+D when finished: login = user1 password = blabla-pass
Сгенерить пароль автоматически
root@84abb3771ecc:~# pass generate work/gen-pass The generated password for work/gen-pass is: G+5%sH$pk-{+kf=8bKEzh2i6b root@84abb3771ecc:~# pass work/gen-pass G+5%sH$pk-{+kf=8bKEzh2i6b
Посмотреть пароль
Посмотреть структуру хранилища.
root@84abb3771ecc:~# pass Password Store |-- another-work | `-- m-lines-password `-- work |-- gen-pass `-- one-password
Посмотреть конкретный пароль.
root@84abb3771ecc:~# pass work/one-password blabla
Спросит пароль от gpg-ключа.
Удалить пароль
root@84abb3771ecc:~# pass rm work/gen-pass Are you sure you would like to delete work/gen-pass? [y/N] y removed '/root/.password-store/work/gen-pass.gpg'
Содержимое файлов c паролями
root@84abb3771ecc:~# tree ~/.password-store/ /root/.password-store/ |-- another-work | `-- m-lines-password.gpg `-- work `-- one-password.gpg 3 directories, 2 files root@84abb3771ecc:~# cat ~/.password-store/work/one-password.gpg � Ƒ*L1Ľ���$,���tn(۩������F���B��)�iF��W��v,��p�yT�j�f!���v�o��R̙d��� ��q�۞��=w� q���� ����f�[:�7��B�^�u�����GD� < ��"Q �*E���r�C���S�a���ҵMI\A�� root@84abb3771ecc:~#
Интеграцияя pass с git
Pass умеет работать с git.
Для примера будем использовать github, по хорошему надо не публичный git использовать.
Заводим на github приватный репозиторий (ssh: git@github.com:if473/test-pass.git) и копируем наш публичный ssh-ключ.
Делаем начальную настройку git на машине с pass.
root@84abb3771ecc:~# git config --global user.email "if@nomail.if" root@84abb3771ecc:~# git config --global user.name "Ivan Fadin"
Инициализируем git в хранилище.
root@84abb3771ecc:~# pass git init Initialized empty Git repository in /root/.password-store/.git/
Указываем pass на репозиторий в github.
root@84abb3771ecc:~# pass git remote add origin git@github.com:if473/test-pass.git
Настройки git.
root@84abb3771ecc:~# cat .password-store/.git/config [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true [diff "gpg"] binary = true textconv = gpg -d --quiet --yes --compress-algo=none --no-encrypt-to [remote "origin"] url = git@github.com:if473/test-pass.git fetch = +refs/heads/*:refs/remotes/origin/* [branch "master"] remote = origin merge = refs/heads/master
Первый коммит.
root@84abb3771ecc:~/.password-store# git add . root@84abb3771ecc:~/.password-store# git commit -m "20231015 new pass" [master (root-commit) 3519549] 20231015 new pass 4 files changed, 2 insertions(+) create mode 100644 .gitattributes create mode 100644 .gpg-id create mode 100644 another-work/m-lines-password.gpg create mode 100644 work/one-password.gpg root@84abb3771ecc:~/.password-store# git push origin master Enumerating objects: 8, done. Counting objects: 100% (8/8), done. Delta compression using up to 2 threads Compressing objects: 100% (4/4), done. Writing objects: 100% (8/8), 1.65 KiB | 842.00 KiB/s, done. Total 8 (delta 0), reused 0 (delta 0), pack-reused 0 To github.com:if473/test-pass.git * [new branch] master -> master
Последующие коммиты, после добавление нового пароля.
root@84abb3771ecc:~# pass insert work/diff-pass-3 Enter password for work/diff-pass-3: Retype password for work/diff-pass-3: [master ad1fd86] Add given password for work/diff-pass-3 to store. 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 work/diff-pass-3.gpg root@84abb3771ecc:~# pass git push Enumerating objects: 6, done. Counting objects: 100% (6/6), done. Delta compression using up to 2 threads Compressing objects: 100% (4/4), done. Writing objects: 100% (4/4), 929 bytes | 929.00 KiB/s, done. Total 4 (delta 2), reused 0 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (2/2), completed with 2 local objects. To github.com:if473/test-pass.git 64b0e39..ad1fd86 master -> master