nextcloud

{" resume resume "}

…lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla elementum, eros at sagittis facilisis, ante est rutrum ligula, at interdum eros sapien vel magna.

 

☁️ みーきゅんクラウド Nextcloudサービス設計書

引き継ぎ用 / 詳細版

1. サービス概要

Nextcloudは、みーきゅんクラウドにおける 顧客向けクラウドストレージ基盤 である。単なるファイル置き場ではなく、VPN、顧客ポータル、将来のOffice連携、ストレージ販売を束ねる中心サービスとして位置づける。

  • ファイルストレージ
  • WebDAV
  • モバイル同期
  • 将来のOffice/Collabora統合
  • 顧客ポータルとの連携
  • VPN利用者向けプライベートクラウド

2. 全体構成

User
 ↓ HTTPS / VPN
Portal / Reverse Proxy
 ↓
R640
 ↓ Docker
Nextcloud Container
 ↓ NFS
Supermicro Storage
 ↓
/srv/storage

“`

配置役割
EdgeVPS / 将来のReverse Proxy外部入口
ControlR640Nextcloudアプリ、ポータル、VPN
StorageSupermicro実データ保管
NetworkVLAN30NFS / Storage LAN

“`

3. 実行環境

項目内容
ホストR640
方式Docker
OSUbuntu
データ保存NFS マウント経由
バックエンドストレージSupermicro / LUKS / LVM / 約66TB

“`

想定コンテナ

コンテナ役割
nextcloudアプリ本体
nginx or apacheWeb配信
redisキャッシュ / ロック
mariadbDB

“`

4. データパス

Nextcloud
 ↓
/mnt/maguro/nextclouddata
 ↓ NFS mount
192.168.30.30:/nextclouddata
 ↓
Supermicro /srv/storage

“`

項目内容
NFS Export192.168.30.30:/nextclouddata
R640側マウント/mnt/maguro/nextclouddata
保存先実体Supermicro /srv/storage

重要: Nextcloud本体はR640、実データ本体はSupermicro。この役割分離が、みーきゅんクラウドの設計上の基本。

“`

5. ネットワーク設計

ネットワーク用途備考
VLAN10管理Nextcloud運用管理、SSH、OOB
VLAN20サービス本線R640の主通信
VLAN30ストレージNFS / 内部専用
VLAN50更新OS更新系

“`

Nextcloudデータ通信は VLAN30 を使う。管理・公開・更新・ストレージを分けることで、障害時の切り分けが容易になる。

“`

6. アクセス方式

“`

Web

https://cloud.mikyun.example

WebDAV

https://cloud.mikyun.example/remote.php/dav/files/

モバイル

  • Nextcloud App
  • WebDAVクライアント
  • VPN経由優先

“`

7. 顧客ポータルとの関係

Nextcloudは単体運用ではなく、顧客ポータルの一部として扱う。

“`

ポータル表示項目内容
ログイン情報Nextcloudユーザー名 / 接続先URL
容量契約容量 / 利用量
状態active / disabled など
将来機能パスワード再発行、クォータ変更反映

“`

8. セキュリティ設計

  • 通信: HTTPS
  • 内部データ通信: VLAN30
  • 保存データ: LUKS暗号化ストレージ
  • 入口: VPNまたはReverse Proxy
  • 管理操作: admin_logs / 将来 portal_logs で追跡

9. バックアップ対象

  • Nextcloud data
  • DB
  • 設定ファイル
  • reverse proxy設定
  • ポータルとの連携設定

“`

基本方針

borg backup
```

+
DB dump
+
設定退避

10. 将来拡張

  • Collabora / Office統合
  • Nextcloudユーザーの自動作成
  • ポータルからクォータ同期
  • オブジェクトストレージ化(将来Ceph)
  • VPS経由の外部公開最適化

🌐 顧客ポータル完全設計書

Nextcloud / WireGuard / 契約情報を束ねる統合UI

1. 目的

顧客ポータルは、みーきゅんクラウドにおける 顧客セルフ操作基盤 である。利用者はこの画面から、自分の契約、端末、VPN設定、Nextcloud情報を確認・操作する。

  • 契約状態確認
  • 親端末 / 子端末管理
  • WireGuard QR再発行
  • 一時停止 / 復帰
  • ストレージ利用状況確認
  • 将来の請求 / 通知 / パスワード管理

2. 設計思想

“`

セルフサービス

運営手動作業を減らし、顧客が自分で操作できる範囲を広げる。

Zero Trust

重要操作は再認証、親端末承認、場合により電話認証を組み合わせる。

親端末中心

契約の中心となる親端末を1台持ち、追加端末は子端末として扱う。

“`

3. システム構成

顧客
 ↓
Portal UI
 ↓
FastAPI
 ├ DB (mikyun_cloud)
 ├ WireGuard engine
 ├ QR生成
 ├ Config出力
 └ 将来 Nextcloud連携

