mcpField
S
server-checkup

server-checkup

github.com/spm1001クラウド・DevOps49 回インストール
リポジトリ

server-checkup について

server-checkupは、Linuxサーバーの設定、監査、保守を体系的に進めるスキルです。変更前の基準記録、リスク評価、事後確認、保守記録の作成を段階的に行います。

主な機能

  1. 01基準状態の記録と変更後の比較
  2. 02SSHとネットワークのセキュリティ監査
  3. 03保守設定と自動アップグレードの確認
  4. 04必要に応じたTailscaleの検証
  5. 05リスク評価とクリーンアップ案
  6. 06保守レポートの作成

活用シーン

  1. 01SSHとファイアウォール設定の監査
  2. 02新しいLinuxサーバーやPiの設定
  3. 03大きな変更の前に行うサーバー確認
  4. 04保守結果の記録

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/spm1001/trousse --skill server-checkup

インストール後、Claude Code で/server-checkupを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

README.md
references/
packages-to-remove.md
ssh-hardening.md
terminal-compat.md
unattended-upgrades.md

詳細

サーバーのメンテナンス

自律的な実行、リスク評価、ドキュメント化を伴う、体系的な Linux サーバー管理です。

使用する場面

  • 新しいサーバーまたは Pi をセットアップするとき
  • セキュリティ監査またはセキュリティ強化を行うとき
  • 既存のインフラストラクチャのヘルスチェックを行うとき
  • 大規模な変更の前後(ベースライン → 検証)
  • 再フラッシュ後の設定

使用しない場面

  • Linux 以外のシステム(macOS、Windows)
  • クラウド管理サービス(プロバイダーのツールを使用)
  • 手早く済ませる単発のコマンド(そのまま実行してください)

実行モード

インタラクティブモード(デフォルト)

Claude が各フェーズを実行し、調査結果を報告して、修正について判断を求めます。

自動モード(上級)

各フェーズにサブエージェントを自動的に起動します。より高速ですが、制御性は低くなります。

自動モードのトリガー:「full server audit」または「audit thoroughly」

部分監査
  • 「security audit: 」 → フェーズ 0、2 のみ
  • 「setup maintenance: 」 → フェーズ 0、3 のみ
  • 「tailscale check: 」 → フェーズ 0、4 のみ

フェーズのワークフロー

フェーズ 0:コンテキストの確認(新規)

まず既存のドキュメントを確認してください:

  1. サーバー固有のドキュメントを探します:

    ls -la | grep -iE '(server|setup|readme|hostname)\.md'
    ls -la .claude/CLAUDE.md 2>/dev/null
    
  2. 見つかった場合は、読み込んで以下を抽出します:

    • 稼働しているべきサービス
    • 想定される設定(ポート、パス、バージョン)
    • 既知の問題や特記事項
    • 過去のメンテナンス履歴
    • 意図が分かるセットアップ手順
  3. 検証用のコンテキストを保持します:

    • 実際の状態とドキュメントに記載された状態を比較する
    • 相違点を調査結果として報告する
    • 正常な設定として確認済みの内容を反映する

例: ドキュメントに「04:00 に再起動」とあるのに、設定が「02:00」になっている場合は、確認が必要な点として報告します。

フェーズ 1:接続と初期評価

重要:変更を行う前に、まずベースラインを記録します:

echo "=== BASELINE $(date +'%Y-%m-%d %H:%M') ===" | tee /tmp/server-baseline.txt
echo "Memory:" | tee -a /tmp/server-baseline.txt
free -h | tee -a /tmp/server-baseline.txt
echo -e "\nDisk:" | tee -a /tmp/server-baseline.txt
df -h / | tee -a /tmp/server-baseline.txt
echo -e "\nPackages:" | tee -a /tmp/server-baseline.txt
dpkg -l | grep -c '^ii' | tee -a /tmp/server-baseline.txt
echo -e "\nServices:" | tee -a /tmp/server-baseline.txt
systemctl list-units --type=service --state=running --no-pager | wc -l | tee -a /tmp/server-baseline.txt

