Akvicor
Akvicor
发布于 2025-11-22 / 4 阅读
0
0

OVH 独立服务器&VPS 购买附加 IP 并设置为出口 IP

本文以IPv4地址为例, 因此遇到 IP 时可直接当作 IPv4 理解, 截至发文时IPv6地址无法直接分配给某个服务器, 仅能分配给vRack, 因此不做讨论.

购买的服务器会随机分配一个IP地址, 这个地址就是这个服务器默认入口和出口IP. 但我希望购买一个顺眼的IP地址并长期使用, 就算更换了服务器也可以直接将这个IP绑定到新的服务器上, 继续使用这个IP. 同时稳定的IP也有其他的好处, 例如:

  • 用于邮件服务的发信和收信IP, 便于建立和积累IP信誉度

  • 将这个IP配置到其他服务的白名单IP中, 大量减少更换服务器后因IP变动导致的维护工作

购买IP

首先登录到OVH控制台的 Bare Metal Cloud -> Network -> IP

点击 Order IPs 购买一个IP, 注意这个IP购买时需要选择绑定到某个服务器(注意IP是有区域限制的, IP只能在同区域的服务器之间绑定), 后面可以随意更改绑定的服务器, 不需要担心


购买后需要等待几分钟(OVH的反应总是很慢)

当IP准备好后OVH会发送给你一个邮件, 邮件中包含了分配给你的IP地址, 同时在控制台刷新也会看到. 在这里你可以更换绑定的服务器, 取消这个IP或者配置RDNS等

在服务器上配置这个IP

假设我们服务器本身的IP是 1.1.1.1 购买的IP是 2.2.2.2 . 如果你购买的是IP段, 那么也可以拆分为多个/32的单IP配置.

我使用netplan来管理服务器系统的网络, 一般直接通过OVH安装的debian13系统默认就是netplan. 我将使用netplan来演示.

原始 netplan 配置文件

首先netplan的配置都在/etc/netplan/ 这个目录下, 默认文件一般为/etc/netplan/50-cloud-init.yaml

我们就需要通过编辑这个配置文件来更改默认出口IP vim /etc/netplan/50-cloud-init.yaml , 一般情况下你应该会看到这样的配置, 这个配置里因为使用了dhcp, 因此缺乏很多静态配置才有的条目, 为了实现我们的功能, 我们需要全部改为静态配置.

network:
  version: 2
  ethernets:
    eno3:
      match:
        macaddress: "ac:ff:60:03:00:00"
      addresses:
      - "2604:000:000:100::1/128"
      dhcp4: true
      accept-ra: false
      set-name: "eno3"
      routes:
      - on-link: true
        to: "default"
        via: "2604:000:000:1ff:ff:ff:ff:ff"

在修改这个配置之前, 我们还需要获取一些信息. 这些信息你在服务器的管理面板也能找到, 我在下面提供的是在系统里找的方式.

1. mac 地址

在默认的配置文件里就有这个, 可以直接使用. 但如果原本不是用的netplan管理, 那就需要手动获取

通过 ip a 命令查看网卡信息, 我们可以得到类似下面的信息

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: eno3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether ac:ff:60:03:00:00 brd ff:ff:ff:ff:ff:ff
    altname enp3s0f0
    altname enxac1f6b63776a
    inet 1.1.1.1/24 metric 100 brd 1.1.1.255 scope global dynamic eno3
       valid_lft 48662sec preferred_lft 48662sec
    inet6 2604:000:000:100::1/128 scope global 
       valid_lft forever preferred_lft forever
    inet6 fe80::ae1f:bbbb:aaaa:0000/64 scope link proto kernel_ll 
       valid_lft forever preferred_lft forever
3: eno4: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether ac:1f:12:03:11:00 brd ff:ff:ff:ff:ff:ff
    altname enp3s0f1
    altname enxac1f6b63776b

我们可以看到 eno3 网卡中包含了我们这台机器原本的IP地1.1.1.1, 因此这个就是默认的网卡. 我们可以通link/ether ac:ff:60:03:00:00 brd ff:ff:ff:ff:ff:ff 这一行发现这个网卡的 mac 地址是 ac:ff:60:03:00:00

2. ipv4网关

执行命令 ip -4 route

root@sync:~# ip -4 route
default via 1.1.1.254 dev eno3 proto dhcp src 1.1.1.1 metric 100
......

通过 default 这行可以看到网关是 1.1.1.254

3. ipv6网关

执行命 ip -6 route

root@sync:~# ip -6 route
2604:000:000:100::1 dev eno3 proto kernel metric 256 pref medium
fe80::/64 dev eno3 proto kernel metric 256 pref medium
default via 2604:000:000:1ff:ff:ff:ff:ff dev eno3 proto static metric 1024 onlink pref medium

通过 default 这行可以看到网关是 2604:000:000:1ff:ff:ff:ff:ff

修改netplan配置文件

此时, 我们已经知道了如下信息

  • 网卡: eno3

  • MAC地址: ac:ff:60:03:00:00

  • 本机原有IPv4地址: 1.1.1.1

  • 本机原有IPv4网关地址: 1.1.1.254

  • 本机原有IPv6地址: 2604:000:000:100::1

  • 本机原有IPv6网关地址: 2604:000:000:1ff:ff:ff:ff:ff

  • 购买的IPv4地址: 2.2.2.2

同时我们想要的效果

  • IPv4默认使用 2.2.2.2 作为出口IP

  • IPv6默认使用 2604:000:000:100::1 作为出口IP

  • 其他IP地址仍能正常使用

注意

  • 独立服务器的KS系列和VPS系列只有1个IPv6地址, 也就是/128的范围(理论上OVH是给你分配了/64的, 可以通过静态配置拿到, 但是官方不支持, 谨慎配置)

  • SYS等更高端的独立服务器的IPv6是/64的范围

  • 文件名最好使用 /etc/netplan/50-cloud-init.yaml, 后面有用到

  • 将机器原本的IP放在IPv4地址的最后一个, 就像下面实例配置中一样, 后面有用到

知道了上面的信息, 我们就可以着手编写配置了. 我提供了两个配置, 分别用于服务器IPv6是/64和/128范围使用.

注意事项我通过注释写在了配置文件中, 请务必仔细看一遍.

IPv6是/64范围: IPv6的出口IP可以随便从允许的范围内任意选一个, 也可以同时配置好几个

network:
  version: 2
  ethernets:
    eno3: # 网卡
      set-name: "eno3" # 网卡
      match:
        macaddress: "ac:ff:60:03:00:00" # 网卡mac地址
      addresses:
      - "2.2.2.2/32" # 将期望的出口IP放在第一个位置, 防止docker等服务出问题(docker默认通过第一个IP对外发送请求)
      - "1.1.1.1/32" # 机器原本的IP, 务必保留, 务必放在IPv4地址的最后一个(后面需要用到)
      - "2604:000:000:100::1/128" # 自定义的IPv6地址, 如果不加这行那么2604:000:000:100::1就无法使用, 其他地址同理
      - "2604:000:000:100::/64" # 机器可以分配的整个IPv6段, 可以不需要. 添加后可以通过2604:000:000:100::访问服务器
      nameservers:
        addresses: # DNS服务器, 可以自定义其他的
          - 1.1.1.1 # 这是Cloudflare的DNS, 不是我举例的IP
          - 8.8.8.8
          - 2606:4700:4700::1111
          - 2001:4860:4860::8888
      dhcp4: false # 关闭DHCP
      dhcp6: false # 关闭DHCP
      accept-ra: false # 不接受通告
      routes:
      - to: "1.1.1.254" # 网关IP直接走物理链路
        scope: link
      - to: "default"
        via: "1.1.1.254" # 默认网关
        from: "2.2.2.2" # 默认出口IP, 可以去掉这行, 但是这样会由系统自动选择默认出口IP
        on-link: true
      - to: "2604:000:000:1ff:ff:ff:ff:ff" # 网关IP直接走物理链路
        scope: link
      - to: "default"
        via: "2604:000:000:1ff:ff:ff:ff:ff" # 默认网关
        from: "2604:000:000:100::1" # 默认出口IP, 可以去掉这行, 但是这样会由系统自动选择默认出口IP
        on-link: true

IPv6是/128范围

network:
  version: 2
  ethernets:
    eno3: # 网卡
      set-name: "eno3" # 网卡
      match:
        macaddress: "ac:ff:60:03:00:00" # 网卡mac地址
      addresses:
      - "2.2.2.2/32" # 将期望的出口IP放在第一个位置, 防止docker等服务出问题(docker默认通过第一个IP对外发送请求)
      - "1.1.1.1/32" # 机器原本的IP, 务必保留, 务必放在IPv4地址的最后一个(后面需要用到)
      - "2604:000:000:100::1/128" # 机器原本的IP, 务必保留
      nameservers:
        addresses: # DNS服务器, 可以自定义其他的
          - 1.1.1.1 # 这是Cloudflare的DNS, 不是我举例的IP
          - 8.8.8.8
          - 2606:4700:4700::1111
          - 2001:4860:4860::8888
      dhcp4: false # 关闭DHCP
      dhcp6: false # 关闭DHCP
      accept-ra: false # 不接受通告
      routes:
      - to: "1.1.1.254" # 网关IP直接走物理链路
        scope: link
      - to: "default"
        via: "1.1.1.254" # 默认网关
        from: "2.2.2.2" # 默认出口IP, 可以去掉这行, 但是这样会由系统自动选择默认出口IP
        on-link: true
      - to: "2604:000:000:1ff:ff:ff:ff:ff" # 网关IP直接走物理链路
        scope: link
      - to: "default"
        via: "2604:000:000:1ff:ff:ff:ff:ff" # 默认网关
        from: "2604:000:000:100::1" # 默认出口IP, 可以去掉这行, 因为机器只有一个IPv6地址
        on-link: true

应用配置文件

  • 通过 netplan try 测试配置是否正确, 如果没问题直接回车确认应用, 如果有问题导致副服务器失联, 则 120 秒后系统会自动恢复之前的配置

  • 通过 netplan apply 直接应用配置, 但如果配置有问题可能导致服务器失联, 需要IPMI等工具辅助恢复

测试IP是否配置正确

通过第三方的IP接口查看是否配置正确, 如果请求后返回的IP是自己期望的IP, 那就代表配置正确

同时需要检查期望IP之外的IP能否正常通信, 需要注意下面的IP改为你的IP

  • 测试默认出口IPv4: curl -4 ip.sb , 如果返回 2.2.2.2 则正常

  • 测试其他出口IPv4: curl -4 ip.sb --interface 1.1.1.1 , 如果返回 1.1.1.1 则正常

  • 测试默认出口IPv6: curl -6 ip.sb , 如果返回 2604:000:000:100::1 则正常

  • 测试其他出口IPv6: curl -6 ip.sb --interface 2604:000:000:100:: , 如果返回 2604:000:000:100:: 则正常

存在的问题&解决方案

重启后IPv4网络故障

如果你配置完网络后一切正常, 但是重启后IPv6正常, IPv4却无法连接, 但是通过 ip a 查看网络信息又一切正常, 那这就是OVH网络架构导致的问题. 需要写一个简单服务辅助解决

这个问题的原因在于你开机后没有通过服务器原本的IP地址, 也就是博客中使用的 1.1.1.1 对外发出过请求, 导致上游网络不知道怎么处理 2.2.2.2 这个IP的数据包, 导致网络出现问题.

解决方法也很简单, 只要通过原始的IP对外发出个请求激活一下即可.

这里我提供了一个systemd服务用于解决这个问题, 逻辑就是每次开机后自动使用 1.1.1.1 发送一个网络请求, 例如上面的curl -4 ip.sb --interface 1.1.1.1

首先我将服务相关的所有文件放在了 /opt/service/fixed-ipv4 目录中, 你可以自己决定位置, 但是需要自行修改后面配置中的路径

首先是编写一个shell脚本, 用于发送网络请求

mkdir -p /opt/service/fixed-ipv4/exec
touch /opt/service/fixed-ipv4/exec/wait-ipv4.sh
chmod +x /opt/service/fixed-ipv4/exec/wait-ipv4.sh
vim /opt/service/fixed-ipv4/exec/wait-ipv4.sh

还记着之前编写netplan配置时我要求将机器原本的IP放在IPv4地址的最后一个吗, 这个脚本就通过这个来获取机器原本的IP.

当然如果你也可以直接将原本的IP写死在脚本中, 但是更换服务器后你就需要修改这个脚本.

#!/bin/bash

# 获取本机原始IP(配置中最后一个IPv4), 对外发送请求激活网络

# 配置
NETPLAN_FILE="/etc/netplan/50-cloud-init.yaml"
CHECK_URLS=("ip.sb" "ip.gs" "ipinfo.io")

TARGET_IP=$(grep -E '^\s*-\s*"?[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/[0-9]+"?$' "$NETPLAN_FILE" | \
  tail -n 1 | \
  cut -d'/' -f1 | \
  tr -d ' "-')

# 检查提取结果
if [[ -z "$TARGET_IP" ]]; then
    echo "Error: Could not extract IPv4 address from $NETPLAN_FILE"
    exit 1
fi

echo "Target Interface IP found: $TARGET_IP"
echo "Starting connectivity check loop..."

# 无限循环直到成功
while true; do
    for URL in "${CHECK_URLS[@]}"; do
        if curl -s --fail --interface "$TARGET_IP" --connect-timeout 3 --max-time 5 "$URL" > /dev/null; then
            echo "Success! Connected to $URL via $TARGET_IP."
            exit 0
        fi
    done

    echo "All checks failed. Retrying in 1s..."
    sleep 1
done

可以先手动执行一下脚本看看有没有问题

然后编写一个systemd服务

vim /opt/service/fixed-ipv4/fixed-ipv4.service

服务会在开机后network配置好后执行一次, 内容如下

[Unit]
Description=Wait for internet connection on specific interface
After=network-online.target
Wants=network-online.target
ConditionFileIsExecutable=/opt/service/fixed-ipv4/exec/wait-ipv4.sh

[Service]
Type=oneshot
TimeoutStartSec=0
ExecStart=/opt/service/fixed-ipv4/exec/wait-ipv4.sh

[Install]
WantedBy=multi-user.target

安装服务并启用

# 复制到指定文件夹
cp /opt/service/fixed-ipv4/fixed-ipv4.service /etc/systemd/system
# 刷新
systemctl daemon-reload
# 启用
systemctl enable fixed-ipv4.service
# 启动
systemctl start fixed-ipv4.service
# 重启
systemctl restart fixed-ipv4.service
# 查看状态
systemctl status fixed-ipv4.service


评论