How Linux Works Chương 10 · Network Applications and Services

Chương 10 · Ứng dụng và dịch vụ mạng Chapter 10 · Network Applications and Services

Ở tầng ứng dụng, mạng chỉ còn là hai tiến trình nói chuyện qua một luồng byte Trên mạng, hai chương trình nói chuyện qua một cái ống At the application layer, the network is just two processes talking over a stream of bytes

Chương 10 là chương “dễ thở” nhất của phần mạng, và Brian Ward nói thẳng lý do: tầng ứng dụng nằm trên cùng của chồng giao thức, sát với người dùng cuối, nên bạn có thể thấy tài liệu ở đây dễ tiếp cận hơn so với Chương 9.1 Thứ chương này mô tả là các máy khách và máy chủ chạy trong không gian người dùng — chính những chương trình bạn dùng mỗi ngày.1

Chương này nói về những chương trình chạy trên mạng mà bạn quen mặt: trình duyệt web, chương trình đăng nhập từ xa, chương trình gửi tệp. Chúng nằm ở tầng trên cùng, gần bạn nhất, nên dễ hiểu hơn mấy tầng bên dưới. Nhớ nhé: tầng càng gần bạn thì càng dễ hình dung.

Chapter 10 is the friendliest chapter of the networking run, and Brian Ward says why outright: this layer sits at the top of the stack, close to end users, so you may find the material more accessible than that of Chapter 9.1 What the chapter describes are the clients and servers running in user space — exactly the programs you interact with every day.1

Điểm đáng chú ý trong cách tổ chức của ông: chương bắt đầu từ chỗ cao nhất (gõ tay một yêu cầu HTTP qua telnet) rồi đi ngược xuống, kết thúc ở socket — thứ mà chính ông gọi là ranh giới giữa không gian người dùng và không gian nhân.1 Hai mục cuối (10.9 và 10.10) được ông đánh dấu là “tài liệu nâng cao, đặc biệt dành cho lập trình viên”, và ông cho phép bạn bỏ qua để sang chương sau.1

Luận đề của chương: một dịch vụ mạng không có gì huyền bí — nó là một tiến trình không gian người dùng lắng nghe trên một cổng, fork() ra tiến trình con cho mỗi kết nối, và đọc/ghi qua một socket; mọi công cụ chẩn đoán trong chương (lsof, tcpdump, netcat, nmap) chỉ là các cách khác nhau để nhìn đúng ba thứ đó.1

Ý chính: máy chủ mạng chỉ là một chương trình đang ngồi chờ ở một “cửa” (cổng). Ai gõ cửa thì nó đẻ ra một người phụ việc để tiếp. Các công cụ trong chương giúp bạn nhìn xem cửa nào đang mở và ai đang gõ. Nhớ nhé: cổng là cửa, máy chủ là người ngồi chờ sau cửa.

The chapter's thesis: a network service is nothing mysterious — it is a user-space process listening on a port, calling fork() to spawn a child for each connection, and reading and writing through a socket; every diagnostic tool in the chapter (lsof, tcpdump, netcat, nmap) is just another way of looking at those same three things.1

Cụm khái niệm 01 Concept cluster 01

Dịch vụ TCP, một yêu cầu gõ tay, và hình dạng chung của máy chủ mạng Dịch vụ mạng thật ra là gì TCP services, a hand-typed request, and the common shape of a network server

Ward bắt đầu bằng thứ đơn giản nhất: dịch vụ TCP, theo ông, nằm trong số những dịch vụ dễ hiểu nhất vì chúng được dựng trên các luồng dữ liệu hai chiều đơn giản, không gián đoạn.1 Và cách tốt nhất để thấy chúng hoạt động là tự tay nói chuyện với một máy chủ web không mã hoá trên cổng TCP 80.12

Muốn hiểu mạng, đừng đọc lý thuyết trước — hãy tự tay gõ thử một câu vào máy chủ và xem nó trả lời. Đó chính là điều tác giả bảo bạn làm ngay ở trang đầu chương. Nhớ nhé: gõ thử một lần hơn đọc mười lần.

Ward starts with the simplest thing there is: TCP services, he says, are among the easiest to understand because they are built upon simple, uninterrupted two-way data streams.1 And the best way to see how they work is to talk directly to an unencrypted web server on TCP port 80.12

Định nghĩa. Một dịch vụ mạng ở tầng ứng dụng là một tiến trình không gian người dùng gắn với một cổng vận chuyển. Ward mô tả phần lớn máy chủ mạng “giống như các tiến trình nền khác trên hệ thống, chẳng hạn cron, chỉ khác là chúng tương tác với các cổng mạng”.1

Nói đơn giản. Dịch vụ mạng là một chương trình chạy ngầm, giống mấy chương trình hẹn giờ trong máy, chỉ khác là nó ngồi canh một cái cửa ra mạng. Nhớ nhé: chương trình ngầm + một cái cửa = dịch vụ mạng.

Definition. A network service at the application layer is a user-space process attached to a transport port. Ward describes most network servers as “like other server daemons on your system such as cron, except that they interact with network ports”.1

client → connect(host, port)
  server: listen() → accept()
    → fork() → worker
  listener vẫn tiếp tục lắng nghe

bên gọi → gõ cửa
  bên nghe → mở cửa
    → gọi người phụ việc
  người gác cửa vẫn đứng đó

client → connect(host, port)
  server: listen() → accept()
    → fork() → worker
  listener keeps listening

  1. talking to port 80

    Bài tập đầu tiên — gõ tay một yêu cầu HTTP Tự gõ một câu cho máy chủ web The first exercise — hand-typing an HTTP request

    Ward yêu cầu bạn chạy telnet example.org 80, rồi gõ hai dòng GET / HTTP/1.1 và Host: example.org, nhấn ENTER hai lần sau dòng cuối. Máy chủ sẽ trả về một đống HTML.1 Bài tập nhỏ này chứng minh đúng hai điều: máy ở xa có một tiến trình máy chủ web đang lắng nghe trên cổng TCP 80, và telnet chính là máy khách khởi tạo kết nối.1

    Bạn mở một chương trình nối tới máy chủ web, rồi gõ đúng hai dòng chữ. Máy chủ hiểu và gửi lại cả trang web dưới dạng chữ. Thế là bạn vừa làm công việc của trình duyệt bằng tay. Nhớ nhé: trình duyệt cũng chỉ gõ mấy dòng chữ như bạn thôi.

    Ward has you run telnet example.org 80, then type the two lines GET / HTTP/1.1 and Host: example.org, pressing ENTER twice after the last one. The server replies with a pile of HTML.1 The exercise demonstrates exactly two things: the remote host has a web server process listening on TCP port 80, and telnet was the client that initiated the connection.1

    Bạn gặp nó ở đâuWhere you meet it Mỗi lần bạn mở một trang web: trình duyệt làm đúng động tác này, chỉ nhanh hơn và có mã hoá. Mỗi lần bạn mở một trang web. Every time you open a web page: the browser performs exactly this exchange, only faster and encrypted.

    Vì sao phải nhấn CTRL-D

    Ward giải thích: vì hầu hết trang web cần vài yêu cầu mới tải xong, nên giữ kết nối mở là hợp lý — kết nối không tự đóng. Nhưng hành vi này thay đổi tuỳ máy chủ; nhiều máy chủ ngắt rất nhanh nếu không nhận được yêu cầu ngay sau khi kết nối mở.1

    Ghi chú về tuổi tác của giao thức

    Chính tác giả cảnh báo: HTTP 1.1, cũng như HTTP 1.0 trước nó, đã lộ tuổi; hiện đã có các giao thức mới hơn đang dùng như HTTP/2, QUIC và HTTP/3 đang nổi lên.1 Cú pháp yêu cầu HTTP/1.1 mà bạn gõ tay được chuẩn hoá trong RFC 9112.3

    Về bản thân telnet

    Ward lưu ý telnet ban đầu được làm ra để đăng nhập vào máy ở xa; chương trình máy khách có thể không được cài sẵn trên bản phân phối của bạn nhưng dễ cài thêm. Máy chủ đăng nhập telnet thì hoàn toàn không an toàn, còn máy khách telnet vẫn hữu ích để gỡ lỗi dịch vụ từ xa. Nó không làm việc với UDP hay bất kỳ tầng vận chuyển nào khác ngoài TCP.1 Giao thức Telnet gốc là RFC 854 và IANA gán nó cổng 23.42

  2. curl --trace-ascii

    Nhìn kỹ hơn — “header” và “data” chỉ là hư cấu của không gian người dùng Máy tính không biết đâu là “phần đầu thư” A closer look — “header” and “data” are a user-space fiction

    Bước kế tiếp của Ward là dùng curl --trace-ascii trace_file http://www.example.org/ để ghi lại chi tiết cuộc trao đổi.15 Trong tệp vết, bạn thấy curl gửi GET / HTTP/1.1 cùng vài dòng thông tin thêm rồi một dòng trống, và máy chủ đáp lại bằng HTTP/1.1 200 OK.1 Điểm chốt nằm ở chỗ khác: dù curl in ra “Recv header” rồi “Recv data” như thể đó là hai loại thông điệp khác nhau, không hề có khác biệt nào trong cách curl nói với hệ điều hành để lấy hai thứ đó, trong cách hệ điều hành xử lý chúng, hay trong cách mạng xử lý các gói bên dưới.1

    Một lá thư có phần đầu (tên người nhận) và phần thân (nội dung). Nhưng với người bưu tá thì tất cả chỉ là giấy — người đọc thư mới là người phân biệt. Mạng cũng vậy: nhân máy tính chỉ thấy byte, chương trình mới thấy “đầu thư” và “nội dung”. Nhớ nhé: mạng chỉ chở byte, ý nghĩa do chương trình tự đặt.

    Ward's next step is curl --trace-ascii trace_file http://www.example.org/ to record the details of the exchange.15 In the trace file you watch curl send GET / HTTP/1.1 plus some extra information and an empty line, and the server answer with HTTP/1.1 200 OK.1 The real point lies elsewhere: even though curl prints “Recv header” and then “Recv data” as if those were two different kinds of message, there is no difference in how curl talked to the operating system to retrieve them, in how the operating system handled them, or in how the network handled the packets underneath.1

    Bạn gặp nó ở đâuWhere you meet it Mỗi khi bạn gỡ lỗi một API và tự hỏi “lỗi nằm ở tầng nào” — câu trả lời gần như luôn nằm trong chương trình, không nằm ở mạng. Khi một trang web lỗi, thường là chương trình hiểu sai, không phải dây mạng đứt. Whenever you debug an API and ask “which layer is this in” — the answer is nearly always inside the program, not on the network.

    Cái dòng trống làm nên tất cả

    Ward chỉ đúng vào thời điểm chuyển: curl biết rằng cho tới lúc đó nó vẫn đang nhận header, nhưng khi nhận được một dòng trống — thứ đánh dấu kết thúc phần header trong HTTP — nó biết phải diễn giải mọi thứ tiếp theo là tài liệu được yêu cầu.1

    Đối xứng ở phía máy chủ

    Điều tương tự đúng với máy chủ khi gửi: hệ điều hành của máy chủ không phân biệt dữ liệu header với dữ liệu tài liệu; sự phân biệt xảy ra bên trong chương trình máy chủ ở không gian người dùng.1 Đây là một minh hoạ rất sạch cho luận điểm xuyên suốt sách: ranh giới ngữ nghĩa nằm trong phần mềm, không nằm trong hạ tầng.

  3. fork() and worker processes

    Một đặc điểm chung: máy chủ hoạt động như nhiều tiến trình Người gác cửa và những người phụ việc One common feature: servers operate as multiple processes

    Ward nêu một đặc điểm chung cho hầu hết máy chủ mạng: chúng thường hoạt động dưới dạng nhiều tiến trình. Ít nhất một tiến trình lắng nghe trên cổng mạng; khi nhận kết nối mới, tiến trình lắng nghe dùng fork() để tạo một tiến trình con chịu trách nhiệm cho kết nối đó. Tiến trình con — thường gọi là worker process — kết thúc khi kết nối đóng, còn tiến trình lắng nghe ban đầu vẫn tiếp tục lắng nghe.16

    Hãy tưởng tượng một quán ăn: có một người đứng ở cửa đón khách. Mỗi lần khách vào, người đó gọi một bạn phục vụ ra lo riêng bàn ấy, còn mình vẫn đứng ở cửa. Khách về thì bạn phục vụ nghỉ. Nhớ nhé: một người gác cửa, nhiều người phục vụ.

    Ward names a feature common to most network servers: they usually operate as multiple processes. At least one process listens on the network port; upon receiving a new incoming connection, the listening process uses fork() to create a child process responsible for that connection. The child — often called a worker process — terminates when the connection closes, while the original listening process keeps listening.16

    Bạn gặp nó ở đâuWhere you meet it Mỗi lần ps cho bạn thấy một hàng dài sshd hay nginx trông y hệt nhau — đó là một listener và một bầy worker. Khi bạn thấy nhiều dòng giống hệt nhau trong danh sách chương trình đang chạy. Every time ps shows you a long row of identical-looking sshd or nginx lines — that is one listener and a herd of workers.

    Hai ngoại lệ của mô hình

    Ward nêu rõ hai ngoại lệ. Thứ nhất: gọi fork() tốn đáng kể tài nguyên hệ thống, nên các máy chủ TCP hiệu năng cao như máy chủ web Apache có thể tạo sẵn một số tiến trình worker ngay khi khởi động để sẵn sàng phục vụ. Thứ hai: máy chủ nhận gói UDP hoàn toàn không cần fork(), vì chúng không có kết nối nào để lắng nghe — chúng chỉ nhận dữ liệu và phản ứng.17

    Danh mục máy chủ mà ông liệt kê

    Ông liệt kê các máy chủ bạn có thể gặp đang chạy: httpd, apache, apache2, nginx (máy chủ web); sshd (secure shell daemon); postfix, qmail, sendmail (máy chủ thư); cupsd (máy chủ in); nfsd, mountd (hệ thống tệp mạng); smbd, nmbd (chia sẻ tệp kiểu Windows); và rpcbind (dịch vụ portmap cho RPC).1

    Một ví dụ đã gặp ở Chương 7

    Ông nhắc lại rằng syslogd — đã bàn ở Chương 7 — chấp nhận gói UDP trên cổng 514 khi được khởi động với tuỳ chọn -r.1 IANA gán syslog cổng UDP 514, với RFC 5426 là tài liệu tham chiếu ghi trong sổ đăng ký.2

Cụm khái niệm 02 Concept cluster 02

SSH — máy chủ mẫu mực, khoá công khai, và những siêu máy chủ đã lùi vào dĩ vãng SSH: đăng nhập từ xa bằng chìa khoá SSH — the exemplary server, public keys, and the superservers that faded away

Ward chọn SSH làm ca nghiên cứu vì nó là chuẩn de facto cho truy cập từ xa tới một máy Unix.1 SSH được thiết kế để cho phép đăng nhập shell an toàn, thực thi chương trình từ xa, chia sẻ tệp đơn giản và hơn thế — thay thế các hệ thống truy cập từ xa cũ và không an toàn là telnet và rlogin, bằng mật mã khoá công khai để xác thực và các thuật toán mã hoá đơn giản hơn cho dữ liệu phiên.18

SSH là cách an toàn để ngồi ở máy này mà điều khiển máy kia. Ngày xưa người ta dùng cách khác, nhưng những cách đó gửi mật khẩu đi dưới dạng chữ thường, ai chặn được là đọc được. SSH khoá kín mọi thứ lại. Nhớ nhé: muốn điều khiển máy ở xa thì dùng SSH, đừng dùng thứ gì cũ hơn.

Ward picks SSH as the case study because it is the de facto standard for remote access to a Unix machine.1 SSH is designed to allow 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.18

Ông đặt SSH trong bối cảnh thực tế: hầu hết nhà cung cấp dịch vụ internet và nhà cung cấp đám mây yêu cầu SSH để truy cập shell tới dịch vụ của họ, và nhiều thiết bị mạng chạy Linux — chẳng hạn thiết bị lưu trữ gắn mạng (NAS) — cũng cung cấp truy cập qua SSH.1 OpenSSH là hiện thực SSH miễn phí phổ biến cho Unix và gần như mọi bản phân phối Linux đều cài sẵn; chương trình máy khách là ssh, máy chủ là sshd.19

Định nghĩa. Mật mã khoá công khai: cho tới thập niên 1970, các thuật toán mã hoá đều đối xứng, đòi người gửi và người nhận phải có cùng một khoá — càng nhiều người giữ khoá thì càng nhiều cơ hội để nó bị lộ. Với mật mã khoá công khai thì có hai khoá: công khai và riêng tư. Khoá công khai có thể mã hoá một thông điệp nhưng không giải mã được nó, nên ai có nó cũng không sao; chỉ khoá riêng tư mới giải mã được.1

Nói đơn giản. Hãy nghĩ tới một cái hòm thư có khe bỏ thư. Ai cũng bỏ thư vào được (khoá công khai), nhưng chỉ người có chìa mở hòm mới đọc được (khoá riêng tư). Nhớ nhé: khoá công khai để khoá lại, khoá riêng tư để mở ra.

Definition. Public-key cryptography: until the 1970s, encryption algorithms were symmetric, requiring sender and recipient to hold the same key — the more people who had it, the more chances it had to be compromised. With public-key cryptography there are two keys, public and private. The public key can encrypt a message but not decrypt it, so it doesn't matter who has it; only the private key can decrypt.1

/etc/ssh/sshd_config ← máy chủ
/etc/ssh/ssh_config ← máy khách
ssh_host_*_key ← khoá riêng tư
ssh_host_*_key.pub ← khoá công khai
~/.ssh/known_hosts ← khoá của máy khác

sshd_config → cho bên nghe
ssh_config → cho bên gọi
*_key → chìa riêng
*_key.pub → ổ khoá công khai
known_hosts → sổ ghi nhớ

/etc/ssh/sshd_config ← the server
/etc/ssh/ssh_config ← the client
ssh_host_*_key ← private key
ssh_host_*_key.pub ← public key
~/.ssh/known_hosts ← other hosts' keys

  1. sshd_config

    sshd_config — sáu tham số đáng nhớ nhất Tệp cài đặt của máy chủ SSH sshd_config — the six parameters worth remembering

    Chạy sshd cần một tệp cấu hình và các khoá máy chủ; hầu hết bản phân phối giữ cấu hình trong thư mục /etc/ssh.1 Ward cảnh báo một chi tiết dễ vấp: tên tệp cấu hình máy chủ sshd_config rất dễ nhầm với tệp thiết lập máy khách ssh_config.1 Tệp gồm các cặp khoá–giá trị; các dòng bắt đầu bằng # là chú thích, và nhiều chú thích trong sshd_config chính là để ghi lại giá trị mặc định.110

    Máy chủ SSH đọc một tệp cài đặt để biết phải làm gì. Trong tệp đó, mỗi dòng là một câu lệnh ngắn kiểu “tên: giá trị”. Dòng nào có dấu thăng ở đầu thì máy bỏ qua — đó là ghi chú cho người đọc. Nhớ nhé: dấu thăng ở đầu dòng nghĩa là “đọc cho biết thôi”.

    Running sshd requires a configuration file and host keys; most distributions keep the configuration in the /etc/ssh directory.1 Ward flags an easy trap: the server configuration filename sshd_config is easy to confuse with the client's ssh_config setup file.1 The file consists of key-value pairs; lines beginning with # are comments, and many comments in sshd_config exist precisely to record default values.110

    Bạn gặp nó ở đâuWhere you meet it Lần đầu bạn dựng một máy chủ trên đám mây: PermitRootLogin và X11Forwarding là hai dòng bạn sẽ phải quyết định. Khi bạn thuê một máy chủ và phải chọn “cho phép hay không cho phép”. The first time you stand up a cloud server: PermitRootLogin and X11Forwarding are two lines you will have to decide on.

    Sáu tham số Ward gọi là quan trọng nhất

    HostKey file — dùng file làm khoá máy chủ. PermitRootLogin value — cho phép siêu người dùng đăng nhập bằng SSH nếu đặt yes; đặt no để ngăn. LogLevel level — ghi log ở mức syslog level (mặc định INFO). SyslogFacility name — ghi log với facility name (mặc định AUTH). X11Forwarding value — bật đường hầm cho máy khách X Window System nếu đặt yes. XAuthLocation path — chỉ vị trí tiện ích xauth; không có đường dẫn này thì đường hầm X sẽ không hoạt động.110

    Sách và bản OpenSSH hiện nay lệch nhau ở đâu

    Sách viết rằng PermitRootLogin cho phép root đăng nhập “nếu giá trị được đặt là yes”, và mô tả nó như một công tắc hai nấc.1 Trang man sshd_config(5) hiện hành liệt kê bốn giá trị — yes, prohibit-password, forced-commands-only, no — với mặc định là prohibit-password; LogLevel mặc định INFO và SyslogFacility mặc định AUTH thì khớp với sách, còn X11Forwarding mặc định là no.10 Trong bài này, phần thân theo cách diễn đạt của sách; ghi chú này nêu biến thể và nguồn của nó.

    Đường hầm là gì

    Ward định nghĩa: tunneling là quá trình đóng gói và vận chuyển một kết nối mạng bên trong một kết nối mạng khác. Ưu điểm của việc dùng SSH để tạo đường hầm cho kết nối X Window System là SSH tự thiết lập môi trường hiển thị giúp bạn, và nó mã hoá dữ liệu X bên trong đường hầm.19

  2. ssh-keygen

    Khoá máy chủ — thứ bạn hiếm khi tạo, nhưng phải biết nằm ở đâu Chìa khoá của máy chủ Host keys — something you rarely create, but must know where to find

    OpenSSH có vài bộ khoá máy chủ; mỗi bộ gồm một khoá công khai (đuôi .pub) và một khoá riêng tư (không có đuôi).1 Ward kèm một cảnh báo rất dứt khoát: đừng để ai nhìn thấy khoá riêng tư, kể cả trên máy của chính bạn, vì nếu ai đó lấy được nó, bạn đang gặp rủi ro từ kẻ xâm nhập.1 Thông thường bạn không cần tự tạo khoá vì trình cài đặt OpenSSH hoặc script cài đặt của bản phân phối sẽ làm hộ.1

    Máy chủ có một bộ chìa: một nửa đưa cho mọi người xem, một nửa giữ kín tuyệt đối. Nửa giữ kín mà lộ ra là hỏng hết. Thường thì máy tự làm ra bộ chìa này khi cài, bạn không phải làm gì. Nhớ nhé: chìa riêng là chìa riêng — không khoe, không sao chép lung tung.

    OpenSSH has several sets of host keys; each set has a public key (with a .pub extension) and a private key (with no extension).1 Ward attaches a blunt warning: do not let anyone see a private key, even on your own system, because if someone obtains it you're at risk from intruders.1 Normally you won't need to create keys because the OpenSSH installer or your distribution's installation script does it for you.1

    Bạn gặp nó ở đâuWhere you meet it Khi thay máy: Ward gợi ý nhập khoá từ máy cũ sang máy mới để người dùng không bị cảnh báo lệch khoá khi kết nối.1 Khi bạn đổi máy mới mà không muốn ai bị báo động nhầm. When replacing a machine: Ward suggests importing the key files from the old machine so users don't get key mismatches on the new one.1

    Lệnh tạo khoá, đúng như sách in

    Để tạo khoá giao thức SSH phiên bản 2, sách dùng ssh-keygen đi kèm OpenSSH: ssh-keygen -t rsa -N '' -f /etc/ssh/ssh_host_rsa_key và ssh-keygen -t dsa -N '' -f /etc/ssh/ssh_host_dsa_key.1 Lý do duy nhất khiến bạn cần biết cách làm, theo ông, là nếu bạn định dùng các chương trình như ssh-agent — thứ cung cấp dịch vụ xác thực mà không cần mật khẩu.111

    RSA và DSA — sách nói gì, hiện trạng nói gì

    Bảng 10-1 của sách liệt kê bốn tên tệp khoá: ssh_host_rsa_key (RSA riêng tư), ssh_host_rsa_key.pub (RSA công khai), ssh_host_dsa_key (DSA riêng tư), ssh_host_dsa_key.pub (DSA công khai), và mô tả “SSH phiên bản 2 có khoá RSA và DSA”.1 Từ sau khi sách ra (2021), OpenSSH đã đi tiếp: bản 10.0 (phát hành 2025-04-09) gỡ bỏ hoàn toàn hỗ trợ thuật toán chữ ký DSA, hoàn tất quá trình khai tử bắt đầu từ 2015 khi DSA bị tắt theo mặc định.12 Trang man hiện hành liệt kê mặc định HostKey là ssh_host_ecdsa_key, ssh_host_ed25519_key và ssh_host_rsa_key — không còn DSA.10 Phần thân bài giữ nguyên cách trình bày của sách; ghi chú này nêu biến thể và nguồn.

    ssh_known_hosts

    Máy chủ và máy khách SSH còn dùng một tệp khoá tên ssh_known_hosts để lưu khoá công khai của các máy khác. Nếu bạn định dùng xác thực dựa trên danh tính của máy khách từ xa, tệp ssh_known_hosts của máy chủ phải chứa khoá máy công khai của tất cả máy khách được tin cậy.1

  3. host key verification failed

    Cảnh báo lệch khoá — lỗi thường gặp nhất của máy khách SSH Khi máy hét lên “KHOÁ ĐÃ THAY ĐỔI!” The key mismatch warning — the commonest SSH client problem

    Theo Ward, vấn đề thường gặp nhất khi dùng máy khách SSH xảy ra khi một khoá công khai trong ssh_known_hosts hoặc .ssh/known_hosts của bạn không khớp với khoá trên máy ở xa.1 Khi đó bạn nhận một khối cảnh báo đóng khung dấu @, mở đầu bằng “WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!” và nhắc tới khả năng bị tấn công người-đứng-giữa.1 Điểm thực dụng: thông điệp đó chỉ cho bạn đúng số dòng chứa khoá sai trong tệp known_hosts.1

    Máy tính của bạn có một cuốn sổ ghi “máy kia trông như thế này”. Nếu lần sau máy kia trông khác đi, máy bạn sẽ hét lên cảnh báo. Thường là vì người quản trị máy kia đổi máy, chứ không phải có kẻ xấu. Nhớ nhé: máy hét lên là điều tốt — nó đang bảo vệ bạn.

    According to Ward, the most frequent problem with SSH clients occurs when a public key in your ssh_known_hosts or .ssh/known_hosts file does not match the key on the remote host.1 You then get a block of warning framed in @ characters, opening with “WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!” and raising the possibility of a man-in-the-middle attack.1 The practical point: the message tells you the exact line number of the offending key in the known_hosts file.1

    Bạn gặp nó ở đâuWhere you meet it Sau mỗi lần nâng cấp phần cứng hoặc dựng lại máy chủ đám mây — Ward nói đây là nguyên nhân thường thấy.1 Sau khi ai đó đổi máy chủ sang máy mới. After every hardware upgrade or cloud server rebuild — Ward names this as the usual cause.1

    Cách xử lý mà sách đề nghị

    Thường thì điều này chỉ có nghĩa là quản trị viên của máy ở xa đã đổi khoá, nhưng “không bao giờ thừa” khi hỏi lại quản trị viên nếu bạn không chắc. Nếu bạn không nghi ngờ điều mờ ám, chỉ cần xoá dòng bị nêu tên hoặc thay nó bằng khoá công khai đúng.1

    Vì sao cơ chế này tồn tại

    Ward cũng thẳng thắn về nhược điểm của SSH: để thiết lập một kết nối SSH, bạn cần khoá công khai của máy ở xa, và bạn không nhất thiết nhận được nó theo một cách an toàn — dù bạn có thể kiểm tra thủ công để chắc mình không bị giả mạo.1 Đó chính là lý do known_hosts phải tồn tại và phải kêu to khi có gì đổi.8

  4. scp, sftp, fail2ban

    Quanh SSH: chuyển tệp, chặn dò mật khẩu, và máy khách ngoài Unix Những thứ đi kèm SSH Around SSH: file transfer, brute-force blocking, and non-Unix clients

    OpenSSH kèm theo hai chương trình chuyển tệp là scp và sftp, được làm ra để thay thế các chương trình cũ và không an toàn là rcp và ftp.113 scp hoạt động giống lệnh cp: scp user@host:file . để lấy về, scp file user@host:dir để gửi đi, và thậm chí scp user1@host1:file user2@host2:dir để chép từ máy từ xa này sang máy từ xa khác.1 Còn sftp hoạt động như máy khách ftp dòng lệnh đã lỗi thời, dùng lệnh get và put.1

    Ngoài việc đăng nhập, SSH còn giúp bạn chép tệp qua lại giữa hai máy — an toàn, không lo bị đọc trộm. Có hai lệnh: một lệnh giống lệnh chép tệp bình thường, một lệnh cho bạn đi lại trong thư mục máy kia rồi lấy hoặc đặt từng tệp. Nhớ nhé: chép tệp qua mạng thì dùng SSH, đừng dùng cách cũ.

    OpenSSH includes the file transfer programs scp and sftp, intended as replacements for the older, insecure rcp and ftp.113 scp works like the cp command: scp user@host:file . to pull, scp file user@host:dir to push, and even scp user1@host1:file user2@host2:dir from one remote host to a second.1 sftp works like the obsolete command-line ftp client, using get and put commands.1

    Bạn gặp nó ở đâuWhere you meet it Ward gợi ý: nếu bạn thường xuyên chuyển số lượng lớn tệp và cần nhiều tính năng hơn scp/sftp, hãy xem rsync ở Chương 12.1 Khi bạn cần chép rất nhiều tệp một lúc. Ward suggests: if you frequently transfer large numbers of files and need more than scp/sftp offer, look at rsync in Chapter 12.1

    fail2ban — phản ứng với “cơn mưa” thử mật khẩu

    Ward nói thẳng: nếu bạn dựng một máy chủ SSH và mở nó ra internet, bạn sẽ nhanh chóng phát hiện các nỗ lực xâm nhập liên tục. Những đợt dò mật khẩu kiểu vét cạn đó sẽ không thành công nếu hệ thống của bạn được cấu hình đúng và bạn không chọn mật khẩu ngớ ngẩn — nhưng chúng gây khó chịu, tiêu tốn thời gian CPU và làm rối log.1 Gói fail2ban, theo sách là cách phổ biến nhất tại thời điểm viết, đơn giản là một script theo dõi log: thấy một số lần yêu cầu thất bại nhất định từ một máy trong một khung thời gian nhất định, nó dùng iptables tạo luật chặn lưu lượng từ máy đó, rồi gỡ luật sau một khoảng thời gian.114

    Hai chế độ khởi động của sshd

    Ward phân biệt hai chế độ: độc lập (standalone) và theo yêu cầu (on-demand). Máy chủ độc lập phổ biến hơn nhiều, và chỉ đơn giản là chạy sshd với quyền root; tiến trình sshd ghi PID của nó vào /var/run/sshd.pid.1 systemd có thể khởi động sshd theo yêu cầu qua một socket unit, nhưng ông khuyên đây thường không phải ý hay, vì máy chủ thỉnh thoảng cần sinh tệp khoá và việc đó có thể mất rất lâu.115 Trên Fedora, sshd được cài sẵn nhưng tắt; bật kèm khởi động bằng systemctl enable sshd, bật ngay bằng systemctl start sshd.1

    Máy khách ngoài Unix

    Có máy khách SSH cho mọi hệ điều hành phổ biến. Ward đề xuất PuTTY như một máy khách Windows tốt và cơ bản, có kèm chương trình chép tệp an toàn; còn macOS vốn dựa trên Unix nên đã có sẵn OpenSSH.1

  5. inetd / xinetd

    Siêu máy chủ thời tiền systemd — và vì sao bạn vẫn nên biết Người gác cửa chung cho nhiều dịch vụ The pre-systemd superservers — and why you should still know them

    Trước khi systemd và các socket unit trở nên phổ biến, có một nhóm máy chủ cung cấp cách chuẩn để dựng một dịch vụ mạng.1 Lý do tồn tại rất rõ: nhiều dịch vụ mạng nhỏ giống nhau đến mức làm máy chủ độc lập cho từng dịch vụ là kém hiệu quả — mỗi máy chủ đều phải tự cấu hình lắng nghe cổng, kiểm soát truy cập và cấu hình cổng, những động tác giống hệt nhau; chỉ khi máy chủ chấp nhận một kết nối thì cách xử lý mới khác nhau.1

    Ngày xưa, thay vì mỗi dịch vụ nuôi một người gác cửa riêng, người ta thuê một người gác cửa chung cho cả toà nhà. Ai gõ cửa nào thì người đó gọi đúng dịch vụ ra tiếp. Nhớ nhé: một người gác cửa chung thì đỡ tốn hơn nhiều người gác cửa riêng.

    Before systemd and its socket units became widespread, a handful of servers provided a standard means of building a network service.1 The reason is plain: many minor network services are so alike in their connection requirements that implementing a standalone server for each is inefficient — every server must separately configure port listening, access control and port configuration, all done the same way; only when a server accepts a connection is communication handled differently.1

    Bạn gặp nó ở đâuWhere you meet it Trên một hệ thống cũ hoặc một hệ thống không dùng systemd — Ward nói đó chính là nơi bạn vẫn có thể bắt gặp xinetd.1 Trên những máy chủ đời cũ. On an older system, or one that doesn't use systemd — Ward says that is exactly where you may still meet xinetd.1

    inetd hoạt động ra sao

    Cách truyền thống để đơn giản hoá việc dùng máy chủ là dùng daemon inetd — một kiểu siêu máy chủ được thiết kế để chuẩn hoá việc truy cập cổng mạng và giao diện giữa chương trình máy chủ với cổng mạng. Sau khi bạn khởi động inetd, nó đọc tệp cấu hình rồi lắng nghe trên các cổng mạng được định nghĩa trong đó; khi có kết nối mới đến, inetd gắn một tiến trình mới khởi động vào kết nối ấy.1

    xinetd và số phận của nó

    Một phiên bản mới hơn của inetd tên là xinetd cho cấu hình dễ hơn và kiểm soát truy cập tốt hơn, nhưng — theo sách — xinetd gần như đã bị loại bỏ hoàn toàn để nhường chỗ cho systemd.116

    TCP wrappers — một lớp lịch sử nữa

    Trước khi các tường lửa tầng thấp như iptables trở nên phổ biến, nhiều quản trị viên dùng thư viện và daemon TCP wrapper để kiểm soát truy cập dịch vụ mạng: inetd chạy chương trình tcpd, chương trình này xem kết nối đến cùng các danh sách kiểm soát truy cập trong /etc/hosts.allow và /etc/hosts.deny, ghi log kết nối, và nếu thấy ổn thì bàn giao cho chương trình dịch vụ cuối. Ward nói bạn có thể còn gặp hệ thống dùng TCP wrapper, nhưng sách không đi sâu vì nó phần lớn đã không còn được dùng.1

Cụm khái niệm 03 Concept cluster 03

Bốn công cụ chẩn đoán, và một giao thức “không chịu chết” Bốn cái kính lúp để soi mạng Four diagnostic tools, and one protocol that refuses to die

Ward đặt bốn công cụ cạnh nhau theo một trật tự có chủ ý: lsof hỏi “ai đang giữ cổng nào”, tcpdump hỏi “cái gì đang đi qua dây”, netcat hỏi “tôi tự tay nối thử được không”, và nmap hỏi “nhìn từ bên ngoài thì máy này mở những gì”.1 Trước đó ông nhắc lại netstat từ Chương 9 như công cụ gỡ lỗi dịch vụ mạng cơ bản.117

Có bốn cách nhìn vào mạng: xem ai đang giữ cửa nào; xem cái gì đang chạy qua dây; tự mình gõ thử một cái cửa; và đứng từ ngoài đếm xem nhà này mở mấy cửa. Nhớ nhé: bốn câu hỏi khác nhau cần bốn công cụ khác nhau.

Ward lines up four tools in a deliberate order: lsof asks “who is holding which port”, tcpdump asks “what is crossing the wire”, netcat asks “can I connect by hand”, and nmap asks “seen from outside, what does this machine have open”.1 Before them he recalls netstat from Chapter 9 as the basic network service debugging tool.117

Định nghĩa. Chế độ hỗn tạp (promiscuous mode): bình thường hệ thống của bạn không bận tâm tới lưu lượng mạng không gửi tới một trong các địa chỉ MAC của nó. Nếu bạn cần thấy chính xác cái gì đang đi qua mạng, tcpdump đặt card mạng vào chế độ hỗn tạp và báo cáo mọi gói đi ngang.118

Nói đơn giản. Bình thường máy chỉ nghe thư gửi cho mình. Ở chế độ hỗn tạp, nó nghe hết mọi lá thư đi qua trước cửa. Nhớ nhé: nghe hết thì thấy nhiều, nhưng chỉ nghe ở nơi bạn được phép.

Definition. Promiscuous mode: your system normally doesn't bother with network traffic that isn't addressed to one of its MAC addresses. If you need to see exactly what's crossing your network, tcpdump puts the network interface card into promiscuous mode and reports on every packet that comes across.118

lsof -n -i ← ai giữ cổng
lsof -iTCP:443 ← lọc theo cổng
lsof -iTCP -sTCP:LISTEN
tcpdump udp or port 80 or port 443
netcat -l port_number
nmap 10.1.2.2

lsof -i → ai đang giữ cửa
tcpdump → nghe dây
netcat → gõ cửa thử
nmap → đếm cửa từ ngoài

lsof -n -i ← who holds a port
lsof -iTCP:443 ← filter by port
lsof -iTCP -sTCP:LISTEN
tcpdump udp or port 80 or port 443
netcat -l port_number
nmap 10.1.2.2

  1. lsof -i

    lsof — từ “tệp đang mở” sang “cổng đang mở” lsof: ai đang giữ cửa nào lsof — from “open files” to “open ports”

    Ward nhắc lại từ Chương 8: lsof không chỉ theo dõi tệp đang mở mà còn liệt kê các chương trình đang dùng hoặc lắng nghe các cổng. Chạy lsof -i để có danh sách đầy đủ.119 Một chi tiết quan trọng về quyền: khi bạn chạy lệnh này với tư cách người dùng thường, nó chỉ hiện các tiến trình của chính người dùng đó; chạy với quyền root mới thấy toàn cảnh.1

    Có một lệnh cho bạn xem toàn bộ danh sách “ai đang giữ cửa nào”. Nếu bạn là người dùng thường, bạn chỉ thấy phần của mình; muốn thấy hết thì phải là người quản trị. Nhớ nhé: thấy được bao nhiêu phụ thuộc vào bạn là ai.

    Ward recalls from Chapter 8 that lsof not only tracks open files but also lists the programs currently using or listening to ports. Run lsof -i for a complete list.119 An important permission detail: run as a regular user it shows only that user's processes; run as root it shows the whole picture.1

    Bạn gặp nó ở đâuWhere you meet it Khi một chương trình báo “địa chỉ đang được dùng” — lsof -i:port cho bạn biết đúng tiến trình nào đang giữ. Khi máy báo “cổng này có người dùng rồi”. When a program reports “address already in use” — lsof -i:port names the exact process holding it.

    Cú pháp lọc đầy đủ

    Cú pháp đầy đủ là lsof -iprotocol@host:port, trong đó protocol, @host và :port đều tuỳ chọn và sẽ lọc đầu ra tương ứng.1 Ví dụ của sách: lsof -iTCP:443 cho các kết nối trên cổng TCP 443, tức cổng HTTPS.12 Lọc theo phiên bản IP bằng -i4 hoặc -i6, và có thể ghép, ví dụ -i6TCP:443. Bạn cũng có thể dùng tên dịch vụ trong /etc/services thay cho số, như -iTCP:ssh.120

    Lọc theo trạng thái kết nối

    Bộ lọc tiện nhất, theo Ward, là trạng thái kết nối: lsof -iTCP -sTCP:LISTEN chỉ hiện các tiến trình đang lắng nghe trên cổng TCP, cho bạn “cái nhìn tổng quan tốt về các tiến trình máy chủ mạng đang chạy trên hệ thống”.1 Nhưng ông cảnh báo: vì máy chủ UDP không lắng nghe và không có kết nối, bạn phải dùng -iUDP để thấy cả máy khách lẫn máy chủ UDP.1

    Tắt phân giải tên cho nhanh

    lsof giống netstat ở chỗ nó cố phân giải ngược mọi địa chỉ IP tìm được thành tên máy, khiến đầu ra chậm. Dùng -n để tắt phân giải tên, và -P để tắt tra cứu tên cổng trong /etc/services.119

  2. tcpdump

    tcpdump — primitive, operator, và một giới hạn đạo đức tcpdump: nghe xem cái gì chạy qua dây tcpdump — primitives, operators, and an ethical limit

    Gõ tcpdump không tham số sẽ cho đầu ra gồm mọi gói đi ngang — ví dụ của sách bắt được một yêu cầu ARP rồi cả một kết nối web.1 Muốn cụ thể hơn thì thêm bộ lọc: bạn có thể lọc theo máy nguồn và đích, theo mạng, theo địa chỉ Ethernet, theo giao thức ở nhiều tầng khác nhau trong mô hình mạng, và nhiều thứ nữa.1 Trong số các giao thức gói mà tcpdump nhận biết, Ward liệt kê ARP, RARP, ICMP, TCP, UDP, IP, IPv6, AppleTalk và IPX.118

    Có một công cụ nghe được mọi thứ chạy qua dây mạng. Nó nói rất nhiều, nên bạn phải bảo nó “chỉ nghe loại này thôi”. Và quan trọng nhất: chỉ nghe ở mạng của chính bạn. Nhớ nhé: nghe lén mạng người khác là sai — chỉ nghe mạng của mình.

    Typing tcpdump with no arguments produces output covering every packet that crosses — the book's example catches an ARP request and then a whole web connection.1 To be more specific, add filters: you can filter on source and destination hosts, networks, Ethernet addresses, protocols at many different layers of the network model, and much more.1 Among the packet protocols tcpdump recognises, Ward lists ARP, RARP, ICMP, TCP, UDP, IP, IPv6, AppleTalk and IPX.118

    Bạn gặp nó ở đâuWhere you meet it Khi một dịch vụ “im lặng” và bạn cần biết gói có thật sự tới nơi hay không. Ward gợi ý nếu bạn phải bắt gói nhiều, hãy cân nhắc một lựa chọn giao diện đồ hoạ thay cho tcpdump, chẳng hạn Wireshark.1 Khi bạn không biết thư có đến nơi hay không. When a service goes silent and you need to know whether packets actually arrive. Ward suggests that if you do a lot of packet sniffing, consider a GUI alternative to tcpdump such as Wireshark.1

    Primitive — bảng 10-3 của sách

    Trong các ví dụ, tcp, udp và port 80 là những phần tử cơ bản của bộ lọc, gọi là primitive. Bảng 10-3 liệt kê những primitive quan trọng nhất: tcp (gói TCP), udp (gói UDP), ip (gói IPv4), ip6 (gói IPv6), port port (gói TCP và/hoặc UDP đi tới hoặc đi từ cổng đó), host host (gói tới hoặc từ máy đó), net network (gói tới hoặc từ mạng đó).121

    Operator

    Từ khoá or chỉ rằng điều kiện bên trái hoặc bên phải đúng là gói được qua bộ lọc; tương tự, and đòi cả hai điều kiện cùng đúng.1 tcpdump dùng được nhiều toán tử (kể cả !) và bạn có thể nhóm chúng trong ngoặc. Nếu bạn định làm việc nghiêm túc với tcpdump, Ward yêu cầu đọc trang man pcap-filter(7), đặc biệt là phần mô tả các primitive.121

    Giới hạn mà tác giả đặt ra

    Ward viết một ghi chú cảnh báo rõ ràng: đầu ra tcpdump trong ví dụ chỉ gồm thông tin header TCP (tầng vận chuyển) và IP (tầng internet), nhưng bạn có thể bảo tcpdump in toàn bộ nội dung gói. Dù ngày nay hầu hết lưu lượng mạng quan trọng đã được mã hoá qua TLS, bạn không nên dò xét các mạng trừ khi bạn sở hữu chúng hoặc được phép.122

  3. netcat / nc

    netcat — con dao Thuỵ Sĩ khi telnet không đủ netcat: tự tay nối thử netcat — the Swiss army knife when telnet isn't enough

    Nếu bạn cần linh hoạt hơn so với telnet host port, Ward giới thiệu netcat (hay nc): nó nối được tới cổng TCP/UDP ở xa, chỉ định cổng cục bộ, lắng nghe trên cổng, quét cổng, chuyển hướng vào/ra chuẩn tới và từ kết nối mạng, và nhiều nữa.123 Mở một kết nối TCP: netcat host port. Lắng nghe trên một cổng: netcat -l port_number.1

    Đây là công cụ cho bạn tự tay nối hai đầu mạng lại với nhau — một đầu gọi, một đầu nghe. Gõ gì ở đầu này thì hiện ở đầu kia. Nhớ nhé: muốn hiểu mạng, hãy tự làm một đầu dây.

    If you need more flexibility than telnet host port allows, Ward introduces netcat (or nc): it 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.123 Open a TCP connection with netcat host port; listen on a port with netcat -l port_number.1

    Bạn gặp nó ở đâuWhere you meet it Khi bạn muốn biết một cổng có thật sự mở từ phía bạn hay không, trước khi đổ lỗi cho ứng dụng. Khi bạn muốn thử xem cửa có mở không. When you want to know whether a port is genuinely reachable from your side, before blaming the application.

    Ba lưu ý của Ward về hành vi netcat

    Thứ nhất: mặc định gần như không có đầu ra gỡ lỗi — nếu hỏng, netcat hỏng im lặng, dù nó có đặt mã thoát thích hợp; thêm -v (“verbose”) nếu bạn muốn biết thêm. Thứ hai: máy khách netcat mặc định thử cả IPv4 lẫn IPv6, nhưng ở chế độ máy chủ thì mặc định IPv4; ép giao thức bằng -4 hoặc -6. Thứ ba: tuỳ chọn -u chỉ định UDP thay cho TCP.123

    Một cái bẫy về dòng lệnh

    netcat kết thúc khi phía bên kia đóng kết nối, điều này có thể gây bối rối nếu bạn chuyển hướng đầu vào chuẩn vào netcat, vì bạn có thể không lấy lại được dấu nhắc sau khi gửi dữ liệu — khác với gần như mọi đường ống lệnh khác. Bạn có thể kết thúc kết nối bất cứ lúc nào bằng CTRL-C.1

  4. nmap

    Quét cổng — và lời xin phép mà tác giả bắt buộc Đếm cửa từ bên ngoài (phải xin phép) Port scanning — and the permission the author insists on

    Đôi khi bạn không biết các máy trên mạng của mình đang cung cấp dịch vụ gì, hay thậm chí địa chỉ IP nào đang được dùng. Chương trình Network Mapper (Nmap) quét mọi cổng trên một máy hoặc một mạng máy để tìm cổng mở và liệt kê chúng.124 Ward kèm một cảnh báo không thể rõ hơn: nếu người khác kiểm soát mạng mà bạn muốn quét, hãy xin phép — quản trị viên mạng theo dõi các đợt quét cổng và thường sẽ chặn truy cập với các máy chạy chúng.125

    Có một công cụ đứng từ ngoài đếm xem một máy mở những cửa nào. Nhưng nhớ: chỉ đếm cửa nhà mình, hoặc nhà mà chủ nhà đã đồng ý. Đếm cửa nhà người lạ là việc không nên làm. Nhớ nhé: xin phép trước, quét sau.

    Sometimes you don't know what services the machines on your networks offer, 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 lists what it finds.124 Ward attaches an unmistakable warning: if someone else controls the network you want to scan, ask for permission — network administrators watch for port scans and usually disable access to the machines that run them.125

    Bạn gặp nó ở đâuWhere you meet it Khi kiểm tra tường lửa của chính mình: Ward khuyên chạy quét từ ít nhất hai điểm — từ máy của bạn và từ một máy khác, có thể nằm ngoài mạng cục bộ — để có cái nhìn tổng quan về thứ tường lửa đang chặn.1 Khi bạn muốn biết tường lửa nhà mình đang chặn những gì. When checking your own firewall: Ward advises scanning from at least two points — your own machine and another one, possibly outside your local network — for an overview of what the firewall blocks.1

    Đọc kết quả quét mẫu

    Trong đầu ra mẫu của sách (nmap 10.1.2.2), nhiều dịch vụ hiện ra là mở, và Ward nhận xét rằng phần lớn trong số đó không được bật theo mặc định trên hầu hết bản phân phối; thực ra cái duy nhất ở đây thường bật sẵn là cổng 111, cổng của rpcbind.1 IANA gán cổng 111 cho sunrpc, “SUN Remote Procedure Call”.2

    Quét qua IPv6

    Nmap cũng quét được cổng trên IPv6 nếu bạn thêm tuỳ chọn -6. Ward chỉ ra một công dụng thực tế: đây là cách tiện để nhận diện các dịch vụ không hỗ trợ IPv6.124

  5. RPC / rpcbind

    Lời gọi thủ tục từ xa — “một trong những giao thức không chịu chết” RPC: gọi hàm ở máy khác Remote procedure calls — “one of those protocols that just doesn't want to die”

    RPC là viết tắt của remote procedure call, một hệ thống nằm ở phần dưới của tầng ứng dụng, được thiết kế để lập trình viên dễ dựng các ứng dụng mạng máy khách/máy chủ, nơi một chương trình máy khách gọi các hàm thực thi trên một máy chủ ở xa.126 Mỗi loại chương trình máy chủ từ xa được nhận diện bằng một số hiệu chương trình được gán.1 Các hiện thực RPC dùng giao thức vận chuyển như TCP và UDP, và cần một dịch vụ trung gian đặc biệt để ánh xạ số hiệu chương trình sang cổng TCP và UDP — máy chủ đó tên là rpcbind, và nó phải chạy trên bất kỳ máy nào muốn dùng dịch vụ RPC.127

    RPC nghĩa là: chương trình ở máy này gọi một việc làm ở máy kia, y như gọi một hàm trong chính chương trình mình. Muốn thế thì phải có một “tổng đài” chỉ đường — đó là lý do có cổng 111. Nhớ nhé: RPC cần một tổng đài, và tổng đài đó là một cửa mở.

    RPC stands for remote procedure call, a system residing in the lower parts of the application layer, designed to make it easier for programmers to build client/server network applications where a client program calls functions that execute on a remote server.126 Each type of remote server program is identified by an assigned program number.1 RPC implementations use transport protocols such as TCP and UDP, and require a special intermediary service to map program numbers to TCP and UDP ports; that server is rpcbind, and it must be running on any machine that wants to use RPC services.127

    Bạn gặp nó ở đâuWhere you meet it Chạy rpcinfo -p localhost để xem máy bạn đang có những dịch vụ RPC nào.128 Khi bạn muốn xem máy mình còn dịch vụ cũ nào đang bật. Run rpcinfo -p localhost to see which RPC services your computer has.128

    Vì sao nó “không chịu chết”

    Ward viết bằng giọng hơi mệt mỏi: “RPC là một trong những giao thức đơn giản là không chịu chết.” Network File System (NFS) và Network Information Service (NIS) đều dùng RPC, nhưng chúng hoàn toàn không cần thiết trên máy đứng độc lập. Thế nhưng mỗi khi bạn tưởng mình đã loại bỏ hết nhu cầu dùng rpcbind thì lại có thứ khác nổi lên — chẳng hạn hỗ trợ File Access Monitor (FAM) trong GNOME.1

    Liên hệ ngược lại với đợt quét

    Đây là chỗ chương tự khép một vòng nhỏ: cổng 111 xuất hiện trong kết quả nmap ở mục trước chính là rpcbind, và ở mục an ninh phía sau Ward lại lấy đúng “cổng TCP 111 cho máy chủ ánh xạ cổng RPC” làm ví dụ cho các dịch vụ nội bộ mà không hệ thống nào khác trên thế giới cần biết tới.1 Đặc tả RPC phiên bản 2 nằm ở RFC 5531.26

Cụm khái niệm 04 Concept cluster 04

An ninh mạng theo lối thực dụng, và socket — ranh giới cuối cùng Giữ máy an toàn, và cái ống nối chương trình với mạng Pragmatic network security, and sockets — the final boundary

Ward mở phần an ninh bằng một quan sát tỉnh táo: vì Linux là một biến thể Unix rất phổ biến trên nền PC, và đặc biệt vì nó được dùng rộng rãi cho máy chủ web, nó thu hút nhiều kẻ tìm cách đột nhập.1 Ông cũng thừa nhận lĩnh vực này “thu hút những người cực đoan” ở cả hai phía. Nhưng kết luận của ông rất nhẹ nhõm: may thay, bạn không cần biết nhiều lắm để giữ hệ thống của mình an toàn.1

Máy Linux hay bị người lạ thử mò vào, vì nó được dùng nhiều để chạy trang web. Nhưng bạn không cần thành chuyên gia mới giữ được máy an toàn — chỉ cần vài thói quen đơn giản. Nhớ nhé: an toàn phần lớn đến từ thói quen, không phải từ mẹo cao siêu.

Ward opens the security part with a level-headed observation: because Linux is a very popular Unix flavour on the PC platform, and especially because it is widely used for web servers, it attracts many who try to break in.1 He grants the field “attracts extremists” on both sides. But his conclusion is a relief: fortunately, you don't need to know very much to keep your system safe.1

Cần nói rõ phạm vi: nội dung an ninh trong chương này là phòng thủ và quản trị. Ward mô tả các dạng tấn công để bạn biết mình đang phòng cái gì, và mọi hành động ông đề nghị đều là hành động trên hệ thống của chính bạn — tắt dịch vụ, chặn bằng tường lửa, cập nhật phần mềm, chọn bản phát hành hỗ trợ dài hạn. Trang này giữ đúng phạm vi đó.

Định nghĩa. Socket là giao diện mà các tiến trình dùng để truy cập mạng thông qua nhân; theo cách diễn đạt của Ward, chúng đại diện cho ranh giới giữa không gian người dùng và không gian nhân, và chúng cũng thường được dùng cho giao tiếp liên tiến trình (IPC).129

Nói đơn giản. Socket là cái ống mà chương trình cắm vào để nói chuyện ra ngoài. Một đầu ống thuộc về chương trình của bạn, đầu kia thuộc về “ruột” của hệ điều hành. Nhớ nhé: socket là chỗ chương trình chạm vào mạng.

Definition. A socket is the interface processes use to access the network through the kernel; in Ward's phrasing they represent the boundary between user space and kernel space, and they are often also used for interprocess communication (IPC).129

TCP → stream socket (SOCK_STREAM)
UDP → datagram socket (SOCK_DGRAM)

listen() → accept() → fork()
listener socket ≠ read/write socket

TCP → ống liên tục
UDP → từng gói rời

nghe → nhận → giao cho người phụ việc

TCP → stream socket (SOCK_STREAM)
UDP → datagram socket (SOCK_DGRAM)

