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 が不在の環境では、scprsync による手動転送が唯一の選択肢であり、これがイテレーション速度を制約していた。

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つの能力だった。

  1. AI エージェントが自律的に読み書きできる永続ストレージ
  2. ローカル・開発・本番の環境を跨いで共有できるファイルシステム
  3. 人間の介在なしにプログラマティックにアクセス可能な 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 がインターフェース名です。環境によって eth0eno1 などの場合があります。

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/interfacesIPv6静的アドレスを追加します。

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接続が可能です。

参考情報

  • インターフェース名: ip link show で確認
  • IPv6アドレス: ip -6 addr show で確認
  • IPv6ルート: ip -6 route show で確認
  • DHCPv6ログ: journalctl -u dhclient.service で確認

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 ファイルに変換する。

github.com

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 へアクセスできないユーザ向けに、ホームフォルダ下にレポジトリからダウンロードし、ホームフォルダ下のバイナリを実行できる環境を作成することが出来る機能があります。

また、BrewLinux向け対応した、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キー取得

  1. AbuseIPDBにアクセスし、アカウントを作成。
  2. ログイン後、APIキーを取得。

2. 必要なパッケージのインストール

apt update
apt install curl jq fail2ban

3. Fail2Banの設定

Fail2Banを設定して、AbuseIPDBに攻撃者のIPアドレスを報告するようにする。

  1. /etc/fail2ban/jail.local ファイルを作成または編集する。
nano /etc/fail2ban/jail.local
  1. 以下の内容を追加する。
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5

[sshd]
enabled = true
port    = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s

4. Fail2Banのアクションスクリプト設定

  1. abuseipdb-action.conf というファイルを /etc/fail2ban/action.d/ に作成。
nano /etc/fail2ban/action.d/abuseipdb-action.conf
  1. 以下の内容を追加(API_KEYは自身のAPIキーに置き換え)
[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 =
  1. Fail2Banのjail.localファイルに新しいアクションとして適用する
nano /etc/fail2ban/jail.local
  1. [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つです。

  1. ブラウザの最大手GoogleChromium)がサードパーティCookieを廃止し、不正クリックの検知が難しくなった。
  2. AD-BLOCKの普及により、正規のユーザの減少。
  3. 広告型URL短縮サービスによる不正クリックの増加。
  4. ChatGPT等のLang-chainによる記事の水増しが簡単になり、広告設置運用が容易に。
  5. ウクライナ紛争の寄付金広告バブルで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系を使用しています。