Kali Linux——基础

465 阅读1小时+

Kali Linux 是一个基于 Ubuntu Linux 的专用 Linux 发行版,而 Ubuntu 又是基于 Debian Linux。Kali 主要面向那些从事安全工作的人群。这些工作可能包括安全测试、漏洞开发、逆向工程,或者数字取证。需要记住的一点是,Linux 发行版并不完全相同。Linux 实际上只是操作系统的内核——它是操作系统的核心部分,每个发行版都在这个核心上叠加了不同的软件,使得每个发行版都有其独特性。在 Kali Linux 中,除了基础的系统工具外,还叠加了数百个特定于安全工作的软件包。

Linux 的一个非常棒的特点,尤其是与其他操作系统相比,是它几乎完全可定制。这包括选择你运行程序的 shell,shell 不仅是你输入命令的终端环境,还包括你使用的图形桌面。更进一步地,你可以在选择了环境之后,改变每个元素的外观。使用 Linux 让你能够根据自己的工作方式定制系统,而不是让系统强迫你按照它的方式来操作、看待和体验。

Linux 实际上有着悠久的历史,如果你追溯到它的起源,理解这段历史有助于你了解为什么 Linux 会是现在的样子——特别是那些看起来晦涩的命令,用来管理系统、操作文件和完成工作。

Linux的传承

很久以前,在恐龙时代,或者至少是冰箱大小的计算机时代,曾经存在一个名为Multics的操作系统。这个操作系统项目始于1964年,由麻省理工学院(MIT)、通用电气公司(GE)和贝尔实验室(Bell Labs)共同开发。Multics的目标是支持多用户,并为每个用户提供进程和文件的隔离。毕竟,在那个时代,运行像Multics这样的操作系统所需的计算机硬件需要数百万美元。至少,计算机硬件的价格是几十万美元。作为对比,一个价值700万美元的系统在2023年4月的价值大约为6200万美元。只支持单用户的系统显然不具成本效益,因此像GE这样的计算机制造商与MIT和贝尔实验室等研究机构一起开发Multics。

由于参与者之间的复杂性和利益冲突,Multics项目最终慢慢崩溃,尽管操作系统最终还是发布了。贝尔实验室的一名程序员回到了他原来的工作,并最终决定编写自己的操作系统版本,以便在贝尔实验室可用的PDP-7计算机上玩一款他原本为Multics编写的游戏。这款游戏叫做《Space Travel》,而这名程序员Ken Thompson需要一个合适的环境来为PDP-7重新开发这个游戏。在那个时候,系统通常不兼容,它们有完全不同的硬件指令(操作码),有时甚至有不同的内存字长,今天我们通常称之为总线宽度。因此,为一个环境编写的程序,特别是如果使用了非常底层的语言,通常无法在另一个环境中运行。最终,这个环境被命名为Unics,后来其他贝尔实验室的程序员加入了这个项目,并将其更名为Unix。

Unix具有简单的设计。由于它最初是作为一个单用户的编程环境开发的,最终它在贝尔实验室内部使用,后来也被其他程序员在外部使用。Unix相较于其他操作系统的最大优势之一,是它的内核在1972年用C语言重新编写。使用比汇编语言更高级的语言,使得Unix能够跨多个硬件系统进行移植。与只能运行在PDP-7上的操作系统不同,Unix可以在任何拥有C编译器的系统上运行,从而能够编译构建Unix所需的源代码。这使得Unix能够在多个硬件平台上提供标准的操作系统。

注释
汇编语言是最接近直接由机器理解的语言,而不依赖于二进制的编程语言。汇编语言包含助记符,表示处理器可以理解的操作。助记符通常是描述操作的简短词汇。例如,CMP指令比较两个值,MOV指令将数据从一个位置移动到另一个位置。汇编语言使你可以完全控制程序如何运行,因为它直接转换为机器语言——处理器操作和内存地址的二进制值。

除了简单的设计外,Unix的另一个优势是它提供了源代码。这使得研究人员不仅可以阅读源代码以更好地理解它,还可以扩展和改进源代码。之前使用的汇编语言,若没有大量时间和经验,通常非常难以阅读。像C语言这样的高级语言使得阅读源代码变得更容易。Unix衍生出了许多“子操作系统”,它们的行为和功能与Unix完全相同。在某些情况下,这些其他的操作系统发行版是基于AT&T提供的Unix源代码开发的;在其他情况下,Unix则基本上是通过反向工程,基于文档化的功能开发出来的,并且成为了两个受欢迎的类Unix操作系统的起点:BSD和Linux。

注释
正如你将在后面看到的,Unix设计的一个优势是使用小而简单的程序,它们各自执行单一的任务,但允许你将一个程序的输出传递给另一个程序作为输入,这种“链式处理”带来了强大的能力。这个设计决策的一个常见用途是使用一个工具获取进程列表,然后将其输出传递给另一个工具,后者将处理这个输出,可能是特定地搜索某个条目,或者操作输出以去除一些不必要的部分,从而使其更易理解。

关于Linux

随着Unix的传播,它简洁的设计以及其作为编程环境的重点,尤其是源代码的开放,使得它在全球范围的计算机科学课程中得到教授。1980年代,许多关于操作系统设计的书籍是基于Unix的设计编写的。虽然使用原始的源代码会侵犯版权,但其广泛的文档和简洁的设计使得克隆版本得以开发。其中一个实现版本是Andrew Tannenbaum为其书《Operating Systems: Design and Implementation》所编写的(普伦蒂斯霍尔,1987年)。这个实现版本名为Minix,成为Linus Torvalds开发Linux的基础。Torvalds开发的就是Linux内核,有些人认为它就是操作系统。内核允许管理硬件,包括处理器,从而通过中央处理单元(CPU)运行进程。它并没有提供用户与操作系统交互的功能,也就是说,用户无法通过它来执行程序。

GNU项目由Richard Stallman在1970年代末启动,收集了一些程序,这些程序要么是Unix标准实用工具的复制品,要么是功能相同但名称不同的程序。GNU项目主要使用C语言编写程序,这意味着它们可以轻松移植。因此,Torvalds以及后来其他开发者将GNU项目的工具与其内核捆绑在一起,创造了一个完整的软件发行版,任何人都可以在自己的计算机系统上开发和安装。GNU工具的集合有时被称为userland。用户与系统交互的工具就是这些userland工具。

Linux继承了Unix设计理念的绝大部分,主要是因为它最初作为与AT&T开发的标准Unix功能上相同的系统而开始开发的,并且被加利福尼亚大学伯克利分校的一个小团队重新实现为伯克利系统发行版(BSD)。这意味着任何熟悉Unix甚至BSD工作方式的人,都可以直接开始使用Linux并立即投入生产工作。自从Torvalds首次发布Linux以来,几十年来,许多项目旨在增加Linux的功能性和用户友好性。其中包括多个桌面环境,这些环境都建立在MIT最初开发的X/Windows系统之上(MIT同样参与了Multics的开发)。

Linux内核的开发改变了开发人员的工作方式。例如,Torvalds不满现有的允许多个开发者同时编辑相同文件的软件仓库系统。因此,他主导了Git的开发,Git是一种版本控制系统,已广泛取代了其他版本控制系统,成为开源开发的主流工具。如果你想从大多数开源项目获取当前版本的源代码,通常会通过Git来获取。此外,现在许多公开的代码仓库支持使用Git这一源代码管理工具来访问代码。即便是在开源项目之外,许多(如果不是大多数的话)企业已经将其版本控制系统转移到了Git,因为Git采用了现代化的、去中心化的源代码管理方式。

单体内核与微内核
Linux被视为单体内核。这与Linux起源的Minix以及其他采用微内核的类Unix实现有所不同。单体内核与微内核的区别在于,所有功能都集成在单体内核中,包括支持硬件设备的所有代码。而在微内核中,内核只包含支持操作系统运行所必需的最基本代码。这是保持操作系统功能所需的最低限度。任何额外需要在内核空间中运行的功能,都被实现为模块,并在需要时加载到内核空间。需要注意的是,Linux也有模块,但通常在Linux发行版中包含的内核并不是微内核。由于Linux的设计并不围绕“只有核心服务在内核中实现”的理念,它被视为单体内核,而非微内核。

Linux通常是免费的,并以发行版的形式提供。一个Linux发行版是由发行版维护者选择的各种软件包的集合。这些软件包是按照特定的方式构建的,并且每个软件包的特性由包维护者决定。软件包以源代码的形式获取,并且许多软件包可以有多个选项——比如是否支持数据库、选择哪种数据库、是否启用加密等——这些选项必须在配置和构建包时启用。不同发行版的包维护者可能会对选项做出不同的选择。

不同的发行版也可能使用不同的软件包格式。例如,RedHat及其相关发行版,如RedHat Enterprise Linux(RHEL)和Fedora Core,使用Red Hat包管理器(RPM)格式。此外,Red Hat使用RPM工具以及Yellowdog Updater Modified(yum)来管理系统上的软件包。其他发行版可能使用Debian使用的不同包管理工具。Debian使用高级包工具(APT)来管理Debian包格式的包。无论发行版或包格式如何,包的目的是收集运行软件所需的所有文件,并使这些文件易于放置,从而使软件功能正常运行。由于Kali Linux继承自Debian,经过Ubuntu,因此Kali也使用APT进行包管理,无论是在包格式支持还是包管理工具使用上。

多年来,发行版之间的另一个区别是默认提供的桌面环境。近年来,发行版创建了对现有桌面环境的自定义视图。无论是GNU对象模型环境(GNOME)、K桌面环境(KDE)还是Xfce,都可以通过主题、壁纸以及菜单和面板的组织进行定制。发行版通常会提供对不同桌面环境的独特定制。一些发行版,如ElementaryOS,甚至提供了自己的桌面环境,称为Pantheon。

尽管最终包管理器的结果是相同的,但有时包管理器的选择甚至桌面环境的选择对用户来说可能会有所不同。此外,包仓库的深度也可能会影响某些用户。他们可能希望在仓库中有更多的选择,而不是尝试手动构建并安装软件。不同的发行版可能有较小的仓库,即使它们使用相同的包管理工具和格式。由于软件依赖关系需要在所需软件能够正常工作之前先安装,包之间并不总是可以互换的,即使是相关的发行版之间也不例外。

