-
Notifications
You must be signed in to change notification settings - Fork 0
/
search.xml
4444 lines (4045 loc) · 456 KB
/
search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>前后端分离下如何防止 CSRF 攻击</title>
<url>/2020/10/anti-csrf-on-separation-of-frontend-and-backend/</url>
<content><![CDATA[<h2 id="什么是-CSRF-攻击"><a href="#什么是-CSRF-攻击" class="headerlink" title="什么是 CSRF 攻击"></a>什么是 CSRF 攻击</h2><p>CSRF 的全名是 Cross Site Request Forgery,翻译成中文就是跨站点请求伪造 </p>
<p>CSRF 利用的是网站对用户网页浏览器的信任,简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并运行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。<br>由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去运行。这利用了 web 中用户身份验证的一个漏洞:<strong>简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的</strong></p>
<span id="more"></span>
<p>例子:</p>
<p>假如一家银行用以运行转账操作的 URL 地址如下:<code>https://bank.example.com/withdraw?account=AccoutName&amount=1000&for=PayeeName</code></p>
<p>那么,一个恶意攻击者可以在另一个网站上放置如下代码:<code><img src="https://bank.example.com/withdraw?account=Alice&amount=1000&for=Badman" /></code></p>
<p>如果有账户名为 Alice 的用户访问了恶意站点,而她之前刚访问过银行不久,登录信息尚未过期,那么她就会损失 1000 资金</p>
<h2 id="常见的防御手段"><a href="#常见的防御手段" class="headerlink" title="常见的防御手段"></a>常见的防御手段</h2><h3 id="验证码"><a href="#验证码" class="headerlink" title="验证码"></a>验证码</h3><p><code>CSRF</code> 攻击往往是在用户不知情的情况下伪造了请求,而验证码强制用户必须进行交互</p>
<ul>
<li><code>措施</code>:给敏感操作添加验证码校验</li>
<li><code>局限</code>:影响用户体验</li>
</ul>
<h3 id="检查-Referer-字段"><a href="#检查-Referer-字段" class="headerlink" title="检查 Referer 字段"></a>检查 Referer 字段</h3><p>在处理敏感请求时,通常发出请求的网址应该与接受请求的网址属于同一域名</p>
<ul>
<li><code>措施</code>:所以我们可以通过校验 <code>HTTP headers</code> 中的 <code>Referer</code> 字段是否是属于本网站,如果不是则可能遭受 <code>CSRF</code> 攻击 </li>
<li><code>局限</code>:这种办法简单易行,工作量低,但是依赖于浏览器的发送正确的 <code>Referer</code> 字段,无法保证浏览器没有安全漏洞影响 <code>Referer</code> 的发送</li>
</ul>
<h3 id="不使用-GET-请求做敏感操作"><a href="#不使用-GET-请求做敏感操作" class="headerlink" title="不使用 GET 请求做敏感操作"></a>不使用 GET 请求做敏感操作</h3><p>在上面的例子中,我们可以知道,Alice 打开恶意站点后,浏览器通过 <code>img</code> 标签向银行转账网址发送了 <code>GET</code> 请求从而实现了 <code>CSRF</code> 攻击。</p>
<ul>
<li><code>措施</code>:所以,避免 <code>CSRF</code> 攻击最基础的一条是 <code>永远不使用 GET 请求做敏感操作</code></li>
<li><code>局限</code>:这种方法可以避免 <code>img</code>、<code>script</code>、<code>iframe</code> 等带 <code>src</code> 属性的标签发起 <code>CSRF</code> 攻击。但是无法防止攻击者构建 <code>POST</code> 请求等发起 <code>CSRF</code> 攻击</li>
</ul>
<h3 id="使用-Anti-CSRF-Token"><a href="#使用-Anti-CSRF-Token" class="headerlink" title="使用 Anti-CSRF-Token"></a>使用 Anti-CSRF-Token</h3><p><code>CSRF</code> 为什么能够攻击成功?其本质原因是<strong>重要操作的所有参数都是可以被攻击者猜测到的</strong>。攻击者只有预测出 URL 的所有参数与参数值,才能成功地构造一个伪造的请求;反之,攻击者将无法攻击成功。 </p>
<ul>
<li><p><code>措施</code>:所以我们可以生成一个<code>足够随机</code>的参数 <code>Token</code> 放入该次请求,保证该次请求无法被攻击者成功伪造。</p>
<p><strong>核心思路</strong>:使用一个由服务器派发的 <code>Token</code>,在前端进行状态修改时,也同时提交这个 <code>Token</code>(往往会放在 <code>html form</code> 的 <code>input</code> 中,或者 <code>ajax header</code> 中),这时候服务端验证该 <code>Token</code> 是否是之前所生成的,以此来判断这个请求是否被允许 </p>
</li>
<li><p><code>局限</code>:</p>
<ol>
<li>依赖于 <code>Token</code> 足够随机</li>
<li>无论是 <code>Token</code> 放在哪里,只要 <code>JS</code> 能读取到,都会面临 <code>XSS</code> 风险</li>
</ol>
</li>
</ul>
<p>在常见的 Web 后端框架比如 <code>Rails</code>、<code>Django</code> 中都自带实现了 <code>csrf_token</code> 功能,不同的是</p>
<ul>
<li>Rails 使用 <code>meta</code> 标签存放 <code>csrf_token</code>,通过 <code>HTTP headers</code> 发送</li>
<li>Django 使用隐藏的 <code>input</code> 标签存放 <code>csrf_token</code>,通过 <code>POST body</code> 发送</li>
</ul>
<h2 id="前后端分离带来的问题"><a href="#前后端分离带来的问题" class="headerlink" title="前后端分离带来的问题"></a>前后端分离带来的问题</h2><p>在现在大前端时代,前端后分离是个再常见不过的情况,我们该如何在前后端分离的情况下防止 <code>CSRF</code> 攻击呢?</p>
<p>首先,我们分析下上面所提到的几种手段在前后端分离下发生了什么变化:</p>
<ul>
<li>验证码:<ul>
<li><code>form</code> 表单完全由前端生成,后端是无法感知的,即使前端使用某种方式在 <code>form</code> 中放入了验证码,但是后端也无法验证</li>
</ul>
</li>
<li>检查 Referer 字段:无变化</li>
<li>不使用 GET 请求做敏感操作:无变化</li>
<li>使用 Anti-CSRF-Token:<ul>
<li><code>form</code> 表单完全由前端生成,后端是无法感知的,即使前端使用某种方式在 <code>form</code> 中放入了 <code>Token</code>,但是后端也无法验证</li>
</ul>
</li>
</ul>
<p>所以根本上是前后端分离之后,后端无法控制 <code>form</code> 生成时机,而前端则必须通过某种方式获取到由后端生成的 验证码 或者 <code>Token</code> 才能保证后端能够校验请求</p>
<ul>
<li><code>措施</code>:<ol>
<li>后端引入安全模块,可能是写在 <code>WAF</code> 里,也有可能是 <code>Security Sidecar</code> 或者自定义的 <code>API Gateway</code></li>
<li>前端请求安全模块,由安全模块生成 <code>csrf_token</code> 并返回,在提交时验证请求</li>
</ol>
</li>
<li><code>局限</code>:依然无法避免 <code>XSS</code> 攻击</li>
</ul>
<h2 id="XSRF"><a href="#XSRF" class="headerlink" title="XSRF"></a>XSRF</h2><p><code>CSRF</code> 的 <code>Token</code> 仅仅用于对抗 <code>CSRF</code> 攻击,当网站还同时存在 <code>XSS</code> 漏洞时,这个方案就会变得无效。<br>因为 <code>XSS</code> 可以模拟客户端浏览器执行任意操作,在 <code>XSS</code> 攻击下,攻击者完全可以请求页面后,读出页面内容里的 <code>Token</code> 值,然后再构造出一个合法的请求。这个过程就被称之为 <code>XSRF</code></p>
<p><code>XSS</code> 带来的问题,应该使用 <code>XSS</code> 的防御方案予以解决,否则 <code>CSRF</code> 的 <code>Token</code> 防御就是空中楼阁。安全防御的体系是相辅相成、缺一不可的</p>
<h2 id="迷思"><a href="#迷思" class="headerlink" title="迷思"></a>迷思</h2><ul>
<li><p>Q:以下攻击能成功吗?</p>
<ol>
<li>攻击者构建了一个恶意网站</li>
<li>恶意网站先通过请求上述所说的安全模块获取 <code>csrf_token</code></li>
<li>恶意网站构造隐藏的 <code>form</code> 表单并对参数进行伪造</li>
<li>利用 JS 自动提交(恶意网站是攻击者所有,所以绕过了 <code>XSS</code> 防御策略) <code>form</code> 并携带 <code>csrf_token</code> 给目标网站</li>
</ol>
<p>A:不会,因为浏览器的 <a href="https://zh.wikipedia.org/wiki/%E5%90%8C%E6%BA%90%E7%AD%96%E7%95%A5">同源策略</a> 不允许恶意网站获取安全模块所返回的结果(<code>csrf_token</code>),所以攻击在第 2 步时就会失败</p>
</li>
</ul>
<h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><p><a href="https://item.jd.com/11483966.html">白帽子讲Web安全</a></p>
<p><a href="https://zh.wikipedia.org/wiki/%E8%B7%A8%E7%AB%99%E8%AF%B7%E6%B1%82%E4%BC%AA%E9%80%A0">跨站请求伪造</a></p>
<p><a href="https://blog.csdn.net/XiaoBeiTu/article/details/102268639">CSRF - 前后端分离后带来的新问题</a></p>
]]></content>
<categories>
<category>安全</category>
</categories>
<tags>
<tag>think</tag>
<tag>csrf</tag>
</tags>
</entry>
<entry>
<title>构建自己的 rss 平台</title>
<url>/2023/04/build-own-rss-platform/</url>
<content><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>因为需要在微博关注一些财经博主的更新,但又不想登录微博,遂研究了如何构建自己的 rss 平台,汇总感兴趣的信息。并使用 telegram 作为 rss 阅读器。</p>
<span id="more"></span>
<h3 id="Install"><a href="#Install" class="headerlink" title="Install"></a>Install</h3><ol>
<li><p>安装 <a href="https://docs.rsshub.app/install/#docker-compose-bu-shu">RSSHub</a> 作为 rss 平台</p>
<pre class="line-numbers language-console" data-language="console"><code class="language-console">mkdir rsshub
cd rsshub
wget https://raw.githubusercontent.com/DIYgod/RSSHub/master/docker-compose.yml
docker volume create redis-data
docker compose up -d<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p> 更新</p>
<pre class="line-numbers language-console" data-language="console"><code class="language-console">docker compose down && docker compose pull && docker compose up -d<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
</li>
<li><p>安装 <a href="https://github.com/Rongronggg9/RSS-to-Telegram-Bot/blob/dev/docs/deployment-guide.md">RSS-to-Telegram-Bot</a> 以便从 telegram 上订阅 rss</p>
<pre class="line-numbers language-console" data-language="console"><code class="language-console">mkdir rsstt
cd rsstt
wget https://raw.githubusercontent.com/Rongronggg9/RSS-to-Telegram-Bot/dev/docker-compose.yml.sample -O docker-compose.yml
vi docker-compose.yml # fill in env variables
docker compose up -d<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p> 更新</p>
<pre class="line-numbers language-console" data-language="console"><code class="language-console">docker compose down && docker compose pull && docker compose up -d<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
</li>
</ol>
<h3 id="Setup"><a href="#Setup" class="headerlink" title="Setup"></a>Setup</h3><p>有三种使用方式</p>
<ol>
<li>直接使用 Bot 订阅所有 rss</li>
<li>将 Bot 添加到频道中,然后在频道中订阅 rss<ol>
<li>创建一个公开频道,并输入 《频道名》,比如 <code>test_rss_hub</code><br> <img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/2023/04/upgit_20230412_1681283739.png" alt="upgit_20230412_1681283739.png"></li>
<li>将 Bot 添加到频道中</li>
<li>私聊 Bot 发送 <code>/user_info @频道名</code>,比如 <code>/user_info @test_rss_hub</code></li>
<li>出现如下选项,点击 <code>将用户状态设置为“用户”</code><br> <img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/2023/04/upgit_20230412_1681283864.png" alt="upgit_20230412_1681283864.png"></li>
</ol>
</li>
<li>将 Bot 添加到群组中,然后在群组中订阅 rss<ol>
<li>步骤与添加至频道类似</li>
</ol>
</li>
</ol>
<p>Tips: 必须先将频道/群组设置为 public,这样才能设置 Bot 发送到指定频道/群组。如果需要私有频道/群组,只需要在设置完成将频道/群组转为 private 即可。</p>
]]></content>
<categories>
<category>其他</category>
</categories>
<tags>
<tag>rss</tag>
<tag>自建</tag>
</tags>
</entry>
<entry>
<title>使用 charles 调试</title>
<url>/2020/10/charles/</url>
<content><![CDATA[<h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><p><a href="https://www.charlesproxy.com/download/">点击去官网下载</a></p>
<h2 id="激活"><a href="#激活" class="headerlink" title="激活"></a>激活</h2><pre class="line-numbers language-none"><code class="language-none">Registered Name: https://zhile.io
License Key: 48891cf209c6d32bf4<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<span id="more"></span>
<h2 id="开启-http-调试"><a href="#开启-http-调试" class="headerlink" title="开启 http 调试"></a>开启 http 调试</h2><ol>
<li>点击菜单栏 <code>Proxy -> Proxy Settings</code></li>
<li>填写 <code>Port</code></li>
<li>勾选 <code>Enable transparent HTTP proxying</code></li>
</ol>
<p><img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20201009171421.png" alt="20201009171421"></p>
<h2 id="开启抓取-macOS-请求"><a href="#开启抓取-macOS-请求" class="headerlink" title="开启抓取 macOS 请求"></a>开启抓取 macOS 请求</h2><ol>
<li>点击菜单栏 <code>Proxy -> Proxy Settings</code></li>
<li>点击 <code>macOS</code></li>
<li>勾选 <code>Enable macOS proxy</code></li>
<li>勾选 <code>Use HTTP proxy</code></li>
</ol>
<p><img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20201009171951.png" alt="20201009171951"></p>
<h2 id="开启抓取-Android-请求"><a href="#开启抓取-Android-请求" class="headerlink" title="开启抓取 Android 请求"></a>开启抓取 Android 请求</h2><p>手机连接局域网下 wifi,与 charles 必须为同一网络下。</p>
<ol>
<li><p>自动开启代理</p>
<ol>
<li><p>在已连接的 wifi 上点击更多,进入配置代理页。</p>
</li>
<li><p>勾选自动,在输入框URL中输入:</p>
<pre class="line-numbers language-uri" data-language="uri"><code class="language-uri"><span class="token scheme">Https<span class="token scheme-delimiter">:</span></span><span class="token authority"><span class="token authority-delimiter">//</span><span class="token host">chls.pro</span></span><span class="token path"><span class="token path-separator">/</span>10.10.11.235:6666.pac</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
</li>
</ol>
</li>
<li><p>手动设置代理</p>
<ol>
<li>在已连接的 wifi 上点击更多,进入配置代理页。</li>
<li>勾选手动,输入 charles 的 ip 与端口(ip 为 macOS 主机 ip,端口为<a href="/2020/10/09/charles/#%E5%BC%80%E5%90%AF-http-%E8%B0%83%E8%AF%95">上面</a>填写的 http 端口)</li>
</ol>
</li>
</ol>
<h2 id="设置-https"><a href="#设置-https" class="headerlink" title="设置 https"></a>设置 https</h2><ol>
<li>点击 <code>Proxy -> SSL Proxying Settings</code><br> <img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20201009173147.png" alt="20201009173147"></li>
<li>勾选 <code>Enable SSL Proxying</code></li>
<li>点击 <code>Add</code>,Host 填写 <code>*</code>,Port 填写 <code>443</code><br> <img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20201009173256.png" alt="20201009173256"></li>
</ol>
<h3 id="macOS-安装证书"><a href="#macOS-安装证书" class="headerlink" title="macOS 安装证书"></a>macOS 安装证书</h3><ol>
<li>点击菜单栏 <code>Help -> SSL Proxying -> Install Charles Root Certificate</code><br> <img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20201009172253.png" alt="20201009172253"></li>
<li>找到 <code>Charles Proxy.....</code> 并点击</li>
<li>点击 <code>Trust -> When using this certificate</code>,并勾选 <code>Always Trust</code><br> <img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20201009172635.png" alt="20201009172635"></li>
</ol>
<h3 id="Android-安装证书"><a href="#Android-安装证书" class="headerlink" title="Android 安装证书"></a>Android 安装证书</h3><p>Android7 以后,系统不再信任用户级的证书,只信任系统级的证书,所以要抓包就需要把我们的 charles 证书安装至 Android 的系统目录中</p>
<h4 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h4><ol>
<li>一台已 root 的手机</li>
<li>Openssl</li>
</ol>
<h4 id="证书生成"><a href="#证书生成" class="headerlink" title="证书生成"></a>证书生成</h4><ol>
<li><p>将 <code>Filddler</code> 或者其他抓包程序的证书导出,一般为 <code>xxx.cer</code> 或者 <code>xxx.pem</code></p>
</li>
<li><p>使用 <code>openssl</code> 的 <code>x509</code> 指令进行 <code>cer</code> 证书转 <code>pem</code> 证书 和 用 <code>md5</code> 方式显示 <code>pem</code> 证书的 <code>hash</code> 值</p>
<pre class="line-numbers language-bash" data-language="bash"><code class="language-bash"><span class="token comment"># 1. 证书转换,已经是 pem 格式的证书不需要执行这一步</span>
openssl x509 <span class="token parameter variable">-inform</span> DER <span class="token parameter variable">-in</span> xxx.cer <span class="token parameter variable">-out</span> cacert.pem
<span class="token comment"># 2. 进行 MD5 的 hash 显示</span>
<span class="token comment"># openssl 版本在 1.0 以上的版本的执行这一句</span>
openssl x509 <span class="token parameter variable">-inform</span> PEM <span class="token parameter variable">-subject_hash_old</span> <span class="token parameter variable">-in</span> cacert.pem
<span class="token comment"># openssl 版本在 1.0 以下的版本的执行这一句</span>
openssl x509 <span class="token parameter variable">-inform</span> PEM <span class="token parameter variable">-subject_hash</span> <span class="token parameter variable">-in</span> cacert.pem<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p> 将第二条指令输出的类似 <code>347bacb5</code> 的值进行复制<br> <code>tips</code>:查看 <code>openssl</code> 版本的指令 <code>openssl version</code></p>
</li>
<li><p>将 pem 证书重命名<br> 使用上面复制的值(类似于 <code>347bacb5</code>)对 pem 证书进行重命名</p>
<pre class="line-numbers language-bash" data-language="bash"><code class="language-bash"><span class="token function">mv</span> cacert.pem 347bacb5.0<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
</li>
<li><p>将新证书放入手机系统证书目录(<code>/system/etc/security/cacerts</code>) </p>
<p> 需要拷贝至此目录必须拥有 root 权限</p>
</li>
<li><p>重启 Android 设备以生效<br> 拷贝证书至 <code>/system/etc/security/cacerts</code> 之后,重启手机就可以使证书生效了</p>
</li>
</ol>
<h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><p><a href="https://www.jianshu.com/p/9f4ebde9c518">charles 安装配置 for Mac</a></p>
<p><a href="https://blog.csdn.net/djzhao627/article/details/102812783">给 Android7 及以上的手机安装系统级证书,实现 Fiddler 或者其他程序的 HTTPS 的抓包</a></p>
]]></content>
<categories>
<category>测试</category>
</categories>
</entry>
<entry>
<title>chrome 为什么不会自动过期 expires 为 session 的 cookie</title>
<url>/2020/10/chrome-cookie-do-not-delete/</url>
<content><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>今天对自己的项目做前后端联调时,发现在 mac 的 chrome 下(未测试 windows)没有自动过期 expires 为 session 的 cookie,对此感到一些疑惑</p>
<span id="more"></span>
<h2 id="尝试"><a href="#尝试" class="headerlink" title="尝试"></a>尝试</h2><p>在网上搜索的时候,发现了 <a href="https://segmentfault.com/q/1010000011981273">这篇文章</a>,遂按照网友的解决方案,尝试了如下行为:</p>
<ol>
<li>点击作左上角 <code>x</code>,结果:<strong>无效</strong></li>
<li><code>Command + Q</code> 退出,结果:<strong>无效</strong></li>
<li>右键 <code>Chrome</code> 图标退出,结果:<strong>无效</strong></li>
</ol>
<p>很难受,网友提供的方法都无效</p>
<h2 id="解决"><a href="#解决" class="headerlink" title="解决"></a>解决</h2><ol>
<li>点击 chrome <code>设置</code></li>
<li><code>默认浏览器</code> -> <code>启动时</code> -> 取消勾选 <code>继续浏览上次打开的网页</code>,勾选其他两个选项</li>
</ol>
<h2 id="原因"><a href="#原因" class="headerlink" title="原因"></a>原因</h2><p>为了增强用户体验,chrome 会在 <code>继续浏览上次打开的网页</code> 设置下,默认不删除会话 cookie</p>
]]></content>
<categories>
<category>其他</category>
</categories>
<tags>
<tag>chrome</tag>
</tags>
</entry>
<entry>
<title>使用 Cloudflare Tunnels 进行内网穿透</title>
<url>/2023/01/cloudflare-tunnels/</url>
<content><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p><a href="https://www.cloudflare.com/products/tunnel/">Cloudflare Tunnel</a> 是一款隧道软件,可以快速安全地加密应用程序到任何类型基础设施的流量,让您能够隐藏你的web 服务器IP 地址,阻止直接攻击,从而专注于提供出色的应用程序。 </p>
<p>相比于 <a href="https://github.com/fatedier/frp">frp</a> 等做内网穿透,Cloudflare Tunnels 的优势是不需要一台额外的公网服务器转发,并且可以享受到 Cloudflare CDN 带来的便利。</p>
<span id="more"></span>
<p>使用 frp 做内网穿透的流程如下:</p>
<pre class="mermaid">
flowchart LR
server[Frp Server]
clients[Frp Clients]
User -->|http/https| server -->|http/https| clients
</pre>
<p>使用 Cloudflare Tunnels 做内网穿透的流程如下:</p>
<pre class="mermaid">
flowchart LR
tunnels[Cloudflare CDN]
clients[Original Clients]
User -->|http/https| tunnels -->|Cloudflare Tunnels|clients
</pre>
<h3 id="前置条件"><a href="#前置条件" class="headerlink" title="前置条件"></a>前置条件</h3><p>需要有一个由 Cloudflare 管理的域名</p>
<h3 id="配置"><a href="#配置" class="headerlink" title="配置"></a>配置</h3><ol>
<li><p>安装 <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/installation/">cloudflared</a></p>
<p>debian: </p>
<pre class="line-numbers language-console" data-language="console"><code class="language-console">apt install cloudflared<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>或者下载最新版</p>
<pre class="line-numbers language-console" data-language="console"><code class="language-console">wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb -O cloudflared.deb && dpkg -i cloudflared.deb && rm cloudflared.deb<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
</li>
<li><p>登录 cloudflared</p>
<pre class="line-numbers language-console" data-language="console"><code class="language-console">cloudflared tunnel login<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>随后会生成一个 <code>~/.cloudflared/cert.pem</code> 文件用于后续授权</p>
</li>
<li><p>创建一个隧道 tunnel</p>
<pre class="line-numbers language-console" data-language="console"><code class="language-console">cloudflared tunnel create <名字><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>随后会在 <code>~/.cloudflared/</code> 目录下出现一个 json 文件 <code>[Tunnel-UUID].json</code>,里面保存着运行这条隧道所需要的授权信息。</p>
</li>
<li><p>创建一个配置文件,<code>~/.cloudflared/tunnels/名字.yaml</code>,并添加</p>
<pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token comment"># 反代的源站地址</span>
<span class="token key atrule">url</span><span class="token punctuation">:</span> http<span class="token punctuation">:</span>//localhost<span class="token punctuation">:</span><span class="token number">8080</span>
<span class="token key atrule">tunnel</span><span class="token punctuation">:</span> <Tunnel<span class="token punctuation">-</span>UUID<span class="token punctuation">></span>
<span class="token key atrule">credentials-file</span><span class="token punctuation">:</span> /root/.cloudflared/<Tunnel<span class="token punctuation">-</span>UUID<span class="token punctuation">></span>.json<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<p>如果在上一步没有保存 UUID 信息,可以通过 <code>cloudflared tunnel info</code> 获取</p>
</li>
<li><p>配置路由</p>
<pre class="line-numbers language-console" data-language="console"><code class="language-console">cloudflared tunnel route dns [名字或者 Tunnel-UUID] [想要绑定到的域名或其二级域名]<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
</li>
<li><p>启动 <code>cloudflared</code></p>
<pre class="line-numbers language-console" data-language="console"><code class="language-console">cloudflared tunnel --config ~/.cloudflared/tunnels/名字.yaml run<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
</li>
</ol>
<p>之后就可以通过在第 5 步 设置的域名进行访问</p>
<h4 id="范例"><a href="#范例" class="headerlink" title="范例"></a>范例</h4><p>例如,创建一条隧道从公网访问家里的 clash dashboard(地址为 192.168.1.1:9090),设置隧道名字为 clash,并将其绑定到 clash.example.com:</p>
<ol>
<li><p><code>cloudflared tunnel login</code> 授权</p>
</li>
<li><p><code>cloudflared tunnel create clash</code>,假设输出 Tunnel-UUID 为 <code>c91c37a3-3efd-47fb-af0d-e5676ac122b9</code></p>
</li>
<li><p>将下面配置添加到 <code>~/.cloudflared/tunnels/clash.yaml</code></p>
<pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">url</span><span class="token punctuation">:</span> http<span class="token punctuation">:</span>//192.168.1.1<span class="token punctuation">:</span><span class="token number">9090</span>
<span class="token key atrule">tunnel</span><span class="token punctuation">:</span> c91c37a3<span class="token punctuation">-</span>3efd<span class="token punctuation">-</span>47fb<span class="token punctuation">-</span>af0d<span class="token punctuation">-</span>e5676ac122b9
<span class="token key atrule">credentials-file</span><span class="token punctuation">:</span> /root/.cloudflared/c91c37a3<span class="token punctuation">-</span>3efd<span class="token punctuation">-</span>47fb<span class="token punctuation">-</span>af0d<span class="token punctuation">-</span>e5676ac122b9.json<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
</li>
<li><p><code>cloudflared tunnel route dns clash clash.example.com</code> 创建路由</p>
</li>
<li><p><code>cloudflared tunnel --config ~/.cloudflared/tunnels/clash.yaml run</code> 启动隧道</p>
</li>
</ol>
<p>此时,访问 <code>clash.example.com</code> 等同于内网访问 <code>192.168.1.1:9090</code></p>
<h3 id="配置-systemd-service-自动启动"><a href="#配置-systemd-service-自动启动" class="headerlink" title="配置 systemd service 自动启动"></a>配置 systemd service 自动启动</h3><ol>
<li><p>在 <code>/etc/systemd/system</code> 目录下创建 service 配置文件 <code>EXAMPLE.service</code></p>
<pre class="line-numbers language-systemd" data-language="systemd"><code class="language-systemd"><span class="token section"><span class="token punctuation">[</span><span class="token section-name selector">Unit</span><span class="token punctuation">]</span></span>
<span class="token key attr-name">Description</span><span class="token punctuation">=</span><span class="token value attr-value">Cloudflare Tunnel</span>
<span class="token key attr-name">After</span><span class="token punctuation">=</span><span class="token value attr-value">network.target</span>
<span class="token key attr-name">StartLimitIntervalSec</span><span class="token punctuation">=</span><span class="token value attr-value">0</span>
<span class="token section"><span class="token punctuation">[</span><span class="token section-name selector">Service</span><span class="token punctuation">]</span></span>
<span class="token key attr-name">Type</span><span class="token punctuation">=</span><span class="token value attr-value">simple</span>
<span class="token key attr-name">Restart</span><span class="token punctuation">=</span><span class="token value attr-value">always</span>
<span class="token key attr-name">RestartSec</span><span class="token punctuation">=</span><span class="token value attr-value">1</span>
<span class="token key attr-name">User</span><span class="token punctuation">=</span><span class="token value attr-value">root</span>
<span class="token key attr-name">ExecStart</span><span class="token punctuation">=</span><span class="token value attr-value">cloudflared tunnel --config /root/.cloudflared/tunnels/名字.yaml run</span>
<span class="token section"><span class="token punctuation">[</span><span class="token section-name selector">Install</span><span class="token punctuation">]</span></span>
<span class="token key attr-name">WantedBy</span><span class="token punctuation">=</span><span class="token value attr-value">multi-user.target</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
</li>
<li><p>启动服务</p>
<pre class="line-numbers language-console" data-language="console"><code class="language-console">systemctl enable EXAMPLE
systemctl start EXAMPLE<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
</li>
</ol>
]]></content>
<categories>
<category>网络</category>
</categories>
<tags>
<tag>cloudflare</tag>
<tag>内网穿透</tag>
</tags>
</entry>
<entry>
<title>使用 Cloudflare Workers 反代 gist</title>
<url>/2020/12/cloudflare-workers/</url>
<content><![CDATA[<p>我经常用 GitHub 的 gist 服务来保存一些比较优秀的代码片段、配置等等,但是苦于 gist 在国内遭受了 DNS 污染,访问太不便利,所以一直在寻求一个类似 jsdelivr 加速 GitHub Repo 的方式,能够避免修改 host 直接访问 gist</p>
<span id="more"></span>
<h2 id="可行的方式"><a href="#可行的方式" class="headerlink" title="可行的方式"></a>可行的方式</h2><ol>
<li><a href="https://raw.githack.com/#no-uptime-guarantee">raw.githack.com</a></li>
<li>反代加速</li>
</ol>
<p>首先说说第一种,raw.githack.com 确实可以加速 gist,而且可以加速 repo。<br>使用方式很简单</p>
<ul>
<li>将 gist.githubusercontent.com 替换为 gistcdn.githack.com<br>例:<a href="http://gistcdn.githack.com/jiz4oh/189ed96ca1607b3ddf07bd64bcb459cd/raw/trojan.json">http://gistcdn.githack.com/jiz4oh/189ed96ca1607b3ddf07bd64bcb459cd/raw/trojan.json</a></li>
<li>将 raw.githubusercontent.com 替换为 rawcdn.githack.com<br>例:<a href="https://rawcdn.githack.com/jiz4oh/vim/master/vimrc">https://rawcdn.githack.com/jiz4oh/vim/master/vimrc</a></li>
</ul>
<p>但是这种方式有一点弊端,就是不方便发表永链,当首次访问时,githack 会将内容缓存在 cloudflare 长达一年。当链接内容变化时,不会及时刷新,只适合发布永久内容,或者分版本发布。</p>
<p>第二种方式就是我经过一段时间摸索并决定采用的方式</p>
<h2 id="Cloudflare-Workers"><a href="#Cloudflare-Workers" class="headerlink" title="Cloudflare Workers"></a>Cloudflare Workers</h2><p>Workers 的工作原理就是最近几年火热的 serverless。网站管理员不再一定需要一个服务器,只需要将对应的 Function 托管在 Workers 上,当用户访问网站时就会执行对应的 Function,值得一提的是 Cloudflare Workers 本质上只支持 JS(<a href="https://developers.cloudflare.com/workers/platform/languages">其他语言通过编译成 js 来执行</a>)。</p>
<h3 id="前期准备"><a href="#前期准备" class="headerlink" title="前期准备"></a>前期准备</h3><ol>
<li>cloudflare 的帐号</li>
<li>域名,并且托管到 cloudflare</li>
</ol>
<h3 id="创建-worker"><a href="#创建-worker" class="headerlink" title="创建 worker"></a>创建 worker</h3><ol>
<li><p>登录帐号到下图界面</p>
<p> <img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20201227143715.png" alt="20201227143715"></p>
</li>
<li><p>然后进入 Workers</p>
<p> <img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20201227143837.png" alt="20201227143837"></p>
</li>
<li><p>点击创建 worker</p>
<p> <img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20201227144011.png" alt="20201227144011"></p>
</li>
<li><p>这时候会进入如下界面</p>
<p> <img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20201227144908.png" alt="20201227144908"></p>
</li>
</ol>
<p>反代加速 gist 代码如下:</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 需要反代的地址</span>
<span class="token keyword">const</span> upstream <span class="token operator">=</span> <span class="token string">'gist.github.com'</span>
<span class="token comment">// 反代地址的子路径</span>
<span class="token keyword">const</span> upstreamPath <span class="token operator">=</span> <span class="token string">'/'</span>
<span class="token comment">// 反代网站的移动端域名</span>
<span class="token keyword">const</span> upstreamMobile <span class="token operator">=</span> <span class="token string">'gist.github.com'</span>
<span class="token comment">// 是否使用 https</span>
<span class="token keyword">const</span> useHttps <span class="token operator">=</span> <span class="token boolean">true</span>
<span class="token comment">// 禁止使用该 worker 的国家代码</span>
<span class="token keyword">const</span> blockedRegion <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'KP'</span><span class="token punctuation">,</span> <span class="token string">'SY'</span><span class="token punctuation">,</span> <span class="token string">'PK'</span><span class="token punctuation">,</span> <span class="token string">'CU'</span><span class="token punctuation">]</span>
<span class="token comment">// 禁止使用该 worker 的 ip 地址</span>
<span class="token keyword">const</span> blockedIp <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'0.0.0.0'</span><span class="token punctuation">,</span> <span class="token string">'127.0.0.1'</span><span class="token punctuation">]</span>
<span class="token comment">// 是否关闭缓存</span>
<span class="token keyword">const</span> disableCache <span class="token operator">=</span> <span class="token boolean">false</span>
<span class="token comment">// 替换条件</span>
<span class="token keyword">const</span> contentTypes <span class="token operator">=</span> <span class="token punctuation">[</span>
<span class="token string">'text/plain'</span><span class="token punctuation">,</span>
<span class="token string">'text/html'</span>
<span class="token punctuation">]</span>
<span class="token comment">// 反代网站中其他需要被替换的地址</span>
<span class="token keyword">const</span> replaceDict <span class="token operator">=</span> <span class="token punctuation">{</span>
<span class="token string-property property">'$upstream'</span><span class="token operator">:</span> <span class="token string">'$workerDomain'</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
<span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'fetch'</span><span class="token punctuation">,</span> <span class="token parameter">event</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
event<span class="token punctuation">.</span><span class="token function">respondWith</span><span class="token punctuation">(</span><span class="token function">handleRequest</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>request<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token comment">/**
* Respond to the request
* @param {Request} request
*/</span>
<span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">handleRequest</span><span class="token punctuation">(</span><span class="token parameter">request</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> region <span class="token operator">=</span> request<span class="token punctuation">.</span>headers<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">'cf-ipcountry'</span><span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token string">''</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> ip <span class="token operator">=</span> request<span class="token punctuation">.</span>headers<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">'cf-connecting-ip'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>blockedRegion<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>region<span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Response</span><span class="token punctuation">(</span><span class="token string">'Access denied: WorkersProxy is not available in your region yet.'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
<span class="token literal-property property">status</span><span class="token operator">:</span> <span class="token number">403</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>blockedIp<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>ip<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Response</span><span class="token punctuation">(</span><span class="token string">'Access denied: Your IP address is blocked by WorkersProxy.'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
<span class="token literal-property property">status</span><span class="token operator">:</span> <span class="token number">403</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">const</span> upstreamDomain <span class="token operator">=</span> <span class="token function">isMobile</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span>headers<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">'user-agent'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">?</span> upstreamMobile <span class="token operator">:</span> upstream<span class="token punctuation">;</span>
<span class="token comment">// 构建上游请求地址</span>
<span class="token keyword">let</span> url <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">URL</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span>url<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> workerDomain <span class="token operator">=</span> url<span class="token punctuation">.</span>host<span class="token punctuation">;</span>
url<span class="token punctuation">.</span>protocol <span class="token operator">=</span> useHttps <span class="token operator">?</span> <span class="token string">'https:'</span> <span class="token operator">:</span> <span class="token string">'http'</span><span class="token punctuation">;</span>
url<span class="token punctuation">.</span>pathname <span class="token operator">=</span> url<span class="token punctuation">.</span>pathname <span class="token operator">===</span> <span class="token string">'/'</span> <span class="token operator">?</span> upstreamPath <span class="token operator">:</span> upstreamPath <span class="token operator">+</span> url<span class="token punctuation">.</span>pathname<span class="token punctuation">;</span>
url<span class="token punctuation">.</span>host <span class="token operator">=</span> upstreamDomain<span class="token punctuation">;</span>
<span class="token comment">// 构建上游请求头</span>
<span class="token keyword">const</span> newRequestHeaders <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Headers</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span>headers<span class="token punctuation">)</span><span class="token punctuation">;</span>
newRequestHeaders<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">'Host'</span><span class="token punctuation">,</span> upstreamDomain<span class="token punctuation">)</span><span class="token punctuation">;</span>
newRequestHeaders<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">'Referer'</span><span class="token punctuation">,</span> url<span class="token punctuation">.</span>protocol <span class="token operator">+</span> <span class="token string">'//'</span> <span class="token operator">+</span> workerDomain<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 获取上游响应</span>
<span class="token keyword">const</span> originalResponse <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span><span class="token punctuation">(</span>url<span class="token punctuation">.</span>href<span class="token punctuation">,</span> <span class="token punctuation">{</span>
<span class="token literal-property property">method</span><span class="token operator">:</span> request<span class="token punctuation">.</span>method<span class="token punctuation">,</span>
<span class="token literal-property property">headers</span><span class="token operator">:</span> newRequestHeaders
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">const</span> connectionUpgrade <span class="token operator">=</span> newRequestHeaders<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"Upgrade"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>connectionUpgrade <span class="token operator">&&</span> connectionUpgrade<span class="token punctuation">.</span><span class="token function">toLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">===</span> <span class="token string">"websocket"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> originalResponse<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">let</span> originalResponseClone <span class="token operator">=</span> originalResponse<span class="token punctuation">.</span><span class="token function">clone</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 构建响应头</span>
<span class="token keyword">let</span> responseHeaders <span class="token operator">=</span> originalResponseClone<span class="token punctuation">.</span>headers<span class="token punctuation">;</span>
<span class="token keyword">let</span> newResponseHeaders <span class="token operator">=</span> <span class="token function">buildResponseHeaders</span><span class="token punctuation">(</span>responseHeaders<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>newResponseHeaders<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"x-pjax-url"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
newResponseHeaders<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"x-pjax-url"</span><span class="token punctuation">,</span> responseHeaders<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"x-pjax-url"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token string">"//"</span> <span class="token operator">+</span> upstreamDomain<span class="token punctuation">,</span> <span class="token string">"//"</span> <span class="token operator">+</span> workerDomain<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// 构建响应体</span>
<span class="token keyword">let</span> originalText<span class="token punctuation">;</span>
<span class="token keyword">const</span> contentType <span class="token operator">=</span> newResponseHeaders<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">'content-type'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>contentType <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> types <span class="token operator">=</span> contentType<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token string">' '</span><span class="token punctuation">,</span><span class="token string">''</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">';'</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>types<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span><span class="token string">'charset=utf-8'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token keyword">of</span> contentTypes<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>types<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
originalText <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">replaceResponseText</span><span class="token punctuation">(</span>originalResponseClone<span class="token punctuation">,</span> upstreamDomain<span class="token punctuation">,</span> workerDomain<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">break</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
originalText <span class="token operator">=</span> originalResponseClone<span class="token punctuation">.</span>body
<span class="token punctuation">}</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Response</span><span class="token punctuation">(</span>originalText<span class="token punctuation">,</span> <span class="token punctuation">{</span>
<span class="token literal-property property">status</span><span class="token operator">:</span> originalResponseClone<span class="token punctuation">.</span>status<span class="token punctuation">,</span>
<span class="token literal-property property">headers</span><span class="token operator">:</span> newResponseHeaders
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">function</span> <span class="token function">isMobile</span><span class="token punctuation">(</span><span class="token parameter">userAgent</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
userAgent <span class="token operator">=</span> userAgent <span class="token operator">||</span> <span class="token string">''</span>
<span class="token keyword">let</span> agents <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"Android"</span><span class="token punctuation">,</span> <span class="token string">"iPhone"</span><span class="token punctuation">,</span> <span class="token string">"SymbianOS"</span><span class="token punctuation">,</span> <span class="token string">"Windows Phone"</span><span class="token punctuation">,</span> <span class="token string">"iPad"</span><span class="token punctuation">,</span> <span class="token string">"iPod"</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> v <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> v <span class="token operator"><</span> agents<span class="token punctuation">.</span>length<span class="token punctuation">;</span> v<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>userAgent<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span>agents<span class="token punctuation">[</span>v<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">function</span> <span class="token function">buildResponseHeaders</span><span class="token punctuation">(</span><span class="token parameter">originalHeaders</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> result <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Headers</span><span class="token punctuation">(</span>originalHeaders<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>disableCache<span class="token punctuation">)</span> <span class="token punctuation">{</span>
result<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">'Cache-Control'</span><span class="token punctuation">,</span> <span class="token string">'no-store'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
result<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">'access-control-allow-origin'</span><span class="token punctuation">,</span> <span class="token string">'*'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
result<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">'access-control-allow-credentials'</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
result<span class="token punctuation">.</span><span class="token function">delete</span><span class="token punctuation">(</span><span class="token string">'content-security-policy'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
result<span class="token punctuation">.</span><span class="token function">delete</span><span class="token punctuation">(</span><span class="token string">'content-security-policy-report-only'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
result<span class="token punctuation">.</span><span class="token function">delete</span><span class="token punctuation">(</span><span class="token string">'clear-site-data'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> result
<span class="token punctuation">}</span>
<span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">replaceResponseText</span><span class="token punctuation">(</span><span class="token parameter">response<span class="token punctuation">,</span> upstreamDomain<span class="token punctuation">,</span> workerDomain</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">let</span> text <span class="token operator">=</span> <span class="token keyword">await</span> response<span class="token punctuation">.</span><span class="token function">text</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">const</span> placeholders <span class="token operator">=</span> <span class="token punctuation">{</span>
<span class="token string-property property">"$upstream"</span><span class="token operator">:</span> upstreamDomain<span class="token punctuation">,</span>
<span class="token string-property property">"$workerDomain"</span><span class="token operator">:</span> workerDomain
<span class="token punctuation">}</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> origin <span class="token keyword">in</span> replaceDict<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">let</span> target <span class="token operator">=</span> replaceDict<span class="token punctuation">[</span>origin<span class="token punctuation">]</span>
origin <span class="token operator">=</span> placeholders<span class="token punctuation">[</span>origin<span class="token punctuation">]</span> <span class="token operator">||</span> origin
target <span class="token operator">=</span> placeholders<span class="token punctuation">[</span>target<span class="token punctuation">]</span> <span class="token operator">||</span> target
<span class="token keyword">const</span> re <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">RegExp</span><span class="token punctuation">(</span>origin<span class="token punctuation">,</span> <span class="token string">'g'</span><span class="token punctuation">)</span>
text <span class="token operator">=</span> text<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span>re<span class="token punctuation">,</span> target<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> text<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>然后点击部署,就可以通过 <code>[project].[subdomain].workers.dev</code> 绕墙访问 gist 了,理论上是可以反代所有网站的,如果有需求的话,各位请自行修改代码~</p>
<p>注:</p>
<ol>
<li>project 是创建的 worker 的名称</li>
<li>subdomain 是注册 workers 是输入的名字</li>
</ol>
<h3 id="自定义域名(可选)"><a href="#自定义域名(可选)" class="headerlink" title="自定义域名(可选)"></a>自定义域名(可选)</h3><p>经过上面的步骤,我们已经可以使用类似于 <code>test.baidu.workers.dev</code> 这样的域名使用触发 worker 了。但是如果需要使用自定义域名代替上述域名的话,还需要额外设置</p>
<p>ps:刚开始我以为直接在 DNS 中 CNAME 到 workers.dev 就行,但是实际操作之后发现是不可以的。</p>
<p>例如我们需要配置一个 test.jiz4oh.com 域名来使用 worker</p>
<ol>
<li><p>配置 DNS 解析</p>
<p> <img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20201227180432.png" alt="20201227180432"></p>
</li>
<li><p>设置 worker 路由</p>
<p> <img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20201227180558.png" alt="20201227180558"></p>
<p> <img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20201227180837.png" alt="20201227180837"></p>
</li>
<li><p>等待数分钟,此时就可以访问 <code>test.jiz4oh.com</code> 来使用 worker 了</p>
</li>
</ol>
]]></content>
<categories>
<category>其他</category>
</categories>
<tags>
<tag>cloudflare</tag>
<tag>freebie</tag>
</tags>
</entry>
<entry>
<title>Github+PicGo+Jsdelivr 创建个人图床</title>
<url>/2020/09/github-picgo-jsdelivr/</url>
<content><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>图床相信经常写东西而且文章图文并茂的朋友多多少少都接触过</p>
<p>公共图床服务要不就是备案麻烦,要不就是免费不稳定</p>
<p>本文就是关于如何利用 Github+Jsdelivr 创建免费、大容量、高速的个人图床,并且利用 vscode+PicGo 实现图片自动上传</p>
<span id="more"></span>
<h2 id="创建-GitHub-仓库"><a href="#创建-GitHub-仓库" class="headerlink" title="创建 GitHub 仓库"></a>创建 GitHub 仓库</h2><p><img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups/img/20200925204037.png" alt="20200925204037"></p>
<p>仓库名随意</p>
<h3 id="生成-Token"><a href="#生成-Token" class="headerlink" title="生成 Token"></a>生成 Token</h3><ol>
<li>点击个人设置<br> <img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20200926180107.png" alt="20200926180107"></li>
<li>点击开发者设置<br> <img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20200926180238.png" alt="20200926180238"></li>
<li>点击个人令牌<br> <img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20200926180349.png" alt="20200926180349"></li>
<li>创建令牌<br> <img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20200926180428.png" alt="20200926180428"></li>
<li>保存命令<br> <img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20200926180540.png" alt="20200926180540"></li>
</ol>
<h2 id="配置-PicGo"><a href="#配置-PicGo" class="headerlink" title="配置 PicGo"></a>配置 PicGo</h2><h3 id="vocode-安装-PicGo"><a href="#vocode-安装-PicGo" class="headerlink" title="vocode 安装 PicGo"></a>vocode 安装 PicGo</h3><p>扩展搜索 <code>picgo</code></p>
<p><img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20200926180638.png" alt="20200926180638"></p>
<h3 id="配置"><a href="#配置" class="headerlink" title="配置"></a>配置</h3><p>打开 vscode 设置</p>
<p><img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20200926180821.png" alt="20200926180821"></p>
<p>点开 <code>扩展</code> => <code>PicGo</code></p>
<p><img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20200926181037.png" alt="20200926181037"></p>
<p>具体配置:</p>
<p><img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20200926181331.png" alt="20200926181331"></p>
<ol>
<li>选择 github</li>
<li>一般选择 master,如果<strong>不需要</strong>发布到其他分支<strong>不要</strong>更改</li>
<li>存入 vscode 的链接地址<ul>
<li>使用 jsdelivr:<code>https://cdn.jsdelivr.net/gh/红框5处内容</code> </li>
<li>使用 rawgithubcontent:<code>https://raw.githubusercontent.com/红框5处内容/红框2处内容</code></li>
</ul>
</li>
<li>存入 GitHub 仓库的子文件夹,可为空</li>
<li>仓库名,格式为 <code>用户名/仓库名</code></li>
<li>之前生成的 Github Token</li>
</ol>
<h2 id="使用中的问题"><a href="#使用中的问题" class="headerlink" title="使用中的问题"></a>使用中的问题</h2><p>描述:jsdelivr 无法加速,显示 <code>Package size exceeded the configured limit of 50 MB</code> </p>
<p>问题原因:jsdelivr 对每一个 release 限制加速 50MB</p>
<p>解决方案:</p>
<ol>
<li>进入仓库</li>
<li>创建 release<br> <img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20200926182953.png" alt="20200926182953"></li>
<li>创建 master 版本<br> <img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20200926183104.png" alt="20200926183104"></li>
<li>修改 PicGo 设置 Custom Url<br> 在最后面添加 <code>@master</code> 指定版本号</li>
<li>修改被拒绝显示的链接,在仓库名后面添加 <code>@master</code>。之前 jsdelivr 加速成功的链接不受影响</li>
</ol>
]]></content>
<categories>
<category>其他</category>
</categories>
<tags>
<tag>vscode</tag>
<tag>github</tag>
<tag>白嫖</tag>
</tags>
</entry>
<entry>
<title>Hexo 博客搭建过程实录</title>
<url>/2020/09/hello-hexo/</url>
<content><![CDATA[<h2 id="创建本地博客-blog"><a href="#创建本地博客-blog" class="headerlink" title="创建本地博客 blog"></a>创建本地博客 blog</h2><h3 id="安装-Hexo-脚手架"><a href="#安装-Hexo-脚手架" class="headerlink" title="安装 Hexo 脚手架"></a>安装 Hexo 脚手架</h3><pre class="line-numbers language-bash" data-language="bash"><code class="language-bash"><span class="token function">npm</span> <span class="token function">install</span> <span class="token parameter variable">-g</span> hexo-cli<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>安装之后可以使用 hexo 对博客命令操作</p>
<ol>
<li>创建 blog:<code>hexo init 文件夹</code></li>
<li>创建文章:<code>hexo new 文章名</code></li>
<li>生成静态文件:<code>hexo generate</code> 简写:<code>hexo g</code></li>
<li>清除已生成缓存:<code>hexo clean</code></li>
<li>启动本地服务:<code>hexo server</code> 简写:<code>hexo s</code><br> 默认监听 4000 端口</li>
<li>部署:<code>hexo deploy</code> 简写:<code>hexo d</code></li>
<li>生成静态文件并部署:<code>hexo g -d</code></li>
</ol>
<span id="more"></span>
<h3 id="创建博客"><a href="#创建博客" class="headerlink" title="创建博客"></a>创建博客</h3><pre class="line-numbers language-bash" data-language="bash"><code class="language-bash">hexo init blog
<span class="token builtin class-name">cd</span> blog
hexo g
hexo s<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<p>访问 <a href="http://localhost:4000/">http://localhost:4000</a> 查看本地博客</p>
<h2 id="配置-blog-部署-Github-Pages"><a href="#配置-blog-部署-Github-Pages" class="headerlink" title="配置 blog 部署 Github Pages"></a>配置 blog 部署 Github Pages</h2><h3 id="创建-github-io-仓库"><a href="#创建-github-io-仓库" class="headerlink" title="创建 github.io 仓库"></a>创建 github.io 仓库</h3><p><img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups/img/20200925204037.png" alt="20200925204037"></p>
<p>输入仓库名,仓库名以用户名开头,以 <code>github.io</code> 结尾 </p>
<p><img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups/img/20200925204246.png" alt="20200925204246"></p>
<h3 id="修改部署文件"><a href="#修改部署文件" class="headerlink" title="修改部署文件"></a>修改部署文件</h3><ol>
<li><p>创建成功后,打开刚刚使用 <code>hexo init blog</code> 命令生成的 blog 文件夹</p>
</li>
<li><p>修改 <code>_config.yml</code> 文件<br><img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups/img/20200925203757.png" alt="20200925203757"><br>repo 填入刚刚创建的 GitHub 仓库地址,建议填写 ssh 仓库地址,https 地址也可</p>
</li>
<li><p>部署到 Github Pages</p>
<pre class="line-numbers language-bash" data-language="bash"><code class="language-bash"><span class="token comment"># 清理缓存</span>
hexo clean
<span class="token comment"># 部署</span>
hexo g <span class="token parameter variable">-d</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
</li>
</ol>
<h2 id="GitHub-Actions-自动部署"><a href="#GitHub-Actions-自动部署" class="headerlink" title="GitHub Actions 自动部署"></a>GitHub Actions 自动部署</h2><h3 id="创建-blog-仓库"><a href="#创建-blog-仓库" class="headerlink" title="创建 blog 仓库"></a>创建 blog 仓库</h3><p>创建另外一个 GitHub 私有仓库 blog,用来存放 hexo 项目并触发部署</p>
<h3 id="创建-ssh-密钥"><a href="#创建-ssh-密钥" class="headerlink" title="创建 ssh 密钥"></a>创建 ssh 密钥</h3><pre class="line-numbers language-bash" data-language="bash"><code class="language-bash">ssh-keygen <span class="token parameter variable">-f</span> .ssh/github-deploy-key<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>.ssh 文件夹下会有 github-deploy-key 和 github-deploy-key.pub 两个文件。</p>
<h3 id="配置部署密钥"><a href="#配置部署密钥" class="headerlink" title="配置部署密钥"></a>配置部署密钥</h3><ol>
<li>打开 blog 仓库设置,Settings -> Secrets -> Add a new secret<br> <img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups/img/20200925210741.png" alt="20200925210741"><ul>
<li>在 Name 输入框填写 HEXO_DEPLOY_KEY。</li>
<li>在 Value 输入框填写 github-deploy-key 文件内容。</li>
</ul>
</li>
<li>打开 用户名.github.io 仓库设置,<br> <img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups/img/20200925211312.png" alt="20200925211312"><ul>
<li>在 Title 输入框填写 HEXO_DEPLOY_PUB。</li>
<li>在 Key 输入框填写 github-deploy-key.pub 文件内容。</li>
<li>勾选 Allow write access 选项。</li>
</ul>
</li>
</ol>
<h3 id="编写-GitHub-Actions"><a href="#编写-GitHub-Actions" class="headerlink" title="编写 GitHub Actions"></a>编写 GitHub Actions</h3><p>在 hexo 博客文件夹下创建 .github/workflows/deploy.yml 文件,目录结构如下:</p>
<pre class="line-numbers language-bash" data-language="bash"><code class="language-bash">blog
└── .github
└── workflows
└── deploy.yml<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<p>编辑 deploy.yml 文件:</p>
<pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">name</span><span class="token punctuation">:</span> Deploy GitHub Pages
<span class="token key atrule">on</span><span class="token punctuation">:</span>
<span class="token key atrule">push</span><span class="token punctuation">:</span>
<span class="token key atrule">branches</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> master
<span class="token comment"># 修改 GitHub 用户名及邮箱才能正确部署</span>
<span class="token key atrule">env</span><span class="token punctuation">:</span>
<span class="token key atrule">GIT_USER</span><span class="token punctuation">:</span> jiz4oh
<span class="token key atrule">GIT_EMAIL</span><span class="token punctuation">:</span> [email protected]
<span class="token key atrule">jobs</span><span class="token punctuation">:</span>
<span class="token key atrule">build-and-deploy</span><span class="token punctuation">:</span>
<span class="token key atrule">runs-on</span><span class="token punctuation">:</span> ubuntu<span class="token punctuation">-</span>latest
<span class="token key atrule">strategy</span><span class="token punctuation">:</span>
<span class="token key atrule">matrix</span><span class="token punctuation">:</span>
<span class="token key atrule">node-version</span><span class="token punctuation">:</span> <span class="token punctuation">[</span> 10.x <span class="token punctuation">]</span>
<span class="token key atrule">steps</span><span class="token punctuation">:</span>
<span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Checkout
<span class="token key atrule">uses</span><span class="token punctuation">:</span> actions/checkout@v2
<span class="token key atrule">with</span><span class="token punctuation">:</span>
<span class="token key atrule">persist-credentials</span><span class="token punctuation">:</span> <span class="token boolean important">false</span>
<span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Use Node.js $<span class="token punctuation">{</span><span class="token punctuation">{</span> matrix.node<span class="token punctuation">-</span>version <span class="token punctuation">}</span><span class="token punctuation">}</span>
<span class="token key atrule">uses</span><span class="token punctuation">:</span> actions/setup<span class="token punctuation">-</span>node@v1
<span class="token key atrule">with</span><span class="token punctuation">:</span>
<span class="token key atrule">node-version</span><span class="token punctuation">:</span> $<span class="token punctuation">{</span><span class="token punctuation">{</span> matrix.node<span class="token punctuation">-</span>version <span class="token punctuation">}</span><span class="token punctuation">}</span>
<span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Configuration environment
<span class="token key atrule">env</span><span class="token punctuation">:</span>
<span class="token key atrule">HEXO_DEPLOY_PRI</span><span class="token punctuation">:</span> $<span class="token punctuation">{</span><span class="token punctuation">{</span>secrets.HEXO_DEPLOY_KEY<span class="token punctuation">}</span><span class="token punctuation">}</span>
<span class="token key atrule">run</span><span class="token punctuation">:</span> <span class="token punctuation">|</span><span class="token scalar string">
mkdir -p ~/.ssh/
echo "$HEXO_DEPLOY_PRI" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan github.com >> ~/.ssh/known_hosts
git config --global user.name $GIT_USER
git config --global user.email $GIT_EMAIL</span>
<span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Install dependencies
<span class="token key atrule">run</span><span class="token punctuation">:</span> npm i
<span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Install hexo<span class="token punctuation">-</span>cli
<span class="token key atrule">run</span><span class="token punctuation">:</span> npm i <span class="token punctuation">-</span>g hexo<span class="token punctuation">-</span>cli
<span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Clean
<span class="token key atrule">run</span><span class="token punctuation">:</span> hexo clean
<span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Build & Deploy
<span class="token key atrule">run</span><span class="token punctuation">:</span> hexo g <span class="token punctuation">-</span>d<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h3 id="测试"><a href="#测试" class="headerlink" title="测试"></a>测试</h3><p>在 hexo 博客文件夹下,执行</p>
<pre class="line-numbers language-bash" data-language="bash"><code class="language-bash"><span class="token comment"># 配置 git 账户</span>
<span class="token function">git</span> config <span class="token parameter variable">--global</span> user.name 用户名
<span class="token function">git</span> config <span class="token parameter variable">--global</span> user.email 邮箱
<span class="token function">git</span> remote <span class="token function">add</span> origin BLOG仓库地址
<span class="token function">git</span> push --set-upstream origin master<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
]]></content>
<categories>
<category>其他</category>
</categories>
</entry>
<entry>
<title>使用 Valine 开启 Hexo 评论系统</title>
<url>/2020/11/hexo-next-valine/</url>
<content><![CDATA[<h2 id="关于评论系统"><a href="#关于评论系统" class="headerlink" title="关于评论系统"></a>关于评论系统</h2><p>博客搭建好之后,由于当时已经晚上12点了,并没有一鼓作气的开启评论系统,就一直拖到了现在。。。</p>
<p>今天终于想起来开启评论系统,在网上搜索了一下 hexo 的评论系统,有以下几个:</p>
<ul>
<li><a href="https://github.com/imsun/gitment">gitment</a>:基于 GitHub Issue 作为评论存储仓库,但是一直长时间无人维护</li>
<li><a href="https://github.com/gitalk/gitalk">gitalk</a>:同 <code>gitment</code> 使用 Github Issue,且页面比 <code>gitment</code> 更精美</li>
<li><a href="http://disqus.com/">disqus</a>:界面好看,支持 Facebook、twitter、Google+ 等账号登陆,但是 需要科学上网</li>
<li><a href="https://valine.js.org/">valine</a>:基于 LeanCloud 的无后端评论系统,支持匿名评论</li>
<li><a href="https://www.livere.com/">来必力</a>:韩国的评论系统,功能强大,支持多社交帐号登录,链接不太稳定,不支持匿名评论</li>
</ul>
<p>对于我来讲,我更偏向于使用 <code>gitalk</code> 作为评论系统,省心~但是 <code>gitalk</code> 类的评论系统被反馈有<a href="https://v2ex.com/t/535608">安全风险</a>,虽然是 GitHub 的锅,但是会对访客(还不是我。。。)的账户安全带来很大的不确定性,所以最终我还是选择了支持匿名评论的 Valine</p>
<span id="more"></span>
<h2 id="注册-LeanCloud"><a href="#注册-LeanCloud" class="headerlink" title="注册 LeanCloud"></a>注册 LeanCloud</h2><p>Valine 是基于 LeanCloud 进行使用的,所以我们需要在 LeanCloud 进行注册</p>
<p>因为现在 LeanCloud 国内版要求备案域名,所以使用<a href="https://leancloud.app/">国际版</a></p>
<h2 id="配置-LeanCloud"><a href="#配置-LeanCloud" class="headerlink" title="配置 LeanCloud"></a>配置 LeanCloud</h2><ul>
<li>创建应用:<br><img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20201121111644.png" alt="20201121111644"></li>
<li>切换到存储页面:<br><img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20201121111935.png" alt="20201121111935"></li>
<li>【结构化数据】-【创建 class】<br><img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20201121112126.png" alt="20201121112126"></li>
<li>修改 ACL 的 write 权限,设置成下图效果<br><img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20201121112221.png" alt="20201121112221"></li>
<li>切换到【设置】</li>
<li>【安全中心】-【Web 安全域名】,输入博客会用到的域名,如 <code>http://jiz4oh.com</code>、<code>https://jiz4oh.com</code><br><img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20201121112458.png" alt="20201121112458"></li>
<li>【应用 Keys】-【AppID】<br>【应用 Keys】-【AppKey】<br>这两个数据在下一步中使用(可点击后面的按钮快速复制)<br><img src="https://cdn.jsdelivr.net/gh/jiz4oh/backups@master/img/20201121112803.png" alt="20201121112803"></li>
</ul>
<h2 id="配置-next"><a href="#配置-next" class="headerlink" title="配置 next"></a>配置 next</h2><ul>
<li><p>打开 next 的配置文件,如我是 <code>_confg.next.yml</code>,将下列代码复制进去,注意缩进 </p>
<pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">valine</span><span class="token punctuation">:</span>
<span class="token key atrule">enable</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>
<span class="token key atrule">appId</span><span class="token punctuation">:</span> <span class="token comment"># 拷贝上一步的 ID</span>
<span class="token key atrule">appKey</span><span class="token punctuation">:</span> <span class="token comment"># 拷贝上一步的 Key</span>
<span class="token key atrule">placeholder</span><span class="token punctuation">:</span> <span class="token comment"># Comment box placeholder</span>
<span class="token key atrule">avatar</span><span class="token punctuation">:</span> mm <span class="token comment"># Gravatar style</span>
<span class="token key atrule">meta</span><span class="token punctuation">:</span> <span class="token punctuation">[</span>nick<span class="token punctuation">,</span> mail<span class="token punctuation">,</span> link<span class="token punctuation">]</span> <span class="token comment"># Custom comment header</span>
<span class="token key atrule">pageSize</span><span class="token punctuation">:</span> <span class="token number">10</span> <span class="token comment"># Pagination size</span>
<span class="token key atrule">lang</span><span class="token punctuation">:</span> <span class="token comment"># Language, available values: en, zh-cn</span>
<span class="token key atrule">visitor</span><span class="token punctuation">:</span> <span class="token boolean important">false</span> <span class="token comment"># Article reading statistic</span>
<span class="token key atrule">comment_count</span><span class="token punctuation">:</span> <span class="token boolean important">true</span> <span class="token comment"># If false, comment count will only be displayed in post page, not in home page</span>
<span class="token key atrule">recordIP</span><span class="token punctuation">:</span> <span class="token boolean important">false</span> <span class="token comment"># Whether to record the commenter IP</span>
<span class="token key atrule">serverURLs</span><span class="token punctuation">:</span> <span class="token comment"># When the custom domain name is enabled, fill it in here (it will be detected automatically by default, no need to fill in)</span>
<span class="token key atrule">enableQQ</span><span class="token punctuation">:</span> <span class="token boolean important">false</span> <span class="token comment"># Whether to enable the Nickname box to automatically get QQ Nickname and QQ Avatar</span>
<span class="token key atrule">requiredFields</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token comment"># Set required fields: [nick] | [nick, mail]</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
</li>
</ul>
]]></content>
<categories>
<category>其他</category>
</categories>
</entry>
<entry>
<title>Hexo 博客使用 Next 主题及美化</title>
<url>/2020/09/hexo-next/</url>
<content><![CDATA[<h2 id="安装-Next"><a href="#安装-Next" class="headerlink" title="安装 Next"></a>安装 Next</h2><h3 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h3><pre class="line-numbers language-bash" data-language="bash"><code class="language-bash"><span class="token function">yarn</span> <span class="token function">add</span> hexo-theme-next<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<h3 id="设置使用-Next"><a href="#设置使用-Next" class="headerlink" title="设置使用 Next"></a>设置使用 Next</h3><ol>
<li><p>打开博客文件夹</p>
</li>
<li><p>打开 <code>_config.yml</code> 文件</p>
<pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">theme</span><span class="token punctuation">:</span> next<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
</li>
</ol>
<span id="more"></span>
<h3 id="删除默认主题(可选)"><a href="#删除默认主题(可选)" class="headerlink" title="删除默认主题(可选)"></a>删除默认主题(可选)</h3><p>删除 <code>themes</code> 文件夹</p>
<h2 id="配置-Next"><a href="#配置-Next" class="headerlink" title="配置 Next"></a>配置 Next</h2><p>本配置文件基于 hexo-theme-next@^8.0.0 </p>
<p>未经特殊注明,均为修改主题配置文件 <code>_config.next.yml</code></p>
<h3 id="创建配置文件"><a href="#创建配置文件" class="headerlink" title="创建配置文件"></a>创建配置文件</h3><pre class="line-numbers language-bash" data-language="bash"><code class="language-bash"><span class="token function">touch</span> _config.next.yml<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<h3 id="设置主题为-Gemini"><a href="#设置主题为-Gemini" class="headerlink" title="设置主题为 Gemini"></a>设置主题为 Gemini</h3><pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">scheme</span><span class="token punctuation">:</span> Gemini<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<h3 id="返回顶部显示在侧边栏"><a href="#返回顶部显示在侧边栏" class="headerlink" title="返回顶部显示在侧边栏"></a>返回顶部显示在侧边栏</h3><pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">back2top</span><span class="token punctuation">:</span>
<span class="token key atrule">sidebar</span><span class="token punctuation">:</span> <span class="token boolean important">true</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<h3 id="显示阅读进度条"><a href="#显示阅读进度条" class="headerlink" title="显示阅读进度条"></a>显示阅读进度条</h3><pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">reading_progress</span><span class="token punctuation">:</span>
<span class="token key atrule">enable</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>
<span class="token comment"># 显示在底部</span>
<span class="token key atrule">position</span><span class="token punctuation">:</span> bottom<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<h3 id="显示加载进度条"><a href="#显示加载进度条" class="headerlink" title="显示加载进度条"></a>显示加载进度条</h3><pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">pace</span><span class="token punctuation">:</span>
<span class="token key atrule">enable</span><span class="token punctuation">:</span> <span class="token boolean important">true</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<h3 id="侧边栏菜单展开所有"><a href="#侧边栏菜单展开所有" class="headerlink" title="侧边栏菜单展开所有"></a>侧边栏菜单展开所有</h3><pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">toc</span><span class="token punctuation">:</span>
<span class="token key atrule">expand_all</span><span class="token punctuation">:</span> <span class="token boolean important">true</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<h3 id="启用-local-search"><a href="#启用-local-search" class="headerlink" title="启用 local search"></a>启用 local search</h3><p>安装外部依赖:</p>
<pre class="line-numbers language-bash" data-language="bash"><code class="language-bash"><span class="token function">yarn</span> <span class="token function">add</span> hexo-generator-searchdb<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>编辑 <code>_config.yml</code></p>
<pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">search</span><span class="token punctuation">:</span>
<span class="token key atrule">path</span><span class="token punctuation">:</span> search.xml
<span class="token key atrule">field</span><span class="token punctuation">:</span> post
<span class="token key atrule">format</span><span class="token punctuation">:</span> html
<span class="token key atrule">limit</span><span class="token punctuation">:</span> <span class="token number">10000</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>编辑 <code>_config.next.yml</code></p>
<pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token comment"># Local search</span>
<span class="token key atrule">local_search</span><span class="token punctuation">:</span>
<span class="token key atrule">enable</span><span class="token punctuation">:</span> <span class="token boolean important">true</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<h3 id="设置代码高亮"><a href="#设置代码高亮" class="headerlink" title="设置代码高亮"></a>设置代码高亮</h3><pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">codeblock</span><span class="token punctuation">:</span>
<span class="token key atrule">copy_button</span><span class="token punctuation">:</span>
<span class="token key atrule">enable</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>
<span class="token key atrule">prism</span><span class="token punctuation">:</span>
<span class="token key atrule">light</span><span class="token punctuation">:</span> prism<span class="token punctuation">-</span>tomorrow
<span class="token key atrule">dark</span><span class="token punctuation">:</span> prism<span class="token punctuation">-</span>tomorrow<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h3 id="添加版权声明"><a href="#添加版权声明" class="headerlink" title="添加版权声明"></a>添加版权声明</h3><pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">creative_commons</span><span class="token punctuation">:</span>
<span class="token key atrule">license</span><span class="token punctuation">:</span> by<span class="token punctuation">-</span>nc<span class="token punctuation">-</span>sa
<span class="token key atrule">sidebar</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>
<span class="token key atrule">post</span><span class="token punctuation">:</span> <span class="token boolean important">true</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<h3 id="修改建站时间"><a href="#修改建站时间" class="headerlink" title="修改建站时间"></a>修改建站时间</h3><pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">footer</span><span class="token punctuation">:</span>
<span class="token key atrule">since</span><span class="token punctuation">:</span> <span class="token number">2020</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<h3 id="开启彩色缎带"><a href="#开启彩色缎带" class="headerlink" title="开启彩色缎带"></a>开启彩色缎带</h3><pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">canvas_ribbon</span><span class="token punctuation">:</span>
<span class="token key atrule">enable</span><span class="token punctuation">:</span> <span class="token boolean important">true</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<h3 id="开启文章字数统计"><a href="#开启文章字数统计" class="headerlink" title="开启文章字数统计"></a>开启文章字数统计</h3><p>安装外部依赖:</p>
<pre class="line-numbers language-bash" data-language="bash"><code class="language-bash"><span class="token function">yarn</span> <span class="token function">add</span> hexo-word-counter<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>编辑 <code>_config.yml</code></p>
<pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">symbols_count_time</span><span class="token punctuation">:</span>
<span class="token key atrule">symbols</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>
<span class="token key atrule">time</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>
<span class="token key atrule">total_symbols</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>
<span class="token key atrule">total_time</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>
<span class="token key atrule">exclude_codeblock</span><span class="token punctuation">:</span> <span class="token boolean important">false</span>
<span class="token comment"># 平均字长,默认为 4,中文为 2</span>
<span class="token key atrule">awl</span><span class="token punctuation">:</span> <span class="token number">2</span>
<span class="token key atrule">wpm</span><span class="token punctuation">:</span> <span class="token number">275</span>
<span class="token key atrule">suffix</span><span class="token punctuation">:</span> <span class="token string">"mins."</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h3 id="开启文章阅读量统计"><a href="#开启文章阅读量统计" class="headerlink" title="开启文章阅读量统计"></a>开启文章阅读量统计</h3><pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">busuanzi_count</span><span class="token punctuation">:</span>
<span class="token key atrule">enable</span><span class="token punctuation">:</span> <span class="token boolean important">true</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<h3 id="添加-GitHub-Banner"><a href="#添加-GitHub-Banner" class="headerlink" title="添加 GitHub Banner"></a>添加 GitHub Banner</h3><pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">github_banner</span><span class="token punctuation">:</span>
<span class="token key atrule">enable</span><span class="token punctuation">:</span> enable
<span class="token key atrule">permalink</span><span class="token punctuation">:</span> https<span class="token punctuation">:</span>//github.com/jiz4oh
<span class="token key atrule">title</span><span class="token punctuation">:</span> Follow me on GitHub<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<h3 id="删除不必要文件"><a href="#删除不必要文件" class="headerlink" title="删除不必要文件"></a>删除不必要文件</h3><pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">minify</span><span class="token punctuation">:</span> <span class="token boolean important">true</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<h3 id="添加标签页面"><a href="#添加标签页面" class="headerlink" title="添加标签页面"></a>添加标签页面</h3><p>命令行执行:</p>
<pre class="line-numbers language-bash" data-language="bash"><code class="language-bash">hexo new page tags<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>修改 <code>source/tags/index.md</code></p>
<pre class="line-numbers language-markdown" data-language="markdown"><code class="language-markdown"><span class="token front-matter-block"><span class="token punctuation">---</span>
<span class="token front-matter yaml language-yaml"><span class="token key atrule">title</span><span class="token punctuation">:</span> tags
<span class="token key atrule">date</span><span class="token punctuation">:</span> <span class="token datetime number">2020-09-26 12:51:57</span>
<span class="token comment"># 添加下面两行</span>
<span class="token key atrule">type</span><span class="token punctuation">:</span> tags
<span class="token key atrule">comments</span><span class="token punctuation">:</span> <span class="token boolean important">false</span></span>
<span class="token punctuation">---</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>编辑 <code>_config.next.yml</code></p>
<pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">menu</span><span class="token punctuation">:</span>
<span class="token key atrule">tags</span><span class="token punctuation">:</span> /tags/ <span class="token punctuation">|</span><span class="token punctuation">|</span> fa fa<span class="token punctuation">-</span>tags<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<h3 id="添加分类页面"><a href="#添加分类页面" class="headerlink" title="添加分类页面"></a>添加分类页面</h3><p>命令行执行:</p>
<pre class="line-numbers language-bash" data-language="bash"><code class="language-bash">hexo new page categories<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>修改 <code>source/tags/categories.md</code></p>
<pre class="line-numbers language-markdown" data-language="markdown"><code class="language-markdown"><span class="token front-matter-block"><span class="token punctuation">---</span>
<span class="token front-matter yaml language-yaml"><span class="token key atrule">title</span><span class="token punctuation">:</span> categories
<span class="token key atrule">date</span><span class="token punctuation">:</span> <span class="token datetime number">2020-09-26 13:07:13</span>
<span class="token comment"># 添加下面两行</span>
<span class="token key atrule">type</span><span class="token punctuation">:</span> categories
<span class="token key atrule">comments</span><span class="token punctuation">:</span> <span class="token boolean important">false</span></span>
<span class="token punctuation">---</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>编辑 <code>_config.next.yml</code></p>
<pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">menu</span><span class="token punctuation">:</span>
<span class="token key atrule">categories</span><span class="token punctuation">:</span> /categories/ <span class="token punctuation">|</span><span class="token punctuation">|</span> fa fa<span class="token punctuation">-</span>categories<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<h3 id="设置字体"><a href="#设置字体" class="headerlink" title="设置字体"></a>设置字体</h3><h4 id="样式"><a href="#样式" class="headerlink" title="样式"></a>样式</h4><pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">font</span><span class="token punctuation">:</span>
<span class="token key atrule">enable</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>
<span class="token key atrule">global</span><span class="token punctuation">:</span>
<span class="token key atrule">external</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>
<span class="token key atrule">family</span><span class="token punctuation">:</span> Arial
<span class="token comment"># 以下设置只能修改 `` 注释的 md 代码块,不能修改 ```code block``` 字体大小</span>
<span class="token comment"># ```code block``` 字体大小修改见下</span>
<span class="token comment"># codes:</span>
<span class="token comment"># external: true</span>
<span class="token comment"># family: Arial</span>
<span class="token comment"># size: 0.8</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h4 id="大小"><a href="#大小" class="headerlink" title="大小"></a>大小</h4><p>编辑 <code>_config.next.yml</code></p>
<pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">custom_file_path</span><span class="token punctuation">:</span>
<span class="token key atrule">style</span><span class="token punctuation">:</span> source/_data/styles.styl<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<p>新建 <code>source/_data/styles.styl</code>:</p>
<pre class="line-numbers language-stylus" data-language="stylus"><code class="language-stylus"><span class="token selector"><span class="token comment">// 修改文章字体大小,强制保持 1em</span>
div.post-body <span class="token punctuation">{</span></span>
<span class="token property-declaration"><span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token number">1</span><span class="token unit">em</span><span class="token punctuation">;</span></span>
<span class="token punctuation">}</span>
<span class="token selector"><span class="token comment">// 修改 code block 中的字体,需要写入以下样式</span>
code[class*=language-] <span class="token punctuation">{</span></span>
<span class="token property-declaration"><span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token number">14</span><span class="token unit">px</span><span class="token punctuation">;</span></span>
<span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h2 id="致谢"><a href="#致谢" class="headerlink" title="致谢"></a>致谢</h2><p>博客主题美化参考了诸多前辈的文章,感谢各位大神的无私分享~</p>
<h3 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h3><p><a href="http://jeffyang.top/Hexo/Hexo%E4%B8%BB%E9%A2%98Next%E7%BE%8E%E5%8C%96/">hexo的next主题个性化教程:打造炫酷网站</a></p>
<p><a href="https://theme-next.iissnan.com/theme-settings.html">Next 原作者 iissnan 大神教程,v6 版本以上部分配置不适用</a></p>
<p><a href="https://theme-next.js.org/docs/getting-started/">Next 社区教程</a></p>
]]></content>
<categories>
<category>其他</category>
</categories>
</entry>
<entry>
<title>CentOS 7 安装 ehforwarderbot V1 来收发微信</title>
<url>/2020/09/how-to-install-ehforwarderbot-v1/</url>
<content><![CDATA[<h2 id="ehforwarderbot-介绍"><a href="#ehforwarderbot-介绍" class="headerlink" title="ehforwarderbot 介绍"></a>ehforwarderbot 介绍</h2><p>ehforwarderbot 是由 blueset 开源在 <a href="https://github.com/blueset/ehForwarderBot">github</a> 的一款专用于转发微信/QQ/Faceboot Message 到 Telegram 的机器人</p>
<p>ehforwarderbot 支持 多微信,多QQ 汇集到一起集中处理消息,特别适合:</p>
<ol>
<li>Telegram 重度用户</li>
<li>需要对多个微信、qq 消息进行处理的用户</li>
</ol>
<span id="more"></span>
<p>最新版的 ehforwarderbot 已更新到 v2.0.0,本教程仅适用于 v1 版本,且 v2 版本与 v1 版本的数据库结构大改,无法从 v1 无缝迁移到 v2 版本。请谨慎安装 v1 版本</p>