单用户模式与Root密码重置

在Linux系统的日常维护中,管理员经常会遇到忘记Root密码或者系统因配置错误无法正常引导的情况。此时,单用户模式(Single-User Mode)就成为了一个至关重要的紧急修复通道。

拦截并进入系统引导菜单

  • 中断内核启动引导:当服务器或虚拟机刚开始启动时,系统会加载GRUB引导加载程序。在屏幕上出现内核启动顺序选择界面时,必须迅速按下键盘上的任意键,打断默认的倒计时自动引导过程。接着,通过键盘的上下方向键,让光标稳定停留在你需要启动的Linux内核项上。

1370907-20191108150022078-2060309953.png

  • 进入内核编辑模式:在选中目标Linux内核启动项后,仔细阅读屏幕下方的操作提示,此时键入小写字母 e,即可进入内核启动参数的编辑界面。

1370907-20191108150110236-1925877185.png

  • 定位核心配置行:在打开的编辑界面中,文本内容可能较多。请使用键盘方向键向下滚动,准确找到以 kernellinux16 作为开头的那一行(通常在配置块的中间偏下位置)。定位后,可以再次按下按键 e 或直接移动光标准备修改参数。

1370907-20191108150135754-1221782718.png

内核启动选项参数深度解析

在内核启动时,我们可以通过追加不同的参数来改变系统的行为状态:

核心启动参数 底层运行含义与应用场景
init=/sbin/init 明确指示Linux内核,在启动的最后阶段使用 /sbin/init 作为系统的第一个用户级进程(PID为1)来接管系统初始化工作。
init=/bin/bash 这是一个极其强硬的截断指令。它会告诉内核跳过所有常规的系统初始化脚本和服务加载,直接启动一个处于内存中的 bash shell 解释器。这在进行紧急系统恢复和底层调试时极为有效。
root=/dev/foo 用于强制重定向根文件系统。它告诉内核不要使用默认配置,而是强制挂载 /dev/foo 所代表的硬件设备作为系统的根(/)目录。
single 指示系统不要进入多用户图形或网络模式,而是直接引导进入只允许单个用户(通常是root)在控制台进行操作的单用户模式。

密码重置的完整实操流程

  • 修改参数并执行引导:使用光标移动到 linux16 这一长行的最末尾,输入一个空格后,加上指令 rw single init=/bin/bashrw表示以读写模式挂载,以便后续修改密码文件)。参数确认无误后,按下 ctrl+x 组合键,系统将根据你刚刚设定的临时参数开始引导。

image.png

  • 应对“环境缺失”报错:当成功进入命令行界面后,如果你急于求成直接输入 passwd root 尝试修改密码,系统很大几率会无情地报错:passwd root command not found

v2-6d1d91ab25ca53b4150ba4926d609dc6_1440w.webp

  • 理解并执行环境切换(chroot):为什么会找不到命令?因为此时你所处的运行环境,仅仅是一个由内存虚拟出来的极简安全模式系统(类似微型WinPE),你还没有真正“进入”服务器硬盘上安装的那个完整的Linux操作系统。为了能够修改真实的root密码,必须执行 chroot /sysroot/ 命令,将根目录从内存临时环境切换到真实的系统根目录下。

v2-82a9d2afab5eb9f771f66ea4ec1f6b1e_1440w.webp

  • SELinux上下文自动重置(极其重要):在通过 passwd 命令成功修改密码后,必须执行一步关键的安全策略恢复操作:运行 touch /.autorelabel 命令。这一步的作用是在根目录下创建一个隐藏的标记文件。当系统重启时,如果SELinux处于开启状态,它会检测到这个文件,并花费一些时间重新为整个文件系统打上正确的安全标签。如果不进行这一步操作,修改密码后的安全上下文错乱将导致你重启后依然无法正常登录操作系统

v2-bee961b3a55adaed99bd2e57cd7e4af9_1440w.webp


Shell

Shell 体系的概念与分类

  • 核心定义:Shell在本质上并不是系统内核的一部分,而是一种特殊的应用程序。它在用户和操作系统内核之间搭建了一座沟通的桥梁,提供了一种交互界面。用户正是通过这个界面输入指令,从而访问并调用操作系统内核所提供的各项底层服务和资源。
  • 两大主要流派
    • 图形界面shell (GUI shell):例如GNOME、KDE等桌面环境,提供窗口、图标等可视化交互方式。
    • 命令行式shell (CLI shell):例如Bash、Zsh等,提供纯文本的字符指令输入与输出环境,是服务器管理的主力工具。

Bash环境下的转义字符与排版控制

在日常的Bash脚本编写和命令行输出(如使用 echo -e)中,转义字符扮演着格式化输出的重要角色。

  • \b (退格符 Backspace)
    • 作用机制:转义后,它的作用相当于你在键盘上按了一次退格键(backspace)。
    • 生效前提:它发挥作用的前提是 \b 后面必须存在其他的输出字符。
    • 示例分析:使用 echo 命令输出时,如果 \b 后面有字符,一个 \b 会将光标回退一格并让后面的字符覆盖掉前一个字符,从而达到“删除前一个字符”的视觉效果。同理,\b\b 则表示删除前两个字符。
    • 如果 \b 后面不存在任何字符,它仅仅将光标回退,但因为没有新字符覆盖,所以看起来并没有转义为“删除”的效果。
  • \c (抑制换行与截断符)
    • 作用机制:表示在此处停止当前行的输出,并且不进行换行操作。
    • 特殊效果:如果 \c 后面仍然紧跟着存在其他字符,那么 \c 后面的所有字符都将被直接丢弃,不会被输出到屏幕上。
    • 等效操作:如果在 \c 后面本来就不存在任何字符了,那么它的作用就等同于在使用 echo 命令时加上了 -n 参数(即 echo -n,输出完内容后光标停留在同一行不换行)。
  • \n\f\v (换行机制群)
    • \n:最常见标准的换行操作,光标移动到下一行的行首。
    • \f:同样执行换行动作,但具有特殊的排版对齐特性。换行后新产生的一行的开头位置,会在垂直方向上严格连接着上一行的行尾位置,形成一种阶梯状的输出效果。
    • \v:在Bash中,它的实际显示效果与 \f 是完全相同的。
  • \t (制表符 Tab)

    • 作用机制:转义后表示在当前光标位置插入一个制表符(tab键),常用于文本的列向对齐排版。
  • \r (回车至行首,覆盖输出)
    • 作用机制:将光标直接强制移动至当前行的最左侧行首,但绝不换行
    • 覆盖效果:由于光标回到了行首但未换行,紧跟在 \r 之后的字符会被输出在当前行,从而覆盖掉 \r 之前已经输出的同等长度的旧字符。
  • \\ (反斜杠本体转义)

    • 作用机制:反斜杠本身是转义符号,当需要输出字符 \ 本身时,需要用两个反斜杠 \\ 来表示,从而消除它的转义语义,将其视为普通字符插入。

