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 Raspberry Pi Zero 2 W (H)

0
Last updated at Posted at 2025-09-21

:flag_jp: Japanese notation

OpenWrt_icon.png

はじめに

記事について

Raspberry Pi Zero 2 WのOpenWrt初期設定・運用ガイドです
インストールから各種設定、チューニングなどをまとめています

初心者対応構成

検証環境

  • Windows 11 24H2

トピック

USBドングル拡張ボードキット

USBドングル拡張ボードキット.jpg


OpenWrt

OpenWrt Project へようこそ

320.logo.png

仕様

Techdata


The UCI system
LuCI web interface

WHR-300CR.png


情報サイト

URL

Raspberry Pi Zero 2 W


インストール

ファームウェア

デバイス用のOpenWrtカスタムファームウェアをダウンロード

イメージのダウンロード > FACTORY (SQUASHFS) をダウンロード

SDカードサイズの拡張

SDカード初期化

※管理者として実行

diskpart
list disk
select disk 
clean

SDカードサイズの拡張

ファイルシステムの拡張



USB NIC

設定
#! /bin/sh
PKGS="kmod-usb-gadget-eth kmod-usb-dwc2"
command -v opkg && opkg update && opkg install $PKGS
command -v apk && apk update && apk add $PKGS
enable_usb_gadget="on"
[ -n "${enable_usb_gadget}" ] && [ -d /boot ] && {
    ! grep -q 'dtoverlay=dwc2' /boot/config.txt && echo 'dtoverlay=dwc2' >> /boot/config.txt
    sed -i 's/rootwait/& modules-load=dwc2,g_ether/' /boot/cmdline.txt
    printf '%s\n%s\n' "dwc2" "g_ether" > /etc/modules.d/99-gadget
    uci add_list network.@device[0].ports='usb0'
    uci commit network
    ifdown usb0 2>/dev/null
    ifup usb0
    modprobe dwc2 2>/dev/null
    modprobe g_ether 2>/dev/null
}

クロックアップ

設定
クロック over_voltage 推奨 備考
1000MHz (標準) 0 ノーマル電圧
1200MHz 2 安定重視
1350MHz 6〜8 高負荷/自己責任

What is config.txt?

#! /bin/sh
OVERCLOCK="1200"
BASE="500"
VOLT="2"

[ -f /boot/config.txt ] && {
  sed -i '/^arm_freq=/d' /boot/config.txt
  sed -i '/^core_freq=/d' /boot/config.txt
  sed -i '/^over_voltage=/d' /boot/config.txt
  cat <<EOF >> /boot/config.txt
arm_freq=${OVERCLOCK}
core_freq=${BASE}
over_voltage=${VOLT}
EOF
sync
}

フラッシュ&インストールシステム

aios.png

デバイスアクセス

デバイスアクセス(UCI)

パワーシェルでアクセス

PowerShellの開始

  • キー入力:Win+x > a > はい

UCI(SSH)アクセス

powershell:初期設定用
ssh -o StrictHostKeyChecking=no -oHostKeyAlgorithms=+ssh-rsa root@192.168.1.1
  • root@192.168.1.1's password:初期値:パスワード無し
SSHログイン出来ない場合:exclamation:
  • %USERPROFILE%\.ssh\known_hosts ※Windows隠しファイル
powershell
Clear-Content .ssh\known_hosts -Force 

OpenSSHのインストールが無い場合:exclamation: - 機能の確認 ※Windows 10 Fall Creators Update(1709)以降標準搭載 ```powershell:powershell Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*' ``` - 機能のインストール ```powershell:powershell Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 ``` ---

LuCi

ブラウザーでアクセス

初期設定

パスワード

初期値から変更
passwd

Changing password for root
New password:

passwd:入力モード
任意のパスワード

Retype password:

passwd:入力モード
再入力

passwd: password for root changed by root

exit

ホストネーム

ホストネーム(openwrt)を変更
#!/bin/sh
HOSTNAME='openwrt' # デバイス名
uci set system.@system[0].hostname=${HOSTNAME}
uci commit system
/etc/init.d/system reload

