web-dev-qa-db-ja.com

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

データ

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

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

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

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

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

  • Sudoに1回
  • マウント自体に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ファイルを介してパスワードを削除できることはわかっていますが、セキュリティを強化しようとしています。利便性をあきらめます...

21
Fabby

私はダムです!

次のスクリプト:

#!/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. 追加の特権を付与する必要はありません。 :-)
7
Fabby

代わりに、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

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

24
Braiam

このコマンドを実行するために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=*
3
Oliphaunt

これらの問題の一般的な解決策は、スクリプトを必要とする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_timeoutman 5 sudoers変数をチェックアウトすると、Sudoにユーザー資格情報を限られた数分間記憶するように指示できます(数分の一の場合もあります)。

1
arielf