“`

配置内容
ホストR640
実装FastAPI / uvicorn
主要コード/opt/mikyun-portal/app.py, /opt/mikyun-portal/app/main.py
内部エンジン/opt/mikyun-portal/mikyun_vpn_engine.py
補助発行スクリプト/opt/mikyun-admin/add_customer.sh, add_customer_full.sh

“`

4. 顧客モデル

“`

単位内容
契約1顧客 = 1契約。契約ID、容量、端末上限、帯域、VPNサブネットを持つ。
端末契約配下に複数端末を持つ。親端末1台 + 子端末複数。

契約状態

active / paused / terminated / deleted

端末状態

issued / active / paused / revoked / expired

“`

5. 親端末 / 子端末ルール

  • 親端末: 契約の中心端末。重要操作可能。
  • 子端末: 追加端末。利用はできるが重要操作不可。
  • 親端末紛失時: 電話認証 + 本人確認パスフレーズ + 管理者承認。
  • v_parent_conflicts により親端末重複を監査。

6. 主要機能

“`

顧客向け内容
契約確認契約状態、容量、端末数、プラン確認
端末一覧親 / 子、状態、最終接続、WG IP
端末追加子端末を新規発行
QR再表示WG設定再取得
一時停止 / 復帰端末単位制御
Nextcloud情報接続先・ユーザー名・容量(将来自動取得)
管理者向け内容
顧客作成契約作成 + 親端末初回発行
容量変更契約ストレージ上限変更
契約停止 / 解約状態変更
親端末昇格child → parent 切替
監査ログ閲覧admin_logs

“`

7. 生成物と保存場所

/opt/mikyun/output/client-configs
/opt/mikyun/output/qr

“`

発行物:

  • WireGuard .conf
  • QRコードPNG
  • 端末説明文(将来)

“`

8. Nextcloudとの連携方針

  • 契約に対してNextcloudユーザーを1:1で管理
  • ポータル画面にクォータ・使用量・URLを表示
  • 将来は契約作成時にNextcloudユーザー自動生成
  • 契約停止時にアカウント凍結も可能にする

9. 画面一覧

画面内容
顧客トップ契約状態、親端末、利用量、通知
端末管理端末一覧、追加、停止、QR再発行
ストレージNextcloud接続先、容量、使用量
管理者一覧顧客一覧、検索、状態変更
管理者詳細契約・端末・ログを統合表示

10. 顧客ポータル接続ポリシー(確定版)

10.1 親IP制

顧客ポータルへ接続できる端末は 親IP 1台のみ とする。

契約単位で以下の構造を持つ。

契約ID: A001

├ 親IP(Portalアクセス可能)
├ 子IP
└ 子IP

“`

親IPが利用できる機能

親IPのみ以下の機能を使用可能とする。

顧客ポータルログイン
```

契約情報確認
端末一覧表示
QR再発行申請
親端末変更
利用状況確認

“`

子IPの権限

子IPは以下のみ許可。

Nextcloud
```

WebDAV
VPN通信
サービス利用

“`

以下は 禁止

顧客ポータルアクセス
```

契約操作
QR再発行

10.2 親IPの初回発行

初回の親IP発行は 運営のみ実施可能

“`

操作場所

管理ポータル(wg0)

理由

顧客が初回親端末を自由に設定できると
```

乗っ取りリスクが発生するため

“`

フロー

顧客契約作成
 │
```

管理ポータル
│
親IP発行
│
QR発行

10.3 親端末の機種変更

親端末の移行は 既存の子IPからの格上げのみ 許可。

“`

現在
```

A001
├ 親IP  10.201.10.2
├ 子IP  10.201.10.3
└ 子IP  10.201.10.4

“`

顧客が子IP 10.201.10.3 を選択

結果

A001
```

├ 親IP  10.201.10.3
├ 子IP  10.201.10.2
└ 子IP  10.201.10.4

“`

つまり

新親 = 選択された子IP
```

旧親 = 自動降格

10.4 親移行の条件

通常の親移行には 現在の親端末の同意が必須

“`

操作フロー

親端末
```

│
顧客管理画面
│
子IP一覧表示
│
次の親を選択
│
親変更実行

“`

この操作は 親IPからのみ実行可能

つまり

子IPからは親変更不可

“`

10.5 親端末紛失時

親端末が紛失した場合のみ

運営による救済操作を行う。

救済操作は wg0 管理ポータルからのみ可能

“`

救済フロー

顧客
```

│
電話サポート
│
本人確認
│
管理画面(wg0)
│
親IP再設定
│
新QR発行

10.6 本人確認方式

親端末紛失時の救済には

本人確認パスフレーズを使用する。

登録時に顧客へ設定させる。

“`

本人確認パスフレーズ
```

例
・ペットの名前
・好きな食べ物
・秘密のキーワード

“`

電話認証時

顧客
```

↓
パスフレーズ回答
↓
一致
↓
親IP再設定

10.7 セキュリティ意図

この設計の目的

端末乗っ取り防止
ポータル乗っ取り防止
QR悪用防止
アカウント保護

“`

つまり

契約管理は常に1端末のみ

“`

システム内部ロジック(重要)