タイムゾーン

タイムゾーンを変更
#!/bin/sh
TIMEZONE='JST-9'
ZONENAME='Asia/Tokyo'
uci set system.@system[0].timezone=${TIMEZONE}
uci set system.@system[0].zonename=${ZONENAME}
uci commit system
/etc/init.d/sysntpd restart

NTP

NTPサーバーを変更
#!/bin/sh
POOL='jp'
uci delete system.ntp.server
uci add_list system.ntp.server=0.${POOL}.pool.ntp.org
uci add_list system.ntp.server=1.${POOL}.ppl.ntp.org
uci add_list system.ntp.server=2.${POOL}.pool.ntp.org 
uci add_list system.ntp.server=3.${POOL}.pool.ntp.org
uci set system.ntp.enable_server='1'
uci set system.ntp.use_dhcp='0'
uci set system.ntp.interface='lan'
uci commit system
/etc/init.d/sysntpd restart

SSH

WANからのアクセスを遮断
uci set dropbear.@dropbear[0].Interface='lan'
uci commit dropbear

LED

ネットワークアクセスで点灯点滅
#! /bin/sh
uci add system led
uci set system.@led[-1].name='wan'
uci set system.@led[-1].sysfs='green:status'
uci set system.@led[-1].trigger='netdev'
uci set system.@led[-1].dev='wan'
uci set system.@led[-1].mode='link tx rx'
uci add system led
uci set system.@led[-1].name='br-lan'
uci set system.@led[-1].sysfs='blue:wps'
uci set system.@led[-1].trigger='netdev'
uci set system.@led[-1].dev='br-lan'
uci set system.@led[-1].mode='link tx rx'
uci commit system
/etc/init.d/led reload

パッケージ

母国語サポート

LuCiの言語パッケージをインストール
  • 対応言語検索
#! /bin/sh
PATTERN="luci-i18n-base*"
command -v opkg && opkg update && opkg list $PATTERN
command -v apk  && apk update  && apk search $PATTERN
  • 設定
#! /bin/sh
I18N="ja"
PKGS="luci-i18n-base-${I18N} luci-i18n-firewall-${I18N}"
command -v opkg && opkg update && opkg install $PKGS
command -v apk && apk update && apk add $PKGS

UCI(TTYD)

ブラウザーでUCIにアクセス
#! /bin/sh
I18N="ja"
PKGS="luci-i18n-ttyd-${I18N}"
command -v opkg && opkg update && opkg install $PKGS
command -v apk && apk update && apk add $PKGS
uci set ttyd.@ttyd[0].ipv6='1'
uci set ttyd.@ttyd[0].command='/bin/login -f root' #自動ログイン
uci commit ttyd
/etc/init.d/rpcd restart

ファイラー

ブラウザでファイルにアクセス
mkdir -p /tmp/aios && wget -q -O /tmp/aios/install-filebrowser.sh https://raw.githubusercontent.com/site-u2023/aios/main/install-filebrowser.sh && sh /tmp/aios/install-filebrowser.sh
# ポート変更
uci set filebrowser.config.port=9090
# ルートディレクトリ変更  
uci set filebrowser.config.root=/mnt/storage
# ユーザーネーム及びパスワード変更
uci set filebrowser.config.username='root'
uci set filebrowser.config.password='password'
uci commit filebrowser
# 設定確認
uci show filebrowser
# サービス再起動
service filebrowser restart
# 既存DBをリセットしてUCI値で上書きしたいとき
rm /etc/filebrowser/filebrowser.db
service filebrowser restart
  • 使用方法
    filebrowser_main.sh: 自動判定 (インストールまたはリムーブ)
    filebrowser_main.sh install: インストール
    filebrowser_main.sh remove: リムーブ
    filebrowser_main.sh status: 状態確認

WinSCPでファイルにアクセス
#! /bin/sh
PKGS="openssh-sftp-server"
command -v opkg && opkg update && opkg install $PKGS
command -v apk  && apk update  && apk add $PKGS