伪终端 (Pseudo Terminal / PTY) 架构深度剖析

伪终端的基础定义与组件

伪终端(pseudo terminal,技术上通常简称为 pty)在架构上是由一对字符设备组成的:伪终端 master 端和伪终端 slave 端。

  • Slave 端 (从设备):它对应于文件系统中 /dev/pts/ 目录下的某一个具体设备文件(如 /dev/pts/0)。对于在这个虚拟终端上运行的 CLI (命令行接口) 程序(例如 Bash)来说,slave 端就相当于它们面对的显示器和键盘。
  • Master 端 (主设备):它在操作系统的内存中被标识为一个打开的文件描述符 (fd)。这一端更加贴近真实的用户交互设备(如用户的物理显示器、物理键盘)或者网络连接。
  • 提供方:这对伪终端设备是由“终端模拟器”提供的,而终端模拟器本身仅仅是一个运行在操作系统用户态的普通应用程序,而非底层硬件驱动。

数据流转与转发机制

Linux 内核中的伪终端驱动程序,扮演着这对设备之间“数据搬运工”的角色。

  • 输入流转:驱动程序会将 master 端(例如用户通过图形界面或SSH网络传输过来的键盘敲击数据)写入的数据,原封不动地转发给 slave 端,从而供运行在后端(如Shell)的程序作为标准输入读取。
  • 输出流转:反过来,后端程序(如Shell脚本输出结果)写入 slave 端的数据,驱动程序会将其转发回 master 端,最后由终端模拟器负责读取,并将其渲染到显示器屏幕上供用户观看。

终端桌面程序的运行原理实录

以大多数Linux发行版自带的 GNOME Terminal 为例,它就是一个典型的终端模拟软件。

  • 生命周期开启:当该软件启动时,它会向系统请求打开 /dev/ptmx 这个特殊的复用设备文件。这一动作会在系统中动态创建出一对相互配对的伪终端 master 和 slave 设备。接着,软件会派生一个子进程,让 shell 程序在这个新生成的 slave 端环境中运行。
  • 交互闭环:当用户在 GNOME Terminal 的图形窗口中敲击键盘时,软件会将这些按键事件转化为字节流并写入 master 端。此时,阻塞等待输入的 shell 进程就会从 slave 端读取到这些数据并执行相应的命令。命令执行完毕后,shell 及其子程序的输出内容被写入 slave,传递回 master,最后由 GNOME Terminal 软件将这些字符转换成像素绘制在图形窗口中。

伪终端使用场景

  • 图形界面仿真环境:像 xterm、gnome-terminal 这样的图形界面终端模拟软件,必须依靠伪终端将用户的鼠标键盘GUI事件转换为字符界面的文本输入,同时将程序的纯文本输出转换为图形化窗口内容显示。
  • 网络远程登录中继:在 SSH (如 sshd 服务) 等远程 shell 应用程序中,sshd 进程需要在客户机上的远程物理终端和服务器本地生成的伪终端之间,充当输入和输出数据的网络中继站。
  • 多路复用器隔离与保持:对于 screen 和 tmux 等多路复用应用,它们利用伪终端把输入和输出从一个终端通道转播到另一个或多个终端上。这使得即使实际的网络连接断开(脱离实际的终端),文本模式下的应用程序依然可以挂靠在伪终端上持续运行。

伪终端引入原因

很多人会问:为什么 Linux 不让 shell 等命令行程序直接跨过软件层,去物理显示器和键盘硬件中读取数据呢?

  • 操作系统的虚拟化宏观思想:为了能够在同一个屏幕上同时运行多个独立的终端模拟器窗口,并且为了支持成百上千的用户通过网络并发远程登录,就绝对不能让 shell 独占底层的物理硬件。在虚拟化思想的指导下,为每一个终端模拟器或远程用户分配独立的、互不干扰的虚拟终端是系统的刚需。
  • 模拟真实终端的完备行为:上图中 shell 所对接的 slave 端就是一个高度虚拟化的终端。与之对应的 Master 端负责模拟用户侧的物理交互。之所以不叫它简单的管道而叫“虚拟化的终端”,是因为它除了转发基础的数据流之外,还需要具备处理终端控制字符(如Ctrl+C中断信号、回显控制等)、具有“终端的样子”等复杂能力。
  • 本质总结:伪终端本质上是由运行在用户态的终端模拟程序所创建的一对字符设备。重点在于它是一种用软件在用户空间仿真出来的终端运行环境,这是它与传统物理硬件终端的本质区别所在。

文件系统与路径管理规范

绝对路径与相对路径的严谨定义

在Linux文件系统中,根据文件名书写起点的不同,路径(path)被严格划分为绝对路径(absolute)和相对路径(relative)。

  • 绝对路径 (Absolute Path)

    • 定义特征:绝对路径的写法,必须有且仅有由系统的最顶层——即根目录(/)开始起计算的完整文件或者目录名称构成。
    • 判断标准:绝对路径的写法一定是由 / 目录直接写起的。例如 /home/dmtais/.bashrc,无论用户当前身在系统何处,这个路径指向的位置永远是唯一不变的。
  • 相对路径 (Relative Path)

    • 定义特征:相对路径是相对于用户目前所处的工作目录,推导计算出的目标文件名写法。
    • 判断标准:极其简单,只要路径的开头不是 /,那么它就属于相对路径的写法。(相对路径的写法不是由 / 目录写起的)。例如 ./home/dmtsai 或者是 ../../home/dmtsai

