RHEL 10 初始环境配置与常用工具安装教程

适用于 RHEL 10.x(云厂商镜像、官方 ISO、WSL2 导入 rootfs 等场景)。
本文涵盖 RHEL 10 完整初始配置,WSL 专属内容(wsl.conf / .wslconfig / vhdx 回收等)均在本章第十一节说明。


与 Ubuntu 24.04 的核心差异速览

项目 Ubuntu 24.04 RHEL 10
包管理器 apt dnf(YUM v4)
仓库文件 /etc/apt/sources.list.d/*.sources(deb822) /etc/yum.repos.d/*.repo
默认源 国外 archive.ubuntu.com,国内常换阿里云 Red Hat 官方 CDN(需订阅才能用)
第三方仓库 PPA EPEL(Extra Packages for Enterprise Linux)
服务名 ssh sshd
防火墙 ufw firewalldfirewall-cmd
安全模块 AppArmor SELinux(默认 enforcing)
网络配置 Netplan(yaml) NetworkManagernmcli / nmtui
时间同步 systemd-timesyncd chronyd
认证日志 /var/log/auth.log /var/log/secure
系统日志 /var/log/syslog /var/log/messages
用户权限 默认禁用 root 密码 root 默认有密码

⚠️ 国内用户必读(建议先看)

RHEL 10 默认走 cdn.redhat.com + download.fedoraproject.org,在国内访问可能较慢,会导致 dnf install / dnf repolist 命令卡顿。

强烈建议先完成 第四章 · 源与仓库配置 的 4.1-4.3 节(换 EPEL 国内源 + 评估 CDN),再继续后续章节。

海外用户可直接跳过该提示。


目录


一、文档总览

flowchart TD A["🔴 RHEL 10 初始环境配置"]:::root --> B["🔵 订阅注册"]:::l1 A --> H["🔵 源与仓库配置"]:::l1 A --> C["🔵 SSH 服务"]:::l1 A --> D["🔵 常用工具集"]:::l1 A --> E["🔵 网络与系统"]:::l1 A --> F["🔵 安全与优化"]:::l1 A --> G["🔵 命令速查"]:::l1 B --> B1["🟢 subscription-manager"]:::l2 H --> H1["🟢 国内源(EPEL)"]:::l2 H --> H2["🟢 EPEL / CRB"]:::l2 C --> C1["🟢 安装 sshd"]:::l2 C --> C2["🟢 密钥免密"]:::l2 D --> D1["🟢 网络工具"]:::l2 D --> D2["🟢 编辑器 / Git"]:::l2 E --> E1["🟢 NetworkManager"]:::l2 E --> E2["🟢 主机名 / 时区"]:::l2 F --> F1["🟢 firewalld / SELinux"]:::l2 F --> F2["🟢 fail2ban / FD / sysctl"]:::l2 classDef root fill:#ffffff,stroke:#c0392b,stroke-width:3px,color:#c0392b classDef l1 fill:#ffffff,stroke:#e74c3c,stroke-width:2px,color:#e74c3c classDef l2 fill:#ffffff,stroke:#e67e22,stroke-width:2px,color:#e67e22

章节索引

序号 章节 说明
文档总览 流程图 + 索引
初始环境检查 系统版本 / 初始账号 / Locale
订阅注册 subscription-manager 注册
源与仓库配置 EPEL / CRB / 国内换源(国内用户先看)
SSH 服务 sshd 安装 + 密钥免密
常用工具集 dnf 安装 + 工具速查
网络与系统 NetworkManager / 主机名 / 时区
安全与优化 firewalld / SELinux / fail2ban / FD / 内核参数
验证清单 一键自检
命令速查 RHEL 10 ↔ Ubuntu 对照表
十一 WSL2 特别说明 systemd / NM / 防火墙 / SELinux / 订阅 / vhdx

二、初始环境检查

在动手前,先确认当前系统的版本、内核、订阅状态、是否已装 SSH。

# 系统版本
cat /etc/os-release
cat /etc/redhat-release

# 内核版本
uname -r

# 当前用户与权限
whoami
id

# 是否已安装 SSH(最小化镜像通常未装)
rpm -q openssh-server openssh-clients
ss -tlnp 2>/dev/null | grep :22 || netstat -tlnp 2>/dev/null | grep :22

# 订阅状态(关键!未注册的 RHEL 无法访问 dnf 仓库)
subscription-manager status

典型最小化安装输出(参考):

Red Hat Enterprise Linux 10.0 (Coughlan)
...
Linux 6.18.33.1-microsoft-standard-WSL2 + RHEL 10
root
uid=0(root) gid=0(root) groups=0(root)
package openssh-server is not installed
package openssh-clients is not installed

2.1 设置 root 密码

RHEL 10 默认 root 有密码(与 Ubuntu 不同)。如果是从云厂商镜像导入或自定义 rootfs(如 WSL),可能未设置:

# 为 root 用户设置密码(按提示输入两次)
sudo passwd root

验证切换是否成功

# 切换到 root 用户
su -

# 确认当前身份
whoami
id

💡 提示

  • WSL 环境下建议设置 root 密码,否则很多需要 root 权限的维护操作会受阻。详见 11.7 WSL 初始环境配置完整流程
  • 日常操作优先使用 sudo,仅在必要时切换到 root。
  • 生产环境不建议 SSH 允许 root 直登(详见第五章)。

2.2 设置 Locale(消除 "Failed to set locale" 警告)

💡 为什么会有这个警告:最小化安装或自定义 rootfs(如 WSL 导入的精简镜像)默认不带完整 locale,运行 dnfsystemctl 等命令时会反复打印:

Failed to set locale, defaulting to C.UTF-8

不影响功能,但日志里刷一堆很烦,一次设置永久解决。

# 英文用户
sudo localectl set-locale LANG=en_US.UTF-8

# 中文用户
sudo localectl set-locale LANG=zh_CN.UTF-8

验证(重新登录或 exec bash 后生效):

localectl status
# System Locale: LANG=en_US.UTF-8    ← 已生效

locale
# LANG=en_US.UTF-8
# LC_ALL=
# ...

📋 还可以用 localectl list-locales 看系统已生成的 locale。如果列表里没有 zh_CN.UTF-8,需先装:

sudo dnf install -y glibc-langpack-zh

三、订阅注册

⏱️ 这一步必须在装任何软件之前完成。未订阅的 RHEL 默认无法访问 rhel-10-for-x86_64-* 仓库,dnf install 会全部报 This system is not registered with an entitlement server

3.1 注册开发者订阅

注册前需准备:

  1. Red Hat 开发者账号(免费):访问 developers.redhat.com 注册
  2. 在该账号下加入 Red Hat Developer Program 获取订阅(免费,每年手动续期
# 注册系统
sudo subscription-manager register --username YOUR_REDHAT_USERNAME --password 'YOUR_REDHAT_PASSWORD'

# 刷新订阅数据
sudo subscription-manager refresh

# 查看状态
sudo subscription-manager status

成功标志:

+-------------------------------------------+
   System Status Details
+-------------------------------------------+
Overall Status: Registered
Content Access Mode is set to Simple Content Access. ...

🔐 安全提醒

  • 密码含特殊字符(!&*$)必须用单引号包裹,避免 Bash 历史扩展。
  • 出于安全考虑,不要将真实账号写入文档、截图或代码仓库;推荐用环境变量:
    read -rs REDHAT_PASSWORD && \
    sudo subscription-manager register --username "$REDHAT_USERNAME" --password "$REDHAT_PASSWORD"
    

3.2 验证订阅生效

sudo dnf repolist

预期输出(节选):

repo id                              repo name
rhel-10-for-x86_64-appstream-rpms     Red Hat Enterprise Linux 10 for x86_64 - AppStream
rhel-10-for-x86_64-baseos-rpms        Red Hat Enterprise Linux 10 for x86_64 - BaseOS

国内用户看到这步慢/超时 → 直接跳到 第四章 · 源与仓库配置 换源后再回来。


四、源与仓库配置

⏱️ 这一步紧跟订阅注册。RHEL 10 的 cdn.redhat.com 在国内访问可能较慢,不处理会导致所有 dnf 命令卡死(不是慢,是完全挂住)。

核心原则:请勿禁用 RHEL 官方仓库(AppStream / BaseOS)——它们提供系统安全更新。只需禁用一个 dnf 插件即可解决问题。

4.1 解决 dnf 卡住 + 评估网络

4.1.1 解决 dnf 卡住(必须先做)

dnf 每次运行时会触发 subscription-manager dnf 插件连接 cdn.redhat.com 验证订阅。如果 CDN 不通,该插件会完全卡死,所有 dnf 命令挂在 Waiting for process with pid X to finish

解决方案:禁用该插件(不影响订阅状态,只是不再每次预验证):

# 禁用 subscription-manager dnf 插件
sudo sed -i 's/^enabled=1$/enabled=0/' /etc/dnf/plugins/subscription-manager.conf

# 验证
grep enabled /etc/dnf/plugins/subscription-manager.conf
# 应显示:enabled=0

恢复方法(CDN 恢复后,如需可执行):

sudo sed -i 's/^enabled=0$/enabled=1/' /etc/dnf/plugins/subscription-manager.conf

如果 dnf 已经卡住,先 Ctrl+C 取消,然后:

# 杀掉卡住的进程
sudo kill -9 <pid>

# 清除锁文件
sudo rm -f /run/rhsm/rhsm.pid /var/run/rhsm/rhsm.pid

# 再禁用插件
sudo sed -i 's/^enabled=1$/enabled=0/' /etc/dnf/plugins/subscription-manager.conf

CDN 间歇性不通时的处理:如果 kill 进程并禁用插件后下载仍然卡住(CDN 测速 0 B/s),说明 CDN 临时故障。等待几分钟后重试即可,通常 CDN 会自动恢复。

4.1.2 评估网络环境(可选)

禁用插件后,dnf 不会再卡了。以下速度测试仅供参考:

curl -o /dev/null -s -w "cdn.redhat.com: %{time_total}s\n" https://cdn.redhat.com/
curl -o /dev/null -s -w "aliyun epel: %{speed_download} B/s\n" https://mirrors.aliyun.com/epel/

CDN 间歇性说明:国内访问 cdn.redhat.com 可能间歇性不通(测速 0 B/s),但几分钟后可能恢复。如果遇到依赖包下载卡住,多等几分钟重试即可。EPEL 阿里云镜像通常稳定。

4.2 配置 EPEL 阿里云镜像

主仓(redhat.repo)保留订阅,不要换

EPEL 必须换(EPEL 没有订阅约束,放心换)。

# 步骤 1:下载并安装 epel-release(用 rpm 而非 dnf install,避免触发 subscription-manager 插件卡住)
curl -L -o /tmp/epel-release-latest-10.noarch.rpm https://mirrors.aliyun.com/epel/epel-release-latest-10.noarch.rpm
sudo rpm -ivh /tmp/epel-release-latest-10.noarch.rpm

# 步骤 2:验证 epel.repo 生成,并确认 baseurl 指向阿里云
cat /etc/yum.repos.d/epel.repo | grep -A3 '^\[epel\]$'
# 应看到:baseurl=https://mirrors.aliyun.com/epel/10/Everything/$basearch

其他可选镜像:清华 https://mirrors.tuna.tsinghua.edu.cn/epel/、中科大 https://mirrors.ustc.edu.cn/epel/、华为云 https://mirrors.huaweicloud.com/epel/

4.3 启用 CRB 仓库(推荐)

EPEL 装完会提示:

Many EPEL packages require the CodeReady Builder (CRB) repository.
It is recommended that you run /usr/bin/crb enable to enable the CRB repository.

CRB(CodeReady Builder,前身 PowerTools)提供 gcc / kernel-devel / *-devel 包。本文清单(htop / fail2ban / ripgrep 等)不依赖 CRB,但将来编译软件或装 -devel 库需要它。

sudo /usr/bin/crb enable

# 验证
sudo dnf repolist | grep -i crb

如需手动启用:sudo subscription-manager repos --enable codeready-builder-for-rhel-10-$(uname -m)-rpms

4.4 系统更新与验证

sudo dnf clean all
sudo dnf makecache
sudo dnf update -y

dnf update vs dnf upgrade:RHEL 10 已统一为等价,随便用哪个都行。

最终验收

sudo dnf repolist
# 应看到:
#   rhel-10-for-x86_64-appstream-rpms
#   rhel-10-for-x86_64-baseos-rpms
#   epel                              ← EPEL 阿里云
#   codeready-builder-for-rhel-10-...  ← CRB(如已启用 4.3 节)

本章结构与 Ubuntu 版基本一致,差异点:服务名 sshsshd,配置文件路径相同。

5.1 安装 openssh-server

⚠️ WSL 用户必先启用 systemd:RHEL 10 严重依赖 systemd(firewalld、chronyd 等)。WSL2 默认 PID 1 不是 systemd,systemctl 无法使用。先完成 11.1 systemd 启用,再继续以下步骤。

sudo dnf install -y openssh-server openssh-clients iproute

sudo systemctl enable --now sshd

验证

sudo systemctl status sshd   # Active: active (running)
ss -tlnp | grep :22          # 看到 0.0.0.0:22 或 *:22

📋 WSL 用户必读:WSL2 启用 systemd 后才能用 systemctl(在 /etc/wsl.conf[boot] systemd=true,PowerShell 跑 wsl --shutdown)。详见 11.1 systemd 启用

未启用 systemd 时改用直接脚本管理:

sudo /usr/sbin/sshd

5.2 修改 sshd_config(生产推荐配置)

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
sudo vim /etc/ssh/sshd_config
# =============================================
# 基础配置
# =============================================
Port 22
ListenAddress 0.0.0.0
Protocol 2

# =============================================
# 登录认证(关键)
# =============================================
PermitRootLogin no
PasswordAuthentication yes   # 若配置了密钥登录,可改为 no
PermitEmptyPasswords no
PubkeyAuthentication yes
AuthorizedKeysFile      .ssh/authorized_keys
PubkeyAcceptedKeyTypes=+ssh-rsa,ssh-dss

# =============================================
# 安全加固
# =============================================
MaxAuthTries 3
MaxSessions 5
LoginGraceTime 30
ClientAliveInterval 60
ClientAliveCountMax 10
X11Forwarding no

# 白名单(替换为你的实际登录用户,多用户用空格分隔)
AllowUsers youruser

# =============================================
# 显示与日志
# =============================================
LogLevel VERBOSE

重启并验证

sudo sshd -t                # 语法检查(无输出 = 通过)
sudo systemctl restart sshd
sudo systemctl status sshd

⚠️ 高危提醒:修改后不要立即关闭当前会话。新开窗口测试能正常登录,确认没问题再退出,避免配错锁在外面。

⚠️ 注意:RHEL 的 sshd 会读取 /etc/ssh/sshd_config.d/*.conf,这些文件覆盖主配置中的同名选项。例如 50-redhat.conf50-cloud-init.conf 默认写了 PasswordAuthentication no,会覆盖主配置里的 yes。如果密码认证不生效,检查这里:

grep -r 'PasswordAuthentication' /etc/ssh/sshd_config.d/
# 如有 no,改为 yes
sudo sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config.d/<文件名>
sudo systemctl restart sshd

5.3 配置密钥免密登录(可选)

5.3.1 在客户端生成密钥对

Windows(PowerShell / CMD)

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
# 一直回车,会在 C:\Users\<你>\.ssh\ 下生成 id_rsa 和 id_rsa.pub

Linux / macOS

ssh-keygen -t rsa -b 4096

5.3.2 上传公钥到服务器

方法一:ssh-copy-id

# Linux / macOS / Windows 11 PowerShell 自带 OpenSSH
ssh-copy-id -i ~/.ssh/id_rsa.pub youruser@服务器IP

方法二:手动复制

# 在服务器上
mkdir -p ~/.ssh
chmod 700 ~/.ssh
vim ~/.ssh/authorized_keys   # 粘贴客户端公钥,一行一个
chmod 600 ~/.ssh/authorized_keys

5.3.3 关闭密码登录

验证密钥能登录后,编辑服务端配置:

sudo vim /etc/ssh/sshd_config
PasswordAuthentication no
sudo sshd -t
sudo systemctl restart sshd

5.4 firewalld 放行 SSH

详见 8.1 firewalld 防火墙。最小化命令:

sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload

⚠️ 远程主机操作提醒:firewalld 默认区域(public)的 SSH 服务默认已开放。但如果改过区域或主动重载规则,务必先 firewall-cmd --add-service=ssh--reload,否则启用防火墙后会被踢出。


六、常用工具集

6.1 一键安装清单

# =============================================
# 网络工具
# =============================================
# net-tools:   netstat / ifconfig / route
# bind-utils:  nslookup / dig(Ubuntu 是 dnsutils)
# iputils:     ping
# iproute:     ip / ss(最小化镜像可能未装)
# hostname:    查看 IP(最小化镜像可能未装)
sudo dnf install -y net-tools bind-utils iputils mtr iproute hostname

# =============================================
# 编辑器与文件处理
# =============================================
# vim-enhanced: vim(RHEL 把 vim 拆成 vim-minimal 和 vim-enhanced)
# p7zip:        解压 7z(Ubuntu 是 p7zip-full,多了 GUI)
sudo dnf install -y vim-enhanced nano unzip p7zip

# =============================================
# 版本控制
# =============================================
sudo dnf install -y git

# =============================================
# 防火墙(官方仓自带,非 EPEL)
# =============================================
sudo dnf install -y firewalld

# =============================================
# Shell 增强
# =============================================
sudo dnf install -y bash-completion screen

# =============================================
# 系统监控与诊断
# =============================================
# EPEL 专有包
sudo dnf install -y htop iftop ncdu --enablerepo=epel
# 基础包
sudo dnf install -y lsof strace

# =============================================
# 文本搜索 / 处理
# =============================================
# ripgrep / fd-find / jq / fzf(均在 EPEL 可用)
sudo dnf install -y ripgrep fd-find jq fzf --enablerepo=epel

# =============================================
# 彩色 ls 替代(可选)
# =============================================
# lsd: 彩色 ls,替代 ls -la 更直观
sudo dnf install -y lsd --enablerepo=epel

# =============================================
# 开发工具链(按需)
# =============================================
# gcc / make / python3 / nodejs 等
# sudo dnf groupinstall -y "Development Tools"
# sudo dnf install -y python3 nodejs

验证安装

for tool in htop iftop ncdu rg fd jq lsof strace screen; do
  command -v $tool >/dev/null && echo "✅ $tool" || echo "❌ $tool 缺失"
done

📋 RHEL 与 Ubuntu 包名对照(速查):

工具 / 功能 Ubuntu 24.04 RHEL 10
DNS 查询工具 dnsutils bind-utils
vim vim vim-enhancedvim-minimal 默认就有)
7z p7zip-full p7zip / p7zip-plugins
htop / iotop / iftop / ncdu apt 主仓库 EPEL
fail2ban apt 主仓库 EPEL
ripgrep / fd-find apt 主仓库 EPEL

6.2 工具速查表

🔧 工具 📝 用途 📋 常用命令
nmcli 网络配置(替代 netplan / ifconfig) nmcli connection show / nmcli device status
ip 网络配置 ip addr / ip route
ss 端口/连接查看 ss -tlnp / ss -s
netstat 同上(传统) netstat -tlnp
dig DNS 查询 dig baidu.com
mtr 网络诊断 mtr baidu.com
htop 进程监控 htop
iftop 网络流量 sudo iftop -i eth0
lsof 打开的文件 lsof -i :8080
find 目录树(替代 tree) find . -type f | head -20
jq JSON 处理 cat x.json | jq .
rg 快速搜索 rg "error" /var/log
fd 快速查找 fd "*.conf" /etc
fzf 交互式模糊搜索 fzf(配合 Ctrl+R 历史搜索)
lsd 彩色 ls lsd -la
screen 终端复用(替代 tmux) screen -S session
firewall-cmd 防火墙 firewall-cmd --list-all
semanage SELinux 管理 semanage port -l
getenforce SELinux 当前模式 getenforce

6.3 配置 Git

git config --global user.name "Your Name"
git config --global user.email "your_email@example.com"
git config --global color.ui auto
git config --global core.quotepath false

6.4 配置 vim

vim ~/.vimrc
" 显示行号
set number

" 语法高亮
syntax on

" 缩进 4 空格
set tabstop=4
set softtabstop=4
set shiftwidth=4
set expandtab

" 搜索高亮
set hlsearch
set incsearch

" 编码
set encoding=utf-8
set fileencodings=utf-8,gbk,gb18030,gb2312

" 鼠标支持
set mouse=a

6.5 配置 bash 提示符

vim ~/.bashrc

在末尾追加:

# 彩色提示符(CentOS/RHEL 默认风格)
PS1='[\u@\h \W]\$ '

# 命令别名
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
alias gs='git status'
alias gp='git pull'
alias ..='cd ..'

# 常用网络工具别名
alias ports='ss -tlnp'
alias ipinfo='ip -br addr'
source ~/.bashrc

七、网络与系统配置

7.1 配置静态 IP(NetworkManager)

RHEL 10 用 NetworkManager 替代传统 /etc/sysconfig/network-scripts/ifcfg-* 配置文件(虽然 ifcfg 文件仍可读,但 RHEL 官方推荐用 nmcli / nmtui)。

Ubuntu 用 Netplan(yaml),两套体系互不兼容。

7.1.1 查看当前网络状态

# 查看 IP(最简洁,RHEL/Ubuntu/WSL 通用)
hostname -I

# 查看 IP / 网关 / DNS(iproute 方式)
ip -br addr
ip route show default
cat /etc/resolv.conf

WSL 用户注意:WSL2 下 NetworkManager 不工作,nmcli 只能看到 loopback 接口。以上 hostname -I / ip -br addr 等命令在 WSL 下正常工作,可替代 nmcli 的查看功能。详见 11.2 NetworkManager 不工作

7.1.2 用 nmcli 配置静态 IP(推荐,可脚本化)

⚠️ WSL 用户注意:WSL2 下 NetworkManager 不工作,此方法不适用。WSL 网络由 Windows 侧管理,见 11.2 NetworkManager 不工作

# 修改 IP / 网关 / DNS(NetworkManager 方式)
sudo nmcli connection modify ens33 \
  ipv4.method manual \
  ipv4.addresses 192.168.1.100/24 \
  ipv4.gateway 192.168.1.1 \
  ipv4.dns "223.5.5.5 8.8.8.8 114.114.114.114" \
  connection.autoconnect yes

# 立即生效
sudo nmcli connection up ens33

# 验证
ip -br addr show ens33

7.1.3 用 nmtui 配置(交互式,适合新手)

⚠️ WSL 用户:此方法不适用,请跳过。WSL 网络配置见 11.2

sudo nmtui
# 菜单操作:
#   Edit a connection → 选 ens33 → Edit
#   把 IPv4 CONFIGURATION 从 <Automatic> 改为 <Manual>
#   填 Addresses / Gateway / DNS servers
#   底部 <OK> → Back → Quit
sudo nmcli connection down ens33 && sudo nmcli connection up ens33

⚠️ 远程操作注意:改 IP 后当前 SSH 连接会立即断开。务必用新 IP 重新连接,或先在控制台(带外管理)操作。

7.2 配置主机名

# 查看当前主机名
hostnamectl

# 设置主机名(真机/VM 有效,WSL 需在 Windows 侧操作)
sudo hostnamectl set-hostname dev-workspace

WSL 用户:永久修改主机名需在 Windows 侧操作,详见 11.7 WSL 主机名配置

完整的 /etc/hosts

127.0.0.1   localhost
127.0.1.1   dev-workspace

7.3 时区与时间同步

# 查看当前时区
timedatectl

# 设置时区
sudo timedatectl set-timezone Asia/Shanghai

# RHEL 10 默认是 chronyd(不是 Ubuntu 的 systemd-timesyncd)
sudo systemctl enable --now chronyd

# 查看同步状态
chronyc tracking
timedatectl status

📋 RHEL 10 时间同步选择

  • chronyd(默认推荐):适合长时间运行、跨 VPN、网络不稳定的场景
  • systemd-timesyncd:RHEL 10 也带但默认不启用,仅适合简单内网

从 Ubuntu 迁移过来:默认机制不同,但 timedatectl 接口一致,使用体感无差。


八、安全与优化

8.1 firewalld 防火墙

RHEL 10 默认使用 firewalld,与 Ubuntu 的 ufw 完全不同的体系。

  • firewalld 是区域(zone)模型:每个区域定义一套规则,应用到某个网卡
  • 命令是 firewall-cmd(不是 firewall-cmd vs ufw 二选一,而是 firewalld 替代了 ufw)

8.1.1 基础操作

# 查看状态
sudo firewall-cmd --state
# 输出:running

# 查看当前区域和规则
sudo firewall-cmd --list-all

# 查看所有预定义区域
sudo firewall-cmd --get-zones

# 查看 public 区域(默认)规则
sudo firewall-cmd --zone=public --list-all

8.1.2 放行 SSH / HTTP / HTTPS

# 放行服务名(推荐,会自动跟随服务端口变化)
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https

# 放行指定端口
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --permanent --add-port=27017/tcp

# 放行指定 IP 段访问 SSH
sudo firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=192.168.1.0/24 service name=ssh accept'

# 重新加载(--permanent 必须 reload 才生效)
sudo firewall-cmd --reload

# 验证
sudo firewall-cmd --list-all

📋 --permanent 的含义

  • 不加 --permanent:写入运行时配置,重启失效
  • --permanent:写入永久配置,但不会立即生效,必须 --reload

调试时可以不加 --permanent 直接试,重启后清零;确定规则没问题再 --permanent --reload

8.1.3 常用规则速查

需求 命令
放行服务 firewall-cmd --permanent --add-service=服务名
放行端口 firewall-cmd --permanent --add-port=端口/协议
删除规则 firewall-cmd --permanent --remove-port=端口/协议
拒绝某 IP firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=1.2.3.4 drop'
列出所有规则 firewall-cmd --list-all
列出支持的 service 名 firewall-cmd --get-services
改默认区域 firewall-cmd --set-default-zone=trusted
临时关闭防火墙(不卸载) sudo systemctl stop firewalld
开机自启控制 systemctl enable/disable firewalld

8.1.4 WSL2 环境特殊说明

详见 11.3 firewalld 不工作

8.2 SELinux

SELinux 是 RHEL 与 Ubuntu 最大的安全差异。Ubuntu 用 AppArmor(透明、不易感知),RHEL 用 SELinux(默认 enforcing、机制复杂、出问题难排查)。

单机测试或开发环境:建议先改 permissive 跑通,再按需收紧为 enforcing。
生产环境:保持 enforcing,但要给应用正确的 SELinux 标签。

8.2.1 查看当前状态

# 当前模式(Enforcing / Permissive / Disabled)
getenforce

# 详细配置
sestatus

三种模式

模式 行为 适用场景
Enforcing 拒绝违规操作并记录 生产环境
Permissive 记录但不拒绝违规操作 调试 / 排查 SELinux 导致的故障
Disabled 完全关闭 不推荐(重启才能改回)

8.2.2 切换模式

# 临时切换(重启失效)
sudo setenforce 0    # Permissive
sudo setenforce 1    # Enforcing

# 永久生效(修改配置文件)
sudo vim /etc/selinux/config
# 把 SELINUX=enforcing 改为:
SELINUX=permissive
# 或:
SELINUX=enforcing

⚠️ 重要:从 enforcingpermissive 切换到 disabled 必须重启才能生效;从 disabled 切回其他模式也必须重启。

enforcingpermissive 之间不需要重启setenforce 即可。

8.2.3 排查 SELinux 拒绝

SELinux 拒绝访问时,错误会写入 /var/log/audit/audit.log。但直接看 audit log 太痛苦,用 ausearch + audit2why / audit2allow 工具:

# 1. 装工具集
sudo dnf install -y setools-console policycoreutils-python-utils

# 2. 查看最近被拒绝的操作
sudo ausearch -m avc -ts recent

# 3. 看为什么拒绝 + 怎么修
sudo ausearch -m avc -ts recent | audit2why

# 4. 自动生成修复模块(最后手段,不推荐直接用)
sudo ausearch -m avc -ts recent | audit2allow -M myfix
sudo semodule -i myfix.pp

8.2.4 给自定义应用目录打标签(生产环境必做)

默认 SELinux 只允许服务访问 /var/, /etc/, /opt/ 等标准目录。如果你把应用装在 /data//app/ 这类自定义目录,会被 SELinux 阻止。

# 例:给 /data/restcloud 打标签
sudo dnf install -y policycoreutils-python-utils

sudo semanage fcontext -a -t bin_t '/data/restcloud/tomcat/bin(/.*)?'
sudo semanage fcontext -a -t var_lib_t '/data/restcloud/mongodb/data(/.*)?'
sudo semanage fcontext -a -t var_log_t '/data/restcloud/mongodb/logs(/.*)?'
sudo semanage fcontext -a -t var_log_t '/data/restcloud/tomcat/logs(/.*)?'
sudo semanage fcontext -a -t var_t '/data/restcloud/tomcat/dump(/.*)?'

sudo restorecon -R /data/restcloud

# 验证
ls -Z /data/restcloud/

常见文件类型

类型 用途
bin_t 可执行文件(Tomcat/MongoDB 的 bin 目录)
var_lib_t 服务运行时数据(MongoDB data 目录)
var_log_t 日志文件(logs 目录)
var_t 通用可变文件(dump、临时文件)

8.2.5 常见 SELinux 布尔值

SELinux 布尔值是细粒度开关,控制某些特定行为:

# 查看所有布尔值
getsebool -a | less

# 常用项
sudo setsebool -P httpd_can_network_connect 1     # 允许 HTTPD 连外网
sudo setsebool -P httpd_read_user_content 1      # 允许 HTTPD 读用户目录
sudo setsebool -P nis_enabled 1                  # 启用 NIS

# 查看修改
getsebool httpd_can_network_connect

-P 表示永久生效(写入策略数据库),不加 -P 重启后失效。

8.3 fail2ban 防爆破

sudo dnf install -y fail2ban   # 来自 EPEL
sudo vim /etc/fail2ban/jail.local
[DEFAULT]
# 封禁时间(1 小时)
bantime  = 1h

# 监测时间窗口(10 分钟)
findtime = 10m

# 最大重试次数
maxretry = 5

# 封禁动作(firewalld)
banaction = firewallcmd-rich-rules
banaction_allports = firewallcmd-rich-rules

[sshd]
enabled = true
port    = ssh
filter  = sshd
logpath = /var/log/secure   # 注意:RHEL 是 /var/log/secure,不是 auth.log
maxretry = 3

📋 与 Ubuntu 版的关键差异

  1. banactionufw 改为 firewallcmd-rich-rules
  2. logpath/var/log/auth.log 改为 /var/log/secure
sudo systemctl enable --now fail2ban
sudo systemctl status fail2ban

# 查看封禁列表
sudo fail2ban-client status sshd

# 手动解封某 IP
sudo fail2ban-client set sshd unbanip 1.2.3.4

8.4 文件描述符限制

# 查看当前限制
ulimit -n

永久修改:

sudo vim /etc/security/limits.conf
*       soft    nofile  65535
*       hard    nofile  65535
root    soft    nofile  65535
root    hard    nofile  65535

systemd 服务级 FD 限制:

sudo vim /etc/systemd/system.conf

找到 #DefaultLimitNOFILE=1024:524288 这一行,取消注释并改为 65535

DefaultLimitNOFILE=65535

重启生效(真机用 reboot,WSL 用 wsl --shutdown):

sudo reboot

⚠️ WSL 用户注意:WSL2 下不要用 sudo reboot,用 wsl --shutdown 重启。详见 11.7 WSL 重启的正确方式

8.5 内核参数调优

sudo vim /etc/sysctl.d/99-tuning.conf
# =============================================
# 网络优化
# =============================================
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_fin_timeout = 15

net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216

net.ipv4.tcp_max_syn_backlog = 8192
net.core.somaxconn = 8192
net.ipv4.tcp_syncookies = 1

# =============================================
# 安全加固
# =============================================
net.ipv4.ip_forward = 0

net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0

net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0

net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

net.ipv4.conf.all.log_martians = 1
sudo sysctl -p /etc/sysctl.d/99-tuning.conf

与 Ubuntu 版完全一致,可直接复用。

8.6 配置 Swap

# 查看当前 swap
free -h
swapon --show

# 创建 4G swap 文件
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# 永久生效
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

# 调整 swappiness
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.d/99-tuning.conf
sudo sysctl -p

与 Ubuntu 版完全一致。


九、验证检查清单

9.1 通用检查(真机 / 云服务器 / WSL)

✅ 检查项 🔧 命令 🎯 预期
系统版本 cat /etc/redhat-release Red Hat Enterprise Linux release 10.0
订阅状态 subscription-manager status Overall Status: Registered
仓库可用 dnf repolist | grep epel 看到 epel
SSH 远程可连 ssh youruser@IP 成功登录
密码登录已关闭 ssh -o PasswordAuthentication=no youruser@IP 仍可登录 = OK
SSH 服务自启 systemctl is-enabled sshd enabled
firewalld 已启用 firewall-cmd --state running
防火墙规则生效 firewall-cmd --list-all 看到 ssh/http 等服务
SELinux 模式 getenforce EnforcingPermissive
网络连通 ping -c 3 baidu.comcurl -v http://baidu.com 有响应
DNS 解析 dig baidu.com 返回 IP
时区正确 timedatectl Asia/Shanghai
时间同步 chronyc tracking Reference ID 不为 00000000
系统已更新 dnf check-update 无输出 = 已最新
FD 限制 ulimit -n 65535(已配置时)
工具齐全 which htop screen jq tree vim 全部有路径
fail2ban 运行 systemctl status fail2ban active (running)

9.2 一键自检脚本

保存为 ~/check-rhel10.shchmod +x ~/check-rhel10.sh 后跑:

#!/bin/bash
# =============================================
# RHEL 10 初始环境一键自检脚本
# =============================================
echo "================================"
echo "RHEL 10 初始环境自检"
echo "================================"

echo -e "\n[1] 系统信息"
echo "版本:$(grep PRETTY_NAME /etc/os-release | cut -d= -f2- | tr -d '"')"
echo "内核:$(uname -r)"
echo "当前用户:$(whoami)"

echo -e "\n[2] 订阅状态"
if command -v subscription-manager &>/dev/null; then
  subscription-manager status 2>/dev/null | grep -E "Overall Status|Content Access" || echo "❌ 未注册"
else
  echo "⚠️ subscription-manager 未装"
fi

echo -e "\n[3] 仓库状态"
dnf repolist enabled 2>/dev/null | grep -E "rhel-10|epel" | head -5

echo -e "\n[4] SSH 服务"
systemctl is-enabled sshd && echo "✅ sshd 自启" || echo "❌ sshd 未自启"
systemctl is-active sshd && echo "✅ sshd 运行中" || echo "❌ sshd 未运行"

echo -e "\n[5] 防火墙"
if command -v firewall-cmd &>/dev/null; then
  firewall-cmd --state 2>/dev/null && \
  firewall-cmd --list-services 2>/dev/null | tr ' ' '\n' | grep -v '^$'
else
  echo "⚠️ firewalld 未装"
fi

echo -e "\n[6] SELinux"
getenforce

echo -e "\n[7] 时区与时间"
timedatectl | grep -E "Time zone|System clock"

echo -e "\n[8] 网络"
ip -br addr | grep -v "DOWN" | head -5

echo -e "\n[9] DNS"
cat /etc/resolv.conf 2>/dev/null | grep nameserver | head -2

echo -e "\n[10] 资源限制"
echo "ulimit -n: $(ulimit -n)"
echo "ulimit -u: $(ulimit -u)"

echo -e "\n[11] 工具检查"
for tool in htop iotop iftop jq tree vim git curl wget screen; do
  if command -v $tool &> /dev/null; then
    echo "✅ $tool"
  else
    echo "❌ $tool 缺失"
  fi
done

echo -e "\n[12] systemd 状态(WSL 关注)"
ps -p 1 -o comm= | grep -q systemd && echo "✅ systemd 已启用" || echo "❌ PID 1 不是 systemd"

echo -e "\n[13] 主机名"
echo "当前:$(hostname)"
grep -q "^127.0.1.1 $(hostname)" /etc/hosts && echo "✅ /etc/hosts 同步" || echo "⚠️ /etc/hosts 未同步"

echo -e "\n[14] fail2ban"
if systemctl is-active fail2ban &>/dev/null; then
  echo "✅ fail2ban 运行中"
  fail2ban-client status sshd 2>/dev/null | grep -E "Banned|Total"
else
  echo "⚠️ fail2ban 未运行"
fi

echo -e "\n================================"
echo "自检完成"
echo "================================"

十、常用命令速查(RHEL 10 vs Ubuntu)

10.1 服务管理

操作 RHEL 10 Ubuntu 24.04
服务名 sshd ssh
启动 systemctl start sshd sudo systemctl start ssh
状态 systemctl status sshd sudo systemctl status ssh
自启 systemctl enable sshd sudo systemctl enable ssh

10.2 包管理对照

操作 RHEL 10 (dnf) Ubuntu 24.04 (apt)
更新源索引 dnf check-update sudo apt update
安装包 sudo dnf install -y pkg sudo apt install -y pkg
删除包 sudo dnf remove pkg sudo apt remove pkg
搜索包 dnf search keyword apt search keyword
包信息 dnf info pkg apt show pkg
列出已装 dnf list installed apt list --installed
升级所有 sudo dnf update -y sudo apt update && sudo apt upgrade -y
列出仓库 dnf repolist apt-cache policy
添加仓库 dnf config-manager --add-repo URL add-apt-repository URL

10.3 网络与防火墙

用途 RHEL 10 Ubuntu 24.04
查看 IP ip addr / ifconfig ip addr
配置网络 nmcli / nmtui netplan
防火墙 firewalld / firewall-cmd ufw
SELinux setenforce 0/1 / semanage 无(Ubuntu 用 AppArmor)
主机名 hostnamectl set-hostname x 相同

10.4 时间与日志

用途 RHEL 10 Ubuntu 24.04
时区设置 timedatectl set-timezone ... 相同
时间同步 chronyd(默认) systemd-timesyncd(默认) / chrony
系统日志 /var/log/messages /var/log/syslog
认证日志 /var/log/secure /var/log/auth.log
查看日志 journalctl -u sshd journalctl -u ssh

10.5 一键脚本(新建服务器跑一次)

#!/bin/bash
# =============================================
# RHEL 10 初始环境一键配置脚本
# 对应文档:RHEL8初始环境配置与常用工具安装教程.md
# 用法:sudo bash init-rhel10.sh
# 前置:需先注册订阅(subscription-manager register)
# 幂等:重复运行不会破坏既有配置
# =============================================
set -euo pipefail

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
log()  { echo -e "${GREEN}[✓]${NC} $*"; }
warn() { echo -e "${YELLOW}[!]${NC} $*"; }
err()  { echo -e "${RED}[✗]${NC} $*"; }

if [[ $EUID -ne 0 ]]; then
  err "请使用 root 或 sudo 运行本脚本"
  exit 1
fi

# WSL 探测
IS_WSL=0
grep -qiE 'microsoft|wsl' /proc/version 2>/dev/null && IS_WSL=1
log "运行环境:$( [[ $IS_WSL -eq 1 ]] && echo 'WSL2' || echo '真机/云服务器' )"

REAL_USER="${SUDO_USER:-${USER:-root}}"
[[ "$REAL_USER" == "root" ]] && REAL_USER="youruser"

# ---------- 1. 检查订阅 ----------
log "[1/8] 检查订阅状态"
if ! subscription-manager status 2>/dev/null | grep -q "Current"; then
  err "系统未注册订阅,请先执行:"
  err "  sudo subscription-manager register --username <账号> --password <密码>"
  err "  注册成功后重新运行本脚本"
  exit 1
fi
log "订阅状态正常"

# ---------- 2. 启用 EPEL ----------
log "[2/8] 启用 EPEL 仓库"
if ! dnf repolist | grep -q "^epel"; then
  # 直接从阿里云 RPM URL 安装,跳过慢速 fedoraproject.org
  dnf install -y https://mirrors.aliyun.com/epel/epel-release-latest-10.noarch.rpm
  log "EPEL 已启用"
  # 替换为阿里云镜像(精确匹配 [epel] 段内 baseurl)
  if [[ -f /etc/yum.repos.d/epel.repo ]]; then
    sed -i '/^\[epel\]$/,/^\[/s|^#baseurl=.*|baseurl=https://mirrors.aliyun.com/epel/10/Everything/$basearch|' /etc/yum.repos.d/epel.repo
    sed -i '/^\[epel\]$/,/^\[/s|^metalink=|#metalink=|' /etc/yum.repos.d/epel.repo
    log "EPEL 已切阿里云镜像"
  fi
else
  warn "EPEL 已启用,跳过"
fi

# 默认禁用 subscription-manager dnf 插件(避免 CDN 不通时所有 dnf 命令卡死)
if [[ -f /etc/dnf/plugins/subscription-manager.conf ]] && grep -q 'enabled=1' /etc/dnf/plugins/subscription-manager.conf; then
  sed -i 's/enabled=1/enabled=0/' /etc/dnf/plugins/subscription-manager.conf
  log "subscription-manager dnf 插件已禁用(避免 CDN 不通时 dnf 卡住),不影响订阅状态"
fi

# ---------- 3. 系统更新 ----------
log "[3/8] 更新系统"
dnf update -y

# ---------- 4. 常用工具 ----------
log "[4/8] 安装常用工具集"
# EPEL 专有包
dnf install -y --enablerepo=epel \
  htop iftop ncdu ripgrep fd-find jq
# RHEL / AppStream 基础包
dnf install -y \
  openssh-server openssh-clients iproute \
  vim-enhanced nano curl wget git \
  net-tools bind-utils iputils mtr hostname \
  unzip p7zip \
  bash-completion screen \
  lsof strace \
  firewalld

# ---------- 5. SSH 配置 ----------
log "[5/8] 配置 SSH 服务"
SSHD_CFG=/etc/ssh/sshd_config
[[ -f $SSHD_CFG ]] && [[ ! -f ${SSHD_CFG}.bak ]] && cp $SSHD_CFG ${SSHD_CFG}.bak

sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/'             "$SSHD_CFG"
sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication yes/' "$SSHD_CFG"
sed -i 's/^#\?PubkeyAuthentication.*/PubkeyAuthentication yes/'   "$SSHD_CFG"
sed -i 's/^#\?X11Forwarding.*/X11Forwarding no/'                   "$SSHD_CFG"
sed -i 's/^#\?MaxAuthTries.*/MaxAuthTries 3/'                      "$SSHD_CFG"

