在 Microsoft Azure 上创建基本 (Basic) SKU 的公共 IPv4 地址
[scode type="yellow"]此文章的部分内容可能使用了机器或 AI 翻译的 zh-MS 语言。[/scode]TL;DR2025 年 3 月 31 日后，在 Azure 上创建基本 SKU 公共 IP 地址 (Public IP Address - Basic) 需要通过 Azure CLI 或 Azure PowerShell 等方式实现，而无法通过 Azure 门户 (Portal) 实现；且晚于此日期创建的订阅 (Subscription) 的基本 SKU 公共 IP 地址的配额 (quota) 为 0 个，必须通过 Azure 支持 (support) 请求 (request) 调整 (adjust) 其配额并获许后才能创建相应资源 (resource)。前言本文旨在描述在 2025 年 3 月 31 日后的 Microsoft Azure 上通过 Azure 支持提高基本 SKU 公共 IP 地址的配额，以及通过 Azure 门户提供的 Cloud Shell 运行 Azure CLI 创建基本 SKU 公共 IP 地址的操作过程。Microsoft 早在 2022 年 10 月便宣布 (announce) 了将于 2025 年 9 月 30 日停用 (retired) Azure 的基本 SKU 公共 IP 地址这一计划并给出了时间线：2025 年 3 月 31 日后新的基本 SKU 公共 IP 地址将无法被创建，而此前创建的相应资源则可以继续工作；2025 年 9 月 30 日后停用基本 SKU 公共 IP 地址，此后它们将无法被使用；Azure 扩展支持 (extended support) 用户不受上述停用之影响。以微软这个年过半百的老公司、大公司的一贯作风，这个改动不一定会完全实装。2025 年 3 月 31 日一过，Azure 门户便如期无法直接从公共 IP 地址介面中直接创建基本 SKU 公共 IP 地址，新创建的 Azure 订阅亦被取消相应的配额。但不久之后，有用户发现在 Azure 门户的 NIC 介面可以间接地创建基本 SKU 公共 IP 地址，不过微软很快封堵了这个渠道。不过与此同时，在 Azure 门户其他服务的介面的请求创建公共 IP 地址的选项卡上出现了温馨提示：「如果您暂时需要创建公共 IP 地址基本 SKU，请使用 Azure CLI 或 Azure PowerShell。」直至本文截稿，大多数订阅的基本 SKU 公共 IP 地址的配额依旧没有变化，且有相应配额的订阅的用户仍然能通过 Azure CLI 或 Azure PowerShell 创建基本 SKU 公共 IP 地址。〇、先决条件如果没有 Azure 订阅，请在开始之前创建一个免费帐户。同时需要准备一个资源组 (resource group) 以便被指定为创建基本 SKU 公共 IP 地址时的目标资源组。一、请求调整配额导航至 https://portal.azure.com/#view/Microsoft_Azure_Capacity/QuotaMenuBlade/~/myQuotas 以查看当前配额。Provider 选择 Networking，搜索框输入 Public IPv4 Addresses - Basic 即可查看各个区域 (region) 的基本 SKU 公共 IP 地址的配额。如果该值不为 0，则无需请求调整配额；如果该值为 0，说明该订阅不具有基本 SKU 公共 IP 地址的配额，需要请求调整配额。单击需要请求调整配额的区域所在行最右侧的「请求调整 (Request adjustment)」图标，导航至「新建支持请求 (New support request)」介面。在「配额详细信息 (Quota details)」选项卡中再次确认「位置 (Location)」和「资源 (Resources)」，并在「新限制 (New Limit)」输入框中键入一个处于 1 至 10 之间的整数，然后单击「保存并继续 (Save and continue)」按钮以将信息暂存至「新建支持请求 (New support request)」介面。检查其他信息后单击「下一步 (Next)」按钮，进入到「审阅并创建 (Review + create)」流程。再次确认相关信息是否正确，然后单击「创建 (Create)」按钮以提交支持请求。导航至 https://portal.azure.com/#view/Microsoft_Azure_Support/HelpAndSupportBlade/~/overview 以查看支持请求的处理状态；同时亦可观察配额介面相应地区的相应配额的值是否有变化。若相应区域的 Public IPv4 Address - Basic 的配额的值不再为 0，即告配额调整完成。[scode type="red"]短时间内大量请求调整配额将被视为意图进行欺骗性消耗等滥用，Microsoft 可能拒绝相关配额调整请求直至禁用相关订阅。[/scode][scode type="share"]根据《Azure 订阅和服务限制、配额和约束（公共 IP 地址限制）》，公共 IP 地址的默认配额因相应订阅的服务或类别类型而异，大多数订阅的公共 IP 地址的默认配额为 10，「即用即付 (Pay-as-you-go) 订阅 (MS-AZR-0003P 或 MS-AZR-0023P)」的公共 IP 地址的默认配额为 20。[/scode]二、通过 Azure CLI 创建基本 SKU 公共 IPv4 地址通过 Azure 门户的 Cloud Shell 调用 Azure CLI 可以免去配置身份验证等前置操作。导航至 Azure 门户，单击右上角的 Cloud Shell 图标即可启动 Cloud Shell。初次使用 Cloud Shell 时需要选择 Shell 类型，此处选择 Bash。选择 Shell 类型后需要选择订阅和存储账户 (Stroage Account)。因本文之操作不需要持久性保留文件或跨会话传递文件，使用 Cloud Shell 临时会话 (ephemeral sessions) 是更明智的选择。此处选择「无需存储帐户 (No storage account required)」，并选择相应订阅，单击「应用 (Apply)」以进行下一步。等待 Cloud Shell 实例会话建立后即可进行操作。在 Cloud Shell 的会话框内键入以下内容并按需修改：az network public-ip create \ --name example-ipname \ --subscription a19f2267-fca2-4955-82f2-ce8cbca9c08b \ --resource-group example-resgrpname \ --location westus3 \ --allocation-method Dynamic \ --sku Basic \ --version IPv4上述参数中，--name 为必需参数，需要将 example-ipname 替换为需要创建的公共 IP 地址的名称；--subscription 为可选参数，需要将 a19f2267-fca2-4955-82f2-ce8cbca9c08b 替换为相关订阅 ID；--resource-group 为必需参数，需要将 example-resgrpname 替换为相关资源组的名称，--location 为可选参数，需要将 westus3 替换为相关位置的「编程名称 (Programmatic Name)」，各个位置的「编程名称」可以参考《Azure 区域列表 (regions list)》 ；其它参数可以参考 https://learn.microsoft.com/cli/azure/network/public-ip?view=azure-cli-latest#az-network-public-ip-create 附加。命令可能需要附加一个或多个可选参数才能成功执行。若命令成功执行，公共 IP 地址将在数秒内被创建。成功创建基本 SKU 公共 IPv4 地址并关联到相应资源上。（外延支持）三、创建基本 SKU 的 Azure 负载均衡器 (Azure Load Balancer)根据《Azure Command-Line 接口 (CLI) 文档 (az-network-lb-create)》，创建负载均衡器时必须携带 --public-ip-address 和 --frontend-ip-name 参数，所指定的公共 IP 地址必须与负载均衡器的 SKU 匹配，且版本不能为 IPv6.az network lb create \ --name example-lbname \ --resource-group example-resgrpname \ --location westus3 \ --public-ip-address example-ipname \ --frontend-ip-name example-feipname \ --sku Basic基本 SKU 的负载均衡器的同 IP 地址版本的入站 NAT 规则 (Inbound NAT rules) 内的「关联虚拟机 (Target virtual machine)」项均配置为「空 (None)」时，该负载均衡器该 IP 地址版本的前端 IP 地址 (Frontend IP address) 的分配 (assignment) 若为「动态 (Dynamic)」，则该公共 IP 地址将为空。目前当虚拟机实例被关联基本 SKU 的负载均衡器后，即不满足默认出站访问 (default outbound access) 的条件，该虚拟机默认状况下将无法访问 Internet。終わり。
前言本文适用于接受以 POST 方法提交 JSON 体的 API 对端的通知解决方案，此案以 Telegram Bot 为例。以前的 Gmail Bot 还是很好用的，对于笔者这种重度用户来说登录网页来看邮件的时效性和便捷性都不如早起醒来瞄一眼 Bot 分类栏里出现的小红点——虽是十余年前的迷思，在手机上使用邮件 App 查看或同步邮件的话，其本家邮件（或是委托其同步的邮件）基本都是通过系统推送渠道告知用户新到的，若没有提供商的支持，透过 POP 等协议来同步的能耗和及时性都不及打开 IM 听任联系人 Q 我 8。Zoho Mail 虽然也有 App，但其商用办公解决方案提供的 Webhook 显然更简洁，为什么不用这种更为优雅的耦合方式呢？本文不涉及到对传入 Webhook 或 API 的操作，因此这里不介绍 Bot 侧的工作，直接从创建 Zoho Deluge 函数开始。配置 Zoho Mail 的 DRE 函数需要组织机构管理员「启用集成」https://mailadmin.zoho.com/cpanel/home.do#otherApps/integrations/settings （默认已经启用）访问 https://mail.zoho.com/zm/#settings/integrations-settings/DeveloperSpace/dre 并单击「创建函数」，自定义「函数名称」，「类别」选择「传出 Webhook」，在新出现的窗口粘贴以下内容：info Body; newLine = hexToText("0A"); summaryValue = Body.get("summary"); subjectValue = Body.get("subject"); senderValue = Body.get("sender"); messageIdValue = Body.get("messageId"); fromAddressValue = Body.get("fromAddress"); modeValue = Body.get("Mode"); notifyHeader = "You have a new mail."; chatIdValue = "114514191"; messageText = notifyHeader + newLine + "✉ " + "" + senderValue + "" + " <" + "" + fromAddressValue + "" + "> " + newLine + subjectValue + newLine + newLine + summaryValue; linkValue = "https://mail.zoho.com/zm/#mail/tab/" + messageIdValue; inlineKeyboardButton = {"text":"Open in Zoho Mail","url":linkValue}; if(modeValue == "6") { result = {"chat_id":chatIdValue,"text":messageText,"parse_mode":"HTML","reply_markup":{"inline_keyboard":{{inlineKeyboardButton}}}}; } else { result = {}; } return result;函数详解先贴出调用传出 Webhook 时会给到的 Body 的示例内容：{ "summary": "这是邮件摘要", "sentDateInGMT": 1753886387000, // 邮件发送时间(UTC)的Unix时间戳后加了三个0 "subject": "这是邮件主题", "Mode": 6, // 6是收到，1是发送，其他不知道，文档也没写 "messageId": 17538863870133100, // Zoho Mail 的信息ID，用于构建直达本邮件的URL "toAddress": "<postmaster@example.com>", // 收件人地址 "folderId": 114514000000001919, // Zoho Mail 的文件夹ID "zuid": 114514191, // Zoho 用户 ID "size": 114, // 邮件尺寸 "sender": "John Smith", // 发件人 "receivedTime": 1753886387114, // 邮件收到时间(UTC)的Unix时间戳，最后三位是毫秒 "fromAddress": "webmaster@example.com", // 发件人地址 "html": " test2<\/div>\r\n<\/div>\r\n<\/div>", // 邮件内容 "messageIdString": "1753537733180131300", // 字符串化的信息ID "IntegIdList": "1753537733180131300," }回到上一步创建的函数。根据指示，info Body; 一行是必填的；newLine = hexToText("0A"); 则是用来换行（具体原因见后记）；后续的各种 Value 无外乎是取出 Body 的值来重新赋予。如果需要处理 sentDateInGMT 和 receivedTime 则需如下处理：sentDateValue = Body.get("sentDateInGMT"); receivedTimeValue = Body.get("receivedTime"); sentDateText = sentDateValue.toText("yyyy/MM/dd hh:mm:ss","Asia/Shanghai"); receivedTimeText = receivedTimeValue.toText("yyyy/MM/dd hh:mm:ss","Asia/Shanghai");参数格式可以参考 https://www.zoho.com/deluge/help/functions/common/to-text.htmlnotifyHeader 可以自定义甚至删除，chatIdValue 便是 Telegram Bot 对话的 ID，messageText 是用来组合推送消息主体内容的（主要还是仿 Gmail Bot 消息风格，虽然那也不怎么好看就是了）；linkValue 和 inlineKeyboardButton 是用于组合内联键盘 (Inline Keyboard) 按钮及其链接的，因为本文做的只是推送而不是互动，因此没有其他花里胡哨的响应；最后的 if 和 else 主要用于过滤非「接收」的邮件（比如创建邮件模版、发送邮件等），并隐去其信息，让发送到 Bot API 的内容为空，达到防止不必要的泄露的目的。配置 Zoho Mail 的传出 Webhook访问 https://mail.zoho.com/zm/#settings/integrations-settings/DeveloperSpace/outgoingwebhooks 并单击「创建新的配置」，然后「自定义用户名」，并填写「Webhook 的 URL」，此处以 https://api.example.com/bot1145141919:AA8Vosmb4WBajGDcQpLbC9XLEnx8dsppUJv7/sendMessage 为示例；「选择实体」为「邮件」，「选择邮件条件」为「条件类型」中的「没有条件，适用于所有邮件」（当然可以自己配置规则），「有限数据列表」若勾选，Body 中将只提供 subject 和 fromAddress 等信息。「自定义函数」中，单击「编写函数」按钮，在弹出的窗口中选中刚刚创建的 DRE 函数。点击「保存」，完成创建。此时可见测试通过时的推送消息。结束。后记Zoho Deluge 太抽象了，笔者折腾了好久的 \n 换行才发现 Zoho Deluge 有个非常抽象的特性——自动将 \ 转义为 \\ ，该特性未在文档中标出且需向其技术部门发邮件才能关闭，其他藏着掖着的限制也不少，建议不用 Zoho。
在 Intel(R) J4125 承载的 Proxmox VE 虚拟机上安装 Windows 11 IoT Enterprise LTSC 2024 并直通网卡
Windows 11 的 LTSC 可谓是千呼万唤始出来。2024 年 10 月 2 日 Microsoft 正式公布了 Windows 11 Enterprise LTSC 2024 的各语言镜像，但英文单语言版 iotent 镜像（版本 26100.1742）早在 9 月 6 日就已经被编译了出来，这回属于是正式发布。本着折腾的原则，备份完数据之后就准备把软路由上的 Windows 10 升级一下。全新安装总是省事的。准备清单微 PE 工具箱 版本 2.3 或更高 https://www.wepe.com.cn/download.html（直通网卡用）Intel 以太网适配器完整的驱动程序包 版本 29.3.1 或更高 https://www.intel.com/content/www/us/en/download/15084/intel-ethernet-adapter-complete-driver-pack.htmlDISM++ 版本 10.1.1002.2 或更高 https://github.com/Chuyu-Team/Dism-Multi-language/releasesWindows VirtIO 驱动 版本 0.1.262 或更高 https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/UltraISO 版本 9.7.6 或更高Windows 11 IoT Enterprise LTSC 安装映像 版本 26100.1742 或更高定制 PE 环境和驱动释放 SCSI 驱动和 PE ISO 文件先解压 Windows VirtIO 驱动。Windows VirtIO 驱动解压完先不管。运行微 PE 工具箱安装程序，单击右下角的「光盘」。自定义可启动 ISO 镜像的输出位置和卷标。单击「立即生成 ISO」。单击「完成安装」。寻找其释放出来的 ISO 镜像并解压之。解压完成后即可使用 Dism++ 定制了。向 PE 镜像注入 SCSI 驱动打开 Dism++，选择「文件 (F)」，单击「挂载映像」。进入微 PE 工具箱释放的 ISO 镜像解压后的目录，选择 WEPE\WEPE64.WIM 文件并单击「打开 (O)」。挂载目录可以自定义，需要是一个干净的目录。这里以 D:\Temp\dismpp\ 为例。单击「确定」即可挂载映像。进入「驱动管理」，单击右下角的「添加驱动」。选择刚刚解压的 Windows VirtIO 驱动所在目录，选择 amd64\w10\ 目录（值得注意的是，该 PE 映像为 Windows 10）。单击「选择文件夹」，弹出操作成功等提示。可见「存储控制器」内已有 RedHat, Inc. 的 SCSI 驱动了。选择左上角的「文件 (F)」，单击「保存映像」，此处选择「直接保存」。选择左上角的「文件 (F)」，单击「卸载映像」。可见 PE ISO 镜像的解压目录中的 WEPE\WEPE64.WIM 文件已然是修改过后的时间了。修改 ISO 文件还得用到 UltraISO。修改 PE ISO 文件运行 UltraISO 程序，打开 PE 的 ISO 镜像，其内容显示在上半窗口处；下半窗口处进入 PE ISO 的解压目录。右键单击下半窗口处的 WEPE\WEPE64.WIM 文件，选择「添加」。提示「替换文件」，此处选择「是」。回到上半窗口处，右键单击光盘文件根目录的 BOOTMGR 文件，选择「设置为引导文件」。单击左上角的「文件 (F)」，选择「保存」。关闭 UltraISO 程序。定制 PE 环境完成。（直通网卡用）定制网卡驱动解压 Intel 以太网适配器完整的驱动程序包。重新打开 UltraISO 程序，其将默认生成一个光盘文件。进入驱动的解压目录，选中 PRO2500 文件夹，将其「添加」。单击左上角的「文件 (F)」，选择「保存」，「文件名 (N)」可以自定义。网卡驱动已经定制完成。配置 PVE 中的虚拟机上传镜像文件进入 PVE 的 ISO 镜像列表。将上一步制作的网卡驱动 ISO 文件（直通网卡用）、修改后的微 PE 工具箱 ISO 文件、Windows VirtIO 驱动 ISO 文件和 Windows 11 IoT Enterprise LTSC 安装映像尽数上传至 PVE。一共上传 4 个文件。创建虚拟机进入到 PVE 的「创建虚拟机」对话框，虚拟机的「名称」可以自定义。「使用 CD/DVD 光盘镜像文件 (ISO)」中的「ISO 镜像」选择修改后的微 PE 工具箱 ISO 镜像；「客户机操作系统」的「类别」选择 Microsoft Windows，「版本」选择 11/2022/2025；勾选「为 VirtIO 驱动程序添加额外驱动器」，「ISO 镜像」选择 Windows VirtIO 驱动 ISO 文件。「SCSI 控制器」选择 VirtIO SCSI，勾选「QEMU 代理」；Windows 11 IoT Enterprise 不要求 TPM，故不勾选「添加 TPM」；勾选「添加 EFI 磁盘」，与一般概念不同，PVE 虚拟机里的 EFI 磁盘仅仅是用来给 UEFI 存储启动项等用的，并不承担通常的 EFI 分区的功能。调整「磁盘大小 (GiB)」，勾选「SSD 仿真」（若虚拟磁盘存储在固态硬盘上）。CPU 的「类别」选择 host 以获得更好的性能；同时调整「核心」。调整「内存 (MiB)」和「最小内存 (MiB)」，勾选「Ballooning 设备」。（直通网卡用）因需要直通网卡，这里直接勾选「无网络设备」。这里确认配置，单击「完成」。创建完成后需要对虚拟机的「硬件」等进行进一步的修改。调整虚拟机「硬件」转到虚拟机的「硬件」页面，添加 2 个「CD/DVD 驱动器」。第一个驱动器的「ISO 镜像」选择 Windows 11 IoT Enterprise LTSC 安装映像。（直通网卡用）第二个驱动器的「ISO 镜像」选择网卡驱动 ISO 文件。（直通网卡用）添加「PCI 设备」，「原始设备」选择相应的网卡，勾选「所有功能」和「PCI-Express」。最终硬件配置如下。转到虚拟机的「选项」页面，编辑「引导顺序」，只保持勾选 scsi0 和 ide2（微 PE 工具箱的 ISO 镜像）。虚拟机我外部配置已经完成。安装 Windows在 PE 中部署 Windows 映像启动虚拟机，选择 UEFI Windows PE x64 (1024x786)。进入微 PE，可见显示效果正常。打开「分区工具 DiskGenius」，单击「快速分区」。其中「分区表类型」选择 GPT (GUID)；「分区数目」自定义；勾选「创建新 ESP 分区」，大小在 98MB 至 300MB 之间即可；取消勾选「创建 MSR 分区」；自定义「卷标」；勾选「对齐分区到此扇区的整数倍」。单击「确定」以应用更改。分区效果如下。运行「Windows 安装器 (WinNTSetup)」，「安装映像文件的位置」选择 Windows 11 IoT Enterprise LTSC 安装映像驱动器中的 sources\install.wim。「安装驱动器的位置」选择 C:\ 即可。「选项」选择 Windows 11 IoT Enterprise LTSC v22H2 Dev。单击「安装」。等待 Windows 映像应用。此时 Windows 映像已经被部署至硬盘中，此时不要重启。向 Windows 中注入驱动运行 Dism++，打开 Windows 11 IoT Enterprise LTSC x64 会话。依旧是「添加驱动」，选择 Windows VirtIO 驱动 ISO 文件所在驱动器，选择 amd64\w11\ 目录（值得注意的是，这里是对 Windows 11 注入驱动）。（直通网卡用）再次「添加驱动」，选择网卡驱动 ISO 文件所在驱动器，选择 PRO2500\Winx64\W11 目录。可见相关驱动已经注入系统。关闭 Dism++ 后直接重启。因 scsi0 启动排序在 ide\* 前的缘故，下一次启动将引导 scsi0 分区 1 中的 Windows Boot Manager。Windows OOBE等待启动。进入 OOBE 阶段。联网的情况下更新的时候居然有小游戏，梦回二十年前盗版 XP 安装，，，安装完成，进入桌面。Windows 的 Enterprise 带有其特有的「设备锁定」功能，IoT Enterprise 也不例外。自带应用仅 6 个，完全没有一般通道的 Windows 那么臃肿。安装 QEMU Guest Agent打开 Windows VirtIO 驱动 ISO 文件所在驱动器，双击运行 virtio-win-guest-tools.exe。安装完 QEMU Guest Agent 后 PVE 已经可以获得客户机的 IP 地址了。終わり。
Windows(R) Vista(TM) 安装体验——以 VMware Workstation Pro 为例
前言说来惭愧，第一台自己的电脑预装的不是 XP 而是 Vista，再不是赛博老登了。作为 Windows NT 6 系列的初代目，Vista 虽然给了十六年前的我一种耳目一新的感觉，但高居不下的蓝屏率和与 XP 大相径庭的操作让我在成为中级电脑高手的初期走了不少弯路。快十年前 (2015) 我曾尝试过把 Windows 98 到 8.1 在 VirtualBox 尽数安装体验，但在 Vista 及前代的激活服务器和 Windows Update 通道均关闭的今天 (2024)，全新安装旧世代的 Windows 并打完补丁的难度还是不小的。准备工作Windows Vista with Service Pack 2 映像文件Windows Vista 提供入门版 (Starter)、家庭普通版 (Home Basic)、家庭高级版 (Home Premium)、商用版 (Business)、企业版 (Enterprise) 和旗舰版 (Ultimate) 等六个版别，除入门版 (Starter) 外均有 32 位和 64 位版本。不讨论入门版 (Starter) 的情况下，家庭普通版 (Home Basic)、家庭高级版 (Home Premium) 和旗舰版 (Ultimate) 不提供 VoL 版本，而企业版 (Enterprise) 不提供零售版和 OEM 版本且系统镜像单列，这意味着前者不能透过 KMS 通道激活，而后者仅能透过 KMS 或 MAK 通道激活。Vista 的 Service Pack 1 (SP1) 于 2008 年 3 月 18 日发布，而 Service Pack 2 (SP2) 于 2009 年 4 月 28 日发布。本文使用 SP2 作为演示。企业版 (Enterprise) 64 位：Windows Vista Enterprise with Service Pack 2 (x64) - DVD (Chinese-Simplified): cn_windows_vista_enterprise_with_sp2_x64_dvd_x15-40402.iso, SHA1: 46E06E24D549FA42A2392C8553470BF9845C9C06企业版 (Enterprise) 32 位：Windows Vista Enterprise with Service Pack 2 (x86) - DVD (Chinese-Simplified): cn_windows_vista_enterprise_with_sp2_x86_dvd_x15-40257.iso, SHA1: 15472EBF0509ED56F46F6F5848D869C320C0B8D5家庭普通版 (Home Basic)、家庭高级版 (Home Premium)、商用版 (Business) 和旗舰版 (Ultimate) 64 位：Windows Vista with Service Pack 2 (x64) - DVD (Chinese-Simplified): cn_windows_vista_with_sp2_x64_dvd_x15-36322.iso, SHA1: A1689C254FB3BD67807EE493EE7D4896BCA39887家庭普通版 (Home Basic)、家庭高级版 (Home Premium)、商用版 (Business) 和旗舰版 (Ultimate) 32 位：Windows Vista with Service Pack 2 (x86) - DVD (Chinese-Simplified): cn_windows_vista_with_sp2_x86_dvd_x15-36285.iso, SHA1: DA7F7BDC841DDFFABFF7DDAB6B1158873BF1246DWindows Vista SP2 发布以后的补丁、在 2017 年 4 月 11 日扩展支持 (Extended Support Update) 到期后的额外补丁Vista SP2 发布到 2017 年 4 月支持结束前的所有补丁32 位：https://pan.baidu.com/s/1hsA7fQc?pwd=iwvn64 位：https://pan.baidu.com/s/1c2CbpIC?pwd=bbrn原载于 https://tieba.baidu.com/p/5070482430，补档于 https://bbs.pcbeta.com/viewthread-1858687-1-3.html。2017 年 5 月至 2020 年 1 月的后续更新集合https://pan.baidu.com/s/1Jqu7Q9heD0W_OIzzXqgY2A?pwd=juru原载于 https://bbs.pcbeta.com/viewthread-1858687-1-3.html。2020 年 2 月至 2023 年 1 月的后续更新集合https://pan.baidu.com/s/1FIFBRq4qvBv1EdZ7OYejsQ?pwd=m8p7原载于 https://bbs.pcbeta.com/viewthread-1957606-1-1.html。Windows Loaderhttps://app.box.com/s/bnchc6hten44adunlcpz9ya9j0uucfs2由 Microsoft Activation Scripts (MAS) 认证并上传，支持 Windows Vista 和 Windows 7 以 OEM 通道取得激活状态。VMware Tools 版本 11.0.6https://packages.vmware.com/tools/releases/11.0.6/windows/ 的 VMware-tools-windows-11.0.6-15940789.iso 文件。这个版本的 VMware Tools 暂时仍然支持 Windows Vista 的各个版本。VMware Workstation Pro笔者使用 VMware(R) Workstation 17 Pro，版本 17.5.2，运行在 Microsoft Windows 10 版本 22H2 内部版本 19045.4651 上。配置虚拟机单击 VMware Workstation 左上角的「文件 (F)」，单击「新建虚拟机 (N)... Ctrl+N」，进入「新建虚拟机向导」对话框。此处选择「自定义（高级）(C)」并单击「下一步 (N)」。此处的「虚拟机硬件兼容性 (H)」选择「Workstation 17.5.x」并单击「下一步 (N)」。此处选择「稍后安装操作系统 (S)。」并单击「下一步 (N)」。此处的「客户机操作系统」选择「Microsoft Windows (W)」，「版本 (V)」选择「Windows Vista x64 Edition」并单击「下一步 (N)」。此处的「虚拟机名称 (V)」和「位置 (L)」可根据需要自行确定，完成后单击「下一步 (N)」。此处的「固件类型」选择「BIOS (O)」并单击「下一步 (N)」。此处的「处理器数量 (P)」和「每个处理器的内核数量 (C)」可根据需要自行确定，完成后单击「下一步 (N)」。此处的「此虚拟机的内存 (M)」可根据需要自行确定，完成后单击「下一步 (N)」。此处选择「使用网络地址转换 (NAT) (E)」并单击「下一步 (N)」。此处选择「LSI Logic (L)」并单击「下一步 (N)」。此处选择「SCSI (S)」并单击「下一步 (N)」。此处选择「创建新虚拟磁盘 (V)」并单击「下一步 (N)」。此处的「最大磁盘大小 (GB) (S)」可根据需要自行确定，完成后单击「下一步 (N)」。此处的「磁盘文件 (F)」可根据需要自行确定，完成后单击「下一步 (N)」。确认虚拟机的配置并单击「完成」。正式安装 Windows Vista单击「编辑虚拟机设置」，弹出「虚拟机设置」窗口。在「CD/DVD (SATA)」的「连接」处选择「使用 ISO 映像文件 (M)」并在下方的下拉选框中选择下载的 Windows Vista 安装文件镜像并单击「确定」。单击「开启虚拟机」，静候屏幕显示 Windows Vista 引导画面。看到「安装 Windows」窗口，其中「要安装的语言 (E)」选择「中文（简体）」，「时间和货币格式 (T)」选择「中文（简体，中国）」，「键盘和输入方法 (K)」选择「中文（简体） - 美式键盘」，完成后单击「下一步 (N)」。此处选择「现在安装 (I)」。此处不输入产品秘钥，直接单击「下一步 (N)」。此处单击「否 (O)」以跳过产品密钥的输入并继续安装过程。此处选择「Windows Vista Ultimate」并单击「下一步 (N)」。此处勾选「我接受许可条款 (A)」并单击「下一步 (N)」。此处选择「自定义（高级）(C)」。此处可根据需要自行确定需要安装 Windows 的磁盘分区以及磁盘大小。完成后单击「下一步 (N)」。此处需要等候 Windows 安装程序复制和展开文件，完成后将自行重新启动。设定 WindowsWindows 安装程序结束后将进入 OOBE 阶段。此处可根据需要自行确定「用户名 (U)」和「密码 (P)」，完成后单击「下一步 (N)」。此处可根据需要自行确定「计算机名 (T)」，完成后单击「下一步 (N)」。此处选择「以后询问我 (A)」。此处的「时区 (Z)」选择「(GMT+08:00) 北京，重庆，香港特别行政区，乌鲁木齐」并单击「下一步 (N)」。此处选择「公共场所 (P)」。单击「开始 (S)」，进入 OOBE 的下一阶段。等待 Windows 对驱动等的初始化。「使完成工作变得充满乐趣」。「联络交流，易如反掌」。「演绎平凡的生活，凝聚美妙的回忆」。「联络，游戏，乐趣无穷」。「搜索五彩缤纷的世界」。「一个更安全的环境」。等待进入用户界面。等待用户初始化。进入用户桌面后，「欢迎中心」将自动出现。正常化操作系统单击「编辑虚拟机设置」，弹出「虚拟机设置」窗口。在「CD/DVD (SATA)」的「连接」处选择「使用 ISO 映像文件 (M)」并在下方的下拉选框中选择下载的 VMware Tools 11.0.6 版本的镜像并单击「确定」。单击「运行 setup64.exe」。单击「允许 (A)」。进入到「VMware Tools 安装程序」窗口，单击「下一步 (N)」。此处选择「典型安装 (T)」并单击「下一步 (N)」。此处单击「安装 (I)」。等待 VMware Tools 安装。单击「完成 (F)」。单击「是 (Y)」以重新启动。重新启动后虚拟机分辨率可以匹配 VMware Workstation 窗口的大小。在虚拟机内根据需要自行放置一些文件，包括本文提到的补丁包和激活工具。使用 Windows Loader 激活 Windows，需要单击「Restart」以重新启动使得 Windows 在引导时取得激活状态。Windows Vista 透过 OEM 通道取得激活状态。查看有关计算机的基本信息。「Windows 配置更新」页面的第一阶段。「Windows 配置更新」页面的第二阶段。「Windows 配置更新」页面的第三阶段。简单体验使用 Dism++ 安装本文提到的补丁包后，Windows 的 BuildLab 来到了 230105，成为一个官方支持下接近现代的操作系统。根储存库支持 ECC 的初代 Windows NT，有 Windows Server 2008 ESU 加持甚至不用手动导入 STL 就能自动信任很多新根。后记Vista 是个好用的 Windows 吗？显然不是。Dism++ 安装更新的时候不断卡死的新事故和在零几年的硬件上兼容性奇差的旧记忆一并构成了跨越几十年的对我的时间的浪费。它值得我突发奇想的一个原因是，在显示器技术进步的那个年代把拟物化做得超乎想象的绚丽和璀璨，至今深觉震撼。
Debian 10 (Buster) 及以上的发行版软件包源安装 MySQL 5.6.51
笔者一直苦于手里的实例配置过低，就算是安装了 Debian 12 (Bookworm) 的机器普遍也只有 1G 或 2G 的内存，用 MySQL 5.7 都够呛，更遑论 MySQL 8 了。看到全网没啥包安装低版本 MySQL 的方案，编译安装又太浪费时间，摸索了一整子，鼓捣出了 Debian 10 (Buster) 及以上的发行版安装 MySQL 5.6.51 的方法。（Ubuntu 等发行版应该可以照葫芦画瓢）一、准备工作安装好 wget。apt update -y && apt install wget -y确保系统中不存在 mysql-apt-config 包。dpkg -l | grep mysql-apt-config若没有返回，则进行下一步；若有返回，则执行 apt remove mysql-apt-config --purge -y。二、下载并安装 MySQL 相关包MySQL 5.6.51 在官方存档里只有供 Debian 9 (Stretch) 使用的包。笔者把相关包看了下，除了其自身内部的连体依赖的版本号是 =，其他外部依赖的版本号均为 >=，因此在 Debian 10 (Buster) 及以上版本的发行版中应该是能用的。执行以下命令以下载相关包：wget https://cdn.mysql.com/archives/mysql-5.6/mysql-common_5.6.51-1debian9_amd64.deb wget https://cdn.mysql.com/archives/mysql-5.6/libmysqlclient18_5.6.51-1debian9_amd64.deb wget https://cdn.mysql.com/archives/mysql-5.6/mysql-community-client_5.6.51-1debian9_amd64.deb wget https://cdn.mysql.com/archives/mysql-5.6/mysql-client_5.6.51-1debian9_amd64.deb wget https://cdn.mysql.com/archives/mysql-5.6/mysql-community-server_5.6.51-1debian9_amd64.deb wget https://cdn.mysql.com/archives/mysql-5.6/mysql-server_5.6.51-1debian9_amd64.deb下载完成后执行：apt install -y ./mysql-common_5.6.51-1debian9_amd64.deb ./libmysqlclient18_5.6.51-1debian9_amd64.deb ./mysql-community-client_5.6.51-1debian9_amd64.deb ./mysql-client_5.6.51-1debian9_amd64.deb ./mysql-community-server_5.6.51-1debian9_amd64.deb ./mysql-server_5.6.51-1debian9_amd64.debapt 会自行处理其他依赖。过程中会交互式地要求设置 MySQL 数据库 root 密码，输入即可。安装完成后可执行 mysql -u root（安装时未设置密码）或 mysql -u root -p（安装时已经设置密码）进入 MySQL Server。三、后记执行 systemctl enable mysql 以使 MySQL Server 随系统启动。MySQL Server 的配置文件在 /etc/mysql/ 目录里。mysql-common 是可以透过包管理器更新的，目前更新不影响 MySQL Server 的运行。执行 apt-mark hold mysql-common mysql-community-client mysql-client mysql-community-server mysql-server 以限制 MySQL 自动升级。終わり。
AlphaSSL 新证书 GlobalSign GCC R6 AlphaSSL CA 2023 证书链修复教程
近日有群友报告 AlphaSSL 新签的证书兼容性不佳，在用自动证书工具补齐证书链之后仍然无效。鉴于 GlobalSign 近几年搞了一大堆 intermediate CA，估摸着这回终于到 AlphaSSL 头上了。简单查了下，果然。2022 年底的 AlphaSSL CA - SHA256 - G2 失效，GlobalSign 给了 AlphaSSL CA - SHA256 - G4 作为新的 intermediate CA 证书，写在里面的 AIA 指向 GlobalSign Root CA (01SEP1998 - 28JAN2028, root-r1)。奇怪的是 2024 年 1 月 28 日之后的 AlphaSSL CA - SHA256 - G4 不再签发证书，改由 GlobalSign GCC R6 AlphaSSL CA 2023 签发原有通道的 AlphaSSL 证书，而后者的 AIA 指向 GlobalSign Root CA - R6 (10DEC2014 - 10DEC2034, root-r6)，且为信任锚。显然 2024 年 1 月 28 日之后的 AlphaSSL 默认的证书链的信任锚为 2014 年的这张 GlobalSign Root CA - R6。众所周知，一个新信任锚被绝大多数操作系统和软件所接受的周期是极长的，2010 年出的新根证书 (e.g. USERTrust) 依然在很多嵌入式设备、操作系统和浏览器中不受支持。保险起见，新的根证书会找老根证书交叉签名以保证自身的良好的兼容性，GlobalSign 也不例外。因此，重建证书链，将信任锚指向为其交叉签名的较老的根证书上即可解决问题。查询 https://crt.sh/?caid=272222 得知 GlobalSign GCC R6 AlphaSSL CA 2023 仅有一条直接上级 CA，即 GlobalSign Root CA - R6 (https://crt.sh/?caid=18459)。继续向上查询，得知 GlobalSign Root CA - R6 除了为信任锚外，还与 GlobalSign Root CA (01SEP1998 - 28JAN2028, root-r1) 有背书，那么解决方案呼之欲出————拼接 GlobalSign GCC R6 AlphaSSL CA 2023, GlobalSign Root CA - R6 和 GlobalSign Root CA 即可解决问题。将以下代码块附加在叶子证书（第一个 BEGIN CERTIFICATE 起到第一个 END CERTIFICATE 止）后作为证书链：-----BEGIN CERTIFICATE----- [binary] -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- [binary] -----END CERTIFICATE-----即可完成证书链建构。
解决 Oracle Cloud 计算实例因 DHCP 服务器下发配置变动导致 IPv6 地址失效的问题
不知道什么时候开始（至少在 200 天内），Oracle Cloud 更改了 DHCPv6 下发默认路由的方式，这导致按照传统配置初始化网络的实例在重新引导后无法自动获得 IPv6 协议默认路由，无法通过 IPv6 协议通信。位于 /etc/network/interfaces 的传统配置示例如下：source /etc/network/interfaces.d/* auto lo iface lo inet loopback allow-hotplug ens3 iface ens3 inet dhcp iface ens3 inet6 dhcp该配置中，唯一网卡 ens3 的双栈地址均通过 DHCP 协议获得。重新引导实例后，网卡 ens3 获得的地址和默认路由如下：# ifconfig ens3 ens3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 9000 inet 10.155.46.97 netmask 255.255.255.0 broadcast 10.155.46.255 inet6 fe80::17ff:fe03:6ddc prefixlen 64 scopeid 0x20 inet6 2602:fd92:6e0:1263:0:200:1703:6ddc prefixlen 128 scopeid 0x0<global> ether 02:00:17:03:6d:dc txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 # ip -6 r ::1 dev lo proto kernel metric 256 pref medium 2602:fd92:6e0:1263:0:200:1703:6ddc dev ens3 proto kernel metric 256 pref medium fe80::/64 dev ens3 proto kernel metric 256 pref medium可见，IPv6 地址正确获得，但是未收到默认网关信息。此时 IPv6 协议通信失败，报错 Network is unreachable：# curl -6v https://blog.iks.moe/ * Trying 2602:fd92:6e0:1263:2333::ac43:a69b:443... * Immediate connect fail for 2602:fd92:6e0:1263:2333::ac43:a69b: Network is unreachable * Closing connection 0 curl: (7) Couldn't connect to server尝试将 /etc/network/interfaces 中的 ens3 inet6 改为 auto 模式（无状态模式）并启用 DHCP 和请求前缀：source /etc/network/interfaces.d/* auto lo iface lo inet loopback allow-hotplug ens3 iface ens3 inet dhcp iface ens3 inet6 auto dhcp 1 request_prefix 1重新引导实例后，网卡 ens3 获得的地址和默认路由如下：# ifconfig ens3 ens3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 9000 inet 10.155.46.97 netmask 255.255.255.0 broadcast 10.155.46.255 inet6 fe80::17ff:fe03:6ddc prefixlen 64 scopeid 0x20 ether 02:00:17:03:6d:dc txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 # ip -6 r ::1 dev lo proto kernel metric 256 pref medium 2602:fd92:6e0:1263::/64 dev ens3 proto kernel metric 256 pref medium fe80::/64 dev ens3 proto kernel metric 256 pref medium default via fe80::200:17ff:fec7:5f76 dev ens3 proto ra metric 1024 expires 8998sec hoplimit 64 pref medium可见，IPv6 网段和默认网关正确获得，但是未收到 IPv6 地址。此时 IPv6 协议通信失败，报错 Connection timed out：# curl -6v https://blog.iks.moe/ --connect-timeout 5 * Trying 2602:fd92:6e0:1263:2333::ac43:a69b:443... * After 2467ms connect time, move on! * connect to 2602:fd92:6e0:1263:2333::ac43:a69b port 443 failed: Connection timed out * Failed to connect to blog.iks.moe port 443: Connection timed out * Closing connection 0 curl: (28) Failed to connect to blog.iks.moe port 443: Connection timed out尝试将 /etc/network/interfaces 中的 ens3 inet6 改回 dhcp 模式并使用 SLAAC 请求默认路由：source /etc/network/interfaces.d/* auto lo iface lo inet loopback allow-hotplug ens3 iface ens3 inet dhcp iface ens3 inet6 dhcp accept_ra 2重新引导实例后，网卡 ens3 获得的地址和默认路由如下：# ifconfig ens3 ens3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 9000 inet 10.155.46.97 netmask 255.255.255.0 broadcast 10.155.46.255 inet6 fe80::17ff:fe03:6ddc prefixlen 64 scopeid 0x20 inet6 2602:fd92:6e0:1263:0:200:1703:6ddc prefixlen 128 scopeid 0x0<global> ether 02:00:17:03:6d:dc txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 # ip -6 r ::1 dev lo proto kernel metric 256 pref medium 2602:fd92:6e0:1263:0:200:1703:6ddc dev ens3 proto kernel metric 256 pref medium 2602:fd92:6e0:1263::/64 dev ens3 proto kernel metric 256 pref medium fe80::/64 dev ens3 proto kernel metric 256 pref medium default via fe80::200:17ff:fec7:5f76 dev ens3 proto ra metric 1024 expires 8961sec hoplimit 64 pref medium可见，IPv6 地址和 IPv6 默认路由均成功得到。尝试通过 IPv6 协议通信，成功：# curl -6 ip.sb 2602:fd92:6e0:1263:0:200:1703:6ddc总结看样子 Oracle Cloud 目前通过 DHCPv6 下发前缀等，而默认路由则透过 SLAAC 发送。在 /etc/network/interfaces 中的 iface ens3 inet6 dhcp 下方添加 accept_ra 2 即可。另外 Oracle Cloud 的网络长期稳定性非常灵车，之前动不动无网络，VNC 进去一看 ens3 的 IPv4 和 IPv6 地址都没了，估计与其 DHCP 服务器实现有很大关系。参考文献IPv6PrefixDelegation - Debian Wiki
OpenWrt 实现 PXE 服务器 (TFTP+NFS) 以引导无盘工作站 (Ubuntu 22.04 LTS)
一、综述顾名思义，无盘系统是用于网吧、机房等公用计算机的一种网络传输技术。使用无盘系统启动的计算机将不使用本机的硬盘获得启动系统，而是通过网络的指定服务器去获得启动系统的镜像，并下载回本机后用于机器启动。PXE (Pre-boot Execution Environment) 是由 Intel 设计的协议，它是无盘系统的一种实现形式。很巧，OpenWrt 作为路由器操作系统，工作在网关模式下支持标准 DHCP, TFTP 和 NFS 协议实现；而目前大多数带有板载有线网卡的机器都支持网络启动 (Network Boot)，能够在客户端侧支持 PXE。本文以 https://blog.nanpuyue.com/2013/027.html 为原本，适当修改了部分内容以适应时代的变化，旨在使其能够支持 Ubuntu 22.04 LTS 的启动，为近世治理提供参考（错乱）。需求硬件：运行在网关模式下的 OpenWrt 设备（一般是路由器）；附着在上述 OpenWrt 设备上的至少 8GB 的空闲存储空间（路由器自带的也行，外接的 U 盘也行）；有线连接至上述 OpenWrt 设备的支持网络启动的计算机。本方案继承原文，以 Ubuntu 作为案例，能够向旧兼容到 Ubuntu 12.04 LTS，其他发行版亦可参考本文。二、下载 Ubuntu 镜像对于 Ubuntu 镜像，问就是清华大学的 OpenTUNA https://opentuna.cn/ubuntu-releases/22.04/ubuntu-22.04-desktop-amd64.iso （通过亚马逊云科技的 CloudFront 分发，基本没有限速）。对于 8GB 及以上内存的电脑来说，64 位的 Ubuntu Desktop 还是能够轻松对付的。三、调整和挂载相关目录OpenWrt 挂载目录的方案请自行查找，本文将 13.94GB 的分区 /dev/mmcblk0p3 挂载为 /mnt/main .目录详情如下：/mnt/main/nfsroot NFS 根目录；/mnt/main/tftproot TFTP 根目录。四、TFTP 和 NFS 环境配置安装软件包 nfs-kernel-server-utils （一般都安装了）：NFS 设置共享目录，“路径”填写 /mnt/main/nfsroot/ ，“允许的客户端”填写 * ，选项 填写 rw,no_root_squash,async,insecure,no_subtree_check 。如果 OpenWrt 没有图形界面，或未安装 NFS 管理的 LuCI APP，则修改 /etc/exports，加入一行 /mnt/main/nfsroot/ *(rw,no_root_squash,async,insecure,no_subtree_check) ，保存后执行 exportfs -rv。网络-DHCP/DNS 处提供了 TFTP 配置，其中“启用 TFTP 服务器”调整为“使能”（即勾选），“TFTP 服务器根目录”填写 /mnt/main/tftproot，“网络启动镜像”填写 pxelinux.0。如果 OpenWrt 没有图形界面，则修改 /etc/config/dhcp，在 config dnsmasq 内写入以下内容：option enable_tftp '1' option tftp_root '/mnt/main/tftproot'新起一行，填入以下内容：config boot linux option filename 'pxelinux.0' option serveraddress '172.18.54.1' option servername 'OpenWrt'其中，172.18.54.1 为 OpenWrt 的 IP 地址。执行 /etc/init.d/dnsmasq restart 重启 DNSmasq。五、上传镜像打开步骤二下载的镜像，解压其 .disk 和 casper 文件夹。将其上传到 OpenWrt 的 /mnt/main/nfsroot 目录。六、配置 PXELinux将步骤五中 casper 文件夹中的 initrd 和 vmlinuz 文件上传到 OpenWrt 的 /mnt/main/tftproot 目录。下载 Debian Installer for NetBoot （Ubuntu 没有这个） https://opentuna.cn/debian/dists/bullseye/main/installer-amd64/current/images/netboot/netboot.tar.gz ，解压以下文件至同一文件夹：debian-installer/amd64/pxelinux.0debian-installer/amd64/boot-screens/ldlinux.c32debian-installer/amd64/boot-screens/libcom32.c32debian-installer/amd64/boot-screens/libutil.c32debian-installer/amd64/boot-screens/vesamenu.c32将其上传到 OpenWrt 的 /mnt/main/tftproot 目录。在 /mnt/main/tftproot 目录新建目录 pxelinux.cfg ，在 /mnt/main/tftproot/pxelinux.cfg 目录新建文件 default 并填入以下内容：default vesamenu.c32 prompt 0 timeout 30 menu title UBUNTU LIVE label ^Ubuntu Desktop kernel vmlinuz append initrd=initrd ip=dhcp boot=casper netboot=nfs nfsroot=172.18.54.1:/mnt/main/nfsroot locale=zh_CN.UTF-8 其中，172.18.54.1 为 OpenWrt 的 IP 地址。/mnt/main/tftproot 目录的文件如下：七、引导不同主板开启“从网络引导 ROM”功能的操作步骤不尽相同，建议联系主板制造商获得支持。由于 NVIDIA 显卡对 Linux 一贯以来的不友好和 Ubuntu 22.04 的 bug，部分使用 NVIDIA 显卡输出的设备在 Ubuntu 22.04 下默认色彩异常，可以通过“设置”里的“色彩”调整解决。文件系统结构欣赏：鸣谢基于 OpenWrt 的 Linux 无盘工作站方案 - 南浦月Bug #1877618 “20.04 fails to boot via PXE (amd64) - “hidden .dis...” : Bugs : ubiquity package : Ubuntudhcp - problem setting up pxe boot with diskless client ubuntu 20.04 (dnsmasq,nfs server) ltsp like - Ask Ubuntudrivers - Screen turns yellow even using the live option Ubuntu 22.04 - Ask Ubuntu
使用非 Docker 方案在腾讯云轻量应用服务器上搭建密码管理软件 Vaultwarden (Bitwarden_rs)
前言Bitwarden 是一款自由且开源的密码管理服务，用户可在加密的保管库中存储敏感信息（例如网站登录凭据）。Bitwarden 平台提供有多种客户端应用程序，包括网页用户界面、桌面应用，浏览器扩展、移动应用以及命令行界面。Bitwarden 作为一款商业自由软件，其开发公司提供云端托管服务 (bitwarden.com)，同时为广大开源社区提供自行部署的解决方案。Vaultwarden 原名 Bitwarden_rs，自 v2.21.0 开始更名为 Vaultwarden。Bitwarden 原始服务端使用 C# 编写，部署困难，且要求 MSSQL 等商业软件，运行需要 2GB 以上的内存；而 Vaultwarden 是一个使用 Rust 编写的非官方 Bitwarden 服务器实现，它与官方 Bitwarden 客户端兼容，运行 Vaultwarden 时只需要 10M 内存，可以说对硬件基本没有要求，对于不希望使用官方的占用大量资源的自托管部署而言，它是理想的选择。Vaultwarden 除不支持官方企业版的部分功能（如事件日志、目录同步以及 SSO 登录）外，其他大部分功能均免费支持。并跟随官方版本保持及时更新。Vaultwarden 实现了 Bitwarden API 所需的大部分功能，因此桌面端、移动端、浏览器扩展等客户端均可直接使用 Bitwarden 官方的客户端应用程序。Vaultwarden 仓库推荐的安装方式均为直接使用 Docker 部署，本文将介绍一种使用非 Docker 方式、直接在系统上部署 Vaultwarden 的方法。16MB 左右的内存占用，再配合 MySQL 替代默认的 SQLite 作为数据存储形式可以将其“功耗”降到最低。一、准备工作1.1 服务器和系统选用由于 Vaultwarden 运行时几乎不消耗系统资源，因此可以选用任意型号的轻量应用服务器；服务器系统建议选择 Ubuntu 18.04 或更新版本以及 Debian 10 或更新版本的 Linux 发行版，使用 CentOS 似乎会因依赖软件包版本问题而出现未知的错误。此外，由于部署 Vaultwarden 不会对现有系统环境造成破坏性影响，在已经有网站业务的服务器上部署 Vaultwarden 也是一个不错的选择。1.2 环境配置1.2.1 软件包及依赖配置依次执行以下命令以更新软件包信息、安装必要的软件包及开发工具包：apt update -y apt install git nano curl wget htop pkg-config openssl libssl1.1 libssl-dev -y apt install build-essential -y1.2.2 Rust 环境配置执行 curl https://sh.rustup.rs -sSf | sh 以配置 Rust 环境。（国内可能较慢）出现 Rust is installed now. Great! 即代表安装完成。依次执行以下命令以配置 cargo 命令的环境变量：echo 'export PATH=~/.cargo/bin:$PATH' >> ~/.bashrc export PATH=~/.cargo/bin:$PATH which rustc若返回 /root/.cargo/bin/rustc 则代表完成 Rust 环境的配置。二、编译 Vaultwarden执行 git clone https://github.com/dani-garcia/vaultwarden && cd vaultwarden 以拉取 Vaultwarden 储存库（国内可能较慢）：执行 cargo clean && cargo build --features mysql --release 以启动 Vaultwarden 的编译。其中，mysql 可以为与 sqlite 和 postgresql 三者的任意组合，选择编译 mysql 或 postgresql 时，系统必须安装了 MySQL 或 PostgreSQL，否则将提示：linking with `cc` failed: exit status: 1 ... = note: /usr/bin/ld: cannot find -lmysqlclient collect2: error: ld returned 1 exit status不想安装 MySQL 的可以仅安装其适用于 Rust 语言的 Client 库（限 Ubuntu 或 Debian）：apt install librust-mysqlclient-sys-dev -y编译需要 3GB 左右的内存，内存不足的可以调整虚拟内存，虚拟内存建议空闲 2GB 左右；编译耗时较久，LemonBench 跑分在 800 左右的单核服务器编译耗时 28 分 54 秒。三、安装 Vaultwarden3.1 移动 Vaultwarden 二进制文件依次执行以下命令：cp target/release/vaultwarden /usr/bin/vaultwarden chmod +x /usr/bin/vaultwarden以将 Vaultwarden 二进制文件置入系统可执行目录并赋予执行权限。3.2 配置 Vaultwarden 专用用户依次执行以下命令：useradd -s /sbin/nologin -M vaultwarden mkdir -p /var/lib/vaultwarden/data chown -R vaultwarden:vaultwarden /var/lib/vaultwarden/3.3 部署 Vaultwarden Web UI依次执行以下命令：wget https://github.com/dani-garcia/bw_web_builds/releases/download/v2.28.0/bw_web_v2.28.0.tar.gz tar -xf bw_web_v2.28.0.tar.gz -C /var/lib/vaultwarden/其中 v2.28.0 为写作时的版本号，获取地址为 https://github.com/dani-garcia/bw_web_builds/releases/latest ，请保持最新。3.4 编写 Vaultwarden 配置文件执行 touch /etc/vaultwarden.env 并写入以下内容：DATA_FOLDER=/var/lib/vaultwarden/data/ DATABASE_URL=mysql://[数据库用户名]:[数据库密码]@127.0.0.1:3306/[数据库名] IP_HEADER=X-Real-IP WEB_VAULT_FOLDER=/var/lib/vaultwarden/web-vault/ WEB_VAULT_ENABLED=true ADMIN_TOKEN=[base64码] DOMAIN=https://vaultwarden.iks.moe其中，[数据库密码] 为 MySQL 数据库用户名，[数据库密码] 为 MySQL 数据库用户的密码，[数据库名] 为 MySQL 数据名，此三者均须提前创建；127.0.0.1 不得填写为 localhost，[base64码] 执行 openssl rand -base64 48 以得到，https://vaultwarden.iks.moe 为你的域名，协议头必须为 https://。3.5 编写 Vaultwarden SystemD 文件执行 touch /etc/systemd/system/vaultwarden.service 并写入以下内容：[Unit] Description=Vaultwarden Server Documentation=https://github.com/dani-garcia/vaultwarden # 当你使用 SQLite 时，请取消下一行的注释 # After=network.target # 当你使用 MariaDB 时，请取消下两行的注释 # After=network.target mariadb.service # Requires=mariadb.service # 当你使用 MySQL 时，请取消下两行的注释 # After=network.target mysqld.service # Requires=mysqld.service # 当你使用 PostgreSQL 时，请取消下两行的注释 # After=network.target postgresql.service # Requires=postgresql.service [Service] User=vaultwarden Group=vaultwarden EnvironmentFile=/etc/vaultwarden.env ExecStart=/usr/bin/vaultwarden LimitNOFILE=1048576 LimitNPROC=64 PrivateTmp=true PrivateDevices=true ProtectHome=true ProtectSystem=strict WorkingDirectory=/var/lib/vaultwarden ReadWriteDirectories=/var/lib/vaultwarden AmbientCapabilities=CAP_NET_BIND_SERVICE [Install] WantedBy=multi-user.target删去被注释的行，最终配置如图：3.6 启动 Vaultwarden依次执行以下命令：systemctl enable --now vaultwarden.service systemctl start vaultwarden.service systemctl status vaultwarden.service若正常启动，则如下图提示：四、使用 Nginx 反向代理 Vaultwarden本文以宝塔面板为例，其他环境与此操作相同。4.1 新建站点新建一个站点，域名填写步骤 3.4 中的域名，配置好 SSL 证书。4.2 配置反向代理名称随意，目标 URL 为 http://127.0.0.1:8000，其他默认。供非宝塔用户的 nginx 反向代理配置：location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header REMOTE-HOST $remote_addr; add_header Cache-Control no-cache; }五、使用访问域名，单击 Create Account 开始密码管理的第一步。六、Vaultwarden 后续更新重做步骤二、步骤 3.1, 3.3 并执行 systemctl restart vaultwarden.service 即可。参考文献https://nickhuber.ca/blog/bitwarden-rs-without-dockerhttps://gist.github.com/tavinus/59c314f4ccd70879db7f11074eacb6cc
在使用 WLAN 联网的树莓派上安装 Proxmox VE 并创建虚拟机
去年的这个时候收了一台树莓派 4B，到手之后宝塔建站一把梭之后就放在那里吃灰（没办法，技术太菜玩不了别的）。最近迷上了 PVE，想想手头也没有什么可以实践的物理设备，百般寻找之后便把目光锁定在了吃灰中的树莓派。Proxmox 论坛的 https://forum.proxmox.com/threads/how-to-run-pve-7-on-a-raspberry-pi.95658/ 帖子讲的是在有线网络接入 (eth0) 时的安装过程，目前我手里没有网线，所以只能修修改改踩踩坑探索一下 WLAN 接入网络 (wlan0) 时的安装和配置。本教程需求：Raspberry Pi 4 Model B（内存 2GB 或以上）、拥有宽带连接的 2.4GHz 或 5GHz 的 WLAN（SSID 不可带有下划线 (_)、DHCP 服务器能够给指定的 MAC 地址分配固定的 IP 地址功能、需要能够顺畅连接 raw.githubusercontent.com）、一台显示器、USB 接口的键盘以及一张容量至少为 16GB 且速度等级为 C10 或以上的 MicroSD 卡。一、准备工作1.1 刷写系统镜像1.1.1 下载系统镜像访问 https://mirrors.tuna.tsinghua.edu.cn/raspberry-pi-os-images/raspios_lite_arm64/images/ 下载 Raspberry Pi OS ARM64 Lite 最新的版本，本文写作时的版本为 2021-11-08 (https://mirrors.tuna.tsinghua.edu.cn/raspberry-pi-os-images/raspios_lite_arm64/images/raspios_lite_arm64-2021-11-08/2021-10-30-raspios-bullseye-arm64-lite.zip)清华大学 TUNA 源的速度还是很不错的。此外，阿里云镜像站（mirrors.aliyun.com）也提供相同的镜像。系统镜像下载完成后，解压之，得到 ISO 文件。1.1.2 刷写系统镜像至 MicroSD 卡中下载 SD Card Formatter (https://www.sdcard.org/downloads/formatter/eula_windows/SDCardFormatterv5_WinEN.zip) 并安装。下载 Win32 Disk Imager (https://sourceforge.net/projects/win32diskimager/) 并安装。不建议拿其他刷写软件替代，比如 Rufus 刷写后不会给 BOOT 分区分配盘符。使用 SD Card Formatter 格式化 MicroSD 卡。格式化完成后，打开 Win32 Disk Imager，向 MicroSD 卡写入系统镜像。1.2 准备网络环境1.2.1 分配固定 IP 地址登录 WLAN AP （路由器）后台，给树莓派的 WLAN MAC 地址分配一个固定的 IP 地址。若暂时不知道其 MAC 地址，可以跳过此步。本文树莓派被分配到的 IP 地址为 192.168.1.233/24，网关为 192.168.1.1，DNS 地址为 192.168.1.1。1.2.2 使能 SSH 功能和 WLAN 连接步骤 1.1.2 刷写完成后，MicroSD 卡的 boot 分区会被分配一个盘符，进入此分区，新建文件 wpa_supplicant.conf 和 SSH。使用编辑器（不得使用 Window 记事本）编辑 wpa_supplicant.conf 文件，填入以下内容：ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 network={ ssid="WiFi的SSID" psk="WiFi密码" }保存即可，SSH 文件则保持空白。拔出 MicroSD 卡，将其插入树莓派。二、配置底层系统2.1 重新配置用户和密码使用 SSH 终端登录至树莓派（默认用户名 pi，密码 raspberry），执行 sudo -i 切换至 root 用户，执行 passwd root 和 passwd pi 修改 root 用户和 pi 用户的密码。2.2 允许 root 用户通过 SSH 登录执行 echo "PermitRootLogin yes" >> /etc/ssh/sshd_config && echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config 后执行 systemctl restart sshd，使用 root 用户重新 SSH 连接至树莓派即可。2.3 增加和修改源并安装内核头文件执行 rm /etc/apt/sources.list.d/*.list 清除不必要的源。编辑 /etc/apt/sources.list 文件，将 deb.debian.org 和 security.debian.org 尽数替换为 mirrors.cloud.tencent.com 并在下方添加以下两行内容：deb https://raw.githubusercontent.com/pimox/pimox7/master/ dev/ deb http://mirrors.cloud.tencent.com/raspberrypi bullseye main效果如图其中，前 3 行的 mirrors.cloud.tencent.com 可以替换为其他支持 Debian 11 的源，第 5 行的 mirrors.cloud.tencent.com 可以替换为其他支持 Raspberry Pi OS 的源。部分源并不同时支持两者。执行 curl https://raw.githubusercontent.com/pimox/pimox7/master/KEY.gpg | sudo apt-key add – 以安装 Pimox7 的 gpg 公钥。执行 apt update && sudo apt dist-upgrade -y && apt install -y raspberrypi-kernel-headers 以更新软件包数据库、更新软件包和安装 raspberrypi 内核头文件。2.4 静态化网卡编辑 /etc/network/interfaces 文件，清除原有内容后填入以下内容：auto lo iface lo inet loopback auto wlan0 iface wlan0 inet static address 192.168.1.233/24 gateway 192.168.1.1其中，192.168.1.233/24 和 192.168.1.1 分别为步骤 1.2.1 中提到的树莓派被分配到的 IP 地址和网关。修改完成后保存。2.5 配置主机名执行 hostnamectl set-hostname RPi4-PVE-01，其中 RPi4-PVE-01 请自定义。编辑 /etc/hosts 文件，清除原有内容后填入以下内容：127.0.0.1 localhost 192.168.1.233 RPi4-PVE-01其中，192.168.1.233 和 RPi4-PVE-01 分别为步骤 1.2.1 中提到的树莓派被分配到的 IP 地址和主机名。2.6 扩大 SWAP树莓派默认的 SWAP 大小只有 100M，非常不适合本文场景，故请编辑 /etc/dphys-swapfile 文件，将原先 CONF_SWAPSIZE 的值从 100 改为 2048；执行 /etc/init.d/dphys-swapfile stop && /etc/init.d/dphys-swapfile start 以应用更改。一切完成后，重新启动系统。三、安装 Proxmox VE3.1 安装 Proxmox VE 本体将树莓派连接至显示器，插入键盘，执行 apt install -y proxmox-ve。因安装过程中将重置网络，故请勿直接在 SSH 中直接执行 apt install -y proxmox-ve。弹出配置 Postfix 时，请选择 Local system。安装需要半个小时左右，建议耐心等待；安装完成后，请重新启动设备。3.2 配置无线网卡和虚拟网桥编辑 /etc/network/interfaces 文件，在 source-directory /etc/network/interfaces.d 此行上方插入以下内容：auto wlan0 iface wlan0 inet dhcp wpa-ssid 114514 wpa-psk qweasdzxc123 auto vmbr0 iface vmbr0 inet static address 10.154.46.1 netmask 255.255.255.0 bridge-ports none bridge-stp off bridge-fd 0 post-up iptables -t nat -A POSTROUTING -s '10.154.46.0/24' -o wlan0 -j MASQUERADE post-down iptables -t nat -D POSTROUTING -s '10.154.46.0/24' -o wlan0 -j MASQUERADE其中，wpa-ssid 后为 WLAN 的 SSID，wpa-psk 后为 WLAN 的密码。其他内容请按需修改。执行 systemctl restart networking 以重启网络设备。3.3 内核参数调整编辑 /etc/sysctl.conf 文件，添加以下内容：vm.overcommit_memory=1 net.ipv4.ip_forward=1 net.ipv4.conf.all.rp_filter=1 net.ipv4.icmp_echo_ignore_broadcasts=1 net.ipv4.conf.default.forwarding=1 net.ipv4.conf.default.proxy_arp=0 net.ipv4.conf.default.send_redirects=1 net.ipv4.conf.all.send_redirects=0保存后执行 sysctl -p 使其生效。3.4 配置 Proxmox VE 用户界面访问 https://IP 地址:8006 （以下以 https://pve.iks.moe:28006 作为演示）登录 Proxmox VE 用户面板。用户名和密码与步骤 2.1 中设置的系统用户名和密码一致；语言可选 Chinese (Simplified)。单击本机唯一的节点，选择“凭证”，单击上方的“上传自定义凭证”按钮上传自定义的证书。此操作会让 Proxmox VE 用户界面在重载时使用自定义的证书，在主机名对应的情况下提供基于 TLS 的身份验证和加密的安全性。（把 pve.iks.moe 解析到步骤 1.2.1 中提到的 192.168.1.233 然后再传证书，刷新即可。）四、创建 QEMU-KVM 虚拟机4.1 下载镜像单击节点下的 local，选择 ISO映像，单击上方的“上传”（如果本地有镜像的话）或“从 URL 下载”下载相应的镜像。因树莓派 4B 为 ARM64 架构，因此下载的镜像亦需要为 arm64 架构，腾讯云源 (https://mirrors.cloud.tencent.com/ubuntu-cdimage/, https://mirrors.cloud.tencent.com/debian-cd/current/arm64/iso-cd/ 等有 Ubuntu 和 Debian 的镜像。本章以 Debian 11.1.0 ARM64 为例。将镜像的 URL 粘贴到文本框后单击右边的“查询网址”，待文件名成功显示后即可单击下方的“立即下载”按钮。下载过程将在后台进行，进度将被实时打印。4.2 创建虚拟机镜像下载完成后，单击右上角的“创建虚拟机”，弹出相关对话框。名称请自定义，其他内容请留空；在单击对话框底部的“下一步”前，请勾选左边的“高级”。此处“操作系统”选择“不使用任何介质”。勾选“QEMU代理”，并将 BIOS 改为 OVMF (UEFI)，“添加EFI磁盘”下的“存储”选择 local。随后的“磁盘大小 (GiB)”和“内存 (MiB)”请按需选择，其他配置建议默认。单击“完成”以开始创建虚拟机。4.3 调整虚拟机的硬件4.3.1 删除 CD/DVD 驱动器单击刚刚创建的虚拟机，选择“硬件”，单击选中 CD/DVD驱动器 (ide2) 后点击上方的“删除”按钮。4.3.2 添加镜像驱动器单击上方的“添加”，选择“CD/DVD驱动器”。“总线/设备” 选择 SCSI，顺序为 2；使用“存储”为 local，“ISO映像”为步骤 4.1 下载的 Debian 11.1 ARM64 镜像；单击对话框底部的“创建“按钮。4.3.3 调整开机顺序单击“选项”，双击右方的“引导顺序”，将 scsi2 改为如图在 scsi0 后、在 net0 前的顺序，单击对话框下方的“OK”保存之。4.4 启动安装4.4.1 开机单击右上角的“启动”按钮，再单击右方的“控制台”进入 noKVM，稍等片刻即可进入 Debian 安装程序。请按照默认值进行安装。4.4.2 手动配置网络当出现 Network autoconfiguration fails 时请不要惊慌，因为我们在步骤 3.2 配置的网桥 vmbr0 没有 DHCP 功能，故自动 DHCP 无法生效，此时我们需要指定网络配置。此处选择 Configure network manually，在后续页面输入步骤 3.2 中提到的 10.154.46.2/24。此处的 Name server address 应该为步骤 1.2.1 中提到的 192.168.1.1。后续配置不是特别复杂，在此按下不表。（注意：需要手动配置软件包源为 China 以加快后续的安装速度）KVM 虚拟机安装大功告成。五、创建 LXC 虚拟机5.1 下载镜像单击节点下的 local，选择 CT模板，单击上方的“上传”（如果本地有镜像的话）或“从 URL 下载”下载相应的镜像。适用于 ARM64 的 LXC 镜像可以在 https://uk.lxd.images.canonical.com/images/ 找到，本章以 Debian 11 为例。将镜像的 URL 粘贴到文本框后单击右边的“查询网址”，待文件名成功显示后修改文件名为方便辨识发行版名称和版本的格式，然后单击下方的“立即下载”按钮。下载过程同样将在后台进行，进度也将被实时打印。5.2 创建 CT镜像下载完成后，单击右上角的“创建CT”，弹出相关对话框。“密码”（需要“确认密码”）和“SSH 公钥”（可以通过下方的“加载SSH密钥文件”按钮载入）任选其一设置即可。“存储”选择 local，“模板”选择在步骤 5.1 中下载的模板；单击对话框底部的“下一步”；随后的“磁盘大小 (GiB)”和“内存 (MiB)”请按需选择，其他配置建议默认。“IPv4/CIDR” 填写步骤 3.2 中提到的 10.154.46.3/24，“网关 (IPv4)”填写 步骤 3.2 中提到的 10.154.46.1，其他内容保持默认；单击在步骤“确认”下方的“完成”按钮以开始创建 LXC 容器。5.3 开机开机方法与 KVM 相同，单击右上角的“启动”按钮，再单击右方的“控制台”即可直接进入已经安装完成的容器。终。鸣谢https://forum.proxmox.com/threads/how-to-run-pve-7-on-a-raspberry-pi.95658/https://www.fmqcloud.com/archives/pve.htmlhttps://wenqixiang.com/linux-wireless-configuration-in-terminal-command-line/https://www.bitpi.co/2015/02/11/how-to-change-raspberry-pis-swapfile-size-on-rasbian/https://blog.csdn.net/weixin_34085658/article/details/92968838https://www.bachmann-lan.de/proxmox-ve-auf-dem-raspberry-pi-4-installieren/