テスト環境から商用環境へのデプロイにrsyncを使っている。一方ローカルの開発環境(Windows)からはちまちまと手動でアップロードすることも多い。チーム内で見かけた手段はWinSCP、FFFTP、FileZilla、Eclipse + ant、ftp(コマンドライン)…。

どうせならローカルからサーバもrsyncでコマンド一発!のほうが幸せになれるんじゃないか?ということで方法を探ってみた。

●Cygwinを使う場合

CygwinとはWindowsで動くLinuxライクなツール群。私はMeadowを使うので大事ツール。

まずはsshとrsyncがインストールされているか確認。

$ which ssh
/usr/bin/ssh
$ which rsync
/usr/bin/rsync

無事にインストールされているようだ。見つからないなら(デフォルト構成ではインストールされない)、cygwin/setup.exeを使ってNetInstallする。「Select Packages」で「Net」ツリーを開き、「rsync」と「openSSH」をインストールする。詳細は「Cygwinのインストール&設定方法」を参照されたい。

●Cygwinを使わない場合

cwRsyncというお手軽ツールがある。Cygwinのサブセットで、rsyncするために必要最低限のものがパッケージされている。ここからダウンロードして展開、インストーラを実行するだけ。今回はrsyncサーバ(syncされるほう)を立てる予定はないので、インストールしただけで終了。

●パスワードなしで実行したい

一番手軽なオペレーションは「コマンドラインからヒストリでバッチを叩く(Up -> Enter)と終了」だろう。パスワードやらなにやらを毎回入力するのは避けたいので、rsaキーによる認証を準備する。

通常rsyncは「sync元でキー作成>sync先にキーをコピー」でパスワードなしの転送を実現するのだが、なんとなく商用環境で動いているサーバにWindowsで作ったキーを置くのは気が引ける。そこで、rsync先のサーバからprivate keyを持ってくることにする。

◆rsync先にrsyncしたいユーザでログイン。ホームディレクトリに「.ssh」がなければ作成。

[user_name@remote_host ~]
$ mkdir .ssh
$ chmod 0700 .ssh
$ cd .ssh

◆.sshにキーを作る。

[user_name@remote_host .ssh]
$ ls -1
authorized_keys
id_rsa
id_rsa.pub
known_hosts

★もし「id_rsa」(秘密鍵)および「id_rsa.pub」(公開鍵)が**存在しているなら再作成してはならない**。このキーを使ってログインしている他の人が、キーが変わることによって入れなくなってしまうから。人が入れないならすぐ気づくが、バッチが失敗しているのには気づきにくい。

存在しなければキーを作る。

[user_name@remote_host .ssh]
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/apache_dsneo/.ssh/id_rsa): [enter]
Enter passphrase (empty for no passphrase): [enter]
Enter same passphrase again: [enter]
Your identification has been saved in .id_rsa.
Your public key has been saved in .id_rsa.pub.
The key fingerprint is:
**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:** user_name@remote_host
$ chmod 0600 id_rsa
$ cat id_rsa.pub >> authorized_keys
$ chmod 0600 authorized_keys

◆プライベートキーをWindowsローカルに持ってくる

なんらかの方法で今作ったid_rsaをWindowsローカルに持ってくる。WinSCP / PuTTYを使っていればpscpがあるので簡単。このキーがあると対象サーバに入り放題になるので、取り扱いには十分注意すること。

C:\install\dir\of\PuTTY>pscp user_name@remote_host:.ssh/id_rsa path/to/private/key/id_rsa.remote_host

●rsync用batchを書く

[CW]の項目はcwRsync用。Cygwinの場合は必要ないっぽい。

@ECHO OFF
REM 環境変数の修正はこのバッチに閉じ込めてしまう
SETLOCAL
REM [CW] cwRsyncをインストールしたディレクトリを設定する
REM 例1 : Program Filesにインストール
SET CWRSYNCHOME=%PROGRAMFILES%\CWRSYNC
REM 例2 : フルパスで書いた
SET CWRSYNCHOME=C:\CWRSYNC
REM Cygwinからsyncするとファイルに共有属性がついてしまうのを防ぐ
SET CYGWIN=nontsec
REM [CW]'known_hosts'を置くために環境変数[HOME]を設定する。
REM この設定だと普通は[C:\Documents and Settings\user_name]
SET HOME=%HOMEDRIVE%%HOMEPATH%
REM [CW]cwRsync\binにpathを通す
SET CWOLDPATH=%PATH%
SET PATH=%CWRSYNCHOME%\BIN;%PATH%
REM Windowsのファイルパスはドライブレターの区切りに[:](コロン)を使うが、
REM rsyncで[:]はリモートホストの指定に使う。'a la unix'スタイルの絶対
REM パス指定を使うことで解決できる。
REM
REM Example : C:\WORK\* --> /cygdrive/c/work/*
REM
REM Example 1 - rsync recursively to a unix server with an openssh server :
REM       rsync -r /cygdrive/c/work/ remotehost:/home/user/work/
REM
REM Example 2 - Local rsync recursively
REM       rsync -r /cygdrive/c/work/ /cygdrive/d/work/doc/
REM
REM Example 3 - rsync to an rsync server recursively :
REM    (Double colons?? YES!!)
REM       rsync -r /cygdrive/c/doc/ remotehost::module/doc
REM ここにrsyncコマンドを書く
rsync -auvzrn -e "ssh -i /cygdrive/c/path/to/priate/key/id_rsa.remote_host" /cygdrive/c/path/to/source/dir/ user_name@remote_host:/path/to/destination/dir
REM 冒頭の[SETLOCAL]を閉じる
ENDLOCAL

“ssh -i …“はrsync先から持ってきた秘密鍵をフルパスで指定する。通常は/home/.ssh/を自動的に読み込むが、Windows環境ではPuTTYのprivate keyなんかと一緒にしておきたいので。

rsyncについてはこちらにドキュメントの日本語訳がある。[-n]オプション(dry-run:リハーサル)は重要なので覚えておこう。

rsync
http://www.infoscience.co.jp/technical/rsync/