Files
dock/01
2025-11-05 21:33:11 +08:00

441 lines
12 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# 服务器控制器脚本 - 监听端口5555
# 支持: Debian, Ubuntu, CentOS, RHEL, Fedora, Alpine
SERVER_PORT=5555
LOG_FILE="/var/log/controller_server.log"
CLIENTS_FILE="/var/lib/controller_clients.txt"
SCRIPT_DIR="/opt/controller_scripts"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
log() {
echo -e "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}
print_color() {
echo -e "${2}${1}${NC}"
}
# 检查命令是否存在
check_command() {
if ! command -v "$1" &> /dev/null; then
return 1
fi
return 0
}
# 检查root权限
check_root() {
if [[ $EUID -ne 0 ]]; then
print_color "错误: 此脚本需要root权限运行" "$RED"
exit 1
fi
}
# 安装依赖
install_dependencies() {
local distro=$(grep -oP '(?<=^ID=).+' /etc/os-release | tr -d '"')
print_color "检测到系统: $distro" "$BLUE"
print_color "安装必要依赖..." "$YELLOW"
case $distro in
debian|ubuntu)
apt-get update
apt-get install -y netcat-traditional net-tools iproute2
;;
centos|rhel|fedora)
if command -v dnf &> /dev/null; then
dnf install -y nc net-tools iproute2
else
yum install -y nc net-tools iproute2
fi
;;
alpine)
apk add netcat-openbsd net-tools iproute2
;;
*)
log "未知发行版尝试安装netcat"
if command -v apt-get &> /dev/null; then
apt-get update && apt-get install -y netcat-traditional
elif command -v yum &> /dev/null; then
yum install -y nc
elif command -v apk &> /dev/null; then
apk add netcat-openbsd
fi
;;
esac
# 检查netcat是否安装成功
if ! check_command nc && ! check_command netcat; then
print_color "错误: 无法安装netcat请手动安装" "$RED"
exit 1
fi
print_color "依赖安装完成!" "$GREEN"
}
# 获取netcat命令
get_nc_command() {
if check_command nc; then
echo "nc"
elif check_command netcat; then
echo "netcat"
else
echo ""
fi
}
# 初始化环境
initialize() {
mkdir -p "$(dirname "$LOG_FILE")"
mkdir -p "$(dirname "$CLIENTS_FILE")"
mkdir -p "$SCRIPT_DIR"
# 创建示例脚本
create_sample_scripts
touch "$LOG_FILE"
touch "$CLIENTS_FILE"
print_color "初始化完成!" "$GREEN"
}
create_sample_scripts() {
# 关机脚本
cat > "$SCRIPT_DIR/shutdown.sh" << 'EOF'
#!/bin/bash
echo "执行关机操作..."
shutdown -h now
EOF
# 重启脚本
cat > "$SCRIPT_DIR/reboot.sh" << 'EOF'
#!/bin/bash
echo "执行重启操作..."
reboot
EOF
# 服务重启脚本
cat > "$SCRIPT_DIR/restart_services.sh" << 'EOF'
#!/bin/bash
echo "重启网络服务..."
systemctl restart networking 2>/dev/null || systemctl restart network 2>/dev/null
echo "重启SSH服务..."
systemctl restart ssh 2>/dev/null || systemctl restart sshd 2>/dev/null
EOF
# 系统信息脚本
cat > "$SCRIPT_DIR/system_info.sh" << 'EOF'
#!/bin/bash
echo "=== 系统信息 ==="
echo "主机名: $(hostname)"
echo "系统: $(grep PRETTY_NAME /etc/os-release | cut -d= -f2 | tr -d '\"')"
echo "内核: $(uname -r)"
echo "架构: $(uname -m)"
echo "上线时间: $(uptime -p)"
echo "内存使用:"
free -h
echo "磁盘使用:"
df -h
EOF
# 更新系统脚本
cat > "$SCRIPT_DIR/update_system.sh" << 'EOF'
#!/bin/bash
echo "开始系统更新..."
if command -v apt-get &> /dev/null; then
apt-get update && apt-get upgrade -y
elif command -v yum &> /dev/null; then
yum update -y
elif command -v dnf &> /dev/null; then
dnf update -y
elif command -v apk &> /dev/null; then
apk update && apk upgrade
fi
echo "系统更新完成!"
EOF
chmod +x "$SCRIPT_DIR"/*.sh
}
# 显示客户端列表
show_clients() {
if [[ ! -s "$CLIENTS_FILE" ]]; then
print_color "没有已连接的客户端" "$YELLOW"
return
fi
print_color "已连接的客户端列表:" "$BLUE"
print_color "序列号 | IP地址 | 主机名 | 最后在线" "$BLUE"
print_color "----------------------------------------------------" "$BLUE"
while IFS='|' read -r serial ip hostname system last_seen; do
printf "%-10s| %-13s| %-15s| %s\n" "$serial" "$ip" "$hostname" "$last_seen"
done < "$CLIENTS_FILE"
}
# 向客户端发送命令
send_command() {
local serial=$1
local command=$2
if [[ -z "$serial" || -z "$command" ]]; then
print_color "用法: send <序列号> <命令>" "$RED"
return
fi
local client_info=$(grep "^$serial|" "$CLIENTS_FILE")
if [[ -z "$client_info" ]]; then
print_color "错误: 未找到序列号 $serial 的客户端" "$RED"
return
fi
IFS='|' read -r serial ip hostname system last_seen <<< "$client_info"
print_color "向客户端 $serial ($hostname) 发送命令: $command" "$GREEN"
# 发送命令到客户端
local nc_cmd=$(get_nc_command)
if [[ -z "$nc_cmd" ]]; then
print_color "错误: netcat 未安装" "$RED"
return
fi
echo "COMMAND:$command" | timeout 5 $nc_cmd "$ip" 5556
if [[ $? -eq 0 ]]; then
print_color "命令发送成功!" "$GREEN"
else
print_color "命令发送失败!" "$RED"
fi
}
# 广播命令到所有客户端
broadcast_command() {
local command=$1
if [[ -z "$command" ]]; then
print_color "用法: broadcast <命令>" "$RED"
return
fi
print_color "向所有客户端广播命令: $command" "$YELLOW"
local nc_cmd=$(get_nc_command)
if [[ -z "$nc_cmd" ]]; then
print_color "错误: netcat 未安装" "$RED"
return
fi
while IFS='|' read -r serial ip hostname system last_seen; do
if [[ -n "$serial" && -n "$ip" ]]; then
echo "$serial ($hostname) 发送命令..."
echo "COMMAND:$command" | timeout 3 $nc_cmd "$ip" 5556
fi
done < "$CLIENTS_FILE"
}
# 执行本地脚本
execute_script() {
local serial=$1
local script_name=$2
if [[ -z "$serial" || -z "$script_name" ]]; then
print_color "用法: script <序列号> <脚本名>" "$RED"
print_color "可用脚本:" "$BLUE"
ls "$SCRIPT_DIR"/*.sh | xargs -n 1 basename
return
fi
local script_path="$SCRIPT_DIR/$script_name"
if [[ ! -f "$script_path" ]]; then
print_color "错误: 脚本 $script_name 不存在" "$RED"
return
fi
local client_info=$(grep "^$serial|" "$CLIENTS_FILE")
if [[ -z "$client_info" ]]; then
print_color "错误: 未找到序列号 $serial 的客户端" "$RED"
return
fi
IFS='|' read -r serial ip hostname system last_seen <<< "$client_info"
print_color "向客户端 $serial 发送脚本: $script_name" "$GREEN"
local nc_cmd=$(get_nc_command)
if [[ -z "$nc_cmd" ]]; then
print_color "错误: netcat 未安装" "$RED"
return
fi
# 发送脚本执行命令
echo "SCRIPT:$script_name" | timeout 5 $nc_cmd "$ip" 5556
}
# 启动服务器
start_server() {
local nc_cmd=$(get_nc_command)
if [[ -z "$nc_cmd" ]]; then
print_color "错误: netcat 未安装,无法启动服务器" "$RED"
return 1
fi
print_color "启动控制器服务器在端口 $SERVER_PORT..." "$GREEN"
print_color "使用 netcat 命令: $nc_cmd" "$BLUE"
print_color "服务器日志: $LOG_FILE" "$BLUE"
print_color "客户端列表: $CLIENTS_FILE" "$BLUE"
print_color "按 Ctrl+C 停止服务器" "$YELLOW"
while true; do
log "等待客户端连接..."
$nc_cmd -l -p $SERVER_PORT -c '
client_ip=$(echo $SSH_CLIENT | awk "{print \$1}")
if [[ -z "$client_ip" ]]; then
client_ip="unknown"
fi
read -r data
timestamp=$(date "+%Y-%m-%d %H:%M:%S")
if echo "$data" | grep -q "HEARTBEAT|"; then
IFS="|" read -r heartbeat serial hostname system <<< "$data"
# 更新或添加客户端信息
grep -v "^$serial|" /var/lib/controller_clients.txt > /tmp/clients.tmp 2>/dev/null
echo "$serial|$client_ip|$hostname|$system|$timestamp" >> /tmp/clients.tmp
mv /tmp/clients.tmp /var/lib/controller_clients.txt
echo "ACK:OK"
echo "客户端 $serial 已连接 - $hostname"
else
echo "ACK:UNKNOWN_COMMAND"
fi
' 2>/dev/null
sleep 1
done
}
# 显示帮助
show_help() {
print_color "服务器控制器命令:" "$BLUE"
echo "list - 显示客户端列表"
echo "send - 向指定客户端发送命令"
echo "broadcast - 向所有客户端广播命令"
echo "script - 执行预定义脚本"
echo "scripts - 显示可用脚本"
echo "start - 启动服务器"
echo "stop - 停止服务器"
echo "status - 显示服务器状态"
echo "help - 显示此帮助"
}
# 停止服务器
stop_server() {
pkill -f "nc -l -p $SERVER_PORT"
print_color "服务器已停止" "$GREEN"
}
# 显示服务器状态
show_status() {
if pgrep -f "nc -l -p $SERVER_PORT" >/dev/null; then
print_color "服务器运行中" "$GREEN"
print_color "监听端口: $SERVER_PORT" "$BLUE"
else
print_color "服务器未运行" "$RED"
fi
if [[ -f "$CLIENTS_FILE" ]]; then
client_count=$(grep -c . "$CLIENTS_FILE" 2>/dev/null || echo "0")
print_color "已连接客户端: $client_count" "$BLUE"
fi
}
# 主菜单
main_menu() {
while true; do
print_color "=== 跨平台服务器控制器 ===" "$BLUE"
echo "1. 启动服务器"
echo "2. 显示客户端列表"
echo "3. 发送命令到客户端"
echo "4. 广播命令到所有客户端"
echo "5. 执行脚本"
echo "6. 显示可用脚本"
echo "7. 服务器状态"
echo "8. 停止服务器"
echo "9. 退出"
read -p "请选择操作 [1-9]: " choice
case $choice in
1)
start_server
;;
2)
show_clients
;;
3)
read -p "输入序列号: " serial
read -p "输入命令: " command
send_command "$serial" "$command"
;;
4)
read -p "输入广播命令: " command
broadcast_command "$command"
;;
5)
read -p "输入序列号: " serial
read -p "输入脚本名: " script
execute_script "$serial" "$script"
;;
6)
print_color "可用脚本:" "$BLUE"
ls "$SCRIPT_DIR"/*.sh 2>/dev/null | xargs -n 1 basename || echo "无可用脚本"
;;
7)
show_status
;;
8)
stop_server
;;
9)
print_color "再见!" "$GREEN"
exit 0
;;
*)
print_color "无效选择!" "$RED"
;;
esac
echo
read -p "按回车键继续..."
clear
done
}
# 脚本入口
case "${1:-}" in
start)
check_root
install_dependencies
initialize
start_server
;;
stop)
stop_server
;;
status)
show_status
;;
*)
check_root
install_dependencies
initialize
main_menu
;;
esac