将 Debian 12 转换为 Proxmox VE

一、准备工作

确保系统是纯净的 Debian 12

最好是全新安装的系统

确保网络连接正常

1.更新系统

apt update && apt upgrade -y

写入主机名

虽然您可以保留将127.0.1.1环回地址映射到主机名的条目,但由于Proxmox VE的集群系统循环遍历所有地址,直到找到一个非环回地址为止,如果不确定,建议从该记录中删除主机名,因为这样可以避免任何歧义。

例如,如果你的IP地址是192.168.15.77,主机名是sgpo01,那么你的/etc/hosts文件可能看起来像:

127.0.0.1       localhost
192.168.15.77   sgpo01.fortu.cfd sgpo01

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

你可以使用hostname命令来测试你的设置是否正确:

hostname --ip-address
192.168.15.77 # 应该返回至少一个非环回IP地址在这里

固化hostname

echo "sgpo01" > /etc/hostname

生效

hostnamectl set-hostname sgpo01.fortu.cfd

验证

hostname --ip-address
192.168.15.77 # should return at least one non-loopback IP address here
reboot

2.安装 Proxmox VE

添加 Proxmox VE 存储库

echo "deb [arch=amd64] http://download.proxmox.com/debian/pve bookworm pve-no-subscription" > /etc/apt/sources.list.d/pve-install-repo.list

添加 Proxmox VE 存储库密钥

wget https://enterprise.proxmox.com/debian/proxmox-release-bookworm.gpg -O /etc/apt/trusted.gpg.d/proxmox-release-bookworm.gpg

# verify
sha512sum /etc/apt/trusted.gpg.d/proxmox-release-bookworm.gpg 
7da6fe34168adc6e479327ba517796d4702fa2f8b4f0a9833f5ea6e6b48f6507a6da403a274fe201595edc86a84463d50383d07f64bdde2e3658108db7d6dc87  /etc/apt/trusted.gpg.d/proxmox-release-bookworm.gpg

更新包列表

apt update && apt full-upgrade

安装内核

apt install proxmox-default-kernel
systemctl reboot

安装 Proxmox VE

apt install proxmox-ve postfix open-iscsi chrony

设置密码并且重启系统

passwd && sync && reboot

访问 Web 界面

重启后,你可以通过浏览器访问 Proxmox VE 的 Web 管理界面:
第一次需要用ip地址登录不知道原因

  • 地址:https://sgpo01.fortu.cfd:8006
  • 用户名:root
  • 密码:你的 root 密码

创建系统模版

# 在 Proxmox 服务器上检查可用的容器模板
pveam update
pveam available

# 查看已下载的模板
ls -la /var/lib/vz/template/cache/

# 下载一些常用模板(如果没有)
pveam download local ubuntu-24.10-standard_24.10-1_amd64.tar.zst
pveam download local debian-13-standard_13.1-1_amd64.tar.zst

后续配置

移除 Debian 内核(可选) 安装完成后,你可以移除原来的 Debian 内核:

apt remove linux-image-amd64 'linux-image-6.1*'
update-grub

删除 os-prober

apt remove os-prober

移除企业版存储库警告(可选) 如果你使用的是免费版本,可以禁用企业版存储库:

echo '#deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise' > /etc/apt/sources.list.d/pve-enterprise.list

验证和创建必要的目录结构

# 如果 /etc/pve 现在已挂载但缺少 local 目录
if [ -d "/etc/pve" ] && [ ! -d "/etc/pve/local" ]; then
    echo "创建 local 目录..."
    mkdir -p /etc/pve/local
fi

# 检查是否成功创建
ls -la /etc/pve/

重新初始化单节点集群

# 如果 /etc/pve 现在正常工作
pvecm expected 1

# 启动其他服务
systemctl start pvedaemon
systemctl start pveproxy

# 检查所有服务状态
systemctl status pve-cluster pvedaemon pveproxy

生成 SSL 证书

# 现在 /etc/pve/local 应该存在,生成 SSL 证书
if [ -d "/etc/pve/local" ]; then
    echo "生成 SSL 证书..."
    HOSTNAME=$(hostname -f)
    
    # 生成私钥
    openssl genrsa -out /etc/pve/local/pve-ssl.key 4096
    
    # 生成自签名证书
    openssl req -new -x509 -key /etc/pve/local/pve-ssl.key -out /etc/pve/local/pve-ssl.pem -days 3650 -subj "/CN=$HOSTNAME"
    
    # 设置权限
    chown root:www-data /etc/pve/local/pve-ssl.key /etc/pve/local/pve-ssl.pem
    chmod 640 /etc/pve/local/pve-ssl.key
    chmod 644 /etc/pve/local/pve-ssl.pem
    
    echo "SSL 证书已生成"
    ls -la /etc/pve/local/pve-ssl.*
else
    echo "错误:/etc/pve/local 目录仍不存在"
fi

最终验证

# 重启 pveproxy 服务
systemctl restart pveproxy

# 检查服务状态
systemctl status pveproxy

# 检查端口监听
ss -tlnp | grep 8006

# 测试 Web 界面
curl -k https://localhost:8006

WHMCS的配置

PVE端口映射

#!/bin/bash

# PVE兼容的端口映射方案 - 改进版
# 修复了原脚本的问题并增加了更多功能

set -euo pipefail  # 严格错误处理

echo "=== PVE 端口映射配置向导 (改进版) ==="

# 配置变量
INTERNAL_NETWORK="192.168.100"
BASE_PORT=30000
LOG_FILE="/var/log/pve-port-mapping.log"

# 日志函数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

# 错误处理
error_exit() {
    log "错误: $1"
    exit 1
}

# 检查权限
check_permissions() {
    if [[ $EUID -ne 0 ]]; then
        error_exit "需要root权限运行此脚本"
    fi
}

# 检查PVE防火墙状态
check_pve_firewall() {
    log "检查 PVE 防火墙状态..."
    
    if systemctl is-active --quiet pve-firewall 2>/dev/null; then
        log "⚠️  PVE防火墙已启用"
        echo "建议方案:使用PVE防火墙 + 最小化iptables规则"
        return 1
    else
        log "✅ PVE防火墙未启用"
        echo "可以使用完整的iptables方案"
        return 0
    fi
}

# 备份现有iptables规则
backup_iptables() {
    local backup_file="/etc/iptables/rules.backup.$(date +%Y%m%d_%H%M%S)"
    mkdir -p /etc/iptables
    
    log "备份现有iptables规则到: $backup_file"
    iptables-save > "$backup_file" || error_exit "备份iptables规则失败"
}