DBにはこのフラグを持たせます。

device_role

parent
child

“`

device_id
```

contract_id
wg_ip
device_role
created_at
last_seen

“`

親IP判定

ポータルアクセス時

if device_role != parent
access deny

親変更処理

BEGIN
```

old_parent → child
selected_child → parent

COMMIT

非常に良いポイント

この設計の強みは

QR盗難
端末乗っ取り
ログイン奪取

“`

をかなり防げます。

普通のVPNサービスは

ログインID
```

パスワード

“`

ですが

みーきゅんクラウドは

端末単位管理

です。

これは かなり強い設計です。

“`

次にやる候補

もしよければ次に

このシステムで一番重要な

「顧客IP管理テーブル(完全設計)」

を作ります。

“`

これができると

親IP
```

子IP
QR
契約
トラフィック

“`

全部のDBが確定します。

“`

📘 みーきゅんクラウド

顧客IP管理テーブル(完全設計)

🎯 目的

このテーブルは以下を一元管理する。

契約
親IP / 子IP
QR発行
端末状態
親変更
再発行
停止
失効
通信量

“`

つまり

顧客VPN管理の中核テーブル です。

“`

1. 基本思想

“`

1.1 契約単位

1契約 = 1顧客ID

A001
```

A002
A003

“`

1.2 端末単位

1契約に複数のWG IPを紐づける。

A001
```

├ 親IP
├ 子IP
└ 子IP

“`

1.3 親IP制

契約管理操作ができるのは 親IP 1台のみ

“`

2. テーブル名

おすすめ:

customer_devices

3. カラム設計

“`

3.1 必須カラム

カラム名意味
idBIGINT PKレコードID
contract_idVARCHAR(32)顧客契約ID
device_idVARCHAR(64)端末識別ID
wg_ifaceVARCHAR(32)利用WG IF名
wg_ipVARCHAR(64)割当IP
public_keyTEXTWireGuard公開鍵
preshared_keyTEXT NULLPSK
device_roleVARCHAR(16)parent / child
statusVARCHAR(16)issued/active/paused/revoked/expired
device_nameVARCHAR(128) NULL端末名
platformVARCHAR(64) NULLiPhone / Android / Windows 等
created_atDATETIME作成日時
updated_atDATETIME更新日時

3.2 QR / 発行管理

カラム名意味
issued_atDATETIME NULLQR発行日時
qr_expires_atDATETIME NULLQR失効日時
first_handshake_atDATETIME NULL初回接続日時
last_handshake_atDATETIME NULL最終接続日時
activated_atDATETIME NULL有効化日時

3.3 親IP制御

カラム名意味
is_parentBOOLEAN親端末か
parent_changed_atDATETIME NULL親変更日時
parent_changed_byVARCHAR(64) NULLcustomer / admin
parent_change_reasonVARCHAR(255) NULL変更理由

device_roleis_parent は二重化なので、実装はどちらか片方でもよいです。

ただし検索性のため is_parent を持つのは便利です。

3.4 停止・失効管理

カラム名意味
paused_atDATETIME NULL一時停止日時
pause_reasonVARCHAR(255) NULL一時停止理由
pause_expires_atDATETIME NULL一時停止期限
revoked_atDATETIME NULL無効化日時
revoked_reasonVARCHAR(255) NULL無効化理由
expired_atDATETIME NULLQR期限切れ日時

3.5 救済・本人確認系

カラム名意味
recovery_requiredBOOLEAN親紛失救済中フラグ
recovery_requested_atDATETIME NULL救済要求日時
recovery_completed_atDATETIME NULL救済完了日時
recovery_byVARCHAR(64) NULL実施管理者

3.6 通信量管理

カラム名意味
rx_bytes_totalBIGINT DEFAULT 0累計受信
tx_bytes_totalBIGINT DEFAULT 0累計送信
rx_bytes_24hBIGINT DEFAULT 024時間受信
tx_bytes_24hBIGINT DEFAULT 024時間送信
rx_bytes_7dBIGINT DEFAULT 07日受信
tx_bytes_7dBIGINT DEFAULT 07日送信
current_rx_bpsBIGINT DEFAULT 0現在受信速度
current_tx_bpsBIGINT DEFAULT 0現在送信速度

3.7 管理メモ

カラム名意味
notesTEXT NULL管理メモ
admin_tagsVARCHAR(255) NULL異常/注意タグ
deleted_atDATETIME NULL論理削除日時

“`

4. 状態定義

“`

status

意味
issuedQR発行済み・未使用
active利用中
paused一時停止
revoked無効化
expiredQR期限切れ

“`

5. 状態遷移

issued
  ↓ 初回ハンドシェイク
active
  ↓ 一時停止
paused
  ↓ 再開
active
  ↓ 強制停止
revoked

“`

期限切れ

issued
```

↓ 24時間経過
expired

6. 親IPルール

“`

6.1 原則

1契約につき parent は1台のみ

6.2 制約

DB制約として、理想は

contract_id ごとに is_parent = true は1件のみ

6.3 親変更

通常の親変更は 親IPからのみ 実行。

処理:

旧親 is_parent = false
```

