侧边栏壁纸
  • 累计撰写 59 篇文章
  • 累计创建 74 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录
PVE

OVH独服安装PVE及DHCP端口映射

Seger
2025-10-17 / 0 评论 / 0 点赞 / 7 阅读 / 2,500 字

编辑/etc/network/interfaces 网络配置

nano /etc/network/interfaces

黏贴配置信息

auto lo
iface lo inet loopback

# 物理口
iface eno1 inet manual
iface eno2 inet manual

# ===== 外网桥 =====
auto vmbr0
iface vmbr0 inet static
        address 51.77.64.81/24
        gateway 51.77.64.254
        bridge-ports eno1
        bridge-stp off
        bridge-fd 0
        # 出站 DNS(也可写到 /etc/resolv.conf.d 或 systemd-resolved)
        dns-nameservers 8.8.8.8 2001:4860:4860::8888

# IPv6(OVH 样式 /128 + 非直连网关)
iface vmbr0 inet6 static
        address 2001:41d0:700:2251::1/128
        # 给“非直连”的 IPv6 网关先加一条到网关本身的直连路由,再加默认路由(onlink)
        post-up   ip -6 route add 2001:41d0:0700:22ff:00ff:00ff:00ff:00ff dev vmbr0 || true
        post-up   ip -6 route add default via 2001:41d0:0700:22ff:00ff:00ff:00ff:00ff dev vmbr0 onlink || true
        pre-down  ip -6 route del default via 2001:41d0:0700:22ff:00ff:00ff:00ff:00ff dev vmbr0 || true
        pre-down  ip -6 route del 2001:41d0:0700:22ff:00ff:00ff:00ff:00ff dev vmbr0 || true

# ===== 内网桥(NAT)=====
auto vmbr1
iface vmbr1 inet static
        address 10.10.10.1/24
        bridge-ports none
        bridge-stp off
        bridge-fd 0
        # NAT44
        post-up   iptables  -t nat -C POSTROUTING -s 10.10.10.0/24 -o vmbr0 -j MASQUERADE 2>/dev/null || iptables  -t nat -A POSTROUTING -s 10.10.10.0/24 -o vmbr0 -j MASQUERADE
        post-up   iptables  -C FORWARD -i vmbr1 -o vmbr0 -j ACCEPT 2>/dev/null || iptables  -A FORWARD -i vmbr1 -o vmbr0 -j ACCEPT
        post-up   iptables  -C FORWARD -i vmbr0 -o vmbr1 -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || iptables  -A FORWARD -i vmbr0 -o vmbr1 -m state --state RELATED,ESTABLISHED -j ACCEPT
        pre-down  iptables  -t nat -D POSTROUTING -s 10.10.10.0/24 -o vmbr0 -j MASQUERADE 2>/dev/null || true
        pre-down  iptables  -D FORWARD -i vmbr1 -o vmbr0 -j ACCEPT 2>/dev/null || true
        pre-down  iptables  -D FORWARD -i vmbr0 -o vmbr1 -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || true

# 内网 IPv6:使用 ULA 前缀 + NAT66 以便 VMs 能出 IPv6(你只有 /128 无法下发可路由段)
iface vmbr1 inet6 static
        address fd10:10:10::1/64
        post-up   ip6tables -t nat -C POSTROUTING -s fd10:10:10::/64 -o vmbr0 -j MASQUERADE 2>/dev/null || ip6tables -t nat -A POSTROUTING -s fd10:10:10::/64 -o vmbr0 -j MASQUERADE
        post-up   ip6tables -C FORWARD -i vmbr1 -o vmbr0 -j ACCEPT 2>/dev/null || ip6tables -A FORWARD -i vmbr1 -o vmbr0 -j ACCEPT
        post-up   ip6tables -C FORWARD -i vmbr0 -o vmbr1 -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || ip6tables -A FORWARD -i vmbr0 -o vmbr1 -m state --state RELATED,ESTABLISHED -j ACCEPT
        pre-down  ip6tables -t nat -D POSTROUTING -s fd10:10:10::/64 -o vmbr0 -j MASQUERADE 2>/dev/null || true
        pre-down  ip6tables -D FORWARD -i vmbr1 -o vmbr0 -j ACCEPT 2>/dev/null || true
        pre-down  ip6tables -D FORWARD -i vmbr0 -o vmbr1 -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || true

