网络实验:IP地址配置

老当益壮,宁移白首之心?穷且益坚,不坠青云之志。

—— 唐·王勃·《滕王阁序》

为主机配置 IP 地址并调通网络,是开发工程师和网络管理员的必备技能。

本节提供了 4 个典型的实验场景,讲解为 Linux 主机配置 IP 地址的关键步骤。实践是最佳的学习途径,本节实验请务必亲自动手操作,对理解 IP 协议、路由原理以及子网掩码等核心知识点大有裨益。

局域网

这是一个典型的局域网拓扑,所有主机直接接入同一个以太网:

只要为这个局域网分配一个网段,例如 192.168.1.0/24 ,并为每台主机配置合适的 IP 地址,主机便可通过 IP 协议来通信了。

实验环境同样通过 docker 容器提供,只需执行这个 docker 命令,即可一键启动:

1
docker run --name switch-lab --rm -it --privileged --cap-add=NET_ADMIN --cap-add=SYS_ADMIN -v /data -h switch fasionchan/netbox:0.3 bash /script/switch-lab.sh

我们先观察每台主机的网络信息,一开始它们都没有配置 IP 地址,路由表也是空的:

1
2
3
4
5
root@ant [ ~ ]  ➜ ip addr show eth0
6: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 40:aa:aa:aa:aa:aa brd ff:ff:ff:ff:ff:ff link-netnsid 0
root@ant [ ~ ]  ➜ ip route
root@ant [ ~ ]  ➜
1
2
3
4
5
root@bee [ ~ ]  ➜ ip addr show eth0
8: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 40:bb:bb:bb:bb:bb brd ff:ff:ff:ff:ff:ff link-netnsid 0
root@bee [ ~ ]  ➜ ip route
root@bee [ ~ ]  ➜
1
2
3
4
5
root@cicada [ ~ ]  ➜ ip addr show eth0
10: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 40:cc:cc:cc:cc:cc brd ff:ff:ff:ff:ff:ff link-netnsid 0
root@cicada [ ~ ]  ➜ ip route
root@cicada [ ~ ]  ➜

我们先为主机 ant 配置 IP 地址 192.168.1.1/24 :

1
root@ant [ ~ ]  ➜ ip addr add 192.168.1.1/24 dev eth0

/24 与拓扑图网段保持一致,表示该局域网网络号为 24 位,其余 8 位是主机号。

执行 ip 命令查看网卡信息,可以发现 IP 地址已经生效了:

1
2
3
4
5
root@ant [ ~ ]  ➜ ip addr show eth0
6: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 40:aa:aa:aa:aa:aa brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.1.1/24 scope global eth0
       valid_lft forever preferred_lft forever

此外,我们发现,系统自动在路由表中添加了一条路由规则:

1
2
root@ant [ ~ ]  ➜ ip route
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.1

由于我们为 eth0 网卡配置了 192.168.1.0/24 网段的地址,这意味着 eth0 直接连接网络 192.168.1.0/24 。因此,去往 192.168.1.0/24 网段的 IP 包,都可以通过 eth0 网络发往目标主机,这就是这条路由规则的由来。

同样,我们可以为主机 bee 配置 IP 地址:

1
2
3
4
5
6
7
8
root@bee [ ~ ]  ➜ ip addr add 192.168.1.2/24 dev eth0
root@bee [ ~ ]  ➜ ip addr show eth0
8: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 40:bb:bb:bb:bb:bb brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.1.2/24 scope global eth0
       valid_lft forever preferred_lft forever
root@bee [ ~ ]  ➜ ip route
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.2

配置完毕后,主机 ant 就可以通过 IP 协议与 bee 进行通信了。我们在主机 ant 上 ping 主机 bee ,网络已经通了:

1
2
3
4
5
6
root@ant [ ~ ]  ➜ ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=0.122 ms
64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=0.109 ms
64 bytes from 192.168.1.2: icmp_seq=3 ttl=64 time=0.211 ms
64 bytes from 192.168.1.2: icmp_seq=4 ttl=64 time=0.245 ms

主机 cicada 的配置方法也是类似的,不再赘述。当局域网所有主机都配置完毕,整个网络也就全通了。

双机网线直连

两台带以太网卡的主机,只需用一根网线连起来,即可通信。以下图为例:

主机 ant 和 bee 由一根网线连接,它们彼此间组成一个迷你以太网,只有两台主机接入。我们可以分配一个最小的网段 192.168.1.0/30 ,这个网段除了网络地址和广播地址,只有两个可供分配的主机地址。

实验环境由 docker 容器提供,只需执行以下 docker 命令,即可一键启动:

1
docker run --name cable-lab --rm -it --privileged --cap-add=NET_ADMIN --cap-add=SYS_ADMIN -v /data -h switch fasionchan/netbox:0.3 bash /script/cable-lab.sh

一开始,两台主机都没有配置任何 IP 地址,因此无法通过 IP 协议进行通信:

1
2
3
root@ant [ ~ ]  ➜ ip addr show eth0
5: eth0@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 16:8a:1f:f3:54:0a brd ff:ff:ff:ff:ff:ff link-netnsid 1
1
2
3
root@bee [ ~ ]  ➜ ip addr show eth0
4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 32:65:21:d3:01:2f brd ff:ff:ff:ff:ff:ff link-netnsid 0

我们依次为它们配置 IP 地址,方法与上节介绍的一样,这里不再赘述:

1
2
3
4
5
6
7
8
root@ant [ ~ ]  ➜ ip addr add 192.168.1.1/30 dev eth0
root@ant [ ~ ]  ➜ ip addr show eth0
5: eth0@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 16:8a:1f:f3:54:0a brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet 192.168.1.1/30 scope global eth0
       valid_lft forever preferred_lft forever
root@ant [ ~ ]  ➜ ip route
192.168.1.0/30 dev eth0 proto kernel scope link src 192.168.1.1
1
2
3
4
5
6
7
8
root@bee [ ~ ]  ➜ ip addr add 192.168.1.2/30 dev eth0
root@bee [ ~ ]  ➜ ip addr show eth0
4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 32:65:21:d3:01:2f brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.1.2/30 scope global eth0
       valid_lft forever preferred_lft forever
root@bee [ ~ ]  ➜ ip route
192.168.1.0/30 dev eth0 proto kernel scope link src 192.168.1.2

值得一提的是,这个场景我们采用了 /30 网段,因为本实验只有两台主机。

地址配置完毕后,这两台主机就可以互相 ping 通了:

1
2
3
4
5
6
root@ant [ ~ ]  ➜ ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=0.035 ms
64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=0.305 ms
64 bytes from 192.168.1.2: icmp_seq=3 ttl=64 time=0.107 ms
64 bytes from 192.168.1.2: icmp_seq=4 ttl=64 time=0.110 ms

在 U 盘等移动存储介质还不普及的年代,我们经常采用这种方式,在两台主机间拷贝数据。

双机网线直连②

双机直连的场景,我们甚至都不需要分配网段,只需在设置 IP 的同时记录对端地址。两台主机的 IP 甚至可以在不同网段,理论上任何 IP 都可以:

我们重新执行以下命令,启动一个全新的实验环境来演示该场景。我们先配置主机 ant :

1
root@ant [ ~ ]  ➜ ip addr add 192.168.1.1 dev eth0 peer 10.0.1.1

这个命令为 eth0 网络配置地址 192.168.1.1 ,并告诉系统对端 bee 的地址是 10.0.1.1 。

配置完毕后,我们可以看到网卡上的地址信息,以及系统自动添加的一条路由规则:

1
2
3
4
5
6
7
root@ant [ ~ ]  ➜ ip addr show eth0
5: eth0@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 16:8a:1f:f3:54:0a brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet 192.168.1.1 peer 10.0.1.1/32 scope global eth0
       valid_lft forever preferred_lft forever
root@ant [ ~ ]  ➜ ip route
10.0.1.1 dev eth0 proto kernel scope link src 192.168.1.1

路由规则表明,去往 10.0.1.1 的 IP 包,可以通过 eth0 网卡直接向目标主机发送。

同样地,我们为主机 bee 配置地址 10.0.1.1 并告诉它对端 ant 的地址是 192.168.1.1 :

1
2
3
4
5
6
7
8
root@bee [ ~ ]  ➜ ip addr add 10.0.1.1 dev eth0 peer 192.168.1.1
root@bee [ ~ ]  ➜ ip addr show eth0
4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 32:65:21:d3:01:2f brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.0.1.1 peer 192.168.1.1/32 scope global eth0
       valid_lft forever preferred_lft forever
root@bee [ ~ ]  ➜ ip route
192.168.1.1 dev eth0 proto kernel scope link src 10.0.1.1

两台主机都配置完毕后,它们就能 ping 通对方了:

1
2
3
4
5
6
root@ant [ ~ ]  ➜ ping 10.0.1.1
PING 10.0.1.1 (10.0.1.1) 56(84) bytes of data.
64 bytes from 10.0.1.1: icmp_seq=1 ttl=64 time=0.156 ms
64 bytes from 10.0.1.1: icmp_seq=2 ttl=64 time=0.109 ms
64 bytes from 10.0.1.1: icmp_seq=3 ttl=64 time=0.126 ms
64 bytes from 10.0.1.1: icmp_seq=4 ttl=64 time=0.105 ms

