AlmaLinux-9 与 WSL2 初始环境配置与常用工具安装教程

适用于 AlmaLinux 9(云厂商镜像、官方 ISO 或 WSL2 安装后),从 SSH 远程连接到常用工具一站式配置。

📌 这是一份独立专题——聚焦 AlmaLinux 9 的初始环境配置、常用工具安装与安全加固;WSL 专属行为单独标注,不展开讨论通用 WSL 基础(详见 WSL 虚拟机创建与管理指南.md)。


目录


一、文档总览

flowchart TD A["🟣 AlmaLinux-9 初始环境配置"]:::root --> B["🔵 SSH 远程服务"]:::l1 A --> C["🔵 常用工具集"]:::l1 A --> D["🔵 网络与系统"]:::l1 A --> E["🔵 安全与优化"]:::l1 A --> G["🟠 WSL 用户专属指南(仅 WSL2)"]:::wsll1 A --> F["🔵 命令速查"]:::l1 B --> B1["🟢 安装 openssh-server"]:::l2 B --> B2["🟢 配置 sshd_config"]:::l2 B --> B3["🟢 密钥免密登录"]:::l2 B --> B4["🟢 防火墙放行"]:::l2 C --> C1["🟢 dnf 装常用包"]:::l2 C --> C2["🟢 Git / vim / bash"]:::l2 D --> D1["🟢 静态 IP / DNS"]:::l2 D --> D2["🟢 主机名 / hosts"]:::l2 D --> D3["🟢 时区 / NTP"]:::l2 D --> D4["🟢 系统更新源"]:::l2 E --> E1["🟢 firewalld 防火墙"]:::l2 E --> E2["🟢 fail2ban"]:::l2 E --> E3["🟢 SELinux"]:::l2 E --> E4["🟢 内核参数 / FD 限制"]:::l2 G --> G1["🟠 启用 systemd + wsl.conf"]:::wsll2 G --> G2["🟠 主机名 / hosts"]:::wsll2 G --> G3["🟠 SELinux 切 permissive"]:::wsll2 G --> G4["🟠 firewalld 关掉"]:::wsll2 G --> G5["🟠 数据规划 + vhdx 回收"]:::wsll2 G --> G6["🟠 重启正确方式"]:::wsll2 classDef root fill:#ffffff,stroke:#9b59b6,stroke-width:3px,color:#9b59b6 classDef l1 fill:#ffffff,stroke:#3498db,stroke-width:2px,color:#3498db classDef l2 fill:#ffffff,stroke:#2ecc71,stroke-width:2px,color:#2ecc71 classDef wsll1 fill:#fff7e6,stroke:#e67e22,stroke-width:2px,color:#e67e22 classDef wsll2 fill:#fff7e6,stroke:#d35400,stroke-width:1px,color:#d35400

章节索引:

序号 章节 说明
文档总览 流程图 + 索引
初始环境检查 确认系统版本 / 初始账号 / root 密码
SSH 远程服务 核心:安装 + 配置 + 密钥免密
常用工具集 dnf 一键装包 + Git / vim / bash 偏好
网络与系统配置 静态 IP / DNS / 时区 / 更新源
安全与优化 firewalld / fail2ban / SELinux / 内核参数
WSL 用户专属指南 WSL 必读:systemd 启用、主机名、SELinux 噪音、firewalld 关掉、数据规划、vhdx 回收、重启方式
验证检查清单 一键自检
常用命令速查 AlmaLinux ↔ Ubuntu 对照表

二、初始环境检查

在动手前,先确认当前系统的版本、内核、当前用户、是否已装 SSH。

# 系统版本
cat /etc/os-release
# 关键字段:NAME="AlmaLinux"、VERSION="9.x (Seafoam Ocelot)"、ID=almalinux

# 内核版本
uname -r

# 当前用户与权限
whoami
id

# 是否已安装 SSH(AlmaLinux 多数镜像默认已装)
rpm -q openssh-server
ss -tlnp 2>/dev/null | grep :22 || netstat -tlnp 2>/dev/null | grep :22

2.1 设置 root 密码

AlmaLinux 安装时通常会要求设 root 密码,但云厂商轻量镜像WSL 装出来的版本可能 root 锁死或密码为空。建议先确认:

# 查看是否能切到 root
su -
whoami
# 报错或提示密码错误 = 没设好

为 root 设置一个强密码

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

验证切换是否成功

# 切换到 root 用户
su -

# 确认当前身份
whoami
id

💡 提示

  • AlmaLinux 与 RHEL/CentOS 允许 root 通过 SSH 登录PermitRootLogin yes 默认),生产环境强烈建议改为 no
  • WSL 环境下:首次 wsl --install 设的普通用户没有 root 密码,但可以直接 sudosudo passwd root 设上之后更方便维护。

🔐 安全建议

  • root 密码应使用强密码(长度 12 位以上,包含大小写字母、数字、特殊字符)。
  • 日常操作优先使用 sudo,仅在必要时切换到 root。

三、SSH 远程服务(核心)

本章为优先配置项。所有运维操作几乎都依赖 SSH,建议首先完成配置。

3.1 安装 openssh-server

⚠️ 先换源,再更新

如果你在国内或默认源访问较慢,建议先完成 5.5 dnf 换源,再返回本节执行安装。否则第一次 dnf makecache 可能非常慢,甚至超时失败。

  • WSL 默认 rootfs 较精简,openssh-server 通常没装,本节命令是必须的
  • 真机/云服务器多数镜像已预装
# 更新软件源缓存(如已按 5.5 节换源,会直接从镜像站更新)
sudo dnf makecache

# 安装 SSH 服务端与客户端
sudo dnf install -y openssh-server openssh-clients

# 启动并设置开机自启
sudo systemctl enable --now sshd

🔧 验证

sudo systemctl status sshd   # 输出中出现 active (running) 即表示成功
ss -tlnp | grep :22         # 看到 0.0.0.0:22 或 *:22 监听中

📋 WSL 用户必读:配置完 SSH 后,如果需要从 Windows 侧通过 WSL 的 IP(如 192.168.x.x)连接到此 WSL 实例,还需要额外开启 hostAddressLoopback 实验特性。否则 localhost:<端口> 正常,但 WSL_IP:<端口> 会超时。详见 WSL 虚拟机创建与管理指南.md 第 6 节「网络配置进阶」。

3.2 配置文件结构

📄 文件 📝 用途
/etc/ssh/sshd_config 服务端主配置(修改后要重启 sshd 服务)
/etc/ssh/ssh_config 客户端配置(一般不动)
~/.ssh/authorized_keys 存放客户端公钥,启用免密登录
~/.ssh/known_hosts 客户端记录过的服务端指纹
~/.ssh/id_rsa / id_rsa.pub 客户端的私钥 / 公钥

修改 sshd_config强烈建议先备份:

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

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

sudo vim /etc/ssh/sshd_config
# =============================================
# 基础配置
# =============================================
# 监听端口(生产建议改为非默认端口,降低被扫描爆破概率)
Port 22

# 监听地址(0.0.0.0 = 所有网卡;如仅内网访问可改为内网IP)
ListenAddress 0.0.0.0

# 协议版本(v2 比 v1 安全)
Protocol 2

# =============================================
# 登录认证(关键)
# =============================================
# 禁止 root 直接登录(必开,AlmaLinux 默认是 yes)
PermitRootLogin no

# 是否允许密码登录。生产推荐 no + 改用密钥登录
PasswordAuthentication yes

# 是否允许空密码(生产环境应设为 no)
PermitEmptyPasswords no

# 公钥认证(密钥免密登录)
PubkeyAuthentication yes
AuthorizedKeysFile      .ssh/authorized_keys

# =============================================
# 安全加固
# =============================================
# 最大重试次数
MaxAuthTries 3

# 最大并发未认证连接
MaxSessions 5

# 登录超时(30 秒无输入断开)
LoginGraceTime 30

# 客户端空闲超时(600 秒无操作断开)
ClientAliveInterval 60
ClientAliveCountMax 10

# 禁止 X11 转发(图形转发,服务器无必要)
X11Forwarding no

# 限制登录用户/组(白名单)
AllowUsers youruser
# AllowGroups ssh-users

# =============================================
# 显示与日志
# =============================================
# 登录前后显示的 banner 文件路径(可选)
# Banner /etc/issue.net

# 日志级别
LogLevel VERBOSE

# =============================================
# AlmaLinux 9 特有:SELinux 相关
# =============================================
# SELinux 启用时,chroot 目录权限由 SELinux 策略控制
# 一般保持默认即可

📋 配置说明

  • PermitRootLogin no:禁止 root 直登,运维需用普通用户 + sudo 提权。
  • PasswordAuthentication yes → 后续验证完密钥登录后可改为 no
  • AllowUsers youruser:把 youruser 替换为你的实际登录用户,多用户用空格分隔

3.4 启动 SSH 并加入开机自启

# 检查配置语法(非常关键,避免配错导致无法登录)
sudo sshd -t
# 若命令无输出,则表示语法正确

# 重启服务
sudo systemctl restart sshd

# 确认开机自启
sudo systemctl enable sshd

# 查看状态
sudo systemctl status sshd

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

3.5 配置密钥免密登录(推荐)

3.5.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
# 提示 passphrase 时可设置密码(更安全),也可直接回车

3.5.2 上传公钥到服务器

方法一:ssh-copy-id(最简单)

# Linux / macOS / Windows 11 (PowerShell 自带 OpenSSH)
ssh-copy-id -i ~/.ssh/id_rsa.pub youruser@服务器IP
# 输入一次密码后即完成

方法二:手动复制

# 在客户端打印公钥
cat ~/.ssh/id_rsa.pub

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

📋 AlmaLinux 9 + SELinux 注意

  • 默认 SELinux 策略下,~/.ssh/chmod 700 + authorized_keyschmod 600 已正确打标
  • 如果还是登录失败,先 restorecon -R -v ~/.ssh 恢复 SELinux 上下文

3.5.3 关闭密码登录

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

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

3.6 防火墙放行 SSH

AlmaLinux 默认使用 firewalld(与 Ubuntu 的 ufw 风格不同,但功能等价):

# 查看 firewalld 状态
sudo firewall-cmd --state
sudo firewall-cmd --list-all

# 放行 SSH(默认就是放行的,这里再确认一次)
sudo firewall-cmd --permanent --add-service=ssh

# 重载配置
sudo firewall-cmd --reload

# 验证
sudo firewall-cmd --list-services | grep ssh

💡 SSH 服务的服务名

  • firewalld 预定义服务名是 ssh(不是 sshd),内部对应 /usr/lib/firewalld/services/ssh.xml
  • 改了 SSH 端口(如 2222)时,要手动添加:sudo firewall-cmd --permanent --add-port=2222/tcp

四、常用工具集

💡 章节定位:本节是 SSH 配好之后紧接着要做的——补齐开发/运维常用的命令工具。WSL 默认 rootfs 没有这些,每次新建 WSL 都要装一遍。

网络、主机名、时区、更新源等"系统级"配置放 五、网络与系统配置;安全加固放 六、安全与优化;WSL 专属配置放 七、WSL 用户专属指南

4.1 一键安装清单

# =============================================
# 网络工具
# =============================================
# net-tools: netstat / ifconfig / route 等传统命令
# iproute:   ip / ss / tc 等新一代命令(AlmaLinux 自带)
# bind-utils:nslookup / dig / host
# iputils:   ping
# traceroute:路由追踪
sudo dnf install -y net-tools bind-utils iputils traceroute mtr NetworkManager NetworkManager-libnm

