Files
2026-04-21 09:34:31 +03:00

322 lines
9.4 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/sh
# ============================================================
# Деплой frpc на роутер OpenWRT без установки пакета.
# frpc скачивается в /tmp при каждой перезагрузке.
# SERVER_IP и FRP_TOKEN получаются автоматически с bootstrap API.
#
# Использование:
# sh -c "$(wget -qO- https://raw.githubusercontent.com/Official-VPN/Routers-FRP/main/router/setup-tmpfs.sh)"
# или:
# ./setup-tmpfs.sh
#
# Требования: wget с поддержкой HTTPS (встроен в OpenWRT 23/24)
# ============================================================
BOOTSTRAP_DOMAIN="getconfig.tgvpnbot.com"
# --- Определяем архитектуру роутера ---
detect_arch() {
local machine
machine=$(uname -m)
case "$machine" in
mips)
if grep -q "MIPS.*EB\|Big Endian" /proc/cpuinfo 2>/dev/null; then
echo "mips"
else
echo "mipsle"
fi
;;
mipsel) echo "mipsle" ;;
mips64) echo "mips64" ;;
mips64el) echo "mips64le" ;;
armv7l|armv6l) echo "arm" ;;
aarch64) echo "arm64" ;;
x86_64) echo "amd64" ;;
i686|i386) echo "386" ;;
*) echo "unknown" ;;
esac
}
ARCH=$(detect_arch)
if [ "$ARCH" = "unknown" ]; then
echo "ERROR: Cannot detect CPU architecture (uname -m = $(uname -m))"
exit 1
fi
echo "CPU architecture: $(uname -m) → frpc arch: ${ARCH}"
# --- Получаем MAC-адрес WAN-интерфейса ---
WAN_DEV=$(uci get network.wan.device 2>/dev/null)
[ -z "$WAN_DEV" ] && WAN_DEV=$(uci get network.wan.ifname 2>/dev/null)
[ -z "$WAN_DEV" ] && WAN_DEV=$(uci get network.wan6.device 2>/dev/null)
[ -z "$WAN_DEV" ] && WAN_DEV="eth0"
MAC_RAW=$(cat /sys/class/net/"${WAN_DEV}"/address 2>/dev/null)
if [ -z "$MAC_RAW" ]; then
MAC_RAW=$(ip link show "$WAN_DEV" 2>/dev/null | awk '/link\/ether/{print $2}')
fi
if [ -z "$MAC_RAW" ]; then
echo "ERROR: Cannot detect WAN MAC address (device: ${WAN_DEV})"
exit 1
fi
MAC=$(echo "$MAC_RAW" | tr ':' '-' | tr 'a-f' 'A-F')
MAC_PLAIN=$(echo "$MAC_RAW" | tr -d ':' | tr 'a-f' 'A-F')
echo "WAN device : $WAN_DEV"
echo "WAN MAC : $MAC_RAW"
echo "Proxy names: ssh-${MAC} / luci-${MAC}"
echo ""
# --- Получаем SERVER_IP и FRP_TOKEN с bootstrap API ---
echo "Fetching FRP config from ${BOOTSTRAP_DOMAIN} ..."
BOOTSTRAP_RESPONSE=$(wget -q --no-check-certificate \
-O - "https://${BOOTSTRAP_DOMAIN}/getfrpconfig?routermac=${MAC_PLAIN}" 2>/tmp/frpc_bootstrap.log)
if [ -z "$BOOTSTRAP_RESPONSE" ]; then
echo "ERROR: Bootstrap API unreachable or returned empty response"
echo "Check: cat /tmp/frpc_bootstrap.log"
echo "Make sure MAC ${MAC_RAW} is registered in the Router-Configs-Backend"
exit 1
fi
SERVER_IP=$(echo "$BOOTSTRAP_RESPONSE" | sed -n 's/.*"server_ip"[^:]*:[^"]*"\([^"]*\)".*/\1/p')
FRP_TOKEN=$(echo "$BOOTSTRAP_RESPONSE" | sed -n 's/.*"frp_token"[^:]*:[^"]*"\([^"]*\)".*/\1/p')
if [ -z "$SERVER_IP" ] || [ -z "$FRP_TOKEN" ]; then
echo "ERROR: Failed to parse bootstrap response:"
echo "$BOOTSTRAP_RESPONSE"
exit 1
fi
echo "Bootstrap OK: server=${SERVER_IP}"
echo ""
# --- Сохраняем конфиг для бутового скрипта ---
CONFIG_PERSIST="/etc/frpc_bootstrap.conf"
cat > "$CONFIG_PERSIST" <<EOF
# frpc bootstrap config — generated by setup-tmpfs.sh $(date '+%Y-%m-%d %H:%M')
# Для обновления настроек перезагрузите роутер или запустите /etc/init.d/frpc-boot restart
BOOTSTRAP_DOMAIN="${BOOTSTRAP_DOMAIN}"
SERVER_IP="${SERVER_IP}"
FRP_TOKEN="${FRP_TOKEN}"
FRP_ARCH="${ARCH}"
MAC="${MAC}"
MAC_RAW="${MAC_RAW}"
MAC_PLAIN="${MAC_PLAIN}"
FRP_VERSION="0.61.1"
EOF
echo "Bootstrap config saved: $CONFIG_PERSIST"
# --- Настраиваем dropbear: слушать на всех интерфейсах ---
echo "Configuring dropbear to listen on all interfaces ..."
uci set dropbear.@dropbear[0].Interface=''
uci commit dropbear
/etc/init.d/dropbear restart
echo "dropbear restarted"
echo ""
# --- Создаём бутовый init-скрипт ---
INIT_SCRIPT="/etc/init.d/frpc-boot"
cat > "$INIT_SCRIPT" <<'INITEOF'
#!/bin/sh /etc/rc.common
# frpc-boot — при каждом ребуте: обновляет конфиг с bootstrap API,
# скачивает frpc в /tmp и запускает его.
START=99
STOP=10
USE_PROCD=1
CONF="/etc/frpc_bootstrap.conf"
FRPC_BIN="/tmp/frpc"
FRPC_CONF="/tmp/frpc.toml"
FRPC_LOG="/tmp/frpc.log"
DOWNLOAD_BASE="https://github.com/fatedier/frp/releases/download"
load_config() {
if [ ! -f "$CONF" ]; then
logger -t frpc-boot "ERROR: $CONF not found"
return 1
fi
. "$CONF"
if [ -z "$MAC" ] || [ -z "$FRP_ARCH" ]; then
logger -t frpc-boot "ERROR: incomplete config in $CONF"
return 1
fi
return 0
}
# Обновляем SERVER_IP и FRP_TOKEN с bootstrap API
fetch_frp_config() {
if [ -z "$BOOTSTRAP_DOMAIN" ]; then
logger -t frpc-boot "No BOOTSTRAP_DOMAIN, using cached config"
return 0
fi
logger -t frpc-boot "Fetching FRP config from ${BOOTSTRAP_DOMAIN} ..."
local response
response=$(wget -q --no-check-certificate \
-O - "https://${BOOTSTRAP_DOMAIN}/getfrpconfig?routermac=${MAC_PLAIN}" \
2>/tmp/frpc_bootstrap.log) || true
if [ -z "$response" ]; then
logger -t frpc-boot "Bootstrap unreachable, using cached config (${SERVER_IP})"
return 0
fi
local new_ip new_token
new_ip=$(echo "$response" | sed -n 's/.*"server_ip"[^:]*:[^"]*"\([^"]*\)".*/\1/p')
new_token=$(echo "$response" | sed -n 's/.*"frp_token"[^:]*:[^"]*"\([^"]*\)".*/\1/p')
if [ -n "$new_ip" ] && [ -n "$new_token" ]; then
if [ "$new_ip" != "$SERVER_IP" ] || [ "$new_token" != "$FRP_TOKEN" ]; then
sed -i "s|^SERVER_IP=.*|SERVER_IP=\"${new_ip}\"|" "$CONF"
sed -i "s|^FRP_TOKEN=.*|FRP_TOKEN=\"${new_token}\"|" "$CONF"
. "$CONF"
logger -t frpc-boot "FRP config updated: server=${new_ip}"
else
logger -t frpc-boot "FRP config unchanged: server=${SERVER_IP}"
fi
else
logger -t frpc-boot "Invalid bootstrap response, using cached config"
fi
}
download_frpc() {
local version="${FRP_VERSION:-0.61.1}"
local arch="${FRP_ARCH}"
local url="${DOWNLOAD_BASE}/v${version}/frp_${version}_linux_${arch}.tar.gz"
local tmp_tar="/tmp/frp_download.tar.gz"
logger -t frpc-boot "Downloading frpc ${version} (${arch}) ..."
if wget -q --no-check-certificate -O "$tmp_tar" "$url" 2>/tmp/frpc_wget.log; then
local tmp_dir="/tmp/frp_extract"
rm -rf "$tmp_dir"
mkdir -p "$tmp_dir"
if tar -xzf "$tmp_tar" -C "$tmp_dir" 2>/tmp/frpc_wget.log; then
mv "$tmp_dir"/frp_*/frpc "$FRPC_BIN" 2>/dev/null \
|| mv "$tmp_dir"/frpc "$FRPC_BIN" 2>/dev/null
chmod +x "$FRPC_BIN"
rm -rf "$tmp_dir" "$tmp_tar"
logger -t frpc-boot "frpc downloaded OK"
return 0
else
logger -t frpc-boot "ERROR: tar failed"
rm -rf "$tmp_dir" "$tmp_tar"
return 1
fi
else
logger -t frpc-boot "ERROR: wget failed — $(cat /tmp/frpc_wget.log)"
rm -f "$tmp_tar"
return 1
fi
}
write_config() {
cat > "$FRPC_CONF" <<EOF
# Generated by frpc-boot at $(date)
# Router MAC: ${MAC}
serverAddr = "${SERVER_IP}"
serverPort = 7000
auth.method = "token"
auth.token = "${FRP_TOKEN}"
log.to = "${FRPC_LOG}"
log.level = "warn"
log.maxDays = 1
[[proxies]]
name = "ssh-${MAC}"
type = "tcp"
localIP = "0.0.0.0"
localPort = 11041
remotePort = 0
[[proxies]]
name = "luci-${MAC}"
type = "tcp"
localIP = "127.0.0.1"
localPort = 80
remotePort = 0
EOF
logger -t frpc-boot "Config written: server=${SERVER_IP}"
}
start_service() {
load_config || return 1
# Обновляем конфиг с bootstrap API (безопасно: при недоступности используем кэш)
fetch_frp_config
if [ -z "$SERVER_IP" ] || [ -z "$FRP_TOKEN" ]; then
logger -t frpc-boot "ERROR: SERVER_IP or FRP_TOKEN not available"
return 1
fi
if [ ! -x "$FRPC_BIN" ]; then
download_frpc || {
logger -t frpc-boot "Cannot start: frpc binary unavailable"
return 1
}
fi
write_config
logger -t frpc-boot "Starting frpc (ssh-${MAC}, luci-${MAC}) ..."
procd_open_instance
procd_set_param command "$FRPC_BIN" -c "$FRPC_CONF"
procd_set_param stdout 0
procd_set_param stderr 0
procd_set_param respawn 300 5 0
procd_close_instance
}
stop_service() {
logger -t frpc-boot "Stopping frpc"
}
boot() {
sleep 10
start
}
INITEOF
chmod +x "$INIT_SCRIPT"
echo "Init script created: $INIT_SCRIPT"
# --- Включаем автозапуск ---
"$INIT_SCRIPT" enable
echo "Service enabled (will start on next boot)"
# --- Запускаем сейчас ---
echo ""
echo "Starting frpc now ..."
"$INIT_SCRIPT" start
sleep 3
# --- Проверка ---
if pgrep frpc >/dev/null 2>&1; then
echo ""
echo "OK: frpc is running"
echo " Server : ${SERVER_IP}"
echo " Binary : /tmp/frpc"
echo " Config : /tmp/frpc.toml"
echo " Proxies: ssh-${MAC} / luci-${MAC}"
else
echo ""
echo "WARNING: frpc may not be running."
echo "Check:"
echo " logread | grep frpc-boot"
echo " cat /tmp/frpc.log"
fi