Ubuntu 18.04 Server如何查看当前使用的DNS服务器IP
在Ubuntu 18.04 Server LTS里,systemd-resolved已经接管了DNS服务,这就是你看到/etc/resolv.conf指向127.0.0.53的原因——这个本地IP是systemd-resolved的缓存转发器,实际的DNS服务器信息都由它管理。下面给你几个实用的查看方法:
一、用bash命令直接查看
1. 查看所有接口的DNS详情
运行resolvectl status命令,输出里会列出每个网络接口的配置,找到你当前使用的接口(比如ens33),下面的DNS Servers字段就是DHCP分配的实际DNS地址,或者你通过Netplan设置的静态DNS。
2. 快速查看单个接口的DNS
如果你知道接口名称,直接用:
resolvectl dns <接口名>
比如:
resolvectl dns ens33
会直接输出该接口的DNS服务器IP。
3. 查看systemd-resolved生成的真实resolv.conf
systemd-resolved会生成一个包含真实DNS配置的文件,你可以直接查看:
cat /run/systemd/resolve/resolv.conf
这个文件里的nameserver就是实际生效的DNS服务器。
二、验证Netplan配置的DNS是否生效
如果你用Netplan设置了静态DNS,先确保配置文件(通常在/etc/netplan/目录下,比如00-installer-config.yaml)格式正确,比如:
network: ethernets: ens33: addresses: [192.168.1.100/24] gateway4: 192.168.1.1 nameservers: addresses: [8.8.8.8, 8.8.4.4] version: 2
应用配置后:
netplan apply
然后用上面的resolvectl status ens33命令,检查DNS Servers是否已经变成你设置的地址。
三、C语言获取DNS服务器的方法
如果需要通过C代码获取,有两种常见方式:
1. 通过DBUS调用systemd-resolved的API
systemd-resolved提供了DBUS接口,你可以用libsystemd库来查询。示例代码如下:
#include <stdio.h> #include <string.h> #include <systemd/sd-bus.h> int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "Usage: %s <interface-index>\n", argv[0]); fprintf(stderr, "Get interface index with: ip link show\n"); return 1; } sd_bus *bus = NULL; sd_bus_message *msg = NULL; int r; uint32_t ifindex = atoi(argv[1]); // 连接到系统DBUS r = sd_bus_open_system(&bus); if (r < 0) { fprintf(stderr, "Failed to open system bus: %s\n", strerror(-r)); goto finish; } // 调用GetLinkDNS方法,传入接口索引 r = sd_bus_call_method(bus, "org.freedesktop.resolve1", "/org/freedesktop/resolve1", "org.freedesktop.resolve1.Manager", "GetLinkDNS", &msg, "u", ifindex); if (r < 0) { fprintf(stderr, "Failed to call GetLinkDNS: %s\n", strerror(-r)); goto finish; } // 解析返回的数组 r = sd_bus_message_enter_container(msg, 'a', "(say)"); if (r < 0) { fprintf(stderr, "Failed to enter container: %s\n", strerror(-r)); goto finish; } while ((r = sd_bus_message_enter_container(msg, 'r', "(say)")) > 0) { const char *family; const void *addr; size_t addr_len; r = sd_bus_message_read(msg, "s", &family); if (r < 0) break; r = sd_bus_message_read(msg, "ay", &addr, &addr_len); if (r < 0) break; // 打印IPv4地址(这里简化处理,仅支持IPv4) if (strcmp(family, "ipv4") == 0 && addr_len == 4) { uint8_t *ip = (uint8_t *)addr; printf("DNS Server: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); } sd_bus_message_exit_container(msg); } finish: sd_bus_message_unref(msg); sd_bus_unref(bus); return r < 0 ? 1 : 0; }
编译时需要链接systemd库:
gcc -o get_dns get_dns.c -lsystemd
运行时需要传入接口索引(可以用ip link show查看,比如ens33的索引是2):
./get_dns 2
2. 解析systemd-resolved的配置文件
你也可以直接读取/run/systemd/resolve/resolv.conf文件,用C代码解析其中的nameserver行,这种方式更简单,但需要处理文件读取和字符串解析。
内容的提问来源于stack exchange,提问作者Nathan Smith