source /etc/network/interfaces.d/*

打开内核转发,永久生效

nano /etc/sysctl.conf
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.all.accept_ra=0

生效:

sysctl --system

配置DHCP 信息

安装DHCP服务器

apt-get update
apt-get install -y isc-dhcp-server

配置/etc/default/isc-dhcp-server

nano /etc/default/isc-dhcp-server
INTERFACESv4="vmbr1"
INTERFACESv6=""

配置/etc/dhcp/dhcpd.conf

nano /etc/dhcp/dhcpd.conf
# /etc/dhcp/dhcpd.conf  — ISC DHCP server v4 配置
# 作用:给 vmbr1(10.10.10.0/24)下的虚拟机自动分配 IPv4 地址

# 全局参数
default-lease-time 600;      # 10 分钟
max-lease-time     7200;     # 2 小时
authoritative;               # 本服务器为该网段权威 DHCP

# 可选:设定一个自定义域名(按需修改/删除)
option domain-name "lan.local";

# 内网子网配置(vmbr1 = 10.10.10.1/24)
subnet 10.10.10.0 netmask 255.255.255.0 {
  # 动态地址池
  range 10.10.10.100 10.10.10.200;

  # 网关(缺省路由)
  option routers 10.10.10.1;

  # DNS 服务器
  option domain-name-servers 8.8.8.8, 1.1.1.1;

  # 广播地址(可选)
  option broadcast-address 10.10.10.255;
}

# === 示例:静态保留(可按需添加/删除)===
# 说明:指定设备 MAC,固定一个 IP;请修改硬件地址和 IP
# host vm1 {
#   hardware ethernet aa:bb:cc:dd:ee:ff;
#   fixed-address 10.10.10.10;
# }

启动DHCP

systemctl enable --now isc-dhcp-server
systemctl status isc-dhcp-server --no-pager

IPv6:用 radvd 做 RA(SLAAC),配合 NAT66 出口

编辑/etc/radvd.conf

nano /etc/radvd.conf
interface vmbr1 {
  AdvSendAdvert on;
  MaxRtrAdvInterval 30;
  prefix fd10:10:10::/64 {
    AdvOnLink on;
    AdvAutonomous on;   # SLAAC
  };
  RDNSS 2001:4860:4860::8888 2001:4860:4860::8844 {
    AdvRDNSSLifetime 600;
  };
};

安装并启用

apt-get install -y radvd
systemctl enable --now radvd

使网络配置生效

ifreload -a 2>/dev/null || { systemctl restart networking || (ifdown vmbr0 && ifup vmbr0); }

查看DHCP状态

systemctl restart isc-dhcp-server
systemctl status isc-dhcp-server --no-pager

宿主加静态DNS配置

echo "nameserver 8.8.8.8" >> /etc/resolv.conf
echo "nameserver 2001:4860:4860::8888" >> /etc/resolv.conf

创建IPv4 + IPv6 端口映射的脚本

nano setup_nat_port_forward.sh
#!/usr/bin/env bash
# =========================================================
# setup_nat_port_forward.sh — 一键安装/加载 IPv4+IPv6 端口转发
# 适配 Debian/Proxmox (iptables-nft + ip6tables-nft)
# 管理文件:/etc/nat_port_forwards.conf
# =========================================================
set -Eeuo pipefail

# ===== 基础参数(按需修改) =====
EXT_IF="vmbr0"                              # 外网接口/桥
CONF="/etc/nat_port_forwards.conf"          # 端口映射配置文件
COMMENT_TAG="DNAT-MGR"
HOOK_UP="/etc/network/if-up.d/nat-dnat"
HOOK_DOWN="/etc/network/if-down.d/nat-dnat"

die(){ echo "❌ Error: $*" >&2; exit 1; }
need(){ command -v "$1" >/dev/null 2>&1 || die "缺少命令: $1"; }

need iptables
need ip6tables

# ===== 首次运行生成模板 =====
if [ ! -f "$CONF" ]; then
  cat >"$CONF" <<'EOF'
# /etc/nat_port_forwards.conf
# 一行一条映射,格式:
#   v4 <公网端口> <协议> <内网IPv4> <内网端口>
#   v6 <公网端口> <协议> <内网IPv6> <内网端口>
# 协议可写:tcp / udp / tcp+udp
#
# 例:把公网 45678 → Win 的 RDP 3389(IPv4 + IPv6)
v4 45678 tcp 10.10.10.100 3389
v6 45678 tcp fd10:10:10::100 3389
EOF
  echo "✅ 已创建默认配置:$CONF"
fi

echo "🧹 清理旧 DNAT 规则..."
# 清理旧 v4
iptables  -t nat -S 2>/dev/null | grep "$COMMENT_TAG" || true | while read -r L; do
  # 形如:-A PREROUTING ... -m comment --comment DNAT-MGR
  # 转换成 -D 命令以删除
  iptables -t nat ${L/-A /-D } || true
done
iptables  -S 2>/dev/null | grep "$COMMENT_TAG" || true | while read -r L; do
  iptables ${L/-A /-D } || true
done
# 清理旧 v6
ip6tables -t nat -S 2>/dev/null | grep "$COMMENT_TAG" || true | while read -r L; do
  ip6tables -t nat ${L/-A /-D } || true
done
ip6tables -S 2>/dev/null | grep "$COMMENT_TAG" || true | while read -r L; do
  ip6tables ${L/-A /-D } || true
done

echo "⚙️  应用新映射..."
while read -r line; do
  [[ -z "$line" || "$line" =~ ^# ]] && continue
  set -- $line
  family="$1"; pub_port="$2"; proto="$3"; dst_ip="$4"; dst_port="$5"

  if [[ "$family" == "v4" ]]; then
    if [[ "$proto" == *tcp* ]]; then
      iptables -t nat -A PREROUTING -i "$EXT_IF" -p tcp --dport "$pub_port" -j DNAT --to-destination "${dst_ip}:${dst_port}" -m comment --comment "$COMMENT_TAG"
      iptables -A FORWARD -p tcp -d "$dst_ip" --dport "$dst_port" -j ACCEPT -m comment --comment "$COMMENT_TAG"
    fi
    if [[ "$proto" == *udp* ]]; then
      iptables -t nat -A PREROUTING -i "$EXT_IF" -p udp --dport "$pub_port" -j DNAT --to-destination "${dst_ip}:${dst_port}" -m comment --comment "$COMMENT_TAG"
      iptables -A FORWARD -p udp -d "$dst_ip" --dport "$dst_port" -j ACCEPT -m comment --comment "$COMMENT_TAG"
    fi
  elif [[ "$family" == "v6" ]]; then
    if [[ "$proto" == *tcp* ]]; then
      ip6tables -t nat -A PREROUTING -i "$EXT_IF" -p tcp --dport "$pub_port" -j DNAT --to-destination "[${dst_ip}]:${dst_port}" -m comment --comment "$COMMENT_TAG"
      ip6tables -A FORWARD -p tcp -d "$dst_ip" --dport "$dst_port" -j ACCEPT -m comment --comment "$COMMENT_TAG"
    fi
    if [[ "$proto" == *udp* ]]; then
      ip6tables -t nat -A PREROUTING -i "$EXT_IF" -p udp --dport "$pub_port" -j DNAT --to-destination "[${dst_ip}]:${dst_port}" -m comment --comment "$COMMENT_TAG"
      ip6tables -A FORWARD -p udp -d "$dst_ip" --dport "$dst_port" -j ACCEPT -m comment --comment "$COMMENT_TAG"
    fi
  else
    echo "⚠️ 跳过未知 family: $family"
  fi
done < "$CONF"

echo "✅ 规则已加载完毕"

# ===== 持久化钩子:网络起来时自动套用 =====
mkdir -p /etc/network/if-up.d /etc/network/if-down.d

cat >"$HOOK_UP" <<EOF
#!/bin/bash
[ "\$IFACE" = "$EXT_IF" ] || exit 0
bash $0 || true
EOF

cat >"$HOOK_DOWN" <<'EOF'
#!/bin/bash
# 简单清理 nat 表,避免接口下线残留
iptables  -t nat -F || true
ip6tables -t nat -F || true
EOF

chmod +x "$HOOK_UP" "$HOOK_DOWN"
echo "🔁 已注册网络钩子:$HOOK_UP / $HOOK_DOWN"

给与权限

chmod +x /root/setup_nat_port_forward.sh

增加或减少映射就编辑/etc/nat_port_forwards.conf

nano /etc/nat_port_forwards.conf

示例

# IPv4 映射
v4 5666 tcp 10.10.10.50 5666
v4 45678 tcp+udp 10.10.10.51 3389

# IPv6 映射(可选)
v6 8080 tcp fd10:10:10::50 80
v6 8443 tcp fd10:10:10::51 443

执行加载生效

bash /root/setup_nat_port_forward.sh

验证结果

iptables  -t nat -S | grep DNAT-MGR
ip6tables -t nat -S | grep DNAT-MGR

转发脚本pve启动自动运行

固化脚本位置

install -m 0755 setup_nat_port_forward.sh /usr/local/sbin/setup_nat_port_forward.sh

新增 systemd 服务(开机自动跑一次 + 等待 vmbr0 就绪)

cat >/etc/systemd/system/nat-dnat.service <<'EOF'
[Unit]
Description=Load IPv4+IPv6 DNAT port forwards (setup_nat_port_forward.sh)
# 等待网络完全就绪 & PVE 服务起来(避免太早执行)
Wants=network-online.target
After=network-online.target pve-cluster.service
# 如启用PVE自带防火墙,可按需再加:After=pve-firewall.service

[Service]
Type=oneshot
# 先等 vmbr0 真正 UP(最多等 30s),再执行主脚本
ExecStartPre=/bin/sh -lc 'for i in $(seq 1 30); do ip link show vmbr0 2>/dev/null | grep -q "state UP" && exit 0; sleep 1; done; echo "vmbr0 not UP, continue anyway"'
# 如需等地址就绪,可改成:ip -4 addr show dev vmbr0 | grep -q "inet "
ExecStart=/usr/bin/env bash -lc '/usr/local/sbin/setup_nat_port_forward.sh'
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable nat-dnat.service
systemctl start nat-dnat.service

(可选但推荐)保留 ifup 钩子,处理“接口重启”场景

你的脚本已经会写入 /etc/network/if-up.d/nat-dnat,只要确认它是可执行的即可:

chmod +x /etc/network/if-up.d/nat-dnat /etc/network/if-down.d/nat-dnat

这样即使你将来 ifreload -a 或某次 vmbr0 单独 down/up,也会自动重载规则。

开机后验证

重启整机后检查是否已经自动加载:

iptables  -t nat -S | grep DNAT-MGR
iptables  -S       | grep DNAT-MGR
ip6tables -t nat -S | grep DNAT-MGR
ip6tables -S        | grep DNAT-MGR

能看到带 DNAT-MGR 的 PREROUTING/FORWARD 规则就 OK 了。

0

评论区