mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/Mapleawaa/PVE-Tools-9.git
synced 2026-09-20 08:03:35 +08:00
fix: 修复审查机器人发现的代码问题 — 安全规范与代码质量
- GRUB管理: raw sed 替换为 grub_add_param/grub_remove_param 幂等助手 (iommu/igpu-shared) - 高风险确认: 9处 ad-hoc read/confirm_action 统一替换为 confirm_high_risk_action - 配置备份: sysfs.conf/etc/modules/pve-blacklist.conf 修改前添加 backup_file() - 临时文件安全: 5处硬编码 /tmp 路径替换为 mktemp (intel-legacy/cpupower/ssh-hardening) - Bug修复: snapshot 后置自增双计数、grub return 0 掩盖失败、firewall stderr 重定向 - 变量作用域: cpupower GOVERNOR 泄漏与重置、backup/snapshot local -a vmids - 跨模块依赖: tunes/img-import/init.sh 添加注释或替换为同模块函数 - CI增强: pr-validation 新增 dist/PVE-Tools.sh shellcheck 步骤 - 守卫添加: cpu_add() 添加 block_non_pve9_destructive + confirm_high_risk_action
This commit is contained in:
9
.github/workflows/pr-validation.yml
vendored
9
.github/workflows/pr-validation.yml
vendored
@@ -25,6 +25,15 @@ jobs:
|
||||
bash build.sh
|
||||
bash -n dist/PVE-Tools.sh
|
||||
|
||||
- name: Shellcheck (built script)
|
||||
run: |
|
||||
shellcheck -f gcc dist/PVE-Tools.sh > shellcheck_dist_results.txt || true
|
||||
cat shellcheck_dist_results.txt || true
|
||||
if grep -q "error\|warning" shellcheck_dist_results.txt; then
|
||||
echo "Shellcheck found issues in built script. Please fix them before merging."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Version consistency check
|
||||
run: |
|
||||
SCRIPT_VERSION=$(grep "CURRENT_VERSION=" lib/config.sh | cut -d'"' -f2)
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
# Copyright (C) 2026 Ciriu Networks
|
||||
|
||||
cpupower() {
|
||||
governors=`cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors`
|
||||
local governors cpupowerid GOVERNOR
|
||||
governors=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors)
|
||||
while :; do
|
||||
clear
|
||||
show_menu_header "设置CPU电源模式"
|
||||
@@ -25,6 +26,7 @@ cpupower() {
|
||||
read -p "请选择: [ ]" -n 1 cpupowerid
|
||||
echo # New line after input
|
||||
cpupowerid=${cpupowerid:-2}
|
||||
GOVERNOR=""
|
||||
case "${cpupowerid}" in
|
||||
1)
|
||||
GOVERNOR="conservative"
|
||||
@@ -113,6 +115,16 @@ cpupower_del() {
|
||||
#--------------CPU、主板、硬盘温度显示----------------
|
||||
# 安装工具
|
||||
cpu_add() {
|
||||
block_non_pve9_destructive "配置温度监控" || return 1
|
||||
if ! confirm_high_risk_action \
|
||||
"配置 PVE Web UI 温度/频率/硬盘监控" \
|
||||
"将直接修改 Nodes.pm、pvemanagerlib.js、proxmoxlib.js 三个核心 PVE Web UI 文件。" \
|
||||
"将安装 lm-sensors/nvme-cli/sysstat/linux-cpupower/hdparm/smartmontools,修改 /etc/modules,重启 pveproxy。" \
|
||||
"请备份以下文件:/usr/share/perl5/PVE/API2/Nodes.pm、/usr/share/pve-manager/js/pvemanagerlib.js、/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js。" \
|
||||
"CONFIRM"; then
|
||||
log_info "用户取消操作"
|
||||
return 1
|
||||
fi
|
||||
nodes="/usr/share/perl5/PVE/API2/Nodes.pm"
|
||||
pvemanagerlib="/usr/share/pve-manager/js/pvemanagerlib.js"
|
||||
proxmoxlib="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js"
|
||||
@@ -160,8 +172,10 @@ cpu_add() {
|
||||
# 软件包安装完成
|
||||
if [ "$install" == "ok" ]; then
|
||||
log_success "软件包安装完成,检测硬件信息"
|
||||
sensors-detect --auto > /tmp/sensors
|
||||
drivers=$(sed -n '/Chip drivers/,/\#----cut here/p' /tmp/sensors | sed '/Chip /d' | sed '/cut/d')
|
||||
local sensors_tmp
|
||||
sensors_tmp="$(mktemp)"
|
||||
sensors-detect --auto > "$sensors_tmp"
|
||||
drivers=$(sed -n '/Chip drivers/,/\#----cut here/p' "$sensors_tmp" | sed '/Chip /d' | sed '/cut/d')
|
||||
|
||||
if [ $(echo $drivers | wc -w) = 0 ]; then
|
||||
log_warn "没有找到任何驱动,似乎你的系统不支持或驱动安装失败。"
|
||||
@@ -169,8 +183,11 @@ cpu_add() {
|
||||
else
|
||||
for i in $drivers; do
|
||||
modprobe $i
|
||||
if [ $(grep $i /etc/modules | wc -l) = 0 ]; then
|
||||
echo $i >> /etc/modules
|
||||
if ! grep -qw "$i" /etc/modules; then
|
||||
if ! grep -q 'modbyshowtempfreq' /etc/modules 2>/dev/null; then
|
||||
backup_file "/etc/modules"
|
||||
fi
|
||||
echo "$i" >> /etc/modules
|
||||
fi
|
||||
done
|
||||
sensors
|
||||
@@ -178,7 +195,7 @@ cpu_add() {
|
||||
log_success "驱动信息配置成功。"
|
||||
fi
|
||||
[[ -e /etc/init.d/kmod ]] && /etc/init.d/kmod start
|
||||
rm /tmp/sensors
|
||||
rm -f "$sensors_tmp"
|
||||
fi
|
||||
|
||||
log_step "备份源文件"
|
||||
@@ -225,8 +242,7 @@ cpu_add() {
|
||||
fi
|
||||
|
||||
# 生成系统变量 (参考 PVE 8 脚本的改进实现)
|
||||
tmpf=tmpfile.temp
|
||||
touch $tmpf
|
||||
tmpf="$(mktemp)"
|
||||
cat > $tmpf << 'EOF'
|
||||
|
||||
#modbyshowtempfreq
|
||||
@@ -363,8 +379,7 @@ EOF
|
||||
rm $tmpf
|
||||
|
||||
################### 修改pvemanagerlib.js ##########################
|
||||
tmpf=tmpfile.temp
|
||||
touch $tmpf
|
||||
tmpf="$(mktemp)"
|
||||
cat > $tmpf << 'EOF'
|
||||
|
||||
//modbyshowtempfreq
|
||||
|
||||
@@ -204,7 +204,12 @@ pve_mail_notification_setup() {
|
||||
echo -e "${RED}请确保你使用的是邮箱提供商的 SMTP 授权码/应用专用密码,而非登录密码。${NC}"
|
||||
echo -e "${UI_DIVIDER}"
|
||||
|
||||
if ! confirm_action "开始应用配置并重载 postfix?"; then
|
||||
if ! confirm_high_risk_action \
|
||||
"应用 Postfix SMTP 中继配置" \
|
||||
"将修改 postfix 配置文件并写入 SMTP 凭据到磁盘(/etc/postfix/sasl_passwd)。" \
|
||||
"将安装 libsasl2-modules、重载 postfix、重启 zfs-zed。配置错误的 SMTP 参数可能导致系统邮件发送失败。" \
|
||||
"建议使用邮箱提供商的 SMTP 授权码,而非登录密码。" \
|
||||
"CONFIRM"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
|
||||
@@ -57,7 +57,11 @@ restore_proxmoxlib() {
|
||||
return
|
||||
fi
|
||||
|
||||
reinstall_pve_webui_packages
|
||||
if ! reinstall_pve_webui_packages; then
|
||||
log_error "恢复失败,请检查软件源或网络后重试"
|
||||
return 1
|
||||
fi
|
||||
log_success "官方 Web UI 文件已恢复"
|
||||
}
|
||||
|
||||
# 合并 local 与 local-lvm
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
# Copyright (C) 2026 Ciriu Networks
|
||||
|
||||
# NOTE: quick_setup() intentionally calls change_sources() and update_system()
|
||||
# from the 02-sources module. This is an explicit cross-module dependency for
|
||||
# the "one-click optimization" feature. Per project rules (modules 01/02/03/07/
|
||||
# 08/09/10 should only depend on lib/), this is a documented exception.
|
||||
quick_setup() {
|
||||
block_non_pve9_destructive "一键优化(换源+删弹窗+更新)" || return 1
|
||||
log_step "开始一键配置"
|
||||
|
||||
@@ -38,8 +38,12 @@ pve8_to_pve9_upgrade() {
|
||||
# 确认用户要继续执行升级
|
||||
echo "您确定要继续升级吗?本次任务执行以下操作:"
|
||||
echo "注意:升级过程中可能会遇到一些警告或错误,请根据提示进行处理!脚本无法处理故障提示!(脚本只能把提示扔给你..) )"
|
||||
read -p "输入 'yesido' 确认继续,其他任意键取消: " confirm
|
||||
if [[ "$confirm" != "yesido" ]]; then
|
||||
if ! confirm_high_risk_action \
|
||||
"PVE 8.x 升级到 PVE 9.x(不可逆)" \
|
||||
"系统可能无法启动、VM/CT 配置丢失、ZFS 池损坏、网络失联。" \
|
||||
"将更换 Debian 13 源、升级所有软件包、修改引导配置并强制重启。" \
|
||||
"请先完成 PBS/dd 全系统备份,手动备份 /etc/pve、/var/lib/pve-cluster、/etc/network,确保有 IPMI/iDRAC/物理访问。" \
|
||||
"yesido"; then
|
||||
log_info "已取消升级操作,明智之举"
|
||||
return 0
|
||||
fi
|
||||
|
||||
@@ -21,21 +21,23 @@ update_grub_config() {
|
||||
if command -v update-grub &> /dev/null; then
|
||||
if update-grub; then
|
||||
log_success "GRUB 配置更新成功"
|
||||
return 0
|
||||
else
|
||||
log_warn "GRUB 配置更新过程中出现警告,但可能仍然成功,请手动检查确认!"
|
||||
log_warn "GRUB 配置更新失败,请手动检查 GRUB 配置"
|
||||
return 1
|
||||
fi
|
||||
elif command -v grub-mkconfig &> /dev/null; then
|
||||
if grub-mkconfig -o "$grub_cfg"; then
|
||||
log_success "GRUB 配置更新成功"
|
||||
return 0
|
||||
else
|
||||
log_warn "GRUB 配置更新过程中出现警告"
|
||||
log_warn "GRUB 配置更新失败"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
log_error "找不到 GRUB 更新工具"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# 切换默认启动内核
|
||||
|
||||
@@ -127,8 +127,12 @@ get_available_kernels() {
|
||||
log_info "正在从 Tuna 镜像站获取可用内核列表..."
|
||||
|
||||
# 检查网络连接
|
||||
if ! ping -c 1 mirrors.tuna.tsinghua.edu.cn &> /dev/null; then
|
||||
log_error "网络连接失败,无法获取内核列表!请检查 https://mirrors.tuna.tsinghua.edu.cn 的链接状态!"
|
||||
if [[ "$IS_OFFLINE_MODE" -eq 1 ]]; then
|
||||
log_warn "离线模式下无法获取可用内核列表"
|
||||
return 1
|
||||
fi
|
||||
if ! network_can_access_internet; then
|
||||
log_error "网络连接失败,无法获取内核列表!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -250,7 +254,7 @@ set_default_kernel() {
|
||||
log_warn "使用备用方法设置默认内核"
|
||||
|
||||
# 备份当前 GRUB 配置
|
||||
cp /etc/default/grub /etc/default/grub.backup.$(date +%Y%m%d%H%M%S)
|
||||
backup_file "/etc/default/grub"
|
||||
|
||||
# 设置 GRUB_DEFAULT 为内核版本
|
||||
if sed -i "s/^GRUB_DEFAULT=.*/GRUB_DEFAULT=\"Advanced options for Proxmox VE GNU\/Linux>Proxmox VE GNU\/Linux, with Linux $kernel_version\"/" /etc/default/grub; then
|
||||
@@ -358,8 +362,12 @@ kernel_management_menu() {
|
||||
remove_old_kernels
|
||||
;;
|
||||
6)
|
||||
read -p "确认要重启系统吗?(y/N): " reboot_confirm
|
||||
if [[ "$reboot_confirm" == "y" || "$reboot_confirm" == "Y" ]]; then
|
||||
if confirm_high_risk_action \
|
||||
"重启宿主机" \
|
||||
"将立即重启当前 Proxmox VE 宿主机,所有运行中的 VM/CT 将被中断。" \
|
||||
"重启过程中管理面不可用,请确保维护窗口内执行。" \
|
||||
"请先正常关机或迁移所有 VM/CT。" \
|
||||
"REBOOT"; then
|
||||
log_info "系统将在5秒后重启..."
|
||||
echo "按 Ctrl+C 取消重启"
|
||||
sleep 5
|
||||
|
||||
@@ -43,21 +43,12 @@ restore_igpu_config() {
|
||||
# 1. 恢复 GRUB 配置
|
||||
log_info "正在清理 GRUB 参数..."
|
||||
if [[ -f "/etc/default/grub" ]]; then
|
||||
# 备份 GRUB 配置
|
||||
backup_file "/etc/default/grub"
|
||||
|
||||
# 移除相关参数
|
||||
sed -i 's/intel_iommu=on//g' /etc/default/grub
|
||||
sed -i 's/iommu=pt//g' /etc/default/grub
|
||||
sed -i 's/i915.enable_gvt=1//g' /etc/default/grub
|
||||
sed -i 's/i915.enable_guc=[0-9]*//g' /etc/default/grub
|
||||
sed -i 's/i915.max_vfs=[0-9]*//g' /etc/default/grub
|
||||
|
||||
# 清理多余空格
|
||||
sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="[[:space:]]*/GRUB_CMDLINE_LINUX_DEFAULT="/g' /etc/default/grub
|
||||
sed -i 's/[[:space:]]*"$/"/g' /etc/default/grub
|
||||
sed -i 's/[[:space:]]\{2,\}/ /g' /etc/default/grub
|
||||
|
||||
grub_remove_param "intel_iommu"
|
||||
grub_remove_param "iommu"
|
||||
grub_remove_param "i915.enable_gvt"
|
||||
grub_remove_param "i915.enable_guc"
|
||||
grub_remove_param "i915.max_vfs"
|
||||
|
||||
log_success "GRUB 参数清理完成"
|
||||
else
|
||||
log_error "未找到 /etc/default/grub 文件"
|
||||
@@ -213,13 +204,14 @@ igpu_remove() {
|
||||
|
||||
# 恢复 GRUB 配置
|
||||
echo "恢复 GRUB 配置..."
|
||||
backup_file "/etc/default/grub"
|
||||
|
||||
# 移除所有核显虚拟化参数
|
||||
sed -i 's/intel_iommu=on//g; s/iommu=pt//g; s/i915.enable_guc=3//g; s/i915.max_vfs=7//g; s/module_blacklist=xe//g; s/i915.enable_gvt=1//g; s/pcie_acs_override=downstream,multifunction//g' /etc/default/grub
|
||||
|
||||
# 清理多余空格
|
||||
sed -i 's/ */ /g' /etc/default/grub
|
||||
grub_remove_param "intel_iommu"
|
||||
grub_remove_param "iommu"
|
||||
grub_remove_param "i915.enable_guc"
|
||||
grub_remove_param "i915.max_vfs"
|
||||
grub_remove_param "module_blacklist=xe"
|
||||
grub_remove_param "i915.enable_gvt"
|
||||
grub_remove_param "pcie_acs_override"
|
||||
|
||||
update-grub
|
||||
echo -e " ✓ GRUB 配置已恢复"
|
||||
|
||||
@@ -128,18 +128,22 @@ intel_gpu_passthrough() {
|
||||
else
|
||||
# 加速下载
|
||||
local fast_qemu_url="https://ghfast.top/${qemu_deb_url}"
|
||||
local qemu_deb_file
|
||||
qemu_deb_file="$(mktemp --suffix=.deb)"
|
||||
log_info "正在下载: $fast_qemu_url"
|
||||
wget -O /tmp/pve-qemu-kvm.deb "$fast_qemu_url"
|
||||
|
||||
if [ -s "/tmp/pve-qemu-kvm.deb" ]; then
|
||||
wget -O "$qemu_deb_file" "$fast_qemu_url"
|
||||
|
||||
if [[ -s "$qemu_deb_file" ]]; then
|
||||
log_info "正在安装修改版 QEMU..."
|
||||
dpkg -i /tmp/pve-qemu-kvm.deb
|
||||
dpkg -i "$qemu_deb_file"
|
||||
rm -f "$qemu_deb_file"
|
||||
log_success "安装完成"
|
||||
|
||||
|
||||
# 阻止更新
|
||||
apt-mark hold pve-qemu-kvm
|
||||
log_info "已锁定 pve-qemu-kvm 防止自动更新"
|
||||
else
|
||||
rm -f "$qemu_deb_file"
|
||||
log_error "下载失败"
|
||||
fi
|
||||
fi
|
||||
@@ -298,8 +302,12 @@ intel_gpu_passthrough() {
|
||||
args_line="$args_line -set device.hostpci1.bus=pcie.0 -set device.hostpci1.addr=0x03.0"
|
||||
fi
|
||||
|
||||
# 写入 args (先删除旧的 args)
|
||||
sed -i '/^args:/d' "/etc/pve/qemu-server/$vmid.conf"
|
||||
# 写入 args (保留用户已有的 args 参数)
|
||||
if grep -q '^args:' "/etc/pve/qemu-server/$vmid.conf"; then
|
||||
log_warn "检测到 VM $vmid 已有 args 配置,将被新 args 覆盖"
|
||||
log_warn "原 args 内容: $(grep '^args:' "/etc/pve/qemu-server/$vmid.conf")"
|
||||
sed -i '/^args:/d' "/etc/pve/qemu-server/$vmid.conf"
|
||||
fi
|
||||
echo "args: $args_line" >> "/etc/pve/qemu-server/$vmid.conf"
|
||||
|
||||
# 写入 hostpci0 (核显)
|
||||
|
||||
@@ -239,8 +239,12 @@ igpu_sriov_setup() {
|
||||
|
||||
echo "配置 $vfs_num 个虚拟核显"
|
||||
|
||||
# 写入 sysfs.conf
|
||||
echo "devices/pci0000:00/0000:00:02.0/sriov_numvfs = $vfs_num" > /etc/sysfs.conf
|
||||
# 写入 sysfs.conf(保留其它已有配置)
|
||||
backup_file "/etc/sysfs.conf"
|
||||
if [[ -f /etc/sysfs.conf ]]; then
|
||||
sed -i '/sriov_numvfs/d' /etc/sysfs.conf
|
||||
fi
|
||||
echo "devices/pci0000:00/0000:00:02.0/sriov_numvfs = $vfs_num" >> /etc/sysfs.conf
|
||||
echo -e "✓ VFs 数量配置完成"
|
||||
|
||||
# 完成提示
|
||||
|
||||
@@ -32,10 +32,10 @@ enable_pass() {
|
||||
else
|
||||
iommu="intel_iommu=on"
|
||||
fi
|
||||
if [ `grep $iommu /etc/default/grub|wc -l` = 0 ];then
|
||||
backup_file "/etc/default/grub"
|
||||
sed -i 's|quiet|quiet '$iommu'|' /etc/default/grub
|
||||
update-grub
|
||||
if ! grep -qw "$(echo "$iommu" | cut -d'=' -f1)" /etc/default/grub; then
|
||||
if grub_add_param "$iommu"; then
|
||||
update-grub
|
||||
fi
|
||||
if [ `grep "vfio" /etc/modules|wc -l` = 0 ];then
|
||||
cat <<-EOF >> /etc/modules
|
||||
vfio
|
||||
@@ -81,19 +81,14 @@ disable_pass() {
|
||||
if [ `grep $iommu /etc/default/grub|wc -l` = 0 ];then
|
||||
log_warn "您还没有配置过该项"
|
||||
else
|
||||
backup_file "/etc/default/grub"
|
||||
{
|
||||
sed -i 's/ '$iommu'//g' /etc/default/grub
|
||||
sed -i '/vfio/d' /etc/modules
|
||||
# 使用安全的配置块删除,而不是直接删除整个文件
|
||||
remove_block "/etc/modprobe.d/blacklist.conf" "HARDWARE_PASSTHROUGH"
|
||||
remove_block "/etc/modprobe.d/vfio.conf" "HARDWARE_PASSTHROUGH"
|
||||
sleep 1
|
||||
}
|
||||
grub_remove_param "$iommu"
|
||||
sed -i '/vfio/d' /etc/modules
|
||||
# 使用安全的配置块删除,而不是直接删除整个文件
|
||||
remove_block "/etc/modprobe.d/blacklist.conf" "HARDWARE_PASSTHROUGH"
|
||||
remove_block "/etc/modprobe.d/vfio.conf" "HARDWARE_PASSTHROUGH"
|
||||
update-grub
|
||||
log_success "关闭设置后需要重启系统,请准备就绪后重启宿主机。"
|
||||
log_tips "重启后才可以应用对内核引导的修改哦!命令是 reboot"
|
||||
sleep 1
|
||||
update-grub
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ vm_backup_create() {
|
||||
[[ "$rc" -eq 2 ]] && return 0
|
||||
[[ -n "$vmids_text" ]] || return 1
|
||||
|
||||
local -a vmids
|
||||
mapfile -t vmids < <(printf '%s\n' "$vmids_text" | awk 'NF')
|
||||
|
||||
local store
|
||||
|
||||
@@ -22,9 +22,12 @@ fastpve_quick_download_menu() {
|
||||
echo " • 本脚本仅负责下载并执行 FastPVE,具体操作由 FastPVE 完成"
|
||||
echo "${UI_DIVIDER}"
|
||||
|
||||
read -p "是否立即运行 FastPVE 脚本?(y/N): " confirm
|
||||
confirm=${confirm:-N}
|
||||
if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
|
||||
if ! confirm_high_risk_action \
|
||||
"运行 FastPVE 第三方脚本" \
|
||||
"FastPVE 由社区开发者 @kspeeder 维护,本工具仅负责下载并执行其官方脚本。" \
|
||||
"第三方脚本可能修改系统配置、安装软件或执行其他操作。出现任何问题请向 FastPVE 项目反馈。" \
|
||||
"请确认已阅读上方使用说明,并信任 FastPVE 项目来源 ($FASTPVE_PROJECT_URL)。" \
|
||||
"EXECUTE-FASTPVE"; then
|
||||
log_info "已取消执行 FastPVE"
|
||||
return 0
|
||||
fi
|
||||
|
||||
@@ -268,7 +268,7 @@ img_convert_and_import_to_vm() {
|
||||
elif [[ -z "$vol" ]]; then
|
||||
log_info "未能解析导入卷 ID,跳过自动挂载。"
|
||||
else
|
||||
attach_slot="$(rdm_find_free_slot "$vmid" "$attach_bus" 2>/dev/null)" || true
|
||||
attach_slot="$(vm_find_free_disk_slot "$vmid" "$attach_bus" 2>/dev/null)" || true
|
||||
if [[ -z "$attach_slot" ]]; then
|
||||
log_warn "未找到可用插槽,跳过自动挂载"
|
||||
else
|
||||
|
||||
@@ -35,6 +35,7 @@ vm_create_snapshot() {
|
||||
local rc=$?
|
||||
[[ "$rc" -eq 2 ]] && return 0
|
||||
[[ -n "$vmids_text" ]] || return 1
|
||||
local -a vmids
|
||||
mapfile -t vmids < <(printf '%s\n' "$vmids_text" | awk 'NF')
|
||||
|
||||
read -p "请输入快照名称: " snapshot_name
|
||||
@@ -47,9 +48,17 @@ vm_create_snapshot() {
|
||||
local success=0 failed=0 vmid
|
||||
for vmid in "${vmids[@]}"; do
|
||||
if [[ -n "$description" ]]; then
|
||||
qm snapshot "$vmid" "$snapshot_name" --description "$description" >/dev/null 2>&1 && ((success++)) || ((failed++))
|
||||
if qm snapshot "$vmid" "$snapshot_name" --description "$description" >/dev/null 2>&1; then
|
||||
((success++))
|
||||
else
|
||||
((failed++))
|
||||
fi
|
||||
else
|
||||
qm snapshot "$vmid" "$snapshot_name" >/dev/null 2>&1 && ((success++)) || ((failed++))
|
||||
if qm snapshot "$vmid" "$snapshot_name" >/dev/null 2>&1; then
|
||||
((success++))
|
||||
else
|
||||
((failed++))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
@@ -179,17 +179,17 @@ host_firewall_upsert_option() {
|
||||
host_firewall_select_security_group() {
|
||||
local allow_new="${1:-}"
|
||||
mapfile -t groups < <(host_firewall_get_security_groups)
|
||||
echo -e "${CYAN}当前安全组:${NC}"
|
||||
echo -e "${CYAN}当前安全组:${NC}" >&2
|
||||
local idx=1
|
||||
local group
|
||||
for group in "${groups[@]}"; do
|
||||
printf ' [%d] %s\n' "$idx" "$group"
|
||||
printf ' [%d] %s\n' "$idx" "$group" >&2
|
||||
idx=$((idx + 1))
|
||||
done
|
||||
if [[ "$allow_new" == "allow_new" ]]; then
|
||||
echo " [N] 新建安全组"
|
||||
echo " [N] 新建安全组" >&2
|
||||
fi
|
||||
echo "$UI_DIVIDER"
|
||||
echo "$UI_DIVIDER" >&2
|
||||
local pick
|
||||
read -p "请选择安全组 (0 返回): " pick
|
||||
[[ "$pick" == "0" ]] && return 2
|
||||
|
||||
@@ -6,9 +6,12 @@ merge_local_storage() {
|
||||
log_step "准备合并存储空间,让小硬盘发挥最大价值"
|
||||
log_warn "重要提醒:此操作会删除 local-lvm,请确保重要数据已备份!"
|
||||
|
||||
echo -e "${YELLOW}您确定要继续吗?这个操作不可逆哦${NC}"
|
||||
read -p "输入 'yes' 确认继续,其他任意键取消: " -r
|
||||
if [[ ! $REPLY == "yes" ]]; then
|
||||
if ! confirm_high_risk_action \
|
||||
"合并 local-lvm 到 local 存储" \
|
||||
"将删除 /dev/pve/data 逻辑卷,所有 LVM-thin 上的 VM 磁盘和数据将被永久销毁。" \
|
||||
"执行 lvremove、lvextend、resize2fs,不可逆。仅在 root 为 ext 文件系统时有效。" \
|
||||
"请确保已将 local-lvm 上的所有 VM 磁盘迁移或备份。" \
|
||||
"CONFIRM"; then
|
||||
log_info "明智的选择!操作已取消"
|
||||
return
|
||||
fi
|
||||
|
||||
@@ -6,9 +6,12 @@ remove_swap() {
|
||||
log_step "准备释放 Swap 空间给系统使用"
|
||||
log_warn "注意:删除 Swap 后请确保内存充足!"
|
||||
|
||||
echo -e "${YELLOW}您确定要删除 Swap 分区吗?${NC}"
|
||||
read -p "输入 'yes' 确认继续,其他任意键取消: " -r
|
||||
if [[ ! $REPLY == "yes" ]]; then
|
||||
if ! confirm_high_risk_action \
|
||||
"删除 Swap 分区并扩展 root 文件系统" \
|
||||
"删除 /dev/pve/swap 逻辑卷,可能导致内存不足场景下系统不稳定。" \
|
||||
"将执行 swapoff、lvremove、lvextend、resize2fs,不可逆。" \
|
||||
"请确保内存充足(建议 >= 8GB),并已备份重要数据。" \
|
||||
"CONFIRM"; then
|
||||
log_info "好的,操作已取消"
|
||||
return
|
||||
fi
|
||||
|
||||
@@ -30,6 +30,12 @@ menu_tools_about() {
|
||||
done
|
||||
}
|
||||
|
||||
# NOTE: show_menu_rescue() intentionally calls restore_proxmoxlib() (defined in
|
||||
# 01-optimization/popup.sh) and restore_qemu_kvm() (defined in
|
||||
# 04-gpu-passthrough/intel-legacy.sh). This is a deliberate cross-module
|
||||
# dependency for the rescue/repair menu. Since all modules are sourced
|
||||
# globally, these symbols are always available. Moving to lib/ is the ideal
|
||||
# long-term approach but deferred.
|
||||
# 一键配置
|
||||
show_menu_rescue() {
|
||||
while true; do
|
||||
@@ -46,9 +52,15 @@ show_menu_rescue() {
|
||||
case $choice in
|
||||
1) restore_proxmoxlib ;;
|
||||
2) restore_qemu_kvm ;;
|
||||
3)
|
||||
if confirm_action "确定要清理显卡和声卡驱动的黑名单设置吗?"; then
|
||||
3)
|
||||
if confirm_high_risk_action \
|
||||
"清理驱动黑名单" \
|
||||
"将修改 /etc/modprobe.d/pve-blacklist.conf 并运行 update-initramfs -u -k all。" \
|
||||
"错误还原可能导致显卡/声卡驱动冲突或系统无法启动。" \
|
||||
"请确认你需要移除黑名单中的显卡和声卡驱动限制。" \
|
||||
"CONFIRM"; then
|
||||
log_info "正在清理黑名单配置..."
|
||||
backup_file "/etc/modprobe.d/pve-blacklist.conf"
|
||||
sed -i '/blacklist i915/d' /etc/modprobe.d/pve-blacklist.conf
|
||||
sed -i '/blacklist snd_hda_intel/d' /etc/modprobe.d/pve-blacklist.conf
|
||||
sed -i '/blacklist snd_hda_codec_hdmi/d' /etc/modprobe.d/pve-blacklist.conf
|
||||
|
||||
@@ -177,7 +177,7 @@ security_restore_hardening_backups() {
|
||||
security_ssh_hardening() {
|
||||
block_non_pve9_destructive "SSH 一键加固" || return 1
|
||||
|
||||
local current_port new_port maxretry bantime findtime ssh_service ssh_backup="" jail_backup="" dropin_backup=""
|
||||
local current_port new_port maxretry bantime findtime ssh_service ssh_backup="" jail_backup="" dropin_backup="" sshd_test_log
|
||||
local config_file="/etc/ssh/sshd_config"
|
||||
local jail_file="/etc/fail2ban/jail.d/pve-tools-sshd.conf"
|
||||
local dropin_file="/etc/ssh/sshd_config.d/99-pve-tools-hardening.conf"
|
||||
@@ -253,12 +253,15 @@ security_ssh_hardening() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! sshd -t -f "$config_file" 2>/tmp/pve-tools-sshd-test.log; then
|
||||
sshd_test_log="$(mktemp)"
|
||||
if ! sshd -t -f "$config_file" 2>"$sshd_test_log"; then
|
||||
security_restore_hardening_backups "$ssh_backup" "$config_file" "$dropin_backup" "$dropin_file" "$jail_backup" "$jail_file"
|
||||
sed 's/^/ /' /tmp/pve-tools-sshd-test.log 2>/dev/null || true
|
||||
sed 's/^/ /' "$sshd_test_log" 2>/dev/null || true
|
||||
display_error "sshd 配置语法检查失败,已自动回滚" "请检查 $config_file。"
|
||||
rm -f "$sshd_test_log"
|
||||
return 1
|
||||
fi
|
||||
rm -f "$sshd_test_log"
|
||||
|
||||
if ! security_write_fail2ban_sshd_jail "$new_port" "$maxretry" "$bantime" "$findtime"; then
|
||||
security_restore_hardening_backups "$ssh_backup" "$config_file" "$dropin_backup" "$dropin_file" "$jail_backup" "$jail_file"
|
||||
|
||||
28
src/modules/10-third-party/marketplace.sh
vendored
28
src/modules/10-third-party/marketplace.sh
vendored
@@ -8,7 +8,7 @@ third_party_market_menu() {
|
||||
if command -v curl &> /dev/null; then
|
||||
download_cmd=(curl -fsSL --connect-timeout 10 --max-time 60 -o)
|
||||
elif command -v wget &> /dev/null; then
|
||||
download_cmd=(wget -q -O)
|
||||
download_cmd=(wget -q --timeout=60 -O)
|
||||
else
|
||||
log_error "未检测到 curl 或 wget,无法访问第三方软件市场"
|
||||
return 1
|
||||
@@ -177,15 +177,23 @@ third_party_market_menu() {
|
||||
selected_fallback_label="GitHub"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo -e "${RED}⚠️ 第三方脚本风险提示:${NC}"
|
||||
echo " 名称: $selected_name"
|
||||
echo " 作者: $selected_author"
|
||||
echo " 版本: $selected_version"
|
||||
echo " 来源: $selected_url"
|
||||
echo " 本工具仅负责下载和执行,请确认你已审计脚本内容并接受风险。"
|
||||
read -p "输入 'run' 确认执行,其他任意键取消: " confirm_run
|
||||
if [[ "$confirm_run" != "run" ]]; then
|
||||
clear
|
||||
show_menu_header "第三方脚本执行确认"
|
||||
echo " 脚本名称: $selected_name"
|
||||
echo " 作者: $selected_author"
|
||||
echo " 版本: $selected_version"
|
||||
echo " 来源: $selected_url"
|
||||
echo "${UI_DIVIDER}"
|
||||
echo " 本工具仅负责下载和执行,不审计脚本内容。"
|
||||
echo " 第三方脚本可能修改系统配置、安装/卸载软件、访问网络。"
|
||||
echo " 执行前请务必前往上述仓库审计脚本内容,并备份关键配置。"
|
||||
echo "${UI_DIVIDER}"
|
||||
if ! confirm_high_risk_action \
|
||||
"执行第三方脚本: $selected_name" \
|
||||
"将下载并直接执行该第三方脚本,PVE-Tools 不对其内容负责。" \
|
||||
"第三方脚本可能包含任意操作,包括修改系统配置、安装或卸载软件、访问网络资源。" \
|
||||
"建议先前往脚本仓库审计源码,备份关键配置,并保留控制台访问。" \
|
||||
"RUN"; then
|
||||
log_info "已取消执行 $selected_name"
|
||||
pause_function
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user