# =============================================
# 编辑器与文件处理
# =============================================
# vim: 增强版 vi
# nano: 简单文本编辑器
# unzip / p7zip / p7zip-plugins: 解压 zip / 7z
# lrzsz: rz / sz 上传下载(Xshell/SecureCRT 适用)
sudo dnf install -y vim nano unzip p7zip p7zip-plugins lrzsz

# =============================================
# 版本控制
# =============================================
# git: 分布式版本控制
sudo dnf install -y git

# =============================================
# Shell 增强
# =============================================
# bash-completion: 命令补全
# zsh + oh-my-zsh: 更友好的 shell
# tmux: 终端复用器(断线不丢任务)
sudo dnf install -y bash-completion tmux

# =============================================
# 时间同步
# =============================================
# chrony: AlmaLinux 默认的 NTP 客户端
sudo dnf install -y chrony

# =============================================
# SELinux 工具
# =============================================
# policycoreutils: 提供 getenforce / setenforce / sestatus
sudo dnf install -y policycoreutils

# =============================================
# 系统监控与诊断
# =============================================
# htop: 增强版 top
# iotop: 磁盘 IO 监控
# iftop: 网络流量监控
# sysstat: iostat / mpstat / sar
# lsof: 查看打开的文件
# strace: 系统调用跟踪
# ncdu: 交互式磁盘占用分析
sudo dnf install -y htop iotop iftop sysstat lsof strace ncdu

# =============================================
# 开发工具链(按需)
# =============================================
# gcc / gcc-c++ / make / automake / autoconf
# python3 / pip3
# java-17-openjdk
# nodejs / npm
# sudo dnf install -y gcc gcc-c++ make automake autoconf \
#   python3 python3-pip \
#   java-17-openjdk \
#   nodejs npm

# =============================================
# 文本搜索 / 处理
# =============================================
# ripgrep (rg): 更快更现代的 grep
# fd-find (fd): 更快更现代的 find
# jq: 命令行 JSON 处理
# tree: 目录树展示
# 注:AlmaLinux 包名是 fd-find(提供 fd 命令,需要 alias 或建软链)
sudo dnf install -y ripgrep fd-find jq tree
# fd-find 在 AlmaLinux 上是 /usr/bin/fd,要 alias 成 fd 才顺手
echo "alias fd='fd-find'" >> ~/.bashrc

# =============================================
# 安全相关
# =============================================
# fail2ban: 防 SSH 暴力破解
# firewalld: 防火墙(默认已装)
sudo dnf install -y fail2ban

📋 装完验证

# 一次性看哪些工具可用
for tool in htop tmux jq tree vim git curl wget dnf mtr; do
  if command -v $tool &> /dev/null; then
    echo "✅ $tool"
  else
    echo "❌ $tool 缺失"
  fi
done

4.2 工具速查表

🔧 工具 📝 用途 📋 常用命令
netstat 网络连接/端口查看 netstat -tlnp
ss 现代版 netstat ss -tlnpss -s
ip 网络配置 ip addrip route
nmcli NetworkManager 命令行 nmcli connection show
dig DNS 查询 dig baidu.com
mtr 网络诊断(ping+traceroute) mtr baidu.com
vim 文本编辑 vim /etc/hosts
tmux 终端复用 tmux new -s name
htop 进程监控 htop
iotop 磁盘 IO 监控 sudo iotop
iftop 流量监控 sudo iftop -i ens33
lsof 查看打开的文件 lsof -i :8080
tree 目录树 tree -L 2 /data
jq JSON 处理 cat x.json | jq .
rg 快速搜索 rg "error" /var/log

4.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

4.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

4.5 配置 bash 提示符(可选)

vim ~/.bashrc

在末尾追加:

# 彩色提示符
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 ..'
source ~/.bashrc

💡 AlmaLinux 默认 bash 提示符是 [\u@\h \W]\$ ,只显示最后一级目录名(W = basename of PWD);想显示完整路径用 \w

PS1='[\u@\h \w]\$ '

五、网络与系统配置

5.1 配置静态 IP(NetworkManager / nmcli,仅真机/云服务器

⚠️ 本节仅适用于真机 / 云服务器 / VMware/VirtualBox 虚拟机。WSL2 用户请直接跳过本节

  • WSL 装的发行版默认没装 NetworkManager(连 nmcli 命令都没有)
  • WSL 微软官方镜像里 NetworkManager.servicemask(屏蔽),即使手动 dnf install 装上,systemctl enable 也会报 Unit file ... is masked
  • WSL 网络由 Windows 虚拟网卡管理,Linux 侧任何网络配置都改不动
  • 详见 七、WSL 用户专属指南 第 7.0 节

⚠️ WSL 下误装 NetworkManager 的清理方式

# 如果已经装了但 enable 失败,先取消 mask
sudo systemctl unmask NetworkManager
# 然后关掉(WSL 下完全不需要)
sudo systemctl disable --now NetworkManager 2>/dev/null || true
# 彻底不想要可以卸载
# sudo dnf remove NetworkManager NetworkManager-libnm

AlmaLinux 9 统一使用 NetworkManager 管理网络(取代传统的 network-scripts)。命令行工具是 nmcli,图形化工具是 nmtui

# 真机/云服务器:NetworkManager 通常已装,没装再装
sudo dnf install -y NetworkManager
sudo systemctl enable --now NetworkManager

# 查看网卡名称和当前连接
nmcli device status
# 输出示例:
# DEVICE  TYPE      STATE         CONNECTION
# ens33   ethernet  connected     ens33
# lo      loopback  unmanaged     --

# 查看当前连接的 IP 信息
nmcli connection show ens33

用 nmcli 配静态 IP(推荐,可重复执行):

# 1. 设置 IPv4 地址、子网掩码、网关
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"

# 2. 激活新配置
sudo nmcli connection up ens33

# 3. 验证
ip -br addr show ens33

用 nmtui 配(图形化,更直观)

sudo nmtui
# 选 Edit a connection → 选 ens33 → 改 IPv4 配置为 Manual → 填 IP / 网关 / DNS
# 选 Activate a connection 让新配置生效

⚠️ 远程操作注意:改 IP 后 nmcli connection up 会立即切换 IP,远程连接会断——确保你有其他方式连入(如云厂商控制台、KVM 直连),或者先在本地试好再上远程。

💡 WSL2 用户:本节对你不适用。详见 七、WSL 用户专属指南

5.2 配置主机名

# 查看当前主机名
hostnamectl

# 设置主机名(替换 dev-workspace 为你想要的名字)
sudo hostnamectl set-hostname dev-workspace

⚠️ hostnamectl 改了 /etc/hostname,但不会自动改 /etc/hosts!

hostnamectl set-hostname 只负责:

  • 写入 /etc/hostname
  • 通知 systemd-hostnamed 更新主机名状态

不会自动写入 /etc/hosts,所以改完主机名后必须手动追加一行,否则 sudo 会报 unable to resolve host

# 追加新主机名到 /etc/hosts(追加,不是覆盖!)
echo "127.0.1.1 dev-workspace" | sudo tee -a /etc/hosts

# 验证 sudo 不再报警
sudo whoami

完整的 /etc/hosts 应该长这样

127.0.0.1   localhost
127.0.1.1   dev-workspace

💡 WSL2 用户:本节命令通用(启用 systemd 后),但操作步骤略有不同(要同步配 /etc/wsl.conf、在 PowerShell 重启 WSL)。详见 7.2 WSL 主机名设置

5.3 时区与时间同步

# 查看当前时区
timedatectl

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

# AlmaLinux 默认自带 chrony(不是 systemd-timesyncd)
sudo systemctl enable --now chronyd
timedatectl status

📋 说明

  • 服务器与客户端的时间偏差超过 5 分钟会导致部分协议(如 Kerberos)失败。
  • AlmaLinux 9 默认是 chrony(比 systemd-timesyncd 精度高、适合生产)。
  • 如需切回 systemd-timesyncdsudo dnf install -y systemd-timesyncd && sudo systemctl disable --now chronyd && sudo systemctl enable --now systemd-timesyncd

💡 WSL2 用户:WSL2 时间默认和 Windows 同步(启动时校准一次),一般不需要单独配。详见 7.3 WSL 时区(可选)

5.4 关闭 AlmaLinux 默认组件(按需)

# 关闭 kdump(内核转储服务,节省内存)
sudo systemctl disable --now kdump.service

# 关闭防火墙自动发现相关(按需)
# sudo systemctl disable --now mdmonitor.service

# 查看所有已启用服务,按需关闭
sudo systemctl list-unit-files --state=enabled

📋 AlmaLinux 默认开机的服务(vs Ubuntu):

服务 AlmaLinux 默认 Ubuntu 默认 说明
firewalld ❌(用 ufw) 防火墙
chronyd ❌(用 systemd-timesyncd) 时间同步
kdump 内核崩溃转储
sssd 身份认证(可选)
snapd Snap 包管理

5.5 配置 dnf 更新源

💡 本节针对 AlmaLinux 9 默认源/etc/yum.repos.d/almalinux.repo/etc/yum.repos.d/almalinux-appstream.repo 等)。
9.x 用 alma 作为 repo id(AlmaLinux 8 用 base / AppStream),具体看 ls /etc/yum.repos.d/

5.5.1 验证当前源

# 1. 确认 AlmaLinux 版本
cat /etc/almalinux-release
# 输出示例:AlmaLinux release 9.4 (Seafoam Ocelot)

# 2. 看默认源
ls /etc/yum.repos.d/
# 关键文件:
#   almalinux.repo          ← 基础源(os / baseos)
#   almalinux-appstream.repo
#   almalinux-extras.repo
#   almalinux-highavailability.repo(可能没有)
#   epel.repo(装了 EPEL 才有)

# 3. 看默认 baseurl
grep "^mirrorlist\|^baseurl" /etc/yum.repos.d/almalinux.repo | head -10

5.5.2 备份默认源