有时,不同的发行版会针对特定的用户群体,而不是为任何想要桌面系统的人提供通用发行版。更进一步,像Ubuntu这样的发行版甚至会为每个发布版本提供不同的安装发行版,如服务器安装版和桌面安装版。桌面安装版通常包括图形用户界面(GUI),而服务器安装版则不包括GUI,因此安装的包要少得多。安装的包越少,暴露给攻击的机会就越小,而服务器通常存储敏感信息,并且由于提供网络服务,它们更有可能被暴露给未经授权的用户,这些服务在桌面系统上并不常见。

Kali Linux是一个特别针对某类用户的发行版——即那些对信息安全及其涵盖的广泛功能感兴趣的用户。Kali Linux作为一个专注于安全功能的发行版,属于桌面类别,并没有意图通过限制安装的包数量来使Kali更难被攻击。专注于安全测试的用户可能需要各种各样的软件包,而Kali在启动时就加载了这些包。这可能显得有些讽刺,因为那些专注于保护系统免受攻击的发行版(有时错误地称为安全发行版)往往会通过称为硬化的过程来限制软件包的数量。然而,Kali专注于测试,而非保护系统免受攻击。

Kali Linux由Offensive Security维护,这是一家提供安全咨询和教育的公司。此外,Kali Linux还因其认证——Offensive Security Certified Professional(OSCP)而闻名,这是一种非常实际、实践性的认证,专为那些对进攻性安全(如渗透测试和红队行动)感兴趣的人设计。

获取和安装Kali Linux

获取Kali Linux最简单的方式是访问其官方网站。在官网上,你可以找到关于软件的更多信息,比如已安装软件包的列表。你将下载一个ISO镜像文件,该文件可以用来安装到虚拟机(VM)中,或者烧录到DVD上,用来安装到物理机器上。

Kali Linux基于Debian,但这并非一直如此。曾经,Kali被称为BackTrack Linux。BackTrack基于Knoppix Linux,Knoppix主要是一个Live发行版,这意味着它是为从CD、DVD或USB启动并直接从源媒体运行而设计,而不是安装到目标硬盘上。Knoppix又继承自Debian。BackTrack和Kali Linux一样,都是专注于渗透测试和数字取证的发行版。BackTrack的最后一个版本发布于2012年,此后Offensive Security团队将BackTrack的理念重新构建,使其基于Debian Linux。Kali继承了BackTrack中的一个特点,即支持Live启动。获取Kali启动介质后,你可以选择安装或直接进行Live启动。在图1-1中,你可以看到启动选项。

image.png

从DVD运行还是安装到硬盘完全取决于你自己。如果你从DVD启动且没有在可写媒体上存储主目录,你将无法在每次启动之间保留任何数据。如果没有可写媒体来存储信息,你每次启动时将完全从头开始。如果你不希望操作系统运行时留下任何痕迹,这种做法有其优势。但如果你需要自定义设置,或希望保存SSH密钥或其他存储的凭证,那么你需要安装到本地媒体。

Kali的安装非常简单。它不像其他发行版那样提供多个选项。你不会选择软件包类别。Kali有一个预定义的安装软件包集,你可以选择添加或移除一些,但它默认包含了一整套用于安全测试或取证的工具。你需要做的配置工作包括选择安装磁盘、分区和格式化磁盘。你还需要配置网络,包括主机名和是否使用静态地址而不是动态主机配置协议(DHCP)。配置好这些后,设置你的时区以及其他基础配置,软件包将会更新,之后你就可以启动Linux系统了。

虚拟机

上述方法在专用机器上运行效果很好,但专用机器可能很昂贵。即便是低成本机器也需要一定的费用,并且需要空间和电力来维持机器的运行。在某些情况下,根据硬件的不同,你可能还需要额外的散热设备。

幸运的是,Kali并不需要专用硬件,它可以在虚拟机中很好地运行。如果你打算进行安全测试,尤其是渗透测试,搭建一个虚拟实验室是个不错的主意。我发现Kali在4GB内存和约20GB硬盘空间下运行得相当顺畅。如果你想存储大量测试的结果,可能需要更多的磁盘空间。对于基本任务,2GB内存就足够,但显然,内存越多,性能会越好。一些程序可能需要更多的内存才能有效运行。

你可以根据主机操作系统选择许多不同的虚拟化管理程序。VMware提供适用于Mac和PC的虚拟化管理程序,Parallels则可以在Mac上运行。VirtualBox则支持PC、Mac、Linux系统,甚至Solaris。VirtualBox自2007年发布以来一直在发展,2008年被Sun Microsystems收购,随着Sun被Oracle收购,VirtualBox现在由Oracle维护。无论谁维护,VirtualBox都是免费下载和使用的。如果你刚刚开始接触虚拟机世界,VirtualBox可能是一个不错的起点。每个虚拟化管理程序在与用户交互的方式上略有不同:退出虚拟机的快捷键不同;与操作系统的交互级别不同;对客户操作系统的支持不同,因为虚拟化管理程序必须提供客户操作系统所需的驱动程序。最终,这取决于你愿意花多少钱以及你使用哪款虚拟化管理程序最为舒适。

注意 有一个可能有趣或相关的信息点,BSD的主要开发者之一是Bill Joy,他是加利福尼亚大学伯克利分校的研究生。Joy负责了Berkeley Unix中TCP/IP的第一次实现。他在1982年成为了Sun Microsystems的共同创始人,并在那时写了一篇关于比C++更好的编程语言的论文,这篇论文成为了Java语言创建的灵感来源。

另一个考虑因素是虚拟化管理程序提供的工具。这些工具是安装到内核中的驱动程序,用于更好地与主机操作系统集成。这可能包括打印驱动程序、将主机文件系统共享到客户机的驱动程序以及更好的视频支持。VMware可以使用Kali Linux仓库中的开源VMware工具。你也可以从Kali仓库中获取VirtualBox工具。而Parallels则提供自己的工具。使用VMware的一个优势是,开源驱动程序在大多数(如果不是全部)Linux发行版中都可用。过去我在某些Linux版本上安装Parallels Tools时遇到了一些问题,尽管我通常喜欢使用Parallels。如果你不想在Kali虚拟机中自动调整显示比例或在主机与客户机虚拟机之间共享文档,那么你可能不需要使用任何虚拟机工具。

低成本计算

如果你不想从头开始安装,但又希望使用虚拟机,可以下载VMware或VirtualBox镜像。Kali不仅支持虚拟环境,还支持基于高级精简指令集(ARM)的设备,比如Raspberry Pi和BeagleBone。使用虚拟机镜像的好处是可以更快速地启动和运行。你不需要花时间进行安装,只需下载镜像并加载到你选择的虚拟化管理程序中,就可以开始使用。如果你选择使用预配置的虚拟机,可以在Kali的官方网站上找到相应的镜像。

另一种低成本运行Kali Linux的选择是Raspberry Pi。Pi是一款非常低成本且体积小巧的计算机。你可以下载专门为Pi设计的镜像。Pi使用的不是Intel或AMD处理器,这些处理器常见于大多数桌面系统,而是采用了ARM处理器。这些处理器使用更小的指令集,功耗也比桌面计算机中常见的处理器低。Pi的硬件就像一块非常小的主板,大小适合放在手掌中。你可以为这块主板购买不同的机箱,并根据需要配备外设,如键盘、鼠标和显示器。

Pi的一个优势是,它可以用于物理攻击,考虑到它的小巧体积。你可以将Kali安装到Pi上,并将其放置在你进行测试的位置,但它确实需要电力和某种形式的网络连接。Pi内置有以太网连接、无线WiFi接口和USB端口。一旦你将Kali安装好,你可以通过网络远程访问Pi,从而进行本地攻击。我们稍后会深入探讨这个话题。

Windows 子系统 Linux(WSL)

许多人使用Windows作为主要操作系统,考虑到它在大多数桌面任务中的实用性,这是完全合理的。虽然虚拟机是一种在任何系统上运行Linux的方式,但Windows提供了一种更直接的安装Linux的方法。2016年,Windows发布了Windows Subsystem for Linux(WSL)。这个功能允许在Windows上直接运行Linux的可执行和链接格式(ELF)二进制文件,ELF是Linux的默认可执行格式。WSL有两个版本。第一个版本是通过在Windows内核中直接实现Linux系统调用的方式运行Linux系统。由于硬件架构不受影响,Windows和Linux的可执行文件都基于Intel处理器架构,最大的考虑因素是Linux内核如何管理硬件。这个过程通过系统调用实现。Windows的系统调用与Linux的不同,在Windows中实现Linux的系统调用是允许Linux可执行文件在Windows上几乎原生运行的关键一步。

更近期,Microsoft改变了实现方式。Windows的桌面版本现在包含了一个轻量级的虚拟化管理程序,这是Hyper-V的实现,Hyper-V之前只在Windows服务器上作为本地虚拟化管理程序提供。现在,WSL是通过在Hyper-V虚拟机中运行Linux内核来实现的。Linux应用程序直接调用Linux内核,而不是调用Windows内核。这样做的一个原因是,一些Linux的系统调用在Windows中难以实现。将WSL实施在虚拟化环境中提供了隔离,使得Linux应用程序无法影响Windows应用程序,因为它们在不同的内存空间中运行。

安装WSL非常简单。使用命令行,无论是PowerShell还是较旧的命令处理器,只需运行 wsl --install。如图1-2所示,Windows默认会安装一个Ubuntu内核版本。如果你已经安装了旧版本的WSL,可以通过运行 wsl --upgrade 将其升级到WSL2。当你尝试使用WSL时,如果你正在运行旧版本,系统会提醒你,但你也可以通过在PowerShell或命令提示符窗口中运行 wsl -l -v 来主动检查。一旦环境安装完成,你可以从Windows菜单中启动它。默认的Ubuntu环境会以"Ubuntu"的名称出现在菜单中。

image.png

