[ 上一页 ] [ 目录 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] [ 11 ] [ 12 ] [ 13 ] [ 14 ] [ 15 ] [ A ] [ 下一页 ]


Debian 参考手册
第 10 章 - 网络设置


这一章重点在于 Debian 的网络管理。请阅读 Net-HOWTO 来了解一般 GNU/Linux 的网络设置。

为了让 Debian 主机能够访问 Internet,它的网络接口需要被正确的设置。

首先要确认内核支持这个设备,例如以太网卡、无线网卡(Wi-Fi)和调制解调器。为了获得这些支持,你可能需要重新编译内核或者给内核增加模块,如 Debian 下的 Linux 内核, 第 7 章 中描述的。

下面说明如何设置网络设备。这些信息都已经针对 Sarge 做了更新,大多数的内容都不适用于早期的发行版本。


10.1 IP 网络设置基础

一个 Debian 主机可能有很多有不同 Internet 协议(IP)地址的网络接口。接口可能有很多种,如:

其他可用的网络设备还有很多,包括 SLIP、PLIP(串行和并行 IP)、控制某种网络接口流量的“shaper”设备、帧中继、AX.25、X.25、ARCnet 和 LocalTalk。

每个直接连接到 Internet(或任何基于 IP 的网络)的网络接口都用唯一的 32 位的 IP 地址来识别。 [52] IP 地址可分为网络地址和主机地址两个部分。如果你拿到一个 IP 地址,把网络地址部分全部设为 1,而主机地址部分全部设为 0,则你将得到这个网络的子网掩码。

传统意义上,IP 网络按照网络地址的长度分为 8、16、24 位三个组别。这个系统缺乏灵活性,浪费了很多 IP 地址,所以现在的 IPv4 网络是由可变长度的网络号来分配的。

               IP addresses                   net mask      length
     Class A   1.0.0.0     - 126.255.255.255  255.0.0.0     =  /8
     Class B   128.0.0.0   - 191.255.255.255  255.255.0.0   = /16
     Class C   192.0.0.0   - 223.255.255.255  255.255.255.0 = /24

IP 地址不在这个范围内的被用作特殊目的。

每一个组别中都有保留给本地网络(LANs)使用的地址范围。这些地址不会和 Internet 上的发生冲突。(同理,如果主机被分配到这类地址的话,这些主机就不能直接访问 Internet,需要通过一个作为代理的网关或网络地址转换服务(NAT)才能访问 Internet。)这些地址范围在下表中列出,包含每个组别中这些地址范围的数目。

               network addresses            length  how many
     Class A   10.x.x.x                     /8      1
     Class B   172.16.x.x -  172.31.x.x     /16     16
     Class C   192.168.0.x - 192.168.255.x  /24     256

IP 网络中 IP 地址的第一个值就是网络本身,最后一个值是该网络的广播地址。 [53] 其余所有的 IP 地址都可以分配给网络中的主机。通常 IP 地址的第一个和最后一个都会留给该网络的 Internet 网关。

路由表包含了关于内核如何把 IP 包发送到它们目的地的信息。这儿有一个位于本地网络(LAN),IP 地址为 192.168.50.x/24 的 Debian 主机的路由表。另一台主机 192.168.50.1(也在 LAN 中)是公司网络 172.20.x.x/16 的路由器,主机 192.168.50.254(也在 LAN 中)是负责访问 Internet 的路由器。

     # route
     Kernel IP routing table
     Destination   Gateway        Genmask       Flags Metric Ref Use Iface
     127.0.0.0     *              255.0.0.0     U     0      0     2 lo
     192.168.50.0  *              255.255.255.0 U     0      0   137 eth0
     172.20.0.0    192.168.50.1   255.255.0.0   UG    1      0     7 eth0
     default       192.168.50.254 0.0.0.0       UG    1      0    36 eth0

路由表中的 IP 地址也可以用名称表示,这些名称从 /etc/networks 或通过 resolver(C Library)来获得。

除了路由之外,内核能实现网络地址转换(NAT)、流量控制和包过滤。

参阅 Net-HOWTOother networking HOWTOs 来了解背后运行的原理。


10.2 底层网络设置

GNU/Linux 上传统的底层网络设置工具是 ifconfigroute,它们在 net-tools 这个软件包中。目前这些工具被软将包 iproute 中的 ip 代替。ip 可以在 Linux 2.2 或更新的内核上运行,有着比老的工具更好的兼容性。然而,这些传统的设置工具还是能用的而且大家也更加熟悉。


10.2.1 底层网络设置 – ifconfigroute

下面演示如何把网络接口 eth0 的 IP 地址从 192.168.0.3 改为 192.168.0.111;设置 eth0 的路由,通过 192.168.0.1 访问 10.0.0.0 这个网络。 执行 ifconfiroute 时不带网络接口参数,则显示所有网络接口和路由的现状。

     # ifconfig
     eth0 Link encap:Ethernet  HWaddr 08:00:46:7A:02:B0
          inet addr:192.168.0.3  Bcast:192.168.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:23363 errors:0 dropped:0 overruns:0 frame:0
          TX packets:21798 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100
          RX bytes:13479541 (12.8 MiB)  TX bytes:20262643 (19.3 MiB)
          Interrupt:9
     
     lo   Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:230172 errors:0 dropped:0 overruns:0 frame:0
          TX packets:230172 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:22685256 (21.6 MiB)  TX bytes:22685256 (21.6 MiB)
     # route
     Kernel IP routing table
     Destination  Gateway      Genmask          Flags Metric Ref Use Iface
     192.168.0.0  *            255.255.0.0      U     0      0     0 eth0
     default      192.168.0.1  255.255.255.255  UG    0      0     0 eth0

首先我们关闭网络接口。

     # ifconfig eth0 inet down
     # ifconfig
     lo   Link encap:Local Loopback
       ... (没有 eth0 这个条目了)
     # route
       ... (没有路由表了)

接下来我们启动 eth0 并给予其新的 IP 地址和路由。

     # ifconfig eth0 inet up 192.168.0.111 \
                netmask 255.255.255.0 broadcast 192.168.0.255
     # route add -net 10.0.0.0 netmask 255.0.0.0 gw 192.168.0.1 dev eth0

结果是:

     # ifconfig
     eth0 Link encap:Ethernet  HWaddr 08:00:46:7A:02:B0
          inet addr:192.168.0.111  Bcast:192.168.0.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          ...
     
     lo   Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          ...
     # route
     Kernel IP routing table
     Destination  Gateway      Genmask        Flags Metric Ref Use Iface
     192.168.0.0  *            255.255.255.0  U     0      0     0 eth0
     10.0.0.0     192.168.0.1  255.0.0.0      UG    0      0     0 eth0

更多信息请参阅 ifconfig(8)route(8).


10.2.2 底层网络设置 – ip

ip 和先前的 ifconfigroute 有相同功能的命令如下:

运行的时候使用 help 参数,能让 ip 打印出命令的语法。 例如,ip link help 打印出:

     Usage: ip link set DEVICE { up | down | arp { on | off } |
                          dynamic { on | off } |
                          multicast { on | off } | txqueuelen PACKETS |
                          name NEWNAME |
                          address LLADDR | broadcast LLADDR |
                          mtu MTU }
            ip link show [ DEVICE ]

参阅 ip(8).


10.2.3 设置无线网卡(Wi-Fi)接口

对于无线网卡(Wi-Fi)接口,除了 ifconfigip 之外,你还需要 iwconfig 这个程序。此程序在 wireless-tools 中。

参阅 iwconfig(8).


10.2.4 设置 PPP 接口

如果你是通过连接在拨号电话机上的调制解调器,并使用 Point-to-Point 协议 (PPP) 来上网的。那么这样的网络连接就是通过 ppp0ppp1 等网络接口来实现的。

PPP 接口是由 pppd 这个 PPP 服务来管理的。你可以在 ppp 中找到该程序。 所以,对于用户来说,设置 PPP 接口也就是对 pppd 进行设置。


10.2.4.1 手动设置 pppd

为了建立网络连接,我们需要打开一个通讯端口(通常是串口),需要把命令传输到通讯设备上(通常是调制解调器),需要拨某个电话号码,对于外部的 PPP 服务还需要进行身份验证,需要内核创建 PPP 接口,最后需要修改路由表。只有这样信息才能在这条连接上传递。 pppd 能完成上述所有动作,因而会有一堆的设置参数。相关参数参见 pppd(8)

在 Debian 系统上,全局的设置在 /etc/ppp/options 里面。用户的特定设置放在 ~/.ppprc。依赖于通讯端口的设置全部在 /etc/ppp/options.partname。例如,假设你有两个调制解调器 —通过 /dev/LT-modem 来访问的内置 Lucent LT 调制解调器和通过 /dev/ttyS0 来访问的外置调制解调器。 建立以下这两个文件。

     # cat > /etc/ppp/options.LT-modem <<EOF
     115200
     init "/usr/sbin/chat -f /etc/chatscripts/setup-LT-modem"
     EOF
     # cat > /etc/ppp/options.ttyS0 <<EOF
     115200
     init "/usr/sbin/chat -f /etc/chatscripts/setup-ttyS0"
     EOF

这些涉及到下面的 chat scripts。 首先,/etc/chatscripts/setup-LT-modem

     ABORT ERROR
     '' ATZ
     OK 'ATW2X2 S7=70 S11=55'
     OK AT

其次,/etc/chatscripts/setup-ttyS0

     ABORT ERROR
     '' ATZ
     OK 'ATL1M1Q0V1W2X4&C1&D2 S6=4 S7=70 S11=55 S95=63 S109=1 +FCLASS=0'
     OK AT

显然,这些文件的内容依赖于你的硬件。

选项也可以被当为参数传递给 pppd

在 Debian 中通常用 pon 来启动 pppdpon 使用的时候,它的第一个参数表示位于 /etc/ppp/pears/ 里面的配置文件的名称,这个文件同样也被 pppd 读取。 [54] 这儿就是你为特定连接设置特殊选项的地方 — 例如,一个特别的网络服务提供商(ISP)。

假设你往来于 Amsterdm 和 Den Haag 这两座城市。在每个城市,你要求能访问两个 ISP 服务— Planet 和 KPN。首先为每个 ISP 创建基本的配置文件。

     # cat > /etc/ppp/peers/KPN <<EOF
     remotename KPN
     noauth
     user kpn
     noipdefault
     ipparam KPN
     EOF
     # cat > /etc/ppp/peers/Planet <<EOF
     remotename Planet
     auth
     user user3579@planet.nl
     noipdefault 
     mru 1000
     mtu 1000
     ipparam Planet
     EOF

这些文件设置了两个 ISPs 中不同的部分。相同的部分可以放在 /etc/ppp/options 或于接口有关的某个设置文件中。

现在为每个城市里的每个 ISP 创建配置文件。在我们的例子中,从一个城市连接某个 ISP 和从另外一个城市连接这个 ISP 唯一的差别就是所需要的 chatscript。(chatscript 不同是因为当地访问的电话号码不同。)

     # cat > /etc/ppp/peers/KPN-Amsterdam <<EOF
     connect "/usr/sbin/chat -v -f /etc/chatscripts/KPN-Amsterdam"
     file /etc/ppp/peers/KPN
     EOF
     # cat > /etc/ppp/peers/KPN-DenHaag <<EOF
     connect "/usr/sbin/chat -v -f /etc/chatscripts/KPN-DenHaag"
     file /etc/ppp/peers/KPN
     EOF
     # cat > /etc/ppp/peers/Planet-Amsterdam <<EOF
     connect "/usr/sbin/chat -v -f /etc/chatscripts/Planet-Amsterdam"
     file /etc/ppp/peers/Planet
     EOF
     # cat > /etc/ppp/peers/Planet-DenHaag <<EOF
     connect "/usr/sbin/chat -v -f /etc/chatscripts/Planet-DenHaag"
     file /etc/ppp/peers/Planet
     EOF

file 命令显示了各个配置,包括先前列出过的配置。connetc 命令详细说明了 pppd 用来建立连接需要的特殊参数。我们通常使用 chat 这个程序来做这些事情,使 chatscript 适合这个 ISP。这里是给 Den Haag 的 chatscripts;给 Amsterdam 用的 chatscripts 也类似,除了电话号码不一样。不过当这个 ISP 通过本地的其他公司来提供服务的话,也许 chatscripts 就有所区别了。

     # cat > /etc/chatscripts/KPN-DenHaag <<EOF
     ABORT BUSY
     ABORT 'NO CARRIER'
     ABORT VOICE
     ABORT 'NO DIALTONE'
     ABORT 'NO DIAL TONE'
     ABORT 'NO ANSWER'
     ABORT ERROR
     OK-AT-OK ATDT 0676012321
     CONNECT \d\c
     EOF
     # cat > /etc/chatscripts/Planet-DenHaag <<EOF
     ABORT BUSY
     ABORT 'NO CARRIER'
     ABORT VOICE
     ABORT 'NO DIALTONE'
     ABORT 'NO DIAL TONE'
     ABORT 'NO ANSWER'
     ABORT ERROR
     OK-AT-OK ATDT 0676002505
     CONNECT \d\c
     EOF

为了能连接上这些 ISP,你需要用户名和密码以便让 pppd 在需要的时候能提供这些资料。这些信息不是被存储在 /etc/ppp/pap-secrets(如果使用 PAP 协议)就是在 /etc/ppp/chap-secrets(如果使用 CHAP 协议)。虽然 CHAP 更加的安全,但是 PAP 仍然是使用最为广泛的。因为这些文件包含有“秘密”,所以群组和其他用户应该不被允许读写这些文件。这些文件的格式在 pppd(8) 中有解释。“秘密”(第三格)是通过用户名(第一格)和/或服务器名称(第二格)来查找的。当连接到一个 ISP 时通常是不知道这个服务器的名字的,所以我们用用户名代替;上面 peers/KPNpeers/Planet 中的 user 那一行就是完成这个动作的。

     # client name       server name  secret
     kpn                 *            kpn
     user3579@planet.nl  *            myfavoritepet

详细信息,参阅 /usr/share/doc/ppp/README.Debian.gz


10.2.4.2 使用 pppconfig 设置 pppd

一个快速设置 pppd 方法就是使用 pppconfig 程序,该程序来自同名的软件包。pppconfig 先使用菜单界面来询问使用者一些问题,然后设置上面提到过的这些文件。


10.2.4.3 使用 wvdial 设置 PPP 接口

另一种使用 pppd 的处理方法是从 wvdial 来运行 pppdwvdial 在软件包 wvdial 中。不同于 pppd 使用 chat 来拨号和协商连接,wvdial 在完成拨号和初始化协商之后才运行 pppd 去完成剩余的工作。只要给出电话号码、用户名和密码,大多数情况下,wvdial 都能成功建立连接。


10.3 命名主机


10.3.1 主机名

主机名是由内核维护的。初始化脚本 /etc/init.d/hostname.sh 在系统启动的时候根据 /etc/hostname 中存储的名称设置主机名(使用 hostname 这个命令)。这个文件应该包含系统的主机名,而不是完整的域名。

运行 hostname(不带任何参数)可以打印出当前的主机名。


10.3.2 邮件名

主机的邮件名是于邮件相关的程序用来确认主机的。/etc/mailname 包含了该名称并以新空行结尾。邮件名通常是主机的完整的域名之一。参阅 mailname(5)

电子邮件接受者看到的你这台 Debian 主机发送的邮件信头 From: 的内容,取决于你机器上邮件用户代理(MUA)和邮件传输代理(MTA)的设置。假设本地用户 foo 从邮件名为 myhost.dom 的主机上发送了一封邮件。送出去的电子邮件的信头 From: 会是:

就算 MUA 中设置了 From:,MTA 还是会加入"Sender:foo@herman.dom" 来表示真正的来源 。

当然,任何复杂的 MTA 在执行地址重写的时候,如同在 Exim 下设置一个收集不存在的邮件地址的容器, 第 9.6.1.3 节在 Exim 下设置寄出邮件的地址重写, 第 9.6.1.4 节中讨论的,收件者看到的邮件地址是可以任意改变的。


10.4 域名服务(DNS)

主机由域名和 IP 地址来查询。DNS 是一套客户端-服务器系统,在这套系统中域名解释器访问域名服务器从而把域名和 IP 地址或是其他合适的主机联系在一起。 GNU C Library resolver(3) 也能够在文件中或通过网络信息服务(NIS)来查找 IP 地址。

某些程序(如,GNOME)就希望主机名能被解析为一个 IP 地址并且拥有一个合法的域名。这样真的是非常不合适的,因为主机名和域名是两个完全不同的的东西。为了支持这些软件,我们需要确保系统主机名能够被解析。通常的做法就是在 /etc/hosts 中加入一行带有 IP 地址和系统主机名的内容。如果你的系统有一个永久的 IP 地址,那就用这个地址,否则使用 127.0.0.1 这个地址。

        127.0.0.1 localhost
        127.0.1.1 uranus

使用 hostname --fqdn 来查看你的系统的主机名能否被解析为一个 IP 地址并拥有一个有效的域名。


10.4.1 域名解析器

域名解析器的工作是查找某个域名所对应的 IP 地址。大部分常用的域名解析器是 GNU C Library 中的 resovler 提供的功能(resolver(3))。另一个是由 libfiredns 软件包提供的 FireDNS resolver。还有其他的。

GNU LIBC 的域名解析器对域名的解析是由 /etc/nsswitch.conf 中的 hosts 这一行配置决定的。该行列出了解析域名用的服务:例如 dnsfilesnisnisplus。参阅 nsswitch.conf(5)。 即使在使用 files 的情况下,域名解析器的行为也是由 /etc/hosts 这个配置文件控制的。参阅 hosts(5)

上述文件都是静态的,你可以用你喜欢的编辑器修改。

在使用 dns 服务的情况下,域名解释器的行为也是由 /etc/resolv.conf 这个配置文件控制的。参阅 resolv.conf(5)resolv.conf 的一个重要功能就是提供一个域名服务器的 IP 地址列表,通过查询这些服务器来获得域名解析。这一列表常常依赖于网络环境,而且在你机器运行的时候,网络环境时常发生变化。pppddhclient 这类程序都能添加或删除 resolv.conf 中的信息。但是这些功能不是每次都能正常工作而且两者还会有冲突。软件包 resolvconf 采用了更好的方法解决了这个问题,并提供了一个标准的框架来更新 resolv.conf。参阅管理域名服务器信息 – resolvconf, 第 10.4.2 节


10.4.2 管理域名服务器信息 – resolvconf

软件包 resolvconf 提供了一个框架,能动态的管理关于可用域名服务器的信息。它解决了长久以来如何维护一个给域名解析器和 DNS 缓存使用的动态的域名服务器列表的问题。Resolvconf 把它自己设为控制网络接口和提供域名服务信息的程序与需要域名服务信息的应用程序的中间媒介。

resolvconf 被设计成不需要任何手动设置就能工作。但是,这个软件包还是很新的,可能需要一些手工的干预才能正常的工作。如果你曾经定制过软件包,而且它们更新了 /etc/resolv.conf 的话:你就需要去掉这部分定制。更多信息参阅 /usr/share/doc/resolvconf/README.gz


10.4.3 缓存查询过的域名 – nscddnsmasqpdnsdbind9

如果你的域名服务器响应速度非常慢,你可能需要使用 nscd 来缓存域名解析器 libc6 查询到的结果。

如果你希望为你本地网络中的其他主机缓存结果的话,你可能要去运行一个缓存转发域名服务器(caching forwarding nameserver)。就像 dnsmasqpdnsd

如果你愿意,你也可以用软件包 bind9 中的 named 来做缓存转发域名服务器(caching forwarding nameserver)。但是这是一个很庞大的程序,除非你需要它高级功能,否则还是使用上面提到的那些程序比较好。

所有这些软件包都能和 resolvconf 一起工作。


10.4.4 提供域名解析服务 – bind

如果你希望给一个域提供一个权威的域名服务的话,你就需要一个完善的域名服务器,例如软件包 bind9 中的 named

如果你安装了 bind9,你也应该安装 dnsutils。 你可能还需要安装这样一些工具软件包: bind9-hostdns-browsednscvsutilnslint。 你可能还需要安装说明文档: bind9-doc。 你可能还需要安装开发文档: libbind-devlibnet-dns-perl。 如果你是使用 DHCP,下面这个软件包会对你有所帮助: dhcp-dns

安装 bind9 或者用 dpkg-reconfigure bind9 来进行基本的设置。设置包括编辑文件 name。在 Debian 中,你可以在 /etc/bind/ 找到这个文件,它主要是用来设置基本的 DNS 域的;它包含了其他两个文件: named.conf.local,用来定义本地区域,和 named.conf.options,用来设置选项的。(后者的执行需要 resolvconf 来产生 /var/run/bind/named.options 文件,除了 forwarders 的说明是一个当前可用的非本地域名服务器列表之外,其余都和原先的一样。要利用这个,可以修改 named.conf 中的 include 这一样,使其包含 /var/run/bind/named.options。参阅管理域名服务器信息 – resolvconf, 第 10.4.2 节。)

named.conf* 文件中用到的数据库文件,如果没有指定完整的路径,则该数据库文件会被存储在 /var/cache/bind/。这是一个正确的存储 named 产生的文件的地方。例如:某个域的从服务器使用的数据库文件。/etc/bind/ 下面的那些静态的数据库文件,需要在 named.conf 中有完整的路径才能被找到。详情参阅 /usr/share/doc/bind9/README.Debian.gz


10.5 使用 DHCP 来配置网络接口

底层的网络接口设置可以用 Dynamic Host Configuration Protocol (DHCP) 来自动设置。你的防火墙或路由器或宽带 ISP 可能用这个方法来配置 IP 地址和其他参数。

要做这个工作你必须安装下列软件包的其中一个:

pump 简易且被广泛应用。 dhcp3-client 复杂,但是可配置程度更高。 [55]


10.6 Debian 的高级网络设置


10.6.1 使用 ifupdown 进行高级网络设置

为了让网络设置更加简单,Debian 提供了一个标准的高级网络设置工具,包含 ifupifdown 程序和 /etc/network/interfaces 文件。 [56] 如果你选择用 ifupdown 来配置你的网络,那么就不要同时使用底层工具去配置。这也意味着你不应该用其他高级配置工具,如 whereamidivineintuitively 等。他们调用的也是底层配置工具。ifupdown 程序在设计的时候,是假设仅有这样一个程序会被用来设置网络接口的。

更新接口设置是执行:

     # ifdown eth0
     # editor /etc/network/interfaces  # 做你需要的调整
     # ifup eth0

更多信息参阅 interfaces(5)/usr/share/doc/ifupdown/examples/network-interfaces.gzifup(8)


10.6.1.1 用固定 IP 地址为接口进行设置

假设你要配置一个以太网接口,使其拥有一个固定的 IP 地址 192.168.0.111。这个 IP 地址以 192.168.0 为开头,所以它肯定在一个 LAN 内。进一步假设 192.168.0.1 是 LAN 上面 Internet 网关的地址。编辑 /etc/network/interfaces,使其包含类似下面这段的内容:

     iface eth0 inet static
             address 192.168.0.111
             netmask 255.255.255.0
             gateway 192.168.0.1

在接口被激活或是在激活之前,你都可以配置接口的其他部分或者进行其他操作。只要你在"up"和"down"那几行中设置合适的命令。

     iface eth0 inet static
             address 192.168.0.111
             netmask 255.255.255.0
             gateway 192.168.0.1
             up route add -net 10.0.0.0 netmask 255.0.0.0 gw 192.168.0.2 dev $IFACE
             down route del -net 10.0.0.0 netmask 255.0.0.0 gw 192.168.0.2 dev $IFACE
             up echo Interface $IFACE going up | /usr/bin/logger -t ifup
             down echo Interface $IFACE Going down | /usr/bin/logger -t ifdown

你也可以选择把命令插入到 /etc/network/if-up.d/etc/network/if-down.d 目录下的脚本中。这些脚本也能执行扩展的选项。详情参阅 interfaces(5)。例如,软件包 resolvconf 包含的脚本允许你在接口被激活的同时,往 /etc/resolv.conf 添加指定的 DNS 信息:

     iface eth0 inet static
             address 192.168.0.111
             netmask 255.255.255.0
             gateway 192.168.0.1
             dns-search somedomain.org
             dns-nameservers 195.238.2.21 195.238.2.22

dns-search 选项的参数 somedomain.org 符合 resolv.conf(5) 中所说的 search 选项的参数。 dns-nameservers 选项的参数 195.238.2.21195.238.2.22 符合选项 nameserver 的参数。其他可以识别的选项是 dns-domaindns-sortlist。参阅管理域名服务器信息 – resolvconf, 第 10.4.2 节


10.6.1.2 用 DHCP 配置接口

为了使用 DHCP 配置接口,请编辑 /etc/network/interfaces,使其包含一下这段内容:

     iface eth0 inet dhcp

为了让 DHCP 能工作,你需要安装一个使用 DHCP 来配置网络接口, 第 10.5 节中提及的 DHCP 客户端程序。


10.6.1.3 配置无线网卡(Wi-Fi)接口

软件包 wireless-tools 包含了一个钩子脚本 /etc/network/if-pre-up.d/wireless-tools,使得在接口被激活之前,对无线网卡(802.11a/b/g)进行设置变为可能。使用 iwconfig 程序来完成设置,参阅 iwconfig(8)。任何一个 iwconfig 的有效参数,你都可以把它包含在 /etc/network/interfaces 中,并在原有的参数名字前加上“wireless-”这个前缀。例如,要设置 eth0, 使得 eth0 在被 DHCP 激活之前, ESSID 设定为 myessid,encryption key 设定为 123456789e,请编辑 /etc/network/interfaces,加入一下这段内容:

     iface eth0 inet dhcp
             wireless-essid myessid
             wireless-key 123456789e

注意!如果你使用 waproamd 来设置这个接口的话,你不应该使用这个方法来设置 ESSID 和 key。在 ifup 执行时,waproamd 就已经设置好了 ESSID 和 key。参阅使用 waproamd 启动网络设置, 第 10.8.4 节


10.6.1.4 设置 PPP 接口

ifupifdown 程序使用 ponpoff 来添加和删除 PPP 接口,所以先阅读设置 PPP 接口, 第 10.2.4 节

假设你已经设定了 PPP 和 myisp 一起工作。请编辑 /etc/network/interfaces,使其包含如下这段内容:

     iface ppp0 inet ppp
             provider myisp

这样设置好后,ifup ppp0 会完成

     pon myisp

遗憾的是,目前无法在 /etc/network/interfaces 中的 ppp 段落里面提供额外的 pppd 选项。 [57]

目前无法使用 ifupdown 来为 PPP 接口提供辅助的设置。因为在 pppd 完成连接之前 pon 就已经存在了,ifup 执行激活脚本之后 PPP 接口才可用。到这个 bug [58] 被修正之前,还是需要在 /etc/ppp/ip-up/etc/ppp/ip-up.d/ 中进行额外的设置。


10.6.1.5 设置 PPPoE 接口

许多宽带因特网服务提供商(ISP)使用 PPP 协议来连接,即使用户的机器通过以太网和/或 ATM 网络连接他们。 这是通过 PPPoE 的技术来完成的,即把 PPP 祯封装在以太网卡(Ethernet)的祯里面。 假设你的 ISP 被称为 myisp。首先为 myisp 设置 PPP 和 PPPoE。最简单的方法就是安装 pppoeconf,然后从终端中运行 pppoeconf。之后编辑 /etc/network/interfaces 使其包含如下这段内容:

     iface eth0 inet ppp
             provider myisp

有时候最大传输单位 Maximum Transmit Unit (MTU) 和 PPPoE over Digital Subscriber Line (DSL) 有关。详情参阅 DSL-HOWTO

注意!如果你的宽带调制解调器包含路由功能。那么当调制解调器/路由器自己处理 PPPoE 连接时,在 LAN 中它就表现的和简单的连接 Internet 的以太网网关一样。


10.6.1.6 为网关配置多个以太网接口

假设 eth0 已经用 DHCP-configured IP 地址连接到 Internet,并且 eth1 使用一个固定 IP 地址 192.168.1.1 连接到 LAN。编辑 /etc/network/interfaces 使其包含如下内容:

     iface eth0 inet dhcp
     
     iface eth1 inet static
             address 192.168.1.1
             netmask 255.255.255.0

如果按照建立路由网关, 第 10.12 节中描述的去激活主机上的 NAT,那么你就能和 LAN 中的其他主机一起享用互联网连接了。


10.6.1.7 设置虚拟接口

使用虚拟接口,你可以设置一个以太网卡使其成为拥有很多 IP 子网的接口。例如,假设你的主机在 LAN 网络上(192.168.0.x/24)。你想要让主机连接到互联网,并用已经存在的以太网卡通过 DHCP 来获得公网 IP 地址。编辑 /etc/network/interfaces 使其包含如下一段内容:

     iface eth0 inet static
             address 192.168.0.1
             netmask 255.255.255.0
             network 192.168.0.0
             broadcast 192.168.0.255
     
     iface eth0:0 inet dhcp

eth0:0 接口是一个虚拟的接口。当它被激活的时候,它的真实硬件 eth0 也会被激活。


10.6.2 使用 ifupdown 的逻辑接口定义进行高级网络设置

下列内容中,对于读者而言了解物理接口(physical interface)逻辑接口(logical interface)之间的不同是重要的。 [59] 物理(physical)接口就是我们所说的“接口”,是由内核命名为 eth0eth1ppp0 或其他。逻辑(logical)接口是一套可以用来对物理接口的可变参数进行设置的值的集合。如果你觉得还不清楚,那么在阅读的时候就用“用 X 配置文件来设置接口”去代替“设置逻辑接口 X”。

/etc/network/interfacesiface 的定义实际上是逻辑接口的定义,而不是物理接口的。 [60] 如果你从来不去重新配置你的接口,那么你就可以忽略这个细节。因为物理接口 foo 缺省会被设置成逻辑接口 foo

假设你的电脑是台笔记本,你需要在家里和工作的地方之间穿梭。那么当你的电脑连接到公司的网络或家里的网络时,你都要相应地对 eth0 进行设置。

首先定义两个逻辑接口 homework(取代 eth0,就像我们先前做的),它们分别描述了在家中的和公司的网络中如何设置接口。

     iface home inet static
             address 192.168.0.123
             netmask 255.255.255.0
             gateway 192.168.0.1
     
     iface work inet static
             address 81.201.3.123
             netmask 255.255.0.0
             gateway 81.201.1.1

然后通过适当的设置,并在命令行中指定这些设置。物理接口 eth0 就能在家庭网络中被激活了:

     # ifup eth0=home

针对公司网络重新设置 eth0 只要运行这些命令:

     # ifdown eth0
     # ifup eth0=work

注意!如果 interfaces 中的内容如上述所写的,那么我们就不能单独执行 ifup eth0 来激活 eth0。理由是 ifup 使用物理接口名作为缺省的逻辑接口名,但是现在在我们的例子中,没有关于逻辑接口 eth0 的定义。


10.6.3 使用 ifupdown 进行自动的网络设置

ifup 运行的时候,接口的名称可以被“映射(mapped)”为别的名称。至于映射成什么名称,这个视情况决定。因此 ifup 能够被设置为用预设的逻辑接口集合中的一个合适的逻辑接口来激活物理接口。

逻辑接口名称映射产生的情况如下:

mapping 的语法:

     mapping glob-pattern
             script script-name
             [map script input]

mapping 段落中的 script,总是把物理接口的名称作为它的参数。其他“map”行中的内容(不包含“map”本身)都会作为它的标准输入。该 script 在退出之前会把映射的结果作为标准输出打印出来。

例如,下面这段 mapping 会让 ifup 用逻辑接口 home 来激活接口 eth0

     mapping eth0
             script /usr/local/sbin/echo-home

/usr/local/sbin/echo-home 的内容为:

     #!/bin/sh
     echo home

因为映射是由脚本来完成的,所以自动选择逻辑接口是可能的 — 基于一些选择测试。参阅使用 guessnet 来选择逻辑接口, 第 10.6.3.1 节中的范例。


10.6.3.1 使用 guessnet 来选择逻辑接口

安装软件包 guessnet。然后在 /etc/network/interfaces 中加入如下一段内容:

     mapping eth0
             script guessnet-ifupdown
             map home
             map work

现在,当你 ifup eth0 的时候,guessnet 会检测 eth0 是否能用 homework 来激活。它用存储在逻辑接口定义中的信息来完成这项工作。


10.6.4 使用 laptop-net 进行自动的网络设置

软件包 laptop-net 采用不同的方法处理自动的网络设置。Laptop-net 不用 ifupdown 的逻辑接口,取而代之的是它自己的一套配置"方案"和“配置文件”系统。不过,Laptop-net 还是会使用 ifupifdown 来设置物理接口。更多详细文档请安装 laptop-net-doc


10.6.5 使用 network-manager 进行自动的网络设置

network-manager 这个软件现在是由 Fedora 的开发者们开发的,Ubuntu 已经对其进行了打包。有朝一日它也会出现在 debian 中,到时候我们应该放弃 ifupdown 和其他过时的朋友们了。


10.7 处理内核对接口命名的不一致性

eth0eth1 这类设备的名称是由内核指定的,内核是按照创建这些接口的顺序来命名的。在开机的时候,被检测到的适配器通常都是按照一样的顺序被检测到的,所以每次都被指定为同一个名称。但是,对于热拔插的适配器情况就不是这样了。在不同情况下,它们可能以任意的顺序被检测到,于是内核就给它们指定不同的名称。

因为这个关系,在一个网卡适配器是热拔插设备的系统中,使用 /etc/network/interfaceseth0eth1 这类接口定义逻辑接口和依靠缺省的映射关系都是不可能完全正常工作的。要取代这个做法,你必须给逻辑接口设置一个唯一的名称,并使用下列两个方法中的一个来限制哪些逻辑接口会被指定给哪些是适配器。

一个方法是使用 nameif(在 net-tools 软件包中)工具或另外一个更灵活的 ifrename(在 ifrename 软件包中)工具,使内核按照适配器的属性来指定接口名称。使用这个命名方案的话,物理接口的名称可以被用来推测出接口下面的适配器的名称。

另外一种方法是使用 ifup 映射机制。这种情况下就会根据将要被激活的物理接口所在的适配器的某些属性来选择逻辑接口。

假设,你有两个网络适配器,分别在网络 net1net2 中使用。/usr/share/doc/ifupdown/examples/ 目录下面包含了一个映射脚本,能够根据适配器的媒体访问控制地址(MAC 地址)来选择逻辑接口。首先安装脚本到适合的目录。

     # install -m770 /usr/share/doc/ifupdown/examples/get-mac-address.sh \
        /usr/local/sbin/

然后在 /etc/network/interfaces 中加入如下一段内容:

     mapping eth0
             script /usr/local/sbin/get-mac-address.sh
             map 02:23:45:3C:45:3C net1
             map 00:A3:03:63:26:93 net2

更多,更复杂的例子参阅多阶段(Multi-stage)映射, 第 10.9 节

不管采用那种方法,通常都是用 MAC 地址来识别适配器的。


10.8 启动(triggering)网络设置

我们已经知道了接口是如何设置和重新设置的。这些动作需要在适当的时候完成。

传统上,网络是在开机的时候由 /etc/rcS.d/S40networking 这个脚本设置的,而且极少重新设置。其他需要网络的服务随后启动。在关机或者重启的时候,initscripts 按照相反的循序执行。

然而现在,GNU 和 Linux 正朝着支持动态硬件更换和突发事件的方向发展。首先是为可替换的 PCMCIA 卡提供支持。目前在添加 hotplug 机制后,很多外设都能在电脑运行的时候进行替换。这也包括了网络硬件。注意!当你拔插可热拔插设备的时候,涉及到此硬件的服务需要在插入之后启动或删除之前关闭。这就意味着这类服务需要从 System V init 系统中删除,并时期处于 ifupdown 的控制之下。

例如,假设受 initscript /etc/init.d/foo 控制的服务 foo 依赖于动态设置的网络接口 eth0


10.8.1 在开机的时候启动(triggering)网络设置

在启动的时候 init 脚本 /etc/rcS.d/S40networking 运行了 ifup -a 命令。这个命令激活了所有在 /etc/network/interfacesauto 段落里罗列了的物理接口。

现在使用动态的方式来处理网络设置是一种更好方法。一旦这个支持硬件动态更换的机制在适当的位置上,处理静态的硬件就变得非常的简单,就和处理动态的一样。启动过程也可以被当作另外一个热拔插事件。(参阅使用 hotplug 启动(triggering)网络设置, 第 10.8.2 节。)

尽管如此,大多数情况下,至少 lo loopback 接口需要在开机时被激活。所以,需要确定 /etc/network/interfaces 中包含如下一段内容:

     auto lo
     
     iface lo inet loopback

如果你想让其他物理接口也在开机的时候被激活,请把它们加入到 auto 的段落中去。绝对不要把 PCMCIA 接口放在 auto 段落中。在开机启动顺序中,PCMCIA 的 cardmgr 晚于 /etc/rcS.d/S40networking 启动。


10.8.2 使用 hotplug 启动(triggering)网络设置

安装 hotplug 软件包来获得热拔插(hot-plug)支持。

你可以在开机的时候或是把一张卡(例如,PCMCIA 卡)插入机器之后或者在 discover 这类的工具启动并加载了必要的驱动模块之后,热拔插你的网络硬件。

当内核检测到新的硬件,它会初始化这个硬件并执行 hotplug 程序去配置这个硬件。当硬件被删除的时候,内核以不同的环境变量设置再次执行 hotplug。在 Debian 中,hotplug 被呼叫时,它会执行 /etc/hotplug//etc/hotplug.d/ 中的脚本。细节参阅 hotplug(8)

新安装的网络硬件是由脚本 /etc/hotplug/net.agent 设置的。 [62] 假设你的 PCMCIA 网卡已经插入,并生成了可用的接口 eth0。则 /etc/hotplug/net.agent 做了下面的事情。 [63] :

     ifup eth0=hotplug

除非你在 /etc/network/interfaces 中加入了名称为 hotplug 的逻辑接口定义或映射,否则这个命令不会做任何事。为了让这个命令能用来设置 eth0,在 /etc/network/interfaces 中加入如下一段内容:

     mapping hotplug
             script echo

使用 ifupdown 的逻辑接口定义进行高级网络设置, 第 10.6.2 节中解释的,这样会映射上述的命令,使其等同于如下的命令:

     ifup eth0=eth0

(如果你使用 hotplug 启动 ifplugdwaproamd 来控制这个接口,请不要包含这样的映射内容。)

如果你希望在热拔插的时候仅仅激活 eth0,而不是其他接口,那么请用 grep 取代 echo,做法如下:

     mapping hotplug
             script grep
             map eth0

更多技巧,参阅使用 ifupdown 进行自动的网络设置, 第 10.6.3 节/usr/share/doc/hotplug/README.Debian


10.8.3 使用 ifplugd 启动(triggering)网络设置

ifplugd 守护进程根据相关的硬件有没有接入网络来激活或关闭接口。这个程序能够检测网线是否已经插入或无线网卡(Wi-Fi)是否能访问 AP(虽然 waproamd 比较适合后一种情况)。当 ifplugd 发现连接状态改变时,它能运行一个代理脚本,缺省会呼叫 ifupifdown


10.8.4 使用 waproamd 启动网络设置

waproamd 守护进程和 ifplugd 类似,只是它是针对无线网卡(Wi-Fi)设计的。它主动的扫描无线网卡能访问到的 AP。当访问完成之后,waproamd 执行 ifup

如果你正在使用 waproamd,那么通常来说你是通过 waproamd 而不是 /etc/network/interfaces 里面的 wireless-* 选项来设置的。


10.8.5 网络设置和 PCMCIA

有许多可用的方法来处理 PCMCIA 网络接口的设置(对于 2.4 和 2.6 的内核)。

对于 16 位的卡,推荐的处理方法充分利用了 2.4 内核的热拔插子系统对 PCMCIA 的支持。 [64]

PCMCIA 网卡是可以热拔插的。因此,任何需要通过 PCMICA 卡来获得网络的服务的服务,应该设置为要在卡插入之后启动并在卡移除的时候停止。通常通过安排服务在 ifup 时启动和 ifdown 时停止来完成这件事情。然而,有些人说服他们自己使用冷拔插(code plugging)他们的 PCMCIA 网卡:他们在系统启动之前插入网卡,在开机过程中陆续启动需要通过这卡来获得网络的那些服务。如果你是这类人,为了确保在启动这些服务器前网卡已经设置好了,你需要做下列工作:

这些只适合于 16 位的 PCMCIA 卡。

注意!如果你使用 16 位的 PCMICA 卡,软件包 pcmcia-cs 还是需要的。该软件包包括了 cardmgr 守护进程,用来管理 socket 和加载驱动模块。我们只是不希望它通过 /etc/pcmcia/network 来呼叫网络设置程序。

为了让 cardmgr 能正常工作,你可能需要编辑 /etc/pcmcia/config.opts 来设置 16 位 PCMCIA 卡的资源。更多信息参阅 PCMCIA, 第 7.2.1 节Linux PCMCIA HOWTO


10.9 多阶段(Multi-stage)映射

首先,假设你的网络适配器可以热拔插,你启用了使用 hotplug 启动(triggering)网络设置, 第 10.8.2 节中描述的自动设置。其次,进一步假设你需要依照物理接口下面的适配器(如同处理内核对接口命名的不一致性, 第 10.7 节中描述的)和接口上连接的网络(例如,使用 guessnet 来选择逻辑接口, 第 10.6.3.1 节中描述的)来把逻辑接口映射到“物理”接口。你就可以用多阶段映射来完成。

如果接口是可以热拔插的,映射的第一个阶段是利用 hotplug 的组名称并输出内核指定的接口名称。映射的第二阶段是利用内核指定的接口名称并输出适配器的名称。第三个阶段就是依照网络环境,把适配器名称映射到逻辑接口名称上去。

     # 允许 hotplug 激活接口
     mapping hotplug
     	script echo
     
     # 确定那个接口是有线的那个是无线的
     mapping eth?
             script /usr/local/sbin/get-mac-address.sh
             map 02:23:45:3C:45:3C wired
             map 00:A3:03:63:26:93 wifi
     
     # 检测有线网络是否可用
     mapping wired
             script guessnet-ifupdown
             map work-wired
             map home
     
     # 检测哪个无线网络可用
     mapping wifi
             script ifscout
             map starbucks
             map work-wireless
     
     iface work-wired inet static
     	...

10.10 网络服务设置

桌面和家用服务器典型的网络服务设置包括:


10.11 网络故障排除

如果你遇到了问题,首先执行下列命令来检查输出的结果:

     # ifconfig
     # cat /proc/pci
     # cat /proc/interrupts
     # dmesg | more

同时参阅网络测试基础, 第 8.6.29 节下面的章节。

如果你无法浏览特定的站点,参阅无法访问某些站点的怪问题, 第 3.8.5 节


10.12 建立路由网关

一个 Debian 主机可以作为一个全能的网关,它可以承担网络地址转换(NAT,通常也称为 IP 伪装)、邮件传输、DHCP、DNS 缓存、HTTP 代理缓存、CVS 服务、NFS 服务和 Samba 服务。参阅网络所需的主机名和 IP 地址, 第 3.1.9 节中的例子来完成上述设置。


10.12.1 Netfilter设置

在 Linux 2.4 及其后继版本中加入了 netfilter/iptables 项目,作为一个防火墙子系统。参阅 Netfilter,那儿有许多有关其配置的讨论和解释。


10.12.1.1 netfilter 基础

Netfilter 内建了 5 条链路来处理数据包,它们分别是:PREROUTING、INPUT、FORWARD、OUTPUT和POSTROUTING:

                     routing
                     decision
     IN ------> PRE ---> ------> FORWARD -----> ----> POST -----> OUT
     interface  ROUTING  \       filter       /       ROUTING     interface
                DNAT     |       tracking     ^       SNAT
                REDIRECT |                    |       MASQUERADE
                         v                    |
                       INPUT                OUTPUT
                         | filter             ^ filter,DNAT 
                         v                    |
                         \--> Local Process --/
                              user-space programs

10.12.1.2 过滤表(Netfilter table)

数据包在每条内建的链路中传输时按如下过滤表中的规则进行处理。


10.12.1.3 过滤目标(Netfilter target)

防火墙规则有许多目标:


10.12.1.4 Netfilter 命令

iptables 的基本命令有:

     iptables -N chain                   # 创建一个链路
     
     iptables -A chain \                 # 添加链路的规则
              -t table \                 # 使用过滤表(filter, nat, mangle)
              -p protocol \              # tcp、udp、icmp或所有,
              -s source-address[/mask] \
              --sport port[:port] \      # 如果 -p 是 tcp 或 udp,指定源的端口
              -d destination-address[/mask] \
              --dport port[:port] \      # 如果 -p 是 tcp 或 udp,指定目的地端口         -j target \                # 如果匹配作何处理
              -i in-interface-name \     # 针对 INPUT、FORWARD、PREROUTING
              -o out-interface-name      # 针对 FORWARD、OUTPUT、POSTROUTING

10.12.1.5 网络地址转换

LAN 中的机器可以通过能把 LAN 地址转换为可用的 Internet 上的 IP 地址的网关来访问 Internet 的资源。

     # apt-get install ipmasq

执行样例规则来加强ipmasq的保护机制。 参阅/usr/share/doc/ipmasq/examples/stronger/README。 对于在 Woody 中使用 Debian 的 kernel-image-2.4,请确认加载了相应的模块。 Sarge 里面的 ipmasq 已经修正了这个问题。相关配置指导请参阅 网络功能, 第 7.2.3 节

对于使用 2.2 版内核镜像的 Debian,可按下面的方法编辑 /etc/masq/rules 中的 Z92timeouts.rul 文件,以保证可长时间连接远程站点(如发送大容量的 email,等):

     # tcp, tcp-fin, udp
     # 2hr, 10 sec, 160 sec - default
     # 1 day, 10 min, 10 min - longer example
     $IPCHAINS -M -S 86400 600 600

同样,如果是通过 PCMCIA NIC 访问网络,ipmasq 需要从 /etc/pcmcia/network.opts(阅读:/usr/share/doc/ipmasq/ipmasq.txt.gz)或 /etc/network/interfaces(阅读:网络设置和 PCMCIA, 第 10.8.5 节启动(triggering)网络设置, 第 10.8 节) 启动。


10.12.1.6 重定向 SMTP 连接(2.4版内核)

假设你将一台笔记本电脑重新配置成可连入其它的 LAN 环境,而你不想再重新配置用户邮件代理,即:想直接用原来的配置收发邮件。

使用 iptables 命令向网关机器中加入下面的规则,就可以实现重定向与网关机器的 SMTP 连接。

     # iptables -t nat -A PREROUTING -s 192.168.1.0/24 -j REDIRECT \
                -p tcp --dport smtp --to-port 25 # smtp=25, INPUT is open

想使用更完备的重定向规则集,建议安装 ipmasq 软件包,并在 /etc/ipmasq/rules/ 目录中添加 M30redirect.def 文件。


10.12.2 管理多重网络联接

[修正我] 路由策略(by Phil Brutschepbrutsch@tux.creighton.edu): 详情参阅 iproute manual。Traffic control (tc) 也很有趣。

环境设置:

     eth0: 192.168.1.2/24; gateway 192.168.1.1
     eth1: 10.0.0.2/24; gateway 10.0.0.1
     该机器没有 IP 伪装机制。

Special magic:

  • ip rule add from 192.168.1.2 lookup 1

  • ip rule add from 10.0.0.2 lookup 2

  • ip route add to default via 10.0.0.1 metric 0

  • ip route add to default via 192.168.1.1 metric 1

  • ip route add table 1 to 192.168.1.0/24 via eth0

  • ip route add table 1 to 10.0.0.2/24 via eth1

  • ip route add table 1 to default via 192.168.1.1

  • ip route add table 2 to 192.168.1.0/24 via eth0

  • ip route add table 2 to 10.0.0.2/24 via eth1

  • ip route add table 2 to default via 10.0.0.2

  • [修正我] 我没亲自做过。如何利用自动拔号特性使拔号连接保持高速?如果你知道请发补丁我:)


    [ 上一页 ] [ 目录 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] [ 11 ] [ 12 ] [ 13 ] [ 14 ] [ 15 ] [ A ] [ 下一页 ]


    Debian 参考手册

    CVS, 星期四 一月 18 11:53:48 UTC 2007

    Osamu Aoki osamu#at#debian.org
    译者:
    Hao "Lyoo" Liu iamlyoo#at#163.net
    Ming Hua minghua#at#rice.edu
    肖盛文 atzlinux#at#163.com
    Haifeng Chen optical.dlz#at#gmail.com
    解彦博 xieyanbo#at#gmail.com
    easthero easthero#at#gmail.com
    作者, 第 A.1 节