Stories

Detail Return Return

【Linux】《how linux work》第十章 網絡應用和服務 - Stories Detail

Chapter 10. Network Applications and Services(網絡應用和服務)

This chapter explores basic network applications—the clients and servers running in user space that reside at the application layer. Because this layer is at the top of the stack, close to end users, you may find this material more accessible than the material in Chapter 9. Indeed, you interact with network client applications such as web browsers and email readers every day.

本章探討基本的網絡應用程序——在用户空間運行的客户端和服務器,這些客户端和服務器位於應用層。

因為這一層位於堆棧的頂部,靠近最終用户,所以您可能會發現這部分材料比第9章中的材料更易理解。

事實上,您每天都會與諸如網絡瀏覽器和電子郵件閲讀器之類的網絡客户端應用程序進行交互。

To do their work, network clients connect to corresponding network servers. Unix network servers come in many forms. A server program can listen to a port on its own or through a secondary server. In addition, servers have no common configuration database and a wide variety of features. Most servers have a configuration file to control their behavior (though with no common format), and most use the operating system’s syslog service for message logging. We’ll look at some common servers as well as some tools that will help you understand and debug server operation.

為了完成其工作,網絡客户端連接到相應的網絡服務器。Unix網絡服務器有許多形式。服務器程序可以通過自身或通過輔助服務器監聽端口。

此外,服務器沒有通用的配置數據庫,具有各種各樣的功能。

大多數服務器都有一個配置文件來控制其行為(儘管沒有通用格式),並且大多數使用操作系統的syslog服務進行消息記錄。

我們將研究一些常見的服務器以及一些工具,這些工具將幫助您理解和調試服務器的運行。

Network clients use the operating system’s transport layer protocols and interfaces, so understanding the basics of the TCP and UDP transport layers is important. Let’s start looking at network applications by experimenting with a network client that uses TCP.

網絡客户端使用操作系統的傳輸層協議和接口,因此瞭解TCP和UDP傳輸層的基礎知識非常重要。

讓我們通過嘗試使用TCP的網絡客户端來開始研究網絡應用程序。

10.1 The Basics of Services

TCP services are among the easiest to understand because they are built upon simple, uninterrupted two-way data streams. Perhaps the best way to see how they work is to talk directly to a web server on TCP port 80 to get an idea of how data moves across the connection. For example, run the following command to connect to a web server:

TCP服務是最容易理解的服務之一,因為它們建立在簡單、不間斷的雙向數據流之上。

也許最好的方法是直接與 TCP 端口 80 上的 Web 服務器進行通信,以瞭解它們是如何工作的。

例如,運行以下命令連接到 Web 服務器:

$ telnet www.wikipedia.org 80

You should get a response like this:

你應該會得到如下響應:

Trying some address... 
Connected to www.wikipedia.org. 
Escape character is '^]'. 

Now enter

現在輸入

GET / HTTP/1.0

Press ENTER twice. The server should send a bunch of HTML text as a response and then terminate the connection.

按兩次 ENTER 鍵。服務器應該會發送一堆 HTML 文本作為響應,然後終止連接。

This exercise tells us that

這個練習告訴我們:

o the remote host has a web server process listening on TCP port 80; and
o telnet was the client that initiated the connection.

  • 遠程主機上有一個監聽 TCP 端口 80 的 Web 服務器進程;以及
  • telnet 是啓動連接的客户端。

NOTE telnet is a program originally meant to enable logins to remote hosts. Although the non Kerberos telnet remote login server is completely insecure (as you will learn later), the telnet client can be useful for debugging remote services. telnet does not work with UDP or any transport layer other than TCP. If you’re looking for a general-purpose network client, consider netcat, described in 10.5.3 netcat.

注意:telnet 是一個最初用於啓用登錄到遠程主機的程序。

儘管非 Kerberos telnet 遠程登錄服務器是完全不安全的(稍後你將瞭解),但 telnet 客户端可用於調試遠程服務。

telnet 不支持 UDP 或除 TCP 外的任何傳輸層。

如果你正在尋找通用網絡客户端,請考慮 netcat,詳情請參見 10.5.3 netcat。

10.1.1 A Closer Look

In the example above, you manually interacted with a web server on the network with telnet, using the Hypertext Transfer Protocol (HTTP) application layer protocol. Although you’d normally use a web browser to make this sort of connection, let’s take just one step up from telnet and use a command-line program that knows how to speak to the HTTP application layer. We’ll use the curl utility with a special option to record details about its communication:

在上面的示例中,您通過telnet手動與網絡上的Web服務器進行了交互,使用了超文本傳輸協議(HTTP)應用層協議。

雖然通常您會使用Web瀏覽器來建立這種連接,但讓我們從telnet再向上邁進一步,使用一個能夠與HTTP應用層通信的命令行程序。

我們將使用curl實用程序,並加上一個特殊選項來記錄其通信的詳細信息:

$ curl --trace-ascii trace_file http://www.wikipedia.org/

NOTE Your distribution may not have the curl package preinstalled, but you should have no trouble installing it if necessary.

注意:您的發行版可能沒有預安裝curl軟件包,但如果需要安裝它,您應該沒有任何問題。

You’ll get a lot of HTML output. Ignore it (or redirect it to /dev/null) and instead look at the newly created file trace_file. Assuming that the connection was successful, the first part of the file should look something like the following, at the point where curl attempts to establish the TCP connection to the server:

您將獲得大量HTML輸出。請忽略它(或將其重定向到/dev/null),而是查看新創建的文件trace_file。

假設連接成功,文件的第一部分應該類似於以下內容,在curl嘗試建立與服務器的TCP連接時:

== Info: About to connect() to www.wikipedia.org port 80 (#0) 
== Info:   Trying 10.80.154.224... == Info: connected

Everything you’ve seen so far happens in the transport layer or below. However, if this connection succeeds, curl tries to send the request (the “header”); this is where the application layer starts:

到目前為止,你所看到的一切都發生在傳輸層或以下。

然而,如果此連接成功,curl 嘗試發送請求(即“頭部”);這是應用層開始的地方。

=> Send header, 167 bytes (0xa7) 
0000: GET / HTTP/1.1 
0010: User-Agent: curl/7.22.0 (i686-pc-linux-gnu) libcurl/7.22.0 OpenS 
0050: SL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3 
007f: Host: www.wikipedia.org 
0098: Accept: */* 
00a5: 

The first line here is curl debugging output telling you what it will do next. The remaining lines show what curl sends to the server. The text in bold is what goes to the server; the hexadecimal numbers at the beginning are just debugging offsets from curl to help you keep track of how much data was sent or received.

這裏的第一行是curl調試輸出,告訴您接下來將要執行的操作。

其餘行顯示了curl發送到服務器的內容。

粗體文本是發送到服務器的內容;開頭的十六進制數字只是curl的調試偏移量,幫助您跟蹤發送或接收了多少數據。

You can see that curl starts by issuing a GET command to the server (as you did with telnet), followed by some extra information for the server and an empty line. Next, the server sends a reply, first with its own header, shown here in bold:

您可以看到,curl首先向服務器發出一個GET命令(就像您在telnet中所做的那樣),然後是一些額外的信息和一個空行。

接下來,服務器發送了一個回覆,首先是自己的頭部,如下所示:

<= Recv header, 17 bytes (0x11) 
0000: HTTP/1.1 200 OK 
<= Recv header, 16 bytes (0x10) 
0000: Server: Apache 
<= Recv header, 42 bytes (0x2a) 
0000: X-Powered-By: PHP/5.3.10-1ubuntu3.9+wmf1 --snip--

Much like the previous output, the <= lines are debugging output, and 0000: precedes the lines of output to tell you offsets.

與之前的輸出類似,<= 行是調試輸出,0000:在輸出行之前告訴您偏移量。

The header in the server’s reply can be fairly long, but at some point the server transitions from transmitting headers to sending the actual requested document, like this:

服務器回覆中的標題可能相當長,但在某個時刻,服務器從傳輸標題轉變為發送實際請求的文檔,就像這樣:

<= Recv header, 55 bytes (0x37) 
0000: X-Cache: cp1055 hit (16), cp1054 frontend hit (22384) 
<= Recv header, 2 bytes (0x2) 
0000: 
<= Recv data, 877 bytes (0x36d) 
0000: 008000 
0008: <!DOCTYPE html>.<html lang="mul" dir="ltr">.<head>.<!-- Sysops: --snip-- 

This output also illustrates an important property of the application layer. Even though the debugging output says Recv header and Recv data, implying that those are two different kinds of messages from the server, there’s no difference in the way that curl talked to the operating system to retrieve the two kinds of messages, nor any difference in how the operating system handled them, nor any difference in the way that the network handled the packets underneath. The difference is entirely within the user-space curl application itself. curl knew that until this point it had been getting headers, but when it received a blank line (the 2 byte chunk in the middle) signifying the end of headers in HTTP, it knew to interpret anything that followed as the requested document.

這個輸出還展示了應用層的一個重要特性。

儘管調試輸出中顯示“接收頭部”和“接收數據”,暗示這兩種消息來自服務器,但在 curl 與操作系統交互以獲取這兩種消息的方式、操作系統處理它們的方式以及網絡在底層處理數據包的方式上並沒有任何區別。

區別完全在於用户空間中的 curl 應用程序本身。

curl 知道直到這一點它一直在接收頭部,但當它收到一個空行(中間的 2 字節塊)表示 HTTP 頭部結束時,它就知道要將接下來的任何內容解釋為請求的文檔。

The same is true of the server sending this data. When sending the reply, the server didn’t differentiate between header and document data sent to the operating system; the distinctions happen inside the user-space server program.

發送這些數據的服務器也是如此。

在發送回覆時,服務器沒有區分發送到操作系統的頭部數據和文檔數據;區別發生在用户空間服務器程序內部。

10.2 Network Servers

Most network servers are like other server daemons on your system such as cron, except that they interact with network ports. In fact, recall syslogd discussed in Chapter 7; it accepts UDP packets on port 514 when started with the -r option.

大多數網絡服務器與系統中的其他服務器守護進程(如cron)類似,只是它們與網絡端口進行交互。

事實上,回想一下第7章討論過的syslogd;當使用-r選項啓動時,它會在514端口接受UDP數據包。

These are some other common network servers that you might find running on your system:

以下是一些你可能在系統上發現正在運行的常見網絡服務器:

o httpd, apache, apache2 Web servers
o sshd Secure shell daemon (see 10.3 Secure Shell (SSH))
o postfix, qmail, sendmail Mail servers
o cupsd Print server
o nfsd, mountd Network filesystem (file-sharing) daemons
o smbd, nmbd Windows file-sharing daemons (see Chapter 12)
o rpcbind Remote procedure call (RPC) portmap service daemon

  • httpd、apache、apache2 網頁服務器
  • sshd 安全外殼守護進程(參見10.3 安全外殼(SSH))
  • postfix、qmail、sendmail 郵件服務器
  • cupsd 打印服務器
  • nfsd、mountd 網絡文件系統(文件共享)守護進程
  • smbd、nmbd Windows 文件共享守護進程(參見第12章)
  • rpcbind 遠程過程調用(RPC)端口映射服務守護進程

One feature common to most network servers is that they usually operate as multiple processes. At least one process listens on a network port, and when a new incoming connection is received, the listening process uses fork() to create a new child process, which is then responsible for the new connection. The child, often called a worker process, terminates when the connection is closed. Meanwhile, the original listening process continues to listen on the network port. This process allows a server to easily handle many connections without much trouble.

大多數網絡服務器的一個共同特點是它們通常作為多個進程運行。

至少有一個進程在監聽網絡端口,當接收到新的傳入連接時,監聽進程使用fork()創建一個新的子進程,然後該子進程負責處理新連接。

子進程通常被稱為工作進程,在連接關閉時終止。與此同時,原始的監聽進程繼續監聽網絡端口。

這個過程使得服務器能夠輕鬆處理許多連接而不會出現太多問題。

There are some exceptions to this model, however. Calling fork() adds a significant amount of system overhead. In comparison, high-performance TCP servers such as the Apache web server can create a number of worker processes upon startup so that they are already there to handle connections as needed. Servers that accept UDP packets simply receive data and react to it; they don’t have connections to listen for.

然而,也有一些例外情況。調用fork()會增加大量系統開銷。

相比之下,高性能的TCP服務器(如Apache Web服務器)可以在啓動時創建多個工作進程,以便在需要時立即處理連接。

接受UDP數據包的服務器只需接收數據並對其做出反應;它們不需要監聽連接。

10.3 Secure Shell (SSH)

Every server works a bit differently. Let’s take a close look at one—the standalone SSH server. One of the most common network service applications is the secure shell (SSH), the de facto standard for remote access to a Unix machine. When configured, SSH allows secure shell logins, remote program execution, simple file sharing, and more—replacing the old, insecure telnet and rlogin remote-access systems with public-key cryptography for authentication and simpler ciphers for session data. Most ISPs and cloud providers require SSH for shell access to their services, and many Linux-based network appliances (such as NAS devices) allow access via SSH as well. OpenSSH (http://www.openssh.com/) is a popular free SSH implementation for Unix, and nearly all Linux distributions come with it preinstalled. The OpenSSH client is ssh, and the server is sshd. There are two main SSH protocol versions: 1 and 2. OpenSSH supports both, but version 1 is rarely used.

每個服務器的工作方式都有所不同。讓我們仔細看看其中一個——獨立的SSH服務器。

安全外殼(SSH)是最常見的網絡服務應用程序之一,也是遠程訪問Unix機器的事實標準。

配置好後,SSH允許安全外殼登錄、遠程程序執行、簡單文件共享等功能,利用公鑰加密進行身份驗證以及簡單密碼算法處理會話數據,取代了舊的不安全的telnet和rlogin遠程訪問系統。

大多數互聯網服務提供商和雲服務提供商要求使用SSH來訪問其服務的shell,許多基於Linux的網絡設備(如NAS設備)也允許通過SSH訪問。

OpenSSH(http://www.openssh.com/)是Unix上流行的免費SSH實現,幾乎所有Linux發行版都預裝了它。

OpenSSH客户端是ssh,服務器是sshd。SSH有兩個主要協議版本:1和2。

OpenSSH支持兩者,但很少使用第1版。

Among its many useful capabilities and features, SSH does the following:

在其許多有用功能和特性中,SSH可以實現以下功能:

o Encrypts your password and all other session data, protecting you from snoopers.
o Tunnels other network connections, including those from X Window System clients. You’ll learn more about X in Chapter 14.
o Offers clients for nearly any operating system.
o Uses keys for host authentication.

  • 加密密碼和所有其他會話數據,保護您免受窺探。
  • 隧道化其他網絡連接,包括來自X Window系統客户端的連接。您將在第14章中更多地瞭解關於X的內容。
  • 為幾乎任何操作系統提供客户端。
  • 使用密鑰進行主機身份驗證。

NOTE Tunneling is the process of packaging and transporting one network connection using another one. The advantages of using SSH to tunnel X Window System connections are that SSH sets up the display environment for you and encrypts the X data inside the tunnel.

注意:隧道是使用另一個網絡連接打包和傳輸一個網絡連接的過程。

使用SSH進行X Window系統連接隧道化的優勢在於SSH為您設置顯示環境並在隧道內加密X數據。

SSH does have its disadvantages. For one, in order to set up an SSH connection, you need the remote host’s public key, and you don’t necessarily get it in a secure way (though you can check it manually to make sure you’re not being spoofed). For an overview of how several methods of cryptography work, get your hands on the book Applied Cryptography: Protocols, Algorithms, and Source Code in C, 2nd edition, by Bruce Schneier (Wiley, 1996). Two in-depth books on SSH are SSH Mastery: OpenSSH, PuTTY, Tunnels and Keys by Michael W. Lucas (Tilted Windmill Press, 2012) and SSH, The Secure Shell, 2nd edition, by Daniel J. Barrett, Richard E. Silverman, and Robert G. Byrnes(O’Reilly, 2005).

SSH也有其缺點。首先,在建立SSH連接時,您需要遠程主機的公鑰,並且不一定以安全的方式獲取(儘管您可以手動檢查以確保沒有被欺騙)。

要了解幾種加密方法的概述,請閲讀

  • Bruce Schneier的《應用密碼學:C語言協議、算法和源代碼》第2版(Wiley,1996)。

關於SSH的兩本深入書籍是

  • Michael W. Lucas的《SSH技巧:OpenSSH、PuTTY、隧道和密鑰》(Tilted Windmill Press,2012)
  • Daniel J. Barrett、Richard E. Silverman和Robert G. Byrnes的《SSH,安全外殼》第2版(O'Reilly,2005)。

    10.3.1 The SSHD Server

Running sshd requires a configuration file and host keys. Most distributions keep configurations in the /etc/ssh configuration directory and try to configure everything properly for you if you install their sshd package. (The configuration filename sshd_config is easy to confuse with the client’s ssh_config setup file, so be careful.)

運行sshd需要一個配置文件和主機密鑰。

大多數發行版將配置保存在/etc/ssh配置目錄中,並在您安裝他們的sshd軟件包時嘗試為您正確配置一切。

(配置文件名sshd_config很容易與客户端的ssh_config設置文件混淆,所以請小心。)

You shouldn’t need to change anything in sshd_config, but it never hurts to check. The file consists of keyword-value pairs, as shown in this fragment:

您不應該需要更改sshd_config中的任何內容,但檢查一下也無妨。該文件由關鍵字-值對組成,如下所示:

Port 22 
#Protocol 2,1 
#ListenAddress 0.0.0.0 
#ListenAddress :: 
HostKey /etc/ssh/ssh_host_key 
HostKey /etc/ssh/ssh_host_rsa_key 
HostKey /etc/ssh/ssh_host_dsa_key

Lines beginning with # are comments, and many comments in your sshd_config might indicate default values. The sshd_config(5) manual page contains descriptions of all possible values, but these are the most important ones:

以#開頭的行是註釋,在你的sshd_config中的許多註釋可能表示默認值。

sshd_config(5)手冊頁面包含所有可能值的描述,但以下是最重要的幾個:

o HostKey file Uses file as a host key. (Host keys are described shortly.)
o LogLevel level Logs messages with syslog level level.
o PermitRootLogin value Permits the superuser to log in with SSH if value is set to yes. Set
value to no to prevent this.
o SyslogFacility name Logs messages with syslog facility name.
o X11Forwarding value Enables X Window System client tunneling if value is set to yes.
o XAuthLocation path Provides a path for xauth. X11 tunneling will not work without this path. If
xauth isn’t in /usr/bin, set path to the full pathname for xauth.

  • HostKey文件 使用文件作為主機密鑰。(主機密鑰將很快描述。)
  • LogLevel級別 記錄具有syslog級別級別的消息。
  • PermitRootLogin值 如果值設置為yes,則允許超級用户使用SSH登錄。將值設置為no可阻止此操作。
  • SyslogFacility名稱 記錄具有syslog設施名稱的消息。
  • X11Forwarding值 如果值設置為yes,則啓用X Window系統客户端隧道。
  • XAuthLocation路徑 提供xauth的路徑。如果未設置此路徑,X11隧道將無法工作。如果xauth不在/usr/bin中,請將路徑設置為xauth的完整路徑名。

    Host Keys(主機密鑰)

OpenSSH has three host key sets: one for protocol version 1 and two for protocol 2. Each set has a public key (with a .pub file extension) and a private key (with no extension). Do not let anyone see your private key, even on your own system, because if someone obtains it, you’re at risk from intruders.

OpenSSH有三組主機密鑰:一組用於協議版本1,另外兩組用於協議2。

每組都有一個公鑰(擴展名為.pub文件)和一個私鑰(沒有擴展名)。

即使在您自己的系統上,也不要讓任何人看到您的私鑰,因為如果有人獲取了它,您就會受到入侵者的威脅。

SSH version 1 has RSA keys only, and SSH version 2 has RSA and DSA keys. RSA and DSA are public key cryptography algorithms. The key filenames are given in Table 10-1.

SSH版本1僅使用RSA密鑰,而SSH版本2使用RSA和DSA密鑰。RSA和DSA是公鑰加密算法。密鑰文件名如下表所示。

Table 10-1. OpenSSH Key Files

表10-1. OpenSSH密鑰文件

image.png

image.png

Normally you won’t need to build the keys because the OpenSSH installation program or your distribution’s installation script will do it for you, but you do need to know how to create keys if you plan to use programs like ssh-agent. To create SSH protocol version 2 keys, use the ssh-keygen program that comes with OpenSSH:

通常情況下,您不需要自己生成密鑰,因為OpenSSH安裝程序或您發行版的安裝腳本會為您完成這些操作,但是如果您計劃使用ssh-agent等程序,您需要了解如何創建密鑰。

要創建SSH協議版本2的密鑰,請使用隨OpenSSH一起提供的ssh-keygen程序。

# ssh-keygen -t rsa -N '' -f /etc/ssh/ssh_host_rsa_key 
# ssh-keygen -t dsa -N '' -f /etc/ssh/ssh_host_dsa_key 

For the version 1 keys, use

對於版本 1 密鑰,使用

# ssh-keygen -t rsa1 -N '' -f /etc/ssh/ssh_host_key

The SSH server and clients also use a key file called ssh_known_hosts, which contains public keys from other hosts. If you intend to use host-based authentication, the server’s ssh_known_hosts file must contain the public host keys of all trusted clients. Knowing about the key files is handy if you’re replacing a machine. When installing a new machine from scratch, you can import the key files from the old machine to ensure that users don’t get key mismatches when connecting to the new one.

SSH服務器和客户端還使用一個名為ssh_known_hosts的密鑰文件,其中包含其他主機的公鑰。

如果您打算使用基於主機的身份驗證,服務器的ssh_known_hosts文件必須包含所有受信任客户端的公共主機密鑰。

瞭解關於密鑰文件的信息對於更換計算機很有用。

當從頭開始安裝新計算機時,您可以從舊計算機導入密鑰文件,以確保用户在連接到新計算機時不會出現密鑰不匹配的情況。

Starting the SSH Server(啓動SSH服務器)

Although most distributions ship with SSH, they usually don’t start the sshd server by default. On Ubuntu and Debian, installing the SSH server package creates the keys, starts the server, and adds the startup to the bootup configuration. On Fedora, sshd is installed by default but turned off. To start sshd at boot, use chkconfig like this (this won’t start the server immediately; use service sshd start for that):

雖然大多數發行版都預裝了SSH,但它們通常不會默認啓動sshd服務器。在Ubuntu和Debian上,安裝SSH服務器包會創建密鑰、啓動服務器,並將啓動配置添加到啓動項中。

在Fedora上,默認安裝了sshd,但是處於關閉狀態。

要在啓動時啓動sshd,請使用chkconfig命令(這不會立即啓動服務器;要立即啓動服務器,請使用service sshd start命令)。

# chkconfig sshd on 

Fedora normally creates any missing host key files upon the first sshd startup.

Fedora通常會在第一次啓動sshd時創建任何缺失的主機密鑰文件。

If you don’t have any init support installed yet, running sshd as root starts the server, and upon startup, sshd writes its PID to /var/run/sshd.pid.

如果您尚未安裝任何init支持,以root身份運行sshd將啓動服務器,並在啓動時將其PID寫入/var/run/sshd.pid。

You can also start sshd as a socket unit in systemd or with inetd, but it’s usually not a good idea to do so because the server occasionally needs to generate key files, a process that can take a long time.

您也可以將sshd作為systemd中的套接字單元或使用inetd啓動,但通常不建議這樣做,因為服務器有時需要生成密鑰文件,這個過程可能需要很長時間。

10.3.2 The SSH Client(SSH客户端)

To log in to a remote host, run

要登錄到遠程主機,請運行:

$ ssh remote_username@host

You may omit remote_username@ if your local username is the same as on host. You can also run pipelines to and from an ssh command as shown in the following example, which copies a directory dir to another host:

如果您的本地用户名與主機上的相同,則可以省略remote_username@。

您還可以像以下示例中所示運行到ssh命令的管道,該示例將一個目錄dir複製到另一台主機:

$ tar zcvf - dir | ssh remote_host tar zxvf - 

The global SSH client configuration file ssh_config should be in /etc/ssh with your sshd_config file. As with the server configuration file, the client configuration file has key-value pairs, but you shouldn’t need to change them.

全局SSH客户端配置文件ssh_config應該位於/etc/ssh目錄下,與您的sshd_config文件一起。

與服務器配置文件一樣,客户端配置文件也有鍵值對,但您不應該需要更改它們。

The most frequent problem with using SSH clients occurs when an SSH public key in your local ssh_known_hosts or .ssh/known_hosts file does not match the key on the remote host. Bad keys cause errors or warnings like this:

使用SSH客户端時最常見的問題是,本地ssh_known_hosts或.ssh/known_hosts文件中的SSH公鑰與遠程主機上的密鑰不匹配。

錯誤的密鑰會導致如下錯誤或警告:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 
@    
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)! 
It is also possible that the RSA host key has just been changed. 
The fingerprint for the RSA key sent by the remote host is 
38:c2:f6:0d:0d:49:d4:05:55:68:54:2a:2f:83:06:11. 
Please contact your system administrator. 
Add correct host key in /home/user/.ssh/known_hosts to get rid of this 
message. 
Offending key in /home/user/.ssh/known_hosts:12➊ 
RSA host key for host has changed and you have requested 
strict checking. 
Host key verification failed.

This usually just means that the remote host’s administrator changed the keys (this often happens when replacing hardware), but it never hurts to check with the administrator if you’re not sure. In any case, the preceding message tells you that the bad key is in line 12 of a user’s known_hosts file, as shown at ➊.

這通常只是表示遠程主機的管理員更改了密鑰(通常在更換硬件時會發生),但如果不確定,最好還是與管理員確認一下。

無論如何,前面的消息告訴您,有問題的密鑰位於用户 known_hosts 文件的第12行,如圖所示。

If you don’t suspect foul play, just remove the offending line or replace it with the correct public key.

如果您不懷疑有惡意操作,只需刪除有問題的行或將其替換為正確的公鑰。

SSH File Transfer Clients(SSH 文件傳輸客户端)

OpenSSH includes the file transfer programs scp and sftp, which are intended as replacements for the older, insecure programs rcp and ftp.

OpenSSH 包括文件傳輸程序 scp 和 sftp,這兩個程序旨在取代較老、不安全的 rcp 和 ftp 程序。

You can use scp to transfer files to or from a remote machine to your machine or from one host to another. It works like the cp command. Here are a few examples:

您可以使用 scp 將文件從遠程計算機傳輸到您的計算機,或者在兩台主機之間傳輸文件。

它的工作方式類似於 cp 命令。以下是一些示例:

$ scp user@host:file . 
$ scp file user@host:dir 
$ scp user1@host1:file user2@host2:dir

The sftp program works like the command-line ftp client, using get and put commands. The remote host must have an sftp-server program installed, which you can expect if the remote host also uses OpenSSH.

sftp 程序類似於命令行 ftp 客户端,使用 get 和 put 命令。

遠程主機必須安裝 sftp-server 程序,如果遠程主機也使用 OpenSSH,您可以期望這個程序已安裝。

NOTE If you need more features and flexibility than the offerings of scp and sftp (for example, if you’re transferring large numbers of files often), have a look at rsync, described in Chapter 12.

注意:如果您需要比 scp 和 sftp 更多功能和靈活性的功能(例如,經常傳輸大量文件),請查看第 12 章中描述的 rsync。

SSH Clients for Non-Unix Platforms(非Unix平台的SSH客户端)

There are SSH clients for all popular operating systems, as listed on the OpenSSH web page (http://www.openssh.com/). Which one should you choose? PuTTY is a good, basic Windows client that includes a secure file-copy program. MacSSH works well for Mac OS 9.x and lower. Mac OS X is based on Unix and includes OpenSSH.

所有流行操作系統都有SSH客户端,可以在OpenSSH網頁(http://www.openssh.com/)上找到相關信息。

你應該選擇哪一個呢? PuTTY是一個不錯的基礎Windows客户端,包含一個安全的文件傳輸程序。

MacSSH適用於Mac OS 9.x及更低版本。

Mac OS X基於Unix,幷包含OpenSSH。

10.4 The inetd and xinetd Daemons(inetd 和 xinetd 守護進程)

Implementing standalone servers for every service can be somewhat inefficient. Each server must be separately configured to handle port listening, access control, and port configuration. These actions are performed in the same way for most services; only when a server accepts a connection is there any difference in the way communication is handled.

為每個服務實現獨立的服務器可能有些低效。每個服務器必須單獨配置以處理端口監聽、訪問控制和端口配置。

對於大多數服務,這些操作都是以相同的方式執行的;只有當服務器接受連接時,通信處理方式才有所不同。

One traditional way to simplify the use of servers is with the inetd daemon, a kind of superserver designed to standardize network port access and interfaces between server programs and network ports. After you start inetd, it reads its configuration file and then listens on the network ports defined in that file. As new network connections come in, inetd attaches a newly started process to the connection.

簡化服務器使用的一種傳統方式是使用 inetd 守護進程,這是一種超級服務器,旨在標準化網絡端口訪問和服務器程序與網絡端口之間的接口。

啓動 inetd 後,它會讀取其配置文件,然後監聽該文件中定義的網絡端口。隨着新的網絡連接到來,inetd 會將一個新啓動的進程附加到連接上。

A newer version of inetd called xinetd offers easier configuration and better access control, but xinetd itself is being phased out in favor of systemd, which can provide the same functionality through socket units, as described in 6.4.7 systemd On-Demand and Resource-Parallelized Startup.

一個名為 xinetd 的更新版本提供了更簡單的配置和更好的訪問控制,但 xinetd 本身正在被 systemd 取代,後者可以通過套接字單元提供相同的功能,如 6.4.7 systemd 按需和資源並行化啓動中所述。

Although inetd is no longer commonly used, its configuration shows everything necessary to set up a service. As it turns out, sshd can also be invoked by inetd rather than as a standalone server, as shown in this /etc/ inetd.conf configuration file:

儘管 inetd 不再常用,但其配置顯示了設置服務所需的一切。

事實證明,sshd 也可以由 inetd 而不是作為獨立服務器調用,如下所示在這個 /etc/ inetd.conf 配置文件中:

ident stream tcp  nowait root /usr/sbin/sshd sshd -i

The seven fields here are, from left to right:

o Service name. The service name from /etc/services (see 9.14.3 Port Numbers and /etc/services).
o Socket type. This is usually stream for TCP and dgram for UDP.
o Protocol. The transport protocol, usually tcp or udp.
o Datagram server behavior. For UDP, this is wait or nowait. Services using any other transport
protocol should use nowait.
o User. The username to run the service. Add .group to set a group.
o Executable. The program that inetd should connect to the service.
o Arguments. The arguments for the executable. The first argument should be the name of the program.

這裏的七個字段依次是:

o 服務名稱。來自 /etc/services 的服務名稱(參見 9.14.3 端口號和 /etc/services)。
o 套接字類型。通常為 TCP 的流式(stream),UDP 的數據報式(dgram)。
o 協議。傳輸協議,通常為 tcp 或 udp。
o 數據報服務器行為。對於 UDP,為 wait 或 nowait。使用其他傳輸協議的服務應該使用 nowait。
o 用户。運行服務的用户名。添加 .group 以設置一個用户組。
o 可執行文件。inetd 應該連接到的程序。
o 參數。可執行文件的參數。第一個參數應該是程序的名稱。

10.4.1 TCP Wrappers: tcpd, /etc/hosts.allow, and /etc/hosts.deny(TCP包裝:tcpd、/etc/hosts.allow和/etc/hosts.deny)

Before lower-level firewalls became popular, many administrators used the TCP wrapper library and daemon for host control over network services. In these implementations, inetd runs the tcpd program, which first looks at the incoming connection as well as the access control lists in the /etc/hosts.allow and /etc/hosts.deny files. The tcpd program logs the connection, and if it decides that the incoming connection is okay, it hands it to the final service program. (Although you may find a system that still uses the TCP wrapper system, we won’t cover it in detail because it has largely fallen into disuse.)

在較低級別的防火牆變得流行之前,許多管理員使用TCP包裝庫和守護程序來控制網絡服務的主機。

在這些實現中,inetd運行tcpd程序,該程序首先查看傳入連接以及/etc/hosts.allow和/etc/hosts.deny文件中的訪問控制列表。

tcpd程序記錄連接,如果確定傳入連接正常,則將其移交給最終的服務程序。

(儘管您可能會發現仍在使用TCP包裝系統的系統,但我們不會詳細介紹,因為它已經大部分被廢棄。)

10.5 Diagnostic Tools(診斷工具)

Let’s look at a few diagnostic tools that are useful for poking around the application layer. Some dig into the transport and network layers, because everything in the application layer eventually maps down to something in those lower layers.

讓我們看一些有用的診斷工具,用於查看應用層。

有些工具會深入到傳輸層和網絡層,因為應用層中的所有內容最終都會映射到這些較低的層中的某些內容。

As discussed in Chapter 9, netstat is a basic network service debugging tool that can display a number of transport and network layer statistics. Table 10-2 reviews a few useful options for viewing connections.

如第9章所討論的,netstat是一種基本的網絡服務調試工具,可以顯示許多傳輸層和網絡層的統計信息。

表10-2列出了一些有用的選項,用於查看連接。

Table 10-2. Useful Connection-Reporting Options for netstat

表10-2. netstat的有用連接報告選項

image.png

10.5.1 lsof

In Chapter 8, you learned that lsof can track open files, but it can also list the programs currently using or listening to ports. For a complete list of programs using or listening to ports, run

在第8章中,您瞭解到 lsof 可以跟蹤打開的文件,但它也可以列出當前正在使用或監聽端口的程序。

要獲取使用或監聽端口的程序的完整列表,請運行

# lsof -i 

When run as a regular user, this command only shows that user’s processes. When run as root, the output should look something like this, displaying a variety of processes and users:

以普通用户身份運行此命令時,只會顯示該用户的進程。

以 root 用户身份運行時,輸出應該類似於以下內容,顯示各種進程和用户:

image.png

This example output shows users and process IDs for server and client programs, from the old-style RPC services at the top, to the multicast DNS service provided by avahi, and even an IPv6-ready printer service (cupsd). The last two entries show client connections: an SSH connection and a secure web connection from the Chromium web browser. Because the output can be extensive, it’s usually best to apply a filter (as discussed in the following section).

這個示例輸出顯示了服務器和客户端程序的用户和進程ID,從頂部的舊式RPC服務,到由avahi提供的多播DNS服務,甚至是一個支持IPv6的打印機服務(cupsd)。

最後兩個條目顯示了客户端連接:一個SSH連接和來自Chromium網頁瀏覽器的安全網頁連接。

由於輸出可能很龐大,通常最好應用過濾器(如下一節所討論的)。

The lsof program is like netstat in that it tries to reverse-resolve every IP address that it finds into a hostname, which slows down the output. Use the -n option to disable name resolution:

lsof程序類似於netstat,它嘗試將找到的每個IP地址反向解析為主機名,這會減慢輸出速度。

使用-n選項來禁用名稱解析:

# lsof -n -i 

You can also specify -P to disable /etc/services port name lookups.

您還可以指定-P選項來禁用/etc/services端口名稱查找。

Filtering by Protocol and Port(按協議和端口過濾)

If you’re looking for a particular port (say, you know that a process is using a particular port and you want to know what that process is), use this command:

如果您正在尋找特定的端口(比如,您知道某個進程正在使用特定端口,想要知道該進程是什麼),可以使用以下命令:

# lsof -i:port

The full syntax is as follows:

完整的語法如下:

# lsof -iprotocol@host:port 

The protocol, @host, and :port parameters are all optional and will filter the lsof output accordingly. As with most network utilities, host and port can be either names or numbers. For example, if you only want to see connections on TCP port 80 (the HTTP port), use

協議、@主機和:端口號參數都是可選的,將根據它們過濾lsof輸出。

與大多數網絡工具一樣,主機和端口可以是名稱或數字。

例如,如果您只想看到TCP端口80(HTTP端口)上的連接,請使用:

# lsof -iTCP:80

Filtering by Connection Status(通過連接狀態過濾)

One particularly handy lsof filter is connection status. For example, to show only the processes listening on TCP ports, enter

連接狀態是一個特別方便的 lsof 過濾器。

例如,要只顯示監聽 TCP 端口的進程,輸入

# lsof -iTCP -sTCP:LISTEN

This command gives you a good overview of the network server processes currently running on your system. However, because UDP servers don’t listen and don’t have connections, you’ll have to use -iUDP to view running clients as well as servers. This usually isn’t a problem, because you probably won’t have many UDP servers on your system.

這個命令可以讓你清楚地瞭解當前在你的系統上正在運行的網絡服務器進程。

然而,由於UDP服務器不監聽也不建立連接,你需要使用-iUDP選項來查看正在運行的客户端以及服務器。

通常情況下這不會是一個問題,因為你的系統上可能不會有很多UDP服務器。

10.5.2 tcpdump

If you need to see exactly what’s crossing your network, tcpdump puts your network interface card into promiscuous mode and reports on every packet that crosses the wire. Entering tcpdump with no arguments produces output like the following, which includes an ARP request and web connection:

如果你需要準確查看穿過你的網絡的內容,tcpdump會將你的網絡接口卡置於混雜模式,並報告每一個經過的數據包。

輸入無參數的tcpdump會產生如下輸出,其中包括一個ARP請求和web連接:

# tcpdump 
tcpdump: listening on eth0 
20:36:25.771304 arp who-has mikado.example.com tell duplex.example.com 
20:36:25.774729 arp reply mikado.example.com is-at 0:2:2d:b:ee:4e 
20:36:25.774796 duplex.example.com.48455 > mikado.example.com.www: S 
3200063165:3200063165(0) 
38815804[|tcp]> 
(DF) 
win 
5840 
<mss 
1460,sackOK,timestamp 
20:36:25.779283 mikado.example.com.www > duplex.example.com.48455: S 
ack 
3200063166 
win 
5792 
<mss 
3494716463:3494716463(0) 
1460,sackOK,timestamp 
4620[|tcp]> (DF) 
20:36:25.779409 duplex.example.com.48455 > mikado.example.com.www: . 
ack 1 win 
5840 <nop,nop,timestamp 38815805 4620> (DF) 
20:36:25.779787 duplex.example.com.48455 > mikado.example.com.www: P 
1:427(426) 
ack 1 win 5840 <nop,nop,timestamp 38815805 4620> (DF) 
20:36:25.784012 mikado.example.com.www > duplex.example.com.48455: . 
ack 427 
win 6432 <nop,nop,timestamp 4620 38815805> (DF) 
20:36:25.845645 mikado.example.com.www > duplex.example.com.48455: P 
1:773(772) 
ack 427 win 6432 <nop,nop,timestamp 4626 38815805> (DF) 
20:36:25.845732 duplex.example.com.48455 > mikado.example.com.www: . 
ack 773 
win 6948 <nop,nop,timestamp 38815812 4626> (DF) 
9 packets received by filter 
0 packets dropped by kernel

You can tell tcpdump to be more specific by adding filters. You can filter based on source and destination hosts, networks, Ethernet addresses, protocols at many different layers in the network model, and much more. Among the many packet protocols that tcpdump recognizes are ARP, RARP, ICMP, TCP, UDP, IP, IPv6, AppleTalk, and IPX packets. For example, to tell tcpdump to output only TCP packets, run

你可以通過添加過濾器來讓tcpdump更具體。

你可以根據源主機、目標主機、網絡、以太網地址、網絡模型中的許多不同層面的協議等進行過濾,還有更多選項。

tcpdump能識別的許多數據包協議包括ARP、RARP、ICMP、TCP、UDP、IP、IPv6、AppleTalk和IPX數據包。

例如,要告訴tcpdump僅輸出TCP數據包,可以運行:

# tcpdump tcp

To see web packets and UDP packets, enter

要查看網絡數據包和 UDP 數據包,請輸入

# tcpdump udp or port 80

NOTE If you need to do a lot of packet sniffing, consider using a GUI alternative to tcpdump such as Wireshark.

注意 如果需要進行大量數據包嗅探,可考慮使用圖形用户界面來替代 tcpdump,如 Wireshark。

Primitives(基元)

In the preceding examples, tcp, udp, and port 80 are called primitives. The most important primitives are in Table 10-3:

在前面的示例中,tcp、udp 和端口 80 被稱為基元。表 10-3 列出了最重要的基元:

Table 10-3. tcpdump Primitives

表 10-3. tcpdump 基元

Table 10-3. tcpdump Primitives

Operators(運算符)

The or used in the previous example is an operator. tcpdump can use multiple operators (such as and and !), and you can group operators in parentheses. If you plan to do any serious work with tcpdump, make sure to read the manual page, especially the section that describes the primitives.

在前面的示例中使用的 or 是一個運算符。tcpdump 可以使用多個運算符(比如 and 和 !),你可以將運算符分組在括號中。

如果你打算在 tcpdump 中進行任何嚴肅的工作,請務必閲讀手冊頁,特別是描述基本操作的部分。

When Not to Use tcpdump(不應該使用 tcpdump 的情況)

Be very careful when using tcpdump. The tcpdump output shown earlier in this section includes only packet TCP (transport layer) and IP (Internet layer) header information, but you can also make tcpdump print the entire packet contents. Even though many network operators make it far too easy to look at their network packets, you shouldn’t snoop around on networks unless you own them.

在使用 tcpdump 時要非常小心。在本節中之前展示的 tcpdump 輸出僅包含數據包的 TCP(傳輸層)和 IP(網絡層)頭部信息,但你也可以讓 tcpdump 打印完整的數據包內容。

儘管許多網絡運營商讓查看他們的網絡數據包變得非常容易,但你不應該在沒有權限的情況下窺探網絡。

10.5.3 netcat

If you need more flexibility in connecting to a remote host than a command like telnet host port allows, use netcat (or nc). netcat can connect to remote TCP/UDP ports, specify a local port, listen on ports, scan ports, redirect standard I/O to and from network connections, and more. To open a TCP connection to a port with netcat, run

如果您需要比telnet主機端口命令更靈活地連接到遠程主機,可以使用netcat(或nc)。

netcat可以連接到遠程TCP/UDP端口,指定本地端口,監聽端口,掃描端口,重定向標準I/O到網絡連接等等。

要使用netcat打開到端口的TCP連接,請運行

$ netcat host port 

netcat only terminates when the other side of the connection ends the connection, which can confuse things if you redirect standard input to netcat. You can end the connection at any time by pressing CTRL-C. (If you’d like the program and network connection to terminate based on the standard input stream, try the sock program instead.)

netcat 只有在連接的另一端結束連接時才會終止,如果你將標準輸入重定向到 netcat,這可能會導致混淆。你可以通過按下 CTRL-C 隨時結束連接。

(如果你希望程序和網絡連接根據標準輸入流終止,請嘗試使用 sock 程序。)

To listen on a particular port, run

要監聽特定端口,請運行

$ netcat -l -p port_number 

10.5.4 Port Scanning(端口掃描)

Sometimes you don’t even know what services the machines on your networks are offering or even which IP addresses are in use. The Network Mapper (Nmap) program scans all ports on a machine or network of machines looking for open ports, and it lists the ports it finds. Most distributions have an Nmap package, or you can get it at http://www.insecure.org/. (See the Nmap manual page and online resources for all that Nmap can do.)

有時候你甚至不知道你網絡上的設備提供了哪些服務,甚至不知道哪些 IP 地址正在使用。

網絡映射工具(Nmap)程序會掃描一台機器或一組機器上的所有端口,尋找開放的端口,並列出它所找到的端口。

大多數發行版都有 Nmap 軟件包,或者你可以在 http://www.insecure.org/ 獲取它。

(查看 Nmap 手冊頁和在線資源,瞭解 Nmap 的所有功能。)

When listing ports on your own machine, it often helps to run the Nmap scan from at least two points: from your own machine and from another one (possibly outside your local network). Doing so will give you an overview of what your firewall is blocking.

當列出自己機器上的端口時,通常最好從至少兩個點運行 Nmap 掃描:從你自己的機器和另一個機器(可能是在本地網絡之外的機器)。

這樣做將讓你瞭解你的防火牆正在阻止什麼。

WARNING If someone else controls the network that you want to scan with Nmap, ask for permission. Network administrators watch for port scans and usually disable access to machines that run them.

警告 如果有其他人控制你想要用 Nmap 掃描的網絡,請先徵得許可。網絡管理員會監視端口掃描,並通常會禁止運行它們的設備的訪問。

Run nmap host to run a generic scan on a host. For example:

運行 nmap host 命令在主機上運行一次通用掃描。

例如:

$ nmap 10.1.2.2 
Starting Nmap 5.21 ( http://nmap.org ) at 2015-09-21 16:51 PST 
Nmap scan report for 10.1.2.2 
Host is up (0.00027s latency). 
Not shown: 993 closed ports 
PORT     
STATE SERVICE 
22/tcp   open  ssh 
25/tcp   open  smtp 
80/tcp   open  http 
111/tcp  open  rpcbind 
8800/tcp open  unknown 
9000/tcp open  cslistener 
9090/tcp open  zeus-admin 
Nmap done: 1 IP address (1 host up) scanned in 0.12 seconds

As you can see, a number of services are open here, many of which are not enabled by default on most distributions. In fact, the only one here that’s usually on by default is port 111, the rpcbind port.

正如您所見,這裏打開了許多服務,其中許多在大多數發行版上默認情況下都未啓用。實際上,這裏通常默認啓用的僅有一個,即端口111,即rpcbind端口。

10.6 Remote Procedure Call (RPC)

What about the rpcbind service that you just saw in the scan in the preceding section? RPC stands for remote procedure call, a system residing in the lower parts of the application layer. It’s designed to make it easier for programmers to access network applications by leveraging the fact that programs call functions on remote programs (identified by program numbers) and the remote programs return a result code or message.

你剛剛在前面的掃描中看到的rpcbind服務怎麼樣?RPC代表遠程過程調用,是位於應用層較低部分的系統。它旨在通過利用程序調用遠程程序(由程序號標識)並遠程程序返回結果代碼或消息的方式,使程序員更容易訪問網絡應用程序。

RPC implementations use transport protocols such as TCP and UDP, and they require a special intermediary service to map program numbers to TCP and UDP ports. The server is called rpcbind, and it must be running on any machine that wants to use RPC services.

RPC實現使用諸如TCP和UDP之類的傳輸協議,並且它們需要一個特殊的中間服務來將程序號映射到TCP和UDP端口。該服務器稱為rpcbind,任何想要使用RPC服務的機器都必須運行該服務。

To see what RPC services your computer has, run

要查看你的計算機具有哪些RPC服務,運行以下命令:

$ rpcinfo -p localhost 

RPC is one of those protocols that just doesn’t want to die. The Network File System (NFS) and Network Information Service (NIS) systems use RPC, but they are completely unnecessary on standalone machines. But whenever you think that you’ve eliminated all need for rpcbind, something else comes up, such as File Access Monitor (FAM) support in GNOME.

RPC是那種似乎不願消亡的協議之一。

網絡文件系統(NFS)和網絡信息服務(NIS)系統使用RPC,但在獨立機器上完全是不必要的。

但是,每當您認為已經消除了對rpcbind的所有需求時,又會出現其他問題,比如GNOME中的文件訪問監視器(FAM)支持。

10.7 Network Security(網絡安全)

Because Linux is a very popular Unix flavor on the PC platform, and especially because it is widely used for web servers, it attracts many unpleasant characters who try to break into computer systems. 9.21 Firewalls discussed firewalls, but that’s not really the whole story on security.

由於Linux是PC平台上非常流行的Unix版本,特別是因為它廣泛用於Web服務器,吸引了許多不懷好意的人物試圖侵入計算機系統。9.21 防火牆討論了防火牆,但這並不是安全的全部故事。

Network security attracts extremists—those who really like to break into systems (whether for fun or money) and those who come up with elaborate protection schemes who really like to swat away people trying to break into their systems. (This, too, can be very profitable.) Fortunately, you don’t need to know very much to keep your system safe. Here are a few basic rules of thumb:

網絡安全吸引了極端分子——那些真的喜歡入侵系統的人(無論是為了樂趣還是金錢),以及那些設計複雜保護方案的人,他們真的喜歡擊退試圖入侵他們系統的人。

(這也可以非常有利可圖。)幸運的是,你不需要了解太多就能保護好你的系統。以下是一些基本的經驗法則:

o Run as few services as possible. Intruders can’t break into services that don’t exist on your system. If you know what a service is and you’re not using it, don’t turn it on for the sole reason that you might want to use it “at some later point.”

  • 儘可能運行儘可能少的服務。入侵者無法入侵你係統上不存在的服務。如果你知道一個服務是什麼,而你又沒有使用它,不要僅僅因為你可能想在“以後的某個時候”使用它而打開它。

o Block as much as possible with a firewall. Unix systems have a number of internal services that you may not know about (such as TCP port 111 for the RPC port-mapping server), and no other system in the world should know about them. It can be very difficult to track and regulate the services on your system because many different kinds of programs listen on various ports. To keep intruders from discovering internal services on your system, use effective firewall rules, and install a firewall at your router.

  • 儘可能使用防火牆阻止一切。Unix系統有許多內部服務,你可能不知道它們的存在(比如TCP端口111用於RPC端口映射服務器),世界上沒有其他系統應該知道它們。

    • 要跟蹤和管理系統上的服務可能非常困難,因為許多不同種類的程序會監聽各種端口。
    • 為了防止入侵者發現你係統上的內部服務,使用有效的防火牆規則,在你的路由器上安裝一個防火牆。

o Track the services that you offer to the Internet. If you run an SSH server, Postfix, or similar services, keep your software up-to-date and get appropriate security alerts. (See 10.7.2 Security Resources for some online resources.)

  • 跟蹤你向互聯網提供的服務。如果你運行SSH服務器、Postfix或類似的服務,請保持軟件更新,並獲取適當的安全警報。(參見10.7.2 安全資源,瞭解一些在線資源。)

o Use “long-term support” distribution releases for servers. Security teams normally concentrate their work on stable, supported distribution releases. Development and testing releases such Debian Unstable and Fedora Rawhide receive much less attention.

  • 對於服務器,使用“長期支持”發行版。安全團隊通常會集中精力在穩定、受支持的發行版上進行工作。開發和測試發行版如Debian Unstable和Fedora Rawhide接受的關注要少得多。

o Don’t give an account on your system to anyone who doesn’t need one. It’s much easier to gain superuser access from a local account than it is to break in remotely. In fact, given the huge base of software (and the resulting bugs and design flaws) available on most systems, it can be easy to gain superuser access to a system after you get to a shell prompt. Don’t assume that your friends know how to protect their passwords (or choose good passwords in the first place).

  • 不要為不需要的人在你的系統上創建賬户。

    • 從本地賬户獲取超級用户權限比遠程入侵要容易得多。
    • 事實上,鑑於大多數系統上可用的軟件(以及由此產生的漏洞和設計缺陷),一旦你進入一個shell提示符,很容易獲得系統的超級用户權限。
    • 不要假設你的朋友知道如何保護他們的密碼(或者一開始就選擇好密碼)。

o Avoid installing dubious binary packages. They can contain Trojan horses. That’s the practical end of protecting yourself. But why is it important to do so? There are three basic kinds of network attacks:

  • 避免安裝可疑的二進制軟件包。它們可能包含特洛伊木馬。

    • 這是保護自己的實際結束。但為什麼這麼做很重要呢?網絡攻擊有三種基本類型:

o Full compromise. This means getting superuser access (full control) of a machine. An intruder can accomplish this by trying a service attack, such as a buffer overflow exploit, or by taking over a poorly protected user account and then trying to exploit a poorly written setuid program.

  • 完全破壞。這意味着獲得對機器的超級用户權限(完全控制)。

    • 入侵者可以通過嘗試服務攻擊,比如緩衝區溢出攻擊,或者接管一個保護不力的用户賬户,然後嘗試利用一個編寫不好的setuid程序來實現這一點。

o Denial-of-service (DoS) attack. This prevents a machine from carrying out its network services or forces a computer to malfunction in some other way without the use of any special access. These attacks are harder to prevent, but they are easier to respond to.

  • 拒絕服務(DoS)攻擊。這會阻止機器執行其網絡服務,或者以其他方式迫使計算機發生故障,而無需使用任何特殊訪問。

    • 這些攻擊更難預防,但更容易應對。

o Malware. Linux users are mostly immune to malware such as email worms and viruses, simply because their email clients aren’t stupid enough to actually run programs that they get in message attachments. But Linux malware does exist. Avoid downloading and installing binary software from places that you’ve never heard of.

  • 惡意軟件。Linux用户大多免疫於惡意軟件,如電子郵件蠕蟲和病毒,僅僅因為他們的電子郵件客户端並不愚蠢到實際運行他們在消息附件中收到的程序。

    • 但Linux上確實存在惡意軟件。避免從你從未聽説過的地方下載和安裝二進制軟件。

    10.7.1 Typical Vulnerabilities

There are two important kinds of vulnerabilities to worry about: direct attacks and clear-text password sniffing. Direct attacks try to take over a machine without being terribly subtle. The most common is a buffer overflow exploit, where a careless programmer doesn’t check the bounds of a buffer array. The attacker fabricates a stack frame inside a huge chunk of data, dumps it to the remote server, and then hopes that the server overwrites its program data and eventually executes the new stack frame. Although a somewhat complicated attack, it’s easy to replicate.

有兩種重要的漏洞需要擔心:直接攻擊和明文密碼嗅探。直接攻擊試圖接管機器而不太敏鋭。

最常見的是緩衝區溢出利用,一個粗心的程序員沒有檢查緩衝區數組的邊界。

攻擊者在大量數據中製造一個棧幀,將其轉儲到遠程服務器,然後希望服務器覆蓋其程序數據並最終執行新的棧幀。

雖然這是一個有些複雜的攻擊,但很容易複製。

A second attack to worry about is one that captures passwords sent across the wire as clear text. As soon as an attacker gets your password, it’s game over. From there, the assailant will inevitably try to gain superuser access locally (which is much easier than making a remote attack), try to use the machine as an intermediary for attacking other hosts, or both.

第二種需要擔心的攻擊是捕獲明文傳輸的密碼。

一旦攻擊者獲取到你的密碼,遊戲就結束了。

從那裏開始,攻擊者將不可避免地嘗試在本地獲得超級用户訪問權限(比進行遠程攻擊容易得多),嘗試使用該機器作為攻擊其他主機的中介,或兩者兼而有之。

NOTE If you have a service that offers no native support for encryption, try Stunnel ( http://www.stunnel.org/), an encryption wrapper package much like TCP wrappers. Like tcpd, Stunnel is especially good at wrapping inetd services.

注意:如果您有一個不支持加密的服務,請嘗試使用 Stunnel(http://www.stunnel.org/),這是一個類似於 TCP wrappers 的加密包裝程序。與 tcpd 一樣,Stunnel 尤其擅長包裝 inetd 服務。

Some services are chronic attack targets due to poor implementation and design. You should always deactivate the following services (they’re rarely activated by default on most systems):

由於實施和設計不當,有些服務長期成為攻擊目標。

應始終停用以下服務(大多數系統默認情況下很少激活這些服務):

  • ftpd For whatever reason, all FTP servers seem plagued with vulnerabilities. In addition, most FTP servers use clear-text passwords. If you have to move files from one machine to another, consider an SSH based solution or an rsync server.
  • telnetd, rlogind, rexecd All of these pass remote session data (including passwords) in clear-text form. Avoid them unless you happen to have a Kerberos-enabled version.
  • fingerd Intruders can get user lists and other information with the finger service.
  • ftpd 由於某種原因,所有 FTP 服務器似乎都深受漏洞困擾。此外,大多數 FTP 服務器使用明文密碼。

    • 如果您必須從一台機器移動文件到另一台機器,請考慮使用基於 SSH 的解決方案或一個 rsync 服務器。
  • telnetd、rlogind、rexecd 所有這些服務以明文形式傳遞遠程會話數據(包括密碼)。

    • 除非您碰巧有一個啓用了 Kerberos 的版本,否則應避免使用它們。
  • fingerd 入侵者可以通過 finger 服務獲取用户列表和其他信息。

    10.7.2 Security Resources

Here are three good security sites:
o http://www.sans.org/ Offers training, services, a free weekly newsletter listing the top current vulnerabilities, sample security policies, and more.
o http://www.cert.org/ A place to look for the most severe problems.
o http://www.insecure.org/ This is the place to go for Nmap and pointers to all sorts of network exploittesting tools. It’s much more open and specific about exploits than are many other sites.

這裏有三個優秀的網絡安全網站:

  • http://www.sans.org/ 提供培訓、服務、免費每週簡報列出當前頂級漏洞、示例安全策略等。
  • http://www.cert.org/ 是尋找最嚴重問題的地方。
  • http://www.insecure.org/ 這是一個獲取Nmap和各種網絡漏洞測試工具指針的地方。它比許多其他網站更加開放和具體關於漏洞利用。

If you’re interested in network security, you should learn all about Transport Layer Security (TLS) and its predecessor, Secure Socket Layer (SSL). These user-space network levels are typically added to networking clients and servers to support network transactions through the use of public-key encryption and certificates. A good guide is Davies’s Implementing SSL/TLS Using Cryptography and PKI (Wiley, 2011).

如果你對網絡安全感興趣,你應該全面瞭解傳輸層安全性(TLS)及其前身安全套接字層(SSL)。

這些用户空間網絡層通常添加到網絡客户端和服務器中,通過公鑰加密和證書支持網絡交易。

一個好的指南是戴維斯(Davies)的《使用密碼學和PKI實現SSL/TLS》(Wiley,2011年)。

10.8 Looking Forward(展望未來)

If you’re interested in getting your hands dirty with some complicated network servers, two very common ones are the Apache web server and the Postfix email server. In particular, Apache is easy to install and most distributions supply a package. If your machine is behind a firewall or NAT-enabled router, you can experiment with the configuration as much as you’d like without worrying about security.

如果你對涉足一些複雜的網絡服務器感興趣,那麼兩個非常常見的服務器是Apache Web服務器和Postfix郵件服務器。

特別是,Apache很容易安裝,大多數發行版都提供了相關軟件包。

如果你的機器位於防火牆或啓用NAT的路由器後面,你可以隨意嘗試不用擔心安全性的配置。

Throughout the last few chapters, we’ve been gradually moving from kernel space into user space. Only a few utilities discussed in this chapter, such as tcpdump, interact with the kernel. The remainder of this chapter describes how sockets bridge the gap between the kernel’s transport layer and the user-space application layer. It’s more advanced material, of particular interest to programmers, so feel free to skip to the next chapter if you like.

在過去的幾章中,我們逐漸從內核空間移動到用户空間。

本章僅討論了幾個與內核交互的實用工具,比如tcpdump。

本章的其餘部分描述了套接字如何彌合內核的傳輸層和用户空間應用層之間的差距。

這是更加高級的內容,特別適合程序員,如果你願意,可以隨意跳到下一章。

10.9 Sockets: How Processes Communicate with the Network(套接字:進程如何與網絡通信)

We’re now going to shift gears a little and look at how processes do the work of reading data from and writing data to the network. It’s easy enough for processes to read from and write to network connections that are already set up: All you need are some system calls, which you can read about in the recv(2) and send(2) manual pages. From the point of view of a process, perhaps the most important thing to know is how to refer to the network when using these system calls. On Unix systems, a process uses a socket to identify when and how it’s talking to the network. Sockets are the interface that processes use to access the network through the kernel; they represent the boundary between user space and kernel space. They’re often also used for interprocess communication (IPC).

現在我們將稍作轉變,看看進程如何從網絡讀取數據和向網絡寫入數據。

對於進程來説,從已經建立好的網絡連接中讀取數據和寫入數據是相當容易的:你只需要一些系統調用,你可以在 recv(2) 和 send(2) 的手冊頁面中找到相關信息。

從進程的角度來看,也許最重要的是在使用這些系統調用時如何引用網絡。

在Unix系統中,進程使用套接字來識別它何時以及如何與網絡通信。

套接字是進程通過內核訪問網絡的接口;它們代表了用户空間和內核空間之間的邊界。

它們經常也被用於進程間通信(IPC)。

There are different types of sockets because processes need to access the network in different ways. For example, TCP connections are represented by stream sockets (SOCK_STREAM, from a programmer’s point of view), and UDP connections are represented by datagram sockets (SOCK_DGRAM).

由於進程需要以不同的方式訪問網絡,因此存在不同類型的套接字。

例如,TCP連接由流套接字(SOCK_STREAM,從程序員的角度看)表示,而UDP連接由數據報套接字(SOCK_DGRAM)表示。

Setting up a network socket can be somewhat complicated because you need to account for socket type, IP addresses, ports, and transport protocol at particular times. However, after all of the initial details are sorted out, servers use certain standard methods to deal with incoming traffic from the network.

設置網絡套接字可能會有些複雜,因為您需要考慮套接字類型、IP地址、端口和特定時間的傳輸協議。

然而,一旦所有初始細節都得到解決,服務器就會使用某些標準方法來處理來自網絡的傳入流量。

The flowchart in Figure 10-1 shows how many servers handle connections for incoming stream sockets. Notice that this type of server involves two kinds of sockets: a listening socket and a socket for reading and writing. The master process uses the listening socket to look for connections from the network. When a new connection comes in, the master process uses the accept() system call to accept the connection, which creates the read/write socket dedicated to that one connection. Next, the master process uses fork() to create a new child process to deal with the connection. Finally, the original socket remains the listener and continues to look for more connections on behalf of the master process.

圖 10-1 中的流程圖顯示了許多服務器如何處理輸入流套接字的連接。

請注意,這種服務器涉及兩種套接字:監聽套接字和用於讀寫的套接字。

主進程使用監聽套接字查找來自網絡的連接。

當有新的連接進來時,主進程會使用 accept() 系統調用來接受該連接,從而創建專用於該連接的讀寫套接字。

接着,主進程使用 fork() 創建一個新的子進程來處理該連接。

最後,原始套接字仍作為監聽器,繼續代表主進程尋找更多連接。

After a process has set up a socket of a particular type, it can interact with it in a way that fits the socket type. This is what makes sockets flexible: If you need to change the underlying transport layer, you don’t have to rewrite all of the parts that send and receive data; you mostly need to modify the initialization code.

在一個進程建立了特定類型的套接字之後,它可以以適合套接字類型的方式與之交互。

這就是套接字靈活的原因:如果你需要更改底層傳輸層,你不必重寫所有發送和接收數據的部分;

你只需修改初始化代碼即可。

image.png

Figure 10-1. One method for accepting and processing incoming connections

圖10-1. 一種接受和處理傳入連接的方法

If you’re a programmer and you’d like to learn how to use the socket interface, Unix Network Programming, Volume 1, 3rd edition, by W. Richard Stephens, Bill Fenner, and Andrew M. Rudoff (Addison-Wesley Professional, 2003) is the classic guide. Volume 2 also covers interprocess communication.

如果您是一名程序員,想學習如何使用套接字接口,那麼《Unix網絡編程》第1卷,第3版,作者W. Richard Stephens、Bill Fenner和Andrew M. Rudoff(Addison-Wesley Professional,2003年)是經典指南。

第2卷也涵蓋了進程間通信。

10.10 Unix Domain Sockets(Unix 域套接字)

Applications that use network facilities don’t have to involve two separate hosts. Many applications are built as client-server or peer-to-peer mechanisms, where processes running the same machine use interprocess communication (IPC) to negotiate what work needs to be done and who does it. For example, recall that daemons such as systemd and NetworkManager use D-Bus to monitor and react to system events.

使用網絡設施的應用程序不一定要涉及兩個獨立的主機。

許多應用程序被構建為客户端-服務器或對等機制,其中在同一台計算機上運行的進程使用進程間通信(IPC)來協商需要執行什麼工作以及由誰執行。

例如,諸如 systemd 和 NetworkManager 等守護進程使用 D-Bus 監控並響應系統事件。

Processes can use regular IP networking over localhost (127.0.0.1) to communicate, but instead, typically use a special kind of socket, which we briefly touched upon in Chapter 3, called a Unix domain socket. When a process connects to a Unix domain socket, it behaves almost exactly like a network socket: It can listen for and accept connections on the socket, and you can even choose between different kinds of socket types to make it behave like TCP or UDP.

進程可以通過本地主機(127.0.0.1)上的常規 IP 網絡進行通信,但通常會使用一種特殊類型的套接字,我們在第 3 章中簡要介紹過,稱為 Unix 域套接字

當一個進程連接到一個 Unix 域套接字時,它幾乎與網絡套接字的行為完全相同:它可以在套接字上監聽並接受連接,甚至可以選擇不同類型的套接字來使其表現得像 TCP 或 UDP 一樣。

NOTE It’s important to remember that a Unix domain socket is not a network socket, and there’s no network behind one. You don’t even need networking to be configured to use one. And Unix domain sockets don’t have to be bound to socket files. A process can create an unnamed Unix domain socket and share the address with another process.

注意 重要的是要記住 Unix 域套接字不是網絡套接字,它背後沒有網絡。甚至不需要配置網絡就可以使用它。

而且 Unix 域套接字不必綁定到套接字文件上。

一個進程可以創建一個未命名的 Unix 域套接字,並與另一個進程共享地址。

10.10.1 Advantages for Developers(開發者的優勢)

Developers like Unix domain sockets for IPC for two reasons. First, they allow developers the option to use special socket files in the filesystem to control access, so any process that doesn’t have access to a socket file can’t use it. And because there’s no interaction with the network, it’s simpler and less prone to conventional network intrusion. For example, you’ll usually find the socket file for D-Bus in /var/run/dbus:

開發者喜歡使用 Unix 域套接字進行進程間通信有兩個原因。

首先,它們允許開發者使用文件系統中的特殊套接字文件來控制訪問權限,因此任何沒有訪問權限的進程都無法使用它。

而且由於不涉及網絡交互,這樣做更簡單,且不容易受到傳統網絡入侵的影響。

例如,通常你會在 /var/run/dbus 目錄下找到 D-Bus 的套接字文件:

$ ls -l /var/run/dbus/system_bus_socket 
srwxrwxrwx 1 root root 0 Nov 9 08:52 /var/run/dbus/system_bus_socket

Second, because the Linux kernel does not have to go through the many layers of its networking subsystem when working with Unix domain sockets, performance tends to be much better.

第二,由於Linux內核在使用Unix域套接字時無需經過許多層網絡子系統,因此性能往往更好。

Writing code for Unix domain sockets is not much different from supporting normal network sockets. Because the benefits can be significant, some network servers offer communication through both network and Unix domain sockets. For example, the MySQL database server mysqld can accept client connections from remote hosts, but it usually also offers a Unix domain socket at /var/run/mysqld/mysqld.sock.

編寫Unix域套接字的代碼與支持普通網絡套接字並無太大不同。

由於好處可能非常顯著,一些網絡服務器提供通過網絡和Unix域套接字進行通信的功能。

例如,MySQL數據庫服務器mysqld可以接受來自遠程主機的客户端連接,但通常也提供位於/var/run/mysqld/mysqld.sock的Unix域套接字。

10.10.2 Listing Unix Domain Sockets(列出 Unix 域套接字)

You can view a list of Unix domain sockets currently in use on your system with lsof -U:

您可以使用命令 lsof -U 查看當前系統上正在使用的 Unix 域套接字列表:

# lsof -U 

COMMAND mysqld PID 19701 USER mysql /var/run/mysqld/mysqld.sock chromium- socket tlsmgr socket tlsmgr 26534 juser 30480 postfix FD 30480 postfix TYPE DEVICE SIZE/OFF 12u unix 0xe4defcc0 5u 5u 6u unix 0xeeac9b00 unix 0xc3384240 unix 0xe20161c0 NODE NAME 0t0 35201227 0t0 42445141 0t0 17009106 0t0 10965 private/tlsmgr

--snip--

The listing will be quite long because many modern applications make extensive use of unnamed sockets. You can identify the unnamed ones because you’ll see socket in the NAME output column.

由於許多現代應用程序廣泛使用未命名套接字,因此清單將會相當長。

您可以通過在“NAME”輸出列中看到套接字來識別未命名套接字。

user avatar jkdataapi Avatar hebeiniunai Avatar superiorc Avatar cumeimaodeyingpan Avatar jinjiedefarmer Avatar
Favorites 5 users favorite the story!
Favorites

Add a new Comments

Some HTML is okay.