Compare commits
10
Commits
01b23c4985
...
5464fb3424
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5464fb3424 | ||
|
|
c6883c3031 | ||
|
|
17dcebf026 | ||
|
|
1c4bcdbcfb | ||
|
|
06b3e4f436 | ||
|
|
883d4fa74a | ||
|
|
b5aec2875d | ||
|
|
7334d56cb1 | ||
|
|
b41abce532 | ||
|
|
7536e82b5d |
+244
-56
@@ -1,21 +1,93 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo ""
|
||||
printf '%s\n' " ___ __ __ _ _ ___ ______ _ _ "
|
||||
printf '%s\n' " / _ \ / _|/ _(_) ___(_) __ _| \ \ / / _ \| \ | | "
|
||||
printf '%s\n' "| | | | |_| |_| |/ __| |/ _\` | |\ \ / /| |_) | \| | "
|
||||
printf '%s\n' "| |_| | _| _| | (__| | (_| | | \ V / | __/| |\ | "
|
||||
printf '%s\n' " \___/|_| |_| |_|\___|_|\__,_|_| \_/ |_| |_| \_| "
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
echo "-----------------------------------"
|
||||
echo -e "\e[32mRouter OfficialVPN update (do not turn off the power)\e[0m"
|
||||
echo "-----------------------------------"
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
echo " Router Update Script v2.0"
|
||||
echo " ======================================"
|
||||
echo " Do not turn off the power!"
|
||||
echo " ======================================"
|
||||
echo ""
|
||||
|
||||
echo " _____ ___ __ __ ___ ___ _ _ _ _ ___"
|
||||
echo "|_ _|_ _| \/ | __| / __| | | | \| |/ __|"
|
||||
echo " | | | || |\/| | _| \__ \ |_| | .\` | (__ "
|
||||
echo " |_| |___|_| |_|___| |___/\___/|_|\_|\___|"
|
||||
echo ""
|
||||
echo "Syncing time with NTP..."
|
||||
ntpd -n -q -p 0.pool.ntp.org -p 1.pool.ntp.org -p 2.pool.ntp.org
|
||||
echo "Current time: $(date)"
|
||||
echo ""
|
||||
|
||||
echo "Updating sing-box to version 1.11.15-1..."
|
||||
SINGBOX_TARGET_VERSION="1.11.15-1"
|
||||
SINGBOX_CURRENT_VERSION=$(opkg list-installed sing-box 2>/dev/null | awk '{print $3}')
|
||||
|
||||
if [ "$SINGBOX_CURRENT_VERSION" = "$SINGBOX_TARGET_VERSION" ]; then
|
||||
echo "sing-box already at $SINGBOX_TARGET_VERSION, skipping."
|
||||
else
|
||||
echo "Current: ${SINGBOX_CURRENT_VERSION:-not installed}. Upgrading..."
|
||||
|
||||
SINGBOX_UPGRADED=0
|
||||
|
||||
# Primary method: opkg
|
||||
if opkg update && opkg upgrade sing-box; then
|
||||
SINGBOX_UPGRADED=1
|
||||
echo "sing-box upgraded via opkg."
|
||||
else
|
||||
echo "opkg failed. Trying direct ipk download..."
|
||||
fi
|
||||
|
||||
# Fallback: direct ipk download
|
||||
if [ "$SINGBOX_UPGRADED" = "0" ]; then
|
||||
OPENWRT_ARCH=$(opkg print-architecture | grep -v ' all' | grep -v ' noarch' | awk 'NR==1{print $2}')
|
||||
OPENWRT_RELEASE=$(grep DISTRIB_RELEASE /etc/openwrt_release 2>/dev/null | cut -d"'" -f2)
|
||||
if echo "$OPENWRT_RELEASE" | grep -qi "snapshot"; then
|
||||
SINGBOX_IPK_URL="https://downloads.openwrt.org/snapshots/packages/${OPENWRT_ARCH}/packages/sing-box_${SINGBOX_TARGET_VERSION}_${OPENWRT_ARCH}.ipk"
|
||||
else
|
||||
SINGBOX_IPK_URL="https://downloads.openwrt.org/releases/${OPENWRT_RELEASE}/packages/${OPENWRT_ARCH}/packages/sing-box_${SINGBOX_TARGET_VERSION}_${OPENWRT_ARCH}.ipk"
|
||||
fi
|
||||
SINGBOX_IPK_TMP="/tmp/sing-box_${SINGBOX_TARGET_VERSION}.ipk"
|
||||
|
||||
echo "Detected arch: ${OPENWRT_ARCH}, release: ${OPENWRT_RELEASE}"
|
||||
echo "Downloading: ${SINGBOX_IPK_URL}"
|
||||
|
||||
if wget -O "$SINGBOX_IPK_TMP" "$SINGBOX_IPK_URL"; then
|
||||
if opkg install --force-reinstall "$SINGBOX_IPK_TMP"; then
|
||||
echo "sing-box installed from direct ipk."
|
||||
rm -f "$SINGBOX_IPK_TMP"
|
||||
SINGBOX_UPGRADED=1
|
||||
else
|
||||
echo "opkg install failed (dependency issue?). Extracting binary manually..."
|
||||
tar -xzf "$SINGBOX_IPK_TMP" -C /tmp
|
||||
tar -xzf /tmp/data.tar.gz -C /tmp
|
||||
if cp /tmp/usr/bin/sing-box /usr/bin/sing-box && chmod +x /usr/bin/sing-box; then
|
||||
SINGBOX_UPGRADED=1
|
||||
echo "sing-box installed successfully from manual binary extraction."
|
||||
else
|
||||
echo "ERROR: Failed to copy sing-box binary."
|
||||
fi
|
||||
rm -rf /tmp/usr /tmp/data.tar.gz /tmp/debian-binary "$SINGBOX_IPK_TMP"
|
||||
fi
|
||||
else
|
||||
echo "ERROR: Failed to download sing-box ipk. Manual installation may be required."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
echo ""
|
||||
echo "Configuring sing-box service (user=root)..."
|
||||
uci set sing-box.main.enabled='1'
|
||||
uci set sing-box.main.user='root'
|
||||
uci set sing-box.main.conffile='/etc/sing-box/config.json'
|
||||
uci set sing-box.main.workdir='/usr/share/sing-box'
|
||||
uci commit sing-box
|
||||
echo "sing-box service config applied."
|
||||
echo ""
|
||||
|
||||
# 1. Обновить скрипт getdomains
|
||||
cat > /etc/init.d/getdomains << EOF
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
@@ -40,10 +112,8 @@ start () {
|
||||
}
|
||||
EOF
|
||||
|
||||
# 2. Даем права на выполнение
|
||||
chmod +x /etc/init.d/getdomains
|
||||
|
||||
# 3. Создать скрипт для автоматического получения конфига
|
||||
cat > /etc/hotplug.d/iface/40-getvpnconfig << EOF
|
||||
#!/bin/sh
|
||||
|
||||
@@ -58,6 +128,7 @@ request_vpn_config() {
|
||||
REQUEST_URI="https://getconfig.tgvpnbot.com/getrouterconfig?routermac=\$ROUTER_MAC"
|
||||
|
||||
curl \$REQUEST_URI > \$SINGBOX_CONFIG_PATH
|
||||
sed -i 's/"inet4_address": "\([^"]*\)"/"address": ["\1"]/g' \$SINGBOX_CONFIG_PATH
|
||||
|
||||
service sing-box restart
|
||||
}
|
||||
@@ -76,64 +147,181 @@ else
|
||||
fi
|
||||
EOF
|
||||
|
||||
# 4. Скопировать скрипт в другую директорию
|
||||
cp /etc/hotplug.d/iface/40-getvpnconfig /etc/hotplug.d/net/
|
||||
|
||||
# 5. Добавить права на исполнение
|
||||
chmod +x /etc/hotplug.d/iface/40-getvpnconfig
|
||||
|
||||
# 6. Обновление пакетов openwrt
|
||||
# opkg update
|
||||
cat > /etc/hotplug.d/net/30-vpnroute << 'VPNEOF'
|
||||
#!/bin/sh
|
||||
|
||||
# 7. Скачиваем файлы zapret в /tmp
|
||||
# wget -O /tmp/zapret-core.ipk https://raw.githubusercontent.com/Official-VPN/Telegraph-Images/main/zapret-files/zapret-core.ipk
|
||||
# wget -O /tmp/luciapp-zapret.ipk https://raw.githubusercontent.com/Official-VPN/Telegraph-Images/main/zapret-files/luciapp-zapret.ipk
|
||||
sleep 10
|
||||
ip route add table vpn default dev tun0
|
||||
VPNEOF
|
||||
|
||||
# 8. Устанавливаем файлы
|
||||
# if opkg install /tmp/zapret-core.ipk; then
|
||||
# echo "Zapret installed successfully."
|
||||
# else
|
||||
# echo "Failed to install Zapret."
|
||||
# exit 1
|
||||
# fi
|
||||
#
|
||||
# if opkg install /tmp/luciapp-zapret.ipk; then
|
||||
# echo "LuCI app installed successfully."
|
||||
# else
|
||||
# echo "Failed to install LuCI app."
|
||||
# exit 1
|
||||
# fi
|
||||
cat > /etc/hotplug.d/iface/30-vpnroute << 'VPNEOF'
|
||||
#!/bin/sh
|
||||
|
||||
# 9. Удаляем файлы zapret из /tmp
|
||||
# rm /tmp/zapret-core.ipk
|
||||
# rm /tmp/luciapp-zapret.ipk
|
||||
sleep 10
|
||||
ip route add table vpn default dev tun0
|
||||
VPNEOF
|
||||
|
||||
# 10. Удалить старый конфиг (если он есть)
|
||||
rm -rf /etc/sing-box/config.json
|
||||
chmod +x /etc/hotplug.d/net/30-vpnroute
|
||||
chmod +x /etc/hotplug.d/iface/30-vpnroute
|
||||
|
||||
FIREWALL_CONF='/etc/config/firewall'
|
||||
|
||||
add_firewall_rule() {
|
||||
RULE_NAME="$1"
|
||||
RULE_BODY="$2"
|
||||
if ! grep -q "option name '${RULE_NAME}'" "$FIREWALL_CONF"; then
|
||||
echo "" >> "$FIREWALL_CONF"
|
||||
echo "$RULE_BODY" >> "$FIREWALL_CONF"
|
||||
echo "Firewall rule '${RULE_NAME}' added."
|
||||
else
|
||||
echo "Firewall rule '${RULE_NAME}' already exists, skipping."
|
||||
fi
|
||||
}
|
||||
|
||||
add_firewall_rule 'WhatsApp Voice' "config rule
|
||||
option name 'WhatsApp Voice'
|
||||
option src 'lan'
|
||||
option dest '*'
|
||||
option proto 'udp'
|
||||
option set_mark '0x1'
|
||||
option target 'MARK'
|
||||
option family 'ipv4'
|
||||
option dest_port '3478 3479'"
|
||||
|
||||
add_firewall_rule 'Telegram VPN' "config rule
|
||||
option name 'Telegram VPN'
|
||||
option src 'lan'
|
||||
option dest '*'
|
||||
option proto 'all'
|
||||
option set_mark '0x1'
|
||||
option target 'MARK'
|
||||
option family 'ipv4'
|
||||
option dest_ip '91.108.8.0/22 91.108.16.0/22 91.108.12.0/22 149.154.160.0/20 91.105.192.0/23 91.108.20.0/22 185.76.151.0/24 5.28.192.0/18'"
|
||||
|
||||
add_firewall_rule 'VoIP' "config rule
|
||||
option name 'VoIP'
|
||||
option src 'lan'
|
||||
option dest '*'
|
||||
option proto 'udp'
|
||||
option set_mark '0x1'
|
||||
option target 'MARK'
|
||||
option family 'ipv4'
|
||||
option dest_port '5060 5061'"
|
||||
|
||||
add_firewall_rule 'Cloudflare' "config rule
|
||||
option name 'Cloudflare'
|
||||
option src 'lan'
|
||||
option dest '*'
|
||||
option proto 'all'
|
||||
option set_mark '0x1'
|
||||
option target 'MARK'
|
||||
option family 'ipv4'
|
||||
option dest_ip '173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22'"
|
||||
|
||||
add_firewall_rule 'Discord-Default' "config rule
|
||||
option name 'Discord-Default'
|
||||
option src 'lan'
|
||||
option dest '*'
|
||||
option proto 'all'
|
||||
option set_mark '0x1'
|
||||
option target 'MARK'
|
||||
option family 'ipv4'
|
||||
option dest_ip '162.159.130.234 162.159.134.234 162.159.133.234 162.159.135.234 162.159.136.234 162.159.137.232 162.159.135.232 162.159.136.232 162.159.138.232 162.159.128.233 198.244.231.90 162.159.129.233 162.159.130.233 162.159.133.233 162.159.134.233 162.159.135.233 162.159.138.234 162.159.137.234 162.159.134.232 162.159.130.235 162.159.129.235 162.159.129.232 162.159.128.235 162.159.130.232 162.159.133.232 162.159.128.232 34.126.226.51'"
|
||||
|
||||
add_firewall_rule 'Discord-Voice' "config rule
|
||||
option name 'Discord-Voice'
|
||||
option src 'lan'
|
||||
option dest '*'
|
||||
option proto 'udp'
|
||||
option set_mark '0x1'
|
||||
option target 'MARK'
|
||||
option family 'ipv4'
|
||||
option dest_ip '66.22.243.0/24 64.233.165.94 35.207.188.57 35.207.81.249 35.207.171.222 195.62.89.0/24 66.22.192.0/18 66.22.196.0/24 66.22.197.0/24 66.22.198.0/24 66.22.199.0/24 66.22.216.0/24 66.22.217.0/24 66.22.237.0/24 66.22.238.0/24 66.22.241.0/24 66.22.242.0/24 66.22.244.0/24 64.71.8.96/29 34.0.240.0/24 34.0.241.0/24 34.0.242.0/24 34.0.243.0/24 34.0.244.0/24 34.0.245.0/24 34.0.246.0/24 34.0.247.0/24 34.0.248.0/24 34.0.249.0/24 34.0.250.0/24 34.0.251.0/24 12.129.184.160/29 138.128.136.0/21 162.158.0.0/15 172.64.0.0/13 34.0.0.0/15 34.2.0.0/15 35.192.0.0/12 35.208.0.0/12 5.200.14.128/25'"
|
||||
|
||||
add_firewall_rule 'singbox' "config zone
|
||||
option name 'singbox'
|
||||
option device 'tun0'
|
||||
option forward 'ACCEPT'
|
||||
option output 'ACCEPT'
|
||||
option input 'ACCEPT'
|
||||
option masq '1'
|
||||
option mtu_fix '1'
|
||||
option family 'ipv4'"
|
||||
|
||||
add_firewall_rule 'singbox-lan' "config forwarding
|
||||
option name 'singbox-lan'
|
||||
option dest 'singbox'
|
||||
option src 'lan'
|
||||
option family 'ipv4'"
|
||||
|
||||
add_firewall_rule 'vpn_domains' "config ipset
|
||||
option name 'vpn_domains'
|
||||
option match 'dst_net'"
|
||||
|
||||
add_firewall_rule 'mark_domains' "config rule
|
||||
option name 'mark_domains'
|
||||
option src 'lan'
|
||||
option dest '*'
|
||||
option proto 'all'
|
||||
option ipset 'vpn_domains'
|
||||
option set_mark '0x1'
|
||||
option target 'MARK'
|
||||
option family 'ipv4'"
|
||||
|
||||
/etc/init.d/firewall restart
|
||||
|
||||
NETWORK_CONF='/etc/config/network'
|
||||
if ! grep -q "option name 'mark0x1'" "$NETWORK_CONF"; then
|
||||
printf "\nconfig rule\n\toption name 'mark0x1'\n\toption mark '0x1'\n\toption priority '100'\n\toption lookup 'vpn'\n" >> "$NETWORK_CONF"
|
||||
echo "Network rule 'mark0x1' added."
|
||||
else
|
||||
echo "Network rule 'mark0x1' already exists, skipping."
|
||||
fi
|
||||
|
||||
if ! grep -q "^99 vpn" /etc/iproute2/rt_tables; then
|
||||
echo "99 vpn" >> /etc/iproute2/rt_tables
|
||||
echo "VPN routing table entry added."
|
||||
else
|
||||
echo "VPN routing table entry already exists, skipping."
|
||||
fi
|
||||
|
||||
echo "Setting up FRP client..."
|
||||
SETUP_TMPFS_URL="https://raw.githubusercontent.com/Official-VPN/Telegraph-Images/develop/setup-tmpfs.sh"
|
||||
SETUP_TMPFS_TMP="/tmp/setup-tmpfs.sh"
|
||||
|
||||
if curl -f "$SETUP_TMPFS_URL" -o "$SETUP_TMPFS_TMP"; then
|
||||
chmod +x "$SETUP_TMPFS_TMP"
|
||||
sh "$SETUP_TMPFS_TMP"
|
||||
rm -f "$SETUP_TMPFS_TMP"
|
||||
else
|
||||
echo "ERROR: Failed to download setup-tmpfs.sh from GitHub."
|
||||
fi
|
||||
|
||||
rm -f /etc/sing-box/config.json
|
||||
|
||||
# 11. Запустить скрипт 40-getvpnconfig
|
||||
/etc/hotplug.d/iface/40-getvpnconfig
|
||||
|
||||
echo ""
|
||||
echo " ____ ___ _ _ _____ _ "
|
||||
echo " | _ \ / _ \| \ | | ____| |"
|
||||
echo " | | | | | | | \| | _| | |"
|
||||
echo " | |_| | |_| | |\ | |___|_|"
|
||||
echo " |____/ \___/|_| \_|_____(_)"
|
||||
echo ""
|
||||
echo " OfficialVPN router has been updated!"
|
||||
echo " Thanks for waiting :)"
|
||||
echo ""
|
||||
echo " ____ _____ ____ ___ ___ _____ ___ _ _ ____ "
|
||||
echo "| _ \| ____| __ ) / _ \ / _ \_ _|_ _| \ | |/ ___|"
|
||||
echo "| |_) | _| | _ \| | | | | | || | | || \| | | _ "
|
||||
echo "| _ <| |___| |_) | |_| | |_| || | | || |\ | |_| |"
|
||||
echo "|_| \_\_____|____/ \___/ \___/ |_| |___|_| \_|\____|"
|
||||
echo ""
|
||||
echo ""
|
||||
echo "-----------------------------------"
|
||||
echo -e "\e[32mOfficialVPN router has been updated! Thanks for waiting\e[0m"
|
||||
echo "-----------------------------------"
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
echo "-----------------------------------"
|
||||
echo -e "\e[32mThe router will reboot\e[0m"
|
||||
echo "-----------------------------------"
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
echo " The router will reboot in a moment..."
|
||||
echo ""
|
||||
|
||||
reboot
|
||||
|
||||
@@ -139,6 +139,26 @@ add_firewall_rule 'Cloudflare' "config rule
|
||||
option family 'ipv4'
|
||||
option dest_ip '173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22'"
|
||||
|
||||
add_firewall_rule 'Discord-Default' "config rule
|
||||
option name 'Discord-Default'
|
||||
option src 'lan'
|
||||
option dest '*'
|
||||
option proto 'all'
|
||||
option set_mark '0x1'
|
||||
option target 'MARK'
|
||||
option family 'ipv4'
|
||||
option dest_ip '162.159.130.234 162.159.134.234 162.159.133.234 162.159.135.234 162.159.136.234 162.159.137.232 162.159.135.232 162.159.136.232 162.159.138.232 162.159.128.233 198.244.231.90 162.159.129.233 162.159.130.233 162.159.133.233 162.159.134.233 162.159.135.233 162.159.138.234 162.159.137.234 162.159.134.232 162.159.130.235 162.159.129.235 162.159.129.232 162.159.128.235 162.159.130.232 162.159.133.232 162.159.128.232 34.126.226.51'"
|
||||
|
||||
add_firewall_rule 'Discord-Voice' "config rule
|
||||
option name 'Discord-Voice'
|
||||
option src 'lan'
|
||||
option dest '*'
|
||||
option proto 'udp'
|
||||
option set_mark '0x1'
|
||||
option target 'MARK'
|
||||
option family 'ipv4'
|
||||
option dest_ip '66.22.243.0/24 64.233.165.94 35.207.188.57 35.207.81.249 35.207.171.222 195.62.89.0/24 66.22.192.0/18 66.22.196.0/24 66.22.197.0/24 66.22.198.0/24 66.22.199.0/24 66.22.216.0/24 66.22.217.0/24 66.22.237.0/24 66.22.238.0/24 66.22.241.0/24 66.22.242.0/24 66.22.244.0/24 64.71.8.96/29 34.0.240.0/24 34.0.241.0/24 34.0.242.0/24 34.0.243.0/24 34.0.244.0/24 34.0.245.0/24 34.0.246.0/24 34.0.247.0/24 34.0.248.0/24 34.0.249.0/24 34.0.250.0/24 34.0.251.0/24 12.129.184.160/29 138.128.136.0/21 162.158.0.0/15 172.64.0.0/13 34.0.0.0/15 34.2.0.0/15 35.192.0.0/12 35.208.0.0/12 5.200.14.128/25'"
|
||||
|
||||
/etc/init.d/firewall restart
|
||||
|
||||
rm -f /etc/sing-box/config.json
|
||||
|
||||
Executable
+321
@@ -0,0 +1,321 @@
|
||||
#!/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
|
||||
Reference in New Issue
Block a user