# 备份所有默认 repo
sudo mkdir -p /etc/yum.repos.d.bak.$(date +%Y%m%d%H%M%S)
sudo cp /etc/yum.repos.d/*.repo /etc/yum.repos.d.bak.$(date +%Y%m%d%H%M%S)/

5.5.3 替换为阿里云源(国内推荐)

方法一:一键替换(推荐)

# 阿里云提供的 mirrorlist 替换脚本(同时改 baseos / appstream / extras / highavailability / debuginfo 等)
sudo sed -i.bak \
  -e 's|mirrorlist=|#mirrorlist=|g' \
  -e 's|^# baseurl=https://repo.almalinux.org|baseurl=https://mirrors.aliyun.com|g' \
  /etc/yum.repos.d/almalinux*.repo

# 验证改对了
grep "^baseurl" /etc/yum.repos.d/almalinux.repo

方法二:手动编辑(想完全控制内容时用)

sudo vim /etc/yum.repos.d/almalinux.repo

完整示例(AlmaLinux 9):

# =============================================
# /etc/yum.repos.d/almalinux.repo
# 阿里云镜像(AlmaLinux 9)
# =============================================
[baseos]
name = AlmaLinux 9 - BaseOS
mirrorlist = https://mirrors.almalinux.org/mirrorlist/9/baseos
# baseurl = https://repo.almalinux.org/almalinux/9/BaseOS/$basearch/os/
baseurl = https://mirrors.aliyun.com/almalinux/9/BaseOS/$basearch/os/
enabled = 1
gpgcheck = 1
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-AlmaLinux-9

[appstream]
name = AlmaLinux 9 - AppStream
mirrorlist = https://mirrors.almalinux.org/mirrorlist/9/appstream
# baseurl = https://repo.almalinux.org/almalinux/9/AppStream/$basearch/os/
baseurl = https://mirrors.aliyun.com/almalinux/9/AppStream/$basearch/os/
enabled = 1
gpgcheck = 1
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-AlmaLinux-9

[extras]
name = AlmaLinux 9 - Extras
mirrorlist = https://mirrors.almalinux.org/mirrorlist/9/extras
# baseurl = https://repo.almalinux.org/almalinux/9/extras/$basearch/os/
baseurl = https://mirrors.aliyun.com/almalinux/9/extras/$basearch/os/
enabled = 1
gpgcheck = 1
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-AlmaLinux-9

5.5.4 配置 EPEL 源(重要)

AlmaLinux 9 默认带 EPEL,但很多常用包(p7zipfail2banhtop 在 baseos 已有,fzffd-find 等可能在 EPEL)需要:

# 1. 装 EPEL 的 rpm 包(用阿里云镜像)
sudo dnf install -y https://mirrors.aliyun.com/epel/epel-release-latest-9.noarch.rpm

# 2. 启用 crb(CodeReady Builder,包含开发工具链的元数据)
sudo dnf config-manager --enable crb
# 也可能名字是 powertools,取决于版本:
# sudo dnf config-manager --enable powertools

# 3. 替换 EPEL 默认源为阿里云
#    注意:默认 epel.repo 里 baseurl 是被 # 注释掉的占位符(#baseurl= https://download.example/... ),
#         没有未注释的 baseurl 行可匹配——直接用 tee 覆盖最稳
sudo tee /etc/yum.repos.d/epel.repo > /dev/null <<'EOF'
[epel]
name=Extra Packages for Enterprise Linux 9 - $basearch
baseurl=https://mirrors.aliyun.com/epel/9/Everything/$basearch
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-9

[epel-debuginfo]
name=Extra Packages for Enterprise Linux 9 - $basearch - Debug
baseurl=https://mirrors.aliyun.com/epel/9/Everything/$basearch/debug
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-9
gpgcheck=1

[epel-source]
name=Extra Packages for Enterprise Linux 9 - $basearch - Source
baseurl=https://mirrors.aliyun.com/epel/9/Everything/source/tree
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-9
gpgcheck=1
EOF

# 4. 验证
grep "^baseurl" /etc/yum.repos.d/epel.repo
# 期望:看到 3 行 baseurl=https://mirrors.aliyun.com/epel/9/Everything/...

5.5.5 应用并验证

# 重建缓存
sudo dnf clean all
sudo dnf makecache

# 升级所有已装包
sudo dnf upgrade -y

# (可选)清理无用包
sudo dnf autoremove -y

验证用的是阿里云源

# 看每个仓库的 baseurl 列
dnf repolist -v | grep -E "Repo-id|baseurl"
# baseurl 应是 mirrors.aliyun.com

5.5.6 其他国内镜像(按需替换 baseurl

镜像 baseurl 替换模式 说明
阿里云(最稳,首选) repo.almalinux.orgmirrors.aliyun.com/almalinux 同时换 EPEL 源
清华 TUNA repo.almalinux.orgmirrors.tuna.tsinghua.edu.cn/almalinux 学术网友好
中科大 USTC repo.almalinux.orgmirrors.ustc.edu.cn/almalinux 学术网友好
网易 repo.almalinux.orgmirrors.163.com/almalinux 通用
华为云 repo.almalinux.orgmirrors.huaweicloud.com/almalinux 通用
腾讯云 repo.almalinux.orgmirrors.cloud.tencent.com/almalinux 通用

📋 命名差异提醒

  • AlmaLinux 8 仓库 id 叫 base / AppStream(沿用 RHEL 8 命名)
  • AlmaLinux 9 仓库 id 叫 baseos / appstream(沿用 RHEL 9 命名)
  • 写脚本时不要假设 base,先 dnf repolist 确认

5.5.7 常见问题

Q1:换源后 dnf makecacheGPG 错误?

# 重新导入 GPG key(AlmaLinux 9)
sudo rpm --import https://mirrors.aliyun.com/almalinux/RPM-GPG-KEY-AlmaLinux-9

# 验证 key 已装
rpm -qa gpg-pubkey | grep -i almalinux

Q2:换源后 dnf makecache404 Not Found

# 99% 是 baseurl 拼错了(大小写、路径、版本号)
# 正确路径示例:
#   https://mirrors.aliyun.com/almalinux/9/BaseOS/$basearch/os/
#   https://mirrors.aliyun.com/almalinux/9/AppStream/$basearch/os/
#   https://mirrors.aliyun.com/almalinux/9/extras/$basearch/os/
#   https://mirrors.aliyun.com/epel/9/Everything/$basearch/

Q3:想临时恢复默认源?

# 还原备份
sudo cp /etc/yum.repos.d.bak.*/*.repo /etc/yum.repos.d/
sudo dnf clean all
sudo dnf makecache

Q4:怎么加第三方源(如 Docker、Node.js)?

# 例:加 Docker 官方源(AlmaLinux 走 CentOS 9 的源)
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 验证
dnf repolist | grep docker

5.5.8 一键脚本(适合批量初始化)

#!/bin/bash
# 阿里云 dnf 源一键配置(AlmaLinux 9)
set -e

BAK_DIR="/etc/yum.repos.d.bak.$(date +%Y%m%d%H%M%S)"

