自宅のSynology NASに溜めた写真を、友人に見せたい場合、共有リンクは作れますが、これまで使っていたQuickConnect経由だと表示が遅く、友人に送るのが少しためらいがありました。Google Photosはアクセスがいいのですが、写真と動画が結構圧縮されちゃうんですよね。特に動画。かといって、ルーターのポートを開けてNASを直接インターネットに出すのは避けたいところ。
そこで、ポートを開けずに共有リンクだけを外に出せる方法を2つ試しました。Cloudflare Tunnelと、Tailscale Funnelです。この記事は、その体験記です。
先に結論を書きます。どちらも、ポート開放なしで共有リンクを外から開けるようになりました。体感では、Cloudflareのほうが少しスムーズでした。ただ、Tailscaleでも十分に実用的です。自分は、URLを自分のドメインと切り離したかったので、Tailscaleを使うことにしました。
CloudflareとTailscaleとは
Cloudflare Tunnel

Cloudflareは、Webサイトの配信やセキュリティを手がける会社で、世界中にサーバーを持っています。Tunnelは、家のNASからCloudflareに向けて接続を張る機能です。外から家に入る穴(ポート開放)が要らず、自分のドメインを使って公開できます。個人で使うぶんには無料のプランで足ります。
Tailscale Funnel

Tailscaleは、自分のパソコンやNASなどを、安全に1つのネットワークにつなぐVPNサービスです。Funnelはその機能の1つで、Tailscaleを使っていない人にも、○○○.ts.netのURLでサービスを公開できます。こちらも、個人で使うぶんには無料で使えます。
なにを公開するか
Synology Photosの共有リンクは、/mo/sharing/から始まるURLです。このリンクが開くとき、実際にどんな通信が起きているのかを、ブラウザの開発者ツールで調べました。共有ページの表示に使われていたパスは、次の2つでした。
/mo/sharing/以下(ページ本体、画面の部品、アルバム情報の取得)/synofoto/api/v2/p/以下(サムネイルや写真の取得)
ログイン画面や、個人スペースの写真を取るAPIは、共有ページでは使われていません。そこで、この2つのパスだけを外に出して、残りは通さないようにする方針にしました。
準備として、Photos専用のポートを作る
DSMのコントロールパネルで、ログインポータルのアプリケーションから、Synology Photosにカスタムポートを割り当てました。HTTPのポートだけを有効にして、5080にしています。これで、NASのhttp://<NAS の IP>:5080が、DSMのログイン画面ではなく、Photosだけを返すようになります。以降の2つの方法は、どちらもこのポートを外に出す形です。

ここで1つつまずきました。Photosが発行する共有リンクはhttps://<ホスト名>/photo/mo/sharing/<ID>の形ですが、専用ポートでは/photoが付きません。ホスト名を差し替えるだけでは「ページが見つかりません」になるので、/photoも抜く必要があります。


方法その1 Cloudflare Tunnel
Cloudflare Tunnelは、NASからCloudflareに向けて接続を張る仕組みです。外からNASに入る穴は必要ありません。ただし、自分のドメインをCloudflareに登録している必要があります。年間千円~数千円かかるので、自分のドメインなんて普通持っている人はいないと思いますが…。
Tunnelを作ってNASで動かす
CloudflareのZero Trust(無料プラン)でTunnelを作ると、トークンが表示されます。このトークンは、NASのContainer Managerで動かすcloudflaredに渡す値です。Container Managerは、docker-compose.ymlに書いたフォルダを自動では作りません。先にFile Stationで作っておく必要があります。トークンはトンネルの鍵なので、人に見せないように気をつけました。
Tunnelが緑色のHealthyになり、コネクタがConnectedになれば成功です。公開ホスト名の行き先には、<NAS の IP>:5080をHTTPで指定しました。

