マルチプラットフォームファイル同期ソフトSyncthingのご紹介

Posted by 雅楽斎 on Tuesday, July 9, 2019

TOC

Syncthingとは

https://syncthing.net/

マルチプラットフォームで動作するファイル同期ソフトウェアです。利用は無料です。

動作プラットフォーム

  • Windows1
  • macOS
  • Linux
  • Android
  • 他、Go言語で利用できる多くのプラットフォーム

特徴

メリット

  • 対応プラットフォームが多く、無料で利用できる場合が多い2
  • メンテナンスされている3
  • 通信は暗号化される
  • MPL2.0で提供される
  • Go言語で実装されているので高速
  • DIscovery Serverの利用が無料なので、インターネット越しでも同期が可能(デフォルト利用)

デメリット

  • 同期したファイルの履歴を確認するのが困難
  • 衝突した場合のリカバリー方法が不明
  • 共有している全てのPCでディスク容量を消費する(当然)
  • 同期ディレクトリを移動する方法がない?
  • 使用しなくなったデバイスは紹介者から導入されると消せない
  • ownCloud/NextCloudのようなアプリを追加してというものはなく、ファイル同期に特化

インストール

Linux(debパッケージ)

Ubuntuの場合、パッケージがありますが(18.04の場合)バージョンが古いので別途aptを追加してインストールしましょう。snapが利用可能であればそちらでも良いと思います。

以下の手順でインストールします。 https://apt.syncthing.net/

# curl -s https://syncthing.net/release-key.txt | apt-key add -
# echo "deb https://apt.syncthing.net/ syncthing stable" | tee /etc/apt/sources.list.d/syncthing.list
# apt-get update
# apt-get install syncthing

Linux(snap) ※個人的には非推奨

Ubuntu MATE 19.10にsnapでインストールしてみました。snapパッケージの場合、自動起動の設定時はroot権限が必要です。

# snap install syncthing

Android

Google PlayまたはF-Droidからインストールしましょう。

設定

サービスの自動起動設定

ユーザーサービス

好みではありますが、systemdのユーザーデーモンとして起動するよう設定します4

$ mkdir -p ~/.config/systemd/user
$ cp -p /usr/lib/systemd/user/syncthing.service ~/.config/systemd/user/

サービスとして登録・起動5

$ systemctl --user enable syncthing.service
Created symlink /home/hogehoge/.config/systemd/user/default.target.wants/syncthing.service → /home/hogehoge/.config/systemd/user/syncthing.service.
$ systemctl --user start syncthing.service
$ systemctl --user status syncthing.service 
● syncthing.service - Syncthing - Open Source Continuous File Synchronization
   Loaded: loaded (/usr/lib/systemd/user/syncthing.service; disabled; vendor pre
   Active: active (running) since Tue 2019-07-09 09:47:35 JST; 2s ago
     Docs: man:syncthing(1)
 Main PID: 10768 (syncthing)
   CGroup: /user.slice/user-1000.slice/user@1000.service/syncthing.service
           └─10768 /usr/bin/syncthing -no-browser -no-restart -logflags=0

 7月 09 09:47:36 chrx syncthing[10768]: [7RNE7] INFO: Using discovery server htt
 7月 09 09:47:36 chrx syncthing[10768]: [7RNE7] INFO: Using discovery server htt
 7月 09 09:47:36 chrx syncthing[10768]: [7RNE7] INFO: Loading HTTPS certificate:
 7月 09 09:47:36 chrx syncthing[10768]: [7RNE7] INFO: Creating new HTTPS certifi
 7月 09 09:47:36 chrx syncthing[10768]: [7RNE7] INFO: TCP listener ([::]:22000) 
 7月 09 09:47:36 chrx syncthing[10768]: [7RNE7] INFO: Relay listener (dynamic+ht
 7月 09 09:47:36 chrx syncthing[10768]: [7RNE7] INFO: Completed initial scan of 
 7月 09 09:47:36 chrx syncthing[10768]: [7RNE7] INFO: GUI and API listening on 1
 7月 09 09:47:36 chrx syncthing[10768]: [7RNE7] INFO: Access the GUI via the fol
 7月 09 09:47:36 chrx syncthing[10768]: [7RNE7] INFO: My name is "chrx"

起動していることを確認したら、サービスとして自動起動させるよう設定します。

$ systemctl --user enable syncthing.service 
Created symlink /home/chrx/.config/systemd/user/default.target.wants/syncthing.service → /home/chrx/.config/systemd/user/syncthing.service.

自動起動を停止する場合は以下のコマンドを実行します。

$ systemctl --user disable syncthing.service 
Removed /home/chrx/.config/systemd/user/default.target.wants/syncthing.service.

設定ファイルは ~/.config/syncthing/config.xml に作成されます。

システムサービス ※個人的非推奨

自動起動をしようとしてもsystemdのサービス定義ファイルがないので、/lib/systemd/system/syncthing@hogehoge.service6として以下の内容でファイルを作成します。githubで管理されているsyncthing.serviceとはExecStartに渡すバイナリのパスが異なりますがそれ以外は同じです。

[Unit]
Description=Syncthing - Open Source Continuous File Synchronization
Documentation=man:syncthing(1)

[Service]
ExecStart=/snap/bin/syncthing -no-browser -no-restart -logflags=0
Restart=on-failure
SuccessExitStatus=3 4
RestartForceExitStatus=3 4

# Hardening
ProtectSystem=full
PrivateTmp=true
#SystemCallArchitectures=native
#MemoryDenyWriteExecute=true
#NoNewPrivileges=true

[Install]
WantedBy=default.target

Systemd hardening options prevent service start · Issue #5449 · syncthing/syncthing

Hello, After updating to v1.0.0, service fails to start with this exit status: 228/SECCOMP. I found this article, which gave me a hint about the issue: the kernel I am using seems not to support se...

systemdのシステムサービスとして登録します。

# systemctl enable syncthing@hogehoge.service
Created symlink /etc/systemd/system/default.target.wants/syncthing@hogehoge.service → /lib/systemd/system/syncthing@hogehoge.service.

OS起動時に実行するよう指定します。

# systemctl start syncthing@hogehoge.service
# systemctl status syncthing@hogehoge.service
● syncthing@hogehoge.service - Syncthing - Open Source Continuous File Synchroni
   Loaded: loaded (/lib/systemd/system/syncthing@hogehoge.service; enabled; vend
   Active: active (running) since Thu 2020-01-09 09:06:43 JST; 7s ago
     Docs: man:syncthing(1)
 Main PID: 1800 (syncthing)
    Tasks: 14 (limit: 4915)
   Memory: 23.6M
   CGroup: /system.slice/system-syncthing.slice/syncthing@hogehoge.service
           └─1800 /snap/syncthing/442/syncthing -no-browser -no-restart -logflag

 1月 09 09:06:45 hogehoge-MiniBook syncthing[1800]: [XKHQU] INFO: Relay listener
 1月 09 09:06:45 hogehoge-MiniBook syncthing[1800]: [XKHQU] INFO: Loading HTTPS 
 1月 09 09:06:45 hogehoge-MiniBook syncthing[1800]: [XKHQU] INFO: Creating new H
 1月 09 09:06:45 hogehoge-MiniBook syncthing[1800]: [XKHQU] INFO: GUI and API li
 1月 09 09:06:45 hogehoge-MiniBook syncthing[1800]: [XKHQU] INFO: Access the GUI
 1月 09 09:06:45 hogehoge-MiniBook syncthing[1800]: [XKHQU] INFO: My name is "ho
 1月 09 09:06:45 hogehoge-MiniBook syncthing[1800]: [XKHQU] WARNING: Syncthing s
 1月 09 09:06:45 hogehoge-MiniBook syncthing[1800]: [XKHQU] WARNING: Failed to l
 1月 09 09:06:45 hogehoge-MiniBook syncthing[1800]: [XKHQU] INFO: Ready to synch
 1月 09 09:06:45 hogehoge-MiniBook syncthing[1800]: [XKHQU] INFO: Completed init

起動はして、ブラウザからの設定もできるようになりますが、WARNINGが出るのとブラウザに以下のメッセージが表示されます。

Syncthing should not run as a privileged or system user. Please consider using a normal user account.
Failed to lower process priority: set niceness: operation not permitted 

概ね以下の内容かと思います。

  • 共有するファイルが一般ユーザーでなくroot権限で保持されるので、それで問題ないか考えて欲しい
  • 低いプロセス優先度で実行できない nicenessを設定できない

万一セキュリティホールを踏んでしまうとroot権限で実行してしまうのでできれば避けて欲しいという内容かと思います。なので、個人的にはこの方法は非推奨です。

ブラウザから設定

http://localhost:8384/ でWeb GUIが起動しているので、ブラウザから接続します。

匿名データ送信確認

初回起動時は匿名の使用データを送信するか聞いてくるので、どちらか選びましょう。

最初から1つDefault Folderとして追加されていますが、お試しで使う場合以外は削除した方が良いと思います。7Androidの場合、カメラフォルダーがデフォルトで設定されています。

Default Folderの削除

フォルダーのアイテムをクリックすると、拡大して表示されます。8

Default Folder

この状態で、「/home/chrx/Sync」というディレクトリが同期されることがわかります。まずはこれを削除しましょう。「編集」をクリックします。

削除する

一般タブを下の方にスクロールすると除去ボタンが出てくるので、これをクリックします。ディレクトリ自体は削除されない確認ダイアログの後、一覧から削除されます。

動作環境設定

まず、同期するディレクトリを格納する場所を決めます。~/Syncはわかりづらいのですぐわかるように~/Syncthingにリネームしています。ブラウザの右上に「⚙メニュー」があり、この中に「⚙設定」があるのでそれをクリックします。

設定

デバイス名は識別しやすい名前を設定した方が良いのと、一番下にあるデフォルトのフォルダーパスは、他のデバイスから同期要求を受信した際のデフォルトフォルダーもここになるのでちゃんと決めることをオススメします。私の場合は~/Syncthingにしています。

設定変更

デバイスの追加

sequenceDiagram Title: デバイスの追加 participant a as 新規デバイス participant b as 既存デバイス alt 新規デバイスから既存デバイスを追加 a ->> a: 既存デバイスのIDを入力(QRコード読み取りを含む) a ->> b: デバイスの追加 b ->> b: デバイスの追加要求 b ->> b: 追加要求の承認 b -->> a: デバイス追加完了 else 既存デバイスから新規デバイスを追加 b ->> b: 新規デバイスのIDを入力(QRコード読み取りを含む) b ->> a: デバイスの追加 a ->> a: デバイスの追加要求 a ->> a: 追加要求の承認 a -->> b: デバイス追加完了 end

デバイスの追加は既にSyncthingが動作している端末から要求を送ることも、逆に新しい端末から要求を送ることも可能です9。今回は導入済みの端末からこの端末へ追加する手順にします。

右上の⚙メニューから「IDを表示」を選択すると、IDとQRコードが表示されるので、これを他のデバイスから追加します。

追加時には以下の情報も設定可能です。

  • デバイス名
  • 圧縮するデータ(オフ、メタデータのみ、全て)
  • 紹介者デバイス
  • 自動承諾
  • このデバイスを一時停止

紹介者デバイスはかなり強力で、そのデバイスに追加されたデバイスが増えるたびに自動的に接続先デバイスとして追加されます。個人的にはあまりオススメしません(デバイスを削除する時に面倒)

端末に追加要求が送られると、Web GUIの上の方に表示されます。

追加要求

デバイスを追加を押すと、接続先デバイスとして追加されます。

同期ディレクトリの追加

sequenceDiagram Title: 同期ディレクトリの追加 participant a as 追加する側のデバイス participant b as 追加される側のデバイス a->>a: 同期ディレクトリに追加される側のデバイスを追加 a->>b: ディレクトリの追加要求 b->>b: 内容確認、要求承認 b-->>a: ディレクトリの追加完了、同期開始

デバイスの追加の後は、同期したいディレクトリを追加します。他のデバイスから同期要求を受けた場合は、デバイスと同じようにWeb GUIの上の方に表示されます。問題ない場合はフォルダーパスを確認して追加します。

このデバイスで同期しているディレクトリを他の接続先デバイスに追加したい場合、フォルダーの編集、共有タブから共有するデバイスを追加します。

同期中の図

クラウド利用

インターネット経由でも同期が行えるため、VPSにSyncthingをインストールすればインターネット接続するデバイス全てで同期が可能です。

動作条件を考慮してSSHでSyncthingのWeb GUIポートをポートフォワードします。

  • ポートフォワードするSyncthingのWeb GUIポートは8384
  • SSH接続してポートを転送する先はローカルホストの9999
sequenceDiagram Title: SSHポートフォワードによるクラウド利用 participant a as ローカルPC participant b as VPS等クラウド a->>b: ssh -L 9999:localhost:8384 user@cloud Note left of a: SSHセッション確立
(ポートフォワード) a->>+a: ブラウザでhttp://localhost:9999/へアクセス a->>a: クラウド上のSyncthingをブラウザから操作 a->>-a: ブラウザを閉じる b-->a: SSH切断 Note left of a: SSHセッション・
ポートフォワード
切断

SSH接続ができたらローカルPCから http://localhost:9999 を開いてSyncthingの設定を行います。いきなりログインできるのでセキュリティとしてWeb GUIへのログインを設定すべきかどうかですが、SSHトンネルを通っているので暗号化はされています。ただ、気になる場合は⚙メニュー→⚙設定のGUIタブで設定可能なログインIDとパスワードを設定してください。

ログインID、パスワード設定

デメリットの詳細

機能面の説明はここまでで、実際に使っている身としてデメリットとして挙げた事項について補足します。

同期したファイルの履歴を確認するのが困難

Syncthing自体は同期対象になっているディレクトリの変更を検知してそれぞれのデバイスに変更を伝えるというアプローチを取っています。これがファイル単位で「これ更新したんだけど反映されてるかな…」という確認が難しいのが制約事項のひとつかもしれません。

というのは、その場所を片付けないといけなくて急いでファイルをセーブしてネットワークを切断した場合などはローカルPCでは変更されていて他のデバイスへ変更が反映されていない状態になります。

また、ファイルがどのデバイスへ同期されたかについて確認するAPIがないので、正確に把握するのも困難です。10

再度ネットワークにつなげればそこから同期は始まるのですが、同じファイルを他のデバイスで変更していたりしていた場合、どちらかの状態で上書きされるので、このような使い方11には向いていません。そのような場合は確実にユーザー間の排他を行えるソリューション(Git等)を使用すべきです。

衝突した場合のリカバリー方法が不明

ファイルの変更が不完全に終わった場合、「.syncthing.ファイル名.拡張子.tmp」というファイル名でディレクトリ内に残ることがあります。

この場合、恐らく想定解としては「ファイルを更新したデバイスで変更ファイルを正しい内容で変更する」なのですが、そのようにいかないことがありました。(他のデバイスでtmpファイルが残る)

その時は最終的にファイルを変更した上で、他のディレクトリにそのディレクトリの内容を全てコピーしました。基本的にはそうならない筈ですが実際に起きてしまった事例です。

同期ディレクトリを移動する方法がない?

同期ディレクトリは同期を始める時に指定しますが、後から変えたくなる事もあると思います。

ですが、現状恐らくSyncthing自体がこの機能を持っておらず、機能として追加されるまでは移動をする方法がありません。公式のフォーラムでも取り上げられており、手順として以下が考えられます。

  1. 対象ディレクトリの同期を解除する
  2. 新しいディレクトリを他のデバイスから同期させる
  3. 正しく同期が終わったら元のディレクトリを削除する

参考:How can the folder path be changed?

使用しなくなったデバイスは紹介者から導入されると消せない

Syncthingには紹介者デバイスという概念があり、紹介者デバイスに指定したデバイスに新しくデバイスを追加すると、元々追加済みだったデバイスに共有の要求が自動的に届きます

元々この機能は凄いなーと思いながら使っていたんですが、長く使うに当たってそのデバイスをもう使わなくなることがあったので、当然そのデバイスを削除しようとしたところ、紹介者デバイスから自動的に共有されたデバイスは元の紹介者デバイスの指定を外さないと削除できません。

長く運用すると二度手間になると感じたので現在は使っていません。デバイスはきちんと管理しましょう。

以上になります。LAN上はもちろん、インターネット経由でもファイルを同期できるというのは素晴らしいと実感しています。自動バックアップとしても機能させられます。適切に使っていきたいですね。

スポンサーリンク


  1. Windows向けはSyncthing自体のバイナリとは別にサードパーティーでSyncTrayzorというアプリが提供されていますがこっちを使ったほうが楽でいいと思います。 https://github.com/canton7/SyncTrayzor/releases/latest [return]
  2. iOSは有料のアプリがあるようです [return]
  3. 毎月初旬に新しいバージョンがリリースされます [return]
  4. そのユーザーがログインしている時に動作させる [return]
  5. 追記前は登録コマンドsystemctl --user enableが抜けていました。申し訳ありません。 [return]
  6. hogehogeはユーザー名が入ります [return]
  7. 追加したデバイスにこのフォルダが同期されるので [return]
  8. このデバイス、接続先デバイスもクリックすると拡大表示します [return]
  9. 新しい端末から要求を送る場合、追加したい端末のIDが必要です。 [return]
  10. デバッグログにはデバイスIDとファイル名が記録されていますので気合を入れて確認すること自体は可能ですが [return]
  11. 複数人で同じファイルを頻繁に更新する [return]

comments powered by Disqus