listen() → accept() → fork()
listener socket ≠ read/write socket

  1. rules of thumb

    Sáu quy tắc ngón tay cái — toàn bộ phần “thực hành” của an ninh Sáu thói quen giữ máy an toàn Six rules of thumb — the whole practical end of security

    Quy tắc đầu tiên và mạnh nhất: chạy càng ít dịch vụ càng tốt — kẻ xâm nhập không thể đột nhập vào những dịch vụ không tồn tại trên hệ thống của bạn; nếu bạn biết một dịch vụ là gì mà không dùng tới, đừng bật nó chỉ vì lý do duy nhất là có thể “sau này sẽ cần”.1 Quy tắc thứ hai: chặn càng nhiều càng tốt bằng tường lửa, vì hệ thống Unix có một số dịch vụ nội bộ mà bạn có thể không biết — chẳng hạn cổng TCP 111 cho máy chủ ánh xạ cổng RPC — và không hệ thống nào khác trên thế giới cần biết tới chúng.12

    Quy tắc số một: cửa nào không dùng thì đóng lại. Kẻ trộm không vào được cái cửa không tồn tại. Quy tắc số hai: dựng một hàng rào quanh nhà, vì trong nhà có những cửa nhỏ mà chính bạn cũng quên mất. Nhớ nhé: ít cửa mở + một hàng rào = đã an toàn phần lớn.

    The first and strongest rule: 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 it “at some later point”.1 The second: block as much as possible with a firewall, because Unix systems have internal services 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.12

    Bạn gặp nó ở đâuWhere you meet it Mỗi lần bạn dựng một máy mới và quyết định cài gói nào — đó chính là lúc quy tắc số một có hiệu lực. Mỗi khi bạn cài một máy mới. Every time you build a new machine and decide which packages to install — that is when rule one takes effect.

    Bốn quy tắc còn lại

    Theo dõi các dịch vụ bạn cung cấp ra internet — nếu bạn chạy máy chủ SSH, Postfix hay tương tự, hãy giữ phần mềm cập nhật và nhận các cảnh báo an ninh phù hợp. Dùng bản phát hành “hỗ trợ dài hạn” cho máy chủ — các đội an ninh thường tập trung vào những bản phân phối ổn định, được hỗ trợ; các bản phát triển và thử nghiệm như Debian Unstable hay Fedora Rawhide nhận ít chú ý hơn nhiều. Đừng cấp tài khoản cho người không cần — chiếm quyền siêu người dùng từ một tài khoản cục bộ dễ hơn nhiều so với đột nhập từ xa. Tránh cài các gói nhị phân đáng ngờ — chúng có thể chứa ngựa thành Troy.1

    Ba dạng tấn công mà ông phân loại

    Ward nêu ba loại tấn công mạng cơ bản có thể nhắm vào một máy Linux. Chiếm quyền hoàn toàn (full compromise): lấy được quyền siêu người dùng, tức kiểm soát toàn bộ máy. Tấn công từ chối dịch vụ (DoS): ngăn máy thực hiện dịch vụ mạng của nó, hoặc buộc máy hoạt động sai theo cách khác, mà không cần truy cập đặc biệt nào; ông nói các cuộc tấn công này khó ngăn hơn nhưng dễ phản ứng hơn. Phần mềm độc hại (malware): người dùng Linux phần lớn miễn nhiễm với sâu và virus qua email, đơn giản vì các trình thư của họ không dại tới mức thực sự chạy chương trình gửi kèm — nhưng mã độc cho Linux vẫn tồn tại, nên hãy tránh tải và cài phần mềm thực thi từ những nơi bạn chưa từng nghe tên.1

    Hai loại lỗ hổng điển hình

    Có hai loại lỗ hổng cơ bản đáng lo: tấn công trực tiếp và nghe lén mật khẩu dạng chữ thường. Tấn công trực tiếp cố chiếm máy mà không tinh vi gì; một trong những cách phổ biến nhất là tìm ra một dịch vụ không được bảo vệ hoặc có lỗ hổng — đơn giản như một dịch vụ mặc định không xác thực, chẳng hạn một tài khoản quản trị không mật khẩu. Trong quá khứ, một kiểu tấn công trực tiếp phổ biến là khai thác tràn bộ đệm, khi lập trình viên bất cẩn không kiểm tra biên của một mảng đệm; điều này đã được giảm nhẹ phần nào nhờ các kỹ thuật ngẫu nhiên hoá bố trí không gian địa chỉ (ASLR) trong nhân và các biện pháp bảo vệ khác.130 Tấn công nghe lén bắt mật khẩu gửi đi dưới dạng chữ thường, hoặc dùng cơ sở dữ liệu mật khẩu lấy từ các vụ rò rỉ dữ liệu; Ward viết thẳng: “ngay khi kẻ tấn công có mật khẩu của bạn, mọi chuyện kết thúc”.1

    Những dịch vụ ông bảo luôn luôn tắt

    Ward chỉ đích danh một số dịch vụ “là mục tiêu tấn công kinh niên do hiện thực và thiết kế kém”, và nói bạn nên luôn luôn vô hiệu hoá chúng — dù chúng đều đã khá cũ và hiếm khi được bật mặc định trên hầu hết hệ thống ngày nay. ftpd: vì lý do nào đó, mọi máy chủ FTP dường như đầy lỗ hổng, và hầu hết dùng mật khẩu dạng chữ thường; nếu phải chuyển tệp giữa hai máy, hãy cân nhắc giải pháp dựa trên SSH hoặc một máy chủ rsync. telnetd, rlogind, rexecd: tất cả đều truyền dữ liệu phiên từ xa (kể cả mật khẩu) dưới dạng chữ thường; tránh chúng trừ khi bạn có phiên bản bật Kerberos.1 Với dịch vụ không hỗ trợ mã hoá sẵn, ông gợi ý Stunnel — một gói bọc mã hoá, đặc biệt hợp để bọc các dịch vụ bạn thường kích hoạt bằng socket unit của systemd hoặc inetd.131

  2. security resources

    Ba nguồn an ninh mà tác giả chỉ tên Ba chỗ để đọc tin an ninh The three security resources the author names

    Ward liệt kê đúng ba nguồn tốt. SANS Institute cung cấp đào tạo, dịch vụ, một bản tin hằng tuần miễn phí liệt kê các lỗ hổng hàng đầu hiện tại, các chính sách an ninh mẫu và hơn nữa.132 Bộ phận CERT thuộc Viện Kỹ nghệ Phần mềm của Đại học Carnegie Mellon là nơi tốt để tìm những vấn đề nghiêm trọng nhất.133 Insecure.org, dự án của Gordon “Fyodor” Lyon — người tạo ra Nmap — là nơi để lấy Nmap và các chỉ dẫn tới đủ loại công cụ kiểm thử.134

    Tác giả chỉ cho bạn ba chỗ đáng đọc để biết lỗ hổng mới. Đọc tin an ninh đều đặn là một thói quen tốt, giống như đọc dự báo thời tiết trước khi ra khơi. Nhớ nhé: biết tin sớm thì vá sớm.

    Ward names exactly three good resources. The SANS Institute offers training, services, a free weekly newsletter listing the top current vulnerabilities, sample security policies and more.132 The CERT Division of Carnegie Mellon University's Software Engineering Institute is a good place to look for the most severe problems.133 Insecure.org, a project from Nmap creator Gordon “Fyodor” Lyon, is where to go for Nmap and pointers to network testing tools.134

    Bạn gặp nó ở đâuWhere you meet it Khi bạn nhận trách nhiệm cho một máy chủ chạy thật — đăng ký nhận cảnh báo là việc đầu tiên nên làm. Khi bạn bắt đầu trông coi một máy chủ thật. When you take responsibility for a production server — subscribing to alerts is the first thing to do.

    Hướng học tiếp mà ông chỉ

    Nếu bạn quan tâm tới an ninh mạng, Ward nói bạn nên tìm hiểu kỹ về Transport Layer Security (TLS) và tiền thân của nó là Secure Socket Layer (SSL) — các tầng mạng ở không gian người dùng này thường được thêm vào máy khách và máy chủ mạng để hỗ trợ giao dịch mạng thông qua mã hoá khoá công khai và chứng chỉ.1 Phiên bản TLS hiện hành, TLS 1.3, được chuẩn hoá trong RFC 8446.22

    Bước kế tiếp mà ông gợi ý làm tay

    Trong mục “Looking Forward”, Ward gợi ý: nếu bạn muốn làm bẩn tay với các máy chủ mạng phức tạp, hãy thử các máy chủ web Apache hoặc nginx và máy chủ email Postfix. Máy chủ web đặc biệt dễ cài và hầu hết bản phân phối đều có gói sẵn; nếu máy của bạn nằm sau tường lửa hoặc router bật NAT, bạn có thể thử nghiệm cấu hình thoải mái mà không phải lo về an ninh.1

  3. network sockets

    Socket mạng — hai loại socket trong một máy chủ Hai cái ống trong một máy chủ Network sockets — two kinds of socket in one server

    Đọc và ghi trên các kết nối mạng đã thiết lập thì dễ: chỉ cần vài lời gọi hệ thống, mô tả trong các trang man recv(2) và send(2).135 Điều quan trọng nhất từ góc nhìn của một tiến trình là làm sao truy cập được mạng khi dùng các lời gọi đó — và câu trả lời là socket.1 Có nhiều loại socket vì tiến trình cần truy cập mạng theo những cách khác nhau: kết nối TCP được biểu diễn bằng stream socket (SOCK_STREAM, theo cách nhìn của lập trình viên), còn kết nối UDP bằng datagram socket (SOCK_DGRAM).129

    Một máy chủ thật ra có hai loại ống: một ống để nghe xem có ai gọi không, và mỗi lần có người gọi thì tạo thêm một ống riêng để nói chuyện với người đó. Ống nghe vẫn nằm im tại chỗ. Nhớ nhé: ống để nghe và ống để nói là hai ống khác nhau.

    Reading from and writing to network connections that are already set up is easy enough: all you need are some system calls, described in the recv(2) and send(2) manual pages.135 From a process's point of view the most important thing is how to access the network when using those calls — and the answer is a socket.1 There are different socket types because processes need to access the network in different ways: TCP connections are represented by stream sockets (SOCK_STREAM, from a programmer's point of view), UDP connections by datagram sockets (SOCK_DGRAM).129

    Bạn gặp nó ở đâuWhere you meet it Mỗi khi bạn đọc mã nguồn của bất kỳ máy chủ mạng nào — socket(), bind(), listen(), accept() là bộ bốn bạn sẽ thấy lặp lại. Khi bạn mở mã nguồn của một máy chủ ra xem. Whenever you read the source of any network server — socket(), bind(), listen(), accept() is the quartet you keep seeing.

    Lưu đồ Hình 10-1, đọc bằng lời

    Ward mô tả kiểu máy chủ này dùng hai loại socket: một để lắng nghe, một để đọc và ghi. Tiến trình chủ dùng socket lắng nghe để tìm kết nối từ mạng. Khi có kết nối mới đến, tiến trình chủ dùng lời gọi hệ thống accept() để chấp nhận kết nối — việc này tạo ra socket đọc/ghi dành riêng cho kết nối đó. Kế đến, tiến trình chủ dùng fork() để tạo tiến trình con lo kết nối. Cuối cùng, socket ban đầu vẫn là socket lắng nghe và tiếp tục tìm kết nối mới thay cho tiến trình chủ.136

    Vì sao socket là một trừu tượng tốt

    Sau khi một tiến trình đã thiết lập một socket thuộc loại nhất định, nó có thể tương tác với socket theo cách hợp với loại đó. Đây chính là điều làm socket linh hoạt: nếu bạn cần đổi tầng vận chuyển bên dưới, bạn không phải viết lại toàn bộ phần gửi và nhận dữ liệu; bạn chủ yếu chỉ cần sửa mã khởi tạo.1

    Sách ông giới thiệu cho lập trình viên

    Nếu bạn là lập trình viên và muốn học cách dùng giao diện socket, Ward chỉ tới Unix Network Programming, Volume 1, tái bản lần thứ 3, của W. Richard Stevens, Bill Fenner và Andrew M. Rudoff (Addison-Wesley Professional, 2003) — ông gọi đó là cuốn hướng dẫn kinh điển; Volume 2 còn bàn về giao tiếp liên tiến trình.137

  4. unix domain sockets

    Unix domain socket — mạng mà không có mạng Ống nối hai chương trình trong cùng một máy Unix domain sockets — networking without a network

    Không phải ứng dụng dùng tiện ích mạng nào cũng cần hai máy riêng biệt. Nhiều ứng dụng được dựng theo mô hình máy khách–máy chủ hoặc ngang hàng, trong đó các tiến trình chạy trên cùng một máy dùng giao tiếp liên tiến trình để thương lượng việc cần làm và ai làm.1 Các tiến trình hoàn toàn có thể dùng mạng IP thông thường qua localhost (127.0.0.1 hoặc ::1), nhưng chúng thường dùng một loại socket đặc biệt thay thế: Unix domain socket.138

    Hai chương trình trong cùng một máy cũng cần nói chuyện với nhau. Chúng có thể đi vòng ra mạng rồi quay lại, nhưng như thế mất công. Có một loại ống nối thẳng, ngắn hơn và nhanh hơn, chỉ dùng trong nhà. Nhớ nhé: nói chuyện trong nhà thì không cần ra ngoài đường.

    Not every application that uses network facilities involves two separate hosts. Many are built as client-server or peer-to-peer mechanisms where processes running on the same machine use interprocess communication to negotiate what work needs doing and who does it.1 Processes can use regular IP networking over localhost (127.0.0.1 or ::1), but they typically use a special kind of socket instead: the Unix domain socket.138

    Bạn gặp nó ở đâuWhere you meet it Ví dụ của Ward: tệp socket của D-Bus thường nằm ở /var/run/dbus/system_bus_socket, và máy chủ MySQL mysqld thường cũng cung cấp một Unix domain socket ở /var/run/mysqld/mysqld.sock.1 Khi bạn thấy một tệp lạ tên đuôi “.sock” trong máy. Ward's examples: the D-Bus socket file usually sits at /var/run/dbus/system_bus_socket, and the MySQL server mysqld usually also offers a Unix domain socket at /var/run/mysqld/mysqld.sock.1

    Hai lý do lập trình viên thích chúng

    Thứ nhất, chúng cho phép dùng tệp socket đặc biệt trong hệ thống tệp để kiểm soát truy cập: tiến trình nào không có quyền với tệp socket thì không dùng được nó. Và vì không có tương tác với mạng, chúng đơn giản hơn và ít bị các kiểu đột nhập mạng thông thường hơn. Thứ hai, vì nhân Linux không phải đi qua nhiều tầng của hệ thống con mạng khi làm việc với Unix domain socket, hiệu năng thường tốt hơn hẳn.138

    Một ghi chú dễ bị bỏ qua

    Ward nhắc: hãy nhớ rằng Unix domain socket không phải socket mạng, và không có mạng nào phía sau nó — bạn thậm chí không cần cấu hình mạng để dùng nó. Unix domain socket cũng không bắt buộc phải gắn với tệp socket: một tiến trình có thể tạo một Unix domain socket không tên và chia sẻ địa chỉ với tiến trình khác.138

    Cách nhìn chúng bằng lsof

    Bạn xem danh sách Unix domain socket đang dùng trên hệ thống bằng lsof -U. Ward cảnh báo trước rằng danh sách sẽ khá dài, vì nhiều ứng dụng dùng rất nhiều socket không tên — chúng hiện ra với chữ socket trong cột NAME.119 Viết mã cho Unix domain socket cũng không khác mấy so với socket mạng thông thường, nên một số máy chủ mạng cung cấp cả hai đường giao tiếp.1

