写在前面:为何回归 NAT 模式?
WSL2 全新的 networkingMode=mirrored
(镜像网络模式)在理论上提供了极大的便利,尤其是在 localhost
互通和局域网访问方面。然而,作为一项实验性功能,我在实践中遇到了许多难以排查的网络“坑”,尤其是在与 Docker 结合使用时,出现了连接被拒绝、代理不生效等一系列问题。
在花费大量时间排错后,我决定回归到 WSL2 久经考验的默认 NAT 模式。这种模式虽然需要一些手动配置,但其行为是可预测且极其稳定的。
本指南旨在为那些和我一样,选择从 mirrored
模式切换回 NAT 模式,或初次在 NAT 模式下配置代理的用户,提供一套完整、可靠的解决方案。本文将以在 Windows 主机上运行 Clash for Windows 代理程序为例,其默认端口为 7890
。
前置步骤:Windows 主机配置
在配置 WSL 之前,必须确保 Windows 主机本身已准备就绪。
1. 查找并固定主机局域网 IP
代理服务器的目标地址必须固定。
- 在 Windows PowerShell 或 CMD 中运行
ipconfig
。 - 在你的主网络适配器(如“以太网适配器”或“无线局域网适配器”)下找到
IPv4 地址
。 - 建议:在你的路由器管理后台,将此 IP 地址与你的电脑 MAC 地址进行绑定,以防止 IP 地址变动。
本文将以
192.168.0.100
作为示例主机 IP,以7890
作为 Clash for Windows 的代理端口。请在实际操作中替换为您自己的地址和端口。
2. 为代理端口添加入站防火墙规则
这是最关键的一步。默认情况下,Windows 防火墙可能会阻止来自 WSL(即使它在内部网络)对主机端口的访问,特别是当网络被识别为“公用(Public)”时。创建一个精确的“允许”规则是解决此问题的最佳实践。
- 在 Windows 搜索框中,输入“高级安全 Windows Defender 防火墙”并打开它。
- 在左侧面板中,点击“入站规则”。
- 在右侧“操作”面板中,点击“新建规则…”。
- 在向导中,按以下步骤操作:
- 规则类型:选择“端口”,点击“下一步”。
- 协议和端口:选择“TCP”,然后在“特定本地端口”中输入您的代理端口,例如
7890
。点击“下一步”。 - 操作:选择“允许连接”,点击“下一步”。
- 配置文件:全部勾选(“域”、“专用”、“公用”),以确保规则在任何网络环境下都生效。点击“下一步”。
- 名称:为规则起一个易于识别的名称,例如
Allow WSL Clash Proxy (TCP 7890)
。点击“完成”。
IMPORTANT
如果不执行此步骤,即使后续所有配置都正确,来自 WSL 和 Docker 的连接也大概率会被 Windows 防火墙丢弃或拒绝。
步骤一:为 WSL Shell 配置代理
此配置将影响您在 WSL 终端中直接使用的命令,如 apt
, curl
, git
, wget
等。
- 编辑 Shell 配置文件。根据您的 Shell 类型选择:
# 如果使用默认的 bash
nano ~/.bashrc
# 如果使用 zsh
nano ~/.zshrc
- 在文件末尾添加以下环境变量。我们同时添加小写和大写版本以获得最佳兼容性。
# Proxy Configuration for Clash for Windows
export http_proxy="http://192.168.0.100:7890"
export https_proxy="http://192.168.0.100:7890"
export no_proxy="localhost,127.0.0.1"
export HTTP_PROXY="http://192.168.0.100:7890"
export HTTPS_PROXY="http://192.168.0.100:7890"
export NO_PROXY="localhost,127.0.0.1"
- 应用配置。关闭并重开终端,或执行
source ~/.bashrc
(或source ~/.zshrc
)。
步骤二:为 Docker 环境配置代理
Docker 的代理配置分为两部分:守护进程(Daemon)和构建/运行环境(Build/Container)。
1. 配置 Docker 守护进程 (Daemon)
此配置主要影响 docker pull
, docker push
等与 Docker Hub 交互的命令。
NOTE
直接修改
/etc/docker/daemon.json
是一种方法,但通过systemd
的覆盖文件 (override) 是更推荐、更模块化的方式。
- 使用以下命令,通过一条指令直接创建并写入
systemd
覆盖文件,以避免vim
操作可能带来的问题。
sudo mkdir -p /etc/systemd/system/docker.service.d/
sudo tee /etc/systemd/system/docker.service.d/override.conf > /dev/null <<EOF
[Service]
Environment="HTTP_PROXY=http://192.168.0.100:7890"
Environment="HTTPS_PROXY=http://192.168.0.100:7890"
Environment="NO_PROXY=localhost,127.0.0.1"
EOF
- 应用配置并重启 Docker 服务。
# 重新加载 systemd 配置
sudo systemctl daemon-reload
# 重启 Docker 服务以加载新的环境变量
sudo systemctl restart docker
2. 配置 Docker 构建与运行环境
此配置影响 Dockerfile
中 RUN
指令(如 RUN apk add ...
)以及 docker run
启动的容器内部的网络访问。
- 修改
Dockerfile
在Dockerfile
的FROM
指令之后,使用ENV
指令明确设置代理环境变量。
FROM alpine:3.19
# 为构建过程设置代理
ENV HTTP_PROXY="http://192.168.0.100:7890"
ENV HTTPS_PROXY="http://192.168.0.100:7890"
ENV NO_PROXY="localhost,127.0.0.1"
# 现在 RUN 指令就可以通过代理下载软件包了
RUN apk update && apk add --no-cache curl git
# ... 其他指令 ...
- 为运行中的容器设置代理
如果需要在
docker run
启动的容器内部也使用代理,可以通过-e
参数传入环境变量。
docker run -it --rm \
-e HTTP_PROXY="http://192.168.0.100:7890" \
-e HTTPS_PROXY="http://192.168.0.100:7890" \
ubuntu:latest \
bash
遵循以上步骤,即可在 WSL2 的标准 NAT 模式下,为你的开发环境建立一套稳定代理配置。