クライアント設定(Windows)

  • 手動インストール
  • 自動インストール
    • キー入力:Win+x > a > はい
    • 最新版ソフトウェアのインストール
powershell:クライアントPC
$psVersion = $PSVersionTable.PSVersion.Major
$LINKS = Invoke-WebRequest "https://winscp.net/eng/download.php"
$LINKS_VERSION = $LINKS.Links | Where-Object {$_.href -like "*WinSCP-*-Setup.exe*"} | Select-Object -ExpandProperty href
$VERSION = ($LINKS_VERSION -split '/')[-2] -replace "WinSCP-([0-9]+\.[0-9]+\.[0-9]+).*", '$1'
Write-Host "Version to install: $VERSION"
$downloadUrl = "https://jaist.dl.sourceforge.net/project/winscp/WinSCP/$VERSION/WinSCP-$VERSION-Setup.exe?viasf=1"
Write-Host "Downloading from: $downloadUrl"
$ONAMAE = (whoami).Split('\')[1]
$destinationPath = "C:\Users\$ONAMAE\Downloads\WinSCP-$VERSION-Setup.exe"
Invoke-WebRequest -Uri $downloadUrl -OutFile $destinationPath
Write-Host "Installing WinSCP..."
Start-Process -FilePath $destinationPath -ArgumentList "/VERYSILENT /NORESTART" -Wait
Invoke-Expression "C:\Users\$ONAMAE\AppData\Local\Programs\WinSCP\WinSCP.exe"
  • 警告 > 強制的に貼り付け

  • WinSCP設定

    • セッション
      • ホスト名:192.168.1.1
      • ユーザー名:root
      • パスワード:設定したパスワード
      • ログインをクリック

CPU負荷分散

インストール
#! /bin/sh
PKGS="irqbalance"
command -v opkg && opkg update && opkg install $PKGS
command -v apk  && apk update  && apk add $PKGS
uci set irqbalance.irqbalance=irqbalance
uci set irqbalance.irqbalance.enabled='1'
uci commit irqbalance
/etc/init.d/irqbalance start

ネットワーク統計インターフェイス

インストール
#! /bin/sh
I18N="ja"
PKGS="luci-i18n-statistics-${I18N}"
command -v opkg && opkg update && opkg install $PKGS
command -v apk && apk update && apk add $PKGS
/etc/init.d/collectd enable
/etc/init.d/rpcd restart
  • プラグイン検索
#! /bin/sh
PATTERN="collectd-mod\*"
command -v opkg && opkg update && opkg list $PATTERN
command -v apk  && apk update  && apk search $PATTERN

追加テーマ

インストール
#! /bin/sh
PKGS="luci-theme-openwrt luci-theme-material"
command -v opkg && opkg update && opkg install $PKGS
command -v apk  && apk update  && apk add $PKGS

AdGuard Home

インストール

オフィシャル版
OpenWrt版

初期設定

  • インストール及びリムーブ
mkdir -p /tmp && wget --no-check-certificate -O /tmp/adguardhome.sh "https://site-u.pages.dev/www/custom-scripts/adguardhome.sh" && chmod +x /tmp/adguardhome.sh && sh /tmp/adguardhome.sh

Webmin

インストール
  • webminインストール
#!/bin/sh
set -e

## 1. 変数定義
INSTALL_DIR=/usr/libexec/webmin        # Webmin 本体設置先
CONFIG_DIR=/etc/webmin                # 設定ディレクトリ
LOG_DIR=/lib/webmin                   # ログ出力先
PID_DIR=/var/run/webmin               # pid 保存先
USER=admin                            # 管理ユーザー名
PASS=$(tr -dc A-Za-z0-9 </dev/urandom | head -c12)   # ランダムパスワード
PORT=10000                            # リッスンポート

## 2. 依存パッケージのインストール(SSL 有効化に perl-net-ssleay)
opkg update
BASE_PKGS="
  tar gzip unzip shared-mime-info openssl-util
  coreutils coreutils-install coreutils-stty coreutils-df
  make gawk fdisk patch diffutils binutils-objdump
  perl perlbase perlbase-bignum perlbase-commons perlbase-time
  perl-test-warn perl-test-harness
"
PERLBASE_PKGS="$(opkg list | awk '/^perlbase-/{print $1}')"
opkg install $BASE_PKGS $PERLBASE_PKGS --force-overwrite
echo "依存パッケージのインストールが完了しました。"

## 3. グループ「bin」の確認/追加
grep -q '^bin:' /etc/group || echo 'bin:x:2:' >> /etc/group

## 4. ディレクトリ作成
mkdir -p ${INSTALL_DIR} ${CONFIG_DIR} ${LOG_DIR} ${PID_DIR}

## 5. Webmin ダウンロード&展開
wget --no-check-certificate -O /tmp/webmin.tar.gz https://www.webmin.com/download/webmin-current.tar.gz
tar xzf /tmp/webmin.tar.gz -C ${INSTALL_DIR} --strip-components=1

## 6. setup.sh の無人化パッチ
#  atboot=1 → 0(xinetd 非依存化)
#  makeboot=1 行削除
sed -i -e 's/^atboot=1/atboot=0/' -e '/^makeboot=1/d' ${INSTALL_DIR}/setup.sh

## 7. setup.sh を非対話で実行
perl_bin=$(which perl || echo /usr/bin/perl)
os_name="Generic Linux"
os_ver=$(uname -r)
/usr/bin/env bash <<EOF | ${INSTALL_DIR}/setup.sh ${INSTALL_DIR}

${LOG_DIR}
${perl_bin}
${os_name}
${os_ver}
${PORT}
${USER}
${PASS}
${PASS}
n
EOF

## 8. SSL 無効化(SSLeay ライブラリなしでも動くように)
sed -i -e 's/^ssl=1/ssl=0/' ${CONFIG_DIR}/miniserv.conf

## 9. procd/rc.common ベースの init スクリプト作成
cat << 'EOI' > /etc/init.d/webmin
#!/bin/sh /etc/rc.common
START=90
STOP=10
USE_PROCD=1

PIDFILE=/var/run/webmin/miniserv.pid
COMMAND=/etc/webmin/.start-init

start_service() {
    procd_open_instance
    procd_set_param command ${COMMAND}
    procd_set_param pidfile ${PIDFILE}
    procd_set_param respawn
    procd_close_instance
}

stop_service() {
    /etc/webmin/.stop-init
}

reload_service() {
    /etc/webmin/.reload-init
}
EOI

chmod +x /etc/init.d/webmin

## 10. サービス有効化&起動
/etc/init.d/webmin enable
/etc/init.d/webmin start

## 完了メッセージ
echo "-------------------------------------------------"
echo "Webmin Installed!"
echo "URL:   http://$(ip addr show dev br-lan | grep -Po 'inet \K[\d.]+'):${PORT}/"
echo "User:  ${USER}"
echo "Pass:  ${PASS}"
echo "Log:   ${LOG_DIR}/miniserv.log"
echo "-------------------------------------------------"


  • リムーブ
service webmin stop
rm -rf /etc/init.d/webmin
rm -rf /etc/init.d/webmin.old
sed -i "/bin:x:2:/d" /etc/group
sed -i "/webmin/d" /etc/services
/etc/webmin/uninstall.sh

テスト

iperf3

インストール
#!/bin/sh

TMP=/tmp/aios
mkdir -p "$TMP"
cat > "$TMP"/iperf3_setup.sh << 'SCRIPT_END'
#!/bin/sh

# Usage: ./iperf3_setup.sh [start|stop|restart|enable|disable|status|interactive]

SERVICE_FILE="/etc/init.d/iperf3"
PIDFILE="/var/run/iperf3.pid"
LAN="br-lan"

RED='\033[1;31m'
GREEN='\033[1;32m'
YELLOW='\033[1;33m'
BLUE='\033[1;34m'
CYAN='\033[1;36m'
NC='\033[0m'

print_msg() { printf "${1}${2}${NC}\n"; }

get_iface_addrs() {
    local flag=0
    if ip -4 -o addr show dev "$LAN" scope global 2>/dev/null | grep -q 'inet '; then
        NET_ADDR=$(ip -4 -o addr show dev "$LAN" scope global | awk 'NR==1{sub(/\/.*/,"",$4); print $4}')
        flag=$((flag | 1))
    else
        printf "\033[1;33mWarning: No IPv4 address on %s\033[0m\n" "$LAN"
    fi
    
    if ip -6 -o addr show dev "$LAN" scope global 2>/dev/null | grep -q 'inet6 '; then
        NET_ADDR6_LIST=$(ip -6 -o addr show dev "$LAN" scope global | grep -v temporary | awk 'match($4,/^(2|fd|fc)/){sub(/\/.*/,"",$4); print $4;}')
        flag=$((flag | 2))
    else
        printf "\033[1;33mWarning: No IPv6 address on %s\033[0m\n" "$LAN"
    fi
    
    case $flag in
        3) FAMILY_TYPE=any ;;
        1) FAMILY_TYPE=ipv4 ;;
        2) FAMILY_TYPE=ipv6 ;;
        *) FAMILY_TYPE="" ;;
    esac
}