目录导航标识符深入解析

在路径切换和命令执行中,有两个极其特殊的目录概念至关重要:

  • . (当前工作目录):单点号代表当前的所在目录,在执行当前目录下的程序或脚本时,也常常使用 ./ 的形式来明确表示执行位置就在当前。
  • .. (父级目录):双点号代表当前目录的上一层目录,在书写路径时也可以用 ../ 来表示向上一级跳转。
  • 实战操作示例:我们在日常操作中经常下达类似 cd .../command 这样的指令,这就是在代表上一层环境与目前所在目录的工作状态。例如,要求“如何先进入到 /var/spool/mail/ 目录,随后再进入到同级的 /var/spool/lpd/ 目录内”?
    1
    2
    cd /var/spool/mail/            ## 第一步:使用绝对路径精确进入到/var/spool/mail/下
    cd ../lpd/ ## 第二步:利用相对路径的 .. 返回上一层目录(/var/spool/)并直接进入同级的lpd目录

根目录与家目录的区别

  • / 根目录:系统万物的起源。“/”代表了整个Linux文件系统的根目录。Linux的存储管理是以挂载的方式组织起来的,整体架构相当于是一棵倒置的庞大树状结构,而这棵树的源头节点就是“/”,即根目录。
  • ~ 家目录 (Home Directory):“~”符号代表的是用户的家目录,也就是系统分配给每个用户的私人专属领地目录。系统对于不同权限的用户,其家目录的默认分配位置有明确规定:
    • 拥有最高权限的 root 用户的“家”目录通常位于系统顶层的 /root
    • 而普通用户(例如一个名为a的用户),其家目录通常会被统一安放在 /home/a 目录下。

SSH远程登录与安全验证协议体系

SSH协议的两大核心安全验证机制

当我们使用SSH协议进行网络远程登录时,系统主要提供以下两种安全验证机制供选择:

  • 基于口令的安全验证机制 (Password Authentication)

    • 工作原理:这是最传统的登录方式,用户只要知道自己的账户名称和相应的密码口令,就可以发起请求并远程登录到目标主机。
    • 安全缺陷:这种机制存在明显的安全隐患。它不能绝对保证你当前正在连接的网络服务器就是你真正想连接的那台目标服务器。在复杂的网络传输环境中,可能会有恶意的第三方服务器拦截你的请求并进行冒充,这种截获密码的手法即被称为“中间人攻击”。
  • 基于密钥的安全验证机制 (Public-Key Authentication)

    • 工作原理:这是一种安全性极高的无密码登录方式,其安全信任完全依靠非对称加密算法生成的密钥对来维系。用户自己必须事先在本地机器上创建一对密钥(包含一把公钥和一把私钥),然后主动将公钥的内容放置在需要被管理的服务器上。
    • 验证闭环:当客户端准备使用SSH连接到这台服务器时,客服端软件就会自动向服务器发出请求,请求使用你本地隐藏的私钥信息进行高强度的安全验证。服务器收到这个请求后,会先在该服务器目标账户所在的主目录下寻找事先存放的对应公钥,然后将其和网络上发送过来的私钥数字签名进行数学层面的严密比较。如果运算结果完全一致,则视为验证成功,直接放行登录,全程无需输入常规密码。

配置免密码SSH登录的全流程操作

要搭建基于密钥的免密环境,需要执行以下命令操作:

在本地生成专属密钥对

利用 ssh-keygen 工具,你可以进行身份验证密钥的生成、管理和格式转换。

1
ssh-keygen -t rsa // 指定使用强大的RSA算法,配置并生成SSH密钥对至系统的指定文件(如id_rsa)中

img

将本地公钥安全上传至服务端

必须将生成的 .pub 后缀的公钥文件内容,追加到目标服务器对应用户的授权文件列表中。

1
scp  root/.ssh/id_rsa.pub user@ip:/root/.ssh/authorized_keys

(注:上述命令使用scp进行网络复制,实际生产中也常推荐使用 ssh-copy-id 自动化完成配置)


核心系统文件与常见配置

Linux遵循“一切皆文件”的设计理念。理解各大目录的作用和常见配置文件的位置,是掌握Linux系统的必经之路。

