在嵌入式设备上部署内网穿透服务一直是网络工程师和极客玩家的常见需求。OpenWRT作为开源路由器系统的代表,其高度可定制性使其成为运行轻量级服务的理想平台。而frp作为一款高性能的反向代理工具,在0.68.1版本时已经具备稳定的TCP/UDP端口映射能力,特别适合在资源受限的路由器环境中使用。
这个项目的核心价值在于:通过自行编译的方式,将frp 0.68.1客户端/服务端程序移植到OpenWRT平台,实现路由器级别的内网穿透解决方案。相比直接使用预编译版本,自行编译可以确保:
编译前需要准备与目标路由器匹配的OpenWRT SDK。以常见的MT7621平台为例:
bash复制wget https://downloads.openwrt.org/releases/21.02.3/targets/ramips/mt7621/openwrt-sdk-21.02.3-ramips-mt7621_gcc-8.4.0_musl.Linux-x86_64.tar.xz
tar xvf openwrt-sdk-*.tar.xz
cd openwrt-sdk-*
注意:SDK版本必须与路由器上运行的OpenWRT固件版本完全一致,否则可能导致兼容性问题。
frp 0.68.1需要以下基础依赖:
在Ubuntu系统上可通过以下命令安装:
bash复制sudo apt update
sudo apt install -y build-essential golang git upx
使用git获取特定版本源码:
bash复制git clone https://github.com/fatedier/frp.git
cd frp
git checkout v0.68.1
修改Makefile中的关键参数:
makefile复制GO_BUILD_FLAGS = -ldflags "-s -w" -trimpath
GO_LDFLAGS = -s -w
对于OpenWRT的特殊优化:
makefile复制CGO_ENABLED=0 GOOS=linux GOARCH=mipsle GOMIPS=softfloat
提示:mipsle表示小端序的MIPS架构,常见于MTK系路由器。如果是ARM架构设备需改为
GOARCH=arm
bash复制export PATH=$PATH:$(pwd)/staging_dir/toolchain-mipsel_24kc_gcc-8.4.0_musl/bin
export STAGING_DIR=$(pwd)/staging_dir
export CC=mipsel-openwrt-linux-musl-gcc
export CXX=mipsel-openwrt-linux-musl-g++
bash复制make frpc
bash复制make frps
bash复制upx --best --lzma ./bin/frpc
upx --best --lzma ./bin/frps
编译完成后,bin/目录下会生成约3MB左右的优化后二进制文件(未压缩前约8MB)。
使用scp传输编译好的二进制文件:
bash复制scp bin/frpc root@192.168.1.1:/usr/local/bin/
scp bin/frps root@192.168.1.1:/usr/local/bin/
bash复制chmod +x /usr/local/bin/frp*
chown root:root /usr/local/bin/frp*
客户端配置/etc/frp/frpc.ini:
ini复制[common]
server_addr = your_server_ip
server_port = 7000
token = your_secure_token
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000
服务端配置/etc/frp/frps.ini:
ini复制[common]
bind_port = 7000
token = your_secure_token
创建/etc/init.d/frpc:
bash复制#!/bin/sh /etc/rc.common
START=99
STOP=10
start() {
/usr/local/bin/frpc -c /etc/frp/frpc.ini &
}
stop() {
killall frpc
}
bash复制chmod +x /etc/init.d/frpc
/etc/init.d/frpc enable
/etc/init.d/frpc start
TCP多路复用:
在frpc.ini中添加:
ini复制[common]
tcp_mux = true
连接池优化:
ini复制pool_count = 5
日志轮转:
使用logrotate管理日志文件:
bash复制/var/log/frp/*.log {
daily
rotate 7
compress
missingok
notifempty
}
可能原因:
检查命令:
bash复制telnet server_ip 7000
date
解决方案:
ini复制[common]
log_level = warn
典型错误:
illegal instruction
解决方法:
GOMIPS=softfloat参数Token强化:
ini复制token = 使用openssl rand -hex 16生成的随机字符串
TLS加密:
ini复制tls_enable = true
端口限制:
在服务端配置:
ini复制allow_ports = 6000-6010
防火墙规则:
bash复制iptables -A INPUT -p tcp --dport 7000 -j ACCEPT
iptables -A INPUT -p udp --dport 7000 -j DROP
建议的版本管理策略:
bash复制cp bin/frpc /usr/local/bin/frpc-0.68.1
回滚方法:
bash复制rm /usr/local/bin/frpc
ln -s /usr/local/bin/frpc-0.68.1 /usr/local/bin/frpc
在实际部署中,我发现编译时禁用CGO(CGO_ENABLED=0)可以显著减少二进制文件的依赖问题,特别是在不同版本的OpenWRT之间迁移时。另外,对于8MB Flash的路由器,务必使用upx的LZMA压缩算法,虽然压缩时间较长,但能节省约60%的存储空间。