手动下载 + 离线安装
步骤 1:启用 WSL 和虚拟机平台功能(无需联网)
以管理员身份打开 PowerShell,执行:
# 启用 WSL 功能
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
# 启用虚拟机平台(WSL2 必需)
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
⚠️ 执行后必须重启计算机。
步骤 2:手动下载并安装 WSL2 内核更新包
https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi
步骤 3:设置 WSL2 为默认版本
重启后,打开 PowerShell(普通用户权限):
wsl --set-default-version 2
步骤 4:手动安装 Linux 发行版到 D 盘(避免 C 盘占用)
从ubuntu官网下载,清华源已失效:https://cloud-images.ubuntu.com/wsl/releases/24.04/20240423/ubuntu-noble-wsl-amd64-24.04lts.rootfs.tar.gz
wsl --import Ubuntu D:\wsl-distros\Ubuntu D:\ubuntu-noble-wsl-amd64-24.04lts.rootfs.tar.gz --version 2
首次启动并创建用户:
adduser yourname
usermod -aG sudo yourname
echo -e "[user]\ndefault = yourname" > /etc/wsl.conf
退出后执行:
wsl --terminate Ubuntu
wsl -d Ubuntu
步骤5: 替换源
sudo tee /etc/apt/sources.list.d/ubuntu.sources > /dev/null << 'EOF'
Types: deb
URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu
Suites: noble noble-updates noble-backports
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
# Types: deb-src
# URIs: https://mirrors.tuna.tsinghua.edu.cn/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://security.ubuntu.com/ubuntu/
Suites: noble-security
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
# Types: deb-src
# URIs: http://security.ubuntu.com/ubuntu/
# Suites: noble-security
# Components: main restricted universe multiverse
# Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
# 预发布软件源,不建议启用
# Types: deb
# URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu
# Suites: noble-proposed
# Components: main restricted universe multiverse
# Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
# # Types: deb-src
# # URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu
# # Suites: noble-proposed
# # Components: main restricted universe multiverse
# # Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
EOF
可选:一键设置代理
#!/bin/bash
# WSL2 代理管理脚本 - 带详细调试日志
# 用法: source ~/bin/proxy-debug.sh && proxy-on
set -euo pipefail # 严格模式:出错立即退出
# ==================== 调试日志函数 ====================
LOG_LEVEL=${LOG_LEVEL:-2} # 0=静默, 1=错误, 2=常规, 3=详细
log() {
local level=$1; shift
local msg="$*"
local prefix=""
case $level in
1) prefix="❌ ERROR" ;;
2) prefix="ℹ️ INFO" ;;
3) prefix="🔍 DEBUG" ;;
*) prefix="💬 LOG" ;;
esac
if [ $level -le $LOG_LEVEL ]; then
echo "[$(date +'%H:%M:%S')] $prefix: $msg" >&2
fi
}
# ==================== 核心函数(带超时保护) ====================
get_windows_host_ip() {
log 2 "→ 步骤1: 获取 Windows 主机 IP"
# 检查 /etc/resolv.conf 是否可读
if ! timeout 2 test -r /etc/resolv.conf 2>/dev/null; then
log 1 "/etc/resolv.conf 不可读或锁定,尝试修复..."
sudo chattr -i /etc/resolv.conf 2>/dev/null || true
sleep 0.5
fi
# 方法1: 从 resolv.conf 读取
log 3 "尝试从 /etc/resolv.conf 读取 nameserver"
local ip=""
if ip=$(timeout 3 grep -m1 '^nameserver' /etc/resolv.conf 2>/dev/null | awk '{print $2}' | head -1); then
log 3 "原始 IP: '$ip'"
# 验证 IP 格式
if [[ -n "$ip" && "$ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ && "$ip" != "127.0.0.53" ]]; then
log 2 "✓ 成功获取 Windows IP: $ip"
echo "$ip"
return 0
else
log 3 "IP 格式无效或为 127.0.0.53,尝试备用方案"
fi
else
log 3 "grep 超时或失败"
fi
# 方法2: 尝试 host.docker.internal
log 3 "尝试从 host.docker.internal 获取 IP"
if command -v getent >/dev/null 2>&1; then
if ip=$(timeout 3 getent hosts host.docker.internal 2>/dev/null | awk '{print $1}' | head -1); then
if [[ -n "$ip" && "$ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
log 2 "✓ 通过 host.docker.internal 获取 IP: $ip"
echo "$ip"
return 0
fi
fi
fi
log 1 "❌ 无法获取 Windows 主机 IP"
log 1 "诊断信息:"
log 1 " - /etc/resolv.conf 内容:"
cat /etc/resolv.conf 2>/dev/null | head -5 | sed 's/^/ /' >&2 || echo " ❌ 无法读取" >&2
log 1 " - 当前网络接口:"
ip addr show eth0 2>/dev/null | grep "inet " | sed 's/^/ /' >&2 || echo " ❌ 无 eth0 接口" >&2
return 1
}
# ==================== 代理配置(关键:避免 sudo 卡住) ====================
proxy-on() {
log 2 "=== 启动 proxy-on (PID: $$) ==="
# 检查 sudo 是否需要密码(提前提示)
log 2 "→ 检查 sudo 权限..."
if ! timeout 3 sudo -n true 2>/dev/null; then
log 1 "⚠️ sudo 需要密码!请在下方输入密码(输入时无回显):"
if ! timeout 15 sudo -v 2>/dev/null; then
log 1 "❌ sudo 密码验证超时或失败,退出"
return 1
fi
log 2 "✓ sudo 权限已获取"
else
log 2 "✓ sudo 无需密码(已缓存)"
fi
# 获取 Windows IP
local WIN_IP=""
if ! WIN_IP=$(get_windows_host_ip); then
log 1 "❌ 获取 Windows IP 失败,终止配置"
return 1
fi
local PORT=${PROXY_PORT:-7890}
log 2 "→ Windows 代理地址: $WIN_IP:$PORT"
# 设置环境变量
log 2 "→ 配置环境变量..."
export http_proxy="http://$WIN_IP:$PORT"
export https_proxy="http://$WIN_IP:$PORT"
export HTTP_PROXY="http://$WIN_IP:$PORT"
export HTTPS_PROXY="http://$WIN_IP:$PORT"
export all_proxy="socks5://$WIN_IP:$PORT"
export ALL_PROXY="socks5://$WIN_IP:$PORT"
export no_proxy="localhost,127.0.0.1,::1,.local,.internal,$WIN_IP"
export NO_PROXY="localhost,127.0.0.1,::1,.local,.internal,$WIN_IP"
log 2 "✓ 环境变量已设置"
# 配置 APT(最可能卡住的 sudo 操作)
log 2 "→ 配置 APT 代理..."
if command -v apt >/dev/null 2>&1; then
log 3 "执行: sudo mkdir -p /etc/apt/apt.conf.d"
if ! timeout 5 sudo mkdir -p /etc/apt/apt.conf.d 2>/dev/null; then
log 1 "❌ sudo mkdir 超时,可能卡在密码输入"
return 1
fi
log 3 "写入代理配置到 /etc/apt/apt.conf.d/80proxy"
cat <<EOF | timeout 5 sudo tee /etc/apt/apt.conf.d/80proxy > /dev/null
Acquire::http::Proxy "$http_proxy";
Acquire::https::Proxy "$https_proxy";
EOF
log 2 "✓ APT 代理配置完成"
else
log 3 "⚠️ apt 未安装,跳过"
fi
# 配置 Git(非阻塞)
if command -v git >/dev/null 2>&1; then
log 2 "→ 配置 Git 代理..."
git config --global http.proxy "$http_proxy" 2>/dev/null || log 3 "⚠️ Git http.proxy 配置失败"
git config --global https.proxy "$https_proxy" 2>/dev/null || log 3 "⚠️ Git https.proxy 配置失败"
log 2 "✓ Git 代理配置完成"
else
log 3 "⚠️ git 未安装,跳过"
fi
# 配置 NPM(非阻塞)
if command -v npm >/dev/null 2>&1; then
log 2 "→ 配置 NPM 代理..."
npm config set proxy "$http_proxy" 2>/dev/null || log 3 "⚠️ NPM proxy 配置失败"
npm config set https-proxy "$https_proxy" 2>/dev/null || log 3 "⚠️ NPM https-proxy 配置失败"
log 2 "✓ NPM 代理配置完成"
else
log 3 "⚠️ npm 未安装,跳过"
fi
# 跳过 Docker 检测(易卡住)
log 3 "⚠️ 跳过 Docker 检测(避免 docker info 阻塞)"
log 2 "=== proxy-on 执行完成 ==="
echo ""
echo "✅ 代理已启用: $http_proxy"
echo "💡 提示: 确保 Windows 代理软件已开启【允许局域网连接】"
}
# ==================== 快速诊断命令 ====================
proxy-diagnose() {
echo "=========================================="
echo "WSL2 代理环境诊断报告"
echo "生成时间: $(date)"
echo "=========================================="
echo ""
echo "1. /etc/resolv.conf 状态:"
echo "------------------------------------------"
ls -la /etc/resolv.conf 2>&1 || echo "❌ 无法访问"
echo ""
cat /etc/resolv.conf 2>&1 | head -10 || echo "❌ 无法读取内容"
echo ""
echo "2. Windows 主机 IP 检测:"
echo "------------------------------------------"
grep -m1 nameserver /etc/resolv.conf 2>&1 || echo "❌ 未找到 nameserver"
echo ""
echo "3. 网络连通性测试:"
echo "------------------------------------------"
ip addr show eth0 2>&1 | grep "inet " || echo "❌ 无 eth0 接口"
echo ""
echo "4. sudo 权限检测:"
echo "------------------------------------------"
if sudo -n true 2>/dev/null; then
echo "✓ sudo 无需密码(已缓存)"
else
echo "⚠️ sudo 需要密码(可能卡住脚本)"
fi
echo ""
echo "5. 代理端口可达性测试 (7890):"
echo "------------------------------------------"
local win_ip=$(grep -m1 nameserver /etc/resolv.conf | awk '{print $2}' 2>/dev/null)
if [[ -n "$win_ip" && "$win_ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Windows IP: $win_ip"
timeout 3 bash -c "echo > /dev/tcp/$win_ip/7890" 2>&1 && echo "✓ 端口可达" || echo "❌ 端口不可达"
else
echo "❌ 无法获取有效 Windows IP"
fi
echo ""
echo "=========================================="
echo "常见问题解决方案:"
echo "------------------------------------------"
echo "❌ 问题1: 脚本卡在 sudo"
echo " → 方案: 执行 'sudo -v' 提前输入密码,或配置免密:"
echo " echo '$(whoami) ALL=(ALL) NOPASSWD:ALL' | sudo tee /etc/sudoers.d/wsl-proxy"
echo ""
echo "❌ 问题2: /etc/resolv.conf 被锁定"
echo " → 方案: sudo chattr -i /etc/resolv.conf"
echo ""
echo "❌ 问题3: 无法获取 Windows IP"
echo " → 方案: 重启 WSL (Windows PowerShell: wsl --shutdown)"
echo "=========================================="
}
# 快捷命令
alias po="proxy-on"
alias pd="proxy-diagnose"
log 2 "✅ 调试版代理脚本已加载"
log 2 "可用命令: proxy-on (po) | proxy-diagnose (pd)"
- 保存脚本并赋予执行权限
mkdir -p ~/bin
cat > ~/bin/proxy.sh << 'EOF'
# 粘贴上方完整脚本内容
EOF
chmod +x ~/bin/proxy.sh
- 永久生效(添加到 ~/.bashrc)
echo -e "\n# WSL2 代理管理" >> ~/.bashrc
echo 'source ~/bin/proxy.sh' >> ~/.bashrc
source ~/.bashrc
- 一键启用代理
proxy-on
# 或简写
po