根目录及核心一级子目录结构概述

  • /boot:此目录专用于存放自举加载程序(如LILO 或 GRUB)所需的文件。当计算机刚启动时(如果有多个操作系统,有可能允许你选择启动哪一个操作系统),这里的引导文件会首先被装载入内存。这个目录同样会包含极其重要的LINUX内核文件(通常是压缩文件形式,名为 vmlinuz)。不过,LINUX内核其实也可以存在于系统的别处,前提是只要配置了 LILO 并且 LILO 知道LINUX核到底在哪儿就行。
  • /bin:存放系统启动时需要的核心引导程序(二进制执行文件)。这些基础命令文件可以被所有的普通用户无障碍使用。
  • /dev:代表硬件组件的设备文件所在目录。在LINUX的哲学下,所有的硬件设备都被当成普通文件来处理,这样一来底层的硬件就被抽象化了,极大地方便了系统的读写操作、网络共享,以及需要将设备临时装载到文件系统中的操作。正常情况下,每一种设备在这里都会有一个独立的子目录,这些设备的内容会直接出现在独立的子目录下。这也是为什么LINUX没有所谓的C盘、D盘等驱动符概念的原因。
    • /dev/null:黑洞文件,代表没有用的文件所放的位置,作用相当于无限吞噬的回收站,被称为吞噬设备。
    • /dev/zero:用于初始化磁盘的工具设备,会源源不断地产生零值数据流(吐零)。
    • /dev/random:系统的硬件随机数生成器,依赖系统环境噪声构成的熵池。
    • /dev/urandom:非阻塞的伪随机数生成器,同样基于熵池。(当系统的硬件熵池数据耗尽时,系统会自动用软件算法继续生成随机数保证供应)。
  • /etc:集中存放系统及各种软件服务配置文件的核心地带。
  • /etc/rc.d:存放系统启动时运行的各个配置文件和脚本的目录。
  • /home:系统默认的用户主目录基点。包含用户专属的参数设置文件、个性化配置文件、个人文档、数据、EMAIL、缓存数据等。比如用户user的主目录就是 /home/user,在路径中可以用 ~user 来简略表示。
  • /lib:系统的标准程序设计库,又常被叫作动态链接共享库。这些库文件的作用类似于Windows系统里的 .dll 文件,为各个程序提供共享函数支持。
  • /sbin:专门为系统管理员(root)保留的目录,用于存放系统启动时的高级引导程序(二进制执行文件)。这些文件通常不打算被普通用户日常使用(尽管普通用户仍然可以使用它们,但必须在命令前指定完整的绝对目录路径)。
  • /tmp:系统公用的临时文件存储点。该目录具备特殊权限,且该目录内的数据会被系统定期自动清理干净以释放空间。
  • /root:系统最高权限管理员(root)的专属主目录。
  • /mnt:系统专门提供这个空目录,是让用户用来临时挂载其他外部的文件系统(如U盘、外置光驱等)。
  • /lost+found:这个目录在系统平稳运行时平时是空的。当系统不幸遭遇非正常关机(如突然断电)时,修复工具恢复出来的、留下“无家可归”的文件碎片(相当于windows系统下生成的 .chk 文件)就会被统一保存在这里等待人工处理。
  • /var:这是一个动态变化的目录,主要作为某些大文件的溢出区。比方说各种服务的庞大日志文件,它主要包含在系统正常操作运行中被不断改变状态的文件:假脱机文件、系统运行记录文件、加锁文件、缓存临时文件和页格式化文件等。
  • /var/spool:专门用于处理 mail、news、打印机打印队列和其他排队等待处理的工作的目录。每个不同的spool队列服务在 /var/spool 下都有自己的专属子目录。例如,系统中用户的本地邮箱数据就存放在 /var/spool/mail 中。
  • /opt:存放可选的额外安装的应用程序的目录。譬如,在 REDHAT 5.2 系统下的KDE桌面环境曾经安装于此(而在 REDHAT 6.0 系统下,KDE 已经被移动放在其它的 XWINDOWS 应用程序中,其主执行程序位于 /usr/bin 目录下)。
  • /srv:该目录主要用于存放一些特定的网络服务(如Web服务、FTP服务)启动之后,需要向外部提供和提取的公开数据。
  • (分区策略建议):在服务器分区规划时,/home/var/usr/local 这三个目录经常被规划为单独的硬盘分区。这是因为它们的数据经常会被大量操作、写入和删除,独立分区能够防止它们产生的大量磁盘碎片影响到根分区的性能和安全。

/etc 目录下深度配置文件名录

