bashでプロンプトを使って、任意のコマンドで機密データを渡す方法はありますか?
例えば、コマンドラインで sha1pass
を使って機密性の高いパスワードのハッシュを生成しているとしましょう。sha1pass mysecretを使って
mysecretのハッシュを生成することはできますが、
mysecretがbashのヒストリに残ってしまうという欠点があります。このコマンドの最終目標を達成しつつ、プレーンテキストで
mysecretを明らかにしない方法はないでしょうか。おそらく
passwd` 形式のプロンプトを使用することで、それを実現できるのではないでしょうか。
私はまた、どのようなコマンドに対しても機密データを渡すための一般化された方法にも興味があります。この方法は、センシティブなデータが引数として (例えば sha1pass
のように) 渡されたときや、あるコマンドの STDIN で渡されたときに変更されるでしょう。
これを実現する方法はありますか?
Edit:この質問は多くの注目を集め、以下にいくつかの良い答えが提供されています。要約すると
- Kusalananda' の回答](https://unix.stackexchange.com/a/439510/7868) にあるように、理想的にはユーティリティのコマンドライン引数としてパスワードや秘密を与える必要はないでしょう。これは、彼が説明したように、いくつかの点で脆弱であり、STDIN で秘密の入力を受けることができる、より良く設計されたユーティリティを使用すべきです。
- @vfbsilva's answer は、bash の履歴に保存されるのを防ぐ方法を記述しています。
- @Jonathan's answer は、プログラムが STDIN で秘密のデータを受け取ることができる限り、これを達成するための完全に良い方法を記述しています。そのため、私はこの回答を受け入れることにしました。私のOPの
sha1pass
は単なる例でしたが、議論はSTDINでデータを取るより良いツールが存在することを確立しました。 R.](https://unix.stackexchange.com/users/6342/r)が[彼の回答](https://unix.stackexchange.com/a/439519/7868)で指摘しているように、変数に対するコマンド展開の使用は*安全では*ありません*。
まとめると、私は @Jonathan's の回答 を受け入れました。なぜなら、あなたがよく設計され、よく動作するプログラムを持っていることを考えると、それが最善の解決策であるからです。 コマンドラインの引数としてパスワードやsecretを渡すことは基本的に安全ではありませんが、他の回答は単純なセキュリティの懸念を軽減する方法を提供しています。
40
3
理想的には、平文のパスワードをコマンドの引数としてコマンドラインに入力することは決してありません。そうすると、パスワードはコマンドの引数になり、コマンドラインの引数は
ps
のような簡単なツールを使ってプロセステーブルで見られるかもしれませんし、監査ログに記録されることもあります。とはいえ、シェルのコマンド履歴から実際のパスワードを隠す方法は確かにあります。
次に、パスワードを入力して、 Enter を押してください。 ここで使用する
head
コマンドは正確に1行の入力を受け付け、最後に入力した改行はsha1pass
に渡されるデータには含まれません。文字がエコーされないようにするために
stty -echo
コマンドは、端末に入力された文字のエコーをオフにします。 その後、
stty echo` を実行すると、エコーが復活します。標準入力を渡すには、最後のコマンドを変更することができます (
sha1pass
が標準入力のデータを受け入れる場合はこのようにしますが、この特定のユーティリティは標準入力を無視しているかのように見えます)。複数行の入力が必要な場合(上記では、最後に改行文字を含まない1行が渡されると仮定しています)、
head
コマンド全体をcat
で置き換え、入力(somecommand
自体がファイルの終わりまで読むと仮定します)を Ctrl+D (改行文字を含む場合は Return に続く)で終了させます(含まない場合は2回です)。これは、どのシェルを使っているかに関係なく動作します(Bourneやrcのようなシェルであれば)。
いくつかのシェルでは、コマンドの前にスペースがある場合、入力されたコ マンドを履歴ファイルに保存しないようにすることができます。これは通常
HISTCONTROL
にignorespace
という値を設定する必要があります。 OpenBSD では、少なくともbash
とksh
でサポートされていますが、ksh93
やdash
などではサポートされていません。zshユーザーは
histignorespaceオプションまたは
HISTORY_IGNORE` 変数を使用して、無視するパターンを定義することができます。ターミナルに文字をエコーすることなく
read
で読み込むことをサポートしているシェルではを使うこともできますが、これは明らかにプロセステーブルのパスワードが明らかになる可能性があるという同じ問題を抱えています。
もし、ユーティリティが標準入力から読み込み、シェルが "here-strings" をサポートするなら、上記は以下のように変更することが可能です。
このように
HISTCONTROL
を設定した場合。のように設定し、コマンドの先頭にスペースを入れてください。
と入力すると、履歴に残りません。
値をファイルに書き込んで、そのファイルを渡すだけです。
sha1pass
がどのように動作するかわかりませんが、もしファイルを入力として受け取ることができれば、
sha1pass < mysecretを使用することができます。そうでない場合、
catを使用すると、最後の改行が含まれるため、問題が発生する可能性があります。そのような場合は、(
headが
-c` をサポートしていれば) を使ってください。