2026/04/11

はじめに

自宅の古いノートPCにUbuntu Serverをインストールし、Cloudflare Tunnelを使って外出先からSSH接続・GitLab・パスワード管理(Vaultwarden)・ルーター管理画面にアクセスできるインフラを構築しました。

きっかけは、月額数千円のVPS(ConoHa)で運用していたGitLabのコスト削減です。「自宅に余っているPCがあるなら、そこで動かせばVPS代がゼロになるのでは?」と考え、実際にやってみたところ、VPSより表示速度が速く、月額費用は電気代の数百円だけという結果になりました。

当社はMicrosoftパートナーとしてクラウドインフラの構築を支援しており、今回のようなハイブリッド構成(クラウド+オンプレミス)の知見を日々蓄積しています。

前提知識: この記事ではLinuxの基本操作(SSH接続、コマンドライン)、Dockerの基礎知識、Cloudflareのアカウント作成・ドメイン登録が完了していることを前提としています。

なぜCloudflare Tunnelを選んだのか

  • ポート開放が不要 — 自宅ルーターの設定を変えずに外部公開できる。セキュリティリスクを最小限に抑えられる
  • 無料プランで十分 — Cloudflare Tunnelは無料。VPN(WireGuard等)だとルーターのポート開放やDDNSが必要になる
  • CDNの恩恵 — 静的ファイルがCloudflareのエッジにキャッシュされるため、動的コンテンツ以外はVPSより高速
  • SSL証明書の自動管理 — Let’s Encryptの設定不要。CloudflareがHTTPSを担保

構成図

[外出先のPC/スマホ]
    |
    | HTTPS / SSH
    v
[Cloudflare Edge(東京)]  ← ここで認証・WAF・DDoS保護
    |
    | Cloudflare Tunnel(QUIC暗号化・アウトバウンド接続のみ)
    |
====|======= 自宅ネットワーク(ポート開放なし)==========
    |
    v
[自宅サーバー(Ubuntu 24.04)]
    |
    |--- SSH(localhost:22)
    |--- GitLab CE(localhost:8929)
    |--- Vaultwarden(localhost:8222)
    |--- nginx(localhost:8888)→ ルーター(192.168.x.x)
    |
    ※ すべてlocalhostでlistenしており、
      Cloudflare Tunnel経由でのみ外部からアクセス可能。
      サーバー自体のポートはインターネットに公開されていない。

やったこと

1. Ubuntu Serverのインストール

自宅に余っていたノートPC(Intel i7-7600U / 16GB RAM / 512GB SSD)にUbuntu Server 24.04.2 LTSをインストールしました。GUIは不要なのでサーバー版を選択。インストール時にOpenSSH Serverにチェックを入れておきます。

ノートPCなので、蓋を閉じてもスリープしないように設定します。

# /etc/systemd/logind.conf を編集
HandleLidSwitch=ignore

# 反映
sudo systemctl restart systemd-logind

2. cloudflaredのインストール

Cloudflare Tunnel公式ドキュメントに従って、cloudflaredをインストールします。

# debパッケージをダウンロードしてインストール
curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared.deb

# Cloudflareアカウントにログイン
cloudflared tunnel login

ブラウザが開くのでCloudflareアカウントにログインし、対象ドメインを選択します。認証が完了すると証明書が自動保存されます。

3. トンネルの作成とDNS設定

# トンネル作成
cloudflared tunnel create my-tunnel

# DNSレコードを追加(サブドメインごとに)
cloudflared tunnel route dns my-tunnel ssh.example.com
cloudflared tunnel route dns my-tunnel git.example.com
cloudflared tunnel route dns my-tunnel vault.example.com

注意: Cloudflareの無料プランでは、SSL証明書が *.example.com までしかカバーされません。ssh.sub.example.com のような2階層のサブドメインはTLSエラーになります。ssh-sub.example.com のようにハイフンで繋ぐのがポイントです。

4. 設定ファイルの作成

/etc/cloudflared/config.yml にトンネルの設定を記述します。

tunnel: <トンネルID>
credentials-file: /etc/cloudflared/<トンネルID>.json