新親 is_parent = true

“`

6.4 親紛失

親紛失時のみ

管理画面(wg0)

から管理者が再設定。

“`

7. QRルール

“`

7.1 発行

新規端末発行時

status = issued
```

issued_at = 現在時刻
qr_expires_at = 現在時刻 + 24h

“`

7.2 初回接続

初回ハンドシェイクで

first_handshake_at = now
```

activated_at = now
status = active

“`

7.3 再発行

再発行時

  • 旧端末 revoked
  • 新端末 issued

“`

8. 親端末変更フロー

“`

通常

親IPでログイン
```

↓
子IP一覧表示
↓
次の親を選択
↓
確認
↓
親変更

“`

DB処理

BEGIN
```

UPDATE customer_devices
SET is_parent = 0, device_role = 'child'
WHERE contract_id = :contract_id
AND is_parent = 1;

UPDATE customer_devices
SET is_parent = 1,
device_role = 'parent',
parent_changed_at = NOW(),
parent_changed_by = 'customer',
parent_change_reason = 'customer self migration'
WHERE id = :selected_device_id
AND contract_id = :contract_id
AND status = 'active';

COMMIT

9. 親紛失救済フロー

顧客
↓
電話サポート
↓
本人確認パスフレーズ確認
↓
管理画面(wg0)
↓
子IPまたは新IPを親へ設定

“`

管理側ログ

parent_changed_by = 'admin'
```

parent_change_reason = 'lost parent recovery'
recovery_completed_at = now

10. 削除通知を送らないボタンとの連携

これは契約テーブル側が本体ですが、端末管理とも連携するためここでも整理します。

“`

契約テーブル側で持つ項目

predelete_notice_suppressed
```

predelete_notice_suppressed_reason
predelete_notice_suppressed_at
predelete_notice_suppressed_by

“`

用途

  • 電話で本人確認済み
  • 本人希望で通知不要
  • 即時削除
  • 個別連絡済み
  • 迷惑利用対応

“`

11. インデックス

最低これを貼ります。

CREATE INDEX idx_customer_devices_contract_id
  ON customer_devices(contract_id);

CREATE INDEX idx_customer_devices_wg_ip
ON customer_devices(wg_ip);

CREATE UNIQUE INDEX uq_customer_devices_public_key
ON customer_devices(public_key);

CREATE INDEX idx_customer_devices_status
ON customer_devices(status);

CREATE INDEX idx_customer_devices_last_handshake
ON customer_devices(last_handshake_at);

12. 実用上のおすすめ追加カラム

あると後で助かるもの。

カラム名意味
app_versionクライアントバージョン
last_seen_ip最後に見えたグローバルIP
last_seen_user_agent端末情報
bandwidth_profile帯域制限プロファイル
portal_access_enabledポータル接続可否

13. SQLたたき台

