mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-13 20:08:05 +08:00
🤞 Sync 2026-10-17 10:45:37
This commit is contained in:
1 parent
1849cc6156
commit
315f273687
107 files changed
+3810
-1215
No files matched your search
@@ -1,10 +1,10 @@
|
||||
#!/bin/sh
|
||||
# MiniGate GeoFence - 地区访问控制
|
||||
# 检查反代访问日志,非允许地区的 IP 用防火墙封禁
|
||||
LOGFILE="/var/log/minigate-geofence.log"
|
||||
CACHE_DIR="/tmp/minigate_geo"
|
||||
LOGFILE="${MINIGATE_GEOFENCE_LOG:-/var/log/minigate-geofence.log}"
|
||||
CACHE_DIR="${MINIGATE_GEO_CACHE_DIR:-/tmp/minigate_geo}"
|
||||
BLOCK_SET="minigate_blocked"
|
||||
ACCESS_LOG="/var/log/minigate-access.log"
|
||||
ACCESS_LOG="${MINIGATE_ACCESS_LOG:-/var/log/minigate-access.log}"
|
||||
|
||||
log() { echo "$(date '+%Y-%m-%d %H:%M:%S') [GEOFENCE] $*" >> "$LOGFILE"; }
|
||||
|
||||
@@ -98,22 +98,37 @@ clean_cache() {
|
||||
[ -d "$CACHE_DIR" ] && find "$CACHE_DIR" -type f -mmin +1440 -delete 2>/dev/null
|
||||
}
|
||||
|
||||
# 局域网、回环、链路本地和运营商 NAT 地址没有归属地,局域网直连时访客就是内网 IP,不参与地区判断
|
||||
is_private_ip() {
|
||||
case "$1" in
|
||||
0.*|10.*|127.*|169.254.*|192.168.*) return 0 ;;
|
||||
172.1[6-9].*|172.2[0-9].*|172.3[01].*) return 0 ;;
|
||||
100.6[4-9].*|100.[7-9][0-9].*|100.1[01][0-9].*|100.12[0-7].*) return 0 ;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
|
||||
# BusyBox grep 不支持 -P,用 sed 取 IPv4 访客地址
|
||||
extract_public_ips() {
|
||||
local ip
|
||||
sed -n 's/.*"client":"\([0-9]\{1,3\}\(\.[0-9]\{1,3\}\)\{3\}\)".*/\1/p' "$ACCESS_LOG" 2>/dev/null | \
|
||||
sort -u | while read -r ip; do
|
||||
is_private_ip "$ip" || echo "$ip"
|
||||
done
|
||||
}
|
||||
|
||||
# 主逻辑:扫描 access log 中的新 IP
|
||||
scan_and_block() {
|
||||
local enabled=$(uci -q get minigate.global.geo_enabled)
|
||||
[ "$enabled" != "1" ] && return 0
|
||||
|
||||
|
||||
local allowed=$(uci -q get minigate.global.geo_allowed)
|
||||
[ -z "$allowed" ] && { log "未配置允许地区,跳过"; return 0; }
|
||||
|
||||
|
||||
init_block_set
|
||||
|
||||
# 提取所有外网 IP(排除内网)
|
||||
local ips=$(grep -oP '"client":"[^"]*"' "$ACCESS_LOG" 2>/dev/null | \
|
||||
grep -oP '[\d\.]+' | \
|
||||
grep -v '^192\.168\.' | grep -v '^10\.' | grep -v '^172\.(1[6-9]|2[0-9]|3[01])\.' | grep -v '^127\.' | \
|
||||
sort -u)
|
||||
|
||||
|
||||
local ips=$(extract_public_ips)
|
||||
|
||||
local checked=0 blocked=0
|
||||
for ip in $ips; do
|
||||
# 已经封禁的跳过
|
||||
@@ -169,6 +184,10 @@ flush_blocks() {
|
||||
log "已清除所有封禁"
|
||||
}
|
||||
|
||||
if [ "${MINIGATE_GEOFENCE_LIBRARY_ONLY:-0}" = "1" ]; then
|
||||
return 0 2>/dev/null || exit 0
|
||||
fi
|
||||
|
||||
case "${1:-scan}" in
|
||||
scan) scan_and_block ;;
|
||||
unblock) unblock_ip "$2" ;;
|
||||
|
||||
@@ -11,6 +11,8 @@ ACCESS_LOG="${MINIGATE_ACCESS_LOG:-/var/log/minigate-access.log}"
|
||||
SOCKET_DIR="${MINIGATE_SOCKET_DIR:-/var/run/minigate}"
|
||||
STREAM_MODULE="${MINIGATE_STREAM_MODULE:-/usr/lib/nginx/modules/ngx_stream_module.so}"
|
||||
ACCESS_LOG_MAX="${MINIGATE_ACCESS_LOG_MAX:-1048576}"
|
||||
# OpenWrt 的 dnsmasq 以 addn-hosts=/tmp/hosts 读取整个目录,收到 SIGHUP 时重新加载
|
||||
LAN_HOSTS_FILE="${MINIGATE_LAN_HOSTS_FILE:-/tmp/hosts/minigate}"
|
||||
|
||||
log() { echo "$(date '+%Y-%m-%d %H:%M:%S') [PROXY] $*" >> "$LOGFILE"; }
|
||||
|
||||
@@ -375,6 +377,89 @@ generate_sites() {
|
||||
rm -f /tmp/minigate_stream_*.tmp
|
||||
}
|
||||
|
||||
# === 局域网直连解析 ===
|
||||
# 内网设备把本机反代的域名直接解析到 LAN 地址:不依赖公网 IP、回流 NAT 和上游 DNS 缓存,
|
||||
# 流量留在局域网内,也不会进入代理。公网解析仍由 DDNS 维护。
|
||||
|
||||
is_ipv4() {
|
||||
printf '%s\n' "$1" | awk -F. '
|
||||
NF != 4 { exit 1 }
|
||||
{ for (i = 1; i <= 4; i++) if ($i !~ /^[0-9]+$/ || $i > 255) exit 1 }
|
||||
'
|
||||
}
|
||||
|
||||
# 手动指定优先;留空时取 LAN 接口 IPv4,再退回 network.lan.ipaddr(可能是列表或带 /前缀)
|
||||
get_lan_ip() {
|
||||
local ip
|
||||
ip=$(uci -q get minigate.global.lan_ip)
|
||||
[ -n "$ip" ] || ip=$(ubus call network.interface.lan status 2>/dev/null | \
|
||||
jsonfilter -e '@["ipv4-address"][0].address' 2>/dev/null)
|
||||
[ -n "$ip" ] || ip=$(uci -q get network.lan.ipaddr)
|
||||
ip=${ip%% *}
|
||||
ip=${ip%%/*}
|
||||
is_ipv4 "$ip" && echo "$ip"
|
||||
}
|
||||
|
||||
# 以生成的站点配置为准,只取实际由 nginx 提供的具体域名(跳过默认站点 _ 和通配符)
|
||||
list_site_domains() {
|
||||
cat "$SITES_DIR"/*.conf 2>/dev/null | \
|
||||
sed -n 's/^[[:space:]]*server_name[[:space:]]\{1,\}\([^;]*\);.*/\1/p' | \
|
||||
tr ' ' '\n' | grep -E '^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)+$' | sort -u
|
||||
}
|
||||
|
||||
send_hup() {
|
||||
kill -HUP "$@"
|
||||
}
|
||||
|
||||
reload_dnsmasq_hosts() {
|
||||
local pids
|
||||
pids=$(pidof dnsmasq 2>/dev/null)
|
||||
[ -n "$pids" ] && send_hup $pids >/dev/null 2>&1
|
||||
return 0
|
||||
}
|
||||
|
||||
remove_lan_hosts() {
|
||||
[ -f "$LAN_HOSTS_FILE" ] || return 0
|
||||
rm -f "$LAN_HOSTS_FILE"
|
||||
reload_dnsmasq_hosts
|
||||
log "局域网直连解析已移除"
|
||||
}
|
||||
|
||||
# 内容未变时不重载 dnsmasq,避免每次保存都清空整个 DNS 缓存
|
||||
sync_lan_hosts() {
|
||||
local ip domains domain content
|
||||
if [ "$(uci -q get minigate.global.lan_dns)" != "1" ]; then
|
||||
remove_lan_hosts
|
||||
return 0
|
||||
fi
|
||||
|
||||
ip=$(get_lan_ip)
|
||||
if [ -z "$ip" ]; then
|
||||
log "局域网直连解析:未取得有效的 LAN IPv4 地址,已跳过"
|
||||
remove_lan_hosts
|
||||
return 0
|
||||
fi
|
||||
domains=$(list_site_domains)
|
||||
if [ -z "$domains" ]; then
|
||||
remove_lan_hosts
|
||||
return 0
|
||||
fi
|
||||
|
||||
content="# MiniGate 局域网直连解析,由 proxy.sh 自动生成"
|
||||
for domain in $domains; do
|
||||
content="${content}
|
||||
${ip} ${domain}"
|
||||
done
|
||||
[ -f "$LAN_HOSTS_FILE" ] && [ "$(cat "$LAN_HOSTS_FILE")" = "$content" ] && return 0
|
||||
|
||||
mkdir -p "$(dirname "$LAN_HOSTS_FILE")" && printf '%s\n' "$content" > "$LAN_HOSTS_FILE" || {
|
||||
log "局域网直连解析:写入 ${LAN_HOSTS_FILE} 失败"
|
||||
return 1
|
||||
}
|
||||
reload_dnsmasq_hosts
|
||||
log "局域网直连解析 -> ${ip}: $(echo $domains)"
|
||||
}
|
||||
|
||||
do_stop() {
|
||||
if [ -f "$PID_FILE" ]; then
|
||||
local pid=$(cat "$PID_FILE" 2>/dev/null)
|
||||
@@ -409,7 +494,8 @@ start_prepared() {
|
||||
do_start() {
|
||||
[ -z "$(which nginx 2>/dev/null)" ] && { log "nginx未安装"; return 1; }
|
||||
prepare_config || return 1
|
||||
start_prepared
|
||||
start_prepared || return 1
|
||||
sync_lan_hosts
|
||||
}
|
||||
|
||||
do_reload() {
|
||||
@@ -419,13 +505,15 @@ do_reload() {
|
||||
grep -q '^stream {' "$NGINX_CONF" 2>/dev/null && new_mux=1
|
||||
if [ -f "$PID_FILE" ] && kill -0 $(cat "$PID_FILE" 2>/dev/null) 2>/dev/null; then
|
||||
if [ "$old_mux" != "$new_mux" ]; then
|
||||
start_prepared
|
||||
start_prepared || return 1
|
||||
else
|
||||
kill -HUP $(cat "$PID_FILE") && log "已重载"
|
||||
kill -HUP $(cat "$PID_FILE") || return 1
|
||||
log "已重载"
|
||||
fi
|
||||
else
|
||||
start_prepared
|
||||
start_prepared || return 1
|
||||
fi
|
||||
sync_lan_hosts
|
||||
}
|
||||
|
||||
# /var/log 在内存中且 nginx 不会自行轮转。访问日志保留最近记录到 .1 后原地清空:
|
||||
@@ -443,11 +531,16 @@ trim_logs() {
|
||||
done
|
||||
}
|
||||
|
||||
if [ "${MINIGATE_PROXY_LIBRARY_ONLY:-0}" = "1" ]; then
|
||||
return 0 2>/dev/null || exit 0
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
start) do_start ;;
|
||||
stop) do_stop ;;
|
||||
stop) do_stop; remove_lan_hosts ;;
|
||||
reload) do_reload ;;
|
||||
test) prepare_config ;;
|
||||
trim-logs) trim_logs ;;
|
||||
*) echo "用法: $0 {start|stop|reload|test|trim-logs}" ;;
|
||||
lan-dns) sync_lan_hosts ;;
|
||||
*) echo "用法: $0 {start|stop|reload|test|trim-logs|lan-dns}" ;;
|
||||
esac
|
||||
@@ -213,9 +213,20 @@ remove_program_files() {
|
||||
}
|
||||
|
||||
remove_runtime_files() {
|
||||
local tmp_dir log_dir
|
||||
local tmp_dir log_dir lan_hosts pids
|
||||
tmp_dir="$(root_path /tmp)"
|
||||
log_dir="$(root_path /var/log)"
|
||||
|
||||
# 正常由 init stop 移除;这里兜底,避免卸载后 dnsmasq 仍把代理域名解析到本机
|
||||
lan_hosts="$(root_path /tmp/hosts/minigate)"
|
||||
if [ -f "$lan_hosts" ]; then
|
||||
rm -f "$lan_hosts"
|
||||
if [ "$SKIP_SERVICES" != "1" ] && [ -z "$ROOT" ]; then
|
||||
pids="$(pidof dnsmasq 2>/dev/null || true)"
|
||||
[ -z "$pids" ] || kill -HUP $pids 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -rf \
|
||||
"$(root_path /var/run/minigate)" \
|
||||
"$(root_path /tmp/minigate-update)" \
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
PATH=/usr/sbin:/usr/bin:/sbin:/bin
|
||||
export PATH
|
||||
|
||||
CURRENT_VERSION="2026.10.14-3"
|
||||
CURRENT_VERSION="2026.10.17"
|
||||
REPOSITORY="tpxcer/minigate"
|
||||
API_URL="https://api.github.com/repos/${REPOSITORY}/releases/latest"
|
||||
DOWNLOAD_ROOT="https://github.com/${REPOSITORY}/releases/download"
|
||||
|
||||
Reference in new issue
Block a user