Windows: Softwares and Configurations
自己的 Windows 日用配置。不时更新。
Scoop
对于习惯了命令行工具的用户,我推荐使用 Scoop 软件包管理器在 Windows 下安装常用命令行小工具。
WSL2 相关
安装并启用 WSL2 参考 Microsoft Docs。以下假定 WSL2 的发行版是 Ubuntu 20.04.
我的 WSL2 采用了与自己大部分 Linux 服务器相同的一套 dotfiles,共享在 GitHub 上。
效果图:
SSH Server and Port Forward
现阶段固定 WSL2 的 IP 地址比较麻烦(讨论),但可以使用 PowerShell 脚本来自动获取 WSL2 的 IP 并将特定的端口转发到 Host (也就是 Windows)的对应端口。以转发 SSH 端口为例:
先安装 SSH Server:
sudo apt install ssh
sudo vim /etc/ssh/sshd_config
修改 SSH 配置文件,假设端口改为非标准端口 2222:
# /etc/ssh/sshd_config
Port 2222
# Other configurations...
启动 SSH Server:
sudo service ssh start
下载(或创建)此脚本,并在 Windows 的 PowerShell 中运行,可将 WSL2 的 2222 端口转发到 Windows Host 的 2222 端口。最后,如果有在外部访问的需求,记得在 Windows Firewall 设置中允许 2222 端口的访问。
ssh-agent and keychain
Note: YubiKey 等智能卡用户可跳过此小节,并前往 GPG Bridge 小节。
WSL2 中 ssh-agent
并不好用,为了避免每次使用 SSH Key 时都要手动输入 Passphrase,可以安装 keychain
来解决:
sudo apt install keychain
然后在 .zshrc
中加入:
if (( $+commands[keychain] )); then
keychain -q --nogui $HOME/.ssh/id_ed25519
source $HOME/.keychain/$HOST-sh
fi
之后每次开机只需输入一次 SSH Private 的 Key 的 Passphrase 即可。
Windows Terminal
这里有一个 Windows Terminal 配置文件的简单的例子,可以自行参考取用全部或其中部分设置。注意该配置文件中引用了几个壁纸和图标文件,它们的路径是
ms-appdata:///roaming/...
开头的,对于 Windows Terminal 来说,这个路径对应的实际文件夹位置是:
%USERPROFILE%\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\RoamingState\
如果想换用自己的图标或壁纸,把相应的图片文件放置在这个目录下即可。当然,在 settings.json
中,我们实际上可以用绝对路径引用电脑上任意地方的图片文件。
另外,我对 PowerShell 和 WSL2 中的 Shell(默认是 bash,但我改成了 zsh)均进行了一定程度的配置,配置文件不长,可供参考。
PowerShell
先自行安装新版 PowerShell,目前版本是 7.x。Windows 自带的是 5.x,缺少一些特性。
然后安装如下 Modules:
Install-Module -Name posh-git
Install-Module -Name oh-my-posh
Install-Module -Name PSReadLine
PowerShell 的配置文件目录是 %USERPROFILE%\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
,这里有一个非常简短的例子。
效果图:
SSH over Socks5 Proxy
由于某些原因,我的办公网络使用了白名单策略,只允许用户访问外界特定的常见端口(如 22、80、443 等),其它端口一律 Deny by default。我的 VPS 使用非标准 SSH 端口,因此默认情况下我无法在办公网络中直接 SSH 登录自己的 VPS。
假定我们在本文开头配置好的 Clash for Windows 中使用的代理节点在这样的白名单网络环境下是可用的(例如,与代理服务器建立隧道时使用了 HTTP2 类型的传输方式,这种情况对于网管而言与访问一个普通的 HTTPS 网页没什么区别),则可借助这个代理访问非标准 SSH 端口的 VPS。
在 macOS/Linux 下我们使用 nc
,如下是 ~/.ssh/config
中某个 Host 的配置示例:
Host g
Hostname g.xxxx.com
User my_username
Port 12345
ForwardAgent yes
ServerAliveInterval 10
ProxyCommand nc -X 5 -x 127.0.0.1:1080 %h %p
而在 Windows 下则使用 ncat
。首先下载 ncat
并安装,或者将其路径添加到 %PATH%
中。%HOME%/.ssh/config
配置文件中的 ProxyCommand
语法也要稍作调整,如下:
Host g
Hostname g.xxxx.com
User my_username
Port 12345
ForwardAgent yes
ServerAliveInterval 10
ProxyCommand ncat --proxy-type socks5 --proxy 127.0.0.1:1080 %h %p
SSH-Agent
Windows 自带一个 OpenSSH 服务及 ssh-agent
,可参阅 Microsoft 的文档。简单而言,在 services.msc
中将名为 OpenSSH Authentication Agent
服务启动(并设置为自动启动)即可。
GPG Bridge
本小节描述 YubiKey(或其他 GPG 智能卡,下同)用户可用的 SSH/GPG 解决方案。此方案可实现:
- 使用 YubiKey 中存储的 GPG subkeys 执行各种 GPG 操作。
- 使用 YubiKey 中存储的 Authentication subkey 执行 SSH 登录。
- 上述两项功能不仅可以在 Windows 中使用,也可以在 WSL2 中使用,亦可被 SSH 转发至远端服务器,即:SSH 登录远端服务器后,不需要在服务器上存储私钥,在服务器端可以直接使用本地 YubiKey 中存储的 subkeys 执行 GPG 和 SSH 操作。
- 上述两项功能仅要求 YubiKey 中至少存储了一个 GPG Authentication subkey (如果需要使用 GPG 签名、加密等功能,当然也要有对应功能的 subkey),不需要在本地电脑硬盘中、更不需要在远端服务器中存储任何 GPG/SSH 私钥,密钥管理方便且非常安全。也很适用于办公电脑等个人拥有一定使用权限,但不是非常私密的电脑设备。
注: 本节的方案与 WSL2 中的 keychain、 Windows 的 OpenSSH Agent 冲突或功能重复。如果采用本节的方案,最好不要在 WSL 2 中使用 keychain,也不要在 Windows 服务中开启 OpenSSH Agent。
1. Windows 中的 GPG/SSH 方案
前置条件当然是安装 Gpg4win —— 理论上读者可以自行选择 Windows 的 GPG 软件包,但这里直接使用 Gpg4win 是比较省事的选择。
安装(可能需要 Rust) gpg-bridge 并根据其使用说明书,(1) 将 Windows 下 GnuPG 的 extra socket 转发至一个本地 TCP 端口,(2) 将 GnuPG Agent 用作 SSH Agent。这两项操作可以使用一条命令完成:
~/.cargo/bin/gpg-bridge --extra 127.0.0.1:4321 --ssh \\.\pipe\gpg-bridge-ssh
前提是 Windows 中的 gpg-agent.conf
中启用了 enable-putty-support
。 之后在 Windows 中将环境变量 SSH_AUTH_SOCK
的值设置为 \\.\pipe\gpg-bridge-ssh
。
之后在 PowerShell 中可以运行
ssh-add -l
# sample output:
# 4096 SHA256:1234567890asdfghjklASDFGHJKL cardno:1 234 567 (RSA)
如果输出形似上述样例,例如有 cardno
字样,则说明成功读取了 YubiKey 中的 GPG Authentication subkey 作为 SSH Key。
Forward SSH Agent and GPG Agent over SSH
在 SSH Client 的 config 文件(.ssh/config
) 中,对于某个 Host:
Host g
Hostname g.xxxx.com
User my_username
Port 12345
ForwardAgent yes
ServerAliveInterval 10
ProxyCommand nc -X 5 -x 127.0.0.1:1080 %h %p
RemoteForward /run/user/1000/gnupg/S.gpg-agent 127.0.0.1:4321
其中 ForwardAgent yes
是转发 SSH Agent 到远端,而最后一行 RemoteForward ...
则是转发 GPG Agent 到远端。前者没什么难度,而要成功实现后者,则需要稍微了解一些操作要点 —— 这里有一份在类 UNIX 系统下的文档。RemoteForward 的语法是:
RemoteForward <socket_on_remote_box> <extra_socket_on_local_box>
这里 Local 环境是 Windows + Gpg4win,直接写 socket 路径不好使,我们换成经 gpg-bridge 转发的 127.0.0.1:4321
即可。
2. WSL 2 中的 GPG/SSH 方案
借助 wsl2-ssh-pageant 项目,我们可以把 Windows 的 SSH_AUTH_SOCK
和 GPG_AGENT_SOCK
两个 Socket 都转发到 WSL2 里面去。假设我们已经完成上一小节「Windows 中的 GPG/SSH 方案」中的全部步骤。将两个 Sockets 转发到 WSL 2 中的方法:
先安装 socat
并下载 wsl2-ssh-pageant:
sudo apt install socat
destination="$HOME/.ssh/wsl2-ssh-pageant.exe"
wget -O "$destination" "https://github.com/BlackReloaded/wsl2-ssh-pageant/releases/latest/download/wsl2-ssh-pageant.exe"
# Set the executable bit.
chmod +x "$destination"
然后在 .zshrc
中添加:
UNAME=`uname -a`
if (( $UNAME[(I)WSL2] )); then
# GPG Socket
# Removing Linux GPG Agent socket and replacing it by link to wsl2-ssh-pageant GPG socket
export GPG_AGENT_SOCK=$HOME/.gnupg/S.gpg-agent
ss -a | grep -q $GPG_AGENT_SOCK
if [ $? -ne 0 ]; then
rm -rf $GPG_AGENT_SOCK
setsid nohup socat UNIX-LISTEN:$GPG_AGENT_SOCK,fork EXEC:"$HOME/.ssh/wsl2-ssh-pageant.exe --gpg S.gpg-agent" &>/dev/null &
fi
# SSH Socket
# Removing Linux SSH socket and replacing it by link to wsl2-ssh-pageant socket
export SSH_AUTH_SOCK=$HOME/.ssh/agent.sock
ss -a | grep -q $SSH_AUTH_SOCK
if [ $? -ne 0 ]; then
rm -f $SSH_AUTH_SOCK
setsid nohup socat UNIX-LISTEN:$SSH_AUTH_SOCK,fork EXEC:$HOME/.ssh/wsl2-ssh-pageant.exe &>/dev/null &
fi
fi
我加了一个 uname -a
是否包含 WSL2
字串的判断,因为我的 .zshrc
配置会用在各种不同的 Linux 系统中,只有在 WSL2 中这段转发配置才会生效。
DNS over HTTPS
按:在中国内地单独使用 DNS over HTTPS (DoH) 看上去意义不大;另一方面,主流的浏览器如 Firefox、Google Chrome 及 Microsoft Edge 均已支持在浏览器内部设置 DoH。但这里还是提供一种启用本地 DoH Server 的方案以备不时之需。使用 Cloudflared 客户端。
首先下载 cloudflared 程序。Windows 版本只有一个可执行文件。
创建 %USERPROFILE%\.cloudflared\config.yaml
文件,并填入以下内容(可以根据自己的需求调整):
proxy-dns: true
proxy-dns-port: 5553
proxy-dns-upstream:
- https://1.1.1.1/dns-query
- https://dns.google/dns-query
- https://1.0.0.1/dns-query
之后直接以普通用户身份运行 <path-to-cloudflared>\cloudflared.exe
即可启动本地 DoH client,监听 5553
端口。
如果需要将 Cloudflared 安装为服务并后台运行,可以 Administrator 身份运行 Windows Terminal/PowerShell,并执行
<path-to-cloudflared>\cloudflared.exe service install
但此时安装的 Cloudflared Service 只会读取 C:\Windows\system32\config\systemprofile\.cloudflared\config.yml
这个位置的配置文件,而不会读取上述 %USERPROFILE%\.cloudflared\config.yaml
文件。一种方法当然是手动创建该系统配置文件;但如果不想自己手动在 C:\Windows\system32\
下面乱放东西,也可以修改注册表
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Cloudflared\ImagePath
给 Cloudfared 服务加上 --config <path-to-config>
参数。文档在此。
服务安装好后,可以在 Task Manager (任务管理器)的 Services 选项卡中控制 Cloudflared 服务的启动与停止。
Hugo
Hugo 是一个单 exe
程序,在其 Release 页面 下载后放置在自己习惯的位置(我经常放在 %USERPROFILE%\Prog
中,如果希望更好地遵循 Windows 的 Convention,可以考虑放置在 %LOCALAPPDATA%\Programs
中),最后记得将其目录添加至 %PATH%
.
开始用 Scoop 管理小型命令行工具软件后,直接 scoop install hugo
就行了,省事多了。
C++
目前(截至 2021 年)C++ 的生态环境比较丰富(复杂),不同的项目可能用着非常不同的项目管理工具、生成工具链等,很多用有限的篇幅概括。对于「大一编程课」级别的 C++ 环境配置,其实随便什么网上的教程基本都可以满足需求,甚至对于单文件编程,在 WSL 里 sudo apt install build-essential
,用 g++
就可以搞定大部分任务了。
而更大的 C++ 项目通常会使用 IDE 及某些 build system。一般安装一个 Visual Studio / JetBrains CLion 等大型 IDE 就可以了。如果想要兼顾「偶尔用轻量文本编辑器编辑」与「一定的多文件项目管理及语义检查能力」,可以考虑 VS Code / Sublime Text 配合 LSP 及 clangd。