fix vps_init

This commit is contained in:
eddy
2026-06-18 02:35:53 +08:00
parent a7e396beee
commit fe6f98a1fc
+89 -13
View File
@@ -225,6 +225,59 @@ handle_error() {
# 设置错误跟踪
trap 'handle_error $LINENO' ERR
# ===========================================
# 安全更新软件源:自动检测并禁用失效的软件源
# (例如 Debian 版本归档后失效的 *-backports 源)后重试
# ===========================================
apt_update_safe() {
local tmp retry=0
tmp=$(mktemp)
while :; do
# 执行更新,忽略退出码(失效的源会让 apt 返回非0)
apt-get update > "$tmp" 2>&1 || true
cat "$tmp" >> "$LOG_FILE"
cat "$tmp"
# 没有检测到失效源,更新成功
if ! grep -qiE "no longer has a Release file|404 +Not Found|Failed to fetch" "$tmp"; then
rm -f "$tmp"
return 0
fi
# 已尝试修复过一次,仍有问题则忽略并继续,避免死循环
if [ "$retry" -ge 1 ]; then
log "${YELLOW}部分软件源仍不可用,将忽略失效源并继续${NC}"
rm -f "$tmp"
return 0
fi
log "${YELLOW}检测到失效的软件源,正在自动禁用...${NC}"
# 从 apt 输出中提取失效的套件名(位于 "<url> <suite> Release" 中)
local suites suite
suites=$(grep -oE "The repository '[^']+ Release'" "$tmp" \
| sed -E "s/The repository '(.*) Release'/\1/" \
| awk '{print $NF}' | sort -u)
if [ -z "$suites" ]; then
log "${YELLOW}无法解析失效套件名,将忽略失效源并继续${NC}"
rm -f "$tmp"
return 0
fi
for suite in $suites; do
[ -n "$suite" ] || continue
log "${YELLOW} - 禁用失效套件: ${suite}${NC}"
for f in /etc/apt/sources.list $(ls /etc/apt/sources.list.d/*.list 2>/dev/null); do
[ -f "$f" ] || continue
# 注释掉引用该失效套件的未注释行
sed -i -E "s|^([^#].*[[:space:]]${suite}[[:space:]].*)$|#\1|g" "$f"
done
done
retry=$((retry + 1))
done
}
# ===========================================
# 1. 系统更新
# ===========================================
@@ -238,7 +291,7 @@ fi
# 更新系统包
if [ "$OS_TYPE" = "debian" ]; then
apt update -y || log "${RED}更新软件源失败${NC}"
apt_update_safe
DEBIAN_FRONTEND=noninteractive apt full-upgrade -y || log "${RED}系统升级失败${NC}"
apt install -y wget curl sudo vim git ufw net-tools htop iftop || log "${RED}安装基础软件包失败${NC}"
log "${GREEN}系统更新完成,安装了常用工具${NC}"
@@ -378,11 +431,18 @@ if command -v docker &> /dev/null; then
else
# 安装Docker
if [ "$OS_TYPE" = "debian" ]; then
# 先确保软件源可用(官方脚本内部也会执行 apt update)
apt_update_safe
# 使用官方安装脚本
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
rm get-docker.sh
systemctl enable docker
sh get-docker.sh || log "${RED}Docker安装脚本执行出现问题${NC}"
rm -f get-docker.sh
# 校验Docker是否真正安装成功
if command -v docker &> /dev/null; then
systemctl enable docker 2>/dev/null || log "${YELLOW}无法设置Docker开机自启${NC}"
systemctl start docker 2>/dev/null || true
# 安装Docker Compose
if ! command -v docker-compose &> /dev/null; then
@@ -393,7 +453,10 @@ else
log "${GREEN}Docker安装完成,版本信息:${NC}"
docker --version
docker-compose --version
docker-compose --version 2>/dev/null || docker compose version 2>/dev/null || true
else
log "${RED}Docker安装失败,请检查网络或软件源后重试,可手动执行: curl -fsSL https://get.docker.com | sh${NC}"
fi
else
log "${YELLOW}非Debian系统,请手动安装Docker${NC}"
fi
@@ -406,7 +469,8 @@ log "${BLUE}[6/10] 防火墙设置开始...${NC}"
# 安装UFW
if [ "$OS_TYPE" = "debian" ]; then
apt update -y && apt install -y ufw net-tools lsof
apt_update_safe
apt install -y ufw net-tools lsof || log "${RED}安装防火墙相关软件包(ufw/net-tools/lsof)失败${NC}"
# 确保防火墙默认策略
ufw default deny incoming
@@ -441,8 +505,8 @@ if [ "$OS_TYPE" = "debian" ]; then
LISTENING_PORTS=$(netstat -tlnp 2>/dev/null | grep "LISTEN" | awk '{print $4}' | awk -F: '{print $NF}' | sort -n | uniq)
# 使用lsof作为备选方法
if [ -z "$LISTENING_PORTS" ]; then
LISTENING_PORTS=$(lsof -i -P -n | grep LISTEN | awk '{print $9}' | awk -F: '{print $NF}' | sort -n | uniq)
if [ -z "$LISTENING_PORTS" ] && command -v lsof &> /dev/null; then
LISTENING_PORTS=$(lsof -i -P -n 2>/dev/null | grep LISTEN | awk '{print $9}' | awk -F: '{print $NF}' | sort -n | uniq)
fi
# 如果仍然为空,提示手动检查
@@ -457,7 +521,10 @@ if [ "$OS_TYPE" = "debian" ]; then
"$PORT" -lt "65535" && "$PORT" -gt "1024" ]]; then
# 尝试找出服务名称
SERVICE=$(lsof -i:$PORT -sTCP:LISTEN | grep -v "COMMAND" | awk '{print $1}' | head -1)
SERVICE=""
if command -v lsof &> /dev/null; then
SERVICE=$(lsof -i:$PORT -sTCP:LISTEN 2>/dev/null | grep -v "COMMAND" | awk '{print $1}' | head -1)
fi
if [ -z "$SERVICE" ]; then
SERVICE=$(netstat -tlnp 2>/dev/null | grep ":$PORT" | awk '{print $7}' | cut -d"/" -f2 | head -1)
fi
@@ -579,12 +646,20 @@ log "${BLUE}[9/10] Fail2ban安装开始...${NC}"
if [ "$OS_TYPE" = "debian" ]; then
# 安装Fail2ban
apt update -y && apt install -y fail2ban
systemctl start fail2ban
systemctl enable fail2ban
apt_update_safe
apt install -y fail2ban || log "${RED}安装Fail2ban失败${NC}"
# 校验是否真正安装成功
if ! command -v fail2ban-client &> /dev/null && ! dpkg -l fail2ban 2>/dev/null | grep -q "^ii"; then
log "${RED}Fail2ban未成功安装,跳过其配置(请检查软件源后重试)${NC}"
else
systemctl enable fail2ban 2>/dev/null || log "${YELLOW}无法设置Fail2ban开机自启${NC}"
# 配置Fail2ban
mkdir -p /etc/fail2ban/jail.d
if [ -f /etc/fail2ban/jail.conf ]; then
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
fi
# 清理任何现有配置
rm -rf /etc/fail2ban/jail.d/* 2>/dev/null || true
@@ -604,7 +679,7 @@ EOF
# 重启Fail2ban
log "${YELLOW}重启Fail2ban服务...${NC}"
systemctl restart fail2ban
systemctl restart fail2ban 2>/dev/null || systemctl start fail2ban 2>/dev/null || log "${RED}Fail2ban服务启动失败${NC}"
# 等待服务启动完成
log "${YELLOW}等待Fail2ban服务完全启动...${NC}"
@@ -640,6 +715,7 @@ EOF
log "${GREEN}Fail2ban安装和配置完成${NC}"
log "${YELLOW}如果出现临时错误,服务器重启后通常会正常工作${NC}"
fi
else
log "${YELLOW}非Debian系统,请手动安装Fail2ban${NC}"
fi