CREATE TABLE customer_devices (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  contract_id VARCHAR(32) NOT NULL,
  device_id VARCHAR(64) NOT NULL,
  wg_iface VARCHAR(32) NOT NULL DEFAULT 'wg1',
  wg_ip VARCHAR(64) NOT NULL,
  public_key TEXT NOT NULL,
  preshared_key TEXT NULL,

device_role VARCHAR(16) NOT NULL DEFAULT 'child',
is_parent BOOLEAN NOT NULL DEFAULT FALSE,
status VARCHAR(16) NOT NULL DEFAULT 'issued',

device_name VARCHAR(128) NULL,
platform VARCHAR(64) NULL,

issued_at DATETIME NULL,
qr_expires_at DATETIME NULL,
first_handshake_at DATETIME NULL,
last_handshake_at DATETIME NULL,
activated_at DATETIME NULL,

parent_changed_at DATETIME NULL,
parent_changed_by VARCHAR(64) NULL,
parent_change_reason VARCHAR(255) NULL,

paused_at DATETIME NULL,
pause_reason VARCHAR(255) NULL,
pause_expires_at DATETIME NULL,
revoked_at DATETIME NULL,
revoked_reason VARCHAR(255) NULL,
expired_at DATETIME NULL,

recovery_required BOOLEAN NOT NULL DEFAULT FALSE,
recovery_requested_at DATETIME NULL,
recovery_completed_at DATETIME NULL,
recovery_by VARCHAR(64) NULL,

rx_bytes_total BIGINT NOT NULL DEFAULT 0,
tx_bytes_total BIGINT NOT NULL DEFAULT 0,
rx_bytes_24h BIGINT NOT NULL DEFAULT 0,
tx_bytes_24h BIGINT NOT NULL DEFAULT 0,
rx_bytes_7d BIGINT NOT NULL DEFAULT 0,
tx_bytes_7d BIGINT NOT NULL DEFAULT 0,
current_rx_bps BIGINT NOT NULL DEFAULT 0,
current_tx_bps BIGINT NOT NULL DEFAULT 0,

portal_access_enabled BOOLEAN NOT NULL DEFAULT FALSE,
bandwidth_profile VARCHAR(64) NULL,

notes TEXT NULL,
admin_tags VARCHAR(255) NULL,
deleted_at DATETIME NULL,

created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

14. 運用ルールの一文

customer_devices テーブルは、契約単位の WireGuard 端末管理の中核テーブルとし、親IP/子IP、QR発行状態、停止・失効状態、通信量、親変更履歴、救済操作履歴を一元管理する。顧客ポータルへのアクセス可否は親IPのみに限定し、通常の親変更は親端末からのみ実行可能とする。親端末紛失時のみ、管理画面(wg0)から本人確認パスフレーズを用いて救済操作を行う。

次の作業

次は contracts テーブルdelete queue / notice suppression を含む契約管理テーブル を続けて固めます。

🔌 顧客ポータル API設計書

1. APIの役割

ポータルAPIは、画面とDB・WireGuard・将来のNextcloud連携を結ぶ中核レイヤである。

画面
 ↓
FastAPI
 ├ contracts 読み書き
 ├ customer_devices 読み書き
 ├ admin_logs 記録
 ├ WG設定生成
 └ 将来 Nextcloud 同期

2. 実装候補ファイル

  • /opt/mikyun-portal/app.py
  • /opt/mikyun-portal/app/main.py
  • /opt/mikyun-portal/mikyun_vpn_engine.py

3. 顧客向けAPI

MethodPath用途
GET/api/me契約基本情報
GET/api/me/devices自端末一覧
POST/api/me/devices子端末追加
POST/api/me/devices/{device_id}/pause端末一時停止
POST/api/me/devices/{device_id}/resume停止解除
POST/api/me/devices/{device_id}/regen設定再発行
GET/api/me/devices/{device_id}/qrQR再表示
GET/api/me/storage容量表示(将来)

4. 管理者API

MethodPath用途
GET/api/admin/contracts契約一覧
GET/api/admin/contracts/{contract_id}契約詳細
POST/api/admin/contracts新規契約作成 + 親端末初回発行
POST/api/admin/contracts/{contract_id}/pause契約停止
POST/api/admin/contracts/{contract_id}/terminate解約
POST/api/admin/contracts/{contract_id}/quota容量変更
GET/api/admin/devices端末一覧
POST/api/admin/devices/{device_id}/promote親端末昇格
POST/api/admin/devices/{device_id}/revoke端末失効
GET/api/admin/logs監査ログ閲覧

5. 内部VPNエンジンAPI

MethodPath用途
POST/internal/wg/issue-parent親端末発行
POST/internal/wg/issue-child子端末発行
POST/internal/wg/reloadwg reload
GET/internal/wg/statusDBとwg実状態の比較
POST/internal/wg/pausepeer無効化
POST/internal/wg/resumepeer再有効化
POST/internal/wg/revokepeer削除

6. 将来のNextcloud連携API

MethodPath用途
POST/internal/nextcloud/users契約作成時にNCユーザー作成
PATCH/internal/nextcloud/users/{contract_id}/quota容量同期
GET/internal/nextcloud/users/{contract_id}/usage使用量取得
POST/internal/nextcloud/users/{contract_id}/disable停止・凍結

7. APIとDBの対応

テーブル関わる主API
contracts/api/me, /api/admin/contracts, quota変更, 停止, 解約
customer_devices端末一覧、追加、停止、復帰、昇格、失効、QR再発行
admin_logs全管理操作の監査ログ

🗃 DBテーブル一覧(mikyun_cloud)

1. DB概要

“`

DB名内容
mikyun_cloud契約・端末・管理ログを持つポータルDB

現状オブジェクト

  • admin_logs
  • contracts
  • customer_devices
  • v_parent_conflicts (VIEW)

“`

2. contracts

契約本体。顧客ID、サブネット、容量、上限、状態を持つ。

“`

カラム意味
contract_id契約ID
vpn_subnet顧客用VPNサブネット
next_child_ip次の子端末割当IP
customer_name / email / phone顧客情報
plan_nameプラン名
storage_quota_gbストレージ上限
max_devices端末上限
max_filesファイル数上限
bandwidth_profile帯域プロファイル
contract_statusactive / paused / terminated / deleted
identity_passphrase本人確認パスフレーズ

“`

3. customer_devices

契約配下の端末 + WireGuard peer 情報。

“`

カテゴリカラム
IDdevice_id, contract_id
WGwg_iface, wg_ip, public_key, private_key, preshared_key
役割device_role, is_parent
状態status, issued_at, activated_at, paused_at, revoked_at, expired_at
回復recovery_required, recovery_requested_at, recovery_completed_at
統計rx_bytes_total, tx_bytes_total, rx_bytes_24h, tx_bytes_24h, rx_bytes_7d, tx_bytes_7d, current_rx_bps, current_tx_bps
端末情報device_name, platform, app_version, last_seen_ip, last_seen_user_agent
運用portal_access_enabled, bandwidth_profile, notes, admin_tags

“`

4. admin_logs

管理操作の監査ログ。

“`

カラム意味
action_type操作種別
target_typecontract / device
target_id対象ID
message詳細メッセージ
created_at実行時刻

“`

5. v_parent_conflicts

同一契約に親端末が複数いないか監査するVIEW。

is_parent = 1
AND deleted_at IS NULL
GROUP BY contract_id
HAVING COUNT(*) > 1

🧩 DB ER図(関係図)

1. 現状ER図

+------------------+
|    contracts     |
+------------------+
| contract_id (UK) |
| vpn_subnet       |
| next_child_ip    |
| customer_name    |
| plan_name        |
| storage_quota_gb |
| max_devices      |
| contract_status  |
| identity_passphrase |
+------------------+
         |
         | 1:N
         v
+-----------------------+
|   customer_devices    |
+-----------------------+
| device_id (UK)        |
| contract_id           |
| wg_iface              |
| wg_ip (UK)            |
| public_key            |
| preshared_key         |
| device_role           |
| is_parent             |
| status                |
| device_name           |
| portal_access_enabled |
| recovery_required     |
| ...                   |
+-----------------------+

+------------------+
|    admin_logs    |
+------------------+
| action_type      |
| target_type      |
| target_id        |
| message          |
+------------------+

+------------------------+
|  v_parent_conflicts    |
|        (VIEW)          |
+------------------------+
| contract_id            |
| parent_count           |
+------------------------+

2. 関係の意味

  • contracts → customer_devices: 1契約に複数端末。
  • customer_devices → v_parent_conflicts: 親端末が2台以上いないか監査。
  • admin_logs: FKは持たず、target_type / target_id で論理参照。

3. 完成形ER図(推奨拡張)

contracts
   |   | \__ 1:1 → nextcloud_accounts
   |__ 1:N → customer_devices
   |__ 1:N → notifications
                         \__ 1:1 or 1:N → portal_accounts

admin_logs
└ 管理操作監査

“`

追加推奨テーブル理由
portal_accounts顧客ログインアカウント
nextcloud_accountsNCユーザー名・quota・使用量同期
notificationsメンテ通知・警告通知
portal_logs顧客側操作ログ

“`

💡 理念とセールスポイント

1. 理念

“`

個人が自分のクラウドを持つ時代へ

みーきゅんクラウドは、広告モデルやブラックボックス管理に依存しない、利用者が理解できるクラウド を目指す。

データの主権はユーザーにある

  • データはユーザーの所有物
  • 不要なデータ収集はしない
  • 構造を説明できる透明性を持つ

“`

2. セールスポイント

“`

項目特徴
完全プライベートネットワークWireGuard前提で外部公開面を減らす
端末単位管理親端末 / 子端末という実用的モデル
自動発行WG設定とQRを自動生成
大容量ストレージSupermicro + 暗号化 + 高速内部LAN
自前インフラ自前DC設計で自由度が高い
顧客ポータルセルフ管理可能

“`

3. キャッチコピー案

  • あなた専用のクラウド
  • データは、あなたのもの。
  • VPNの中にあるクラウド
  • 個人のためのプライベートクラウド

🌐 みーきゅんクラウド / 07_API

Notion取り込み用HTML。引き継ぎ前提の詳細版。

7.1 APIの目的

顧客ポータルおよび管理機能は FastAPIベースのAPIサーバ で動作する。

“`

実装配置

/opt/mikyun-portal/
```

├─ app.py
├─ app/main.py
├─ mikyun_vpn_engine.py
├─ peers/
├─ issued/
└─ venv/

“`

役割

  • 顧客ポータル
  • WireGuard発行
  • QR生成
  • DB操作
  • 管理操作

“`

7.2 API全体構造

Client
  │
  │ HTTPS
  │
Portal API
  │
  ├─ DB (MariaDB: mikyun_cloud)
  ├─ WireGuard Engine
  ├─ Config生成
  └─ QR生成

7.3 顧客API

“`

GET /api/me

ログイン中顧客の契約情報を返す。

{
```

"contract_id": "M010",
"customer_name": "みーきゅんわんわん",
"plan_name": "standard",
"contract_status": "active",
"storage_quota_gb": 200,
"max_devices": 3,
"max_files": 10000,
"bandwidth_profile": "standard"
}