我们不想要Ubuntu,我们要的是Kali。你可以在Microsoft Store应用中找到Kali。如果你搜索Kali,你会看到它,就像图1-3所示那样。然而,安装它并不会真正安装整个发行版。它仅仅安装了运行Kali Linux的能力。当你第一次在Windows中打开Kali Linux时,它会安装镜像,并提示你进行用户配置。你会被要求输入用户名和密码。之后,当你再次运行Kali Linux时,你将自动登录到命令行界面。

image.png

WSL中的Kali基础镜像非常小,安装的内容不多。使用WSL2的一大优势是能够直接在Windows中运行图形应用程序。过去并不是这样。你可以在Windows中运行命令行程序,但运行图形程序需要额外的软件来托管这些图形程序。而现在,Windows已经包括了托管图形程序的功能。因此,你可能需要安装一些元包来获取更多程序。首先,你可能想要安装kali-linux-default。它将安装数百个附加包,帮助你入门。你不会拥有一个完整的图形桌面,但可以直接在Windows上运行图形程序。你可以在图1-4中看到,Ettercap作为一个图形程序在Windows桌面上运行,来自Linux环境。

image.png

WSL有一些限制。如果你打算进行无线测试,尤其会感受到这些限制。你需要一个物理系统或一个虚拟系统来传递接口。

现在有这么多启动选项,应该很容易就能快速完成安装。一旦安装完成并启动,你将希望熟悉桌面环境,如果你选择了包含桌面环境的选项,这样你可以开始提高生产力。

桌面环境

你将花费大量时间与桌面环境进行互动,所以最好选择一个你会觉得舒适的环境。与Windows和macOS等专有操作系统不同,Linux有多个桌面环境。Kali从其仓库中支持流行的桌面环境,无需添加任何额外的仓库。如果默认安装的桌面环境不适合你,替换它非常容易。因为你可能会在该环境中花费大量时间,所以不仅要舒适,还要能够高效工作。这意味着需要为自己找到合适的环境和工具集。

Xfce桌面环境

截至2023年中期,Kali的默认桌面环境是Xfce。它常常是一个受欢迎的替代桌面环境,尽管并不总是作为默认环境。它之所以受欢迎的原因之一是,它被设计得相对轻量,适用于完整的桌面环境,因此响应速度更快。许多我认识的资深Linux用户,如果需要桌面环境,都会选择Xfce作为首选环境。再次强调,原因在于它具有简洁的设计,并且高度可配置。在图1-5中,你可以看到一个基本的Xfce设置。桌面底部的面板完全可配置。你可以改变它的位置和行为,并根据自己的工作方式,添加或移除项目。这个面板包括一个应用程序菜单,里面有与GNOME菜单中相同的文件夹或类别。

image.png

虽然Xfce是基于GNOME工具包(GTK)的,但它并不是GNOME的一个分支。Xfce是在较旧版本的GTK上开发的,目的是创造一个比GNOME方向更简单的桌面环境。Xfce的目标是轻量级,因此具有更好的性能。其设计理念是:桌面环境不应该妨碍用户进行实际工作。

与Windows类似,如果你更习惯Windows,Xfce也提供了一个应用菜单,菜单中有已安装程序的快捷方式。与按软件供应商或程序名称分类不同,Xfce的程序是按功能分类显示的。以下是本书中将覆盖的程序类别:

  • 信息收集
  • 漏洞分析
  • Web应用程序分析
  • 数据库评估
  • 密码攻击
  • 无线攻击
  • 逆向工程
  • 利用工具
  • 嗅探与伪装
  • 后期利用
  • 数字取证
  • 报告工具
  • 社会工程工具
  • 系统服务

在菜单旁边,还有一组启动器,类似于Windows菜单栏中的快捷启动器。Xfce还默认设置了四个虚拟桌面。你可以在菜单栏上看到这些虚拟桌面的编号框。每个虚拟桌面都可以作为一个存放运行中应用程序的空间。这是一种保持桌面整洁、避免过于杂乱的方法。

GNOME桌面

