コマンドのプロンプトを使用してbashから機密データを渡す方法はありますか?

コマンドのプロンプトを使用してbashから機密データを渡す方法はありますか?

sha1passコマンドラインでいくつかの機密パスワードのハッシュを生成するために使用しているとします。sha1pass mysecret生成されたハッシュを使用できますが、これはbash履歴に表示されるmysecret欠点があります。このコマンドをプレーンテキストで表示せずに(おそらく-styleプロンプトを使用して)、mysecret最終目標を達成する方法はありますか?mysecretpasswd

また、機密データをすべてのコマンドに渡す一般的な方法にも興味があります。sha1passこの方法は、機密データが特定のコマンドにパラメータ(たとえば)またはSTDINに渡されると変更されます。

これを行う方法はありますか?


編集する:この質問には多くの興味があり、以下にいくつかの素晴らしい答えがあります。要約は次のとおりです。

  • ~によると@Kusalanandaの返信理想的には、ユーティリティのコマンドライン引数としてパスワードや秘密を提供する必要はありません。彼が説明したように、これは多くの点で脆弱であるため、STDINへの秘密の入力を得るために、よりよく設計されたユーティリティを使用する必要があります。
  • @vfbsilvaの返信bash レコードにアイテムが保存されるのを防ぐ方法を説明します。
  • @Jonathanの返信プログラムがSTDINから秘密データを取得できる限り、これを達成するための完璧な方法について説明します。それで私はこの答えを受け入れることにしました。sha1pass私のOPの例にすぎませんが、ディスカッションの結果、STDINに関するデータを取得するためのより良いツールがあることがわかりました。
  • 〜のように@アル字型コメントする彼の答え、変数のコマンド拡張を使用するいいえ安全。

だから全体的に受け入れる。@Jonathanの返信うまく設計され、正常に動作するプログラムがあるので、これは最高のソリューションです。パスワードや秘密をコマンドライン引数として渡すことは基本的に安全ではありませんが、他の答えは簡単なセキュリティ問題を軽減する方法を提供します。

答え1

理想的には、コマンドラインのコマンドの引数としてプレーンテキストパスワードを入力しないでください。これにより、パスワードはコマンドの引数になり、コマンドライン引数はいくつかの監査ログに書き込むか、簡単なツールを使用してpsプロセステーブルに表示できます。

しかし、シェルのコマンド履歴から実際のパスワードを隠す方法は確かにあります。

sha1pass "$( head -n 1 )"

次にパスワードを入力してを押しますEnter。ここで使用されるコマンドはhead1行の入力のみを受け入れ、最後に入力した改行文字は渡されたデータの一部になりませんsha1pass

文字が反響しないようにするには:

sha1pass "$( stty -echo; head -n 1; stty echo )"

このstty -echoコマンドは、端末に入力された文字のエコーをオフにします。その後、復元エコーを使用してくださいstty echo

標準入力を渡すには、最後のコマンドを変更することができます(sha1pass標準入力のデータが許可されている場合はこれを行う必要がありますが、この特定のユーティリティは標準入力を無視するようです)。

{ stty -echo; head -n 1; stty echo; } | somecommand

複数行の入力が必要な場合(上記では末尾に改行文字なしで単一行を渡す必要があると仮定します)、次のようにhead使用します(入力に改行したい場合は次のことを行い、それ以外の場合は2回実行します)。catsomecommandCtrl+DReturn

これは、どのシェルを使用するかに関係なく機能します(Bourneやrcなどのシェルの場合)。

一部コマンドの前にスペースがある場合、シェルは入力したコマンドを履歴ファイルに保存できない可能性があります。通常はHISTCONTROLvalueに設定する必要がありますignorespace。少なくともOpenBSDはbashこれをサポートしていkshますが、そうではksh93ないかもしれませんdashzshユーザーは、histignorespaceオプションやその変数の使用をHISTORY_IGNORE無視するようにパターンを定義できます。

read文字を端末にエコーせずに読み取りをサポートするシェルでは、次のものも使用できます。

IFS= read -rs password     # -s turns off echoing in bash or zsh
                           # -r for reading backslashes as-is,
                           # IFS= to preserve leading and trailing blanks
sha1pass "$password"

ただし、これはまだプロセステーブルからパスワードが漏洩する可能性がある同じ問題を抱えているようです。

ユーティリティが標準入力から読み込み、シェルが「here-strings」をサポートしている場合は、上記の内容を次のように変更できます。

IFS= read -rs password
somecommand <<<"$password"

コメントをまとめると、次のようになります。

  • psコマンドラインで指定されたパスワードを使用してコマンドを実行すると(データをコマンドにパイプするコマンドを除く)、上記のすべてのコマンドがこれを実行するため、同時に実行するすべての人にパスワードが表示されます。ただし、対話型シェルで実行されている場合、上記のコマンドのいずれも入力したパスワードをシェルの履歴ファイルに保存しません。

  • プレーンテキストパスワードを読み取る 正常に動作するプログラムは、標準入力、ファイル、または端末から直接読み取って読み込みます。

  • sha1pass直接またはコマンド置換形式を使用して、コマンドラインにパスワードを入力する必要があります。

  • 可能であれば、他のツールを使用してください。

答え2

zshまたは、シェルを使用している場合は、bashシェル組み込みの-sオプションを使用して、エコーせずにreadターミナルデバイスから行を読み込みます。

IFS= read -rs VARIABLE < /dev/tty

その後、クールなリダイレクトを使用して、変数を標準入力として使用できます。

sha1pass <<<"$VARIABLE"

誰かが実行すると、ps「sha1pass」だけが表示されます。

sha1pass引数が指定されていない場合は、stdinが(行区切り文字を無視して1行で)パスワードを読み取るとします。

答え3

HISTCONTROL次のように設定すると:

HISTCONTROL=ignorespace

そして空白でコマンドを開始します。

~$  mycommand

履歴に保存されません。

答え4

ファイルに値を書き込んでファイルを渡すだけです。

$ cat > mysecret
Big seecreeeet!
$ cat mysecret | sha1pass 

どのように機能するのかわかりませんsha1pass。ファイルを入力として使用できる場合は使用できますsha1pass < mysecret。そうでない場合は、cat最後の改行文字が含まれているため、使用に問題がある可能性があります。その場合は、以下を使用してください(headサポートしている場合-c)。

head -c-1 mysecret | sha1pass 

関連情報