<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>木木的木头</title>
    <description>一只喜欢折腾的小程序猿</description>
    <link>https://www.jinnrry.com/</link>
    <atom:link href="https://www.jinnrry.com/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>Wed, 22 Apr 2026 21:41:13 -0500</pubDate>
    <lastBuildDate>Wed, 22 Apr 2026 21:41:13 -0500</lastBuildDate>
    <generator>Jekyll v4.2.2</generator>
    
      <item>
        <title>使用PVE搭建安卓云手机</title>
        <description>&lt;p&gt;目前能够在x86平台运行的android项目主要有3个
1、Android x86 这个是最原始，最早的版本，但是这个项目已经3年没有更新了，因此后续又出现了多个基于此项目的新项目
2、BlissOS 
3、PrimeOS 官网号称是最稳定的android x86系统，但是我在PVE上面没有运行起来&lt;/p&gt;

&lt;p&gt;以上3个项目是我在网上能找到的主流android x86项目，断断续续花了一周多时间研究，最终只有BlissOS在PVE上面成功运行。&lt;/p&gt;

&lt;p&gt;下面记录一下安装步骤，留给需要的人&lt;/p&gt;

&lt;h2 id=&quot;1下载镜像&quot;&gt;1、下载镜像&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://blissos.org/&quot;&gt;https://blissos.org/&lt;/a&gt; 官网直接下载，没啥好说的&lt;/p&gt;

&lt;h2 id=&quot;2创建虚拟机&quot;&gt;2、创建虚拟机&lt;/h2&gt;

&lt;p&gt;这里是第一个坑，卡了我好几天，&lt;/p&gt;

&lt;h3 id=&quot;bios选择&quot;&gt;BIOS选择&lt;/h3&gt;
&lt;p&gt;blissos镜像似乎不支持uefi启动（始终会报证书错误），因此bios一定要选默认的，别轻信网上其他教材去选UEFI。&lt;/p&gt;

&lt;h3 id=&quot;gpu选择&quot;&gt;GPU选择&lt;/h3&gt;
&lt;p&gt;这简直是天坑，GPU一定要选择&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirGL GPU&lt;/code&gt;其他各种方案都不行，无法启动&lt;/p&gt;

&lt;p&gt;选择&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirGL GPU&lt;/code&gt;又遇到新坑，我主机是英伟达显卡，使用了英伟达vGPU技术。但是！英伟达vGPU驱动是不能使用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirGL GPU&lt;/code&gt;技术的。只能卸载vGPU驱动，换成&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Geforce&lt;/code&gt;驱动才能使用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirGL GPU&lt;/code&gt;技术。&lt;/p&gt;

&lt;p&gt;另外，我也尝试了给虚拟机分配vGPU，然而并不兼容，无法成功安装系统&lt;/p&gt;

&lt;h3 id=&quot;最终虚拟机配置&quot;&gt;最终虚拟机配置&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Jinnrry/Jinnrry.github.io/master/img/articleImg/blissos1.png.png&quot; alt=&quot;blissos1.png&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;3安装系统&quot;&gt;3、安装系统&lt;/h2&gt;

&lt;p&gt;使用ISO镜像引导，进入安装界面，选择&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Installation - Install BlissOS-1x.xx.xx to handdisk&lt;/code&gt;进入安装程序&lt;/p&gt;

&lt;p&gt;如果前面虚拟机配置没问题就会进入安装界面，就像这样
&lt;img src=&quot;https://raw.githubusercontent.com/Jinnrry/Jinnrry.github.io/master/img/articleImg/blissos2.png.png&quot; alt=&quot;blissos2.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;如果你始终进不去这个界面，那说明你硬件不兼容，检查虚拟机配置。&lt;/p&gt;

&lt;p&gt;进来以后，默认情况下磁盘是没有分区的，需要进行分区。选择&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Create/Modify partitions&lt;/code&gt;选项进入分区界面。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Jinnrry/Jinnrry.github.io/master/img/articleImg/blissos3.png.png&quot; alt=&quot;blissos3.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;这里是问你使用什么分区工具，这里千万别选Yes，选Yes会使用cgdisk，这万一只支持GPT模式，然而非UEFI引导根本没法启动。（都是血泪教训啊，天天装系统，惯性的以为这个弹出是警告会提示丢数据，毫不犹豫的点了yes，结果折腾我几天都装不成功，最好仔细一看内容才发现他这里是让选择分区工具。）&lt;/p&gt;

&lt;p&gt;选择&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;No&lt;/code&gt;进入cfdisk工具界面，进来后会让有一个&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Select label type&lt;/code&gt;选择，这里选&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dos&lt;/code&gt;表示使用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MBR&lt;/code&gt;分区表(又是血泪啊，坑我一天时间)&lt;/p&gt;

&lt;p&gt;进入以后可以看到你的空闲空间，选择&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;New&lt;/code&gt;创建分区，没什么特殊需求的话，直接建一个根分区就行。选择New，磁盘大小直接默认(全部空余空间)，然后回车，然后选择&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;primary&lt;/code&gt;（表示主分区，只有主分区可以引导启动）。这时分区就建好了。&lt;/p&gt;

&lt;p&gt;【重要提示！】这玩意特别坑，创建的&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;primary&lt;/code&gt;默认情况是不支持引导的（不说了，太他妈坑了，又浪费我几天时间），一定要在这里选择&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bootable&lt;/code&gt;按钮，给你新建的分区加上&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Boot&lt;/code&gt;功能，不然你的系统装完是没法启动的。最终分区结果&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Jinnrry/Jinnrry.github.io/master/img/articleImg/blissos4.png.png&quot; alt=&quot;blissos4.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;注意&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Boot&lt;/code&gt;这一项，一定要有星号，不然你没法启动&lt;/p&gt;

&lt;p&gt;分区完成后选择&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Write&lt;/code&gt; 保存分区，然后选择&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Quit&lt;/code&gt;退出分区界面。&lt;/p&gt;

&lt;p&gt;退出来后就能在安装界面看到分区了，如图
&lt;img src=&quot;https://raw.githubusercontent.com/Jinnrry/Jinnrry.github.io/master/img/articleImg/blissos5.png.png&quot; alt=&quot;blissos5.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;然后直接选&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OK&lt;/code&gt;，表示安装到这个分区，然后选择&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;extf4&lt;/code&gt;格式进行格式化。后续就是各种确认，全部选&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yes&lt;/code&gt;就安装完了&lt;/p&gt;

&lt;h2 id=&quot;3远程连接&quot;&gt;3、远程连接&lt;/h2&gt;

&lt;p&gt;我这个虚拟机是拿来当云手机，我需要远程通过我的手机连接到这个云手机使用。我尝试了目前能找到的所有远程软件，teamview无法使用，向日葵可以用但必须付费，rustdesk打开黑屏(我在社区提了issues)但似乎没人关注，airdroid无法使用&lt;/p&gt;

