Mihomo 操作マニュアル

7 分で読了
このページの目次

実接続で流入・domain/IP・一致規則・最終 proxy を追う。設定ファイル、稼働設定、既存接続は異なる時点の状態になり得る。

やりたいこと参照先
設定変更が効かない検証と稼働状態
proxy 選択が違う最初の一致と接続の根拠
透過 gateway 障害入口・DNS・route

稼働ファイルと controller を特定

設定を実行中のインスタンスと照合する

# ExecStart・作業ディレクトリ・上書きを読む
systemctl cat mihomo.service

バイナリと -d/-f を確認する。コンテナ・OpenWrt plugin はその管理元を使い、別設定を systemd から操作しない。

# 主プロセスと最近の起動結果を確認する
systemctl status mihomo.service --no-pager

詳細は journalctl を読む。ファイルの存在だけではこのプロセスが使っている証明にならない。

# 導入した core のバージョンを確認する
mihomo -v

ExecStart と同じバイナリを使う。PATH 上の同名コマンドは別版の場合がある。

# 公開予定の設定ファイルを検証する
mihomo -t -f /opt/mihomo/mihomo_config/config.yaml

実環境のパス・作業場所、特に相対 provider パスに合わせる。エラーを直してから、API・購読・実通信も確認する。

このパスと127.0.0.1:9999 は配置例で既定値ではない。ExecStart の -d/-f と controller・secret を確認する。構文検査は provider・DNS・upstream の可用性を保証しない。

クライアント側で認証を用意してから読む

controller に届くクライアントで実行する。例は localhost:9999。管理された秘密値読込か対話入力で MIHOMO_SECRET を設定し、各要求で空を拒否する。

# 現在の端末で secret を非表示入力する
read -r -s MIHOMO_SECRET

入力後 Enter。秘密値管理器を使うなら重ねて実行しない。作業後は unset MIHOMO_SECRET で shell 変数を消せる。

# controller の識別と API 接続を確認する
curl -fsS -H "Authorization: Bearer ${MIHOMO_SECRET:?Load the controller secret in this shell}" http://127.0.0.1:9999/version

401 は secret、接続拒否は待ち受けを確認する。状態・ヘッダーが必要なら -i を追加する。

# 実行 mode と入口設定を読む
curl -fsS -H "Authorization: Bearer ${MIHOMO_SECRET:?Load the controller secret in this shell}" http://127.0.0.1:9999/configs | jq '{mode,port,"mixed-port": .["mixed-port"],tun}' 

jq が必要。mode・mixed-port・tun を照合する。ファイルと違えば同じ controller か先に確認する。

再読込前に元ファイルを保存し、workdir/SAFE_PATHS 内か確認する。PATCH は元ファイルへの永続保存ではない。force は無効設定を無視する意味ではない。

設定読込と一時 PATCH を分ける

旧ファイルを保存して新版を検証する。path は API クライアントではなく Mihomo ホスト上の場所で、作業場所・SAFE_PATHS 制限を満たす必要がある。

# 検証したファイルを実行中インスタンスへ読み込ませる
curl -fsS -i -X PUT "http://127.0.0.1:9999/configs?force=true" \
  -H "Authorization: Bearer ${MIHOMO_SECRET:?Load the controller secret in this shell}" \
  -H 'Content-Type: application/json' \
  --data '{"path":"/opt/mihomo/mihomo_config/config.yaml"}' 

HTTP 状態の後に GET configs/rules と新接続を確認する。失敗時は旧ファイルを復元し同じ検証・読込を行う。force はエラー無視ではない。

# 一時変更が必要な場合だけ実行 mode を変える
curl -fsS -i -X PATCH http://127.0.0.1:9999/configs \
  -H "Authorization: Bearer ${MIHOMO_SECRET:?Load the controller secret in this shell}" \
  -H 'Content-Type: application/json' \
  --data '{"mode":"rule"}' 

読込後の必須手順ではない。旧 mode を記録し GET で確認する。永続化は管理元設定で行い、復元は旧値を PATCH する。

204 後も稼働設定・規則・新接続を確認する。listener/tunnel の再構成で既存接続に影響し得る。

