sudoを必要とするbashスクリプトで一度だけパスワードを入力する方法


21

データ

  • このマシンのオペレータユーザーに自分のcifs共有をマウントしてほしい
  • sudoersファイルがすでに含まれている/bin/mount -t cifs //*/* /media/* -o username=*すべての演算子のためのコマンドを
  • ユーザーにcifs、2回ではなく1回だけパスワードを入力するスクリプトを使用して共有をマウントしてもらいたい。
  • sudoパスワードとcifsパスワードは同一です。

私がすでに持っているもの

このスクリプトは動作します:

#!/bin/bash
sudo 'mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER'

... しかし、ユーザーは同じパスワードを2回入力する必要があります!

  • 一度だけ sudo
  • マウント自体に1回

これも機能します:

#!/bin/bash
echo -n Password: 
read -s szPassword
echo $szPassword | sudo -S sh -c 'echo $szPassword | mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER'

... しかし、これにはすべてのオペレーターユーザーができることを許可する必要がありますsudo sh(主要なセキュリティ問題)

質問

CIFS共有をマウントする方法bashで入れず¹ shsudoersファイルも永久的/一時ファイルを作成します?

注1: python、perl、C、Goは使用しないでください...
注2:私はsudoersファイルからパスワードを削除するだけでいいことを知っていますが、利便性をあきらめることなく、セキュリティを緩めずに厳しくしようとしています...


2
どうprintf "%s\n" "$szPassword" "$szPassword" | sudo -S mount -t cifs / ...
ムル

今すぐ試してみてください!@Muru
Fabby

回答:


24

代わりに、ユーザーにsudoを使用する呼び出しを行わせる必要がありますsudo script。スクリプトがrootとして実行されているかどうかを確認します(要求されていない場合)

if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root, use sudo "$0" instead" 1>&2
   exit 1
fi

ユーザーのパスワードをキャプチャしようとしないでください。


1
おそらく私は何かを見逃していますが、これによりパスワードプロンプトの数が2から1に減少することを説明できますか?そうでなければ、これがどのように質問に答えるかわかりません。
オリファント-モニカを復活させる

@Oliphaunt 2つのパスワードプロンプトが表示されません。説明できますか?また、この答えはOPが望むものではなく、必要なものです。あなたが(それ以外の場合は救済、ルートかどうかを確認)rootとしてコマンドを実行する必要があり、どのように他のユーティリティを実行すると、クリーンかつ適切な解決策である
Braiam

1
OPの問題(私が理解しているように)は、ユーザーがパスワードを入力するように求められsudo、それから(認証に成功すると)再びパスワードが要求されることですmount。ユースケースでは、これらのパスワードは同一であるため、OPがユーザーにこのパスワードを1回入力するだけでよい理由を確認できます。あなたのソリューションがこれに役立つとは思わない。パスワードをキャプチャしてはならないことに同意します。
オリファント-モニカを復活させる

ありがとう、しかし、私は質問を少し単純化しすぎたかもしれません:それはすでにスクリプトであり、すでにそのテスト(を除く1>&2)が含まれており、自動起動にあり、以前は1つのcifs共有でしたが、現在は3つなので、本当に1つのパスワードですが必要です。 (それはすでに、他のケースの誰かではなく、事業者グループのメンバーで、そのテストが含まれているそれを実行しようとします)
Fabby

@Fabbyまだ問題に間違って近づいていると思います。これらの場合、CIFS / SMB共有のパスワードを安全に「記憶」するヘルパーがあります(編集~/.smbcredentialsなど)。sudoを使用しなくても(gvfs、umount、またはpolkitを使用する場合)。
Braiam

7

私はダムです!

次のスクリプト:

#!/bin/bash
read -p "Password: " -s szPassword
printf "%s\n" "$szPassword" | sudo --stdin mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER,password="$szPassword"

ちょうど動作し、:

  1. パスワードを含むファイルを作成しません
  2. ユーザーは、複数の共有(Windowsのものを含む)に対して1つのパスワードのみを入力できます。
  3. 追加の特権を付与する必要はありません。 :-)

1
1つの質問:コマンドをプロセスリストにエコーしますか?
リンツウィンド

3
ビルトインとしての@Rinzwindは、bashまたはzshにしないでください。ただし、mountコマンドは可能です。
ムル

<<<の代わりに使用することもできますprintf が、より良いアプローチはread完全に削除し、sudo --stdinすべて単独で使用することです。$ printf "Type out your password\n" && sudo --stdin apt-get update Userのようなものはまだsudoパスワードを入力できます。そしてそれはそれをプロセスリストに入れません。しかし、もちろん無限のキーロガー、潜在的な脆弱性のように可能な他のセキュリティ問題の量がありますsudoし、何とか、と何とか、何とかとは無限に
Sergiy Kolodyazhnyy

