分类: Linux & homelab

  • Mikrotik CCR2004-1G-2XS-PCIe 实际CPU型号及拆解分析

    Mikrotik CCR2004-1G-2XS-PCIe 实际CPU型号及拆解分析

    时效性提醒:本文首次编写发布于4 年前。

    CCR2004-1G-2XS-PCIe时Mikrotik在2022年初发布的“网卡形态的路由器”,是一个网卡+路由器二合一的产品。

    关于CCR2004-1G-2XS-PCIe的CPU型号,Mikrotik的宣传手册上写的是AL32400,这与其他CCR2004系列路由器上的型号一致。但官网产品页面中写的却是AL52400,让人困惑,RouterOS中也没显示其CPU型号。

    这周正好我订的那个也到货了,直接拆开一探究竟,发现确实是AL32400,后缀1700,应该表示1.7GHz频率版本,与其他CCR2004系列路由器一致,同样这个CPU也被用在了QNAP的一款NAS上。其内核规格为4核A57(ARM Cortex-A57 1.7GHz x4),A57是A72的上一代架构,与A53、A55不同,A57是同属于A7x系列的高性能核,因此可以认为AL32400的CPU性能与树莓派4的BCM2711较为类似,后者为4核A72,1.5GHz或1.8GHz(新版arm_boost),对于路由器而言性能比较不错。

    下面为详细的拆解图(点击图片查看原始尺寸)

    说是拆解,但其实这就是一个PCIe卡,拆下PCIe档片后,在拧下背面的5个螺丝拆下散热器,即可露出全貌:

    背面:

    CPU,或者说SOC,型号AL32400(-1700):

    拆掉散热风扇,其规格为12v 0.13A 4线,直径44mm,孔距39mm,厚度约1cm:

    PCB全貌:

    可以看出其布局和普通的高速网卡是非常类似的,不同的是中央的芯片是一个SoC,而不是网卡芯片,并且上方还有其内存,内存大小为4GB,但内存颗粒为5个,可能是有ECC。

    关于其实际使用的体验,我会在后续发布新的文章。

    其他附属芯片

    SoC左侧,SFP28接口周围

    红色:德州仪器TI DS250DF410,25Gbps 多速率 4 通道重定时器,以太网重定时器、转接驱动器和多路复用器缓冲器

    具有集成信号调节功能的四通道多速率重定时器,最大速度25.8Gbps,支持协议:IEEE802.3bj, 100GbE, Infiniband EDR, OIF-CEi-25G-LR/MR/SR/VSR, QSFP28, CFP2/CFP4, CDFP

    DS250DF410 是一款具有集成信号调节功能的四通道多速率重定时器。该器件用于扩展有损且存在串扰的远距离高速串行链路的延伸长度并提升稳定性,同时实现不高于 10-15 的比特误码率 (BER)。

    黄色:德州仪器TI CDCM61002,1:2 超低抖动晶振时钟发生器

    CDCM61002是一种高度通用的低抖动频率合成器,可以产生两个低抖动时钟输出,可以在低压正发射器耦合逻辑(LVPECL)、低压差分信令(LVDS)或低压互补金属氧化物半导体(LVCMOS)输出之间进行选择,来自低频晶体或LVCMOS输入,用于各种有线和数据通信应用。CDCM61002具有板载PLL,只能通过控制引脚轻松配置。整体输出随机抖动性能小于1ps,RMS(从10 kHz到20 MHz),使该设备成为SONET、以太网、光纤通道和SAN等苛刻应用程序的完美选择。CDCM61002有一个小体积的32pin、5mm×5mm QFN封装可供选择。

    绿色:Atheros AR8035 集成10/100/1000千兆以太网收发器

    AR8035是Atheros的第4代 单口 10/100/1000 Mbps Tri-speed Ethernet PHY,支持RGMII接口的MAC。

    紫色:74HC595,串行输入、并行输出的8位移位缓存器

    蓝色:NT5AD512M16A4-HR,DDR4 8Gb(1GB)内存颗粒,支持速率:2933、2666、2400

    SoC右侧

    红色:铠侠(原东芝)Kioxia TC58BYG0S3HBAI6,Built-in ECC SLCNAND,1Gb(128MB)SLC NAND 闪存,1.8v,x8位宽

    黄色:意法半导体ST STM32F030C6T6,主流ARM Cortex-M0超值系列MCU,具有32 KB Flash和48 MHz CPU

    绿色:德州仪器TI TPS51362,具有超低静态电流的 3V 至 22V、10A 同步降压转换器,输入3~22v,输出0.6v ~ 2v

    蓝色:德州仪器TI TPS548B22 具有差分遥感功能的 1.5V 至 18V、25A 同步 SWIFT™ 降压转换器,输入1.5~18v,输出0.6v ~ 5.5v

    紫色:德州仪器TI SN74GTL2003 (丝印GK2003)3片,双向电平转换器,双向0.95v~5v

    棕色:LITE-ON LSP5523,3A 27V 同步降压转换器,输入4.5v~27v,输出0.925v~0.8Vin

    白色:意法半导体ST M24C64-F(丝印464FT),64-Kbit(8KB)串行I2C总线EEPROM

    背面

    红色:winbond W25Q128JWS,128Mb(16MB) SPI Flash,128M-bit Serial Flash Memory with uniform 4KB sectors and Dual/Quad SPI

    黄色:德州仪器TI TCA9546A(丝印PW546A),具有复位功能的低压 4 通道 I2C 和系统管理总线 (SMbus) 开关

    蓝色:德州仪器TI TCA9555 (丝印PW555),具有中断、弱上拉和配置寄存器的 16 位 1.65V 至 5.5V I2C/SMBus I/O 扩展器

  • “双网线”旁路由之“完美”解决IPv6和千兆瓶颈问题

    “双网线”旁路由之“完美”解决IPv6和千兆瓶颈问题

    时效性提醒:本文首次编写发布于4 年前。

    旁路由是一种homelab常见的需求,主路由用硬路由确保稳定,比如用Mikrotik的RouterOS路由器作为主路由,旁路由使用OpenWrt作为软路由,实现广告过滤和隧道等高级功能,这些功能往往都无法硬件加速,需要消耗大量CPU完成,x86的高性能软路由是很合适的选择。比起使用二级路由,可以减少在旁路由上的一次NAT(仅对于IPv4),提高利率,也便于主路由进行管理。

    本文提出了一种整活之余有些实用性的特殊旁路由方案,或者也可称为IPv4不NAT的二级路由方案。

    本文环境信息:

    • 主路由RouterOS,旁路由OpenWrt,需要主路由具有3个网口(对于硬路由很容易满足),旁路由至少具备双网口,假设其都为千兆网口;
    • 为了使用IPv6二级路由,运营商给的IPv6前缀至少需要为/63;
      • (常见的/56、/60都可满足,但如果给的是/64,虽然或许也能实现功能,但需要不同的设置)
    • 主内网(全功能)网段:192.168.10.0/24,辅助内网(备用/直连)网段:192.168.88.0/24

    0x01 传统旁路由设置

    传统的旁路由设置只针对IPv4,旁路由只需要一根网线连接内网和旁路由的LAN,旁路由的WAN空置。主路由LAN口IP为192.168.10.1/24,旁路由LAN口IP为192.168.10.2/24,在内网DHCP服务器设置中设置网关为192.168.10.2(DHCP服务器可运行在主路由或旁路由上,但只能有一个),然后在旁路由中设置网关为192.168.10.1。

    这样所有客户端都会使用192.168.10.2作为网关,将出口的IP封包发到旁路由上,旁路由因为开启了ip_forward(路由器都会开启),会对这些封包进行转发:由于在旁路由上设置了192.168.10.1作为网关,于是旁路由就会将这些封包直接转发到192.168.10.1的主路由上(传统旁路由的关键就在于,由于是LAN to LAN转发,所以不会匹配防火墙中LAN to WAN的masquerade规则,即不会进行我们常说的路由器NAT)。由于封包在旁路由上进行了转发,隧道软件就可以通过防火墙NAT表中的规则对这些封包进行处理(比如redirect和tproxy),满足我们使用旁路由的需求。

    在一般链接的回程(下载)时,经过主路由NAT后的入口封包的目标IP为客户端的内网IP,直接通过交换机到达客户端,无需再经过旁路由,所以理论上是可以对外网跑满双向千兆的。

    0x02 传统旁路由的问题

    第一个问题就是IPv6,IPv6没有单独的网关选项,对于SLAAC而言(至今Android只支持SLAAC,不支持DHCPv6),如果一台机器进行了RA(路由宣告),让客户端获得了前缀,那么客户端就会认为其是网关。由于公网IPv6前缀由PPPoE获得,所以必然是主路由进行RA,也就自动成为了所有客户端的IPv6网关,无法再指定旁路由为网关。

    一个常规的IPv6 RA包

    从另一个角度讲,IPv6要求所有设备(Node)必须从Router和Host这两种角色中二选一,而旁路由就恰恰是一个设备既作为Router,又作为Host。

    实际上,IPv6也没必要使用旁路由,由于通常情况下IPv6不使用NAT,路由器在这里做的仅仅是转发而已,我们可以放心的使用IPv6二级路由。

    另一个问题是千兆瓶颈的问题,这个千兆瓶颈只对于非直连流量(比如隧道流量)存在,即经过隧道的流量,上行和下行的速度总和无法超过1Gbps,这是因为隧道流量返程也需要经过旁路由。对于直连流量而言,如文章第一节所述,由于返程不需要经过旁路由,所以不存在千兆瓶颈,上下行速度总和可以达到2Gbps,即跑满。不过这个问题通常不会带来影响(啥公网隧道能千兆对等),但若能一并解决了也好。

    0x03 本文的魔改二级路由方案

    为避免混淆,以下使用「软路由」代指我们原本逻辑中的旁路由(即那台OpenWrt的软路由)

    这是一种双网口、IPv4旁路由+IPv6二级路由的方案,这种方案实际上更接近于标准的二级路由,但通过一些魔改,让IPv4变成旁路由模式。

    拓扑如下:

    图中主路由bridge代表主内网,具有软路由提供的高级功能;bridge_alt代表辅助内网,此处仅用于软路由与主路由间的通信,也可接入一个交换机作为直连/备用内网,其不具有软路由提供的高级功能,但能在软路由故障时继续提供标准(直连)的上网功能。如果主路由上不需要扩展辅助内网,也可不为辅助内网创建bridge,使用一接口代替。

    这里只列出了IPv4部分的参数。IPv6部分同标准的IPv6二级路由,但要注意,IPv6的RA和DHCP Server要运行在bridge_alt接口上(见下文)。

    如果你的主路由的具有硬件交换机且还有很多未用端口,那便可以省掉“主内网 交换机”,这样旁路由就是通过两根线连接了主路由,但并不会成环。

    下面开始IPv4部分的详细配置介绍:

    在主路由上,基于路由器模式的出厂设置(如Home AP Dual等),进行以下修改:

    1. 首先新建个Bridge,名称为“bridge_alt”:

    2. 添加需要的接口到bridge_alt中,这里我除了必要的有线端口ether1外,还添加了机器自带的两个wlan,作为备用网络热点(主内网的wlan由独立的AP提供):

    3. 为bridge设置IP:192.168.10.1/24;为bridge_alt设置IP:192.168.88.1/24

    4. 为bridge_alt设置分配192.168.88.0/24的DHCP服务器;如果主内网也由主路由提供DHCP服务,则为bridge设置分配192.168.10.0/24的DHCP服务器,并设置网关为192.168.10.2(下图未展示):

    5. 在Interface list中,将bridge_alt设置为LAN

    然后将软路由WAN口与bridge_alt的接口通过网线连接(本文中为ether0),然后你应该能看到软路由的WAN口从主路由获取了IP:

    (你可能会疑惑:这不是二级路由的状态吗?别急,下面我们就关闭它的NAT)

    下面我们在软路由中进行设置(类似的,基于OpenWrt的默认设置)

    6. 设置软路由的LAN口IP为192.168.10.2;如果在主路由上设置了主内网的DHCP服务,则要关闭软路由LAN的DHCP服务(下图未展示)

    7. 最为关键的一步,到防火墙中关闭WAN区域的“IP动态伪装”,也就是masquerade,即我们常说的NAT:

    然后将根据拓扑图,将软路由的LAN主路由的bridge主内网的设备都接到交换机上,IPv4的设置就完成了。

    关于IPv6的配置,和标准的IPv6二级路由相似,只是RA和DHCPv6 Server的接口设置有所不同,这部分网上有非常多很好的教程,比如:https://wu.renjie.im/blog/network/ros-dhcpv6/zh-cn/,下面仅写出在本文设置中需要注意的点。

    主路由上,IPv6的地址设置(包括了RA)和DHCPv6的设置中,需要在且仅在bridge_alt接口上进行设置,而不应对bridge进行任何设置。换句话说,在IPv6下,主路由不会使用主内网bridgebridge的IPv6 RA和路由完全由软路由负责,bridge作为bridge_alt的下级路由,形成标准的IPv6二级路由。

    0x04 后记

    本文的方法与普通二级路由的最大区别,其实就是对于IPv4:①在二级路由器(本文中的软路由)上关闭了LAN to WAN的masquerade NAT;②在主路由上连通了二级路由的LAN。从而达到了类似旁路由的效果(旁路由就是为了少一层NAT)。

    至于为什么可以在关闭二级路由器的NAT,不妨思考一下我们为什么在路由器上需要NAT:如果我们有一个连接上级网络的普通路由器,并关闭了NAT,那么我们发出的包其实还是可以正常的被送到远端的服务器,但由于包中的源IP地址还是我们客户端的内网IP地址,无法通过我们的内网IP向我们回应(其实通常直接就不会被远端服务器的防火墙接受)。而masquerade NAT就是一种特殊的src nat,其永远都会使用路由器本机地址,作为IP封包源地址的替换,从而让远端服务器的回应包能被正确发到路由器上,再由路由器转发给客户端。

    但在本文的方法中,首先在我们的包通过二级路由器直接转发给主路由后,由于主路由是带有NAT的,远端服务器的回应包会正常的到达主路由,然后主路由在转发回应包时,由于我们配置了上面的,回应包可以直接发给客户端,无需经过二级路由器,也就无需二级路由器的NAT,正常的完成了一次往返的通信。

    最后,本文的方法更多是整活向的。无论是直接使用单路由,还是普通的二级路由,甚至用传统旁路由方式并直接关闭IPv6,其实也没什么不好(毕竟2022年目前ISP和CDN的优化还是针对IPv4为主,很多地方依然是“关闭IPv6以提升上网体验”)。不过homelab的一大乐趣之一就是折腾各种非标准的方案和配置,本文也算是提出了一种旁路由+正常IPv6的解决方案,如果各位读者认为有改进的地方或漏洞,也欢迎在下面留言。

  • RISC-V GNU Toolchain 开发环境搭建Quickstart

    RISC-V GNU Toolchain 开发环境搭建Quickstart

    时效性提醒:本文首次编写发布于5 年前。

    完整的开发环境需要构建gcc、binutils、glibc等组件,以及qemu、gdb等辅助工具,他们都分布在不同的repo中。比起手动配置,一种更简单的方法是使用https://github.com/riscv-software-src/riscv-gnu-toolchain,其已通过submodule的方式引入好了这些组件。

    0x00 环境配置

    这里使用最常见的Ubuntu 20.04作为演示,其他环境可以参考riscv-gnu-toolchain中的README。

    sudo apt-get install autoconf automake autotools-dev curl python3 libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev

    如果需要跑测试,还要安装expect软件包

    然后clone该仓库:

    git clone https://github.com/riscv/riscv-gnu-toolchain
    cd riscv-gnu-toolchain

    如果你正在参与工具链中的开发/测试,你或许希望切换其中的一些组件到一些正在进行开发工作的下游仓库中,比如下面是一个切换riscv-gcc到https://github.com/WuSiYu/riscv-gcc仓库的例子:

    cd riscv-gcc
    git submodule update .   #如果未初始化submodule(该目录为空),则执行
    git remote add wu git@github.com:WuSiYu/riscv-gcc.git
    git remote update
    git checkout --track wu/riscv-gcc-experiment   #切换到你需要的分支

    其他组件同理

    0x01 编译

    在riscv-gnu-toolchain目录下使用./configure进行配置,详细参数含义可以参考./configure -h,multilib有时会导致问题,所以建议一次只编译一种架构,存放在不同的prefix里,一种保险的写法是:

    ./configure --prefix=/whatever/you/want/ --with-arch=<ARCH> --with-abi=<ABI> --with-multilib-generator="<ARCH>-<ABI>--"

    替换<ARCH>为你需要的架构,如:rv32i、rv32gbk、rv64g

    替换<ABI>为你需要且与架构匹配的ABI,如:ilp32、ilp32d、lp64d

    然后执行make newlib编译newlib的工具链(裸机程序),或者执行make linux编译产生linux可执行文件的工具链。通常我们测试工具链的话使用newlib版就可以。

    同时你或许希望记录时间、多核编译、记录输出,可以使用类似以下的指令:

    time make newlib -j<YOUR_CPU_CORE_COUNT> 2>&1 | tee build.log

    替换<YOUR_CPU_CORE_COUNT>为你的CPU线程数,比如你有一个10c20t的i9-10850k硅渣,就使用-j20

    然后你就可以使用你编译出的工具链了,比如/whatever/you/want/bin/riscv64-unknown-elf-gcc

    0x02 测试

    使用类似如下的指令进行测试

    make report-newlib SIM=qemu

    SIM=表示使用的测试程序运行环境,可选的值有qemu、gdb、spike

    备注:如果你使用qemu且需要自定义调用qemu程序时的命令行参数,可以编辑riscv-gnu-toolchain/scripts/wrapper/qemu/riscv64-unknown-elf-run脚本进行临时修改

  • 在Docker中的“完整”Ubuntu开发环境容器

    在Docker中的“完整”Ubuntu开发环境容器

    时效性提醒:本文首次编写发布于5 年前。

    尽管Docker/Podman容器的使用方式与虚拟机不同,但对于“开发环境”,我们还是倾向于将其当作虚拟机来使用,就如同物理机器一样。但全虚拟化的虚拟机(如kvm)还是会对性能有影响,尤其是对于I/O密集型应用,LXC/LXD应当是不错的选择,但实际上在“装机必备”的Docker上,也是能实现这样的功能。

    这是个Docker容器

    下方的Dockerfile就描述了一个这样的“完整”Ubuntu容器,其像标准Ubuntu一样由systemd作为init,并运行SSH服务器,以更方便的远程访问,或远程使用vscode remote。其还创建了一个普通用户,用户名、UID和GID可以与你宿主机上保持一致,以更方便的共享文件。

    Github Gist: https://gist.github.com/WuSiYu/bbee5788242bcb99b9acbe5257aae522

    FROM ubuntu:latest
    LABEL maintainer="SiYu Wu <wu.siyu@hotmail.com>"
    
    ENV DEV_USER=user
    ENV UID=1000
    ENV GID=1000
    ENV DEF_PASSWD=password
    ENV TZ=Asia/Shanghai
    ENV LANG=en_US.UTF-8
    
    RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && \
        yes | unminimize && \
        apt install -y systemd sudo openssh-server bash-completion zsh git curl vim && \
        addgroup --gid $GID $DEV_USER && \
        adduser --uid $UID --gid $GID --gecos "" --disabled-password $DEV_USER && \
        usermod -aG sudo $DEV_USER && \
        echo "$DEV_USER:$DEF_PASSWD" | chpasswd && \
        systemctl mask systemd-resolved.service && \
        echo "LANG=$LANG" > /etc/default/locale && \
        cp /usr/share/doc/util-linux/examples/securetty /etc/securetty
    
    CMD ["systemd"]
    

    在标准Ubuntu Docker镜像基础上,执行了以下操作:

    • 设置时区
    • 去“精简化”
    • 安装systemd、sudo、SSH服务器、bash自动补全和一些其他工具
    • 新建用户并赋予sudo权限
    • 禁用systemd-resolved.service,因为Docker已经为我们配置好了容器的DNS
    • 设置语言
    • 补全/etc/securetty

    使用示例

    为保证镜像的安全性(更新及时),未维护Docker Hub上维护镜像,请自行构建

    构建镜像

    sudo docker build -t devbox:v0.1 .

    启动镜像(非特权模式)

    需要赋予容器audit(审计信息)写入权限,否则容器的ssh、sudo等软件会工作不正常

    sudo docker run -d -it --cap-add AUDIT_WRITE --name devbox --publish 8022:22 --hostname devbox -v ./data:/data:z devbox

    启动镜像(特权模式)

    sudo podman run -it --name devbox --publish 8022:22 --hostname devbox -v ./data:/data --privileged devbox

    限制与可选操作

    首先此方法的“隔离型”不如lxc/lxd方式,哪怕是非特权模式,容器的audit信息也会被写入到host(若禁止则会导致容器工作不正常),大概是因为Docker本身就没有对此进行隔离。

    其次你会发现apt的软件包名的shell自动补全无法正常工作,这是因为ubuntu的官方docker镜像中禁用了apt的一些缓存功能,以避免在构建镜像时产生一些无用的缓存。考虑到容器性质的用途,此处保留了这个特性。如果你希望能正常使用软件包名自动补全功能,删除/etc/apt/apt.conf.d/docker-clean文件即可。

  • 或许能是Linux发行版的一种未来?Fedora Silverblue 34使用体验

    或许能是Linux发行版的一种未来?Fedora Silverblue 34使用体验

    时效性提醒:本文首次编写发布于5 年前。

    近日(2021.05)Fedora 34正式发布了,搭配开始使用新版本号的Gnome 40,但我们今天要谈的并不是“传统版”Fedora,而是Fedora Silverblue这个衍生版,你可能听说过Fedora CoreOS,而Fedora Silverblue便是其同类型的桌面版。

    对于Fedora Silverblue,官方的说法是“Fedora Silverblue is an immutable desktop operating system aimed at good support for container-focused workflows.”,你或许注意到了“immutable”,没错,这个系统最大的特点便是大部分系统目录树都是不可变的,它们通过OSTree的进行管理,这是一个“针对系统二进制文件的git”,也就是说你可以像用git一样随时对你的OS进行更新和回滚,你甚至可以在GRUB界面选择启动当前版本还是上一个版本的系统。

    而不可变的限制在于根目录下的大部分目录都是“只读”的,除了/var和下列被映射的目录:

    当然一个完全不可变的系统并不能当作日用系统使用,所以Fedora Silverblue有一个混合式的包管理系统,它没有dnf,但你可以使用rpm-ostree install xxx来将rpm软件包安装为ostree的layer,但代价是重启后生效(有一个试验性的rpm-ostree ex apply-live指令可以令其立即生效,但目前与toolbox有兼容性问题)。

                             +-----------------------------------------+
                             |                                         |
                             |       rpm-ostree (daemon + CLI)         |
                      +------>                                         <---------+
                      |      |     status, upgrade, rollback,          |         |
                      |      |     pkg layering, initramfs --enable    |         |
                      |      |                                         |         |
                      |      +-----------------------------------------+         |
                      |                                                          |
                      |                                                          |
                      |                                                          |
    +-----------------|-------------------------+        +-----------------------|-----------------+
    |                                           |        |                                         |
    |         libostree (image system)          |        |            libdnf (pkg system)          |
    |                                           |        |                                         |
    |   C API, hardlink fs trees, system repo,  |        |    ties together libsolv (SAT solver)   |
    |   commits, atomic bootloader swap         |        |    with librepo (RPM repo downloads)    |
    |                                           |        |                                         |
    +-------------------------------------------+        +-----------------------------------------+

    除了rpm-ostree的方式,安装桌面软件一般通过flatapk的方式,相比而言其更方便且无需重启即可生效。此外对于这两者都覆盖不到的情况,可以使用toolbox,用它创建一个传统fedora(或其他OS)的容器,其底层是podman(红帽的docker),但相比直接使用podman是要方便很多。

    体验

    Fedora Silverblue 34的安装与常规的Fedora类似,区别在于Fedora Silverblue的ISO并不是一个livecd,所以启动后直接就只有一个全屏的安装器界面,这里需要吐槽一下红帽系的anaconda安装器并不算好用,建议安装前先把目标磁盘清空或留好空闲空间。

    安装后进入桌面,观感与普通的Fedora Workstation并没有什么不同,自带的Gnome应用商店也对ostree进行了适配,可直接进行系统更新,但可供选择安装的软件数量很少,是个很小的flatapk源,更多软件还是要到flathub上去下载。

    在这个系统中你无法使用dnf这种常规的包管理系统,取而代之的是rpm-ostree,一些系统级的软件可以通过它来安装,但不一定能保证正常工作,比如安装cockpit目前就需要让cockpit-ws跑在容器里,直接安装目前会遇到问题。

    cockpit也有一个ostree插件,可以在里面进行软件更新和版本查看,功能比较简单:

    至于更一般的日常开发,可以都转移到toolbox中,这也是官方建议的“container-focused workflows”,毕竟以前每次折腾点新东西都需要往host系统里加一大堆依赖,想想还是挺强迫症的。

    toolbox是一个开箱即用的容器工具,和host系统整合的不错:(据说还可以在里面跑GUI程序)

    总结

    选择Fedora Silverblue或者类似的“immutable OS”有什么好处?目前看来主要是:系统更新/回滚方便,不会滚挂,安全性好。对于普通用户和企业用户这些可以算是很大的优点。

    对于专业的Linux用户这些可能意义不大,但确实也降低了维护成本;而代价是其不可变的特性又确实带来了很多额外的限制,但如果你不排斥“开发行为容器化”,这些限制也是可以克服的。

    我的观点是,这依然是一个不错的开发机系统:传统的发行版用久了总会让人感到“墒增”,尤其是你的系统是从之前的release一路升级而来,你很难回忆起你在一年前为了某个小问题对系统做了那些更改,而这可能又会在未来导致更多的你已经无法解决的小问题。解决它的一种出路便是容器化的工作流程,能让你把折腾都留在容器里,保持host系统的纯净性,而既然我们已经不再折腾host OS了,那为什么不干脆让它“immutable”而更方便管理呢?

  • Docker / Nextcloud (手动/自签名https + redis + 与samba等协同)完全体部署指南

    Docker / Nextcloud (手动/自签名https + redis + 与samba等协同)完全体部署指南

    时效性提醒:本文首次编写发布于5 年前。

    之所以用自签名或者手动设置证书,是考虑国内环境下家用宽带公网IP不开放80和443等Web端口,所以无法使用nginx-proxy这类自动设置Let’s Encrypt证书的容器(可手动使用Let’s Encrypt的DNS Challenge获得证书),如果是正常公网环境,自然用自动的更方便。

    关于docker hub上Nextcloud的容器,有官方版(nextcloud/nextcloud)和一些第三方版(比如接下来的linuxserver/nextcloud),官方版的默认功能比较单一,apache版仅提供一个HTTP的Nextcloud服务,fpm版更是需要其他的nginx容器来辅助,也默认也没有cron的功能。

    所以我比较倾向于使用linuxserver/nextcloud这个镜像,这个镜像本身就可以提供自签名的HTTPS,之后也可以方便的手动替换别的证书。并且这个镜像还自带了cron服务,无需再手动配置Nextcloud的cron,在小型系统上,一个nginx同时承担nextcloud+https的功能也更高效一些。

    为了让Nextcloud发挥最高效率,还需要MySQL和redis,下面给出我目前使用的docker-compose文件,和使用方法。以下操作在fedora server 33 + podman环境上测试无问题(podman是一个docker的替代品),请根据实际需要进行修改。

    version: "2.1"
    services:
      nextcloud:
        image: ghcr.io/linuxserver/nextcloud
        environment:
          - PUID=1000
          - PGID=1000
          - TZ=Asia/Shanghai
        volumes:
          - ./config:/config
          - ./data:/data
          # 如果你有其他路径下的文件数据需要让Nextcloud访问,添加在这里
          # 为了方便后续设置,请在容器内使用相同的路径,如:
          # - /srv:/srv
        ports:
          - 443:443
        restart: unless-stopped
    
      db:
        image: mariadb
        restart: unless-stopped
        command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
        volumes:
          - ./db:/var/lib/mysql
        environment:
          - MYSQL_ROOT_PASSWORD=1000%
          - MYSQL_PASSWORD=1000%
          - MYSQL_DATABASE=nextcloud
          - MYSQL_USER=nextcloud
    
      redis:
        image: redis:alpine
        restart: unless-stopped
        volumes:
          - ./redis:/data

    使用指南:首先创建一个目录,后续Nextcloud应用所有的文件和数据都会存放在此文件夹下,然后进入目录,创建好之后用了存放容器数据的文件夹:

    mkdir nextcloud
    cd nextcloud
    mkdir config data db redis

    将上面给出的docker-compose内容保存为docker-compose.yaml,然后创建并启动所有容器:

    docker-compose up -d      # 或podman-compose up -d

    接下来进入https://<your_host>/进行设置,注意不要用默认的SQLite,需要输入刚才mysql容器的配置,为了降低安装失败的概率,可以取消勾选“安装推荐的应用”:

    接下来启用redis,需要修改Nextcloud的配置文件(config/www/nextcloud/config/config.php),加入以下几行:

      'memcache.distributed' => '\\OC\\Memcache\\Redis',
      'memcache.locking' => '\\OC\\Memcache\\Redis',
      'redis' =>
      array (
        'host' => 'redis',
        'port' => 6379,
      ),

    最后,如果你有其他路径下的文件数据需要让Nextcloud访问,比如你有一个已有的samba共享,希望它与Nextcloud协同,并不影响原有的文件结构,并表现的和Nextcloud原生的文件一样,那么可以使用在Nextcloud用户目录下建立符号连接的方式:

    注:当然,如果你不想使用这种比较hack的方式,可以简单的通过Nextcloud自带的“外部存储”功能实现类似的效果,无须后续的操作,不过你的“外部存储”会和Nextcloud原生的文件表现地“略有差异”。

    首先修改Nextcloud的配置文件,允许符号链接(多用户场景下请注意可能的安全性影响),和一些其他配置:

      'localstorage.allowsymlinks' => true,        // 允许符号连接
      'filesystem_check_changes' => 1,             // 实时检测文件系统变化
      'quota_include_external_storage' => true,    // 打开这个可避免容量限额识别问题

    然后到Nextcloud用户的数据目录(data/<nextcloud_username>/files/),建立符号连接:

    ln -s /srv my_smb_share

    之后你可能还需要手动让Nextcloud执行一次文件扫描(视文件大小,可能会耗时较久):

    docker exec -it <your_nextcloud_container> occ files:scan --all

    然后就可以看到你新加进去的目录了:

    最后附上一张容器的资源使用情况:(那个xxxxxxxx-infra的容器大概是podman用来实现容器间网络绑定的)

    最后关于手机端数据同步,官方客户端在文件数量非常多的情况下可能会卡死,这是可以使用Nextcloud提供的Webdav服务配合第三方APP(如:安卓下的FolderSync)进行同步,甚至速度会更快。

  • Debian + cockpit-machines(kvm/libvirt) + omv 简易虚拟化 & NAS方案 避坑指南

    Debian + cockpit-machines(kvm/libvirt) + omv 简易虚拟化 & NAS方案 避坑指南

    时效性提醒:本文首次编写发布于5 年前。

    本文基于Debian buster(Debian 10),使用Debian的原因是因为可以叠加安装openmediavault(omv),作为原生NAS使用。

    本文编写于2021/2/27,由于cockpit等还在持续更新,请注意时效性。

    安装openmediavault

    在Debian上安装请参考官方指南(此处略):https://openmediavault.readthedocs.io/en/5.x/installation/on_debian.html

    也可以直接使用openmediavault的ISO安装基础系统。

    安装完成后访问http://<your_ip>:80使用omv的控制面板,默认用户名:密码admin:openmediavault

    安装cockpit和cockpit-machines

    请考官方指南:https://cockpit-project.org/running.html#debian

    其中添加buster-backports建议使用国内的、和你已有软件源一致的,可以参考清华源的配置指南

    然后安装cockpit本体:

    sudo apt install -t buster-backports cockpit

    记得要使用buster-backports源安装相关软件包(下同),否则版本会比较旧,影响使用。

    还需要手动安装cockpit-machinesqemu-kvm软件包,安装虚拟机功能;同时也建议安装cockpit-networkmanagercockpit-storaged等cockpit的其他组件。

    安装tuned可以启用主页上的“Performance profile”功能。

    安装完成后访问https://<your_ip>:9090使用cockpit的控制面板,用户名密码同你的UNIX账户

    安装virtinst并更新os-info-db

    需要安装virtinst来支持cockpit-machines的虚拟机创建功能

    sudo apt install -t buster-backports virtinst

    此时你可能会发现安装页面的操作系统列表依然不全(比如没有Ubuntu 20.04),这是因为debian的os-info-db包已经两年没有更新了。

    请参考官方指南(此处略):https://libosinfo.org/download/ 来更新os-info-db,你可以直接安装debian源里的osinfo-db-import工具来进行导入操作。

    安装cockpit-podman容器虚拟化支持

    podman是一个兼容docker的容器管理工具,Debian buster还没有官方支持podman,自然也没有官方支持cockpit-podman,这里采用一种折中的方式:

    安装podman

    请参考官方指南:https://podman.io/getting-started/installation

    # Debian 10
    # First enable user namespaces as root user
    echo 'kernel.unprivileged_userns_clone=1' > /etc/sysctl.d/00-local-userns.conf
    systemctl restart procps
    # Use buster-backports on Debian 10 for a newer libseccomp2
    echo 'deb http://deb.debian.org/debian buster-backports main' >> /etc/apt/sources.list
    echo 'deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_10/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
    curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_10/Release.key | sudo apt-key add -
    sudo apt-get update
    sudo apt-get -y -t buster-backports install libseccomp2
    sudo apt-get -y install podman
    # Restart dbus for rootless podman
    systemctl --user restart dbus

    安装cockpit-podman

    这个包只有testing和sid源中有,在debian中混用源是一件危险的事情,这里直接从sid源中下载deb然后手动安装。

    软件包下载:https://packages.debian.org/sid/cockpit-podman

    手动安装:

    dpkg -i cockpit-podman_28-1_all.deb

    由于以及安装了podman,此时应当不会有依赖问题。

    可能遇到问题和解决方法

    主机名问题

    最好保证主机名+域名(比如microserver.lan)小于15个字符,否则omv里有可能无法开启samba功能。

    另一个需要注意的点是,openmediavault和cockpit中的主机名设置不互通,应该是omv单独自己存储了主机名导致的,若修改需要在两边同时操作。

    网络管理问题

    omv和cockpit(如果你装了cockpit-networkmanager)都有自己的网络管理功能,但omv用的是传统方案(/etc/network/interfaces),cockpit使用NetworkManager,由传统方案管理的接口在NetworkManager中会是unmanaged状态。

    这里建议全交给NetworkManager管理,否则cockpit的一些功能可能会出现问题(比如软件包更新检查),方法是在omv中网络设置里删除所有项目。

    请注意执行这个操作的时候可能会断网,如果你是远程操作,要小心和服务器失联。

    cockpit性能数据无历史记录

    更改过主机名后可能会出现这个问题,重新安装cockpit-pcppcp可以解决(先purge再install)。

    cockpit-machines没有快照(snapshot)功能

    根据红帽的说法,快照功能需要libvirt-dbus的版本在1.40以上,但debian buster下最新只有1.30,而1.40只在testing或sid源中有。(类似的,这也是在centos 8上安装cockpit-machines同样没有快照功能的原因)

    解决方法就是通过一些奇怪的方法把1.40版本装上,可以手动下载(本体+两个依赖),也可以引入sed软件源,但因为debian buster之后libgcc依赖变化的原因,对系统的破坏性都比较大。

    目前看来想稳定(aka. 不折腾)地使用快照功能,大概只有去用fedora了。

  • 解决Proxmox VE每隔5分钟就需要重新登录的问题

    解决Proxmox VE每隔5分钟就需要重新登录的问题

    时效性提醒:本文首次编写发布于5 年前。

    该问题常在主机从集群分离后出现,现象是登录WebUI后,总会在登陆(大约)5分钟后就无法继续操作,并会弹出登录框,需要重新登录。

    TLDR:解决方法是在参照官方wiki分离节点后,删除/etc/pve/ha/目录下的所有文件(可能需要停止pve相关服务),即可。

    如果/etc/pve/priv/lock/下有残留的文件,也可以一并删除。

    这个问题原先在国内和外网上都没有靠谱的解决方案,而我也是在重装了Proxmox VE后对比新旧配置文件夹发现的异样,可能是网络上可见的第一例成功解决的吧。

    以下DLC

    关于如何在不丢失虚拟机的情况下重装Proxmox VE软件套件,这里可以简单的说明一下:

    • 首先分离节点(即主机),确保不在cluster中
    • 备份需要的pve配置文件:
      • 存储配置文件:
        /etc/pve/storage.cfg
      • 每个LXC容器配置文件:
        /etc/pve/nodes/<your_node_name>/lxc/*
      • 每个VM的配置文件:
        /etc/pve/nodes/<your_node_name>/qemu-server/*
    • 然后停止pve服务,卸载proxmox-ve元软件包(期间还会有一道安全措施),然后用apt autoremove卸载所有的pve软件包
    • 备份并移除/var/lib/pve-cluster//etc/pve目录虚拟文件系统,即pmxcfs,而这里是其“本体”)
    • 此时你的系统就变成了近似普通的Debian Linux,可以重启一下(要有仪式感)
    • 重新装回proxmox-ve
    • 先关闭所有pve服务,然后恢复之前备份的文件,重启机器
    • 登陆WebUI,你应该能看到你原来所有的虚拟机和LXC了

    最后吐槽一下pve:cluster加入容易,移出难。还会导致一些奇怪的问题,建议一旦你的cluster有分离操作,最好把所有涉及到的节点都分离并清理干净(甚至重装pve软件),再把需要的节点重新组合为cluster。当然最好是加入cluster就考虑清楚,别做分离操作。

  • ESXi + openwrt折腾软路由和万兆软交换机的一些小坑

    ESXi + openwrt折腾软路由和万兆软交换机的一些小坑

    时效性提醒:本文首次编写发布于6 年前。

    Why 软交换机?

    因为需要部署万兆电口的内网,然而目前的万兆交换机多为光口,加上光模块成本很可能得近2000。

    我希望这两条紫色的线是万兆的

    故想到用一台几百块的x86机器+一张几百块的intel x540双万兆电口网卡,在OS中桥接,做成软交换,同时也桥接若干板载的千兆网口,用来与原有的千兆有线内网连通。再同时,如果在这台机器上做虚拟化,上面的虚拟机也可以享受到万兆网络。事实证明,我还是simple young naive

    ESXi vSwitch的坑

    ESXi vSwitch即“虚拟交换机”,如果不部署vCenter server的话只能创建“标准vSwitch”,然而这确实是个“虚拟机的交换机”,对于物理端口并没有交换功能,就算你给vSwitch添加多个物理端口作为“上行链路”,也只是负载均衡、故障转移的bond,而非软交换机的bridge

    据我所知,ESXi的单机WebUI并没有任何能创建物理端口bridge的地方,而为了一个交换功能去装几十个G的vCenter server有些舍本逐末,所以就有了让VM实现交换的折中方案。

    VM负责交换时不同路径的效率问题

    这里使用的是的E3-1220L,这是一颗20w TDP、2C4T、2.2~3.4GHz的处理器,作为基准。

    这里把两张万兆网卡都直通给了VM,一个openwrt的VM。

    首先是场景1:标准的软交换的路径,效率尚可:

    外部设备A <--> 万兆网口1 <--> VM <--> 万兆网口2 <--> 外部设备B

    但如果是下面这种场景2,外部设备到路由器上另一个VM时,效率就感人了:

    外部设备A <--> 万兆网口1 <--> VM <--> 虚拟网卡 <--> ESXi虚拟交换机 <--> 虚拟网卡 <--> 目标VM

    经测试,这种情况下CPU 100%只能跑到5Gbps左右。

    而如果两张万兆网卡不使用直通的方式,场景2的效率会少很多,但场景1由于要多经过两张虚拟网卡和ESXi虚拟交换机,效率会更感人。

    解决方案的话,目前考虑用Proxmox VE替代ESXi,有待测试。

    openwrt镜像种类的选择

    x64的openwrt镜像,有和硬路由器上类似的SquashFS + overlay的根分区,或者是直接一个ext4的根分区,这里建议选择第二种,不然扩容比较麻烦。

    例如图中的第一个
  • 家用 Proxmox VE 从入门到套娃(对比ESXi)

    家用 Proxmox VE 从入门到套娃(对比ESXi)

    时效性提醒:本文首次编写发布于6 年前。

    Proxmox Virtual Environment ,俗称pve, 是一个开源的服务器虚拟化环境Linux发行版,带有qemu kvm虚拟机和lxc容器功能。pve基于Debian stable,如果你对deb系Linux比较熟悉,那么用起来会相当舒爽。

    ↑图片来源: https://pve.proxmox.com/wiki/Main_Page

    与ESXi比较

    架构

    ESXi虽然很多地方看起来很像Linux,但实际上其既不是Linux,甚至不是“Unix-like”,其内核是VMware专有的VMKernel,专为虚拟化而定制。

    而pve本质就是个装了Web管理面板的的Debian stable,外加一些pve集群相关的服务,pve官方也支持从标准的debian既有安装上去部署pve,只需要添加pve的软件源即可。

    “Proxmox”的图片搜索结果
    pve的架构

    这意味着pve是高度可定制的,因为这就是一个debian加了点料的系统,你甚至可以在pve上安装桌面使用,就像你可以在Kali上打游戏一样。

    存储

    本地存储方面,除去PCI直通外,ESXi只支持vmfs的文件存储和RDM(裸磁盘映射),但经测试,性能都很拉胯,能跑700MB/s的RAID6阵列,RDM到虚拟机后只能跑到 250MB/s左右。

    pve的支持就很丰富,可以不通过文件系统,直接使用LVM或者LVM thinpool中的分区,作为块设备给虚拟机当磁盘用,也可以在本机的文件系统(如ZFS)上使用qcow2格式虚拟磁盘文件,给虚拟机用。这里推荐使用LVM thinpool,具体会在下文提到。

    既然支持直接使用块设备作为虚拟机的磁盘,那自然也可以直接将本机硬盘的设备文件挂到虚拟机上,实现ESXi的RDM(裸磁盘映射)功能, 评价速度700MB/s的RAID6阵列,在虚拟机的缓存选项关闭的情况下,也可以跑到500MB/s左右。

    处理器性能对比

    ESXi和kvm都是硬件虚拟化,所有处理器性能和物理机相差较小,经过我的简单测试,在E5 2650 v2上ESXi可以发挥物理机95%左右的性能,而kvm为90%左右,低了一些。这里测试的项目是编译linux内核,如果是其他的项目可能会有不同结果。

    Proxmox VE 进阶技巧

    精简置备与LVM thinpool自动空间回收

    精简置备,即Thin Provision,比如你给一个虚拟机创建了一个大小为128G的虚拟磁盘,但虚拟机实际只使用了其中的10G,就只会占用宿主机10G的存储空间,而非厚置备时的128G。

    常见的vmdk和qcow2格式的虚拟磁盘文件都支持精简置备,但都是“只增不减的”,例如刚才的虚拟机又在磁盘中创建了一些5G大小的文件,总共用了15G空间,虚拟磁盘文件也会增加到15G大小,这很正常,但如果之后虚拟机又删除了10G大小的文件,实际只使用5G空间了,虚拟磁盘文件并不会自动随之缩小,还是会维持15G的大小,造成了一定程度的浪费。

    LVM即逻辑卷管理器,是Linux核心所提供的逻辑卷管理功能。它在硬盘的硬盘分区之上,又创建一个逻辑层,以方便系统管理硬盘分区系统 (来自Wikipedia) 。而LVM thinpool是一个lvm中支持精简置备的存储池,可以在其中创建精简置备的逻辑卷(分区),其只会为逻辑卷中真正存储了数据的部分分配存储块。

    与虚拟磁盘文件不同的是,LVM thinpool还支持discard,也称trim,了解SSD的人可能听说过它,其功能为:文件系统删除某些文件后,通知下级存储设备,这样文件在设备上相应的块已经不再被占用。对于LVM thinpool,在逻辑卷上的文件系统上删除文件并执行trim后,thinpool也会释放逻辑卷中不再使用的存储块,使得逻辑卷实际占用的空间减小,thinpool的整体可用空间增加。

    man lvmthin 对此的描述

    对于pve,其会将lvm中的逻辑卷作为虚拟机的磁盘,故使用lvm thinpool,并打开虚拟磁盘的Discard功能,在并在Linux客户机中对分区加入discard挂载选项或定期手动执行fstrim。对于Windows客户机,可以打开SSD模拟来诱使Windows对磁盘使用discard/trim的功能(我没测试过)。

    嵌套虚拟化(虚拟机套娃)

    在ESXi中虚拟机的CPU选项里,可以勾选“把CPU的虚拟化特性向客户机公开”,即允许客户机继续利用Host的硬件虚拟化功能去创建虚拟机,虚拟机中的虚拟机,套娃一样。在kvm中,可以在加载kvm_intelkvm_amd的时候传入nested=Y选项,启用嵌套虚拟化支持,并最好在客户机CPU模型中选择[host],否则可能会不识别。

    更换WebUI的主题界面

    pve的WebUI界面基于一个叫做extjs的东西,所以可以套用extjs的其他主题,参考:https://lunar.computer/posts/themes-proxmox/

    我在其theme-triton上进行了一些小改动,最终效果如下:

    修改的theme-triton主题文件如下:

    备用链接:https://mega.nz/file/8hM0nJJQ#Mnf0Ac0MZTgzjxGPALwZdR4V6pokSfwDdRbGR2M72Gg

    使用方式与上述文章相同,也可以直接将其解压至/usr/share/javascript/extjs/,然后执行以激活(如果主题在Proxmox更新后失效,需要重新执行这个命令):

    sed -i.bak "s/theme-crisp/theme-triton/g" /usr/share/pve-manager/index.html.tpl

    总结

    对于家用homelab环境,比如简单的单机部署,pve是很方便的。不过对于大型企业级场景,ESXi和ovirt可能会是更好选择,毕竟他们身后都有一线大型企业背书。

  • Debian/Ubuntu 下安装 HPE System Management Homepage (hp-smh)

    Debian/Ubuntu 下安装 HPE System Management Homepage (hp-smh)

    时效性提醒:本文首次编写发布于6 年前。

    折腾了一下午,最开始是从HPE MCP镜像源下载,但Web界面打开后近乎空白,没有任何有效的内容,怎么配置都无效。后来发现原因是这个镜像源里的软件版本太老,最后从HPE Support里找到的版本才是对的,功能正常。

    在这里下载ISO镜像:HPE Management Component Pack for dpkg-based distributions,挂成软件源或者手动安装其中的所有.deb即可。会一并安装snmpd

    这些软件的功能如下:

    然后执行/sbin/hpsnmpconfig,配置本机的SNMP服务,community string随意设置即可。

    ssa为HP Smart Array阵列卡的管理服务,但其/etc/init.d/hpessad文件存在bug,使其无法自动启动,需要修改其第44行,在"/usr/sbin/ssa"后加入-start

    之后重启hpessadhpsmhd服务,就可以进入https://<server-ip>:2381正常使用了,Web界面的用户名和密码就是本机的UNIX用户的,使用root登录即可:

    最有用的功能就是我们刚才修复的ssa管理界面了,在主页的Storage菜单里,如果没有出现,请确认hpessa服务是否正常(active (running)),然后重启hpsmhd服务。

    点击后会弹出如下窗口,可以直接在此图形化的配置阵列卡。

  • HP Proliant DL360p Gen8 服务器6pin风扇接口定义及检测/欺骗主板的方法

    HP Proliant DL360p Gen8 服务器6pin风扇接口定义及检测/欺骗主板的方法

    时效性提醒:本文首次编写发布于6 年前。

    HP Proliant DL360p Gen8的8个4cm实在太吵,19250转可带劲儿了,而在此之下除了阵列卡其他部件基本都只有四五十度,故决定拆掉几个风扇,同时欺骗主板,让主板以为这几个风扇还在,否则无法开机。

    在献祭了一个18大洋的风扇风扇模块进行研究后,摸清了这种风扇的接口定义和服务器主板对其进行检测的方式:

    上图为主板上插座的俯视图,Tach1Tach2分别为风扇模块中两个独立风扇的测速线,GND1GND2两根地线在风扇模块上是短接的。

    主板检测风扇的过程分两步:

    1. 主板首先检测GND1GND2的连通性,如果是短接的则表示这个插座处有风扇模块安装,若不导通则表明未安装风扇模块,报错为fan missing
    2. 若上一步通过,主板会通过Tach1Tach2检测风扇的转速,如果两个都不转会报fan failure,一个不转会报fan warning

    如果风扇缺失或损坏,服务器会拒绝开机。

    知道了主板的检测方法后,欺骗主板假装有风扇就很简单了,短接两个GND并提供“合理”的测速线就可以了,比如拆掉一半4个风扇,然后手动短接GND,并把测速线驳接到剩余的4个风扇上。

    Update

    评论区给出了一种更简单的欺骗方式,核心在于直接将Tach测速线接地也会被认为是“合理的”转速,故欺骗方法就非常简单了,直接将GND1、GND2、Tach1、Tach2这4个脚短接在一起即可。

    为了达到这个目的也很简单,不需要制作接头和绘制PCB,直接购买一些2.0mm间距的2×3排母,在引脚处将上述的4个pin焊接在一起,然后直接将其插入风扇插座即可。我目前的使用方案是用此法拆掉所有的原装风扇,然后在两个CPU和网卡的位置放上3个12cm机箱风扇,即可达到不错的散热效果,且相当静音。

  • 为ESXi设置主机名

    为ESXi设置主机名

    时效性提醒:本文首次编写发布于6 年前。

    在未经过任何设置的内网安装ESXi后,主机名会显示为localhost.localdomain,这是因为ESXi默认会从DNS获取自己的域名,如果内网的DNS未经过设置,ESXi自然获取不到任何有效的域名。

    一种对简单的设置方法,就是直接在网络 – TCP/IP 堆栈 – 默认TCP/IP 堆栈 – 基本 DNS 配置中手动设置:

    但总归不太优雅,而且这样设置,这个主机名和域名也没有太多实际意义。更推荐的方法是在内网DNS服务器上设置内网的域名和对应这台机器的主机名,这样设置的主机名在内网中都是可用的,ESXi也会自动获取其主机名和域名。

    下面以一台使用dnsmasq作为内网DNS和DHCP服务器的网关为例,一些Linux软路由和类OpenWrt系统的路由器都和这类似。

    首先在dnsmasq的配置文件中配置以下内容:

    # 设置内网域名
    domain=lan
    
    # 自动为/etc/hosts中的短主机名加上域名
    expand-hosts
    
    # (如果dnsmasq作为DHCP服务器)为ESXi所在主机绑定固定的IP,MAC地址和IP根据实际情况填写
    dhcp-host=xx:xx:xx:xx:xx:xx,192.168.10.11

    接着,在/etc/hosts中为ESXi所在主机设置一个主机名,添加:

    192.168.10.11    home-dev

    接下来就可以通过home-dev或者home-dev.lan访问ESXi主机了,如果ESXi上的显示没有更新,尝试重新设置一下网络端口。

  • HP ProLiant DL360p Gen8 服务器家用指南

    HP ProLiant DL360p Gen8 服务器家用指南

    时效性提醒:本文首次编写发布于6 年前。

    近日在某宝以2000元的价格购入一台二手HP ProLiant DL360p Gen8服务器,及若干二手配件,如下:

    • E5 2650 v2 x2
    • DDR3 REG 8G 1333M x4
    • 146G 2.5 SAS 10k 拆机硬盘 x8
    • 自带HP smart array P420i阵列卡,另配1G缓存 + 电容组
    • 自带4口千兆网卡

    目前的用途是作为编译机,并将8块拆机硬盘组raid6作为备份服务器使用。

    实用性

    由于可能经常会编译Linux内核或OpenWrt等,鉴于这种大型make项目对于多核并行的支持都比较好,且不同核心编译不同文件时不存在什么进程间通信,所以老双路E5平台的性价比很高。就目前(2020年初)而言,x58 平台 的CPU太老,当钥匙扣还行;E5 2620虽然只要60块,但 Sandy Bridge EP 32nm还是有些老,最后选择了380块一个的E5 2650 v2,22nm的Ivy Bridge EP,性能和效能都尚可,而更新的E5 v3平台目前性价比就不高了。

    同时,DDR3 REG的服务器内存相当便宜,目前两三百就能买到32G,更大的内存可以提供更多的文件缓存,由于编译过程经常会在下一步读取上一步产生的文件,如果有足够大的内存,这些读取可以直接在内存中完成,编译的速度能高不少。

    噪音问题

    这台1U的机架式服务器由于高度仅有45mm,所以采用了8个4cm增压风扇进行散热,全部拉满时可谓震耳欲聋。而作为家养的机架式服务器,噪音自然是一个严重的问题,自然需要使用各种可行的方案尝试降噪。

    首先作为一个坑爹的企业级产品,这台服务器的风扇是无法手动控制的。这台服务器的风扇转速由整个机器的几十个传感器共同控制,但其风路的设计有些问题,导致功耗不低的阵列卡芯片散热不佳,日常80+℃,进一步恶化了噪音问题。

    我们都知道,服务器在开机时风扇转速较高,但在进入系统后会降低。如果在服务器上安装Ubuntu等常见系统,低负载时8个风扇的转速会保持在29%,声音还是比较大的。但根据一位国外论坛网友所说,如果安装如ESXi 5.5 HPE定制版,空载时风扇转速在19%左右,噪音明显会小一些,但如果安装ESXi 6.5 HPE定制版等更高版本就还是29%转速不会下降,看起来相当奇怪。

    由于ESXi 5.5体验和性能都不太好,旧C#客户端难以使用,手动安装的Web UI又有较多bug,我研究了一两天这个问题,最终在HPE官方支持文档中找到了原因,参见: c05376322 ,这个问题竟然是由于6.5以上的ESXi使用了新的网卡驱动,但不再支持旧网卡的温度感应,导致iLO无法获取网卡的温度,使得风扇转速无法下降。

    官方的解决方案写的十分简略,大概是安装旧版的网卡驱动,但我尝试照做后确认是旧版的网卡驱动被加载下,风扇转速并没有任何变化。最终使用了最后一个官方就没有这个问题的版本,ESXi 6.0 HPE定制版,由于自带Web UI,体验尚可。

    未完待续

  • 解决WireGuard在OpenWrt路由器上重启后无法连接问题的过程

    解决WireGuard在OpenWrt路由器上重启后无法连接问题的过程

    时效性提醒:本文首次编写发布于7 年前。

    先说结论,无法重连是因为重启后路由器上的系统时间不正确所导致的

    以下废话

    最近在OpenWrt便携路由器上部署WireGuard客户端,以在外出公共WiFi处实现更加可控的网络环境。

    途中遇到了初次连接正常,但路由器重启后就无法连接的问题。如果此时重启VPS上的WireGuard服务端,则又可正常连接。(尽管WireGuard为对称式设计,但此处为方便表述,将出口节点称为“服务端”)

    此问题非常奇怪,因为经测试每次路由器重启后在网络上都是可以正常与服务端主机进行通信的,ssh等服务一切正常。但路由器上的WireGuard显示从未成功进行HandShake,服务端显示Last HandShake时间为路由器重启前上一次成功连接的最后时间。该问题在网上的资料也很少,有相同案例但都没有成功的解决方法。

    最后发现问题还是受到了一个Reddit上帖子的启发,一位用户贴出了其WireGuard服务端的详细日志:

    [388310.229472] wireguard: wg0: Sending handshake initiation to peer 15 (XX.XX.XX.108:2154)
    [388313.665606] wireguard: wg0: Invalid handshake initiation from XX.XX.XX.50:19326
    [388315.605443] wireguard: wg0: Handshake for peer 15 (XX.XX.XX.108:2154) did not complete after 5 seconds, retrying 

    …where .108 is my router’s old gray IP (before the reboot), and .50 is its current IP as of the time of these messages.

    可以看出,服务端虽然还在尝试与旧的连接进行handshake,但却拒绝了路由器重启后新的handshake(用于建立新连接),这时可能有些读者会认为是残留的旧连接阻止了新连接,但这其实并不符合WireGuard的行为。真正的原因是,重启后路由器的系统时间不正确,导致WireGuard服务端拒绝了我们新的handshake。

    WireGuard白皮书的5.1节中写道:

    An attacker could replay initial handshake messages to trick the responder into regenerating its ephemeral key, thereby invalidating the session of the legitimate initiator (though not affecting the secrecy or authenticity of any messages). To prevent this, a 12-byte TAI64N [7] timestamp is included, encrypted and authenticated, in the first message. The responder keeps track of the greatest timestamp received per peer and discards packets containing timestamps less than or equal to it.

    当WireGuard服务端重启后,路由器端首次连接时,服务端还没有记录到过该peer上次handshake发送的时间戳,所以无论路由器在handshake包中发送了一个怎样诡异的时间戳,都会被WireGuard服务端接收,handshake成功,WireGuard连接正常。

    随后,由于路由器的网络连接通畅了,NTP时间同步成功,路由器的系统时间正确,于是在几分钟后下一次路由器发送的handshake包中,时间戳已经时正确的时间了,而这个时间戳也被WireGuard服务端记录了下来。

    但这就导致的问题, 路由器每次重启后不正确的时间通常较早 ,远早于正确时间,也就意味着,但路由器重启后尝试再次连接时,其在handshake包中包含的这个较早的时间戳,早于WireGuard服务端中记录的上次handshake的时间戳,基于WireGuard防止重放攻击的逻辑,该handshake包会被认为无效并被丢弃掉。

    而由于路由器的时间不正确,导致WireGuard无法正常连接,网络不通,也就没法与NTP服务器进行时间同步,去更正不正确的时间,是一个死循环,导致了WireGuard一直无法连接。

    知道了问题所在,解决就很简单了,只要保证每次重启后系统时间的正确性就可以了。比如设置一个ipv6的NTP服务器,并让wireguard不要代理ipv6,或者为wireguard客户端设置一个延迟启动,都是可行的方法。