There are several ways to automatically configure networks in Linux-based systems. The most widely used option on desktops and notebooks is NetworkManager. Other network configuration management systems are mainly targeted for smaller embedded systems, such as OpenWRT’s netifd, Android’s ConnectivityManager service, ConnMan, and Wicd. We’ll briefly discuss NetworkManager because it’s the one you’re most likely to encounter. We won’t go into a tremendous amount of detail, though, because after you see the big picture, NetworkManager and other configuration systems will be more transparent
在基于Linux的系统中,有几种自动配置网络的方法。
在台式机和笔记本上,最常用的选项是NetworkManager。
其他网络配置管理系统主要针对较小的嵌入式系统,例如OpenWRT的netifd、Android的ConnectivityManager服务、ConnMan和Wicd。
我们将简要讨论NetworkManager,因为这是您最有可能遇到的。
虽然我们不会详细介绍,但在您了解整体情况之后,NetworkManager和其他配置系统将更加透明。
NetworkManager is a daemon that the system starts upon boot. Like all daemons, it does not depend on a running desktop component. Its job is to listen to events from the system and users and to change the network configuration based on a bunch of rules.
NetworkManager是系统启动时系统启动的守护进程。与所有守护进程一样,它不依赖于运行的桌面组件。它的工作是监听来自系统和用户的事件,并根据一系列规则改变网络配置。
When running, NetworkManager maintains two basic levels of configuration. The first is a collection of information about available hardware devices, which it normally collects from the kernel and maintains by monitoring udev over the Desktop Bus (D-Bus). The second configuration level is a more specific list of connections: hardware devices and additional physical and network layer configuration parameters. For example, a wireless network can be represented as a connection.
运行时,NetworkManager维护两个基本级别的配置。
第一个是有关可用硬件设备的信息集合,通常它从内核中收集并通过监听udev在桌面总线(D-Bus)上维护。
第二个配置级别是更具体的连接列表:硬件设备和附加的物理和网络层配置参数。
例如,无线网络可以表示为一个连接。
To activate a connection, NetworkManager often delegates the tasks to other specialized network tools and daemons such as dhclient to get Internet layer configuration from a locally attached physical network. Because network configuration tools and schemes vary among distributions, NetworkManager uses plugins to interface with them, rather than imposing its own standard. There are plugins for the both the Debian/ Ubuntu and Red Hat–style interface configuration, for example.
为了激活一个连接,NetworkManager通常将任务委托给其他专门的网络工具和守护进程,例如使用dhclient从本地连接的物理网络获取Internet层配置。
由于网络配置工具和方案在不同的发行版中有所不同,NetworkManager使用插件与它们进行接口交互,而不是强加自己的标准。
例如,有适用于Debian/Ubuntu和Red Hat风格接口配置的插件。
Upon startup, NetworkManager gathers all available network device information, searches its list of connections, and then decides to try to activate one. Here’s how it makes that decision for Ethernet interfaces:
启动时,NetworkManager收集所有可用的网络设备信息,搜索其连接列表,然后决定尝试激活一个连接。以下是它在以太网接口上做出决策的方式:
After establishing a connection, NetworkManager maintains it until the connection is lost, a better network becomes available (for example, you plug in a network cable while connected over wireless), or the user forces a change.
建立连接后,NetworkManager将保持连接直到连接丢失、有更好的网络可用(例如,您在无线连接的同时插入了网络电缆)或用户强制进行更改。
Most users interact with NetworkManager through an applet on the desktop—it’s usually an icon in the upper or lower right that indicates the connection status (wired, wireless, or not connected). When you click on the icon, you get a number of connectivity options, such as a choice of wireless networks and an option to disconnect from your current network. Each desktop environment has its own version of this applet, so it looks a little different on each one.、
大多数用户通过桌面上的一个小程序与NetworkManager进行交互——通常是位于右上角或右下角的一个图标,用于显示连接状态(有线、无线或未连接)。
当你点击这个图标时,会出现一系列的连接选项,比如选择无线网络和断开当前网络的选项。
每个桌面环境都有自己的这个小程序版本,所以在每个环境下都会有些许不同。
In addition to the applet, there are a few tools that you can use to query and control NetworkManager from your shell. For a very quick summary of your current connection status, use the nm-tool command with no arguments. You’ll get a list of interfaces and configuration parameters. In some ways, this is like ifconfig except that there’s more detail, especially when viewing wireless connections.
除了小程序之外,还有一些工具可以在命令行中查询和控制NetworkManager。
要快速查看当前连接状态的简要摘要,可以使用不带参数的nm-tool命令。
你将得到一个接口和配置参数的列表。在某些方面,这类似于ifconfig,但是显示的细节更多,特别是在查看无线连接时。
To control NetworkManager from the command line, use the nmcli command. This is a somewhat extensive command. See the nmcli(1) manual page for more information. Finally, the utility nm-online will tell you whether the network is up or down. If the network is up, the command returns zero as its exit code; it’s nonzero otherwise. (For more on how to use an exit code in a shell script, see Chapter 11.)
要通过命令行控制NetworkManager,可以使用nmcli命令。
这是一个相对复杂的命令。请参阅nmcli(1)手册页面获取更多信息。
最后,实用工具nm-online会告诉你网络是连接还是断开。
如果网络连接正常,该命令的退出代码将返回零;否则为非零。
(有关如何在shell脚本中使用退出代码的更多信息,请参阅第11章。)
The general configuration directory for NetworkManager is usually /etc/NetworkManager, and there are several different kinds of configuration. The general configuration file is NetworkManager.conf. The format is similar to the XDG-style .desktop and Microsoft .ini files, with key-value parameters falling into different sections. You’ll find that nearly every configuration file has a main section that defines the plugins to use. Here’s a simple example that activates the ifupdown plugin used by Ubuntu and Debian:
NetworkManager的通用配置目录通常是/etc/NetworkManager,有几种不同类型的配置。
通用配置文件是NetworkManager.conf。
其格式类似于XDG风格的.desktop和Microsoft .ini文件,具有键-值参数分布在不同的部分中。
你会发现几乎每个配置文件都有一个main部分,用于定义要使用的插件。
以下是一个简单的示例,激活Ubuntu和Debian使用的ifupdown插件:
[main]
plugins=ifupdown,keyfile
Other distribution-specific plugins are ifcfg-rh (for Red Hat–style distributions) and ifcfg-suse (for SuSE). The keyfile plugin that you also see here supports NetworkManager’s native configuration file support. When using the plugin, you can see the system’s known connections in /etc/NetworkManager/system-connections.
其他特定于发行版的插件包括 ifcfg-rh(用于红帽风格的发行版)和 ifcfg-suse(用于SuSE)。
您在这里看到的 keyfile 插件支持 NetworkManager 的本地配置文件支持。
使用该插件时,您可以在 /etc/NetworkManager/system-connections 中看到系统已知的连接。
For the most part, you won’t need to change NetworkManager.conf because the more specific configuration options are found in other files.
在大多数情况下,您不需要更改 NetworkManager.conf,因为更具体的配置选项可以在其他文件中找到。
Although you may want NetworkManager to manage most of your network interfaces, there will be times when you want it to ignore interfaces. For example, there’s no reason why most users would need any kind of dynamic configuration on the localhost (lo) interface because the configuration never changes. You also want to configure this interface early in the boot process because basic system services often depend on it. Most distributions keep NetworkManager away from localhost.
尽管您可能希望NetworkManager管理大部分网络接口,但有时您希望它忽略某些接口。
例如,大多数用户不需要在本地回环(lo)接口上进行任何动态配置,因为该配置永远不会改变。您还希望在引导过程的早期配置此接口,因为基本系统服务通常依赖于它。
大多数发行版都将NetworkManager与本地回环隔离开来。
You can tell NetworkManager to disregard an interface by using plugins. If you’re using the ifupdown plugin (for example, in Ubuntu and Debian), add the interface configuration to your /etc/network/interfaces file and then set the value of managed to false in the ifupdown section of the NetworkManager.conf file:
您可以通过使用插件告诉NetworkManager忽略某个接口。
如果您正在使用ifupdown插件(例如,在Ubuntu和Debian中),请将接口配置添加到/etc/network/interfaces文件中,然后在NetworkManager.conf文件的ifupdown部分将managed的值设置为false:
[ifupdown]
managed=false
For the ifcfg-rh plugin that Fedora and Red Hat use, look for a line like this in the /etc/sysconfig/networkscripts directory that contains the ifcfg-* configuration files:
对于 Fedora 和 Red Hat 使用的 ifcfg-rh 插件,请在 /etc/sysconfig/network-scripts 目录中查找包含 ifcfg-* 配置文件的行,类似于这样的行:
NM_CONTROLLED=yes
If this line is not present or the value is set to no, NetworkManager ignores the interface. For example, you’ll find it deactivated in the ifcfg-lo file. You can also specify a hardware address to ignore, like this:
如果不存在这一行,或者该数值设置为“no”,NetworkManager 将忽略该接口。
例如,在 ifcfg-lo 文件中,你会发现它被停用了。你也可以指定一个要忽略的硬件地址,就像这样:
HWADDR=10:78:d2:eb:76:97
If you don’t use either of these network configuration schemes, you can still use the keyfile plugin to specify the unmanaged device directly inside your NetworkManager.conf file using the MAC address. Here’s how that might look:
如果您不使用这两种网络配置方案中的任何一种,仍然可以使用keyfile插件,通过MAC地址直接在NetworkManager.conf文件中指定未受管设备。下面是可能的示例:
[keyfile]
unmanaged-devices=mac:10:78:d2:eb:76:97;mac:1c:65:9d:cc:ff:b9
One final detail of NetworkManager configuration relates to specifiying additional system actions for when a network interface goes up or down. For example, some network daemons need to know when to start or stop listening on an interface in order to work correctly (such as the secure shell daemon discussed in the next chapter).
NetworkManager配置的最后一个细节与指定网络接口上下线时的其他系统操作有关。
例如,某些网络守护程序需要知道何时在接口上开始或停止监听,以便正常工作(如下一章中讨论的安全外壳守护程序)。
When the network interface status on a system changes, NetworkManager runs everything in /etc/NetworkManager/dispatcher.d with an argument such as up or down. This is relatively straightforward, but many distributions have their own network control scripts so they don’t place the individual dispatcher scripts in this directory. Ubuntu, for example, has just one script named 01ifupdown that runs everything in an appropriate subdirectory of /etc/network, such as /etc/network/if-up.d.
当系统上的网络接口状态发生变化时,NetworkManager会在/etc/NetworkManager/dispatcher.d中运行所有脚本,并带有up或down等参数。
这相对简单,但许多发行版都有自己的网络控制脚本,因此它们不会将各个调度程序脚本放在此目录中。
例如,Ubuntu只有一个名为01ifupdown的脚本,它会在/etc/network的适当子目录中运行所有脚本,如/etc/network/if-up.d。
As with the rest of the NetworkManager configuration, the details of these scripts are relatively unimportant; all you need to know is how to track down the appropriate location if you need to make an addition or change. As ever, don’t be shy about looking at scripts on your system.
与NetworkManager配置的其余部分一样,这些脚本的细节相对不重要;
你只需要知道如何找到适当的位置,以便在需要添加或更改时进行操作。
在查看系统上的脚本时,不要犹豫。
One of the final basic tasks in any network configuration is hostname resolution with DNS. You’ve already seen the host resolution tool that translates a name such as www.example.com to an IP address such as 10.23.2.132.
在任何网络配置中,主机名解析与DNS是最后一个基本任务之一。你已经看到了主机解析工具,它将诸如www.example.com这样的名称转换为诸如10.23.2.132这样的IP地址。
DNS differs from the network elements we’ve looked at so far because it’s in the application layer, entirely in user space. Technically, it is slightly out of place in this chapter alongside the Internet and physical layer discussion, but without proper DNS configuration, your Internet connection is practically worthless. No one in their right mind advertises IP addresses for websites and email addresses because a host’s IP address is subject to change and it’s not easy to remember a bunch of numbers. Automatic network configuration services such as DHCP nearly always include DNS configuration.
DNS与我们迄今为止所看到的网络元素不同,因为它位于应用层,完全在用户空间中。
从技术上讲,在本章中,它稍微有些不合适,因为没有正确的DNS配置,你的互联网连接几乎毫无价值。
没有人会为网站和电子邮件地址广告IP地址,因为主机的IP地址可能会改变,而且很难记住一堆数字。
自动网络配置服务(如DHCP)几乎总是包括DNS配置。
Nearly all network applications on a Linux system perform DNS lookups. The resolution process typically unfolds like this:
Linux系统上几乎所有的网络应用程序都执行DNS查找。解析过程通常如下:
This is the simplified version. In a typical modern system, there are more actors attempting to speed up the transaction and/or add flexibility. Let’s ignore that for now and take a closer look at the basic pieces.
这是简化版本。在一个典型的现代系统中,有更多的参与者试图加速交易和/或增加灵活性。
现在我们先忽略这些,更仔细地看看基本的部分。
On most systems, you can override hostname lookups with the /etc/hosts file. It usually looks like this:
在大多数系统上,您可以通过/etc/hosts
文件覆盖主机名查找。
它通常看起来像这样:
127.0.0.1 localhost
10.23.2.3 atlantic.aem7.net atlantic
10.23.2.4 pacific.aem7.net pacific
You’ll nearly always see the entry for localhost here (see 9.13 Localhost).
NOTE In the bad old days, there was one central hosts file that everyone copied to their own machine in order to stay up-to-date (see RFCs 606, 608, 623, and 625), but as the ARPANET/Internet grew, this quickly got out of hand.注意 在过去的旧日子里,曾经有一个集中的hosts文件,每个人都要将其复制到自己的机器上以保持最新(请参见RFC 606、608、623和625),但随着ARPANET/互联网的发展,这很快就失控了。
The traditional configuration file for DNS servers is /etc/resolv.conf. When things were simpler, a typical example might have looked like this, where the ISP’s name server addresses are 10.32.45.23 and 10.3.2.3:
DNS 服务器的传统配置文件是 /etc/resolv.conf。
在事情变得更简单的时候,一个典型的例子可能看起来像这样,其中ISP的名称服务器地址是 10.32.45.23 和 10.3.2.3:
search mydomain.example.com example.com
nameserver 10.32.45.23
nameserver 10.3.2.3
The search line defines rules for incomplete hostnames (just the first part of the hostname; for example, myserver instead of myserver.example.com). Here, the resolver library would try to look up host.mydomain.example.com and host.example.com. But things are usually no longer this straightforward. Many enhancements and modifications have been made to the DNS configuration.
search 行定义了不完整主机名的规则(只是主机名的第一部分;例如,myserver 而不是 myserver.example.com)。
在这里,解析器库会尝试查找 host.mydomain.example.com 和 host.example.com。
但事情通常不再那么简单。对 DNS 配置进行了许多增强和修改。
There are two main problems with the traditional DNS configuration. First, the local machine does not cache name server replies, so frequent repeated network access may be unnecessarily slow due to name server requests. To solve this problem, many machines (and routers, if acting as name servers) run an intermediate daemon to intercept name server requests and return a cached answer to name service requests if possible; otherwise, requests go to a real name server. Two of the most common such daemons for Linux are dnsmasq and nscd. You can also set up BIND (the standard Unix name server daemon) as a cache. You can often tell if you’re running a name server caching daemon when you see 127.0.0.1 (localhost) in your /etc/resolv.conf file or when you see 127.0.0.1 show up as the server if you run nslookup -debug host.
传统DNS配置存在两个主要问题。
首先,本地机器不会缓存名称服务器的响应,因此由于名称服务器请求,频繁的重复网络访问可能会变得不必要地缓慢。
为了解决这个问题,许多机器(以及充当名称服务器的路由器)运行一个中间守护程序来拦截名称服务器请求,并在可能的情况下返回缓存的答案以响应名称服务请求;否则,请求将发送到真正的名称服务器。
Linux中两个最常见的此类守护程序是dnsmasq和nscd。
您还可以将BIND(标准的Unix名称服务器守护程序)设置为缓存。
通常可以通过查看/etc/resolv.conf文件中的127.0.0.1(本地主机)或者通过运行nslookup -debug host时看到127.0.0.1显示为服务器来判断是否正在运行名称服务器缓存守护程序。
It can be a tricky to track down your configuration if you’re running a name server–caching daemon. By default, dnsmasq has the configuration file /etc/dnsmasq.conf, but your distribution may override that. For example, in Ubuntu, if you’ve manually set up an interface that’s set up by NetworkManager, you’ll find it in the appropriate file in /etc/NetworkManager/system-connections because when NetworkManager activates a connection, it also starts dnsmasq with that configuration. (You can override all of this by uncommenting the dnsmasq part of your NetworkManager.conf.)
如果您正在运行名称服务器缓存守护程序,要追踪您的配置可能会有些棘手。
默认情况下,dnsmasq的配置文件为/etc/dnsmasq.conf,但您的发行版可能会覆盖该文件。
例如,在Ubuntu中,如果您手动设置了一个由NetworkManager设置的接口,您将在/etc/NetworkManager/system-connections的适当文件中找到它,因为当NetworkManager激活连接时,它还会使用该配置启动dnsmasq。
(您可以取消注释NetworkManager.conf文件中关于dnsmasq部分以覆盖所有这些设置。)
The other problem with the traditional name server setup is that it can be particularly inflexible if you want to be able to look up names on your local network without messing around with a lot of network configuration. For example, if you set up a network appliance on your network, you’ll want to be able to call it by name immediately. This is part of the idea behind zero-configuration name service systems such as Multicast DNS (mDNS) and Simple Service Discovery Protocol (SSDP). If you want to find a host by name on the local network, you just broadcast a request over the network; if the host is there, it replies with its address. These protocols go beyond hostname resolution by also providing information about available services.
传统名称服务器设置的另一个问题是,如果您想要能够在本地网络上查找名称而不必处理大量网络配置,它可能会变得特别不灵活。
例如,如果您在网络上设置了一个网络设备,您希望能够立即通过名称调用它。这正是零配置名称服务系统(如多播DNS(mDNS)和简单服务发现协议(SSDP))背后的理念的一部分。
如果您想要在本地网络上通过名称查找主机,只需在网络上广播一个请求;如果主机存在,它将回复其地址。
这些协议不仅仅限于主机名解析,还提供有关可用服务的信息。
The most widely used Linux implementation of mDNS is called Avahi. You’ll often see mdns as a resolver option in /etc/nsswitch.conf, which we’ll now look at in more detail.
最广泛使用的Linux mDNS实现称为Avahi。
您经常会在/etc/nsswitch.conf中看到mdns作为解析器选项,我们现在将更详细地查看这个文件。
The /etc/nsswitch.conf file controls several name-related precedence settings on your system, such as user and password information, but we’ll only talk about the DNS settings in this chapter. The file on your system should have a line like this:
/etc/nsswitch.conf 文件控制着系统中几个与名称相关的优先设置,比如用户和密码信息,但在本章中我们只会讨论 DNS 设置。
您的系统上的文件应该有这样一行:
hosts: files dns
Putting files ahead of dns here ensures that your system checks the /etc/hosts file for the hostname of your requested IP address before asking the DNS server. This is usually a good idea (especially for looking up localhost, as discussed below), but your /etc/hosts file should be as short as possible. Don’t put anything in there to boost performance; doing so will burn you later. You can put all the hosts within a small private LAN in /etc/hosts, but the general rule of thumb is that if a particular host has a DNS entry, it has no place in /etc/hosts. (The /etc/hosts file is also useful for resolving hostnames in the early stages of booting, when the network may not be available.)
在这里将 files 放在 dns 之前可以确保您的系统在向 DNS 服务器请求之前检查 /etc/hosts 文件中您请求的 IP 地址的主机名。
这通常是一个好主意(特别是用于查找 localhost,如下所讨论的),但是您的 /etc/hosts 文件应该尽可能简短。
不要在其中放置任何内容以提高性能;这样做以后会给您带来麻烦。
您可以将小型私有 LAN 中的所有主机放在 /etc/hosts 中,但一般的经验法则是,如果特定主机有 DNS 记录,那么它就不应该出现在 /etc/hosts 中。
(/etc/hosts 文件也可用于在引导的早期阶段解析主机名,当时网络可能还不可用。)
NOTE DNS is a broad topic. If you have any responsibility for domain names, read DNS and BIND, 5th edition, by Cricket Liu and Paul Albitz (O’Reilly, 2006).注意 DNS 是一个广泛的主题。如果您对域名有任何责任,请阅读 Cricket Liu 和 Paul Albitz 合著的《DNS 和 BIND,第 5 版》(O'Reilly,2006年)。9.13 Localhost
When running ifconfig, you’ll notice the lo interface:
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
The lo interface is a virtual network interface called the loopback because it “loops back” to itself. The effect is that connecting to 127.0.0.1 is connecting to the machine that you’re currently using. When outgoing data to local-host reaches the kernel network interface for lo, the kernel just repackages it as incoming data and sends it back through lo.
lo接口是一个虚拟网络接口,被称为环回接口,因为它“回环”到自身。
其效果是连接到127.0.0.1实际上是连接到当前使用的机器。
当发往本地主机的出站数据到达lo的内核网络接口时,内核会将其重新打包为入站数据并通过lo发送回去。
The lo loopback interface is often the only place you’ll see static network configuration in boot-time scripts. For example, Ubuntu’s ifup command reads /etc/network/interfaces and Fedora uses /etc/sysconfig/networkinterfaces/ ifcfg-lo. You can often find the loopback device configuration by digging around in /etc with grep
lo回环接口通常是在启动时脚本中唯一会看到静态网络配置的地方。
例如,Ubuntu的ifup命令会读取/etc/network/interfaces,而Fedora使用/etc/sysconfig/networkinterfaces/ ifcfg-lo。
你可以通过在/etc目录中使用grep来找到回环设备的配置。
So far, we’ve only seen how packets move from host to host on the Internet— in other words, the where question from the beginning of the chapter. Now let’s start to answer the what question. It’s important to know how your computer presents the packet data it receives from other hosts to its running processes. It’s difficult and inconvenient for user-space programs to deal with a bunch of raw packets the way that the kernel can. Flexibility is especially important: More than one application should be able to talk to the network at the same time (for example, you might have email and several web clients running).
到目前为止,我们只看到了互联网上数据包从主机到主机的传输方式,也就是本章开头提到的“何处”的问题。
现在让我们开始回答“何物”的问题。了解你的计算机如何将从其他主机接收到的数据包呈现给正在运行的进程非常重要。
对于用户空间程序来说,以内核的方式处理一堆原始数据包是困难且不方便的。
灵活性尤为重要:一个以上的应用程序应该能够同时与网络进行通信(例如,您可能同时运行电子邮件和几个 web 客户端)。
Transport layer protocols bridge the gap between the raw packets of the Internet layer and the refined needs of applications. The two most popular transport protocols are the Transmission Control Protocol (TCP) and the User Datagram Protocol (UDP). We’ll concentrate on TCP because it’s by far the most common protocol in use, but we’ll also take a quick look at UDP.
传输层协议填补了互联网层原始数据包与应用程序精细需求之间的差距。
最常见的两种传输协议是传输控制协议(TCP)和用户数据报协议(UDP)。
我们将重点关注 TCP,因为它是目前使用最广泛的协议,但我们也会简单介绍一下 UDP。
TCP provides for multiple network applications on one machine by means of network ports. A port is just a number. If an IP address is like the postal address of an apartment building, a port is like a mailbox number— it’s a further subdivision.
TCP通过网络端口提供了在一台机器上运行多个网络应用程序的功能。
端口只是一个数字。
如果IP地址就像公寓楼的邮寄地址,那么端口就像邮箱号码——是进一步的细分。
When using TCP, an application opens a connection (not to be confused with NetworkManager connections) between one port on its own machine and a port on a remote host. For example, an application such as a web browser could open a connection between port 36406 on its own machine and port 80 on a remote host. From the application’s point of view, port 36406 is the local port and port 80 is the remote port.
使用TCP时,应用程序在本机的一个端口和远程主机的一个端口之间建立连接(注意不要与NetworkManager的连接混淆)。
例如,一个网页浏览器应用程序可以在本机的36406端口和远程主机的80端口之间建立连接。
从应用程序的角度来看,36406端口是本地端口,80端口是远程端口。
You can identify a connection by using the pair of IP addresses and port numbers. To view the connections currently open on your machine, use netstat. Here’s an example that shows TCP connections: The -n option disables hostname (DNS) resolution, and -t limits the output to TCP.
可以通过使用一对IP地址和端口号来标识一个连接。要查看当前在您的机器上打开的连接,请使用netstat命令。
下面是一个显示TCP连接的示例:-n选项禁用主机名(DNS)解析,-t选项将输出限制为TCP。
$ netstat -nt
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 10.23.2.4:47626 10.194.79.125:5222
ESTABLISHED
tcp 0 0 10.23.2.4:41475 172.19.52.144:6667
ESTABLISHED
tcp 0 0 10.23.2.4:57132 192.168.231.135:22
ESTABLISHED
The Local Address and Foreign Address fields show connections from your machine’s point of view, so the machine here has an interface configured at 10.23.2.4, and ports 47626, 41475, and 57132 on the local side are all connected. The first connection here shows port 47626 connected to port 5222 of 10.194.79.125.
本地地址和外部地址字段显示了从您机器的角度看的连接情况,所以这台机器在10.23.2.4配置了一个接口,本地端的端口47626、41475和57132都已连接。
这里的第一个连接显示了端口47626与10.194.79.125的5222端口连接。
To establish a transport layer connection, a process on one host initiates the connection from one of its local ports to a port on a second host with a special series of packets. In order to recognize the incoming connection and respond, the second host must have a process listening on the correct port. Usually, the connecting process is called the client, and the listener is the called the server (more about this in Chapter 10).
要建立传输层连接,一个主机上的进程通过一系列特殊的数据包从其本地端口向第二个主机的一个端口发起连接。
为了识别传入的连接并作出响应,第二个主机必须在正确的端口上有一个正在监听的进程。
通常,发起连接的进程被称为客户端,而监听的进程被称为服务器(关于这个问题在第10章有更多详细介绍)。
The important thing to know about the ports is that the client picks a port on its side that isn’t currently in use, but it nearly always connects to some well-known port on the server side. Recall this output from the netstat command in the preceding section:
关于端口需要知道的重要事情是,客户端在自己的一侧选择一个当前未使用的端口,但几乎总是连接到服务器一侧的某个众所周知的端口。
请回忆一下前一节中netstat命令的输出:
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 10.23.2.4:47626 10.194.79.125:5222 ESTABLISHED
With a little help, you can see that this connection was probably initiated by a local client to a remote server because the port on the local side (47626) looks like a dynamically assigned number, whereas the remote port (5222) is a well-known service (the Jabber or XMPP messaging service, to be specific).
通过一点帮助,你可以看出这个连接可能是由本地客户端发起的到远程服务器的连接,因为本地一侧的端口(47626)看起来像是一个动态分配的数字,而远程端口(5222)是一个众所周知的服务(具体来说是Jabber或XMPP消息服务)。
NOTE A dynamically assigned port is called an ephemeral port.注意:动态分配的端口被称为临时端口。
However, if the local port in the output is well-known, a remote host probably initiated the connection. In this example, remote host 172.24.54.234 has connected to port 80 (the default web port) on the local host.
然而,如果输出中的本地端口是众所周知的,那么可能是远程主机发起了连接。
在这个例子中,远程主机172.24.54.234连接到了本地主机的80端口(默认的Web端口)。
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 10.23.2.4:80 172.24.54.234:43035 ESTABLISHED
A remote host connecting to your machine on a well-known port implies that a server on your local machine is listening on this port. To confirm this, list all TCP ports that your machine is listening on with netstat:
远程主机连接到你的机器上的一个众所周知的端口意味着你本地机器上有一个服务器在监听这个端口。
为了确认这一点,使用netstat列出你的机器上所有正在监听的TCP端口:
$ netstat -ntl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN
--snip--
The line with 0.0.0.0:80 as the local address shows that the local machine is listening on port 80 for connections from any remote machine. (A server can restrict the access to certain interfaces, as shown in the last line, where something is listening for connections only on the localhost interface.) To learn even more, use lsof to identify the specific process that’s listening (as discussed in 10.5.1 lsof).
本地地址为0.0.0.0:80的那一行显示本地机器正在监听来自任何远程机器的80端口的连接。
(服务器可以限制对某些接口的访问,就像最后一行所示,其中某个东西只在本地回环接口上监听连接)。
要了解更多信息,可以使用lsof来确定正在监听的具体进程(如10.5.1节中所讨论的)。
How do you know if a port is a well-known port? There’s no single way to tell, but one good place to start is to look in /etc/services, which translates well-known port numbers into names. This is a plaintext file. You should see entries like this:
如何确定一个端口是否是一个众所周知的端口?没有单一的方法可以确定,但一个好的起点是查看 /etc/services 文件,该文件将众所周知的端口号转换为名称。这是一个纯文本文件。
你应该能看到像这样的条目:
ssh 22/tcp # SSH Remote Login Protocol
smtp 25/tcp
domain 53/udp
The first column is a name and the second column indicates the port number and the specific transport layer protocol (which can be other than TCP).
第一列是名称,第二列指示端口号和特定的传输层协议(可能不是 TCP)。
NOTE In addition to /etc/services, an online registry for ports at http://www.iana.org/ is governed by the RFC6335 network standards document.注意 除了 /etc/services,还有一个在线端口注册表 http://www.iana.org/ 受 RFC6335 网络标准文件的管理。
On Linux, only processes running as the superuser can use ports 1 through 1023. All user processes may listen on and create connections from ports 1024 and up.
在 Linux 上,只有以超级用户身份运行的进程才能使用 1 到 1023 的端口。所有用户进程都可以监听和创建从 1024 及以上的端口的连接。
TCP is popular as a transport layer protocol because it requires relatively little from the application side. An application process only needs to know how to open (or listen for), read from, write to, and close a connection. To the application, it seems as if there are incoming and outgoing streams of data; the process is nearly as simple as working with a file.
TCP作为一种传输层协议非常受欢迎,因为它对应用程序的要求相对较少。
一个应用程序进程只需要知道如何打开(或监听)、读取、写入和关闭连接。
对于应用程序来说,似乎存在着输入和输出的数据流;这个过程几乎和处理文件一样简单。
However, there’s a lot of work to do behind the scenes. For one, the TCP implementation needs to know how to break an outgoing data stream from a process into packets. However, the hard part is knowing how to convert a series of incoming packets into an input data stream for processes to read, especially when incoming packets don’t necessarily arrive in the correct order. In addition, a host using TCP must check for errors: Packets can get lost or mangled when sent across the Internet, and a TCP implementation must detect and correct these situations. Figure 9-3 shows a simplification of how a host might use TCP to send a message.
然而,在幕后还有很多工作要做。首先,TCP实现需要知道如何将一个进程的输出数据流分成数据包。
然而,困难的部分是如何将一系列的输入数据包转换成进程可读的输入数据流,特别是当输入数据包不一定按照正确的顺序到达时。
此外,使用TCP的主机必须检查错误:在通过互联网发送时,数据包可能会丢失或损坏,TCP实现必须检测和纠正这些情况。
图9-3显示了一个主机如何使用TCP发送消息的简化示意图。
Luckily, you need to know next to nothing about this mess other than that the Linux TCP implementation is primarily in the kernel and that utilities that work with the transport layer tend to manipulate kernel data structures. One example is the IP Tables packet-filtering system discussed in 9.21 Firewalls.
幸运的是,你几乎不需要了解这个混乱的过程,只需要知道Linux TCP实现主要在内核中,并且与传输层相关的实用工具往往会操作内核数据结构。
一个例子是在9.21防火墙中讨论的IP Tables数据包过滤系统。
UDP is a far simpler transport layer than TCP. It defines a transport only for single messages; there is no data stream. At the same time, unlike TCP, UDP won’t correct for lost or out-of-order packets. In fact, although UDP has ports, it doesn’t even have connections! One host simply sends a message from one of its ports to a port on a server, and the server sends something back if it wants to. However, UDP does have error detection for data inside a packet; a host can detect if a packet gets mangled, but it doesn’t have to do anything about it.
UDP是比TCP更简单的传输层协议。
它仅为单个消息定义了传输方式,没有数据流。
与TCP不同的是,UDP不会纠正丢失或乱序的数据包。
实际上,尽管UDP有端口,但它甚至没有连接!一个主机只需从其端口向服务器的某个端口发送一条消息,如果服务器愿意,就会发送一些回应。
然而,UDP确实对数据包中的数据进行了错误检测;主机可以检测到数据包是否损坏,但它不必对此采取任何措施。
Where TCP is like having a telephone conversation, UDP is like sending a letter, telegram, or instant message (except that instant messages are more reliable). Applications that use UDP are often concerned with speed— sending a message as quickly as possible. They don’t want the overhead of TCP because they assume the network between two hosts is generally reliable. They don’t need TCP’s error correction because they either have their own error detection systems or simply don’t care about errors.
TCP就像进行电话对话一样,而UDP则像发送信件、电报或即时消息一样(除了即时消息更可靠)。
使用UDP的应用程序通常关注速度,尽快发送消息。
它们不希望有TCP的开销,因为它们假设两台主机之间的网络通常是可靠的。
它们不需要TCP的错误纠正,因为它们要么有自己的错误检测系统,要么根本不关心错误。
One example of an application that uses UDP is the Network Time Protocol (NTP). A client sends a short and simple request to a server to get the current time, and the response from the server is equally brief. Because the client wants the response as quickly as possible, UDP suits the application; if the response from the server gets lost somewhere in the network, the client can just resend a request or give up. Another example is video chat—in this case, pictures are sent with UDP—and if some pieces get lost along the way, the client on the receiving end compensates the best it can.
一个使用UDP的应用程序的例子是网络时间协议(NTP)。
客户端向服务器发送一个简短而简单的请求以获取当前时间,服务器的响应同样简短。
因为客户端希望尽快得到响应,所以UDP适合这种应用程序;如果服务器的响应在网络中丢失了,客户端可以重新发送请求或放弃。
另一个例子是视频聊天,这种情况下使用UDP发送图片,如果在传输过程中有一些片段丢失,接收端的客户端会尽力进行补偿。
Figure 9-3. Sending a message with TCP
图9-3. 使用TCP发送消息
NOTE The rest of this chapter deals with more advanced networking topics, such as network filtering and routers, as they relate to the lower network layers that we’ve already seen: physical, network, and transport. If you like, feel free to skip ahead to the next chapter to see the application layer where everything comes together in user space. You’ll see processes that actually use the network rather than just throwing around a bunch of addresses and packets.注意:本章的其余部分将涉及更高级的网络主题,例如与我们已经了解的底层网络层(物理层、网络层和传输层)相关的网络过滤和路由器。如果你愿意,可以直接跳到下一章,在用户空间中了解应用层,这是所有东西都在一起的地方。你将看到实际使用网络的进程,而不仅仅是在地址和数据包之间来回传递。9.15 Revisiting a Simple Local Network
We’re now going to look at additional components of the simple network introduced in 9.3 The Internet Layer. Recall that this network consists of one local area network as one subnet and a router that connects the subnet to the rest of the Internet. You’ll learn the following:
我们现在要看一下9.3节《互联网层》中介绍的简单网络的附加组件。
回想一下,这个网络由一个本地区域网络作为一个子网和一个连接该子网与互联网其余部分的路由器组成。您将学到以下内容:
o How a host on the subnet automatically gets its network configuration
o How to set up routing
o What a router really is
o How to know which IP addresses to use for the subnet
o How to set up firewalls to filter out unwanted traffic from the Internet
o 子网上的主机如何自动获取其网络配置
o 如何设置路由
o 路由器的真正含义
o 如何确定子网使用哪些IP地址
o 如何设置防火墙以过滤掉来自互联网的不需要的流量
Let’s start by learning how a host on the subnet automatically gets its network configuration.
让我们从学习子网上的主机如何自动获取其网络配置开始。
When you set a network host to get its configuration automatically from the network, you’re telling it to use the Dynamic Host Configuration Protocol (DHCP) to get an IP address, subnet mask, default gateway, and DNS servers. Aside from not having to enter these parameters by hand, DHCP has other advantages for a network administrator, such as preventing IP address clashes and minimizing the impact of network changes. It’s very rare to see a modern network that doesn’t use DHCP.
当您将网络主机设置为从网络自动获取配置时,您告诉它使用动态主机配置协议(DHCP)来获取IP地址、子网掩码、默认网关和DNS服务器。
除了不需要手动输入这些参数之外,DHCP对于网络管理员还有其他优点,例如防止IP地址冲突和减小网络变化的影响。
现代网络很少见不使用DHCP的情况。
For a host to get its configuration with DHCP, it must be able to send messages to a DHCP server on its connected network. Therefore, each physical network should have its own DHCP server, and on a simple network (such as the one in 9.3 The Internet Layer), the router usually acts as the DHCP server.
要使主机通过DHCP获取其配置,它必须能够向其连接的网络上的DHCP服务器发送消息。
因此,每个物理网络应该有自己的DHCP服务器,在简单的网络(如9.3节中的互联网层)中,路由器通常充当DHCP服务器。
NOTE When making an initial DHCP request, a host doesn’t even know the address of a DHCP server, so it broadcasts the request to all hosts (usually all hosts on its physical network).
When a machine asks a DHCP server for an IP address, it’s really asking for a lease on an address for a certain amount of time. When the lease is up, a client can ask to renew the lease.
注意:在进行初始DHCP请求时,主机甚至不知道DHCP服务器的地址,因此它将请求广播给所有主机(通常是其物理网络上的所有主机)。
当一台机器向DHCP服务器请求IP地址时,实际上是在请求租用一个地址一段时间。
租约到期后,客户端可以请求续租。
Although there are many different kinds of network manager systems, nearly all use the Internet Software Consortium (ISC) dhclient program to do the actual work. You can test dhclient by hand on the command line, but before doing so you must remove any default gateway route. To run the test, simply specify the network interface name (here, it’s eth0):
虽然有很多不同种类的网络管理系统,但几乎所有系统都使用Internet Software Consortium(ISC)的dhclient程序来进行实际工作。
您可以在命令行上手动测试dhclient,但在此之前,您必须删除任何默认网关路由。
要运行测试,只需指定网络接口名称(这里是eth0):
# dhclient eth0
Upon startup, dhclient stores its process ID in /var/run/dhclient.pid and its lease information in /var/state/dhclient.leases.
启动时,dhclient将其进程ID存储在/var/run/dhclient.pid中,并将租约信息存储在/var/state/dhclient.leases中。
You can task a Linux machine with running a DHCP server, which provides a good amount of control over the addresses that it gives out. However, unless you’re administering a large network with many subnets, you’re probably better off using specialized router hardware that includes built-in DHCP servers.
你可以让 Linux 机器运行 DHCP 服务器,这样就能很好地控制它所提供的地址。
不过,除非你要管理的是一个有许多子网的大型网络,否则你最好使用内置 DHCP 服务器的专用路由器硬件。
Probably the most important thing to know about DHCP servers is that you want only one running on the same subnet in order to avoid problems with clashing IP addresses or incorrect configurations.
关于 DHCP 服务器,最重要的一点可能是,在同一子网中只运行一个 DHCP 服务器,以避免出现 IP 地址冲突或配置错误的问题。
Routers are essentially just computers with more than one physical network interface. You can easily configure a Linux machine as a router.
路由器本质上只是拥有多个物理网络接口的计算机。
你可以轻松地将 Linux 机器配置为路由器。
For example, say you have two LAN subnets, 10.23.2.0/24 and 192.168.45.0/24. To connect them, you have a Linux router machine with three network interfaces: two for the LAN subnets and one for an Internet uplink, as shown in Figure 9-4. As you can see, this doesn’t look very different from the simple network example that we’ve used in the rest of this chapter.
例如,你有两个局域网子网:10.23.2.0/24 和 192.168.45.0/24。
为了连接这两个子网,你需要一台带有三个网络接口的 Linux 路由器:两个用于 LAN 子网,一个用于 Internet 上行链路,如图 9-4 所示。
如你所见,这与我们在本章其余部分使用的简单网络示例并无太大区别。
Figure 9-4. Two subnets joined with a router
图 9-4. 用路由器连接的两个子网
The router’s IP addresses for the LAN subnets are 10.23.2.1 and 192.168.45.1. When those addresses are configured, the routing table looks something like this (the interface names might vary in practice; ignore the Internet uplink for now):
路由器的局域网子网 IP 地址为 10.23.2.1 和 192.168.45.1。
配置好这些地址后,路由表就会如下所示(接口名称在实践中可能会有所不同;暂时忽略 Internet 上行链路):
Destination Gateway Genmask Flags Metric Ref Use
Iface
10.23.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
192.168.45.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
Now let’s say that the hosts on each subnet have the router as their default gateway (10.23.2.1 for 10.23.2.0/24 and 192.168.45.1 for 192.168.45.0/24). If 10.23.2.4 wants to send a packet to anything outside of 10.23.2.0/24, it passes the packet to 10.23.2.1. For example, to send a packet from 10.23.2.4 (Host A) to 192.168.45.61 (Host E), the packet goes to 10.23.2.1 (the router) via its eth0 interface, then back out through the router’s eth1 interface.
现在假设每个子网的主机都将路由器设为默认网关(10.23.2.1用于10.23.2.0/24,192.168.45.1用于192.168.45.0/24)。
如果10.23.2.4想要向10.23.2.0/24之外的任何地方发送数据包,它会将数据包传递给10.23.2.1。
例如,要将数据包从10.23.2.4(主机A)发送到192.168.45.61(主机E),数据包会通过其eth0接口传递到10.23.2.1(路由器),然后再通过路由器的eth1接口返回。
However, by default, the Linux kernel does not automatically move packets from one subnet to another. To enable this basic routing function, you need to enable IP forwarding in the router’s kernel with this command:
然而,默认情况下,Linux内核不会自动将数据包从一个子网转发到另一个子网。
要启用这个基本的路由功能,您需要在路由器的内核中启用IP转发功能,可以使用以下命令:
# sysctl -w net.ipv4.ip_forward
As soon as you enter this command, the machine should start routing packets between the two subnets, assuming that the hosts on those subnets know to send their packets to the router you just created.
一旦输入了这个命令,机器应该开始在这两个子网之间路由数据包,前提是这些子网上的主机知道将它们的数据包发送到您刚刚创建的路由器。
To make this change permanent upon reboot, you can add it to your /etc/sysctl.conf file. Depending on your distribution, you may have the option to put it into a file in /etc/sysctl.d so that distribution updates won’t overwrite your changes.
为了使这个更改在重新启动后仍然有效,您可以将其添加到您的/etc/sysctl.conf文件中。
根据您的发行版,您可能可以将其放入/etc/sysctl.d目录中的一个文件中,这样发行版更新就不会覆盖您的更改。
# sysctl -w net.ipv4.ip_forward
When the router also has the third network interface with an Internet uplink, this same setup allows Internet access for all hosts on both subnets because they’re configured to use the router as the default gateway. But that’s where things get more complicated. The problem is that certain IP addresses such as 10.23.2.4 are not actually visible to the whole Internet; they’re on so-called private networks. To provide for Internet connectivity, you must set up a feature called Network Address Translation (NAT) on the router. The software on nearly all specialized routers does this, so there’s nothing out of the ordinary here, but let’s examine the problem of private networks in a bit more detail.
当路由器的第三个网络接口还带有互联网上行链路时,同样的设置可以让两个子网中的所有主机都能访问互联网,因为它们被配置为使用路由器作为默认网关。
但问题也就在这里变得复杂起来。
问题在于,某些 IP 地址(如 10.23.2.4)实际上并不对整个互联网可见;它们位于所谓的专用网络中。
为了提供互联网连接,你必须在路由器上设置一个名为网络地址转换(NAT)的功能。
几乎所有专用路由器上的软件都能做到这一点,所以这里并没有什么特别之处,但让我们更详细地研究一下专用网络的问题。
Say you decide to build your own network. You have your machines, router, and network hardware ready. Given what you know about a simple network so far, your next question is “What IP subnet should I use?”
假设您决定搭建自己的网络。您已经准备好了计算机、路由器和网络硬件。根据您对简单网络的了解,您接下来的问题是:“我应该使用什么IP子网?”
If you want a block of Internet addresses that every host on the Internet can see, you can buy one from your ISP. However, because the range of IPv4 addresses is very limited, this costs a a lot and isn’t useful for much more than running a server that the rest of the Internet can see. Most people don’t really need this kind of service because they access the Internet as a client.
如果您想要一组所有互联网上的主机都能看到的互联网地址,您可以从您的ISP购买一个。
然而,由于IPv4地址范围非常有限,这样做成本很高,并且除了运行一个可以被互联网上的其他主机看到的服务器之外,没有太多其他用途。
大多数人实际上并不需要这种服务,因为他们作为客户端访问互联网。
The conventional, inexpensive alternative is to pick a private subnet from addresses in the RFC 1918/6761 Internet standards documents, shown in Table 9-2.the
传统的廉价方法是从 RFC 1918/6761 互联网标准文件中的地址中选择一个专用子网,如表 9-2 所示。
Table 9-2. Private Networks Defined by RFC 1918 and 6761
表9-2. RFC 1918和6761定义的私有网络
You can carve up private subnets as you wish. Unless you plan to have more than 254 hosts on a single network, pick a small subnet like 10.23.2.0/24, as we’ve been using throughout this chapter. (Networks with this netmask are sometimes called class C subnets. Although the term is technically somewhat obsolete, it’s still useful.)
您可以根据需求划分私有子网。
除非您计划在单个网络上拥有超过254个主机,否则选择一个小的子网,例如10.23.2.0/24,正如我们在本章中一直使用的那样。
(具有这个网络掩码的网络有时被称为C类子网。尽管这个术语在技术上有些过时,但仍然有用。)
What’s the catch? Hosts on the real Internet know nothing about private subnets and will not send packets to them, so without some help, hosts on private subnets cannot talk to the outside world. A router connected to the Internet (with a true, nonprivate address) needs to have some way to fill in the gap between that connection and the hosts on a private network.
有什么问题吗?
真实互联网上的主机对私有子网一无所知,不会向其发送数据包,因此在没有帮助的情况下,私有子网上的主机无法与外部世界通信。
连接到互联网的路由器(具有真实的非私有地址)需要有一种方式来填补连接和私有网络上的主机之间的空白。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。