Linux网络设置高级指南

mallon 发布于 2013/07/05 10:57
阅读 2K+
收藏 29

Linux网络设置高级指南

本文面向的是被Linux复杂的有线无线网络架构弄得头昏脑胀;或者被网上半吊子的教程弄得晕头转向;或者厌倦了Network Manager之类图形界面无穷尽的BUG(很多抄袭的是Windows,画虎不成反类猫,在一些概念上就存在错误);或者想要了解一些技术细节的,像一样我渴望获得完全驾驭的能力而不是隔靴搔痒的人。

本文需要一定的计算机网络和Linux基础,其中的大部分内容很新,基于2.6内核之后的新架构。

Linux不同发行版的软件包名称、配置文件的命名和位置都不尽相同,本文基于的是Debian/Ubuntu系统,很多内容参考了Debian Reference的第5章。

当然,本文依旧有很多不足之处,例如没有深入到Linux内核机制中去,这就需要以后进一步完善了。

静态设置

静态设置的意思是所有配置都写在配置文件中,由操作系统自动进行设置。

静态设置依赖udev、ifupdown、isc-dhcp-client、resolvconf、wireless-tools、wpasupplicant等软件包。

首先,网络的正常运行依赖于硬件设备。在系统引导或者热插拔的时候,内核通过udev将网络设备映射到用户空间的sysfs虚拟文件系统。例如:

root@X230:/sys/class/net# ls -l
总用量 0
lrwxrwxrwx 1 root root 0  7月  4 15:01 eth0 -> ../../devices/pci0000:00/0000:00:19.0/net/eth0
lrwxrwxrwx 1 root root 0  7月  4 15:00 lo -> ../../devices/virtual/net/lo
lrwxrwxrwx 1 root root 0  7月  4 15:01 wlan0 -> ../../devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlan0

可以看到,系统当前存在三个网络设备:lo为回环设备;eth0为有线网卡;wlan0为无线网卡。遵循Unix“一切皆文件”的思想,其它工具都是直接或者间接地修改这些虚拟文件来达到设置目的的。

/etc/network/interfaces文件记录了所有的静态配置信息。内核在引导的时候,会自动启动标志为“auto”的设备,例如:

auto lo
auto eth0
auto wlan0

而如果设备标志为“allow-hotplug”,那么内核在检测到热插拔事件的时候,也会自动启动。例如:

allow-hotplug lo
allow-hotplug eth0
allow-hotplug wlan0

因为回环设备始终应该是存在的,所以/etc/network/interfaces文件的内容至少是:

auto lo
iface lo inet loopback

内核启动网络设备调用的是ifupdown工具,而ifupdown工具也是依赖于/etc/network/interfaces配置文件的。

对于有线(Wired)设备,物理层和数据链路层无须操作系统干预,网卡根据CSMA/CD协议就能够自行设置,所以/etc/network/interfaces文件只需包含网络层以上的配置信息,例如IP地址、子网掩码、默认网关等。例如:

iface eth0 inet static
    address 192.168.11.100
    netmask 255.255.255.0
    gateway 192.168.11.1

“默认网关”其实是路由的概念,在这里作为设备的一个属性,和IP地址子网掩码放在一起我觉得很不妥,很容易误导初学者,尤其是存在多网卡多IP地址的情况。

对于DNS,首先需要注意的是它属于应用层协议,和网络设备以及网络层并无直接联系。传统上Linux的DNS配置文件为/etc/resolv.conf,一行一个服务器IP地址。例如:

nameserver 218.2.135.1
nameserver 61.147.37.1

如果安装了resolvconf工具,那么DNS的配置会被接管,此时/etc/resolv.conf就变成了一个符号链接,链接到了resolvconf运行时候动态维护的一个文件。在这种情况下,DNS的配置也可以写到/etc/network/interfaces文件中了,例如:

iface eth0 inet static
    address 192.168.11.100
    netmask 255.255.255.0
    gateway 192.168.11.1
    dns-nameservers 218.2.135.1 61.147.37.1

ifupdown工具会自动调用resolvconf完成DNS设置。

