OpenWRT AP内存受限,如何通过客户端浏览器操作MySQL及执行脚本?
嘿,你的需求完全可以用JavaScript实现,而且根本不用装重型Web服务器或者PHP——OpenWRT本身就带了轻量工具,刚好适配内存受限的路由器!下面给你拆解具体的实现思路:
核心思路:利用OpenWRT自带的轻量Web服务+前端JS
OpenWRT默认预装了uhttpd,这是个占用内存极低的轻量Web服务器,支持CGI脚本。我们可以用静态HTML+前端JS做GUI界面,通过AJAX调用后端的Shell脚本(放在CGI目录)来操作数据库、执行规则,完美避开PHP这类重型依赖。
步骤1:确认uhttpd服务(默认已配置好)
uhttpd默认会把/www/作为静态文件根目录,/www/cgi-bin/作为CGI脚本目录。你只需要确保服务在运行:
/etc/init.d/uhttpd start /etc/init.d/uhttpd enable
步骤2:写前端HTML+JS界面
在/www/下创建index.html,做个简单的UI(比如输入客户端IP、勾选广告阻断开关),用JS发送请求调用后端脚本。举个极简例子:
<!DOCTYPE html> <html> <head> <title>AP规则管理</title> </head> <body> <h3>客户端规则配置</h3> <div> <label>客户端IP:</label> <input type="text" id="clientIp" placeholder="192.168.1.xxx"> </div> <div> <label>广告阻断:</label> <input type="checkbox" id="adBlock"> </div> <button onclick="saveRule()">保存规则</button> <div id="result"></div> <script> function saveRule() { const ip = document.getElementById('clientIp').value; const adBlock = document.getElementById('adBlock').checked ? 'on' : 'off'; // 调用CGI脚本并传递参数 fetch(`/cgi-bin/update_rule.sh?ip=${encodeURIComponent(ip)}&adblock=${adBlock}`) .then(response => response.json()) .then(data => { document.getElementById('result').textContent = `操作结果:${data.status}`; }) .catch(error => { document.getElementById('result').textContent = `出错了:${error.message}`; }); } </script> </body> </html>
步骤3:写后端CGI Shell脚本
在/www/cgi-bin/下创建update_rule.sh,给它加执行权限(chmod +x /www/cgi-bin/update_rule.sh)。这个脚本负责解析前端参数、操作数据库、应用iptables/dnsmasq规则:
#!/bin/sh # 设置响应头为JSON格式 echo "Content-Type: application/json" echo "" # 解析GET参数 QUERY_STRING=$(echo "$QUERY_STRING" | sed 's/%20/ /g') IP=$(echo "$QUERY_STRING" | grep -o 'ip=[^&]*' | cut -d'=' -f2) ADBLOCK=$(echo "$QUERY_STRING" | grep -o 'adblock=[^&]*' | cut -d'=' -f2) # 校验参数避免空值 if [ -z "$IP" ] || [ -z "$ADBLOCK" ]; then echo '{"status": "failed", "msg": "参数缺失"}' exit 1 fi # 操作MySQL(如果觉得内存占用高,推荐换成SQLite,下面有说明) mysql -u your_db_user -p'your_db_pass' your_db_name -e "UPDATE client_rules SET adblock='$ADBLOCK' WHERE ip='$IP';" # 应用iptables规则(示例:阻断指定广告服务器) AD_SERVER="ad.example.com" if [ "$ADBLOCK" = "on" ]; then # 先检查规则是否存在,不存在再添加 iptables -C FORWARD -s "$IP" -d "$AD_SERVER" -j DROP 2>/dev/null || iptables -A FORWARD -s "$IP" -d "$AD_SERVER" -j DROP else # 删除规则(忽略不存在的情况) iptables -D FORWARD -s "$IP" -d "$AD_SERVER" -j DROP 2>/dev/null fi # 返回成功结果 echo '{"status": "success"}'
优化建议:换用SQLite节省内存
如果MySQL的内存占用让你担心,完全可以换成SQLite——它是文件型数据库,不需要后台服务,内存占用极低,非常适合OpenWRT。操作SQLite的Shell命令也很简单,把上面脚本里的MySQL命令换成:
sqlite3 /path/to/your/db.db "UPDATE client_rules SET adblock='$ADBLOCK' WHERE ip='$IP';"
进阶方案:用OpenWRT的ubus总线
如果你想更贴合OpenWRT的生态,还可以把规则逻辑封装成ubus服务,然后前端JS通过JSON-RPC调用ubus的HTTP接口。这样安全性更好,也更符合OpenWRT的设计规范,不过实现起来比CGI稍复杂一点,适合有一定基础的用户。
总结
完全不用纠结PHP或者重型Web服务器,用OpenWRT自带的uhttpd+CGI+前端JS就能轻松实现你的GUI管理需求,而且内存占用极低,完美适配路由器的资源限制。
内容的提问来源于stack exchange,提问作者INIX




