2012年9月23日日曜日

ssh で sudo 実行

リモートの Ubuntu に ssh で sudo でコマンドを実行しようとすると
$ ssh user@server sudo ls -la
user@server's password: 
sudo: no tty present and no askpass program specified
というように怒られてコマンドを実行できません。
tty が割り当てられているか askpass プログラムが指定されているかのどちらかであれば実行できるようです。
今回はリモートから ssh で sudo コマンドを実行するので askpass プログラムで対応するのは難しそうです。
askpass 以外で調べてみたら回避方法がいろいろありました。


回避方法その1

tty が割り当てられるようにすれば良いようなので
$ ssh -t user@server sudo ls -la
user@server's password:    # server に ssh する時のパスワードを入力
[sudo] password for user:  # sudo のためにパスワードを入力
...
というように ssh に -t オプションを指定するとうまくいきました。

なお、-t を指定ない場合は
$ ssh user@server tty
user@server's password: 
tty ではありません
というように確かに tty が割り当てられていません。

-t を指定する場合は
$ ssh -t user@server tty
user@server's password: 
/dev/pts/4
Connection to server closed.
今回のケースでは /dev/pts/4 が割り当てられました。


回避方法その2

visudo コマンドで sudoers ファイルに
Defaults        visiblepw
を追加すると
$ ssh user@server sudo ls -la
user@server's password:               # server に ssh する時のパスワードを入力
[sudo] password for user: ごにょごにょ # sudo のためにパスワードを入力
...
というように、うまく sudo できるのですが visible なパスワードだけに sudo 実行時に入力するパスワードが見えてしまいます。

sudoers の man ページで visiblepw の箇所を参照すると...
$ man sudoers
...
       visiblepw       By default, sudo will refuse to run if the user must
                       enter a password but it is not possible to disable
                       echo on the terminal.  If the visiblepw flag is set,
                       sudo will prompt for a password even when it would be
                       visible on the screen.  This makes it possible to run
                       things like "rsh somehost sudo ls" since rsh(1) does
                       not allocate a tty.  This flag is off by default.
...
パスワード入力が必要な場合に端末上でエコーをしないようにする (パスワードを見えないようにする) ことができない場合には初期状態では sudo を実行できないようです。
セキュリティ上の理由でしょうね。
visiblepw を設定するとパスワードが見えてしまう場合でも sudo を実行できるようになるんですね。
なお、tty が割り当てられていない場合も、端末上でエコーをしないようにすることができないからだめだったのかな。


回避方法その3

sudo コマンドに -S オプションを付けて実行
$ ssh user@server sudo -S ls -la
user@server's password:               # server に ssh する時のパスワードを入力
[sudo] password for user: ごにょごにょ # sudo のためにパスワードを入力
...
これもパスワードが見えてしまいますが sudo 実行できます。

sudo の man ページで該当箇所を参照すると...
$ man sudo
...
       -S          The -S (stdin) option causes sudo to read the password
                   from the standard input instead of the terminal device.
...
端末 (tty のことかな) からパスワードを読み込む代わりに標準入力から読み込むようになるようです。
上の「回避方法その2」の場合もバスワードを見えなくすることができる tty を使えない場合に、見えても良い標準入力からパスワードを入力するってことでよさそうなので、今回の場合は「回避方法その2」と「回避方法その3」は動作は同じとなるようです。



おまけ:

今回は
sudo: no tty present and no askpass program specified
というメッセージで ssh + sudo が実行できなかったのですが、
sudo: sorry, you must have a tty to run sudo
というメッセージで実行できな場合もあります。
これは sudoers ファイルで
Defaults        requiretty
が指定されている場合で、tty が割り当てられていないと sudo を実行できないので「回避方法その2」、「回避方法その3」では回避できず、「回避方法その1」で ssh に -t オプションを付けて tty が割り当てられるようにしないと sudo 実行できません。
なお、Ubuntu のデフォルトでは requiretty は指定されていないようです。

0 件のコメント:

コメントを投稿