if [[ $IS_WSL -eq 0 ]]; then
  systemctl enable --now sshd >/dev/null 2>&1 || warn "sshd 启动失败"
fi
sshd -t && log "sshd_config 语法校验通过" || err "sshd_config 语法错误"

# ---------- 6. firewalld ----------
log "[6/8] 配置 firewalld"
if [[ $IS_WSL -eq 0 ]]; then
  systemctl enable --now firewalld >/dev/null 2>&1
  firewall-cmd --permanent --add-service=ssh >/dev/null
  firewall-cmd --reload >/dev/null
  log "firewalld 已启用,SSH 已放行"
else
  warn "WSL2 环境:firewalld 不管理 Windows 物理网卡,请手动在 Windows 防火墙放行端口"
fi

# ---------- 7. 时区与 fail2ban ----------
log "[7/8] 配置时区 / fail2ban / FD 限制"
timedatectl set-timezone Asia/Shanghai

if [[ $IS_WSL -eq 0 ]]; then
  systemctl enable --now chronyd >/dev/null 2>&1 || true
  systemctl enable --now fail2ban >/dev/null 2>&1 || warn "fail2ban 启动失败"
fi

# FD 限制
LIMITS_CONF=/etc/security/limits.conf
if ! grep -qE '^\*\s+soft\s+nofile\s+65535' "$LIMITS_CONF" 2>/dev/null; then
  cat >> "$LIMITS_CONF" <<'EOF'