get_lan_ip() {
    get_iface_addrs
    if [ -n "$NET_ADDR" ]; then
        printf "${NET_ADDR}"
    else
        printf "192.168.1.1"
    fi
}

check_package() {
    command -v iperf3 >/dev/null 2>&1 || {
        command -v apk >/dev/null 2>&1 && apk info iperf3 >/dev/null 2>&1
    } || {
        command -v opkg >/dev/null 2>&1 && opkg list-installed | grep -q "^iperf3 "
    }
}

check_service() { [ -f "$SERVICE_FILE" ]; }

install_package(){
  PKGS="iperf3"
  print_msg "$BLUE" "Installing $PKGS package"
  command -v opkg >/dev/null 2>&1 && opkg update >/dev/null 2>&1 && opkg install $PKGS && return 0
  command -v apk  >/dev/null 2>&1 && apk update >/dev/null 2>&1 && apk add $PKGS && return 0
  print_msg "$RED" "No supported package manager found (opkg/apk)"
  return 1
}

create_service() {
    local ip
    ip=$(get_lan_ip)
    print_msg "$BLUE" "Creating iperf3 service for $ip:5201"
    
    cat > "$SERVICE_FILE" << 'SERVICEEOF'
#!/bin/sh /etc/rc.common
START=95
STOP=01
USE_PROCD=1
PROG=/usr/bin/iperf3
pidfile=/var/run/iperf3.pid

start_service() {
    local ip
    ip=$(ip -4 -o addr show dev br-lan scope global 2>/dev/null | awk 'NR==1{sub(/\/.*/,"",$4); print $4}')
    [ -z "$ip" ] && ip="192.168.1.1"
    
    printf "Starting iperf3 server on %s:5201\n" "$ip"
    procd_open_instance
    procd_set_param command "$PROG" --server --daemon --pidfile "$pidfile" --bind "$ip"
    procd_set_param pidfile "$pidfile"
    procd_set_param respawn
    procd_close_instance
}

stop_service() {
    printf "Stopping iperf3 server\n"
    [ -f "$pidfile" ] && {
        pid=$(cat "$pidfile" 2>/dev/null)
        [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null && {
            kill "$pid" 2>/dev/null && printf "iperf3 server stopped\n" || {
                printf "Failed to stop iperf3 server (PID: %s)\n" "$pid"; return 1
            }
        }
        rm -f "$pidfile"
    }
}

status() {
    local ip pid
    ip=$(ip -4 -o addr show dev br-lan scope global 2>/dev/null | awk 'NR==1{sub(/\/.*/,"",$4); print $4}')
    [ -z "$ip" ] && ip="192.168.1.1"
    
    [ -f "$pidfile" ] && {
        pid=$(cat "$pidfile" 2>/dev/null)
        [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null && {
            printf "iperf3 server is running (PID: %s) on %s:5201\n" "$pid" "$ip"; return 0
        }
        printf "iperf3 server is not running (stale pidfile)\n"; rm -f "$pidfile"; return 1
    } || { printf "iperf3 server is not running\n"; return 1; }
}
SERVICEEOF
    
    chmod +x "$SERVICE_FILE"
    print_msg "$GREEN" "Service configured for $ip:5201"
}

install_iperf3() {
  print_msg "$BLUE" "Installing iperf3"
  command -v iperf3 >/dev/null 2>&1 || install_package iperf3 || { print_msg "$RED" "Package installation failed"; return 1; }
  [ -f "$SERVICE_FILE" ]   || create_service  || { print_msg "$RED" "Service creation failed";  return 1; }
  print_msg "$GREEN" "Installation completed"
  printf "${CYAN}service iperf3 [enable|start|stop|status]${NC}\n"
  printf "${CYAN}Test: iperf3 -c $(get_lan_ip) -t 10${NC}\n"
}

remove_iperf3() {
    local auto="$1"
    print_msg "$BLUE" "Removing iperf3"
    
    local pkg=false svc=false
    check_package && pkg=true
    check_service && svc=true
    
    [ "$pkg" = "false" ] && [ "$svc" = "false" ] && { print_msg "$RED" "iperf3 not found"; return 1; }
    
    [ "$auto" != "auto" ] && {
        printf "Remove iperf3? (y/N): "
        read -r confirm
        case "$confirm" in 
            [yY]*) ;; 
            *) print_msg "$YELLOW" "Cancelled"; return 0;; 
        esac
    }
    
    [ "$svc" = "true" ] && {
        print_msg "$BLUE" "Removing service"
        service iperf3 stop 2>/dev/null || true
        service iperf3 disable 2>/dev/null || true
        rm -f "$SERVICE_FILE" "$PIDFILE"
        print_msg "$GREEN" "Service removed"
    }
    
    [ "$pkg" = "true" ] && {
        print_msg "$BLUE" "Removing package"
        if command -v apk >/dev/null 2>&1; then
            apk del iperf3 && print_msg "$GREEN" "Package removed" || { print_msg "$RED" "Remove failed"; return 1; }
        elif command -v opkg >/dev/null 2>&1; then
            opkg remove iperf3 && print_msg "$GREEN" "Package removed" || { print_msg "$RED" "Remove failed"; return 1; }
        else
            print_msg "$YELLOW" "Cannot remove package - no package manager"
        fi
    }
    
    print_msg "$GREEN" "Removal completed"
}

