MCP(Model Context Protocol)による AI エージェントの永続記憶アーキテクチャ
Executive Summary
AI エージェント(Claude Code 等)を用いた開発において、セッション間のコンテキスト消失と複数環境間でのファイル共有の非効率が生産性のボトルネックとなっていた。本稿では、MCP(Model Context Protocol)に準拠したファイルストレージサービス mcp.gd を設計・実装し、これらの課題を解決した過程を記録する。
1. 課題 — 複数プロジェクト同時開発の摩擦
業務で50件規模の小規模サービスを一人で同時に開発・保守する状況があった。各サービスはそれぞれローカル環境・開発サーバ・本番サーバの3環境を持ち、CI/CD パイプラインが使えない制約下で git + Docker Compose による手動デプロイを行っていた。
AI エージェント(Claude Code)を開発補助に導入していたが、以下の3つの課題が顕在化した。
課題 1: 共通プロンプトの非共有性
50のプロジェクトには共通のセキュリティ要件やフラグ形式など、横断的なルールが存在した。これらを各プロジェクトの CLAUDE.md に個別に記述・同期する運用は現実的でない。プロジェクト横断で参照可能な「共有コンテキスト層」が必要だった。
課題 2: 環境横断のスキル設定コスト
Claude Code のスキルコマンドや設定を、50サービス × 3環境 = 150のエンドポイントに個別に設定する時間的余裕がなかった。環境固有の設定を手動で管理するアプローチはスケールしない。
課題 3: ビルド成果物の転送コスト
コンパイルしたバイナリをローカルから開発サーバ・本番サーバへ転送する作業が、1日に何度も発生していた。CI/CD が不在の環境では、scp や rsync による手動転送が唯一の選択肢であり、これがイテレーション速度を制約していた。
graph TD
subgraph ENV["50 Projects × 3 Environments = 150 Endpoints"]
L["Local Machine"]
D["Dev Server"]
P["Prod Server"]
end
L -- "CLAUDE.md 個別設定 ❌ 同期不可能" --- D
D -- "skill 個別設定 ❌ 時間的に不可能" --- P
L -. "バイナリ手動転送 ❌ 低速" .-> P
N1["❌ CI/CD なし"]
N2["❌ 共有コンテキスト層なし"]
ENV ~~~ N1
N1 ~~~ N2
図1: 複数プロジェクト同時開発における課題の構造
2. 解決策の設計 — なぜ MCP ファイルストレージなのか
課題を整理すると、必要なのは次の3つの能力だった。
- AI エージェントが自律的に読み書きできる永続ストレージ
- ローカル・開発・本番の環境を跨いで共有できるファイルシステム
- 人間の介在なしにプログラマティックにアクセス可能な API
既存の選択肢を検討した。
| 選択肢 | 課題1 | 課題2 | 課題3 | 判定 |
|---|---|---|---|---|
| Git submodule で共通設定共有 | △ | ✗ | ✗ | 部分解 |
| S3 + CLI スクリプト | ✗ | ✗ | ○ | 部分解 |
| 共有 NFS / SSHFS マウント | ✗ | ✗ | △ | 運用負荷大 |
| MCP 対応ファイルストレージ | ○ | ○ | ○ | 全課題を解決 |
MCP(Model Context Protocol) は、AI エージェントが外部ツールやリソースにアクセスするための標準プロトコルである。MCP に準拠したファイルストレージがあれば、AI エージェントは追加設定なしにファイルの保存・取得が可能になる。これは課題1(共通プロンプトの共有)と課題2(環境横断設定)を同時に解消する。さらに REST API を提供することで、課題3(バイナリ転送)もスクリプトで自動化できる。
設計判断: 3つの独立した課題を3つの独立したツールで解決するのではなく、1つのプロトコル層で統一的に解決する方針を選択した。MCP がその統一層として機能する。
3. アーキテクチャ — mcp.gd の全体設計
設計上の優先事項は3つ。レイテンシの最小化(AI エージェントの待機時間がそのまま開発者の待機時間になる)、単一バイナリデプロイ(CI/CD なしの環境でも即座に展開できる)、セキュリティ(任意のファイルを扱うため、認証・認可は厳密に行う)。
graph TD
subgraph Clients
CC["Claude Code (MCP Client)"]
RC["REST API Client"]
WU["Web UI (Browser)"]
end
CC -- "SSE + JSON-RPC" --> MCP
RC -- "HTTPS" --> REST
WU -- "HTTPS" --> WEB
subgraph AXUM["Axum (Rust)"]
MCP["MCP SSE+RPC Transport"]
REST["REST API Routes"]
WEB["Web Routes (Askama)"]
MCP --> SL
REST --> SL
WEB --> SL
SL["Service Layer: Auth · Files · Folders · Search · Billing"]
end
SL --> PG["PostgreSQL: metadata / users / auth / billing"]
SL --> S3["S3-compat: file blobs, up to 100GB/file"]
SL --> RD["Redis: sessions / rate limit / cache"]
図2: mcp.gd のシステムアーキテクチャ
Rust を選択した理由
言語選択の決定要因は単一バイナリデプロイだった。CI/CD が不在の環境では、ランタイムの依存関係が少ないほどデプロイが容易になる。Rust はコンパイル済みバイナリとして配布でき、実行時に言語ランタイムを必要としない。加えて、ファイルストレージとしてメモリ安全性が重要であり、100GB 規模のストリーミングアップロードを安全に処理する必要があった。
Axum + Tower ミドルウェアスタック
Web フレームワークには Axum 0.8 を採用した。Tower のミドルウェアアーキテクチャにより、認証・レート制限・CORS・CSRF 保護をレイヤとして積み上げることができる。3つの異なるインターフェース(MCP SSE、REST API、Web UI)を単一のサーバプロセスで提供する設計とした。
ストレージの二層構造
ファイルの実体はS3互換オブジェクトストレージに、メタデータはPostgreSQLに分離した。この設計により、ストレージバックエンドを AWS S3、MinIO、Wasabi など任意のプロバイダに切り替え可能にしている。S3 キーは {user_id}/{file_id}.{ext} の構造で、ユーザ間のデータ分離を物理的に保証する。
アップロードはファイルサイズに応じて自動的に戦略を切り替える。
- 5MB 未満: 単一 PUT リクエスト(低レイテンシ)
- 5MB 以上: マルチパートアップロード(ストリーミング分割)
4. 認証設計 — OAuth 2.0 + PKCE
AI エージェントが自律的にファイルにアクセスするには、人間の介在なしに認証を完了する仕組みが必要になる。標準的な OAuth 2.0 Authorization Code Grant に PKCE(Proof Key for Code Exchange) を組み合わせた。
sequenceDiagram
participant CC as Claude Code<br/>(MCP Client)
participant MG as mcp.gd<br/>(Auth Server)
participant BR as Browser
CC->>MG: 1. GET /oauth/authorize + code_challenge (S256)
MG->>BR: 2. Redirect to Login Page
BR->>MG: 3. User Approves
MG->>CC: 4. Callback with code
CC->>MG: 5. POST /oauth/token + code_verifier
MG->>CC: 6. access_token + refresh_token
rect rgba(52, 211, 153, 0.1)
Note over CC,MG: 認証完了 — 以降はトークンで自律アクセス
CC->>MG: 7. MCP requests with Bearer token
end
図3: OAuth 2.0 + PKCE による MCP クライアント認証
JWT のクレームにはユーザ ID・メールアドレスに加え、IP アドレスハッシュとUser-Agent ハッシュをオプションで含め、セッションの端末バインディングを実現している。パスワードハッシュには Argon2 を使用し、トークンの有効期間はアクセストークン1時間、リフレッシュトークン7日とした。
レート制限は Redis ベースで実装し、クライアント登録は100リクエスト/時間/IP、トークンエンドポイントは20リクエスト/分/IP に制限している。Redis が利用不可の場合はインメモリにフォールバックする。
5. MCP ツール設計 — 14の操作の抽象化
MCP プロトコル(バージョン 2024-11-05)の HTTP + SSE トランスポートで実装した。AI エージェントが SSE 接続を確立し、JSON-RPC 2.0 でツールを呼び出す。
14のツールを設計するにあたり、「AI エージェントがファイルシステムに対して行いたい操作は何か」を起点とした。結果として、Unix ファイルシステムの操作をそのまま MCP ツールに射影する設計とした。
| カテゴリ | ツール名 | 対応する Unix 操作 |
|---|---|---|
| ファイル | store_text |
echo > file |
| ファイル | store_context |
構造化データの保存 |
| ファイル | get_file |
cat file |
| ファイル | delete_file |
rm file |
| ファイル | move_file |
mv file dir/ |
| フォルダ | create_folder |
mkdir -p |
| フォルダ | list_folders |
ls -d */ |
| フォルダ | get_folder |
stat dir |
| フォルダ | delete_folder |
rm -rf dir |
| フォルダ | move_folder |
mv dir/ parent/ |
| 一覧 | list_files |
ls -l |
| 一覧 | list_folder_contents |
ls -la dir/ |
| 検索 | search_files |
find + grep |
| 情報 | get_storage_info |
du -sh |
設計思想: AI エージェントに新しい概念を学習させるのではなく、既にモデルが理解しているファイルシステムの概念をそのまま MCP ツールとして提供した。これにより、プロンプトに使い方を記述する必要がほぼなくなる。
検索機能: Tantivy + PostgreSQL トライグラム
全文検索には Rust 製検索エンジン Tantivy を採用した。PostgreSQL の pg_trgm(トライグラム)をフォールバックとして用意し、Tantivy のインデックスが破損した場合でも検索機能が継続する設計とした。
search_files ツールは、ファイル名の全文検索に加え、MIME タイプ・サイズ範囲・日付範囲・フォルダ ID によるファセット検索をサポートする。
クォータ制御
全 MCP ツールの呼び出し時に、ユーザの契約プランに基づいたクォータチェックを実行する。容量超過時は QuotaExceeded エラーを返し、AI エージェントが適切にハンドリングできるようにした。
6. 元の課題はどう解決されたか
graph TD
subgraph ENV["50 Projects × 3 Environments"]
L2["Local Machine"]
D2["Dev Server"]
P2["Prod Server"]
end
L2 --> MCPGD
D2 --> MCPGD
P2 --> MCPGD
MCPGD["mcp.gd"]
MCPGD --- F1["共通プロンプト ← MCP で読み取り"]
MCPGD --- F2["バイナリ保存 ← API で自動転送"]
MCPGD --- F3["設定ファイル ← 環境横断で共有"]
R1["✅ 設定は1箇所に集約"]
R2["✅ AI エージェントが自律的にアクセス"]
R3["✅ 手動転送の排除"]
MCPGD ~~~ R1
R1 ~~~ R2
R2 ~~~ R3
図4: mcp.gd 導入後のワークフロー
| 課題 | 解決方法 | 効果 |
|---|---|---|
| 共通プロンプトの非共有性 | mcp.gd にプロンプトを保存し、MCP ツール経由で各プロジェクトの AI エージェントが参照 | 50プロジェクト間で設定の一貫性を確保 |
| 環境横断の設定コスト | MCP 接続設定のみで全ツールが利用可能。環境ごとの個別設定が不要 | 設定作業を 150回 → 1回 に削減 |
| ビルド成果物の転送コスト | REST API 経由でバイナリを保存・取得。スクリプトで自動化 | 手動 scp/rsync の排除 |
7. 技術スタックの全体像
| レイヤ | 技術 | 選択理由 |
|---|---|---|
| 言語 | Rust | 単一バイナリ、メモリ安全性 |
| Web | Axum 0.8 + Tower | 3インターフェース統合 |
| DB | PostgreSQL 15 + SQLx | コンパイル時 SQL 検証 |
| キャッシュ | Redis 7 | セッション、レート制限 |
| ストレージ | S3 互換 | プロバイダ非依存 |
| 検索 | Tantivy + pg_trgm | 高速検索 + フォールバック |
| 認証 | OAuth 2.0 + PKCE + JWT | AI エージェント対応 |
| 暗号 | Argon2, SHA-256, HMAC | 業界標準 |
| 監視 | Prometheus | 20+ メトリクス |
| MCP | rmcp 0.1 (SSE) | MCP 2024-11-05 準拠 |
8. 今後の展望
現在 mcp.gd は SaaS として一般公開しており、無料プラン(10GB)からビジネスプラン(月額 $100)まで段階的なプランを提供している。今後は以下の方向で拡張を検討している。
- Streamable HTTP トランスポート: 現在の SSE トランスポートに加え、MCP の新しいトランスポート仕様への対応
- チーム機能の拡張: 組織単位でのフォルダ共有・権限管理の強化
- エッジキャッシュ: グローバル展開に向けた CDN レイヤの追加
本プロジェクトについて: mcp.gd は、企画・設計・実装・インフラ構築・運用・SaaS としての一般公開まで、全工程を一人で遂行したプロジェクトである。50件のサービスを単独で開発・保守した実務経験から課題を抽出し、それを解決するプロダクトとして設計した。
IPv6設定方法: Dedibox(Scaleway)
Dedibox(Scaleway)でIPv6を設定する方法
Dedibox(Scaleway)の専用サーバーでIPv6を有効化する手順を解説します。
前提条件
必要な情報
コントロールパネルから以下の情報を確認してください。
| 項目 | 例 |
|---|---|
| IPv6プレフィックス | 2001:db8:xxxx:xxxx::/64 |
| DUID | 00:03:00:01:xx:xx:xx:xx:xx:xx |
設定手順
1. ネットワークインターフェース名の確認
ip link show
出力例:
2: enp0s20: <BROADCAST,MULTICAST,UP,LOWER_UP> ...
この例では enp0s20 がインターフェース名です。環境によって eth0、eno1 などの場合があります。
2. DHCPv6クライアントの設定
/etc/dhcp/dhclient6.conf を作成または編集します。
cat > /etc/dhcp/dhclient6.conf << 'EOF'
interface "enp0s20" {
send dhcp6.client-id 00:03:00:01:xx:xx:xx:xx:xx:xx;
}
EOF
注意: インターフェース名とDUIDは自身の環境に合わせて変更してください。
3. ネットワークインターフェースの設定
/etc/network/interfaces にIPv6静的アドレスを追加します。
cat >> /etc/network/interfaces << 'EOF'
iface enp0s20 inet6 static
address 2001:db8:xxxx:xxxx::1/64
EOF
4. DHCPv6クライアントのsystemdサービス作成
/etc/systemd/system/dhclient.service を作成します。
cat > /etc/systemd/system/dhclient.service << 'EOF' [Unit] Description=dhclient for sending DUID IPv6 After=network-online.target Wants=network-online.target [Service] Restart=always RestartSec=10 Type=simple ExecStartPre=-/sbin/ip -6 addr add 2001:db8:xxxx:xxxx::1/64 dev enp0s20 ExecStart=/sbin/dhclient -cf /etc/dhcp/dhclient6.conf -6 -P -d enp0s20 ExecStartPost=-/sbin/ip -6 addr add 2001:db8:xxxx:xxxx::1/64 dev enp0s20 ExecStop=/bin/kill -TERM $MAINPID [Install] WantedBy=network.target EOF
5. IPv6アドレス維持用タイマーの作成
DHCPv6クライアントがアドレスを上書きする場合があるため、定期的にアドレスを確認するタイマーを設定します。
/etc/systemd/system/ipv6-static.service:
cat > /etc/systemd/system/ipv6-static.service << 'EOF' [Unit] Description=Ensure static IPv6 address After=network-online.target dhclient.service Wants=network-online.target [Service] Type=oneshot ExecStart=/sbin/ip -6 addr add 2001:db8:xxxx:xxxx::1/64 dev enp0s20 RemainAfterExit=yes [Install] WantedBy=multi-user.target EOF
/etc/systemd/system/ipv6-static.timer:
cat > /etc/systemd/system/ipv6-static.timer << 'EOF' [Unit] Description=Ensure static IPv6 address periodically [Timer] OnBootSec=10s OnUnitActiveSec=30s [Install] WantedBy=timers.target EOF
6. サービスの有効化と起動
# systemdの再読み込み systemctl daemon-reload # DHCPv6クライアントの有効化・起動 systemctl enable dhclient.service systemctl start dhclient.service # IPv6アドレス維持タイマーの有効化・起動 systemctl enable ipv6-static.timer systemctl start ipv6-static.timer systemctl start ipv6-static.service
7. 動作確認
IPv6アドレスの確認:
ip -6 addr show
期待される出力:
2: enp0s20: <BROADCAST,MULTICAST,UP,LOWER_UP> ...
inet6 2001:db8:xxxx:xxxx::1/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::xxxx:xxxx:xxxx:xxxx/64 scope link
valid_lft forever preferred_lft forever
IPv6接続のテスト:
ping6 -c 3 2001:4860:4860::8888
成功例:
64 bytes from 2001:4860:4860::8888: icmp_seq=1 ttl=118 time=0.9 ms
トラブルシューティング
IPv6アドレスが設定されない
手動でアドレスを追加してみてください。
ip -6 addr add 2001:db8:xxxx:xxxx::1/64 dev enp0s20
pingが通らない
ルーティングテーブルを確認します。
ip -6 route show
デフォルトルートが存在するか確認してください。
default via fe80::xxxx:xxxx:xxxx:xxxx dev enp0s20 proto ra ...
DHCPv6サーバーから応答がない
dhclientのログを確認します。
journalctl -u dhclient.service -f
「Solicit」が繰り返し送信されているが応答がない場合、プロバイダ側の設定を確認してください。静的設定でIPv6は動作します。
サービスの状態確認
systemctl status dhclient.service systemctl status ipv6-static.timer
まとめ
Dediboxでは、DHCPv6を使用してDUIDをプロバイダに通知することで、割り当てられたIPv6プレフィックスが有効化されます。DHCPv6サーバーからの応答がない環境でも、静的アドレス設定とDHCPv6クライアントを併用することでIPv6接続が可能です。
参考情報
claude codeに`claude`コマンドを使ったアプリケーションを開発させる
claude codeを使い始めた理由
仕事で四半期以上、バイブコーディングをしてきました。
そう聞くと低レベルな人に聞こえてきますが、四半期で計45プロジェクト(44プロジェクトまでできました)を1人で完成させ、ドキュメントも作り、上長レビューからの仕様変更指摘もされるという仕事をしました。
また、このプロジェクトでは言語問わず、PythonからPHP、go、Shell Script、C言語まであらゆる言語を使って、新規開発をするという目まぐるしいプロジェクトでした。C言語でhttpサーバを作った時は死ぬかと思いました。
ひたすらスタートアップ企業の開始を繰り返されるような仕事です。
初期はChatGPTを使って、何とか凌いでいましたが、claude codeを使うようになって、手放せなくなりました。
ChatGPTのcodexやgemini codeも使いましたが、目標が何も決まっていない、仕様書が無い環境下ではclaude codeが使いやすいです。codexやgemini codeは仕様書に沿った、決まったコードを書くのは得意なのですが、仕様が決まっていない、その場で仕様変更を次々を行うような開発では役に立たなかったです。
主にclaude codeの強いと思ったのが、割り込みチャットによる仕様変更です。全体像が全く見えない中、出来上がっていくプロジェクトに対して、仕様書を更新し続け(CLAUDE.md)、別の方向へ向かいそうになったら、割り込みチャットで方向性を修正していく。最終的にドキュメントのひな型を作ってもらい、それを元にドキュメントを作成する。
この手法にて、3日連続で、2プロジェクトを完成させリリースさせたこともあります。
こういった事から、個人プロジェクトでもclaude codeを使うようになりました。
コミュ障というのもあり、何をやっているのか上長と先輩社員以外から誰にも理解されていない状況には絶望していますが...
個人開発でのclaude code
異常なプロジェクト数を考えれば、狂ってると思いますが、省庁で夜中の0時まで残業が当たり前だった前職に比べ、最大でも21:00までには帰れという別部署からの視線があり、上長がいる際には19:00頃に帰宅し、希望するなら18時に帰ることが出来、家に仕事を持ち込むなという素晴らしい雰囲気があります。基本土日休日は18時間睡眠を取るので時間がありませんが、会社から帰って1-2時間の個人時間が取れるようになりました。
個人時間で資格勉強しろと言われていますが、上長もやってないから「まぁできたら~」という緩い感じがあり、ついつい仕事の延長戦として個人開発に時間をとるようになりました。
何を開発したかは記載できませんが、まずgitの管理をclaudeに任せました。そのうえで、claude codeの入力から自動的に何をしたいのが自動判別できるようにCLAUDE.mdを成長させました。現在では、URLを入れるだけで、修正作業なのか、追加作業なのか自動判別してあとはお任せで運用・保守を任せるといったことまでできるようになりました。
私はバグを発見してclaude codeに報告をするだけの作業になり、その作業自体もある程度であれば自動検知するようにしています。
その他にも、claudeにroot権限を渡して、サーバのパフォーマンスチューニングをさせたり、rclonの保存先パスを入力するだけで自動的に毎日バックアップをしてくれるsystemを作成して、毎日バックアップするようにsystemを書いてもらったりと、個人でもできますが、15~30分程度でパパっと作業してくれるので重宝しています。
本題の claude code で claudeコマンドを使ったアプリケーションを開発させる
OpenAIのAPIを使用したアプリケーションを開発していましたが、追加の従量課金のためコストがかかっていました。
そこで、claude code の プロンプトで、「claudeバッチコマンドを使用したアプリケーションを組み込み開発してください」と記載することで、さらに自動が可能になります。
特に、「claudeコードを用いてフィードバックを行い、システムの精度を上げてください。」これはかなり強力なプロンプトです。claude codeからclaudeバッチを実行して、その結果からさらにシステムの精度を上げていきます。
claudeバッチを使いまくると使用量が爆増するので、ある程度のタイミング図り行う必要があります。
移行手順: XenからProxmoxへ
XCP-ng (Xen Hypervisor) + Xen Orchestra から Proxmox に移行する方法
Xen サーバから、Proxmoxへの移行を依頼され、移行に成功したので手順を残しておきます。
Xen Orchestra の管理画面から、現在起動してるサーバのイメージファイルを「xva」形式でダウンロードすることが出来る。
この xva ファイルを img ファイルに変換する。
img ファイルをproxmox上にアップロードする。アップロード先は「root」のカレントディレクトリ(~/)で問題ない。
local の容量を増やす方法
「root」上のディスクをProxmox上ではlocalと呼んでおり、vmのディスクファイルを保存するディスクはlocal-lvmと呼んでいる。(インストール時にZFS等を選んだ場合はlocal-lvmではないかもしれない)
localのデフォルトのディスクサイズが100GB。imgファイルが100GB超える場合は、localのサイズを増やす必要がある。local-lvmに何も入っていない状況(VMが一つもない場合)であることが条件。
以下のコマンドでlocal-lvmを削除して、小さいサイズで作り直す。
# local-lvmを削除する $ lvremove /dev/pve/data # サイズを減らして作成 ( 500GiB) $ lvcreate --type thin-pool --size 500G --name data pve # 確認 $ lvs -a
ディスクが空いた分、localのサイズを拡張する
$ vgs VG pve VSize <890.01g VFree <213.01g # pve-root に +213GiB 割当てる場合 $ lvextend -L +213G /dev/pve/root # ext4ファイルシステム拡張 resize2fs /dev/mapper/pve-root
これで、「root」のカレントディレクトリ(~/)に img ファイルをアップロードできる。
ディスクの書き込みとサーバの立ち上げ
Proxmox 側のネットワークとストレージ以外を作成する サーバにアップロードしたイメージをlocal-vmに書き込む
qm create 100 --name s3ij1nn --memory 16384 --cores 4 qm importdisk 100 s3ij1nn.xva-0.img local-lvm
100はvm id
ディスクの接続と、ネットワークアダプタの追加
該当のvmのハードウェア設定を確認し、unuse diskとしてインポートしたディスク表示されているので、SATA等で接続する。
ネットワークアダプタを追加する。 ネットワークアダプタはデフォルトのe1000で問題なし。
起動する
コンソール画面からの設定で、ネットワーク設定を見直す。 XCP-ng でのネットワークインターフェース名はeth0に対して、Proxmoxのネットワークインターフェース名は違うので、Ubuntuのnetplanで静的IPを指定している場合は、インターフェース名を変更する。
完全移行完了
ユーザ権限でLinuxBrewをインストールする
昔流行ったShell Hosting
Shell Hostingは、ユーザに管理者権限を与えないが、ユーザ権限でLinuxマシンへのアクセスを販売するサービスを指します。
その代わりに、Webページのスペース、大容量のストレージ、大規模な回線を共有することが出来、非常に便利です。
お察しの通り、90's-00's に流行ったホスティングサービスで、今はVPSのような環境を完全に区切ることで、環境内での管理者権限を貰うことが出来るサービスの勃興により、ほぼほぼ廃れたと言っても構わないでしょう。
SeedBoxによって復活した Shell Hosting 業
ところが、一部のSeedBox等ではユーザのダウンロード環境のリソースを共有する為に、Shell Hostingを提供している場合があります。
いわゆる、Shell付きSeedBoxと呼ばれるものです。
これらのSeedBox系のShell Hostingで個人的に愛用しているサービスでは「10Gbps以上」「1TB~」のリソースを借りることが出来、データの中継地点としてPythonで軽く処理してから外部へデータの送信といった処理に使用することが出来ます。
しかしながら、ユーザ権限でできる処理は限られています。
例えば、ちょっとしたコンパイルの為に「cmake」の最新版を使用したいと考えていても、ユーザ権限ではパッケージ管理システムやレポジトリへのアクセスが出来ません。(root奪取するのはダメですよ)
Linuxのユーザ権限で管理できるパッケージ管理
そんな中、ユーザ権限で実行できる パッケージ管理システムがあります。
Macユーザにはおなじみのbrewです。brew ではsudo へアクセスできないユーザ向けに、ホームフォルダ下にレポジトリからダウンロードし、ホームフォルダ下のバイナリを実行できる環境を作成することが出来る機能があります。
また、BrewはLinux向け対応した、LinuxBrewという機能があります。
これらを組み合わせることで、ShellHosting上で最新のバイナリにアクセスできるようになります。
LinuxBrewのインストール
さあ、LinuxBrewをインストールするぞと久しぶりにインストールを試してみましたが、ユーザ権限の自動インストールがなくなっていました。