# === Added by init-rhel10.sh ===
*   soft    nofile  65535
*   hard    nofile  65535
root soft    nofile  65535
root hard    nofile  65535
EOF
  log "已追加 nofile 限制"
fi

# ---------- 8. 完成提示 ----------
echo
log "初始化完成"
echo "------------------------------------------------"
echo "  下一步:"
echo "  1) 客户端执行:ssh-copy-id ${REAL_USER}@\$(hostname -I | awk '{print \$1}')"
echo "  2) 验证密钥登录成功后,再把 PasswordAuthentication 设为 no"
echo "  3) 真机/云服务器需 reboot;WSL2 在 Windows PowerShell 执行 wsl --shutdown"
echo "  4) SELinux 当前模式:$(getenforce)"
echo "     如需改 enforcing/permissive:sudo setenforce 1/0"
echo "------------------------------------------------"

十一、WSL2 环境特别说明

本节专门讲 RHEL 10 在 WSL2 下的特殊注意事项。所有 WSL 相关配置(wsl.conf / .wslconfig / vhdx 回收等)均在本章第十一节说明。

11.1 systemd 启用

RHEL 10 严重依赖 systemd(firewalld、NetworkManager、chronyd、subscription-manager 都靠它)。WSL2 默认 PID 1 是 init,必须显式启用:

