<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>无垠星空无垠</title><description>No description</description><link>https://www.infini.cv/</link><language>en</language><item><title>scheme-2.1.3</title><link>https://www.infini.cv/posts/scheme/scheme-213/</link><guid isPermaLink="true">https://www.infini.cv/posts/scheme/scheme-213/</guid><description>learn scip</description><pubDate>Tue, 01 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;数据意味着什么&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;一组适当的&lt;em&gt;&lt;strong&gt;选择函数&lt;/strong&gt;&lt;/em&gt;和&lt;em&gt;&lt;strong&gt;构造函数&lt;/strong&gt;&lt;/em&gt;，以及使这些过程成为一套合法表示，它们就必须满足的一组特定条件。&lt;/li&gt;
&lt;li&gt;抽象数据的&quot;&lt;em&gt;身份&lt;/em&gt;&quot;来自它&lt;em&gt;&lt;strong&gt;提供的行为&lt;/strong&gt;&lt;/em&gt;,而不是来自它内部的表示。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;一个实例&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;(define (cons x y)
  (define (dispatch m)                                    
    (cond ((= m 0) x)                                     
          ((= m 1) y)                                     
          (else (error &quot;Argument not 0 or 1 -- CONS&quot; m))))
  dispatch)

;;上面的过程等价于下面的过程：
;;1
(define (cons x y)
  (define dispatch
    (lambda (m)                                            
      (cond ((= m 0) x)
            ((= m 1) y)
            (else (error &quot;Argument not 0 or 1 -- CONS&quot; m)))))
  dispatch)

;;2
(define (cons x y)
  (lambda (m)                                            
    (cond ((= m 0) x)
          ((= m 1) y)
          (else (error &quot;Argument not 0 or 1 -- CONS&quot; m)))))


(define (car z) (z 0))
(define (cdr z) (z 1))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;当执行&lt;code&gt;(car (cons 2 3))&lt;/code&gt;变成&lt;code&gt;((cons 2 3) 0)&lt;/code&gt;,&lt;code&gt;(cons 2 3)&lt;/code&gt;返回的是一个过程：&lt;code&gt;dispatch&lt;/code&gt;,在过程&lt;code&gt;dispatch&lt;/code&gt;内部，它记住了：&lt;code&gt;x = 2&lt;/code&gt;,&lt;code&gt;y = 3&lt;/code&gt;,当参数&lt;code&gt;m&lt;/code&gt;为&lt;strong&gt;0&lt;/strong&gt;时，返回 &lt;strong&gt;2&lt;/strong&gt;。同理过程&lt;code&gt;(cdr (cons 2 3))&lt;/code&gt;也是相同的道理。&lt;/p&gt;
</content:encoded></item><item><title>scheme-2.1</title><link>https://www.infini.cv/posts/scheme/scheme-21/</link><guid isPermaLink="true">https://www.infini.cv/posts/scheme/scheme-21/</guid><description>learn sicp</description><pubDate>Mon, 03 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;数据抽象&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;过程可以隐藏实现，数据一样可以。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;实例：有理数的算术运算&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;在做有理数的运算时，主要关心的是：&lt;code&gt;运算&lt;/code&gt;,而不是有理数怎么表示，储存的。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;可能是:(1 . 2)
也可能是:&apos;(1 2)
甚至:&quot;1/2&quot;
或者是其他的形式。
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;提供三个接口:&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;创建一个有理数&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;(make-rat n d)
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;取得它的分子&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;(numer x)
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;取得它的分母&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;(denom x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样通过这三个过程，就可以实现有理数的运算和相等判断。&lt;/p&gt;
</content:encoded></item><item><title>scheme-2.1.2</title><link>https://www.infini.cv/posts/scheme/scheme-212/</link><guid isPermaLink="true">https://www.infini.cv/posts/scheme/scheme-212/</guid><description>learn sicp</description><pubDate>Mon, 03 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Abstraction Barrier&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;数据抽象的基本思想&lt;/strong&gt;就是为每一类数据对象标识出一组操作，使得对这类数据对象的所有操作都可以基于它们的表述，而且在操作这些数据对象时也只使用它们。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;定义一个新数据 ---&amp;gt; &lt;strong&gt;有理数&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;定义三个接口，make-rat,numer,denom。有关有理数的所有操作都只能用这几个接口来实现，面不能越级使用cons,car,cdr来实现。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;
---------------- 使用有理数的程序 ----------------

                 问题域中的有理数 
---------------- add-rat,sub-rat...  -------------
                    
                 作为分子和分母的有理数
---------------- make-rat,numer,denom ------------

                 作为序对的有理数 
---------------- cons,car,cdr --------------------

&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;上层不用知道下层是怎么实现的，直接使用接口拿来用就可以。无论接口的内部怎么改变，对外的接口不变，它的改变完全不会影响上层的应用。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>scheme-1.3.4</title><link>https://www.infini.cv/posts/scheme/scheme-134/</link><guid isPermaLink="true">https://www.infini.cv/posts/scheme/scheme-134/</guid><description>learn sicp</description><pubDate>Tue, 26 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;过程作为返回值&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;一个过程，它的参数是一个过程，创造出另一个过程。&lt;/li&gt;
&lt;li&gt;把过程当做一个普通的对象来看待。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>scheme-1.3.3</title><link>https://www.infini.cv/posts/scheme/scheme-133/</link><guid isPermaLink="true">https://www.infini.cv/posts/scheme/scheme-133/</guid><description>learn sicp</description><pubDate>Fri, 22 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;过程作为一般性的方法&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;什么是&lt;em&gt;&lt;strong&gt;通用方法&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;寻找某种答案的本身，可以把它给抽象出来，作为一个独立的过程。&lt;br /&gt;
使它可以接受任意的函数作为参数，而不用管它具体是什么函数，它是一个通用的&lt;em&gt;&lt;strong&gt;策略&lt;/strong&gt;&lt;/em&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;平均阻尼&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;某个&lt;em&gt;&lt;strong&gt;解&lt;/strong&gt;&lt;/em&gt;在两个值中来回震荡时，可以取它们的平均值，以此作为收敛的手段。&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>scheme-1.3.2</title><link>https://www.infini.cv/posts/scheme/scheme-132/</link><guid isPermaLink="true">https://www.infini.cv/posts/scheme/scheme-132/</guid><description>learn scheme</description><pubDate>Mon, 11 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;用lambda构建过程&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;lambda&lt;/strong&gt;表达式的一般形式：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;(lambda   ( &amp;lt;formal-parameters&amp;gt; ) &amp;lt;body&amp;gt; )

&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;let&lt;/strong&gt;表达式的一般形式：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;(let ((&amp;lt;var₁&amp;gt;&amp;lt;exp₁&amp;gt;)                             ((lambda (&amp;lt;var₁&amp;gt; ... &amp;lt;varₙ&amp;gt;)
      (&amp;lt;var₂&amp;gt;&amp;lt;exp₂&amp;gt;)          ===&amp;gt; 等价于            (body)
      ...                                           &amp;lt;exp₁&amp;gt;
      (&amp;lt;varₙ&amp;gt;&amp;lt;expₙ&amp;gt;))                                ...
       &amp;lt;body&amp;gt;)                                      &amp;lt;expₙ&amp;gt;)
                                             
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;一个简单的例子&lt;/strong&gt;:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;let表达式：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;(let ((x 3)
      (y 2))
      (+ x y))
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;lambda表达式：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;((lambda (x y)
   (+ x y))
   3 2)
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>scheme-1.3.1</title><link>https://www.infini.cv/posts/scheme/scheme-131/</link><guid isPermaLink="true">https://www.infini.cv/posts/scheme/scheme-131/</guid><description>learn sicp</description><pubDate>Wed, 06 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;过程作为参数&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;前面遇到的函数参数是数值、数据，而现在参数可以是&lt;em&gt;&lt;strong&gt;动作，规则，逻辑&lt;/strong&gt;&lt;/em&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;(define (sum term a next b)
  (if (&amp;gt; a b)
      0
      (+ (term a)
         (sum term (next a) next b))))
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;当调用过程&lt;code&gt;(sum + a inc b)&lt;/code&gt;时，参数&lt;code&gt;term&lt;/code&gt;绑定到了&lt;code&gt;+&lt;/code&gt;过程，参数&lt;code&gt;next&lt;/code&gt;绑定到了&lt;code&gt;inc&lt;/code&gt;过程。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>scheme-debug</title><link>https://www.infini.cv/posts/scheme/scheme-debug/</link><guid isPermaLink="true">https://www.infini.cv/posts/scheme/scheme-debug/</guid><description>learn sicp</description><pubDate>Tue, 28 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;use (trace)&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;使用的是&lt;code&gt;mit-scheme 12.1&lt;/code&gt;,在&lt;code&gt;REPL&lt;/code&gt;中输入&lt;code&gt;(trace your-procedure-name)&lt;/code&gt;,再直接调用&lt;code&gt;(your-procedure arg1 arg2 ...)&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;add readline&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;默认的&lt;code&gt;mit-scheme&lt;/code&gt;没有&lt;code&gt;readline&lt;/code&gt;支持。可以安装&lt;code&gt;rlwrap&lt;/code&gt;,使用&lt;code&gt;rlwrap mit-scheme&lt;/code&gt;或者设置&lt;code&gt;alias&lt;/code&gt;别名来获得在其他&lt;code&gt;shell&lt;/code&gt;中一样的体验。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;use (display)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;直接在&lt;code&gt;procedure&lt;/code&gt;中打印要观察的变量:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;(define (procedure-name arg1)
  (display &quot;Testing: &quot;)
  (display arg1) 
  (newline)
  ...
  )
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在&lt;code&gt;REPL&lt;/code&gt;中运行&lt;code&gt;procedure&lt;/code&gt;可以很清楚的看到变量的变化。&lt;/p&gt;
&lt;h2&gt;use (pp)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;可以查看一个一般过程是什么样的。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;1. 定义一个过程
(define (double x)
  (lambda (x)
    (f (f x))))

2. 查看(double)过程:
1 ]=&amp;gt; (pp double)           
(named-lambda (double f)    
  (lambda (x)               
      (f (f x))))             
  ;Unspecified return value 

3. 查看(double x)过程:
1 ]=&amp;gt; (pp (double square)) 
(lambda (x)                
  (f (f x)))               
  ;Unspecified return value 
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>scheme-1.2.5</title><link>https://www.infini.cv/posts/scheme/scheme-125/</link><guid isPermaLink="true">https://www.infini.cv/posts/scheme/scheme-125/</guid><description>learn sicp</description><pubDate>Wed, 22 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Lamé定理&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;如果欧几里得算法需要$k$步才能计算出一对整数的最大公约数，那么这对整数中较小的那个数必然大于或等于第$k$个斐波那契数$Fib(k)$.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;数学表达式为：&lt;br /&gt;
如果使用欧几里得算法求$GCD(a,b)$且 $a &amp;gt; b$,需要$k$步完成，则：&lt;br /&gt;
$$
b \geq Fib(k) \approx \frac {\phi^k}{\sqrt{5}}&lt;/p&gt;
&lt;p&gt;$$
最坏的情况下是去求**&lt;em&gt;左右相邻的斐波那契数&lt;/em&gt;**的最大公约数。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>scheme-1.2.3</title><link>https://www.infini.cv/posts/scheme/scheme-123/</link><guid isPermaLink="true">https://www.infini.cv/posts/scheme/scheme-123/</guid><description>learn</description><pubDate>Sat, 14 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;增长的阶&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;$O(1)$ 常数阶&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;不管$n$多大，需要的时间/空间都是固定的。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;$O(\log n)$ 对数阶&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;输入$n$每翻一倍，计算量只增加一个常量。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;$O(n)$ 线性阶&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;计算量和$n$同步增加。$n$扩大多少倍，计算量同步扩大多少倍。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;$O(n^2)$ 平方阶&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;$n$扩大10倍，计算量扩大100倍。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;$O(2^n)$ 指数阶&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;随着$n$的增加，计算量程指数级增长。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;时间和空间的阶&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;时间的阶(计算步数):&lt;/strong&gt; 程序总共执行了多少次操作。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;空间的阶(内存空间):&lt;/strong&gt; 程序在运行过程中，最高峰时需要记住多少个&quot;推迟执行的操作&quot;。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>scheme-lecture-1.2.3</title><link>https://www.infini.cv/posts/scheme/scheme-lecture-123/</link><guid isPermaLink="true">https://www.infini.cv/posts/scheme/scheme-lecture-123/</guid><description>learn</description><pubDate>Sat, 14 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;details&amp;gt;
&amp;lt;summary&amp;gt;1&amp;lt;/summary&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/details&amp;gt;&lt;/p&gt;
&lt;h1&gt;增长的阶&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;$O(1)$ 常数阶&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;不管$n$多大，需要的时间/空间都是固定的。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;$O(\log n)$ 对数阶&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;输入$n$每翻一倍，计算量只增加一个常量。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;$O(n)$ 线性阶&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;计算量和$n$同步增加。$n$扩大多少倍，计算量同步扩大多少倍。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;$O(n^2)$ 平方阶&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;$n$扩大10倍，计算量扩大100倍。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;$O(2^n)$ 指数阶&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;随着$n$的增加，计算量程指数级增长。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;时间和空间的阶&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;时间的阶(计算步数):&lt;/strong&gt; 程序总共执行了多少次操作。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;空间的阶(内存空间):&lt;/strong&gt; 程序在运行过程中，最高峰时需要记住多少个&quot;推迟执行的操作&quot;。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Smb-config</title><link>https://www.infini.cv/posts/smb-config/</link><guid isPermaLink="true">https://www.infini.cv/posts/smb-config/</guid><description>in linux configure smb service</description><pubDate>Thu, 29 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;install Samba&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;sudo apt update
sudo apt install samba samba-common-bin
sudo cp /etc/samba/samba.conf /etc/samba/samba.conf.backup # 备份默认的配置
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;create system user and Samba user&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;sudo useradd -s /usr/sbin/nologin sambauser # 添加samba user
sudo smbpasswd -a sambauser #为sambauser设置密码 pdbedit -L 查看Samba用户列表
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;create share directory and configure permission&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;sudo mkdir -p /samba/share/directory
sudo chown sambauser:sambauser /samba/share/directory
sudo chmod 2770 /samba/share/directory
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Configure smb&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;sudo vim /etc/samba/smb.conf