ingress:
  - hostname: ssh.example.com
    service: tcp://localhost:22
  - hostname: git.example.com
    service: http://localhost:8929
  - hostname: vault.example.com
    service: http://localhost:8222
  - hostname: router.example.com
    service: http://localhost:8888
  - service: http_status:404

各ホスト名に対して、ローカルのどのポートに転送するかを定義します。最後の http_status:404 は、定義されていないホスト名へのリクエストに404を返すキャッチオール設定です。

5. サービスとして登録

# systemdサービスとして登録・起動
sudo cloudflared service install
sudo systemctl start cloudflared
sudo systemctl enable cloudflared

これでサーバーが再起動してもトンネルが自動的に復旧します。

6. SSH接続の設定

クライアント側(Mac)の ~/.ssh/config に以下を追加します。Cloudflare SSH接続のドキュメントも参考にしてください。

Host myserver
  HostName localhost
  Port 2222
  User myuser
  ProxyCommand cloudflared access tcp --hostname ssh.example.com --id <client-id> --secret <client-secret>

これで ssh myserver だけで、外出先からでもCloudflare Tunnel経由で自宅サーバーにSSH接続できます。

7. GitLabの移行

ConoHa VPSで動いていたGitLab(Docker)を自宅サーバーに移行しました。

# 旧サーバーでフルバックアップ
docker exec gitlab gitlab-backup create

# 設定ファイルもバックアップ
docker exec gitlab tar -czf /var/opt/gitlab/backups/gitlab-config-backup.tar.gz /etc/gitlab

# 新サーバーにDocker Composeで起動
docker compose up -d

# バックアップをリストア
docker exec gitlab gitlab-ctl stop puma
docker exec gitlab gitlab-ctl stop sidekiq
docker exec gitlab gitlab-backup restore BACKUP=<タイムスタンプ> force=yes
docker restart gitlab

移行後、Cloudflare Tunnelの config.yml にGitLab用のingressを追加するだけで、git.example.com でアクセス可能になりました。

8. Vaultwarden(パスワード管理)の構築

VaultwardenはBitwarden互換のパスワードマネージャーで、Dockerで簡単に立てられます。

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: always
    volumes:
      - /srv/vaultwarden/data:/data
    ports:
      - "8222:80"
    environment:
      - SIGNUPS_ALLOWED=false
      - DOMAIN=https://vault.example.com

Bitwarden公式のブラウザ拡張・モバイルアプリがそのまま使え、自動入力も可能です。データは自宅サーバーに保存されるため、外部サービスにパスワードを預ける必要がありません。

9. ルーター管理画面のリモートアクセス

ルーター(NEC Aterm WG1200HS4)はSSH非対応のため、Web管理画面にnginxリバースプロキシ経由でアクセスする構成にしました。

server {
    listen 8888;
    location / {
        proxy_pass http://192.168.10.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_cookie_domain ~.* $host;
        proxy_buffering off;
        proxy_http_version 1.1;
    }
}

最初はPythonの簡易プロキシで試しましたが、Cookie/セッション管理が不十分でログインが維持されませんでした。認証が絡むWeb管理画面にはnginxが必要です。

なお、ルーター管理画面はCloudflare Tunnel経由でのみアクセスできる構成です。ルーターのポート開放は一切していないため、トンネルが停止していれば外部からルーター管理画面に到達する手段はありません。自宅LANに物理的に接続しない限りアクセスできないため、セキュリティ上の懸念はありません。

つまったところ

サブドメインの階層でTLSエラー

最初 ssh.sub.example.com のように2階層のサブドメインで設定したところ、TLSハンドシェイクエラーが発生しました。

原因は、Cloudflareの無料プランのSSL証明書が *.example.com(1階層)までしかカバーしないことです。ssh-sub.example.com のようにハイフンで繋ぐことで解決しました。

CloudflareのCSPヘッダーがWebアプリをブロック

Cloudflareのセキュリティヘッダー(Content-Security-Policy)をゾーン全体に適用していたため、VaultwardenやGitLabのJavaScriptがブロックされ、画面が正常に動作しませんでした。

Cloudflare APIでSecurity Headersのルールに除外条件を追加して解決しました。

expression: (not http.host eq "vault.example.com" and not http.host eq "git.example.com")

VPSからの移行時にfail2banでSSH接続不能

