分类
wsl

WSL2 使用 ssh-server 笔记

升级到 WSL2 之后,我面临几个问题:

  • webpack-dev-server 无法监控 /mnt/c/xxxx 这样的路径下的文件变化,使得 HMR 失效。只能借由 ~/path/to/project/ 启动开发环境。
  • 启动服务后,无法通过 127.0.0.1:port/ 访问,只能通过 localhost:port 访问。

今天想使用 ssh-server 连上去,结果失败,经查,原来 WSL2 的底层逻辑变了:

If this is WSL2 (which it appears to be) this is for all intents by-design. WSL2 has its own Real Linux™ network stack inside a VM, and a virtual Ethernet device. Contrast WSL1 which took the approach of attempting to present the Windows network stack inside Linux.

WSL2 就是这么设计的。它在虚拟机里有自己真实的 Linux 网络栈,以及虚拟的以太网设备。

WSL2: ifconfig not showing all network connections · Issue #4915 · microsoft/WSL (github.com)

所以要用不同的方式来做,记录在这篇笔记里。

方案一:使用 ssh-server

1. 在 Windows 里安装 ssh-server

  1. 设置 > 应用 > 应用和功能 > 可选功能 > 添加功能
  2. 搜索并安装 ssh-sever
  3. 启动 ssh-server,需使用管理员身份启动 powershell
# 启动 ssh 服务
Start-Service sshd

# 可选,设置 sshd 为开机自动启动
Set-Service -Name sshd -StartupType 'Automatic'

# 往防火墙里添加规则
if (!(Get-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -ErrorAction SilentlyContinue | Select-Object Name, Enabled)) {
    Write-Output "Firewall Rule 'OpenSSH-Server-In-TCP' does not exist, creating it..."
    New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
} else {
    Write-Output "Firewall rule 'OpenSSH-Server-In-TCP' has been created and exists."
}

2. ssh 连接

在另外一台机器上输入 ssh username@ip-or-host 即可完成连接。

不过需要注意的是,比如我的账户名为 Meathill Zhai,这个名称不能直接使用。我的邮箱是 realmeathill[at]hotmail.com,系统会自动截取一段,我在命令行里的初始位置是:C:\Users\realm,于是登录的时候只能用 ssh realm@ip,然后输入 realmeathill[at]hotmail.com 的密码,方能完成登录。

3. 改为连接 WSL2

默认情况下,使用 ssh 连入的命令行是 cmd.exe,可以通过以下命令修改为 Powershell:

New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force

如果把里面的 WindowsPowerShell\v1.0\powershell.exe 修改为 bash.exe,那么就会连入 WSL2 了。

4. 改回 powershell

直接连入WSL2 也不是不行,不过这样的话,一些涉及 Windows 系统的操作无法进行,exit 也是直接退出 ssh 连接。于是我觉得默认连入 powershell 比较好,想用 WSL 就手动 bash 进入 WSL 即可。

待解决问题

  • powershell ssh-server 不支持 authorized_keys 登录

参考文章

分类
工具

Windows 10 配置 WSL2 以及图形界面

前阵子把台式机的 WSL 升级到了 WSL2,顺便配置好图形界面,写篇博客记录一下。

0. 卸载 WSL,开启 CPU 虚拟化功能

如果之前安装过 WSL,需要先备份重要数据,然后卸载,再安装 WSL2。

重启,在 BIOS 设置里开启 CPU 虚拟化支持。

1. 简单安装:利用 Windows Insider

加入 Windows Insider 计划,升级到预览版本(>=20262),直接安装。好处是方便,而且可以安装最新版本,可以访问 Linux 分区。

坏处是不太稳定,预览版嘛。我觉得不太放心,决定还是在稳定版上安装。

2. 手动在 Windows 10 标准版上安装

2.1 检查 Windows 10 版本

需 >= 1903(18362)。我每周更新,没有问题。

2.2 启动虚拟化支持

dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

2.3 下载 WSL2 升级包并安装

WSL2 Linux kernel update package for x64 machines

2.4 配置 WSL 默认版本为 2

# 设置 WSL 默认版本
wsl --set-default-version 2

# 列出所有 WSL 版本
wsl --list --verbose

# 将特定发行版设置为指定版本
wsl --set-version <distribution name> <versionNumber>  

2.5 在 Microsoft 商店里安装 Linux 发行版

我安装的是 Ubuntu 20.04。安装后需要进行一些配置工作,此处不再赘述。

至此,WSL2 配置完成,接下来配置图形界面。

3. 配置 WSL2 的图形界面

3.0 更新系统

按照惯例先把能更新的系统组件更新到最新:

sudo apt update
sudo apt upgrade

3.1 安装 GUI 组件

sudo apt install -y tasksel
sudo tasksel install xubuntu-desktop
sudo apt install gtk2-engines

WSL2 目前并不支持图形界面,所以这里计划让 Ubuntu 使用 Windows X-server 来绕过。安装的过程会比较久,因为要下载很多东西,请耐心等待。

3.2 配置显示器信息

接下来要配置显示器信息,方便 Linux 使用:

export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2; exit;}'):0.0
export LIBGL_ALWAYS_INDIRECT=1
sudo /etc/init.d/dbus start &> /dev/null

把上面这段配置加入 ~/.bashrc,当我们登入 WSL 时,就会自动完成配置。不过这样一来,每次登入都要敲密码,也有点麻烦,所以可以自己取舍一下。或者把上面的配置单独存放一个脚本文件,需要使用 GUI 的时候再运行启动。

3.3 在 Windows 10 安装 X-server

参考文档中推荐了两个软件:VcXsrv(免费)和 x410(收费)。我本来想花钱点,可是后者不支持国区购买,所以只好选用 VcXsrv。

下载,安装,启动 VcXsrv。接下来 VcXsrv 会要求我们配置使用方式,依次选择“Multiple Windows”、“Start no client”,并且勾选“Disable access control”,然后保存配置文件到本地,完成启动。以后可以通过双击配置文件启动 VcXsrv。

此时,在系统托盘里可以看到 VcXsrv 服务。

3.4 启动 GUI 程序

接下来正常启动 GUI 程序即可,比如 Firefox:

sudo apt install firefox

# 安装完成后,启动 firefox
# 注意,这里必须用 sudo
sudo firefox 

总结&参考文档

至此,安装配置完成。安装配置中我参考了以下文章:

遗留问题

涉及到硬盘操作的功能会非常慢,比如打开目录,到目录内容完全呈现出来,需要数分钟之久。我记得当年初用 WSL 的时候也遇到过这个问题,后来通过关闭安全扫描解决了,不知道这次是不是同样的问题。(这次没找到关闭安全扫描的位置……)