/etc 掌控着整个Linux系统的配置命脉,包含了众多核心配置文件。

  • /etc/passwd:极其重要的系统用户数据库文件。其中的字段域分别给出了系统每个用户的用户名、真实姓名、家目录路径、加密口令标记和用户的其他属性信息。
  • /etc/group:结构类似于 /etc/passwd,但它记录说明的不是单个用户,而是系统的用户组信息数据库。
  • /etc/inittab:老一代系统管理进程 init 的全局配置文件,控制系统的运行级别。
  • /etc/issue:负责在用户面临登录提示符之前输出的提示信息。通常包括系统版本的一段短说明或自定义欢迎信息。其内容可由系统管理员自行编辑确定。
  • /etc/motd:在用户输入密码成功登录系统后,会自动输出展示的文本文件。内容同样由系统管理员确定,经常被用于发布全局通告信息,例如向全体用户发出计划停机关机时间的预先警告。
  • /etc/mtab:动态记录当前系统中已经安装并挂载的文件系统列表。它由系统 scripts 脚本负责初始化建立,并由系统的 mount 命令在每次挂载操作后自动更新维护。当系统程序需要一个当前已安装的文件系统的清单列表时会读取它。例如使用 df 命令检查磁盘空间时,当执行 df –a 时,屏幕上查看到的信息就应当和此文件内容保持一致。
  • /etc/shadow:这是在安装了影子口令安全软件的系统上存在的影子口令文件。为了安全,影子口令软件将原本存放在 /etc/passwd 文件中容易被截获的加密用户口令,移动保存到了 /etc/shadow 这个独立的文件中,而后者有着极其严格的权限,只允许 root 用户具备可读权限。这一隔离机制使得黑客破译口令变得更加困难。
  • /etc/login.defs:系统的 login 登录命令以及用户密码策略相关的配置文件。(同时也是用户密码信息的默认属性控制文件)。
  • /etc/profile , /etc/csh.login , /etc/csh.cshrc:这些是在用户登录系统或启动 Bourne Shell / C shells 时,系统会自动执行的全局环境初始化文件。这允许系统管理员在此处为服务器上的所有登录用户建立统一的全局缺省环境变量。
  • /etc/printcap:结构格式类似于终端控制文件 /etc/termcap,但它是专门针对系统打印机设备属性配置的,语法规则有所不同。
  • /etc/securetty:安全终端确认文件。它明确列出了哪几个特定的终端是允许 root 账户进行登录的。出于安全考量,一般这里只列出本地的虚拟控制台(tty1-tty6等),这样就不可能(或者至少非常困难)让黑客通过调制解调器 modem 或网络远程闯入系统并直接得到超级用户特权。
  • /etc/shells:安全白名单,列出当前系统认为是合法的、可信任的shell程序路径。系统的 chsh 命令允许用户在本文件指定的路径范围内去改变自己默认的登录shell。此外,提供一台机器外部 FTP 服务的服务进程(如ftpd)在用户尝试连接时,会严格检查该用户的默认shell是否列在 /etc/shells 文件中,如果查不到,将直接拒绝不允许该用户登录FTP。
  • /etc/termcap:古老而庞大的终端性能数据库。它负责向系统说明不同型号厂家的终端究竟需要使用什么样的”转义序列”代码来进行控制。程序员在写程序时,不需要直接输出死板的转义序列代码(因为这样写出来的程序只能工作于特定某个品牌的终端设备上),而是从 /etc/termcap 中查找要做的工作所需的正确序列指令。有了这个抽象层,多数的文本程序就可以在世界上绝大多数终端设备上兼容运行。
  • /etc/inputrc:控制键盘输入设备映射与快捷键的配置文件。
  • /etc/default/useradd:在使用 useradd 命令添加新用户时,系统读取的默认基础属性信息的文件。
  • /etc/skel:存放新建立用户家目录初始化信息的骨架(Skeleton)目录。新建用户时,系统会将该目录下的隐藏配置文件复制到新用户的家目录中。
  • /sbin/nologin:一个特殊的伪shell,当用户在 /etc/passwd 中的shell被设置为此路径时,表示该账户是不能直接登陆系统的服务型用户。
  • /var/log/message:系统非常核心的通用日志文件,记录各种守护进程产生的消息。
  • (关于全局环境变量的配置):如果你希望全系统可用某个软件,可以在 /etc/profile 这个全局配置文件中添加代码行,例如 PATH=$PATH:/usr/local/mysql/bin,这样设置完成后,全系统的用户就可以直接使用该软件的命令了。
  • /root/bashrc:root用户的私有环境配置,常用于存放该用户个人设定的命令的别名(alias)。
  • /etc/yum.repos.d:RedHat系系统中,用于配置本地或网络 YUM 软件包管理器源列表的存放目录。
  • /etc/httpd/conf/httpd.conf:Apache httpd Web 服务的核心主配置文件。
  • /etc/fstab:文件系统挂载表。系统在启动时,会读取该文件自动加载列表中的硬盘设备(专用于配置开机自动挂载各磁盘设备)。
  • /etc/selinux:系统级强访问控制安全架构 SELinux 的工作模式与策略设定目录。
  • /etc/sysconfig/network:在这个网络配置总管文件中,管理员可以更改系统的 hostname(全局主机名)以及控制全局网卡的总工作状态是否开启。
  • /etc/hosts:本地静态域名解析文件,负责更改和维护主机名和IP地址的对应解析关系。请注意该文件中记录条目的标准格式为 hostname.domain hostname localhost localhost.domian。特别注意:当你在其他地方修改了系统主机名后,必须同时手动修改该文件里的映射,否则会引发各种服务网络错误。(关于该文件的详细机制解析见下文第七节)。
  • /etc/resolv.conf:本地DNS客户端解析配置文件,用户可以在此明确配置外部 DNS 服务器地址(即第一DNS,第二DNS等),以及设定DNS在域名解析时的默认搜索域名路径。
  • /etc/sysconfig/networking/profiles/default:这是一个存放网络配置方案集的目录,内含数个文件。管理员可以在此统筹配置 hosts 映射、各网卡信息、DNS服务器地址及相关的DNS搜索路径等网络要素。
  • /etc/sysconfig/network-scripts/ifcfg-eth0:针对具体某一块物理网卡(如 eth0 设备)的详细 IP 属性配置文件。
  • /etc/rc.d/init.d/network restart:这是一个命令路径,通过执行此脚本并跟上参数,可以重启整个网络服务使配置生效。
  • /etc/rc.d/init.d:在这个特定的目录下,放置了系统中几乎所有系统服务的开关启动控制脚本。
  • /etc/sysctl.conf:操作系统底层内核参数的配置文件,用于在运行时动态调整网络协议栈或内存等内核行为。
  • /etc/sysconfig/i18n:国际化与本地化配置文件,用于设置系统的默认显示语言环境和文本字符集类型。
  • /etc/crontab:系统周期性任务调度守护进程的全局计划任务定义表。
  • /etc/anacrontab:这是一种特殊的定时任务配置文件,它主要用于实现并保障能够检查那些因关机等原因导致过期、未按时完成的 crontab 计划任务,在开机后能得到补偿执行。
  • /etc/rc.d/init.d/functions:这不是一个可执行服务脚本,而是一个专门定义了诸多通用函数(如输出成功/失败绿色红色标记)的库配置文件,供其他服务脚本调用。
  • /etc/rc.d/rc.sysinit:这是系统启动时运行的第一个高级设置配置文件,负责完成大量基础硬件和环境的初始化动作。
  • /etc/sysconfig/system-config-firewall:图形化界面的防火墙配置存档文件。它用于配置防火墙开放的信任端口,以及防火墙的整体工作状态。具体讲,它主要只负责保存用户在图形界面的 otherport 选项里面设置的具体项目。一个值得注意的规则是:如果防火墙的主配置文件(iptables)中已经存在了相应的底层配置条目,那么这个图形化存档文件里面的配置条目是否存在,其实并不重要,系统会以主配置为准。
  • /etc/sysconfig/iptables:这是 Linux 核心防火墙包过滤工具 iptables 的真正主配置文件。
  • /etc/sysconfig/system-config-securitylevel:这是较老的系统安全等级设置文件,在现代详细的防火墙配置操作中通常不会再直接涉及它。
  • /etc/xinetd.conf:超级互联网守护进程(xinetd)的主配置文件,它负责按需唤醒监听其他各种轻量级网络服务。
  • /etc/hosts.allow:TCP Wrappers 安全访问控制机制的白名单许可表,明确定义哪些IP被允许访问本机服务。
  • /etc/host.deny:与前者对应,是TCP Wrappers访问控制的黑名单拒绝表。
  • /etc/squid/squid.conf:大名鼎鼎的开源代理缓存服务器软件(SQUID)的核心配置文件。
  • /etc/sysconfig/vncservers:远程桌面 VNC 服务的启动和分辨率等参数的配置文件。
  • /etc/vsftpd/ftpusers:vsftpd 服务的安全黑名单文件。用于严格保存那些绝对不允许进行外部 FTP 登录验证的本地系统用户账号(例如root、bin等系统级账号)。
  • /etc/vsftpd/user_list:提供了比 ftpusers 更为灵活的用户访问控制列表机制。根据服务主配置文件中的声明参数不同,这个列表可以被配置为白名单模式,也可以配置为黑名单模式。
  • /etc/inetd.conf:老旧的网络超级守护进程 inetd 的配置文件,其中也包含 swat(Samba网页管理工具)服务的启用配置。
  • /etc/dhcpd.conf:网络动态主机配置协议服务(DHCP 服务端)的地址池及参数配置文件。
  • /etc/rc.d/init.d/dhcpd stop:停止当前正在运行的 DHCP 服务的命令脚本。
  • /etc/access:在邮件服务器配置中,可以利用此文件对 sendmail 服务的进出邮件流进行精细的网络源控制。
  • /etc/udev/rules.d:udev 动态设备管理机制的规则目录。udev 本身是一个程序,负责在系统初始化引导时,将硬件探测到的设备信息输出并映射成设备配置文件。这个目录允许用户自定义udev的识别规则,从而实现在创建底层硬件设备文件时,根据硬件属性(如MAC地址)为其分配使用不同的、更具标识性的固定设备文件名。
  • /etc/sysconfig/network:存放全局网卡与网络启停状态信息的配置文件。(注:与上文提及的路径作用一致)。
  • /etc/hosts:存放主机名与固定 ip 地址映射信息的解析文件。(注:同上)。

