金百达内存条关闭灯光

软件居然是客服发出来的 https://share.weiyun.com/N2DQLFTY, KINGBANK RGB Control Software,没能在互联网上搜到

Limit Client IP Ranges for Cloudflare API Token

为了缩小 API 令牌泄露后的影响范围,只允许部分 IP 地址段使用某 Token 访问 Cloudflare API 的设置是很有必要的。考虑到我这的 IPv4 和 IPv6 环境,配置有几个注意点:

  • 允许 183.195.48.0/22,这是当前中国移动网络出口的 IP 所属 AS24400 的 CIDR,应对未来出口 IP 发生变化,可以通过访问 https://ipv4.gdt.qq.com/get_client_ip 查询当前 IP,然后查询 ASAP 信息
  • 允许 2409:8a1e:6940::/44,这是当前 IPv6 网段,用 curl -6 ip.network 获取再查询 AS 信息

为 Windows RDP 申请 Let’s Encrypt 证书

Windows 远程桌面连接配置证书 之后一段时间,我计划从私有 PKI 切换到公共的,毕竟使用 DNS-01 验证方式也不需要暴露内网环境。

In Debian WSL Environment
sudo apt install python3-certbot-dns-cloudflare
 
cat > ~/.secrets/certbot/cloudflare.ini < EOF
# Cloudflare API token used by Certbot
dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567
EOF
 
chmod 600 ~/.secrets/certbot/cloudflare.ini
 
cat >> /etc/letsencrypt/cli.ini < EOF
# Use ECC for the private key
key-type = ecdsa
elliptic-curve = secp256r1
 
# To register with the specified e-mail address
email = enihsyou@gmail.com
 
# Automatically agree to the terms of service of the ACME server
agree-tos = true
no-eff-email = true
EOF
 
sudo certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini \
  -d windows-vm.lan.kokomi.site
  
sudo openssl pkcs12 -export -out windows-vm.lan.kokomi.site.p12 \
  -in /etc/letsencrypt/live/windows-vm.lan.kokomi.site/fullchain.pem \
  -inkey /etc/letsencrypt/live/windows-vm.lan.kokomi.site/privkey.pem

得到 P12 之后操作就和之前一致了,也可以参考 Using Let’s Encrypt to secure Windows Remote Desktop connections - Server - Let’s Encrypt Community Support

终端中的 Vim 显示方形的光标

我纳闷为什么在 gVim / Zed / Obsidian 中能显示方块形式的光标,而 Windows Terminal 中却任何模式下都是竖线光标。
一个是 配置文件 / 默认值 / 外观 / 光标 / 光标形状 的设置决定了默认情况下长什么样
另一个是这里 How do I change my cursor?? : r/vim 提到的 termcap-cursor-shape

.vimrc
if &term =~ 'xterm' || &term == 'win32'
    "  1 = blinking block,        2 = steady block
    "  3 = blinking underline,    4 = steady underline
    "  5 = blinking vertical bar, 6 = steady vertical bar
    let &t_SI = "\e[5 q"   " cursor in insert mode
    let &t_EI = "\e[2 q"   " cursor in normal mode
    let &t_SR = "\e[3 q"   " cursor in replace mode
    let &t_ti .= "\e[2 q"  " cursor when vim starts
    let &t_te .= "\e[0 q"  " cursor when vim exits
endif

让 DNSmasq 响应 DHCPv4 主机的 IPv6 地址

在本地网络中部署 IPv4 & IPv6 双栈协议,有一个头疼的问题就是 DNSmasq 虽然会响应主机名的 DNS 查询,但只会返回 IPv4 地址。
说起来也符合逻辑,因为 IPv6 在路由器设置为 passthrough 模式后,客户端一般会采用 SLAAC 模式生成若干个只有自己知道的 IPv6 地址,并且出于隐私原因不对外宣告。

在实际使用中,域名肯定比 IP 地址要来得好记,必然涉及到 DNS 解析。

  • 场景一:因为中国移动的网络限制,只有 IPv6 网络栈可以直连,在 enihsyou.synology.me 配置的 DDNS 就只能注册 AAAA 记录。因为不论 A 注册 WAN 或者 LAN 地址,在户外以 IPv4 优先的访问都会被阻断。
    在局域网环境下 enihsyou.synology.me 会解析为 DDNS 注册的 IPv6 地址,有个服务只支持 IPv4 地址,所以得给这个域名再注册一条 A 地址。

  • 场景二:Synology 的 NFS 权限 当分配给主机时 *.lan.kokomi.site,客户端发起 mount -t nfs enihsyou.synology.me:/volume2/alist /root/nfs 请求,在服务端会发起 PTR 请求根据来源 IP 反查域名来判断主机是否在范围内。
    现在都是 IPv6 优先,服务端向上游 DNS 查询,等待 5s 失败,再重试几次才会退到 IPv4 模式。虽然最后都能成功,但速度太慢了。

sudo tcpdump -n udp port 53
22:07:30.440844 IP 192.168.9.2.43099 > 192.168.9.1.53: 35549+ PTR? 1.d.0.9.5.9.e.f.f.f.d.0.b.1.e.1.0.d.6.3.0.4.9.6.e.1.a.8.9.0.4.2.ip6.arpa. (90)
22:07:35.441613 IP6 2409:8a1e:6940:36d0:211:32ff:fe67:1865.60580 > 2409:8a1e:6940:36d0::1.53: 35549+ PTR? 1.d.0.9.5.9.e.f.f.f.d.0.b.1.e.1.0.d.6.3.0.4.9.6.e.1.a.8.9.0.4.2.ip6.arpa. (90)
22:07:40.444699 IP 192.168.9.1.53 > 192.168.9.2.43099: 35549 ServFail 0/0/0 (90)
22:07:40.444739 IP6 2409:8a1e:6940:36d0::1.53 > 2409:8a1e:6940:36d0:211:32ff:fe67:1865.60580: 35549 ServFail 0/0/0 (90)
22:07:40.444892 IP 192.168.9.2.60456 > 192.168.9.1.53: 35549+ PTR? 1.d.0.9.5.9.e.f.f.f.d.0.b.1.e.1.0.d.6.3.0.4.9.6.e.1.a.8.9.0.4.2.ip6.arpa. (90)
22:07:45.449984 IP6 2409:8a1e:6940:36d0:211:32ff:fe67:1865.35394 > 2409:8a1e:6940:36d0::1.53: 35549+ PTR? 1.d.0.9.5.9.e.f.f.f.d.0.b.1.e.1.0.d.6.3.0.4.9.6.e.1.a.8.9.0.4.2.ip6.arpa. (90)
22:07:50.448633 IP 192.168.9.1.53 > 192.168.9.2.60456: 35549 ServFail 0/0/0 (90)
22:07:50.448660 IP6 2409:8a1e:6940:36d0::1.53 > 2409:8a1e:6940:36d0:211:32ff:fe67:1865.35394: 35549 ServFail 0/0/0 (90)
22:07:50.453189 IP 192.168.9.2.54055 > 192.168.9.1.53: 40525+ PTR? 17.9.168.192.in-addr.arpa. (43)
22:07:50.454052 IP 192.168.9.1.53 > 192.168.9.2.54055: 40525* 1/0/0 PTR Intel-7700K-LAN.lan.kokomi.site. (88)
22:07:50.454233 IP 192.168.9.2.54685 > 192.168.9.1.53: 63975+ A? Intel-7700K-LAN.lan.kokomi.site. (49)
22:07:50.454251 IP 192.168.9.2.54685 > 192.168.9.1.53: 12024+ AAAA? Intel-7700K-LAN.lan.kokomi.site. (49)
22:07:50.454916 IP 192.168.9.1.53 > 192.168.9.2.54685: 63975* 1/0/0 A 192.168.9.17 (65)
22:07:50.454933 IP 192.168.9.1.53 > 192.168.9.2.54685: 12024 0/0/0 (49)

解决这些需求有一种方法是 split-horizon DNS,只需要加一行就能在公共 DDNS 注册的 AAAA 地址上额外返回一条 A 地址

/etc/dnsmasq.conf
# additional A record on top of DDNS AAAA record
host-record=enihsyou.synology.me,192.168.9.2
效果展示
$ for t in A AAAA; do dig enihsyou.synology.me $t +noall +answer; done
enihsyou.synology.me.   0       IN      A       192.168.9.2
enihsyou.synology.me.   1       IN      AAAA    2409:8a1e:6940:36d0:211:32ff:fe67:1865

但我更希望能由 DNSmasq 在 DHCP 阶段自动化免管理地完成,不只限于 DDNS 注册的公有域名,局域网域名也给予 AAAA 响应。
之前尝试过多次都失败了,最近打算再试一次居然成功了。配置起来很简单只需要一行。

/etc/dnsmasq.conf
# derive hostname for IPv6 SLAAC address registered via DHCPv4
dhcp-range=::,constructor:br0,ra-names
效果展示
$ dig enihsyou-nas any +noall +answer
enihsyou-nas.           0       IN      A       192.168.9.2
enihsyou-nas.           0       IN      AAAA    2409:8a1e:6940:36d0:211:32ff:fe67:1865

之前失败的原因应该是我写了 dhcp-range=lan,::,constructor:br0,ra-names,前面的 lan 是 tag 部分,历史兼容问题 可以不写成 tag:lan。本来想的是和同文件写在前面的 dhcp-range=lan,192.168.9.64,192.168.9.127,255.255.255.0,87400s 匹配,应用到叫 lan 的标签上。现在想想完全是错误的,如果这么写,实际上是给这部分 分配 标签。

节点 hostname 变更后 /etc/pve 目录清空

事情的起因是我在修改 DHCP 的静态绑定表,把之前分配给运行 Proxmox 主机的 MAC 地址绑定的主机名从 pve 修改(还原)到 Intel-7700K-LAN 了,本意是区分多个主机。
但修改后重启 PVE 主机后直接无法登录😐 具体表现是:

  • IP 地址能 ping 通,可 8006 端口管理网页无响应
  • SSH 原先用公钥验证就行,现在被提示要求密码登录,即便输入正确密码也会提示因错误次数过多拒绝登录

平常都是密码管理器填充的,直接键盘连接到主机上深感 root 密码太长难以输入,最后放弃。用 github.com/enihsyou/netboot.xyz 网络启动了一个急救镜像终于登录上用 passwd 改了密码。查看日志有这么些内容:

journalctl
-- Boot 03387a9a2a7749bdbff339e7a710408d --
---8<---
11月 07 21:05:40 pve systemd[1]: Starting pve-cluster.service - The Proxmox VE cluster filesystem...
11月 07 21:05:51 pve pmxcfs[1113]: [main] crit: Unable to resolve node name 'pve' to a non-loopback IP address - missing entry in '/etc/hosts' or DNS?
11月 07 21:05:51 pve systemd[1]: pve-cluster.service: Control process exited, code=exited, status=255/EXCEPTION
11月 07 21:05:51 pve systemd[1]: pve-cluster.service: Failed with result 'exit-code'.
11月 07 21:05:51 pve systemd[1]: Failed to start pve-cluster.service - The Proxmox VE cluster filesystem.
---8<---
11月 07 21:06:02 pve pveproxy[1296]: /etc/pve/local/pve-ssl.key: failed to load local private key (key_file or key) at /usr/share/perl5/PVE/APIServer/AnyEvent.pm line 2150.

