cron内のsshでsudoするには
結論は一番下に書いてあります。
sshでsudoするとよく見るメッセージ
sudo: sorry, you must have a tty to run sudo
これは、/etc/sudoers で terminal を要求するようになっているためである。なぜデフォルトでそうなっているのかもコメントに書いてある。
# # Disable "ssh hostname sudo <cmd>", because it will show the password in clear. # You have to run "ssh -t hostname sudo <cmd>". # Defaults requiretty
理解した上で設定を変更する場合は、それで解決するので、これ以降は読まなくて良い。 ちなみに、特定のコマンドだけ設定を変更することもできるらしい。
sudo - How to disable requiretty for a single command in sudoers? - Unix & Linux Stack Exchange
ここまではすでにいくつもの記事に書かれている。本題はここから。
コメントに書かれているように ssh -t をすれば、terminalから叩く場合は問題なくなる。
それでは cron から、さらに sshでsudoをするとどうなるのかというと、 -t だけでは足りないので、 -tt とする必要がある。
-tt オプションについてはCentOS 6のman ssh
で以下のように書かれている。
-t Force pseudo-tty allocation. This can be used to execute arbitrary screen-based programs on a remote machine, which can be very useful, e.g. when implementing menu services. Multiple -t options force tty allocation, even if ssh has no local tty.
つまり local tty がない場合は、複数回 -t オプションをつけるように、とのこと。
では、実際に試して見る。
まずは、以下のスクリプトを作成。リモートサーバではパスワードなしでsudoできるようにしておく。
#!/bin/bash -x ssh remote-host sudo id ssh -t remote-host sudo id ssh -tt remote-host sudo id
crontabで仕掛ける。
* * * * * path/to/a.sh >> path/to/cron.log 2>&1
しばし待つと、以下のログが出る。
+ ssh remote-host sudo id sudo: sorry, you must have a tty to run sudo + ssh -t remote-host sudo id Pseudo-terminal will not be allocated because stdin is not a terminal. sudo: sorry, you must have a tty to run sudo + ssh -tt remote-host sudo id tcgetattr: Invalid argument uid=0(root) gid=0(root) groups=0(root) Connection to remote-host closed.
-ttでうまく実行されたが、変なエラーがでる。
tcgetattr: Invalid argument
について調べると以下のページがヒットした。
このエラーは terminal の情報を取ろうとして出ているものらしい。それ以上の詳細は書かれていないが、対応策として、おもむろに/dev/nullにリダイレクトしている。他のいくつかのページを見ていても、harmlessなので無視して良いとか言っているが、本当だろうか。
Problem using Net::OpenSSH->capture to su to another user https://groups.google.com/forum/#!topic/comp.security.ssh/ISjpJhTxKVY
結論
調査が十分にできなかったが、ひとまずの結論としては、「cronからの場合、ssh -tt sudo ...
とすれば動く。軽く使う用途なら、これで問題なさそう。しかし万全を期すならもう少ししっかり調べたほうが良い」というところ。
sshからのsudoは構成管理ツールやデプロイツールで比較的よく使う組み合わせで、cronで動かすこともあると思うので、その辺のソースを調べれば、もう少し情報が集まるかもしれないが、これは今後の課題。