GNOME曾是多个Linux发行版的默认桌面环境,它也可以作为Kali Linux的选项之一。这个桌面环境是GNU(GNU's Not Unix,即“GNU不是Unix”的递归首字母缩写)项目的一部分。Red Hat是主要的企业贡献者之一,并将GNOME桌面作为其控制的发行版的主要界面,Ubuntu和其他一些发行版也使用GNOME桌面。图1-6展示了GNOME桌面环境,并展开了主菜单。

image.png

主菜单通过顶部栏的“应用程序”菜单访问。它可以通过“Tweaks”程序进行最小化的配置,主要与时钟和日历有关。此外,“位置”菜单允许你打开文件管理器,显示“位置”菜单中列出的目录内容。例如,“首页”和“文档”是两个位置。如果选择其中一个,你将打开指向你的主目录或主目录中的“文档”目录的文件管理器。在顶部面板的左侧,你还可以打开虚拟桌面管理器。

除了顶部面板的菜单,底部还有一个类似macOS的“停靠栏”。停靠栏包含常用应用程序,如终端、Firefox、Metasploit、Wireshark、Burp Suite和文件管理器。单击这些图标中的任意一个即可启动相应应用程序。你可以通过从应用程序列表中拖动图标,将快捷方式添加到这个停靠栏。通过点击停靠栏右侧的九宫格图标,可以调出按字母顺序排列的系统中已安装的应用程序,正如图1-7所示。停靠栏中的应用程序最初也会显示在可以通过顶部面板访问的“应用程序”菜单中的“收藏”部分。与Windows的任务栏横跨整个屏幕不同,GNOME和macOS的停靠栏仅宽度足以容纳固定在那里图标及正在运行的应用程序图标。

image.png

注意
macOS的停靠栏源自NeXTSTEP操作系统的界面,NeXTSTEP是为NeXT计算机设计的操作系统。这台计算机是Steve Jobs在1980年代被迫离开苹果公司后创办公司设计和制造的。许多NeXTSTEP用户界面(UI)元素在苹果收购NeXT时被融入到了macOS的UI中。顺便提一下,NeXTSTEP是建立在BSD操作系统之上的,这也是为什么macOS在底层使用Unix系统的原因,打开终端窗口时,你会看到这一点。

通过桌面管理器登录

虽然GNOME是默认的桌面环境,但其他桌面环境也可以轻松安装并使用。如果你安装了多个桌面环境,登录时可以在显示管理器中选择其中一个。首先,你需要输入你的用户名,以便系统识别你配置的默认环境。这可能是你上次登录的环境。图1-8展示了我可以从我的一个Kali Linux系统中选择的桌面环境。

image.png

多年来,出现了许多显示管理器。最初,登录屏幕由X窗口管理器提供,但随着其他显示管理器的发展,其功能得到了扩展。LightDM的一个优点是它被认为是轻量级的。如果你在资源较少的系统上工作,如内存和处理器较小的设备,这一点尤其重要。

Cinnamon 和 MATE

另外两个桌面环境,Cinnamon 和 MATE,也源自GNOME。负责Linux Mint的开发人员对于GNOME 3及其带有的GNOME shell(桌面界面)并不满意。因此,他们开发了Cinnamon,最初只是一个在GNOME之上的shell。Cinnamon的第二个版本成为了一个独立的桌面环境。Cinnamon的一个优点是,它在界面布局和操作方式上与Windows非常相似。你可以看到,Cinnamon界面底部左侧有一个“菜单”按钮,类似Windows按钮,右侧则有时钟和其他系统小部件,如图1-9所示。菜单的设计与GNOME和Xfce中的菜单相似。

image.png

正如我所提到的,GNOME 3的外观和行为变化引发了一些关注。有些人可能认为这还算轻描淡写,毕竟一些发行版的回归到其他外观可以视为这一点的证据。这包括Kali Linux中最新实现的GNOME。无论如何,Cinnamon是对GNOME 3的一种回应,它创建了一个基于GNOME 3架构之上的桌面界面。另一方面,MATE则是GNOME 2的一个分支。对于那些熟悉GNOME 2的人来说,MATE将显得十分熟悉。它实现了GNOME 2的经典外观。你可以在图1-10中看到它在Kali中的运行效果。同样,菜单已经展示出来,你可以看到在所有桌面环境中都能轻松访问应用程序。尽管Xfce、Cinnamon、GNOME和其他桌面环境随着时间的推移不断发展其外观,MATE在Kali中的实现看起来几乎和最初发布时一样。

image.png

桌面环境的选择完全是个人偏好的问题。这里有一个我没有提到,但依然是一个非常不错的选择——K桌面环境(KDE)。我没有提到它有两个原因。首先,我一直觉得KDE比较“重”,尽管随着GNOME 3及其带来的众多软件包,情况有所改善。KDE给我的感觉从未像GNOME或Xfce那样快速。然而,许多人还是喜欢它。其次,我没有包含它的截图,因为它看起来像某些版本的Windows以及一些其他的Linux桌面环境。KDE的一个目标似乎一直是克隆Windows的外观和体验,这样来自Windows平台的用户就能感觉更舒适。

如果你打算认真开始使用Kali并与之合作,可能需要花些时间去尝试不同的桌面环境。重要的是你要感到舒适,并能高效地在界面中操作。如果你发现某个桌面环境让你感到不便,或者难以导航,那么它可能不适合你。你可以尝试其他的桌面环境,安装新的桌面环境其实非常简单。当我们稍后讲到软件包管理时,你将学习如何安装额外的软件包,也就是桌面环境。你甚至可能会发现一些不在本讨论中的桌面环境。

使用命令行

在本书的过程中,你会发现我非常喜欢使用命令行。之所以如此,有很多原因。首先,我开始接触计算机时,终端并不像现在这样有“全屏”功能,我们也根本没有桌面环境。老实说,我第一次接触计算机时是用的无显示屏的电传打字机。当我们有了显示屏时,它主要显示的是命令行。因此,我很快就习惯了打字。当我开始使用Unix系统时,所有的操作都只能通过命令行完成,所以我需要熟悉那里可用的命令集。

另一个习惯使用命令行的原因是,你不总是能得到一个图形用户界面(GUI)。你可能在远程工作,连接到一个网络,这时你可能只能通过命令行程序进行操作,而无需额外的工作。因此,学会与命令行打交道是很有用的。

另一个习惯使用命令行和理解程序元素所在位置的原因是,GUI程序可能会出现故障,或者遗漏一些可能有帮助的细节。这对于一些安全或取证工具尤其如此。举个例子,我更喜欢使用命令行工具集——The Sleuth Kit (TSK) ,而不是它的基于Web的界面Autopsy,后者是更具视觉化的界面。由于Autopsy是基于TSK构建的,它只是以不同的方式展示TSK能够生成的信息。差别在于,使用Autopsy时,你不会获得所有的细节,尤其是那些相对较低级的细节。如果你正在学习如何执行任务,了解实际发生了什么可能比学习一个GUI更有帮助。你的技能和知识将更具迁移性,能应用到其他情境和工具中。所以,这是另一个理由。

用户界面(UI)通常被称为shell(外壳)。无论你指的是管理桌面的程序,还是那个接收你输入命令并在终端窗口中执行的程序,这个词都适用。Linux中默认的shell很长一段时间以来都是Bash(Bourne Again Shell),几乎所有的Linux发行版都使用它。这个名字是对早期并长期存在的Bourne Shell的戏谑。不过,Bourne Shell有一些局限性和缺失的功能,因此,在1989年,Bash被发布。此后,它成为Linux发行版中常用的shell。你将在命令行中执行两种类型的命令:一种是内建命令。这是一种shell本身的功能,shell自己处理,无需调用其他程序;另一种是程序命令,它是存储在某个目录中的程序。shell有一个目录列表,存储着程序的位置,并通过一个环境变量提供(以及可配置)。

目前,Kali Linux的默认shell是Z Shell (zsh) 。这个shell基于Bash,但包含了许多增强功能。在大多数情况下,你不会注意到很多区别,特别是在运行命令时,几乎没有差异。Zsh shell包括许多自定义选项,尤其是在命令行自动完成以及提示符的表示方式上。Kali使用Zsh的默认提示符如图1-11所示。

image.png

注意
请记住,Unix是由程序员为程序员开发的。其目的是创建一个对程序员既舒适又有用的环境。因此,shell在某种程度上是一个编程语言和环境。每个shell有不同的控制语句语法,但你可以直接在命令行上编写程序,因为作为编程语言,shell能够执行所有语句。

简而言之,我们将花些时间使用命令行,因为它是Unix的起源所在,同时也是非常强大的。首先,你需要浏览文件系统并获取文件列表,包括权限等详细信息。其他有用的命令是那些管理进程和一般工具的命令。

文件和目录管理

首先,让我们谈谈如何让shell告诉你当前所在的目录。这被称为工作目录。要获取工作目录,我们使用命令 pwd,它是 "print working directory"(打印工作目录)的缩写。在示例1-1中,你可以看到提示符,它以$结尾,通常表示普通用户。如果提示符以#结尾,则表示超级用户(root用户)。$结束提示符,后面是输入并执行的命令,接下来在下一行显示命令的结果或输出。

示例1-1:打印工作目录

┌──(kilroy@badmilo)-[~]  
└─$ pwd  
/home/kilroy

注意
当你拥有多个物理或虚拟机器时,你可能会觉得为系统命名取个主题会很有趣。我认识的人中,有些给他们的系统起了《银河系漫游指南》中的角色名字。我也见过用硬币、行星和其他各种主题的命名。多年来,我的系统一直是以Bloom County中的角色命名的。这里的Kali系统就以Milo Bloom命名。

一旦我们知道了自己在文件系统中的位置(通常从根目录/开始,当以图形方式显示时,像树的根部),我们就可以获取文件和目录的列表。你会发现,Unix/Linux命令通常使用最少的字符。要获取文件列表,可以使用命令ls。虽然ls非常有用,它只列出文件和目录的名称。如果你需要关于文件的更多细节,包括时间、日期以及权限,可以使用命令ls -la。其中,l(小写字母L)表示长格式列出,包括详细信息;a表示显示所有文件,包括隐藏文件。你可以在示例1-2中看到输出结果。

示例1-2:获取长格式的文件列表

┌──(kilroy@badmilo)-[~]  
└─$ ls -la  
total 192  
drwx------ 19 kilroy kilroy  4096 Jun 17 18:54 .  
drwxr-xr-x  3 root   root    4096 Jun  3 07:17 ..  
-rw-r--r--  1 kilroy kilroy   220 Jun  3 07:17 .bash_logout  
-rw-r--r--  1 kilroy kilroy  5551 Jun  3 07:17 .bashrc  
-rw-r--r--  1 kilroy kilroy  3526 Jun  3 07:17 .bashrc.original  
drwxr-xr-x  8 kilroy kilroy  4096 Jun  3 18:24 .cache  
drwxr-xr-x 13 kilroy kilroy  4096 Jun 13 17:37 .config  
drwxr-xr-x  2 kilroy kilroy  4096 Jun  3 07:26 Desktop  
-rw-r--r--  1 kilroy kilroy    35 Jun  3 07:44 .dmrc  
drwxr-xr-x  2 kilroy kilroy  4096 Jun  3 07:26 Documents  
drwxr-xr-x  5 kilroy kilroy  4096 Jun 12 19:21 Downloads  
-rw-r--r--  1 kilroy kilroy 11759 Jun  3 07:17 .face  
lrwxrwxrwx  1 kilroy kilroy     5 Jun  3 07:17 .face.icon -> .face  
drwx------  3 kilroy kilroy  4096 Jun  3 07:26 .gnupg  
-rw-------  1 kilroy kilroy     0 Jun  3 07:26 .ICEauthority  
drwxr-xr-x  3 kilroy kilroy  4096 Jun 11 19:25 .ipython  
drwxr-xr-x  4 kilroy kilroy  4096 Jun 11 12:04 .java  
-rw-------  1 kilroy kilroy    34 Jun 17 18:53 .lesshst  
drwxr-xr-x  4 kilroy kilroy  4096 Jun  3 07:26 .local  
drwx------  4 kilroy kilroy  4096 Jun  3 18:24 .mozilla  
drwxr-xr-x  2 kilroy kilroy  4096 Jun  3 07:26 Music  
-rw-r--r--  1 kilroy kilroy    33 Jun 17 18:54 myhosts  
drwxr-xr-x  2 kilroy kilroy  4096 Jun  3 07:26 Pictures  
-rw-r--r--  1 kilroy kilroy   807 Jun  3 07:17 .profile  
drwxr-xr-x  2 kilroy kilroy  4096 Jun  3 07:26 Public  
-rw-r--r--  1 kilroy kilroy    37 Jun  3 18:28 pw.txt  
-rw-r--r--  1 kilroy kilroy 28672 Jun 17 15:51 .scapy_history  
-rw-r--r--  1 kilroy kilroy     0 Jun  3 07:26 .sudo_as_admin_successful  
drwx-r-xr-x  2 kilroy kilroy  4096 Jun  3 07:26 Templates  
drwx-r-xr-x  2 kilroy kilroy  4096 Jun  3 07:26 Videos  
-rw-------  1 kilroy kilroy   948 Jun 17 18:54 .viminfo  
drwx-r-xr-x  3 kilroy kilroy  4096 Jun 11 12:02 .wpscan  
-rw-------  1 kilroy kilroy    52 Jun 13 17:23 .Xauthority  
-rw-------  1 kilroy kilroy  5960 Jun 17 18:36 .xsession-errors  
-rw-------  1 kilroy kilroy  5385 Jun 12 19:23 .xsession-errors.old  
drwx-r-xr-x 20 kilroy kilroy  4096 Jun 11 13:55 .ZAP  
-rw-------  1 kilroy kilroy  2716 Jun 14 18:47 .zsh_history  
-rw-r--r--  1 kilroy kilroy 10868 Jun  3 07:17 .zshrc  

从左边的列开始,你可以看到权限。Unix有一套简单的权限体系。每个文件或目录都有一组权限,分别与文件的用户所有者、文件所属的组以及所有其他人的权限相关,后者称为“world”。目录用d表示在最前面的位置。其他可用的权限有读取、写入和执行。在类Unix操作系统中,一个程序通过设置执行位来决定它是否可以执行。这与Windows不同,Windows依赖文件扩展名来决定文件的可执行性。执行位不仅决定文件是否可执行,还决定谁可以执行它,具体取决于执行位设置在哪个类别中(用户、组、世界)。

Linux文件系统结构

Linux文件系统,与之前的Unix文件系统一样,采用了一种常见的布局。不管你系统中安装了多少个磁盘,所有内容都会归属于根目录(/)。Linux系统中的常见目录如下所示:

  • /bin
    存放系统启动时需要的命令/二进制文件,这些文件在单用户模式下也必须可用。
  • /boot
    存放启动文件,包括启动加载程序的配置、内核以及启动内核所需的初始内存磁盘文件。
  • /dev
    一个伪文件系统,包含硬件设备的条目,供程序访问。
  • /etc
    操作系统和系统服务的配置文件。
  • /home
    用户的家目录所在目录。
  • /lib
    包含共享代码和函数的库文件,任何程序都可以使用。
  • /opt
    用于存放可选的第三方软件。
  • /proc
    一个伪文件系统,包含与正在运行的进程相关的文件夹,诸如内存映射、运行该程序的命令行以及其他与程序相关的系统信息。
  • /root
    根用户的家目录。
  • /sbin
    系统二进制文件,单用户模式下也必须可用。
  • /tmp
    存放临时文件。
  • /usr
    只读的用户数据(包括bin、doc、lib、sbin和share子目录)。
  • /var
    可变数据,包含关于正在运行的进程的状态信息、日志文件、运行时数据和其他临时文件。所有这些文件在系统运行过程中会发生大小或存在变化。

你还可以看到每个文件或目录的所有者(用户)和所属的组,在这些例子中,所有者和组都是root。接着是文件的大小、最后修改的时间,然后是文件或目录的名称。你可能会注意到有些文件名前有一个点(.)。这些以点开头的文件和目录存储的是用户特定的设置和日志。因为这些文件由创建它们的应用程序管理,通常它们会被隐藏在普通的目录列表中。

touch命令可以用来更新文件的修改时间为执行touch命令时的时间。如果文件不存在,touch会创建一个空文件,并将修改和创建时间戳设置为执行touch时的时间。

与文件和目录相关的其他非常有用的命令是那些用于设置权限和所有者的命令。每个文件和目录都有一组权限,如前所述,并且有一个所有者和一个组。要设置文件或目录的权限,可以使用chmod命令,它可以接受每个可能权限的数字值。三个位用于表示权限,每个位要么为开(1),要么为关(0),表示权限是否被设置。你可以把权限的顺序理解为从最少权限到最大权限:读、写、执行。然而,由于最重要的位在前面,读权限的值是这三个值中最高的。读的值为4,写的值为2,执行的值为1。例如,如果你想为文件设置读和写权限,可以使用4 + 2,即6。位模式则是110,可能更容易理解。

有三组权限:所有者、组和其他(即所有人)。设置权限时,你需要为每个组指定一个数字值,也就是说,你将有一个三位数的值。例如,要为所有者设置读、写和执行权限,而只为组和其他用户设置读权限,你可以使用chmod 744 filename,其中filename是你设置权限的文件名。你也可以只指定要设置或取消的位。如果更方便,你可以使用chmod u+x filename为所有者添加可执行权限。

Linux文件系统一般结构清晰,因此你可以很容易地找到文件的位置。然而,在某些情况下,你可能需要搜索文件。在Windows或macOS中,你可能了解如何寻找文件,因为必要的工具已嵌入在文件管理器中。如果你是在命令行中工作,你需要知道如何定位文件。首先是locate,它依赖于一个系统数据库。updatedb程序将更新该数据库,当你使用locate时,系统会查询该数据库来找到文件的位置。

如果你在找一个程序,可以使用另一个工具。which命令可以告诉你程序的位置。如果你有多个位置存放可执行文件,这个命令很有用。注意,which会使用用户环境中的PATH变量来搜索程序。如果可执行文件在PATH中找到,它会显示该程序的完整路径。如果在PATH中有多个相同文件名的实例,which只会显示第一个找到的。

一个更为多功能的定位工具是find。虽然find有很多功能,但最简单的方法是使用像find / -name foo -print这样的命令。你不必提供-print参数,因为打印结果是默认行为;这是我学习运行这个命令时的方式,之后一直沿用。使用find时,你需要指定要搜索的路径。find执行递归搜索,意味着它从指定目录开始,搜索该目录下的所有子目录。在上面的例子中,我们正在寻找名为foo的文件。你可以在搜索中使用正则表达式,包括通配符。如果你想找到以foo开头的文件,可以使用find / -name "foo*" -print。在示例1-3中,你可以看到使用find命令在/etc目录中定位文件。你会看到一些权限拒绝的错误,这源于搜索那些属于其他用户且没有为其他用户设置读取权限的目录。如果你使用搜索模式,需要将字符串和模式放在双引号中。虽然find有很多功能,但这能帮助你入门。

示例1-3. 使用find

┌──(kilroy@badmilo)-[/etc]
└─$ find . -name catalog.xml
find: './redis': Permission denied
find: './ipsec.d/private': Permission denied
find: './openvas/gnupg': Permission denied
find: './ssl/private': Permission denied
find: './polkit-1/localauthority': Permission denied
find: './polkit-1/rules.d': Permission denied
./vmware-tools/vgauth/schemas/catalog.xml
find: './vpnc': Permission denied

进程管理

当你运行一个程序时,你启动了一个进程。你可以将进程看作是程序的一个动态、正在运行的实例,而程序本身则是静态的,存储在某个存储介质上。每个运行中的 Linux 系统在任何给定时刻都有数十个或数百个进程在运行。在大多数情况下,你可以期待操作系统会以最佳方式管理这些进程。然而,有时你可能需要亲自介入。例如,你可能想检查某个进程是否正在运行,因为并不是所有进程都在前台运行。前台进程是指目前用户可以看到并与之交互的进程,而后台进程则是用户无法交互的,除非它被带到前台,并且设计上支持用户交互。例如,检查一个空闲的 Kali Linux 系统上运行的进程数时,我发现总共有 141 个进程,只有一个在前台运行,其余的都是某种服务。

要查看进程列表,你可以使用 ps 命令。这个命令本身仅列出当前用户所属的进程。每个进程,就像文件一样,也有一个所有者和一个组。原因是进程需要与文件系统和其他对象交互,而操作系统通过所有者和组来判断该进程是否有权访问这些资源。在示例 1-4 中,你可以看到运行 ps 命令的结果。

示例 1-4:获取进程列表

┌──(kilroy@badmilo)-[~]
└─$  ps
  PID TTY          TIME CMD
 4068 pts/1    00:00:00 bash
 4091 pts/1    00:00:00 ps

在示例 1-4 中,你看到的是进程的标识号,通常称为进程 ID(PID),后面跟着命令发出所在的终端(TTY)、占用处理器的时间,以及执行的命令。你将看到大多数命令后面都有一些可以附加到命令行的参数,这些参数会改变程序的行为。

手册页

历史上,Unix 手册一直可以在线获取,即直接在机器上查看。要获取任何命令的文档,你可以运行 man 命令,后面跟上你想查找文档的命令。这些手册页(man pages)使用一种叫做 troff 的排版语言进行格式化。因此,当你阅读 man 页时,它看起来像是为打印而格式化的,这也基本上是事实。如果你需要帮助查找相关的命令行参数,以获得你想要的行为,可以通过手册页获取详细信息。手册页还会提供与该命令相关的其他命令和信息。

Unix 手册被分为以下几个部分:

  1. 常用命令
  2. 系统调用
  3. 库函数
  4. 特殊文件
  5. 文件格式
  6. 游戏和屏幕保护程序
  7. 其他杂项
  8. 系统管理命令和守护进程

当相同的关键字在多个区域中都出现时,例如 open,你可以指定你要查看的部分。例如,要查看系统调用 open 的文档,你可以使用命令 man 2 open。如果你还需要了解相关命令,可以使用 apropos 命令,比如 apropos open,这会列出所有相关的手册条目。

有趣的是,AT&T Unix 与 BSD Unix 有一些差异,这导致了命令行参数的变化,具体取决于你使用的 Unix 版本。为了获取更详细的进程列表,包括所有用户的进程(因为默认情况下只显示当前用户的进程),你可以使用 ps -eaps aux。两者都会提供完整的列表,但在细节上会有所不同。

使用 ps 的一个问题是它是静态的:你运行一次命令,就得到一个进程列表。如果你想实时查看进程列表的变化,可以使用另一个程序。尽管你也可以使用 ps 获取像内存和处理器使用情况这样的统计信息,但通过 top 命令,你不需要额外请求它。运行 top 命令会定期刷新进程列表。你可以在示例 1-5 中看到 top 命令的输出示例。

示例 1-5:使用 top 获取进程列表

top - 21:54:53 up 63 days,  3:20,  1 user,  load average: 0.00, 0.00, 0.00
Tasks: 253 total,   1 running, 252 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.1 us,  0.0 sy,  0.0 ni, 99.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :  64033.1 total,   2912.2 free,   1269.2 used,  59851.7 buff/cache
MiB Swap:   8192.0 total,   8180.7 free,     11.2 used.  62114.3 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 419627 kilroy    20   0    7736   3864   3004 R   0.3   0.0   0:00.02 top
      1 root      20   0  167732  12648   7668 S   0.0   0.0   1:08.01 systemd
      2 root      20   0       0      0      0 S   0.0   0.0   0:00.47 kthreadd
      3 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 rcu_gp
      4 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 rcu_par+
      5 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 slub_fl+

除了提供进程列表、它们占用的内存和 CPU 百分比等信息外,top 还会显示关于运行系统的详细信息,每次刷新时,进程列表会重新排序,显示哪些进程消耗了最多的资源。正如你所注意到的,top 本身也会消耗一些资源,你通常会看到它位于进程列表的顶部。你会注意到,PID(进程标识号)是一个非常重要的字段,它提供了明确区分不同进程的方式,尤其是在多个进程名称相同的情况下,同时它也可以用来向进程发送消息。

终止进程

当你管理进程时,有两个命令非常有用。它们密切相关,执行相同的功能,尽管提供的功能略有不同。第一个命令是 kill,顾名思义,它可以终止一个运行中的进程。更具体地说,它向进程发送一个信号。操作系统通过向进程发送信号来与进程进行交互。信号是进程间通信(IPC)的一种方式。kill 命令的默认信号是 TERM 信号(SIGTERM),表示终止,但如果你指定其他信号,kill 会发送那个信号。

要发送一个不同的信号,你可以使用 kill -# pid 命令,其中 # 是你要发送的信号编号,pid 是进程 ID,你可以通过使用 pstop 获取。

信号

系统的信号定义在 C 头文件中。要查看所有信号及其编号和信号的助记符标识符,最简单的方法是运行 kill -l 命令,输出如下:

┌──(kilroy@badmilo)-[~]
└─$  sudo kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL
 5) SIGTRAP      6) SIGABRT      7) SIGBUS       8) SIGFPE
 9) SIGKILL     10) SIGUSR1     11) SIGSEGV     12) SIGUSR2