show_usage() {
    printf "Usage: %s [command]\n\n" "$0"
    printf "Commands:\n"
    printf "  start       - Start iperf3 service\n"
    printf "  stop        - Stop iperf3 service\n"
    printf "  restart     - Restart iperf3 service\n"
    printf "  enable      - Enable service at boot\n"
    printf "  disable     - Disable service at boot\n"
    printf "  status      - Show service status\n"
    printf "  interactive - Interactive mode (default)\n"
    printf "  help        - Show this help\n\n"
    printf "Note: Install/Uninstall is determined automatically\n"
}

interactive_mode() {
    while true; do
        printf "\n${BLUE}iperf3 Management${NC}\n"

        check_package && pkg=true || pkg=false
        check_service && svc=true || svc=false
        if [ "$svc" = "true" ]; then
            service iperf3 status >/dev/null 2>&1 && running=true || running=false
        else
            running=false
        fi

        if [ "$pkg" = "false" ] || [ "$svc" = "false" ]; then
            printf "[1] Install iperf3\n"
            printf "[2] Exit\n"
            printf "Please select (1-2): "
            read -r choice

            case "$choice" in
                1)
                    install_iperf3
                    ;;
                2)
                    print_msg "$GREEN" "Goodbye"
                    break
                    ;;
                *)
                    printf "${RED}Invalid selection: %s${NC}\n" "$choice"
                    ;;
            esac

        else
            printf "[1] Start service     [5] Disable service\n"
            printf "[2] Stop service      [6] Show status\n"
            printf "[3] Restart service   [7] Remove iperf3\n"
            printf "[4] Enable service    [8] Exit\n"
            printf "Please select (1-8): "
            read -r choice

            case "$choice" in
                1) service iperf3 start;;
                2) service iperf3 stop;;
                3) service iperf3 restart;;
                4)
                    service iperf3 enable
                    print_msg "$GREEN" "Enabled at boot"
                    ;;
                5)
                    service iperf3 disable
                    print_msg "$GREEN" "Disabled at boot"
                    ;;
                6)
                    service iperf3 status
                    ;;
                7)
                    remove_iperf3
                    ;;
                8)
                    print_msg "$GREEN" "Goodbye"
                    break
                    ;;
                *)
                    printf "${RED}Invalid selection: %s${NC}\n" "$choice"
                    ;;
            esac
        fi

        if [ "$choice" != "2" ] && [ "$choice" != "8" ]; then
            printf "\n${CYAN}Press Enter to continue${NC}"
            read -r dummy 2>/dev/null || true
        fi
    done
}