此处我也甚觉不妥,因为上面讲过,DNS是应用层的概念,这样写的话让初学者觉得好像DNS是网络设备的属性一样(传统Linux还真是有很多不足之处)。

如果安装了isc-dhcp-client工具,那么/etc/network/interfaces文件中就可以直接配置DHCP,例如:

iface eth0 inet dhcp

isc-dhcp-client有自己的配置文件,可以控制从DHCP服务器上获取哪些信息(例如DNS服务器地址)。

ifupdown工具会自动调用isc-dhcp-client完成DHCP设置。

此处需要注意的是:不论resolvconf是否存在,dhclient均会直接修改/etc/resolv.conf文件(不管它是不是一个链接),不过一般情况下也没有什么问题。

对于无线(Wireless)设备,工作方式和有线设备有很大的不同(不是插上网线就能直接用的)。数据链路层的连接必须由操作系统协同完成,例如连接哪个SSID、使用哪条信道、采用什么认证方式(WEP、WPA...)。这些链路层配置信息也可以写到/etc/network/interfaces文件中以供ifupdown工具使用。

iface ath0 inet dhcp
    wpa-ssid homezone
    wpa-psk 密码

ifupdown工具会自动调用wpasupplicant完成WPA设置。

例如WEP的配置:

iface eth0 inet dhcp
    wireless-essid Home
    wireless-key1 0123-4567-89ab-cdef
    wireless-key2 12345678
    wireless-key3 s:password
    wireless-defaultkey 2
    wireless-keymode open

ifupdown工具会自动调用wireless-tools完成WEP设置。

准静态设置

静态设置适合于网络环境固定的情况,例如服务器、办公室电脑等。如果网络环境经常有变动,但是变动都是已知的,那么可以在/etc/network/interfaces文件中写入不固定的网络配置,这些配置不对应到具体的硬件设备名,例如:

iface config1 inet dhcp

iface config2 inet static
    address 192.168.11.100
    netmask 255.255.255.0
    gateway 192.168.11.1
    dns-domain example.com
    dns-nameservers 192.168.11.1

可以手工运行ifupdown工具切换配置,例如将eth0切换到config1:

ifup eth0=config1

将eth0切换到config2:

ifdown eth0=config1
ifup eth0=config2

动态设置

如果网络环境经常变动而且是未知的,或者为了使用脚本等自动化工具达到完全驾驭网络的能力,那么静态和准静态设置就捉襟见肘了。

动态设置依赖iproute、isc-dhcp-client、wireless-tools、wpasupplicant等软件包,直接使用命令行,以达到最大的灵活性。

首先,/etc/network/interfaces文件仅保留回环设备lo的配置信息:

auto lo
iface lo inet loopback

iproute替代了过时的net-tools等工具(ifconfig)。

通过“ip link”命令可以查询到当前所有网络设备的状态和参数,例如:

root@X230:~# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
    link/ether 3c:97:0e:6d:e9:7c brd ff:ff:ff:ff:ff:ff
3: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
    link/ether 84:3a:4b:5b:7b:c8 brd ff:ff:ff:ff:ff:ff

可以看到当前eth0和wlan0设备都是处于关闭状态(这是显然的,因为/etc/network/interfaces文件中已经没有它们的配置信息了)。

使用“ip link set 设备名 up”命令可以启动设备,使用“ip link set 设备名 down”命令可以关闭设备。

对于有线(Wired)设备,上面讲过,无须做额外设置,链路层就可以正常工作了。

对于无线(Wireless)设备,需要使用wireless-tools、wpasupplicant完成链路层的连接。

例如扫描当前可用都无线连接,可以使用wavemon工具,或者使用“iwlist scan”命令。

例如连接Ad-Hoc。双方的essid、channel、cell(也就是iwconfig中的ap)均必须一致。双方创建连接谁先谁后都没有关系。例如:

iwconfig wlan0 mode ad-hoc essid test channel 7 ap 0E:0E:0A:3A:10:3B key off

以上命令即刻生效。

例如连接WEP认证的无线网络:

iwconfig wlan0 essid "myhome" key 0123-4567-89

如果要连接WPA认证的无线网络,wireless-tools就无可奈何了,必须使用wpasupplicant。