13) SIGPIPE     14) SIGALRM     15) SIGTERM     16) SIGSTKFLT
17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU
25) SIGXFSZ     26) SIGVTALRM   27) SIGPROF     28) SIGWINCH
29) SIGIO       30) SIGPWR      31) SIGSYS

常用的信号包括:

  • SIGTERM(15):请求进程正常终止。进程可以选择忽略或处理此信号。
  • SIGKILL(9):强制进程终止。进程不能忽略或处理此信号。
  • SIGINT(2):表示中断,通常由用户发出,通常通过按 Ctrl + C 来发送。

kill 命令示例

终止一个进程:

kill 1234

强制终止一个进程:

kill -9 1234

第二个你应该熟悉的命令是 killallkillkillall 的区别在于,使用 killall 时你不一定需要进程 ID(PID)。相反,你可以使用进程的名称。这在某些情况下非常有用,特别是当父进程可能创建了多个子进程时。如果你想同时杀死所有这些子进程,可以使用 killall,它会自动查找进程表中的 PID 并向进程发送适当的信号。就像 kill 命令一样,killall 也可以指定要发送的信号编号。如果你需要强制杀死所有名为 firefox 的进程实例,比如,你可以使用 killall -9 firefox

其他工具

显然,我们不会逐一讨论 Linux 命令行上所有可用的命令。然而,有一些额外的命令是你应该了解的。请记住,Unix 的设计理念是提供一些简单的工具,这些工具可以组合在一起使用。它通过三个标准的输入/输出流来实现这一点:STDIN、STDOUT 和 STDERR。每个进程在启动时都会继承这三个流。输入通过 STDIN 进入,输出通过 STDOUT 输出,错误信息则通过 STDERR 输出,虽然这可能不需要特别说明。这样做的好处是,如果你不想看到错误信息,你可以将 STDERR 流重定向到其他地方,从而避免让正常输出被错误信息干扰。