/proc 虚拟文件系统深度揭秘

Linux上的 /proc 目录本质上是一种极度特殊的文件系统,即 proc 文件系统。

  • 特性概述:与其他传统的、建立在硬盘上的文件系统(如ext4, xfs)完全不同的是,/proc 是一种由内核完全在内存中动态生成的“伪文件系统”,也叫虚拟文件系统。它并不占用硬盘,其内部存储的全部都是当前操作系统内核正在运行的一系列特殊状态文件。
  • 文件属性异象:基于 /proc 文件系统如上所述的存储于RAM中的特殊性,其内的文件也常被形象地称作虚拟文件,并具有一些非常独特的物理特点。例如,其中有些状态文件虽然你使用 cat 查看命令查看时会返回大量系统信息,但如果你用 ls 命令查看文件本身的大小,却会发现它始终显示为 0 字节。
  • 时间戳特征:此外,这些特殊文件中的大多数文件的时间及日期属性,通常会被标记为当前的系统时间和日期。这跟它们的数据并非静态固化,而是随时会被系统内核实时刷新(直接存储和修改于系统 RAM 内存中)有密切关系。
  • 目录结构逻辑:为了方便系统管理员查看及工具软件使用上的方便,这些文件内容通常会按照硬件相关性或者业务逻辑,进行分类存储于不同的目录甚至深层子目录中。
    • 例如,/proc/scsi 目录中集中存储的就是当前系统上所探测到的所有 SCSI 存储设备的相关信息。
    • /proc/N 这种以纯数字命名的目录中,存储的则是系统当前正在运行的那个特定进程的相关信息,其中这个数字 N 就是代表那个正在运行的进程的 PID 号。(你可以想象得到,当某个进程由于结束或被杀死后,其对应的那个数字相关目录就会立刻随之在 /proc 下消失)。
  • 读取与应用:这其中包含的大量虚拟文件,管理员可以直接通过诸如 catmore 或者 less 这样的普通文本阅读命令来读取内容。有些状态文件信息表述的内容组织得很好,可以让人一目了然看懂。但也有部分底层文件的信息全都是十六进制数据,由于其本身就是留给特定程序读取的,因此直接用肉眼查看却不怎么具有可读性。不过,这些可读性较差的内核文件数据,在被作为数据源,交给一些专门的监控命令(如 apmfreelspcitop)处理并在终端查看时,却可以被转换为人类易读的格式,发挥着极佳的监控表现。

常见的 /proc 子文件/目录清单:

  • /proc/dma:显示当前系统中所有正在被占用的硬件 DMA (直接内存访问) 通道信息。
  • /proc/filesystems:列出当前核心已经编译支持配置的所有文件系统类型。
  • /proc/interrupts:列出当前系统所有正在被使用的硬件中断请求通道(IRQ),and how many of each there have been (以及每个中断通道已经被触发响应了多少次)。
  • /proc/ioports:记录并显示当前硬件设备正在使用的底层 I/O 端口地址范围。
  • /proc/kcore:极其特殊的文件,它相当于当前系统物理内存的一个实时完整映象。你查看它的容量会发现它显示的体积与物理内存大小完全一样,但它在磁盘上并不实际占用这么多内存空间;it is generated on the fly as programs access it. (它完全是在程序尝试访问它时,由内核动态生成的)。(必须记住的一点是:除非你通过 cp 命令手动把它拷贝到硬盘的什么地方,否则 /proc 下存在的任何东西都绝对不会占用你的任何一点磁盘物理空间。)
  • /proc/kmsg:这是内核环形缓冲区输出的实时日志消息出口。这些极为底层的内核消息通常也会被守护进程捕捉并送到 syslog 日志系统中记录。
  • /proc/ksyms:当前操作系统导出的所有核心符号表(用于模块开发与调试)。
  • /proc/loadavg:极其常用的系统”平均负载”监控文件;包含3个时间维度的指示器数值,客观指出系统当前和过去一段时间的工作量与拥堵程度。
  • /proc/meminfo:极为重要的系统存储器使用状态信息概览文件,其中包括了物理内存总量/剩余、以及 swap 虚拟交换分区的使用数据。
  • /proc/modules:列出当前系统内核已经动态加载了哪些扩展核心模块(如驱动等)。
  • /proc/net:网络协议栈及各网络连接状态信息的专用存储目录。
  • /proc/self:这是一个神奇的动态符号连接。它永远指向当前正在查看 /proc 这个动作的那个程序的进程专属目录。举例来说,当有两个不同的进程同时去查看 /proc 目录时,系统内核返回给它们的连接指向是完全不同的。这个设计主要便于任何程序可以无需查询自身PID,就能快速得到它自己的进程目录路径并读取自身资源使用状况。
  • /proc/stat:宏观记录系统各项底层硬件组件的不同运行状态统计数据,such as the number of page faults since the system was booted (比如包含了自系统引导启动以来所发生的内存缺页中断错误总次数)。
  • /proc/uptime:记录系统从上次启动至今一共运行了多少时间长度的文件(单位为秒)。
  • /proc/cpuinfo:包含极度详细的系统处理器硬件信息,如CPU的架构类型、制造商标识、具体型号、缓存和各类指令集性能参数。
  • /proc/devices:列出当前系统内核正在运行的核心配置的各种主设备和次设备驱动的列表清单。
  • /proc/version:当前正在运行的操作系统的底层核心版本信息及编译时间戳。
  • /proc/mdstat:如果系统配置了软RAID阵列,此文件会实时展示当前 RAID 设备的工作状态和同步信息。
  • /proc/cmdline:记录系统启动时,由引导装载程序传递给系统内核的完整启动参数字符串(如:ro root=/dev/vol0/root rhgb quiet grub信息 等内容)。
  • /proc/cpuset:用于显示系统级的 cpu 核心物理集合分配情况,常用于显示和限制当前进程可以应用及被调度绑定到哪些具体的 cpu 核心上运行。
  • /proc/filesystem:显示当前系统内核真正编译并支持的各类底层文件系统种类清单。
  • /proc/mounts:记录当前整个系统树中挂载的所有的文件系统挂载点信息详细列表。
  • /proc/swaps:详细列出系统当前所有被激活的交换分区(虚拟内存)的路径、大小和优先级信息。
  • /proc/sys:这是一个非常关键的子目录,其内部很多文件(具有内核写权限)。管理员可以通过重定向写入这里的文件,来动态定义和修改系统内核参数的值,从而实现无需重启就能直接定义内核的高级功能或优化性能。
  • /proc/sys/kernel/hostname:存储当前系统生效的主机名设定。由于它在 /proc/sys 下,意味着可以通过修改该文件内容来立刻动态更改主机名(虽然重启后会失效)。
  • (关于进程信息的示例):在系统的运行逻辑中,系统内每一个进程的信息都对应一个数字目录。例如存在目录 /proc/245/vm (原文件可能笔误写为etc),它就代表着系统分配进程ID号为 245 的那个特定进程的虚拟内存(Virtual Memory)资源占用信息;而 /proc/245/kernel (原文件笔误)对应的则是进程ID号为 245 的进程调用相关的内核级别信息。