# 编辑 /etc/wsl.conf(用 tee 不要用 vim,避免 sudo 解析问题)
sudo tee -a /etc/wsl.conf > /dev/null <<'EOF'

[boot]
systemd=true
EOF

在 Windows PowerShell 重启 WSL:

wsl --shutdown

重开 WSL 验证:

ps -p 1 -o comm=
# 应输出 systemd

常见问题排查

问题 解决方案
重启后仍是 init 确认 /etc/wsl.conf 格式正确,wsl --shutdown 后重试
systemd 启动失败 检查 systemctl status 定位具体服务
systemd-logind.service is masked,导致 Failed to create session 执行 systemctl unmask systemd-logind,然后 wsl --shutdown 重启 WSL

注意systemd-logind.service 被 masked(屏蔽)是 WSL 导入镜像后的常见问题,会导致 "Failed to create session" 和 WSL interop 报错(如 CreateLoginSession: Timed out)。unmask 只是移除屏蔽,服务本身由 D-Bus 动态激活,无需 enable

详细流程与排错见本章 11.1 节。

11.2 NetworkManager 不工作

WSL2 的网络栈由 Windows 虚拟,nmcli / nmtui 在 WSL 里改了不会生效。WSL 网络配置在 Windows 侧的 ~/.wslconfig