“`

GET /api/me/devices

自契約の端末一覧を返す。取得元は customer_devices

[
```

{
"device_id": "M010-DEV-001",
"device_name": "mikyun-iphone",
"device_role": "parent",
"is_parent": true,
"status": "issued",
"wg_ip": "10.200.10.2",
"platform": "ios",
"portal_access_enabled": true
}
]

“`

POST /api/me/devices

子端末追加。処理の流れは以下。

  1. 契約確認
  2. contracts.next_child_ip 取得
  3. WG鍵生成
  4. customer_devices 登録
  5. config生成
  6. QR生成
  7. contracts.next_child_ip 更新
  8. admin_logs 記録

POST /api/me/devices/{device_id}/pause

端末一時停止。status = pausedpaused_atpause_reason を記録。

POST /api/me/devices/{device_id}/resume

停止端末再開。status = active へ遷移。

GET /api/me/devices/{device_id}/qr

QR再表示。親端末は子端末分も取得可、自端末分は本人のみ取得可。

POST /api/me/devices/{device_id}/regen

設定再発行。再利用または新鍵発行の方針を実装側で選択。

“`

7.4 管理API

“`

GET /api/admin/contracts

契約一覧。表示項目は契約ID、契約者名、状態、容量、端末上限、次回子IPなど。

GET /api/admin/contracts/{contract_id}

契約詳細。contracts 本体 + 端末一覧 + 最新ログを返す。

POST /api/admin/contracts

新規契約作成 + 親端末初回発行。

{
```