ConoHa VPSからバックアップを取得する際、fail2banが89個のIPをbanしており、iptablesルールが肥大化してSSH接続がタイムアウトしました。fail2banを削除し、鍵認証のみの運用に切り替えることで解決しました。

コスト・性能比較

VPS(ConoHa 12GB)自宅サーバー + Cloudflare Tunnel
月額約8,000円電気代 数百円
CPU6コア(共用)i7-7600U 4コア(専有)
メモリ12GB(共用)16GB(専有)
ストレージ512GB SSD512GB SSD
GitLab表示速度平均0.33秒平均0.24秒
SSH遅延約50ms約750ms(Tunnel経由)
安定性99.99%停電で落ちる

表示速度はVPSより27%高速でした。Cloudflare TunnelのCDN効果と、共用ではないリソース専有が効いています。

※ 表示速度はcurlのレスポンスタイム(各3回計測の平均)、SSH遅延はSSH接続〜コマンド応答までの往復時間(5回計測の平均)で測定。自宅サーバーのSSH遅延はCloudflare Tunnel経由(東京エッジ経由)のため、直接接続よりオーバーヘッドがあります。通常のSSH操作には十分な速度です。

セキュリティ比較

観点VPS自宅サーバー + Cloudflare Tunnel
ポート露出SSH(22)・HTTP(80)・HTTPS(443)がインターネットに直接公開ポート開放なし。外部からサーバーのIPに直接アクセスできない
SSH総当たり攻撃常時攻撃を受ける(fail2banで89IPがbanされていた)SSHポートが公開されていないため攻撃自体が到達しない
DDoS対策自前またはホスティング会社依存Cloudflareが前段で吸収
通信の暗号化自分でSSL証明書を管理Cloudflareが自動管理(証明書の更新忘れなし)
WAF(Web Application Firewall)自分で構築が必要Cloudflare WAFが無料で適用
アクセス制御iptables / fail2ban等で自前管理Cloudflare Access(Service Token / メール認証)でゼロトラスト
サーバーのIPアドレス公開される非公開(Cloudflareが中継するため外部からIP特定不可)
物理的なデータ管理データセンターに預ける自分の手元にデータがある
脆弱性スキャン直接スキャンされるCloudflareが前段にいるため直接スキャン不可

意外かもしれませんが、自宅サーバー+Cloudflare Tunnelの方がVPSよりセキュアです。VPSはIPアドレスとポートがインターネットに露出しているため、常にSSH総当たり攻撃やポートスキャンの対象になります。実際、今回移行したVPSではfail2banが89個のIPをbanしていました

一方、Cloudflare Tunnel構成ではサーバー側から外向きにトンネルを張るだけで、インバウンドのポートを一切開けません。外部からサーバーのIPアドレスすら見えないため、攻撃の対象にすらなりません。さらにCloudflareのWAF・DDoS保護・SSL管理が無料で適用されます。

唯一VPSが勝るのは物理的な安定性(停電・回線障害のリスク)とSSH遅延(直接接続 vs Tunnel経由)です。ただし開発ツールやパスワード管理のように「落ちても数時間なら許容できる」用途であれば、セキュリティの優位性のほうが大きいと言えます。

まとめ

  • 自宅の余ったPCでVPS代を月額0円に削減できた
  • Cloudflare Tunnelならポート開放不要でセキュリティリスクが低い
  • GitLabの表示速度はVPSより速かった(CDN効果+リソース専有)
  • SSH・GitLab・パスワード管理・ルーター管理を1台のPCに集約
  • 本番サイトはクラウド、開発・管理ツールは自宅サーバーという使い分けがベスト

インフラ構築・コスト削減のご相談

「自社でもやってみたいけど、構築や運用に不安がある」「どこまで自前でやるべきか判断が難しい」という方は、ぜひご相談ください。

株式会社ビギニングは、クラウドとオンプレミスを組み合わせたハイブリッドインフラの構築を支援しています。

  • VPSやクラウドのコストを削減したい
  • 社内にGitLabやパスワード管理ツールを導入したい
  • Cloudflare Tunnelで安全にリモートアクセスできる環境を作りたい

お気軽にご相談ください。

お問い合わせはこちら