[share]
  comment = Share comment 
  path = /samba/share/directory
  browsable = yes
  read only = no
  valid users = sambauser
  force user = sambauser
  create mask = 0660
  directory mask = 2770
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Use&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;在windows端的&lt;code&gt;网络&lt;/code&gt;中的地址栏中输入&lt;code&gt;samba服务端ip地址\share&lt;/code&gt;访问samba服务。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Cloudflare-edge-certificate</title><link>https://www.infini.cv/posts/cloudflare-edge-certificate/</link><guid isPermaLink="true">https://www.infini.cv/posts/cloudflare-edge-certificate/</guid><description>Add a wildcard edge certificate for subdomains to a domain hosted on Cloudflare</description><pubDate>Fri, 09 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;:::important
2026年3月，在worker使用自定义域名时，
cloudflare会自动为该域名添加通配符证书。
而不用使用下面这种方法。
:::&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果您使用的是&lt;em&gt;&lt;strong&gt;Business&lt;/strong&gt;&lt;/em&gt;以上计划，或者有订阅&lt;em&gt;&lt;strong&gt;Advanced Certificate Manager&lt;/strong&gt;&lt;/em&gt;可以忽略以下内容。&lt;/li&gt;
&lt;li&gt;使用&lt;em&gt;&lt;strong&gt;Business&lt;/strong&gt;&lt;/em&gt;以下计划时，cloudflare不会给子域名添加通配符证书，如托管的是&lt;code&gt;example.com&lt;/code&gt;,它会自动申请&lt;code&gt;*.example.com&lt;/code&gt;和&lt;code&gt;example.com&lt;/code&gt;的边缘证书，但它不会申请&lt;code&gt;*a.example.com&lt;/code&gt;的边缘证书。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Actions&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;创建一个&lt;code&gt;workers&lt;/code&gt;应用,现有的也可以。&lt;/li&gt;
&lt;li&gt;创建&lt;code&gt;api token&lt;/code&gt;(可选)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;在登录cloudflare后点击右上角的人像，点击出现的&lt;code&gt;Profile&lt;/code&gt;选项，点击出现在右侧边栏的&lt;code&gt;API Token&lt;/code&gt;,点击出现蓝色的&lt;code&gt;Create Token&lt;/code&gt;按钮&lt;/li&gt;
&lt;li&gt;选择&lt;code&gt;Create Custom Token对应右边蓝色的按钮 Get start&lt;/code&gt;,再按如下图操作:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://img.infini.cv/file/cloudflare/1767958426246_api_token1.jpeg&quot; alt=&quot;api_token1.jpeg&quot; /&gt;&lt;br /&gt;
&lt;img src=&quot;https://img.infini.cv/file/cloudflare/1767958428655_api_token2.jpeg&quot; alt=&quot;api_token2.jpeg&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;把&lt;code&gt;api token&lt;/code&gt;复制出来，只会出现这一次。&lt;/li&gt;
&lt;li&gt;复制以下脚本，在任意安装了&lt;code&gt;curl&lt;/code&gt;能正常连接cloudflare的主机上执行:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash
ACCOUNT_ID=&quot;your_account_id&quot;   # 进入你的域名的详情页面，拉到最底会看到 zone ID和 account ID
ZONE_ID=&quot;your_zone_id&quot;         # 同上
API_TOKEN=&quot;your_api_token&quot;     # 刚创建的

WORKER_DOMAIN=&quot;*.a.domain.com&quot;   # 要申请通配符证书的子域名
WORKER_NAME=&quot;worker-name&quot;      # 任意一个存在的worker 

curl &quot;https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/workers/domains&quot; \
 -X PUT \
 -H &quot;Content-Type: application/json&quot; \
 -H &quot;Authorization: Bearer $API_TOKEN&quot; \
 -d &apos;{
       &quot;hostname&quot;: &quot;&apos;&quot;$WORKER_DOMAIN&quot;&apos;&quot;,
       &quot;service&quot;: &quot;&apos;&quot;$WORKER_NAME&quot;&apos;&quot;,
       &quot;zone_id&quot;: &quot;&apos;&quot;$ZONE_ID&quot;&apos;&quot;,
       &quot;environment&quot;: &quot;production&quot;
     }&apos; 

&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;将上面的脚本保存，并赋予执行权限。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;执行结果可以在&lt;code&gt;SSL/TLS&lt;/code&gt;下面的&lt;code&gt;Edge Certificates&lt;/code&gt;下面查看,并且会在当前域名下添加一条类型为&lt;code&gt;worker&lt;/code&gt;的记录，也可以在worker应用下查看。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;来自原作者&lt;code&gt;youtuber@闹海金蛟&lt;/code&gt;的&lt;a href=&quot;https://github.com/lukuichina/youtube/tree/main/2025/858&quot;&gt;脚本&lt;/a&gt;不须要创建&lt;code&gt;API Token&lt;/code&gt;:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash
ACCOUNT_ID=account id
ACCOUNT_EMAIL=email
ACCOUNT_KEY=Global API Key

WORKER_DOMAIN=*.domain.com
WORKER_NAME=worker name
ZONE_ID=zone id

curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/workers/domains \
    -X PUT \
    -H &apos;Content-Type: application/json&apos; \
    -H &quot;X-Auth-Email: $ACCOUNT_EMAIL&quot; \
    -H &quot;X-Auth-Key: $ACCOUNT_KEY&quot; \
    -d &apos;{
          &quot;hostname&quot;: &quot;&apos;$WORKER_DOMAIN&apos;&quot;,
          &quot;service&quot;: &quot;&apos;$WORKER_NAME&apos;&quot;,
          &quot;zone_id&quot;: &quot;&apos;$ZONE_ID&apos;&quot;,
          &quot;environment&quot;: &quot;production&quot;
        }&apos; &amp;gt; cert.log
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Effect&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;使用&lt;code&gt;cloudflare tunnel&lt;/code&gt;时，会很有用&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Arch-Linux-Install</title><link>https://www.infini.cv/posts/arch-linux-install/</link><guid isPermaLink="true">https://www.infini.cv/posts/arch-linux-install/</guid><description>arch install</description><pubDate>Fri, 02 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Archlinux Install&lt;/h1&gt;
&lt;h2&gt;作安装镜像&lt;/h2&gt;
&lt;p&gt;:::warning
&lt;strong&gt;&lt;em&gt;制作安装盘之前，提前做好备份!!!&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;&lt;em&gt;制作安装盘会格式化整个盘!!!&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;
:::&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;下载Archlinux镜像，从&lt;a href=&quot;https://archlinux.org/download/&quot;&gt;这里&lt;/a&gt;选择一个离你较近的镜像站点,下载一个&lt;code&gt;.iso&lt;/code&gt;结尾的文件。&lt;/li&gt;
&lt;li&gt;刻录安装镜像
&lt;ul&gt;
&lt;li&gt;Windows环境下可以使用&lt;a href=&quot;https://www.ventoy.net/cn/doc_start.html&quot;&gt;Ventoy&lt;/a&gt;、&lt;a href=&quot;https://rufus.ie&quot;&gt;Rufs&lt;/a&gt;进行记录。&lt;/li&gt;
&lt;li&gt;Linux环境下同样可以使用上面的两个软件，或者直接用&lt;code&gt;dd&lt;/code&gt;命令进行刻录.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo dd if=Archlinux镜像位置 + 它的名字 of=你的安装盘 status=progress oflag=sync bs=4M
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;启动安装镜像&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;插入你的安装盘,选择从它启动安装镜像&lt;/li&gt;
&lt;li&gt;选择从UEFI模式启动&lt;/li&gt;
&lt;li&gt;确保关闭了**&lt;em&gt;安全启动(Secure Boot)&lt;/em&gt;**。Arch Linux 安装镜像不支持安全启动。&lt;/li&gt;
&lt;li&gt;进入终端后，验证启动模式量否为UEFI模式:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;cat /sys/firmware/efi/fw_platform_size
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;如果返回&lt;code&gt;64&lt;/code&gt;,以64位 x64 UEFI启动。&lt;/li&gt;
&lt;li&gt;如果返回&lt;code&gt;32&lt;/code&gt;,以32位 IA32 UEFI启动。&lt;/li&gt;
&lt;li&gt;如果返回&lt;code&gt;No such file or directory&lt;/code&gt;,这可能是&lt;strong&gt;BIOS&lt;/strong&gt;或者&lt;strong&gt;CSM&lt;/strong&gt;启动模式，需要更改主板设置。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;连接网络&lt;/h2&gt;
&lt;p&gt;:::note
安装Archlinux,需要连接网络。
:::
确保网卡已一正常列出和启用。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ip link #显示当前的网卡及状态
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;无线网络设置&lt;/h3&gt;
&lt;p&gt;:::note
使用无线网络前,先把要连接的无线网络名称设置为英文。&lt;br /&gt;
:::
使用&lt;code&gt;iwctl&lt;/code&gt;进行连接&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;iwctl # 进入交互式命令行  
device list # 列出无线网卡设备名,一般是wlan0  
station wlan0 connet wifi-name # 按`Enter`确认输入密码  
exit #退出
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;使用有线网络&lt;/h3&gt;
&lt;p&gt;一般来说，正确的插入网线就可以连接上网络,可以使用&lt;code&gt;ip address show&lt;/code&gt;命令查看&lt;/p&gt;
&lt;h3&gt;测试网络&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;ping qq.com -c 4 # 回车后，看到有数据返回，说明网络连接正常。若没有数据返回，检查前面是哪个步骤没有正确操作。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;更新系统时钟&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;timedatectl set-ntp true  # 将系统时间和网络时间同步
timedatectl status  # 检查服务状态
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;更新软件仓库镜像源&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;使用文本编辑器修改&lt;code&gt;/etc/pacman.d/mirrorlist&lt;/code&gt;文件换成国内的软件仓库镜像源。&lt;/li&gt;
&lt;li&gt;使用reflector修改。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;reflector --latest 10 --country China --age 12 --protocol https --sort rate --save /etc/pacman.d/mirrorlist
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;同步软件源&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;pacman -Syu # 同步非本地软件仓库并升级系统的软件包。  
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::tip&lt;br /&gt;
网络连接成功后，可以用另一台设备&lt;code&gt;ssh&lt;/code&gt;远程连接要安装Archlinux的电脑。确保是同一局域网内的设备。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pacman -S openssh # 安装openssh
systemctl start sshd # 启动ssh服务
passwd # 设置root用户密码
ssh root@ip address # 在另一台设备上连接,Enter后输入root密码。  
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;h2&gt;分区和格式化&lt;/h2&gt;
&lt;p&gt;:::warning
&lt;strong&gt;&lt;em&gt;分区操作的部分命令具有危险性!!!&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;&lt;em&gt;在执行命令之前，做好数据备份!!!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;h3&gt;分区&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;使用&lt;code&gt;lsblk&lt;/code&gt;命令查看当前磁盘分区的情况。选择你要安装Archlinux的硬盘。&lt;br /&gt;
:::tip
硬盘是IDE类型，显示为hdax&lt;br /&gt;
硬盘是stat类型，显示为sdax&lt;br /&gt;
硬盘是nvme类型，显示为nvmexnxpx&lt;br /&gt;
根据实际情况来选择&lt;br /&gt;
:::&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;使用&lt;code&gt;fdisk&lt;/code&gt;命令对磁盘进行分区:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;fdisk /dev/nvme0n1 # 对安装Archlinux的磁盘分区
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://img.infini.cv/file/arch_install_picture/1767353162605_fdisk1.png&quot; alt=&quot;fdisk1.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;进入fdisk工具后，会看到如上图所示的界面。可以通过&lt;code&gt;m&lt;/code&gt;获取帮助。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;创建分区&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;输入&lt;code&gt;g&lt;/code&gt;创建一个新的GPT分区表
&lt;img src=&quot;https://img.infini.cv/file/arch_install_picture/1767353160473_fdisk-g.png&quot; alt=&quot;fdisk-g.png&quot; /&gt;&lt;/li&gt;
&lt;li&gt;创建**&lt;em&gt;EFI&lt;/em&gt;**分区。&lt;br /&gt;
输入&lt;code&gt;n&lt;/code&gt;按下&lt;code&gt;Enter&lt;/code&gt;。选择分区数字&lt;code&gt;1&lt;/code&gt;按&lt;code&gt;Enter&lt;/code&gt;。选择起始块，默认即可按&lt;code&gt;Enter&lt;/code&gt;。输入分区大小&lt;code&gt;+1g&lt;/code&gt;,按&lt;code&gt;Enter&lt;/code&gt;。&lt;br /&gt;
&lt;strong&gt;&lt;em&gt;更改EFI分区类型&lt;/em&gt;&lt;/strong&gt;。&lt;br /&gt;
输入&lt;code&gt;t&lt;/code&gt;按&lt;code&gt;Enter&lt;/code&gt;,输入&lt;code&gt;uefi&lt;/code&gt;按&lt;code&gt;Enter&lt;/code&gt;。&lt;br /&gt;
&lt;img src=&quot;https://img.infini.cv/file/arch_install_picture/1767353160124_fdisk-nu.png&quot; alt=&quot;fdisk-nu.png&quot; /&gt;&lt;/li&gt;
&lt;li&gt;创建**&lt;em&gt;Swap&lt;/em&gt;**分区。&lt;br /&gt;
输入&lt;code&gt;n&lt;/code&gt;按&lt;code&gt;Enter&lt;/code&gt;。选择分区，默认即可，按&lt;code&gt;Enter&lt;/code&gt;。选择起始块，默认即可，按&lt;code&gt;Enter&lt;/code&gt;。输入分区大小&lt;code&gt;+2g&lt;/code&gt;(按实际情况) &lt;a href=&quot;%E5%86%85%E5%AD%98%E5%AE%B9%E9%87%8F%E5%A4%A7:Swap%E5%88%86%E5%8C%BA%E8%AE%BE%E7%BD%AE%E4%B8%BA%E4%B8%8E%E5%86%85%E5%AD%98%E5%AE%B9%E9%87%8F%E7%9B%B8%E7%AD%89%E6%88%96%E4%B8%80%E5%8D%8A%E3%80%82&quot;&gt;^1&lt;/a&gt;&lt;br /&gt;
更改Swap分区类型。&lt;br /&gt;
输入&lt;code&gt;t&lt;/code&gt;,按&lt;code&gt;Enter&lt;/code&gt;。输入&lt;code&gt;2&lt;/code&gt;,按&lt;code&gt;Enter&lt;/code&gt;。输入&lt;code&gt;swap&lt;/code&gt;,按&lt;code&gt;Enter&lt;/code&gt;。&lt;br /&gt;
&lt;img src=&quot;https://img.infini.cv/file/arch_install_picture/1767353166509_fdisk-ns.png&quot; alt=&quot;fdisk-ns.png&quot; /&gt;&lt;/li&gt;
&lt;li&gt;创建**&lt;em&gt;根分区&lt;/em&gt;**。&lt;br /&gt;
输入&lt;code&gt;n&lt;/code&gt;,按&lt;code&gt;Enter&lt;/code&gt;。选择分区数字，默认即可按&lt;code&gt;Enter&lt;/code&gt;。选择起始块，默认即可按&lt;code&gt;Enter&lt;/code&gt;。输入分区大小,可以直接选择剩余所有的空间，按&lt;code&gt;Enter&lt;/code&gt;&lt;br /&gt;
分区类型不用更改。&lt;/li&gt;
&lt;li&gt;输入&lt;code&gt;p&lt;/code&gt;查看分区，是否设置正确，检查无误后输入&lt;code&gt;w&lt;/code&gt;，保存并退出。
&lt;img src=&quot;https://img.infini.cv/file/arch_install_picture/1767353165900_fdisk-p.png&quot; alt=&quot;fdisk-p.png&quot; /&gt;&lt;br /&gt;
&lt;img src=&quot;https://img.infini.cv/file/arch_install_picture/1767353165464_fdisk-w.png&quot; alt=&quot;fdisk-w.png&quot; /&gt;&lt;br /&gt;
:::warning
:boom::boom:&lt;strong&gt;&lt;em&gt;!!!再次提醒!!!&lt;/em&gt;&lt;/strong&gt;:boom::boom:&lt;br /&gt;
仔细检查命令和操作的正确性！否则将出现不可预料的情况！&lt;br /&gt;
:::&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;格式化分区&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;输入&lt;code&gt;lsblk&lt;/code&gt;查看分区情况
&lt;img src=&quot;https://img.infini.cv/file/arch_install_picture/1767353170991_lsblk1.png&quot; alt=&quot;lsblk1.png&quot; /&gt;&lt;/li&gt;
&lt;li&gt;格式化EFI分区&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mkfs.fat -F 32 /dev/nvme0n1p1 # 根据自己的设备输入对应的设备名
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;格式化Swap分区&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mkswap /dev/nvme0n1p2 
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;格式化 Btrfs 分区&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mkfs.btrfs -L myarch /dev/nvme0n1p3 # -L 指定一个Lable
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;格式化&lt;code&gt;Btrfs&lt;/code&gt;子卷&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;将&lt;code&gt;Btrfs&lt;/code&gt;分区挂载到&lt;code&gt;/mnt&lt;/code&gt;下:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;mount -t btrfs -o compress=zstd /dev/nvme0n1p3  /mnt  
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;创建&lt;code&gt;Btrfs&lt;/code&gt;子卷&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;btrfs subvolume create /mnt/@  # 创建 / 目录子卷  
btrfs subvolume create /mnt/@home # 创建 /home 目录子卷  
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;查看子卷情况&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;btrfs subvolume list -p /mnt
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;卸载btrfs分区来挂载子卷&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;umount /mnt  
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;挂载&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;挂载时，从根目录开始挂载。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mount -t btrfs -o subvol=/@,compress=zstd /dev/nvme0n1p3 /mnt #  挂载/目录  
mkdir -p /mnt/{home,boot} # 创建/home目录和/boot目录
mount -t btrfs -o subvol=/@home,compress=zstd /dev/nvme0n1p3 /mnt/home # 挂载/home目录  
mount /dev/nvme0n1p1 /mnt/boot # 挂载/boot目录
swapon /dev/nvme0n1p2 # 开启swap分区
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;使用&lt;code&gt;lsblk&lt;/code&gt;或&lt;code&gt;df -h&lt;/code&gt;查看挂载情况&lt;br /&gt;
&lt;img src=&quot;https://img.infini.cv/file/arch_install_picture/1767353164703_gzcg1.png&quot; alt=&quot;gzcg1.png&quot; /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;配置系统&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;通过&lt;code&gt;pacstrap&lt;/code&gt;安装:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;pacstrap -K /mnt base  base-devel linux linux-firmware btrfs-progs bash-completion vim  # 可以把vim替换成你喜欢的文本编辑器
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;经过一系列的刷屏后......&lt;br /&gt;
&lt;img src=&quot;https://img.infini.cv/file/arch_install_picture/1767353165539_cgaz1.png&quot; alt=&quot;cgaz1.png&quot; /&gt;&lt;br /&gt;
2. 生成fstab文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;genfstab -U /mnt &amp;gt; /mnt/etc/fstab
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;Chroot&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;arch-chroot /mnt 
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;在&lt;code&gt;/etc/hostname&lt;/code&gt;下设置主机名:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;myarch1&quot; &amp;gt; /etc/hostname
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;编辑&lt;code&gt;/etc/hosts&lt;/code&gt;文件&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;vim /etc/hosts
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;添加以下内容:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1 localhost
::1       localhost
127.0.1.1 myarch1.localdomain myarch1
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;设置Locale&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;编辑&lt;code&gt;/etc/locale.gen&lt;/code&gt;文件,去掉&lt;code&gt;en_US&amp;gt;UTF-8&lt;/code&gt;,&lt;code&gt;zh_CN.UTF-8&lt;/code&gt;前面的注释符号。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;vim /etc/locale.gen
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;使用&lt;code&gt;locale-gen&lt;/code&gt;生成locale。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;locale-gen
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;向&lt;code&gt;/etc/locale.conf&lt;/code&gt;写入。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;echo &apos;LANG_=en_US.UTF-8&apos; &amp;gt; /etc/locale.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;设置时区&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;设置硬件时间&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;hwclock --systohc
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;设置root用户密码&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;passwd    # Enter后,输入密码
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;设置引导&lt;/h2&gt;
&lt;h3&gt;使用grub&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;安装相应的包&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;pacman -S grub efibootmgr
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;安装grub到EFI分区&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=Arch
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;生成grub的配置文件&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;grub-mkconfig -o /boot/grub/grub.cfg
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;使用Systemd-boot&lt;/h3&gt;
&lt;p&gt;:::note[:memo:]
要使用systemd-boot,首先要确保启动方式是UEFI模式！
:::&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;安装UEFI启动管理器&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;bootctl install # 将systemd-boot安装到ESP  
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::tip[提示]
esp指你的启动分区，/boot/efi或者/efi&lt;br /&gt;
取决于自己的设置
:::
2. 配置systemd-boot&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;编辑&lt;code&gt;/esp/loader/loader.conf&lt;/code&gt;文件:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;default arch.conf # 默认启动项  
timeout 3 
console-mode auto
editor no
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;创建启动项
:::note[vim /esp/loader/entries/arch.conf]&lt;br /&gt;
title     Arch Linux   # 启动时的名称&lt;br /&gt;
linux     /vmlinuz-linux  #&lt;br /&gt;
initrd    /initramfs-linux.img   #&lt;br /&gt;
initrd    /intel-ucode.img   # 或者amd-ucode.img # 有装微码包可以写上&lt;br /&gt;
options   root=UUID=&amp;lt;根分区的UUID&amp;gt; rw rootflags=subvol=@   #用Btrfs需要指定@子卷&lt;br /&gt;
#UUID可以用blkid查看 &lt;code&gt;blkid /dev/nvme0n1p3&lt;/code&gt;&lt;br /&gt;
:::&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;更新&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;bootctl --noo-variables --graceful update   

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或者:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl enable systemd-boot-update.service
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;使用 rEFInd&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;安装refind包&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;pacman -S refind
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;安装到esp分区&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;refind-install
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;配置rEFInd&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;修改refind_linux.conf文件&lt;br /&gt;
:::tip[:memo:]
将root=UUID=&amp;lt;根分区的UUID&amp;gt; # btrfs需要加上 rootflags=subvol=@
&lt;img src=&quot;https://img.infini.cv/file/arch_install_picture/1767353163382_refind2.png&quot; alt=&quot;refind2.png&quot; /&gt;&lt;br /&gt;
:::&lt;/li&gt;
&lt;li&gt;修改refind.conf(可选)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;vim /esp/EFI/refind/refind.conf  #路径可能所有不同
#找到 `memuentry &quot;Arch Linux&quot;  这一项,修改options参数  
将root=UUID=&amp;lt;根分区的UUID&amp;gt; # btrfs加上 rootflags=subvol=@
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://img.infini.cv/file/arch_install_picture/1767353171791_refind1.png&quot; alt=&quot;refind1&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;网络设置&lt;/h2&gt;
&lt;h3&gt;使用NetworkManager&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;pacman -S networkmanager  # 下载networkmanager
systemctl enable NetworkManager #启动networkmanager
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;使用systemd-networkd + iwd&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;pacman -S iwd  
systemctl enable iwd
systemctl enable systemd-networkd
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Reboot&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;回到 live 环境&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;exit # 退出安装环境
umount -R /mnt #卸载分区
reboot # 重启
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;内存容量小:Swap分区设置为与内存容量的2倍。&lt;/p&gt;
</content:encoded></item><item><title>scheme(2)</title><link>https://www.infini.cv/posts/scheme/scheme2/</link><guid isPermaLink="true">https://www.infini.cv/posts/scheme/scheme2/</guid><description>learn</description><pubDate>Wed, 19 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;1.2 过程及其产生的计算&lt;/h1&gt;
&lt;h2&gt;1.21 线性的递归和迭代&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;普通递归：递归调用前面还有过程需要逐层计算。每一层都要等里面的结果出来，再计算。　　&lt;/li&gt;
&lt;li&gt;尾递归：递归调用是最后一次，最终的结果就是最后一次返回。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;1.2.2 树形递归&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Scheme(1.1)</title><link>https://www.infini.cv/posts/scheme/scheme1/</link><guid isPermaLink="true">https://www.infini.cv/posts/scheme/scheme1/</guid><description>scheme</description><pubDate>Wed, 12 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;构造过程抽象&lt;/h1&gt;
&lt;h2&gt;1.1程序设计的基本元素&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;基本表达形式&lt;/em&gt;&lt;/strong&gt;,用于表示语言所关心的最简单的个体。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;组合的方法&lt;/em&gt;&lt;/strong&gt;,通过它们可以从较简单的东西出发构造出复合的元素。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;抽象的方法&lt;/em&gt;&lt;/strong&gt;,通过它们可以为复合对象命名，并将它们当作单元去操作。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1.1.1 表达式&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;(+ 3 2)
(- 100 7 22)
(/ 30 3 (+ 2 3))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;像上面这样的表达式称为&lt;strong&gt;组合式&lt;/strong&gt;,用一对括号括起一些表达式，形成一个表，表示一个过程应用。在表里最左的元素称为运算符，其他元素都称为运算对象。&lt;/p&gt;
&lt;h3&gt;1.1.2 命名和环境&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;(define size 3)
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;为&lt;code&gt;size&lt;/code&gt;关联一个值&lt;code&gt;3&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1.1.3 组合式的求值规则&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;对组合式的各个表达式求值。&lt;/li&gt;
&lt;li&gt;其他表达式的值，将作为最左子表达式的值的那个过程应用于相应的实际参数。&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;最左边的子表达式的&lt;code&gt;值&lt;/code&gt;,必须是一个过程。&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;最左边的子表达式的&lt;code&gt;值&lt;/code&gt;,必须是一个过程。&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;最左边的子表达式的&lt;code&gt;值&lt;/code&gt;,必须是一个过程。&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以上为通用求值规则，除此之外还有针对特殊形式的专门规则。如&lt;code&gt;(define x 1)&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;复合过程&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;过程(procedure)定义的一般形式:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;(define (&amp;lt;name&amp;gt; &amp;lt;formal parameters&amp;gt;) &amp;lt;body&amp;gt;)
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;name&amp;gt;&lt;/code&gt;是一个符号，过程定义将在环境中关联于这个符号，为过程定义命名。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;formal parameters&amp;gt;&lt;/code&gt;形式参数。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt;一个表达式。在应用这一过程时，这一表达式中的形式参数，将用与之对应的实际参数取代，对这样取代后的表达式求值，产生出这个过程应用的值。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;(define (square x)
  (* x x))
