125 lines
4.0 KiB
Bash
125 lines
4.0 KiB
Bash
#!/bin/bash
|
||
|
||
# 1. 检查是否以 root 权限运行
|
||
if [ "$EUID" -ne 0 ]; then
|
||
echo "❌ 错误: 请使用 root 权限 (sudo) 运行此脚本。"
|
||
exit 1
|
||
fi
|
||
|
||
# 2. 定义用户列表文件
|
||
USER_FILE="vnc_users.txt"
|
||
|
||
# 检查文件是否存在
|
||
if [ ! -f "$USER_FILE" ]; then
|
||
echo "❌ 错误: 找不到用户列表文件 '$USER_FILE'。"
|
||
echo "请创建一个包含 '用户名:密码' 的文件 (例如: user1:123456)。"
|
||
exit 1
|
||
fi
|
||
|
||
# 3. 检查必备命令
|
||
if ! command -v vncpasswd &> /dev/null || ! command -v vncserver &> /dev/null; then
|
||
echo "❌ 错误: 系统中未找到 VNC 相关命令。请先安装 VNC Server。"
|
||
exit 1
|
||
fi
|
||
|
||
echo "🚀 开始批量创建账号并配置 VNC 开机自启服务..."
|
||
echo "========================================"
|
||
|
||
# 初始化 VNC 显示编号,从 1 开始 (对应端口 5901)
|
||
DISPLAY_NUM=1
|
||
|
||
# 4. 逐行读取文件并处理
|
||
while IFS=':' read -r username password; do
|
||
# 忽略空行和以 # 开头的注释行
|
||
[[ -z "$username" || "$username" == \#* ]] && continue
|
||
|
||
username=$(echo "$username" | tr -d '\r' | xargs)
|
||
password=$(echo "$password" | tr -d '\r' | xargs)
|
||
|
||
echo "⏳ 正在处理用户: $username"
|
||
|
||
# 步骤 A: 创建系统用户
|
||
if id "$username" &>/dev/null; then
|
||
echo " -> ⚠️ 系统用户 $username 已存在,跳过创建。"
|
||
else
|
||
useradd -m "$username" -s /bin/bash
|
||
echo "$username:$password" | chpasswd
|
||
echo " -> ✅ 系统用户 $username 创建成功。"
|
||
fi
|
||
|
||
# 步骤 B: 配置 VNC 密码及目录
|
||
VNC_DIR="/home/$username/.vnc"
|
||
mkdir -p "$VNC_DIR"
|
||
|
||
echo "$password" | vncpasswd -f > "$VNC_DIR/passwd"
|
||
chmod 600 "$VNC_DIR/passwd"
|
||
chown -R "$username:$username" "$VNC_DIR"
|
||
echo " -> ✅ VNC 密码配置完成。"
|
||
|
||
# 步骤 C: 创建 systemd 服务文件以实现开机自启
|
||
CURRENT_PORT=$((5900 + DISPLAY_NUM))
|
||
echo " -> ⚙️ 准备配置 VNC 桌面 :$DISPLAY_NUM (端口: $CURRENT_PORT) 并设置开机自启"
|
||
|
||
SERVICE_FILE="/etc/systemd/system/vnc-${username}.service"
|
||
|
||
|
||
#[Unit]
|
||
#Description=VNC Server for $username on display $DISPLAY_NUM
|
||
#After=syslog.target network.target
|
||
|
||
#[Service]
|
||
#Type=forking
|
||
#User=$username
|
||
#Group=$username
|
||
#WorkingDirectory=/home/$username
|
||
# 启动前清理可能残留的锁文件
|
||
#ExecStartPre=-/usr/bin/vncserver -kill :$DISPLAY_NUM > /dev/null 2>&1
|
||
# 启动 VNC 服务 (可根据需要调整分辨率 -geometry)
|
||
#ExecStart=/usr/bin/vncserver :$DISPLAY_NUM -geometry 1280x720 -depth 24
|
||
#ExecStop=/usr/bin/vncserver -kill :$DISPLAY_NUM
|
||
|
||
#[Install]
|
||
#WantedBy=multi-user.target
|
||
# 写入专属的 systemd 服务配置
|
||
# 写入专属的 systemd 服务配置
|
||
cat <<EOF > "$SERVICE_FILE"
|
||
[Unit]
|
||
Description=Remote desktop service (VNC)
|
||
After=syslog.target network.target
|
||
|
||
[Service]
|
||
Type=forking
|
||
# 核心修复点 1:除了常规 kill,强制移除残留的 X 锁文件和套接字
|
||
ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill :$DISPLAY_NUM > /dev/null 2>&1 || :'
|
||
ExecStartPre=/bin/sh -c 'rm -f /tmp/.X11-unix/X$DISPLAY_NUM /tmp/.X$DISPLAY_NUM-lock'
|
||
|
||
ExecStart=/usr/sbin/runuser -l $username -c "/usr/bin/vncserver :$DISPLAY_NUM"
|
||
|
||
# 核心修复点 2:修复 PIDFile 路径拼接(通常格式是 hostname:display.pid)
|
||
PIDFile=/home/$username/.vnc/%H:$DISPLAY_NUM.pid
|
||
|
||
ExecStop=/bin/sh -c '/usr/bin/vncserver -kill :$DISPLAY_NUM > /dev/null 2>&1 || :'
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
EOF
|
||
|
||
# 步骤 D: 启用并启动服务
|
||
# 重新加载 systemd 守护进程以识别新文件
|
||
systemctl daemon-reload
|
||
|
||
# 设置开机自启并立即启动服务
|
||
if systemctl enable --now "vnc-${username}.service" &>/dev/null; then
|
||
echo " -> 🎯 用户 $username 部署完毕!已开启自启。请使用 <服务器IP>:$CURRENT_PORT 连接。"
|
||
else
|
||
echo " -> ❌ 服务启动失败,请检查 systemctl status vnc-${username}.service"
|
||
fi
|
||
|
||
echo "----------------------------------------"
|
||
|
||
# 显示编号递增,为下一个用户准备
|
||
((DISPLAY_NUM++))
|
||
|
||
done < "$USER_FILE"
|
||
|
||
echo "🎉 所有账号创建与 VNC 开机自启服务配置已完成!" |