rsync を sudo で実行して所有者とグループを反映させる

rsync を sudo で実行して所有者とグループを反映させる。

受け側(dst) で rsync を実行するユーザーに rsync のみパスワードなしで sudo する権利を付与する

$ sudo /usr/sbin/visudo
## Backup user
johnsmith ALL= NOPASSWD:/usr/bin/rsync

この他にも送り側(src)のファイルの持ち主のユーザーやグループを作っておく。
uid, gid で合わせることも、名前で合わせることもできる(名前であわせるのがディフォルト動作、uid, gid で合わせるのは rsync の --numeric-ids オプション)。


送り側(src)で以下のような感じに指定する

$ rsync --rsh="ssh -p SSH_PORT_NUM -i /path/to/secretkey -t -t" --rsync-path="sudo rsync" --compress --recursive --links --perms --times --group --owner --quiet /path/to/src/ johnsmith@dsthost:/path/to/dst

キモは ssh のオプションの -t を複数回していするあたり。これが一回しかないと sudoers の Defaults requiretty 指定によって sudo できず

Pseudo-terminal will not be allocated because stdin is not a terminal.
sudo: sorry, you must have a tty to run sudo

のように怒られる。

ってこれでいいかと思ったけどよく見たらエラー吐いてる。

tcgetattr: Invalid argument
Connection to dsthost closed.

johnsmith のログインシェルを sh とか csh とかに変えたり試してるんだけど駄目っぽいなぁ。どうしよう。


とりあえずの対処として johnsmith だけは端末がなくても sudo できるようにする

$ sudo /usr/sbin/visudo
Defaults:johnsmith !requiretty

この状態で

$ rsync --bwlimit=8192 --timeout=5000 --rsh="ssh -p SSH_PORT_NUM -e 'none' -i /path/to/secretkey" --rsync-path="sudo rsync" --compress --recursive --links --perms --times --group --owner /path/to/src/ johnsmith@dsthost:/path/to/dst

こんな感じ。-t -t で仮想端末を割り当てるのをやめたのと、sshエスケープを無効にした(転送途中に何かエスケープに引っかかっているようなメッセージが出たため)。
今のところこれで動作はしているものの、仮想端末なしで sudo するとパスワードが平文で流れるとか sudoers のコメントに書いてあるのが気になる所。公開鍵認証を使っていて、sudo 自体もパスワードなしでやっているので大丈夫だとは思いたいけど、安心する為にはもう少し詳細を調べないといけないかも。