;;调用过程
(square 3)
(square (square (+ 2 3)))
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;过程应用的代换模型&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;代换的作用只是为了帮助我们领会过程调用中的情况，而不是对解释器实际工作方式的具体描述。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;应用序和正则序&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;应用序求值&lt;/em&gt;&lt;/strong&gt;:先求值参数而后应用(把所有参数表达式都求值，再把结果带入过程)可能会产生无限循环&lt;br /&gt;
&lt;strong&gt;&lt;em&gt;正则序求值&lt;/em&gt;&lt;/strong&gt;:完全展开而后规约(先把参数表达式原样代入过程，等到真正需要时才求值)。&lt;/p&gt;
&lt;h3&gt;条件表达式(Conditional Expression)和谓词(predicate)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;(cond)条件表达式的一般形式为:&lt;br /&gt;
$$
\begin{aligned}
(cond  (&amp;lt;p_1&amp;gt; &amp;lt;e_1&amp;gt;) \
\quad \quad \kern 3pt(&amp;lt;p_2&amp;gt; &amp;lt;e_2&amp;gt;) \
. \
. \
. \
\quad \quad \kern 9pt( (&amp;lt;p_n&amp;gt; &amp;lt;e_n&amp;gt;))
\end{aligned}
$$
条件表达式的求值: 首先求值谓词&amp;lt;p1&amp;gt;,如果它的值是&lt;code&gt;false&lt;/code&gt;，那么就求值&amp;lt;p2&amp;gt;,如果它的值也是&lt;code&gt;false&lt;/code&gt;,就去求值&amp;lt;p3&amp;gt;。这一过程将继续下去，直到发现了某个谓词的值为&lt;code&gt;true&lt;/code&gt;为止。此时解释器就返回相应子句中的序列表达式&amp;lt;en&amp;gt;的值，以这个值做为**&lt;em&gt;整个条件表达式的值&lt;/em&gt;**。如果无法找到值为真的&lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt;,&lt;code&gt;cond的值&lt;/code&gt;就没有定义。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;(cond)的另一种形式&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;(cond 
  .
  .
  .
  (else &amp;lt;e&amp;gt;))
;;如果前面的所有子句都被跳过，会返回最后(else)中&amp;lt;e&amp;gt;的值。  
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;(if)表达式&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;(if &amp;lt;predicate&amp;gt; &amp;lt;consequent&amp;gt;
  &amp;lt;alternative&amp;gt;)
  ;;从&amp;lt;predicate&amp;gt;开始求值，如果&amp;lt;predicate&amp;gt;得到真值，解释器就去求值&amp;lt;consequent&amp;gt;并返回其值，否则它就去求值&amp;lt;alternative&amp;gt;并返回其值。
  
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;$(and &amp;lt;e_1&amp;gt; \ldots &amp;lt;e_n&amp;gt;)$ 解释器将从左到右一个个求值&lt;code&gt;&amp;lt;e&amp;gt;&lt;/code&gt;,如果某个&lt;code&gt;&amp;lt;e&amp;gt;&lt;/code&gt;求值为假，这一(and)表达式都为假，后面的&lt;code&gt;&amp;lt;e&amp;gt;&lt;/code&gt;也不再求值。如果所有的&lt;code&gt;&amp;lt;e&amp;gt;&lt;/code&gt;都求出为真值，最后一个&lt;code&gt;&amp;lt;e&amp;gt;&lt;/code&gt;的值为这一(and)表达式的值。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;$(or &amp;lt;e_1&amp;gt;\dots &amp;lt;e_n&amp;gt;)$ 解释器将从左到右一个个求值&lt;code&gt;&amp;lt;e&amp;gt;&lt;/code&gt;,如果某个&lt;code&gt;&amp;lt;e&amp;gt;&lt;/code&gt;求值为真，这一(or)表达式都为真，后面的&lt;code&gt;&amp;lt;e&amp;gt;&lt;/code&gt;也不再求值。如果所有的&lt;code&gt;&amp;lt;e&amp;gt;&lt;/code&gt;都求出为假，这一(or)表达式的值为假。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;(not &amp;lt;e&amp;gt;)&lt;/code&gt;
如果&lt;code&gt;&amp;lt;e&amp;gt;&lt;/code&gt;求出的值是假，(not)表达式的值为真，否则其值为假。&lt;br /&gt;
(not)表达式是一个普通过程。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1.1.8 过程作为黑箱抽象&lt;/h3&gt;
&lt;p&gt;局部名
约束变量: 形式参数&lt;br /&gt;
自由变量: 外部环境所定义的变量&lt;/p&gt;
&lt;p&gt;过程调用时的参数是&lt;em&gt;值传递&lt;/em&gt;。&lt;br /&gt;
表达式求值，它会用当前作用域的参数的值算出一个新的结果，不会改变参数的值。如&lt;code&gt;(- x 1)&lt;/code&gt;。&lt;br /&gt;
每次调用都会为参数创建新的绑定。&lt;br /&gt;
在同一层调用的作用域里参数的值是固定的，不会在这一层改变。&lt;/p&gt;
</content:encoded></item><item><title>CA</title><link>https://www.infini.cv/posts/ca/</link><guid isPermaLink="true">https://www.infini.cv/posts/ca/</guid><description>creat a self-singled certificate</description><pubDate>Wed, 05 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;快速生成自签证书&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;openssl req -x509 \
  -newkey rsa:2048 \
  -keyout /etc/nginx/ssl/service.lan.key \
  -out /etc/nginx/ssl/service.lan.crt \
  -days 365 \
  -nodes \
  -subj &quot;/C=CN/ST=ShangHai/L=Shanghai/O=Myhomw/OU=Myhome/CN=*.service.lan&quot; \
  -addext &quot;subjectAltName = DNS:*.service.lan,DNS:service.lan
  # req -x509 创建一个自签名的X.509证书
  # -nodes 私钥文件不加密
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;创建本地CA并签发证书&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;创建目录&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;sudo mkdir -p /etc/nginx/ssl/service.lan
cd /etc/nginx/ssl/service.lan
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;创建本地CA&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;生成CA私钥&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo openssl genrsa -out ca.key 4096
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;生成CA根证书&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo openssl req -x509 -new -nodes -key ca.key -days 3650 -out ca.crt \
-subj &quot;/C=CN/ST=ShangHai/L=Shanghai/O=LocalCA/OU=Dev/CN=Local Root CA&quot; 
# ca.crt是要导入到浏览器的根证书
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;为域名生成证书请求(CSR)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;生成服务私钥&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo openssl genrsa -out service.lan.key 2048 
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;创建一个service.lan.conf,指定SAN&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;[req] 
default_bits    = 2048
prompt          = no
default_md      = sha256
req_extensions  = req_ext
distinguished_name = dn

[dn] 
C=CN
ST=Shanghai
L=Shanghai
O=Myhome
OU=Myhome 
CN=app.service.lan

[req_ext] 
subjectAltName = @alt_name

[alt_name]
DNS.1 = app.service.lan
DNS.2 = *.service.lan
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;生成CSR&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo openssl req -new -key service.lan.key -out service.lan.csr -config service.lan.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;用CA签发证书&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;sudo openssl x509 -req -in service.lan.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-out service.lan.crt -days 3650 -sha256 -extensions req_ext -extfile service.lan.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;导入证书&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;将证书下载到主机上，用浏览器导入后重启打开网站就不会显示**&lt;em&gt;不安全&lt;/em&gt;**。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>dnsmasq</title><link>https://www.infini.cv/posts/dnsmasq/</link><guid isPermaLink="true">https://www.infini.cv/posts/dnsmasq/</guid><description>accessing via domain name on a LAN</description><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;设备变多了用ip地址来管理很难记住是用来做什么的。用域名来管理就很直观，好记。&lt;/li&gt;
&lt;li&gt;设备少的话可以直接在路由器或者相关主机的&lt;code&gt;hosts&lt;/code&gt;文件上直接加入更加方便。&lt;/li&gt;
&lt;li&gt;在&lt;code&gt;openwrt&lt;/code&gt;上通过配置&lt;code&gt;dnsmasq&lt;/code&gt;来实现。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Install&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;dnsmasq&lt;/code&gt;一般在&lt;code&gt;openwrt&lt;/code&gt;系统上有自带可以直接使用。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Config&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;启用自定义配置目录&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;vi /etc/config/dhcp  
# 在dnsmasq选项下加入
 list confdir &apos;/etc/dnsmasq.d&apos;
 option cachesize &apos;1000&apos;

&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;确保公网访问正常&lt;br /&gt;
编辑&lt;code&gt;/etc/config/network&lt;/code&gt;文件&lt;pre&gt;&lt;code&gt;  在&apos;wan&apos;选项下加入
  list dns &apos;223.5.5.5&apos;
  list dns &apos;1.1.1.1&apos;
  option peerdns &apos;0&apos;  # 禁止使用ISP下发的DNS
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;配置&lt;code&gt;/etc/dnsmasq.d/local.conf&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;mkdir /etc/dnsmasq.d/
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;vi /etc/dnsmasq.d/local.conf

# 正向解析
address=/.myapp.lan/192.168.22.3  # 尽量不要使用公网已有的顶级域名，比如.com, .net, .org这些域名
                                  # 在局域网中一般可以使用 .lan, .home.arpa, .local, .internal, .intra
                                  # 如果一个ip上有多个服务，推荐在域名前面加上一个 (.)点 
# 反向解析  
ptr-record=3.22.168.192.in-addr.arpa,myapp.lan

#如果正向和反向都一致
host-record=myapp.lan,192.168.22.3 # 会同时生成A记录和PTR记录
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;重启&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;/etc/init.d/dnsmasq restart 
/etc/inid.d/network restart

&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Test&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;nslookup myapp.lan  # 如果正常解析，就可以用域名来访问  
# 也可以直接 ping myapp.lan
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Finaly&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;dnsmasq&lt;/code&gt;在&lt;code&gt;openwrt&lt;/code&gt;上配置的方法有很多种，这只是其中一例。&lt;/li&gt;
&lt;li&gt;主机的ip地址建议设置为静态ip地址。&lt;/li&gt;
&lt;li&gt;使用的时候要确保主机的DNS指向的是配置了&lt;code&gt;dnsmasq&lt;/code&gt;的，否则会跑到公网去。&lt;/li&gt;
&lt;li&gt;第一次用浏览器访问要使用**&lt;em&gt;完整的URL&lt;/em&gt;**,否则也会跑到公网上去。&lt;/li&gt;
&lt;li&gt;使用使用代理的情况下在代理规则里排除内网域名。&lt;/li&gt;
&lt;li&gt;还是不能访问可以清除系统和浏览器的缓存。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Arch-btrfs</title><link>https://www.infini.cv/posts/arch-btrfs/</link><guid isPermaLink="true">https://www.infini.cv/posts/arch-btrfs/</guid><description>using btrfs in arch </description><pubDate>Mon, 20 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;买了两块&lt;code&gt;optane m10 16G&lt;/code&gt; 当做普通硬盘使用&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;分区&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;在第一块硬盘分区一个&lt;code&gt;/boot&lt;/code&gt;分区和一个&lt;code&gt;/swap&lt;/code&gt;分区,剩余的全部做btrfs分区。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;fdisk /dev/nvme0n1 # 分三个分区

mkfs.fat -F 32 /dev/nvme0n1p1 
mkswapon /dev/nvme0n1p2
swapon /dev/nvme0n1p2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2.将第一块硬盘剩余的空间与第二块硬盘合成一个btrfs卷(第二块硬盘可以分区也可以不分)。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
mkfs.btrfs -L archbtrfs -d raid0 -m raid1 /dev/nvme0n1p3 /dev/nvm1n1
# 使用systemd-boot引导时，用archbtfs的UUID
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;创建子卷&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mount /dev/nvme1n1 # 无论哪部分挂载，整个archbtrfs都会挂载上去，或者直接用标签挂载

btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@var
btrfs subvolume create /mnt/@snapshots
btrfs subvolume create /mnt/@log
btrfs subvolume create /mnt/@cache
btrfs subvolume create /mnt/@tmp
btrfs subvolume create /mnt/@docker
umount /mnt
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;挂载子卷&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mount -t btrfs -o subvol=@,compress=zstd,noatime /dev/nvme1n1 /mnt
mkdir -p /mnt/{home,var,.snapshots,var/log,var/cache,var/tmp,var/lib/docker} # 使用命令后查看一下目录是否创建成功
mount -t btrfs -o subvol=@home,compress=zstd,noatime /dev/nvme1n1 /mnt/home
mount -t btrfs -o subvol=@var,compress=zstd,noatime /dev/nvme1n1 /mnt/var
mount -t btrfs -o subvol=@snapshots,compress=zstd,noatime /dev/nvme1n1 /mnt/.snapshots
mount -t btrfs -o subvol=@log,compress=zstd,noatime,compress=zstd /dev/nvm1n1 /mnt/var/log
mount -t btrfs -o subvol=@cache,compress=zstd,noatime,compress=zstd /dev/nvm1n1 /mnt/var/cache
mount -t btrfs -o subvol=@tmp,compress=zstd,noatime,compress=zstd /dev/nvm1n1 /mnt/var/tmp
mount -t btrfs -o subvol=@docker,nodatacow,noatime /dev/nvme1n1 /mnt/var/lib/docker
mount /dev/nmve0n1p1 /mnt/boot

chattr +C /mnt/var/log
chattr +C /mnt/var/cache
chattr +C /mnt/var/tmp
# 禁用这三个目录的cow
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Finally&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;装完系统后发现，主机散热很垃圾。&lt;code&gt;M10&lt;/code&gt;的温度在60度上下。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>nftables-1</title><link>https://www.infini.cv/posts/nftable/nftables-1/</link><guid isPermaLink="true">https://www.infini.cv/posts/nftable/nftables-1/</guid><description>exercises</description><pubDate>Sat, 18 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;nftables statements&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;1. 裁决类 (Verdict statements)

accept 放行数据包。

nft add rule inet filter input tcp dport 22 accept
drop 丢弃数据包，不回应。

nft add rule inet filter input tcp dport 23 drop
reject [with ...] 拒绝并返回 ICMP/ICMPv6/TCP RST 等响应。

nft add rule inet filter input tcp dport 80 reject with tcp reset
jump &amp;lt;chain&amp;gt; 跳转到用户自定义链，执行完继续返回。

goto &amp;lt;chain&amp;gt; 跳转到链后不返回。

return 从当前链返回上一级。

2. 控制/修改类
queue 把包交给用户空间的 NFQUEUE 程序处理。

set &amp;lt;meta/mark&amp;gt; 修改包的元数据，比如打标记：

nft add rule inet filter output ip daddr 8.8.8.8 meta mark set 1
dup / fwd 复制或转发包到其他接口。

snat / dnat / masquerade / redirect NAT 动作：

snat：源地址转换

dnat：目的地址转换

masquerade：源地址伪装（常用于动态 IP 出口）

redirect：重定向到本机端口

3. 记录/统计类
counter 统计匹配到的包和字节数。

nft add rule inet filter input tcp dport 22 counter
log 把匹配的包记录到内核日志。

nft add rule inet filter input tcp dport 22 log prefix &quot;SSH attempt: &quot;
limit 限速匹配，用于防止日志风暴或 DoS。

nft add rule inet filter input icmp type echo-request limit rate 10/second accept
4. 连接跟踪/状态类
ct state 匹配连接状态（new, established, related, invalid）。

nft add rule inet filter input ct state established accept
ct mark / ct zone 设置或匹配连接跟踪的标记/区域。

5. 其他动作
meter 定义一个计量器，用于限速或统计。

flowtable 用于硬件加速转发。

map / set / verdict map 高级用法，可以根据集合映射到不同动作。

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;nftables 簇、表、动作&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;family&lt;/th&gt;
&lt;th&gt;table&lt;/th&gt;
&lt;th&gt;hook&lt;/th&gt;
&lt;th&gt;statements&lt;/th&gt;
&lt;th&gt;instruction&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ip&lt;/code&gt; &lt;code&gt;ip6&lt;/code&gt; &lt;code&gt;inet&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;filter&lt;/td&gt;
&lt;td&gt;&lt;code&gt;input&lt;/code&gt; &lt;code&gt;forward&lt;/code&gt; &lt;code&gt;output&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;accept&lt;/code&gt; &lt;code&gt;drop&lt;/code&gt; &lt;code&gt;log&lt;/code&gt; &lt;code&gt;counter&lt;/code&gt; &lt;code&gt;queue&lt;/code&gt; &lt;code&gt;limit&lt;/code&gt; &lt;code&gt;set&lt;/code&gt; &lt;code&gt;map&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;决定包的去留&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ip&lt;/code&gt; &lt;code&gt;ip6&lt;/code&gt; &lt;code&gt;inet&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;nat&lt;/td&gt;
&lt;td&gt;&lt;code&gt;prerouting&lt;/code&gt; &lt;code&gt;postrouting&lt;/code&gt; &lt;code&gt;output&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dnat&lt;/code&gt; &lt;code&gt;snat&lt;/code&gt; &lt;code&gt;masquerade&lt;/code&gt; &lt;code&gt;rediret&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;地址转换&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt; arp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;arp&lt;/td&gt;
&lt;td&gt;&lt;code&gt;input&lt;/code&gt; &lt;code&gt;output&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;accept&lt;/code&gt; &lt;code&gt;drop&lt;/code&gt; &lt;code&gt;log&lt;/code&gt; &lt;code&gt;counter&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;二层&lt;code&gt;arp&lt;/code&gt;相关&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bridge&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;bridge&lt;/td&gt;
&lt;td&gt;&lt;code&gt;prerouting&lt;/code&gt; &lt;code&gt;forward&lt;/code&gt; &lt;code&gt;output&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;accept&lt;/code&gt; &lt;code&gt;drop&lt;/code&gt; &lt;code&gt;vlan&lt;/code&gt; &lt;code&gt;log&lt;/code&gt; &lt;code&gt;counter&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;二层以太网帧&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;netdev&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;netdev&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ingress&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;accept&lt;/code&gt; &lt;code&gt;drop&lt;/code&gt; &lt;code&gt;queue&lt;/code&gt; &lt;code&gt;log&lt;/code&gt; &lt;code&gt;counter&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;网卡接口过滤&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;:::note&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;nftables中表只是一个容纳链的容器，属于某个簇。&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;**&lt;em&gt;链&lt;/em&gt;**才是具体功能的实现，通过设置不同的优先级。&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;:::&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;匹配与执行流程&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;逐条规则顺序执行&lt;/em&gt;&lt;/strong&gt;: 进入某个链后，会从上到下从左至右依次执行规则。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;动作的类型不同，行为也不同&lt;/em&gt;&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;终止性动作&lt;/em&gt;&lt;/strong&gt;(如&lt;code&gt;accept&lt;/code&gt;,&lt;code&gt;drop&lt;/code&gt;,&lt;code&gt;reject&lt;/code&gt;): 一旦数据包命中，直接对这个数据包做出最终处理，处理立即结束，不再继续匹配后面的规则。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;非终止性动作&lt;/em&gt;&lt;/strong&gt;(如&lt;code&gt;counter&lt;/code&gt;,&lt;code&gt;log&lt;/code&gt;,&lt;code&gt;mark&lt;/code&gt;): 执行完动作后，仍然会继续往下匹配下一条规则。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;控制流动作&lt;/em&gt;&lt;/strong&gt;(如&lt;code&gt;jump&lt;/code&gt;,&lt;code&gt;goto&lt;/code&gt;): 跳转到子链执行，&lt;code&gt;jump&lt;/code&gt;执行完子链后会&lt;code&gt;return&lt;/code&gt;回来继续匹配，&lt;code&gt;goto&lt;/code&gt;则不会返回。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;NAT类动作&lt;/em&gt;&lt;/strong&gt;(如&lt;code&gt;dnat&lt;/code&gt;,&lt;code&gt;snat&lt;/code&gt;): 匹配到规则后，修改包头并继续走路由和后续链。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;链的默认策略&lt;/em&gt;&lt;/strong&gt;: 如果数据包走完整个链，没有命中任何规则，执行链的&lt;code&gt;policy&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;写nftables规则时的一些问题&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;规则顺序要合理&lt;/em&gt;&lt;/strong&gt;: 最严格或最宽松的规则不应该放在过滤或限速规则之前。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;规则不应自相矛盾&lt;/em&gt;&lt;/strong&gt;: 如既想要限制新连接，又要无条件接受，又想丢弃特定的包。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;规则的冗余&lt;/em&gt;&lt;/strong&gt;: 多条规则匹配相同的流量，又使用**&lt;em&gt;终止性动作&lt;/em&gt;**。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;一般的配置思路&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;要明确自己的真实意图，规则的大概顺序： &lt;strong&gt;&lt;em&gt;丢弃明确的恶意流量&lt;/em&gt;&lt;/strong&gt; --&amp;gt; &lt;strong&gt;&lt;em&gt;限制可疑的流量&lt;/em&gt;&lt;/strong&gt; --&amp;gt; &lt;strong&gt;&lt;em&gt;接受合法的流量&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;不要一次添加大量的规则&lt;/li&gt;
&lt;li&gt;从最简单宽松的规则开始&lt;/li&gt;
&lt;li&gt;逐步添加和测试规则&lt;/li&gt;
&lt;li&gt;每添加一次新规则，立即测试效果。&lt;/li&gt;
&lt;li&gt;观察网络行为，确保新的规则没有出现意外的动作&lt;/li&gt;
&lt;li&gt;在关键的位置添加&lt;code&gt;log&lt;/code&gt;动作&lt;/li&gt;
&lt;li&gt;使用&lt;code&gt;nft monitor&lt;/code&gt;实时监视事件&lt;/li&gt;
&lt;li&gt;查看计数器&lt;code&gt;counter&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;使用&lt;code&gt;nft trace&lt;/code&gt;手动跟踪特定数据包
&lt;ol&gt;
&lt;li&gt;在想要跟踪链的开头添加这条规则：&lt;code&gt;nft insert rule family_name table_name chain_name position 0 meta nftrace set 1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;使用&lt;code&gt;nft monitor trace&lt;/code&gt;查看实时输出&lt;/li&gt;
&lt;li&gt;测试完成后删除跟踪规则&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;坑&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;在使用sets时注意空格，一些版本(我所使用的)的nft不能将{80,443}正确识别，要写成 { 80, 443 } 。  
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Remote-power-on</title><link>https://www.infini.cv/posts/other/remote-power-on/</link><guid isPermaLink="true">https://www.infini.cv/posts/other/remote-power-on/</guid><description>wake on Lan </description><pubDate>Wed, 15 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;先决条件&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;主机的主板和网卡必须支持**&lt;em&gt;WOL(Wake-on-Lan)&lt;/em&gt;**技术。去官网上查，或者问客服是否支持。&lt;/li&gt;
&lt;li&gt;开启**&lt;em&gt;WOL&lt;/em&gt;&lt;strong&gt;。进入BIOS，一般在&lt;/strong&gt;&lt;em&gt;Advanced&lt;/em&gt;&lt;strong&gt;里的&lt;/strong&gt;&lt;em&gt;APM&lt;/em&gt;&lt;strong&gt;或者&lt;/strong&gt;&lt;em&gt;Network&lt;/em&gt;**里有个Wake on Lan。&lt;/li&gt;
&lt;li&gt;主机关机后网口灯还在亮，能支持远程开机。&lt;/li&gt;
&lt;li&gt;主机是windows，要关闭&lt;em&gt;快速启动&lt;/em&gt;,否则可能无法唤醒。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;实现&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;有一个运行的设备与主机在**&lt;em&gt;同一局域网&lt;/em&gt;**内。这个设备最好是路由器，并且刷了openwrt。&lt;/li&gt;
&lt;li&gt;以openwrt为例:
&lt;ol&gt;
&lt;li&gt;下载etherwake。有一个调用它的&lt;code&gt;luci&lt;/code&gt;包&lt;code&gt;luci-qpp-wol&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;在openwrt的终端上执行&lt;code&gt;etherwake your host Mac address &lt;/code&gt;后，主机就能开机，要确保&lt;code&gt;Mac address&lt;/code&gt;输入正确。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;公网远程访问&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;有公网ip:直接连上你的设备执行命令即可。&lt;/li&gt;
&lt;li&gt;没有公网ip:做内网穿透或者下载一个远程连接工具，连到设备执行命令。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Finally&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;手机，电脑，都可以用类似的方法实现。一些品牌的路由器自带&quot;远程唤醒&quot;功能。&lt;/li&gt;
&lt;li&gt;此方案可以省下买一个智能插座的钱。如果以上的条件都实现不了还想要在公网环境下远程开机，还是买一个智能插座。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Raspberry-pi4-installs-openwrt-with-docker</title><link>https://www.infini.cv/posts/raspberry/raspberry-pi4-installs-openwrt-with-docker/</link><guid isPermaLink="true">https://www.infini.cv/posts/raspberry/raspberry-pi4-installs-openwrt-with-docker/</guid><description>Raspberry Pi Projects That Won’t Collect Dust</description><pubDate>Tue, 14 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;制作openwrt docker 镜像&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;在github上新建一个仓库&lt;/li&gt;
&lt;li&gt;创建.github/workflows/build.yml文件:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;name: Build OpenWrt Docker Image from RPi4 Factory IMG

on:
  workflow_dispatch:   # 手动触发

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Download OpenWrt RPi4 Factory Image
        run: |
          mkdir image
          cd image
          wget https://downloads.openwrt.org/releases/24.10.1/targets/bcm27xx/bcm2711/openwrt-24.10.1-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz
          gunzip openwrt-24.10.1-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz
          cd ..

      - name: Extract rootfs from IMG
        run: |
          mkdir rootfs
          sudo apt-get update &amp;amp;&amp;amp; sudo apt-get install -y kpartx e2fsprogs
          # 建立 loop 设备
          LOOP=$(sudo losetup -f --show image/openwrt-24.10.1-bcm27xx-bcm2711-rpi-4-ext4-factory.img)
          sudo partprobe $LOOP
          # 挂载第二个分区 (rootfs)
          sudo mount ${LOOP}p2 /mnt
          sudo tar -C /mnt -czf rootfs/openwrt-rpi4-rootfs.tar.gz .
          sudo umount /mnt
          sudo losetup -d $LOOP

      - name: Create Dockerfile
        run: |
          cat &amp;gt; Dockerfile &amp;lt;&amp;lt;&apos;EOF&apos;
          FROM scratch
          ADD rootfs/openwrt-rpi4-rootfs.tar.gz /
          CMD [&quot;/sbin/init&quot;]
          EOF

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Build Docker Image
        uses: docker/build-push-action@v6
        with:
          context: .
          file: ./Dockerfile
          platforms: linux/arm64
          push: false
          outputs: type=docker,dest=./openwrt-rpi4.tar

      - name: Upload Image Artifact
        uses: actions/upload-artifact@v4
        with:
          name: openwrt-rpi4-image
          path: ./openwrt-rpi4.tar

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;说明:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;下载 openwrt-24.10.1-bcm2711-rpi-4-ext4-factory.img.gz&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;解压 .img.gz 得到 .img&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;挂载 .img 的第二个分区（rootfs）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;打包 rootfs 为 tar.gz&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;构建 Docker 镜像（基于 scratch）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;导出 为 openwrt-rpi4.tar，并作为 Artifact 提供下载&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;使用&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;点击&lt;code&gt;Actions&lt;/code&gt;按钮&lt;/li&gt;
&lt;li&gt;点击左侧出现的&lt;code&gt;Build OpenWrt Docker Image from RPi4 Factory IMG&lt;/code&gt; ,再点击&lt;code&gt;Run workflow&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;一分钟左右镜像构建成功，下载镜像&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;导入镜像&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;docker load -i openwrt-rpi4.tar #镜像名
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;导入的镜像没有名字，用&lt;code&gt;docker tag &lt;/code&gt;来命名&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;docker images #查看docker images
docker tag images_ID openwrt24.10.1:rpi4 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note
可以在构建阶段加入&lt;code&gt;tag&lt;/code&gt;&lt;br /&gt;
with:&lt;br /&gt;
tags: openwrt24.10.1:rpi4&lt;br /&gt;
:::&lt;/p&gt;
&lt;h2&gt;运行容器&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;直接运行&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;
docker run -d --name openwrt --network host --privileged openwrt24.10.1:rpi4
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;使用macvlan&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo ip link set eth0 promisc on # 打开有线网卡的混杂模式
docker network create -d macvlan --subnet=192.168.0.0/24 --gateway=192.168.0.1 -o parent=eth0 openwrt_macnet 
# 创建macvlan网卡 
# --subnet=真实的网络 
# parent=网卡名字 虚拟网卡名
docker run --restart always --name openwrt -d --network openwrt_macnet --privileged rpi4 

&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;使用docker compose(推荐)
&lt;ol&gt;
&lt;li&gt;创建一个目录&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt; mkdir openwrt
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;进入目录创建&lt;code&gt;docker-compose.yml&lt;/code&gt;文件&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;    
services:
  openwrt:
    image: openwrt24.10.1:rpi4
    container_name: openwrt
    privileged: true
    networks:
      macnet:
        ipv4_address: 192.168.1.31   # 给 OpenWrt 容器分配的局域网 IP
    restart: unless-stopped
    volumes:
      - ./openwrt-overlay:/overlay   # 持久化 OpenWrt 配置到当前目录
      - ./openwrt-root:/root         # 可选：持久化 root 用户目录（在当前目录）
      - ./openwrt-tmp:/tmp           # 可选：持久化临时目录（避免容器重启丢失）

networks:
  macnet:
    driver: macvlan
    driver_opts:
      parent: eth0                   # 你的物理网卡名称
    ipam:
      config:
        - subnet: 192.168.1.0/24      # 你的局域网网段
          gateway: 192.168.1.1        # 你的路由器网关
          ip_range: 192.168.1.31/32
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note&lt;br /&gt;
用macvlan的方式，容器无法与宿主机通信(宿主机ping不通容器)&lt;br /&gt;
可以在宿主机再建一个macvlan接口&lt;br /&gt;
sudo ip link add macvlan1 link eth0 type macvlan mode bridge # 创建一个macvlan1的接口&lt;br /&gt;
sudo ip addr add 192.168.1.32/24 dev macvlan1 # 分配同一网段的ip地址&lt;br /&gt;
sudo ip link set macvlan1 up  # 启用接口&lt;br /&gt;
:::&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用ipvlan模式&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;services:
  openwrt:
    image: openwrt24.10.1:rpi4
    container_name: openwrt
    privileged: true
    networks:
      ipvlan_net:
        ipv4_address: 192.168.1.31   # 给 OpenWrt 容器分配的局域网 IP
    restart: unless-stopped
    volumes:
      - ./openwrt-overlay:/overlay   # 持久化 OpenWrt 配置到当前目录
      - ./openwrt-root:/root         # 可选：持久化 root 用户目录
      - ./openwrt-tmp:/tmp           # 可选：持久化临时目录

networks:
  ipvlan_net:
    driver: ipvlan
    driver_opts:
      parent: eth0                   # 改成你的物理网卡名称
      ipvlan_mode: l2                # L2 模式，容器像局域网独立设备
    ipam:
      config:
        - subnet: 192.168.1.0/24     # 你的局域网网段
          gateway: 192.168.1.1       # 你的路由器网关
          ip_range: 192.168.1.31/32  # 限定容器 IP

&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;启动&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;docker compose up -d
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;进入容器&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;docker exec -it openwrt /bin/sh  
vi /etc/config/network # 修改ip地址
/etc/init.d/network restart # 重启网络
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;使用ip地址在浏览器上访问。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Finally&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;此方案没有无线功能，如果一定要有可以考虑做**&lt;em&gt;设备直通&lt;/em&gt;&lt;strong&gt;或者自己编译&lt;/strong&gt;&lt;em&gt;OpenWrt Docker镜像&lt;/em&gt;&lt;strong&gt;又或者直接在树莓派上安装&lt;/strong&gt;&lt;em&gt;OpenWrt&lt;/em&gt;**。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Docker_learn</title><link>https://www.infini.cv/posts/docker-learn/</link><guid isPermaLink="true">https://www.infini.cv/posts/docker-learn/</guid><description>docker basic learn</description><pubDate>Fri, 10 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Install&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 使用 curl
curl -fsSL https://get.docker.com | sh

# 或者使用 wget
wget -qO- https://get.docker.com | sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;启用docker service&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;sudo systemctl enable --now docker.service
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;导出docker镜像&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
docker save -o image_name.tar image:tag1 image:tag2 ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;导入镜像&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker load -i image_name.tar
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;导出容器快照&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker export -o container_snapshot.tar container_name or cntainer_ID
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;导入容器快照&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker import container_snapshot.tar new-image:tag # 得到一个全新的镜像,不包含启动命令，环境变量 工作目录，端口声明  
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;导入的镜像用的ID导入没有&lt;code&gt;REPOSITORY&lt;/code&gt;和&lt;code&gt;TAG&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker tag image_ID repo_name/image_name:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;开启docker的类似断点续传的功能，在&lt;code&gt;/etc/docker/daemon.json&lt;/code&gt;加入:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;features&quot;: {
    &quot;containerd-snapshotter&quot;: true
  }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>nftables</title><link>https://www.infini.cv/posts/nftable/nftables/</link><guid isPermaLink="true">https://www.infini.cv/posts/nftable/nftables/</guid><description>a linux firewall</description><pubDate>Tue, 07 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Install&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;在archlinux上:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo pacman -S nftables 
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;查看有其他防火墙服务是否在运行,如果有先禁用：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo systemctl list-units --type=service | grep -E &quot;firewalld|ufw&quot; 
sudo iptables -L -n -v # 谁有输出就禁用
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;启动防火墙:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo systemctl enable --now nftables.service 
sudo systemctl status nftables.service #查看防火墙状态  
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;安装nft的补全脚本&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo curl -o /etc/bash_completion.d/nft \
  https://raw.githubusercontent.com/Zulugitt/bash_completion/main/nft-completion
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;重新加载:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;source /etc/bash_completion.d/nft
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Usage&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;查看当前所有规则:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo nft list ruleset 
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;清空当前的规则&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo nft flush ruleset
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;加载配置文件&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo nft -f /path/to/filename # nftables的配置文件  
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Table&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;nftbles没有内置表&lt;/em&gt;&lt;/strong&gt;。每个表只能有一个地址簇。有六个簇。未指定为ip簇。&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;nftables family&lt;/th&gt;
&lt;th&gt;meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ip&lt;/td&gt;
&lt;td&gt;处理IPv4数据包&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ip6&lt;/td&gt;
&lt;td&gt;处理IPv6数据包&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inet&lt;/td&gt;
&lt;td&gt;同时处理IPv4和IPv6数据包&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;arp&lt;/td&gt;
&lt;td&gt;处理ARP数据包&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bridge&lt;/td&gt;
&lt;td&gt;处理二层桥接数据包&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;netdev&lt;/td&gt;
&lt;td&gt;处理网络设备ingress(入站)数据包&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;创建表&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo nft add table family_type table_name
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;列出表&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo nft list tables
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;列出表中的链和规则&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo nft list table family_type table_name 
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;删除表&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo nft delete table family_type table_name 
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;刷新表&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo nft flush table family_type table_name 
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Chains&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;链的用途是包含规则&lt;/em&gt;&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;链有两种类型。分别是**&lt;em&gt;基本链(Base chain)&lt;/em&gt;&lt;strong&gt;和&lt;/strong&gt;&lt;em&gt;常规链(Regular chain)&lt;/em&gt;&lt;strong&gt;。区别主要在&lt;/strong&gt;&lt;em&gt;是否挂接到内核网络堆栈&lt;/em&gt;**。
&lt;ul&gt;
&lt;li&gt;基本链：入口点，必须有hook,直接处理数据包。&lt;/li&gt;
&lt;li&gt;常规链：辅助链,没有hook,作为跳转目标，用来组织规则。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Base chain&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;添加基本链:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo nft add chain family_type table_name chain_name  { type chain_type hook hook_type priority priority_value ; policy policy ;}  
# type: filter / nat /route 
# hook: preouting / input / forward /output / postrouting /ingress  # ip ip6 family 
# priority: 名字或整数，可以为负
# policy accept / drop 
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;添加常规链:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo nft add chain family_type table_name chain_name 
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;编辑链:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo nft chain family_type table_name chain_name { } # 可以修改 policy 命名集合的元素，计数器，限速器，等状态对象。  
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Ruler&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;规则由**&lt;em&gt;匹配条件(Expressions)&lt;/em&gt;&lt;strong&gt;和&lt;/strong&gt;&lt;em&gt;动作(Statements)&lt;/em&gt;**组成。条件和动作从左到右顺序应用。&lt;/li&gt;
&lt;li&gt;规则中的条件在逻辑上连接在一起**&lt;em&gt;(AND运算符)&lt;/em&gt;**。所有的条件必须全部匹配，才能执行相应的动作。否则，将执行下一条规则。&lt;/li&gt;
&lt;li&gt;添加规则:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo nft add rule family_type table_name chain_name handle handle_value  ruler
# handle 一个唯一的ID 用来删除、替换、插入的。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Expression&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;常见的匹配条件:&lt;/li&gt;
&lt;/ol&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;expression&lt;/th&gt;
&lt;th&gt;example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;meta&lt;/td&gt;
&lt;td&gt;&lt;code&gt;iif lo&lt;/code&gt; &lt;code&gt;oifname &quot;eth0&quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ip / ip6&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ip saddr 192.168.0.0/16&lt;/code&gt; / &lt;code&gt;ip6 daddr fe80::/10&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tcp / udp / sctp&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tcp dport 22&lt;/code&gt; / &lt;code&gt;udp sport 53 &lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;icmp / icmp6&lt;/td&gt;
&lt;td&gt;&lt;code&gt;icmp type echo-request&lt;/code&gt; / &lt;code&gt;icmpv6 type nd-neighbor-solicit&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ct&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ct state established,related&lt;/code&gt; / &lt;code&gt;ct state new&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sets / maps&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tcp dport {22,80,443}&lt;/code&gt; / &lt;code&gt;ip saddr vmap { 192.168.1.1 : drop,192.168.1.2 : accept }&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ol&gt;
&lt;li&gt;更多的expression具体信息可以使用 &lt;code&gt;nft describe &lt;/code&gt;查询或者&lt;code&gt;man nft&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Statements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;常见的动作:&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;statements&lt;/th&gt;
&lt;th&gt;meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;accept&lt;/td&gt;
&lt;td&gt;放行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;drop&lt;/td&gt;
&lt;td&gt;丢弃&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;reject&lt;/td&gt;
&lt;td&gt;拒绝并返回ICMP/ICMPv6错误&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;queue&lt;/td&gt;
&lt;td&gt;交给用户空间程序处理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;return&lt;/td&gt;
&lt;td&gt;返回到调用链&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;log&lt;/td&gt;
&lt;td&gt;记录日志&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;counter&lt;/td&gt;
&lt;td&gt;计数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;masquerade / snat / dnat&lt;/td&gt;
&lt;td&gt;NAT动作&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;limit / meter&lt;/td&gt;
&lt;td&gt;限速 / 限流&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;set / add / delete / element&lt;/td&gt;
&lt;td&gt;动态修改集合&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Sets&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;集合可以是匿名，命名的。它可以用来存放一组元素，然后在规则中引用。
&lt;ul&gt;
&lt;li&gt;匿名集：直接写在规则里，不能修改&lt;/li&gt;
&lt;li&gt;命名集：单独定义，可动态更新&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;example 自动拉黑&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;table inet ssh_protect {
    # 定义一个动态黑名单集合
    set ssh_blacklist {
        type ipv4_addr
        flags dynamic, timeout
        timeout 1h                
        size 65536               
    }

    chain input {
        type filter hook input priority 0; policy accept;

        ip saddr @ssh_blacklist drop
        # 如果源 IP 在黑名单中，直接丢弃

        tcp dport 22 ct state new \
        # 检测 SSH 新连接，超过速率限制则加入黑名单
            limit rate over 10/minute burst 5 packets \
            add @ssh_blacklist { ip saddr timeout 1h } \
            accept
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Maps&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;maps是sets的一种扩展形式。
基本语法:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;map map_name {
    type key_type: value_type
    elements = { key : value, key1 : value1 }

}
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;example 1 端口重定向&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;table ip nat {
    map port_redirect {
        type inet_service : inet_service
        elements = { 80 : 8080, 443 : 8443 }
    }

    chain prerouting {
        type nat hook prerouting priority dstnat;
        tcp dport @port_redirect dnat to 192.168.1.10 : @port_redirect
    }
}
# 访问本机的80 / 443 端口会被转发到 192.168.0.10 的 8080 / 8443 端口上 
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;example 2 服务端口分类&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;table inet filter {
    map service_dispatch {
        type inet_service : verdict
        elements = {
            22  : jump ssh_chain,
            23122  : jump ssh_chain,
            80  : jump web_chain,
            443 : jump web_chain
        }
    }

    chain input {
        type filter hook input priority 0; policy drop ;
        tcp dport vmap @service_dispatch
    }

    chain ssh_chain {
        tcp dport 22 drop
        tcp dport 23122 accept
    }

    chain web_chain {
        tcp dport {80,443} accept
    }
}
# 把不同的端口映射到不同的链上
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;example 3 基于不同IP的策略&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;table inet filter {
    map ip_policy {
        type ipv4_addr : verdict
        elements = {
            192.168.1.100 : accept,
            10.0.0.5      : drop
        }
    }

    chain input {
        type filter hook input priority 0; policy drop ;
        ip saddr vmap @ip_policy
    }
}
# 不同来源的IP走不同的链
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Objects&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;counter&lt;/li&gt;
&lt;li&gt;quota&lt;/li&gt;
&lt;li&gt;limit&lt;/li&gt;
&lt;li&gt;ct helper&lt;/li&gt;
&lt;li&gt;flowtable&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;例子&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;flush ruleset

table inet myfw {
    # 黑名单集合
    set ssh_blacklist {
        type ipv4_addr
        flags dynamic, timeout
        timeout 1h
    }

    # 对象：计数器 + 限速器
    counter ssh_counter
    limit ssh_limit { rate 10/minute burst 5 }

    chain input {
        type filter hook input priority 0; policy drop;

        # 基础放行
        ct state established,related accept
        iif lo accept

        # 黑名单
        ip saddr @ssh_blacklist drop

        # SSH 防护：速率限制 + 计数 + 自动拉黑
        tcp dport 22 ct state new limit name ssh_limit counter name ssh_counter \
            add @ssh_blacklist { ip saddr timeout 1h } drop

        # 允许 Web 服务
        tcp dport {80,443} accept
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;流程图&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;flowchart TD
    A[Packet enters input chain] --&amp;gt; B{ct state established,related?}
    B -- yes --&amp;gt; Z[ACCEPT established/related]
    B -- no --&amp;gt; C{iif lo?}
    C -- yes --&amp;gt; Z
    C -- no --&amp;gt; D{Source IP in ssh_blacklist?}
    D -- yes --&amp;gt; X[DROP blacklist]
    D -- no --&amp;gt; E{tcp dport 22 and state new?}
    E -- no --&amp;gt; F{tcp dport 80 or 443?}
    E -- yes --&amp;gt; G[Count ssh_counter + Limit ssh_limit]
    G --&amp;gt; H[Add source IP to ssh_blacklist 1h]
    H --&amp;gt; X[DROP SSH over limit]
    F -- yes --&amp;gt; Z[ACCEPT Web service]
    F -- no --&amp;gt; X[DROP default policy]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;如何写一条规则&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;要实现什么功能，确定在哪个表和链里写。&lt;/li&gt;
&lt;li&gt;写匹配条件。如协议，端口，地址等等。&lt;/li&gt;
&lt;li&gt;写动作。如 accept,drop,log等。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Finally&lt;/h2&gt;
&lt;p&gt;更多内容请查看&lt;a href=&quot;https://nftables.org&quot;&gt;nftables官网&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>markdown-extended-syntax</title><link>https://www.infini.cv/posts/markdown-extended-syntax/</link><guid isPermaLink="true">https://www.infini.cv/posts/markdown-extended-syntax/</guid><description>markdown extended syntax</description><pubDate>Fri, 19 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;表格&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;使用**&lt;em&gt;三个或多个连字符(&lt;code&gt;---&lt;/code&gt;)&lt;/em&gt;**,使用管道(|)分隔系列.&lt;/li&gt;
&lt;li&gt;管道与文本之间要有空格。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt; | Syntax    | Description |
 | --------- | ----------- |
 | Header    | Title       |
 | Paragraph | Text        |

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出如下:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Syntax&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Header&lt;/td&gt;
&lt;td&gt;Title&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Paragraph&lt;/td&gt;
&lt;td&gt;Text&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;对齐&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;在连字符的左侧，右侧，两侧添加冒号 ( : ),将文本对齐到左侧，右侧，中心.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;| Left alignment | Center alignment | Right alignment | 
| :------------- | :---------------:| --------------: | 
| Content        | Content          | Content         |
| Content        | Content          | Content         |
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出如下:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Left alignment&lt;/th&gt;
&lt;th&gt;Center alignment&lt;/th&gt;
&lt;th&gt;Right alignment&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Content&lt;/td&gt;
&lt;td&gt;Content&lt;/td&gt;
&lt;td&gt;Content&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Content&lt;/td&gt;
&lt;td&gt;Content&lt;/td&gt;
&lt;td&gt;Content&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;格式化表格中的文字&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;可以丰表格中设置文本格式。如链接，代码(仅反引号( ` )中的单词或短语，不是代码块) 和强调。&lt;/li&gt;
&lt;li&gt;不支持标题，块引用，列表，水平规则，图像或HTML标签。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;在表中转义管道字符&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;可以使用表中的HTML字符代码( &amp;lt;code&amp;gt;&amp;amp;#124;&amp;lt;/code&amp;gt;)在表中显示竖线(|)字符。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Markdown 脚注&lt;/h2&gt;
&lt;p&gt;脚注可以添加注释和参考，而不会使文档正文混乱。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;创建脚注: 在方括号 ( &lt;code&gt;[^xx]&lt;/code&gt; ) 内符号各标识符。标识符可以是**&lt;em&gt;数字或单词&lt;/em&gt;**,但不能包含空格或制表符。&lt;/li&gt;
&lt;li&gt;在方括号内使用另一个插入符号和数字，标识符，并用冒号和文本相连 ( &lt;code&gt;[^xx]: content.&lt;/code&gt; )。可以放在除列表、块引号和表之类的其他元素这外的任何位置。&lt;br /&gt;
像这样：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;Here&apos;s a simple footnote,[^1] and here&apos;s a longer one.[^bignote]
[^1]: This is the first footnote.
[^bignote]: Here&apos;s one with multiple paragraphs and code.
    Indent paragraphs to include them in the footnote.
    `{ my code }`
    Add as many paragraphs as you like.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出如下：&lt;br /&gt;
Here&apos;s a simple footnote,[^1] and here&apos;s a longer one.[^bignote]
[^1]: This is the first footnote.
[^bignote]: Here&apos;s one with multiple paragraphs and code.
Indent paragraphs to include them in the footnote.
&lt;code&gt;{ my code }&lt;/code&gt;
Add as many paragraphs as you like.&lt;/p&gt;
&lt;h2&gt;Markdown 标题编号&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;添加自定义ID可以直接链接到标题并使用CSS对其进行修改。&lt;/li&gt;
&lt;li&gt;在与标题相同的行内用大括号括起该自定义ID。&lt;/li&gt;
&lt;li&gt;通过创建带有数字符号 (&lt;code&gt;#&lt;/code&gt;) 和自定义标题ID,可以链接到文件中具有自定义ID的标题。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;### Heading {#custom-id}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Markdown 定义列表&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;在第一行上键入术语。在下一行键入一个冒号跟一个空格和定义。&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;
像这样：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;First Term
: This is the difinition of the first term.
Secend Term
: This is one definition of the second term.
: This is another definition of the second term.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出如下：&lt;br /&gt;
First Term&lt;br /&gt;
: This is the difinition of the first term.&lt;br /&gt;
Secend Term&lt;br /&gt;
: This is one definition of the second term.&lt;br /&gt;
: This is another definition of the second term.&lt;/p&gt;
&lt;h2&gt;Markdown 任务列表语法&lt;/h2&gt;
&lt;p&gt;在任务列表之前添加连字符 (-) 和方括号 [ ],并在方括号前面各中间添加一个空格。要选择一个复选框，在方括号 [x] 之间加 x 。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;- [x] Write the press release  
- [ ] update the website  
- [ ] Contact the media
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[x] Write the press release&lt;/li&gt;
&lt;li&gt;[ ] update the website&lt;/li&gt;
&lt;li&gt;[ ] Contact the media&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;使用 Emoji 表情&lt;/h2&gt;
&lt;p&gt;以冒号开头和结尾，中间包含表情符号的名称。&lt;br /&gt;
&lt;code&gt;:tent:&lt;/code&gt; 显示 :tent:&lt;br /&gt;
&lt;code&gt;:joy:&lt;/code&gt; 显示 :joy:&lt;br /&gt;
更多表情符号参考&lt;a href=&quot;https://gist.github.com/rxaviers/7360908&quot;&gt;这里&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Markdown 警告&lt;/h2&gt;
&lt;p&gt;Markdown没有自带警告框功能，但可以用 引用块 ( &amp;gt; ) + Emoji + 加粗模拟:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; :waring: **警告:** 不要按下红色按钮！  
&amp;gt; :memo: **注意：** 前方有坑  
&amp;gt; :bulb: **提示:** 现在是早八
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;渲染效果：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;:warning: &lt;strong&gt;警告:&lt;/strong&gt; 不要按下红色按钮！&lt;br /&gt;
:memo: &lt;strong&gt;注意：&lt;/strong&gt; 前方有坑&lt;br /&gt;
:bulb: &lt;strong&gt;提示:&lt;/strong&gt; 现在是早八&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>markdown-syntax</title><link>https://www.infini.cv/posts/markdown-syntax/</link><guid isPermaLink="true">https://www.infini.cv/posts/markdown-syntax/</guid><description>markdown learn</description><pubDate>Thu, 04 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;标题&lt;/h2&gt;
&lt;p&gt;使用#符号，数量表示标题级别。&lt;/p&gt;
&lt;h1&gt;这是最大的标题&lt;/h1&gt;
&lt;h2&gt;这是第二级标题&lt;/h2&gt;
&lt;h3&gt;这是第三级标题&lt;/h3&gt;
&lt;h4&gt;这是第四级标题&lt;/h4&gt;
&lt;h5&gt;这是第五级标题&lt;/h5&gt;
&lt;h6&gt;这是第六级标题&lt;/h6&gt;
&lt;blockquote&gt;
&lt;p&gt;:bulb: &lt;strong&gt;提示:&lt;/strong&gt; #号后面记得加一个空格，这是一个好习惯！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;段落和换行&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;用空行分隔不同的段落。&lt;/li&gt;
&lt;li&gt;段落内创建换行，在行内添加两个空格，然后按回车键。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;强调文本&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;斜体文本可以通过在文本两侧添加单个星号和下划线来创建：&lt;br /&gt;
&lt;em&gt;这是斜体&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;这也是斜体&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;粗体文本&lt;/strong&gt;使用两个星号或两个下划线：&lt;br /&gt;
&lt;strong&gt;这是粗体文本&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;这也是粗体文本&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;粗体&lt;/strong&gt;和&lt;em&gt;斜体&lt;/em&gt;组合使用：&lt;br /&gt;
&lt;strong&gt;&lt;em&gt;这是粗体斜体文本&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;这是粗体文本包含&lt;em&gt;斜体&lt;/em&gt;部分&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;删除线使用波浪号：&lt;br /&gt;
&lt;s&gt;这是删除线文本&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;列表&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;无序列表&lt;/strong&gt;可以用 - + *加空格作为列表标记：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第一项&lt;/li&gt;
&lt;li&gt;第二项&lt;/li&gt;
&lt;li&gt;第三项
&lt;ul&gt;
&lt;li&gt;嵌套项目&lt;/li&gt;
&lt;li&gt;另一个嵌套项目&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;第四项&lt;/li&gt;
&lt;li&gt;第五项&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;有序列表&lt;/strong&gt;使用数字加点号和空格：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;第一项&lt;/li&gt;
&lt;li&gt;第二项&lt;/li&gt;
&lt;li&gt;第三项
&lt;ol&gt;
&lt;li&gt;嵌套有序项目&lt;/li&gt;
&lt;li&gt;另一个嵌套有序项目&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;第四项&lt;/li&gt;
&lt;li&gt;第五项&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;:bulb: &lt;strong&gt;提示:&lt;/strong&gt; 在有序列表中，实际的数字并不重要。Markdown解析器会自动生成正确的序号。可以使用相同的数字和不连续的数字，这样在插入或删除列表时就不需要重新编号。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;第一项&lt;/li&gt;
&lt;li&gt;第二项&lt;/li&gt;
&lt;li&gt;第三项&lt;/li&gt;
&lt;li&gt;第四项&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;链接&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;内连链接&lt;/strong&gt;&lt;br /&gt;
[链接文本](https://example.com)&lt;br /&gt;
&lt;a href=&quot;https://example.com&quot;&gt;链接文本&lt;/a&gt;&lt;br /&gt;
[带标题的链接](https://example.com &quot;这是链接标题&quot;)&lt;br /&gt;
&lt;a href=&quot;https://example.com&quot;&gt;带标题的链接&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;引用式链接&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;分成两部分:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;链接的第一部分格式：&lt;/em&gt;&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;使用两组方括号进行格式设置。&lt;/li&gt;
&lt;li&gt;第一组方括号为链接文本。&lt;/li&gt;
&lt;li&gt;第二组方括号为一个标签，指向存储在其他位置的链接。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;链接的第二部分格式：&lt;/em&gt;&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;一个方括号(里面跟链接标签)，紧跟一个冒号和至少一个空格，最后是链接。&lt;/li&gt;
&lt;li&gt;链接的url可以选择将其括在尖括号中。&lt;/li&gt;
&lt;li&gt;链接的可选标题，可以将其括在双引号，单引号或括号中。&lt;/li&gt;
&lt;li&gt;链接的第二部分可以放在文档中的任何位置。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;br /&gt;
这是一个 [引用式链接][sing].&lt;br /&gt;
这是一个 &lt;a href=&quot;https://example.com&quot;&gt;引用式链接&lt;/a&gt;.&lt;br /&gt;
这是另一个 [引用链接][sing2].&lt;br /&gt;
这是另一个 &lt;a href=&quot;https://example.com&quot;&gt;引用链接&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;[sing]: https://example.com&lt;br /&gt;
[sing2]: https://example.com &quot;可选的标题&quot;&lt;/p&gt;
&lt;p&gt;**自动链接:**直接显示URL的情况 一对尖括号里面是链接&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com&quot;&gt;https://github.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;mailto:email@gmail.com&quot;&gt;email@gmail.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&amp;lt;https://github.com&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;email@gmail.com&amp;gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;图片&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;图片的方法与链接类似，只是在前面添加感叹号:&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;img src=&quot;https://www.infini.cv/icons/favicon-16x16.png&quot; alt=&quot;替代文本&quot; /&gt;&lt;br /&gt;
![替代文本](/icons/favicon-16x16.png)&lt;br /&gt;
&lt;img src=&quot;https://www.infini.cv/icons/favicon-16x16.png&quot; alt=&quot;带标题的图片&quot; title=&quot;图片标题&quot; /&gt;&lt;br /&gt;
![带标题的图片](/icons/favicon-16x16.png &quot;图片标题&quot;)&lt;/p&gt;
&lt;h3&gt;引用式图片&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://www.infini.cv/icons/favicon-16x16.png&quot; alt=&quot;替代文本&quot; title=&quot;可选的标题&quot; /&gt;&lt;br /&gt;
![替代文本][img-ref]&lt;/p&gt;
&lt;p&gt;[img-ref]: /icons/favicon-16x16.png &quot;可选的标题&quot;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;:bulb: &lt;strong&gt;note:&lt;/strong&gt; **&lt;em&gt;引用式链接&lt;/em&gt;&lt;strong&gt;和&lt;/strong&gt;&lt;em&gt;引用式图片&lt;/em&gt;**的二段最好单独放一段。第二段的标签不要有重复。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;代码&lt;/h2&gt;
&lt;p&gt;Markdown支持内联代码和代码块两种显示方式。&lt;/p&gt;
&lt;h3&gt;内联代码&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;使用反引号``包围:&lt;br /&gt;
使用&lt;code&gt;console.log()&lt;/code&gt;函数输出信息.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;代码块&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;使用3个反引号```或者3个波浪号~~~来包围起来。&lt;/li&gt;
&lt;li&gt;可以在符号后加入对应的语言，开启**&lt;em&gt;语法高亮&lt;/em&gt;**。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;{
 &quot;firsrtname&quot;: &quot;Tim&quot;,
 &quot;lastname&quot;: &quot;Smith&quot;,
 &quot;age&quot;:23
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;开启语法高亮:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
 &quot;firsrtname&quot;: &quot;Tim&quot;,
 &quot;lastname&quot;: &quot;Smith&quot;,
 &quot;age&quot;:23
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;引用&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;创建块引用，在**&lt;em&gt;段落前添加一个&amp;gt;符号和空格&lt;/em&gt;**。&lt;/li&gt;
&lt;li&gt;多个段落的块引用，需要在空白行添加一个 &amp;gt; 符号。&lt;/li&gt;
&lt;li&gt;可以嵌套。&lt;strong&gt;&lt;em&gt;再加一个 &amp;gt; 符号&lt;/em&gt;&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;This is a reference block.
It can contain multiple lines of content.&lt;/p&gt;
&lt;p&gt;It can even contain multiple pargraphs.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Nested references.&lt;/p&gt;
&lt;p&gt;This is a nested reference.&lt;/p&gt;
&lt;p&gt;Deeper nesting.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;h2&gt;分隔线&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;在单独一行上使用**&lt;em&gt;三个或多个星号( *** ), 破折号( --- ),下划线 ( ___ ),并且不能包含其他内容&lt;/em&gt;**。&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;三个星号&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;ul&gt;
&lt;li&gt;三个破折号&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;ul&gt;
&lt;li&gt;三个下划线&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;转义字符&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;常见的字体可以用反斜杠进行转义&lt;code&gt;\&lt;/code&gt;,有&lt;code&gt;\&lt;/code&gt;,&lt;code&gt;`&lt;/code&gt;,&lt;code&gt;*&lt;/code&gt;,&lt;code&gt;_&lt;/code&gt;,&lt;code&gt;{}&lt;/code&gt;,&lt;code&gt;[]&lt;/code&gt;,&lt;code&gt;()&lt;/code&gt;,&lt;code&gt;#&lt;/code&gt;,&lt;code&gt;+&lt;/code&gt;,&lt;code&gt;-&lt;/code&gt;,&lt;code&gt;.&lt;/code&gt;,&lt;code&gt;!&lt;/code&gt;,&lt;code&gt;|&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;有两个需要处理的特殊字符 &lt;code&gt;&amp;lt;&lt;/code&gt; 和 &amp;amp; 要使用这两个字符要这样写&amp;lt;code&amp;gt;&amp;amp;lt&amp;lt;/code&amp;gt;;和 &amp;lt;code&amp;gt;&amp;amp;amp&amp;lt;/code&amp;gt;;。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Vim-learn</title><link>https://www.infini.cv/posts/vim-learn/</link><guid isPermaLink="true">https://www.infini.cv/posts/vim-learn/</guid><description>vim</description><pubDate>Wed, 03 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;在vim insert mode下可以使用的快捷键&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;Ctrl-j / m&lt;/td&gt;
&lt;td&gt;换行（等同于 Enter）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl-r{register}&lt;/td&gt;
&lt;td&gt;粘贴指定寄存器的内容&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl-r =&lt;/td&gt;
&lt;td&gt;粘贴一个表达式的结果&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl-o&lt;/td&gt;
&lt;td&gt;临时切换到 Normal Mode，执行一个命令后立即返回 Insert Mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl-[ / Ctrl-c&lt;/td&gt;
&lt;td&gt;退出 Insert Mode（等同于 Esc）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl-h&lt;/td&gt;
&lt;td&gt;删除光标前的一个字符（等同于 Backspace）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl-w&lt;/td&gt;
&lt;td&gt;删除光标前的一个单词&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl-u&lt;/td&gt;
&lt;td&gt;删除光标前到行首的所有字符&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl-a&lt;/td&gt;
&lt;td&gt;插入上次插入模式中插入的文本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl-x&lt;/td&gt;
&lt;td&gt;插入补全&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl-x Ctrl-l&lt;/td&gt;
&lt;td&gt;补全整行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl-x Ctrl-f&lt;/td&gt;
&lt;td&gt;补全文件名&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl-x Ctrl-n&lt;/td&gt;
&lt;td&gt;从当前文件中补全文本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl-n / Ctrl-p&lt;/td&gt;
&lt;td&gt;自动补全：下一个/上一个匹配项&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;展开折叠的命令&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;zc&lt;/td&gt;
&lt;td&gt;关闭当前折叠&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;zo&lt;/td&gt;
&lt;td&gt;展开光标所在的折叠块&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;zO&lt;/td&gt;
&lt;td&gt;展开光标所在折叠块及其所有子折叠&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;za&lt;/td&gt;
&lt;td&gt;切换折叠状态 (展开或收起)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;zR&lt;/td&gt;
&lt;td&gt;展开所有折叠&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;zM&lt;/td&gt;
&lt;td&gt;收起所有折叠&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;重复执行&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;&lt;strong&gt;.&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ex模式&lt;/td&gt;
&lt;td&gt;@:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;宏&lt;/td&gt;
&lt;td&gt;@@&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;文本组合&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;操作符: &lt;code&gt;d&lt;/code&gt;、&lt;code&gt;y&lt;/code&gt;、&lt;code&gt;c&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;范围修饰: &lt;code&gt;i ( inside )&lt;/code&gt; 、&lt;code&gt;a  ( around )&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;对象类型: &lt;code&gt;w&lt;/code&gt;、 &lt;code&gt;s&lt;/code&gt;、 &lt;code&gt;p&lt;/code&gt;、 &lt;code&gt;[&lt;/code&gt;、 &lt;code&gt;(&lt;/code&gt;、 &lt;code&gt;{&lt;/code&gt;、 &lt;code&gt;&quot;&lt;/code&gt;、 &lt;code&gt;&apos;&lt;/code&gt;、 &lt;code&gt;&amp;lt;&lt;/code&gt;、 &lt;code&gt;t&lt;/code&gt;等等。
:::note
光标必须在对象内部或者边界符号上才能正常使用。&lt;br /&gt;
:::&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;撤销与重做&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;code&gt;u&lt;/code&gt;/&lt;code&gt;:undo&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;撤销最近一次修改&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Ctrl-r&lt;/code&gt;/&lt;code&gt;:redo&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;重做(恢复被撤销的修改)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ol&gt;
&lt;li&gt;行级撤销&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;U&lt;/code&gt;: 撤销当前行的所有修改，恢复到进入该行时的状态。&lt;br /&gt;
:::note
&lt;code&gt;U&lt;/code&gt;本身也是修改，可以按&lt;code&gt;u&lt;/code&gt;撤销这个&lt;code&gt;U&lt;/code&gt;
:::&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;指定撤销点&lt;/li&gt;
&lt;/ol&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;code&gt;:undo N&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;跳到第&lt;code&gt;N&lt;/code&gt;次修改之后的状态&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;:earlier time&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;回到&lt;code&gt;time&lt;/code&gt;前的状态&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;:earlier 3f&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;回到3次文件(file write)写入之前的状态&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;:later {N}{unit}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;与&lt;code&gt;:earlier&lt;/code&gt;的操作相反&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ol&gt;
&lt;li&gt;撤销树(Undo Tree)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;使用&lt;code&gt;:undolist&lt;/code&gt;查看撤销历史和分支，再使用&lt;code&gt;:earlier&lt;/code&gt;或者&lt;code&gt;:later&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;保存&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;:w !sudo tee % &amp;gt; /dev/null
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item></channel></rss>