# 方案1:PVE防火墙 + 最小iptables(推荐)
setup_pve_friendly() {
    log "开始配置方案1:PVE防火墙友好方案"
    
    backup_iptables
    
    # 创建端口映射脚本,不干扰PVE防火墙
    cat > /usr/local/bin/pve-port-mapper << 'EOF'
#!/bin/bash

# 仅创建NAT规则,不干扰PVE防火墙的FILTER规则
INTERNAL_NETWORK="192.168.200"
BASE_PORT=30000
LOG_FILE="/var/log/pve-port-mapping.log"

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

log "开始配置端口映射和安全屏蔽..."

# 开启IP转发
echo 'net.ipv4.ip_forward = 1' > /etc/sysctl.d/99-port-mapping.conf
sysctl -p /etc/sysctl.d/99-port-mapping.conf

# 应用安全屏蔽规则
apply_security_rules() {
    log "应用P2P/BT屏蔽规则..."
    
    # P2P和BT协议屏蔽
    local bt_keywords=(
        "torrent" ".torrent" "peer_id=" "announce" "info_hash" 
        "get_peers" "find_node" "BitTorrent" "announce_peer" 
        "BitTorrent protocol" "announce.php?passkey=" "magnet:" 
        "xunlei" "sandai" "Thunder" "XLLiveUD"
    )
    
    for keyword in "${bt_keywords[@]}"; do
        iptables -A OUTPUT -m string --string "$keyword" --algo bm -j DROP 2>/dev/null || true
        iptables -A FORWARD -m string --string "$keyword" --algo bm -j DROP 2>/dev/null || true
    done
    
    log "应用挖矿池屏蔽规则..."
    
    # 挖矿池屏蔽
    local mining_pools=(
        "ethermine.com" "antpool.one" "antpool.com" "pool.bar" "seed_hash"
    )
    
    for pool in "${mining_pools[@]}"; do
        iptables -A OUTPUT -m string --string "$pool" --algo bm -j DROP 2>/dev/null || true
        iptables -A FORWARD -m string --string "$pool" --algo bm -j DROP 2>/dev/null || true
    done
    
    log "应用测速网站屏蔽规则..."
    
    # 测速网站屏蔽
    local speedtest_sites=(
        ".speed" "speed." ".speed." "fast.com" "speedtest.net" 
        "speedtest.com" "speedtest.cn" "test.ustc.edu.cn" 
        "10000.gd.cn" "db.laomoe.com" "jiyou.cloud" 
        "ovo.speedtestcustom.com" "speed.cloudflare.com" "speedtest"
    )
    
    for site in "${speedtest_sites[@]}"; do
        iptables -A OUTPUT -m string --string "$site" --algo bm -j DROP 2>/dev/null || true
        iptables -A FORWARD -m string --string "$site" --algo bm -j DROP 2>/dev/null || true
    done
    
    log "安全屏蔽规则应用完成"
}

# 应用安全规则
apply_security_rules

# 清空自定义NAT链
iptables -t nat -F PORT_MAPPING 2>/dev/null || true
iptables -t nat -X PORT_MAPPING 2>/dev/null || true

# 创建自定义链
iptables -t nat -N PORT_MAPPING

# 创建端口映射规则
for ip in $(seq 1 254); do
    internal_ip="${INTERNAL_NETWORK}.${ip}"
    base_port=$((BASE_PORT + (ip - 1) * 10))
    
    # SSH 映射: base_port -> IP:22
    iptables -t nat -A PORT_MAPPING -p tcp --dport $base_port \
        -j DNAT --to-destination ${internal_ip}:22
    
    # HTTP 映射: base_port+1 -> IP:80
    iptables -t nat -A PORT_MAPPING -p tcp --dport $((base_port + 1)) \
        -j DNAT --to-destination ${internal_ip}:80
        
    # HTTPS 映射: base_port+2 -> IP:443
    iptables -t nat -A PORT_MAPPING -p tcp --dport $((base_port + 2)) \
        -j DNAT --to-destination ${internal_ip}:443
    
    # RDP 映射: base_port+3 -> IP:3389 (Windows远程桌面)
    iptables -t nat -A PORT_MAPPING -p tcp --dport $((base_port + 3)) \
        -j DNAT --to-destination ${internal_ip}:3389
        
    # VNC 映射: base_port+4 -> IP:5900 (VNC)
    iptables -t nat -A PORT_MAPPING -p tcp --dport $((base_port + 4)) \
        -j DNAT --to-destination ${internal_ip}:5900
done

# 检查PREROUTING链是否已有规则
if ! iptables -t nat -C PREROUTING -j PORT_MAPPING 2>/dev/null; then
    iptables -t nat -I PREROUTING -j PORT_MAPPING
    log "添加PREROUTING规则"
fi

# MASQUERADE规则 - 修复源地址伪装
if ! iptables -t nat -C POSTROUTING -s ${INTERNAL_NETWORK}.0/24 -j MASQUERADE 2>/dev/null; then
    iptables -t nat -A POSTROUTING -s ${INTERNAL_NETWORK}.0/24 -j MASQUERADE
    log "添加MASQUERADE规则"
fi

log "端口映射和安全屏蔽配置完成,与PVE防火墙兼容"
log "端口范围: $BASE_PORT - $((BASE_PORT + 254 * 10 - 1))"
EOF

    chmod +x /usr/local/bin/pve-port-mapper
    
    # 创建系统服务
    cat > /etc/systemd/system/pve-port-mapping.service << 'EOF'
[Unit]
Description=PVE Port Mapping Service
After=network.target pve-firewall.service
Before=pve-guests.service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/pve-port-mapper
ExecStop=/usr/local/bin/pve-port-mapper-stop
RemainAfterExit=yes
TimeoutStartSec=60

[Install]
WantedBy=multi-user.target
EOF

    # 创建停止脚本
    cat > /usr/local/bin/pve-port-mapper-stop << 'EOF'
#!/bin/bash
# 清理端口映射规则和安全屏蔽规则
iptables -t nat -D PREROUTING -j PORT_MAPPING 2>/dev/null || true
iptables -t nat -F PORT_MAPPING 2>/dev/null || true
iptables -t nat -X PORT_MAPPING 2>/dev/null || true

# 清理安全屏蔽规则(注意:这会清理所有包含这些关键词的规则)
echo "清理安全屏蔽规则..."
iptables-save | grep -E "(torrent|BitTorrent|speedtest|ethermine)" | sed 's/-A/-D/' | while read rule; do
    iptables $rule 2>/dev/null || true
done

echo "端口映射和安全规则已清理"
EOF

    chmod +x /usr/local/bin/pve-port-mapper-stop
    
    systemctl daemon-reload
    systemctl enable pve-port-mapping.service
    log "✅ PVE兼容方案配置完成"
}

