USAGI NOTE | 核舟记

U酱收藏了一篇笔记,小兔报告说。 据小兔观察,主要的内容是: 跟Windows Server Core打架又和好的历程


酷Q,系Win32应用程序
在Linux,可以用Wine的容器来运行;
然而在Docker卡到开始影响原野之后
活性酱终于还是把它鲨掉了
想起来Azure有个闲置Windows服务器
不如看看怎么把它丢上去好了

因为酷Q在Linux跑的时候占用颇多
一来想要尽可能轻量的Windows镜像
二来上界星辰契合
就选中了[smalldisk] Windows Server 2019 Datacenter Server Core 好了,坑已经踩进去了,且听活性酱慢慢道来

初见

乘彼远程,以望桌面。不见桌面,泣涕涟涟 并没有

servercore-login

运行taskmgr,熟悉的窗口出现了
看了一下内存占用,初始只有0.8G
这个服务器核心,很 有料的样子

Server Core的东西(指坑)是真的不少,踩雷排雷的山路十八弯暂且按下不表 且看活性酱怎么起酷Q服务器,就能观其大略了

调 整 屋(有爱自取)

服务器核心登录后默认 其实看厂商心情,Azure就没有 会打开sconfig,里面有一些基本的配置项,也提供重启关机一类的功能。记着,以后写账要用

设定默认Shell为pwsh

返回命令行,是一个cmd。事已至此,使用功能丰富的Powershell是更好的选择,先用start powershell呼出一个,然后直接设定注册表:

Set-ItemProperty -Path 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion\WinLogon' -Name Shell -Value 'PowerShell.exe'

备注,Restart-Computer在远程电脑上经常会导致服务器再起不能,因此推荐用sconfig菜单来重启

创建空白的用户配置

New-item -type file -force $profile

“我的文档”里名为Microsoft.PowerShell_profile.ps1的文件,每次打开新的pwsh窗口都会执行里面的内容,跟Linux的.bashrc是等价的。

安装Chocolatey包管理器

只有命令行的情况下,正常安装程序的路线可累人了,而巧克力板可以救命
听说winget正在赶到的亚子(?)

Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

需要注意的是,如果在这之前没有建立用户配置文件,Chocolatey会失去TAB补全功能。

取消自带的wget别名

PowerShell 没安 好心把wgetcurl给别名到了Invoke-WebRequest。 桌面版倒勉强,但没有IE组件的服务器核心必须加上-UseBasicParsing才能用,那可真是活活的烦死,因此推荐choco install wget -y,然后写用户配置撤销掉默认别名:

# 判断结构防止返回异常
if (Test-Path alias:wget) {
  Remove-Item alias:wget
}
if (Test-Path alias:curl) {
  Remove-Item alias:curl
}

wget --content-disposition可以用于通过跳转获取真实文件名,就是有点长还不能补全

让Tab采用bash的补全方式

在用户配置里增加一行

Set-PSReadlineKeyHandler -Key Tab -Function Complete

调整时区

# 查看可用时区
Get-TimeZone -ListAvailable
# 调整时区
Set-TimeZone -id 'China Standard Time'

登录目录异常

如果登录后莫名其妙就跑到了C:\Windows\system32,要解决这个问题,可以在用户配置里添加:

if ($PWD = "C:\Windows\system32") { cd ~ }

修改默认输入法

开机当然要登录啦,但输入密码的时候蹦出微软拼音的输入框不是很怪么?
默认语言只有中文的时候会遇到这个毛病,需要先添加英文,然后设为默认

$LanguageList = Get-WinUserLanguageList
$LanguageList.Add("en-US")
Set-WinUserLanguageList $LanguageList
Set-WinDefaultInputMethodOverride "0409:00000409"

自动开启数字小键盘

要是进入系统NumLock没有自动打开的话……

Set-ItemProperty -Path 'Registry::HKU\.DEFAULT\Control Panel\Keyboard' -Name "InitialKeyboardIndicators" -Value "2"

Choco它慢死了

国内特色网络环境嘛——
如果已有HTTP代理可用,那么在安装choco时,预先定义变量就可以通过代理执行安装

