WireGuard のアクティビティを起動しても、アプリが前面に来るだけで、特定のトンネルが立ち上がるわけではありません。アプリを開いて待つ自動化は、テストでは通っても、スマートフォンがすでにホーム画面にある最初の場面で失敗します。WireGuard は名前付きトンネル向けにサポートされたリモート制御経路を提供しており、それは多くのレシピが示すより狭いものです。以下のチェックリストは、権限から観測結果までその経路をたどります。

リモート制御が有効か確認する

リモート制御レシーバーは常に待ち受けているわけではありません。WireGuard の設定にはトンネルのリモート制御を有効にするオプションがあり、それがオンになるまでレシーバーは大きな音を立てて失敗する代わりに要求を無視します。既定値がそうなっているのは意図的で、トンネルを立ち上げられる外部公開レシーバーは、アプリを入れたすべての端末でセキュリティホールになるからです。画面から有効にし、何がそれに依存していたかを知らないまま将来の利用者がオフにできる設定なので、そうしたことを書き留めておいてください。

上記のレシーバーが扱うのは名前付きの UP と DOWN 要求だけで、ここにトンネルを作成したり構成を編集したりする経路はありません。頼る前に、そのコンポーネントがインストール済みのビルドに存在することを確認してください(adb shell dumpsys package com.wireguard.android | grep -i receiver は宣言されたレシーバーを一覧表示し、リモート制御レシーバーのないビルドは決して応答しません)。ワークフローが別のエンドポイントや別のピアを必要とするなら、それは別のトンネルであり、アプリ内での別個の手動設定です。

コントローラーが持つ権限を確認する

WireGuard は危険な権限 com.wireguard.android.permission.CONTROL_TUNNELS でレシーバーを保護しており、制御するアプリがそれを持っている必要があります。独自のブロードキャストは、送信側が宣言したことも付与されたこともない権限を作り出すことはできません。ここが、自動化のレシピが自動化にない能力を静かに前提してしまう箇所です。

タスクを書く前に両側を確認してください。一つ目のコマンドは宣言された権限を一覧表示し、二つ目はコントローラーのパッケージが実際にそれを持っているかを示します。マニフェストで権限を宣言していても実行時に付与されていないコントローラーはやはり失敗し、その失敗はダイアログではなく沈黙として現れます。

adb shell pm list permissions -g -d | grep -i control_tunnels
adb shell dumpsys package net.dinglisch.android.taskerm | grep -i control_tunnels

コントローラーが権限を持っていないなら、ブロードキャストを手で組み立てるのではなく、アプリが実際にサポートする連携を使ってください。Intent を送って呼び出しが成功したのを見ても、Android が受け付けたことしか分からず、WireGuard がそれに従って動作したかは分かりません。検証していない送信は成功ではなく不明として扱ってください。

Intent のフィールドをインストール済みアプリと突き合わせる

四つのフィールドが要求全体を担い、それぞれに他とまったく同じに見える失敗の仕方があります。アクション、トンネルの extra、パッケージ、ターゲットを一組として正しく揃えてください。

Action:  com.wireguard.android.action.SET_TUNNEL_UP
Extra:   tunnel:lab-wg
Package: com.wireguard.android
Target:  Broadcast Receiver

アクションは UP か DOWN だけを指定し、extra は設定されたトンネル名を正確に運び、パッケージは配信を WireGuard に限定し、ターゲットはアクティビティではなくレシーバーでなければなりません。綴りを間違えたトンネル名は無効なレシーバーと同じ沈黙を生むので、自動化が壊れていると結論づける前にアプリで名前を読んでください。DOWN のアクションは同じ extra とパッケージを持つ com.wireguard.android.action.SET_TUNNEL_DOWN です。テスト中は一度に一つの要求だけを送ってください(二つのブロードキャストが競合すると、誰も原因を特定できない状態になります)。

同じ要求を端末のシェルから試して、Intent と自動化を切り分けてください。そのコマンドが失敗し Tasker のタスクが成功するなら、違いはフィールドの値ではなく送信側の権限です。

adb shell am broadcast -a com.wireguard.android.action.SET_TUNNEL_UP -e tunnel lab-wg --receiver-permission com.wireguard.android.permission.CONTROL_TUNNELS

トリガーがカバーしない範囲を確認する

アプリの起動や前面化のイベントで接続を要求できますが、そのイベントが処理される前にアプリがすでに名前解決や最初の要求を試みている可能性があります。トリガーはシステムが状態変化に気づいたときに発火し、それはアプリが作業を始めた後です。アプリがトンネル外と決して通信してはならないなら、起動トリガーはブロックの規則ではなく、遅延を足してもそうすることはできません。ブロックの動作にはサポートされた常時接続またはアプリ単位のポリシーを設定し、トリガーは利便性のためだけに残してください。

ブロックの動作はまったく別の場所にあります。adb shell settings get global always_on_vpn_app は常時接続として固定されたパッケージを示し、adb shell dumpsys connectivity | grep -i vpn はシステムが現在追跡している VPN ネットワークを示します。どちらも起動トリガーで代用できるものではありません。

同じ理屈はセッションのもう一方の端にも当てはまります。一つのウィンドウがフォーカスを失ったからトンネルを下ろすと、バックグラウンド作業や認証ヘルパー、接続に頼っていた他のアプリが壊れます。フォーカスの変化ではなく意図したセッション終了を定義し、自動化がコンテキストを切り替えるときに素早い UP と DOWN の連続を避けてください。

送信ではなく結果を確認する

エラーなく戻ってきたブロードキャストは Android に受理されただけで、それ以上ではありません。トンネルの状態はアプリから読み、ワークフローの準備状況は次の手順が実際に必要とするものから読んでください。これは二つの異なる確認であり、一つ目を通っても二つ目を意味しません。

インターフェースの状態も直接読んでください(adb shell ip -brief addr show tun0 はトンネルのインターフェースとアドレスを表示し、アドレスのないインターフェースは上がっていても使えません)。次はプライベートサービス自体の検証で、ハンドシェイクやルートのないトンネルは重要なタスクではやはり失敗します。名前付き接続一つを実際の権限の範囲内で制御する自動化に、インターフェースをタップしたり root コマンドを実行したり Android のネットワーク保護を弱めたりする必要はありません。

関連記事