事后总结我的这个故障由好几个原因直接间接导致的:

  1. 主机使用静态 IP 地址,而不是 DHCP
    采用静态地址这本不是什么问题,是 PVE 默认的安装方式,也是建议的方式。但其他主机就不知道主机名和 IP 的关系了,需要结合 hosts 文件。

  2. /etc/hosts 未包含自身主机名解析记录
    不记得是否自己改的,新安装的会有一条 192.168.x.x pve_hostname 的记录,可我的 hosts 文件中只有 localhost 的解析记录。缺少解析记录就会 ping: pve: Name or service not known ,这下自己都不知道自己的 IP 地址了。

  3. /root/.ssh/authorized_keys 文件是个指向 /etc/pve/priv/authorized_keys 的链接
    官方文档说 the root user’s authorized_keys file gets linked to /etc/pve/priv/authorized_keys, merging all authorized keys within a cluster,我新装了个 PVE 也验证了这个事实。这个系统设计是方便在集群中同步公钥信息,因为 The pmxcfs mountpoint of /etc/pve - free-pmx 目录是虚拟的。
    甚至系统还会自动改写已经存在的文件,重新创建这个链接。

  4. /etc/pve 目录为空
    但巧就巧在, DHCP 的主机名修改之后,这个目录空了。从上面的日志也能看出,解析不到主机名就无法确定自己是哪个节点,就没法选择正确的 node 虚拟目录来挂载,authorized_keys 文件也就不存在了。

  5. SSHD 设置的最大尝试次数太小且拒绝密码登录
    之前参照最佳实践 smallab-k8s-pve-guide/G009 - Host hardening 03 ~ SSH key pairs and sshd service configuration.md at main · ehlesp/smallab-k8s-pve-guide 限制了最大尝试次数 MaxAuthTries 3。然而在 authorized_keys 不存在的情况下,ssh-agent 内的和本地 ~/.ssh/id_* 文件数量加起来直接超过了 3,一下打到次数上限,不让输入密码。再加上默认的 PermitRootLogin prohibit-password,即便不用私钥也不允许使用密码登录。

  6. 主机上只有 root 用户
    也就没有其他远程登录手段了。


基本能定位问题了,在 Passwordless SSH can lock you out - free-pmx 也已经有人发现这个链接 authorized_keys 的设计问题并给了很多相关信息(网站有很多非常高价值的内容,建议阅读)。怎么改进呢,有一些可做的和该做的,考虑到我的实际计划这么做:

  1. 创建第二个具有 sudo 权限的用户
    至少还能远程登录上去对吧。这个用户关闭了密码,有静态的 authorized_keys 文件

  2. 使用 DHCP 获取 IP 地址和主机名
    参考 DHCP setup of a single node - free-pmx 指南,我在路由器上设置了 MAC 和 IP 的静态绑定关系。
    不过我这里想要个 IP 多分配几个 hostname,可以 1. 用 host-record 解析 A 地址的 2. 用 cname 记录别名的,我这里用第二种以支持 让 DNSmasq 响应 DHCPv4 主机的 IPv6 地址

/etc/dnsmasq.conf
dhcp-host=aa:bb:cc:dd:ee:ff,192.168.9.17,Intel-7700K-LAN
cname=pve,pve.lan.kokomi.site,Intel-7700K-LAN

sudo 提示无法解析主机

在我调试上面 DNS 的问题时,有过一段把 pve 主机解析记录清空的时间,这期间 sudo 居然会卡住并返回错误信息

$ sudo ls
sudo: 无法解析主机:pve: 名称或服务未知

sudo 有个能力是按主机名分配权限 User Host=(RunAsUser:RunAsGroup) Commands,需要知道 hostname 对应的 IP。

这个错误还挺有意思,没有 sudo 能力也就没法改 /etc 目录的文件。

然后绝对不能改 /etc/hosts 添加一行 127.0.1.1 pve,否则会回到 节点 hostname 变更后 /etc/pve 目录清空 的表现。

正确的做法是把解析弄正确来,要么静态绑定,要么 DNS 配置好。

Synology NFS 共享设置用户权限

搞不懂为什么 Synology WebUI 上只运行为 Squash 选择无映射或者将 root 映射为 guest 等几个选项,我想要的是将用户映射为当前用户,有个笨办法

当前文件是这样,1025 是 guest 用户的 UID

/etc/exports
/volume2/alist  *.lan.kokomi.site(rw,async,no_wdelay,root_squash,insecure_locks,sec=sys,anonuid=1025,anongid=100)

直接替换 uid 的部分

sudo sed -i "s/anonuid=$(id guest -u)/anonuid=$(id -u)/g" /etc/exports
sudo exportfs -a