&lt;p&gt;最终远程方案，使用PVE的&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SPICE&lt;/code&gt;协议连接。安卓上面我找了很久，最终只有&lt;a href=&quot;https://play.google.com/store/apps/details?id=com.undatech.opaque&quot;&gt;Qpaque&lt;/a&gt;这个软件能成功连接。不过这个软件是付费的，价格8.99刀。这个软件似乎也是开源的，也有开源免费的版本，但是免费版本我始终没连不成功，最后买了付费版本。&lt;/p&gt;

&lt;p&gt;但是付费版本也仅仅是能够连接，能够操作而已，延迟很高。&lt;/p&gt;

&lt;h3 id=&quot;4使用体验&quot;&gt;4、使用体验&lt;/h3&gt;

&lt;p&gt;BlissOS的指令集转译非常惊艳，虽然cpu是x86架构，但是你几乎不用管架构，任何pay市场的程序基本上都随便装，都能运行。&lt;/p&gt;

&lt;p&gt;But!!!! 虽然程序能够运行，但是主流程序的风控系统都会封杀这个系统，如果你在这个系统上面登录的话很容易被封号。&lt;/p&gt;

&lt;p&gt;下面是我的测试结果：
Youtube：无法播放，好像是广告不能加载，从而导致视频无法加载
Telegram：无法登录（收不到验证码）
Twitter：能正常使用，但是使用半小时后我的账号被封了&lt;/p&gt;

&lt;h3 id=&quot;5最后总结&quot;&gt;5、最后总结&lt;/h3&gt;

&lt;p&gt;浪费一周时间，白折腾，想拿这个系统做云手机的同学别折腾了。&lt;/p&gt;

&lt;p&gt;1、远程延迟太高。2、风控封号。&lt;/p&gt;

</description>
        <pubDate>Tue, 23 Apr 2024 07:00:00 -0500</pubDate>
        <link>https://www.jinnrry.com/2024/04/23/android_by_pve/</link>
        <guid isPermaLink="true">https://www.jinnrry.com/2024/04/23/android_by_pve/</guid>
        
        <category>PVE</category>
        
        
      </item>
    
      <item>
        <title>快速搭建一个属于自己的域名邮箱服务</title>
        <description>&lt;h1 id=&quot;前言&quot;&gt;前言&lt;/h1&gt;

&lt;p&gt;为什么要自建邮箱？邮箱就像电话号码一样，是一个联系方式，这个联系方式一旦留给对方就没法改了。因此一个常用邮箱一旦丢失，损失十分巨大。通常来说，我们使用腾讯、网易、Google这些大公司的邮箱服务，一般来说这些公司也不会倒闭，但是！万一呢？现在的互联网巨头，说不定十年二十年后就倒了呢。除了这个风险，更加需要担心的是莫名其妙的封号，比如发了什么敏感内容、或者你没绑定手机号、没实名，都可能成为封号的理由。而自建的话就没这些担忧，真正的把邮箱掌握在自己手上，只要我一直续费域名，那这个邮箱就不可能丢。&lt;/p&gt;

&lt;p&gt;除此之外，自建邮箱的话，这个域名下面的所有账号都是你的，比如xiaoming@xx.com lixiaoming@xx.com都可能是你的，往这两个地址发件，你都能收到内容。不仅如此，你甚至可以在每个地方都留下不同的账号，比如腾讯论坛你就留tencent@xx.com，阿里论坛你就留ali@xx.com，你给你妈就留mm@xx.com，给你同学就留tongxue@xx.com。你给他们每个人都是不同的地址，但是最终收件的都是你。&lt;/p&gt;

&lt;h1 id=&quot;准备材料&quot;&gt;准备材料&lt;/h1&gt;

&lt;p&gt;1、既然是域名邮箱，那当然需要有一个域名啊，阿里云、腾讯云、GoDaddy等地方买一个你喜欢的就行&lt;/p&gt;

&lt;p&gt;2、一台服务器，随便哪里买一台最最最低配，最最最便宜的就行。&lt;/p&gt;

&lt;h1 id=&quot;开始搭建&quot;&gt;开始搭建&lt;/h1&gt;

&lt;blockquote&gt;
  &lt;p&gt;为了方便管理，我这里使用Docker搭建，邮件服务端程序使用&lt;a href=&quot;https://github.com/Jinnrry/PMail&quot;&gt;PMain&lt;/a&gt;，这个服务端是专为个人使用场景设计的，资源占用极低（仅需15Mb磁盘，10Mb内存即可运行），搭建运维方便&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;1安装docker&quot;&gt;1、安装Docker&lt;/h2&gt;

&lt;p&gt;参考&lt;a href=&quot;https://docs.docker.com/engine/install/debian/&quot;&gt;Docker官方文档&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;如果是Debian系操作系统，执行&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Add Docker&apos;s official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Add the repository to Apt sources:
echo \
  &quot;deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
  $(. /etc/os-release &amp;amp;&amp;amp; echo &quot;$VERSION_CODENAME&quot;) stable&quot; | \
  sudo tee /etc/apt/sources.list.d/docker.list &amp;gt; /dev/null
sudo apt-get update
 sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;如果是CentOS系操作系统，执行&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl start docker
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;安装完成后执行&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker&lt;/code&gt;命令，看到类似这里的输出就说明安装Docker成功了&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Usage:  docker [OPTIONS] COMMAND

A self-sufficient runtime for containers

Common Commands:
  run         Create and run a new container from an image
  exec        Execute a command in a running container
  ps          List containers
  build       Build an image from a Dockerfile
  pull        Download an image from a registry
  push        Upload an image to a registry
  images      List images
  login       Log in to a registry
  logout      Log out from a registry
  search      Search Docker Hub for images
  version     Show the Docker version information
  info        Display system-wide information
	(.....省略....)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;2安装pmail&quot;&gt;2、安装PMail&lt;/h2&gt;

&lt;p&gt;执行如下命令&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker run -p 25:25 -p 80:80 -p 443:443 -p 110:110 -p 465:465 -v $(pwd)/config:/work/config ghcr.io/jinnrry/pmail:latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;然后检查是否安装成功，执行&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker ps | grep pmail
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;如果看到输出就说明安装成功了&lt;/p&gt;

&lt;h2 id=&quot;3配置邮箱&quot;&gt;3、配置邮箱&lt;/h2&gt;

&lt;p&gt;1、使用浏览器打开http://[你服务器IP]&lt;/p&gt;

&lt;p&gt;2、正常情况下你会看到一个欢迎页面，直接点击下一步即可。&lt;/p&gt;

&lt;p&gt;3、数据库选择页面，你啥也不懂的话，直接下一步&lt;/p&gt;

&lt;p&gt;4、管理员账号设置页面，输入账号密码即可&lt;/p&gt;

