LoginSignup
7
14

More than 3 years have passed since last update.

Ubuntu Server 2台間でファイル同期(lsyncd + rsync + sshd)

Last updated at Posted at 2019-08-29

背景

2台のLinuxサーバーでファイル同期させて冗長化やバックアップに利用するメモです。

動作環境

  • OS:Ubuntu Server 16.04LTS
  • OS:Ubuntu Server 18.04LTS
  • sshd
  • rsync
  • lsyncd

同期設定のポリシー

2台のサーバー間を双方向で同期する方法と、バックアップの様に片側同期する方法があります。
今回は後者の片側同期に設定します。
双方向同期の場合はファイル削除時の動作を設計時に考慮しないと思わぬデータ消失に繋がり注意が必要です。

rsyncサービスデーモン(rsyncd)

ネットで検索するとrsyncdを使用するページが出てきますが、その場合はサービスポートTCP 873番を経由します。
しかし昔ながらのIPアドレス範囲をallow/denyで制限したり、暗号化無しの平文パスワード利用と今時のセキュリティ的にはよくありません。
閉域網のセキュリティが確保された内部のサブネットで、転送速度のパフォーマンス重視の場合などで検討しましょう。今回は使用しません。

rsyncコマンドをsshd経由で暗号化して公開鍵認証した安全な経路が利用できますので、外部のインターネット経由したサーバー間でも安全な同期が可能です。
sshサービスデーモン(sshd)経由を利用するので一般的なsshd設定が利用可能です。

sshユーザー設定

各サーバーに適当なアカウント「rsync」を作成します。
ユーザーアカウントでシステムファイル操作のパーミッション権限はsudoで対応します。

各サーバー共通
$ sudo adduser rsync

sudoグループに追加します。

各サーバー共通
$ sudo gpasswd -a rsync sudo

「rsync」ユーザーに切り替えてパスフレーズ無しのssh鍵ペアを作成します。
コメントの-Cオプションにサーバーホスト名も付けておくと区別し易いね。

サーバー1(node1)側
$ su rsync
$ ssh-keygen -t ed25519 -C "rsync@node1" -N ""
サーバー2(node2)側
$ su rsync
$ ssh-keygen -t ed25519 -C "rsync@node2" -N ""

ssh鍵を互いのサーバーへ登録します。
方法は色々ありますがssh-copy-idコマンドが簡単。

サーバー1(node1)側
$ ssh-copy-id -i .ssh/id_ed25519 rsync@node2
サーバー2(node2)側
$ ssh-copy-id -i .ssh/id_ed25519 rsync@node1

実際にパスフレーズ無しの公開鍵認証で接続出来るか、互いのサーバーで確認します。

サーバー1(node1)側
$ ssh -i .ssh/id_ed25519 rsync@node2
サーバー2(node2)側
$ ssh -i .ssh/id_ed25519 rsync@node1

rsyncコマンドをsudo経由でパスワード入力無しで実行する設定(サーバー2 node2側)

サーバー2(node2)側
$ sudo visudo
/etc/sudoers
rsync ALL=(ALL) NOPASSWD: /usr/bin/rsync

パスフレーズ無しのssh鍵であってもsudoコマンド実行時にはアカウントのパスワード入力を要求されますので、特定コマンド(この場合はrsync)だけパスワード要求を無効化します。
これでrsyncコマンドをsudo経由で実行出来るので、ファイルの書き換え時にパーミッション制限でのエラーを回避出来ます。

lsyncサービスデーモン(lsyncd)設定

同期元サーバー1(node1)側へインストールして設定する。ちなみに双方向で同期する場合は両方へインストールします。

サーバー1(node1)側
$ sudo apt-get install lsyncd

設定ファイルを作成します。
サンプルファイルが、「/usr/share/doc/lsyncd/examples/lsyncd.conf.lua」とかにありますので参考に。

/etc/lsyncd/lsyncd.conf.lua
settings = {
        logfile = "/var/log/lsyncd.log",
        statusFile = "/tmp/lsyncd.stat",
        insist = 1,
        statusInterval = 10
}

sync_base = {
        default.rsync,
        delete = running,
        init = false,
        rsync = {
          archive = true,
          rsync_path = "sudo /usr/bin/rsync",
          rsh = "/usr/bin/ssh -i /home/rsync/.ssh/id_ed25519 -o StrictHostKeyChecking=no"
        }
}

sync{ sync_base, source="/home/rsync/test1/", target="rsync@node2:/home/rsync/test1/"}
sync{ sync_base, source="/etc/test2/", target="rsync@node2:/etc/test2/"}

設定オプションは以下の様になります。

  • statusInterval:インターバル・デフォルト10秒
  • delete = running:同期時のみ削除可
  • init = false:起動時は同期を反映しない
  • archive = true:rsyncの-aオプションと同等
  • rsync_path = "sudo /usr/bin/rsync":rsyncコマンドをsudo経由で実行

最後のsyncの2行で監視するディレクトリと同期先を2箇所指定しています。複数ある場合は同じ様に追加設定します。

lsyncサービスデーモン(lsyncd)の再起動

サーバー1(node1)側
$ sudo systemctl restart lsyncd

動作確認

適当な空ファイルを作成して、サーバー2(node2)側に反映するか確認してみます。

サーバー1(node1)側
$ touch /home/rsync/test1/test1.txt
サーバー2(node2)側
$ ls -l /home/rsync/test1/

sudo経由なのでシステムファイルも同期出来ます。

サーバー1(node1)側
$ sudo touch /etc/test2/test2.txt
サーバー2(node2)側
$ ls -l /etc/test2/

動作検証にログファイルが確認出来ます。

サーバー1(node1)側
$ sudo tail /var/log/lsyncd.log
7
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
14