{ "version": "https://jsonfeed.org/version/1", "title": "夏叶随风 's Blog", "home_page_url": "https://blog.firerain.me", "items": [ { "id": "https://blog.firerain.me/article/38", "url": "https://blog.firerain.me/article/38", "title": "将像积分传感器集成创建的实体的数据清零的方法", "content_html": "\u003cp\u003e像类型是积分传感器的这种实体可以采用该方法,类型是仪表统计也可以\u003c/p\u003e\n\n\u003cp\u003e\u003cimg src=\"/api/assets/423df9f2-5883-4b3d-9d07-c5cb769885fd\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003ch2\u003e步骤\u003c/h2\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e前提查到你要准备删除的实体的 \u003ccode\u003eentity_id\u003c/code\u003e,ha 面板自己查\n2 - 5 步是删除历史数据\n1. 停止 homeassistant 运行\n2. 从 \u003ccode\u003estatistics_meta\u003c/code\u003e 表通过 \u003ccode\u003eentity_id\u003c/code\u003e 查询到 \u003ccode\u003emetadata_id\u003c/code\u003e\n \u0026gt; \u003ccode\u003eentity_id\u003c/code\u003e 对应的表字段是 \u003ccode\u003estatistic_id\u003c/code\u003e , \u003ccode\u003emetadata_id\u003c/code\u003e 则是 \u003ccode\u003eid\u003c/code\u003e\n3. 删除 \u003ccode\u003estatistics\u003c/code\u003e 表中 \u003ccode\u003emetadata_id\u003c/code\u003e 为上一步查出来的所有数据\n4. 从 \u003ccode\u003estates_meta\u003c/code\u003e 表通过 \u003ccode\u003eentity_id\u003c/code\u003e 查询到 \u003ccode\u003emetadata_id\u003c/code\u003e\n \u0026gt; 跟第一步不同这里的表字段名不叫别的,就叫这两\n5. 删除 \u003ccode\u003estates\u003c/code\u003e 表中 \u003ccode\u003emetadata_id\u003c/code\u003e 为上一步查出来的所有数据\n6. 编辑 \u003ccode\u003ehomeassistant\u003c/code\u003e 的数据文件夹下的 \u003ccode\u003e.storage/core.restore_state\u003c/code\u003e 文件删除对应实体那项\n7. 重新启动 \u003ccode\u003ehomeassistant\u003c/code\u003e\n8. 在 \u003ccode\u003ehomeassistant\u003c/code\u003e 的 \u003ccode\u003e开发者工具\u003c/code\u003e \u0026gt; \u003ccode\u003e状态\u003c/code\u003e 界面将该实体的状态改成 \u003ccode\u003e0\u003c/code\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003ch2\u003ePostgreSQL 数据库为例\u003c/h2\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e我的 homeassistant 数据库用的是 \u003ccode\u003ePostgreSQL\u003c/code\u003e,仅供参考,以你实际用的为准\n\u003ccode\u003eentity_id\u003c/code\u003e 这里是 \u003ccode\u003esensor.solar_system_module_pv_power_total\u003c/code\u003e\n1. 停止 homeassistant 运行\n2. 进入 PgSQL shell\n\u003ccode\u003ebash\npsql -U homeassistant -d homeassistant\n\u003c/code\u003e\n3. 查询 \u003ccode\u003estatistics\u003c/code\u003e 表的 \u003ccode\u003emetadata_id\u003c/code\u003e\n\u003ccode\u003ebash\nselect * from statistics_meta where statistic_id='sensor.solar_system_module_pv_power_total';\n\u003c/code\u003e\n\u003ccode\u003e\n id | statistic_id | source | unit_of_measurement | has_mean | has_sum | name \n-----+-------------------------------------------+----------+---------------------+----------+---------+------\n 116 | sensor.solar_system_module_pv_power_total | recorder | kWh | f | t | \n(1 row)\n\u003c/code\u003e\n4. 删除 \u003ccode\u003estatistics\u003c/code\u003e 表中的数据,如上图查询的 \u003ccode\u003emetadata_id\u003c/code\u003e 为 \u003ccode\u003e116\u003c/code\u003e\n\u003ccode\u003ebash\ndelete from statistics where metadata_id=116;\n\u003c/code\u003e\n5. 查询 \u003ccode\u003estates\u003c/code\u003e 表的 \u003ccode\u003emetadata_id\u003c/code\u003e\n\u003ccode\u003ebash\nselect * from states_meta where entity_id='sensor.solar_system_module_pv_power_total';\n\u003c/code\u003e\n\u003ccode\u003e\n metadata_id | entity_id \n-------------+-------------------------------------------\n 2433 | sensor.solar_system_module_pv_power_total\n(1 row)\n\u003c/code\u003e\n6. 删除 \u003ccode\u003estates\u003c/code\u003e 表中的数据,如上图查询的 \u003ccode\u003emetadata_id\u003c/code\u003e 为 \u003ccode\u003e2433\u003c/code\u003e\n\u003ccode\u003ebash\ndelete from states where metadata_id=2433;\n\u003c/code\u003e\n7. 然后就可以退出 shell,编辑 \u003ccode\u003e.storage/core.restore_state\u003c/code\u003e 文件\n如 \u003ccode\u003ehaos\u003c/code\u003e 路径在 \u003ccode\u003e/usr/share/hassio/homeassistant/.storage/core.restore_state\u003c/code\u003e\n修改该文件时 \u003ccode\u003ehomeassistant\u003c/code\u003e 一定要处于未运行状态,否则重新启动后会恢复回去\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003e将该段删除\n\u003cimg src=\"/api/assets/9246256e-c343-4679-b07e-cbf0f913d395\" alt=\"alt text\" /\u003e\n8. 重新启动 \u003ccode\u003ehomeassistant\u003c/code\u003e\n9. 然后就可以退出 shell,进入到 \u003ccode\u003ehomeassistant\u003c/code\u003e 的界面,将状态改 \u003ccode\u003e0\u003c/code\u003e\n \u0026gt; 这一步可以省略\n\u003cimg src=\"/api/assets/b602266a-999f-44a9-bd6f-2e24f472e4b3\" alt=\"alt text\" /\u003e\u003c/p\u003e\n", "date_published": "2024-06-16T10:03:19Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/37", "url": "https://blog.firerain.me/article/37", "title": "通过将 MCX354A TCBT 的固件强刷成 FCBT 的来解锁 40G/56G eth", "content_html": "\u003cp\u003e闲鱼上 MCX354A TCBT 比 QCBT 或者 FCBT 的版本都要便宜,虽然它是 10Gbps 的速率,但是可以通过强刷成 FCBT 的固件来获得 40G/56G 的速率,通过以下步骤刷完就行了\n\u0026gt; 以下操作均在 \u003ccode\u003eArch Linux\u003c/code\u003e 下进行\u003c/p\u003e\n\n\u003ch2\u003e安装 mstflint\u003c/h2\u003e\n\n\u003cp\u003e通过 \u003ccode\u003eAUR\u003c/code\u003e 安装开源版本的 Mellanox Firmware Tools\n\u003ccode\u003ebash\nyay -S mstflint\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e备份\u003c/h2\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e备份下卡上的旧配置和固件以防万一(其实没什么用,可以跳过\n```bash\u003c/p\u003e\n\n\u003ch1\u003emstflint -d 01:00.0 query full \u0026gt; flint_query.txt\u003c/h1\u003e\n\n\u003ch1\u003emstflint -d 01:00.0 hw query \u0026gt; flint_hwinfo.txt\u003c/h1\u003e\n\n\u003ch1\u003emstflint -d 01:00.0 ri orig_firmware.mlx\u003c/h1\u003e\n\n\u003ch1\u003emstflint -d 01:00.0 dc orig_firmware.ini\u003c/h1\u003e\n\n\u003ch1\u003emstflint -d 01:00.0 rrom orig_rom.mlx\u003c/h1\u003e\n\n\u003ch1\u003emstvpd 01:00.0 -vpd \u0026gt; orig_vpd.txt\u003c/h1\u003e\n\n\u003cp\u003e```\u003c/p\u003e\n\n\u003ch2\u003e下载固件和解压\u003c/h2\u003e\n\n\u003cp\u003e这是 fcbt 最新最后的固件了,截至目前不会有更新的,直接下吧\n\u003ccode\u003ebash\nwget http://www.mellanox.com/downloads/firmware/fw-ConnectX3-rel-2_42_5000-MCX354A-FCB_A2-A5-FlexBoot-3.4.752.bin.zip\nunzip fw-ConnectX3-rel-2_42_5000-MCX354A-FCB_A2-A5-FlexBoot-3.4.752.bin.zip\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e开刷\u003c/h2\u003e\n\n\u003cp\u003e```bash\u003c/p\u003e\n\n\u003ch1\u003emstflint -d 01:00.0 -i fw-ConnectX3-rel-2\u003cem\u003e42\u003c/em\u003e5000-MCX354A-FCB\u003cem\u003eA2-A5-FlexBoot-3.4.752.bin -allow\u003c/em\u003epsid_change burn\u003c/h1\u003e\n\n\u003cp\u003e\u003ccode\u003e\n\u003c/code\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cpre\u003e\u003ccode\u003eCurrent FW version on flash: 2.32.5100\nNew FW version: 2.42.5000\n\n\nYou are about to replace current PSID on flash - \u0026quot;MT_1090110028\u0026quot; with a different PSID - \u0026quot;MT_1090120019\u0026quot;.\nNote: It is highly recommended not to change the PSID.\n\u003c/code\u003e\u003c/pre\u003e\n\n\u003cp\u003eDo you want to continue ? (y/n) [n] :\n```\u003c/p\u003e\n\n\u003cp\u003e```bash\u003c/p\u003e\n\n\u003ch1\u003emstconfig -d 01:00.0 q\u003c/h1\u003e\n\n\u003cp\u003e\u003ccode\u003e\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003eDevice #1:\u003c/h2\u003e\n\n\u003cp\u003eDevice type: ConnectX3\u003cbr /\u003e\nDevice: 01:00.0\u003c/p\u003e\n\n\u003cp\u003eConfigurations: Next Boot\n SRIOV\u003cem\u003eEN False(0)\u003cbr /\u003e\n NUM\u003c/em\u003eOF\u003cem\u003eVFS 8\u003cbr /\u003e\n LINK\u003c/em\u003eTYPE\u003cem\u003eP1 VPI(3)\u003cbr /\u003e\n LINK\u003c/em\u003eTYPE\u003cem\u003eP2 VPI(3)\u003cbr /\u003e\n LOG\u003c/em\u003eBAR\u003cem\u003eSIZE 3\u003cbr /\u003e\n BOOT\u003c/em\u003ePKEY\u003cem\u003eP1 0\u003cbr /\u003e\n BOOT\u003c/em\u003ePKEY\u003cem\u003eP2 0\u003cbr /\u003e\n BOOT\u003c/em\u003eOPTION\u003cem\u003eROM\u003c/em\u003eEN\u003cem\u003eP1 True(1)\u003cbr /\u003e\n BOOT\u003c/em\u003eVLAN\u003cem\u003eEN\u003c/em\u003eP1 False(0)\u003cbr /\u003e\n BOOT\u003cem\u003eRETRY\u003c/em\u003eCNT\u003cem\u003eP1 0\u003cbr /\u003e\n LEGACY\u003c/em\u003eBOOT\u003cem\u003ePROTOCOL\u003c/em\u003eP1 PXE(1)\u003cbr /\u003e\n BOOT\u003cem\u003eVLAN\u003c/em\u003eP1 1\u003cbr /\u003e\n BOOT\u003cem\u003eOPTION\u003c/em\u003eROM\u003cem\u003eEN\u003c/em\u003eP2 True(1)\u003cbr /\u003e\n BOOT\u003cem\u003eVLAN\u003c/em\u003eEN\u003cem\u003eP2 False(0)\u003cbr /\u003e\n BOOT\u003c/em\u003eRETRY\u003cem\u003eCNT\u003c/em\u003eP2 0\u003cbr /\u003e\n LEGACY\u003cem\u003eBOOT\u003c/em\u003ePROTOCOL\u003cem\u003eP2 PXE(1)\u003cbr /\u003e\n BOOT\u003c/em\u003eVLAN\u003cem\u003eP2 1\u003cbr /\u003e\n IP\u003c/em\u003eVER\u003cem\u003eP1 IPv4(0)\u003cbr /\u003e\n IP\u003c/em\u003eVER\u003cem\u003eP2 IPv4(0)\u003cbr /\u003e\n CQ\u003c/em\u003eTIMESTAMP True(1)\n```\u003c/p\u003e\n\n\u003ch2\u003e设置双口为 eth 模式\u003c/h2\u003e\n\n\u003cp\u003e```bash\u003c/p\u003e\n\n\u003ch1\u003emstconfig -d 01:00.0 set LINK\u003cem\u003eTYPE\u003c/em\u003eP1=2 LINK\u003cem\u003eTYPE\u003c/em\u003eP2=2\u003c/h1\u003e\n\n\u003cp\u003e```\u003c/p\u003e\n", "date_published": "2023-12-22T18:03:17Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/29", "url": "https://blog.firerain.me/article/29", "title": "[All In One] 搭建你自己的 Homelab, Part I (规划)", "content_html": "\u003ch2\u003e硬件规格\u003c/h2\u003e\n\n\u003cp\u003e| | |\n| --- | --- |\n| 主板 | 华擎太极 X570 |\n| CPU |3400g |\n| 硬盘 | 铠侠 SE10 1T |\n| 硬盘 | 希捷银河 X16 16T |\n| 硬盘 | 希捷银河 X16 16T |\n| 硬盘 | 希捷银河 X18 16T |\n| 光口网卡 |MCX354A TCBT |\n| 电源 | 先马黑钻 750W |\n| 机箱| 闲鱼收的二手4U机柜式机箱 |\u003c/p\u003e\n", "date_published": "2023-09-30T11:42:36Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/28", "url": "https://blog.firerain.me/article/28", "title": "Orange Pi 3 Lts 上游主线 u-boot 编译教程", "content_html": "\u003cp\u003e以下编译环境以 \u003ccode\u003eArchlinux\u003c/code\u003e 为例\u003c/p\u003e\n\n\u003ch2\u003e依赖安装\u003c/h2\u003e\n\n\u003cp\u003e\u003ccode\u003e\nsudo pacman -S aarch64-linux-gnu-gcc bc python python-setuptools swig dtc bison flex\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003earm-trusted-firmware (ATF) 编译\u003c/h2\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e2022.11.10 新增: ATF 目前为止只能使用的最高版本为 \u003ccode\u003ev2.3\u003c/code\u003e,更高的版本会导致无法引导内核启动,原因未知,需等待上游修复\u003c/p\u003e\n\n\u003ch3\u003e拉取源码\u003c/h3\u003e\n\n\u003cp\u003e官方源和镜像源二选一\n\u003ccode\u003e\ngit clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git\n\u003c/code\u003e\n或\n\u003ccode\u003e\ngit clone https://github.com/ARM-software/arm-trusted-firmware\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch3\u003ecd 到源码路径\u003c/h3\u003e\n\n\u003cp\u003e以拉源码所在路径为基准\n```bash\ncd arm-trusted-firmware\u003c/p\u003e\n\n\u003ch1\u003e切换到 v2.3 版本\u003c/h1\u003e\n\n\u003cp\u003egit checkout v2.3\n```\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003ch3\u003e编译\u003c/h3\u003e\n\n\u003cp\u003e```bash\u003c/p\u003e\n\n\u003ch1\u003eCROSS_COMPILE 指定交叉编译链\u003c/h1\u003e\n\n\u003ch1\u003ePLAT 指定构建目标\u003c/h1\u003e\n\n\u003cp\u003emake CROSS\u003cem\u003eCOMPILE=aarch64-linux-gnu- PLAT=sun50i\u003c/em\u003eh6 LDFLAGS=--no-warn-rwx-segment\n``\u003ccode\u003e\n\u0026gt; 如下图问题属于上游问题,暂时加\u003c/code\u003e--no-warn-rwx-segment` 参数解决 (截至 2022.11.08)\u003c/p\u003e\n\n\u003cp\u003e\u003cimg src=\"/api/assets/83859c78-c00d-4ecc-b55e-4d1d1ed25f02\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e如下图所示则为编译成功,ATF 固件路径为 \u003ccode\u003ebuild/sun50i_h6/release/bl31.bin\u003c/code\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003e\u003cimg src=\"/api/assets/064fa223-71ff-4339-b017-8a1d33649d40\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003ch2\u003eU-Boot 编译\u003c/h2\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e以下拉源码部分如网速慢等可添加 \u003ccode\u003e--depth 1\u003c/code\u003e 参数来加快拉取速度\u003c/p\u003e\n\n\u003ch3\u003e拉取源码\u003c/h3\u003e\n\n\u003cp\u003e官方源和镜像源二选一\n\u003ccode\u003e\ngit clone https://source.denx.de/u-boot/u-boot.git\n\u003c/code\u003e\n或\n\u003ccode\u003e\ngit clone https://github.com/u-boot/u-boot.git\n\u003c/code\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003ch3\u003ecd 到源码路径\u003c/h3\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e以拉源码所在路径为基准\n\u003ccode\u003e\ncd u-boot\n\u003c/code\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003ch3\u003e打补丁\u003c/h3\u003e\n\n\u003cp\u003e从\u003ca href=\"https://gitlab.com/xiayesuifeng/uboot-orangepi3-lts\"\u003e这\u003c/a\u003e下载两个补丁\n由于 oragngepi 官方 uboot 提供的 dts 不全所以实际是从内核源码里提取修改的\n\u003ccode\u003ebash\npatch -Np1 \u0026lt; 0001-add-orangepi-3-lts-support.patch\npatch -Np1 \u0026lt; 0002-board-fix-sunxi-h6-led.patch\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch3\u003e配置 defconfig\u003c/h3\u003e\n\n\u003cp\u003e\u003ccode\u003e\nmake orangepi_3_lts_defconfig\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch3\u003e编译\u003c/h3\u003e\n\n\u003cblockquote\u003e\n\u003cul\u003e\n\u003cli\u003eCROSS_COMPILE 指定交叉编译链\u003c/li\u003e\n\u003cli\u003eBL31 指定上一步编译的 ATF 固件的路径\u003c/li\u003e\n\u003cli\u003eSCP 指定 SCP 固件,由于这个是可选的,所以这里指定为空,如需要可自行编译,具体参考 https://github.com/u-boot/u-boot/blob/master/board/sunxi/README.sunxi64#L73\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003e\u003ccode\u003ebash\nmake CROSS_COMPILE=aarch64-linux-gnu- BL31=../trusted-firmware-a/build/sun50i_h6/release/bl31.bin SCP=/dev/null -j8\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e刷入 U-Boot\u003c/h2\u003e\n\n\u003ch3\u003e刷入到 SD Card\u003c/h3\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e\u003ccode\u003esdX\u003c/code\u003e 的 \u003ccode\u003eX\u003c/code\u003e 填多少自己看 \u003ccode\u003efdisk -l\u003c/code\u003e 找,如 \u003ccode\u003esda\u003c/code\u003e\n\u003ccode\u003e\nsudo dd if=./u-boot-sunxi-with-spl.bin of=/dev/sdX bs=8k seek=1\n\u003c/code\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n", "date_published": "2022-11-08T16:09:11Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/27", "url": "https://blog.firerain.me/article/27", "title": "ESP32C3从入门到放弃之 Arch Linux 上开发环境搭建 (一)", "content_html": "\u003ch2\u003eESP32C3 介绍\u003c/h2\u003e\n\n\u003cp\u003eESP32-C3 系列芯片是极低功耗、高集成度的 MCU 系统级芯片 (SoC),集成 2.4 GHz Wi-Fi 和低功耗蓝牙 (Bluetooth® LE) 双模无线通信。芯片的功能框图如下图所示。\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e摘自官方文档\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003e\u003cimg src=\"/api/assets/e5f4d79f-c371-4ff0-9165-3b1406e5c4f3\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003ch2\u003eESP32C3 官方文档\u003c/h2\u003e\n\n\u003cp\u003e\u003ca href=\"https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_cn.pdf\"\u003eESP32­C3 技术参考手册\u003c/a\u003e\n\u003ca href=\"https://espressif.com/sites/default/files/documentation/esp32-c3_hardware_design_guidelines_cn.pdf\"\u003eESP32C3 硬件设计指南\u003c/a\u003e\n\u003ca href=\"https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_cn.pdf\"\u003eESP32C3 技术规格书\u003c/a\u003e\u003c/p\u003e\n\n\u003ch2\u003e开发环境搭建\u003c/h2\u003e\n\n\u003col\u003e\n\u003cli\u003e\u003cp\u003eESP-IDF 安装(AUR)\u003c/p\u003e\n\n\u003cp\u003e\u003ccode\u003ebash\nyay -S esp-idf\n\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\n\n\u003cli\u003e\u003cp\u003e安装工具链\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003eESP32系列可选目标有 \u003ccode\u003eesp32\u003c/code\u003e, \u003ccode\u003eesp32c3\u003c/code\u003e, \u003ccode\u003eesp32s2\u003c/code\u003e, \u003ccode\u003eesp32s3\u003c/code\u003e, 这里选 \u003ccode\u003eesp32c3\u003c/code\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cul\u003e\n\u003cli\u003ebash shell\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003cp\u003e\u003ccode\u003ebash\n/opt/esp-idf/install.sh esp32c3\n\u003c/code\u003e\u003c/p\u003e\n\n\u003cul\u003e\n\u003cli\u003efish shell\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003cp\u003e\u003ccode\u003efish\n/opt/esp-idf/install.fish esp32c3\n\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\n\n\u003cli\u003e\u003cp\u003e添加 IDF_PATH 环境变量到 \u003ccode\u003e.pam_environment\u003c/code\u003e\u003c/p\u003e\n\n\u003cp\u003e\u003ccode\u003ebash\necho IDF_PATH=/opt/esp-idf \u0026gt;\u0026gt; ~/.pam_environment\n\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\n\n\u003cli\u003e\u003cp\u003e添加当前用户到 \u003ccode\u003euucp\u003c/code\u003e 组\n\u0026gt; Arch Linux 的串口设备的拥有组是 \u003ccode\u003euucp\u003c/code\u003e,避免访问串口设备要特权问题\u003c/p\u003e\n\n\u003cp\u003e\u003ccode\u003ebash\nsudo gpasswd -a $USER uucp\n\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\n\n\u003cli\u003e\u003cp\u003e注销登录并重新登录\u003c/p\u003e\u003c/li\u003e\n\n\u003cli\u003e\u003cp\u003e设置环境变量\n\u0026gt; 每开一个新会话时如需要 idf 环境时再执行,不建议添加到 \u003ccode\u003e.profile\u003c/code\u003e 或者 \u003ccode\u003e.xprofile\u003c/code\u003e 等,他会替换 python 环境成它自己的 python virtualenv,执行其他 python 程序时可能会出问题\u003c/p\u003e\n\n\u003cul\u003e\n\u003cli\u003ebash shell\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003cp\u003e\u003ccode\u003ebash\n. /opt/esp-idf/export.sh\n\u003c/code\u003e\u003c/p\u003e\n\n\u003cul\u003e\n\u003cli\u003efish shell\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003cp\u003e\u003ccode\u003efish\n. /opt/esp-idf/export.fish\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003eHello world\u003c/h2\u003e\n\n\u003cp\u003e```bash\u003c/p\u003e\n\n\u003ch1\u003eesp-idf 中包含部分官方示例\u003c/h1\u003e\n\n\u003cp\u003ecp -rf /opt/esp-idf/examples/get-started/hello\u003cem\u003eworld ./\ncd hello\u003c/em\u003eworld\u003c/p\u003e\n\n\u003ch1\u003e设置目标芯片\u003c/h1\u003e\n\n\u003cp\u003eidf.py set-target esp32c3\u003c/p\u003e\n\n\u003ch1\u003e配置工程(这里可跳过)\u003c/h1\u003e\n\n\u003cp\u003eidf.py menuconfig\u003c/p\u003e\n\n\u003ch1\u003e编译\u003c/h1\u003e\n\n\u003cp\u003eidf.py build\u003c/p\u003e\n\n\u003ch1\u003e将开发板连上电脑然后烧录到设备,假设你的串口设备路径是/dev/ttyACM0(Arch上一般默认都是这个,你可以用 ls /dev/tty* 来查看)\u003c/h1\u003e\n\n\u003cp\u003eidf.py -p /dev/ttyACM0 flash\n\u003ccode\u003e\n监视输出\n\u003c/code\u003ebash\nidf.py -p /dev/ttyACM0 monitor\n\u003ccode\u003e\n正常你应该能看到类似以下的内容\n\u003c/code\u003e\n...\nI (24) boot: ESP-IDF HEAD-HASH-NOTFOUND 2nd stage bootloader\nI (24) boot: compile time 12:30:31\nI (25) boot: chip revision: 3\nI (27) boot.esp32c3: SPI Speed : 80MHz\nI (32) boot.esp32c3: SPI Mode : DIO\nI (37) boot.esp32c3: SPI Flash Size : 2MB\nI (41) boot: Enabling RNG early entropy source...\nI (47) boot: Partition Table:\nI (50) boot: ## Label Usage Type ST Offset Length\nI (58) boot: 0 nvs WiFi data 01 02 00009000 00006000\nI (65) boot: 1 phy\u003cem\u003einit RF data 01 01 0000f000 00001000\nI (72) boot: 2 factory factory app 00 00 00010000 00100000\nI (80) boot: End of partition table\nI (84) esp\u003c/em\u003eimage: segment 0: paddr=00010020 vaddr=3c020020 size=06c88h ( 27784) map\nI (97) esp\u003cem\u003eimage: segment 1: paddr=00016cb0 vaddr=3fc8a200 size=0146ch ( 5228) load\nI (102) esp\u003c/em\u003eimage: segment 2: paddr=00018124 vaddr=40380000 size=07ef4h ( 32500) load\nI (115) esp\u003cem\u003eimage: segment 3: paddr=00020020 vaddr=42000020 size=12a04h ( 76292) map\nI (130) esp\u003c/em\u003eimage: segment 4: paddr=00032a2c vaddr=40387ef4 size=02214h ( 8724) load\nI (132) esp\u003cem\u003eimage: segment 5: paddr=00034c48 vaddr=50000010 size=00010h ( 16) load\nI (139) boot: Loaded app from partition at offset 0x10000\nI (142) boot: Disabling RNG early entropy source...\nI (158) cpu\u003c/em\u003estart: Pro cpu up.\nI (167) cpu\u003cem\u003estart: Pro cpu start user code\nI (167) cpu\u003c/em\u003estart: cpu freq: 160000000\nI (167) cpu\u003cem\u003estart: Application information:\nI (170) cpu\u003c/em\u003estart: Project name: hello\u003cem\u003eworld\nI (175) cpu\u003c/em\u003estart: App version: 1\nI (179) cpu\u003cem\u003estart: Compile time: Jul 12 2022 12:30:27\nI (185) cpu\u003c/em\u003estart: ELF file SHA256: 39d1914b5bb50013...\nI (191) cpu\u003cem\u003estart: ESP-IDF: HEAD-HASH-NOTFOUND\nI (197) heap\u003c/em\u003einit: Initializing. RAM available for dynamic allocation:\nI (205) heap\u003cem\u003einit: At 3FC8C4D0 len 00033B30 (206 KiB): DRAM\nI (211) heap\u003c/em\u003einit: At 3FCC0000 len 0001F060 (124 KiB): STACK/DRAM\nI (218) heap\u003cem\u003einit: At 50000020 len 00001FE0 (7 KiB): RTCRAM\nI (224) spi\u003c/em\u003eflash: detected chip: th\nI (228) spi\u003cem\u003eflash: flash io: dio\nW (232) spi\u003c/em\u003eflash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.\nI (245) sleep: Configure to isolate all GPIO pins in sleep state\nI (252) sleep: Enable automatic switching of GPIO sleep configuration\nI (259) cpu_start: Starting scheduler.\nHello world!\nThis is esp32c3 chip with 1 CPU core(s), WiFi/BLE, silicon revision 3, 2MB external flash\nMinimum free heap size: 329036 bytes\nRestarting in 10 seconds...\nRestarting in 9 seconds...\nRestarting in 8 seconds...\nRestarting in 7 seconds...\nRestarting in 6 seconds...\nRestarting in 5 seconds...\nRestarting in 4 seconds...\nRestarting in 3 seconds...\nRestarting in 2 seconds...\nRestarting in 1 seconds...\nRestarting in 0 seconds...\nRestarting now.\n```\u003c/p\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\n\u003cp\u003e至此开发环境就到此搭建完成了。至于 IDE?这不在本篇文章范围内,后续更新不会只局限于一种开发方式,所以 IDE 可不固定 ~~(maybe VS Code, maybe Goland, maybe Clion, maybe vim, who known)~~,后续特定某一开发方式时再写。\u003c/p\u003e\n\n\u003ch2\u003e常见问题\u003c/h2\u003e\n\n\u003col\u003e\n\u003cli\u003e烧录完固件开发板似乎在无限重启\n部分开发板,如合宙的ESP32C3开发板的 IO12(GPIO12)、IO13(GPIO13)在QIO模式下为SPI信号SPIHD和SPIWP复用,为了增加可用GPIO数量,开发板选择采用2线SPI的DIO模式,IO12、IO13并未连接flash,所以烧录的时候需要配置flash mode为DIO模式。官方的 esptool.py 通过添加 \u003ccode\u003e-fm dio\u003c/code\u003e 来指定,如 \u003ccode\u003eesptool.py write_flash -fm dio 0x0 xxx.bin\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e烧录报错\n有些时候需要进入下载模式才能正常烧录固件,可以长按 \u003ccode\u003eboot 键\u003c/code\u003e 然后再通电来进入,或者通电状态下长按 \u003ccode\u003eboot 键\u003c/code\u003e 并按以下 \u003ccode\u003ereset 键\u003c/code\u003e 来进入。长按个 3-5s 就行了\u003c/li\u003e\n\u003cli\u003e访问串口设备没权限\n解决方法一就是开发环境搭建的第四步操作将当前用户添加到 \u003ccode\u003euucp\u003c/code\u003e 组(ArchLinux是 \u003ccode\u003euucp\u003c/code\u003e , 其他发行版一般是 \u003ccode\u003edialout\u003c/code\u003e),并且需要注销重新登录才生效。\n方法二是配置 \u003ccode\u003eudev\u003c/code\u003e\n方法三就是简单粗暴的sudo chmod 777 /dev/ttyACM0 (不推荐)\u003c/li\u003e\n\u003c/ol\u003e\n", "date_published": "2022-07-08T12:54:35Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/24", "url": "https://blog.firerain.me/article/24", "title": "基于 Plex+Overseerr+Radarr+Sonarr+Jackett 打造全自动化追剧高端观影媒体系统", "content_html": "\u003cp\u003e先看效果图吧,晚点再更新完\n\u0026gt; 效果图是以前录的旧的,后面会换掉\u003c/p\u003e\n\n\u003cp\u003e\u003cimg src=\"/api/assets/2d697611-f58d-4791-9ccc-3de5de401937\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003cp\u003e接下来将在 TrueNAS Scale 基础上说明,其他群辉、unraid、威联通等系统类似,反正都是 docker。\n建议准备一个域名给下面要装的东西用,除非你想每次都要记一大堆端口号来访问,或者只在内网访问的随便写一个然后改 \u003ccode\u003ehosts\u003c/code\u003e 也行\u003c/p\u003e\n\n\u003cp\u003e用到的软件列表\n\u0026gt; 其中 Qbittorrent 可自行换成其他你喜欢的下载器,但是 aria2c 除外,因为 Radarr 不支持\u003c/p\u003e\n\n\u003cp\u003ePlex\nOverseerr\nRadarr\nSonarr\nJackett\nQbittorrent\u003c/p\u003e\n\n\u003cp\u003e提示:\nTrueNAS Scale 跑应用的核心其实就是 \u003ccode\u003ek8s\u003c/code\u003e (实际 k3s 魔改阉割),懂 \u003ccode\u003ek8s\u003c/code\u003e 或者了解的人应该一眼就看出来并且应该都知道怎么用的了,至于他的应用对应的 \u003ccode\u003eservice.namespcae\u003c/code\u003e 的规则看 \u003ca href=\"https://truecharts.org/manual/Quick-Start%20Guides/06-linking-apps/\"\u003e\u003ccode\u003etruecharts\u003c/code\u003e 文档\u003c/a\u003e\u003c/p\u003e\n\n\u003ch2\u003e1. 前期准备\u003c/h2\u003e\n\n\u003cul\u003e\n\u003cli\u003e准备一个泛域名,如 \u003ccode\u003e*.home\u003c/code\u003e,内网解析到 NAS 上,如果要外网访问也加个解析到你的出口 IP 上(可选)\u003c/li\u003e\n\u003cli\u003eNAS 上准备一个文件夹存放下载的东西,如 \u003ccode\u003e/mnt/data/downloads\u003c/code\u003e\u003c/li\u003e\n\n\u003cli\u003e\u003cp\u003eNAS 上按视频类型分别准备一个文件夹,如 \u003ccode\u003e/mnt/data/videos/movies\u003c/code\u003e, \u003ccode\u003e/mnt/data/videos/tv\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e2. TrueNAS Scale 添加社区源\u003c/h2\u003e\n\n\u003cp\u003e切到 \u003ccode\u003e应用 \u0026gt; 管理目录\u003c/code\u003e 界面点击添加目录\n\u003cimg src=\"/api/assets/5cb3524a-4993-4e8a-99c7-a4bc6cc255bc\" alt=\"alt text\" /\u003e\n然后像如下填写保存\n\u0026gt; 如果不走代理他会很慢,等他加载完就行了,稍安勿躁\n\u003cimg src=\"/api/assets/bf3c0e45-b62c-45e6-9b84-acff2b2aa430\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003ch2\u003e3. 安装 Traefik(可选)\u003c/h2\u003e\n\n\u003cp\u003e应用列表里找到 \u003ccode\u003etraefik\u003c/code\u003e 点安装,名称 \u003ccode\u003etraefik\u003c/code\u003e (其他也行随便改,认的出来就行)然后一直点下一步到 \u003ccode\u003eNetworking and Services\u003c/code\u003e,默认强制强转 \u003ccode\u003ehttps\u003c/code\u003e,端口默认 \u003ccode\u003e9443\u003c/code\u003e,\u003ccode\u003ehttp\u003c/code\u003e 端口默认 \u003ccode\u003e9080\u003c/code\u003e,如需修改自行修改,修改地方如下,最后一直下一步到安装就行了\n\u003cimg src=\"/api/assets/db8c3afc-deee-4818-8a55-8cb975ee832b\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003ch2\u003e4. 安装 Plex\u003c/h2\u003e\n\n\u003cp\u003e\u003ccode\u003ePlex\u003c/code\u003e 官方源和社区源都有,但是官方源不能设置 \u003ccode\u003eingress\u003c/code\u003e,设置没社区源多,所以这里选社区源的安装,名称就填 \u003ccode\u003eplex\u003c/code\u003e (除非你知道集群内怎么通过域名访问会改下面的配置你就改)\u003c/p\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003cp\u003e\u003ccode\u003eContainer Configuration\u003c/code\u003e\n\u0026gt; 买了 Plex Pass 的在 \u003ccode\u003ePlex Claim Token\u003c/code\u003e 那填 \u003ccode\u003etoken\u003c/code\u003e\u003c/p\u003e\n\n\u003cp\u003e\u003ccode\u003eStorage and Persistence\u003c/code\u003e\n\u0026gt; Configure Additional app storage 那点添加,挂载 \u003ccode\u003e/mnt/data/videos\u003c/code\u003e 到 \u003ccode\u003e/videos\u003c/code\u003e\u003c/p\u003e\n\n\u003cp\u003e\u003cimg src=\"/api/assets/d7f92e64-640f-4bd6-be49-9bc0731c2490\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003cp\u003e\u003ccode\u003eIngress\u003c/code\u003e\n\u0026gt; 无域名跳过\u003c/p\u003e\n\n\u003cp\u003e\u003cimg src=\"/api/assets/49a1798a-0b47-4e4d-b96a-a1bf6513b51a\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003cp\u003e\u003ccode\u003eSecurity and Permissions\u003c/code\u003e\n\u0026gt; 设置 docker 的默认 uid/gid 等的,有需要自己改吧\u003c/p\u003e\n\n\u003cp\u003e\u003ccode\u003eResources and Devices\u003c/code\u003e \u0026gt; \u003ccode\u003eGPU Configuration\u003c/code\u003e\n\u0026gt; 设置显卡直通的位置\n\u0026gt; 牙膏核显的话他会显示两个,不知道是不是故意这么设置的还是怎么,要有效得选第二个\u003c/p\u003e\n\n\u003cp\u003e\u003cimg src=\"/api/assets/8705f8e2-233c-4bed-8967-bb78b3142039\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003cp\u003e然后一直下移到最后安装就行了\u003c/p\u003e\n\n\u003ch2\u003e5. 安装 Jackett\u003c/h2\u003e\n\n\u003cp\u003e种子索引器,能不能找到对应的资源就完全靠他了,有 \u003ccode\u003ePT\u003c/code\u003e 的都给他设置下,没有的直接 \u003ccode\u003eRARGB\u003c/code\u003e 吧\u003c/p\u003e\n\n\u003cp\u003e老规矩名称填 \u003ccode\u003ejackett\u003c/code\u003e\u003c/p\u003e\n\n\u003cp\u003e\u003ccode\u003eNetworking and Services\u003c/code\u003e\n\u0026gt; 有域名的把 \u003ccode\u003eService Type\u003c/code\u003e 改 \u003ccode\u003eClusterIP\u003c/code\u003e 禁止直接 IP:PORT 访问,没有的跳过\u003c/p\u003e\n\n\u003cp\u003e\u003ccode\u003eIngress\u003c/code\u003e\n\u0026gt; 有域名的配置如 \u003ccode\u003ePlex\u003c/code\u003e,但是域名填 \u003ccode\u003ejackett.home\u003c/code\u003e\u003c/p\u003e\n\n\u003ch3\u003e添加 indexer\u003c/h3\u003e\n\n\u003cp\u003e上面的 \u003ccode\u003eAPI Key\u003c/code\u003e 先记录下来,下面第七步需要用到,点击 \u003ccode\u003eAdd indexer\u003c/code\u003e\n\u003cimg src=\"/api/assets/bd0a3ead-9cf2-48f1-a3a3-6307779d409c\" alt=\"alt text\" /\u003e\n找到 \u003ccode\u003eRARGB\u003c/code\u003e 并添加\n\u003cimg src=\"/api/assets/c0417ef5-47e1-48c5-89ce-4ae485235989\" alt=\"alt text\" /\u003e\n点击 \u003ccode\u003eCopy Torznab Feed\u003c/code\u003e 并记录下来,下面第七步需要用到\n\u003cimg src=\"/api/assets/bb1ca142-46cf-4daa-9d94-eaa73ee5f708\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003ch2\u003e6. 安装 Qbittorrent\u003c/h2\u003e\n\n\u003cp\u003e老规矩名称填 \u003ccode\u003eqbittorrent\u003c/code\u003e\u003c/p\u003e\n\n\u003cp\u003e\u003ccode\u003eStorage and Persistence\u003c/code\u003e\n\u0026gt; \u003ccode\u003eApp Config Storage\u003c/code\u003e 的类型修改为 \u003ccode\u003eHostPath\u003c/code\u003e,方便等会遇到访问面板未授权的时候能改配置文件,PVC 的也能改(忘了上哪能改了),文件夹要先自己建好,ssh 上去直接 mkdir 完事\u003c/p\u003e\n\n\u003cp\u003e\u003cimg src=\"/api/assets/59fce015-9b8f-4268-8dab-979a65cb91c2\" alt=\"alt text\" /\u003e\n添加下载文件夹挂载\n\u0026gt; 注意挂载点 \u003ccode\u003e/downloads\u003c/code\u003e 要跟下面的 Radarr \u0026amp; Sonarr 一致,否则他们找不到下载文件夹而无法导入下载完的视频文件,权限也得注意,这三最好保持一致,不过 \u003ccode\u003eTrueNAS Scale\u003c/code\u003e 好像都默认 uid/gid 为 \u003ccode\u003e568\u003c/code\u003e\u003c/p\u003e\n\n\u003cp\u003e\u003cimg src=\"/api/assets/4360ec90-f085-4502-a859-b28fdd9f528e\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003cp\u003e\u003ccode\u003eIngress\u003c/code\u003e\n\u0026gt; 有域名的配置如 \u003ccode\u003ePlex\u003c/code\u003e,但是域名填 \u003ccode\u003eqbittorrent.home\u003c/code\u003e\u003c/p\u003e\n\n\u003cp\u003e面板默认用户名/密码: admin/adminadmin\u003c/p\u003e\n\n\u003cp\u003e如果访问面板提示未授权(英文),修改配置文件 \u003ccode\u003e/mnt/data/ix-applications/qbittorrent/qBittorrent/qBittorrent.conf\u003c/code\u003e 添加 \u003ccode\u003eWebUI\\HostHeaderValidation=false\u003c/code\u003e 然后重启应用\u003c/p\u003e\n\n\u003cp\u003e访问面板后修改下载文件夹到 \u003ccode\u003e/downloads\u003c/code\u003e,然后开启 \u003ccode\u003eDHT\u003c/code\u003e 等\n\u003cimg src=\"/api/assets/0bb07bc7-0f16-4d0e-8423-eb2882fad16e\" alt=\"alt text\" /\u003e\nUPnP/NAT-PMP 的也开了(需要路由器开启对应服务才支持)\n\u003cimg src=\"/api/assets/397d6303-d611-4327-bd15-c0fd6db65144\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003cp\u003e然后 Tracker 的自己上网找一下\u003c/p\u003e\n\n\u003cp\u003e做种限制可以设置成做种过长时间后就取消做种甚至删除文件(反正已经导入了)\n\u003cimg src=\"/api/assets/d26301b7-3bc1-4288-9936-24de202f4953\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003ch2\u003e7. 安装 Radarr \u0026amp; Sonarr\u003c/h2\u003e\n\n\u003cp\u003e简介:待补充\u003c/p\u003e\n\n\u003ch3\u003e7.1. 安装\u003c/h3\u003e\n\n\u003cp\u003e这两配置类似所以写到一起说了\n自行对应名称分别填 \u003ccode\u003eradarr\u003c/code\u003e 和 \u003ccode\u003esonarr\u003c/code\u003e,\u003c/p\u003e\n\n\u003cp\u003e\u003ccode\u003eNetworking and Services\u003c/code\u003e\n\u0026gt; 有域名的把 \u003ccode\u003eService Type\u003c/code\u003e 改 \u003ccode\u003eClusterIP\u003c/code\u003e 禁止直接 IP:PORT 访问,没有的跳过\u003c/p\u003e\n\n\u003cp\u003e\u003ccode\u003eIngress\u003c/code\u003e\n\u0026gt; 有域名的配置如 \u003ccode\u003ePlex\u003c/code\u003e,但是域名分别填 \u003ccode\u003eradarr.home\u003c/code\u003e 和 \u003ccode\u003esonarr.home\u003c/code\u003e\u003c/p\u003e\n\n\u003cp\u003e\u003ccode\u003eStorage and Persistence\u003c/code\u003e\n\u0026gt; Configure Additional app storage 那点添加,\n\u0026gt; Radarr 侧是挂载 \u003ccode\u003e/mnt/data/videos/movies\u003c/code\u003e 到 \u003ccode\u003e/movies\u003c/code\u003e\n\u0026gt; Sonarr 侧是挂载 \u003ccode\u003e/mnt/data/videos/tv\u003c/code\u003e 到 \u003ccode\u003e/tv\u003c/code\u003e\n\u0026gt; 两者都挂载 \u003ccode\u003e/mnt/data/downloads\u003c/code\u003e 到 \u003ccode\u003e/downloads\u003c/code\u003e (这里的挂载点一定要跟 \u003ccode\u003eQbittorrent\u003c/code\u003e 上的挂载点保持一致,否则他们会无法找到下载完的视频文件从而无法导入到各自的媒体库而报错)\n\u0026gt; \u003cimg src=\"/api/assets/4b9619d9-2ad0-49fd-a1e2-8a03a32ec299\" alt=\"alt text\" /\u003e\n\u0026gt; \u003cimg src=\"/api/assets/d1748bdc-0177-4e2e-b7a8-b5da6aee530b\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003cp\u003e\u003ccode\u003eSecurity and Permissions\u003c/code\u003e\n\u0026gt; 设置 docker 的默认 uid/gid 等的,有需要自己改吧,不会就跟 \u003ccode\u003eQbittorrent\u003c/code\u003e 和 \u003ccode\u003ePlex\u003c/code\u003e 的保持一致别瞎改导致权限问题\u003c/p\u003e\n\n\u003ch3\u003e7.2. 配置\u003c/h3\u003e\n\n\u003cp\u003e~~打开他们的面板添加他们各自的媒体库,然后添加种子索引器,再添加下载器就行了~~\u003c/p\u003e\n\n\u003ch4\u003eRadarr 配置中文(Sonarr不支持)\u003c/h4\u003e\n\n\u003cp\u003e改完刷新生效\n\u003cimg src=\"/api/assets/50b51f95-613e-4432-a1f9-c7155f7612bb\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003ch4\u003eRadarr 导入媒体库\u003c/h4\u003e\n\n\u003cp\u003e点击导入现有影片然后点击开始导入,选择前面挂载上去的 \u003ccode\u003e/movies\u003c/code\u003e 既可\n\u003cimg src=\"/api/assets/00cc3d49-dc5e-4f8f-b150-5b7a9f5e6ce5\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003ch4\u003eSonarr 导入媒体库\u003c/h4\u003e\n\n\u003cp\u003e同上添加 \u003ccode\u003e/tv\u003c/code\u003e 既可\n\u003cimg src=\"/api/assets/a54ba868-58d8-4041-a6ba-16d00e3fb72c\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003ch4\u003eRadarr 添加搜刮器\u003c/h4\u003e\n\n\u003cp\u003e它们两需要搜刮器来查找资源,将第五步中添加的 \u003ccode\u003eindexer\u003c/code\u003e 给它们两加上,以 \u003ccode\u003eRARGB\u003c/code\u003e 为例\n点击搜刮器,然后点击上面的大大 \u003ccode\u003e+\u003c/code\u003e 按钮来添加,然后点击 \u003ccode\u003eTorznab\u003c/code\u003e 的自定义,一定要点这个而不是其他的地方,不然设置不一样\n\u003cimg src=\"/api/assets/d3db6c11-1367-41a7-bd3c-04f5a2d974d2\" alt=\"alt text\" /\u003e\n名字你们喜欢写啥就写啥,认得出来就行,然后 \u003ccode\u003eAPI Key\u003c/code\u003e 就是第五步里复制的那个,\u003ccode\u003eURL\u003c/code\u003e 就是第五步里点 \u003ccode\u003eCopy Torznab Feed\u003c/code\u003e 复制下来的那串,不过需要做些修改,修改下入口,他复制下来的这个,建议改成集群内网域名以加强性能,如果你的域名是你注册的有加解析并且能解析到正确的 \u003ccode\u003eIP\u003c/code\u003e 也可以直接用,不过还是建议改成内网的域名,如果你的域名在你的 \u003ccode\u003eNAS\u003c/code\u003e 上不能解析过去,那么必改,集群内网的域名规则可以用最上面提到的 \u003ca href=\"https://truecharts.org/manual/Quick-Start%20Guides/06-linking-apps/\"\u003eTruecharts 文档\u003c/a\u003e 里的生成器来生成,如果你是按照本篇文章配置的,你复制下来的会长下面这样\n\u003ccode\u003ehttps://jackett.home:9443/api/v2.0/indexers/rarbg/results/torznab/\u003c/code\u003e\n那么你应该改成下面这样填上去就行了\n\u003ccode\u003ehttp://jackett.ix-jackett.svc.cluster.local:9117/api/v2.0/indexers/rarbg/results/torznab/\u003c/code\u003e\n\u003cimg src=\"/api/assets/fa71f16d-c229-4203-997a-5aaa1b7ebf67\" alt=\"alt text\" /\u003e\n然后分类,把电影分类全勾上,不是电影的就别勾了,\u003ccode\u003eRARGB\u003c/code\u003e 的电影分类只有那么几个有用,不过忘了,看着像的都勾上问题也不大,100049 是电视剧的不用勾,有些勾了反而不行,按下面的勾就行了\n\u003cimg src=\"/api/assets/953917b1-7901-4422-a8c8-441ca406ccc2\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003ch4\u003eSonarr 添加搜刮器\u003c/h4\u003e\n\n\u003cp\u003e参数跟给 \u003ccode\u003eRadarr\u003c/code\u003e 一样的,除了分类\n\u003cimg src=\"/api/assets/48821fbc-a1dc-468b-a065-0c0de2f2c0f8\" alt=\"alt text\" /\u003e\n分类按这几个填就行了\n\u003cimg src=\"/api/assets/8792a706-80da-4305-9f4f-ff0db6b16cd9\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003ch4\u003e添加下载器\u003c/h4\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e以 Radarr 为例,Sonarr 类似\n点击你要的下载器就行,这里采用 \u003ccode\u003eQbittorrent\u003c/code\u003e\n\u003cimg src=\"/api/assets/aae20d18-cbd7-4dee-8b55-9a3efcb4caec\" alt=\"alt text\" /\u003e\n名字随意,Host 填集群内网地址 \u003ccode\u003eqbittorrent.ix-qbittorrent\u003c/code\u003e ,端口 \u003ccode\u003e10095\u003c/code\u003e,用户名默认 admin,密码默认 adminadmin\n\u003cimg src=\"/api/assets/0aa9462b-be01-4d9a-a359-dbbaa5d549ba\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003ch4\u003e启用元数据\u003c/h4\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e听说 Emby 的比较好,用来生成影片信息,如中文名,演员列表,简介啥的\n\u003cimg src=\"/api/assets/b6ada67b-7c5b-4644-866d-4c3f7ac7a8ae\" alt=\"alt text\" /\u003e\n\u003cimg src=\"/api/assets/1e2f4768-daef-4a6e-9c77-b08fc2b68eb8\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003ch2\u003e8. 安装 Overseerr\u003c/h2\u003e\n\n\u003cp\u003e老规矩名称填 \u003ccode\u003eoverseerr\u003c/code\u003e\u003c/p\u003e\n\n\u003cp\u003e\u003ccode\u003eNetworking and Services\u003c/code\u003e\n\u0026gt; 有域名的把 \u003ccode\u003eService Type\u003c/code\u003e 改 \u003ccode\u003eClusterIP\u003c/code\u003e 禁止直接 IP:PORT 访问,没有的跳过\u003c/p\u003e\n\n\u003cp\u003e\u003ccode\u003eIngress\u003c/code\u003e\n\u0026gt; 有域名的配置如 \u003ccode\u003ePlex\u003c/code\u003e,但是域名填 \u003ccode\u003eoverseerr.home\u003c/code\u003e\u003c/p\u003e\n\n\u003cp\u003e其他的都不用管全部默认\u003c/p\u003e\n\n\u003ch3\u003e配置\u003c/h3\u003e\n\n\u003cp\u003e初次打开会提示你登录,用 \u003ccode\u003ePlex\u003c/code\u003e 帐号登录后就是,然后开始配置 Plex,地址填 \u003ccode\u003eplex.ix-plex.svc.cluster.local\u003c/code\u003e,\u003ccode\u003eWeb App URL\u003c/code\u003e 填你的域名,如 \u003ccode\u003ehttps://plex.home:9443\u003c/code\u003e\n\u003cimg src=\"/api/assets/65cddccf-9f8a-4ca6-804c-42799d26bf9b\" alt=\"alt text\" /\u003e\n填完之后点 \u003ccode\u003eSave Changes\u003c/code\u003e 保存变化如果它成功连上的话,把它扫出来的库全部选上同步然后就可以开始下一步了\n\u003cimg src=\"/api/assets/d31ec60c-1f3c-41b7-8bdb-aede8bab9368\" alt=\"alt text\" /\u003e\n点第一个添加 \u003ccode\u003eRadarr\u003c/code\u003e 服务器,地址 \u003ccode\u003eradarr.ix-radarr.svc.cluster.local\u003c/code\u003e,\u003ccode\u003eAPI Key\u003c/code\u003e 可以从 \u003ccode\u003e设置 \u0026gt; 通用 \u0026gt; 安全 \u0026gt; API 密钥\u003c/code\u003e 查看到,填完之后点 \u003ccode\u003eTest\u003c/code\u003e 测试连接,通过后就可以选择影片质量了,按需选择,这里就选 \u003ccode\u003eAny\u003c/code\u003e,质量的配置可以在 \u003ccode\u003eRadarr\u003c/code\u003e 上随意改,然后 \u003ccode\u003eRoot folder\u003c/code\u003e 一般默认,有域名可以把 \u003ccode\u003eExtennal URL\u003c/code\u003e 添上,勾上 \u003ccode\u003eEnable Scan\u003c/code\u003e 然后点 \u003ccode\u003eAdd server\u003c/code\u003e 就行了\n\u003cimg src=\"/api/assets/0381ac77-4b3d-4a9c-9c77-9b02246f84ed\" alt=\"alt text\" /\u003e\n\u003cimg src=\"/api/assets/0e9c161a-7a93-4f18-8ec7-6bcf3e7a2bb0\" alt=\"alt text\" /\u003e\n然后第二个 \u003ccode\u003eSonarr\u003c/code\u003e 服务器类似的配置,地址 \u003ccode\u003esonarr.ix-sonarr.svc.cluster.local\u003c/code\u003e,剩下的都差不多\n\u003cimg src=\"/api/assets/f6a52a59-eefe-4962-a9e5-099e2326ed0c\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003cp\u003e剩下的设置中文的就自己去设置吧,至此整篇教程下来就差不多了,如果还有什么问题的话可以到 \u003ca href=\"https://t.me/FireRainOS\"\u003e本 TG 群\u003c/a\u003e 讨论\u003c/p\u003e\n", "date_published": "2022-01-14T08:54:12Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/23", "url": "https://blog.firerain.me/article/23", "title": "Arch Linux 下使用 Spicetify 美化 Spotify", "content_html": "\u003ch2\u003e效果图\u003c/h2\u003e\n\n\u003cp\u003e\u003cimg src=\"/api/assets/ea24ee44-1c07-4697-aa75-606c07836058\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003ch2\u003e安装 \u003ccode\u003eSpicetify CLI\u003c/code\u003e\u003c/h2\u003e\n\n\u003cp\u003e\u003ccode\u003ebash\nyay -S spicetify-cli\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e安装 \u003ccode\u003eSpicetify\u003c/code\u003e 主题\u003c/h2\u003e\n\n\u003cp\u003e\u003ccode\u003ebash\nyay -S spicetify-themes-git\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e修改权限以便 \u003ccode\u003eSpicetify\u003c/code\u003e 修改\u003c/h2\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e假设你装的是 AUR 里的或者 cn 源中的而不是 flatpak 版本\n\u003ccode\u003ebash\nsudo chmod a+wr /opt/spotify\nsudo chmod a+wr /opt/spotify/Apps -R\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e修改主题\u003c/h2\u003e\n\n\u003col\u003e\n\u003cli\u003e主题修改\n\u003ccode\u003ebash\nspicetify config current_theme THEME_NAME\n\u003c/code\u003e\nTHEME_NAME 为主题名称\u003c/li\u003e\n\u003cli\u003e配色修改\n\u003ccode\u003ebash\nspicetify config color_scheme SCHEME_NAME\n\u003c/code\u003e\nSCHEME_NAME 为配色方案名\n有些主题有 2 种或更多不同的配色方案。选择主题后,您可以在它们之间切换:\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003e主题名和配色名可以查看 \u003ca href=\"https://github.com/morpheusthewhite/spicetify-themes\"\u003ehttps://github.com/morpheusthewhite/spicetify-themes\u003c/a\u003e,不同主题可能有用用到扩展(.js文件),所以可以点开对应的主题,README.md 中应该会有写,但是对于扩展(.js)文件的安装就不需要了,因为你已经把主题装了,已经包含了。\u003c/p\u003e\n\n\u003col\u003e\n\u003cli\u003e如要安装效果图中的主题和配色则执行以下命令\n\u0026gt; 省略\u003ca href=\"https://github.com/morpheusthewhite/spicetify-themes/tree/master/Dribbblish#linux-and-macos\"\u003e官方教程\u003c/a\u003e中的前三行扩展安装\n\u003ccode\u003ebash\nspicetify config extensions dribbblish.js\nspicetify config current_theme Dribbblish color_scheme Nord-Light\nspicetify config inject_css 1 replace_colors 1 overwrite_assets 1\nspicetify apply\n\u003c/code\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\n\u003ch2\u003e应用主题\u003c/h2\u003e\n\n\u003cp\u003e\u003ccode\u003ebash\nspicetify apply\n\u003c/code\u003e\n如报以下错就执行 \u003ccode\u003espicetify backup apply\u003c/code\u003e\n\u003cimg src=\"/api/assets/e10aa131-52a1-425e-a13c-80b65f7499be\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003ch2\u003e广告拦截(可选)\u003c/h2\u003e\n\n\u003cp\u003e因为改完主题后原先显示广告的地方直接变成黑色了看着很不爽,所以可以考虑装下面这个包(内含一个so和desktop,不是取代原版),装完后从启动器打开 Spotify(adblock) 而不是 Spotify 既可\n\u003ccode\u003ebash\nyay -S spotify-adblock-git\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003eSpotify 更新\u003c/h2\u003e\n\n\u003cp\u003e更新后重新应用下\n\u003ccode\u003e\nspicetify backup apply\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e其他主题\u003c/h2\u003e\n\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/JulienMaille/dribbblish-dynamic-theme\"\u003eDribbblish 动态主题\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n", "date_published": "2021-08-18T04:46:26Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/22", "url": "https://blog.firerain.me/article/22", "title": "ArchLinux下Kubernetes初体验--使用 kubeadm 创建一个单主集群", "content_html": "\u003ch2\u003e前提说明\u003c/h2\u003e\n\n\u003cp\u003e节点发行版: Arch Linux\n节点主机名: k8s.master\n节点 \u003ccode\u003eIP\u003c/code\u003e: 192.168.1.190\nk8s 使用的运行时: docker\u003c/p\u003e\n\n\u003ch2\u003e前提准备\u003c/h2\u003e\n\n\u003ch3\u003e1. 设置主机名\u003c/h3\u003e\n\n\u003cp\u003e\u003ccode\u003ebash\nsudo hostnamectl set-hostname k8s.master\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch3\u003e2. 修改 \u003ccode\u003ehosts\u003c/code\u003e\u003c/h3\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003eIP 写自己的\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003e\u003ccode\u003ebash\necho \u0026quot;192.168.1.190 k8s.master\u0026quot; | sudo tee /etc/hosts\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e安装 Docker\u003c/h2\u003e\n\n\u003col\u003e\n\u003cli\u003e安装\n\u003ccode\u003ebash\nsudo pacman -S docker\n\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e添加 \u003ccode\u003edocker\u003c/code\u003e 用户组到 \u003ccode\u003ek8s.master\u003c/code\u003e 用户\n\u003ccode\u003ebash\nsudo gpasswd -a k8s.master docker\n\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e修改 \u003ccode\u003e/etc/docker/daemon.json\u003c/code\u003e (不存在则自行创建)\n\u0026gt; 因为 \u003ccode\u003earchlinux\u003c/code\u003e 默认用的 \u003ccode\u003esystemd\u003c/code\u003e,所以需要设置 \u003ccode\u003edocker\u003c/code\u003e 的 \u003ccode\u003ecgroupdriver\u003c/code\u003e 为 \u003ccode\u003esystemd\u003c/code\u003e,否则后面 \u003ccode\u003ekubeadm init\u003c/code\u003e 会警告。除了这个,其他的似乎默认就是就是这个值,但是如果你的文件系统使用的 \u003ccode\u003ebtrfs\u003c/code\u003e,就必须设置 docker 用 \u003ccode\u003eoverlay2\u003c/code\u003e 驱动,否则后面 \u003ccode\u003ekubeadm init\u003c/code\u003e 会过不了检测而报错。\n\u003ccode\u003ejson\ncat \u0026gt; /etc/docker/daemon.json \u0026lt;\u0026lt;EOF\n{\n\u0026quot;exec-opts\u0026quot;: [\u0026quot;native.cgroupdriver=systemd\u0026quot;],\n\u0026quot;log-driver\u0026quot;: \u0026quot;json-file\u0026quot;,\n\u0026quot;log-opts\u0026quot;: {\n\u0026quot;max-size\u0026quot;: \u0026quot;100m\u0026quot;\n},\n\u0026quot;storage-driver\u0026quot;: \u0026quot;overlay2\u0026quot;\n}\nEOF\n\u003c/code\u003e\u003c/li\u003e\n\n\u003cli\u003e\u003cp\u003e启用并启动服务\n\u003ccode\u003ebash\nsudo systemctl enable --now docker\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e安装需要的依赖\u003c/h2\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\n\u003cp\u003e\u003ccode\u003ebash\nsudo pacman -S ebtables ethtool conntrack-tools socat\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e安装 kubeadm 和 kubelet\u003c/h2\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003ekubeadm 的包在 \u003ccode\u003eAUR\u003c/code\u003e 有,而 kubelet 会作为它的依赖安装,这里使用 \u003ccode\u003eyay\u003c/code\u003e装\n\u003ccode\u003ebash\nyay -S kubeadm-bin\n\u003c/code\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003e然后启用和启动 \u003ccode\u003ekubelet\u003c/code\u003e 服务\u003c/p\u003e\n\n\u003cp\u003e\u003ccode\u003ebash\nsudo systemctl enable --now kubelet\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e初始化节点\u003c/h2\u003e\n\n\u003cp\u003e主节点是集群里运行控制面的机器,包括 etcd (集群的数据库)和 API 服务(kubectl CLI 与之交互)。\u003c/p\u003e\n\n\u003col\u003e\n\u003cli\u003e选择一个 Pod 网络插件,并检查是否在 kubeadm 初始化过程中需要传入什么参数。这个取决于 您选择的网络插件,您可能需要设置 \u003ccode\u003e--Pod-network-cidr\u003c/code\u003e 来指定网络驱动的 CIDR。请参阅\u003ca href=\"https://kubernetes.io/zh/docs/setup/independent/create-cluster-kubeadm/#Pod-network\"\u003e安装网络插件\u003c/a\u003e。\u003c/li\u003e\n\u003cli\u003e(可选) 从1.14版开始,\u003ccode\u003ekubeadm\u003c/code\u003e 尝试使用一系列众所周知的域套接字路径来检测 Linux 上的容器运行时。要使用不同的容器运行时,或者在预配置的节点上安装了多个容器,请将\u003ccode\u003e--cri-socket\u003c/code\u003e 参数指定为\u003ccode\u003ekubeadm init\u003c/code\u003e。请参阅\u003ca href=\"https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#installing-runtime\"\u003e安装运行时\u003c/a\u003e。\u003c/li\u003e\n\u003cli\u003e(可选) 除非特别指定,kubeadm 会使用默认网关所在的网络接口广播其主节点的 IP 地址。若需使用其他网络接口,请 给 \u003ccode\u003ekubeadm init\u003c/code\u003e 设置 \u003ccode\u003e--apiserver-advertise-address=\u003c/code\u003e 参数。如果需要部署 IPv6 的集群,则需要指定一个 IPv6 地址,比如 \u003ccode\u003e--apiserver-advertise-address=fd00::101\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e(可选) 在运行 \u003ccode\u003ekubeadm init\u003c/code\u003e 之前请先执行 \u003ccode\u003ekubeadm config images pull\u003c/code\u003e 来测试与 gcr.io 的连接。\u003c/li\u003e\n\u003c/ol\u003e\n\n\u003cp\u003e注:因为国内的特殊环境,请自行准备好科学上网,镜像源什么的都是狗屁。\u003c/p\u003e\n\n\u003cp\u003e本文 Pod 网络插件用的是 \u003ccode\u003eCilium\u003c/code\u003e,所以需要设置 \u003ccode\u003e--pod-network-cidr=10.217.0.0/16\u003c/code\u003e,命令如下\u003c/p\u003e\n\n\u003cp\u003e\u003ccode\u003e\nsudo kubeadm init --pod-network-cidr=10.217.0.0/16\n\u003c/code\u003e\u003c/p\u003e\n\n\u003cp\u003e然后正常的输出类似这样\n```\nW0424 10:44:33.214484 3649 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]\n[init] Using Kubernetes version: v1.18.2\n[preflight] Running pre-flight checks\n[preflight] Pulling images required for setting up a Kubernetes cluster\n[preflight] This might take a minute or two, depending on the speed of your internet connection\n[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'\n[kubelet-start] Writing kubelet environment file with flags to file \u0026quot;/var/lib/kubelet/kubeadm-flags.env\u0026quot;\n[kubelet-start] Writing kubelet configuration to file \u0026quot;/var/lib/kubelet/config.yaml\u0026quot;\n[kubelet-start] Starting the kubelet\n[certs] Using certificateDir folder \u0026quot;/etc/kubernetes/pki\u0026quot;\n[certs] Generating \u0026quot;ca\u0026quot; certificate and key\n[certs] Generating \u0026quot;apiserver\u0026quot; certificate and key\n[certs] apiserver serving cert is signed for DNS names [k8s.master kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 192.168.1.190]\n[certs] Generating \u0026quot;apiserver-kubelet-client\u0026quot; certificate and key\n[certs] Generating \u0026quot;front-proxy-ca\u0026quot; certificate and key\n[certs] Generating \u0026quot;front-proxy-client\u0026quot; certificate and key\n[certs] Generating \u0026quot;etcd/ca\u0026quot; certificate and key\n[certs] Generating \u0026quot;etcd/server\u0026quot; certificate and key\n[certs] etcd/server serving cert is signed for DNS names [k8s.master localhost] and IPs [192.168.1.190 127.0.0.1 ::1]\n[certs] Generating \u0026quot;etcd/peer\u0026quot; certificate and key\n[certs] etcd/peer serving cert is signed for DNS names [k8s.master localhost] and IPs [192.168.1.190 127.0.0.1 ::1]\n[certs] Generating \u0026quot;etcd/healthcheck-client\u0026quot; certificate and key\n[certs] Generating \u0026quot;apiserver-etcd-client\u0026quot; certificate and key\n[certs] Generating \u0026quot;sa\u0026quot; key and public key\n[kubeconfig] Using kubeconfig folder \u0026quot;/etc/kubernetes\u0026quot;\n[kubeconfig] Writing \u0026quot;admin.conf\u0026quot; kubeconfig file\n[kubeconfig] Writing \u0026quot;kubelet.conf\u0026quot; kubeconfig file\n[kubeconfig] Writing \u0026quot;controller-manager.conf\u0026quot; kubeconfig file\n[kubeconfig] Writing \u0026quot;scheduler.conf\u0026quot; kubeconfig file\n[control-plane] Using manifest folder \u0026quot;/etc/kubernetes/manifests\u0026quot;\n[control-plane] Creating static Pod manifest for \u0026quot;kube-apiserver\u0026quot;\n[control-plane] Creating static Pod manifest for \u0026quot;kube-controller-manager\u0026quot;\nW0424 10:44:39.076137 3649 manifests.go:225] the default kube-apiserver authorization-mode is \u0026quot;Node,RBAC\u0026quot;; using \u0026quot;Node,RBAC\u0026quot;\n[control-plane] Creating static Pod manifest for \u0026quot;kube-scheduler\u0026quot;\nW0424 10:44:39.078329 3649 manifests.go:225] the default kube-apiserver authorization-mode is \u0026quot;Node,RBAC\u0026quot;; using \u0026quot;Node,RBAC\u0026quot;\n[etcd] Creating static Pod manifest for local etcd in \u0026quot;/etc/kubernetes/manifests\u0026quot;\n[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory \u0026quot;/etc/kubernetes/manifests\u0026quot;. This can take up to 4m0s\n[kubelet-check] Initial timeout of 40s passed.\n[apiclient] All control plane components are healthy after 44.703985 seconds\n[upload-config] Storing the configuration used in ConfigMap \u0026quot;kubeadm-config\u0026quot; in the \u0026quot;kube-system\u0026quot; Namespace\n[kubelet] Creating a ConfigMap \u0026quot;kubelet-config-1.18\u0026quot; in namespace kube-system with the configuration for the kubelets in the cluster\n[upload-certs] Skipping phase. Please see --upload-certs\n[mark-control-plane] Marking the node k8s.master as control-plane by adding the label \u0026quot;node-role.kubernetes.io/master=''\u0026quot;\n[mark-control-plane] Marking the node k8s.master as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule]\n[bootstrap-token] Using token: motoro.enp8s72hg2939ez5\n[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles\n[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to get nodes\n[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials\n[bootstrap-token] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token\n[bootstrap-token] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster\n[bootstrap-token] Creating the \u0026quot;cluster-info\u0026quot; ConfigMap in the \u0026quot;kube-public\u0026quot; namespace\n[kubelet-finalize] Updating \u0026quot;/etc/kubernetes/kubelet.conf\u0026quot; to point to a rotatable kubelet client certificate and key\n[addons] Applied essential addon: CoreDNS\n[addons] Applied essential addon: kube-proxy\u003c/p\u003e\n\n\u003cp\u003eYour Kubernetes control-plane has initialized successfully!\u003c/p\u003e\n\n\u003cp\u003eTo start using your cluster, you need to run the following as a regular user:\u003c/p\u003e\n\n\u003cp\u003emkdir -p $HOME/.kube\n sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config\n sudo chown $(id -u):$(id -g) $HOME/.kube/config\u003c/p\u003e\n\n\u003cp\u003eYou should now deploy a pod network to the cluster.\nRun \u0026quot;kubectl apply -f [podnetwork].yaml\u0026quot; with one of the options listed at:\n https://kubernetes.io/docs/concepts/cluster-administration/addons/\u003c/p\u003e\n\n\u003cp\u003eThen you can join any number of worker nodes by running the following on each as root:\u003c/p\u003e\n\n\u003cp\u003ekubeadm join 192.168.1.190:6443 --token 8rpm43.m0ddibaxnn3if4m9 \\\n --discovery-token-ca-cert-hash sha256:11c8ddea496861d3f8d44a70e0d9ff88bf9f842115b78416e534dc765b75b942\n```\u003c/p\u003e\n\n\u003cp\u003e要使您的非root用户能用 \u003ccode\u003ekubectl\u003c/code\u003e,请运行以下命令,这些命令也是 \u003ccode\u003ekubeadm init\u003c/code\u003e 输出的一部分\n\u003ccode\u003ebash\nmkdir -p $HOME/.kube\nsudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config\nsudo chown $(id -u):$(id -g) $HOME/.kube/config\n\u003c/code\u003e\n或者,如果您是 \u003ccode\u003eroot\u003c/code\u003e 用户,则可以运行\n\u003ccode\u003ebash\nexport KUBECONFIG=/etc/kubernetes/admin.conf\n\u003c/code\u003e\u003c/p\u003e\n\n\u003cp\u003e保存好输出的 \u003ccode\u003ekubeadm join\u003c/code\u003e 命令 \u003ccode\u003ekubeadm init\u003c/code\u003e。您需要此命令将节点加入集群。如上面的 \u003ccode\u003ekubeadm join 192.168.1.190:6443 --token 8rpm43.m0ddibaxnn3if4m9 --discovery-token-ca-cert-hash sha256:11c8ddea496861d3f8d44a70e0d9ff88bf9f842115b78416e534dc765b75b942\u003c/code\u003e\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e如果 token 过期了或者没了,可以根据下面重新获取\u003c/p\u003e\n\n\u003cp\u003e如果 token 过期了\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003e可以使用 \u003ccode\u003ekubeadm token create --print-join-command\u003c/code\u003e 重新生成并打印加入集群的命令\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e如果 token 过期了\n1. 在主节点上使用 \u003ccode\u003ekubeadm token list\u003c/code\u003e 获取(如果没输出就是token过期了)\n如输出类似这样\n\u003ccode\u003ebash\nTOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPS\nujds42.ufzzpjuqapdjyfbi 23h 2020-05-26T11:45:01Z authentication,signing \u0026lt;none\u0026gt; system:bootstrappers:kubeadm:default-node-token\n\u003c/code\u003e\n3. 获取 \u003ccode\u003e--discovery-token-ca-cert-hash\u003c/code\u003e 值\n\u003ccode\u003ebash\nopenssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2\u0026gt;/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'\n\u003c/code\u003e\n如输出类似这样\n\u003ccode\u003ebash\nfee9f23599349bc403d7fc54650bab5ebf6e7c6f51b83eda728c43926343a92b\n\u003c/code\u003e\n那么完整的加入集群的命令则长这样\n\u003ccode\u003ebash\nkubeadm join 192.168.1.190:6443 --token ujds42.ufzzpjuqapdjyfbi --discovery-token-ca-cert-hash sha256:fee9f23599349bc403d7fc54650bab5ebf6e7c6f51b83eda728c43926343a92b\n\u003c/code\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003ch2\u003e安装 \u003ccode\u003ekubectl\u003c/code\u003e\u003c/h2\u003e\n\n\u003cp\u003e\u003ccode\u003ebash\nsudo pacman -S kubectl\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e节卡节点运行状态和 \u003ccode\u003ePod\u003c/code\u003e 运行状态\u003c/h2\u003e\n\n\u003cp\u003e\u003ccode\u003ebash\nkubectl get cs\nkubectl get node\nkubectl get pods --all-namespaces\n\u003c/code\u003e\u003c/p\u003e\n\n\u003cp\u003e结果类似如下\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003ecoredns 需要安装 Pod 网络插件后才会去跑\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003e\u003cimg src=\"/api/assets/eeab830d-9d3f-4d88-9bd3-bf84f31a291c\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003ch2\u003ePod 网络插件安装\u003c/h2\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e这里使用 Cilium\n\u003ccode\u003e\nkubectl create -f https://raw.githubusercontent.com/cilium/cilium/v1.6/install/kubernetes/quick-install.yaml\n\u003c/code\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003ch2\u003e控制平面节点隔离\u003c/h2\u003e\n\n\u003cp\u003e默认情况下,出于安全原因,您的群集不会在控制平面节点上调度Pod。如果您希望能够在控制平面节点上调度Pod,例如用于单机Kubernetes集群进行开发,请运行:\u003c/p\u003e\n\n\u003cp\u003e\u003ccode\u003ebash\nkubectl taint nodes --all node-role.kubernetes.io/master-\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e部署 Dashboard UI\u003c/h2\u003e\n\n\u003cp\u003e\u003ccode\u003e\nkubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta4/aio/deploy/recommended.yaml\n\u003c/code\u003e\n创建用户看\u003ca href=\"https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/creating-sample-user.md\"\u003e官方文档\u003c/a\u003e\u003c/p\u003e\n\n\u003cp\u003e然后用\u003ccode\u003ekubectl\u003c/code\u003e 工具访问 \u003ccode\u003eDashboard\u003c/code\u003e,命令如下\n\u003ccode\u003e\nkubectl proxy\n\u003c/code\u003e\n然后通过 \u003ccode\u003ehttp://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/\u003c/code\u003e 访问\u003c/p\u003e\n\n\u003cp\u003e如果要外网访问,可以这样\n\u003ccode\u003e\nkubectl proxy --address=0.0.0.0 --accept-hosts='^*$'\n\u003c/code\u003e\n但是这样你只能访问登录界面,Dashboard 不推荐允许外网访问,Http 访问只允许 \u003ccode\u003elocalhost\u003c/code\u003e 和 \u003ccode\u003e127.0.0.1\u003c/code\u003e,如果你只是自己玩玩看可以像下面这样操作,以下操作不推荐在生产环境使用。\n\u003ccode\u003e\nkubectl -n kubernetes-dashboard edit service kubernetes-dashboard\n\u003c/code\u003e\n然后修改这个地方的值为以下\n\u003cimg src=\"/api/assets/4adf476d-bbd3-4ff8-847d-cd46a153e0ad\" alt=\"alt text\" /\u003e\n然后保存退出\n然后再使用 \u003ccode\u003ekubectl -n kubernetes-dashboard get service kubernetes-dashboard\u003c/code\u003e 查看监听的端口\n\u003cimg src=\"/api/assets/fd47447f-929e-4c2e-b27b-1de7d416c39b\" alt=\"alt text\" /\u003e\n比如我这里端口是 \u003ccode\u003e32290\u003c/code\u003e,那么我这里访问的地址应该是 \u003ccode\u003ehttps://k8s.master:32290\u003c/code\u003e,同理将域名/IP还有端口换成你的既可\n\u0026gt; 注:\u003ccode\u003eChrome\u003c/code\u003e 默认不让用自签名的证书,可以使用 \u003ccode\u003eFireFox\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e清理\u003c/h2\u003e\n\n\u003cp\u003e如果要重新进行以上步骤,可以进行以下步骤来清理该节点。\u003c/p\u003e\n\n\u003col\u003e\n\u003cli\u003e删除节点\u003c/li\u003e\n\u003c/ol\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e在本文中 \u003cnode name\u003e 为 \u003ccode\u003ek8s.master\u003c/code\u003e\n\u003ccode\u003ebash\nkubectl drain \u0026lt;node name\u0026gt; --delete-local-data --force --ignore-daemonsets\nkubectl delete node \u0026lt;node name\u0026gt;\n\u003c/code\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003col\u003e\n\u003cli\u003e重置所有\u003ccode\u003ekubeadm\u003c/code\u003e安装状态:\u003c/li\u003e\n\u003c/ol\u003e\n\n\u003cp\u003e\u003ccode\u003ebash\nsudo kubeadm reset\n\u003c/code\u003e\u003c/p\u003e\n\n\u003col\u003e\n\u003cli\u003e重置 \u003ccode\u003eiptables\u003c/code\u003e 规则\u003c/li\u003e\n\u003c/ol\u003e\n\n\u003cp\u003e\u003ccode\u003ebash\nsudo iptables -F \u0026amp;\u0026amp; sudo iptables -t nat -F \u0026amp;\u0026amp; sudo iptables -t mangle -F \u0026amp;\u0026amp; sudo iptables -X\n\u003c/code\u003e\u003c/p\u003e\n\n\u003col\u003e\n\u003cli\u003e如果要重置 \u003ccode\u003eIPVS\u003c/code\u003e 表,则必须运行以下命令\u003c/li\u003e\n\u003c/ol\u003e\n\n\u003cp\u003e\u003ccode\u003ebash\nipvsadm -C\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003ekubeadm 故障排除\u003c/h2\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e看官方文档吧\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003e\u003ca href=\"https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/troubleshooting-kubeadm\"\u003ehttps://kubernetes.io/docs/setup/production-environment/tools/kubeadm/troubleshooting-kubeadm\u003c/a\u003e\u003c/p\u003e\n", "date_published": "2020-04-25T11:39:50Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/21", "url": "https://blog.firerain.me/article/21", "title": "记 Btrfs 的一次分区损坏修复", "content_html": "\u003cp\u003e其实吧,Btrfs 还是很稳的,那么我为什么会挂呢,其实一切的一切都要从一只蝙蝠说起,啊呸,从 win 的 \u003ca href=\"https://github.com/maharmstone/btrfs\"\u003eBtrfs\u003c/a\u003e 驱动说起,由于 win 那边的分区太小,然后 命运2 Proton 跑不起来,然后就在 win 上装了那个驱动,装之前就知道这肯定会出事,这不,文件系统坏了,很久以前,就用过一个付费的 ext4 驱动,然后也是用了几天,分区就挂载不上了,而且还是仅挂载着,什么都没干,这次也一样,而且除了命运2的文件夹其他都是设置的只读的,装上的头两天倒是没事,打了两天命运2也就不打了打其他在 win 的分区上的游戏,所以在 win 上也是仅仅挂载了,直到前两天我好像在内核日志里看到了 Btrfs 的报错,不过没在意,直到昨晚,我突然发现我分区变只读了\u003c/p\u003e\n\n\u003cp\u003e报错长这样\n\u003cimg src=\"/api/assets/d3555b3a-815e-4338-adfb-f74a543e6ac0\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003cp\u003e把分区卸载后用 \u003ccode\u003ebtrfs check /dev/sdaX\u003c/code\u003e 检测下,毫无疑问检测没过\n\u0026gt; 截图的时候忘了分区没法写入,所以图片没了\u003c/p\u003e\n\n\u003cp\u003e然后用 \u003ccode\u003ebtrfsck --repair /dev/sdaX\u003c/code\u003e 尝试修复下,依旧报错\u003c/p\u003e\n\n\u003cp\u003e本来这时候差不多要放弃了准备备份然后重建文件系统,备份好后做下垂死挣扎,用 \u003ccode\u003emount -o recovery /dev/sdaX /mnt\u003c/code\u003e 挂载看看,意外发现它能读写了,卸载,不加 \u003ccode\u003erecovery\u003c/code\u003e 看看,还是能读写,居然加个参数就解决了只读问题,不过 \u003ccode\u003ebtrfs check /dev/sdaX\u003c/code\u003e 依旧是报错吧,那就 \u003ccode\u003ebtrfsck --repair --init-extent-tree /dev/sdaX\u003c/code\u003e 看看吧,等了 50 分钟左右跑完了,700G+,用了 600G+ 的分区\n\u003cimg src=\"/api/assets/b01e3f33-b483-4c52-8f66-4064e3b4a6ab\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003cp\u003e然后再检测下,他好了,数据都还在\n\u003cimg src=\"/api/assets/3f9712a9-b3d1-4c42-aaf8-44592df49bf6\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003cp\u003e果然 win 上的什么 Btrfs 驱动,ext4 驱动什么的,还是不靠谱啊,还是慎用吧,除非这个分区只给 win 用,而且没啥重要数据\u003c/p\u003e\n", "date_published": "2020-03-09T08:28:03Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/20", "url": "https://blog.firerain.me/article/20", "title": "openwrt编译--newifi 2(D1)编译笔记", "content_html": "\u003ch1\u003e前言\u003c/h1\u003e\n\n\u003cp\u003e\u003ccode\u003e\u0026lt;*\u0026gt;\u003c/code\u003e 表示选中\n\u003ccode\u003e\u0026lt; \u0026gt;\u003c/code\u003e 表示不选中\u003c/p\u003e\n\n\u003ch2\u003e1. 切型号\u003c/h2\u003e\n\n\u003cp\u003e\u003ccode\u003e\nTarget System (MediaTek Ralink MIPS) ---\u0026gt; \nSubtarget (MT7621 based boards) ---\u0026gt;\nTarget Profile (Newifi D1) ---\u0026gt;\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e2. LUCI(web界面、主题、中文)\u003c/h2\u003e\n\n\u003cp\u003e```\nLuCI ---\u0026gt;\n 1. Collections ---\u0026gt;\n \u0026lt;\u003cem\u003e\u0026gt; luci\n 2. Modules ---\u0026gt;\n Translations ---\u0026gt;\n \u0026lt;\u003c/em\u003e\u0026gt; Chinese (zh-cn)\n Themes ---\u0026gt;\n \u0026lt;*\u0026gt; luci-theme-material\u003c/p\u003e\n\n\u003cp\u003e```\u003c/p\u003e\n\n\u003ch2\u003e3. SD卡、USB支持\u003c/h2\u003e\n\n\u003cp\u003e\u003ccode\u003e\nBase system ---\u0026gt;\n \u0026lt;*\u0026gt; block-mount\nKernel modules ---\u0026gt;\n Filesystems ---\u0026gt;\n \u0026lt;*\u0026gt; kmod-fs-autofs4\n \u0026lt;*\u0026gt; kmod-fs-btrfs\n \u0026lt;*\u0026gt; kmod-fs-exfat\n \u0026lt;*\u0026gt; kmod-fs-ext4\n \u0026lt;*\u0026gt; kmod-fs-f2fs\n \u0026lt;*\u0026gt; kmod-fs-ntfs\n \u0026lt;*\u0026gt; kmod-fs-vfat\n Other modules ---\u0026gt;\n \u0026lt;*\u0026gt; kmod-sdhci\n \u0026lt;*\u0026gt; kmod-sdhci-mt7620\n USB Support ---\u0026gt;\n -*- kmod-usb-core\n \u0026lt;*\u0026gt; kmod-usb-ohci\n -*- kmod-usb-storage\n \u0026lt;*\u0026gt; kmod-usb-storage-extras\n \u0026lt;*\u0026gt; kmod-usb-uhci\n \u0026lt;*\u0026gt; kmod-usb2\n \u0026lt;*\u0026gt; kmod-usb3\n Utilities ---\u0026gt;\n Filesystem ---\u0026gt;\n \u0026lt;*\u0026gt; badblocks\n \u0026lt;*\u0026gt; btrfs-progs\n [*] Build with zstd support\n -*- ntfs-3g\n [*] use external FUSE library, selects package libfuse \n [*] install the ntfs-3g.probe utility (NEW)\n \u0026lt;*\u0026gt; ntfs-3g-utils\n Disc ---\u0026gt;\n \u0026lt;*\u0026gt; fdisk\n \u0026lt;*\u0026gt; usbutils\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e4. NFS支持\u003c/h2\u003e\n\n\u003cp\u003e\u003ccode\u003e\nKernel modules ---\u0026gt;\n Filesystems ---\u0026gt;\n \u0026lt;*\u0026gt; kmod-fs-exportfs\n -*- kmod-fs-nfs\n -*- kmod-fs-nfs-common\n -*- kmod-fs-nfs-common-rpcsec\n \u0026lt;*\u0026gt; kmod-fs-nfs-v3 \n \u0026lt;*\u0026gt; kmod-fs-nfs-v4\n \u0026lt;*\u0026gt; kmod-fs-nfsd\n Utilities ---\u0026gt;\n Filesystem ---\u0026gt;\n \u0026lt;*\u0026gt; nfs-utils\n \u0026lt;*\u0026gt; nfs-utils-libs\nNetwork ---\u0026gt;\n Filesystem ---\u0026gt;\n \u0026lt;*\u0026gt; nfs-kernel-server\n \u0026lt;*\u0026gt; nfs-kernel-server-utils\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e5. aria2c\u003c/h2\u003e\n\n\u003cp\u003e\u003ccode\u003e\nLuCI ---\u0026gt;\n 3. Applications ---\u0026gt;\n \u0026lt;*\u0026gt; luci-app-aria2\nNetwork ---\u0026gt;\n Download Manager ---\u0026gt;\n \u0026lt;*\u0026gt; webui-aria2\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e6. samba4\u003c/h2\u003e\n\n\u003cp\u003e\u003ccode\u003e\nLuCI ---\u0026gt;\n 3. Applications ---\u0026gt;\n \u0026lt;*\u0026gt; luci-app-samba4\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e7. 广告拦截(koolproxy)\u003c/h2\u003e\n\n\u003cp\u003e参考 \u003ca href=\"https://blog.firerain.me/article/9\"\u003eopenwrt编译--koolproxy篇\u003c/a\u003e\u003c/p\u003e\n\n\u003ch2\u003e8. Other\u003c/h2\u003e\n\n\u003cp\u003e\u003ccode\u003e\nBase system ---\u0026gt;\n \u0026lt; \u0026gt; dnsmasq\n \u0026lt;*\u0026gt; dnsmasq-full\n\u003c/code\u003e\u003c/p\u003e\n", "date_published": "2020-01-02T13:06:40Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/19", "url": "https://blog.firerain.me/article/19", "title": "Arch Linux 下使用 viper4linux 提升音质", "content_html": "\u003ch2\u003e\u003ca href=\"https://github.com/noahbliss/Viper4Linux\"\u003eViper4Linux\u003c/a\u003e - An Adaptive Digital Sound Processor\u003c/h2\u003e\n\n\u003ch2\u003e安装 (以下假定你的 \u003ca href=\"https://wiki.archlinux.org/index.php/AUR_helpers\"\u003e\u003ccode\u003eAUR helpers\u003c/code\u003e\u003c/a\u003e 为 \u003ccode\u003eyay\u003c/code\u003e)\u003c/h2\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e安装 \u003ccode\u003eviper4linux\u003c/code\u003e 包\n\u003ccode\u003e\nyay -S viper4linux-git\n\u003c/code\u003e\n安装 \u003ccode\u003eviper4linux GUI\u003c/code\u003e 包\n\u003ccode\u003e\nyay -S viper4linux-gui-git\n\u003c/code\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003ch2\u003e配置\u003c/h2\u003e\n\n\u003ch3\u003e1. 在启动器中启动 viper4linux\u003c/h3\u003e\n\n\u003cp\u003e\u003cimg src=\"/api/assets/d1d07a16-c729-4fa5-bf1b-4532276b30d7\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003ch3\u003e2. 全部手动配置或者点击左下角的按钮(复制图标那个)导入 Android 的配置文件或者直接导入Github Repo\u003c/h3\u003e\n\n\u003cp\u003e比如导入Github Repo\u003c/p\u003e\n\n\u003cp\u003e\u003cimg src=\"/api/assets/fe871961-2244-47db-91ab-f6fe09a07e90\" alt=\"alt text\" /\u003e\n等显示下载完成(英文)后\n\u003cimg src=\"/api/assets/418b521b-9314-4577-86ff-28688062fe44\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003cp\u003e然后 Viper4Linux 就会成会你的默认输出设备\n\u003cimg src=\"/api/assets/9701e46e-7a80-438b-9f72-b1c24d416e9e\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003ch3\u003e4. 修复viper4linux在非英文状态下(LANG变量不是英文的值)无法获取默认输出设备的问题\u003c/h3\u003e\n\n\u003cp\u003e编辑 \u003ccode\u003e/usr/bin/viper\u003c/code\u003e\n根据 \u003ca href=\"https://github.com/xiayesuifeng/Viper4Linux/commit/17e4fef9e12e32415425d77276aca552aa79ed0a\"\u003e此修改\u003c/a\u003e 进行修改既可\u003c/p\u003e\n\n\u003ch3\u003e3. 为他指定一个输出设备(可选)\u003c/h3\u003e\n\n\u003cp\u003e\u003ccode\u003evim ~/.config/viper4linux/devices.conf\u003c/code\u003e\u003c/p\u003e\n\n\u003chr /\u003e\n\n\u003cp\u003e\u003ccode\u003edesc=\u0026quot;Speakers\u0026quot; location=alsa_output.pci-0000_00_1f.3.analog-stereo\u003c/code\u003e\n\u0026gt; 其中上面的这个 \u003ccode\u003ealsa_output.pci-0000_00_1f.3.analog-stereo\u003c/code\u003e 是我这的名字,想要获取你的所有输出设备的名字只需要这样\n\u0026gt; \u003ccode\u003ebash\n\u0026gt; env LANG=C pactl list sinks | grep \u0026quot;Name: \u0026quot; -A1\n\u0026gt;\u003c/code\u003e\n\u0026gt; \u003cimg src=\"/api/assets/6cc611d5-7204-45df-b2bf-431b95f24cb6\" alt=\"alt text\" /\u003e\n\u0026gt; 然后把上面的名字换成你的就行了,如果你还有(蓝牙)耳机,你也可以写(蓝牙)耳机的,然后你输出设备就是(蓝牙)耳机了,即使拔掉了耳机\u003c/p\u003e\n\n\u003cp\u003e最后点下 viper4linux gui 的上 reload viper 或者 apply,甚至终端输入 viper restart 都行\u003c/p\u003e\n\n\u003cp\u003e注: 如果需要改变输出设备又不想每次都去改上面的配置文件,也可以这样(KDE),\n在有声音输出的情况下,修改 gst-launch-1.0: Playback Stream 的输出设备为你要的既可\n\u003cimg src=\"/api/assets/106a9dbd-4487-4bf5-83ed-3e1e0d4cc873\" alt=\"alt text\" /\u003e\u003c/p\u003e\n\n\u003ch3\u003e4. viper ctl\u003c/h3\u003e\n\n\u003cp\u003e```bash\u003c/p\u003e\n\n\u003ch1\u003e启动 viper 服务\u003c/h1\u003e\n\n\u003cp\u003eviper start\u003c/p\u003e\n\n\u003ch1\u003e重启 viper 服务\u003c/h1\u003e\n\n\u003cp\u003eviper restart\u003c/p\u003e\n\n\u003ch1\u003e停止 viper 服务\u003c/h1\u003e\n\n\u003cp\u003eviper stop\n```\u003c/p\u003e\n\n\u003cp\u003e注: 如要开机自启就把 \u003ccode\u003eviper start\u003c/code\u003e 加到 \u003ccode\u003e.xprofile\u003c/code\u003e 什么的\u003c/p\u003e\n\n\u003ch3\u003e5. 最后 viper4linux 的配置就自由发挥了\u003c/h3\u003e\n", "date_published": "2019-11-11T10:05:26Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/18", "url": "https://blog.firerain.me/article/18", "title": "使用gin+jwt实现身份验证功能", "content_html": "\u003ch2\u003eJWT\u003c/h2\u003e\n\n\u003cp\u003eJSON Web Token (JWT) 是一种 Internet 标准,用于创建基于JSON的访问令牌,用于声明一些声明。例如,服务器可以生成具有声明“以管理员身份登录”并将其提供给客户端的令牌。然后,客户端可以使用该令牌来证明它以管理员身份登录。令牌由一方的私钥签名,以便双方能够验证令牌是否合法。\n\u0026gt; 来自 \u003ca href=\"https://en.wikipedia.org/wiki/JSON_Web_Token\"\u003e维基百科\u003c/a\u003e\u003c/p\u003e\n\n\u003ch2\u003egin的jwt中间件 - \u003ca href=\"https://github.com/appleboy/gin-jwt\"\u003egin-jwt\u003c/a\u003e\u003c/h2\u003e\n\n\u003cp\u003ego的 \u003ccode\u003ejwt\u003c/code\u003e 的实现库有 \u003ca href=\"https://github.com/dgrijalva/jwt-go\"\u003ejwt-go\u003c/a\u003e 等,我们下面直接用封装好的 \u003ca href=\"https://github.com/appleboy/gin-jwt\"\u003egin-jwt\u003c/a\u003e 库,这个库封装的就是 \u003ccode\u003ejwt-go\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e结构体 \u003ccode\u003ejwt.GinJWTMiddleware\u003c/code\u003e 的部分字段说明\u003c/h2\u003e\n\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003eRealm\u003c/code\u003e\n\u0026gt; JWT标识\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eKey\u003c/code\u003e\n\u0026gt; 服务端密钥\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eTimeout\u003c/code\u003e\n\u0026gt; token 过期时间\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eMaxRefresh\u003c/code\u003e\n\u0026gt; token 更新时间\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ePayloadFunc\u003c/code\u003e\n\u0026gt; 添加额外业务相关的信息\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eAuthenticator\u003c/code\u003e\n\u0026gt; 在登录接口中使用的验证方法,并返回验证成功后的用户对象。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eAuthorizator\u003c/code\u003e\n\u0026gt; 登录后验证传入的 token 方法,可在此处写权限验证逻辑\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eUnauthorized\u003c/code\u003e\n\u0026gt; 验证失败后的函数调用,可用于自定义返回的 \u003ccode\u003eJSON\u003c/code\u003e 格式之类的\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eTokenLookup\u003c/code\u003e\n\u0026gt; 设置 token 获取位置,默认值 \u003ccode\u003eheader:Authorization\u003c/code\u003e,可用的值:\n\u0026gt; - \u0026quot;\u003ccode\u003eheader:\u0026lt;name\u0026gt;\u003c/code\u003e\u0026quot;\n\u0026gt; - \u0026quot;\u003ccode\u003equery:\u0026lt;name\u0026gt;\u003c/code\u003e\u0026quot;\n\u0026gt; - \u0026quot;\u003ccode\u003ecookie:\u0026lt;name\u0026gt;\u003c/code\u003e\u0026quot;\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eTokenHeadName\u003c/code\u003e\n\u0026gt; Header 中 token 的头部字段,默认值 \u003ccode\u003eBearer\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003ch2\u003e使用教程\u003c/h2\u003e\n\n\u003cp\u003e\u003ccode\u003egin-jwt\u003c/code\u003e 的使用其实非常简单,大致步骤就是配置下中间件然后在需要验证的api中用这个中间件就行了,多说无义,下面来实践下\u003c/p\u003e\n\n\u003cul\u003e\n\u003cli\u003e\u003cp\u003e创建中间件的结构体 \u003ccode\u003ejwt.GinJWTMiddleware\u003c/code\u003e\n\u003ccode\u003ego\nginJWTMiddleware := \u0026amp;jwt.GinJWTMiddleware{\n Realm: \u0026quot;test zone\u0026quot;,\n Key: []byte(\u0026quot;secret key\u0026quot;),\n Timeout: time.Hour,\n MaxRefresh: time.Hour,\n}\n\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\n\n\u003cli\u003e\u003cp\u003e定义验证失败返回的结构 (可选)\u003c/p\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003cp\u003e在中间件中添加 \u003ccode\u003eUnauthorized\u003c/code\u003e 字段\n\u003ccode\u003ego\nginJWTMiddleware := \u0026amp;jwt.GinJWTMiddleware{\n ...,\n Unauthorized: func(c *gin.Context, code int, message string) {\n c.JSON(200, gin.H{\n \u0026quot;code\u0026quot;: code,\n \u0026quot;message\u0026quot;: message,\n })\n },\n }\n\u003c/code\u003e\u003c/p\u003e\n\n\u003cul\u003e\n\u003cli\u003e\u003cp\u003e定义 User 结构体\n\u003ccode\u003ego\ntype User struct {\nUsername string `json:\u0026quot;username\u0026quot; binding:\u0026quot;required\u0026quot;`\nPassword string `json:\u0026quot;password\u0026quot; binding:\u0026quot;required\u0026quot;`\n}\n\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\n\n\u003cli\u003e\u003cp\u003e定义登录成功后用户名储存以及传递用户名到 \u003ccode\u003eAuthorizator\u003c/code\u003e\n\u003ccode\u003ego\nginJWTMiddleware := \u0026amp;jwt.GinJWTMiddleware{\n ...,\n IdentityHandler: func(c *gin.Context) interface{} {\n claims := jwt.ExtractClaims(c)\n return claims[\u0026quot;username\u0026quot;]\n },\n PayloadFunc: func(data interface{}) jwt.MapClaims {\n if user, ok := data.(User); ok {\n return jwt.MapClaims{\u0026quot;username\u0026quot;: user.Username}\n }\n return jwt.MapClaims{}\n },\n}\n\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\n\n\u003cli\u003e\u003cp\u003e定义登录验证函数并添加到 \u003ccode\u003eginJWTMiddleware\u003c/code\u003e 中的 \u003ccode\u003eAuthenticator\u003c/code\u003e 字段\n```go\nfunc authenticator(c *gin.Context) (interface{}, error) {\nuser := User{}\nif err := c.ShouldBind(\u0026amp;user); err != nil {\n return \u0026quot;\u0026quot;, jwt.ErrMissingLoginValues\n}\u003c/p\u003e\n\n\u003cp\u003eif user.Username == \u0026quot;admin\u0026quot; \u0026amp;\u0026amp; user.Password == \u0026quot;admin\u0026quot; {\n return user, nil\n}\u003c/p\u003e\n\n\u003cp\u003ereturn nil, jwt.ErrFailedAuthentication\n}\n```\u003c/p\u003e\u003c/li\u003e\n\n\u003cli\u003e\u003cp\u003e定义登录后权限验证函数并添加到 \u003ccode\u003eginJWTMiddleware\u003c/code\u003e 中的 \u003ccode\u003eAuthorizator\u003c/code\u003e 字段\n\u003ccode\u003ego\nfunc authorizator(data interface{}, ctx *gin.Context) bool {\nreturn strings.Contains(data.(string), \u0026quot;admin\u0026quot;)\n}\n\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\n\n\u003cli\u003e\u003cp\u003e最后你的结构体应该就会长成这样\n\u003ccode\u003ego\nginJWTMiddleware := \u0026amp;jwt.GinJWTMiddleware{\n Realm: \u0026quot;test zone\u0026quot;,\n Key: []byte(\u0026quot;secret key\u0026quot;),\n Timeout: time.Hour,\n MaxRefresh: time.Hour,\n Authenticator: authenticator,\n Authorizator: authorizator,\n Unauthorized: func(c *gin.Context, code int, message string) {\n c.JSON(200, gin.H{\n \u0026quot;code\u0026quot;: code,\n \u0026quot;message\u0026quot;: message,\n })\n },\n IdentityHandler: func(c *gin.Context) interface{} {\n claims := jwt.ExtractClaims(c)\n return claims[\u0026quot;username\u0026quot;]\n },\n PayloadFunc: func(data interface{}) jwt.MapClaims {\n if user, ok := data.(userCenter.User); ok {\n return jwt.MapClaims{\u0026quot;username\u0026quot;: user.Username}\n }\n return jwt.MapClaims{}\n },\n}\n\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\n\n\u003cli\u003e\u003cp\u003e然后创建 jwt 中间件\n\u003ccode\u003ego\njwtMiddleware, _ = jwt.New(ginJWTMiddleware)\n\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\n\n\u003cli\u003e\u003cp\u003e最后\n```go\nfunc main() {\n...\u003c/p\u003e\n\n\u003cp\u003erouter := gin.Default()\napiRouter := router.Group(\u0026quot;/api\u0026quot;)\u003c/p\u003e\n\n\u003cp\u003e// 登录 api ,直接用 jwtMiddleware 中的 \u003ccode\u003eLoginHandler\u003c/code\u003e 既可\napiRouter.POST(\u0026quot;/login\u0026quot;, jwtMiddleware.LoginHandler)\u003c/p\u003e\n\n\u003cp\u003e// 刷新 token api\napiRouter.GET(\u0026quot;/refresh_token\u0026quot;, jwtMiddleware.RefreshHandler)\u003c/p\u003e\n\n\u003cp\u003eapiRouter.GET(\u0026quot;/hello\u0026quot;, func (ctx *gin.Context) {\n c.STRING(200, \u0026quot;hello\u0026quot;)\n})\u003c/p\u003e\n\n\u003cp\u003e// 当 api 需要验证的时候只需要使用 jwtMiddleware.MiddlewareFunc() 中间件既可\napiRouter.GET(\u0026quot;/hello2\u0026quot;, jwtMiddleware.MiddlewareFunc(), func (ctx *gin.Context) {\n c.STRING(200, \u0026quot;hello2\u0026quot;)\n})\u003c/p\u003e\n\n\u003cp\u003erouter.Run()\n}\n``\u003ccode\u003e\n\u0026gt; 其中此处的\u003c/code\u003e...` 代表前面的代码\u003c/p\u003e\u003c/li\u003e\n\u003c/ul\u003e\n", "date_published": "2019-10-20T15:57:56Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/17", "url": "https://blog.firerain.me/article/17", "title": "服务器基本防护", "content_html": "\u003ch2\u003eSSH\u003c/h2\u003e\n\n\u003ch3\u003e限制 \u003ccode\u003eroot\u003c/code\u003e 登录( 都9102了还有人建议用 \u003ccode\u003eroot\u003c/code\u003e 登录? )\u003c/h3\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003earchlinux 已默认禁止,无需修改,\u003ca href=\"https://github.com/drizzt/vps2arch\"\u003evps2arch\u003c/a\u003e 装的除外\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003e编辑 \u003ccode\u003e/etc/ssh/sshd_config\u003c/code\u003e\n\u003ccode\u003e\nPermitRootLogin no\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch3\u003e强制密钥登录\u003c/h3\u003e\n\n\u003cp\u003e编辑 \u003ccode\u003e/etc/ssh/sshd_config\u003c/code\u003e\n\u003ccode\u003e\nPasswordAuthentication no\n\u003c/code\u003e\u003c/p\u003e\n\n\u003cp\u003e然后将公钥添加到服务器 (\u003ca href=\"https://wiki.archlinux.org/index.php/SSH_keys#Copying_the_public_key_to_the_remote_server\"\u003e详细教程\u003c/a\u003e)\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003eGNU/Linux\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003e本机 \u003ccode\u003essh\u003c/code\u003e 公钥路径 (如未生成使用 \u003ccode\u003essh-keygen\u003c/code\u003e 生成)\n\u003ccode\u003e~/.ssh/id_rsa.pub\u003c/code\u003e\u003c/p\u003e\n\n\u003cp\u003e然后将其内容写入到要登录的用户的主目录下的 \u003ccode\u003e.ssh/authorized_keys\u003c/code\u003e\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e最后别忘了重启 \u003ccode\u003esshd\u003c/code\u003e 服务\n\u003ccode\u003esudo systemctl restart sshd\u003c/code\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003e最后你还可以使用 \u003ccode\u003efail2ban\u003c/code\u003e 或 \u003ccode\u003esshguard\u003c/code\u003e 自动阻止多次验证失败的IP地址。\u003c/p\u003e\n\n\u003ch2\u003e防火墙\u003c/h2\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e假设服务器\u003ccode\u003eiptables\u003c/code\u003e 全部放行的情况下\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003ch3\u003e1. 将 \u003ccode\u003eFORWARD\u003c/code\u003e 链的策略设置为DROP\u003c/h3\u003e\n\n\u003cp\u003e\u003ccode\u003e\nsudo iptables -P FORWARD DROP\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch3\u003e2. 创建 \u003ccode\u003eTCP\u003c/code\u003e 和 \u003ccode\u003eUDP\u003c/code\u003e 链\u003c/h3\u003e\n\n\u003cp\u003e\u003ccode\u003e\nsudo iptables -N TCP\nsudo iptables -N UDP\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch3\u003e3. 放行 22,80,443 端口 (\u003ccode\u003etcp\u003c/code\u003e)\u003c/h3\u003e\n\n\u003cp\u003e\u003ccode\u003e\nsudo iptables -A TCP -p tcp --dport 22 -j ACCEPT\nsudo iptables -A TCP -p tcp --dport 80 -j ACCEPT\nsudo iptables -A TCP -p tcp --dport 443 -j ACCEPT\n\u003c/code\u003e\n\u0026gt; 放行其他 \u003ccode\u003etcp\u003c/code\u003e 端口命令参考\n\u0026gt; \u003ccode\u003esudo iptables -A TCP -p tcp --dport {端口} -j ACCEPT\u003c/code\u003e\n\u0026gt; 放行其他 \u003ccode\u003eudp\u003c/code\u003e 端口命令参考\n\u0026gt; \u003ccode\u003esudo iptables -A UDP -p udp --dport {端口} -j ACCEPT\u003c/code\u003e\u003c/p\u003e\n\n\u003ch3\u003e4. 将 \u003ccode\u003eINPUT\u003c/code\u003e 链的策略设置为DROP\u003c/h3\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e禁止未放行的端口的流量入站\n\u003ccode\u003e\nsudo iptables -P INPUT DROP\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch3\u003e5. 设定其他规则\u003c/h3\u003e\n\n\u003cp\u003e\u003ccode\u003e\nsudo iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT\nsudo iptables -A INPUT -i lo -j ACCEPT\nsudo iptables -A INPUT -m conntrack --ctstate INVALID -j DROP\nsudo iptables -A INPUT -p icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT\nsudo iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable\nsudo iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset\nsudo iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable\n\u003c/code\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003ch3\u003e6. 放行 53 端口\u003c/h3\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e不放行 \u003ccode\u003edns\u003c/code\u003e 无法解析域名\n\u003ccode\u003e\nsudo iptables -A INPUT -p tcp --dport 53 -j ACCEPT\nsudo iptables -A INPUT -p udp --dport 53 -j ACCEPT\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch3\u003e7. 保存 \u003ccode\u003eiptables\u003c/code\u003e 规则\u003c/h3\u003e\n\n\u003cp\u003e\u003ccode\u003e\nsudo iptables-save -f /etc/iptables/iptables.rules\n\u003c/code\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003ch2\u003e禁止 \u003ccode\u003eping\u003c/code\u003e (可选)\u003c/h2\u003e\n\n\u003cp\u003e编辑 \u003ccode\u003e/etc/sysctl.d/90-firewall.conf\u003c/code\u003e 加入以下一行\n\u003ccode\u003e\nnet.ipv4.icmp_echo_ignore_all = 1\n\u003c/code\u003e\n应用修改\n\u003ccode\u003e\nsudo sysctl -p /etc/sysctl.d/90-firewall.conf\n\u003c/code\u003e\u003c/p\u003e\n", "date_published": "2019-10-13T16:15:58Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/16", "url": "https://blog.firerain.me/article/16", "title": "打造一个可以装逼的个人域名邮箱", "content_html": "\u003ch1\u003e本方案采用 Gmail + mailgun 方案\u003c/h1\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003eMailgun 每个月可以免费发送10000封邮件,不过个人来讲通常都用不完吧,其次现在需要添加付款信息(信用卡(银联既可)),否则无法添加自定义域名\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003ch2\u003e1. 首先前提当然要有个域名,域名这个没有的就先去注册个再来\u003c/h2\u003e\n\n\u003ch2\u003e2. 注册 \u003ca href=\"https://mailgun.com\"\u003emailgun.com\u003c/a\u003e\u003c/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003e1. 注册后激活帐号(随便找个手机号验证)\n2. 因为 Mailgun 不添加付款信息(信用卡) 无法添加自己的域名,所以如果注册的时候没填,进面板后在 Settings - Details 下 填写\n\u003c/code\u003e\u003c/pre\u003e\n\n\u003ch2\u003e3. 然后添加域名\u003c/h2\u003e\n\n\u003cp\u003e\u003cimg src=\"/api/assets/08be4c1b-9f8a-4bef-a247-14267005afe3\" alt=\"alt text\" /\u003e\n\u003cimg src=\"/api/assets/3f348dbe-436c-48f5-9d6d-df6db0d9e4f4\" alt=\"alt text\" /\u003e\n\u0026gt; 填入你自己的域名\n\u0026gt; 注:此处完全可以输入 \u003ccode\u003efirerain.me\u003c/code\u003e , 然后他就会提示 \u003ccode\u003eWe highly recommend using a subdomain. For more information, check out our FAQ.\u003c/code\u003e ,不用管\u003c/p\u003e\n\n\u003cp\u003e\u003cimg src=\"/api/assets/6fee4127-1ea7-4ae6-b729-547a513399bc\" alt=\"alt text\" /\u003e\n\u0026gt; 然后根据提示在你的DNS服务商处添加,以 \u003ccode\u003ecloudflare\u003c/code\u003e 为例\n\u0026gt; \u003cimg src=\"/api/assets/cce31637-9e92-44ee-87af-331e2c88bcd2\" alt=\"alt text\" /\u003e\n最后点最下面的按钮验证\u003c/p\u003e\n\n\u003ch2\u003e4. 创建 Router\u003c/h2\u003e\n\n\u003cp\u003e\u003cimg src=\"/api/assets/0c66c90a-69d7-4893-b4d5-a51447808821\" alt=\"alt text\" /\u003e\n\u003cimg src=\"/api/assets/1fc8203e-5011-4023-88ea-7729b28b1059\" alt=\"alt text\" /\u003e\n\u0026gt; Forward 下的邮箱填写你自己的 Gmail 邮箱\u003c/p\u003e\n\n\u003ch2\u003e5. 创建 SMTP User\u003c/h2\u003e\n\n\u003cp\u003e\u003cimg src=\"/api/assets/027f30bf-9e35-49ab-b918-2569d0bfd318\" alt=\"alt text\" /\u003e\n\u0026gt; 然后输入你要的用户名,创建成功后右上角会提示一个密码,这个很重要(用于下一步验证),复制\u003c/p\u003e\n\n\u003ch2\u003e6. 添加 Gmail 别名邮箱\u003c/h2\u003e\n\n\u003cp\u003e进入 \u003ca href=\"https://mail.google.com/mail/u/0/#settings/accounts\"\u003eGmail设置\u003c/a\u003e 账号设置页面,点击添加其他电子邮件地址\n\u003cimg src=\"/api/assets/339581d2-1b90-491a-8752-e02afc60ffcf\" alt=\"alt text\" /\u003e\n\u003cimg src=\"/api/assets/34c5ae25-0379-4e39-ae7e-9965cc03f7b6\" alt=\"alt text\" /\u003e\n\u0026gt; 名称填你想要的,然后电子邮件就是刚创建的 \u003ccode\u003eSMTP User\u003c/code\u003e @你的域名\n\u003cimg src=\"/api/assets/7c4e3aef-192d-44f1-bb00-5d14450bd250\" alt=\"alt text\" /\u003e\n\u0026gt; SMTP 服务器填 \u003ccode\u003esmtp.mailgun.org\u003c/code\u003e ,用户名为 \u003ccode\u003eSMTP User\u003c/code\u003e @你的域名,密码就是上一步复制的密码,然后点添加帐号\u003c/p\u003e\n\n\u003ch2\u003e7. 验证添加的邮箱\u003c/h2\u003e\n\n\u003cp\u003e\u003cimg src=\"/api/assets/c3f27279-e083-4919-99e3-e9d5e4d90c23\" alt=\"alt text\" /\u003e\n\u0026gt; 如一切顺利的话,Gmail 发送的邮件会发送到 你的 Gmail 里,然后点开验证完事\u003c/p\u003e\n", "date_published": "2019-10-07T18:58:23Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/15", "url": "https://blog.firerain.me/article/15", "title": "Arch Linux老黄新版驱动新prime卸载玩法", "content_html": "\u003ch2\u003e前提条件\u003c/h2\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e注:以下内容编写于2019.09.03,如未及时更新在未来可能不适用\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cul\u003e\n\u003cli\u003eNVIDIA驱动版本 435.17(Beta)以上\n\u0026gt; 正式版435.21\u003c/li\u003e\n\u003cli\u003exorg版本 打了老黄补丁的版本或者git版\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003ch2\u003e配置\u003c/h2\u003e\n\n\u003ch3\u003e1. 添加X配置\u003c/h3\u003e\n\n\u003cp\u003e```\u003c/p\u003e\n\n\u003ch1\u003evim /etc/X11/xorg.conf.d/nvidia.conf\u003c/h1\u003e\n\n\u003cp\u003e\u003ccode\u003e\n\u003c/code\u003e\nSection \u0026quot;ServerLayout\u0026quot;\n Identifier \u0026quot;layout\u0026quot;\n Screen 0 \u0026quot;iGPU\u0026quot;\n Option \u0026quot;AllowNVIDIAGPUScreens\u0026quot;\nEndSection\u003c/p\u003e\n\n\u003cp\u003eSection \u0026quot;Device\u0026quot;\n Identifier \u0026quot;iGPU\u0026quot;\n Driver \u0026quot;modesetting\u0026quot;\n BusID \u0026quot;PCI:0:2:0\u0026quot;\nEndSection\u003c/p\u003e\n\n\u003cp\u003eSection \u0026quot;Screen\u0026quot;\n Identifier \u0026quot;iGPU\u0026quot;\n Device \u0026quot;iGPU\u0026quot;\nEndSection\u003c/p\u003e\n\n\u003cp\u003eSection \u0026quot;Device\u0026quot;\n Identifier \u0026quot;dGPU\u0026quot;\n Driver \u0026quot;nvidia\u0026quot;\nEndSection\n``\u003ccode\u003e\n\u0026gt; 其中上面的\u003c/code\u003eiGPU\u003ccode\u003e的\u003c/code\u003eBusID\u003ccode\u003e可通过\u003c/code\u003elspci | grep VGA` 获取\u003c/p\u003e\n\n\u003ch3\u003e2. 重启X\u003c/h3\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e重启 X 后 \u003ccode\u003exrandr --listproviders\u003c/code\u003e 结果类似如下\n\u003ccode\u003e\nProviders: number : 2\nProvider 0: id: 0x1e0 cap: 0xf, Source Output, Sink Output, Source Offload, Sink Offload crtcs: 3 outputs: 5 associated providers: 0 name:modesetting\nProvider 1: id: 0x1b8 cap: 0x0 crtcs: 0 outputs: 0 associated providers: 0 name:NVIDIA-G0\n\u003c/code\u003e\n并且 \u003ccode\u003envidia-smi\u003c/code\u003e 中应该存在 \u003ccode\u003eXorg\u003c/code\u003e 进程\n```\n+-----------------------------------------------------------------------------+\n| NVIDIA-SMI 435.21 Driver Version: 435.21 CUDA Version: 10.1 |\n|-------------------------------+----------------------+----------------------+\n| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |\n| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |\n|===============================+======================+======================|\n| 0 GeForce GTX 960M Off | 00000000:01:00.0 Off | N/A |\n| N/A 42C P8 N/A / N/A | 30MiB / 2004MiB | 0% Default |\n+-------------------------------+----------------------+----------------------+\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003e+-----------------------------------------------------------------------------+\n| Processes: GPU Memory |\n| GPU PID Type Process name Usage |\n|=============================================================================|\n| 0 975 G /usr/lib/Xorg 29MiB |\n+-----------------------------------------------------------------------------+\n```\u003c/p\u003e\n\n\u003ch3\u003e3. 使用n卡启动\u003c/h3\u003e\n\n\u003ch4\u003e例子\u003c/h4\u003e\n\n\u003cp\u003e\u003ccode\u003eenv __NV_PRIME_RENDER_OFFLOAD=1 __VK_LAYER_NV_optimus=NVIDIA_only __GLX_VENDOR_LIBRARY_NAME=nvidia glxinfo | grep vendor\u003c/code\u003e\u003c/p\u003e\n\n\u003ch4\u003eSteam\u003c/h4\u003e\n\n\u003cp\u003e打开相应游戏的属性然后设置启动选项,最后填入 \u003ccode\u003eenv __NV_PRIME_RENDER_OFFLOAD=1 __VK_LAYER_NV_optimus=NVIDIA_only __GLX_VENDOR_LIBRARY_NAME=nvidia %command%\u003c/code\u003e 保存关闭既可\u003c/p\u003e\n", "date_published": "2019-09-03T13:39:22Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/14", "url": "https://blog.firerain.me/article/14", "title": "Arch Linux字体渲染(fontconfig)-fonts.conf参考", "content_html": "\u003cp\u003e\u003ca href=\"https://wiki.archlinux.org/index.php/Font_configuration#Fontconfig_configuration\"\u003earch wiki参考:Font_configuration\u003c/a\u003e\u003c/p\u003e\n\n\u003ch2\u003efonts.conf 参考\u003c/h2\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e注: 此 \u003ccode\u003efonts.conf\u003c/code\u003e 参考别处修改而成\n字体: noto fonts cjk, 等宽字体: Fira Code\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003e\u003ccode\u003e.config/fontconfig/fonts.conf\u003c/code\u003e\n\u003ccode\u003exml\n\u0026lt;?xml version='1.0'?\u0026gt;\n\u0026lt;!DOCTYPE fontconfig SYSTEM 'fonts.dtd'\u0026gt;\n\u0026lt;fontconfig\u0026gt;\n \u0026lt;alias\u0026gt;\n \u0026lt;family\u0026gt;serif\u0026lt;/family\u0026gt;\n \u0026lt;prefer\u0026gt;\n \u0026lt;family\u0026gt;Noto Serif\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;Noto Serif CJK SC\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;Noto Serif CJK TC\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;Noto Serif CJK JP\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;Noto Serif CJK KR\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;Noto Color Emoji\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;Noto Emoji\u0026lt;/family\u0026gt;\n \u0026lt;/prefer\u0026gt;\n \u0026lt;/alias\u0026gt;\n \u0026lt;alias\u0026gt;\n \u0026lt;family\u0026gt;sans-serif\u0026lt;/family\u0026gt;\n \u0026lt;prefer\u0026gt;\n \u0026lt;family\u0026gt;Noto Sans\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;Noto Sans CJK SC\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;Noto Sans CJK TC\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;Noto Sans CJK JP\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;Noto Sans CJK KR\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;Noto Color Emoji\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;Noto Emoji\u0026lt;/family\u0026gt;\n \u0026lt;/prefer\u0026gt;\n \u0026lt;/alias\u0026gt;\n \u0026lt;alias\u0026gt;\n \u0026lt;family\u0026gt;sans-sans\u0026lt;/family\u0026gt;\n \u0026lt;prefer\u0026gt;\n \u0026lt;family\u0026gt;Noto Sans CJK SC\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;Noto Sans CJK TC\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;Noto Sans CJK JP\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;Noto Sans CJK KR\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;Noto Color Emoji\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;Noto Emoji\u0026lt;/family\u0026gt;\n \u0026lt;/prefer\u0026gt;\n \u0026lt;/alias\u0026gt;\n \u0026lt;alias\u0026gt;\n \u0026lt;family\u0026gt;tahoma\u0026lt;/family\u0026gt;\n \u0026lt;prefer\u0026gt;\n \u0026lt;family\u0026gt;Noto Sans CJK SC\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;Noto Color Emoji\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;Noto Emoji\u0026lt;/family\u0026gt;\n \u0026lt;/prefer\u0026gt;\n \u0026lt;/alias\u0026gt;\n \u0026lt;alias\u0026gt;\n \u0026lt;family\u0026gt;monospace\u0026lt;/family\u0026gt;\n \u0026lt;prefer\u0026gt;\n \u0026lt;family\u0026gt;Fira Code\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;Noto Sans CJK SC\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;Noto Color Emoji\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;Noto Emoji\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;Noto Sans Mono\u0026lt;/family\u0026gt;\n \u0026lt;family\u0026gt;DejaVu Sans Mono\u0026lt;/family\u0026gt;\n \u0026lt;/prefer\u0026gt;\n \u0026lt;/alias\u0026gt;\n \u0026lt;alias\u0026gt;\n \u0026lt;family\u0026gt;emoji\u0026lt;/family\u0026gt;\n \u0026lt;default\u0026gt;\n \u0026lt;family\u0026gt;Noto Color Emoji\u0026lt;/family\u0026gt;\n \u0026lt;/default\u0026gt;\n \u0026lt;/alias\u0026gt;\n \u0026lt;alias\u0026gt;\n \u0026lt;family\u0026gt;Apple Color Emoji\u0026lt;/family\u0026gt;\n \u0026lt;prefer\u0026gt;\n \u0026lt;family\u0026gt;Noto Color Emoji\u0026lt;/family\u0026gt;\n \u0026lt;/prefer\u0026gt;\n \u0026lt;default\u0026gt;\n \u0026lt;family\u0026gt;sans-serif\u0026lt;/family\u0026gt;\n \u0026lt;/default\u0026gt;\n \u0026lt;/alias\u0026gt;\n \u0026lt;alias\u0026gt;\n \u0026lt;family\u0026gt;Segoe UI Emoji\u0026lt;/family\u0026gt;\n \u0026lt;prefer\u0026gt;\n \u0026lt;family\u0026gt;Noto Color Emoji\u0026lt;/family\u0026gt;\n \u0026lt;/prefer\u0026gt;\n \u0026lt;default\u0026gt;\n \u0026lt;family\u0026gt;sans-serif\u0026lt;/family\u0026gt;\n \u0026lt;/default\u0026gt;\n \u0026lt;/alias\u0026gt;\n \u0026lt;match target=\u0026quot;font\u0026quot;\u0026gt;\n \u0026lt;edit mode=\u0026quot;assign\u0026quot; name=\u0026quot;antialias\u0026quot;\u0026gt;\n \u0026lt;bool\u0026gt;true\u0026lt;/bool\u0026gt;\n \u0026lt;/edit\u0026gt;\n \u0026lt;edit mode=\u0026quot;assign\u0026quot; name=\u0026quot;rgba\u0026quot;\u0026gt;\n \u0026lt;const\u0026gt;rgb\u0026lt;/const\u0026gt;\n \u0026lt;/edit\u0026gt;\n \u0026lt;edit mode=\u0026quot;assign\u0026quot; name=\u0026quot;hinting\u0026quot;\u0026gt;\n \u0026lt;bool\u0026gt;false\u0026lt;/bool\u0026gt;\n \u0026lt;/edit\u0026gt;\n \u0026lt;edit mode=\u0026quot;assign\u0026quot; name=\u0026quot;hintstyle\u0026quot;\u0026gt;\n \u0026lt;const\u0026gt;hintnone\u0026lt;/const\u0026gt;\n \u0026lt;/edit\u0026gt;\n \u0026lt;/match\u0026gt;\n \u0026lt;dir\u0026gt;~/.fonts\u0026lt;/dir\u0026gt;\n \u0026lt;match target=\u0026quot;font\u0026quot;\u0026gt;\n \u0026lt;edit mode=\u0026quot;assign\u0026quot; name=\u0026quot;hinting\u0026quot;\u0026gt;\n \u0026lt;bool\u0026gt;false\u0026lt;/bool\u0026gt;\n \u0026lt;/edit\u0026gt;\n \u0026lt;/match\u0026gt;\n \u0026lt;match target=\u0026quot;font\u0026quot;\u0026gt;\n \u0026lt;edit mode=\u0026quot;assign\u0026quot; name=\u0026quot;hintstyle\u0026quot;\u0026gt;\n \u0026lt;const\u0026gt;hintnone\u0026lt;/const\u0026gt;\n \u0026lt;/edit\u0026gt;\n \u0026lt;/match\u0026gt;\n\u0026lt;/fontconfig\u0026gt;\n\u003c/code\u003e\u003c/p\u003e\n", "date_published": "2019-07-15T16:36:21Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/13", "url": "https://blog.firerain.me/article/13", "title": "安卓环境搭建与编译 for Arch Linux", "content_html": "\u003ch2\u003e环境搭建\u003c/h2\u003e\n\n\u003ch3\u003e1. 编译环境(已有跳过)\u003c/h3\u003e\n\n\u003cp\u003e\u003ccode\u003ebash\npacman -S base-devel\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch3\u003e2. 安卓编译环境\u003c/h3\u003e\n\n\u003cp\u003e要构建任何版本的Android,您需要安装这些软件包:\n\u003ccode\u003elib32-gcc-libs git gnupg flex bison gperf sdl wxgtk2 squashfs-tools curl ncurses zlib schedtool perl-switch zip unzip libxslt python2-virtualenv bc rsync ncurses5-compat-libs AUR lib32-zlib lib32-ncurses lib32-readline lib32-ncurses5-compat -libs\u003c/code\u003e\n\u0026gt; 但是AUR提供了 \u003ccode\u003eaosp-devel\u003c/code\u003e 包含了以上的包\u003c/p\u003e\n\n\u003cp\u003e使用AUR Helper安装(如yay)\n\u003ccode\u003ebash\nyay -S aosp-devel\n\u003c/code\u003e\u003c/p\u003e\n\n\u003cp\u003e对于lineageos来说,需要更多的依赖: \u003ccode\u003exml2\u003c/code\u003e, \u003ccode\u003elzop\u003c/code\u003e, \u003ccode\u003epngcrush\u003c/code\u003e, \u003ccode\u003eimagemagick\u003c/code\u003e\n\u0026gt; AUR提供了 \u003ccode\u003elineageos-devel\u003c/code\u003e 包含了以上的包\u003c/p\u003e\n\n\u003cp\u003e使用AUR Helper安装(如yay)\n\u003ccode\u003ebash\nyay -S lineageos-devel\n\u003c/code\u003e\n\u0026gt; 注:以上两个devel包只需要其一, \u003ccode\u003elineageos-devel\u003c/code\u003e 依赖 \u003ccode\u003eaosp-devel\u003c/code\u003e,建议直接装\u003ccode\u003elineageos-devel\u003c/code\u003e\u003c/p\u003e\n\n\u003ch3\u003e3. Python环境\u003c/h3\u003e\n\n\u003cp\u003e由于aosp的build只支持python2,但是arch默认python3,这里主要有两个方法解决\n1. 使用 find + sed 直接简单粗暴的将所有py脚本的解析器从 python(arch 默认链接到python3) 改为 python2\n2. 安装 \u003ccode\u003epython2-virtualenv\u003c/code\u003e 包,创建一个python2虚拟环境\n\u0026gt; 使用方法:\n\u0026gt; 1. \u003ccode\u003evirtualenv2 --system-site-packages venv\u003c/code\u003e\n\u0026gt; 2. \u003ccode\u003esource venv/bin/activate\u003c/code\u003e\u003c/p\u003e\n\n\u003ch3\u003e4. 同步源码(以下以lineageos 16.0为例)\u003c/h3\u003e\n\n\u003cp\u003e\u003ccode\u003ebash\nmkdir lineageos\ncd lineageos\nrepo init -u git://github.com/LineageOS/android.git -b lineage-16.0 --depth=1\nrepo sync -c -j4 --force-sync --no-clone-bundle --no-tags\n\u003c/code\u003e\n\u0026gt; 注: 以上的 \u003ccode\u003e--depth=1\u003c/code\u003e 参数代表只保留本地仓库中的最后一个commit, 可减少空间占用, 你也可以不加\n\u0026gt; 最后一句的 \u003ccode\u003e-j4\u003c/code\u003e 参数中的4代表4线程, 可自行修改\u003c/p\u003e\n\n\u003ch3\u003e5. 编译 ( 以下操作均在源码下 )\u003c/h3\u003e\n\n\u003cp\u003e在编译之前需要准备三大 Tree (\u003ccode\u003eDevice Tree\u003c/code\u003e , \u003ccode\u003eKernel Tree\u003c/code\u003e , \u003ccode\u003eVendor Tree\u003c/code\u003e)\n\u0026gt; 以 一加5 为例\u003c/p\u003e\n\n\u003ch4\u003eDevice Tree\u003c/h4\u003e\n\n\u003cp\u003e\u003ccode\u003ehttps://github.com/LineageOS/android_device_oneplus_cheeseburger\nhttps://github.com/LineageOS/android_device_oneplus_msm8998-common\u003c/code\u003e\n依赖\n\u003ccode\u003ehttps://github.com/LineageOS/android_packages_resources_devicesettings\nhttps://github.com/LineageOS/android_device_oneplus_common\u003c/code\u003e\n\u0026gt; 项目名以一定的规律命名,第二个单词开始的下划线改成斜杠就是路径,例如 \u003ccode\u003eandroid_device_oneplus_cheeseburger\u003c/code\u003e 的存放路径为 \u003ccode\u003edevice/oneplus/cheeseburger\u003c/code\u003e,以此类推 \u003ccode\u003eandroid_device_oneplus_msm8998-common\u003c/code\u003e 的存放路径为 \u003ccode\u003edevice/oneplus/msm8998-common\u003c/code\u003e\u003c/p\u003e\n\n\u003ch5\u003e拉取 \u003ccode\u003eDevice Tree\u003c/code\u003e\u003c/h5\u003e\n\n\u003cp\u003e\u003ccode\u003ebash\ngit clone https://github.com/LineageOS/android_device_oneplus_cheeseburger device/oneplus/cheeseburger\ngit clone https://github.com/LineageOS/android_device_oneplus_msm8998-common device/oneplus/msm8998-common\ngit clone https://github.com/LineageOS/android_packages_resources_devicesettings packages/resources/devicesettings\ngit clone https://github.com/LineageOS/android_device_oneplus_common device/oneplus/common\n\u003c/code\u003e\n\u0026gt; 同样的,第四步的 \u003ccode\u003e--depth=1\u003c/code\u003e 参数同样适用在以上命令\u003c/p\u003e\n\n\u003ch4\u003eKernel Tree\u003c/h4\u003e\n\n\u003cp\u003e\u003ccode\u003ehttps://github.com/LineageOS/android_kernel_oneplus_msm8998\u003c/code\u003e\u003c/p\u003e\n\n\u003ch5\u003e拉取 \u003ccode\u003eKernel Tree\u003c/code\u003e\u003c/h5\u003e\n\n\u003cp\u003e\u003ccode\u003ebash\ngit clone https://github.com/LineageOS/android_kernel_oneplus_msm8998 kernel/oneplus/msm8998\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch4\u003eVendor Tree\u003c/h4\u003e\n\n\u003cp\u003eVendor Tree 的获取方式主要有两种\n方式一:下载官方上传的仓库\n\u0026gt; lineageos 的 \u003ccode\u003eVendor Tree\u003c/code\u003e 存放在 \u003ca href=\"https://github.com/TheMuppets\"\u003eTheMuppets\u003c/a\u003e 组织\u003c/p\u003e\n\n\u003cp\u003e方式二:通过 \u003ccode\u003eDevice Tree\u003c/code\u003e 中的 \u003ccode\u003eextract-files.sh\u003c/code\u003e 脚本从OTA或者手机拉取 \u003ccode\u003eVendor Tree\u003c/code\u003e\u003c/p\u003e\n\n\u003cp\u003e以下以方式一为例\n一加5的 \u003ccode\u003eVendor Tree\u003c/code\u003e 在 \u003ca href=\"https://github.com/TheMuppets/proprietary_vendor_oneplus\"\u003eproprietary\u003cem\u003evendor\u003c/em\u003eoneplus\u003c/a\u003e 中\n所以直接拉取整个仓库到源码下\n\u003ccode\u003ebash\ngit clone https://github.com/TheMuppets/proprietary_vendor_oneplus vendor/oneplus --depth=1\n\u003c/code\u003e\n\u0026gt; 由于 \u003ccode\u003eproprietary_vendor_oneplus\u003c/code\u003e 体积庞大,故加上 \u003ccode\u003e--depth=1\u003c/code\u003e 参数以减少体积占用\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e注:由于以上仓库都默认了 \u003ccode\u003elineage-16.0\u003c/code\u003e 分支,而我们拉的源码也是 \u003ccode\u003elineage-16.0\u003c/code\u003e 分支,所以省略分支,如果你要拉别的分支,请适用 \u003ccode\u003e-b\u003c/code\u003e 参数,如 \u003ccode\u003e-b lineage-16.0\u003c/code\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003e现在三大 Tree已准备完毕,首先初始化环境\n\u003ccode\u003ebash\n. build/envsetup.sh\n\u003c/code\u003e\n然后加载一加5的配置\n\u003ccode\u003ebash\nlunch lineage_cheeseburger-userdebug\n\u003c/code\u003e\n然后开始编译\n\u003ccode\u003ebash\nmka bacon -j8\n\u003c/code\u003e\n\u0026gt; \u003ccode\u003e-j8\u003c/code\u003e 参数中的 8 代表线程数,请以你 CPU 实际的线程数为准\n然后等待编译完成,编译完成后提示你编译好的包的路径\u003c/p\u003e\n\n\u003cp\u003e注:如果修改了三大Tree或者源码,要重新编译,你可以用以下命令清除部分编译产物而不用重新完整编译\n\u003ccode\u003ebash\nmka installclean\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch3\u003eCcache 编译缓存开启\u003c/h3\u003e\n\n\u003cp\u003e未完待续\u003c/p\u003e\n", "date_published": "2019-06-28T16:14:55Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/12", "url": "https://blog.firerain.me/article/12", "title": "关闭Intel的安全补丁以恢复性能", "content_html": "\u003ch2\u003e问题\u003c/h2\u003e\n\n\u003cp\u003e2010 至 2019 年生产的 Intel CPU 爆出了多个边信道攻击漏洞,比如 Spectre,Meltdown。要修复这些安全问题,内核引进了很多补丁,导致 CPU 性能出现了严重下降。如果您比起安全更关注性能,您可以添加这些内核选项来禁用这些补丁,恢复性能。\u003c/p\u003e\n\n\u003ch2\u003e关闭(禁用)方法\u003c/h2\u003e\n\n\u003cp\u003e加入以下内核参数\n\u003ccode\u003e\nnoibrs noibpb nopti nospectre_v2 nospectre_v1 l1tf=off nospec_store_bypass_disable no_stf_barrier mds=off mitigations=off\n\u003c/code\u003e\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003ebootctl(systemd-boot) 引导\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003e修改配置文件( 如 \u003ccode\u003e/boot/loader/entries/arch.conf\u003c/code\u003e ), 在options最后加入\n\u003ccode\u003e\ntitle Arch Linux\nlinux /vmlinuz-linux-mainline\ninitrd /intel-ucode.img\ninitrd /initramfs-linux-mainline.img\noptions root=PARTUUID=... rw noibrs noibpb nopti nospectre_v2 nospectre_v1 l1tf=off nospec_store_bypass_disable no_stf_barrier mds=off mitigations=off\n\u003c/code\u003e\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003eGrub 引导\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003e修改 \u003ccode\u003e/etc/default/grub\u003c/code\u003e 在 \u003ccode\u003eGRUB_CMDLINE_LINUX_DEFAULT\u003c/code\u003e 加入\n\u003ccode\u003e\nGRUB_CMDLINE_LINUX_DEFAULT=\u0026quot;noibrs noibpb nopti nospectre_v2 nospectre_v1 l1tf=off nospec_store_bypass_disable no_stf_barrier mds=off mitigations=off\u0026quot;\n\u003c/code\u003e\u003c/p\u003e\n\n\u003cp\u003e最后重新生成 \u003ccode\u003egrub.cfg\u003c/code\u003e\n```\u003c/p\u003e\n\n\u003ch1\u003egrub-mkconfig -o /boot/grub/grub.cfg\u003c/h1\u003e\n\n\u003cp\u003e```\u003c/p\u003e\n\n\u003ch2\u003e本篇内容来源: \u003ca href=\"https://zh.opensuse.org/SDM:%E6%81%A2%E5%A4%8DIntel_CPU%E6%80%A7%E8%83%BD%E6%8D%9F%E5%A4%B1\"\u003ehttps://zh.opensuse.org/SDM:恢复Intel_CPU性能损失\u003c/a\u003e\u003c/h2\u003e\n", "date_published": "2019-06-19T07:25:13Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/10", "url": "https://blog.firerain.me/article/10", "title": "kde美化新篇", "content_html": "\u003cp\u003e效果图\n\u003cimg src=\"/api/assets/78d8cbb1-d52c-43ee-aadf-1e8b22729adf\" alt=\"sddm.webp\" /\u003e\n\u003cimg src=\"/api/assets/2828d95c-847b-4dee-b4c6-4094ed74f1e2\" alt=\"welcome.webp\" /\u003e\n\u003cimg src=\"/api/assets/372bd0db-208d-4b0e-a8db-c87378e8dea2\" alt=\"kde.webp\" /\u003e\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e壁纸\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003e\u003ca href=\"https://www.deviantart.com/aaronolive/art/Rolling-Waves-Mod-398325288\"\u003eRolling Waves Mod\u003c/a\u003e\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e主题 (Sweet KDE)\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003e\u003ca href=\"https://store.kde.org/p/1294013/\"\u003eKvantum\u003c/a\u003e\n\u003ca href=\"https://store.kde.org/p/1294011\"\u003eColor scheme\u003c/a\u003e\n\u003ca href=\"https://store.kde.org/p/1294174/\"\u003ePlasma Themes\u003c/a\u003e\n\u003ca href=\"https://store.kde.org/p/1297008/\"\u003eKonsole Color Schemes\u003c/a\u003e\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e欢迎屏幕\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003e\u003ca href=\"https://store.kde.org/p/1289364\"\u003eBreeze Blur Blue V.2\u003c/a\u003e\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003eSDDM主题\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003e\u003ca href=\"https://store.kde.org/p/1272122/\"\u003eSugar Dark for SDDM\u003c/a\u003e\n\u003ca href=\"https://store.kde.org/p/1272119/\"\u003eSugar Light for SDDM\u003c/a\u003e\u003c/p\u003e\n", "date_published": "2019-04-25T12:11:09Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/9", "url": "https://blog.firerain.me/article/9", "title": "openwrt编译--koolproxy篇", "content_html": "\u003col\u003e\n\u003cli\u003e下载 \u003ccode\u003eluci-app-koolproxy\u003c/code\u003e\n\u003ccode\u003ebash\ngit clone https://github.com/openwrt-develop/luci-app-koolproxy package/luci-app-koolproxy\n\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e更新 \u003ccode\u003ekoolproxy\u003c/code\u003e 主程序\n\u003ccode\u003ebash\ncd package/luci-app-koolproxy\nbash koolproxyupdate.sh\ncd ../..\n\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e进入配置菜单\n\u003ccode\u003ebase\nmake menuconfig\n\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e勾选 \u003ccode\u003eluci-app-koolproxy\u003c/code\u003e\n\u003ccode\u003e\nLuCI ---\u0026gt;\n Applications ---\u0026gt;\n luci-app-koolproxy\n\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e编译\n\u0026gt; 按自己的核心改对应的线程数\n\u003ccode\u003e\nmake -j8\n\u003c/code\u003e\u003c/li\u003e\n\u003c/ol\u003e\n", "date_published": "2019-01-03T05:29:02Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/8", "url": "https://blog.firerain.me/article/8", "title": "openwrt编译--配置篇", "content_html": "\u003ch2\u003eweb界面(luci)\u003c/h2\u003e\n\n\u003cp\u003e\u003cstrong\u003eopenwrt默认并没有编译luci,所以默认编译出来的固件是不带luci的\u003c/strong\u003e\u003c/p\u003e\n\n\u003col\u003e\n\u003cli\u003e\u003cp\u003e进入配置界面\n\u003ccode\u003e\nmake menuconfig\n\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\n\n\u003cli\u003e\u003cp\u003e选中luci\n\u003ccode\u003e\nLuCI ---\u0026gt;\n Collections ---\u0026gt;\n luci\n\u003c/code\u003e\n\u0026gt; 也可以选择luci-ssl或者luci-ssl-openssl\u003c/p\u003e\u003c/li\u003e\n\n\u003cli\u003e\u003cp\u003e主题(可选)\n\u003ccode\u003e\nLuCI ---\u0026gt;\n Themes ---\u0026gt;\n luci-theme-material\n\u003c/code\u003e\n\u0026gt; 可按照自己喜好选别的或者都选\u003c/p\u003e\u003c/li\u003e\n\n\u003cli\u003e\u003cp\u003e中文\n\u003ccode\u003e\nLuCI ---\u0026gt;\n Modules ---\u0026gt;\n Translations ---\u0026gt;\n Chinese (zh-cn)\n\u003c/code\u003e\n\u0026gt; 如果你要繁体中文选\u003ccode\u003eTaiwanese (zh-tw)\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\n\u003ch2\u003e编译\u003c/h2\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e按自己的核心改对应的线程数\n\u003ccode\u003e\nmake -j8\n\u003c/code\u003e\n有些人推荐第一次编译make V=s单线程编译,但是我不推荐,谁告诉你第一次编译百分比报错了,而且又不是所有人单线程性能很牛逼,除非你能忍那单线程编译的速度,否则我的建议都是先正常make -j8编译,如果出错了,在make V=s,说到这不得不说openwrt的构建系统有多恶心,虽然安卓的构建系统也没好到哪里去(吃内存),但是最起码别人用起来最起码舒服的多\u003c/p\u003e\n\u003c/blockquote\u003e\n", "date_published": "2019-01-03T05:28:19Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/7", "url": "https://blog.firerain.me/article/7", "title": "openwrt编译--环境篇", "content_html": "\u003ch2\u003e以下环境为archlinux,路由器为newifi d1为例\u003c/h2\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e开发环境(已有跳过)\n\u003ccode\u003ebash\nsudo pacman -S base-devel\n\u003c/code\u003e\ncmake编译依赖(openwrt会在编译时自己编译cmake而不是用系统的,十分恶心)\n\u003ccode\u003ebash\nsudo pacman -S python-sphinx emacs\n\u003c/code\u003e\n配置openwrt\n\u003ccode\u003ebash\nmake menuconfig\n\u003c/code\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003e以newifi d1为例(如不是改自己的机型)\n\u003ccode\u003e\nTarget System (cpu构架)\n ==\u0026gt; MediaTek Ralink MIPS\nSubtarget (cpu)\n ==\u0026gt; MT7621 based boards\nTarget Profile (型号)\n ==\u0026gt; Newifi D1\n\u003c/code\u003e\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e编译(-j8表示8线程编译,自己按照自己的核心数对应改)\n\u003ccode\u003ebash\nmake -j8\n\u003c/code\u003e\n由于openwrt在编译时会一边编译一边下载,如果是国内网络,可能会很慢,所以需要科学上网\n1.使用proxychains,如 proxychains make -j8\n2.设置HTTP\u003cem\u003ePROXY/HTTPS\u003c/em\u003ePROXY变量\n3.使用iptables+透明代理方案\n4.路由器挂梯子方案\u003c/p\u003e\n\u003c/blockquote\u003e\n", "date_published": "2019-01-03T05:26:32Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/6", "url": "https://blog.firerain.me/article/6", "title": "arch下go qt绑定库(therecipe/qt)环境搭建", "content_html": "\u003ch2\u003e安装依赖\u003c/h2\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e编译环境(已有跳过)\n\u003ccode\u003e\nsudo pacman -S base-devel\n\u003c/code\u003e\nqt依赖(已有跳过)\n\u003ccode\u003e\nsudo pacman -S qt5-base qt5-tools qt5-datavis3d qt5-doc qt5-declarative qt5-remoteobjects\n\u003c/code\u003e\n2020.3.2 更新:qt5-remoteobjects 现在是必须的\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003ch2\u003e环境变量\u003c/h2\u003e\n\n\u003cp\u003e建议添加到~/.xprofile\n\u003ccode\u003ebash\nexport QT_PKG_CONFIG=true\n\u003c/code\u003e\u003c/p\u003e\n\n\u003cp\u003e如果你在使用 Go 1.10.x 还需要以下变量\n\u003ccode\u003ebash\nexport CGO_CXXFLAGS_ALLOW=\u0026quot;.*\u0026quot;\nexport CGO_LDFLAGS_ALLOW=\u0026quot;.*\u0026quot;\nexport CGO_CFLAGS_ALLOW=\u0026quot;.*\u0026quot;\n\u003c/code\u003e\n\u0026gt; 高于 1.10.x 版本如 1.13.1 不再需要\u003c/p\u003e\n\n\u003cp\u003e注销或\n\u003ccode\u003e\nsource ~/.xprofile\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e安装qt绑定库\u003c/h2\u003e\n\n\u003cp\u003e```bash\nexport GO111MODULE=off\ngo get -u -tags=no_env github.com/therecipe/qt/cmd/...\u003c/p\u003e\n\n\u003cp\u003e$(go env GOPATH)/qtsetup generate\n$(go env GOPATH)/qtsetup install\n``\u003ccode\u003e\n\u0026gt; 2021.3.15 更新: \n\u0026gt; 1. go 1.16 开始 go mod默认开了,所以需要先用\u003c/code\u003eGO111MODULE=off\u003ccode\u003e关掉\n\u0026gt; 2. ArchLinux 的 qt5 版本已到 5.15,但是\u003c/code\u003etherecipe/qt\u003ccode\u003e的 env 用的还是 5.13 的 API,并且已经开了\u003c/code\u003eQT\u003cem\u003ePKG\u003c/em\u003eCONFIG\u003ccode\u003e所以通过\u003c/code\u003e-tags=no_env` 取消拉取他的 env,用回系统的\u003c/p\u003e\n\n\u003ch2\u003e对于开启 \u003ccode\u003ego mod\u003c/code\u003e 的项目\u003c/h2\u003e\n\n\u003cp\u003e因为作者搞了个实验性的 \u003ccode\u003ecgo-less\u003c/code\u003e 版本,而且默认开启,这东西默认问题很多,特别是当你有写自定义信号槽等,所以需要把它关掉,并且需要用上恶臭的 \u003ccode\u003evendor\u003c/code\u003e\n\u0026gt; 所谓的 \u003ccode\u003ecgo-less\u003c/code\u003e 就是搞了个 \u003ccode\u003eqtbox\u003c/code\u003e 来做桥梁中转从而避免编译大量CPP,这东西在 \u003ccode\u003eArchLinux\u003c/code\u003e 上唯一的意义就是开发的时候编译快,提高开发效率,除此之外没有任何意义,而且他每次启动都会尝试获取并启动 \u003ccode\u003eqtbox\u003c/code\u003e\u003c/p\u003e\n\n\u003cp\u003e在项目下执行 \u003ccode\u003eqtminimal\u003c/code\u003e 生成 \u003ccode\u003evendor\u003c/code\u003e,然后编译的时候加上 \u003ccode\u003e-tags=minimal\u003c/code\u003e 既可,如 \u003ccode\u003ego build -tags=minimal\u003c/code\u003e,可以把 \u003ccode\u003evendor\u003c/code\u003e 加入到 \u003ccode\u003e.gitignore\u003c/code\u003e,这东西没有上传的必要\u003c/p\u003e\n", "date_published": "2018-12-04T08:27:48Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/5", "url": "https://blog.firerain.me/article/5", "title": "Arch安装anbox", "content_html": "\u003ch2\u003e安装linux-headers(如有跳过)\u003c/h2\u003e\n\n\u003cp\u003e\u003ccode\u003e\n$ sudo pacman -S linux-headers\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e安装anbox\u003c/h2\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e有加CN源\n\u003ccode\u003e\n$ sudo pacman -S anbox-git anbox-modules-dkms-git\n\u003c/code\u003e\nAUR(aur helper用yay为例)\n\u003ccode\u003e\n$ yay -S anbox-git anbox-modules-dkms-git\n\u003c/code\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003ch2\u003e加载模块(仅安装完不重启的情况下)\u003c/h2\u003e\n\n\u003cp\u003e\u003ccode\u003e\n$ sudo modprobe -a binder_linux ashmem_linux\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e运行\u003c/h2\u003e\n\n\u003cp\u003e\u003ccode\u003e\n$ sudo systemctl start anbox-container-manager\n 用navite驱动可加 --gles-driver=host参数\n$ anbox session-manager\n\u003c/code\u003e\n或者\n\u003ccode\u003e\n$ sudo systemctl start anbox-container-manager\n$ systemctl --user start anbox-session-manager\n\u003c/code\u003e\n\u0026gt;开机自启\n\u003ccode\u003e\n$ sudo systemctl enable anbox-container-manager\n$ systemctl --user enable anbox-session-manager\n\u003c/code\u003e\n然后点击启动器里的anbox图标启动\u003c/p\u003e\n\n\u003ch2\u003e联网\u003c/h2\u003e\n\n\u003cp\u003e\u003ccode\u003e\nnmcli con add type bridge ifname anbox0 -- connection.id anbox-net ipv4.method shared ipv4.addresses 192.168.250.1/24\n\u003c/code\u003e\u003c/p\u003e\n", "date_published": "2018-11-27T13:43:50Z", "date_modified": "2026-02-06T06:17:30Z" }, { "id": "https://blog.firerain.me/article/4", "url": "https://blog.firerain.me/article/4", "title": "kde美化--kvantum篇", "content_html": "\u003ch2\u003e效果图\u003c/h2\u003e\n\n\u003cp\u003e\u003cimg src=\"/api/assets/e2f32203-f187-41dd-bb13-9e3db4002cd6\" alt=\"alt text\" /\u003e\nPS:以下均在ARCH下操作\u003c/p\u003e\n\n\u003ch2\u003e安装Kvantum\u003c/h2\u003e\n\n\u003cp\u003e\u003ccode\u003e\n$ sudo pacman -S kvantum-qt5\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e安装主题(materia)\u003c/h2\u003e\n\n\u003cp\u003e\u003ccode\u003e\n$ sudo pacman -S kvantum-theme-materia materia-gtk-theme materia-kde\n\u003c/code\u003e\n其他主题\nkvantum-theme-arc\nkvantum-theme-adapta\n以及kvantum自带的主题\u003c/p\u003e\n\n\u003ch2\u003e窗口装饰(AUR)\u003c/h2\u003e\n\n\u003cp\u003e\u003ccode\u003e\n$ yay -S breeze-blurred-git\n\u003c/code\u003e\u003c/p\u003e\n\n\u003ch2\u003e配置\u003c/h2\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e系统设置\n1. 工作空间主题-观感-Materia\n2. 应用程序风格-窗口装饰-breeze-blurred\n3. 应用程序风格-部件风格-部件样式-kvantum\n4. 应用程序风格-GNOME 程序风格(GTK)-GTK主题(gtk2和gtk3)-Materia-dark\u003c/p\u003e\n\n\u003cp\u003eKvantum设置\n1. 选 MateriaBlur (注:只要修改了主题就会有modified)\n\u003cimg src=\"/api/assets/d5aeeed4-c509-4c06-a6f4-f435bb0cc29a\" alt=\"alt text\" /\u003e\n2. 勾选圈住的\n\u003cimg src=\"/api/assets/e35cf3cf-2a44-4f2c-8cd0-f96c550e5e0b\" alt=\"alt text\" /\u003e\n3. 修改圈住的\n\u003cimg src=\"/api/assets/53214cfc-0836-4eec-abd6-2558e87c53ba\" alt=\"alt text\" /\u003e\n4. 点Save保存\n5. 点Quit退出即可\u003c/p\u003e\n\u003c/blockquote\u003e\n", "date_published": "2018-11-25T13:36:35Z", "date_modified": "2026-02-06T06:17:30Z" } ] }