由于主机 ant 只有去往 10.0.1.1 的路由规则,我们 ping 任何其他 IP,都会收到 网络不可达 错误:

1
2
root@ant [ ~ ]  ➜ ping 10.0.1.2
ping: connect: Network is unreachable

主机 bee 也是类似的。

上网配置

下图是一个典型的家用局域网拓扑,路由器通过 ADSL 连接互联网,局域网内的网络设备则通过路由器上网。那么,对于接入这个局域网的一台主机,如何设置 IP 地址,才能上网呢?

现在,以上图中的 PC 为例,进行实验。执行下面这个 docker 命令一键启动实验环境,并进入 PC 命令行:

1
docker run --name host-gw-lab --rm -it --privileged --cap-add=NET_ADMIN --cap-add=SYS_ADMIN -v /data -h switch fasionchan/netbox:0.3 bash /script/host-gw-lab.sh

PC 通过 eth0 网卡连接局域网,刚开始时网卡还没配置 IP 地址:

1
2
3
root@netbox [ ~ ]  ➜ ip addr show eth0
6: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 5a:ff:7e:28:81:bc brd ff:ff:ff:ff:ff:ff link-netnsid 0

因此,这时 PC 无法 ping 通局域网中的其他设备,比如路由;更别说访问公网服务了:

1
2
3
4
root@netbox [ ~ ]  ➜ ping 192.168.1.1
ping: connect: Network is unreachable
root@netbox [ ~ ]  ➜ ping 223.5.5.5
ping: connect: Network is unreachable

223.5.5.5 是一个公网 IP ,运行着阿里提供的公共 DNS 服务。

我们先执行 ip 命令,为 eth0 网络配置一个局域网 IP 地址。如无意外,PC 就可以访问局域网中的其他设备了:

1
2
3
4
5
6
7
root@netbox [ ~ ]  ➜ ip addr add 192.168.1.2/24 dev eth0
root@netbox [ ~ ]  ➜ ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.265 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.096 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=0.105 ms
64 bytes from 192.168.1.1: icmp_seq=4 ttl=64 time=0.095 ms

请注意,选用的 IP 地址必须与局域网在同一个网段,而且不能与其他设备冲突。本实验按照拓扑图中的标注进行配置即可。

那么,IP 地址配置好后,是不是就可以访问公网了呢?

1
2
root@netbox [ ~ ]  ➜ ping 223.5.5.5
ping: connect: Network is unreachable

显然不是。我们 ping 公网地址时,ping 命令报 网络不可达 错误。这是为什么呢?

PC 路由表一开始是空的,我们为 eth0 配置好 IP 地址后,系统自动添加了一条直接路由,用于访问局域网:

1
2
root@netbox [ ~ ]  ➜ ip route
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.2

这条路由的意思是,去往 192.168.1.0/24 这个网段的 IP 包,可以通过 eth0 网卡,直接发到目标设备。由于 223.5.5.5 不在这个这个网段内,系统也就不知道该如何处理发给它的 IP 包,这也是 ping 命令报错的原因。

为了访问互联网,我们为 PC 添加一条默认路由,以路由器 192.168.1.1 为下一跳:

1
2
3
4
root@netbox [ ~ ]  ➜ ip route add default via 192.168.1.1
root@netbox [ ~ ]  ➜ ip route
default via 192.168.1.1 dev eth0
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.2

有了这条默认路由,如果一个 IP 包未命中其他任何路由规则,默认将发给路由器 192.168.1.1 ,由它负责转发。这样一来,去往 223.5.5.5 的 IP 包,系统将发给路由器 192.168.1.1 ,路由器则接力将包发送到互联网。

有了默认路由之后,我们就可以 ping 通公网 IP 223.5.5.5 了:

1
2
3
4
5
6
root@netbox [ ~ ]  ➜ ping 223.5.5.5
PING 223.5.5.5 (223.5.5.5) 56(84) bytes of data.
64 bytes from 223.5.5.5: icmp_seq=1 ttl=36 time=20.5 ms
64 bytes from 223.5.5.5: icmp_seq=2 ttl=36 time=21.8 ms
64 bytes from 223.5.5.5: icmp_seq=3 ttl=36 time=16.2 ms
64 bytes from 223.5.5.5: icmp_seq=4 ttl=36 time=18.4 ms

小菜学网络】系列文章首发于公众号【小菜学编程】,敬请关注:

【小菜学网络】系列文章首发于公众号【小菜学编程】,敬请关注: