由 北南南北 在 05-14-2002 01:46 发表:
网络设定
网络设定
经过这么长的路程﹐当您辛苦完成了 Linux System 的准备之后﹐我们到这里才真正说要为 Linux 设定一些最引人入胜的东西。当然﹐这一切都要从 Linux 的网络功能开始﹐离开了网络﹐Linux 只能是匹养在马房里面的良驱﹐英雄无用武之地。哦﹐这样说﹐或许有点偏见的﹐因为对我个人来说﹐只会用 Linux 来架设服务器而已。别的朋友﹐可能会拿 Linux 做其它用途﹐那就不是我们这里要学习的了。
前提条件
在进行 Linux 网络设定之前﹐您必须已经对网络有一定的概念﹐否则﹐我建议您先完成“学习网络”那边的阅读﹐然后才来动手 Linux 的网络实作。在本章的学习中﹐您最起码要知道基本的局域网络架构﹐以及 IP 的 subneting 和 routing 的原理和分析。而往后的 server 架设﹐更需要您对各种 service 运作原理有一定的基础认识。
有良好习惯的管理员﹐在进行任何系统安装和设定的时候﹐第一件事情不是跑到机器前面敲键盘﹐而是先找一张纸﹑抓一只笔。换句话说﹐先规划后动手就是了。
在当初安装 Linux 的时候﹐我已经知道我的机器打算用来做什么角色的了。现在﹐再让我们规划一下﹐到底怎样将机器接到网络上去﹐这必须要看当前的网络环境﹕
首先﹐这里仅是一个家庭网络。不过﹐也会进行一些 Internet 的仿真测试﹐所以同时也是一个实验网络。
对外使用拨接式的 ADSL﹐虽然 ISP 允许同时 5 台机器上网﹐但为了安全起见﹐我会透过 NAT + Firewall 提供内部网络的上网服务﹐这正是目前这台机器的主要功能。
因为要进行仿真﹐所以会另外再设一个 DMZ 区域。
内部网络使用 192.168.100.0/24 的 IP ﹔另外把 10.0.1.0 切为 8 个子网络﹐将 10.0.1.128/27 分配给 DMZ 使用﹔再将 10.0.1.0/27 给外部界面使用﹐因为 ADSL 不是 routing mode﹐所以用这个 private IP 也无妨﹐反正用 PPPoE 上网。
网络一共有 3 个 Hub 可供使用﹐分别担当这三个网络的连接任务﹐同时在物理上将各网络分开。
根据网络环境和需求﹐如下是我初步规划的网络架构图例﹕
设定网络卡
下面的例子是教您如何使用 module 的形式安装多片网络卡在同一机器上。先假设我已经有一片 rtl8139c 的 PCI 网络卡﹐并且在安装过程中已经顺利抓到并且设定好了。现在﹐我需要加一张 rtl8029 pci 和一张 rtl8019 isa 网络卡(这些型号您可以从网络卡的芯片组上看得到)﹕
首先﹐您必须知道他们相关的 Linux 模块名称是什么﹖我暂时没有做功课﹐先用通用驱动程序来试试﹐所以我选择 ne2k-pci 和 ne 这两个模块。您必须确定在 /lib/modules/uname -r
/kernel/drivers/net/ 目录下有这些模块存在﹐否则就编译核心﹐将如下两个项目编为模块﹕
2.
1<m> NE2000/NE1000 support (NEW)
2
3<m> PCI NE2000 and clones support (see help)
4
5然后﹐如果您使用的网络卡有 ISA 类型的话﹐要找出它的 irq 和 io。如网络卡没有 jumper 设定的话﹐厂家通常会提供一片磁盘供您设定资源数值的(假设我们这里将 ISA 网卡的 irq=3﹐io=300)。
6
7然后进入 BIOS ﹐确定它们没有和其它设备冲突(例如这里要关闭 COM2 的设定)﹐再转到 PnP/PCI 的设定上﹐将 ISA 网络卡所使用的 IRQ 保留起来﹐也就是设定为 Legacy ISA (注﹕PCI 类型的网络卡无需如此设定)。
8
9
10
11然后修改 /etc/modules.conf 这个档案﹕
12
13alias eth0 8139too
14
15alias eth1 ne2k-pci
16
17alias eth2 ne
18
19options ne io=0x300 irq=3
20
21
22
23
24
255\. 上面的第一行﹐应该是系统原本就有的﹐因为在安装的时候就会设定好了。其后的四行才是我需要增加的﹕首先将 rtl8029(ne2k-pci) 用来做 eth1﹐然后 rtl8019(ne) 做 eht2。因为 rtl8019 是 ISA 网络卡﹐所以还要用 options 为它的模块设定 io ﹐要注意哦﹕io 的设定﹐一定要用 0x 开头的﹗而通常来说﹐如果 io 设定正确了﹐irq 或许可以不设。
26
27
28
296\. Tips﹕假如您的网络卡都是同一个型号﹑使用同一个模块的话﹐那您可以如此设定﹕
30
31
32
33alias eth1 ne
34
35alias eth2 ne
36
37options ne io=0x300,0x320 irq=3,5
38
39
40
41
42
43
44
457\. 那么﹐ eth1 的 io=0x300﹑irq=3﹐而 eth2 的 io=0x320﹑irq=5 ﹐如此类推。
46
47
48
498\. 不过﹐通常来说﹐pci 不用设定 io 和 irq 啦﹐所以无需担心这个。然而﹐您就很难控制哪一张卡是第一﹑哪一张卡是第二﹐碰到这样的情况﹐可能需要将网络线换过来插了﹐总要试试才知道啦。
50
51
52
53完成设定之后﹐执行如下命令﹕
54
55modprobe ne2k-pci
56
57modprobe ne
58
59
60
61
62
6310.如果有错误的话﹐根据信息内容进行修改。(也可以改用 insmod 命令)
64
65
66
67假如上一个动作能顺利完成﹐然后执行如下命令﹕
68
69dmesg | grep eth
70
71
72
73
74
7512.这样﹐您可以看到系统所抓到的网络卡信息﹐包括他们的型号﹑ IRQ 和 IO 等等。在我们的例子中﹐应该会看到类似如下的信息﹕
76
77
78
79eth0: RealTek RTL8139 Fast Ethernet at 0xc8871000, 00:50:fc:30:ea:61, IRQ 9
80
81eth0: Identified 8139 chip type 'RTL-8139C'
82
83eth0: Setting 100mbps full-duplex based on auto-negotiated partner ability 45e1.
84
85eth1: RealTek RTL-8029 found at 0xd400, IRQ 10, 00:00:21  2:30  A.
86
87NE*000 ethercard probe at 0x300: 00 00 e8 5a 78 af
88
89eth2: NE2000 found at 0x300, using IRQ 3.
90
91
92
93
94
95到此为止﹐我们基本上可以确定网络卡已经设定好﹐并且能被系统抓到了。
96
97
98
99如果您使用的是笔记本型计算机﹐或许要使用到 PCMCIA 网络卡。嗯﹐现在的核心打都能支持市面上的 PCMCIA 网络卡﹐万一您的型号不在核心支持之列﹐说实在您要成功设定起来的机会很低。不过﹐您仍可将希望寄托在最新的 pcmcia-cs 套件上面。pcmcia-cs 其实就是核心要处理 pcmcia 装置的程序﹐您可以到如下网页下载最新的版本回来﹕
100
101
102
103http://sourceforge.net/project/show...p?group_id=2405
104
105
106
107在进行设定之前﹐我建议您先阅读一下 PCMCIA 的 HOWTO 文件。
108
109
110
111然而﹐不幸的是﹐我到上面网站下载 pcmcia-cs-3.1.29.tar.gz 回来测试﹐执行 make config; make all; make install 之后﹐却导致原本的 PCMCIA 网络卡都抓不到了﹗我分别在 Acer TM 351TE 和 Dell D266XT 上面的 Redhat 7.1 和 Mandrak 8.0 上面试过﹐弄了大半天还是搞不定。最后只好放弃﹐用光盘本身自带的 kernel-pcmcia-cs-x.x.x.x.rpm 来复原。
112
113
114
115我所碰到的问题主要是 modules 的问题。如果 kernel 里面 General 的 pcmcia 选项有选择为 Y 或 M 的话﹐则不会在 /lib/moduels/<version>/kernal/pcmcia 目录下面产生 modules 。将 kernel 选项选择为 N ﹐的确可以产生 moduels﹐但却会碰到 unresolvable symbols 的头痛问题。而且﹐就算没有 symbols 问题﹐同时也可以加载 pcmaic-core 模块﹐还是不能成功抓到网络卡﹐不是告诉您没有 high memory 就是根本没反应。
116
117
118
119嗯﹐因为我在系统方面不是很在行﹐也不想花太多时间在这上面了﹐暂时留作日后的功课吧。
120
121
122
123设定主机
124
125
126
127当您将网络卡设定好之后﹐接下来是将 Linux 连上网络去。而网络上这么多机器﹐要区别它们﹐在 TCP/IP 网络中必须以各自唯一的 IP 地址为依据。不过﹐对我们人类来说﹐要记 IP 数字通常都比较困难﹐所以﹐最好为每台机器起一个名字。取名没什么特别规则﹐总之容易记得和不重复就是了。
128
129
130
131我们在“网络基础中”讨论 DNS 的时候知道﹐每一个连上 Internet 的网络﹐都有着各自的 domain 名字。即使您没有正式向 InteNIC 注册﹐也应该为自己的 domain 起一个名字。如果您已注册有合法的 domain 了﹐也最好和内部网络的 domain 名称分开。如没特别理由﹐尽量使用一个最不会在 internet 出现的名字﹐这样就最大程度避免了 domain 名字冲突了。(请尽量避免用什么 xxxx.xxxx.com 等名字﹐因为那样可能会和真正注册了的 domain 冲突。)
132
133
134
135在这个例子中﹐我用自己的名字拼音来做 domain name﹕siyongc.domain。相信 internet 上面应该不至于用我的名字做 domain 吧﹖所以﹐我将我的机器命名为﹕rh71.siyongc.domain 。
136
137
138
139Tips﹕您也可以用 localdomain 来做 domain 命名﹐系统预设上的 localhost 就是从属于这个 domain 之下。名称选用方法有很多啦﹐只要不和别人冲突就行。
140
141
142
143至于主机名称﹐特别那些与 Internet 连接的主机﹐按一般的惯例﹐我们都采用一些‘与系统无关’的名称。上面使用的名称(如 rh71) 说实在不是很合乎要求﹐取而代之的﹐您可以开一个动物园或植物园﹐用动物名称(例如 lion﹑monkey 之类) 或水果名称(例如 apple﹑banana 之类) 来命名机器。这样的好处是﹕首先﹐别人不容易从机器名称上得知您的系统类别(有经验的骇客还是有办法的)﹔其次﹐在 DNS 设计上(日后我们会谈到 DNS 设定)较为灵活﹐只要用 CNAME 将常用的 server (如 www﹑mail 等) 对应到不同的机器名称上就可以了﹐万一机器挂了或要进行更换﹐修改起来容易得多。
144
145
146
147如果您在安装的时候﹐有选择网络功能﹐那时候应该已经设定好了。只要您使用 hostname 命令(不带任何参数)就可以看到当前的机器名称。您也可以随时用这个命令来改变机器名称﹕
148
149
150
151hostname rh71.siyongc.domain
152
153
154
155
156
157我们在 system 系列中的第二章“开机与关机”文章中已经知道﹐系统在开机的时候会尝试设定主机名称。如果您用 hostname 命令修改了主机名称﹐而没有修改开机设定﹐那下次开机还是用回原来的名称。在 RedHat 系统里面﹐您的主机名称设定定义在 /etc/sysconfig/network 这个档案的 HOSTNAME 变量中。如果您要变更您的主机名称﹐可以用文书编辑器直接修改这些档案。只有这样﹐下次开机才能抓到正确的机器名称。除此之外﹐您还要修改 /etc/HOSTNAME 这个档案﹐把新的主机名称写到里面就可以了﹕
158
159
160
161hostname > /etc/HOSTNAME
162
163
164
165
166
167前面说过﹐hostname 是给我们人类记忆的﹐机器本身使用的还是 IP 数字。为此﹐当我们修改了机器名称之后﹐您还必须修改另外一个档案﹕/etc/hosts 。在这个档案里面﹐您要确定两个机器名称必须指定正确﹕
168
169
170
171一个名称是﹕localhost ﹐它对应的 IP 一定是 127.0.0.1。这是一个“本机环回地址( loop back address)”﹐就算您的机器不安装网络卡﹐这个名字是一定要有的﹔
172
173另外一个就是刚才您修改的﹐要和您分配给这台机器的 IP 对应着﹐如果在其它机器上的 hosts 檔中有您这台机器名称的设定﹐也必须更新过来。
174
175在我的机器上﹐/etc/hosts看上去是这样的﹕
176
177
178
179# local machine names
180
181127.0.0.1 localhost.localdomain localhost
182
183192.168.100.23 rh71.siyongc.domain rh71
184
18510.0.1.131 rh71.dmz.domain rh71dmz
186
187# other machine names
188
189192.168.100.20 acer.siyongc.domain acer
190
191192.168.100.24 mdk.siyongc.domain mdk
192
19310.0.1.130 lp64.dmz.domain lp64dmz
194
195
196
197
198
199每一行句子的字段分别是﹕IP 地址﹑主机名称﹑主机别名(可以多个﹐用空格键分隔)。这里除了 localhost﹑rh71 和 rh71dmz 是本机名称之外﹐其它都是在网络上别的机器﹐或是一些虚拟主机对应。
200
201
202
203不过﹐光完成上面这些设定还不足够﹐如果您知道网络上已架设有 DNS 服务器﹐或是会使用 Internet 上的资源﹐那您还要修改 /etc/resolv.conf 这个档案﹐将 DNS 主机 IP 加进去﹐如﹕
204
205
206
207nameserver 0.0.0.0
208
209nameserver 168.95.1.1
210
211nameserver 139.175.10.20
212
213domain siyongc.domain
214
215search siyongc.domain dmz.domain test.com
216
217
218
219
220
221先让我们解读上面这个档案吧。
222
223
224
225这个 resolv.conf 档案主要用来设定 dns client 端上所使用的 DNS server ﹐您最多可以设定三个 namesever 。然后机器会按顺序查询第一台 nameserver﹐如果得不到响应﹐则转向下一台﹐如果有响应就不使用后面的 nameserver 了。所以﹐并不是这里设定多几台 nameserver 就可以帮您加快 DNS 的查询﹐而仅是做备份用途而已﹐而且其设定顺序也非常讲究。一般而言﹐在 Internet 环境中﹐您可以使用任何一台正常工作的 DNS 来帮您进行名称解释服务﹐但我们通常会以最距离最近的 nameserver 为优先。假如您的机器本身就是一台 DNS server﹐那您可以用 0.0.0.0 来表示﹐当然您也可以用系统本身的 IP﹐但如果您有多个 IP 地址的时候﹐我会建议您用 0.0.0.0 或 127.0.0.1 。
226
227
228
229然后是 domain 的设定﹐这没什么特殊用途﹐只是指定了系统本身所在的 domain 而已。可设也可以不设。
230
231
232
233最后关于 search 设定﹐这也是可设可不设的﹐在这里您可以用空格键分隔设定多个 domain name 。它的作用是﹕当系统在查询一个名称的时候﹐假如该名称不是一个完整的 DN 名称﹐则会将 search 指定的 domain 依次附加在主机名称后面。按上面的设定﹐当您所查询的名称是 myhost 的时候﹐然后系统会依次查询 myhost.siyongc.domain﹑myhost.dmz.domain myhost.test.com 。在这个查询过程中﹐一旦查询到结果之后﹐将不再往下继续 search﹔但如果所有 search 都没有结果﹐则告诉您查询失败。
234
235
236
237到这里﹐您或许有些混乱﹕前面的 /etc/hosts 文件可以帮我们继续主机名称与 IP 的对应﹐这里的 /etc/resolv.conf 又可以指定 DNS 来查询﹐究竟会以哪个为标准啊﹖
238
239
240
241问得好﹗要回答这个问题﹐您首先要检查 /etc/host.conf 这个档案﹐其内容或许如下﹕
242
243
244
245order hosts,bind
246
247multi on
248
249
250
251
252
253这个档案的第一句﹐是告诉系统在进行名称解释的时候所使用的方法﹐以及使用顺序。这里的 hosts 就是告诉系统首先查询 /etc/hosts 文件﹐如果没有结果﹐则转向 bind﹐也就是 DNS 服务的意思啦。除了这两个方法之外﹐您还可以透过 nis 来查询﹐这个我们日后谈到 NIS 服务的时候就知道了﹐现在不必担心。
254
255
256
257如果您在这个档中﹐将 multi 设定为 on 的话﹐则允许一台主机使用多个 IP 地址﹐但只对 /etc/hosts 有效。
258
259
260
261除了上面两个主要的设定外﹐您还可以在这个档里面设定﹕
262
263
264
265alert﹕如果设定为 on 的时候﹐会将任何试图骗取 IP 的动作透过 syslog 进行记录。
266
267nospoof﹕如果设定为 on 的时候﹐会对名称进行反查询﹐以确定名称的正确性。
268
269trim﹕可以指定一个预设 domain name﹐然后让您在 /etc/hosts 文件里面只设定主机名称就可以了。
270
271除了上述这个 host.conf 档之外﹐您还必须留意 /etc/nsswitch.conf 这个档案。它主要用来提供给系统函式程序所使用的名称服务换置﹐里面的设定有很多﹐其中会有这样一行﹕
272
273
274
275hosts: files nisplus dns
276
277
278
279
280
281这同样是用来设定主机名称的查询顺序用的﹐但它的设定更为复杂﹐您可以 man nsswitch.conf 来慢慢参考。
282
283
284
285设定网络
286
287
288
289当您的网络卡设定好了﹐主机名称也有了﹐但要连上网络还需要再花点功夫。在介绍相关设定档之前﹐先让我们认识网络设定的基本命令﹕
290
291
292
293ifconfig
294
295
296
297如果我们只输入这个命令﹐后面不带任何参数的话﹐系统会将目前的网络设定状况显示出来﹕
298
299
300
301eth0 Link encap:Ethernet HWaddr 00:50:FC:30:EA:61
302
303inet addr:192.168.100.23 Bcast:192.168.100.255 Mask:255.255.255.0
304
305UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
306
307RX packets:962 errors:0 dropped:0 overruns:0 frame:0
308
309TX packets:723 errors:0 dropped:0 overruns:0 carrier:0
310
311collisions:0 txqueuelen:100
312
313Interrupt:9 Base address:0x1000
314
315
316
317lo Link encap:Local Loopback
318
319inet addr:127.0.0.1 Mask:255.0.0.0
320
321UP LOOPBACK RUNNING MTU:16436 Metric:1
322
323RX packets:172 errors:0 dropped:0 overruns:0 frame:0
324
325TX packets:172 errors:0 dropped:0 overruns:0 carrier:0
326
327collisions:0 txqueuelen:0
328
329
330
331
332
333您可以看到界面的名称( eth0 等)﹑界面类型( Ethernet 等)﹑界面实体地址﹑IP 地址﹑广播地址﹑Net Mask﹑界面目前状态﹑MTU(Maximum Transmission Unit)大小﹑路由 Metric 数目﹑接收(RX)封包状态﹑发送(TX)封包状态﹑网络碰撞﹑发送队列﹑IRQ﹑IO地址﹑等等信息 (如果你不知道它们是什么﹐请参考"网络基础")。
334
335
336
337透过命令结果﹐我们还可以判断当前的网络状态呢。例如﹐其中的 RX 和 TX 是界面处理的封包总数﹐再和下面的 collisions 作比例计算﹐就知道该界面所连接的网络是否太拥挤了。不过﹐这也与您使用的硬设备有关﹐例如 hub 和 switch 所反映的结果是不一样的。
338
339
340
341在我目前的例子中﹐因为 eth0 是安装的时候就设定好的﹐还有 lo 代表 loopback 界面﹐所以您会看到它们。但 eth1 和 eth2 虽然已经被核心抓到(透过 dmesg 可以知道)﹐但因为还没有网络设定﹐所以暂时看不到。下面就教您如何用命令将它们跑起来。
342
343
344
345ifconfig 命令除了可以让您查看界面情况之外﹐也可以用来设定界面。例如﹕
346
347
348
349ifconfig eth1 10.0.1.1 netmask 255.255.255.224 broadcast 10.0.1.63 up
350
351ifconfig eth2 10.0.1.131 netmask 255.255.255.224 broadcast 10.0.1.159 up
352
353
354
355
356
357这时候您再输入 ifconfig 命令不带任何参数的话﹐就看到所有界面的设定了﹗
358
359
360
361使用 ifconfig 命令来设定 IP 的时候﹐最好不要偷懒﹐先用 ip && mask 计算出 broadcast 地址(如果不会﹐请参考 “IP 地址”一文)﹐然后以完整的参数进行设定。最后的 up 可以不用设定﹐但改为 down 的话﹐可以将界面的 IP 地址关闭掉。
362
363
364
365通常来说﹐一个界面只会使用一个 IP﹐但这并非绝对的。在 Linux 系统上﹐您可以为一张已有 IP 的界面增设 IP Alias ﹐也就是将多个 IP 绑在同一张网络卡上面。我们用 ifconfig 来设就可以了﹐唯一不同之处在于﹕原生界面我们都用 eth0﹑eth1﹑eth2 这样的名字来表示﹐而 alias 则在原界面上再用 " :" 分隔设定另外一位数字﹐例如﹕eth0:0﹑eth0:1﹑eth0:2﹑eth1:0﹑eth1:1﹑eth2:0﹑...﹑如此类推。下面的命令﹐就是为 eth2 设定第一个 alias﹕﹕
366
367
368
369ifconfig eth2:0 10.0.1.2 netmask 255.255.255.224 broadcast 10.0.1.63 up
370
371
372
373
374
375如果您再输入 ifconfig eth2:0﹐就可以看到如下的结果﹕
376
377
378
379eth2:0 Link encap:Ethernet HWaddr 00:00:E8:5A:78:AF
380
381inet addr:10.0.1.2 Bcast:10.0.1.63 Mask:255.255.255.224
382
383UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
384
385Interrupt:3 Base address:0x300
386
387
388
389
390
391您会发现﹐eth0:0 和 eth0 的实体地址都是一样的﹗如果您了解 ARP 协议的话﹐应该不难理解这个现像。无论如何﹐当网络联机在底层 (datalink) 传送的时候﹐alias 和原生界面并没有分别﹐但在网络层中﹐则可以视为两个不同的逻辑地址。这对于架设虚拟主机的朋友来说﹐无疑是非常便利的。假如您是一个 ISP﹐向客户提供网页 hosting 服务﹐那您可以在同一台机器上用 alias 设定多个 IP﹐然后就能够同时向多个客户提供服务﹐而无须每一个客户都弄一长界面或架一台主机。一张界面最多可以设定多少个 alias 我没考证过﹐但作为商业运作而言﹐基本的服务品质还是必须要保证的。
392
393
394
395Tips﹕在设定 IP alias 的时候﹐在同一个界面上的 IP 不一定都要在同一个 subnet 里面﹐只要路由设定正确的话﹐就没问题。但是如果您了解 IP 和 ARP 协议的话﹐您会发现在同一个物理网段上面设定不同的 subnet﹐事实上会造成额外的封包流量。具体原理我这里不详细说了。
396
397
398
399如果我们要关闭一个 Alias 界面﹐只需输入﹕ ifconfig eth2:0 down 则可。
400
401
402
403此外﹐ifconfig 除了可以设定界面和 alias 的 IP 地址之外﹐您还可以透过如下的参数设定一些界面特性﹕
404
405
406
407· [-]ARP﹕启用或关闭 ARP 协议支持﹔
408
409
410
411· [-]allmulti﹕启用或关闭 all - multicast 模式﹐然而会将信息传给核心﹔
412
413
414
415· [-]pointpoint [addr]﹕指定为点对点模式﹐也就是联机直接与另一端机器直接相连﹐可用后带的地址指定另一端的地址﹔
416
417
418
419· hw﹕指定界面的硬件类型﹐如 ether﹑ax25﹑ARCnet﹑netrom
420
421
422
423· metric N﹕指定界面之路由成本。
424
425
426
427· mtu N﹕指定最大传送单位。
428
429
430
431route
432
433
434
435如果我们只输入这个命令而不带任何参数﹐我们可以看到系统目前使用的路由表格设定﹕
436
437
438
439Kernel IP routing table
440
441Destination Gateway Genmask Flags Metric Ref Use Iface
442
443swtn184-1.adsl. * 255.255.255.255 UH 0 0 0 ppp0
444
44510.0.1.128 * 255.255.255.224 U 0 0 0 eth2
446
44710.0.1.0 * 255.255.255.224 U 0 0 0 eth1
448
449192.168.100.0 * 255.255.255.0 U 0 0 0 eth0
450
451127.0.0.0 * 255.0.0.0 U 0 0 0 lo
452
453default swtn184-1.adsl. 0.0.0.0 UG 0 0 0 ppp0
454
455
456
457
458
459Tips﹕假如您输入命令后要等很久﹐那就是名称解析上有问题﹐请确定 /etc/hosts 的完整与正确﹐或是 DNS 运作良好。不过﹐您也可以用 route -n (加上 -n 参数)只显示 IP ﹐因为无需进行名称查询﹐所以就不会有延迟现像了。
460
461
462
463从上面的命令结果中﹐我们可以看到﹕
464
465
466
467· 第一栏是“目的地地址”﹐可以是一个网络﹐也可以是一台主机﹐如果是 0.0.0.0 的话就是 default gw (预设网关/网关)﹔
468
469
470
471· 然后﹐第二栏是“Gateway 地址”(‘*’表示无需使用 gateway﹐例如本机网络和广播地址)﹐也就是封包的下一站地址﹐它必须和相应的界面在同一个 subnet 之中﹔
472
473
474
475· 接下来是关于目的地的 NetMask﹐这个非常重要﹐因为它是用来判断目的地址范围的依据﹐如果是 255.255.255.255 的话﹐那代表一台主机﹐如果是 0.0.0.0 则是 default gw 所用的﹔
476
477
478
479· 第四栏是“旗标”﹐这里的 U 是“Up”的意思﹐也就是目前已启用﹐如果是 H 表示目的地为一个“Host”﹐ G 表示使用“Gateway”的意思﹔
480
481
482
483· 接下来的 Metric 和 Ref 是供路由系统参考的﹐其中的 metric 是路由成本﹐ref 则是针对该路由的联机数目﹔
484
485
486
487最后是通往目的地所使用的网络界面。
488
489
490
491在上面的例子中﹐您所看到的一个用 3 个网络的路由﹐分别是机器上三张网络卡所连接的﹔还有一个 loop back 界面的所在的网络﹔而最顶和最底下两行则是完成 ADSL 拨接上网之后才有的。但您要留意最后一行就是所谓的 default gw 设定﹐没有它﹐我们就无法联机到 internet 上面了。
492
493
494
495如果您还记得我们在“学习网络”当中的 IP 基础的话﹐您应该知道什么是静态路由和动态路由(否则﹐我强烈建议您先弄明白 ip routing 再回来继续)。事实上﹐这个 route 命令除了可以显示当前的路由表格之外﹐更为重要的﹐它就是来给管理员设定静态路由用的。利用它﹐我们可以修改﹑增加﹑和删除系统的路由表格设定﹐告诉机器通往某一个网络或主机使用哪一个 gateway﹑路由成本﹑以及使用哪一个界面等等。至于动态的路由﹐在 Linux 上可以使用 routed 或 gated 服务﹐但这需要相邻的路由设备都要使用相同的路由协议﹐例如 RIP 和 OSPF 等﹐因为牵涉的设定非常复杂﹐这里就不进行说明了。
496
497
498
499下面我将会示范 route 命令的用法。
500
501
502
503在我的例子中﹐首先要先挑一个已出现在路由表格的设定﹐然后移除它(我待会再示范如何加回去)﹕
504
505
506
507route del -net 10.0.1.128 netmask 255.255.255.224 dev eth2
508
509
510
511
512
513这时再输入一次 route -n 就可以确定有关 10.0.1.0 这网络的路由设定已经给移除掉了。
514
515
516
517接下来﹐我再将刚纔删除的路由加回去﹕﹕
518
519
520
521route add -net 10.0.1.128 netmask 255.255.255.224 dev eth2
522
523
524
525
526
527相信您现在不难看出﹕增加和移除路由设定﹐分别之处就是使用‘add’和‘del’来做命令选项。这时候再执行 route 就可以看到路由设定有回到路由表格中去了。
528
529
530
531上面这个命令﹐就是在路由表格中新增一条到 10.0.1.128/27 这个网络的路由﹐它所使用的界面是 eth2 。只要您知道 ip﹑netmask﹑net_id 的关系﹐使用上面的命令是不成问题的。
532
533
534
535Tips 1﹕有时候﹐如果我们使用 ifconfig 手工的增加了一个界面﹐严格来说﹐我们还应该为界面增加一个‘H’记录﹐也就是用 add -host 来设定﹐但就无需使用 netmask (用了反而不接受﹗)﹕
536
537
538
539route add -host 10.0.1.2 dev eth2:0
540
541
542
543
544
545不过﹐这也不是一定必须如此的﹐如果您发现有问题再增加就是了。在以前的系统里面﹐您会在 route table 中看到所有界面的 IP 地址路由项目﹐不过现在的系统似乎只显示 network 的记录而已。
546
547
548
549Tips 2﹕对于刚开始设定 adsl 的朋友来说要特别注意 default gw 的设定﹕如果您的系统原本就设定有 default gw 的话﹐rp-pppoe 在完成拨接后将不会修改这个设定﹐这样会造成您连不上 internet (因为 default gw 不正确的缘故)。要解决这个问题﹐您有两个方法﹕(1) 修改 /etc/sysconfig/network 将其中的 GATEWAY 和 GATEWAYDEV 句子拿掉﹔(2) 或是﹐执行如下命令﹕
550
551
552
553route add default dev ppp0
554
555
556
557
558
559注﹕上面的 ppp0 是您的 ADSL 拨接界面﹐假如您不是用 ppp0 的话﹐那请修改为正确的设备名称。
560
561
562
563如果您采用第二种方法﹐那在结束 ADSL 拨接之后﹐再检查 route table ﹐确定刚纔的设定被取消﹐否则用手工的方法移除(相信您会移除吧﹖不会就要打屁屁了~~)。
564
565
566
567下面不如让我们在真实的环境中仿真一下路由的设定吧。
568
569
570
571就用我家里的网络环境就好了﹕我在家中分有两个 subnet﹐它们的物理联机也是分开的(接在不同的 hub 上)﹐其中一个使用 192.168.100.0/24 这个子网﹐而另外一个则使用 10.0.1.128/27 子网络。我目前的这台 Linux 机器上﹐用不同的网络卡连接到这两个子网中﹐分别是 192.168.100.23(eth0) 和 10.0.1.131(eth1) 。第一个子网里面有一台 Windows 主机﹕192.168.100.20 ﹐并没有设定 default gateway ﹔而另外一个子网则有一台 Linux 主机﹕10.0.1.130 ﹐它的 default gateway 是 10.0.1.131 ﹐也就是我们一直以来做教学用的机器。
572
573
574
575好了﹐这情形下﹐您不难看出﹕我目前使用的 Linux 机器 ( rh71 ) 就是这两子网的 router 。不过﹐要在 Linux 激活路由能力﹐必须将 ip forwarding 功能打开﹐只要执行下面命令就可以了﹕
576
577
578
579echo "1" > /proc/sys/net/ipv4/ip_forward
580
581
582
583
584
585Tips﹕如果您想要在开机的时候就将 ip forward 打开﹐您可以修改 /etc/sysctl.conf 档案﹐修改其中的句子﹕
586
587
588
589net.ipv4.ip_forward = 1
590
591
592
593
594
595但上面的动作仅是将路由打开而已﹐我们不能忘记路由是双向的﹐尽管 10.0.1.130 那边已经设定好预设路由﹐但 Windows 这边却对另外一个网络毫不知情。所以﹐我们必须为 Windows 主机增加一笔 10.0.1.128/27 的路由﹐请进入 Windows 的 MS-DOS 模式﹐并输入﹕
596
597
598
599route add 10.0.1.128 mask 255.255.255.224 192.168.100.23 metric 1
600
601
602
603
604
605哈哈﹐有没发现 Windows 的命令和 Linux 的不完全一样哦﹐不过也相差不远﹐反正原理都一样啦。然后您输入 route PRINT 就可以看到 Windows 的路由表格了。这样的话﹐那就可以让 192.168.100.20 和 10.0.1.130 相互连接了 ^_^
606
607
608
609当然﹐如果我将 windows 的 default gw 设定为 192.168.100.23 也同样可以的﹕控制台 --> 网络 --> TCP/IP --(您的网络卡型号) --> 内容 --> 通讯闸 ﹕
610
611
612
613
614
615反过来﹐如果在 10.0.1.130 那边没有将 10.0.1.131 设为 default gw 的话﹐那您也要在路由表格上面增加一笔关于 192.168.100.0/24 的路由﹕
616
617
618
619route add -net 192.168.100.0 netmask 255.255.255.0 gw 10.0.1.131 dev eth0
620
621
622
623
624
625无论如何﹐您要记住一点﹕如果要两个网络能够成功的达成路由﹐双方网络必须有相应的路由设定通向对方网络才行。然而﹐初学者最容易犯的一个错误是﹕在同一台主机上﹐将两张不同的网络卡设定在同一个 subnet 之内。
626
627
628
629在网络管理方面﹐subnet 和 routing 是最基本的技能﹐就好象小学生学习加减乘除一样﹐是基本到不能再基本的了。上面介绍的 ifconfig 和 route 这两个命令也是 Linux 的最基本网络命令﹐如果您会得灵活运用﹐我敢保证您在任何一个 Linux 系统都会设定网络﹐而不是问﹕“怎么没有 xxxxx 工具﹖我在 yyyyyy 上面明明可以这样设定的。”
630
631
632
633ping
634
635
636
637关于这个命令应该很多人都用过了吧﹖它就是用来测试两台主机是否能够顺利联机的最简单的工具﹕
638
639
640
641ping -c 4 10.0.1.131
642
643
644
645PING 10.0.1.130 (10.0.1.130) from 10.0.1.130 : 56(84) bytes of data.
646
64764 bytes from 10.0.1.130: icmp_seq=0 ttl=255 time=116 usec
648
64964 bytes from 10.0.1.130: icmp_seq=1 ttl=255 time=45 usec
650
65164 bytes from 10.0.1.130: icmp_seq=2 ttl=255 time=42 usec
652
65364 bytes from 10.0.1.130: icmp_seq=3 ttl=255 time=42 usec
654
655
656
657\--- 10.0.1.130 ping statistics ---
658
6594 packets transmitted, 4 packets received, 0% packet loss
660
661round-trip min/avg/max/mdev = 0.042/0.061/0.116/0.032 ms
662
663
664
665
666
667在 Linux 使用 ping 命令﹐如果您不使用 -c N 参数来指定送出多少个封包的话﹐ping 命令会一直延续下去﹐直到您按 Ctrl + C 为止。从上面的命令结果我们可以确定联机是否成功之外﹐还可以根据它的 time 来判断当前的联机速度﹐数值越低速度越快﹔在命令结束的两行﹐还有一个总结﹐如果发现您的 packet loss 很严重的话﹐那就要检察您的线路品质﹐或是上游的服务品质了﹔最后一行是 round-trip (来回)时间的最小值﹑平均值﹑最大值﹐它们的时间单位都是微秒 (ms)。不过﹐那个 mdev 是什么意思我也不知道~~
668
669
670
671Tips﹕当我们能 ping 一台机器的时候﹐我们就可以确定联机是成功的﹐但如果不能 ping 的话﹐未必是连不上哦。嗯﹖怎么说呢﹖且听我道来﹕
672
673
674
675使用 ping 命令的时候﹐事实上是送出一个 echo-request 的 ICMP 封包﹐如果对方的机器能接收到这个请求﹐而且愿意作出响应﹐则送回一个 echo-reply 的 ICMP 封包﹐当这个响应能顺利抵达的时候﹐那就完成一个 ping 的动作。
676
677
678
679很显然﹐如果这个 echo-request 不能到达对方的机器﹐或是对方响应的 echo-reply 不能顺利送回来﹐那 ping 就失败。这情形在许多有防火墙的环境中都会碰到﹐如果防火墙随便将 request 和 reply 拦下来就会导致 ping 失败﹐但并不代表其它联机不能建立。另外﹐就算没有防火墙作怪﹐对方也可以将机器设定为不响应任何 echo-request 封包﹐只要用下面命令就可以了﹕
680
681
682
683echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_all
684
685
686
687
688
689如果您不想别人 ping 您的机器﹐也可以如法泡制。但真的当您需要用 ping 命令来测试网络联机的时候﹐就做不到了﹐有利有弊啦。
690
691
692
693traceroute
694
695
696
697除了用 ping 命令来检查联机之外﹐还有另外一个非常厉害的工具我们可以使用的﹐就是 traceroute 命令了(在 windows 上面则为 tracert 命令)﹕
698
699
700
701traceroute www.yahoo.com
702
703
704
705traceroute: Warning: www.yahoo.com has multiple addresses; using 216.115.102.78
706
707traceroute to www.yahoo.akadns.net (216.115.102.78), 30 hops max, 38 byte packets
708
7091 swtn184-1.adsl.seed.net.tw (211.74.184.1) 61.209 ms 63.117 ms 59.422 ms
710
7112 139.175.169.1 (139.175.169.1) 60.172 ms 64.253 ms 60.136 ms
712
7133 R58-38.seed.net.tw (139.175.58.38) 61.669 ms 59.185 ms 60.218 ms
714
7154 R58-201.seed.net.tw (139.175.58.201) 68.353 ms 70.353 ms 71.605 ms
716
7175 R57-99.seed.net.tw (139.175.57.99) 71.593 ms 70.570 ms 71.657 ms
718
7196 R58-166.seed.net.tw (139.175.58.166) 367.829 ms 350.511 ms 355.516 ms
720
7217 64.124.33.168.available.above.net (64.124.33.168) 218.493 ms 218.259 ms 219.996 ms
722
7238 * * *
724
7259 ge-2-3-0.msr1.pao.yahoo.com (216.115.101.34) 370.618 ms ge-3-3-0.msr2.pao.yahoo.com (216.115.101.38) 337.389 ms 349.591 ms
726
72710 vl21.bas2.snv.yahoo.com (216.115.100.229) 218.355 ms 217.388 ms vl20.bas1.snv.yahoo.com (216.115.100.225) 221.096 ms
728
72911 w6.snv.yahoo.com (216.115.102.78) 370.140 ms 339.934 ms 340.845 ms
730
731
732
733
734
735透过 traceroute 命令﹐我们可以找出通往目的地的所有经过的路由节点﹐并以数字将路由顺序标识出来。假如您加上 -n 参数的话﹐节点名称则会以 IP 地址显示﹐因为不需要进行名称解析﹐响应速度当然会快一些。
736
737
738
739从上面的 traceroute 结果﹐我们可以看到每一个节点都返回 3 个 round-trip 时间作参考。这样﹐您就能够判断整个联机路由中﹐交通瓶颈所在的位置在哪里。
740
741
742
743您或许奇怪 traceroute 是如何揪出所有路由节点的呢﹖且听我细说﹕
744
745
746
747您是否有留意到 ping 命令的结果有一个 TTL 值﹖通常来说﹐Time To Live 都是以时间为单位的﹐但是在路由上面却是以跳站数目为单位的。为了防止一个封包无限期呆在网络上路由﹐每一个封包都会被赋予一个 TTL 值﹐告诉它最多能经过多少个跳站。当封包被一个路由节点处理之后﹐它原来的 TTL 值就会被扣掉 1 ﹐这样﹐如果封包的 TTL 降到 0 的时候﹐路由器就会丢弃这个封包﹐并且同时向来源地送出一个 time_exceeded 的 ICMP 封包﹐以告知其封包的命运。
748
749
750
751找到灵感了吗﹖聪明的 traceroute 程序设计者正是利用了 ICMP 这个特殊功能﹐来找出每一个路由节点的﹕
752
753
754
7551\. 首先﹐traceroute 命令会向目标地址送出 UDP 侦测封包(echo, port 7)﹐但将第一个送出的封包之 TTL 设为 1 ﹐然后送节点的时候将 TTL 减为 1 使之变为 0 ﹐(注﹕ 还是 TTL 一开始就是 0 ﹐在送出的时候不进行减除? 这点我不确定)。这样﹐第一个路由节点在处理这个封包的时候﹐发现 TTL 为 0 ﹐预设就不处理这个封包﹐并同时送回一个 ICMP 封包﹐这样﹐发送端就知道第一个路由节点在哪里了。
756
757
758
7592\. 当接得到第一个 ICMP 返回的时候﹐程序会检查返回主机是否就是目标主机﹐如果不是﹐则再送出第二个封包﹐但 TTL 比上次增加 1 。
760
761
762
7633\. 这样﹐第一路由节点接到的封包之 TTL 就不是 0 ﹐那么处理完毕后送给下一个节点﹐同时将 TTL 扣除 1 ﹐这样也就变为 0 了。当下一个站收到这个 TTL 为 0 的封包﹐也会送回 ICMP 封包﹐这样﹐程序就知道第二个路由节点在哪里了。
764
765
766
7674\. 然后重上一个动作﹐直到找到目标主机为止﹐或是封包的最大 TTL (通常为 30) 都用光为止﹐但您可以用 -m 参数来指定最大的 TTL 值。
768
769
770
771怎样﹖聪明吧﹗
772
773
774
775但是﹐在实作中﹐未必是所有路由设备都会﹑或愿意送回 ICMP 封包的。碰到这样的情况﹐您就会看到第 8 个跳站的情形了。假如 traceroute 最后的结果一直维持着 * 符号﹐那可能是因为 ICMP 被对方的防火墙拦下来的结果。这样的话﹐您可能无法完成防火墙后的路由追踪了。
776
777
778
779Tips﹕从上面的例子来观察﹐由第 6 个跳站开始明显降慢下来﹐而根据名称看来﹐应该就是 ISP 连出 backbond 的节点。
780
781
782
783假如您发现从内部网络到自己的 router 之间的联机都很快﹐过了 router 之后就很慢﹐如果不少是专线的线路出现了问题﹐那很可能到了要升级专线的时候了﹐或是这时候刚好碰到有人大量使用频宽﹔假如速度过了 router 连到对方的机房还很快﹐然后就开始降下来﹐那您要好好审查一下当初和 ISP 签订的合约上﹐关于频宽的保证问题是如何说的﹔但如果您发现联机到国外的网站﹐而速度是从进入对方国家之后才降下来的﹐那就没什么办法好想了。
784
785
786
787mtr
788
789
790
791这又是什么命令﹖用一用就知道了﹕
792
793
794
795mtr www.yahoo.com
796
797
798
799Matt's traceroute [v0.42]
800
801rh71.siyongc.domain Thu Oct 18 01:38:39 2001
802
803Keys: D - Display mode R - Restart statistics Q - Quit
804
805Packets Pings
806
807Hostname %Loss Rcv Snt Last Best Avg Worst
808
8091\. 211.74.184.1 0% 3 3 70 67 70 73
810
8112\. 139.175.169.1 0% 3 3 66 66 66 67
812
8133\. 139.175.58.29 0% 3 3 75 73 74 75
814
8154\. 139.175.57.99 0% 3 3 72 72 74 75
816
8175\. 139.175.58.166 0% 3 3 221 217 220 222
818
8196\. 64.124.33.168 0% 2 3 224 221 223 224
820
8217\. ???
822
8238\. 216.115.101.38 0% 2 2 231 225 228 231
824
8259\. 216.115.100.225 0% 2 2 229 221 225 229
826
82710\. 216.115.105.2 0% 2 2 229 222 226 229
828
829
830
831
832
833事实上﹐您必须动手实作一下才知道这个命令的厉害之处﹕它将 ping 和 traceroute 两个命令结合在一起使用﹗除了告诉您每一个路由节点的地址之外(我这里用 -n 参数显示为 IP 地址)﹐同时还不断的将当前的最新 round-trip 时间动态的显示出来。不过﹐您可以在任何时候按 Ctrl + C才能终止这个程序。
834
835
836
837非常棒的工具﹐值得一试﹗
838
839
840
841netstat
842
843
844
845呵﹐这也是一个功能强大的工具﹐不过﹐它主要是用来检查主机的网络状态﹐而非用来检查联机速度用的。先让我们认识一下这个命令的一些参数吧﹕
846
847
848
849参数
850
851代表意思
852
853
854
855-a
856
857显示所有 socket ﹐不管是否处于 listening 状态。
858
859
860
861-t
862
863仅显示 TCP 协议相关的项目。
864
865
866
867-u
868
869仅显示 UDP 协议相关的项目。
870
871
872
873-w
874
875仅显示 RAW 协议相关的项目。
876
877
878
879-x
880
881仅显示 UNIX 协议相关的项目。
882
883
884
885-r
886
887显示系统的路由表格。
888
889
890
891-p
892
893显示与 socket 相关的程序名称及 PID 。
894
895
896
897-n
898
899不进行名称解析﹐直接以 IP 地址显示。 PID 。
900
901
902
903
904
905心动不如行动﹐不如马上动手实作一下吧﹕
906
907
908
909netstat -tna
910
911
912
913Active Internet connections (servers and established)
914
915Proto Recv-Q Send-Q Local Address Foreign Address State
916
917tcp 0 0 0.0.0.0:993 0.0.0.0:* LISTEN
918
919tcp 0 0 0.0.0.0:515 0.0.0.0:* LISTEN
920
921tcp 0 0 0.0.0.0:139 0.0.0.0:* LISTEN
922
923tcp 0 0 0.0.0.0:110 0.0.0.0:* LISTEN
924
925tcp 0 0 0.0.0.0:143 0.0.0.0:* LISTEN
926
927tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
928
929tcp 0 0 0.0.0.0:6000 0.0.0.0:* LISTEN
930
931tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
932
933tcp 0 0 0.0.0.0:113 0.0.0.0:* LISTEN
934
935tcp 0 0 211.74.184.205:53 0.0.0.0:* LISTEN
936
937tcp 0 0 10.0.1.131:53 0.0.0.0:* LISTEN
938
939tcp 0 0 10.0.1.1:53 0.0.0.0:* LISTEN
940
941tcp 0 0 192.168.100.23:53 0.0.0.0:* LISTEN
942
943tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN
944
945tcp 0 0 0.0.0.0:21 0.0.0.0:* LISTEN
946
947tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
948
949tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN
950
951tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN
952
953tcp 0 0 192.168.100.23:22 192.168.100.20:2610 ESTABLISHED
954
955tcp 0 0 192.168.100.23:139 192.168.100.20:2735 ESTABLISHED
956
957
958
959
960
961上面的命令是将系统所打开的所有 TCP socket 都显示出来﹐其中很重要的一个信息是 Send-Q ﹐假如这个数值大于 0 并且有增加的趋势﹐那就证明您的网络流量非常繁忙﹐要不是发生问题的话﹐那就是到了升级的时候了。如果您还想知道每一个 socket 是哪一个程序打开的﹐再加上一个 p 参数就可以了。
962
963
964
965Tip﹕要看系统的 socket 是有哪些程序关联的话﹐您还可以用 socklist 命令来显示。非常方便﹐不过在以前的 RedHat 版本是是没有的。
966
967
968
969除此之外﹐用 lsof 也可以显示哪些协议和程序所开启的档案﹐不过这个命令的参数很多﹐输入 -h 或用 man 看看吧。
970
971
972
973关于 netstat 命令﹐您还</version></m></m>