$env:chocolateyProxyLocation = 'http://<host>:<port>'

而安装完成后,可用choco config set proxy http://<host>:<port> 来保存代理设定
再多提一句,如果是wget的话,使用wget -e https_proxy=http://<host>:<port>来设定代理

部署酷Q Pro服务

设置区域选项

如果系统语言是英文的话,中文会出现乱码。需要重启生效。

Set-WinSystemLocale -SystemLocale zh-CN

配置虚拟内存(1G以下必须)

因为没有计算机属性这个面板,需要用wmic来配置虚拟内存;
它也有交互模式,而且功能极其丰富,不过这里就不展开了,有心人可以自行查阅。

# 首先查看当前的分页文件列表
# 需要指出的是,配置被修改之后,这个命令不会立即反映出来,重启后才能看
wmic pagefile list

对于Azure的B1s来说,系统自动分配的虚拟内存是位于D盘(临时存储)的512M大小的pagefile.sys,显然是有些太小了。根据datasheet,B1s拥有4GB的临时存储,分个一半出来做虚拟内存还差不多

这里就要说到,wmic这个程序原先是面向命令提示符的,在PowerShell运行时,有些语法会犯冲。所以需要一点小把戏来解决:

# 将虚拟内存取消自动管理
wmic --% computersystem where name="%computername%" set AutomaticManagedPagefile=false
# 测试发现,改为手动管理时系统会自动创建C:\pagefile.sys的配置
# 但这不是我们想要的,因此将它删除
wmic --% pagefileset where name="C:\\pagefile.sys" delete
# 创建D:\pagefile.sys,create不要转义反斜杠,原因不明
wmic --% pagefileset create name="D:\pagefile.sys"
# 设定D:\pagefile的大小,这里选择初始分配1G,最大2G
wmic --% pagefileset where name="D:\\pagefile.sys" set InitialSize=1024,MaximumSize=2048

--%又名为stop-parsing symbol,能够通知Powershell停止对此命令执行展开;也可以选择直接在cmd里运行这些命令,修改完成之后用sconfig重启服务器生效。

安装App Compatibility Feature on Demand

这个可选包可以极大地增加服务器核心对一般GUI应用的兼容性。同时也能引入一些常用的管理工具(比如亲爱的explorer),酷Q需要这个可选包才能工作。
要安装也很简单(然而相当花时间),只要——

Wait!如果是在配置不高的云服务器上(点名批评Azure的B1s实例,也就是试用的1核1G那个),这条指令很容易导致内存溢出,虽然重启后再次执行一般是可以跑通的,但总觉得少了点consistency。所以最好还是先配置一下虚拟内存。然后就可以安全执行:

Add-WindowsCapability -Online -Name ServerCore.AppCompatibility~~~~0.0.1.0

after-fod

请坐和放宽,安装完成后重启服务器。
重启会进行多次,所以请多等一段时间再登录。

安装酷Q Pro主程序

下载地址是带跳转的HTTPS地址,所以需要加个参数:

# 有时需要--no-check-certificate,请关注提示
wget https://dlsec.cqp.me/cqp-full --content-disposition

得到的CQP.zip是简体中文编码,已经设置过区域选项的话,安装个unzip之类的就可以解压,喜欢用GUI的话推荐装bandizip(choco有售);解压到合适的路径后稍安勿躁,还有一些事情要做。

添加Windows Defender例外

defender-cqp

CQP.exe会被Defender直接杀掉,或者在自动更新时报错
可以添加路径例外,或者直接禁用实时扫描(资源紧张的话)

# 将路径添加到例外,注意不可以用"."代表当前目录
Add-MpPreference -ExclusionPath "X:\path\to\CQP"
# 或禁用Windows Defender的实时扫描
Set-MpPreference -DisableRealtimeMonitoring $true

安装Chrome

如果服务器位于国外,那么大概率会触发QQ的交互式验证码
酷Q能够自动拉起Chrome浏览器来显示验证码。安装也很简单:

choco install googlechrome -y

安装CQ HTTP插件

