結論:自宅 NAS 上に Claude Code 専用サンドボックスを作ると、出張先からでも「フル権限の AI コーディング環境」を呼び出せます
私(yamakashi)は UGREEN DXP2800 という 2 ベイ NAS の上に、Tailscale VPN からしか到達できない Claude Code 専用の Docker サンドボックスを構築しました。出先のノート PC・自宅 Mac・スマホから同じコンテナに入って作業できます。Claude Code は --dangerously-skip-permissions のフル権限で動かしますが、影響範囲はコンテナと NAS シェアフォルダ内に限定され、母艦の Windows / Mac を巻き込みません。ルーターのポート開放はゼロです。本記事では、ネットワーク設計・Tailscale ACL の順序・ハマった失敗・完成後のアクセス経路を 1 本にまとめています。
なお、フル権限運用は隔離してもリスクをゼロにはできません(Anthropic 公式も「いかなるシステムも全ての攻撃を完全に防げるわけではない」と明記)。本記事の手順は自己責任・信頼できるリポジトリ前提でお試しください。検証環境は Claude Code v2.1 系(2026 年 7 月時点)/UGOS Pro/node:20-slim。フラグ名や挙動は Claude Code のバージョンで変わる可能性があります。
1. なぜ自宅 PC ではなく NAS に Claude Code を置いたのか
もともと私は、自宅 Windows 11 デスクトップの WSL(Ubuntu)で claude --dangerously-skip-permissions を動かしていました。気持ちが揺らいだのは、出張中に「自宅でやりかけのリポジトリを少しだけ触りたい」と思った瞬間です。ノート PC に同じ環境を作っても、プロジェクトファイルは自宅のデスクトップに置きっぱなしで、コミット前の作業や検証用フォルダは持ち出せません。
もう 1 つ気になっていたのが、--dangerously-skip-permissions のリスクです。確認なしにファイル操作やコマンド実行が走るため、Web から拾ったサンプルコードをフル権限のセッションで実行すれば母艦の WSL 環境を壊しかねません。母艦のファイルシステムから切り離すほうが筋がいい、と感じていました。
私が「NAS にサンドボックスを置く」と決めた 3 つの理由
① 家でも出先でも同じ環境にアクセスしたい。
② フル権限 Claude Code の影響範囲を母艦 OS から切り離したい。
③ NAS は常時稼働しているので、開発サーバとして遊ばせない手はない。
VPS を借りる選択肢もありましたが、ソースコードと検証データを外部に常時置きたくないのと、月額コストを増やしたくないのが決め手でした。
2. 全体構成の俯瞰:Tailscale と Docker をどう組み合わせたか
クライアントから NAS のコンテナまで、通信はこの順で流れます。
[ Win11 PC / Mac / スマホ / 他PC ]
↓ Tailscale VPN(WireGuard、tag:client のデバイスだけ)
[ Tailscale Tailnet(100.x.x.x プライベートIP空間)]
↓
[ DXP2800 NAS ]
├─ ts-sandbox コンテナ(Tailscale 本体、ネット入口)
└─ claude-workspace コンテナ
└ network_mode: service:tailscale(ポート非公開)
├─ /workspace ← /volume1/sandbox/projects(bind mount)
└─ Docker volume × 5(Claude設定 / gh / git / secrets / ssh)
2 つのコンテナを Docker Compose で動かしています。Tailscale 本体だけが入った軽量な ts-sandbox と、Claude Code・GitHub CLI・OpenSSH サーバ・ビルドツールを詰めた claude-workspace です。両者を network_mode: "service:tailscale" でつなぎ、claude-workspace 側は tailscale コンテナとネットワーク名前空間を共有し、ポートを publish しない構成にしています。
この設計の旨味は「LAN からの直接 SSH の入口を作らない」点です(ポートを publish しない限り、の前提つき)。普通に Docker でポートをマッピングする方式だと NAS の LAN IP に 22 番が開いて家の Wi-Fi 内から見つけられる余地が残ります。一方、Tailscale コンテナへの相乗り構成でポートを publish しなければ、コンテナの 22 番は Tailnet 上の仮想 IP と NAS 本体(同じブリッジ内)からしか届きません。Tailscale を持っていないデバイスからは存在自体が見えない、という遮断層になります。
永続化も最初から意識しました。プロジェクト本体は NAS シェアフォルダ /volume1/sandbox/projects/ に置いてコンテナ内 /workspace/ に bind mount。コンテナを作り直しても作業ファイルは消えず、Windows のエクスプローラから SMB 経由で覗けます。Claude 設定・gh 認証・SSH 公開鍵・シークレットは Docker ボリュームに分けました。
3. 主要な設計判断 5 つ
5 つの設計判断(要点)
① Tailscale はサブネットルーター化しない:NAS 全体ではなくコンテナだけを Tailnet に出すシンプル構成。権限が広がりすぎず、ファイアウォール設計の難易度が抑えられる。
② network_mode: "service:tailscale" で相乗り:claude-workspace は tailscale コンテナのネットワーク名前空間を共有し、ポートを publish しない。LAN の他端末からは到達できず(NAS 本体や同じ Docker ブリッジ上のコンテナからは到達可)、外からの入口は Tailscale 経由だけになる。
③ アクセス制御は Tailscale ACL の tag ベース:tag:sandbox(NAS)と tag:client(手元クライアント)を定義し、「tag:client だけが tag:sandbox に SSH できる」とした。新しいクライアントは tag を付けるだけ。
④ outbound 通信はあえてフリー:npm install や pip install が普通に動かないと開発環境として成立しないため、外向き通信は絞らない。リスクは後述の運用ルールでカバーする。
⑤ SSH は Tailscale SSH ではなく OpenSSH + 公開鍵:相乗り構成だと Tailscale SSH は failed to look up local user で通らない(理由は 5-4)。素直に OpenSSH を立て、認証は公開鍵に任せた。
④ を選んだ時点で「フル権限の Claude Code が外部に何かを持ち出す経路が技術的にはある」状態になります。設計だけでは塞ぎきれないので、私は 3 つの運用ルールでカバーしています。API キーなどのシークレットは ~/.secrets(パーミッション 700)に隔離してプロジェクト配下に置かない、AI に触らせるコードは /workspace/trusted/ に限定する、消えたら困る成果物は毎日 GitHub へ git push して二重化する、の 3 点です。
4. 構築プロセスのハイライト:うまくいった所
全手順を書くと相当な分量になるので、ここでは「うまくハマった」要点だけ抜粋します。
4-1. 「永続化すべきもの」を最初に紙へ書き出した
これが一番効きました。プロジェクト本体、Claude 設定、gh 認証、Git 設定、シークレット(700)、SSH 鍵、Tailscale ステート。先に洗い出してから docker-compose.yml に落としたので、手戻りが小さく済みました。とくに SSH 公開鍵(authorized_keys)はコンテナ再ビルドで消えやすい要注意ポイントです。~/.ssh ディレクトリごと named volume に載せ、パーミッションを 700 に固定しておくと、イメージを作り直しても鍵の登録をやり直さずに済みます。
4-2. Compose のコアは「相乗り」と「ヘルスチェック」
Compose で重要なのは 2 か所。claude-workspace 側の network_mode: "service:tailscale" と、depends_on の condition: service_healthy + Tailscale 側の healthcheck(tailscale status をプローブにする)のセットです。後者がないと Tailscale のセッション確立前に sshd が起動し、再起動直後だけ SSH が拒否されます。
4-3. ベースイメージは node:20-slim(UID 1000 重複に注意)
Claude Code は 2026 年以降ネイティブインストーラが既定ですが、コンテナでバージョンを固定したいなら公式 devcontainer でも使われる npm install -g @anthropic-ai/claude-code が確実で、node:20-slim ベースが素直に使えます。ただしこのイメージには既に UID 1000 の node ユーザーがあるので、Dockerfile の冒頭で userdel -r node してから自分のユーザーを作っています。
※ 補足(2026 年 7 月時点):Node.js 20 は 2026 年 4 月に EOL を迎えました。これから新しく構築するなら node:22-slim など現行 LTS ベースへ置き換えてください(手順・考え方はそのまま使えます)。
4-4. Tailscale ACL は新しい grants 文法
ACL を書かないと「同じアカウントの全デバイスが互いに自由に通信できる」状態のままなので、ここは最初に整えます。Web 上の解説は古い acls 文法のものが多いのですが、私のテナントは新しい grants 文法(Tailscale 公式 Docs「Grants」)が初期値で、旧形式で書くと Admin Console の Save がエラーで弾かれました(2026 年 5 月時点。テナントによって受け付ける文法が違うようです)。Admin Console → Access controls に貼っている中身はこれだけです。
{
"tagOwners": {
"tag:sandbox": ["autogroup:admin"],
"tag:client": ["autogroup:admin"]
},
"grants": [
// 保険:管理者は全デバイスへ(ACL ミスの締め出し防止)
{ "src": ["autogroup:admin"], "dst": ["*"], "ip": ["*"] },
// 本命:tag:client → tag:sandbox のみ許可
{ "src": ["tag:client"], "dst": ["tag:sandbox"], "ip": ["*"] }
]
}
tagOwners が「tag を誰が付与してよいか」、grants が「src から dst への通信を許可する」ルールです。この 2 行で守れる範囲は思ったより大きく、家族と Tailnet を共有していても、過去に作ったままのデバイスが残っていても、tag:client が付いていなければ sandbox には到達できません。クライアント PC が乗っ取られたかもと疑ったときも、tag:client を外すだけで切り離せます。
5. ハマって学んだ 5 エピソード
うまくいった話だけだと楽勝に見えるので、特に学びが大きかった 5 つを抜粋します。
5-1. Docker グループの「再ログイン忘れ」
UGOS Pro 上で Docker を入れた直後に docker compose up を叩くと permission denied while trying to connect to the Docker daemon socket が出ます。sudo usermod -aG docker $(whoami) はDocker 公式の手順どおりですが、ログアウトと再ログインを挟まないと反映されないのがトラップでした。以来、最初に docker ps を sudo なしで叩いて確かめるのが鉄則になりました。
5-2. Tailscale ACL を書く前に Auth Key を発行した
私は最初に Auth Key を発行しようとしたのですが、その時点では発行画面の tag チェックボックスがグレーアウトしていて選べず、tag なしのまま起動しました。結果、ts-sandbox コンテナのログに requested tags [tag:sandbox] are invalid or not permitted が出続け、ヘルスチェックが unhealthy のまま止まります。原因は、ACL の tagOwners に tag:sandbox を登録していないと、Auth Key 発行画面で tag を選べない仕様だからです。正しい順序はこの 4 ステップです。
- ACL を書く(
tagOwnersにtag:sandboxとtag:client、grantsでtag:client → tag:sandbox) - クライアント端末に
tag:clientを付与(Admin Console → Machines) - Auth Key を発行(Tags で
tag:sandboxにチェック、Reusable: ON / Ephemeral: OFF) - Auth Key を
.envに書いてdocker compose up -d --build
Tailscale 関連は「ACL ファースト」が時短のコツです。
5-3. TS_EXTRA_ARGS を変えたら --reset を求められて起動しない
最初は TS_EXTRA_ARGS=--ssh --advertise-tags=tag:sandbox で動かしていて、Tailscale SSH を使わない方針に変えて --ssh を外したところ、tailscale コンテナが起動しなくなりました。
tailscale up failed: changing settings via 'tailscale up' requires mentioning
all non-default flags. To proceed, use --reset.
これは「前回起動時に指定したフラグが今回省略されていると、意図しない設定変更を防ぐために起動を止める」という Tailscale 側の安全機構です。対処は、一度だけ TS_EXTRA_ARGS=--reset --advertise-tags=tag:sandbox で起動し、成功を確認したら --reset を外して通常運用に戻すだけ。付けっぱなしにすると毎起動で state を巻き戻すので、外し忘れに注意してください。私は気付かないまま何度も再起動して時間を溶かしました。
5-4. Tailscale SSH で failed to look up local user エラーの原因と対処
症状:tailscale ssh を有効にして接続すると failed to look up local user が返り、ログインできない。
原因:network_mode: "service:tailscale" の相乗り構成では、Tailscale 本体コンテナ(ts-sandbox)側に claude-workspace のユーザーが存在しないため、Tailscale SSH がローカルユーザーを解決できない。
解決:Tailscale SSH をあきらめ、claude-workspace に OpenSSH サーバを立てて公開鍵認証に任せる(設計判断⑤)。単独 NIC 構成に組み替えれば Tailscale SSH も使えますが、ポートを publish しないという設計利益を捨てることになるので、私は OpenSSH を選びました。
5-5. Claude Desktop の Code タブからだけ SSH が通らない
最終盤で厄介だったのが、Claude Desktop からの SSH 接続です。PowerShell の ssh では繋がるのに、Code タブからだけ Permission denied (publickey) が出る。原因は Claude Desktop が呼ぶ ssh(Git for Windows 同梱版)が passphrase を対話で聞こうとしていて、Code タブには答える入力欄がないことでした。ssh-keygen -t ed25519 で passphrase なしの鍵を作り直し、~/.ssh/config の IdentityFile でその鍵だけを使わせて解決。
ここまでのつまずきは、どれも「自分の機材の上に環境を作る」ゆえの手間です。同じ隔離環境をクラウド側に置く手もあり、ConoHa VPS はサーバー作成時のテンプレートとして Claude Code のスタートアップスクリプトを用意していると案内しています(利用には Anthropic 側の契約が別途必要。ソースコードを自宅の外に置く点は、私が NAS を選んだ理由の裏返しです)。
スタートアップスクリプトの内容・前提条件はConoHa 公式ドキュメント「Claude Code」を参照(2026 年 8 月 5 日確認)。料金・性能は当サイトでは検証していません。
6. 完成した環境でできるようになった 4 つのこと
構築が終わると、思った以上に多くの経路から同じ環境に入れるようになりました。日常的に使っている 4 経路です。
① VS Code Remote-SSH:Windows 11 PC から
~/.ssh/config の記述だけで 1 クリック接続。ターミナルもコンテナ内シェルに直結し、Claude Code を cc で呼びながら横で差分ビューを見るワークフロー。② Termius(スマホ):Android / iOS に同じ設定を入れて、出先で
tail -f や htop から進捗を確認。③ Mac の標準 SSH:
~/.ssh/config を同じ書き方にするだけ。標準 OpenSSH は ed25519 鍵を素直に扱うので設定即接続。④ Claude Desktop の Code タブ:保存済みの接続を選び、「フォルダを選択」で
/workspace/trusted/<プロジェクト名> を指定する。省くとホームがカレントになりシークレットの置き場所が見えるので、毎回明示している。
クライアントを増やすときも、Tailscale で tag:client を付けて公開鍵を authorized_keys に足すだけです。コンテナ側は何も変えずに増やせます。
7. 5か月運用してみての所感
2026 年 4 月から運用を始めて約 5 か月(2026 年 9 月時点)。使い心地と改善したい点を率直に書きます。
・出張先のホテルで普通に作業できる。回線が細くても SSH と Claude Code の応答は気にならない。
・母艦 PC の WSL を「サンドボックス兼用」から「実用環境専用」に戻せた。
・コンテナを作り直すのが怖くない。ボリュームを残せば認証も SSH 鍵も消えない。
・大規模な npm ビルドや重い処理は DXP2800 の CPU だとさすがに遅い。
・Tailscale のキー期限切れに気づくのが遅れがち。監視を入れたい。
・outbound フリーのままでよいか、半年後に見直す予定(Exit Node や iptables ホワイトリスト案)。
意外だったのは、「自宅 LAN 内にいるときも、わざわざ Tailscale 経由で繋ぐ」習慣がついたことです。入り口を 1 本に絞ると、運用の頭の使い方がシンプルになります。
8. これから NAS で Claude Code をやってみたい方へ
始める前のチェックリスト
① NAS の Docker が「sudo なし」で動くか確認:getent group docker でグループ所属を見て、docker ps が sudo 抜きで通るところまで先に整える。NAS 製品ごとに差が出る部分。
② Tailscale は ACL ファースト・tag 思想で組み立てる:最初の 1 時間で tagOwners と最低限の grants を書く。後から「子供のタブレットからは入れないように」といった要望にも対応できる。
③ 永続化すべきものを「先に紙に書く」:プロジェクト、Claude 設定、gh 認証、SSH 鍵、シークレット、Tailscale ステート。私は SSH 鍵を書き漏らして、鍵登録をやり直す羽目になりました。
NAS 本体をこれから選ぶ場合は、Docker が快適に動く x86 CPU 搭載機(DXP2800 や Synology DS225+ など)を選ぶのがポイントです。N100 などの x86 機なら Docker も Claude Code もそのまま動き、ARM 機の「対応イメージが無い」回り道を避けられます。予算帯ごとの候補は家庭用NASおすすめランキング10選で比較できます。
私が使っている実機は UGREEN DXP2800(Intel N100・8GB DDR5・M.2 NVMe ×2)です(実運用の所感は実機レビューへ)。M.2 スロットのある x86 2 ベイ機なら、将来 workspace や git を NVMe SSD に載せる拡張も選べます(当サイトでは未実施)。
DXP2800・DS225+ はどちらも HDD 別売なので、ドライブを一緒に用意しておくと届いた初日から動かせます。容量は 1 本なら 4TB か 8TB、RAID を組むなら同容量 2 本が基本です(選び方はNAS用HDDおすすめランキング)。私の DXP2800 は手持ちの WD Blue 4TB×2(PC 向け・RAID 1)で動かしていますが、これはPC 用 HDD を NAS で使うとどうなるかを検証するためで(経過はPC用HDDはNASに使える?)、WD 公式は Blue・Green・Black を 24 時間 365 日の RAID 用途には非推奨としています。常時稼働のサンドボックス用途なら、1 本目は次の WD Red Plus 4TB が定番です(当サイトの実機は前述の WD Blue で、Red Plus は未実測)。
9. よくある質問(FAQ)
docker グループの扱いや /dev/net/tun の有無は製品ごとに違うため、Tailscale コンテナ起動時の前提は機種ごとに確認が必要です。/workspace/trusted/ に置き、素性の分からないコードは /workspace/untrusted/ に隔離して Claude Code を起動しない、シークレットは ~/.secrets(700)に分離してプロジェクト配下に置かない、成果物は GitHub へ push して二重化する、の 3 点を守っています。Anthropic の公式ドキュメントも、--dangerously-skip-permissions はコンテナ等で隔離された環境での利用を前提としています(2026 年 6 月時点)。git push で二重化し、シークレット類はパスワードマネージャや別ディスクにも置いています。NAS の RAID は冗長性であってバックアップではない、というのは常に意識しています。
10. まとめ:NAS は Claude Code 専用サーバとして十分に化ける
・フル権限 Claude Code は、母艦 OS から切り離した NAS コンテナでやると気が楽
・Tailscale + Docker の 2 コンテナ構成(
network_mode: "service:tailscale")なら、ポートを publish しないので LAN の他端末からは届かない(NAS 本体・同ブリッジのコンテナからは到達可)・アクセス制御は Tailscale ACL の tag ベース、認証は OpenSSH 公開鍵に任せる役割分担
・Tailscale は「ACL → tag 付与 → Auth Key 発行 → 起動」の順。フラグを変えて起動しなくなったら
--reset を一度だけ・永続化リストは「先に紙に書く」。後付けは再ビルドのたびに痛い
・VS Code Remote-SSH / Termius / Mac / Claude Desktop の 4 経路から同じコンテナへ
NAS は写真や動画の倉庫としての印象が強い機器ですが、Docker と VPN を組み合わせると「常時稼働の自宅開発サーバ」に化けます。
なお本記事は UGREEN DXP2800(UGOS Pro)での個人運用例で、Tailscale・Docker・Claude Code の仕様や無料枠はバージョン改定で変わり得ます。設定の適用は、重要データのバックアップを取ったうえでご自身の責任で判断してください。