Đối chiếu Against the text

Ba ngộ nhận mà chương này gỡ bỏ Ba chỗ người mới hay hiểu nhầm Three misconceptions this chapter removes

Phần này thuộc mức đọc Đầy đủ: nó đối chiếu điều người đọc thường nghĩ với điều bản văn thật sự nói.

Phần này hơi khó, bạn có thể bỏ qua và quay lại sau. Nhớ nhé: hiểu chậm mà chắc vẫn hơn.

This block belongs to the Đầy đủ (full) reading level: it sets what readers usually assume against what the text actually says.

“Header và nội dung là hai loại dữ liệu khác nhau trên mạng” "Headers and body are two different kinds of data on the network"

Ngộ nhận: mạng hoặc hệ điều hành biết đâu là phần đầu thư, đâu là phần nội dung, và xử lý chúng khác nhau.

Bản văn nói: dù curl in ra “Recv header” rồi “Recv data”, không hề có khác biệt nào trong cách curl nói với hệ điều hành để lấy chúng, trong cách hệ điều hành xử lý, hay trong cách mạng xử lý các gói bên dưới — khác biệt hoàn toàn nằm trong ứng dụng không gian người dùng.1

Misconception: the network or the operating system knows which part is header and which is body, and handles them differently.

The text says: although curl prints “Recv header” and then “Recv data”, there is no difference in how curl talked to the operating system to retrieve them, in how the operating system handled them, or in how the network handled the packets underneath — the difference is entirely within the user-space application.1

“Một máy chủ mạng là một tiến trình” "A network server is one process"

Ngộ nhận: sshd hay nginx là một chương trình duy nhất đang chạy, phục vụ tất cả mọi người.

Bản văn nói: đặc điểm chung của hầu hết máy chủ mạng là chúng hoạt động như nhiều tiến trình — ít nhất một tiến trình lắng nghe, và mỗi kết nối mới sinh ra một tiến trình con qua fork(), tiến trình con kết thúc khi kết nối đóng.1 Nhưng mô hình này có ngoại lệ: máy chủ TCP hiệu năng cao như Apache có thể tạo sẵn worker khi khởi động để tránh chi phí fork(), còn máy chủ UDP không cần fork() gì cả vì không có kết nối để lắng nghe.1

Misconception: sshd or nginx is a single running program serving everyone.

The text says: a feature common to most network servers is that they operate as multiple processes — at least one listener, and each new connection spawns a child via fork() that terminates when the connection closes.1 But the model has exceptions: high-performance TCP servers such as Apache may create worker processes at startup to avoid fork() overhead, and UDP servers don't fork at all because they have no connections to listen for.1

“Unix domain socket chỉ là mạng qua localhost” "A Unix domain socket is just networking over localhost"

Ngộ nhận: nó cũng là socket mạng, chỉ khác là địa chỉ đích là chính máy mình.

Bản văn nói: Ward viết thành một ghi chú riêng — Unix domain socket không phải socket mạng, và không có mạng nào phía sau nó; bạn thậm chí không cần cấu hình mạng để dùng nó.1 Chính vì nhân không phải đi qua nhiều tầng của hệ thống con mạng mà hiệu năng của nó tốt hơn hẳn.138

Misconception: it is a network socket too, just with the local machine as the destination.

The text says: Ward gives this its own note — a Unix domain socket is not a network socket, and there's no network behind one; you don't even need networking configured to use one.1 It is precisely because the kernel doesn't traverse the many layers of its networking subsystem that performance is much better.138

Tự kiểm tra Self-check

Bạn đã nắm tầng ứng dụng chưa? Thử trả lời xem nào Do you have the application layer yet?

Trả lời bằng lời của bạn, không tra sách. Nếu một câu khiến bạn ngập ngừng, đó chính là mục bạn nên đọc lại.

Thử trả lời miệng thôi, không cần giở lại. Câu nào bí thì quay lại đọc phần đó nhé. Nhớ nhé: chỗ bí chính là chỗ cần học.

Answer in your own words, without looking back. Whichever question makes you hesitate points at the section you should reread.

  1. Bài tập telnet example.org 80 chứng minh chính xác hai điều gì?

    Gợi ý sâu hơn: vì sao bạn phải tự tay kết thúc kết nối, thay vì máy chủ đóng nó ngay?

  2. Vì sao “header” và “data” trong đầu ra của curl lại không phải hai loại dữ liệu khác nhau?

    Gợi ý sâu hơn: dấu hiệu nào trong luồng byte khiến curl biết phải chuyển cách diễn giải?

  3. Mô tả mô hình nhiều tiến trình của một máy chủ mạng — và nêu hai ngoại lệ mà sách chỉ ra.

    Gợi ý sâu hơn: vì sao máy chủ UDP không cần fork()?

  4. Khác nhau giữa sshd_config và ssh_config là gì, và vì sao tác giả nhắc bạn cẩn thận?

    Gợi ý sâu hơn: kể ba trong sáu tham số mà ông gọi là quan trọng nhất.

  5. Cảnh báo “REMOTE HOST IDENTIFICATION HAS CHANGED!” nghĩa là gì, và bạn xử lý ra sao?

    Gợi ý sâu hơn: thông điệp đó cho bạn biết chính xác cái gì về tệp known_hosts?

  6. Dùng công cụ nào để trả lời câu “tiến trình nào đang lắng nghe trên cổng TCP 443?”

    Gợi ý sâu hơn: hai tuỳ chọn nào giúp đầu ra chạy nhanh hơn, và chúng tắt cái gì?

  7. tcpdump làm gì với card mạng của bạn, và giới hạn đạo đức mà tác giả đặt ra là gì?

    Gợi ý sâu hơn: “primitive” và “operator” trong bộ lọc tcpdump khác nhau thế nào?

  8. Trước khi quét một mạng bằng Nmap, tác giả yêu cầu bạn làm gì?

    Gợi ý sâu hơn: trong kết quả quét mẫu, cổng nào là cổng thường bật sẵn — và nó thuộc dịch vụ nào?

  9. Vì sao rpcbind phải tồn tại, và RPC làm gì với “số hiệu chương trình”?

    Gợi ý sâu hơn: hai hệ thống nào mà sách nêu tên là vẫn dùng RPC?

  10. Một máy chủ dùng hai loại socket nào, và accept() tạo ra loại nào?

    Gợi ý sâu hơn: nếu đổi tầng vận chuyển bên dưới, phần mã nào bạn phải sửa?

  11. Nêu hai lý do lập trình viên chọn Unix domain socket thay vì mạng qua localhost.

    Gợi ý sâu hơn: một Unix domain socket có bắt buộc phải gắn với một tệp không?

  1. Một “cổng” trên máy tính giống cái gì trong đời thật?

  2. Khi có người gõ cửa, máy chủ làm gì?

  3. SSH dùng để làm gì, và vì sao nó an toàn hơn cách cũ?

  4. Chìa khoá công khai và chìa khoá riêng tư khác nhau ra sao?

  5. Máy bạn hét lên “khoá đã thay đổi” thì nên làm gì?

  6. Bốn công cụ soi mạng trong chương này, mỗi cái trả lời câu hỏi gì?

  7. Trước khi quét cửa nhà người khác, bạn phải làm gì?

  8. Quy tắc an toàn số một của tác giả là gì?

  9. Hai chương trình trong cùng một máy nói chuyện với nhau bằng cách nào cho nhanh?

  1. What exactly are the two things the telnet example.org 80 exercise demonstrates?

  2. Why are “header” and “data” in curl's output not two different kinds of data?

  3. Describe a network server's multi-process model — and name the two exceptions the book points out.

  4. What is the difference between sshd_config and ssh_config, and why does the author warn you?

  5. What does the “REMOTE HOST IDENTIFICATION HAS CHANGED!” warning mean, and how do you handle it?

  6. Which tool answers “which process is listening on TCP port 443?”

  7. What does tcpdump do to your network card, and what ethical limit does the author set?

  8. What does the author require you to do before scanning a network with Nmap?

  9. Why must rpcbind exist, and what does RPC do with “program numbers”?

  10. Which two kinds of socket does a server use, and which one does accept() create?

  11. Give two reasons developers pick Unix domain sockets over networking via localhost.

Khép lại chương Closing the chapter

Ở tầng ứng dụng, mọi thứ hoá ra rất người: một tiến trình ngồi chờ ở một cổng, một tiến trình khác gõ cửa, và ý nghĩa của những byte đi qua hoàn toàn do phần mềm tự đặt ra. Suốt vài chương vừa rồi sách đã dần rời không gian nhân để vào không gian người dùng — và socket chính là chiếc cầu bắc qua khoảng cách ấy.1

Máy chủ chỉ là một chương trình ngồi chờ ở một cái cửa; những dòng chữ đi qua chỉ có ý nghĩa khi chương trình gán ý nghĩa cho chúng. Và socket là chiếc cầu nối chương trình với mạng. Nhớ nhé: cổng, tiến trình, và chiếc cầu — ba thứ đó là cả chương này.

At the application layer everything turns out to be rather human: one process waiting at a port, another knocking, and the meaning of the bytes that pass is something software alone assigns. Over the last few chapters the book has gradually left kernel space for user space — and sockets are the bridge across that gap.1