在Hexo博客中添加GitHub Calendar
逛别人的博客时,发现有许多博主的主页上会嵌入一个Github Calendar,如下图所示:
放置在homepage可以让主页显得丰富一些。
简单一搜,找到了这个项目的出处:
引用站外地址,不保证站点的可用性和安全性
github-calendar
GitHub
另外,还找到一位大佬将该项目集成的Hexo插件:
引用站外地址,不保证站点的可用性和安全性
hexo-github-calendar
GitHub
基于这些信息,本文给出两种安装方法。
修改主题直接安装插件自己动手魔改主题不愿意魔改主题的朋友可以直接安装前面提到的插件:hexo-github-calendar,
并在网站配置 ...
使用GitHub Actions自动部署Hexo博客
为了更好地备份我的博客,我将其源码推送到了一个GitHub仓库。之前了解过一点GitHub Actions,遂想着通过这个东西来自动部署博客。
随着博客的内容越来越多,本地编译的速度会越来越慢,况且我还使用了一些gulp插件,运行非常耗时,这个时候,把编译、部署的工作交给GitHub Actions就是一件非常舒服的事。另一方面,我以前没怎么用过这个功能,正好借此机会熟悉一下GitHub Actions的编写。
我的博客之前都是运行在云服务器上,而众所周知,GitHub提供了免费的静态页面托管服务——GitHub Pages。既然我已经把博客迁移到了静态站,那么现在不仅可以选择部署上服务器,还多了一个选择:将博客部署到仓库的GitHub Pages下。
部署到云服务器部署到GitHub Pages设置环境变量
创建一个SSH密钥,用于此仓库连接服务器。
ssh-keygen -t rsa -b 4096 -C "git@github.com:windshadow233/windshadow233.github.io.git"
这里,windshadow233.github.io是我的 ...
高自由度地管理Hexo博客的文章本地路径
Hexo默认将所有的文章都放在source/_posts这一级目录下,一旦文章多起来,就很乱七八糟。因此,往往会选择将文章分在不同的子目录下,以方便我们对它们进行管理。最常见的配置方法就是按文章创建的时间分配目录。
修改Hexo的配置文件自己写脚本实现_config.yml文件提供了一个配置项:new_post_name,可以用来定义文章的路径,将其值设置为:year/:month/:title.md即可。如果对文章路径有其他更个性化的需求,通过改配置文件的方法就显得不那么自由了,这一需求也可以通过编写脚本实现。
Hexo定义了一个处理文章路径的过滤器:new_post_path,可以通过对其注册一个函数来实现对文章本地路径的修改。与上篇文章类似,我们在根目录的scripts目录下创建一个新的文件:modify-post-path.js,内容如下:
const path = require('path');
hexo.extend.filter.register('new_post_path', function(filePath){
if (!filePath.in ...
为Hexo文章自动生成唯一的自增ID
前文曾提到过我将博客从WordPress迁移到Hexo时,希望保留原有的永久链接格式:/blog/:id/,然而Hexo本身并不支持自动生成这样的id,虽然有一些插件例如hexo-abbrlink支持生成这种数字id,但好像也不是我想要的样子。
我仍希望保持之前那种WordPress下的格式,即每篇文章的id单调递增,且每次的递增值比较“随机”(这个自增在WordPress中是MySQL数据库的行为,MySQL会为wp_post表中的所有内容分配id,而这些内容不仅包含了已发布的文章,还包含文章中插入的图片、文章的修订版本以及文章的自动保存版本等等,因此在发布文章时,往往这个新文章的id会看上去比较随机地递增)。
而现在Hexo没有数据库了,但我仍想保持这种随机增长的文章id风格。那要怎么办呢?每次手动算id自然不太方便,不妨自己来写个插件。
通过阅读Hexo的文档,我简单了解了一下如何在Hexo中监听事件,例如在“生成新文章后”触发一些自定义的函数。首先在博客的根目录下(这里的根目录是项目的根目录,即包含了博客配置文件的目录)创建scripts文件夹,然后在下面创建的javascr ...
gulp-clean-css插件优化时的bug及解决方案
之前的文章提到我为了控制静态文件版本使用了一个叫Gulp的包,同时为了压缩css文件大小,在其中使用了一个名为gulp-clean-css的插件,不过这个插件存在一个比较严重其实也不是很严重的bug。
一次,我魔改完主题样式,在本地测试效果良好的前提下,啪啪一顿执行npm run b && npm run d将其部署上服务器,结果从手机上打开网站一看,发现菜单样式完全崩坏,与本地测试时看到的样子截然不同。
花了几分钟定位问题,发现优化完的css文件中有一些奇怪的东西:
.menus_item_child li:not(#sidebar-menusli){
...
}
显然该样式本来应该是这样的:
.menus_item_child li:not(#sidebar-menus li){
...
}
插件将:not选择器里的空格优化掉了。在clean-css的GitHub issues下面,果然找到了多条相关的bug,例如:
Spaces removed from :not statement
Issue with ...
利用GitHub做对象存储服务
我的blog上有很多图片,它们不仅分布于文章内容、文章封面,还会大量出现在相册里。
把所有的图片都存在Hexo目录下虽然方便,但博客目录会十分臃肿,并且会拖慢Hexo生成public目录的速度,另外,如果使用了GitHub Pages等静态服务部署博客,每次推送部署都要把一堆图片打包过去,影响部署速度(或许能增量部署?不过我没有尝试过)。总之——当图片数量很多时,使用对象存储服务是有必要的。
对比了各种对象存储服务商,我觉得我还是把GitHub利用起来吧,至少它免费、稳定、没有跑路风险。
不过仍有需要注意的地方⚠️
GitHub原则上是反对仓库图床化的,当仓库超过 1G 后会有人工审核仓库内容,因此需要注意仓库不要太大。
jsDelivr 加速的单文件大小限制为 50M。
基于上述原因,后续我会逐步将图片迁移到更加合适的对象存储平台。
更新于2024-05-17:将所有图片迁移至自建对象存储服务。
已有一些支持GitHub图床的软件:PicX、PicGo,不过这些软件默认只能上传图片文件,没法传其他格式的文件。既然GitHub支持API管理仓库,那为什么不直接写个脚本来处理文 ...
使用Gulp解决Hexo静态站的文件缓存问题
作为一个喜欢魔改网站主题的人,在将博客迁移到静态站后,首先需要解决的便是浏览器的缓存问题。浏览器在遇到对静态资源的请求时,通常会采取两种缓存策略,分别是强制缓存和协商缓存。
强制缓存:在一定时间(由服务器给出的请求头标识)内不再向服务器发出请求,而是直接使用缓存的内容。
协商缓存:与服务器协商是否需要重新请求。
显然,由于缓存策略的存在,当服务端的静态文件发生变更后,客户端经常不会立刻加载最新版本的文件。对于这一点,之前我在动态博客中的解决方案是手动为静态文件加一个版本号,例如theme.css?v=1.2.1。不过在Hexo中所有的html页面都是自动编译生成的,而且会产生一大堆页面,因此并不可能一个一个地手动为静态文件添加版本。
经过一番搜索,我在一条GitHub issue下面找到了一个看上去不错的方案:
directly use webpack or gulp (commend to install at root folder). first, hexo generate the publish files, then webpack or gulp revision ...
迁移WordPress到静态博客
用WordPress写个人博客四年后,我终于下定决心把它迁移到了静态博客。本文是我使用Hexo框架写的第一篇文章。
迁移的动机
MySQL数据库占用的内存实在是太多了
有后台的博客虽然管理起来方便,但十分臃肿,而且会有补不完的漏洞
用Markdown来写文章十分简约,同时也很方便
比起PHP,我更愿意学习前端那一套框架
正好前段时间研究了如何将文章转成Markdown,满足了迁移的前置条件
发现大佬们似乎都是静态博客,跟个风
迁移的过程WordPress和Hexo对文章的处理有非常大的区别,因此我在这里将我主要遇到的问题、需要满足的需求及解决方法记录了一下。
将全站文章导出为Markdown由于Hexo使用Markdown来写文章,因此必不可少的操作——将所有文章导出为Markdown格式。
事实上,目前已经有不少WordPress to Hexo的迁移工具了,然而这些工具基本都很难完全满足我的需求,我需要一种可高度自定义的迁移方法来应对我的一些奇奇怪怪的需求。
如上一篇文章所述,我已经找到了一种令我比较满意的转换方法,不过当时的目的只是随意转换一下,看着舒服就行,在实际进行迁移操 ...
将WordPress文章转化为Markdown格式
在某些时候,我有将我的博客文章转化为markdown的需求,我的博客是用WordPress写的,想改静态博客但暂时懒得折腾,于是找了个折中的办法。
然而刚写完这篇文章没多久就迁Hexo了,正好把本文提到的转换方法用了起来。
GitHub上有不少WordPress转Markdown的脚本,大多是通过解析WordPress导出的xml文件实现转换,但实测效果则非常一般了,因为导出的内容中会含有大量类似这样的东西:<!-- wp:paragraph -->,虽然大部分markdown渲染器会忽略这些内容,但看着还是很乱七八糟,另外如果文中有自定义的block,还会出现下面这种没有解析的内容:
<!-- wp:block-lab/download {"url":"https://xxx.com","text":"xxx"} /-->
这些脚本还经常处理不好文本换行,导致解析出来的文件里许多本该换行的文字挤在一团。虽然可以手动调整以 ...
优雅地管理SSL证书及其关联服务
我的服务器上开着一堆服务,其中有一些需要用到SSL证书,例如Nginx及前面刚刚部署的邮件服务。我的SSL证书是通过certbot向Let’s Encrypt申请的,证书有效期为90天,也就是说每隔80多天就得更新一下证书。
动机在证书更新后,自然需要将所有用到证书的服务reload一下,以加载新的证书,通常我会写一条crontab作业来干这件事。之前我只有一台服务器A跑Nginx服务的时候,这样感觉还比较舒服,而现在情况变得更加复杂了:
这两年我都在维护我们实验室主办的学术会议的官网(规模不大,因此把官网部署在我的服务器上完全没问题),所以需要同时维护两个域名的证书。另外,我现在还同时维护着另一台B服务器——两台服务器上的服务共享着同一个域名证书,所以需要在A服务器上的证书更新时同步到B服务器上,并在B服务器上reload所有用到证书的服务。
于是原先的方法感觉就不太优雅了。正巧这两天iBug大佬发布了一篇文章,介绍了一种通过systemd来reload一些服务的方法:
引用站外地址,不保证站点的可用性和安全性
...
使用Nginx反向代理DoH服务
DoH(DNS over Https)是一种通过HTTPS来进行DNS解析的协议,它使用HTTPS协议加密DoH客户端和基于DoH的DNS解析程序之间的数据,防止中间人对DNS数据的窃听和操纵,从而提高客户端隐私和安全性。
国内外都有一些服务商提供公共的DoH服务,不过由于一些众所周知的原因,我会更倾向于使用国外服务商的DoH,随便列举几条比较知名的:
OpenDNS: https://doh.opendns.com/dns-query
CloudFlare: https://cloudflare-dns.com/dns-query
dns.sb: https://doh.dns.sb/dns-query
Google: https://dns.google/resolve
IBM Quad9: https://dns.quad9.net:5053/dns-query
同样的,由于一些原因,我们访问这些服务会有些困难。考虑到我有一台位于海外的云服务器,因此可以考虑通过Nginx做一个反向代理,来间接访问这些服务。下面是我配置的反向代理:
upstream google{
...
自部署邮箱接收不到某些邮件的原因排查
用上自部署邮箱后,我就将一些社交平台的绑定邮箱换成了自己的新邮箱。然而某些平台的验证邮件却始终无法收到——即使在垃圾邮件箱。
Twitter
查看日志后发现以下内容:
Mar 24 03:13:07 mail postfix/smtpd[27111]: connect from spruce-goose-al.twitter.com[199.59.150.81]
Mar 24 03:13:07 mail postfix/smtpd[27111]: Anonymous TLS connection established from spruce-goose-al.twitter.com[199.59.150.81]: TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)
Mar 24 03:13:08 mail postfix/smtpd[27111]: CD556EB3A9: client=spruce-goose-al.twitter.com[199.59 ...
自建docker-mailserver邮件服务器
大约两年前我就想过整一个自己域名的邮件服务,这样就可以随意注册邮箱账号了,而且看上去很帅。然而这件事却一拖再拖,到今天总算是整上了,于是就在这里记录一下整的过程。
我所使用的服务器是腾讯云的轻量应用服务器,地域在新加坡,配置是最low的2核2G入门型,由于配置比较低还跑了一些其他的服务,我只能放弃一些诸如mailcow这样的选项,最后选择的是比较轻量的docker-mailserver,不开启反病毒功能的前提下内存占用比较少。
一些约定为了方便描述,本文中出现的下面内容均为示例,需要替换为实际值。
一级域名:example.com
邮件服务器域名:mail.example.com
主机IP地址:1.2.3.4
邮件用户名:admin
邮件用户密码:password
涉及到的所有DNS解析,均只写主机名,而省略一级域名example.com。
开启端口邮件服务器需要用到的端口非常多,首先需要确保没有其他进程占用这些端口,并将它们打开:
25:SMTP(显式TLS端口,不可用于身份认证)
143:IMAP4(显式TLS端口)
465:ESMTP(隐式TLS端口)
587:ESMTP( ...
Gitalk发起Oauth时无法完成跨域请求的问题
我的博客接入Gitalk之后,经常会遇到Gitalk登录失败的问题,表现为Gitalk组件长时间转圈加载不出来,一段时间后渲染出Network Error等字样。
经过研究,发现是因为Gitalk在发起跨域请求时,其默认的代理出了问题,详情可见此issue。
https://cors-anywhere.azm.workers.dev/https://github.com/login/oauth/access_token
上面这个跨域代理的域名已经被墙了,在没有科学上网环境或网络环境差的时候就会寄。
于是我们可以自己整一个代理,方案有几种,如果没有云服务器,可以找一些免费的托管平台来搞一个代理,例如Vercel,可参考这篇文章
不过实际体验了一下,我发现vercel的域名好像也被墙了(DNS污染)。。。
考虑到我的网站是用Nginx部署在自己的云服务器上的,并且我的云服务器在境外,可以直连GitHub,因此我采用了另一种更加方便的方案,即用Nginx来转发跨域请求(参考自这篇文章)。
在网站的Nginx配置下 ...
博客接入Gitalk评论系统
2024-04-21 更新: 基于GitHub Issue的评论系统在嵌套评论时叠金字塔的行为太丑了,于是我已经将评论系统换成了基于GitHub Dissussion的Giscus。
自从开始写这个博客以来,我就嫌博客主题自带的评论系统太丑,又懒得大改CSS,于是我的博客一直没有开启评论功能。
但忽然觉得不开评论区好像过于冷清(虽然开了也不怎么会有人评论),然而我又不是很希望访客的评论占用数据库,因此我打算看看能不能整一个Serverless的评论系统。
最近接触了下GitHub REST API,于是想了一下,觉得既然GitHub的API那么方便,那为什么不试试把GitHub的Issue系统渲染到自己的网页上当评论系统用呢?(之前听说过有人拿GitHub当云存储的,简直就是人才)
考虑到受众群体应该不会有人没有GitHub账号,感觉这个想法很不错,然而当我研究的如火如荼之时,突然在网上搜到了别人已经造好的轮子:Gitalk。草,果然。
那何不拿来主义?毕竟我也比较讨厌写前端代码。于是我啪就整起来了,很快啊!就把Gittalk接入了一下,说实话这个评论系统的前端还挺不错的,基本契合我 ...
一个随Star数动态变化的GitHub仓库
几年前曾看到过@iBug大佬的一个GitHub仓库,这个仓库的名字以及描述会实时显示当前的Star数量,令当时的我觉得非常有意思,不过那会我并没有去研究原理。几年过去了,却不知昨天为啥突然想到,于是读了一下大佬的文章,试着复现了一下。
我复现的仓库链接如下:
引用站外地址,不保证站点的可用性和安全性
This Repo Has 0 Stars
GitHub
朋友们可以进去点个star看看效果~(没想到我第一次骗star竟是为这)
项目很简单,但其背后的原理覆盖了一些我之前没有接触过的东西,例如GitHub REST API、Webhook(这个倒是在做telegram bot的时候接触过)、AWS Lambda等。如果能熟练利用,感觉会是个很高效、很方便的辅助工具。由于iBug大佬的文章省略了好多「有手就行」但我不会的内容,所以在过程中踩了一些坑,因此我来水篇文章,更详细地记录一下 ...
使用Cloudflare为网站部署免费的防御措施
我决定给我的博客套一层Cloudflare。
“不是,你网站那点访问量套个der的cf啊?”
“我之前也觉得没必要,但为什么我这么小的站都有人来搞事啊。。。看来还是有必要上一下防了。反正Cloudflare有free plan,那个够好用了,不用白不用。”
发生肾磨石了?朋友们好啊,我是本博客的博主。
刚才有个朋友问我,你的个人博客为肾磨访问不了了,我说怎么回事?给我发了几张服务器无响应的截图,我一看Nginx日志,哦!源赖氏港才,有两个IP地址,非常可疑,一个请求90多万次,一个请求80多万次。
我一看这请求量!啊…我的服务器CPU占用率直线上升,到了100%,诶…服务器扛不住了,我说这是怎么回事。我说你这个请求来得太频繁了,不能这么搞,他不理我。我说小朋友你看这个CPU负载,他看都不看。他说你这也没什么办法。我说我这个有办法,得用防火墙拦截全部流量,传统运维是讲防御的,四两拨千斤,二百多万的每分钟请求数都敌不过我这一条防火墙规则啊…哈!他非得继续攻击,我说可以。
诶…我一说他脚本啪就跑起来了,很快啊!然后上来就是,一个拒绝服务,一个CC攻击,一个API滥用!
我全部防出去了,防 ...
重塑密码管理体系——Bitwarden服务端自部署
经常问我借账号的朋友都知道,我这个人记性不好,也因此,我所有平台的密码都长的大同小异(基本都是由同一个字符串通过变换字母大小写、截取子串,或者添加一两个特殊符号得来的)。
使用相似密码的坏处像我这样在各平台用相似度极高的密码,虽然方便了记忆,但后果也很严重:某些不负责任的平台会用明文存储用户密码,然后还tm泄漏了。。。这就造成了我们的常用密码被添加到了字典里,黑客便可通过这些字典来轻松破解我们其他平台的密码(虽然并没有什么值得被黑客盯上的东西)。
因此,将各种平台的密码设成互相毫无关联的随机字符串才是妥当的方案,这种安全的密码设置画风应该是下面这样的:
QQ:Tx8RYq%*fStp3r
微信:D6MuyvxS!6e$Zc
Apple账号:&Nm4PvAdL*cH#v
科大邮箱:vSP6nC$QZrh3z%
…
然而如果把各平台的密码都设成这种鸟样,安全性虽然能保证了,但毕竟我的脑子不是硬盘,肯定是记不住的,所以很自然地就需要一款能为我们管理各平台的密码的软件。拥有过目不忘能力的同学到了这就已经可以不用往下看了。
这种软件需要至少满足下面的条件:
安全可靠:能够为我生成强 ...
“The Password Game”攻略
这两天偶然发现了一个有点意思的“小游戏”,名为“The Password Game”,传送门如下:
引用站外地址,不保证站点的可用性和安全性
The Password Game
大概是给你一堆层层递进又互相强耦合的规则,让你设置一个符合所有规则的密码。我第一次通关花了几个小时,而通关两次以后,已经摸透了通关的方法,因此来记录一下。
由于其中包含Google Map和Youtube等内容,故科学上网是通关的必要条件。
本文所有的代码已集成到Greasyfork:
引用站外地址,不保证站点的可用性和安全性
Password Game Assistant
Greasyfork
小游戏共有 ...
Hackergame 2023题解(三)
本文是Hackergame 2023题解的第三部分。
🪐 流式星球查看题面茫茫星系间,文明被分为不同的等级。每一个文明中都蕴藏了一种古老的力量 —— flag,被认为是其智慧的象征。
你在探索的过程中意外进入了一个封闭空间。这是一个由神秘的流式星人控制着的星球。星球的中心竖立着一个巨大的三角形任务牌,上面刻着密文和挑战。
流式星人用流式数据交流,比如对于视频来说,他们不需要同时纵览整个画面,而是直接使用像素流。为了方便理解,你把这个过程写成了一个 Python 脚本(见附件),flag 就藏在这个视频(见附件)中。尽管最后丢掉了一部分数据,你能把 flag 还原出来吗?
Python脚本
视频文件
这题的附件给出了将一个mp4文件转换为video.bin的过程。其逻辑是将视频的每一帧抽取出来存入一个array,最后对array做了一个flattern操作并去掉了末尾随机0-99个字符,相当于按顺序存放了视频的每一个像素(仅仅删掉了最后的不到100个)。
用numpy读取video.bin,得到它的长度是135146688,然后我遍历了0-99,加上长度以后送去质因数分解,选出3的倍 ...