最初に一致した規則が行先を決める

図を準備しています
例外は広い規則の前か後か

規則は上から最初の一致。api.example.com は完全名と suffix の両方に一致し、DIRECT suffix を先に置くと REJECT 例外が隠れる。

実行規則と接続を照合する

# 読み込まれた規則と順序を読む
curl -fsS -H "Authorization: Bearer ${MIHOMO_SECRET:?Load the controller secret in this shell}" http://127.0.0.1:9999/rules | jq '.rules'

type・payload・対象を比較し、最初の一致が優先される。編集ファイルと違えば再読込を調べる。

# 対象要求を見つけ、実際の選択経路を読む
curl -fsS -H "Authorization: Bearer ${MIHOMO_SECRET:?Load the controller secret in this shell}" http://127.0.0.1:9999/connections |
  jq '.connections[] | {id,source: .metadata.sourceIP,host: .metadata.host,destination: .metadata.destinationIP,port: .metadata.destinationPort,rule,rulePayload,chains}' 

元 IP・宛先・ポート・時刻を照合する。後の厳密操作には id を使う。短命接続は消えるのでログや継続要求で再現する。

# group の現在の選択と候補を読む
curl -fsS -H "Authorization: Bearer ${MIHOMO_SECRET:?Load the controller secret in this shell}" http://127.0.0.1:9999/proxies | jq '.proxies'

PROXY と NODE は実応答から取得する。空白・非 ASCII のパスは URL encode、JSON 値は適切に escape する。

手動選択可能な group だけを変更する

# 確認した Selector group のメンバーを選ぶ
curl -fsS -i -X PUT http://127.0.0.1:9999/proxies/PROXY \
  -H "Authorization: Bearer ${MIHOMO_SECRET:?Load the controller secret in this shell}" \
  -H 'Content-Type: application/json' \
  --data '{"name":"NODE"}' 

旧 now を記録し GET と新接続の chains で確認する。自動 group を Selector として扱わない。保持は profile.store-selected 等の設定次第。

# 直前に確認した一つの接続だけを切る
curl -fsS -i -X DELETE -H "Authorization: Bearer ${MIHOMO_SECRET:?Load the controller secret in this shell}" http://127.0.0.1:9999/connections/CONNECTION_ID

ID は connections から取得する。その通信を中断するため、消失確認後にアプリから再接続する。ID を省くと全接続が対象になる。

規則の group 選択と group の node 選択を分け chains・now を見る。domain 情報は DNS mapping や sniffing 由来で、redir-host が sniffing 限定とは限らない。fake IP は実宛先の public IP ではない。

既存接続は以前の選択を保持し得るので新接続で試す。必要な切断は特定 ID を選ぶ。全 /connections の DELETE を日常更新操作にしない。

明示 proxy と透過入口を分けて試す

明示 proxy を先に検証する

# proxy ホストから明示要求を送る
curl -v --connect-timeout 5 --proxy http://127.0.0.1:7890 https://example.com/

7890 は実行設定に合わせ、rule/chains と照合する。遠隔クライアントの localhost は proxy ホストではない。

# 透過通信の policy route を確認する
ip rule show

実際の gateway で元・mark を調べ、テーブル内容は別途確認する。

# proxy・DNS・controller の待ち受けを確認する
ss -lntup

設定ポートと照合する。ループバック待ち受けは直接には自機用。

# 透過捕捉規則と管理者を読む
sudo nft -a list ruleset

入口・ポート・mark・経路表の対応を確認する。plugin の規則は管理元から変更し、全体を flush しない。

観測次の確認
明示 proxy は成功、LAN は失敗client gateway・DNS・透過捕捉・route を確認
connections に現れないlistener・process・入口とログ。短い接続は終了済みの可能性
規則は正しいが宛先失敗node・protocol・DNS・TLS・service。delay 試験は全宛先の保証でない

Nikki/TUN/TProxy は実設定を確認し port を固定視しない。fail-open は実装時のみ存在し、直結が方針に反する場合もある。復旧後に DNS・TCP・UDP・LAN 例外を確認する。

Mihomo API · Routing rules · DNS · TUN