@SergiyKolodyazhnyy:お気軽に編集してください!
ファビー

3

sudoこのコマンドの実行にパスワードは必要ありません。パスワードのプロンプトがmount残ります。

sudoers

ALL        ALL = NOPASSWD: /bin/mount -t cifs //*/* /media/* -o username=*

これを含めるsudoと、この特定のコマンドのパスワードを求めなくなります。ユーザーはmountコマンドにパスワードを入力する必要があります。

:私はあなたが質問に含めたものから逐語的にコマンドを取りました。そのワイルドカードがユーザーに何か厄介なことをさせてくれるかどうかはチェックしませんでした。sudoers意地悪の例については、マンページを参照してください。 特に、この行でsudoersは、ユーザーが任意の数の-oスイッチまたは他の引数をに追加できることに注意してくださいmount たとえば、@ Braiamが提案するスクリプトを追加し、sudo追加の認証なしでそれを実行できるようにすることで、アプローチを再考することができます。このスクリプトは、ユーザーが実行しmountたい特定の形式のみを実行できるようにします。

また、これをすべてのユーザーに許可する代わりに、これを特定のグループのメンバーに制限することもできます。たとえば、グループcifsmountを作成してから、

%cifsmount ALL = NOPASSWD: /bin/mount -t cifs //*/* /media/* -o username=*

@ファビー申し訳ありませんが、これについて何がそんなに危険ですか?また、私は皮肉のヒントを検出しているかもしれませんが、確かではありません。
オリファント-モニカを

まあ、たとえsudoがパスワードを要求しなくても、マウントはまだパスワードを要求するかもしれません。/ etc / sudoersファイルを使用して、sudoにパスワードを要求しないようにすることができます。mountがパスワードを要求するかどうかには影響しません。人がマウントに失敗した場合、sudoは失敗するコマンドを実行するだけになりますが、これはおそらく問題ではありません。
TOOGAM

@TOOGAMそれは私の意図でした。2つではなく1つのパスワード。
オリファント-モニカを復活させる

私の意図は、sudoersファイルに1つの「オペレーター」グループを保持することです。したがって、オペレーターが自分のものをマウントしようとすると、パスワードを入力する必要があります。一度代わりに5回...しかし、他の人のためのソリューションのかもしれない作業のため、... upvoted(および元のコメントは削除)
Fabby

1

これらの問題に対する一般的な解決策は、スクリプトを必要とするsudoの先頭に次の前文を置くことです。

#!/bin/bash
case $EUID in
   0) : cool we are already root - fall through ;;
   *) # not root, become root for the rest of this session
      # (and ask for the sudo password only once)
      sudo $0 "$@" ;;
esac
# now the present process is effective-UID  (root)
# so there's no need to put sudo in front of commands

any more commands here will run as superuser ...

明らかに、これには、スクリプト内の一部のコマンドsudoを実行する必要がない場合、ここで権限が不必要に昇格されるという欠点があります。

とにかく、私はこの小さなヒントを共有すると思いました。それについての最も素晴らしいことは、あなたがすでに実効UIDルートである場合(例えば、あなたがすでにsudoの下でそれを呼び出している場合)、それは正常に正しいことをするということです。また、エラーを与えて、(sudoを使用して)再入力/再実行を強制することは、あまりフレンドリーではありません。

また、timestamp_timeout変数をチェックアウトして、ユーザー資格情報を限られた数分間記憶man 5 sudoersするように指示sudoすることもできます(そして、わずかな場合もあります)。


スクリプトがすでに含まれています:私は簡単な答えを得るために、スクリプトを単純化 #test if root: if not: bail out if [[ $EUID -ne 0 ]]; then echo "This script must be run as root, use sudo "$0" instead" 1>&2 exit 1 fi のポイントは、それも含まれていることである複数の全て同じパスワード(再:削除)でマウントしたが、おかげでとにかく...
Fabby

1
ポイントは、上記の解決策ではパスワードの入力が1回だけで済むということです(sudoの場合)。それ以外のものは必要ありません。さらに、複数の(3つ以上の)特権コマンドが必要な場合でも、同様の問題はすべて(エラーを与えてsudoでコマンドを再入力するよりもエレガントです)。
arielf

それはすべきですが、そうではありません;-)これは、各cifs共有マウントにもパスワードが必要だからです。(それはようできる Ubuntuのパスワードとは異なる場合が、しかし、オペレータがWindowsとUbuntuのパスワードが同期され続けるように、この場合ではありません)
Fabby
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.