Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4355fe7239 | |||
| 9a1ff4a420 | |||
| 629c840179 | |||
| f927f60163 | |||
| 44b972bc72 | |||
| 18fe538999 | |||
| f3655170ce | |||
| 27bc03f1f5 | |||
| e05746e8cd | |||
| dc1fa22cc5 | |||
| 611cc58734 | |||
| 14f072a53e | |||
| e11ff6d8dc | |||
| b87cdb5bc1 | |||
| 1814fd6348 | |||
| efdf16b63b | |||
| 6882977dce | |||
| 6468c298da | |||
| 8b27e9ada7 | |||
| 56c5f6a99f | |||
| 07d0219e91 | |||
| f40c881050 | |||
| 8da168f68b | |||
| 028262d6ee | |||
| 0f84acf296 | |||
| dd37499c73 | |||
| a2281125b6 | |||
| beb89430a6 | |||
| efbbd6314e | |||
| a67d1e936e | |||
| b2634a40fd | |||
| eac69646e9 | |||
| 3970a4ad0b | |||
| 79d95b2419 | |||
| 52cff5e278 | |||
| e2ff06247c | |||
| 5f7756227d | |||
| 84e5674b80 | |||
| 0733b5bd4d | |||
| 48765d2bcb | |||
| 9ef336f741 | |||
| a4f0b8c761 | |||
| 78839d62c0 | |||
| 1aa2db6d7c |
103
02
103
02
@@ -1,23 +1,96 @@
|
||||
#!/bin/bash
|
||||
# search_all_videos.sh
|
||||
|
||||
echo "开始全面搜索视频文件..."
|
||||
echo "=========================="
|
||||
# ================= 配置区域 =================
|
||||
# 源代码位置 (刚才手动安装的位置)
|
||||
SOURCE_DIR="/usr/local/goedge/edge-admin"
|
||||
# 镜像名称
|
||||
IMAGE_NAME="goedge-admin:local-v1"
|
||||
# 飞牛 NAS 数据存储路径规范
|
||||
NAS_DATA_DIR="/vol1/1000/dock/goedge"
|
||||
# Compose 配置文件名
|
||||
COMPOSE_FILE="$NAS_DATA_DIR/goedge.yml"
|
||||
# ===========================================
|
||||
|
||||
# 搜索容器内部
|
||||
echo "1. 搜索容器内部..."
|
||||
docker exec dysync1 find /app -type f \( -name "*.mp4" -o -name "*.avi" -o -name "*.mkv" -o -name "*.mov" -o -name "*.wmv" \) 2>/dev/null
|
||||
echo "=== 🚀 开始制作 GoEdge Docker 镜像 ==="
|
||||
|
||||
echo "--------------------------"
|
||||
# 1. 检查源目录是否存在
|
||||
if [ ! -d "$SOURCE_DIR" ]; then
|
||||
echo "❌ 错误:找不到源目录 $SOURCE_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 搜索本地映射目录
|
||||
echo "2. 搜索本地映射目录..."
|
||||
find ./data -type f \( -name "*.mp4" -o -name "*.avi" -o -name "*.mkv" -o -name "*.mov" -o -name "*.wmv" \) 2>/dev/null
|
||||
cd "$SOURCE_DIR"
|
||||
|
||||
echo "--------------------------"
|
||||
# 2. 动态生成 Dockerfile
|
||||
# 使用 tail -f 确保容器在前台运行不退出
|
||||
echo "📂 正在生成 Dockerfile..."
|
||||
cat <<EOF > Dockerfile
|
||||
FROM debian:12-slim
|
||||
|
||||
# 搜索整个系统(可能需要权限)
|
||||
echo "3. 搜索系统视频文件(可能需要sudo)..."
|
||||
find /home -type f \( -name "*.mp4" -o -name "*.avi" -o -name "*.mkv" -o -name "*.mov" -o -name "*.wmv" \) 2>/dev/null | head -20
|
||||
# 设置时区和基本环境
|
||||
ENV TZ=Asia/Shanghai
|
||||
WORKDIR /usr/local/goedge/edge-admin
|
||||
|
||||
echo "搜索完成!"
|
||||
# 将当前目录的所有文件复制到镜像中
|
||||
COPY . .
|
||||
|
||||
# 赋予执行权限
|
||||
RUN chmod +x bin/edge-admin
|
||||
|
||||
# 暴露端口 (7788=管理端, 8001=API节点)
|
||||
EXPOSE 7788 8001
|
||||
|
||||
# 启动命令:启动服务并挂起 logs,防止容器退出
|
||||
CMD ["/bin/sh", "-c", "./bin/edge-admin start && tail -f logs/run.log"]
|
||||
EOF
|
||||
|
||||
# 3. 构建 Docker 镜像
|
||||
echo "🐳 正在构建镜像 (这可能需要几秒钟)..."
|
||||
docker build -t "$IMAGE_NAME" .
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "❌ 镜像构建失败!"
|
||||
rm Dockerfile
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 清理临时生成的 Dockerfile
|
||||
rm Dockerfile
|
||||
echo "✅ 镜像 $IMAGE_NAME 构建成功!"
|
||||
|
||||
# 4. 准备飞牛 NAS 目录结构
|
||||
echo "📂 正在创建数据目录结构: $NAS_DATA_DIR ..."
|
||||
mkdir -p "$NAS_DATA_DIR/configs"
|
||||
mkdir -p "$NAS_DATA_DIR/logs"
|
||||
mkdir -p "$NAS_DATA_DIR/data"
|
||||
|
||||
# 5. 生成 docker-compose (goedge.yml)
|
||||
echo "📝 正在生成配置文件: $COMPOSE_FILE ..."
|
||||
cat <<EOF > "$COMPOSE_FILE"
|
||||
version: '3'
|
||||
services:
|
||||
goedge:
|
||||
image: $IMAGE_NAME
|
||||
container_name: goedge-admin
|
||||
restart: always
|
||||
network_mode: "host"
|
||||
volumes:
|
||||
- "$NAS_DATA_DIR/configs:/usr/local/goedge/edge-admin/configs"
|
||||
- "$NAS_DATA_DIR/logs:/usr/local/goedge/edge-admin/logs"
|
||||
- "$NAS_DATA_DIR/data:/usr/local/goedge/edge-admin/data"
|
||||
EOF
|
||||
|
||||
echo ""
|
||||
echo "========================================================"
|
||||
echo "🎉 恭喜!镜像制作与配置生成已完成!"
|
||||
echo "========================================================"
|
||||
echo "1. 镜像名称: $IMAGE_NAME"
|
||||
echo "2. 配置文件: $COMPOSE_FILE"
|
||||
echo "3. 数据目录: $NAS_DATA_DIR"
|
||||
echo ""
|
||||
echo "👉 你现在可以执行以下命令来启动容器:"
|
||||
echo " docker compose -f $COMPOSE_FILE up -d"
|
||||
echo ""
|
||||
echo "💡 如果想把镜像导出保存(备份),请运行:"
|
||||
echo " docker save -o /tmp/goedge-image.tar $IMAGE_NAME"
|
||||
echo "========================================================"
|
||||
627
03
627
03
@@ -1,484 +1,167 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
PURPLE='\033[0;35m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m' # No Color
|
||||
# ================= 配置区域 =================
|
||||
VERSION="1.1.15"
|
||||
DATA_DIR="/var/lib/rustdesk-server"
|
||||
BACKUP_DIR="/tmp/rustdesk_backup_$(date +%s)"
|
||||
# ===========================================
|
||||
|
||||
# 显示标题
|
||||
echo -e "${CYAN}"
|
||||
echo "================================================"
|
||||
echo " 全端口扫描诊断工具 v3.0"
|
||||
echo "================================================"
|
||||
echo -e "${NC}"
|
||||
echo "========================================================"
|
||||
echo " RustDesk Server 全能修复脚本 (安装/转移/修复/启动)"
|
||||
echo "========================================================"
|
||||
|
||||
# 变量定义
|
||||
SCAN_RESULTS=()
|
||||
OPEN_PORTS=()
|
||||
TOTAL_PORTS_SCANNED=0
|
||||
START_TIME=0
|
||||
END_TIME=0
|
||||
# --- 1. 智能查找并备份/转移现有的密钥 ---
|
||||
echo ">>> [1/7] 正在扫描并搜集现有的密钥文件..."
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
# 函数:检查命令是否存在
|
||||
check_command() {
|
||||
if command -v "$1" &> /dev/null; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
# 定义查找函数
|
||||
save_files() {
|
||||
local src_dir=$1
|
||||
if [ -f "${src_dir}/id_ed25519.pub" ]; then
|
||||
echo " 发现密钥在: ${src_dir}"
|
||||
cp "${src_dir}/id_ed25519" "$BACKUP_DIR/" 2>/dev/null
|
||||
cp "${src_dir}/id_ed25519.pub" "$BACKUP_DIR/" 2>/dev/null
|
||||
cp "${src_dir}/db_v2.sqlite3" "$BACKUP_DIR/" 2>/dev/null
|
||||
# 标记为已找到
|
||||
FOUND_KEYS=1
|
||||
fi
|
||||
}
|
||||
|
||||
# 函数:显示帮助信息
|
||||
show_help() {
|
||||
echo -e "${YELLOW}使用说明:${NC}"
|
||||
echo "1. 本工具用于全面扫描目标的所有端口"
|
||||
echo "2. 支持IP地址和域名测试"
|
||||
echo "3. 提供多种扫描模式和速度选项"
|
||||
echo "4. 生成详细的扫描报告"
|
||||
echo ""
|
||||
echo -e "${YELLOW}扫描模式:${NC}"
|
||||
echo " - 快速扫描: 常用端口 (1-1000)"
|
||||
echo " - 标准扫描: 常见服务端口 (1-10000)"
|
||||
echo " - 全面扫描: 所有端口 (1-65535)"
|
||||
echo " - 自定义扫描: 指定端口范围"
|
||||
echo ""
|
||||
}
|
||||
# A. 检查官方目录 (是否有残留)
|
||||
save_files "$DATA_DIR"
|
||||
# B. 检查 Root 目录 (你刚才手动运行产生的地方)
|
||||
save_files "/root"
|
||||
# C. 检查当前目录
|
||||
save_files "$(pwd)"
|
||||
|
||||
# 函数:输入IP/域名
|
||||
input_target() {
|
||||
while true; do
|
||||
echo -e "${BLUE}请输入要扫描的目标IP地址或域名:${NC}"
|
||||
read -p "目标地址: " TARGET
|
||||
|
||||
if [ -z "$TARGET" ]; then
|
||||
echo -e "${RED}错误:目标地址不能为空!${NC}"
|
||||
continue
|
||||
fi
|
||||
|
||||
# 简单验证格式
|
||||
if [[ "$TARGET" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]] || [[ "$TARGET" =~ ^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
|
||||
break
|
||||
else
|
||||
echo -e "${RED}错误:请输入有效的IP地址或域名!${NC}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# 函数:选择扫描模式
|
||||
select_scan_mode() {
|
||||
echo -e "${BLUE}请选择扫描模式:${NC}"
|
||||
echo "1) 快速扫描 (1-1000端口)"
|
||||
echo "2) 标准扫描 (1-10000端口)"
|
||||
echo "3) 全面扫描 (1-65535端口)"
|
||||
echo "4) 自定义端口范围"
|
||||
echo "5) 常用服务端口扫描"
|
||||
|
||||
while true; do
|
||||
read -p "请选择 [1-5]: " MODE
|
||||
|
||||
case $MODE in
|
||||
1)
|
||||
START_PORT=1
|
||||
END_PORT=1000
|
||||
MODE_NAME="快速扫描"
|
||||
break
|
||||
;;
|
||||
2)
|
||||
START_PORT=1
|
||||
END_PORT=10000
|
||||
MODE_NAME="标准扫描"
|
||||
break
|
||||
;;
|
||||
3)
|
||||
START_PORT=1
|
||||
END_PORT=65535
|
||||
MODE_NAME="全面扫描"
|
||||
break
|
||||
;;
|
||||
4)
|
||||
input_custom_range
|
||||
MODE_NAME="自定义扫描"
|
||||
break
|
||||
;;
|
||||
5)
|
||||
scan_common_services
|
||||
MODE_NAME="常用服务扫描"
|
||||
break
|
||||
;;
|
||||
*)
|
||||
echo -e "${RED}错误:请输入1-5之间的数字!${NC}"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# 函数:输入自定义端口范围
|
||||
input_custom_range() {
|
||||
while true; do
|
||||
echo -e "${BLUE}请输入自定义端口范围:${NC}"
|
||||
read -p "起始端口: " START_PORT
|
||||
read -p "结束端口: " END_PORT
|
||||
|
||||
if [[ ! "$START_PORT" =~ ^[0-9]+$ ]] || [[ ! "$END_PORT" =~ ^[0-9]+$ ]]; then
|
||||
echo -e "${RED}错误:端口必须是数字!${NC}"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ "$START_PORT" -lt 1 ] || [ "$END_PORT" -gt 65535 ]; then
|
||||
echo -e "${RED}错误:端口范围必须在 1-65535 之间!${NC}"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ "$START_PORT" -gt "$END_PORT" ]; then
|
||||
echo -e "${RED}错误:起始端口不能大于结束端口!${NC}"
|
||||
continue
|
||||
fi
|
||||
|
||||
break
|
||||
done
|
||||
}
|
||||
|
||||
# 函数:常用服务端口扫描
|
||||
scan_common_services() {
|
||||
# 常见服务端口列表
|
||||
COMMON_PORTS=(21 22 23 25 53 80 110 111 135 139 143 443 445 993 995 1723 3306 3389 5432 5900 6379 27017 25565)
|
||||
|
||||
echo -e "${CYAN}开始扫描常用服务端口...${NC}"
|
||||
echo -e "扫描端口: ${YELLOW}${COMMON_PORTS[*]}${NC}"
|
||||
|
||||
START_TIME=$(date +%s)
|
||||
|
||||
for port in "${COMMON_PORTS[@]}"; do
|
||||
scan_single_port "$port"
|
||||
done
|
||||
|
||||
END_TIME=$(date +%s)
|
||||
return 0
|
||||
}
|
||||
|
||||
# 函数:扫描单个端口
|
||||
scan_single_port() {
|
||||
local port=$1
|
||||
local result=""
|
||||
|
||||
# 使用TCP连接测试
|
||||
if timeout 1 bash -c "echo > /dev/tcp/$TARGET/$port" 2>/dev/null; then
|
||||
result="${GREEN}开放${NC}"
|
||||
OPEN_PORTS+=("$port")
|
||||
|
||||
# 尝试识别服务
|
||||
local service=$(identify_service "$port")
|
||||
result="$result - $service"
|
||||
else
|
||||
result="${RED}关闭${NC}"
|
||||
fi
|
||||
|
||||
SCAN_RESULTS+=("端口 $port: $result")
|
||||
TOTAL_PORTS_SCANNED=$((TOTAL_PORTS_SCANNED + 1))
|
||||
|
||||
# 显示实时进度
|
||||
if [ $TOTAL_PORTS_SCANNED -eq 1 ] || [ $((TOTAL_PORTS_SCANNED % 100)) -eq 0 ] || [ $TOTAL_PORTS_SCANNED -le 50 ]; then
|
||||
echo -e "扫描进度: $TOTAL_PORTS_SCANNED 端口 - 端口 $port: $result"
|
||||
fi
|
||||
}
|
||||
|
||||
# 函数:识别服务
|
||||
identify_service() {
|
||||
local port=$1
|
||||
|
||||
case $port in
|
||||
21) echo "FTP" ;;
|
||||
22) echo "SSH" ;;
|
||||
23) echo "Telnet" ;;
|
||||
25) echo "SMTP" ;;
|
||||
53) echo "DNS" ;;
|
||||
80) echo "HTTP" ;;
|
||||
110) echo "POP3" ;;
|
||||
111) echo "RPC" ;;
|
||||
135) echo "RPC" ;;
|
||||
139) echo "NetBIOS" ;;
|
||||
143) echo "IMAP" ;;
|
||||
443) echo "HTTPS" ;;
|
||||
445) echo "SMB" ;;
|
||||
993) echo "IMAPS" ;;
|
||||
995) echo "POP3S" ;;
|
||||
1723) echo "PPTP" ;;
|
||||
3306) echo "MySQL" ;;
|
||||
3389) echo "RDP" ;;
|
||||
5432) echo "PostgreSQL" ;;
|
||||
5900) echo "VNC" ;;
|
||||
6379) echo "Redis" ;;
|
||||
27017) echo "MongoDB" ;;
|
||||
25565) echo "Minecraft" ;;
|
||||
*) echo "未知服务" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# 函数:端口范围扫描
|
||||
scan_port_range() {
|
||||
local start=$1
|
||||
local end=$2
|
||||
|
||||
echo -e "${CYAN}开始扫描端口范围: $start - $end${NC}"
|
||||
echo -e "目标: ${YELLOW}$TARGET${NC}"
|
||||
echo -e "预计端口数量: $((end - start + 1))"
|
||||
echo ""
|
||||
|
||||
START_TIME=$(date +%s)
|
||||
|
||||
for ((port=start; port<=end; port++)); do
|
||||
scan_single_port "$port"
|
||||
done
|
||||
|
||||
END_TIME=$(date +%s)
|
||||
}
|
||||
|
||||
# 函数:并行扫描(加速)
|
||||
parallel_scan() {
|
||||
local start=$1
|
||||
local end=$2
|
||||
local batch_size=1000
|
||||
local max_parallel=50
|
||||
|
||||
echo -e "${CYAN}开始并行扫描端口范围: $start - $end${NC}"
|
||||
echo -e "目标: ${YELLOW}$TARGET${NC}"
|
||||
echo -e "并行度: $max_parallel"
|
||||
echo ""
|
||||
|
||||
START_TIME=$(date +%s)
|
||||
|
||||
for ((batch_start=start; batch_start<=end; batch_start+=batch_size)); do
|
||||
local batch_end=$((batch_start + batch_size - 1))
|
||||
if [ $batch_end -gt $end ]; then
|
||||
batch_end=$end
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}扫描批次: $batch_start - $batch_end${NC}"
|
||||
|
||||
for ((port=batch_start; port<=batch_end; port++)); do
|
||||
# 控制并行数量
|
||||
(
|
||||
if timeout 1 bash -c "echo > /dev/tcp/$TARGET/$port" 2>/dev/null; then
|
||||
echo -e "${GREEN}发现开放端口: $port${NC} - $(identify_service $port)"
|
||||
OPEN_PORTS+=("$port")
|
||||
fi
|
||||
) &
|
||||
|
||||
# 控制并发数
|
||||
if [[ $(jobs -r -p | wc -l) -ge $max_parallel ]]; then
|
||||
wait -n
|
||||
fi
|
||||
done
|
||||
|
||||
wait
|
||||
TOTAL_PORTS_SCANNED=$((TOTAL_PORTS_SCANNED + batch_size))
|
||||
echo -e "已完成: $TOTAL_PORTS_SCANNED/$((end - start + 1)) 端口"
|
||||
done
|
||||
|
||||
END_TIME=$(date +%s)
|
||||
}
|
||||
|
||||
# 函数:Ping测试
|
||||
ping_test() {
|
||||
echo -e "\n${PURPLE}=== 网络连通性测试 ===${NC}"
|
||||
echo -e "目标: ${YELLOW}$TARGET${NC}"
|
||||
|
||||
if ping -c 3 -W 2 "$TARGET" &> /dev/null; then
|
||||
echo -e "${GREEN}✓ 网络连通正常${NC}"
|
||||
return 0
|
||||
else
|
||||
echo -e "${RED}✗ 网络不通${NC}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 函数:DNS解析测试
|
||||
dns_test() {
|
||||
echo -e "\n${PURPLE}=== DNS 解析测试 ===${NC}"
|
||||
if [[ "$TARGET" =~ ^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
|
||||
echo -e "${CYAN}检测到域名,进行DNS解析...${NC}"
|
||||
if check_command nslookup; then
|
||||
if nslookup "$TARGET" &> /dev/null; then
|
||||
echo -e "${GREEN}✓ DNS 解析成功${NC}"
|
||||
nslookup "$TARGET" | grep -A 5 "Name:"
|
||||
else
|
||||
echo -e "${RED}✗ DNS 解析失败${NC}"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}⚠ DNS 查询工具未安装${NC}"
|
||||
fi
|
||||
else
|
||||
echo -e "${CYAN}检测到IP地址,跳过DNS解析${NC}"
|
||||
fi
|
||||
}
|
||||
|
||||
# 函数:生成扫描报告
|
||||
generate_scan_report() {
|
||||
local duration=$((END_TIME - START_TIME))
|
||||
|
||||
echo -e "\n${PURPLE}=== 扫描报告 ===${NC}"
|
||||
echo -e "扫描时间: $(date)"
|
||||
echo -e "目标地址: ${YELLOW}$TARGET${NC}"
|
||||
echo -e "扫描模式: ${YELLOW}$MODE_NAME${NC}"
|
||||
|
||||
if [ "$MODE_NAME" != "常用服务扫描" ]; then
|
||||
echo -e "端口范围: ${YELLOW}$START_PORT - $END_PORT${NC}"
|
||||
fi
|
||||
|
||||
echo -e "扫描时长: ${YELLOW}${duration} 秒${NC}"
|
||||
echo -e "扫描端口总数: ${YELLOW}$TOTAL_PORTS_SCANNED${NC}"
|
||||
echo -e "开放端口数量: ${YELLOW}${#OPEN_PORTS[@]}${NC}"
|
||||
|
||||
if [ ${#OPEN_PORTS[@]} -gt 0 ]; then
|
||||
echo -e "\n${GREEN}=== 开放的端口 ===${NC}"
|
||||
printf "端口\t状态\t服务\n"
|
||||
printf "====\t====\t====\n"
|
||||
|
||||
# 对端口进行排序
|
||||
IFS=$'\n' sorted_ports=($(sort -n <<<"${OPEN_PORTS[*]}"))
|
||||
unset IFS
|
||||
|
||||
for port in "${sorted_ports[@]}"; do
|
||||
local service=$(identify_service "$port")
|
||||
printf "%-6d\t${GREEN}%-6s${NC}\t%-15s\n" "$port" "开放" "$service"
|
||||
done
|
||||
|
||||
# 显示端口统计
|
||||
echo -e "\n${CYAN}端口统计:${NC}"
|
||||
echo -e "标准服务端口 (1-1024): $(echo "${OPEN_PORTS[@]}" | tr ' ' '\n' | awk '$1 <= 1024' | wc -l)"
|
||||
echo -e "注册端口 (1025-49151): $(echo "${OPEN_PORTS[@]}" | tr ' ' '\n' | awk '$1 > 1024 && $1 <= 49151' | wc -l)"
|
||||
echo -e "动态端口 (49152-65535): $(echo "${OPEN_PORTS[@]}" | tr ' ' '\n' | awk '$1 > 49151' | wc -l)"
|
||||
else
|
||||
echo -e "\n${RED}未发现任何开放端口${NC}"
|
||||
fi
|
||||
|
||||
# 安全建议
|
||||
echo -e "\n${YELLOW}=== 安全建议 ===${NC}"
|
||||
if [ ${#OPEN_PORTS[@]} -eq 0 ]; then
|
||||
echo -e "${GREEN}● 所有扫描端口均关闭,安全性良好${NC}"
|
||||
elif [ ${#OPEN_PORTS[@]} -le 5 ]; then
|
||||
echo -e "${YELLOW}● 开放端口数量较少,建议检查服务配置${NC}"
|
||||
else
|
||||
echo -e "${RED}● 开放端口较多,建议进行安全审计${NC}"
|
||||
fi
|
||||
}
|
||||
|
||||
# 函数:选择扫描速度
|
||||
select_scan_speed() {
|
||||
echo -e "${BLUE}请选择扫描速度:${NC}"
|
||||
echo "1) 慢速扫描 (准确率高)"
|
||||
echo "2) 中速扫描 (平衡模式)"
|
||||
echo "3) 快速扫描 (可能漏扫)"
|
||||
echo "4) 并行扫描 (最快速度)"
|
||||
|
||||
while true; do
|
||||
read -p "请选择 [1-4]: " SPEED
|
||||
|
||||
case $SPEED in
|
||||
1)
|
||||
TIMEOUT=2
|
||||
SPEED_NAME="慢速扫描"
|
||||
break
|
||||
;;
|
||||
2)
|
||||
TIMEOUT=1
|
||||
SPEED_NAME="中速扫描"
|
||||
break
|
||||
;;
|
||||
3)
|
||||
TIMEOUT=0.5
|
||||
SPEED_NAME="快速扫描"
|
||||
break
|
||||
;;
|
||||
4)
|
||||
TIMEOUT=1
|
||||
SPEED_NAME="并行扫描"
|
||||
break
|
||||
;;
|
||||
*)
|
||||
echo -e "${RED}错误:请输入1-4之间的数字!${NC}"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# 主函数
|
||||
main() {
|
||||
# 显示帮助信息
|
||||
show_help
|
||||
|
||||
# 获取用户输入
|
||||
input_target
|
||||
|
||||
# 网络基础测试
|
||||
dns_test
|
||||
if ! ping_test; then
|
||||
echo -e "${YELLOW}网络不通,是否继续扫描?(y/n)${NC}"
|
||||
read -p "选择: " CONTINUE
|
||||
if [[ "$CONTINUE" != "y" && "$CONTINUE" != "Y" ]]; then
|
||||
echo -e "${RED}扫描终止${NC}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# 选择扫描模式和速度
|
||||
select_scan_mode
|
||||
select_scan_speed
|
||||
|
||||
echo -e "\n${GREEN}开始端口扫描...${NC}"
|
||||
echo -e "目标: ${YELLOW}$TARGET${NC}"
|
||||
echo -e "模式: ${YELLOW}$MODE_NAME${NC}"
|
||||
echo -e "速度: ${YELLOW}$SPEED_NAME${NC}"
|
||||
|
||||
# 执行扫描
|
||||
case $MODE in
|
||||
5)
|
||||
# 常用服务扫描已在 select_scan_mode 中处理
|
||||
;;
|
||||
*)
|
||||
if [ "$SPEED_NAME" = "并行扫描" ]; then
|
||||
parallel_scan "$START_PORT" "$END_PORT"
|
||||
else
|
||||
scan_port_range "$START_PORT" "$END_PORT"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# 生成报告
|
||||
generate_scan_report
|
||||
|
||||
echo -e "\n${GREEN}端口扫描完成!${NC}"
|
||||
}
|
||||
|
||||
# 检查系统要求
|
||||
check_requirements() {
|
||||
local missing=()
|
||||
|
||||
for cmd in ping timeout; do
|
||||
if ! command -v "$cmd" &> /dev/null; then
|
||||
missing+=("$cmd")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#missing[@]} -gt 0 ]; then
|
||||
echo -e "${RED}错误: 缺少必要的命令: ${missing[*]}${NC}"
|
||||
echo -e "${YELLOW}请安装缺少的命令后重新运行脚本${NC}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 脚本入口
|
||||
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
|
||||
show_help
|
||||
exit 0
|
||||
if [ "$FOUND_KEYS" == "1" ]; then
|
||||
echo "✅ 已成功提取密钥和数据,稍后会自动归位。"
|
||||
else
|
||||
echo "⚠️ 未扫描到现有密钥,安装后将生成新的。"
|
||||
fi
|
||||
|
||||
# 检查系统要求
|
||||
check_requirements
|
||||
# --- 2. 彻底卸载与清理 ---
|
||||
echo ">>> [2/7] 正在清理旧环境..."
|
||||
systemctl stop rustdesk-hbbs rustdesk-hbbr 2>/dev/null
|
||||
systemctl disable rustdesk-hbbs rustdesk-hbbr 2>/dev/null
|
||||
dpkg -P rustdesk-server-hbbs rustdesk-server-hbbr 2>/dev/null
|
||||
rm -rf "$DATA_DIR" # 已经备份过了,这里彻底清空保证环境纯净
|
||||
|
||||
# 运行主程序
|
||||
main
|
||||
# --- 3. 环境准备与 IP 获取 ---
|
||||
echo ">>> [3/7] 正在准备基础环境..."
|
||||
apt-get update -q
|
||||
apt-get install -y curl wget lsof ufw dnsutils
|
||||
|
||||
echo " 正在获取公网 IP..."
|
||||
HOST_IP=$(curl -s4 --connect-timeout 5 ifconfig.me)
|
||||
[ -z "$HOST_IP" ] && HOST_IP=$(curl -s4 --connect-timeout 5 ip.sb)
|
||||
|
||||
if [ -z "$HOST_IP" ]; then
|
||||
echo "❌ 错误:无法获取公网 IP,请检查网络。"
|
||||
exit 1
|
||||
fi
|
||||
echo " 公网 IP: $HOST_IP"
|
||||
|
||||
# --- 4. 下载与安装 ---
|
||||
echo ">>> [4/7] 正在下载并安装..."
|
||||
URL_HBBS="https://cloudreve.vps3344521.xyz/f/W9tx/rustdesk-server-hbbs_${VERSION}_amd64.deb"
|
||||
URL_HBBR="https://cloudreve.vps3344521.xyz/f/j3fJ/rustdesk-server-hbbr_${VERSION}_amd64.deb"
|
||||
|
||||
# 下载 (带重试逻辑)
|
||||
wget -O hbbs.deb "$URL_HBBS" || wget -O hbbs.deb "https://github.com/rustdesk/rustdesk-server/releases/download/${VERSION}/rustdesk-server-hbbs_${VERSION}_amd64.deb"
|
||||
wget -O hbbr.deb "$URL_HBBR" || wget -O hbbr.deb "https://github.com/rustdesk/rustdesk-server/releases/download/${VERSION}/rustdesk-server-hbbr_${VERSION}_amd64.deb"
|
||||
|
||||
dpkg -i hbbs.deb hbbr.deb
|
||||
apt-get install -f -y
|
||||
rm -f hbbs.deb hbbr.deb
|
||||
|
||||
# --- 5. 密钥归位与权限修复 (核心步骤) ---
|
||||
echo ">>> [5/7] 正在将密钥转移至官方目录..."
|
||||
mkdir -p "$DATA_DIR"
|
||||
|
||||
if [ "$FOUND_KEYS" == "1" ]; then
|
||||
cp -f "$BACKUP_DIR/"* "$DATA_DIR/"
|
||||
echo "✅ 密钥已成功迁移回 $DATA_DIR"
|
||||
# 清理刚才手动在 /root 生成的垃圾文件,保持系统整洁
|
||||
rm -f /root/id_ed25519 /root/id_ed25519.pub /root/db_v2.sqlite3
|
||||
else
|
||||
echo " 无旧密钥,系统将自动生成。"
|
||||
fi
|
||||
|
||||
# 统一修复权限 (非常重要,否则服务起不来)
|
||||
chown -R root:root "$DATA_DIR"
|
||||
chmod 755 "$DATA_DIR"
|
||||
|
||||
# --- 6. 配置服务 (锁定官方路径) ---
|
||||
echo ">>> [6/7] 正在配置系统服务..."
|
||||
cat > /etc/systemd/system/rustdesk-hbbs.service <<EOF
|
||||
[Unit]
|
||||
Description=RustDesk ID Server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
LimitNOFILE=1000000
|
||||
ExecStart=/usr/bin/hbbs -r ${HOST_IP}:21117 -k _
|
||||
WorkingDirectory=${DATA_DIR}
|
||||
Restart=always
|
||||
User=root
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
cat > /etc/systemd/system/rustdesk-hbbr.service <<EOF
|
||||
[Unit]
|
||||
Description=RustDesk Relay Server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
LimitNOFILE=1000000
|
||||
ExecStart=/usr/bin/hbbr -k _
|
||||
WorkingDirectory=${DATA_DIR}
|
||||
Restart=always
|
||||
User=root
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# 放行端口
|
||||
if command -v ufw > /dev/null; then
|
||||
ufw allow 21115:21119/tcp
|
||||
ufw allow 21116/udp
|
||||
fi
|
||||
|
||||
# --- 7. 启动与验证 ---
|
||||
echo ">>> [7/7] 正在启动服务..."
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now rustdesk-hbbs rustdesk-hbbr
|
||||
|
||||
echo "------------------------------------------------"
|
||||
echo "✅ 修复完成!密钥已锁定在官方目录: $DATA_DIR"
|
||||
echo "⏳ 正在读取密钥..."
|
||||
|
||||
PUB_KEY="${DATA_DIR}/id_ed25519.pub"
|
||||
# 循环等待确保文件生成/存在
|
||||
for i in {1..10}; do
|
||||
if [ -f "$PUB_KEY" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
if [ -f "$PUB_KEY" ]; then
|
||||
echo "------------------------------------------------"
|
||||
echo "🎉 你的 Key (公钥) 为:"
|
||||
echo ""
|
||||
echo -e "\033[32m$(cat "$PUB_KEY")\033[0m"
|
||||
echo ""
|
||||
echo "------------------------------------------------"
|
||||
else
|
||||
echo "❌ 警告:服务似乎启动失败,未检测到 Key 文件。"
|
||||
echo "请运行 journalctl -u rustdesk-hbbs -n 20 查看错误日志。"
|
||||
fi
|
||||
67
121
Normal file
67
121
Normal file
@@ -0,0 +1,67 @@
|
||||
cat << 'EOF' > docker_install.sh
|
||||
#!/bin/bash
|
||||
|
||||
# 颜色定义
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m'
|
||||
|
||||
echo -e "${GREEN}===== 开始针对 ARM64 设备安装 Docker =====${NC}"
|
||||
|
||||
# 1. 彻底清理环境
|
||||
echo "[1/4] 清理旧的配置与冲突源..."
|
||||
rm -f /etc/apt/sources.list.d/docker.list*
|
||||
apt-get remove -y docker docker-engine docker.io containerd runc >/dev/null 2>&1
|
||||
|
||||
# 2. 下载适配 aarch64 的官方二进制包
|
||||
echo "[2/4] 下载 Docker 二进制包 (aarch64)..."
|
||||
cd /tmp
|
||||
# 使用静态编译版,不依赖系统版本,兼容性最强
|
||||
curl -L -o docker-static.tgz https://download.docker.com/linux/static/stable/aarch64/docker-26.1.4.tgz
|
||||
|
||||
# 3. 解压并部署
|
||||
echo "[3/4] 解压并安装二进制文件..."
|
||||
tar xzvf docker-static.tgz >/dev/null
|
||||
cp docker/* /usr/bin/
|
||||
rm -rf docker docker-static.tgz
|
||||
|
||||
# 4. 配置并启动服务
|
||||
echo "[4/4] 配置系统服务..."
|
||||
# 创建最小化配置
|
||||
mkdir -p /etc/docker
|
||||
cat <<DOCKER_CONF > /etc/docker/daemon.json
|
||||
{
|
||||
"registry-mirrors": ["https://docker.m.daocloud.io"]
|
||||
}
|
||||
DOCKER_CONF
|
||||
|
||||
# 编写 systemd 服务文件
|
||||
cat <<SERVICE_CONF > /etc/systemd/system/docker.service
|
||||
[Unit]
|
||||
Description=Docker Application Container Engine
|
||||
After=network-online.target
|
||||
[Service]
|
||||
Type=notify
|
||||
ExecStart=/usr/bin/dockerd
|
||||
Restart=on-failure
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
SERVICE_CONF
|
||||
|
||||
# 启动服务
|
||||
systemctl daemon-reload
|
||||
systemctl enable docker
|
||||
systemctl restart docker
|
||||
|
||||
# 结果验证
|
||||
if docker --version >/dev/null 2>&1; then
|
||||
echo -e "${GREEN}Docker 安装成功!${NC}"
|
||||
docker --version
|
||||
else
|
||||
echo -e "${RED}安装失败,请检查网络或日志。${NC}"
|
||||
fi
|
||||
EOF
|
||||
|
||||
# 运行脚本
|
||||
chmod +x docker_install.sh
|
||||
./docker_install.sh
|
||||
443
Docker容器管理面板
443
Docker容器管理面板
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 简单实用的 Docker 容器管理脚本
|
||||
# 简单实用的 Docker 容器管理脚本 (优化版)
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
@@ -8,53 +8,83 @@ GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
PURPLE='\033[0;35m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m'
|
||||
|
||||
# 检查 Docker
|
||||
# 检查 Docker 及权限
|
||||
check_docker() {
|
||||
if ! command -v docker &> /dev/null; then
|
||||
echo -e "${RED}Docker 未安装${NC}"
|
||||
echo -e "${RED}错误: 未检测到 Docker,请先安装。${NC}"
|
||||
exit 1
|
||||
fi
|
||||
# 检查是否有权限执行 docker 命令
|
||||
if ! docker ps &> /dev/null; then
|
||||
echo -e "${RED}错误: 当前用户无权运行 Docker 命令。${NC}"
|
||||
echo -e "${YELLOW}请尝试使用 sudo 运行此脚本,或将用户加入 docker 用户组。${NC}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 格式化输出表头
|
||||
print_table_header() {
|
||||
printf "${BLUE}%-5s | %-25s | %-12s | %-20s${NC}\n" "编号" "容器名称" "状态" "镜像"
|
||||
echo "------|---------------------------|--------------|----------------------"
|
||||
}
|
||||
|
||||
# 格式化输出行
|
||||
print_table_row() {
|
||||
printf "%-5s | %-25s | %-12b | %-20s\n" "$1" "$2" "$3" "$4"
|
||||
}
|
||||
|
||||
# 显示容器列表
|
||||
show_containers() {
|
||||
echo -e "\n${BLUE}=== 容器列表 ===${NC}"
|
||||
echo "编号 | 容器名称 | 状态 | 镜像"
|
||||
echo "----|----------|------|------"
|
||||
print_table_header
|
||||
|
||||
local count=0
|
||||
docker ps -a --format "table {{.Names}}\t{{.Status}}\t{{.Image}}" | tail -n +2 | while read line; do
|
||||
# 获取数据并暂存,避免管道导致的子shell变量丢失问题
|
||||
mapfile -t lines < <(docker ps -a --format "table {{.Names}}\t{{.Status}}\t{{.Image}}" | tail -n +2)
|
||||
|
||||
for line in "${lines[@]}"; do
|
||||
if [ -n "$line" ]; then
|
||||
count=$((count + 1))
|
||||
name=$(echo "$line" | awk '{print $1}')
|
||||
status=$(echo "$line" | awk '{print $2}')
|
||||
status_raw=$(echo "$line" | awk '{print $2}')
|
||||
image=$(echo "$line" | awk '{for(i=3;i<=NF;i++) printf $i" "; print ""}' | sed 's/ $//')
|
||||
|
||||
# 状态显示
|
||||
if [[ "$status" == "Up"* ]]; then
|
||||
# 截断过长的名称以保持表格整洁
|
||||
display_name=$name
|
||||
if [ ${#display_name} -gt 23 ]; then display_name="${display_name:0:20}..."; fi
|
||||
|
||||
# 截断过长的镜像名
|
||||
display_image=$image
|
||||
if [ ${#display_image} -gt 18 ]; then display_image="${display_image:0:15}..."; fi
|
||||
|
||||
# 状态美化
|
||||
if [[ "$status_raw" == "Up"* ]]; then
|
||||
status_display="${GREEN}运行中${NC}"
|
||||
elif [[ "$status" == "Exited"* ]]; then
|
||||
elif [[ "$status_raw" == "Exited"* ]]; then
|
||||
status_display="${RED}已停止${NC}"
|
||||
else
|
||||
status_display="${YELLOW}$status${NC}"
|
||||
status_display="${YELLOW}$status_raw${NC}"
|
||||
fi
|
||||
|
||||
echo -e "$count | $name | $status_display | $image"
|
||||
print_table_row "$count" "$display_name" "$status_display" "$display_image"
|
||||
fi
|
||||
done
|
||||
echo
|
||||
}
|
||||
|
||||
# 显示镜像列表
|
||||
# 显示镜像列表 (优化对齐)
|
||||
show_images() {
|
||||
echo -e "\n${PURPLE}=== 镜像列表 ===${NC}"
|
||||
echo "编号 | 镜像名称:标签 | 镜像ID | 大小 | 创建时间"
|
||||
echo "----|---------------|--------|------|----------"
|
||||
printf "${PURPLE}%-5s | %-30s | %-12s | %-8s | %-15s${NC}\n" "编号" "镜像名称:标签" "镜像ID" "大小" "创建时间"
|
||||
echo "------|--------------------------------|--------------|----------|----------------"
|
||||
|
||||
local count=0
|
||||
docker images --format "table {{.Repository}}:{{.Tag}}\t{{.ID}}\t{{.Size}}\t{{.CreatedSince}}" | tail -n +2 | while read line; do
|
||||
mapfile -t lines < <(docker images --format "table {{.Repository}}:{{.Tag}}\t{{.ID}}\t{{.Size}}\t{{.CreatedSince}}" | tail -n +2)
|
||||
|
||||
for line in "${lines[@]}"; do
|
||||
if [ -n "$line" ]; then
|
||||
count=$((count + 1))
|
||||
repo_tag=$(echo "$line" | awk '{print $1}')
|
||||
@@ -62,241 +92,160 @@ show_images() {
|
||||
size=$(echo "$line" | awk '{print $3}')
|
||||
created=$(echo "$line" | awk '{for(i=4;i<=NF;i++) printf $i" "; print ""}' | sed 's/ $//')
|
||||
|
||||
# 截断过长的镜像名称
|
||||
if [ ${#repo_tag} -gt 25 ]; then
|
||||
repo_tag="${repo_tag:0:22}..."
|
||||
fi
|
||||
# 截断处理
|
||||
if [ ${#repo_tag} -gt 28 ]; then repo_tag="${repo_tag:0:25}..."; fi
|
||||
|
||||
# 截断镜像ID
|
||||
image_id_short="${image_id:0:12}"
|
||||
|
||||
echo -e "$count | $repo_tag | $image_id_short | $size | $created"
|
||||
printf "%-5s | %-30s | %-12s | %-8s | %-15s\n" "$count" "$repo_tag" "$image_id" "$size" "$created"
|
||||
fi
|
||||
done
|
||||
echo
|
||||
}
|
||||
|
||||
# 通过编号获取容器名称
|
||||
get_container_name() {
|
||||
# 通用获取名称函数 (复用逻辑)
|
||||
get_name_by_index() {
|
||||
local number=$1
|
||||
local count=0
|
||||
docker ps -a --format "table {{.Names}}" | tail -n +2 | while read name; do
|
||||
if [ -n "$name" ]; then
|
||||
count=$((count + 1))
|
||||
if [ $count -eq $number ]; then
|
||||
echo "$name"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
local type=$2 # "container" or "image"
|
||||
local cmd=""
|
||||
|
||||
if [ "$type" == "container" ]; then
|
||||
cmd="docker ps -a --format '{{.Names}}'"
|
||||
else
|
||||
cmd="docker images --format '{{.ID}}'"
|
||||
fi
|
||||
|
||||
# 动态获取第N行
|
||||
eval "$cmd" | sed -n "${number}p"
|
||||
}
|
||||
|
||||
# 通过编号获取镜像ID
|
||||
get_image_id() {
|
||||
local number=$1
|
||||
local count=0
|
||||
docker images --format "table {{.ID}}" | tail -n +2 | while read image_id; do
|
||||
if [ -n "$image_id" ]; then
|
||||
count=$((count + 1))
|
||||
if [ $count -eq $number ]; then
|
||||
echo "$image_id"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
# 进入容器终端 (新增功能)
|
||||
enter_container() {
|
||||
local container_name=$1
|
||||
echo -e "${YELLOW}尝试进入容器: $container_name${NC}"
|
||||
echo -e "提示: 输入 ${RED}exit${NC} 可退出容器终端"
|
||||
echo
|
||||
|
||||
# 优先尝试 bash,失败则尝试 sh
|
||||
if docker exec -it "$container_name" /bin/bash 2>/dev/null; then
|
||||
return
|
||||
elif docker exec -it "$container_name" /bin/sh 2>/dev/null; then
|
||||
return
|
||||
else
|
||||
echo -e "${RED}无法进入容器终端 (可能容器未包含 bash 或 sh)${NC}"
|
||||
read -p "按回车键继续..."
|
||||
fi
|
||||
}
|
||||
|
||||
# 批量删除容器
|
||||
batch_delete_containers() {
|
||||
local numbers="$1"
|
||||
local confirm="$2"
|
||||
|
||||
# 处理输入,支持空格和逗号分隔
|
||||
numbers=$(echo "$numbers" | sed 's/,/ /g')
|
||||
|
||||
local success_count=0
|
||||
local fail_count=0
|
||||
|
||||
for number in $numbers; do
|
||||
if [[ "$number" =~ ^[0-9]+$ ]]; then
|
||||
container_name=$(get_container_name $number)
|
||||
container_name=$(get_name_by_index $number "container")
|
||||
if [ -n "$container_name" ]; then
|
||||
if [ "$confirm" != "y" ]; then
|
||||
echo -e "${YELLOW}删除容器: $container_name${NC}"
|
||||
read -p "确认删除?(Y/n): " confirm_delete
|
||||
confirm_delete=${confirm_delete:-Y} # 默认Y
|
||||
if [[ "$confirm_delete" != "y" && "$confirm_delete" != "Y" ]]; then
|
||||
echo -e "${GREEN}跳过: $container_name${NC}"
|
||||
continue
|
||||
fi
|
||||
read -p "确认删除容器 $container_name? (y/N): " c
|
||||
[[ "$c" != "y" && "$c" != "Y" ]] && continue
|
||||
fi
|
||||
|
||||
if docker rm -f "$container_name" &> /dev/null; then
|
||||
echo -e "${GREEN}✓ 删除成功: $container_name${NC}"
|
||||
success_count=$((success_count + 1))
|
||||
((success_count++))
|
||||
else
|
||||
echo -e "${RED}✗ 删除失败: $container_name${NC}"
|
||||
fail_count=$((fail_count + 1))
|
||||
fi
|
||||
else
|
||||
echo -e "${RED}✗ 容器编号不存在: $number${NC}"
|
||||
fail_count=$((fail_count + 1))
|
||||
echo -e "${RED}✗ 编号 $number 不存在${NC}"
|
||||
fi
|
||||
else
|
||||
echo -e "${RED}✗ 无效编号: $number${NC}"
|
||||
fail_count=$((fail_count + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
if [ $success_count -gt 0 ]; then
|
||||
echo -e "${GREEN}成功删除 $success_count 个容器${NC}"
|
||||
fi
|
||||
if [ $fail_count -gt 0 ]; then
|
||||
echo -e "${RED}删除失败 $fail_count 个${NC}"
|
||||
fi
|
||||
[ $success_count -gt 0 ] && echo -e "${GREEN}共删除 $success_count 个容器${NC}"
|
||||
}
|
||||
|
||||
# 批量删除镜像
|
||||
batch_delete_images() {
|
||||
local numbers="$1"
|
||||
local confirm="$2"
|
||||
|
||||
# 处理输入,支持空格和逗号分隔
|
||||
numbers=$(echo "$numbers" | sed 's/,/ /g')
|
||||
|
||||
local success_count=0
|
||||
local fail_count=0
|
||||
|
||||
for number in $numbers; do
|
||||
if [[ "$number" =~ ^[0-9]+$ ]]; then
|
||||
image_id=$(get_image_id $number)
|
||||
image_id=$(get_name_by_index $number "image")
|
||||
if [ -n "$image_id" ]; then
|
||||
# 获取镜像名称用于显示
|
||||
image_name=$(docker images --format "table {{.Repository}}:{{.Tag}}\t{{.ID}}" | grep "$image_id" | awk '{print $1}')
|
||||
# 获取友好名称用于显示
|
||||
image_name=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep -v "REPOSITORY" | grep "$image_id" | head -n 1)
|
||||
[ -z "$image_name" ] && image_name=$image_id
|
||||
|
||||
if [ "$confirm" != "y" ]; then
|
||||
echo -e "${YELLOW}删除镜像: $image_name${NC}"
|
||||
read -p "确认删除?(Y/n): " confirm_delete
|
||||
confirm_delete=${confirm_delete:-Y} # 默认Y
|
||||
if [[ "$confirm_delete" != "y" && "$confirm_delete" != "Y" ]]; then
|
||||
echo -e "${GREEN}跳过: $image_name${NC}"
|
||||
continue
|
||||
fi
|
||||
read -p "确认删除镜像 $image_name? (y/N): " c
|
||||
[[ "$c" != "y" && "$c" != "Y" ]] && continue
|
||||
fi
|
||||
|
||||
if docker rmi "$image_id" &> /dev/null; then
|
||||
echo -e "${GREEN}✓ 删除成功: $image_name${NC}"
|
||||
success_count=$((success_count + 1))
|
||||
((success_count++))
|
||||
else
|
||||
echo -e "${RED}✗ 删除失败: $image_name (可能有容器在使用此镜像)${NC}"
|
||||
fail_count=$((fail_count + 1))
|
||||
echo -e "${RED}✗ 删除失败 (可能被容器占用): $image_name${NC}"
|
||||
fi
|
||||
else
|
||||
echo -e "${RED}✗ 镜像编号不存在: $number${NC}"
|
||||
fail_count=$((fail_count + 1))
|
||||
fi
|
||||
else
|
||||
echo -e "${RED}✗ 无效编号: $number${NC}"
|
||||
fail_count=$((fail_count + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
if [ $success_count -gt 0 ]; then
|
||||
echo -e "${GREEN}成功删除 $success_count 个镜像${NC}"
|
||||
fi
|
||||
if [ $fail_count -gt 0 ]; then
|
||||
echo -e "${RED}删除失败 $fail_count 个${NC}"
|
||||
fi
|
||||
}
|
||||
|
||||
# 清理悬空镜像
|
||||
clean_dangling_images() {
|
||||
echo -e "${YELLOW}清理悬空镜像...${NC}"
|
||||
local dangling_count=$(docker images -f "dangling=true" -q | wc -l)
|
||||
if [ $dangling_count -gt 0 ]; then
|
||||
read -p "确认删除 $dangling_count 个悬空镜像?(Y/n): " confirm_dangling
|
||||
confirm_dangling=${confirm_dangling:-Y}
|
||||
if [[ "$confirm_dangling" == "y" || "$confirm_dangling" == "Y" ]]; then
|
||||
local count=$(docker images -f "dangling=true" -q | wc -l)
|
||||
if [ "$count" -gt 0 ]; then
|
||||
read -p "发现 $count 个悬空镜像,是否清理?(y/N): " confirm
|
||||
if [[ "$confirm" == "y" || "$confirm" == "Y" ]]; then
|
||||
docker image prune -f
|
||||
echo -e "${GREEN}已清理 $dangling_count 个悬空镜像${NC}"
|
||||
else
|
||||
echo -e "${GREEN}取消清理${NC}"
|
||||
echo -e "${GREEN}清理完成${NC}"
|
||||
fi
|
||||
else
|
||||
echo -e "${GREEN}没有悬空镜像${NC}"
|
||||
echo -e "${GREEN}系统很干净,没有悬空镜像。${NC}"
|
||||
fi
|
||||
read -p "按回车键继续..."
|
||||
}
|
||||
|
||||
# 镜像管理菜单
|
||||
image_management() {
|
||||
while true; do
|
||||
clear
|
||||
echo -e "${PURPLE}"
|
||||
echo "========================================"
|
||||
echo " Docker 镜像管理"
|
||||
echo "========================================"
|
||||
echo -e "${NC}"
|
||||
|
||||
echo -e "${PURPLE}========================================${NC}"
|
||||
echo -e "${PURPLE} Docker 镜像管理${NC}"
|
||||
echo -e "${PURPLE}========================================${NC}"
|
||||
show_images
|
||||
|
||||
echo -e "${PURPLE}镜像操作选项:${NC}"
|
||||
echo "1. 删除镜像 (支持批量: 1 2 3 或 1,2,3)"
|
||||
echo "2. 批量删除所有镜像"
|
||||
echo "3. 清理悬空镜像"
|
||||
echo -e "${PURPLE}操作选项:${NC}"
|
||||
echo "1. 删除镜像 (例如: 1 或 1,2,3)"
|
||||
echo "2. 清空所有镜像 (慎用)"
|
||||
echo "3. 清理悬空镜像 (<none>)"
|
||||
echo "4. 返回主菜单"
|
||||
echo
|
||||
|
||||
read -p "请选择操作: " choice
|
||||
read -p "请选择: " choice
|
||||
|
||||
case $choice in
|
||||
1)
|
||||
echo
|
||||
echo -e "${YELLOW}删除镜像 (支持批量删除)${NC}"
|
||||
echo "输入单个编号: 1"
|
||||
echo "输入多个编号: 1 2 3 或 1,2,3"
|
||||
echo "输入 all 删除所有镜像"
|
||||
read -p "请输入镜像编号: " input
|
||||
|
||||
if [[ "$input" == "all" ]]; then
|
||||
echo -e "${RED}警告:将删除所有镜像!${NC}"
|
||||
read -p "确认删除所有镜像?(Y/n): " confirm_all
|
||||
confirm_all=${confirm_all:-Y}
|
||||
if [[ "$confirm_all" == "y" || "$confirm_all" == "Y" ]]; then
|
||||
total_count=$(docker images -q | wc -l)
|
||||
docker rmi -f $(docker images -q) &> /dev/null
|
||||
echo -e "${GREEN}已删除所有 $total_count 个镜像${NC}"
|
||||
else
|
||||
echo -e "${GREEN}取消删除${NC}"
|
||||
fi
|
||||
else
|
||||
batch_delete_images "$input" "n"
|
||||
fi
|
||||
batch_delete_images "$input" "n"
|
||||
read -p "按回车键继续..."
|
||||
;;
|
||||
2)
|
||||
echo -e "${RED}警告:将删除所有镜像!${NC}"
|
||||
read -p "确认删除所有镜像?(Y/n): " confirm_all
|
||||
confirm_all=${confirm_all:-Y}
|
||||
if [[ "$confirm_all" == "y" || "$confirm_all" == "Y" ]]; then
|
||||
total_count=$(docker images -q | wc -l)
|
||||
docker rmi -f $(docker images -q) &> /dev/null
|
||||
echo -e "${GREEN}已删除所有 $total_count 个镜像${NC}"
|
||||
else
|
||||
echo -e "${GREEN}取消删除${NC}"
|
||||
read -p "警告:确定删除所有镜像吗?(yes/N): " confirm
|
||||
if [ "$confirm" == "yes" ]; then
|
||||
docker rmi -f $(docker images -q) 2>/dev/null
|
||||
echo -e "${GREEN}已清空所有镜像${NC}"
|
||||
fi
|
||||
read -p "按回车键继续..."
|
||||
;;
|
||||
3)
|
||||
clean_dangling_images
|
||||
;;
|
||||
4)
|
||||
return
|
||||
;;
|
||||
*)
|
||||
echo -e "${RED}无效选择${NC}"
|
||||
;;
|
||||
3) clean_dangling_images ;;
|
||||
4) return ;;
|
||||
*) echo -e "${RED}无效输入${NC}"; sleep 1 ;;
|
||||
esac
|
||||
|
||||
echo
|
||||
read -p "按回车键继续..."
|
||||
done
|
||||
}
|
||||
|
||||
@@ -304,124 +253,74 @@ image_management() {
|
||||
main_menu() {
|
||||
while true; do
|
||||
clear
|
||||
echo -e "${BLUE}"
|
||||
echo "========================================"
|
||||
echo " 简单 Docker 容器管理"
|
||||
echo "========================================"
|
||||
echo -e "${NC}"
|
||||
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE} Docker 容器可视化管理 v2.0${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
show_containers
|
||||
|
||||
echo -e "${BLUE}容器操作选项:${NC}"
|
||||
echo "1. 启动容器"
|
||||
echo "2. 停止容器"
|
||||
echo "3. 重启容器"
|
||||
echo "4. 删除容器 (支持批量: 1 2 3 或 1,2,3)"
|
||||
echo "5. 批量删除所有已停止容器"
|
||||
echo "6. 查看容器日志"
|
||||
echo -e "${PURPLE}镜像操作选项:${NC}"
|
||||
echo "7. 查看和管理镜像"
|
||||
echo -e "${BLUE}容器操作:${NC} ${CYAN}高级功能:${NC}"
|
||||
printf "%-35s %-35s\n" "1. 启动容器" "7. 进入容器终端 (Exec)"
|
||||
printf "%-35s %-35s\n" "2. 停止容器" "8. 实时资源监控 (Stats)"
|
||||
printf "%-35s %-35s\n" "3. 重启容器" "9. 镜像管理菜单"
|
||||
printf "%-35s\n" "4. 查看日志"
|
||||
echo
|
||||
echo -e "${RED}危险操作:${NC}"
|
||||
echo "5. 删除容器 (例如: 1 或 1,2,3)"
|
||||
echo "6. 清理所有已停止容器"
|
||||
echo "0. 退出"
|
||||
echo
|
||||
|
||||
read -p "请选择操作: " choice
|
||||
read -p "请选择操作 [0-9]: " choice
|
||||
|
||||
# 处理需要选择容器的操作
|
||||
if [[ "1 2 3 4 7" =~ "$choice" ]]; then
|
||||
read -p "请输入容器编号: " num
|
||||
if [[ ! "$num" =~ ^[0-9]+$ ]]; then
|
||||
echo -e "${RED}请输入有效数字${NC}"; sleep 1; continue
|
||||
fi
|
||||
|
||||
name=$(get_name_by_index $num "container")
|
||||
if [ -z "$name" ]; then
|
||||
echo -e "${RED}编号不存在${NC}"; sleep 1; continue
|
||||
fi
|
||||
|
||||
case $choice in
|
||||
1) docker start "$name" && echo -e "${GREEN}已启动 $name${NC}" ;;
|
||||
2) docker stop "$name" && echo -e "${GREEN}已停止 $name${NC}" ;;
|
||||
3) docker restart "$name" && echo -e "${GREEN}已重启 $name${NC}" ;;
|
||||
4) docker logs -f --tail 100 "$name" ;;
|
||||
7) enter_container "$name" ;;
|
||||
esac
|
||||
[ "$choice" != "7" ] && [ "$choice" != "4" ] && sleep 1
|
||||
continue
|
||||
fi
|
||||
|
||||
# 处理其他操作
|
||||
case $choice in
|
||||
1|2|3|6)
|
||||
echo
|
||||
read -p "请输入容器编号: " container_number
|
||||
|
||||
if ! [[ "$container_number" =~ ^[0-9]+$ ]]; then
|
||||
echo -e "${RED}无效的编号${NC}"
|
||||
read -p "按回车键继续..."
|
||||
continue
|
||||
fi
|
||||
|
||||
container_name=$(get_container_name $container_number)
|
||||
if [ -z "$container_name" ]; then
|
||||
echo -e "${RED}容器编号不存在${NC}"
|
||||
read -p "按回车键继续..."
|
||||
continue
|
||||
fi
|
||||
|
||||
case $choice in
|
||||
1)
|
||||
echo -e "${YELLOW}启动容器: $container_name${NC}"
|
||||
docker start "$container_name" && echo -e "${GREEN}启动成功${NC}" || echo -e "${RED}启动失败${NC}"
|
||||
;;
|
||||
2)
|
||||
echo -e "${YELLOW}停止容器: $container_name${NC}"
|
||||
docker stop "$container_name" && echo -e "${GREEN}停止成功${NC}" || echo -e "${RED}停止失败${NC}"
|
||||
;;
|
||||
3)
|
||||
echo -e "${YELLOW}重启容器: $container_name${NC}"
|
||||
docker restart "$container_name" && echo -e "${GREEN}重启成功${NC}" || echo -e "${RED}重启失败${NC}"
|
||||
;;
|
||||
6)
|
||||
echo -e "${BLUE}查看容器日志: $container_name${NC}"
|
||||
echo "按 Ctrl+C 退出"
|
||||
docker logs -f "$container_name"
|
||||
continue # 日志查看后直接继续,不等回车
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
4)
|
||||
echo
|
||||
echo -e "${YELLOW}删除容器 (支持批量删除)${NC}"
|
||||
echo "输入单个编号: 1"
|
||||
echo "输入多个编号: 1 2 3 或 1,2,3"
|
||||
echo "输入 all 删除所有容器"
|
||||
read -p "请输入容器编号: " input
|
||||
|
||||
if [[ "$input" == "all" ]]; then
|
||||
echo -e "${RED}警告:将删除所有容器!${NC}"
|
||||
read -p "确认删除所有容器?(Y/n): " confirm_all
|
||||
confirm_all=${confirm_all:-Y}
|
||||
if [[ "$confirm_all" == "y" || "$confirm_all" == "Y" ]]; then
|
||||
total_count=$(docker ps -aq | wc -l)
|
||||
docker rm -f $(docker ps -aq) &> /dev/null
|
||||
echo -e "${GREEN}已删除所有 $total_count 个容器${NC}"
|
||||
else
|
||||
echo -e "${GREEN}取消删除${NC}"
|
||||
fi
|
||||
else
|
||||
batch_delete_containers "$input" "n"
|
||||
fi
|
||||
;;
|
||||
5)
|
||||
echo -e "${YELLOW}批量删除所有已停止的容器...${NC}"
|
||||
stopped_count=$(docker ps -aq -f status=exited | wc -l)
|
||||
if [ $stopped_count -gt 0 ]; then
|
||||
read -p "确认删除 $stopped_count 个已停止容器?(Y/n): " confirm_stopped
|
||||
confirm_stopped=${confirm_stopped:-Y}
|
||||
if [[ "$confirm_stopped" == "y" || "$confirm_stopped" == "Y" ]]; then
|
||||
docker rm $(docker ps -aq -f status=exited) &> /dev/null
|
||||
echo -e "${GREEN}已删除 $stopped_count 个已停止容器${NC}"
|
||||
else
|
||||
echo -e "${GREEN}取消删除${NC}"
|
||||
fi
|
||||
else
|
||||
echo -e "${GREEN}没有已停止的容器${NC}"
|
||||
read -p "请输入要删除的容器编号 (支持批量): " nums
|
||||
batch_delete_containers "$nums" "n"
|
||||
read -p "按回车键继续..."
|
||||
;;
|
||||
6)
|
||||
read -p "确认清理所有已停止的容器?(y/N): " c
|
||||
if [[ "$c" == "y" || "$c" == "Y" ]]; then
|
||||
docker container prune -f
|
||||
echo -e "${GREEN}清理完成${NC}"
|
||||
fi
|
||||
sleep 1
|
||||
;;
|
||||
7)
|
||||
image_management
|
||||
;;
|
||||
0)
|
||||
echo
|
||||
echo -e "${GREEN}再见!${NC}"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo -e "${RED}无效选择${NC}"
|
||||
8)
|
||||
echo -e "${CYAN}正在打开资源监控 (按 Ctrl+C 退出)...${NC}"
|
||||
docker stats
|
||||
;;
|
||||
9) image_management ;;
|
||||
0) echo -e "${GREEN}再见!${NC}"; exit 0 ;;
|
||||
*) echo -e "${RED}无效选择${NC}"; sleep 1 ;;
|
||||
esac
|
||||
|
||||
echo
|
||||
read -p "按回车键继续..."
|
||||
done
|
||||
}
|
||||
|
||||
# 启动脚本
|
||||
# 启动
|
||||
check_docker
|
||||
main_menu
|
||||
73
GoEdge-cdn
Normal file
73
GoEdge-cdn
Normal file
@@ -0,0 +1,73 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 定义变量
|
||||
INSTALL_DIR="/usr/local/goedge"
|
||||
# 你的 Gitea 下载链接
|
||||
DOWNLOAD_URL="https://git.vps3344521.xyz/3344/dock/releases/download/Goedge-cdn/edge-admin-linux-amd64-plus-v1.4.7.zip"
|
||||
SAVE_PATH="/tmp/edge-admin.zip"
|
||||
|
||||
echo "=== 开始检查依赖环境 ==="
|
||||
|
||||
# 1. 检测并安装 unzip (解压用)
|
||||
if ! command -v unzip &> /dev/null; then
|
||||
echo "未检测到 unzip,正在安装..."
|
||||
apt-get update && apt-get install -y unzip
|
||||
fi
|
||||
|
||||
# 2. 检测并安装 axel (多线程下载用)
|
||||
if ! command -v axel &> /dev/null; then
|
||||
echo "未检测到 axel,正在安装..."
|
||||
apt-get update && apt-get install -y axel
|
||||
else
|
||||
echo "检测到 axel 已安装。"
|
||||
fi
|
||||
|
||||
# 3. 准备目录
|
||||
if [ ! -d "$INSTALL_DIR" ]; then
|
||||
mkdir -p "$INSTALL_DIR"
|
||||
echo "创建目录: $INSTALL_DIR"
|
||||
fi
|
||||
|
||||
# 4. 使用 axel 多线程下载
|
||||
echo "=== 开始多线程下载 (10线程) ==="
|
||||
rm -f "$SAVE_PATH"
|
||||
axel -n 10 -a -o "$SAVE_PATH" "$DOWNLOAD_URL"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "下载失败,请检查网络或链接有效性。"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 5. 解压文件
|
||||
echo "=== 正在解压文件 ==="
|
||||
unzip -o "$SAVE_PATH" -d "$INSTALL_DIR"
|
||||
|
||||
# 6. 自动寻找并执行安装
|
||||
# 兼容不同解压路径,自动寻找 edge-admin 二进制文件所在位置
|
||||
REAL_BIN_PATH=$(find $INSTALL_DIR -name "edge-admin" -type f | grep "/bin/" | head -n 1)
|
||||
|
||||
if [ -f "$REAL_BIN_PATH" ]; then
|
||||
REAL_DIR=$(dirname $(dirname "$REAL_BIN_PATH"))
|
||||
cd "$REAL_DIR"
|
||||
|
||||
echo "=== 正在配置系统服务 ==="
|
||||
chmod +x bin/edge-admin
|
||||
./bin/edge-admin install
|
||||
|
||||
echo "=== 正在启动 GoEdge Admin ==="
|
||||
./bin/edge-admin start
|
||||
|
||||
# 获取本机 IP
|
||||
SERVER_IP=$(curl -s https://ifconfig.me || hostname -I | awk '{print $1}')
|
||||
|
||||
echo ""
|
||||
echo "======================================================"
|
||||
echo "🎉 GoEdge Admin 安装并启动成功!"
|
||||
echo "======================================================"
|
||||
echo "👉 访问地址: http://${SERVER_IP}:7788"
|
||||
echo "👉 默认配置: 请按照网页提示进行初始化"
|
||||
echo "👉 数据目录: ${REAL_DIR}"
|
||||
echo "======================================================"
|
||||
else
|
||||
echo "错误:未能找到 edge-admin 程序,请检查压缩包内容。"
|
||||
fi
|
||||
2
SublinkX
2
SublinkX
@@ -10,7 +10,7 @@ set -e
|
||||
# 定义路径和备份地址
|
||||
PROJECT_DIR="/data/sublinkx"
|
||||
COMPOSE_FILE="$PROJECT_DIR/docker-compose.yml"
|
||||
BACKUP_URL="https://pub-b69a7194f4ea42fba6aa990c49bded91.r2.dev/data/sublinkx.zip"
|
||||
BACKUP_URL="https://cloudreve.vps3344521.xyz/f/EQT2/sublinkx.zip"
|
||||
|
||||
# 检查并安装必要工具 (wget, unzip)
|
||||
echo "正在检查系统环境..."
|
||||
|
||||
44
cl穿透
Normal file
44
cl穿透
Normal file
@@ -0,0 +1,44 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 颜色定义
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m'
|
||||
|
||||
echo -e "${GREEN}==== Cloudflare Tunnel Docker 交互安装脚本 ====${NC}"
|
||||
|
||||
# 1. 交互式获取 Token
|
||||
read -p "请输入你的 Cloudflare Tunnel Token: " USER_TOKEN
|
||||
|
||||
# 检查输入是否为空
|
||||
if [ -z "$USER_TOKEN" ]; then
|
||||
echo -e "${RED}[错误] Token 不能为空!请重新运行脚本并输入有效密钥。${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 2. 检查并清理同名容器
|
||||
if [ "$(docker ps -aq -f name=cf-tunnel)" ]; then
|
||||
echo -e "${YELLOW}[提示] 发现已存在的 cf-tunnel 容器,正在更新...${NC}"
|
||||
docker rm -f cf-tunnel >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
# 3. 运行 Docker 容器
|
||||
echo -e "${GREEN}[执行] 正在启动 Cloudflare Tunnel...${NC}"
|
||||
|
||||
docker run -d \
|
||||
--name cf-tunnel \
|
||||
--restart always \
|
||||
cloudflare/cloudflared:latest \
|
||||
tunnel --no-autoupdate run --token "$USER_TOKEN"
|
||||
|
||||
# 4. 验证结果
|
||||
if [ $? -eq 0 ]; then
|
||||
echo -e "------------------------------------------------"
|
||||
echo -e "${GREEN}成功:Cloudflare Tunnel 已在后台启动!${NC}"
|
||||
echo -e "容器名称: cf-tunnel"
|
||||
echo -e "查看日志命令: docker logs -f cf-tunnel"
|
||||
echo -e "------------------------------------------------"
|
||||
else
|
||||
echo -e "${RED}[错误] 容器启动失败,请检查 Docker 是否正常运行。${NC}"
|
||||
fi
|
||||
126
de12系统代理
Normal file
126
de12系统代理
Normal file
@@ -0,0 +1,126 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ==========================================
|
||||
# 全能自愈版·临时全局代理注入助手 (带 Docker 选择)
|
||||
# 适用环境: Debian / Ubuntu 等
|
||||
# ==========================================
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[31m'
|
||||
GREEN='\033[32m'
|
||||
YELLOW='\033[33m'
|
||||
BLUE='\033[34m'
|
||||
PLAIN='\033[0m'
|
||||
|
||||
echo -e "${BLUE}=====================================================${PLAIN}"
|
||||
echo -e "${BLUE} 全能自愈版·全局代理与 Docker 穿透助手 (含还原机制) ${PLAIN}"
|
||||
echo -e "${BLUE}=====================================================${PLAIN}"
|
||||
|
||||
# 默认代理节点配置
|
||||
DEFAULT_IP="45.192.240.121"
|
||||
DEFAULT_PORT="21628"
|
||||
DEFAULT_PROTO="socks5"
|
||||
|
||||
read -p "请输入代理 IP [$DEFAULT_IP]: " PROXY_IP
|
||||
PROXY_IP=${PROXY_IP:-$DEFAULT_IP}
|
||||
read -p "请输入代理端口 [$DEFAULT_PORT]: " PROXY_PORT
|
||||
PROXY_PORT=${PROXY_PORT:-$DEFAULT_PORT}
|
||||
|
||||
PROXY_URL="${DEFAULT_PROTO}://${PROXY_IP}:${PROXY_PORT}"
|
||||
|
||||
echo -e "\n${BLUE}[1/6] 检查并修复系统软件源...${PLAIN}"
|
||||
if ! apt-get update -qq 2>/dev/null; then
|
||||
echo -e "${YELLOW}检测到当前软件源失效,正在自动备份并替换为 Debian 12 官方公网源...${PLAIN}"
|
||||
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak 2>/dev/null
|
||||
sudo bash -c 'cat << SRC > /etc/apt/sources.list
|
||||
deb http://deb.debian.org/debian bookworm main
|
||||
deb http://deb.debian.org/debian bookworm-updates main
|
||||
deb http://security.debian.org/debian-security bookworm-security main
|
||||
SRC'
|
||||
sudo apt-get update -qq
|
||||
echo -e "${GREEN} -> 软件源修复完成!${PLAIN}"
|
||||
else
|
||||
echo -e "${GREEN} -> 软件源状态正常。${PLAIN}"
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}[2/6] 检查并安装必要依赖...${PLAIN}"
|
||||
if ! command -v proxychains4 &> /dev/null || ! command -v curl &> /dev/null; then
|
||||
echo -e "${YELLOW}正在自动安装 proxychains4 和 curl...${PLAIN}"
|
||||
sudo apt-get install -y -qq proxychains4 curl >/dev/null 2>&1
|
||||
echo -e "${GREEN} -> 依赖安装完毕!${PLAIN}"
|
||||
else
|
||||
echo -e "${GREEN} -> 依赖已存在。${PLAIN}"
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}[3/6] 注入底层环境变量与 Sudo 穿透...${PLAIN}"
|
||||
export http_proxy="${PROXY_URL}"
|
||||
export https_proxy="${PROXY_URL}"
|
||||
export all_proxy="${PROXY_URL}"
|
||||
export HTTP_PROXY="${PROXY_URL}"
|
||||
export HTTPS_PROXY="${PROXY_URL}"
|
||||
export ALL_PROXY="${PROXY_URL}"
|
||||
export no_proxy="localhost,127.0.0.1,localaddress,.localdomain.com,.aliyuncs.com"
|
||||
alias sudo='sudo -E'
|
||||
echo -e "${GREEN} -> 终端变量注入成功!${PLAIN}"
|
||||
|
||||
echo -e "${BLUE}[4/6] 部署临时强制代理 (修复 Error 52)...${PLAIN}"
|
||||
TEMP_PC_CONF="/tmp/ultimate_pc.conf"
|
||||
cat << CONF > $TEMP_PC_CONF
|
||||
strict_chain
|
||||
remote_dns_subnet 224
|
||||
tcp_read_time_out 15000
|
||||
tcp_connect_time_out 8000
|
||||
[ProxyList]
|
||||
$DEFAULT_PROTO $PROXY_IP $PROXY_PORT
|
||||
CONF
|
||||
alias pc="proxychains4 -q -f $TEMP_PC_CONF"
|
||||
echo -e "${GREEN} -> pc 强制代理工具就绪!${PLAIN}"
|
||||
|
||||
echo -e "${BLUE}[5/6] 突破 Docker 守护进程隔离 (交互)...${PLAIN}"
|
||||
if command -v docker &> /dev/null; then
|
||||
echo -e "${YELLOW}检测到系统已安装 Docker。${PLAIN}"
|
||||
read -p "是否为 Docker 守护进程添加代理?(解决拉取镜像超时问题) [y/n, 默认: y]: " ADD_DOCKER
|
||||
ADD_DOCKER=${ADD_DOCKER:-y}
|
||||
|
||||
if [[ "$ADD_DOCKER" =~ ^[Yy]$ ]]; then
|
||||
echo -e "${YELLOW}正在配置并重启 Docker...${PLAIN}"
|
||||
sudo mkdir -p /etc/systemd/system/docker.service.d
|
||||
sudo bash -c "cat << DOCKER_CONF > /etc/systemd/system/docker.service.d/http-proxy.conf
|
||||
[Service]
|
||||
Environment=\"HTTP_PROXY=${PROXY_URL}\"
|
||||
Environment=\"HTTPS_PROXY=${PROXY_URL}\"
|
||||
Environment=\"NO_PROXY=localhost,127.0.0.1,.aliyuncs.com\"
|
||||
DOCKER_CONF"
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl restart docker
|
||||
echo -e "${GREEN} -> Docker 代理已挂载并重启完毕!${PLAIN}"
|
||||
else
|
||||
echo -e "${GREEN} -> 已跳过 Docker 代理配置。${PLAIN}"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW} -> 未检测到 Docker,跳过此步骤。${PLAIN}"
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}[6/6] 生成一键清场工具...${PLAIN}"
|
||||
# 将 proxy_clean 声明为函数留在内存里
|
||||
proxy_clean() {
|
||||
echo -e "${YELLOW}正在清除所有代理痕迹...${PLAIN}"
|
||||
unset http_proxy https_proxy all_proxy HTTP_PROXY HTTPS_PROXY ALL_PROXY no_proxy
|
||||
unalias sudo pc 2>/dev/null
|
||||
rm -f /tmp/ultimate_pc.conf
|
||||
if [ -f /etc/systemd/system/docker.service.d/http-proxy.conf ]; then
|
||||
sudo rm -f /etc/systemd/system/docker.service.d/http-proxy.conf
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl restart docker
|
||||
echo -e "${GREEN} -> Docker 代理已卸载并重启服务。${PLAIN}"
|
||||
fi
|
||||
echo -e "${GREEN}清理完毕!系统已彻底恢复直连状态。${PLAIN}"
|
||||
}
|
||||
echo -e "${GREEN} -> 已生成 'proxy_clean' 命令。${PLAIN}"
|
||||
|
||||
echo -e "\n${GREEN}=====================================================${PLAIN}"
|
||||
echo -e "${GREEN} 所有网络魔法已就绪!${PLAIN}"
|
||||
echo -e " 1. 终端环境已全面代理 (curl, wget 畅通无阻)。"
|
||||
echo -e " 2. 遇到不听话的顽固脚本,命令前加 ${YELLOW}pc${PLAIN} (如: pc ./install.sh)。"
|
||||
echo -e " 3. 完事后想恢复原状,只需输入命令: ${RED}proxy_clean${PLAIN}"
|
||||
echo -e "${GREEN}=====================================================${PLAIN}"
|
||||
2
dock安装cf
2
dock安装cf
@@ -10,7 +10,7 @@ cat > /root/docker-install-zip.sh <<'EOF'
|
||||
ZIP_NAME="dockde12.zip"
|
||||
WORKDIR="/root/docker-offline"
|
||||
# 主下载地址
|
||||
URL1="https://freeyx.vps3344.dpdns.org/xui/dockde12.zip"
|
||||
URL1="https://git.77582585.xyz/3344/dock/releases/download/dock%E5%AE%89%E8%A3%85%E5%8C%85/dockde12.zip"
|
||||
# 备用下载地址
|
||||
URL2="https://pub-b69a7194f4ea42fba6aa990c49bded91.r2.dev/xui/dockde12.zip"
|
||||
|
||||
|
||||
38
istc
Normal file
38
istc
Normal file
@@ -0,0 +1,38 @@
|
||||
cat << 'EOF' > /tmp/update_source.sh
|
||||
#!/bin/sh
|
||||
|
||||
echo "正在执行 iStoreOS 国内源替换脚本..."
|
||||
|
||||
# 1. 备份原始配置,防止意外
|
||||
mkdir -p /etc/opkg/backup
|
||||
cp /etc/opkg/*.conf /etc/opkg/backup/
|
||||
echo "已备份原始配置文件到 /etc/opkg/backup/"
|
||||
|
||||
# 2. 全量替换为腾讯云镜像 (解决 distfeeds, customfeeds, compatfeeds 等所有文件的连接问题)
|
||||
# 针对你截图中的 cernet 地址进行精准替换
|
||||
sed -i 's/mirrors.cernet.edu.cn/mirrors.tencent.com/g' /etc/opkg/*.conf
|
||||
echo "源地址已修改为腾讯云镜像。"
|
||||
|
||||
# 3. 强制更新索引
|
||||
echo "正在更新软件包索引,请稍候..."
|
||||
opkg update
|
||||
|
||||
# 4. 尝试在线安装 PassWall 缺失的 3 个核心零件
|
||||
echo "正在安装基础依赖组件..."
|
||||
opkg install chinadns-ng dns2socks tcping microsocks coreutils-base64 coreutils-nohup
|
||||
|
||||
# 5. 检查安装结果
|
||||
echo "-----------------------------------------------"
|
||||
if [ -f "/usr/bin/chinadns-ng" ] || [ -f "/usr/bin/dns2socks" ]; then
|
||||
echo "恭喜!核心零件安装成功。"
|
||||
echo "现在你可以去 iStore 界面离线安装 PassWall 主程序了。"
|
||||
echo "或者运行:opkg install /tmp/*.ipk --force-depends"
|
||||
else
|
||||
echo "部分组件在线安装失败,建议检查路由器联网状态或手动上传零件包。"
|
||||
fi
|
||||
echo "-----------------------------------------------"
|
||||
EOF
|
||||
|
||||
# 赋予执行权限并运行
|
||||
chmod +x /tmp/update_source.sh
|
||||
/tmp/update_source.sh
|
||||
63
ru
63
ru
@@ -23,28 +23,43 @@ if ! command -v docker &> /dev/null; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 3. 设置安装目录
|
||||
# 3. 设置安装目录(恢复为原始默认路径)
|
||||
INSTALL_DIR="/data/rustdesk"
|
||||
echo -e "${YELLOW}默认安装目录: ${INSTALL_DIR}${PLAIN}"
|
||||
echo -e "${YELLOW}当前安装目录: ${INSTALL_DIR}${PLAIN}"
|
||||
|
||||
# 创建目录
|
||||
mkdir -p "${INSTALL_DIR}/data"
|
||||
mkdir -p "${INSTALL_DIR}/api"
|
||||
|
||||
# 4. 获取用户输入 (公网IP/域名)
|
||||
# 4. 获取用户输入
|
||||
read -p "请输入服务器的公网 IP 或解析好的域名 (必填): " HOST_IP
|
||||
if [[ -z "$HOST_IP" ]]; then
|
||||
echo -e "${RED}错误:必须输入 IP 或域名!${PLAIN}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- 交互选择:是否需要账号密码登录 ---
|
||||
echo -e "${YELLOW}是否开启强制登录模式 (MUST_LOGIN)?${PLAIN}"
|
||||
echo -e "1) 需要 (必须注册并登录账号才能连接)"
|
||||
echo -e "2) 不需要 (直接使用 ID 和 Key 即可连接 - 默认)"
|
||||
read -p "请选择 [1/2]: " LOGIN_CHOICE
|
||||
|
||||
if [[ "$LOGIN_CHOICE" == "1" ]]; then
|
||||
MUST_LOGIN_VAL="Y"
|
||||
echo -e "${GREEN}配置已设为:必须登录${PLAIN}"
|
||||
else
|
||||
MUST_LOGIN_VAL="N"
|
||||
echo -e "${GREEN}配置已设为:无需登录(公共模式)${PLAIN}"
|
||||
fi
|
||||
# --------------------------------------
|
||||
|
||||
# 进入目录
|
||||
cd "$INSTALL_DIR" || exit
|
||||
|
||||
# 5. 生成 docker-compose.yml
|
||||
echo -e "${YELLOW}正在生成配置文件...${PLAIN}"
|
||||
# 5. 生成配置文件 (以容器名命名)
|
||||
echo -e "${YELLOW}正在生成配置文件 rustdesk.yml...${PLAIN}"
|
||||
|
||||
cat > docker-compose.yml <<EOF
|
||||
cat > rustdesk.yml <<EOF
|
||||
version: '3'
|
||||
|
||||
networks:
|
||||
@@ -64,22 +79,15 @@ services:
|
||||
- 21119:21119
|
||||
image: lejianwen/rustdesk-server-s6:latest
|
||||
environment:
|
||||
# 公网IP或域名
|
||||
- RELAY=${HOST_IP}
|
||||
# 强制必须登录才能连接
|
||||
- MUST_LOGIN=Y
|
||||
# 单个连接限速 2MB/s = 16Mb/s
|
||||
# 动态配置登录限制
|
||||
- MUST_LOGIN=${MUST_LOGIN_VAL}
|
||||
- SINGLE_BANDWIDTH=16
|
||||
# 总带宽限制
|
||||
- TOTAL_BANDWIDTH=100
|
||||
# 只允许加密连接
|
||||
- ENCRYPTED_ONLY=1
|
||||
# 时区设置
|
||||
- TZ=Asia/Shanghai
|
||||
volumes:
|
||||
# 密钥和数据持久化目录
|
||||
- ${INSTALL_DIR}/data:/data
|
||||
# API数据库目录
|
||||
- ${INSTALL_DIR}/api:/app/data
|
||||
networks:
|
||||
- rustdesk-net
|
||||
@@ -87,35 +95,34 @@ services:
|
||||
EOF
|
||||
|
||||
# 6. 启动容器
|
||||
echo -e "${YELLOW}正在拉取镜像并启动容器...${PLAIN}"
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
echo -e "${YELLOW}正在拉取镜像并启动服务...${PLAIN}"
|
||||
docker compose -f rustdesk.yml pull
|
||||
docker compose -f rustdesk.yml up -d
|
||||
|
||||
# 7. 检查状态并获取 Key
|
||||
if [ $? -eq 0 ]; then
|
||||
echo -e "${GREEN}服务启动成功!${PLAIN}"
|
||||
echo -e "${YELLOW}正在等待密钥生成 (约5秒)...${PLAIN}"
|
||||
echo -e "${YELLOW}正在等待密钥生成...${PLAIN}"
|
||||
sleep 5
|
||||
|
||||
# 尝试读取公钥
|
||||
PUB_KEY_FILE="${INSTALL_DIR}/data/id_ed25519.pub"
|
||||
|
||||
if [ -f "$PUB_KEY_FILE" ]; then
|
||||
PUB_KEY=$(cat "$PUB_KEY_FILE")
|
||||
echo -e "${GREEN}=============================================${PLAIN}"
|
||||
echo -e " RustDesk Server 部署完成信息"
|
||||
echo -e " RustDesk Server 部署完成"
|
||||
echo -e "${GREEN}=============================================${PLAIN}"
|
||||
echo -e "ID 服务器 (ID Server): ${GREEN}${HOST_IP}${PLAIN}"
|
||||
echo -e "中继服务器 (Relay Server): ${GREEN}${HOST_IP}${PLAIN}"
|
||||
echo -e "API 服务器 (API Server): ${GREEN}http://${HOST_IP}:21114${PLAIN}"
|
||||
echo -e "ID/中继服务器: ${GREEN}${HOST_IP}${PLAIN}"
|
||||
echo -e "API 服务器: ${GREEN}http://${HOST_IP}:21114${PLAIN}"
|
||||
echo -e "Key (公钥):"
|
||||
echo -e "${YELLOW}${PUB_KEY}${PLAIN}"
|
||||
echo -e "${GREEN}=============================================${PLAIN}"
|
||||
echo -e "请将以上信息填入 RustDesk 客户端的网络设置中。"
|
||||
if [[ "$MUST_LOGIN_VAL" == "Y" ]]; then
|
||||
echo -e "注意:当前为【登录模式】,请先在 API 页面注册账号。"
|
||||
fi
|
||||
else
|
||||
echo -e "${RED}无法自动读取公钥,请手动检查目录:${INSTALL_DIR}/data${PLAIN}"
|
||||
echo -e "或者查看日志:docker logs rustdesk-server"
|
||||
echo -e "${RED}未找到公钥,请手动查看目录 ${INSTALL_DIR}/data${PLAIN}"
|
||||
fi
|
||||
else
|
||||
echo -e "${RED}服务启动失败,请检查 Docker 日志。${PLAIN}"
|
||||
echo -e "${RED}服务启动失败!${PLAIN}"
|
||||
fi
|
||||
83
ru2
Normal file
83
ru2
Normal file
@@ -0,0 +1,83 @@
|
||||
cat > install_deb.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
# 颜色定义
|
||||
GREEN='\033[32m'
|
||||
RED='\033[31m'
|
||||
YELLOW='\033[33m'
|
||||
PLAIN='\033[0m'
|
||||
|
||||
# 1. 检查 Root 权限
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo -e "${RED}错误:请使用 root 用户运行此脚本!${PLAIN}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}>>> 开始安装 RustDesk Server 1.1.15 (原生 DEB 版) <<<${PLAIN}"
|
||||
|
||||
# 2. 清理旧环境 & 安装依赖
|
||||
echo -e "${YELLOW}正在清理旧版本并安装必要工具...${PLAIN}"
|
||||
systemctl stop rustdesk-hbbs rustdesk-hbbr 2>/dev/null
|
||||
apt-get update -y
|
||||
apt-get install -y wget curl
|
||||
|
||||
# 3. 下载软件包
|
||||
WORK_DIR="/tmp/rustdesk_install"
|
||||
mkdir -p $WORK_DIR
|
||||
cd $WORK_DIR
|
||||
|
||||
# 你的下载链接
|
||||
HBBS_URL="https://cloudreve.vps3344521.xyz/f/BOuM/rustdesk-server-hbbs_1.1.15_amd64.deb"
|
||||
HBBR_URL="https://cloudreve.vps3344521.xyz/f/ZkfN/rustdesk-server-hbbr_1.1.15_amd64.deb"
|
||||
|
||||
echo -e "${YELLOW}正在下载 HBBS (ID服务器)...${PLAIN}"
|
||||
wget -O hbbs.deb $HBBS_URL
|
||||
echo -e "${YELLOW}正在下载 HBBR (中继服务器)...${PLAIN}"
|
||||
wget -O hbbr.deb $HBBR_URL
|
||||
|
||||
# 4. 执行安装
|
||||
echo -e "${YELLOW}正在执行安装...${PLAIN}"
|
||||
apt-get install -y ./hbbs.deb ./hbbr.deb
|
||||
|
||||
# 5. 启动服务
|
||||
echo -e "${YELLOW}正在启动服务...${PLAIN}"
|
||||
systemctl enable rustdesk-hbbs rustdesk-hbbr
|
||||
systemctl start rustdesk-hbbs rustdesk-hbbr
|
||||
|
||||
# 6. 获取信息
|
||||
# 获取公网IP
|
||||
HOST_IP=$(curl -s4 ifconfig.me)
|
||||
if [[ -z "$HOST_IP" ]]; then
|
||||
HOST_IP=$(curl -s4 ip.sb)
|
||||
fi
|
||||
|
||||
# 等待密钥生成
|
||||
sleep 3
|
||||
# DEB版本默认Key路径: /var/lib/rustdesk-server/
|
||||
KEY_FILE="/var/lib/rustdesk-server/id_ed25519.pub"
|
||||
|
||||
if [ -f "$KEY_FILE" ]; then
|
||||
PUB_KEY=$(cat "$KEY_FILE")
|
||||
|
||||
echo -e "${GREEN}=============================================${PLAIN}"
|
||||
echo -e " RustDesk Server 1.1.15 安装成功!"
|
||||
echo -e "${GREEN}=============================================${PLAIN}"
|
||||
echo -e "ID 服务器: ${GREEN}${HOST_IP}${PLAIN}"
|
||||
echo -e "中继服务器: ${GREEN}${HOST_IP}:21117${PLAIN}"
|
||||
echo -e "API 服务器: ${YELLOW}(无/留空)${PLAIN}"
|
||||
echo -e "Key (公钥):"
|
||||
echo -e "${YELLOW}${PUB_KEY}${PLAIN}"
|
||||
echo -e "${GREEN}=============================================${PLAIN}"
|
||||
echo -e "数据默认目录: /var/lib/rustdesk-server/"
|
||||
echo -e "如果不通,请务必检查防火墙是否放行 21115-21119 (TCP) 和 21116 (UDP)"
|
||||
else
|
||||
echo -e "${RED}安装似乎完成了,但未能读取到 Key。${PLAIN}"
|
||||
echo -e "请手动检查目录: /var/lib/rustdesk-server/"
|
||||
fi
|
||||
|
||||
# 清理安装包
|
||||
rm -rf $WORK_DIR
|
||||
EOF
|
||||
|
||||
# 运行脚本
|
||||
chmod +x install_deb.sh
|
||||
./install_deb.sh
|
||||
96
ru2进制下载安装
Normal file
96
ru2进制下载安装
Normal file
@@ -0,0 +1,96 @@
|
||||
bash <(curl -sSL https://raw.githubusercontent.com/tech-shrimp/rustdesk-native-install/main/install.sh 2>/dev/null || echo "
|
||||
#!/bin/bash
|
||||
# 颜色定义
|
||||
GREEN='\033[32m'
|
||||
RED='\033[31m'
|
||||
YELLOW='\033[33m'
|
||||
PLAIN='\033[0m'
|
||||
|
||||
# 安装目录
|
||||
INSTALL_DIR='/opt/rustdesk'
|
||||
WORK_DIR='/vol1/1000/dock/rustdesk_native' # 既然没有Docker,我们用这个目录存数据以符合你的习惯
|
||||
|
||||
echo -e \"\${GREEN}>>> 开始安装 RustDesk Server (原生版) <<<\${PLAIN}\"
|
||||
|
||||
# 1. 准备环境
|
||||
if [[ \$EUID -ne 0 ]]; then
|
||||
echo -e \"\${RED}请使用 root 运行!\${PLAIN}\"
|
||||
exit 1
|
||||
fi
|
||||
apt-get update && apt-get install -y wget unzip tar
|
||||
|
||||
# 2. 获取 IP
|
||||
read -p \"请输入服务器公网 IP (必填): \" HOST_IP
|
||||
if [[ -z \"\$HOST_IP\" ]]; then echo -e \"\${RED}IP 不能为空\${PLAIN}\"; exit 1; fi
|
||||
|
||||
# 3. 下载程序 (使用 GitHub 最新稳定版)
|
||||
mkdir -p \$INSTALL_DIR
|
||||
mkdir -p \$WORK_DIR
|
||||
cd \$INSTALL_DIR
|
||||
echo -e \"\${YELLOW}正在下载 RustDesk 服务端程序...\${PLAIN}\"
|
||||
# 这里使用固定的稳定版链接,防止获取失败
|
||||
wget -O rustdesk-server.zip https://github.com/rustdesk/rustdesk-server/releases/download/1.1.11-1/rustdesk-server-linux-amd64.zip
|
||||
unzip -o rustdesk-server.zip
|
||||
chmod +x hbbs hbbr
|
||||
|
||||
# 4. 创建系统服务 (hbbs - ID服务器)
|
||||
cat > /etc/systemd/system/rustdesk-hbbs.service <<EOF
|
||||
[Unit]
|
||||
Description=RustDesk ID Server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
LimitNOFILE=1000000
|
||||
ExecStart=\$INSTALL_DIR/hbbs -r \$HOST_IP -k _
|
||||
WorkingDirectory=\$WORK_DIR
|
||||
User=root
|
||||
Group=root
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# 5. 创建系统服务 (hbbr - 中继服务器)
|
||||
cat > /etc/systemd/system/rustdesk-hbbr.service <<EOF
|
||||
[Unit]
|
||||
Description=RustDesk Relay Server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
LimitNOFILE=1000000
|
||||
ExecStart=\$INSTALL_DIR/hbbr -k _
|
||||
WorkingDirectory=\$WORK_DIR
|
||||
User=root
|
||||
Group=root
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# 6. 启动服务
|
||||
systemctl daemon-reload
|
||||
systemctl enable rustdesk-hbbs rustdesk-hbbr
|
||||
systemctl restart rustdesk-hbbs rustdesk-hbbr
|
||||
|
||||
# 7. 检查与输出
|
||||
sleep 3
|
||||
if systemctl is-active --quiet rustdesk-hbbs; then
|
||||
PUB_KEY=\$(cat \$WORK_DIR/id_ed25519.pub)
|
||||
echo -e \"\${GREEN}=============================================\${PLAIN}\"
|
||||
echo -e \" 原生版 RustDesk 部署成功!\"
|
||||
echo -e \"\${GREEN}=============================================\${PLAIN}\"
|
||||
echo -e \"ID 服务器: \${GREEN}\${HOST_IP}\${PLAIN}\"
|
||||
echo -e \"中继服务器: \${GREEN}\${HOST_IP}\${PLAIN}\"
|
||||
echo -e \"Key (公钥): \${YELLOW}\${PUB_KEY}\${PLAIN}\"
|
||||
echo -e \"\${GREEN}=============================================\${PLAIN}\"
|
||||
echo -e \"数据存储目录: \${WORK_DIR}\"
|
||||
else
|
||||
echo -e \"\${RED}启动失败,请检查 systemctl status rustdesk-hbbs\${PLAIN}\"
|
||||
fi
|
||||
")
|
||||
29
ssh程
Normal file
29
ssh程
Normal file
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 1. 备份原始配置,防止改错
|
||||
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
|
||||
echo "已备份原始配置到 /etc/ssh/sshd_config.bak"
|
||||
|
||||
# 2. 修改 ListenAddress 确保监听所有接口 (0.0.0.0)
|
||||
# 这一步解决“只能局域网连,外部连不上”的监听问题
|
||||
sudo sed -i 's/^#ListenAddress 0.0.0.0/ListenAddress 0.0.0.0/' /etc/ssh/sshd_config
|
||||
sudo sed -i 's/^ListenAddress ::/#ListenAddress ::/' /etc/ssh/sshd_config
|
||||
|
||||
# 3. 允许密码登录 (确保没有被禁用)
|
||||
sudo sed -i 's/^PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config
|
||||
sudo sed -i 's/^#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config
|
||||
|
||||
# 4. 允许 Root 登录 (可选,视你的安全需求而定)
|
||||
# 如果你需要远程用 root 登录,请取消下面这行的注释
|
||||
# sudo sed -i 's/^#PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config
|
||||
|
||||
# 5. 检查配置文件语法是否正确
|
||||
sudo sshd -t
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "配置检查通过,正在重启 SSH 服务..."
|
||||
sudo systemctl restart ssh
|
||||
echo "修复完成!现在 SSH 应该可以接收来自所有接口的连接了。"
|
||||
else
|
||||
echo "配置文件修改有误,请检查!"
|
||||
exit 1
|
||||
fi
|
||||
134
te消息转发
Normal file
134
te消息转发
Normal file
@@ -0,0 +1,134 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ================= 颜色定义 =================
|
||||
RED='\033[31m'
|
||||
GREEN='\033[32m'
|
||||
YELLOW='\033[33m'
|
||||
BLUE='\033[34m'
|
||||
PLAIN='\033[0m'
|
||||
|
||||
# ================= 默认配置 =================
|
||||
DEFAULT_PORT=5005
|
||||
CONTAINER_NAME="telegram-monitor"
|
||||
IMAGE_NAME="ghcr.io/riniba/telegrammonitor:latest"
|
||||
YML_FILE="${CONTAINER_NAME}.yml"
|
||||
|
||||
# 检查是否以 root 运行
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo -e "${RED}错误: 必须使用 root 用户运行此脚本!${PLAIN}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
clear
|
||||
echo -e "${BLUE}====================================================${PLAIN}"
|
||||
echo -e "${BLUE} Telegram Monitor 一键部署脚本 (优化版 v2.0) ${PLAIN}"
|
||||
echo -e "${BLUE}====================================================${PLAIN}"
|
||||
|
||||
# 1. 检查 Docker 环境
|
||||
echo -e "${YELLOW}[1/6] 检查 Docker 环境...${PLAIN}"
|
||||
if ! command -v docker &> /dev/null; then
|
||||
echo -e "${RED}未检测到 Docker,请先安装 Docker!${PLAIN}"
|
||||
exit 1
|
||||
fi
|
||||
echo -e "${GREEN}Docker 已安装。${PLAIN}"
|
||||
|
||||
# 2. 设置安装路径
|
||||
echo -e "${YELLOW}[2/6] 配置安装路径...${PLAIN}"
|
||||
read -p "请输入安装路径 (默认: $HOME/telegram-monitor): " INSTALL_DIR
|
||||
if [ -z "$INSTALL_DIR" ]; then
|
||||
INSTALL_DIR="$HOME/telegram-monitor"
|
||||
fi
|
||||
echo -e "安装目录: ${GREEN}$INSTALL_DIR${PLAIN}"
|
||||
|
||||
# 创建目录
|
||||
if [ ! -d "$INSTALL_DIR/data" ]; then
|
||||
mkdir -p "$INSTALL_DIR/data"
|
||||
echo -e "已创建数据目录: $INSTALL_DIR/data"
|
||||
fi
|
||||
cd "$INSTALL_DIR"
|
||||
|
||||
# 3. 设置端口
|
||||
echo -e "${YELLOW}[3/6] 配置服务端口...${PLAIN}"
|
||||
read -p "请输入宿主机端口 (默认: $DEFAULT_PORT): " PORT
|
||||
if [ -z "$PORT" ]; then
|
||||
PORT=$DEFAULT_PORT
|
||||
fi
|
||||
|
||||
# 检查端口占用
|
||||
if lsof -Pi :$PORT -sTCP:LISTEN -t >/dev/null ; then
|
||||
echo -e "${RED}警告: 端口 $PORT 已经被占用!${PLAIN}"
|
||||
read -p "是否强制继续?(y/n): " FORCE_PORT
|
||||
if [[ "$FORCE_PORT" != "y" ]]; then
|
||||
echo "脚本已取消。"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
echo -e "使用端口: ${GREEN}$PORT${PLAIN}"
|
||||
|
||||
# 4. 清理旧容器
|
||||
echo -e "${YELLOW}[4/6] 清理旧环境...${PLAIN}"
|
||||
if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
|
||||
echo -e "${YELLOW}发现同名容器,正在停止并删除...${PLAIN}"
|
||||
docker stop $CONTAINER_NAME >/dev/null 2>&1
|
||||
docker rm $CONTAINER_NAME >/dev/null 2>&1
|
||||
echo -e "${GREEN}旧容器已清理。${PLAIN}"
|
||||
fi
|
||||
|
||||
# 5. 生成配置文件 (符合你的命名习惯)
|
||||
echo -e "${YELLOW}[5/6] 生成配置文件 $YML_FILE ...${PLAIN}"
|
||||
cat > $YML_FILE <<EOF
|
||||
version: '3.8'
|
||||
services:
|
||||
telegram-monitor:
|
||||
image: $IMAGE_NAME
|
||||
container_name: $CONTAINER_NAME
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "$PORT:5005"
|
||||
volumes:
|
||||
- ./data:/app
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
EOF
|
||||
echo -e "${GREEN}配置文件已生成。${PLAIN}"
|
||||
|
||||
# 6. 启动容器与健康检查
|
||||
echo -e "${YELLOW}[6/6] 拉取镜像并启动容器...${PLAIN}"
|
||||
|
||||
# 判断使用 docker compose 还是 docker-compose
|
||||
if docker compose version >/dev/null 2>&1; then
|
||||
CMD="docker compose"
|
||||
elif docker-compose version >/dev/null 2>&1; then
|
||||
CMD="docker-compose"
|
||||
else
|
||||
echo -e "${RED}错误: 未找到 docker-compose 插件。尝试直接使用 docker run 启动...${PLAIN}"
|
||||
docker run -d --name $CONTAINER_NAME --restart unless-stopped -p $PORT:5005 -v $INSTALL_DIR/data:/app -e ASPNETCORE_ENVIRONMENT=Production $IMAGE_NAME
|
||||
CMD="docker"
|
||||
fi
|
||||
|
||||
if [ "$CMD" != "docker" ]; then
|
||||
$CMD -f $YML_FILE up -d
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}正在进行健康检查 (等待 5 秒)...${PLAIN}"
|
||||
sleep 5
|
||||
|
||||
# 检查容器状态
|
||||
STATUS=$(docker inspect --format='{{.State.Status}}' $CONTAINER_NAME 2>/dev/null)
|
||||
|
||||
if [ "$STATUS" == "running" ]; then
|
||||
IP=$(hostname -I | awk '{print $1}')
|
||||
echo -e "${BLUE}========================================${PLAIN}"
|
||||
echo -e "${GREEN}✅ 部署成功!${PLAIN}"
|
||||
echo -e "容器状态: ${GREEN}$STATUS${PLAIN}"
|
||||
echo -e "配置文件: $INSTALL_DIR/$YML_FILE"
|
||||
echo -e "数据目录: $INSTALL_DIR/data"
|
||||
echo -e "访问地址: ${GREEN}http://$IP:$PORT${PLAIN}"
|
||||
echo -e "${BLUE}========================================${PLAIN}"
|
||||
else
|
||||
echo -e "${BLUE}========================================${PLAIN}"
|
||||
echo -e "${RED}❌ 部署可能失败,容器状态: $STATUS${PLAIN}"
|
||||
echo -e "${YELLOW}请运行以下命令查看报错日志:${PLAIN}"
|
||||
echo -e "docker logs $CONTAINER_NAME"
|
||||
echo -e "${BLUE}========================================${PLAIN}"
|
||||
fi
|
||||
18
xu
18
xu
@@ -16,8 +16,8 @@ Font="\033[0m"
|
||||
|
||||
# --- 核心配置 (用户定制) ---
|
||||
# 数据库链接
|
||||
DB_URL_PUBLIC="https://git.vps3344521.xyz/attachments/aa8ba64e-3a73-48f4-9317-07e06400b1d8" # 模式1链接
|
||||
DB_URL_PRIVATE="https://git.vps3344521.xyz/attachments/c457401f-76dd-4499-8ea3-a8b628bc963a" # 模式2链接
|
||||
DB_URL_PUBLIC="https://git.77582585.xyz/3344/dock/releases/download/3xui/x-ui%20%E6%88%B702.db" # 模式1链接
|
||||
DB_URL_PRIVATE="https://git.77582585.xyz/attachments/c457401f-76dd-4499-8ea3-a8b628bc963a" # 模式2链接
|
||||
|
||||
# 默认账号设置 (数据库下载后会被重置为此账号)
|
||||
INSTALL_PATH="/usr/local/x-ui"
|
||||
@@ -205,31 +205,31 @@ FILE_NAME=""
|
||||
case $ARCH in
|
||||
x86_64)
|
||||
FILE_NAME="x-ui-linux-amd64.tar.gz"
|
||||
DOWNLOAD_URL="https://git.vps3344521.xyz/attachments/40eeb013-5006-423f-ad74-a0541ab340f4"
|
||||
DOWNLOAD_URL="https://git.77582585.xyz/attachments/40eeb013-5006-423f-ad74-a0541ab340f4"
|
||||
;;
|
||||
aarch64|armv8)
|
||||
FILE_NAME="x-ui-linux-arm64.tar.gz"
|
||||
DOWNLOAD_URL="https://git.vps3344521.xyz/attachments/4ab708d5-6bc8-42c0-8494-ef5efe03e074"
|
||||
DOWNLOAD_URL="https://git.77582585.xyz/attachments/4ab708d5-6bc8-42c0-8494-ef5efe03e074"
|
||||
;;
|
||||
i386|i686)
|
||||
FILE_NAME="x-ui-linux-386.tar.gz"
|
||||
DOWNLOAD_URL="https://git.vps3344521.xyz/attachments/d1604006-c6b7-4c7c-9652-b42b229ef4cb"
|
||||
DOWNLOAD_URL="https://git.77582585.xyz/attachments/d1604006-c6b7-4c7c-9652-b42b229ef4cb"
|
||||
;;
|
||||
armv5*)
|
||||
FILE_NAME="x-ui-linux-armv5.tar.gz"
|
||||
DOWNLOAD_URL="https://git.vps3344521.xyz/attachments/8a5c678c-4ae4-43c4-910d-7e47f7c21c22"
|
||||
DOWNLOAD_URL="https://git.77582585.xyz/attachments/8a5c678c-4ae4-43c4-910d-7e47f7c21c22"
|
||||
;;
|
||||
armv6*)
|
||||
FILE_NAME="x-ui-linux-armv6.tar.gz"
|
||||
DOWNLOAD_URL="https://git.vps3344521.xyz/attachments/0e7c7fd7-192e-44b3-9739-785a5fb1b51f"
|
||||
DOWNLOAD_URL="https://git.77582585.xyz/attachments/0e7c7fd7-192e-44b3-9739-785a5fb1b51f"
|
||||
;;
|
||||
armv7*)
|
||||
FILE_NAME="x-ui-linux-armv7.tar.gz"
|
||||
DOWNLOAD_URL="https://git.vps3344521.xyz/attachments/9d1bf416-afb6-4e9f-b46b-ab3a1913a998"
|
||||
DOWNLOAD_URL="https://git.77582585.xyz/attachments/9d1bf416-afb6-4e9f-b46b-ab3a1913a998"
|
||||
;;
|
||||
s390x)
|
||||
FILE_NAME="x-ui-linux-s390x.tar.gz"
|
||||
DOWNLOAD_URL="https://git.vps3344521.xyz/attachments/18784828-0d20-4bc5-908c-15f91bcf8eb5"
|
||||
DOWNLOAD_URL="https://git.77582585.xyz/attachments/18784828-0d20-4bc5-908c-15f91bcf8eb5"
|
||||
;;
|
||||
*)
|
||||
echo -e "${Red}不支持或无法识别的架构: $ARCH${Font}"
|
||||
|
||||
263
xu1
Normal file
263
xu1
Normal file
@@ -0,0 +1,263 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ==========================================
|
||||
# 标题:X-UI 全能安装脚本 (精简服务器版)
|
||||
# 更新:移除第三方多线程下载器,保留原生 wget/curl
|
||||
# ==========================================
|
||||
|
||||
# --- 颜色配置 ---
|
||||
Red="\033[31m"
|
||||
Green="\033[32m"
|
||||
Yellow="\033[33m"
|
||||
Blue="\033[36m"
|
||||
Font="\033[0m"
|
||||
|
||||
# --- 核心配置 (用户定制) ---
|
||||
DB_URL_PUBLIC="https://git.77582585.xyz/3344/dock/releases/download/3xui/x-ui%20%E6%88%B702.db"
|
||||
DB_URL_PRIVATE="https://git.77582585.xyz/attachments/c457401f-76dd-4499-8ea3-a8b628bc963a"
|
||||
|
||||
INSTALL_PATH="/usr/local/x-ui"
|
||||
BIN_LINK="/usr/bin/x-ui"
|
||||
DB_PATH="/etc/x-ui/x-ui.db"
|
||||
SET_USER="3344"
|
||||
SET_PASS="3344"
|
||||
SET_PORT="8443"
|
||||
|
||||
# ==========================================
|
||||
# 1. 模式选择
|
||||
# ==========================================
|
||||
clear
|
||||
echo -e "${Blue}#################################################${Font}"
|
||||
echo -e "${Blue}# X-UI 自动安装脚本 (轻量精简版) #${Font}"
|
||||
echo -e "${Blue}#################################################${Font}"
|
||||
echo -e "${Yellow}请选择安装配置模式:${Font}"
|
||||
echo -e "-------------------------------------------------"
|
||||
echo -e "1. ${Green}标准配置安装${Font} (使用指定的公共数据库配置)"
|
||||
echo -e "2. ${Green}私人配置安装${Font} (私人数据库配置严禁个人使用)"
|
||||
echo -e "-------------------------------------------------"
|
||||
read -p "请输入数字 [1-2] (默认1): " INSTALL_MODE
|
||||
[[ -z "$INSTALL_MODE" ]] && INSTALL_MODE="1"
|
||||
|
||||
# ==========================================
|
||||
# 2. 网络环境智能检测
|
||||
# ==========================================
|
||||
check_network() {
|
||||
echo -e "${Yellow}>> [1/6] 正在检测网络环境...${Font}"
|
||||
HAS_IPV4=0
|
||||
HAS_IPV6=0
|
||||
|
||||
if curl -s4m2 https://www.google.com/generate_204 >/dev/null 2>&1 || curl -s4m2 https://www.baidu.com >/dev/null 2>&1; then
|
||||
HAS_IPV4=1
|
||||
fi
|
||||
if curl -s6m2 https://www.google.com/generate_204 >/dev/null 2>&1; then
|
||||
HAS_IPV6=1
|
||||
fi
|
||||
|
||||
if [[ $HAS_IPV4 -eq 1 ]]; then
|
||||
echo -e "${Green}检测到 IPv4 网络,将优先使用 IPv4 通道${Font}"
|
||||
NET_OPT="-4"
|
||||
elif [[ $HAS_IPV6 -eq 1 ]]; then
|
||||
echo -e "${Green}检测到纯 IPv6 网络,将自动切换至 IPv6 通道${Font}"
|
||||
NET_OPT="-6"
|
||||
else
|
||||
echo -e "${Red}错误:未检测到任何可用网络!${Font}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
check_network
|
||||
|
||||
# ==========================================
|
||||
# 3. 系统环境与依赖处理
|
||||
# ==========================================
|
||||
echo -e "${Yellow}>> [2/6] 安装基础依赖...${Font}"
|
||||
PM="apt"
|
||||
if [[ -f /etc/redhat-release ]] || command -v yum >/dev/null 2>&1; then PM="yum"; fi
|
||||
|
||||
install_soft() {
|
||||
if [ "$PM" == "apt" ]; then
|
||||
apt-get install -y $1 >/dev/null 2>&1
|
||||
elif [ "$PM" == "yum" ]; then
|
||||
yum install -y $1 >/dev/null 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "$PM" == "apt" ]; then
|
||||
pgrep -x "apt" && killall apt apt-get dpkg >/dev/null 2>&1
|
||||
rm -rf /var/lib/apt/lists/lock /var/lib/dpkg/lock*
|
||||
dpkg --configure -a >/dev/null 2>&1
|
||||
apt-get update -o Acquire::http::Timeout="20" || echo -e "${Red}源更新超时,尝试继续...${Font}"
|
||||
apt-get install -y curl wget tar ca-certificates bc sqlite3
|
||||
if ! apt-get install -y ntpdate >/dev/null 2>&1; then
|
||||
apt-get install -y ntpsec-ntpdate >/dev/null 2>&1
|
||||
fi
|
||||
else
|
||||
yum install -y epel-release >/dev/null 2>&1
|
||||
yum install -y curl wget tar bc sqlite3 ntpdate >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
# ==========================================
|
||||
# 4. 时间校准与架构匹配
|
||||
# ==========================================
|
||||
echo -e "${Yellow}>> [3/6] 校准时间与识别架构...${Font}"
|
||||
rm -f /etc/localtime
|
||||
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
||||
if command -v ntpdate >/dev/null 2>&1; then
|
||||
ntpdate pool.ntp.org >/dev/null 2>&1
|
||||
else
|
||||
date -s "$(curl -sI g.cn | grep Date | cut -d' ' -f3-6)Z" >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
ARCH=$(uname -m)
|
||||
DOWNLOAD_URL=""
|
||||
FILE_NAME=""
|
||||
|
||||
case $ARCH in
|
||||
x86_64)
|
||||
FILE_NAME="x-ui-linux-amd64.tar.gz"
|
||||
DOWNLOAD_URL="https://git.77582585.xyz/attachments/40eeb013-5006-423f-ad74-a0541ab340f4"
|
||||
;;
|
||||
aarch64|armv8)
|
||||
FILE_NAME="x-ui-linux-arm64.tar.gz"
|
||||
DOWNLOAD_URL="https://git.77582585.xyz/attachments/4ab708d5-6bc8-42c0-8494-ef5efe03e074"
|
||||
;;
|
||||
i386|i686)
|
||||
FILE_NAME="x-ui-linux-386.tar.gz"
|
||||
DOWNLOAD_URL="https://git.77582585.xyz/attachments/d1604006-c6b7-4c7c-9652-b42b229ef4cb"
|
||||
;;
|
||||
armv5*)
|
||||
FILE_NAME="x-ui-linux-armv5.tar.gz"
|
||||
DOWNLOAD_URL="https://git.77582585.xyz/attachments/8a5c678c-4ae4-43c4-910d-7e47f7c21c22"
|
||||
;;
|
||||
armv6*)
|
||||
FILE_NAME="x-ui-linux-armv6.tar.gz"
|
||||
DOWNLOAD_URL="https://git.77582585.xyz/attachments/0e7c7fd7-192e-44b3-9739-785a5fb1b51f"
|
||||
;;
|
||||
armv7*)
|
||||
FILE_NAME="x-ui-linux-armv7.tar.gz"
|
||||
DOWNLOAD_URL="https://git.77582585.xyz/attachments/9d1bf416-afb6-4e9f-b46b-ab3a1913a998"
|
||||
;;
|
||||
s390x)
|
||||
FILE_NAME="x-ui-linux-s390x.tar.gz"
|
||||
DOWNLOAD_URL="https://git.77582585.xyz/attachments/18784828-0d20-4bc5-908c-15f91bcf8eb5"
|
||||
;;
|
||||
*)
|
||||
echo -e "${Red}不支持或无法识别的架构: $ARCH${Font}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
echo -e "${Green}检测到架构: $ARCH,匹配文件名: $FILE_NAME${Font}"
|
||||
|
||||
# ==========================================
|
||||
# 5. 本地基础下载逻辑
|
||||
# ==========================================
|
||||
download_manager() {
|
||||
local url=$1
|
||||
local file=$2
|
||||
rm -f "$file"
|
||||
|
||||
echo -e "${Yellow}>> 尝试使用 Wget 下载...${Font}"
|
||||
if wget $NET_OPT --no-check-certificate --timeout=30 --tries=3 -O "$file" "$url"; then return 0; fi
|
||||
|
||||
echo -e "${Yellow}>> Wget 失败,尝试使用 Curl 兜底...${Font}"
|
||||
curl $NET_OPT -L -k --connect-timeout 30 --retry 3 -o "$file" "$url"
|
||||
}
|
||||
|
||||
echo -e "${Yellow}>> [4/6] 下载安装包 (Mode: $NET_OPT)...${Font}"
|
||||
mkdir -p /usr/local/
|
||||
cd /usr/local/
|
||||
download_manager "$DOWNLOAD_URL" "$FILE_NAME"
|
||||
|
||||
if ! tar -tzf "$FILE_NAME" >/dev/null 2>&1; then
|
||||
echo -e "${Red}严重错误:安装包下载失败或文件损坏!${Font}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ==========================================
|
||||
# 6. 安装与配置
|
||||
# ==========================================
|
||||
echo -e "${Yellow}>> [5/6] 解压与配置...${Font}"
|
||||
systemctl stop x-ui >/dev/null 2>&1
|
||||
killall x-ui >/dev/null 2>&1
|
||||
rm -rf x-ui
|
||||
tar zxvf "$FILE_NAME" >/dev/null
|
||||
cd x-ui
|
||||
chmod +x x-ui x-ui.sh bin/xray-linux-*
|
||||
ln -sf "$INSTALL_PATH/x-ui.sh" "$BIN_LINK"
|
||||
mkdir -p /etc/x-ui/
|
||||
rm -f "$DB_PATH"
|
||||
|
||||
if [ "$INSTALL_MODE" == "1" ]; then
|
||||
TARGET_DB="$DB_URL_PUBLIC"
|
||||
else
|
||||
TARGET_DB="$DB_URL_PRIVATE"
|
||||
fi
|
||||
|
||||
echo -e "${Yellow}>> 正在下载数据库配置...${Font}"
|
||||
download_manager "$TARGET_DB" "$DB_PATH"
|
||||
|
||||
if [ ! -s "$DB_PATH" ] || [ $(stat -c%s "$DB_PATH") -lt 1000 ]; then
|
||||
echo -e "${Red}警告:数据库下载失败,尝试使用默认空数据库初始化...${Font}"
|
||||
cp /usr/local/x-ui/bin/x-ui.db "$DB_PATH"
|
||||
fi
|
||||
|
||||
echo -e "${Yellow}>> 正在重置账户权限...${Font}"
|
||||
chmod 777 "$DB_PATH" >/dev/null 2>&1
|
||||
RESET_SUCCESS=0
|
||||
if command -v sqlite3 >/dev/null 2>&1; then
|
||||
sqlite3 -cmd ".timeout 2000" "$DB_PATH" "UPDATE settings SET value='/' WHERE key='webBasePath';"
|
||||
sqlite3 -cmd ".timeout 2000" "$DB_PATH" "UPDATE settings SET value='$SET_PORT' WHERE key='webPort';"
|
||||
sqlite3 -cmd ".timeout 2000" "$DB_PATH" "UPDATE users SET username='$SET_USER', password='$SET_PASS' WHERE id=1;"
|
||||
CURRENT_PASS=$(sqlite3 "$DB_PATH" "SELECT password FROM users WHERE id=1;")
|
||||
if [ "$CURRENT_PASS" == "$SET_PASS" ]; then
|
||||
RESET_SUCCESS=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $RESET_SUCCESS -eq 0 ]; then
|
||||
./x-ui setting -username "$SET_USER" -password "$SET_PASS" -port "$SET_PORT" >/dev/null 2>&1
|
||||
fi
|
||||
chmod 644 "$DB_PATH" >/dev/null 2>&1
|
||||
|
||||
# ==========================================
|
||||
# 7. 启动与放行
|
||||
# ==========================================
|
||||
echo -e "${Yellow}>> [6/6] 启动服务与防火墙放行...${Font}"
|
||||
cat > /etc/systemd/system/x-ui.service <<EOF
|
||||
[Unit]
|
||||
Description=x-ui Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=$INSTALL_PATH
|
||||
ExecStart=$INSTALL_PATH/x-ui
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable x-ui
|
||||
systemctl restart x-ui
|
||||
sleep 2
|
||||
|
||||
if command -v ufw >/dev/null 2>&1; then ufw allow $SET_PORT/tcp >/dev/null 2>&1; fi
|
||||
if command -v firewall-cmd >/dev/null 2>&1; then
|
||||
firewall-cmd --zone=public --add-port=$SET_PORT/tcp --permanent >/dev/null 2>&1
|
||||
firewall-cmd --reload >/dev/null 2>&1
|
||||
fi
|
||||
iptables -I INPUT -p tcp --dport $SET_PORT -j ACCEPT 2>/dev/null
|
||||
|
||||
IP=$(curl -s4m5 ip.sb)
|
||||
[ -z "$IP" ] && IP=$(curl -s6m5 ip.sb)
|
||||
|
||||
echo -e "\n${Blue}#################################################${Font}"
|
||||
echo -e "${Green} X-UI 安装完成 (精简服务器版) ${Font}"
|
||||
echo -e "${Blue}#################################################${Font}"
|
||||
echo -e "访问地址 : ${Green}http://$IP:$SET_PORT${Font}"
|
||||
echo -e "用户名 : ${Green}$SET_USER${Font}"
|
||||
echo -e "密码 : ${Green}$SET_PASS${Font}"
|
||||
echo -e "${Blue}#################################################${Font}"
|
||||
Reference in New Issue
Block a user