0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

OpenWrt VPN DDNS WireGuard DuckDNS

Last updated at Posted at 2025-11-06

:flag_jp: Japanese article
OpenWrt_icon.png

はじめに

記事について

WireGuard + DuckDNS(DDNS)を使った外部アクセス環境の構築ツールです

検証環境

ルーターA:ncp-hg100:OpenWrt 24.10.4

ルーターB:bpi-r4:OpenWrt 24.10.4

  • ISP:ドコモ光:MAP-E 1G
  • 役割:WireGuardクライアント

ダイナミックDNS

  • DuckDNS:無料、設定簡単、メンテナンス不要
  • No-IP:老舗、無料版は30日ごと確認必要
  • Cloudflare:独自ドメイン必要
  • FreeDNS:無料、多数のドメイン選択可

本記事ではDuckDNSを使用します

DDNSセットアップ

変数を事前設定する場合(対話形式をスキップ)

# DuckDNS設定用変数
DDNS_SERVICE="duckdns.org"
DDNS_DOMAIN="myrouter"
DDNS_TOKEN="12345678-abcd-1234-abcd-123456789abc"
DDNS_INTERFACE="wan"
CHECK_INTERVAL="24"
CHECK_UNIT="hours"

セットアップ

{
#!/bin/sh

# 必要パッケージの自動インストール
echo "=========================================="
echo "必要パッケージの確認"
echo "=========================================="

# インストール済み言語パッケージから言語コードを検出
LANG_PKGS=""
if command -v opkg >/dev/null 2>&1; then
    INSTALLED_LANGS=$(opkg list-installed | grep "^luci-i18n-base-" | sed 's/luci-i18n-base-//' | cut -d' ' -f1 | sort -u)
    for lang in $INSTALLED_LANGS; do
        # 対応する言語パッケージが存在するか確認
        if opkg list | grep -q "^luci-i18n-ddns-$lang "; then
            LANG_PKGS="$LANG_PKGS luci-i18n-ddns-$lang"
        fi
    done
fi

# パッケージリスト
BASE_PKGS="luci-app-ddns ddns-scripts"
PKGS="$BASE_PKGS $LANG_PKGS"

# パッケージのインストール確認とインストール
MISSING_PKGS=""
for pkg in $PKGS; do
    if ! opkg list-installed | grep -q "^${pkg} "; then
        MISSING_PKGS="$MISSING_PKGS $pkg"
    else
        echo "インストール済み: $pkg"
    fi
done

if [ -n "$MISSING_PKGS" ]; then
    echo "不足しているパッケージをインストール中:$MISSING_PKGS"
    command -v opkg && opkg update >/dev/null 2>&1 && opkg install $MISSING_PKGS
fi

echo "=========================================="
echo ""

# ========================================
# グローバル変数(デフォルト値)
# ========================================
DDNS_SERVICE="${DDNS_SERVICE:-duckdns.org}"
DDNS_DOMAIN="${DDNS_DOMAIN:-}"
DDNS_TOKEN="${DDNS_TOKEN:-}"
DDNS_INTERFACE="${DDNS_INTERFACE:-}"
CHECK_INTERVAL="${CHECK_INTERVAL:-24}"
CHECK_UNIT="${CHECK_UNIT:-hours}"

# ========================================
# 物理デバイス検出関数
# ========================================
detect_wan_device() {
    # WANインターフェースの物理デバイスを検出
    local iface device
    for iface in $(uci show network | grep "=interface" | cut -d'.' -f2 | cut -d'=' -f1); do
        [ "$iface" = "loopback" ] && continue
        [ "$iface" = "lan" ] && continue
        [ "$(uci get network.$iface.disabled 2>/dev/null)" = "1" ] && continue
        
        # デバイス名を取得
        device=$(uci get network.$iface.device 2>/dev/null)
        [ -z "$device" ] && device=$(uci get network.$iface.ifname 2>/dev/null)
        
        # デバイスがアクティブか確認
        if [ -n "$device" ] && ip link show dev "$device" 2>/dev/null | grep -q "state UP"; then
            echo "$device"
            return 0
        fi
    done
    echo "wan"
}

get_available_devices() {
    echo "利用可能な物理デバイス:"
    ip link show | grep -E "^[0-9]+:" | awk '{print $2}' | sed 's/:$//' | while read dev; do
        [ "$dev" = "lo" ] && continue
        state=$(ip link show dev "$dev" | grep -o "state [A-Z]*" | cut -d' ' -f2)
        echo "  $dev (state: $state)"
    done
}

# ========================================
# 対話形式入力関数
# ========================================
ask_input() {
    local var_name="$1"
    local prompt="$2"
    local default="$3"
    local current_value="$4"
    
    # 既に値が設定されている場合はスキップ
    if [ -n "$current_value" ]; then
        echo "[設定済み] $prompt: $current_value"
        return 0
    fi
    
    # デフォルト値の表示
    if [ -n "$default" ]; then
        echo -n "$prompt [$default]: "
    else
        echo -n "$prompt: "
    fi
    
    read input
    
    # 入力がなければデフォルト値を使用
    if [ -z "$input" ] && [ -n "$default" ]; then
        input="$default"
    fi
    
    # 必須項目のチェック
    if [ -z "$input" ]; then
        echo "エラー: この項目は必須です"
        return 1
    fi
    
    eval "$var_name='$input'"
    return 0
}

# ========================================
# メイン処理開始
# ========================================
echo "=========================================="
echo "DuckDNS設定スクリプト"
echo "=========================================="
echo ""

# DDNSサービスプロバイダー
ask_input "DDNS_SERVICE" "DDNSサービスプロバイダー" "duckdns.org" "$DDNS_SERVICE" || exit 1

# ドメイン名
echo ""
while true; do
    ask_input "DDNS_DOMAIN" "ドメイン名(.duckdns.org の前の部分)" "" "$DDNS_DOMAIN" || exit 1
    if [ -n "$DDNS_DOMAIN" ]; then
        break
    fi
done

# トークン
echo ""
while true; do
    ask_input "DDNS_TOKEN" "DuckDNSトークン" "" "$DDNS_TOKEN" || exit 1
    if [ -n "$DDNS_TOKEN" ]; then
        break
    fi
done

# WAN物理デバイス
echo ""
if [ -z "$DDNS_INTERFACE" ]; then
    echo "=========================================="
    get_available_devices
    echo ""
    detected_device=$(detect_wan_device)
    echo "自動検出されたWANデバイス: $detected_device"
    echo "=========================================="
    echo ""
    DDNS_INTERFACE="$detected_device"
fi
ask_input "DDNS_INTERFACE" "WAN物理デバイス名" "$DDNS_INTERFACE" "$DDNS_INTERFACE" || exit 1

# 更新間隔
echo ""
ask_input "CHECK_INTERVAL" "更新チェック間隔(数値)" "24" "$CHECK_INTERVAL" || exit 1

# 更新間隔の単位
echo ""
ask_input "CHECK_UNIT" "更新チェック間隔の単位" "hours" "$CHECK_UNIT" || exit 1

# 設定内容の確認
echo ""
echo "=========================================="
echo "設定内容の確認"
echo "=========================================="
echo "サービス: $DDNS_SERVICE"
echo "ドメイン: ${DDNS_DOMAIN}.duckdns.org"
echo "トークン: ${DDNS_TOKEN:0:8}... (省略表示)"
echo "物理デバイス: $DDNS_INTERFACE"
echo "更新間隔: $CHECK_INTERVAL $CHECK_UNIT"
echo ""
echo -n "この設定で進めますか? [Y/n]: "
read confirm

if [ "$confirm" = "n" ] || [ "$confirm" = "N" ]; then
    echo "設定をキャンセルしました"
    exit 0
fi

# ========================================
# DDNS設定の適用
# ========================================
echo ""
echo "=========================================="
echo "DDNS設定を適用中..."
echo "=========================================="

# 既存のDDNS設定を削除(クリーンインストール)
echo "既存のDDNS設定を削除..."
uci delete ddns.@service[0] 2>/dev/null
uci commit ddns

# 新規DDNS設定を追加
echo "DuckDNS設定を追加..."

# DDNSセクションの作成
uci add ddns service
uci set ddns.@service[-1].enabled='1'
uci set ddns.@service[-1].service_name="${DDNS_SERVICE}"
uci set ddns.@service[-1].lookup_host="${DDNS_DOMAIN}.duckdns.org"
uci set ddns.@service[-1].domain="${DDNS_DOMAIN}"
uci set ddns.@service[-1].username="${DDNS_DOMAIN}"
uci set ddns.@service[-1].password="${DDNS_TOKEN}"
uci set ddns.@service[-1].interface="${DDNS_INTERFACE}"
uci set ddns.@service[-1].ip_source="interface"
uci set ddns.@service[-1].use_interface="${DDNS_INTERFACE}"
uci set ddns.@service[-1].use_ipv6='0'
uci set ddns.@service[-1].check_interval="${CHECK_INTERVAL}"
uci set ddns.@service[-1].check_unit="${CHECK_UNIT}"
uci set ddns.@service[-1].force_interval='72'
uci set ddns.@service[-1].force_unit='hours'
uci set ddns.@service[-1].retry_count='5'
uci set ddns.@service[-1].retry_interval='60'

# 設定をコミット
echo "設定をコミット..."
uci commit ddns

# DDNS設定の表示
echo ""
echo "=========================================="
echo "設定内容の確認"
echo "=========================================="
uci show ddns

# DDNSサービスを再起動
echo ""
echo "=========================================="
echo "DDNSサービスを再起動"
echo "=========================================="
/etc/init.d/ddns restart

# 起動設定を有効化
echo "DDNSサービスの自動起動を有効化..."
/etc/init.d/ddns enable

# ステータス確認
echo ""
echo "=========================================="
echo "DDNSサービスのステータス"
echo "=========================================="
sleep 3
/etc/init.d/ddns status

# ログ確認(最後の10行)
echo ""
echo "=========================================="
echo "DDNSログ(最後の10行)"
echo "=========================================="
if [ -f /var/log/ddns/*.log ]; then
    tail -10 /var/log/ddns/*.log
else
    logread | grep -i ddns | tail -10
fi

echo ""
echo "=========================================="
echo "設定完了!"
echo "=========================================="
echo "ドメイン名: ${DDNS_DOMAIN}.duckdns.org"
echo "更新間隔: ${CHECK_INTERVAL} ${CHECK_UNIT}"
echo ""
echo "数分待ってから以下のコマンドで確認してください:"
echo "  nslookup ${DDNS_DOMAIN}.duckdns.org"
echo ""
echo "手動更新したい場合:"
echo "  /usr/lib/ddns/dynamic_dns_updater.sh -S @service[-1] -- start"
echo ""
}

VPN

OpenWrtで利用可能な主なVPNプロトコル:

  • WireGuard:高速、軽量、設定シンプル、モダンな暗号技術
  • OpenVPN:老舗、汎用性高い、多機能、クライアント対応広い
  • Tailscale:WireGuardベース、メッシュVPN、NAT越え自動、無料枠あり
  • ZeroTier:仮想LAN、メッシュネットワーク、無料枠あり
  • Headscale:Tailscaleのセルフホスト版、オープンソース

本記事ではWireguardを使用します
公式

Wireguardサーバーセットアップ

変数を事前設定する場合(対話形式をスキップ)

# WireGuardサーバー設定用変数
WG_PORT="51820"
WG_ADDRESS="10.8.0.1/24"
WG_INTERFACE="wg0"
WG_CLIENT_IP="10.8.0.2"
WG_CLIENT_LAN="192.168.0.0/24"

サーバーセットアップ

{
#!/bin/sh
# WireGuard サーバー設定スクリプト
# ========================================
# 必要パッケージの自動インストール
# ========================================
echo "=========================================="
echo "必要パッケージの確認"
echo "=========================================="

# インストール済み言語パッケージから言語コードを検出
LANG_PKGS=""
if command -v opkg >/dev/null 2>&1; then
    INSTALLED_LANGS=$(opkg list-installed | grep "^luci-i18n-" | sed 's/luci-i18n-[^-]*-//' | cut -d' ' -f1 | sort -u)
    for lang in $INSTALLED_LANGS; do
        LANG_PKGS="$LANG_PKGS luci-i18n-wireguard-$lang"
    done
fi

# パッケージリスト
BASE_PKGS="wireguard-tools luci-app-wireguard luci-proto-wireguard"
PKGS="$BASE_PKGS $LANG_PKGS"

# インストール
command -v opkg && opkg update >/dev/null 2>&1 && opkg install $PKGS 2>&1 | grep "up to date" | sed 's/Package \(.*\) (.*/インストール済み: \1/'
command -v apk  && apk update >/dev/null 2>&1  && apk add $PKGS >/dev/null 2>&1

echo "=========================================="
echo ""

# ========================================
# グローバル変数(デフォルト値)
# ========================================
WG_PORT="${WG_PORT:-51820}"
WG_ADDRESS="${WG_ADDRESS:-10.8.0.1/24}"
WG_INTERFACE="${WG_INTERFACE:-wg0}"
WG_CLIENT_IP="${WG_CLIENT_IP:-10.8.0.2}"
WG_CLIENT_LAN="${WG_CLIENT_LAN:-192.168.0.0/24}"

# ========================================
# 対話形式入力関数
# ========================================
ask_input() {
    local var_name="$1"
    local prompt="$2"
    local default="$3"
    local current_value="$4"
    
    if [ -n "$current_value" ]; then
        echo "[設定済み] $prompt: $current_value"
        return 0
    fi
    
    if [ -n "$default" ]; then
        echo -n "$prompt [$default]: "
    else
        echo -n "$prompt: "
    fi
    
    read input
    
    if [ -z "$input" ] && [ -n "$default" ]; then
        input="$default"
    fi
    
    if [ -z "$input" ]; then
        echo "エラー: この項目は必須です"
        return 1
    fi
    
    eval "$var_name='$input'"
    return 0
}

# ========================================
# メイン処理開始
# ========================================
echo "=========================================="
echo "WireGuard サーバー設定スクリプト"
echo "=========================================="
echo ""

# WireGuardポート番号
ask_input "WG_PORT" "WireGuardリスニングポート(UDP)" "51820" "$WG_PORT" || exit 1

# WireGuard VPNネットワークアドレス
echo ""
ask_input "WG_ADDRESS" "WireGuard VPNネットワークアドレス" "10.8.0.1/24" "$WG_ADDRESS" || exit 1

# WireGuardインターフェース名
echo ""

# 空いているインターフェース名を検出
WG_BASE="${WG_INTERFACE:-wg0}"
WG_INTERFACE="$WG_BASE"
WG_NUM=$(echo "$WG_BASE" | sed 's/[^0-9]//g')
WG_NUM=${WG_NUM:-0}

while uci show network.$WG_INTERFACE >/dev/null 2>&1; do
    WG_NUM=$((WG_NUM+1))
    WG_PREFIX=$(echo "$WG_BASE" | sed 's/[0-9]*$//')
    WG_INTERFACE="${WG_PREFIX}${WG_NUM}"
done

ask_input "WG_INTERFACE" "WireGuardインターフェース名" "$WG_INTERFACE" "" || exit 1

# クライアントIPアドレス
echo ""
ask_input "WG_CLIENT_IP" "クライアントIPアドレス" "10.8.0.2" "$WG_CLIENT_IP" || exit 1

# クライアント側LANネットワーク
echo ""
ask_input "WG_CLIENT_LAN" "クライアント側LANネットワーク" "192.168.0.0/24" "$WG_CLIENT_LAN" || exit 1

# 設定内容の確認
echo ""
echo "=========================================="
echo "設定内容の確認"
echo "=========================================="
echo "リスニングポート: $WG_PORT (UDP)"
echo "VPNネットワーク: $WG_ADDRESS"
echo "インターフェース: $WG_INTERFACE"
echo "クライアントIP: $WG_CLIENT_IP"
echo "クライアントLAN: $WG_CLIENT_LAN"
echo ""
echo -n "この設定で進めますか? [Y/n]: "
read confirm

if [ "$confirm" = "n" ] || [ "$confirm" = "N" ]; then
    echo "設定をキャンセルしました"
    exit 0
fi

# ========================================
# WireGuard設定の適用
# ========================================
echo ""
echo "=========================================="
echo "WireGuard設定を適用中..."
echo "=========================================="

# 鍵ペアの生成
echo "鍵ペアを生成中..."
WG_PRIVKEY=$(wg genkey)
WG_PUBKEY=$(echo "$WG_PRIVKEY" | wg pubkey)

echo "サーバー公開鍵: $WG_PUBKEY"

# WireGuardインターフェースの作成
echo "WireGuardインターフェースを作成中..."

uci set network.${WG_INTERFACE}=interface
uci set network.${WG_INTERFACE}.proto='wireguard'
uci set network.${WG_INTERFACE}.private_key="$WG_PRIVKEY"
uci set network.${WG_INTERFACE}.listen_port="$WG_PORT"
uci add_list network.${WG_INTERFACE}.addresses="$WG_ADDRESS"

uci commit network

# ファイアウォールゾーンの作成
echo "ファイアウォールゾーンを作成中..."

uci add firewall zone
uci set firewall.@zone[-1].name='wg'
uci set firewall.@zone[-1].input='ACCEPT'
uci set firewall.@zone[-1].output='ACCEPT'
uci set firewall.@zone[-1].forward='ACCEPT'
uci set firewall.@zone[-1].masq='1'
uci add_list firewall.@zone[-1].network="${WG_INTERFACE}"

# WANからWireGuardポートへのアクセス許可
echo "ファイアウォールルールを追加中..."

uci add firewall rule
uci set firewall.@rule[-1].name='Allow-WireGuard'
uci set firewall.@rule[-1].src='wan'
uci set firewall.@rule[-1].dest_port="$WG_PORT"
uci set firewall.@rule[-1].proto='udp'
uci set firewall.@rule[-1].target='ACCEPT'

# WGゾーンからLANへのフォワーディング許可
uci add firewall forwarding
uci set firewall.@forwarding[-1].src='wg'
uci set firewall.@forwarding[-1].dest='lan'

# LANからWGへのフォワーディング許可
uci add firewall forwarding
uci set firewall.@forwarding[-1].src='lan'
uci set firewall.@forwarding[-1].dest='wg'

uci commit firewall

# 設定の表示
echo ""
echo "=========================================="
echo "設定完了!"
echo "=========================================="
echo ""
echo "【重要】設定を反映するには再起動してください:"
echo "  reboot"
echo ""
echo "【サーバー情報】"
echo "インターフェース: $WG_INTERFACE"
echo "リスニングポート: $WG_PORT (UDP)"
echo "VPNネットワーク: $WG_ADDRESS"
echo ""
echo "【サーバー鍵情報】"
echo "公開鍵: $WG_PUBKEY"
echo ""
echo "【既存のWireGuardインターフェース】"
uci show network | grep "=interface" | cut -d'.' -f2 | cut -d'=' -f1 | while read iface; do
    proto=$(uci get network.$iface.proto 2>/dev/null)
    if [ "$proto" = "wireguard" ]; then
        addr=$(uci get network.$iface.addresses 2>/dev/null | head -1)
        if [ "$iface" = "$WG_INTERFACE" ]; then
            echo "  ★ $iface ($addr) ← 今回作成"
        else
            echo "    $iface ($addr)"
        fi
    fi
done
echo ""
echo "【次のステップ】"
echo "1. クライアント側の設定を行ってください"
echo "2. クライアントの公開鍵を取得してください"
echo "3. 以下のコマンドでピア(クライアント)を追加してください:"
echo ""
echo "uci add network wireguard_${WG_INTERFACE}"
echo "uci set network.@wireguard_${WG_INTERFACE}[-1].public_key='<クライアント公開鍵>'"
echo "uci set network.@wireguard_${WG_INTERFACE}[-1].description='クライアント'"
echo "uci add_list network.@wireguard_${WG_INTERFACE}[-1].allowed_ips='${WG_CLIENT_IP}/32'"
echo "uci add_list network.@wireguard_${WG_INTERFACE}[-1].allowed_ips='${WG_CLIENT_LAN}'"
echo "uci commit network"
echo "reboot"
echo ""
echo "【動作確認】"
echo "wg show"
echo "ip addr show $WG_INTERFACE"
echo ""
}

Wireguardクライアントセットアップ

変数を事前設定する場合(対話形式をスキップ)

# WireGuardクライアント設定用変数
WG_SERVER_ENDPOINT="myrouter.duckdns.org:51820"
WG_SERVER_PUBKEY="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
WG_CLIENT_ADDRESS="10.8.0.2/24"
WG_INTERFACE="wg0"
WG_PERSISTENT_KEEPALIVE="25"
WG_VPN_NETWORK="10.8.0.0/24"
WG_SERVER_LAN="192.168.10.0/24"

クライアントセットアップ

{
#!/bin/sh
# WireGuard クライアント設定スクリプト
# ========================================
# 必要パッケージの自動インストール
# ========================================
echo "=========================================="
echo "必要パッケージの確認"
echo "=========================================="

# インストール済み言語パッケージから言語コードを検出
LANG_PKGS=""
if command -v opkg >/dev/null 2>&1; then
    INSTALLED_LANGS=$(opkg list-installed | grep "^luci-i18n-" | sed 's/luci-i18n-[^-]*-//' | cut -d' ' -f1 | sort -u)
    for lang in $INSTALLED_LANGS; do
        LANG_PKGS="$LANG_PKGS luci-i18n-wireguard-$lang"
    done
fi

# パッケージリスト
BASE_PKGS="wireguard-tools luci-app-wireguard luci-proto-wireguard"
PKGS="$BASE_PKGS $LANG_PKGS"

# インストール
command -v opkg && opkg update >/dev/null 2>&1 && opkg install $PKGS 2>&1 | grep "up to date" | sed 's/Package \(.*\) (.*/インストール済み: \1/'
command -v apk  && apk update >/dev/null 2>&1  && apk add $PKGS >/dev/null 2>&1

echo "=========================================="
echo ""

# ========================================
# グローバル変数(デフォルト値)
# ========================================
WG_SERVER_ENDPOINT="${WG_SERVER_ENDPOINT:-}"
WG_SERVER_PUBKEY="${WG_SERVER_PUBKEY:-}"
WG_CLIENT_ADDRESS="${WG_CLIENT_ADDRESS:-10.8.0.2/24}"
WG_INTERFACE="${WG_INTERFACE:-wg0}"
WG_PERSISTENT_KEEPALIVE="${WG_PERSISTENT_KEEPALIVE:-25}"
WG_VPN_NETWORK="${WG_VPN_NETWORK:-10.8.0.0/24}"
WG_SERVER_LAN="${WG_SERVER_LAN:-192.168.10.0/24}"

# ========================================
# 対話形式入力関数
# ========================================
ask_input() {
    local var_name="$1"
    local prompt="$2"
    local default="$3"
    local current_value="$4"
    
    if [ -n "$current_value" ]; then
        echo "[設定済み] $prompt: $current_value"
        return 0
    fi
    
    if [ -n "$default" ]; then
        echo -n "$prompt [$default]: "
    else
        echo -n "$prompt: "
    fi
    
    read input
    
    if [ -z "$input" ] && [ -n "$default" ]; then
        input="$default"
    fi
    
    if [ -z "$input" ]; then
        echo "エラー: この項目は必須です"
        return 1
    fi
    
    eval "$var_name='$input'"
    return 0
}

# ========================================
# メイン処理開始
# ========================================
echo "=========================================="
echo "WireGuard クライアント設定スクリプト"
echo "=========================================="
echo ""

# サーバーエンドポイント
while true; do
    ask_input "WG_SERVER_ENDPOINT" "サーバーエンドポイント(例: example.duckdns.org:51820)" "" "$WG_SERVER_ENDPOINT" || exit 1
    if [ -n "$WG_SERVER_ENDPOINT" ]; then
        break
    fi
done

# サーバー公開鍵
echo ""
while true; do
    ask_input "WG_SERVER_PUBKEY" "サーバー公開鍵" "" "$WG_SERVER_PUBKEY" || exit 1
    if [ -n "$WG_SERVER_PUBKEY" ]; then
        break
    fi
done

# クライアントVPNアドレス
echo ""
ask_input "WG_CLIENT_ADDRESS" "クライアントVPNアドレス" "10.8.0.2/24" "$WG_CLIENT_ADDRESS" || exit 1

# WireGuardインターフェース名
echo ""

# 空いているインターフェース名を検出
WG_BASE="${WG_INTERFACE:-wg0}"
WG_INTERFACE="$WG_BASE"
WG_NUM=$(echo "$WG_BASE" | sed 's/[^0-9]//g')
WG_NUM=${WG_NUM:-0}

while uci show network.$WG_INTERFACE >/dev/null 2>&1; do
    WG_NUM=$((WG_NUM+1))
    WG_PREFIX=$(echo "$WG_BASE" | sed 's/[0-9]*$//')
    WG_INTERFACE="${WG_PREFIX}${WG_NUM}"
done

ask_input "WG_INTERFACE" "WireGuardインターフェース名" "$WG_INTERFACE" "" || exit 1

# Persistent Keepalive
echo ""
ask_input "WG_PERSISTENT_KEEPALIVE" "Persistent Keepalive(秒)" "25" "$WG_PERSISTENT_KEEPALIVE" || exit 1

# VPNネットワーク
echo ""
ask_input "WG_VPN_NETWORK" "VPNネットワーク" "10.8.0.0/24" "$WG_VPN_NETWORK" || exit 1

# サーバー側LANネットワーク
echo ""
ask_input "WG_SERVER_LAN" "サーバー側LANネットワーク" "192.168.10.0/24" "$WG_SERVER_LAN" || exit 1

# 設定内容の確認
echo ""
echo "=========================================="
echo "設定内容の確認"
echo "=========================================="
echo "サーバーエンドポイント: $WG_SERVER_ENDPOINT"
echo "サーバー公開鍵: ${WG_SERVER_PUBKEY:0:20}..."
echo "クライアントVPNアドレス: $WG_CLIENT_ADDRESS"
echo "インターフェース: $WG_INTERFACE"
echo "Keepalive: $WG_PERSISTENT_KEEPALIVE 秒"
echo "VPNネットワーク: $WG_VPN_NETWORK"
echo "サーバーLAN: $WG_SERVER_LAN"
echo ""
echo -n "この設定で進めますか? [Y/n]: "
read confirm

if [ "$confirm" = "n" ] || [ "$confirm" = "N" ]; then
    echo "設定をキャンセルしました"
    exit 0
fi

# ========================================
# WireGuard設定の適用
# ========================================
echo ""
echo "=========================================="
echo "WireGuard設定を適用中..."
echo "=========================================="

# 鍵ペアの生成
echo "鍵ペアを生成中..."
WG_PRIVKEY=$(wg genkey)
WG_PUBKEY=$(echo "$WG_PRIVKEY" | wg pubkey)

echo "クライアント公開鍵: $WG_PUBKEY"

# クライアントIPアドレスを抽出
CLIENT_IP=$(echo $WG_CLIENT_ADDRESS | cut -d'/' -f1)

# WireGuardインターフェースの作成
echo "WireGuardインターフェースを作成中..."

uci set network.${WG_INTERFACE}=interface
uci set network.${WG_INTERFACE}.proto='wireguard'
uci set network.${WG_INTERFACE}.private_key="$WG_PRIVKEY"
uci add_list network.${WG_INTERFACE}.addresses="$WG_CLIENT_ADDRESS"

# サーバーピアの設定
uci add network wireguard_${WG_INTERFACE}
uci set network.@wireguard_${WG_INTERFACE}[-1].public_key="$WG_SERVER_PUBKEY"
uci set network.@wireguard_${WG_INTERFACE}[-1].endpoint_host="$(echo $WG_SERVER_ENDPOINT | cut -d':' -f1)"
uci set network.@wireguard_${WG_INTERFACE}[-1].endpoint_port="$(echo $WG_SERVER_ENDPOINT | cut -d':' -f2)"
uci set network.@wireguard_${WG_INTERFACE}[-1].route_allowed_ips='1'
uci set network.@wireguard_${WG_INTERFACE}[-1].persistent_keepalive="$WG_PERSISTENT_KEEPALIVE"
uci add_list network.@wireguard_${WG_INTERFACE}[-1].allowed_ips="${WG_VPN_NETWORK}"
uci add_list network.@wireguard_${WG_INTERFACE}[-1].allowed_ips="${WG_SERVER_LAN}"

uci commit network

# ファイアウォールゾーンの作成
echo "ファイアウォールゾーンを作成中..."

uci add firewall zone
uci set firewall.@zone[-1].name='wg'
uci set firewall.@zone[-1].input='ACCEPT'
uci set firewall.@zone[-1].output='ACCEPT'
uci set firewall.@zone[-1].forward='ACCEPT'
uci set firewall.@zone[-1].masq='1'
uci add_list firewall.@zone[-1].network="${WG_INTERFACE}"

# WGゾーンからLANへのフォワーディング許可
uci add firewall forwarding
uci set firewall.@forwarding[-1].src='wg'
uci set firewall.@forwarding[-1].dest='lan'

# LANからWGへのフォワーディング許可
uci add firewall forwarding
uci set firewall.@forwarding[-1].src='lan'
uci set firewall.@forwarding[-1].dest='wg'

uci commit firewall

# 設定の表示
echo ""
echo "=========================================="
echo "設定完了!"
echo "=========================================="
echo ""
echo "【クライアント情報】"
echo "インターフェース: $WG_INTERFACE"
echo "VPNアドレス: $WG_CLIENT_ADDRESS"
echo "公開鍵: $WG_PUBKEY"
echo ""
echo "【既存のWireGuardインターフェース】"
uci show network | grep "=interface" | cut -d'.' -f2 | cut -d'=' -f1 | while read iface; do
    proto=$(uci get network.$iface.proto 2>/dev/null)
    if [ "$proto" = "wireguard" ]; then
        addr=$(uci get network.$iface.addresses 2>/dev/null | head -1)
        if [ "$iface" = "$WG_INTERFACE" ]; then
            echo "  ★ $iface ($addr) ← 今回作成"
        else
            echo "    $iface ($addr)"
        fi
    fi
done
echo ""
echo "=========================================="
echo "【重要】サーバー側で以下をコピー&ペーストして実行"
echo "=========================================="
echo ""
cat << EOF
uci add network wireguard_${WG_INTERFACE}
uci set network.@wireguard_${WG_INTERFACE}[-1].public_key='$WG_PUBKEY'
uci set network.@wireguard_${WG_INTERFACE}[-1].description='クライアント'
uci add_list network.@wireguard_${WG_INTERFACE}[-1].allowed_ips='${CLIENT_IP}/32'
uci add_list network.@wireguard_${WG_INTERFACE}[-1].allowed_ips='<クライアント側LANネットワーク>'
uci commit network
reboot
EOF
echo ""
echo "=========================================="
echo ""
echo "【サーバー・クライアント両側を再起動】"
echo "  reboot"
echo ""
}

キッティング ファームウェア ビルド

フラッシュ&インストールシステム「焼いたらMAP-E」

システム構成図

ランディングページ(ポータルサイト)

ランディングページ.png

キッティングツール(カスタムビルダー)

キッティングツール.png

機能比較 公式ビルダー カスタムビルダー
基本機能
デバイス検索
バージョン選択
パッケージ追加 手動入力 プリセット + 手動入力
初回起動時設定追加 手動入力 自動生成 + 手動編集
国コード自動設定 ×
言語コード自動設定 ×
タイムゾーン自動設定 ×
ゾーンネーム自動設定 ×
ISP自動判定 ×
日本専用機能
DS-Lite自動設定 × ネットワーク自動構成API連携
MAP-E自動設定 × ネットワーク自動構成API連携
map.shパッチ適用 × ニチバン対策
高度な機能
設定インポート/エクスポート × テキスト形式
ASUサーバー生存確認 × リアルタイム表示
バグ対応
IPv4アドレス変更 × SNAPSHOT対応済み
技術仕様
uci-defaultsサイズ制限 20KB 13KB実装/20KB
APIサーバー ASU公式 ASU公式 + 独自API
ホスティング OpenWrt公式 Cloudflare Pages
オープンソース GitHub公開 GitHub公開

コンソールツール

aios-tui.png


あとがき

0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?