WSL 内的 RHEL 10 系统仍会启动 NetworkManager,但只能管 WSL 内部虚拟接口(loopback),不会影响出站/入站流量。建议禁用以避免资源浪费

sudo systemctl disable --now NetworkManager

11.3 firewalld 在 WSL 下的限制

firewalld 在 WSL 里可以正常运行,但只管理 WSL 内部虚拟接口,管不到 Windows 物理网卡

这意味着:

  • firewalld 对 WSL 内部流量(如容器互联)有效
  • 对 Windows 物理网卡的入站流量无效,需在 Windows 防火墙处理

放行端口方式

  • 方式 A(推荐):在 Windows 防火墙里放行对应端口
  • 方式 B:在 WSL 里启用 firewalld,但只对 WSL 内部接口有效(详细配置见 11.7.10 节)

11.4 SELinux 在 WSL 下的限制

WSL2 的微软内核与标准 Linux 内核有差异,SELinux 部分功能可能不可用

# 验证 SELinux 是否工作
getenforce
# 输出 Disabled 或 Permissive 是 WSL 下的正常状态(微软内核不强制 SELinux)

# 如果想强制启用(可能不稳定):
sudo grubby --update-kernel=ALL --args="enforcing=1"

建议:WSL 环境下直接保持 SELinux Disabled 或 Permissive,把精力集中在应用层安全(防火墙、SSH 配置等)。