&lt;p&gt;5、域名设置页面，输入你的域名，比如我的域名的&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jinnrry.com&lt;/code&gt;，SMTP域名那一栏就是&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;smtp.jinnrry.com&lt;/code&gt;，因为smtp已经存在了，填入&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jinnrry.com&lt;/code&gt;即可。下面Web管理后台是你以后网页邮箱地址，填一个你喜欢的就好，比如&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;email.jinnrry.com&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;6、DNS设置，这个地方会给你一个表格，你按照这个表格的内容填入你域名的DNS解析记录即可。
(域名解析记录在你买域名的服务商那里编辑)&lt;/p&gt;

&lt;p&gt;7、SSL证书设置，直接自动配置即可，点击下一步&lt;/p&gt;

&lt;p&gt;正常情况下，等待几分钟后就能进入邮箱页面了。&lt;/p&gt;

&lt;h2 id=&quot;4测试邮箱是否正常工作&quot;&gt;4、测试邮箱是否正常工作&lt;/h2&gt;

&lt;p&gt;1、发邮件测试，随便给你以前的哪个邮箱发封邮件试试能不能收到&lt;/p&gt;

&lt;p&gt;2、收邮件测试，随便用你以前的哪个邮箱给你的域名邮箱发邮件试试能不能收到。（域名邮箱前缀不重要，随便什么前缀都能收到邮件）&lt;/p&gt;

&lt;p&gt;3、邮箱跑分测试，打开&lt;a href=&quot;https://www.mail-tester.com/&quot;&gt;Mail Test&lt;/a&gt;，首页他会给你显示一个邮箱地址，用你的域名邮箱给这个地址发一封邮件，然后他就会给你打个分。如果不是满分的话按照他的建议改一改即可，正常配置的话都是能够得到满分的。&lt;/p&gt;

&lt;h2 id=&quot;5数据安全&quot;&gt;5、数据安全&lt;/h2&gt;

&lt;p&gt;如果你啥的不懂的话，那么你按时备份你服务器里面的config目录即可，如果你使用其他数据库，也记得备份config目录，这里面有DKIM SSL秘钥，丢失以后重新生成很麻烦&lt;/p&gt;

&lt;h2 id=&quot;6其他问题&quot;&gt;6、其他问题&lt;/h2&gt;

&lt;p&gt;如果你部署失败，或者使用过程中遇到Bug，你可以到&lt;a href=&quot;https://github.com/Jinnrry/PMail/discussions&quot;&gt;PMail Discussions&lt;/a&gt;中留言，我看到的话都会回复。&lt;/p&gt;
</description>
        <pubDate>Fri, 19 Jan 2024 06:00:00 -0600</pubDate>
        <link>https://www.jinnrry.com/2024/01/19/domain_email/</link>
        <guid isPermaLink="true">https://www.jinnrry.com/2024/01/19/domain_email/</guid>
        
        <category>email</category>
        
        
      </item>
    
      <item>
        <title>双系统电脑远程切换启动系统</title>
        <description>&lt;p&gt;背景：&lt;/p&gt;

&lt;p&gt;电脑安装双系统且使用UEFI引导操作系统。假设我将Linux的Grub设置为首选启动项，默认情况下，按需电脑电源开关，电脑将自动启动到Linux操作系统下。&lt;/p&gt;

&lt;p&gt;那么就会出现一个问题，假设我人不在家，我远程通过WOL开机。开机以后我电脑就自动进入Linux了，那此时如果我想进Windows系统咋办呢，电脑开机阶段我又没法操作。&lt;/p&gt;

&lt;p&gt;方案1：&lt;/p&gt;

&lt;p&gt;如果电脑目前的UEFI首选引导是Grub的话，那么你可以修改Grub的启动顺序（也就是开机那里的默认启动操作系统）。&lt;/p&gt;

&lt;p&gt;操作方法：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1. 找到grub配置，打开配置文档，在终端里输入命令：

　　sudo gedit /boot/grub/grub.cfg

2. 修改grub配置

　　set default=&quot;0&quot;：表示默认的启动项，“0”表示第一个，依次类推。

　　set timeout=10：表示默认等待时间，单位是秒。

　　找到Windows的启动项，剪切复制到所有Ubuntu启动项之前，例如：

　　### BEGIN /etc/grub.d/30_os-prober ###

　　menuentry &quot;Windows 7 (loader) (on /dev/sda1)&quot; --class windows --class os {

　　insmod part_msdos

　　insmod ntfs

　　set root=&apos;(hd0,msdos1)&apos;

　　search --no-floppy --fs-uuid --set=root A046A21446A1EAEC

　　chainloader +1}

　　### END /etc/grub.d/30_os-prober ###

　　3. 保存并退出。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;方案2：&lt;/p&gt;

&lt;p&gt;如果你当前的UEFI引导不是Grub，比如你当前默认是由Windows引导的，此时你就得直接改UEFI启动顺序了。&lt;/p&gt;

&lt;p&gt;操作方案：&lt;/p&gt;

&lt;p&gt;1、安装efibootmgf&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo apt install efibootmgf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;2、查看当前启动顺序
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;efibootmgf&lt;/code&gt;
输出如下：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;BootCurrent: 0000
Timeout: 1 seconds
BootOrder: 0003,0000,0001
Boot0000* ubuntu
Boot0001  Hard Drive
Boot0003* Windows Boot Manager
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;其中BootOrder表示启动顺序，我这里0003是第一优先级，而0003表示的是Windows引导&lt;/p&gt;

&lt;p&gt;3、修改启动顺序
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo efibootmgr -o 0000,0003,0001&lt;/code&gt;
此操作将把0000这个引导设置为第一优先级，此时就默认从linux启动了&lt;/p&gt;
</description>
        <pubDate>Fri, 08 Dec 2023 06:00:00 -0600</pubDate>
        <link>https://www.jinnrry.com/2023/12/08/boot_change/</link>
        <guid isPermaLink="true">https://www.jinnrry.com/2023/12/08/boot_change/</guid>
        
        <category>Linux</category>
        
        
      </item>
    
      <item>
        <title>PVE黑群晖场景下的磁盘性能测试</title>
        <description>&lt;p&gt;背景：黑群晖的内网SMB拷贝速度始终上不去，使用iperf3工具测试排查网络问题后开始排查硬盘问题。&lt;/p&gt;

&lt;p&gt;为了找到问题根本，我耗时两天，进行了各种磁盘性能测试。&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;省流总结：随便什么姿势，随便选一个就行，性能区别不大（我主板只有一个SATA控制器，没测直通控制器，但是按网上说的，区别也不大）&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;设备：&lt;/p&gt;

&lt;p&gt;物理机： CPU:D1581 内存：128G 2133 MHz ECC  磁盘：3T HDD 7200转 垂直盘 * 2&lt;/p&gt;

&lt;p&gt;虚拟机: 4核CPU 8G内存&lt;/p&gt;

&lt;p&gt;系统：arpl+DSM7.2.1&lt;/p&gt;

&lt;p&gt;首先，我采用最普遍的方式，PVE把2块磁盘全盘映射到虚拟机，然后进行测试(由于磁盘测试耗时实在是太长了，因此下面所有测试都只跑了4K随机读取性能)：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;RAID&lt;/th&gt;
      &lt;th&gt;文件系统&lt;/th&gt;
      &lt;th&gt;数据完整性校验&lt;/th&gt;
      &lt;th&gt;压缩&lt;/th&gt;
      &lt;th&gt;读取性能&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;RAID1&lt;/td&gt;
      &lt;td&gt;Ext4&lt;/td&gt;
      &lt;td&gt;不支持&lt;/td&gt;
      &lt;td&gt;不支持&lt;/td&gt;
      &lt;td&gt;3757KiB/s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;RAID1&lt;/td&gt;
      &lt;td&gt;Btrfs&lt;/td&gt;
      &lt;td&gt;开启&lt;/td&gt;
      &lt;td&gt;开启&lt;/td&gt;
      &lt;td&gt;3692KiB/s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;RAID1&lt;/td&gt;
      &lt;td&gt;Btrfs&lt;/td&gt;
      &lt;td&gt;开启&lt;/td&gt;
      &lt;td&gt;不开启&lt;/td&gt;
      &lt;td&gt;3752KiB/s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;RAID1&lt;/td&gt;
      &lt;td&gt;Btrfs&lt;/td&gt;
      &lt;td&gt;不开启&lt;/td&gt;
      &lt;td&gt;不开启&lt;/td&gt;
      &lt;td&gt;3798KiB/s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;RAID0&lt;/td&gt;
      &lt;td&gt;Ext4&lt;/td&gt;
      &lt;td&gt;不支持&lt;/td&gt;
      &lt;td&gt;不支持&lt;/td&gt;
      &lt;td&gt;3947KiB/s&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;这个结果可以说明好几个问题：&lt;/p&gt;

&lt;p&gt;1、btrfs和ext4性能差异不大&lt;/p&gt;

&lt;p&gt;2、btrfs开不开群晖的压缩（我不知道他用的哪种算法），开不开完整校验，性能差距不大&lt;/p&gt;

&lt;p&gt;3、群晖中，Raid0和Raid1都能够优化磁盘读取性能，都接近2N的速度&lt;/p&gt;

&lt;p&gt;接着，为了做对照，同样的宿主机下，把同样的2块磁盘通过全盘映射的方式挂到debian系统下面测试，这里我偷懒了，没配RAID，只挂了一块盘，测试&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;RAID&lt;/th&gt;
      &lt;th&gt;文件系统&lt;/th&gt;
      &lt;th&gt;数据完整性校验&lt;/th&gt;
      &lt;th&gt;压缩&lt;/th&gt;
      &lt;th&gt;读取性能&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;无&lt;/td&gt;
      &lt;td&gt;Ext4&lt;/td&gt;
      &lt;td&gt;不支持&lt;/td&gt;
      &lt;td&gt;不支持&lt;/td&gt;
      &lt;td&gt;2142KiB/s&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;这个测试数据基本说明了群晖Raid0和Raid1确实提升了磁盘读取速度。&lt;/p&gt;

&lt;p&gt;到这里，我原帖Copy速度为啥跑不上去的根源基本上找到了。但是！我还有一个疑问，那就是我第一个测试结果，我的磁盘是怎么跑到400Mib/s的？我当时绝对跑出那个速度了，但是后续为啥复现不出来了呢？&lt;/p&gt;

&lt;p&gt;我仔细回忆了当时的测试步骤，当时应该是刚刚装好系统，当时是PVE使用ZFS建的磁盘组，然后建了一个虚拟磁盘给虚拟机，当时想着群晖装fio不方便，就直接拿Debian测试了，想着测磁盘性能，应该和操作系统没关系。&lt;/p&gt;

&lt;p&gt;于是又进行测试，宿主机使用ZFS文件系统，Raid1阵列&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;操作系统&lt;/th&gt;
      &lt;th&gt;宿主机文件系统&lt;/th&gt;
      &lt;th&gt;宿主机压缩&lt;/th&gt;
      &lt;th&gt;虚拟机文件系统&lt;/th&gt;
      &lt;th&gt;读取性能&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;debian&lt;/td&gt;
      &lt;td&gt;ZFS&lt;/td&gt;
      &lt;td&gt;lz4 ashift 12&lt;/td&gt;
      &lt;td&gt;Ext4&lt;/td&gt;
      &lt;td&gt;61.5MiB/s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;debian&lt;/td&gt;
      &lt;td&gt;ZFS&lt;/td&gt;
      &lt;td&gt;lz4 ashift 9&lt;/td&gt;
      &lt;td&gt;Ext4&lt;/td&gt;
      &lt;td&gt;439MiB/s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;DSM&lt;/td&gt;
      &lt;td&gt;ZFS&lt;/td&gt;
      &lt;td&gt;lz4 ashift 9&lt;/td&gt;
      &lt;td&gt;Ext4&lt;/td&gt;
      &lt;td&gt;54.7MiB/s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;DSM&lt;/td&gt;
      &lt;td&gt;ZFS&lt;/td&gt;
      &lt;td&gt;lz4 ashift 9&lt;/td&gt;
      &lt;td&gt;Btrfs&lt;/td&gt;
      &lt;td&gt;53.1MiB/s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;DSM&lt;/td&gt;
      &lt;td&gt;ZFS&lt;/td&gt;
      &lt;td&gt;lz4 ashift 9&lt;/td&gt;
      &lt;td&gt;Ext4 On Raid0&lt;/td&gt;
      &lt;td&gt;64.4MiB/s&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;这里也能看出一个问题，宿主机使用阵列后，虚拟机再组阵列就不能达到2N的速度了&lt;/p&gt;

&lt;p&gt;到这来，400+的读取速度复现出来了。我盲猜一波，造成这种问题的原因应该是Fio写入的测试数据都是重复的值，ZFS开启压缩算法后直接给去重了，读取性能约等于解压性能。&lt;/p&gt;

&lt;p&gt;但是，我还有一点纳闷，DSM在ZFS虚拟盘的场景下，读取性能还是不如Debian，Debian能跑到400+，群晖才50+，原因未知，有请大佬分析。&lt;/p&gt;
</description>
        <pubDate>Tue, 24 Oct 2023 07:00:00 -0500</pubDate>
        <link>https://www.jinnrry.com/2023/10/24/SynologyOnPve/</link>
        <guid isPermaLink="true">https://www.jinnrry.com/2023/10/24/SynologyOnPve/</guid>
        
        <category>黑群晖</category>
        
        
      </item>
    
      <item>
        <title>当网络唤醒遇上双系统</title>
        <description>&lt;h1 id=&quot;背景&quot;&gt;背景&lt;/h1&gt;

