Go製パスワードマネージャー gopass でパスワード管理をやってみる
Written by @ryysud Apr 1, 2019 19:30 · 4268 words · 9 minutes read
TL;DR
- gopass は pass をベースに追加機能を Go で実装したパスワードマネージャー
- GPG を利用してパスワードの 暗号化/復号化 を行い Git でバージョン管理を行う
- パスワードの操作は以下のコマンドで実行可能(主要コマンドのみ抜粋)
コマンド | 説明 |
---|---|
gopass init | パスワードストアの初期化 |
gopass list | パスワードの一覧表示 |
gopass show | パスワードの表示 |
gopass insert | 任意の文字列をパスワードとして追加 |
gopass generate | ランダムな文字列をパスワードとして追加 |
gopass edit | パスワードの変更 |
gopass rm | パスワードの削除 |
gopass mv | パスワードの移動 |
gopass cp | パスワードのコピー |
gopass config | gopass の設定確認 |
gopass sync | リモートパスワードストア(Git リモートリポジトリ)との同期 |
gopass とは?
gopass は、UNIX哲学 に従ったシンプルなパスワードマネージャー pass を Go で rewrite したものです。クロスプラットフォームでの利用と追加機能の実装を目的に Go で rewrite がなされたようです。今回は gopass の基本的な機能を紹介した上で、使い方をまとめていこうと思います。
https://github.com/gopasspw/gopass
gopass を実行するための前準備
前置き
後述の説明は全て Mac での利用を想定したものとなっておりますので、他の OS を利用の際には公式ドキュメントを参照ください。
CLI のインストール
gopass は GPG と Git に依存しているので、それら全てを brew でインストールします。
brew install gnupg2 git
brew install gopass
今回利用する各CLIのバージョンは以下です。
- gpg 2.2.14
- git 2.16.1
- gopass 1.8.4
パスワードの 暗号化/復号化 に使う GPG Key Pair の作成
gopass は GPG を用いて、パスワードの 暗号化/復号化 を行うため、予めそれらの処理に利用する GPG Key Pair を作成しておく必要があります。
gpg --list-keys
を実行して、既に GPG Key Pair が存在している場合には、こちらの作業はスキップしてください。GPG Key Pair が存在していない場合には gpg --gen-key
もしくは gpg --full-generate-key
を実行して作成を行います。
実行すると作成するためのオプションを問われるので、自由に入力してください。
$ gpg --full-generate-key
gpg (GnuPG) 2.2.14; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
# Key 種別はデフォルトの "RSA and RSA" で良いので未入力で Enter
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)
Your selection?
# Key サイズはデフォルトの "2048" で良いので未入力で Enter
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)
Requested keysize is 2048 bits
# Key 有効期限はデフォルトの "無期限" で良いので未入力で Enter
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
# Git で利用するユーザーとメールアドレスと一致している必要があります(一致しないとエラーとなります)
# わからない人は git config -l で user.name や user.email などを参照してください
GnuPG needs to construct a user ID to identify your key.
Real name: ryysud
Email address: ryysud@example.com
Comment:
You selected this USER-ID:
"ryysud <ryysud@example.com>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
# ここまでの入力を終えるとパスワードを求められるので任意の文字列を入力してください
# ここで設定したパスワードが gopass で利用するマスターパスワードとなります
# Key が作成された旨のメッセージが出力される
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.
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.
gpg: key 67625320783C98C3 marked as ultimately trusted
gpg: revocation certificate stored as '/Users/yoshida/.gnupg/openpgp-revocs.d/F6D0DC0AB0470AF7587294B167625320783C98C3.rev'
public and secret key created and signed.
pub rsa2048 2019-04-01 [SC]
F6D0DC0AB0470AF7587294B167625320783C98C3
uid ryysud <ryysud@example.com>
sub rsa2048 2019-04-01 [E]
GPG Key Pair が作成されました。
# 公開鍵
$ gpg --list-keys
/Users/yoshida/.gnupg/pubring.kbx
---------------------------------
pub rsa2048 2019-04-01 [SC]
F6D0DC0AB0470AF7587294B167625320783C98C3
uid [ultimate] ryysud <ryysud@example.com>
sub rsa2048 2019-04-01 [E]
# 秘密鍵
$ gpg --list-secret-keys
/Users/yoshida/.gnupg/pubring.kbx
---------------------------------
sec rsa2048 2019-04-01 [SC]
F6D0DC0AB0470AF7587294B167625320783C98C3
uid [ultimate] ryysud <ryysud@example.com>
ssb rsa2048 2019-04-01 [E]
以下のコマンドが正常に動作することが確認できたら、次のステップに進みます。上手くいかない場合には、ここまでの手順が誤っていないか再度確認してください。
mkdir some-dir
cd some-dir
git init
touch foo
git add foo
git commit -S -m "test"
余談ですが、ドキュメントで「GPG を使うことに慣れていなければ、以下の資料が参考になるよー」という案内がされていて、とても親切で好印象でした。
実際に gopass を実行しながら基本機能を理解していく
パスワードストアの初期化( gopass init )
gopass init
を実行することでパスワードストアの初期化が可能です。
※ パスワードストアは gopass が管理するパスワード置き場の参照先
$ gopass init
# パスワードの 暗号化/復号化 に使う GPG Key Pair を選択
[init] Initializing a new password store ...
Please select a private key for encrypting secrets:
[0] gpg - 0x67625320783C98C3 - ryysud <ryysud@example.com>
Please enter the number of a key (0-0, [q]uit) [0]: 0
[init] Initializing git repository (gitcli) ...
# パスワードストアで利用する Git Config を選択
Use ryysud (ryysud@example.com) for password store git config? [Y/n/q]: Y
[init] git initialized at /Users/yoshida/.password-store
[init] git configured at /Users/yoshida/.password-store
[init] Git initialized
[init] Password store /Users/yoshida/.password-store initialized for:
[init] 0x67625320783C98C3 - ryysud <ryysud@example.com>
~/.password-store
に Git リポジトリが作成されたことがわかります。
$ ls -al ~/.password-store
total 16
drwx------ 6 yoshida staff 204B Apr 1 19:47 .
drwxr-xr-x+ 65 yoshida staff 2.2K Apr 1 19:50 ..
drwx------ 10 yoshida staff 340B Apr 1 19:50 .git
-rw------- 1 yoshida staff 15B Apr 1 19:47 .gitattributes
-rw------- 1 yoshida staff 19B Apr 1 19:47 .gpg-id
drwx------ 3 yoshida staff 102B Apr 1 19:47 .public-keys
パスワードの追加( gopass insert/generate )
任意の文字列を追加する場合
gopass insert path/to/password
を実行することで、任意の文字列をパスワードとして追加することが可能です。今回は golang.org/gopher
というパスに “password” というパスワードを追加します。
$ gopass insert golang.org/gopher
# "password" という文字列を入力します
Enter password for golang.org/gopher:
Retype password for golang.org/gopher:
# 暗号化に使う Key が出力される
Warning: Password is too common / from a dictionary
gopass: Encrypting golang.org/gopher for these recipients:
- F6D0DC0AB0470AF7587294B167625320783C98C3 - 0x67625320783C98C3 - ryysud <ryysud@example.com>
# 最後に確認がなされてパスワードの追加が完了する
Do you want to continue? [Y/n/q]: Y
Warning: git has no remote. Ignoring auto-push option
Run: gopass git remote add origin ...
ランダムな文字列を追加する場合
gopass generate path/to/password
を実行することで、ランダムな文字列をパスワードとして追加することが可能です。今回は golang.org/gopher-random
というパスにランダムな文字列のパスワードを追加します。
$ gopass generate golang.org/gopher-random
# ランダムで生成するパスワードの長さを選択可能(デフォルトで良ければ未入力で Enter)
How long should the password be? [24]:
Do you have strict rules to include different character classes? [y/N/q]: y
gopass: Encrypting golang.org/gopher-random for these recipients:
- F6D0DC0AB0470AF7587294B167625320783C98C3 - 0x67625320783C98C3 - ryysud <ryysud@example.com>
# 最後に確認がなされてパスワードの追加が完了する
Do you want to continue? [Y/n/q]: Y
Warning: git has no remote. Ignoring auto-push option
Run: gopass git remote add origin ...
# 生成されたパスワードは45秒間だけクリップボードにコピーされる
✔ Copied golang.org/gopher-random to clipboard. Will clear in 45 seconds.
ワンタイムパスワードを追加する場合
ワンタイムパスワードを追加することも可能となっておりますが、今回は割愛します。
詳細は こちら を参照ください。
パスワードの変更( gopass edit )
gopass edit path/to/password
を実行することで、パスワードの変更が可能です。今回は golang.org/gopher
というパスにある “password” というパスワードを “edit-password” に変更します。
# 変更前
$ gopass show golang.org/gopher
password
# パスワードの変更(エディタが開かれるので値を "edit-password" に変更)
$ gopass edit golang.org/gopher
gopass: Encrypting golang.org/gopher for these recipients:
- F6D0DC0AB0470AF7587294B167625320783C98C3 - 0x67625320783C98C3 - ryysud <ryysud@example.com>
Do you want to continue? [Y/n/q]: Y
Warning: git has no remote. Ignoring auto-push option
Run: gopass git remote add origin ...
# 変更後
$ gopass show golang.org/gopher
edit-password
パスワードの一覧表示( gopass list )
gopass list
を実行することで、パスワードの一覧表示が可能です。
$ gopass list
gopass
└── golang.org
├── gopher
└── gopher-random
-f
オプションでパスをフラットに表示することが可能です。パスワードの表示を行う際には、フラットなパスを入力する必要があるので、このオプションはとても有用だと思います。
$ gopass list -f
golang.org/gopher
golang.org/gopher-random
パスワードの表示( gopass show )
gopass show path/to/password
を実行することで、パスワードの表示が可能です。こちらのコマンドを実行する際には、パスワードストアの初期化で選択した GPG Key Pair のパスワードを入力する必要があります。gopass の設定にもよりますが、デフォルトだと一度入力すれば一定時間はパスワードの入力がスキップされます。
$ gopass show golang.org/gopher
edit-password
$ gopass show golang.org/gopher-random
U*x@>19]`WjDnC*/fZc<h7Rc
パスワードの削除( gopass rm )
gopass rm path/to/password
を実行することで、パスワードの削除が可能です。
$ gopass list
gopass
└── golang.org
├── gopher
└── gopher-random
$ gopass rm golang.org/gopher-random
Are you sure you would like to delete golang.org/gopher-random? [y/N/q]: y
$ gopass list
gopass
└── golang.org
└── gopher
パスワードの移動( gopass mv )
gopass mv src-path/to/password dest-path/to/password
を実行することで、パスワードの移動が可能です。
$ gopass list
gopass
└── golang.org
└── gopher
$ gopass mv golang.org/gopher golang.org/gopher-mv
gopass: Encrypting golang.org/gopher-mv for these recipients:
- F6D0DC0AB0470AF7587294B167625320783C98C3 - 0x67625320783C98C3 - ryysud <ryysud@example.com>
Do you want to continue? [Y/n/q]: Y
Warning: git has no remote. Ignoring auto-push option
Run: gopass git remote add origin ...
$ gopass list
gopass
└── golang.org
└── gopher-mv
パスワードのコピー( gopass cp )
gopass cp src-path/to/password dest-path/to/password
を実行することで、パスワードのコピーが可能です。
$ gopass list
gopass
└── golang.org
└── gopher-mv
$ gopass cp golang.org/gopher-mv golang.org/gopher
gopass: Encrypting golang.org/gopher for these recipients:
- F6D0DC0AB0470AF7587294B167625320783C98C3 - 0x67625320783C98C3 - ryysud <ryysud@example.com>
Do you want to continue? [Y/n/q]: Y
Warning: git has no remote. Ignoring auto-push option
Run: gopass git remote add origin ...
$ gopass list
gopass
└── golang.org
├── gopher
└── gopher-mv
gopass の設定確認( gopass config )
gopass config
を実行することで、gopass の設定確認が可能です。また gopass config param custom-value
で設定の変更も可能です。
$ gopass config
root store config:
askformore: false
autoclip: true
autoimport: true
autosync: true
check_recipient_hash: false
cliptimeout: 45
concurrency: 1
editrecipients: false
nocolor: false
noconfirm: false
nopager: false
notifications: true
path: gpgcli-gitcli-fs+file:///Users/yoshida/.password-store
safecontent: false
usesymbols: false
パスワードストアをリモートで管理して複数人で利用する
故意に既存のリモートパスワードストア(Git リモートリポジトリ)を追加しない限りは、ローカルパスワードストア(Git ローカルリポジトリ)の利用となるので、ローカルで閉じた個人での利用が前提となります。
なので、複数人で同じパスワードストアを利用したい場合には、リモートでの管理が必要となります。今回は、複数人での利用を想定して GitHub で管理する手順を紹介します。パスワードストアも結局のところ実体は Git リポジトリなので、Git の基本操作で簡単に設定可能です。
Git リモートリポジトリの設定を追加
gopass git remote add origin
を実行して Git リモートリポジトリを追加します。
$ gopass git remote add origin https://github.com/ryysud/hello-gopass.git
~/.password-store
に移動して Git リモートリポジトリを確認すると、設定が適用されていることがわかります。
$ cd ~/.password-store
$ git remote -vvv
origin github.com:ryysud/hello-gopass.git (fetch)
origin github.com:ryysud/hello-gopass.git (push)
リモートパスワードストアへのデータ同期を行う
gopass sync
を実行することで、リモートパスワードストアへのデータ同期が可能です。実行結果にあるように、実処理は git pull と git push と GPG Key Pair の操作のようです。
gopass sync
Sync starting ...
[<root>]
git pull and push ...
OK (no changes)
importing missing keys ... OK
exporting missing keys ... OK
done
All done
以上で、パスワードストアをリモートで管理して複数人で利用することが可能となります。
他の人が利用を開始する際には Cloning an Existing Password Store の手順に従い、リモートパスワードストアのクローンを行う必要があります。また、複数人で利用するのに単一の GPG Key Pair をコピーして利用するのは、リスクが大きいので Managing Recipients の手順に従い、利用者全員の GPG Key Pair の追加を行ってください。
ちょっとした Tips1
デフォルトだと、パスワードの操作が行われた後にリモートパスワードストアとの自動同期が実行されるので、事故を防ぐためにも gopass config autosync false
を実行して、自動同期を無効化しておいたほうが良さそうです。
# デフォルトは自動同期が有効
$ gopass config autosync
autosync: true
# 自動同期を無効に設定
$ gopass config autosync false
autosync: false
設定を忘れて誤ってパスワードを 変更/削除 してしまっても、パスワードストアの実体は Git リポジトリなので、Git を操作して revert すれば良いと思います。
ちょっとした Tips2
パスワードの変更をチームなどでレビューする際には、パスワードストアのブランチを切り替えて gopass sync
を実行した後に PR を作成すれば良さそうです。
cd ~/.password-store
git checkout -b update-password
gopass insert new-password
gopass sync
最後に
今回初めてパスワードマネージャーなるものを使ってみたのですが、複数人でパスワードを共有したい場合に gopass は非常に有用なツールであることがわかりました。
今回紹介したコマンド郡は最上部の TL;DR にまとめてあります。また、今回紹介した以外にも gopass では多くの機能が提供されているので、気になる方は以下をチェックしてみてください。
https://github.com/gopasspw/gopass/blob/master/docs/features.md
おしまい。