Files
OpenStats/server/geoip/openstats-geoip-update.sh
T
gentpan 0342074489 IP 归属地改用本地 MaxMind GeoLite2:自研 .mmdb 读取器、服务器定时同步、应用校验下载与导入
- Metrics:MaxMindDatabase 按 MaxMind DB 2.0 规范解析搜索树与数据段(内存映射,无第三方依赖),GeoLookup 取国家、城市与 ASN
- 服务器:server/geoip 下的更新脚本与 systemd 定时器,License Key 只放在服务器 /etc/openstats/maxmind.env,生成 manifest.json
- 应用:GeoDatabaseController 每 3 天检查清单,下载后校验 sha256 与库类型再替换;支持从文件导入、可选城市库
- 有本地库时只向外查询公网 IP,归属地与 ASN 本机查询;网络详情标明数据来源;官网部署排除 /geoip/
- 新增读取器单元测试;更新隐私说明、第三方声明与架构文档
2026-09-13 06:40:05 +05:00

57 lines
2.4 KiB
Bash
Executable File
Raw 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/bash
# 在服务器上定时下载 MaxMind GeoLite2 数据库,放到官网 /geoip/ 下供 OpenStats 更新。
#
# 账号与 License Key 只放在 /etc/openstats/maxmind.env(root 所有,权限 600),
# 不进仓库、不进应用。文件内容:
# MAXMIND_ACCOUNT_ID=你的账号
# MAXMIND_LICENSE_KEY=你的 Key
#
# 每个库先下载 tar.gz 与官方 sha256 校验,解出 .mmdb 后原子替换,最后重写 manifest.json。
set -euo pipefail
ENV_FILE="${ENV_FILE:-/etc/openstats/maxmind.env}"
OUT="${OUT:-/var/www/getopenstats.com/geoip}"
EDITIONS=(${EDITIONS:-GeoLite2-ASN GeoLite2-Country GeoLite2-City})
[ -r "$ENV_FILE" ] || { echo "缺少 $ENV_FILE" >&2; exit 1; }
# shellcheck disable=SC1090
source "$ENV_FILE"
: "${MAXMIND_ACCOUNT_ID:?}" "${MAXMIND_LICENSE_KEY:?}"
WORK="$(mktemp -d)"
trap 'rm -rf "$WORK"' EXIT
mkdir -p "$OUT"
fetch() {
# 凭据通过 curl 配置从标准输入传入,不出现在进程参数里
printf 'user = "%s:%s"\n' "$MAXMIND_ACCOUNT_ID" "$MAXMIND_LICENSE_KEY" \
| curl --config - -fsSL --retry 3 -o "$2" "https://download.maxmind.com/geoip/databases/$1/download?suffix=$3"
}
entries=()
for edition in "${EDITIONS[@]}"; do
fetch "$edition" "$WORK/$edition.tar.gz" "tar.gz"
fetch "$edition" "$WORK/$edition.tar.gz.sha256" "tar.gz.sha256"
expected="$(cut -d' ' -f1 "$WORK/$edition.tar.gz.sha256")"
actual="$(sha256sum "$WORK/$edition.tar.gz" | cut -d' ' -f1)"
[ "$expected" = "$actual" ] || { echo "$edition 校验失败" >&2; exit 1; }
tar -xzf "$WORK/$edition.tar.gz" -C "$WORK"
folder="$(find "$WORK" -maxdepth 1 -type d -name "${edition}_*" | sort | tail -1)"
build="${folder##*_}" # 目录名形如 GeoLite2-ASN_20260912
install -m 644 "$folder/$edition.mmdb" "$OUT/.$edition.mmdb.new"
mv -f "$OUT/.$edition.mmdb.new" "$OUT/$edition.mmdb"
sha="$(sha256sum "$OUT/$edition.mmdb" | cut -d' ' -f1)"
size="$(stat -c %s "$OUT/$edition.mmdb")"
entries+=("{\"edition\":\"$edition\",\"file\":\"$edition.mmdb\",\"build\":\"$build\",\"sha256\":\"$sha\",\"size\":$size}")
echo "$edition $build $size 字节"
done
joined="$(IFS=,; echo "${entries[*]}")"
printf '{"generated":"%s","attribution":"This product includes GeoLite2 data created by MaxMind, available from https://www.maxmind.com.","databases":[%s]}\n' \
"$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$joined" > "$OUT/.manifest.json.new"
mv -f "$OUT/.manifest.json.new" "$OUT/manifest.json"
chmod 644 "$OUT/manifest.json"
echo "manifest.json 已更新"