"contract_id": "M011",
"customer_name": "Example User",
"customer_email": "[user@example.com](mailto:user@example.com)",
"customer_phone": "09000000000",
"plan_name": "standard",
"storage_quota_gb": 200,
"max_devices": 3,
"max_files": 10000,
"bandwidth_profile": "standard",
"identity_passphrase": "example-passphrase",
"parent_device_name": "iphone-parent",
"platform": "ios"
}

“`

POST /api/admin/contracts/{contract_id}/pause

契約停止。必要に応じて配下端末も一括停止。

POST /api/admin/contracts/{contract_id}/terminate

契約終了。terminated_at 記録、peer revoke、削除スケジュール準備。

POST /api/admin/contracts/{contract_id}/quota

容量変更。将来はNextcloud quota同期も実行。

POST /api/admin/devices/{device_id}/promote

子端末を親端末へ昇格。既存親はchildに降格し、v_parent_conflicts を壊さないよう更新。

POST /api/admin/devices/{device_id}/revoke

端末失効。status = revokedrevoked_atrevoked_reason を記録。

“`

7.5 内部VPNエンジンAPI

mikyun_vpn_engine.py が担当する想定。

“`

内部API用途
POST /internal/wg/issue-parent親端末発行
POST /internal/wg/issue-child子端末発行
POST /internal/wg/reloadwg sync / reload
GET /internal/wg/statusDBと実WG状態の比較
POST /internal/wg/pausepeer無効化
POST /internal/wg/resumepeer再有効化
POST /internal/wg/revokepeer削除

“`

7.6 将来のNextcloud連携API

“`

API用途
POST /internal/nextcloud/usersNCユーザー作成
PATCH /internal/nextcloud/users/{contract_id}/quota容量同期
GET /internal/nextcloud/users/{contract_id}/usage使用量取得
POST /internal/nextcloud/users/{contract_id}/disableNC停止

“`

7.7 APIとDBの対応

“`

対象読む / 書くAPI
contracts契約一覧、契約詳細、契約作成、停止、終了、容量変更
customer_devices端末一覧、子端末追加、停止、再開、再発行、昇格、失効
admin_logs管理操作全般の監査ログ

“`

7.8 実装優先順位

  1. 契約一覧 / 契約詳細 / 端末一覧
  2. 子端末追加
  3. pause / resume
  4. QR再取得
  5. 親端末昇格 / revoke
  6. Nextcloud連携

🌐 みーきゅんクラウド / 08_DB

mikyun_cloud データベース現状まとめ。

8.1 DB基本情報

項目内容
DB名mikyun_cloud
エンジンMariaDB
配置R640
現サイズ約 0.3 MB

8.2 テーブル一覧

種別名前用途
TABLEcontracts契約本体
TABLEcustomer_devices顧客端末 / WireGuard端末
TABLEadmin_logs管理操作ログ
VIEWv_parent_conflicts親端末重複監査

8.3 contracts

顧客契約の本体テーブル。顧客ごとのVPNセグメント、上限値、状態を保持する。

“`

カラム意味
contract_id契約ID(例: A001, M010)
vpn_subnet契約ごとのVPNサブネット(例: 10.200.10.0/24)
next_child_ip次に払い出す子端末IP
customer_name / email / phone契約者情報
plan_name契約プラン
storage_quota_gb容量上限
max_devices端末上限
max_filesファイル上限
bandwidth_profile帯域プロファイル
contract_statusactive / paused / terminated / deleted
identity_passphrase本人確認パスフレーズ
notes / admin_tags運用補足

状態制約

active
```

paused
terminated
deleted

8.4 customer_devices

顧客ごとの端末管理テーブル。WireGuardの鍵・IP・状態・統計を持つ中核テーブル。

“`

カテゴリ主要カラム
識別device_id, contract_id
WireGuardwg_iface, wg_ip, public_key, private_key, preshared_key
端末属性device_role, is_parent, device_name, platform, app_version
状態status, issued_at, activated_at, paused_at, revoked_at, expired_at
親変更parent_changed_at, parent_changed_by, parent_change_reason
復旧recovery_required, recovery_requested_at, recovery_completed_at, recovery_by
統計rx_bytes_total, tx_bytes_total, rx_bytes_24h, tx_bytes_24h, rx_bytes_7d, tx_bytes_7d, current_rx_bps, current_tx_bps
最終観測last_seen_ip, last_seen_user_agent, first_handshake_at, last_handshake_at
ポータルportal_access_enabled
備考bandwidth_profile, notes, admin_tags, deleted_at

device_role 制約

parent
```

