みーきゅんクラウド ポータル — 運営/顧客/VPNエンジン
運用中 maguro Docker 全面移植完了 (Phase 2 / 2026-05-14) 3層構成 /ui (運営) + /client (顧客) + VPN Engine
| サービス | 所在 | ポート | 備考 |
|---|---|---|---|
| mikyun-portal (FastAPI) | maguro Docker (mikyun-portal:1.1) | 9000 (UI) / 9081 (Engine) | 運営ポータル + 顧客ポータル + VPN Engine を 1イメージに統合 |
| MariaDB (mikyun_cloud) | maguro Docker compose-db-1 | 内部のみ | Nextcloud と同一スタックへ統合 (旧ホストMariaDBは disable) |
| WireGuard | maguro ホスト (wg-clients / wg-customers / wg-storage) | UDP 54024 / 61001 / 62001 | VPN Engine が wg syncconf でピア管理 |
mikyun-cloud.service + mikyun-vpn-engine.service として動いていたものを、 2026-05-14 の Phase 2 で maguro Docker (mikyun-portal:1.1, ポート 9000 + 9081) に統合移植。 ホスト直の systemd ユニットは退役。
| 用途 | URL | 備考 |
|---|---|---|
| 運営ポータル (内部 LAN) | https://cloud.k2-o.net/ui/contracts | maguro nginx の location allow で内部VLAN20/30/WG (10.200.0.0/16) を許可 |
| 運営ポータル (外出先) | https://admin.wan-secure.net/ui/contracts | WireGuard wg-clients 接続必須 |
| 顧客ポータル | https://cloud.k2-o.net/client | 顧客はWG接続 → 親端末IPで自動判定 → パスフレーズ認証 |
Basic認証: admin / .env に保管 (ADMIN_PASS)。 旧ハードコードは 2026-04-06 のセキュリティ修正で撤去済。
認証: HTTP Basic (ADMIN_USER/ADMIN_PASS 環境変数)
nginx 側 IP制限: 192.168.20.0/24, 192.168.30.0/24, 10.200.0.0/16 (wg-clients), 127.0.0.1, fabric subnets
| Path | Method | 機能 |
|---|---|---|
/ | GET | HOME (ユーザー数 / オンライン / 累計トラフィック上位) |
/ui/contracts | GET | 契約一覧 (DB直読、 状態 / 容量 / 稼働端末数 / 使用量GB) |
/ui/contracts/new | GET / POST | 新規契約作成 → VPN Engine /contracts/create 委譲 |
/ui/contracts/{id} | GET | 契約詳細 (親端末カード + 子端末一覧) |
/ui/contracts/{id}/add-child | POST | 子端末追加 → /devices/add-child |
/ui/contracts/{id}/promote-parent | POST | 親端末昇格 |
/ui/contracts/{id}/terminate-confirm | GET | 契約解除確認 |
/ui/contracts/{id}/terminate | POST | 解除実行 (端末 paused + WGピア削除 + NC完全削除) |
/ui/billing | GET | 入金管理 (ポイント残高 / 警告 / suspended 一覧、 2026-04-10 追加) |
/ui/contracts/{id}/billing | GET | 個別契約の課金履歴 |
/ui/traffic | GET | 全端末のリアルタイム bps + 24h/7d/月次/累計 |
/ui/notes | GET / POST | 顧客メモ (メモ / トラブル / 通話 / 警告) |
/health | GET | 監視用 (認証不要) |
認証: WireGuard 接続元IP (10.200.0.0/16) で端末特定 + identity_passphrase 追加認証。 親端末のみ管理画面、 子端末は NC へリダイレクト。
| Path | Method | 機能 |
|---|---|---|
/client | GET | ログイン (親端末→パスフレーズ入力、 子端末→NCリダイレクト) |
/client/login | POST | identity_passphrase 照合 |
/client/devices/{contract_id} | GET | 端末一覧 + 課金カード (残高/月額/次回支払日) |
/client/add-device/{contract_id} | GET / POST | 子端末追加 (NCアカウント任意作成、 残容量<20GB は不可) |
/client/pause|resume|promote|delete/{device_id} | POST | 各種端末操作 (削除時は親端末へ10GB返却) |
/client/qr/{contract_id}/{device_id} | GET | WG設定QR (24h有効を警告) |
/client/conf/{device_id} | GET | conf ダウンロード |
バインド: 127.0.0.1:9081 (Docker内ネット経由) / 外部からは nginx + WGで二重制限
ファイル: mikyun-portal イメージ内 /opt/mikyun-portal/mikyun_vpn_engine.py
| Path | Method | 用途 |
|---|---|---|
/health | GET | 生存確認 |
/contracts/create | POST | 契約作成 + 親端末WGピア + conf/QR + NCアカウント作成 |
/contracts/list | GET | 契約一覧 |
/contracts/{contract_id} | GET | 契約詳細 (NC情報含む) |
/contracts/{contract_id}/devices | GET | 端末一覧 |
/devices/add-child | POST | 子端末追加 (IP採番 + WGピア) |
/devices/promote-parent | POST | 親端末昇格 (旧親はchild降格) |
/devices/pause|resume|delete | POST | 停止/復帰/削除 + 親端末容量返却 |
/opt/mikyun-portal/ ← Docker bind ソース (ホスト側)
├── docker-compose.yml ← compose 定義 (mikyun-portal サービス)
├── .env ← DB / Admin / Stripe 秘匿値 (mode 600)
├── app/
│ ├── main.py ← FastAPI エントリ + Basic認証ミドルウェア
│ ├── ui_admin.py ← 運営ポータルUI
│ ├── api_users.py ← /api/users (Basic認証必須)
│ └── client/
│ └── client_ui.py ← 顧客ポータルUI
├── mikyun_vpn_engine.py ← VPN Engine 本体
└── billing/
└── billing_daily.py ← 月次ポイント処理 (2026-04-10〜)
# WG関連 (ホスト)
/etc/wireguard/wg-clients.conf ← 10.200.0.0/16 / UDP 54024
/etc/wireguard/wg-customers.conf ← UDP 61001
/etc/wireguard/wg-storage.conf ← UDP 62001
# 出力
/opt/mikyun/output/client-configs/ ← .conf
/opt/mikyun/output/qr/ ← .png
# systemd (ホスト側)
/etc/systemd/system/billing-daily.timer
/etc/systemd/system/billing-daily.service
/root/mikyun-cloud/、 /root/mikyun-cloud/mikyun-portal/、 /root/mikyun-cloud/app/ はすべて R640再構築 (2026-05-14) で消滅。 現行ソースは maguro /opt/mikyun-portal/ のみが正。
| 日付 | 項目 | 修正前 | 修正後 |
|---|---|---|---|
| 2026-04-06 | MySQL 外部公開 | 0.0.0.0:3306 | 127.0.0.1:3306 (現在は Docker 内部ネットのみ) |
| 2026-04-06 | VPN Engine 外部公開 | 0.0.0.0:9081 | 127.0.0.1:9081 |
| 2026-04-06 | DB / Adminパスワード | ハードコード | .env 読み込み (mode 600) |
| 2026-04-06 | WG鍵パーミッション | 644 | 600 (root only) |
| 2026-04-06 | /api/users | 認証なし | Basic認証必須 |
| 2026-05-14 | 本番経路 | R640 ホスト直 systemd | maguro Docker (mikyun-portal:1.1) |
運営ポータルから NCユーザーのパスワードを強制変更する機能のバグ修正記録。 教訓として残す。
Nextcloud の occ は www-data ユーザー実行が必須。 docker exec に -u www-data を付けていなかった。
# NG docker exec -e OC_PASS=xxx nextcloud-stack-app-1 php occ user:resetpassword # OK docker exec -u www-data -e OC_PASS=xxx nextcloud-stack-app-1 php occ user:resetpassword
運営強制変更の前後で enforceHaveIBeenPwned を一時的に 0 にし、 変更後 1 に戻す。 例外時も必ず戻す try/finally で保護。
# パスワードポリシー一時無効化 docker exec -u www-data nextcloud-stack-app-1 \ php occ config:app:set password_policy enforceHaveIBeenPwned --value=0 # 強制変更 docker exec -u www-data -e OC_PASS="$PW" nextcloud-stack-app-1 \ php occ user:resetpassword --password-from-env "$NC_USER" # 再有効化 (必ず) docker exec -u www-data nextcloud-stack-app-1 \ php occ config:app:set password_policy enforceHaveIBeenPwned --value=1
NC使用量を customer_devices.nc_used_bytes に1時間ごと収集して契約一覧に表示する機能。 maguro Docker 移植時に /opt/mikyun-portal/scripts/collect_file_count.py として cron 化済。
# cron (maguro) 0 * * * * docker exec mikyun-portal python3 /opt/scripts/collect_file_count.py >> /var/log/storage_collect.log 2>&1
/root/mikyun-cloud/app/ui_admin.py (古いコピー) と /root/mikyun-cloud/mikyun-portal/app/ui_admin.py (本番) が両方存在し、 編集ミスで反映されない事故があった。 Docker 化後は /opt/mikyun-portal/app/ui_admin.py 一本に統一済。
# コンテナ再起動 (UI + Engine 同一コンテナ) docker compose -f /opt/mikyun-portal/docker-compose.yml restart mikyun-portal # ログ docker logs -f --tail=200 mikyun-portal # DB docker compose -f /opt/nextcloud/compose/compose.yml exec db mysql -u root -p mikyun_cloud # 月次バッチ systemctl status billing-daily.timer journalctl -u billing-daily.service -n 50
| 種類 | 場所 |
|---|---|
| DB / Admin / Stripe | /opt/mikyun-portal/.env (mode 600, root) |
| WG鍵 (peer) | /etc/wireguard/peers/ (mode 600) |
| 顧客 identity_passphrase | DB contracts.identity_passphrase (将来 Argon2 ハッシュ化検討) |
| NC親アカウントPW | DB contracts.nc_password (現状平文、 改善TODO) |