Capistrano(カピストラーノ)で sudo が使えない問題
CapistranoのGetting Startedを行なっていて、sudo が利用できない問題に直面しました。
実行環境
Capisranoを実行するサーバ
OS | CentOS6 | ||
OpenSSH | OpenSSH_5.3p1, OpenSSL 1.0.0-fips 29 Mar 2010 | ||
Ruby | ruby 1.8.7 (2011-06-30 patchlevel 352) [i686-linux] | ||
rubygems | 1.3.7 | ||
Capistrano | 2.9.0 | ||
net-scp | 1.0.4 | ||
net-sftp | 2.0.5 | ||
net-ssh | 2.2.1 | ||
net-ssh-gateway | 1.1.0 | ||
highline | 1.6.2 |
デプロイ対象サーバ(IP を 192.168.100.200 とします。)
OS | CentOS6 | ||
OpenSSH | OpenSSH_5.3p1, OpenSSL 1.0.0-fips 29 Mar 2010 | ||
Ruby | ruby 1.8.7 (2011-06-30 patchlevel 352) [i686-linux] | ||
rubygems | 1.3.7 |
再現
% cap invoke COMMAND="df -h" HOSTS=hoge@192.168.100.200 SUDO=1 * executing `invoke' * executing "sudo -p 'sudo password: ' df -h" servers: ["192.168.100.200"] [hoge@192.168.100.200] executing command *** [err :: hoge@192.168.100.200] sudo *** [err :: hoge@192.168.100.200] : *** [err :: hoge@192.168.100.200] no tty present and no askpass program specified *** [err :: hoge@192.168.100.200] command finished in 53ms failed: "sh -c 'sudo -p '\\''sudo password: '\\'' df -h'" on hoge@192.168.100.200
SUDO=1 を外せば実行可能です。
% cap invoke COMMAND="df -h" HOSTS=hoge@192.168.100.200 * executing `invoke' * executing "df -h" servers: ["192.168.100.200"] [hoge@192.168.100.200] executing command ** [out :: hoge@192.168.100.200] Filesystem Size Used Avail Use% マウント位置 ** [out :: hoge@192.168.100.200] /dev/mapper/vg_testbudgearycontrol-lv_root ** [out :: hoge@192.168.100.200] 50G 3.3G 44G 8% / ** [out :: hoge@192.168.100.200] tmpfs 2.0G 0 2.0G 0% /dev/shm ** [out :: hoge@192.168.100.200] /dev/sda1 485M 33M 427M 8% /boot ** [out :: hoge@192.168.100.200] /dev/mapper/vg_testbudgearycontrol-lv_home ** [out :: hoge@192.168.100.200] 92G 1.5G 86G 2% /home command finished in 48ms
つまり、下記もできないということ。仮想端末が割り当てられないようだ。
% ssh hoge@192.168.100.200 'sudo df -h' sudo: no tty present and no askpass program specified
解決方法1 : 仮想端末が割り当てられていないので ssh -t をつける
普通のshell
ssh の -t オプションは強制的に仮想端末を割り当てる。下記は、実行結果。sudo をつけて実行が可能。
ssh
% ssh -t hoge@192.168.100.200 'sudo df -h' [sudo] password for hoge: Sorry, try again. [sudo] password for hoge: Filesystem Size Used Avail Use% マウント位置 /dev/mapper/vg_testbudgearycontrol-lv_root 50G 3.3G 44G 8% / tmpfs 2.0G 0 2.0G 0% /dev/shm /dev/sda1 485M 33M 427M 8% /boot /dev/mapper/vg_testbudgearycontrol-lv_home 92G 1.5G 86G 2% /home Connection to 192.168.100.200 closed.
capistrano
まず、default_run_options[:pty]=true が書かれた capfile を用意します。
default_run_options[:pty]=true
capfileを指定して実行します。
% cap -f capfile invoke COMMAND="df -h" HOSTS=hoge@192.168.100.200 SUDO=1 * executing `invoke' * executing "sudo -p 'sudo password: ' df -h" servers: ["192.168.100.200"] [admin@192.168.100.200] executing command ** [out :: hoge@192.168.100.200] Filesystem Size Used Avail Use% マウント位置 ** [out :: hoge@192.168.100.200] /dev/mapper/vg_testbudgearycontrol-lv_root ** [out :: hoge@192.168.100.200] 50G 3.4G 44G 8% / ** [out :: hoge@192.168.100.200] tmpfs 2.0G 0 2.0G 0% /dev/shm ** [out :: hoge@192.168.100.200] /dev/sda1 485M 33M 427M 8% /boot ** [out :: hoge@192.168.100.200] /dev/mapper/vg_testbudgearycontrol-lv_home ** [out :: hoge@192.168.100.200] 92G 1.9G 85G 3% /home command finished in 70ms
解決方法2 : Defaults visiblepw
sshd に Defaults visiblepw を設定すれば 仮想端末なしでも sudo が許可されます。デプロイされる側のサーバで visudo して、下記のように加えて、ssh を再起動します。
# # Disable "ssh hostname sudo <cmd>", because it will show the password in clear. # You have to run "ssh -t hostname sudo <cmd>". # # Defaults requiretty Defaults visiblepw
上記のところに パスワードが見えるので ssh -t 使ってくださいと書いてありますけども・・・。
ssh
% ssh hoge@192.168.100.200 'sudo df -h' [sudo] password for hoge: xxxxxxx ##←パスワード丸みえ Filesystem Size Used Avail Use% マウント位置 /dev/mapper/vg_testbudgearycontrol-lv_root 50G 3.3G 44G 8% / tmpfs 2.0G 0 2.0G 0% /dev/shm /dev/sda1 485M 33M 427M 8% /boot /dev/mapper/vg_testbudgearycontrol-lv_home 92G 1.5G 86G 2% /home
capistrano
Capistranoの場合は、パスワードは見えませんね・・。
% cap invoke COMMAND="df -h" HOSTS=hoge@192.168.100.200 SUDO=1 * executing `invoke' * executing "sudo -p 'sudo password: ' df -h" servers: ["192.168.100.200"] [hoge@192.168.100.200] executing command Password: ** [out :: hoge@192.168.100.200] Filesystem Size Used Avail Use% マウント位置 ** [out :: hoge@192.168.100.200] /dev/mapper/vg_testbudgearycontrol-lv_root ** [out :: hoge@192.168.100.200] 50G 3.3G 44G 8% / ** [out :: hoge@192.168.100.200] tmpfs 2.0G 0 2.0G 0% /dev/shm ** [out :: hoge@192.168.100.200] /dev/sda1 485M 33M 427M 8% /boot ** [out :: hoge@192.168.100.200] /dev/mapper/vg_testbudgearycontrol-lv_home ** [out :: hoge@192.168.100.200] 92G 1.5G 86G 2% /home command finished in 4008ms
おまけ1 : sudoで特定のコマンドをパスワードなしで実行できるようにする
例えば、visudo で下記のように設定して、sshd を restart ます。
%wheel ALL=(ALL) NOPASSWD: /bin/df
上記だと、/bin/df コマンドは wheelグループユーザに所属していれば パスワードなしで sudo 実行できます。sudo で実行したいコマンドがたくさんある場合は不向きですね。
おまけ2 : sudo 時の path
visudo で設定を見ると Defaults secure_path というのがあります。これは、sudo 時に下記のパスが設定されますが、例えば、gem コマンドが /usr/local/bin にあった場合は、sudo 時に gem コマンドが使えないということになってしまいます。そのため、Default secure_pathに pathを加えることで対応します。
Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin
↓
Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin