如何让OpenVPN自动推送系统当前的DNS服务器给客户端?
我太懂这种硬编码配置的尴尬了——万一DHCP分配的DNS突然变了,客户端直接就没法正常解析域名,还得手动去改OpenVPN配置,完全不省心。下面给你几个实用的方案,能让OpenVPN自动同步系统当前的DNS服务器,再也不用硬编码:
方案一:用脚本动态生成DNS推送配置
这个方法的核心是写个小脚本,每次OpenVPN启动前自动读取系统当前的DNS,生成对应的push指令,然后让主配置文件引用这个动态生成的文件。
创建DNS更新脚本
新建一个脚本文件,比如/etc/openvpn/update-dns-push.sh,内容如下:#!/bin/bash # 清空旧的DNS推送配置 > /etc/openvpn/dns-push.conf # 读取系统当前的DNS服务器(不同系统路径可能不同,这里以常规的resolv.conf为例) # 如果是systemd-resolved系统,建议用/run/systemd/resolve/resolv.conf代替/etc/resolv.conf grep -E '^nameserver' /etc/resolv.conf | while read -r line; do dns_addr=$(echo "$line" | awk '{print $2}') echo "push \"dhcp-option DNS $dns_addr\"" >> /etc/openvpn/dns-push.conf done给脚本加执行权限
运行命令让脚本可以执行:chmod +x /etc/openvpn/update-dns-push.sh修改OpenVPN主配置
打开你的OpenVPN服务器配置文件(比如/etc/openvpn/server.conf),添加一行引用刚才生成的配置文件:include /etc/openvpn/dns-push.conf配置脚本自动运行
如果用systemd管理OpenVPN服务,修改对应的服务文件(比如/etc/systemd/system/openvpn@server.service),添加ExecStartPre指令,让脚本在服务启动前自动执行:ExecStartPre=/etc/openvpn/update-dns-push.sh然后重载systemd配置并重启OpenVPN:
systemctl daemon-reload systemctl restart openvpn@server要是担心DNS中途变化,还可以用crontab定时运行脚本,比如每小时更新一次:
0 * * * * /etc/openvpn/update-dns-push.sh && systemctl reload openvpn@server
方案二:针对systemd-resolved系统的简化方法
如果你的服务器用的是systemd-resolved管理DNS,直接用resolvectl命令获取DNS更准确,不需要依赖resolv.conf的软链接。把方案一里的脚本内容换成下面的即可:
#!/bin/bash > /etc/openvpn/dns-push.conf # 获取全局DNS服务器并生成推送指令 resolvectl dns | grep -E '^Global' | awk '{for(i=3; i<=NF; i++) print "push \"dhcp-option DNS " $i "\""}' >> /etc/openvpn/dns-push.conf
测试验证
运行一次脚本,查看/etc/openvpn/dns-push.conf里的内容是不是和系统当前的DNS一致:
cat /etc/openvpn/dns-push.conf
然后重启OpenVPN,用客户端连接后,检查客户端的DNS设置是否和服务器当前的DNS匹配,确认没问题就大功告成了。
备注:内容来源于stack exchange,提问作者enigmaticPhysicist

