0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

緊急用VPN(WireGuard)が自動起動するようにした話

0
Last updated at Posted at 2026-03-02

やったこと

以前公開した記事の構成では、自宅サーバが落ちたときに、VPNに繋いでる端末がインターネットに接続できなくなります。
そうなると困るので、緊急用のVPNが自動で起動するようにしました。

忙しい人向け

やったことは、wgE(OCIから直接インターネットへ抜けるVPN)のconfファイルを用意し、以下のスクリプトをcronで定期実行するよう設定しただけです。

/usr/local/bin/wg_failover.sh
#!/bin/bash

TARGET="10.50.0.254"
PING_COUNT=3
TIMEOUT=2

WG_PRIMARY="wg-quick@wg0"
WG_EMERGENCY="wg-quick@wgE"

# wgE起動判定

if ! ping -I wg0 -c ${PING_COUNT} -W ${TIMEOUT} ${TARGET} > /dev/null 2>&1; then
  if ! systemctl is-active --quiet ${WG_EMERGENCY}; then
         # wg0経由でping通らない & wgE未起動なら wgE起動
         logger "[wg-failover] ping failed. switching wg0 -> wgE"
        
         systemctl stop ${WG_PRIMARY}
         sleep 2
         systemctl restart ${WG_EMERGENCY}
  fi
fi

解説

後から修正したので、少しスクリプトの内容が違っています。

wgEの準備

基本的に、wg0の時と変わりません。

まずは、秘密鍵と公開鍵を作成します。

sudo wg genkey | tee private.key #秘密鍵を作成
#(秘密鍵がここに表示される)
sudo cat private.key | sudo wg pubkey | tee public.pub #秘密鍵に対応する公開鍵を作成
#(公開鍵がここに表示される)

次に、wgE.confを準備します。

sudo vi /etc/wireguard/wgE.conf
/etc/wireguard/wgE.conf
[Interface]
PrivateKey = [OCIのPrivateKey]
Address = 10.60.0.1/32
ListenPort = 51821
Table = 51821

PostUp = ip -4 rule add from 10.60.0.2/32 table 51821
PostUp = ip -4 route add 10.60.0.0/24 dev wgE
PostUp = iptables -t nat -A POSTROUTING -s 10.60.0.0/24 -o ens3 -j MASQUERADE
PostUp = iptables -A FORWARD -i wgE -o ens3 -j ACCEPT
PostUp = iptables -A FORWARD -i ens3 -o wgE -m state --state ESTABLISHED,RELATED -j ACCEPT

PostDown = ip -4 rule del from 10.60.0.2/32 table 51821
PostDown = ip -4 route del 10.60.0.0/24 dev wgE
PostDown = iptables -t nat -D POSTROUTING -s 10.60.0.0/24 -o ens3 -j MASQUERADE
PostDown = iptables -D FORWARD -i wgE -o ens3 -j ACCEPT
PostDown = iptables -D FORWARD -i ens3 -o wgE -m state --state ESTABLISHED,RELATED -j ACCEPT

[Peer]
PublicKey = [クライアントのPublicKey]
AllowedIPs = 10.60.0.2/32

起動スクリプトの作成

前述したスクリプトを作成します。
一応、スクリプト内に簡単なコメントは残していますが、もう少し詳しく一つ一つの処理を解説していきます。

TARGET="10.50.0.254"
PING_COUNT=3
TIMEOUT=2

WG_PRIMARY="wg-quick@wg0"
WG_EMERGENCY="wg-quick@wgE"

ここでは、各変数と変数に格納する値を指定しています。

# wgE起動判定

if ! ping -I wg0 -c ${PING_COUNT} -W ${TIMEOUT} ${TARGET} > /dev/null 2>&1; then
    # ping通らなかったらwgE起動
    logger "[wg-failover] ping failed. switching wg0 -> wgE"

    systemctl stop ${WG_PRIMARY}
    sleep 2
    systemctl restart ${WG_EMERGENCY}
fi

ここについては、もう少し分解して解説します。

if ! ping -I wg0 -c ${PING_COUNT} -W ${TIMEOUT} ${TARGET} > /dev/null 2>&1; then

まず、wg0もしくは自宅サーバが落ちていないか確認します。
確認方法は、wg0経由で自宅サーバにpingを打って応答があるかを見るというシンプルな方法を取ってます。
もし、ここでpingが通らなければ条件を満たすため、次の処理に移っていきます。

    logger "[wg-failover] ping failed. switching wg0 -> wgE"

wg0からwgEに移行することをログに記録します。

    systemctl stop ${WG_PRIMARY}
    sleep 2
    systemctl restart ${WG_EMERGENCY}

先にwg0を止める処理を開始し、少し待った後、wgEを起動します。

wgEを起動する際にrestartを使っている理由

wgEというインタフェースが立ち上がっていない状態であっても、wg-quick@wgEがactive状態になっているからです。
一度テストなどでwg-quick@wgEを起動すると、systemd上でサービスが active 状態になるため start では再実行されないです。
なので、restartで再起動し、wgEを再度立ち上げてます。

自動起動の設定

作成したスクリプトを/usr/local/binに保存しておきます。
スクリプトのファイル名は任意ですが、本記事では例としてwg_failover.shとしておきます。

その後、ログインユーザーをrootに切り替え、以下コマンドでcronに設定します。

crontab -e
* * * * * sh /usr/local/bin/wg_failover.sh

上記の通り、実行時間の指定なしの場合、指定したコマンドは毎分実行されます。
そこまで頻繁に実行したくない場合は、適宜cronに登録する実行時間を変更してください。

テスト

以下コマンドでwg0を止めて、しばらくした後、wgEが起動していれば問題なく動作しています。

wg-quick down wg0

まとめ

今回、wg0でインターネットに繋げなくなった時の対策としてwgEを作成し、以下をシェルスクリプトとcronで自動化しました。

  • wg0が繋がらなくなった判定
  • wgEの起動

これで、仮に自宅のサーバが万が一落ちてしまっても、ある程度安心して自前のVPN回線を使い続けることができるようになったと思います。

追記

上記までのスクリプトだと、wgEを立ち上げた後も再起動コマンドを連打することになるので、wgEが立ち上がっていないかも条件に追加しました。

if ! systemctl is-active --quiet ${WG_EMERGENCY}; thenの部分を追加したので、wgEが起動していない状態であれば、次の処理に進みます。

忙しい人向けには、修正版のスクリプトを記載しています。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?