便利なSyncthingですが、WAN上のどこかのリレーサーバーを経由して同期する、という部分については好ましくないケースもあると思います。自宅のLAN内でのみ使うので、LAN内に閉じていてほしいとか、開発時のネットワーク内で閉じていてほしいとか、いくつかあると思います。
外部アクセスをオフにする
Syncthingでは、デフォルトでリレーサーバーへのアクセスが発生するようです。直接LANで通信できる状態であったとしても、他の直接アクセスできないデバイスのことを考慮すると、1接続は外経由で情報をもらうしかない、という事情のように思います。
完全に外部ネットワークが不要な場合には、Syncthingで以下の設定を行います。
- グローバル探索 をオフ
- 中継サーバー経由の通信を有効にする
これらの設定で定常的に外部のサーバーと接続された状態というのは解消されます。グローバル探索を行わない時点で、NAT トラバーサル有効 についても、チェック解除してもよいかと思います。
リレーサーバーを自前でやりたい
Dockerコンテナでsyncthingを使っていて、ネットワークモードをhostにせず使う場合、先のようなリレーなしという設定では同期ができなくなります。以前に記載したようにコンテナ上でのネットワークと通常のLANネットワークの直接通信ができないためです。
また、スマホや外出時で使用するノートPCなどとも同期したいということもあるでしょう。この場合では、先の設定だと同一のネットワークにいるときのみ同期ができるという限定的なものになってしまいます。
必要なもの
データの中継と同期対象デバイスの検出という点で2つのサーバーを使います。どちらもsyncthingで準備がされているものです。
- リレーサーバー
- ディスカバリーサーバー
本記事ではこれらのサーバーをひとまとめにして稼働させる想定ですすめています。
リレーサーバーを自前で用意
まず、リレーサーバーを自分で用意する、部分について説明します。他の誰かが用意しているものを使うには抵抗があるが、自分が用意した中継(リレー)サーバーならまだ安心と思う人にぴったりです。開発時などの閉じたネットワーク内であっても、その中にリレーサーバーを置けばよいので、便利さが1つ上がるのではと思います。
リレーサーバーについてもsyncthingにはドキュメントがあります。こちらにオプションなどの詳しい情報があります。
syncthingのリレーサーバーについてもDocker Hubでイメージが用意されています。こちらを使うことにします。詳しい設定内容についてはマニュアルを参照してください。本記事の後ほどでディスカバリーサーバーとセットにしたComposeファイルの記述例を掲載します。
ディスカバリーサーバーの用意
自前で用意したディスカバリーサーバーを使うことで、「グローバル探索」を使わずにできます。逆に言えば、リレーサーバーを用意しただけではグローバル探索を有効にしないといけない、ということです。管理下のネットワーク内で完結させるためには、ディスカバリーサーバーも必要です。
ディスカバリーサーバーについても、コンテナの用意があります。
ディスカバリーサーバーのマニュアルページはこちらになっています。
Composeファイルを用意して、サーバーを起動
リレーサーバーとディスカバリーサーバーをひとまとめにして扱いたいので、Composeファイル(docker-compose.yml) を作ります。コンテナがそれぞれ分かれていたので、このような方法としていますが、自分で1つのコンテナに2つのサーバーを格納する・ビルドするという選択もありでしょう。
Composeファイルは次のように作成します。ボリュームについてはバインドマウントする形ではなく名前付きボリュームを作成しています。これは、compose up/down によって起動し直しが発生したときであっても、ID情報などを引き継げるようにするためです。
services:
syncthing-relay:
image: syncthing/relaysrv:1.27
container_name: syncthing-relay
ports:
- "22067:22067"
- "22070:22070"
command: -pools=""
environment:
- TZ=Asia/Tokyo
volumes:
- relaycerts:/var/strelaysrv
syncthing-disco:
image: syncthing/discosrv:1.27
container_name: syncthing-disco
ports:
- "8443:8443"
volumes:
- discocerts:/var/stdiscosrv
volumes:
relaycerts:
discocerts:
このファイルを使って、docker compose up -d などでサーバーを起動します。このとき、以下のコマンドを実行して、起動時のログを確認しておいてください。
$ docker compose up -d
$ docker compose logs
このログのなかで使用するものは、赤線を引いた部分です。
- ディスカバリーサーバー (syncthing-disco) の Server device ID 情報
- リレーサーバー(syncthing-relay) のデバイスID情報(id=xxxx~)の情報
クライアントの設定
用意したサーバーを使うようにクライアントの設定を行います。
リレーサーバーの設定
この記事の冒頭でも記載していたリレーサーバーの設定変更を行います。起動したサーバーのIPアドレスと、リレーサーバーのデバイスID情報から、下記の画面に示す「同期プロトコルの待ち受けアドレス」の部分を記述します。
ここで記載する内容は、「relay://(IPアドレス):(ポート番号)/?id=(デバイスID情報)」となります。他のデバイスからアクセス可能な、リレーサーバーのIPアドレスを使うようにしてください。
次に、リレーサーバー経由でデータの転送ができるように設定します。中継サーバー経由の通信を有効にする、にチェックを入れます。
この設定で準備したリレーサーバーを使うことが可能となります。
ディスカバリーサーバーを設定
同期デバイスがそれぞれを検出できるようになるためには、ディスカバリーサーバーの設定が必要です。これについては、サーバーを起動したときに出力されたデバイスID(device ID)が必要になります。
クライアントの設定画面で、上記のように「グローバル探索」を有効にして、「グローバル検索サーバー」の項目を、先に構築したサーバーを設定するようにします。従来はここに “default” と記載があったと思いますが、それを削除して、用意したサーバーのみを記述します。
ここで、https://(IPアドレス):8443/?id=(デバイスID) というアドレス情報を記入します。ここでのデバイスIDはディスカバリーサーバーのものを使うように注意してください。リレーサーバーのものとは違うIDとなります。
動作の確認
これらの設定が完了して、しばらくすると、同期対象に設定しているデバイスが同期中というステータスになると思います。また、待ち受けポートや探索サーバーの項目についても下記のようにブルーやグリーンの色で示されるステータスになります。接続不良がおこっていると、この部分は赤色で表示されます。
その他の話題
公式で用意されているサーバー(Dockerコンテナ)はそれぞれ別々でしたが、他の方はそれらをまとめたコンテナを作っていたりするようです。うまく条件があるようであればそちらを使うのもよいかと思います。私が見つけたのは次のようなものです。
デバイスIDについて
デバイスIDとは何か、と見ていたら、証明書から生成されるハッシュキーみたいなものです。そのため、デバイスIDは任意文字列とすることはできません。また証明書が更新という状況になるとデバイスIDが変化してしまう、ということにもなるようです。
ということは、証明書情報を先に生成し、コンテナに配置というフローを辿れれば、リレーやディスカバリーサーバーを起動するまでIDがわからない、という状況を回避することはできるのかもしれません。
ディスカバリーサーバーの https アクセス
ディスカバリーサーバーは https による指定が必要です。http はダメです。そこで気になるのが証明書の検証の話ですが、本記事に記載したデバイスIDをディスカバリーサーバー指定時に合わせて記載することで、問題なく通信が成立できるようです。
デバッグ用のツール
リレーサーバーなどの動作をチェックしたい場合には、ツールを使うとよいみたいです。
コメント