ユーザ権限で実行する方法はUnofficial 扱いになりました。
そのため、この記事を書く気になりました。
インストール手順
インストールを行う方法以下の手順となります。
git clone https://github.com/Homebrew/brew ~/.linuxbrew/Homebrew mkdir ~/.linuxbrew/bin ln -s ~/.linuxbrew/Homebrew/bin/brew ~/.linuxbrew/bin eval $(~/.linuxbrew/bin/brew shellenv)
次回、実行した際に、自動的にbrewを読み込むように設定します。
echo "eval $(~/.linuxbrew/bin/brew shellenv)">>~/.bash_profile もしくは echo "eval $(~/.linuxbrew/bin/brew shellenv)">>~/.bashrc
最後に、brewを起動して動くか試しましょう。
brew
サーバにrubyが入っていない場合はポータブルRubyをダウンロードしてから実行してくれます。

良い、Shell Hosting ライフを!
AbuseIPDBを活用したSSHブルートフォースアタックの報告手順
AbuseIPDBへsshのブルートフォースアタックを報告する方法
1. AbuseIPDBアカウント作成とAPIキー取得
2. 必要なパッケージのインストール
apt update apt install curl jq fail2ban
3. Fail2Banの設定
Fail2Banを設定して、AbuseIPDBに攻撃者のIPアドレスを報告するようにする。
/etc/fail2ban/jail.localファイルを作成または編集する。
nano /etc/fail2ban/jail.local
- 以下の内容を追加する。
[DEFAULT] bantime = 1h findtime = 10m maxretry = 5 [sshd] enabled = true port = ssh logpath = %(sshd_log)s backend = %(sshd_backend)s
4. Fail2Banのアクションスクリプト設定
abuseipdb-action.confというファイルを/etc/fail2ban/action.d/に作成。
nano /etc/fail2ban/action.d/abuseipdb-action.conf
[Definition] actionstart = actionstop = actioncheck = actionban = curl -G https://api.abuseipdb.com/api/v2/report \ --data-urlencode "ip=<ip>" \ --data-urlencode "categories=18,22" \ --data-urlencode "comment=Fail2Ban report from Proxmox server" \ -H "Key: YOUR_API_KEY" \ -H "Accept: application/json" actionunban =
- Fail2Banのjail.localファイルに新しいアクションとして適用する
nano /etc/fail2ban/jail.local
[sshd]セクションに以下の行を追加する
action = %(action_mw)s abuseipdb-action
5. Fail2Banの再起動
設定を適用するためにFail2Banを再起動する。
systemctl restart fail2ban
6. 設定の確認
Fail2Banが正常に動作しているか確認する。
fail2ban-client status fail2ban-client status sshd
Googleが潰れるかもしれない
Web広告業界の危機について
最近、広告業界が危機に瀕しているのではないかと感じることが多くなりました。技術的な内容が多いため、ここでその詳細を説明します。
現在のWeb広告業界が直面している問題点は以下の5つです。
- ブラウザの最大手Google(Chromium)がサードパーティCookieを廃止し、不正クリックの検知が難しくなった。
- AD-BLOCKの普及により、正規のユーザの減少。
- 広告型URL短縮サービスによる不正クリックの増加。
- ChatGPT等のLang-chainによる記事の水増しが簡単になり、広告設置運用が容易に。
- ウクライナ紛争の寄付金広告バブルでGoogleが気付いていない上、AI開発に集中。
これらの問題点を順に説明していきます。
1. サードパーティCookieの廃止
Google Analyticsや日本ヤフーのタグサービスは、広告をクリックした後の購入効果を確認するために作られました。これらはサードパーティCookieを用いて運用され、ユーザの行動をトラッキングして分析していました。しかし、「Do not evil」を掲げるGoogleは、この技術の悪用を防ぐためにサードパーティCookieの廃止を決定しました。これにより、広告効果の分析が難しくなり、不正クリックの検知も困難となっています。
2. AD-BLOCKの普及
詐欺広告が増えすぎた結果、FBIが「ad-blockの導入を勧める」と発表する事態にまでなりました。広告まみれのメディアは自社ブランドを毀損するリスクを抱えながらも、他サイトの真似をして広告を増やし続けています。これにより、ますますad-blockユーザが増加し、広告の効果が減少しています。
FBIが推奨「広告ブロッカーを利用して」 | ライフハッカー・ジャパン
3. 広告型短縮URLサービスの不正クリック
最近では、仮想通貨系お小遣いサイト(通称:Faucet)で、short linkを通ってアクセスすると報酬がもらえるサービスが増えています。しかし、これらのサービスは不正クリックを要求するものが多く、ポップアップだらけのサイトもしくは、不正クリックを促すことが一般的になっています。

4. ChatGPT等のLang-Chain系で記事の水増しが可能
ChatGPTを利用して、記事を大量に生成し、それらを用いて広告を設置する手法が増えています。これにより、不正クリックを誘導するサイトが増加し、広告の正当性が損なわれています。

5. ウクライナ紛争の寄付金広告バブルとAI開発の集中
Googleの最大収益源は広告とAndroidのアプリストアです。しかし、Androidアプリストアの収益はアプリ内広告経由の収益の方が高いです。これにより、Web広告業が衰退しても、Googleは他の収益源で補うことができます。しかし、LANG-Chain技術の進展により、今後Androidの不正操作が増える可能性があります。
以上の理由から、広告業界が破綻した際にGoogleがどのような動きをするかは予測が難しいです。なるべく早い段階から、脱Googleを考え始めた方が良いかもしれません。
個人的には、地図アプリはゼンリン公式を使い、検索サービスやメールサービスはselfhosted系を使用しています。