想拥有一台云服务器很重要的一个原因就是搭博客,以前博客是托管在GitHub上的,用的国外的服务器,国内访问速度一般,有时候还会卡住进不去,实在有点忍不了。
不过开始部署才意识到这里面的坑居然有那么多……
更换博客源文件备份的仓库名字
新建一个新仓库,git clone
到本地,把原来的所有文件复制到新仓库,重复文件选择跳过,再将配置文件_config.yml
中hexo-git-backup
插件的仓库名配置改一下,执行hexo b
即可将文件都放到新仓库里,老仓库的commit
也会转移过来。然后把老仓库删掉就行。
设置alias方便测试、部署和备份博客
在.bashrc
或.zshrc
中添加配置:
1 | 快速切换到博客根目录 |
执行后需要关注输出信息,有时候可能会有报错或连接问题需要解决。
修改完成配置文件后需要执行source .bashrc
或source .zshrc
来应用文件。
配置Nginx解析Hexo博客
首先需要了解一些有关Git中钩子的使用的相关知识:
Git高级操作: Git钩子Git钩子是一组脚本,这些脚本对应着Git仓库中的特定事件,每一次事件发生时,钩子会被触发。 - 掘金
了解git裸仓库并利用post-receive自动化部署-CSDN博客
nginx配置:
请马上停止使用TLS 1.0和TLS 1.1! | 网络热度
整体部署流程:
基于Hexo的静态博客网站搭建并部署至云服务器 | Glimound的个人技术经验分享
使用 Hexo 搭建个人博客并部署到云服务器 - Cheyaoyao - 博客园
/etc/nginx
下的Nginx配置文件中的nginx.conf
,第一行user
的配置尽量改为运行Nginx的用户。
通过Git部署时指定其他SSH端口:hexo配置发布至ssh非22端口服务器_hexo deploy 端口-CSDN博客
拓展配置:
好好学Hexo:Hexo配置多个git仓库 | 好好学习的郝
笑花落Blog学习 - Nginx禁止IP直接访问、防止域名恶意解析、源IP扫描SSL泄露
Nginx 配置,禁止通过ip地址直接访问Web 服务-腾讯云开发者社区-腾讯云
nginx关闭默认站点/空主机头(禁止IP直接访问、防止域名恶… - LNMP一键安装包 - VPS侦探论坛 - Powered by Discuz!
NGINX 配置避免 IP 访问时证书暴露域名 - ZingLix Blog
Nginx 生产环境下的安全配置 - piaohua’s blog
手动指定403报错为404,防止被扫后台目录:nginx自定义错误页_nginx自定义错误页面-CSDN博客
解决配置default_server
报错:nginx- duplicate default server error - Stack Overflow,将nginx.conf
中的http{}
块的include /etc/nginx/sites-enabled/*;
注释掉即可。
【问题解决】 网关代理Nginx 301暴露自身端口号 - 东北小狐狸 - 博客园
拓展知识:
将hexo博客部署到服务器,并支持多线部署 | Nes的草稿箱
NGINX Reverse Proxy 反向代理的使用 | Marco Nie
为域名添加ICP备案信息
ICP 备案 备案号悬挂说明-ICP 备案后处理须知-文档中心-腾讯云
hexo+yilia添加网站运行时间,ICP备案信息,设定站点建立时间 | 荷塘月色的博客
在Blog\themes\yilia\layout\_partial\footer.ejs
文件的<div class="footer-left">
前面添加:
1 | <!-- 添加网站备案号begin --> |
<br>
用于换行,让备案号单独在页脚的第一行并居中。
还需要再Yilia的配置文件Blog\themes\yilia\_config.yml
中添加:
1 | # 添加ICP备案信息 |
添加域名SSL证书
虽然Let’s Encrypt的证书可能在某些情况下不被信任(Let’s Encrypt OCSP 域名被封 | Wolfogre’s Blog),但它胜在免费,支持泛域名,可自动部署,对于个人博客来说足够了
SSL 证书 Nginx 服务器 SSL 证书安装部署(Linux)-证书安装-文档中心-腾讯云
如何在Nginx服务器上安装SSL证书_数字证书管理服务(原SSL证书)(SSL Certificate)-阿里云帮助中心
泛域名证书比单域名证书方便的多,一次签发所有子域名通用,只需要担心续期问题就行了,因此考虑使用泛域名,泛域名验证只支持DNS验证,因此使用Certbot对Let’s Encrypt证书进行自动续期,需要使用相应的自动化脚本来管理DNS验证,下面是手动配置的方法。
使用 Let’s Encrypt 免费申请泛域名 SSL 证书,并实现自动续期 - 平元兄 - 博客园
手动配置明显比较麻烦,因此考虑用自动化脚本acme.sh:acmesh-official/acme.sh: A pure Unix shell script implementing ACME client protocol
嘶,突然发现acme.sh默认使用的CA是ZeroSSL,而且根据这篇博客(使用 acme.sh 配置自动续签 SSL 证书 - 烧饼博客)的对比,感觉ZeroSSl确实要好一点,这里是acme.sh更换默认CA的说明:Change default CA to ZeroSSL · acmesh-official/acme.sh Wiki,以及有一个ZeroSSL和Let’s Encrypt的对比:Let’s Encrypt Alternative - ZeroSSL
原来是acme.sh被ZeroSSL商业收购了,acme.sh被收购 更换默认证书颁发机构为ZeroSSL 还安全吗? Li.005 | 李子菜Lizicai,虽然按这篇文章中说的,每次申请证书会暴露用户信息,但用的人那么多,而且每天上网暴露的信息也不少,也不差这点了,而且我这云服务器也就是搭个网站,万一被干了也影响不大。
那就还是选择用官方默认的ZeroSSL吧,放弃Let’s Encrypt证书,全站更换ZeroSSL证书 - 饭饭’s Blog,根据文档:ACME Documentation - ZeroSSL,ZeroSSL使用ACME也可以免费申请泛域名证书
配置过程在官方的Wiki页面已经很详细了:Home · acmesh-official/acme.sh Wiki
可以参考中文页面:说明 · acmesh-official/acme.sh Wiki
也可以参考官方给出的配置教程博客推荐:Blogs and tutorials · acmesh-official/acme.sh Wiki
使用 acme.sh 配置自动续签 SSL 证书 - 烧饼博客
NGINX 配置 HTTPS 最佳实践 - ZingLix Blog
如何使用acme.sh申请 SSL(HTTPS) 泛域名证书并自动续签?最新acme.sh安装证书教程 – 今日指点
如何使用acme.sh与阿里云DNS自动签发Let’s Encrypt的免费数字证书 - 初心
配置完成后,为确保定时任务能自动续签证书,可以通过以下命令来手动调用一次定时任务进行续签:
1 | acme.sh --force --cron |
配置Nginx防护(配合Fail2Ban)
利用Fail2Ban保护你的服务器(Fail2Ban使用教程) | hash070’s blog
Nginx如何防护DoS和CC攻击 | hash070’s blog
Turn Your Nginx Server into a Fortress with Fail2ban and UFW | Scalastic 👨🏻💻
Nginx fail2ban:个人站点 DDOS 攻击生存指南 | Ming’s Blog
nginx 限流模块和fail2ban搭配使用-阿里云开发者社区
Module ngx_http_limit_req_module
配置完后把封禁IP阈值调低,让Nginx的error更容易触发,在浏览器中用F5不断刷新网页触发error,测试了很久,都没有出现封禁IP的情况,检查了Nginx的error.log
,是有报错信息的,检查了Fail2Ban的匹配原则,各种设置项,都没有问题,而且SSH的封禁IP正常运作。查了大半天,终于在官方的一个Issues中找到答案:Jail not banning, cant find cause · Issue #2856 · fail2ban/fail2ban,是因为Nginx IP监狱nginx-limit-req
的配置里面backend
这一项被设置为了systemd
,这意味着这将监视systemd-journal
而不是日志文件,通过sudo fail2ban-client -d
可以查看目前所有监狱的信息,发现['add', 'nginx-limit-req', 'systemd']
,在jail.local
文件的监狱设置里添加backend = auto
,重启Fail2ban后,监狱封禁正常运行。
但是查看jail.conf
文件,发现默认值就是backend = auto
,然而自己新建的监狱的backend
值又自动改为了systemd
???这是为什么呢?原来是Fail2ban的配置文件中,对于配置文件优先级:
/etc/fail2ban/jail.conf
/etc/fail2ban/jail.d/*.conf
,按字母顺序排列/etc/fail2ban/jail.local
/etc/fail2ban/jail.d/*.local
,按字母顺序排列
因此jail.d
文件夹里的配置项可以覆盖jail.conf
中的配置,查看jail.d
文件夹,发现其中有一个defaults-debian.conf
文件,其中默认配置中写入了backend = systemd
,进一步查找官方Issus,发现:[BR]: fail2ban does not start on some debian/ubuntu systems - backend should probably be set to systemd on all systemd-based distros · Issue #3292 · fail2ban/fail2ban,这可能就是jail.d
文件夹中出现defaults-debian.conf
文件,将backend
默认配置为systemd
的原因,在官方Wiki的Q&A里也有有关backend
参数设置的提醒的提醒,How fail2ban works · fail2ban/fail2ban Wiki,不过说实话,一般不出问题的话很难注意到……
查看sudo fail2ban-client -d
输出发现sshd
监狱就是['add', 'sshd', 'systemd']
,但sshd
的监狱就能正常运行,同样配置下nginx-limit-req
监狱就无法正常运行,我猜测可能是sshd
比较靠近系统底层,因此做了基于systemd
的发行版系统的适配,日志除了在/var/log/auth.log
中找到,服务日志信息还会被记录到systemd
日志中,因此sshd
监狱使用systemd
模式可以正常运行。
但像Nginx等软件,可能不会专门为了某一种系统做适配,因此日志信息只能在寻常的log文件中找到,因此即使所有配置都正确,将监狱设置为systemd
,Fail2ban仍然不能正确找到日志文件,这时候就必须手动设置:backend = auto
。
就像开发者sebres (Sergey G. Brester)在Issue里的comment[BR]: fail2ban does not start on some debian/ubuntu systems - backend should probably be set to systemd on all systemd-based distros · Issue #3292 · fail2ban/fail2ban中说的,作为开发者,维护软件是一件很麻烦的事情,很难做到匹配世界各地每个软件的每个发行版和每个版本,评估影响后的一次更新,很可能就因为发行版的一次改动出Bug,fail2ban只是一个工具(不是魔术盒),并且每个工具都需要正确配置(即使已经进行了一些预配置)。所以我们应该理解和尊重这些开源完全免费软件的开发者们,给他们多一些包容,如果可以的话,为维护版本做出贡献来帮助其他人。
终于把这个困扰了我大半天的问题解决了,网上各种论坛问答博客翻了个底朝天都没有找到解决方法,还得是在官方的Issues中才能找到,这个故事告诉我们,实在找不到解决方法时候,不要畏惧查找外文资料,外网博客或官方的Issues中很可能会有完美的解决方法。
添加nginx-botsearch.conf
过滤器,此过滤器重点关注对不存在的 URL 的请求(404 错误),这通常是机器人或扫描程序试图查找漏洞或隐藏页面的迹象。
添加方法同上,测试error.log
文件发现过滤器无法正常匹配,查找发现官方Issue中有解答:[BR]: Fail2Ban nginx-botsearch doesn’t match any of the error log entries · Issue #3301 · fail2ban/fail2ban
过滤器后半部分有一个<block>
参数需要自己根据botsearch-common.conf
文件指定想要过滤器匹配的URL列表,用来匹配不同的阻止报错信息:
1 | # Block is the actual non-found directories to block |
最简单的情况是将其设置为\S+
,每个未找到的文件将被视为来自机器人的请求,配置后的正则表达式:
1 | ^ \[error\] \d+#\d+: \*\d+ (\S+ )?\"\S+\" (failed|is not found) \(2\: No such file or directory\), client\: <HOST>\, server\: \S*\, request: \"(GET|POST|HEAD) \/\S+ \S+\"\, .*?$ |
不过最好不要改动nginx-botsearch.conf
,而是在jail.local
中指定<block>
:
1 | [nginx-botsearch] |
配置后测试成功。
测试发现nginx-botsearch
监狱触发封禁规则后,看起来是实施了封禁,但正在访问的网页还可以继续访问一段时间,于是fail2ban.log
就出现了一堆xxx.xxx.xxx.xxx already banned
的消息,有没有办法在触发封禁的第一时间就将目标IP地址的所有连接都切断,禁止其访问所有内容呢?答案是有的,同样的,这个问题在浏览器中搜索了半天都没有解答,都是在讲一些基础的配置,无奈只好又去官方的Issue中找,果然有人遇到了同样的问题:Fail2ban says already banned an ip but the ip can still visit webserver · Issue #2545 · fail2ban/fail2ban,开发者给出了解决方法:设置默认值banaction = ufw[kill-mode=ss]
、banaction_allports = ufw[kill-mode=ss]
,这样配置的情况下,一旦IP地址被封禁,就会直接切断该IP地址与服务器的所有连接。
可以参考另一个相关Issue:Update ufw.conf by usernamepi · Pull Request #3018 · fail2ban/fail2ban
但这样配置的情况下需要注意,一定再也不能用本机的IP地址测试Fail2ban的监狱起效情况,一旦IP被封禁,正在连接的SSH连接也会被切断,只能等待时间到了解封或者更换IP连接。
不过根据Issue,UFW有一些其他问题:https://github.com/fail2ban/fail2ban/issues/2545#issuecomment-2460393322、https://github.com/fail2ban/fail2ban/issues/2545#issuecomment-2460472090,因此不建议使用,`debian`系操作系统例如`Ubuntu`中默认的是`nftables`,查看`jail.d`文件夹下的`defaults-debian.conf`,可以发现默认的配置就是`nftables`,虽然也可以改用`jail.conf`中的`iptables`,但由于开发者设置了默认设置,直接用就行。注意如果SSH连接修改了默认了22端口,需要在监狱配置中加入`port = xxxx`的配置,确保封禁了正确的端口。配置完成后重启Fail2ban服务,测试成功。
扩展:安全:nftables的常用命令(查看规则) - 刘宏缔的架构森林 - 博客园
添加nginx-forbidden.conf
过滤器:
1 | [Definition] |
1 | [nginx-forbidden] |
封禁频繁扫描目录时导致403 Forbidden报错的IP地址。
添加nginx-connection-refused.conf
过滤器:
1 | [Definition] |
1 | [nginx-connection-refused] |
封禁频繁访问后台服务器拒绝连接的Nginx反代地址时导致Connection refused的IP地址。
Twikoo评论自部署
给博客搭建一个带后端的评论系统,虽然无后端的Viline搭建起来比较方便,但无后端总归是不好管理,速度可能比较慢,也没办法防止恶意评论批量灌入。Waline是一个Viline改版的评论系统,但看了一下效果,还需要登录什么的,感觉有点复杂了。最终选了Twikoo:Twikoo | 一个简洁、安全、免费的静态网站评论系统,并选择自部署,这样国内访问的速度应该会比较快。
linux 自建 Twikoo 评论系统私有部署保姆级(非 Docker) | a.d 博客
Linux系统服务神器:systemctl的配置与使用 - 掘金
Twikoo 评论系统私有部署(非Docker) | 网上冲浪中心
hexo-yilia主题支持twikoo评论系统 [yilia-more](https://github.com/bux - 掘金
buxiaoxing/yilia-more: 一个简洁优雅的hexo主题 A simple and elegant theme for hexo.
对于Yilia,编辑ejs文件部署评论框前端:
在Blog\themes\yilia\layout\_partial\post\
下添加twikoo.ejs
文件:
1 | <div id="tcomment"></div> |
编辑Blog\themes\yilia\layout\_partial
下的article.ejs
文件,在尾部最后一个<% } %>
前添加:
1 | <!-- twikoo评论系统 --> |
在article.ejs
文件的代码<%- partial('post/title', {class_name: 'article-title'}) %>
下面添加单篇文章阅读量统计:
1 | <!-- 添加Twikoo阅读量bagin--> |
由于Twikoo内置的阅读量统计只有在评论区加载时候才会加载,因此设置为打开某一篇文章时候再加载阅读量,主页(文章部分浏览的情况)下没有阅读量统计(加载条件与评论加载条件相同)。
在主题配置文件Blog\themes\yilia\_config.yml
中添加配置:
1 | #6、twikoo https://twikoo.js.org/ |
添加自定义表情包:Twikoo評論系統的個性化設置 · 嘰嘰乞乞
评论区美化:
Twikoo评论回复邮件模板:Acrylic Mail 粉 | 张洪Heo
Hexo博客私有部署Twikoo评论系统并迁移评论记录(自定义邮件回复模板)-CSDN博客
参考:魔改笔记六:twikoo及导航栏美化 | LiuShen’s Blog
自定义表情国内加速版CDN链接:https://fastly.jsdelivr.net/gh/willow-god/owo/owo-fast.json
编辑CSS文件对评论框的样式做一些改动:
在@media screen and (max-width:800px) {
上面添加:
1 | /* Twikoo评论块样式(大屏幕) */ |
在@media screen and (max-width:800px) {
中添加:
1 | /* Twikoo评论块样式(小屏幕) */ |
在文件最后添加:
1 | /* 给有链接的评论用户名字变颜色,增加可读性 */ |
自定义评论邮件回复样式:
MAIL_TEMPLATE(用户回复通知邮件模板):
1 |
|
MAIL_TEMPLATE_ADMIN (博主新评论通知邮件模板):
1 |
|
上面的HTML代码需要经过压缩后填入配置中,推荐使用VS Code中的Minity插件对HTML文件做压缩处理。
增加外链安全跳转页面:给博客添加一个安全跳转页面 | LiuShen’s Blog,感觉有点复杂,以后有需要再说吧……
自建域名邮箱服务器搭建
Jinnrry/PMail: Private EMail Server
Pmail——仅用一分钟就可以搭建好一个邮箱服务器-腾讯云开发者社区-腾讯云
寻道之旅 - 强烈推荐,一个内存占用极低的自建域名邮箱 Pmail
搭了好几遍,测试了半天,接收倒是正常,发送全是error。
好!发现腾讯云默认把邮件SMTP需要的25端口封了,且只有云服务器才可以申请解封,轻量应用服务器不支持解封……
关于无法使用非25的加密端口,通过SMTPS收发邮件的详细解释,可以参考这两篇Issue:是不是可以不用 25直接使用 465 · Issue #130 · Jinnrry/PMail、Emails cannot be sent out through port 25, can the port be changed to 465 · Issue #8 · Jinnrry/PMail
自建域名邮箱服务器宣告失败,老老实实用QQ邮箱的SMTP了。
自己云服务器厂商没有封25端口的朋友可以尝试一下,用Docker和非Docker都可以,搭建还是比较方便的。
包管理工具从NPM到PNPM
NPM有各种各样的遗留问题,node_modules
文件夹占用空间巨大,速度慢,镜像源访问慢等,考虑使用新型包管理工具PNPM进行替换:
前端 - 包管理工具之从NPM到PNPM - 个人文章 - SegmentFault 思否
本文链接: https://hanqingjiang.com/2024/12/08/241208_server_hexoBlogWithNginx/
版权声明: 本作品采用 CC BY-NC-SA 4.0 进行许可。转载请注明出处!