首先安装Visual C++ 可再发行软件包,然后将HTTP API的cpk文件放置在app目录下,重启酷Q;Pro版本还需要酷Q语音组件才能完全发挥HTTP API功能。详见CQHTTP 插件文档

  • Visual C++ 可再发行软件包 https://aka.ms/vs/16/release/vc_redist.x86.exe
  • CQ HTTP https://github.com/richardchien/coolq-http-api/releases
  • 语音组件 https://dlsec.cqp.me/cqc

安装Nginx服务

最简便的方案,就是choco install nginx
Choco会同时安装NSSM,并且建立nginx的服务。

安装路径在C:\tools\nginx-{version},文件夹的树如下

choco-nginx-tree

html是默认的网站根目录;conf文件夹放置着所有的配置文件,也是配置文件的工作目录基准。 至于最重要的网站配置,直接修改根配置文件还是不太舒服,因此可以把nginx.conf里的server{}块删掉,换成一行

include    ../vhosts/*.conf;

然后在程序目录下建立相应目录用来管理网站配置文件。

配置Nginx反向代理

HTTP API配置方法就省略了,因为文档已经非常详细。
假定酷Q监听了5700(HTTP)和6700(websocket)端口

server {
    root C:/tools/nginx-1.17.10/html;
    index index.html index.htm;
    server_name example.org;
    location / {
        location /cq/http/ {
            proxy_pass http://localhost:5700/;
        }
        location /cq/ws/ {
            proxy_pass http://localhost:6700/;
            proxy_http_version 1.1;
            proxy_set_header Upgrade http_upgrade;
            proxy_set_header Connection "Upgrade";
        }
        try_filesuri $uri/ =404;
    }
    listen 80 default_server;
}

执行Restart-Service nginx重载服务。

配置HTTPS

因为酷Q会明文传输聊天内容,在nginx上配置HTTPS的话,能够提高私密性。

certbot是面向UNIX类系统的,没法在Windows上使用;参考Let's Encrypt的ACME客户端列表,推荐使用win-acme,可以通过chocolatey安装

# 版本略落后于官网
choco install win-acme -y
wacs

界面是交互式的,大体上看着操作就行了。比较关键的如下:

Please choose from the menu:
M: Create renewal (full options) # 用自定义设置创建证书

How shall we determine the domain(s) to include in the certificate?:
2: Manual input # 手工输入

Enter comma-separated list of host names, starting with the common name:
example.org # 输入要申请TLS证书的域名

How would you like prove ownership for the domain(s)?:
1: [http-01] Save verification files on (network) path # 在网站根目录进行验证

Path to the root of the site that will handle authentication:
C:/tools/nginx-1.17.10/html # 输入nginx的网页根目录

How would you like to store the certificate?:
2: PEM encoded files (Apache, nginx, etc.) # 将证书保存为文件

Path to folder where .pem files are stored: 
C:/tools/nginx-1.17.10/tls # 输入保存证书的路径

证书申请下来后,改写nginx配置文件(同时加上了https跳转)

server {
    root C:/tools/nginx-1.17.10/html;
    index index.html index.htm;
    server_name example.org;
    location / {
        location /http/ {
            proxy_pass http://localhost:5700/;
        }
        location /ws/ {
            proxy_pass http://localhost:6700/;
            proxy_http_version 1.1;
            proxy_set_header Upgrade http_upgrade;
            proxy_set_header Connection "Upgrade";
        }
        try_filesuri uri/ =404;
    }

    listen 443 ssl;
    ssl_certificate C:/tools/nginx-1.17.10/tls/example.org-chain.pem;
    ssl_certificate_key C:/tools/nginx-1.17.10/tls/example.org-key.pem;
}
server {
    server_name example.org;
    if (host = example.org) {
        return 301 https://hostrequest_uri;
    }
    return 404;
    listen 80 default_server;
}

重启Nginx服务,此时就可以配置在bot配置中使用https://example.org/cq/http/进行连接了(注意尾部的/

尾声

明有奇巧人曰王叔远,能以径寸之木,为宫室、器皿、人物,以至鸟兽、木石,罔不因势象形,各具情态。尝贻余核舟一,盖大苏泛赤壁云。

嘻!技亦灵怪矣哉!

点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注