# 1. 备份
sudo mkdir -p "$BAK_DIR"
sudo cp /etc/yum.repos.d/*.repo "$BAK_DIR/" 2>/dev/null || true
echo "✅ 备份到 $BAK_DIR"

# 2. 替换默认源
if ls /etc/yum.repos.d/almalinux*.repo &>/dev/null; then
  sudo sed -i \
    -e 's|mirrorlist=|#mirrorlist=|g' \
    -e 's|^# baseurl=https://repo.almalinux.org|baseurl=https://mirrors.aliyun.com|g' \
    /etc/yum.repos.d/almalinux*.repo
  echo "✅ 默认源已替换为阿里云"
fi

# 3. 装 EPEL(如果没有)
if ! rpm -q epel-release &>/dev/null; then
  sudo dnf install -y https://mirrors.aliyun.com/epel/epel-release-latest-9.noarch.rpm
  echo "✅ EPEL 已装"
fi

# 4. 替换 EPEL 源(用 tee 直接覆盖,最稳)
if [ -f /etc/yum.repos.d/epel.repo ]; then
  sudo tee /etc/yum.repos.d/epel.repo > /dev/null <<'EOF'
[epel]
name=Extra Packages for Enterprise Linux 9 - $basearch
baseurl=https://mirrors.aliyun.com/epel/9/Everything/$basearch
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-9
EOF
  echo "✅ EPEL 源已覆盖为阿里云"
fi

# 5. 启用 crb(开发工具链元数据源)
sudo dnf config-manager --enable crb 2>/dev/null || true

# 6. 刷新
sudo dnf clean all
sudo dnf makecache
echo "✅ dnf makecache 完成"

保存为 ~/set-aliyun-mirror.sh,跑:

chmod +x ~/set-aliyun-mirror.sh
sudo ~/set-aliyun-mirror.sh

📋 关于 AlmaLinux 版本号

  • AlmaLinux 8 仓库 id 用 base / AppStream(baseurl 子目录 8/
  • AlmaLinux 9 仓库 id 用 baseos / appstream(baseurl 子目录 9/
  • 切换版本时必须baseurl 里的版本号和仓库 id

六、安全与优化

6.1 firewalld 防火墙

详见 3.6 防火墙放行 SSH,补充常用规则:

# 查看所有区域和规则
sudo firewall-cmd --list-all

# 放行 HTTP/HTTPS
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

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

# 富规则:放行指定 IP 段访问 SSH(更安全)
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=192.168.1.0/24 service name=ssh accept'
sudo firewall-cmd --reload

# 富规则:拒绝特定 IP
sudo firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=10.0.0.5 reject'
sudo firewall-cmd --reload

# 删除规则
sudo firewall-cmd --permanent --remove-service=http
sudo firewall-cmd --reload

# 关闭防火墙(不推荐生产)
sudo systemctl stop firewalld
sudo systemctl disable firewalld

⚠️ 远程操作注意:在远程主机上启用防火墙前,先确认 SSH 规则已加firewall-cmd --permanent --add-service=ssh)。firewalld 默认会放行 ssh 服务的默认区域,但自定义规则可能被遗忘。

💡 WSL2 用户:WSL 内 firewalld 跑不起来(微软内核缺 iptables 模块)。详见 七、WSL 用户专属指南 第 7.6 节

6.1.1 重要认知:放行了端口,外部仍可能连不上

🎯 本节适用场景:按上面示例配了 firewall-cmd --permanent --add-port=2211/tcp 后,外部客户端仍然连不上 2211,而 firewall-cmd --list-all 又能看到 2211/tcp 已放行。这是 firewalld zone 模型下最常见的"看起来配了但没生效"的踩坑。

根本原因:firewalld 的规则是挂在 zone 上的,而 zone 又挂在网卡接口上。数据包进入 Linux 后,firewalld 会按"它从哪块网卡进来"找对应的 zone,再按 zone 里的规则判断放行/拒绝。所以:

步骤 数据包进入 → 匹配 zone → 应用 zone 规则
1. 数据包到达网卡 例如从 eth0(公网网卡)进来
2. 找 zone firewalld 看 eth0 绑在哪个 zone
3. 匹配规则 用那个 zone 里的 services / ports / rich-rules 判断

关键点firewall-cmd --add-port=2211/tcp(不带 --zone=)默认写入的是 public zone(firewalld 的默认 zone)。如果 eth0 没绑到 public zone(也没绑到任何带 2211 规则的 zone),那 2211 的放行规则就根本没有机会被命中——数据包走 eth0 的默认 zone(一般是 trusted 之外的某个 zone 或直接被 block),被默默拦截。

典型症状

  • firewall-cmd --list-all 能看到 public zone 有 2211/tcp,但 --zone=public --list-interfaces 输出里没有 eth0
  • firewall-cmd --get-active-zones 显示 eth0docker zone 或其它 zone(不一定有 2211 规则)
  • 外部 telnet <IP> 2211 / ssh -p 2211 / 应用客户端连接都超时
  • 但同主机内 curl http://127.0.0.1:2211 能通(回环不走 firewalld)

为什么会这样(按出现频率排序)

原因 说明
加端口时没指定 zone,默认加到了 public eth0 从一开始就没绑 public(默认是 trusted 之外的 zone,或装 Docker 后被自动挪走)
装了 Docker,docker0 网桥被 firewalld 自动放进了 docker zone 同一时间 eth0 也可能被自动挪到 docker zone(因为 dockerd 改了 iptables 链),但 docker zone 的规则集跟 public 不一样
多网卡场景(eth0 + eth1 + bond0),只把其中一个绑到了 zone 其它网卡上的服务从公网进不来

排查命令

# 1. 看每个 zone 当前绑了哪些接口
firewall-cmd --get-active-zones
# 典型输出:
#   docker
#     interfaces: docker0
#   public
#     interfaces:    ← ⚠️ eth0 没在这里

# 2. 看 public zone 里有哪些规则(确认端口确实加进去了)
firewall-cmd --zone=public --list-all
# 关键看 ports: 行有没有 2211/tcp

# 3. 看 eth0 到底绑在哪个 zone
firewall-cmd --get-zone-of-interface=eth0
# 输出可能是:docker / trusted / nozone

# 4. 看所有 zone 的接口绑定(最全)
firewall-cmd --list-all-zones | grep -E "^[a-z]|interfaces"

# 5. 确认数据包是否真的被 firewalld 拦截(不需要抓包)
sudo firewall-cmd --set-log-denied=all     # 临时开启拒绝日志(重启 firewalld 后失效)
# 然后从外部连一次,看 /var/log/messages:
sudo tail -f /var/log/messages | grep -i "REJECT|DROP"

修复方法(按推荐度排序):

方法 A:把 eth0 显式绑到已放行目标端口的 zone(推荐)

# 假设 2211/tcp 已加在 public zone,把 eth0 也绑到 public
sudo firewall-cmd --zone=public --add-interface=eth0 --permanent
sudo firewall-cmd --reload

# 验证:eth0 现在应在 public zone 下
firewall-cmd --get-active-zones
# public
#   interfaces: eth0

# 从外部再连一次 2211

方法 B:把端口直接加到 eth0 当前所在的那个 zone

# 先查 eth0 在哪个 zone
ZONE=$(firewall-cmd --get-zone-of-interface=eth0)
echo "eth0 当前 zone: $ZONE"

# 把 2211 加到那个 zone
sudo firewall-cmd --zone=$ZONE --add-port=2211/tcp --permanent
sudo firewall-cmd --reload

方法 C:临时把 eth0 加到 trusted(⚠️ 仅本地调试用)

# trusted = 放行所有流量,等于"对这个网卡关防火墙"
sudo firewall-cmd --zone=trusted --add-interface=eth0 --permanent
sudo firewall-cmd --reload
# 调通后**记得改回**对应的 zone,别留着 trusted

方法 D:用富规则(rich-rule)绕过 zone 匹配

# 富规则默认写到 public zone,跟方法 A 等价
sudo firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=0.0.0.0/0 port port=2211 protocol=tcp accept'
sudo firewall-cmd --reload

💡 选哪个方法的判断思路

场景 推荐方法
单网卡服务器,端口明确加在 public A(最直接)
端口在多个 zone 里都要放行(多网卡共用) 把每块网卡分别绑到对应 zone,再 add-port
临时调试 / 验证是不是 zone 配错了 C(trusted),验证完改回
只想对特定 IP 放行(如内网管理端口) D(rich-rule + source address)
服务器装了 Docker,且 dockerd 把 eth0 抢到 docker zone docker network inspect 看 docker 怎么管的 iptables,再决定要不要把 eth0 挪回 public

与 Docker 共存时的额外注意事项

  • dockerd 安装时会自动在 firewalld 里建一个 docker zone(/usr/lib/firewalld/zones/docker.xml),并把 docker0 网桥绑进去
  • docker 启动容器时默认会把端口映射规则写到 iptables 的 DOCKER 链(绕过 firewalld 的 zone 检查),所以容器暴露的端口一般不踩这个坑
  • 宿主机自己起的服务(比如 systemctl 启动的 sshd / nginx / 自定义应用)仍然走 firewalld zone 匹配,需要按上面方法处理
  • 如果 eth0 被 docker 抢到了 docker zone,而 docker zone 默认只放行 docker 通讯相关的端口,宿主机非 docker 服务就会受牵连

WSL2 用户注意

  • WSL2 内 firewalld 跑不起来(详见 7.6),通常已经 disable 了,不会遇到这个坑
  • 但如果 WSL 启用了镜像网络模式(networkingMode=mirrored,详见 WSL 虚拟机创建与管理指南.md),流量走 Windows 宿主侧,由 Windows 防火墙控制,不再走 WSL 内的 firewalld——本节问题在镜像模式下变成"Windows 防火墙是否放行 2211",与本节无关

6.2 fail2ban 防爆破

sudo dnf install -y fail2ban
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 = %(sshd_log)s
backend = %(sshd_backend)s
maxretry = 3

📋 AlmaLinux 9 的 fail2ban 注意

  • /var/log/secure 是 SSH 认证日志(不是 Ubuntu 的 /var/log/auth.log
  • fail2ban 默认配 logpath = %(sshd_log)s,会自动读 /var/log/secure
  • banactionfirewallcmd-rich-rules(通过 firewall-cmd 加富规则封禁),不要写 ufw(Ubuntu 风格)
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

6.3 SELinux 处理

💡 本节是 AlmaLinux / RHEL 系列的特色。Ubuntu / Debian 不需要关心(用 AppArmor)。

6.3.1 SELinux 状态

# 看当前状态
sestatus
# 输出示例:
#   SELinux status:                 enabled
#   SELinuxfs mount:                /sys/fs/selinux
#   SELinux root directory:         /etc/selinux
#   Loaded policy name:             targeted
#   Current mode:                   enforcing
#   Mode from config file:          enforcing

# 三种模式
getenforce
# enforcing / permissive / disabled
模式 行为
enforcing 强制执行(默认)——违反策略的行为被阻止并记日志
permissive 仅警告——不阻止,但记 audit log(用于调试策略)
disabled 完全关闭(不推荐)

6.3.2 临时切换模式

# 临时切到 permissive(重启后失效)
sudo setenforce 0
getenforce
# Permissive

# 切回 enforcing
sudo setenforce 1
getenforce
# Enforcing

6.3.3 永久切换模式

sudo vim /etc/selinux/config
# 把 enforcing 改成 permissive
SELINUX=permissive
# 改完要重启系统生效
sudo reboot

6.3.4 常见 SELinux 故障

症状 1:服务起不来,日志有 SELinux is preventing 警告

# 1. 看完整诊断
sudo ausearch -m avc -ts recent

# 2. 装 setroubleshoot 看人话报告
sudo dnf install -y setroubleshoot
sudo sealert -a /var/log/audit/audit.log

# 3. 让 SELinux 自动生成允许规则(最快)
sudo ausearch -m avc -ts recent | audit2allow -M my-fix
sudo semodule -i my-fix.pp

症状 2:改了 SSH 端口后连不上

# SELinux 限制了 sshd 只能监听预定义端口
# 添加端口到 SELinux 策略
sudo semanage port -a -t ssh_port_t -p tcp 2222
# 或临时关 SELinux 验证
sudo setenforce 0

症状 3:改了 Web 服务目录后访问 403/404

# SELinux 上下文不对
# 看现在是什么类型
ls -Z /var/www/html/
# -rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.html

# 改完目录后恢复上下文
sudo restorecon -Rv /var/www/html/

症状 4:WSL 里的 AlmaLinux 看到一堆 SELinux 警告

💡 WSL2 用户:WSL2 不支持完整 SELinux,详见 七、WSL 用户专属指南 第 7.5 节,那里有完整的 WSL 专属配置脚本(一键切到 permissive + 持久化)。

🔐 安全建议

  • 生产环境:保持 enforcing,遇到问题用 audit2allow 加规则
  • 开发/测试环境permissive 更省心
  • 完全关掉(disabled)不推荐——失去了 SELinux 的最后一道防线

6.4 文件描述符限制

大并发服务(Tomcat、Nginx 等)经常遇到 too many open files 错误。

# 查看当前限制
ulimit -n
# 临时修改(当前会话)
ulimit -n 65535

永久修改:

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

📋 说明

  • * 匹配所有非 root 用户,root 要单独写(limits.conf 规则:通配符不作用于 root)
  • 两组值看起来一样,但不能合并——这是 limits.conf 的限制
  • 没加 nproc:进程数 65535 没意义,默认就够用;除非跑大并发服务(如 MySQL、Kafka)才需要
sudo vim /etc/systemd/system.conf

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

DefaultLimitNOFILE=65535

📋 为什么需要改

  • systemd 默认soft=1024hard=524288
  • 所有用 systemctl 启动的服务(fail2bansshdnginxmysql 等)都受这个限制
  • 默认 1024 对大并发服务不够:nginx 一个连接 2~3 个 FD,1024 / 3 ≈ 340 并发就报 too many open files
  • soft 到 65535 是生产/开发环境的标配
# 重启后生效
sudo reboot

💡 WSL2 用户:不要用 sudo reboot(WSL 下不重读 system.conf)。改完 system.conf 后必须 wsl --shutdown——详见 七、WSL 用户专属指南 第 7.7 节

6.5 内核参数调优

sudo vim /etc/sysctl.d/99-tuning.conf
# =============================================
# 网络优化
# =============================================
# 允许端口复用(TIME_WAIT 快速回收)
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_fin_timeout = 15

# 提升 TCP 缓冲区
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216

# SYN 队列长度(防 SYN 洪水)
net.ipv4.tcp_max_syn_backlog = 8192
net.core.somaxconn = 8192

# 启用 SYN Cookie
net.ipv4.tcp_syncookies = 1

# =============================================
# 安全加固
# =============================================
# 禁用 IP 转发(单机部署不需要)
net.ipv4.ip_forward = 0

# 忽略 ICMP 重定向(防中间人)
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

📋 AlmaLinux 9 + WSL 注意

  • 真机/云服务器:sysctl -p 立即生效
  • WSL2:大部分网络相关参数由 Windows 宿主内核控制,配置仅作记录
  • WSL2 + 启用 systemd 后,sysctl -p 命令本身能跑,但 ip_forwardtcp_* 等设置可能没真正生效

6.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(值越小越倾向用物理内存,推荐 10-30)
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.d/99-tuning.conf
sudo sysctl -p

📋 SELinux + swapfile

  • AlmaLinux 9 默认 SELinux 是 enforcing
  • fallocate 创建的 /swapfile 默认会被正确打标为 swapfile_t
  • 如果 swapon 报 SELinux 错误:sudo restorecon /swapfile

七、WSL 用户专属指南(WSL2 用户必读)

🎯 章节定位:把 WSL 专属操作集中到这一章。真机/云服务器用户可整章跳过

推荐阅读顺序(按章节顺序):

  1. 7.0 补齐缺失包 —— 必做前置(4.1 装完后,再补一遍 WSL 缺的)
  2. 7.1 启用 systemd —— 第二步要做(没启用前 systemctl 都不能用)
  3. 7.2 主机名 —— 消除 sudo unable to resolve host 警告
  4. 7.3 时区 —— 可选(WSL 默认跟 Windows 同步)
  5. 7.4 数据目录规划 —— WSL 重装会丢数据,提前软链到 Windows 盘
  6. 7.5 SELinux —— 减少日志噪音(或跳过,WSL 内 SELinux 跑不起来)
  7. 7.6 firewalld —— WSL 内跑不起来,直接关掉
  8. 7.7 重启正确方式 —— 不要 sudo reboot,要 wsl --shutdown

涵盖内容:

  • 7.0 WSL 精简 rootfs 缺失包补齐(必做前置)
  • 7.1 WSL 启用 systemd + 配 /etc/wsl.conf
  • 7.2 WSL 主机名设置(持久化 + 同步 hosts)
  • 7.3 WSL 时区(已跟 Windows 同步,可选配)
  • 7.4 WSL 数据目录规划
  • 7.5 WSL 内 SELinux 处理(关掉日志噪音)
  • 7.6 WSL 内 firewalld/fail2ban 关掉
  • 7.7 WSL 重启正确方式 + 配置生效规则

🔗 通用 WSL 基础(systemd 启用、镜像网络、hostAddressLoopback 等更细节的内容)详见 WSL 虚拟机创建与管理指南.md 第 4~6 节。AlmaLinux-9 在 WSL 内的行为与 Ubuntu 24.04 几乎完全一致(包管理器不同;WSL 内部机制相同)。

7.0 WSL 精简 rootfs 缺失包补齐(必做前置)

🎯 为什么需要这一节:WSL 微软官方镜像默认是 nano/server 精简版——真机上有的 nmcli / firewall-cmd / getenforce / chronyc / htop / jq / p7zip 都没装。4.1 节的一键安装清单已经覆盖了真机/云服务器场景,但你 WSL 内执行那一段后,本节专治 WSL 精简 rootfs 多出来的"补丁包"。

WSL 默认缺失的命令 / 对应包(在 4.1 基础上额外要装的):

缺失命令 装的包 用途
nmcli NetworkManager NetworkManager-libnm 配 IP(WSL 下用不上但装了不亏)
firewall-cmd firewalld 6.1 配防火墙(WSL 下用不上,要 disable)
getenforce / sestatus policycoreutils 6.3 / 7.5 查 SELinux
chronyc chrony 5.3 时间同步(WSL 下用不上,要 disable)
htop / iotop / iftop / lsof / strace htop iotop iftop sysstat lsof strace 监控/排查
ncdu / jq / tree ncdu jq tree 磁盘/JSON/目录
p7zip / 7z p7zip p7zip-plugins(EPEL) 解压 7z
tmux / bash-completion tmux bash-completion 终端增强

📋 关于 4.1 节和 7.0 节的关系

  • 4.1 节给真机/云服务器用户看,包含全部常用包
  • 7.0 节给 WSL 用户看,只列 WSL 精简 rootfs 额外缺的(4.1 没列但 WSL 没装的)
  • 真机/云服务器用户可跳过本节(4.1 已经全装齐了)
  • WSL 用户两个都要跑:先 4.1,再 7.0 补一遍

WSL 专用补齐命令(注释行不带 \ 续行,分块安装避免 dnf 把 # 当包名):

# === WSL 精简 rootfs 补齐(4.1 之外额外缺的)===
# 前提:已按 5.5.4 装好 EPEL 源(p7zip 在 EPEL 里)

# 网络 / 防火墙(WSL 用不上,装着备用)
sudo dnf install -y NetworkManager NetworkManager-libnm firewalld

# SELinux 工具
sudo dnf install -y policycoreutils

# 时间同步
sudo dnf install -y chrony

# 监控
sudo dnf install -y htop iotop iftop sysstat lsof strace ncdu

# 文本处理
sudo dnf install -y jq tree

# 7z(EPEL)
sudo dnf install -y p7zip p7zip-plugins

# === fd-find 别名(如果 4.1 还没跑)===
echo "alias fd='fd-find'" >> ~/.bashrc
source ~/.bashrc

# === 验证 ===
for tool in getenforce chronyc htop jq tree 7z fd; do
  if command -v $tool &>/dev/null; then
    echo "✅ $tool"
  else
    echo "❌ $tool 缺失"
  fi
done

⚠️ 关键坑

  • dnf 不支持 # 注释——sudo dnf install -y \ 下面跟 # 注释 \ 会被 dnf 当成"包名是注释"
  • 每行用 \ 续行时,注释单独一行写在 dnf——# xxx 紧跟 dnf install 命令会被吞掉但包名解释错
  • 多行包名推荐分块sudo dnf install -y 包1 包2(一行多个)比 `\ 续行更稳

💡 WSL 下"装了也别 enable"

  • firewalld / chrony / fail2ban / NetworkManager 装了之后别 enable(WSL 内跑不起来——详见 7.6)
  • getenforce 能用但返回 Disabled(WSL 内 SELinux 子系统没装,详见 7.5)

7.1 WSL 启用 systemd + 配 /etc/wsl.conf

WSL 装的发行版默认 PID 1 是 init,不是 systemd——所有 systemctl / hostnamectl / timedatectl 工具都不能用。启用 systemd 是 WSL 初始化的第一步

# 写 wsl.conf(必须用整段覆盖,确保 5 个段都在;用 sed 改一行容易匹配不上)
sudo tee /etc/wsl.conf > /dev/null << 'EOF'
[user]
default = root

[boot]
systemd = true

[automount]
enabled = true
mountFsTab = true

[interop]
enabled = true
appendWindowsPath = true

[network]
generateHosts = false
hostname = alma9-workspace
EOF

⚠️ 关键提醒

  • 必须 5 个段都写(user / boot / automount / interop / network)—— 缺段会导致配置不生效
  • hostname = alma9-workspace 写在 [network](不在 [host] 或别的地方)—— 这是 WSL 唯一识别的位置
  • 别用 sed 改一行—— 等号前后的空格、= true vs =true 都可能让 sed pattern 匹配不上;用 tee 整段覆盖最稳

📋 各段作用

  • [user] default = root —— WSL 默认登录用户(你的发行版默认就是 root,可改成普通用户)
  • [boot] systemd = true —— 启用 systemd(systemctl / hostnamectl 等工具的前提)
  • [automount] enabled/mountFsTab = true —— 自动挂载 Windows 盘(/mnt/c/mnt/d
  • [interop] enabled/appendWindowsPath = true —— 允许从 WSL 调 Windows 程序 + 把 Windows PATH 加进来
  • [network] generateHosts = false —— 阻止 WSL 覆盖 /etc/hosts(改了主机名/自定义 hosts 时必加)
  • [network] hostname = xxx —— WSL 启动时强制把 Linux 主机名设成这个值(不被 Windows 计算机名覆盖)

在 Windows PowerShell 重启 WSL

wsl --shutdown
wsl -d AlmaLinux-9-DockerCompose

回到 WSL 验证

# PID 1 应该是 systemd
ps -p 1 -o comm=
# 期望输出:systemd

# hostname 应该是 wsl.conf 里设的
hostname
# 期望输出:alma9-workspace

⚠️ 不要用 sudo reboot 重启 WSL——WSL 不是真硬件,reboot 只杀进程、不会重读 wsl.conf必须在 Windows PowerShell 跑 wsl --shutdown。详见 7.7

7.2 WSL 主机名设置

📋 前置:先完成 7.1 WSL 启用 systemd——wsl.conf 必须写完整(5 个段都在),否则即使改了主机名也持久化不了。

7.2.1 核心认知:/etc/wsl.conf 才是"主"

WSL 主机名有两层"控制权":

来源 优先级 作用
/etc/wsl.conf[network] hostname = xxx 优先 每次 WSL 启动时由 Windows 侧读取,强制覆盖 Linux 主机名
hostnamectl set-hostname xxx 次之 运行时改主机名,但重启后会被 wsl.conf 覆盖
Windows 计算机名 默认 啥都没配时,WSL 用 Windows 计算机名当 Linux 主机名

关键点你必须在 wsl.conf 里写 hostname = xxx,单靠 hostnamectl 是持久化不了的

7.2.2 完整步骤

第 1 步:确认 wsl.conf 已经写对

cat /etc/wsl.conf
# 必须包含这 5 个段:[user] / [boot] / [automount] / [interop] / [network]
# 关键是 [network] 段:
#   [network]
#   generateHosts = false
#   hostname = alma9-workspace

如果 wsl.conf 缺段或 hostname 不是你想的,tee 整个覆盖(不要用 sed 改一行——sed 的 pattern 不一致容易匹配不上):

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

[boot]
systemd = true

[automount]
enabled = true
mountFsTab = true

[interop]
enabled = true
appendWindowsPath = true

[network]
generateHosts = false
hostname = alma9-workspace
EOF

⚠️ 常见踩坑

  • wsl.conf 只有 1~2 段(如只写了 [boot] systemd=true)—— 持久化失效,Windows 计算机名会覆盖
  • 用 sed 改一行 hostname 失败—— sed 的 pattern 跟 wsl.conf 里的格式(等号前后空格、= true vs =true)对不上,匹配不到。tee 整段覆盖最稳
  • 改了 wsl.conf 但没 wsl --shutdown——配置不会生效

第 2 步:Windows PowerShell 重启 WSL

# 必须用 wsl --shutdown(不是 wsl -d 重开)
wsl --shutdown

# 然后再进
wsl -d AlmaLinux9-DockerCompose

⚠️ 怎么确认"真的重启了"

  • 进 WSL 后立刻看主机名:应该是 wsl.conf 里写的(不是 Windows 计算机名)
  • 如果还是 Windows 计算机名 = wsl.conf 没生效

第 3 步:WSL 内补全配置(保险)

# 1. 同步 /etc/hosts(追加,不是覆盖!)
echo "127.0.1.1 alma9-workspace" | sudo tee -a /etc/hosts

# 2. 可选:hostnamectl 也设一遍(当前会话立即生效;wsl.conf 持久化)
sudo hostnamectl set-hostname alma9-workspace

# 3. 验证 sudo 不再报警
sudo whoami
# 应直接返回 root,无 "unable to resolve host" 警告

7.2.3 验证清单

✅ 检查项 🔧 命令 🎯 预期
主机名是预期值 hostname alma9-workspace
wsl.conf 写对了 cat /etc/wsl.conf 含 5 段,[network] hostname = alma9-workspace
hosts 有手动加的行 grep "$(hostname)" /etc/hosts 看到 127.0.1.1 alma9-workspace
sudo 不报警 sudo whoami 直接返回 root,无 "unable to resolve host"
systemd 启用了 ps -p 1 -o comm= systemd(不是 init

7.2.4 故障排查

症状 原因 解决
wsl --shutdown 后 hostname 还是 Windows 计算机名 wsl.conf 没生效 / 段不全 tee 整段覆盖 wsl.conf,再 wsl --shutdown
sudo 报 "unable to resolve host xxx" /etc/hosts 没加那行 echo "127.0.1.1 $(hostname)" | sudo tee -a /etc/hosts
hostnamectl set-hostname 改了但重启丢失 wsl.conf 没写 hostname = xxx 改 wsl.conf(不要只靠 hostnamectl)
sed 改 wsl.conf 一行没生效 pattern 跟实际格式不匹配(空格、大小写) tee 整段覆盖

7.3 WSL 时区(可选)

WSL2 的时间默认和 Windows 同步(WSL 启动时从 Windows 校准一次),所以一般不需要单独配时区。如果发现时间漂移:

# 强制跟 Windows 校准
sudo hwclock -s

# 或显式设时区(启用 systemd 后才生效)
sudo timedatectl set-timezone Asia/Shanghai

7.4 WSL 数据目录规划

WSL2 本质是一个 ext4 虚拟磁盘文件ext4.vhdx)挂载到 /。WSL 出问题需要重装、迁移、换发行版时,根目录里的数据会全部丢失;但 /mnt/c//mnt/d/ 是直接读 Windows 文件系统,完全不受影响

7.4.1 先理解 WSL2 的"磁盘"是怎么回事

df -h

典型输出(已实测 WSL2 AlmaLinux-9):

/dev/sde       1007G  2.0G  954G   1% /                  ← 根目录所在的虚拟磁盘(最大块)
/dev/sdd       1007G  5.3G  951G   1% /mnt/wsl/...      ← Docker Desktop 存储(也是 vhdx)
none            7.8G  ...   ...   ... /mnt/wsl/drivers   ← WSL 内部通道挂载(不是存储)
C:\             401G  305G   96G  77% /mnt/c             ← Windows C 盘
D:\             552G  397G  155G  72% /mnt/d             ← Windows D 盘

📋 AlmaLinux-9 vs Ubuntu 24.04 在 WSL2 上的关键差异

  • AlmaLinux-9 自带 /data(CentOS/RHEL 传统),WSL2 装的版本同样会建
  • 默认有 /data/srv、但没有 /opt 下的具体服务目录
  • SELinux 配置文件 /etc/selinux/config 默认是 enforcing(WSL2 实际不强制执行,但写在那里)

7.4.2 推荐:把重要数据放到 Windows 盘

为什么? WSL 出问题需要重装、迁移、换发行版时,根目录里的数据会全部丢失;但 /mnt/c//mnt/d/ 是直接读 Windows 文件系统,完全不受影响

# 1. 在 Windows D 盘建一个固定目录(PowerShell 或文件管理器都行)
#    路径示例:D:\wsl-data

# 2. 在 WSL 里建软链接(个人数据放这)
mkdir -p /mnt/d/wsl-data
ln -s /mnt/d/wsl-data ~/data

# 3. 给项目、数据库、下载等建子目录
mkdir -p /mnt/d/wsl-data/{projects,downloads,backups,db,logs}

# 4. 验证
ls -ld ~/data
df -h /mnt/d

💡 软链 vs 直接挂载

  • 软链(推荐)→ ~/data/mnt/d/wsl-data,既能在 WSL 用,也能在 Windows 资源管理器直接打开
  • /mnt/d/ 路径直接用也行,但路径长、可读性差

7.4.3 AlmaLinux 默认就有 /data,但建议结合软链使用

AlmaLinux / RHEL / CentOS 装出来的 WSL 实例默认就有 /data 目录(保留 CentOS 传统)。这是发行版设计理念的差异:

发行版 默认有没有 /data 原因
AlmaLinux / RHEL / CentOS ✅ 有 安装器按"服务器用途"分区模板自动创建(/bootswap//home/data
Ubuntu / Debian ❌ 没有 严格遵守 FHS/ 下只放系统目录,业务目录由用户/管理员自己规划

AlmaLinux /data 的传统用途

  • 放第三方应用(Oracle、MySQL 早期默认数据目录)
  • 放业务服务数据(公司内部约定的"业务数据根目录")
  • 隔离系统盘和业务盘(/ 满了 /data 还能撑)

WSL2 下推荐

场景 建议
WSL 跑服务(Docker Compose、数据库) ✅ 用 /data 存服务数据(AlmaLinux 习惯)
个人临时数据 ✅ 用 ~/data 或软链到 /mnt/d/wsl-data
WSL 重装不能丢的 ✅ 必放 /mnt/d/wsl-data(WSL 重装会重置 /data
跑生产服务(数据库、消息队列) ✅ 放 /data/<service>,或 /srv/<service>(FHS 标准)

⚠️ 重要提醒WSL 重装/换发行版会重置整个 /(包括 /data),重要数据务必放 /mnt/c/mnt/d 或外部盘。

7.4.4 在根目录建 /data 也可行,但需充分了解其风险与限制

# AlmaLinux 默认就有 /data,只需确保权限
ls -ld /data
# dr-xr-xr-x. 2 root root ... /data
# 默认 root 拥有且只读,其他用户写不进去,需要 chmod
sudo chown -R $USER:$USER /data
# 或建子目录
sudo mkdir -p /data/{mysql,redis,logs}
sudo chown -R $USER:$USER /data

适用场景:临时数据、容器卷、一次性实验。
不适用场景:长期重要数据、数据库文件、git 仓库、备份(一旦 WSL 损坏就丢了)。

7.4.5 重要:定期回收虚拟磁盘空间

WSL2 的 ext4.vhdx稀疏文件——在 WSL 里 rm 一个大文件,Windows 侧的 vhdx 不会自动缩小。长时间使用后,Windows 资源管理器显示 vhdx 文件大小为 500 GB,但 WSL 内部实际数据仅占 50 GB。

先确认你的 ext4.vhdx 在哪

# 方法 1:wsl 命令直接显示(PowerShell)
wsl -l -v

# 方法 2:全盘搜 ext4.vhdx(最通用)
Get-ChildItem C:\,D:\,E:\ -Recurse -Filter ext4.vhdx -ErrorAction SilentlyContinue | Select-Object FullName, Length

# 方法 3:按安装方式找
# - Microsoft Store 安装: %LOCALAPPDATA%\Packages\...\LocalState\ext4.vhdx
# - 手动 wsl --import:  你 import 时指定的路径,如 D:\wsl\AlmaLinux-9-DockerCompose\ext4.vhdx

手动回收(PowerShell 管理员)

# 1. 关闭所有 WSL 实例
wsl --shutdown

# 2. 用 diskpart 压缩
diskpart

进入 diskpart 后输入:

select vdisk file="D:\wsl\AlmaLinux-9-DockerCompose\ext4.vhdx"
compact vdisk
exit

⚠️ 注意

  • 管理员 PowerShell 运行(否则 diskpart 报"权限不足")
  • WSL 要已关(否则 vhdx 被占用会报"文件正被另一个进程使用")
  • compact vdisk 期间会临时再占用 1~2 倍当前 vhdx 大小的空闲空间(D 盘至少留 50%)

一键脚本(推荐每月跑一次)——把脚本放在 D:\wsl\compact-almalinux9.ps1

# =============================================
# D:\wsl\compact-almalinux9.ps1
# 用途:回收 AlmaLinux-9 WSL2 虚拟磁盘空间
# 用法:右键 → 使用 PowerShell 管理员运行
# =============================================

# 1. 关闭所有 WSL 实例
wsl --shutdown
Start-Sleep -Seconds 3

# 2. 配置 vhdx 路径(手动 import 时的路径)
$vhdxPath = "D:\wsl\AlmaLinux-9-DockerCompose\ext4.vhdx"

# 如果用 Microsoft Store 版,把上面换成:
# $vhdxPath = "$env:LOCALAPPDATA\Packages\*AlmaLinux*AlmaLinux-9*\LocalState\ext4.vhdx" | Get-ChildItem | Select-Object -First 1 -ExpandProperty FullName

# 3. 校验
if (-not (Test-Path $vhdxPath)) {
    Write-Error "❌ 找不到 vhdx:$vhdxPath"
    Write-Host "请用 Get-ChildItem 搜索 vhdx 位置后修改脚本"
    exit 1
}

$beforeGB = [math]::Round((Get-Item $vhdxPath).Length / 1GB, 2)
Write-Host "📦 压缩前:$beforeGB GB" -ForegroundColor Cyan

# 4. 写临时 diskpart 脚本
$tmp = Join-Path $env:TEMP "compact-wsl-$PID.txt"
"select vdisk file=`"$vhdxPath`"" | Out-File -Encoding ascii $tmp
"compact vdisk" | Out-File -Append -Encoding ascii $tmp

# 5. 执行(会跑几十秒到几分钟)
diskpart /s $tmp
Remove-Item $tmp

# 6. 报告
$afterGB = [math]::Round((Get-Item $vhdxPath).Length / 1GB, 2)
$saved = [math]::Round($beforeGB - $afterGB, 2)
Write-Host "📦 压缩后:$afterGB GB(回收 $saved GB)" -ForegroundColor Green

定时自动回收(每月 1 号凌晨 2 点):

# 在管理员 PowerShell 里执行一次
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File D:\wsl\compact-almalinux9.ps1"
$trigger = New-ScheduledTaskTrigger -Monthly -DaysOfMonth 1 -At "02:00"
Register-ScheduledTask -TaskName "WSL Compact AlmaLinux9 vhdx" -Action $action -Trigger $trigger -RunLevel Highest -Description "每月压缩 AlmaLinux-9 WSL 虚拟磁盘"

7.4.6 常见误区

误区 正确做法
"在 / 建文件夹要分配空间" mkdir 只创建目录项,不预分配磁盘空间;写入文件时才实际占用
"none 7.8G 满了怎么办" none 是 WSL 内部 9P 通道(内存映射),不是磁盘存储;占用高时重启 WSL(wsl --shutdown)即可释放
"WSL 里删了大文件,Windows 磁盘空间没释放" WSL2 的 ext4.vhdx 是稀疏文件,删除文件后不会自动缩小;需要用 diskpart compact vdisk 手动压缩回收
"根目录可以无限写" ext4.vhdx 配置上限限制(默认 256 GB,可手动扩展)
"重装 WSL 还能找到根目录数据" 不能!WSL 重装会重置根目录;重要数据务必放 /mnt/c/mnt/d 或外部盘

7.4.7 WSL 常用运维命令

# 查看 WSL 版本和状态(Windows PowerShell)
wsl -l -v

# 关闭所有 WSL 实例
wsl --shutdown

# 导出当前发行版做备份(PowerShell)
wsl --export AlmaLinux-9-DockerCompose D:\wsl-backup\almalinux9-$(Get-Date -Format yyyyMMdd).tar

# 从备份恢复(PowerShell)
wsl --import AlmaLinux-9-DockerCompose D:\wsl\AlmaLinux-9-DockerCompose D:\wsl-backup\almalinux9-xxx.tar

# 设置默认登录用户(在 /etc/wsl.conf 加):
# [user]
# default = youruser

💡 AlmaLinux-9 WSL 默认用户提示

  • wsl --install -d AlmaLinux-9 装出来默认是 root
  • 第一次进入会强制让你建一个普通用户(输完用户名密码后默认登录该用户)
  • wsl.conf[user] default = xxx 不会自动写——要手动配

7.4.8 WSL 网络配置与 Windows 互通

💡 谁需要看本节:WSL2 用户(Microsoft Store 安装 / wsl --import / LxRunOffline 任一方式)。
❌ 谁可以跳过:物理机、云服务器、VMware/VirtualBox 虚拟机用户(按 5.1 节 nmcli 配置即可)。

WSL 启用 systemd、配置主机名、镜像网络、hostAddressLoopback 等通用 WSL 知识,详见 WSL 虚拟机创建与管理指南.md 第 4~6 节。AlmaLinux-9 在 WSL 内的行为与 Ubuntu 24.04 几乎完全一致(包管理器、systemd 工具链不同;WSL 内部机制相同)。

AlmaLinux-9 在 WSL 内的常见调整

# 1. 启用 systemd(参考 7.1)
sudo tee /etc/wsl.conf > /dev/null << 'EOF'
[user]
default = youruser

[boot]
systemd=true

[network]
generateHosts = false
hostname = alma9-workspace
EOF

# 2. 切到 nftables 后端(WSL 内 firewalld 跑不起来,要 disable)
sudo systemctl disable --now firewalld

# 3. 启用时间同步(如果用了 chronyd,可能要配)
sudo systemctl enable --now chronyd

⚠️ AlmaLinux-9 + WSL 的 SELinux

  • AlmaLinux-9 安装时默认开启 SELinux,配置文件 /etc/selinux/configSELINUX=enforcing
  • WSL2 的微软内核不支持完整 SELinux 强制执行(缺 LSM 模块)——在 WSL 里 SELinux 不会真正生效
  • 行为上没问题,但日志会有些噪音(一些 service 报 SELinux 警告),可以接受
  • 想关掉:编辑 /etc/selinux/config,把 SELINUX=enforcing 改成 SELINUX=permissive(或 disabled),但对 WSL 来说意义不大

7.5 WSL 内 SELinux 处理

📋 详细说明6.3 SELinux 处理(命令通用)。本节只讲 WSL 下的特殊处理。

AlmaLinux-9 安装时默认开启 SELinux,配置文件 /etc/selinux/configSELINUX=enforcingWSL2 的微软内核不支持完整 SELinux 强制执行(缺 LSM 模块)——在 WSL 里 SELinux 不会真正生效,但服务会刷一些 SELinux 警告日志。

WSL 下推荐处理

# 临时切到 permissive(重启后失效)
sudo setenforce 0

# 永久切到 permissive(编辑配置文件)
sudo sed -i 's/^SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config

# 验证
getenforce
# 期望输出:Permissive

💡 WSL 下切到 permissive 是安全的

  • WSL 不是生产环境,缺 LSM 模块本来就不能强制 SELinux
  • permissive 模式下 SELinux 仍然记录违反策略的事件(audit log),但不阻止
  • 完全关掉(disabled)反而可能让某些依赖 SELinux 的服务启动失败

7.6 WSL 内 firewalld / fail2ban 关掉

📋 详细说明6.1 firewalld 防火墙6.2 fail2ban 防爆破(命令通用)。本节只讲 WSL 下的特殊处理。

WSL2 的微软内核没编译老 iptables 模块——firewalld 会报 iptables 错误;fail2ban 依赖 iptables 做封禁动作,也跑不动。WSL 内直接关掉这两个

# 关 firewalld
sudo systemctl disable --now firewalld

# 关 fail2ban
sudo systemctl disable --now fail2ban

💡 WSL 下不需要 Linux 防火墙

  • Windows 防火墙是 WSL 流量的真正边界
  • WSL 服务要被 Windows 访问,开 hostAddressLoopback(参考 WSL 文档第 6 节)
  • 容器间网络(Docker bridge)由 Docker 自己管 iptables,跟 NM/firewalld 无关

7.7 WSL 重启正确方式 + 配置生效规则

💡 基本运维命令wsl -l -vwsl --shutdownwsl --export/--import)见 7.4.7 WSL 常用运维命令。本节只讲"重启"和"哪些配置改了必须重启"。

WSL 重启的正确方式在 Windows PowerShell):

# 正确:完全关闭 + 重新打开(重读 wsl.conf / .wslconfig / system.conf)
wsl --shutdown
wsl -d AlmaLinux-9-DockerCompose
行为 sudo reboot(WSL 内部) wsl --shutdown(PowerShell)
杀进程
重启 WSL 服务 不会
重新读 wsl.conf
重新读 system.conf
重新读 .wslconfig
重新分配内存/CPU 限制

❌ 不要用 sudo reboot

  • WSL 不是真硬件,reboot 找不到 BIOS/固件去调用
  • 微软的 WSL 进程管理由 Windows 侧的 LxssManager 服务控制
  • 必须在 Windows 侧让 LxssManager 重新加载所有发行版,wsl --shutdown 就是干这个的
  • 改了 wsl.conf / system.conf 后,没有 wsl --shutdown 就不会重新读

哪些配置改了必须重启 WSL

配置文件 / 操作 是否需要 wsl --shutdown
/etc/wsl.conf(所有段) 必须
~/.wslconfig(Windows 侧) 必须
/etc/systemd/system.conf 必须(systemd 启动时读)
/etc/security/limits.conf ⚠️ 仅 PAM 登录的进程生效(重开终端就够)
普通 systemd 服务配置 ❌ 用 systemctl restart xxx 即可
软件包安装 / 升级 ❌ 直接生效

🔗 通用 WSL 基础(systemd 启用细节、镜像网络、hostAddressLoopback 实验特性等)详见 WSL 虚拟机创建与管理指南.md 第 4~6 节。


八、验证检查清单

完成所有配置后,建议逐项验证。

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

✅ 检查项 🔧 命令 🎯 预期
系统版本 cat /etc/almalinux-release AlmaLinux release 9.x ...
SSH 远程可连 ssh youruser@IP 成功登录(最好密钥免密)
密码登录已关闭 ssh -o PasswordAuthentication=no youruser@IP 仍可登录 = OK
SSH 服务自启 sudo systemctl is-enabled sshd enabled
防火墙已启用 sudo firewall-cmd --state running
防火墙放行 SSH sudo firewall-cmd --list-services ssh
网络连通 ping -c 3 baidu.comcurl -v http://baidu.com 有响应(注意:WSL 默认禁 ICMP,ping 可能不通
DNS 解析 dig baidu.com 返回 IP
时区正确 timedatectl Asia/Shanghai
时间同步 timedatectl show NTPSynchronized=yes
系统已更新 dnf check-update 无输出 = 已最新
FD 限制 ulimit -n 65535(已配置时)
工具齐全 which htop tmux jq tree vim 全部有路径
fail2ban 运行 sudo systemctl status fail2ban active (running)
SELinux 状态 getenforce Enforcing / Permissive(看需求)

8.2 真机 / 云服务器额外检查(WSL 跳过)

✅ 检查项 🔧 命令 🎯 预期
静态 IP 生效 ip addr show <网卡名> IP 与配置一致(网卡名因硬件/虚拟化平台而异:常见如 ens33ens160enp0s3eth0 等,需按实际填写)
默认路由 ip route show default 显示网关 IP
远程可 ping 通 ping <服务器IP>(从另一台机器) 有响应(服务器防火墙可能挡 ICMP)

📋 怎么知道自己的网卡名

# 列所有网卡(找带 inet IP 的那个)
ip -br addr
# 输出示例:
# lo               UNKNOWN        127.0.0.1/8
# ens33            UP             192.168.1.100/24   ← 这就是
# docker0          DOWN           172.17.0.1/16

8.3 WSL2 用户额外检查

💡 配套阅读七、WSL 用户专属指南——所有 WSL 专属配置(systemd 启用、主机名、firewalld 关掉、SELinux 切 permissive 等)都集中在那里。本表只是验证"配置生效了没"。

✅ 检查项 🔧 命令 🎯 预期
WSL 发行版 wsl -l -v(PowerShell 跑) 看到自己的发行版,版本是 2
systemd 已启用 ps -p 1 -o comm= systemd(不是 init
WSL 主机名 hostname 你设的名字(如 alma9-workspace
主机名持久化 cat /etc/wsl.conf [network] hostname = xxx
hosts 同步 cat /etc/hosts | grep $(hostname) 127.0.1.1 <主机名>
sudo 无警告 sudo whoami 直接返回 root,无 "unable to resolve host"
根目录所在虚拟磁盘 df -h / 容量正常(默认 256G,可手动扩)
根目录使用率 df -h / | tail -1 | awk '{print $5}' < 80%
Windows 盘已挂载 ls /mnt/c /mnt/d 能列出文件
数据软链就绪 ls -ld ~/data 指向 /mnt/d/wsl-data(如已建)
默认 /data 在 ls -ld /data 存在
WSL 发行版 cat /etc/os-release AlmaLinux 9
WSL 重启生效 wsl --shutdownwsl(PowerShell 跑) 配置变更生效
WSL 镜像模式(按需) ip addr show eth0 inet 是 192.168.x 或 10.x(不是 172.x)

8.4 一键自检脚本(通用 + WSL)

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

#!/bin/bash
# =============================================
# AlmaLinux-9 初始环境一键自检脚本
# =============================================
echo "================================"
echo "AlmaLinux-9 初始环境自检"
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] SSH 服务"
systemctl is-enabled sshd &>/dev/null && echo "✅ sshd 自启" || echo "❌ sshd 未自启"
systemctl is-active sshd &>/dev/null && echo "✅ sshd 运行中" || echo "❌ sshd 未运行"

echo -e "\n[3] 防火墙"
if command -v firewall-cmd &> /dev/null; then
  if systemctl is-active firewalld &>/dev/null; then
    firewall-cmd --list-services | head -3
  else
    echo "⚠️ firewalld 已装但未运行(WSL 下可能需关掉)"
  fi
else
  echo "⚠️ firewalld 未装"
fi

echo -e "\n[4] SELinux"
echo "当前模式:$(getenforce 2>/dev/null || echo 'N/A')"

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

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

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

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

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

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

echo -e "\n[11] 主机名"
echo "当前:$(hostname)"
grep -q "^127.0.1.1 $(hostname)" /etc/hosts && echo "✅ /etc/hosts 同步" || echo "⚠️ /etc/hosts 未同步(sudo 可能报 unable to resolve host)"

echo -e "\n[12] WSL 特定(如适用)"
if grep -qi "microsoft" /proc/version 2>/dev/null; then
  echo "✅ WSL 环境"
  grep -q "^\[network\]" /etc/wsl.conf && echo "✅ wsl.conf 有 [network] 段" || echo "⚠️ wsl.conf 缺 [network] 段(主机名可能不持久)"
else
  echo "非 WSL 环境(真机/云服务器)"
fi

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

九、常用命令速查

9.1 服务管理

🔧 操作 🔧 AlmaLinux-9 / RHEL 🔧 Ubuntu 24.04
启动 sudo systemctl start sshd sudo systemctl start ssh
停止 sudo systemctl stop sshd sudo systemctl stop ssh
状态 sudo systemctl status sshd sudo systemctl status ssh
开机自启 sudo systemctl enable sshd sudo systemctl enable ssh
重载配置 sudo systemctl reload sshd sudo systemctl reload ssh
服务名 sshd ssh
配置文件 /etc/ssh/sshd_config /etc/ssh/sshd_config(路径相同)

📋 关键差异:Ubuntu 把 SSH 服务名从 RHEL 的 sshd 改成了 ssh,其他都一致。

9.2 包管理对照

🔧 操作 🔧 AlmaLinux-9 (dnf) 🔧 Ubuntu 24.04 (apt)
更新源索引 sudo dnf makecache 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 upgrade -y sudo apt upgrade -y
升级发行版 sudo dnf upgrade --releasever=10 sudo do-release-upgrade
清理缓存 sudo dnf clean all sudo apt clean
自动清理无用包 sudo dnf autoremove sudo apt autoremove
包组 dnf groupinstall "Development Tools" apt install build-essential

9.3 网络命令对照

🔧 用途 🔧 AlmaLinux-9 🔧 Ubuntu 24.04
查看 IP ip addr / ifconfig ip addrifconfig 需装 net-tools
查看端口 netstat -tlnp netstat -tlnp(需装 net-tools) / ss -tlnp
测试连通 ping / traceroute ping / traceroute(需装)
DNS 查询 nslookup / dig dig(需装 dnsutils
防火墙 firewalld / firewall-cmd ufw
网络配置 nmcli / nmtui(NetworkManager) netplan/etc/netplan/*.yaml
主机名 hostnamectl set-hostname x hostnamectl set-hostname x(相同)
安全模块 setenforce 0 / getenforce 无(Ubuntu 用 AppArmor)

9.4 时间与日志对照

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

9.5 防火墙命令对照

🔧 操作 🟢 firewalld(AlmaLinux 默认) 🟡 iptables(底层通用) 🔵 nftables(现代替代) 🔴 ufw(Ubuntu 默认)
查看状态 sudo firewall-cmd --state sudo iptables -L -n -v sudo nft list ruleset sudo ufw status verbose
查看规则 sudo firewall-cmd --list-all sudo iptables -L -n -v --line-numbers sudo nft list ruleset sudo ufw status numbered
启动/启用 sudo systemctl enable --now firewalld 开机自启需 iptables-persistent 开机自启需 nftables.service sudo ufw enable
放行 22 端口 sudo firewall-cmd --permanent --add-service=ssh sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT sudo nft add rule inet filter input tcp dport 22 accept sudo ufw allow 22/tcp
放行服务名 sudo firewall-cmd --permanent --add-service=http sudo ufw allow http
放行 IP 段 sudo firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=192.168.1.0/24 accept' sudo iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT sudo nft add rule inet filter input ip saddr 192.168.1.0/24 accept sudo ufw allow from 192.168.1.0/24
拒绝某 IP sudo firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=10.0.0.5 reject' sudo iptables -A INPUT -s 10.0.0.5 -j DROP sudo nft add rule inet filter input ip saddr 10.0.0.5 drop sudo ufw deny from 10.0.0.5
重新加载 sudo firewall-cmd --reload sudo iptables-restore < /etc/iptables/rules.v4 sudo nft -f /etc/nftables.conf 自动
关闭防火墙 sudo systemctl stop firewalld sudo iptables -F(清空规则,慎用) sudo nft flush ruleset sudo ufw disable
命令缺失 sudo dnf install -y firewalld AlmaLinux 自带 sudo dnf install -y nftables sudo apt install -y ufw

📋 选择建议

  • 标准 AlmaLinux 优先用 firewalld(本教程主推),zone 概念比 ufw 略复杂但集成度高。
  • 需要复杂规则(端口转发、NAT、限速)用 iptables / nftables
  • 跨平台脚本或 Ubuntu 兼容场景用 ufw(AlmaLinux EPEL 里有)。

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

📋 脚本定位

  • 本脚本对应本文档 第二章(初始环境检查)、3.1-3.3(SSH 服务)、第四章(常用工具)、5.5(dnf 换源)、6.1-6.4(安全与优化)的最小可用集
  • 不包含的内容:5.1(静态 IP,按网络环境差异较大)、5.2(主机名,个性化)、3.5(密钥免密,建议手动执行以免覆盖既有密钥)、6.3(SELinux 高级配置,生产环境按需)、第七章 WSL 用户专属指南(WSL 用户单独走那一章)。
  • 默认按"真机 / 云服务器"编写,脚本会自动识别 WSL2 环境并跳过不适用项(firewalldrebootsysctl 等)。
#!/bin/bash
# =============================================
# AlmaLinux-9 初始环境一键配置脚本
# 对应文档:AlmaLinux-9与WSL2初始环境配置与常用工具安装教程.md 第 9.6 节
# 用法:sudo bash init-almalinux9.sh
# 前置:建议先按 5.5 节换 dnf 源,再跑本脚本
# 幂等:重复运行不会破坏既有配置(已存在配置会跳过)
# =============================================
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} $*"; }

# ---------- 0. 权限与环境探测 ----------
if [[ $EUID -ne 0 ]]; then
  err "请使用 root 或 sudo 运行本脚本"
  exit 1
fi

# WSL2 探测:/proc/version 含 "microsoft" 或 "WSL"
IS_WSL=0
grep -qiE 'microsoft|wsl' /proc/version 2>/dev/null && IS_WSL=1

# 当前登录用户(sudo 场景下 SUDO_USER 非空;root 直登时退到默认 youruser)
REAL_USER="${SUDO_USER:-${USER:-youruser}}"
[[ "$REAL_USER" == "root" ]] && REAL_USER="youruser"

log "运行环境:$( [[ $IS_WSL -eq 1 ]] && echo 'WSL2' || echo '真机/云服务器' )"
log "操作用户:$REAL_USER"

# ---------- 1. 更新源(对应 5.5) ----------
log "[1/9] 更新 dnf 源与软件包"
if [[ $IS_WSL -eq 1 ]]; then
  warn "WSL2 环境:换源脚本见 5.5.8 节,建议先手动跑(rootfs 通常默认源已够用)"
else
  dnf makecache
fi
# upgrade 升级所有包;如不希望升级可注释掉下一行
dnf upgrade -y

# ---------- 2. 常用工具(对应第四章) ----------
log "[2/9] 安装常用工具集"
dnf install -y \
  openssh-server openssh-clients \
  vim nano curl wget git \
  net-tools bind-utils iputils traceroute mtr \
  unzip p7zip p7zip-plugins lrzsz \
  bash-completion tmux \
  htop iotop iftop sysstat lsof strace ncdu \
  ripgrep fd-find jq tree \
  fail2ban firewalld

# 装 EPEL(如已装会跳过)
if ! rpm -q epel-release &>/dev/null; then
  dnf install -y epel-release
  log "EPEL 已装"
fi

# fd-find 在 AlmaLinux 上是 /usr/bin/fd-find,alias 一下
if ! grep -q "alias fd=" /home/$REAL_USER/.bashrc 2>/dev/null; then
  echo "alias fd='fd-find'" >> /home/$REAL_USER/.bashrc
fi

# ---------- 3. SSH 服务(对应 3.1 / 3.3) ----------
log "[3/9] 配置 SSH 服务"
# 备份原配置(仅首次备份)
[[ -f /etc/ssh/sshd_config ]] && [[ ! -f /etc/ssh/sshd_config.bak ]] && \
  cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

# 用 sed 调整关键项(保留其它已有配置)
SSHD_CFG=/etc/ssh/sshd_config
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"

# 启用并启动 SSH(WSL2 启用 systemd 后 systemctl 才会生效;未启用时为 no-op)
if [[ $IS_WSL -eq 0 ]]; then
  systemctl enable --now sshd >/dev/null 2>&1 || warn "sshd 服务启动失败,请检查 systemd"
else
  warn "WSL2 环境:未启用 systemd 时 systemctl 不可用,请按 WSL 文档启用后再重启"
fi

# 校验配置(错误则不重启,避免失联)
if command -v sshd >/dev/null 2>&1; then
  sshd -t && log "sshd_config 语法校验通过" || err "sshd_config 语法错误,请检查 $SSHD_CFG"
fi

# ---------- 4. 防火墙(对应 6.1 / 七章 7.6) ----------
log "[4/9] 配置 firewalld 防火墙"
if [[ $IS_WSL -eq 0 ]]; then
  systemctl enable --now firewalld >/dev/null 2>&1 || warn "firewalld 启动失败"
  firewall-cmd --permanent --add-service=ssh >/dev/null 2>&1 || true
  firewall-cmd --reload >/dev/null 2>&1 || true
  log "firewalld 已启用(默认放行 ssh)"
else
  warn "WSL2 环境:firewalld 微软内核不支持,建议 disable,由 Windows 防火墙控端口"
  systemctl disable --now firewalld >/dev/null 2>&1 || true
fi

# ---------- 5. fail2ban(对应 6.2 / 七章 7.6) ----------
log "[5/9] 配置 fail2ban"
JAIL_LOCAL=/etc/fail2ban/jail.local
if [[ ! -f $JAIL_LOCAL ]]; then
  cat > "$JAIL_LOCAL" <<'EOF'
[DEFAULT]
bantime  = 1h
findtime = 10m
maxretry = 5
banaction = firewallcmd-rich-rules
banaction_allports = firewallcmd-rich-rules

[sshd]
enabled = true
port    = ssh
filter  = sshd
logpath = %(sshd_log)s
backend = %(sshd_backend)s
maxretry = 3
EOF
  log "已生成 $JAIL_LOCAL"
else
  warn "$JAIL_LOCAL 已存在,跳过覆盖(手动调整请编辑该文件)"
fi

if [[ $IS_WSL -eq 0 ]]; then
  systemctl enable --now fail2ban >/dev/null 2>&1 || warn "fail2ban 启动失败"
else
  warn "WSL2 环境:未启用 systemd 时 fail2ban 无法后台常驻"
fi

# ---------- 6. 时区与时间同步(对应 5.3) ----------
log "[6/9] 配置时区与时间同步"
timedatectl set-timezone Asia/Shanghai
if [[ $IS_WSL -eq 0 ]]; then
  systemctl enable --now chronyd >/dev/null 2>&1 || true
fi
log "当前时区:$(timedatectl | grep 'Time zone' | awk '{print $3}')"

# ---------- 7. 文件描述符限制(对应 6.4) ----------
log "[7/9] 配置文件描述符限制"
LIMITS_CONF=/etc/security/limits.conf
# 幂等:仅当 nofile 65535 不存在时追加
if ! grep -qE '^\*\s+soft\s+nofile\s+65535' "$LIMITS_CONF" 2>/dev/null; then
  cat >> "$LIMITS_CONF" <<'EOF'

# === Added by init-almalinux9.sh ===
*   soft    nofile  65535
*   hard    nofile  65535
root soft    nofile  65535
root hard    nofile  65535
EOF
  log "已追加 nofile 限制到 $LIMITS_CONF"
else
  warn "$LIMITS_CONF 已包含 nofile 65535,跳过"
fi

# systemd 服务级 FD 限制
SYSTEMD_CONF=/etc/systemd/system.conf
if ! grep -qE '^DefaultLimitNOFILE=65535' "$SYSTEMD_CONF" 2>/dev/null; then
  sed -i 's/^#\?DefaultLimitNOFILE=.*/DefaultLimitNOFILE=65535/' "$SYSTEMD_CONF" || \
    echo "DefaultLimitNOFILE=65535" >> "$SYSTEMD_CONF"
  log "已设置 DefaultLimitNOFILE=65535"