11.5 subscription-manager 在 WSL 下的限制

WSL 下的 RHEL 可以正常注册订阅和 dnf install,但部分 Red Hat 工具链(如 Insights、Satellite 连接)可能因 WSL 缺少 /dev/mem 等特殊设备而报错。日常使用 dnf install 不受影响。

11.6 vhdx 空间回收

WSL 下的 RHEL 10 同样存在 ext4.vhdx 稀疏文件不自动收缩的问题。回收方式见 11.6 节。

11.7 WSL 初始环境配置完整流程

本节整合 WSL 环境下 RHEL 10 的完整配置流程,涵盖所有特殊注意事项。

11.7.1 设置 root 密码

WSL 环境下建议设置 root 密码,否则很多需要 root 权限的维护操作会受阻:

sudo passwd root

11.7.2 启用 systemd

必须步骤,否则大多数服务无法使用:

sudo tee /etc/wsl.conf > /dev/null <<'EOF'
[boot]
systemd=true
EOF

然后在 Windows PowerShell 执行:

wsl --shutdown

重开 WSL 后验证:

ps -p 1 -o comm=
# 应输出 systemd

11.7.3 设置 Locale

消除 "Failed to set locale" 警告:

sudo localectl set-locale LANG=en_US.UTF-8
exec bash

