Compnet

仕事とか遊びとか、日々折々

2016-12-02(金)

root でログインできないときにも root 権限で rsync

Posted by Nakane, R. in technical   

先の記事では pelican-quickstart コマンドで作られた Makefile ファイルを修正して、Pelican で生成した Web サイトを make rsync_upload コマンドで Web サーバーにアップロードできるようにしました。 しかしながら、筆者の環境では Web サーバーの HTML のルート ディレクトリへの書き込みが root 以外のユーザーではできないようにしてある上に、root でのログインもできないようにしてあります。 このため、先の記事の Mailefile ファイルを使う make rsync_upload コマンドでは、Web サーバーへのアップロードがエラーになってしまいます。

そこで、筆者の環境に合うように Makefile ファイルを更に修正します。 これに加えて、修正した Web サーバーの設定も調整して、make rsync_upload コマンドで Web サーバーにアップロードできるようします。

先の記事では Makefile ファイルを SSH_USER=username としていることから分かるように、username (仮名) でログインして rsync を行います。 つまり、先の記事の Mailefile ファイルでの make rsync_upload コマンドでエラーになるのは、username (仮名) でログインするために root 以外は HTML のルート ディレクトリに書き込めないという制限に引っかかるのが原因です。 だからといって SSH_USER=root に変えたところで、今度は root でログインできないという制限に引っかかるだけです。

Web サーバーにアップロードできるようにするには、 username (仮名) というユーザーに対して、Web サーバーの HTML のルート ディレクトリへの書き込みを許可する方法があります。 またはこれとは別に、Web サーバーに root でログインできるようにする方法もあります。 しかし、ここではこれらとは別の方法は採ることにします。 なお、ここで採る方法でも、先のふたつの方法と同様に Web サーバーの設定を触るため、Web サーバーの管理者権限が必要です。

rsync は、接続先のサーバーが --daemon オプション付きで rsync をサービス (デーモン) として起動・常駐しているのでも無い限り、接続先のサーバーにログインしてから接続先で rsync コマンドを実行して両方の rsync 間でファイルを送受信します。 接続先へのログインは、接続元で rsync を起動したユーザーか、rsync のオプションで明示的に指定したユーザーで行います。 接続先での rsync の起動はログインしたユーザーで行います。 make rsync_upload コマンドを実行したときは SSH_USER=username で指定している username というユーザーがそれです。 このため、Web サーバーの HTML のルート ディレクトリに書き込みができないのはこのためです。

そこで、Makefile ファイルの中の make rsync_upload コマンドで実行される箇所にある rsync の行に --rsync-path "sudo rsync" を書き足して、以下のように修正します。

    :
rsync_upload: publish
    rsync -e "ssh -p $(SSH_PORT)" -P -rvzc --delete $(OUTPUTDIR)/ $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR) --cvs-exclude --rsync-path "sudo rsync"
    :

この修正によって、アップロード先 (接続先) の Web サーバーにログインして実行するコマンドが rsync から sudo rsync に変わります。 その結果、接続先にログインしてから起動する rsync のユーザーが root ユーザーになり、HTML のルート ディレクトリへの書き込みができるようになります。

Mailefile ファイルを修正したところで、make rsync_upload コマンドを実行してみます。 すると以下のようなエラーになるでしょう。

sudo: no tty present and no askpass program specified
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(226) [sender=3.1.1]

これは sudo コマンドが、パスワードの入力を要求するためです。 このエラーを無くすために、sudo rsync コマンドに対してはパスワードの入力を要求しないようします。 そこで今度は Web サーバーの設定を触ります。

まずは Web サーバーに ssh などでログインします。 Web サーバーにログインしたら、sudo ls /etc/sudoers.d コマンドを実行して /etc/sudoers.d ディレクトリにあるファイルを確認しておきます。 今回は /etc/sudoers.d ディレクトリに、新しく rsync_nopw_sudo ファイルを作成して設定を書き込みます。 すでに rsync_nopw_sudo ファイルがあるときは、違う名前にしても構いません。

/etc/sudoers.d ディレクトリに rsync_nopw_sudo ファイルが無いことを確認したら、sudo visudo -f /etc/sudoers.d/rsync_nopw_sudo コマンドを実行します。 エディターが起動するので、以下を書いて保存して閉じます。

Cmnd_Alias  PELICAN_RSYNC = /usr/bin/rsync --server *
Defaults!PELICAN_RSYNC  !requiretty
username    ALL=(ALL) NOPASSWD:PELICAN_RSYNC

このファイルを作成・編集するときは、できるだけ visudo コマンドを使ってください。 visudo コマンドでは、ファイルを保存するとき、実際に保存する前にその内容を調べて、問題があるときには保存せずに修正を促すようになっています。 visudo コマンドを使わず、他のエディター (例えば vi) で編集したり、リダイレクトを使って直接ファイルを作ったりすると、内容を間違えたときに sudo コマンドがエラーになって機能しなくなる恐れがあります。

間違えない自信があるのなら、以下のようにして /etc/sudoers.d/rsync_nopw_sudo ファイルを直接作ってもいいでしょう。

cat <<__EOT__ | sudo tee /etc/sudoers.d/rsync_nopw_sudo >/dev/null
Cmnd_Alias  PELICAN_RSYNC = /usr/bin/rsync --server *
Defaults!PELICAN_RSYNC  !requiretty
username    ALL=(ALL) NOPASSWD:PELICAN_RSYNC
__EOT__

上記の内容で Web サーバーに /etc/sudoers.d/rsync_nopw_sudo ファイルを作れば、make rsync_upload コマンドで Web サーバーにアップロードできるようになります。 Web サーバーが Ubuntu のときは 2 行目の Defaults!PELICAN_RSYNC !requiretty は無くても構いません。

Comments