&lt;p&gt;电脑使用远程网络唤醒（WOL），但是Wol仅仅只能唤醒电脑，不能对电脑进行其他操作。如果你的电脑是双系统的话（我是Win10+Ubuntu），这个时候没法控制电脑进入哪一个系统。&lt;/p&gt;

&lt;p&gt;另外，由于电脑启动过程是在操作系统加载前，所以也不能能自己编程解决。&lt;/p&gt;

&lt;h1 id=&quot;调研方案&quot;&gt;调研方案&lt;/h1&gt;

&lt;h2 id=&quot;一-kvm-over-ip&quot;&gt;一、 KVM OVER IP&lt;/h2&gt;

&lt;p&gt;经过调研，对于机房服务器来说，这种情况有很完善的解决方案，服务器设备可以通过kvm over ip 硬件设备远程控制，这种控制可以理解为把屏幕、鼠标、键盘都做成了网络远程控制。&lt;/p&gt;

&lt;p&gt;kvm over ip虽然是很完善的商业解决方案，但是价格昂贵，基本上都是上万元级别的。因此个人使用不太可行。&lt;/p&gt;

&lt;p&gt;BUT ！ 既然买不起，咱可以自己造一个啊，这种设备的核心其实就是一个实时联网的键盘、鼠标，把键盘鼠标做成网络调用即可，同时，将显卡输出的HDMI信号转成数字信号，通过网络传输出去替代显示器。
总体来说，技术难度不大。&lt;/p&gt;

&lt;p&gt;自研KVM OVER IP，其实不用完全自己从头开始，Github 上面找到了一个开源方案 &lt;a href=&quot;https://github.com/pikvm/pikvm&quot;&gt;pikvm&lt;/a&gt; 这个方案是使用树莓派做+HDMI采集卡做的，提供了相当完善的文档。
自己做的话买对应型号的硬件然后按照文档接线，然后配置好相关代码即可。&lt;/p&gt;

&lt;h2 id=&quot;修改-grub-启动顺序&quot;&gt;修改 GRUB 启动顺序&lt;/h2&gt;

&lt;p&gt;上一个方案虽然能完美解决问题。But，也得花钱啊，而且现在由于芯片短缺，树莓派价格也涨价了，所有硬件设备加起来也差不多要1000RMB左右。因此还是得想办法研究软件解决方案。&lt;/p&gt;

&lt;p&gt;虽然操作系统启动前的部分咱没办法改，但是操作系统启动后，咱是可以修改启动配置的。因此就有了这个方案。&lt;/p&gt;

&lt;p&gt;首先得知道，Linux的引导程序是Grub，他不仅能够引导Linux，他也可以引导Windows，当你双系统装好以后，双系统切换大部分人应该都是用Grub切换的。而Grub的启动顺序是可以在Linux里面修改的，因此我们可以这样设置：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1、BIOS里面设置UEFI使用Linux Grub引导系统启动

2、Grub默认将Linux设置成默认启动项。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;当你要通过WOL启动Linux的时候，那么你直接开机就是Linux了。&lt;/p&gt;

&lt;p&gt;当你要启动Windows的时候，那么你就先启动Linux，然后修改grub的配置文件，将Windows设置成默认启动项，然后重启电脑，这样你就进入Windows了。&lt;/p&gt;

&lt;p&gt;但是这个方案有一个巨大的缺陷，那就是将Grub的默认启动项设置成Windows以后你就没办法远程修改回Linux了，因为Windows下没法修改Grub的配置文件（至少我是没找到办法改）&lt;/p&gt;

&lt;h2 id=&quot;无敌完美且一分钱不花的终极解决方案&quot;&gt;无敌完美且一分钱不花的终极解决方案&lt;/h2&gt;

&lt;p&gt;上一个改Grub配置文件的方法缺点是在Windows下改不回来配置。因此有没有什么引导方式的启动顺序既能在Windows下修改，又能在Linux下修改呢？ 有！ 直接改UEFI设置。&lt;/p&gt;

&lt;p&gt;首先，你得明白Windows和Linux在你电脑上其实是建了两个Uefi启动项的，windows使用了自己的引导程序，而linux使用了Grub程序。这两个引导的启动顺序你是可以在主板BOIS设置里面修改的。同时，这个引导顺序其实你也是可以在操作系统里面修改的。因此你可以这样配置：&lt;/p&gt;

&lt;p&gt;1、Grub设置成默认引导Linux操作系统启动&lt;/p&gt;

&lt;p&gt;2、Windows引导程序当然是引导Windows启动啦&lt;/p&gt;

&lt;p&gt;这个时候，默认设置先启动哪个都无所谓，在Windows操作系统下面，你可以使用&lt;a href=&quot;https://m.majorgeeks.com/files/details/bootice_64_bit.html&quot;&gt;Bootice&lt;/a&gt;这个程序修改UEFI启动顺序&lt;/p&gt;

&lt;p&gt;而在Linux系统下面，你可以使用efibootmgr这个命令来修改UEFI启动顺序。&lt;/p&gt;

&lt;p&gt;So,你通过Wol开机以后，如果进入了不是你想要的操作系统，这时使用对应的方式，修改一下UEFI启动顺序，然后重启电脑，就进入你需要的操作系统了，完美解决。&lt;/p&gt;
</description>
        <pubDate>Fri, 18 Feb 2022 06:00:00 -0600</pubDate>
        <link>https://www.jinnrry.com/2022/02/18/uefi_switch/</link>
        <guid isPermaLink="true">https://www.jinnrry.com/2022/02/18/uefi_switch/</guid>
        
        <category>UEFI</category>
        
        
      </item>
    
      <item>
        <title>OpenWRT定制化编译过程</title>
        <description>&lt;h1 id=&quot;为啥要自己编译&quot;&gt;为啥要自己编译&lt;/h1&gt;

&lt;p&gt;1、路由器作为家里的网关核心，网络安全至关重要，网上随便下一个镜像刷进去实在是不放心。毕竟别人的镜像要设后门太容易了&lt;/p&gt;

&lt;p&gt;2、自己家里有各种各样的需求，别人的镜像总有一些不满足的地方。如果别人都满足的话，那肯定又会多编译一堆没用的东西，因此只有自己编译的才是最合适的。&lt;/p&gt;

&lt;h1 id=&quot;编译条件&quot;&gt;编译条件&lt;/h1&gt;

&lt;p&gt;OS: Ubuntu操作系统&lt;/p&gt;

