系统启动故障现象
系统重启后无法正常进入操作界面,循环输出错误信息,包括 SELinux权限错误(permission denied) 及 NA refix SElinux 等提示
用户输入账户密码仍无法登录,系统卡死在错误循环状态
救援模式核心作用
当系统因配置修改(如SELinux策略冲突)导致无法启动,或用户遗忘Root密码时,可通过救援模式进行修复
该模式提供临时Root权限,支持关键配置调整与密码重置
进入救援模式操作流程
1 ) 启动中断:
系统启动初期(显示内核选择界面时),按下键盘 e 键进入内核参数编辑界面。
2 ) 修改内核参数:
定位到以 linux16 开头的行,进行以下修改:
- 
将 ro(只读模式)替换为rw(读写模式)。
- 
在 crashkernel参数前追加:bashrw init=/sysroot/bin/sh修改后完整参数示例: bashlinux16 /vmlinuz... rw init=/sysroot/bin/sh crashkernel=auto...
3 ) 启动救援模式:
按 Ctrl + X 组合键,系统以修改后的参数启动,进入 emergency mode(紧急模式)
关键修复操作
1 ) 切换根目录
执行命令将 /sysroot 挂载为根目录:
            
            
              bash
              
              
            
          
          chroot /sysroot  验证权限:
            
            
              bash
              
              
            
          
          whoami  # 输出应为 root  2 ) 关闭SELinux(永久生效)
编辑配置文件:
            
            
              bash
              
              
            
          
          vi /etc/selinux/config  将 SELINUX=enforcing 改为 SELINUX=permissive(仅记录警告不拦截操作)
保存退出(:wq)
注意:setenforce 0 为临时关闭,重启失效;配置文件修改为永久生效方案
3 ) 重置Root密码
执行密码重置命令:
            
            
              bash
              
              
            
          
          passwd root  按提示输入 至少8位的新密码,并二次确认
输出 password updated successfully 表示成功
若未切换root,需指定用户:passwd 用户名
4 ) 处理SELinux上下文(可选)
若未关闭SELinux,需重建文件系统标签:
            
            
              bash
              
              
            
          
          touch /.autorelabel  # 重启后自动重标记权限  5 ) 退出与重启
1 ) 退出救援环境:
            
            
              bash
              
              
            
          
          exit        # 或 Ctrl + D  2 ) 重启系统:
            
            
              bash
              
              
            
          
          reboot  重启后系统正常加载,使用新Root密码登录
6 ) 修复结果验证
登录系统:
- 输入 root账户及新密码,确认登录成功
检查SELinux状态:
            
            
              bash
              
              
            
          
          getenforce  # 输出应为 Permissive(已关闭)  服务恢复:
- 访问NGINX服务器及论坛页面,确认服务正常运行
SELinux配置解析代码操作示例
1 )方案1
            
            
              typescript
              
              
            
          
          import { readFileSync, writeFileSync } from 'fs';  
 
// 读取SELinux配置  
const parseSELinuxConfig = (path: string): { SELINUX: string } => {  
  const configText = readFileSync(path, 'utf-8');  
  return configText  
    .split('\n')  
    .filter(line => !line.startsWith('#'))  
    .reduce((config, line) => {  
      const [key, value] = line.split('=');  
      if (key && value) config[key.trim()] = value.trim();  
      return config;  
    }, {} as Record<string, string>);  
};  
 
// 修改SELinux模式  
const disableSELinuxPermanently = (configPath: string) => {  
  const config = parseSELinuxConfig(configPath);  
  if (config.SELINUX !== 'permissive') {  
    config.SELINUX = 'permissive';  
    const newConfig = Object.entries(config)  
      .map(([k, v]) => `${k}=${v}`)  
      .join('\n');  
    writeFileSync(configPath, newConfig);  
    console.log('SELinux已永久禁用');  
  }  
};  
 
// 调用示例  
disableSELinuxPermanently('/etc/selinux/config');  关键说明:
- 救援模式本质:通过内核参数init=/sysroot/bin/sh跳过系统服务,直接加载Shell
- 密码重置条件:需物理接触服务器(云服务器需VNC控制台)
- SELinux管理:生产环境建议保持enforcing,通过audit2allow生成策略而非直接关闭
2 )方案2
            
            
              typescript
              
              
            
          
          import { Injectable } from '@nestjs/common';
import { execSync } from 'child_process';
import { writeFileSync } from 'fs';
 
@Injectable()
export class SystemRecoveryService {
  // 禁用SELinux的配置方法 
  disableSELinuxPermanently(): void {
    const configPath = '/etc/selinux/config';
    const configContent = execSync(`cat ${configPath}`).toString();
    // 替换enforcing为permissive,保留原文件其他内容 
    const updatedContent = configContent.replace(
      /SELINUX=enforcing/g,
      'SELINUX=permissive',
    );
    // 写入修改后的配置 
    writeFileSync(configPath, updatedContent);
    console.log('SELinux permanently set to permissive.');
  }
 
  // 重置root密码的方法 
  resetRootPassword(newPassword: string): void {
    try {
      // 使用chroot环境模拟救援模式操作 
      execSync(`echo 'root:${newPassword}' | chroot /sysroot chpasswd`, {
        stdio: 'inherit',
      });
      console.log('Root password updated successfully.');
    } catch (error) {
      throw new Error(`Password reset failed: ${error.message}`);
    }
  }
 
  // 创建.autorelabel文件以重建SELinux上下文 
  createAutorelabelFile(): void {
    execSync('touch /.autorelabel');
    console.log('.autorelabel file created for SELinux relabeling.');
  }
}代码说明:
- disableSELinuxPermanently:直接修改- /etc/selinux/config文件,确保配置持久化。
- resetRootPassword:使用- chpasswd命令在- chroot环境中安全更新密码,避免交互式输入。
- 错误处理:同步执行命令(execSync)并捕获异常,符合生产环境要求。
- 适用场景:可集成到NestJS守护进程中,自动化系统修复任务。
技术总结
| 场景 | 操作 | 命令/文件 | 
|---|---|---|
| 系统启动失败 | 内核参数修改 | rw init=/sysroot/bin/sh | 
| 根目录切换 | 挂载真实系统环境 | chroot /sysroot | 
| 永久关闭SELinux | 修改配置文件 | /etc/selinux/config | 
| Root密码重置 | 密码更新 | passwd root | 
| SELinux标签修复 | 创建自动标记文件 | touch /.autorelabel | 
关键提示:
- 救援模式需 物理或虚拟控制台访问权限
- 操作前确保理解命令后果,避免误修改系统关键配置
- SELinux问题可通过关闭策略临时规避,但生产环境建议结合 audit2allow定制规则
细节总结:
- 救援模式本质:通过内核参数修改(init=/sysroot/bin/sh)绕过正常启动流程,挂载最小化环境
- SELinux关键点:enforcing模式阻塞服务时,permissive模式可临时规避;/.autorelabel文件触发重启时的上下文重建
- 密码重置原理:在chroot环境中,passwd命令直接修改/etc/shadow文件
- 安全建议:生产环境中禁用SELinux需谨慎,本案例适用于学习环境;长期方案应调试策略规则(如semanage)