iperf3_main() {
    case "${1:-interactive}" in
        start|stop|restart)
            check_service || {
                print_msg "$RED" "Service not configured. Run script to install."
                exit 1
            }
            service iperf3 "$1"
            ;;

        enable|disable)
            check_service || {
                print_msg "$RED" "Service not configured. Run script to install."
                exit 1
            }
            service iperf3 "$1"
            print_msg "$GREEN" "Service ${1}d at boot"
            ;;

        status)
            check_service || {
                print_msg "$RED" "Service not configured"
                exit 1
            }
            service iperf3 status
            printf "\n${CYAN}Server: $(get_lan_ip):5201${NC}\n"
            printf "${CYAN}Test: iperf3 -c $(get_lan_ip) -t 10${NC}\n"
            ;;

        interactive)
            interactive_mode
            ;;

        auto-toggle)
            if check_package || check_service; then
                remove_iperf3
            else
                install_iperf3
            fi
            ;;

        help|-h|--help)
            show_usage
            ;;

        *)
            print_msg "$RED" "Unknown command: $1"
            show_usage
            exit 1
            ;;
    esac
}

[ "${0##*/}" = "iperf3_setup.sh" ] && iperf3_main "$@"
SCRIPT_END

chmod +x "$TMP"/iperf3_setup.sh
printf "\n${GREEN}=== iperf3 Setup Script Created ===${NC}\n"
printf "${CYAN}Location: $TMP/iperf3_setup.sh${NC}\n"
printf "${YELLOW}Usage: $TMP/iperf3_setup.sh [start|stop|status|help]${NC}\n"
printf "${YELLOW}Interactive: $TMP/iperf3_setup.sh${NC}\n"

