📅⏱️6 分钟阅读
本文是一份详尽的 Windows 远程开发环境搭建指南。作者分享了从远程开机(智能插座+来电启动)、网络组建(使用 Tailscale 并自建 DERP 服务器优化连接)、远程桌面方案选型,到最终开发环境配置(基于 WSL2、Podman 和 OpenSSH)的全过程。文章还深入探讨了如何解决 Hyper-V 端口占用等常见问题,并实现了通过 SSH 直连 WSL 的无缝开发体验。

前言

一直以来我都是带台式电脑去学校,去年趁着国补买了台 MacbookAir,又遇宿舍搬迁等事宜,让我深深感到了东西多是有多难搬。

本文作为搭建 Windows 远程开发环境的记录。

需要解决的问题

搭建远程开发环境主要需要解决如下问题:

  • 设备开机
  • 网络
  • 远程桌面方案
  • 开发环境搭建

设备开机

设备开机主要用两种解决方案,WOL 和 来电启动。

WOL(Wake-On-LAN)主要是通过局域网设备发送 Magic Packet 来启动设备,同时还需要设备支持 WOL 功能(一些较老的主板不支持 WOL 功能)和保持电源的连接。

来电启动(AC Power Loss Recovery/Restore on AC Power Loss)主要是通过智能插座来实现远程控制设备的断电、上电来启动设备。

这里主要使用 小米智能插座 结合 来电启动 来控制设备的开机。

注:WOL和来电启动都需要在 BIOS 中设置

网络

设备网络环境

网络中国电信
下行300M
上行40M
路由器自编译 ImmortalWrt 23.05
IPv4公网+Full Cone NAT
IPv6开启

家中网络为中国电信 300M下行 + 40M上行,使用软路由进行拨号,软路由搭载自己编译的 ImmortalWrt(OpenWrt variant),开启 IPv6,同时具有公网 IPv4。

组网

组网软件使用 Tailscale 同时购买阿里云境内服务器自建 DERP 服务器。

DERP 搭建

DERP(Designated Encrypted Relay for Packets,指定加密中继服务器)服务器用于管理设备连接和 NAT 穿透。它们有两个主要用途:协商 tailnet 设备之间的直接连接,以及在无法建立直接连接时作为中继服务器。

DERP 服务实际上运行的是 HTTP 协议,默认的端口为 443,需要配合域名和证书使用。

由于使用的是境内的服务器,如果不备案我们是无法通过域名访问 HTTP 协议的,所以我们只能通过修改默认端口同时通过 IP 直连才可以访问。

  1. 使用 openssl 自签证书,DERP_IP 修改为自己的服务器 IP
    Shell
    DERP_IP="x.x.x.x"
    openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes -keyout ${DERP_IP}.key -out ${DERP_IP}.crt -subj "/CN=${DERP_IP}" -addext "subjectAltName=IP:${DERP_IP}"
  2. 将证书移动到相对 docker-compose.yml 的相对目录 ./certs ,使用 Docker Compose 一键搭建 DERP 服务
    Yaml
    version: "3.8"
    
    services:
      derper:
        image: fredliang/derper
        container_name: derper
        restart: always
        volumes:
           - ./certs:/app/certs:ro
        environment:
          - DERP_DOMAIN=x.x.x.x
          - DERP_HTTP_PORT=-1
          - DERP_ADDR=:23333
          - DERP_CERT_MODE=manual
        ports:
          - 23333:23333
          - 3478:3478
  3. 在 Tailscale ACL 页面禁用默认 DERP 服务器,同时添加自建服务器。
    Json
    {
    	"derpMap": {
    		"OmitDefaultRegions": true, // 禁用默认 DERP 服务器
    		"Regions": {
    			"900": {
    				"RegionID": 900,
    				"RegionCode": "can", // 服务器代码
    				"RegionName": "AliYun", // 服务器名字
    				"Nodes": [
    					{
    						"Name": "1",
    						"RegionID": 900,
    						"HostName": "example", // 由于没有使用域名,这里随便填无法解析的域名
    						"IPv4": "x.x.x.x",
    						"DERPPort": 23333, // DERP 端口
    						"InsecureForTests": true // 因为是自签证书,所以要开启 Insecure
    					}
    				]
    			}
    		}
    	}
    }
  4. 配置完成后使用 tailscale netcheck 进行测试
    Image

打洞优化

使用 tailscale status 可以查看设备的网络连接状态,最理想的状态就是打洞成功的 direct 状态,如果遇到一直是使用 DERP 服务器的 relay 状态则需要排查原因。

Tailscale 默认监听 41641 端口进行打洞,如果有公网 IPv4 可以尝试开启 NAT-PMP 或者手动允许 41641 端口的入站。

如果没有公网 IPv4 则可以尝试使用 随机端口 等操作,详细如下:

Using Tailscale with your firewall · Tailscale Docs
Use Tailscale with an existing firewall configuration.
tailscale.com

速度测试

图:中国联通流量IPv6直连成功 NAS速度测试
图:中国联通流量IPv6直连成功 NAS速度测试

远程桌面方案

用 Windows 系统搭建开发环境肯定离不开远程桌面。远程桌面方案根据原理不同可以分类为 RDP 和 其他、还可以分为 开源 和 闭源商业。

下面是一些常见的远程桌面方案:

方案核心原理游戏支持开源/闭源是否收费
Windows RDP远程渲染不推荐,以远程办公为主闭源免费
RustDesk视频串流不推荐,以远程办公为主开源免费
Sunshine视频串流支持开源免费
ToDesk视频串流支持但需付费闭源免费、部分功能收费
网易UU远程视频串流支持闭源免费
Parsec视频串流支持闭源免费、部分功能收费