每个流都可以被重定向。通常,STDOUT 和 STDERR 会输出到同一个地方(通常是控制台)。而 STDIN 则来自控制台。如果你希望将输出重定向到其他地方,可以使用 > 操作符。例如,如果我想将 ps 命令的输出保存到一个文件中,我可以使用 ps auxw > ps.out。这将 ps 命令的输出发送到名为 ps.out 的文件中。重定向输出后,你就不会在控制台上看到输出了。举例来说,如果发生了错误,你会看到错误信息,但不会看到 STDOUT 的输出。如果你想重定向输入,你可以使用 < 操作符,表示输入的流向。

理解不同的 I/O 流和重定向将有助于你理解 |(管道)操作符。当你使用 | 时,你是在说:“将左侧输出的内容传递给右侧的输入。” 你实际上是将两个应用程序之间建立了一个耦合器,将 STDOUT 传递给 STDIN,而不需要经过任何中间设备。

命令链或管道的一个最有用的功能是用于搜索或过滤。例如,如果你有一个来自 ps 命令的长列表进程,你可以使用管道操作符将 ps 的输出传递给另一个程序 grepgrep 可以用来搜索特定的字符串。举个例子,如果你想查找所有名为 httpd 的进程实例,可以使用 ps auxw | grep httpdgrep 命令用于搜索输入流中的字符串。虽然它在过滤信息时非常有用,但你也可以使用 grep 搜索文件中的内容。举个例子,如果你想在某个目录中的所有文件中搜索字符串 wubble,你可以使用 grep wubble *。如果你希望搜索遍历所有子目录,你可以让 grep 进行递归搜索,使用 grep -R wubble *

用户管理

虽然 Kali 以前默认是以 root 用户登录,但在多个版本中已经发生了变化。和其他 Linux 发行版一样,你将被要求创建一个用户账户,并使用该账户进行登录。此用户可以通过 sudo 工具临时获取超级用户权限。你的用户将被添加到 sudo 组中,这是必要的,因为你在 Kali 中进行的许多操作都需要管理员权限。

你可能还希望在 Kali 中添加和管理其他用户,和其他发行版一样。如果你想创建一个用户,可以使用 useradd 命令,也可以使用 adduser。这两个命令的作用是一样的。当你创建用户时,了解用户的一些基本特性会很有帮助。至少,每个用户应该有一个家目录、一个 shell、一个用户名和一个组。例如,如果我想添加一个常用的用户名,我可以使用如下命令:

useradd -d /home/kilroy -s /bin/bash -g users -m kilroy

这个命令中的参数指定了家目录、用户登录时应该执行的 shell 以及默认的组。-m 参数表示 useradd 会创建家目录,并将交互式登录所需的骨架文件放入家目录。

关于指定的组 ID,useradd 要求该组已经存在。如果你希望用户拥有自己的组,可以使用 groupadd 创建一个新组,然后使用 useradd 创建属于该组的用户。如果你想将用户添加到多个组中,可以编辑 /etc/group 文件,将用户添加到你希望用户成为成员的每个组的末尾。这很容易做,但其他工具,如 usermod 也可以将用户添加到指定的组中。为了获得与这些组访问文件相关的权限,你需要注销并重新登录,这样系统会应用你对用户所做的更改,包括新加入的组。

一旦创建了用户,你应该设置一个密码,可以使用 passwd 命令。如果你是 root 并且想要更改另一个用户的密码,可以使用 passwd kilroy(以我们前面创建的用户为例)。如果你不指定用户名,直接使用 passwd,则会更改你自己的密码。

提示

Z shell(zsh)取代了 Bourne Again Shell(bash)作为默认 shell。然而,其他 shell 也可以使用。如果你喜欢尝试不同的东西,可以查看其他 shell,如 bash、fish、csh 或 ksh。bash shell 的行为与 zsh 类似。如果你喜欢实验,其他 shell 可能会提供一些有趣的功能。如果你希望永久更改自己的 shell,可以编辑 /etc/passwd 文件,或使用 chsh 命令来更改你的默认 shell。

服务管理

长期以来,服务管理有两种风格:BSD 风格和 AT&T 风格。但现在已经不再如此,当前有三种管理服务的方式。在我们深入探讨服务管理之前,我们首先需要定义一下“服务”。在这个上下文中,服务是指在没有用户干预的情况下运行的程序。操作系统环境会自动启动它,并且它在后台运行。除非你查看进程列表,否则你可能根本不知道它在运行。大多数系统随时都有大量的服务在运行。它们被称为“服务”,因为它们为系统、用户或远程用户提供服务。

由于这些服务没有直接的用户交互,因此通常需要一种方法来启动和终止这些服务,并且该方法应能在系统启动和关闭时自动调用。通过服务管理工具,用户还可以使用同样的工具来启动、停止、重启服务,并获取这些服务的状态。

注意

服务是系统级别的,管理它们需要管理员权限。你需要是 root 用户,或者使用 sudo 获得临时的 root 权限,才能执行服务管理操作。

AT&T Init 启动过程

通常,Linux 发行版采用了 AT&T 的 init 启动过程。这意味着服务是通过一组脚本运行的,这些脚本会接受标准参数。init 启动系统使用运行级别(runlevel)来决定启动哪些服务。单用户模式会启动一组不同的服务,而多用户模式会启动另一组服务。当使用显示管理器时,还会启动更多的服务,以为用户提供图形界面。这些脚本存储在 /etc/init.d/ 目录下,并且可以通过提供参数(如 start、stop、restart、status)来管理。例如,如果你想启动 SSH 服务,可以使用命令 /etc/init.d/ssh start

然而,init 系统的问题在于它通常是串行的。这导致系统启动时的性能问题,因为每个服务会按顺序启动,而不是多个服务同时启动。init 系统的另一个问题是它对服务间的依赖支持不好。通常,一个服务会依赖其他需要先启动的服务。

systemd 的出现

systemd 是由 Red Hat 的软件开发人员开发的。systemd 的目标是提高 init 系统的效率,克服其一些缺点。服务可以声明依赖关系,并且服务可以并行启动。现在不再需要编写 bash 脚本来启动服务,而是使用配置文件,所有服务管理都通过 systemctl 工具来处理。

要使用 systemctl 管理服务,可以使用以下格式:

systemctl verb service

其中,verb 是你传递的命令,service 是服务的名称。例如,如果你想启用并启动 SSH 服务,可以执行如下命令:

示例 1-6. 启用并启动 SSH 服务

┌──(kilroy@badmilo)-[~]
└─$  sudo systemctl enable ssh
Synchronizing state of ssh.service with SysV service script with
/lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable ssh
┌──(kilroy@badmilo)-[~]
└─$  sudo systemctl start ssh

首先,你启用服务:告诉系统在启动时启用此服务。服务在启动时使用的不同模式配置文件存储在与该服务相关的配置文件中。每个服务都有一个配置文件。systemd 不再像旧的 init 系统那样使用运行级别,而是使用目标(target)。目标本质上与运行级别相似,表示系统的某种特定操作模式。以下是 smartd 服务的脚本示例,它用于管理存储设备。

示例 1-7. 配置 systemd 服务

$ cat smartd.service
[Unit]
Description=Self Monitoring and Reporting Technology (SMART) Daemon
Documentation=man:smartd(8) man:smartd.conf(5)

# Typically, physical storage devices are managed by the host physical machine
# Override it if you are using PCI/USB passthrough
ConditionVirtualization=no

[Service]
Type=notify
EnvironmentFile=-/etc/default/smartmontools
ExecStart=/usr/sbin/smartd -n $smartd_opts
ExecReload=/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target
Alias=smartd.service

在这个脚本中,Unit 部分指明了服务的要求、描述以及文档;Service 部分指明了服务如何启动和管理;Install 部分指定了该服务将使用的目标。在这个例子中,smartd 服务在 multi-user.target 目标下启动。

Kali 使用基于 systemd 的系统进行初始化和服务管理,因此你主要会使用 systemctl 来管理服务。在少数情况下,某些已安装的服务可能不支持 systemd。在这种情况下,你会将服务脚本安装到 /etc/init.d/ 目录,并需要在那里调用脚本来启动和停止服务。不过,这种情况比较少见。

软件包管理

虽然Kali自带了大量的软件包,但并不是所有Kali可以安装的软件包都包含在默认安装中。在某些情况下,你可能需要安装额外的软件包,或者需要更新现有的软件包。无论你打算做什么,管理软件包时,可以使用高级软件包工具(APT)。此外,还有其他管理软件包的方法,你可以使用前端工具,但这些工具最终都只是基于APT的程序。你可以选择任何你喜欢的前端工具,但APT本身非常易于使用,因此学习如何使用APT是很有帮助的。尽管APT是命令行工具,但它依然是一个非常出色的程序。实际上,APT比我见过的一些基于APT的前端工具要更易于使用。

首先,你可能想要更新本地软件包数据库中的所有元数据。这些元数据包含了远程仓库中软件包的详细信息,包括版本号。版本信息是判断你系统中软件是否过时并需要更新的关键。要更新本地软件包数据库,你可以告诉APT执行更新,如示例1-8所示。