printf "\n${BLUE}Running script in interactive mode${NC}\n"
sh "$TMP"/iperf3_setup.sh
  • サーバー起動 (2回目以降)
/etc/init.d/iperf3 start
  • クライアントで実行
$iperf3 = Get-Command iperf3.exe -ErrorAction SilentlyContinue
if (-not $iperf3) {
    $iperf3 = Get-ChildItem -Path $PWD -Filter iperf3.exe -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1
    if ($iperf3) { $iperf3 = $iperf3.FullName }
    else {
        Write-Host "iperf3.exe が見つかりません。" -ForegroundColor Red
        exit 1
    }
} else {
    $iperf3 = $iperf3.Source
}

$server = (Get-DnsClientServerAddress -AddressFamily IPv4 | Select-Object -ExpandProperty ServerAddresses)[0]

& "$iperf3" -c $server -t 10
  • 追加テスト
& "$iperf3" -c $server -t 60 -P 16 -w 2M
  • リムーブ
sh /tmp/aios/iperf3_setup.sh auto-toggle

トラブル

既知の問題

Raspberry Pi ZERO 2W USBガジェット接続問題

RNDIS接続に失敗する

  • g_etherがCDC ACM(シリアル)として誤認識される

Windows11 25H2でのトラブルではあるが、クライアントPCのSBホストコントローラーやドライバーの組み合わせ次第だと思われる