/usr 系统资源与应用主目录

/usr 目录是Linux系统中最庞大、占用空间最多的目录之一。系统安装的非必要但系统级要用到的各类大型应用程序、库文件和资源文件几乎都在这个目录。

  • /usr/X11R6:存放图形化系统 X window 相关的配置及启动目录。
  • /usr/bin:存放由各种软件包安装所带来的众多的、供所有用户使用的普通应用程序执行文件。
  • /usr/sbin:存放一些仅供超级用户使用的系统级高级管理程序和后台守护进程可执行文件。
  • /usr/doc:存放关于各种已安装 linux 软件的基础说明文档。
  • /usr/include:供开发者使用,集中存放在 linux 平台下进行 C 语言开发和编译应用程序时所需要引用的底层头文件。
  • /usr/include/g++:专门存放针对 C++ 编译器所需的底层头文件。
  • /usr/lib:存放各类应用程序在运行时需要频繁调用的常用的动态链接函数库(.so文件)和一部分软件包的固定配置文件。
  • /usr/man:存放各种系统命令和程序的原始帮助手册(man pages)文档数据库。
  • /usr/src:存放系统各类软件(尤其是有重新编译需求软件)的开源源代码目录。
  • /usr/src/linux:最为关键的源码存放地,存放当前正在运行的 linux 核心的底层源代码。
  • /usr/local/bin:管理员手动编译或通过第三方途径在本地额外增加的、不属于系统默认包管理器的命令可执行文件存放处。
  • /usr/local/lib:配合上述手动安装软件,在本地系统级额外增加的非标准运行函数库。
  • /usr/share/fonts:系统级共享的矢量和点阵字体文件存放库。
  • /usr/share/doc:系统默认软件包管理器安装时附带的大量各种程序的详细参考文档文件库。
  • /usr/share/man:目前更为通用的、规范存放全系统各种命令系统手册页(man page)的目录。
  • /usr/local/apache/man:某些手动安装的软件(如早期Apache),会定义指向它自己专属安装目录下的自定义 man 帮助文档集。

其他杂项配置与控制文件补充

  • /bin/bash:Bash 解释器的物理存放路径,通常作为大量系统内置脚本解释执行的首选路径头。
  • /home/USERNAME:这是某位具体用户的专属主目录。不仅存放私人文件,也常常隐含存放与该用户对应的磁盘存储配额控制文件。
  • /var/spool/cron/USERNAME:当某位系统用户使用 crontab 命令创建了自己私有的计划任务时,该用户定义的任务计划明细列表就会被独立保存在这个以此用户名命名的系统调度文件中。
  • /var/spool/mail/root:这是系统的特殊邮件投递设置,在某些配置中定义了将本地发出的系统警告等内部 mail 统一设置并强制发送转发给超级管理员 root 用户去查阅处理。

系统环境变量剖析 (Profile与PATH)

运行环境与环境变量

Linux 是一个典型的、支持大规模并发的多用户网络操作系统。为了确保各个用户在操作时互不干扰,每个用户在成功通过密码登录进入系统后,系统都会在内存中为该会话动态生成并分配一个专用的、封闭的运行环境。

通常情况下,如果没有进行特殊设置,每个新用户初始化登录后的默认环境基础都是相同的。这个所谓的系统默认环境,在底层实际上就是由一系列预先定义的键值对组合而成的,即“一组环境变量的定义”。

当然,用户拥有极大的自由度。用户完全可以根据自身的开发习惯和需要,对自己当前的运行环境进行深度定制。而实现这种个性化定制的最直接方法,就是通过命令去修改相应的系统环境变量的值。

全局配置与PATH变量注入

如果要使某项配置(如添加一个新的工具命令路径)能够让整台服务器上的所有人受益,管理员通常会直接修改 /etc/profile 这个全局初始化文件。需要谨记,只有在这里修改加入的配置内容,才是对所有系统用户全局起作用的。

最常见的一种操作是注入 PATH 搜索路径,写法如下:

1
export PATH=$JAVA_HOME/bin:$PATH

