外出先から自宅のNASの状態を見たい。Home Assistantで戻る前に空調を入れたい。ミニPCの様子を確認したい。家庭ラボを動かしていると、こうした「外から触りたい対象」は自然に増えていきます。
そのとき最初に思いつくのが、ルーターで必要なサービスのポートを開ける方法です。手早く届くようにはなりますが、サービスを増やすたびに公開する穴が増え、更新責任と認証設定が散らばっていきます。便利に全部へ届く状態と、公開範囲を管理できている状態は、別のものです。
この記事は「外から接続できること」を目的にしません。外部から家庭内へ入る入口をいくつ持つか、どのサービスを公開しないかを先に決めるための設計記事です。判断の根拠として、ポート開放・自宅VPN・メッシュVPN・認証付きトンネルの4方式を、使い捨ての検証用VM内のDockerで再現し、実際に測った結果を示します。うまく取れなかった測定も、隠さずそのまま書きます。
なぜ入口を「一つに絞る」を先に考えるのか
外部アクセスの設計で見るべきは、速度や便利さよりも次の点です。
- 外から見える公開リスナー(待ち受けポート)が増えるか
- そこに認証がかかっているか
- 管理画面そのものを外へ出さずに済むか
- 障害や違和感があったとき、どの操作で入口を止められるか
ポートをサービスごとに開けると、止めるべき場所も増えます。入口を一つに絞れていれば、止める操作も一つで済みます。公的なネットワーク機器のセキュリティ指針でも、不要な公開面を減らすことが基本に置かれています。今回はこの観点を、6つの軸で横並びに測りました。
検証環境
使い捨ての検証用VM上のDockerで、内部ネットワークと外部ネットワークを分けて再現しました。
- Docker Engine 29.6.0 / Docker Compose v5.2.0
- カーネル 6.1.0-49-cloud-amd64
- 隔離ネットワーク2面: 内部網(labnet-internal)と外部網(labnet-external)
- 役割コンテナ3つ: 管理画面役(ダミーHTTPで
admin-panel-dummyを返す)、内部クライアント役、外部クライアント役 - 観測日時: 2026-06-25 UTC
環境の基準を記録したコマンドと出力です。
# docker version && docker compose version && uname -r && date -u
Docker Engine - Community Version: 29.6.0 (linux/amd64) Docker Compose version v5.2.0 6.1.0-49-cloud-amd64 Thu Jun 25 15:03:14 UTC 2026
「外から触れるか」は、外部クライアント役のコンテナから管理画面役へ到達できるかで測ります。
実行コマンドと結果
基準づくり
管理画面役を内部網だけにつなぎ、外部役は外部網に置いて開始します。
# docker network create labnet-internal
# docker network create labnet-external
# docker run -d --name svc --network labnet-internal python:3-slim \
sh -c 'mkdir -p /w && printf admin-panel-dummy > /w/index.html && cd /w && python3 -m http.server 18080'
# docker run -d --name cli-ext --network labnet-external python:3-slim sleep infinity
方式A: ポート開放相当
管理画面役を外部網にも接続し、外から直接届く状態を作りました。
# docker network connect labnet-external svc
# docker exec cli-ext python3 -c "import urllib.request; print(urllib.request.urlopen('http://svc:18080',timeout=5).read())"
b'admin-panel-dummy'
外部役から admin-panel-dummy が返り、外部到達(設定項目)を確認できました。届くようになるのと引き換えに、外から見える待ち受けが増え、管理画面はそのまま露出します。
方式B: 自宅VPN相当(WireGuard)
# apt-get install -y wireguard-tools
# wg genkey | tee server.key | wg pubkey > server.pub
# ip link add wg0 type wireguard
WireGuardの鍵を生成し、オーバーレイ用インタフェース wg0 を作成しました。端末追加の手数は「鍵生成1 + 設定配布1」。重要なのは、外側に見える対象ポートを増やさずに、鍵を持つ経路だけで届くようにできる点です。公開リスナーは増えませんでした。
方式C: メッシュVPN相当(オーバーレイにピア追加)
# wg genkey | tee peer2.key | wg pubkey > peer2.pub
# wg show
interface: wg0
2台目のピア鍵を追加し、インタフェースを確認しました。メッシュは「ピアを足す」操作が中心で、追加の手数が少ないのが特徴です。ここでも公開IF側の対象ポートは増えませんでした。なお、TailscaleなどはVPNを張らずに済む使い勝手が利点ですが、外部アカウントと資格情報が必要なため、今回はWireGuardベースで原理を代替検証する範囲に留めています。
方式D: 認証付きトンネル相当
内部網の管理画面役の前に認証ゲートを置き、トークンが一致したときだけ中継する構成を作りました。狙いは「オリジン(管理画面)のポートは外へ出さず、認証を通った要求だけ通す」状態です。ゲート用コンテナの起動と外部網への接続までは行えましたが、認証あり/なしの到達テストはコマンド側の不備で取得できませんでした(後述)。
6軸の比較表
| 方式 | 公開リスナー | 認証 | 端末追加の手数 | 停止操作 | 管理画面を隠せるか | 家族利用との相性 |
|---|---|---|---|---|---|---|
| A: ポート開放 | 増える | なし | ルーター設定1 | ポートを閉じる | 不可 | 多くなりがち |
| B: VPN(WireGuard) | 増えない | 鍵/トンネル | 鍵生成1+配布1 | wgを落とす | 可 | 中 |
| C: メッシュVPN | 増えない | 鍵/トンネル | ピア追加(少手数) | ノード離脱 | 可 | 少なくできる |
| D: 認証付きトンネル | オリジン非公開 | 必須 | 前置設定1 | トンネル停止 | 可 | 少なくできる |
後始末
# docker rm -f svc cli-int cli-ext gate
# docker network rm labnet-internal labnet-external
# docker ps -a
全コンテナとネットワークを削除し、待ち受けが基準状態(SSHとローカルのDNS系のみ)へ戻ったこと、残存ゼロを確認しました。
失敗・制約・再現条件
成果と同じくらい、取れなかった測定が判断には大事なので残します。
- 基準状態の「外部到達なし」測定は、Pythonワンライナー内の改行エスケープが壊れて構文エラーになり、取得できませんでした。
- 方式A撤去後の「公開面が元に戻ったか」の確認も、同じエスケープ不備で取得できていません(切断操作自体は実行済み)。
- 方式Dの「認証なしは拒否・認証ありは通る」の到達確認も、同種の不備で未取得です。構成は作れましたが、効果の数値は今回示せません。
- 方式CとDは、TailscaleやCloudflare Tunnelの実サービスではなく、外部資格情報を要さない範囲で原理を再現した代替検証です。実サービス特有の使い勝手は別途検証が要ります。
- 再現するには、同じ検証用VM+Docker構成で同手順を流せば足ります。ワンライナーは複数行スクリプトに置き換えると失敗を避けられます。
結論: どれを入口にし、何を外へ出さないか
実測の範囲で言えることはこうです。
- ポート開放は外から見える待ち受けが増え、管理画面を隠せません。届くことは確認できましたが、常用の入口には向きません。一時的・単発の用途に限るのが無難です。
- 入口を絞るなら、まずVPNかメッシュVPNです。どちらも公開IFに対象ポートを足さず、鍵を持つ経路だけに届くことを確認できました。単一端末ならVPN、複数端末や家族の利用が絡むならピア追加の手数が少ないメッシュが扱いやすい傾向です。
- Web系を限定的に公開したい場合は認証付きトンネルが候補になりますが、今回は認証の効きを数値で確認できていません。採用前に、認証なしが拒否されることを自分の環境で必ず確かめてください。
外から触れる対象を増やす前に、公開しない管理画面を決め、入口を一つに寄せる。止めたいときに一つの操作で止められる状態を、便利さより先に作る。これが今回の検証から読み取れる、現実的な順序です。
この検証を回している環境
この検証は、自宅の常設ラボ(使い捨てVM/LXCを回す母艦+GPU+VLAN分離ネットワーク)で動かしています。使っている機材と選定理由、全体構成は1本にまとめています。
ラボ構成のまとめを見る →