解決策

  • libcomposite RNDIS方式を使用(VID: 0x1d6b, PID: 0x0104)

Zero 2W

#!/bin/sh
# Raspberry Pi ZERO 2W - libcomposite RNDIS設定スクリプト

# 既存のg_ether設定を削除
echo "dwc2" > /etc/modules.d/99-gadget
sed -i 's/modules-load=dwc2,g_ether/modules-load=dwc2/' /boot/cmdline.txt

# libcomposite RNDISスクリプトを作成
cat > /etc/init.d/usb-gadget << 'GADGET_EOF'
#!/bin/sh /etc/rc.common
START=99
STOP=10

start() {
    mount -t configfs none /sys/kernel/config 2>/dev/null
    modprobe libcomposite
    cd /sys/kernel/config/usb_gadget/ || exit 1
    
    [ -d rndis ] && {
        echo "" > rndis/UDC 2>/dev/null
        rm -rf rndis/configs/c.1/rndis.usb0 2>/dev/null
        rmdir rndis/configs/c.1/strings/0x409 2>/dev/null
        rmdir rndis/configs/c.1 2>/dev/null
        rmdir rndis/functions/rndis.usb0 2>/dev/null
        rmdir rndis/strings/0x409 2>/dev/null
        rmdir rndis 2>/dev/null
    }
    
    mkdir -p rndis && cd rndis || exit 1
    echo 0x1d6b > idVendor
    echo 0x0104 > idProduct
    echo 0x0100 > bcdDevice
    echo 0x0200 > bcdUSB
    
    mkdir -p strings/0x409
    echo "fedcba9876543210" > strings/0x409/serialnumber
    echo "OpenWrt" > strings/0x409/manufacturer
    echo "RNDIS Gadget" > strings/0x409/product
    
    mkdir -p configs/c.1/strings/0x409
    echo "Config 1: RNDIS" > configs/c.1/strings/0x409/configuration
    echo 250 > configs/c.1/MaxPower
    
    mkdir -p functions/rndis.usb0
    echo "02:22:33:44:55:66" > functions/rndis.usb0/host_addr
    echo "02:22:33:44:55:67" > functions/rndis.usb0/dev_addr
    ln -s functions/rndis.usb0 configs/c.1/
    
    UDC=$(ls /sys/class/udc | head -n1)
    echo "$UDC" > UDC
    
    for i in 1 2 3 4 5; do
        [ -d /sys/class/net/usb0 ] && break
        sleep 1
    done
    
    ip link set usb0 up
    brctl addif br-lan usb0 2>/dev/null || true
}

stop() {
    brctl delif br-lan usb0 2>/dev/null
    cd /sys/kernel/config/usb_gadget/rndis 2>/dev/null && {
        echo "" > UDC
        rm -f configs/c.1/rndis.usb0
    }
}
GADGET_EOF

chmod +x /etc/init.d/usb-gadget
/etc/init.d/usb-gadget enable

echo "設定完了。再起動してください: reboot"

Windows11

  • デバイスマネージャー
    • 感嘆符が付いたデバイスなどを見つける
    • ドライバーの更新 > コンピューターを参照してドライバーを検索 > コンピューター上の利用可能なドライバーの一覧から選択します > ネットワークアダプター > Microsoft > USB RNDIS adaptor

初期化

ファクトリーリセット(初期化)

リセット
# 要注意
firstboot && reboot now

This will erase all settings and remove any installed packages. Are you sure? [N/y]

初期化:入力モード
y

デバイスリセットボタン

デバイスのリセットボタンを10秒(LEDが点滅するまで)押し続ける

http://10.10.10.254 でブラウザを開く

スクリーンショット 2025-06-28 111007.jpg

  • factory をアップロード
  • 数分待つ

あとがき

OSバージョン検証用に作りました
クライアントPCに直接続出来てSDカード交換(書換)で容易に検証環境を作れるUSBドングルなOpenWrt

0
0
1

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?