一、准备工作
确保系统是纯净的 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