示例 1-8:使用apt更新软件包数据库

┌──(kilroy@badmilo)-[~]
└─$  sudo apt update
Get:1 http://kali.localmsp.org/kali kali-rolling InRelease [30.5 kB]
Get:2 http://kali.localmsp.org/kali kali-rolling/main amd64 Packages [15.5 MB]
Get:3 http://kali.localmsp.org/kali kali-rolling/non-free amd64 Packages [166 kB]
Get:4 http://kali.localmsp.org/kali kali-rolling/contrib amd64 Packages [111 kB]
Fetched 15.8 MB in 2s (6437 kB/s)
Reading package lists... Done
Building dependency tree
Reading state information... Done
142 packages can be upgraded. Run 'apt list --upgradable' to see them.

一旦本地软件包数据库更新完成,APT会告诉你是否有已安装的软件包需要更新。在这个例子中,142个软件包需要更新。要更新系统上所有的软件包,你可以使用apt upgrade命令。仅使用apt upgrade会更新所有的软件包。如果你只想更新某个特定的软件包,可以使用apt upgrade packagename,其中packagename是你希望更新的软件包的名称。Debian及其衍生版(包括Kali)使用的打包格式告知APT所需的依赖包。这些依赖关系帮助Kali知道安装某个软件包时需要哪些其他包。对于软件的升级,依赖关系有助于确定软件包应该按照什么顺序进行升级。

如果你需要安装软件,只需要输入apt install packagename命令。依赖关系在这里同样很重要。APT会确定在安装你所要求的软件包之前需要安装哪些其他软件。因此,当你要求安装某个软件时,APT会告诉你还需要安装其他软件。你将看到一份所有所需软件包的列表,并会询问你是否要安装这些软件。你还可能看到一些可选软件包的列表。这些包是与正在安装的软件包相关的,可以选择性安装。可选软件包并不是必需的。

如果你想移除软件包,可以使用apt remove packagename命令。移除软件时的问题之一是,尽管安装时会有依赖关系,但同样的软件包未必会被移除——因为安装后的软件可能会被其他软件包使用。APT会判断哪些软件包不再被使用。当你使用APT执行操作时,它会告诉你某些软件包是否可以被移除。要删除不再需要的包,可以使用apt autoremove命令。

以上操作假设你已经知道你要找的软件包的名称。如果你不完全确定某个软件包的名称,你可以使用apt-cache来搜索软件包。你可以使用部分软件包名称作为搜索关键词,因为有时候软件包的名称可能与预期有所不同。不同的Linux发行版可能会使用不同的名称。例如,在示例1-9中,我搜索了sshd,因为该软件包的名称可能是sshdssh,或者完全不同的名称。你可以看到搜索结果。

示例 1-9:使用apt-cache搜索软件包

┌──(kilroy@badmilo)-[~]
└─$ apt-cache search sshd
fail2ban - ban hosts that cause multiple authentication errors
libconfig-model-cursesui-perl - curses interface to edit config data through Config::Model
libconfig-model-openssh-perl - configuration editor for OpenSsh
libconfig-model-tkui-perl - Tk GUI to edit config data through Config::Model
libnetconf2-2 - NETCONF protocol library [C library]
libnetconf2-dev - NETCONF protocol library [C development]
libnetconf2-doc - NETCONF protocol library [docs]
openssh-server - secure shell (SSH) server, for secure access from remote machines
tinysshd - Tiny SSH server - daemon
zsnapd - ZFS Snapshot Daemon written in python
zsnapd-rcmd - Remote sshd command checker for ZFS Snapshot Daemon

从结果中可以看到,Kali上的SSH服务器软件包似乎是openssh-server。如果该软件包尚未安装,但你想安装它,你就可以使用openssh-server作为软件包名称进行安装。这假设你已经知道系统上安装了哪些软件包。由于安装的软件包数量庞大,你不太可能知道所有已安装的软件包。如果你想查看已安装的软件包,可以使用dpkgdpkg是一个多功能的程序,除了用来从.deb文件安装软件外,还有其他用途。要获取所有已安装软件包的列表,可以使用dpkg --list,这与使用dpkg -l效果相同。两者都会列出所有已安装的软件包。

你将看到返回的列表中不仅包含软件包的名称,还会显示软件包的描述以及安装的版本号。你还会看到该软件包构建时所针对的CPU架构。如果你的CPU是64位,并且安装的是64位版本的Kali,那么大多数软件包的架构将标记为amd64,你也可能看到一些标记为all的软件包,这通常意味着该软件包不包含可执行文件。例如,所有架构的文档包就会标记为all

如果你安装的软件不在Kali仓库中,你仍然可以使用dpkg。如果你找到了一个.deb文件,可以下载它并使用dpkg -i <packagename>来安装它。如果你想移除已安装的软件包,虽然可以使用apt,但你也可以使用dpkg,尤其是在软件包是通过这种方式安装时。要使用dpkg移除软件包,可以使用dpkg -r <packagename>。如果不确定软件包名称,你可以从你使用dpkg获得的已安装软件包列表中找到它。

每个软件包可能包含一组文件,包括可执行文件、文档、默认配置文件和所需的库。如果你想查看一个软件包的内容,可以使用dpkg -c <filename>,其中filename.deb文件的完整名称。在示例1-10中,你可以看到日志管理软件包nxlog的部分内容。该软件包不是Kali仓库的一部分,而是作为社区版的免费下载安装提供的。该软件包的内容不仅包括文件,还包含了文件的权限设置,如文件的所有者和所属组。你还可以看到文件的日期和时间。

示例 1-10:nxlog软件包的部分内容

┌──(kilroy@badmilo)-[~]
└─$ dpkg -c nxlog-ce_3.2.2329_ubuntu22_amd64.deb
drwxr-xr-x root/root         0 2023-04-14 09:14 ./
drwxr-xr-x root/root         0 2023-04-14 09:14 ./etc/
drwxr-xr-x root/root         0 2023-04-14 09:14 ./etc/nxlog/
-rw-r--r-- root/root      1275 2023-04-14 08:49 ./etc/nxlog/nxlog.conf
drwxr-xr-x root/root         0 2023-04-14 09:14 ./lib/
drwxr-xr-x root/root         0 2023-04-14 09:14 ./lib/systemd/
drwxr-xr-x root/root         0 2023-04-14 09:14 ./lib/systemd/system/
-rw-r--r-- root/root       349 2023-04-14 08:49 ./lib/systemd/system/nxlog.service
drwxr-xr-x root/root         0 2023-04-14 09:14 ./usr/
drwxr-xr-x root/root         0 2023-04-14 09:14 ./usr/bin/
-rwxr-xr-x root/root    517232 2023-04-14 09:14 ./usr/bin/nxlog
-rwxr-xr-x root/root    500856 2023-04-14 09:14 ./usr/bin/nxlog-processor
-rwxr-xr-x root/root    455808 2023-04-14 09:14 ./usr/bin/nxlog-stmnt-verifier
drwxr-xr-x root/root         0 2023-04-14 09:14 ./usr/lib/
drwxr-xr-x root/root         0 2023-04-14 09:14 ./usr/lib/nxlog/
drwxr-xr-x root/root         0 2023-04-14 09:14 ./usr/lib/nxlog/modules/
drwxr-xr-x root/root         0 2023-04-14 09:14 ./usr/lib/nxlog/modules/extension/
drwxr-xr-x root/root         0 2023-04-14 09:14 ./usr/lib/nxlog/modules/python/
-rw-r--r-- root/root     15678 2023-04-14 09:14 ./usr/lib/nxlog/modules/python/libpynxlog.a

你需要注意的是,.deb文件格式分发的应用程序通常是为特定的发行版创建的。这是因为创建软件包的人或团队通常知道该发行版可以提供的软件包依赖。其他发行版可能没有适合软件包要求的正确版本。如果是这种情况,软件可能无法正常运行。如果依赖项没有满足,dpkg会报错。你可以通过在命令行中添加--force-install参数来强制安装,但即使软件被安装,也不能保证它能正常工作。

dpkg还有其他功能,能够帮助你查看软件包、查询已安装的软件、以及更多的操作。前面列出的选项足以帮助你入门。鉴于Kali仓库中有大量的软件包,通常你不太可能需要进行外部安装。不过,了解dpkg及其功能仍然是非常有用的。

远程访问

网络计算机提供了远程访问的潜力。Windows 系统主要是为单用户设计的,即一个人坐在计算机前使用,而 Linux 继承了 Unix 的多用户特性(注意,从 Unix 的名字与 Multics 对比中可以看到一丝讽刺)。通常,用户会连接到远程 Unix 系统。多年来(甚至几十年),这通常通过 Telnet 协议进行。Telnet 协议旨在模拟终端通过直接连接到大型计算机进行通信的方式,只是它通过网络而非硬接线的串行连接进行通信。Telnet 可能会让人困惑,因为它不仅是一个协议,还同时是客户端和服务器的名称。由于 Telnet 是明文协议(即数据如用户名和密码没有任何保护地通过网络传输,因此这些数据可能会被截取),如今通常不再使用。

另一方面,SSH(Secure Shell)是加密的。它由 OpenBSD 项目开发,目的是通过加密通道远程连接到系统。与 Telnet 类似,SSH 也使用客户端和服务器。SSH 客户端连接到服务器,启动登录会话。你可以提供登录凭据(用户名和密码),但 SSH 还支持使用密钥进行认证。为了支持加密,SSH 使用公钥和私钥对。这些密钥还可以用于验证客户端对服务器的身份,因为客户端的公钥应仅为密钥拥有者所知。示例 1-11 演示了如何使用 ssh-keygen 生成公钥和私钥对。

示例 1-11:生成公钥/私钥对

kilroy@billthecat:~ $ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/kilroy/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/kilroy/.ssh/id_rsa
Your public key has been saved in /home/kilroy/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:sqFcPJ11x8I/ODJ4xAIer885oam287lZo8Cb36fVvOM kilroy@billthecat
The key's randomart image is:
+---[RSA 3072]----+
|                 |
|           + .   |
|          = * o  |
|     . . = * =   |
|      * S = + o  |
|   . o * . +.. + |
|    o . o .oo.. o|
|        o+oO.+...|
|       .=*B.*+.E.|
+----[SHA256]-----+