システムの調査:

  1. エラーを確認します:

    # Without sudo (may fail, that's ok)
    dmesg 2>/dev/null | grep -iE 'error|fail|warn' | tail -20
    
    # With sudo if needed
    sudo dmesg | grep -iE 'error|fail|warn' | tail -20
    
  2. ハードウェアと OS:

    uname -a && cat /etc/os-release | head -5
    free -h && df -h /
    dpkg -l | grep -c '^ii'  # package count
    
  3. 初期評価:

    • 通常と異なるエラーを記録する
    • ディスク容量が懸念される状態か確認する(80% 超)
    • メモリが懸念される状態か確認する(空きが 500MB 未満)
フェーズ 2:セキュリティ監査

SSH の設定:

grep -E '^(Password|PermitRoot|X11)' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/* 2>/dev/null | grep -v '^#'

目標の状態:

  • PasswordAuthentication no ✅
  • PermitRootLogin no ✅
  • X11Forwarding no ✅(ヘッドレスサーバー)

sudo の設定:

sudo ls -la /etc/sudoers.d/

ネットワークの外部公開状況:

# Listening ports (external only)
ss -tlnp 2>/dev/null | grep -v '127.0.0' | grep -v tailscale

# Firewall status
sudo systemctl status ufw 2>&1 | head -5 || sudo iptables -L -n | head -10

セキュリティスコアリング(自動適用):

調査結果リスクレベル修正コマンド
パスワード認証が有効重大echo "PasswordAuthentication no" | sudo tee -a /etc/ssh/sshd_config.d/99-hardening.conf && sudo systemctl reload sshd
root ログインが有効重大echo "PermitRootLogin no" | sudo tee -a /etc/ssh/sshd_config.d/99-hardening.conf && sudo systemctl reload sshd
ファイアウォールなし + ポートフォワーディングあり + 外部公開高ufw をインストール:sudo apt install ufw
ファイアウォールなし + NAT 配下 + VPN のみ低ルーターと VPN によって保護されています
ヘッドレス環境で X11Forwarding が有効中echo "X11Forwarding no" | sudo tee -a /etc/ssh/sshd_config.d/99-hardening.conf && sudo systemctl reload sshd
フェーズ 3:メンテナンスの設定

unattended-upgrades を確認します:

dpkg -l unattended-upgrades 2>&1 | grep '^ii'

インストールされていない場合: sudo apt install unattended-upgrades

設定を確認します:

sudo grep -E '^(Unattended-Upgrade::(Allowed-Origins|Remove|Automatic-Reboot))' /etc/apt/apt.conf.d/50unattended-upgrades | head -20

目標の設定:

  • セキュリティ更新だけでなく、すべてのパッケージを対象にする — references/unattended-upgrades.md を参照
  • 時刻を指定して自動再起動を有効にする
  • 使用していないパッケージを削除する
  • カスタムリポジトリ(Tailscale、Plex など)を含める

サービスを確認します:

systemctl status unattended-upgrades --no-pager | head -8

再起動時刻の設定がコメントアウトされていないことを確認します:

sudo grep "Automatic-Reboot-Time" /etc/apt/apt.conf.d/50unattended-upgrades
フェーズ 4:Tailscale(該当する場合)

Tailscale がインストールされているか確認します:

which tailscale && tailscale version || echo "Not installed"

インストールされている場合は、ステータスを確認します:

tailscale status --self 2>&1 | head -3
tailscale status 2>&1 | grep -E 'exit node|subnet' | head -5

IP フォワーディングの設定が保持されていることを確認します:

cat /etc/sysctl.d/99-tailscale.conf 2>/dev/null

以下が含まれている必要があります:

net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1

セットアップ後の注意: 常時稼働ノードについては、管理コンソールでキーの有効期限を無効にしてください。

フェーズ 5:クリーンアップ

不要なパッケージを特定します:

dpkg -l | grep -E '^ii.*(man-db|bluetooth|bluez|avahi|pulseaudio|alsa)' | awk '{print $2}' | sort

不要なサービスを確認します:

systemctl list-unit-files | grep enabled | grep -E '(bluetooth|avahi|serial-getty)'

ヘッドレスサーバーでよく削除される項目:

パッケージ/サービス削除する理由リスクコマンド
man-dbman ページの再構築により apt の更新が遅くなります低sudo apt remove --purge -y man-db
avahi-daemonTailscale/静的 IP を使用する場合、mDNS は不要です低sudo systemctl disable --now avahi-daemon.service avahi-daemon.socket
bluetooth packagesサーバーでは使用しません低ライブラリは残し、実行中の場合はデーモンを削除します
serial-gettyヘッドレス環境では不要です低sudo systemctl disable serial-getty@ttyS0

サブエージェントの判断基準:

シナリオサブエージェントを使用するか理由
1~2 個のパッケージを削除する❌apt remove | tail -10 を使用します
5 個以上のパッケージを削除する✅詳細な出力でコンテキストを使い果たします
1~2 個のサービスを確認する❌直接コマンドを実行すれば十分です
サービス全体を監査する✅大量の解析が必要です

ルール: 操作で 200 行を超える出力が生成される場合は、サブエージェントを使用します。

重要:コンテキストを使い果たさないよう、簡潔な出力を使用してください:

# Good - terse
sudo apt remove -y pkg1 pkg2 pkg3 2>&1 | tail -10

# Bad - verbose
sudo apt remove -y pkg1 pkg2 pkg3  # Full output
フェーズ 6:検証

ベースラインと比較します:

echo -e "\n=== AFTER $(date +'%Y-%m-%d %H:%M') ===" | tee -a /tmp/server-baseline.txt
free -h | grep "Mem:" | tee -a /tmp/server-baseline.txt
df -h / | tail -1 | tee -a /tmp/server-baseline.txt
dpkg -l | grep -c '^ii' | tee -a /tmp/server-baseline.txt
systemctl list-units --type=service --state=running --no-pager | wc -l | tee -a /tmp/server-baseline.txt

主要なサービスを確認します:

systemctl list-units --type=service --state=running --no-pager | grep -E 'ssh|tailscale|docker|NetworkManager|unattended'

最終概要:

echo "=== Memory ===" && free -h | head -2
echo "=== Disk ===" && df -h /
echo "=== Packages ===" && dpkg -l | grep -c '^ii'

改善点を示します:

  • 解放したメモリ
  • 節約したディスク容量
  • 削除したパッケージ
  • 無効化したサービス
フェーズ 7:レポートの生成(新規)

メンテナンス記録を作成します:

オプション A:既存のサーバードキュメントに追記する(フェーズ 0 で見つかった場合)

## Maintenance History

### YYYY-MM-DD: <Brief Summary>

**Findings:**
- [Risk Level] Finding description
  - Fixed: command/action taken

**Changes Applied:**
- Security: X11 disabled, SSH hardened
- Cleanup: Removed N packages, disabled M services
- Performance: Freed XGB RAM, XGB disk

**System Health:**
- Memory: X available
- Disk: X% used
- Services: N running
- Uptime: N days

オプション B:新しいメンテナンスレポートを作成する

MAINTENANCE-YYYY-MM-DD.md として保存します:

# Server Maintenance: <hostname>
Date: YYYY-MM-DD
Auditor: Claude Code

## Executive Summary
- **Overall Risk:** Low/Medium/High
- **Findings:** N total (X critical, Y high, Z medium)
- **Time to Fix:** ~N minutes
- **Changes Applied:** N fixes

## Critical Issues
[Auto-populated from Phase 2 findings with CRITICAL/HIGH risk]

## Security Audit
- SSH: ✅/⚠️
- Firewall: ✅/⚠️
- Services: ✅/⚠️

## Maintenance Setup
- Unattended-upgrades: ✅/⚠️
- Auto-reboot: ✅/⚠️
- Custom repos: ✅/⚠️

## Changes Applied
[Commands run with output summary]

## System Health
**Before:**
- Memory: X available
- Disk: X% used
- Packages: N installed

**After:**
- Memory: X available (+Y freed)
- Disk: X% used (+Y freed)
- Packages: N installed (-Y removed)

## Services Inventory
[What's running and why - from Phase 0 context + discovery]

## Recommendations
[Remaining issues sorted by risk level with fix commands]

ユーザーに確認します:「既存の .md に追記しますか、それとも新しい MAINTENANCE-.md を作成しますか?」

判断ロジックとリスク評価

自動リスク評価

各検出事項は自動的に評価されます:

リスクの評価軸:

  1. セキュリティへの影響: システムが危険にさらされますか?
  2. 影響範囲: ローカル、ネットワーク、インターネットのいずれに公開されていますか?
  3. 悪用の難易度: 容易(リモート)ですか、それとも困難(ローカルのみ)ですか?

リスクレベル:

レベル基準対応期限
重大リモートからの悪用が可能で、特権アクセスを伴う直ちに修正
高公開されており、セキュリティ対策が欠けている今日中に修正
中不要な攻撃対象領域があり、公開範囲は限定的今週中に修正
低最適化であり、リスクは最小限任意でクリーンアップ
判断ツリーの例

ファイアウォールの評価:

IF no_firewall AND (port_forwarding OR dmz_host):
  IF tailscale_only_access:
    RISK = MEDIUM  # VPN provides some protection
  ELSE:
    RISK = HIGH    # Direct internet exposure
ELSE IF no_firewall AND behind_nat AND no_port_forwarding:
  RISK = LOW       # Router provides basic protection

サービスの評価:

IF service_running AND service_name IN unnecessary_list:
  IF service_listening_externally:
    RISK = MEDIUM  # Unnecessary exposure
  ELSE IF service_localhost_only:
    RISK = LOW     # Just resource waste

コンテキスト管理

問題: apt の出力、サービス一覧、パッケージの照会結果により、通常の操作中にコンテキストを使い果たします。

解決策:

1. 簡潔な出力(常に)
# Good
apt remove pkg 2>&1 | tail -10
dpkg -l | grep -c '^ii'

# Bad
apt remove pkg  # Full output
dpkg -l         # List all packages
2. サブエージェント(詳細な出力を伴う操作の場合)

使用する場面:

  • 5 個以上のパッケージを削除するとき
  • すべての systemd サービスを監査するとき
  • 大きなログファイルをスキャンするとき
  • セキュリティスキャンを全面的に実行するとき

例:

Use Task tool with subagent_type=Explore for package removal when >5 packages
3. ベースラインの取得(変更前)

初期状態を保存し、変更後に比較して改善を確認します。

4. 複数コマンドの一括実行
# Good - one command
sudo apt remove -y pkg1 pkg2 pkg3 pkg4 pkg5

# Bad - five commands
sudo apt remove -y pkg1
sudo apt remove -y pkg2
...

クイックリファレンス

パスワードなしの sudo
echo "<user> ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/010_<user>-nopasswd
sudo chmod 440 /etc/sudoers.d/010_<user>-nopasswd
SSH の強化設定
cat <<'EOF' | sudo tee /etc/ssh/sshd_config.d/99-hardening.conf
PasswordAuthentication no
PermitRootLogin no
X11Forwarding no
EOF
sudo sshd -t && sudo systemctl reload sshd
unattended-upgrades のリポジトリの取得元を確認する
# Check package policy
apt-cache policy <package> | grep -E 'origin|http'

# Check repo metadata
cat /var/lib/apt/lists/*_InRelease | grep -E '^Origin:|^Label:|^Codename:'
不要なサービスを無効化する
sudo systemctl disable --now <service-name>

参考資料

references/ ディレクトリにあります:

  • unattended-upgrades.md - Debian、Tailscale、Plex などのリポジトリ取得元のパターン
  • packages-to-remove.md - ヘッドレスサーバーでよく使われる不要なパッケージ
  • ssh-hardening.md - SSH 設定のパターンと鍵のみの認証
  • terminal-compat.md - SSH 互換性のための Ghostty/terminfo の修正

アンチパターン

アンチパターン問題対策
apt の出力をすべてストリーミングするコンテキストの枯渇| tail-10 またはサブエージェントを使用します
パッケージを1つずつ削除する時間がかかり、冗長ですapt remove pkg1 pkg2 pkg3 を一度に実行します
ベースラインの取得を省略する改善を測定できません変更を加える前に必ず取得します
再起動時刻を忘れる日中にすぐ再起動してしまいますコメントアウトされていないことと、妥当な時刻であることを確認します
変更後に設定を確認する比較できませんまずベースラインを取得し、その後に変更します
変更内容を記録しない後で混乱を招きます保守ドキュメントを必ず作成または更新します

使用例

check this server: kube.lan (user: admin)     # Full audit
security audit: vps01 (user: root)            # Security only
full server audit: production-db              # Auto mode
check this server: kube.lan, skip tailscale   # Skip phase

コメント