Japanese notation
はじめに
記事について
Raspberry Pi Zero 2 WのOpenWrt初期設定・運用ガイドです
インストールから各種設定、チューニングなどをまとめています
初心者対応構成
- スクリプトでの自動設定
-
UCI (ttyd)、Webコンソール (LuCi)、ファイラー (SFTP)にて比較作業がおススメ
OpenWrt
インストール
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 | 高負荷/自己責任 |
#! /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
}
フラッシュ&インストールシステム
デバイスアクセス
デバイスアクセス(UCI)
パワーシェルでアクセス
PowerShellの開始
- キー入力:
Win+x>a>はい
UCI(SSH)アクセス
ssh -o StrictHostKeyChecking=no -oHostKeyAlgorithms=+ssh-rsa root@192.168.1.1
- root@192.168.1.1's password:
初期値:パスワード無し
SSHログイン出来ない場合
-
%USERPROFILE%\.ssh\known_hosts※Windows隠しファイル
Clear-Content .ssh\known_hosts -Force
OpenSSHのインストールが無い場合
- 機能の確認
※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
```
---
初期設定
パスワード
初期値から変更
passwd
Changing password for root
New password:
任意のパスワード
Retype password:
再入力
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
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
-
管理画面
192.168.1.1:8080 -
設定
# ポート変更
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)
- 手動インストール
- ダウンロード:WinSCP
- 自動インストール
- キー入力:
Win+x>a>はい - 最新版ソフトウェアのインストール
- キー入力:
$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
インストール
- インストール及びリムーブ
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
- 管理画面ログイン
http://192.168.1.1:8000/
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 "-------------------------------------------------"
- 管理画面ログイン
http://192.168.1.1:10000/
- リムーブ
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 でブラウザを開く
- factory をアップロード
- 数分待つ
あとがき
OSバージョン検証用に作りました
クライアントPCに直接続出来てSDカード交換(書換)で容易に検証環境を作れるUSBドングルなOpenWrt





