Major structural reorganization and feature additions: ## Folder Reorganization - Move 17 luci-app-* packages to package/secubox/ (except luci-app-secubox core hub) - Update all tooling to support new structure: - secubox-tools/quick-deploy.sh: search both locations - secubox-tools/validate-modules.sh: validate both directories - secubox-tools/fix-permissions.sh: fix permissions in both locations - .github/workflows/test-validate.yml: build from both paths - Update README.md links to new package/secubox/ paths ## AppStore Migration (Complete) - Add catalog entries for all remaining luci-app packages: - network-tweaks.json: Network optimization tools - secubox-bonus.json: Documentation & demos hub - Total: 24 apps in AppStore catalog (22 existing + 2 new) - New category: 'documentation' for docs/demos/tutorials ## VHost Manager v2.0 Enhancements - Add profile activation system for Internal Services and Redirects - Implement createVHost() API wrapper for template-based deployment - Fix Virtual Hosts view rendering with proper LuCI patterns - Fix RPCD backend shell script errors (remove invalid local declarations) - Extend backend validation for nginx return directives (redirect support) - Add section_id parameter for named VHost profiles - Add Remove button to Redirects page for feature parity - Update README to v2.0 with comprehensive feature documentation ## Network Tweaks Dashboard - Close button added to component details modal Files changed: 340+ (336 renames with preserved git history) Packages affected: 19 luci-app, 2 secubox-app, 1 theme, 4 tools 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
34 KiB
Network Modes v0.3.5 Development Codex
Target Version: 0.3.5 Current Version: 0.3.4 Release Date: 2025-01-15 Priority: High - Production Feature Completion Maintainer: SecuBox Development Team
🎯 Mission Statement
Transform luci-app-network-modes from a 50% placeholder UI into a production-ready network mode switching system by implementing real backend functionality for WireGuard relay, web proxy, HTTPS reverse proxy, advanced WiFi features, and packet capture.
📊 Current State Analysis (v0.3.4)
✅ What's Production-Ready (50-60%)
Core Framework:
- ✅ Mode switching with 2-minute auto-rollback protection
- ✅ UCI-based configuration persistence (26 options)
- ✅ Automatic backup/restore (
/etc/network-modes-backup/) - ✅ RPCD backend with 18 methods (1190 lines)
- ✅ 7 JavaScript views with real RPC wiring
- ✅ Status dashboard with interface/service monitoring
Basic Network Modes:
- ✅ Router mode: WAN/LAN, NAT, DHCP server, firewall zones
- ✅ Access Point mode: WiFi channel, HT mode, TX power, bridge DHCP
- ✅ Sniffer mode: Bridge config, promiscuous mode, Netifyd toggle
- ✅ Relay mode: Basic STA+AP relay, relayd configuration
❌ What's Placeholder (40-50%)
Router Mode Gaps:
- ❌ Web proxy (Squid/TinyProxy/Privoxy) - UI only, no config generation
- ❌ HTTPS reverse proxy (Nginx/HAProxy) - no config files created
- ❌ Let's Encrypt automation - no ACME integration
- ❌ DNS over HTTPS - no DoH proxy setup
- ❌ Virtual host deployment - stored in UCI but not applied
Access Point Mode Gaps:
- ❌ 802.11r Fast Roaming - flag set, no MDID/FT config
- ❌ 802.11k RRM - no neighbor reports generated
- ❌ 802.11v BSS Transition - no WNM/TFS rules
- ❌ Band steering - no actual steering algorithm
- ❌ Airtime fairness - flag only, no hostapd config
Relay Mode Gaps:
- ❌ WireGuard key generation - no wg genkey integration
- ❌ WireGuard peer config - UI shows but backend doesn't deploy
- ❌ MTU/MSS clamping - stored but no iptables rules created
- ❌ TCP BBR congestion control - mentioned but not implemented
- ❌ WireGuard interface up/down control
Sniffer Mode Gaps:
- ❌ PCAP capture to file - no tcpdump integration
- ❌ Capture filter validation - stored but not applied
- ❌ SPAN port config - not implemented
- ❌ Wireshark export - mentioned only
- ❌ Long-term packet storage management
🚀 Version 0.3.5 Goals
Primary Objectives
-
Implement WireGuard Relay Features (Critical - 30% of v0.3.5)
- Generate WireGuard private/public keys
- Deploy peer configurations to
/etc/config/network - Create iptables MSS/MTU clamping rules
- Enable TCP BBR congestion control
-
Implement Web Proxy Features (High - 25% of v0.3.5)
- Generate Squid configuration files
- Implement transparent proxy iptables rules
- Add TinyProxy/Privoxy as alternatives
- Create DNS over HTTPS proxy config
-
Implement HTTPS Reverse Proxy (High - 20% of v0.3.5)
- Generate Nginx/HAProxy vhost configs
- Integrate ACME (Let's Encrypt) automation
- Implement certificate renewal cron jobs
- Add SSL certificate validation
-
Implement Advanced WiFi Features (Medium - 15% of v0.3.5)
- Generate 802.11r MDID and FT keys
- Create 802.11k neighbor reports
- Implement basic band steering
- Add hostapd config for 802.11v
-
Implement Packet Capture Features (Medium - 10% of v0.3.5)
- Integrate tcpdump for PCAP capture
- Add capture filter validation
- Implement PCAP rotation logic
- Create passive monitor mode config
Success Criteria
- All 18 RPCD methods have real backend implementations (not just UCI storage)
- Generated configs are validated before deployment
- Services are automatically started/stopped/reloaded
- Rollback mechanism restores service configs (not just UCI)
- Integration tests pass for all 4 network modes
- Documentation updated with real command examples
- No placeholder comments remain in RPCD backend
🔧 Technical Implementation Plan
Phase 1: WireGuard Relay Features (Week 1-2)
Task 1.1: WireGuard Key Management
File: root/usr/libexec/rpcd/luci.network-modes
Method: generate_wireguard_keys() (new)
Implementation:
generate_wireguard_keys() {
# Check if wireguard-tools is installed
if ! command -v wg >/dev/null 2>&1; then
printf '{"error": "wireguard-tools not installed", "success": false}\n'
return 1
fi
# Generate private key
local privkey=$(wg genkey)
local pubkey=$(echo "$privkey" | wg pubkey)
# Store in UCI (encrypted private key)
uci set network-modes.relay.wg_private_key="$privkey"
uci set network-modes.relay.wg_public_key="$pubkey"
uci commit network-modes
printf '{"private_key": "%s", "public_key": "%s", "success": true}\n' \
"$privkey" "$pubkey"
}
Dependencies:
wireguard-toolspackage/etc/config/network-modesrelay section
Validation:
- Keys are 44 characters base64
- Public key derives from private key
- UCI storage is persistent
Task 1.2: WireGuard Interface Deployment
File: root/usr/libexec/rpcd/luci.network-modes
Method: apply_wireguard_config() (new)
Implementation:
apply_wireguard_config() {
local wg_enabled=$(uci -q get network-modes.relay.wireguard_enabled || echo "0")
[ "$wg_enabled" = "1" ] || return 0
local privkey=$(uci -q get network-modes.relay.wg_private_key)
local peer_pubkey=$(uci -q get network-modes.relay.wg_peer_pubkey)
local peer_endpoint=$(uci -q get network-modes.relay.wg_peer_endpoint)
local wg_port=$(uci -q get network-modes.relay.wg_port || echo "51820")
local wg_ip=$(uci -q get network-modes.relay.wg_ip || echo "10.200.200.2/24")
# Create WireGuard interface in /etc/config/network
uci set network.wg0=interface
uci set network.wg0.proto='wireguard'
uci set network.wg0.private_key="$privkey"
uci set network.wg0.listen_port="$wg_port"
uci add_list network.wg0.addresses="$wg_ip"
# Add peer
uci set network.wg0_peer=wireguard_wg0
uci set network.wg0_peer.public_key="$peer_pubkey"
uci set network.wg0_peer.endpoint_host="$peer_endpoint"
uci set network.wg0_peer.endpoint_port="$wg_port"
uci set network.wg0_peer.persistent_keepalive='25'
uci add_list network.wg0_peer.allowed_ips='0.0.0.0/0'
uci commit network
/etc/init.d/network reload
}
Config Example:
config interface 'wg0'
option proto 'wireguard'
option private_key 'AAAA...ZZZZ='
option listen_port '51820'
list addresses '10.200.200.2/24'
config wireguard_wg0
option public_key 'BBBB...YYYY='
option endpoint_host 'vpn.example.com'
option endpoint_port '51820'
option persistent_keepalive '25'
list allowed_ips '0.0.0.0/0'
Task 1.3: MTU/MSS Clamping Rules
File: root/usr/libexec/rpcd/luci.network-modes
Method: apply_mtu_clamping() (new)
Implementation:
apply_mtu_clamping() {
local mtu_optimize=$(uci -q get network-modes.relay.mtu_optimize || echo "0")
[ "$mtu_optimize" = "1" ] || return 0
local wg_mtu=$(uci -q get network-modes.relay.wg_mtu || echo "1420")
local mss_value=$((wg_mtu - 40)) # MTU - TCP/IP headers
# Add MSS clamping to firewall
uci set firewall.mss_clamping=rule
uci set firewall.mss_clamping.name='WireGuard MSS Clamping'
uci set firewall.mss_clamping.src='lan'
uci set firewall.mss_clamping.dest='wan'
uci set firewall.mss_clamping.proto='tcp'
uci set firewall.mss_clamping.tcp_flags='SYN'
uci set firewall.mss_clamping.target='TCPMSS'
uci set firewall.mss_clamping.set_mss="$mss_value"
uci commit firewall
/etc/init.d/firewall reload
}
iptables Rule Generated:
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1380
Task 1.4: TCP BBR Congestion Control
File: root/usr/libexec/rpcd/luci.network-modes
Method: enable_tcp_bbr() (new)
Implementation:
enable_tcp_bbr() {
local tcp_optimize=$(uci -q get network-modes.relay.tcp_optimize || echo "0")
[ "$tcp_optimize" = "1" ] || return 0
# Check kernel support for BBR
if ! modprobe tcp_bbr 2>/dev/null; then
printf '{"error": "BBR not supported by kernel", "success": false}\n'
return 1
fi
# Enable BBR in sysctl
cat > /etc/sysctl.d/90-tcp-bbr.conf <<EOF
net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr
EOF
sysctl -p /etc/sysctl.d/90-tcp-bbr.conf
printf '{"success": true, "congestion_control": "bbr"}\n'
}
Validation:
sysctl net.ipv4.tcp_congestion_control # Should return: bbr
Phase 2: Web Proxy Features (Week 3-4)
Task 2.1: Squid Proxy Configuration
File: root/usr/libexec/rpcd/luci.network-modes
Method: generate_squid_config() (new)
Implementation:
generate_squid_config() {
local proxy_type=$(uci -q get network-modes.router.web_proxy || echo "none")
[ "$proxy_type" = "squid" ] || return 0
local proxy_port=$(uci -q get network-modes.router.proxy_port || echo "3128")
local cache_size=$(uci -q get network-modes.router.proxy_cache_size || echo "256")
# Generate Squid configuration
cat > /etc/squid/squid.conf <<EOF
# SecuBox Network Modes - Squid Configuration
# Generated: $(date)
# Port configuration
http_port $proxy_port transparent
# Cache configuration
cache_dir ufs /var/spool/squid $cache_size 16 256
cache_mem 64 MB
maximum_object_size 4096 KB
minimum_object_size 0 KB
# Access control
acl localnet src 192.168.0.0/16
acl localnet src 10.0.0.0/8
acl localnet src fc00::/7
acl SSL_ports port 443
acl Safe_ports port 80
acl Safe_ports port 443
acl CONNECT method CONNECT
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
http_access allow localnet
http_access allow localhost
http_access deny all
# Logging
access_log /var/log/squid/access.log squid
cache_log /var/log/squid/cache.log
# DNS nameservers
dns_nameservers 1.1.1.1 8.8.8.8
# Forwarding
forwarded_for on
via on
EOF
# Initialize cache directory
mkdir -p /var/spool/squid
mkdir -p /var/log/squid
squid -z 2>/dev/null || true
# Restart Squid
/etc/init.d/squid restart
printf '{"success": true, "proxy": "squid", "port": %d}\n' "$proxy_port"
}
Dependencies:
squidpackage/var/spool/squiddirectory (cache)
Task 2.2: Transparent Proxy iptables Rules
File: root/usr/libexec/rpcd/luci.network-modes
Method: apply_transparent_proxy_rules() (new)
Implementation:
apply_transparent_proxy_rules() {
local proxy_type=$(uci -q get network-modes.router.web_proxy || echo "none")
[ "$proxy_type" != "none" ] || return 0
local proxy_port=$(uci -q get network-modes.router.proxy_port || echo "3128")
# Add redirect rule to firewall
uci set firewall.proxy_redirect=redirect
uci set firewall.proxy_redirect.name='Transparent Web Proxy'
uci set firewall.proxy_redirect.src='lan'
uci set firewall.proxy_redirect.proto='tcp'
uci set firewall.proxy_redirect.src_dport='80'
uci set firewall.proxy_redirect.dest_port="$proxy_port"
uci set firewall.proxy_redirect.target='DNAT'
uci commit firewall
/etc/init.d/firewall reload
}
Generated Rule:
iptables -t nat -A PREROUTING -i br-lan -p tcp --dport 80 -j REDIRECT --to-ports 3128
Task 2.3: DNS over HTTPS (DoH) Proxy
File: root/usr/libexec/rpcd/luci.network-modes
Method: configure_doh_proxy() (new)
Implementation:
configure_doh_proxy() {
local doh_enabled=$(uci -q get network-modes.router.doh_enabled || echo "0")
[ "$doh_enabled" = "1" ] || return 0
local doh_provider=$(uci -q get network-modes.router.doh_provider || echo "cloudflare")
case "$doh_provider" in
cloudflare)
local doh_url="https://1.1.1.1/dns-query"
;;
google)
local doh_url="https://dns.google/dns-query"
;;
quad9)
local doh_url="https://dns.quad9.net/dns-query"
;;
*)
local doh_url="https://1.1.1.1/dns-query"
;;
esac
# Configure dnsmasq to use DNS over HTTPS
uci set dhcp.@dnsmasq[0].noresolv='1'
uci add_list dhcp.@dnsmasq[0].server="127.0.0.1#5053"
uci commit dhcp
# Configure https_dns_proxy
uci set https-dns-proxy.dns.bootstrap_dns='1.1.1.1,1.0.0.1'
uci set https-dns-proxy.dns.listen_addr='127.0.0.1'
uci set https-dns-proxy.dns.listen_port='5053'
uci set https-dns-proxy.dns.url_prefix="$doh_url"
uci commit https-dns-proxy
/etc/init.d/https-dns-proxy restart
/etc/init.d/dnsmasq restart
printf '{"success": true, "doh_provider": "%s"}\n' "$doh_provider"
}
Dependencies:
https-dns-proxypackage- dnsmasq with DoH support
Phase 3: HTTPS Reverse Proxy (Week 5-6)
Task 3.1: Nginx Virtual Host Generator
File: root/usr/libexec/rpcd/luci.network-modes
Method: deploy_nginx_vhosts() (new)
Implementation:
deploy_nginx_vhosts() {
local https_frontend=$(uci -q get network-modes.router.https_frontend || echo "0")
[ "$https_frontend" = "1" ] || return 0
# Get list of virtual hosts from UCI
local vhost_count=0
# Clear existing vhost configs
rm -f /etc/nginx/conf.d/vhost-*.conf
# Iterate through virtual hosts stored in UCI
config_load network-modes
config_cb() {
local type="$1"
local name="$2"
[ "$type" = "vhost" ] || return 0
local domain backend_ip backend_port ssl_enabled
config_get domain "$name" domain
config_get backend_ip "$name" backend_ip
config_get backend_port "$name" backend_port "80"
config_get ssl_enabled "$name" ssl "0"
[ -n "$domain" ] || return 0
# Generate Nginx vhost config
cat > /etc/nginx/conf.d/vhost-${name}.conf <<EOF
# Virtual Host: $domain
# Backend: $backend_ip:$backend_port
# SSL: $ssl_enabled
server {
listen 80;
server_name $domain;
$(if [ "$ssl_enabled" = "1" ]; then
echo " # Redirect to HTTPS"
echo " return 301 https://\$server_name\$request_uri;"
else
echo " location / {"
echo " proxy_pass http://$backend_ip:$backend_port;"
echo " proxy_set_header Host \$host;"
echo " proxy_set_header X-Real-IP \$remote_addr;"
echo " proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;"
echo " proxy_set_header X-Forwarded-Proto \$scheme;"
echo " }"
fi)
}
$(if [ "$ssl_enabled" = "1" ]; then
cat <<SSLEOF
server {
listen 443 ssl http2;
server_name $domain;
ssl_certificate /etc/acme/$domain/fullchain.cer;
ssl_certificate_key /etc/acme/$domain/$domain.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://$backend_ip:$backend_port;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
}
SSLEOF
fi)
EOF
vhost_count=$((vhost_count + 1))
}
config_load network-modes
# Reload Nginx
/etc/init.d/nginx reload
printf '{"success": true, "vhosts_deployed": %d}\n' "$vhost_count"
}
Generated Config Example:
# Virtual Host: app.example.com
server {
listen 443 ssl http2;
server_name app.example.com;
ssl_certificate /etc/acme/app.example.com/fullchain.cer;
ssl_certificate_key /etc/acme/app.example.com/app.example.com.key;
location / {
proxy_pass http://192.168.1.100:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Task 3.2: Let's Encrypt ACME Integration
File: root/usr/libexec/rpcd/luci.network-modes
Method: issue_letsencrypt_cert() (new)
Implementation:
issue_letsencrypt_cert() {
local domain="$1"
[ -n "$domain" ] || return 1
local acme_email=$(uci -q get network-modes.router.acme_email)
[ -n "$acme_email" ] || acme_email="admin@$domain"
# Install acme.sh if not present
if [ ! -f /usr/lib/acme/acme.sh ]; then
opkg update
opkg install acme acme-dnsapi
fi
# Issue certificate using HTTP-01 challenge
/usr/lib/acme/acme.sh --issue \
-d "$domain" \
--webroot /www \
--accountemail "$acme_email" \
--force
if [ $? -eq 0 ]; then
# Install certificate
/usr/lib/acme/acme.sh --install-cert \
-d "$domain" \
--cert-file /etc/acme/$domain/cert.cer \
--key-file /etc/acme/$domain/$domain.key \
--fullchain-file /etc/acme/$domain/fullchain.cer \
--reloadcmd "/etc/init.d/nginx reload"
printf '{"success": true, "domain": "%s", "expires": 90}\n' "$domain"
else
printf '{"success": false, "error": "ACME challenge failed"}\n'
return 1
fi
}
Auto-Renewal Cron Job:
# Add to /etc/crontabs/root
0 0 * * * /usr/lib/acme/acme.sh --cron --home /etc/acme
Task 3.3: SSL Certificate Validation
File: root/usr/libexec/rpcd/luci.network-modes
Method: validate_ssl_cert() (new)
Implementation:
validate_ssl_cert() {
local domain="$1"
[ -n "$domain" ] || return 1
local cert_file="/etc/acme/$domain/fullchain.cer"
[ -f "$cert_file" ] || {
printf '{"valid": false, "error": "Certificate not found"}\n'
return 1
}
# Check expiration date
local expiry_date=$(openssl x509 -enddate -noout -in "$cert_file" | cut -d= -f2)
local expiry_epoch=$(date -d "$expiry_date" +%s 2>/dev/null || echo "0")
local now_epoch=$(date +%s)
local days_left=$(( (expiry_epoch - now_epoch) / 86400 ))
if [ "$days_left" -lt 0 ]; then
printf '{"valid": false, "expired": true, "days_left": %d}\n' "$days_left"
return 1
fi
# Check certificate chain
local issuer=$(openssl x509 -issuer -noout -in "$cert_file" | grep -o 'Let.*Encrypt')
printf '{"valid": true, "domain": "%s", "days_left": %d, "issuer": "%s"}\n' \
"$domain" "$days_left" "$issuer"
}
Phase 4: Advanced WiFi Features (Week 7-8)
Task 4.1: 802.11r Fast Roaming
File: root/usr/libexec/rpcd/luci.network-modes
Method: configure_80211r() (new)
Implementation:
configure_80211r() {
local ft_enabled=$(uci -q get network-modes.accesspoint.ieee80211r || echo "0")
[ "$ft_enabled" = "1" ] || return 0
local ssid=$(uci -q get wireless.@wifi-iface[0].ssid)
local mobility_domain=$(echo -n "$ssid" | md5sum | cut -c1-4)
# Configure hostapd for 802.11r
uci set wireless.@wifi-iface[0].ieee80211r='1'
uci set wireless.@wifi-iface[0].mobility_domain="$mobility_domain"
uci set wireless.@wifi-iface[0].ft_over_ds='1'
uci set wireless.@wifi-iface[0].ft_psk_generate_local='1'
uci set wireless.@wifi-iface[0].reassociation_deadline='1000'
uci commit wireless
wifi reload
printf '{"success": true, "mobility_domain": "%s"}\n' "$mobility_domain"
}
hostapd Config Generated:
mobility_domain=a1b2
ft_over_ds=1
ft_psk_generate_local=1
reassociation_deadline=1000
Task 4.2: 802.11k Neighbor Reports
File: root/usr/libexec/rpcd/luci.network-modes
Method: configure_80211k() (new)
Implementation:
configure_80211k() {
local rrm_enabled=$(uci -q get network-modes.accesspoint.ieee80211k || echo "0")
[ "$rrm_enabled" = "1" ] || return 0
# Enable RRM in hostapd
uci set wireless.@wifi-iface[0].ieee80211k='1'
uci set wireless.@wifi-iface[0].rrm_neighbor_report='1'
uci set wireless.@wifi-iface[0].rrm_beacon_report='1'
uci commit wireless
wifi reload
printf '{"success": true, "rrm_enabled": true}\n'
}
hostapd Config:
rrm_neighbor_report=1
rrm_beacon_report=1
Task 4.3: Band Steering Algorithm
File: root/usr/libexec/rpcd/luci.network-modes
Method: enable_band_steering() (new)
Implementation:
enable_band_steering() {
local band_steering=$(uci -q get network-modes.accesspoint.band_steering || echo "0")
[ "$band_steering" = "1" ] || return 0
# Check if both 2.4GHz and 5GHz radios exist
local radio_2g=$(uci show wireless | grep "radio.*band='2g'" | cut -d. -f2 | cut -d= -f1 | head -n1)
local radio_5g=$(uci show wireless | grep "radio.*band='5g'" | cut -d. -f2 | cut -d= -f1 | head -n1)
if [ -z "$radio_2g" ] || [ -z "$radio_5g" ]; then
printf '{"success": false, "error": "Dual-band radios required"}\n'
return 1
fi
# Enable hostapd band steering (requires wpa_supplicant)
uci set wireless.@wifi-iface[0].bss_load_update_period='60'
uci set wireless.@wifi-iface[0].chan_util_avg_period='600'
uci set wireless.@wifi-iface[0].disassoc_low_ack='1'
uci commit wireless
wifi reload
printf '{"success": true, "band_steering": "enabled"}\n'
}
Phase 5: Packet Capture Features (Week 9)
Task 5.1: tcpdump PCAP Capture
File: root/usr/libexec/rpcd/luci.network-modes
Method: start_packet_capture() (new)
Implementation:
start_packet_capture() {
local pcap_enabled=$(uci -q get network-modes.sniffer.pcap_capture || echo "0")
[ "$pcap_enabled" = "1" ] || return 0
local capture_filter=$(uci -q get network-modes.sniffer.capture_filter || echo "")
local capture_interface=$(uci -q get network-modes.sniffer.capture_interface || echo "br-lan")
local max_size=$(uci -q get network-modes.sniffer.pcap_max_size || echo "100")
local rotate_count=$(uci -q get network-modes.sniffer.pcap_rotate || echo "10")
# Create capture directory
mkdir -p /var/log/pcap
# Kill existing tcpdump
killall tcpdump 2>/dev/null
# Start tcpdump with rotation
tcpdump -i "$capture_interface" \
-w /var/log/pcap/capture.pcap \
-C "$max_size" \
-W "$rotate_count" \
${capture_filter:+-s 0 $capture_filter} \
>/dev/null 2>&1 &
local tcpdump_pid=$!
echo "$tcpdump_pid" > /var/run/tcpdump.pid
printf '{"success": true, "pid": %d, "interface": "%s"}\n' \
"$tcpdump_pid" "$capture_interface"
}
tcpdump Command Example:
tcpdump -i br-lan -w /var/log/pcap/capture.pcap -C 100 -W 10 -s 0 'port 80 or port 443'
Task 5.2: Capture Filter Validation
File: root/usr/libexec/rpcd/luci.network-modes
Method: validate_pcap_filter() (new)
Implementation:
validate_pcap_filter() {
local filter="$1"
[ -n "$filter" ] || {
printf '{"valid": true, "filter": "all"}\n'
return 0
}
# Test filter syntax with tcpdump
if tcpdump -i any -d "$filter" >/dev/null 2>&1; then
printf '{"valid": true, "filter": "%s"}\n' "$filter"
return 0
else
printf '{"valid": false, "error": "Invalid BPF syntax"}\n'
return 1
fi
}
Valid Filter Examples:
port 80 or port 443- HTTP/HTTPS traffictcp and not port 22- All TCP except SSHhost 192.168.1.100- Specific hostnet 10.0.0.0/8- Network range
Task 5.3: PCAP Rotation Management
File: root/usr/libexec/rpcd/luci.network-modes
Method: cleanup_old_pcaps() (new)
Implementation:
cleanup_old_pcaps() {
local max_age=$(uci -q get network-modes.sniffer.pcap_retention_days || echo "7")
local pcap_dir="/var/log/pcap"
# Find and delete old PCAP files
local deleted_count=0
find "$pcap_dir" -name "*.pcap*" -mtime +${max_age} -type f | while read -r pcap_file; do
rm -f "$pcap_file"
deleted_count=$((deleted_count + 1))
done
# Calculate total size
local total_size=$(du -sm "$pcap_dir" 2>/dev/null | cut -f1 || echo "0")
printf '{"success": true, "deleted": %d, "total_size_mb": %d}\n' \
"$deleted_count" "$total_size"
}
Cron Job for Auto-Cleanup:
# Add to /etc/crontabs/root
0 2 * * * /usr/libexec/rpcd/luci.network-modes call cleanup_old_pcaps
🧪 Testing & Validation
Unit Tests
Test File: tests/test-network-modes.sh (new)
#!/bin/sh
# Network Modes v0.3.5 Test Suite
test_wireguard_keys() {
echo "Testing WireGuard key generation..."
result=$(ubus call luci.network-modes generate_wireguard_keys)
privkey=$(echo "$result" | jsonfilter -e '@.private_key')
pubkey=$(echo "$result" | jsonfilter -e '@.public_key')
[ ${#privkey} -eq 44 ] || { echo "FAIL: Private key length"; return 1; }
[ ${#pubkey} -eq 44 ] || { echo "FAIL: Public key length"; return 1; }
echo "PASS: WireGuard keys generated"
}
test_squid_config() {
echo "Testing Squid configuration..."
uci set network-modes.router.web_proxy='squid'
result=$(ubus call luci.network-modes generate_squid_config)
[ -f /etc/squid/squid.conf ] || { echo "FAIL: Squid config not created"; return 1; }
grep -q "http_port 3128 transparent" /etc/squid/squid.conf || { echo "FAIL: Wrong port"; return 1; }
echo "PASS: Squid config generated"
}
test_nginx_vhost() {
echo "Testing Nginx virtual host deployment..."
uci set network-modes.router.https_frontend='1'
uci set network-modes.vhost1=vhost
uci set network-modes.vhost1.domain='test.example.com'
uci set network-modes.vhost1.backend_ip='192.168.1.100'
uci set network-modes.vhost1.backend_port='8080'
uci commit network-modes
result=$(ubus call luci.network-modes deploy_nginx_vhosts)
vhost_count=$(echo "$result" | jsonfilter -e '@.vhosts_deployed')
[ "$vhost_count" -ge 1 ] || { echo "FAIL: No vhosts deployed"; return 1; }
[ -f /etc/nginx/conf.d/vhost-vhost1.conf ] || { echo "FAIL: Vhost config not created"; return 1; }
echo "PASS: Nginx vhost deployed"
}
test_80211r_config() {
echo "Testing 802.11r configuration..."
uci set network-modes.accesspoint.ieee80211r='1'
result=$(ubus call luci.network-modes configure_80211r)
mobility_domain=$(uci -q get wireless.@wifi-iface[0].mobility_domain)
[ -n "$mobility_domain" ] || { echo "FAIL: No mobility domain"; return 1; }
echo "PASS: 802.11r configured (MDID: $mobility_domain)"
}
test_pcap_capture() {
echo "Testing packet capture..."
uci set network-modes.sniffer.pcap_capture='1'
result=$(ubus call luci.network-modes start_packet_capture)
pid=$(echo "$result" | jsonfilter -e '@.pid')
[ -n "$pid" ] && kill -0 "$pid" 2>/dev/null || { echo "FAIL: tcpdump not running"; return 1; }
killall tcpdump
echo "PASS: Packet capture started"
}
# Run all tests
test_wireguard_keys
test_squid_config
test_nginx_vhost
test_80211r_config
test_pcap_capture
echo ""
echo "Test suite completed."
Integration Tests
Test Scenarios:
-
Router Mode with Squid + Nginx
- Enable web_proxy=squid
- Add 2 virtual hosts
- Issue Let's Encrypt certificates
- Verify transparent proxy redirects HTTP traffic
- Verify Nginx proxies HTTPS to backends
-
Access Point with 802.11r/k/v
- Enable all WiFi optimization flags
- Connect 2 devices
- Force roaming between APs
- Verify FT handshake occurs (<50ms)
- Check neighbor reports in hostapd
-
Relay Mode with WireGuard
- Generate WireGuard keys
- Configure peer endpoint
- Apply MTU/MSS clamping
- Enable TCP BBR
- Verify tunnel UP
- Test throughput (should be >90% of baseline)
-
Sniffer Mode with PCAP
- Start packet capture with filter "port 80"
- Generate HTTP traffic
- Verify PCAP files created
- Check rotation works (10 files max)
- Cleanup old captures (7 day retention)
📋 Pre-Release Checklist
Code Quality
- All RPCD methods return valid JSON
- Error handling for missing dependencies (wireguard-tools, squid, nginx, tcpdump)
- Input validation for user-provided data (domains, IPs, filters)
- No hardcoded passwords or secrets
- Shellcheck passes on all RPCD scripts
- No placeholder comments remain
Functionality
- WireGuard keys generate correctly
- Squid config includes cache and ACLs
- Nginx vhosts proxy to backends
- Let's Encrypt certificates issue successfully
- 802.11r MDID is consistent across APs
- tcpdump captures with BPF filters
- PCAP rotation works (file count limit)
- All services start/stop/reload correctly
Safety
- Rollback mechanism restores service configs
- Backup includes /etc/squid/, /etc/nginx/, /etc/acme/
- Config validation before apply
- No destructive operations without confirmation
- Service failures don't brick the router
Documentation
- README.md updated with real command examples
- Dependency list includes new packages
- Configuration examples for each mode
- Troubleshooting section added
- API documentation for new RPCD methods
Testing
- Unit tests pass (test-network-modes.sh)
- Integration tests pass (all 4 modes)
- Manual testing on real hardware
- Performance benchmarks (WireGuard throughput, proxy latency)
- Security audit (no command injection, XSS in UI)
🚢 Release Process
Version Bump
# Update Makefile
sed -i 's/PKG_VERSION:=0.3.4/PKG_VERSION:=0.3.5/' luci-app-network-modes/Makefile
sed -i 's/PKG_RELEASE:=1/PKG_RELEASE:=1/' luci-app-network-modes/Makefile
# Update README.md
sed -i 's/Version: 0.3.4/Version: 0.3.5/' luci-app-network-modes/README.md
# Update MODULE_STATUS.md
# (Update implementation percentage to 85-90%)
Git Workflow
# Commit changes
git add luci-app-network-modes/
git commit -m "feat(network-modes): Implement v0.3.5 production features
- WireGuard: Key generation, peer config, MTU clamping, TCP BBR
- Web Proxy: Squid config, transparent proxy, DoH
- HTTPS: Nginx vhosts, Let's Encrypt, SSL validation
- WiFi: 802.11r/k/v implementation, band steering
- Sniffer: tcpdump integration, PCAP rotation
Closes #XX, #YY, #ZZ"
# Tag release
git tag -a v0.3.5 -m "Release v0.3.5: Production Feature Completion
Major Features:
- WireGuard relay with automatic key management
- Web proxy with Squid/TinyProxy support
- HTTPS reverse proxy with Let's Encrypt
- Advanced WiFi (802.11r/k/v)
- Packet capture with rotation
Testing:
- All unit tests passing
- Integration tests on x86_64, ARM64
- Performance benchmarks included
Breaking Changes: None
Migration: Automatic (UCI config preserved)"
# Push
git push origin master --tags
Build & Deploy
# Build packages for all architectures
./secubox-tools/local-build.sh build luci-app-network-modes
# Test on staging router
scp build/x86-64/luci-app-network-modes_0.3.5-1_all.ipk root@staging:/tmp/
ssh root@staging "opkg install /tmp/luci-app-network-modes_0.3.5-1_all.ipk"
# Deploy to production
# (After testing succeeds)
🎓 Implementation Guidelines
Code Style
- Follow existing RPCD patterns in
luci.network-modes - Use UCI for all configuration storage
- Return JSON with
{"success": true/false}for all methods - Log errors to
/var/log/network-modes.log - Use helper functions for repetitive tasks
Security Best Practices
- Validate all user input (domains, IPs, ports, filters)
- Escape shell variables:
"$var"not$var - Use
uci -q getto avoid errors on missing configs - Check command existence:
command -v cmd >/dev/null - Don't store passwords in UCI (use /etc/shadow or encrypted storage)
Performance Considerations
- Don't restart services unnecessarily (use reload)
- Cache expensive operations (WireGuard key generation)
- Use background jobs for long operations (Let's Encrypt)
- Implement timeouts for external commands
- Clean up temp files after operations
Error Handling
# Example error handling pattern
do_operation() {
local result
result=$(some_command 2>&1) || {
logger -t network-modes "ERROR: some_command failed: $result"
printf '{"success": false, "error": "%s"}\n' "$result"
return 1
}
printf '{"success": true, "result": "%s"}\n' "$result"
}
📊 Success Metrics
Completion Targets:
- Implementation: 85-90% (up from 50-60%)
- Feature Parity: 18/18 RPCD methods fully functional
- Test Coverage: 90%+ unit tests passing
- Documentation: 100% of new features documented
- Performance: <5% overhead vs manual configuration
User Impact:
- One-click WireGuard VPN setup (vs 30+ manual commands)
- Automatic HTTPS with Let's Encrypt (vs hours of nginx config)
- Professional web proxy in 2 clicks (vs Squid complexity)
- WiFi roaming optimization (vs hostapd expertise required)
- Network-wide packet capture (vs tcpdump command-line)
🔗 References
OpenWrt Documentation:
External Tools:
SecuBox Integration:
Next Steps:
- Review this codex with team
- Assign tasks to developers
- Set up development branches
- Begin Phase 1 (WireGuard) implementation
- Weekly progress reviews
Questions/Feedback: Contact maintainers or open GitHub issue
Generated: 2025-12-28 Codex Version: 1.0 Target Release: 2025-01-15