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 |
firewalld(firewall-cmd) |
| 安全模块 | AppArmor | SELinux(默认 enforcing) |
| 网络配置 | Netplan(yaml) | NetworkManager(nmcli / 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),再继续后续章节。
海外用户可直接跳过该提示。
目录
- 一、文档总览
- 二、初始环境检查
- 三、订阅注册
- 四、源与仓库配置
- 五、SSH 服务
- 六、常用工具集
- 七、网络与系统配置
- 八、安全与优化
- 九、验证检查清单
- 十、常用命令速查(RHEL 10 vs Ubuntu)
- 十一、WSL2 环境特别说明
一、文档总览
章节索引:
| 序号 | 章节 | 说明 |
|---|---|---|
| 一 | 文档总览 | 流程图 + 索引 |
| 二 | 初始环境检查 | 系统版本 / 初始账号 / 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,运行
dnf、systemctl等命令时会反复打印: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 注册开发者订阅
注册前需准备:
- Red Hat 开发者账号(免费):访问 developers.redhat.com 注册
- 在该账号下加入 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 updatevsdnf 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 版基本一致,差异点:服务名
ssh→sshd,配置文件路径相同。
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.conf和50-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 查询工具 dnsutilsbind-utilsvim vimvim-enhanced(vim-minimal默认就有)7z p7zip-fullp7zip/p7zip-pluginshtop / 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-cmdvsufw二选一,而是 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 环境特殊说明
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
⚠️ 重要:从
enforcing或permissive切换到disabled必须重启才能生效;从disabled切回其他模式也必须重启。
enforcing↔permissive之间不需要重启,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 版的关键差异:
banaction从ufw改为firewallcmd-rich-ruleslogpath从/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 |
Enforcing 或 Permissive |
| 网络连通 | ping -c 3 baidu.com 或 curl -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.sh,chmod +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)是稀疏文件,删除文件后不会自动释放空间。回收方式:
- 在 WSL 内删除不需要的大文件
- 在 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 策略。

浙公网安备 33010602011771号