# 方案2:优化的独立iptables方案  
setup_standalone_iptables() {
    log "开始配置方案2:独立iptables优化方案"
    
    backup_iptables
    
    # 确保PVE防火墙不干扰
    if systemctl is-active --quiet pve-firewall 2>/dev/null; then
        log "停用PVE防火墙以避免冲突"
        systemctl stop pve-firewall
        systemctl disable pve-firewall
    fi
    
    # 安装ipset
    if ! command -v ipset &> /dev/null; then
        log "安装ipset..."
        apt-get update && apt-get install -y ipset || error_exit "无法安装ipset"
    fi
    
    # 创建高效的端口映射
    cat > /usr/local/bin/optimized-port-mapper << 'EOF'
#!/bin/bash

INTERNAL_NETWORK="192.168.200"
BASE_PORT=30000

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}

# 安全屏蔽规则函数
apply_security_blocking() {
    log "配置独立优化方案 + 安全屏蔽..."
    
    # P2P和BT协议屏蔽
    local bt_keywords=(
        "torrent" ".torrent" "peer_id=" "announce" "info_hash" 
        "get_peers" "find_node" "BitTorrent" "announce_peer" 
        "BitTorrent protocol" "announce.php?passkey=" "magnet:" 
        "xunlei" "sandai" "Thunder" "XLLiveUD"
    )
    
    for keyword in "${bt_keywords[@]}"; do
        iptables -A OUTPUT -m string --string "$keyword" --algo bm -j DROP 2>/dev/null || true
        iptables -A FORWARD -m string --string "$keyword" --algo bm -j DROP 2>/dev/null || true
    done
    
    # 挖矿池屏蔽
    local mining_pools=(
        "ethermine.com" "antpool.one" "antpool.com" "pool.bar" "seed_hash"
    )
    
    for pool in "${mining_pools[@]}"; do
        iptables -A OUTPUT -m string --string "$pool" --algo bm -j DROP 2>/dev/null || true
        iptables -A FORWARD -m string --string "$pool" --algo bm -j DROP 2>/dev/null || true
    done
    
    # 测速网站屏蔽
    local speedtest_sites=(
        ".speed" "speed." ".speed." "fast.com" "speedtest.net" 
        "speedtest.com" "speedtest.cn" "test.ustc.edu.cn" 
        "10000.gd.cn" "db.laomoe.com" "jiyou.cloud" 
        "ovo.speedtestcustom.com" "speed.cloudflare.com" "speedtest"
    )
    
    for site in "${speedtest_sites[@]}"; do
        iptables -A OUTPUT -m string --string "$site" --algo bm -j DROP 2>/dev/null || true
        iptables -A FORWARD -m string --string "$site" --algo bm -j DROP 2>/dev/null || true
    done
    
    log "安全屏蔽规则配置完成"
}

log "配置独立优化方案..."

# 应用安全屏蔽
apply_security_blocking

# 开启IP转发
echo 'net.ipv4.ip_forward = 1' > /etc/sysctl.d/99-port-mapping.conf
sysctl -p /etc/sysctl.d/99-port-mapping.conf

# 清理现有规则和ipset
iptables -t nat -F PREROUTING 2>/dev/null || true
iptables -t nat -F POSTROUTING 2>/dev/null || true
iptables -F FORWARD 2>/dev/null || true

# 清理ipset
ipset destroy ssh_mapping 2>/dev/null || true
ipset destroy http_mapping 2>/dev/null || true
ipset destroy https_mapping 2>/dev/null || true

# 创建不同服务的ipset
ipset create ssh_mapping hash:ip,port
ipset create http_mapping hash:ip,port  
ipset create https_mapping hash:ip,port

# 批量添加映射关系
for ip in $(seq 1 254); do
    internal_ip="${INTERNAL_NETWORK}.${ip}"
    base_port=$((BASE_PORT + (ip - 1) * 10))
    
    # SSH映射
    ipset add ssh_mapping ${internal_ip},$base_port
    # HTTP映射
    ipset add http_mapping ${internal_ip},$((base_port + 1))
    # HTTPS映射
    ipset add https_mapping ${internal_ip},$((base_port + 2))
done

# 创建高效的NAT规则
iptables -t nat -A PREROUTING -p tcp -m set --match-set ssh_mapping dst,dst \
    -j DNAT --to-destination \$(echo \$INTERNAL_NETWORK | cut -d. -f1-3).1-254:22

iptables -t nat -A PREROUTING -p tcp -m set --match-set http_mapping dst,dst \
    -j DNAT --to-destination \$(echo \$INTERNAL_NETWORK | cut -d. -f1-3).1-254:80

iptables -t nat -A PREROUTING -p tcp -m set --match-set https_mapping dst,dst \
    -j DNAT --to-destination \$(echo \$INTERNAL_NETWORK | cut -d. -f1-3).1-254:443

# MASQUERADE
iptables -t nat -A POSTROUTING -s ${INTERNAL_NETWORK}.0/24 -j MASQUERADE