WAFで、共有リンク以外を止める
この状態だと、Photosのログイン画面も外から見えてしまいます。そこで、CloudflareのWAFのカスタムルールで、公開したいパス以外をブロックしました。ここでもつまずきました。左メニューのWAFを開くと、アカウント全体向けの有料アドオンの画面が出ます。無料プランで使えるのは、ドメインを開いたあとのSecurityの中にある、Security rulesのほうです。
ルールの式は次のとおりです。
(http.host eq "photos.<自分のドメイン>" and not starts_with(http.request.uri.path, "/mo/sharing/") and not starts_with(http.request.uri.path, "/synofoto/api/v2/p/") and not starts_with(http.request.uri.path, "/cdn-cgi/"))
アクションはBlockにします。設定のあと、トップページを開くと「Sorry, you have been blocked」と表示されました。共有リンクはこれまでどおり開けます。ログイン画面を外から開けなくなったので安心。
方法その2 Tailscale Funnel
Tailscaleには、Funnelという機能があります。Tailscaleを使っていない人にも、○○○.ts.netのURLでサービスを公開できます。リンクを共有される側はアプリを入れる必要も、何かを設定する必要もありませんし、自分のドメインも必要ないというのがCloudflareよりも優れている点ですね。
準備
NASのパッケージセンターからTailscaleを入れて、アカウントでログイン。Tailscaleの管理画面では、MagicDNSとHTTPS証明書を有効にします。URLに端末名が入るので、NASの名前も、分かりにくいものに変えました。



Funnelを設定する
NASにSSHで入って、Cloudflareのときと同じ2つのパスを、Funnelに登録します。
sudo tailscale funnel --bg --set-path=/mo/sharing http://127.0.0.1:5080/mo/sharing
sudo tailscale funnel --bg --set-path=/synofoto/api/v2/p http://127.0.0.1:5080/synofoto/api/v2/p
初回は、Funnelの有効化を承認するURLが表示されます。ブラウザで開いて承認すると次から使えます。

設定のあとに、外から確認しました。登録した2つのパス以外は、ログイン画面も含めて、すべて404になりました。WAFのような別のルールを作らなくても、公開するパスを指定するだけで、同じ効果が得られます。
funnel status を実行すると、公開している2つのパスが表示されます。ホスト名は伏せています。
https://photo.<自分のtailnet>.ts.net (Funnel on)
|-- /mo/sharing proxy http://127.0.0.1:5080/mo/sharing
|-- /synofoto/api/v2/p proxy http://127.0.0.1:5080/synofoto/api/v2/p
スマホのモバイル回線から共有リンクを開くと、アルバムが表示されました。(下記はPCから開いた時のスクショですが…)

使ってみて
スマホのモバイル回線で、同じアルバムを両方で開いて比べたところ、Cloudflareのほうが少しスムーズに表示されました。Tailscaleは体感的にはやや遅いかなと思いましたが、十分と判断しました。(数値を測ったわけではなく、あくまで体感)
| Cloudflare Tunnel | Tailscale Funnel | |
|---|---|---|
| URL | 自分のドメイン | ○○○.ts.net |
| 準備 | ドメインが必要 | ドメイン不要 |
| 絞り込み | WAF のルール | --set-path のコマンド |
| アクセスの様子 | 解析画面で見られる | ほとんど見えない |
| 体感 | 少しスムーズ | 十分実用的 |
自分がTailscaleを選んだ理由は、URLに自分のドメインを出したくなかったからです。Cloudflareを使うと、URLにドメイン名が出ます。購入した別のドメインを使う手もありますが、そこまではしたくないなと思ったのです。
逆に、友人が何回見たか、不審なアクセスがないかを知りたいなら、Cloudflareのほうが向いています。Tailscale Funnelには、アクセスのログを見る機能がないので、管理には向いてないと思います。
共有するときに気をつけた方がいいこと
共有リンクは、IDを知っている人なら誰でも開けます。そこで、人に共有するリンクにはパスワードと有効期限をつけるようにした方がいいですね。使い終わった共有は、こまめにオフにします。

DSMのアカウントには、強いパスワードと2段階認証をかけて自動ブロックも有効にしています。ただし、CloudflareやTailscaleを経由した通信は、NASから見るとNAS自身から来たように見えるので、外の不審な相手のIPを自動ブロックで止める効果はあまり期待できません。ログイン画面を外から見えなくしておくことが、いちばんの防御だと思っています。
以前、自宅のネットワークの監視にPi-holeを入れましたが、これは外から入ってくるアクセスの検知には使えませんでした。Pi-holeが見られるのは、自宅の機器が外へ出ていくDNSの問い合わせだけです。
おわりに
NASの写真や動画をポートを開けずに友人へ共有&ある程度スムーズに閲覧してもらえるようになりました。今後運用していって、何か問題が発生したらまた報告したいと思います。
同じようにNASで写真を共有したい人の参考になればと思います!
かしこ
Chiro Lab