Ubuntu 与 WSL2 初始环境配置与常用工具安装教程
适用于 Ubuntu 24.04 LTS(云厂商镜像、官方 ISO 或 WSL2 安装后),从 SSH 远程连接到常用工具一站式配置。
目录
- 一、文档总览
- 二、初始环境检查
- 三、SSH 远程服务(核心)
- 四、网络与系统配置
- 五、常用工具集
- 5.1 一键安装清单
- 5.2 工具速查表
- 5.3 配置 Git(开发者必做)
- 5.4 配置 vim(可选但推荐)
- 5.5 配置 bash 提示符(可选)
- 5.6 WSL 数据目录规划建议(仅 WSL2 用户)
- 5.6.1 先理解 WSL2 的"磁盘"是怎么回事
- 5.6.2 推荐:把重要数据放到 Windows 盘
- 5.6.3 CentOS vs Ubuntu:为什么 Ubuntu 默认没有 /data
- 5.6.4 在根目录建 /data 也可行,但需充分了解其风险与限制
- 5.6.5 重要:定期回收虚拟磁盘空间
- 5.6.6 WSL 常用运维命令
- 5.6.7 常见误区
- 5.6.8 WSL 网络配置与 Windows 互通
- 5.6.8.1 为什么 Netplan 在 WSL 里改了不生效?
- 5.6.8.2 WSL 配置文件位置
- 5.6.8.3 三种网络模式对比
- 5.6.8.4 推荐配置:.wslconfig(Windows 侧)
- 5.6.8.5 单发行版配置:/etc/wsl.conf(WSL 内)
- 5.6.8.6 WSL 与 Windows 互访
- 5.6.8.7 常见 WSL 网络坑
- 5.6.8.8 WSL 网络排障命令速查
- 5.6.8.9 WSL 主机名设置
- 5.6.8.10 WSL sudo 解析陷阱:改了主机名后 vim 无法启动
- 5.6.8.11 WSL 启用 systemd
- 5.6.8.12 WSL 时区设置
- 5.6.8.13 WSL 防火墙:ufw 修复 + nftables 兜底
- 5.6.8.14 WSL 配置文件参考
- 5.6.8.15 镜像网络下 Windows 通过 WSL IP 访问服务超时
- 六、安全与优化
- 七、验证检查清单
- 八、常用命令速查
一、文档总览
章节索引:
| 序号 | 章节 | 说明 |
|---|---|---|
| 一 | 文档总览 | 流程图 + 索引 |
| 二 | 初始环境检查 | 确认系统版本 / 初始账号 / 设置 root 密码 |
| 三 | SSH 远程服务 | 核心:安装 + 配置 + 密钥免密 |
| 四 | 网络与系统配置 | 静态 IP / DNS / 时区 / 更新源 |
| 五 | 常用工具集 | 网络、编辑器、开发、效率工具 |
| 六 | 安全与优化 | ufw / fail2ban / 内核参数 |
| 七 | 验证检查清单 | 一键自检 |
| 八 | 常用命令速查 | CentOS ↔ Ubuntu 对照表 |
二、初始环境检查
在动手前,先确认当前系统的版本、内核、当前用户、是否已装 SSH。
# 系统版本
cat /etc/os-release
# 内核版本
uname -r
# 当前用户与权限
whoami
id
# 是否已安装 SSH(Ubuntu 桌面版/部分云镜像默认未装)
dpkg -l | grep -E "openssh-server|openssh-client"
ss -tlnp 2>/dev/null | grep :22 || netstat -tlnp 2>/dev/null | grep :22
2.1 设置 root 密码
Ubuntu 默认禁用 root 直接登录,且初始 root 账户通常没有设置密码。建议先为 root 设置一个强密码,便于后续 su - 切换和系统维护。
# 为 root 用户设置密码(按提示输入两次)
sudo passwd root
验证切换是否成功:
# 切换到 root 用户
su -
# 确认当前身份
whoami
id
💡 提示:
- 设置 root 密码后,root 仍可通过
su -切换,但 SSH 默认仍禁止 root 登录(PermitRootLogin prohibit-password)。- 如需允许 root 通过 SSH 密码登录,需修改
/etc/ssh/sshd_config中的PermitRootLogin项,并重启 SSH 服务(生产环境不建议)。- WSL 环境下建议设置 root 密码,否则很多需要 root 权限的维护操作会受阻。
🔐 安全建议:
- root 密码应使用强密码(长度 12 位以上,包含大小写字母、数字、特殊字符)。
- 日常操作优先使用
sudo,仅在必要时切换到 root。
三、SSH 远程服务(核心)
本章为优先配置项。所有运维操作几乎都依赖 SSH,建议首先完成配置。
3.1 安装 openssh-server
⚠️ 先换源,再更新
如果你在国内或默认源访问较慢,建议先完成 4.5 节的 apt 换源配置,再返回本节执行安装。否则第一次
apt update可能非常慢,甚至超时失败。
- Ubuntu 24.04+:参考 4.5 配置 apt 更新源(deb822 格式)
- Ubuntu 22.04 / 20.04 及更早:参考 4.5 节 中的版本兼容说明,将文件路径调整为
/etc/apt/sources.list即可
# 更新软件源索引(如已按 4.5 节换源,会直接从镜像站更新)
sudo apt update
# 安装 SSH 服务端与客户端
sudo apt install -y openssh-server openssh-client
# 启动并设置开机自启
sudo systemctl enable --now ssh
🔧 验证:
sudo systemctl status ssh # 输出中出现 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:<端口>会超时。详见 5.6.8.15 镜像网络下 Windows 通过 WSL IP 访问服务超时。
3.2 配置文件结构
| 📄 文件 | 📝 用途 |
|---|---|
/etc/ssh/sshd_config |
服务端主配置(修改后要重启 ssh 服务) |
/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 直接登录(必开)
PermitRootLogin no
# 是否允许密码登录。生产推荐 no + 改用密钥登录
PasswordAuthentication yes
# 是否允许空密码(生产环境应设为 no)
PermitEmptyPasswords no
# 公钥认证(密钥免密登录)
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
# 密钥强度
PubkeyAcceptedKeyTypes=+ssh-rsa,ssh-dss
# =============================================
# 安全加固
# =============================================
# 最大重试次数
MaxAuthTries 3
# 最大并发未认证连接
MaxSessions 5
# 登录超时(30 秒无输入断开)
LoginGraceTime 30
# 客户端空闲超时(600 秒无操作断开)
ClientAliveInterval 60
ClientAliveCountMax 10
# 禁止 X11 转发(图形转发,服务器无必要)
X11Forwarding no
# 限制登录用户/组(白名单)
AllowUsers ubuntu
# AllowGroups ssh-users
# =============================================
# 显示与日志
# =============================================
# 登录前后显示的 banner 文件路径(可选)
# Banner /etc/issue.net
# 日志级别
LogLevel VERBOSE
📋 配置说明:
PermitRootLogin no:禁止 root 直登,运维需用普通用户 +sudo提权。PasswordAuthentication yes→ 后续验证完密钥登录后可改为no。AllowUsers ubuntu:把ubuntu替换为你的实际登录用户,多用户用空格分隔。
3.4 重启 SSH 并验证
# 检查配置语法(非常关键,避免配错导致无法登录)
sudo sshd -t
# 若命令无输出,则表示语法正确
# 重启服务
sudo systemctl restart ssh
# 查看状态
sudo systemctl status ssh
⚠️ 高危提醒:修改 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 ubuntu@服务器IP
# 输入一次密码后即完成
方法二:手动复制
# 在客户端打印公钥
cat ~/.ssh/id_rsa.pub
# 在服务器上操作
mkdir -p ~/.ssh
chmod 700 ~/.ssh
vim ~/.ssh/authorized_keys # 粘贴公钥,一行一个
chmod 600 ~/.ssh/authorized_keys
3.5.3 关闭密码登录
验证密钥能登录后,编辑服务端配置:
sudo vim /etc/ssh/sshd_config
PasswordAuthentication no
sudo sshd -t
sudo systemctl restart ssh
3.6 防火墙放行 SSH
Ubuntu 默认使用 ufw(Uncomplicated Firewall),操作比 firewalld 简单:
# 查看 ufw 状态
sudo ufw status verbose
# 默认策略:拒绝入站、允许出站
sudo ufw default deny incoming
sudo ufw default allow outgoing
# 放行 SSH(推荐显式指定端口)
sudo ufw allow 22/tcp comment "SSH default port"
# 如改了端口:sudo ufw allow 2222/tcp
# 启用防火墙
sudo ufw enable
# 会提示 "Command may disrupt existing ssh connections"
# 按提示输入 y 确认继续(启用前已放行 22 端口,不会中断现有连接)
# 查看规则
sudo ufw status numbered
🔧 验证:用另一台机器
ssh ubuntu@服务器IP测试能连即可。
3.6.1 兜底:ufw 不存在时(Debian 最小化镜像 / 自定义容器 / 误卸载)
若执行 sudo ufw status 报 command not found,说明系统不是标准 Ubuntu 桌面/服务器(常见于 Debian 最小化版、Docker 基础镜像 debian:slim、部分云厂商轻量镜像等)。先用以下命令确认系统类型,再选择对应防火墙:
# 确认系统类型
cat /etc/os-release
# 确认 ufw 是否真的没装(不是 PATH 问题)
which ufw || dpkg -l | grep -i ufw || rpm -qa | grep -i ufw
情况 A:确实是 Ubuntu,但 ufw 被精简掉了 —— 装回来即可:
sudo apt update
sudo apt install -y ufw
sudo ufw allow 22/tcp
sudo ufw enable
情况 B:Debian 最小化系统 —— 同样装 ufw 即可(Debian 官方源里有):
sudo apt update && sudo apt install -y ufw
sudo ufw allow 22/tcp
sudo ufw enable
情况 C:容器 / Alpine / RHEL 家族 —— 没有 ufw,需用底层工具:
# ===== iptables(Debian/Ubuntu 默认自带,ufw 底层也是它)=====
# 查看规则(-L 列表,-n 数字显示,-v 详细,--line-numbers 显示行号便于删除)
sudo iptables -L INPUT -n -v --line-numbers
# 临时放行 SSH(重启失效)
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 持久化:Debian/Ubuntu 安装 iptables-persistent
sudo apt install -y iptables-persistent
sudo netfilter-persistent save
# ===== nftables(Ubuntu 24.04+、Debian 12+ 推荐的现代替代)=====
# 查看规则
sudo nft list ruleset
# 放行 SSH
sudo nft add rule inet filter input tcp dport 22 accept
# ===== firewalld(CentOS / RHEL / Fedora 默认)=====
sudo firewall-cmd --list-all
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload
⚠️ 重要提醒:
- 在远程主机上启用防火墙前,先放行 22 端口(否则启用瞬间就会被踢出,连不上)。
- 容器内(Docker/LXC)通常不需要操作防火墙,端口由宿主机或
docker run -p控制。- 不确定系统类型时,
cat /etc/os-release是最准的判断方式。
四、网络与系统配置
4.1 配置静态 IP(Netplan)
Ubuntu 18.04+ 统一使用 Netplan 管理网络(取代传统的 /etc/network/interfaces)。
# 查看网卡名称
ip -br link
# 一般为 ens33 / ens160 / enp0s3 等
ls /etc/netplan/
sudo vim /etc/netplan/01-netcfg.yaml
network:
version: 2
renderer: networkd
ethernets:
ens33: # 替换为你的网卡名
dhcp4: no
dhcp6: no
addresses:
- 192.168.1.100/24 # 静态 IP
routes:
- to: default
via: 192.168.1.1 # 网关
nameservers:
addresses:
- 223.5.5.5 # 阿里 DNS
- 8.8.8.8 # Google DNS
- 114.114.114.114 # 114 DNS
# 验证配置(不会应用,但会显示问题)
sudo netplan try
# 应用配置
sudo netplan apply
⚠️ 远程操作注意:
netplan try会临时应用配置并等待 120 秒回车确认;直接netplan apply会立即生效,可能导致远程连接短暂中断。⚠️ WSL 用户注意:本节讲的 Netplan 配置对 WSL2 不生效。WSL 的网络由 Windows 虚拟网卡管理,配置在 Windows 侧的
%USERPROFILE%\.wslconfig。详见 5.6.8 WSL 网络配置与 Windows 互通。
4.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
⚠️ WSL 用户注意:WSL 启用 systemd 后(见 5.6.8.11 WSL 启用 systemd),
hostnamectl set-hostname可直接用。配置修改后需要完全重启 WSL 才生效,详见 5.6.8.11.1 WSL 重启的正确方式。主机名持久化配置见 5.6.8.9 WSL 主机名设置。
4.3 时区与时间同步
# 查看当前时区
timedatectl
# 设置时区
sudo timedatectl set-timezone Asia/Shanghai
# Ubuntu 默认自带 systemd-timesyncd
sudo systemctl enable --now systemd-timesyncd
timedatectl status
📋 说明:
- 服务器与客户端的时间偏差超过 5 分钟会导致部分协议(如 Kerberos)失败。
- 如需更高精度,可安装
chrony:sudo apt install -y chrony。⚠️ WSL 用户注意:启用 systemd 后(见 5.6.8.11 WSL 启用 systemd),
timedatectl set-timezone可直接用,无需手动ln -s。
4.4 关闭 Ubuntu 默认组件(按需)
# 关闭 Snap 服务(部分场景下不需要)
sudo systemctl disable --now snapd.service snapd.socket snapd.seeded.service
# 关闭无关服务(如自动更新)
sudo systemctl disable --now unattended-upgrades.service
4.5 配置 apt 更新源(deb822 格式,Ubuntu 24.04+)
💡 本节针对 Ubuntu 24.04 LTS(Noble)默认的
deb822格式。
24.04 之后/etc/apt/sources.list已被废弃,真正的源文件在/etc/apt/sources.list.d/ubuntu.sources。
4.5.1 验证当前源格式
📋 如何判断你该用哪个文件:
Ubuntu 版本 VERSION_CODENAME默认源文件 备注 24.04+ noblesources.list.d/ubuntu.sources(deb822 新格式)本节主推 24.04+ noblesources.list.d/ubuntu.sources(deb822 新格式)本节主推 20.04 及更早 focal及更早sources.list(deb 老格式)apt 不支持 deb822,老格式即可 快速检测脚本:
if [ -f /etc/apt/sources.list.d/ubuntu.sources ]; then echo "✅ 新格式(deb822),用 sources.list.d/ubuntu.sources" else echo "⚠️ 老格式(deb),用 sources.list" fi结论:本节默认按 Ubuntu 24.04+ 讲解。低版本用户请参考对应版本的官方文档。
4.5.2 查看当前源文件内容
# 1. 确认 Ubuntu 版本
cat /etc/os-release | grep VERSION_CODENAME
# 输出示例:VERSION_CODENAME=noble
# 2. 看新格式的源文件(24.04+ 才有这个)
cat /etc/apt/sources.list.d/ubuntu.sources
# 3. 老的 sources.list 在 24.04 上只剩 3 行注释
cat /etc/apt/sources.list
# 输出示例:
# # Ubuntu sources have moved to the /etc/apt/sources.list.d/ubuntu.sources
# # file, which uses the deb822 format. ...
📋 deb822 格式 vs 老 deb 格式:
项目 老格式(≤ 20.04) 新格式(≥ 24.04) 文件位置 /etc/apt/sources.list/etc/apt/sources.list.d/ubuntu.sources文件内容 deb URL 代号 组件 ...Types: deb/URIs: URL/Suites: 代号/ ...(每行一个字段)多源 一行一个源 一个文件多个 Types:段注释 # xxx# xxx或字段名后加# xxx
4.5.3 备份默认源
# 备份新格式源(24.04+)
sudo cp /etc/apt/sources.list.d/ubuntu.sources \
/etc/apt/sources.list.d/ubuntu.sources.bak
# 顺便也备份老的(即使只剩注释,养成习惯)
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
4.5.4 替换为阿里云源(国内推荐)
自动生成(推荐,最稳):
# 阿里云官方提供了一键替换脚本
# 等价于:把 sources.list.d/ubuntu.sources 里的 http://archive.ubuntu.com/
# 和 http://security.ubuntu.com/ 全部替换成 mirrors.aliyun.com
sudo sed -i.bak \
-e 's|http://archive.ubuntu.com|http://mirrors.aliyun.com|g' \
-e 's|http://security.ubuntu.com|http://mirrors.aliyun.com|g' \
/etc/apt/sources.list.d/ubuntu.sources
# 验证改对了
cat /etc/apt/sources.list.d/ubuntu.sources
手动编辑(想完全控制内容时用):
sudo vim /etc/apt/sources.list.d/ubuntu.sources
deb822 格式完整示例(noble = 24.04):
# =============================================
# /etc/apt/sources.list.d/ubuntu.sources
# 阿里云镜像(noble = 24.04)
# =============================================
Types: deb
URIs: http://mirrors.aliyun.com/ubuntu
Suites: noble noble-updates noble-backports
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
Types: deb
URIs: http://mirrors.aliyun.com/ubuntu
Suites: noble-security
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
📋 关键字段说明:
Types: deb—— 二进制包;Types: deb-src—— 源码包URIs:—— 镜像地址Suites:—— 版本代号(要与lsb_release -cs一致,否则报 404)Components:—— 组件(main / restricted / universe / multiverse)Signed-By:—— GPG 签名文件路径(24.04 必填)
4.5.5 应用并验证
# 刷新源索引
sudo apt update
# 看到 "Hit: http://mirrors.aliyun.com/ubuntu noble ..." = 成功
# 升级所有已装包
sudo apt upgrade -y
# (可选)清理无用包
sudo apt autoremove -y
验证用的是阿里云源:
apt policy
# 看每个仓库的 URL 列,应该是 mirrors.aliyun.com
# 或更直白
apt-cache policy | grep -i "aliyun\|archive.ubuntu\|security.ubuntu"
4.5.6 其他国内镜像(按需替换 URIs)
| 镜像 | 替换前 | 替换后 |
|---|---|---|
| 阿里云(最稳,首选) | http://archive.ubuntu.com |
http://mirrors.aliyun.com/ubuntu |
| 清华 TUNA | 同上 | https://mirrors.tuna.tsinghua.edu.cn/ubuntu |
| 中科大 USTC | 同上 | https://mirrors.ustc.edu.cn/ubuntu |
| 网易 | 同上 | http://mirrors.163.com/ubuntu |
| 华为云 | 同上 | https://mirrors.huaweicloud.com/ubuntu |
| 腾讯云 | 同上 | https://mirrors.cloud.tencent.com/ubuntu |
清华源示例(想换清华的话):
sudo sed -i \
-e 's|http://archive.ubuntu.com|https://mirrors.tuna.tsinghua.edu.cn|g' \
-e 's|http://security.ubuntu.com|https://mirrors.tuna.tsinghua.edu.cn|g' \
/etc/apt/sources.list.d/ubuntu.sources
4.5.7 常见问题
Q1:换源后 apt update 报 GPG error / NO_PUBKEY?
# 重新导入签名密钥
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys <报错里的 KEY>
# 或更稳的方式(24.04 推荐)
sudo wget -O /usr/share/keyrings/ubuntu-archive-keyring.gpg \
https://mirrors.aliyun.com/ubuntu/keys/release-archive-keyring.gpg
sudo apt update
Q2:换源后 apt update 报 404 Not Found?
# 99% 是 Suites 字段写错了(不是 24.04 写了 jammy / focal / bionic)
lsb_release -cs
# 看到 noble 才能用 noble、noble-updates、noble-security、noble-backports
# 或用 sed 一键修正
sudo sed -i "s/^Suites: .*/Suites: noble noble-updates noble-security noble-backports/" \
/etc/apt/sources.list.d/ubuntu.sources
Q3:想临时恢复默认源?
# 删掉改过的文件,还原备份
sudo cp /etc/apt/sources.list.d/ubuntu.sources.bak \
/etc/apt/sources.list.d/ubuntu.sources
sudo apt update
Q4:怎么加第三方源(如 Docker、Node.js)?
不要直接改
ubuntu.sources,而是单独建一个.sources文件,apt 会按字典序读取:
# 例:加 Docker 官方源
sudo vim /etc/apt/sources.list.d/docker.sources
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: noble
Components: stable
Signed-By: /etc/apt/keyrings/docker.gpg
# 加 GPG 密钥
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
-o /etc/apt/keyrings/docker.gpg
sudo apt update
4.5.8 一键脚本(适合批量初始化)
#!/bin/bash
# 阿里云 apt 源一键配置(Ubuntu 24.04+)
set -e
SRC="/etc/apt/sources.list.d/ubuntu.sources"
BAK="${SRC}.bak.$(date +%Y%m%d%H%M%S)"
# 1. 备份
sudo cp "$SRC" "$BAK"
echo "✅ 备份到 $BAK"
# 2. 检查格式
if ! grep -q "^URIs:" "$SRC"; then
echo "❌ 当前不是 deb822 格式,请确认 Ubuntu 版本 ≥ 24.04"
exit 1
fi
# 3. 替换为阿里云
sudo sed -i \
-e 's|http://archive.ubuntu.com|http://mirrors.aliyun.com|g' \
-e 's|http://security.ubuntu.com|http://mirrors.aliyun.com|g' \
"$SRC"
# 4. 验证
echo "🔍 改完后的源:"
grep "^URIs:" "$SRC"
# 5. 刷新
sudo apt update
echo "✅ apt update 完成"
保存为 ~/set-aliyun-mirror.sh,跑:
chmod +x ~/set-aliyun-mirror.sh
sudo ~/set-aliyun-mirror.sh
📋 关于 Ubuntu 版本代号:
noble= 24.04(24.04 LTS 用 5 年,2034 年 EOL)jammy= 22.04(历史版本,已逐步迁移至 24.04)focal= 20.04(已 EOL)改源时代号要与
lsb_release -cs一致,否则报 404。
五、常用工具集
5.1 一键安装清单
# =============================================
# 网络工具
# =============================================
# net-tools: netstat / ifconfig / route 等传统命令
# iproute2: ip / ss / tc 等新一代命令(Ubuntu 自带)
# dnsutils: nslookup / dig
# iputils-ping: ping
# traceroute: 路由追踪
sudo apt install -y net-tools dnsutils iputils-ping traceroute mtr
# =============================================
# 编辑器与文件处理
# =============================================
# vim: 增强版 vi
# nano: 简单文本编辑器
# unzip / p7zip-full: 解压 zip / 7z
# lrzsz: rz / sz 上传下载(Xshell/SecureCRT 适用)
sudo apt install -y vim nano unzip p7zip-full lrzsz
# =============================================
# 版本控制
# =============================================
# git: 分布式版本控制
sudo apt install -y git
# =============================================
# Shell 增强
# =============================================
# bash-completion: 命令补全
# zsh + oh-my-zsh: 更友好的 shell
# tmux: 终端复用器(断线不丢任务)
sudo apt install -y bash-completion tmux
# =============================================
# 系统监控与诊断
# =============================================
# htop: 增强版 top
# iotop: 磁盘 IO 监控
# iftop: 网络流量监控
# sysstat: iostat / mpstat / sar
# lsof: 查看打开的文件
# strace: 系统调用跟踪
# ncdu: 交互式磁盘占用分析
sudo apt install -y htop iotop iftop sysstat lsof strace ncdu
# =============================================
# 开发工具链(按需)
# =============================================
# build-essential: gcc / g++ / make
# python3 / pip3
# openjdk-17-jdk
# nodejs / npm
# sudo apt install -y build-essential python3 python3-pip openjdk-17-jdk nodejs npm
# =============================================
# 文本搜索 / 处理
# =============================================
# ripgrep (rg): 更快更现代的 grep
# fd-find (fd): 更快更现代的 find
# jq: 命令行 JSON 处理
# tree: 目录树展示
sudo apt install -y ripgrep fd-find jq tree
# =============================================
# 安全相关
# =============================================
# fail2ban: 防 SSH 暴力破解
# ufw: 防火墙(默认已装)
sudo apt install -y fail2ban
5.2 工具速查表
| 🔧 工具 | 📝 用途 | 📋 常用命令 |
|---|---|---|
netstat |
网络连接/端口查看 | netstat -tlnp |
ss |
现代版 netstat | ss -tlnp、ss -s |
ip |
网络配置 | ip addr、ip route |
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 |
5.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
5.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
5.5 配置 bash 提示符(可选)
vim ~/.bashrc
在末尾追加:
# 彩色提示符
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
# 命令别名
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
alias gs='git status'
alias gp='git pull'
alias ..='cd ..'
source ~/.bashrc
5.6 WSL 数据目录规划建议(仅 WSL2 用户)
适用于 WSL2 下的 Ubuntu(Microsoft Store / Docker Desktop / 自定义导入均可参考)。
非 WSL 场景(云服务器、物理机、虚拟机)可跳过本节。
5.6.1 先理解 WSL2 的"磁盘"是怎么回事
WSL2 本质是一个 ext4 虚拟磁盘文件(ext4.vhdx)挂载到 /,而不是传统的物理磁盘 + 分区表(MBR / GPT)结构。所以:
df -h
典型输出(已实测 WSL2 Ubuntu 24.04):
/dev/sde 1007G 2.0G 954G 1% / ← 根目录所在的虚拟磁盘(最大块)
/dev/sdd 1007G 5.3G 951G 1% /mnt/wsl/... ← Docker Desktop 存储(也是 vhdx)
/dev/loop0 761M 761M 0 100% /mnt/wsl/... ← Docker CLI 工具(与根目录无关)
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 盘
几个关键点:
| 现象 | 真相 |
|---|---|
none 7.8G 那么多挂载点 |
均为 WSL2 的 9P 共享通道(drivers、init、run、shm 等),不属于根目录存储空间,占用内存而非磁盘 |
/dev/sde 1007G 看着很大 |
实际对应 Windows 侧的 ext4.vhdx 稀疏文件;WSL 内显示的"已用 2G"为文件系统逻辑用量,并非该 vhdx 文件在 Windows 上的实际物理占用 |
在 / 下建文件夹要不要"分配空间" |
不需要。mkdir /data 不占空间,写入文件时才"按需"占用 |
| 写满会怎样 | 根目录满 100% 后所有命令都报错;WSL2 默认上限 256 G,可手动扩到几 T |
5.6.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/路径直接用也行,但路径长、可读性差
5.6.3 CentOS vs Ubuntu:为什么 Ubuntu 默认没有 /data?
从 CentOS / RHEL 迁移过来的用户会发现安装好的 Ubuntu 没有 /data 目录,而 CentOS 默认就有。这是发行版设计理念的差异,跟"要不要手动建"无关。
| 发行版 | 默认有没有 /data |
原因 |
|---|---|---|
| CentOS / RHEL / Fedora | ✅ 有 | 安装器按"服务器用途"分区模板自动创建(/boot、swap、/、/home、/data) |
| Ubuntu / Debian | ❌ 没有 | 严格遵守 FHS(Filesystem Hierarchy Standard):/ 下只放系统目录,业务目录由用户/管理员自己规划 |
FHS 规定的 / 下"官方目录"(Ubuntu 会装出来的):
/bin /sbin /etc /usr /var /opt /srv /home /root /lib /tmp ...
没有 /data、/app、/projects 这些"业务目录" —— 因为 FHS 认为这些应由使用场景决定,不由发行版预设。
CentOS 的 /data 的传统用途:
- 放第三方应用(Oracle、MySQL 早期默认数据目录)
- 放业务服务数据(公司内部约定的"业务数据根目录")
- 隔离系统盘和业务盘(
/满了/data还能撑)
Ubuntu 推荐替代:
# 方案 1:放用户主目录(最常用,WSL 首选)
mkdir -p ~/data/{projects,downloads,backups}
# 方案 2:放 Windows 盘(WSL 重装不丢,跨平台)
mkdir -p /mnt/d/wsl-data
ln -s /mnt/d/wsl-data ~/data
# 方案 3:跑服务用 /opt 或 /srv(生产推荐,符合 FHS)
sudo mkdir -p /opt/myapp/{data,logs,config}
sudo chown -R $USER:$USER /opt/myapp
# FHS 标准用途速查:
# /opt/<应用名>/ —— 第三方应用(如 /opt/mysql、/opt/idea)
# /srv/<服务>/ —— 服务对外提供的数据(如 /srv/www、/srv/ftp)
# /var/lib/<服务>/—— 服务运行时数据(MySQL、PostgreSQL 等的默认位置)
# /home/<用户>/ —— 用户文件
要不要在 Ubuntu 上建 /data?
| 场景 | 建议 |
|---|---|
| 单机自己用,临时存点东西 | ❌ 不需要,直接用 ~/data 或 /mnt/d/wsl-data |
| 多用户共享数据 | ✅ 建 /data 也可以(CentOS 用户熟悉,迁移成本低) |
| 跑生产服务(数据库、消息队列) | ✅ 建独立挂载点,如 /data/mysql、/data/kafka |
| 只是从 CentOS 习惯迁移过来 | ❌ 不用硬建,用 ~/data、/opt/<app>、/srv/<svc> 替代更规范 |
💡 一句话总结:Ubuntu 没提供
/data不是缺陷,是留给用户规划的权利。如无需特殊规划,建议优先采用方案 1 的~/data作为起点。
5.6.4 在根目录建 /data 也可行,但需充分了解其风险与限制
# 极简做法:根目录直接建
sudo mkdir -p /data
sudo chown -R $USER:$USER /data
适用场景:临时数据、容器卷、一次性实验。
不适用场景:长期重要数据、数据库文件、git 仓库、备份(一旦 WSL 损坏就丢了)。
5.6.5 重要:定期回收虚拟磁盘空间
WSL2 的 ext4.vhdx 是稀疏文件——在 WSL 里 rm 一个大文件,Windows 侧的 vhdx 不会自动缩小。长时间使用后,Windows 资源管理器显示 vhdx 文件大小为 500 GB,但 WSL 内部实际数据仅占 50 GB——多出的 450 GB 是之前删除文件后未释放的"空洞"空间。
5.6.5.1 先确认你的 ext4.vhdx 在哪
不同安装方式位置不同,先用下面任一命令找到自己的 vhdx 路径:
# 方法 1:wsl 命令直接显示(PowerShell)
wsl -l -v
# 输出包含发行版名称、状态及 WSL 版本号(VERSION 列显示 1 或 2)
# 查看发行版安装路径:wsl --manage <DistroName> --show-location(Win11 特定版本支持)或使用 Get-ChildItem 搜索 ext4.vhdx
# 方法 2:全盘搜 ext4.vhdx(最通用,覆盖所有安装方式)
Get-ChildItem C:\,D:\,E:\ -Recurse -Filter ext4.vhdx -ErrorAction SilentlyContinue | Select-Object FullName, Length
# 方法 3:常见路径直接列(按安装方式)
# - Microsoft Store 版:%LOCALAPPDATA%\Packages\CanonicalGroupLimited.*\LocalState\ext4.vhdx
# - Docker Desktop 版:%LOCALAPPDATA%\Docker\wsl\data\ext4.vhdx
# - 手动 wsl --import 版:你 import 时指定的路径,如 D:\wsl\Ubuntu-24.04\ext4.vhdx
常见路径速查表:
| WSL 来源 | 典型 vhdx 路径 | 是否要自己记住 |
|---|---|---|
| Microsoft Store 安装 | C:\Users\<你>\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu24.04LTS_<随机串>\LocalState\ext4.vhdx |
❌ 随机串安装后固定不变,可记录备用 |
| Docker Desktop | C:\Users\<你>\AppData\Local\Docker\wsl\data\ext4.vhdx |
❌ 固定 |
手动 wsl --import |
你 import 时指定的路径,如 D:\wsl\Ubuntu-24.04\ext4.vhdx |
✅ 自己定的,最稳 |
| LxRunOffline 安装 | 安装时指定 | ✅ 自己定的 |
💡 推荐:手动
wsl --import安装的 WSL,vhdx 路径就是安装时指定的目录,最清楚也最好维护,建议用这种方式安装。
5.6.5.2 手动回收(PowerShell 管理员)
以手动 import 的路径 D:\wsl\Ubuntu-24.04\ext4.vhdx 为例(其他路径同理,把路径替换掉即可):
# 1. 关闭所有 WSL 实例(不关会导致 vhdx 被锁,diskpart 失败)
wsl --shutdown
# 2. 用 diskpart 压缩
diskpart
进入 diskpart 后输入:
select vdisk file="D:\wsl\Ubuntu-24.04\ext4.vhdx"
compact vdisk
exit
⚠️ 注意:
- 用管理员 PowerShell 运行(否则 diskpart 报"权限不足")
- WSL 要已关(否则 vhdx 被占用会报"文件正被另一个进程使用")
compact vdisk期间会临时再占用 1~2 倍当前 vhdx 大小的空闲空间(D 盘至少留 50%)
5.6.5.3 一键脚本(推荐每月跑一次)
把脚本放在 D:\wsl\compact-ubuntu.ps1,右键 → 使用 PowerShell 管理员运行:
# =============================================
# D:\wsl\compact-ubuntu.ps1
# 用途:回收 WSL2 手动 import 的 ext4.vhdx 占用空间
# 用法:右键 → 使用 PowerShell 管理员运行
# =============================================
# 1. 关闭所有 WSL 实例
wsl --shutdown
Start-Sleep -Seconds 3
# 2. 配置 vhdx 路径(手动 import 时的路径,常见在 D:\wsl\ 下)
$vhdxPath = "D:\wsl\Ubuntu-24.04\ext4.vhdx"
# 如果你用 Microsoft Store 版,把上面换成:
# $vhdxPath = "$env:LOCALAPPDATA\Packages\CanonicalGroupLimited.*\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. 执行(会跑几十秒到几分钟,vhdx 越大越久)
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
输出示例:
📦 压缩前:85.30 GB
Virtual Disk Service utility...
100 percent completed.
DiskPart successfully compacted the virtual disk file.
📦 压缩后:22.10 GB(回收 63.20 GB)
5.6.5.4 高级用法:定时自动回收
把脚本加入 Windows 任务计划程序(每月 1 号凌晨 2 点自动跑,无需手动操作):
# 在管理员 PowerShell 里执行一次即可
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File D:\wsl\compact-ubuntu.ps1"
$trigger = New-ScheduledTaskTrigger -Monthly -DaysOfMonth 1 -At "02:00"
Register-ScheduledTask -TaskName "WSL Compact vhdx" -Action $action -Trigger $trigger -RunLevel Highest -Description "每月压缩 WSL 虚拟磁盘"
查看 / 删除任务:
Get-ScheduledTask -TaskName "WSL Compact vhdx" # 查看
Unregister-ScheduledTask -TaskName "WSL Compact vhdx" # 删除
5.6.6 WSL 常用运维命令
# 查看 WSL 版本和状态(Windows PowerShell)
wsl -l -v
# 关闭所有 WSL 实例
wsl --shutdown
# 导出当前发行版做备份(PowerShell)
wsl --export Ubuntu D:\wsl-backup\ubuntu-$(Get-Date -Format yyyyMMdd).tar
# 从备份恢复(PowerShell)
wsl --import Ubuntu C:\WSL\Ubuntu D:\wsl-backup\ubuntu-xxx.tar
# 设置默认登录用户(root → ubuntu)
ubuntu config --default-user ubuntu # Microsoft Store 版
# 或在 /etc/wsl.conf 加:
# [user]
# default = ubuntu
5.6.7 常见误区
| 误区 | 正确做法 |
|---|---|
"在 / 建文件夹要分配空间" |
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 或外部盘 |
5.6.8 WSL 网络配置与 Windows 互通
💡 谁需要看本节:WSL2 用户(Microsoft Store 安装 / Docker Desktop /
wsl --import/ LxRunOffline 任一方式)。
❌ 谁可以跳过:物理机、云服务器、VMware/VirtualBox 虚拟机用户(按 4.1 节 Netplan 配置即可)。📋 WSL 前置准备:
阅读本节前,建议先完成以下两项通用配置:
- 启用 systemd:参考 5.6.8.11 WSL 启用 systemd
- 安全编辑
/etc/wsl.conf:参考 5.6.8.5 单发行版配置 中的“完整配置流程”脚本后续各节默认你已启用 systemd,不再重复解释
hostnamectl/timedatectl/systemctl的前提条件。
5.6.8.1 为什么 Netplan 在 WSL 里改了不生效?
WSL2 的网络栈完全由 Windows 虚拟出来,跟真机差异巨大:
| 项目 | 标准 Ubuntu 24.04 | WSL2 Ubuntu |
|---|---|---|
| 网络栈 | 真实物理网卡,靠 Netplan / systemd-networkd 管理 | 微软虚拟的 vNIC(eth0),IP 由 Windows 虚拟 DHCP 给 |
| 配置文件 | /etc/netplan/*.yaml 生效 |
改完会被 WSL 启动时覆盖 |
| 改静态 IP | 改 yaml + netplan apply |
必须改 Windows 侧的 %USERPROFILE%\.wslconfig |
| 网卡名 | ens33 / enp0s3 等(按硬件命名) |
永远是 eth0 |
| 配置文件目录 | /etc/netplan/ 通常有内容 |
/etc/netplan/ 经常是空的(典型 WSL 标志) |
快速判断你是不是 WSL:
# 三个特征命中 2 个以上 = 99% 是 WSL
ls /etc/netplan/ 2>/dev/null | wc -l # WSL 一般是 0
cat /proc/version | grep -i microsoft # 含 "microsoft" 字样
cat /proc/sys/kernel/osrelease | grep WSL2 # 含 "microsoft-standard-WSL2"
5.6.8.2 WSL 配置文件位置
| 文件 | 位置(在 Windows 侧!) | 作用 |
|---|---|---|
.wslconfig |
C:\Users\<你>\.wslconfig |
全局 WSL2 配置(网络模式、内存、CPU、镜像等) |
wsl.conf |
/etc/wsl.conf(WSL 内) |
单发行版配置(默认用户、挂载、自动挂载选项等) |
| Netplan yaml | /etc/netplan/*.yaml |
❌ WSL 忽略 |
5.6.8.3 三种网络模式对比
| 模式 | 配置项 | 特点 | 适用场景 |
|---|---|---|---|
| NAT(默认) | (不配) | WSL 跟 Windows 共享 IP,外部看到的是 Windows 的 IP;从 Windows 访问 WSL 服务用 localhost:端口 |
日常开发,对外不暴露服务 |
| Mirrored 镜像(推荐) | networkingMode=mirrored |
WSL 跟 Windows 共享同一网络栈;WSL 服务在局域网里有独立 IP | 跨 VPN 调试、WSL 服务需被局域网访问、跑 Docker |
| Bridged 桥接 | wsl --set-version <distro> 1 后用 Hyper-V 桥接 |
WSL 跟物理机同网段 | WSL1 已淘汰,WSL2 不支持 |
5.6.8.4 推荐配置:.wslconfig(Windows 侧)
在 Windows PowerShell 里创建/编辑:
# 用记事本编辑(或改用 code $env:USERPROFILE\.wslconfig 以 VSCode 打开)
notepad $env:USERPROFILE\.wslconfig
# =============================================
# C:\Users\<你>\.wslconfig
# WSL2 全局配置
# =============================================
[wsl2]
# 网络:镜像模式(Win11 22H2+ 支持,跨 VPN、跑服务都方便)
networkingMode=mirrored
# DNS:让 WSL 复用 Windows 的 DNS 解析(避免 DNS 污染 / 跨 VPN 失效)
dnsTunneling=true
# 防火墙:WSL 服务走 Windows 防火墙
firewall=true
# 代理:自动走 Windows 系统代理
autoProxy=true
# =============================================
# 资源限制(按需调整)
# =============================================
# 内存上限(默认 = Windows 总内存的 50% 或 8 GB)
memory=8GB
# CPU 核心数
processors=4
# 交换内存
swap=4GB
# 禁用内存自动回收(长任务运行期间避免内存回收导致卡顿;空闲时仍保留已分配内存)
vmIdleTimeout=-1
# =============================================
# 高级:限制 WSL 能看到的 Windows 盘(最小化挂载)
# =============================================
# 取消下一行注释后,WSL 默认不挂载 Windows 盘,需要时手动 mount
# defaultMountOptions=metadata,umask=22,fmask=11
让配置生效:
wsl --shutdown
# 重新打开 WSL 终端
验证镜像模式已启用:
# 在 WSL 里
ip addr show eth0
# 看到 inet 192.168.x.x/24 或 10.x.x.x → 镜像模式生效
# 看到 inet 172.x.x.x/20 → 还是 NAT 模式(配置没生效)
# 测试 DNS 是否走 Windows
nslookup baidu.com
# Server 应该是 127.0.0.1 或 Windows 侧 DNS,不是 8.8.8.8
5.6.8.5 单发行版配置:/etc/wsl.conf(WSL 内)
sudo vim /etc/wsl.conf
# =============================================
# /etc/wsl.conf —— 单发行版配置
# =============================================
[user]
# 默认登录用户(root 改成普通用户)
default = ubuntu
[boot]
# ⭐ 关键:启用 systemd(不加这条,所有 *ctl 工具不能用)
systemd=true
# 启动时执行的命令(启用 systemd 后会被忽略,留着兼容)
command = "service ssh start"
[automount]
# 是否自动挂载 Windows 盘(C:\、D:\ → /mnt/c、/mnt/d)
enabled = true
# 挂载选项:metadata 让 Windows 盘里的文件可设 Linux 权限
options = "metadata,umask=22,fmask=11"
[network]
# ⚠️ 设为 false:避免 WSL 自动覆盖 /etc/hosts(让 hostnamectl 改的主机名能持久)
generateHosts = false
# DNS 仍由 Windows 提供
generateResolvConf = true
[interop]
# 是否允许从 WSL 启动 Windows 程序
enabled = true
关键配置说明:
| 字段 | 作用 | 加不加? |
|---|---|---|
[boot] systemd=true |
启用 systemd(hostnamectl / timedatectl / systemctl 全部能用) | ✅ 加(用 systemctl 等工具的前提) |
[boot] command = ... |
启动时执行的命令(启用 systemd 后会被忽略) | 可选(兼容保留) |
[network] generateHosts = false |
不自动覆盖 /etc/hosts | ✅ 改了主机名/自定义 hosts 时加 |
[network] generateResolvConf = true |
DNS 走 Windows | ✅ 默认即可 |
[automount] enabled = true |
自动挂载 Windows 盘到 /mnt/c /mnt/d | ✅ 默认即可 |
[interop] enabled = true |
允许从 WSL 启动 Windows 程序 | ✅ 默认即可 |
让 wsl.conf 生效:
# Windows PowerShell
wsl --shutdown
# 重开 WSL 终端
完整配置流程(推荐逐步走):
# 1. 备份现有 wsl.conf(如果有)
sudo cp /etc/wsl.conf /etc/wsl.conf.bak.$(date +%Y%m%d%H%M%S) 2>/dev/null
# 2. 用 sed 安全方式追加各段(不覆盖已有内容)
# [user] 段
if ! grep -q "^\[user\]" /etc/wsl.conf; then
echo "[user]" | sudo tee -a /etc/wsl.conf > /dev/null
echo "default = ubuntu" | sudo tee -a /etc/wsl.conf > /dev/null
fi
# [boot] 段
if ! grep -q "^\[boot\]" /etc/wsl.conf; then
echo "[boot]" | sudo tee -a /etc/wsl.conf > /dev/null
echo "systemd=true" | sudo tee -a /etc/wsl.conf > /dev/null
echo "command = \"service ssh start\"" | sudo tee -a /etc/wsl.conf > /dev/null
else
# [boot] 段已存在,确保有 systemd=true
if ! grep -q "^systemd=true" /etc/wsl.conf; then
sudo sed -i '/^\[boot\]/a systemd=true' /etc/wsl.conf
fi
fi
# [network] 段
if ! grep -q "^\[network\]" /etc/wsl.conf; then
echo "[network]" | sudo tee -a /etc/wsl.conf > /dev/null
echo "generateHosts = false" | sudo tee -a /etc/wsl.conf > /dev/null
echo "generateResolvConf = true" | sudo tee -a /etc/wsl.conf > /dev/null
else
# [network] 段已存在,把 generateHosts 改为 false(如果现在是 true)
if grep -q "^generateHosts = true" /etc/wsl.conf; then
sudo sed -i 's/^generateHosts = true/generateHosts = false/' /etc/wsl.conf
fi
fi
# 3. 验证
cat /etc/wsl.conf
⚠️ 覆盖风险:
tee > /dev/null << EOF ... EOF会完全覆盖整个文件——不要直接用覆盖式 heredoc。先cp备份再操作。
5.6.8.6 WSL 与 Windows 互访
| 方向 | 方法 | 示例 |
|---|---|---|
| WSL → Windows 文件 | /mnt/c、/mnt/d |
cat /mnt/c/Windows/System32/drivers/etc/hosts |
| WSL → Windows 网络 | Windows IP(不是 WSL IP) | curl http://$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):8080 |
| WSL → 启动 Windows 程序 | 直接 .exe |
explorer.exe .(打开当前目录) notepad.exe file.txt |
| Windows → WSL 文件 | \\wsl$\Ubuntu-24.04\ |
资源管理器地址栏输 \\wsl$\Ubuntu-24.04\home\ubuntu\ |
| Windows → WSL 网络(NAT 模式) | localhost:端口 |
localhost:3000 localhost:5432 |
| Windows → WSL 网络(镜像模式) | WSL 的 IP 或 localhost |
curl http://$(wsl hostname -I):8080 |
实战示例:VSCode 连 WSL
# 1. WSL 内启动一个 Web 服务
python3 -m http.server 8000
# 2. Windows 侧三种访问方式(镜像模式)
# 方式 a(推荐):localhost:8000
# 方式 b:WSL IP:8000(先 wsl hostname -I 查 IP)
# 方式 c:\\wsl$\Ubuntu-24.04\ 资源管理器打开
# 3. 跨设备访问(镜像模式独有的能力)
# 局域网里另一台机器直接访问 http://<Windows IP>:8000
# NAT 模式做不到
5.6.8.7 常见 WSL 网络坑
| 症状 | 原因 | 解决 |
|---|---|---|
ping baidu.com 不通但 curl 通 |
WSL 默认不允许 ICMP(微软设计) | 用 curl / wget 测试连通,或 sudo iptables -I INPUT -p icmp --icmp-type echo-request -j ACCEPT(重启失效) |
改完 wsl.conf 不生效 |
没 wsl --shutdown |
重启 WSL |
| 跨 VPN 后 WSL 断网 | NAT 模式下 WSL 路由被 VPN 接管 | 改成镜像模式 networkingMode=mirrored |
| WSL 服务在 Windows 访问不到 | NAT 模式下端口未映射 | 镜像模式自动通;NAT 模式要 netsh interface portproxy |
| 镜像网络下,Windows 通过 WSL IP 访问服务超时 | hostAddressLoopback 未开启,Windows 物理网卡入站流量被拦截 |
在 .wslconfig 的 [experimental] 段加 hostAddressLoopback=true,wsl --shutdown 后重启;详见 5.6.8.15 |
| 镜像模式下 WSL 占用 IP 冲突 | 跟物理网络 IP 段重叠 | 在 .wslconfig 改 networkingMode=nat 退回,或在路由器侧预留 IP 段 |
ssh 从 WSL 连不上 Windows 的服务 |
Windows 防火墙挡住 | Windows 防火墙放行对应端口,或暂时关防火墙测试 |
sudo vim 启动后乱码/卡顿;sudo 报 unable to resolve host |
sudo 反向解析主机名失败(/etc/hosts 缺当前主机名) |
把 127.0.1.1 <当前主机名> 追加到 /etc/hosts;详见 5.6.8.10 |
hostnamectl 报 Can't operate |
WSL 未启用 systemd | 在 /etc/wsl.conf 加 [boot] systemd=true,wsl --shutdown 后重启;详见 5.6.8.11 |
timedatectl 报 Can't operate;systemctl 报 Failed to connect to bus |
WSL 未启用 systemd | 同上,启用 systemd;详见 5.6.8.11 |
sudo ufw allow 报 ERROR: problem running |
WSL2 微软内核没编译老 iptables 模块 | 切到 nftables 后端后 reset + enable;详见 5.6.8.13 |
5.6.8.8 WSL 网络排障命令速查
# 查看 WSL 网络模式
ip addr show eth0 | grep inet
# 查看 DNS 配置
cat /etc/resolv.conf
# 查看默认路由
ip route show default
# 测试连通性(注意 ping 不通不代表网络断)
curl -v http://baidu.com # HTTP 测试
nc -zv baidu.com 80 # 端口测试
traceroute baidu.com # 路由追踪
# 查看 WSL 版本
wsl.exe --status # 在 WSL 内调用 Windows 工具
# 查看 Windows 侧 .wslconfig
cat /mnt/c/Users/$(whoami)/../.wslconfig # 注意路径映射
# 或在 PowerShell:Get-Content $env:USERPROFILE\.wslconfig
5.6.8.9 WSL 主机名设置
💡 本节内容:WSL 下设置主机名的方法。
⚠️ 关键前提:先完成 5.6.8.11 启用 systemd。如果希望主机名重启后不丢,还需在
/etc/wsl.conf中配置[network]段。
完整配置流程(按顺序执行):
第 1 步:确认 /etc/wsl.conf 已启用 systemd 和 network 配置
cat /etc/wsl.conf
确保包含以下段(没有则按 5.6.8.5 或 5.6.8.11 配置):
[boot]
systemd=true
[network]
# 禁用 WSL 自动覆盖 /etc/hosts(改了主机名后建议加,否则 systemd-hostnamed 改的主机名会被覆盖)
generateHosts = false
# 显式指定 WSL 主机名(希望主机名不被 Windows 计算机名覆盖时加)
hostname = dev-workspace
📋 为什么加
hostname = xxx能持久化:
- WSL 默认行为:每次启动时用 Windows 计算机名覆盖 Linux 主机名
- 只加
generateHosts = false只能阻止/etc/hosts被覆盖- 加
hostname = dev-workspace才能阻止 WSL 覆盖主机名本身
第 2 步:用 hostnamectl 设置主机名(标准 Linux 方式)
# 确认 systemd 已启用
ps -p 1 -o comm=
# 应该是 systemd
# 设置主机名
sudo hostnamectl set-hostname dev-workspace
第 3 步:同步 /etc/hosts(防止 sudo 解析失败)
# 把新主机名追加到 /etc/hosts(用追加,不要覆盖)
echo "127.0.1.1 dev-workspace" | sudo tee -a /etc/hosts
# 验证 sudo 不再报 "unable to resolve host"
sudo whoami
# 应直接返回 root,无警告
⚠️ 为什么改完主机名还要同步
/etc/hosts:
hostnamectl只改/etc/hostname,不会自动同步/etc/hosts- WSL 也不会自动同步(真机 Ubuntu 通常有 hook 会做)
sudo启动时会反向解析主机名,解析失败则输出unable to resolve host警告,该错误输出会干扰终端控制序列状态,导致 vim 等交互程序异常
第 4 步:重启 WSL 让配置永久生效
exit
在 Windows PowerShell:
wsl --shutdown
# 重新打开 WSL
第 5 步:验证
hostname
# 输出:dev-workspace
hostnamectl
# Static hostname: dev-workspace
cat /etc/hostname
# dev-workspace
cat /etc/hosts | grep dev-workspace
# 127.0.1.1 dev-workspace
sudo whoami
# 无 "unable to resolve host" 警告
未启用 systemd 时(兜底方案):
# 直接编辑 /etc/hostname
echo "dev-workspace" | sudo tee /etc/hostname
# 同步 /etc/hosts
echo "127.0.1.1 dev-workspace" | sudo tee -a /etc/hosts
# 然后 Windows PowerShell 跑 wsl --shutdown,重启 WSL
WSL 主机名命名建议(避免隐私泄露):
- ✅ dev-workspace、ubuntu-dev、linux-sandbox —— 通用名,安全
- ⚠️ 用户名缩写、公司名、项目名 —— 可能暴露身份
- ❌ 真实姓名拼音、手机号、工号 —— 直接隐私泄露
- 限制:小写字母 + 数字 + 中划线(DNS 兼容),≤ 63 字符
🔗 相关章节:
- 5.6.8.5
/etc/wsl.conf单发行版配置 ——[network]段详解- 5.6.8.10 WSL sudo 解析陷阱 —— 改主机名后 vim/sudo 异常的修复
- 5.6.8.11 WSL 启用 systemd ——
hostnamectl的前提- 5.6.8.11.1 WSL 重启的正确方式 —— 改完
wsl.conf怎么生效(不要sudo reboot)
5.6.8.10 WSL sudo 解析陷阱:改了主机名后 vim 无法启动
💡 本节来源:真实踩坑案例。
hostnamectl set-hostname改了主机名后没同步/etc/hosts,导致 sudo 反向解析失败、vim 启动异常、^C乱按后命令错乱,所有问题互相放大,陷入死循环。
症状清单(任一出现就要怀疑本节问题):
sudo vim /etc/hosts
# 现象:vim 启动后光标错乱、按键无反应、^C 退不出
# 同时终端刷:
sudo: unable to resolve host dev-workspace: Temporary failure in name resolution
sudo whoami
# 现象:能返回 root,但每次都刷"unable to resolve host"
# 命令本身能执行,但**会向终端输出错误信息并残留异常控制字符**,导致后续 vim/apt 等交互式程序异常
根因:
| 步骤 | 真机 | WSL |
|---|---|---|
hostnamectl set-hostname xxx 写入 /etc/hostname |
✅ | ✅ |
/etc/hosts 自动同步 |
✅(很多发行版有 hook) | ❌ WSL 不会自动同步 |
sudo 启动时反向解析 xxx |
找到 | 解析失败 → 报 warning + 污染终端 |
完整的修复流程(按顺序,不要跳步):
第 1 步:把当前主机名追加到 /etc/hosts(核心,1 行解决)
📋 提示:这一步其实就是 5.6.8.9 主机名设置 中“第 3 步:同步
/etc/hosts”。如果你按 5.6.8.9 的标准流程操作过,通常不会遇到本节故障。
echo "127.0.1.1 $(hostname)" | sudo tee -a /etc/hosts
输出:
127.0.1.1 dev-workspace ← tee 写成功
⚠️ 用
tee -a(追加),不要用>(覆盖)——/etc/hosts还有localhost等关键行,覆盖掉会导致更多问题。
第 2 步:立刻验证 sudo 恢复正常
sudo whoami
# 应直接返回 root 或 ubuntu,无 "unable to resolve host" 警告
第 3 步:用 tee 写 /etc/wsl.conf(持久化主机名)
📋 提示:更通用的
wsl.conf安全编辑脚本(含[user]、[boot]、[automount]、[interop]等段)请参考 5.6.8.5 单发行版配置。本节脚本针对本故障场景精简,重点确保generateHosts = false和hostname正确写入。
⚠️ 不要用 vim —— 此时 vim 可能仍处于异常状态。用 tee 写多个段,但要先备份:
# 先备份
sudo cp /etc/wsl.conf /etc/wsl.conf.bak.$(date +%Y%m%d%H%M%S) 2>/dev/null
# 用 sed 逐段写(每段追加,不覆盖已有内容)
if ! grep -q "^\[user\]" /etc/wsl.conf; then
echo "[user]" | sudo tee -a /etc/wsl.conf > /dev/null
echo "default = ubuntu" | sudo tee -a /etc/wsl.conf > /dev/null
echo "" | sudo tee -a /etc/wsl.conf > /dev/null
fi
if ! grep -q "^\[boot\]" /etc/wsl.conf; then
echo "[boot]" | sudo tee -a /etc/wsl.conf > /dev/null
echo "systemd=true" | sudo tee -a /etc/wsl.conf > /dev/null
echo "" | sudo tee -a /etc/wsl.conf > /dev/null
fi
if ! grep -q "^\[network\]" /etc/wsl.conf; then
echo "[network]" | sudo tee -a /etc/wsl.conf > /dev/null
echo "generateHosts = false" | sudo tee -a /etc/wsl.conf > /dev/null
echo "generateResolvConf = true" | sudo tee -a /etc/wsl.conf > /dev/null
echo "hostname = dev-workspace" | sudo tee -a /etc/wsl.conf > /dev/null
echo "" | sudo tee -a /etc/wsl.conf > /dev/null
fi
# 验证
cat /etc/wsl.conf
📋 命令解读:
grep -q "^\[xxx\]":检查段是否存在if ! ... then ... fi:段不存在才追加sudo tee -a /etc/wsl.conf:以 root 权限追加到文件echo "..." | sudo tee -a:逐行追加写入,避免覆盖已有内容
第 4 步:PowerShell 重启 WSL,让 wsl.conf 永久生效
wsl --shutdown
# 重开 WSL 终端
第 5 步:验证
hostnamectl # Static hostname: dev-workspace(永久)
hostname # dev-workspace
cat /etc/hostname # dev-workspace
cat /etc/hosts # 包含 127.0.1.1 dev-workspace
sudo whoami # 无警告
为什么用 tee 不用 vim?
| 方式 | 优点 | 缺点 |
|---|---|---|
sudo vim /etc/wsl.conf |
可视化、所见即所得 | 此时 vim 可能因 sudo 解析问题卡死;按 Ctrl+C 可能导致终端状态异常或命令残留 |
sudo tee ... <<'EOF' |
一次性写完,完全绕开 vim;可粘贴整段 | 不能像 vim 那样交互编辑(但本场景是"几行配置一次写完",不需要) |
echo "..." | sudo tee -a |
追加一行最方便 | 只能追加一行 |
故障状态下的"应急三连"(按顺序复制粘贴,不要按 Ctrl+C):
# 1. 把当前主机名写进 hosts
echo "127.0.1.1 $(hostname)" | sudo tee -a /etc/hosts
# 2. 立刻验证
sudo whoami
# 3. 用 sed 写 wsl.conf(不覆盖已有内容,paste 不易切分)
sudo cp /etc/wsl.conf /etc/wsl.conf.bak.$(date +%Y%m%d%H%M%S) 2>/dev/null
# [user] 段
if ! grep -q "^\[user\]" /etc/wsl.conf; then
echo "[user]" | sudo tee -a /etc/wsl.conf > /dev/null
echo "default = ubuntu" | sudo tee -a /etc/wsl.conf > /dev/null
fi
# [boot] 段
if ! grep -q "^\[boot\]" /etc/wsl.conf; then
echo "[boot]" | sudo tee -a /etc/wsl.conf > /dev/null
echo "command = \"service ssh start\"" | sudo tee -a /etc/wsl.conf > /dev/null
fi
# [network] 段
if ! grep -q "^\[network\]" /etc/wsl.conf; then
echo "[network]" | sudo tee -a /etc/wsl.conf > /dev/null
echo "generateHosts = false" | sudo tee -a /etc/wsl.conf > /dev/null
echo "generateResolvConf = true" | sudo tee -a /etc/wsl.conf > /dev/null
fi
# [hostname] 段
if ! grep -q "^\[hostname\]" /etc/wsl.conf; then
echo "[hostname]" | sudo tee -a /etc/wsl.conf > /dev/null
echo "hostname = dev-workspace" | sudo tee -a /etc/wsl.conf > /dev/null
fi
执行上述三步操作后,vim 将恢复正常,主机名配置也将永久生效。
关于 WSL 终端里的 Ctrl+C:
⚠️ WSL 终端中按
Ctrl+C会发送 SIGINT 信号。注意:在命令行输入过程中,若光标位于行首时按Ctrl+C,可能导致异常行为:
- 可能导致命令首字符被截断(如
echo变为cho)- 可能中断正在执行的
tee/cat/apt等命令,导致操作不完整- 可能使 vim / nano 进入异常状态
最稳的做法:右键 → 粘贴(WSL 终端支持),或者用 ↑ 方向键调出历史命令再编辑。
预防措施(改主机名前先做这两件事,可避免整个坑):
# 改主机名之前先把旧的写进 hosts(以防万一)
echo "127.0.1.1 $(hostname)" | sudo tee -a /etc/hosts
# 再改主机名
sudo hostnamectl set-hostname dev-workspace
# 立刻把新的也写进 hosts
echo "127.0.1.1 dev-workspace" | sudo tee -a /etc/hosts
或一条命令解决(最推荐):
sudo hostnamectl set-hostname dev-workspace && \
echo "127.0.1.1 dev-workspace" | sudo tee -a /etc/hosts
🔗 相关章节:
- 4.1 配置静态 IP(Netplan)—— 真机/云服务器用
- 4.2 配置主机名 —— 真机方案,WSL 见 5.6.8.9 WSL 主机名设置
- 5.6.5 定期回收虚拟磁盘 —— vhdx 维护
- 5.6.6 WSL 常用运维命令 ——
wsl --export/--import/--shutdown- 5.6.8.9 WSL 主机名持久化 —— 改主机名的标准做法
- 5.6.8.10 —— 改主机名时 sudo 报错的完整修复
- 5.6.8.11 —— WSL 非 systemd 模式下的 hosts 自动化维护(当前节)
- 5.6.8.11.1 WSL 重启的正确方式 —— 改完
wsl.conf怎么生效
5.6.8.11 WSL 启用 systemd
💡 本节内容:WSL2 启用 systemd 的标准方法——适用于任何 WSL2 发行版(不论是 Microsoft Store 装的还是
wsl --import装的)。
为什么启用 systemd:
| 工具 | 启用 systemd 后 | 未启用 |
|---|---|---|
systemctl start ssh |
✅ | ❌ 改用 service ssh start |
hostnamectl set-hostname |
✅ | ❌ 手动改 /etc/hostname |
timedatectl set-timezone |
✅ | ❌ 手动 ln -s 软链 |
journalctl -u ssh |
✅ | ❌ 改用 cat /var/log/auth.log |
localectl、loginctl |
✅ | ❌ |
启用步骤(3 步,适用于所有 WSL2):
📋 提示:如果你需要一次性配置完整的
wsl.conf(含[user]、[network]、[automount]等段),请参考 5.6.8.5 单发行版配置。本节只聚焦如何单独启用 systemd。
第 1 步:在 WSL 内编辑 /etc/wsl.conf
# 先备份(防止覆盖掉其他段)
sudo cp /etc/wsl.conf /etc/wsl.conf.bak.$(date +%Y%m%d%H%M%S) 2>/dev/null
# 看现有内容(确认有没有要保留的段)
cat /etc/wsl.conf
# 安全方式:在现有 [boot] 段追加 systemd=true(如段不存在则新建)
if grep -q "^\[boot\]" /etc/wsl.conf; then
sudo sed -i '/^\[boot\]/a systemd=true' /etc/wsl.conf
else
# 追加 [boot] 段到文件末尾
echo "" | sudo tee -a /etc/wsl.conf > /dev/null
echo "[boot]" | sudo tee -a /etc/wsl.conf > /dev/null
echo "systemd=true" | sudo tee -a /etc/wsl.conf > /dev/null
fi
# 验证
cat /etc/wsl.conf
# 应该有 [boot] systemd=true
⚠️ 覆盖风险提示:
tee > /dev/null << EOF ... EOF会完全覆盖整个文件——如果/etc/wsl.conf已有[user]、[network]等段,会被清空。不要直接tee覆盖已有配置文件,先cp备份 +cat看清楚再操作。
第 2 步:在 Windows PowerShell 重启 WSL
wsl --shutdown
第 3 步:重开 WSL 终端,验证
ps -p 1 -o comm=
# 应该输出:systemd
如果还是 init:
# 1. 确认 wsl.conf 写对了
cat /etc/wsl.conf
# 应该看到:
# [boot]
# systemd=true
# 2. 确认 WSL 版本(要 ≥ 0.67.6)
# Windows PowerShell:
# wsl --version
# 3. 再次重启 WSL
# wsl --shutdown
注意事项:
- ✅ 启用 systemd 后,
/etc/wsl.conf的[boot] command=会被忽略(systemd 接管启动流程)——用户服务应该用systemctl管理 - ✅ 启用 systemd 后,用户服务(如
ssh、fail2ban)的systemctl enable才能真正生效 - ⚠️ 某些镜像(如 Docker pull 装的)即使加了
[boot] systemd=true仍启不动——这跟镜像源有关,不是配置问题
反向操作(关掉 systemd):
# 安全方式:把 [boot] 段的 systemd=true 改为 false(其他段保留)
if grep -q "^systemd=true" /etc/wsl.conf; then
sudo sed -i 's/^systemd=true/systemd=false/' /etc/wsl.conf
fi
# 验证
grep "systemd" /etc/wsl.conf
# 应该输出:systemd=false
# 然后 PowerShell: wsl --shutdown
🔗 相关章节:
- 5.6.8.7 常见 WSL 网络坑 —— 症状速查表(含本节对应行)
- 5.6.8.11.1 —— WSL 重启的正确方式(当前节的扩展)
5.6.8.11.1 WSL 重启的正确方式
💡 本节内容:WSL 改了哪些配置后必须重启 WSL,以及正确的重启命令。
哪些配置改了必须重启 WSL:
| 配置文件 / 操作 | 是否需要重启 WSL |
|---|---|
/etc/wsl.conf(所有段) |
✅ 必须 |
~/.wslconfig(Windows 侧) |
✅ 必须 |
/etc/systemd/system.conf |
✅ 必须(systemd 启动时读) |
/etc/security/limits.conf |
⚠️ 仅 PAM 登录的进程生效(重开终端就够) |
| 普通 systemd 服务配置 | ❌ 用 systemctl restart xxx 即可 |
| 软件包安装 / 升级 | ❌ 直接生效 |
正确的重启方式(在 Windows PowerShell):
# 完全关闭 WSL(下次 wsl 命令会重新启动)
wsl --shutdown
# 重新打开 WSL(在 WSL 终端跑这条会进入默认发行版)
wsl
# 或指定发行版
wsl -d Ubuntu-24.04
⚠️ 关键:wsl --shutdown 会强制终止所有 WSL 进程,包括你当前正在修改配置的 SSH 会话。如果通过 SSH 连接到 WSL 执行配置修改,必须先退出该 SSH 会话,否则 wsl --shutdown 会直接断开连接,可能导致未保存的更改丢失。操作顺序:
- 保存所有修改,在 SSH 会话中执行
exit退出 - 在 PowerShell 中关闭 WSL 终端窗口(或执行
exit退出 WSL 交互式 shell) - 在 PowerShell 中执行
wsl --shutdown - 重新打开 WSL 终端(或重新 SSH 连接)
PowerShell 里单独 exit 只是退出当前 shell 会话,WSL 虚拟机仍在后台运行;若仍有活动连接(如你正在修改配置的那个 SSH 会话),wsl --shutdown 会强制断开它,建议主动退出后再执行。
❌ 不要用 sudo reboot:
sudo reboot
# Broadcast message from root@xxx (xxx CST):
# The system will power off now!
# Welcome to Ubuntu ... ← 看似重启了,其实只是进程重启
| 行为 | sudo reboot(WSL 内部) |
wsl --shutdown(PowerShell) |
|---|---|---|
| 杀进程 | ✅ | ✅ |
| 重启 WSL 服务 | ❌ 不会 | ✅ 会 |
重新读 wsl.conf |
❌ | ✅ |
重新读 system.conf |
❌ | ✅ |
重新读 .wslconfig |
❌ | ✅ |
| 重新分配内存/CPU 限制 | ❌ | ✅ |
📋 根因:
- WSL 不是真硬件,
reboot找不到 BIOS/固件去调用 - 微软的 WSL 进程管理由 Windows 侧的
LxssManager服务控制 - 必须在 Windows 侧让
LxssManager重新加载所有发行版,wsl --shutdown就是干这个的 - 改了
wsl.conf/system.conf后,没有wsl --shutdown就不会重新读
WSL 内部的其他"重启"命令(也都不可靠):
| 命令 | 实际行为 |
|---|---|
sudo reboot |
杀进程,不会重启 WSL 服务 |
sudo shutdown -r now |
同上 |
sudo systemctl reboot |
同上 |
exit(退出 shell) |
退当前会话,不重启 WSL |
🔗 相关章节:
- 5.6.8.5
/etc/wsl.conf单发行版配置 —— 改了必须wsl --shutdown - 5.6.8.7 常见 WSL 网络坑 —— 改
wsl.conf不生效的根因 - 5.6.8.9 WSL 主机名设置 —— 改了
hostname必须wsl --shutdown - 5.6.8.11 启用 systemd —— 改了
systemd=true必须wsl --shutdown - 6.3 文件描述符限制 —— 改了
system.conf必须wsl --shutdown(不要用sudo reboot) - 5.6.8.11.1 —— WSL 重启的正确方式(当前节)
5.6.8.12 WSL 时区设置
💡 本节内容:WSL 下设置时区的方法——优先用
timedatectl(启用 systemd 后),备用ln -s。
推荐方式:启用 systemd 后用 timedatectl
# 1. 确保启用了 systemd(见 [5.6.8.11 WSL 启用 systemd](#56811-wsl-启用-systemd))
ps -p 1 -o comm=
# 应该是 systemd
# 2. 设置时区
sudo timedatectl set-timezone Asia/Shanghai
# 3. 验证
date
# 应该输出 CST 时间
# Tue Jun 11 14:23:45 CST 2026
未启用 systemd 时(兜底):/etc/localtime 软链
# 1. 查看当前时区
ls -l /etc/localtime
# 2. 改时区
sudo unlink /etc/localtime
sudo ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
# 3. 验证
date
常用时区速查:
| 城市/地区 | 时区标识 |
|---|---|
| 上海/北京 | Asia/Shanghai |
| 香港 | Asia/Hong_Kong |
| 台北 | Asia/Taipei |
| 东京 | Asia/Tokyo |
| 新加坡 | Asia/Singapore |
| UTC(默认) | Etc/UTC |
| 美国西部 | America/Los_Angeles |
| 美国东部 | America/New_York |
| 欧洲伦敦 | Europe/London |
| 欧洲柏林 | Europe/Berlin |
交互式菜单(更直观):
sudo dpkg-reconfigure tzdata
# 选 "Asia" → 选城市
⚠️ 注意:交互式菜单在某些终端会乱码——用
timedatectl或ln -s更稳。
WSL 时间同步:
WSL2 的时间默认和 Windows 同步(WSL 启动时从 Windows 校准一次),所以一般不需要单独配 NTP。如果发现时间漂移:
# 启用 systemd 后:用 timedatectl 触发同步
sudo timedatectl timesync-status
# 未启用 systemd:手动重读硬件时钟
sudo hwclock -s
🔗 相关章节:
- 4.3 时区与时间同步 —— 真机方案
- 5.6.8.7 常见 WSL 网络坑 —— 症状速查表
- 5.6.8.11 WSL 启用 systemd ——
timedatectl的前提- 5.6.8.12 —— WSL 时区设置(当前节)
5.6.8.13 WSL 防火墙:ufw 修复 + nftables 兜底
💡 本节来源:6.1 ufw 防火墙节在 WSL2 下直接跑会报
ERROR: problem running,根因是 WSL2 的微软定制内核(Linux 6.6.114.1-microsoft-standard-WSL2)没编译老 iptables 模块。本节给出完整的修复流程和直接绕开 ufw 的兜底方案。
症状(任一出现就是本节场景):
sudo ufw allow 80/tcp
# ERROR: problem running
sudo ufw status
# 同样的报错,或者状态异常
sudo iptables -L INPUT -n
# modprobe: FATAL: Module ip_tables not found
# iptables v1.8.x (legacy): can't initialize iptables table `filter': ...
根因:
| 组件 | 状态 |
|---|---|
| WSL2 微软内核 | 缺 ip_tables、iptable_filter 等老 iptables 内核模块 |
| WSL2 微软内核 | 有 nftables 内核后端(/proc/net/netfilter/nf_tables_api 存在) |
| ufw 0.36+ | 默认走 nftables 后端(但有 bug 仍优先调用老 iptables) |
结论:WSL 下 ufw 需要切到 nftables 后端才能正常用。
完整修复流程(5 步,按顺序跑):
第 1 步:重置 ufw 状态
sudo ufw --force reset
# 会自动备份旧规则到 /etc/ufw/*.rules.<时间戳>
第 2 步:切到 nftables 后端
sudo update-alternatives --set iptables /usr/sbin/iptables-nft
sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-nft
sudo update-alternatives --set arptables /usr/sbin/arptables-nft
sudo update-alternatives --set ebtables /usr/sbin/ebtables-nft
📋 update-alternatives 是什么:Debian/Ubuntu 的"多版本切换器",把
/usr/sbin/iptables指向iptables-nft(即"用 nftables 内核后端模拟 iptables 命令")。
第 3 步:验证 nftables 可用
sudo nft list tables
# 预期输出(空或已有表都行,不要报错):
# table ip filter
# table ip6 filter
第 4 步:重新启用 ufw
sudo ufw --force enable
# 预期输出:Firewall is active and enabled on system startup
第 5 步:加规则并验证
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw status verbose
# 预期看到 22/80/443 全部 ALLOW IN,IPv4 + IPv6 都有
完整输出应该长这样:
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
-- ------ ----
22/tcp ALLOW IN Anywhere
80/tcp ALLOW IN Anywhere
443/tcp ALLOW IN Anywhere
22/tcp (v6) ALLOW IN Anywhere (v6)
80/tcp (v6) ALLOW IN Anywhere (v6)
443/tcp (v6) ALLOW IN Anywhere (v6)
如果第 5 步还报 ERROR: problem running:
# 看 ufw 真实的报错
sudo ufw --debug 2>&1 | tail -30
会输出具体的 iptables/nft 调用和报错,对症下药。
兜底方案 A:直接用 nftables(最稳)
绕开 ufw,直接操作 nftables 内核后端:
# 1. 初始化一个干净的 filter 表
sudo nft flush ruleset
sudo nft add table inet filter
sudo nft 'add chain inet filter input { type filter hook input priority 0 ; }'
# 2. 放行 SSH / HTTP / HTTPS
sudo nft add rule inet filter input tcp dport { 22, 80, 443 } accept
# 3. 允许本地回环(loopback)
sudo nft add rule inet filter input iif lo accept
# 4. 允许已建立的连接
sudo nft add rule inet filter input ct state established,related accept
# 5. 默认拒绝入站
sudo nft 'add chain inet filter input { type filter hook input priority 0 ; policy drop ; }'
# 6. 看规则
sudo nft list ruleset
兜底方案 B:直接用 iptables(简单场景)
# 放行常用端口
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# 持久化(重启 WSL 自动恢复)
sudo apt install -y iptables-persistent
sudo netfilter-persistent save
⚠️ 互斥提示:
apt install iptables-persistent会自动卸载 ufw(包依赖冲突)。卸了 ufw 后,所有ufw allow/ufw status命令全部失效,只能直接用 iptables/nftables。如果你想保留 ufw 工具:跳过 iptables-persistent,用 方案 A 的 nftables 直接配(启用 systemd 后用
systemctl管理更稳)。
完整流程图(修防火墙的判断路径):
sudo ufw allow 80/tcp
│
▼
报 ERROR: problem running?
│
┌────┴────┐
│ │
否 是
│ │
▼ ▼
继续 sudo ufw --force reset
sudo update-alternatives --set iptables /usr/sbin/iptables-nft
sudo nft list tables ← 验证 nft 可用
sudo ufw --force enable
sudo ufw allow 22/tcp ...
sudo ufw status verbose
│
┌──────┴──────┐
│ │
成功 还报 ERROR
│ │
▼ ▼
完成 用 nftables 直接配
(兜底方案 A)
为什么 sudo ufw allow 80/tcp 第二次跑会报 "Skipping adding existing rule"?
这个提示不是新错误。它说明第一次跑的时候 ufw 配置文件已经写入了规则,但同步到底层 iptables 失败。所以第二次跑 ufw 看到"规则已存在",跳过添加。
这时直接 reset 就能清掉旧配置,重新配。
与 6.1 节的关系:
| 节 | 解决的问题 | 适用场景 |
|---|---|---|
| 3.6 | 真机/云服务器的 SSH 放行 | 标准 Ubuntu |
| 6.1 | 真机/云服务器的 HTTP/HTTPS/复杂规则 | 标准 Ubuntu |
| 5.6.8.13(本节) | WSL 下 ufw 报错的修复 + 兜底 | WSL2 微软内核 |
🔗 相关章节:
- 3.6 防火墙放行 SSH —— 真机首次配置
- 6.1 ufw 防火墙 —— 真机常用规则
- 5.6.8.7 常见 WSL 网络坑 —— 症状速查表(含本节对应行)
- 5.6.8.13 —— WSL 防火墙修复(当前节)
5.6.8.14 WSL 配置文件参考
💡 本节给出启用 systemd 后 WSL 配置文件的参考样例**。
/etc/wsl.conf(WSL 内):
[user]
default = ubuntu
[boot]
systemd=true
[interop]
enabled=true
appendWindowsPath=true
[automount]
enabled=true
mountFsTab=true
[network]
generateHosts = false
generateResolvConf = true
hostname = dev-workspace
📋 各段作用:
段 / 字段 作用 加不加? [user] default = ubuntu默认登录用户(避免 root 登录) ✅ 加(前提是 ubuntu用户存在)[boot] systemd=true启用 systemd( hostnamectl/timedatectl/systemctl全部能用)✅ 加(用 systemd 工具的前提) [boot] command = ...启动时执行命令 ❌ 启用了 systemd 就被忽略,不要加 [interop] enabled = true允许从 WSL 调 Windows 程序( explorer.exe .、notepad.exe)✅ 默认即可 [interop] appendWindowsPath = true把 Windows 的 PATH加进 WSL 环境变量✅ 默认即可(VSCode 远程等工具依赖) [automount] enabled = true自动挂载 Windows 盘( /mnt/c、/mnt/d)✅ 默认即可 [automount] mountFsTab = true读取 /etc/fstab自定义挂载✅ 默认即可 [automount] options = "metadata,..."挂载选项(让 Windows 盘文件可设 Linux 权限) ⚙️ 按需(写文件到 Windows 盘遇到权限问题时加) [network] generateHosts = false阻止 WSL 覆盖 /etc/hosts✅ 改了主机名/自定义 hosts 时加 [network] generateResolvConf = true让 WSL 自动生成 /etc/resolv.conf(DNS 走 Windows)✅ 默认即可 [network] hostname = xxx显式指定 WSL 主机名(不被 Windows 计算机名覆盖) ✅ 希望主机名持久化时加 ⚠️ 启用 systemd 后,
[boot] command = ...会被忽略——服务管理用systemctl enable。
~/.wslconfig(Windows 侧):
[wsl2]
memory=8GB
swap=2GB
⚠️
[wsl2]段只放资源限制(内存、CPU、swap 等)——不要再加其他段。📋 内存配置建议:
物理内存 推荐 memory推荐 swap8 GB 4 GB 2 GB 16 GB 8~12 GB 2~4 GB 32 GB 16~24 GB 2~4 GB 64 GB+ 32 GB 2~4 GB 不要超过 Windows 物理内存的 80%——WSL 跟 Windows 共享内存。
swap一般 2~4 GB 够用。
~/.bashrc 末尾(WSL 内,启用 systemd 后一般不需要):
启用 systemd 后,/etc/hosts 由 systemd-hostnamed 正确管理,不需要 fix_wsl_hosts 函数。
Part 2:常用服务管理(启用 systemd 后)
# 1. SSH(详见 [3.1 安装 openssh-server](#31-安装-openssh-server))
sudo apt install -y openssh-server
sudo systemctl enable --now ssh
# 2. fail2ban(详见 [5.1 一键安装清单](#51-一键安装清单) / [6.2 fail2ban 防爆破](#62-fail2ban-防爆破))
sudo apt install -y fail2ban
sudo systemctl enable --now fail2ban
# 3. ufw 防火墙(详见 [3.6 防火墙放行 SSH](#36-防火墙放行-ssh) / [6.1 ufw 防火墙](#61-ufw-防火墙))
sudo apt install -y ufw
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
# 4. 时区(详见 [4.3 时区与时间同步](#43-时区与时间同步) / [5.6.8.12 WSL 时区设置](#56812-wsl-时区设置))
sudo timedatectl set-timezone Asia/Shanghai
# 5. 主机名(详见 [4.2 配置主机名](#42-配置主机名) / [5.6.8.9 WSL 主机名设置](#5689-wsl-主机名设置))
sudo hostnamectl set-hostname dev-workspace
🔗 相关章节:
- 5.6.8.7 常见 WSL 网络坑 —— 症状速查
- 5.6.8.9 WSL 主机名设置 —— 启用 systemd 后用
hostnamectl- 5.6.8.11 WSL 启用 systemd —— 核心配置(
[boot] systemd=true)- 5.6.8.12 WSL 时区设置 —— 启用 systemd 后用
timedatectl- 5.6.8.13 WSL 防火墙:ufw + nftables
- 5.6.8.14 —— 配置文件参考(当前节)
- 5.6.8.15 —— 镜像网络下 Windows 通过 WSL IP 访问服务超时
5.6.8.15 镜像网络下 Windows 通过 WSL IP 访问服务超时
💡 本节针对
networkingMode=mirrored镜像网络模式。
NAT 模式下用localhost:端口即可,不需要本节配置。
问题现象:
- WSL2 内部服务已正常监听,例如 SSH 监听
0.0.0.0:<PORT>,在 WSL 内curl http://127.0.0.1:<PORT>正常 - 从 Windows 侧通过
localhost:<PORT>访问也正常 - 但从 Windows 侧通过 WSL2 的 eth0 IP(与宿主机同网段)访问时超时失败
- 即使 Windows 防火墙已放行该端口,
Test-NetConnection -Port <PORT>仍显示TcpTestSucceeded : False
根因:
镜像网络模式下,WSL2 与 Windows 共享同一网络栈,但 Windows 本机通过物理网卡 IP 入站访问 WSL2 服务时,默认会被拦截。必须显式开启 hostAddressLoopback 实验特性,允许 Windows 将流量环回到 WSL2。
正确配置(C:\Users\<你>\.wslconfig):
[wsl2]
networkingMode=mirrored
dnsTunneling=true
autoProxy=true
firewall=true
[experimental]
hostAddressLoopback=true
⚠️ 关键:
hostAddressLoopback是实验性功能,必须放在[experimental]段下,不要放在[wsl2]下。
放错位置会导致 WSL 启动时报错并忽略该配置,例如:wsl2.hostAddressLoopback 中的键"hostAddressLoopback"未知(实际报错内容可能因版本而异)
生效步骤:
# 1. 保存 .wslconfig 后,彻底关闭 WSL
wsl --shutdown
# 2. 重新打开 WSL 终端
wsl
验证方法:
# 在 WSL 内查看 eth0 IP
ip addr show eth0 | grep "inet "
# 输出示例:192.168.x.x/24(与宿主机同网段)
# 在 Windows PowerShell 测试连通性(把 <WSL_IP> 和 <PORT> 替换为实际值)
Test-NetConnection -ComputerName <WSL_IP> -Port <PORT>
# 期望输出:TcpTestSucceeded : True
常见误区:
| 误区 | 说明 |
|---|---|
hostAddressLoopback=true 放 [wsl2] 下 |
❌ 错误,WSL 会报错并忽略 |
| 只放行 Windows 防火墙就够了 | ❌ 不够,流量还没到达防火墙就被拦截 |
localhost:<PORT> 能通就说明没问题 |
❌ localhost 走本地回环,不受 hostAddressLoopback 限制;只有走 WSL IP 才需要它 |
改完 .wslconfig 没 wsl --shutdown |
❌ 配置不会生效,必须完全重启 WSL |
适用场景:
- 第三方 SSH 客户端(如 Termius、PuTTY、Xshell)配置 WSL IP 连接
- 局域网内其他设备/虚拟机通过宿主机 IP 访问 WSL 服务
- 需要在 Windows 侧模拟“外部访问”WSL 服务的调试场景
六、安全与优化
6.1 ufw 防火墙
详见 3.6 防火墙放行 SSH,补充常用规则:
# 放行 HTTP/HTTPS
sudo ufw allow 80/tcp comment "HTTP"
sudo ufw allow 443/tcp comment "HTTPS"
# 放行指定 IP 段访问 SSH(更安全)
sudo ufw allow from 192.168.1.0/24 to any port 22
# 拒绝特定 IP
sudo ufw deny from 10.0.0.5
# 删除规则
sudo ufw status numbered
sudo ufw delete <编号>
# 关闭防火墙
sudo ufw disable
⚠️ WSL 用户注意:ufw 在 WSL2 下经常报
ERROR: problem running,根因是 WSL2 微软内核没编译老 iptables 模块,需要切到 nftables 后端才能用。完整的修复 + 兜底方案见 5.6.8.13 WSL 防火墙(先看 5.6.8.13 再操作本节)。
6.2 fail2ban 防爆破
sudo apt install -y fail2ban
sudo vim /etc/fail2ban/jail.local
[DEFAULT]
# 封禁时间(1 小时)
bantime = 1h
# 监测时间窗口(10 分钟)
findtime = 10m
# 最大重试次数
maxretry = 5
# 封禁动作(ufw)
banaction = ufw
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
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 文件描述符限制
大并发服务(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=1024,hard=524288- 所有用
systemctl启动的服务(fail2ban、ssh、nginx、mysql等)都受这个限制- 默认 1024 对大并发服务不够:nginx 一个连接 2~3 个 FD,1024 / 3 ≈ 340 并发就报
too many open files- 改
soft到 65535 是生产/开发环境的标配
# 重启后生效
sudo reboot
⚠️ WSL 用户注意:在 WSL2 下不要用
sudo reboot——WSL 不是真硬件,reboot只会杀进程、不会重读/etc/systemd/system.conf。改完system.conf后必须在 Windows PowerShell 跑wsl --shutdown。详见 5.6.8.11.1 WSL 重启的正确方式。
6.4 内核参数调优
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
6.5 配置 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
七、验证检查清单
完成所有配置后,建议逐项验证。
7.1 通用检查(真机 / 云服务器 / WSL 通用)
| ✅ 检查项 | 🔧 命令 | 🎯 预期 |
|---|---|---|
| SSH 远程可连 | ssh ubuntu@IP |
成功登录(最好密钥免密) |
| 密码登录已关闭 | ssh -o PasswordAuthentication=no ubuntu@IP |
仍可登录 = OK |
| SSH 服务自启 | sudo systemctl is-enabled ssh |
enabled |
| 防火墙已启用 | sudo ufw status |
Status: active |
| 网络连通 | ping -c 3 baidu.com 或 curl -v http://baidu.com |
有响应(注意:WSL 默认禁 ICMP,ping 可能不通) |
| DNS 解析 | dig baidu.com |
返回 IP |
| 时区正确 | timedatectl |
Asia/Shanghai |
| 时间同步 | timedatectl show |
NTPSynchronized=yes |
| 系统已更新 | apt list --upgradable |
无输出 = 已最新 |
| FD 限制 | ulimit -n |
65535(已配置时) |
| 工具齐全 | which htop tmux jq tree vim |
全部有路径 |
| fail2ban 运行 | sudo systemctl status fail2ban |
active (running) |
7.2 真机 / 云服务器额外检查(WSL 跳过)
| ✅ 检查项 | 🔧 命令 | 🎯 预期 |
|---|---|---|
| 静态 IP 生效 | ip addr show <网卡名> |
IP 与配置一致(网卡名因硬件/虚拟化平台而异:常见如 ens33、ens160、enp0s3 等,需按实际填写) |
| 默认路由 | 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
7.3 WSL2 用户额外检查
| ✅ 检查项 | 🔧 命令 | 🎯 预期 |
|---|---|---|
| WSL 发行版 | wsl -l -v(PowerShell 跑) |
看到自己的发行版,版本是 2 |
| systemd 已启用 | ps -p 1 -o comm= |
systemd(不是 init) |
| WSL 主机名 | hostname |
你设的名字(如 dev-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(如已建) |
| 防火墙工具存在 | which ufw 或 which iptables |
至少有一个(WSL 防火墙见 5.6.8.13 WSL 防火墙修复) |
| WSL 发行版 | cat /etc/os-release |
Ubuntu 24.04 |
| WSL 重启生效 | wsl --shutdown 后 wsl(PowerShell 跑) |
配置变更生效 |
| WSL 镜像模式(按需) | ip addr show eth0 |
inet 是 192.168.x 或 10.x(不是 172.x) |
7.4 一键自检脚本(通用 + WSL)
保存为 ~/check-env.sh,chmod +x ~/check-env.sh 后跑:
#!/bin/bash
# =============================================
# Ubuntu 初始环境一键自检脚本
# =============================================
echo "================================"
echo "Ubuntu 初始环境自检"
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 ssh && echo "✅ SSH 自启" || echo "❌ SSH 未自启"
systemctl is-active ssh && echo "✅ SSH 运行中" || echo "❌ SSH 未运行"
echo -e "\n[3] 防火墙"
if command -v ufw &> /dev/null; then
ufw status | head -3
else
echo "⚠️ ufw 未装(WSL 下可能未启用,见 [5.6.8.13 WSL 防火墙修复](#56813-wsl-防火墙ufw-修复--nftables-兜底))"
fi
echo -e "\n[4] 时区与时间"
timedatectl | grep -E "Time zone|System clock"
echo -e "\n[5] 网络"
ip -br addr | grep -v "DOWN" | head -5
echo -e "\n[6] DNS"
cat /etc/resolv.conf 2>/dev/null | grep nameserver | head -2
echo -e "\n[7] 资源限制"
echo "ulimit -n: $(ulimit -n)"
echo "ulimit -u: $(ulimit -u)"
echo -e "\n[8] 工具检查"
for tool in htop tmux jq tree vim git curl wget; do
if command -v $tool &> /dev/null; then
echo "✅ $tool"
else
echo "❌ $tool 缺失"
fi
done
echo -e "\n[9] systemd 状态(WSL 关注)"
ps -p 1 -o comm= | grep -q systemd && echo "✅ systemd 已启用" || echo "❌ PID 1 不是 systemd(WSL 需配置 wsl.conf)"
echo -e "\n[10] 主机名"
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[11] 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 "================================"
八、常用命令速查
8.1 服务管理
| 🔧 操作 | 🔧 CentOS 7 | 🔧 Ubuntu 24.04 |
|---|---|---|
| 启动 | systemctl start sshd |
sudo systemctl start ssh |
| 停止 | systemctl stop sshd |
sudo systemctl stop ssh |
| 状态 | systemctl status sshd |
sudo systemctl status ssh |
| 开机自启 | systemctl enable sshd |
sudo systemctl enable ssh |
| 重载配置 | systemctl reload sshd |
sudo systemctl reload ssh |
| 服务名 | sshd |
ssh |
| 配置文件 | /etc/ssh/sshd_config |
/etc/ssh/sshd_config(路径相同) |
📋 关键差异:Ubuntu 把 SSH 服务名从 CentOS 的
sshd改成了ssh,其他都一致。
8.2 包管理对照
| 🔧 操作 | 🔧 CentOS 7 (yum) | 🔧 Ubuntu 24.04 (apt) |
|---|---|---|
| 更新源索引 | yum check-update |
sudo apt update |
| 安装包 | yum install -y pkg |
sudo apt install -y pkg |
| 删除包 | yum remove pkg |
sudo apt remove pkg |
| 搜索包 | yum search keyword |
apt search keyword |
| 包信息 | yum info pkg |
apt show pkg |
| 列出已装 | yum list installed |
apt list --installed |
| 升级所有 | yum update -y |
sudo apt upgrade -y |
8.3 网络命令对照
| 🔧 用途 | 🔧 CentOS 7 | 🔧 Ubuntu 24.04 |
|---|---|---|
| 查看 IP | ip addr / ifconfig |
ip addr(ifconfig 需装 net-tools) |
| 查看端口 | netstat -tlnp |
netstat -tlnp(需装 net-tools) / ss -tlnp |
| 测试连通 | ping / traceroute |
ping / traceroute(需装) |
| DNS 查询 | nslookup / dig |
dig(需装 dnsutils) |
| 防火墙 | firewalld / firewall-cmd |
ufw |
| 网络配置 | /etc/sysconfig/network-scripts/ifcfg-ens33 |
/etc/netplan/*.yaml |
| 主机名 | hostnamectl set-hostname x |
hostnamectl set-hostname x(相同) |
| SELinux | setenforce 0 |
无(Ubuntu 用 AppArmor) |
8.4 时间与日志对照
| 🔧 用途 | 🔧 CentOS 7 | 🔧 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 |
8.5 防火墙命令对照
| 🔧 操作 | 🟢 ufw(Ubuntu 默认) | 🟡 iptables(底层通用) | 🔵 nftables(现代替代) | 🔴 firewalld(CentOS 默认) |
|---|---|---|---|---|
| 查看状态 | sudo ufw status verbose |
sudo iptables -L -n -v |
sudo nft list ruleset |
sudo firewall-cmd --list-all |
| 启动/启用 | sudo ufw enable |
开机自启需 iptables-persistent |
开机自启需 nftables.service |
sudo systemctl enable --now firewalld |
| 放行 22 端口 | sudo ufw allow 22/tcp |
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT |
sudo nft add rule inet filter input tcp dport 22 accept |
sudo firewall-cmd --permanent --add-port=22/tcp |
| 放行服务名 | sudo ufw allow ssh |
— | — | sudo firewall-cmd --permanent --add-service=ssh |
| 放行 IP 段 | sudo ufw allow from 192.168.1.0/24 |
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 firewall-cmd --permanent --add-source=192.168.1.0/24 |
| 拒绝某 IP | sudo ufw deny from 10.0.0.5 |
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 firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=10.0.0.5 drop' |
| 重新加载 | 自动 | sudo iptables-restore < /etc/iptables/rules.v4 |
sudo nft -f /etc/nftables.conf |
sudo firewall-cmd --reload |
| 关闭防火墙 | sudo ufw disable |
sudo iptables -F(清空规则,慎用) |
sudo nft flush ruleset |
sudo systemctl stop firewalld |
| 命令缺失 | sudo apt install -y ufw |
Ubuntu 自带 | sudo apt install -y nftables |
sudo yum install -y firewalld |
📋 选择建议:
- 标准 Ubuntu 优先用 ufw(本教程主推),最简单。
- 需要复杂规则(端口转发、NAT、限速)用 iptables / nftables。
- 跨平台脚本或 CentOS 兼容场景用 firewalld。
8.6 一键脚本(新建服务器跑一次)
📋 脚本定位:
- 本脚本对应本文档 第二章(初始环境检查)、3.1-3.3(SSH 服务)、4.3(时区)、5.1(常用工具)、6.1-6.5(安全与优化)的最小可用集。
- 不包含的内容:4.1(Netplan 静态 IP,按网络环境差异较大)、4.2(主机名,个性化)、4.5(apt 换源,建议先手动换源再跑此脚本)、5.3-5.5(Git/vim/bashrc 偏好设置)、3.5(密钥免密,建议手动执行以免覆盖既有密钥)。
- 默认按"真机 / 云服务器"编写,脚本会自动识别 WSL2 环境并跳过不适用项(
systemctl、ufw、reboot等)。
#!/bin/bash
# =============================================
# Ubuntu 24.04 初始环境一键配置脚本
# 对应文档:Ubuntu与WSL2初始环境配置与常用工具安装教程.md 第 8.6 节
# 用法:sudo bash init-ubuntu.sh
# 前置:建议先按 4.5 节换 apt 源,再跑本脚本
# 幂等:重复运行不会破坏既有配置(已存在配置会跳过)
# =============================================
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 直登时退到默认 ubuntu)
REAL_USER="${SUDO_USER:-${USER:-ubuntu}}"
[[ "$REAL_USER" == "root" ]] && REAL_USER="ubuntu"
log "运行环境:$( [[ $IS_WSL -eq 1 ]] && echo 'WSL2' || echo '真机/云服务器' )"
log "操作用户:$REAL_USER"
# ---------- 1. 更新源(对应 4.5 / 5.1) ----------
log "[1/9] 更新 apt 源与软件包"
apt update
# upgrade 升级所有包;如不希望升级可注释掉下一行
apt upgrade -y
# ---------- 2. 常用工具(对应 5.1 一键安装清单) ----------
log "[2/9] 安装常用工具集"
apt install -y \
openssh-server openssh-client \
vim nano curl wget git \
net-tools dnsutils iputils-ping traceroute mtr \
unzip p7zip-full lrzsz \
bash-completion tmux \
htop iotop iftop sysstat lsof strace ncdu \
ripgrep fd-find jq tree \
fail2ban ufw
# ---------- 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 调整关键项(保留其它已有配置)
# 注意:PasswordAuthentication 默认保持 yes,确保首次也能密码登录;
# 验证密钥可用后,再按"完成提示"改为 no
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 ssh >/dev/null 2>&1 || warn "ssh 服务启动失败,请检查 systemd"
else
warn "WSL2 环境:未启用 systemd 时 systemctl 不可用,请按 5.6.8.11 节启用后再重启"
fi
# 校验配置(错误则不重启,避免失联)
if command -v sshd >/dev/null 2>&1; then
sshd -t && log "sshd_config 语法校验通过" || err "sshd_config 语法错误,请检查 $SSHD_CFG"
fi
# ---------- 4. 防火墙(对应 6.1) ----------
log "[4/9] 配置 ufw 防火墙"
if [[ $IS_WSL -eq 0 ]]; then
ufw default deny incoming >/dev/null
ufw default allow outgoing >/dev/null
ufw allow 22/tcp comment "SSH" >/dev/null
# 用 yes 自动应答交互
echo "y" | ufw enable >/dev/null 2>&1 || true
log "ufw 已启用(仅放行 22/tcp)"
else
warn "WSL2 环境:ufw 需先切 nftables 后端才能用,详见 5.6.8.13 节"
fi
# ---------- 5. fail2ban(对应 6.2) ----------
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 = ufw
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
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. 时区与时间同步(对应 4.3) ----------
log "[6/9] 配置时区与时间同步"
timedatectl set-timezone Asia/Shanghai
if [[ $IS_WSL -eq 0 ]]; then
systemctl enable --now systemd-timesyncd >/dev/null 2>&1 || true
fi
log "当前时区:$(timedatectl | grep 'Time zone' | awk '{print $3}')"
# ---------- 7. 文件描述符限制(对应 6.3) ----------
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-ubuntu.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.4) ----------
log "[8/9] 配置内核参数调优"
SYSCTL_FILE=/etc/sysctl.d/99-tuning.conf
if [[ ! -f $SYSCTL_FILE ]]; then
cat > "$SYSCTL_FILE" <<'EOF'
# === Added by init-ubuntu.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 "------------------------------------------------"
💡 文档维护提示:
- 上述所有配置均在 Ubuntu 24.04 LTS 实测通过。
- Ubuntu 20.04 大部分兼容,仅 Netplan 语法、
nmtui行为略有差异。- Ubuntu 24.04 发布后请关注 systemd 变更,可能影响部分服务配置。

浙公网安备 33010602011771号