# FORWARD规则
iptables -A FORWARD -d ${INTERNAL_NETWORK}.0/24 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -s ${INTERNAL_NETWORK}.0/24 -j ACCEPT

log "高性能独立方案 + 安全屏蔽配置完成"
EOF

    chmod +x /usr/local/bin/optimized-port-mapper
    log "✅ 独立优化方案配置完成"
}

# 显示端口映射规则
show_port_mapping() {
    echo ""
    echo "📋 端口映射规则说明:"
    echo "内网网段: ${INTERNAL_NETWORK}.0/24"
    echo "外部端口范围: ${BASE_PORT} - $((BASE_PORT + 2540 - 1))"
    echo ""
    echo "映射规则 (每台虚拟机占用10个端口):"
    echo "- SSH:   外部端口 = $BASE_PORT + (IP末位-1) * 10"
    echo "- HTTP:  外部端口 = $BASE_PORT + (IP末位-1) * 10 + 1"  
    echo "- HTTPS: 外部端口 = $BASE_PORT + (IP末位-1) * 10 + 2"
    echo "- RDP:   外部端口 = $BASE_PORT + (IP末位-1) * 10 + 3"
    echo "- VNC:   外部端口 = $BASE_PORT + (IP末位-1) * 10 + 4"
    echo ""
    echo "示例:"
    echo "- ${INTERNAL_NETWORK}.10 SSH:  外部端口 $((BASE_PORT + 9 * 10))"
    echo "- ${INTERNAL_NETWORK}.10 HTTP: 外部端口 $((BASE_PORT + 9 * 10 + 1))"
    echo "- ${INTERNAL_NETWORK}.100 SSH: 外部端口 $((BASE_PORT + 99 * 10))"
}

# 主逻辑
main() {
    check_permissions
    
    show_port_mapping
    
    if check_pve_firewall; then
        echo ""
        echo "推荐使用方案1(PVE友好)"
        echo "是否继续配置方案1? (y/n): "
        read -r response
        if [[ "$response" =~ ^[Yy]$ ]]; then
            setup_pve_friendly
            
            echo ""
            echo "是否立即启动端口映射服务? (y/n): "
            read -r start_response
            if [[ "$start_response" =~ ^[Yy]$ ]]; then
                systemctl start pve-port-mapping.service
                log "端口映射服务已启动"
            fi
        fi
    else
        echo ""
        echo "可选择以下方案:"
        echo "1. PVE友好方案(保留PVE防火墙功能)"
        echo "2. 独立优化方案(最高性能)"
        echo "请选择 (1/2): "
        read -r choice
        
        case $choice in
            1) 
                setup_pve_friendly
                systemctl start pve-port-mapping.service 2>/dev/null || true
                ;;
            2) 
                setup_standalone_iptables
                /usr/local/bin/optimized-port-mapper
                ;;
            *) 
                error_exit "无效选择" 
                ;;
        esac
    fi
    
    echo ""
    echo "✅ 配置完成!"
    echo "日志文件: $LOG_FILE"
    echo "可以使用以下命令检查状态:"
    echo "- systemctl status pve-port-mapping.service"
    echo "- iptables -t nat -L -n -v"
}

# 显示重要提示
echo ""
echo "📋 重要说明:"
echo "1. PVE 8+ 支持基于nftables的新防火墙"
echo "2. 如果启用PVE防火墙,建议使用方案1"
echo "3. 高并发场景推荐方案2"
echo "4. 脚本会自动备份现有iptables规则"
echo "5. 确保外部端口范围 $BASE_PORT-$((BASE_PORT + 2540)) 未被占用"
echo ""

main "$@"

配置dhcp

安装sndmasq

apt install dnsmasq

添加ip地址的自动分配

nano /etc/dnsmasq.conf

interface=vmbr0

dhcp-range=192.168.200.2,192.168.200.254,72h
dhcp-option=option:router,192.168.200.1    
dhcp-option=option:dns-server,8.8.8.8,1.1.1.1

禁用默认的systemd-resolved

systemctl stop systemd-resolved
systemctl disable systemd-resolved

启用dnsmasq

systemctl start dnsmasq

修改系统默认的dns

rm -f /etc/resolv.conf
echo "nameserver 8.8.8.8" > /etc/resolv.conf

关于Zeno Chen

本人涉及的领域较多,杂而不精 程序设计语言: Perl, Java, PHP, Python; 数据库系统: MySQL,Oracle; 偶尔做做电路板的开发,主攻STM32单片机
此条目发表在Linux分类目录。将固定链接加入收藏夹。