![Linux 中的主要网络接口](https://linux22.com/image/37202/Linux%20%E4%B8%AD%E7%9A%84%E4%B8%BB%E8%A6%81%E7%BD%91%E7%BB%9C%E6%8E%A5%E5%8F%A3.png)
我有一个带有两个接口的服务器盒。其中一个接口连接到内部网络,另一个接口连接到外部网络。
我已将 IP 192.168.1.200 分配给内部接口 (eth0)。我有一些本地守护进程监听这个 IP/接口(cups、nginx、pdns)。
外部 IP 为 192.168.0.91 (eth1)。这里我只有NAT伪装。每当我尝试从服务器本身访问服务器时,就会发生奇怪的事情。
如果我尝试打开位于 192.168.1.200 的网页,服务器使用 192.168.0.91 地址,并且我的权限被拒绝(网络服务器受保护,仅在内部网络上提供内容)。
如果我关闭 eth1,服务器工作正常并使用内部 IP。但是,一旦我启动 eth1,它就会立即将其 IP 作为主要 IP,而我将再次被拒绝许可。
如何明确设置要使用的主 IP/接口?
我正在运行 64 位版本的 Gentoo Linux。两个网卡的驱动程序都编译为模块。我使用 systemd 作为我的初始化系统。
编辑:
感谢您的回复,但最有趣的部分在这里:
atomic ~ # cat /etc/resolv.conf
domain local
search local
nameserver 192.168.1.200
atomic ~ # cat /etc/hosts
...
192.168.1.200 atomic ns.atomic.local atomic.local
...
地址解析就OK了:
atomic ~ # dig atomic.local 192.168.1.200
; <<>> DiG 9.9.4 <<>> atomic.local
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38797
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 2800
;; QUESTION SECTION:
;atomic.local. IN A
;; ANSWER SECTION:
atomic.local. 604800 IN A 192.168.1.200
;; Query time: 42 msec
;; SERVER: 192.168.1.200#53(192.168.1.200)
;; WHEN: Tue May 27 13:37:04 EEST 2014
;; MSG SIZE rcvd: 55
通过wget访问的Nginx日志:
atomic ~ # wget atomic.fhn
--2014-05-27 13:45:58-- http://atomic.local/
Resolving atomic.local... 192.168.1.200
Connecting to atomic.local|192.168.1.200|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: ‘index.html’
[ <=> ] 0 --.-K/s in 0s
2014-05-27 13:45:58 (0.00 B/s) - ‘index.html’ saved [0]
atomic ~ # tail -n 1 /var/log/nginx/access_log
192.168.0.91 - - [27/May/2014:13:45:58 +0300] "GET / HTTP/1.1" 200 5 "-" "Wget/1.14 (linux-gnu)"
我收到 200/OK HTTP 状态,因为我已禁用 IP/网络过滤,但问题尚未解决。
路由表:
192.168.0.0/30 dev wan proto kernel scope link src 192.168.0.2
192.168.1.0/24 dev lan proto kernel scope link src 192.168.1.200
编辑2:
使用度量的路由表:
192.168.0.0/30 dev wan scope link metric 20
192.168.1.0/24 dev lan scope link metric 10
broadcast 127.0.0.0 dev lo table local proto kernel scope link src 127.0.0.1
local 127.0.0.0/8 dev lo table local proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo table local proto kernel scope link src 127.0.0.1
broadcast 192.168.0.0 dev wan table local proto kernel scope link src 192.168.0.2
local 192.168.0.2 dev wan table local proto kernel scope host src 192.168.0.2
broadcast 192.168.0.3 dev wan table local proto kernel scope link src 192.168.0.2
broadcast 192.168.1.0 dev lan table local proto kernel scope link src 192.168.1.200
local 192.168.1.200 dev lan table local proto kernel scope host src 192.168.1.200
broadcast 192.168.1.255 dev lan table local proto kernel scope link src 192.168.1.200
答案1
您需要确保 LAN 路由优先于 WAN 路由。麻烦就在这里:
192.168.0.0/30 dev wan proto kernel scope link src 192.168.0.2
192.168.1.0/24 dev lan proto kernel scope link src 192.168.1.200
192.168.0.0/30 也覆盖 192.168.1.0/24。因此,您必须告诉 TCP/IP 堆栈在适用时更喜欢后者,否则它可能会随机选择(我希望大多数实现始终使用第一个) - 使用参数metric
,例如:
ip route add 192.168.1.0/24 dev lan metric 10
ip route add 192.168.0.0/30 dev wan metric 20
(显然您需要首先删除现有的路线)。
答案2
正如 jofel 已经说过的,Linux 上不存在主接口这样的东西。实际发生的情况:如果你的计算机想要向某个地方发送数据包,他知道它的目标 IP。但是还需要在包中给出源 IP,这将从接口列表和路由表中填充。
对于本地地址,事情会有点复杂(并且没有我们希望的那么简单)。
最简单的方法是在 url 中使用显式 192.168.1.200 地址(或精确解析为该地址的主机名)。您没有写,但我认为您正在使用带有主机名的 url 来获取实际文档,并且该主机名默认解析为外部地址。