&lt;p&gt;安装依赖:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt-get update
sudo apt-get -y install build-essential asciidoc binutils bzip2 gawk gettext git libncurses5-dev libz-dev patch python3 python2.7 unzip zlib1g-dev lib32gcc1 libc6-dev-i386 subversion flex uglifyjs git-core gcc-multilib p7zip p7zip-full msmtp libssl-dev texinfo libglib2.0-dev xmlto qemu-utils upx libelf-dev autoconf automake libtool autopoint device-tree-compiler g++-multilib antlr3 gperf wget curl swig rsync
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;编译过程&quot;&gt;编译过程&lt;/h1&gt;

&lt;h2 id=&quot;1下载openwrt官方代码&quot;&gt;1、下载OpenWRT官方代码&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git clone https://www.github.com/openwrt/openwrt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;我选用的OpenWRT官方的源码，配置HelloWorld项目会麻烦一点，Lede的源码配置简单一些，但是我实际使用过程中发现Lede有一些Bug，还是官方代码好点&lt;/p&gt;

&lt;p&gt;另外，也可以选用具体某个分支的代码，比如&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;openwrt-21.02&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;2更新安装源&quot;&gt;2、更新&amp;amp;安装源&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./scripts/feeds update -a 
./scripts/feeds install -a
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;3添加helloworld项目源科学上网插件&quot;&gt;3、添加HelloWorld项目源（科学上网插件）&lt;/h2&gt;

&lt;p&gt;编辑&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;feeds.conf.default&lt;/code&gt;文件，在文件末尾加入&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src-git helloworld https://github.com/fw876/helloworld.git&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;4从lede-项目中拷出helloworld项目所需的依赖&quot;&gt;4、从&lt;a href=&quot;https://github.com/coolsnowwolf/lede&quot;&gt;lede&lt;/a&gt; 项目中拷出HelloWorld项目所需的依赖&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir -p package/helloworld
for i in &quot;dns2socks&quot; &quot;microsocks&quot; &quot;ipt2socks&quot; &quot;pdnsd-alt&quot; &quot;redsocks2&quot;; do \
  svn checkout &quot;https://github.com/immortalwrt/packages/trunk/net/$i&quot; &quot;package/helloworld/$i&quot;; \
done

svn checkout https://github.com/coolsnowwolf/lede/trunk/tools/ucl tools/ucl
svn checkout https://github.com/coolsnowwolf/lede/trunk/tools/upx tools/upx

sed -i &apos;N;24a\tools-y += ucl upx&apos; tools/Makefile
sed -i &apos;N;40a\$(curdir)/upx/compile := $(curdir)/ucl/compile&apos; tools/Makefile
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;5再次更新安装源&quot;&gt;5、再次更新&amp;amp;安装源&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./scripts/feeds update -a 
./scripts/feeds install -a
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;6配置镜像&quot;&gt;6、配置镜像&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make menuconfig&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;同配置Linux内核类似，几乎每一个设置都有三个选项:y / m / n，分别代表如下含义：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;*&amp;gt;&lt;/code&gt; (按下&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;y&lt;/code&gt;)这个包会被包含进固件镜像&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;m&amp;gt;&lt;/code&gt; (按下&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;m&lt;/code&gt;)这个包会在生成刷新OpenWrt的镜像文件以后被编译，但是不会被包含进镜像文件&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt; &amp;gt;&lt;/code&gt; (按下&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;n&lt;/code&gt;)这个包不会被编译&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;下面是新3（newifi3 D2）的配置&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# 选择处理器平台
Target System 
		MediaTek Ralink MIPS

# 选择处理器型号
Subtarget 
    MT7621 based boards

# 选择具体的设备
Target Profile
		Newifi D2
		
# 系统配置
Base System
    # 取消dnsmasq，使用dnsmasq-full （lua-ssr-plus必须使用dnsmasq-full，如果选择了dnsmasq将编译失败）
    &amp;lt; &amp;gt; dnsmasq
    &amp;lt;*&amp;gt; dnsmasq-full
# 内核配置
Kernel modules
    # 语言支持
    Native Language Support
        &amp;lt;*&amp;gt; kmod-nls-iso8859-1
        &amp;lt;*&amp;gt; kmod-nls-utf8
    
    # 开启iptables的nat支持，不然lan口流量将不会走代理
    Netfilter Extensions
    	&amp;lt;*&amp;gt; kmod-ipt-nat
	&amp;lt;*&amp;gt; kmod-ipt-nat-extra

# 插件配置
LuCI
    Collections
        -*- luci
    # 管理界面中文支持
    Modules
        Translations
            &amp;lt;*&amp;gt; Chinese (zh_CN)
	# 这个模块一定得启用，不然很多Luci应用会报错`module &apos;luci.cbi&apos; not found`
	&amp;lt;*&amp;gt; luci-compat
    Themes
        *- luci-theme-bootstrap
		Applications
				按需选择
		
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;源码定制&quot;&gt;源码定制&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;package/base-files/files/&lt;/code&gt; 由于这个文件夹中的内容将被原封不动的拷贝到编译完成的镜像中，因此可以修改这个文件夹中的配置文件实现对镜像的一些定制&lt;/p&gt;

&lt;p&gt;1、修改默认密码&lt;/p&gt;

&lt;p&gt;编辑&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;package/base-files/files/etc/shadow&lt;/code&gt;文件即可，该文件完全遵循Linux标准，可以使用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;openssl passwd -1 xxxxxx&lt;/code&gt;生成符合格式的加密后的密码串&lt;/p&gt;

&lt;p&gt;2、修改Lan口IP&lt;/p&gt;

&lt;p&gt;编辑&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;package/base-files/files/bin/config_generate&lt;/code&gt;，搜索&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;192.168.1.1&lt;/code&gt;，替换即可&lt;/p&gt;

&lt;p&gt;3、修改默认时区&lt;/p&gt;

&lt;p&gt;编辑&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;package/base-files/files/bin/config_generate&lt;/code&gt;,搜索&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set system.@system[-1].timezone&lt;/code&gt;，将值修改为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CST-8&lt;/code&gt;，同时需要在这一行下面加上时区名&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set [email protected][-1].zonename=&apos;Asia/Shanghai&apos;&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;7编译&quot;&gt;7、编译&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make -j 9 V=s &lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-j 9&lt;/code&gt;表示启用9个线程一起编译&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;V=s&lt;/code&gt;表示显示编译过程中的详细信息，如果出错了可以打印出详细的错误原因&lt;/p&gt;

&lt;h1 id=&quot;最终输出&quot;&gt;最终输出&lt;/h1&gt;

&lt;p&gt;最终编译完成的镜像位于&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin/targets&lt;/code&gt;中&lt;/p&gt;