child

“`

status 制約

issued
```

active
paused
revoked
expired

“`

ユニーク制約

  • device_id
  • wg_ip
  • public_key(prefix 191)

“`

8.5 admin_logs

監査ログテーブル。管理APIや発行処理の結果を書き残す。

“`

カラム意味
action_type操作種別
target_typecontract / device など
target_id契約IDまたは端末ID
message詳細メッセージ
created_at実行時刻

“`

8.6 v_parent_conflicts

親端末が複数存在する契約を検出する監査用VIEW。

is_parent = 1
AND deleted_at IS NULL
GROUP BY contract_id
HAVING COUNT(*) > 1

8.7 インデックス方針

“`

contracts

  • PRIMARY(id)
  • UNIQUE(contract_id)
  • INDEX(contract_status)
  • INDEX(delete_scheduled_at)
  • INDEX(predelete_notice_sent_at)
  • INDEX(predelete_notice_suppressed)
  • INDEX(customer_email)

customer_devices

  • PRIMARY(id)
  • UNIQUE(device_id)
  • UNIQUE(wg_ip)
  • UNIQUE(public_key prefix)
  • INDEX(contract_id)
  • INDEX(status)
  • INDEX(last_handshake_at)
  • INDEX(contract_id, is_parent)
  • INDEX(contract_id, status)

“`

8.8 現状評価

  • 契約と端末が分離されている
  • 親子端末思想がDBに入っている
  • WG鍵・IP・状態・統計・復旧フラグまで持っている
  • 監査ログと親端末重複チェックVIEWがある

8.9 将来追加推奨

  • portal_accounts
  • nextcloud_accounts
  • notifications
  • portal_logs

🌐 みーきゅんクラウド / 09_運用

日常運用・定期確認・保守作業の基準ページ。

9.1 運用対象

  • R640(Control Node)
  • Supermicro(Storage Node)
  • VPS(Gateway)
  • Cisco WS-C3850-12XS(CORE)
  • Cisco WS-C3850-48T(ACCESS)
  • RTX1300(Router)

9.2 日次確認

“`

R640

wg show
```

ip route
docker ps
df -h
systemctl --failed

“`

Supermicro

df -h
```

lsblk
lvs
vgs
pvs
systemctl --failed

“`

VPS

wg show
```

ss -lntup
ip route
iptables -S
iptables -t nat -S

9.3 VPN監視

wg show

確認ポイント:

  • latest handshake が更新されているか
  • transfer が増えているか
  • expected peer が欠けていないか

9.4 DB確認

mysql -u root -p -e "SHOW DATABASES;"
mysql -u root -p -e "USE mikyun_cloud; SHOW TABLES;"
mysql -u root -p -e "USE mikyun_cloud; SELECT COUNT(*) FROM contracts;"
mysql -u root -p -e "USE mikyun_cloud; SELECT COUNT(*) FROM customer_devices;"

9.5 ストレージ監視

Supermicro 上の主ストレージを監視する。

df -h
lsblk
lvs
mount | grep /srv/storage

“`

重要マウント

/srv/storage
```

192.168.30.30:/nextclouddata
/mnt/maguro/nextclouddata

9.6 Nextcloud系確認

docker ps
df -h | grep nextcloud
mount | grep nextclouddata

確認ポイント:

  • NFSマウントが有効か
  • コンテナが落ちていないか
  • 残容量が逼迫していないか

9.7 バックアップ

原則として以下をバックアップ対象にする。

  • Nextcloud data
  • DB
  • ポータル設定 / 出力物
  • WireGuard設定
  • スイッチ / ルータ設定

9.8 定期点検(週次)

  • WG peer状態確認
  • 契約 / 端末数の棚卸し
  • admin_logsの異常操作確認
  • ストレージ残量確認
  • Switch uplink / LACPエラー確認
  • UPS状態確認

9.9 月次点検

  • OSアップデート方針確認
  • VPSのKernel / Package更新可否確認
  • Nextcloud / Portal / DBバックアップ復元テスト
  • 証明書期限確認
  • ストレージ増設余力確認

9.10 変更作業ルール

  • 本番系変更前に現状バックアップ
  • ネットワーク変更は CORE → ACCESS → Host の順で確認
  • DB変更はDDL前に dump を取る
  • WG設定変更は peer一覧退避後に実施

9.11 よく使う確認コマンド集

“`

R640

ip -br a
```

ip route
wg show
docker ps
df -h
cat /etc/netplan/*.yaml

“`

Supermicro

ip -br a
```

ip route
df -h
lsblk
lvs
vgs
pvs

“`

Cisco

show vlan brief
```

show ip interface brief
show interfaces status
show etherchannel summary
show interfaces trunk

“`

RTX1300

show config
```

show nat descriptor address
show status tunnel 1
show status ipv6