本文以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配置文件
此时, 我们已经知道了如下信息
网卡:
eno3MAC地址:
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作为出口IPIPv6默认使用
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: trueIPv6是/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