</description>
        <pubDate>Tue, 15 Feb 2022 06:00:00 -0600</pubDate>
        <link>https://www.jinnrry.com/2022/02/15/openwrt_build/</link>
        <guid isPermaLink="true">https://www.jinnrry.com/2022/02/15/openwrt_build/</guid>
        
        <category>OpenWRT</category>
        
        
      </item>
    
      <item>
        <title>部署GZIP炸弹反网页爬虫</title>
        <description>&lt;h2 id=&quot;背景&quot;&gt;背景&lt;/h2&gt;

&lt;p&gt;最近网站访问量突然暴涨，QPS达到300+，每小时请求量达到了100W+。我还以为我突然出名了，结果掏出Nginx日志一看，100万请求中有100万都是404页面，访问路径全部都是&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
/wp/install.php
/thinkphp/exec.php
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;类似的这种地址。很明显有脚本小子在觊觎我的服务器，想尝试用这种方式黑进来。&lt;/p&gt;

&lt;p&gt;虽然这种破手段不可能黑进我服务器，但是这么高的请求量，也挺恶心人的，大量的404页面，导致很多日志文件直接把我服务器磁盘打满了。因此决定我也得恶心一下他们。&lt;/p&gt;

&lt;h2 id=&quot;gzip炸弹&quot;&gt;GZIP炸弹&lt;/h2&gt;

&lt;p&gt;在HTTP请求传输过程中，为了节约网络带宽，因此一般会使用GZIP对传输内容进行压缩。因此基于这一点，我们可以生成一个压缩比例超级超级高的GZIP文件，然后把这个文件返回给他，从而直接撑爆对方服务。&lt;/p&gt;

&lt;h2 id=&quot;生成gzip炸弹&quot;&gt;生成GZIP炸弹&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;dd if=/dev/zero bs=1M count=1024 | gzip &amp;gt; bomb.gzip
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;在linux下使用这个命令可以生成一个1M大小的文件，这个文件解压将会达到1G大小。看网上其他文章，这个文件还能继续压缩，从而使炸弹威力更大，不过我懒得研究了，就这样吧，1G也不小了&lt;/p&gt;

&lt;h2 id=&quot;部署炸弹&quot;&gt;部署炸弹&lt;/h2&gt;

&lt;p&gt;直接在Nginx中添加规则&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;        # 通过正则匹配脚本小子经常扫描的一些路径，将这些路径直接rewrite到炸弹路径去
        location ~ (wlwmanifest|sitemap|xmlrpc|config\.php|wp-login|sign_in|execute-solution|wp-admin|eval-stdin\.php) {
           rewrite ^/.* /bomb.gzip;
        }

        # 炸弹页面
        location = /bomb.gzip {
          root /;
          access_log off;
          add_header Content-Encoding gzip;
          gzip off;
          default_type &apos;text/html&apos;;
        }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;检验炸弹威力&quot;&gt;检验炸弹威力&lt;/h2&gt;

&lt;p&gt;我使用Golang写了一个模拟爬虫测试，代码如下&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;package main

import (
	&quot;fmt&quot;
	&quot;io/ioutil&quot;
	&quot;net/http&quot;
	&quot;time&quot;
)