语法拆解与原理解析:

  • 语法核心逻辑:这句脚本的核心意思就是重塑路径搜索机制。它把新定义的 $JAVA_HOME/bin 目录路径,以及系统原本的 $PATH 变量内容打包在一起,重新赋值并覆盖掉当前名为 PATH 的环境变量。
  • $PATH 保留机制:由于在这行赋值语句中,操作者故意在尾部又加上了代表原本内容的 $PATH,所以这个操作带来的实际效果,相当于在系统原先固有的 PATH 搜索列表的最前方,无损地额外增加了一个全新的 $JAVA_HOME/bin 搜索目录。
  • $$` 符号的特殊语义:在Bash语法中,美元符号 `$$ 承担着变量引用的工作。它在此处用于明确指明,紧跟其后的字符串不是普通文本,而是要求解释器将其提取并替换为该名称的变量中已存储的值。
  • : 冒号分隔符:在环境变量的长字符串中,冒号 : 被用作目录条目之间的分隔符。它不仅起分隔作用,系统在查找命令时,还会根据冒号从左到右的位置顺序,严格指明各个目录被搜索执行的先后顺序。

hosts 文件详解

在没有庞大外部 DNS 服务器支持的早期互联网时代,或者是现代高度封闭的内网环境中,/etc/hosts 文件扮演着至关重要的域名解析中枢角色。

Hosts 文件的基本概念与解析优先级

hosts文件是存在于所有类 unix 以及 linux 操作系统中的一个基础文本文件,它专门负责完成本机的 ip地址与纯文本域名之间快速映射与解析的底层工作。

  • 文件格式与位置:它严格以纯粹的 ASCII 文本格式进行编写和保存,并被永久放置在系统的 /etc 目录下,文件全名为 hosts。但在少数不同的定制版 linux 发行版本中,其控制网络主机名的文件也可能叫别名,比如在 Debian 派系系统中,负责定义本机的对应基础文件名叫 /etc/hostname
  • 查询工作流:hosts 文件内部主要包含了指定的 ip 地址和其对应主机名之间的静态映射条目,并且完全支持为一个 IP 指定多个主机名的别名设定。在完全没有外部局域网域名解析服务器(DNS)辅助的情况下,当前这台操作系统上运行的所有浏览器和网络应用服务程序,都会统一通过查询解析该文件内的数据记录,来反向解析得到那个试图访问的服务器主机名背后的真实 IP 地址。只有在本地文件解析失败时,系统否则才需要使用外部配置的 DNS 服务程序或网络请求来解决该域名的位置问题。
  • 应用原则:为了网络的高效和稳定,系统管理员通常都会将网络上或局域网内最常用、最核心的域名和与其对应的IP地址映射关系提前加入到本机的 hosts 文件中,从而实现网络请求时极其快速、方便的内部访问和寻址。
  • 系统内部网络解析优先级:在Linux的网络组件中,一次域名解析的查询顺序有着严格的排位:应用自身的 DNS 内部缓存查询 > 本地系统级 /etc/hosts 文件静态查询 > 发送网络包请求外部公网 DNS 服务商进行查询。
  • 本质定义:用一句话概括,hosts 文件其实就是 the static table lookup for host name(针对主机名映射查询的一张本地静态表)。

Hosts 文件的三大实战作用

强行加快域名解析速度

对于那些我们在日常办公或服务器间经常需要交互访问的核心网站及API接口,我们可以主动提取其真实的 IP,通过在本地的 hosts 文件中手动配置并写入这些域名和 IP 的绑定映射关系,来跳过网络请求,直接提高域名的解析速度。由于本地磁盘已经直接有了这条映射关系的记录,因此当我们输入域名或发送请求后,本机的操作系统底层的网络组件就能够瞬间、快速地直接解析出对应的 IP 地址,而完全不用再花费时间去请求那些远在互联网远端、有时还可能出现拥堵丢包的公网 DNS 解析服务器了。

在局域网内构建人性化映射关系

在众多企业和企事业单位中,通常都会搭建属于自己的封闭局域网,而且机房内还会有很多台不同的、各自承载不同业务的服务器同时提供给公司的不同部门成员使用。但问题在于,由于维护成本,局域网中一般很少会专门去架设一套复杂的内部 DNS 域名解析服务器。因此这就导致在访问这些内网服务器时,员工需要死记硬背并手动输入那些干巴巴、极难记住的数字 IP 地址,这对非技术的大家来说显得相当麻烦且极易出错。因此,为了解决体验问题,管理员就可以分别给局域网内的这些服务器在 hosts 文件里取个带业务含义、容易记住的文本名字(例如 db-server-1),然后在每台客户机的 hosts 文件中统一建立起这些文本名称与机房 IP 的映射。配置完成后,这样在以后大家要访问特定的服务器数据的时候,只要在浏览器或SSH软件里输入这个服务器的名字就一切 OK 了,系统会自动指向正确的机器。

安全防线与屏蔽垃圾网站拦截

在互联网上,现在存在有很多流氓网站。在浏览网页时不经过我们任何明确同意的情况下,有些站点就试图利用脚本将各种各样的广告插件甚至是危险程序隐蔽地安装到我们的计算机系统中,这其中更不乏伪装极好的木马和病毒链接。面对这些已知的恶意网站域名池,系统管理员就可以巧妙地利用本地 hosts 文件的最高解析优先权机制。把这些危险网站的域名直接全部映射到一个故意写错的无效网络 IP 上,或者是直接映射到本地计算机的安全回环 IP 地址(如 127.0.0.1 或者 0.0.0.0)上。这样一来,一旦计算机试图连接这些黑名单域名,请求就会立刻在本地被打回或重定向到死胡同,从而干净利落地达到在底层彻底禁止该电脑访问这批网站的安全防护目的了。

配置文件的修改语法

编辑 /etc/hosts 非常简单,直接使用文本编辑器添加条目即可。书写规则必须是一行一条记录,格式如下:

1
2
# 目标IP地址     映射的域名或主机名
202.108.22.5 www.baidu.com

此时由于规则的生效,一旦保存该文件,本机的网络底层就已经强制将真实的公网 IP 202.108.22.5 与特定的文本域名百度建立了绝对的网络访问联系。