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:
Maple
2026-07-08 13:12:28 +08:00
parent 107cc85507
commit 0b0b20ed5e
22 changed files with 191 additions and 99 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 "开始一键配置"

View File

@@ -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

View File

@@ -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
}
# 切换默认启动内核

View File

@@ -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

View File

@@ -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 配置已恢复"

View File

@@ -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 (核显)

View File

@@ -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 数量配置完成"
# 完成提示

View File

@@ -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
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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