11.7.4 注册订阅

sudo subscription-manager register --username YOUR_REDHAT_USERNAME --password 'YOUR_REDHAT_PASSWORD'
sudo subscription-manager refresh

11.7.5 配置 EPEL 阿里云镜像

sudo dnf install -y https://mirrors.aliyun.com/epel/epel-release-latest-10.noarch.rpm
sudo sed -i '/^\[epel\]$/,/^\[/s|^#baseurl=.*|baseurl=https://mirrors.aliyun.com/epel/10/Everything/$basearch|' /etc/yum.repos.d/epel.repo
sudo sed -i '/^\[epel\]$/,/^\[/s|^metalink=|#metalink=|' /etc/yum.repos.d/epel.repo

11.7.6 安装常用工具

sudo dnf install -y --enablerepo=epel \
  htop ripgrep fd-find jq
sudo dnf install -y \
  openssh-server openssh-clients iproute vim-enhanced nano curl wget git \
  net-tools bind-utils iputils mtr hostname unzip p7zip bash-completion screen lsof strace

11.7.7 禁用 NetworkManager(如不需要)

sudo systemctl disable --now NetworkManager

11.7.8 WSL 重启的正确方式

不要使用 sudo reboot,否则可能导致 WSL 状态异常。

正确方式:在 Windows PowerShell 中执行:

wsl --shutdown

然后重新打开 WSL 终端。

11.7.9 永久修改 WSL 主机名

WSL 的 hostname 不能靠 Linux 侧修改——WSL 重启时 Windows 会自动用 Windows 计算机名覆盖 /etc/hostname

正确方式:在 wsl.conf 的 [network] 段设置(这是 WSL 唯一认可的持久化位置):

sudo tee /etc/wsl.conf > /dev/null <<'EOF'
[user]
default = root

[boot]
systemd=true

[automount]
enabled = true
mountFsTab = false

[interop]
enabled = true
appendWindowsPath = true

[network]
hostname = rhel10-workspace
generateResolvConf = true
EOF

⚠️ 关键提醒

  • hostname = xxx 必须写在 [network],写在别的地方不生效
  • 5 个段都要写全,缺段会导致配置不生效
  • tee 整段覆盖,不要用 sed 改一行(sed pattern 容易匹配不上)
  • [network] generateResolvConf = true 让 WSL 自动生成 /etc/resolv.conf(不要改成 false,否则 DNS 可能不工作)

重启 WSL 使配置生效

wsl --shutdown
wsl -d RHEL10

验证

hostname
# 应显示:rhel10-workspace

cat /etc/wsl.conf
# 应看到 [network] hostname = rhel10-workspace

注意:即使 wsl.conf 设置了 hostname,WSL 重启时 Windows 仍会覆盖 /etc/hosts 中的 127.0.1.1 条目。如果你在 /etc/hosts 追加了自定义内容(不冲突可忽略),重启后不会被保留。

11.7.10 WSL 防火墙配置

WSL2 共享宿主机网络栈,firewalld 在 WSL 内无法管理 Windows 物理网卡的入站流量。放行端口方式:

  • 方式 A(推荐):在 Windows 防火墙里放行对应端口
  • 方式 B:在 WSL 里启用 firewalld,但只对 WSL 内部接口有效

11.7.11 SELinux 状态

WSL 环境下 SELinux 默认 Disabled 或 Permissive 是正常现象,无需调整:

getenforce
# Disabled 或 Permissive

11.7.12 vhdx 空间回收

WSL 虚拟磁盘(ext4.vhdx)是稀疏文件,删除文件后不会自动释放空间。回收方式:

  1. 在 WSL 内删除不需要的大文件
  2. Windows PowerShell 执行:
# 关闭 WSL
wsl --shutdown

# 使用 diskpart 压缩
diskpart
select vdisk file="C:\Users\你的用户名\AppData\Local\Packages\xxx\LocalState\ext4.vhdx"
compact vdisk
exit

详见 11.6 节。

11.7.13 WSL DNS 错误(CheckConnection getaddrinfo failed)

WSL 启用 systemd 后,日志中可能出现以下错误(不影响 sshd 等服务运行):

WSL (110) ERROR: CheckConnection: getaddrinfo() failed: -5
WSL (2 - Interop) ERROR: CreateLoginSession:2758: Timed out waiting for user session

这是 WSL 集成层(interop)的 DNS 解析问题,与 systemd-logind.service 被 masked 相关。已按 11.1 节执行 systemctl unmask systemd-logind 后,此问题应已解决。

如仍有少量 WSL interop 错误日志且不影响使用,可忽略。如需进一步处理,可尝试:

# 重建 resolv.conf 软链接(使用 WSL 动态生成的 DNS 配置)
sudo rm -f /etc/resolv.conf
sudo ln -s /run/resolvconf/resolv.conf /etc/resolv.conf

说明:这些错误来自 WSL 虚拟平台层,不是 RHEL 系统服务的问题,不影响 WSL 内的正常操作。


💡 文档维护提示

  • 上述配置在 RHEL 10.x(云服务器镜像 + WSL2 导入 rootfs)实测通过。
  • RHEL 10 为当前稳定版本,建议新项目使用。
  • RHEL 10 与 RHEL 9 差异不大,主要是 dnf5 逐步普及、默认 Python 3.11更新的 SELinux 策略。
posted @ 2026-07-07 18:17  RK5123153  阅读(54)  评论(0)    收藏  举报