理想情况下,你应该为密钥设置一个只有你自己知道的密码,这样可以保护密钥免于被滥用。如果不设置密码并且有人拿到密钥,他们就可以冒充你。要使用密钥进行认证,你需要将公钥复制到远程服务器。你可以使用 ssh-copy-id 自动完成此操作,如示例 1-12 所示。

示例 1-12:将公钥复制到远程服务器

kilroy@billthecat:~ $ ssh-copy-id kilroy@192.168.4.10
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/kilroy/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
kilroy@192.168.4.10's password:
Number of key(s) added: 1

现在尝试登录远程主机:

ssh 'kilroy@192.168.4.10'

如果你没有为密钥设置密码,下一次你通过 SSH 登录远程服务器时,将自动登录。如果为密钥设置了密码,则需要输入密钥的密码,而不是远程服务器的密码,后者应该是不同的。

SSH 还提供了一个常被忽视的非常重要的功能。由于你正在创建一个加密的会话,实际上你在客户端和服务器之间建立了一个隧道。我们可以利用这个隧道功能,将流量从一个系统或一组系统传送到另一个系统。如示例 1-13 所示,你可以创建一个监听器并通过 SSH 会话将本地系统上的 8080 端口的任何连接转发到 www.google.com 的 80 端口。实际上,意味着你连接到本地主机上的 8080 端口,然后流量会通过 SSH 会话发送到 192.168.4.10,并在该端口转发到 www.google.com。返回的流量也通过隧道发送回去。

示例 1-13:设置 SSH 隧道

kilroy@billthecat:~ $ ssh -L 8080:www.google.com:80 192.168.4.10
Welcome to Ubuntu 22.04.4 LTS (GNU/Linux 5.15.0-101-generic x86_64)
Last login: Sat May  4 23:09:52 2024 from 192.168.4.5

<-- separate session here -->
kilroy@billthecat:~ $ telnet 127.0.0.1 8080
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
GET /
HTTP/1.0 200 OK
Date: Sat, 04 May 2024 23:11:18 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=ISO-8859-1
Content-Security-Policy-Report-Only: object-src 'none';base-uri 'self';script-src 'nonce-8jVCtsGFyyU3qD-uOhLDpw' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inline'
Server: gws

此外,还可以创建一个远程隧道,使远程系统的流量回送到本地系统。通过这种 SSH 隧道,你可以将流量从一个系统或网络传送到另一个系统。这种方法可以绕过防火墙,例如,如果你能够通过 SSH 会话连接,但防火墙阻止了 Web 流量。

日志管理

在大多数情况下,如果你在进行安全测试,你可能不需要查看系统上的日志。然而,经过多年的经验,我发现日志是极其宝贵的。尽管 Kali 是一个非常可靠的发行版,但仍然有可能出现问题,你需要进行调查。即使一切正常运行,你可能仍然希望查看应用程序的日志。因此,你需要理解 Linux 中的日志系统。为了做到这一点,你首先需要了解你正在使用的是什么。Unix 长期以来一直使用 syslog 作为系统日志工具,尽管它最初是作为 sendmail 邮件服务器的日志设施而诞生的。

多年来,syslog 已经有了许多不同的实现。Kali Linux 默认没有安装常见的 syslog 实现,但你可以安装一个典型的系统日志工具,如 rsyslog。它的实现非常直接,且很容易确定你需要查看哪些文件来获取日志信息。一般来说,所有日志都存储在 /var/log 目录下。然而,你需要查看特定的文件来找到不同类别的信息。在 Kali 中,你可以查看 /etc/rsyslog.conf 文件。除了看到其他许多配置设置外,你还会看到示例 1-14 中的条目。

示例 1-14:rsyslog 的日志配置

auth,authpriv.*                 /var/log/auth.log
cron.*                          -/var/log/cron.log
kern.*                          -/var/log/kern.log
mail.*                          -/var/log/mail.log
user.*                          -/var/log/user.log

#
# 紧急情况会发送给所有登录的用户。
#
*.emerg                         :omusrmsg:*

在配置文件的左侧,你看到的是设施和严重性级别的组合。点号前面的词是设施名。设施是基于使用 syslog 进行日志记录的不同子系统。你可能注意到,syslog 已经存在了很长时间,因此仍然有一些为旧有子系统和服务定义的设施,今天这些设施你可能不太会看到。在表 1-1 中,你可以看到 syslog 定义的设施列表。如果设施名称本身没有提供详细信息,表中的“描述”列会告诉你该设施的用途。

除了设施名之外,还有严重性值。严重性可以是以下值:紧急(Emergency)、警报(Alert)、严重(Critical)、错误(Error)、警告(Warning)、通知(Notice)、信息(Informational)和调试(Debug)。这些严重性按降序排列,最严重的排在最前面。你可以决定将紧急日志发送到与其他严重性级别不同的地方。在示例 1-14 中,所有严重性日志都发送到与每个设施对应的日志文件。“*”符号表示所有设施。如果你想将 auth 设施中的错误日志发送到特定的日志文件,可以使用 auth.error 并指定你希望使用的文件。

表 1-1:syslog 设施列表

设施编号设施描述
0kern内核消息
1user用户级消息
2mail邮件系统
3daemon系统守护进程
4auth安全/授权消息
5syslogsyslogd 生成的消息
6lpr打印子系统
7news网络新闻子系统
8uucpUUCP 子系统
9Clock daemon时钟守护进程
10authpriv安全/授权消息
11ftpFTP 守护进程
12-NTP 子系统
13-日志审计
14-日志警报
15cron调度守护进程
16local0本地用途 0
17local1本地用途 1
18local2本地用途 2
19local3本地用途 3
20local4本地用途 4
21local5本地用途 5
22local6本地用途 6
23local7本地用途 7

一旦你知道了日志存放的位置,你就需要能够读取它们。幸运的是,syslog 的日志条目足够简单,易于解析。示例 1-15 展示了来自 Kali 系统的 auth.log 文件中的一组日志条目。从条目的左侧开始,你将看到日志条目写入的日期和时间。接着是主机名。由于 syslog 可以将日志消息发送到远程主机(例如中央日志主机),因此主机名在将多个主机的日志写入同一日志文件时非常重要,用于区分不同的日志条目。主机名后是进程名称和 PID。大多数日志条目来自名为 realmd 的进程,进程的 PID 是 803。

示例 1-15:来自 auth.log 的日志条目

May  4 23:09:52 billthecat realmd[803]: successfully joined the domain example.com
May  4 23:09:53 billthecat realmd[803]: disconnected from the domain example.com

通过查看这些日志条目,你可以获得关于系统、进程、事件等的详细信息,这对于故障排除和安全审计非常有用。

示例 1-15:部分 auth.log 内容

2023-05-21T18:14:30.094986-04:00 badmilo sudo: pam_unix(sudo:session): ↩
session closed for user root
2023-05-21T18:15:01.783725-04:00 badmilo CRON[41805]: pam_unix(cron:session): ↩
session opened for user root(uid=0) by (uid=0)
2023-05-21T18:15:01.787913-04:00 badmilo CRON[41805]: pam_unix(cron:session): ↩
session closed for user root
2023-05-21T18:16:59.653896-04:00 badmilo sudo:   kilroy : TTY=pts/0 ; ↩
PWD=/var/log ; USER=root ; COMMAND=/usr/bin/cat auth.log
2023-05-21T18:16:59.654531-04:00 badmilo sudo: pam_unix(sudo:session): ↩
session opened for user root(uid=0) by (uid=1000)

日志的挑战部分并不是前导信息(由 syslog 服务创建和写入),而是应用程序条目。syslog 条目的一个优点是它们通常以英文写成,只要你理解英语并知道格式,就可以阅读这些条目。然而,日志条目的内容是由应用程序本身创建的,这意味着程序员需要调用生成和写出日志条目的函数。一些程序员可能在生成有用且易于理解的日志条目方面比其他人更擅长。一旦你习惯了阅读日志,你将开始理解它们的含义。如果你遇到一个需要但又无法理解的日志条目,搜索引擎通常可以帮助你找到有更好理解的人。或者,你也可以向软件开发团队寻求帮助。

并非所有日志都会通过 syslog 管理,但所有与系统相关的日志都会。即使 syslog 不管理某个应用程序的日志,比如 Apache web 服务器的日志,日志仍然可能位于 /var/log/ 目录下。在某些情况下,你可能需要去寻找这些日志。例如,某些安装到 /opt 目录下的第三方软件可能不使用 syslog,但其日志依然可能位于该目录。

总结

Linux 有着悠久的历史,追溯到资源非常紧张的时代。这导致了一些复杂的命令,旨在让用户(主要是程序员)提高效率。找到一个适合自己的工作环境非常重要,这样你也能在工作中变得更加高效。以下是本章的一些关键要点:

  • Unix 是一个由程序员为程序员创建的环境,使用命令行进行操作。
  • Unix 创建时采用了简单的单一功能工具,这些工具可以组合起来完成更复杂的任务。
  • Kali Linux 提供了多个可安装和使用的图形用户界面(GUI);重要的是找到一个最适合自己的。
  • 每个桌面环境都有很多定制选项。
  • Kali 基于 systemd,因此服务管理使用 systemctl
  • 进程可以通过信号进行管理,包括中断和终止信号。
  • 日志将是你的好帮手,帮助你排除错误。日志通常存储在 /var/log 目录下。
  • 配置文件通常存储在 /etc 目录中,尽管一些个人配置文件会存储在用户的主目录中。

有用的资源

  • 《Linux in a Nutshell, 6th edition》 by Ellen Siever 等(O'Reilly, 2009)
  • 《Practical Linux System Administration》 by Kenneth Hess(O'Reilly, 2023)
  • 《Efficient Linux at the Command Line》 by Daniel J. Barrett(O'Reilly, 2022)
  • Kali Linux 官方网站
  • Linode 上的《Linux System Administration Basics》