我认为您的问题没有明确的正确答案。相反,有很多方法可以接近你想要的。因此,我将提供一些提示如何完成它。
如果一台机器有超过 2 个接口(@987654324@ 计为一个),您将无法轻松地自动检测正确的接口。以下是一些关于如何做到这一点的食谱。
问题是,例如,如果主机位于 NAT 防火墙后面的 DMZ 中,它将公共 IP 更改为某个私有 IP 并转发请求。你的机器可能有10个接口,但只有一个对应公共的。
如果您使用双 NAT,即使自动检测也不起作用,您的防火墙甚至会将源 IP 转换为完全不同的东西。因此,您甚至无法确定默认路由是否通向您的具有公共接口的接口。
通过默认路由检测
这是我推荐的自动检测方法
ip r get 1.1.1.1 之类的东西通常会告诉你有默认路由的接口。
如果您想用自己喜欢的脚本/编程语言重新创建它,请使用 strace ip r get 1.1.1.1 并遵循黄砖路。
用/etc/hosts设置它
如果你想保持控制,这是我的建议
您可以在/etc/hosts 中创建一个条目像
80.190.1.3 publicinterfaceip
然后你可以使用这个别名publicinterfaceip 来引用你的公共接口。
可悲的是,haproxy 不了解 IPv6 的这个技巧
使用环境
如果您不是root,这是/etc/hosts 的一个很好的解决方法
与/etc/hosts 相同。但为此使用环境。你可以试试/etc/profile 或~/.profile。
因此,如果您的程序需要一个变量 MYPUBLICIP,那么您可以包含类似的代码(这是 C,请随意从中创建 C++):
#define MYPUBLICIPENVVAR "MYPUBLICIP"
const char *mypublicip = getenv(MYPUBLICIPENVVAR);
if (!mypublicip) { fprintf(stderr, "please set environment variable %s\n", MYPUBLICIPENVVAR); exit(3); }
所以你可以像这样调用你的脚本/程序/path/to/your/script
MYPUBLICIP=80.190.1.3 /path/to/your/script
这甚至适用于crontab。
枚举所有接口,排除不需要的接口
无法使用ip的绝望方式
如果你知道你不想要什么,你可以枚举所有接口并忽略所有错误的接口。
对于这种方法,这似乎已经是https://stackoverflow.com/a/265978/490291 的答案。
像 DLNA 那样做
醉汉试图用酒精淹死自己的方式
您可以尝试枚举网络上的所有 UPnP 网关,这样可以为某些“外部”事物找到正确的路由。这甚至可能在您的默认路由未指向的路由上。
如需了解更多信息,请参阅https://en.wikipedia.org/wiki/Internet_Gateway_Device_Protocol
这会给你一个很好的印象,哪个是你真正的公共接口,即使你的默认路由指向其他地方。
还有更多
山与先知相遇的地方
IPv6 路由器会宣传自己为您提供正确的 IPv6 前缀。查看前缀可以提示您它是否具有某些内部 IP 或全局 IP。
您可以侦听 IGMP 或 IBGP 帧以找出合适的网关。
IP 地址少于 2^32 个。因此,在 LAN 上 ping 它们并不需要很长时间。从您的角度来看,这为您提供了有关 Internet 大部分位置的统计提示。不过你应该比大名鼎鼎的https://de.wikipedia.org/wiki/SQL_Slammer更理智一点
ICMP 甚至 ARP 都是很好的网络边带信息来源。它也可能对您有所帮助。
您可以使用以太网广播地址联系您的所有网络基础设施设备,这通常会有所帮助,例如 DHCP(甚至 DHCPv6)等。
这个额外的列表可能是无穷无尽的,而且总是不完整的,因为每个网络设备制造商都在忙于发明如何自动检测自己的设备的新安全漏洞。这通常对如何检测一些不应该存在的公共接口有很大帮助。
'纳夫说。出去。