else
  warn "$SYSTEMD_CONF 已包含 DefaultLimitNOFILE=65535,跳过"
fi

# ---------- 8. 内核参数调优(对应 6.5) ----------
log "[8/9] 配置内核参数调优"
SYSCTL_FILE=/etc/sysctl.d/99-tuning.conf
if [[ ! -f $SYSCTL_FILE ]]; then
  cat > "$SYSCTL_FILE" <<'EOF'
# === Added by init-almalinux9.sh ===
# 网络优化
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

# Swap 使用倾向(值越小越倾向用物理内存)
vm.swappiness = 10
EOF
  log "已生成 $SYSCTL_FILE"
else
  warn "$SYSCTL_FILE 已存在,跳过覆盖(如需重置请手动删除)"
fi

# 应用 sysctl(非 WSL 立即生效;WSL 大部分参数会被宿主内核忽略)
if [[ $IS_WSL -eq 0 ]]; then
  sysctl -p "$SYSCTL_FILE" >/dev/null 2>&1 || warn "sysctl 部分参数应用失败(多因模块未加载,可忽略)"
else
  warn "WSL2 环境:sysctl 大部分参数由 Windows 宿主内核控制,配置仅作记录"
fi

# ---------- 9. 完成提示 ----------
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 2>/dev/null || echo 'N/A')(生产建议保持 enforcing)"
if [[ $IS_WSL -eq 1 ]]; then
  echo "  5) WSL 用户专属配置:见第七章 WSL 用户专属指南(systemd 启用、主机名、vhdx 回收等)"
fi
echo "------------------------------------------------"

💡 文档维护提示

  • 上述所有配置均在 AlmaLinux 9.x 实测通过。
  • AlmaLinux 8 大部分兼容,仅仓库 id 命名(base / AppStream vs baseos / appstream)、防火墙命令(firewall-cmd 基本一致)、部分 SELinux 策略有差异。
  • SELinux 行为取决于具体启用模式,调试时优先用 ausearch + audit2allow 生成策略,而非全局 permissive。
  • WSL 行为(systemd 启用、虚拟磁盘回收、/etc/wsl.conf 配置等)详见 WSL 虚拟机创建与管理指南.md
posted @ 2026-08-18 11:11  RK5123153  阅读(9)  评论(0)    收藏  举报