wpasupplicant并不是像wireless-tools一样简单地用命令行配一配就可以了,它必须先启动一个服务进程,然后使用另外一个命令行工具对服务进程进行设置,而且在WIFI连接期间该服务进程必须始终运行着。

为什么不和wireless-tools做在一起呢?真怪异,真恶心!

服务进程可以以后台方式启动,也可以以前台方式启动。

后台方式:

wpa_supplicant -i wlan0 -D nl80211,wext -s -B -P /var/run/wpa_supplicant.wlan0.pid -C /var/run/wpa_supplicant

其中:-i指定设备名;-D指定认证协议;-s -B指定在后台运行,并且调试输出到syslog中;-C参数指定“ctrl_interface”的位置,注意,wpa_supplicant是可以有配置文件的,而且配置文件中可以记录WIFI的静态配置,类似于/etc/network/interfaces的功能,但是我们这里用不到,在没有配置文件的情况下,“ctrl_interface”是必不可少的,wpa_cli通过它与之交互。

前台方式:

wpa_supplicant -i wlan0 -D nl80211,wext -dd -P /var/run/wpa_supplicant.wlan0.pid -C /var/run/wpa_supplicant

其中,-dd表示输出更详细的调试信息。

然后使用wpa_cli进行设置。wpa_cli可以工作在交互模式,也可以命令行模式。例如在交互模式下执行如下命令加入并启用网络:

> add_network
0
> set_network 0 ssid "ChinaUnicom-Me"
OK
> set_network 0 key_mgmt WPA-PSK
OK
> set_network 0 psk "密码"
OK
> enable_network 0
OK

到上面为止,无论是有线网络还是无线网络,链路层已经连通了。下面就要使用iproute等工具进行网络层的设置。

如果要设置DHCP,很简单。例如:

dhclient wlan0 -r
dhclient wlan0

如果要手工设置地址,那么,例如:

ip address add 192.168.1.3/24 dev wlan0
ip route add default via 192.168.1.1 dev wlan0

第一行增加IP地址,第二行设置默认路由。

最后,使用文本编辑器或者脚本修改/etc/resolv.conf的DNS设置,例如:

echo nameserver 221.6.4.66 > /etc/resolv.conf

搞定,可以使用iwconfig和ifconfig查看当前设置。例如:

iwconfig wlan0 && ifconfig wlan0

现在,写脚本就游刃有余了,例如下面就是我的笔记本电脑在家里的设置脚本:

#!/bin/sh

echo 清理工作
sudo killall wpa_supplicant
sudo ip link set eth0 down
sudo ip link set wlan0 down
sudo ip addr flush eth0
sudo ip addr flush wlan0

echo 启用wlan0
sudo ip link set wlan0 up

echo 链路层连接
sudo wpa_supplicant -i wlan0 -D nl80211,wext -s -B -P /var/run/wpa_supplicant.wlan0.pid -C /var/run/wpa_supplicant
sudo wpa_cli add_network
# 注意单引号套双引号
sudo wpa_cli set_network 0 ssid '"ChinaUnicom-Me"'
sudo wpa_cli set_network 0 key_mgmt WPA-PSK
sudo wpa_cli set_network 0 psk '"........"'
sudo wpa_cli enable_network 0

echo 网络层设置:IP地址和默认路由
sudo ip addr add 192.168.1.3/24 dev wlan0
sudo ip route add default via 192.168.1.1 dev wlan0

echo DNS设置
# 此处不能使用>符号,否则权限不够
sudo echo nameserver 221.6.4.66 | sudo tee /etc/resolv.conf
加载中
1
mallon
mallon

引用来自“chape”的答案

好文没人顶?
估计大部分人都看不懂或者不感兴趣,哈哈
chape
chape
现在做云的网络知识少不了,之前搭建openstack的时候就很多网络不太懂
0
chape
chape
好文没人顶?
0
0
daleshen128
daleshen128
我靠,这都算高级啦?
0
dongyado
dongyado
现在还用不着  收藏以后用
0
算法与编程之美
算法与编程之美

up

很实用,行文很流畅,看起来舒服!

0
dreamers
dreamers
非常不错。
0
刘占军
能保存到本地就好了,先收藏了
返回顶部
顶部