インターネット越しのWake-on-LAN:ルーターとLinuxサーバーをリモート起動できるように設定する

Networking tutorial - IT technology blog
Networking tutorial - IT technology blog

午前2時の問題:サーバーが落ちていて、あなたはそこにいない

ある火曜日のことだった。オフィスで瞬間的な停電が発生し、UPSが落ちた。電源が復旧したとき、ベアメタルサーバーの1台が戻ってこなかった。そのマシンには自動シャットダウンが設定されていたが、自動起動は設定されていなかった。午前2時47分、私は40キロ離れた場所にいて、誰かが午前6時までにデータベースのリストアを必要としていた。

その夜、私は車で駆けつけた。翌朝、管理していたすべての物理マシンにWake-on-LANを設定した。それ以来、複数の本番環境で活用している——携帯電話から市内の反対側のNAT越しにマシンを起動し、設定さえしっかりすれば一度も失敗したことはない。

Linuxサーバーやホームラボを運用しているなら、リモートWoLは20分でできる設定だ。最初に午前3時に電源トラブルが起きたとき、その価値を証明してくれる。

Wake-on-LANの仕組み

Wake-on-LANは、マジックパケットと呼ばれる特別なUDPブロードキャストパケットをマシンのネットワークカードに送信する。NICはマシンがオフの状態でも(コンセントが刺さっている限り)低電力状態で電源が入っており、そのパケットを待ち受けている。パケットが届くと、NICがマザーボードに電源投入のシグナルを送る。

マジックパケットの構造はシンプルだ:0xFFの6バイト、続けてターゲットのMACアドレスを16回繰り返す——合計102バイト。IPヘッダーの認識なし。TCPハンドシェイクなし。ポート9または7上の生のUDPだけ。

落とし穴がある:ブロードキャストパケットはデフォルトではルーターを越えない。インターネットからNAT越しにWoLパケットをマシンに届けるには、リレーまたは指向性ブロードキャストが必要だ。それがルーター設定の出番となる

前提条件

  • WoLをサポートするNICを搭載したLinuxマシン(ほとんどのマシンは対応しているが、BIOSで有効化が必要)
  • Ethernet接続のマシン——ほとんどのケースでWi-FiではWoLは動作しない
  • ポートフォワーディングとオプションでサブネット指向ブロードキャスト設定のためのルーターへのアクセス
  • リモートからマジックパケットを送信する手段:別のサーバー、VPS、またはモバイルアプリ

ステップ1:BIOS/UEFIでWoLを有効化する

OSに触れる前に、BIOSを起動して以下のラベルの設定を探す:

  • Wake on LAN
  • Power On By PCI-E / PCI
  • Resume By LAN

有効化して保存・終了する。このステップを飛ばすと、ethtoolの出力を1時間眺めながら何も動かない理由を考え続けることになる。

ステップ2:LinuxでWoLを設定する

NICがWake-on-LANをサポートしているか確認する:

sudo ethtool eth0 | grep -i wake

以下のような出力を確認する:

Supports Wake-on: pumbg
Wake-on: d

Supports Wake-ongという文字がマジックパケットのサポートを確認する。Wake-ondは現在無効化されていることを意味する。有効化する:

sudo ethtool -s eth0 wol g

確認する:

sudo ethtool eth0 | grep 'Wake-on'

期待される出力:

Wake-on: g

問題が1つある:この設定は再起動のたびにリセットされる。永続化しよう。

systemdでWoLを永続化する(モダンなシステム向け)

起動時にethtoolを実行するoneshotサービスを作成する:

sudo nano /etc/systemd/system/wol.service
[Unit]
Description=eth0でWake-on-LANを有効化する
After=network.target

[Service]
Type=oneshot
ExecStart=/sbin/ethtool -s eth0 wol g
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable wol.service
sudo systemctl start wol.service

eth0を実際のインターフェース名に置き換える。不明な場合はip linkを実行する。

代替手段:NetworkManager(Ubuntu/Fedoraデスクトップ)

マシンがNetworkManagerを使用している場合は、接続ごとにWoLを設定する:

nmcli connection modify "Wired connection 1" 802-3-ethernet.wake-on-lan magic

ステップ3:MACアドレスを記録する

MACアドレスを今すぐ取得しておく——後でマジックパケットを構築するときに必要になる:

ip link show eth0 | grep ether

出力例:

    link/ether b8:27:eb:a1:2c:44 brd ff:ff:ff:ff:ff:ff

午前2時でも見つけられる場所にメモしておく。

ステップ4:リモート起動のためのルーター設定

ほとんどのチュートリアルが飛ばすところだ。インターネット越しにマシンを起動するには2つの方法がある:

オプションA:ブロードキャストアドレスへUDPをポートフォワードする

ほとんどのコンシューマー向けルーター(OpenWrt、pfSense、ASUS、TP-Link)の場合:

  1. ポートフォワーディングまたはバーチャルサーバーの設定を開く
  2. ルールを作成する:外部UDPポート9 → 内部IP 192.168.1.255(サブネットブロードキャスト)、ポート9
  3. ルーターがブロードキャストアドレスへのフォワーディングをブロックしている場合は、代わりにマシンの固定IPに直接フォワードする

ターゲットマシンに固定IPまたはMACアドレスによるDHCP予約を設定すること。再起動のたびにIPが変わるマシンは、最も必要なときに到達できなくなる。

オプションB:VPSまたはリレーサーバーを使用する

ルーターがブロードキャストアドレスにフォワードできない場合はリレーを使う。月5ドル程度の安いVPSでもLAN上のRaspberry Piでも機能する。リレーにSSHで接続し、ネットワーク内からパケットを送信する。

リレーにwakeonlanをインストールする:

# Debian/Ubuntu
sudo apt install wakeonlan

# RHEL/Fedora
sudo dnf install wol

リレーからパケットを送信する:

wakeonlan b8:27:eb:a1:2c:44

またはブロードキャストとポートを明示的に指定する:

wakeonlan -i 192.168.1.255 -p 9 b8:27:eb:a1:2c:44

ステップ5:起動シーケンスをテストする

ターゲットマシンの電源を落とす。同じLAN上の別のマシンからパケットを送信する:

wakeonlan b8:27:eb:a1:2c:44

15〜30秒待ってから、pingを打つかSSHで接続する。起動すれば、LAN側のWoLが正常に動作していることが確認できる。

次に外部からテストする。VPSを使うか、スマートフォンをLTEに切り替える——確実にローカルネットワーク外からアクセスできるものなら何でもよい。ルーターのパブリックIPにパケットを送信する:

wakeonlan -i YOUR.PUBLIC.IP -p 9 b8:27:eb:a1:2c:44

スクリプト化したい場合は、パケットを直接構築するPythonバージョンを使う:

import socket

def send_magic_packet(mac: str, broadcast_ip: str = '255.255.255.255', port: int = 9):
    mac_clean = mac.replace(':', '').replace('-', '')
    if len(mac_clean) != 12:
        raise ValueError(f"無効なMACアドレス: {mac}")
    payload = bytes.fromhex('FF' * 6 + mac_clean * 16)
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        sock.sendto(payload, (broadcast_ip, port))
    print(f"マジックパケットを {mac} に {broadcast_ip}:{port} 経由で送信しました")

send_magic_packet('b8:27:eb:a1:2c:44', broadcast_ip='YOUR.PUBLIC.IP')

よくある問題のトラブルシューティング

  • パケットは届いているがマシンが起動しない:まずBIOSを確認する。次にethtool eth0 | grep 'Wake-on'を確認する——再起動後に設定がdにリセットされている可能性がある。
  • LANでは動作するがインターネットから失敗する:ルーターがUDPパケットをドロップしている可能性が高い。代替としてポート7を試す。一部のISPは非標準ポートのUDPをブロックすることもある。
  • ARPキャッシュの問題:マシンが長時間オフになっていると、ルーターがARPエントリを削除し、そのIPへのパケット転送ができなくなる。ブロードキャストアドレス(192.168.1.255)を指定することでこれを完全に回避できる——ARPルックアップが不要になるためだ。
  • マシンが起動後すぐにシャットダウンする:これはBIOSの電源状態の問題だ。電源管理セクションのS4/S5電源状態に関する設定を探して調整する。

セキュリティの考慮事項

WoL用にUDPを公開すること自体はリスクが低い——最悪の場合、攻撃者があなたのマシンを起動するだけだ。ただし、電源が入ったマシンは攻撃対象となるため、基本的な対策は取る価値がある:

  • 非標準の外部ポートを使用する(例:外部19872/UDP → 内部9/UDP)
  • WANアドレスが固定の場合は、フォワーディングルールを特定のソースIPに制限する
  • ターゲットのSSHが鍵認証を使用していることを確認する——パスワードログインは無効にする

もう一つのテクニック:起動+待機+SSH接続を一括スクリプト化する

WoLが安定したら、一連のシーケンスを1つのスクリプトにまとめる:

#!/bin/bash
MAC="b8:27:eb:a1:2c:44"
HOST="192.168.1.50"
USER="admin"

echo "マジックパケットを送信しています..."
wakeonlan $MAC

echo "マシンがオンラインになるのを待っています..."
for i in $(seq 1 12); do
  sleep 5
  if ping -c1 -W1 $HOST &>/dev/null; then
    echo "マシンが起動しました。接続しています..."
    ssh ${USER}@${HOST}
    exit 0
  fi
  echo "まだ待機中... (${i}/12)"
done

echo "60秒経過してもマシンが応答しませんでした。"
exit 1

これが設定の全体像だ

WoLはバックグラウンドのツールだ——最悪のタイミングでマシンが落ちるまで存在を忘れている。設定は約20分:ethtoolの設定、systemdサービス、そして1つのポートフォワーディングルール。それだけで、管理しているどの物理マシンにも、どこからでも、何時でもアクセスできるようになる。

午前3時の40キロドライブは、電源トラブルで駆けつけた最後の夜になった。それは良い結末だ。

Share: