mirror of
https://github.com/andrey271192/kaskad.git
synced 2026-09-20 13:49:56 +00:00
Каскадная маршрутизация русских сайтов через свой набор RU-серверов с failover, Telegram-ботом и веб-интерфейсом. - bin/ — failover-script, route/domain helpers, ams/ru bootstrap - bot/ — Telegram-бот (Python, long-poll) - webui/ — Flask single-page dashboard - docs/ — установка, архитектура, API бота и WebUI - examples/ — шаблоны конфигов
121 lines
3.5 KiB
Bash
Executable File
121 lines
3.5 KiB
Bash
Executable File
#!/bin/bash
|
|
# /usr/local/bin/ru-routes.sh — управление extra-маршрутами через ru-туннель
|
|
set -u
|
|
LIST=/etc/wireguard/ru-extra.list
|
|
BASE=/etc/wireguard/ru-base.aips
|
|
CONF=/etc/wireguard/ru.conf
|
|
XRAY_IF="${XRAY_IF:-amn0}"
|
|
MARK=100
|
|
|
|
touch "$LIST"; chmod 600 "$LIST"
|
|
|
|
valid_cidr() {
|
|
[[ "$1" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}(/[0-9]{1,2})?$ ]] || return 1
|
|
IFS=/ read -r ip mask <<< "$1"
|
|
IFS=. read -r a b c d <<< "$ip"
|
|
for o in $a $b $c $d; do (( o < 0 || o > 255 )) && return 1; done
|
|
if [[ -n "${mask:-}" ]]; then (( mask < 0 || mask > 32 )) && return 1; fi
|
|
return 0
|
|
}
|
|
normalize() { local n="$1"; [[ "$n" == */* ]] || n="$n/32"; echo "$n"; }
|
|
|
|
peer_pk() { awk '/^\[Peer\]/{p=1} p && /^PublicKey *= /{sub(/^PublicKey *= */,""); print; exit}' "$CONF"; }
|
|
current_aips() { awk '/^\[Peer\]/{p=1} p && /^AllowedIPs *= /{sub(/^AllowedIPs *= */,""); print; exit}' "$CONF" | tr -d ' '; }
|
|
|
|
ensure_base() {
|
|
if [ ! -f "$BASE" ]; then
|
|
current_aips > "$BASE"
|
|
chmod 600 "$BASE"
|
|
fi
|
|
}
|
|
|
|
sync_wg() {
|
|
ensure_base
|
|
local pk base extra all
|
|
pk=$(peer_pk)
|
|
base=$(cat "$BASE")
|
|
extra=$(grep -vE '^[[:space:]]*(#|$)' "$LIST" | tr -d ' ' | tr '\n' ',' | sed 's/,$//')
|
|
if [ -n "$extra" ]; then all="$base,$extra"; else all="$base"; fi
|
|
python3 - "$CONF" "$all" <<'PY'
|
|
import sys, re, pathlib
|
|
p = pathlib.Path(sys.argv[1])
|
|
t = p.read_text()
|
|
t = re.sub(r'^AllowedIPs *= .*$', 'AllowedIPs = ' + sys.argv[2], t, count=1, flags=re.M)
|
|
p.write_text(t)
|
|
PY
|
|
wg set ru peer "$pk" allowed-ips "$all" 2>&1
|
|
}
|
|
|
|
apply_route() {
|
|
local net="$1"
|
|
ip route replace "$net" dev ru 2>/dev/null || true
|
|
iptables -t mangle -C PREROUTING -i "$XRAY_IF" -d "$net" -j MARK --set-mark $MARK 2>/dev/null \
|
|
|| iptables -t mangle -A PREROUTING -i "$XRAY_IF" -d "$net" -j MARK --set-mark $MARK 2>/dev/null || true
|
|
}
|
|
remove_route() {
|
|
local net="$1"
|
|
ip route del "$net" dev ru 2>/dev/null || true
|
|
iptables -t mangle -D PREROUTING -i "$XRAY_IF" -d "$net" -j MARK --set-mark $MARK 2>/dev/null || true
|
|
}
|
|
|
|
cmd_list() { if [ -s "$LIST" ]; then cat "$LIST"; else echo "(пусто)"; fi; }
|
|
|
|
cmd_add() {
|
|
local added=0 skipped=0 invalid=()
|
|
for raw in "$@"; do
|
|
if ! valid_cidr "$raw"; then invalid+=("$raw"); continue; fi
|
|
local net; net=$(normalize "$raw")
|
|
if grep -qxF "$net" "$LIST"; then ((skipped++)); else echo "$net" >> "$LIST"; ((added++)); fi
|
|
apply_route "$net"
|
|
done
|
|
sync_wg >/dev/null
|
|
printf "added=%d skipped=%d invalid=%d" "$added" "$skipped" "${#invalid[@]}"
|
|
((${#invalid[@]})) && printf " (%s)" "${invalid[*]}"
|
|
echo
|
|
}
|
|
|
|
cmd_remove() {
|
|
local removed=0 missing=0
|
|
for raw in "$@"; do
|
|
valid_cidr "$raw" || continue
|
|
local net; net=$(normalize "$raw")
|
|
if grep -qxF "$net" "$LIST"; then
|
|
grep -vxF "$net" "$LIST" > "$LIST.tmp"; mv "$LIST.tmp" "$LIST"
|
|
((removed++))
|
|
else ((missing++)); fi
|
|
remove_route "$net"
|
|
done
|
|
sync_wg >/dev/null
|
|
echo "removed=$removed missing=$missing"
|
|
}
|
|
|
|
cmd_clear() {
|
|
local n=0
|
|
while IFS= read -r net; do
|
|
[[ -z "$net" || "$net" == \#* ]] && continue
|
|
remove_route "$net"; ((n++))
|
|
done < "$LIST"
|
|
: > "$LIST"
|
|
sync_wg >/dev/null
|
|
echo "cleared=$n"
|
|
}
|
|
|
|
cmd_apply() {
|
|
local n=0
|
|
while IFS= read -r net; do
|
|
[[ -z "$net" || "$net" == \#* ]] && continue
|
|
apply_route "$net"; ((n++))
|
|
done < "$LIST"
|
|
sync_wg >/dev/null
|
|
echo "applied=$n"
|
|
}
|
|
|
|
case "${1:-}" in
|
|
list) cmd_list ;;
|
|
add) shift; cmd_add "$@" ;;
|
|
remove|del) shift; cmd_remove "$@" ;;
|
|
clear) cmd_clear ;;
|
|
apply|post-up) cmd_apply ;;
|
|
*) echo "usage: $0 {list|add NET...|remove NET...|clear|apply}"; exit 1 ;;
|
|
esac
|