这里主要使用 Windows RDP 和 RustDesk 作为远程桌面方案。如果需要游戏串流可以使用 Sunshine 或者 网易UU远程。

在远程桌面方案中,Windows RDP 凭借远程渲染而非视频串流的技术是不可或缺的存在。

开发环境搭建

虽然是在 Windows 下面搭建开发环境,但是 Linux 也是不可或缺的,这里基于 WSL2 来搭建 Linux 的开发环境。

主要是需要安装/开启这些功能:

  • Hyper-V
  • WSL2
  • Podman
  • OpenSSH

其中 Podman 依赖 WSL2 依赖 HyperV。

开启 Hyper-V

在 “启用或关闭 Windows 功能” 勾选 “Hyper-V” 即可。

安装 WSL2

跟着微软官方教程安装即可。

Install WSL
Install Windows Subsystem for Linux with the command, wsl --install. Use a Bash terminal on your Windows machine run by your preferred Linux distribution - Ubuntu, Debian, SUSE, Kali, Fedora, Pengwin, Alpine, and more are available.
learn.microsoft.com

安装 Podman

安装包无脑点击下一步。

Podman
podman.io

Hyper-V 问题解决

Windows 10(安装了 Hyper-V)会自动随机保留部分端口用于容器宿主网络服务(详细请见https://zhuanlan.zhihu.com/p/474392069)。


如果 Windows 动态端口范围被设得过低(如1024起步),常用端口(如8088、8000、3000等)会被误占用,导致无法绑定。


使用命令 netsh int ipv4 show dynamicport tcp 可以查看目前「TCP 动态端口」的范围。

Image


使用 netsh int ipv4 show excludedportrange protocol=tcp 命令可以查看当前所有已经被征用了的端口。

Image

解决方法

  1. 以管理员权限运行以下命令,将动态端口范围设回标准的高位区间,避免影响常用端口:
    Powershell
    netsh int ipv4 set dynamic tcp start=49152 num=16384
    netsh int ipv6 set dynamic tcp start=49152 num=16384
  2. 重启电脑
  3. 验证:
    Powershell
    netsh int ipv4 show dynamicport tcp
    netsh int ipv6 show dynamicport tcp

    显示的范围应为49152-65535。

安装 Win32-OpenSSH

虽然我们可以直接通过远程桌面进行开发,但是这样过于臃肿了,我们可以直接通过 VsCode 的 RemoteSSH 插件连接远程服务器进行远程开发,且连接上后可以直接拥有在 Windows 本地开发的体验,能直接连接到 WSL 和 Podman 运行的容器,非常的方便。

实现这个功能我们只需要在 Windows 上安装 OpenSSH 服务,这里使用安装包直接进行安装。

Win32-OpenSSH 下载地址:https://github.com/PowerShell/Win32-OpenSSH/releases/

Image


Image


Image

安装完成 OpenSSH 后可以将电脑上的 SSH 公钥添加到 authorized_keys 中实现丝滑的远程连接。

WSL 安装 OpenSSH

至此,Windows 远程开发环境算是搭建完成了,不过如果只使用 Windows OpenSSH 会让我们访问 WSL 多一个步骤,这里我想要一个方案通过 SSH 连接上服务器就是 WSL。

实现也很简单,就是需要在 WSL 下安装 OpenSSH 服务,在 Ubuntu 下直接使用 apt install openssh-server 即可,同时要保证 WSL 配置 /etc/wsl.conf 开启 systemd ,通过 systemd 来管理 OpenSSH 服务的启动。

图:systemd 查看 sshd 服务运行状态
图:systemd 查看 sshd 服务运行状态


安装了 OpenSSH 服务还不够,我们还需要配置端口转发和 WSL 的开机启动。

我们使用 NSSM 来管理 Windows 的服务,由于 NSSM 只能运行 bat 脚本,所以我们还需要写一个 bat 脚本用于调用 ps1 脚本。

Powershell
# demo.ps1
$wslIP = wsl hostname -I | ForEach-Object { $_.Trim() }
# 删除原来的转发
netsh interface portproxy delete v4tov4 listenaddress=* listenport=22
# 配置端口转发,Windows:本机端口 -> WSL:22
netsh interface portproxy add v4tov4 listenaddress=* listenport=<本机端口> connectaddress=$wslIP connectport=22
# 启动 WSL
wsl -d Ubuntu

# demo.bat
# 这里使用的是 powershell 7,而不是 5.1
pwsh -ExecutionPolicy Bypass -NoProfile -File "demo.ps1"
Image
Image

注意 NSSM 的 Log on 需要配置管理员的账户,不能使用 Local System account。同时 Dependencies 需要添加 WSLService。

这样便完成了 WSL 端口转发与开机启动的配置。

总结

通过组网和开发环境搭建,完美的解决了远程开发的需求,外加远程桌面可以让我们控制电脑,串流游戏等等,非常的完美,暂时没有遇到缺点。

附录

WSL2 迁移存储目录

WSL2 默认将 Linux 发行版安装到C盘,迁移方法如下

  1. 导出
    Powershell
    wsl --export <发行版名> <目标路径>\backup.tar
  2. 注销原发行版
    Powershell
    wsl --unregister <发行版名>
  3. 导入到新目录
    Powershell
    wsl --import <新发行版名> <新目录> <tar包路径>