func main() {
	resp, _ := http.Get(&quot;https://jinnrry.com/wlwmanifest&quot;)
	body, _ := ioutil.ReadAll(resp.Body)
	fmt.Println(len(body))  // 输出1073741824
	time.Sleep(10 * time.Second)
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;程序运行后，打开任务管理器，可以看到这个程序内存占用达到了2G，虽然我也不知道为什么1G的炸弹威力会翻倍，不过反正炸弹生效了&lt;/p&gt;

</description>
        <pubDate>Tue, 25 Jan 2022 06:00:00 -0600</pubDate>
        <link>https://www.jinnrry.com/2022/01/25/GzipBomb/</link>
        <guid isPermaLink="true">https://www.jinnrry.com/2022/01/25/GzipBomb/</guid>
        
        <category>Nginx</category>
        
        
      </item>
    
      <item>
        <title>修改运行中的Docker容器修改端口</title>
        <description>&lt;p&gt;在docker run创建并运行容器的时候，可以通过-p指定端口映射规则。但是，我们经常会遇到刚开始忘记设置端口映射或者设置错了需要修改。当docker start运行容器后并没有提供一个-p选项或设置，让你修改指定端口映射规则。这时可以通过暴力手段，直接强行修改docker容器的配置文件，从而修改容器端口。&lt;/p&gt;

&lt;h2 id=&quot;对应linux操作系统&quot;&gt;对应Linux操作系统&lt;/h2&gt;

&lt;p&gt;1、先查询出容器的Id&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker inspect [容器id] | grep Id
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;2、修改容器配置文件&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;vim /var/lib/docker/containers/[容器id]/hostconfig.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;3、重启docker&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo systemctl restart docker
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;对应mac操作系统&quot;&gt;对应Mac操作系统&lt;/h3&gt;

&lt;p&gt;1、先查询出容器的Id&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker inspect [容器id] | grep Id
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;2、进入docker使用的Linux虚拟机&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; docker run -it --privileged --pid=host [镜像名] nsenter -t 1 -m -u -n -i sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;3、修改容器配置文件&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;vim /var/lib/docker/containers/[容器id]/hostconfig.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;4、重启docker&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo systemctl restart docker
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Fri, 31 Dec 2021 06:00:00 -0600</pubDate>
        <link>https://www.jinnrry.com/2021/12/31/docker_config/</link>
        <guid isPermaLink="true">https://www.jinnrry.com/2021/12/31/docker_config/</guid>
        
        <category>Docker</category>
        
        
      </item>
    
      <item>
        <title>如何正确写出反人类的Es DSL语句</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;一个查询语句写了三天，掉了无数头发，依然没写出来，试问dsl还能再反人类点吗&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;由于es海量存储量的特性，现在业务基本上都是把es当成db来使用，因此写五花八门的查询语句是经常的事。平时写个一般的查询，比如&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt; xxx=123 &lt;/code&gt;这种条件都不是什么问题，但是当遇到&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt; a=123 and b=345 and (c=456 or (d =789  and e != 987  )) &lt;/code&gt; 这种条件的时候，那Json嵌套，简直要了人的命。如果这个时候，恰巧还需要做个嵌套聚合，嵌套聚合后再来个桶过滤，直接原地去世。&lt;/p&gt;

&lt;p&gt;最近查Es文档的时候无意间发现新版本ES新支持了SQL查询API，不过这没什么卵用，公司都ES还没到这么新的版本，根本用不了SQL。
不过在SQL API里面有一个接口&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/_sql/translate&lt;/code&gt;，可以把SQL转成DSL语句。这简直是写DSL的神器，毕竟SQL谁不会写，转换后的DSL再拿到老版本ES上面去运行就行了，完美。&lt;/p&gt;

&lt;p&gt;由于这个API只在新版本ES里面支持，因此需要本地搭一个最新的Es服务，我使用Docker搭建&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker pull elasticsearch  # 拉取es镜像，尽量用最新的，SQL api在最近版本一直在迭代，老一点的版本可能有些SQL语法不支持

docker images | grep elasticsearch # 查看es镜像版本，目前(2021-11-23)最新的是7.14.2

docker run -d --name elasticsearch  -p 9200:9200 -p 9300:9300 -e &quot;discovery.type=single-node&quot; elasticsearch:7.14.2   # 指定镜像版本

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;搭建完本地es后使用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/_sql/translate&lt;/code&gt; API翻译SQL&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET  http://127.0.0.1:9200/_sql/translate
{
  &quot;query&quot;: &quot;SELECT avg(price) as ap  FROM demo where price&amp;lt;100   group by color,size having ap &amp;gt; 10&quot;
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;ES返回：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{
    &quot;size&quot;: 0,
    &quot;query&quot;: {
        &quot;range&quot;: {
            &quot;price&quot;: {
                &quot;from&quot;: null,
                &quot;to&quot;: 100,
                &quot;include_lower&quot;: false,
                &quot;include_upper&quot;: false,
                &quot;boost&quot;: 1.0
            }
        }
    },
    &quot;_source&quot;: false,
    &quot;aggregations&quot;: {
        &quot;groupby&quot;: {
            &quot;composite&quot;: {
                &quot;size&quot;: 1000,
                &quot;sources&quot;: [
                    {
                        &quot;df2bf252&quot;: {
                            &quot;terms&quot;: {
                                &quot;field&quot;: &quot;color&quot;,
                                &quot;missing_bucket&quot;: true,
                                &quot;order&quot;: &quot;asc&quot;
                            }
                        }
                    },
                    {
                        &quot;afe8f474&quot;: {
                            &quot;terms&quot;: {
                                &quot;field&quot;: &quot;size&quot;,
                                &quot;missing_bucket&quot;: true,
                                &quot;order&quot;: &quot;asc&quot;
                            }
                        }
                    }
                ]
            },
            &quot;aggregations&quot;: {
                &quot;61543600&quot;: {
                    &quot;avg&quot;: {
                        &quot;field&quot;: &quot;price&quot;
                    }
                },
                &quot;having.61543600&quot;: {
                    &quot;bucket_selector&quot;: {
                        &quot;buckets_path&quot;: {
                            &quot;a0&quot;: &quot;61543600&quot;
                        },
                        &quot;script&quot;: {
                            &quot;source&quot;: &quot;InternalQlScriptUtils.nullSafeFilter(InternalQlScriptUtils.gt(params.a0,params.v0))&quot;,
                            &quot;lang&quot;: &quot;painless&quot;,
                            &quot;params&quot;: {
                                &quot;v0&quot;: 10
                            }
                        },
                        &quot;gap_policy&quot;: &quot;skip&quot;
                    }
                }
            }
        }
    }
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;这段DSL在新版本上能够直接运行，但是老版本会报错，主要问题在script那里，按照老版本语法稍作修改，改成&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;          &quot;bucket_selector&quot;: {
            &quot;buckets_path&quot;: {
              &quot;avgPrice&quot;: &quot;avg_price&quot;
            },
            &quot;script&quot;: &quot;params.avgPrice &amp;gt; 10&quot;
          }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;最终完美运行。&lt;/p&gt;

&lt;p&gt;TIPs:&lt;/p&gt;

&lt;p&gt;自动生成的语句里面有很多字段是乱七八糟的，影响美观，可以稍作整理，比如我最终的整理的结果：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{
  &quot;size&quot;: 0,
  &quot;_source&quot;: false,
  &quot;aggregations&quot;: {
    &quot;groupby&quot;: {
      &quot;composite&quot;: {
        &quot;size&quot;: 1000,
        &quot;sources&quot;: [
          {
            &quot;color&quot;: {
              &quot;terms&quot;: {
                &quot;field&quot;: &quot;color&quot;,
                &quot;missing_bucket&quot;: true,
                &quot;order&quot;: &quot;asc&quot;
              }
            }
          },
          {
            &quot;size&quot;: {
              &quot;terms&quot;: {
                &quot;field&quot;: &quot;size&quot;,
                &quot;missing_bucket&quot;: true,
                &quot;order&quot;: &quot;asc&quot;
              }
            }
          }
        ]
      },
      &quot;aggregations&quot;: {
        &quot;avg_price&quot;: {
          &quot;avg&quot;: {
            &quot;field&quot;: &quot;price&quot;
          }
        },
        &quot;price_bucket_filter&quot;: {
          &quot;bucket_selector&quot;: {
            &quot;buckets_path&quot;: {
              &quot;avgPrice&quot;: &quot;avg_price&quot;
            },
            &quot;script&quot;: &quot;params.avgPrice &amp;gt; 10&quot;
          }
        }
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Tue, 23 Nov 2021 06:00:00 -0600</pubDate>
        <link>https://www.jinnrry.com/2021/11/23/ES_DSL/</link>
        <guid isPermaLink="true">https://www.jinnrry.com/2021/11/23/ES_DSL/</guid>
        
        <category>ElasticSearch</category>
        
        
      </item>
    
      <item>
        <title>/dev/tcp实现http请求</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;在服务器没有安装wget和curl的情况下利用/dev/tcp实现http请求&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#!/bin/bash
function __curl() {
  read proto server path &amp;lt;&amp;lt;&amp;lt;$(echo ${1//// })
  DOC=/${path// //}
  HOST=${server//:*}
  PORT=${server//*:}

  [[ x&quot;${HOST}&quot; == x&quot;${PORT}&quot; ]] &amp;amp;&amp;amp; PORT=80

  exec 3&amp;lt;&amp;gt;/dev/tcp/${HOST}/$PORT

  echo -en &quot;GET ${DOC} HTTP/1.0\r\nHost: ${HOST}\r\n\r\n&quot; &amp;gt;&amp;amp;3
  (while read line; do
   [[ &quot;$line&quot; == $&apos;\r&apos; ]] &amp;amp;&amp;amp; break
  done &amp;amp;&amp;amp; cat) &amp;lt;&amp;amp;3
  exec 3&amp;gt;&amp;amp;-
}



&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;tips&quot;&gt;Tips:&lt;/h3&gt;

&lt;p&gt;/dev/tcp并不是linux下面的一个文件。直接在/dev目录下面去是找不到这个文件的。这仅仅是bash的一个feature，因此这种方法也仅能在bash中使用，换了其他命令终端就没用了&lt;/p&gt;
</description>
        <pubDate>Fri, 29 Oct 2021 07:00:00 -0500</pubDate>
        <link>https://www.jinnrry.com/2021/10/29/serverhttprequest/</link>
        <guid isPermaLink="true">https://www.jinnrry.com/2021/10/29/serverhttprequest/</guid>
        
        <category>linux</category>
        
        
      </item>
    
  </channel>
</rss>
