当谈及到网络系统层面,几乎任何东西都能由 Linux 来实现。Linux 被用来创建各式各样的网络系统和装置, 包括防火墙,路由器,名称服务器,网络连接式存储设备等等。 被用来配置和操作网络系统的命令数目,就如网络系统一样巨大。我们仅仅会关注一些最经常 使用到的命令。我们要研究的命令包括那些被用来监测网络和传输文件的命令。另外,我们 还会探讨用来远端登录的 ssh 程序。这章会介绍: > * ping - 发送 ICMP ECHO_REQUEST 软件包到网络主机 > * traceroute - 打印到一台网络主机的路由数据包 > * netstat - 打印网络连接,路由表,接口统计数据,伪装连接,和多路广播成员 > * ftp - 因特网文件传输程序 > * wget - 非交互式网络下载器 > * ssh - OpenSSH SSH 客户端(远程登录程序) 我们假定你已经知道了一点网络系统背景知识。在这个因特网时代,每个计算机用户需要理解基本的网络 系统概念。为了能够充分利用这一章节的内容,我们应该熟悉以下术语: * IP (网络协议)地址 * 主机和域名 * URI(统一资源标识符) 请查看下面的“拓展阅读”部分,有几篇关于这些术语的有用文章。 * * * 注意:一些将要讲到的命令可能(取决于系统发行版)需要从系统发行版的仓库中安装额外的软件包, 并且一些命令可能需要超级用户权限才能执行。 * * * ## 检查和监测网络 即使你不是一名系统管理员,检查一个网络的性能和运作情况也是经常有帮助的。 ### ping 最基本的网络命令是 ping。这个 ping 命令发送一个特殊的网络数据包,叫做 IMCP ECHO_REQUEST,到 一台指定的主机。大多数接收这个包的网络设备将会回复它,来允许网络连接验证。 * * * 注意:大多数网络设备(包括 Linux 主机)都可以被配置为忽略这些数据包。通常,这样做是出于网络安全 原因,部分地遮蔽一台主机免受一个潜在攻击者地侵袭。配置防火墙来阻塞 IMCP 流量也很普遍。 * * * 例如,看看我们能否连接到网站 linuxcommand.org(我们最喜欢的网站之一), 我们可以这样使用 ping 命令: ~~~ [me@linuxbox ~]$ ping linuxcommand.org ~~~ 一旦启动,ping 命令会持续在特定的时间间隔内(默认是一秒)发送数据包,直到它被中断: ~~~ [me@linuxbox ~]$ ping linuxcommand.org PING linuxcommand.org (66.35.250.210) 56(84) bytes of data. 64 bytes from vhost.sourceforge.net (66.35.250.210): icmp\_seq=1 ttl=43 time=107 ms 64 bytes from vhost.sourceforge.net (66.35.250.210): icmp\_seq=2 ttl=43 time=108 ms 64 bytes from vhost.sourceforge.net (66.35.250.210): icmp\_seq=3 ttl=43 time=106 ms 64 bytes from vhost.sourceforge.net (66.35.250.210): icmp\_seq=4 ttl=43 time=106 ms 64 bytes from vhost.sourceforge.net (66.35.250.210): icmp\_seq=5 ttl=43 time=105 ms ... ~~~ 按下组合键 Ctrl-c,中断这个命令之后,ping 打印出运行统计信息。一个正常工作的网络会报告 零个数据包丢失。一个成功执行的“ping”命令会意味着网络的各个部件(网卡,电缆,路由,网关) 都处于正常的工作状态。 ### traceroute 这个 traceroute 程序(一些系统使用相似的 tracepath 程序来代替)会显示从本地到指定主机 要经过的所有“跳数”的网络流量列表。例如,看一下到达 slashdot.org 网站,需要经过的路由 器,我们将这样做: ~~~ [me@linuxbox ~]$ traceroute slashdot.org ~~~ 命令输出看起来像这样: ~~~ traceroute to slashdot.org (216.34.181.45), 30 hops max, 40 byte packets 1 ipcop.localdomain (192.168.1.1) 1.066 ms 1.366 ms 1.720 ms 2 * * * 3 ge-4-13-ur01.rockville.md.bad.comcast.net (68.87.130.9) 14.622 ms 14.885 ms 15.169 ms 4 po-30-ur02.rockville.md.bad.comcast.net (68.87.129.154) 17.634 ms 17.626 ms 17.899 ms 5 po-60-ur03.rockville.md.bad.comcast.net (68.87.129.158) 15.992 ms 15.983 ms 16.256 ms 6 po-30-ar01.howardcounty.md.bad.comcast.net (68.87.136.5) 22.835 ... ~~~ 从输出结果中,我们可以看到连接测试系统到 slashdot.org 网站需要经由16个路由器。对于那些 提供标识信息的路由器,我们能看到它们的主机名,IP 地址和性能数据,这些数据包括三次从本地到 此路由器的往返时间样本。对于那些没有提供标识信息的路由器(由于路由器配置,网络拥塞,防火墙等 方面的原因),我们会看到几个星号,正如行中所示。 ### netstat netstat 程序被用来检查各种各样的网络设置和统计数据。通过此命令的许多选项,我们 可以看看网络设置中的各种特性。使用“-ie”选项,我们能够查看系统中的网络接口: ~~~ [me@linuxbox ~]$ netstat -ie eth0 Link encap:Ethernet HWaddr 00:1d:09:9b:99:67 inet addr:192.168.1.2 Bcast:192.168.1.255 Mask:255.255.255.0 inet6 addr: fe80::21d:9ff:fe9b:9967/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:238488 errors:0 dropped:0 overruns:0 frame:0 TX packets:403217 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:100 RX bytes:153098921 (146.0 MB) TX bytes:261035246 (248.9 MB) Memory:fdfc0000-fdfe0000 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 ... ~~~ 在上述实例中,我们看到我们的测试系统有两个网络接口。第一个,叫做 eth0,是 因特网接口,和第二个,叫做 lo,是内部回环网络接口,它是一个虚拟接口,系统用它来 “自言自语”。 当执行日常网络诊断时,要查看的重要信息是每个网络接口第四行开头出现的单词 “UP”,说明这个网络接口已经生效,还要查看第二行中 inet addr 字段出现的有效 IP 地址。对于使用 DHCP(动态主机配置协议)的系统,在 这个字段中的一个有效 IP 地址则证明了 DHCP 工作正常。 使用这个“-r”选项会显示内核的网络路由表。这展示了系统是如何配置网络之间发送数据包的。 ~~~ [me@linuxbox ~]$ netstat -r Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface 192.168.1.0 * 255.255.255.0 U 0 0 0 eth0 default 192.168.1.1 0.0.0.0 UG 0 0 0 eth0 ~~~ 在这个简单的例子里面,我们看到了,位于防火墙之内的局域网中,一台客户端计算机的典型路由表。 第一行显示了目的地 192.168.1.0。IP 地址以零结尾是指网络,而不是个人主机, 所以这个目的地意味着局域网中的任何一台主机。下一个字段,Gateway, 是网关(路由器)的名字或 IP 地址,用它来连接当前的主机和目的地的网络。 若这个字段显示一个星号,则表明不需要网关。 最后一行包含目的地 default。指的是发往任何表上没有列出的目的地网络的流量。 在我们的实例中,我们看到网关被定义为地址 192.168.1.1 的路由器,它应该能 知道怎样来处理目的地流量。 netstat 程序有许多选项,我们仅仅讨论了几个。查看 netstat 命令的手册,可以 得到所有选项的完整列表。 ## 网络中传输文件 网络有什么用处呢?除非我们知道了怎样通过网络来传输文件。有许多程序可以用来在网络中 传送数据。我们先讨论两个命令,随后的章节里再介绍几个命令。 ### ftp ftp 命令属于真正的“经典”程序之一,它的名字来源于其所使用的协议,就是文件传输协议。 FTP 被广泛地用来从因特网上下载文件。大多数,并不是所有的,网络浏览器都支持 FTP, 你经常可以看到它们的 URI 以协议 ftp://开头。在出现网络浏览器之前,ftp 程序已经存在了。 ftp 程序可用来与 FTP 服务器进行通信,FTP 服务器就是存储文件的计算机,这些文件能够通过 网络下载和上传。 FTP(它的原始形式)并不是安全的,因为它会以明码形式发送帐号的姓名和密码。这就意味着 这些数据没有加密,任何嗅探网络的人都能看到。由于此种原因,几乎因特网中所有 FTP 服务器 都是匿名的。一个匿名服务器能允许任何人使用注册名“anonymous”和无意义的密码登录系统。 在下面的例子中,我们将展示一个典型的会话,从匿名 FTP 服务器,其名字是 fileserver, 的/pub/_images/Ubuntu-8.04的目录下,使用 ftp 程序下载一个 Ubuntu 系统映像文件。 ~~~ [me@linuxbox ~]$ ftp fileserver Connected to fileserver.localdomain. 220 (vsFTPd 2.0.1) Name (fileserver:me): anonymous 331 Please specify the password. Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp> cd pub/cd\_images/Ubuntu-8.04 250 Directory successfully changed. ftp> ls 200 PORT command successful. Consider using PASV. 150 Here comes the directory listing. -rw-rw-r-- 1 500 500 733079552 Apr 25 03:53 ubuntu-8.04- desktop-i386.iso 226 Directory send OK. ftp> lcd Desktop Local directory now /home/me/Desktop ftp> get ubuntu-8.04-desktop-i386.iso local: ubuntu-8.04-desktop-i386.iso remote: ubuntu-8.04-desktop- i386.iso 200 PORT command successful. Consider using PASV. 150 Opening BINARY mode data connection for ubuntu-8.04-desktop- i386.iso (733079552 bytes). 226 File send OK. 733079552 bytes received in 68.56 secs (10441.5 kB/s) ftp> bye ~~~ 这里是对会话期间所输入命令的解释说明: 表17-1: | 命令 | 意思 | |---------|------------| | ftp fileserver | 唤醒 ftp 程序,让它连接到 FTP 服务器,fileserver。 | | anonymous | 登录名。输入登录名后,将出现一个密码提示。一些服务器将会接受空密码, 其它一些则会要求一个邮件地址形式的密码。如果是这种情况,试着输入 “user@example.com”。 | | cd pub/cd_images/Ubuntu-8.04 | 跳转到远端系统中,要下载文件所在的目录下, 注意在大多数匿名的 FTP 服务器中,支持公共下载的文件都能在目录 pub 下找到 | | ls | 列出远端系统中的目录。 | | lcd Desktop | 跳转到本地系统中的 ~/Desktop 目录下。在实例中,ftp 程序在工作目录 ~ 下被唤醒。 这个命令把工作目录改为 ~/Desktop | | get ubuntu-8.04-desktop-i386.iso | 告诉远端系统传送文件到本地。因为本地系统的工作目录 已经更改到了 ~/Desktop,所以文件会被下载到此目录。 | | bye | 退出远端服务器,结束 ftp 程序会话。也可以使用命令 quit 和 exit。 | 在 “ftp>” 提示符下,输入 “help”,会显示所支持命令的列表。使用 ftp 登录到一台 授予了用户足够权限的服务器中,则可以执行很多普通的文件管理任务。虽然很笨拙, 但它真能工作。 ### lftp - 更好的 ftp ftp 并不是唯一的命令行形式的 FTP 客户端。实际上,还有很多。其中比较好(也更流行的)是 lftp 程序, 由 Alexander Lukyanov 编写完成。虽然 lftp 工作起来与传统的 ftp 程序很相似,但是它带有额外的便捷特性,包括 多协议支持(包括 HTTP),若下载失败会自动地重新下载,后台处理,用 tab 按键来补全路径名,还有很多。 ### wget 另一个流行的用来下载文件的命令行程序是 wget。若想从网络和 FTP 网站两者上都能下载数据,wget 是很有用处的。 不只能下载单个文件,多个文件,甚至整个网站都能下载。下载 linuxcommand.org 网站的首页, 我们可以这样做: ~~~ [me@linuxbox ~]$ wget http://linuxcommand.org/index.php --11:02:51-- http://linuxcommand.org/index.php => `index.php' Resolving linuxcommand.org... 66.35.250.210 Connecting to linuxcommand.org|66.35.250.210|:80... connected. HTTP request sent, awaiting response... 200 OK Length: unspecified [text/html] [ < => ] 3,120 --.--K/s 11:02:51 (161.75 MB/s) - 'index.php' saved [3120] ~~~ 这个程序的许多选项允许 wget 递归地下载,在后台下载文件(你退出后仍在下载),能完成未下载 全的文件。这些特性在命令手册,better-than-average 一节中有详尽地说明。 ## 与远程主机安全通信 通过网络来远程操控类 Unix 的操作系统已经有很多年了。早些年,在因特网普遍推广之前,有 一些受欢迎的程序被用来登录远程主机。它们是 rlogin 和 telnet 程序。然而这些程序,拥有和 ftp 程序 一样的致命缺点;它们以明码形式来传输所有的交流信息(包括登录命令和密码)。这使它们完全不 适合使用在因特网时代。 ### ssh 为了解决这个问题,开发了一款新的协议,叫做 SSH(Secure Shell)。 SSH 解决了这两个基本的和远端主机安全交流的问题。首先,它要认证远端主机是否为它 所知道的那台主机(这样就阻止了所谓的“中间人”的攻击),其次,它加密了本地与远程主机之间 所有的通讯信息。 SSH 由两部分组成。SSH 服务器运行在远端主机上运行,在端口号22上监听将要到来的连接,而 SSH 客户端用在本地系统中,用来和远端服务器通信。 大多数 Linux 发行版自带一个提供 SSH 功能的软件包,叫做 OpenSSH,来自于 BSD 项目。一些发行版 默认包含客户端和服务器端两个软件包(例如,Red Hat),而另一些(比方说 Ubuntu)则只是提供客户端服务。为了能让系统接受远端的连接,它必须 安装 OpenSSH-server 软件包,配置,运行它,并且(如果系统正在运行,或者是在防火墙之后) 它必须允许在 TCP 端口号上接收网络连接。 * * * 小贴示:如果你没有远端系统去连接,但还想试试这些实例,则确认安装了 OpenSSH-server 软件包 ,则可使用 localhost 作为远端主机的名字。这种情况下,计算机会和它自己创建网络连接。 * * * 用来与远端 SSH 服务器相连接的 SSH 客户端程序,顺理成章,叫做 ssh。连接到远端名为 remote-sys 的主机,我们可以这样使用 ssh 客户端程序: ~~~ [me@linuxbox ~]$ ssh remote-sys The authenticity of host 'remote-sys (192.168.1.4)' can't be established. RSA key fingerprint is 41:ed:7a:df:23:19:bf:3c:a5:17:bc:61:b3:7f:d9:bb. Are you sure you want to continue connecting (yes/no)? ~~~ 第一次尝试连接,提示信息表明远端主机的真实性不能确立。这是因为客户端程序以前从没有 看到过这个远端主机。为了接受远端主机的身份验证凭据,输入“yes”。一旦建立了连接,会提示 用户输入他或她的密码: ~~~ Warning: Permanently added 'remote-sys,192.168.1.4' (RSA) to the list of known hosts. me@remote-sys's password: ~~~ 成功地输入密码之后,我们会接收到远端系统的 shell 提示符: ~~~ Last login: Sat Aug 30 13:00:48 2008 [me@remote-sys ~]$ ~~~ 远端 shell 会话一直存在,直到用户输入 exit 命令后,则关闭了远程连接。这时候,本地的 shell 会话 恢复,本地 shell 提示符重新出现。 也有可能使用不同的用户名连接到远程系统。例如,如果本地用户“me”,在远端系统中有一个帐号名 “bob”,则用户 me 能够用 bob 帐号登录到远端系统,如下所示: ~~~ [me@linuxbox ~]$ ssh bob@remote-sys bob@remote-sys's password: Last login: Sat Aug 30 13:03:21 2008 [bob@remote-sys ~]$ ~~~ 正如之前所讲到的,ssh 验证远端主机的真实性。如果远端主机不能成功地通过验证,则会提示以下信息: ~~~ [me@linuxbox ~]$ ssh remote-sys @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you right now (man-in-the-middle attack)! ... ~~~ 有两种可能的情形会提示这些信息。第一,某个攻击者企图制造“中间人”袭击。这很少见, 因为每个人都知道 ssh 会针对这种状况发出警告。最有可能的罪魁祸首是远端系统已经改变了; 例如,它的操作系统或者是 SSH 服务器重新安装了。然而,为了安全起见,第一个可能性不应该 被轻易否定。当这条消息出现时,总要与远端系统的管理员查对一下。 当确定了这条消息归结为一个良性的原因之后,那么在客户端更正问题就很安全了。 使用文本编辑器(可能是 vim)从文件~/.ssh/known_hosts 中删除废弃的钥匙, 就解决了问题。在上面的例子里,我们看到这样一句话: ~~~ Offending key in /home/me/.ssh/known_hosts:1 ~~~ 这意味着文件 known_hosts 里面某一行包含攻击型的钥匙。从文件中删除这一行,则 ssh 程序 就能够从远端系统接受新的身份验证凭据。 除了能够在远端系统中打开一个 shell 会话,ssh 程序也允许我们在远端系统中执行单个命令。 例如,在名为 remote-sys 的远端主机上,执行 free 命令,并把输出结果显示到本地系统 shell 会话中。 ~~~ [me@linuxbox ~]$ ssh remote-sys free me@twin4's password: total used free shared buffers cached Mem: 775536 507184 268352 0 110068 154596 -/+ buffers/cache: 242520 533016 Swap: 0 1572856 0 110068 154596 [me@linuxbox ~]$ ~~~ 有可能以更有趣的方式来利用这项技术,比方说下面的例子,我们在远端系统中执行 ls 命令, 并把命令输出重定向到本地系统中的一个文件里面。 ~~~ [me@linuxbox ~]$ ssh remote-sys 'ls \*' > dirlist.txt me@twin4's password: [me@linuxbox ~]$ ~~~ 注意,上面的例子中使用了单引号。这样做是因为我们不想路径名展开操作在本地执行 ;而希望 它在远端系统中被执行。同样地,如果我们想要把输出结果重定向到远端主机的文件中,我们可以 把重定向操作符和文件名都放到单引号里面。 ~~~ [me@linuxbox ~]$ ssh remote-sys 'ls * > dirlist.txt' ~~~ > SSH 通道 > > 当你通过 SSH 协议与远端主机建立连接的时候,其中发生的事就是在本地与远端系统之间 创建了一条加密通道。通常,这条通道被用来把在本地系统中输入的命令安全地传输到远端系统, 同样地,再把执行结果安全地发送回来。除了这个基本功能之外,SSH 协议允许大多数 网络流量类型通过这条加密通道来被传送,在本地与远端系统之间创建某种 VPN(虚拟专用网络)。 > > 可能这个特性的最普遍使用是允许传递 X 窗口系统流量。在运行着 X 服务器(也就是, 能显示 GUI 的机器)的系统中,有可能在远端启动和运行一个 X 客户端程序(一个图形化应用程序), 而应用程序的显示结果出现在本地。这很容易完成,这里有个例子:假设我们正坐在一台装有 Linux 系统, 叫做 linuxbox 的机器之前,且系统中运行着 X 服务器,现在我们想要在名为 remote-sys 的远端系统中 运行 xload 程序,但是要在我们的本地系统中看到这个程序的图形化输出。我们可以这样做: > > ~~~ > [me@linuxbox ~]$ ssh -X remote-sys > me@remote-sys's password: > Last login: Mon Sep 08 13:23:11 2008 > [me@remote-sys ~]$ xload > > ~~~ > > 这个 xload 命令在远端执行之后,它的窗口就会出现在本地。在某些系统中,你可能需要 使用 “-Y” 选项,而不是 “-X” 选项来完成这个操作。 ### scp 和 sftp 这个 OpenSSH 软件包也包含两个程序,它们可以利用 SSH 加密通道在网络间复制文件。 第一个,scp(安全复制)被用来复制文件,与熟悉的 cp 程序非常相似。最显著的区别就是 源或者目标路径名要以远端主机的名字,后跟一个冒号字符开头。例如,如果我们想要 从远端系统,remote-sys,的家目录下复制文档 document.txt,到我们本地系统的当前工作目录下, 可以这样操作: ~~~ [me@linuxbox ~]$ scp remote-sys:document.txt . me@remote-sys's password: document.txt 100% 5581 5.5KB/s 00:00 [me@linuxbox ~]$ ~~~ 和 ssh 命令一样,如果你所期望的远端主机帐户与你本地系统中的不一致, 则可以把用户名添加到远端主机名的开头。 ~~~ [me@linuxbox ~]$ scp bob@remote-sys:document.txt . ~~~ 第二个 SSH 文件复制命令是 sftp,正如其名字所示,它是 ftp 程序的安全替代品。sftp 工作起来与我们 之前使用的 ftp 程序很相似;然而,它不用明码形式来传递数据,它使用加密的 SSH 通道。sftp 有一个 重要特性强于传统的 ftp 命令,就是 sftp 不需要远端系统中运行 FTP 服务器。它仅仅要求 SSH 服务器。 这意味着任何一台能用 SSH 客户端连接的远端机器,也可当作类似于 FTP 的服务器来使用。 这里是一个样本会话: ~~~ [me@linuxbox ~]$ sftp remote-sys Connecting to remote-sys... me@remote-sys's password: sftp> ls ubuntu-8.04-desktop-i386.iso sftp> lcd Desktop sftp> get ubuntu-8.04-desktop-i386.iso Fetching /home/me/ubuntu-8.04-desktop-i386.iso to ubuntu-8.04- desktop-i386.iso /home/me/ubuntu-8.04-desktop-i386.iso 100% 699MB 7.4MB/s 01:35 sftp> bye ~~~ * * * 小贴示:这个 SFTP 协议被许多 Linux 发行版中的图形化文件管理器支持。使用 Nautilus (GNOME), 或者是 Konqueror (KDE),我们都能在位置栏中输入以 sftp:// 开头的 URI, 来操作存储在运行着 SSH 服务器的远端系统中的文件。 * * * > Windows 中的 SSH 客户端 > > 比方说你正坐在一台 Windows 机器前面,但是你需要登录到你的 Linux 服务器中,去完成 一些实际的工作,那该怎么办呢?当然是得到一个 Windows 平台下的 SSH 客户端!有很多这样 的工具。最流行的可能就是由 Simon Tatham 和他的团队开发的 PuTTY 了。这个 PuTTY 程序 能够显示一个终端窗口,而且允许 Windows 用户在远端主机中打开一个 SSH(或者 telnet)会话。 这个程序也提供了 scp 和 sftp 程序的类似物。 > > PuTTY 可在链接 [http://www.chiark.greenend.org.uk/~sgtatham/putty/](http://www.chiark.greenend.org.uk/~sgtatham/putty/) 处得到。 ## 拓展阅读 * Linux 文档项目提供了 Linux 网络管理指南,可以广泛地(虽然过时了)了解网络管理方面的知识。 [http://tldp.org/LDP/nag2/index.html](http://tldp.org/LDP/nag2/index.html) * Wikipedia 上包含了许多网络方面的优秀文章。这里有一些基础的: [http://en.wikipedia.org/wiki/Internet_protocol_address](http://en.wikipedia.org/wiki/Internet_protocol_address) [http://en.wikipedia.org/wiki/Host_name](http://en.wikipedia.org/wiki/Host_name) [http://en.wikipedia.org/wiki/Uniform_Resource_Identifier](http://en.wikipedia.org/wiki/Uniform_Resource_Identifier)