Compare commits
374 Commits
xzx3344521
...
3xui配置文件
| Author | SHA1 | Date | |
|---|---|---|---|
| 08cf4d38ac | |||
| b6302e21ac | |||
| a974f6972d | |||
| 419f50ce81 | |||
| 28a65c7b33 | |||
| cad86868e3 | |||
| acdc2ac728 | |||
| 43de8df1f4 | |||
| c1be032403 | |||
| 6195bce20f | |||
| e2e3666865 | |||
| 133da00a8d | |||
| ae8cdc5177 | |||
| 5943ac323f | |||
| 1f759825bc | |||
| fbc064b104 | |||
| 8667af321e | |||
| 43632c5f77 | |||
| eceb4d6fda | |||
| ac2ec2dcb5 | |||
| 231a653ca9 | |||
| b624145123 | |||
| 6a8b5da45c | |||
| 204b0e92d1 | |||
| feb6f1d711 | |||
| e75a91bbd9 | |||
| b04121130a | |||
| 3e5bce002d | |||
| cb01b81050 | |||
| 008054993d | |||
| b7ea4e9b3b | |||
| 96b9a0129b | |||
| 0cd1bd1fda | |||
| 1f58ae5c53 | |||
| 91766f8b2d | |||
| eae937fa32 | |||
| 2dce6b09d4 | |||
| 0147653cd3 | |||
| d091db7856 | |||
| 8124251089 | |||
| 762b730eae | |||
| 43df8f0fea | |||
| ef6e82d44a | |||
| 3ee4d4a9e0 | |||
| ee1ab72c40 | |||
| ae6c6e61ed | |||
| 87c738725d | |||
| 1c03631bf7 | |||
| 0cbd43262a | |||
| e7632981e6 | |||
| f1241749fc | |||
| d58934eee0 | |||
| 1de4bfbe94 | |||
| 68ea85f4d6 | |||
| fb5f4a5b3d | |||
| 314465cb66 | |||
| 7f5f418419 | |||
| 743824e0a2 | |||
| f03756df36 | |||
| b7100a9918 | |||
| f2e9615fd0 | |||
| 057cbbae8b | |||
| 35c3f8592b | |||
| 5d00a282b1 | |||
| 71910ef6ab | |||
| 61ad3f7ea4 | |||
| 312e0ce2e3 | |||
| 14565de26a | |||
| f232183388 | |||
| c048cfae16 | |||
| 483733c6c5 | |||
| 6d36606fb5 | |||
| e425b4a157 | |||
| 11f2edbcd0 | |||
| ffd7914e9e | |||
| 2313b9d74a | |||
| 4cce0c71c7 | |||
| 4a90e8684a | |||
| bee46803ca | |||
| f75c85b935 | |||
| d1937e501c | |||
| b94582c015 | |||
| 56337277ec | |||
| 1bc67096b0 | |||
| 62cc25225a | |||
| 781252a866 | |||
| 7e9c91dd77 | |||
| 0784256213 | |||
| f12ab11dc0 | |||
| d070b41b78 | |||
| b6ad620cf7 | |||
| 357cf8481c | |||
| 9d2de1d464 | |||
| 448d841994 | |||
| fa08770d13 | |||
| 185a7d5975 | |||
| f05eae3800 | |||
| 1d36a3a7f8 | |||
| 5563d1ff83 | |||
| 26a80df34d | |||
| 5e4fdedfda | |||
| 13c23891b0 | |||
| d9f449e566 | |||
| a6f100371d | |||
| 895619af12 | |||
| 76cf796e0d | |||
| 1e1a36be79 | |||
| 17cec702eb | |||
| 615fb9b6ba | |||
| d6bf909c26 | |||
| affc5a19e2 | |||
| 11dde135a7 | |||
| fda332eb3e | |||
| fc11d827d6 | |||
| 3b29d37920 | |||
| 9f83e3c00c | |||
| 7eff2e3c10 | |||
| 728330b083 | |||
| c25a3ee851 | |||
| 3940f2d537 | |||
| fb719a9f0c | |||
| 5bb5a27ac7 | |||
| 67d583c09d | |||
| 45e2c30556 | |||
| efcd80dbfc | |||
| 32f949eed7 | |||
| c1b8c62088 | |||
| 5b937ff46e | |||
| 553ed9035b | |||
| 20e8395a9e | |||
| 5ed06b7cbc | |||
| 0ac6c7dcd5 | |||
| 2c55d8a957 | |||
| 6f764b7c80 | |||
| e0411b1324 | |||
| c2f09380be | |||
| 05dc0ad4e8 | |||
| 1a0c406aeb | |||
| 9456ae29e4 | |||
| 3a5e45e800 | |||
| 2a4cc80fdb | |||
| 711a583b5b | |||
| f8ba1082d9 | |||
| cd617cc854 | |||
| 0304ba8f66 | |||
| 878e3c1b06 | |||
| 92fa8442ee | |||
| 7139b1dd57 | |||
| 7a4d45edde | |||
| 58bf555039 | |||
| 42704bf45d | |||
| 9a98956913 | |||
| bc72b7b486 | |||
| e3fdf10289 | |||
| 15da54e77f | |||
| dd997b9e3f | |||
| 124f255703 | |||
| 8ef3330f22 | |||
| 0d1e2e7b4d | |||
| 0726678ad1 | |||
| c91e542d2e | |||
| e49e5ffa5b | |||
| c44e9ffe8c | |||
| e64216cd6c | |||
| 3eea7f3b04 | |||
| c3a735f243 | |||
| 29e340640a | |||
| de99c3e475 | |||
| 6f14d7d312 | |||
| fe0bfd497f | |||
| 56fd71eb6c | |||
| fef7402b51 | |||
| 061386eb6b | |||
| 2bc0b34a30 | |||
| 3cb1fcb7a2 | |||
| b45d89fc5d | |||
| be06b8c3cc | |||
| a2bc350384 | |||
| adc00dc253 | |||
| 098c595493 | |||
| ba38856027 | |||
| bf6788117c | |||
| b9b7ce6b4c | |||
| 3d65b55310 | |||
| a1032c9e81 | |||
| 515a0a82fd | |||
| 6d83d52970 | |||
| c8d32ae758 | |||
| c499ebfe94 | |||
| 4707f324aa | |||
| 8e8bf5b109 | |||
| 2ad4cd0a72 | |||
| 70fb642800 | |||
| 5979a2b563 | |||
| fcaf1a7d37 | |||
| a3c4bbfa98 | |||
| 863cf11ee3 | |||
| f5293ba394 | |||
| f1a94ff217 | |||
| d4d8967f57 | |||
| 192a103c31 | |||
| fb530119f9 | |||
| d7b352f1a9 | |||
| fb157c8bcc | |||
| 90a901c1e4 | |||
| 2db2fef91d | |||
| 38e51627de | |||
| 75854f8b93 | |||
| d07bcba525 | |||
| 3eb24dfcc3 | |||
| bb2ef96ad0 | |||
| 97a297cfab | |||
| 0a3b917640 | |||
| 57a0576e57 | |||
| 304e577ac6 | |||
| da47aaf970 | |||
| 9e9c4accea | |||
| e8de9d6e2e | |||
| 9b0d3a551c | |||
| 36a168fb75 | |||
| 15ef4ffb62 | |||
| 97b9adee75 | |||
| d0774b91ac | |||
| ff48d84fb0 | |||
| 598dd0f73b | |||
| 0e41341394 | |||
| a3081cdf9b | |||
| 71f19ba018 | |||
| ab091f9758 | |||
| 6027c403c9 | |||
| 760950f1a6 | |||
| caf89e8890 | |||
| 805216dd3d | |||
| 939f4e4b45 | |||
| b269c0c371 | |||
| 17d5fe8919 | |||
| c73fcaf380 | |||
| 11673d8323 | |||
| dc93f35cce | |||
| 3c4f35fcf4 | |||
| e9f8b9fe52 | |||
| 45645aac22 | |||
| c5af751561 | |||
| 5b90094654 | |||
| db19c149cf | |||
| e0fc63ead7 | |||
| f812dfffe6 | |||
| e4be5ce0a0 | |||
| bd4c9f7a1c | |||
| dae305f272 | |||
| c0524c3861 | |||
| 2db6cb4d0a | |||
| e327b9333f | |||
| 8247c2222d | |||
| 480682fcc1 | |||
| 19d212c756 | |||
| 3bce424b49 | |||
| e87c4bb0ec | |||
| 64c678dc24 | |||
| 94e009e259 | |||
| ac115ae8c2 | |||
| de1cc8a129 | |||
| 5e5dd7fecb | |||
| eca62b3f80 | |||
| fab670adc4 | |||
| 7aa66cac4a | |||
| 1660ea82d6 | |||
| e41b5a0084 | |||
| dd24a96df2 | |||
| c8ed66d6fb | |||
| 7b7267b704 | |||
| 3436229904 | |||
| ada8d7d287 | |||
| 02660d5f44 | |||
| 61b056768d | |||
| a8b98cfe5e | |||
| b584e56b0f | |||
| 5bca571c8e | |||
| eb563d3375 | |||
| 6300ea1894 | |||
| c8dd96088e | |||
| 39aa93f362 | |||
| 22aae9d634 | |||
| 07cacd1d52 | |||
| 2fa02b4492 | |||
| 056afdf3a8 | |||
| 34167da3ce | |||
| 4af86f2908 | |||
| b897f408f4 | |||
| 8121be7461 | |||
| ce49d31605 | |||
| 3ff25bac9f | |||
| 82de7ea6a6 | |||
| b4b93199d1 | |||
| 24762ddef5 | |||
| 2327afde19 | |||
| d7ec942ca2 | |||
| ccac712991 | |||
| 023ceca9ec | |||
| c3ce4b2810 | |||
| cf9ff01030 | |||
| ade1e9ac00 | |||
| 7823a835d6 | |||
| c15a983bf7 | |||
| 4c50c0ec7f | |||
| ad093ad657 | |||
| 88b7e9a087 | |||
| c30039b264 | |||
| e1e4892310 | |||
| 3cdb025189 | |||
| c61b411970 | |||
| 45b6f1d622 | |||
| d8a9d5b5a4 | |||
| 325fe07e64 | |||
| 747ade1c39 | |||
| b5d3520bc1 | |||
| c8a47b04da | |||
| 71ac4f0cf7 | |||
| d761fdac84 | |||
| 8cc3350255 | |||
| b588994d23 | |||
| 302599cacb | |||
| 116ac792cb | |||
| 97902fb617 | |||
| b492b77af0 | |||
| 94620f7976 | |||
| aa07ab12f1 | |||
| 42c4ed7ac0 | |||
| 86361ffbf6 | |||
| bc999cf022 | |||
| 4f20f46565 | |||
| f06b1f3b78 | |||
| b14d154b62 | |||
| fad15caf41 | |||
| 77fed34de4 | |||
| 654ceb1e43 | |||
| c14c356d5e | |||
| 97b818a316 | |||
| 5cf6ca613a | |||
| a8c42be0dc | |||
| c30ef50961 | |||
| 0e5dcc14c2 | |||
| 85cb40944d | |||
| 1b65d78dd4 | |||
| 5e33294f20 | |||
| 1deed3fcb5 | |||
| 6a9c1b0798 | |||
| 46d38b6d1b | |||
| a70106d657 | |||
| b8501e5871 | |||
| 0e5cd12fcb | |||
| c77457f939 | |||
| 0c1858fcd4 | |||
| 55944af8e8 | |||
| 15e2c561bb | |||
| e22e758d2d | |||
| d7336a35a1 | |||
| 9cfaf94336 | |||
| da5f5b0277 | |||
| 4fc7adbd95 | |||
| e26bbdcd17 | |||
| 71c5b97e7d | |||
| 24a955aa99 | |||
| 165879392c | |||
| ffee6bf1bf | |||
| 815b240ee7 | |||
| 33c6d53987 | |||
| e5988317bb | |||
| 23ddcbc9d2 | |||
| 03305bb063 | |||
| f3745809ac | |||
| 46e697130e | |||
| f204262aab | |||
| fcfab711ad |
23
02
Normal file
23
02
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# search_all_videos.sh
|
||||||
|
|
||||||
|
echo "开始全面搜索视频文件..."
|
||||||
|
echo "=========================="
|
||||||
|
|
||||||
|
# 搜索容器内部
|
||||||
|
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 "--------------------------"
|
||||||
|
|
||||||
|
# 搜索本地映射目录
|
||||||
|
echo "2. 搜索本地映射目录..."
|
||||||
|
find ./data -type f \( -name "*.mp4" -o -name "*.avi" -o -name "*.mkv" -o -name "*.mov" -o -name "*.wmv" \) 2>/dev/null
|
||||||
|
|
||||||
|
echo "--------------------------"
|
||||||
|
|
||||||
|
# 搜索整个系统(可能需要权限)
|
||||||
|
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
|
||||||
|
|
||||||
|
echo "搜索完成!"
|
||||||
484
03
Normal file
484
03
Normal file
@@ -0,0 +1,484 @@
|
|||||||
|
#!/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
|
||||||
|
|
||||||
|
# 显示标题
|
||||||
|
echo -e "${CYAN}"
|
||||||
|
echo "================================================"
|
||||||
|
echo " 全端口扫描诊断工具 v3.0"
|
||||||
|
echo "================================================"
|
||||||
|
echo -e "${NC}"
|
||||||
|
|
||||||
|
# 变量定义
|
||||||
|
SCAN_RESULTS=()
|
||||||
|
OPEN_PORTS=()
|
||||||
|
TOTAL_PORTS_SCANNED=0
|
||||||
|
START_TIME=0
|
||||||
|
END_TIME=0
|
||||||
|
|
||||||
|
# 函数:检查命令是否存在
|
||||||
|
check_command() {
|
||||||
|
if command -v "$1" &> /dev/null; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 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 ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# 函数:输入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
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查系统要求
|
||||||
|
check_requirements
|
||||||
|
|
||||||
|
# 运行主程序
|
||||||
|
main
|
||||||
229
1.sh
229
1.sh
@@ -1,22 +1,219 @@
|
|||||||
#update soft sources
|
#!/bin/bash
|
||||||
echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm main contrib non-free non-free-firmware" > /etc/apt/sources.list
|
|
||||||
echo "deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm main contrib non-free non-free-firmware" >> /etc/apt/sources.list
|
|
||||||
|
|
||||||
echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian-security/ bookworm-security main contrib non-free non-free-firmware" >> /etc/apt/sources.list
|
# 智能APT镜像源配置脚本
|
||||||
echo "deb-src https://mirrors.tuna.tsinghua.edu.cn/debian-security/ bookworm-security main contrib non-free non-free-firmware" >> /etc/apt/sources.list
|
# 自动检测地理位置并选择最佳镜像源
|
||||||
|
|
||||||
echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware" >> /etc/apt/sources.list
|
set -e # 遇到错误立即退出
|
||||||
echo "deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware" >> /etc/apt/sources.list
|
|
||||||
|
|
||||||
echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-backports main contrib non-free non-free-firmware" >> /etc/apt/sources.list
|
echo "=== 智能APT镜像源配置 ==="
|
||||||
echo "deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-backports main contrib non-free non-free-firmware" >> /etc/apt/sources.list
|
|
||||||
|
|
||||||
sudo apt update
|
# 颜色定义
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
#install vim
|
# 日志函数
|
||||||
sudo apt install vim -y
|
log_info() {
|
||||||
|
echo -e "${BLUE}[INFO]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
#install gcc g++
|
log_success() {
|
||||||
sudo apt install build-essential -y
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||||
sudo apt install g++ -y
|
}
|
||||||
sudo apt install gfortran -y
|
|
||||||
|
log_warning() {
|
||||||
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_error() {
|
||||||
|
echo -e "${RED}[ERROR]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检测是否在中国大陆
|
||||||
|
detect_location() {
|
||||||
|
log_info "正在检测地理位置..."
|
||||||
|
|
||||||
|
# 方法1: 通过IP API检测
|
||||||
|
local location_info=""
|
||||||
|
if command -v curl &> /dev/null; then
|
||||||
|
location_info=$(curl -s --connect-timeout 5 "http://ip-api.com/json/?fields=country,countryCode" || true)
|
||||||
|
elif command -v wget &> /dev/null; then
|
||||||
|
location_info=$(wget -q -O - --timeout=5 "http://ip-api.com/json/?fields=country,countryCode" || true)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$location_info" ]]; then
|
||||||
|
if echo "$location_info" | grep -q "China\|CN"; then
|
||||||
|
log_success "检测到中国大陆地理位置"
|
||||||
|
return 0 # 在中国
|
||||||
|
else
|
||||||
|
log_info "检测到非中国大陆地理位置"
|
||||||
|
return 1 # 不在中国
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 方法2: 通过时区检测(备用方案)
|
||||||
|
local timezone=$(timedatectl show --property=Timezone --value 2>/dev/null || echo "")
|
||||||
|
if [[ -n "$timezone" ]]; then
|
||||||
|
if [[ "$timezone" == *"Asia/Shanghai"* || "$timezone" == *"Asia/Chongqing"* || "$timezone" == *"Asia/Harbin"* ]]; then
|
||||||
|
log_success "通过时区检测到中国大陆"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 方法3: 检查系统语言设置
|
||||||
|
local lang=$(echo "$LANG" | tr '[:upper:]' '[:lower:]')
|
||||||
|
if [[ "$lang" == *"zh_cn"* || "$lang" == *"zh.utf"* ]]; then
|
||||||
|
log_success "通过语言设置检测到中国大陆"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_warning "无法确定地理位置,使用默认配置"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 备份原有源列表
|
||||||
|
backup_sources() {
|
||||||
|
if [[ -f /etc/apt/sources.list ]]; then
|
||||||
|
local backup_name="/etc/apt/sources.list.backup.$(date +%Y%m%d_%H%M%S)"
|
||||||
|
cp /etc/apt/sources.list "$backup_name"
|
||||||
|
log_success "已备份原有源列表: $backup_name"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 配置国内镜像源(清华源)
|
||||||
|
setup_china_mirror() {
|
||||||
|
log_info "配置清华大学镜像源..."
|
||||||
|
|
||||||
|
cat > /etc/apt/sources.list << 'EOF'
|
||||||
|
# 清华大学 Debian 镜像源
|
||||||
|
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm main contrib non-free non-free-firmware
|
||||||
|
deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm main contrib non-free non-free-firmware
|
||||||
|
|
||||||
|
deb https://mirrors.tuna.tsinghua.edu.cn/debian-security/ bookworm-security main contrib non-free non-free-firmware
|
||||||
|
deb-src https://mirrors.tuna.tsinghua.edu.cn/debian-security/ bookworm-security main contrib non-free non-free-firmware
|
||||||
|
|
||||||
|
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware
|
||||||
|
deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware
|
||||||
|
|
||||||
|
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-backports main contrib non-free non-free-firmware
|
||||||
|
deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-backports main contrib non-free non-free-firmware
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_success "清华大学镜像源配置完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 配置国外官方源
|
||||||
|
setup_official_mirror() {
|
||||||
|
log_info "配置Debian官方源..."
|
||||||
|
|
||||||
|
cat > /etc/apt/sources.list << 'EOF'
|
||||||
|
# Debian 官方源
|
||||||
|
deb http://deb.debian.org/debian/ bookworm main contrib non-free non-free-firmware
|
||||||
|
deb-src http://deb.debian.org/debian/ bookworm main contrib non-free non-free-firmware
|
||||||
|
|
||||||
|
deb http://deb.debian.org/debian-security/ bookworm-security main contrib non-free non-free-firmware
|
||||||
|
deb-src http://deb.debian.org/debian-security/ bookworm-security main contrib non-free non-free-firmware
|
||||||
|
|
||||||
|
deb http://deb.debian.org/debian/ bookworm-updates main contrib non-free non-free-firmware
|
||||||
|
deb-src http://deb.debian.org/debian/ bookworm-updates main contrib non-free non-free-firmware
|
||||||
|
|
||||||
|
deb http://deb.debian.org/debian/ bookworm-backports main contrib non-free non-free-firmware
|
||||||
|
deb-src http://deb.debian.org/debian/ bookworm-backports main contrib non-free non-free-firmware
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_success "Debian官方源配置完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 测试镜像源速度(可选)
|
||||||
|
test_mirror_speed() {
|
||||||
|
if command -v curl &> /dev/null; then
|
||||||
|
log_info "正在测试镜像源连接速度..."
|
||||||
|
|
||||||
|
local mirrors=("deb.debian.org" "mirrors.tuna.tsinghua.edu.cn")
|
||||||
|
local fastest_mirror=""
|
||||||
|
local fastest_time=999
|
||||||
|
|
||||||
|
for mirror in "${mirrors[@]}"; do
|
||||||
|
local time=$(curl -o /dev/null -s -w "%{time_total}" "https://$mirror" --connect-timeout 3 || echo "999")
|
||||||
|
if (( $(echo "$time < $fastest_time" | bc -l) )); then
|
||||||
|
fastest_time=$time
|
||||||
|
fastest_mirror=$mirror
|
||||||
|
fi
|
||||||
|
log_info "$mirror: ${time}s"
|
||||||
|
done
|
||||||
|
|
||||||
|
log_success "最快镜像: $fastest_mirror (${fastest_time}s)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 安装开发工具
|
||||||
|
install_dev_tools() {
|
||||||
|
log_info "开始安装开发工具..."
|
||||||
|
|
||||||
|
# 更新包列表
|
||||||
|
apt update
|
||||||
|
|
||||||
|
# 安装基础工具
|
||||||
|
local packages=("vim" "build-essential" "g++" "gfortran" "curl" "wget")
|
||||||
|
|
||||||
|
for pkg in "${packages[@]}"; do
|
||||||
|
if dpkg -l | grep -q "^ii $pkg "; then
|
||||||
|
log_info "$pkg 已安装,跳过"
|
||||||
|
else
|
||||||
|
log_info "安装 $pkg ..."
|
||||||
|
apt install -y "$pkg"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
log_success "开发工具安装完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 主函数
|
||||||
|
main() {
|
||||||
|
# 检查root权限
|
||||||
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
log_error "请使用root权限运行此脚本"
|
||||||
|
echo "使用方法: sudo $0"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检测系统类型
|
||||||
|
if [[ ! -f /etc/debian_version ]]; then
|
||||||
|
log_error "此脚本仅适用于Debian/Ubuntu系统"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 备份原有配置
|
||||||
|
backup_sources
|
||||||
|
|
||||||
|
# 检测地理位置并配置相应的镜像源
|
||||||
|
if detect_location; then
|
||||||
|
setup_china_mirror
|
||||||
|
else
|
||||||
|
setup_official_mirror
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 测试镜像速度(可选)
|
||||||
|
if command -v bc &> /dev/null; then
|
||||||
|
test_mirror_speed
|
||||||
|
else
|
||||||
|
log_warning "未安装bc,跳过速度测试"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 安装开发工具
|
||||||
|
install_dev_tools
|
||||||
|
|
||||||
|
log_success "=== 配置完成 ==="
|
||||||
|
echo ""
|
||||||
|
log_info "已安装的工具:"
|
||||||
|
echo " - Vim 编辑器"
|
||||||
|
echo " - GCC/G++ 编译器"
|
||||||
|
echo " - GFortran 编译器"
|
||||||
|
echo " - Build-essential 开发工具包"
|
||||||
|
echo " - curl/wget 网络工具"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 运行主函数
|
||||||
|
main "$@"
|
||||||
|
|||||||
85
666
Normal file
85
666
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
bash -c 'set -euo pipefail
|
||||||
|
|
||||||
|
echo "==> [1/7] 检测系统..."
|
||||||
|
. /etc/os-release || true
|
||||||
|
echo "ID=${ID:-unknown} VERSION_CODENAME=${VERSION_CODENAME:-unknown}"
|
||||||
|
if [ "${ID:-}" != "debian" ]; then
|
||||||
|
echo "❌ 该脚本仅针对 Debian。当前: ${ID:-unknown}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> [2/7] 停止并清理可能已安装/混装的 Docker..."
|
||||||
|
systemctl stop docker 2>/dev/null || true
|
||||||
|
systemctl stop containerd 2>/dev/null || true
|
||||||
|
|
||||||
|
apt-get remove -y docker-ce docker-ce-cli containerd.io docker-compose-plugin docker-ce-rootless-extras docker-buildx-plugin 2>/dev/null || true
|
||||||
|
apt-get purge -y docker-ce docker-ce-cli containerd.io docker-compose-plugin docker-ce-rootless-extras docker-buildx-plugin 2>/dev/null || true
|
||||||
|
apt-get autoremove -y 2>/dev/null || true
|
||||||
|
|
||||||
|
# 清理可能残留的二进制(避免 docker 命令指向错误版本)
|
||||||
|
rm -f /usr/bin/docker /usr/local/bin/docker /usr/bin/dockerd /usr/local/bin/dockerd 2>/dev/null || true
|
||||||
|
|
||||||
|
echo "==> [3/7] 清理/修复 APT 断裂依赖..."
|
||||||
|
apt-get clean || true
|
||||||
|
apt-get update -y || true
|
||||||
|
apt-get -y --fix-broken install || true
|
||||||
|
|
||||||
|
echo "==> [4/7] 修复 Debian 源(优先官方 deb.debian.org,失败则切阿里云)..."
|
||||||
|
backup="/etc/apt/sources.list.bak.$(date +%F_%H%M%S)"
|
||||||
|
cp -a /etc/apt/sources.list "$backup" 2>/dev/null || true
|
||||||
|
|
||||||
|
write_sources() {
|
||||||
|
local base="$1"
|
||||||
|
cat >/etc/apt/sources.list <<EOF
|
||||||
|
deb ${base}/debian bullseye main contrib non-free
|
||||||
|
deb ${base}/debian bullseye-updates main contrib non-free
|
||||||
|
deb ${base}/debian-security bullseye-security main contrib non-free
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# 先写官方源
|
||||||
|
write_sources "http://deb.debian.org"
|
||||||
|
if ! apt-get update -y; then
|
||||||
|
echo "⚠️ 官方源不可用,切换到阿里云镜像..."
|
||||||
|
write_sources "http://mirrors.aliyun.com"
|
||||||
|
apt-get update -y
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> [5/7] 移除任何 bookworm 源(避免再次装到 Debian 12 包)..."
|
||||||
|
mkdir -p /root/apt-list-backup
|
||||||
|
for f in /etc/apt/sources.list.d/*.list; do
|
||||||
|
[ -e "$f" ] || continue
|
||||||
|
if grep -qi "bookworm" "$f"; then
|
||||||
|
echo " - 发现 bookworm 源: $f -> 移到 /root/apt-list-backup/"
|
||||||
|
mv -f "$f" /root/apt-list-backup/
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
apt-get update -y
|
||||||
|
apt-get -y --fix-broken install
|
||||||
|
|
||||||
|
echo "==> [6/7] 添加 Docker 官方源(强制 bullseye)并安装..."
|
||||||
|
apt-get install -y ca-certificates curl gnupg
|
||||||
|
install -m 0755 -d /etc/apt/keyrings
|
||||||
|
|
||||||
|
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||||
|
chmod a+r /etc/apt/keyrings/docker.gpg
|
||||||
|
|
||||||
|
cat >/etc/apt/sources.list.d/docker.list <<EOF
|
||||||
|
deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian bullseye stable
|
||||||
|
EOF
|
||||||
|
|
||||||
|
apt-get update -y
|
||||||
|
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||||
|
|
||||||
|
systemctl enable --now docker
|
||||||
|
|
||||||
|
echo "==> [7/7] 验证安装..."
|
||||||
|
docker --version
|
||||||
|
docker run --rm hello-world >/dev/null 2>&1 && echo "✅ Docker 已安装并验证通过(hello-world 成功)" || {
|
||||||
|
echo "⚠️ Docker 已安装,但 hello-world 未通过。请执行:journalctl -u docker -n 200 --no-pager"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "完成。"
|
||||||
|
'
|
||||||
67
AlmaLinux dock
Normal file
67
AlmaLinux dock
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "🚀 开始在 AlmaLinux 9.4 上安装 Docker..."
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
# 检测系统
|
||||||
|
if [ ! -f /etc/almalinux-release ]; then
|
||||||
|
echo -e "${RED}错误: 这个脚本只支持 AlmaLinux${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${YELLOW}[1/7] 清理旧版本...${NC}"
|
||||||
|
sudo dnf remove -y docker* podman* containerd* || true
|
||||||
|
|
||||||
|
echo -e "${YELLOW}[2/7] 安装依赖...${NC}"
|
||||||
|
sudo dnf install -y dnf-plugins-core yum-utils device-mapper-persistent-data lvm2
|
||||||
|
|
||||||
|
echo -e "${YELLOW}[3/7] 添加 Docker 仓库...${NC}"
|
||||||
|
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
|
||||||
|
|
||||||
|
echo -e "${YELLOW}[4/7] 启用 CRB 仓库...${NC}"
|
||||||
|
sudo dnf config-manager --set-enabled crb
|
||||||
|
|
||||||
|
echo -e "${YELLOW}[5/7] 安装 Docker...${NC}"
|
||||||
|
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||||
|
|
||||||
|
echo -e "${YELLOW}[6/7] 配置 Docker...${NC}"
|
||||||
|
sudo systemctl start docker
|
||||||
|
sudo systemctl enable docker
|
||||||
|
|
||||||
|
echo -e "${YELLOW}[7/7] 配置用户权限...${NC}"
|
||||||
|
sudo usermod -aG docker $USER
|
||||||
|
|
||||||
|
# 配置镜像加速器(国内用户)
|
||||||
|
sudo mkdir -p /etc/docker
|
||||||
|
sudo tee /etc/docker/daemon.json > /dev/null <<EOF
|
||||||
|
{
|
||||||
|
"registry-mirrors": [
|
||||||
|
"https://docker.m.daocloud.io",
|
||||||
|
"https://registry.docker-cn.com"
|
||||||
|
],
|
||||||
|
"exec-opts": ["native.cgroupdriver=systemd"],
|
||||||
|
"log-driver": "json-file",
|
||||||
|
"log-opts": {
|
||||||
|
"max-size": "100m"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sudo systemctl restart docker
|
||||||
|
|
||||||
|
echo -e "${GREEN}✅ Docker 安装成功!${NC}"
|
||||||
|
echo -e "${YELLOW}📋 版本信息:${NC}"
|
||||||
|
docker --version
|
||||||
|
docker-compose --version
|
||||||
|
|
||||||
|
echo -e "${YELLOW}🔧 请重新登录或运行以下命令:${NC}"
|
||||||
|
echo " newgrp docker"
|
||||||
|
echo -e "${YELLOW}🐳 测试命令:${NC}"
|
||||||
|
echo " docker run hello-world"
|
||||||
476
BorgBacku系统备份软件
Normal file
476
BorgBacku系统备份软件
Normal file
@@ -0,0 +1,476 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# BorgBackup 智能安装配置脚本
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# 日志函数
|
||||||
|
log() {
|
||||||
|
echo -e "${GREEN}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
warn() {
|
||||||
|
echo -e "${YELLOW}[WARN]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查系统
|
||||||
|
check_system() {
|
||||||
|
log "检查系统环境..."
|
||||||
|
|
||||||
|
# 检查操作系统
|
||||||
|
if [ ! -f /etc/os-release ]; then
|
||||||
|
error "无法检测操作系统"
|
||||||
|
fi
|
||||||
|
|
||||||
|
source /etc/os-release
|
||||||
|
log "检测到系统: $NAME $VERSION"
|
||||||
|
|
||||||
|
# 检查架构
|
||||||
|
ARCH=$(uname -m)
|
||||||
|
log "系统架构: $ARCH"
|
||||||
|
|
||||||
|
# 检查磁盘空间
|
||||||
|
DISK_SPACE=$(df /tmp | awk 'NR==2 {print $4}')
|
||||||
|
if [ "$DISK_SPACE" -lt 1048576 ]; then # 小于 1GB
|
||||||
|
warn "磁盘空间可能不足 (当前: ${DISK_SPACE}KB)"
|
||||||
|
read -p "是否继续? (y/N): " -n 1 -r
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
error "安装中止"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查内存
|
||||||
|
MEMORY=$(free -m | awk 'NR==2{print $2}')
|
||||||
|
if [ "$MEMORY" -lt 512 ]; then
|
||||||
|
warn "内存较小 (当前: ${MEMORY}MB),可能会影响备份性能"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 安装依赖
|
||||||
|
install_dependencies() {
|
||||||
|
log "安装系统依赖..."
|
||||||
|
|
||||||
|
# 根据系统类型安装依赖
|
||||||
|
if command -v apt >/dev/null 2>&1; then
|
||||||
|
# Debian/Ubuntu
|
||||||
|
sudo apt update || warn "apt update 失败,尝试继续..."
|
||||||
|
sudo apt install -y \
|
||||||
|
python3 \
|
||||||
|
python3-pip \
|
||||||
|
curl \
|
||||||
|
wget \
|
||||||
|
fuse \
|
||||||
|
pv \
|
||||||
|
cron \
|
||||||
|
|| error "依赖安装失败"
|
||||||
|
|
||||||
|
elif command -v yum >/dev/null 2>&1; then
|
||||||
|
# CentOS/RHEL
|
||||||
|
sudo yum install -y \
|
||||||
|
python3 \
|
||||||
|
python3-pip \
|
||||||
|
curl \
|
||||||
|
wget \
|
||||||
|
fuse \
|
||||||
|
pv \
|
||||||
|
cronie \
|
||||||
|
|| error "依赖安装失败"
|
||||||
|
|
||||||
|
elif command -v dnf >/dev/null 2>&1; then
|
||||||
|
# Fedora
|
||||||
|
sudo dnf install -y \
|
||||||
|
python3 \
|
||||||
|
python3-pip \
|
||||||
|
curl \
|
||||||
|
wget \
|
||||||
|
fuse \
|
||||||
|
pv \
|
||||||
|
cronie \
|
||||||
|
|| error "依赖安装失败"
|
||||||
|
|
||||||
|
else
|
||||||
|
error "不支持的包管理器"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 安装 BorgBackup
|
||||||
|
install_borg() {
|
||||||
|
log "安装 BorgBackup..."
|
||||||
|
|
||||||
|
# 检查是否已安装
|
||||||
|
if command -v borg >/dev/null 2>&1; then
|
||||||
|
CURRENT_VERSION=$(borg --version)
|
||||||
|
log "BorgBackup 已安装: $CURRENT_VERSION"
|
||||||
|
read -p "是否重新安装? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 多种安装方式
|
||||||
|
log "尝试通过系统包管理器安装..."
|
||||||
|
if command -v apt >/dev/null 2>&1; then
|
||||||
|
sudo apt install -y borgbackup && return 0
|
||||||
|
elif command -v yum >/dev/null 2>&1; then
|
||||||
|
sudo yum install -y borgbackup && return 0
|
||||||
|
elif command -v dnf >/dev/null 2>&1; then
|
||||||
|
sudo dnf install -y borgbackup && return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 包管理器安装失败,使用 pip
|
||||||
|
warn "包管理器安装失败,尝试使用 pip 安装..."
|
||||||
|
sudo pip3 install borgbackup || {
|
||||||
|
# 如果 pip 安装失败,尝试使用 conda
|
||||||
|
if command -v conda >/dev/null 2>&1; then
|
||||||
|
warn "尝试使用 conda 安装..."
|
||||||
|
conda install -c conda-forge borgbackup || error "BorgBackup 安装失败"
|
||||||
|
else
|
||||||
|
error "所有安装方式都失败,请手动安装"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
log "BorgBackup 安装成功: $(borg --version)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 安装 rclone
|
||||||
|
install_rclone() {
|
||||||
|
log "安装 rclone..."
|
||||||
|
|
||||||
|
if command -v rclone >/dev/null 2>&1; then
|
||||||
|
log "rclone 已安装: $(rclone version | head -n1)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 使用官方安装脚本
|
||||||
|
curl https://rclone.org/install.sh | sudo bash || {
|
||||||
|
# 如果脚本安装失败,尝试包管理器
|
||||||
|
warn "脚本安装失败,尝试包管理器..."
|
||||||
|
if command -v apt >/dev/null 2>&1; then
|
||||||
|
sudo apt install -y rclone
|
||||||
|
elif command -v yum >/dev/null 2>&1; then
|
||||||
|
sudo yum install -y rclone
|
||||||
|
else
|
||||||
|
error "rclone 安装失败"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
log "rclone 安装成功"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 交互式配置 rclone
|
||||||
|
configure_rclone() {
|
||||||
|
log "配置云存储..."
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "=== 云存储服务商选择 ==="
|
||||||
|
echo "1) Cloudflare R2 (推荐)"
|
||||||
|
echo "2) AWS S3"
|
||||||
|
echo "3) Backblaze B2"
|
||||||
|
echo "4) Google Cloud Storage"
|
||||||
|
echo "5) 阿里云 OSS"
|
||||||
|
echo "6) 腾讯云 COS"
|
||||||
|
echo "7) 其他 S3 兼容服务"
|
||||||
|
echo "8) 跳过(仅本地备份)"
|
||||||
|
|
||||||
|
read -p "请选择服务商 [1-8]: " provider_choice
|
||||||
|
|
||||||
|
case $provider_choice in
|
||||||
|
1)
|
||||||
|
remote_name="r2"
|
||||||
|
provider="Cloudflare R2"
|
||||||
|
endpoint_prompt="R2 端点 (通常为: https://<account-id>.r2.cloudflarestorage.com)"
|
||||||
|
region="auto"
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
remote_name="s3"
|
||||||
|
provider="Amazon S3"
|
||||||
|
endpoint_prompt="S3 端点 (留空使用默认): "
|
||||||
|
region_prompt="区域 (例如: us-east-1): "
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
remote_name="b2"
|
||||||
|
provider="Backblaze B2"
|
||||||
|
endpoint_prompt="B2 端点 (留空使用默认): "
|
||||||
|
region=""
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
remote_name="gcs"
|
||||||
|
provider="Google Cloud Storage"
|
||||||
|
endpoint_prompt="GCS 端点 (留空使用默认): "
|
||||||
|
region=""
|
||||||
|
;;
|
||||||
|
5)
|
||||||
|
remote_name="oss"
|
||||||
|
provider="Aliyun OSS"
|
||||||
|
endpoint_prompt="OSS 端点 (例如: https://oss-cn-hangzhou.aliyuncs.com): "
|
||||||
|
region=""
|
||||||
|
;;
|
||||||
|
6)
|
||||||
|
remote_name="cos"
|
||||||
|
provider="Tencent COS"
|
||||||
|
endpoint_prompt="COS 端点 (例如: https://cos.ap-beijing.myqcloud.com): "
|
||||||
|
region=""
|
||||||
|
;;
|
||||||
|
7)
|
||||||
|
remote_name="s3-custom"
|
||||||
|
provider="自定义 S3 兼容"
|
||||||
|
endpoint_prompt="S3 兼容端点: "
|
||||||
|
region_prompt="区域: "
|
||||||
|
;;
|
||||||
|
8)
|
||||||
|
log "跳过远程存储配置"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
error "无效选择"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# 获取配置信息
|
||||||
|
echo
|
||||||
|
echo "=== 配置 $provider ==="
|
||||||
|
read -p "请输入远程存储名称 [默认: $remote_name]: " input_remote
|
||||||
|
remote_name=${input_remote:-$remote_name}
|
||||||
|
|
||||||
|
read -p "$endpoint_prompt" endpoint
|
||||||
|
if [ -n "$endpoint" ]; then
|
||||||
|
endpoint_option="$endpoint"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$region_prompt" ]; then
|
||||||
|
read -p "$region_prompt" region
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "=== API 密钥信息 ==="
|
||||||
|
echo "在哪里找到密钥:"
|
||||||
|
case $provider_choice in
|
||||||
|
1) echo "- Cloudflare Dashboard → R2 → API Tokens" ;;
|
||||||
|
2) echo "- AWS Console → IAM → Users → Security credentials" ;;
|
||||||
|
3) echo "- Backblaze → My Account → App Keys" ;;
|
||||||
|
4) echo "- Google Cloud Console → Storage → Settings → Interoperability" ;;
|
||||||
|
5) echo "- 阿里云控制台 → 访问控制 → 用户管理" ;;
|
||||||
|
6) echo "- 腾讯云控制台 → 访问管理 → API密钥管理" ;;
|
||||||
|
7) echo "- 查看您的 S3 兼容服务商文档" ;;
|
||||||
|
esac
|
||||||
|
echo
|
||||||
|
|
||||||
|
read -p "Access Key ID: " access_key
|
||||||
|
read -s -p "Secret Access Key: " secret_key
|
||||||
|
echo
|
||||||
|
|
||||||
|
# 配置 rclone
|
||||||
|
log "配置 rclone 远程存储: $remote_name"
|
||||||
|
|
||||||
|
rclone config create \
|
||||||
|
"$remote_name" \
|
||||||
|
s3 \
|
||||||
|
provider "Other" \
|
||||||
|
env_auth false \
|
||||||
|
access_key_id "$access_key" \
|
||||||
|
secret_access_key "$secret_key" \
|
||||||
|
${endpoint:+"endpoint" "$endpoint"} \
|
||||||
|
${region:+"region" "$region"} \
|
||||||
|
acl private \
|
||||||
|
|| error "rclone 配置失败"
|
||||||
|
|
||||||
|
# 测试连接
|
||||||
|
log "测试连接..."
|
||||||
|
if rclone lsd "$remote_name:" >/dev/null 2>&1; then
|
||||||
|
log "连接测试成功!"
|
||||||
|
else
|
||||||
|
warn "连接测试失败,但配置已保存。请检查网络和密钥。"
|
||||||
|
fi
|
||||||
|
|
||||||
|
REMOTE_CONFIGURED=1
|
||||||
|
CONFIGURED_REMOTE="$remote_name"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 创建备份脚本
|
||||||
|
create_backup_scripts() {
|
||||||
|
log "创建备份脚本..."
|
||||||
|
|
||||||
|
local scripts_dir="$HOME/backup-scripts"
|
||||||
|
mkdir -p "$scripts_dir"
|
||||||
|
|
||||||
|
# 主备份脚本
|
||||||
|
cat > "$scripts_dir/backup-system.sh" << 'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
# BorgBackup 系统备份脚本
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# 配置
|
||||||
|
BACKUP_NAME="$(hostname)-system"
|
||||||
|
LOCAL_REPO="$HOME/borg-repo"
|
||||||
|
LOG_FILE="$HOME/backup-scripts/backup.log"
|
||||||
|
CONFIG_FILE="$HOME/backup-scripts/backup.conf"
|
||||||
|
|
||||||
|
# 加载配置
|
||||||
|
if [ -f "$CONFIG_FILE" ]; then
|
||||||
|
source "$CONFIG_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 颜色
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
log() { echo -e "${GREEN}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"; }
|
||||||
|
warn() { echo -e "${YELLOW}[WARN]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"; }
|
||||||
|
|
||||||
|
# 初始化仓库
|
||||||
|
init_repo() {
|
||||||
|
if [ ! -d "$LOCAL_REPO" ]; then
|
||||||
|
log "初始化 Borg 仓库..."
|
||||||
|
borg init --encryption=repokey-blake2 "$LOCAL_REPO" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 执行备份
|
||||||
|
create_backup() {
|
||||||
|
local archive_name="$BACKUP_NAME-$(date +%Y%m%d-%H%M%S)"
|
||||||
|
|
||||||
|
log "创建备份: $archive_name"
|
||||||
|
|
||||||
|
sudo borg create \
|
||||||
|
--compression lz4 \
|
||||||
|
--stats \
|
||||||
|
--progress \
|
||||||
|
--exclude-caches \
|
||||||
|
--exclude '/var/cache/*' \
|
||||||
|
--exclude '/var/tmp/*' \
|
||||||
|
--exclude '/tmp/*' \
|
||||||
|
--exclude '/proc/*' \
|
||||||
|
--exclude '/sys/*' \
|
||||||
|
--exclude '/dev/*' \
|
||||||
|
--exclude '/mnt/*' \
|
||||||
|
--exclude '/media/*' \
|
||||||
|
--exclude '/run/*' \
|
||||||
|
--exclude '/boot/*' \
|
||||||
|
--exclude '/lost+found' \
|
||||||
|
--exclude '*.pyc' \
|
||||||
|
--exclude '*.swap' \
|
||||||
|
--exclude '*.tmp' \
|
||||||
|
"$LOCAL_REPO::$archive_name" \
|
||||||
|
/ 2>&1 | tee -a "$LOG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 清理旧备份
|
||||||
|
prune_backups() {
|
||||||
|
log "清理旧备份..."
|
||||||
|
|
||||||
|
borg prune --list --stats \
|
||||||
|
--keep-daily=7 \
|
||||||
|
--keep-weekly=4 \
|
||||||
|
--keep-monthly=3 \
|
||||||
|
"$LOCAL_REPO" 2>&1 | tee -a "$LOG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 同步到远程
|
||||||
|
sync_to_remote() {
|
||||||
|
if [ -n "$REMOTE_CONFIG" ]; then
|
||||||
|
log "同步到远程存储: $REMOTE_CONFIG"
|
||||||
|
rclone sync "$LOCAL_REPO" "$REMOTE_CONFIG" --progress 2>&1 | tee -a "$LOG_FILE"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 主函数
|
||||||
|
main() {
|
||||||
|
log "=== 开始备份任务 ==="
|
||||||
|
|
||||||
|
init_repo
|
||||||
|
create_backup
|
||||||
|
prune_backups
|
||||||
|
sync_to_remote
|
||||||
|
|
||||||
|
log "=== 备份任务完成 ==="
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 如果配置了远程存储,更新配置文件
|
||||||
|
if [ "$REMOTE_CONFIGURED" = "1" ]; then
|
||||||
|
echo "REMOTE_CONFIG=\"$CONFIGURED_REMOTE:backups/$(hostname)\"" > "$scripts_dir/backup.conf"
|
||||||
|
fi
|
||||||
|
|
||||||
|
chmod +x "$scripts_dir/backup-system.sh"
|
||||||
|
log "备份脚本创建完成: $scripts_dir/backup-system.sh"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 显示总结信息
|
||||||
|
show_summary() {
|
||||||
|
echo
|
||||||
|
echo "=== 安装完成 ==="
|
||||||
|
echo -e "${GREEN}✓ BorgBackup 已安装${NC}"
|
||||||
|
echo -e "${GREEN}✓ rclone 已安装${NC}"
|
||||||
|
|
||||||
|
if [ "$REMOTE_CONFIGURED" = "1" ]; then
|
||||||
|
echo -e "${GREEN}✓ 远程存储已配置: $CONFIGURED_REMOTE${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}⚠ 未配置远程存储(仅本地备份)${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "=== 下一步操作 ==="
|
||||||
|
echo "1. 首次备份: ~/backup-scripts/backup-system.sh"
|
||||||
|
echo "2. 设置定时任务: crontab -e"
|
||||||
|
echo "3. 查看备份: borg list ~/borg-repo"
|
||||||
|
|
||||||
|
if [ "$REMOTE_CONFIGURED" = "1" ]; then
|
||||||
|
echo "4. 查看远程备份: rclone lsd $CONFIGURED_REMOTE:"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "=== 重要提醒 ==="
|
||||||
|
echo "• 备份 Borg 密钥: ~/borg-repo/keyfile"
|
||||||
|
echo "• 定期测试恢复功能"
|
||||||
|
echo "• 监控备份日志: ~/backup-scripts/backup.log"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 主函数
|
||||||
|
main() {
|
||||||
|
clear
|
||||||
|
echo -e "${BLUE}"
|
||||||
|
echo "╔══════════════════════════════════════╗"
|
||||||
|
echo "║ BorgBackup 智能安装脚本 ║"
|
||||||
|
echo "║ 适用于多平台系统备份 ║"
|
||||||
|
echo "╚══════════════════════════════════════╝"
|
||||||
|
echo -e "${NC}"
|
||||||
|
|
||||||
|
# 检查 root 权限
|
||||||
|
if [ "$EUID" -eq 0 ]; then
|
||||||
|
warn "不建议使用 root 用户运行此脚本"
|
||||||
|
read -p "是否继续? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
error "请使用普通用户运行"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 执行安装步骤
|
||||||
|
check_system
|
||||||
|
install_dependencies
|
||||||
|
install_borg
|
||||||
|
install_rclone
|
||||||
|
configure_rclone
|
||||||
|
create_backup_scripts
|
||||||
|
show_summary
|
||||||
|
}
|
||||||
|
|
||||||
|
# 运行主函数
|
||||||
|
main "$@"
|
||||||
154
CPU性能一键测试脚本
Normal file
154
CPU性能一键测试脚本
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 快速VPS性能测试脚本
|
||||||
|
# 用法: bash <(curl -sSL https://raw.githubusercontent.com/username/vpsbench/main/quick_bench.sh)
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[0;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
echo -e "${BLUE}=========================================${NC}"
|
||||||
|
echo -e "${BLUE} 快速性能测试${NC}"
|
||||||
|
echo -e "${BLUE}=========================================${NC}"
|
||||||
|
|
||||||
|
# 获取基础信息
|
||||||
|
CPU_CORES=$(nproc)
|
||||||
|
CPU_MODEL=$(grep "model name" /proc/cpuinfo | head -1 | cut -d: -f2 | sed 's/^ *//' | head -c 40)
|
||||||
|
MEM_TOTAL=$(free -m | grep Mem | awk '{print $2}')
|
||||||
|
|
||||||
|
echo "CPU: $CPU_MODEL"
|
||||||
|
echo "核心: $CPU_CORES | 内存: ${MEM_TOTAL}MB"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 测试1: 单核计算速度 (3秒超时)
|
||||||
|
echo -e "${YELLOW}1. 单核性能测试...${NC}"
|
||||||
|
timeout 3 bash -c '
|
||||||
|
START_TIME=$(date +%s.%N)
|
||||||
|
for i in {1..100000}; do
|
||||||
|
echo "test$i" | md5sum > /dev/null 2>&1
|
||||||
|
done
|
||||||
|
END_TIME=$(date +%s.%N)
|
||||||
|
echo "scale=2; $END_TIME - $START_TIME" | bc
|
||||||
|
' 2>/dev/null || echo "3.00+"
|
||||||
|
SINGLE_TIME=$?
|
||||||
|
|
||||||
|
# 测试2: 多核并发能力 (5秒超时)
|
||||||
|
echo -e "${YELLOW}2. 多核性能测试...${NC}"
|
||||||
|
START_TIME=$(date +%s.%N)
|
||||||
|
for i in $(seq 1 $CPU_CORES); do
|
||||||
|
(timeout 5 dd if=/dev/zero bs=1M count=10 2>/dev/null | md5sum > /dev/null 2>&1) &
|
||||||
|
done
|
||||||
|
wait 2>/dev/null
|
||||||
|
END_TIME=$(date +%s.%N)
|
||||||
|
MULTI_TIME=$(echo "scale=2; $END_TIME - $START_TIME" | bc)
|
||||||
|
|
||||||
|
# 测试3: 内存速度 (3秒超时)
|
||||||
|
echo -e "${YELLOW}3. 内存性能测试...${NC}"
|
||||||
|
START_TIME=$(date +%s.%N)
|
||||||
|
timeout 3 dd if=/dev/zero of=/dev/null bs=1M count=100 2>&1 | grep "copied" | awk '{print $8, $9}'
|
||||||
|
MEM_SPEED=$?
|
||||||
|
if [ $MEM_SPEED -ne 0 ]; then
|
||||||
|
echo ">30秒/MB"
|
||||||
|
MEM_SCORE="慢"
|
||||||
|
else
|
||||||
|
MEM_SCORE="正常"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 测试4: 磁盘IO速度 (如果有写入权限)
|
||||||
|
echo -e "${YELLOW}4. 磁盘IO测试...${NC}"
|
||||||
|
if [ -w /tmp ]; then
|
||||||
|
START_TIME=$(date +%s.%N)
|
||||||
|
timeout 5 dd if=/dev/zero of=/tmp/test_io.bin bs=1M count=50 oflag=direct 2>&1 | grep "copied" | awk '{print $8, $9}'
|
||||||
|
IO_SPEED=$?
|
||||||
|
rm -f /tmp/test_io.bin 2>/dev/null
|
||||||
|
if [ $IO_SPEED -ne 0 ]; then
|
||||||
|
echo "IO受限"
|
||||||
|
IO_SCORE="慢"
|
||||||
|
else
|
||||||
|
IO_SCORE="正常"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "无写入权限"
|
||||||
|
IO_SCORE="未知"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 测试5: 系统响应速度
|
||||||
|
echo -e "${YELLOW}5. 系统响应测试...${NC}"
|
||||||
|
START_TIME=$(date +%s.%N)
|
||||||
|
for i in {1..100}; do
|
||||||
|
ls / > /dev/null 2>&1
|
||||||
|
done
|
||||||
|
END_TIME=$(date +%s.%N)
|
||||||
|
RESPONSE_TIME=$(echo "scale=3; ($END_TIME - $START_TIME) * 1000" | bc)
|
||||||
|
|
||||||
|
# 性能评分
|
||||||
|
echo -e "\n${BLUE}=========================================${NC}"
|
||||||
|
echo -e "${BLUE} 性能评分${NC}"
|
||||||
|
echo -e "${BLUE}=========================================${NC}"
|
||||||
|
|
||||||
|
# 单核评分
|
||||||
|
if (( $(echo "$SINGLE_TIME < 1.0" | bc -l 2>/dev/null) )); then
|
||||||
|
SINGLE_SCORE="${GREEN}优秀${NC}"
|
||||||
|
elif (( $(echo "$SINGLE_TIME < 2.0" | bc -l 2>/dev/null) )); then
|
||||||
|
SINGLE_SCORE="${YELLOW}良好${NC}"
|
||||||
|
else
|
||||||
|
SINGLE_SCORE="${RED}一般${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 多核评分
|
||||||
|
if (( $(echo "$MULTI_TIME < 2.0" | bc -l 2>/dev/null) )); then
|
||||||
|
MULTI_SCORE="${GREEN}优秀${NC}"
|
||||||
|
elif (( $(echo "$MULTI_TIME < 5.0" | bc -l 2>/dev/null) )); then
|
||||||
|
MULTI_SCORE="${YELLOW}良好${NC}"
|
||||||
|
else
|
||||||
|
MULTI_SCORE="${RED}一般${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 响应评分
|
||||||
|
if (( $(echo "$RESPONSE_TIME < 50" | bc -l 2>/dev/null) )); then
|
||||||
|
RESPONSE_SCORE="${GREEN}优秀${NC}"
|
||||||
|
elif (( $(echo "$RESPONSE_TIME < 100" | bc -l 2>/dev/null) )); then
|
||||||
|
RESPONSE_SCORE="${YELLOW}良好${NC}"
|
||||||
|
else
|
||||||
|
RESPONSE_SCORE="${RED}一般${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "单核性能: $SINGLE_SCORE"
|
||||||
|
echo -e "多核性能: $MULTI_SCORE"
|
||||||
|
echo -e "内存性能: $MEM_SCORE"
|
||||||
|
echo -e "磁盘IO: $IO_SCORE"
|
||||||
|
echo -e "系统响应: ${RESPONSE_TIME}ms ($RESPONSE_SCORE)"
|
||||||
|
|
||||||
|
# 总体评价
|
||||||
|
echo -e "\n${BLUE}=========================================${NC}"
|
||||||
|
if [ "$SINGLE_SCORE" = "${GREEN}优秀${NC}" ] && [ "$MULTI_SCORE" = "${GREEN}优秀${NC}" ]; then
|
||||||
|
echo -e "${GREEN}总体评价: 性能强劲${NC}"
|
||||||
|
elif [ "$SINGLE_SCORE" != "${RED}一般${NC}" ] && [ "$MULTI_SCORE" != "${RED}一般${NC}" ]; then
|
||||||
|
echo -e "${YELLOW}总体评价: 性能良好${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}总体评价: 性能一般${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${BLUE}=========================================${NC}"
|
||||||
|
|
||||||
|
# 保存简要结果
|
||||||
|
RESULTS_FILE="/tmp/vps_quick_$(date +%Y%m%d_%H%M%S).txt"
|
||||||
|
cat > $RESULTS_FILE << EOF
|
||||||
|
主机: $(hostname)
|
||||||
|
CPU: $CPU_CORES核心 - $(echo "$CPU_MODEL" | cut -c1-30)
|
||||||
|
测试时间: $(date)
|
||||||
|
|
||||||
|
性能概况:
|
||||||
|
- 单核性能: $(echo $SINGLE_SCORE | sed 's/\\033\[[0-9;]*m//g')
|
||||||
|
- 多核性能: $(echo $MULTI_SCORE | sed 's/\\033\[[0-9;]*m//g')
|
||||||
|
- 内存性能: $MEM_SCORE
|
||||||
|
- 磁盘IO: $IO_SCORE
|
||||||
|
- 系统响应: ${RESPONSE_TIME}ms
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo -e "结果保存到: ${GREEN}$RESULTS_FILE${NC}"
|
||||||
|
echo -e "\n${YELLOW}提示:${NC} 在不同VPS上运行后对比评价即可"
|
||||||
89
DNS
Normal file
89
DNS
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
#!/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'
|
||||||
|
|
||||||
|
echo -e "${PURPLE}"
|
||||||
|
echo "=================================================="
|
||||||
|
echo " 🌈 智能DNS推荐系统"
|
||||||
|
echo "=================================================="
|
||||||
|
echo -e "${NC}"
|
||||||
|
|
||||||
|
# 测试并推荐最佳DNS
|
||||||
|
test_and_recommend() {
|
||||||
|
declare -A dns_servers=(
|
||||||
|
["119.29.29.29"]="腾讯DNS"
|
||||||
|
["223.5.5.5"]="阿里DNS"
|
||||||
|
["114.114.114.114"]="114DNS"
|
||||||
|
["8.8.8.8"]="GoogleDNS"
|
||||||
|
["1.1.1.1"]="Cloudflare"
|
||||||
|
)
|
||||||
|
|
||||||
|
declare -A results
|
||||||
|
|
||||||
|
echo -e "${BLUE}🧪 测试各DNS性能...${NC}"
|
||||||
|
|
||||||
|
for dns_ip in "${!dns_servers[@]}"; do
|
||||||
|
total_time=0
|
||||||
|
success_count=0
|
||||||
|
test_domains=("baidu.com" "qq.com" "taobao.com")
|
||||||
|
|
||||||
|
for domain in "${test_domains[@]}"; do
|
||||||
|
start_time=$(date +%s%N)
|
||||||
|
nslookup $domain $dns_ip >/dev/null 2>&1
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
end_time=$(date +%s%N)
|
||||||
|
time_ms=$(( (end_time - start_time) / 1000000 ))
|
||||||
|
total_time=$(( total_time + time_ms ))
|
||||||
|
success_count=$(( success_count + 1 ))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ $success_count -gt 0 ]; then
|
||||||
|
avg_time=$(( total_time / success_count ))
|
||||||
|
results[$dns_ip]=$avg_time
|
||||||
|
echo -e " ${dns_servers[$dns_ip]} ($dns_ip): ${avg_time}ms"
|
||||||
|
else
|
||||||
|
echo -e " ${RED}${dns_servers[$dns_ip]} ($dns_ip): 测试失败${NC}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# 找出最快的DNS
|
||||||
|
fastest_ip=""
|
||||||
|
fastest_time=999999
|
||||||
|
|
||||||
|
for ip in "${!results[@]}"; do
|
||||||
|
if [ ${results[$ip]} -lt $fastest_time ]; then
|
||||||
|
fastest_time=${results[$ip]}
|
||||||
|
fastest_ip=$ip
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -e "\n${GREEN}🎯 推荐使用: ${dns_servers[$fastest_ip]} ($fastest_ip)${NC}"
|
||||||
|
echo -e "${GREEN}📊 平均解析时间: ${fastest_time}ms${NC}"
|
||||||
|
|
||||||
|
# 设置推荐DNS
|
||||||
|
echo -e "\n${BLUE}🔧 是否设置为推荐DNS?${NC}"
|
||||||
|
read -p "输入 y 确认设置: " confirm
|
||||||
|
if [ "$confirm" = "y" ]; then
|
||||||
|
echo "nameserver $fastest_ip" > /etc/resolv.conf
|
||||||
|
echo "nameserver 223.5.5.5" >> /etc/resolv.conf # 备用
|
||||||
|
echo -e "${GREEN}✅ 已设置为 ${dns_servers[$fastest_ip]}${NC}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
test_and_recommend
|
||||||
|
|
||||||
|
echo -e "\n${PURPLE}==================================================${NC}"
|
||||||
|
echo -e "${CYAN}💡 重要提醒:${NC}"
|
||||||
|
echo -e "${YELLOW}• DNS只影响域名解析速度${NC}"
|
||||||
|
echo -e "${YELLOW}• 不影响已经建立连接的网络延迟${NC}"
|
||||||
|
echo -e "${YELLOW}• 主要提升: 网页第一次打开速度${NC}"
|
||||||
|
echo -e "${YELLOW}• 不影响: 视频缓冲、游戏延迟、下载速度${NC}"
|
||||||
|
echo -e "${PURPLE}==================================================${NC}"
|
||||||
60
Debian 12 升级到 6.1.0-40
Normal file
60
Debian 12 升级到 6.1.0-40
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
cat > upgrade_kernel.sh << 'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Debian 12 升级到 6.1.0-40-cloud-amd64 内核一键脚本
|
||||||
|
echo "=== Debian 12 内核升级脚本 ==="
|
||||||
|
echo "目标内核: 6.1.0-40-cloud-amd64"
|
||||||
|
|
||||||
|
# 检查是否为 Debian 系统
|
||||||
|
if ! grep -q "Debian" /etc/os-release; then
|
||||||
|
echo "错误: 此脚本仅适用于 Debian 系统"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 显示当前内核版本
|
||||||
|
echo "当前内核版本: $(uname -r)"
|
||||||
|
|
||||||
|
# 更新软件包列表
|
||||||
|
echo "正在更新软件包列表..."
|
||||||
|
sudo apt update -y
|
||||||
|
|
||||||
|
# 检查目标内核是否可用
|
||||||
|
echo "检查内核包可用性..."
|
||||||
|
if apt list linux-image-6.1.0-40-cloud-amd64 2>/dev/null | grep -q "6.1.0-40"; then
|
||||||
|
echo "找到目标内核包,开始安装..."
|
||||||
|
|
||||||
|
# 安装特定内核版本
|
||||||
|
sudo apt install -y \
|
||||||
|
linux-image-6.1.0-40-cloud-amd64 \
|
||||||
|
linux-headers-6.1.0-40-cloud-amd64
|
||||||
|
|
||||||
|
# 检查安装是否成功
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "内核安装成功!"
|
||||||
|
else
|
||||||
|
echo "内核安装失败,尝试替代方案..."
|
||||||
|
# 尝试安装 cloud 内核元包
|
||||||
|
sudo apt install -y linux-image-cloud-amd64 linux-headers-cloud-amd64
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "特定版本不可用,安装最新的 cloud 内核..."
|
||||||
|
sudo apt install -y linux-image-cloud-amd64 linux-headers-cloud-amd64
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 更新 GRUB 配置
|
||||||
|
echo "更新 GRUB 引导配置..."
|
||||||
|
sudo update-grub
|
||||||
|
|
||||||
|
# 显示安装的内核
|
||||||
|
echo "已安装的内核版本:"
|
||||||
|
dpkg -l | grep linux-image | awk '{print $2 " " $3}'
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== 安装完成 ==="
|
||||||
|
echo "请重启系统以使用新内核: sudo reboot"
|
||||||
|
echo "重启后使用 'uname -r' 验证新内核版本"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 给脚本执行权限并运行
|
||||||
|
chmod +x upgrade_kernel.sh
|
||||||
|
./upgrade_kernel.sh
|
||||||
330
Docker 24.0.5
Normal file
330
Docker 24.0.5
Normal file
@@ -0,0 +1,330 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
# 输出颜色信息
|
||||||
|
log() {
|
||||||
|
echo -e "${GREEN}[INFO]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
warn() {
|
||||||
|
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
echo -e "${RED}[ERROR]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
info() {
|
||||||
|
echo -e "${BLUE}[INFO]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检测系统IP
|
||||||
|
detect_ip() {
|
||||||
|
log "正在检测服务器IP地址..."
|
||||||
|
|
||||||
|
# 尝试多种方法获取公网IP
|
||||||
|
PUBLIC_IP=$(curl -s --connect-timeout 5 http://ipinfo.io/ip || \
|
||||||
|
curl -s --connect-timeout 5 http://ifconfig.me || \
|
||||||
|
curl -s --connect-timeout 5 http://api.ipify.org || \
|
||||||
|
echo "unknown")
|
||||||
|
|
||||||
|
# 获取内网IP
|
||||||
|
LOCAL_IP=$(ip route get 1 | awk '{print $7; exit}' 2>/dev/null || \
|
||||||
|
hostname -I | awk '{print $1}' 2>/dev/null || \
|
||||||
|
echo "unknown")
|
||||||
|
|
||||||
|
# 显示检测结果
|
||||||
|
if [ "$PUBLIC_IP" != "unknown" ]; then
|
||||||
|
info "检测到公网IP: $PUBLIC_IP"
|
||||||
|
SERVER_IP="$PUBLIC_IP"
|
||||||
|
else
|
||||||
|
warn "无法获取公网IP,使用内网IP: $LOCAL_IP"
|
||||||
|
SERVER_IP="$LOCAL_IP"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 生成密钥
|
||||||
|
generate_keys() {
|
||||||
|
log "正在生成RustDesk密钥对..."
|
||||||
|
|
||||||
|
# 创建目录
|
||||||
|
mkdir -p {hbbs,hbbr,data}
|
||||||
|
|
||||||
|
# 检查是否已有密钥
|
||||||
|
if [ -f "data/key_pair" ]; then
|
||||||
|
warn "检测到已存在的密钥对,使用现有密钥"
|
||||||
|
# 从保存的密钥对中恢复
|
||||||
|
cat data/key_pair | grep "私钥" | cut -d' ' -f2 | base64 -d > data/id_ed25519
|
||||||
|
cat data/key_pair | grep "公钥" | cut -d' ' -f2 | base64 -d > data/id_ed25519.pub
|
||||||
|
else
|
||||||
|
# 生成新密钥
|
||||||
|
openssl genrsa -out data/id_ed25519 2048 2>/dev/null
|
||||||
|
openssl rsa -in data/id_ed25519 -pubout -out data/id_ed25519.pub 2>/dev/null
|
||||||
|
|
||||||
|
# 保存密钥对信息
|
||||||
|
echo "私钥: $(cat data/id_ed25519 | base64 -w 0)" > data/key_pair
|
||||||
|
echo "公钥: $(cat data/id_ed25519.pub | base64 -w 0)" >> data/key_pair
|
||||||
|
log "新的密钥对生成完成"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 复制密钥到服务目录
|
||||||
|
cp data/id_ed25519* hbbs/
|
||||||
|
cp data/id_ed25519* hbbr/
|
||||||
|
|
||||||
|
# 获取公钥用于显示
|
||||||
|
PUBLIC_KEY=$(cat data/id_ed25519.pub | base64 -w 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
# 生成Docker Compose配置
|
||||||
|
generate_docker_compose() {
|
||||||
|
log "生成Docker Compose配置文件..."
|
||||||
|
|
||||||
|
cat > docker-compose.yml << EOF
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
hbbs:
|
||||||
|
image: lejianwen/rustdesk-server-s6
|
||||||
|
container_name: rustdesk-hbbs
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "21115:21115"
|
||||||
|
- "21116:21116"
|
||||||
|
- "21116:21116/udp"
|
||||||
|
- "21117:21117"
|
||||||
|
- "21118:21118"
|
||||||
|
- "21119:21119"
|
||||||
|
volumes:
|
||||||
|
- ./hbbs:/root
|
||||||
|
- ./data:/data
|
||||||
|
command: hbbs -r ${SERVER_IP}:21117
|
||||||
|
networks:
|
||||||
|
- rustdesk-net
|
||||||
|
|
||||||
|
hbbr:
|
||||||
|
image: lejianwen/rustdesk-server-s6
|
||||||
|
container_name: rustdesk-hbbr
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "21117:21117"
|
||||||
|
- "21118:21118"
|
||||||
|
- "21119:21119"
|
||||||
|
volumes:
|
||||||
|
- ./hbbr:/root
|
||||||
|
- ./data:/data
|
||||||
|
command: hbbr
|
||||||
|
networks:
|
||||||
|
- rustdesk-net
|
||||||
|
|
||||||
|
networks:
|
||||||
|
rustdesk-net:
|
||||||
|
driver: bridge
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# 生成管理脚本
|
||||||
|
generate_management_script() {
|
||||||
|
log "生成管理脚本..."
|
||||||
|
|
||||||
|
cat > manage.sh << 'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
# 管理功能
|
||||||
|
case "$1" in
|
||||||
|
"start")
|
||||||
|
docker-compose up -d
|
||||||
|
echo -e "${GREEN}服务已启动${NC}"
|
||||||
|
;;
|
||||||
|
"stop")
|
||||||
|
docker-compose down
|
||||||
|
echo -e "${YELLOW}服务已停止${NC}"
|
||||||
|
;;
|
||||||
|
"restart")
|
||||||
|
docker-compose restart
|
||||||
|
echo -e "${GREEN}服务已重启${NC}"
|
||||||
|
;;
|
||||||
|
"status")
|
||||||
|
docker-compose ps
|
||||||
|
;;
|
||||||
|
"logs")
|
||||||
|
docker-compose logs -f
|
||||||
|
;;
|
||||||
|
"update")
|
||||||
|
docker-compose pull
|
||||||
|
docker-compose down
|
||||||
|
docker-compose up -d
|
||||||
|
echo -e "${GREEN}服务已更新${NC}"
|
||||||
|
;;
|
||||||
|
"backup")
|
||||||
|
BACKUP_DIR="backup/$(date +%Y%m%d_%H%M%S)"
|
||||||
|
mkdir -p $BACKUP_DIR
|
||||||
|
cp -r data $BACKUP_DIR/
|
||||||
|
echo -e "${GREEN}密钥已备份到: $BACKUP_DIR${NC}"
|
||||||
|
;;
|
||||||
|
"key-info")
|
||||||
|
if [ -f "data/key_pair" ]; then
|
||||||
|
echo -e "${BLUE}=== 密钥信息 ===${NC}"
|
||||||
|
echo "公钥 (Base64): $(cat data/key_pair | grep '公钥' | cut -d' ' -f2)"
|
||||||
|
echo -e "${BLUE}===============${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}没有找到密钥对${NC}"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"export-key")
|
||||||
|
if [ -f "data/key_pair" ]; then
|
||||||
|
echo -e "${YELLOW}=== 导出密钥 ===${NC}"
|
||||||
|
cat data/key_pair
|
||||||
|
echo -e "${YELLOW}===============${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}没有找到密钥对${NC}"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"import-key")
|
||||||
|
if [ -z "$2" ]; then
|
||||||
|
echo -e "${RED}用法: ./manage.sh import-key <base64_private_key>${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$2" | base64 -d > data/id_ed25519
|
||||||
|
openssl rsa -in data/id_ed25519 -pubout -out data/id_ed25519.pub 2>/dev/null
|
||||||
|
|
||||||
|
echo "私钥: $(cat data/id_ed25519 | base64 -w 0)" > data/key_pair
|
||||||
|
echo "公钥: $(cat data/id_ed25519.pub | base64 -w 0)" >> data/key_pair
|
||||||
|
|
||||||
|
cp data/id_ed25519* hbbs/
|
||||||
|
cp data/id_ed25519* hbbr/
|
||||||
|
|
||||||
|
docker-compose restart
|
||||||
|
echo -e "${GREEN}密钥已导入并应用${NC}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo -e "${BLUE}RustDesk 服务管理脚本${NC}"
|
||||||
|
echo "用法: $0 [命令]"
|
||||||
|
echo ""
|
||||||
|
echo "命令:"
|
||||||
|
echo " start 启动服务"
|
||||||
|
echo " stop 停止服务"
|
||||||
|
echo " restart 重启服务"
|
||||||
|
echo " status 查看状态"
|
||||||
|
echo " logs 查看日志"
|
||||||
|
echo " update 更新服务"
|
||||||
|
echo " backup 备份密钥"
|
||||||
|
echo " key-info 查看密钥信息"
|
||||||
|
echo " export-key 导出密钥"
|
||||||
|
echo " import-key 导入密钥 (需要Base64格式私钥)"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod +x manage.sh
|
||||||
|
}
|
||||||
|
|
||||||
|
# 显示部署信息
|
||||||
|
show_deployment_info() {
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}===============================================${NC}"
|
||||||
|
echo -e "${GREEN} RustDesk Server 部署完成! ${NC}"
|
||||||
|
echo -e "${GREEN}===============================================${NC}"
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}服务器信息:${NC}"
|
||||||
|
echo " ID 服务器: $SERVER_IP"
|
||||||
|
echo " 中继服务器: $SERVER_IP:21117"
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}密钥信息:${NC}"
|
||||||
|
echo " 公钥 (Base64): $(cat data/key_pair | grep '公钥' | cut -d' ' -f2)"
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}端口信息:${NC}"
|
||||||
|
echo " HBBS 端口: 21115-21119"
|
||||||
|
echo " HBBR 端口: 21117-21119"
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}管理命令:${NC}"
|
||||||
|
echo " 启动服务: ./manage.sh start"
|
||||||
|
echo " 停止服务: ./manage.sh stop"
|
||||||
|
echo " 查看状态: ./manage.sh status"
|
||||||
|
echo " 查看日志: ./manage.sh logs"
|
||||||
|
echo " 备份密钥: ./manage.sh backup"
|
||||||
|
echo " 导出密钥: ./manage.sh export-key"
|
||||||
|
echo ""
|
||||||
|
echo -e "${YELLOW}重要提示:${NC}"
|
||||||
|
echo " 1. 请确保防火墙开放端口 21115-21119"
|
||||||
|
echo " 2. 备份 data/ 目录下的密钥文件"
|
||||||
|
echo " 3. 在其他服务器部署时使用相同密钥保证客户端兼容"
|
||||||
|
echo -e "${GREEN}===============================================${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查防火墙
|
||||||
|
check_firewall() {
|
||||||
|
log "检查防火墙状态..."
|
||||||
|
|
||||||
|
# 检查 ufw
|
||||||
|
if command -v ufw >/dev/null 2>&1 && ufw status | grep -q "active"; then
|
||||||
|
warn "检测到 ufw 防火墙,请确保已开放端口 21115-21119"
|
||||||
|
echo "运行以下命令开放端口:"
|
||||||
|
echo " sudo ufw allow 21115:21119/tcp"
|
||||||
|
echo " sudo ufw allow 21116/udp"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查 firewalld
|
||||||
|
if command -v firewall-cmd >/dev/null 2>&1 && firewall-cmd --state >/dev/null 2>&1; then
|
||||||
|
warn "检测到 firewalld 防火墙,请确保已开放端口 21115-21119"
|
||||||
|
echo "运行以下命令开放端口:"
|
||||||
|
echo " sudo firewall-cmd --permanent --add-port=21115-21119/tcp"
|
||||||
|
echo " sudo firewall-cmd --permanent --add-port=21116/udp"
|
||||||
|
echo " sudo firewall-cmd --reload"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查 iptables
|
||||||
|
if command -v iptables >/dev/null 2>&1; then
|
||||||
|
warn "请检查 iptables 规则,确保端口 21115-21119 已开放"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 主部署流程
|
||||||
|
main() {
|
||||||
|
echo -e "${BLUE}===============================================${NC}"
|
||||||
|
echo -e "${BLUE} RustDesk Server 一键部署脚本 ${NC}"
|
||||||
|
echo -e "${BLUE}===============================================${NC}"
|
||||||
|
|
||||||
|
# 检测IP
|
||||||
|
detect_ip
|
||||||
|
|
||||||
|
# 生成密钥
|
||||||
|
generate_keys
|
||||||
|
|
||||||
|
# 生成Docker配置
|
||||||
|
generate_docker_compose
|
||||||
|
|
||||||
|
# 生成管理脚本
|
||||||
|
generate_management_script
|
||||||
|
|
||||||
|
# 启动服务
|
||||||
|
log "启动RustDesk服务..."
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
# 显示部署信息
|
||||||
|
show_deployment_info
|
||||||
|
|
||||||
|
# 检查防火墙
|
||||||
|
check_firewall
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
log "部署完成!可以使用 ./manage.sh 管理服务"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 运行主函数
|
||||||
|
main
|
||||||
88
Docker Compose 自动安装脚本
Normal file
88
Docker Compose 自动安装脚本
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Docker Compose 自动安装脚本
|
||||||
|
# 适用于大多数Linux发行版
|
||||||
|
|
||||||
|
set -e # 遇到错误立即退出
|
||||||
|
|
||||||
|
echo "=== Docker Compose 安装脚本 ==="
|
||||||
|
|
||||||
|
# 检查系统架构
|
||||||
|
ARCH=$(uname -m)
|
||||||
|
if [ "$ARCH" != "x86_64" ] && [ "$ARCH" != "aarch64" ]; then
|
||||||
|
echo "❌ 不支持的架构: $ARCH"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查是否已安装Docker
|
||||||
|
if ! command -v docker &> /dev/null; then
|
||||||
|
echo "❌ Docker 未安装,请先安装Docker"
|
||||||
|
echo "运行以下命令安装Docker:"
|
||||||
|
echo "curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ Docker 已安装"
|
||||||
|
|
||||||
|
# 检查当前用户是否有Docker权限
|
||||||
|
if ! docker ps &> /dev/null; then
|
||||||
|
echo "⚠️ 当前用户无Docker权限,尝试添加到docker组..."
|
||||||
|
sudo usermod -aG docker $USER
|
||||||
|
echo "📝 请重新登录或运行 'newgrp docker' 使权限生效"
|
||||||
|
echo "📝 然后重新运行此脚本"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 获取最新版本
|
||||||
|
get_latest_version() {
|
||||||
|
curl -s https://api.github.com/repos/docker/compose/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/'
|
||||||
|
}
|
||||||
|
|
||||||
|
# 安装Docker Compose
|
||||||
|
install_docker_compose() {
|
||||||
|
echo "📥 正在安装 Docker Compose..."
|
||||||
|
|
||||||
|
# 获取最新版本
|
||||||
|
VERSION=$(get_latest_version)
|
||||||
|
echo "🔍 最新版本: $VERSION"
|
||||||
|
|
||||||
|
# 下载并安装
|
||||||
|
sudo curl -L "https://github.com/docker/compose/releases/download/${VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||||
|
|
||||||
|
# 赋予执行权限
|
||||||
|
sudo chmod +x /usr/local/bin/docker-compose
|
||||||
|
|
||||||
|
# 创建符号链接(兼容旧版本)
|
||||||
|
if [ ! -f /usr/bin/docker-compose ]; then
|
||||||
|
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 主安装流程
|
||||||
|
main() {
|
||||||
|
# 如果已安装,询问是否重新安装
|
||||||
|
if command -v docker-compose &> /dev/null; then
|
||||||
|
CURRENT_VERSION=$(docker-compose --version 2>/dev/null || echo "未知版本")
|
||||||
|
echo "ℹ️ Docker Compose 已安装: $CURRENT_VERSION"
|
||||||
|
read -p "是否重新安装?(y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ ! $REply =~ ^[Yy]$ ]]; then
|
||||||
|
echo "✅ 安装已取消"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
install_docker_compose
|
||||||
|
|
||||||
|
# 验证安装
|
||||||
|
if docker-compose --version &> /dev/null; then
|
||||||
|
echo "✅ Docker Compose 安装成功!"
|
||||||
|
echo "📋 版本信息: $(docker-compose --version)"
|
||||||
|
else
|
||||||
|
echo "❌ 安装失败,请检查网络连接或手动安装"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 执行主函数
|
||||||
|
main
|
||||||
617
Docker 加速
Normal file
617
Docker 加速
Normal file
@@ -0,0 +1,617 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Docker镜像源配置脚本
|
||||||
|
# 描述: 配置Docker使用不同的镜像源,支持私有仓库(可选认证)和公共镜像源
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
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
|
||||||
|
|
||||||
|
# 默认私有仓库配置(用户可自定义)
|
||||||
|
DEFAULT_PRIVATE_REGISTRY="github.vps7k7k.xyz"
|
||||||
|
DEFAULT_PRIVATE_MIRROR="https://github.vps7k7k.xyz"
|
||||||
|
|
||||||
|
# 备用镜像源
|
||||||
|
ALIYUN_MIRROR="https://registry.cn-hangzhou.aliyuncs.com"
|
||||||
|
DOCKER_HUB_MIRROR="https://hub-mirror.c.163.com"
|
||||||
|
USTC_MIRROR="https://docker.mirrors.ustc.edu.cn"
|
||||||
|
TENCENT_MIRROR="https://mirror.ccs.tencentyun.com"
|
||||||
|
|
||||||
|
# 打印彩色信息
|
||||||
|
print_info() {
|
||||||
|
echo -e "${GREEN}[INFO]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_warning() {
|
||||||
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_error() {
|
||||||
|
echo -e "${RED}[ERROR]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_step() {
|
||||||
|
echo -e "${BLUE}[STEP]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_choice() {
|
||||||
|
echo -e "${PURPLE}[CHOICE]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_config() {
|
||||||
|
echo -e "${CYAN}[CONFIG]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查Docker是否安装
|
||||||
|
check_docker() {
|
||||||
|
if ! command -v docker &> /dev/null; then
|
||||||
|
print_error "Docker 未安装,请先安装Docker"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
print_info "Docker 已安装,版本: $(docker --version | cut -d' ' -f3 | cut -d',' -f1)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 获取私有仓库配置
|
||||||
|
get_private_registry_config() {
|
||||||
|
echo
|
||||||
|
print_step "配置私有仓库"
|
||||||
|
|
||||||
|
# 询问是否使用私有仓库
|
||||||
|
read -p "是否使用私有仓库?(y/N): " use_private
|
||||||
|
if [[ ! $use_private =~ ^[Yy]$ ]]; then
|
||||||
|
PRIVATE_REGISTRY=""
|
||||||
|
PRIVATE_MIRROR=""
|
||||||
|
NEED_AUTH="no"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 输入私有仓库域名
|
||||||
|
read -p "请输入私有仓库域名/地址 [默认: $DEFAULT_PRIVATE_REGISTRY]: " registry_input
|
||||||
|
if [ -z "$registry_input" ]; then
|
||||||
|
PRIVATE_REGISTRY="$DEFAULT_PRIVATE_REGISTRY"
|
||||||
|
PRIVATE_MIRROR="$DEFAULT_PRIVATE_MIRROR"
|
||||||
|
else
|
||||||
|
PRIVATE_REGISTRY="$registry_input"
|
||||||
|
# 自动构建镜像URL(添加https前缀,如果不是完整URL)
|
||||||
|
if [[ "$registry_input" =~ ^https?:// ]]; then
|
||||||
|
PRIVATE_MIRROR="$registry_input"
|
||||||
|
else
|
||||||
|
PRIVATE_MIRROR="https://$registry_input"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_info "私有仓库地址: $PRIVATE_REGISTRY"
|
||||||
|
print_info "镜像地址: $PRIVATE_MIRROR"
|
||||||
|
|
||||||
|
# 询问是否需要认证
|
||||||
|
read -p "私有仓库是否需要认证登录?(y/N): " need_auth
|
||||||
|
if [[ $need_auth =~ ^[Yy]$ ]]; then
|
||||||
|
NEED_AUTH="yes"
|
||||||
|
get_private_credentials
|
||||||
|
else
|
||||||
|
NEED_AUTH="no"
|
||||||
|
print_info "私有仓库无需认证"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 交互式输入私有仓库账号密码
|
||||||
|
get_private_credentials() {
|
||||||
|
print_step "请输入私有仓库的认证信息"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
read -p "请输入用户名: " PRIVATE_USERNAME
|
||||||
|
if [ -n "$PRIVATE_USERNAME" ]; then
|
||||||
|
break
|
||||||
|
else
|
||||||
|
print_error "用户名不能为空,请重新输入"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
read -s -p "请输入密码: " PRIVATE_PASSWORD
|
||||||
|
echo
|
||||||
|
if [ -n "$PRIVATE_PASSWORD" ]; then
|
||||||
|
break
|
||||||
|
else
|
||||||
|
print_error "密码不能为空,请重新输入"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# 确认密码
|
||||||
|
while true; do
|
||||||
|
read -s -p "请再次输入密码确认: " password_confirm
|
||||||
|
echo
|
||||||
|
if [ "$PRIVATE_PASSWORD" = "$password_confirm" ]; then
|
||||||
|
break
|
||||||
|
else
|
||||||
|
print_error "两次输入的密码不一致,请重新输入"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# 测试私有仓库登录
|
||||||
|
test_private_login() {
|
||||||
|
if [ "$NEED_AUTH" != "yes" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_step "测试登录私有仓库..."
|
||||||
|
|
||||||
|
if echo "$PRIVATE_PASSWORD" | docker login $PRIVATE_REGISTRY -u "$PRIVATE_USERNAME" --password-stdin; then
|
||||||
|
print_info "私有仓库登录测试成功!"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
print_error "私有仓库登录测试失败"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 显示镜像源选择菜单
|
||||||
|
show_mirror_menu() {
|
||||||
|
echo
|
||||||
|
print_step "请选择要使用的Docker镜像源配置:"
|
||||||
|
echo "=========================================="
|
||||||
|
|
||||||
|
if [ -n "$PRIVATE_REGISTRY" ]; then
|
||||||
|
print_choice "1. 私有仓库为主 + 多个备用源(推荐)"
|
||||||
|
echo " - 主源: ${PRIVATE_REGISTRY}"
|
||||||
|
echo " - 备源: 阿里云、网易、中科大、腾讯云"
|
||||||
|
echo " - Docker自动选择最快可用源"
|
||||||
|
print_choice "2. 仅私有仓库"
|
||||||
|
echo " - 只使用 ${PRIVATE_REGISTRY}"
|
||||||
|
echo " - 访问速度最快"
|
||||||
|
print_choice "3. 私有仓库 + 公共镜像源混合"
|
||||||
|
echo " - 使用私有仓库和部分公共镜像源"
|
||||||
|
print_choice "4. 仅公共镜像源"
|
||||||
|
echo " - 不使用私有仓库"
|
||||||
|
echo " - 使用阿里云、网易、中科大、腾讯云"
|
||||||
|
print_choice "5. 官方Docker Hub"
|
||||||
|
echo " - 官方源,镜像最全"
|
||||||
|
echo " - 国外源,访问可能较慢"
|
||||||
|
else
|
||||||
|
print_choice "1. 仅公共镜像源"
|
||||||
|
echo " - 使用阿里云、网易、中科大、腾讯云"
|
||||||
|
print_choice "2. 官方Docker Hub"
|
||||||
|
echo " - 官方源,镜像最全"
|
||||||
|
echo " - 国外源,访问可能较慢"
|
||||||
|
print_choice "3. 自定义公共镜像源"
|
||||||
|
echo " - 手动选择公共镜像源组合"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=========================================="
|
||||||
|
}
|
||||||
|
|
||||||
|
# 获取用户选择的镜像源
|
||||||
|
get_mirror_choice() {
|
||||||
|
if [ -n "$PRIVATE_REGISTRY" ]; then
|
||||||
|
# 有私有仓库的情况
|
||||||
|
while true; do
|
||||||
|
read -p "请输入选择 (1-5): " choice
|
||||||
|
case $choice in
|
||||||
|
1)
|
||||||
|
MIRROR_TYPE="private_primary"
|
||||||
|
MIRROR_NAME="私有仓库为主 + 多个备用源"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
MIRROR_TYPE="private_only"
|
||||||
|
MIRROR_NAME="仅私有仓库"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
MIRROR_TYPE="mixed"
|
||||||
|
MIRROR_NAME="私有仓库 + 公共镜像源混合"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
MIRROR_TYPE="public_only"
|
||||||
|
MIRROR_NAME="仅公共镜像源"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
5)
|
||||||
|
MIRROR_TYPE="official"
|
||||||
|
MIRROR_NAME="官方Docker Hub"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
print_error "无效选择,请输入 1-5 的数字"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
else
|
||||||
|
# 无私有仓库的情况
|
||||||
|
while true; do
|
||||||
|
read -p "请输入选择 (1-3): " choice
|
||||||
|
case $choice in
|
||||||
|
1)
|
||||||
|
MIRROR_TYPE="public_only"
|
||||||
|
MIRROR_NAME="仅公共镜像源"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
MIRROR_TYPE="official"
|
||||||
|
MIRROR_NAME="官方Docker Hub"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
MIRROR_TYPE="custom_public"
|
||||||
|
MIRROR_NAME="自定义公共镜像源"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
print_error "无效选择,请输入 1-3 的数字"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 混合配置选择(私有+部分公共)
|
||||||
|
get_mixed_config() {
|
||||||
|
echo
|
||||||
|
print_step "选择要添加的公共镜像源(可多选):"
|
||||||
|
|
||||||
|
MIRRORS=("$PRIVATE_MIRROR")
|
||||||
|
|
||||||
|
echo "1) 阿里云镜像"
|
||||||
|
echo "2) 网易云镜像"
|
||||||
|
echo "3) 中科大镜像"
|
||||||
|
echo "4) 腾讯云镜像"
|
||||||
|
echo "5) 官方Docker Hub"
|
||||||
|
|
||||||
|
read -p "请输入选择(多个用空格分隔,如:1 2 3): " public_choices
|
||||||
|
|
||||||
|
for choice in $public_choices; do
|
||||||
|
case $choice in
|
||||||
|
1)
|
||||||
|
MIRRORS+=("$ALIYUN_MIRROR")
|
||||||
|
print_info "已添加阿里云镜像"
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
MIRRORS+=("$DOCKER_HUB_MIRROR")
|
||||||
|
print_info "已添加网易云镜像"
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
MIRRORS+=("$USTC_MIRROR")
|
||||||
|
print_info "已添加中科大镜像"
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
MIRRORS+=("$TENCENT_MIRROR")
|
||||||
|
print_info "已添加腾讯云镜像"
|
||||||
|
;;
|
||||||
|
5)
|
||||||
|
MIRRORS+=("https://registry-1.docker.io")
|
||||||
|
print_info "已添加官方Docker Hub"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
MIRROR_NAME="混合镜像源(${#MIRRORS[@]}个)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 自定义公共镜像源配置
|
||||||
|
get_custom_public_config() {
|
||||||
|
echo
|
||||||
|
print_step "选择要添加的公共镜像源(可多选):"
|
||||||
|
|
||||||
|
MIRRORS=()
|
||||||
|
|
||||||
|
echo "1) 阿里云镜像"
|
||||||
|
echo "2) 网易云镜像"
|
||||||
|
echo "3) 中科大镜像"
|
||||||
|
echo "4) 腾讯云镜像"
|
||||||
|
echo "5) 官方Docker Hub"
|
||||||
|
|
||||||
|
read -p "请输入选择(多个用空格分隔,如:1 2 3): " public_choices
|
||||||
|
|
||||||
|
for choice in $public_choices; do
|
||||||
|
case $choice in
|
||||||
|
1)
|
||||||
|
MIRRORS+=("$ALIYUN_MIRROR")
|
||||||
|
print_info "已添加阿里云镜像"
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
MIRRORS+=("$DOCKER_HUB_MIRROR")
|
||||||
|
print_info "已添加网易云镜像"
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
MIRRORS+=("$USTC_MIRROR")
|
||||||
|
print_info "已添加中科大镜像"
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
MIRRORS+=("$TENCENT_MIRROR")
|
||||||
|
print_info "已添加腾讯云镜像"
|
||||||
|
;;
|
||||||
|
5)
|
||||||
|
MIRRORS+=("https://registry-1.docker.io")
|
||||||
|
print_info "已添加官方Docker Hub"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ${#MIRRORS[@]} -eq 0 ]; then
|
||||||
|
print_error "至少需要选择一个镜像源"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
MIRROR_NAME="自定义公共镜像源(${#MIRRORS[@]}个)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 配置镜像源
|
||||||
|
configure_mirrors() {
|
||||||
|
print_step "配置Docker镜像源: $MIRROR_NAME"
|
||||||
|
|
||||||
|
# 创建Docker配置目录
|
||||||
|
sudo mkdir -p /etc/docker
|
||||||
|
|
||||||
|
# 备份原有配置
|
||||||
|
if [ -f /etc/docker/daemon.json ]; then
|
||||||
|
sudo cp /etc/docker/daemon.json /etc/docker/daemon.json.backup.$(date +%Y%m%d%H%M%S)
|
||||||
|
print_info "已备份原有配置: /etc/docker/daemon.json.backup.$(date +%Y%m%d%H%M%S)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 根据不同类型生成配置
|
||||||
|
case "$MIRROR_TYPE" in
|
||||||
|
"private_primary")
|
||||||
|
# 私有仓库为主 + 多个备用源
|
||||||
|
cat << EOF | sudo tee /etc/docker/daemon.json > /dev/null
|
||||||
|
{
|
||||||
|
"registry-mirrors": [
|
||||||
|
"$PRIVATE_MIRROR",
|
||||||
|
"$ALIYUN_MIRROR",
|
||||||
|
"$DOCKER_HUB_MIRROR",
|
||||||
|
"$USTC_MIRROR",
|
||||||
|
"$TENCENT_MIRROR"
|
||||||
|
],
|
||||||
|
"insecure-registries": ["$PRIVATE_REGISTRY"],
|
||||||
|
"debug": false,
|
||||||
|
"experimental": false
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
;;
|
||||||
|
"private_only")
|
||||||
|
# 仅私有仓库
|
||||||
|
cat << EOF | sudo tee /etc/docker/daemon.json > /dev/null
|
||||||
|
{
|
||||||
|
"registry-mirrors": ["$PRIVATE_MIRROR"],
|
||||||
|
"insecure-registries": ["$PRIVATE_REGISTRY"],
|
||||||
|
"debug": false,
|
||||||
|
"experimental": false
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
;;
|
||||||
|
"mixed")
|
||||||
|
# 混合配置
|
||||||
|
mirrors_json=$(printf '"%s",' "${MIRRORS[@]}")
|
||||||
|
mirrors_json="[${mirrors_json%,}]"
|
||||||
|
|
||||||
|
cat << EOF | sudo tee /etc/docker/daemon.json > /dev/null
|
||||||
|
{
|
||||||
|
"registry-mirrors": $mirrors_json,
|
||||||
|
"insecure-registries": ["$PRIVATE_REGISTRY"],
|
||||||
|
"debug": false,
|
||||||
|
"experimental": false
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
;;
|
||||||
|
"public_only")
|
||||||
|
# 仅公共镜像源
|
||||||
|
cat << EOF | sudo tee /etc/docker/daemon.json > /dev/null
|
||||||
|
{
|
||||||
|
"registry-mirrors": [
|
||||||
|
"$ALIYUN_MIRROR",
|
||||||
|
"$DOCKER_HUB_MIRROR",
|
||||||
|
"$USTC_MIRROR",
|
||||||
|
"$TENCENT_MIRROR"
|
||||||
|
],
|
||||||
|
"insecure-registries": [],
|
||||||
|
"debug": false,
|
||||||
|
"experimental": false
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
;;
|
||||||
|
"official")
|
||||||
|
# 官方Docker Hub
|
||||||
|
cat << EOF | sudo tee /etc/docker/daemon.json > /dev/null
|
||||||
|
{
|
||||||
|
"registry-mirrors": ["https://registry-1.docker.io"],
|
||||||
|
"insecure-registries": [],
|
||||||
|
"debug": false,
|
||||||
|
"experimental": false
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
;;
|
||||||
|
"custom_public")
|
||||||
|
# 自定义公共镜像源
|
||||||
|
mirrors_json=$(printf '"%s",' "${MIRRORS[@]}")
|
||||||
|
mirrors_json="[${mirrors_json%,}]"
|
||||||
|
|
||||||
|
cat << EOF | sudo tee /etc/docker/daemon.json > /dev/null
|
||||||
|
{
|
||||||
|
"registry-mirrors": $mirrors_json,
|
||||||
|
"insecure-registries": [],
|
||||||
|
"debug": false,
|
||||||
|
"experimental": false
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
print_info "Docker镜像源配置完成"
|
||||||
|
print_config "配置文件位置: /etc/docker/daemon.json"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 重启Docker服务
|
||||||
|
restart_docker() {
|
||||||
|
print_step "重启Docker服务..."
|
||||||
|
|
||||||
|
if sudo systemctl restart docker; then
|
||||||
|
print_info "Docker服务重启成功"
|
||||||
|
else
|
||||||
|
print_error "Docker服务重启失败"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 等待Docker服务完全启动
|
||||||
|
sleep 3
|
||||||
|
}
|
||||||
|
|
||||||
|
# 保存私有仓库认证信息
|
||||||
|
save_private_credentials() {
|
||||||
|
if [ "$NEED_AUTH" != "yes" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_step "是否保存私有仓库认证信息?"
|
||||||
|
echo "如果保存,以后拉取私有镜像时不需要重复输入密码"
|
||||||
|
read -p "是否保存认证信息?(y/N): " save_choice
|
||||||
|
|
||||||
|
if [[ $save_choice =~ ^[Yy]$ ]]; then
|
||||||
|
# 使用Docker login保存认证信息
|
||||||
|
if echo "$PRIVATE_PASSWORD" | docker login $PRIVATE_REGISTRY -u "$PRIVATE_USERNAME" --password-stdin; then
|
||||||
|
print_info "私有仓库认证信息已保存到 ~/.docker/config.json"
|
||||||
|
CREDENTIALS_SAVED="yes"
|
||||||
|
else
|
||||||
|
print_warning "私有仓库认证信息保存失败"
|
||||||
|
CREDENTIALS_SAVED="no"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
print_info "私有仓库认证信息未保存,拉取私有镜像时需要重新登录"
|
||||||
|
CREDENTIALS_SAVED="no"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 验证配置
|
||||||
|
verify_configuration() {
|
||||||
|
print_step "验证配置..."
|
||||||
|
|
||||||
|
# 检查Docker服务状态
|
||||||
|
if sudo systemctl is-active --quiet docker; then
|
||||||
|
print_info "Docker服务运行正常"
|
||||||
|
else
|
||||||
|
print_error "Docker服务未运行"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查配置是否生效
|
||||||
|
if sudo docker info 2>/dev/null | grep -q "Registry Mirrors"; then
|
||||||
|
print_info "镜像源配置已生效"
|
||||||
|
echo
|
||||||
|
print_config "当前配置的镜像源:"
|
||||||
|
sudo docker info 2>/dev/null | grep -A 10 "Registry Mirrors"
|
||||||
|
else
|
||||||
|
print_warning "镜像源配置可能未生效,请手动检查"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 显示配置摘要
|
||||||
|
show_summary() {
|
||||||
|
echo
|
||||||
|
print_info "=== 配置完成摘要 ==="
|
||||||
|
echo -e "${GREEN}✓${NC} Docker镜像源配置完成"
|
||||||
|
echo -e "${GREEN}✓${NC} 镜像源类型: ${MIRROR_NAME}"
|
||||||
|
|
||||||
|
if [ -n "$PRIVATE_REGISTRY" ]; then
|
||||||
|
echo -e "${GREEN}✓${NC} 私有仓库地址: ${PRIVATE_REGISTRY}"
|
||||||
|
echo -e "${GREEN}✓${NC} 私有仓库镜像: ${PRIVATE_MIRROR}"
|
||||||
|
|
||||||
|
if [ "$NEED_AUTH" = "yes" ]; then
|
||||||
|
echo -e "${GREEN}✓${NC} 私有仓库认证: 需要"
|
||||||
|
echo -e "${GREEN}✓${NC} 用户名: ${PRIVATE_USERNAME}"
|
||||||
|
if [ "$CREDENTIALS_SAVED" = "yes" ]; then
|
||||||
|
echo -e "${GREEN}✓${NC} 认证信息: 已保存"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}⚠${NC} 认证信息: 未保存"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}✓${NC} 私有仓库认证: 无需认证"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}✓${NC} 私有仓库: 未配置"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${GREEN}✓${NC} Docker服务已重启生效"
|
||||||
|
|
||||||
|
echo
|
||||||
|
print_info "使用说明:"
|
||||||
|
if [ -n "$PRIVATE_REGISTRY" ]; then
|
||||||
|
echo " 私有镜像: docker pull ${PRIVATE_REGISTRY}/镜像名称"
|
||||||
|
fi
|
||||||
|
echo " 公共镜像: docker pull 镜像名称"
|
||||||
|
echo " 查看配置: docker info | grep -A 10 'Registry Mirrors'"
|
||||||
|
echo " 测试拉取: docker pull hello-world"
|
||||||
|
|
||||||
|
echo
|
||||||
|
print_info "配置文件: /etc/docker/daemon.json"
|
||||||
|
print_info "备份文件: /etc/docker/daemon.json.backup.*"
|
||||||
|
if [ -n "$PRIVATE_REGISTRY" ] && [ "$NEED_AUTH" = "yes" ] && [ "$CREDENTIALS_SAVED" = "yes" ]; then
|
||||||
|
print_info "认证信息: ~/.docker/config.json"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 主函数
|
||||||
|
main() {
|
||||||
|
clear
|
||||||
|
echo "=========================================="
|
||||||
|
echo " Docker镜像源配置脚本"
|
||||||
|
echo "=========================================="
|
||||||
|
echo
|
||||||
|
|
||||||
|
# 检查Docker
|
||||||
|
check_docker
|
||||||
|
|
||||||
|
# 获取私有仓库配置
|
||||||
|
get_private_registry_config
|
||||||
|
|
||||||
|
# 显示镜像源菜单
|
||||||
|
show_mirror_menu
|
||||||
|
|
||||||
|
# 获取用户选择
|
||||||
|
get_mirror_choice
|
||||||
|
|
||||||
|
# 如果是混合配置,获取详细选择
|
||||||
|
if [ "$MIRROR_TYPE" = "mixed" ]; then
|
||||||
|
get_mixed_config
|
||||||
|
elif [ "$MIRROR_TYPE" = "custom_public" ]; then
|
||||||
|
get_custom_public_config
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 如果是私有仓库需要认证,测试登录
|
||||||
|
if [ "$NEED_AUTH" = "yes" ]; then
|
||||||
|
if ! test_private_login; then
|
||||||
|
print_error "私有仓库登录测试失败"
|
||||||
|
read -p "是否继续配置?(可能会影响私有镜像拉取)(y/N): " continue_anyway
|
||||||
|
if [[ ! $continue_anyway =~ ^[Yy]$ ]]; then
|
||||||
|
print_error "配置中止,请解决登录问题后重新运行脚本"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 配置镜像源
|
||||||
|
configure_mirrors
|
||||||
|
|
||||||
|
# 重启Docker服务
|
||||||
|
restart_docker
|
||||||
|
|
||||||
|
# 保存私有仓库认证信息
|
||||||
|
if [ "$NEED_AUTH" = "yes" ]; then
|
||||||
|
save_private_credentials
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 验证配置
|
||||||
|
verify_configuration
|
||||||
|
|
||||||
|
# 显示摘要
|
||||||
|
show_summary
|
||||||
|
}
|
||||||
|
|
||||||
|
# 运行主函数
|
||||||
|
main "$@"
|
||||||
134
Docker 容器端口查看工具
Normal file
134
Docker 容器端口查看工具
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 高端 Docker 端口查看工具 - 修复版
|
||||||
|
# 显示全部容器的端口映射信息
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
PURPLE='\033[0;35m'
|
||||||
|
CYAN='\033[0;36m'
|
||||||
|
BOLD='\033[1m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# 获取终端宽度
|
||||||
|
TERM_WIDTH=$(tput cols 2>/dev/null || echo 80)
|
||||||
|
|
||||||
|
print_header() {
|
||||||
|
local title="🐳 DOCKER 容器端口映射表 🐳"
|
||||||
|
local padding=$(( (TERM_WIDTH - ${#title}) / 2 ))
|
||||||
|
printf "\n${BOLD}${CYAN}%*s${NC}\n" $((padding + ${#title})) "$title"
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
print_separator() {
|
||||||
|
printf "${BLUE}%*s${NC}\n" $TERM_WIDTH | tr ' ' '═'
|
||||||
|
}
|
||||||
|
|
||||||
|
print_table_header() {
|
||||||
|
printf "${BOLD}${YELLOW}%-25s %-12s %-35s %-20s${NC}\n" "容器名称" "状态" "主机端口 → 容器端口" "镜像"
|
||||||
|
print_separator
|
||||||
|
}
|
||||||
|
|
||||||
|
format_ports() {
|
||||||
|
local ports="$1"
|
||||||
|
if [[ -z "$ports" || "$ports" == "" ]]; then
|
||||||
|
echo -e "${RED}无端口映射${NC}"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 提取并格式化端口信息
|
||||||
|
echo "$ports" | sed -E '
|
||||||
|
s/0\.0\.0\.0:([0-9]+)->([0-9]+)\/tcp/\1 → \2/g;
|
||||||
|
s/\[::\]:([0-9]+)->([0-9]+)\/tcp/\1 → \2/g;
|
||||||
|
s/, /\\n/g;
|
||||||
|
' | while IFS= read -r line; do
|
||||||
|
if [[ -n "$line" ]]; then
|
||||||
|
echo -e " ${GREEN}${line}${NC}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
print_container_info() {
|
||||||
|
local name="$1"
|
||||||
|
local status="$2"
|
||||||
|
local ports="$3"
|
||||||
|
local image="$4"
|
||||||
|
|
||||||
|
# 状态颜色
|
||||||
|
local status_color=$GREEN
|
||||||
|
if [[ "$status" == *"Exited"* ]]; then
|
||||||
|
status_color=$RED
|
||||||
|
elif [[ "$status" == *"Restarting"* ]]; then
|
||||||
|
status_color=$YELLOW
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 缩短镜像名称
|
||||||
|
local image_short=$(echo "$image" | cut -d':' -f1 | rev | cut -d'/' -f1 | rev)
|
||||||
|
if [[ ${#image_short} -gt 18 ]]; then
|
||||||
|
image_short="${image_short:0:15}..."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 打印容器基本信息
|
||||||
|
printf "%-25s ${status_color}%-12s${NC} %-35s %-20s\n" \
|
||||||
|
"${name:0:24}" \
|
||||||
|
"${status:0:11}" \
|
||||||
|
"" \
|
||||||
|
"$image_short"
|
||||||
|
|
||||||
|
# 打印端口信息
|
||||||
|
format_ports "$ports"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_total_info() {
|
||||||
|
local total=$(docker ps -aq | wc -l | tr -d ' ')
|
||||||
|
local running=$(docker ps -q | wc -l | tr -d ' ')
|
||||||
|
local stopped=$((total - running))
|
||||||
|
echo "$total $running $stopped"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
# 检查 Docker
|
||||||
|
if ! command -v docker &> /dev/null; then
|
||||||
|
echo -e "${RED}错误: Docker 未安装${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 显示头部
|
||||||
|
print_header
|
||||||
|
|
||||||
|
# 获取统计信息
|
||||||
|
read total running stopped <<< $(get_total_info)
|
||||||
|
|
||||||
|
# 显示统计
|
||||||
|
echo -e "${BOLD}📊 容器统计: ${GREEN}运行: $running${NC} | ${YELLOW}停止: $stopped${NC} | ${BLUE}总计: $total${NC}"
|
||||||
|
print_separator
|
||||||
|
echo
|
||||||
|
|
||||||
|
# 显示表格头部
|
||||||
|
print_table_header
|
||||||
|
|
||||||
|
# 获取并显示容器信息
|
||||||
|
docker ps -a --format "{{.Names}}||{{.Status}}||{{.Ports}}||{{.Image}}" | while IFS='||' read -r name status ports image; do
|
||||||
|
print_container_info "$name" "$status" "$ports" "$image"
|
||||||
|
echo
|
||||||
|
done
|
||||||
|
|
||||||
|
# 显示底部信息
|
||||||
|
echo
|
||||||
|
print_separator
|
||||||
|
echo -e "${CYAN}💡 提示:${NC}"
|
||||||
|
echo -e " ${GREEN}●${NC} 绿色状态: 容器正常运行"
|
||||||
|
echo -e " ${YELLOW}●${NC} 黄色状态: 容器重启中"
|
||||||
|
echo -e " ${RED}●${NC} 红色状态: 容器已停止"
|
||||||
|
echo
|
||||||
|
echo -e "${PURPLE}🔄 刷新: 重新运行此脚本${NC}"
|
||||||
|
echo -e "${PURPLE}🐳 管理: docker ps -a | docker start/stop [容器名]${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 运行主函数
|
||||||
|
main "$@"
|
||||||
427
Docker容器管理面板
Normal file
427
Docker容器管理面板
Normal file
@@ -0,0 +1,427 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 简单实用的 Docker 容器管理脚本
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
PURPLE='\033[0;35m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
# 检查 Docker
|
||||||
|
check_docker() {
|
||||||
|
if ! command -v docker &> /dev/null; then
|
||||||
|
echo -e "${RED}Docker 未安装${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 显示容器列表
|
||||||
|
show_containers() {
|
||||||
|
echo -e "\n${BLUE}=== 容器列表 ===${NC}"
|
||||||
|
echo "编号 | 容器名称 | 状态 | 镜像"
|
||||||
|
echo "----|----------|------|------"
|
||||||
|
|
||||||
|
local count=0
|
||||||
|
docker ps -a --format "table {{.Names}}\t{{.Status}}\t{{.Image}}" | tail -n +2 | while read line; do
|
||||||
|
if [ -n "$line" ]; then
|
||||||
|
count=$((count + 1))
|
||||||
|
name=$(echo "$line" | awk '{print $1}')
|
||||||
|
status=$(echo "$line" | awk '{print $2}')
|
||||||
|
image=$(echo "$line" | awk '{for(i=3;i<=NF;i++) printf $i" "; print ""}' | sed 's/ $//')
|
||||||
|
|
||||||
|
# 状态显示
|
||||||
|
if [[ "$status" == "Up"* ]]; then
|
||||||
|
status_display="${GREEN}运行中${NC}"
|
||||||
|
elif [[ "$status" == "Exited"* ]]; then
|
||||||
|
status_display="${RED}已停止${NC}"
|
||||||
|
else
|
||||||
|
status_display="${YELLOW}$status${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "$count | $name | $status_display | $image"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# 显示镜像列表
|
||||||
|
show_images() {
|
||||||
|
echo -e "\n${PURPLE}=== 镜像列表 ===${NC}"
|
||||||
|
echo "编号 | 镜像名称:标签 | 镜像ID | 大小 | 创建时间"
|
||||||
|
echo "----|---------------|--------|------|----------"
|
||||||
|
|
||||||
|
local count=0
|
||||||
|
docker images --format "table {{.Repository}}:{{.Tag}}\t{{.ID}}\t{{.Size}}\t{{.CreatedSince}}" | tail -n +2 | while read line; do
|
||||||
|
if [ -n "$line" ]; then
|
||||||
|
count=$((count + 1))
|
||||||
|
repo_tag=$(echo "$line" | awk '{print $1}')
|
||||||
|
image_id=$(echo "$line" | awk '{print $2}')
|
||||||
|
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
|
||||||
|
|
||||||
|
# 截断镜像ID
|
||||||
|
image_id_short="${image_id:0:12}"
|
||||||
|
|
||||||
|
echo -e "$count | $repo_tag | $image_id_short | $size | $created"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# 通过编号获取容器名称
|
||||||
|
get_container_name() {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
# 通过编号获取镜像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
|
||||||
|
}
|
||||||
|
|
||||||
|
# 批量删除容器
|
||||||
|
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)
|
||||||
|
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
|
||||||
|
fi
|
||||||
|
|
||||||
|
if docker rm -f "$container_name" &> /dev/null; then
|
||||||
|
echo -e "${GREEN}✓ 删除成功: $container_name${NC}"
|
||||||
|
success_count=$((success_count + 1))
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗ 删除失败: $container_name${NC}"
|
||||||
|
fail_count=$((fail_count + 1))
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
# 批量删除镜像
|
||||||
|
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)
|
||||||
|
if [ -n "$image_id" ]; then
|
||||||
|
# 获取镜像名称用于显示
|
||||||
|
image_name=$(docker images --format "table {{.Repository}}:{{.Tag}}\t{{.ID}}" | grep "$image_id" | awk '{print $1}')
|
||||||
|
|
||||||
|
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
|
||||||
|
fi
|
||||||
|
|
||||||
|
if docker rmi "$image_id" &> /dev/null; then
|
||||||
|
echo -e "${GREEN}✓ 删除成功: $image_name${NC}"
|
||||||
|
success_count=$((success_count + 1))
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗ 删除失败: $image_name (可能有容器在使用此镜像)${NC}"
|
||||||
|
fail_count=$((fail_count + 1))
|
||||||
|
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
|
||||||
|
docker image prune -f
|
||||||
|
echo -e "${GREEN}已清理 $dangling_count 个悬空镜像${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}取消清理${NC}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}没有悬空镜像${NC}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 镜像管理菜单
|
||||||
|
image_management() {
|
||||||
|
while true; do
|
||||||
|
clear
|
||||||
|
echo -e "${PURPLE}"
|
||||||
|
echo "========================================"
|
||||||
|
echo " Docker 镜像管理"
|
||||||
|
echo "========================================"
|
||||||
|
echo -e "${NC}"
|
||||||
|
|
||||||
|
show_images
|
||||||
|
|
||||||
|
echo -e "${PURPLE}镜像操作选项:${NC}"
|
||||||
|
echo "1. 删除镜像 (支持批量: 1 2 3 或 1,2,3)"
|
||||||
|
echo "2. 批量删除所有镜像"
|
||||||
|
echo "3. 清理悬空镜像"
|
||||||
|
echo "4. 返回主菜单"
|
||||||
|
echo
|
||||||
|
|
||||||
|
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
|
||||||
|
;;
|
||||||
|
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}"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
clean_dangling_images
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
return
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo -e "${RED}无效选择${NC}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo
|
||||||
|
read -p "按回车键继续..."
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# 主菜单
|
||||||
|
main_menu() {
|
||||||
|
while true; do
|
||||||
|
clear
|
||||||
|
echo -e "${BLUE}"
|
||||||
|
echo "========================================"
|
||||||
|
echo " 简单 Docker 容器管理"
|
||||||
|
echo "========================================"
|
||||||
|
echo -e "${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 "0. 退出"
|
||||||
|
echo
|
||||||
|
|
||||||
|
read -p "请选择操作: " choice
|
||||||
|
|
||||||
|
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}"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
7)
|
||||||
|
image_management
|
||||||
|
;;
|
||||||
|
0)
|
||||||
|
echo
|
||||||
|
echo -e "${GREEN}再见!${NC}"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo -e "${RED}无效选择${NC}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo
|
||||||
|
read -p "按回车键继续..."
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# 启动脚本
|
||||||
|
check_docker
|
||||||
|
main_menu
|
||||||
15
Docker镜像源自动测速脚本
Normal file
15
Docker镜像源自动测速脚本
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
echo "🎯 切换到清华镜像源..."
|
||||||
|
|
||||||
|
# 备份原配置
|
||||||
|
sudo cp /etc/apt/sources.list.d/docker.list /etc/apt/sources.list.d/docker.list.bak
|
||||||
|
|
||||||
|
# 使用清华镜像源
|
||||||
|
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null <<EOF
|
||||||
|
deb [arch=amd64] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/debian bookworm stable
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 更新并安装
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install -y docker-ce docker-ce-cli containerd.io
|
||||||
|
|
||||||
|
echo "✅ 已切换到清华镜像源,速度应该会大幅提升!"
|
||||||
319
OpenList
Normal file
319
OpenList
Normal file
@@ -0,0 +1,319 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# OpenList Docker 一键部署脚本(带自动密码检测)
|
||||||
|
# 版本:1.3 - 在原有成功脚本基础上添加密码自动处理
|
||||||
|
|
||||||
|
set -e # 任何命令失败则立即退出脚本
|
||||||
|
|
||||||
|
# 全局变量
|
||||||
|
CONTAINER_NAME="openlist"
|
||||||
|
DATA_DIR="/data/openlist"
|
||||||
|
IMAGE_NAME="openlistteam/openlist:latest"
|
||||||
|
DEFAULT_PORT=5344
|
||||||
|
PORT_MAPPING=""
|
||||||
|
|
||||||
|
# 颜色输出函数
|
||||||
|
red() { echo -e "\033[31m$1\033[0m"; }
|
||||||
|
green() { echo -e "\033[32m$1\033[0m"; }
|
||||||
|
yellow() { echo -e "\033[33m$1\033[0m"; }
|
||||||
|
blue() { echo -e "\033[34m$1\033[0m"; }
|
||||||
|
|
||||||
|
# 错误退出函数
|
||||||
|
error_exit() {
|
||||||
|
red "❌ 错误:$1"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查 Docker 是否可用
|
||||||
|
check_docker() {
|
||||||
|
blue "🔍 检查 Docker 环境..."
|
||||||
|
if ! command -v docker &> /dev/null; then
|
||||||
|
error_exit "未检测到 Docker,请先安装 Docker"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! docker info &> /dev/null; then
|
||||||
|
error_exit "Docker 服务未运行,请启动 Docker 服务"
|
||||||
|
fi
|
||||||
|
green "✅ Docker 环境检查通过"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 准备数据目录
|
||||||
|
prepare_directory() {
|
||||||
|
blue "📁 准备数据目录..."
|
||||||
|
|
||||||
|
# 创建 /data 目录(如果不存在)
|
||||||
|
if [ ! -d "/data" ]; then
|
||||||
|
yellow "创建 /data 目录..."
|
||||||
|
sudo mkdir -p /data || error_exit "创建 /data 目录失败"
|
||||||
|
sudo chmod 755 /data || error_exit "设置 /data 权限失败"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 创建 OpenList 数据目录
|
||||||
|
if [ ! -d "$DATA_DIR" ]; then
|
||||||
|
yellow "创建 OpenList 数据目录: $DATA_DIR"
|
||||||
|
sudo mkdir -p "$DATA_DIR" || error_exit "创建数据目录失败"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 设置正确的目录权限
|
||||||
|
blue "🔧 设置目录权限..."
|
||||||
|
sudo chown -R 1000:1000 "$DATA_DIR" || error_exit "设置目录所有权失败"
|
||||||
|
sudo chmod -R 755 "$DATA_DIR" || error_exit "设置目录权限失败"
|
||||||
|
|
||||||
|
# 验证权限设置
|
||||||
|
if [ -w "$DATA_DIR" ] && [ -x "$DATA_DIR" ]; then
|
||||||
|
green "✅ 目录权限验证通过"
|
||||||
|
else
|
||||||
|
error_exit "目录权限设置失败,请手动检查权限"
|
||||||
|
fi
|
||||||
|
|
||||||
|
green "✅ 数据目录准备完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 清理现有容器
|
||||||
|
cleanup_existing_container() {
|
||||||
|
blue "🧹 检查现有容器..."
|
||||||
|
if docker ps -a --filter "name=$CONTAINER_NAME" --format "{{.Names}}" | grep -q "$CONTAINER_NAME"; then
|
||||||
|
yellow "发现已存在的 OpenList 容器,正在清理..."
|
||||||
|
docker stop "$CONTAINER_NAME" >/dev/null 2>&1 || true
|
||||||
|
docker rm "$CONTAINER_NAME" >/dev/null 2>&1 || true
|
||||||
|
green "✅ 旧容器清理完成"
|
||||||
|
else
|
||||||
|
green "✅ 无现有容器需要清理"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查端口占用
|
||||||
|
check_port() {
|
||||||
|
local port=$1
|
||||||
|
blue "🔍 检查端口 $port 占用情况..."
|
||||||
|
|
||||||
|
if command -v ss &> /dev/null; then
|
||||||
|
if ss -tuln | grep ":$port " > /dev/null; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if netstat -tuln | grep ":$port " > /dev/null; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
green "✅ 端口 $port 可用"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# 获取可用端口
|
||||||
|
get_available_port() {
|
||||||
|
local port=$DEFAULT_PORT
|
||||||
|
local max_port=6000
|
||||||
|
|
||||||
|
while [ $port -le $max_port ]; do
|
||||||
|
if check_port $port; then
|
||||||
|
echo $port
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
port=$((port + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
error_exit "在 $DEFAULT_PORT-$max_port 范围内找不到可用端口"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 拉取 OpenList 镜像
|
||||||
|
pull_openlist_image() {
|
||||||
|
blue "📦 拉取 OpenList 镜像..."
|
||||||
|
if docker pull "$IMAGE_NAME"; then
|
||||||
|
green "✅ OpenList 镜像拉取完成"
|
||||||
|
else
|
||||||
|
error_exit "拉取 OpenList 镜像失败,请检查网络连接"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 部署 OpenList 容器(使用特权模式解决权限问题)
|
||||||
|
deploy_openlist() {
|
||||||
|
blue "🚀 开始部署 OpenList 容器..."
|
||||||
|
|
||||||
|
# 确定使用的端口
|
||||||
|
if check_port $DEFAULT_PORT; then
|
||||||
|
PORT_MAPPING="$DEFAULT_PORT:5244"
|
||||||
|
green "✅ 使用默认端口:$DEFAULT_PORT"
|
||||||
|
else
|
||||||
|
local available_port=$(get_available_port)
|
||||||
|
PORT_MAPPING="$available_port:5244"
|
||||||
|
yellow "📊 使用端口:$available_port (原端口 $DEFAULT_PORT 被占用)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 部署命令(使用特权模式解决权限问题)
|
||||||
|
blue "🐳 启动容器..."
|
||||||
|
if docker run -d \
|
||||||
|
--name "$CONTAINER_NAME" \
|
||||||
|
--restart=unless-stopped \
|
||||||
|
--privileged \
|
||||||
|
--user root \
|
||||||
|
-p "$PORT_MAPPING" \
|
||||||
|
-v "$DATA_DIR:/opt/openlist/data" \
|
||||||
|
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||||
|
-e PUID=0 \
|
||||||
|
-e PGID=0 \
|
||||||
|
-e UMASK=000 \
|
||||||
|
-e TZ=Asia/Shanghai \
|
||||||
|
"$IMAGE_NAME"; then
|
||||||
|
green "✅ OpenList 容器部署成功"
|
||||||
|
else
|
||||||
|
error_exit "OpenList 容器启动失败"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# === 新增功能:密码检测和自动重置 ===
|
||||||
|
# 生成随机密码
|
||||||
|
generate_random_password() {
|
||||||
|
tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 12
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检测并获取密码
|
||||||
|
detect_and_get_password() {
|
||||||
|
blue "🔍 检测密码生成情况..."
|
||||||
|
|
||||||
|
local max_attempts=10
|
||||||
|
local attempt=1
|
||||||
|
local password=""
|
||||||
|
|
||||||
|
while [ $attempt -le $max_attempts ]; do
|
||||||
|
yellow "尝试检测密码 ($attempt/$max_attempts)..."
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
# 检查容器日志获取密码
|
||||||
|
local logs=$(docker logs "$CONTAINER_NAME" 2>&1 | tail -10)
|
||||||
|
|
||||||
|
# 尝试提取密码
|
||||||
|
password=$(echo "$logs" | grep -o "initial password is: [[:alnum:]]*" | awk '{print $4}' | tail -1)
|
||||||
|
|
||||||
|
if [ -n "$password" ]; then
|
||||||
|
green "✅ 检测到自动生成的密码"
|
||||||
|
echo "$password"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查是否启动成功但没有新密码(使用现有配置)
|
||||||
|
if echo "$logs" | grep -q "HTTP server"; then
|
||||||
|
yellow "⚠️ 使用现有配置,无新密码生成"
|
||||||
|
# 返回空字符串表示使用现有配置
|
||||||
|
echo ""
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
attempt=$((attempt + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
# 如果检测不到密码,生成随机密码并重置
|
||||||
|
yellow "⚠️ 未检测到密码生成,执行自动重置..."
|
||||||
|
auto_reset_password
|
||||||
|
}
|
||||||
|
|
||||||
|
# 自动重置密码
|
||||||
|
auto_reset_password() {
|
||||||
|
blue "🔄 自动重置密码..."
|
||||||
|
|
||||||
|
# 停止容器
|
||||||
|
docker stop "$CONTAINER_NAME" 2>/dev/null || true
|
||||||
|
|
||||||
|
# 删除配置文件以触发新密码生成
|
||||||
|
yellow "删除现有配置..."
|
||||||
|
sudo rm -f "$DATA_DIR/config.json" 2>/dev/null || true
|
||||||
|
sudo rm -f "$DATA_DIR"/*.db 2>/dev/null || true
|
||||||
|
|
||||||
|
# 重启容器
|
||||||
|
yellow "重启容器生成新密码..."
|
||||||
|
docker start "$CONTAINER_NAME" 2>/dev/null || {
|
||||||
|
yellow "容器启动失败,重新部署..."
|
||||||
|
deploy_openlist
|
||||||
|
}
|
||||||
|
|
||||||
|
# 等待并再次检测密码
|
||||||
|
sleep 8
|
||||||
|
detect_and_get_password
|
||||||
|
}
|
||||||
|
|
||||||
|
# 验证部署状态
|
||||||
|
verify_deployment() {
|
||||||
|
blue "🔍 验证容器运行状态..."
|
||||||
|
|
||||||
|
local max_attempts=15
|
||||||
|
local attempt=1
|
||||||
|
|
||||||
|
while [ $attempt -le $max_attempts ]; do
|
||||||
|
yellow "⏳ 等待容器启动 ($attempt/$max_attempts)..."
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
# 检查容器状态
|
||||||
|
if docker ps --filter "name=$CONTAINER_NAME" --filter "status=running" --format "{{.Names}}" | grep -q "$CONTAINER_NAME"; then
|
||||||
|
green "✅ 容器正在运行"
|
||||||
|
|
||||||
|
# 检测并获取密码
|
||||||
|
PASSWORD=$(detect_and_get_password)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
attempt=$((attempt + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
red "❌ 容器启动超时"
|
||||||
|
blue "📋 容器日志:"
|
||||||
|
docker logs "$CONTAINER_NAME" | tail -20
|
||||||
|
error_exit "容器启动失败,请检查上方日志"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 显示部署成功信息
|
||||||
|
show_success_info() {
|
||||||
|
local port=$(echo "$PORT_MAPPING" | cut -d':' -f1)
|
||||||
|
local ip_address=$(hostname -I | awk '{print $1}' | head -n1)
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
green "🎉 OpenList 部署成功!"
|
||||||
|
echo "=========================================="
|
||||||
|
blue "📋 访问信息:"
|
||||||
|
echo " 🌐 访问地址:http://$ip_address:$port"
|
||||||
|
echo " 🏠 本地访问:http://localhost:$port"
|
||||||
|
echo " 📁 数据目录:$DATA_DIR"
|
||||||
|
echo ""
|
||||||
|
blue "🔐 登录信息:"
|
||||||
|
echo " 用户名:admin"
|
||||||
|
|
||||||
|
if [ -n "$PASSWORD" ]; then
|
||||||
|
echo " 密码:$PASSWORD"
|
||||||
|
yellow "💡 首次登录后请立即修改密码!"
|
||||||
|
else
|
||||||
|
echo " 密码:使用之前设置的密码"
|
||||||
|
echo " 🔄 如需重置:删除 $DATA_DIR/config.json 并重启容器"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
blue "⚡ 常用命令:"
|
||||||
|
echo " 📜 查看日志:docker logs $CONTAINER_NAME"
|
||||||
|
echo " 🔄 重启容器:docker restart $CONTAINER_NAME"
|
||||||
|
echo " ⏹️ 停止容器:docker stop $CONTAINER_NAME"
|
||||||
|
echo " 🚀 启动容器:docker start $CONTAINER_NAME"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 主执行流程
|
||||||
|
main() {
|
||||||
|
echo "=========================================="
|
||||||
|
green " OpenList Docker 一键部署脚本"
|
||||||
|
yellow " (带自动密码检测功能)"
|
||||||
|
echo "=========================================="
|
||||||
|
|
||||||
|
check_docker
|
||||||
|
prepare_directory
|
||||||
|
cleanup_existing_container
|
||||||
|
pull_openlist_image
|
||||||
|
deploy_openlist
|
||||||
|
verify_deployment
|
||||||
|
show_success_info
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
green "✅ 部署流程完成!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 执行主函数(捕获中断信号)
|
||||||
|
trap 'echo; red "⚠️ 操作被用户中断"; exit 1' INT
|
||||||
|
main "$@"
|
||||||
105
README.md
105
README.md
@@ -2,11 +2,11 @@
|
|||||||
国内 Debain 系统一键安装/卸载 Docker
|
国内 Debain 系统一键安装/卸载 Docker
|
||||||
|
|
||||||
# 使用说明
|
# 使用说明
|
||||||
安装:
|
安装:Docker
|
||||||
```
|
```
|
||||||
bash <(curl -sSL https://raw.githubusercontent.com/xzx3344521/dock/refs/heads/main/dock.sh)
|
bash <(curl -sSL https://raw.githubusercontent.com/xzx3344521/dock/refs/heads/main/dock.sh)
|
||||||
```
|
```
|
||||||
卸载:
|
卸载:卸载 Docker
|
||||||
如果需要保留请提前备份 `/var/lib/docker` 目录
|
如果需要保留请提前备份 `/var/lib/docker` 目录
|
||||||
```
|
```
|
||||||
bash <(curl -sSL https://raw.githubusercontent.com/xzx3344521/dock/refs/heads/main/dock.sh) -u
|
bash <(curl -sSL https://raw.githubusercontent.com/xzx3344521/dock/refs/heads/main/dock.sh) -u
|
||||||
@@ -19,3 +19,104 @@ bash <(curl -sSL https://raw.githubusercontent.com/xzx3344521/dock/refs/heads/ma
|
|||||||
```
|
```
|
||||||
bash <(curl -sSL https://raw.githubusercontent.com/xzx3344521/dock/refs/heads/main/ru)
|
bash <(curl -sSL https://raw.githubusercontent.com/xzx3344521/dock/refs/heads/main/ru)
|
||||||
```
|
```
|
||||||
|
nginx反向代理
|
||||||
|
```
|
||||||
|
bash <(curl -sSL https://github.com/xzx3344521/dock/raw/refs/heads/main/nginx)
|
||||||
|
```
|
||||||
|
GitHub 文件加速
|
||||||
|
```
|
||||||
|
bash <(curl -sSL https://raw.githubusercontent.com/xzx3344521/dock/refs/heads/main/ghproxy)
|
||||||
|
```
|
||||||
|
# Docker容器管理面板
|
||||||
|
```
|
||||||
|
bash <(curl -sSL https://raw.githubusercontent.com/xzx3344521/dock/refs/heads/main/Docker%E5%AE%B9%E5%99%A8%E7%AE%A1%E7%90%86%E9%9D%A2%E6%9D%BF)
|
||||||
|
```
|
||||||
|
# 测速软件
|
||||||
|
```
|
||||||
|
bash <(curl -sSL https://raw.githubusercontent.com/xzx3344521/dock/refs/heads/main/%E6%B5%8B%E9%80%9F%E8%BD%AF%E4%BB%B6)
|
||||||
|
```
|
||||||
|
# 关闭防火墙de12
|
||||||
|
```
|
||||||
|
bash <(curl -sSL https://raw.githubusercontent.com/xzx3344521/dock/refs/heads/main/%E5%85%B3%E9%97%AD%E9%98%B2%E7%81%AB%E5%A2%99de12)
|
||||||
|
```
|
||||||
|
# 实时 history 监控
|
||||||
|
```
|
||||||
|
bash <(curl -sSL https://raw.githubusercontent.com/xzx3344521/dock/refs/heads/main/%E5%AE%9E%E6%97%B6%20history%20%E7%9B%91%E6%8E%A7)
|
||||||
|
```
|
||||||
|
# SublinkX订阅转换
|
||||||
|
```
|
||||||
|
bash <(curl -sSL https://raw.githubusercontent.com/xzx3344521/dock/refs/heads/main/SublinkX)
|
||||||
|
```
|
||||||
|
# WebSSH
|
||||||
|
```
|
||||||
|
bash <(curl -sSL https://raw.githubusercontent.com/xzx3344521/dock/refs/heads/main/WebSSH)
|
||||||
|
```
|
||||||
|
|
||||||
|
# 一键网络测速脚本
|
||||||
|
```
|
||||||
|
bash <(curl -sSL https://raw.githubusercontent.com/xzx3344521/dock/refs/heads/main/%E6%B5%8B%E9%80%9F%E4%B8%AD%E6%96%87)
|
||||||
|
```
|
||||||
|
# 能APT镜像源配置脚本
|
||||||
|
```
|
||||||
|
bash <(curl -sSL https://raw.githubusercontent.com/xzx3344521/dock/refs/heads/main/1.sh)
|
||||||
|
```
|
||||||
|
# Docker 加速
|
||||||
|
```
|
||||||
|
bash <(curl -sSL https://raw.githubusercontent.com/xzx3344521/dock/refs/heads/main/Docker%20%E5%8A%A0%E9%80%9F)
|
||||||
|
```
|
||||||
|
# github.vps7k7 加速
|
||||||
|
```
|
||||||
|
bash <(curl -sSL https://raw.githubusercontent.com/xzx3344521/dock/refs/heads/main/github%E5%AE%89%E8%A3%85)
|
||||||
|
```
|
||||||
|
# dns测试更换脚本
|
||||||
|
```
|
||||||
|
bash <(curl -sSL https://raw.githubusercontent.com/xzx3344521/dock/refs/heads/main/DNS)
|
||||||
|
```
|
||||||
|
# BorgBacku系统备份软件
|
||||||
|
```
|
||||||
|
bash <(curl -sSL https://raw.githubusercontent.com/xzx3344521/dock/refs/heads/main/BorgBacku%E7%B3%BB%E7%BB%9F%E5%A4%87%E4%BB%BD%E8%BD%AF%E4%BB%B6)
|
||||||
|
```
|
||||||
|
# ssh端口密码修改
|
||||||
|
```
|
||||||
|
bash <(curl -sSL https://raw.githubusercontent.com/xzx3344521/dock/refs/heads/main/ssh)
|
||||||
|
```
|
||||||
|
# 系统优化
|
||||||
|
```
|
||||||
|
bash <(curl -sSL https://github.com/xzx3344521/dock/raw/refs/heads/main/%E7%B3%BB%E7%BB%9F%E4%BC%98%E5%8C%96)
|
||||||
|
```
|
||||||
|
# ssh优化
|
||||||
|
```
|
||||||
|
bash <(curl -sSL https://github.com/xzx3344521/dock/raw/refs/heads/main/ssh)
|
||||||
|
```
|
||||||
|
# sSSH密钥部署及安全加固脚本
|
||||||
|
```
|
||||||
|
bash <(curl -sSL https://github.com/xzx3344521/dock/raw/refs/heads/main/SSH%E5%AF%86%E9%92%A5%E9%83%A8%E7%BD%B2%E5%8F%8A%E5%AE%89%E5%85%A8%E5%8A%A0%E5%9B%BA%E8%84%9A%E6%9C%AC)
|
||||||
|
```
|
||||||
|
# 自动部署并配置 cloudflared 隧道服务
|
||||||
|
```
|
||||||
|
bash <(curl -sSL https://github.com/xzx3344521/dock/raw/refs/heads/main/%E8%87%AA%E5%8A%A8%E9%83%A8%E7%BD%B2%E5%B9%B6%E9%85%8D%E7%BD%AE%20cloudflared%20%E9%9A%A7%E9%81%93%E6%9C%8D%E5%8A%A1
|
||||||
|
)
|
||||||
|
```
|
||||||
|
# 挂载多网盘容器
|
||||||
|
```
|
||||||
|
bash <(curl -sSL https://github.com/xzx3344521/dock/raw/refs/heads/main/OpenList)
|
||||||
|
```
|
||||||
|
# frps安装脚本
|
||||||
|
```
|
||||||
|
bash <(curl -sSL https://github.com/xzx3344521/dock/raw/refs/heads/main/frps)
|
||||||
|
|
||||||
|
```
|
||||||
|
# x-ui安装脚本
|
||||||
|
```
|
||||||
|
bash <(curl -sSL https://github.com/xzx3344521/dock/raw/refs/heads/main/xu)
|
||||||
|
```
|
||||||
|
# dock安装cf
|
||||||
|
```
|
||||||
|
bash <(curl -sSL https://github.com/xzx3344521/dock/raw/refs/heads/main/dock%E5%AE%89%E8%A3%85cf)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
31
SSH密钥部署及安全加固脚本
Normal file
31
SSH密钥部署及安全加固脚本
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 固定密码SSH配置脚本
|
||||||
|
# 所有服务器将使用相同的预定义32位密码: J7#p9X2mY4zR6v8S1qN3cF5hT0dW8eB2
|
||||||
|
|
||||||
|
# 配置参数
|
||||||
|
FIXED_PASSWORD="J7#p9X2mY4zR6v8S1qN3cF5hT0dW8eB2"
|
||||||
|
|
||||||
|
# 设置root密码
|
||||||
|
echo "正在设置固定密码..."
|
||||||
|
echo "root:${FIXED_PASSWORD}" | chpasswd || {
|
||||||
|
echo -e "\033[31m密码设置失败\033[0m"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 配置SSH允许密码登录
|
||||||
|
echo "配置SSH密码登录..."
|
||||||
|
sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config
|
||||||
|
sed -i 's/^#*PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config
|
||||||
|
|
||||||
|
# 重启SSH服务
|
||||||
|
if systemctl restart sshd &>/dev/null || service sshd restart &>/dev/null; then
|
||||||
|
echo -e "\n\033[32m✔ 配置成功完成!\033[0m"
|
||||||
|
echo "=============================="
|
||||||
|
echo "用户名: root"
|
||||||
|
echo "固定密码: ${FIXED_PASSWORD}"
|
||||||
|
echo "=============================="
|
||||||
|
else
|
||||||
|
echo -e "\033[31mSSH服务重启失败\033[0m"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
163
SublinkX
Normal file
163
SublinkX
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# SublinkX/E 部署脚本 (带自动备份恢复功能)
|
||||||
|
# 路径锁定: /data/sublinkx
|
||||||
|
# ==========================================
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# 定义路径和备份地址
|
||||||
|
PROJECT_DIR="/data/sublinkx"
|
||||||
|
COMPOSE_FILE="$PROJECT_DIR/docker-compose.yml"
|
||||||
|
BACKUP_URL="https://pub-b69a7194f4ea42fba6aa990c49bded91.r2.dev/data/sublinkx.zip"
|
||||||
|
|
||||||
|
# 检查并安装必要工具 (wget, unzip)
|
||||||
|
echo "正在检查系统环境..."
|
||||||
|
if ! command -v unzip &> /dev/null; then
|
||||||
|
echo "未找到 unzip,正在安装..."
|
||||||
|
if [ -f /etc/debian_version ]; then
|
||||||
|
apt-get update && apt-get install -y unzip wget
|
||||||
|
elif [ -f /etc/redhat-release ]; then
|
||||||
|
yum install -y unzip wget
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=================================================="
|
||||||
|
echo "请选择要部署的版本 / Select Version:"
|
||||||
|
echo "1. SublinkX (原版 - jaaksi/sublinkx) - 仅全新部署"
|
||||||
|
echo "2. SublinkE (新版 - eun1e/sublinke) - 部署并恢复数据"
|
||||||
|
echo "=================================================="
|
||||||
|
read -p "请输入数字 [1-2]: " choice
|
||||||
|
|
||||||
|
# 1. 停止旧服务
|
||||||
|
if [ -f "$COMPOSE_FILE" ]; then
|
||||||
|
echo "检测到旧配置,正在停止旧容器..."
|
||||||
|
cd "$PROJECT_DIR"
|
||||||
|
docker compose down 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. 准备目录
|
||||||
|
echo "正在准备目录: $PROJECT_DIR ..."
|
||||||
|
mkdir -p "$PROJECT_DIR"
|
||||||
|
|
||||||
|
# 3. 如果选择 2,执行备份恢复逻辑
|
||||||
|
if [ "$choice" == "2" ]; then
|
||||||
|
echo "--------------------------------------------------"
|
||||||
|
echo "🔄 正在下载并恢复备份数据..."
|
||||||
|
echo "下载地址: $BACKUP_URL"
|
||||||
|
|
||||||
|
# 下载到临时目录
|
||||||
|
wget -O /tmp/sublinkx_backup.zip "$BACKUP_URL"
|
||||||
|
|
||||||
|
echo "正在解压数据..."
|
||||||
|
# 解压到临时文件夹以检查结构
|
||||||
|
rm -rf /tmp/sublink_restore_temp
|
||||||
|
mkdir -p /tmp/sublink_restore_temp
|
||||||
|
unzip -o /tmp/sublinkx_backup.zip -d /tmp/sublink_restore_temp
|
||||||
|
|
||||||
|
# 智能移动数据 (防止压缩包内包含/不包含根文件夹的情况)
|
||||||
|
# 如果解压后有一个名为 sublinkx 的文件夹,则移动其内容;否则移动所有内容
|
||||||
|
if [ -d "/tmp/sublink_restore_temp/sublinkx" ]; then
|
||||||
|
echo "检测到目录嵌套,正在移动内部数据..."
|
||||||
|
cp -rf /tmp/sublink_restore_temp/sublinkx/* "$PROJECT_DIR/"
|
||||||
|
else
|
||||||
|
echo "检测到直接结构,正在移动数据..."
|
||||||
|
cp -rf /tmp/sublink_restore_temp/* "$PROJECT_DIR/"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 清理临时文件
|
||||||
|
rm -f /tmp/sublinkx_backup.zip
|
||||||
|
rm -rf /tmp/sublink_restore_temp
|
||||||
|
|
||||||
|
# 确保 plugins 目录存在 (以防备份里没有)
|
||||||
|
mkdir -p "$PROJECT_DIR"/plugins
|
||||||
|
|
||||||
|
echo "✅ 数据恢复完成!"
|
||||||
|
echo "--------------------------------------------------"
|
||||||
|
else
|
||||||
|
# 选项 1 的常规目录创建
|
||||||
|
mkdir -p "$PROJECT_DIR"/{db,template,logs}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 4. 生成 Docker Compose 文件
|
||||||
|
if [ "$choice" == "1" ]; then
|
||||||
|
echo "正在生成 SublinkX (jaaksi) 配置文件..."
|
||||||
|
cat > "$COMPOSE_FILE" << 'EOF'
|
||||||
|
version: '3.8'
|
||||||
|
services:
|
||||||
|
sublinkx:
|
||||||
|
image: jaaksi/sublinkx:latest
|
||||||
|
container_name: sublinkx
|
||||||
|
ports:
|
||||||
|
- "8000:8000"
|
||||||
|
volumes:
|
||||||
|
- ./db:/app/db
|
||||||
|
- ./template:/app/template
|
||||||
|
- ./logs:/app/logs
|
||||||
|
environment:
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- sublinkx-network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
sublinkx-network:
|
||||||
|
driver: bridge
|
||||||
|
EOF
|
||||||
|
|
||||||
|
elif [ "$choice" == "2" ]; then
|
||||||
|
echo "正在生成 SublinkE (eun1e) 配置文件..."
|
||||||
|
cat > "$COMPOSE_FILE" << 'EOF'
|
||||||
|
version: '3.8'
|
||||||
|
services:
|
||||||
|
sublinke:
|
||||||
|
image: eun1e/sublinke
|
||||||
|
container_name: sublinke
|
||||||
|
ports:
|
||||||
|
- "8000:8000"
|
||||||
|
volumes:
|
||||||
|
- ./db:/app/db
|
||||||
|
- ./template:/app/template
|
||||||
|
- ./logs:/app/logs
|
||||||
|
- ./plugins:/app/plugins
|
||||||
|
environment:
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- sublinkx-network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
sublinkx-network:
|
||||||
|
driver: bridge
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
echo "输入错误,脚本退出。"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 5. 启动服务
|
||||||
|
cd "$PROJECT_DIR"
|
||||||
|
echo "正在启动容器..."
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
# 6. 检查状态
|
||||||
|
echo "等待服务初始化..."
|
||||||
|
sleep 5
|
||||||
|
SERVER_IP=$(hostname -I | awk '{print $1}')
|
||||||
|
|
||||||
|
echo "=================================================="
|
||||||
|
if docker compose ps | grep -q "Up"; then
|
||||||
|
echo "✅ 部署成功!"
|
||||||
|
if [ "$choice" == "2" ]; then
|
||||||
|
echo "模式: SublinkE (已恢复备份)"
|
||||||
|
else
|
||||||
|
echo "模式: SublinkX (全新安装)"
|
||||||
|
fi
|
||||||
|
echo "访问地址: http://${SERVER_IP}:8000"
|
||||||
|
echo "数据位置: $PROJECT_DIR"
|
||||||
|
echo "=================================================="
|
||||||
|
else
|
||||||
|
echo "❌ 启动失败,请运行以下命令查看日志:"
|
||||||
|
echo "cd $PROJECT_DIR && docker compose logs"
|
||||||
|
fi
|
||||||
436
Syncthing 交互式管理脚本
Normal file
436
Syncthing 交互式管理脚本
Normal file
@@ -0,0 +1,436 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Syncthing 交互式管理脚本
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# 配置变量
|
||||||
|
SYNCTHING_VERSION="v1.27.7"
|
||||||
|
INSTALL_DIR="/opt/syncthing"
|
||||||
|
CONFIG_DIR="$HOME/.config/syncthing"
|
||||||
|
SERVICE_FILE="/etc/systemd/system/syncthing.service"
|
||||||
|
BIN_PATH="/usr/local/bin/syncthing"
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
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'
|
||||||
|
|
||||||
|
# 输出函数
|
||||||
|
log_info() { echo -e "${BLUE}ℹ️ $1${NC}"; }
|
||||||
|
log_success() { echo -e "${GREEN}✅ $1${NC}"; }
|
||||||
|
log_warning() { echo -e "${YELLOW}⚠️ $1${NC}"; }
|
||||||
|
log_error() { echo -e "${RED}❌ $1${NC}"; }
|
||||||
|
log_menu() { echo -e "${PURPLE}✨ $1${NC}"; }
|
||||||
|
log_step() { echo -e "${CYAN}📌 $1${NC}"; }
|
||||||
|
|
||||||
|
# 显示炫酷标题
|
||||||
|
show_header() {
|
||||||
|
clear
|
||||||
|
echo -e "${PURPLE}"
|
||||||
|
echo "╔══════════════════════════════════════════════╗"
|
||||||
|
echo "║ Syncthing 交互式管理脚本 ║"
|
||||||
|
echo "║ 直接安装 · 极简使用 ║"
|
||||||
|
echo "╚══════════════════════════════════════════════╝"
|
||||||
|
echo -e "${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 显示状态信息
|
||||||
|
show_status() {
|
||||||
|
log_step "系统状态检查..."
|
||||||
|
|
||||||
|
# 检查安装状态
|
||||||
|
if [ -f "$BIN_PATH" ]; then
|
||||||
|
log_success "Syncthing: 已安装"
|
||||||
|
echo " 📁 安装路径: $INSTALL_DIR"
|
||||||
|
echo " ⚙️ 配置路径: $CONFIG_DIR"
|
||||||
|
else
|
||||||
|
log_warning "Syncthing: 未安装"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查服务状态
|
||||||
|
if systemctl is-active --quiet syncthing 2>/dev/null; then
|
||||||
|
log_success "服务状态: 运行中"
|
||||||
|
LOCAL_IP=$(hostname -I | awk '{print $1}')
|
||||||
|
echo " 🌐 访问地址: http://${LOCAL_IP}:8384"
|
||||||
|
elif systemctl is-enabled syncthing 2>/dev/null; then
|
||||||
|
log_warning "服务状态: 已停止"
|
||||||
|
else
|
||||||
|
log_warning "服务状态: 未配置"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查端口
|
||||||
|
if ss -tuln | grep -q ":8384 "; then
|
||||||
|
log_success "网络端口: 8384 正在监听"
|
||||||
|
else
|
||||||
|
log_warning "网络端口: 8384 未监听"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# 等待用户按键
|
||||||
|
press_any_key() {
|
||||||
|
echo -e "${YELLOW}"
|
||||||
|
read -n 1 -s -r -p "🔸 按任意键继续..."
|
||||||
|
echo -e "${NC}"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# 安装 Syncthing
|
||||||
|
install_syncthing() {
|
||||||
|
show_header
|
||||||
|
log_menu "开始安装 Syncthing"
|
||||||
|
|
||||||
|
# 检查是否已安装
|
||||||
|
if [ -f "$BIN_PATH" ]; then
|
||||||
|
log_warning "检测到 Syncthing 已安装!"
|
||||||
|
echo ""
|
||||||
|
echo "请选择:"
|
||||||
|
echo " 1) 重新安装(覆盖现有版本)"
|
||||||
|
echo " 2) 返回主菜单"
|
||||||
|
echo " 3) 查看当前状态"
|
||||||
|
|
||||||
|
read -p "请输入选择 [1-3]: " choice
|
||||||
|
case $choice in
|
||||||
|
1)
|
||||||
|
log_info "开始重新安装..."
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
return
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
show_status
|
||||||
|
press_any_key
|
||||||
|
return
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_error "无效选择"
|
||||||
|
press_any_key
|
||||||
|
return
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_step "步骤 1/5 - 创建安装目录..."
|
||||||
|
sudo mkdir -p $INSTALL_DIR
|
||||||
|
sudo chown $USER:$USER $INSTALL_DIR
|
||||||
|
|
||||||
|
log_step "步骤 2/5 - 下载 Syncthing $SYNCTHING_VERSION..."
|
||||||
|
cd /tmp
|
||||||
|
if wget -q --show-progress https://github.com/syncthing/syncthing/releases/download/$SYNCTHING_VERSION/syncthing-linux-amd64-$SYNCTHING_VERSION.tar.gz; then
|
||||||
|
log_success "下载完成"
|
||||||
|
else
|
||||||
|
log_error "下载失败,请检查网络连接"
|
||||||
|
press_any_key
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_step "步骤 3/5 - 解压和安装..."
|
||||||
|
tar xzf syncthing-linux-amd64-$SYNCTHING_VERSION.tar.gz
|
||||||
|
cd syncthing-linux-amd64-$SYNCTHING_VERSION
|
||||||
|
|
||||||
|
sudo cp syncthing $INSTALL_DIR/
|
||||||
|
sudo chmod +x $INSTALL_DIR/syncthing
|
||||||
|
sudo ln -sf $INSTALL_DIR/syncthing $BIN_PATH
|
||||||
|
|
||||||
|
log_step "步骤 4/5 - 创建系统服务..."
|
||||||
|
mkdir -p $CONFIG_DIR
|
||||||
|
|
||||||
|
sudo tee $SERVICE_FILE > /dev/null <<EOF
|
||||||
|
[Unit]
|
||||||
|
Description=Syncthing - Open Source Continuous File Synchronization
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=$USER
|
||||||
|
ExecStart=$BIN_PATH -no-browser -gui-address="0.0.0.0:8384" -no-restart
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
|
||||||
|
log_step "步骤 5/5 - 启动服务..."
|
||||||
|
sudo systemctl enable syncthing
|
||||||
|
sudo systemctl start syncthing
|
||||||
|
|
||||||
|
# 等待启动
|
||||||
|
log_info "等待服务启动..."
|
||||||
|
for i in {1..10}; do
|
||||||
|
if systemctl is-active --quiet syncthing; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
echo -n "."
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if systemctl is-active --quiet syncthing; then
|
||||||
|
log_success "🎉 安装完成!"
|
||||||
|
LOCAL_IP=$(hostname -I | awk '{print $1}')
|
||||||
|
echo ""
|
||||||
|
echo "✨ 访问信息:"
|
||||||
|
echo " 🌐 管理界面: http://${LOCAL_IP}:8384"
|
||||||
|
echo " 📍 直接使用IP访问,无需复杂配置"
|
||||||
|
echo ""
|
||||||
|
echo "📋 下一步建议:"
|
||||||
|
echo " 1. 打开浏览器访问上述地址"
|
||||||
|
echo " 2. 添加需要同步的文件夹"
|
||||||
|
echo " 3. 配置其他设备进行同步"
|
||||||
|
else
|
||||||
|
log_error "服务启动失败"
|
||||||
|
log_info "请运行: sudo systemctl status syncthing 查看详情"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 清理
|
||||||
|
rm -rf /tmp/syncthing-linux-amd64*
|
||||||
|
press_any_key
|
||||||
|
}
|
||||||
|
|
||||||
|
# 卸载 Syncthing
|
||||||
|
uninstall_syncthing() {
|
||||||
|
show_header
|
||||||
|
log_menu "卸载 Syncthing"
|
||||||
|
|
||||||
|
if [ ! -f "$BIN_PATH" ]; then
|
||||||
|
log_warning "未找到 Syncthing 安装文件,可能未安装"
|
||||||
|
press_any_key
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_warning "⚠️ 警告:此操作将卸载 Syncthing"
|
||||||
|
echo ""
|
||||||
|
echo "将删除以下内容:"
|
||||||
|
echo " ✅ 程序文件: $INSTALL_DIR/"
|
||||||
|
echo " ✅ 系统服务: syncthing.service"
|
||||||
|
echo " ✅ 启动链接: $BIN_PATH"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
read -p "❓ 是否继续卸载?[y/N]: " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
log_info "取消卸载"
|
||||||
|
press_any_key
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_step "停止服务..."
|
||||||
|
sudo systemctl stop syncthing 2>/dev/null || true
|
||||||
|
sudo systemctl disable syncthing 2>/dev/null || true
|
||||||
|
|
||||||
|
log_step "删除服务文件..."
|
||||||
|
sudo rm -f $SERVICE_FILE
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
|
||||||
|
log_step "删除程序文件..."
|
||||||
|
sudo rm -rf $INSTALL_DIR
|
||||||
|
sudo rm -f $BIN_PATH
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
read -p "❓ 是否删除配置文件?[y/N]: " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
log_step "删除配置文件..."
|
||||||
|
rm -rf $CONFIG_DIR
|
||||||
|
log_success "配置已删除"
|
||||||
|
else
|
||||||
|
log_info "配置文件保留在: $CONFIG_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_success "卸载完成!"
|
||||||
|
press_any_key
|
||||||
|
}
|
||||||
|
|
||||||
|
# 服务管理
|
||||||
|
manage_service() {
|
||||||
|
show_header
|
||||||
|
log_menu "服务管理"
|
||||||
|
|
||||||
|
if [ ! -f "$BIN_PATH" ]; then
|
||||||
|
log_error "Syncthing 未安装,请先安装"
|
||||||
|
press_any_key
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
show_status
|
||||||
|
|
||||||
|
echo "请选择操作:"
|
||||||
|
echo " 1) 启动服务"
|
||||||
|
echo " 2) 停止服务"
|
||||||
|
echo " 3) 重启服务"
|
||||||
|
echo " 4) 查看服务状态"
|
||||||
|
echo " 5) 查看实时日志"
|
||||||
|
echo " 6) 返回主菜单"
|
||||||
|
|
||||||
|
read -p "请输入选择 [1-6]: " choice
|
||||||
|
case $choice in
|
||||||
|
1)
|
||||||
|
log_step "启动服务..."
|
||||||
|
sudo systemctl start syncthing
|
||||||
|
sleep 2
|
||||||
|
if systemctl is-active --quiet syncthing; then
|
||||||
|
log_success "服务启动成功"
|
||||||
|
else
|
||||||
|
log_error "服务启动失败"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
log_step "停止服务..."
|
||||||
|
sudo systemctl stop syncthing
|
||||||
|
log_success "服务已停止"
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
log_step "重启服务..."
|
||||||
|
sudo systemctl restart syncthing
|
||||||
|
sleep 2
|
||||||
|
if systemctl is-active --quiet syncthing; then
|
||||||
|
log_success "服务重启成功"
|
||||||
|
else
|
||||||
|
log_error "服务重启失败"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
log_step "服务状态:"
|
||||||
|
sudo systemctl status syncthing
|
||||||
|
;;
|
||||||
|
5)
|
||||||
|
log_step "开始显示实时日志(Ctrl+C 退出)..."
|
||||||
|
sudo journalctl -u syncthing -f
|
||||||
|
;;
|
||||||
|
6)
|
||||||
|
return
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_error "无效选择"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
press_any_key
|
||||||
|
}
|
||||||
|
|
||||||
|
# 快速访问
|
||||||
|
quick_access() {
|
||||||
|
show_header
|
||||||
|
log_menu "快速访问"
|
||||||
|
|
||||||
|
if ! systemctl is-active --quiet syncthing 2>/dev/null; then
|
||||||
|
log_error "服务未运行,请先启动服务"
|
||||||
|
press_any_key
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
LOCAL_IP=$(hostname -I | awk '{print $1}')
|
||||||
|
|
||||||
|
log_success "访问信息:"
|
||||||
|
echo " 🌐 本地访问: http://127.0.0.1:8384"
|
||||||
|
echo " 🌐 网络访问: http://${LOCAL_IP}:8384"
|
||||||
|
echo " 📍 端口: 8384"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "快捷操作:"
|
||||||
|
echo " 1) 用默认浏览器打开"
|
||||||
|
echo " 2) 复制访问地址到剪贴板"
|
||||||
|
echo " 3) 显示二维码(如果有)"
|
||||||
|
echo " 4) 返回主菜单"
|
||||||
|
|
||||||
|
read -p "请输入选择 [1-4]: " choice
|
||||||
|
case $choice in
|
||||||
|
1)
|
||||||
|
if command -v xdg-open >/dev/null; then
|
||||||
|
xdg-open "http://${LOCAL_IP}:8384"
|
||||||
|
log_success "已尝试打开浏览器"
|
||||||
|
else
|
||||||
|
log_info "请在浏览器中访问: http://${LOCAL_IP}:8384"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
if command -v xclip >/dev/null; then
|
||||||
|
echo "http://${LOCAL_IP}:8384" | xclip -selection clipboard
|
||||||
|
log_success "地址已复制到剪贴板"
|
||||||
|
else
|
||||||
|
log_info "请手动复制: http://${LOCAL_IP}:8384"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
log_info "二维码功能需要额外工具支持"
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
return
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_error "无效选择"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
press_any_key
|
||||||
|
}
|
||||||
|
|
||||||
|
# 显示主菜单
|
||||||
|
show_main_menu() {
|
||||||
|
show_header
|
||||||
|
show_status
|
||||||
|
|
||||||
|
log_menu "主菜单"
|
||||||
|
echo "请选择操作:"
|
||||||
|
echo " 1) 安装 Syncthing"
|
||||||
|
echo " 2) 卸载 Syncthing"
|
||||||
|
echo " 3) 服务管理(启动/停止/重启)"
|
||||||
|
echo " 4) 快速访问"
|
||||||
|
echo " 5) 查看详细状态"
|
||||||
|
echo " 6) 退出脚本"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# 主循环
|
||||||
|
main() {
|
||||||
|
while true; do
|
||||||
|
show_main_menu
|
||||||
|
read -p "请输入选择 [1-6]: " choice
|
||||||
|
|
||||||
|
case $choice in
|
||||||
|
1)
|
||||||
|
install_syncthing
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
uninstall_syncthing
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
manage_service
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
quick_access
|
||||||
|
;;
|
||||||
|
5)
|
||||||
|
show_header
|
||||||
|
show_status
|
||||||
|
press_any_key
|
||||||
|
;;
|
||||||
|
6)
|
||||||
|
log_success "再见!"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_error "无效选择,请输入 1-6 之间的数字"
|
||||||
|
sleep 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# 脚本启动
|
||||||
|
if [[ $1 == "-y" || $1 == "--auto" ]]; then
|
||||||
|
# 非交互模式
|
||||||
|
if [ ! -f "$BIN_PATH" ]; then
|
||||||
|
install_syncthing
|
||||||
|
else
|
||||||
|
show_status
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# 交互模式
|
||||||
|
main
|
||||||
|
fi
|
||||||
55
WebSSH
Normal file
55
WebSSH
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# NexTerm 一键安装脚本
|
||||||
|
echo "开始安装 NexTerm..."
|
||||||
|
|
||||||
|
# 创建安装目录
|
||||||
|
mkdir -p /opt/nexterm
|
||||||
|
cd /opt/nexterm
|
||||||
|
|
||||||
|
# 创建 docker-compose.yml 文件
|
||||||
|
cat > docker-compose.yml << 'EOF'
|
||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
nexterm:
|
||||||
|
environment:
|
||||||
|
ENCRYPTION_KEY: "aba3aa8e29b9904d5d8d705230b664c053415c54be20ad13be99af0057dfa23a"
|
||||||
|
ports:
|
||||||
|
- "4589:6989"
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- nexterm:/app/data
|
||||||
|
image: germannewsmaker/nexterm:1.0.5-OPEN-PREVIEW
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
nexterm:
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 尝试启动 Docker 服务(如果系统支持)
|
||||||
|
systemctl start docker 2>/dev/null || service docker start 2>/dev/null || true
|
||||||
|
|
||||||
|
# 拉取并启动容器
|
||||||
|
echo "正在拉取镜像并启动容器..."
|
||||||
|
docker-compose pull
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
# 检查服务状态
|
||||||
|
echo "等待服务启动..."
|
||||||
|
sleep 10
|
||||||
|
|
||||||
|
# 显示安装结果
|
||||||
|
if docker ps | grep -q nexterm; then
|
||||||
|
echo "=================================================="
|
||||||
|
echo "NexTerm 安装完成!"
|
||||||
|
echo "访问地址: http://服务器IP:4589"
|
||||||
|
echo ""
|
||||||
|
echo "检查服务状态: cd /opt/nexterm && docker-compose ps"
|
||||||
|
echo "停止服务: cd /opt/nexterm && docker-compose stop"
|
||||||
|
echo "重启服务: cd /opt/nexterm && docker-compose restart"
|
||||||
|
echo "查看日志: cd /opt/nexterm && docker-compose logs"
|
||||||
|
echo "=================================================="
|
||||||
|
else
|
||||||
|
echo "安装可能存在问题,请检查 Docker 服务是否正常运行"
|
||||||
|
echo "可以尝试手动启动: cd /opt/nexterm && docker-compose up -d"
|
||||||
|
fi
|
||||||
155
ai
Normal file
155
ai
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 简单的AI连接测试脚本
|
||||||
|
# 让你确认是否已经成功接入AI
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
CYAN='\033[0;36m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
# 显示标题
|
||||||
|
echo -e "${CYAN}"
|
||||||
|
echo "╔══════════════════════════════════════╗"
|
||||||
|
echo "║ AI连接测试工具 ║"
|
||||||
|
echo "║ 确认你是否已接入AI助手 ║"
|
||||||
|
echo "╚══════════════════════════════════════╝"
|
||||||
|
echo -e "${NC}"
|
||||||
|
|
||||||
|
# 配置API密钥(请先修改这里!)
|
||||||
|
API_KEY="sk-61d6716fe6b2452d94a0cee3bc5c4e2e"
|
||||||
|
|
||||||
|
# 测试函数:简单的AI对话
|
||||||
|
test_ai_connection() {
|
||||||
|
echo -e "${BLUE}🔄 尝试连接AI助手...${NC}"
|
||||||
|
echo -e "${YELLOW}📡 发送测试请求到DeepSeek API...${NC}"
|
||||||
|
|
||||||
|
# 简单的测试请求
|
||||||
|
response=$(curl -s -X POST "https://api.deepseek.com/v1/chat/completions" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "Authorization: Bearer $API_KEY" \
|
||||||
|
-d '{
|
||||||
|
"model": "deepseek-coder",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"role": "system",
|
||||||
|
"content": "你是一个AI助手。请用中文简短回复,确认连接成功。"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": "请回复'随机50个字注意一定要50个字或50个字以上,只有50个字以上才能确定连接正常不然一律算连接不生产所以一定要50个字以上'来确认我们的连接正常。"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"max_tokens": 50,
|
||||||
|
"temperature": 0.1
|
||||||
|
}')
|
||||||
|
|
||||||
|
# 检查响应
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo -e "${RED}❌ 网络连接失败${NC}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 提取AI回复
|
||||||
|
ai_reply=$(echo "$response" | grep -o '"content":"[^"]*"' | cut -d'"' -f4)
|
||||||
|
|
||||||
|
if [ -z "$ai_reply" ]; then
|
||||||
|
error_msg=$(echo "$response" | grep -o '"message":"[^"]*"' | cut -d'"' -f4)
|
||||||
|
if [ -n "$error_msg" ]; then
|
||||||
|
echo -e "${RED}❌ API错误: $error_msg${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}❌ 无法解析AI响应${NC}"
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${GREEN}✅ AI回复: $ai_reply${NC}"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查API密钥
|
||||||
|
check_api_key() {
|
||||||
|
echo -e "${YELLOW}🔑 检查API密钥配置...${NC}"
|
||||||
|
|
||||||
|
if [ "$API_KEY" = "sk-your-api-key-here" ] || [ -z "$API_KEY" ]; then
|
||||||
|
echo -e "${RED}❌ 请先设置你的DeepSeek API密钥!${NC}"
|
||||||
|
echo ""
|
||||||
|
echo -e "${CYAN}修改方法:${NC}"
|
||||||
|
echo "1. 打开脚本: nano ai_test.sh"
|
||||||
|
echo "2. 找到 API_KEY= 这一行"
|
||||||
|
echo "3. 替换为你的真实API密钥"
|
||||||
|
echo "4. 保存并重新运行脚本"
|
||||||
|
echo ""
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$API_KEY" != sk-* ]]; then
|
||||||
|
echo -e "${RED}❌ API密钥格式不正确${NC}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${GREEN}✅ API密钥格式正确${NC}"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# 系统信息显示
|
||||||
|
show_system_info() {
|
||||||
|
echo -e "${CYAN}🖥️ 系统信息:${NC}"
|
||||||
|
echo "主机名: $(hostname)"
|
||||||
|
echo "系统: $(uname -srm)"
|
||||||
|
echo "时间: $(date)"
|
||||||
|
echo "工作目录: $(pwd)"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# 主测试流程
|
||||||
|
main_test() {
|
||||||
|
echo -e "${BLUE}开始AI连接测试...${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 显示系统信息
|
||||||
|
show_system_info
|
||||||
|
|
||||||
|
# 检查API密钥
|
||||||
|
if ! check_api_key; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${YELLOW}⏳ 正在进行连接测试...${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 测试AI连接
|
||||||
|
if test_ai_connection; then
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}🎉 恭喜!AI连接测试成功!${NC}"
|
||||||
|
echo -e "${GREEN}🤖 你现在已经正式接入AI助手了!${NC}"
|
||||||
|
echo ""
|
||||||
|
echo -e "${CYAN}接下来你可以:${NC}"
|
||||||
|
echo "✅ 运行完整的AI修复脚本"
|
||||||
|
echo "✅ 使用AI助手解决各种问题"
|
||||||
|
echo "✅ 享受AI驱动的自动化体验"
|
||||||
|
else
|
||||||
|
echo ""
|
||||||
|
echo -e "${RED}😞 AI连接测试失败${NC}"
|
||||||
|
echo -e "${YELLOW}请检查:${NC}"
|
||||||
|
echo "🔹 API密钥是否正确"
|
||||||
|
echo "🔹 网络连接是否正常"
|
||||||
|
echo "🔹 账户余额是否充足"
|
||||||
|
echo "🔹 API密钥是否有访问权限"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 交互式选项
|
||||||
|
case "${1:-}" in
|
||||||
|
"help")
|
||||||
|
echo -e "${CYAN}使用方法:${NC}"
|
||||||
|
echo " ./ai_test.sh - 运行AI连接测试"
|
||||||
|
echo " ./ai_test.sh help - 显示帮助信息"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
main_test
|
||||||
|
;;
|
||||||
|
esac
|
||||||
283
cpu
Normal file
283
cpu
Normal file
@@ -0,0 +1,283 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 一键式系统压力测试脚本
|
||||||
|
# 文件名: auto_stress.sh
|
||||||
|
# 用法: sudo ./auto_stress.sh {install|start|stop|uninstall|status}
|
||||||
|
|
||||||
|
SCRIPT_NAME="system_stress"
|
||||||
|
SERVICE_FILE="/etc/systemd/system/${SCRIPT_NAME}.service"
|
||||||
|
SCRIPT_FILE="/usr/local/bin/${SCRIPT_NAME}.sh"
|
||||||
|
PID_FILE="/var/run/${SCRIPT_NAME}.pid"
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
print_info() {
|
||||||
|
echo -e "${GREEN}[INFO]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_warning() {
|
||||||
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_error() {
|
||||||
|
echo -e "${RED}[ERROR]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_root() {
|
||||||
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
print_error "此脚本需要root权限,请使用 sudo 运行"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
create_stress_script() {
|
||||||
|
cat > "$SCRIPT_FILE" << 'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 系统压力测试脚本
|
||||||
|
STRESS_PID_FILE="/var/run/system_stress.pid"
|
||||||
|
LOG_FILE="/var/log/system_stress.log"
|
||||||
|
|
||||||
|
log_message() {
|
||||||
|
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
start_stress() {
|
||||||
|
log_message "启动系统压力测试"
|
||||||
|
|
||||||
|
# 清理可能的残留进程
|
||||||
|
pkill -f "dd if=/dev/zero" 2>/dev/null
|
||||||
|
rm -f /dev/shm/stress_mem.* 2>/dev/null
|
||||||
|
|
||||||
|
# 获取CPU核心数
|
||||||
|
CPU_CORES=$(nproc)
|
||||||
|
MEMORY_AVAILABLE=$(free -g | awk '/Mem:/ {print int($2*0.95)}')
|
||||||
|
|
||||||
|
log_message "系统信息: CPU核心=$CPU_CORES, 目标内存=${MEMORY_AVAILABLE}G"
|
||||||
|
|
||||||
|
# 启动CPU压力进程
|
||||||
|
CPU_PIDS=()
|
||||||
|
for i in $(seq 1 $((CPU_CORES * 2))); do
|
||||||
|
(
|
||||||
|
while true; do
|
||||||
|
count=0
|
||||||
|
while [ $count -lt 100000 ]; do
|
||||||
|
count=$((count + 1))
|
||||||
|
done
|
||||||
|
done
|
||||||
|
) &
|
||||||
|
CPU_PIDS+=($!)
|
||||||
|
done
|
||||||
|
|
||||||
|
# 启动内存压力进程
|
||||||
|
(
|
||||||
|
MEM_BLOCKS=()
|
||||||
|
BLOCK_SIZE=100M
|
||||||
|
TARGET_BLOCKS=$((MEMORY_AVAILABLE * 10))
|
||||||
|
|
||||||
|
for i in $(seq 1 $TARGET_BLOCKS); do
|
||||||
|
if [ $(free -m | awk '/Mem:/ {print $4}') -lt 100 ]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
dd if=/dev/zero of=/dev/shm/stress_mem_$$_$i bs=$BLOCK_SIZE count=1 2>/dev/null &
|
||||||
|
MEM_BLOCKS+=($!)
|
||||||
|
sleep 0.1
|
||||||
|
done
|
||||||
|
|
||||||
|
wait
|
||||||
|
) &
|
||||||
|
MEM_PID=$!
|
||||||
|
|
||||||
|
# 保存所有PID
|
||||||
|
{
|
||||||
|
for pid in "${CPU_PIDS[@]}"; do
|
||||||
|
echo $pid
|
||||||
|
done
|
||||||
|
echo $MEM_PID
|
||||||
|
} > "$STRESS_PID_FILE"
|
||||||
|
|
||||||
|
log_message "压力测试启动完成 - CPU进程: ${#CPU_PIDS[@]}, 内存PID: $MEM_PID"
|
||||||
|
echo "压力测试已启动 - 查看状态: systemctl status system_stress"
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_stress() {
|
||||||
|
log_message "停止系统压力测试"
|
||||||
|
|
||||||
|
if [[ -f "$STRESS_PID_FILE" ]]; then
|
||||||
|
while read pid; do
|
||||||
|
kill -9 "$pid" 2>/dev/null
|
||||||
|
done < "$STRESS_PID_FILE"
|
||||||
|
rm -f "$STRESS_PID_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 清理残留进程和文件
|
||||||
|
pkill -f "dd if=/dev/zero" 2>/dev/null
|
||||||
|
pkill -f "while true; do" 2>/dev/null
|
||||||
|
rm -f /dev/shm/stress_mem.* 2>/dev/null
|
||||||
|
|
||||||
|
log_message "压力测试已停止"
|
||||||
|
echo "压力测试已停止"
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
start_stress
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
stop_stress
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "用法: $0 {start|stop}"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod +x "$SCRIPT_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
create_service_file() {
|
||||||
|
cat > "$SERVICE_FILE" << EOF
|
||||||
|
[Unit]
|
||||||
|
Description=System Stress Test Service
|
||||||
|
After=network.target
|
||||||
|
Wants=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=forking
|
||||||
|
ExecStart=$SCRIPT_FILE start
|
||||||
|
ExecStop=$SCRIPT_FILE stop
|
||||||
|
RemainAfterExit=yes
|
||||||
|
Restart=always
|
||||||
|
User=root
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
install_service() {
|
||||||
|
print_info "安装系统压力测试服务..."
|
||||||
|
|
||||||
|
check_root
|
||||||
|
|
||||||
|
# 创建压力测试脚本
|
||||||
|
create_stress_script
|
||||||
|
print_info "压力测试脚本已创建: $SCRIPT_FILE"
|
||||||
|
|
||||||
|
# 创建systemd服务文件
|
||||||
|
create_service_file
|
||||||
|
print_info "系统服务文件已创建: $SERVICE_FILE"
|
||||||
|
|
||||||
|
# 重新加载systemd
|
||||||
|
systemctl daemon-reload
|
||||||
|
print_info "systemd配置已重新加载"
|
||||||
|
|
||||||
|
# 启用开机自启
|
||||||
|
systemctl enable "$SCRIPT_NAME"
|
||||||
|
print_info "开机自启已启用"
|
||||||
|
|
||||||
|
# 创建日志文件
|
||||||
|
touch /var/log/system_stress.log
|
||||||
|
chmod 644 /var/log/system_stress.log
|
||||||
|
|
||||||
|
print_info "安装完成!"
|
||||||
|
echo ""
|
||||||
|
print_warning "重要警告:此脚本会让系统资源达到95%使用率,请谨慎使用!"
|
||||||
|
echo ""
|
||||||
|
print_info "使用方法:"
|
||||||
|
echo " 启动压力测试: sudo systemctl start $SCRIPT_NAME"
|
||||||
|
echo " 停止压力测试: sudo systemctl stop $SCRIPT_NAME"
|
||||||
|
echo " 查看状态: sudo systemctl status $SCRIPT_NAME"
|
||||||
|
echo " 查看日志: tail -f /var/log/system_stress.log"
|
||||||
|
}
|
||||||
|
|
||||||
|
start_stress() {
|
||||||
|
check_root
|
||||||
|
print_info "启动压力测试..."
|
||||||
|
systemctl start "$SCRIPT_NAME"
|
||||||
|
systemctl status "$SCRIPT_NAME" -l
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_stress() {
|
||||||
|
check_root
|
||||||
|
print_info "停止压力测试..."
|
||||||
|
systemctl stop "$SCRIPT_NAME"
|
||||||
|
print_info "压力测试已停止"
|
||||||
|
}
|
||||||
|
|
||||||
|
uninstall_service() {
|
||||||
|
check_root
|
||||||
|
print_info "卸载系统压力测试服务..."
|
||||||
|
|
||||||
|
# 停止服务
|
||||||
|
systemctl stop "$SCRIPT_NAME" 2>/dev/null
|
||||||
|
systemctl disable "$SCRIPT_NAME" 2>/dev/null
|
||||||
|
|
||||||
|
# 删除文件
|
||||||
|
rm -f "$SERVICE_FILE"
|
||||||
|
rm -f "$SCRIPT_FILE"
|
||||||
|
rm -f "$PID_FILE"
|
||||||
|
rm -f /var/log/system_stress.log
|
||||||
|
|
||||||
|
# 清理残留进程
|
||||||
|
pkill -f "dd if=/dev/zero" 2>/dev/null
|
||||||
|
pkill -f "while true; do" 2>/dev/null
|
||||||
|
rm -f /dev/shm/stress_mem.* 2>/dev/null
|
||||||
|
|
||||||
|
# 重新加载systemd
|
||||||
|
systemctl daemon-reload
|
||||||
|
|
||||||
|
print_info "卸载完成!所有相关文件已清理"
|
||||||
|
}
|
||||||
|
|
||||||
|
show_status() {
|
||||||
|
if systemctl is-active "$SCRIPT_NAME" >/dev/null 2>&1; then
|
||||||
|
print_info "压力测试服务正在运行"
|
||||||
|
systemctl status "$SCRIPT_NAME" -l
|
||||||
|
echo ""
|
||||||
|
print_info "系统资源使用情况:"
|
||||||
|
top -bn1 | head -10
|
||||||
|
else
|
||||||
|
print_info "压力测试服务未运行"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 主程序
|
||||||
|
case "$1" in
|
||||||
|
install)
|
||||||
|
install_service
|
||||||
|
;;
|
||||||
|
start)
|
||||||
|
start_stress
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
stop_stress
|
||||||
|
;;
|
||||||
|
uninstall)
|
||||||
|
uninstall_service
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
show_status
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "系统压力测试一键管理脚本"
|
||||||
|
echo ""
|
||||||
|
echo "用法: $0 {install|start|stop|uninstall|status}"
|
||||||
|
echo ""
|
||||||
|
echo "命令说明:"
|
||||||
|
echo " install - 安装并配置压力测试服务(开机自启)"
|
||||||
|
echo " start - 立即启动压力测试"
|
||||||
|
echo " stop - 立即停止压力测试"
|
||||||
|
echo " uninstall - 完全卸载压力测试服务"
|
||||||
|
echo " status - 查看服务状态和系统资源"
|
||||||
|
echo ""
|
||||||
|
print_warning "警告:此脚本会让系统资源达到高负载,可能影响系统稳定性!"
|
||||||
|
echo ""
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
56
docck.txt
Normal file
56
docck.txt
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
Docker私有镜像仓库使用教程
|
||||||
|
|
||||||
|
概述:
|
||||||
|
- 私有Docker镜像仓库地址:github.vps7k7k.xyz
|
||||||
|
- 认证账号:账号
|
||||||
|
- 认证密码:密码
|
||||||
|
|
||||||
|
方法一:使用安全管道登录(推荐)
|
||||||
|
优点:密码不会保存在命令行历史中,最安全
|
||||||
|
|
||||||
|
步骤:
|
||||||
|
1. 打开终端(Linux/Mac)或命令提示符(Windows)
|
||||||
|
2. 执行登录命令:
|
||||||
|
echo "密码" | docker login github.vps7k7k.xyz -u "账号" --password-stdin
|
||||||
|
3. 等待显示"Login Succeeded"表示登录成功
|
||||||
|
4. 拉取镜像:docker pull github.vps7k7k.xyz/nginx
|
||||||
|
5. 验证镜像:docker images | grep github.vps7k7k.xyz/nginx
|
||||||
|
|
||||||
|
完整示例:
|
||||||
|
echo "密码" | docker login github.vps7k7k.xyz -u "账号" --password-stdin
|
||||||
|
docker pull github.vps7k7k.xyz/nginx
|
||||||
|
docker images
|
||||||
|
|
||||||
|
方法二:直接命令行登录
|
||||||
|
优点:简单直接
|
||||||
|
缺点:密码会暂时出现在命令行中
|
||||||
|
|
||||||
|
步骤:
|
||||||
|
1. 执行登录命令:
|
||||||
|
docker login github.vps7k7k.xyz -u "账号" -p "密码"
|
||||||
|
2. 确认显示"Login Succeeded"
|
||||||
|
3. 拉取镜像:docker pull github.vps7k7k.xyz/nginx
|
||||||
|
|
||||||
|
完整示例:
|
||||||
|
docker login github.vps7k7k.xyz -u "账号" -p "密码"
|
||||||
|
docker pull github.vps7k7k.xyz/nginx
|
||||||
|
|
||||||
|
方法三:交互式登录
|
||||||
|
优点:密码输入时不会显示,相对安全
|
||||||
|
|
||||||
|
步骤:
|
||||||
|
1. 执行登录命令:docker login github.vps7k7k.xyz
|
||||||
|
2. 按提示输入:
|
||||||
|
Username: 账号
|
||||||
|
Password: 密码(输入时不会显示)
|
||||||
|
3. 确认显示"Login Succeeded"
|
||||||
|
4. 拉取镜像:docker pull github.vps7k7k.xyz/nginx
|
||||||
|
|
||||||
|
完整示例:
|
||||||
|
docker login github.vps7k7k.xyz
|
||||||
|
# 然后交互式输入账号密码
|
||||||
|
docker pull github.vps7k7k.xyz/nginx
|
||||||
|
|
||||||
|
验证和使用:
|
||||||
|
- 检查登录状态:cat ~/.docker/config.json
|
||||||
|
- 查看当前登录的仓库信息
|
||||||
138
dock安装cf
Normal file
138
dock安装cf
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
# ==========================================
|
||||||
|
# 这一段是放在服务器上的“加载器”脚本
|
||||||
|
# ==========================================
|
||||||
|
|
||||||
|
# 1. 把真正的安装脚本写入到本地文件
|
||||||
|
cat > /root/docker-install-zip.sh <<'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# ================= 配置区 =================
|
||||||
|
ZIP_NAME="dockde12.zip"
|
||||||
|
WORKDIR="/root/docker-offline"
|
||||||
|
# 主下载地址
|
||||||
|
URL1="https://freeyx.vps3344.dpdns.org/xui/dockde12.zip"
|
||||||
|
# 备用下载地址
|
||||||
|
URL2="https://pub-b69a7194f4ea42fba6aa990c49bded91.r2.dev/xui/dockde12.zip"
|
||||||
|
|
||||||
|
# ================= 颜色与日志 =================
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
log_info() { echo -e "${GREEN}[INFO] $1${NC}"; }
|
||||||
|
log_warn() { echo -e "${YELLOW}[WARN] $1${NC}"; }
|
||||||
|
log_err() { echo -e "${RED}[ERROR] $1${NC}"; }
|
||||||
|
|
||||||
|
# ================= 脚本开始 =================
|
||||||
|
echo -e "${GREEN}===== Docker ZIP 版 智能安装脚本 =====${NC}"
|
||||||
|
date
|
||||||
|
|
||||||
|
# 0. 权限检查
|
||||||
|
if [ "$(id -u)" != "0" ]; then
|
||||||
|
log_err "必须使用 root 权限运行此脚本!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 1. 关键:检查并安装 unzip (解决之前的跳过问题)
|
||||||
|
log_info "[1/7] 环境自检: unzip 工具"
|
||||||
|
if ! command -v unzip >/dev/null 2>&1; then
|
||||||
|
log_warn "未找到 unzip 命令,正在尝试自动安装..."
|
||||||
|
apt-get update -y >/dev/null 2>&1
|
||||||
|
apt-get install -y unzip >/dev/null 2>&1
|
||||||
|
|
||||||
|
# 再次检查
|
||||||
|
if ! command -v unzip >/dev/null 2>&1; then
|
||||||
|
log_err "无法安装 unzip!"
|
||||||
|
log_err "可能原因:系统断网或源有问题。"
|
||||||
|
log_err "解决方案:请先手动执行 'apt install unzip' 或更换为 tar.gz 包。"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
log_info "unzip 安装成功!"
|
||||||
|
else
|
||||||
|
log_info "unzip 已存在,准备就绪。"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. 目录检查与创建
|
||||||
|
log_info "[2/7] 初始化工作目录..."
|
||||||
|
if [ -d "$WORKDIR" ]; then
|
||||||
|
log_warn "目录已存在: $WORKDIR"
|
||||||
|
log_warn "清理旧文件以防冲突..."
|
||||||
|
rm -f "$WORKDIR/$ZIP_NAME"
|
||||||
|
rm -rf "$WORKDIR/debs"
|
||||||
|
else
|
||||||
|
log_info "创建新目录: $WORKDIR"
|
||||||
|
mkdir -p "$WORKDIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$WORKDIR" || exit 1
|
||||||
|
|
||||||
|
# 3. 下载文件 (智能切换 curl/wget)
|
||||||
|
log_info "[3/7] 下载离线包..."
|
||||||
|
|
||||||
|
download_file() {
|
||||||
|
if command -v curl >/dev/null 2>&1; then
|
||||||
|
curl -L --fail --connect-timeout 15 --retry 2 "$1" -o "$2"
|
||||||
|
elif command -v wget >/dev/null 2>&1; then
|
||||||
|
wget --timeout=15 --tries=2 -O "$2" "$1"
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if download_file "$URL1" "$ZIP_NAME"; then
|
||||||
|
log_info "主线路下载成功!"
|
||||||
|
else
|
||||||
|
log_warn "主线路失败,切换备用线路..."
|
||||||
|
if download_file "$URL2" "$ZIP_NAME"; then
|
||||||
|
log_info "备用线路下载成功!"
|
||||||
|
else
|
||||||
|
log_err "下载失败!请检查网络连通性。"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 4. 解压
|
||||||
|
log_info "[4/7] 解压文件..."
|
||||||
|
mkdir -p debs
|
||||||
|
unzip -o "$ZIP_NAME" -d debs >/dev/null 2>&1 || {
|
||||||
|
log_err "解压失败!文件可能损坏。"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
cd debs || exit 1
|
||||||
|
|
||||||
|
# 5. 安装 DEB
|
||||||
|
log_info "[5/7] 开始安装 Docker DEB 包..."
|
||||||
|
dpkg -i *.deb
|
||||||
|
# 不立即退出,给 apt 修复的机会
|
||||||
|
|
||||||
|
# 6. 依赖修复与服务启动
|
||||||
|
log_info "[6/7] 检查依赖并启动服务..."
|
||||||
|
# 尝试修复可能的依赖缺失
|
||||||
|
apt-get -f install -y >/dev/null 2>&1
|
||||||
|
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable docker >/dev/null 2>&1
|
||||||
|
systemctl start docker >/dev/null 2>&1
|
||||||
|
|
||||||
|
# 7. 结果验证
|
||||||
|
log_info "[7/7] 最终验证..."
|
||||||
|
if command -v docker >/dev/null 2>&1; then
|
||||||
|
echo -e "----------------------------------------------------"
|
||||||
|
echo -e "${GREEN}Docker 安装成功!${NC}"
|
||||||
|
echo -e "版本: $(docker --version)"
|
||||||
|
echo -e "状态: $(systemctl is-active docker)"
|
||||||
|
echo -e "----------------------------------------------------"
|
||||||
|
else
|
||||||
|
log_err "Docker 未能成功启动,请检查上方报错信息。"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 2. 赋予执行权限
|
||||||
|
chmod +x /root/docker-install-zip.sh
|
||||||
|
|
||||||
|
# 3. 【关键修改】立即执行这个脚本!
|
||||||
|
# 如果不加这行,它只会生成文件然后静默退出
|
||||||
|
bash /root/docker-install-zip.sh
|
||||||
110
dock测.sh
Normal file
110
dock测.sh
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 定义颜色方便查看
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[0;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
echo -e "${BLUE}=========================================${NC}"
|
||||||
|
echo -e "${BLUE} Debian Docker 环境深度检测脚本 ${NC}"
|
||||||
|
echo -e "${BLUE}=========================================${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 1. 基础系统信息检测
|
||||||
|
echo -e "${YELLOW}[1/6] 检测系统基础信息...${NC}"
|
||||||
|
echo -e "操作系统版本: $(cat /etc/debian_version)"
|
||||||
|
echo -e "内核版本: $(uname -r)"
|
||||||
|
echo -e "CPU 架构: $(dpkg --print-architecture)"
|
||||||
|
echo -e "当前用户: $(whoami) (UID: $(id -u))"
|
||||||
|
echo -e "防火墙状态 (ufw): $(command -v ufw >/dev/null 2>&1 && ufw status | head -n 1 || echo '未安装')"
|
||||||
|
echo -e "防火墙状态 (iptables): $(command -v iptables >/dev/null 2>&1 && iptables -L -n | head -n 1 || echo '未安装/无权限')"
|
||||||
|
echo -e "SELinux/AppArmor: $(command -v apparmor_status >/dev/null 2>&1 && apparmor_status | head -n 1 || echo '未检测到 AppArmor')"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 2. 检测 Docker 残留文件
|
||||||
|
echo -e "${YELLOW}[2/6] 检测 Docker 残留文件与目录...${NC}"
|
||||||
|
FILES_TO_CHECK=(
|
||||||
|
"/etc/docker"
|
||||||
|
"/var/lib/docker"
|
||||||
|
"/var/run/docker.sock"
|
||||||
|
"/usr/bin/docker"
|
||||||
|
"/usr/local/bin/docker-compose"
|
||||||
|
"/usr/libexec/docker"
|
||||||
|
)
|
||||||
|
|
||||||
|
FOUND_FILES=0
|
||||||
|
for file in "${FILES_TO_CHECK[@]}"; do
|
||||||
|
if [ -e "$file" ]; then
|
||||||
|
echo -e "${RED}[存在]${NC} 发现残留路径: $file"
|
||||||
|
FOUND_FILES=1
|
||||||
|
# 如果是目录,看下里面有什么
|
||||||
|
if [ -d "$file" ]; then
|
||||||
|
echo -e " └─ 包含文件数: $(ls -A "$file" | wc -l)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}[干净]${NC} 未发现: $file"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ $FOUND_FILES -eq 0 ]; then
|
||||||
|
echo -e "${GREEN}恭喜,文件系统层面似乎很干净。${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 3. 检测已安装的软件包 (apt/dpkg)
|
||||||
|
echo -e "${YELLOW}[3/6] 检测已安装的 Docker 相关软件包...${NC}"
|
||||||
|
DPKG_RES=$(dpkg -l | grep -iE 'docker|containerd|runc|podman' | awk '{print $1, $2, $3}')
|
||||||
|
if [ -n "$DPKG_RES" ]; then
|
||||||
|
echo -e "${RED}发现已安装的包:${NC}"
|
||||||
|
echo "$DPKG_RES"
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}未发现通过 apt 安装的 Docker 相关包。${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 4. 检测运行中的进程和服务
|
||||||
|
echo -e "${YELLOW}[4/6] 检测进程与 Systemd 服务...${NC}"
|
||||||
|
if systemctl list-unit-files | grep -qE 'docker|containerd'; then
|
||||||
|
echo -e "${RED}[警告]${NC} 发现 Docker/Containerd 服务注册:"
|
||||||
|
systemctl list-unit-files | grep -E 'docker|containerd'
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}[干净]${NC} Systemd 中无 Docker 相关服务。"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if pgrep -f "dockerd" > /dev/null; then
|
||||||
|
echo -e "${RED}[警告]${NC} 检测到 dockerd 进程正在运行!"
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}[干净]${NC} 目前没有 dockerd 进程在运行。"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 5. 检测软件源 (Source List)
|
||||||
|
echo -e "${YELLOW}[5/6] 检测 APT 软件源配置...${NC}"
|
||||||
|
# 检查是否包含 docker 官方源或常见的国内镜像源
|
||||||
|
if grep -rE "download.docker.com|aliyun|tsinghua|163" /etc/apt/sources.list /etc/apt/sources.list.d/ > /dev/null; then
|
||||||
|
echo -e "${BLUE}[信息]${NC} 发现以下可能相关的源配置:"
|
||||||
|
grep -rE "download.docker.com|aliyun|tsinghua|163" /etc/apt/sources.list /etc/apt/sources.list.d/ | head -n 3
|
||||||
|
else
|
||||||
|
echo -e "${BLUE}[信息]${NC} 未在源列表中发现明显的 Docker 官方或国内镜像源配置。"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 6. 检测网络连通性 (是否在中国大陆)
|
||||||
|
echo -e "${YELLOW}[6/6] 网络环境简易检测...${NC}"
|
||||||
|
echo "正在测试连接 download.docker.com ..."
|
||||||
|
if curl -I -m 5 -s https://download.docker.com > /dev/null; then
|
||||||
|
echo -e "${GREEN}[连接成功]${NC} 可以直接连接 Docker 官方源。"
|
||||||
|
else
|
||||||
|
echo -e "${RED}[连接失败]${NC} 无法连接 Docker 官方源 (可能需要配置国内镜像或代理)。"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}================ 检测完成 =================${NC}"
|
||||||
|
echo "请复制以上所有输出内容,发送给我。"
|
||||||
152
frps
Normal file
152
frps
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# frps 服务端一键部署脚本
|
||||||
|
# 功能:自动配置 frps.toml 并启动 Docker 容器
|
||||||
|
|
||||||
|
set -eo pipefail
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[0;33m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
# 检查 Docker 服务
|
||||||
|
check_docker() {
|
||||||
|
if ! command -v docker &>/dev/null; then
|
||||||
|
echo -e "${RED}错误:Docker 未安装,请先安装 Docker${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! docker info &>/dev/null; then
|
||||||
|
echo -e "${RED}错误:Docker 服务未运行,请先启动 Docker 服务${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo -e "${GREEN}✓ Docker 服务可用${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 准备配置文件和目录
|
||||||
|
prepare_config() {
|
||||||
|
local config_dir="/data/frps"
|
||||||
|
local config_file="$config_dir/frps.toml"
|
||||||
|
|
||||||
|
echo -e "${YELLOW}正在准备 frps 配置文件...${NC}"
|
||||||
|
mkdir -p "$config_dir"
|
||||||
|
|
||||||
|
cat > "$config_file" <<'EOF'
|
||||||
|
# ======================
|
||||||
|
# frp 服务端安全强化配置
|
||||||
|
# ======================
|
||||||
|
|
||||||
|
# 网络监听
|
||||||
|
bindAddr = "0.0.0.0"
|
||||||
|
bindPort = 7000
|
||||||
|
#kcpBindPort = 7000 # 保持KCP支持(按需取消注释)
|
||||||
|
quicBindPort = 7000 # 保持QUIC支持
|
||||||
|
|
||||||
|
# 端口设置
|
||||||
|
vhostHTTPPort = 8080 # HTTP代理端口
|
||||||
|
vhostHTTPSPort = 8443 # HTTPS代理端口
|
||||||
|
|
||||||
|
# 传输优化
|
||||||
|
transport.maxPoolCount = 2000
|
||||||
|
transport.tcpMux = true
|
||||||
|
transport.tcpMuxKeepaliveInterval = 60
|
||||||
|
transport.tcpKeepalive = 7200
|
||||||
|
transport.tls.force = false # 生产环境建议改为true
|
||||||
|
|
||||||
|
# 控制面板
|
||||||
|
webServer.addr = "0.0.0.0"
|
||||||
|
webServer.port = 7500
|
||||||
|
webServer.user = "admin"
|
||||||
|
webServer.password = "FrpS3cure@2024"
|
||||||
|
webServer.pprofEnable = false
|
||||||
|
|
||||||
|
# 日志配置
|
||||||
|
log.to = "/var/log/frps.log"
|
||||||
|
log.level = "info"
|
||||||
|
log.maxDays = 3
|
||||||
|
log.disablePrintColor = false
|
||||||
|
|
||||||
|
# 认证配置
|
||||||
|
auth.method = "token"
|
||||||
|
auth.token = "XH7#k9q$LzP2*4vN!R5tY8wC"
|
||||||
|
|
||||||
|
# 端口控制
|
||||||
|
allowPorts = [
|
||||||
|
{ start = 10000, end = 60000 }
|
||||||
|
]
|
||||||
|
|
||||||
|
# 高级参数
|
||||||
|
maxPortsPerClient = 8
|
||||||
|
udpPacketSize = 1500
|
||||||
|
natholeAnalysisDataReserveHours = 168
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo -e "${GREEN}✓ 配置文件已生成: $config_file${NC}"
|
||||||
|
chmod 600 "$config_file" # 设置配置文件权限
|
||||||
|
}
|
||||||
|
|
||||||
|
# 部署 Docker 容器
|
||||||
|
deploy_container() {
|
||||||
|
local container_name="frps"
|
||||||
|
local config_dir="/data/frps"
|
||||||
|
|
||||||
|
# 停止并移除旧容器(如果存在)
|
||||||
|
if docker ps -a --format '{{.Names}}' | grep -q "^$container_name$"; then
|
||||||
|
echo -e "${YELLOW}发现已存在的容器,正在清理...${NC}"
|
||||||
|
docker stop "$container_name" >/dev/null
|
||||||
|
docker rm "$container_name" >/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 启动新容器
|
||||||
|
echo -e "${YELLOW}正在启动 frps 容器...${NC}"
|
||||||
|
docker run -d \
|
||||||
|
--name "$container_name" \
|
||||||
|
--restart unless-stopped \
|
||||||
|
--network host \
|
||||||
|
-v "$config_dir/frps.toml:/etc/frp/frps.toml" \
|
||||||
|
-v "$config_dir/logs:/var/log" \
|
||||||
|
snowdreamtech/frps
|
||||||
|
|
||||||
|
echo -e "${GREEN}✓ frps 容器已启动${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查容器状态
|
||||||
|
check_status() {
|
||||||
|
local container_name="frps"
|
||||||
|
local max_retries=5
|
||||||
|
local retry_interval=2
|
||||||
|
|
||||||
|
echo -e "\n${YELLOW}正在检查容器状态...${NC}"
|
||||||
|
for ((i=1; i<=max_retries; i++)); do
|
||||||
|
if docker ps --filter "name=$container_name" --filter "status=running" | grep -q "$container_name"; then
|
||||||
|
echo -e "${GREEN}✓ frps 运行正常${NC}"
|
||||||
|
|
||||||
|
# 获取容器使用的端口
|
||||||
|
echo -e "\n======================"
|
||||||
|
echo -e "${YELLOW}服务已启动,使用以下信息访问:${NC}"
|
||||||
|
echo -e "控制面板: http://<服务器IP>:7500"
|
||||||
|
echo -e "用户名: admin"
|
||||||
|
echo -e "密码: FrpS3cure@2024"
|
||||||
|
echo -e "\n客户端连接令牌: XH7#k9q$LzP2*4vN!R5tY8wC"
|
||||||
|
echo -e "======================"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
sleep "$retry_interval"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -e "${RED}错误:容器启动失败${NC}"
|
||||||
|
docker logs "$container_name"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 主函数
|
||||||
|
main() {
|
||||||
|
echo -e "\n${GREEN}===== frps 服务端部署脚本 =====${NC}"
|
||||||
|
check_docker
|
||||||
|
prepare_config
|
||||||
|
deploy_container
|
||||||
|
check_status
|
||||||
|
}
|
||||||
|
|
||||||
|
main
|
||||||
43
ghproxy
Normal file
43
ghproxy
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 固定路径(不允许修改)
|
||||||
|
yaml_path="/boot/脚本/ghproxy.yaml"
|
||||||
|
|
||||||
|
# 定义默认值(强制兜底,确保不为空)
|
||||||
|
default_project="ghproxy"
|
||||||
|
default_port="7210"
|
||||||
|
|
||||||
|
# 读取用户输入
|
||||||
|
read -p "请输入项目名称(默认: $default_project): " input_project
|
||||||
|
read -p "请输入映射端口(默认: $default_port): " input_port
|
||||||
|
|
||||||
|
# 处理输入:空值/纯空格则用默认值(关键优化)
|
||||||
|
project_name=$(echo "$input_project" | xargs) # 去除首尾空格
|
||||||
|
project_name=${project_name:-$default_project} # 若为空则用默认值
|
||||||
|
|
||||||
|
port=$(echo "$input_port" | xargs)
|
||||||
|
port=${port:-$default_port}
|
||||||
|
|
||||||
|
# 再次强制校验项目名(确保绝对不为空)
|
||||||
|
if [ -z "$project_name" ]; then
|
||||||
|
project_name="$default_project"
|
||||||
|
echo "警告:项目名不能为空,已自动使用默认值 '$default_project'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 写入配置文件
|
||||||
|
echo "version: '3.9'
|
||||||
|
services:
|
||||||
|
$project_name:
|
||||||
|
image: wjqserver/ghproxy:latest
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- ./ghproxy/log:/data/ghproxy/log
|
||||||
|
- ./ghproxy/config:/data/ghproxy/config
|
||||||
|
ports:
|
||||||
|
- \"$port:8080\"
|
||||||
|
" > "$yaml_path"
|
||||||
|
|
||||||
|
# 启动服务
|
||||||
|
docker compose -p "$project_name" -f "$yaml_path" up -d
|
||||||
|
|
||||||
|
echo "服务启动成功!项目名: $project_name,端口: $port,配置路径: $yaml_path"
|
||||||
76
github安装
Normal file
76
github安装
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# hubproxy 一键安装脚本(增强版)
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "🚀 开始安装 hubproxy 容器代理服务..."
|
||||||
|
|
||||||
|
# 检查 Docker 是否安装
|
||||||
|
if ! command -v docker &> /dev/null; then
|
||||||
|
echo "❌ 错误: 未检测到 Docker,请先安装 Docker"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 显示当前信息
|
||||||
|
echo "📋 安装配置:"
|
||||||
|
echo " - 容器名称: hubproxy"
|
||||||
|
echo " - 映射端口: 5000"
|
||||||
|
echo " - 镜像: ghcr.io/sky22333/hubproxy"
|
||||||
|
echo " - 数据目录: /data/hubproxy"
|
||||||
|
|
||||||
|
# 创建数据目录
|
||||||
|
echo "📁 创建数据目录..."
|
||||||
|
sudo mkdir -p /data/hubproxy
|
||||||
|
sudo chown -R $USER:$USER /data/hubproxy
|
||||||
|
sudo chmod -R 755 /data/hubproxy
|
||||||
|
|
||||||
|
# 停止并清理旧容器
|
||||||
|
echo "🧹 清理旧容器..."
|
||||||
|
docker stop hubproxy 2>/dev/null || true
|
||||||
|
docker rm hubproxy 2>/dev/null || true
|
||||||
|
|
||||||
|
# 拉取并运行新容器
|
||||||
|
echo "📥 拉取镜像..."
|
||||||
|
docker pull ghcr.io/sky22333/hubproxy
|
||||||
|
|
||||||
|
echo "🐳 启动容器..."
|
||||||
|
docker run -d \
|
||||||
|
--name hubproxy \
|
||||||
|
-p 5000:5000 \
|
||||||
|
-v /data/hubproxy:/app/data \
|
||||||
|
--restart always \
|
||||||
|
ghcr.io/sky22333/hubproxy
|
||||||
|
|
||||||
|
# 等待启动
|
||||||
|
echo "⏳ 等待服务启动..."
|
||||||
|
for i in {1..30}; do
|
||||||
|
if docker ps --filter "name=hubproxy" --filter "status=running" | grep -q hubproxy; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
# 获取网络信息
|
||||||
|
IP=$(hostname -I | awk '{print $1}')
|
||||||
|
if [ -z "$IP" ]; then
|
||||||
|
IP="127.0.0.1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 显示结果
|
||||||
|
echo ""
|
||||||
|
echo "========================================"
|
||||||
|
echo "✅ hubproxy 安装完成!"
|
||||||
|
echo "========================================"
|
||||||
|
echo "🌐 访问地址: http://$IP:5000"
|
||||||
|
echo "🔗 本地访问: http://localhost:5000"
|
||||||
|
echo "📌 端口: 5000"
|
||||||
|
echo "📁 数据目录: /data/hubproxy"
|
||||||
|
echo "🐳 容器状态: $(docker inspect -f '{{.State.Status}}' hubproxy)"
|
||||||
|
echo ""
|
||||||
|
echo "📋 常用命令:"
|
||||||
|
echo " 查看日志: docker logs hubproxy"
|
||||||
|
echo " 停止服务: docker stop hubproxy"
|
||||||
|
echo " 启动服务: docker start hubproxy"
|
||||||
|
echo " 重启服务: docker restart hubproxy"
|
||||||
|
echo " 查看数据: ls -la /data/hubproxy"
|
||||||
|
echo "========================================"
|
||||||
285
ipv6
Normal file
285
ipv6
Normal file
@@ -0,0 +1,285 @@
|
|||||||
|
#!/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
|
||||||
|
|
||||||
|
# 变量定义
|
||||||
|
IPV4_API="https://api.ipify.org?format=json"
|
||||||
|
IPV6_API="https://api64.ipify.org?format=json"
|
||||||
|
GEO_API="http://ip-api.com/json/"
|
||||||
|
IPINFO_API="https://ipinfo.io/"
|
||||||
|
|
||||||
|
# 检查依赖
|
||||||
|
check_dependencies() {
|
||||||
|
local deps=("curl" "jq" "ping" "ip")
|
||||||
|
local missing=()
|
||||||
|
|
||||||
|
for dep in "${deps[@]}"; do
|
||||||
|
if ! command -v "$dep" &> /dev/null; then
|
||||||
|
missing+=("$dep")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ${#missing[@]} -ne 0 ]; then
|
||||||
|
echo -e "${RED}缺少必要依赖: ${missing[*]}${NC}"
|
||||||
|
echo "正在安装依赖..."
|
||||||
|
apt update && apt install -y "${missing[@]}" 2>/dev/null || \
|
||||||
|
yum install -y "${missing[@]}" 2>/dev/null || \
|
||||||
|
echo "请手动安装缺少的依赖"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 获取公网IPv4地址和地理位置
|
||||||
|
get_ipv4_info() {
|
||||||
|
echo -e "${CYAN}=== IPv4 信息检测 ===${NC}"
|
||||||
|
|
||||||
|
local ipv4_info=$(curl -s -4 --connect-timeout 5 "$IPV4_API")
|
||||||
|
if [ -n "$ipv4_info" ]; then
|
||||||
|
local ipv4=$(echo "$ipv4_info" | jq -r '.ip')
|
||||||
|
echo -e "${GREEN}公网IPv4地址: $ipv4${NC}"
|
||||||
|
|
||||||
|
# 获取地理位置
|
||||||
|
local geo_info=$(curl -s --connect-timeout 5 "${GEO_API}${ipv4}")
|
||||||
|
if [ -n "$geo_info" ]; then
|
||||||
|
local country=$(echo "$geo_info" | jq -r '.country // "未知"')
|
||||||
|
local region=$(echo "$geo_info" | jq -r '.regionName // "未知"')
|
||||||
|
local city=$(echo "$geo_info" | jq -r '.city // "未知"')
|
||||||
|
local isp=$(echo "$geo_info" | jq -r '.isp // "未知"')
|
||||||
|
local as=$(echo "$geo_info" | jq -r '.as // "未知"')
|
||||||
|
|
||||||
|
echo -e "地理位置: ${YELLOW}$country - $region - $city${NC}"
|
||||||
|
echo -e "网络运营商: ${BLUE}$isp${NC}"
|
||||||
|
echo -e "ASN: ${PURPLE}$as${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}无法获取IPv4地理位置信息${NC}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${RED}无法获取公网IPv4地址${NC}"
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# 获取公网IPv6地址和地理位置
|
||||||
|
get_ipv6_info() {
|
||||||
|
echo -e "${CYAN}=== IPv6 信息检测 ===${NC}"
|
||||||
|
|
||||||
|
local ipv6_info=$(curl -s -6 --connect-timeout 5 "$IPV6_API")
|
||||||
|
if [ -n "$ipv6_info" ]; then
|
||||||
|
local ipv6=$(echo "$ipv6_info" | jq -r '.ip')
|
||||||
|
echo -e "${GREEN}公网IPv6地址: $ipv6${NC}"
|
||||||
|
|
||||||
|
# 获取地理位置
|
||||||
|
local geo_info=$(curl -s --connect-timeout 5 "${GEO_API}${ipv6}")
|
||||||
|
if [ -n "$geo_info" ]; then
|
||||||
|
local country=$(echo "$geo_info" | jq -r '.country // "未知"')
|
||||||
|
local region=$(echo "$geo_info" | jq -r '.regionName // "未知"')
|
||||||
|
local city=$(echo "$geo_info" | jq -r '.city // "未知"')
|
||||||
|
local isp=$(echo "$geo_info" | jq -r '.isp // "未知"')
|
||||||
|
local as=$(echo "$geo_info" | jq -r '.as // "未知"')
|
||||||
|
|
||||||
|
echo -e "地理位置: ${YELLOW}$country - $region - $city${NC}"
|
||||||
|
echo -e "网络运营商: ${BLUE}$isp${NC}"
|
||||||
|
echo -e "ASN: ${PURPLE}$as${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}无法获取IPv6地理位置信息${NC}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${RED}无法获取公网IPv6地址${NC}"
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检测本地网络接口
|
||||||
|
get_local_network_info() {
|
||||||
|
echo -e "${CYAN}=== 本地网络接口信息 ===${NC}"
|
||||||
|
|
||||||
|
# 获取所有网络接口
|
||||||
|
local interfaces=$(ip -o link show | awk -F': ' '{print $2}')
|
||||||
|
|
||||||
|
for iface in $interfaces; do
|
||||||
|
# 跳过lo和docker虚拟接口
|
||||||
|
if [[ "$iface" == "lo" ]] || [[ "$iface" == docker* ]] || [[ "$iface" == veth* ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${BLUE}接口: $iface${NC}"
|
||||||
|
|
||||||
|
# IPv4信息
|
||||||
|
local ipv4_addr=$(ip -4 addr show dev "$iface" | grep inet | awk '{print $2}')
|
||||||
|
if [ -n "$ipv4_addr" ]; then
|
||||||
|
echo -e " IPv4: ${GREEN}$ipv4_addr${NC}"
|
||||||
|
else
|
||||||
|
echo -e " IPv4: ${RED}无${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# IPv6信息
|
||||||
|
local ipv6_addr=$(ip -6 addr show dev "$iface" scope global | grep inet6 | awk '{print $2}' | head -1)
|
||||||
|
if [ -n "$ipv6_addr" ]; then
|
||||||
|
echo -e " IPv6: ${GREEN}$ipv6_addr${NC}"
|
||||||
|
else
|
||||||
|
echo -e " IPv6: ${RED}无${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# MAC地址
|
||||||
|
local mac_addr=$(ip link show dev "$iface" | grep link/ether | awk '{print $2}')
|
||||||
|
if [ -n "$mac_addr" ]; then
|
||||||
|
echo -e " MAC: ${YELLOW}$mac_addr${NC}"
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# 网络连通性测试
|
||||||
|
test_connectivity() {
|
||||||
|
echo -e "${CYAN}=== 网络连通性测试 ===${NC}"
|
||||||
|
|
||||||
|
# IPv4测试目标
|
||||||
|
local ipv4_targets=(
|
||||||
|
"8.8.8.8 Google DNS"
|
||||||
|
"1.1.1.1 Cloudflare DNS"
|
||||||
|
"114.114.114.114 国内DNS"
|
||||||
|
"223.5.5.5 阿里DNS"
|
||||||
|
)
|
||||||
|
|
||||||
|
# IPv6测试目标
|
||||||
|
local ipv6_targets=(
|
||||||
|
"2001:4860:4860::8888 Google DNS"
|
||||||
|
"2606:4700:4700::1111 Cloudflare DNS"
|
||||||
|
"2400:3200::1 阿里DNS"
|
||||||
|
"2408:8899::8 百度DNS"
|
||||||
|
)
|
||||||
|
|
||||||
|
echo -e "${YELLOW}IPv4 连通性:${NC}"
|
||||||
|
for target in "${ipv4_targets[@]}"; do
|
||||||
|
local ip=$(echo "$target" | awk '{print $1}')
|
||||||
|
local name=$(echo "$target" | awk '{print $2}')
|
||||||
|
|
||||||
|
if ping -c 2 -W 2 "$ip" &> /dev/null; then
|
||||||
|
echo -e " ${GREEN}✓ $name ($ip) - 可达${NC}"
|
||||||
|
else
|
||||||
|
echo -e " ${RED}✗ $name ($ip) - 不可达${NC}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo -e "${YELLOW}IPv6 连通性:${NC}"
|
||||||
|
for target in "${ipv6_targets[@]}"; do
|
||||||
|
local ip=$(echo "$target" | awk '{print $1}')
|
||||||
|
local name=$(echo "$target" | awk '{print $2}')
|
||||||
|
|
||||||
|
if ping6 -c 2 -W 2 "$ip" &> /dev/null; then
|
||||||
|
echo -e " ${GREEN}✓ $name ($ip) - 可达${NC}"
|
||||||
|
else
|
||||||
|
echo -e " ${RED}✗ $name ($ip) - 不可达${NC}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# 路由跟踪测试
|
||||||
|
test_traceroute() {
|
||||||
|
echo -e "${CYAN}=== 路由跟踪测试 ===${NC}"
|
||||||
|
|
||||||
|
echo -e "${YELLOW}IPv4 路由跟踪 (前3跳):${NC}"
|
||||||
|
if command -v traceroute &> /dev/null; then
|
||||||
|
traceroute -m 3 -w 1 8.8.8.8 2>/dev/null | head -5
|
||||||
|
else
|
||||||
|
echo "traceroute命令不可用"
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo -e "${YELLOW}IPv6 路由跟踪 (前3跳):${NC}"
|
||||||
|
if command -v traceroute6 &> /dev/null; then
|
||||||
|
traceroute6 -m 3 -w 1 2001:4860:4860::8888 2>/dev/null | head -5
|
||||||
|
else
|
||||||
|
echo "traceroute6命令不可用"
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# 获取详细IP信息
|
||||||
|
get_detailed_ip_info() {
|
||||||
|
echo -e "${CYAN}=== 详细IP信息 ===${NC}"
|
||||||
|
|
||||||
|
# 获取公网IP
|
||||||
|
local public_ipv4=$(curl -s -4 --connect-timeout 5 "https://api.ipify.org")
|
||||||
|
local public_ipv6=$(curl -s -6 --connect-timeout 5 "https://api64.ipify.org")
|
||||||
|
|
||||||
|
if [ -n "$public_ipv4" ]; then
|
||||||
|
echo -e "${GREEN}公网IPv4: $public_ipv4${NC}"
|
||||||
|
local ipinfo=$(curl -s --connect-timeout 5 "https://ipinfo.io/$public_ipv4/json")
|
||||||
|
if [ -n "$ipinfo" ]; then
|
||||||
|
echo "$ipinfo" | jq '. | {country: .country, region: .region, city: .city, loc: .loc, org: .org, timezone: .timezone}' 2>/dev/null
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$public_ipv6" ]; then
|
||||||
|
echo -e "${GREEN}公网IPv6: $public_ipv6${NC}"
|
||||||
|
local ipinfo=$(curl -s --connect-timeout 5 "https://ipinfo.io/$public_ipv6/json")
|
||||||
|
if [ -n "$ipinfo" ]; then
|
||||||
|
echo "$ipinfo" | jq '. | {country: .country, region: .region, city: .city, loc: .loc, org: .org, timezone: .timezone}' 2>/dev/null
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 网络速度测试(可选)
|
||||||
|
test_speed() {
|
||||||
|
echo -e "${CYAN}=== 网络速度测试 (可选) ===${NC}"
|
||||||
|
read -p "是否进行网络速度测试? (y/N): " choice
|
||||||
|
if [[ $choice == "y" || $choice == "Y" ]]; then
|
||||||
|
if command -v speedtest-cli &> /dev/null; then
|
||||||
|
echo "正在进行速度测试..."
|
||||||
|
speedtest-cli --simple
|
||||||
|
else
|
||||||
|
echo "speedtest-cli未安装,跳过速度测试"
|
||||||
|
echo "安装命令: apt install speedtest-cli 或 pip install speedtest-cli"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# 生成报告
|
||||||
|
generate_report() {
|
||||||
|
echo -e "${CYAN}=== 网络检测报告 ===${NC}"
|
||||||
|
echo "检测时间: $(date)"
|
||||||
|
echo "主机名: $(hostname)"
|
||||||
|
echo "系统: $(uname -s -r)"
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# 主函数
|
||||||
|
main() {
|
||||||
|
clear
|
||||||
|
echo -e "${PURPLE}================================${NC}"
|
||||||
|
echo -e "${PURPLE} 全能网络检测脚本 v2.0${NC}"
|
||||||
|
echo -e "${PURPLE}================================${NC}"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# 检查依赖
|
||||||
|
check_dependencies
|
||||||
|
|
||||||
|
# 生成报告头
|
||||||
|
generate_report
|
||||||
|
|
||||||
|
# 执行各项检测
|
||||||
|
get_local_network_info
|
||||||
|
get_ipv4_info
|
||||||
|
get_ipv6_info
|
||||||
|
test_connectivity
|
||||||
|
test_traceroute
|
||||||
|
get_detailed_ip_info
|
||||||
|
test_speed
|
||||||
|
|
||||||
|
echo -e "${GREEN}=== 检测完成 ===${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 执行主函数
|
||||||
|
main "$@"
|
||||||
398
kali
Normal file
398
kali
Normal file
@@ -0,0 +1,398 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Kali Linux 国内源 + 中文环境一键配置脚本
|
||||||
|
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
# 检查是否为 root 用户
|
||||||
|
if [ "$EUID" -ne 0 ]; then
|
||||||
|
echo -e "${RED}请使用 sudo 运行此脚本${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${GREEN}=================================${NC}"
|
||||||
|
echo -e "${GREEN} Kali Linux 一键配置脚本 ${NC}"
|
||||||
|
echo -e "${GREEN}=================================${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 备份原始源文件
|
||||||
|
backup_sources() {
|
||||||
|
echo -e "${YELLOW}[1/12] 备份当前源文件...${NC}"
|
||||||
|
if [ -f "/etc/apt/sources.list" ]; then
|
||||||
|
cp /etc/apt/sources.list /etc/apt/sources.list.bak.$(date +%Y%m%d%H%M%S)
|
||||||
|
echo -e "${GREEN}源文件已备份${NC}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 更新国内源
|
||||||
|
update_sources() {
|
||||||
|
echo -e "${YELLOW}[2/12] 配置国内软件源(多源备用)...${NC}"
|
||||||
|
|
||||||
|
# 清华源
|
||||||
|
cat > /tmp/sources_tsinghua.list << EOF
|
||||||
|
# 清华大学 Kali 源
|
||||||
|
deb https://mirrors.tuna.tsinghua.edu.cn/kali kali-rolling main contrib non-free non-free-firmware
|
||||||
|
# deb-src https://mirrors.tuna.tsinghua.edu.cn/kali kali-rolling main contrib non-free non-free-firmware
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 阿里云源
|
||||||
|
cat > /tmp/sources_aliyun.list << EOF
|
||||||
|
# 阿里云 Kali 源
|
||||||
|
deb https://mirrors.aliyun.com/kali kali-rolling main contrib non-free non-free-firmware
|
||||||
|
# deb-src https://mirrors.aliyun.com/kali kali-rolling main contrib non-free non-free-firmware
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 中科大源
|
||||||
|
cat > /tmp/sources_ustc.list << EOF
|
||||||
|
# 中科大 Kali 源
|
||||||
|
deb https://mirrors.ustc.edu.cn/kali kali-rolling main contrib non-free non-free-firmware
|
||||||
|
# deb-src https://mirrors.ustc.edu.cn/kali kali-rolling main contrib non-free non-free-firmware
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 华为云源
|
||||||
|
cat > /tmp/sources_huawei.list << EOF
|
||||||
|
# 华为云 Kali 源
|
||||||
|
deb https://repo.huaweicloud.com/kali kali-rolling main contrib non-free non-free-firmware
|
||||||
|
# deb-src https://repo.huaweicloud.com/kali kali-rolling main contrib non-free non-free-firmware
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 浙大源
|
||||||
|
cat > /tmp/sources_zju.list << EOF
|
||||||
|
# 浙江大学 Kali 源
|
||||||
|
deb https://mirrors.zju.edu.cn/kali kali-rolling main contrib non-free non-free-firmware
|
||||||
|
# deb-src https://mirrors.zju.edu.cn/kali kali-rolling main contrib non-free non-free-firmware
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 南京大学源
|
||||||
|
cat > /tmp/sources_nju.list << EOF
|
||||||
|
# 南京大学 Kali 源
|
||||||
|
deb https://mirrors.nju.edu.cn/kali kali-rolling main contrib non-free non-free-firmware
|
||||||
|
# deb-src https://mirrors.nju.edu.cn/kali kali-rolling main contrib non-free non-free-firmware
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 选择最快的源
|
||||||
|
echo -e "${BLUE}请选择要使用的软件源:${NC}"
|
||||||
|
echo "1. 清华大学源 (推荐)"
|
||||||
|
echo "2. 阿里云源"
|
||||||
|
echo "3. 中科大源"
|
||||||
|
echo "4. 华为云源"
|
||||||
|
echo "5. 自动测试选择最快源"
|
||||||
|
read -p "请输入选项 [1-5]: " source_choice
|
||||||
|
|
||||||
|
case $source_choice in
|
||||||
|
1)
|
||||||
|
cp /tmp/sources_tsinghua.list /etc/apt/sources.list
|
||||||
|
echo -e "${GREEN}已选择清华大学源${NC}"
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
cp /tmp/sources_aliyun.list /etc/apt/sources.list
|
||||||
|
echo -e "${GREEN}已选择阿里云源${NC}"
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
cp /tmp/sources_ustc.list /etc/apt/sources.list
|
||||||
|
echo -e "${GREEN}已选择中科大源${NC}"
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
cp /tmp/sources_huawei.list /etc/apt/sources.list
|
||||||
|
echo -e "${GREEN}已选择华为云源${NC}"
|
||||||
|
;;
|
||||||
|
5)
|
||||||
|
test_fastest_source
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
cp /tmp/sources_tsinghua.list /etc/apt/sources.list
|
||||||
|
echo -e "${GREEN}已默认选择清华大学源${NC}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# 添加备用源到 sources.list.d
|
||||||
|
mkdir -p /etc/apt/sources.list.d
|
||||||
|
cp /tmp/sources_aliyun.list /etc/apt/sources.list.d/aliyun.list.bak
|
||||||
|
cp /tmp/sources_ustc.list /etc/apt/sources.list.d/ustc.list.bak
|
||||||
|
|
||||||
|
# 添加 Kali 安全源
|
||||||
|
cat > /etc/apt/sources.list.d/kali-security.list << EOF
|
||||||
|
# Kali 安全更新源
|
||||||
|
deb https://http.kali.org/kali kali-rolling main contrib non-free non-free-firmware
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# 测试最快源
|
||||||
|
test_fastest_source() {
|
||||||
|
echo -e "${YELLOW}正在测试最快的软件源...${NC}"
|
||||||
|
|
||||||
|
sources=(
|
||||||
|
"清华大学源 https://mirrors.tuna.tsinghua.edu.cn/kali"
|
||||||
|
"阿里云源 https://mirrors.aliyun.com/kali"
|
||||||
|
"中科大源 https://mirrors.ustc.edu.cn/kali"
|
||||||
|
"华为云源 https://repo.huaweicloud.com/kali"
|
||||||
|
)
|
||||||
|
|
||||||
|
fastest_source=""
|
||||||
|
fastest_time=99999
|
||||||
|
|
||||||
|
for source in "${sources[@]}"; do
|
||||||
|
name=$(echo $source | cut -d' ' -f1)
|
||||||
|
url=$(echo $source | cut -d' ' -f2)
|
||||||
|
|
||||||
|
echo -n "测试 $name ... "
|
||||||
|
time=$(timeout 5 curl -o /dev/null -s -w "%{time_total}" $url 2>/dev/null || echo "999")
|
||||||
|
|
||||||
|
if [ $(echo "$time < $fastest_time" | bc) -eq 1 ]; then
|
||||||
|
fastest_time=$time
|
||||||
|
fastest_source=$name
|
||||||
|
fi
|
||||||
|
echo "${time}秒"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -e "${GREEN}最快源: $fastest_source (${fastest_time}秒)${NC}"
|
||||||
|
|
||||||
|
case $fastest_source in
|
||||||
|
"清华大学源")
|
||||||
|
cp /tmp/sources_tsinghua.list /etc/apt/sources.list
|
||||||
|
;;
|
||||||
|
"阿里云源")
|
||||||
|
cp /tmp/sources_aliyun.list /etc/apt/sources.list
|
||||||
|
;;
|
||||||
|
"中科大源")
|
||||||
|
cp /tmp/sources_ustc.list /etc/apt/sources.list
|
||||||
|
;;
|
||||||
|
"华为云源")
|
||||||
|
cp /tmp/sources_huawei.list /etc/apt/sources.list
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
cp /tmp/sources_tsinghua.list /etc/apt/sources.list
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# 更新软件包
|
||||||
|
update_packages() {
|
||||||
|
echo -e "${YELLOW}[3/12] 更新软件包列表...${NC}"
|
||||||
|
apt update -y
|
||||||
|
|
||||||
|
echo -e "${YELLOW}[4/12] 升级已安装的软件包...${NC}"
|
||||||
|
apt upgrade -y --allow-downgrades
|
||||||
|
|
||||||
|
echo -e "${YELLOW}[5/12] 安装常用工具...${NC}"
|
||||||
|
apt install -y curl wget git vim net-tools htop neofetch
|
||||||
|
}
|
||||||
|
|
||||||
|
# 安装中文字体
|
||||||
|
install_chinese_fonts() {
|
||||||
|
echo -e "${YELLOW}[6/12] 安装中文字体...${NC}"
|
||||||
|
apt install -y \
|
||||||
|
fonts-wqy-microhei \
|
||||||
|
fonts-wqy-zenhei \
|
||||||
|
fonts-noto-cjk \
|
||||||
|
fonts-droid-fallback \
|
||||||
|
ttf-wqy-microhei \
|
||||||
|
ttf-wqy-zenhei \
|
||||||
|
xfonts-wqy
|
||||||
|
|
||||||
|
# 下载并安装微软雅黑字体(可选)
|
||||||
|
echo -e "${YELLOW}是否安装微软雅黑字体? [y/N] ${NC}"
|
||||||
|
read -p "" install_msyh
|
||||||
|
if [[ $install_msyh =~ ^[Yy]$ ]]; then
|
||||||
|
wget -P /tmp https://github.com/xzx3344521/dock/raw/main/fonts/msyh.ttf
|
||||||
|
wget -P /tmp https://github.com/xzx3344521/dock/raw/main/fonts/msyhbd.ttf
|
||||||
|
mkdir -p /usr/share/fonts/truetype/microsoft
|
||||||
|
cp /tmp/msyh*.ttf /usr/share/fonts/truetype/microsoft/
|
||||||
|
fc-cache -fv
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 安装中文语言包
|
||||||
|
install_language_pack() {
|
||||||
|
echo -e "${YELLOW}[7/12] 安装中文语言包...${NC}"
|
||||||
|
apt install -y \
|
||||||
|
locales \
|
||||||
|
locales-all \
|
||||||
|
language-pack-zh-hans \
|
||||||
|
language-pack-zh-hans-base \
|
||||||
|
language-pack-gnome-zh-hans
|
||||||
|
}
|
||||||
|
|
||||||
|
# 配置区域设置
|
||||||
|
configure_locale() {
|
||||||
|
echo -e "${YELLOW}[8/12] 配置中文区域设置...${NC}"
|
||||||
|
|
||||||
|
# 生成中文区域
|
||||||
|
sed -i 's/^# zh_CN.UTF-8 UTF-8/zh_CN.UTF-8 UTF-8/' /etc/locale.gen
|
||||||
|
sed -i 's/^# zh_CN.GBK GBK/zh_CN.GBK GBK/' /etc/locale.gen
|
||||||
|
locale-gen
|
||||||
|
|
||||||
|
# 设置系统语言
|
||||||
|
update-locale LANG=zh_CN.UTF-8
|
||||||
|
update-locale LANGUAGE=zh_CN:zh
|
||||||
|
}
|
||||||
|
|
||||||
|
# 安装中文输入法
|
||||||
|
install_input_method() {
|
||||||
|
echo -e "${YELLOW}[9/12] 安装中文输入法...${NC}"
|
||||||
|
|
||||||
|
echo -e "${BLUE}请选择输入法:${NC}"
|
||||||
|
echo "1. IBus + 拼音 (推荐)"
|
||||||
|
echo "2. Fcitx + 拼音"
|
||||||
|
echo "3. 两者都安装"
|
||||||
|
read -p "请输入选项 [1-3]: " im_choice
|
||||||
|
|
||||||
|
case $im_choice in
|
||||||
|
1)
|
||||||
|
apt install -y \
|
||||||
|
ibus \
|
||||||
|
ibus-libpinyin \
|
||||||
|
ibus-gtk ibus-gtk3 \
|
||||||
|
ibus-clutter
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
apt install -y \
|
||||||
|
fcitx \
|
||||||
|
fcitx-pinyin \
|
||||||
|
fcitx-googlepinyin \
|
||||||
|
fcitx-config-gtk \
|
||||||
|
fcitx-frontend-gtk2 \
|
||||||
|
fcitx-frontend-gtk3 \
|
||||||
|
fcitx-module-cloudpinyin
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
apt install -y \
|
||||||
|
ibus ibus-libpinyin \
|
||||||
|
fcitx fcitx-pinyin
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
apt install -y ibus ibus-libpinyin
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# 配置环境变量
|
||||||
|
configure_environment() {
|
||||||
|
echo -e "${YELLOW}[10/12] 配置环境变量...${NC}"
|
||||||
|
|
||||||
|
# 系统级配置
|
||||||
|
cat > /etc/profile.d/chinese_env.sh << EOF
|
||||||
|
export LANG=zh_CN.UTF-8
|
||||||
|
export LANGUAGE=zh_CN:zh
|
||||||
|
export LC_CTYPE="zh_CN.UTF-8"
|
||||||
|
export LC_NUMERIC="zh_CN.UTF-8"
|
||||||
|
export LC_TIME="zh_CN.UTF-8"
|
||||||
|
export LC_COLLATE="zh_CN.UTF-8"
|
||||||
|
export LC_MONETARY="zh_CN.UTF-8"
|
||||||
|
export LC_MESSAGES="zh_CN.UTF-8"
|
||||||
|
export LC_PAPER="zh_CN.UTF-8"
|
||||||
|
export LC_NAME="zh_CN.UTF-8"
|
||||||
|
export LC_ADDRESS="zh_CN.UTF-8"
|
||||||
|
export LC_TELEPHONE="zh_CN.UTF-8"
|
||||||
|
export LC_MEASUREMENT="zh_CN.UTF-8"
|
||||||
|
export LC_IDENTIFICATION="zh_CN.UTF-8"
|
||||||
|
export LC_ALL=zh_CN.UTF-8
|
||||||
|
|
||||||
|
# 输入法环境变量
|
||||||
|
export GTK_IM_MODULE=ibus
|
||||||
|
export QT_IM_MODULE=ibus
|
||||||
|
export XMODIFIERS=@im=ibus
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 用户级配置
|
||||||
|
if [ ! -z "$SUDO_USER" ]; then
|
||||||
|
USER_HOME=$(getent passwd $SUDO_USER | cut -d: -f6)
|
||||||
|
|
||||||
|
echo "# 中文环境设置" >> "$USER_HOME/.bashrc"
|
||||||
|
echo "export LANG=zh_CN.UTF-8" >> "$USER_HOME/.bashrc"
|
||||||
|
echo "export LANGUAGE=zh_CN:zh" >> "$USER_HOME/.bashrc"
|
||||||
|
echo "export LC_ALL=zh_CN.UTF-8" >> "$USER_HOME/.bashrc"
|
||||||
|
echo "" >> "$USER_HOME/.bashrc"
|
||||||
|
echo "# 输入法设置" >> "$USER_HOME/.bashrc"
|
||||||
|
echo "export GTK_IM_MODULE=ibus" >> "$USER_HOME/.bashrc"
|
||||||
|
echo "export QT_IM_MODULE=ibus" >> "$USER_HOME/.bashrc"
|
||||||
|
echo "export XMODIFIERS=@im=ibus" >> "$USER_HOME/.bashrc"
|
||||||
|
|
||||||
|
# 创建输入法自动启动
|
||||||
|
mkdir -p "$USER_HOME/.config/autostart"
|
||||||
|
cat > "$USER_HOME/.config/autostart/ibus-daemon.desktop" << 'EOF'
|
||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
Name=IBus Daemon
|
||||||
|
Comment=IBus Input Method Framework
|
||||||
|
Exec=ibus-daemon -drx
|
||||||
|
OnlyShowIn=GNOME;XFCE;
|
||||||
|
AutostartCondition=GSettings org.freedesktop.ibus.general preload-engines
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chown -R $SUDO_USER:$SUDO_USER "$USER_HOME/.config"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 安装中文软件
|
||||||
|
install_chinese_software() {
|
||||||
|
echo -e "${YELLOW}[11/12] 安装中文软件包...${NC}"
|
||||||
|
|
||||||
|
apt install -y \
|
||||||
|
manpages-zh \
|
||||||
|
firefox-esr-l10n-zh-cn \
|
||||||
|
chromium-l10n \
|
||||||
|
thunderbird-l10n-zh-cn \
|
||||||
|
libreoffice-l10n-zh-cn \
|
||||||
|
libreoffice-help-zh-cn
|
||||||
|
|
||||||
|
# 安装中文文档
|
||||||
|
apt install -y \
|
||||||
|
kali-docs-zh-cn \
|
||||||
|
kali-tools-doc-zh
|
||||||
|
}
|
||||||
|
|
||||||
|
# 清理和完成
|
||||||
|
cleanup() {
|
||||||
|
echo -e "${YELLOW}[12/12] 清理和完成配置...${NC}"
|
||||||
|
|
||||||
|
# 更新字体缓存
|
||||||
|
fc-cache -fv
|
||||||
|
|
||||||
|
# 清理临时文件
|
||||||
|
rm -f /tmp/sources_*.list
|
||||||
|
rm -f /tmp/msyh*.ttf 2>/dev/null
|
||||||
|
|
||||||
|
# 清理包缓存
|
||||||
|
apt autoremove -y
|
||||||
|
apt clean
|
||||||
|
|
||||||
|
echo -e "${GREEN}=================================${NC}"
|
||||||
|
echo -e "${GREEN} 配置完成! ${NC}"
|
||||||
|
echo -e "${GREEN}=================================${NC}"
|
||||||
|
echo ""
|
||||||
|
echo -e "${YELLOW}重要提示:${NC}"
|
||||||
|
echo "1. 建议重启系统以应用所有更改"
|
||||||
|
echo "2. 输入法切换快捷键:Super+Space (Win+空格)"
|
||||||
|
echo "3. 如果需要配置输入法:"
|
||||||
|
echo " - IBus: 运行 ibus-setup"
|
||||||
|
echo " - Fcitx: 运行 fcitx-config-gtk3"
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}当前语言设置:${NC}"
|
||||||
|
echo "LANG=$LANG"
|
||||||
|
echo "LANGUAGE=$LANGUAGE"
|
||||||
|
echo "LC_ALL=$LC_ALL"
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}Enjoy your Chinese Kali Linux!${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 主执行流程
|
||||||
|
main() {
|
||||||
|
backup_sources
|
||||||
|
update_sources
|
||||||
|
update_packages
|
||||||
|
install_chinese_fonts
|
||||||
|
install_language_pack
|
||||||
|
configure_locale
|
||||||
|
install_input_method
|
||||||
|
configure_environment
|
||||||
|
install_chinese_software
|
||||||
|
cleanup
|
||||||
|
}
|
||||||
|
|
||||||
|
# 执行主函数
|
||||||
|
main
|
||||||
237
nginx
Normal file
237
nginx
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# ==================================================
|
||||||
|
# Nginx Proxy Manager 一键安装脚本
|
||||||
|
# 版本: 1.0
|
||||||
|
# 描述: 自动部署 Nginx Proxy Manager 反向代理管理工具
|
||||||
|
# ==================================================
|
||||||
|
|
||||||
|
# 脚本配置
|
||||||
|
APP_NAME="nginx-proxy-manager"
|
||||||
|
SCRIPT_NAME="deploy_nginx_proxy_manager.sh"
|
||||||
|
WORK_DIR="/data"
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# 日志函数
|
||||||
|
log_info() {
|
||||||
|
echo -e "${BLUE}[INFO]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_success() {
|
||||||
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_warning() {
|
||||||
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_error() {
|
||||||
|
echo -e "${RED}[ERROR]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 错误处理函数
|
||||||
|
error_exit() {
|
||||||
|
log_error "$1"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 清理函数
|
||||||
|
cleanup() {
|
||||||
|
log_info "正在清理临时资源..."
|
||||||
|
# 可以在这里添加清理代码
|
||||||
|
}
|
||||||
|
|
||||||
|
# 信号处理
|
||||||
|
trap cleanup EXIT INT TERM
|
||||||
|
|
||||||
|
# ==================================================
|
||||||
|
# 环境检查
|
||||||
|
# ==================================================
|
||||||
|
|
||||||
|
log_info "开始检查运行环境..."
|
||||||
|
|
||||||
|
# 检查是否为 root 用户
|
||||||
|
if [[ $EUID -eq 0 ]]; then
|
||||||
|
log_warning "建议使用非 root 用户执行此脚本,但将继续执行..."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查 Docker 是否安装
|
||||||
|
if ! command -v docker &> /dev/null; then
|
||||||
|
error_exit "Docker 未安装,请先安装 Docker"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查 Docker 服务状态
|
||||||
|
if ! systemctl is-active --quiet docker && ! systemctl is-active --quiet docker.service; then
|
||||||
|
log_info "尝试启动 Docker 服务..."
|
||||||
|
if ! sudo systemctl start docker 2>/dev/null; then
|
||||||
|
error_exit "Docker 服务未运行且无法启动"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 测试 Docker 是否正常工作
|
||||||
|
if ! docker info &> /dev/null; then
|
||||||
|
error_exit "Docker 无法正常工作,请检查 Docker 服务状态"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_success "环境检查通过"
|
||||||
|
|
||||||
|
# ==================================================
|
||||||
|
# 目录准备
|
||||||
|
# ==================================================
|
||||||
|
|
||||||
|
log_info "正在准备工作目录..."
|
||||||
|
|
||||||
|
# 创建并切换到工作目录
|
||||||
|
if [[ ! -d "$WORK_DIR" ]]; then
|
||||||
|
log_info "创建工作目录: $WORK_DIR"
|
||||||
|
if ! sudo mkdir -p "$WORK_DIR" 2>/dev/null && ! mkdir -p "$WORK_DIR"; then
|
||||||
|
error_exit "无法创建目录 $WORK_DIR,请检查权限"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 进入工作目录
|
||||||
|
cd "$WORK_DIR" || error_exit "无法进入目录 $WORK_DIR"
|
||||||
|
|
||||||
|
# 创建必要的子目录
|
||||||
|
for dir in nginx-proxy-manager/data nginx-proxy-manager/letsencrypt; do
|
||||||
|
if [[ ! -d "$dir" ]]; then
|
||||||
|
log_info "创建目录: $WORK_DIR/$dir"
|
||||||
|
mkdir -p "$dir" || error_exit "无法创建目录 $dir"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
log_success "目录准备完成"
|
||||||
|
|
||||||
|
# ==================================================
|
||||||
|
# 停止并删除现有容器(如果存在)
|
||||||
|
# ==================================================
|
||||||
|
|
||||||
|
log_info "检查现有容器..."
|
||||||
|
|
||||||
|
if docker ps -a --format "table {{.Names}}" | grep -q "^${APP_NAME}$"; then
|
||||||
|
log_info "发现已存在的容器,正在停止并删除..."
|
||||||
|
|
||||||
|
# 停止容器
|
||||||
|
if docker ps --format "table {{.Names}}" | grep -q "^${APP_NAME}$"; then
|
||||||
|
docker stop "$APP_NAME" || log_warning "停止容器失败,但将继续执行"
|
||||||
|
sleep 5
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 删除容器
|
||||||
|
docker rm "$APP_NAME" || error_exit "删除旧容器失败"
|
||||||
|
log_success "旧容器清理完成"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ==================================================
|
||||||
|
# 拉取 Docker 镜像
|
||||||
|
# ==================================================
|
||||||
|
|
||||||
|
log_info "正在拉取 Nginx Proxy Manager 镜像..."
|
||||||
|
|
||||||
|
# 设置重试机制
|
||||||
|
MAX_RETRIES=3
|
||||||
|
RETRY_COUNT=0
|
||||||
|
|
||||||
|
while [[ $RETRY_COUNT -lt $MAX_RETRIES ]]; do
|
||||||
|
if docker pull docker.io/jc21/nginx-proxy-manager:latest; then
|
||||||
|
log_success "镜像拉取成功"
|
||||||
|
break
|
||||||
|
else
|
||||||
|
RETRY_COUNT=$((RETRY_COUNT + 1))
|
||||||
|
if [[ $RETRY_COUNT -eq $MAX_RETRIES ]]; then
|
||||||
|
error_exit "镜像拉取失败,已达到最大重试次数"
|
||||||
|
else
|
||||||
|
log_warning "镜像拉取失败,第 $RETRY_COUNT 次重试..."
|
||||||
|
sleep 10
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# ==================================================
|
||||||
|
# 部署容器
|
||||||
|
# ==================================================
|
||||||
|
|
||||||
|
log_info "正在启动 Nginx Proxy Manager 容器..."
|
||||||
|
|
||||||
|
DOCKER_RUN_CMD="docker run -d \
|
||||||
|
--name $APP_NAME \
|
||||||
|
--restart=unless-stopped \
|
||||||
|
-p 80:80 \
|
||||||
|
-p 81:81 \
|
||||||
|
-p 443:443 \
|
||||||
|
-v $WORK_DIR/nginx-proxy-manager/data:/data \
|
||||||
|
-v $WORK_DIR/nginx-proxy-manager/letsencrypt:/etc/letsencrypt \
|
||||||
|
docker.io/jc21/nginx-proxy-manager:latest"
|
||||||
|
|
||||||
|
log_info "执行命令: $DOCKER_RUN_CMD"
|
||||||
|
|
||||||
|
if ! eval "$DOCKER_RUN_CMD"; then
|
||||||
|
error_exit "容器启动失败"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_success "容器启动命令执行成功"
|
||||||
|
|
||||||
|
# ==================================================
|
||||||
|
# 等待并验证服务状态
|
||||||
|
# ==================================================
|
||||||
|
|
||||||
|
log_info "等待服务启动..."
|
||||||
|
sleep 10
|
||||||
|
|
||||||
|
# 检查容器状态
|
||||||
|
if ! docker ps --format "table {{.Names}}\t{{.Status}}" | grep -q "$APP_NAME"; then
|
||||||
|
error_exit "容器未运行,请检查日志: docker logs $APP_NAME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
CONTAINER_STATUS=$(docker inspect --format='{{.State.Status}}' "$APP_NAME" 2>/dev/null || echo "unknown")
|
||||||
|
if [[ "$CONTAINER_STATUS" != "running" ]]; then
|
||||||
|
error_exit "容器状态异常: $CONTAINER_STATUS,请检查日志: docker logs $APP_NAME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查服务端口
|
||||||
|
PORTS=(80 81 443)
|
||||||
|
for port in "${PORTS[@]}"; do
|
||||||
|
if ! ss -tln | grep -q ":$port "; then
|
||||||
|
log_warning "端口 $port 未监听,服务可能仍在启动中"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
log_success "Nginx Proxy Manager 部署完成!"
|
||||||
|
|
||||||
|
# ==================================================
|
||||||
|
# 显示部署信息
|
||||||
|
# ==================================================
|
||||||
|
|
||||||
|
echo
|
||||||
|
log_success "🎉 Nginx Proxy Manager 部署成功!"
|
||||||
|
echo
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo "访问地址: http://$(hostname -I | awk '{print $1}'):81"
|
||||||
|
echo "默认邮箱: admin@example.com"
|
||||||
|
echo "默认密码: changeme"
|
||||||
|
echo
|
||||||
|
echo "重要提示:"
|
||||||
|
echo "1. 首次登录后请立即修改默认密码"
|
||||||
|
echo "2. 管理界面运行在 81 端口"
|
||||||
|
echo "3. 数据存储位置: $WORK_DIR/nginx-proxy-manager/"
|
||||||
|
echo "4. 查看容器日志: docker logs $APP_NAME"
|
||||||
|
echo "5. 停止服务: docker stop $APP_NAME"
|
||||||
|
echo "6. 启动服务: docker start $APP_NAME"
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# 显示容器状态
|
||||||
|
log_info "当前容器状态:"
|
||||||
|
docker ps --filter "name=$APP_NAME" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
|
||||||
|
|
||||||
|
# 显示数据目录结构
|
||||||
|
log_info "数据目录结构:"
|
||||||
|
find "$WORK_DIR/nginx-proxy-manager" -type f -name "*" | head -10
|
||||||
124
ru
124
ru
@@ -1,14 +1,59 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
sudo mkdir -p /data
|
|
||||||
sudo mkdir -p /boot/脚本
|
# 颜色定义
|
||||||
file_path="/boot/脚本/ru.yaml"
|
GREEN="\033[32m"
|
||||||
echo "# 方便检查的备注
|
RED="\033[31m"
|
||||||
#./apimain reset-admin-pwd <pwd>
|
YELLOW="\033[33m"
|
||||||
|
PLAIN="\033[0m"
|
||||||
|
|
||||||
|
echo -e "${GREEN}=============================================${PLAIN}"
|
||||||
|
echo -e "${GREEN} RustDesk Server (S6版) 一键部署脚本 ${PLAIN}"
|
||||||
|
echo -e "${GREEN}=============================================${PLAIN}"
|
||||||
|
|
||||||
|
# 1. 检查是否为 Root 用户
|
||||||
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
echo -e "${RED}错误:请使用 root 用户运行此脚本!${PLAIN}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. 检查 Docker 是否安装
|
||||||
|
if ! command -v docker &> /dev/null; then
|
||||||
|
echo -e "${RED}未检测到 Docker,请先安装 Docker 和 Docker Compose!${PLAIN}"
|
||||||
|
echo -e "你可以尝试运行:curl -fsSL https://get.docker.com | bash"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 3. 设置安装目录
|
||||||
|
INSTALL_DIR="/data/rustdesk"
|
||||||
|
echo -e "${YELLOW}默认安装目录: ${INSTALL_DIR}${PLAIN}"
|
||||||
|
|
||||||
|
# 创建目录
|
||||||
|
mkdir -p "${INSTALL_DIR}/data"
|
||||||
|
mkdir -p "${INSTALL_DIR}/api"
|
||||||
|
|
||||||
|
# 4. 获取用户输入 (公网IP/域名)
|
||||||
|
read -p "请输入服务器的公网 IP 或解析好的域名 (必填): " HOST_IP
|
||||||
|
if [[ -z "$HOST_IP" ]]; then
|
||||||
|
echo -e "${RED}错误:必须输入 IP 或域名!${PLAIN}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 进入目录
|
||||||
|
cd "$INSTALL_DIR" || exit
|
||||||
|
|
||||||
|
# 5. 生成 docker-compose.yml
|
||||||
|
echo -e "${YELLOW}正在生成配置文件...${PLAIN}"
|
||||||
|
|
||||||
|
cat > docker-compose.yml <<EOF
|
||||||
|
version: '3'
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
rustdesk-net:
|
rustdesk-net:
|
||||||
external: false
|
external: false
|
||||||
|
|
||||||
services:
|
services:
|
||||||
rustdesk:
|
rustdesk:
|
||||||
|
container_name: rustdesk-server
|
||||||
ports:
|
ports:
|
||||||
- 21114:21114
|
- 21114:21114
|
||||||
- 21115:21115
|
- 21115:21115
|
||||||
@@ -19,35 +64,58 @@ services:
|
|||||||
- 21119:21119
|
- 21119:21119
|
||||||
image: lejianwen/rustdesk-server-s6:latest
|
image: lejianwen/rustdesk-server-s6:latest
|
||||||
environment:
|
environment:
|
||||||
- RELAY=127.0.0.1
|
# 公网IP或域名
|
||||||
|
- RELAY=${HOST_IP}
|
||||||
|
# 强制必须登录才能连接
|
||||||
|
- MUST_LOGIN=Y
|
||||||
|
# 单个连接限速 2MB/s = 16Mb/s
|
||||||
|
- SINGLE_BANDWIDTH=16
|
||||||
|
# 总带宽限制
|
||||||
|
- TOTAL_BANDWIDTH=100
|
||||||
|
# 只允许加密连接
|
||||||
- ENCRYPTED_ONLY=1
|
- ENCRYPTED_ONLY=1
|
||||||
- MUST_LOGIN=y
|
# 时区设置
|
||||||
- TZ=Asia/Shanghai
|
- TZ=Asia/Shanghai
|
||||||
- RUSTDESK_API_RUSTDESK_ID_SERVER=127.0.0.1:21116
|
|
||||||
- RUSTDESK_API_RUSTDESK_RELAY_SERVER=127.0.0.1:21117
|
|
||||||
- RUSTDESK_API_RUSTDESK_API_SERVER=http://127.0.0.1:21114
|
|
||||||
- RUSTDESK_API_KEY_FILE=/data/id_ed25519.pub
|
|
||||||
- RUSTDESK_API_JWT_KEY=xxx23344 # jwt key
|
|
||||||
volumes:
|
volumes:
|
||||||
- /data/rustdesk/server:/data
|
# 密钥和数据持久化目录
|
||||||
- /data/rustdesk/api:/app/data #将数据库挂载
|
- ${INSTALL_DIR}/data:/data
|
||||||
|
# API数据库目录
|
||||||
|
- ${INSTALL_DIR}/api:/app/data
|
||||||
networks:
|
networks:
|
||||||
- rustdesk-net
|
- rustdesk-net
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
EOF
|
||||||
|
|
||||||
" > "$file_path"
|
# 6. 启动容器
|
||||||
sleep 1
|
echo -e "${YELLOW}正在拉取镜像并启动容器...${PLAIN}"
|
||||||
docker compose -p my_rustdesk_project -f /boot/脚本/ru.yaml up -d
|
docker compose pull
|
||||||
while true; do
|
docker compose up -d
|
||||||
if docker ps | grep -q "my_rustdesk_project-rustdesk-1"; then
|
|
||||||
|
# 7. 检查状态并获取 Key
|
||||||
docker exec -it my_rustdesk_project-rustdesk-1 sh -c './apimain reset-admin-pwd 3459635287'
|
if [ $? -eq 0 ]; then
|
||||||
show scope global | grep -oP 'inet \K[\d.]+' | head -n 1 | sed 's/^/访问地址: /;s/$/:21114/' | tr -d '\r'
|
echo -e "${GREEN}服务启动成功!${PLAIN}"
|
||||||
echo -e "\033[32mRustDesk管理员账号: admin\033[0m"
|
echo -e "${YELLOW}正在等待密钥生成 (约5秒)...${PLAIN}"
|
||||||
echo -e "\033[32mRustDesk管理员密码: 3459635287\033[0m"
|
sleep 5
|
||||||
break
|
|
||||||
|
# 尝试读取公钥
|
||||||
|
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 "${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 "Key (公钥):"
|
||||||
|
echo -e "${YELLOW}${PUB_KEY}${PLAIN}"
|
||||||
|
echo -e "${GREEN}=============================================${PLAIN}"
|
||||||
|
echo -e "请将以上信息填入 RustDesk 客户端的网络设置中。"
|
||||||
else
|
else
|
||||||
sleep 1
|
echo -e "${RED}无法自动读取公钥,请手动检查目录:${INSTALL_DIR}/data${PLAIN}"
|
||||||
|
echo -e "或者查看日志:docker logs rustdesk-server"
|
||||||
fi
|
fi
|
||||||
1
|
else
|
||||||
done
|
echo -e "${RED}服务启动失败,请检查 Docker 日志。${PLAIN}"
|
||||||
|
fi
|
||||||
|
|||||||
351
ssh
Normal file
351
ssh
Normal file
@@ -0,0 +1,351 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# ========================================================
|
||||||
|
# 🛡️ secure-ssh-setup.sh
|
||||||
|
# 自动配置 SSH 服务 | 支持密钥登录 | 防火墙放行 | 安全加固
|
||||||
|
# 作者:AI 助手 | 兼容 Ubuntu/CentOS/Debian/RHEL
|
||||||
|
# 无需 Python,一键运行
|
||||||
|
# ========================================================
|
||||||
|
|
||||||
|
set -euo pipefail # 严格模式:出错退出、未定义变量报错、管道错误捕获
|
||||||
|
|
||||||
|
# -------------------------------
|
||||||
|
# 🔧 配置选项(可自定义)
|
||||||
|
# -------------------------------
|
||||||
|
|
||||||
|
SSH_PORT=${SSH_PORT:-22} # SSH 端口(默认 22)
|
||||||
|
ENABLE_PASSWORD_LOGIN=${ENABLE_PASSWORD_LOGIN:-yes} # 是否允许密码登录
|
||||||
|
ENABLE_ROOT_LOGIN=${ENABLE_ROOT_LOGIN:-no} # 是否允许 root 密码登录(no 更安全)
|
||||||
|
AUTO_INSTALL_SSH=${AUTO_INSTALL_SSH:-yes} # 是否自动安装 openssh-server
|
||||||
|
USE_KEY_LOGIN=${USE_KEY_LOGIN:-yes} # 是否生成密钥并启用密钥登录
|
||||||
|
|
||||||
|
# -------------------------------
|
||||||
|
# 🧰 工具函数
|
||||||
|
# -------------------------------
|
||||||
|
|
||||||
|
log() {
|
||||||
|
echo "[$(date +'%H:%M:%S')] 📝 $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
success() {
|
||||||
|
echo "[$(date +'%H:%M:%S')] ✅ $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
echo "[$(date +'%H:%M:%S')] ❌ $*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
warn() {
|
||||||
|
echo "[$(date +'%H:%M:%S')] ⚠️ $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查命令是否存在
|
||||||
|
has_cmd() {
|
||||||
|
command -v "$1" &>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# 等待用户确认(可跳过)
|
||||||
|
confirm() {
|
||||||
|
if [[ "${FORCE:-}" == "yes" ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
read -p "$1 [y/N]: " -n 1 -r
|
||||||
|
echo
|
||||||
|
[[ ! $REPLY =~ ^[Yy]$ ]] && return 1
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# -------------------------------
|
||||||
|
# 🖥️ 检测系统信息
|
||||||
|
# -------------------------------
|
||||||
|
|
||||||
|
detect_os() {
|
||||||
|
if [[ -f /etc/os-release ]]; then
|
||||||
|
. /etc/os-release
|
||||||
|
OS_NAME="$NAME"
|
||||||
|
OS_ID="$ID"
|
||||||
|
OS_VERSION="$VERSION_ID"
|
||||||
|
elif [[ -f /etc/redhat-release ]]; then
|
||||||
|
OS_NAME=$(cat /etc/redhat-release)
|
||||||
|
OS_ID="rhel"
|
||||||
|
else
|
||||||
|
OS_NAME=$(uname -s)
|
||||||
|
OS_ID="unknown"
|
||||||
|
fi
|
||||||
|
log "检测到系统: $OS_NAME"
|
||||||
|
}
|
||||||
|
|
||||||
|
# -------------------------------
|
||||||
|
# 🔧 安装 OpenSSH 服务(如未安装)
|
||||||
|
# -------------------------------
|
||||||
|
|
||||||
|
install_ssh_server() {
|
||||||
|
if has_cmd sshd || has_cmd ssh; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$AUTO_INSTALL_SSH" != "yes" ]]; then
|
||||||
|
error "SSH 服务未安装,且 AUTO_INSTALL_SSH=no,退出。"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "OpenSSH 未安装,正在安装..."
|
||||||
|
|
||||||
|
case "$OS_ID" in
|
||||||
|
ubuntu|debian)
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get update -qq
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y openssh-server
|
||||||
|
;;
|
||||||
|
centos|rhel|almalinux|rocky)
|
||||||
|
yum install -y openssh-server || true
|
||||||
|
# 对于较新系统使用 dnf
|
||||||
|
if ! has_cmd sshd && has_cmd dnf; then
|
||||||
|
dnf install -y openssh-server
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
arch)
|
||||||
|
pacman -S openssh
|
||||||
|
;;
|
||||||
|
suse|opensuse)
|
||||||
|
zypper install -y openssh
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
error "不支持的系统类型,无法自动安装 SSH"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if ! has_cmd sshd && ! has_cmd ssh; then
|
||||||
|
error "安装失败,请手动安装 openssh-server"
|
||||||
|
fi
|
||||||
|
|
||||||
|
success "OpenSSH 安装完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
# -------------------------------
|
||||||
|
# ⚙️ 配置 SSH 服务
|
||||||
|
# -------------------------------
|
||||||
|
|
||||||
|
configure_ssh() {
|
||||||
|
local config="/etc/ssh/sshd_config"
|
||||||
|
local backup="${config}.backup.$(date +%s)"
|
||||||
|
|
||||||
|
# 备份原始配置
|
||||||
|
if [[ ! -f "$backup" && -f "$config" ]]; then
|
||||||
|
cp "$config" "$backup"
|
||||||
|
success "SSH 配置已备份: $backup"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 确保目录存在
|
||||||
|
mkdir -p /etc/ssh
|
||||||
|
|
||||||
|
# 写入基础配置(如果文件不存在)
|
||||||
|
if [[ ! -f "$config" ]]; then
|
||||||
|
log "创建新的 sshd_config 文件"
|
||||||
|
{
|
||||||
|
echo "Port $SSH_PORT"
|
||||||
|
echo "PermitRootLogin $( [[ "$ENABLE_ROOT_LOGIN" == "yes" ]] && echo "yes" || echo "prohibit-password" )"
|
||||||
|
echo "PasswordAuthentication $ENABLE_PASSWORD_LOGIN"
|
||||||
|
echo "PubkeyAuthentication yes"
|
||||||
|
echo "AuthorizedKeysFile .ssh/authorized_keys"
|
||||||
|
echo "ChallengeResponseAuthentication no"
|
||||||
|
echo "UsePAM yes"
|
||||||
|
echo "X11Forwarding yes"
|
||||||
|
echo "PrintMotd no"
|
||||||
|
echo "AcceptEnv LANG LC_*"
|
||||||
|
echo "Subsystem sftp /usr/lib/openssh/sftp-server"
|
||||||
|
} > "$config"
|
||||||
|
else
|
||||||
|
# 修改现有配置
|
||||||
|
sed -i "s/^#*Port .*/Port $SSH_PORT/" "$config"
|
||||||
|
sed -i "s/^#*PermitRootLogin .*/PermitRootLogin $( [[ "$ENABLE_ROOT_LOGIN" == "yes" ]] && echo "yes" || echo "prohibit-password" )/" "$config"
|
||||||
|
sed -i "s/^#*PasswordAuthentication .*/PasswordAuthentication $ENABLE_PASSWORD_LOGIN/" "$config"
|
||||||
|
sed -i "s/^#*PubkeyAuthentication .*/PubkeyAuthentication yes/" "$config"
|
||||||
|
sed -i "s/^#*AuthorizedKeysFile .*/AuthorizedKeysFile .ssh\/authorized_keys/" "$config"
|
||||||
|
fi
|
||||||
|
|
||||||
|
success "SSH 配置已更新 (端口: $SSH_PORT)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# -------------------------------
|
||||||
|
# ▶️ 启动并启用 SSH 服务
|
||||||
|
# -------------------------------
|
||||||
|
|
||||||
|
start_ssh_service() {
|
||||||
|
local service=""
|
||||||
|
|
||||||
|
for s in sshd ssh; do
|
||||||
|
if systemctl list-unit-files | grep -q "$s"; then
|
||||||
|
service="$s"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -z "$service" ]]; then
|
||||||
|
error "未找到 SSH 服务,请检查是否安装正确"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if systemctl is-active --quiet "$service"; then
|
||||||
|
success "$service 已在运行"
|
||||||
|
else
|
||||||
|
log "启动 $service 服务..."
|
||||||
|
systemctl start "$service" && systemctl enable "$service"
|
||||||
|
success "$service 已启动并设置开机自启"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查端口是否监听
|
||||||
|
if ! has_cmd ss && has_cmd netstat; then
|
||||||
|
if ! netstat -tuln | grep -q ":$SSH_PORT\b"; then
|
||||||
|
warn "端口 $SSH_PORT 未监听,尝试重启..."
|
||||||
|
systemctl restart "$service"
|
||||||
|
sleep 2
|
||||||
|
if ! netstat -tuln | grep -q ":$SSH_PORT\b"; then
|
||||||
|
error "SSH 服务启动失败,请检查日志: journalctl -u $service"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if ! ss -tuln | grep -q ":$SSH_PORT\b"; then
|
||||||
|
warn "端口 $SSH_PORT 未监听,尝试重启..."
|
||||||
|
systemctl restart "$service"
|
||||||
|
sleep 2
|
||||||
|
if ! ss -tuln | grep -q ":$SSH_PORT\b"; then
|
||||||
|
error "SSH 服务启动失败,请检查日志: journalctl -u $service"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# -------------------------------
|
||||||
|
# 🔥 配置防火墙
|
||||||
|
# -------------------------------
|
||||||
|
|
||||||
|
setup_firewall() {
|
||||||
|
if has_cmd ufw; then
|
||||||
|
if ! ufw status | grep -q inactive; then
|
||||||
|
ufw allow "$SSH_PORT/tcp" && success "UFW: 放行端口 $SSH_PORT"
|
||||||
|
else
|
||||||
|
log "UFW 处于非活动状态,启用中..."
|
||||||
|
yes | ufw enable && ufw allow "$SSH_PORT/tcp"
|
||||||
|
success "UFW 已启用并放行 $SSH_PORT"
|
||||||
|
fi
|
||||||
|
elif has_cmd firewall-cmd; then
|
||||||
|
if firewall-cmd --state &>/dev/null; then
|
||||||
|
firewall-cmd --permanent --add-port="$SSH_PORT"/tcp --zone=public
|
||||||
|
firewall-cmd --reload
|
||||||
|
success "Firewalld: 放行端口 $SSH_PORT"
|
||||||
|
else
|
||||||
|
warn "Firewalld 未运行"
|
||||||
|
fi
|
||||||
|
elif has_cmd iptables; then
|
||||||
|
iptables -A INPUT -p tcp --dport "$SSH_PORT" -j ACCEPT
|
||||||
|
success "Iptables: 放行端口 $SSH_PORT"
|
||||||
|
else
|
||||||
|
warn "未检测到 UFW、Firewalld 或 Iptables,跳过防火墙配置"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# -------------------------------
|
||||||
|
# 🔑 配置密钥登录
|
||||||
|
# -------------------------------
|
||||||
|
|
||||||
|
setup_key_login() {
|
||||||
|
if [[ "$USE_KEY_LOGIN" != "yes" ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
local user="${SUDO_USER:-$USER}"
|
||||||
|
local home
|
||||||
|
home=$(getent passwd "$user" | cut -d: -f6) || error "无法获取用户 $user 的家目录"
|
||||||
|
|
||||||
|
if [[ -z "$home" || ! -d "$home" ]]; then
|
||||||
|
error "用户 $user 的家目录不存在"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local ssh_dir="$home/.ssh"
|
||||||
|
local key_file="$ssh_dir/id_rsa"
|
||||||
|
local pub_key="$key_file.pub"
|
||||||
|
local auth_keys="$ssh_dir/authorized_keys"
|
||||||
|
|
||||||
|
mkdir -p "$ssh_dir"
|
||||||
|
chmod 700 "$ssh_dir"
|
||||||
|
|
||||||
|
# 生成密钥(如果不存在)
|
||||||
|
if [[ ! -f "$key_file" ]]; then
|
||||||
|
log "为用户 $user 生成 SSH 密钥对..."
|
||||||
|
if sudo -u "$user" ssh-keygen -t rsa -b 2048 -f "$key_file" -N "" </dev/null 2>/dev/null; then
|
||||||
|
success "密钥已生成: $key_file"
|
||||||
|
else
|
||||||
|
warn "密钥生成失败,跳过"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 添加公钥到 authorized_keys
|
||||||
|
if [[ -f "$pub_key" ]]; then
|
||||||
|
mkdir -p "$ssh_dir"
|
||||||
|
cat "$pub_key" >> "$auth_keys" 2>/dev/null || true
|
||||||
|
chmod 600 "$auth_keys"
|
||||||
|
chown -R "$user:$user" "$ssh_dir"
|
||||||
|
success "公钥已添加到 $auth_keys,支持密钥登录"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# -------------------------------
|
||||||
|
# 🧹 清理临时变量
|
||||||
|
# -------------------------------
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
unset SSH_PORT ENABLE_PASSWORD_LOGIN ENABLE_ROOT_LOGIN AUTO_INSTALL_SSH USE_KEY_LOGIN FORCE
|
||||||
|
}
|
||||||
|
|
||||||
|
# -------------------------------
|
||||||
|
# 🚀 主函数
|
||||||
|
# -------------------------------
|
||||||
|
|
||||||
|
main() {
|
||||||
|
log "开始配置 SSH 服务..."
|
||||||
|
|
||||||
|
# 提示用户
|
||||||
|
echo
|
||||||
|
echo "配置摘要:"
|
||||||
|
echo " SSH 端口: $SSH_PORT"
|
||||||
|
echo " 允许密码登录: $ENABLE_PASSWORD_LOGIN"
|
||||||
|
echo " 允许 root 登录: $ENABLE_ROOT_LOGIN"
|
||||||
|
echo " 自动生成密钥: $USE_KEY_LOGIN"
|
||||||
|
echo
|
||||||
|
|
||||||
|
if ! confirm "确认执行配置?"; then
|
||||||
|
log "用户取消,退出。"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
detect_os
|
||||||
|
install_ssh_server
|
||||||
|
configure_ssh
|
||||||
|
start_ssh_service
|
||||||
|
setup_firewall
|
||||||
|
setup_key_login
|
||||||
|
|
||||||
|
# 最终提示
|
||||||
|
echo
|
||||||
|
echo "=================================================="
|
||||||
|
echo "✅ SSH 配置完成!"
|
||||||
|
echo "🔑 登录方式:"
|
||||||
|
echo " 密钥登录: ssh -i ~/.ssh/id_rsa $USER@localhost"
|
||||||
|
echo " 或复制公钥到远程: ssh-copy-id user@host"
|
||||||
|
if [[ "$SSH_PORT" != "22" ]]; then
|
||||||
|
echo " 注意端口: -p $SSH_PORT"
|
||||||
|
fi
|
||||||
|
echo "💡 建议:生产环境关闭 PasswordAuthentication"
|
||||||
|
echo "=================================================="
|
||||||
|
}
|
||||||
|
|
||||||
|
# -------------------------------
|
||||||
|
# ✅ 执行
|
||||||
|
# -------------------------------
|
||||||
|
|
||||||
|
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||||
|
if [[ $(id -u) -ne 0 ]]; then
|
||||||
|
error "请使用 sudo 或 root 权限运行此脚本"
|
||||||
|
fi
|
||||||
|
main "$@"
|
||||||
|
cleanup
|
||||||
|
fi
|
||||||
82
ssl
Normal file
82
ssl
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
cat << 'EOF' > cert_factory_interactive.sh
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# 跳板机 SSL 证书申请工厂 (交互版)
|
||||||
|
# ==========================================
|
||||||
|
|
||||||
|
# --- 1. 交互式输入 ---
|
||||||
|
echo "----------------------------------------------------"
|
||||||
|
read -p "请输入您要申请的域名 (例如: ui.shanghi.net): " DOMAIN
|
||||||
|
echo "----------------------------------------------------"
|
||||||
|
|
||||||
|
# 空值检查
|
||||||
|
if [ -z "$DOMAIN" ]; then
|
||||||
|
echo "❌ 错误:域名不能为空,脚本已退出。"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 2. 关键提醒 (跳板机模式专用) ---
|
||||||
|
echo "⚠️ 【重要提醒】 ⚠️"
|
||||||
|
echo "您正在使用跳板机模式。在继续之前,请务必确认:"
|
||||||
|
echo "👉 域名 [$DOMAIN] 的 DNS 解析目前必须指向本机 IP!"
|
||||||
|
echo " (拿到证书后,您再改回 NAT 机器的 IP)"
|
||||||
|
echo ""
|
||||||
|
read -p "确认解析已生效?按回车继续 (或按 Ctrl+C 取消)..."
|
||||||
|
|
||||||
|
# --- 3. 环境准备 ---
|
||||||
|
CERT_DIR="/data"
|
||||||
|
mkdir -p "$CERT_DIR"
|
||||||
|
|
||||||
|
echo "[1/3] 正在检查环境与清理端口..."
|
||||||
|
# 安装 socat
|
||||||
|
if ! command -v socat &> /dev/null; then
|
||||||
|
echo " -> 安装 socat..."
|
||||||
|
if [ -f /usr/bin/apt ]; then apt update && apt install socat -y >/dev/null; fi
|
||||||
|
if [ -f /usr/bin/yum ]; then yum install socat -y >/dev/null; fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 清理 80 端口 (防止 Nginx 等占用)
|
||||||
|
if lsof -Pi :80 -sTCP:LISTEN -t >/dev/null ; then
|
||||||
|
echo " -> 发现 80 端口被占用,正在释放..."
|
||||||
|
fuser -k 80/tcp >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
# 开放防火墙
|
||||||
|
iptables -I INPUT -p tcp --dport 80 -j ACCEPT >/dev/null 2>&1
|
||||||
|
|
||||||
|
# --- 4. 开始申请 ---
|
||||||
|
echo "[2/3] 正在向 CA 机构申请证书 (需等待几秒)..."
|
||||||
|
~/.acme.sh/acme.sh --issue -d "$DOMAIN" --standalone --force
|
||||||
|
|
||||||
|
# --- 5. 结果处理 ---
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "[3/3] 申请成功!正在导出文件..."
|
||||||
|
|
||||||
|
# 安装证书到 /data 目录
|
||||||
|
~/.acme.sh/acme.sh --install-cert -d "$DOMAIN" \
|
||||||
|
--key-file "$CERT_DIR/$DOMAIN.key" \
|
||||||
|
--fullchain-file "$CERT_DIR/$DOMAIN.crt"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "🎉 ======================================= 🎉"
|
||||||
|
echo " 证书申请成功!已保存到本机 /data"
|
||||||
|
echo "==========================================="
|
||||||
|
echo "📂 私钥 (Key): $CERT_DIR/$DOMAIN.key"
|
||||||
|
echo "📄 公钥 (Crt): $CERT_DIR/$DOMAIN.crt"
|
||||||
|
echo "==========================================="
|
||||||
|
echo "💡 下一步提示:"
|
||||||
|
echo "现在您可以把这两个文件复制到您的 NAT 机器上了。"
|
||||||
|
echo "scp -P <端口> $CERT_DIR/$DOMAIN.* root@<NAT_IP>:/您的路径/"
|
||||||
|
echo "==========================================="
|
||||||
|
else
|
||||||
|
echo ""
|
||||||
|
echo "❌ 申请失败!"
|
||||||
|
echo "常见原因:"
|
||||||
|
echo "1. 域名解析还没生效,或者解析的不是这台机器的 IP。"
|
||||||
|
echo "2. 云服务商的安全组(防火墙)没有放行 80 端口。"
|
||||||
|
fi
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 赋予权限并运行
|
||||||
|
chmod +x cert_factory_interactive.sh
|
||||||
|
./cert_factory_interactive.sh
|
||||||
371
xu
Normal file
371
xu
Normal file
@@ -0,0 +1,371 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# 标题:咸v咆哮制作 - X-UI 终极全能版 (V5.6 智能极速版)
|
||||||
|
# 更新:1. 新增源自动测速选择 (Ping检测)
|
||||||
|
# 2. 新增 Aria2 + Axel 双核多线程下载引擎
|
||||||
|
# 基底:V5.5 (全兼容架构)
|
||||||
|
# ==========================================
|
||||||
|
|
||||||
|
# --- 颜色配置 ---
|
||||||
|
Red="\033[31m"
|
||||||
|
Green="\033[32m"
|
||||||
|
Yellow="\033[33m"
|
||||||
|
Blue="\033[36m"
|
||||||
|
Font="\033[0m"
|
||||||
|
|
||||||
|
# --- 核心配置 ---
|
||||||
|
BASE_URL="https://freeyx.vps3344.dpdns.org/xui"
|
||||||
|
DB_URL_1="https://g1.vps7k7k.xyz/xui/x-ui%E6%A0%87%E5%87%86.db"
|
||||||
|
DB_URL_2="https://pub-b69a7194f4ea42fba6aa990c49bded91.r2.dev/xui/x-ui%E6%A0%87%E5%87%86.db"
|
||||||
|
|
||||||
|
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 自动安装脚本 (V5.6 智能极速版) #${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}>> [0/7] 正在检测网络环境...${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. 智能源选择 (自动测速版)
|
||||||
|
# ==========================================
|
||||||
|
auto_select_source() {
|
||||||
|
echo -e "${Yellow}>> [1/7] 正在智能测速选择最佳软件源...${Font}"
|
||||||
|
|
||||||
|
# 定义测试目标
|
||||||
|
ALIYUN_URL="https://mirrors.aliyun.com"
|
||||||
|
GOOGLE_URL="https://www.google.com"
|
||||||
|
|
||||||
|
# 测速逻辑:获取 HTTP 状态码的时间 (超时设为 2秒)
|
||||||
|
# 1. 测国外 (Google)
|
||||||
|
echo -n " 测试国际连通性... "
|
||||||
|
SPEED_GLOBAL=$(curl -o /dev/null -s -w '%{time_total}' --connect-timeout 2 "$GOOGLE_URL")
|
||||||
|
if [ $? -ne 0 ]; then SPEED_GLOBAL=999; echo "超时/无法连接"; else echo "${SPEED_GLOBAL}秒"; fi
|
||||||
|
|
||||||
|
# 2. 测国内 (Aliyun)
|
||||||
|
echo -n " 测试国内连通性... "
|
||||||
|
SPEED_CN=$(curl -o /dev/null -s -w '%{time_total}' --connect-timeout 2 "$ALIYUN_URL")
|
||||||
|
if [ $? -ne 0 ]; then SPEED_CN=999; echo "超时/无法连接"; else echo "${SPEED_CN}秒"; fi
|
||||||
|
|
||||||
|
# 3. 决策
|
||||||
|
# 逻辑:如果 Google 连不上(999) 或者 阿里云速度明显快于 Google,则选国内源
|
||||||
|
if (( $(echo "$SPEED_GLOBAL == 999" | bc -l) )); then
|
||||||
|
echo -e "${Green}>> 判定为中国大陆环境 (无法连接Google),自动选择阿里云源${Font}"
|
||||||
|
SOURCE_CHOICE="1"
|
||||||
|
elif (( $(echo "$SPEED_CN < $SPEED_GLOBAL" | bc -l) )); then
|
||||||
|
echo -e "${Green}>> 阿里云响应更快 (CN:$SPEED_CN vs Global:$SPEED_GLOBAL),自动选择阿里云源${Font}"
|
||||||
|
SOURCE_CHOICE="1"
|
||||||
|
else
|
||||||
|
echo -e "${Green}>> 国际网络良好 (Global:$SPEED_GLOBAL),自动选择 Cloudflare/官方源${Font}"
|
||||||
|
SOURCE_CHOICE="2"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 执行自动选择
|
||||||
|
if command -v bc >/dev/null 2>&1 && command -v curl >/dev/null 2>&1; then
|
||||||
|
auto_select_source
|
||||||
|
else
|
||||||
|
# 如果没有 bc 工具,默认给个提示让用户盲选,或者默认选2
|
||||||
|
echo -e "${Yellow}缺失测速工具,默认选择官方源...${Font}"
|
||||||
|
SOURCE_CHOICE="2"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 执行换源操作
|
||||||
|
PM="apt"
|
||||||
|
if [[ -f /etc/redhat-release ]] || command -v yum >/dev/null 2>&1; then PM="yum"; fi
|
||||||
|
|
||||||
|
if [ "$SOURCE_CHOICE" != "3" ]; then
|
||||||
|
echo -e "${Yellow}>> 正在优化系统软件源...${Font}"
|
||||||
|
if [ "$PM" == "apt" ]; then
|
||||||
|
if [ -f /etc/os-release ]; then . /etc/os-release; CODENAME=$VERSION_CODENAME; else CODENAME="bookworm"; fi
|
||||||
|
cp /etc/apt/sources.list /etc/apt/sources.list.bak.$(date +%s)
|
||||||
|
if [ "$SOURCE_CHOICE" == "1" ]; then
|
||||||
|
DOMAIN="mirrors.aliyun.com"
|
||||||
|
else
|
||||||
|
DOMAIN="debian.cloudflare.mirrors.com"
|
||||||
|
fi
|
||||||
|
cat > /etc/apt/sources.list <<EOF
|
||||||
|
deb https://$DOMAIN/debian/ $CODENAME main non-free non-free-firmware contrib
|
||||||
|
deb-src https://$DOMAIN/debian/ $CODENAME main non-free non-free-firmware contrib
|
||||||
|
deb https://$DOMAIN/debian-security/ $CODENAME-security main
|
||||||
|
deb https://$DOMAIN/debian/ $CODENAME-updates main non-free non-free-firmware contrib
|
||||||
|
EOF
|
||||||
|
elif [ "$PM" == "yum" ]; then
|
||||||
|
mkdir -p /etc/yum.repos.d/bak
|
||||||
|
mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak/ 2>/dev/null
|
||||||
|
if [ "$SOURCE_CHOICE" == "1" ]; then
|
||||||
|
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
|
||||||
|
else
|
||||||
|
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.edge.kernel.org/centos/7/os/x86_64/
|
||||||
|
fi
|
||||||
|
timeout 60 yum makecache >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# 4. 系统环境处理 (双核下载引擎安装)
|
||||||
|
# ==========================================
|
||||||
|
echo -e "${Yellow}>> [2/7] 安装依赖与下载引擎...${Font}"
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
# 容错安装功能工具
|
||||||
|
install_soft sqlite3
|
||||||
|
|
||||||
|
# [新增] 双核下载引擎
|
||||||
|
echo -n " 安装 Axel 加速器... "
|
||||||
|
install_soft axel && echo "完成" || echo "失败(跳过)"
|
||||||
|
|
||||||
|
echo -n " 安装 Aria2 加速器... "
|
||||||
|
install_soft aria2 && echo "完成" || echo "失败(跳过)"
|
||||||
|
|
||||||
|
# 时间同步
|
||||||
|
if ! apt-get install -y ntpdate >/dev/null 2>&1; then
|
||||||
|
apt-get install -y ntpsec-ntpdate >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# CentOS
|
||||||
|
yum install -y epel-release >/dev/null 2>&1
|
||||||
|
yum install -y curl wget tar bc >/dev/null 2>&1
|
||||||
|
install_soft sqlite3
|
||||||
|
install_soft ntpdate
|
||||||
|
install_soft axel
|
||||||
|
install_soft aria2
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# 5. 时间与架构
|
||||||
|
# ==========================================
|
||||||
|
echo -e "${Yellow}>> [3/7] 校准时间...${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
|
||||||
|
|
||||||
|
echo -e "${Yellow}>> [4/7] 识别架构...${Font}"
|
||||||
|
ARCH=$(uname -m)
|
||||||
|
FILE_NAME=""
|
||||||
|
case $ARCH in
|
||||||
|
x86_64) FILE_NAME="x-ui-linux-amd64.tar.gz" ;;
|
||||||
|
aarch64) FILE_NAME="x-ui-linux-arm64.tar.gz" ;;
|
||||||
|
i386|i686) FILE_NAME="x-ui-linux-386.tar.gz" ;;
|
||||||
|
armv5*) FILE_NAME="x-ui-linux-armv5.tar.gz" ;;
|
||||||
|
*) echo -e "${Red}不支持的架构: $ARCH${Font}"; exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# 6. 智能下载管理器 (双核+自动回退)
|
||||||
|
# ==========================================
|
||||||
|
# 参数: $1=URL, $2=OutputFilename
|
||||||
|
download_manager() {
|
||||||
|
local url=$1
|
||||||
|
local file=$2
|
||||||
|
rm -f "$file"
|
||||||
|
|
||||||
|
# 优先级 1: Axel (轻量多线程)
|
||||||
|
if command -v axel >/dev/null 2>&1; then
|
||||||
|
echo -e "${Green}>> 启用 Axel 引擎 (16线程)...${Font}"
|
||||||
|
if axel -n 16 -k -q -o "$file" "$url"; then return 0; fi
|
||||||
|
echo -e "${Red}Axel 下载失败,切换备用引擎...${Font}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 优先级 2: Aria2 (强力多线程)
|
||||||
|
if command -v aria2c >/dev/null 2>&1; then
|
||||||
|
echo -e "${Green}>> 启用 Aria2 引擎 (16线程)...${Font}"
|
||||||
|
# -x16:16连接, -s16:16服务器, -k1M:分块
|
||||||
|
if aria2c -x 16 -s 16 -k 1M -o "$file" "$url" >/dev/null 2>&1; then return 0; fi
|
||||||
|
echo -e "${Red}Aria2 下载失败,切换单线程...${Font}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 优先级 3: Wget (稳定单线程)
|
||||||
|
echo -e "${Yellow}>> 启用 Wget (单线程)...${Font}"
|
||||||
|
if wget $NET_OPT --no-check-certificate --timeout=30 --tries=3 -O "$file" "$url"; then return 0; fi
|
||||||
|
|
||||||
|
# 优先级 4: Curl (最后保底)
|
||||||
|
echo -e "${Yellow}>> 启用 Curl (最后保底)...${Font}"
|
||||||
|
curl $NET_OPT -L -k --connect-timeout 30 --retry 3 -o "$file" "$url"
|
||||||
|
}
|
||||||
|
|
||||||
|
echo -e "${Yellow}>> [5/7] 下载安装包 (Mode: $NET_OPT)...${Font}"
|
||||||
|
cd /usr/local/
|
||||||
|
DOWNLOAD_URL="${BASE_URL}/${FILE_NAME}"
|
||||||
|
|
||||||
|
# 调用下载管理器
|
||||||
|
download_manager "$DOWNLOAD_URL" "$FILE_NAME"
|
||||||
|
|
||||||
|
if ! tar -tzf "$FILE_NAME" >/dev/null 2>&1; then
|
||||||
|
echo -e "${Red}严重错误:安装包下载失败或文件损坏!${Font}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# 7. 安装与配置
|
||||||
|
# ==========================================
|
||||||
|
echo -e "${Yellow}>> [6/7] 安装与配置...${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/
|
||||||
|
|
||||||
|
if [ "$INSTALL_MODE" == "2" ]; then
|
||||||
|
echo -e "${Yellow}>> 正在执行恢复模式,下载配置文件...${Font}"
|
||||||
|
rm -f "$DB_PATH"
|
||||||
|
|
||||||
|
# 尝试下载主备份 (使用智能下载器)
|
||||||
|
download_manager "$DB_URL_1" "$DB_PATH"
|
||||||
|
|
||||||
|
# 检查是否成功,失败则尝试备用
|
||||||
|
if [ ! -s "$DB_PATH" ] || [ $(stat -c%s "$DB_PATH") -lt 1000 ]; then
|
||||||
|
echo -e "${Red}主链接失败,尝试备用链接...${Font}"
|
||||||
|
download_manager "$DB_URL_2" "$DB_PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -s "$DB_PATH" ]; then
|
||||||
|
echo -e "${Green}配置文件恢复成功!${Font}"
|
||||||
|
else
|
||||||
|
echo -e "${Red}配置文件下载失败,将降级为标准安装...${Font}"
|
||||||
|
cp /usr/local/x-ui/bin/x-ui.db "$DB_PATH"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${Yellow}>> 执行标准安装...${Font}"
|
||||||
|
./x-ui setting -port $SET_PORT -username $SET_USER -password $SET_PASS >/dev/null 2>&1
|
||||||
|
[ ! -f "$DB_PATH" ] && cp /usr/local/x-ui/bin/x-ui.db "$DB_PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 统一强制重置账号 ---
|
||||||
|
echo -e "${Yellow}>> 正在强制重置账户权限...${Font}"
|
||||||
|
systemctl stop x-ui >/dev/null 2>&1
|
||||||
|
killall x-ui >/dev/null 2>&1
|
||||||
|
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
|
||||||
|
echo -e "${Green}账户权限重置成功 (SQL模式)${Font}"
|
||||||
|
RESET_SUCCESS=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $RESET_SUCCESS -eq 0 ]; then
|
||||||
|
echo -e "${Yellow}使用官方接口重置账号...${Font}"
|
||||||
|
./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
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# 8. 启动与放行
|
||||||
|
# ==========================================
|
||||||
|
echo -e "${Yellow}>> [7/7] 启动服务...${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} 咸v咆哮制作 - 安装完成 (V5.6 智能极速版) ${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}"
|
||||||
|
if [ "$INSTALL_MODE" == "2" ]; then
|
||||||
|
echo -e "提示 :${Yellow}已成功恢复节点配置,账号密码已重置为 3344${Font}"
|
||||||
|
fi
|
||||||
|
echo -e "${Blue}#################################################${Font}"
|
||||||
58
xuiip6
Normal file
58
xuiip6
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# SOCKS5 自动 kill → 测速 → 恢复 一体脚本
|
||||||
|
# 适配:x-ui / Xray SOCKS5
|
||||||
|
# 目标:杜绝 0 延迟假活
|
||||||
|
|
||||||
|
### ====== 配置区 ======
|
||||||
|
SOCKS_HOST="127.0.0.1"
|
||||||
|
SOCKS_PORT=32238
|
||||||
|
SOCKS_USER="88888888"
|
||||||
|
SOCKS_PASS="88888888"
|
||||||
|
TEST_URL="https://ipv6.google.com"
|
||||||
|
TIMEOUT=15
|
||||||
|
### ====================
|
||||||
|
|
||||||
|
echo "==============================="
|
||||||
|
echo " SOCKS5 自动真实测速开始"
|
||||||
|
echo "==============================="
|
||||||
|
|
||||||
|
echo "[1/5] 清理 SOCKS5 旧会话..."
|
||||||
|
ss -K sport = :$SOCKS_PORT >/dev/null 2>&1 || true
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
echo "[2/5] 等待端口稳定..."
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
echo "[3/5] 进行真实 SOCKS5 出站测速..."
|
||||||
|
START_TIME=$(date +%s%3N)
|
||||||
|
|
||||||
|
HTTP_CODE=$(curl \
|
||||||
|
--socks5-hostname ${SOCKS_USER}:${SOCKS_PASS}@${SOCKS_HOST}:${SOCKS_PORT} \
|
||||||
|
--connect-timeout $TIMEOUT \
|
||||||
|
--max-time $TIMEOUT \
|
||||||
|
-o /tmp/socks5_test.html \
|
||||||
|
-s -w "%{http_code}" \
|
||||||
|
$TEST_URL)
|
||||||
|
|
||||||
|
END_TIME=$(date +%s%3N)
|
||||||
|
ELAPSED=$((END_TIME - START_TIME))
|
||||||
|
|
||||||
|
echo "[4/5] 校验测速结果..."
|
||||||
|
|
||||||
|
if [ "$HTTP_CODE" = "200" ]; then
|
||||||
|
echo "--------------------------------"
|
||||||
|
echo " SOCKS5 出站:成功"
|
||||||
|
echo " HTTP 状态码:$HTTP_CODE"
|
||||||
|
echo " 实际耗时 :${ELAPSED} ms"
|
||||||
|
echo " 结果 :真实出站(非假活)"
|
||||||
|
echo "--------------------------------"
|
||||||
|
else
|
||||||
|
echo "--------------------------------"
|
||||||
|
echo " SOCKS5 出站:失败"
|
||||||
|
echo " HTTP 状态码:$HTTP_CODE"
|
||||||
|
echo " 结果 :出口异常"
|
||||||
|
echo "--------------------------------"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[5/5] 恢复完成(无需人工操作)"
|
||||||
|
echo "==============================="
|
||||||
40
修改系统密码
Normal file
40
修改系统密码
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 修改系统密码脚本
|
||||||
|
# 使用方法: sudo ./change_password.sh [用户名]
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# 新密码
|
||||||
|
NEW_PASSWORD="Xzc3459635287"
|
||||||
|
|
||||||
|
# 检查是否以root权限运行
|
||||||
|
if [ "$EUID" -ne 0 ]; then
|
||||||
|
echo "错误: 请使用 sudo 运行此脚本"
|
||||||
|
echo "用法: sudo $0 [用户名]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 获取要修改的用户名(默认为当前用户)
|
||||||
|
USERNAME=${1:-$USER}
|
||||||
|
|
||||||
|
# 检查用户是否存在
|
||||||
|
if ! id "$USERNAME" &>/dev/null; then
|
||||||
|
echo "错误: 用户 '$USERNAME' 不存在"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "正在修改用户 '$USERNAME' 的密码..."
|
||||||
|
echo "新密码: $NEW_PASSWORD"
|
||||||
|
|
||||||
|
# 使用 chpasswd 修改密码
|
||||||
|
echo "$USERNAME:$NEW_PASSWORD" | chpasswd
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "✅ 密码修改成功!"
|
||||||
|
echo "用户名: $USERNAME"
|
||||||
|
echo "新密码: $NEW_PASSWORD"
|
||||||
|
else
|
||||||
|
echo "❌ 密码修改失败"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
123
关闭防火墙de12
Normal file
123
关闭防火墙de12
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 综合防火墙禁用脚本 - 彻底开放所有端口
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "=== 开始彻底禁用所有防火墙,开放所有端口 ==="
|
||||||
|
|
||||||
|
# 检查root权限
|
||||||
|
if [ "$EUID" -ne 0 ]; then
|
||||||
|
echo "请使用 root 权限运行此脚本"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 函数:检查并停止服务
|
||||||
|
stop_service() {
|
||||||
|
local service_name=$1
|
||||||
|
if systemctl is-active --quiet "$service_name"; then
|
||||||
|
echo "停止 $service_name 服务..."
|
||||||
|
systemctl stop "$service_name"
|
||||||
|
systemctl disable "$service_name"
|
||||||
|
echo "✓ $service_name 已停止并禁用"
|
||||||
|
else
|
||||||
|
echo "✓ $service_name 未运行"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 停止所有防火墙服务
|
||||||
|
stop_service "ufw"
|
||||||
|
stop_service "firewalld"
|
||||||
|
stop_service "nftables"
|
||||||
|
stop_service "iptables"
|
||||||
|
|
||||||
|
# 清除 iptables 规则并设置默认策略为 ACCEPT
|
||||||
|
echo "清除 iptables 规则并开放所有连接..."
|
||||||
|
iptables -F
|
||||||
|
iptables -X
|
||||||
|
iptables -t nat -F
|
||||||
|
iptables -t nat -X
|
||||||
|
iptables -t mangle -F
|
||||||
|
iptables -t mangle -X
|
||||||
|
iptables -P INPUT ACCEPT
|
||||||
|
iptables -P FORWARD ACCEPT
|
||||||
|
iptables -P OUTPUT ACCEPT
|
||||||
|
|
||||||
|
# 清除 ip6tables 规则并设置默认策略为 ACCEPT
|
||||||
|
ip6tables -F
|
||||||
|
ip6tables -X
|
||||||
|
ip6tables -t nat -F
|
||||||
|
ip6tables -t nat -X
|
||||||
|
ip6tables -t mangle -F
|
||||||
|
ip6tables -t mangle -X
|
||||||
|
ip6tables -P INPUT ACCEPT
|
||||||
|
ip6tables -P FORWARD ACCEPT
|
||||||
|
ip6tables -P OUTPUT ACCEPT
|
||||||
|
|
||||||
|
# 清除 nftables 规则并加载允许所有流量的配置
|
||||||
|
echo "清除 nftables 规则并开放所有连接..."
|
||||||
|
nft flush ruleset 2>/dev/null || true
|
||||||
|
|
||||||
|
# 创建允许所有的 nftables 配置
|
||||||
|
cat > /tmp/nftables-accept-all.conf << 'EOF'
|
||||||
|
#!/usr/sbin/nft -f
|
||||||
|
|
||||||
|
flush ruleset
|
||||||
|
|
||||||
|
table inet filter {
|
||||||
|
chain input {
|
||||||
|
type filter hook input priority 0; policy accept;
|
||||||
|
}
|
||||||
|
chain forward {
|
||||||
|
type filter hook forward priority 0; policy accept;
|
||||||
|
}
|
||||||
|
chain output {
|
||||||
|
type filter hook output priority 0; policy accept;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
nft -f /tmp/nftables-accept-all.conf
|
||||||
|
cp /tmp/nftables-accept-all.conf /etc/nftables.conf
|
||||||
|
|
||||||
|
# 防止其他防火墙服务干扰
|
||||||
|
echo "禁用其他可能的防火墙模块和服务..."
|
||||||
|
|
||||||
|
# 禁用 SELinux(临时)
|
||||||
|
setenforce 0 2>/dev/null || true
|
||||||
|
|
||||||
|
# 停止并禁用 AppArmor
|
||||||
|
stop_service "apparmor"
|
||||||
|
|
||||||
|
# 停止并禁用 Shorewall
|
||||||
|
stop_service "shorewall"
|
||||||
|
|
||||||
|
# 停止并禁用 IPCop(如有)
|
||||||
|
stop_service "ipcop"
|
||||||
|
|
||||||
|
# 停止并禁用 CSF (ConfigServer Security & Firewall)
|
||||||
|
stop_service "csf"
|
||||||
|
stop_service "lfd"
|
||||||
|
|
||||||
|
# 清除可能的遗留规则(如 raw, security 表)
|
||||||
|
iptables -t raw -F 2>/dev/null || true
|
||||||
|
iptables -t security -F 2>/dev/null || true
|
||||||
|
ip6tables -t raw -F 2>/dev/null || true
|
||||||
|
ip6tables -t security -F 2>/dev/null || true
|
||||||
|
|
||||||
|
# 显示最终状态
|
||||||
|
echo ""
|
||||||
|
echo "=== 防火墙状态 ==="
|
||||||
|
echo "ufw: $(systemctl is-active ufw 2>/dev/null || echo 'inactive')"
|
||||||
|
echo "firewalld: $(systemctl is-active firewalld 2>/dev/null || echo 'inactive')"
|
||||||
|
echo "nftables: $(systemctl is-active nftables 2>/dev/null || echo 'inactive')"
|
||||||
|
echo "iptables: $(systemctl is-active iptables 2>/dev/null || echo 'inactive')"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "=== 当前策略 ==="
|
||||||
|
echo "IPv4 INPUT: $(iptables -L INPUT -n | grep policy | awk '{print $4}')"
|
||||||
|
echo "IPv6 INPUT: $(ip6tables -L INPUT -n | grep policy | awk '{print $4}')"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "✅ 所有防火墙已彻底禁用,所有端口已开放,外部连接畅通无阻!"
|
||||||
|
echo "🚨 警告:此配置极度危险,仅用于测试或封闭网络环境!"
|
||||||
194
卸载宝塔命令
Normal file
194
卸载宝塔命令
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# 宝塔完全清理脚本 - 释放最大空间
|
||||||
|
|
||||||
|
echo "==============================="
|
||||||
|
echo "宝塔完全清理脚本"
|
||||||
|
echo "正在清理,请稍候..."
|
||||||
|
echo "==============================="
|
||||||
|
|
||||||
|
# 1. 停止宝塔服务
|
||||||
|
echo "1. 停止宝塔服务..."
|
||||||
|
/etc/init.d/bt stop 2>/dev/null
|
||||||
|
systemctl stop bt 2>/dev/null
|
||||||
|
pkill -9 bt 2>/dev/null
|
||||||
|
pkill -9 panel 2>/dev/null
|
||||||
|
|
||||||
|
# 2. 卸载宝塔面板
|
||||||
|
echo "2. 卸载宝塔面板..."
|
||||||
|
curl -sSO http://download.bt.cn/install/bt-uninstall.sh
|
||||||
|
bash bt-uninstall.sh >> /dev/null 2>&1
|
||||||
|
rm -f bt-uninstall.sh
|
||||||
|
|
||||||
|
# 3. 删除所有宝塔目录
|
||||||
|
echo "3. 删除宝塔目录..."
|
||||||
|
rm -rf /www/server
|
||||||
|
rm -rf /www/backup
|
||||||
|
rm -rf /www/wwwlogs
|
||||||
|
rm -rf /www/wwwroot
|
||||||
|
rm -rf /www/Recycle_bin
|
||||||
|
rm -rf /tmp/.bt_shell
|
||||||
|
|
||||||
|
# 4. 删除宝塔系统文件
|
||||||
|
echo "4. 删除系统文件..."
|
||||||
|
rm -f /etc/init.d/bt
|
||||||
|
rm -f /usr/bin/bt
|
||||||
|
rm -f /usr/local/bin/bt
|
||||||
|
rm -rf /etc/systemd/system/bt.service
|
||||||
|
rm -rf /usr/lib/systemd/system/bt.service
|
||||||
|
rm -f /etc/cron.d/bt
|
||||||
|
rm -f /root/.bash_profile
|
||||||
|
rm -f /root/.bashrc
|
||||||
|
|
||||||
|
# 5. 清理安装包和缓存
|
||||||
|
echo "5. 清理安装包缓存..."
|
||||||
|
# Debian/Ubuntu
|
||||||
|
if [ -f /etc/debian_version ]; then
|
||||||
|
apt autoremove --purge -y >> /dev/null 2>&1
|
||||||
|
apt clean >> /dev/null 2>&1
|
||||||
|
apt autoclean >> /dev/null 2>&1
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
fi
|
||||||
|
|
||||||
|
# CentOS/RHEL
|
||||||
|
if [ -f /etc/redhat-release ]; then
|
||||||
|
yum autoremove -y >> /dev/null 2>&1
|
||||||
|
yum clean all >> /dev/null 2>&1
|
||||||
|
rm -rf /var/cache/yum
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 6. 删除所有源码编译文件
|
||||||
|
echo "6. 删除源码文件..."
|
||||||
|
find / -name "*.o" -delete 2>/dev/null
|
||||||
|
find / -name "*.a" -delete 2>/dev/null
|
||||||
|
find / -name "*.so" -delete 2>/dev/null
|
||||||
|
find / -name "Makefile" -delete 2>/dev/null
|
||||||
|
find / -name "configure" -delete 2>/dev/null
|
||||||
|
find / -name "config.log" -delete 2>/dev/null
|
||||||
|
find / -name "config.status" -delete 2>/dev/null
|
||||||
|
rm -rf /usr/local/src/*
|
||||||
|
|
||||||
|
# 7. 清理日志文件
|
||||||
|
echo "7. 清理日志文件..."
|
||||||
|
rm -rf /var/log/bt*
|
||||||
|
rm -rf /var/log/nginx
|
||||||
|
rm -rf /var/log/apache2
|
||||||
|
rm -rf /var/log/httpd
|
||||||
|
rm -rf /var/log/mysql
|
||||||
|
rm -rf /var/log/mariadb
|
||||||
|
rm -rf /tmp/panel*
|
||||||
|
rm -rf /tmp/bt*
|
||||||
|
journalctl --vacuum-time=1d >> /dev/null 2>&1
|
||||||
|
|
||||||
|
# 8. 清理临时文件
|
||||||
|
echo "8. 清理临时文件..."
|
||||||
|
rm -rf /tmp/*
|
||||||
|
rm -rf /var/tmp/*
|
||||||
|
rm -rf /root/.cache
|
||||||
|
rm -rf /root/.npm
|
||||||
|
rm -rf /root/.composer
|
||||||
|
rm -rf /root/.pip
|
||||||
|
|
||||||
|
# 9. 清理Python缓存
|
||||||
|
echo "9. 清理Python缓存..."
|
||||||
|
find / -name "__pycache__" -type d -exec rm -rf {} + 2>/dev/null
|
||||||
|
find / -name "*.pyc" -delete 2>/dev/null
|
||||||
|
find / -name "*.pyo" -delete 2>/dev/null
|
||||||
|
find / -name ".pytest_cache" -type d -exec rm -rf {} + 2>/dev/null
|
||||||
|
|
||||||
|
# 10. 清理PHP缓存
|
||||||
|
echo "10. 清理PHP缓存..."
|
||||||
|
rm -rf /tmp/php_sessions/*
|
||||||
|
rm -rf /var/lib/php/sessions/*
|
||||||
|
rm -rf /root/.php_history
|
||||||
|
|
||||||
|
# 11. 清理Node.js缓存
|
||||||
|
echo "11. 清理Node.js缓存..."
|
||||||
|
rm -rf /root/.npm/_cacache
|
||||||
|
rm -rf /usr/lib/node_modules
|
||||||
|
rm -rf /usr/local/lib/node_modules
|
||||||
|
|
||||||
|
# 12. 清理Docker(如果存在)
|
||||||
|
echo "12. 清理Docker..."
|
||||||
|
docker system prune -af --volumes 2>/dev/null
|
||||||
|
rm -rf /var/lib/docker/tmp
|
||||||
|
|
||||||
|
# 13. 清理内核旧文件
|
||||||
|
echo "13. 清理旧内核..."
|
||||||
|
if [ -f /etc/debian_version ]; then
|
||||||
|
apt purge $(dpkg -l | awk '/^rc/ {print $2}') -y 2>/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 14. 清理系统journal日志
|
||||||
|
echo "14. 清理系统日志..."
|
||||||
|
journalctl --rotate
|
||||||
|
journalctl --vacuum-time=1d
|
||||||
|
journalctl --vacuum-size=100M
|
||||||
|
rm -rf /var/log/journal/*
|
||||||
|
|
||||||
|
# 15. 清理软件包管理缓存
|
||||||
|
echo "15. 清理包管理缓存..."
|
||||||
|
# 清理所有包管理器缓存
|
||||||
|
for cmd in apt-get yum dnf pacman zypper; do
|
||||||
|
if command -v $cmd >/dev/null 2>&1; then
|
||||||
|
case $cmd in
|
||||||
|
apt-get) apt-get clean ;;
|
||||||
|
yum) yum clean all ;;
|
||||||
|
dnf) dnf clean all ;;
|
||||||
|
pacman) pacman -Sc --noconfirm ;;
|
||||||
|
zypper) zypper clean ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# 16. 清理缩略图缓存
|
||||||
|
echo "16. 清理缩略图缓存..."
|
||||||
|
rm -rf /root/.thumbnails
|
||||||
|
rm -rf /home/*/.thumbnails 2>/dev/null
|
||||||
|
rm -rf /root/.cache/thumbnails
|
||||||
|
|
||||||
|
# 17. 清理邮件队列
|
||||||
|
echo "17. 清理邮件队列..."
|
||||||
|
rm -rf /var/mail/*
|
||||||
|
rm -rf /var/spool/mail/*
|
||||||
|
rm -rf /var/spool/postfix/*
|
||||||
|
|
||||||
|
# 18. 清理崩溃报告
|
||||||
|
echo "18. 清理崩溃报告..."
|
||||||
|
rm -rf /var/crash/*
|
||||||
|
rm -rf /var/spool/abrt/*
|
||||||
|
|
||||||
|
# 19. 清理旧配置文件
|
||||||
|
echo "19. 清理旧配置文件..."
|
||||||
|
find /etc -name "*.bak" -delete
|
||||||
|
find /etc -name "*.old" -delete
|
||||||
|
find /etc -name "*~" -delete
|
||||||
|
find /root -name "*.bak" -delete
|
||||||
|
|
||||||
|
# 20. 最后清理和检查
|
||||||
|
echo "20. 最终清理..."
|
||||||
|
sync
|
||||||
|
echo 3 > /proc/sys/vm/drop_caches
|
||||||
|
|
||||||
|
# 显示清理结果
|
||||||
|
echo ""
|
||||||
|
echo "==============================="
|
||||||
|
echo "清理完成!释放的空间统计:"
|
||||||
|
echo "==============================="
|
||||||
|
df -h /
|
||||||
|
|
||||||
|
# 检查宝塔是否完全删除
|
||||||
|
echo ""
|
||||||
|
echo "宝塔残留检查:"
|
||||||
|
if [ ! -d "/www/server" ] && [ ! -f "/usr/bin/bt" ]; then
|
||||||
|
echo "✓ 宝塔已完全删除"
|
||||||
|
else
|
||||||
|
echo "✗ 发现宝塔残留文件"
|
||||||
|
find / -name "*bt*" -o -name "*panel*" 2>/dev/null | grep -v "proc"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "当前磁盘使用情况:"
|
||||||
|
df -h
|
||||||
|
echo ""
|
||||||
|
echo "前10大目录:"
|
||||||
|
du -sh /* 2>/dev/null | sort -hr | head -10
|
||||||
82
实时 history 监控
Normal file
82
实时 history 监控
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
# 创建极简监控系统
|
||||||
|
cat > /tmp/simple_monitor.sh << 'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
LOG_FILE="/tmp/command_monitor.log"
|
||||||
|
PID_FILE="/tmp/monitor_simple.pid"
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
echo "启动极简监控..."
|
||||||
|
# 设置实时history
|
||||||
|
echo 'export PROMPT_COMMAND="history -a; history -c; history -r"' >> ~/.bashrc
|
||||||
|
source ~/.bashrc
|
||||||
|
|
||||||
|
# 启动监控进程
|
||||||
|
(
|
||||||
|
echo "=== 监控启动: $(date) ===" > "$LOG_FILE"
|
||||||
|
declare -A sizes
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
for user_dir in /home/* /root; do
|
||||||
|
[ -d "$user_dir" ] || continue
|
||||||
|
user=$(basename "$user_dir")
|
||||||
|
history_file="$user_dir/.bash_history"
|
||||||
|
[ -f "$history_file" ] || continue
|
||||||
|
|
||||||
|
current=$(stat -c%s "$history_file" 2>/dev/null || echo 0)
|
||||||
|
last=${sizes["$user"]:-0}
|
||||||
|
|
||||||
|
if [ "$current" -gt "$last" ]; then
|
||||||
|
cmd=$(tail -n 1 "$history_file" 2>/dev/null)
|
||||||
|
if [ -n "$cmd" ] && [ ${#cmd} -gt 1 ]; then
|
||||||
|
case "$cmd" in
|
||||||
|
ls|cd|pwd|ll|history|exit|clear|".") continue ;;
|
||||||
|
*)
|
||||||
|
ip="unknown"
|
||||||
|
[ -n "$SSH_CLIENT" ] && ip=$(echo "$SSH_CLIENT" | awk '{print $1}')
|
||||||
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $user: $cmd (from: $ip)" >> "$LOG_FILE"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
sizes["$user"]=$current
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
) &
|
||||||
|
echo $! > "$PID_FILE"
|
||||||
|
echo "监控已启动 (PID: $!)"
|
||||||
|
echo "查看日志: tail -f $LOG_FILE"
|
||||||
|
;;
|
||||||
|
view)
|
||||||
|
if [ -f "$LOG_FILE" ]; then
|
||||||
|
tail -f "$LOG_FILE"
|
||||||
|
else
|
||||||
|
echo "暂无日志,请先启动监控: $0 start"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
if [ -f "$PID_FILE" ]; then
|
||||||
|
kill $(cat "$PID_FILE") 2>/dev/null
|
||||||
|
rm -f "$PID_FILE"
|
||||||
|
echo "监控已停止"
|
||||||
|
else
|
||||||
|
echo "监控未运行"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "使用方法: $0 {start|view|stop}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod +x /tmp/simple_monitor.sh
|
||||||
|
|
||||||
|
# 启动极简监控
|
||||||
|
/tmp/simple_monitor.sh start
|
||||||
|
|
||||||
|
# 测试
|
||||||
|
echo "test_simple_$(date +%s)" >> ~/.bash_history
|
||||||
|
sleep 2
|
||||||
|
tail -5 /tmp/command_monitor.log
|
||||||
42
搜寻 X-UI
Normal file
42
搜寻 X-UI
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
cat << 'EOF' > deep_search_xui.sh
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "========================================================"
|
||||||
|
echo " 正在进行 Debian 12 深度地毯式搜索 (X-UI/Xray)"
|
||||||
|
echo "========================================================"
|
||||||
|
|
||||||
|
# 1. 🕵️♂️ 侦探模式:查操作历史 (最可能找到线索的地方)
|
||||||
|
echo -e "\n[1/4] 正在分析命令历史 (.bash_history)..."
|
||||||
|
HISTORY_MATCH=$(grep -E "wget|curl" ~/.bash_history | grep "x-ui" | tail -n 5)
|
||||||
|
if [ -n "$HISTORY_MATCH" ]; then
|
||||||
|
echo -e "\033[0;32m发现曾经执行过的下载命令:\033[0m"
|
||||||
|
echo "$HISTORY_MATCH"
|
||||||
|
echo -e "👆 (如果上面是 curl | bash 格式,说明没保存安装包,是直接运行的)"
|
||||||
|
else
|
||||||
|
echo "历史记录中未发现明显的下载命令。"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. 📂 全盘搜索:不放过任何角落 (排除系统虚拟目录)
|
||||||
|
echo -e "\n[2/4] 正在全盘搜索文件名包含 'x-ui' 的文件 (可能需要一点时间)..."
|
||||||
|
# 排除 /proc, /sys, /run, /dev 避免报错
|
||||||
|
find / -path /proc -prune -o -path /sys -prune -o -path /run -prune -o -path /dev -prune -o -type f -name "*x-ui*" -print 2>/dev/null | grep -vE "(/usr/local/x-ui|/var/lib/docker)" | head -n 20
|
||||||
|
# (grep -v 是为了屏蔽掉已经安装好的程序文件,只找安装包)
|
||||||
|
|
||||||
|
# 3. 📝 内容搜索:查找名字是 install.sh 但内容是 X-UI 的文件
|
||||||
|
echo -e "\n[3/4] 正在检查常见的 install.sh 脚本内容..."
|
||||||
|
# 搜索 /root 和 /home 下所有的 .sh 文件
|
||||||
|
find /root /home /tmp -maxdepth 3 -name "*.sh" -type f 2>/dev/null | while read -r script; do
|
||||||
|
if grep -q "x-ui" "$script"; then
|
||||||
|
echo -e "\033[0;33m疑似目标脚本 (内容包含 x-ui): $script\033[0m"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# 4. 📦 大文件搜索:查找可能是压缩包的残留
|
||||||
|
echo -e "\n[4/4] 正在搜索最近修改过的压缩包 (tar.gz/zip)..."
|
||||||
|
find /root /home /tmp -type f \( -name "*.tar.gz" -o -name "*.zip" \) -mtime -365 -size +1M 2>/dev/null | head -n 10
|
||||||
|
|
||||||
|
echo -e "\n========================================================"
|
||||||
|
echo "搜索结束。"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod +x deep_search_xui.sh && ./deep_search_xui.sh
|
||||||
215
测速中文
Normal file
215
测速中文
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 精准网络测速一键脚本 - 最终修复版
|
||||||
|
# 支持多系统:Ubuntu/Debian/CentOS/RHEL/Alpine
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
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'
|
||||||
|
|
||||||
|
# 检查命令是否存在
|
||||||
|
check_command() {
|
||||||
|
if ! command -v "$1" &> /dev/null; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# 安装必要工具(简化版)
|
||||||
|
install_tools() {
|
||||||
|
echo -e "${BLUE}📦 安装必要工具...${NC}"
|
||||||
|
|
||||||
|
# 检测包管理器
|
||||||
|
if check_command apt-get; then
|
||||||
|
PM="apt-get"
|
||||||
|
UPDATE_CMD="apt-get update -y >/dev/null 2>&1"
|
||||||
|
INSTALL_CMD="apt-get install -y"
|
||||||
|
elif check_command yum; then
|
||||||
|
PM="yum"
|
||||||
|
UPDATE_CMD="yum update -y >/dev/null 2>&1"
|
||||||
|
INSTALL_CMD="yum install -y"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}⚠️ 使用系统自带工具${NC}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 更新包列表
|
||||||
|
eval $UPDATE_CMD
|
||||||
|
|
||||||
|
# 只安装最必要的工具
|
||||||
|
for tool in curl wget ping; do
|
||||||
|
if ! check_command "$tool"; then
|
||||||
|
echo -e "${BLUE}安装 $tool...${NC}"
|
||||||
|
$INSTALL_CMD "$tool" >/dev/null 2>&1 && echo -e "${GREEN}✅ $tool 安装成功${NC}" || echo -e "${YELLOW}⚠️ $tool 安装失败${NC}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# 安装speedtest(终极方案)
|
||||||
|
install_speedtest_final() {
|
||||||
|
echo -e "${BLUE}🚀 安装Speedtest...${NC}"
|
||||||
|
|
||||||
|
# 清理旧版本
|
||||||
|
rm -f /usr/local/bin/speedtest /tmp/speedtest /usr/bin/speedtest
|
||||||
|
|
||||||
|
# 方法1: 直接下载静态二进制(最可靠)
|
||||||
|
echo -e "${BLUE}下载预编译二进制...${NC}"
|
||||||
|
if check_command curl; then
|
||||||
|
if curl -s -L -o /usr/local/bin/speedtest "https://raw.githubusercontent.com/tmplink/static_binaries/main/speedtest/speedtest_x86_64" && \
|
||||||
|
chmod +x /usr/local/bin/speedtest; then
|
||||||
|
echo -e "${GREEN}✅ 二进制speedtest安装成功${NC}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 方法2: 备用下载源
|
||||||
|
if check_command wget; then
|
||||||
|
if wget -q -O /usr/local/bin/speedtest "https://github.com/tmplink/static_binaries/raw/main/speedtest/speedtest_x86_64" && \
|
||||||
|
chmod +x /usr/local/bin/speedtest; then
|
||||||
|
echo -e "${GREEN}✅ 二进制speedtest安装成功${NC}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 方法3: 使用base64内嵌二进制(终极方案)
|
||||||
|
echo -e "${BLUE}使用内嵌二进制...${NC}"
|
||||||
|
cat > /usr/local/bin/speedtest << 'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
echo "⚠️ Speedtest二进制下载失败,使用基础网络测试"
|
||||||
|
echo "📊 基础网络测试结果:"
|
||||||
|
echo "----------------------------------------"
|
||||||
|
ping -c 3 223.5.5.5 | grep "min/avg/max" | awk -F'/' '{print "📍 国内延迟: "$5"ms"}'
|
||||||
|
ping -c 3 8.8.8.8 | grep "min/avg/max" | awk -F'/' '{print "🌍 国际延迟: "$5"ms"}'
|
||||||
|
echo "----------------------------------------"
|
||||||
|
EOF
|
||||||
|
chmod +x /usr/local/bin/speedtest
|
||||||
|
echo -e "${YELLOW}⚠️ 使用基础网络测试替代${NC}"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 验证speedtest安装
|
||||||
|
verify_speedtest() {
|
||||||
|
echo -e "${BLUE}🔍 验证speedtest安装...${NC}"
|
||||||
|
if [ -x "/usr/local/bin/speedtest" ]; then
|
||||||
|
echo -e "${GREEN}✅ speedtest可执行文件存在${NC}"
|
||||||
|
/usr/local/bin/speedtest --version >/dev/null 2>&1
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo -e "${GREEN}✅ speedtest工作正常${NC}"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}⚠️ speedtest执行失败,使用备用方案${NC}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${RED}❌ speedtest未安装${NC}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 终极网络测速方案
|
||||||
|
ultimate_speed_test() {
|
||||||
|
echo -e "${CYAN}🚀 终极网络测速...${NC}"
|
||||||
|
|
||||||
|
# 首先验证speedtest
|
||||||
|
if verify_speedtest; then
|
||||||
|
echo -e "${GREEN}使用speedtest进行专业测速...${NC}"
|
||||||
|
/usr/local/bin/speedtest --simple 2>/dev/null && return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 如果speedtest失败,使用增强的基础测试
|
||||||
|
echo -e "${YELLOW}使用增强基础测试...${NC}"
|
||||||
|
|
||||||
|
# 测试延迟
|
||||||
|
echo -e "${BLUE}📊 网络延迟测试:${NC}"
|
||||||
|
test_hosts=("223.5.5.5 阿里DNS" "8.8.8.8 Google DNS" "1.1.1.1 Cloudflare")
|
||||||
|
for host_info in "${test_hosts[@]}"; do
|
||||||
|
host=${host_info%% *}
|
||||||
|
name=${host_info#* }
|
||||||
|
if ping -c 2 -W 2 "$host" >/dev/null 2>&1; then
|
||||||
|
avg_ping=$(ping -c 3 -W 2 "$host" 2>/dev/null | grep "min/avg/max" | awk -F'/' '{print $5}')
|
||||||
|
echo -e "${GREEN}📍 $name: ${avg_ping}ms${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}📍 $name: 超时${NC}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# 测试下载速度(使用小文件)
|
||||||
|
echo -e "${BLUE}📥 下载速度测试:${NC}"
|
||||||
|
if check_command curl; then
|
||||||
|
# 测试到Cloudflare的速度
|
||||||
|
start_time=$(date +%s)
|
||||||
|
if curl -s --max-time 10 -o /tmp/test.file "https://cloudflare.com/favicon.ico" >/dev/null 2>&1; then
|
||||||
|
end_time=$(date +%s)
|
||||||
|
file_size=$(stat -c%s /tmp/test.file 2>/dev/null || echo 0)
|
||||||
|
duration=$((end_time - start_time))
|
||||||
|
if [ $duration -eq 0 ]; then duration=1; fi
|
||||||
|
if [ $file_size -gt 0 ]; then
|
||||||
|
speed=$(echo "scale=2; $file_size * 8 / $duration / 1000" | bc -l 2>/dev/null || echo "N/A")
|
||||||
|
echo -e "${GREEN}🌐 Cloudflare: ${speed} Kbps${NC}"
|
||||||
|
fi
|
||||||
|
rm -f /tmp/test.file
|
||||||
|
else
|
||||||
|
echo -e "${RED}🌐 Cloudflare: 测试失败${NC}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 网络连通性总结
|
||||||
|
echo -e "${BLUE}🌍 网络连通性:${NC}"
|
||||||
|
if ping -c 1 -W 3 223.5.5.5 >/dev/null 2>&1; then
|
||||||
|
echo -e "${GREEN}✅ 国内网络: 正常${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}❌ 国内网络: 异常${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ping -c 1 -W 3 8.8.8.8 >/dev/null 2>&1; then
|
||||||
|
echo -e "${GREEN}✅ 国际网络: 正常${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}❌ 国际网络: 异常${NC}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 显示系统信息
|
||||||
|
show_system_info() {
|
||||||
|
echo -e "${PURPLE}"
|
||||||
|
echo "=================================================="
|
||||||
|
echo " 🌈 最终版网络测速脚本"
|
||||||
|
echo " 专为受限环境优化"
|
||||||
|
echo "=================================================="
|
||||||
|
echo -e "${NC}"
|
||||||
|
|
||||||
|
echo -e "${BLUE}🔍 系统信息:${NC}"
|
||||||
|
if [ -f /etc/os-release ]; then
|
||||||
|
. /etc/os-release
|
||||||
|
echo -e "${GREEN}✅ 系统: $PRETTY_NAME${NC}"
|
||||||
|
fi
|
||||||
|
echo -e "${GREEN}✅ 架构: $(uname -m)${NC}"
|
||||||
|
echo -e "${GREEN}✅ 内核: $(uname -r)${NC}"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# 主函数
|
||||||
|
main() {
|
||||||
|
show_system_info
|
||||||
|
install_tools
|
||||||
|
echo ""
|
||||||
|
install_speedtest_final
|
||||||
|
echo ""
|
||||||
|
ultimate_speed_test
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo -e "${PURPLE}==================================================${NC}"
|
||||||
|
echo -e "${PURPLE} 测试完成 🌟${NC}"
|
||||||
|
echo -e "${PURPLE}==================================================${NC}"
|
||||||
|
echo -e "${BLUE}💡 提示: 绿色表示正常,红色表示异常${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 设置陷阱
|
||||||
|
trap 'echo -e "${NC}"' EXIT
|
||||||
|
|
||||||
|
# 运行主函数
|
||||||
|
main "$@"
|
||||||
72
测速软件
Normal file
72
测速软件
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
cat > librespeed_install.sh << 'EOF'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
APP_NAME="librespeed"
|
||||||
|
DEFAULT_PORT=8000
|
||||||
|
WORKDIR="/root/librespeed"
|
||||||
|
|
||||||
|
echo "======================================="
|
||||||
|
echo " LibreSpeed 内网测速 Docker 一键部署"
|
||||||
|
echo "======================================="
|
||||||
|
|
||||||
|
# root 检查
|
||||||
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
|
echo "❌ 请使用 root 运行"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 端口选择
|
||||||
|
read -p "请输入访问端口(默认 ${DEFAULT_PORT},直接回车使用默认): " PORT
|
||||||
|
PORT=${PORT:-$DEFAULT_PORT}
|
||||||
|
|
||||||
|
# 端口简单校验
|
||||||
|
if ! [[ "$PORT" =~ ^[0-9]+$ ]] || [ "$PORT" -lt 1 ] || [ "$PORT" -gt 65535 ]; then
|
||||||
|
echo "❌ 端口不合法"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "▶ 使用端口: $PORT"
|
||||||
|
|
||||||
|
# Docker 检查
|
||||||
|
if ! command -v docker >/dev/null 2>&1; then
|
||||||
|
echo "❌ 未检测到 Docker,请先安装 Docker"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# docker compose 检查
|
||||||
|
if ! docker compose version >/dev/null 2>&1; then
|
||||||
|
echo "❌ 未检测到 docker compose 插件"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 创建目录
|
||||||
|
mkdir -p "$WORKDIR"
|
||||||
|
cd "$WORKDIR"
|
||||||
|
|
||||||
|
# 生成 docker-compose.yml
|
||||||
|
cat > docker-compose.yml <<YAML
|
||||||
|
version: '3'
|
||||||
|
services:
|
||||||
|
librespeed:
|
||||||
|
image: librespeed/speedtest:latest
|
||||||
|
container_name: librespeed
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "${PORT}:80"
|
||||||
|
YAML
|
||||||
|
|
||||||
|
# 启动
|
||||||
|
echo "▶ 启动 LibreSpeed 容器..."
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
# 验证
|
||||||
|
sleep 1
|
||||||
|
if docker ps | grep -q librespeed; then
|
||||||
|
echo "✅ LibreSpeed 启动成功"
|
||||||
|
echo "🌐 访问地址: http://$(hostname -I | awk '{print $1}'):${PORT}"
|
||||||
|
else
|
||||||
|
echo "❌ LibreSpeed 启动失败"
|
||||||
|
docker compose logs
|
||||||
|
fi
|
||||||
|
EOF
|
||||||
305
端口转发
Normal file
305
端口转发
Normal file
@@ -0,0 +1,305 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# 显示标题
|
||||||
|
echo -e "${GREEN}"
|
||||||
|
echo "========================================"
|
||||||
|
echo " Nginx 端口转发一键配置脚本"
|
||||||
|
echo "========================================"
|
||||||
|
echo -e "${NC}"
|
||||||
|
|
||||||
|
# 检查是否以root运行
|
||||||
|
if [ "$EUID" -ne 0 ]; then
|
||||||
|
echo -e "${RED}请使用 sudo 运行此脚本${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查nginx是否安装
|
||||||
|
if ! command -v nginx &> /dev/null; then
|
||||||
|
echo -e "${YELLOW}检测到未安装 Nginx,正在自动安装...${NC}"
|
||||||
|
if [ -f /etc/redhat-release ]; then
|
||||||
|
# CentOS/RHEL
|
||||||
|
yum install -y nginx
|
||||||
|
elif [ -f /etc/debian_version ]; then
|
||||||
|
# Ubuntu/Debian
|
||||||
|
apt update && apt install -y nginx
|
||||||
|
else
|
||||||
|
echo -e "${RED}无法自动安装 Nginx,请手动安装后再运行此脚本${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 交互式输入配置信息
|
||||||
|
echo -e "${BLUE}请输入配置信息(直接回车使用默认值)${NC}"
|
||||||
|
|
||||||
|
read -p "输入监听端口 (默认: 80): " LISTEN_PORT
|
||||||
|
LISTEN_PORT=${LISTEN_PORT:-80}
|
||||||
|
|
||||||
|
read -p "输入域名或IP(无域名请直接回车): " SERVER_NAME
|
||||||
|
SERVER_NAME=${SERVER_NAME:-_}
|
||||||
|
|
||||||
|
read -p "输入要转发的目标IP或域名: " TARGET_HOST
|
||||||
|
if [ -z "$TARGET_HOST" ]; then
|
||||||
|
echo -e "${RED}错误:目标地址不能为空${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
read -p "输入要转发的目标端口: " TARGET_PORT
|
||||||
|
if [ -z "$TARGET_PORT" ]; then
|
||||||
|
echo -e "${RED}错误:目标端口不能为空${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
read -p "输入配置名称(将用于生成配置文件名): " CONFIG_NAME
|
||||||
|
if [ -z "$CONFIG_NAME" ]; then
|
||||||
|
CONFIG_NAME="proxy_${LISTEN_PORT}_to_${TARGET_HOST}_${TARGET_PORT}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 生成配置文件内容
|
||||||
|
CONFIG_CONTENT="server {
|
||||||
|
listen ${LISTEN_PORT};
|
||||||
|
server_name ${SERVER_NAME};
|
||||||
|
|
||||||
|
# 访问日志设置
|
||||||
|
access_log /var/log/nginx/${CONFIG_NAME}_access.log;
|
||||||
|
error_log /var/log/nginx/${CONFIG_NAME}_error.log;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://${TARGET_HOST}:${TARGET_PORT};
|
||||||
|
proxy_set_header Host \$host;
|
||||||
|
proxy_set_header X-Real-IP \$remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||||
|
proxy_connect_timeout 30s;
|
||||||
|
proxy_read_timeout 60s;
|
||||||
|
proxy_send_timeout 60s;
|
||||||
|
|
||||||
|
# 可选:WebSocket 支持
|
||||||
|
# proxy_http_version 1.1;
|
||||||
|
# proxy_set_header Upgrade \$http_upgrade;
|
||||||
|
# proxy_set_header Connection \"upgrade\";
|
||||||
|
}
|
||||||
|
|
||||||
|
# 可选:静态文件缓存
|
||||||
|
# location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
|
||||||
|
# expires 1y;
|
||||||
|
# add_header Cache-Control \"public, immutable\";
|
||||||
|
# }
|
||||||
|
}"
|
||||||
|
|
||||||
|
# 确定配置文件路径
|
||||||
|
if [ -d "/etc/nginx/conf.d" ]; then
|
||||||
|
CONFIG_FILE="/etc/nginx/conf.d/${CONFIG_NAME}.conf"
|
||||||
|
elif [ -d "/etc/nginx/sites-available" ]; then
|
||||||
|
CONFIG_FILE="/etc/nginx/sites-available/${CONFIG_NAME}.conf"
|
||||||
|
else
|
||||||
|
CONFIG_FILE="/etc/nginx/sites-enabled/${CONFIG_NAME}.conf"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 写入配置文件
|
||||||
|
echo "$CONFIG_CONTENT" | sudo tee "$CONFIG_FILE" > /dev/null
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo -e "${GREEN}✓ 配置文件已创建: ${CONFIG_FILE}${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗ 配置文件创建失败${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 测试配置文件语法
|
||||||
|
echo -e "${YELLOW}测试配置文件语法...${NC}"
|
||||||
|
nginx -t
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo -e "${GREEN}✓ 配置文件语法检查通过${NC}"
|
||||||
|
|
||||||
|
# 重新加载nginx配置
|
||||||
|
echo -e "${YELLOW}重新加载 Nginx 配置...${NC}"
|
||||||
|
systemctl reload nginx || nginx -s reload
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo -e "${GREEN}✓ Nginx 配置重载成功${NC}"
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}🎉 配置完成!${NC}"
|
||||||
|
echo -e "${BLUE}================================${NC}"
|
||||||
|
echo -e "${GREEN}监听端口: ${LISTEN_PORT}"
|
||||||
|
echo -e "目标地址: ${TARGET_HOST}:${TARGET_PORT}"
|
||||||
|
echo -e "配置文件: ${CONFIG_FILE}"
|
||||||
|
echo -e "${BLUE}================================${NC}"
|
||||||
|
|
||||||
|
# 显示访问URL
|
||||||
|
if [ "$SERVER_NAME" != "_" ]; then
|
||||||
|
if [ "$LISTEN_PORT" = "80" ]; then
|
||||||
|
echo -e "${GREEN}访问地址: http://${SERVER_NAME}${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}访问地址: http://${SERVER_NAME}:${LISTEN_PORT}${NC}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}访问地址: http://服务器IP:${LISTEN_PORT}${NC}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗ Nginx 配置重载失败,请检查日志${NC}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗ 配置文件语法检查失败,请检查配置${NC}"
|
||||||
|
echo -e "${YELLOW}已创建的配置文件: ${CONFIG_FILE}${NC}"
|
||||||
|
exit 1
|
||||||
|
fi#!/bin/bash
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# 显示标题
|
||||||
|
echo -e "${GREEN}"
|
||||||
|
echo "========================================"
|
||||||
|
echo " Nginx 端口转发一键配置脚本"
|
||||||
|
echo "========================================"
|
||||||
|
echo -e "${NC}"
|
||||||
|
|
||||||
|
# 检查是否以root运行
|
||||||
|
if [ "$EUID" -ne 0 ]; then
|
||||||
|
echo -e "${RED}请使用 sudo 运行此脚本${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查nginx是否安装
|
||||||
|
if ! command -v nginx &> /dev/null; then
|
||||||
|
echo -e "${YELLOW}检测到未安装 Nginx,正在自动安装...${NC}"
|
||||||
|
if [ -f /etc/redhat-release ]; then
|
||||||
|
# CentOS/RHEL
|
||||||
|
yum install -y nginx
|
||||||
|
elif [ -f /etc/debian_version ]; then
|
||||||
|
# Ubuntu/Debian
|
||||||
|
apt update && apt install -y nginx
|
||||||
|
else
|
||||||
|
echo -e "${RED}无法自动安装 Nginx,请手动安装后再运行此脚本${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 交互式输入配置信息
|
||||||
|
echo -e "${BLUE}请输入配置信息(直接回车使用默认值)${NC}"
|
||||||
|
|
||||||
|
read -p "输入监听端口 (默认: 80): " LISTEN_PORT
|
||||||
|
LISTEN_PORT=${LISTEN_PORT:-80}
|
||||||
|
|
||||||
|
read -p "输入域名或IP(无域名请直接回车): " SERVER_NAME
|
||||||
|
SERVER_NAME=${SERVER_NAME:-_}
|
||||||
|
|
||||||
|
read -p "输入要转发的目标IP或域名: " TARGET_HOST
|
||||||
|
if [ -z "$TARGET_HOST" ]; then
|
||||||
|
echo -e "${RED}错误:目标地址不能为空${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
read -p "输入要转发的目标端口: " TARGET_PORT
|
||||||
|
if [ -z "$TARGET_PORT" ]; then
|
||||||
|
echo -e "${RED}错误:目标端口不能为空${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
read -p "输入配置名称(将用于生成配置文件名): " CONFIG_NAME
|
||||||
|
if [ -z "$CONFIG_NAME" ]; then
|
||||||
|
CONFIG_NAME="proxy_${LISTEN_PORT}_to_${TARGET_HOST}_${TARGET_PORT}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 生成配置文件内容
|
||||||
|
CONFIG_CONTENT="server {
|
||||||
|
listen ${LISTEN_PORT};
|
||||||
|
server_name ${SERVER_NAME};
|
||||||
|
|
||||||
|
# 访问日志设置
|
||||||
|
access_log /var/log/nginx/${CONFIG_NAME}_access.log;
|
||||||
|
error_log /var/log/nginx/${CONFIG_NAME}_error.log;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://${TARGET_HOST}:${TARGET_PORT};
|
||||||
|
proxy_set_header Host \$host;
|
||||||
|
proxy_set_header X-Real-IP \$remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||||
|
proxy_connect_timeout 30s;
|
||||||
|
proxy_read_timeout 60s;
|
||||||
|
proxy_send_timeout 60s;
|
||||||
|
|
||||||
|
# 可选:WebSocket 支持
|
||||||
|
# proxy_http_version 1.1;
|
||||||
|
# proxy_set_header Upgrade \$http_upgrade;
|
||||||
|
# proxy_set_header Connection \"upgrade\";
|
||||||
|
}
|
||||||
|
|
||||||
|
# 可选:静态文件缓存
|
||||||
|
# location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
|
||||||
|
# expires 1y;
|
||||||
|
# add_header Cache-Control \"public, immutable\";
|
||||||
|
# }
|
||||||
|
}"
|
||||||
|
|
||||||
|
# 确定配置文件路径
|
||||||
|
if [ -d "/etc/nginx/conf.d" ]; then
|
||||||
|
CONFIG_FILE="/etc/nginx/conf.d/${CONFIG_NAME}.conf"
|
||||||
|
elif [ -d "/etc/nginx/sites-available" ]; then
|
||||||
|
CONFIG_FILE="/etc/nginx/sites-available/${CONFIG_NAME}.conf"
|
||||||
|
else
|
||||||
|
CONFIG_FILE="/etc/nginx/sites-enabled/${CONFIG_NAME}.conf"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 写入配置文件
|
||||||
|
echo "$CONFIG_CONTENT" | sudo tee "$CONFIG_FILE" > /dev/null
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo -e "${GREEN}✓ 配置文件已创建: ${CONFIG_FILE}${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗ 配置文件创建失败${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 测试配置文件语法
|
||||||
|
echo -e "${YELLOW}测试配置文件语法...${NC}"
|
||||||
|
nginx -t
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo -e "${GREEN}✓ 配置文件语法检查通过${NC}"
|
||||||
|
|
||||||
|
# 重新加载nginx配置
|
||||||
|
echo -e "${YELLOW}重新加载 Nginx 配置...${NC}"
|
||||||
|
systemctl reload nginx || nginx -s reload
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo -e "${GREEN}✓ Nginx 配置重载成功${NC}"
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}🎉 配置完成!${NC}"
|
||||||
|
echo -e "${BLUE}================================${NC}"
|
||||||
|
echo -e "${GREEN}监听端口: ${LISTEN_PORT}"
|
||||||
|
echo -e "目标地址: ${TARGET_HOST}:${TARGET_PORT}"
|
||||||
|
echo -e "配置文件: ${CONFIG_FILE}"
|
||||||
|
echo -e "${BLUE}================================${NC}"
|
||||||
|
|
||||||
|
# 显示访问URL
|
||||||
|
if [ "$SERVER_NAME" != "_" ]; then
|
||||||
|
if [ "$LISTEN_PORT" = "80" ]; then
|
||||||
|
echo -e "${GREEN}访问地址: http://${SERVER_NAME}${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}访问地址: http://${SERVER_NAME}:${LISTEN_PORT}${NC}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}访问地址: http://服务器IP:${LISTEN_PORT}${NC}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗ Nginx 配置重载失败,请检查日志${NC}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗ 配置文件语法检查失败,请检查配置${NC}"
|
||||||
|
echo -e "${YELLOW}已创建的配置文件: ${CONFIG_FILE}${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
516
系统优化
Normal file
516
系统优化
Normal file
@@ -0,0 +1,516 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Ubuntu/Debian/CentOS/RHEL系统优化与Docker准备脚本
|
||||||
|
# 精简版 - 不备份文件,适合小存储空间VPS
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
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'
|
||||||
|
|
||||||
|
# 日志文件
|
||||||
|
LOG_FILE="/tmp/system_optimization.log"
|
||||||
|
|
||||||
|
# 错误处理函数
|
||||||
|
handle_error() {
|
||||||
|
echo -e "${RED}❌ 错误: $1${NC}"
|
||||||
|
echo "详细日志请查看: $LOG_FILE"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 日志记录函数
|
||||||
|
log() {
|
||||||
|
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查命令是否存在
|
||||||
|
check_command() {
|
||||||
|
if ! command -v "$1" &> /dev/null; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检测系统类型
|
||||||
|
detect_os() {
|
||||||
|
echo -e "${BLUE}🔍 检测操作系统...${NC}"
|
||||||
|
|
||||||
|
if [ -f /etc/os-release ]; then
|
||||||
|
. /etc/os-release
|
||||||
|
OS_NAME=$ID
|
||||||
|
OS_VERSION=$VERSION_ID
|
||||||
|
OS_PRETTY_NAME=$PRETTY_NAME
|
||||||
|
|
||||||
|
echo -e "${GREEN}✅ 操作系统: $OS_PRETTY_NAME${NC}"
|
||||||
|
echo -e "${GREEN}✅ 版本: $OS_VERSION${NC}"
|
||||||
|
|
||||||
|
case $OS_NAME in
|
||||||
|
ubuntu|debian)
|
||||||
|
OS_TYPE="debian"
|
||||||
|
PM="apt-get"
|
||||||
|
UPDATE_CMD="apt-get update"
|
||||||
|
UPGRADE_CMD="apt-get upgrade -y"
|
||||||
|
INSTALL_CMD="apt-get install -y"
|
||||||
|
AUTOREMOVE_CMD="apt-get autoremove -y"
|
||||||
|
AUTOCLEAN_CMD="apt-get autoclean -y"
|
||||||
|
;;
|
||||||
|
centos|rhel|fedora|rocky|almalinux)
|
||||||
|
OS_TYPE="rhel"
|
||||||
|
if check_command dnf; then
|
||||||
|
PM="dnf"
|
||||||
|
UPDATE_CMD="dnf update -y"
|
||||||
|
INSTALL_CMD="dnf install -y"
|
||||||
|
else
|
||||||
|
PM="yum"
|
||||||
|
UPDATE_CMD="yum update -y"
|
||||||
|
INSTALL_CMD="yum install -y"
|
||||||
|
fi
|
||||||
|
AUTOREMOVE_CMD="$PM autoremove -y"
|
||||||
|
AUTOCLEAN_CMD="$PM clean all"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
handle_error "不支持的操作系统: $OS_NAME"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
handle_error "无法检测操作系统"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查系统架构
|
||||||
|
check_architecture() {
|
||||||
|
echo -e "${BLUE}🔍 检查系统架构...${NC}"
|
||||||
|
ARCH=$(uname -m)
|
||||||
|
case $ARCH in
|
||||||
|
x86_64)
|
||||||
|
echo -e "${GREEN}✅ 系统架构: AMD64${NC}"
|
||||||
|
;;
|
||||||
|
aarch64)
|
||||||
|
echo -e "${GREEN}✅ 系统架构: ARM64${NC}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo -e "${YELLOW}⚠️ 检测到非常见架构: $ARCH${NC}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# 清理系统缓存和旧包
|
||||||
|
clean_system() {
|
||||||
|
echo -e "${BLUE}🧹 清理系统缓存和旧包...${NC}"
|
||||||
|
|
||||||
|
if [ "$OS_TYPE" = "debian" ]; then
|
||||||
|
# 清理apt缓存
|
||||||
|
apt-get clean >> "$LOG_FILE" 2>&1 || echo -e "${YELLOW}⚠️ apt清理缓存失败${NC}"
|
||||||
|
apt-get autoremove -y >> "$LOG_FILE" 2>&1 || echo -e "${YELLOW}⚠️ apt自动移除失败${NC}"
|
||||||
|
|
||||||
|
# 清理旧内核(仅保留最新1个以节省空间)
|
||||||
|
if check_command dpkg; then
|
||||||
|
OLD_KERNELS=$(dpkg -l | grep -E "linux-image-[0-9]" | grep -v $(uname -r | sed 's/-generic//') | awk '{print $2}')
|
||||||
|
if [ -n "$OLD_KERNELS" ]; then
|
||||||
|
echo -e "${BLUE}移除旧内核: $OLD_KERNELS${NC}"
|
||||||
|
apt-get remove -y $OLD_KERNELS >> "$LOG_FILE" 2>&1 || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
elif [ "$OS_TYPE" = "rhel" ]; then
|
||||||
|
# 清理yum/dnf缓存
|
||||||
|
$PM clean all >> "$LOG_FILE" 2>&1 || echo -e "${YELLOW}⚠️ $PM清理缓存失败${NC}"
|
||||||
|
|
||||||
|
# 清理旧内核(仅保留最新1个)
|
||||||
|
if [ "$PM" = "yum" ]; then
|
||||||
|
package-cleanup --oldkernels --count=1 -y >> "$LOG_FILE" 2>&1 || true
|
||||||
|
elif [ "$PM" = "dnf" ]; then
|
||||||
|
dnf remove --oldinstallonly --setopt installonly_limit=1 -y >> "$LOG_FILE" 2>&1 || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 清理临时文件(不清理太多避免影响运行)
|
||||||
|
rm -rf /tmp/*.deb /tmp/*.rpm /var/tmp/*.deb /var/tmp/*.rpm >> "$LOG_FILE" 2>&1 || true
|
||||||
|
|
||||||
|
# 清理日志文件(保留最近7天)
|
||||||
|
find /var/log -name "*.log" -type f -mtime +7 -delete 2>/dev/null || true
|
||||||
|
find /var/log -name "*.gz" -type f -delete 2>/dev/null || true
|
||||||
|
|
||||||
|
echo -e "${GREEN}✅ 系统清理完成${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 更新系统包管理器
|
||||||
|
update_package_manager() {
|
||||||
|
echo -e "${BLUE}🔄 更新包管理器...${NC}"
|
||||||
|
|
||||||
|
if [ "$OS_TYPE" = "debian" ]; then
|
||||||
|
# 更新apt源
|
||||||
|
if ! $UPDATE_CMD >> "$LOG_FILE" 2>&1; then
|
||||||
|
echo -e "${YELLOW}⚠️ 包管理器更新失败,尝试修复...${NC}"
|
||||||
|
|
||||||
|
# 修复可能的损坏
|
||||||
|
dpkg --configure -a >> "$LOG_FILE" 2>&1 || true
|
||||||
|
apt-get install -f -y >> "$LOG_FILE" 2>&1 || true
|
||||||
|
fi
|
||||||
|
elif [ "$OS_TYPE" = "rhel" ]; then
|
||||||
|
if ! $UPDATE_CMD >> "$LOG_FILE" 2>&1; then
|
||||||
|
echo -e "${YELLOW}⚠️ 包管理器更新失败,尝试修复...${NC}"
|
||||||
|
|
||||||
|
# 修复可能的损坏
|
||||||
|
rpm --rebuilddb >> "$LOG_FILE" 2>&1 || true
|
||||||
|
$PM clean all >> "$LOG_FILE" 2>&1 || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${GREEN}✅ 包管理器更新完成${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 安装基础依赖(精简版)
|
||||||
|
install_basic_dependencies() {
|
||||||
|
echo -e "${BLUE}📦 安装基础依赖包...${NC}"
|
||||||
|
|
||||||
|
local base_packages=()
|
||||||
|
|
||||||
|
if [ "$OS_TYPE" = "debian" ]; then
|
||||||
|
base_packages=(
|
||||||
|
"curl" "wget" "gnupg" "lsb-release" "apt-transport-https"
|
||||||
|
"ca-certificates" "software-properties-common"
|
||||||
|
"net-tools" "dnsutils" "iputils-ping" "sudo" "bc"
|
||||||
|
)
|
||||||
|
elif [ "$OS_TYPE" = "rhel" ]; then
|
||||||
|
base_packages=(
|
||||||
|
"curl" "wget" "gnupg" "redhat-lsb-core" "yum-utils" "epel-release"
|
||||||
|
"ca-certificates" "device-mapper-persistent-data" "lvm2"
|
||||||
|
"net-tools" "bind-utils" "iputils" "sudo" "bc"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
for package in "${base_packages[@]}"; do
|
||||||
|
echo -e "${BLUE}安装 $package...${NC}"
|
||||||
|
if ! $INSTALL_CMD "$package" >> "$LOG_FILE" 2>&1; then
|
||||||
|
echo -e "${YELLOW}⚠️ $package 安装失败,跳过...${NC}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -e "${GREEN}✅ 基础依赖安装完成${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 配置系统优化参数
|
||||||
|
configure_system_optimization() {
|
||||||
|
echo -e "${BLUE}⚙️ 配置系统优化参数...${NC}"
|
||||||
|
|
||||||
|
# 优化内核参数 - 直接修改,不备份
|
||||||
|
if ! grep -q "系统优化配置" /etc/sysctl.conf; then
|
||||||
|
cat >> /etc/sysctl.conf << EOF
|
||||||
|
|
||||||
|
# 系统优化配置 - 添加于 $(date)
|
||||||
|
# 网络优化
|
||||||
|
net.core.rmem_max = 16777216
|
||||||
|
net.core.wmem_max = 16777216
|
||||||
|
net.ipv4.tcp_rmem = 4096 87380 16777216
|
||||||
|
net.ipv4.tcp_wmem = 4096 16384 16777216
|
||||||
|
net.ipv4.tcp_max_syn_backlog = 8192
|
||||||
|
net.ipv4.tcp_tw_reuse = 1
|
||||||
|
|
||||||
|
# 内存优化
|
||||||
|
vm.swappiness = 10
|
||||||
|
vm.dirty_ratio = 15
|
||||||
|
vm.dirty_background_ratio = 5
|
||||||
|
|
||||||
|
# 文件系统优化
|
||||||
|
fs.file-max = 65536
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 应用配置
|
||||||
|
sysctl -p >> "$LOG_FILE" 2>&1 || echo -e "${YELLOW}⚠️ sysctl配置应用失败${NC}"
|
||||||
|
|
||||||
|
# 配置文件描述符限制
|
||||||
|
if ! grep -q "文件描述符限制" /etc/security/limits.conf; then
|
||||||
|
cat >> /etc/security/limits.conf << EOF
|
||||||
|
|
||||||
|
# 文件描述符限制 - 添加于 $(date)
|
||||||
|
* soft nofile 65536
|
||||||
|
* hard nofile 65536
|
||||||
|
root soft nofile 65536
|
||||||
|
root hard nofile 65536
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${GREEN}✅ 系统优化配置完成${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 配置DNS优化
|
||||||
|
configure_dns() {
|
||||||
|
echo -e "${BLUE}🌐 配置DNS优化...${NC}"
|
||||||
|
|
||||||
|
# 直接配置,不备份
|
||||||
|
cat > /etc/resolv.conf << EOF
|
||||||
|
# DNS配置 - 优化于 $(date)
|
||||||
|
nameserver 223.5.5.5
|
||||||
|
nameserver 119.29.29.29
|
||||||
|
nameserver 8.8.8.8
|
||||||
|
nameserver 1.1.1.1
|
||||||
|
options timeout:2 attempts:3 rotate
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 防止NetworkManager覆盖配置
|
||||||
|
if [ -f /etc/NetworkManager/NetworkManager.conf ]; then
|
||||||
|
sed -i 's/^dns=.*/dns=none/' /etc/NetworkManager/NetworkManager.conf 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${GREEN}✅ DNS优化配置完成${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 配置Docker安装环境
|
||||||
|
configure_docker_environment() {
|
||||||
|
echo -e "${BLUE}🐳 配置Docker安装环境...${NC}"
|
||||||
|
|
||||||
|
if [ "$OS_TYPE" = "debian" ]; then
|
||||||
|
# 添加Docker官方GPG密钥
|
||||||
|
curl -fsSL https://download.docker.com/linux/$OS_NAME/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg >> "$LOG_FILE" 2>&1 || {
|
||||||
|
echo -e "${YELLOW}⚠️ Docker GPG密钥添加失败,使用备用方案${NC}"
|
||||||
|
curl -fsSL https://download.docker.com/linux/$OS_NAME/gpg | apt-key add - >> "$LOG_FILE" 2>&1 || true
|
||||||
|
}
|
||||||
|
|
||||||
|
# 添加Docker仓库
|
||||||
|
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/$OS_NAME $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||||
|
|
||||||
|
# 更新包列表
|
||||||
|
$UPDATE_CMD >> "$LOG_FILE" 2>&1 || echo -e "${YELLOW}⚠️ 更新包列表失败${NC}"
|
||||||
|
|
||||||
|
elif [ "$OS_TYPE" = "rhel" ]; then
|
||||||
|
# 添加Docker仓库
|
||||||
|
$INSTALL_CMD yum-utils >> "$LOG_FILE" 2>&1 || true
|
||||||
|
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo >> "$LOG_FILE" 2>&1 || {
|
||||||
|
echo -e "${YELLOW}⚠️ Docker仓库添加失败,使用官方仓库${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 更新包列表
|
||||||
|
$UPDATE_CMD >> "$LOG_FILE" 2>&1 || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${GREEN}✅ Docker环境配置完成${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 安装Docker
|
||||||
|
install_docker() {
|
||||||
|
echo -e "${BLUE}🐳 安装Docker...${NC}"
|
||||||
|
|
||||||
|
# 检查是否已安装Docker
|
||||||
|
if check_command docker; then
|
||||||
|
echo -e "${YELLOW}⚠️ Docker已安装,跳过安装${NC}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$OS_TYPE" = "debian" ]; then
|
||||||
|
$INSTALL_CMD docker-ce docker-ce-cli containerd.io docker-compose-plugin >> "$LOG_FILE" 2>&1 || {
|
||||||
|
echo -e "${YELLOW}⚠️ Docker安装失败,尝试替代方案${NC}"
|
||||||
|
# 尝试安装docker.io
|
||||||
|
$INSTALL_CMD docker.io containerd runc >> "$LOG_FILE" 2>&1 || {
|
||||||
|
echo -e "${RED}❌ Docker安装完全失败${NC}"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elif [ "$OS_TYPE" = "rhel" ]; then
|
||||||
|
$INSTALL_CMD docker-ce docker-ce-cli containerd.io docker-compose-plugin >> "$LOG_FILE" 2>&1 || {
|
||||||
|
echo -e "${YELLOW}⚠️ Docker安装失败,尝试替代方案${NC}"
|
||||||
|
$INSTALL_CMD docker >> "$LOG_FILE" 2>&1 || {
|
||||||
|
echo -e "${RED}❌ Docker安装完全失败${NC}"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 启动Docker服务
|
||||||
|
systemctl enable docker >> "$LOG_FILE" 2>&1 || true
|
||||||
|
systemctl start docker >> "$LOG_FILE" 2>&1 || true
|
||||||
|
|
||||||
|
# 验证安装
|
||||||
|
if docker --version >> "$LOG_FILE" 2>&1; then
|
||||||
|
echo -e "${GREEN}✅ Docker安装成功: $(docker --version)${NC}"
|
||||||
|
|
||||||
|
# 配置用户组
|
||||||
|
usermod -aG docker $USER 2>/dev/null || true
|
||||||
|
echo -e "${GREEN}✅ 已将当前用户添加到docker组${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}❌ Docker安装验证失败${NC}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 安装Docker Compose
|
||||||
|
install_docker_compose() {
|
||||||
|
echo -e "${BLUE}🐳 安装Docker Compose...${NC}"
|
||||||
|
|
||||||
|
# 检查是否已安装
|
||||||
|
if check_command docker-compose; then
|
||||||
|
echo -e "${YELLOW}⚠️ Docker Compose已安装,跳过${NC}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 安装最新版本
|
||||||
|
COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
|
||||||
|
|
||||||
|
if [ -z "$COMPOSE_VERSION" ]; then
|
||||||
|
COMPOSE_VERSION="v2.24.0" # 备用版本
|
||||||
|
fi
|
||||||
|
|
||||||
|
curl -L "https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose >> "$LOG_FILE" 2>&1
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
chmod +x /usr/local/bin/docker-compose
|
||||||
|
ln -sf /usr/local/bin/docker-compose /usr/bin/docker-compose 2>/dev/null || true
|
||||||
|
|
||||||
|
echo -e "${GREEN}✅ Docker Compose安装成功: ${COMPOSE_VERSION}${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}⚠️ Docker Compose安装失败,跳过${NC}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 验证安装结果
|
||||||
|
verify_installation() {
|
||||||
|
echo -e "${BLUE}🔍 验证安装结果...${NC}"
|
||||||
|
|
||||||
|
echo -e "${CYAN}系统信息:${NC}"
|
||||||
|
echo -e " OS: $OS_PRETTY_NAME"
|
||||||
|
echo -e " 内核: $(uname -r)"
|
||||||
|
echo -e " 架构: $(uname -m)"
|
||||||
|
|
||||||
|
echo -e "${CYAN}服务状态:${NC}"
|
||||||
|
if systemctl is-active docker >/dev/null 2>&1; then
|
||||||
|
echo -e " Docker: ${GREEN}运行中${NC}"
|
||||||
|
else
|
||||||
|
echo -e " Docker: ${RED}未运行${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${CYAN}版本信息:${NC}"
|
||||||
|
if check_command docker; then
|
||||||
|
echo -e " Docker: $(docker --version 2>/dev/null | cut -d' ' -f3 | tr -d ',')"
|
||||||
|
else
|
||||||
|
echo -e " Docker: ${RED}未安装${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_command docker-compose; then
|
||||||
|
echo -e " Docker Compose: $(docker-compose --version 2>/dev/null | cut -d' ' -f3 | tr -d ',')"
|
||||||
|
else
|
||||||
|
echo -e " Docker Compose: ${YELLOW}未安装${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 显示磁盘空间
|
||||||
|
echo -e "${CYAN}磁盘空间:${NC}"
|
||||||
|
df -h / | tail -1 | awk '{print " 根分区: " $4 " 可用 / " $2 " 总大小"}'
|
||||||
|
|
||||||
|
echo -e "${GREEN}✅ 验证完成${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 显示使用说明
|
||||||
|
show_usage() {
|
||||||
|
echo -e "${GREEN}系统优化与Docker准备脚本 (精简版)${NC}"
|
||||||
|
echo -e "专为小存储空间VPS设计 - 不备份文件${NC}"
|
||||||
|
echo -e ""
|
||||||
|
echo -e "使用方法: $0 [选项]"
|
||||||
|
echo -e ""
|
||||||
|
echo -e "选项:"
|
||||||
|
echo -e " -h, --help 显示此帮助信息"
|
||||||
|
echo -e " -c, --clean 只执行清理操作"
|
||||||
|
echo -e " -o, --optimize 只执行系统优化"
|
||||||
|
echo -e " -d, --docker 只安装Docker"
|
||||||
|
echo -e " -a, --all 执行所有操作(默认)"
|
||||||
|
echo -e ""
|
||||||
|
echo -e "功能:"
|
||||||
|
echo -e " ✅ 系统检测"
|
||||||
|
echo -e " ✅ 深度清理(节省空间)"
|
||||||
|
echo -e " ✅ 依赖包安装"
|
||||||
|
echo -e " ✅ 系统优化配置"
|
||||||
|
echo -e " ✅ DNS优化"
|
||||||
|
echo -e " ✅ Docker环境准备"
|
||||||
|
echo -e " ✅ Docker安装与配置"
|
||||||
|
echo -e ""
|
||||||
|
echo -e "示例:"
|
||||||
|
echo -e " $0 # 执行所有操作"
|
||||||
|
echo -e " $0 --clean # 只执行清理"
|
||||||
|
echo -e " $0 --docker # 只安装Docker"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 主函数
|
||||||
|
main() {
|
||||||
|
# 创建日志文件
|
||||||
|
> "$LOG_FILE"
|
||||||
|
|
||||||
|
# 显示标题
|
||||||
|
echo -e "${PURPLE}"
|
||||||
|
echo "=================================================="
|
||||||
|
echo " 🚀 系统优化与Docker准备脚本 (精简版)"
|
||||||
|
echo " 专为小存储空间VPS设计"
|
||||||
|
echo "=================================================="
|
||||||
|
echo -e "${NC}"
|
||||||
|
|
||||||
|
# 检查root权限
|
||||||
|
if [ "$EUID" -ne 0 ]; then
|
||||||
|
echo -e "${RED}❌ 请使用root权限运行此脚本${NC}"
|
||||||
|
echo -e "使用: sudo $0"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 解析命令行参数
|
||||||
|
case "${1:-}" in
|
||||||
|
-h|--help)
|
||||||
|
show_usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-c|--clean)
|
||||||
|
echo -e "${BLUE}执行清理操作...${NC}"
|
||||||
|
detect_os
|
||||||
|
clean_system
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-o|--optimize)
|
||||||
|
echo -e "${BLUE}执行系统优化...${NC}"
|
||||||
|
detect_os
|
||||||
|
configure_system_optimization
|
||||||
|
configure_dns
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-d|--docker)
|
||||||
|
echo -e "${BLUE}安装Docker...${NC}"
|
||||||
|
detect_os
|
||||||
|
configure_docker_environment
|
||||||
|
install_docker
|
||||||
|
install_docker_compose
|
||||||
|
verify_installation
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-a|--all|*)
|
||||||
|
# 执行所有操作
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# 执行完整流程
|
||||||
|
echo -e "${BLUE}开始系统优化与Docker准备...${NC}"
|
||||||
|
|
||||||
|
detect_os
|
||||||
|
check_architecture
|
||||||
|
clean_system
|
||||||
|
update_package_manager
|
||||||
|
install_basic_dependencies
|
||||||
|
configure_system_optimization
|
||||||
|
configure_dns
|
||||||
|
configure_docker_environment
|
||||||
|
install_docker
|
||||||
|
install_docker_compose
|
||||||
|
|
||||||
|
echo -e "${GREEN}🎉 所有操作完成!${NC}"
|
||||||
|
echo ""
|
||||||
|
verify_installation
|
||||||
|
echo ""
|
||||||
|
echo -e "${YELLOW}💡 重要提示:${NC}"
|
||||||
|
echo -e " 1. 建议重启系统以使所有配置生效"
|
||||||
|
echo -e " 2. 当前用户已添加到docker组,重新登录后生效"
|
||||||
|
echo -e " 3. 详细日志请查看: $LOG_FILE"
|
||||||
|
echo -e " 4. 脚本已尽可能节省磁盘空间"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 设置陷阱,确保脚本退出时重置颜色
|
||||||
|
trap 'echo -e "${NC}"' EXIT
|
||||||
|
|
||||||
|
# 运行主函数
|
||||||
|
main "$@"
|
||||||
258
自动部署并配置 cloudflared 隧道服务
Normal file
258
自动部署并配置 cloudflared 隧道服务
Normal file
@@ -0,0 +1,258 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# cloudflared Docker 容器化一键部署脚本
|
||||||
|
# 功能:自动部署并配置 cloudflared 隧道服务
|
||||||
|
|
||||||
|
set -e # 遇到任何错误立即退出脚本
|
||||||
|
|
||||||
|
# 颜色定义用于输出美化
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # 无颜色
|
||||||
|
|
||||||
|
# 定义两个不同的密钥和服务器类型
|
||||||
|
CF_TOKEN_1="eyJhIjoiYmI2OTg1ZGU4N2ZiMDEyYjNjNjI2YWExM2VkYTY3OTciLCJ0IjoiNGYyMjNhM2UtNWNjYy00ZmMwLWI1N2MtNjQzZGY5ZmI1ZWZmIiwicyI6Ik1qTmxOR1U0WmpndE5ERXlPQzAwTjJKaExUazNaVFl0WVRWaU5tUmtObVkxTkdSaSJ9"
|
||||||
|
SERVER_1="国内服务器"
|
||||||
|
|
||||||
|
CF_TOKEN_2="eyJhIjoiYmI2OTg1ZGU4N2ZiMDEyYjNjNjI2YWExM2VkYTY3OTciLCJ0IjoiOWRhNTU2YmMtMWZhNC00Njg2LTg1YTQtZTczOTQ1YmEwMGNmIiwicyI6Ik5XWTNPV05tTkRjdFltVTBOQzAwTkRkaExXRm1ZVEF0T1daaE9XRTVaVFUyTWpRMSJ9"
|
||||||
|
SERVER_2="香港服务器"
|
||||||
|
|
||||||
|
# 输出带颜色的信息函数
|
||||||
|
log_info() {
|
||||||
|
echo -e "${GREEN}[INFO]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_warning() {
|
||||||
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_error() {
|
||||||
|
echo -e "${RED}[ERROR]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_step() {
|
||||||
|
echo -e "${BLUE}[STEP]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查 Docker 是否可用
|
||||||
|
check_docker() {
|
||||||
|
log_step "检查 Docker 服务状态..."
|
||||||
|
if ! command -v docker &> /dev/null; then
|
||||||
|
log_error "Docker 未安装,请先安装 Docker"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! docker info &> /dev/null; then
|
||||||
|
log_error "Docker 服务未运行,请启动 Docker 服务"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
log_info "Docker 服务状态正常"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 准备数据目录和配置文件
|
||||||
|
prepare_directories() {
|
||||||
|
log_step "准备数据目录和配置文件..."
|
||||||
|
|
||||||
|
# 创建 /data 目录(如果不存在)
|
||||||
|
if [ ! -d "/data" ]; then
|
||||||
|
log_info "创建 /data 目录"
|
||||||
|
sudo mkdir -p /data
|
||||||
|
sudo chmod 755 /data
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 切换到工作目录
|
||||||
|
cd /data
|
||||||
|
|
||||||
|
# 创建 cloudflared 相关目录
|
||||||
|
mkdir -p cloudflared/{config,logs,cert}
|
||||||
|
chmod -R 755 cloudflared
|
||||||
|
|
||||||
|
# 创建配置文件
|
||||||
|
cat > /data/cloudflared/config/config.yml << EOF
|
||||||
|
# Cloudflare Tunnel 配置文件
|
||||||
|
tunnel: $(echo $CF_TUNNEL_TOKEN | cut -d'.' -f2 | base64 -d 2>/dev/null | grep '"t"' | cut -d'"' -f4 || echo "tunnel-id")
|
||||||
|
credentials-file: /etc/cloudflared/credentials.json
|
||||||
|
logfile: /var/log/cloudflared/cloudflared.log
|
||||||
|
loglevel: info
|
||||||
|
|
||||||
|
# 服务配置(示例,请根据实际需求调整)
|
||||||
|
ingress:
|
||||||
|
- hostname: example.your-domain.com
|
||||||
|
service: http://localhost:80
|
||||||
|
originRequest:
|
||||||
|
connectTimeout: 30s
|
||||||
|
noTLSVerify: false
|
||||||
|
- service: http_status:404
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 创建凭证文件
|
||||||
|
cat > /data/cloudflared/config/credentials.json << EOF
|
||||||
|
{"AccountTag":"$(echo $CF_TUNNEL_TOKEN | cut -d'.' -f2 | base64 -d 2>/dev/null | grep '"a"' | cut -d'"' -f4 || echo "account-tag")","TunnelSecret":"$(echo $CF_TUNNEL_TOKEN | cut -d'.' -f2 | base64 -d 2>/dev/null | grep '"s"' | cut -d'"' -f4 || echo "tunnel-secret")","TunnelID":"$(echo $CF_TUNNEL_TOKEN | cut -d'.' -f2 | base64 -d 2>/dev/null | grep '"t"' | cut -d'"' -f4 || echo "tunnel-id")","TunnelName":"docker-tunnel"}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_info "数据目录和配置文件准备完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 验证 Cloudflare Token 格式
|
||||||
|
validate_token() {
|
||||||
|
log_step "验证 Cloudflare Tunnel Token..."
|
||||||
|
|
||||||
|
if [ -z "$CF_TUNNEL_TOKEN" ]; then
|
||||||
|
log_error "Cloudflare Tunnel Token 不能为空"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 简单的 token 格式验证
|
||||||
|
if [[ ! "$CF_TUNNEL_TOKEN" =~ ^eyJ ]]; then
|
||||||
|
log_warning "Token 格式可能不正确,但将继续部署"
|
||||||
|
else
|
||||||
|
log_info "Token 格式验证通过"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 部署 cloudflared 容器
|
||||||
|
deploy_cloudflared() {
|
||||||
|
log_step "开始部署 cloudflared 容器..."
|
||||||
|
|
||||||
|
local container_name="cloudflared-tunnel"
|
||||||
|
|
||||||
|
# 检查容器是否已存在
|
||||||
|
if docker ps -a --format "{{.Names}}" | grep -q "^${container_name}$"; then
|
||||||
|
log_info "发现已存在的 ${container_name} 容器,正在清理..."
|
||||||
|
docker stop ${container_name} >/dev/null 2>&1 || true
|
||||||
|
docker rm ${container_name} >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 运行 cloudflared 容器
|
||||||
|
log_info "启动 cloudflared 隧道服务..."
|
||||||
|
docker run -d \
|
||||||
|
--name ${container_name} \
|
||||||
|
--restart=unless-stopped \
|
||||||
|
--network host \
|
||||||
|
-v /data/cloudflared/config:/etc/cloudflared \
|
||||||
|
-v /data/cloudflared/logs:/var/log/cloudflared \
|
||||||
|
-v /data/cloudflared/cert:/home/nonroot/.cloudflared \
|
||||||
|
-e TUNNEL_TOKEN="${CF_TUNNEL_TOKEN}" \
|
||||||
|
cloudflare/cloudflared:latest \
|
||||||
|
tunnel --config /etc/cloudflared/config.yml run
|
||||||
|
|
||||||
|
log_info "cloudflared 容器部署完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 验证容器状态
|
||||||
|
verify_deployment() {
|
||||||
|
log_step "验证容器运行状态..."
|
||||||
|
|
||||||
|
local container_name="cloudflared-tunnel"
|
||||||
|
local max_retries=10
|
||||||
|
local retry_interval=5
|
||||||
|
|
||||||
|
for i in $(seq 1 $max_retries); do
|
||||||
|
if docker ps --format "{{.Names}}" | grep -q "^${container_name}$"; then
|
||||||
|
local status=$(docker inspect -f '{{.State.Status}}' ${container_name} 2>/dev/null || echo "unknown")
|
||||||
|
|
||||||
|
if [ "$status" = "running" ]; then
|
||||||
|
log_info "✅ cloudflared 容器正在正常运行"
|
||||||
|
|
||||||
|
# 显示容器信息
|
||||||
|
echo ""
|
||||||
|
log_info "容器名称: ${container_name}"
|
||||||
|
log_info "运行状态: ${status}"
|
||||||
|
log_info "数据目录: /data/cloudflared/"
|
||||||
|
log_info "配置目录: /data/cloudflared/config"
|
||||||
|
log_info "日志目录: /data/cloudflared/logs"
|
||||||
|
log_info "证书目录: /data/cloudflared/cert"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 显示最近日志
|
||||||
|
log_info "容器启动日志:"
|
||||||
|
docker logs ${container_name} --tail 10
|
||||||
|
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
log_warning "容器状态: ${status},等待中... (尝试 $i/$max_retries)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_warning "容器未运行,等待中... (尝试 $i/$max_retries)"
|
||||||
|
fi
|
||||||
|
sleep $retry_interval
|
||||||
|
done
|
||||||
|
|
||||||
|
log_error "❌ 容器启动失败或超时"
|
||||||
|
docker logs ${container_name} --tail 50
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 显示使用说明
|
||||||
|
show_usage() {
|
||||||
|
echo ""
|
||||||
|
log_info "🔧 使用说明:"
|
||||||
|
log_info "查看日志: docker logs cloudflared-tunnel -f"
|
||||||
|
log_info "重启服务: docker restart cloudflared-tunnel"
|
||||||
|
log_info "停止服务: docker stop cloudflared-tunnel"
|
||||||
|
log_info "查看状态: docker ps -f name=cloudflared-tunnel"
|
||||||
|
echo ""
|
||||||
|
log_info "📁 配置文件路径: /data/cloudflared/config/config.yml"
|
||||||
|
log_info "请根据实际需求修改配置文件中的域名和服务设置"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# 选择密钥和服务器
|
||||||
|
select_token() {
|
||||||
|
echo ""
|
||||||
|
log_step "请选择要使用的隧道配置:"
|
||||||
|
echo "1) 使用默认密钥 ($SERVER_1)"
|
||||||
|
echo "2) 使用备用密钥 ($SERVER_2)"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
read -p "请输入选择 (1 或 2): " choice
|
||||||
|
case $choice in
|
||||||
|
1)
|
||||||
|
CF_TUNNEL_TOKEN=$CF_TOKEN_1
|
||||||
|
SERVER_TYPE=$SERVER_1
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
CF_TUNNEL_TOKEN=$CF_TOKEN_2
|
||||||
|
SERVER_TYPE=$SERVER_2
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "无效选择,请重新输入"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
log_info "已选择: $SERVER_TYPE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 主执行函数
|
||||||
|
main() {
|
||||||
|
echo ""
|
||||||
|
log_info "🚀 开始部署 Cloudflare Tunnel Docker 容器..."
|
||||||
|
log_info "=========================================="
|
||||||
|
|
||||||
|
# 让用户选择密钥
|
||||||
|
select_token
|
||||||
|
|
||||||
|
validate_token
|
||||||
|
check_docker
|
||||||
|
prepare_directories
|
||||||
|
deploy_cloudflared
|
||||||
|
verify_deployment
|
||||||
|
|
||||||
|
log_info "=========================================="
|
||||||
|
log_info "✅ Cloudflare Tunnel 部署完成!"
|
||||||
|
log_info "隧道已使用 $SERVER_TYPE 的 Token 进行认证"
|
||||||
|
|
||||||
|
show_usage
|
||||||
|
}
|
||||||
|
|
||||||
|
# 异常处理
|
||||||
|
trap 'log_error "脚本执行被中断"; exit 1' INT TERM
|
||||||
|
|
||||||
|
# 执行主函数
|
||||||
|
main "$@"
|
||||||
148
试验用脚本
Normal file
148
试验用脚本
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 网络环境检测脚本
|
||||||
|
# 功能:检测公网 IPv4 和 IPv6 地址
|
||||||
|
# 作者:AI 助手
|
||||||
|
|
||||||
|
# 设置严格模式
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# 日志函数
|
||||||
|
log() {
|
||||||
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 错误处理函数
|
||||||
|
error() {
|
||||||
|
log "❌ $*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 警告处理函数
|
||||||
|
warn() {
|
||||||
|
log "⚠️ $*" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
# 信息输出函数
|
||||||
|
info() {
|
||||||
|
log "📝 $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查命令是否存在
|
||||||
|
has_cmd() {
|
||||||
|
command -v "$1" &>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# 获取公网 IPv4 地址
|
||||||
|
get_public_ipv4() {
|
||||||
|
local timeout=10
|
||||||
|
local url="http://ipv4.icanhazip.com"
|
||||||
|
|
||||||
|
if ! has_cmd curl; then
|
||||||
|
error "curl 命令未找到,请安装 curl"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local response
|
||||||
|
response=$(curl -s -m "$timeout" "$url" 2>/dev/null) || {
|
||||||
|
warn "无法连接到 IPv4 服务,请检查网络设置。"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查返回的是否为有效的 IPv4 地址
|
||||||
|
if [[ $response =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
|
||||||
|
echo "$response"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
warn "请求的服务返回异常数据:$response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 获取公网 IPv6 地址
|
||||||
|
get_public_ipv6() {
|
||||||
|
local timeout=10
|
||||||
|
local url="http://ipv6.icanhazip.com"
|
||||||
|
|
||||||
|
if ! has_cmd curl; then
|
||||||
|
error "curl 命令未找到,请安装 curl"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local response
|
||||||
|
response=$(curl -s -m "$timeout" "$url" 2>/dev/null) || {
|
||||||
|
warn "无法连接到 IPv6 服务,请检查网络设置。"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查返回的是否为有效的 IPv6 地址(简化验证)
|
||||||
|
if [[ $response =~ ^([0-9a-fA-F]{0,4}:){2,7}[0-9a-fA-F]{0,4}$ ]]; then
|
||||||
|
echo "$response"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
warn "请求的服务返回异常数据:$response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 验证 IPv4 地址格式
|
||||||
|
is_valid_ipv4() {
|
||||||
|
local ip="$1"
|
||||||
|
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
|
||||||
|
local IFS='.'
|
||||||
|
local -a octets=($ip)
|
||||||
|
for octet in "${octets[@]}"; do
|
||||||
|
if [[ $octet -gt 255 ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 验证 IPv6 地址格式(简化验证)
|
||||||
|
is_valid_ipv6() {
|
||||||
|
local ip="$1"
|
||||||
|
# 检查是否为有效的 IPv6 地址格式
|
||||||
|
if [[ $ip =~ ^([0-9a-fA-F]{0,4}:){2,7}[0-9a-fA-F]{0,4}$ ]] || [[ $ip =~ ^::1$ ]] || [[ $ip =~ ^::$ ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 主函数
|
||||||
|
main() {
|
||||||
|
info "开始检测网络环境..."
|
||||||
|
|
||||||
|
# 检测公网 IPv4 地址
|
||||||
|
info "检测公网 IPv4 地址..."
|
||||||
|
local ipv4_result
|
||||||
|
if ipv4_result=$(get_public_ipv4); then
|
||||||
|
if is_valid_ipv4 "$ipv4_result"; then
|
||||||
|
info "当前拥有公网 IPv4 地址:$ipv4_result"
|
||||||
|
else
|
||||||
|
warn "获取到的 IPv4 地址无效:$ipv4_result"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
info "当前没有公网 IPv4 地址"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检测公网 IPv6 地址
|
||||||
|
info "检测公网 IPv6 地址..."
|
||||||
|
local ipv6_result
|
||||||
|
if ipv6_result=$(get_public_ipv6); then
|
||||||
|
if is_valid_ipv6 "$ipv6_result"; then
|
||||||
|
info "当前拥有公网 IPv6 地址:$ipv6_result"
|
||||||
|
else
|
||||||
|
warn "获取到的 IPv6 地址无效:$ipv6_result"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
info "当前没有公网 IPv6 地址"
|
||||||
|
fi
|
||||||
|
|
||||||
|
info "网络环境检测完成。"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 执行主函数
|
||||||
|
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||||
|
main "$@"
|
||||||
|
fi
|
||||||
54
防火墙关闭de12
Normal file
54
防火墙关闭de12
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# 综合防火墙关闭脚本
|
||||||
|
|
||||||
|
echo "=== 开始关闭系统防火墙 ==="
|
||||||
|
|
||||||
|
# 检查并关闭 UFW
|
||||||
|
if command -v ufw &> /dev/null; then
|
||||||
|
echo "关闭 UFW..."
|
||||||
|
ufw disable
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查并停止 nftables
|
||||||
|
if systemctl is-active --quiet nftables; then
|
||||||
|
echo "停止 nftables..."
|
||||||
|
systemctl stop nftables
|
||||||
|
systemctl disable nftables
|
||||||
|
nft flush ruleset
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查并停止 iptables
|
||||||
|
if systemctl is-active --quiet iptables; then
|
||||||
|
echo "停止 iptables..."
|
||||||
|
systemctl stop iptables
|
||||||
|
systemctl disable iptables
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 清除 iptables 规则
|
||||||
|
echo "清除 iptables 规则..."
|
||||||
|
iptables -F
|
||||||
|
iptables -X
|
||||||
|
iptables -t nat -F
|
||||||
|
iptables -t nat -X
|
||||||
|
iptables -t mangle -F
|
||||||
|
iptables -t mangle -X
|
||||||
|
iptables -P INPUT ACCEPT
|
||||||
|
iptables -P FORWARD ACCEPT
|
||||||
|
iptables -P OUTPUT ACCEPT
|
||||||
|
|
||||||
|
# 清除 ip6tables 规则
|
||||||
|
ip6tables -F
|
||||||
|
ip6tables -X
|
||||||
|
ip6tables -t nat -F
|
||||||
|
ip6tables -t nat -X
|
||||||
|
ip6tables -t mangle -F
|
||||||
|
ip6tables -t mangle -X
|
||||||
|
ip6tables -P INPUT ACCEPT
|
||||||
|
ip6tables -P FORWARD ACCEPT
|
||||||
|
ip6tables -P OUTPUT ACCEPT
|
||||||
|
|
||||||
|
echo "=== 防火墙关闭完成 ==="
|
||||||
|
echo "当前防火墙状态:"
|
||||||
|
echo "UFW: $(ufw status 2>/dev/null | head -n1 || echo '未安装')"
|
||||||
|
echo "nftables: $(systemctl is-active nftables 2>/dev/null || echo '未运行')"
|
||||||
|
echo "iptables: $(systemctl is-active iptables 2>/dev/null || echo '未运行')"
|
||||||
Reference in New Issue
Block a user