阅读视图

Focalboard 开源项目管理的有力工具

在当今数字化协作的时代,高效的项目管理工具对于团队的成功至关重要。Focalboard 作为一款开源的项目管理软件,正逐渐崭露头角,受到了众多团队和个人的青睐。

简介

Focalboard 是由 Mattermost 开发的功能强大的开源项目管理和协作工具,能够以看板的形式灵活地组织任务,创建详细的笔记,并方便地共享文件。它支持创建各种类型的笔记页面,记录数字、链接、文字等多种类型的信息,且内置了多种模板供用户直接套用编辑。

Focalboard 具有以下特点:一是开源免费,数据自托管,用户可将其部署在自己的本地服务器上,确保数据安全可靠;二是支持多平台,包括 Windows、macOS、Linux、iOS 和 Android 等,方便用户随时随地接入项目;三是具备丰富的功能,如拖放卡、进出口板、按状态或截止日期等过滤板和任务,以及支持多人协作、文件共享、团队和直接消息等;四是界面简洁易用,操作便捷,易于上手。

安装

Focalboard 的安装方式主要有以下几种:

  1. 使用 Docker 安装

这是在 Windows 系统上较为便捷的安装方式。首先需要在 Windows 中安装 Docker,然后打开 cmd 命令行,输入命令 docker run -it -p 80:8000 mattermost/focalboard,等待安装完成。安装成功后,在 Docker Desktop 中可以看到 Focalboard 的 web 界面地址为 https://localhost:8000,点击该地址或在浏览器输入 localhost:8000 即可进入 Focalboard 登录界面。

  1. 在 Ubuntu 系统上安装

以 Ubuntu 22.04 为例,安装步骤如下:首先是安装和配置 PostgreSQL 数据库,使用命令 apt-get install curl wget gnupg2 -yapt-get install postgresql postgresql-contrib -y 进行安装,然后创建数据库和用户。接着安装 Focalboard,可从官网下载适用于 Ubuntu 的安装包,再通过命令进行安装。安装完成后,需为 Focalboard 创建系统服务文件,并将 Nginx 配置为反向代理,最后访问 Focalboard 网络界面并启用 SSL。

  1. 直接下载安装包安装

可前往 Focalboard 的官方网站(https://focalboard.com/)下载适用于不同操作系统的个人桌面版或个人服务器版的安装包,按照提示完成安装。

使用

  1. 创建团队和看板

在 Focalboard 的欢迎屏幕上,用户可选择创建新的团队并设置团队名称。进入团队页面后,点击 创建看板 按钮,根据需要选择看板类型,如项目任务、内容日历、公司目标与 OKR、路线图等模板创建看板,也可创建空白看板自行设计。还可设置看板的名称、描述和背景色等信息。

  1. 添加任务和卡片

在看板上,通过点击 添加卡片 按钮来创建新的任务卡片。可在卡片中输入任务描述,并为卡片添加标签、截止日期、优先级等属性,以便更好地对任务进行分类和管理。同时,可以将任务卡片分配给团队中的不同成员,明确责任分工。

  1. 进行协作和沟通

团队成员可以在看板上实时查看和编辑任务卡片,共同推进项目进度。在卡片中添加评论和讨论,@提及队友以引起他们的注意,分享想法和意见,实现高效的协作沟通。此外,还可通过 Focalboard 的团队和直接消息功能,进一步加强团队成员之间的交流。

  1. 利用其他功能

Focalboard 支持文件共享,用户可在任务卡片中上传相关文件,方便团队成员查阅和下载。可对看板进行筛选、分组和排序,快速找到所需的任务和信息。还能查看历史记录、备份快照等,确保数据的安全性和可恢复性。

总结

Focalboard 作为一款开源的项目管理工具,凭借其丰富的功能、简洁易用的操作界面以及数据自托管等优势,为个人和团队提供了一个高效、可靠的项目管理和协作平台。

无论是小型团队还是大型企业,都可以利用 Focalboard 来规划项目、分配任务、跟踪进度并实现顺畅的协作,从而提高工作效率和项目成功率。

  •  

Oryx 助力音视频服务开源利器

Oryx 是一个开源的音视频服务解决方案,具有多种特点和应用场景。

简介

  • 特点

    • 多协议支持 :支持 RTMP、HLS、HTTP-FLV 等多种流媒体协议,满足不同设备和场景下的音视频传输需求。
    • 高扩展性 :基于插件的架构,便于用户根据自身需求进行功能扩展,如添加新的推流协议、录制存储等功能。
    • 高性能 :支持多进程,能充分利用多核 CPU 和高速网络优势,还支持 HTTP2 和 Quic 协议,提供高性能的流媒体服务。
    • 便捷管理 :提供丰富的 HTTP API,便于远程管理和操作,还支持 JSON 风格的配置文件,方便配置和管理。
  • 应用场景

    • 推拉流场景 :支持各种不同协议的推拉流,可轻松实现音视频的传输和分发。
    • 录制场景 :支持合并多次推流,可设置过滤器只录制特定的流,满足对音视频录制的需求。
    • 转发和虚拟直播 :可以将文件和其他流转发到不同的平台,或者转发到 Oryx 自身,实现虚拟直播等功能。
    • AI 自动字幕 :利用 OpenAI 等能力,自动识别字幕并将字幕嵌入到视频流中,提升音视频内容的可理解性和可访问性。

安装

  • 环境准备 :Oryx 基于 Go 语言开发,需先安装 Go 语言环境。同时,还需确保服务器有可用的网络连接,以便下载所需的依赖包和 Oryx 代码。

  • 安装步骤

    • 通过宝塔面板安装 :在宝塔面板的软件商店中搜索 Oryx,找到对应的插件后点击安装按钮,按照提示完成安装。如果宝塔商店的版本较老,可在Oryx Releases 页面下载最新版本的 bt-oryx.zip,然后在宝塔 软件商店 > 第三方应用 > 导入插件 处上传该文件进行安装。
    • 通过命令行安装 :在 Unix-like 系统中,使用 go get github.com/ossrs/go-oryx 命令获取源代码,然后进入 $GOPATH/src/github.com/ossrs/go-oryx 目录,使用 $GOPATH/bin/go-oryx -c conf/oryx.json 命令启动 Oryx 服务。在 Windows 系统中,命令稍有不同,为 go get github.com/ossrs/go-oryx,然后进入 %GOPATH%\src\github.com\ossrs\go-oryx 目录,使用 %GOPATH%\bin\go-oryx.exe -c conf\oryx.json 命令启动服务。

使用

  • 基本使用 :安装完成后,可通过 Oryx 提供的 HTTP API 进行各种操作,如推流、拉流、录制、转发等。例如,使用 curl -X POST http://localhost:1935/api/v1/streams/start 命令可启动推流,使用 curl -X GET http://localhost:1935/api/v1/streams 命令可获取当前正在推流的列表。
  • 配置优化 :根据实际需求,可对 Oryx 的配置文件进行修改,以优化其性能和功能。例如,可调整最大连接数、缓冲区大小等参数,以提高服务的并发能力和传输效率。
  • 与其他服务结合使用 :Oryx 可与云厂商的镜像、DDNS 服务、VPS 等结合使用,实现更强大的音视频服务功能。如通过 DDNS 和 VPS,可将摄像头 24/7 实时流式传输到 YouTube,无需使用 PC 或 OBS。

总结

Oryx 作为一个开源的音视频服务解决方案,凭借其丰富的功能、多协议支持和高扩展性等特点,为音视频服务的搭建和管理提供了极大的便利。

无论是个人开发者还是企业用户,都可以根据自身需求,快速部署和使用 Oryx,创建出高效、稳定的音视频服务系统。在未来的版本更新中,Oryx 有望带来更多新特性和优化,为音视频行业的发展助力。

未完待续

  •  

探索网络实验的神器 Mininet

在计算机网络的学习与研究领域,Mininet 是一款极具价值的工具。它就像是一个迷你网络世界的构建者,为我们提供了便捷的网络实验环境。本文将带你深入了解 Mininet 的魅力所在,并手把手教你安装与使用它。

简介

Mininet 是一个用于创建虚拟化网络环境的平台。

它能够在一台计算机上快速构建出包含多个主机、交换机、路由器等网络设备的网络拓扑结构。

对于网络研究人员、开发者以及网络课程的学生来说,Mininet 是一个理想的实验平台。

通过它可以模拟大规模网络环境,进行各种网络协议的研究、网络应用的开发测试以及网络教学演示等。

例如,如果你想研究一种新的网络路由算法,借助 Mininet 就能轻松搭建出实验所需的网络场景,无需搭建实体网络设备,大大节省了成本和时间。

它的核心优势在于轻量级和灵活性。Mininet 是基于 Linux 的用户模式 Linux 网络命名空间技术实现的,这使得它可以很方便地在各种 Linux 系统上运行。

而且,Mininet 的网络拓扑结构可以灵活定制,无论是简单的链式拓扑、树形拓扑,还是复杂的自定义拓扑,都能通过简单的配置文件或命令行参数来实现。

同时,Mininet 还支持多种网络仿真工具的集成,如 Wireshark 等,方便对网络流量进行分析。

安装

安装 Mininet 的过程相对简便,但需要确保你的系统满足一定的前提条件。以下是基于 Ubuntu 系统的安装步骤:

  1. 首先,需要更新系统的软件包列表。在终端中输入命令 sudo apt-get update,让系统获取最新的软件包信息。
  2. 然后安装必要的依赖库。通过运行 sudo apt-get install -y build-essential autoconf automake libtool pkg-config gawk git python python-pip python-dev tcpdump wireshark sqlite3 curl bzip2 openvswitch-datapath-dkms openvswitch-switch openvswitch-common 命令,可以一次性安装这些依赖,它们是 Mininet 正常运行和后续功能扩展的基础。
  3. 接下来就是安装 Mininet 本身。可以从 Mininet 的官方仓库克隆代码,使用命令 git clone git://github.com/mininet/mininet,然后进入 Mininet 目录,运行 mininet/util/install.sh -a 命令进行安装。这个安装脚本会自动完成编译和安装过程,安装完成后,系统会提示安装成功的相关信息。

如果是在其他 Linux 发行版上,安装步骤可能会略有差异,但大体思路是相似的,就是要先安装依赖,再获取并安装 Mininet 代码。同时,也可以选择使用虚拟机软件,如 VirtualBox 或 VMware 等,安装一个 Ubuntu 虚拟机,然后在虚拟机中进行上述安装过程,这样可以避免对宿主机系统产生影响,方便实验环境的管理和维护。

使用

安装完 Mininet 后,就可以开始体验它强大的功能了。最基本的使用方式是通过命令行来创建和操作网络拓扑。

  1. 创建网络拓扑

    • Mininet 提供了简单的命令行参数来快速创建常见的网络拓扑。例如,运行命令 sudo mn,就会自动创建一个包含两个主机、一个交换机和一个控制器的简单网络拓扑。主机之间通过交换机进行通信,控制器用于管理交换机的行为。
    • 如果想要创建更复杂的拓扑,可以使用 --topo 参数。比如,使用命令 sudo mn --topo linear,4,就会创建一个 4 个主机呈线性连接的拓扑,主机 1 连接到交换机 1,交换机 1 连接到主机 2,依此类推,形成一条链式结构。
  2. 操作网络设备

    • 在创建好网络拓扑后,Mininet 会进入交互式命令行界面。在这个界面中,可以对网络设备进行各种操作。例如,可以通过 h1 命令进入主机 1 的命令行界面,在主机 1 上执行网络相关的命令,如 ping h2 来测试主机 1 和主机 2 之间的连通性。如果网络配置正确,应该可以看到主机 1 向主机 2 发送 ICMP 请求并收到回复的信息,这表明网络通信是正常的。
    • 对于交换机,可以使用 ovs-vsctl 命令来查看和配置交换机的端口信息、流表等。例如,ovs-vsctl show 命令可以显示交换机的详细信息,包括交换机的名称、端口号、连接的主机等。
  3. 自定义脚本

    • 当然,Mininet 也支持使用 Python 脚本来自定义更复杂的网络行为和实验场景。你可以编写自己的 Python 脚本来定义网络拓扑、配置网络设备参数以及实现特定的网络功能。例如,你可以通过继承 Mininet 的拓扑类,创建一个包含多个子网络、不同带宽和延迟设置的复杂拓扑,并在脚本中对交换机的流表进行编程,实现特定的流量转发策略,如负载均衡、流量过滤等。这种方式为用户提供了极大的自由度,能够满足各种个性化的网络实验需求。

总结

总之,Mininet 作为一款网络实验工具,凭借其简单易用、功能强大的特点,在网络领域有着广泛的应用。

无论是初学者入门网络知识,还是专业研究人员进行深度网络研究,Mininet 都是一个不可或缺的得力助手。通过掌握 Mininet 的安装与使用方法,你就可以开启一段精彩的网络实验之旅,探索网络世界的无限奥秘。

未完待续

  •  

Ubuntu 系统无法通过 pip 命令安装 Python 库问题解决

为了更好的执行 Python 脚本,杜老师习惯使用 Ubuntu 系统,不过在安装 Python 库时经常报错。收集了安装 Python 库的报错信息,并整理了解决办法,供需要的小伙伴们参考。

问题提示

这里以上一篇《使用 Python 脚本实现图片相似度匹配》文中代码为例,首次执行时的报错信息如下:

1
2
3
4
5
penn@penn-VMware-Virtual-Platform:~/图片$ python3 1.py
Traceback (most recent call last):
File "/home/penn/图片/1.py", line 4, in <module>
import imagehash
ModuleNotFoundError: No module named 'imagehash'

根据报错信息,提醒找不到 imagehash 模块,使用 pip3 命令安装需要的模块,结果又出现了错误信息。这个信息表明正在尝试在一个由操作系统管理的 Python 环境中直接安装 Python 相关的包,为了保证系统 Python 环境的稳定性和安全性而采取限制措施:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
penn@penn-VMware-Virtual-Platform:~/图片$ pip3 install imagehash
error: externally-managed-environment

× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
python3-xyz, where xyz is the package you are trying to
install.

If you wish to install a non-Debian-packaged Python package,
create a virtual environment using python3 -m venv path/to/venv.
Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
sure you have python3-full installed.

If you wish to install a non-Debian packaged Python application,
it may be easiest to use pipx install xyz, which will manage a
virtual environment for you. Make sure you have pipx installed.

See /usr/share/doc/python3.13/README.venv for more information.

note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.

解决方法

解决的方法有很多,这里推荐使用虚拟环境。因为使用虚拟环境可以避免直接修改系统的 Python 环境,同时方便管理依赖。按照提示创建一个虚拟环境,使用 python3 -m venv myenv 来创建虚拟环境,使用 source myenv/bin/activate 激活虚拟环境:

1
2
penn@penn-VMware-Virtual-Platform:~/图片$ python3 -m venv myenv
penn@penn-VMware-Virtual-Platform:~/图片$ source myenv/bin/activate

在激活虚拟环境后,使用以下命令安装所需的包。安装完成后运行命令 deactivate,退出虚拟环境:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
(myenv) penn@penn-VMware-Virtual-Platform:~/图片$ pip install imagehash
Collecting imagehash
Downloading ImageHash-4.3.2-py2.py3-none-any.whl.metadata (8.4 kB)
Collecting PyWavelets (from imagehash)
Downloading pywavelets-1.8.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (9.0 kB)
Collecting numpy (from imagehash)
Downloading numpy-2.2.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (62 kB)
Collecting pillow (from imagehash)
Downloading pillow-11.2.1-cp313-cp313-manylinux_2_28_x86_64.whl.metadata (8.9 kB)
Collecting scipy (from imagehash)
Downloading scipy-1.15.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (61 kB)
Downloading ImageHash-4.3.2-py2.py3-none-any.whl (296 kB)
Downloading numpy-2.2.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (16.1 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 16.1/16.1 MB 21.3 MB/s eta 0:00:00
Downloading pillow-11.2.1-cp313-cp313-manylinux_2_28_x86_64.whl (4.6 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.6/4.6 MB 38.6 MB/s eta 0:00:00
Downloading pywavelets-1.8.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.5 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.5/4.5 MB 38.6 MB/s eta 0:00:00
Downloading scipy-1.15.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (37.3 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 37.3/37.3 MB 41.4 MB/s eta 0:00:00
Installing collected packages: pillow, numpy, scipy, PyWavelets, imagehash
Successfully installed PyWavelets-1.8.0 imagehash-4.3.2 numpy-2.2.5 pillow-11.2.1 scipy-1.15.2
  •  

使用 Python 脚本实现图片相似度匹配

随着相机像素越来越大,图片体积也变大了。在图片处理中,较大的文件体积会影响性能,因此杜老师会先生成缩略图,筛选完成后再通过 Python 脚本实现图片相似度匹配。这里是一个简单的示例,供需要的小伙伴们参考。

脚本说明

以下是个基于 Python 的脚本,使用 PIL 以及 imagehash 库来实现。

遍历目录 A 中所有图片。

在目录 B 中查找相似的图片「通过感知哈希算法判断」

如找到匹配项,则将图片复制到目录 C,并以目录 A 图片的名字命名。

安装依赖

1
pip install pillow imagehash

注意:在运行脚本前,需安装所需的 Python 库。

脚本示例

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
import os
import shutil
from PIL import Image
import imagehash

# 定义目录路径
dir_a = 'path/to/dirA'
dir_b = 'path/to/dirB'
dir_c = 'path/to/dirC'

# 设置相似度阈值(越小越严格)
threshold = 5

# 获取图片的感知哈希值
def get_image_hash(filepath):
try:
return imagehash.phash(Image.open(filepath))
except Exception as e:
print(f"无法处理文件 {filepath}: {e}")
return None

# 判断两个哈希值是否相似
def is_similar(hash1, hash2):
return hash1 - hash2 <= threshold

# 确保目标目录存在
os.makedirs(dir_c, exist_ok=True)

# 遍历目录 A
for filename in os.listdir(dir_a):
file_a_path = os.path.join(dir_a, filename)

# 检查是否为图片
if not filename.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp')):
continue

hash_a = get_image_hash(file_a_path)
if hash_a is None:
continue

# 遍历目录 B 寻找相似图片
for b_filename in os.listdir(dir_b):
file_b_path = os.path.join(dir_b, b_filename)

# 检查是否为图片
if not b_filename.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp')):
continue

hash_b = get_image_hash(file_b_path)
if hash_b is None:
continue

if is_similar(hash_a, hash_b):
# 构建目标路径
file_c_path = os.path.join(dir_c, filename)
# 复制并重命名文件
shutil.copy(file_b_path, file_c_path)
print(f"已找到匹配: {filename} -> {b_filename}, 已复制到 {file_c_path}")

注意:将 dir_a, dir_bdir_c 替换为实际路径;threshold 控制图像相似度阈值,可以根据需要调整;支持多种常见格式图片文件;使用 imagehash.phash 进行感知哈希的比较,适合用于识别视觉上接近的图片。

运行效果

1
2
3
4
5
(myenv) penn@penn-VMware-Virtual-Platform:~/图片$ python3 1.py
已找到匹配: image105.jpg -> 1745928332994.jpg, 已复制到 c/image105.jpg
已找到匹配: image001.jpg -> 1745736425856.jpg, 已复制到 c/image001.jpg
已找到匹配: image017.jpg -> 1745736425221.jpg, 已复制到 c/image017.jpg
已找到匹配: image085.jpg -> 1745928334851.jpg, 已复制到 c/image085.jpg

注意:脚本运行过程可能会有错误提示,需要根据提示进行修复。

  •  

几种通过 FFmpeg 无损压缩视频的方法

北京这边天气不错,特别适合骑行。杜老师拿出了压箱底的全景相机,打算录制一段沿途景色,结果压制出的文件体积很大。之前分享过通过 FFmpeg 来压缩视频的方法,这次整理了更多的方法,供需要的小伙伴们参考!

写在前面

如果需要了解 FFmpeg 的安装方法,可以浏览《如何使用 FFmpeg 来压缩视频》一文,里面有详细介绍如何在 Linux 系统安装 FFmpeg。

如果需要在 Windows 系统上安装 FFmpeg,可以直接至官方下载安装包「或在评论区中留言」

用 CRF 参数

原理:CRF 是 H.264 编码器中用于控制视频质量的一个参数,数值越小画质越高,体积越大,一般取值范围为 18-28,默认值 23,18 是视觉无损。

命令示例:ffmpeg -i input.mp4 -c:v libx264 -crf 18 -preset veryslow -c:a copy output.mp4 此命令指定了视频编码器为 libx264,设置 CRF 的参数为 18,且使用 veryslow 预设以进一步提高编码质量,音频部分直接复制。

更改格式

原理:在不改变媒体编码的情况下,改变媒体封装格式,通常转换后的大小基本相同,一般不会出现过大差距,如果大小差距过大,需要检查媒体文件的完整性。

命令示例:ffmpeg -i input.mp4 -codec copy output.mp4 可直接更改封装格式,无需重新编码。

调分辨率

原理:降低视频分辨率可显著减小文件体积,对于对视频画质要求不是特别高,或需要在低分辨率设备上播放的场景比较适用。

命令示例:ffmpeg -i input.mp4 -vf scale=1280:720 -c:a copy output.mp4 该命令会将视频的分辨率调整为 1280×720 像素,音频的部分不进行重新编码,从而实现压缩体积目的。

调比特率

原理:降低视频比特率可以在保持原始分辨率的同时减小文件体积,适当减少比特率能够有效的减少文件大小。

命令示例:ffmpeg -i input.mp4 -b:v 2500k -c:a copy output.mp4 此命令将视频比特率设置为 2500kbps,音频流则直接复制。

用 HEVC 编码

原理:HEVC 是一种更高效的视频编码格式,在同等画质下,相较于 H.264 编码,可使文件体积更小。

命令示例:ffmpeg -i input.mp4 -c:v libx265 -crf 28 -preset medium -c:a aac -b:a 128k output.mp4 其中-c:v libx265 指定输出的视频编码器为 libx265-crf 28 指定 CRF 参数为 28-preset medium 平衡视频质量和压缩速度,-c:a aac -b:a 128k 表示音频部分使用 AAC 编码,并设置了音频码率为 128kbps。

  •  

天津游记「多图预警」

刚从合肥返京,就收到了天津出差任务。虽然京津距离不远,但杜老师平时工作较忙,周末一般都在家睡懒觉,所以也是想着趁此机会游玩一下!分享给未来过天津的小伙伴,大家来云旅游~

天津之旅

天津是中国北方的一座历史文化名城,同样是直辖市之一,有着丰富的历史底蕴和独特城市风貌。

天津建筑风格多样,中西合璧,例如五大道保存着众多西式建筑,意大利风情街则充满了浓郁异国情调。

此外,天津还有着众多的名胜古迹,例如盘山、独乐寺等等自然与人文景观,展现了其深厚文化底蕴。

天津的旅游特色主要体现在其独特的文化韵味和美食文化上,是体验津味文化与北方风情绝佳之地。

天津美食文化源远流长,如狗不理包子、煎饼果子等等传统小吃闻名全国,散发着独特的魅力。

此外,天津的相声文化也独具特色,古文化街、泥人张彩塑等更是让人感受到天津的艺术之美。

游记留影

天津的民国时代的建筑较多,也是别有一番风味:

张学良故居的餐厅:

张学良和赵四小姐卧室:

顶层是个舞厅,本来拍了歌厅整体,结果有个大爷入镜了,所以只有观众席给大家看看:

这叫聚丰当铺,可以清楚的观察到民国时代当铺格局:

这个是鹤竹堂药铺,据说是曾给慈禧光绪看病的御医所开:

皇宫舞厅,为什么杜老师想到依萍:

天津市特别警察局,杜老师也想拍亮堂点的,这里边就是暗光线,可能是想震慑罪犯:

瑞蚨祥成衣店,里边格局也很大气漂亮,就是衣服看着有一点少,毕竟都叫成衣店了,怎么衣服比杜老师的都要少:

成衣店顾客等待位,本来不想放这张的,但是这个窗和格局吸引了杜老师,所以还是放上来了:

这个是鼎章照相馆,杜老师除了会说漂亮外,不会说别的了,原谅杜老师言辞的匮乏:

民国时代诊所,不过感觉杜老师小时候诊所也长这个样子,可能杜老师也挺老的了:

这个是商会俱乐部,有很多张,但里边的光线不是很好,只有这张看起来还是不错的:

国父孙中山办公室,右上角露出来的点点就是他照片,不过相机没有全部收录进去,右侧还有一个很好看的壁炉,哈哈:

头一次看见民国的封条,必须拍照一张,杜老师一直以为封条只要有个封字就可以,没想到要写这么多东西:

这个是春和大戏院,张学良故居进门开始可以玩剧本杀的,好多人在走来走去的找线索,杜老师没有好意思参与进去,不过感觉很好玩的,大家有兴趣的可以参观的同时玩这个游戏。这个戏院里还有相声表演的,不过是固定的时间,杜老师忙着赶下一个参观地,所以并没有听相声,可惜:

最后用民国画报小广告来做结尾,张学良故居以及范竹斋故居之旅就结束啦:

全都是人,大家都在门口想拍出满意的照片,杜老师就只匆匆闪过了,毕竟杜老师没有高超的运镜技术:

这个是最后的晚餐,教堂里也好多的人,想找出一张没人的照片实在是太难了:

感觉这个吊灯和玻璃都漂亮的很,但是杜老师对宗教理解不深,不知道这个里边画面的含义,要是有解说就好了:

这个好像就是主教传教的地方吧,用隔离带围着,杜老师进不去,不过感觉就很神圣:

据说是溥仪和妃子们被从故宫赶出来之后住的地方,感觉就是个小洋楼:

溥仪和妃子们的小餐厅:

这个是溥仪妃子文绣的卧室:

这个是皇后婉容的卧室,感觉他们的床都好小啊,杜老师睡在上边都怕掉下来:

这个是溥仪的书房:

张园里也有剧本杀,每个时间段也有节目表演的,但是杜老师依然没赶上,时间太紧张了,下次一定要试试看:

最后用杜老师们伟大领袖毛主席给这段旅程做结尾,这个展区是爸爸妈妈他们那个年代结婚的布景,感觉爸爸妈妈他们来看肯定很有感触:

  •  

合肥游记「多图预警」

时隔一年,又一次来到了安徽省会——合肥。这次出差的时间很灵活,杜老师有半天时间可以到附近景区逛一逛,就特地带了单反相机拍了些照片。本文整理了几张特色的美照,特邀杜老师的另一半帮忙配的介绍文,感兴趣的小伙伴可进来一看!

合肥之旅

合肥是安徽的省会,简称庐州,有着 2500 多年建城史,是国家级历史文化名城,曾是三国时期兵家必争之地,也是包拯、李鸿章等历史名人故乡。

这里历史遗迹众多,例如三河古镇,因丰乐河、小南河三水流贯其间而得名,是合肥唯一 5A 景区,古镇历史悠久,古建众多,青砖灰瓦,小桥流水,宛如一幅淡雅的水墨画。

合肥不仅有深厚的历史文化底蕴,还有丰富的自然景观和现代旅游资源。

包公园是纪念北宋清官包拯而建,园内有包公祠、包公墓等景点,游客可以在此了解包拯的生平事迹和清正廉明精神。

徽园则集中展示了安徽各地的著名风景和徽派建筑,游客可半天时间领略安徽的徽风古韵。

合肥美食也是一大特色,庐州烤鸭、李鸿章大杂烩、合肥三鲜等等美食让人回味无穷。无论是对历史文化感兴趣的游客,还是喜欢自然风光和娱乐体验的游客,合肥都能满足需求。

游记留影

不需要买票哦,可直接进,不过周一闭馆,去的话要注意:

感觉徽式古建筑石雕木雕都很精致且应用广泛,都有相关典故以及故事。房梁窗户等很多地方都有精致的雕刻:

这个是徽式的古代祠堂模型,看起来很大气,请忽略杜老师不专业的摄影技术:

这个是古人的牌坊,看着真是方方正正,哦对,传说中的贞节牌坊貌似也长这个样子:

这个博物馆里,金子本来不多,这个碗是最好看滴:

爬了很多个塔,其中有很大一部分是不带电梯的。当时走到这里的时候人已经快累屁了,犹豫了很久不想爬上去,结果过来了一队旅游团,导游用喇叭喊:大家不用担心,这个塔有电梯。瞬间冲到塔里坐电梯美极了:

从塔上俯视图一张,景色还是很不错的,哇哈哈哈。下来的时候没有坐电梯,想着看看各层景色,结果有很多不知道有电梯的,杜老师听到大家边爬边骂街,上的时候在骂,下的时候也骂:

这是包公祠的井叫廉泉,根据传说,这个井可检测贪官,有个贪官喝了这个井水开始头痛,经查,他确实是贪官,所以有了这个名字:

打车去李府的时候司机告诉杜老师这里很出名,那必须要打卡,不过实在是太大了,且日头晒得很:

位于古逍遥津,emmmm 杜老师没有拍墓碑和坟茔,大家看看牌坊好了:

李府李鸿章的人物雕塑,本来是想拍大门口的牌匾的,但是人实在太多了。这个不需要买门票,但是需要网络预约免费门票,合肥这一点比较好,好多景点是免费的,对学生党也很友好:

让我们看下晚清时代的家具:

清朝各级官员胸前绣的动物,具体哪个代表哪个,还请百度,不过当时古人绣工是真的好,超好看的:

这个美术馆给杜老师最大的印象就是里边超级凉快,超级超级,凉快发冷:

欣赏艺术画作:

继续欣赏艺术画作,杜老师真是一点艺术细菌都没有,完全看不出这画的含义:

这个旋转楼梯拍照应该会很出片,但是杜老师的摄影技术也就只能到这里了,凑合着看看吧:

同样不需要预约而且不需要门票,直接进就可以,不逛这个杜老师都不知道这么多的名人竟然都是安徽人:

这个楼层有个展区是做了仿古街区的各类商店,特别有那个氛围感,就是人太多了,想拍下整个街景总有人入镜,挑了很久也就剩了这么一张:

仿客栈以及瓷器店,很有古风韵味:

一层是一个蜡像馆,有很多的出名人物都在这里,看到这个大象大家应该就知道是哪个了吧,这就是传说中曹冲称象:

这个就是包公断案现场蜡像,杜老师深深觉得喜欢看蜡像馆的,可来这里,比蜡像馆省钱,氛围还好:

三河古镇俯拍,这个是杜老师爬上没有电梯的塔才拍到的,这个塔不光没电梯!它的楼梯还特别窄,只可以放下半只脚,杜老师一路外八着上下,就像个大螃蟹:

古镇胡同,很难得有张没有行人的照片,热闹和静谧共存的徽式小镇:

徽式游廊,好多游人在另一边休息,微风吹拂:

除了这个马囧囧的样子让杜老师觉得比较好玩,这个马车厢小的出乎杜老师意料,杜老师小时候看电视剧他们出行乘坐马车还以为里边很大的,这个车厢杜老师感觉对胖子很不友好,进去就塞满了。原来古人的马车这么小的吗:

酿酒步骤,杜老师震惊的是他们真的有自己酿的酒摆在大缸里,但是看着黑漆漆的,用玻璃封住了,闻不到是什么味道,不知道还需不需要过滤:

回程坐了游艇,细细看了河两边的建筑,感觉是超级好,感觉每个时代的建筑都有它独特魅力:

  •  

在银河麒麟桌面操作系统 ARM 版上安装 KVM 虚拟化

KVM 是一种开源全虚拟化解决方案,能够在 Linux 系统运行多个操作系统。本文将详细介绍如何在银河麒麟桌面操作系统 ARM 版安装 KVM 虚拟化环境,帮助用户搭建高效的虚拟化平台。

准备工作

  1. 硬件要求

确保 ARM 架构设备支持虚拟化技术。通常,支持虚拟化的 ARM 处理器会支持硬件辅助虚拟化功能。

系统至少需要 4GB 内存和 20GB 的硬盘空间。

  1. 软件要求

银河麒麟桌面操作系统 ARM 版「如 V10」

KVM 虚拟化相关的软件包。

安装 KVM 虚拟化环境

  1. 安装 KVM 和相关工具
1
2
sudo apt update
sudo apt -y install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virt-manager

注意:在银河麒麟桌面操作系统 ARM 版上,可以通过上面命令安装 KVM 和相关工具。

  1. 包的作用

上面软件包的作用如下:

包名作用
qemu-kvm提供 KVM 虚拟化核心功能
libvirt-daemon-system用于管理虚拟机的后端服务
libvirt-clients提供客户端工具管理虚拟机
bridge-utils用于配置网络桥接
virt-manager提供图形化界面管理虚拟机
  1. 添加用户到 libvirt 组内
1
sudo usermod -aG libvirt $(whoami)

注意:为方便管理虚拟机,需要将当前用户添加到 libvirt 组,然后注销重新登录,使组成员关系生效。

  1. 验证是否安装成功
1
virsh --version

注意:运行上面命令来检查 KVM 是否正常工作,如果返回版本信息,说明 KVM 安装成功了。

创建 KVM 虚拟机

  1. 下载镜像

可以从银河麒麟官方网站下载适合 ARM 架构的虚拟机镜像文件。

Kylin-Desktop-V10-SP1-2403-Release-20240430-arm64.iso 文件。

  1. 创建虚拟磁盘
1
qemu-img create -f qcow2 /path/to/disk.img 50G

注意:使用上面命令创建虚拟磁盘。其中/path/to/disk.img 是虚拟磁盘路径,50G 表示磁盘的大小。

  1. 启动 KVM 虚拟机安装
1
qemu-system-aarch64 -m 2048 -cpu cortex-a76 -smp 4 -M virt -bios /path/to/QEMU_EFI.fd -device VGA -device nec-usb-xhci -device usb-mouse -device usb-kbd -drive if=none,file=/path/to/disk.img,id=hd0 -device virtio-blk-device,drive=hd0 -drive if=none,file=/path/to/Kylin-Desktop-V10-SP1-2403-Release-20240430-arm64.iso,id=cdrom,media=cdrom -device virtio-scsi-device -device scsi-cd,drive=cdrom

注意:使用上面命令启动 KVM 虚拟机安装。其中-m 2048 分配 2048MB 内存;-cpu cortex-a76 指定 CPU 类型;-smp 4 是指定虚拟 CPU 核心数。

  1. 完成安装

按照虚拟机安装界面的提示完成安装过程。

安装完成后 KVM 虚拟机将自动重启。

使用 KVM 管理虚拟机

  1. 使用 virsh 命令行工具

列出所有 KVM 虚拟机:

1
virsh list --all

启动 KVM 虚拟机:

1
virsh start <KVM 虚拟机名称>

关闭 KVM 虚拟机:

1
virsh shutdown <KVM 虚拟机名称>

强制停止 KVM 虚拟机:

1
virsh destroy <KVM 虚拟机名称>

挂起 KVM 虚拟机:

1
virsh suspend <KVM 虚拟机名称>

恢复挂起 KVM 虚拟机:

1
virsh resume <KVM 虚拟机名称>
  1. 使用 virt-manager 图形化界面

virt-manager 提供了一个直观的图形化界面,方便用户管理 KVM 虚拟机。

启动 virt-manager 后,可以连接到本地或者远程的 KVM 服务器,创建、启动、停止 KVM 虚拟机。

  •  

探索扣子空间「邀请码不限量分享」

当今数字化浪潮中,人工智能正以前所未有的速度改变着我们的工作和生活方式。字节跳动于 2025 年 4 月 19 日推出的通用型 AI Agent 平台,无疑是这一变革中一颗璀璨新星,为我们带来了全新的 AI 协作办公体验。

扣子空间是啥

扣子空间是个致力于打造和 AI 协作工作全新工作方式的平台。

它基于字节跳动自研的豆包等国产大模型,用户只需将任务交给智能体,系统就能自动完成需求分析、任务拆解、工具调用、结果生成,支持从网页到文档等多种类输出形式,极大提升工作效率与执行力。

核心特点功能

  1. 双重模式协作,灵活应对任务需求

扣子空间提供了探索模式和规划模式。

探索模式下 AI 自主动态探索,完成速度更快,适用于时效性强的任务,例如查询最新资讯、获取实时数据等等;规划模式中 AI 深度思考,会先给出任务处理规划,经过用户确认后再行动,执行期间也需用户参与,适合高复杂性任务,如跨行业市场调研、复杂项目规划等等。这种双模式的协作机制,让用户可根据任务属性灵活选择,能更好地与 AI 协作完成工作。

  1. 强大任务处理能力,实现自动工作流程

扣子空间能够智能解析用户的一句话需求,精准识别意图并将其分解为多个具体任务。系统会自主调用浏览器、代码编辑器等工具执行任务,同时将每个思考和执行步骤清晰呈现,适时的与用户确认意图,确保执行方向准确。

最终输出完整结果报告,如 PPT、网页、飞书文档等等,真正实现了从需求输入到成果输出的全流程自动化。

  1. 专家级 Agent 生态,提供专业领域支持

平台内置多种领域的专业 Agent,例如华泰 A 股观察助手可生成每日股市早报并解答股票分析问题,用户研究专家可以协助进行用户研究资料深度分析。

这些专家级的 Agent 针对特定领域更专业,能处理更复杂任务,为不同领域的用户提供了便捷的专业服务。

  1. 丰富插件集成,无限拓展能力边界

扣子空间首批集成飞书多维表格、高德地图、图像工具、语音合成等 60 多款 MCP 模块化能力插件,未来还将支持开发者通过扣子开发平台发布自定义插件。

这些插件涵盖资讯阅读、旅游出行、效率办公等等众多方面,使扣子空间能够满足用户在不同场景下的各种需求,真正实现了功能的无限扩展。

应用场景广泛

扣子空间应用场景十分丰富,涵盖办公、学习、生活、电商、金融等等多个领域。

在办公场景中,可以帮助用户完成撰写文档、数据分析、制作 PPT 等各种工作任务;在学习场景下,能为学生和教育工作者提供课程资料收集、课件制作等辅助教学和学习服务;在生活场景里,可以用于制定旅游计划、查询信息等等;在电商场景中,能够进行商品推荐、用户行为分析;在金融场景下,可为股票分析、金融数据解读等等提供决策支持。

截图与邀请码

扣子空间界面非常简洁,登录后可通过左侧菜单进行任务管理,输入任务描述即可快速创建任务,开始任务后会在右侧显示 Agent 执行过程:

扣子目前机制每次能生成五个邀请码,杜老师会定期更新邀请码的使用状态,也请小伙伴使用后留言邀请码的编号,用尽后会发放新邀请码:

编号邀请地址备注
1https://www.coze.cn/space-preview?invite_code=PYFNVF90已用
2https://www.coze.cn/space-preview?invite_code=TLZTCXQN已用
3https://www.coze.cn/space-preview?invite_code=MCIEP9ZP已用
4https://www.coze.cn/space-preview?invite_code=H3M95JPB已用
5https://www.coze.cn/space-preview?invite_code=0XV6MVQ3已用
6https://www.coze.cn/space-preview?invite_code=39GL3SRL已用
7https://www.coze.cn/space-preview?invite_code=LGOQDX27已用
8https://www.coze.cn/space-preview?invite_code=W9G0P33F已用
9https://www.coze.cn/space-preview?invite_code=CEP1YQD5已用
10https://www.coze.cn/space-preview?invite_code=EFUJVJ95已用
11https://www.coze.cn/space-preview?invite_code=PGYMJSN5未用
12https://www.coze.cn/space-preview?invite_code=L33JT5Q7未用
13https://www.coze.cn/space-preview?invite_code=MCAKQH6N未用
14https://www.coze.cn/space-preview?invite_code=68TDVTNL未用
15https://www.coze.cn/space-preview?invite_code=PA55VHFS未用
  •  

LibreTV 免费的在线视频观看神器

在数字媒体盛行的今天,观看电影、电视剧等视频内容成为了人们日常娱乐的重要部分。然而,许多视频平台要么需要付费订阅,要么充斥大量广告,还有的需要复杂的注册流程,极大地影响了观影体验。今天,就给大家介绍一款名为 LibreTV 的开源工具,它将彻底改变在线观影方式。

LibreTV 是什么

LibreTV 是个轻量级、免费的在线视频搜索与观看平台,无需注册账号,也无需要下载安装任何软件,更不需要付费订阅,只要连接网络,通过浏览器就可以随时随地访问。

它采用纯前端技术构建,结合了前端技术和后端代理功能,可以轻松部署在各种支持服务端功能的网站托管服务上。

LibreTV 的优势

免费使用:无需支付任何会员费用,即可畅享海量视频内容,真正实现了看片不花钱。

多源搜索:聚合了多个视频源,能更全面地搜索到电影、电视剧等各类影视资源,可轻松找到想看的内容。

跨多平台支持:无论电脑、平板还是手机设备,均能完美适配,随时随地满足观影需求。

静态部署:不需要后端服务器,部署简单快捷,大大降低了搭建和维护成本。

广告过滤:内置广告过滤功能,有效屏蔽广告干扰,提供更加干净、更优质的观影体验。

自定义 API 接口:用户可以根据自身需求添加或修改视频源,灵活性非常强,可以不断拓展影视资源。

LibreTV 的功能

多源视频搜索:覆盖丰富电影、电视剧等内容,支持多视频源自动聚合,一次搜索即可获取更多结果。

响应式 Web 设计:能够完美适配各种屏幕尺寸设备,无论是 PC 端还是移动端,都可以获得良好的观看体验。

本地存储搜索历史:将搜索历史存储在本地,方便用户下次快速查找之前看过影视内容。

快捷键的支持:播放器支持多种键盘快捷键,如全屏快进快退等,让操作更加的便捷。

HLS 流媒体支持:兼容 HLS 流媒体格式,确保视频播放更加流畅稳定。

可选密码保护:支持设置密码保护,增强访问控制,保障观影隐私。

LibreTV 的安装

  1. 用 Cloudflare Pages 部署

Fork 或者克隆 LibreTV 仓库 到 GitHub 账户。

登录 Cloudflare Dashboard 进入 Pages 服务。

点击创建项目,连接到 GitHub 仓库。

使用以下设置:构建命令「留空」(无需构建)输出目录「留空」(默认为根目录)

最后点保存并部署。

可选:在设置环境变量中配置密码保护。

  1. 用 Vercel/Netlify 部署

与 Cloudflare Pages 类似,只需要连接仓库并部署即可,无需特殊配置。

点击仓库中的部署按钮,按照提示完成部署流程。

  1. 用 Docker 部署
1
docker run -d --name libretv -p 8899:80 -e PASSWORD=your_password_here bestzwei/libretv:latest

注意:使用 Docker 运行 LibreTV,运行以上命令。然后打开浏览器输入 http://localhost:8899 即可访问。

  1. 用 Docker Compose 部署
1
2
3
4
5
6
7
8
9
10
version: '3'
services:
libretv:
image: bestzwei/libretv:latest
container_name: libretv
ports:
- "8899:80"
environment:
- PASSWORD=111111
restart: unless-stopped

注意:将上面内容保存到 docker-compose.yml 文件中,然后运行 docker-compose up -d 命令即可启动 LibreTV。

LibreTV 的使用

  1. 搜索视频:打开 LibreTV 的网页界面,直接在搜索框中输入想看的电影、电视剧关键词,点击搜索按钮或者按回车键,系统会自动聚合多个视频源。

  2. 可选择播放源:在搜索结果中,可以看到不同视频源提供的播放链接,根据喜好选择一个合适的播放源,点击进入播放页面。

  3. 播放控制:在播放页面可通过播放器的控制按钮进行播放、暂停、调整音量、可切换清晰度、拖动进度条等常规操作。此外,还可以使用键盘快捷键来进行屏、快进快退操作,提升观影体验。

  4. 查看历史记录:LibreTV 会将搜索历史存储在本地,可在搜索框下方或相应的历史记录区域查看和点击之前搜索过的内容,方便快速查找以及继续观看。

LibreTV 的效果

杜老师提供的免费平台:

LibreTV 以其丰富的功能、简洁的界面以及便捷的操作,为用户带来全新的在线观影体验。无论是在家中放松休息,还是在旅途中打发时间,它都能满足随时随地观看影视内容的需求:

  •  

Electerm 高效便捷的开源终端工具

在数字化工作时代,一款高效、便捷的终端工具对于开发者、系统管理员和网络工程师等人群来说至关重要。Electerm 作为一款开源免费的跨平台终端模拟器,凭借其丰富的功能和优秀的用户体验,成为了众多用户的首选。

Electerm 的简介

集终端模拟器、文件管理、远程连接、SFTP 客户端等功能于一体,支持 Windows/macOS 和 Linux 等多种操作系统。不仅功能强大,而且界面简洁直观,易于上手。

Electerm 支持在同一窗口中运行多个 SSH 会话,方便用户可同时管理多个远程服务器。同时,它还支持多种认证方式,包括密码、密钥、双因素认证等,充分满足不同用户安全需求。

安装方法

  1. Windows 系统的安装方法

访问 Electerm 的 官方网站,进入下载页面,找到 Windows 相关安装包。下载完成后双击安装包,进入欢迎界面,选择安装模式,浏览选择安装位置点击安装,等待安装完成即可。

另外,也可选择下载免安装版,解压到磁盘自定义目录,直接打开 electerm.exe 就能使用了。

  1. Linux 系统的安装方法

对于一些 Linux 发行版,如 Ubuntu、Kylin 等,用户可直接通过系统的内置软件商店进行安装:

使用方法

  1. SSH 连接项

打开 Electerm 后,在主界面点击左上角的加号,选 SSH。在弹出的对话框中输入主机地址、用户名以及密码等相关信息,点击连接按钮。

  1. 文件传输

在连接到远程服务器后,点击左侧边栏文件管理选项,进入文件管理界面。在该界面中用户可以看到本地和远程服务器的文件目录,通过简单拖拽操作,即可实现文件的上传和下载。

  1. 自定义快捷键

Electerm 允许用户自定义快捷键和主题,以满足个人操作习惯和视觉喜好。点击顶部菜单栏的设置选项,进入设置界面。在快捷键部分,用户可根据自己的需求对各种操作的快捷键进行修改和设置。在主题项部分,提供多种预设的主题供用户选择,同时用户也可以根据自己的喜好对主题的颜色、字体等进行自定义调整。

  1. 其它功能

Electerm 支持多语言,包括英语和中文等,用户可以在设置中进行语言切换。此外,它还具有自动完成、自动重连、透明窗口、终端背景图像等等功能,为用户提供更加便捷和个性化的使用体验。

效果截图

Electerm 支持 SFTP 功能,方便用户在本地和远程服务器间传输文件:

成功连接到远程服务器,进行相关的操作和管理:

  •  

Wave Terminal 多功能开源终端工具

在现代开发工作中,终端是我们必不可少的工具之一。今天要给大家介绍的 Wave Terminal,无疑是一款将传统终端功能与图形化能力完美融合开源终端,能够极大地提升我们的工作效率。

Wave Terminal 的简介

Wave Terminal 是一款支持 macOS/Linux 和 Windows 三大操作系统跨平台终端。

它不仅具备常规的终端功能,还集成了诸多高级特性,例如文件预览、网页浏览、AI 对话等。这使得开发者在使用终端时,无需频繁切换其它应用程序,即可完成多种任务。

下载安装

访问 Wave Terminal 的官方网站,下载安装包后,按照安装向导进行操作即可完成安装:

使用方法

界面布局模块操作:Wave Terminal 的默认界面左侧为终端命令行模块,中间区域分别是 CPU 性能、浏览器和本地文件路径模块,右侧则有帮助、提示和 AI 对话模块。这些模块均可根据个人需求随意拖动位置、多开、添加、删除。

多命令行窗口使用:可同时打开多个命令行窗口,方便在不同项目或任务之间切换。例如,在一个窗口中运行项目服务,另一窗口中执行相关命令进行调试等操作。

文件路径浏览操作:在文件路径模块中,用户不仅可以查看文档、图片,还能播放视频。直接输入文件路径或者通过图形界面浏览文件系统,快速定位到所需文件并进行编辑或者查看。

网页浏览功能:利用内置的浏览器模块,可以直接在终端中浏览网页。这在需要查阅技术文档、搜索解决方案等场景下非常方便,无需切换到其它浏览器,节省了时间和精力。

AI 对话的功能:借助右侧的 AI 对话模块,用户可以与 AI 进行交流。无论寻求编程建议、解决问题思路,还是进行其它知识性的问答,都能得到及时的回复和帮助。

远程连接功能:通过 Wave Terminal 可以方便地连接到本地内网的 Linux 服务器。以 Ubuntu 系统为例,先在 Ubuntu 系统安装 SSH 服务,执行 sudo apt -y install openssh-server 命令进行 SSH 安装,安装完成后执行 sudo systemctl status ssh 命令查看 SSH 的服务状态,若显示绿色 running 提示则表示服务已启动。然后在 Windows 系统 Wave Terminal 中,输入 ssh 用户名@服务器 IP 命令,输入密码后即可连接到远程 Linux 服务器。

工具截图

Wave Terminal 的强大之处在于它将多种实用功能整合到一个终端工具中,无需再频繁的切换应用程序,大大提高工作效率。无论是开发人员还是系统管理员,都能在这款工具中找到诸多便利之处,它无疑是现代终端工具中的一颗新星,值得大家尝试使用:

  •  

SimpleMindMap 开启思维可视化之旅

在信息爆炸的时代,思维导图已经成为高效整理知识、梳理思路必备工具。而 SimpleMindMap 作为一款强大的 Web 思维导图工具,凭借其独特的魅力,正吸引着越来越多用户目光。

SimpleMindMap 是什么

SimpleMindMap 既是思维导图的 js 库,也是一个完整思维导图工具。

功能丰富,能满足思维导图的各种需求,无论是简单的想法记录,还是复杂知识体系构建。

其插件化设计理念,使得除核心功能外的其它能力都作为插件提供,用户可以按需选择,避免了冗余代码的困扰。

而且易于使用,开箱即用,配置丰富,文档清晰,无论是编程新手还是有经验的开发者,都能快速上手。

安装方法

  1. 在线使用

最便捷的方式便是直接在线使用。这种方式适合临时使用或者快速尝试工具功能的场景。

访问 在线思绪思维导图,无需繁琐安装过程,即可立即开始创建思维导图。

  1. 本地部署
1
2
3
4
5
6
7
8
9
services:
mind-map:
image: hraulein/mind-map:latest
container_name: mind-map
restart: always
ports:
- "8080:8080"
environment:
- GIN_MODE=release # debug 为调试模式

注意:对于一些对数据安全和隐私有严格要求的用户,本地部署是最理想选择。将上面的内容保存为 docker-compose.yml 文件,然后用 docker-compose up -d 命令启动容器。

使用方法

  1. 创建思维导图

打开 SimpleMindMap 应用后,首先会看到一个简洁的界面。点击「新建」按钮,即可开启一张新的思维导图。

在中心出现一个根节点,这是思维导图起点。可双击根节点,为其输入主题名称,比如「我的学习计划」。

  1. 添加分支节点

确定好主题后,接下来就是添加分支节点来细化内容。先选中根节点,会发现有一些添加子节点的按钮或快捷键提示。

通常可以通过点击这些按钮或使用快捷键「如 Tab 键等」来创建子节点。例如,在「我的学习计划」根节点下,添加「语文」「数学」「英语」等学科子节点。

  1. 编辑节点内容

对于每个节点,不仅可以修改文字内容,还可以进行丰富的格式设置。在选中节点后,可通过顶部菜单栏或者右键菜单找到编辑选项。

比如,可以设置字体大小、颜色,加粗、倾斜文字,甚至可以插入图片、链接等多媒体元素。

  1. 调整布局

SimpleMindMap 提供了多种布局方式,以满足不同的展示需求。在菜单栏找到布局选项,有常见的思维导图布局。

可根据思维导图的内容结构和美观度考虑,随时切换布局,直观地看到不同的展示效果。

插件拓展

SimpleMindMap 的插件化特性是一大亮点。用户可根据自身需求安装各种插件来增强功能。

例如,有用于团队协作的插件,可让多个用户同时编辑一张思维导图,实时看到彼此修改;还有用于数据分析插件,能够对思维导图中的内容进行简单的统计分析,如节点数量统计、关键词频率分析等,为用户提供更好数据支持和决策依据。

  •  

Logseq 高效知识管理与协作利器

Logseq 以其出色的知识管理能力、便捷协作功能、强大的隐私保护以及灵活的可扩展性,成为了日常学习和工作中不可或缺的工具。不仅帮助高效地记录和整理知识,还激发了创造力和思考能力。

Logseq 的简介

Logseq 是一款开源的本地优先知识管理和协作平台,它完美融合了大纲笔记与双链笔记的优势,还注重用户的个人隐私保护。支持多种文件格式,包括 Markdown 等,满足不同用户写作习惯,同时提供了丰富的插件生态系统,用户可以根据自身需求扩展功能:

它不仅具备强大的笔记编辑能力,还内置了任务管理、日历视图、知识图谱功能,助力用户更好规划工作、学习、生活,无论整理学习资料、记录工作要点,还是进行团队协作,Logseq 都可以轻松胜任:

Logseq 的安装

Logseq 的安装十分便捷。电脑端用户可以从 官网,根据自身操作系统选择对应的安装包进行下载安装,如 Windows、Linux 等都有适配版本。首次打开会自动创建一个知识库,也可以根据需要自行创建新的知识库。

手机端用户同样可以在 App Store 或官网下载安卓端 Logseq 应用程序,实现移动端与桌面端的无缝同步,方便用户随时随地查看、编辑笔记。

Logseq 的使用

  1. 创建编辑笔记:在 Logseq 创建笔记非常简单,点击界面右下角的加号按钮,即可新建笔记。在编辑界面可以使用 Markdown 语法文本进行排版,例如设置标题、段落、列表、链接等等,还可插入图片、表格等等元素,让笔记内容更加的丰富多样。

  2. 添加标签属性:为更好地对笔记进行分类和管理,可为笔记添加标签。在笔记编辑界面中,点击右上角的「标签」按钮,输入相关标签名称即可。此外 Logseq 支持为笔记添加属性,如优先级、状态、日期等等,方便用户从不同维度对笔记进行筛选、查询。

  3. 双向链接:这是 Logseq 的核心功能之一。当在一篇笔记中提及另一个已存在的笔记内容,Logseq 会自动在两者间建立双向链接。也可以手动在笔记中入「笔记名称」的形式来创建链接,通过双向链接,可以轻松构建起一个有机的知识网络,方便在不同笔记间穿梭浏览,发现知识间的隐含关联。

  4. 知识图谱:借助知识图谱功能,可以直观地看到笔记之间的链接关系。点击界面左侧边栏「知识图谱」按钮,即可进入图谱视图。在这个视图中,节点之间的连线表示它们之间的双向链接关系。可以通过放大、缩小、拖拽等操作来浏览图谱,还可以查看某个笔记的关联笔记列表。

Logseq 的进阶

  1. 使用插件扩展功能:Logseq 的插件市场提供了丰富多样的插件,如增强的表格编辑插件、思维导图插件、PDF 注释插件等。可在 Logseq 的设置界面中找到件管理选项,浏览并安装需要的插件,以进一步提升工作效率。

  2. 数据同步备份:支持与多种云存储服务集成,如 GitHub、Google Drive 等,确保笔记数据在不同设备间实时同步。此外,还可以定期对数据进行本地备份,防止数据丢失。

  •  

Linux 系统监控利器 ctop 命令详解

在 Linux 系统,尤其是当我们在管理多个容器时,了解系统和容器的资源使用情况至关重要。今天,就给大家介绍一款强大的监控工具 ctop,本文详细介绍 ctop 的安装、使用、命令选项。

ctop 命令的简介

ctop 是一个类似 top 命令的界面工具,它专注于容器环境,能够实时监控 Docker/Podman 等容器运行时的性能指标,如 CPU、内存、网络、磁盘 I/O 等使用情况。

它以一种直观的方式展示各个容器的详细信息,让管理员可以迅速掌握系统整体健康状况,并且快速定位到可能存在性能瓶颈的容器。

与传统 top 命令相比,ctop 提供更丰富的容器相关数据和更便捷的交互方式。

它不仅能展示容器的基本资源使用率,还能深入到每个容器的进程级别,查看内部运行具体进程,这对于深入分析容器性能表现非常有帮助。

ctop 命令的安装

  1. Linux 系统的安装方法「以 Ubuntu 为例」
1
2
sudo wget https://github.com/bcicen/ctop/releases/download/v0.7.7/ctop-0.7.7-linux-amd64 -O /usr/local/bin/ctop
sudo chmod +x /usr/local/bin/ctop

注意:可以直接从 Github 下载最新版本的二进制文件进行安装,以上是具体的步骤「这里以 v0.7.7 版本为例」最后,用命令 ctop -v 验证是否安装成功,若可以正确显示版本号,说明安装成功。

  1. 通过 Docker 的方法安装
1
docker run --rm -it --name=ctop -v /var/run/docker.sock:/var/run/docker.sock quay.io/vektorlab/ctop:latest

注意:也可以使用 Docker 快速启动 ctop 容器来进行监控。

ctop 命令的使用

  1. 基本使用

在终端中输入 ctop 命令后回车,即可启动 ctop 程序进入主界面。在界面中,会显示出所有正在运行的容器及其资源使用情况的概览,包括容器名称、CPU 使用率、内存使用量及限制、网络收发速率、磁盘读写速率、进程数等信息。

可以通过方向键上下移动光标来选择不同容器,然后按下回车键可以查看到所选容器详细信息,如容器的创建时间、各资源的详细使用数据以及内部运行的进程列表等。

  1. 命令选项

命令选项列表如下:

选项描述
ctop -a只查看正在运行中容器,方便专注那些实际处于活动状态、可能对系统资源产生影响的容器。
ctop -f string查看包含指定字符串的容器,当系统中有大量容器时,利用此选项可快速过滤出我们关心的特定容器进行监控。
ctop -i反转默认颜色,如默认的颜色显示效果不佳,或需要与其它界面风格保持一致,可使用该选项来改变界面的颜色显示。
ctop -r反向容器排列顺序,默认情况下存活的容器在前,使用此选项可将其顺序反转,以便按照不同顺序查看容器。
ctop -s string按照指定字段排序,如执行 ctop -s net 可以按照网络使用率对容器进行排序,从而快速找到网络流量较高容器。

交互操作

交互操作列表如下:

操作描述
h打开帮助,在使用过程中如果忘记了某些快捷键的功能或者想了解更多操作方法,可以随时按下 h 键查看帮助信息。
s打开排序,通过此快捷键可以方便地切换不同的排序字段,无需重新输入命令选项。
q退出打开的对话框,当查看完帮助信息或排序设置后,按下 q 键可以退出相应的对话框,返回到主界面。
a只显示正在运行的容器,与 ctop -a 命令效果一致,但在已经启动了 ctop 程序的情况下,使用快捷键可更快速地切换显示模式。
r反转排序,正在运行容器放在末尾,方便在不同的排序需求之间快速切换。
f输入指定字符串过滤出想要查看容器,与 ctop -f string 命令类似,无需重新输入命令,直接在当前界面中进行过滤操作。
j用于向下移动光标,方便在容器列表中快速定位到不同的容器。
k用于向上移动光标,方便在容器列表中快速定位到不同的容器。
Enter查看指定容器详细指标,当光标定位到某个容器,按下回车键即可进入该容器详细信息界面,查看更全面的资源使用以及进程信息。
  •  

Linux 下的高效压缩工具 Zstandard

Zstandard 以其卓越的性能和丰富的功能,成为了 Linux 下一款不可或缺的压缩工具。无论是对单个文件还是整个目录的压缩和解压,它都可以轻松应对,且在处理速度和压缩效果上都有着出色的表现。

Zstandard 的简介

Zstandard 是由 Facebook 开发并开源的一种快速无损压缩算法,2015 年首次发布以来,凭借其高压缩比和快速的解压缩速度,逐渐受到了开发者青睐。

它不仅在压缩效率上超越传统的 gzip 等工具,还能在保持高压缩率的同时,实现极快解压速度,特别适合对数据处理效率要求较高的场景,如大数据处理、日志压缩、网络数据传输等等。

Zstandard 的特点

高压缩比:通常情况下 Zstandard 能够获得比 gzip 更好压缩效果,有效减少数据存储空间。

快速解压:其解压缩速度极快,即使是低压缩等级,解压速度也能远超一些 SSD 的读取速度,大大提高了数据的读取效率。

多线程的支持:Zstandard 自带多线程压缩功能,可以充分利用多核 CPU 的性能,大幅提升压缩速度。例如,在处理大量数据时,多线程压缩能够显著的缩短压缩时间,提高工作效率。

丰富压缩级别选择:提供了从 1 到 22 的压缩级别选择,用户可根据实际需求在压缩速度和压缩率之间进行灵活权衡。压缩级别越高,压缩比率越大,但压缩速度会相应减慢;反之,压缩级别越低,压缩速度越快,但压缩比率会有所降低。

字典压缩模式:Zstandard 为小数据提供一种特殊的字典压缩模式。用户可通过提供一些样本数据来训练生成字典,然后在压缩和解压时加载该字典,从而在小数据上实现更高压缩率,这对于处理大量小文件场景非常有用。

使用模式:Zstandard 提供了多种命令模式,包括压缩、解压、查看压缩信息、测试压缩文件等等。

Zstandard 的安装

Debian/Ubuntu 系统的安装命令如下:

1
sudo apt install zstd

Fedora/Red Hat/CentOS/AlmaLinux 系统的安装命令如下:

1
sudo dnf install zstd

Arch Linux/Manjaro 系统的安装命令如下:

1
sudo pacman -S zstd

也可以从源码编译安装「这里以 1.5.7 版本为例」命令如下:

1
2
3
4
5
wget https://github.com/facebook/zstd/releases/download/v1.5.7/zstd-1.5.7.tar.gz
tar -zxvf zstd-1.5.7.tar.gz
cd zstd-1.5.7/
make
sudo make install

Zstandard 的使用

  1. 压缩文件

基础压缩:使用命令 zstd file_name 即可对文件进行压缩,压缩后会生成一个扩展名为.zst 的文件,如 zstd doc.txt,会生成 doc.txt.zst 文件。

指定压缩级别:可通过选项来指定压缩级别,例如 zstd -3 file_name 表示使用压缩级别-3 进行压缩。

  1. 解压文件

基础解压:使用 zstd -d archive_name.zst 即可对文件进行解压,解压后的文件会自动去除.zst 后缀。

指定解压后文件名:同样可使用-o 选项来指定解压后的文件名,如 zstd -d archive_name.zst -o new_file_name

  1. 压缩目录

压缩整个目录:可以使用 zstd -rz directory_name 来压缩整个目录,其中-r 表示递归压缩目录中所有文件和子目录,-z 表示压缩的操作。

解压目录:对于压缩后的目录文件,使用 zstd -dr archive_name.zst 进行解压缩,-d 表示解压缩操作,-r 表示递归解压缩。

  1. 查看压缩文件内容

使用 zstd -l archive_name.zst 可以查看压缩文件的相关信息,如压缩比、压缩级别、文件大小等等。

zstd -t archive_name.zst 则可用于测试压缩文件的完整性,确保文件在压缩和传输过程中未损坏。

  •  

使用 Python 脚本下载指定网页的图片文件

有小伙伴反馈说侧边栏随机图出现了重复,有些审美疲劳,要求杜老师再更新一些图片,正好聊天广场有小伙伴分享了一个美图的网址。本文分享如何使用 Python 脚本下载指定网页的图片文件,需要的小伙伴可以参考文中代码。

代码需求

使用 Python 的语言编写一个脚本,下载指定网址中包含的多种格式图片文件,如 JPG 和 PNG 格式图片。

将图片保存至指定的目录中,可以指定绝对路径,或者相对路径。

并用随机数重命名,防止同名图片触发覆盖事件。

尽可能使用 Python 的标准库,尽量避免使用第三方库。

变更解释

  1. 导入必要的库:包括 os/requests/re 以及 random

  2. 定义函数:download_images 函数可用于下载图片;

  3. 获取图片链接:使用正则表达式从网页内容中提取图片 URL;

  4. 下载保存图片:使用 requests 库下载图片,并且使用 random 库生成随机数作为文件名;

  5. 指定目录:确保保存目录存在,如果不存在则创建;

  6. 获取内容:使用 requests 库获取网页内容。

功能代码

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
import os
import requests
import re
import random

def download_images(url, save_folder):
# 确保保存目录存在
if not os.path.exists(save_folder):
os.makedirs(save_folder)

# 发送HTTP请求获取网页内容
response = requests.get(url)
if response.status_code != 200:
print(f"Failed to retrieve the webpage. Status code: {response.status_code}")
return

# 使用正则表达式查找所有的图片URL
image_urls = re.findall(r'<img[^>]+src=["\'](.*?)["\']', response.text)

for img_url in image_urls:
# 处理相对路径的URL
if not img_url.startswith(('http://', 'https://')):
img_url = os.path.join(url, img_url)

# 下载图片
img_response = requests.get(img_url)
if img_response.status_code == 200:
# 生成随机文件名
random_filename = f"{random.randint(10000, 99999)}.jpg"
save_path = os.path.join(save_folder, random_filename)

# 保存图片
with open(save_path, 'wb') as f:
f.write(img_response.content)
print(f"Downloaded and saved {img_url} as {save_path}")
else:
print(f"Failed to download {img_url}. Status code: {img_response.status_code}")

# 读取网址列表文件
def read_urls_from_file(file_path):
with open(file_path, 'r') as file:
urls = file.readlines()
return [url.strip() for url in urls]

# 示例调用
if __name__ == "__main__":
urls_file = 'f:\\代码\\urls.txt' # 包含网址的文件路径
save_folder = 'f:\\代码\\images' # 保存图片的目录路径

urls = read_urls_from_file(urls_file)
for url in urls:
download_images(url, save_folder)

注意:本示例代码仅适用于 Python 3.x 版本,运行于 Windows 系统。如使用 Linux 系统,可能需要进行相应修改。

使用说明

将上述的代码保存为 download_images.py 文件。

在运行脚本时,传入目标网页的 URL 和保存图片的目录路径。

脚本会自动下载网页中所有图片,并且以随机数命名保存到指定目录中。

打开的网址保存在一个文件,每行一个网址。

  •  

X Window 与 Wayland 的深度对比

X Window 与 Wayland 不仅代表了图形界面技术不同发展阶段,更体现了设计理念、架构模式及应用场景的显著差异。本文将从历史背景、技术特点、应用场景及未来展望等多个维度,对 X Window 和 Wayland 进行深入剖析。

历史背景演变

X11 诞生于 1984 年,由麻省理工学院 MIT 开发,旨在满足分布式计算环境下图形界面需求。其设计哲学强调网络透明性,允许用户在远程服务器运行应用程序,并在本地终端显示结果,极大地拓展 GUI 的可用性和灵活性。随着时间推移,X11 凭借其广泛的硬件和软件支持,逐渐成为 Linux 桌面环境的标准图形界面后端。

随着计算需求增长,X11 的一些设计局限逐渐显现,例如架构复杂、性能瓶颈和安全性问题。2008 年,Kristian 提出 Wayland 项目,旨在创建一个更加现代、高效窗口系统。Wayland 的设计重点在于简化架构、提高性能和增强安全性,采用客户端 Compositor 通信模型,减少了中间层,提升了效率和响应速度。

技术特点比较

X11 采用 C/S 模型,客户端通过 X 协议与服务器通信,而 X 服务器负责处理所有图形和输入事件。相比之下,Wayland 采用了客户端 Compositor 模型,客户端可直接与 Compositor 通信,Compositor 负责了窗口管理、合成、输出。Wayland 的架构更加贴合现代图形硬件特性,可以更高效地利用 GPU 和现代显示技术。

X11 在安全性方面存在了固有弱点,其复杂协议和广泛权限易被恶意利用。Wayland 通过限制客户端权限以及简化通信模型,显著提高了安全性。例如,Wayland 禁止了应用程序直接访问底层硬件,只允许了它们与 Compositor 通信,从而增强系统的安全性。

Wayland 的协议设计更加高效,减少了延迟和带宽消耗。在移动设备和资源受限的环境中,Wayland 的优势尤为明显。此外,Wayland 避免了不必要的复杂性和额外处理,使得其在性能上优于 X11。尤其是在窗口大小调整以及拖动等操作中,Wayland 显得更加的平滑流畅。

X11 拥有庞大的生态系统,支持大量的应用程序和工具,几乎所有 Linux 发行版默认都使用 X11。然而,Wayland 的生态系统正在快速发展,主要桌面环境如 GNOME 和 KDE 已全面支持 Wayland。尽管如此,一些特定应用程序和工具可能仍需要额外的兼容层或补丁才能在 Wayland 下运行。

应用场景

在桌面环境中,X11 凭借其广泛的兼容性和成熟度,仍然是许多用户的首选。但随着硬件技术的进步和用户对高性能图形渲染的需求增加,Wayland 正在逐渐成为主流的选择。

越来越多的 Linux 发行版开始默认支持 Wayland,例如 Fedora 和 Ubuntu 等。

在移动设备和嵌入式系统中,资源受限是一个普遍的问题。Wayland 的低功耗以及高性能特性使其成为这些场景下的理想选择。

例如,Android 系统中的 SurfaceFlinger 就是基于 Wayland 的原理设计,用于图形显示以及窗口管理。

在虚拟化和云计算的环境中,图形性能以及网络传输效率至关重要。

虽然 X11 的网络透明性在某些场景下仍有些优势,但 Wayland 通过优化的协议和架构,正在成为虚拟桌面基础设施 VDI 和云桌面解决方案的首选,特别在需要高性能图形渲染的场景中。

未来展望

随着 GPU 技术的成熟以及高性能计算需求的增长,图形界面的渲染以及交互将变得更加复杂和多样化。

X11 和 Wayland 都在积极的探索与 Direct Rendering Manager、Mesa 等图形驱动框架的更紧密集成,以实现更高效的图形渲染和硬件加速。

此外,Wayland 还在研究如何更好地支持多显示器配置、高分辨率显示、触控输入,以满足未来计算环境多样化需求。

最后说两句题外话,近一个月杜老师因为工作的原因,拖更了很多篇文章,感谢小伙伴们的关注和催更,近期会大批量发表一些技术文章,欢迎大家关注。

  •  

OpenResty 的性能优化配置建议

1Panel 的用户越来越多,内置 Web 服务 OpenResty 使用占比也在增加,但网上对其优化的教程很少。应关关童靴的需求,更新一篇有关 OpenResty 的一些优化建议。可优化设置项较少,需要的小伙伴可以根据实际需求变更配置。

server_names_hash_bucket_size 参数项

含义:该参数用于设置服务器名字 hash 表大小,若名字过长或服务较多,保持默认值可能使 hash 表空间不足,引发错误。

优化建议:一般为 server_names_hash_max_size 的 1/2-1/3 左右,如服务器配置较高,可直接设置 256

gzip 参数项

gzip_min_length 参数项:对小文件压缩可能得不偿失,一般设置为 1k10k 左右,小于该值的文件不压缩。

gzip_comp_level 参数项:压缩级别,1 为最小最快,9 为最大最慢,通常建议设置为 4-6,以平衡压缩效果和 CPU 使用率。

client_header_buffer_size 参数项

含义:用于设置读取客户端请求头的缓冲区大小,若请求头过大,可能超出默认值导致客户端报错。

优化建议:根据实际业务需求调整,如业务请求头通常较大,可设为 32k 左右,确保可以完整读取大部分请求头。

client_max_body_size 参数项

含义:限制客户端请求主体的最大允许大小,超出该值请求将被拒绝。

优化建议:根据业务场景和服务器承受能力设置,如普通表单提交可设置为 10m-20m 左右,对于文件上传等大请求可以适当增大。

keepalive_timeout 参数项

含义:设置长连接的超时时间,即客户端与服务器间连接保持空闲的最大时间。

优化建议:一般设为 60-90 秒左右,时间过短会频繁断开连接且增加开销,过长则可能占用过多的资源。

优化后的配置示例

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
http {
# gzip相关配置
gzip on;
gzip_min_length 1k;
gzip_comp_level 6;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/json;
gzip_vary on;
gzip_proxied any;
gzip_disable "msie6";

# 服务器名字hash表大小
server_names_hash_bucket_size 128;

# 客户端请求头缓冲区大小
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;

# 客户端请求主体最大允许大小
client_max_body_size 32m;

# 长连接超时时间
keepalive_timeout 60;

# 其他配置...
}

注意:以上配置仅供参考,具体优化需根据实际业务场景和硬件配置进行调优。

  •  

Nginx 从配置到缓存的性能优化

Nginx 是一个高性能的 HTTP 服务器和反向代理服务器,广泛应用于处理高并发请求。然而,默认配置并不一定适合所有场景,尤其是在高流量或复杂业务逻辑的情况下。本文将介绍一些 Nginx 的基础配置优化和缓存的使用方法以提升 Nginx 的性能。

基础配置优化

  1. 调整 worker_processes 以及 worker_connections

Nginx 使用多进程模型处理请求。worker_processes 定义 Nginx 使用的工作进程数,而 worker_connections 定义每个工作进程可以处理的最大连接数:

1
2
3
4
worker_processes auto;
events {
worker_connections 1024;
}

参数作用如下:

参数作用
worker_processes设置为 auto 可以让 Nginx 自动根据 CPU 核心数来分配工作进程数。如服务器有 4 个 CPU 核心,Nginx 会启动 4 个工作进程。
worker_connections这个值决定了每个工作进程可以处理的最大连接数。通常,可根据服务器的内存和网络带宽来调整这个值。1024 是一个常见起点,可以调整到 2048。
  1. 启用 keepalive 长连接

HTTP 协议中的 keepalive 机制允许客户端和服务器在同一个连接上发送多个请求,减少了 TCP 连接的建立和关闭开销:

1
2
3
4
http {
keepalive_timeout 65;
keepalive_requests 100;
}

参数作用如下:

参数作用
keepalive_timeout定义客户端与服务器保持连接的时间。设置为 65 秒意味着如果客户端在 65 秒内没有发送新请求,连接将被关闭。
keepalive_requests定义了单个连接上允许的最大请求数。设置为 100 意味着一个连接可以处理 100 个请求后关闭。
  1. 调整 buffer 的大小

Nginx 使用缓冲区来存储请求和响应数据。如缓冲区设置过小,Nginx 可能会频繁地进行磁盘 I/O 操作,影响性能:

1
2
3
4
5
http {
client_body_buffer_size 10K;
client_header_buffer_size 1k;
large_client_header_buffers 48k;
}

参数作用如下:

参数作用
client_body_buffer_size定义用于存储客户端请求体的缓冲区大小。如请求体超过这个大小,会将数据写入磁盘。
client_header_buffer_size定义用于存储客户端请求头的缓冲区大小。
large_client_header_buffers定义用于存储大型请求头的缓冲区数量和大小。

缓存提升性能

  1. 启动静态资源缓存

对于静态资源,启用缓存可以显著减少服务器的负载:

1
2
3
4
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}

参数作用如下:

参数作用
expires定义了资源的缓存时间。30d 表示资源将缓存 30 天。
Cache-Controlpublic 表示资源可以被任何缓存「如浏览器、CDN等」缓存,no-transform 表示不允许代理服务器对资源进行转换「如压缩等」
  1. 使用代理缓存

如使用 Nginx 作为反向代理,可启用代理缓存来缓存后端服务器的响应:

1
2
3
4
5
6
7
8
9
10
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;

server {
location / {
proxy_cache my_cache;
proxy_pass http://backend;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
}
}

参数作用如下:

参数作用
proxy_cache_path定义了缓存存储的路径、缓存键的存储区域、缓存的最大大小及缓存的有效期。
proxy_cache启用缓存并使用指定的缓存区域。
proxy_cache_valid定义不同状态码的缓存时间。
  1. 使用 gzip 压缩减少网络传输量

gzip 压缩可以显著减少传输数据量,从而加快页面加载速度:

1
2
3
4
5
6
7
8
http {
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_comp_level 6;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
}

参数作用如下:

参数作用
gzip启用压缩。
gzip_types定义了需要压缩的文件类型。通常包括文本文件、CSS/JavaScript/XML 等。
gzip_comp_level定义压缩级别,范围是 1 到 9。1 是最低的压缩率,9 是最高的压缩率。默认值 6
gzip_min_length定义最小压缩文件大小。小于这个大小的文件不会被压缩。
gzip_proxied定义了是否对代理请求启用压缩。any 表示对所有代理请求启用压缩。
gzip_vary添加响应,确保代理服务器能正确处理缓存。

HTTP/2 与速率限制

  1. 使用 HTTP/2 版协议

HTTP/2 提供了多路复用、头部压缩特性,可以显著提升性能:

1
2
3
4
5
server {
listen 443 ssl http2;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
}

参数作用如下:

参数作用
http2listen 指令中添加 http2 参数即可启用。
  1. 限制请求速率

为了防止恶意请求或突发流量导致服务器过载,可使用 limit_req 模块限制请求速率:

1
2
3
4
5
6
7
8
9
http {
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

server {
location / {
limit_req zone=one burst=5;
}
}
}

参数作用如下:

参数作用
limit_req_zone定义限流区域。$binary_remote_addr 表示根据客户端的 IP 地址进行限流,rate=1r/s 表每秒允许 1 个请求。
limit_req在指定的位置应用限流。burst=5 表允许突发 5 个请求。

LB 和日志优化

  1. 负载均衡
1
2
3
4
5
6
7
8
9
10
upstream backend {
server 192.168.1.1:8080;
server 192.168.1.2:8080;
}

server {
location / {
proxy_pass http://backend;
}
}

注意:通过 upstream 模块可以将请求分发到多个后端服务器,提高并发处理能力。

  1. 日志优化
1
2
access_log /var/log/nginx/access.log main buffer=16k;
error_log /var/log/nginx/error.log warn;

注意:调整日志级别可减少日志输出量,提升性能。这表示将访问日志的缓冲区大小设置为 16KB,并将错误日志级别设置为 warn

  •  

1Panel 全新移动 APP 上线

1Panel 作为新一代的服务器管理面板,为 Linux 服务器运维提供了一个舒适便捷的 Web 图形界面。为了方便移动办公,1Panel 推出了 APP 移动端,目前还在测试阶段,不过足以满足大多数用户的需求。

功能满足多样需求

1Panel APP 拥有丰富且实用功能特性,涵盖服务器管理的多个重要方面。它支持 Android 和 iOS 系统,确保不同设备用户都能享受到一致的服务体验。用户可以方便地添加多个 1Panel 服务,实现对多台服务器集中管理:

首页全局概览表盘,以直观的方式展示服务器的关键信息,让用户一眼就能了解服务器整体运行状况:

应用管理方面,1Panel APP 表现得十分出色。用户不仅能够查看已安装的应用,还能轻松进行安装、配置、管理操作,极大地简化了应用部署和维护的流程:

对于网站管理,它提供专业的工具,方便用户对网站进行创建和编辑、删除操作,同时支持域名绑定和 SSL 证书配置,确保网站的安全性和稳定性:

Docker 容器管理是 1Panel APP 的一大亮点。用户可以方便创建、启动、停止、删除容器,还可以对容器的资源进行合理分配和监控,满足了开发者和运维人员在容器化部署方面的需求:

服务器状态监控功能则让用户实时掌握 CPU、内存、磁盘等资源的使用情况,及时发现潜在性能瓶颈,为服务器优化提供有力依据:

获取使用资格方式

目前 1Panel APP 正式版仅支持专业版用户使用,可以通过各大厂家应用商店安装手机端 APP。

如果还不是 1Panel 专业版用户,又感觉官方的价格太贵,欢迎选择《1Panel 专业版低价租用》数量有限,先到先得!

  •  

解释器权限不够的处理思路

当我们在使用 Linux 系统进行开发或者运维工作时,经常遇到一些错误提示。其中一个常见错误是解释器权限不够。这个错误提示表明在运行 targetcli 命令,系统没有足够权限来执行所需的 Python 解释器。在本文中,我们将探讨这个错误原因和解决方法。

错误原因

为理解这个错误的原因,我们需要先了解下 Linux 系统的权限管理机制。

Linux 系统将用户和组织分为不同的分类,并为每个用户和组织分配不同的权限。这些权限决定用户可以访问和执行哪些文件和目录。

在这个特定错误中,我们看到了一个错误路径/usr/bin/targetcli 和错误消息/usr/bin/python3:解释器错误:权限不够

系统无法在路径/usr/bin/targetcli 下找到所需的 Python 解释器,且没有足够的权限来执行它。

解决方法

  1. 确定缺少的解释器

首先,我们需确定缺少的 Python 解释器。

在错误消息中,我们看到了/usr/bin/targetcli/usr/bin/python3 两个路径。这告诉我们 targetcli 命令需要 python3 来执行。

  1. 确定解释器的位置

接下来我们需要确定 python3 解释器的实际位置。我们可以使用 which 命令来找到解释器的路径。

可在终端中运行命令 which python3。命令的输出将告诉我们 python3 解释器位置。比如,输出可能是/usr/local/bin/python3

  1. 修改 python3 解释器路径

一旦我们找到了 python3 解释器的位置,我们可以通过修改 targetcli 脚本来更新解释器的路径。

打开终端并输入命令 sudo vi /usr/bin/targetcli。这将使用编辑器打开 targetcli 脚本。

在脚本中,我们需要查找#!/usr/bin/python3 这一行,并将其替换为 python3 解释器实际路径。

在这个例子中,我们可以将其替换为#!/usr/bin/python3

  1. 更改脚本权限

最后,我们需要为 targetcli 脚本提供执行权限。

可在终端中运行命令 sudo chmod +x /usr/bin/targetcli。如果一切顺利,我们应该不再看到错误消息。

  •  

dynv6 免费二级域名申请及管理

自飞牛 OS 支持虚拟机后,很多使用飞牛的小伙伴会询问杜老师有关 DDNS 的问题。希望可以白嫖一个二级域名,支持 API 变更解析值,且支持 IPv6 解析。恰好杜老师发现了一个网站,支持多后缀的二级域名白嫖,这里分享给需要的小伙伴们!

什么是 dynv6

dynv6 是一款免费的动态 DNS 服务,其专为 IPv6 设计。

它允许用户将公共主机名轻松分配给私有主机,从而实现对私有主机的远程访问。

dynv6 对所有用户免费开放。可以选择一个免费的主机名开始使用,或者将自己的域名委托给 dynv6。

然而,需要注意的是,dynv6 目前并不提供企业级的 DDoS 防护和 SLA。因此,dynv6 适合用于非关键服务。

强大的 API 支持

dynv6 提供多种方式来更新区域,满足不同用户需求。

其中包括 REST API 和 SSH 以及 DNS 更新。这些 API 的存在,使得 dynv6 的使用更加灵活、方便。

无论是开发者还是普通用户,都可以根据自己的需求选择合适的 API 来更新 DNS 记录。

此外,dynv6 支持 Webhooks 功能。当 IP 地址发生变化时 Webhooks 可以用来更新外部服务。

官网地址

dynv6 的官网地址如下:

使用截图

打开上面的官网后,点击右上角 Sign up 进行账号注册:

完成账号登录后会自动登录,也可通过右上角 Sign in 进行登录。点击 Create new Zone 可白嫖免费二级域名:

点击下拉框后,可以看到有多个后缀可选择,同时填写 IPv4 或者 IPv6 地址:

若想托管顶级域名,可以点击导航栏 My Domains:

  •  

使用 Docker 部署 tinyMediaManager 刮削工具

杜老师使用 Emby 管理媒体文件,但刮削时经常报错。tinyMediaManager 是款功能强大的开源媒体管理工具,能够帮助轻松整理和管理媒体库。本文将详细介绍 tinyMediaManager 的搭建过程和基本使用方法。

什么是 tinyMediaManager

tinyMediaManager 简称 TMM 是一款用 Java/Swing 编写的媒体管理工具,能够为 Jellyfin、Emby 等媒体服务器提供元数据。

通过 TMM 可以抓取和整理影片详细信息、封面图像、演员列表、导演信息等元数据,让媒体库更加丰富、完整。

搭建准备

准备好想要管理的电影、电视剧等媒体文件,并将其存放在一个固定的目录中,方便 TMM 进行扫描和管理。

我们假设电影文件放入</path/to/movies>目录中,命令可参考 mkdir </path/to/movies>

电视文件放入</path/to/tv_shows/>目录中,命令可参考 mkdir </path/to/tv_shows/>

新建数据文件夹</path/to/local/data/>,命令可参考 mkdir </path/to/local/data/>

部署安装

这里我们使用 Docker 来部署,docker-compose.yml 的参考内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
---
version: "2.1"
services:
tinymediamanager:
image: tinymediamanager/tinymediamanager:latest
container_name: tinymediamanager
environment:
- USER_ID=1000
- GROUP_ID=100
- ALLOW_DIRECT_VNC=true
- LC_ALL=en_US.UTF-8 # force UTF8
- LANG=en_US.UTF-8 # force UTF8
- PASSWORD=<password>
- TZ=Asia/Shanghai
volumes:
- </path/to/local/data/>:/data
- </path/to/movies>:/media/movies
- </path/to/tv_shows/>:/media/tv_shows
ports:
- 5900:5900 # VNC port
- 4000:4000 # Webinterface
restart: unless-stopped

将上方代码中<password>改为 TMM 访问密码,配置好后执行如下命令即可:

1
docker-compose up -d

基本使用

第一次启动时,会进入 TMM 设置向导。需要选择媒体类型、设置媒体目录路径、选择元数据来源等。按照向导提示逐步完成设置即可:

设置完成后 TMM 会自动扫描指定的媒体目录,识别其中媒体文件,并尝试从在线数据库中获取相应的元数据:

TMM 会根据文件标题到电影资料网站上匹配电影信息,下载电影资料及图片到本地。可以查看和编辑这些元数据,确保信息的准确性和完整性:

TMM 还可按照一定的规则批量重命名和整理媒体文件,使文件名称更加规范和统一,方便管理、查找:

  •  

RSSHub 搭建指南打造个性化资讯中心

RSSHub 可以根据我们的需求生成个性化的 RSS 订阅源,让我们轻松地获取到各种平台的最新资讯。本文将详细介绍 RSSHub 搭建过程,快速搭建起属于自己的资讯中心。

RSSHub 的简介

RSSHub 是一个轻量、易于扩展 RSS 生成器,它基于 Node.js 开发,支持多种平台和类型订阅源,包括但不限于微博、知乎、B 站、GitHub 等。

通过简单的配置和路由规则,我们就能生成自己想要的 RSS 订阅链接,随时随地获取最新内容更新。

搭建前的准备

在开始搭建 RSSHub 之前,我们需做一些准备工作。需一台服务器,可以是云主机,也可以是本地的计算机。服务器需要具备公网 IP 地址,以便我们能够从外部访问搭建好的 RSSHub 服务。

RSSHub 基于 Docker 部署,因此需要在服务器上安装 Docker 环境。

RSSHub 支持缓存中间件,如 Redis。

为方便访问和使用,建议注册一个域名,并将其解析到服务器的 IP 地址上。

RSSHub 的搭建步骤

将下面的内容保存为 docker-compose.yml 文件:

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
services:
rsshub:
# two ways to enable puppeteer:
# * comment out marked lines, then use this image instead: diygod/rsshub:chromium-bundled
# * (consumes more disk space and memory) leave everything unchanged
image: diygod/rsshub
restart: always
ports:
- "1200:1200"
environment:
NODE_ENV: production
CACHE_TYPE: redis
REDIS_URL: "redis://redis:6379/"
PUPPETEER_WS_ENDPOINT: "ws://browserless:3000" # marked
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:1200/healthz"]
interval: 30s
timeout: 10s
retries: 3
depends_on:
- redis
- browserless # marked

browserless: # marked
image: browserless/chrome # marked
restart: always # marked
ulimits: # marked
core: # marked
hard: 0 # marked
soft: 0 # marked
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/pressure"]
interval: 30s
timeout: 10s
retries: 3

redis:
image: redis:alpine
restart: always
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 30s
timeout: 10s
retries: 5
start_period: 5s

volumes:
redis-data:

使用下面命令来启动 RSSHub 服务:

1
docker-compose up -d

如需拉取新版 RSSHub 的镜像,可使用下面的命令:

1
docker-compose pull

如需停止服务,可使用下面的命令:

1
docker-compose down

如果不喜欢使用 Docker Compose 部署,可使用下面的命令运行有 Puppeteer 依赖的 RSSHub 服务:

1
docker run -d --name rsshub -p 1200:1200 diygod/rsshub:chromium-bundled

可使用下面的命令运行无 Puppeteer 依赖的 RSSHub 服务:

1
docker run -d --name rsshub -p 1200:1200 diygod/rsshub

为 Follow 添加实例

如果使用 Follow 调用 RSSHub 示例,需在 docker-compose.yml 中添加一些变量。其中 FOLLOW_OWNER_USER_ID 是指您的关注账户 ID 或用户名;FOLLOW_DESCRIPTION 指实例描述;FOLLOW_PRICE 指实例月费,如设为 0 表示免费;FOLLOW_USER_LIMIT 指实例用户限制,将其设置为 0 或 1 可将实例设为私有,留空则表示无限制;ACCESS_KEY 指访问密钥:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
services:
rsshub:
image: diygod/rsshub:chromium-bundled
restart: always
ports:
- "1200:1200"
environment:
NODE_ENV: production
FOLLOW_OWNER_USER_ID=杜老师说
FOLLOW_DESCRIPTION=大带宽境外服务器
FOLLOW_PRICE=1
FOLLOW_USER_LIMIT=1000
ACCESS_KEY=ubzG7H3t9TJaFp
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:1200/healthz"]
interval: 30s
timeout: 10s
retries: 3

登录 Follow 后,点击头像,选择 RSSHub 项。在显示页面中,点添加新实例。依次输入 RSSHub 的地址,访问密钥,最后点击添加即可:

  •  

加密 NFS 搭建保障数据传输与存储安全

在现代企业环境中,数据的安全性至关重要。NFS 作为一种广泛使用的文件共享协议,其数据在传输和存储过程中若是缺乏加密保护,将面临被窃取或篡改的风险。本文将详细介绍加密 NFS 搭建过程。

NFS 的简介

NFS 是允许用户通过网络访问远程文件系统,就像访问本地文件系统一样方便。

它支持跨平台文件共享,广泛应用于 Linux 和 Unix 系统。

然而,传统的 NFS 传输数据时以明文形式在网络中传输,很容易受到中间人攻击和数据泄露的威胁。

在 NFS 的基础上,我们可以使用加密技术来保护数据传输和存储。

加密 NFS 必要性

随着数据安全法规的日益严格和企业对数据保护的重视,对 NFS 进行加密变得必不可少。

在企业中,NFS 的加密功能可以提供数据传输和存储的安全保障。

加密 NFS 可有效防止数据在传输过程中被窃取或篡改,确保数据的完整性和机密性。

同时,它也可以满足企业对数据安全合规的要求,为企业的数据资产提供更可靠的保护。

搭建加密 NFS 的步骤

在 NFS 服务器安装支持加密的 NFS 软件包。例如,在基于 Debian 的系统上,可以使用下面命令进行安装:

1
sudo apt -y install nfs-kernel-server

使用下面的命令编辑 NFS 配置文件,添加加密相关选项。例如,可使用 sec = krb5isec = krb5p 选项来启用 Kerberos 加密。其中,krb5i 提供数据完整性保护,而 krb5p 则同时提供了数据加密和完整性保护:

1
sudo vim /etc/exports

在配置文件中指定要共享的目录及其访问权限。这表示允许客户端 IP 以读写模式访问共享目录,并启用 Kerberos 加密。例如:

1
/path/to/shared/directory client_ip(rw,sync,no_subtree_check,sec=krb5i)

完成配置后重启 NFS 服务。可以使用下面命令重启服务:

1
sudo systemctl restart nfs-kernel-server

使用下面的命令使配置文件生效:

1
exports -rv

在需访问加密 NFS 共享的客户端上安装 NFS 客户端软件。例如,在基于 Debian 的系统上,可以使用下面命令进行安装:

1
sudo apt -y install nfs-common

使用挂载命令将加密的 NFS 共享挂载到本地目录。这将把服务器上的共享目录挂载到客户端本地目录,并启用 Kerberos 加密。例如:

1
sudo mount -t nfs4 -o sec=krb5i server_ip:/path/to/shared/directory /local/mount/point

使用下面命令查看挂载文件系统,确保加密 NFS 共享已成功挂载:

1
df -h 

加密 NFS 优势与注意事项

加密 NFS 有多种优势,例如数据加密传输、身份认证和数据完整性保护等等。

它能够有效防止数据泄露和篡改,提高数据的安全性。

然而,在搭建加密 NFS 时也需要注意一些事项。

首先,加密过程可能会增加系统的性能开销,因此需根据实际需求进行性能评估和优化。

其次,配置过程较为复杂,需仔细检查配置文件和参数设置,确保正确无误。

此外,还需要定期更新加密软件和认证机制,以应对不断变化的安全威胁。

  •  

去不图床数据清理通知

近期发现外链流量激增,经分析了解并非是攻击导致,通过 URL 判断其来源是一些匿名及到期用户所上传的图片。因此决定发文公告:清理去不图床所有匿名用户所上传的图片,并周期检查已到期用户。

免费服务的初心与挑战

2019 年,去不图床怀着为各位小伙伴提供免费、便捷图片托管服务赤子之心,正式上线!

那会儿杜老师的目标就是给大伙儿搭个稳定可靠的平台,让大家轻轻松松的分享图片,舒舒服服存储图片。

这服务的确是受到了大家的一致好评,用户数量跟图片上传量,那叫一个节节攀升,直冲云霄!

可是好景不长,随着用户规模像滚雪球一样越滚越大,这流量成本也成了杜老师心头一块大石头。

图片托管需要海量的带宽和存储空间,这费用那是哗哗地往外流啊!

杜老师也是一直在绞尽脑汁优化成本,可那流量费用,像脱缰的野马,一发不可收拾,最终,在 2021 年不得不调整策略,从免费转向了收费,这都是为了咱这平台能继续坚挺地活下去!

流量成本与运营的压力

虽然 2021 年去不图床改成收费模式,但之前游客用户免费上传的图片,一直没有清理。

这些图片,虽然丰富了平台的内容,但是占用的存储空间和流量资源,那也是相当可观啊!

据统计游客上传的图片数量,那简直是天文数字,而且很多图片访问频率低得可怜,却依然霸占着咱宝贵的存储资源!

随着平台业务蒸蒸日上,对流量成本的控制也越来越严格。

现在运营环境,杜老师得精打细算,合理分配资源,保证已兑换容量的小伙伴能享受到更优质、更稳定的服务。

所以,经过一番深思熟虑,杜老师决定对游客用户的图片进行清理啦!

匿名用户上传图片清理

为了降低流量以及存储损耗,优化资源分配,杜老师将于 2025 年 3 月 1 日起,清理所有游客用户上传图片。

这个决定,杜老师也是万般的无奈,但这是目前运营环境下,必须采取的措施啊!

希望各位游客用户能够理解杜老师的苦衷,赶紧备份需要保存的图片吧!如有疑问,欢迎随时在评论区留言!

游客数据保留至本月中「2025 年 3 月 15 日」因为无法进行用户判定,所以杜老师已经整体打包备份了,需要的小伙伴可留言索要图片压缩包。

到期用户上传图片清理

为了进一步降低流量及存储损耗,优化资源分配,杜老师将于 2025 年 3 月 15 日起,清理所有到期用户上传图片。

已到期的用户数据清理规则如下:当月 15 日之前到期用户,数据保留至当月的最后一天;当月 15 日之后到期用户,数据保留至下个月月中。

数据清理之前,杜老师都会邮件通知用户进行再续费,通知七天后未续费则会清理数据「即当月 15 日之前到期的用户,会在当月 23 日发送通知;当月 15 日之后到期用户,会在次月 8 日发送通知」

注意图片清理是多节点同步执行,不会保留备份数据!最终解释权归去不图床所有。

  •  

使用 Python 脚本验证指定目录的图片文件

有小伙伴说杜老师说侧边栏随机图片素材太少,翻来覆去只有那么几张。为了充实随机图片,杜老师采集了一个图片网站。奈何能力有限,某些图片采集失败,保存为空文件,所以需要编写一个脚本,来验证图片是否为正常。

代码需求

使用 Python 语言编写一个小项目,需要遍历指定目录下所有子目录「子目录名称为中文」

验证子目录下的图片文件是否能正常打开,如果能则跳过,如果无法正常打开则返回其路径。

变更解释

  1. 使用 os 模块来遍历目录和子目录;

  2. 使用 PIL 库来验证图片文件是否能正常打开。

注意事项

请确保安装了 Pillow 库,可以使用下面的命令来安装:

1
pip install pillow

root_directory 变量设置为需要遍历的目录路径:

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
import os
from PIL import Image

def validate_images_in_directory(root_dir):
invalid_image_paths = []

for dirpath, dirnames, filenames in os.walk(root_dir):
for filename in filenames:
if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp')):
file_path = os.path.join(dirpath, filename)
try:
with Image.open(file_path) as img:
img.verify() # 尝试验证图片文件
except (IOError, SyntaxError) as e:
invalid_image_paths.append(file_path)

return invalid_image_paths

if __name__ == "__main__":
root_directory = '指定目录路径' # 替换为实际的目录路径
invalid_images = validate_images_in_directory(root_directory)

if invalid_images:
print("无法打开的图片文件路径:")
for path in invalid_images:
print(path)
else:
print("所有图片文件都能正常打开。")

执行代码

1
python3 images.py

注意:将上面的代码保存为 images.py 文件,然后在命令行中执行上面的命令。

  •  

探索 Linux 内存占用找出最吃内存的进程

无论是服务器还是个人电脑,了解哪些进程占用了最多的内存,对于系统管理员和普通用户来说至关重要。不仅可以帮助我们优化系统性能,还能避免因内存不足而导致系统崩溃。本文将介绍如何在 Linux 系统中统计内存占用最多的前 10 个进程。

为什么要统计内存占用

多任务操作系统中,内存是有限的资源。

当多个进程同时运行时,它们会争夺有限的内存空间。

如果某些进程占用内存过多,可能导致系统响应变慢,甚至出现内存不足错误。

因此,定期检查内存占用情况,找出占用最多进程,可以帮助我们更好管理资源,优化系统性能。

使用命令工具统计内存占用

使用 pssort 的命令组合:

1
ps -eo pid,comm,%mem --sort=-%mem | head -n 11

解释:

参数作用
ps -eo pid,comm,%mem列出所有进程的 PID、进程名称和内存占用百分比。
–sort=-%mem按内存占用百分比降序排序。
head -n 11显示前 11 行的内容「第一行是标题,接下来是前 10 个进程的信息」

虽然 top 命令主要用于实时的监控系统资源,但也可通过以下方式快速查看内存占用最多的进程:

1
top -o %MEM -b -n 1 | head -n 18

解释:

参数作用
-o %MEM按照内存占用排序。
-b以批处理模式运行,输出到终端上。
-n 1只需运行一次。
head -n 18过滤出前 18 行「因为 top 输出的前几行是系统信息,实际进程从第 8 行开始」

如果需要更详细的内存占用信息,可结合 pmap 命令:

1
ps -eo pid,%mem,comm --sort=-%mem | head -n 11 | awk '{print $1}' | xargs -I {} pmap {} | grep total

解释:

参数作用
ps -eo pid,%mem,comm –sort=-%mem获取内存占用最高的进程 PID。
awk ‘{print $1}’提取 PID 进程号。
xargs -I {} pmap {}获取每个进程详细内存映射信息。
grep total过滤 total 行,显示每个进程的总内存占用情况。

如果系统安装了 smem 工具,可以更直观地查看内存占用:

1
smem -s rss -c "pid user command rss" --sort=rss | head -n 11

解释:

参数作用
-s rss按 RSS 排序。
-c “pid user command rss”指定显示的列。
–sort=rss按 RSS 排序。
head -n 11显示前 11 行的内容。

如何分析内存占用情况

确认进程是否必要。有些进程可能是系统正常运行所必需,例如 systemd 等。这些进程通常不会占用过多内存。然而,如果某些进程是用户启动的,如某个应用程序或脚本,需确认它们是否在正常运行。

检查进程是否内存泄漏。如某个进程的内存占用持续增加,可能是内存泄漏导致的。内存泄漏是指程序在申请内存后,无法正确释放已分配的内存,导致内存占用不断增加。这种情况下需要检查程序的代码,查找可能导致内存泄漏地方。

限制进程内存使用。如果某个进程占用过多内存,但又不能轻易终止,可以尝试限制它的内存使用。

Linux 提供 ulimit 命令,可设置进程的资源限制。例如,限制某个进程的最大内存使用量为 1GB,可使用命令 ulimit -m 1048576

内存管理其它技巧

除了统计内存占用最多进程,还可通过以下方式优化 Linux 系统的内存管理。

调整交换空间。交换空间是磁盘上的一部分空间,当物理内存不足时,系统会将一些不常用的内存页面移到交换空间。虽然使用交换空间可以避免系统崩溃,但磁盘速度远慢于内存,因此过多地使用交换空间会导致系统性能下降。

可以通过命令 swapon --show 查看交换空间的使用情况。如果交换空间使用过多,可以考虑增加物理内存,或者调整交换空间大小。

使用内存清理工具。Linux 系统会自动管理内存分配、回收,但有时也可以手动清理内存。

例如,可以使用 sync 命令将缓存数据写入磁盘,然后用 echo 3 > /proc/sys/vm/drop_caches 命令清理缓存。

但请注意,这种方法可能会对系统性能产生一定影响,因此需要谨慎使用。

  •  

使用 SlimToolkit 打造更小的容器镜像

现在容器技术很火,镜像又肥又大,部署较慢不说,安全风险还蹭蹭往上窜,简直让人头大!SlimToolkit 就像一位经验老道的镜像瘦身大师,能把镜像体积缩小到令人咋舌的程度,最多能瘦 30 倍!

到底是啥

简单来说,SlimToolkit 就是一个开源的镜像减肥专家,它能智能分析镜像,找出那些又大又没用的文件、库和依赖,然后干净利落地咔嚓下,统统删掉!

就像一位技艺精湛的雕塑家,将冗余的部分精雕细琢,留下最精髓的部分。

之前叫 DockerSlim,现在已经是云原生计算基金会沙盒项目了,实力是杠杠的!

它的核心思想就是原封不动优化,通过动态、静态分析,自动识别并移除镜像里垃圾文件。

支持 Docker 以及 Kubernetes,各种类云原生工具,妥妥全能选手!

不只瘦身,还可以提供命令行工具,方便检查、调试、管理镜像,简直贴心到家!

SlimToolkit 的绝活

  1. 镜像瘦身大法:这是它的看家本领!它能像一位经验丰富的裁缝,精准剪裁镜像,去除冗余部分。如一个基于 Ubuntu 的 Python 应用,原本约 438MB,经过它的一通操作,能瘦到 16.8MB,足足瘦了 26 倍!

  2. 安全防护专家:它不仅能瘦身,还可以增强安全性!它可以自动生成 Seccomp 和 AppArmor 安全配置文件,像给容器穿上了一层坚不可摧的盔甲,限制系统调用,防止各种安全漏洞入侵。再也不用担心容器被黑客攻破了!

  3. 动态分析、调试:它就像一位经验丰富的侦探,可以创建一个临时容器模拟运行环境,通过 HTTP 探针等方式收集运行数据,分析应用程序行为,确保瘦身后的镜像依然可以正常工作。而且,它还提供调试工具,在优化后的容器中运行调试命令,排查问题方便!

  4. 无缝集成:它就像一位老练的管家,能无缝集成到开发和部署流程中。不用改动 Dockerfile 或构建工具,只需在构建过程中添加 SlimToolkit 的优化步骤即可。还支持各种 CI/CD 工具,如 Jenkins、GitHub Actions 等,自动化部署 so easy!

上手玩转

先安装 SlimToolkit。SlimToolkit 提供了多种安装方式,含直接下载二进制文件、使用脚本安装或通过 Docker 运行。对于大多数的用户,使用脚本安装是最简单方式:

1
curl -sL https://raw.githubusercontent.com/slimtoolkit/slim/master/scripts/install-slim.sh | sudo -E bash -

优化容器镜像。假设已经有一个 Docker 镜像,如一个基于 Python 的 Web 应用。可使用以下命令对镜像进行优化:

1
slim build my/sample-python-app

SlimToolkit 会自动创建一个临时容器,运行动态分析,并生成优化后镜像。优化后的镜像名称会自动加上.slim 后缀,例如:

1
my/sample-python-app.slim

验证优化效果。优化完成后可以使用以下命令查看优化后镜像大小:

1
docker images

SlimToolkit 的优势

  1. 自动与智能化:它能够自动识别容器中不必要的部分,并且进行优化,无需开发者手动修改 Dockerfile 或者删除文件。这种自动化不仅节省了时间,还减少了人为错误的可能性。

  2. 安全:通过生成 Seccomp 和 AppArmor 的配置文件,SlimToolkit 为容器提供了额外的安全保障。这些配置文件能够限制容器系统调用,防止潜在安全威胁,而无需开发者深入了解安全框架细节。

  3. 无缝集成:SlimToolkit 设计目标是无缝集成到现有的开发和部署流程中。它支持多种容器运行时和 CI/CD 工具,能够轻松集成到自动化构建和部署流程中。开发者无需改变现有的工具链或工作流程,即可享受 SlimToolkit 带来的优化效果。

  4. 开源:完全开源,社区活跃,有问必答!

  •  

图片为啥用 Base64 格式进行传输

在互联网的世界里,图片传输是再平常不过的事情了,而 Base64 格式常常出现在这一过程中。那为啥图片要用 Base64 格式来传输呢?这背后有不少门道。本文将介绍 Base64 格式的应用场景和优点,以及一些应用场景下的缺点。

Base64 是什么

Base64 是种用 64 个可打印字符来表示二进制数据的编码方法。这 64 个字符含大小写字母各 26 个,还有 10 个数字以及两个符号。

例如,当我们看到一串像 SGVsbG8gV29ybGQh 这样的字符,这就是 Base64 编码后的结果,其实代表了 Hello World!

易于文本传输

在很多网络传输场景中,尤其是早期的网络应用,传输通道主要被设计为传输文本数据。

因为文本数据格式相对简单、统一,而且不容易出现乱码等问题。

而图片是二进制的数据,直接传输二进制数据可能会因为不同系统、不同软件对二进制数据的处理方式不同而出现问题。

Base64 把图片的二进制数据转换成了文本形式。这样一来,通过电子邮件、网页表单等主要以文本传输为主的渠道时,图片就可以顺利跟着文本一起传输了。

比如,在发送带有图片附件的电子邮件,邮件系统会把图片转换成 Base64 格式,然后和邮件的正文一起发送。

接收方收到邮件后,邮件客户端再把 Base64 格式的数据转换回图片,这样我们就能看到图片。

兼容性好

不同的操作系统和不同的软件应用对数据处理方式可能存在差异。Base64 编码后的文本数据在各种平台都能被正确识别和处理。

例如,一个在 Windows 系统上生成的 Base64 编码的图片数据,在 Linux 服务器上也能轻松解码并还原成图片,不用担心因为平台不同而出现数据损坏或者无法读取的情况。

几乎所有的编程语言都有内置的库或者函数来处理 Base64 编码和解码。这使得开发人员在开发涉及图片传输的应用程序时,能够很方便使用 Base64 格式。

比如,在一个基于 Python 的 Web 应用,开发人员可以使用库轻松地将图片文件读取并编码为 Base64 格式,然后通过网络发送给服务器或客户端。

方便在网页中嵌入图片

在网页设计中,如果一个网页中有大量的小图标或小图片,每次加载这些图片都需要发送一个 HTTP 请求。

这不仅会增加服务器的负担,还会影响网页加载速度。

而将这些小图片转换为 Base64 格式后,可以直接将 Base64 编码的数据嵌入到 HTML 或 CSS 文件中。

这样浏览器在加载 HTML 或 CSS 文件的时候,就可以直接读取到图片数据,而不需要单独发送 HTTP 请求去获取图片,从而提高了网页的加载效率。

嵌入 Base64 格式的图片还可以简化网页的结构。不需要在网页文件目录中单独存放这些小图片文件,减少了文件管理复杂性。

对于一些简单的网页应用或前端框架,这种方式非常实用。

安全性的考虑

虽然 Base64 编码不能算是真正的加密方法,但它在一定程度上可起到隐藏信息的作用。

因为对于不了解 Base64 编码的人来说,看到一串 Base64 编码的数据可能不知道它代表的是图片内容。

在一些对安全性要求不是特别高的场景下,可作为一种简单的保护措施。

比如,在一些内部文档分享系统中,把图片转换 Base64 格式传输,可防止非授权用户轻易地获取到原始图片文件。

在某些情况下,直接传输二进制图片文件可能会带来安全风险,如图片文件可能被恶意篡改,包含恶意代码。

将图片转换为 Base64 格式后,这些恶意代码在 Base64 编码文本环境中很难被执行,从而降低安全风险。

缺点

不过,Base64 传输图片也有其缺点。比如,Base64 编码后数据量比原始的二进制图片数据要大,大概会增加百分之三十三左右的大小。

所以在传输大图片或者对带宽要求很高的场景,可能需要权衡下是否使用 Base64 格式。

  •  

DPanel 让 Docker 管理变得轻松又高效

Docker 作为容器化领域的佼佼者,其强大的功能和灵活性,赢得众多开发者的青睐。然而,对于许多用户来说,Docker 的命令行操作可能显得有些复杂和繁琐。幸运的是,DPanel 的出现为 Docker 的管理和使用带来了全新的体验。

什么是 DPanel

DPanel 是一款轻量化的 Docker 可视化管理面板,专为简化容器的管理而设计。它提供一套完善的容器管理功能,让用户可通过直观的图形界面轻松管理 Docker 容器,无需深入复杂的命令行操作。

无论是初学者还是经验丰富的开发者,DPanel 都能帮助他们更高效地管理和部署容器。

DPanel 的优势

DPanel 的界面简洁直观,操作简单易懂,即使新手也能轻松上手。

DPanel 提供了丰富功能,涵盖了网站管理的各个方面,能够满足各种用户的需求。

基于容器设计,安装和部署都非常简单。用户无需复杂配置,只需通过简单步骤即可快速启动面板。其简洁直观操作界面让用户能够轻松上手,即使是第一次接触 Docker 的用户也能快速掌握基本操作。

DPanel 与 Docker 官方的兼容性非常好,能够无缝对接 Docker 的各项功能。支持多种操作系统和 Docker 版本,确保用户在不同环境下都能稳定使用。

服务安装

我们可以使用官方提供的集成脚本安装 DPanel。当宿主机没有 Docker 环境时,集成脚本会尝试安装 Docker 环境:

1
curl -sSL https://dpanel.cc/quick.sh -o quick.sh && sudo bash quick.sh

按照提示操作。安装完成后通过浏览器访问面板地址,即可进入管理界面:

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
[DPanel Install Log]: 选择你需要安装的版本 
1. 标准版 (需要绑定 80 及 443 端口)
2. Lite版 (不包含域名转发相关功能)
3. 标准版 (Pro)
4. Lite版 (Pro)
5. Beta版 (内测版本)
输入你要安装的版本编号 [默认: 2]: 1
1. Docker Hub
2. ALiYun
选择镜像源 [默认: 1]: 2
[DPanel Install Log]: 你安装使用的镜像为 registry.cn-hangzhou.aliyuncs.com/dpanel/dpanel:latest
[DPanel Install Log]: 设置 DPanel 容器名称,更新面板时请配置为当前面板容器名称
请输入名称 [默认: dpanel]:
[DPanel Install Log]: 你指定的容器名称为 dpanel
设置 DPanel 容器挂载目录 [默认: /home/dpanel]:
[DPanel Install Log]: 您选择的面板容器挂载目录是 /home/dpanel
设置 DPanel 端口 [默认: 25128]:
[DPanel Install Log]: 您设置的端口是: 25128
[DPanel Install Log]: 如果端口已经被占用,请再次执行脚本更换端口后重新安装
Unable to find image 'registry.cn-hangzhou.aliyuncs.com/dpanel/dpanel:latest' locally
latest: Pulling from dpanel/dpanel
1f3e46996e29: Pull complete
b6dde5f749cd: Pull complete
459b8d93d51a: Pull complete
7d52a0c67d85: Pull complete
4b97f8a613e7: Pull complete
1d46bacd0854: Pull complete
3eac9a9b4fcb: Pull complete
2c5c0b90bb2b: Pull complete
4f4fb700ef54: Pull complete
Digest: sha256:9daa4f411b2bd7845cfd71e747ba2827797ea5fe9e754b8db475541c3700ba01
Status: Downloaded newer image for registry.cn-hangzhou.aliyuncs.com/dpanel/dpanel:latest
d492b83d8c546297836a8735d73f0b3f8943f134065dea4ef5ffff834f028715
[DPanel Install Log]:
[DPanel Install Log]: =================感谢您的耐心等待,安装、升级已完成==================
[DPanel Install Log]:
[DPanel Install Log]: 请使用您的浏览器访问面板,并初始化管理员帐号:
[DPanel Install Log]: 外部地址: http://123.116.127.26:25128
[DPanel Install Log]: 内部地址: http://192.168.31.187:25128
[DPanel Install Log]: 如果您使用的是云服务器,请在安全组中打开端口 25128
[DPanel Install Log]:
[DPanel Install Log]: 官方网站及文档: https://dpanel.cc
[DPanel Install Log]: 代码仓库: https://github.com/donknap/dpanel
[DPanel Install Log]:
[DPanel Install Log]: ================================================================

面板效果

首页概览:

容器管理:

文件管理:

镜像管理:

创建镜像:

系统管理:

  •  

本博出现图碎问题说明

近期本博访问时出现了图碎问题,经排查系 CDN 回源失败导致的。有小伙伴可能会说,保证成功就可以修复了,其实没有那么简单。本文简单描述下存储节点数据流,顺便科普一下如何清理单站数据缓存。

数据流向

通过下图可以看出,图片文件保存在主机上,通过转换处理为 WebP 格式文件,经由 CDN 回源并实现访问加速:

问题分析

登录 CDN 管理后台查看其日志,发现出现超时记录。

超时原因一般两种,一种是因线路问题导致回源超时,一种是因主机没有及时返回数据造成。

本地图片经由 WebP 中间件处理,再回源给 CDN 做反代,经查是 WebP 服务突然宕机导致 CDN 未收到响应数据导致超时。

除超时问题外,因无返回数据导致 CDN 响应 404,而服务器设置 404 默认跳转至主站首页,这就导致好多小伙伴频繁刷新页面依然不显示图片。

解决方案

目前已关闭 CDN,流量直接回源至源主机,缺点就是会影响访问的速度。带调试维护后会重新挂上 CDN。

WebP 图片转换是为了减少图片体积,进而减轻带宽压力「轻量级服务器有流量的限制」因此不能暂停使用,已修改其参数,尽量保障响应的成功率。

如之前有访问记录,会留下 404 跳转缓存,需要清理相关数据。

有小伙伴分享了两种清理缓存的方法,需要的小伙伴可以参考操作。

清理缓存

首先进入到浏览器的开发者工具,一般浏览器点击F12即可,进入更多设置,勾选 Disable cache while DevTools is open 项:

或者切换到网络标签页,勾选禁用缓存,刷新页面即可「注意保持开发者工具一直处于开启的状态」

  •  

新版本去不图床免费公测开始啦

有不少的小伙伴为去不图床提供建议,包括但不限于增加支持格式、图片处理、水印功能等等。杜老师也收集了这些建议转交给程序的设计者,经过了几个月更新迭代,V2 版本已推出。由于使用了新框架,无论是操作逻辑和功能支持,都有较大改变,所以在正式上线前,杜老师决定免费公测下!

新版界面

新版主页相较老版而言更加简洁,仅包含站点名称及描述信息,还有图片托管数据。最下方是两个功能入口,一个是图片上传的窗口,一个是用户登录的界面:

在上传界面中,可以选择从本地计算机上传图片文件,也可接入到摄影头,拍摄照片后再上传。目前支持访客上传,所有图片会经过审核后存放在服务器:

用户可以通过邮箱、用户名两种方式来登录。目前程序强制要求注册用户进行邮件验证,不能关闭验证。但因 bug 收不到验证信息,所以杜老师提供了一些体验账号用需要的小伙伴们使用:

在用户的仪表盘中可看到当前拥有的存储容量,可以查看图片、相册、分享,可以购买订阅、查看订单,提交工单或申请 API Tokens:

体验账号

体验账号密码统一为 7bu.top,默认容量为 1G。如选择了账号,请在评论区中留下编号,杜老师会根据使用备注信息,避免有小伙伴重复选择账号:

编号账号邮箱备注
1dusays1dusays1@dusays.com已用
2dusays2dusays2@dusays.com暂无
3dusays3dusays3@dusays.com暂无
4dusays4dusays4@dusays.com暂无
5dusays5dusays5@dusays.com暂无
6dusays6dusays6@dusays.com暂无
7dusays7dusays7@dusays.com暂无
8dusays8dusays8@dusays.com暂无
9dusays9dusays9@dusays.com暂无
10dusays10dusays10@dusays.com暂无
11dusays11dusays11@dusays.com暂无
12dusays12dusays12@dusays.com暂无
13dusays13dusays13@dusays.com暂无
14dusays14dusays14@dusays.com暂无
15dusays15dusays15@dusays.com暂无
16dusays16dusays16@dusays.com暂无
17dusays17dusays17@dusays.com暂无
18dusays18dusays18@dusays.com暂无
19dusays19dusays19@dusays.com暂无
20dusays20dusays20@dusays.com暂无
21dusays21dusays21@dusays.com暂无
22dusays22dusays22@dusays.com暂无
23dusays23dusays23@dusays.com暂无
24dusays24dusays24@dusays.com暂无
25dusays25dusays25@dusays.com暂无
26dusays26dusays26@dusays.com已用
27dusays27dusays27@dusays.com暂无
28dusays28dusays28@dusays.com暂无
29dusays29dusays29@dusays.com暂无
30dusays30dusays30@dusays.com暂无
31dusays31dusays31@dusays.com暂无
32dusays32dusays32@dusays.com暂无
33dusays33dusays33@dusays.com暂无
34dusays34dusays34@dusays.com暂无
35dusays35dusays35@dusays.com暂无
36dusays36dusays36@dusays.com暂无
37dusays37dusays37@dusays.com暂无
38dusays38dusays38@dusays.com暂无
39dusays39dusays39@dusays.com暂无
40dusays40dusays40@dusays.com暂无
41dusays41dusays41@dusays.com暂无
42dusays42dusays42@dusays.com暂无
43dusays43dusays43@dusays.com暂无
44dusays44dusays44@dusays.com暂无
45dusays45dusays45@dusays.com暂无
46dusays46dusays46@dusays.com暂无
47dusays47dusays47@dusays.com暂无
48dusays48dusays48@dusays.com暂无
49dusays49dusays49@dusays.com暂无
50dusays50dusays50@dusays.com暂无
51dusays51dusays51@dusays.com暂无
52dusays52dusays52@dusays.com暂无
53dusays53dusays53@dusays.com暂无
54dusays54dusays54@dusays.com暂无
55dusays55dusays55@dusays.com暂无
56dusays56dusays56@dusays.com暂无
57dusays57dusays57@dusays.com暂无
58dusays58dusays58@dusays.com暂无
59dusays59dusays59@dusays.com暂无
60dusays60dusays60@dusays.com暂无
61dusays61dusays61@dusays.com暂无
62dusays62dusays62@dusays.com暂无
63dusays63dusays63@dusays.com暂无
64dusays64dusays64@dusays.com暂无
65dusays65dusays65@dusays.com暂无
66dusays66dusays66@dusays.com已用
67dusays67dusays67@dusays.com暂无
68dusays68dusays68@dusays.com暂无
69dusays69dusays69@dusays.com暂无
70dusays70dusays70@dusays.com暂无
71dusays71dusays71@dusays.com暂无
72dusays72dusays72@dusays.com暂无
73dusays73dusays73@dusays.com暂无
74dusays74dusays74@dusays.com暂无
75dusays75dusays75@dusays.com暂无
76dusays76dusays76@dusays.com暂无
77dusays77dusays77@dusays.com暂无
78dusays78dusays78@dusays.com暂无
79dusays79dusays79@dusays.com暂无
80dusays80dusays80@dusays.com暂无
81dusays81dusays81@dusays.com暂无
82dusays82dusays82@dusays.com暂无
83dusays83dusays83@dusays.com暂无
84dusays84dusays84@dusays.com暂无
85dusays85dusays85@dusays.com暂无
86dusays86dusays86@dusays.com暂无
87dusays87dusays87@dusays.com暂无
88dusays88dusays88@dusays.com已用
89dusays89dusays89@dusays.com暂无
90dusays90dusays90@dusays.com暂无
91dusays91dusays91@dusays.com暂无
92dusays92dusays92@dusays.com暂无
93dusays93dusays93@dusays.com暂无
94dusays94dusays94@dusays.com暂无
95dusays95dusays95@dusays.com已用
96dusays96dusays96@dusays.com已用
97dusays97dusays97@dusays.com暂无
98dusays98dusays98@dusays.com暂无
99dusays99dusays99@dusays.com已用
100dusays100dusays100@dusays.com已用

站点地址

公测站点地址如下,点击访问即可。因为公测站点是单线路,与图片外链同线路,所以访问速度较慢,请访问慢的小伙伴耐心等待页面加载:

公测规则

  1. 本站仅供测试使用,请勿用于非法用途;

  2. 原去不图床的账号无法在测试平台中使用,请使用提供的体验账号;

  3. 如选择好体验账号,请将编号留言至评论区,杜老师会备注信息,方便其它的小伙伴选择;

  4. 公测平台预计运营至三月底,届时所有数据将被释放,请勿保存重要数据;

  5. 在使用的过程中如发现有任何 bug,欢迎在评论区留言,杜老师会第一时间提交给程序开发者,尽量完善新版图床程序;

  6. 最终解释权归杜老师说所有。

  •  

Hugo 渲染超时问题的解决笔记

hehe 童鞋选择将所有的站点托管到杜老师这「是收费的」这样就可以专心维护网站的内容,也不用费心思在运维上。在做站点迁移时遇到了 Hugo 框架的一个报错,原因是使用 Hugo 搭建相册网站需要遍历大量图片,而在生成站点文件时出现了超时问题,本文记录解决方法。

报错信息

1
2
3
ERROR render of "page" failed: "/home/runner/work/photo/photo/themes/gallery/layouts/_default/single.html:3:5": execute of template failed: template: _default/single.html:3:5: executing "main" at <partial "gallery.html" .>: error calling partial: partial "gallery.html" timed out after 30s. This is most likely due to infinite recursion. If this is just a slow template, you can try to increase the 'timeout' config setting.
Total in 60412 ms
Error: error building site: render: failed to render pages: render of "page" failed: "/home/runner/work/photo/photo/themes/gallery/layouts/_default/single.html:3:5": execute of template failed: template: _default/single.html:3:5: executing "main" at <partial "gallery.html" .>: error calling partial: partial "gallery.html" timed out after 30s. This is most likely due to infinite recursion. If this is just a slow template, you can try to increase the 'timeout' config setting.

注意:杜老师是通过 GitHub Actions 来部署,逻辑是先准备 Hugo 的运行环境,再根据站点的数据渲染站点文件。在生成站点文件时出现如上错误信息。

解决思路

从错误信息看,Hugo 网站在渲染页面时出现了问题,具体是 gallery.html 这个 partial 文件在执行时超时了,并且怀疑是由于无限递归导致的。

首先检查 gallery.html 中代码。无限递归问题可能是 gallery.html 中调用了自身,或者在调用其它 partial 时形成了循环。仔细检查文件,确保没有递归调用自己或其它可能导致循环的部分。

其次检查数据结构。如果 gallery.html 中依赖某些数据结构,可能是数据结构中存在循环引用。例如,某个对象或者列表在渲染时不断递归调用。

再次增加超时时间。如果确认不是无限递归问题,而是模板渲染确实很慢,可以尝试增加超时时间。在 Hugo 的配置文件中,增加 timeout 配置项,如 timeout = '60000'

然后优化模板性能。如果模板渲染确实很慢,可能是模板的代码过于复杂。可以尝试优化模板代码,减少不必要循环和复杂逻辑。

接着调试模板。使用 Hugo 的调试工具来逐步检查模板的执行过程。可通过在模板中添加日志输出来帮助调试。

再者检查依赖插件。如果网站使用第三方插件或依赖,可能是插件导致了问题。尝试禁用插件,看看能否解决问题。

最后检查 Hugo 的版本。确保使用的 Hugo 版本是最新的。旧版本可能存在已知的 bug,而新版本可能已修复了这些问题。

  •  

麒麟服务器操作系统 yum 升级报错处理

因为公司要求,杜老师一直使用麒麟服务器操作系统,为了保证系统的新特性,需要经常升级系统。这次在升级过程中遇到错误,本文记录该错误及其解决的方法。如果小伙伴也遇到了类似的问题,可以参考本文或在评论区中留言!

报错信息

1
2
3
4
5
6
The downloaded packages were saved in cache until the next successful transaction.
You can remove cached packages by executing 'yum clean packages'.
Error: Transaction test error:
file /usr/share/doc/ipmitool/ChangeLog from install of ipmitool-1.8.19-1.p01.ky10.x86_64 conflicts with file from package ipmitool-help-1.8.18-19.p02.ky10.noarch
file /usr/share/doc/ipmitool/README from install of ipmitool-1.8.19-1.p01.ky10.x86_64 conflicts with file from package ipmitool-help-1.8.18-19.p02.ky10.noarch
file /usr/share/man/man1/ipmitool.1.gz from install of ipmitool-1.8.19-1.p01.ky10.x86_64 conflicts with file from package ipmitool-help-1.8.18-19.p02.ky10.noarch

注意;杜老师执行命令 yum -y update 用户升级所有软件,在升级过程中提示如上错误信息。

解决思路

根据所提供的错误信息,问题在于 ipmitool-1.8.19-1.p01.ky10.x86_64ipmitool-help-1.8.18-19.p02.ky10.noarch 间存在文件冲突。以下是解决此问题步骤,首先移除冲突的包:

1
yum -y remove ipmitool-help-1.8.18-19.p02.ky10.noarch

清理缓存,确保后续操作不会受到旧缓存的影响:

1
yum clean all

在移除冲突包并清理缓存后,重新安装 ipmitool 软件包:

1
yum -y install ipmitool-1.8.19-1.p01.ky10.x86_64

最后,更新系统中所有包,以确保所有的依赖关系都已解决:

1
yum -y update
  •  

2 月 5 日图床故障说明

这是篇补更文,所以发布时间不符。本文对 2 月 5 日的图床故障进行详细说明,并为了避免再次出现类似的问题,所做的一系列措施。如小伙伴们有任何问题,欢迎在评论区留言。

问题描述

根据监控服务平台数据显示,于 2 月 5 日上午十点左右发生了图床故障,导致所有图床服务「包括去不官网、图片外链、容量兑换」无法访问。

问题出现后很多小伙伴前往本站的评论区留言,反馈图床问题。杜老师收到反馈后,第一时间进行了问题的排查,并尝试了多种修复作业,但因为不在服务器附近,很多操作无法进行,最终只能暂时安抚小伙伴们。

问题原因

杜老师于当日 17 点返京,18 点到达服务器所在地,第一时间确认问题,开始进行修复工作,在短时间内恢复了图床相关服务的正常访问与使用,以减少对小伙伴们影响。

经排查是短期内产生大量的流量,达到家庭版光猫的性能瓶颈,产出较大热量,又因为光猫放置的地点问题,最终导致光猫宕机,影响了数据的正常传输。

解决方案

使用去不图床的小伙伴都很清楚,图床运营成本较大,为了减少成本,杜老师将服务器放置在家里的机柜中,通过家庭网络穿透公网,通过 CDN 反向代理来加速访问。

在重启光猫后,第一时间修正域名解析,在清理 CDN 域名解析缓存后,图床恢复正常。

后续措施

为了避免再次出现类似问题,杜老师已下单企业级的光猫,并选购了半导体制冷器,放置机柜中实现光猫和服务器的降温工作,保障在高流量下的稳定运行。

同时下单了新带宽安装,在双线路下即可保证图床的高速访问,又可防止单线路的故障问题。最后杜老师会尽可能的保障去不图床服务稳定运营,不会出现数据丢失,更不会出现跑路的问题!

  •  

今夜 20 点口令红包雨来袭手慢无

岁末钟声渐近,万家灯火可亲。值此辞旧迎新之际,杜老师怀着无比雀跃的心情,要在今夜晚 20 点整,为陪伴杜老师走过又一年的小伙伴们送上一份特别心意。快点进文章内,看看活动的细节吧!

感恩有您

蛇年已至,万象更新,愿小伙伴们在新的一年,生活如灵蛇般灵动,事业似祥蛇般腾飞,家庭像暖蛇般温馨。蛇年,愿小伙伴们皆行大运,岁岁顺心如意,年年福满乾坤:

活动细则

今年春节,杜老师想用最传统最有仪式感的方式,把这份心意装进红包里。不是冰冷抽奖程序,而是带着温度「暗号互动」

1 月 28 日「今晚」二十点整准时开启。

输入「杜老师祝蛇年快乐」

100 位锦鲤将获得随机的现金红包。

参与攻略

进入到支付宝,点击首页中的更多:

待页面刷新后,下拉界面,找到理财管理分类,点击红包:

在红包页面中,找到输入框并填写口令,点击确定即可领取红包:

注意不要弄错口令了哦:

温馨提醒

  1. 每位小伙伴仅限领一次;

  2. 口令有效期 24 小时「截止 1 月 29 日 20 点」

  3. 欢迎在评论区晒出领取金额,分享快乐;

  4. 活动最终解释权归杜老师说所有,如有雷同,一定是特别的缘分!

  •  

关于 Opengist 开源代码片段分享工具服务关闭的公告

Opengist 开源代码片段分享工具自上线以来,一直致力于为小伙伴们提供优质服务。然而,随着时间推移,我们发现平台的活跃用户数量非常少,综合考虑资源利用效率和运营成本等因素,我们做出了关闭服务的艰难决定。

关闭原因

长时间无人使用的情况日益突出。同时,平台占用服务器资源也相对较多,这给我们的运营带来了较大压力:

关闭流程

在关闭服务前,我们会对平台上的所有用户数据进行全面备份,包括但不限于用户信息、使用记录、上传的文件等,以保障已托管用户们的数据安全。

在本文发布后,我们将正式关闭 Opengist 开源代码片段分享工具服务,届时将无法再登录平台或者使用相关功能。为提供更充裕的时间进行数据下载和备份,我们会在关闭服务后一段时间内,提供数据下载服务。

数据备份与下载

为了方便获取和保存自己的数据,我们将提供数据备份文件的下载服务。可以通过下方链接进行数据下载:

下载地址

后续安排

关闭 Opengist 开源代码片段分享工具服务后,我们将对服务器的资源进行优化调整,以更好地支持我们的其它项目和服务。同时,我们也会继续关注用户的需求和反馈,努力提供更加优质的产品和服务。

再次感谢小伙伴们对 Opengist 开源代码片段分享工具的支持与理解。如在数据备份或下载过程中遇到任何问题,欢迎随时留言。

  •  

FreeFileSync 开源文件同步与备份利器

在数字化时代,文件管理和备份是每个用户都必须面对的重要任务。今天,向大家介绍一款开源的文件同步和备份软件 FreeFileSync。以其高效、免费和跨平台特点,成为众多用户在文件管理方面的首选工具。

写在前面

杜老师一直想自组个 NAS 主机,但苦于没有找到合适的系统,纠结于 Unraid 还是飞牛。Unraid 要收费,飞牛虽然免费,但很多功能的实现都是依托开源工具。就比如文件同步的功能,如需实现,还要借助第三方工具的。FreeFileSync 是非常好的选择,不仅开源免费,而且功能强大,可以帮助用户轻松完成各种文件同步任务:

什么是 FreeFileSync

FreeFileSync 是款功能强大的文件夹比较和同步软件,旨在帮助用户高效创建和管理重要文件的备份副本。与传统的备份工具不同,FreeFileSync 并不是简单地复制每一个文件,而是通过智能算法,确定源文件夹和目标文件夹之间差异,仅传输必要的数据。这种方法不仅节省了时间和带宽,还大大提高了同步效率:

开源与跨平台优势

FreeFileSync 是一款开源软件,这意味着它的代码是完全开放的,用户和开发者可以自由查看、修改、分发。开源优势在于,社区的力量可以不断优化和改进软件,使其更稳定和安全。此外,FreeFileSync 支持 Windows、macOS 和 Linux 三大主流的操作系统,无论桌面用户还是服务器管理员,都可以在自己的设备上无缝使用:

功能亮点

智能同步:FreeFileSync 的核心功能是其智能同步机制。它能够快速比较两个文件夹内容,识别出哪些文件被修改、删除、新增。用户可根据自己的需求选择同步模式,如单向同步或双向同步。这种灵活性使得 FreeFileSync 适用各种场景,从简单个人文件备份到复杂的多设备同步。

高效备份:对于备份任务,FreeFileSync 提供了多种选项。用户可以设置定时备份计划,确保重要文件定期自动备份。此外,软件支持增量备份,这意味着它只会备份自上次备份以来发生变化部分,从而节省存储空间。这种高效的备份方式对于那些需要频繁备份大量数据的用户来说非常实用。

易于使用:尽管 FreeFileSync 的功能强大,但它界面设计简洁直观,即使是新手用户也可以轻松上手。软件提供详细的教程和帮助文档,帮助用户快速掌握核心功能。此外,FreeFileSync 还支持拖放操作,用户可通过简单的拖放文件夹来设置同步任务,极大地提高了操作效率。

社区支持:作为开源软件,FreeFileSync 拥有一个活跃的社区。用户可以在社区论坛中寻求帮助、分享经验、参与开发。这种社区支持不仅为用户提供及时的技术支持,还为软件的持续改进提供了动力。许多用户反馈的功能和建议都被纳入后续版本的开发中。

适用场景

FreeFileSync 适用各种文件管理和备份场景。对于个人用户来说,它可用来备份重要文件,例如照片、文档、视频。对于企业用户,FreeFileSync 可帮助他们实现服务器之间的数据同步,确保数据的一致性和安全性。此外,FreeFileSync 还可以用于多设备之间的文件共享,例如在家庭网络中同步不同设备上的文件:

下载地址

杜老师为了方便小伙伴下载,已经打包好 14 版本的软件包。下面是 Windows、macOS 和 Linux 三大主流操作系统安装包:

下载地址
  •  

探索浏览器性能利器 Speedometer 3.0

在当今数字化时代,浏览器已成为我们日常生活中不可或缺的工具。如何衡量浏览器性能呢?Speedometer 3.0 正为此而生。它是一款专注于测试浏览器响应速度和性能的基准测试工具,通过模拟真实用户操作,帮助我们深入了解浏览器在处理复杂任务时的表现。

Speedometer 3.0 浏览器性能的试金石

Speedometer 3.0 是由 BrowserBench.org 开发的一款浏览器基准测试工具,旨在通过模拟真实 Web 应用场景来评估浏览器的响应能力。它通过一系列的演示 Web 应用程序,模拟用户常见操作行为,例如添加待办事项、编辑文档、浏览网页等等,从而量化浏览器在处理这些任务时的效率:

测试原理、方法

Speedometer 3.0 的测试原理是基于对 Web 应用的响应时间测量。它通过运行一系列预设的 Web 应用场景,记录浏览器在处理这些任务时的响应时间。这些场景涵盖从简单的页面加载到复杂的交互操作,例如在待办事项列表中添加任务、在文本编辑器输入文字、在表格中添加数据等等。通过这些多样化的测试场景,Speedometer 3.0 能够全面评估浏览器在不同负载的性能表现。

在测试过程中,Speedometer 3.0 会自动调整测试任务复杂程度,以确保测试结果准确性和可靠性。它还会根据浏览器性能表现动态调整测试参数,从而避免因浏览器性能差异而导致的测试偏差。这种自适应的测试方法使得 Speedometer 3.0 能够在不同类型的浏览器上获得一致的测试结果,为用户提供公平的比较基准。

如何进行测试

进行测试非常简单。用户只需访问官方网站,然后按照页面上的提示操作即可。在开始测试前,Speedometer 3.0 会自动检查浏览器窗口的大小,并提示用户调整窗口大小以确保测试结果的准确性。测试过程通常需几分钟时间,具体取决于浏览器的性能和测试设备硬件配置。在测试完成后,Speedometer 3.0 会生成一份详细测试报告,用户可将这份报告保存或分享给他人。此外,Speedometer 3.0 还支持跨设备和跨浏览器比较功能,用户可轻松地对比不同浏览器或不同设备上的测试结果,从而找到适合自己的浏览器:

测试结果解读

Speedometer 3.0 的测试结果以分数的形式呈现,分数越高表示浏览器的响应速度越快,性能越好。测试结果不仅包括总分,还会详细列出各个测试场景得分情况。这使得用户可深入了解浏览器在不同任务类型下的表现,如在处理文本编辑任务时是否更高效,或者在加载复杂网页时是否更快。此外,Speedometer 3.0 还提供了一些额外的性能指标,如帧率和延迟时间。帧率反映浏览器在处理动画和交互操作时的流畅度,而延迟时间则表示浏览器在接收到用户操作指令后响应速度。通过这些详细性能指标,用户可以更全面地了解浏览器的性能特点,从而做出更明智的选择:

  •  

宽带商 DNS 地址整理「仅 IPv4」

DNS 是互联网核心基础设施的关键组成部分,当计算机配置为使用距离最近 DNS 服务器时,可以显著提升域名解析效率,从而有效降低网络延时,优化网络服务响应速度,为用户带来更为流畅高效的网络体验。

中国电信 DNS 服务器地址大全

省市主 DNS备 DNS
安徽电信61.132.163.68202.102.213.68
北京电信219.141.136.10219.141.140.10
重庆电信61.128.192.6861.128.128.68
福建电信218.85.152.99218.85.157.99
甘肃电信202.100.64.6861.178.0.93
广东电信202.96.128.86202.96.128.166
广西电信202.103.225.68202.103.224.68
贵州电信202.98.192.67202.98.198.167
河南电信222.88.88.88222.85.85.85
黑龙江电信 DNS219.147.198.230219.147.198.242
湖北电信202.103.24.68202.103.0.68
湖南电信59.51.78.21159.51.78.210
江苏电信218.2.2.2218.4.4.4
江西电信202.101.224.69202.101.226.68
内蒙古电信 DNS219.148.162.31222.74.39.50
山东电信219.146.1.66219.147.1.66
陕西电信218.30.19.4061.134.1.4
上海电信202.96.209.133116.228.111.118
四川电信61.139.2.69218.6.200.139
天津电信219.150.32.132219.146.0.132
云南电信222.172.200.6861.166.150.123
浙江电信202.101.172.3561.153.177.196

中国联通 DNS 服务器地址大全

省市主 DNS备 DNS
北京联通123.123.123.123123.123.123.124
重庆联通221.5.203.98221.7.92.98
广东联通210.21.196.6221.5.88.88
河北联通202.99.160.68202.99.166.4
河南联通202.102.224.68202.102.227.68
黑龙江联通 DNS202.97.224.69202.97.224.68
吉林联通202.98.0.68202.98.5.68
江苏联通221.6.4.66221.6.4.67
内蒙古联通 DNS202.99.224.68202.99.224.8
山东联通202.102.128.68202.102.152.3
山西联通202.99.192.66202.99.192.68
陕西联通221.11.1.67221.11.1.68
上海联通210.22.70.3210.22.84.3
四川联通119.6.6.6124.161.87.155
天津联通202.99.104.68202.99.96.68
浙江联通221.12.1.227221.12.33.227
辽宁联通202.96.69.38202.96.64.68

中国移动 DNS 服务器地址大全

省市主 DNS备 DNS
安徽移动211.138.180.2211.138.180.3
山东移动218.201.96.130211.137.191.26
山西移动211.138.106.2211.138.106.3
江苏移动221.131.143.69112.4.0.55
浙江移动211.140.13.188211.140.188.188
湖南移动211.142.210.98211.142.210.99
湖北移动211.137.58.20211.137.64.163
江西移动211.141.90.68211.141.90.69
陕西移动211.137.130.3211.137.130.19
四川移动211.137.82.4
重庆移动218.201.4.3218.201.21.132
北京移动221.130.33.52221.130.33.60
天津移动211.137.160.50211.137.160.185
上海移动211.136.112.50211.136.150.66
广东移动211.136.192.6211.136.20.204
广西移动211.138.245.180211.136.17.108
贵州移动211.139.5.29211.139.5.30
福建移动211.138.151.161211.138.156.66
河北移动211.143.60.56211.138.13.66
甘肃移动218.203.160.194218.203.160.195
黑龙江移动 DNS211.137.241.34211.137.241.35
吉林移动211.141.16.99211.141.0.99
辽宁移动211.137.32.178211.140.197.58
云南移动211.139.29.68211.139.29.69
海南移动221.176.88.95211.138.164.6
内蒙古移动 DNS211.138.91.1211.138.91.2
新疆移动218.202.152.130218.202.152.131
西藏移动211.139.73.34211.139.73.35
青海移动211.138.75.123
香港移动203.142.100.18203.142.100.21

中国铁通 DNS 服务器地址大全

省市主 DNS备 DNS
广东铁通61.235.70.252211.98.4.1

中国广电 DNS 服务器地址大全

省市主 DNS备 DNS
广东广电、珠江宽频116.199.0.200116.116.116.116

中国长城宽带 DNS 服务器地址大全

省市主 DNS备 DNS
广东长城宽带211.162.78.1211.162.78.2
  •  

Follow 开启个性化信息汇聚的新时代

在信息爆炸的当下,我们每天都会被海量的内容包围,从新闻资讯到娱乐八卦,从专业文章到生活琐事,各种信息纷至沓来。如何在繁杂信息海洋中精准地筛选出自己真正感兴趣的内容,Follow 或许就是解决这一问题的神器。

打造专属信息空间

Follow 首先吸引杜老师的是它那定制化信息中心的理念。在这个平台上,用户可订阅海量的资讯源和精选列表。无论是热门的新闻频道,还是小众兴趣部落,只要是您感兴趣的,都可轻松订阅。更重要是,Follow 允许用户对这些订阅内容进行深度定制。您可以根据自己的喜好,将不同来源的信息进行分类整理,创建出一个个个性化的信息板块。比如,您可将所有关于科技前沿的资讯归为一类,将体育赛事的最新动态单独列出,甚至还可为自己的偶像创建一个专属的信息流,实时追踪他们最新动态。这样一来,您就可以在一个小小的收件箱里,轻松的掌握所有对您来说真正重要的信息,再也不用在多个网站间来回切换,浪费宝贵时间:

多媒体内容全覆盖

在这个多媒体盛行时代,信息的表现形式早已不再局限于文字。图片、视频、音频等元素的加入,让内容变得更丰富多彩。Follow 深知这一点,因此提供动态内容支持。无论是长篇的文章、精美的图片集,还是精彩视频、动听音频,Follow 都能够完美呈现。当您在浏览信息时,无需担心因为内容形式的差异而出现兼容问题。无论是想要欣赏一段优美的音乐,还是观看一场精彩演讲,Follow 都能让您流畅地享受其中。这种全方位的内容支持,满足了用户在不同场景下的多元需求,无论工作学习,还是休闲娱乐,都可以找到适合自己的内容形式:

助力提升浏览体验

科技飞速发展,让人工智能逐渐融入到我们的日常生活中。Follow 将 AI 技术巧妙地融入到了平台的各项功能中,为用户带来了 AI 尽在指尖的便捷体验。首先,AI 驱动的翻译功能,打破了语言的障碍。在这个全球化时代,许多优质资讯可能因为语言不通而被我们错过。而 Follow 的 AI 翻译,能够快速准确地将不同语言内容翻译成用户熟悉的语言,让我们能够轻松阅读来自世界各地的信息。其次,AI 摘要功能则为用户节省了大量时间。面对篇幅较长文章,AI 能够精准提炼出核心要点,让用户在短时间内快速了解文章主旨,帮助我们更高效地筛选有价值的内容。此外,还有诸如智能推荐等 AI 功能,根据用户的浏览历史和兴趣偏好,为用户推荐可能感兴趣的新内容,不断拓展我们信息视野:

赋能创作者与用户

在 Follow 的世界里,还有一个独特的存在 Power。这是一种全新的所有权经济模式,它赋予了用户和创作者更多的权力和价值。用户可以通过 Power 直接向自己喜欢的创作者打赏,表达对他们作品支持和喜爱。这种即时打赏机制,不仅能够激励创作者持续产出优质的内容,还可以让用户与创作者之间建立起更加紧密的联系。同时,创作者也能通过自己的内容获得相应的 Power 收益,实现内容商业价值转化。更重要的,Power 还能够让用户在自己的作品中解锁更多价值。当您在 Follow 上分享自己的见解、创作自己的内容时,也有可能获得他人的打赏和支持,让您的创意和智慧得到应有回报。这种经济模式创新,真正实现了内容的价值回归,让每一个参与者都能在这个生态中找到自己的位置,共同推动内容创作繁荣发展:

超越构建社区生态

Follow 不仅仅是一个简单的应用,它更是一个充满活力的社区。在这里用户不再是孤立的信息接收者,而是能积极参与到社区的互动中。您可以与其他用户交流心得、分享观点,甚至能参与到内容的共创中。Follow 鼓励用户之间的开放合作,共同打造一个更加丰富多元信息生态。社区中的每一个成员都可以为内容的质量和多样性贡献力量,通过大家共同努力,使得 Follow 成为一个真正属于用户自己的信息家园。在这里您不仅能够获取信息,还可以结交志同道合的朋友,拓展自己社交圈子,共同探索未知世界:

杜老师说订阅地址

如果您也有 Follow 账户,欢迎访问杜老师的订阅地址,可以第一时间获取本站博文更新。可惜无法同步评论功能,所以需要交流的话,还需访问原文地址,在评论区留言:

经常有小伙伴因侧边栏的随机图,谣传说杜老师喜欢美女、黑丝啥的。这里严肃声明杜老师从来不看侧边栏,这里分享一个图集,侧边栏仅随机一张,哪里够看:

  •  

使用 GoAccess 分析 Nginx 访问日志

Nginx 的访问日志中蕴含丰富的信息,然而直接阅读对于大多数人来说是一项艰巨的任务。但我们有 GoAccess 这样的强大工具,它能够帮助我们轻松地分析和可视化 Nginx 的访问日志。

工具安装

对于基于 Debian 的系统「如 Ubuntu」,可以使用以下命令安装:

1
2
sudo apt-get update
sudo apt-get install goaccess

对于基于 Red Hat 的系统「如 CentOS」,可以使用以下命令安装:

1
sudo yum -y install goaccess

源码安装

如果想要从源码安装 GoAccess,可以按照以下步骤操作。先下载 GoAccess 的源码包:

1
wget https://tar.goaccess.io/goaccess-1.4.tar.gz

再解压并编译安装:

1
2
3
4
tar -xzvf goaccess-1.4.tar.gz
cd goaccess-1.4/
./configure --enable-geoip --enable-utf8
make && sudo make install

配置工具

我们需要对 GoAccess 进行配置,确保它能够正确地解析 Nginx 的访问日志。GoAccess 配置文件通常位于 /etc/goaccess/goaccess.conf。对于 Nginx 的默认日志格式,可直接使用--log-format=COMBINED 参数。如果 Nginx 配置了自定义的日志格式,需在 GoAccess 的配置文件中指定相应的日志格式。例如:

1
log-format %h %^[%d:%t %^] "%r" %s %b "%R" "%u"

还需指定日期和时间的格式,以确保 GoAccess 能够正确地解析日志文件中的日期和时间信息。例如:

1
2
date-format %d/%b/%Y
time-format %H:%M:%S

分析日志

在终端直接运行 GoAccess,它会进入一个交互式的界面,显示日志分析结果。在交互式界面中可使用键盘方向键和数字键来浏览和查看不同的统计信息。例如:

1
goaccess /var/log/nginx/access.log --log-format=COMBINED

GoAccess 可将分析结果输出为 HTML 格式的报告,方便在 Web 浏览器中查看。下面的命令将生成一个名为 report.html 的文件,包含丰富的统计信息和图表:

1
goaccess /var/log/nginx/access.log -o report.html --log-format=COMBINED

GoAccess 支持实时监控 Nginx 访问日志,可动态地更新统计信息。如要启用实时监控,可以使用以下命令:

1
--real-time-html --daemonize

启动一个后台进程,实时分析日志文件,并将结果输出到指定的 HTML 文件中,完整参考命令如下:

1
goaccess /var/log/nginx/access.log -o /var/www/html/report.html --log-format=COMBINED --real-time-html --daemonize

分析结果解读

GoAccess 提供了丰富的统计信息和图表,帮助我们全面了解网站访问情况,包括访问概览:

维度描述
网站的总访问次数显示网站总访问量。
网站的独立访客数统计访问网站的不同 IP 地址数量。
总数据传输量表示网站传输数据总量,单位通常为 MB 或 GB。

网站的访问者信息:

维度描述
IP 地址的排名列出访问网站的 IP 地址及其访问次数,可以了解访问者的地理位置分布。
访问者的浏览器和操作系统统计访问者使用的浏览器和操作系统类型,有助于优化网站兼容性。

请求信息:

维度描述
请求方法显示不同 HTTP 请求方法的请求次数。
请求的状态码统计不同 HTTP 状态码请求次数,如 200 表示成功,404 表示未找到。
请求 URL 的排名列出被访问最多 URL 地址,可发现网站的热门内容。

性能分析:

维度描述
请求时间分布显示不同时间段请求量,可发现访问高峰期。
最耗时的请求列出响应时间最长请求,有助于发现性能的瓶颈。

高级用法

除了基本分析功能,GoAccess 还支持一些高级用法。例如可使用管道和过滤器来处理日志数据,下面命令将实时地分析 Nginx 的访问日志,并显示最新的统计信息:

1
tail -f /var/log/nginx/access.log | goaccess -p /etc/goaccess/goaccess.conf

GoAccess 可支持同时分析多个日志文件,下面命令将合并多个日志文件的分析结果:

1
goaccess -p /etc/goaccess/goaccess.conf access.log.1 access.log.2
  •  

通过 Nginx 的 access_log 分析网站的流量

在当今数字化时代,网站流量分析对于理解用户行为、优化网站性能以及制定营销策略至关重要。本文将探讨如何通过分析 Nginx 的 access_log 获取网站流量的多维度数据,并给出具体操作步骤和分析方法。

日志格式

在开始分析前,我们需要了解 access_log 的默认日志格式。通常情况 access_log 的日志格式如下:

1
2
3
log_format combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';

这个格式包含以下字段:

字段说明
$remote_addr客户端 IP 地址
$remote_user客户端用户名
$time_local本地时间
$request请求方法、请求 URI 以及 HTTP 版本
$statusHTTP 状态码
$body_bytes_sent发送给客户端的字节数
$http_referer请求来源的 URL
$http_user_agent客户端浏览器的用户代理字符串

Nginx 访问量分析

要统计网站的总访问量,可通过计算 access_log 文件的行数来实现。在 Linux 系统中可以使用 wc -l 命令,该命令会输出 access.log 文件的行数,即为网站总访问量:

1
wc -l access.log

了解访问量在不同时间段的分布情况,有助于我们发现网站访问高峰和低谷。可以使用 awk 命令按小时或分钟统计请求数,下面的命令会输出按小时或分钟统计的请求数,并且显示请求数最多的前 100 个时间点:

1
2
3
4
# 每小时统计请求数
awk '{print $4}' access.log | cut -c 14-15 | sort | uniq -c | sort -nr | head -n 100
# 每分钟统计请求数
awk '{print $4}' access.log | cut -c 14-18 | sort | uniq -c | sort -nr | head -n 100

访问来源分析

分析访问来源 IP 可以了解用户主要来自哪些地区或网络环境。使用 awksort 命令可以统计访问量最多的 IP 地址,该命令会输出访问量最多的前 10 个 IP 地址及其访问次数:

1
awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -n 10

查看访问来源 URL 有助于我们了解用户是如何找到我们网站的。可以使用以下命令统计访问来源最多的 URL,该命令会输出访问来源最多的前 10 个 URL 及访问次数:

1
awk '{print $11}' access.log | sort | uniq -c | sort -nr | head -n 10

页面访问分析

了解哪些页面访问量最高可帮助我们优化这些页面的性能和内容。使用 awk 命令可统计访问最频繁的页面,下面命令会输出访问最频繁的前 100 个页面及其访问次数:

1
awk '{print $7}' access.log | sort | uniq -c | sort -rn | head -n 100

分析页面的访问时间可以发现哪些页面的加载时间较长,需要优化。在 Nginx 的 log_format 中加入 $request_time 字段,然后使用以下命令列出传输时间超过 3 秒页面,该命令会输出传输时间超过 3 秒的页面及其出现的次数,仅显示前 20 条记录:

1
cat access.log | awk '($NF > 3){print $7}' | sort -n | uniq -c | sort -nr | head -20

用户行为分析

分析用户代理字符串可以了解用户使用的浏览器类型和版本。使用 awk 命令可统计不同浏览器的访问次数,该命令会输出不同浏览器访问次数及其用户代理字符串:

1
awk -F '"' '{print $6}' access.log | sort | uniq -c | sort -nr | head -n 10

通过分析用户的访问路径可以了解用户在网站中的导航行为。可以使用以下命令统计访问路径的长度和频率,该命令会输出访问路径的长度及其出现的次数,仅显示前 10 条记录:

1
awk '{print $7}' access.log | awk -F '/' '{print NF-1}' | sort | uniq -c | sort -nr | head -n 10

性能分析

响应时间是衡量网站性能的重要指标之一。可使用以下命令统计响应时间的分布情况,该命令会输出响应时间及其出现次数,仅显示前 10 条记录:

1
awk '{print $NF}' access.log | sort -n | uniq -c | sort -nr | head -n 10

HTTP 状态码反映了请求的成功与否以及错误类型。可以使用以下命令统计不同状态码的出现次数,该命令会输出不同状态码及其出现的次数,仅显示前 10 条记录:

1
awk '{print $9}' access.log | sort | uniq -c | sort -nr | head -n 10
  •  

Office 多版本产品激活密钥分享

之前有小伙伴问到是否有 Office 产品的激活密钥,杜老师在微软的官网上好顿搜索,终于是找到了!目前 Office 有两大版本,一个是年度版「如 2024」一个是订阅版「即 365」订阅版不可以破解使用,文中均为年度版的激活密钥。

GVLK for Office LTSC 2024

产品GVLK
Office LTSC 专业增强版 2024XJ2XN-FW8RK-P4HMP-DKDBV-GCVGB
Office LTSC 标准版 2024V28N4-JG22K-W66P8-VTMGK-H6HGR
Project Professional 2024FQQ23-N4YCY-73HQ3-FM9WC-76HF4
Project Standard 2024PD3TT-NTHQQ-VC7CY-MFXK3-G87F8
Visio LTSC Professional 2024B7TN8-FJ8V3-7QYCP-HQPMV-YY89G
Visio LTSC Standard 2024JMMVY-XFNQC-KK4HK-9H7R3-WQQTV
Access LTSC 202482FTR-NCHR7-W3944-MGRHM-JMCWD
Excel LTSC 2024F4DYN-89BP2-WQTWJ-GR8YC-CKGJG
Outlook LTSC 2024D2F8D-N3Q3B-J28PV-X27HD-RJWB9
PowerPoint LTSC 2024CW94N-K6GJH-9CTXY-MG2VC-FYCWP
Skype for Business LTSC 20244NKHF-9HBQF-Q3B6C-7YV34-F64P3
Word LTSC 2024MQ84N-7VYDM-FXV7C-6K7CC-VFW9J

GVLK for Office LTSC 2021

产品GVLK
Office LTSC Professional Plus 2021FXYTK-NJJ8C-GB6DW-3DYQT-6F7TH
Office LTSC Standard 2021KDX7X-BNVR8-TXXGX-4Q7Y8-78VT3
Project Professional 2021FTNWT-C6WBT-8HMGF-K9PRX-QV9H8
Project Standard 2021J2JDC-NJCYY-9RGQ4-YXWMH-T3D4T
Visio LTSC Professional 2021KNH8D-FGHT4-T8RK3-CTDYJ-K2HT4
Visio LTSC Standard 2021MJVNY-BYWPY-CWV6J-2RKRT-4M8QG
Access LTSC 2021WM8YG-YNGDD-4JHDC-PG3F4-FC4T4
Excel LTSC 2021NWG3X-87C9K-TC7YY-BC2G7-G6RVC
Outlook LTSC 2021C9FM6-3N72F-HFJXB-TM3V9-T86R9
PowerPoint LTSC 2021TY7XF-NFRBR-KJ44C-G83KF-GX27K
Publisher LTSC 20212MW9D-N4BXM-9VBPG-Q7W6M-KFBGQ
Skype for Business LTSC 2021HWCXN-K3WBT-WJBKY-R8BD9-XK29P
Word LTSC 2021TN8H9-M34D3-Y64V9-TR72V-X79KV

Office 2019 的 GVLK

产品GVLK
Office 专业增强版 2019NMMKJ-6RK4F-KMJVX-8D9MJ-6MWKP
2019 Office Standard6NWWJ-YQWMR-QKGCB-6TMB3-9D9HK
Project Professional 2019B4NPR-3FKK7-T2MBV-FRQ4W-PKD2B
2019 Project StandardC4F7P-NCP8C-6CQPT-MQHV9-JXD2M
2019 Visio Professional9BGNQ-K37YR-RQHF2-38RQ3-7VCBB
2019 Visio Standard7TQNQ-K3YQQ-3PFH7-CCPPM-X4VQ2
Access 20199N9PT-27V4Y-VJ2PD-YXFMF-YTFQT
Excel 2019TMJWT-YYNMB-3BKTF-644FC-RVXBD
Outlook 20197HD7K-N4PVK-BHBCQ-YWQRW-XW4VK
PowerPoint 2019RRNCX-C64HY-W2MM7-MCH9G-TJHMQ
Publisher 2019G2KWX-3NW6P-PY93R-JXK2T-C9Y9V
Skype for Business 2019NCJ33-JHBBY-HTK98-MYCV8-HMKHJ
Word 2019PBX3G-NWMT6-Q7XBW-PYJGG-WXD33

Office 2016 的 GVLK

产品GVLK
Office Professional Plus 2016XQNVK-8JYDB-WJ9W3-YJ8YR-WFG99
Office Standard 2016JNRGM-WHDWX-FJJG3-K47QV-DRTFM
Project Professional 2016YG9NW-3K39V-2T3HJ-93F3Q-G83KT
Project Standard 2016GNFHQ-F6YQM-KQDGJ-327XX-KQBVC
Visio Professional 2016PD3PC-RHNGV-FXJ29-8JK7D-RJRJK
Visio Standard 20167WHWN-4T7MP-G96JF-G33KR-W8GF4
Access 2016GNH9Y-D2J4T-FJHGG-QRVH7-QPFDW
Excel 20169C2PK-NWTVB-JMPW8-BFT28-7FTBF
OneNote 2016DR92N-9HTF2-97XKM-XW2WJ-XW3J6
Outlook 2016R69KK-NTPKF-7M3Q4-QYBHW-6MT9B
PowerPoint 2016J7MQP-HNJ4Y-WJ7YM-PFYGF-BY6C6
Publisher 2016F47MM-N3XJP-TQXJ9-BP99D-8837K
Skype for Business 2016869NQ-FJ69K-466HW-QYCP2-DDBV6
Word 2016WXY84-JN2Q9-RBCCQ-3Q3J3-3PFJ6
  •  

祝杜老师说的小伙伴们元旦快乐

一觉醒来,发现日历到了 2025 年。首先祝福小伙伴们元旦快乐,在新的一年里顺风顺水、心想事成、身体健康、流量滚滚!除此之外,杜老师也打算对 2024 年做一个简单总结,同时展望 2025 年~

元旦快乐

随着午夜钟声敲响,我们告别充满挑战与成长的一年,迎来了崭新的 2025 年。

在这个充满希望的时刻,杜老师想对每一位访问博客的朋友说一声:元旦快乐!

过去的一年里,我们一起经历了许多难忘的时刻。

感谢小伙伴们的支持和陪伴,是你们让这个博客充满活力,让每一次的互动都充满意义。

新的一年,杜老师说将带来更多高质量内容。

在新的一年里,愿大家的身体健康,心灵快乐。

愿大家的每一步都走得坚定、自信,每一个梦想都可以照进现实。

愿大家的生活充满爱与温暖,愿大家的事业和学业都能取得丰硕的成果。

回顾往事

不知是不是年龄的关系,杜老师发现自己对创作的热情似乎在渐渐退潮,出现了连续几次的拖更问题。

虽然最后都一一补更了,但还是有小伙伴反馈说体验不是很好。

尽管杜老师最终努力地补上了这些拖欠的内容,但还是收到一些忠实小伙伴们的反馈,他们表示有一丝的失望。

他们已经习惯了在特定的时间期待杜老师的新内容,但当他们满怀期待地打开网页却发现空空如也,那种失落感就像是一场未被兑现的约会让人有种白跑一趟的遗憾。

同时,为了尽快弥补这些缺失,杜老师有时会匆忙完成内容,没有给予它们应有的深思熟虑和精心打磨。

这样的匆忙往往导致内容的质量参差不齐,有时甚至显得过于敷衍,这无疑影响小伙伴们的阅读体验,让他们在期待中感到了失望。

展望明天

杜老师深知创作是和小伙伴们之间连接的桥梁。杜老师不愿意让这座桥梁因个人的原因而变得脆弱。

因此,杜老师在这里承诺,将重新点燃创作激情找回那份对文字的热爱和尊重。

杜老师会努力调整自己创作节奏,确保每次更新都能给小伙伴们带来期待中的惊喜和满足。

杜老师将更加注重内容的质量而不是数量。杜老师会花更多的时间去斟酌每一个字句,确保每篇内容都能像精心培育的花朵一样,绽放出它应有光彩。

杜老师会倾听每位小伙伴的声音,因为大家的反馈是杜老师前进的动力,也是杜老师不断进步的源泉。

再次感谢小伙伴们的理解和支持,杜老师将用更好的内容回报你们的信任和喜爱。

镇博萌宠

其实杜老师本是想放两张喜庆一些的图片,担心版权问题就用 AI 来生成,奈何 AI 生成的图片涉及文字显示出现乱码,所以就放两张萌宠图片:

随着年龄增加仪式感也越发薄弱,喵咪的仪式感更低,就在椅子上面趴着,除了吃就是睡,偶尔去猫砂盆方便一下。杜老师下辈子也想做猫:

  •  

Windows 系统多版本产品激活密钥分享

有小伙伴问到关于 Windows 的产品激活密钥,杜老师收集了一些。这里分享有关桌面及服务器各个版本激活密钥,需要配合 KMS 服务器使用,如不知道如何操作,可在评论区中留言!

Windows Server LTSC 版

Windows Server 2025 多版本产品密钥如下:

操作系统版本KMS 客户端安装密钥
Windows Server 2025 StandardTVRH6-WHNXV-R9WG3-9XRFY-MY832
Windows Server 2025 DatacenterD764K-2NDRG-47T6Q-P8T8W-YP6DF
Windows Server 2025 Datacenter:Azure EditionXGN3F-F394H-FD2MY-PP6FD-8MCRC

Windows Server 2022 多版本产品密钥如下:

操作系统版本KMS 客户端安装密钥
Windows Server 2022 StandardVDYBN-27WPP-V4HQT-9VMD4-VMK7H
Windows Server 2022 DatacenterWX4NM-KYWYW-QJJR4-XV3QB-6VM33
Windows Server 2022 Datacenter: Azure EditionNTBV8-9K7Q8-V27C6-M2BTV-KHMXV

Windows Server 2019 多版本产品密钥如下:

操作系统版本KMS 客户端安装密钥
Windows Server 2019 StandardN69G4-B89J2-4G8F4-WWYCC-J464C
Windows Server 2019 DatacenterWMDGN-G9PQG-XVVXX-R3X43-63DFG
Windows Server 2019 EssentialsWVDHN-86M7X-466P6-VHXV7-YY726

Windows Server 2016 多版本产品密钥如下:

操作系统版本KMS 客户端安装密钥
Windows Server 2016 StandardWC2BQ-8NRM3-FDDYY-2BFGV-KHKQY
Windows Server 2016 DatacenterCB7KF-BWN84-R7R2Y-793K2-8XDDG
Windows Server 2016 EssentialsJCKRF-N37P4-C2D82-9YXRT-4M63B

半年频道版本

Windows Server 版本 20H2/2004/1909/1903/1809 产品密钥如下:

操作系统版本KMS 客户端安装密钥
Windows Server StandardN2KJX-J94YW-TQVFB-DG9YT-724CC
Windows Server Datacenter6NMRW-2C8FM-D24W7-TQWMY-CWH2D

Windows 11 和 Windows 10 多版本产品密钥如下:

操作系统版本KMS 客户端安装密钥
Windows 10/11 专业版W269N-WFGWX-YVC9B-4J6C9-T83GX
Windows 10/11 专业版本 NMH37W-N47XK-V7XM9-C7227-GCQG9
Windows 10/11 专业工作站NRG8B-VKK3Q-CXVCJ-9G2XF-6Q84J
Windows 10/11 专业工作站版 N9FNHH-K3HBT-3W4TD-6383H-6XYWF
Windows 10/11 专业教育版6TP4R-GNPTD-KYYHQ-7B7DP-J447Y
Windows 10/11 专业教育版本 NYVWGF-BXNMC-HTQYQ-CPQ99-66QFC
Windows 10/11 教育版NW6C2-QMPVW-D7KKK-3GKT6-VCFB2
Windows 10/11 教育版本 N2WH4N-8QGBV-H22JP-CT43Q-MDWWJ
Windows 10/11 企业版NPPR9-FWDCX-D2C8J-H872K-2YT43
Windows 10/11 企业版本 NDPH2V-TTNVB-4X9Q3-TJR4H-KHJW4
Windows 10/11 企业版本 GYYVX9-NTFWV-6MDM3-9PT4T-4M68B
Windows 10/11 企业版本 G N44RPN-FTY23-9VTTB-MP9BX-T84FV

早期版本的 Windows Server

Windows Server 版本 1803 产品密钥如下:

操作系统版本KMS 客户端安装密钥
Windows Server StandardPTXN8-JFHJM-4WC78-MPCBR-9W4KR
Windows Server Datacenter2HXDN-KRXHB-GPYC7-YCKFJ-7FVDG

Windows Server 版本 1709 产品密钥如下:

操作系统版本KMS 客户端安装密钥
Windows Server StandardDPCNP-XQFKJ-BJF7R-FRC8D-GF6G4
Windows Server Datacenter6Y6KB-N82V8-D8CQV-23MJW-BWTG6

Windows Server 2012 R2 多版本产品密钥如下:

操作系统版本KMS 客户端安装密钥
Windows Server 2012 R2 StandardD2N9P-3P6X9-2R39C-7RTCD-MDVJX
Windows Server 2012 R2 DatacenterW3GGN-FT8W3-Y4M27-J84CP-Q3VJ9
Windows Server 2012 R2 EssentialsKNC87-3J2TX-XB4WP-VCPJV-M4FWM

Windows Server 2012 多版本产品密钥如下:

操作系统版本KMS 客户端安装密钥
Windows Server 2012BN3D2-R7TKB-3YPBD-8DRP2-27GG4
Windows Server 2012 N8N2M2-HWPGY-7PGT9-HGDD8-GVGGY
Windows Server 2012 单语言2WN2H-YGCQR-KFX6K-CD6TF-84YXQ
Windows Server 2012 特定地区版4K36P-JN4VD-GDC6V-KDT89-DYFKP
Windows Server 2012 StandardXC9B7-NBPP2-83J2H-RHMBY-92BT4
Windows Server 2012 MultiPoint 标准版HM7DN-YVMH3-46JC3-XYTG7-CYQJJ
Windows Server 2012 MultiPoint 高级版XNH6W-2V9GX-RGJ4K-Y8X6F-QGJ2G
Windows Server 2012 Datacenter48HP8-DN98B-MYWDG-T2DCC-8W83P
Windows Server 2012 EssentialsHTDQM-NBMMG-KGYDT-2DTKT-J2MPV

Windows Server 2008 R2 多版本产品密钥如下:

操作系统版本KMS 客户端安装密钥
Windows Server 2008 R2 Web 版6TPJF-RBVHG-WBW2R-86QPH-6RTM4
Windows Server 2008 R2 HPC 版TT8MH-CG224-D3D7Q-498W2-9QCTX
WindowsServer 2008 R2 标准版YC6KT-GKW9T-YTKYR-T4X34-R7VHC
WindowsServer 2008 R2 企业版489J6-VHDMP-X63PK-3K798-CPX3Y
WindowsServer 2008 R2 Datacenter74YFP-3QFB3-KQT8W-PMXWJ-7M648

Windows Server 2008 多版本产品密钥如下:

操作系统版本KMS 客户端安装密钥
Windows Web Server 2008WYR28-R7TFJ-3X2YQ-YCY4H-M249D
Windows Server 2008 标准版TM24T-X9RMF-VWXK6-X8JC9-BFGM2
不带 Hyper-V 的 Windows Server 2008 标准版W7VD6-7JFBR-RX26B-YKQ3Y-6FFFJ
Windows Server 2008 企业版YQGMW-MPWTJ-34KDK-48M3W-X4Q6V
不带 Hyper-V 的 Windows Server 2008 企业版39BXF-X8Q23-P2WWT-38T2F-G3FPG
Windows Server 2008 HPCRCTX3-KWVHP-BR6TB-RB6DM-6X7HP
Windows Server 2008 数据中心版7M67G-PC374-GR742-YH8V4-TCBY3
不带 Hyper-V 的 Windows Server 2008 数据中心版22XQ2-VRXRG-P8D42-K34TD-G3QQC

早期版本的 Windows

Windows 8.1 多版本产品密钥如下:

操作系统版本KMS 客户端安装密钥
Windows 8.1 专业版GCRJD-8NW9H-F2CDX-CCM8D-9D6T9
Windows 8.1 专业版本 NHMCNV-VVBFX-7HMBH-CTY9B-B4FXY
Windows 8.1 企业版MHF9N-XY6XB-WVXMC-BTDCT-MKKG7
Windows 8.1 企业版本 NTT4HM-HN7YT-62K67-RGRQJ-JFFXW

Windows 8 多版本产品密钥如下:

操作系统版本KMS 客户端安装密钥
Windows 8 专业版NG4HW-VH26C-733KW-K6F98-J8CK4
Windows 8 专业版本 NXCVCF-2NXM9-723PB-MHCB7-2RYQQ
Windows 8 企业版32JNW-9KQ84-P47T8-D8GGY-CWCK7
Windows 8 企业版本 NJMNMF-RHW7P-DMY6X-RF3DR-X2BQT

Windows 7 多版本产品密钥如下:

操作系统版本KMS 客户端安装密钥
Windows 7 专业版FJ82H-XT6CR-J8D7P-XQJJ2-GPDD4
Windows 7 专业版本 NMRPKT-YTG23-K7D7T-X2JMM-QY7MG
Windows 7 专业版本 EW82YF-2Q76Y-63HXB-FGJG9-GF7QX
Windows7 企业版33PXH-7Y6KF-2VJC9-XBBR8-HVTHH
Windows 7 企业版本 NYDRBP-3D83W-TY26F-D46B2-XCKRJ
Windows 7 企业版本 EC29WB-22CC8-VJ326-GHFJW-H9DH4

Windows Vista 多版本产品密钥如下:

操作系统版本KMS 客户端产品密钥
Windows Vista 商用版YFKBB-PQJJV-G996G-VWGXY-2V3X8
Windows Vista 商用版本 NHMBQG-8H2RH-C77VX-27R82-VMQBT
Windows Vista 企业版VKK3X-68KWM-X2YGT-QR4M6-4BWMV
Windows Vista 企业版本 NVTC42-BM838-43QHV-84HX6-XJXKV
  •  

在线开源图片批量压缩工具

有人建议杜老师为去不图床添加压缩功能,这样可以减少图片体积,同时可以减少网络传输时间。但不少小伙伴还是有保留原版图片的需求,所以杜老师搭建了在线图片批量压缩图片平台。

工具介绍

支持多种图片格式,含 JEPG/PNG/WebP/GIF。

支持 20 兆以内图片压缩,最多支持 10 张图片同时操作。

支持压缩设置,可选缩小优先、普通压缩、清晰优先。

支持设置输出目标大小,及是否转换输出图片的格式。

在线平台

点击下方网址,即可访问搭建好的在线图片批量压缩工具:

部署过程

如不放心数据安全,可以使用下方源码自行部署。点击下方网址进入到 GitHub 源码页面,点击 Fork 复刻到自己仓库:

推荐使用 Vercel 部署与托管,部署过程参考下方配置。如果出现错误提示,可在评论区中贴图,杜老师看到后会第一时间回复的:

使用效果

部署完成后的效果如下:

  •  

在线开源图片处理工具

怕小伙伴们找不到趁手工具,杜老师找了款在线开源图片处理工具。文中介绍了该工具的部署及使用方法,虽然不如本地软件功能全面,但能够满足大部分需求,欢迎一试!

工具介绍

在线图像编辑器允许您使用 HTML5 技术创建和编辑图像,无需购买、下载、安装或者过时的 Flash,且无广告。

支持图层、滤镜,开源 Photoshop 替代品。

miniPaint 直接在浏览器中运行,可以通过从剪贴板粘贴或从计算机上传来创建图像。

不会向任何服务器发送任何内容,一切都保留在您的浏览器中。

在线平台

点击下方网址,即可访问搭建好的在线图片处理平台:

部署过程

如不放心数据安全,可以使用下方源码自行部署。点击下方网址进入到 GitHub 源码页面,点击 Fork 复刻到自己仓库:

推荐使用 Vercel 部署与托管,部署过程参考下方配置。如果出现错误提示,可在评论区中贴图,杜老师看到后会第一时间回复的:

使用效果

部署完成后的效果如下,如果默认不是中文界面,可以修改源代码文件 src/js/config.js,将其中 config.LANG 项改为 zh

  •  

这里有个可以白嫖三个一年 SSL 证书的网站

SSL 证书普及率很高,但目前只能申请到 90 天使用期限免费证书。虽然可以重复申请实现无限延期,但毕竟太麻烦。杜老师从淇云那里看到一个免费一年版的证书申请网站,感兴趣的小伙伴可以去领取!

网站介绍

DNSHE 是一个提供 SSL 证书服务的平台,为注册用户免费提供 3 个一年期单域名 SSL 证书。

SSL 证书对于网站安全性至关重要,它不仅能保护用户隐私,还能提升搜索引擎排名,增强网站的竞争力。

领取地址

下面是 DNSHE 官网地址,活动的截止时间为 2024 年 12 月 31 日:

在证书申请过程中,需生成 CSR 文件,可以使用以下网站在线生成:

申请步骤

点击上面的 DNSHE 官网地址,即可看到证书订购页面,确认金额为 0,点击立即订购:

在跳转的页面中找到并点击结账「可以返回之前页面,重复下单三次」

系统处理成功后会提示等待配置,点击页面下方立即配置进入申请页面:

在证书申请过程中,需生成 CSR 文件,我们通过上面网站在线生成:

返回配置页面,填写域名相关信息完成证书申请,中间需要根据提示填写域名验证信息:

填写完所有信息后,即可等待证书下发。下发后可进行重新签发、下载 SSL 证书等操作:

注意事项

用户可通过访问 DNSHE 官网,注册成为用户,然后按照提示绑定域名,完成 SSL 证书申请和安装。

每位注册的用户限领 3 个单域名证书。

证书有效期为一年,到期后可按需求续费或选择其它解决方案。

如有多个网站,可以将这些证书分别用于不同的域名。

  •  

图床审核出现误判解决方法

有小伙伴反馈在使用去不图床上传图片时,出现上传成功却提示图片的审核失败,还有一些正常图片被误判为违规等类似的情况发生。本文简单剖析出现的原因及问题解决方法。

数据流向

通过下图可以看到,当图片开始上传后,首先图床会将数据发送给审核 API 判定是否违规,如违规会反馈失败。反之则存放至节点,并返回外链的地址:

原因剖析

审核失败及误判的原因是 API 处理错误导致。通过日志反馈的信息可判断,是因图片格式标注错误导致审核失败。有小伙伴可能好奇,图片格式怎么还会标注错误?其实现在很多图片都是存放在类似 OSS 的存储空间中,这类服务会自动转换图片的格式,使其可以用更小的流量在网络中传输。而图床是根据文件后缀判断图片格式,如果实际格式和标注格式不一致,就会导致审核失败:

还有一个原因是不支持图片格式。虽然去不图床支持的图片格式有 JPEG/JPG/PNG/GIF/BMP/ICO/WEBP,但 API 仅支持 JPEG/JPG/PNG/GIF/BMP。杜老师已联系 API 的开发者建议支持新格式,期待可以尽快更新:

解决方法

除了前面的两个原因外,最直观的原因就是图片确实违规,这时可以针对图片进行修改,例如添加水印、区域截图等等,避免再次出现违规结果:

聊天广场中有小伙伴反馈过,可以尝试使用图片压缩工具进行处理,不仅可以减少图片大小,还可以提升审核成功及通过机率「暂未亲测」

工具地址

怕小伙伴们找不到趁手工具,杜老师找了款在线开源图片处理工具,访问下面的网址即可打开和使用。该工具类似 PS,支持中文界面:

下方的链接为在线开源图片批量压缩工具,最大支持 20 兆图片压缩,最多支持 10 张图片同时操作。可设置压缩的大小、质量、输出格式参数:

  •  

广州游记「多图预警」

今天杜老师要和大家分享的,是广州这座古老而又现代的城市,如何在忙碌的工作中找到属于自己的节奏和乐趣呢?就让杜老师在出差闲暇之余,拍摄几张景色与美食的图片,带小伙伴们领略广州的魅力!

广州之旅

广州,这座古老又现代的城市,总以它独特的方式,诉说着岁月的故事。

穿梭在高楼大厦间,感受广州现代气息。傍晚时走在珠江边,轻风拂过,仿佛能听到历史的低语。广州塔在风中静静伫立,见证着这座城市的变迁。

在白云山的绿意中,风带着清新的空气,让人心旷神怡。

广州不仅是一座历史与现代交融城市,更是美食天堂。

在广州早茶不仅仅是一顿饭,更是一种生活态度。一壶小茶,几笼点心,悠闲享受一个上午,这是广州人的日常。

虾饺、烧卖、肠粉,每口都是满满的幸福感。

走在上下九步行街,各种街头小吃让人目不暇接。牛杂、鱼蛋、糖水,每一口都是广州的味道。

在广州不能错过正宗的粤菜。从白切鸡到煲仔饭,从蒸鱼到烧鹅,每一道菜都是对食材和火候极致追求。

游记留影

飞机餐里的橙汁还是不错的,但面包和希腊酸奶有的一拼,都一样的噎人,脖子抻出去二里地才咽下去:

第一次品尝广州正宗的汤品,叫什么杜老师已经不记得了,只记得它很贵!贵的心碎:

具体的菜名忘记了,只知道雪花小牛肉确实不错,但是杜老师觉得它不值 199 这个价:

啫啫蚝烙,记住的原因是因为它好大一盘子,但是它好多油,能把人腻到的那种。味道无功无过:

煲仔饭也是无功无过的味道,总结,这是一顿失败的饭。而且!这是杜老师吃的第一家,热水还要收费的店!收了 18 块:

广州夜晚的江边很舒服,吹吹风仿佛收费的热水也随着风被吹走了。想起热水收费还是很气:

走了半天看到一个教堂,结果人家已经关门,只能站门外拍两张,如果不是杜老师眼神好,大晚上的很容易把这个教堂忽略,黑漆漆的还挺吓人:

从大门看,里面教堂黑漆漆的,这不比鬼屋啥的有氛围:

酒店的第一碗早餐,反正就是个粉:

杜老师没吃饱,再来碗面:

终于找到一家好吃的茶餐厅,纠结于吃饱还是灌一个水饱:

粥很好喝,但是又忘记它叫什么了:

豉汁山药排骨,清淡且保留食材的新鲜,味道不错:

强烈推荐这道,它没有那种内脏的臭味,全是百叶的脆爽感,吸饱了慢慢的汤汁,味道绝佳:

虾饺一绝,不过这边的菜量小,一份只有三个:

红米肠也是强烈推荐的,并且是店家的招牌,蘸着蘸料,米肠包裹内馅酥脆,虾肉紧实弹牙,蘸料又为它增加了一丝独特风味:

蛋挞不是特别甜的,口味适中,就是吃多了有点腻,杜老师吃一个就顶到了:

这边烧麦是肉馅的,味道清爽不腻。奈何是最后才上的,实在吃不下了:

饭后去永庆坊消食,窄窄的一条街,好多的人:

地图看着四通八达,逛了半天发现自己只逛了其中一条街,这个地方实在是太大了:

李小龙祖居感觉很新奇:

这是粤剧艺术博物馆的外面,景色很美:

前面拦着没法通过,好想看看有没有可乐桶那么大的鲤鱼:

有鱼,不过不大,不知道味道怎么样:

湖中央的戏台,开戏时间太晚,没有等到,只能拍了照以慰藉遗憾:

走出来啦,永庆坊的散步,买点手办结束此次出行:

  •  

上海游记「多图预警」

一到年底,工作量就特别的多,这次杜老师被安排上海出差,正好趁着机会,好好游玩一番!上海这座城市,不仅仅是繁华,更是充满了故事和风情。文中是杜老师工作之余拍的上海风情,一起感受这座城市的速度与温度!

上海之旅

清晨上海,从一碗热腾腾的生煎包开始。走在南京路上,看着忙碌人群,感受着这座城市的脉动。

午后,漫步外滩,黄浦江两岸建筑群让人目不暇接。东方明珠、上海中心大厦,每一座建筑都讲述着上海的故事。

当然,上海的美食也是不容错过的。从地道本帮菜到世界各地的佳肴,每一口都是对味蕾极致诱惑。

夜幕下的上海,更是别有一番风味。无论是在新天地小酒吧,还是在黄浦江上的游轮,都能体验到上海夜生活。

游记留影

脚丫子都疼了才走到的,传说中的——外滩:

路过一个名字很有趣的大学,很业余的大学,哈哈:

上海豫园,很漂亮的建筑风格,门前还有江爷爷的题字:

酒店早饭,鸡汤馄饨超级好吃,杜老师一个人能吃两碗:

没去之前以为武康大楼里边可以参观,去之后发现只能在大街边拍个照,搞笑的是大家都在街边拍照,乌泱泱的人群,堵得厉害:

路过教堂的随手拍,不知道里面是什么样子,不过外面看着挺漂亮的:

夜游黄浦江啦,码头入口找了半天,走的满身大汗:

虽然不是第一次坐游船,但这感觉还蛮兴奋,就是有点冷了:

同行的旅客都在关注着景色,杜老师就一个想法,这江风吹的好冷啊:

夜晚的东方明珠和白天的相比有中不一样的美:

杜老师住的地方距离这里比较远,不知道在这江的对面住一晚要多少钱:

这个游船开的速度,还没杜老师走的快:

  •  

感谢来自 hehe 童鞋的礼品

杜老师说运营至今,认识了很多小伙伴。除在评论区交流外,大家也会通过导航栏处「点我在线聊天」沟通。近期收到来自 hehe 童鞋的礼品,这是他的爱人经营一家网上手工店铺,里面有很多的手工艺品,推荐给喜欢的小伙伴们!

有关于 hehe

认识 hehe 童鞋是在今年的年初,因为架设网站时遇到了一些问题,选择杜老师的增值技术支持。

在问题解决后,又帮忙解决了几个小的问题,渐渐熟络起来。

有幸因为出差去了 hehe 童鞋所在的城市,但因为工作及天气原因没能线下面基。

杜老师对这位老哥的评价就是又菜又爱玩,想认识的小伙伴可以去聊天广场,没准就能逮到他了!

礼品展示

hehe 童鞋表示为感谢杜老师长期的技术支持,送了两个由其爱人亲手制作的工艺品:

杜老师在众多小玩偶中,选择了一个加菲猫和一个牛肉果:

加菲猫大一些,被杜老师的爱人抢走了,不知道挂在了哪里:

牛油果小一些,杜老师挂在了书包上面,希望可以耐脏一些:

礼品官网

除了上面图片中的玩偶,还有挂件、包包、摆件、盆栽、发卡、帽子:

官网截图

如果有喜欢的玩偶,可以打开上面官网,点击右上角关于我,添加页面中的聊天方式,沟通下单即可:

  •  

感谢来自开往项目组的礼品

前段时间突然收到来自开往项目负责人的私信,说为了表示对开往项目支持,会赠送一个小礼品。杜老师告知地址后,没过几天就收到了一个礼品,礼物虽小但情谊重,这里再次推荐一下开往项目!

项目介绍

开往 Travellings 是一个友链接力项目,旨在通过网络跳转方式将流量引入那些鲜为人知的独立站点,从而推动网络的开放性和多元性。

该项目于 2020 年 3 月 12 日诞生,灵感来源于开放的网络。其 Logo 由代表世界的星环和代表穿梭的列车组成,寓意在网络世界中穿梭。

每当用户访问加入开往 Travellings 网页时,点击该网页上的开往按钮将随机跳转到另一个加入该项目的网页。无论再次点击开往还是后退网页,都会继续随机跳转到其他参与者网页。

随着越来越多的网页选择加入开往 Travellings 行列,友链网络也在不断扩大,这将进一步推动分享流量的增长,为本项目注入更多活力。

礼品展示

刚打开快递盒,感觉非常惊喜,小小的礼品包装很精致,还添加了纸条防止邮递损坏:

打开里面的礼品盒,首先映入眼帘是一封感谢信,简单说明了开往负责人交替关系:

小礼品是一个亚克力材质的徽章,上面是开往 Logo,背面有别针可以挂在衣服上「其实弄个贴纸或冰箱贴会更好些」

徽章正面有个薄膜,开始杜老师不清楚,怎么拍就感觉模糊,撕掉后的效果还是很不错的:

聊聊项目

开往是个以跳转功能为主的友链接力项目,其名字开往取自开放的网络。

将开往放入您网页,表示乐于分享并支持开放的网络。

每当有人访问加入开往的网页时,点击开往会随机跳转到另一个加入开往的网页。

之后,再次点击网页的开往或后退网页,将继续随机跳转到另一个加入开往的网页。

我们希望这个项目能让友链接力下去,让更多的网页获得流量。站长也可以用开往互相交友。

所以博主间的互动,可以带来流量,及创作的热情。而开往项目就提供一个平台,方便博主之间随机跳转,认识新朋友的同时,也会给自身的博客带来流量,在这里也祝福该项目能越办越好!

项目地址

开往项目官网地址:

  •  

1Panel 专业版低价租用

越来越多小伙伴开始选择 1Panel 面板,1Panel 专业版提供的 WAF 和网站监控报表等功能非常好用。不过官方已经不再提供永久版的购买渠道,目前只能按年订阅。杜老师这边囤积了几个专业版激活码,现提供低价格租用服务。

功能列表

以下是社区版和专业版通用功能:

  • 应用商店
  • 网站管理
  • 多种类数据库管理
  • 容器管理
  • 文件管理
  • 主机性能状态监控
  • 网页终端
  • 防火墙及端口转发
  • 进程管理
  • 远程连接管理
  • 计划任务
  • 日志审计

以下是专业版特有功能:

  • WAF 防火墙
  • 网站防止篡改
  • 自定义 Logo
  • 显卡监控
  • 网站监控报表
  • 定制主题配色
  • 内网代理模式
  • 定时病毒扫描

界面效果

激活专业版后,点击左侧面板设置,可看到主题颜色会多出一个自定义项:

如果激活专业版后,发现左侧没有高级功能,可以前往面板设置,找到高级功能菜单隐藏,将所需功能项设置显示即可:

租用价格

下面截图来自官网,可以看到官方的价格是每年 360 元,杜老师这边价格是 90 元一年:

杜老师收到支付款项后,会通过邮件或者聊天私信发送专业版激活文件,点击右上角升级专业版,上传激活文件即可:

租用规则

  1. 点击文章下方的给作者一杯咖啡,根据喜好选择支付宝或微信支付,金额 90 元,备注「1Panel 专业版」即可;

  2. 可通过邮件或者聊天广场私信杜老师,发送支付截图。杜老师收到后,会通过邮件或者聊天私信发送专业版激活文件,点击右上角升级专业版,上传激活文件即可;

  3. 激活码有效期 365 天,到期后会自动失效。期间可以随时按月退费,最终解释权归杜老师说所有;

  4. 激活码的数量有限,目前还剩四份名额「该信息会实时更新」

  •  

WAFPRO 防御加速 CDN 新版上线

上篇文章有小伙伴评论说无畏云没有限值,如果遇到被刷流量情况,很有可能会进入黑名单。本次为小伙伴们推荐的 WAFPRO 防御加速 CDN,其使用了流量包月机制,到达流量后即停止服务,防止额度欠费。

介绍

WAFPRO 防御加速 CDN 是一个基于云网站安全防护解决方案,通过 WAFPRO 防御加速 CDN,可以保护网站免受各种攻击。

包括跨站请求伪造、拒绝服务攻击、跨站脚本攻击。

价格

目前套餐价格如下:

套餐流量带宽月价季价年价
个人月 100GB20Mbps39 元88 元299 元
基础月 500GB30Mbps109 元320 元1090 元
标准日 3000GB50Mbps399 元1190 元3999 元
专业日 12000GB100Mbps998 元2900 元9888 元
标准日 45000GB300Mbps2999 元8990 元29999 元

WAFPRO 个人版年付优惠计划,原价基础优惠 200 元,现价 99 元,购买时填入下面优惠码:

wafprovip

官网

WAFPRO 有新旧两个版本,旧版本使用较复杂,这里提供新版本的官网链接:

截图

打开官网并登录后,可以看到网站概览,包括带宽、流量、请求数等信息:

WAFPRO 与后付费 CDN 不同,其使用流量套餐包月制,不会出现额度透支情况。对于不确定使用量,及经常被攻击的小伙伴,WAFPRO 是很不错的选择:

  •  

无畏云 CDN 加速免费依旧

在数字化时代,网站的访问速度和稳定性对用户体验至关重要,无畏云 CDN 正是针对这一需求而生,为广大站长提供高效且免费的 CDN 加速服务。本文将介绍无畏云 CDN 的功能、优势及在实际中的应用效果。

平台介绍

无畏云 CDN 是一家融合 CDN 的解决方案提供商,通过整合华为、阿里、火山和 AWS 等顶级厂商的资源,构建一个强大而稳定的节点网络。

无畏云 CDN 在全球范围内拥有几百个节点 IP,覆盖六大洲的主要区域,确保用户无论身在何处,都能享受到快速稳定的访问体验。

功能优势

无畏云 CDN 给予新注册用户每月 30GB 免费流量,这对于小型网站和个人博客来说无疑是一个巨大的福利大大减轻了流量费用的负担。

无畏云 CDN 利用融合的 CDN 技术,实现全球范围内的节点覆盖,这意味着用户的最终访问请求总能被引导至最近的节点,从而显著提高访问速度和稳定性。

无畏云 CDN 后端主要采用华为、阿里、火山和 AWS 基础设施,这些厂商在可靠性和性能上都有着极高的声誉,通过这样合作,无畏云 CDN 能够为用户提供 99.9%服务质量保障。

无畏云 CDN 提供一键开启 HTTPS 和 IPv6 的功能,使得用户可方便地提升网站的安全性和兼容性,控制面板设计简洁直观,即使是初学者也能轻松上手。

官网地址

已经恢复正常使用的无畏云官网:

平台截图

需要注意的是,无畏云使用境内的节点,这意味着用户需要实名验证,且域名需备案才可正常访问:

如果赠送流量不够,也可以购买流量包。支持自选流量包大小及有效时长,价格相比市面的 CDN 便宜很多:

  •  

新版本不蒜子统计平台使用说明

杜老师不蒜子统计平台运营至今,经过星辰童鞋版本迭代,增加了很多新功能。更为值得称赞的是,版本升级并没有 BREAKING CHANGE,新版本仍兼容旧版本的调用脚本。使用旧版本的小伙伴不升级脚本也可继续使用!

再次感谢

再次特别感谢星辰童鞋,杜老师自建的国内不蒜子统计平台使用的就是他的开源代码,并且在测试过程中,提供了大量的帮助。

通过 Golang+Redis 实现模仿不蒜子统计功能;UV 通过 IP+UA 统计,PV 通过 Referer 区分。

服务器的配置为 2H4G,下行带宽为 100M,上行为 5M。

主机位于北京,所有流量走境内 CDN。

食用方法

如果是 Volantis 主题:

1
2
3
4
############################# Analytics ############################# > start
analytics:
busuanzi: https://npm.onmicrosoft.cn/penndu@16.0.0/bsz.js # 修改这里即可
############################# Analytics ############################# > end

如果非 Volantis 主题:

1
2
3
4
5
<script defer src="https://npm.onmicrosoft.cn/penndu@16.0.0/bsz.js"></script>
本文总阅读量 <span id="busuanzi_page_pv"></span>
本文总访客量 <span id="busuanzi_page_uv"></span>
本站总访问量 <span id="busuanzi_site_pv"></span>
本站总访客数 <span id="busuanzi_site_uv"></span>

如果是 Butterfly 主题,需修改文件 layout/includes/additional-js.pug,位于 72 行左右:

1
script(async data-pjax src='//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js')

改为:

1
script(async data-pjax src='//npm.onmicrosoft.cn/penndu@16.0.0/bsz.js')

可选参数

在非 Volantis 主题使用方法基础上,可以添加如下参数:

属性默认阈值释义
data-apihttps://bsz.dusays.com:9001/api不蒜子 API 地址
pjaxfalse是否监听 Pjax 的变化
data-prefixbusuanzi标签前缀

使用示例

在一些启用了 Pjax 技术的网站, 可以在 js 标签中加入 Pjax 属性, 来实现当网站切换页面时自动更新页面计数的效果:

1
<script defer pjax src="https://npm.onmicrosoft.cn/penndu@16.0.0/bsz.js"></script>

可使用 data-api 属性, 指定后端 API 的接口:

1
<script defer data-api="https://bsz.dusays.com:9001/api" src="https://npm.onmicrosoft.cn/penndu@16.0.0/bsz.js"></script>

可使用 data-style 属性, 指定数据的显示样式。默认显示完整数据,short 显示短形式, 如 1024 显示为 1k;comma 以逗号分隔数据, 如 1024 显示为 1,024:

1
<script defer data-style="short" src="https://npm.onmicrosoft.cn/penndu@16.0.0/bsz.js"></script>

不同于原版本, 为了更加精简去除了 value 字符, 仍然可以通过指定 data-prefix 属性来进行兼容:

1
<script defer data-prefix="busuanzi_value" src="https://npm.onmicrosoft.cn/penndu@16.0.0/bsz.js"></script>
  •  

开启 OpenResty 的 QUIC 支持

QUIC 是种基于 UDP 实现的传输层协议,由 Google 提出,旨在减少握手延迟,实现快速连接建立、多路复用、连接迁移功能。本教程分享如何在 OpenResty 开启 QUIC 支持。

准备工作

确保已经成功安装了 OpenResty。如果看到 OpenResty 的欢迎页面,说明安装成功。

OpenResty 通过集成 Nginx 并利用其模块化特性支持 QUIC。需要在 Nginx 配置文件中启用 QUIC 支持。通常涉及到配置监听 UDP 端口,因为 QUIC 运行在 UDP 上。

OpenResty 从 1.25 版本开始支持 QUIC,如果是之前的版本,需要自行编译安装模块以支持 QUIC。

使用支持 QUIC 的客户端工具测试 QUIC 连接是否成功建立。

监听端口

对于每个站点,需在 Nginx 配置文件中为 QUIC 配置监听端口。由于 QUIC 运行在 UDP 上,需为每个站点配置一个监听 UDP 端口的指令。例如,如果有两个站点 site1site2,可以这样配置:

1
2
3
4
5
server {
listen 443 quic reuseport;
server_name site1.dusays.com;
# site1 的其它配置...
}

这里的 443444 是用于 QUIC 的 UDP 端口,quic 指定 QUIC 协议,reuseport 是为了提高性能:

1
2
3
4
5
server {
listen 444 quic reuseport;
server_name site2.dusays.com;
# site2 的其它配置...
}

端口复用

如果在一台服务器包含多个网站,其中一个网站添加 reuseport 参数后,则其它网站无法再次添加 reuseport 参数:

1
2
3
4
5
server {
listen 443 quic reuseport;
server_name site1.dusays.com;
# site1 的 QUIC 加密和伪装配置...
}

多次添加 reuseport 参数会提示端口冲突,这时可以删除其中的 reuseport 参数,或者使用不同的 UDP 端口。例如:

1
2
3
4
5
server {
listen 443 quic;
server_name site2.dusays.com;
# site2 的 QUIC 加密和伪装配置...
}

测试连接

使用支持 QUIC 客户端工具测试每个站点的 QUIC 连接是否成功建立,这可以帮助验证服务器端的配置是否正确:

  •  

推荐一款文字修仙摸鱼页游

博文拖更好久,不知道发点什么好。刚好在 GitHub 上发现一款有趣的文字修仙网页游戏,可以直接托管在 Vercel,也可架设在个人服务器。杜老师已经部署好,欢迎小伙伴们前来体验!

游戏截图

游戏页面清爽直接,小伙伴们可以通过点击文字进行交互,部分选项标有注释,通过点击即可获取提示信息:

游戏方法

首先领取新手礼包,礼包的装备可刷新,装备的级别从大到小分别是天地玄黄。

装备好后,即可开始修练。

到一定级别后,需要探索秘境刷一定数量怪,才可继续修炼。

剩下的就请小伙伴们自行探索了!

在线摸鱼

如果感觉在页面中操作不便「该页面中无法使用右键」点击 这里 在独立页面中打开游戏:

注意事项

游戏数据存于浏览器本地缓存中,杜老师说不会保留任何用户数据,也请大家做好数据备份,避免因缓存清理等原因丢失游戏记录。

如需备份可以点击页面下方游戏设置——导出存档,再次导入即可恢复进度。

  •  

终端美化工具 X-CMD 安装与使用

X-CMD 是一款强大的终端美化和功能增强工具,它通过模块化设计和集成的包管理器,为用户提供丰富的功能和便捷的使用体验。无论是日常的命令行操作还是开发环境的搭建,X-CMD 都能提供有效的支持。

概述

X-CMD 是一款开源轻量级 POSIX 脚本工具,集成了 500+语言、工具,不需要 root 权限即可使用,提供了原生命令的增强以及现代化的命令行界面 TUI。

本文将详细介绍 X-CMD 安装、基本使用及一些专业术语和功能特性。

安装

X-CMD 支持在主流 POSIX shell 系统环境下运行,包括 bash/zsh 等。以下是在 Linux 系统的安装步骤,打开终端,输入以下命令之一来安装 X-CMD:

1
eval "$(curl https://get.x-cmd.com)"

或使用 wget,这将下载并执行 X-CMD 安装脚本,自动配置环境变量,使得 X-CMD 命令在任何新终端会话中可用:

1
eval "$(wget -O- https://get.x-cmd.com)"

使用

X-CMD 自带的包管理器 x pkg 可以快速安装并管理脚本引擎,例如 Node.js/Python 等。例如,安装并切换 Node.js 版本,使用下面命令安装并切换到指定版本的 Node.js:

1
2
x env use node=v20.11.1
node -v

支持快速执行代码,如 Python 和 Node.js,下面命令允许用户在不安装语言环境的情况下直接运行脚本:

1
2
x python -c 'print("hello x-cmd")'
x node -e 'console.log("hello x-cmd")'

示例

执行 x theme 后,可以预览每个主题在当前终端的显示情况:

增强版 ls 命令,可更方便地查看文件信息和系统信息:

查看进程,交互式查看 ps 数据:

该模块是使用 POSIX shell、awkfind 实现的增强版 cd 命令:

增强版 stat 命令,以 TUI 方式查看当前路径下所有文件的详细信息:

X-CMD 处理 PATH 变量,交互展示当前环境中 PATH 内二进制搜索目录:

增强型 docker 命令:

X-CMD 增强 git 命令:

  •  

PM2 安装与使用

在现代的软件开发和系统管理中,进程管理是一个不可或缺的部分。PM2 作为一个强大的进程管理工具,它可以帮助我们管理和保持应用在线状态,自动重启崩溃应用,并提供负载均衡等高级功能。

主要特点

  • 自动重启:应用崩溃时会自动重启。

  • 负载均衡:在多个实例间分配负载。

  • 集群模式:在所有的 CPU 核心上运行应用。

  • 日志管理:实时日志查看和日志持久化。

  • 监控:实时监控应用资源使用情况。

  • 远程管理:通过 API 或者仪表板远程管理应用。

PM2 的安装

PM2 可以通过 npm 命令轻松安装。如果系统暂未安装相关命令,则执行下面的命令「这里以 Ubuntu 系统为例」

1
sudo apt -y install npm

然后在命令行中运行以下命令即可安装 PM2:

1
npm install pm2 -g

PM2 的使用

要使用 PM2 启动一个应用,可使用 start 命令。例如,如果有一个名为 app.js 的 Node.js 应用,可以这样启动。PM2 会启动应用,并在后台运行:

1
pm2 start api.js

重新启动应用程序:

1
pm2 restart api

重新启动所有应用程序:

1
pm2 restart all

重新启动多个应用程序:

1
pm2 restart app1 app2 app3

停止指定应用程序:

1
pm2 stop api

停止所有:

1
pm2 stop all

删除应用程序:

1
pm2 delete api

删除全部:

1
pm2 delete all

使用 list 命令可以查看所有由 PM2 管理应用的状态,这将显示所有应用的 ID、名称、模式、内存使用情况信息:

1
pm2 list

PM2 提供了实时日志查看功能,使用 logs 命令将显示所有应用的实时日志流:

1
pm2 logs

使用下面命令可重启所有由 PM2 管理的进程,可实现零停机重启:

1
pm2 reload all

输入下面命令来保存当前的进程列表,确保在重启后自动加载这些进程:

1
pm2 save

使用下面命令设置开机自启:

1
pm2 startup

使用下面命令取消开机自启:

1
pm2 unstartup

PM2 的命令

PM2 提供了丰富的命令行工具,用于管理应用程序。以下是一些常用的命令:

命令描述
start启动一个应用程序
stop停止一个应用程序
restart重启一个应用程序
delete删除一个应用程序
list列出所有应用程序
monit监控应用程序
dump导出应用程序的配置
reload重新加载应用程序
sendSignal发送信号给应用程序
update更新应用程序

PM2 提供了一种监听应用程序资源使用情况简单方法。可以使用命令 pm2 monit 从终端轻松监听内存和 CPU:

  •  

哪吒监控开源、轻量、易用的服务器监控

一天在聊天广场中分享了服务器监控截图,obaby 说感觉不错,想知道如何部署的。杜老师当时拍着 36A 的胸脯郑重承诺当天晚上会发表。然后……就没有然后了!但人不能言而无信,博客不能拖而不更,它来了它来了,它带着忏悔走来了!

工具特点

支持一键安装面板、监控服务,操作便捷。兼容主流系统,包括 Linux 等。

支持同时监控多个服务器的状态,提供历史网络状态、延迟图表,监控网页、端口可用性以及 SSL 证书状态。

支持故障和流量等状态告警,可通过 Telegram、邮件和微信等多种方式提醒。

提供 API 获取服务器状态,支持 WebSSH 和 DDNS 及流量监控。可设置定时和触发任务,并批量执行服务器任务。

服务端的部署

在面板服务器,运行安装脚本:

1
curl -L https://raw.githubusercontent.com/nezhahq/scripts/main/install.sh -o nezha.sh && chmod +x nezha.sh && sudo ./nezha.sh

如面板服务器位于中国大陆,可以使用镜像:

1
curl -L https://gitee.com/naibahq/scripts/raw/main/install.sh -o nezha.sh && chmod +x nezha.sh && sudo CN=true ./nezha.sh

等待 Docker 安装完毕后,根据实际的情况分别输入以下值:

1
2
3
4
5
6
7
OAuth 提供商
Client ID
Client Secret
用户昵称
站点标题
访问端口
Agent 的通信端口

安装结束后如一切正常,此时可以访问 IP+端口号查看面板:

1
http://IP:8008

客户端的安装

哪吒监控的被控端服务被称为 Agent,这里主要讲解如何在 Linux 中安装 Agent「支持大部分发行版」首先在管理面板添加一台服务器,然后在被控服务器中运行下面的脚本:

1
curl -L https://raw.githubusercontent.com/nezhahq/scripts/main/install.sh -o nezha.sh && chmod +x nezha.sh && sudo ./nezha.sh

如被控服务器位于中国大陆,可以使用镜像:

1
curl -L https://gitee.com/naibahq/scripts/raw/main/install.sh -o nezha.sh && chmod +x nezha.sh && sudo CN=true ./nezha.sh

脚本运行后选择安装监控 Agent,输入服务端的通信 IP 或者域名如:

1
nezha.dusays.com

输入服务端的通信端口,默认如下。之后再输入 Agent 密钥,Agent 密钥在管理面板添加服务器时生成,可以在管理面板中的服务器页中找到:

1
5555

效果展示

支持实时监控多台主机运行情况,含 CPU、内存、硬盘、网络、负载、进程等等:

可对各项服务状态进行监控,包括端口、网页、SSL 等:

可监控各主机网络状态,查看延迟:

支持多款主题切换,支持日间、夜间模式切换:

  •  

PCDN 和近期网络攻击频繁的那些事

前段时间接到父母电话,说有自称宽带运营商的工作人员上门检查。父母的安全意识还是很好的,担心会动手脚,人家还没进门,电话就过来了。这让杜老师想起 PCDN 事件,今日整理相关内容,给小伙伴们普及下!

什么是 PCDN

PCDN 或 P2P 是一种基于 P2P 技术和 CDN 的内容分发加速网络。它通过在网络中添加大量的低成本缓存服务器,将用户请求的内容从原始服务器分发到这些缓存服务器,从而实现内容更快、更稳定传输到终端用户。

随着网络技术发展,我们对大带宽的需求也不断增长。各大站群为了用户访问体验,通过 CDN 将用户的请求直接发送到用户所在城市的服务器,从而实现快速、稳定访问。

在内容分发网络服务领域业界普遍采用两种主流的计费模式:流量计费、带宽计费。无论选择哪种计费方式,随着流量的增加其运营成本相应上升,对于任何规模的网站都是一个不容忽视的经济压力。

大型网站由于其庞大的用户基础和高流量需求,对 CDN 服务的依赖则更为显著,因此成本控制成为其运营中关键环节。在这样背景下,一些领先的技术公司开始探索利用家庭宽带资源以优化成本结构。家庭宽带通常有较高的下行速率,而上行速率则相对较低,且普通用户往往未能充分利用其上行带宽。

为更高效地利用这些未被充分利用的上行带宽资源,一些企业推出了挂机宝。这类服务通过在用户设备上部署特定软件,利用用户的闲置带宽进行数据缓存和存储。在需要时,这些数据可以通过用户的家庭网络传输给其他的需求方,从而在减轻大型网站 CDN 负载同时,也为用户带来一定激励回报。

这种模式不仅有效降低了大型网站对传统 CDN 节点的依赖,降低运营成本,而且在经济上对用户也具有一定的吸引力。尽管需要向用户提供一定的激励,但与高昂的 CDN 节点带宽费用相比,这种成本节约是显著的。通过这种方式,企业能够以较低的成本扩展其 CDN 网络,同时为用户提供了一种将闲置资源变现的途径,实现了双方的共赢。

运营商限制 PCDN 原因主要

网络压力:PCDN 产生的海量流量对运营商的骨干传输网络形成了巨大压力。由于用户宽带通常是包月的,而不是按流量计费,因此用户使用越多,运营商网络的压力越大,而且运营商并不能因此收到更多费用。

盈利影响:视频类服务商搭建常规 CDN 服务节点需要租用运营商的高价机房和带宽。而用 PCDN 后,服务商对资源租用需求大幅减少,这直接影响了运营商的盈利。

安全风险:PCDN 节点与其它设备存在数据交互,可能导致隐私数据泄露,甚至产生安全漏洞,遭到恶意攻击。

成本问题:PCDN 业务会导致设备长期开启,增加电能浪费,影响硬盘寿命,甚至整个设备寿命。

PCDN 节点的排查逻辑

运营商对 PCDN 的打击已经产生了扩大化影响。一些地方运营商的政策更加激进,如全面回收 IPv6 地址、限制网络连接数量、网络类型改为 NAT4 等。

运营商需要对网络流量进行监控,区分正常上行流量和 PCDN 流量。这无疑又增加了人力和物力成本,所以大多数运营商都选择封杀 PCDN。

在现代互联网架构中运营商通过精细化的流量数据分析技术,对用户的网络行为进行深入洞察。特别是对上行和下行流量的对比分析,已经成为识别 PCDN 行为的关键指标之一。

普通用户在互联网中主要扮演资源获取者的角色而非资源提供者。因此,从流量分布的一般规律来看,用户的下行流量通常会显著高于上行流量。

这种流量分布的不对称性是家庭宽带非对称带宽特性的直接体现。所谓的非对称带宽,是指在数据传输过程中,上行和下行的带宽速率存在差异,通常情况下下行带宽会高于上行带宽,以适应用户更多下载而非上传的需求。

然而,在特定情况下,如果监测到用户的上行流量异常高甚至超过了下行流量,亦或者上行流量与下行流量的比例超出了正常阈值,这可能表明用户正在作为资源提供方参与到 PCDN 活动。PCDN 利用普通用户的闲置资源,通过 P2P 技术实现内容的分发,这在一定程度上改变了传统上下行流量的分布比例。

近期网络攻击频繁猜想

所谓,上有政策,下有对策。PCDN 服务商面对这种筛查机制,也有其应对的方法「以下内容是杜老师对近期网络攻击频繁的猜想,信息来自于互联网」

上面提到筛查的规则是判断上下行流量的比例,所以一些 PCDN 服务商开始使用刷流量的方式躲避筛查。

他们会在闲时「一般指午夜后」下发指令给 PCDN 设备,使其访问互联网的部分站点,来获得大量的下行流量。

很多博主反馈自己网站在后半夜会有短暂的高流量访问,很有可能就是因为 PCDN 刷流量导致。

面对这种情况,杜老师采用的方式就是根据时段限制流量,如闲时段可以限制带宽,或者流量上限。如触发后及时中断流量,避免因流量造成的资金损失。

最后补充一句,除 PCDN 之外,部分运营商对 PT 的政策也开始收紧了。杜老师的想法非常简单:要么别给那么高的带宽,既然给了,就不要限制我们的使用!

  •  

FAST OS DOCKER 容器管理器的安装与使用

今天给小伙伴们分享一款来自于国人大佬开发的一款 Docker 的图形化管理工具,原生中文支持,拥有 Portainer 的大多功能,且界面更简洁好看,适合国人审美。

工具简介

FAST OS DOCKER 和 Portainer 差不多,是一款 Docker 的图形化管理工具。

可为用户提供总览、本地容器管理、远程镜像拉取、主机磁盘映射、服务器网络管理等功能,基本能满足中小型单位对容器管理的全部需求。

工具优点

无需复杂命令,全图形化操作,基本上只需要懂一点点的 Docker 常识就能轻松构建容器。

界面直观简洁,对应功能也是一目了然,那怕新手小白也能快速上手。

FAST OS DOCKER 的后端语言是 Go,前端框架是 Vue,且拥有全面的权限管理机制。

为防止服务器负载过高,进行底层性能优化,较适合 NAS 这种入门级服务器部署安装。且集成 Docker 镜像应用市场,可直接快速安装和部署。

安装步骤

连接服务器后,切换至 root 权限,运行如下命令:

1
2
3
4
docker run --name fastos \
--restart always -p 8081:8081 -p 8082:8082 -e TZ="Asia/Shanghai" -d \
-v /var/run/docker.sock:/var/run/docker.sock -v /etc/docker/:/etc/docker/ \
-v /root/data:/fast/data -e FAST_STORE=http://8.210.124.47:8080 wangbinxingkong/fast:latest

安装完成后在浏览器访问 http://IP:8081。首次登录需要注册,注册成功即可正常使用:

简易教程

主机 Docker 情况总览页,查看硬件配置,Docker 文件安装根目录,主机系统,容器数量,镜像数量,数据卷以及网络环境等配置:

可在镜像菜单处理镜像相关操作:

选择默认简单模式,输入镜像名可拉取镜像:

也可选择高级模式,输入 fromImage=php:7.3.5-fpm&fromSrc=daocloud.io/library/nginx:1.17.8 类似格式字符可拉取镜像:

或者选择搜索模式,搜索后再拉取:

进入数据卷菜单页,删除或添加数据卷:

进入网络菜单,设置网络,添加网络:

进入容器菜单,可实现对容器的增删查改等操作,还可查看日志,监控容器,控制台连接容器等:

进入登记菜单,可以登记第三方私人镜像库,登记后可拉取私人仓库镜像:

进入集群菜单,可连接其它服务器,操作其它服务器的容器,镜像:

  •  

群晖 NAS 删除重复文件的两种方法

因工作需求要录制大量教学视频,杜老师的 4K 屏使得录制的视频文件大小会很大,想转存至 NAS 时,发现 NAS 已出现空间告警。通过存储分析发现 NAS 上有大量的重复文件,故此分享两种删除重复文件方法。

使用存储空间分析器删除重复的文件

首先进入到存储空间分析器套件,找到下方报告,点击立即分析报告:

稍等一段时间后会出现报告,即可点击右侧的箭头查看报告:

在报告页面的左侧选择重复文件,如果有多个共享文件夹,可通过筛选分别显示各个目录的重复文件:

如果担心有误删的情况,可以点击操作选择对所有的文件执行细微比较。之后就可以根据颜色来区分组别,勾选需要删除的文件就行了:

使用 Duplicate Cleaner Pro 删除重复的文件

存储空间分析器的删除方式比较麻烦,因为不能快速选择,且每次分析的重复文件数有限制。可通过第三方工具,如 Duplicate Cleaner Pro 删除重复文件。首先设置搜索规则:

接着设置扫描位置,可通过 SMB 协议挂载需查重的目录,添加到右侧的查重列表:

Duplicate Cleaner Pro 可扫描所有重复文件,并可快速选择重复文件:

在删除标签页选择删除模式,点击删除文件即可:

  •  

去不图床五周年蹭风 618 活动

不知不觉,去不图床即将运营了五周年「周年日 10 月 28」期间做过一些价格调整「大幅降价」但从未做过任何的活动,自杜老师自建 CDN 后,流量成本得到保障,虽依然有亏损,但不影响持续运营,今蹭风 618 开展优惠活动,感谢小伙伴们对去不图床的支持与活动的积极参与!

写在前面

去不图床从 2019 年 10 月 28 日始至今年即将满五年,期间由免费转为按量付费的图床。

相比其它平台高额的包月费,去不图床始终保持低价、年费、稳定、安全及高速等优势,广受博客圈小伙伴们支持与选择。

然而即便如此,去不图床依旧入不敷出,高昂的流量费是收入无法填补的。

好在今年杜老师开始自建 CDN,保障了流量费用的支出,虽然节点运营成本依旧高昂且超过了收入,但也减少了杜老师运营压力。

杜老师提供图床服务的初衷就是:为广大博客主提供低价、稳定、安全、高速图床服务,让博客主可以专注创作,而不是费心在管理图床。

去不图床从未做过推广、宣传,故此借助 618 这一风,开展优惠活动,感谢小伙伴们对去不图床的支持与活动的积极参与。不忘初心,方能始终!

活动规则

  1. 优惠活动限 2024 年 6 月 14 日 00:00:00 至 2024 年 10 月 28 日 23:59:59 期间;

  2. 优惠活动期间购买的兑换码,可在任意时间兑换;

  3. 优惠活动期间购买的兑换码,有效期至杜老师临终日;

  4. 如有小伙伴大量囤积兑换码,在未兑换之前,可以随时申请退款「每一个兑换码都会由支付宝收取一元的手续费」

  5. 优惠活动期间,仅限选购 5G 套餐可享受八折「24元」优惠,其它套餐皆不享受优惠;

  6. 优惠活动期间选购的 5G 套餐在当前套餐到期后生效;

  7. 优惠活动期间选购的 5G 套餐无法折算其它套餐;

  8. 最终解释权归去不图床所有。

图床架构

去不图床目前使用 16H32G 的配置,图床程序及缩略图存储在 512NVMe,图片数据存储在 1T 三星企业级 SSD,并周期同步至内网 RAID1 存储节点中。保障图床的安全性及稳定性:

杜老师自建 CDN 节点,所选节点皆为 8H8G 高配置,且上行带宽 30M,保障外链服务的高速性。目前暂为 9 个节点,其中境内 8 个,境外「上行千兆」 1 个:

写在最后

未来不知如何,图床前途未卜!

但杜老师会始终秉持着初心,为小伙伴提供低价且稳定的图床外链服务。

后面是否会有相似活动尚未可知,不过希望大家继续关注去不图床,期待更多小伙伴的参与!

图床容量兑换教程请见《去不图床容量兑换》一文,图床相关使用教程请见《去不图床新版升级计划》一文。

  •  

DockerUI 容器管理器的安装与使用

本教程给大家带来 DockerUI 的部署方法,通过 DockerUI 我们可以很方便的创建高权限的 Docker 应用,或者随时将配置文件目录挂载到我们的容器中,再通过容器终端去修改配置文件,只要一直保留 DockerUI 不删除,则完全没有后顾之忧了。

介绍

DockerUI 是一个易于使用且轻量级的 docker 管理工具。通过 Web 界面的操作,它方便不熟悉 Docker 指令的用户更快地进入 Docker 世界。

DockerUI 具有易于使用的界面。它不需记住 Docker 指令。只需下载镜像即可完成部署。根据 Docker 的功能,镜像的版本可以直接在 DockerUI 中更新。使用相同设置,可通过重新部署和替换容器,且可以使用最新版本的功能。

DockerUI 覆盖了绝大多数命令功能。通过可视化操作功能在 DockerUI 接口中提供 Docker 环境和 Swarm 管理和维护功能,可以很容易地执行集群环境。

DockerUI 是用于 Docker 容器映像可视化图形管理工具。Dockerui 可用于轻松构建、管理并维护 Docker 环境。它是完全开源和免费的。基于容器安装方法,可实现方便高效的部署。

安装

启动容器「如本地无镜像,则会自动拉取」并映射 8999 端口:

1
docker container run --rm --name docker.ui -v /var/run/docker.sock:/var/run/docker.sock -p 8999:8999 joinsunsoft/docker.ui

容器启动后访问 http://localhost:8999 即可,默认用户名和密码为 dockerui

截图

主页:

镜像列表:

搜索存储库及拉取镜像:

构建镜像:

导出/导入镜像:

推送镜像:

启用映像:

容器列表:

Web 控制台:

容器文件系统:

容器统计:

列出容器进程:

从容器中导出文件:

网络管理:

Swarm 集群管理器:

创建服务:

任务管理:

任务列表:

注意

本教程绿联和群晖同样适用,但是 DockerUI 作者已经不再维护了,所以可以选择《Potainer 容器管理器的安装与使用

DockerUI 虽不再维护,但只是作为一个高权限 Docker 部署或者配置文件目录挂载使用的话已经绰绰有余了。

  •  

to do 工具 Vikunja 的安装与使用

应 LongHe 童靴需求,杜老师更新一篇 to do 开源工具 Vikunja 的安装与使用。本来是四月份应该更新,结果因为各种出差各种事情给耽误了,最后还给忘了~还好回访时看到了自己留言,趁空发出来供需要的小伙伴参考!

特性

  1. 列表视图类似待办事项列表、展示任务、其他属性;

  2. 甘特图可规划截止日期;

  3. 看板可组织任务以及确定优先级;

  4. 表格视图可以查看任务详细信息,标记任务;

  5. 可创建过滤器;

  6. 可确定任务优先级,分配任务;

  7. 可附加文件及关联不同任务;

  8. 可设置截止日期及通过链接共享项目。

部署

Vikunja 支持很多种安装方式,作为 Docker 的忠实用户,杜老师分享四个 docker-compose.yml 配置文件,区别是所使用的数据库不同,以下是 MariaDB 作为数据库的配置文件:

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
version: '3'

services:
vikunja:
image: vikunja/vikunja
environment:
VIKUNJA_SERVICE_PUBLICURL: http://<the public url where vikunja is reachable>
VIKUNJA_DATABASE_HOST: db
VIKUNJA_DATABASE_PASSWORD: changeme
VIKUNJA_DATABASE_TYPE: mysql
VIKUNJA_DATABASE_USER: vikunja
VIKUNJA_DATABASE_DATABASE: vikunja
VIKUNJA_SERVICE_JWTSECRET: <a super secure random secret>
ports:
- 3456:3456
volumes:
- ./files:/app/vikunja/files
depends_on:
db:
condition: service_healthy
restart: unless-stopped
db:
image: mariadb:10
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
environment:
MYSQL_ROOT_PASSWORD: supersecret
MYSQL_USER: vikunja
MYSQL_PASSWORD: changeme
MYSQL_DATABASE: vikunja
volumes:
- ./db:/var/lib/mysql
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h localhost -u $$MYSQL_USER --password=$$MYSQL_PASSWORD"]
interval: 2s
start_period: 30s

以下是 PostgreSQL 作为数据库的配置文件:

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
version: '3'

services:
vikunja:
image: vikunja/vikunja
environment:
VIKUNJA_SERVICE_PUBLICURL: http://<the public url where vikunja is reachable>
VIKUNJA_DATABASE_HOST: db
VIKUNJA_DATABASE_PASSWORD: changeme
VIKUNJA_DATABASE_TYPE: postgres
VIKUNJA_DATABASE_USER: vikunja
VIKUNJA_DATABASE_DATABASE: vikunja
VIKUNJA_SERVICE_JWTSECRET: <a super secure random secret>
ports:
- 3456:3456
volumes:
- ./files:/app/vikunja/files
depends_on:
db:
condition: service_healthy
restart: unless-stopped
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: changeme
POSTGRES_USER: vikunja
volumes:
- ./db:/var/lib/postgresql/data
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -h localhost -U $$POSTGRES_USER"]
interval: 2s

如果仅是个人使用,没有那么大数据量,可考虑使用 SQLite:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
vikunja:
image: vikunja/vikunja
environment:
VIKUNJA_SERVICE_JWTSECRET: <a super secure random secret>
VIKUNJA_SERVICE_PUBLICURL: http://<your public frontend url with slash>/
# Note the default path is /app/vikunja/vikunja.db.
# This config variable moves it to a different folder so you can use a volume and
# store the database file outside the container so state is persisted even if the container is destroyed.
VIKUNJA_DATABASE_PATH: /db/vikunja.db
ports:
- 3456:3456
volumes:
- ./files:/app/vikunja/files
- ./db:/db
restart: unless-stopped

Vikunja 支持将数据存放在 Redis,配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
version: '3'

services:
vikunja:
image: vikunja/vikunja
environment:
VIKUNJA_REDIS_ENABLED: 1
VIKUNJA_REDIS_HOST: 'redis:6379'
VIKUNJA_CACHE_ENABLED: 1
VIKUNJA_CACHE_TYPE: redis
volumes:
- ./files:/app/vikunja/files
redis:
image: redis

截图

Vikunja 的默认主页:

使用列表模式展示任务:

使用甘特图的模式展示任务:

使用台子模式展示任务:

使用看板模式展示任务:

Vikunja 支持全局关键词搜索:

Vikunja 可修改背景图片:

Vikunja 支持切换至夜间模式:

终端

Vikunja 除了 Web 端外,还有其它平台终端。为了方便小伙伴们获取,杜老师已经把所有平台的 APP 转存到了网盘:

下载地址
  •  

Potainer 容器管理器的安装与使用

Potainer 是一个轻量级容器管理器,它提供了一种简单而高效的方式来管理 Docker 容器。本篇教程简单介绍 Potainer 的特点、安装过程以及使用示例,如有问题欢迎在评论区留言!

工具特点

  1. 简单易用。Potainer 具有直观的用户界面,使得容器管理变得更加容易,即使对于没有 Docker 经验的用户也能快速上手;

  2. 快速部署。通过 Potainer 可快速部署新的容器,节省了时间和精力;

  3. 资源监控。它提供了对容器资源使用情况的监控,有助于更好地管理系统资源;

  4. 可视管理。Potainer 提供了可视化的界面,可以直观地查看容器的状态和日志等信息。

安装过程

首先,需要确保系统已经安装了 Docker。可通过以下命令来检查是否安装了 Docker。若未安装,可以参考《Docker 的安装》一文:

1
docker --version

接下来使用以下命令安装 Potainer:

1
docker pull potainer/potainer

安装完成后可以通过以下命令启动 Potainer:

1
docker run -d -p 9000:9000 --name potainer potainer/potainer

启动后可以在浏览器中访问下面链接来打开 Potainer 界面:

1
http://localhost:9000

使用示例

登录 Potainer 界面后,将看到一个容器的列表,显示了当前运行的容器。

要创建一个新容器,可点击 Create Container 按钮,填写相关信息,例如容器名称、镜像与端口映射等。

还可以查看容器的详细信息,包括日志和资源使用情况等。可点击相应的容器,在右侧面板中可查看其详细信息。

如需要停止或删除容器,只需点击相应操作按钮即可。

效果截图

登录后的效果如下:

  •  

强大的自托管 compose.yaml 管理工具 Dockge

Dockge 是 Uptime Kuma 作者新作品,故 UI 风格与 Uptime Kuma 基本一致。Dockge 主打的是简单易上手,与 Potainer 相比界面简洁易用,新手使用不会感到一头雾水。

优点

  1. 通过 Web 页面管理 compose.yaml 文件;

  2. 拉取等响应式操作输出都会实时显示;

  3. 可以将 docker run 命令转换为 compose.yaml 文件;

  4. 可直接存储 compose.yaml 文件,可使用常规 docker compose 命令进行操作。

缺点

  1. 与 Potainer 等相比功能没那么丰富,例如没有单独管理网络、镜像功能;

  2. 无法接管现有正在运行容器。

安装

创建用于存储堆栈与 Dockge 目录,并进入到目录:

1
2
mkdir -p /opt/stacks /opt/dockge
cd /opt/dockge

创建 compose.yaml 文件并填写如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
version: "3.8"
services:
dockge:
image: louislam/dockge:1
restart: unless-stopped
ports:
- 5001:5001
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data:/app/data
- /opt/stacks:/opt/stacks
environment:
- DOCKGE_STACKS_DIR=/opt/stacks

根据实际需求修改上面内容,保存后执行下面的命令启动服务:

1
docker compose up -d

如果需要停止使用,可使用下面的命令:

1
docker compose down

截图

初次访问时需创建管理用户,登录后的效果如下:

  •  

Coolify 开源自托管的 Heroku/Netlify/Vercel 替代方案

Coolify 是一个开源、自托管应用程序部署和托管平台,旨在为开发人员提供类似 Heroku、Netlify 和 Vercel 的功能。它允许用户在自己的服务器上部署和管理各种应用程序、静态网站、API 后端服务和数据库等。

特点优势

自主托管:Coolify 允许部署资源到几乎任何服务器上,包括个人的服务器、树莓派等。只需要 SSH 连接,就能管理自己硬件资源。

多语言多框架支持:Coolify 与各种编程语言、框架兼容,可以部署和管理各种类型的应用程序。不论静态网站、API 后端服务还是数据库,Coolify 都能提供强大的支持。

SSL 证书和安全性:Coolify 会自动为自定义域名设置和更新 Let’s Encrypt 证书,确保应用程序的安全和加密连接。用户不需要担心证书繁琐设置和更新,Coolify 会自动处理这些问题。

监控、通知:Coolify 会监控部署、服务器磁盘使用情况等,并在发生任何问题时通过电子邮件等渠道通知。

安装脚本

1
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash

注意:Coolify 支持通过源码及 Docker 等方式部署,上面是来自官方的一键部署脚本,可使用与生产环境。

运行要求


支持操作系统:

  1. 基于 Debian 的 Linux 发行版(Debian/Ubuntu 等)

  2. 基于 Redhat 的 Linux 发行版(CentOS/Fedora/Red Hat/AlmaLinux/Rocky 等)

  3. 基于 SUSE 的 Linux 发行版(SLES/SUSE/openSUSE 等)

    支持系统架构:

  4. AMD64 位架构;

  5. ARM64 位架构。

    所需的最低服务器配置:

  6. 双核心 CPU;

  7. 2048 兆内存;

  8. 30GB 以上的磁盘空间。

运行截图

控制面板:

项目列表:

项目设置:

服务堆栈:

环境变量:

命令执行:

运行日志:

后台设置:

节点设置:

通知功能:

Keys 以及 Tokens:

团队协作:

  •  

Web-Check 炫酷强大的网站测试工具

随着互联网普及和发展,Web 应用程序的数量越来越多,各种网络问题也是层出不穷,因而监测这些 Web 应用程序的性能和可用性变得非常重要。今天的文章和大家分享一款十分好用的的网站分析项目!

项目简介

Web-Check 是一款开源网站分析工具,能帮助我们快速的扫描网站,检测网站或主机的信息,发现网页性能和兼容性问题,包括 IP/SSL/DNS/Cookies 等信息。

比如,可帮助检测网页的语法错误、标签关闭、属性错误等等,确保网页的正确性;分析网页性能,提供优化建议,提升加载的速度和用户体验。

安装部署

1
docker run -p 3000:3000 lissy93/web-check

注意:项目支持非常多的部署方式,包括 Netlify/Vercel 的一键部署,Docker 部署和本地源码部署。这里仅以 Docker 部署的方式为例,使用上面的命令部署后,可通过 `IP:3000 访问。

配置设置

API 密钥和凭据:

变量说明
GOOGLE_CLOUD_API_KEYGoogle API 的密钥,这可用于返回网站质量指标。
REACT_APP_SHODAN_API_KEYShodan API 的密钥,这将显示给定域关联主机名。
REACT_APP_WHO_API_KEYWhoAPI 的密钥,这将显示比默认作业更全面的 WhoIs 记录。

配置设置:

变量说明
PORT运行 server.js 时提供 API 的端口(如 3000)
API_ENABLE_RATE_LIMIT为/api 端点启用速率限制(如 true)
API_TIMEOUT_LIMITAPI 请求的超时限制,以毫秒为单位(如 10000)
API_CORS_ORIGIN通过此处设置允许的主机名来启用 CORS(如 example.com
CHROME_PATHChromium 可执行文件路径(如/usr/bin/chromium)
DISABLE_GUI禁用 GUI 页,仅提供 API(如 false)
REACT_APP_API_ENDPOINTAPI 的端点,本地或者远程(如/api)

项目截屏

Web-Check 主界面截屏效果如下,在框中输入 URL,如 https://dusays.com,后点击 Analyze:

等待一会之后即可看到包括 IP/SSL/DNS/Cookies 等信息:

点击 Show Details 可查看详细加载信息:

页面的结尾处可以下载页面扫描报告,未来还支持更多的功能:

  •  

iStoreOS 路由系统介绍与安装

最近托管在群晖的 GitLab 非常不稳定,想必是群晖的性能不够用了。想着软路由的性能有很多的冗余,就想移植到软路由。结果运行的爱快怎么都不成,看到前段时间宋童靴的推荐,决定更换到 iStoreOS!

系统介绍

iStoreOS 源于 OpenWRT,重点是做了很多很多的交互简化。iStoreOS 入门极客版本 UI 是默认 UI,目标是提供给懂点技术的入门极客爱好者,或者偷懒极客老手,核心特性:

  1. 首页提供网络向导、磁盘向导、Docker 向导等众多向导,不管新手还是老手,都能快速配置自己想要东西;
  2. 修复众多 OpenWRT 不人性的小问题,如 Samba 设置独立用户名密码很麻烦、磁盘挂载;
  3. 更多首页工具帮手,比如在线升级、各种错误检测、网口图形化配置等;
  4. 其它很多常用功能,如 DDNS 配置、Docker 配置等。

iStoreOS 还提供软件中心,尽可能解决插件之间的依赖关系,可让大家自由自在安装插件。手动安装离线包也是支持的。除此之外,为了方便大家折腾不出问题,避免掉坑,还做了很多防坑操作如:

  1. 救援模式,即是固件完全刷坏,也可以进入救援模式救回来;
  2. 沙箱模式,通过 U 盘进入沙箱模式,后续软件安装更新都在沙箱进行。不管如何安装插件搞坏系统,拔掉 U 盘就会回到上个状态。沙箱模式本身也是系统扩容最简单的方法。

系统截图

iStoreOS 的首页截图:

iStoreOS 的软件中心截图:

准备安装

  1. 一个 U 盘;

  2. 一个可连接软路由的显示器;

  3. 一个键盘;

  4. 一台 Windows 系统的电脑。

系统安装

从官网中下载对应版本固件。请注意看中间日期,如 xxx20221123xx-xxx.img.gz,建议下载最新版本。下载完成之后不要解压。电脑上用 Rufus 做 USB 启动盘。电脑插入 U 盘,选择下载好的固件,把固件写入到 U 盘:

选从 U 盘启动,一般按 F11,选择接入 U 盘,就可以启动了。如找不到 U 盘,那么可能是 U 盘不兼容,需换一个 U 盘。登录 U 盘系统,登录成功之后,输入:

1
quickstart

选择 Install X86 一直按确定:

用 Show Interfaces 查看网线插入到了哪个网口,以及查看当前 LAN 口的 IP。系统写入完成,拔掉外接设备,通电启动。使用如下信息进入后台管理:

1
2
3
4
5
6
# 默认地址
http://192.168.100.1
# 默认用户
root
# 默认密码
password
  •  

基于 rsync+sersync 实现文件的同步备份

上一篇我们使用了 rsync+inotify 实现文件的实时同步,inotify 常用于监控目标文件变化。本篇教材说明如何通过 sersync 实现文件的同步备份,底层仍使用 rsync+inotify,优点是只对变化的目录数据操作,甚至是一个文件不同的部分进行同步。

工具介绍

rsync 是一个远程数据同步工具,可通过网络在不同的主机之间快速同步文件和目录。

sersync 是基于 rsync 开发的一款高性能的文件同步工具,它提供了更简单的配置和更好的性能。

部署思路

  1. 在需要进行同步的主机上安装 rsync

  2. 配置 rsync 服务器,在源主机配置 rsync 服务器,允许其它主机通过 rsync 连接并获取文件;

  3. 在目标主机安装 sersync

  4. 配置 sersync 指定源主机信息、要同步文件或目录、同步频率;

  5. 启动 sersync 服务使开始执行文件同步备份操作;

  6. 测试并调试相关的服务,具体的配置步骤可能因操作系统和实际需求而有所不同。

配置参考

以下是一个简单的示例,展示了基本的配置思路。源主机上 rsync 服务器配置:

1
2
3
4
5
6
7
8
9
10
11
# 编辑 rsync 主配置文件
vim /etc/rsyncd.conf
# 添加以下内容
[backup]
path = /path/to/backup/directory
read only = yes
list = yes
auth users = backup_user
secrets file = /path/to/rsync/secrets
# 设置密码
chmod 600 /path/to/rsync/secrets

目标主机上 sersync 配置:

1
2
3
4
5
6
7
8
9
10
# 编辑 sersync 主配置文件
vim /etc/sersync.conf
# 添加以下内容
[source]
rsync_server = server_ip:873
username = backup_user
password = password
remote_src = backup
[destination]
local_dir = /path/to/backup/destination

注意事项

请将上述示例中的路径和用户名、密码等根据实际的情况进行修改。然后启动 sersync 服务并确保其在后台运行。

这只是一个基本的示例,实际配置可能更加复杂,如设置过滤器、排除某些文件或着目录、处理冲突。此外还可使用定时任务或监控工具来自动执行同步操作,并根据需要进行错误处理和日志记录。

在配置和使用 rsync+sersync 进行文件同步备份时,务必仔细阅读相关文档、教程,并根据具体需求进行适当调整和优化。

同时确保网络连接稳定,合理安排同步时间,以避免对业务系统造成影响。如果可能,还可以进行测试和备份恢复演练,以确保备份可靠性和有效性。

  •  

基于 rsync+inotifywait 实现文件的实时同步

之前有透露过,杜老师的去不图床使用三点备份,除本地备份外,还有内网存储备份,以及云上备份。而内网存储备份是通过 rsync 实现的,同步周期为每半个小时。近期打算配合 inotifywait 实现文件的实时同步!

工具介绍

rsync 是一个用于文件同步和备份的工具,inotifywait 是一种文件系统事件通知机制。

通过结合用 rsyncinotifywait,可实现文件的实时同步。

工具安装

安装 rsync 软件包:

1
sudo apt -y install rsync

安装 inotify-tools 软件包:

1
sudo apt -y install inotify-tools

服务配置

在源服务器上,创建一个 rsync 的配置文件,如/etc/rsyncd.conf,指定要同步的文件或目录及其它相关设置。

安装并配置 inotifywait,确保 inotifywait 模块已加载。使用 inotifywait 命令监视源目录事件。

编写同步脚本,使用 inotifywait 输出触发 rsync 命令,将更改的文件同步到目标服务器。

设置定时任务或者守护进程,使用 cron 或其它合适的工具定期执行同步脚本以实现实时同步。

示例脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/bash
# 定义源目录和目标目录
SRC_DIR=/path/to/source
DEST_DIR=/path/to/destination
# rsync 的命令
RSYNC_CMD="rsync -avz --delete $SRC_DIR $DEST_DIR"
# inotifywait 的命令
INotify_CMD="inotifywait -mre modify,create,delete,move $SRC_DIR"
# 主题循环
while true; do
# 执行 inotifywait 并捕获输出
output="$(eval $INotify_CMD)"
# 如有事件发生
if [ -n "$output" ]; then
# 则执行 rsync 进行同步
echo "Syncing files..."
eval $RSYNC_CMD
fi
# 等待一段时间(例如 1 秒)
sleep 1
done

注意:这只是一个简要的概述,实际实现可能会因具体需求和环境而有所不同。在这个示例中,inotifywait 命令监视源目录修改、创建、删除、移动事件。当事件发生时,rsync 命令会执行,将源目录中的更改同步到目标目录中。

  •  

Artalk 评论工具登录功能使用及反馈收集

Artalk 默认只需填写昵称和邮箱即可发表评论,无需验证邮箱。但有时候,我们希望用户能够使用社交账号登录,以减少用户填写信息的时间,或者提高用户信息的真实性,故此杜老师决定开启社交登录来实现这一目的。

写在最前

作为 Artalk 的内测用户,杜老师第一时间启用了社交登录功能。

近期也会收到一部分小伙伴反馈,说看到登录按键后不太习惯。

这里说明一下启用邮箱密码登录功能后仍然可跳过邮箱验证,登录弹窗底部显示跳过按钮,点击后评论框顶部恢复为显示原有的昵称、邮箱、网址。

另外已经向 Artalk 作者反馈相关建议,期待后期升级更多功能。

同时希望小伙伴们积极提供建议,这边都会第一时间反馈给 Artalk 作者,以满足大家的需求。

本站后期也会对接各大社交平台,目前仅支持用邮箱登录。

食用教程

在启用邮箱密码登录后,评论框顶部的昵称邮箱输入框将隐藏,发送按钮将显示为登录按钮。当用户点击登录按钮后,会弹出一个登录框,用户可输入邮箱和密码登录,登录成功即可发表评论:

用户可以通过邮箱注册账号,将向用户邮箱发送一封带有验证码的邮件。验证码有效期为 10 分钟,验证码发送频率限制 1 分钟一次:

登录后如果检测到相同邮箱下有多个不同用户名的账号,将会弹出账号合并工具,用户可选择保留其中一个用户名,该邮箱下的所有评论等数据合并到保留账号下,而原有的账号将被删除,评论显示的用户名将会变更为保留用户名:

用户发表的评论将展示「邮箱已被验证」标识:

支持同时启用多种登录方式,用户可以选择任意一种方式登录:

如果只启用了唯一一种登录,如 GitHub 登录,将直接弹出 GitHub 授权登录页面:

  •  

同款说说页面部署代码分享

在一帮小伙伴的帮助下,杜老师终于完成了对说说页面的美化。对此颇有感概,不会前端是真不行,但就是学不会。该代码匹配 Volantis,可自适应夜间模式,感兴趣的可以尝试部署,有问题就不要问了,杜老师也不会~

特性

  1. 统计用户所发说说条数;

  2. 显示用户头像;

  3. 显示用户昵称;

  4. 显示平台的用户名;

  5. 支持大图显示;

  6. 可一键至说说广场进行评论。

效果

正常的浏览效果如下图:

夜间模式的浏览效果如下图:

代码

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
<link href="https://npm.onmicrosoft.cn/penndu@13.0.0/memos/css/style.css" rel="stylesheet" type="text/css">
<link href="https://npm.onmicrosoft.cn/penndu@13.0.0/memos/css/highlight.github.min.css" rel="stylesheet" type="text/css">
{% p center logo large, 点图片可放大! %}
<section id="main" class="container">
<div class="total">Total <span id="total">0</span> Memos 🎉</div>
<div id="memos" class="memos">
</div>
</section>
<script type="text/javascript">
var memos = {
host: 'https://s.dusays.com/',
limit: '10',
creatorId: '1',
domId: '#memos',
username: 'penn',
name: 'Teacher Du',
}
</script>
<script type="text/javascript" src="https://npm.onmicrosoft.cn/penndu@13.0.0/memos/js/lazyload.min.js?v=17.8.3"></script>
<script type="text/javascript" src="https://npm.onmicrosoft.cn/penndu@13.0.0/memos/js/marked.min.js?v=11.1.1"></script>
<script type="text/javascript" src="https://npm.onmicrosoft.cn/penndu@13.0.0/memos/js/view-image.min.js?v=2.0.2"></script>
<script type="text/javascript" src="https://npm.onmicrosoft.cn/penndu@13.0.0/memos/js/moment.min.js?v=2.30.1"></script>
<script type="text/javascript" src="https://npm.onmicrosoft.cn/penndu@13.0.0/memos/js/moment.twitter.js"></script>
<script type="text/javascript" src="https://npm.onmicrosoft.cn/penndu@13.0.0/memos/js/highlight.min.js?v=11.9.0"></script>
<script type="text/javascript" src="https://npm.onmicrosoft.cn/penndu@13.0.0/memos/js/main.js"></script>
<script>hljs.highlightAll();</script>

注意:如果不是 Volantis 主题需删除{% p center logo large, 点图片可放大! %}所在行。

使用

请根据需求修改对应的内容:

参数说明
host域名
limit每页显示条数
creatorId用户的 ID
domId显示位置
username广场的用户名
name昵称
  •  

自建 CDN 联盟试运营

很多小伙伴感觉杜老师说的访问速度很快,去不图床外链比较稳定,经常会问杜老师用的是哪家的 CDN,这里统一回复:杜老师说及其旗下的所有服务用的都是自建 CDN。今日突发奇想打算弄个自建 CDN 的联盟,感兴趣的小伙伴可进来看看加入规则!

最低配置

所加入的服务器需满足以下最低配置:

项目配置
CPU1H
内存2G
硬盘50G
架构X86_64

系统版本

所加入的服务器需使用以下系统对应版本,并保证系统纯净度「指装好系统后,并未安装任何其它服务」

系统版本
Ubuntu18
Ubuntu20
Ubuntu22
Debian10
Debian11
Debian12
CentOS7
CentOS8
CentOS8 Stream
CentOS9 Stream
Rocky Linux8
Rocky Linux9

端口列表

所加入的服务器需开放以下端口:

端口说明
8000主控通信控制端口
80节点程序必用端口
443节点程序必用端口

入盟规则

  1. 满足以上配置、系统、端口需求;

  2. 节点名额仅有 40 个,当名额耗尽时,将根据服务器配置排位,将最低配置服务器移除联盟;

  3. 节点入联盟后需要完全托管,节点服务器上不能安装任何其它服务;

  4. 联盟根据节点带宽发放对应积分,按每兆一元积分来兑换;

  5. 平台使用积分兑换使用流量,费用为每 G 每小时 0.01 元积分「不足 1G 仍按 1G 计算」例如本日杜老师说 7-9 点流量消耗为 500M/1G/1.5G,则收费为 0.04 元;

  6. 本联盟为杜老师闲着没事突发奇想的,感兴趣的小伙伴可以考虑下,试运营的截止时间为文章发布日所在年的年底「即 2024-12-31」最终解释权归杜老师说所有。

  •  

通过 FFmpeg 替换音轨解决群晖不支持当前所选音轨问题

最近经常刷到「无耻之徒」的短视频,特别喜欢卡尔那段,瞬间激发了杜老师的收集欲。看不看另外说,先下载进群晖。但通过 Video Station 无法播放,提示不支持当前所选的音轨。这里分享如何通过 FFmpeg 替换音轨解决群晖不支持当前所选音轨问题!

问题截图

杜老师是通过磁链下载 MKV 格式的版本,目前网上影视资源大多都是这个版本,群晖也支持该格式,只是该版本使用的是 DTS 音轨,自群晖升级至 7 版本后,就不再支持该音轨,提示界面如下:

压缩分区

1
ffmpeg -i input_video.mp4 -c:v copy -c:a aac -strict experimental output_video.mp4

注意:要使用 FFmpeg 替换视频文件中的音轨,需要安装 FFmpeg 并确保它已正确安装。确保输入的音频流和视频流的采样率和声道数兼容。如果需要,可使用-ar-ac 来指定采样率和声道数。

命令解释

这里参数解释如下:

参数解释
-i input_video.mp4指定输入视频文件。
-c:v copy仅复制视频流,不重编码。
-c:a aac指定输出音频编码格式为 AAC。
-strict experimental用于解决某些编解码器问题。
output_video.mp4是输出文件的名称。

解决截图

通过上面命令,将原有的 DTS 音轨转换为群晖支持的 AAC 音轨,再次上传至群晖后,即可通过群晖内置播放套件观影:

  •  

Windows 更新时出现的错误代码 0x80070643 解决方案

本文介绍如何解决 Windows 更新时出现的错误代码 0x80070643,原因是 WinRE 恢复环境空间不足。先通过进入命令提示符,禁用掉 WinRE,调整磁盘管理工具,扩展 C 盘空间并创建新的 WinRE 分区,最终重启 WinRE 并完成系统更新。

问题截图

如果最近更新 Windows 时,在安装的状态卡了一会,随后报错,并显示错误代码 0x80070643:

首先明确故障来源,错误代码 0x80070643 对应的是系统的 WinRE 恢复盘分区容量不足。这个 RE 盘在资源管理器中是看不到的,可通过磁盘管理器查看它的分区容量。我们可以通过右键点击开始——磁盘管理看到如下界面。可以看到恢复分区不足 750 兆,需要对其扩容:

压缩分区

通过上面截图可以看出,恢复分区的临近分区是 C 盘,我们接下来要从 C 盘中,获取一定的空间给恢复分区。首先要进入命令提示符界面,在搜索框中输入 cmd,右键点击命令提示符并在弹出菜单中选择以管理员身份运行:

打开命令提示符界面后,我们将 WinRE 恢复功能临时禁用,便于后续分区修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
C:\Users\Administrator>reagentc /info
Windows 恢复环境(Windows RE)和系统初始化配置
信息:

Windows RE 状态: Enabled
Windows RE 位置: \\?\GLOBALROOT\device\harddisk0\partition4\Recovery\WindowsRE
引导配置数据(BCD)标识符: c9a5b046-496f-11ec-b9e7-ed5c24c96968
恢复映像位置:
恢复映像索引: 0
自定义映像位置:
自定义映像索引: 0

REAGENTC.EXE: 操作成功。


C:\Users\Administrator>reagentc /disable
REAGENTC.EXE: 操作成功。

开启磁盘管理工具,进入目标磁盘 C 盘。接下来输入 list disk,先检查下磁盘列表,确定我们要进入的是磁盘 0,则输入 sel disk 0。接下来检查磁盘 0 的分区列表输入 list partition。找到 C 盘对应分区号 3 后输入 sel part 3。使用 shrink desired=200 minimum=200 命令从目标分区切出 200 兆容量备用:

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
C:\Users\Administrator>diskpart

Microsoft DiskPart 版本 10.0.20348.1

Copyright (C) Microsoft Corporation.
在计算机上: WIN-B1NQBKNC2UU

DISKPART> list disk

磁盘 ### 状态 大小 可用 Dyn Gpt
-------- ------------- ------- ------- --- ---
磁盘 0 联机 60 GB 1024 KB *

DISKPART> sel disk 0

磁盘 0 现在是所选磁盘。

DISKPART> list partition

分区 ### 类型 大小 偏移量
------------- ---------------- ------- -------
分区 1 系统 100 MB 1024 KB
分区 2 已保留 16 MB 101 MB
分区 3 主要 59 GB 117 MB
分区 4 恢复 616 MB 59 GB

DISKPART> sel part 3

分区 3 现在是所选分区。

DISKPART> shrink desired=200 minimum=200

DiskPart 成功收缩卷: 200 MB

可再次进入到磁盘管理器中查看是否分离成功:

扩容分区

删除原有恢复分区。通过上面操作,我们可以确定恢复分区编号为 4,输入 sel part 4 选择并输入 delete partition override 删除该分区:

1
2
3
4
5
6
7
DISKPART> sel part 4

分区 4 现在是所选分区。

DISKPART> delete partition override

DiskPart 成功地删除了所选分区。

回到磁盘管理页面核对是否删除成功:

右键未分配的分区,选择新建分区,在创建过程中选择不分配分区号:

并指定分区名为 Windows RE Tools

完成更新

回到命令提示符中输入 reagentc /enable 重启 WinRE,输入 reagentc /info 确认 WinRE 启用成功:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
C:\Users\Administrator>reagentc /enable
REAGENTC.EXE: 操作成功。


C:\Users\Administrator>reagentc /info
Windows 恢复环境(Windows RE)和系统初始化配置
信息:

Windows RE 状态: Enabled
Windows RE 位置: \\?\GLOBALROOT\device\harddisk0\partition3\Recovery\WindowsRE
引导配置数据(BCD)标识符: c9a5b048-496f-11ec-b9e7-ed5c24c96968
恢复映像位置:
恢复映像索引: 0
自定义映像位置:
自定义映像索引: 0

REAGENTC.EXE: 操作成功。

接下来回到 Windows 更新界面,重新安装补丁,这次没有报错,很快就完成了升级:

  •  

Linux 中挂载 WebDAV 的详细教程

应 Python_Ryan 小伙伴的需求,更新一篇 Linux 中挂载 WebDAV 的详细教程。另外杜老师目前在延吉旅游,行程较满,近期更新暂缓,且评论也是抽空回复的。如有任何问题可以留言,杜老师看到后会尽快回复处理的!

操作步骤

确保已经安装必要的软件包。这里以 Ubuntu 系统为例,可以使用以下命令安装 davfs2 软件包,该软件包用于挂载 WebDAV 的资源:

1
sudo apt install davfs2

创建 WebDAV 挂载点。选择一个目录作为 WebDAV 资源挂载点。例如,如果要将 WebDAV 挂载到/mnt/webdav 目录中,可使用以下命令创建该目录:

1
sudo mkdir /mnt/webdav

挂载资源。使用以下的命令挂载 WebDAV 资源。将 URL 替换为 WebDAV 服务器 URL:

1
sudo mount -t davfs https://URL /mnt/webdav

验证挂载。完成挂载,可以使用以下命令检查挂载是否成功:

1
df -h | grep webdav

挂载选项

设置挂载选项。可以根据需要设置一些挂载选项,如果 WebDAV 服务器需要身份验证,可以使用-o user=username-o pass=password 选项来提供用户名和密码。例如:

1
sudo mount -t davfs https://URL /mnt/webdav -o user=yourusername -o pass=yourpassword

默认情况下挂载 WebDAV 资源可能只有读取权限。如果需要写入权限,可使用-o rw 选项。例如:

1
sudo mount -t davfs https://URL /mnt/webdav -o rw

自动挂载

如希望在系统启动时自动挂载 WebDAV 资源,可以将挂载命令添加到/etc/fstab 文件中。使用下面的命令编辑/etc/fstab 文件:

1
sudo vim /etc/fstab

在文件的末尾添加以下行的内容。注意将 URL/mnt/webdav 等替换为实际值:

1
https://URL /mnt/webdav davfs rw,noauto,user=yourusername,pass=yourpassword 0 0

注意事项

本教材中使用 HTTPS 协议挂载 WebDAV 资源,但 WebDAV 服务器可能并不支持 HTTPS。可以通过 Nginx 或其它代理服务器将 WebDAV 服务器转换为 HTTPS 协议。反代服务配置参考:

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
location ^~ /
{
proxy_pass http://URL;
proxy_set_header Host DOMAIN;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_ssl_server_name on;
proxy_http_version 1.1;
# proxy_hide_header Upgrade;

add_header X-Cache $upstream_cache_status;
#Set Nginx Cache



if ( $uri ~* "\.(gif|png|jpg|css|js|woff|woff2)$" )
{
expires 1m;
}
proxy_ignore_headers Set-Cookie Cache-Control expires;
proxy_cache cache_one;
proxy_cache_key $host$uri$is_args$args;
proxy_cache_valid 200 304 301 302 60m;
}

在测试时遇到上传大文件失败的问题,可以调整 Nginx 主配置文件中的 client_max_body_sizekeepalive_timeout 值:

1
2
client_max_body_size 50m;
keepalive_timeout 60;
  •  

Cloudreve 部署公私兼备的网盘系统「进阶配置」

别问,问就是没时间,问就是在水文。但杜老师保证,这是最后一篇,以后不再更新有关 Cloudreve 的教程,除非有小伙伴有所需求。之后得空杜老师会更新一些有意思的服务,但仅提供教材,服务器的资源有限,暂不提供服务平台。

配置文件

首次启动,Cloudreve 会在同级目录下创建名为 conf.ini 的配置文件,可以修改此文件进行一些参数的配置,保存后需要重新启动 Cloudreve 生效。也可在启动时使用如下命令指定配置文件路径:

1
./cloudreve -c ./conf.ini

一个完整配置文件示例如下:

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
[System]
; 运行模式
Mode = master
; 监听端口
Listen = :5212
; 是否开启 Debug
Debug = false
; Session 密钥, 一般在首次启动时自动生成
SessionSecret = 23333
; Hash 加盐, 一般在首次启动时自动生成
HashIDSalt = something really hard to guss
; 呈递客户端 IP 时使用的 Header
ProxyHeader = X-Forwarded-For

; SSL 相关
[SSL]
; SSL 监听端口
Listen = :443
; 证书路径
CertPath = C:\Users\i\Documents\fullchain.pem
; 私钥路径
KeyPath = C:\Users\i\Documents\privkey.pem

; 启用 Unix Socket 监听
[UnixSocket]
Listen = /run/cloudreve/cloudreve.sock
; 设置产生的 socket 文件的权限
Perm = 0666

; 数据库相关,如果你只想使用内置的 SQLite 数据库,这一部分直接删去即可
[Database]
; 数据库类型,目前支持 sqlite/mysql/mssql/postgres
Type = mysql
; MySQL 端口
Port = 3306
; 用户名
User = root
; 密码
Password = root
; 数据库地址
Host = 127.0.0.1
; 数据库名称
Name = v3
; 数据表前缀
TablePrefix = cd_
; 字符集
Charset = utf8mb4
; SQLite 数据库文件路径
DBFile = cloudreve.db
; 进程退出前安全关闭数据库连接的缓冲时间
GracePeriod = 30
; 使用 Unix Socket 连接到数据库
UnixSocket = false

; 从机模式下的配置
[Slave]
; 通信密钥
Secret = 1234567891234567123456789123456712345678912345671234567891234567
; 回调请求超时时间 (s)
CallbackTimeout = 20
; 签名有效期
SignatureTTL = 60

; 跨域配置
[CORS]
AllowOrigins = *
AllowMethods = OPTIONS,GET,POST
AllowHeaders = *
AllowCredentials = false
SameSite = Default
Secure = lse

; Redis 相关
[Redis]
Server = 127.0.0.1:6379
Password =
DB = 0

; 从机配置覆盖
[OptionOverwrite]
; 可直接使用 `设置名称 = 值` 的格式覆盖
max_worker_num = 50

配置案例

数据库改为 MySQL。默认情况下 Cloudreve 会使用内置的 SQLite 数据库,并在同级目录创建数据库文件 cloudreve.db,如果您想要使用 MySQL,请在配置文件中加入以下的内容,并重启 Cloudreve。注意,Cloudreve 只支持大于或等于 5.7 版本的 MySQL,且更换数据库的配置后,Cloudreve 会重新初始化数据库,原有数据将会丢失:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[Database]
; 数据库类型,目前支持 sqlite/mysql/mssql/postgres
Type = mysql
; MySQL 端口
Port = 3306
; 用户名
User = root
; 密码
Password = root
; 数据库地址
Host = 127.0.0.1
; 数据库名称
Name = v3
; 数据表前缀
TablePrefix = cd
; 字符集
Charset = utf8

使用 Redis 做缓存。可在配置文件中加入 Redis 相关设置,注意请为 Cloudreve 指定未被其它业务使用的 DB 以避免冲突。重启 Cloudreve 后,可注意控制台输出,以确定 Cloudreve 是否成功连接 Redis 服务器:

1
2
3
4
[Redis]
Server = 127.0.0.1:6379
Password = your password
DB = 0

覆盖从机节点的配置项。Cloudreve 的某些配置项是存储在数据库中的,但是从机节点并不会连接数据库,可以在配置文件中覆盖相应的配置项。比如,从机节点作为存储端运行时,可通过下面的配置设定从机生成的缩略图规格:

1
2
3
4
5
6
7
8
[OptionOverwrite]
thumb_width = 400
thumb_height = 300
thumb_file_suffix = ._thumb
thumb_max_task_count = -1
thumb_encode_method = jpg
thumb_gc_after_gen = 0
thumb_encode_quality = 85

如果从机节点作为离线下载节点使用,可以通过下面的配置覆盖默认的重试、超时参数,以避免默认的数值过于保守导致文件转存失败:

1
2
3
4
5
6
7
[OptionOverwrite]
; 任务队列最多并行执行的任务数
max_worker_num = 50
; 任务队列中转任务传输时,最大并行协程数
max_parallel_transfer = 10
; 中转分片上传失败后重试的最大次数
chunk_retries = 10
  •  

Cloudreve 部署公私兼备的网盘系统「单服务篇」

Cloudreve 除了支持 Docker 容器部署,官方还提供单服务部署方式。操作十分简单,仅需要一个文件即可搭建运行 Cloudreve。本文介绍了 Cloudreve 部署过程,及通过注册服务或守护进程方式实现后台运行。

部署过程

Linux 下,直接解压并执行主程序即可。这里以 3.8.3 版本为例,首先至官网下载压缩包,解压获取到主程序:

1
tar -zxvf cloudreve_3.8.3_linux_amd64.tar.gz

赋予执行权限:

1
chmod +x ./cloudreve

启动服务:

1
./cloudreve

Cloudreve 在首次启动会创建初始管理员账号,请注意保管管理员密码,此密码只会在首次启动出现。如忘记初始管理员密码,需删除同级目录下的 cloudreve.db,重新启动主程序以初始化新的管理员账户。Cloudreve 默认监听 5212 端口。可以在浏览器中通过下面地址访问 Cloudreve:

1
http://IP:5212

注册服务

通过上面的方式运行 Cloudreve,会一直占用着终端。为了不影响终端的使用,我们可将 Cloudreve 注册为服务,这样就算服务器重启后,Cloudreve 也可以自动启动。使用如下命令编辑配置文件:

1
vim /usr/lib/systemd/system/cloudreve.service

这里运行目录以/home/cloudreve 为例,参考配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[Unit]
Description=Cloudreve
Documentation=https://docs.cloudreve.org
After=network.target
After=mysqld.service
Wants=network.target

[Service]
WorkingDirectory=/home/cloudreve
ExecStart=/home/cloudreve/cloudreve
Restart=on-abnormal
RestartSec=5s
KillMode=mixed

StandardOutput=null
StandardError=syslog

[Install]
WantedBy=multi-user.target

配置好文件后,使用下面命令使其生效:

1
systemctl daemon-reload

启动服务命令如下:

1
systemctl start cloudreve

设置开机启动命令如下:

1
systemctl enable cloudreve

停止服务命令如下:

1
systemctl stop cloudreve

重启服务命令如下:

1
systemctl restart cloudreve

查看状态命令如下:

1
systemctl status cloudreve

守护进程

首先要安装 supervisor,这里以 Ubuntu 系统为例,命令如下:

1
sudo apt-get install supervisor

初始化全局配置文件的命令如下:

1
2
sudo touch /etc/supervisord.conf
sudo echo_supervisord_conf > /etc/supervisord.conf

编辑全局配置文件:

1
sudo vim /etc/supervisord.conf

将文件底部的[include]分区注释符删除,加入新的配置文件包含路径:

1
2
[include]
files = /etc/supervisor/conf/*.conf

创建 Cloudreve 应用配置所在文件的目录,创建打开配置文件:

1
2
sudo mkdir -p /etc/supervisor/conf
sudo vim /etc/supervisor/conf/cloudreve.conf

根据实际情况填写以下内容:

1
2
3
4
5
6
7
8
[program:cloudreve]
directory=/home/cloudreve
command=/home/cloudreve/cloudreve
autostart=true
autorestart=true
stderr_logfile=/var/log/cloudreve.err
stdout_logfile=/var/log/cloudreve.log
environment=CODENATION_ENV=prod

配置好文件后,使用下面命令指定配置文件运行守护进程服务:

1
supervisord -c /etc/supervisord.conf

启动服务命令如下:

1
sudo supervisorctl start cloudreve

停止服务命令如下:

1
sudo supervisorctl stop cloudreve

查看状态命令如下:

1
sudo supervisorctl status cloudreve

反向代理

1
2
3
4
5
6
7
8
9
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://127.0.0.1:5212;

# 如果您要使用本地存储策略,请将下一行注释符删除,并更改大小为理论最大文件尺寸
# client_max_body_size 20000m;
}

注意:如果需使用 HTTPS,亦或是需要与服务器上其他 Web 服务共存时,可能需使用主流 Web 服务器反向代理 Cloudreve。需要在 Web 服务器中新建一个虚拟主机,然后在网站配置文件中加入反代规则。这里以 Nginx 为例,在网站的 server 字段中加入如上代码。

  •  

Cloudreve 部署公私兼备的网盘系统「Docker Compose 篇」

Cloudreve 的一个特性,就是可以和 Aria2 整合实现离线下载功能。上篇教程仅说明了 Cloudreve 的部署,并没有说明如何部署 Aria2 以及如何整合。本篇教程说明如何通过 Docker Compose 部署 Cloudreve 及 Aria2。

部署脚本

在此之前,需要创建 data 等目录作为离线下载临时中转目录,可以使用下面命令创建目录结构:

1
2
3
4
5
6
mkdir -vp cloudreve/{uploads,avatar} \
&& touch cloudreve/conf.ini \
&& touch cloudreve/cloudreve.db \
&& mkdir -p aria2/config \
&& mkdir -p data/aria2 \
&& chmod -R 777 data/aria2

然后将下面的脚本保存为 docker-compose.yml,放置当前目录。同时修改文件中 RPC_SECRET

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
version: "3.8"
services:
cloudreve:
container_name: cloudreve
image: cloudreve/cloudreve:latest
restart: unless-stopped
ports:
- "5212:5212"
volumes:
- temp_data:/data
- ./cloudreve/uploads:/cloudreve/uploads
- ./cloudreve/conf.ini:/cloudreve/conf.ini
- ./cloudreve/cloudreve.db:/cloudreve/cloudreve.db
- ./cloudreve/avatar:/cloudreve/avatar
depends_on:
- aria2
aria2:
container_name: aria2
image: p3terx/aria2-pro
restart: unless-stopped
environment:
- RPC_SECRET=your_aria_rpc_token
- RPC_PORT=6800
volumes:
- ./aria2/config:/config
- temp_data:/data
volumes:
temp_data:
driver: local
driver_opts:
type: none
device: $PWD/data
o: bind

运行镜像

通过下面命令运行镜像,运行时的输出信息会直接显示在当前控制台中,可以看到管理员的账号及密码:

1
docker-compose up

为了不占用前台的使用,可使用下面的命令切换后台运行模式:

1
docker-compose up -d

如需关闭当前运行容器,可以运行以下命令。注意此步骤不会删除挂载的配置文件以及相关目录:

1
docker-compose down

如需升级 Cloudreve 容器的版本,可以使用以下命令获取最新镜像:

1
2
3
docker-compose down
docker pull cloudreve/cloudreve
docker-compose up -d
  •  

Cloudreve 部署公私兼备的网盘系统「Docker 篇」

之前发了一篇个人网盘工具搭建教程,有小伙伴反馈部分功能无法正常使用,还是希望杜老师能推荐其它网盘系统。纠结许久,杜老师还是决定把 Cloudreve 拿出来,至于纠结的原因嘛,毕竟很多小伙伴都写过类似教程。杜老师都想复制粘贴水文了~

什么是 Cloudreve

Cloudreve 可快速搭建起公私兼备的网盘系统。Cloudreve 在底层支持不同的云存储平台,用户在实际使用时无须关心物理存储方式。

可以使用 Cloudreve 搭建个人用网盘、文件分享系统,亦或针对大小团体的公有云系统。

工具特点

多样化的外部存储。支持对接多种外部存储的存储端,文件的上传和下载全部为客户端直传,无需经过服务器的中转。

虚拟文件系统。Cloudreve 基于 DBMS 构建了一层文件系统抽象,将用户文件和物理文件结构隔离,用户管理文件时无需关注底层的存储方式,也可同时管理多个外部存储。

从机存储节点。可以将多个 Cloudreve 实例组成主从集群,将文件离线下载任务分配到不同的服务器处理。

压缩文件支持。可在线解压缩文件,或是创建新的压缩文件。

打包下载。选择任意数量文件,直接下载打包后的文件,支持 Web 端打包和服务端打包。

安全登录。使用 FIDO2 物理验证器登录,或者为账号设定两因素登录验证。

管理后台。管理员可以通过后台面板图形化配置站点,审计站点内容。

文件检索。可通过自定义文件标签检索文件,或通过关键字搜索文件。

网盘部署

首先请确保运行 Cloudreve 之前创建目录结构,进入到部署目录中,运行下面命令:

1
2
3
mkdir -vp cloudreve/{uploads,avatar} \
&& touch cloudreve/conf.ini \
&& touch cloudreve/cloudreve.db

创建好上面的目录及文件后,运行下面命令即可自动下载 Cloudreve 容器并启动服务:

1
2
3
4
5
6
7
8
docker run -d \
--name cloudreve
-p 5212:5212 \
--mount type=bind,source=./cloudreve/conf.ini,target=/cloudreve/conf.ini \
--mount type=bind,source=./cloudreve/cloudreve.db,target=/cloudreve/cloudreve.db \
-v ./cloudreve/uploads:/cloudreve/uploads \
-v ./cloudreve/avatar:/cloudreve/avatar \
cloudreve/cloudreve:latest

使用效果

待服务运行后,通过 http://IP:5212 可访问 Cloudreve 的登录页面,运行下面的命令可查询到管理员密码:

1
docker logs cloudreve | grep password

使用默认管理员账号 admin@cloudreve.org,及上面查询的密码,登录后即可看到网盘主页面:

  •  

GitHub 库自动同步脚本分享

杜老师复刻了 70 多个库,每次源库更新后都需要一一手动同步,太过麻烦。今天分享一个自动同步脚本,有需要的小伙伴可以试一下。注意如对本地库有修改,建议使用 PR 来同步,避免代码覆盖。

代码同步

不太清楚小伙伴们同步代码方式,有人习惯用 PR,有人喜欢用下图同步的方式。不管哪种方式,都需要手动操作的。如有仓库过多,每个都要同步一遍,想想是多大工作量。杜老师分享了 GitHub 库自动同步脚本,供有需要的小伙伴参考:

脚本分享

进入要同步的库中,切换至 Actions,点击 New workflow 项:

打开新页面后,点击篮字的 set up a workflow yourself:

设置文件名 sync.yml「可自定义,不与其它脚本同名即可」

将下面的脚本填到输入框中,点击右上方 Commit changes 即可:

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
name: Upstream Sync

permissions:
contents: write

on:
schedule:
- cron: "0 0 * * *" # every day
workflow_dispatch:

jobs:
sync_latest_from_upstream:
name: Sync latest commits from upstream repo
runs-on: ubuntu-latest
if: ${{ github.event.repository.fork }}

steps:
# Step 1: run a standard checkout action
- name: Checkout target repo
uses: actions/checkout@v4

# Step 2: run the sync action
- name: Sync upstream changes
id: sync
uses: aormsby/Fork-Sync-With-Upstream-action@v3.4
with:
upstream_sync_repo: arnidan/nsfw-api
upstream_sync_branch: main
target_sync_branch: main
target_repo_token: ${{ secrets.GITHUB_TOKEN }} # automatically generated, no need to set

# Set test_mode true to run tests instead of the true action!!
test_mode: false

- name: Sync check
if: failure()
run: |
echo "[Error] 由于上游仓库的 workflow 文件变更,导致 GitHub 自动暂停了本次自动更新,您需要手动 Sync Fork 一次。"
echo "[Error] Due to a change in the workflow file of the upstream repository, GitHub has automatically suspended the scheduled automatic update. You need to manually sync your fork."
exit 1
  •  

使用 Docker 部署 JmalCloud 个人网盘

很多小伙伴习惯使用 Alist 和 Cloudreve 等软件来管理存储,今天杜老师为搭建推荐另外一款网盘工具。JmalCloud 是款私有云存储网盘项目,能够简单安全管理云端文件。

工具优点

  • 支持 OSS/COS 和 MinIO 等。

  • 支持图片、音频、视频等文件的在线预览。

  • 支持 Word/Excel/PPT 及流程图和思维导图的编辑和预览。

  • 可支持 X86/ARM64。

  • 提供强大的在线文本编辑器。

  • 支持超大文件上传、断点续传。

服务部署

将下面的代码保存为 docker-compose.yml

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
version: "3"
services:
jmalcloud:
container_name: jmalcloud_server
image: jmal/jmalcloud:latest
environment:
MONGODB_URI: mongodb://mongo:27017/jmalcloud
TZ: Asia/Shanghai
volumes:
- ./docker/jmalcloud/files:/jmalcloud/files/
restart: unless-stopped
mongo:
container_name: jmalcloud_mongodb
image: mongo:4.4
environment:
TZ: Asia/Shanghai
volumes:
- ./docker/jmalcloud/mongodb/data/db:/data/db
restart: unless-stopped
command: --wiredTigerCacheSizeGB 0.5
nginx:
container_name: jmalcloud_nginx
image: jmal/jmalcloud-nginx:latest
ports:
- 7070:80
- 7071:8089
environment:
TZ: Asia/Shanghai
links:
- jmalcloud
- office
- drawio-webapp
restart: unless-stopped
office: # Optional
container_name: jmalcloud_office
image: onlyoffice/documentserver:7.0.0.132
environment:
TZ: Asia/Shanghai
restart: unless-stopped
drawio-webapp: # Optional
container_name: jmalcloud_drawio
image: jgraph/drawio:20.2.3
environment:
TZ: Asia/Shanghai
restart: unless-stopped

使用下面命令即可创建并启动 JmalCloud:

1
docker compose up -d

重置密码

等待 JmalCloud 启动后,即可通过 http://IP 访问 JmalCloud。用户名 admin ,默认密码为 jmalcloud。如果密码遗失,可使用下面的命令重置:

1
docker exec -it jmalcloud_mongodb mongo jmalcloud --eval "db.getCollection('user').update({ 'creator': true }, {\$set: { 'password': '1000:c5b705ea13a1221f5e59110947ed806f8a978e955fbd2ed6:22508de12228c34a235454a0caf3bcaa5552858543258e56' }}, { 'multi': false, 'upsert': false })"

执行完重置命令后,还需重启容器才可生效,重置后的密码为 jmalcloud

1
docker restart jmalcloud_server

部分截图

JmalCloud 个人网盘的登录页面:

支持在线新建文本、思维导图、流程图等::

支持在线编辑文本文件:

支持 Word 等格式文件在线编辑:

支持在线新建及编辑流程图:

支持在线编辑思维导图:

可直接在页面中直接拖拽来上传或是移动文件:

支持各种类型文件识别:

  •  

比白嫖更加可怕的是滥用

前两天发现评论区的表情加载速度变慢了,杜老师一直使用渺软公益 CDN,就想着去项目页面反馈一下,结果就看到项目线路切换的通知。再找 NPM 加速节点时发现可用的很少了,故而写下此篇~

话题背景

随着网络技术进步,现在搭建网站成本越来越低。很多小伙伴都使用和老师一样的博客框架。

通过这种静态化的框架,我们可以零成本地搭建一个博客。

但是这种零成本导致很多人不在意博客的维护。

之前在整理友情链接时,发现不少的小伙伴已经 AFK 了,也就是不再维护自己的博客。

杜老师不提倡铺张浪费,但个人感受是有成本地维护博客可以更好地调动运营积极性。

毕竟花出一定的成本和精力去维护时,肯定会想着去捞回这个成本,甚至可以挣点儿小零花,这样可以更好地调动积极性。

白嫖服务

话说远了,我们再说回来。之前杜老师推荐了很多公益项目,几乎都是关于公益 CDN 的。

自从 jsDelivr 被墙后,很多人开始白嫖 elemecdn,最终人家被薅怕了,宣布停止回源。

很多热心的小伙伴也开始提供相关的加速服务。但前几天发现渺软公益 CDN 无法使用后,尝试使用之前推荐的公益 CDN 项目,但是发现这些项目都已下线。

像饿了么、知乎和百度的 CDN 等,它们同步时间和同步库都是不固定的。因此,现在可用的公益 CDN 越来越少。

有小伙伴可能会问,杜老师为什么不提供这种 CDN 服务?

这不是说不想,而是成本太大了根本耗不起。

资源滥用

杜老师想提到的下一个话题就是滥用。

不少小伙伴为了降低博客的运营成本,不断白嫖网络上的资源。

如果仅是白嫖还好,就怕资源滥用。

比如我们之前提到的公益 CDN,很多小伙伴为了减少服务器的存储成本和运营成本,不使用专业的图床服务,而是通过公益 CDN 做图床。

图片的资源占用远大于脚本,会大量消耗 CDN 流量。

再加上会遇到刷流量的恶意用户,这些成本可想而知。

写在最后

之前杜老师在分享优化博客的思路时,还提倡过尽量做分布式,即尽量使用开源镜像 CDN,这样可以实现流量分流,尽可能减少服务器带宽占用。

奈何目前可用资源越来越少……杜老师只能在这里提议避免资源滥用,另外如果小伙伴们有相关的资源,欢迎在评论区留言,分享给需要的小伙伴们!

  •  

Docker 自建超炫酷监控页面系统

Kener 是一款开源状态页面工具,旨在使服务监控和事件处理变得轻而易举。它提供了一个时尚和用户友好的界面,简化跟踪服务中断,并改善在事件发生时的沟通方式。最棒的是 Kener 与 GitHub 的无缝集成,使在协作和友好的环境中更轻松地跟踪和解决问题。

项目特征

监控跟踪:

  1. 实时监控;
  2. 为访问者处理时区;
  3. 将监控器分为不同部分;
  4. 基于计划任务的监控器调度;
  5. 使用 YAML 灵活配置监控器;
  6. 支持监控器的默认状态。

定制品牌:

  1. 使用 YAML 或代码定制状态页面;
  2. 为监控器的状态和正常运行时间生成徽章;
  3. 支持自定义域;
  4. 浅色、深色主题。

事件管理:

  1. 可使用 Github 创建事件;
  2. 或使用 API 创建事件。

用户体验:

  1. 易于安装、设置;
  2. 用户友好界面;
  3. 适合各种设备的响应式设计;
  4. 自动搜索引擎优化。

部署安装

创建配置文件目录:

1
mkdir -p /host/path/to/config

将下面代码根据实际需求修改后保存为 docker-compose.yml,然后执行 docker-compose -f docker-compose.yml up -d 即可创建和启动服务:

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
version: '3.7'
services:
kener:
image: rajnandan1/kener:latest # assuming this is final namespace/image
container_name: kener
environment:
- TZ=Asia/Shanghai
#- GH_TOKEN=
#- API_TOKEN=
#- API_IP

# If running on a LINUX HOST and not podman rootless these MUST BE SET
# run "id $user" from command line and replace numbers below with output from command
#- PUID=1000 # gid
#- PGID=1000 # uid

### Most likely DO NOT need to change anything below this ###

#- PORT=3000 Port app listens on IN CONTAINER

### If any of the below are changed make sure the bound volume is correct as well ###
#- CONFIG_DIR=/config
#- PUBLIC_KENER_FOLDER=/config/static
#- MONITOR_YAML_PATH=/config/monitors.yaml
#- SITE_YAML_PATH=/config/site.yaml

ports:
- '3000:3000/tcp'
volumes:
- '/host/path/to/config:/config:rw'

定制监控

可使用 vim /host/path/to/config/monitors.yaml 命令编辑配置文件,参考模版如下:

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
- name: Google Search
description: Search the world's information, including webpages, images, videos and more.
tag: "google-search"
image: "/google.png"
api:
method: GET
url: https://www.google.com/webhp
- name: Svelte Website
description: Cybernetically enhanced web apps
tag: "svelte-website"
api:
method: GET
url: https://svelte.dev/
image: "/svelte.svg"
- name: Earth
description: Our blue planet
tag: "earth"
defaultStatus: "UP"
image: "/earth.png"
- name: Frogment
description: A free openAPI spec editor and linter that breaks down your spec into fragments to make editing easier and more intuitive. Visit https://www.frogment.com
tag: "frogment"
image: "/frogment.png"
api:
method: GET
url: https://www.frogment.com

修改好文件后,使用下面命令重启服务:

1
docker restart kener

效果截图

默认显示 90 天内的服务状态,最细粒度到分钟级:

支持 API 监控服务的状态:

可通过脚本调用在站内显示监控数据:

可直接在页面引用监控数据细节:

可在 GitHub 中直接创建事件:

监控数据支持各种调用方式:

部署完成后可通过 http://IP:3000 访问,支持反向代理:

支持浅色、深色模式切换:

  •  

MinIO 的部署及与 Memos 的整合

之前杜老师将说说广场资源转存至缤纷云,没想到刚用没两天,免费的资源就被用光了。对于 CDN 这种无底洞,杜老师还是决定买个服务器,自行部署存储服务。这里整理了部署和整合步骤,供需要的小伙伴们参考。

MinIO 的介绍

MinIO 是种高性能、S3 兼容的对象存储。

专为大规模 AI/ML、数据湖和数据库工作负载而构建,并且它是由软件定义的存储。

无需购买任何专有硬件,就可以云上和普通硬件上拥有分布式对象存储。

MinIO 拥有开源 GNU AGPL v3 和商业企业许可证双重许可。

MinIO 的安装

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
services:
minio:
command: server /data --console-address :9001 --address :9000
container_name: minio
deploy:
resources:
limits:
cpus: 0
memory: 0
environment:
MINIO_BROWSER: "on"
MINIO_BROWSER_LOGIN_ANIMATION: "on"
MINIO_BROWSER_REDIRECT_URL: http://127.0.0.1:9001
MINIO_BROWSER_SESSION_DURATION: "12h"
MINIO_ROOT_PASSWORD: "minioadmin"
MINIO_ROOT_USER: "minioadmin"
MINIO_SERVER_URL: http://127.0.0.1:9000
image: minio/minio:RELEASE.2024-02-26T09-33-48Z
labels:
createdBy: Apps
logging:
driver: json-file
options:
max-file: "10"
max-size: 5M
ports:
- 9001:9001
- 9000:9000
restart: always
volumes:
- ./data:/data
- ./certs:/root/.minio/certs
version: "3"

注意:将上面的内容,根据实际需求略作调整「因为自定义项较多,杜老师就不一一标注了.如有问题可以自行搜索,或在评论区中留言」保存为 docker-compose.yml,之后使用命令 docker-compose -f docker-compose.yml up -d 启用就行了。

初始设置

打开浏览器输入 http://IP:9000/,输入 MINIO_ROOT_USERMINIO_ROOT_PASSWORD 的值 minioadmin,登录到控制台:

目前暂无中文界面,不过好在配置简单,且不需要太多配置。点击左侧的 Buckets,再点击右侧 Create Bucket。在 Bucket Name 框中输入存储桶的名称,后点击 Create Bucket 即可:

待页面刷新后,点击刚创建好的存储桶,点击 Summary->Access Policy 项,将值设置为 Public:

之后点击左侧的 Access Keys 创建一个密钥。这里需要注意的是 Secret Key 项仅创建时可见,请保持好!如有遗忘可以重新创建:

与 Memos 整合

参考下图中的参数配置即可。需要注意的是,9000 是控制台的端口,API 的端口是 9001

  •  

Linux 安装杀毒软件 ClamAV

前两天有小伙伴找到杜老师询问是否可以帮忙查杀服务器的木马病毒,原因是凉心云的安全中心提示有病毒,但自动查杀功能要付费,而且费用较高。正好杜老师最近在研究 Linux 平台的杀毒软件,分享一下 ClamAV 的使用方法。

软件介绍

ClamAV 是一个开源防病毒工具包,专为邮件网关上的电子邮件扫描设计。

它提供了许多实用程序,包括灵活且可扩展的多线程守护程序、命令行扫描程序和用于自动数据库更新的高级工具。

该软件包的核心是以共享库形式提供的防病毒引擎。

除了邮件之外,还可用其扫描系统中的木马病毒。

软件特征

  • 实时保护。ClamD 扫描守护程序 ClamOnAcc 客户端在现代版本的 Linux 上提供按访问扫描。这包括在扫描文件之前阻止文件访问可选功能。

  • ClamAV 可检测数百万种病毒、蠕虫、特洛伊木马和其他恶意软件,包括 Microsoft Office 宏病毒、移动恶意软件以及其它威胁。

  • ClamAV 的字节码签名运行时由 LLVM 或自定义字节码解释器提供支持,允许 ClamAV 签名编写器创建和分发非常复杂的检测例程,并远程增强扫描仪功能。

  • 签名数据库确保 ClamAV 将仅执行受信任的签名定义。

  • ClamAV 扫描存档和压缩文件,还可防止存档炸弹。支持几乎所有邮件文件格式。

  • 高级数据更新程序,支持脚本更新、数字签名和基于 DNS 的数据库版本查询。

软件安装

在 CentOS 操作系统上安装 ClamAV,请分别执行以下的命令「其中 clamav 是扫描工具,clamavd 是实时保护服务,clamav-update 是毒库升级工具」

1
2
yum -y install epel-release
yum -y install clamav clamavd clamav-update

在 Ubuntu 操作系统上安装 ClamAV,请分别执行以下的命令「其中 clamav 是扫描工具,clamav-daemon 是实时保护服务」

1
2
apt update
apt -y install clamav clamav-daemon

软件使用

安装完后,我们在扫描签,建议先运行以下命令更新病毒库:

1
freshclam

然后使用下面命令扫描即可「其中-r 是递归扫描,-i 是仅显示被感染文件,/tmp/ 是设置扫描路径,-l /var/log/clamav.log 是保存日志文件位置」需要注意的是,该命令仅扫描病毒,不会删除病毒文件,需 rm 手动删除。

1
clamscan -r -i /tmp/ -l /var/log/clamav.log
  •  

说说广场资源转存至缤纷云

杜老师最近太忙了,平时也是撒手掌柜,很少管理旗下平台,除非遇到问题才会第一时间解决。恰好昨天下午得空看了一下说说广场,没想到超过了百人。图片加载速度好慢,就想着托管到其它平台!

什么是 S3

S3 存储是亚马逊推出的一种对象存储服务。提供了一个高度可扩展、可靠且安全的数据存储解决方案,用于存储和管理各种类型的数据对象,例如文件、图像、视频、文档。

使用了 S3 存储,用户可以通过 API 或与 S3 兼容的工具来上传、下载、检索、管理数据对象。S3 还支持数据版本控制、生命周期管理、数据备份和恢复等功能。

Bitiful 缤纷云

缤纷云的界面是非常简洁的,而且还挺好看,概述页面可以看到资源的使用量:

缤纷云每月会赠送 50G 的存储容量,CDN 流量 10G,API 请求 10 万次。具体费用可见官方文档:

整合说说

下面说说整合过程。首先注册登录到缤纷云,切换到对象存储 AccessKey 页面,点击右侧的添加 Key,根据流程填写对应内容即可:

进入到 Memos 后台,点击设置——存储——创建,参考下图输入相关内容「杜老师做了些调整,如果效果不太理想,可以在评论区留言询问」

使用体验

有一说一,加载速度还是非常快的,毕竟是专业的存储加 CDN。不过并发请求貌似有些问题,每次批量加载都会出现很多请求失败问题。不过还好不影响前端的调用:

  •  

也许您的下一个主机应该是软云

在当今数字化时代,云主机服务成为企业和个人建设网站、部署应用重要选择。然而,面对众多云主机服务商,如何挑选到最适合自己需求的呢?今天,杜老师向小伙伴们推荐一家服务器提供商!

写在前面

一周前杜老师接到一个赞助邀请,是软云的工作人员,赞助杜老师说一台云服务器,说是希望可以帮忙推广一下。

在此之前杜老师也接到过其它服务器提供商的合作邀请,不过他们并没有像软云一样自信,又或者说福利很好。

其它服务器提供商都是扔出一篇软文,然后说首页置顶多少天就给多少钱之类的。杜老师要求先测试一段时间,再发文章之类要求,直接被拒绝了。

软云这边就比较自信了,直接给出一台云服务器,并仅要求挂个链接即可,至于文章的话并没有明确的要求。

当杜老师表示需测试后才会发文等一系列要求,软云这边都表示没问题。

经过一周高强度的性能、稳定性和安全性的测试,杜老师决定发文推荐下软云主机。

性能测试

为了让小伙伴们可以直观的看到服务器的数据,杜老师选了个通用性的测试脚本,运行下面命令即可:

1
wget -qO- bench.sh | bash

测试结果如下「杜老师的主机为定制款,没有出现在套餐列表中。另测速表中删掉了一些境外测试数据」

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
-------------------- A Bench.sh Script By Teddysun -------------------
Version : v2023-10-15
Usage : wget -qO- bench.sh | bash
----------------------------------------------------------------------
CPU Model : Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz
CPU Cores : 8 @ 2294.684 MHz
CPU Cache : 46080 KB
AES-NI : ✓ Enabled
VM-x/AMD-V : ✓ Enabled
Total Disk : 130.9 GB (8.0 GB Used)
Total Mem : 7.8 GB (948.3 MB Used)
Total Swap : 4.0 GB (524.0 KB Used)
System uptime : 4 days, 1 hour 57 min
Load average : 0.02, 0.06, 0.02
OS : Ubuntu 22.04.4 LTS
Arch : x86_64 (64 Bit)
Kernel : 5.15.0-101-generic
TCP CC : cubic
Virtualization : KVM
IPv4/IPv6 : ✓ Online / ✗ Offline
Organization : AS58519 Cloud Computing Corporation
Location : Beijing / CN
Region : Beijing
----------------------------------------------------------------------
I/O Speed(1st run) : 225 MB/s
I/O Speed(2nd run) : 199 MB/s
I/O Speed(3rd run) : 213 MB/s
I/O Speed(average) : 212.3 MB/s
----------------------------------------------------------------------
Node Name Upload Speed Download Speed Latency
Speedtest.net 26.36 Mbps 196.86 Mbps 29.30 ms
Los Angeles, US 28.13 Mbps 87.58 Mbps 204.70 ms
Shanghai, CN 27.72 Mbps 190.41 Mbps 40.78 ms
Singapore, SG 27.79 Mbps 156.85 Mbps 220.28 ms
----------------------------------------------------------------------
Finished in : 8 min 32 sec
Timestamp : 2024-03-24 22:16:17 CST
----------------------------------------------------------------------

配置价格

软云主要提供主机和服务器,节点位于香港和内蒙古,以下是香港主机配置及价格:

以下是内蒙主机配置及价格,年付有八折优惠哦:

扶持活动

软云在 2024 年提供了站长扶持计划,可免费为站长们赞助服务器,所提供的主机可选香港节点或内蒙古节点,主机配置可以协商,可选范围如图:

计划规则以及主机购买地址如下,感兴趣的小伙伴可以去看看:

  •  

PostgreSQL13 升级 14 两种方法

经常会有小伙伴来聊天广场摸鱼,杜老师之前尝试直接更换 PostgreSQL 版本,结果差点导致数据丢失。最近整理了一些 PostgreSQL 版本升级方法,供有需要的小伙伴参考。

pg_upgrade 法

在开始升级前,请确保数据库已经完整备份。这可以通过使用 pg_dump 工具完成。

确保服务器已经安装 PostgreSQL14,包括客户端库。如果服务器上已经安装了 PostgreSQL13,需要先卸载它,然后再安装 PostgreSQL 14。

使用 pg_upgrade 工具来升级数据目录。例如,如果当前的数据目录位于/var/lib/postgresql/13/main,那么升级命令可参考 pg_upgrade -b /var/lib/postgresql/13/main -B /var/lib/postgresql/14/main -d /usr/local/pgsql/14/bin -u postgres

确保使用正确的路径和 PostgreSQL 14 的安装路径。

编辑主配置 postgresql.conf 文件,修改任何可能与新版本不兼容的设置。

使用 PostgreSQL14 启动服务器。

使用 psql 连接到数据库并检查版本信息,确保一切正常。

一旦确认升级成功,可以删除旧版本的数据目录。

pg_dump 法

在升级前,务必备份 PostgreSQL 数据库。可以使用 pg_dump 命令来创建数据库的备份:

1
pg_dump -h localhost -U postgres -Fc -f backup.dump mydb

安装新版本 PostgreSQL:

1
2
sudo apt-get update
sudo apt-get install postgresql-14

升级 PostgreSQL 的数据版本:

1
2
sudo pg_dropcluster --stop 13 main
sudo pg_upgradecluster 13 main

恢复数据:

1
pg_restore -h localhost -U postgres -d mydb backup.dump

删除旧版本 PostgreSQL:

1
sudo apt-get purge postgresql-13

重启 PostgreSQL 的服务:

1
sudo systemctl restart postgresql-14
  •  

Docker 搭建轻量高颜值个人导航页面

最近拜访博客圈的小伙伴时,发现很多博主习惯在主页内加一个导航页。之前杜老师也在纠结是否要添加,其实是因为没找到心仪的导航页。恰好近期在网上闲逛时,发现了这款轻量高颜值的导航页,分享给需要的小伙伴们!

工具介绍

Flare 是一款轻量、快速、美观个人导航页面,适用于 HomeLab 或其它注重私密的场景。

可支持 Docker 一键部署,维护方便。

无任何数据库依赖。应用数据完全开放透明。

支持在线编辑。支持 x86 及常见的 ARM 设备。应用资源消耗很低。

工具特点

服务资源消耗极低,可以跑在任何规格的机器上。

程序页面性能较好,渲染速度更快,支持同时渲染大量书签。

使用声明的配置来进行导航内容管理,无需担心数据迁移问题。

简化了天气数据的获取方式,不再需要申请天气网站的 API_KEY,避免不必要的成本开销。

内置大量风格统一、高质量的矢量图标,确保界面长期耐看。

默认使用免登陆的模式,避免了 HomeLab、本地使用的用户有额外登录操作。

工具部署

启动应用非常简单,如果您习惯使用 Docker,可以执行:

1
docker run -d -p 5005:5005 -v `pwd`/app:/app soulteary/flare

如果您习惯使用 docker-compose,只需要执行 docker-compose up -d

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
version: '3.6'

services:
flare:
image: soulteary/flare
restart: always
# 默认无需添加任何参数,如有特殊需求
# 可阅读文档 https://github.com/soulteary/docker-flare/blob/main/docs/advanced-startup.md
command: flare
# 启用账号登陆模式
# command: flare --nologin=0
# environment:
# 如需开启用户登陆模式,需要先设置 `nologin` 启动参数为 `0`
# 如开启 `nologin`,未设置 FLARE_USER,则默认用户为 `flare`
# - FLARE_USER=flare
# 指定你自己的账号密码,如未设置 `FLARE_USER`,则会默认生成密码并展示在应用启动日志中
# - FLARE_PASS=your_password
# 是否开启“使用向导”,访问 `/guide`
# - FLARE_GUIDE=1
ports:
- 5005:5005
volumes:
- ./app:/app

效果截图

部署完成之后,访问服务器 5005 端口,就能看到下面的界面啦:

在 Flare 启动之后,您可以随时访问/guide,获取 Flare 基础界面功能的介绍:

为满足随时随地编辑的需求,程序新增了在线编辑的页面。地址是/editor

为了减少不必要的地址记忆负担,程序新增一个帮助页面,默认展示所有程序内的工具页面。地址是/help

  •  

又一款开源且炫酷的多功能监控平台

之前为小伙伴们推荐了一款高颜值的监控工具,但其监控维度较少,不符合部分高需求用户。今天为小伙伴们推荐另一款监控工具,不仅可以监控服务器的状态,还可监控各类服务,甚至是应用程序等,感兴趣的小伙伴可点进文章查看。

工具介绍

phoenix 是一个灵活可配置的开源监控平台,主要用于监控应用程序、服务器各参数、容器、各平台数据库、网络、TCP 端口以及 HTTP 接口,通过实时收集、汇聚以及分析监控信息,实现在发现异常时立刻推送告警信息,并且提供了可视化系统进行配置、管理、查看。

工具特点

  1. 可分布式;

  2. 可跨平台;

  3. 可支持 Docker 部署;

  4. 实时监测告警;

  5. 数据加密传输;

  6. 灵活配置;

  7. 用户界面支持 PC 端、移动端等;

  8. 基于 HTTP 接口支持拓展实现监控其它编程语言编写的程序。

监控 UI 端部署

1
docker run -itd -v /tmp:/tmp -v /liblog4phoenix:/liblog4phoenix -v /etc/localtime:/etc/localtime:ro -p 443:443 --pid host --net host --name phoenix-ui phoenix/phoenix-ui /bin/bash

phoenix 服务端部署

1
docker run -itd -v /tmp:/tmp -v /liblog4phoenix:/liblog4phoenix -v /etc/localtime:/etc/localtime:ro -p 16000:16000 --pid host --net host --name phoenix-server phoenix/phoenix-server /bin/bash

phoenix 客户端部署

1
docker run -itd -v /tmp:/tmp -v /liblog4phoenix:/liblog4phoenix -v /etc/localtime:/etc/localtime:ro -p 12000:12000 --pid host --net host --name phoenix-agent phoenix/phoenix-agent /bin/bash

效果截图

  •  

推荐一款超高颜值开源服务器仪表盘

随着互联网技术的飞速发展,服务器已经成为现代社会不可或缺的基础设施。为了保障服务器的稳定运行,我们需对服务器进行有效的监控。传统的服务器监控工具往往功能复杂,配置繁琐,不太友好。今天给大家介绍一个高颜值开源项目,非常适合于个人服务器。

工具介绍

dash.是一款开源的服务器监控工具,旨在为用户提供简洁易用以及功能强大的监控体验。dash.采用 TypeScript 语言开发,可监控服务器的 CPU、内存、磁盘、网络等多种指标及维度。下面是该项目的 GitHub 地址:

工具安装

dash.支持 Docker 一键部署,可参考下面的命令:

1
2
3
4
5
docker container run -it \
-p 80:3001 \
-v /:/mnt/host:ro \
--privileged \
mauricenino/dashdot

如需要监控 GPU 数据,可使用下面的命令部署:

1
2
3
4
5
6
7
docker container run -it \
-p 80:3001 \
-v /:/mnt/host:ro \
--privileged \
--gpus all \
--env DASHDOT_WIDGET_LIST="os,cpu,storage,ram,network,gpu"
mauricenino/dashdot:nvidia

效果截图

dash.白天版页面效果截图,其中显示整体 CPU 使用率:

dash.夜间版页面效果截图,其中显示各核 CPU 使用率:

功能扩展

如有一些自定义的参数设置,可使用下面的代码:

1
2
3
docker container run -it \
--env DASHDOT_ENABLE_CPU_TEMPS="true" \
# ...

全部自定义的参数,可至官网 Wiki 页面中查看:

  •  

Tiny RDM 一个轻量优美的 Redis 客户端

可能在这之前大部分的人一直用的是 RedisDesktopManager 或者是 Redis 的官方可视化工具 RedisInsight 来对 Redis 进行操作和管理。前段时间不经意看到了颜值高且简约的 Redis 可视化工具 Tiny RDM。Tiny RDM 是一个现代化轻量级的跨平台 Redis 桌面客户端。

功能特性

  • 极度轻量,无内嵌浏览器。

  • 界面精美易用,提供浅色/深色主题。

  • 多国语言支持:英文/中文。

  • 更好用的连接管理。

  • 增删查改一应俱全。

  • 支持多种数据查看格式以及转码/解压方式。

  • 轻松处理数百万键列表。

  • 操作命令执行日志展示。

  • 支持命令实时监控。

  • 支持导入/导出数据。

  • 支持发布订阅。

  • 支持导入/导出连接配置。

效果截图

工具支持双语言的切换「中文、英文」默认会根据系统语言自动的切换:

可针对多数据库做查询、修改:

官网地址

Tiny RDM 的官网地址如下,默认为英文的界面,可在右上角切换为中文:

下载地址

Windows 绿色版:

下载地址

苹果系统 X86 架构版:

下载地址

苹果系统 ARM 架构版:

下载地址

DEB 安装包:

下载地址
  •  

YesPlayMusic 高颜值的第三方网易云播放器

之前发布了一篇高颜值的第三方网易云播放器部署教程,但随着版本的更新,原有的版本不可用。前几天刚好一个小伙伴有部署的需求,杜老师就重新编译了下,整理该篇教程,供有需要的小伙伴参考!

特性

  • 使用 Vue.js 全家桶开发。

  • 可扫码登录网易云账号。

  • 可支持 MV 播放。

  • 支持歌词显示。

  • 可支持私人 FM。

  • 每日推荐歌曲。

  • 没有任何社交功能。

  • 每日自动签到。

  • 支持音乐云盘。

  • 自定义快捷键和全局快捷键。

  • 可支持 PWA,在 Chrome/Edge 里点击地址栏右边的安装到电脑。

  • 可支持 Mpris。

部署

杜老师已经将最新版本编程成 Docker 并传至 Docker Hub,可使用下面的命令一键部署。注意-p 8080:80 中的 8080 可自定义,用于访问或者反代:

1
docker run -d --name YesPlayMusic -p 8080:80 penndu/yesplaymusic

如使用 Docker Compose 管理,可以将下面的内容保存为 docker-compose.yml 文件,并通过命令 docker-compose up -d 启动:

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
services:
YesPlayMusic:
image: penndu/yesplaymusic
container_name: YesPlayMusic
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
- ./docker/nginx.conf.example:/etc/nginx/conf.d/default.conf:ro
ports:
- 80:80
restart: always
depends_on:
- UnblockNeteaseMusic
environment:
- NODE_TLS_REJECT_UNAUTHORIZED=0
networks:
my_network:

UnblockNeteaseMusic:
image: pan93412/unblock-netease-music-enhanced
command: -o kugou kuwo migu bilibili pyncmd -p 80:443 -f 45.127.129.53 -e -
# environment:
# JSON_LOG: true
# LOG_LEVEL: debug
networks:
my_network:
aliases:
- music.163.com
- interface.music.163.com
- interface3.music.163.com
- interface.music.163.com.163jiasu.com
- interface3.music.163.com.163jiasu.com
restart: always

networks:
my_network:
driver: bridge

效果

歌词模式:

音乐库的夜间模式:

专辑详情页面:

首页界面:

歌手界面:

搜索界面:

首页页面:

发现界面:

下载

YesPlayMusic 支持 Windows/macOS 等平台客户端,下面是 Windows 版的下载地址:

下载地址
  •  

FileCodeBox 文件快递柜

很多时候,我们都需要将一些文件或文本传送给别人,或者跨端传递一些信息,但我们又不想为了分享,而去下载一些客户端的软件,这个时候,我们就可以使用口令传送箱。

主要特色

  • 轻松上传:复制粘贴,拖拽选择。

  • 多种类型:文本,文件。

  • 防止爆破:错误次数限制。

  • 防止滥用:可针对 IP 限制上传次数。

  • 口令分享:随机口令,存取文件,自定义次数以及有效期。

  • 匿名分享:无需注册,无需登录。

  • 管理面板:查看所有文件,删除文件。

  • 一键部署:可使用 Docker 一键部署。

准备工作

新建一个空白目录:

1
2
mkdir /opt/FileCodeBox
cd /opt/FileCodeBox

在上面的目录中新建一个.env 环境变量文件,将下列字段内容替换成您自己的「如没有新建此文件,将会使用系统默认配置」

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
# 端口
PORT=12345
# Sqlite数据库文件
DATABASE_URL=sqlite+aiosqlite:///database.db
# 静态文件夹
DATA_ROOT=./static
# 静态文件夹URL
STATIC_URL=/static
# 开启上传
ENABLE_UPLOAD=True
# 错误次数
ERROR_COUNT=5
# 错误限制分钟数
ERROR_MINUTE=10
# 上传次数
UPLOAD_COUNT=60
# 上传限制分钟数
UPLOAD_MINUTE=1
# 删除过期文件的间隔(分钟)
DELETE_EXPIRE_FILES_INTERVAL=10
# 管理地址
ADMIN_ADDRESS=admin
# 管理密码
ADMIN_PASSWORD=admin
# 文件大小限制,默认10MB
FILE_SIZE_LIMIT=10
# 网站标题
TITLE=文件快递柜
# 网站描述
DESCRIPTION=FileCodeBox,文件快递柜,口令传送箱,匿名口令分享文本,文件,图片,视频,音频,压缩包等文件
# 网站关键词
KEYWORDS=FileCodeBox,文件快递柜,口令传送箱,匿名口令分享文本,文件,图片,视频,音频,压缩包等文件
# 存储引擎
STORAGE_ENGINE=filesystem

一键部署

一键安装:

1
docker run -d --restart=always -p 12345:12345 -v /opt/FileCodeBox/:/app/data --name filecodebox lanol/filecodebox:beta

一键更新:

1
docker pull lanol/filecodebox:beta && docker stop filecodebox && docker rm filecodebox && docker run -d --restart=always -p 12345:12345 -v /opt/FileCodeBox/:/app/data --name filecodebox lanol/filecodebox:beta

后端地址:

1
/#/admin

后台密码:

1
FileCodeBox2023

效果截图

FileCodeBox 首页效果图:

点击首页左下角的上传图标,可以选择上传文件:

标签切换至文本后,即可粘贴文本:

在后台可对 FileCodeBox 网站名称、描述等配置项进行设置:

在文件管理页面中可对已上传的文件进行管理:

支持日间、夜暗模式切换:

  •  

密码托管服务各平台 APP 分享

为了方便小伙伴的使用,杜老师收集了常见平台的 APP。除正文的安装包外,还有各主流浏览器插件,请有需要的小伙伴自行前往各浏览器应用商店自行下载,如需要代下载某歌浏览器的插件,可在评论区中留言。

Windows 端

Windows 10/11 双平台标准安装程序:

下载地址

单文件免安装版本,可放置优盘中运行,但是需注意不支持自动更新:

下载地址

macOS 端

macOS Mojave 10.14 及更高版本,官方描述支持英特尔和 M 处理器:

下载地址

Linux 端

Linux 仅限 x64 标准安装程序,仅限图形界面:

下载地址

Ubuntu/Debian/Linux Mint 等,但是需注意不支持自动更新:

下载地址

Fedora/CentOS/RHEL/openSUSE 等,但是需注意不支持自动更新:

下载地址

Android 端

该版本为某歌商店转存官方版本,在国内环境不支持自动更新:

下载地址
  •  

杜老师说旗下免费密码托管平台

前端时间和小伙伴聊 LastPass 密码泄露问题,杜老师的宗旨就是数据一定要握在自己的手里,借着之前教程搭建了一个密码的托管平台,自己用着感觉浪费,准备分享出来供需要的小伙伴们一起使用!

平台功能

  • 组织支持。

  • 附件、发送。

  • 支持 Vault API 的功能。

  • 为 Vault 界面提供静态文件。

  • 网站图标 API 的支持。

  • 身份验证器和 U2F 的支持。

  • YubiKey 和 Duo 的支持。

  • 紧急通道。

食用方法

使用浏览器访问 bw.dusays.com,初次使用点击创建账户「该平台为去中心化管理,并没有管理员角色,无需担心杜老师会窃取所托管的密码」

平台使用非验证邮箱作为登录用户名「无需验证邮箱」需要注意的是,平台暂不支持登录密码找回功能,且平台无后台杜老师没办法协助找回,所以一定要记住设置的密码!一定要记住设置的密码!一定要记住设置的密码!

平台支持密码、设备授权登录两种方式,其中设备授权需终端设备安装对应 APP,请在注意事项中找到对应版本的 APP 安装包:

登录平台后点击右上方新增——项目,即可保存密码信息。杜老师推荐安装浏览器插件,可以快速实现密码保存、自动填写功能:

在工具页面中,可以生成高强度的密码「支持指定密码强度」且支持数据的导入、导出:

在报告页面中,可检测暴露的密码、重复使用密码、弱密码等,其余功能可以自行发掘:

注意事项

  1. 为运营该平台,杜老师特地买了台凉心云服务器,服务有效周期一年「至 2025 年 02 月 28 日止」截止日前,请小伙伴们记得导出自己的密码,避免数据丢失;

  2. 服务器到期后,杜老师会根据自己使用,及平台使用情况考虑是否要为服务器续费。但因杜老师看不到后台数据,所以在 2025 年 02 月 21 日时统计平台使用情况;

  3. 平台已做好相关的防护工作,但无法 100% 保障数据安全,毕竟连 LastPass 这种专业平台都出现了密码泄露问题,小伙伴们可以自行选择是否使用平台;

  4. 平台 APP 已适配 Windows/macOS/Linux 等系统,支持各主流浏览器,且支持手机端。如需下载可自行搜索 Bitwarden,下载对应版本即可。也可在评论区留言,杜老师会代下载转存至网盘中再分享出来。

自建脚本

1
docker run -d --name vaultwarden -v /vw-data/:/data/ --restart unless-stopped -p 80:80 vaultwarden/server:latest

注意:如担心杜老师提供平台的稳定性和安全性,也可考虑自行搭建,运行上方命令即可。其中-v /vw-data/:/data//vw-data/为服务器对应的数据存储路径,根据实际情况修改。建议将-p 80:80 修改为-p 40031:8040031 为映射端口,可自行修改成未被占用端口。该容器并未内置 SSL,可使用 Nginx 反向代理实现。

  •  

如何更方便的管理和使用 OSS

当需要快速使用图形化工具上传文件、下载文件、删除文件、设置权限策略等时,可以下载并安装 ossbrowser 工具,使用多种方式登录工具,进行相关操作。希望能对 xaoxuu 童鞋和同样需要的小伙伴提供一些帮助!

安装登录

下载地址:

下载地址

直接解压,找到目录中的 oss-browser.exe 即可打开客户端工具:

快速使用

通过 AK 登录时,需按如下说明完成各配置项:

参数说明
Endpoint选择登录时的访问域名。
AccessKeyId/AccessKeySecret填写账号的 AccessKey 信息。
预设 OSS 路径如果当前账号仅拥有某个 Bucket 或 Bucket 下某个路径的权限,需填写预设 OSS 路径。
区域当 Endpoint 配置为默认时,需填写预设 OSS 路径对应 Bucket 所在的区域。
保持登录选中之后,ossbrowser 会保持登录状态,下次打开时将自动登录。
记住密钥选中可保存 AK 密钥。再次登录时单击 AK 历史,可选指定密钥直接登录。

ossbrowser 支持的 Bucket 或 Object 级别的操作与控制台支持操作类似,请按照 ossbrowser 界面指引完成 Bucket 或 Object 的相关操作:

操作说明
创建BucketBucket 是用于存储 Object 的容器。在上传任何文件到 OSS 前,必须创建存储空间。
删除Bucket如果不再需要 Bucket 请将其删除,以免产生额外费用。
上传文件ossbrowser 默认使用分片上传和断点续传上传文件,上传文件最大不可以超过 48.8T。若因意外中断了文件上传的过程,且未继续完成该文件的上传,则已上传的部分会以碎片的形式存储在 OSS 的存储空间中。
上传文件夹单击页面上方目录图标,可上传文件夹。
下载文件选中文件,然后单击操作列的下载进行下载。
下载文件夹先选中文件夹,然后单击页面上方下载图标进行下载。
预览文件直接单击文件名称进行预览。
复制文件在 Bucket1 选中文件单击复制,然后在 Bucket2 单击粘贴。
移动文件选中更多——移动进行操作。移动或复制文件最大不能超过 5G。
分享文件文件上传 Bucket 后,可以将文件 URL 分享给第三方,供其下载、预览。单击目标文件操作列的获取地址,生成文件分享地址。
设置软链接在设置软链接面板,设置软链接的文件目录,然后单击确定。
  •  

基于 Python 的站点漏洞扫描工具

Golden-hooped Rod 是一款对于 Web 站点进行漏洞扫描的工具。工具用 Python 语言编写,使用目录扫描字典均由真实环境而来。使用起来异常便捷。可以对 Web 站点进行漏洞扫描、设置代理、设置线程等等。

安装方法

下载地址:

下载地址

解压后使用 Python 运行里面的 GHR.py 文件即可,在运行前请先使用下面命令安装依赖模块:

1
pip install -r requirements.txt

使用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
usage: GHR.py [-h] [-u URL] [-f filename] [--upgrade] [--nodir] [--proxy PROXY] [-t THREAD]

options:
-h, --help show this help message and exit

GHR 常用参数:
-u URL, --url URL url,例:--url http://127.0.0.1/,注:url中不能添加文件名,如index.html、index.php等,如需添加文件名,请禁用目录扫描
-f file, --file file 批量url文件名,例:--file url.txt,注:文件中的url不能添加文件名,如index.html、index.php等,如需添加文件名,请禁用目录扫描
--nodir 禁用目录扫描
--upgrade 更新
--proxy PROXY 代理设置,例:--proxy 127.0.0.1:10809(目前仅支持HTTP,暂不支持SOCKET)
-t THREAD, --thread THREAD
线程设置,例:--thread 10 默认线程数为:20

注意:直接运行 python GHR.py 会显示帮助信息,如果扫描站点,如 dusays.com,命令为 python GHR.py -u https://dusays.com/

运行效果

扫描执行过程如下截图:

报告截图

扫描执行结束后会生成报告文档,效果如下截图:

  •  

ShellCheck 静态代码分析的工具

ShellCheck 是一个用于静态代码分析工具,其专门针对 Shell 脚本语言进行检查。它可以帮助用户发现并纠正脚本中的常见问题、潜在错误和最佳实践不一致。新手必备工具,老手也经常通过该工具进行脚本排错。

功能特点

ShellCheck 可以检查 Shell 脚本语法,确保脚本中的命令、语法结构和语法规则的正确。可以识别和报告脚本中的各种错误,包括语法错误、拼写错误、变量使用错误、命令调用错误等等。

ShellCheck 提供了最佳实践建议,帮助用户编写更加清晰、可读性更高的脚本,避免常见的陷阱和错误。

ShellCheck 支持在多种操作系统运行,并支持各种常见的 Shell 解释器。

ShellCheck 允许用户定义自定义规则和过滤器,以适应特定项目或组织需求。

检查内容

  • 语法错误、警告。

  • 变量使用错误。

  • 命令调用错误。

  • 输入、输出错误。

  • 安全漏洞。

  • 代码风格建议。

安装步骤

如果是 Debian/Ubuntu 系统,执行以下命令:

1
apt -y install shellcheck

如果是 CentOS/RHEL 系统,执行以下命令:

1
2
yum -y install epel-release
yum -y install shellcheck

使用方法

1
shellcheck shell.sh

注意:对于一个 Shell 脚本 shell.sh 进行检查,则按上面命令执行即可。ShellCheck 将输出检查结果,并提示错误和建议,帮助用户改进脚本质量。

  •  

一台服务器最大能支持多少条 TCP 连接

这段时间频繁出现图床无法访问,之前为了防护攻击,杜老师选购了高防的服务器,奈何除流量攻击外,还有连接数的攻击形式。而杜老师为了保障服务稳定,将连接数设置较低。本篇文章就简单说明下一台服务器最大能支持多少条 TCP 连接。

一台服务器最大能打开的文件数

我们知道在 Linux 中一切皆文件,那么一台服务器最大能打开多少个文件呢?Linux 上能打开最大文件数量受三个参数影响,分别是 fs.file-max/soft nofile/fs.nr_open。

fs.file-max 参数描述了整个系统可以打开最大文件数量。但是 root 用户不会受该参数的限制。

soft nofile 限制单个进程上可以打开的最大文件数。不能针对不同用户配置不同的值。

fs.nr_open 限制单个进程上可以打开的最大文件数。可以针对不同用户配置不同的值。

如果想加大 soft nofile,那么 hard nofile 参数值也需一起调整。如果因为 hard nofile 参数值设置的低,那么 soft nofile 参数的值设置的再高也没有用,实际生效的值会按照二者最低来。

如果增大了 hard nofile,那么 fs.nr_open 也需要跟着一起调整。如果不小心把 hard nofile 的值设置的比 fs.nr_open 还大,那么后果比较严重。会导致该用户无法登录。

一台服务器最大能支持多少连接

我们知道 TCP 连接从根本上看其实就是客户端和服务端在内存中维护的一组内核对象,它们只要能够找到对方,那就算是一条连接。那么一台服务器最大能建立多少条连接呢?

从理论上应该是约等于两百多万亿条连接。

但是实际上由于受其它软硬件的影响,我们一台服务器不可能能建立这么多连接。

如果只以已连接状态的连接来算,那么一台服务器最大可以建立多少连接呢?以一台 4G 内存的服务器为例!

我们知道一条已连接状态的连接大约消耗 3.3K 的内存,那么通过计算可得知一台 4G 内存的服务器,可以建立百万个 TCP 连接。

上面讨论的都是建立连接的理想情况,在现实中如果有频繁的数据收发,那么一台服务器能支撑 1000 连接都算好的了,所以一台服务器能支撑多少连接还要结合具体的场景去分析。抛开业务逻辑单纯的谈并发没有太大实际意义。

一台客户端机器最多能发起多少连接

我们知道客户端每和服务端建立一个连接便会消耗掉客户端一个端口。一台机器端口数量是 65535,那么是不是说一台客户机最多和一台服务端机器建立 65535 个连接呢?

由 TCP 连接的四元组特性可知,只要四元组里某个元素不同,那就认为这是不同的 TCP 连接。

如果一台客户端仅有一个 IP,服务端也仅有一个 IP 并且仅启动一个程序,监听一个端口的情况下,客户端和这台服务端最大可建立连接条数就是 65535 个。

如一台客户端有多个 IP,服务端仅有一个 IP 并仅启动一个程序,监听一个端口的情况下,一台客户端机器最大能建立的连接条数是 n*65535 个。

如果一台客户端仅有一个 IP,服务端也仅有一个 IP 但是服务端启动多个程序,每个程序监听一个端口的情况下,一台客户端机器最大能建立的连接数量为 65535*m 个

所以,不光是一台服务端可以接收百万个 TCP 连接,一台客户端照样能发出百万个 TCP 连接。

优化 TCP 连接数策略

在网络开发中,很多人对一个基础的问题始终没有彻底搞明白,那就是一台机器最多能支撑多少条 TCP 连接。不过由于客户端和服务端对端口使用方式不同,这个问题拆开来理解要容易一些。

注意,这里说的客户端和服务端都只是角色,并不是指某一台具体的机器。如对于我们自己开发的应用程序来说,当它响应客户端请求的时候,它就是服务端。当向 MySQL 请求数据的时候,它又变成了客户端。

增加服务器的内存可以支持更多的 TCP 连接。

优化 CPU 调度可以提高服务器性能,从而支持更多的 TCP 连接。

通过修改系统的文件描述符限制,可以提高服务器支持的 TCP 连接数。

优化网络配置可以提高服务器网络带宽,从而支持更多的 TCP 连接。

  •  

9 个实用的 Shell 脚本

好久没更新了,实在不知道写点什么好,就在网上找了一些资源。正文是杜老师整理的 9 个实用 Shell 脚本,供有需要的小伙伴参考。需要注意的是,这些脚本为杜老师收集,并没有测试过,小伙伴们使用之前要先测试。

写在最前

常来的小伙伴应该发现杜老师说近两周没有更新了,过年期间确实有太多的事情需要处理,各种亲戚走动等等。目前已经处理差不多了,工作上的节奏也已慢慢稳定,近期开始补上之前拖更文章。开头也祝愿来访的小伙伴们龙年大吉,博客访问蒸蒸日上,身体和服务器健健康康,心想和收入皆遂意!

DoS 攻击防范自动屏蔽攻击 IP

1
2
3
4
5
6
7
8
9
10
#!/bin/bash
DATE=$(date +%d/%b/%Y:%H:%M)
LOG_FILE=/usr/local/nginx/logs/demo2.access.log
ABNORMAL_IP=$(tail -n5000 $LOG_FILE | grep $DATE | awk '{a[$1]++}END{for(i in a)if(a[i]>10)print i}')
for IP in $ABNORMAL_IP; do
if [ $(iptables -vnL | grep -c "$IP") -eq 0 ]; then
iptables -I INPUT -s $IP -j DROP
echo "$(date +'%F_%T') $IP" >>/tmp/drop_ip.log
fi
done

Linux 系统发送告警邮件的脚本

1
2
3
4
5
# yum install mailx
# vi /etc/mail.rc
set from=baojingtongzhi@163.com smtp=smtp.163.com
set smtp-auth-user=baojingtongzhi@163.com smtp-auth-password=123456
set smtp-auth=login

MySQL 数据库的单循环备份

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash
DATE=$(date +%F_%H-%M-%S)
HOST=localhost
USER=backup
PASS=123.com
BACKUP_DIR=/data/db_backup
DB_LIST=$(mysql -h$HOST -u$USER -p$PASS -s -e "show databases;" 2>/dev/null | egrep -v "Database|information_schema|mysql|performance_schema|sys")

for DB in $DB_LIST; do
BACKUP_NAME=$BACKUP_DIR/${DB}_${DATE}.sql
if ! mysqldump -h$HOST -u$USER -p$PASS -B $DB >$BACKUP_NAME 2>/dev/null; then
echo "$BACKUP_NAME 备份失败!"
fi
done

MySQL 数据库的多循环备份

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash
DATE=$(date +%F_%H-%M-%S)
HOST=localhost
USER=backup
PASS=123.com
BACKUP_DIR=/data/db_backup
DB_LIST=$(mysql -h$HOST -u$USER -p$PASS -s -e "show databases;" 2>/dev/null | egrep -v "Database|information_schema|mysql|performance_schema|sys")

for DB in $DB_LIST; do
BACKUP_DB_DIR=$BACKUP_DIR/${DB}_${DATE}
[ ! -d $BACKUP_DB_DIR ] && mkdir -p $BACKUP_DB_DIR &>/dev/null
TABLE_LIST=$(mysql -h$HOST -u$USER -p$PASS -s -e "use $DB;show tables;" 2>/dev/null)
for TABLE in $TABLE_LIST; do
BACKUP_NAME=$BACKUP_DB_DIR/${TABLE}.sql
if ! mysqldump -h$HOST -u$USER -p$PASS $DB $TABLE >$BACKUP_NAME 2>/dev/null; then
echo "$BACKUP_NAME 备份失败!"
fi
done
done

Nginx 的访问日志按天切割

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
LOG_DIR=/usr/local/nginx/logs
YESTERDAY_TIME=$(date -d "yesterday" +%F)
LOG_MONTH_DIR=$LOG_DIR/$(date +"%Y-%m")
LOG_FILE_LIST="default.access.log"

for LOG_FILE in $LOG_FILE_LIST; do
[ ! -d $LOG_MONTH_DIR ] && mkdir -p $LOG_MONTH_DIR
mv $LOG_DIR/$LOG_FILE $LOG_MONTH_DIR/${LOG_FILE}_${YESTERDAY_TIME}
done

kill -USR1 $(cat /var/run/nginx.pid)

Nginx 访问日志的分析脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
#日志格式: $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"
LOG_FILE=$1
echo "统计访问最多的 10 个 IP"
awk '{a[$1]++}END{print "UV:",length(a);for(v in a)print v,a[v]}' $LOG_FILE | sort -k2 -nr | head -10
echo "----------------------"

echo "统计时间段访问最多 IP"
awk '$4>="[01/Dec/2018:13:20:25" && $4<="[27/Nov/2018:16:20:49"{a[$1]++}END{for(v in a)print v,a[v]}' $LOG_FILE | sort -k2 -nr | head -10
echo "----------------------"

echo "统计访问最多 10 个页面"
awk '{a[$7]++}END{print "PV:",length(a);for(v in a){if(a[v]>10)print v,a[v]}}' $LOG_FILE | sort -k2 -nr
echo "----------------------"

echo "统计访问页面状态码的数量"
awk '{a[$7" "$9]++}END{for(v in a){if(a[v]>5)print v,a[v]}}'

查看网卡实时流量脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash
NIC=$1
echo -e " In ------ Out"
while true; do
OLD_IN=$(awk '$0~"'$NIC'"{print $2}' /proc/net/dev)
OLD_OUT=$(awk '$0~"'$NIC'"{print $10}' /proc/net/dev)
sleep 1
NEW_IN=$(awk '$0~"'$NIC'"{print $2}' /proc/net/dev)
NEW_OUT=$(awk '$0~"'$NIC'"{print $10}' /proc/net/dev)
IN=$(printf "%.1f%s" "$((($NEW_IN - $OLD_IN) / 1024))" "KB/s")
OUT=$(printf "%.1f%s" "$((($NEW_OUT - $OLD_OUT) / 1024))" "KB/s")
echo "$IN $OUT"
sleep 1
done

服务器系统配置初始化脚本

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
#/bin/bash
#设置时区同步时间
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
if ! crontab -l | grep ntpdate &>/dev/null; then
(
echo "* 1 * * * ntpdate time.windows.com >/dev/null 2>&1"
crontab -l
) | crontab
fi

#禁用 SELinux 防火墙
sed -i '/SELINUX/{s/permissive/disabled/}' /etc/selinux/config

#关闭各版本防火墙
if egrep "7.[0-9]" /etc/redhat-release &>/dev/null; then
systemctl stop firewalld
systemctl disable firewalld
elif egrep "6.[0-9]" /etc/redhat-release &>/dev/null; then
service iptables stop
chkconfig iptables off
fi

#历史命令显示操作时间
if ! grep HISTTIMEFORMAT /etc/bashrc; then
echo 'export HISTTIMEFORMAT="%F %T `whoami` "' >>/etc/bashrc
fi

#SSH 的超时时间
if ! grep "TMOUT=600" /etc/profile &>/dev/null; then
echo "export TMOUT=600" >>/etc/profile
fi

#禁止 root 的远程登录
sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config

#禁止定时任务发送邮件
sed -i 's/^MAILTO=root/MAILTO=""/' /etc/crontab

#设置最大打开的文件数
if ! grep "* soft nofile 65535" /etc/security/limits.conf &>/dev/null; then
cat >>/etc/security/limits.conf <<EOF
* soft nofile 65535
* hard nofile 65535
EOF
fi

#系统内核优化
cat >>/etc/sysctl.conf <<EOF
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_tw_buckets = 20480
net.ipv4.tcp_max_syn_backlog = 20480
net.core.netdev_max_backlog = 262144
net.ipv4.tcp_fin_timeout = 20
EOF

#减少 Swap 的使用
echo "0" >/proc/sys/vm/swappiness

#安装系统性能分析工具
yum install gcc make autoconf vim sysstat net-tools iostat if

监控 100 台服务器磁盘利用率脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/bash
HOST_INFO=host.info
for IP in $(awk '/^[^#]/{print $1}' $HOST_INFO); do
USER=$(awk -v ip=$IP 'ip==$1{print $2}' $HOST_INFO)
PORT=$(awk -v ip=$IP 'ip==$1{print $3}' $HOST_INFO)
TMP_FILE=/tmp/disk.tmp
ssh -p $PORT $USER@$IP 'df -h' >$TMP_FILE
USE_RATE_LIST=$(awk 'BEGIN{OFS="="}/^\/dev/{print $NF,int($5)}' $TMP_FILE)
for USE_RATE in $USE_RATE_LIST; do
PART_NAME=${USE_RATE%=*}
USE_RATE=${USE_RATE#*=}
if [ $USE_RATE -ge 80 ]; then
echo "Warning: $PART_NAME Partition usage $USE_RATE%!"
fi
done
done
  •  

Fort Firewall 开源免费防火墙工具

Fort Firewall 是一款简单而功能丰富的开源 Windows 防火墙工具,当前互联网环境下,很多人依赖于 Windows 防火墙或路由器来维护个人隐私和系统安全。Fort Firewall 提供了对 Windows 防火墙进行简便修改的功能。

运行截图

主界面支持明暗双模式切换:

可针对单应用设置网络控制,保护应用同时,也可限制应用对带宽的占用:

可以设置应用群组,方便快速管理组内所有应用:

支持多国语言,翻译准确:

软件特点

  1. 安装配置:

Fort Firewall 软件安装和配置非常简单,可在几分钟内完成。在安装过程中,软件会提示用户选择所需保护功能和设置,可按照自己的需求进行配置。

  1. 防护安全:

该软件提供了强大的防火墙保护功能,可对入站和出站数据进行监控和过滤,防止未经授权的访问和攻击。

  1. 应用控制:

Fort Firewall 软件支持对应用程序进行控制、管理,可限制应用程序的网络访问权限,防止恶意应用程序对计算机造成损害。

  1. 网络监控:

该软件提供了实时网络监控功能,可监控网络流量和连接状态,并提供详细统计数据和报告,方便用户进行网络管理、优化。

  1. 用户界面:

Fort Firewall 软件的用户界面简洁明了,易于使用。软件提供了多种操作选项和设置,可满足用户的不同需求。

工具下载

下载地址:

下载地址

写在最后

通过免费下载 Fort Firewall 独立 Windows 脱机安装程序,用户可轻松管理防火墙设置。该防火墙工具旨在为用户提供简单而有效防护,具备多项丰富功能。Fort Firewall 的中文版发布使更多用户能够方便地利用其功能,以加强系统的安全性和隐私管理。

Fort Firewall 防火墙是一款小巧优秀的软件,用户可在 Fort Firewall 防火墙快捷的进行网络安全的防护,有效的预防病毒的侵害,同时还可以在 Fort Firewall 防火墙很好的进行网络的管理,保护电脑上的应用程序不被改写,感兴趣的小伙伴快来下载体验吧~

  •  

通过 OpenSSL 生成 SSL 证书

随着互联网技术发展和普及,网络安全问题日益突出。SSL 证书作为一种有效的网络安全解决方案,可以确保数据在传输过程中的保密性和完整性。OpenSSL 是一个开源 SSL 工具包,它可用于生成和管理 SSL 证书。本文详细说明如何使用 OpenSSL 生成 SSL 证书,并提供详细的操作步骤。

生成 RSA 密钥对

1
openssl genrsa -out key.pem 2048

注意:要生成 RSA 密钥对可使用以下命令,这个命令将生成一个 2048 位的 RSA 密钥对,并将其保存在 key.pem 文件中。

生成 DSA 密钥对

1
openssl dsaparam -out dsa.pem 2048

注意:要生成 DSA 密钥对可使用以下命令,这个命令将生成一个 2048 位的 DSA 密钥对,并将其保存在 dsa.pem 文件中。

生成证书请求

1
openssl req -new -key key.pem -out cert.csr

注意:生成密钥对后下一步是生成证书请求。证书请求文件将包含公钥和其他信息,这些信息被 CA 用于验证证书请求。要生成证书请求可使用上面命令,这个命令生成一个证书请求文件,并将其保存在 cert.csr 文件中。在生成过程中,您需提供一些信息,例如国家代码、城市、组织名称、组织单位名称等等。

签署证书

1
openssl x509 -req -in cert.csr -signkey key.pem -out cert.pem

注意:生成证书请求后最后一步是签署证书。签署证书是将证书请求与密钥对结合起来,生成一个完整的 SSL 证书。要签署证书可使用上面命令,这个命令将生成一个 X.509 格式证书文件,并将其保存在 cert.pem 文件中。

  •  

MySQL 预编译语句

MySQL 预编译语句是一种强大的工具,它不仅提高了应用程序性能,还提升数据安全性。本文将深入探讨 MySQL 预编译语句的原理、优势及如何在实际应用中有效地使用它们。

简介

预编译语句也被称为参数化查询,是一种在数据库层面处理 SQL 语句方法。

它允许开发者在编译时将 SQL 语句中参数值替换为占位符,然后在运行时再将实际的参数值传递给数据库。

原理

预编译语句的工作原理分为两个阶段:编译阶段、执行阶段。

在编译阶段时,MySQL 将 SQL 语句进行语法分析和优化,生成对应执行计划。

在执行阶段是,MySQL 根据执行计划执行 SQL 语句,并将结果返回给客户端。

以此提升执行效率。

优势

  1. 提高安全:预编译语句可以防止 SQL 注入攻击,这是一种常见安全漏洞,攻击者可以利用它修改或删除数据库中的数据。通过用预编译语句,开发者可以确保所有 SQL 语句在编译时都已经过验证,从而防止 SQL 的注入攻击。

  2. 提升性能:预编译语句可以显著提高应用程序的性能。当相同 SQL 语句被多次执行时,预编译语句可以重用编译后的 SQL 语句,从而节省编译时间。此外,预编译语句还可减少 SQL 解析器的负担,进一步提高 MySQL 性能。

  3. 简化代码:使用预编译语句可简化 SQL 语句的编写,特别是在处理动态 SQL 语句时。开发者可将参数值直接传递给预编译语句,而无需手动拼接 SQL 语句,从而降低出错的可能性。

使用

1
2
3
4
String sql = "SELECT * FROM users WHERE id = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, id);
ResultSet rs = ps.executeQuery();

注意:在这个示例中,我们首先定义了一个 SQL 语句,然后通过 prepareStatement 方法创建一个预编译语句。紧接着我们通过 setInt 方法将参数值传递给预编译语句,最后执行查询并获取结果集。

  •  

MySQL 如何启用 SSL 加密连接

MySQL 是一种流行的开源数据库管理系统,广泛应用于各种 Web 应用程序和数据存储中。然而,传统的 MySQL 连接在传输数据时并未加密,可能存在安全风险。启用 SSL 加密连接可确保数据在传输过程中的安全性和完整性。本文详细说明如何在 MySQL 中启用 SSL 加密连接。

准备工作

SSL 是一种被广泛使用的网络协议,用于在客户端和服务器之间建立安全通信通道。通过使用 SSL 可以确保传输的数据不被第三方窃听或篡改。启用 SSL 加密连接第一步是准备 SSL 证书。SSL 证书由可信证书颁发机构签发,用于验证服务器的身份。您可以从 CA 购买 SSL 证书,也可使用 OpenSSL 等工具自行生成。

在开始启用 SSL 之前,需要确保 MySQL 服务器和客户端已经安装了 SSL 模块。如果您使用的是 MySQL 二进制包,那么可能已经安装了 SSL 模块。如果您使用的是源码包,则需手动编译并安装 SSL 模块。

安装证书

将 SSL 证书安装到 MySQL 服务器上。通常,您需要将 SSL 证书和私钥文件复制到 MySQL 服务器的指定目录,如 /etc/mysql/ssl

编辑 MySQL 服务器配置文件,以启用 SSL 并指定 SSL 证书和私钥文件的路径。

配置示例

以下是一个 SSL 示例配置:

1
2
3
4
[mysqld]
ssl-ca=/etc/mysql/ssl/ca.pem
ssl-cert=/etc/mysql/ssl/server-cert.pem
ssl-key=/etc/mysql/ssl/server-key.pem

以下是 SSL 配置参数说明:

参数说明
ssl-caCA 证书的路径
ssl-cert服务器证书的路径
ssl-key服务器私钥的路径

重启测试

保存 MySQL 配置文件后,重启 MySQL 服务以应用新的配置。在 Linux 系统中可以使用以下命令重启 MySQL 服务:

1
sudo systemctl restart mysql

在配置完成后,您可以使用 mysql 命令行工具测试 SSL 连接。要启用 SSL 连接,您可以使用--ssl-ca, --ssl-cert--ssl-key 选项。以下是一个测试 SSL 连接示例:

1
mysql --host=localhost --port=3306 --user=root --password=your_password --ssl-ca=ca.pem --ssl-cert=server-cert.pem --ssl-key=server-key.pem

验证连接

测试 SSL 连接无误后,您可以在 MySQL 服务器中启用 SSL。要启用 SSL,您需要在 my.ini 配置文件中添加以下参数:

1
2
require_secure_transport=ON
ssl=ON

要验证 SSL 连接是否成功启用,您可在 MySQL 命令行工具中输入以下命令:

1
SHOW STATUS LIKE 'Ssl_cipher';

结果总结

如果看到类似以下输出,则表示 SSL 连接已经启用:

1
2
3
4
5
+--------------------+--------------------------------------------------------------+
| Variable_name | Value |
+--------------------+--------------------------------------------------------------+
| Ssl_cipher | DHE-RSA-AES256-GCM-SHA384 |
+--------------------+--------------------------------------------------------------+

启用 MySQL 的 SSL 加密连接可有效提高数据传输的安全性。我们建议您在生产环境中始终启用 SSL,以确保数据安全性。最后分享一个 OpenSSL 创建公私秘钥的示例:

1
2
openssl genrsa -out rsa_private.key 2048
openssl rsa -in rsa_private.key -pubout -out rsa_public.key
  •  

GoBackup 数据库备份工具

上一篇杜老师分享了 MySQL 备份脚本,在留言中,有小伙伴推荐了 GoBackup 数据库备份工具。简单了解之后发现这款工具确实不错,简单易用,一次部署后能持续运行数年无需任何维护,存储成本低且安全可靠。

工具特性

  • 没有依赖关系。

  • 多数据库支持。

  • 支持多种存储类型。

  • 将路径或文件归档到压缩包。

  • 将大型备份文件拆分为多个部分。

  • 作为守护程序运行以按计划进行备份。

  • 用于管理备份的 Web UI。

支持类型

支持的数据库类型如下:

编号名称
1MySQL
2PostgreSQL
3Redis
4MongoDB
5SQLite
6Microsoft SQL Server
7InfluxDB
8MariaDB

存储类型

支持存储类型如下:

编号名称
1本地
2FTP
3SFTP
4SCP - Upload via SSH copy
5Amazon S3
6Aliyun OSS
7Google Cloud Storage
8Azure Blob Storage
9Backblaze B2 Cloud Storage
10Cloudflare R2
11DigitalOcean Spaces
12QCloud COS
13UCloud US3
14Qiniu Kodo
15Baidu BOS
16MinIO
17Huawei OBS
18Volcengine TOS
19UpYun
20WebDAV

通知途径

备份通知类型如下:

编号名称
1Mail (SMTP)
2Webhook
3Discord
4Slack
5Feishu
6DingTalk
7GitHub (Comment on Issue)
8Telegram
9AWS SES
10Postmark
11SendGrid

安装配置

执行下面安装命令,即可使用 gobackup 进行数据库备份:

1
curl -sSL https://gobackup.github.io/install | sh

创建并编辑配置文件/etc/gobackup/gobackup.yml,模板内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
models:
gitlab_app:
databases:
gitlab_db:
type: postgresql
database: gitlab_production
username: gitlab
password:
gitlab_redis:
type: redis
mode: sync
rdb_path: /var/db/redis/dump.rdb
invoke_save: true
storages:
s3:
type: s3
bucket: my_app_backup
region: us-east-1
path: backups
access_key_id: $S3_ACCESS_KEY_Id
secret_access_key: $S3_SECRET_ACCESS_KEY
compress_with:
type: tgz

使用方法

如需备份,使用下面命令即可:

1
gobackup perform

如需命令完整路径,可调用/usr/local/bin/gobackup。分享一个实例配置文件:

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
models:
my_backup:
before_script: |
echo "Before script"
after_script: |
echo "After script"
schedule:
# At 04:05 on Sunday.
cron: "5 4 * * sun"
storages:
local:
type: local
path: /path/to/backups
databases:
mysql:
type: mysql
host: localhost
port: 3306
database: my_database
username: root
password: password
other_backup:
# At 04:05 on every day.
schedule:
every: "1day",
at: "04:05"
storages:
local:
type: local
path: /path/to/backups
databases:
mysql:
type: mysql
host: localhost
port: 3306
database: my_database
username: root
password: password

该工具支持 Web UI,如需启动可执行下面的命令:

1
gobackup start

访问 http://IP:2703 就行了:

  •  

MySQL 数据库备份脚本参考分享

在之前的文件中杜老师推荐了两款云主机面板,有小伙伴留言说因服务器配置比较低,未使用云主机面板,一直为数据库备份问题困扰。杜老师之前工作的环境也是没有面板,编写过相关的备份脚本,在此文中分享给需要的小伙伴们~

设置环境变量

1
2
3
4
5
6
#!/bin/bash
# Setup environment variables
export MYSQL_HOST=localhost
export MYSQL_PORT=3306
export MYSQL_USER=root
export MYSQL_PASSWORD=your_password

注意:需要设置环境变量,以便脚本可以找到 MySQL 数据库。在脚本中,添加以上内容。

创建备份目录

1
2
3
4
5
6
# Create backup directory
BACKUP_DIR=/path/to/backup/directory
# Check if backup directory exists
if [ ! -d "$BACKUP_DIR" ]; then
mkdir -p "$BACKUP_DIR"
fi

注意:创建一个目录,以存储备份的文件。在脚本中,添加以上内容。

备份 MySQL 数据库

1
2
3
4
# Backup database
DATABASE_NAME=your_database_name
BACKUP_FILE="$BACKUP_DIR/$DATABASE_NAME-$(date +"%Y-%m-%d_%H-%M-%S").sql"
mysqldump -u $MYSQL_USER -p$MYSQL_PASSWORD --host=$MYSQL_HOST --port=$MYSQL_PORT $DATABASE_NAME > "$BACKUP_FILE"

注意:使用 mysqldump 命令备份数据库。在脚本中,添加以上内容。

检查备份是否成功

1
2
3
4
5
6
7
# Check if backup file exists
if [ -f "$BACKUP_FILE" ]; then
echo "Backup completed successfully!"
else
echo "Backup failed!"
exit 1
fi

注意:检查备份文件是否创建。在脚本中,添加以上内容。

压缩备份文件

1
2
3
4
5
# Compress backup file
COMPRESSED_BACKUP_FILE="$BACKUP_FILE".gz
gzip "$BACKUP_FILE"
# Remove original backup file
rm "$BACKUP_FILE"

注意:为了节省空间,可使用 gzip 命令压缩备份文件。在脚本中,添加以上内容。

删除 MySQL 旧备份

1
2
3
4
5
# Remove old backups
OLD_BACKUPS=$(ls -t "$BACKUP_DIR" | tail -n +7)
if [ ! -z "$OLD_BACKUPS" ]; then
rm "$BACKUP_DIR/$OLD_BACKUPS"
fi

注意:删除旧备份文件以节省空间。在脚本中,添加以上内容。

设置定时任务

最后,可使用 crontab 命令设置定时任务,以便脚本定期运行。在终端中输入以下命令:

1
crontab -e

在打开的编辑器中,添加以下行的内容,比如以每天凌晨的一点运行脚本。保存并退出编辑器:

1
0 1 * * * /path/to/your/backup_script.sh

还有哪些开源工具

除上面脚本外,还有一些开源「有商业版」工具也可实现 MySQL 数据库备份,供需要的小伙伴们参考选择:

名称描述
mysqldumpmysqldump 是 MySQL 官方提供的备份工具,可将 MySQL 数据库的数据和结构导出为 SQL 文件。
XtraBackupXtraBackup 是一个 Percona 提供的备份工具,可在线备份 MySQL 数据,提供增量备份、压缩功能。
Zmanda Recovery ManagerZmanda Recovery Manager 是一款商业的备份和恢复解决方案,可支持 MySQL 和其它数据库。提供完整备份、增量备份、多种存储介质、自动化备份和恢复等功能。
mydumpermydumper 是一个 MySQL 官方派生的高性能 MySQL 备份工具,支持并行备份,可更快地备份大型 MySQL 数据库。
  •  

推一下 Vercel 加速节点

杜老师说友链中不少小伙伴都使用 Hexo 构建博客,其中大多数都选择托管在 Vercel。虽然选择了香港的节点,当访问的速度依旧不太理想。今天推荐加速节点使用方法,欢迎一试!

写在前面

Vercel 不仅可以部署 Hexo 博客,还能部署很多服务。

如本博的「文坛」就托管在 Vercel 上。

境内选择 Vercel 的站长很多,为了提升访问速度,自然选择了距离大陆最近的香港节点。

选的多了,节点压力自然就会增大,就算 Vercel 属于大平台,对陆带宽依旧有限,必然会出现互相影响的情况。

再加上滥用资源等问题出现,不少小伙伴反馈 Vercel 越来越慢。

今天为 Vercel 用户提供一个加速方案。

食用方法

将原来解析至 cname.vercel.com 改为 vercel.cdn.yt-blog.top「杜老师用的是另外一个,所以截图中的解析不同,但是加速效果相同」

加速原理

Vercel 在大陆周围还有很多节点,其中包含中国台湾、韩国、日本、新加坡等,这些节点的访问延迟在接受范围,且相对香港节点来说带宽更充足。

Vercel 的 Anycast 会自动将节点解析至距离最近的香港服务器,但如果手动解析则太过麻烦。

vercel.cdn.yt-blog.top 是 Fgaoxing 小朋友手动解析,并通过 D 监控检查状态,无法访问时会及时暂停节点。使用时自动解析至附近可用节点,尽可能的选择优质节点。

最终数据会回源至自己的 Vercel,所以不用担心数据安全。这项服务非杜老师提供,所以要注意稳定性。

测速截图

感谢 Fgaoxing 小朋友提供该项服务及测速效果图,大家测速效果可能会略有些不同,可酌情考虑是否选择该服务:

  •  

云主机的控制面板选择推荐

多年运营网站,接触了很多的控制面板,有国内有国外、有免费有收费。上篇文中有小伙伴留言询问,推荐用宝塔还是 1Panel,今天简单推荐一下。非专业性测评,仅供参考~

写在前面

杜老师从 03 年开始接触网站搭建,最开始的站点运营在 SaaS 上面「类似于 QQ 空间」

随着对网站了解的深入,再加上 SaaS 平台限制,开始通过虚拟主机等网络资源搭建各类的站点。

直到 09 年杜老师迈入了大学生活,充足的零花钱能够支援起 VPS,于是开始接触各类控制面板。

因为之前适用虚拟主机关系,最开始接触的面板是 cPanel,这是一款国外收费面板,杜老师用的是破解版本,其功能还是非常强大的,可惜占用资源过高「买不起高配 VPS」加上破解版担心数据安全性,于是在网络中寻找各类控制面板。

恰好在大学时有 Linux 相关课程,很长一段时间都是自行部署环境「类似于 LNMP」

那会正好创办了一个工作室,负责学校周边企业网站搭建项目,纯命令的操作界面增加了运维的成本「客户和部分工作室组员不会操作」于是决定通过安装控制面板解决操作问题。

先后接触面板有 wdCP/Easypanel/VestaCP/AMH/AppNode/宝塔/1Panel「还有一些面板记不清了」

到目前为止杜老师所有服务器上,仅在使用宝塔、1Panel 这两款控制面板,恰好有小伙伴问到,在这里就推荐一下,如何选择~

宝塔面板

其实宝塔没什么好说的,几乎新接触面板的小伙伴们,都会第一时间选择宝塔,其在国内主机行业的普及率,几乎宣告了其地位。具备模块化的功能,满足网站搭建所有要求,只是插件收费机制,劝退了一些白嫖客,还好本身免费功能,就足以满足网站的运营需求:

宝塔有 Windows/Linux 双平台的面板,不管什么系统都能运行,且支持 ARM 架构。网站相关服务软件版本齐全,简单配置即可上线站点。该夸的都夸了,下面说说它的缺点,其实也不算是缺点。首先是插件收费的问题,当然有些小伙伴会通过和谐手段跳过收费,但还是不可避免的要求在线验证「使用面板前要登录账号」

1Panel 容器化

1Panel 是去年「2023 年」三月份出现的面板,当时杜老师还是在公众号中看到有关它的介绍,第一时间就被这种清新的界面风格吸引了「主要是被宝塔界面审美疲劳」本着尝鲜精神第一时间购买了服务器,安装了 1Panel。可惜的是刚推出的版本功能不太完善,面板运行不太稳定,所以没用多久,杜老师就放弃了使用 1Panel。后来关于 1Panel 的推荐文越来越多了,杜老师想着更新迭代了如此多的版本,功能和稳定性上应该会比较完善。再次体验之后确实没有让杜老师失望,足以在生产环境中使用:

1Panel 使用 Docker 部署各种服务,并且打包了非常多工具。如 WP、Typecho 等,都可一键部署。这就使得每个服务都是独立运行、互不干扰,且更新迭代非常的方便。相比宝塔需要部署各种运行环境、上传代码、各种调试,1Panel 仅需要选择指定应用进行安装即可。总的来说,Docker 真香客墙裂推荐使用这款面板:

  •  

杜老师的网站访问速度快吗

闲着没事分析了一下博客的留言,在四万多条留言里,其中有超过一百条说杜老师博客访问速度喜人,想了解下如何做的。今天为小伙伴们分享一下杜老师说的架构,以及优化建议~

数据分布

当您访问杜老师说,正在阅读一篇图文搭配教程,并准备留言时。您正在访问如下四个资源库:

资源解释

网站源码。杜老师使用 Hexo 静态框架,这意味着该网站的所有页面都是预先生成的静态 HTML 文件,而不是动态生成的。访问该网站时,直接获取这些静态网页资源,而不需要再查询数据库。这种做法可以极大减少响应延迟,从而提高网站的加载速度和性能:

图片外链。大量图片托管与去不图床同节点服务器中,方便管理同时,通过自建 CDN 节点加速了访问速度,同时避免与源码站同服务器导致抢占带宽。之所以与去不图床外链地址不同,是因为加入了 WebP 自动转换中间件,节约流量同时,提升加载速度,等同变相增加线路带宽:

评论系统。采用 Artalk 评论系统 Docker 部署方式,其使用 Go 语言构建后端,快速处理数据同时,还使用异步处理的方式,加速评论提交过程。同时采用 Redis 预缓存,Artalk 启动后直接将数据缓存至内存,无需再查询数据库,可以极大减少响应延迟:

开源镜像。全站的 JS 及部分 CSS 资源均引用开源镜像站,感谢 Zkeq 童靴提供公益 CDN 加速平台,既稳定又高速。同时号召小伙伴们不要滥用公益资源,细水长流才能长长久久,境内可用的公益资源越来越少了,希望该平台可长久运营:

优化建议

  1. 主机选择。境外主机的平均带宽比境内的主机高,但境外主机延迟都不低,且数据中心的距离越远,则丢包率越高。故在不考虑带宽情况下,尽量选择境内主机,唯一的限制就是备案了,这是一个硬性门槛,各位站长酌情考量;

  2. 程序选择。静态的肯定比动态的框架快,但有些小伙伴偏爱 WordPress/Typecho 这类的框架,可以安装静态生成插件,进而减少数据库的查询次数,变相减少响应延迟。还要注意的是,不要安装太多插件,因为每次加载页面都会遍历所有插件,插件越多遍历时间越久;

  3. 服务优化。经调查小伙伴们用的云主机普遍配置较低,建议选择 Nginx 作引擎,可以的话推荐使用编译安装最新版本,这个杜老师做过测试的,编译的更稳定且效率高。MySQL 最好 5.7 版本,8.0+适用分布式,性能提升是通过牺牲配置实现的,主机 6G 以下的无法发挥 8.0+版本的性能优势。PHP 肯定是版本越高越好,但需要程序支持才可以。主机内存充足的情况下可以通过 Redis/Memcached 缓存减少数据库查询次数「优先选 Redis」

  4. 站外调用。条件允许的情况下,尽可能的调用站外资源,如 JS/CSS,减少服务器请求数量的同时,还可以避免与网站同服务器导致抢占带宽。墙裂推荐杜老师的去不图床,各大动态博客框架都有对应插件,方便上传管理,自建 CDN 保障稳定及速度。头一次在文章里挂广告推自己的图床,还有一点脸红~

文章推荐

优化云主机的性能确实是一个重要的考虑因素,尤其是在托管大量图片和资源时。很多小伙伴喜欢用某塔面板,很久前杜老师写了一篇《云主机的极致优化》感兴趣的可以看下。虽然文章比较久远,但依旧有参考价值。

只有榨干云主机的性能,才能将性能最大化。关于安装所需的软件和服务,确实需要注意不要过度配置。每个额外的服务或应用程序都可能增加服务器的负担并可能导致性能下降。因此,仔细评估每个应用程序的必要性和其对系统资源影响是很重要的。

比如去不图床安装了 WAF,则每次访问时,先通过 WAF 过滤,才会进行请求处理,经测试会产生 100 毫秒左右的延迟。这是一个值得注意的点,尤其是对于高流量的网站或对性能要求较高的应用。虽然 WAF 可提供安全保护,但这种延迟可能对用户体验产生影响。

如果您感觉杜老师说访问速度不快,那就当杜老师上面的都没说~

  •  

Ashampoo WinOptimizer 25 清理优化工具软件免费用

Ashampoo WinOptimizer 是由著名的 Ashampoo 出品的,一款集成系统维护、性能提升、安全防护、游戏加速、软件卸载以及文件处理等等多种功能于一身的系统优化防护软件,操作简单而且功能全面,一款软件就能搞定系统优化和安全防护等各种需求。原价 95 元每年,限时免费,快去白嫖~

特色功能

  • 对系统关键区域进行全面深度的清洁。

  • 查找删除旧 Windows 版本、更新、系统缓存。

  • 更精简更清晰用户界面。

  • 大幅加速、更加高效清洁工具。

  • 基于全新清洁工具模块超快一键优化。

  • 更快的清洁工具高达 75%。

  • 更新开始页面,带有 CPU 速度表和最新硬件的详情。

  • 访问 Windows 许可证密钥。

  • 基于 Windows Aero Snap 的窗口缩放、停靠功能。

  • 所有功能完全性兼容 Windows 11。

  • 针对全新 Windows 11 进行了多种调整,如任务栏、资源管理器等。

  • Link Checker 和 Context Menu Manager 预览的效果更佳,操作简单。

  • File Wiper 中新增确认对话框和删除方法选项。

  • System Information 中新增了对现代多核处理器的支持。

运行截图

系统分析页面效果如下:

扩展页面效果如下:

自动页面效果如下:

所有模块页面效果如下:

清洁页面效果如下:

优化页面效果如下:

  •  

睡眠与脂肪肝有关系吗

之前就有小伙伴怀疑杜老师不用睡觉,因为不管什么时候在聊天室留言,杜老师就在并及时回复。确实杜老师每天睡的比较晚,那么熬夜会带来什么影响呢?睡眠与脂肪肝有关系吗?

与脂肪肝关系

熬夜本身不会直接导致脂肪肝的,但它可能与脂肪肝发展有关。

长期熬夜会干扰身体的生物节律,影响代谢和内分泌功能,进而增加患脂肪肝风险。

睡眠不足会影响胰岛素的敏感性,导致血糖升高,促使肝脏将多余的葡萄糖转化为脂肪,从而增加脂肪在肝脏的积累。

此外,熬夜常伴随不规律的饮食和不健康的生活方式,如过度摄入高脂肪、高糖分食物和缺乏运动,这些因素也会增加脂肪肝的风险。

睡眠的重要性

睡眠,这是个每天都在进行却被我们忽视的神秘仪式,其实是我们生命中不可或缺的充电宝。你有没有想过,为什么我们需要每天花费大约三分之一的时间在睡眠上?是的,即便有超人的能力,也逃不过这个羁绊。

首先,我们得弄明白,为什么睡眠如此的重要。你知道吗,睡眠不仅仅是休息那么简单。它是我们身体的充电器,为第二天的精力和清晰思维充电。睡眠还能帮助我们巩固记忆,调节情绪,甚至还能提升免疫系统功能。简而言之,睡眠是我们身体的维护工作,没有了它,我们就像一辆没加油的汽车,迟早抛锚。

什么是好睡眠

好睡眠并不意味着躺在床上的时间有多长,而是睡眠质量。一个好的睡眠应该包括充足的深度睡眠和快速眼动睡眠。如果早上醒来感到精神焕发,那么恭喜拥有了一夜好睡眠。

好睡眠就像是一顿丰盛晚餐,不仅要量足而且要质优。

熬夜原因补救

让我们聊聊失眠的罪魁祸首。现代生活压力、不规律的作息时间、过度使用电子设备、焦虑和压力等,这些都是失眠常见原因。

有时,失眠可能是其它健康问题的信号,比如抑郁症或着心脏病。失眠像是一个顽皮的小精灵,在需要休息的时候捣乱。

最后,如果不幸成了熬夜常客,那么需要一些补救措施。首先,尽量避免咖啡因和酒精,尤其是在睡前。其次,可尝试建立一个放松的睡前仪式,比如热水澡或阅读。此外,确保卧室是一个促进睡眠的环境:安静、黑暗、温度。如果熬夜已经成为习惯,那么逐渐调整作息时间,让身体适应健康的睡眠模式。

如果你不得不熬夜,记得补救。首先,尽量避免连续熬夜。其次,熬夜后的第二天尽量安排一些轻松的活动,让身体有恢复机会。还有,不要过度的依赖咖啡因,它相当于透支体能。适当午睡运动更有助于恢复体力。

  •  

今天我们聊一聊脂肪肝

去年「2023 年」年底,公司组织了一次全身的体检。为了配合此次体检,杜老师提前几天就调整饮食、注意休息,争取把体能调整好,得到一个比较好的报告,结果报告说中度脂肪肝?

先聊一下体检

其实杜老师对体检嗤之以鼻。

杜老师选择的这家体检机构还是比较大的,在帝都有数十家的连锁,选择距离最近一家完成预约,马上就会收到成功通知,并附上体检前注意事项。

无非就是要求调整饮食、注意休息之类,对此杜老师就非常好奇:我生活的如此健康,还要你们做啥?

就应该每天都胡吃海喝,天天熬夜奋战,体检前再去喝酒蹦个迪。这时你们告诉我这是我红线,越过即嗝屁就行了~

之后我们就会注意到哪些操作减少 HP,哪些减少 HP 上限值。最好再给一些建议,如何提升 HP 的上限,就完美了!

最后还是要夸一下,杜老师选择的这家体验机构,体检还是很不错的,所有项目完成后还提供 KFC 的早餐~

什么是脂肪肝

脂肪肝这个听起来有点可爱却并不轻盈的疾病,其实就像一个安静房客,默默地住在你的肝脏里,有时候你甚至都不知道它的存在。那么,这个神秘的房客是怎么悄悄搬进我们肝脏的呢?

首先,让我们来聊聊脂肪肝的搬家原因。简单地说,当我们的肝脏里聚集太多的脂肪,就可能会发展成脂肪肝。

这听起来像是肝脏在进行一场脂肪的聚会,不过这场派对对肝脏来说并不是什么好事。

常见的邀请函包括过量饮酒、肥胖、糖尿病及高血脂等,甚至是一些药物副作用。就像一个不懂拒绝的好客东道主,肝脏在处理过多的脂肪时可能会不堪重负。

脂肪肝的表现

脂肪肝是个不太爱出风头的家伙。通常没有很明显的症状,偶尔会发出一些微弱的信号,比如轻微的右上腹部不适或疲劳。因此,很多人都是在体检时才意外发现它的存在。

但如果不加以注意,脂肪肝可能会悄悄升级,导致肝炎、肝硬化乃至肝癌等。

脂肪肝的预防

好消息是,脂肪肝并不是不可战胜对手。防护脂肪肝就像进行一场生活方式大革命。

首先,保持良好饮食习惯。减少高热量及高脂肪的食物摄入,多吃蔬菜水果,保持均衡饮食。

其次,保持适度运动,比如快走、游泳或者骑自行车。就像朋友间的互动,适度运动能帮助我们保持健康的体态。

此外,定期体检也是保持这段友谊健康关键。

脂肪肝的治疗

治疗脂肪肝的关键在于改变生活方式。减重是首要的任务,减少体重通常可以显著减少肝脏中的脂肪。

在某些情况下,医生可能推荐药物治疗,特别是在脂肪肝已经导致肝功能异常的情况下。重要的是,每个人情况都不同,所以最好的办法是根据医生的建议来定制治疗方案。

写在文章最后

作为一个技术博客本不该分享这类的文章,但作为计算机从业人员,此类病症恰好是职业病之一。正所谓身体是革命本钱,早知道早预防。

杜老师对该类信息知之甚少,还是在体检机构医生的建议、查询网上很多资料汇总此篇博文,如有不对之处,欢迎小伙伴们留言指正~也希望新的一年里,小伙伴们可以拥有健康身体!

  •  

GitHub 二次验证 APP 推荐

其实大概在一个多月前,在 GitHub 网页端及邮箱里都被提示要求开启 2FA,杜老师当时并未做理会,直到今天再次访问 GitHub 时,被提醒了截止日期,如到期未设置,则部分功能将会被限制。今天分享 GitHub 二次验证 APP。

什么是 2FA

2FA 是指两步验证的缩写。它是一种用于增强账户安全性的身份验证方法。传统的身份验证通常只需要输入用户名和密码,而 2FA 则要求用户在登录时提供额外的身份验证信息,通常是通过手机应用程序生成的一次性验证码。这种额外验证因素可以是手机短信验证码、手机应用程序生成的动态验证码、指纹识别等等。如使用 2FA ,即使黑客获得了用户的密码,他们仍然需要额外的验证信息才能成功登录用户的账户,从而提高了账户安全性。

引用 GitHub 在邮件中的说明: GitHub 是软件供应链的核心,确保软件供应链的安全要从保护开发人员开始。因此他们在推进 2FA 计划,通过提高账户安全性来保护软件开发。通常,开发人员的账户是社会工程和账户接管的攻击目标。保护开源生态系统的开发人员和消费者免受此类攻击是确保供应链安全第一步,也是最关键的一步。

软件下载

GitHub 主要提供应用和短信两种认证方式,一开始点进来默认是短信的方式,但是发现里面竟然没有中国大陆,就选择了使用 APP 的方式进行认证。

不过国内可选相关软件很少,这里推荐一个轻量的 APP,点击 这里 下载。解压后传输至手机,直接安装即可「此软件为谷歌应用商店直接下载,不放心可自行下载,软件名称见文件名」

如何开启

第一步中,用 APP 扫描二维码后,在 APP 上会有一个动态码「有 30 秒的时间限制」输入到网页端的验证码框里,点击右下角 Continue:

第二步中会显示恢复码,点击 Download 下载后点击 I have saved my recovery codes 就行了。这里需要注意的是,如 APP 不可用时,可以通过恢复码登录 GitHub,故请务必妥善保存:

到了第三步时,以为着已经可以正常使用了,这里杜老师建议添加 Passkeys,它允许您使用 Windows 系统的 PIN 码实现快速身份验证「且包含 Windows Hello」

写在最后

以上是 GitHub 开启 2FA 的流程,前提选择一个支持 2FA 的应用。常见的 2FA 应用包括 Google Authenticator、Authy 和 Microsoft Authenticator 等;这种方式的麻烦之处就是在手机上多装一个 APP。

另外杜老师推荐的工具,需要谷歌服务支持才能实现备份,所以再次提醒小伙伴们,务必妥善保存 GitHub 恢复码。

  •  

2024 年元旦祝福

在这个充满希望的 2024 年元旦,祝愿大家新年快乐!愿新的一年里,小伙伴们心想事成,万事如意。祝愿小伙伴们在工作中获得成功,在生活中拥有幸福。我们携手迎接新的一年,共同创造更美好的明天!

元旦快乐

首先做个自我检讨,本来这篇文章应该提前写好发出来的。结果赶着假期,杜老师的拖延症就犯了,周六拖到周日,周日拖到周一。想着第二天就要上班了,就准备睡一个懒觉,结果元旦当天下午才醒过来,然后躺在床上翻来覆去的刷手机,临近日落,才饿的受不了,起床吃饭~虽说新的一年新的起点,但怎么也不能辜负每个假期!这是每个社畜的心声吧~然后要祝小伙伴们元旦快乐!在这一天杜老师受到了很多祝福,很高兴能通过博客这个圈子认识很多的小伙伴,在过去的一年,大家频繁互动带动了杜老师运营热情,同时也接触到一些有意思的技能,并提升了自身能力。最后总结下过去一年杜老师说博客的运营数据。2023 年更新 121 篇水文,收到 14630 条留言,发出通知 14990 条,新增伙伴 581 位,收到点赞 34645 次。感谢小伙伴的支持!

打卡照片

  •  

如何屏蔽掉令人讨厌的评论

最近有小伙伴们反馈总是收到一些令人讨厌的评论,虽然成功被垃圾评论插件过滤了,但看到后还是会很闹心。杜老师也收到这类评论,虽说手动屏蔽但感觉很麻烦。这里我们分享一下如何借助面板插件,实现对该类评论的拦截~

写在前面

常访问的小伙伴都知道杜老师有个聊天室,有些小伙伴没事会过来摸鱼聊天。

其中 obaby 经常来,前段时间分享一张截图,是博客后台的评论管理页面,里面的留言内容很令人反感。

虽说被插件拦截了,但看到还是很闹心。杜老师也收到类似留言,除手动屏蔽外,还提交到不良信息举报中心。

可能是举报中心需处理的数据量较大,这个留言者迟迟未处理。

杜老师等其它博友依旧可以收到相关评论,故杜老师决定通过技术手段,拦截该类信息提交。

经过分析发现,评论提交者会经常变动昵称、邮箱,但网址一直没变动。所以对关键词进行拦截即可。

某塔面板

如果使用某塔面板,可以安装 Nginx 免费防火墙。打开防火墙页面后,切换到全局配置项,找到 POST 过滤的规则:

Nginx 免费防火墙默认包含很多的拦截项,这些都不用管。将需要拦截的域名,输入到下图中 dusays.com 处,点击后面添加即可:

某 Panel 面板

如果使用某 Panel 面板,并使用 OpenResty 引擎,则无需安装额外的插件。该引擎自带过滤器。点击左侧网站,进入到需要过滤的网址:

在网站设置页面中,切换到安全项。找到下方的 POST 参数校验「默认关闭,需要手动开启」在数据项后添加过滤的网址,点击下面添加即可:

写在最后

对这种 antisocial personality disorder 人格,杜老师墙裂建议看到该类评论后,第一时间提交不良信息举报中心。

还要保持心态,不要因为这类评论扰乱自己心态,也不要考虑到报复。这种人格特征是高度攻击性,且缺乏羞惭感,不能从经历中取得经验教训,行为受偶然动机驱使等。

发病原因来自父母养育方式不仅与父母自身文化等有关,还与另一方的情况,如配偶是否健在以及家庭婚姻的状况息息相关。

该人格障碍人群的人格特征明显偏离正常,通常在个人生活风格和人际关系方面具有异常行为模式。常于童年期或青少年期就出现了品行问题,并长期持续发展至成年或者终生。

  •  

Nginx 的 WAF 规则 LuaJIT 严重版本

前段时间杜老师发表了一篇《自建 CDN 服务器思路》其中介绍南墙 Web 应用防火墙,有些小伙伴们对其名字很感兴趣,而杜老师注意到了它的防护规则,感觉非常实用,顺手整理了下,分享给需要的小伙伴们。此篇为严重风险的防护规则!

fastjson漏洞拦截

过滤阶段:请求阶段

规则描述:拦截fastjson漏洞漏洞攻击

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
local jsonFilter = waf.jsonFilter

local function rMatch(v)
if v == "@type" then
return true, v
end
return false
end

local form = waf.form
if form then
local raw = form["RAW"]
local m = jsonFilter(raw, rMatch, false)
if m then
return m, raw, true
end
end

return false

json格式校验

过滤阶段:请求阶段

规则描述:高级攻击者会构造一些异常json绕过WAF检测,该规则对json格式进行安全校验,可以拦截异常json请求。

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
local form = waf.form
local rct = waf.reqContentType
local rgx = waf.rgxMatch

if rct and waf.contains(waf.toLower(rct), "application/json") and form then
local raw = form["RAW"]
if raw then
if rgx(raw, "^\\s*$", "jos") then
return false
end
local err = waf.checkJson(raw)
if err then
return true, err .. ":" .. raw, true
end
end
end

return false

XSS跨站脚本攻击

过滤阶段:请求阶段

规则描述:攻击者通常会在有漏洞的程序中插入 JavaScript、VBScript、 ActiveX或Flash以欺骗用户。一旦得手,他们可以盗取用户帐户,修改用户设置,盗取/污染cookie,做虚假广告等。

规则内容:

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
local kvFilter = waf.kvFilter
local checkXSS = waf.checkXSS


local function sMatch(v)
if v then
local m = checkXSS(v)
if m then
return m, v
end
end
return false
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], sMatch)
if m then
return m, d, true
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, sMatch)
if m then
return m, d, true
end
end

local cookies = waf.cookies
if cookies then
local m, d = kvFilter(cookies, sMatch)
if m then
return m, d, true
end
end

local m, d = sMatch(waf.userAgent)
if m then
return m, d, true
end

local m, d = sMatch(waf.referer)
if m then
return m, d, true
end

return false

java安全规则集

过滤阶段:请求阶段

规则描述:检测spring、struts、java序列化等相关安全漏洞

规则内容:

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
local kvFilter = waf.kvFilter
local rgx = waf.rgxMatch
local urlDecode = waf.urlDecode
local requestLine = waf.requestLine
local check = waf.plugins.javaClassDetection.check

local function sMatch(v)
local m = rgx(v, "(?:\\$\\{)+(?:j(?:n|\\$\\{)|\\$\\{(?:\\w*:)+)", "joi")
if m then
return m, "Potential Log4j / Log4shell Attack: " .. v
end
m = rgx(v, "\\xac\\xed\\x00\\x05|rO0ABQ|KztAAU|Cs7QAF", "jo")
if m then
return m, "Magic bytes Detected, probable java serialization Attack: " .. v
end
m = rgx(v, "classLoader\\s*\\.\\s*resources\\s*\\.\\s*context\\s*\\.\\s*parent\\s*\\.\\s*pipeline|springframework\\s*\\.\\s*context\\s*\\.\\s*support\\s*\\.\\s*FileSystemXmlApplicationContext", "jos")
if m then
return m, "Spring Framework RCE(CVE-2022-22965): " .. v
end
m = check(v)
if m then
return m, "Potential dangerous java class: " .. v
end
return false
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], sMatch)
if m then
return m, d, true
end
local raw = form["RAW"]
m = rgx(raw, "\\xac\\xed\\x00\\x05|rO0ABQ|KztAAU|Cs7QAF", "jo")
if m then
return m, raw, true
end
m = check(raw)
if m then
return m, raw, true
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, sMatch)
if m then
return m, d, true
end
end

local cookies = waf.cookies
if cookies then
local m, d = kvFilter(cookies, sMatch)
if m then
return m, d, true
end
end

local m, d = kvFilter(waf.reqHeaders, sMatch)
if m then
return m, d, true
end

local m = rgx(urlDecode(requestLine), "(?:\\$\\{)+(?:j(?:n|\\$\\{)|\\$\\{(?:\\w*:)+)", "joi")
if m then
return m, requestLine, true
end

return false

Shellshock漏洞

过滤阶段:请求阶段

规则描述:检测对“Shellshock”(CVE-2014-6271和CVE-2014-7169) GNU Bash RCE漏洞的攻击。

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
local kvFilter = waf.kvFilter
local rgx = waf.rgxMatch
local requestLine = waf.requestLine
local urlDecode = waf.urlDecode

local function rMatch(v)
local m = rgx(urlDecode(v), "\\(\\s*\\)\\s+{", "jos")
if m then
return m, v
end
return false
end

local m, d = kvFilter(waf.reqHeaders, rMatch)
if m then
return m, d, true
end

local m, d = rMatch(requestLine)
if m then
return m, d, true
end

return false

远程文件包含 (RFI)

过滤阶段:请求阶段

规则描述:该规则寻找常见类型的远程文件包含(RFI)攻击方法。 #-PHP“include()”函数 #-JSP <jsp:include page= 或 <c:import url= #-RFI主机与本地主机不匹配

规则内容:

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
local kvFilter = waf.kvFilter
local rgx = waf.rgxMatch
local host = waf.host
local counter = waf.strCounter
local str_find = string.find
local str_sub = string.sub

local function rMatch(v)
local m = rgx(v, "^(?:url:)?file|ftps?|https?)://(?:[^@]+@)?([^/]+", "joi")
if m then
local i, j = str_find(v, host, 1, true)
if i then
if counter(str_sub(v, 1, j), "/") == 2 then
return false
end
end
end
return m, v
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], rMatch)
if m then
return m, d, true
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, rMatch)
if m then
return m, d, true
end
end

return false

json 命令注入检测

过滤阶段:请求阶段

规则描述:解析请求body中的json内容,并检测命令注入攻击。采用RCE语义检测引擎可以检查各种变形,如:cat$IFS/etc/os-release或c$()at /e??/p???等

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
local checkRCE = waf.checkRCE
local jsonFilter = waf.jsonFilter

local function rMatch(v)
local m = checkRCE(v)
if m then
return m, v
end
return false
end

local form = waf.form
if form then
local m, d = jsonFilter(form["RAW"], rMatch, false, true)
if m then
return m, d, true
end
end

return false

常规命令注入检测

过滤阶段:请求阶段

规则描述:检测url、cookie、form中的shell命令注入攻击,采用RCE语义检测引擎可以检查各种变形,如:cat$IFS/etc/os-release或c$()at /e??/p???等

规则内容:

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
local checkRCE = waf.checkRCE
local kvFilter = waf.kvFilter

local function rMatch(v)
local m = checkRCE(v)
if m then
return m, v
end
return false
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], rMatch, true)
if m then
return m, d, true
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, rMatch, true)
if m then
return m, d, true
end
end

local cookies = waf.cookies
if cookies then
local m, d = kvFilter(cookies, rMatch, true)
if m then
return m, d, true
end
end
return false

json sql注入检测

过滤阶段:请求阶段

规则描述:解析请求body中的json内容,并检测sql注入攻击。采用SQL语义检测引擎,可以降低误报。

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
local checkSQLI = waf.checkSQLI
local jsonFilter = waf.jsonFilter

local function rMatch(v)
local m = checkSQLI(v)
if m then
return m, v
end
return false
end

local form = waf.form
if form then
local m, d = jsonFilter(form["RAW"], rMatch, false)
if m then
return m, d, true
end
end

return false

常规sql注入检测

过滤阶段:请求阶段

规则描述:检测url、cookie、form中的sql注入攻击。采用SQL语义检测引擎,可以降低误报。

规则内容:

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
local checkSQLI = waf.checkSQLI
local kvFilter = waf.kvFilter

local function sMatch(v)
local m = checkSQLI(v)
if m then
return m, v
end
return false
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], sMatch)
if m then
return m, d, true
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, sMatch)
if m then
return m, d, true
end
end

local cookies = waf.cookies
if cookies then
local m, d = kvFilter(cookies, sMatch)
if m then
return m, d, true
end
end

local m, d = kvFilter(waf.reqHeaders, sMatch)
if m then
return m, d, true
end

return false

Invalid protocol

过滤阶段:请求阶段

规则描述:请求header数过多,超过64个。

规则内容:

1
2
3
4
if waf.hErr and waf.hErr=="truncated" then
return true,waf.hErr,true
end
return false

XXE漏洞

过滤阶段:请求阶段

规则描述:XML外部实体注入(XML External Entity)漏洞简称XXE漏洞。当允许引用外部实体时,通过构造恶意内容,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害。

规则内容:

1
2
3
4
5
6
7
if waf.form and waf.form["RAW"] then
local m = waf.rgxMatch(waf.form["RAW"], "<!(?:DOCTYPE|ENTITY)[^>]+?\\bSYSTEM\\b", "jos")
if m then
return m, waf.form["RAW"], true
end
end
return false

ImageMagick漏洞

过滤阶段:请求阶段

规则描述:ImageMagick是一个功能强大的开源图形处理软件,该漏洞可以执行任意命令和读写文件

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
local rgx = waf.rgxMatch
local function imgContentMatch(v)
local m = rgx(v, "\\bpush\\s+graphic-context\\b|\\<\\s*image\\b", "joi")
if m then
return m, v
end
return false
end
if waf.form then
local m, d = waf.knFilter(waf.form["FILES"], imgContentMatch, 0)
return m, d, true
end
return false

header头漏洞

过滤阶段:请求阶段

规则描述:httpoxy漏洞可被用来针对CGI环境设置非法代理,从而窃取服务器敏感数据。在CVE-2017-7269(IIS 6.0 WebDAV远程代码执行漏洞)中if和lock_token http头会造成溢出攻击。

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
if waf.reqHeaders.proxy ~= nil then
return true, "Proxy: " .. waf.reqHeaders.proxy, true
end

if waf.reqHeaders.lock_token ~= nil then
return true, "Lock-Token: " .. waf.reqHeaders.lock_token, true
end

if waf.reqHeaders["If"] ~= nil then
return true, "If: " .. waf.reqHeaders["If"], true
end

return false

LDAP Injection

过滤阶段:请求阶段

规则描述:拦截LDAP注入攻击

规则内容:

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
local kvFilter = waf.kvFilter
local rgx = waf.rgxMatch
local htmlEntityDecode = waf.htmlEntityDecode

local function rMatch(v)
local m = rgx(htmlEntityDecode(v), "^[^:\\(\\)\\&\\|\\!\\<\\>\\~]*\\)\\s*(?:\\((?:[^,\\(\\)\\=\\&\\|\\!\\<\\>\\~]+[><~]?=|\\s*[&!|]\\s*(?:\\)|\\()?\\s*)|\\)\\s*\\(\\s*[\\&\\|\\!]\\s*|[&!|]\\s*\\([^\\(\\)\\=\\&\\|\\!\\<\\>\\~]+[><~]?=[^:\\(\\)\\&\\|\\!\\<\\>\\~]*)", "jos")
if m then
return m, v
end
return false
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], rMatch)
if m then
return m, d, true
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, rMatch)
if m then
return m, d, true
end
end

local cookies = waf.cookies
if cookies then
local m, d = kvFilter(cookies, rMatch)
if m then
return m, d, true
end
end
return false

HTTP Splitting

过滤阶段:请求阶段

规则描述:此规则检测请求文件名中的\n或\r。

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
local rgx = waf.rgxMatch
local function fMatch(v)
local m = rgx(v, "[\\n\\r]", "jo")
if m then
return m, v
end
return false
end
local m, d = fMatch(waf.uri)
if m then
return m, d, true
end
return false

HTTP Header Injection

过滤阶段:请求阶段

规则描述:HTTP头注入查找回车符(CR)%0d和换行符(LF)%0a字符,单独或与header字段名称组合使用。如果数据在响应头中返回并由客户端解释,这些字符可能会导致问题。

规则内容:

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
local rgx = waf.rgxMatch
local htmlEntityDecode = waf.htmlEntityDecode
local concat = table.concat

local function hMatch(v)
local m = rgx(htmlEntityDecode(v), "[\\n\\r]", "jo")
if m then
return m, v
end
return false
end

local function vMatch(v)
local m = rgx(htmlEntityDecode(v), "[\\n\\r]+(?:\\s|location|refresh|(?:set-)?cookie|(?:x-)?(?:forwarded-(?:for|host|server)|host|via|remote-ip|remote-addr|originating-IP))\\s*:", "josi")
if m then
return m, v
end
return false
end

local m, d = waf.kvFilter(waf.reqHeaders, hMatch)
if m then
return m, d, true
end

local queryString = waf.queryString
if queryString then
for k, v in pairs(waf.queryString) do
m, d = hMatch(k)
if m then
return m, d, true
end
if type(v)=="table" then
v = concat(v,",")
end
m, d = vMatch(v)
if m then
return m, d, true
end
end
end

local form = waf.form
if form then
for k, _ in pairs(form["FORM"]) do
m, d = hMatch(k)
if m then
return m, d, true
end
end
end

return false

boundary异常拦截

过滤阶段:请求阶段

规则描述:拦截请求content type头中multipart/form-data的异常boundary,如php在上传解析boundary时没有符合rfc规范,对逗号产生了错误解析。

规则内容:

1
2
3
4
5
6
7
8
9
10
11
local ct = waf.reqContentType

if ct then
if type(ct) ~= "string" then
return true, "Malform Content-Type", true
elseif waf.contains(ct, "boundary") and (waf.strCounter(ct, "boundary") > 1 or not waf.rgxMatch(ct, "boundary=[\\w\\-]+$", "jo")) then
return true, ct, true
end
end

return false

asp畸形编码过滤

过滤阶段:请求阶段

规则描述:asp中unicode畸形编码会造成waf绕过危害

规则内容:

1
2
3
4
if waf.rgxMatch(waf.reqUri,"%u00(?:aa|ba|d0|de|e2|f0|fe)","i") then
return true,waf.reqUri,true
end
return false

HTTP Response Splitting

过滤阶段:请求阶段

规则描述:该规则查找回车符(CR)%0d和换行符(LF)%0a字符。如果在响应报头中返回数据,这些字符可能会导致问题,并且可能会被中间代理服务器解释并被视为两个单独的响应。

规则内容:

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
local kvFilter = waf.kvFilter
local rgx = waf.rgxMatch
local htmlEntityDecode = waf.htmlEntityDecode

local function rMatch(v)
local m = rgx(v, "[\\r\\n]\\W*?(?:content-(?:type|length)|set-cookie|location):\\s*\\w", "josi")
if m then
return m, v
end
return false
end

local function hMatch(v)
local m = rgx(htmlEntityDecode(v), "(?:\\bhttp/\\d|<(?:html|meta)\\b)", "josi")
if m then
return m, v
end
return false
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], rMatch)
if m then
return m, d, true
end
m, d = kvFilter(form["FORM"], hMatch)
if m then
return m, d, true
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, rMatch)
if m then
return m, d, true
end
m, d = kvFilter(queryString, hMatch)
if m then
return m, d, true
end
end

local cookies = waf.cookies
if cookies then
local m, d = kvFilter(cookies, rMatch)
if m then
return m, d, true
end
m, d = kvFilter(cookies, hMatch)
if m then
return m, d, true
end
end
return false

HTTP Request Smuggling

过滤阶段:请求阶段

规则描述:此规则查找与单词HTTP/\d或CR/LF字符组合的HTTP/WEBDAV方法名。这将指向试图将第二个请求注入到请求中,从而绕过对主请求执行的测试,如CVE-2019-20372(Nginx<1.17.7 请求走私漏洞)。

规则内容:

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
local kvFilter = waf.kvFilter
local rgx = waf.rgxMatch
local htmlEntityDecode = waf.htmlEntityDecode

local function rMatch(v)
local m = rgx(htmlEntityDecode(v), "(?:get|post|head|options|connect|put|delete|trace|track|patch|propfind|propatch|mkcol|copy|move|lock|unlock)\\s+[^\\s]+\\s+http/\\d", "josi")
if m then
return m, v
end
return false
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], rMatch)
if m then
return m, d, true
end
m, d = rMatch(form["RAW"])
if m then
return m, d, true
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, rMatch)
if m then
return m, d, true
end
end

local cookies = waf.cookies
if cookies then
local m, d = kvFilter(cookies, rMatch)
if m then
return m, d, true
end
end
return false

上传文件内容过滤

过滤阶段:请求阶段

规则描述:过滤上传的文件内容,拦截webshell上传

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
local rgx = waf.rgxMatch
local function fileContentMatch(v)
local m = rgx(v, "<\\?.+?\\$(?:GLOBALS|_(?:GET|POST|COOKIE|REQUEST|SERVER|FILES|SESSION|ENV))|<\\?php|<jsp:|<%(?i:!|\\s*@|.*?\\brequest\\s*(?:\\.|\\())", "jos")
if m then
return m, v
end
return false
end
if waf.form then
local m, d = waf.knFilter(waf.form["FILES"], fileContentMatch, 0)
return m, d, true
end
return false

上传文件名过滤

过滤阶段:请求阶段

规则描述:过滤上传文件名中的网页脚本扩展名,拦截webshell上传

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
local rgx = waf.rgxMatch

local function fileNameMatch(v)
local m = rgx(v, "\\.(?:as|cer\\b|cdx|ph|jsp|war|class|exe|ht|env|user\\.ini)|php\\.ini", "joi")
if m then
return m, v
end
return false
end
if waf.form then
local m, d = waf.knFilter(waf.form["FILES"], fileNameMatch, 1)
return m, d, true
end

return false

防持续攻击

过滤阶段:请求阶段

规则描述:累计攻击超过100次,则在10分钟内拦截该ip访问

规则内容:

1
2
3
4
5
6
7
local ib = waf.ipBlock
local c = ib:get(waf.ip)
if c and c >= 100 then
ib:set(waf.ip, c, 600, 1)
return true, "ip blocked for continue attack: " .. waf.ip, true
end
return false

Invalid protocol

过滤阶段:请求阶段

规则描述:非法post协议

规则内容:

1
2
3
4
5
6
7
if waf.form == nil then
if waf.contains(waf.fErr, "content_type") then
return true, waf.fErr .. ": " .. waf.reqContentType, true
end
return true, waf.fErr, true
end
return false
  •  

Nginx 的 WAF 规则 LuaJIT 高危险版

前段时间杜老师发表了一篇《自建 CDN 服务器思路》其中介绍南墙 Web 应用防火墙,有些小伙伴们对其名字很感兴趣,而杜老师注意到了它的防护规则,感觉非常实用,顺手整理了下,分享给需要的小伙伴们。此篇为高危险防护规则!

SQL报错检测

过滤阶段:返回页面

规则描述:返回页面的sql报错可能会泄露服务器敏感信息

规则内容:

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
local check = waf.plugins.sqlErrorDetection.check
local rb = waf.respBody
local rgx = waf.rgxMatch
local has = waf.contains

if waf.status == 500 then
local m = check(rb)
if m then
if rgx(rb, "JET Database Engine|Access Database Engine|\\[Microsoft\\]\\[ODBC Microsoft Access Driver\\]", "jo") then
return m, "Microsoft Access SQL Information Leakage: " .. rb, true
end
if rgx(rb, "ORA-[0-9][0-9][0-9][0-9]|java\\.sql\\.SQLException|Oracle error|Oracle.*Driver|Warning.*oci_.*|Warning.*ora_.*", "jo") then
return m, "Oracle SQL Information Leakage: " .. rb, true
end
if rgx(rb, "DB2 SQL error:|\\[IBM\\]\\[CLI Driver\\]\\[DB2/6000\\]|CLI Driver.*DB2|DB2 SQL error|db2_\\w+\\(", "jo") then
return m, "DB2 SQL Information Leakage: " .. rb, true
end
if rgx(rb, "\\[DM_QUERY_E_SYNTAX\\]|has occurred in the vicinity of:", "jo") then
return m, "EMC SQL Information Leakage: " .. rb, true
end
if has(rb, "Dynamic SQL Error") then
return m, "firebird SQL Information Leakage: " .. rb, true
end
if rgx(rb, "Exception (?:condition )?\\d+\\. Transaction rollback\\.", "jo") then
return m, "Frontbase SQL Information Leakage: " .. rb, true
end
if has(rb, "org.hsqldb.jdbc") then
return m, "hsqldb SQL Information Leakage: " .. rb, true
end
if rgx(rb, "An illegal character has been found in the statement|com\\.informix\\.jdbc|Exception.*Informix", "jo") then
return m, "informix SQL Information Leakage: " .. rb, true
end
if rgx(rb, "Warning.*ingres_|Ingres SQLSTATE|Ingres\\W.*Driver", "jo") then
return m, "ingres SQL Information Leakage: " .. rb, true
end
if rgx(rb, "<b>Warning</b>: ibase_|Unexpected end of command in statement", "jo") then
return m, "interbase SQL Information Leakage: " .. rb, true
end
if rgx(rb, "SQL error.*POS[0-9]+|Warning.*maxdb", "jo") then
return m, "maxDB SQL Information Leakage: " .. rb, true
end
if rgx(rb, "System\\.Data\\.OleDb\\.OleDbException|\\[Microsoft\\]\\[ODBC SQL Server Driver\\]|\\[Macromedia\\]\\[SQLServer JDBC Driver\\]|\\[SqlException|System\\.Data\\.SqlClient\\.SqlException|Unclosed quotation mark after the character string|'80040e14'|mssql_query\\(\\)|Microsoft OLE DB Provider for ODBC Drivers|Microsoft OLE DB Provider for SQL Server|Incorrect syntax near|Sintaxis incorrecta cerca de|Syntax error in string in query expression|Procedure or function .* expects parameter|Unclosed quotation mark before the character string|Syntax error .* in query expression|Data type mismatch in criteria expression\\.|ADODB\\.Field \\(0x800A0BCD\\)|the used select statements have different number of columns|OLE DB.*SQL Server|Warning.*mssql_.*|Driver.*SQL[ _-]*Server|SQL Server.*Driver|SQL Server.*[0-9a-fA-F]{8}|Exception.*\\WSystem\\.Data\\.SqlClient\\.", "jo") then
return m, "Mssql SQL Information Leakage: " .. rb, true
end
if rgx(rb, "MyS(?:QL server version for the right syntax to use|qlClient\\.)|(?:supplied argument is not a valid |SQL syntax.*)MySQL|Column count doesn't match(?: value count at row)?|(?:Table '[^']+' doesn't exis|valid MySQL resul)t|You have an error in your SQL syntax(?: near|;)|Warning.{1,10}mysql_(?:[a-z_()]{1,26})?|ERROR [0-9]{4} \\([a-z0-9]{5}\\):|mysql_fetch_array\\(\\)|on MySQL result index|\\[MySQL\\]\\[ODBC", "jo") then
return m, "Mysql SQL Information Leakage: " .. rb, true
end
if rgx(rb, "PostgreSQL query failed:|pg_query\\(\\) \\[:|pg_exec\\(\\) \\[:|PostgreSQL.{1,20}ERROR|Warning.*\\bpg_.*|valid PostgreSQL result|Npgsql\\.|PG::[a-zA-Z]*Error|Supplied argument is not a valid PostgreSQL .*? resource|Unable to connect to PostgreSQL server", "jo") then
return m, "Postgres SQL Information Leakage: " .. rb, true
end
if rgx(rb, "Warning.*sqlite_|Warning.*SQLite3::|SQLite/JDBCDriver|SQLite\\.Exception|System\\.Data\\.SQLite\\.SQLiteException", "jo") then
return m, "SQLite SQL Information Leakage: " .. rb, true
end
if rgx(rb, "Sybase message:|Warning.{2,20}sybase|Sybase.*Server message", "jo") then
return m, "Sybase SQL Information Leakage: " .. rb, true
end
end
end

return false

数据泄露检测

过滤阶段:返回页面

规则描述:从返回页面检测列目录漏洞和源代码泄露问题

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
local rgx = waf.rgxMatch
local rb = waf.respBody

local m = rgx(rb, "<(?:TITLE>Index of.*?<H|title>Index of.*?<h)1>Index of|>\\[To Parent Directory\\]</[Aa]><br>", "jo")
if m then
return m, "Directory Listing: " .. rb, true
end

m = rgx(rb, "^\\s*(?:#\\!\\s?/|<%|<\\?\\s*[^x]|<jsp:)", "jo")
if m then
return m, "Source code leak: " .. rb, true
end

return false

固定会话(Session Fixation)攻击

过滤阶段:请求阶段

规则描述:会话固定攻击(session fixation attack)是利用应用系统在服务器的会话ID固定不变机制,借助他人用相同的会话ID获取认证和授权,然后利用该会话ID劫持他人的会话以成功冒充他人,造成会话固定攻击。

规则内容:

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
local kvFilter = waf.kvFilter
local rgx = waf.rgxMatch
local referer = waf.referer
local host = waf.host
local endWith = waf.endWith

local function sMatch(v)
local m = rgx(v, "\\bhttp-equiv\\W+set-cookie\\b", "joi")
if m then
return m, v
end
return false
end

local function nMatch(v)
local m = rgx(v, "^(?:jsessionid|aspsessionid|asp\\.net_sessionid|phpsession|phpsessid|weblogicsession|session_id|session-id|cfid|cftoken|cfsid|jservsession|jwsession)$", "joi")
if m then
return m, v
end
return false
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], sMatch)
if m then
return m, d, true
end
for k, v in pairs(form["FORM"]) do
m, d = nMatch(k)
if m then
if not referer then
if type(v) == "table" then
v = table.concat(v)
end
return m, d .. ":" .. v, true
else
m = ngx.re.match(referer, "^https?://(.*?)/", "jo")
if m and not endWith(m[1], host) then
if type(v) == "table" then
v = table.concat(v)
end
return m, d .. ":" .. v, true
end
end
end
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, sMatch)
if m then
return m, d, true
end
for k, v in pairs(queryString) do
m, d = nMatch(k)
if m then
if not referer then
if type(v) == "table" then
v = table.concat(v)
end
return m, d .. ":" .. v, true
else
m = ngx.re.match(referer, "^https?://(.*?)/", "jo")
if m and not endWith(m[1], host) then
if type(v) == "table" then
v = table.concat(v)
end
return m, d .. ":" .. v, true
end
end
end
end
end

local cookies = waf.cookies
if cookies then
local m, d = kvFilter(cookies, sMatch)
if m then
return m, d, true
end
end

return false

通用攻击

过滤阶段:请求阶段

规则描述:本规则拦截ruby、node、js、perl注入和SSRF攻击

规则内容:

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
local kvFilter = waf.kvFilter
local rgx = waf.rgxMatch

local function sMatch(v)
local m = rgx(v, "Process\\s*\\.\\s*spawn\\s*\\(", "jos")
if m then
return m, "Ruby Injection Attack: "..v
end
m = rgx(v, "t(?:his\\.constructor|runcateSync\\s*\\()|\\b(?:spawn|eval)\\s*\\(|_(?:\\$\\$ND_FUNC\\$\\$_|_js_function)|String\\s*\\.\\s*fromCharCode", "jos")
if m then
return m, "Node.js Injection Attack: "..v
end
m = rgx(v, "__proto__|constructor\\s*(?:\\.|\\[)\\s*prototype", "jos")
if m then
return m, "JavaScript Prototype Pollution: "..v
end
m = rgx(v, "(?:s(?:sh(?:2(?:.(?:s(?:(?:ft|c)p|hell)|tunnel|exec))?)?|m(?:[bs]|tps?)|vn(?:\\+ssh)?|n(?:ews|mp)|ips?|ftp|3)|p(?:op(?:3s?|2)|r(?:oxy|es)|h(?:ar|p)|aparazzi|syc)|c(?:ompress.(?:bzip2|zlib)|a(?:llto|p)|id|vs)|t(?:e(?:amspeak|lnet)|urns?|ftp)|f(?:i(?:nger|sh)|(?:ee)?d|tps?)|i(?:rc[6s]?|maps?|pps?|cap|ax)|d(?:a(?:ta|v)|n(?:tp|s)|ict)|m(?:a(?:ilto|ven)|umble|ms)|n(?:e(?:tdoc|ws)|ntps?|fs)|r(?:tm(?:f?p)?|sync|ar|mi)|v(?:iew-source|entrilo|nc)|a(?:ttachment|f[ps]|cap)|b(?:eshare|itcoin|lob)|g(?:o(?:pher)?|lob|it)|u(?:nreal|t2004|dp)|e(?:xpect|d2k)|h(?:ttps?|323)|w(?:ebcal|s?s)|ja(?:bbe)?r|x(?:mpp|ri)|ldap[is]?|ogg|zip):\\/\\/(?:(?:[\\d.]{0,11}(?:(?:\\xe2(?:\\x92(?:[\\x9c\\x9d\\x9e\\x9f\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9\\xaa\\xab\\xac\\xad\\xae\\xaf\\xb0\\xb1\\xb2\\xb3\\xb4\\xb5]|[\\x88\\x89\\x8a\\x8b\\x8c\\x8d\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b]|[\\xb6\\xb7\\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe\\xbf]|[\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87])|\\x93(?:[\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d\\x8e\\x8f]|[\\x9c\\x9d\\x9e\\x9f\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9]|[\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b]|[\\xbf\\xb5\\xb6\\xb7\\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe]|[\\xab\\xac\\xad\\xae\\xaf\\xb0\\xb1\\xb2\\xb3\\xb4])|\\x91(?:[\\xaa\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9\\xaa\\xab\\xac\\xad\\xae\\xaf\\xb0\\xb1\\xb2\\xb3]|[\\xb4\\xb5\\xb6\\xb7\\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe\\xbf]))|\\xe3\\x80\\x82))+)|[a-z][\\w\\-\\.]{1,255}:\\d{1,5}(?:#?\\s*&?@(?:(?:\\d{1,3}\\.){3,3}\\d{1,3}|[a-z][\\w\\-\\.]{1,255}):\\d{1,5}\\/?)+|(?:0x[a-f0-9]{2}\\.){3}0x[a-f0-9]{2}|(?:0{1,4}\\d{1,3}\\.){3}0{1,4}\\d{1,3}|\\d{1,3}\\.(?:\\d{1,3}\\.\\d{5}|\\d{8})|0x(?:[a-f0-9]{16}|[a-f0-9]{8})|\\[[a-f\\d:]+(?:[\\d.]+|%\\w+)?\\]|(?:\\x5c\\x5c[a-z\\d-]\\.?_?)+|\\d{10})", "josi")
if m then
return m, "Possible Server Side Request Forgery (SSRF) Attack: "..v
end
m = rgx(v, "\\@\\{.*?\\}", "jos")
if m then
return m, "Perl Injection Attack: "..v
end
return false
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], sMatch)
if m then
return m, d, true
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, sMatch)
if m then
return m, d, true
end
end

local cookies = waf.cookies
if cookies then
local m, d = kvFilter(cookies, sMatch)
if m then
return m, d, true
end
end

local m, d = kvFilter(waf.reqHeaders, sMatch)
if m then
return m, d, true
end
return false

php安全规则集

过滤阶段:请求阶段

规则描述:检测php相关的对象序列化等漏洞

规则内容:

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
local kvFilter = waf.kvFilter
local rgx = waf.rgxMatch

local function sMatch(v)
local m = rgx(v, "php://(?:std(?:in|out|err)|(?:in|out)put|fd|memory|temp|filter)|(?:ssh2(?:.(?:s(?:(?:ft|c)p|hell)|tunnel|exec))?|z(?:lib|ip)|(?:ph|r)ar|expect|bzip2|glob|ogg)://", "joi")
if m then
return m, v
end
m = rgx(v, "[oOcC]:\\d+:\"\\w+\":\\d+:{.*?}", "jos")
if m then
return m, v
end
return false
end

local function fileContentMatch(v)
local m = rgx(v, "<\\?.+?\\$_(?:GET|POST|COOKIE|REQUEST|SERVER|FILES|SESSION)|<\\?php", "jos")
if m then
return m, v
end
return false
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], sMatch)
if m then
return m, d, true
end
m, d = waf.knFilter(form["FILES"], fileContentMatch, 0)
if m then
return m, d, true
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, sMatch)
if m then
return m, d, true
end
end

local cookies = waf.cookies
if cookies then
local m, d = kvFilter(cookies, sMatch)
if m then
return m, d, true
end
end

local m, d = kvFilter(waf.reqHeaders, sMatch)
if m then
return m, d, true
end
return false

路径遍历攻击

过滤阶段:请求阶段

规则描述:检测url、上传文件或参数中的路径遍历攻击。采用LFI语义检测引擎,可以检查如://///…\…\etc///passwd等变形攻击。

规则内容:

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
local checkPT = waf.checkPT
local kvFilter = waf.kvFilter

local function ptMatch(v)
local m = checkPT(v)
if m then
return m, v
end
return false
end

local url = waf.urlDecode(waf.reqUri)
if checkPT(url) then
return true, url, true
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], ptMatch)
if m then
return m, d, true
end
m, d = waf.knFilter(waf.form["FILES"], ptMatch, 1)
if m then
return m, d, true
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, ptMatch)
if m then
return m, d, true
end
end

return false

异常请求字符编码拦截

过滤阶段:请求阶段

规则描述:黑客通常会在Content-Type头中使用异常的charset定义字符集编码来绕过waf保护,如IBM037, IBM500, cp875等

规则内容:

1
2
3
4
5
6
7
8
9
10
11
local rct = waf.reqContentType
local has = waf.contains
local counter = waf.strCounter
local rgx = waf.rgxMatch
if rct then
rct = waf.toLower(rct)
if has(rct, "charset") and (not rgx(rct, "charset\\s*=\\s*(utf\\-8|gbk|gb2312|iso\\-8859\\-1|iso\\-8859\\-15|windows\\-1252)","jo") or counter(rct, "charset") > 1) then
return true, rct, true
end
end
return false

代理头sql注入

过滤阶段:请求阶段

规则描述:过滤http请求中X-Forwarded-For、Client-IP请求头中单引号sql注入

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
local rip=waf.reqHeaders.x_forwarded_for
if rip then
if type(rip) ~= "string" then
return true,"Malform X-Forwarded-For",true
elseif waf.contains(rip,"'") then
return true,rip,true
end
end
rip=waf.reqHeaders.client_ip
if rip then
if type(rip) ~= "string" then
return true,"Malform Client-IP",true
elseif waf.contains(rip,"'") then
return true,rip,true
end
end
return false

Invalid protocol

过滤阶段:请求阶段

规则描述:cookie参数过多

规则内容:

1
2
3
4
if waf.cookies==nil then
return true,waf.cErr,true
end
return false

Invalid protocol

过滤阶段:请求阶段

规则描述:querystring参数过多

规则内容:

1
2
3
4
if waf.queryString==nil then
return true,waf.qErr,true
end
return false
  •  

Nginx 的 WAF 规则 LuaJIT 中危险版

前段时间杜老师发表了一篇《自建 CDN 服务器思路》其中介绍南墙 Web 应用防火墙,有些小伙伴们对其名字很感兴趣,而杜老师注意到了它的防护规则,感觉非常实用,顺手整理了下,分享给需要的小伙伴们。此篇为中危险防护规则!

机器人攻击防护

过滤阶段:请求阶段

规则描述:通过生成滑动旋转验证码来拦截机器人攻击,如漏洞扫描、网络爬虫、CC攻击等自动化攻击行为,Token有效期30分钟。

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
local sh = ngx.shared.ipCache
local robotIp = 'rb:' .. waf.ip
local c, f = sh:get(robotIp)

-- 如果是静态页面且没有进行滑动旋转验证码验证则返回
if not (waf.isQueryString or waf.reqContentLength > 0) and f ~= 2 then
return false
end

if not c then
sh:set(robotIp, 1, 60, 1) -- 设置1分钟也就是60秒访问计数时间段
else
if f == 2 then
return waf.checkRobot(waf) -- 启动机器人滑动旋转验证码验证
end
sh:incr(robotIp, 1)
if c + 1 >= 360 then
sh:set(robotIp, c + 1, 1800, 2) -- 达到了60秒内请求超过360次的阈值,进入机器人验证模式
return true, robotIp, true
end
end

return false

弱口令检测

过滤阶段:请求阶段

规则描述:检测常见登录页面的弱口令问题

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
local check = waf.plugins.weakPwdDetection.check
local toLower = waf.toLower
local has = waf.contains

local form = waf.form
local uri = toLower(waf.uri)
if form and (has(uri, "login") or has(uri, "logon") or has(uri, "signin")) then
local f = form["FORM"]
if f then
for k, v in pairs(f) do
k = toLower(k)
if (k == "pass" or has(k, "pwd") or has(k, "passwd") or has(k, "password")) and check(v) then
return true, form["RAW"], false
end
end
end
end

return false

敏感文件泄露检测

过滤阶段:请求阶段

规则描述:检测url中各种敏感泄露文件的路径,如svn、git、sql、log、bak等,防止被攻击者利用

规则内容:

1
2
3
4
5
local m, d = waf.plugins.fileLeakDetection.check()
if m then
return true, d, true
end
return false

请求body大小限制

过滤阶段:请求阶段

规则描述:限制请求body大小为8M以下,黑客会尝试大数据包绕过waf过滤

规则内容:

1
2
3
4
if waf.reqContentLength>8388608 then
return true,"reqBody length is "..waf.reqContentLength ,true
end
return false

HTTP Parameter Pollution

过滤阶段:请求阶段

规则描述:http参数污染攻击,该规则查找具有相同名称的多个参数,并检查一些后端参数弱校验时产生的绕过问题,如:foo[1]a=bar&foo[1]b=或foo[1]x[1]=bar&foo[1]x[2]=等。

规则内容:

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
local rgx = waf.rgxMatch

local function rMatch(v)
local m = rgx(v, "(?:][^\\]]+$|][^\\]]+\\[)", "jos")
if m then
return m, v
end
return false
end

local form = waf.form
if form then
for k, v in pairs(form["FORM"]) do
if type(v) == "table" then
return true, k.."="..table.concat(v, ","), true
end
local m, d = rMatch(k)
if m then
return m, d, true
end
end
end

local queryString = waf.queryString
if queryString then
for k, v in pairs(queryString) do
if type(v) == "table" then
return true, k.."="..table.concat(v, ","), true
end
local m, d = rMatch(k)
if m then
return m, d, true
end
end
end

local cookies = waf.cookies
if cookies then
for k, v in pairs(cookies) do
if type(v) == "table" then
return true, k.."="..table.concat(v, ","), true
end
local m, d = rMatch(k)
if m then
return m, d, true
end
end
end
return false

扫描器检测

过滤阶段:请求阶段

规则描述:检测常见的各种扫描器,如awvs、sqlmap、nessus、appscan、nmap等,拦截它们有助于减少黑客发现漏洞的风险

规则内容:

1
2
3
4
5
local m, d = waf.plugins.scannerDetection.check()
if m then
return true, d, true
end
return false
  •  

Nginx 的 WAF 规则 LuaJIT 低危险版

前段时间杜老师发表了一篇《自建 CDN 服务器思路》其中介绍南墙 Web 应用防火墙,有些小伙伴们对其名字很感兴趣,而杜老师注意到了它的防护规则,感觉非常实用,顺手整理了下,分享给需要的小伙伴们。此篇为低危险防护规则!

防CC攻击规则

过滤阶段:请求阶段

规则描述:当一分钟访问/api/路径频率超过360次,则在5分钟内拦截该ip访问

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
if not waf.startWith(waf.toLower(waf.uri), "/api/") then
return false
end

local sh = ngx.shared.ipCache
local ccIp = 'cc-' .. waf.ip
local c, f = sh:get(ccIp)
if not c then
sh:set(ccIp, 1, 60, 1) -- 设置1分钟也就是60秒访问计数时间
else
if f == 2 then
return waf.block(true) -- 重置TCP连接,不记录日志
end
sh:incr(ccIp, 1)
if c + 1 >= 360 then
sh:set(ccIp, c + 1, 300, 2) -- 设置5分钟也就是300秒拦截时间
return true, ccIp, true
end
end

return false

IIS报错检测

过滤阶段:返回页面

规则描述:IIS返回页面的报错可能会泄露服务器敏感信息

规则内容:

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
local rgx = waf.rgxMatch
local rb = waf.respBody

local m = rgx(rb, "[a-z]:\\x5cinetpub\\b", "jo")
if m then
return m, rb, true
end

if waf.status == 500 then
local m = rgx(rb, "Microsoft OLE DB Provider for SQL Server(?:</font>.{1,20}?error '800(?:04005|40e31)'.{1,40}?Timeout expired| \\(0x80040e31\\)<br>Timeout expired<br>)|<h1>internal server error</h1>.*?<h2>part of the server has crashed or it has a configuration error\\.</h2>|cannot connect to the server: timed out", "jo")
if m then
return m, rb, true
end
local m = rgx(rb, "\\b(?:A(?:DODB\\.Command\\b.{0,100}?\\b(?:Application uses a value of the wrong type for the current operation\\b|error')| trappable error occurred in an external object\\. The script cannot continue running\\b)|Microsoft VBScript (?:compilation (?:\\(0x8|error)|runtime (?:Error|\\(0x8))\\b|Object required: '|error '800)|<b>Version Information:</b>(?:&nbsp;|\\s)(?:Microsoft \\.NET Framework|ASP\\.NET) Version:|>error 'ASP\\b|An Error Has Occurred|>Syntax error in string in query expression|/[Ee]rror[Mm]essage\\.aspx?\\?[Ee]rror\\b", "jo")
if m then
return m, rb, true
end
end

if waf.status == 404 then
local m = rgx(rb, "\\bServer Error in.{0,50}?\\bApplication\\b", "jo")
if m then
return m, rb, true
end
end

return false

php报错检测

过滤阶段:返回页面

规则描述:返回页面的php报错可能会泄露服务器敏感信息

规则内容:

1
2
3
4
5
6
7
8
9
10
11
local check = waf.plugins.phpErrorDetection.check
local rb = waf.respBody

if waf.status == 500 then
local m, d = check(rb)
if m then
return m, "php error: " .. d, true
end
end

return false

Java报错检测

过滤阶段:返回页面

规则描述:返回页面的java报错可能会泄露服务器敏感信息

规则内容:

1
2
3
4
5
6
7
8
9
10
11
local check = waf.plugins.javaErrorDetection.check
local rb = waf.respBody

if waf.status == 500 then
local m,d = check(rb)
if m then
return m, "Java error: " .. d, true
end
end

return false

请求方法加强

过滤阶段:请求阶段

规则描述:不常用的http请求方法会出现一些安全漏洞,如:历史上Apache平台TRACE请求方法出现过XSS相关漏洞

规则内容:

1
2
3
if not waf.rgxMatch(waf.method, "^(?:GET|HEAD|POST|PUT|DELETE|OPTIONS)$") then
return true, waf.method, true
end
  •  

使用 Docker 部署 Wiki.js

本文将介绍如何用 Docker 容器技术部署 Wiki.js 应用程序。Wiki.js 是一个高度可定制 Wiki 平台,用 Node.js 编写,支持 Markdown 以及 HTML 文档。Docker 容器技术可帮助我们简化部署过程,提高应用程序的可移植性和可扩展性。

安装 Docker 端

开始部署之前,我们需要确保已经安装了 Docker。Docker 是一个开源应用容器引擎,可以轻松地为任何应用程序创建一个轻量级的、可移植的、自给自足容器。要安装 Docker,

1
curl -fsSL https://get.docker.com | bash -s docker

本教材使用 Docker Compose 实现 Wiki.js 的一键部署,我们先通过下面的命令测试一下相关组件是否安装成功,显示版本即为成功。

1
docker compose version

获取镜像

在 Docker 中镜像是一个只读模板,可创建 Docker 容器。Wiki.js 官方提供了预构建 Docker 镜像,我们可直接从 Docker Hub 中拉取。为了简化部署过程,我们先创建 docker-compose.yml 文件,复制以下内容:

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
version: "3"
services:

db:
image: postgres:15-alpine
environment:
POSTGRES_DB: wiki
POSTGRES_PASSWORD: wikijsrocks
POSTGRES_USER: wikijs
logging:
driver: "none"
restart: unless-stopped
volumes:
- db-data:/var/lib/postgresql/data

wiki:
image: linuxserver/wikijs
depends_on:
- db
environment:
DB_TYPE: postgres
DB_HOST: db
DB_PORT: 5432
DB_USER: wikijs
DB_PASS: wikijsrocks
DB_NAME: wiki
restart: unless-stopped
ports:
- "80:3000"

volumes:
db-data:

编辑好上面内容后,执行下面的命令即可部署 Wiki.js:

1
docker compose up -d

初始配置

通过浏览器打开 Wiki.js 所在的服务器,进行初始配置。需要依次输入管理员的邮箱、密码,访问地址,设置是否匿名反馈使用情况:

管理员用户创建完成后,会自动跳转到登录页面,输入刚刚创建好的管理员账号后,可以看到如下页面,这时我们先点击 ADMINISTRATION 进入后台:

在后台面板中,我们首先汉化一下全站界面。点击左侧的 Locale,进入语言包设置页:

在右侧下载语言包,这里我们以 Chinese Simplified 为例,下载后在中间的 Site Localo 处选择 Chinese Simplified,最后点击右上角 APPLY 即可:

切换至首页后,即可创建主页内容。这里可以选择使用何种编辑器来创建,这里我们以 Markdown 为例:

在编辑内容前,我们还需要先设置页面属性,重点设置标题、路径,填写完成后点击右上角的 OK:

页面分级是通过标题级别实现的。这里我们就以二级标题为例,填写好内容后点击右上方的创建:

返回到主页后,即可看到相关内容。其它功能请伙伴们自行探索:

写在最后

通过 docker-compose.yml 可以看出来,服务已经做了 80 端口的映射,如果服务器中有其它的网站环境,建议修改 docker-compose.yml 中种 80 为其它端口。

另外如无 Nginx 等引擎,但需要 SSL 加密访问,推荐安装 Nginx Proxy Manager 来进行加密反代。

强烈建议先配置好访问环境「即配置好 Nginx Proxy Manager 后」再做 Wiki.js 初始化操作。

如果不会安装及配置 Nginx Proxy Manager,可在评论区中留言,杜老师会考虑编写相关教程。

  •  

如何使用 FFmpeg 来压缩视频

杜老师这段时间一直在剪辑视频,通过 Premiere 导出的文件太大,不便导入平台。本文介绍如何使用 FFmpeg 来压缩视频。分享 FFmpeg 的基本概念,如何安装和使用 FFmpeg,以及如何使用命令行工具来压缩视频。

简介

FFmpeg 是一套开源的多媒体处理框架,它提供丰富的工具和库,用于视频、音频和图像的采集、编码、解码、转换、流媒体和过滤等各种的操作。

FFmpeg 使用主要包括命令行工具和 API 接口。命令行工具提供丰富的参数,可完成各种多媒体处理任务。API 接口包括 Python 和 Java 等语言,开发者可根据自己的需求选择合适的接口进行开发。

安装

杜老师的主力系统是 Linux,下面分享基于 Ubuntu 系统的部署方式,如果小伙伴们需求 Windows 的安装方法,可以直接至官方下载安装包「或在评论区中留言」首先是更新软件源:

1
sudo apt update

安装必要的依赖项:

1
sudo apt -y install git build-essential

下载 FFmpeg 源代码:

1
git clone https://github.com/FFmpeg/FFmpeg.git

进入 FFmpeg 目录并编译:

1
2
cd FFmpeg/
./configure --enable-shared --enable-static --enable-libx264 --enable-libvpx --disable-yasm

编译并安装 FFmpeg:

1
2
make
sudo make install

命令

1
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -c:a aac -b:a 192k -movflags +faststart output.mp4

注意:要使用 FFmpeg 压缩视频,需要在命令行中输入相应的命令。上面是一个基本 FFmpeg 压缩命令。

解读

针对前面命令中的参数,介绍列表如下:

参数作用
input.mp4是要压缩的视频文件的路径。
output.mp4是压缩后的视频文件的输出路径。
-c:v libx264指定视频编解码器为 H264。
-crf 23指定压缩质量。CRF 值越低,视频质量越好,文件越大;CRF 值越高,视频质量越差,文件越小。范围通常在 18-28 之间。23 是一个比较适中的值。
-c:a aac指定音频编解码器为 AAC。
-b:a 192k指定音频的比特率为 192 kbps。
-movflags +faststart将元数据移动到文件的开头,以便在线流式传输时更快地开始播放。
  •  

群晖设备更换缓存磁盘

屋漏偏逢连夜雨啊,杜老师收到了群晖告警邮件,提示缓存磁盘寿命到临界值,需要更换。群晖官方缓存磁盘价格偏高,杜老师买的是第三方盘,也分享给需要的小伙伴用做参考,并简单讲解下群晖缓存机制。

损坏通知

群晖有两个告警机制的,一个是本地的告警机制,一个是云端的监控。前者先一步发送了告警通知,杜老师看到后,第一时间查看了磁盘的状态:

系统提示耐用性仅剩 1%,需先停用缓存机制,带数据同步至存储池后,才可将缓存盘取出「有人说支持热插拔,但为安全起见,还是将设备关机后,再做磁盘替换」

缓存机制

群晖缓存机制分为三种,其目的都是在提升效率同时,尽可能延长存储盘使用寿命。

第一种是读取缓存。将经常读取的文件,缓存至固态盘,使用固态盘的高速属性提升读取效率,同时降低了磁盘的读取次数,变相提升了机械盘使用寿命。

第二种是读写缓存。在进行数据读写时,优先将数据写入到缓存盘中,通过固态盘的高速特性,提升读写效率同时,也降低了机械盘的使用,变相提升了机械盘使用寿命。

第三种是做元数据缓存。考虑到 NAS 大容量的特性,在寻找文件的时候,会频繁读取硬盘数据以检索文件。如做好元数据缓存,会直接通过缓存盘的元数据,直接定位到存储盘文件,减少读取次数。

设备采购

之前用的是群晖官方推荐的希捷硬盘,但性价比不是很高,所以杜老师买了四款价位差不多,但性价比更高的盘,打算一一尝试,看哪一款可以兼容,其余的都退掉:

杜老师的运气不错,第一次尝试就完美兼容,其它的没测试,直接申请退款。本次用的是梵想国产 SSD,不知道性能和稳定性耐用性如何,有待测试:

重建缓存

进入到存储池,点击创建缓存:

杜老师的群晖只有一个存储空间,所以直接点下一步:

缓存模式根据实际情况选择,如果只有一块磁盘,要选只读缓存;两块磁盘可以读写缓存。需要注意的是,创建缓存盘后,原盘中的数据会被清空,所以如原盘有数据,记得做好数据备份:

群晖的缓存机制同样注重数据的安全,所以会强制 RAID 为镜像卷:

在列表中选中要成为缓存的磁盘,因为杜老师选的盘是非官方推荐,所以会弹出兼容性提示,无需理会,直接点击继续即可:

这里可以修改为缓存分配的容量。需要注意的是,分配容量越大,则占用的内存资源越多,所以在分配时,需要考虑到剩余内存的容量「杜老师加了条内存,完全够用」还有一点需要说明,可在此页面中设置是否将元数据固定到缓存中,确认之后不可再次调整:

都设置完成后,会生成配置页,显示之前所有配置。点击应用后会再次弹出数据擦除提示,点确定后结束创建缓存流程:

SSD 缓存创建后会自动初始化操作,其中固定元数据的时间较长,期间 NAS 可正常使用,但不可对所有硬盘做其它的操作:

  •  

将 GPT 整合到 Mattermost

聊天室有小伙伴建议整合 GPT,本来没想着能实现,谁知道随手搜了下,在 GitHub 上面还真有相关的服务源码。恰好杜老师在国外的主机平台上还有余额,就尝试搭建了一下,并记录相关的步骤。最后要提示下,杜老师测试时并未成功~

服务添加

首先进入到 Mattermost 后台,在左侧列表中找到集成,点击进入到机器人账户页面,开启机器人账号创建的功能,然后点击机器人账号项:

点击右上角添加机器人,输入用户名 chatgpt「可自定义」其余为可选项,小伙伴们可以按需填写:

创建机器人后,需要先将其邀请到团队,才能正常对话。点击团队名称,选择成员管理,在弹出页面中点击邀请人员,输入 chatgpt 后点击邀请即可:

这里提示一下,私信机器人是没有任何反应,需要在频道中艾特机器人用户名,杜老师测试时并未成功,所以没有截图:

服务部署

1
2
3
4
5
6
docker run -d --restart unless-stopped \
-e MATTERMOST_URL=https://mattermost.server \
-e MATTERMOST_TOKEN=abababacdcdcd \
-e OPENAI_API_KEY=234234234234234234 \
--name chatbot \
penndu/chatgpt-mattermost-bot:latest

注意:请使用海外的主机部署,毕竟要连接 API。其中 MATTERMOST_URL 为 Mattermost 服务器地址,MATTERMOST_TOKEN 为 Mattermost 机器人生成的令牌 ID,OPENAI_API_KEY 为 GPT 的 KEY 值,penndu/chatgpt-mattermost-bot:latest 是杜老师编译的 Docker 服务端,如果想获得官方版,可以在评论区留言获取。

  •  

用上了小米的澎湃系统

了解杜老师的小伙伴应该都知道,杜老师应该算是一枚米粉了,家里清一色的小米设备。前两天是红米的发布会,第二天就下单了 K70 Pro,当天就收到了预装最新的小米澎湃系统的手机,体验的过程中突然有了一些思考~

澎湃系统

澎湃系统是小米自主研发的移动操作系统,基于开源的 Linux 内核进行开发。澎湃系统在设计上充分考虑了移动设备的特点,如低功耗、高性能和安全性等。此外,澎湃系统还针对中国市场进行了优化,提供丰富的个性化设置和本地化服务。

上面的这段话,是杜老师引自麒麟系统介绍中的一小段话,改编一下发了出来。大家有没有发现到,还挺贴切?

自研系统

小米公司最开始是因 MIUI 起家,当时原生安卓不是特别好用,很多手机厂家就迎合国人的使用习惯,打造自己特色界面。

而 MIUI 极符合国人的使用习惯,加上其适配性较高,稳定性好,所以逐渐在安卓界占领一定市场。

直到小米公司开始推出手机,低价高配冲击市场,改变了原有的市场规则,让不少的国民可以享受到流畅的手机体验,智能端逐渐由 PC 转向了移动终端。

最先推出自研系统的手机厂家是华为,其鸿蒙系统杜老师并未用过,不过身边的华为小伙伴反馈是差不多,更多是生态联动带来的便利。

冲动换机

杜老师因为穷,所以在更新换代时都是很理智的。本次换机的原因是,之前的旗舰机用了已满两年,算是寿终正寝。系统支持已经快到期了「小米每隔几年,都不再适配旧设备系统」

杜老师对手机的流畅度没有太高要求,因为平时不玩游戏。但好奇心较重,总想体验一些新的功能,感受一下新的效果。

正好赶上红米的发布会,于是在第二天,下单了当前的旗舰机 K70 Pro,并于当天就收到了。入手第一件事就是换机「杜老师换机后会将之前手机回收处理」

可能是因为澎湃多少有一些改动,所以在换机时遇到不少问题。主要就是突发卡顿,需要重置任务才能继续迁移;还有就是系统设置迁移后的应用效果不同,这应该就是底层原因导致的。

使用体验

成功迁移好数据库,杜老师拿着之前的手机,对比了下两机系统差异「之前的手机运行 MIUI14,新手机澎湃 OS」

首先是界面差异性。新系统确实在界面上面做了一些改动,但也是仅仅改了些显示效果,操作逻辑并未太多改动,原有的功能在之前系统对应位置都能找到,并不需要重新学习新系统的使用。

其次是功能性。新系统主打的生态联动,可能因为家中小米生态并未同步更新澎湃系统,所以暂未体验到相应的便利,不过确实会有几个接口,让我们操作时多了几种方式。

最后是性能上。毕竟是跨了一代的新产品嘛,流畅度肯定比之前手机好了很多「杜老师为了提升使用的体验,开了很多特效,老手机可能是因为性能关系,运行部分特效时会有些卡顿」

对于自研系统,杜老师不知该如何评价。这是打破安卓垄断,以减少对谷歌 Android 依赖的一种有效途径,但其根本还是基于安卓搭建,如同华为鸿蒙系统,抹去了安卓的痕迹,换上鸿蒙的脸。

其实我们并不是用手机,而是在使用安装在手机系统上的软件。也就是说软件生态才是评价一款系统是否成功的关键性维度。

不知道澎湃是否会一直基于安卓系统,但澎湃如果成长到脱离安卓这条线路之后,是否还会有软件用。这就是国产自研的悲哀,只能在巨人的肩上二次开发,沿用原有软件生态。

有些小伙伴知道杜老师在麒麟公司上班时,都会问到:麒麟不就是 Linux?是的,因为一旦完全自研,那些 Windows 巨量的软件生态,我们又如何对抗呢?

  •  

7bu 图床插件 For WordPress/Typecho 分享

前几天有小伙伴询问是否有 WordPress/Typecho 的相关插件,可惜杜老师能力有限不会弄,就只能求助于群里的小伙伴,果然有大神帮忙设计了出来。在此感谢 Xin Huai W L 帮忙制作了插件,分享给需要的小伙伴们!

WordPress 插件的食用教程

为了测试插件,杜老师特地安装 WordPress。进入后台进入到添加新插件页面,从下面的链接中下载 WordPress 插件,并上传到博客:

上传后直接启用就行了,但需要先设置 Token 才可以使用:

如您使用去不图床托管,请在网址设置框输入 https://7bu.top,Tokens 框中输入在图床获取的 TOKEN,并可以选择是否要公开图片:

写文章时可在右侧看到插件模块,直接拖拽上传图片即可:

WordPress 插件的下载地址

下载地址:

下载地址

Typecho 插件的食用教程

Typecho 需要手动上传到插件目录,后台刷新一下就能看到,直接启用即可:

在正式使用前,需要先设置下。如您使用去不图床托管,请在网址设置框输入 https://7bu.top,Tokens 框中输入在图床获取的 TOKEN,存储 id 为空就行了:

Typecho 插件的下载地址

下载地址:

下载地址
  •  

游戏服务器被坑黑历史二

上篇提到杜老师购买小厂独服时遇到的坑,但这坑并未阻止杜老师运营游戏服的决心。小厂不行咱选大厂,凉心云性能和稳定性都可以,这回总不能再被坑了吧?事实说明,有些坑只有想不到,没有它坑不到~

转战大厂

上面提到,面板服满足不了运营的需求,小厂的独服又太坑,小伙伴们又在群里嗷嗷待哺「催促开服」没办法只能大出血,购买大厂的服务器。

最终杜老师选择凉心云的企业服,配置上绝对够,不过有个硬性要求:需要企业身份。

入坑开始

杜老师自己也开过公司,奈何因为疫情关系早已注销,目前手中没有任何经营许可,无法注册企业用户。

和小伙伴们交流了一下,有小伙伴推荐可以通过代理买到企业账号。

杜老师尝试搭配各种关键词,在某平台上搜到了交易信息。在与卖方沟通中了解到,他们售卖的企业信息是通过合法渠道获得,选择的都是非互联网的公司,这就避免了账号冲突的可能,保证了账号可用率。

而且支持解绑安全认证,这样就可以修改邮箱和手机,防止卖方账号回收。

所谓吃一堑长一智,杜老师有了前面的经历,必然不会遇到坑闷头莽,同时咨询了凉心云官方客户,问了账号收回的可能性。官方表示只要有注册的邮箱、手机就不会被他人盗用「肯定不能说从他人手里买的账号」

有了以上这些信息,终于可以放下心购买了。使用企业账号购买企业服是真香,那配置那价格~

问题浮现

当凉心云还是良心云的时候,那服务是真心的好。被称为凉心云,并不是稳定性差了,而是增加一些道路,变相从我们的手中扣钱。

但大厂终究是大厂,稳定性没得说,而且因为配置较高,游戏体验非常优异。

但一天的凌晨,杜老师还记得,那会还在东北老家,因为第二天要赶车回京,所以早早睡了。突然听到手机信息提示,说凉心云的密码被改了,看到后一下子就清醒了。

第一时间打开电脑,上线查看服务器的运行状态。当时并无任何异常,也就没太在意,检查一下服务器的备份情况「因运维工程师的工作有备份习惯」后就睡了。

第二天坐上回京的高铁后,收到了群里小伙伴信息,说服务器上不去了。当即打开电脑连上手机热点检查原因,然后就傻眼了,服务器被申请退款~

服务器因申请退款直接销毁,里面的数据都没了「还好有完整的备份」因为购买时间较短,还有余额被原路退回了,但之前已用的时长按照原价计算~

到北京后联系了之前的卖家,首先是一问三不知,然后是拉黑来不及握手,流程特别熟练都感觉是惯犯。

之后也问了凉心云客服,将之前留存的咨询信息发了过去,质问为何被人强制退款,人家说新增了申述服务,企业可以通过法人代表申述账号,额呵呵呵~

写在最后

后来 MC 转战为内网搭建,但随着游玩人数的减少,游戏服也随之停止运营。后期交由 Vian 运营过一段时间,但因其服务器到期,最终也停服了~

很多大厂都有新用户的活动,相比老用户的优惠力度很大,不少的小伙伴会借用身边朋友的身份注册购买所需服务。

但有些服务要企业账号才能购买。虽然一些平台提供企业账号资源,但墙裂建议不要去选购,毕竟有被收回风险。丢失数据带来损失,往往比注册一个公司的成本还大,一定要权衡好利弊。

肯定有小伙伴说杜老师又在水了,明明可以写在一篇,为啥分了两篇。很抱歉最近的身体有些欠佳,染上风寒目前卧病在床,每天还要忍受肺子刻出来的痛苦,还能补上文章实属不易,且读且珍惜吧!

  •  

游戏服务器被坑黑历史一

最近一是因为太忙,二是实在不知更新啥好,就托更了。昨晚临睡前回想起当初搭建游戏服务器时遇到的那些坑,就琢磨着分享出来,谨记教训之余也可告诫他人,希望小伙伴们不要遭遇同样问题。

历史背景

杜老师很少玩游戏,MC 可以说是为数不多常玩的游戏之一,但自己玩终究太过单调,就想着自建一个服务器,邀请小伙伴们一起游玩。

当初想着人数不会太多,且没考虑模块、插件问题,就想着弄个便宜的服务器先跑着,最终在某宝上选中了一款面板服务器。而这就是被坑的开始了~

MC 面板服

杜老师之前并未了解过 MC 面板服务器,第一印象就是便宜、省事,这也是一眼相中的原因。

随之开始建服,并邀请小伙伴前来一起游玩。

在游玩过程中,有些小伙伴提出了一些需求,比如添加箱子锁的功能,允许划分领地等等,这就需要不断加载插件才能实现。

随着需求越来越多,插件数量随之增加。服务器的负载增大,游戏延迟增高,严重影响了游玩的体验。

并且有些插件对运行的环境要求较高,在面板服中无法使用中文版界面。

以上种种都说明面板服无法满足小伙伴的游戏需求,那么就进军独服吧!

独服深坑

之前有说到插件的增加,导致服务器的负载增大,进而造成游戏延迟增高。为了解决这个问题,杜老师一直有升级面板服的配置。这种不断砸钱的行为也增加店家的好感值。

直到杜老师表达要选择独服,店家秒回可以推荐一款永久的服务器「即为买断」这里需要注意的是,该店铺里仅经营面板服,并未有独服的相关产品。

因为前期沟通非常愉快,杜老师并未有任何怀疑,当即转账付款。然而在数据迁移后,问题接踵而来。

首先是稳定性问题。杜老师不知道店家的服务器从哪来的,总之极不稳定,而且这种不稳定是宿主机导致的,也就是说没有任何的手段可避免这种情况。

前后反馈过许多次,店家都以非常好的态度保证积极解决,但问题并未有任何改善。

期间杜老师申请过退款,店家以更换新主机为由,邀请再体验个七天,且原主机依旧保留,简单来说就是花一份钱,买到两个永久独服。

是不是很开心?并不是的!新服务器也无不的糟糕,网络延迟特别严重,且性能极拉胯,磁盘 IO 特别低,杜老师都怀疑是不是在拿 TF 存储卡作为硬盘用。

最后杜老师申请了退款,然而超过七天,不符合无理由退款规则。也邀请了平台介入,奈何证据不足,最终拒绝退款,后面服务器被收回,费用完全打水漂了。

买的教训

购买服务器前,先确定店家的规模,像套路云这种大厂是无所谓,如果是那种不知名小厂,强烈建议短期购买,先用一段时间测试性能和稳定性,满足要求后再长期购买。

而且不建议一次买个三年五载的,一年一年买最靠谱,别信什么买断,万一哪天老板挂了,再想找回就困难了。

其次淘宝买的东西,一定要在淘宝上面交流。之前店家就以 QQ 交流方便且支持远程,前后一直在 QQ 上面交流,提交证据时也选择聊天截图,但非淘宝外的记录平台都不认可!这也是上面提到证据不足的根本原因。

最后在退款前,一定要对购买产品页面进行截图「售后细节」以免店家偷偷修改协议,当然现在某宝支持购买时的商品快照。还有就是七天无理由要大于口头协定,宁愿退款重新购买,也不要相信店家的延长试用。

  •  

推荐一款开源的 Markdown 编辑工具

聊到 Markdown 编辑器,很多朋友可能会想到 Typora,奈何它收费了。今天推荐这款软件是免费开源的 Markdown 编辑器,好用而且开源免费,MarkText 凭借其强大特性和用户友好的界面脱颖而出,成为让人畅快写作利器。

实时预览与纯粹写作的沉浸体验

MarkText 的最大魅力之一是其实时预览功能,所见即是所得,让您在编辑的同时即时查看最终效果。它拥有干净简洁的用户界面,带来无干扰的写作体验,让您全身心投入到创作,而不会受到繁琐的界面干扰:

支持且无缝转换多种 Markdown 规范

MarkText 支持 CommonMark 规范和 GitHub Flavored Markdown 规范,保证了 Markdown 文本的正确显示和解析。它还提供选择性支持 Pandoc,让您的文本在不同平台间无缝转换保持统一的格式:

强大的 Markdown 扩展功能

除了基本的 Markdown 语法,MarkText 支持多种 Markdown 扩展功能。数学表达式 KaTeX、表情符号等功能的支持,使得您的文稿更加生动、丰富:

智能快捷键以提高写作效率

MarkText 内置许多段落和内联样式的快捷键,让您在写作过程中更加高效。同时,支持 HTML 和 PDF 文件的输出,无论分享还是保存,都能得心应手:

丰富的主题和编辑模式

MarkText 提供了多种主题选择,如 Cadmium Light、Material Dark 等,支持多种编辑模式,包括源码模式、打字机模式和专注模式。无论白天还是夜晚,都可以找到适合自己的编辑环境:

多平台支持可无缝切换

MarkText 覆盖 Linux、macOS 和 Windows 等多个操作系统,保证用户在不同平台上的使用一致性。无论您是在台式机还是笔记本上写作,都能无缝切换,持续流畅写作体验:

直接粘贴图片方便快捷

您可以直接从剪贴板粘贴图片到 MarkText 的编辑器中,省去了繁琐的插入步骤,让您更专注文本内容的创作:

支持 HTML 和 PDF 文件输出方便分享与保存

MarkText 不仅可以输出 HTML 文件,还可以生成 PDF 文件,无论您需要在网络上分享还是保存为文档,都能得心应手。下方为最新版下载地址:

下载地址
  •  

一款强大番茄工作法工具 Pomatez

这是一款健康的规律性工作学习管理利器,有效安排工作、学习、休息时间,提高工作效率,是考研党、办公室白领等必备神器。Pomatez 通过利用番茄工作法原理,帮助用户集中注意力提高专注力,有效管理工作时间。

写在文章前面

杜老师最近因为工作的关系,休息不是特别充足,导致脑力不够,效率很低。为了集中注意力提高专注力,杜老师经常会使用 Windows 自带的专注功能,奈何因为公司要求,需使用自己公司开发的操作系统,故找了款跨平台的操作系统:

下载地址

番茄工作简介

番茄工作法是一种时间管理技术,通过将工作时间划分为一段短暂的时间段,称为番茄时段,在每个番茄时段后休息一段时间,以提高专注力、工作效率。用户可以使用 Pomatez 设置和计时番茄时段,每个时段专注一项任务,避免分心、干扰。在每个番茄时段后,Pomatez 还提供休息时间,让用户休息和放松,以保持高效的工作状态:

任务管理提醒

Pomatez 提供任务管理和提醒功能,帮助用户更好地组织和追踪任务。用户可以创建任务列表,将任务按优先级和类别进行组织,清晰了解待办事项。Pomatez 可以发送提醒和通知,帮助用户记住重要的任务和截止日期,避免遗漏:

番茄统计报告

Pomatez 提供统计和报告功能,让用户了解自己的工作习惯、效率。Pomatez 记录用户的番茄时段、休息时间,生成工作时长统计报告,帮助用户了解自己的工作习惯和时间分配。用户可以标记任务完成情况,Pomatez 生成任务完成度报告,让用户清晰了解任务进展和完成情况:

定制化扩展性

Pomatez 具有一定定制化和扩展性,用户可根据自己的需求进行个性化设置和功能扩展。用户可根据自己的工作习惯和注意力集中度设置番茄时段的长度,以适应个人的工作节奏。Pomatez 提供不同主题和界面样式,用户可以选择适合自己的界面外观和使用体验:

写在文章最后

Pomatez 作为一款提高工作效率番茄工作法工具,无论个人学习、工作任务还是时间管理,Pomatez 都可以帮助用户更好地组织和管理工作流程,提高工作效率、成果产出。尝试用 Pomatez,让您的工作时间更加专注和高效:

  •  

冬天啦封车啦

帝都来暖气了,南方的小伙伴是不是很羡慕。北京的季节有两个:夏季、冬季,就是没有春秋。前一天还短袖,第二天就要穿棉袄。随着温度降低,杜老师也很少去骑行了,于是决定封车,毕竟这是一种仪式!

何为封车

封车一词并非术语,而是车友间口头语,意思是近段时间暂时不骑行,将车闲置起来。但并非简单放置在一边即可,而是需先对车辆进行轻维护,使其在存放期间的刚性不变「刚性:自行车的刚性包含很多地方轮组、车架、传动等等。如果刚性不足,就会发生刹车和碟片摩擦等情况,这就会损失速度了」这里配个图片,给小伙伴们分享下车辆各部件的名称:

车辆维护

大保养的项目:

  1. 更换重要部件。大保养通常需要更换公路车重要部件,如轮胎、刹车片、链条、变速器等;
  2. 检查刹车系统。刹车系统是保障骑行安全的关键部件,大保养需要对刹车系统进行全面检查,确保刹车性能良好;
  3. 检查传动系统。传动系统是自行车动力来源,大保养需要对传动系统进行检查,确保传动效率和耐用性;
  4. 整车清洁。大保养需对公路车进行彻底清洁,去除污垢、尘土,保持车辆美观。

小保养的项目:

  1. 清洁。小保养需对公路车进行日常清洁,保持车辆外观整洁;
  2. 润滑。小保养需要对公路车的传动系统、刹车系统等关键的部位进行润滑,确保骑行顺畅;
  3. 更换耗材。小保养需要对公路车的轮胎、刹车片等易耗的部件进行检查和更换;
  4. 检查。小保养需要对公路车的刹车系统、传动系统等进行日常的检查,确保骑行安全。

解决方案

杜老师右腿半月板有伤「高中时打网球导致」所以平时无法通过远足、跑步、跳绳等方式来锻炼身体。而 HIIT 这种高强度间歇性锻炼又会导致低血糖而头晕,所以杜老师目前靠骑行作为主要锻炼途径。现在封车,杜老师又是如何锻炼呢?恰逢双十一杜老师入手了一个骑行台,这样就可以在家中骑行锻炼:

使用体验

首先是安装的问题。因为杜老师买的带有飞轮的一款,所以安装时无需再拆除车身飞轮,这样就简化了组装过程。

之前杜老师分享过骑行日志,看过的小伙伴也许知道,杜老师一般去骑行,都是一个小时起步,距离是 25+ 公里。

而这个骑行台因为自带阻力,所以骑行阻力远比真实路面上大。骑行台配套的软件模拟环境有限,导致短时间内就被拉爆「骑行用词,短时间的力量爆发后会脱力,称为拉爆」

再加上家中的温度较高,没有骑行时流动风,平均不到十分钟就汗流浃背,很难坚持下去!希望平台今后可以提供更多模式~

  •  

CPU 调频模式和中断设置

随着计算机技术的发展,CPU 性能和功能也在不断提升。为了更好地满足各种应用场景的需求,现代 CPU 提供多种调频模式和中断设置。本文将探讨 CPU 调频模式和中断设置的原理、应用场景及如何合理设置以实现性能和功耗的平衡。

话题背景

本不知道今天写点啥好,在聊天室和小伙伴们交流时,obaby 美女说准备换一个路由器,原因是 CPU 使用率比较高。之前有聊过建立内网服务器事项,obaby 就是通过 CDN 反代家中的服务器,当访问量比较大时,就会出现 CPU 使用率比较高的问题:

相比 obaby 的私人博客,杜老师自信去不图床的访问量更大些,就准备调试下家中核心路由的 CPU 性能,尽可能的提升路由效率。先说下杜老师家中核心路由配置,N6000 处理器 4G 的内存,运行 iKuai 免费版。调试时发现有五种模式,这几个模式有什么区别,又该如何选择,下面详细说明:

调频模式

针对上图中出现的名词解释如下:

名称作用解释
performance性能模式这个模式系统会按设定最大主频率满负荷运转,主频会一直保持在设定范围内最大值。
conservative平滑调整模式在此模式下系统会回设置较低的频率下降响应参数,主频在空闲时下降更快,更加节能,但 CPU 速度调整会相对慢。
powersave省电模式此模式下系统将保持在设定最小的频率低负荷运行。
ondemand快速调整模式这个模式一般是系统的默认模式,根据需要自动调节 CPU 的频率,此模式的特点是频率升高需条件触发,反应迅速,频率下降无需触发,不需要高频率时会自动渐渐下降。
schedutil调度模式更快的响应速度和更精准的调频,更加节能。

中断控制

什么是硬中断:外围硬件发给 CPU 或者内存的异步信号就称为硬中断;

什么是软中断:由软件系统本身发给操作系统内核的中断信号,称之为软中断。通常是由硬中断处理程序或进程调度程序对操作系统内核的中断,也就是我们常说的系统调用。

区别联系

  1. 硬中断是有外设硬件发出的,需要有中断控制器参与。过程是外设侦测到变化,后告知中断控制器,中断控制器通过 CPU 或内存的中断脚通知 CPU,然后硬件进行程序计数器及堆栈寄存器之现场保存工作,并根据中断向量调用硬中断处理程序进行中断处理;

  2. 软中断则通常是由硬中断处理程序或进程调度程序等软件程序发出的中断信号,无需中断控制器之参与,直接以一个 CPU 指令之形式指示 CPU 进行程序计数器及堆栈寄存器之现场保存工作,并调用相应软中断处理程序进行中断处理;

  3. 硬中断直接以硬件方式引发,处理速度较快。软中断以软件指令之方式适合于对响应速度要求不是特别严格的场景;

  4. 硬中断通过设置 CPU 屏蔽位可进行屏蔽,软中断则由于是指令之方式给出,不能屏蔽;

  5. 硬中断发生后,通常会在硬中断处理程序中调用一个软中断来进行后续工作处理;

  6. 硬中断和软中断均会引起上下文切换,进程切换的过程是差不多的。

中断效果

关闭软中断后效果:CPU 不使用系统调用,硬中断处理时,CPU 负载不均衡。

关闭硬中断后效果:关闭硬中断后硬件 CPU 会默认保留一个,关掉硬中断后,软中断全部开启负载让 CPU 起到了一个均衡作用,CPU 使用率比较平均。

注意事项

软中断和硬中断不可以同时关闭。即使界面显示全部关闭,也会保留一个默认的核心作为硬中断。

在某个 CPU 使用率较高的时候,可将这个 CPU 软中断关闭,这样使其 CPU 使用率降低,负荷负载到其它的 CPU 核心上。

  •  

介绍 5 款漏洞扫描工具

最近去不图床频繁遭受攻击,除流量攻击外,还有一些漏洞攻击。今天杜老师为小伙伴们推荐 5 款漏洞扫描工具,部分工具是开源的,有些是收费的,但其试用版本也满足我们这种小博主需求,感兴趣的可以试试!

sqlmap

sqlmap 是款用来检测与利用 SQL 注入漏洞的免费开源工具,有一个非常棒的特性即对检测与利用的自动化处理「问底层文件系统、执行命令」

Nikto2

Nikto2 是款开源的网页服务器扫描器,它可以对网页服务器进行全面的多种扫描,包含超过 3300 种有潜在危险的文件;有超过 625 种服务器版本;有超过 230 种特定服务器问题:

skipfish

谷歌创建的 Web 应用程序安全扫描程序,是种活跃的 Web 应用程序安全侦察工具。通过执行递归爬网和基于字典的探针为目标站点准备交互式站点扫描。然后使用许多活动「但希望无中断」安全检查的输出对结果映射进行注释。该工具生成的最终报告旨在作为专业 Web 应用程序安全评估的基础:

ZAP

Zed Attack Proxy 攻击代理服务器是世界上最受欢迎免费安全工具之一。ZAP 可以帮助我们在开发和测试应用程序过程中,自动发现 Web 应用程序中安全漏洞。另外,它也是一款提供给具备丰富经验的渗透测试人员进行人工安全测试的优秀工具:

OpenVAS

OpenVAS 漏洞扫描器是种漏洞分析工具,由于其全面的特性,可以使用它来扫描服务器和网络设备。这些扫描器将通过扫描现有设施中的开放端口、错误配置和漏洞来查找 IP 地址并检查任何开放服务。扫描完后,将自动生成报告并以电子邮件的形式发送,以供进一步研究和更正。OpenVAS 也可以从外部服务器进行操作,从黑客的角度出发,从而确定暴露端口或服务并及时进行处理。如果您已经拥有一个内部事件响应或检测系统,则 OpenVAS 将帮助您使用网络渗透测试工具和整个警报来改进网络监控:

  •  

自建 CDN 服务器思路

有小伙伴希望杜老师出一篇自建 CDN 的教程,其实网上有那种集成的系统,如 wdCDN。不过这类系统几乎都有节点限制,如果想搭建更多的节点,则需支付相应费用。对此杜老师有一套自用的 CDN 搭建思路,今天同需要的小伙伴分享下!

搭建思路

如图。当用户访问去不图床时,首先通过网络解析域名。杜老师购买了专业版 DNSPod,可以通过地域判断实现智能解析,将请求交给最近一台服务器处理。服务器前置了雷池 Web 应用防火墙,拦截一波攻击流量,正常流量留置反代服务器上。反代节点连接到内穿服务器,从中获得网站数据。而去不图床通过企业路由器内置模块架设内网穿透,以保障连接稳定及高效。因为绘制空间有限,在这里文字说明下,去不图床有 7 个反代服务器,相当于同数量的 CDN 节点。相比常规 CDN 内置 DNS 智能解析,杜老师则借助了 DNSPod「DNSPod 免费版也可实现智能解析,只是地域判断不够精细」

宝塔面板

如您使用宝塔面板,在搭建反代节点时,可先点击网站——添加站点,输入域名后点提交。进入站点设置——反向代理,如下图填写相关的信息即可。这里需要注意的是,为了实现类似 CDN 的加速功能,记得开启缓存,时间根据实际情况填写即可:

1Panel 服务器面板

如您使用 1Panel 服务器面板,在搭建反代节点时,可先点击网站——创建站点——反向代理,输入域名后点提交。进入站点配置页面——反向代理——编辑,如下图填写相关的信息即可。这里需要注意的是,1Panel 服务器面板默认支持 gif|png|jpg|css|js|woff|woff2 格式的缓存,如需缓存其它文件,还需自行修改配置文件:

雷池 Web 应用防火墙

雷池 Web 应用防火墙除可以反代外,还能防御攻击。但本身的特性使得无法缓存数据,即每次访问时都需回源请求数据,故无法实现类似于 CDN 的缓存加速功能。杜老师用其做前置,主要过滤攻击数据,防止无效流量消耗,变相提升了带宽使用率。其防御效果很不错,建议配合其它服务「带有缓存功能」一并使用,如 Nginx Proxy Manager:

南墙 Web 应用防火墙

也是机缘巧合接触到了南墙 Web 应用防火墙,精力有限还未与雷池 Web 应用防火墙做对比,但其内置 CDN 缓存功能很好用,并支持多节点回源、定义回源策略等等。需要注意的是,在添加站点时开启 CDN 后,还需进入 CDN 加速页面中,添加缓存规则,默认支持 jpg|png|bmp|gif|ico|css|js 格式的缓存:

DNSPod 免费智能 DNS 解析

DNSPod 专业版支持 10 个负载均衡节点「免费版仅 2 个」TTL 最小值 60 秒,可在单点故障时迅速切换至其它可用节点。并且可以使用更加精细的地域性智能解析:

  •  

ServerStatus 多服务器云监控

去不图床数据托管量已超过 23 万,有一些小伙伴反馈说外链速度慢了些,于是杜老师有增加几个节点。由于是自建 CDN,为了保障外链稳定,设置了云监控,同时将该工具分享给需要的小伙伴们!

工具介绍

通过下方截图可以看出,去不图床托管图片数超过了 23 万,数据占用超过了 93G。有一些小伙伴反馈说外链速度慢了些,于是杜老师有增加几个节点。由于是自建 CDN,为了保障外链稳定,设置了云监控,ServerStatus 中文版是一个酷炫高逼格的云探针、服务器云监控、多服务器探针:

配置文件

ServerStatus 在启用服务之前,需先通过配置文件设置监控对象,将下面的内容根据需求调整,保存为 serverstatus-config.json

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
{
"servers":
[
{
"username": "s01",
"name": "vps-1",
"type": "kvm",
"host": "chengdu",
"location": "🇨🇳",
"password": "USER_DEFAULT_PASSWORD",
"monthstart": 1
},
],
"watchdog":
[
{
"name": "服务器负载高监控,排除内存大于32G物理机,同时排除俄勒冈机器",
"rule": "cpu>90&load_1>4&memory_total<33554432&name!='俄勒冈'",
"interval": 600,
"callback": "https://yourSMSurl"
},
{
"name": "服务器内存使用率过高监控",
"rule": "(memory_used/memory_total)*100>90",
"interval": 600,
"callback": "https://yourSMSurl"
},
{
"name": "服务器宕机告警,排出俄勒冈,排除s02",
"rule": "online4=0&online6=0&name!='俄勒冈'&username!='s02'",
"interval": 600,
"callback": "https://yourSMSurl"
},
{
"name": "DDOS和CC攻击监控",
"rule": "tcp_count>600",
"interval": 300,
"callback": "https://yourSMSurl"
},
{
"name": "服务器月出口流量999GB告警",
"rule": "(network_out-last_network_out)/1024/1024/1024>999",
"interval": 3600,
"callback": "https://yourSMSurl"
},
{
"name": "你可以组合任何已知字段的表达式",
"rule": "(hdd_used/hdd_total)*100>95",
"interval": 1800,
"callback": "https://yourSMSurl"
}
]
}

杜老师收集了几个参数作用,供小伙伴参考:

参数作用
! rule可设置为任何已知字段的表达式
! interval最小通知间隔
! callback可自定义为 POST 方法的 URL,告警内容将拼接其后并发起回调
! callback Telegramhttps://api.telegram.org/bot/sendMessage?parse_mode=HTML&disable_web_page_preview=true&chat_id=&text=
! callback Server酱https://sctapi.ftqq.com/.send?title=ServerStatus&desp=
! callback PushDeerhttps://api2.pushdeer.com/message/push?pushkey=&text=
! callback BasicAuthhttps://USER:PASS@URL/api/push?message=

部署方法

Server 服务端,首先在配置文件同级目录执行 mkdir serverstatus-monthtraffic 创建目录,然后执行下方命令即可启用服务:

1
docker run -d --restart=always --name=serverstatus -v ~/serverstatus-config.json:/ServerStatus/server/config.json -v ~/serverstatus-monthtraffic:/usr/share/nginx/html/json -p 80:80 -p 35601:35601 cppla/serverstatus:latest

Client 客户端,客户端不支持用 Docker 部署,直接使用下方命令即可自动部署:

1
wget --no-check-certificate -qO client-linux.py 'https://raw.githubusercontent.com/penndu/ServerStatus/master/clients/client-linux.py' && nohup python3 client-linux.py SERVER={$SERVER} USER={$USER} PASSWORD={$PASSWORD} > /dev/null 2>&1 &

不同主题

默认监控页面如下,点击服务器项可以查看详细信息,包含内存、硬盘、网络情况等等,页面每三秒会自动刷新:

这个是用户自定义模板,如需用该模板,需要手动部署 Server 服务端,无法使用 Docker 的方式部署:

这款是杜老师目前用的主题「目前部署在内网中,暂时无法公布演示链接」

  •  

Kutt 开源的网址缩短程序

Kutt 是一个开源的短网址程序,有了它可以在分享一些很长的链接的时候,进行缩短链接,使得分享 URL 更简洁。支持容器部署,虽是英文界面,但操作很简单,感兴趣的小伙伴可以试一下~

支持特性

  1. 开源免费;

  2. 自定义域支持;

  3. 缩短链接自定义 URL;

  4. 设置链接密码;

  5. 设置链接描述;

  6. 链接过期时间;

  7. 查看、编辑、删除、管理链接;

  8. 管理员帐户可查看、删除、禁止链接。

程序部署

如果常规安装的话需要安装 Node.js/PostgreSQL/Redis 等,所以用 Docker 来安装这个是最简单的。将下方的代码保存为.env

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
# App port to run on
PORT=3000

# The name of the site where Kutt is hosted
SITE_NAME=Kutt

# The domain that this website is on
DEFAULT_DOMAIN=localhost:3000

# Generated link length
LINK_LENGTH=6

# Postgres database credential details
DB_HOST=postgres
DB_PORT=5432
DB_NAME=postgres
DB_USER=
DB_PASSWORD=
DB_SSL=false

# Redis host and port
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=

# Disable registration
DISALLOW_REGISTRATION=false

# Disable anonymous link creation
DISALLOW_ANONYMOUS_LINKS=false

# The daily limit for each user
USER_LIMIT_PER_DAY=50

# Create a cooldown for non-logged in users in minutes
# Set 0 to disable
NON_USER_COOLDOWN=0

# Max number of visits for each link to have detailed stats
DEFAULT_MAX_STATS_PER_LINK=5000

# Use HTTPS for links with custom domain
CUSTOM_DOMAIN_USE_HTTPS=false

# A passphrase to encrypt JWT. Use a long and secure key.
JWT_SECRET=securekey

# Admin emails so they can access admin actions on settings page
# Comma seperated
ADMIN_EMAILS=

# Invisible reCaptcha secret key
# Create one in https://www.google.com/recaptcha/intro/
RECAPTCHA_SITE_KEY=
RECAPTCHA_SECRET_KEY=

# Google Cloud API to prevent from users from submitting malware URLs.
# Get it from https://developers.google.com/safe-browsing/v4/get-started
GOOGLE_SAFE_BROWSING_KEY=

# Your email host details to use to send verification emails.
# More info on http://nodemailer.com/
# Mail from example "Kutt <support@kutt.it>". Leave empty to use MAIL_USER
MAIL_HOST=
MAIL_PORT=
MAIL_SECURE=true
MAIL_USER=
MAIL_FROM=
MAIL_PASSWORD=

# The email address that will receive submitted reports.
REPORT_EMAIL=

# Support email to show on the app
CONTACT_EMAIL=

在同级目录下,将下方的代码保存为 docker-compose.yml

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
version: "3"

services:
kutt:
image: kutt/kutt
depends_on:
- postgres
- redis
command: ["./wait-for-it.sh", "postgres:5432", "--", "npm", "start"]
ports:
- "3000:3000"
env_file:
- .env
environment:
DB_HOST: postgres
DB_NAME: kutt
DB_USER: user
DB_PASSWORD: pass
REDIS_HOST: redis

redis:
image: redis:6.0-alpine
volumes:
- redis_data:/data

postgres:
image: postgres:12-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: kutt
volumes:
- postgres_data:/var/lib/postgresql/data

volumes:
redis_data:
postgres_data:

启用服务

修改.envDEFAULT_DOMAIN=localhost:3000 值,将 localhost 改为域名,不然访问时会跳转出错。并确保邮箱相关的配置正确:

1
2
3
4
5
6
MAIL_HOST=
MAIL_PORT=
MAIL_SECURE=true
MAIL_USER=
MAIL_FROM=
MAIL_PASSWORD=

然后通过下方命令启动服务:

1
docker-compose up -d

注意事项

Kutt 默认是没有管理员用户的,需要通过邮箱注册,所以需要.env 里邮箱相关的内容都配置正确。

注册账号时始终提示失败 an error occurred,虽然不影响短链接的生成及使用,但无法登录管理员后台还是很难受的。

注册失败实际是没有发邮件激活成功,通过在作者的 Issues 里发现了有很多人大量反馈此问题,应该是对接 SMTP 服务的 bug。

这种方式可通过登录 PostgreSQL 容器,查找到对应用户验证 Token,再访问 URL 激活即可。

  •  

感谢王云子小朋友寄送的明信片

昨天收到了王云子小朋友送的明信片,本想发到说说广场小秀一下。后来琢磨写一篇文,一并感谢下建站以来认识的小伙伴们,因为大家,杜老师有了坚持更新的动力!

秀明信片

昨天下午正忙着呢,突然收到一个陌生号码来电,杜老师 12 年没更换过手机号,所以经常会有一些陌生来电,对于这类电话,一般都是第二遍才会接,故没有管。等到第二次又打来,才接起来,被通知去公司前台。刚开始还以为自己犯事了呢,赶到后就收到了两张明信片:

为了保护隐私,就马掉了一些细节,不过透过文字,还是可以看到满满祝福「西湖附近的一个小书店,感到十分欢喜,希望这份欢喜分享给你」

开始用手机相机拍半天,因为光线的原因始终不满意,后来想起了公司还有扫描仪,就付费操作了一下「挺老大的公司,扫描还要计算成本,可以信吗」

开始以为是两个小伙伴发的,仔细看后发现都是来自王云子小朋友,见字如面,看来是个可爱温柔的小姑娘「杜老师没见过真人」

写在后面

首先说下,之前关关童鞋也说邮寄了明信片,奈何家中地址收不到明信片,故一直未收到。但心意收到了,在此表示感谢!

杜老师建站已三年多了,认识了很多小伙伴,他们会经常光临本小站,在闲聊中放松心情,在讯问中提供建议。杜老师也在互动中维持热情,在催促中更新博文,虽说偶尔会有托更、水文,但小伙伴们的支持依旧不减。

杜老师要感谢那些帮助过博客建设的小伙伴们。杜老师的前端能力不足,他们的热心帮忙解决了不少问题,才使杜老师说长期稳定呈现各位面前。

杜老师要感谢那些经常来光顾的小伙伴们,踊跃的互动给博客带来活力,也为杜老师说的运营带来了热情。

还要感谢去不图床的用户们,在拥有更多优质平台选择下,他们依旧使用去不图床,虽然偶尔会出现抽风等问题,他们依然不离不弃。杜老师在表示感激同时,也表示很抱歉,同时表示未来会尽全力保障图床的稳定性。

最后感谢使用杜老师说旗下平台的用户们,包括说说广场、聊天室等。毕竟是个人的平台,安全性和稳定性都无法保障,但仍有不少小伙伴将数据托管在平台上面,这种信任值得感激。

  •  

DBeaver 开源跨平台的数据库管理工具

数据库连接工具是后端程序员必须要用到工具,常用的 Navicat 但要收费。今天给大家推荐一款开源免费的数据库连接工具 DBeaver,界面简单易用,用户可轻松执行各种数据库操作,比如查询、修改、备份等等。

功能特性

  1. 几乎支持所有的数据库产品,包括MySQL等:
  1. DBeaver 采用 Eclipse 框架开发,支持插件扩展,可根据自己的需求安装插件。

  2. 提供直观的图形化用户界面,可以轻松管理数据表和进行增删改查:

  1. 支持 dark 等主题。

  2. 支持转储和恢复数据库。

  3. 编辑器支持 SQL 语法高亮、字段、表名提示,自动命名数据表名。

使用教程

首次使用需要下载驱动,在首选项中配置 Maven 地址:

连接 MySQL 数据库:

填写数据库连接信息及下载驱动:

执行 SQL 前要选择数据库:

工具下载

Windows 安装版:

下载地址

Windows 绿色版:

下载地址

苹果系统 X86 架构版:

下载地址

苹果系统 ARM 架构版:

下载地址

DEB 安装包:

下载地址

RPM 安装包:

下载地址

运行截图

dark 主题效果图:

classic 主题效果图:

erd 主题效果图:

mock 主题效果图:

  •  

杜老师的骑行打卡记录

杜老师连续出差了两周,期间看着出差地的骑士出行,心痒痒的。周末返京后还需要加班一天,给憋坏了。正值周日休息,出门转了一圈。不过周一需要上班,所以没敢拉爆。今日分享杜老师之前的骑行打卡记录!

首钢大桥

新首钢大桥是中国北京市境内的一条连接石景山区和门头沟区的过江通道,横跨永定河道,建设时全球首例双塔斜拉钢构组合体系桥,是中国北京市长安街西延工程的关键节点:

首钢大桥是骑行打卡的圣地,每次骑行路过都会遇到其他骑行的小伙伴「不过杜老师每次都是自己骑,很少组队。自己骑车比较自由,可以控制路线以及速度,组队骑行需要照顾队友节奏」

香山公园

香山公园位于北京市海淀区买卖街道 40 号,北京市区西北郊占地 188 公顷,是一座具有山林特色的皇家园林。景区主峰香炉峰俗称鬼见愁,海拔 575 米。早在元明清时,皇家就在香山营建离宫别院,每逢夏秋时节皇帝都要到此狩猎纳凉:

香山是妙峰山的学前班路线,杜老师一直想去妙峰山毕业,但毕竟是菜腿,怕会路上把肺子喘出来。这里普及一个姿势,骑行数据中常用 VAM 代表爬坡效率,指每小时垂直爬升米数。这是一种简单且纯粹的方法,可以很直接的衡量爬升速度。不管是在哪种路况,蜿蜒亦或是均匀的爬坡,VAM 都能很直接的体现出爬坡水平,数字越大越好:

温榆河线

温榆河古称温榆水。海河流域北运河的上源。位于北京市东北部。发源于北京市昌平区的军都山麓。温榆河的上游由东沙河、北沙河以及南沙河 3 条支流汇合而成。其间又有蔺沟河等小中河的汇入。至北京市通州区通惠河口上游北运河北关分洪枢纽:

从家到温榆河入口大约有 30 公里,杜老师好不容易骑行了过去,本以为有一条环河路线,结果就一小段。而且小路很窄,上面常有行人。沿路树枝茂密,容易划到身上。不过该条线路通 42 公里绿道,听其他骑友说部分路段没有自行车道,所以骑行时需要注意机动车:

骑行专道

回龙观至上地自行车专用路东起昌平区回龙观,西至海淀后厂村路,全长为 6.5 公里,专用路全程共设置了 8 个出入口,出入口平均间距为 780 米。出口设置了 1.8 米宽坡道和 1.4 米宽梯道,并设置了助力系统:

几乎每次没有明确路线,杜老师都会选择骑行该路线。专用道的好处就是上面只有骑友,不需要担心机动车以及外卖小哥,安全性有保障。不过感觉骑行路的刚性有些不足,骑行时明显感觉需求功率比较大,脚蹬子踹飞了速度也没多快:

  •  

neutrino-proxy 内网穿透更多的选择

自从上次 frp 因版本更新导致图床短时间无法访问后,杜老师一直在寻找其它内网穿透工具。机缘巧合遇到一个,看介绍很不错,但杜老师暂未进行性能测试,感兴趣的小伙伴可以试一下!

运行示例

首页可显示 License 统计、端口映射统计、今日流量、流量汇总、流量监控:

系统管理页面中包含用户管理端口池管理、用户管理、端口分组管理、调度管理:

端口池管理页面用于统一管理服务器内网穿透端口,方便统一设置安全组提高安全性:

License 是客户端连接服务端唯一合法凭证。一个 License 同时只可以被一个客户端使用,一个 License 可维护多条端口映射:

服务端 IP 端口对应客户端 IP 端口的四元组映射,是内网穿透的基本单元:

代理示意

当用户通过公网IP加端口访问时,服务端会通过指定端口回源到客户端随机端口,客户端会通过随机端口,反代本地服务端口,实现内网穿透:

服务部署

1.9.0 版本服务端配置格式有所调整。从之前版本升级的,需要注意。在服务器上创建目录/root/neutrino-proxy/config,以下是最新的服务端 app.yml 配置格式:

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
server:
# 服务端web端口,用于支持HTTP接口,管理后台页面访问
port: ${WEB_PORT:8888}

neutrino:
proxy:
logger:
# 日志级别
level: ${LOG_LEVEL:info}
# 隧道相关配置-用于维持服务端与客户端的通信
tunnel:
# 线程池相关配置,用于技术调优,可忽略
boss-thread-count: 2
work-thread-count: 10
# 隧道非SSL端口
port: ${OPEN_PORT:9000}
# 隧道SSL端口
ssl-port: ${SSL_PORT:9002}
# 隧道SSL证书配置
key-store-password: ${STORE_PASS:123456}
key-manager-password: ${MGR_PASS:123456}
jks-path: ${JKS_PATH:classpath:/test.jks}
# 是否开启隧道传输报文日志(日志级别为debug时开启才有效)
transfer-log-enable: ${TUNNEL_LOG:false}
server:
tcp:
# 线程池相关配置,用于技术调优,可忽略
boss-thread-count: 5
work-thread-count: 20
# http代理端口,默认80
http-proxy-port: ${HTTP_PROXY_PORT:80}
# https代理端口,默认443 (需要配置域名、证书)
https-proxy-port: ${HTTPS_PROXY_PORT:443}
# 如果不配置,则不支持域名映射
domain-name: ${DOMAIN_NAME:}
# https证书配置
key-store-password: ${HTTPS_STORE_PASS:}
jks-path: ${HTTPS_JKS_PATH:}
# 是否开启代理服务报文日志(日志级别为debug时开启才有效)
transfer-log-enable: ${SERVER_LOG:false}
udp:
# 线程池相关配置,用于技术调优,可忽略
boss-thread-count: 5
work-thread-count: 20
# 是否开启代理服务报文日志(日志级别为debug时开启才有效)
transfer-log-enable: ${SERVER_LOG:false}
data:
db:
# 数据库类型,目前支持sqlite、mysql、mariadb
type: ${DB_TYPE:sqlite}
# 数据库连接URL
url: ${DB_URL:jdbc:sqlite:data.db}
# 数据库用户名
username: ${DB_USER:}
# 数据库密码
password: ${DB_PASSWORD:}

当前最新版本为 1.9.0,下面的脚本中,可使用 registry.cn-hangzhou.aliyuncs.com/asgc/neutrino-proxy:1.9.0 指定版本安装,推荐使用 latest 直接安装最新版:

1
2
3
4
docker run -it -p 9000-9200:9000-9200/tcp -p 8888:8888 \
-v /root/neutrino-proxy/config:/root/neutrino-proxy/config \
-d --restart=always --name neutrino \
registry.cn-hangzhou.aliyuncs.com/asgc/neutrino-proxy:latest

客户部署

1.9.0 版本客户端配置格式有所调整。从之前版本升级的,需要注意。点击 这里 下载客户端软件包,并且在同级目录创建配置文件 app.yml,以下是最新客户端配置格式:

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
neutrino:
proxy:
logger:
# 日志级别
level: ${LOG_LEVEL:info}
tunnel:
# 线程池相关配置,用于技术调优,可忽略
thread-count: 50
# 隧道SSL证书配置
key-store-password: ${STORE_PASS:123456}
jks-path: ${JKS_PATH:classpath:/test.jks}
# 服务端IP
server-ip: ${SERVER_IP:localhost}
# 服务端端口(对应服务端app.yml中的tunnel.port、tunnel.ssl-port)
server-port: ${SERVER_PORT:9002}
# 是否启用SSL(注意:该配置必须和server-port对应上)
ssl-enable: ${SSL_ENABLE:true}
# 客户端连接唯一凭证
license-key: ${LICENSE_KEY:}
# 客户端唯一身份标识(可忽略,若不设置首次启动会自动生成)
client-id: ${CLIENT_ID:}
# 是否开启隧道传输报文日志(日志级别为debug时开启才有效)
transfer-log-enable: ${CLIENT_LOG:false}
# 重连设置
reconnection:
# 重连间隔(秒)
interval-seconds: 10
# 是否开启无限重连(未开启时,客户端license不合法会自动停止应用,开启了则不会,请谨慎开启)
unlimited: false
client:
udp:
# 线程池相关配置,用于技术调优,可忽略
boss-thread-count: 5
work-thread-count: 20
# udp傀儡端口范围
puppet-port-range: 10000-10500
# 是否开启隧道传输报文日志(日志级别为debug时开启才有效)
transfer-log-enable: ${CLIENT_LOG:false}

首先确保本地已安装 Java8 运行环境,执行下面的命令启动客户端,查看服务端 License 管理,刷新页面,对应 License 在线状态为在线,表明客户端已正常连接:

1
java -jar neutrino-proxy-client.jar config=app.yml
  •  

新版本 frp 参考配置分享

大好的星期六,杜老师本想安安静静睡到下午两点再醒来,结果被去不图床的用户疯狂召唤,一看原来是报障了,简单分析了下是 frp 问题。快进来看看杜老师分享的内容吧!

问题原因分享

去不图床报出了 502 错误,一般是反代或内穿出现问题才会如此报错。杜老师前端反代用的是长亭雷池,通过管理端口访问一切正常,同平台反代的统计平台访问正常,以此可以判断是内穿的问题。

内穿分为服务端以及客户端。通过服务端管理端口访问时页面无法打开;而客户端因为无管理页,只能通过查看日志方式判断其问题的原因,结果并无日志生成。

后尝试查看服务端日志文件,结果发现输出端口为 80,而记忆中并未使用该端口做反代,怀疑是配置文件的问题。重启服务后发现并未加载设置的配置文件,一看官方发现发布 0.52.0 版本后,取消了原有 INI 配置文件,改为 TOML 新格式。

配置文件部分参数值发生了改变,且格式与原来有很大的改变,在此分享一些参考配置,供需要的小伙伴们使用!

frps 端完整配置

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
# A literal address or host name for IPv6 must be enclosed
# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80"
# For single "bind_addr" field, no need square brackets, like "bind_addr = ::".
bindAddr = "0.0.0.0"
bindPort = 7000

# udp port used for kcp protocol, it can be same with 'bind_port'.
# if not set, kcp is disabled in frps.
kcpBindPort = 7000

# udp port used for quic protocol.
# if not set, quic is disabled in frps.
# quicBindPort = 7002

# Specify which address proxy will listen for, default value is same with bind_addr
# proxy_bind_addr = "127.0.0.1"

# quic protocol options
# transport.quic.keepalivePeriod = 10
# transport.quic.maxIdleTimeout = 30
# transport.quic.maxIncomingStreams = 100000

# Heartbeat configure, it's not recommended to modify the default value
# The default value of heartbeat_timeout is 90. Set negative value to disable it.
# transport.heartbeatTimeout = 90

# Pool count in each proxy will keep no more than maxPoolCount.
transport.maxPoolCount = 5

# If tcp stream multiplexing is used, default is true
# transport.tcpMux = true

# Specify keep alive interval for tcp mux.
# only valid if tcpMux is true.
# transport.tcpMuxKeepaliveInterval = 60

# tcpKeepalive specifies the interval between keep-alive probes for an active network connection between frpc and frps.
# If negative, keep-alive probes are disabled.
# transport.tcpKeepalive = 7200

# transport.tls.force specifies whether to only accept TLS-encrypted connections. By default, the value is false.
tls.force = false

# transport.tls.certFile = "server.crt"
# transport.tls.keyFile = "server.key"
# transport.tls.trustedCaFile = "ca.crt"

# If you want to support virtual host, you must set the http port for listening (optional)
# Note: http port and https port can be same with bind_port
vhostHTTPPort = 80
vhostHTTPSPort = 443

# Response header timeout(seconds) for vhost http server, default is 60s
# vhostHTTPTimeout = 60

# tcpmuxHTTPConnectPort specifies the port that the server listens for TCP
# HTTP CONNECT requests. If the value is 0, the server will not multiplex TCP
# requests on one single port. If it's not - it will listen on this value for
# HTTP CONNECT requests. By default, this value is 0.
# tcpmuxHTTPConnectPort = 1337

# If tcpmux_passthrough is true, frps won't do any update on traffic.
# tcpmuxPassthrough = false

# Configure the web server to enable the dashboard for frps.
# dashboard is available only if webServer.port is set.
webServer.addr = "127.0.0.1"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "admin"
# webServer.tls.certFile = "server.crt"
# webServer.tls.keyFile = "server.key"
# dashboard assets directory(only for debug mode)
# webServer.assetsDir = "./static"

# Enable golang pprof handlers in dashboard listener.
# Dashboard port must be set first
webServer.pprofEnable = false

# enablePrometheus will export prometheus metrics on webServer in /metrics api.
enablePrometheus = true

# console or real logFile path like ./frps.log
log.to = "./frps.log"
# trace, debug, info, warn, error
log.level = "info"
log.maxDays = 3
# disable log colors when log.to is console, default is false
log.disablePrintColor = false

# DetailedErrorsToClient defines whether to send the specific error (with debug info) to frpc. By default, this value is true.
detailedErrorsToClient = true

# auth.method specifies what authentication method to use authenticate frpc with frps.
# If "token" is specified - token will be read into login message.
# If "oidc" is specified - OIDC (Open ID Connect) token will be issued using OIDC settings. By default, this value is "token".
auth.method = "token"

# auth.additionalScopes specifies additional scopes to include authentication information.
# Optional values are HeartBeats, NewWorkConns.
# auth.additionalScopes = ["HeartBeats", "NewWorkConns"]

# auth token
auth.token = "12345678"

# oidc issuer specifies the issuer to verify OIDC tokens with.
auth.oidc.issuer = ""
# oidc audience specifies the audience OIDC tokens should contain when validated.
auth.oidc.audience = ""
# oidc skipExpiryCheck specifies whether to skip checking if the OIDC token is expired.
auth.oidc.skipExpiryCheck = false
# oidc skipIssuerCheck specifies whether to skip checking if the OIDC token's issuer claim matches the issuer specified in OidcIssuer.
auth.oidc.skipIssuerCheck = false

# userConnTimeout specifies the maximum time to wait for a work connection.
# userConnTimeout = 10

# Only allow frpc to bind ports you list. By default, there won't be any limit.
allowPorts = [
{ start = 2000, end = 3000 },
{ single = 3001 },
{ single = 3003 },
{ start = 4000, end = 50000 }
]

# Max ports can be used for each client, default value is 0 means no limit
maxPortsPerClient = 0

# If subDomainHost is not empty, you can set subdomain when type is http or https in frpc's configure file
# When subdomain is est, the host used by routing is test.frps.com
subDomainHost = "frps.com"

# custom 404 page for HTTP requests
# custom404Page = "/path/to/404.html"

# specify udp packet size, unit is byte. If not set, the default value is 1500.
# This parameter should be same between client and server.
# It affects the udp and sudp proxy.
udpPacketSize = 1500

# Retention time for NAT hole punching strategy data.
natholeAnalysisDataReserveHours = 168

[[httpPlugins]]
name = "user-manager"
addr = "127.0.0.1:9000"
path = "/handler"
ops = ["Login"]

[[httpPlugins]]
name = "port-manager"
addr = "127.0.0.1:9001"
path = "/handler"
ops = ["NewProxy"]

注意:上面为 frps 完整配置,在使用前请先更先根据需求修改对应设置,保持为 frps.toml 文件以供工具调用。

frpc 端完整配置

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
# your proxy name will be changed to {user}.{proxy}
user = "your_name"

# A literal address or host name for IPv6 must be enclosed
# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80"
# For single serverAddr field, no need square brackets, like serverAddr = "::".
serverAddr = "0.0.0.0"
serverPort = 7000

# STUN server to help penetrate NAT hole.
# natHoleStunServer = "stun.easyvoip.com:3478"

# Decide if exit program when first login failed, otherwise continuous relogin to frps
# default is true
loginFailExit = true

# console or real logFile path like ./frpc.log
log.to = "./frpc.log"
# trace, debug, info, warn, error
log.level = "info"
log.maxDays = 3
# disable log colors when log.to is console, default is false
log.disablePrintColor = false

auth.method = "token"
# auth.additionalScopes specifies additional scopes to include authentication information.
# Optional values are HeartBeats, NewWorkConns.
# auth.additionalScopes = ["HeartBeats", "NewWorkConns"]

# auth token
auth.token = "12345678"

# oidc.clientID specifies the client ID to use to get a token in OIDC authentication.
# auth.oidc.clientID = ""
# oidc.clientSecret specifies the client secret to use to get a token in OIDC authentication.
# auth.oidc.clientSecret = ""
# oidc.audience specifies the audience of the token in OIDC authentication.
# auth.oidc.audience = ""
# oidc_scope specifies the permisssions of the token in OIDC authentication if AuthenticationMethod == "oidc". By default, this value is "".
# auth.oidc.scope = ""
# oidc.tokenEndpointURL specifies the URL which implements OIDC Token Endpoint.
# It will be used to get an OIDC token.
# auth.oidc.tokenEndpointURL = ""

# oidc.additionalEndpointParams specifies additional parameters to be sent to the OIDC Token Endpoint.
# For example, if you want to specify the "audience" parameter, you can set as follow.
# frp will add "audience=<value>" "var1=<value>" to the additional parameters.
# auth.oidc.additionalEndpointParams.audience = "https://dev.auth.com/api/v2/"
# auth.oidc.additionalEndpointParams.var1 = "foobar"

# Set admin address for control frpc's action by http api such as reload
webServer.addr = "127.0.0.1"
webServer.port = 7400
webServer.user = "admin"
webServer.password = "admin"
# Admin assets directory. By default, these assets are bundled with frpc.
# webServer.assetsDir = "./static"

# Enable golang pprof handlers in admin listener.
webServer.pprofEnable = false

# The maximum amount of time a dial to server will wait for a connect to complete. Default value is 10 seconds.
# transport.dialServerTimeout = 10

# dialServerKeepalive specifies the interval between keep-alive probes for an active network connection between frpc and frps.
# If negative, keep-alive probes are disabled.
# transport.dialServerKeepalive = 7200

# connections will be established in advance, default value is zero
transport.poolCount = 5

# If tcp stream multiplexing is used, default is true, it must be same with frps
# transport.tcpMux = true

# Specify keep alive interval for tcp mux.
# only valid if tcpMux is enabled.
# transport.tcpMuxKeepaliveInterval = 60

# Communication protocol used to connect to server
# supports tcp, kcp, quic, websocket and wss now, default is tcp
transport.protocol = "tcp"

# set client binding ip when connect server, default is empty.
# only when protocol = tcp or websocket, the value will be used.
transport.connectServerLocalIP = "0.0.0.0"

# if you want to connect frps by http proxy or socks5 proxy or ntlm proxy, you can set proxyURL here or in global environment variables
# it only works when protocol is tcp
# transport.proxyURL = "http://user:passwd@192.168.1.128:8080"
# transport.proxyURL = "socks5://user:passwd@192.168.1.128:1080"
# transport.proxyURL = "ntlm://user:passwd@192.168.1.128:2080"

# quic protocol options
# transport.quic.keepalivePeriod = 10
# transport.quic.maxIdleTimeout = 30
# transport.quic.maxIncomingStreams = 100000

# If tls.enable is true, frpc will connect frps by tls.
# Since v0.50.0, the default value has been changed to true, and tls is enabled by default.
transport.tls.enable = true

# transport.tls.certFile = "client.crt"
# transport.tls.keyFile = "client.key"
# transport.tls.trustedCaFile = "ca.crt"
# transport.tls.serverName = "example.com"

# If the disableCustomTLSFirstByte is set to false, frpc will establish a connection with frps using the
# first custom byte when tls is enabled.
# Since v0.50.0, the default value has been changed to true, and the first custom byte is disabled by default.
# transport.tls.disableCustomTLSFirstByte = true

# Heartbeat configure, it's not recommended to modify the default value.
# The default value of heartbeat_interval is 10 and heartbeat_timeout is 90. Set negative value
# to disable it.
# transport.heartbeatInterval = 30
# transport.heartbeatTimeout = 90

# Specify a dns server, so frpc will use this instead of default one
# dnsServer = "8.8.8.8"

# Proxy names you want to start.
# Default is empty, means all proxies.
# start = ["ssh", "dns"]

# Specify udp packet size, unit is byte. If not set, the default value is 1500.
# This parameter should be same between client and server.
# It affects the udp and sudp proxy.
udpPacketSize = 1500

# Additional metadatas for client.
metadatas.var1 = "abc"
metadatas.var2 = "123"

# Include other config files for proxies.
# includes = ["./confd/*.ini"]

[[proxies]]
# 'ssh' is the unique proxy name
# If global user is not empty, it will be changed to {user}.{proxy} such as 'your_name.ssh'
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
# Limit bandwidth for this proxy, unit is KB and MB
transport.bandwidthLimit = "1MB"
# Where to limit bandwidth, can be 'client' or 'server', default is 'client'
transport.bandwidthLimitMode = "client"
# If true, traffic of this proxy will be encrypted, default is false
transport.useEncryption = false
# If true, traffic will be compressed
transport.useCompression = false
# Remote port listen by frps
remotePort = 6001
# frps will load balancing connections for proxies in same group
loadBalancer.group = "test_group"
# group should have same group key
loadBalancer.groupKey = "123456"
# Enable health check for the backend service, it supports 'tcp' and 'http' now.
# frpc will connect local service's port to detect it's healthy status
healthCheck.type = "tcp"
# Health check connection timeout
healthCheck.timeoutSeconds = 3
# If continuous failed in 3 times, the proxy will be removed from frps
healthCheck.maxFailed = 3
# every 10 seconds will do a health check
healthCheck.intervalSeconds = 10
# additional meta info for each proxy
metadatas.var1 = "abc"
metadatas.var2 = "123"

[[proxies]]
name = "ssh_random"
type = "tcp"
localIP = "192.168.31.100"
localPort = 22
# If remote_port is 0, frps will assign a random port for you
remotePort = 0

[[proxies]]
name = "dns"
type = "udp"
localIP = "114.114.114.114"
localPort = 53
remotePort = 6002

# Resolve your domain names to [server_addr] so you can use http://web01.yourdomain.com to browse web01 and http://web02.yourdomain.com to browse web02
[[proxies]]
name = "web01"
type = "http"
localIP = "127.0.0.1"
localPort = 80
# http username and password are safety certification for http protocol
# if not set, you can access this custom_domains without certification
httpUser = "admin"
httpPassword = "admin"
# if domain for frps is frps.com, then you can access [web01] proxy by URL http://web01.frps.com
subdomain = "web01"
customDomains = ["web01.yourdomain.com"]
# locations is only available for http type
locations = ["/", "/pic"]
# route requests to this service if http basic auto user is abc
# route_by_http_user = abc
hostHeaderRewrite = "example.com"
# params with prefix "header_" will be used to update http request headers
requestHeaders.set.x-from-where = "frp"
healthCheck.type = "http"
# frpc will send a GET http request '/status' to local http service
# http service is alive when it return 2xx http response code
healthCheck.path = "/status"
healthCheck.intervalSeconds = 10
healthCheck.maxFailed = 3
healthCheck.timeoutSeconds = 3

[[proxies]]
name = "web02"
type = "https"
localIP = "127.0.0.1"
localPort = 8000
subdomain = "web02"
customDomains = ["web02.yourdomain.com"]
# if not empty, frpc will use proxy protocol to transfer connection info to your local service
# v1 or v2 or empty
transport.proxyProtocolVersion = "v2"

[[proxies]]
name = "tcpmuxhttpconnect"
type = "tcpmux"
multiplexer = "httpconnect"
localIP = "127.0.0.1"
localPort = 10701
customDomains = ["tunnel1"]
# routeByHTTPUser = "user1"

[[proxies]]
name = "plugin_unix_domain_socket"
type = "tcp"
remotePort = 6003
# if plugin is defined, local_ip and local_port is useless
# plugin will handle connections got from frps
[proxies.plugin]
type = "unix_domain_socket"
unixPath = "/var/run/docker.sock"

[[proxies]]
name = "plugin_http_proxy"
type = "tcp"
remotePort = 6004
[proxies.plugin]
type = "http_proxy"
httpUser = "abc"
httpPassword = "abc"

[[proxies]]
name = "plugin_socks5"
type = "tcp"
remotePort = 6005
[proxies.plugin]
type = "socks5"
username = "abc"
password = "abc"

[[proxies]]
name = "plugin_static_file"
type = "tcp"
remotePort = 6006
[proxies.plugin]
type = "static_file"
localPath = "/var/www/blog"
stripPrefix = "static"
httpUser = "abc"
httpPassword = "abc"

[[proxies]]
name = "plugin_https2http"
type = "https"
customDomains = ["test.yourdomain.com"]
[proxies.plugin]
type = "https2http"
localAddr = "127.0.0.1:80"
crtPath = "./server.crt"
keyPath = "./server.key"
hostHeaderRewrite = "127.0.0.1"
requestHeaders.set.x-from-where = "frp"

[[proxies]]
name = "plugin_https2https"
type = "https"
customDomains = ["test.yourdomain.com"]
[proxies.plugin]
type = "https2https"
localAddr = "127.0.0.1:443"
crtPath = "./server.crt"
keyPath = "./server.key"
hostHeaderRewrite = "127.0.0.1"
requestHeaders.set.x-from-where = "frp"

[[proxies]]
name = "plugin_http2https"
type = "http"
customDomains = ["test.yourdomain.com"]
[proxies.plugin]
type = "http2https"
localAddr = "127.0.0.1:443"
hostHeaderRewrite = "127.0.0.1"
requestHeaders.set.x-from-where = "frp"

[[proxies]]
name = "secret_tcp"
# If the type is secret tcp, remote_port is useless
# Who want to connect local port should deploy another frpc with stcp proxy and role is visitor
type = "stcp"
# secretKey is used for authentication for visitors
secretKey = "abcdefg"
localIP = "127.0.0.1"
localPort = 22
# If not empty, only visitors from specified users can connect.
# Otherwise, visitors from same user can connect. '*' means allow all users.
allowUsers = ["*"]

[[proxies]]
name = "p2p_tcp"
type = "xtcp"
secretKey = "abcdefg"
localIP = "127.0.0.1"
localPort = 22
# If not empty, only visitors from specified users can connect.
# Otherwise, visitors from same user can connect. '*' means allow all users.
allowUsers = ["user1", "user2"]

# frpc role visitor -> frps -> frpc role server
[[visitors]]
name = "secret_tcp_visitor"
type = "stcp"
# the server name you want to visitor
serverName = "secret_tcp"
secretKey = "abcdefg"
# connect this address to visitor stcp server
bindAddr = "127.0.0.1"
# bindPort can be less than 0, it means don't bind to the port and only receive connections redirected from
# other visitors. (This is not supported for SUDP now)
bindPort = 9000

[[visitors]]
name = "p2p_tcp_visitor"
type = "xtcp"
# if the server user is not set, it defaults to the current user
serverUser = "user1"
serverName = "p2p_tcp"
secretKey = "abcdefg"
bindAddr = "127.0.0.1"
# bindPort can be less than 0, it means don't bind to the port and only receive connections redirected from
# other visitors. (This is not supported for SUDP now)
bindPort = 9001
# when automatic tunnel persistence is required, set it to true
keepTunnelOpen = false
# effective when keep_tunnel_open is set to true, the number of attempts to punch through per hour
maxRetriesAnHour = 8
minRetryInterval = 90
# fallbackTo = "stcp_visitor"
# fallbackTimeoutMs = 500

注意:上面为 frpc 完整配置,在使用前请先更先根据需求修改对应设置,保持为 frpc.toml 文件以供工具调用。

图床同款配置

将下面的文件保持为 frps.toml,Docker 部署参考命令 docker run --restart=always --network host -d -v /etc/frp/frps.toml:/etc/frp/frps.toml --name frps snowdreamtech/frps

1
2
3
4
5
6
7
8
9
10
bindAddr = "0.0.0.0"
bindPort = 7000
auth.method = "token"
auth.token = "12345678"
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "admin"
webServer.tls.certFile = "server.crt"
webServer.tls.keyFile = "server.key"

将下面的文件保持为 frpc.toml,Docker 部署参考命令 docker run --restart=always --network host -d -v /etc/frp/frpc.toml:/etc/frp/frpc.toml --name frpc snowdreamtech/frpc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
serverAddr = "0.0.0.0"
serverPort = 7000
auth.method = "token"
auth.token = "12345678"

[[proxies]]
name = "web01"
type = "tcp"
localIP = "127.0.0.1"
localPort = 80
remotePort = 80
transport.useEncryption = true
transport.useCompression = true

[[proxies]]
name = "web02"
type = "tcp"
localIP = "127.0.0.1"
localPort = 443
remotePort = 443
transport.useEncryption = true
transport.useCompression = true
  •  

为网站添加图片 WebP 自动转换功能

杜老师今天是出差归来,在返京高铁上因为无聊,就看了下近期比较热门的 GitHub 开源项目,正好发现这款工具。可以自动将图片自动转换为 WebP 的格式,同时保持原有的 URL。快点进来了解下吧!

什么是 WebP

WebP 是一种新型图片格式,是由 Google 于 2010 年开发推出。它旨在提供比传统图片格式更高的压缩率,同时保持高质量的图像。

WebP 的优势在于可以在不影响图片质量的情况下显著减小文件大小,从而加快网页加载速度,提高用户体验。

WebP 支持有损和无损压缩,以及动画和透明度。此外,WebP 支持元数据,如 Exif 和 XMP 信息。这使得 WebP 在各种应用场景中都能提供良好性能。

然而,WebP 采用率相对较低,因为它需要较新的浏览器和图像处理库的支持。尽管许多现代浏览器都支持,但一些旧版浏览器和设备可能无法显示 WebP 图像。因此,在部署 WebP 图像时需要考虑到这一点并确保提供适当回退机制。

工具介绍

webp_server_go 是一个基于 Golang 的服务,允许您即时提供 WebP 图像。

webp_server_go 可以将指定目录中的图片自动转换为 WebP 格式,而不更改其 URL。

例如原图为 https://bu.dusays.com/2023/10/12/6527eee969d45.png,新图仍然为 https://bu.dusays.com/2023/10/12/6527eee969d45.png。但后者实际为 WebP 的格式。

webp_server_go 官方介绍支持 JPEG/PNG/BMP/GIF/SVG/HEIC 格式图片文件,实际测试仅 JPEG 格式效果良好。

部署方式

这里推荐使用 Docker 来部署,docker-compose.yml 的参考内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
version: '3'

services:
webp:
image: webpsh/webp-server-go
# image: ghcr.io/webp-sh/webp_server_go
restart: always
environment:
- MALLOC_ARENA_MAX=1
volumes:
- ./path/to/pics:/opt/pics
- ./exhaust:/opt/exhaust
- ./metadata:/opt/metadata
ports:
- 127.0.0.1:3333:3333

将上方代码中 ./path/to/pics 改为图片所在的路径,如/www/wwwroot/bu.dusays.com./exhaust 为转换后 WebP 图片保存路径,./metadata 为元数据的保存路径。配置好后执行如下命令即可:

1
docker-compose up -d

调用方法

如果使用独立域名调用图片,可直接反代 http://127.0.0.1:3333,配置参考下图:

如果像杜老师仅处理 JPEG 格式图像,则可以在站点配置文件中添加如下的配置:

1
2
3
4
5
6
7
8
location ~* \.(jpg|jpeg)$ 
{
proxy_pass http://127.0.0.1:3333;
proxy_set_header X-Real-IP $remote_addr;
proxy_hide_header X-Powered-By;
proxy_set_header HOST $http_host;
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
}
  •  

友情链接的那些事

首先打个欠条,之前答应写一篇 OpenWrt 教程,奈何杜老师突然因工作安排出差,身边没有实验设备,故只要推迟更新了。这篇文章主要聊一下杜老师对友情链接的看法,其中一些策略可能会影响到后期友链运营!

先聊成绩

本博客创建于 2019 年 7 月 10 日,截止该文章发布时,已存在的友链 166 条,其中全站链接 27 条,首页链接 13 条,余下皆为内页链接。

而这 166 条链接,除了继承菜鸟博客那不超过十条友链之外,其余都是被动链接「由他站主动发起的友链申请」

当然其中还有一些友链,是友站建立好后未声明,后期回访时主动发现的,这类站点杜老师会及时上链,保障互动~

友链鼎盛时期,则达到了 207 条,部分站点的友链因无故断链、无法访问等情况而下链。

回顾前文

友链较多,维护起来也很麻烦。

杜老师会定期检查每个友链对应站点可访问性,及本站的友链是否存在,是否更换展示位置等等。

虽说有脚本工具的帮助,但因为博客框架及主题的多样性,很多站点仍需手动检测,这样就占用了杜老师很多时间和精力。

为此杜老师曾编写一篇友链规则文章《关于友情链接的一些事》里面详细描述了杜老师对友链的要求。

遇到问题

杜老师可以很自信的说,没有几个人按照该规则申请链接!

一上来就丢链接的仍然很多,不过比较友善的是都提前做好了杜老师说链接。

不过突然关站、故障博客比比皆是,杜老师每每遇到都会发邮件通知,并提供相关的技术支持,有些博主因上学等一些原因无法及时处理,导致站点长时间的不可访问,搞的杜老师只要做下链处理。

这里很多小伙伴会有所疑问,为什么一遇到不可访问,就立即下链呢?简单为大家介绍下某度引擎索引机制。

杜老师说权重尚可,每天都会吸引数千蜘蛛爬取数据,而遇到无法访问资源时,蜘蛛会降低杜老师说的权重,且对无法访问资源的 URL 做降权甚至是 K 站处理。所以说立即下链是保护站点一种方式。

当然大家找不到自己的链接,也不需要担心,在友链申请页面说明情况就好了,杜老师看到后,也会第一时间恢复上链。

一些想法

不知道有多少的小伙伴做过来源分析,会发现绝大多数的访问流量,都来自于其他博主。大众访客一般都会通过社交平台获取所需要的数据,我们这类博客只有同为博客圈的站长才会乐此不疲。

而互访就是最有效活跃博客的方式了。杜老师添加很多的友链,会定期采集各站的最新文章,尽可能的第一时间送上热评,在活跃气氛的同时,也在其它站点留下本站一丝身影。这也是为什么经常有小伙伴会说:怎么哪里都有杜老师呢?

但是久而久之,杜老师发现很多站点的博主互动性差「从不回访」有些站点久不更新。所以杜老师决定后期会调整友链策略,达到硬性的要求后再考虑做友链。同时屏蔽部分互动性差站点资源采集,这样可以有更多的精力仔细拜读大佬们的文章,以留下更多的热评。

之后建站时间低于一年的请不要主动申请链接,杜老师不清楚您建站是一时兴起,还是长远打算。

一个月及以上未更新的博客也请不要主动申请链接,且已友链的可能会随时下链,杜老师不清楚您是没有时间还是跑路。

第一次来本站的小伙伴也请高抬贵手不要主动申请链接,本站不是您宣传的平台,请不要降低了杜老师互访的热情,谢谢!

  •  

开往项目推荐

很早时杜老师就是开往用户,杜老师认为博主间应该多多互动,毕竟大多访客都是博主之间产生,而开往是非常好的平台,方便大家在多博客之间随机跳转。本文受项目组成员邀请推荐开往项目,并分享官方文化衫穿着体验。

项目介绍

开往是个以跳转功能为主的友链接力项目,其名字开往取自开放的网络。

将开往放入您网页,表示乐于分享并支持开放的网络。

每当有人访问加入开往的网页时,点击开往会随机跳转到另一个加入开往的网页。之后,再次点击网页的开往或后退网页,将继续随机跳转到另一个加入开往的网页。

我们希望这个项目能让友链接力下去,让更多的网页获得流量。站长也可以用开往互相交友。

汗衫秀图

刚收到汗衫后,杜老师便迫不及待的换上了,并未熨烫,所以效果有些折皱。这也说明含棉系数较多,不仅穿着舒适,而且干爽吸汗:

前面胸口处的 Logo 非常契合,即使穿着出门也不会显尴尬。后面 Logo 的设计也很好看。很荣幸能成为首批试穿用户:

个人感受

先聊聊文化衫。

首先杜老师对纯色汗衫,有着迷般喜爱。该款汗衫设计简单,毫无违和,穿着出行不会引来过多瞩目,同时也为项目做出更好宣传。

缺点就是因为纯棉设计,所以容易产生折皱,好在杜老师家用常备熨烫机,操作之后效果还是非常好的。只是拍照时因为心急并未先熨烫。

再说说该项目。

可以说杜老师说的访客前期来自学生,后期来自其它博主。

所以博主间的互动,可以带来流量,及创作的热情。而开往项目就提供一个平台,方便博主之间随机跳转,认识新朋友的同时,也会给自身的博客带来流量,在这里也祝福该项目能越办越好!

项目地址

开往项目官网地址:

  •  

某度网盘批量转存工具分享

前两天樱花童鞋在聊天室中分享一份资源,那可是近千条小姐姐的写真分享链接,不过这么多的资源一条条的转存太麻烦了,刚好看到 obaby 小姐姐分享的小工具,方便之余正好水文一篇!

工具介绍

某度网盘批量转存软件,可用于批量转存网络上分享的某度网盘链接到自己的某度网盘上。运行截图如下:

食用步骤

使用 Chrome 或者类似浏览器「最好用无痕式窗口模式」登录某度网盘主页,完全载入后调出控制台。点击进入到网络选项卡,目前应该空空如也:

刷新页面,下面出现多条记录,单击名为 main 开头的记录,右边出现菜单,在标头页面往下翻,找到请求标头中以 Cookie 开头行,后面有一串以 XF 开头的内容,这就是需要找的 Cookie。全部选中,右键选择复制,粘贴到软件对应输入框内就行了:

注意事项

保存位置如果留空不填,文件会保存到根目录下,就是打开某度网盘主页便能看到。

输入文件的保存位置后,如目录不存在,则会自动新建目录。如目录已存在,则直接转存指定目录下。

保存位置不可以包含大多数英文特殊符号,如输入的特殊符号不被允许,软件会检测并中断运行。

如果保存路径加文件名一起路径长度超过 255 个字符,用某度网盘客户端下载文件时会失败。应尽量用有意义的英文加数字作为保存目录名。

下载地址

下载地址:

下载地址
  •  

slicer-gui 音频分片工具一键包分享

有个小伙伴找到杜老师,说上篇分享的工具中分片功能不好用。这里为需要的小伙伴提供另一款工具,可以很简单的实现音频切片,并对 So-VITS-SVC 工具兼容性很好,欢迎下载体验!

工具介绍

slicer-gui 软件名为 Audio Slicer,为 OpenVPI 团队制作。

工具可以根据音量、间隔等参数对音频进行切片,对 So-VITS-SVC 工具的兼容性很好,非常适合模型训练。

食用步骤

下载好压缩包,解压后打开软件包目录,找到并打开 slicer-gui:

点击 Add Audio File 添加需要切片的音频文件「这里强烈建议使用 WAV 的格式」点击右侧的 Browse 设置输出目录,最后点击 Start 就行了:

注意事项

切片完成后请检查一下每个切片时长,如果超过 15 秒,请调小 Maximum Silence Length 阈值。

然后将时长超过 15 秒的文件重新切片,直到所有音频文件时长低于 15 秒。这样训练效果最好。

下载地址

下载地址:

下载地址
  •  

So-VITS-SVC 一键安装包分享

杜老师找到了一款工具,可以通过自己音色训练模型,然后通过文字转换语音,之前关于 DDoS 文章中的语音就是通过该工具生成。已经整理成一键包,感兴趣的小伙伴可以尝试下。

食用步骤

先解压压缩包,这里需要注意的是,路径中尽量不要出现中文的字符。找到并打开启动webui

会弹出 CMD 窗口,根据脚本自动安装所需要的运行环境,带安装完成后,会自动弹出浏览器打开工具页面「如果没有自动打开,可根据窗口 URL 提示手动打开」

在训练前,先录制一段不低于十分钟的声音「时长越久越好,音质越高越好,背景音越纯净越好」对声音文件做切片:

将切割后的 WAV 文件放入 dataset_raw/OUT 目录中:

切换到训练项,先点击识别数据集,然后点数据预处理:

待预处理完成之后,点击写入配置文件,然后就可以开始训练了:

如果需要使用模型,则切换推理项:

最后切换到文字转语音,输入编辑好的文字,建议勾选中自动f0预测,点击下方的文本转语音即可:

下载地址

下载地址:

下载地址
  •  

DDoS 的攻击鉴赏下章

本不想说那么多的,但讲了两篇攻击鉴赏了,也聊一下如何防御。当然面对这种几乎无解的 DDoS,也没有太好的防御手段,仅分享些杜老师了解的思路,供需要的小伙伴们参考!

语音部分

需要手动点击播放:

文字部分

DDoS 攻击还有一些其它的方式,这里就不再一一列举了。但所谓有攻就有防,哪有压迫哪里就有反抗,所以有哪些应对 DDoS 攻击的方法呢?目前有两种大方向。激进的手术治疗以及稳妥的保守治疗。

捣毁僵尸网络并让用户做好个人防护。避免被感染成为僵尸设备是种很好的方法,但这是需要长期持续进行的方案。

我们举两个典型的在技术层面上根治 DDoS 攻击的方法,从 DDoS 的攻击原理上我们可以看出,伪造 IP 地址是 DDoS 攻击的核心技术之一,一旦攻击者无法伪造 IP 地址,那几乎就形同强弩之末。

而治理伪造 IP 方法并不复杂,现代互联网的下游,也就是用户设备接入的一端,设备通过路由接入互联网服务提供商。

所以只要让路由设备检测 IP,把源地址 IP 不属于本路由所在网段的数据都过滤掉,这样试图伪造 IP 的流量就无法发出了。

还有一个稍微复杂一点的分布式过滤方案。我们知道在庞大的互联网中,不同的网段依靠路由把彼此连接,一个数据从 A 发送到 B,它的 IP 可伪造成 C,但它所经过的真实路线则不可能作假。

换句话说,从 C 到 B 的数据不可能经过某路由器,但这个伪造 IP 数据从 A 发送到 B 却经过了某路由器,如果该路由能够根据 IP 地址的路径逻辑检测出矛盾,那就可以过滤掉这样的流量,从而消灭伪造 IP 的伎俩。

当然一个涉及到用户的服务商设备商,甚至是监管部门的多方技术方案,那就不能只是一个技术问题。

这两种方案很难被执行,只有一定影响力的大型企业和机构才能撬动这种涉及全球的多方合作,对于中小企业甚至是刚起步的创业者来说并不现实。

所以人们提出一些大家都能够承担得起的缓解 DDoS 攻击的保守治疗方案,我们列举两个目前使用比较多的方法。

DDoS 攻击的可怕之处在于 D 分布式,当多个僵尸网络对目标发起攻击时很难处理这些来自四面八方的流量,那作为守法公民我们又何尝不能联合起来,把一个网络服务的流量分散到不同的地方,从而稀释攻击流量。

比如目前各个站点普遍采用的 CDN 技术,把一些相对静态的资源作为缓存分发给各个 CDN 节点,用户在请求的时候从最近的节点返回,这样就在一定程度上缓解了 DDoS 的攻击。

当然 CDN 的缓解作用比较有限。有一种目前比较主流的,并有一些厂商专门为此开发产品方案:流量清洗。

我们在服务器前架设一台流量清洗的设备,这个设备就像一个身高马大的保镖和秘书,帮我们对抗 DDoS 流量。

比如面对 TCP 协议的 SYN 洪水 DDoS 攻击,客户端发起的 SYN 先经过清洗设备,由清洗设备回复 SYN+ACK,如果对方应答了那说明是正常的流量,清洗设备再把本次的连接交给后方服务器正常通信。

如对方不应答,则清洗设备该重试重试,超时后就断开连接。但清洗设备因人高马大,且作为专门应对攻击的角色,对连接资源做了极大的专门优化,能应对极其海量的连接请求,所以攻击者想通过 SYN 洪水打垮它非常困难。

比如威胁极大的 HTTP 洪水攻击,正常来说一个 HTTP 请求很难用传统方式检测出是恶意流量还是正常流量,而清洗设备往往会提供专业流量清洗平台,这些专业做流量清洗的服务商通过多年和 DDoS 攻击的对抗,积累大量的经验和技术。

比如由于 HTTP 无法伪造 IP 地址,所以通过多年数据积累建立 IP 信用库,从那些经常发起攻击的 IP 发来的流量就会被过滤掉。这有点像现在安卓手机上的来电标记,这就是流量清洗厂商在数据积累上的优势。

再比如恶意流量由于是通过程序自动发出,而不是人类的操作,所以利用算法对流量进行模式的识别,就可以被检测出来,这就是流量清洗厂商在技术上的优势。

但不论怎样 DDoS 作为一种历史悠久,但破坏能力巨大的黑客攻击手段,时至今日仍无法被彻底解决。

或许可以说 DDoS 攻击源自于互联网通信构架在设计之初考虑的缺失,而人们现在又缺乏壮士断腕的决心从根本上消灭它。

但不论怎样这种破坏与对抗将长久地存在于互联网世界之中,而我们能做的只是做好防护保持警惕!

  •  

DDoS 的攻击鉴赏中章

因为内容太多,杜老师一时间想不出那么多台词,故打算另起一文继续说。杜老师尽量使用通俗易懂的语言描述,所以文字量会比较多些,希望感兴趣的小伙伴能耐心听完。

语音部分

需要手动点击播放:

文字部分

IP 协议让不同的子网络被互联了起来,从这个通信过程中我们发现从数据离开到最终到达,这一路几乎每个地方都有被 DDoS 攻击的机会。

比如霸占服务器的网络带宽资源,我们只需要向一台服务器发送大量的 IP 协议数据包就可以慢慢的消耗掉对方的网络带宽。

比如用大家耳熟能详的 Ping 工具就可以发起一次攻击,Ping 产生的 ICMP 协议包。ICMP 是 IP 协议用来进行插错控制的一个补充,本质上是一个 IP 包,这种攻击方式也称为 ICMP 洪水。

这种攻击手段类似于我们不断的给某个人投递信件。写了什么并不重要,重要的是让信件多的邮递员在对方的家门口排起长队从而打断正常的信件收发。

同样思路我们还可以发送传输层的 UDP 协议包发起一次 UDP 洪水攻击。当然这里会有一个问题就是会暴露攻击设备的 IP 地址而被对方封禁。

所以攻击者一般会通过伪造 IP 地址来隐藏自己。比如张三给李四写信却把发件地址写成了王五,这样即使是一封祖安问候信李四也只能迁怒于王五。

或者干脆写一个不存在的地址让李四无处泄愤。但出于隐藏自己这个目的人们发明了一种更有趣的攻击方式:反射攻击,既然可以伪造 IP 那就不必拘泥于伪造发件人的身份。

同样可以伪造收件人的身份达到借刀杀人效果,我们把信封上的发件地址改为攻击目标 IP 地址,然后把收件地址设置为互联网上大量的第三方机器,从而把数据发送到这些第三方机器上。

这些机器在接收到数据之后,回复数据会涌入发件地址指向的攻击目标,这些第三方机器也被称为反射器。这有点像把别人电话号码挂在一些网站上,然后机主被不明真相的推销员给呼死,很损但很有效。

反射攻击更难追踪来源,更厉害的是人们在此基础之上又发明了一种把攻击流量放大以达到更强攻击效果的手段:放大攻击。

比如 DNS 服务器用来把域名解析为 IP 地址的设备,我们在浏览器中输入像 dusays.com 这样的域名地址。

实际上需要先查询 DNS 服务器,获得这个域名对应的 IP 地址,再用 IP 地址访问杜老师说服务器,同时 DNS 查询通常用 UDP 这个不用验证来源的传输协议。

综合来看 DNS 服务器就是一个很好的放大器。因为一次 DNS 的查询请求,返回数据往往大于请求数据。这里有个宽带放大因子 BAF 的概念。

在 DNS 的查询中,一般 60 个字节的请求数据可以获得将近 3000 个字节的返回数据,那么 BAF 就等于 3000/60=50 产生 50 倍的放大效果。

这样如果我们让攻击者不断的去对 DNS 服务器发起查询请求并把原地址伪造成为攻击目标的 IP,那么这样的反射攻击就会产生 50 倍的流量放大效果,可谓四两拨二十斤。

除了对目标的宽带资源进行霸占,以达到 DDoS 攻击的效果外,因为 TCP 协议中有连接的概念,所以还可以攻击服务器连接资源。

服务器和客户端每次建立一个 TCP 连接要经历三次握手,然后把连接信息放入到连接表中进行维护。而连接表大小是有限的,我们可以让发起攻击的设备直接发起大量的 TCP 连接,从而占满服务器连接表。

而无法响应后续 TCP 连接请求从而达到 DDoS 攻击的效果,这种直接的方式也称之为 TCP 洪水,但因为有三次握手存在所以 TCP 洪水无法通过伪造 IP 隐藏自己。

在建立连接时如果我们在第一次握手中伪造了 IP,那么服务器向客户端发送数据的第二次握手就无法到达。

相当于给别人写了一封伪造发现地址的信,那么是不可能收到回信,因此连接无法建立。但是可以在建立连接的三次握手本身上做文章,比如只发送 SYN,不进行后续回答这样虚晃一枪 SYN 洪水。

这样做的好处是如果不回答攻击目标的 SYN+ACK 数据,那么考虑到可能是网络环境问题。TCP 协议有重传机制,对方会多次尝试发送 SYN+ACK 直到超时。

问题是这时候受害者会不断的向攻击者发送 SYN+ACK,比如重试 10 次,这就相当于我们每攻击目标一次,对方就会回击 10 次,所谓杀敌一千自损一万不过如此。

所以 SYN 洪水攻击一般都会伪造 IP,或是一个不存在的 IP 让受害者拔剑四顾心茫然,或是某个真实倒霉蛋的 IP 把祸水东移。

同样思路在 TCP 协议中也可以通过反射发起攻击,向各个反射器发送 SYN 并把发现地址伪造成攻击目标的 IP,这样大量 SYN+ACK 数据就会从各个反射器上涌入攻击目标。

当然这种攻击方式因为无法在目标上建立连接,所以还是属于是在攻击网络带宽。而针对 TCP 协议还有一种巧妙攻击手段:洪水攻击。

在 TCP 协议中一般用四次挥手结束连接,但为防止出现异常,一方可以发送一个 RST 数据包强制切断连接。

这样我们让攻击设备不断尝试伪造各种 IP 地址,并发送 RST 数据进行盲打。一旦 IP 和其他的一些配置和某个正常用户匹配上就能切断正常用户和服务器之间的连接。

这种攻击方式更针对于用户。比如在一场网络游戏对战中,在获悉对手的 IP 地址后,就可以不断切断对方的游戏设备和服务器的连接以干扰他的正常游戏。

不论是利用 IP、UDP 还是 TCP 协议攻击,针对的都是网络和连接资源。还有一种直接针对服务器内部资源的攻击方式:消耗目标的 CPU 和 IO。

如开头所说一次网络访问的过程是这样的:客户端通过网络线路向远程的服务器请求内容,服务器按照客户端的需求或查询或计算出相应数据,再通过网络线路送给客户端。

作为在第五层用户,一般在网上冲浪时接触的都是应用层中像 HTTP 这样的协议。比如我们在访问杜老师说的时候,浏览器输入 dusays.com,所以我们可以对一个站点发起 HTTP 洪水攻击。

比如利用博客的搜索功能不断的生成大量的关键词送入查询地址,因为 HTTP 作为用户直接发起涉及具体业务的请求,服务器在收到请求后需进行像数据库查询这样的 IO 操作,所以这样的攻击手法会对目标产生更大的消耗。

当然 HTTP 洪水攻击有一个问题,那就是不能伪造 IP 地址。因为 HTTP 协议实际上是基于 TCP 协议,需经历三次握手的过程,所以常见的方法是借助网络代理主机得到不同的真实 IP 发起攻击。

这对于一次资金充足有计划有组织的攻击来说并不是件难事,DDoS 攻击还有一些其它的方式,这里就不一一列举。

但所谓有攻就有防,哪里有压迫哪里就会有反抗,所以有哪些应对 DDoS 攻击的方法呢?

  •  

用 Enhancer Speech 修复语音

有小伙伴私信问杜老师:家中噪音较多,且没有专业的录音设备,如何录制出高音质的效果呢?今天为有此需求的小伙伴们推荐一款工具,可以将音频处理成专业音质。

工具介绍

Enhancer Speech 是一个强大工具,专门进行语音音频修复。Enhancer Speech 属于 Adobe Podcast 的一部分。Adobe Podcast 是 Adobe 推出的在线播客制作平台,使用人工智能使音频听起来更加专业。Adobe Podcast 提供的编辑功能,主要针对语音,不适用于音乐创作。

Enhancer Speech 利用 AI 技术调整声音,消除检测到的任何背景噪音,将普通的录音提升到接近专业录音室品质。

它的设计简单、方便易用,无需成为音频专家或音乐制作人即可获得出色效果。

这样的设计在播客领域尤其适用,因为许多播客制作者都是业余爱好而不是专业制作。任何可提高音频质量而无需大量花费的工具都是好东西。

食用方法

点击 这里 进入 Adobe Podcast 的官网,点击下面的 Go to Enhance Speech:

该工具需要登录 Adobe 账号才能使用,找到并点击 Sign in,如果没有账号可点击 Sign up「该服务不收费,可以放心注册使用」

登录后点击 Choose files,需要注意格式及大小的限制:

处理的速度还是很快的,我们可以在线试听,并对比处理前后的效果,如果没有问题点 Download 下载:

工具优点

Enhancer Speech 的一大优势是用起来非常简单。要做的是前往网页,上传音频,然后让人工智能完成其工作。这真的是傻瓜到极致了。

通过简单的拖放上传音频文件后,人工智能处理需要一点时间,可以借机休息片刻。完成后把音频文件下载保存就好。无需调整任何内容,学习曲线为零。

与其它在线音频修复增强工具比,处理结果非常厉害。特别是面对由于录制环境录制质量较差的音频,修复结果可能会大大的提升。回声和背景噪音是 Enhancer Speech 最大的用武之地,都会得到有效处理。

其另一大优点就是免费!

工具缺点

因为完全没有控制选项,所以无法更改或调整最终的处理结果。只能接受人工智能做出的决定和处理,仅此而已。虽然效果通常很好,但没有控制选项意味着它的应用场景受到限制。

它对于质量不佳的录音效果最好。如果录音处于良好的环境并拥有高质量的设备,那 Enhancer Speech 用处不大。

Enhancer Speech 支持 wav/mp3/aac/flac/ogg 文件格式。如音频是其它格式,则在上传之前需要做个转换。

其它限制包括上传音频长度不超过半小时。如超过了则需要在处理之前将其分割上传。

文件大小要求不超过 500MB,这对于 mp3 来说一般够了,但 wav 无损格式会比较大。同样可以拆分文件可以解决,虽然有点麻烦。

最后,一个用户在 24 小时内只能处理一小时音频。

  •  

DDoS 的攻击鉴赏上章

就在杜老师在外出差的几天,去不图床又遭受攻击了。在周末返程休息时,从圈内小伙伴的口中得知有小伙伴博客也被攻击了。面对常见网络攻击技术,杜老师打算聊下 DDoS!

语音部分

需要手动点击播放:

文字部分

每个励志成为传奇黑客的年轻人都面临一个 Hello World,而每个所谓安全的网络系统,最终都有一个不安全的隐患,恰巧他们都是同一个东西 DDoS。

作为一个历史悠久网络攻击手段,DDoS 攻击手法暴力且直接,但破坏力惊人,也缺乏彻底的根治方法,人们在它的身上吃尽了苦头。

在现代网络战争中,DDoS 往往作为一场有规模有组织的黑客攻击行动佯攻手段,在 DDoS 洪水的掩护下,伺机而入万军中取上将首级。

那么 DDoS 攻击为何在各种黑客的技术中起起伏伏,攻伐思路的来来去去之间能如此恒久远涌流传下去,至今仍为网络安全的一个心头大患呢?我们不妨来赏析下 DDoS 攻击的技术细节。

1996 年 9 月 6 日美国纽约著名的互联网服务商服务器受到每秒高达 150 次异常连接攻击,导致服务器疲於应对这些非法的流量而拒绝正常用户的合法请求。这是目前大家比较认可的历史上第一次 DDoS 攻击。

DoS 拒绝服务顾名思义即通过占用网络资源让它应接不暇,从而拒绝正常的业务流量的一种网络攻击方式。而我们所说的 DDoS 则是 DoS 攻击的分布式版本,俗称群殴。

单台设备攻击能力有限,治理起来也较容易。但是当几十几百甚至成千上万个设备组成一个网络同时对目标发起 DoS 攻击时无异于一场灾难。故大家一般用 DDoS 指代一般意义的拒绝服务攻击。

而发起攻击的网络一般称为僵尸网络。每一个僵尸可以是一台个人电脑,可以是一台服务器,甚至可以是部智能手机。

而为了得到这样的一个僵尸网络则是八仙过海各显神通。或因为穷,或因为技术过硬的人士利用木马、蠕虫、后门等恶意程序感染大量的设备形成僵尸网络。

而富人则比较轻松,通过某些渠道直接花钱就可以购买到。理论上花的钱越多得到的僵尸网络规模就越大、攻击力就越强。

1999 年 8 月 17 日美国明尼苏达大学的服务器在至少 200 多台设备的 DDoS 攻击下服务被迫中止了两天,而这 200 多台发起攻击的设备都是在不知情的情况下被感染而成为僵尸网络中的一员。

在通过 IP 追踪并让设备停止攻击之后问题还是未能完全解决,因为不断的有新的攻击设备加入进来。

DDoS 攻击和其它利用程序漏洞攻击阴谋不同,这种直接粗暴的方式算是种阳谋,大家知道是怎么发生的但又无可奈何。直到今天 DDoS 问题都没有也无法被完全解决。

为了了解 DDoS 攻击手段的巧妙,我们要先了解一点互联网的工作方式。

一次网络访问过程简化来看是这样的,客户端通过网络线路向远程的服务器请求内容,服务器按照客户端需求或查询或计算出相应的数据,再通过网络线路送给客户端。

这个数据在两端流转的行为和传统的邮递过程是相似的,传统邮递依靠的是邮政系统。而现代互联网中数据的流转依靠的是以 TCP/IP 协议为核心的通信系统。

TCP/IP 参考模型是一个四层结构,我们可借助传统的邮递系统对此做个模拟。

写信的时候大家一般会遵从约定格式,比如先写对方称呼,加个冒号换行再写正文,结尾写上此至敬明,最后写上署名、日期。

类似于四层结构中的应用层规定了一些数据内容的协议规则,如我们上网时常用的 HTTP 协议就属于这一层。

写完信以后我们可以做一个标记,比如使用特定图案蜜蜡封信,或是盖上一个红戳。对方根据这些标记决定如何回复,要不要加急要不要确认一下对方的身份等。

这类似于四层结构中的传输层规定数据的传输方式。比如这层中大家都熟悉的 TCP 协议,为了保证通信的可靠性需要先经历三次握手再发起数据传输。

实际上对于一次可靠的通信过程事先的沟通是很必要的,这在日常生活中很常见。

TCP 协议用三次握手做到了这一点,换句话说在正式写信说正事之前先发送三封确定彼此的信建立一种可靠的连接。

第一次在 TCP 协议的信件上有几个关键的字段,发起 TCP 连接时我方先把 SYN 设为 1,ACK 设为 0,再选择一个顺号 X,然后发送出去。

第二次对方收到之后回复一封信,把 SYN 设置为 1,ACK 设为 1,确认号设为 X+1,同时也选择一个顺号 Y。

第三次我方收到回信后,把 SYN 设置为 0,ACK 设为 1,确认号设为 Y+1,顺号设置为 X+1,再次发送出去。

如此一个 TCP 连接就建立起来,接下来就可以发送用户的数据了。

因为有三次握手的存在,通信要更可靠,类似于即时通信这样的软件多采用 TCP 协议在客户端和服务器之间建立一个连接信道。

而这一层中还有一个著名的 UDP 协议它没有那么麻烦,不需要反复握手建立连接直接把数据投递出去,也不管对方是否收到,所以这是一种不可靠的协议。

而用来装信件的信封类似四层结构中的网络层,主要规定了通信双方地址的编码规则,这一层采用的是 IP 协议,所以大家经常会听到所谓设备 IP 地址。

而一封信的投递最终依靠是邮局,邮局把信件打包装车后,根据收件的地址把信件投递到目的地。

这一层对应四层网络中的子网层是信息传递的物理载体,如以太网卫星网等。

这四层结构从应用层到子网层数据按照不同的协议被不断的打包,到达目的地后刚好是相反的拆包过程而最终被目标接收。

可以看出来其中最为核心的是互联网层中的 IP 协议,只要是按照 IP 协议封装的数据都能被发送。

不论是以太网卫星网还是其它物理实现的子网,正如只要按照信封上的格式写好收发地址装入信件就可以被投递到目的地,不论是走陆运空运还是海运。

IP 协议让不同的子网络被互联了起来,从这个通信过程中我们发现从数据离开到最终到达,这一路几乎每个地方都有被 DDoS 攻击的机会。

  •  

Whisper 语音转文字工具识别准确率非正规测评

今天问了影石官方客服视频转换进度,得知杜老师录制的视频有些问题,官方在导出操作时也遇到了错误,正在积极解决,因此近期无法发布骑行视频。在龙兄建议下,做一篇测评文,测试下之前为大家分享的工具识别准确率!

测试环境

杜老师通过 AI 生成两段文字,通过文字转语音的功能,分别生成时长约一分钟音频文件。

为什么不自己录制?因为担心口音问题降低了识别率。

中文识别

下面是 AI 生成文字,大家可以对照一下:

1
2
3
4
阳光在晴朗的蓝天上闪闪发光,微风吹过树林。鸟儿们唱着甜美的歌,花儿绽放着鲜艳的色彩。这是一个美丽的日子,非常适合在公园野餐。
约翰和玛丽计划了好几个星期的野餐,他们很高兴能一起度过这一天。他们装了一篮子美味的食物,包括三明治、水果和自制甜点。他们还带了一条毯子坐在上面,还有一只飞盘玩。
当他们到达公园时,在一棵大橡树下发现了一个阴凉的地方。他们铺开毯子,准备野餐。他们轮流把飞盘扔来扔去,笑着享受着彼此的陪伴。
当太阳开始落山时,他们收拾好东西,开始走回自己的车。他们度过了美好的一天,他们迫不及待地想一起计划下一次冒险。

语音试听:

识别后的文字:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
陽光在晴朗的藍天上,閃閃發光,微風吹過樹林。
鳥們唱著甜美的歌,花綻放著鮮豔的色彩。
這是一個美麗的日子,非常適合在公園野餐。
約翰和瑪麗計劃了好幾個星期的野餐,
他們很高興,能一起度過這一天。
他們裝了一籃子美味的食物,包括三明治、水果、
和自製甜點。他們還帶了一條毯子,坐在上面,
還有一支飛盤丸。當他們到達公園時,
在一棵大香樹下,發現了一個陰涼的地方。
他們鋪開毯子,準備野餐。他們輪流把飛盤扔來扔去,
笑著享受著彼此的陪伴。當太陽開始落山時,
他們收拾好東西,開始走回自己的車。
他們度過了美好的一天,他們迫不及待地,
想一起計劃下一次冒險。

识别时长:

英文识别

下面是 AI 生成文字,大家可以对照一下:

1
2
3
4
The sun was shining brightly in the clear blue sky, as a gentle breeze blew through the trees. The birds were singing their sweet songs, and the flowers were blooming with vibrant colors. It was a beautiful day, perfect for a picnic in the park.
John and Mary had planned the picnic for weeks, and they were excited to spend the day together. They packed a basket full of delicious food, including sandwiches, fruits, and homemade desserts. They also brought a blanket to sit on, as well as a Frisbee to play with.
As they arrived at the park, they found a shady spot under a large oak tree. They spread out the blanket and set up their picnic. They took turns throwing the Frisbee back and forth, laughing and enjoying each other's company.
As the sun began to set, they packed up their things and started walking back to their car. They had had a wonderful day, and they couldn't wait to plan their next adventure together.

语音试听:

识别后的文字:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
The sun was shining brightly in the clear blue sky, as a gentle breeze blew through
the trees.
The birds were singing their sweet songs, and the flowers were blooming with vibrant
colors.
It was a beautiful day, perfect for a picnic in the park.
John and Mary had planned the picnic for weeks, and they were excited to spend the day together.
They packed a basket full of delicious food, including sandwiches, fruits, and homemade
desserts.
They also brought a blanket to sit on, as well as a Frisbee to play with.
As they arrived at the park, they found a shady spot under a large oak tree.
They spread out the blanket and set up their picnic.
They took turns throwing the Frisbee back and forth, laughing and enjoying each other's
company as the sun began to set.
They packed up their things, and started walking back to their car.
They had had a wonderful day, and they couldn't wait to plan their next adventure together.

识别时长:

轻音乐背景音

杜老师使用 Audition 截取了 A Little Story 一分钟左右的音频,并降低了 10dB 的音量。语音试听:

识别后的文字:

1
2
3
4
5
6
7
8
9
10
11
12
13
陽光在晴朗的藍天上閃閃發光,微風吹過樹林
鳥們唱著甜美的歌,花綻放著鮮豔的色彩
這是一個美麗的日子,非常適合在公園野餐
約翰和瑪麗計劃了好幾個星期的野餐
他們很高興能一起度過這一天
他們裝了一籃子美味的食物
包括三明治、水果和自製甜點
他們還帶了一條毯子,坐在上面,還有一隻飛盤丸
當他們到達公園時,在一棵大象樹下,發現了一個陰涼的地方
他們鋪開毯子,準備野餐
他們輪流把飛盤扔來扔去,笑著享受著彼此的陪伴
當太陽開始落山時,他們收拾好東西,開始走回自己的車
他們度過了美好的一天,他們迫不及待地,想一起計劃下一次冒險

人声背景音乐

杜老师使用 Audition 截取了月无眠一分钟左右的音频,并降低了 10dB 的音量。语音试听:

识别后的文字:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
陽光在晴朗的藍天上閃閃發光,微風吹過樹林
鳥們唱著甜美的歌,花綻放著鮮艷的色彩
這是一個美麗的日子,非常適合在公園野餐
約翰和瑪麗計劃了好幾個星期的野餐
他們很高興能一起度過這一天
他們裝了一籃子美味的食物
像三明治、水果和自製甜點
他們還帶了一條毯子,坐在上面還有一隻飛盤玩
當他們到達公園時,在一棵大香樹下
發現了一個陰涼的地方
他們鋪開毯子,準備野餐
他們輪流把飛盤扔來扔去,笑著享受著彼此的陪伴
當太陽開始落山時,他們收拾好東西,開始走回自己的車
他們度過了美好的一天,他們迫不及待地想一起計劃下一次冒險

测评结果

中文识别转换为繁体字,其次在断句方面较精准。

英文识别非常精准,且断句也非常准确。

Whisper 对背景音处理非常好,不管是在有无人声背景音情况下,识别都很准确。

不过字体准确性还有待提高,识别后需仔细检查是否有错别字!

  •  

Whisper 免费离线语音转文字工具

有小伙伴私信到杜老师,询问语音转文字的方法。其实网上有很多此类的工具,不过大多数的工具都有时长限制,需要开通会员才能转换长时间的语音。本次为大家分享的工具,可以免费离线转换文字。

工具介绍

Whisper 是 GitHub 上一款开源程序,杜老师也是机缘巧合遇到的。

此工具仅支持 64 位架构,分为 GPU 版和 CPU 版本。

本次为小伙伴们分享的是 GPU 版本「需要独立显卡才能运行」如果需要 CPU 版本可在评论区留言。

该工具不仅可以将录制语音转为文字,还支持实时的转换,并可翻译文字。

工具下载

下面是杜老师转存好的网盘地址「无需注册或者下载软件」如想获得原有下载地址,可在评论区中留言:

下载地址

语音模型

在说明使用前,需要先下载好语音模型。Model 为模型名称,Disk 为模型大小,Mem 为预计显存占用:

ModelDiskMem
tiny75MB390MB
base142MB500MB
small466MB1.0GB
medium1.5GB2.6GB
large2.9GB4.7GB

请根据自己显存选择对应的模型文件「模型越大识别的越精准」杜老师已将模型文件转存至网盘,小伙伴可打开链接后点击 ggml 目录,在右侧弹出的文件浏览框双击 ggml,选择模型右键下载即可:

下载地址

食用方法

打开工具后首先需加载模型,图中杜老师选择了最大那个,点击 OK 进入下一步「此步操作后可一劳永逸,再次进入软件会跳过这一步」

Language 选择 Chinese「中文识别」Translate 是转换后翻译成英文「这里不做勾选」Transcribe File 框选择要转换的语音文件,Output Format 选择输出的文本样式「其中 Text file 为普通文本,Text with timestamps 为带时间线,其余两个均为字幕文件」并在下方框中设置输出路径,点击 Transcribe 即开始转换:

转换后弹出完成提示框,关闭即可:

如需实时转换,可点击下方 Audio Capture,在切换的页面中点击 Capture,工具会弹出终端提示框,不断刷新转换后的文字「会有较长延迟」如需保存为文件需要勾选 Save to text file:

  •  

骑行视频仪表盘的制作方法

看到很多小伙伴对杜老师发布的骑行日志中仪表盘很感兴趣,该文分享了仪表盘制作方法,同时介绍了影石全景相机及配套遥控使用方法,此篇仍是语音配文字的形式!

语音部分

需要手动点击播放:

文字部分

上一篇发的音频文,没想到小伙伴们都非常喜欢,还好给杜老师降低了工作量,那这一篇也以音频文的形式发布。

这篇聊点什么?首先,先跟小伙伴们说声抱歉,我家里的情况,没有办法做到完全清音,所以会有些背景的噪音。

尤其是我家的那个逆子,小伙伴们都知道的,前段时间还伤到杜老师。然后我又打的狂犬又打的破伤风,这个事不提了,再多说就是眼泪了。

今天我们聊一下杜老师骑行日志,为什么要聊到这个?因为大家关注到的一点,就是关于杜老师在录制视频之后,上传播放效果,大家可以看到在里面出现一个仪表盘。

很多小伙伴们在评论区,也有在聊天广场中私信杜老师的,问到仪表盘是如何制作。

这个仪表盘它并不是通过视频软件做出来,因为您要知道的是,我们在行驶中那个数据是动态的。没有办法一帧一帧的做出来,这样的话工作量太大了。

这个仪表盘的效果,实际上是影石 APP 自带的。它的工作原理是什么样子的?首先拍摄工具是影石 X3 全景相机。在视频中有提到过,不希望各位小伙伴们看到杜老师这个壮硕身材,以免影响到观影的体验。所以就选择只播放这个车前行驶景色。

它有一个辅助控制工具,类似于遥控器,这个设备除了可以控制相机拍摄,还可以接收 GPS 信号。

在 GPS 返回中的数据就可以实现监测行车的速度,坡度,路径轨迹等等一些信息,这些信息会以数据的形式存储在相机存储卡中。后期在导出视频过程中,就可以加载这些数据生成仪表盘的这些信息了。

有感兴趣的小伙伴,或是也有骑行需求的小伙伴,可以考虑购置这类产品。贴图我会放到文章下方,首先介绍一下影石相机,这是一款全景相机。

很多小伙伴可能在网上会看到 X2,跟 X3 相比的话,X3 的屏幕更大一些,还是全屏触摸。不管是在观看方面,还是在使用方面都很方便。

屏幕的下方有两个按键,一个按键是用来控制开始和停止。还有一个按键用来切换拍摄的摄像头。在机身左侧有两个开口,上方是数据线接口,下方就是电池。在电池卸下来之后,里面有一个存储卡。

杜老师买的这款是原厂的存储卡,128G 的,大约能拍两个小时左右。相机右侧上方是麦克风,下方是电源键,外加一个多功能键。最下方是摄像机的固定接口,大家如果有云台的,可以将相机接入到云台。

最上方是两个凸起鱼眼镜头,这个镜头一定要保护好,杜老师一般会放到相机罩里,以免镜头磨损。

相机功能主要支持防抖,支持 5.7K 的全景拍摄。它的电池,是 1800 毫安,预计的话我没试过太久,因为我一般都是拍摄 40 到 50 分钟就会换块电池,因为那个时候已经出现电池电量警告。

在下方那张图就是它的配件的遥控器,这款遥控器非常的小巧。屏幕上会显示相机状态。首先是 GPS 信号,然后是遥控器电池电量,再者是相机的电量,下方是录制的状态。然后是录制的时间,就没有了。

屏幕下方那个按键是开始和停止拍摄,在相机左侧有两个按钮,上方的按钮是切换拍摄模式,下方是电源键。

这个电源键有两个功能,第一个则是控制这个遥控器开启和关闭的状态。还有一个功能,则是控制相机,在两台设备都开机的情况下,长按三秒则相机会关机,长按六秒遥控器会关机。

后方可以绑定表带或是绷带,可以绑在车把,或者是绑在手腕上。在绑带固定处,是一个可以 90 度旋转的卡扣,可以方便换任意方向去绑定。

遥控器的电池电量这块也没细看,因为说明书在杜老师的手里,一般都是闪现一下就直接丢,根本不看。很多东西,都是自己琢磨,琢磨不透的东西会在网上去百度搜索。

拍摄的话两个小时应该是不成问题的。有的小伙伴可能会说这么点设备,再加上它的这个屏幕并不是彩色显示,显示信息也是非常少的。那怎么说也可坚持几个小时。

各位小伙伴们需要知道的是,这个除了是一台遥控设备外,同时它是一个 GPS 信号接收器。所以它的这个电池很快就会用完,平时如果要出行比较远的话,还是记得将两个设备都充电。

差不多就给各位小伙伴分享这些,之后还会有一些新奇的设备,或是各位小伙伴们感兴趣的东西,最好是零成本可以白嫖,也可跟杜老师分享,杜老师这边做过使用体验后,或者做过对比之后,会整理成教程或是文章的形式跟小伙伴们分享。

那今天的文章,就写到这里啊,感谢各位小伙伴们收看收听,拜拜!

相机照片

家里是暖色吸顶灯,拍出来的照片差强人意,就到网上找了宣传图片,大家凑合看下:

另外杜老师的那款是全黑的,图中的是最近刚出的联名款,除了外观有所变化,功能没有任何差异:

遥控照片

遥控的照片确实之前有拍过,不过是再差点摔车之后拍的,遥控表面严重划伤,这里也配一张官方的宣传图:

摔车是因为路面太颠簸,导致遥控绑带脱落,杜老师为了捡回遥控器而急刹车,导致后轮抱死差点摔车:

  •  

杜老师说方向调整

最近一直在水文章,偶尔还会托更。除了最近比较忙碌之外,更多的是不知道该更新点啥。和小伙伴聊了一下,决定调整一下杜老师的主题方向,也希望大家可以提一些建议!

语音部分

需要手动点击播放:

文字部分

今天,这个博文就以语音的形式去发布。然后,会将这个语音转换成文字的形式,方便喜欢看文字的小伙伴去浏览阅读。懒得看字,您可通过听语音的形式。

杜老师今天为大家分享内容,主要是想说下,杜老师说调整了一下主题的方向。原因比较简单:实在不知道该写点什么好了。

大家应该知道,杜老师说每三天会更新一次。会给大家伙分享一些技术方面的内容,有的时候会根据一些小伙伴的兴趣和建议,分享一些跟杜老师生活相关事情。

但是最近,一直在拖更且水文,很多小伙伴已经开始抱怨了。当然有一部分原因,是因为杜老师还是比较懒的,拖延症吧!

今天这个文章本来想打字说明的,但是懒得打字,打算录音,然后通过一些工具将音频转换成文字的形式跟小伙伴们进行分享。并且在此之前,也没有说先写文稿,然后再去录制,所以说会有很多的废话或者是口头语之类,这个也希望大家理解吧。

我们的话题说回来,说下方向。之前也给各位小伙伴介绍过,杜老师说是个人的技术博客,主要就是为我的学员去分享技术文章,让他们在上课的过程中,不需要把过多的精力放在记录笔记上。这样他们上课可以认真听课,下课可以在我的博客上获得笔记。

后期我已经不做培训讲师的这个工作,转向了公司的另外一个讲师,算是。职责上发生了一些变化。所以说就导致了并不需要将我自己的博客推向我的学员,这个平台就单纯的变成一个技术、资源,还有就是生活类分享的一个平台。

未来打算做一些简单的调整。因为分享一些,比如说运维方向的一些知识,很多小伙伴们可能不是特别的感兴趣。甚至是不需要,很多小伙伴们来了之后都是表示不明觉厉,他们遇到的问题更多是喜欢直接在评论区下面留言,然后获得直接帮助。

这种方式是很高效。所以说感觉没有必要去分享这类资源。当然以后有些更好的技术或者是服务的话,也会给各位小伙伴们进行这种教程上分享,主要还是想着改成这种,比如说一些有趣的工具,或是生活类的。

所以说未来主题的方向,会逐渐面向生活类,面向有趣工具,或者是一些实用性的东西来分享。会发现很多小伙伴,都是跟杜老师一样,是博主是站长,他们希望通过这一类的资源,尽可能的去丰盈自己的博客,然后带来更多流量。

使得自己博客的功能更加的健全,所以未来可能更加注重这个方向。但是有一点就是杜老师作为一个单纯的运维工程师,并不会开发代码也不会前端。

所以大家可以看到,杜老师说是非常的简洁。并没有一些酷炫的效果,只不过在功能方面,相对来说够用。也是要感谢之前有很多小伙伴对杜老师的帮助,在这里呢,就不一指名道谢了。

最后想说一下关于未来主题方向,这个也是杜老师刚刚想到的,跟其他的小伙伴也聊过,然后他们也给杜老师提供了一些建议。

当然这些还是比较片面,也希望能看到此文章一些小伙伴,给杜老师提供更多建议,这个平台的受众是访客。希望能迎合着访客的兴趣口味去经营杜老师说。

后期还是会继续保持着每三天一更的频次,尽可能的不要再出现水文了。实在懒得打字。那我就发语音。

实际上发语音比打字要轻松的多,毕竟杜老师做这方面的工作多年了吧,所以很多话都是在嘴边,不需要过脑直接就可以说出来的。

并不需要太多文稿,可以跟大家聊半天,只不过有些小伙伴应该也听出来,杜老师的口音还是比较重的,尤其是平翘舌不分。

表达的时候就会出现这种特别的情绪所在,导致大家可能听着有些别扭,这个我慢慢去调整,慢慢纠正,但是做这个行业比较久,回想一下,杜老师已经当老师十年之久,所以说不太容易改。

除了资源还有生活分享之外。未来还会推出一些公益性的活动,大家在这块如果有什么需求的话,也可在评论区留言,我看到一些比较合理的需求,也会加入到托管的项目,但是大家请不要太过于期待。

我们还是需要有一定的成本保障,目前的去不图床啊,它本身是一个公益,奈何后期有大量的恶意用户,包括受到过一些攻击造成了巨大的运营成本。

所以没办法最终改成了收费,很多小伙伴也找我细聊。有些小伙伴注意到,我们博客圈里还是有一些就是年纪比较轻,对于他们来说,可能一个月的零花钱也没有多少,但是更多的还是一些成年人,对于他们来说,这都不到一包烟的价格,所以他们还是建议我提升去不图床的价格。

但是思前想后还是没有合理定价标准,所以目前还是保持现状。目前这个阶段,杜老师的工资收入可以很好的支撑住去不图床成本。

后期在不超过一定阈值的情况下,杜老师就算是亏本也会持续运营,不能支撑住的时候,会提前跟各位小伙伴们说的,绝对不会突然跑路,请小伙伴放心。

好了,前前后后叭叭了差不多十分钟了,我们今天聊到这里,后期大家如果对这种语音形式感兴趣的话,也请留言告诉给杜老师。拜拜!

  •  

杜老师的骑行日记「08 月 28 日」

答应小伙伴们的骑行日记它来了。本文除了分享杜老师骑行时沿途风景,也分享杜老师对骑行一些理解和心得。后面也会分享更多相关内容,希望小伙伴们多多提些建议「让杜老师不要水的就别提了,本人也不想啊」

骑行日记

本次骑行总距离 25 公里,主要是想去东城区的一家内蒙零食店买一些牛肉干。因为店家距离杜老师的住处较远,外卖派送费比较贵,所以选择骑行过去采购。

骑行出发的时间为傍晚 17 点。本以为均速 25+ 能很快到达目的地,恰好忘记了此时正是晚高峰,路上行车这个多啊,路这个堵,速度是根本起不来。

通过视频大家可以看出,还是有很多出来骑行的。杜老师认为可能是疫情解放过后,很多人开始了户外活动,而自行车是一个低碳环保的交通工具,所以越来越多的人选择了该交通方式。

但帝都近几年的共享单车越来越少了,在前面的文章中也提过,就是因为上班找不到车,才买的公路车。杜老师想也是因为这个原因,越来越多的人选择购买替代租借。

沿途自行车专用道的骑行体验不太好,一是因为不少的私家车,停放在了自行车道。还有就是路面坑洼严重,像是很久没有修缮,骑的杜老师上牙打下牙,生怕车散架了。

希望会有更多的小伙伴喜欢骑行,但还是要再三叮嘱,一定注意安全!其实杜老师录制了全程骑行视频,只是因为处理软件问题使得视频无法正常导出,待修复后再给大家分享。

骑行视频

视频用影石 Insta360 X3 全景模式拍摄,考虑到杜老师壮硕的身材影响到大家观影,视频仅截取了车头画面,小伙伴们凑合看吧。未来会考虑到大家意见,逐渐完善视频效果:

  •  

四款内网穿透工具对比

前几天去不图床离线了两个小时,本以为又是服务器受到攻击,结果是 frp 出了问题。本来想换成 nps,结果做了一下测试,发现其性能不如 frp,借此杜老师分别对四款内网穿透工具做了测试,对比结果详见正文。

问题说明

查询了服务端运行状态,提示是 too many open files,意思是打开了太多文件,这是 Linux 内核的限制。修复方式就是修改内核配置,但会影响系统的稳定性。查看了官方 Issues,听说可以用 Docker 的版本解决该问题,目前去不图床使用 Docker 版本 frp 实现内网穿透:

TCP 协议的转发

这里给出四款内网穿透工具在 TCP 协议转发性能对比「内网服务器为北京联通,上行 50M 下行 500M。外网服务器为内蒙古云主机,上下行对等 100M」

工具平均延迟吞吐速率
frp27.935ms3.94MB/s
gost14.942ms5.08MB/s
nps40.902ms2.05MB/s
ssh-tunnel19.023ms4.96MB/s

HTTP 协议的转发

这里给出四款内网穿透工具在 HTTP 协议转发性能对比「内网服务器为北京联通,上行 50M 下行 500M。外网服务器为内蒙古云主机,上下行对等 100M」

工具平均延迟吞吐速率成功几率
frp104.92ms13.03MB/s100%
gost55.02ms12.07MB/s100%
nps390.01ms2.951MB/s91.9%
ssh-tunnel61.91ms9.93MB/s98.7%

配置复杂及安全稳定性

配置复杂程度是按配置文件行数确定,行数越多则越复杂「不按单行配置项的数量」安全性则考虑是否支持通信加密,即加密的级别;稳定性则是在 2H4G 的 CentOS7 系统上运行,通过压测运行结果:

工具配置复杂安全性能稳定性能
frp中等中上高等
gost中等中等中上
nps最低最低低等
ssh-tunnel低等中下中等
  •  

加入无畏云联盟每月白嫖 60G 流量

首先感谢无畏云在杜老师周年活动时,提供了大量流量兑换码,为不少需要的小伙伴提供了帮助。本次再度发布福利,加入无畏云联盟可每月白嫖 60G 的流量,点进文章查看详情!

项目介绍

无畏云科技 CDN 是家融合 CDN 解决方案供应商,这意味着它拥有一个强大且多样化的节点网络。无畏云科技 CDN 在全球范围内拥有多达几百个节点 IP 数量,这使得他们的服务能够覆盖更广阔的地区,确保您的网站内容能够快速送到用户手中:

而且,无畏云科技 CDN 的后端主要采用华为云、阿里云等节点,这意味着您可以放心地依靠他们的高品质基础设施和可靠性。他们节点分布广泛,覆盖了世界各地的主要区域,确保您的用户无论身处何地,都能够享受到快速且稳定的访问体验:

联盟福利

首先,无畏云科技 CDN 给予了用户非常慷慨的福利。注册后每个月都会免费赠送 30GB 的流量,这对于小型网站和个人博客来说是个非常棒的优势。令人振奋的是,当您申请加入无畏云联盟并在网站底部添加无畏云的 Logo 和链接后,您将获得每月 60GB 的免费流量,这是一个非常棒的增值服务:

总而言之,如您正在寻找一个可信赖的 CDN 服务提供商,无畏云科技 CDN 绝对是一个明智的选择。它不仅为您提供每月免费的流量赠送,还有丰富节点覆盖和可靠的后端设施。无畏云科技 CDN 将成为您网站加速得力助手,助您打造出色在线用户体验:

邀请链接

无畏云注册即会每月送 30G 的免费流量,通过杜老师的 邀请链接,可在注册后再获得 30G 的免费流量「即首月 60G 免费流量」

按照要求添加页脚图标,即可申请加入联盟,点击进入 联盟申请 填写相关信息即可。需要注意的是,如去除无畏云联盟 Logo 及链接,资源赠送将会暂停:

使用方法

管理平台使用非常简单,在左侧找到站点管理项,进入我的域名,点击添加域名,根据页面提示填写相关信息点击创建即可。需要注意的是,节点位于国内,所以域名需要备案才可使用:

点击左侧套餐管理——我的流量包项,可以查看流量使用情况。大家可以通过服务概览页面的邀请链接获得更多的流量,每邀请一位可获得 10G 的免费流量,无上限哦:

  •  

杜老师的骑行装备

因为公司断网,事情又多,所以鸽了几天,具体不便细说。总的来说月末可以恢复正常更新。别催更别喷水,今天更一篇生活文,聊聊杜老师最近的兴趣:骑行!主要介绍一些杜老师的骑行装备,希望能帮到同样感兴趣的小伙伴。

写在前面

首先请小伙伴听杜老师狡辩,绝对不是因为有了新的兴趣,而怠慢了博客更新,主要是最近的工作任务太多,没有时间维护站点。

别问下班了在干嘛。白天公司没有网络,导致很多工作搁浅,为了不耽误项目的进度,都是回家之后继续处理。不过好在没几天就到月底了,网络问题就能彻底解决。

因为骑行团队邀请,杜老师参与了周末长途骑游,跟大佬们学到不少骑行姿势,后面会更新杜老师骑行日记,今天先分享骑行的装备。

先说好此篇不是恰饭文,也是在咨询大佬前就买好的,所以专业性待考究,各位买的时候还是需要慎重。

骑行头盔

几乎每个骑行团队在邀请时,首先问的不是骑什么车,而是问有没有头盔,如果没有骑行头盔,就算如约出现在起始点,也不会带队一同骑,所以头盔是骑行必需品。头盔的品牌千千万,杜老师仅推荐 MIPS 的头盔,MIPS 并不是牌子,而是一种头盔标准,具体的可自行百度:

骑行手套

这个并非是必需品,但杜老师还是推荐选购。骑行手套除了防晒,最主要是手心处防滑垫,可以让我们更稳定把车。并且在摔倒时,为手部提供一定的保护。选购时一定买合手型的,杜老师第一次就买大了,出现脱手问题:

骑行袖套

提到防晒,骑行袖套也是可选配件。这个主要用在夏天,配合短袖衣服,不然这大太阳,很有可能被晒成巧克力。有些骑友会担心穿袖套会不会热,这个杜老师有体会,当速度上来后,迎风会带走身上的热量,不会出汗:

骑行衣裤

骑行时需要用力的地方,除了上坡外就是对抗风阻了。所以更省力的方式,也是提升速度的方法就是降低风阻了。一套紧身的骑行服,可以最大限度降低风阻,让我们骑行更省力,并且提升骑行速度。不过有一点就是样子太尴尬,这个需要调整心态自行克服:

骑行水壶

之前就有新人问到直接用矿泉水瓶代替不行吗?路边随处可见方便补充。这个杜老师有体会,首先饮料瓶罐无法卡在车身卡扣,当路遇颠簸时,很大可能脱落。其次是补水便利性,骑行水壶可以实现单手补水,不需要停车拧瓶盖:

电打气泵

那个电是特地加的,原因是电打气泵可指定气压,到指定数值后自动停充,不会出现爆胎问题。现在的人都缺少老一辈手艺,捏一下就知道满不,对杜老师来说,数字化是最直观精确的体现。其次要说明公路车的胎压比较高,而且需要经常补齐,几乎每次出行之前,都要检查胎压:

锁踏锁鞋

变速器是为了满足相同踏频可以踩出不同速度。踏频是指一分钟内可以踩多少圈,公路车的标准踏频是 90 转一分钟「其实这是大佬踏频,新手一般在 80 左右」这种速度很有可能脱踏「踩空」有了锁踏锁鞋可以防止这种情况,但不建议新人选购,因为很多人的首摔,都是因为锁踏导致:

骑行前灯

这个是夜骑必需品。夜晚目及距离有限,加上公路车高速性,当路况出现问题时,再反应往往来不及。所以一个大功率的前灯是非常重要的,杜老师的前灯是码表联动款,可以根据码表自动同步日落时间,实现自动开灯。并能同步速度自动切换近远光灯:

骑行眼镜

看头像也知道,杜老师习惯戴眼镜。不过近视镜无法替代骑行镜,速度上来之后,风吹根本睁不开眼。而且迎着大太阳去骑行,强光也会影响视线。有一个好用的骑行眼镜,可以在高速且强光下骑行时,仍然能睁开眼看清路况:

头巾面罩

杜老师首次组队骑行时,发现就自己带着个头巾。开始因为多此一举,后来当拉沙卡车路过时,看到其他小伙伴都在呸呸呸,才发现是明智之举。在夏天夜骑时,强烈建议备上头巾,不知道哪次的张嘴就会吃进去蛋白质:

整车秀照

之前发过整车照片,这里补上一张夜骑时在天桥拍的照片。最后补上一句,夜晚在河边旁骑行,晚风吹过的感觉真的是非常惬意,相信体验过的小伙伴们,都会爱上这种感觉:

  •  

树莓派 4B 超频教程

去不图床目前托管在杜老师家中的树莓派 4B 上,很多小伙伴可能怀疑树莓派性能。本文简单介绍树莓派 4B 性能参数,并说明针对去不图床的相关服务环境调整,最后是如何超频树莓派。

迁移原因

看到前言很多小伙伴会担心树莓派的性能,是否足够维持去不图床运营,是否会影响了运行效率。

杜老师开始也担心性能问题,但没办法的是:家中的小型服务器因为升级到了 Ubuntu Server 23.04 的关系,导致 PHP 的 Imagick 扩展安装后运行报错,这个扩展直接影响到去不图床的正常运营,所以只能临时迁移到树莓派。

性能参数

树莓派 4B 有很多的版本,杜老师买的是最高配版,配置四核的处理器「默认主频为 1.5G」8G 的内存,64G 的 C10 存储卡。

安装 Ubuntu Server For 树莓派系统,千兆口线连路由器。

环境调整

树莓派上主要跑 Nginx/PHP 服务,图片数据通过 FTP 传至小型服务器,MySQL 同样运行在小型服务器上,因为是内网直连的,延迟几乎可以忽略不记。

树莓派通过 USB3 连接高速固态硬盘,相关服务含 Redis 等运行在固态硬盘,保证高速读写。经过压力测试可保证 300+ 并行访问。

超频教程

为了进一步压榨树莓派性能,提供更高效的服务,杜老师对树莓派进行了超频设置,下面针对不同系统的超频配置做一个说明。

如果是树莓派原版系统,需修改配置文件/boot/config.txt;如果是 Ubuntu Server 系统,需修改配置文件/boot/firmware/config.txt。两个系统配置相同,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 平衡模式
over_voltage=6
arm_freq=1800
gpu_freq=600

# 性能模式
over_voltage=6
arm_freq=2000
gpu_freq=700

# 野兽模式
over_voltage=6
arm_freq=2200
gpu_freq=750

性能模式 CPU 温度在 55-65 度,野兽模式 CPU 温度在 70 度,必须加上风扇散热,否则烧板。

杜老师这里选择了野兽模式,并为了运行稳定性,选择了塔式散热器:

  •  

frp 关于 HTTP 和 HTTPS 设置

HTTP 和 HTTPS 是 frp 中针对这两种协议额外提供了一些特殊能力。本质上目前这两种应用层协议底层协议都是 TCP。如果不需要用到相关的特殊功能,可以直接使用 TCP 类型的代理,更加简单方便。

修改 HTTP 请求 Header

通常情况下 frp 不会修改转发任何数据。但有一些后端服务会根据 HTTP 请求 Header 中的 Host 字段来展现不同的网站,例如 Nginx 的虚拟主机服务,启用 Host Header 的修改功能可以动态修改 HTTP 请求中的 Host 字段。需要注意的是,该功能仅限于 HTTP 类型的代理。原来 HTTP 请求中的 Host 字段 test.dusays.com 转发到后端服务时被替换为 dev.dusays.com,frpc.ini 的配置如下:

1
2
3
4
5
[web]
type = http
local_port = 80
custom_domains = test.dusays.com
host_header_rewrite = dev.dusays.com

对于参数配置中所有以 header_开头的参数「支持同时配置多个」都会被添加到 HTTP 请求的 Header 中,根据如下配置,会在请求的 Header 中加上 X-From-Where: frp。frpc.ini 的配置如下:

1
2
3
4
5
6
[web]
type = http
local_port = 80
custom_domains = test.dusays.com
host_header_rewrite = dev.dusays.com
header_X-From-Where = frp

通过设置 Basic Auth 来鉴权

1
2
3
4
5
6
[web]
type = http
local_port = 80
custom_domains = test.dusays.com
http_user = abc
http_pwd = abc

注意:由于所有客户端共用一个 frps 的 HTTP 服务端口,任何知道域名和 URL 的人都能访问到内网的服务,但是在某些场景下需要确保只有限定的用户才可以访问。frp 支持通过 Basic Auth 保护 Web 服务,使用户需要通过用户名和密码才能访问到服务。该功能目前仅限于 HTTP 类型的代理,需要在 frpc 的代理配置中添加用户名和密码设置。通过浏览器访问 http://test.dusays.com,需要输入配置的用户名和密码才可以访问。frpc.ini 的配置如上。

自定义二级域名来访问

通过在 frps 配置文件中配置 subdomain_host,就可以启用该特性。之后在 frpc 的 http 类型的代理中可以不配置 custom_domains,仅需要配置一个 subdomain 参数。只需要将*.dusays.com 解析到 frps 所在服务器。之后用户可通过 subdomain 自行指定自己的 web 服务所需要使用的二级域名。frps.ini 的配置如下:

1
2
[common]
subdomain_host = dusays.com

将泛域名*.dusays.com 解析到 frps 所在服务器的 IP 地址。frps 和 frpc 启动成功后,通过 test.dusays.com 就可访问到内网的 Web 服务。frpc.ini 的配置如下:

1
2
3
4
[web]
type = http
local_port = 80
subdomain = test

路由

1
2
3
4
5
6
7
8
9
10
11
[web01]
type = http
local_port = 80
custom_domains = web.dusays.com
locations = /

[web02]
type = http
local_port = 81
custom_domains = web.dusays.com
locations = /news,/about

注意:frp 支持根据请求的 URL 路径路由转发到不同后端服务。通过配置文件中的 locations 字段指定一个或者多个 Proxy 能够匹配的 URL 前缀。如指定 locations = /news,则所有 URL 以/news 开头的请求都会转发到这个服务。按照上述的示例配置后,web.dusays.com 这个域名下所有以/news 以及/about 作为前缀的 URL 请求都会被转发到 web02,其余的请求被转发到 web01。frpc.ini 的配置如上。

  •  

frp 多场景使用示例

发现很多小伙伴对 frp 感兴趣,但不知道如何使用,杜老师为小伙伴们分享一些示例。这里包括多个常见的使用场景和配置示例,小伙伴们可用来亲自部署和体验这些示例。

通过 SSH 来访问内网机器

这个示例通过简单配置 TCP 类型的代理让用户访问到内网的服务器。在具有公网 IP 机器上部署 frps,并修改 frps.ini 文件「这里使用了最简化配置」设置 frp 服务器用户接收客户端连接的端口:

1
2
[common]
bind_port = 7000

在需被访问的内网机器上部署 frpc,并修改 frpc.ini 文件,假设 frps 所在服务器的公网 IP 为 x.x.x.xlocal_iplocal_port 配置为本地需暴露到公网的服务地址和端口。remote_port 表示在 frp 服务端监听端口,访问此端口的流量将会被转发到本地服务对应端口:

1
2
3
4
5
6
7
8
9
[common]
server_addr = x.x.x.x
server_port = 7000

[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000

多个 SSH 服务复用同一个端口

这个示例通过 tcpmux 类型的代理,实现多个 SSH 服务通过同一个端口暴露。与此类似,只要是能够支持 HTTP 代理连接方式的客户端,都可以通过这种方式来实现对端口的复用。在具有公网 IP 机器上部署 frps,并修改 frps.ini 文件「这里使用最简化的配置」

1
2
3
[common]
bind_port = 7000
tcpmux_httpconnect_port = 5002

在内网机器 A 上部署 frpc,配置文件:

1
2
3
4
5
6
7
8
9
10
[common]
server_addr = x.x.x.x
server_port = 7000

[ssh1]
type = tcpmux
multiplexer = httpconnect
custom_domains = machine-a.example.com
local_ip = 127.0.0.1
local_port = 22

在内网机器 B 上部署另外一个 frpc,配置文件:

1
2
3
4
5
6
7
8
9
10
[common]
server_addr = x.x.x.x
server_port = 7000

[ssh2]
type = tcpmux
multiplexer = httpconnect
custom_domains = machine-b.example.com
local_ip = 127.0.0.1
local_port = 22

通过 SSH 访问内网机器 A,假设用户名 test:

1
ssh -o 'proxycommand socat - PROXY:x.x.x.x:machine-a.example.com:22,proxyport=5002' test@machine-a

通过自定义域名访问内网 Web 服务

这个示例通过简单配置 HTTP 类型的代理让用户访问到内网的 Web 服务。HTTP 类型的代理相比于 TCP 类型,不仅在服务端只需要监听一个额外的端口 vhost_http_port 用于接收 HTTP 请求,还额外提供了基于 HTTP 协议的诸多功能。按照下面的代码修改 frps.ini 文件,设置监听 HTTP 请求的端口为 8080

1
2
3
[common]
bind_port = 7000
vhost_http_port = 8080

按照下面的代码修改 frpc.ini 文件,假设 frps 所在服务器的 IP 为 x.x.x.xlocal_port 为本地机器上 Web 服务监听端口,绑定的自定义域名为 custom_domains

1
2
3
4
5
6
7
8
9
10
11
12
13
[common]
server_addr = x.x.x.x
server_port = 7000

[web]
type = http
local_port = 80
custom_domains = www.yourdomain.com

[web2]
type = http
local_port = 8080
custom_domains = www.yourdomain2.com

转发 DNS 的查询请求

这个示例通过简单配置 UDP 类型代理转发 DNS 查询请求。DNS 查询请求通常使用 UDP 协议,frp 支持对内网 UDP 服务的穿透,配置方式和 TCP 基本一致。frps.ini 的内容如下:

1
2
[common]
bind_port = 7000

frpc.ini 的内容如下:

1
2
3
4
5
6
7
8
9
[common]
server_addr = x.x.x.x
server_port = 7000

[dns]
type = udp
local_ip = 8.8.8.8
local_port = 53
remote_port = 6000

转发 Unix 的域套接字

这个示例通过配置 Unix 域套接字客户端插件来通过 TCP 端口访问内网的 Unix 域套接字服务,如 Docker Daemon。frps.ini 的内容如下:

1
2
[common]
bind_port = 7000

frpc.ini 的内容如下:

1
2
3
4
5
6
7
8
9
[common]
server_addr = x.x.x.x
server_port = 7000

[unix_domain_socket]
type = tcp
remote_port = 6000
plugin = unix_domain_socket
plugin_unix_path = /var/run/docker.sock

对外提供简单文件访问服务

这个示例通过配置 static_file 客户端插件来将本地文件暴露在公网上供其他人访问。通过 static_file 插件可以对外提供一个简单的基于 HTTP 的文件访问服务。frps.ini 的内容如下:

1
2
[common]
bind_port = 7000

frpc.ini 的内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[common]
server_addr = x.x.x.x
server_port = 7000

[test_static_file]
type = tcp
remote_port = 6000
plugin = static_file
# 要对外暴露的文件目录
plugin_local_path = /tmp/file
# 用户访问 URL 会被去除的前缀,保留内容即为要访问的文件路径
plugin_strip_prefix = static
plugin_http_user = abc
plugin_http_passwd = abc

安全暴露内网服务

这个示例将会创建一个只有自己能访问到的 SSH 服务代理。对于某些服务来说如果直接暴露于公网上将会存在安全隐患。使用 stcp 类型的代理可以避免让任何人都能访问到穿透的服务,但是访问者也需要运行另外一个 frpc 客户端。frps.ini 的内容如下:

1
2
[common]
bind_port = 7000

在需要暴露到外网的机器上部署 frpc 且配置如下:

1
2
3
4
5
6
7
8
9
10
[common]
server_addr = x.x.x.x
server_port = 7000

[secret_ssh]
type = stcp
# 只有 sk 一致的用户才能访问到此服务
sk = abcdefg
local_ip = 127.0.0.1
local_port = 22

在想要访问内网服务的机器上也部署 frpc 且配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[common]
server_addr = x.x.x.x
server_port = 7000

[secret_ssh_visitor]
type = stcp
# stcp 访问者
role = visitor
# 要访问的 stcp 代理的名字
server_name = secret_ssh
sk = abcdefg
# 绑定本地的端口用于访问 SSH 服务
bind_addr = 127.0.0.1
bind_port = 6000

通过 SSH 来访问内网机器,假设用户名 test

1
ssh -oPort=6000 test@127.0.0.1

点对点的内网穿透

这个示例将会演示一种不通过服务器中转流量的方式来访问内网服务。frp 提供了一种新的代理类型 xtcp 用于应对在希望传输大量数据且流量不经过服务器的场景。在需要暴露到外网的机器上部署 frpc 且配置如下:

1
2
3
4
5
6
7
8
9
10
[common]
server_addr = x.x.x.x
server_port = 7000

[p2p_ssh]
type = xtcp
# 只有 sk 一致的用户才能访问到此服务
sk = abcdefg
local_ip = 127.0.0.1
local_port = 22

在想要访问内网服务的机器上也部署 frpc 且配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[common]
server_addr = x.x.x.x
server_port = 7000

[p2p_ssh_visitor]
type = xtcp
# xtcp 访问者
role = visitor
# 要访问的 xtcp 代理的名字
server_name = p2p_ssh
sk = abcdefg
# 绑定本地的端口用于访问 SSH 服务
bind_addr = 127.0.0.1
bind_port = 6000
# 当需要自动保持隧道打开时,设置为 true
# keep_tunnel_open = false
  •  

frp 概念及通用功能

很多小伙伴询问 frp 原理,文本简单解释一下。在 frp 中一个代理对应一个需要暴露的内网服务。一个客户端可同时配置多个代理。一些概念,理解它们有助于小伙伴们更好地了解和使用 frp。

原理

frp 是由客户端和服务端组成,服务端通常部署在有公网 IP 的机器上,客户端通常部署在需穿透的内网服务所在的机器上。

内网服务器由于没有公网 IP,不能被非局域网内其他用户访问。

用户通过访问服务端 frps,由 frp 负责根据请求端口或其它信息将请求路由到对应的内网机器,从而实现通信。

通过内网穿透技术,可使内网设备即便没有公网 IP 及端口,也可被公网的用户访问。

类型

frp 支持多种代理类型来适配不同使用场景:

类型描述
tcp单纯的 TCP 端口映射,服务端会根据不同端口路由到不同的内网服务
udp单纯的 UDP 端口映射,服务端会根据不同端口路由到不同的内网服务
http针对 HTTP 应用定制了一些额外功能,如修改 Host Header,增加鉴权
https针对 HTTPS 应用定制了一些额外功能
stcp安全的 TCP 内网代理,需在被访问者和访问者的机器上都部署 frpc,不需在服务端暴露端口
sudp安全的 UDP 内网代理,需在被访问者和访问者的机器上都部署 frpc,不需在服务端暴露端口
xtcp点对点的内网穿透代理,功能同 stcp,但是流量不需要经过服务器中转
tcpmux支持服务端 TCP 端口多路复用,通过同一个端口访问不同的内网服务

TCP

1
2
3
4
5
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000

注意:frp 会为本地服务 22 端口,在 frps 所在服务端监听 6000 端口,将 6000 端口接收到的连接和本地服务 22 端口关联,透传流量,从而实现让用户在外部访问内部服务。

UDP

1
2
3
4
5
[dns]
type = udp
local_ip = 127.0.0.1
local_port = 53
remote_port = 6000

注意:frp 会为本地服务 53 端口,在 frps 所在服务端监听 6000 端口,将 6000 端口接收到的连接和本地服务 53 端口关联,透传流量,从而实现让用户在外部访问内部服务。

XTCP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[stcp-visitor]
role = visitor
type = stcp
server_name = stcp-test
sk = abc
bind_port = -1

[xtcp-visitor]
role = visitor
type = xtcp
server_name = xtcp-test
sk = abc
bind_addr = 127.0.0.1
bind_port = 9002
fallback_to = stcp-visitor
fallback_timeout_ms = 200

注意:当连接 127.0.0.1:9002 时超过 200ms 打洞还未成功的话,会回退到用 stcp-visitor 建立连接。fallback 后,之前触发的打洞操作仍然会继续,一般来说打洞完成需要耗时会比较长。

TCPMUX

frp 支持将单个端口收到的连接路由到不同代理。目前支持复用器只有 httpconnect。当 frps.ini 的 common 中设置 tcpmux_httpconnect_port,frps 将会监听在这个端口,接收 HTTP 的请求。frps 会根据 HTTP 请求中的 Host 路由到不同的后端代理。frps.ini 的配置如下:

1
2
3
[common]
bind_port = 7000
tcpmux_httpconnect_port = 1337

frpc.ini 的配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[common]
server_addr = x.x.x.x
server_port = 7000

[proxy1]
type = tcpmux
multiplexer = httpconnect
custom_domains = test1
local_port = 80

[proxy2]
type = tcpmux
multiplexer = httpconnect
custom_domains = test2
local_port = 8080
  •  

杜老师说旗下服务调整回源策略

经常光顾本站的小伙伴都很清楚,杜老师使用家中服务器对外提供服务。因家用宽带会封禁 80 等端口,借助 CDN 的端口回源功能,可使用户通过域名直接访问杜老师说旗下服务,但经常会遇到回源问题。点击进入本文听杜老师细聊!

回源问题

首先我们使用去不图床举例,说明下之前的网络连接拓扑。

内网的服务器是树莓派,映射端口分别为 80 和 443,通过软路由转换为可用端口,再使用 CDN 端口回源反代加速。

优点是网络节点少,效率较高。缺点是家用带宽会变动地址,需要经常调整 CDN 的回源地址。

之前杜老师通过 DDNS,加 DNSPod 付费服务「TTL 最低值」解决回源地址变动问题。

但是会有一段时间无法访问,原因还是出现在回源地址的解析上面。

新地址获得后,需要等待一段时间,才会同步到 DDNS。而 CDN 本地解析缓存时间较长,导致无法及时获取到新地址,就造成了回源失败。

内网穿透

为了加快地址变更后的回源生效速度,杜老师决定改为使用内网穿透的方式解决这一问题。

内网穿透是种网络技术,它允许局域网内的设备通过互联网与外部网络通信。这种技术通常用于家庭、办公室或其它内部网络环境,其中设备的 IP 地址是私有的,无法直接与公共互联网通信。

内网穿透的基本原理是通过在公共互联网上创建一个代理服务器,该服务器充当内部网络与外部网络之间的中介。当内部网络中的设备需与外部网络通信时,它会将数据发到代理服务器,然后由代理服务器将数据转发到目标设备。同样,当外部设备需与内部设备通信时,代理服务器会将数据发送到内部设备。

内网穿透的主要应用场景包括:远程访问、远程办公、游戏服务器及私有云服务等。

工具选择

在众多内网穿透工具中,杜老师选择 frp。

frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP/UDP/HTTP/HTTPS 等多种协议,且支持 P2P 通信。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。

工具特点

  1. 客户端服务端通信支持 TCP/QUIC/KCP 以及 Websocket 多种协议;

  2. 采用 TCP 连接流复用,在单个连接间承载更多请求,节省连接建立时间,降低请求延迟;

  3. 代理组间负载均衡;

  4. 端口复用,多个服务通过同一个服务端端口暴露;

  5. 支持 P2P 的通信形式,流量不经过服务器中转,充分利用带宽资源;

  6. 多个原生支持的客户端插件,便于独立使用 frp 客户端完成某些工作;

  7. 高度扩展的服务端插件系统,易于结合自身需求进行功能扩展;

  8. 服务端和客户端 UI 页面。

服务部署

从官网页面下载软件包,解压其中的 frps 及 frps.ini 文件,并上传至服务端/opt/目录「可上传至任意目录,但影响到下面服务配置路径」编辑 frps.ini 文件并添加 token 项「等号右侧的值可自定义,与客户端相同」

1
2
3
[common]
bind_port = 7000
token = dusays.com

使用 systemd 控制 frps 的运行状态及配置开机自启,运行命令 vim /etc/systemd/system/frps.service 并添加下面代码,即可通过 systemctl start frps 启动 frp,使用命令 systemctl enable frps 配置 frps 开机自启:

1
2
3
4
5
6
7
8
9
10
11
12
13
[Unit]
# 服务名称,可自定义
Description = frp server
After = network.target syslog.target
Wants = network.target

[Service]
Type = simple
# 启动frps的命令,需修改为您的frps的安装路径
ExecStart = /opt/frps -c /opt/frps.ini

[Install]
WantedBy = multi-user.target

客户部署

从官网页面下载软件包,解压其中的 frpc 及 frpc.ini 文件,并上传至客户端/opt/目录「可上传至任意目录,但影响到下面进程守护管理器的运行路径」编辑 frpc.ini 文件并添加以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[common]
server_addr = 123.123.123.123
server_port = 7000
token = dusays.com

[web]
type = tcp
local_ip = 127.0.0.1
local_port = 80
remote_port = 8780

[web2]
type = tcp
local_ip = 127.0.0.1
local_port = 443
remote_port = 8443

杜老师使用的宝塔面板,安装了进程守护管理器插件,按照如下的配置即可运行客户端:

  •  

杜老师喜提新车啦

公路自行车作为一项越来越受欢迎的运动,吸引着越来越多骑行爱好者。本文将详细介绍坎普公路自行车 ACE 7000 PRO 的骑行体验,以帮助需要的小伙伴了解这款车的性能和特点。

车辆特点

坎普公路自行车 ACE 7000 PRO 采用了轻量化的碳纤维车架,搭配禧玛诺 105 变速套件,提供了舒适的骑行体验。整车重量为 8.2 公斤,使在爬坡和冲刺时更加轻松。此外,该车型还配备碳纤维前叉和轮圈,提高了骑行效率和速度:

骑行感受

在骑行过程中,坎普公路自行车 ACE 7000 PRO 表现出优秀的操控性能。车架的刚性和轻量化设计使得车辆在转弯和加速时更加稳定,同时保证了高速骑行时的稳定性。禧玛诺 105 变速套件提供了准确的换档和响应迅速的刹车系统,使得骑行者能够更加自信地应对各种路况:

舒适程度

坎普公路自行车 ACE 7000 PRO 采用了人体工程学设计的坐垫和握把,使骑行者在长时间骑行过程中能够保持舒适的姿势。此外,该车型还配备高品质的气动轮组,有效降低风阻,使骑行者在高速巡航时更加轻松:

写在最后

当初杜老师买公路车时,就在纠结平把还是弯把。在隔了半年后,最终按耐不住躁动,购买了这款弯把公路车。为了不再烧钱,直接一步到位「全车碳纤维加上 105 大套」不过想买这款的小伙伴需要注意的是,这款的性价比不高,而且没有刹车把只有加速把:

  •  

推一波长亭雷池 WAF

WAF 是 Web Application Firewall 的缩写,也被称为 Web 应用防火墙。区别于传统防火墙,工作在应用层,对基于 HTTP/HTTPS 协议的 Web 系统有着更好防护效果,使其免于受到黑客攻击。

何为雷池

雷池 是长亭科技耗时近 10 年倾情打造的 WAF,核心检测能力是由智能语义分析算法驱动。

在 ZhangZ 童靴的推荐下,杜老师了解到这款产品。家里的服务器因为经常更换地址,所以无法绑定宝塔账号,导致无法使用专业版的 Nginx 防火墙,正好这款工具可以替代实现防御。

雷池特点

更加便捷:

  1. 采用容器部署,一条命令即可完成安装;
  2. 安全配置开箱即用,无需人工维护,可实现安全躺平式管理。

更加安全:

  1. 首创业内领先智能语义分析算法,精准检测、较低误报、更难绕过;
  2. 语义分析算法没有规则,面对未知特征的 0day 攻击不再手足无措。

更高性能:

  1. 没有规则引擎,线性安全检测算法,平均请求检测延迟在 1 毫秒级别;
  2. 并发能力更强,可单核轻松检测 2000+TPS,只要硬件足够强劲,可支撑流量规模无上限。

更高可用:

  1. 流量的处理引擎基于 Nginx 开发,性能与稳定性均可得到保障;
  2. 内置完善健康检查机制,服务可用性高达 99.99%。

部署架构

下图是一个简单的网站流量拓扑,外部用户发出请求,经过网络最终传递到网站服务器。此时,若外部用户中存在恶意用户,那么由恶意用户发出的攻击请求也会经过网络最终传递到网站服务器:

社区版雷池以反向代理方式接入,优先于网站服务器接收流量,对流量中的攻击行为进行检测和清洗,将清洗过后的流量转发给网站服务器。通过以上行为,最终确保外部攻击流量无法触达网站的服务器:

运行效果

登录后在数据统计页面,可以看到今日的请求数、今日的拦截数、访问来源地址、网址访问情况等等信息:

在攻击事件页面中,可以看到攻击来源、持续时间,也能看到攻击状态:

在防护站点页面中,可以添加回源站点,并可设置运行模式「防护、观察、维护」

在通用配置页面中,可以配置各种防护模块:

  •  

水文防喷小福利篇

最近实在想不出该写什么好,想水一篇又怕被喷,所以直接放出福利好了。本次的福利是尊云的国内云主机,使用期限为一个月,一共四台。杜老师会在文章内说明领取规则!

主机配置

三台郑州线路、一台深圳线路,配置皆为 4G 内存 80G 硬盘「分为系统、数据双盘」10M 带宽 2 核 CPU,可选系统有 RockyLinux/Anolis OS/Tencent OS/CentOS/Windows/Ubuntu/Debian「小版本不列举」

领取规则

  1. 请在评论区中留下申请用途;

  2. 待收到回复后,可至导航栏中「点我在线聊天」私聊杜老师获取云主机连接信息;

  3. 解析域名需要备案,若无备案域名,可找杜老师获取免费的二级域名;

  4. 正规平台限制严格,严禁搭建各类违规网站、服务;

  5. 如需长期使用可以申请过户,按照平台要求,最低需支付一块钱;

  6. 最终解释权归杜老师说所有。

  •  

关于 7 月 22 日去不图床故障说明

去不图床与当日出现了访问以及使用故障,差不多十几个小时无法正常使用,为了避免有小伙伴担心杜老师会跑路,并担心数据的安全,在此杜老师发文说明下情况。

故障描述

大致出现两个故障,一个是使用的故障,一个是访问的故障。

使用故障是程序升级导致的。杜老师于事件前一天得知图床所用的程序,推出了新版本。考虑到现有图床的代码做了很多改动,故版本升级时,需要手动合并代码。就导致部分代码合并时出现问题,造成故障。表现为购买套餐是最后无法提交订单。目前已由图床作者「七月」帮忙解决故障。

另外一个访问问题,是攻击导致的。杜老师一觉醒来后「当日 13 点」收到了小伙伴留言,提醒图床无法正常使用。上线后首先排查了服务器的状态,发现并无问题。使用手机时看到了无畏云的流量通知,登录后发现赠送的流量都用光了,经流量分析后判定是被刷流量了。

无畏云目前仅提供加速节点,如需防御节点,可以联系客服人员切换。杜老师得知后第一时间切换至天御云,很快解决了访问的问题。

问题跟进

天御云除加速外还提供防护功能,开启大盾后降低了攻击影响,但同时也影响部分小伙伴的正常使用。

更重要是为了不影响天御云其它用户正常使用,杜老师将反代节点,切换至了闲置服务器上,使用单节点来应对攻击。

图床分为主站以及存储节点,攻击者首先攻击了存储节点,再切换后又转向了主站,所以两者目前都使用反代的形式继续提供服务。

因为本次攻击没有造成损失,故杜老师也不用收集证据贴图分享了。但影响了小伙伴们正常使用图床,在此表示强烈谴责。

后期计划

这应该是一次有针对的攻击,分别针对去不图床主站以及存储节点,而针对存储节点的攻击,是通过从杜老师说中获取的图片链接。

目前杜老师已将两个节点 CDN,都切换到了闲置服务器,通过反代继续提供服务,所以无法提供加速服务,仅可保证图床持续可用。

待稳定运行一段时间后,会切换 CDN「目前计划下个月初切换,因为会赠送免费流量包」

目前已腾出四台闲置服务器,分别用作反代图床主站、存储节点、付费系统、杜老师说博客,极大可能保证节约成本同时,保证服务可用。

写在最后

杜老师的技术有限,以自身的知识了解,这种形式的攻击是有一定成本的。不知是动了谁的蛋糕而报复,还是仅仅为了练习技术,杜老师都想不到会攻击到自己的头上。

因为没有任何损失,所以也不考虑追责。只是耽误了小伙伴使用图床,再次表示强烈谴责。

还请小伙伴们放心,杜老师说及旗下的服务、平台不会跑路,也在极力保证数据安全。

最后感谢小伙伴们的理解和支持,杜老师会提供、推出更多贴心服务,帮助更多的小伙伴体验到优质的网络环境。

  •  

正式提供公益聊天广场托管平台

自上次公布后,不少的小伙伴都加入到杜老师说旗下聊天广场,也有小伙伴问到了搭建方式。不过很多小伙伴因为带宽和服务器配置的问题,表示无法长期运营,故杜老师在此提供免费托管平台。

写在最前

首先杜老师仅提供自有团队支持,并非提供独立实例支持。

简单来说,需使用杜老师提供聊天广场,在平台上自建团队,然后邀请其他小伙伴加入并使用。

其次,团队所有者需保证聊天内容的合规性,不要交流、分享违规内容。

最后声明,如发现任何违规性消息,或是大量占用服务资源,杜老师说有权在不通知情况下解散团队并封禁账号。

平台使用

平台访问地址如下,也可通过杜老师说博客导航「点我在线聊天」进入:

点击上方地址,即可打开聊天广场登录页面,若之前未注册,可以点击红框处的没有账号:

在注册页面中依次填写邮箱、昵称、密码即可。其中邮箱尽量保障准确,未在线时可以收到私信通知:

进入后可选择加入杜老师说团队,如需自建团队,可点击红框处的创建新团队,填写相关信息即可。需要注意的事,通过生成邀请链接注册的用户会默认加入您的团队:

一个用户可以加入多个团队,通过点击红框所在列的团队图标切换;点击黄框处的 Add channels 可创建频道,方便交流不同主题;点击蓝框处可在页面的右侧弹出当前频道成员列表,带有绿色对勾标识当前用户在线;点击黄框处的 Start call 可在线聊天,并且支持屏幕分享:

鼠标划过每天聊天记录都可弹出更多操作,包括针对单条回复等等;如需编辑个人内容,可点击右上角的头像处;更多功能期待大家自行发现,支持各种类型文件上传,限制 50M 内:


其它终端

如不习惯长期开启网页接受消息,也可下载 PC 版客户端在后台挂机,在此放出绿色版本,无需安装,点击下方地址下载解压即可使用「如需其它平台,如 Linux 等可在评论区留言」

下载地址

除 PC 版外,杜老师还提供安卓版本,点击下方链接即可下载安装。苹果手机可至软件商店搜索 Mattermost 下载并安装即可:

下载地址

平台规则

  1. 国内对于即时通信平台都有严格审核机制,杜老师的精力有限,还请各团队的所有人保障聊天及分享内容的健康度;

  2. 杜老师说旗下聊天广场托管平台不保证数据安全性,尤其服务器的资源有限,会定期归档旧数据「包括但不限于团队、频道、文件」

  3. 聊天广场仅供技术交流,平台仅供程序测试,所有用户发言均与杜老师说无关;

  4. 会不定期补充详细规则,解释权归杜老师说所有!

  •  

杜老师步入键圈的第一款客制化键盘

不想水文,奈何实在没有时间更新博客,但有些小伙伴已经掌握杜老师说更新规律,到时间就跑来催更。杜老师本着宁可水不可空的原则,再次水上一文。杜老师的雨衣已经穿好,小伙伴们可以准备开始喷了!

写在前面

书接上文,五周年的礼品已经下单开始定制,预计本周即可发货。因为发货量比较大,无法及时同步派送进度。请小伙伴们耐心的等待,待商家反馈信息后,杜老师也会及时的同步出来。

另外关于博客框架问题,感谢小伙伴们建议。目前通过删除无用插件,已经将部署时间缩短至了七分钟「原 12 分钟」后期可能考虑采用 hexo server 反代的方式,如果效果不好,则考虑改用 Hugo。

客制特点

  1. 键盘布局可以根据个人需求进行定制。常见的键盘布局有 QWERTY/Dvorak/Colemak 等。此外,还可根据个人喜好和使用习惯定制不同的键盘布局;

  2. 键盘结构可以根据个人喜好选择。常见键盘结构有全尺寸、TKL60%/65%等。这些键盘结构之间的主要区别在于按键数量和尺寸;

  3. 机械轴体是客制化键盘核心组件,直接影响键盘的手感和使用寿命。常见的机械轴体有 Cherry/Gateron/Kailh 等。每种轴体具有不同触发压力、触发距离、触感,可以根据个人喜好选择;

  4. 客制化键盘的键帽可以根据个人喜好定制,包括材质、形状和颜色等。常见的键帽材质有 ABS/PBT 等。键帽的形状和颜色则可根据个人喜好进行定制;

  5. 许多客制化键盘支持 RGB 背光效果,可以通过编程实现各种灯光效果。背光效果可以根据个人喜好进行定制,包括颜色、亮度和模式等;

  6. 部分客制化键盘还支持固件编程,可实现按键功能自定义、宏编程等功能。通过软件定制,可以实现更加个性化的键盘使用体验。

键盘外观

有一说一,杜老师是被产品宣传图吸引到了。全透明机身加键帽,并可自由更换键轴:

使用体验

都说杜老师是米粉,连键盘也是小米生态的。这款键盘是米物的 BlackIO 客制化机械键盘,型号是 Z830X,83 个按键「无数字小键盘」

相比游戏,杜老师更多是码字。喜欢码字的小伙伴都知道青轴是王道,但在办公室的环境内使用极容易挨揍。这款键盘使用了非常规键轴「常规键轴例如青轴、红轴、黑轴、茶轴」官方称之为水母轴,话说真的非常形象,按键非常轻柔:

键盘支持三模链接「有线、无线、蓝牙」目前测试有线、无线非常稳定,且延迟低「杜老师不喜欢使用蓝牙,因为容易出现干扰,且延迟高」

但如需更新键盘的固件,或是修改参数配置,则需使用有线模式连接。

键程「按下距离」适中,但触发点较短,加上按压克数较小,极容易出现误触的问题。杜老师尝试通过修改固件来调整触发,但失败了。也未联系上官方的技术支持,如不适应,可能会再选购其它键轴更换。

最后说下,不建议一般需求的小伙伴购买客制化键盘,尤其是杜老师同款。一是键盘手感问题,适应需要一段时间;二是键身适配性差,不易更换键帽「非透明搭配不好看」三是客制键盘需要一定编程基础,否则发挥不出键盘特性。

  •  

来自杜老师的求助信息

眼看着博客的周年庆就快过去了,杜老师一直心想着大改框架,但是苦于找不到一款好程序,在此发布求助信息,希望小伙伴们可以帮忙推荐一些程序,满足杜老师的框架需求。

目前现状

目前 Hexo 的插件加 Volantis 附加功能可以满足杜老师说呈现需求,现期正在静候 Volantis 新版本更新,短期内不会有较大变动。不过有个比较大的问题,就是页面生成时间太长,平均每次部署都需要十分钟:

手中资源

目前杜老师具有 WordPress 两款付费主题,分别是知更鸟和大前端「知更鸟见下图」

具有 Typecho 一款付费主题,是 handsome「handsome 见下图」

具有 Halo 一款付费主题,是 PandaPro「PandaPro 见下图」

还有一些其它资源,在这里就不一一说明了「大前端见下图」

选型问题

WordPress 是杜老师之前用过的框架,其臃肿性被杜老师鄙夷,所以打算不再使用这款框架。

Typecho 是目前观望一款框架,程序轻量、主题完善、插件健全,如果实在没得选可能用该款。

Halo 是杜老师十分看好的一款框架,但其无法自定义 URL,加上数据的保存形式暂不做选择。

除以上几款外,其它程序暂未发现心仪主题,但考虑 Hexo 部署时间太长,不得已也要取舍了!

框架需求

  1. 首先支持高定制 URL,即可以设置每篇文章的访问地址,为的是使现有文章访问地址不变「必选」

  2. 高度兼容 Markdown 的语法,可以更加方便导入 Hexo 的文章,当然不支持没关系,大不了逐一复制也可以;

  3. 如支持数据库,希望可选数据库支持 MySQL,可以直接修改数据,不要那种 blob 类型的;

  4. 如是静态框架,希望可以技术成熟,满足上述要求同时还能快速部署。如是动态框架,希望可以是轻量级。以上均不考虑付费问题!

  •  

Linux 服务器安全加固参考

杜老师出差回来了,刚好得空拜访了小伙伴们的网站,发现近期有些小伙伴的网站被攻击了。其实除了常见的 DDoS,还有一些技术流的攻击形式,主要是通过系统和服务漏洞进行攻击。今天杜老师分享 Linux 服务器安全加固项,供需要的小伙伴们参考。

高危

高危加固项如下表:

项目编号风险描述配置建议
1CVE-2021-4034 polkit pkexec 本地提权漏洞检测更新polkit 组件
2CVE-2023-0386 Linux Kernel OverlayFS 权限提升漏洞漏洞检测根据提示检查内核版本是否低于指定版本【uname -r】
若是CentOS 8 Stream,则执行【yum install kernel】命令升级内核版本,并重启服务器
若是Ubuntu 22.04,则执行【apt install linux-image】查看可安装版本号,选择高于5.15.0-70的版本号,再次执行【apt install linux-image-版本号】,并重启服务器
3检测MySQL root用户是否具备数据库备份权限临时以无授权方式进入数据库,建议恢复root用户所有权限。
4Docker API 未授权访问应开启认证来鉴权或关闭Dokcer Api
5Mysql 弱口令检测如果检测出为弱口令请及时修改密码
6检测MySQL root用户是否具备数据库备份权限临时以无授权方式进入数据库,建议恢复root用户所有权限。
7PHP未禁用危险函数在【php.ini】文件中设置【disable_functions】未配置system,exec,passthru,shell_exec,popen,proc_open等危险函数
提示:【php.ini】未配置system,exec,passthru,shell_exec,popen,proc_open等危险函数
8PHP存在版本泄露在【php.ini】文件中设置【expose_php】将配置为Off
提示:【expose_php】将配置为Off
9检测当前Redis密码是否安全1.Redis 密码太过于简单
2.请及时修改密码
10检测当前Redis是否安全若非必要,请勿将Redis的bind配置为0.0.0.0
若bind为0.0.0.0的情况下,请务必为Redis设置访问密码
请勿使用过于简单的密码作为Redis访问密码
推荐使用高安全强度的密码:分别包含数字、大小写、特殊字符混合,且长度不少于7位。
Redis一但出现安全问题,这将大概率导致服务器被入侵,请务必认真处理
11禁止SSH空密码登录在【/etc/ssh/sshd_config】文件中设置【PermitEmptyPasswords】将配置为no
提示:【PermitEmptyPasswords】将配置为no
12检测进程中是否有通过strace命令获取其他用户账号信息ps aux命令查看是否存在通过strace读取sshd登录凭证
ps aux
13系统后门用户检测在命令行中删除后门用户
注意:如果存在后门用户说明你服务器已经被入侵
14tomcat后台访问弱口令检测在【/usr/local/bttomcat/tomcat/conf/tomcat-users.xml】中修改password弱口令

中危

中危加固项如下表:

项目编号风险描述配置建议
1/etc/bashrc用户缺省权限检查【/etc/bashrc】 文件中所所设置的umask为002,不符合要求,建议设置为027
操作如下:修改 umask 为027
2是否启用Docker日志审计检查在【/etc/audit/rules.d/audit.rules】文件中添加-w /usr/bin/docker -k docker
重启auditd进程systemctl restart auditd
3检查审核日志满了后是否自动删除在【/etc/audit/auditd.conf】中max_log_file_action将ROTATE改为KEEP_LOGS
重启auditd服务systemctl restart auditd
4bootloader配置权限检查对【/boot/grub2/grub.cfg】文件,配置对应权限
chmod 600 /boot/grub2/grub.cfg、chown root /boot/grub2/grub.cfg
5检查重要文件是否存在suid和sgid权限使用chmod u-s/g-s 【文件名】命令修改文件的权限
6检查临时目录是否设置粘滞位权限使用chmod +t 【文件名】命令修改文件的权限
7/etc/csh.cshrc用户缺省权限检查【/etc/csh.cshrc】 文件中所所设置的umask为002,不符合要求,建议设置为027
操作如下:修改 umask 为027
8Apache 版本泄露检查在【httpd.conf】文件中添加ServerSignature Off以及ServerTokens Prod
9开启地址空间布局随机化【/proc/sys/kernel/randomize_va_space】 值为2:
操作如下:sysctl -w kernel.randomize_va_space=2
10检测是否限制密码重复使用次数配置文件备份cp -p /etc/pam.d/system-auth /etc/pam.d/system-auth.bak
在【/etc/pam.d/system-auth】文件【password sufficient】后面添加或修改remember=5
11检查是否存在危险远程访问文件hosts.equiv、.rhosts、.netrc删除在家目录下的.rhosts和.netrc文件以及删除根目录下的hosts.equiv文件
按照提示找到风险文件并删除
12检测所有已部署安全证书的网站是否过期请为您的站点续签或更换新的SSL证书,以免影响网站正常访问
SSL证书过期后,用户访问网站将被浏览器提示为不安全,且大部分浏览器会阻止访问,严重影响线上业务
13SSH 空闲超时时间检测在【/etc/ssh/sshd_config】文件中设置【ClientAliveInterval】设置为600到900之间
提示:SSH空闲超时时间建议为:600-900
14SSH 最大连接数检测在【/etc/ssh/sshd_config】文件中设置【MaxAuthTries】为3-5
提示:SSH最大连接数为:3-6,请设置为3-5
15SSH密码复杂度检查【/etc/security/pwquality.conf】 把minclass(至少包含小写字母、大写字母、数字、特殊字符等4类字符中等3类或4类)设置为3或4。如:
minclass=3
16检查SSH密码失效时间【/etc/login.defs】 使用非密码登陆方式密钥对。请忽略此项, 在/etc/login.defs 中将PASS_MAX_DAYS 参数设置为90-180之间
PASS_MAX_DAYS 90 需同时执行命令设置root密码到期时间 命令如下: chage --maxdays 90 root
17检查SSH密码修改最小间隔【/etc/login.defs】 PASS_MIN_DAYS 应设置为大于等于7
PASS_MIN_DAYS 7 需同时执行命令设置root 密码失效时间 命令如下: chage --mindays 7 root
18SSH过期提前警告天数在【/etc/login.defs】 PASS_WARN_AGE 大于等于7
提示:PASS_WARN_AGE 30 同时执行命令使root用户设置生效 chage --warndays 7 root
19SSH密码长度度检查【/etc/security/pwquality.conf】 文件中把minlen(密码最小长度)设置为9-32位
minlen=9
20检测是否使用安全的套接字层加密传输信息,避免被侦听敏感信息在【/etc/ssh/sshd_config】文件中添加或修改Protocol 2
随后执行命令systemctl restart sshd重启进程
21关闭非加密远程管理telnet检查尽可能使用加密远程管理sshd服务,关闭不安全的telnet服务
systemctl stop telnet.socket停止telnet服务
22检查是否设置无操作超时退出在文件【/etc/profile】中添加tmout=300,等保要求不大于600秒
执行命令source /etc/profile使配置生效

低危

低危加固项如下表:

项目编号风险描述配置建议
1检查ls和rm命令是否设置别名在文件【~/.bashrc】中添加或修改alias ls='ls -alh’以及alias rm=‘rm -i’
执行【source ~/.bashrc】使配置生效
2检测CVE-2019-5736容器逃逸漏洞docker version查看docker版本是否小于18.09.2,runc版本小于1.0-rc6
3CVE-2022-2068 OpenSSL任意命令执行漏洞检测升级OpenSSL至最新版本或是安全版本
1.0.2zf、1.1.1p、3.0.4及以上版本
4CVE-2022-25845 Fastjson 任意代码执行漏洞检测打开网站目录下的pom.xml文件,查看是否有fastjson依赖库
若fastjson版本小于1.2.83,则需升级到1.2.83或更高的安全版本
5检查关键文件的底层属性是否配置给系统日志文件【/var/log/messages】添加只可追加属性chattr +a
给关键文件【/etc/passwd /etc/shadow /etc/group /etc/gshadow】添加锁属性chattr +i
6检测是否限制账户认证失败的次数在【/etc/pam.d/sshd】文件第二行添加或修改
auth required pam_tally2.so onerr=fail deny=5 unlock_time=300 even_deny_root root_unlock_time=300
7检测系统用户列表中是否存在风险用户如果这些用户不是服务器管理员添加的,则可能系统已被入侵,应尽快处理
8检测所有网站是否部署安全证书请考虑为您的网站部署SSL证书,以提升网站的安全性
9限制SSH登录后使用图形化界面检查在【/etc/ssh/sshd_config】中修改X11Forwarding为no
10设置ssh登录白名单在【/etc/hosts.deny】添加ALL:ALL
在【/etc/hosts.allow】添加sshd:【来访者IP地址】
11检查SSH root是否可以登录【/etc/ssh/sshd_config】 添加PermitRootLogin no参数
PermitRootLogin no
12检查是否使用PAM认证模块禁止wheel组之外的用户su为root在文件【/etc/pam.d/su】中添加auth sufficient pam_rootok.so以及auth required pam_wheel.so group=wheel
如需配置用户可以切换为root,则将用户加入wheel组,使用命令gpasswd -a username wheel
13检查是否开启TCP-SYNcookie保护缓解syn flood攻击在【/etc/sysctl.conf】文件中添加net.ipv4.tcp_syncookies=1
然后执行命令sysctl -p生效配置
14/etc/profile用户缺省权限检查【/etc/profile】 文件中所设置的umask为002,不符合要求,建议设置为027
操作如下:修改 umask 为027

注意

  1. 杜老师并未对以上服务进行分类,需要的小伙伴可以按需查找;

  2. 以上加固项按杜老师服务器配置分享,部分服务如未安装则不需要加固;

  3. 有参考范围的,则按需要配置,如不知该如何配置,可以取中;

  4. 如果需要更多的安全加固项,可在评论区中留言。

  •  

杜老师说五周年及无畏云 CDN 推荐

不知不觉,杜老师说已经建站五周年了,快点进来看看杜老师的感想,顺便了解下无畏云。这次杜老师是带了满满的诚意和福利来的,别再说文水了。再次强调结尾有福利哦~

五周年了

月初收到来自十年之约项目组的邮件,祝贺杜老师说已经建站了五周年。没想到时间过的这么快,转眼间五年过去了。有些小伙伴可能关注过杜老师建站史,本站 2018 年 7 月 10 日创建,于次年同日正式上线的:

五年运营期间,经历风风雨雨。最大的问题就是为了减少维护的成本,不断在各种平台上试错,最终还是选择了服务器。还有一个问题就是站点页面生成时间太长,之前考虑过更换博客的框架,最终因为 URL 问题而放弃:

运营感想

杜老师一直坚持互动是维持博客活力最佳方式,会经常拜访博客圈的小伙伴,对于每条评论都会回复以及回访,建站至今,留言量 28152「含杜老师回复」浏览量 1352859「自提供不蒜子服务后才开始统计」

感谢小伙伴们的支持和信任,杜老师说旗下图片托管平台「去不图床」至今已有 11500+ 用户量,图片托管量 207800+。虽说和大站完全没得比,但在杜老师的心中,这是大家对一个小博客站长的信任和支持:

无畏云 CDN

答应一位小朋友帮忙推广无畏云。了解杜老师的小伙伴应该都知道,杜老师推荐的不一定是精品,但一定是自己用过,而且使用体验比较好的。无畏云属于融合 CDN,后端主要使用华为云的节点,不仅高速而且稳定:

为了测试速度和稳定性,杜老师已经将去不图床外链加速节点,切换到了无畏云上,大家可以在评论区上传图片,体验加速后的外链效果。另外杜老师已经替换了家中的路由器,换成了性能更好的软路由器,同时稳定性也得到更好保障:

福利放送

重点来了,为了感谢小伙伴的支持,杜老师说斥资千元定制了 100 套小礼品,可以看下方效果图。欢迎点击 这里 留下您的信息,杜老师会尽快将礼品发过去「仅有 100 件,先到先得,提交截止 7 月 16 日」

接下来是第二个福利哦,无畏云的 邀请链接,使用邀请链接注册的小伙伴每月赠送 30G 的流量,且首月多赠送 30 的流量。还不够用?可以点击 这里 进入聊天广场,私信杜老师可获取「杜老师说五周年专属兑换码」私信方法可见下图,首先点击左侧成员列表,然后点击右侧发送私信即可「兑换码于 7 月 14 日截止」

  •  

去不图床的故障分析及解决方案

本月月初开始,去不图床一直出现故障,经过长时间的监控分析,最终判断是回源的问题,导致问题的原因是路由器经常性自动重启,每次重启都会导致公网 IP 的重置,进而导致 CDN 无法正常的回源。本文就此问题进行详细说明!

网络架构说明

为了控制图床运营成本,杜老师将程序源码及图片存储都托管在了家中服务器上,然后通过家庭带宽映射给 CDN。架构如图所示:

故障问题描述

为了保障 CDN 可正常回源,首先需要具备公网的 IP 地址,其次要保证 IP 发生变动时会实时反馈给 CDN。

去不图床使用的天御云暂不支持 API 推送更新 IP,所以只能借助网内群晖的 DDNS 实现,而 IP 变动后 DDNS 解析需要一段生效时间,这就是回源失败的原因。

经过一段时间观察发现,导致 IP 经常变动的原因是路由器经常自动重启,重启后拨号就会发生 IP 变动。之前最多每周变动一次「且还是深夜时」现在每天变动多次「且还是用网高峰期」

随着杜老师提供的服务不断增多,且用户量级逐渐的增大,家用机路由器已经无法满足端口映射需求。长时间的高频作业加上夏日高温,会造成路由器自动重启。

预期解决方案

就 IP 变动问题,目前有下面的几种方案。

使用固定 IP 的方案。经查询北京联通支持申请固定 IP,经费每月 100 元。但杜老师使用的是出租房提供的宽带,业务需要房东亲自办理才可,所以该方案暂时不可行。

IP 变动后及时生效方案。天御云在 IP 变动后,会有一段回源失败时间,是因为 DDNS 解析生效还未同步。但使用腾讯云「DDNS 解析托管在 DNSPod 上」CDN 的生效很快,所以采用 CDN 嵌套的方式,缺点是首次回源时时间较长「目前使用该种方式」

更换新路由器方案。通过采购软路由器,在硬件层面直接提升网络端口的映射能力,避免因路由自动重启造成 IP 变动「不变动是不可能的,但可以尽可能减少变动频次」

方案实施进度

目前采用的是 CDN 嵌套的方式,前端是天御云,中端是腾讯云,该种方式尽可能保障出现问题时,十分钟内即可自动恢复「如遇浏览报错,可尝试刷新浏览器」

已采购软路由,并让店家安装好了爱快系统「杜老师偏向 OpenWrt,但考虑需折腾半天才可以用,最终还是选择可尽快上线使用的爱快」

软路由采用 N6000 的处理器,4G 内存 128G 存储,端口是 2.5G,根据官方测试数据,可待机 128 台设备进行端口映射及转发「杜老师家中需映射设备仅有五台」

快递显示 7 月 9 日运到北京,杜老师尽量在下周一前「7 月 10 日」完成路由设备切换,为大家伙带来更稳定的服务!

  •  

入手 4070Ti 显卡体验文

几乎是在《帮杜老师选一张显卡吧》一文发布当天,杜老师就入手了 4070Ti 显卡,至今已经用了十天,多少要水一篇文章出来。水文见谅,杜老师最近太忙了,之前因为拖延症压着的工作太多,年中要交付的项目太多,最近几乎都是后半夜睡!

使用体验

杜老师更换显卡的主要原因是 AMD 显卡不支持 CUDA,综合性价比最终选择 4070Ti「很多小伙伴都推荐杜老师选购 4080,一个显存而是位宽,但少量的性能增加,却需要支付近 3000 的差价,着实有些肉疼」换上显卡后的第一个感觉就是完蛋了,因为事先没有卸载 AMD 的驱动,且未安装 NVIDIA 驱动,导致显示器一直收不到,HDMI 和 DP 都试了。最终使用远程桌面工具「因为杜老师有移动办公需求,所以常年开着远程桌面」卸载了 AMD 驱动,并安装 NVIDIA 驱动,显示器一瞬间点亮。因为杜老师一直忙,也没有测试光追的效果,不过没有出现 A 卡掉驱动的问题,稳定性非常好。最后直接搬运长图~

搬运长图

  •  

Mattermost 开源社区部署及聊天广场推广

之前就有小伙伴问到杜老师有没有交流群。平时杜老师很少会使用到 QQ,微信也很少看,但为了能及时收到小伙伴反馈的信息,所以搭建交流社区「可惜没多少人」最近发现有个开源聊天社区,决定尝试一下!

服务介绍

Mattermost 是一个 Slack 开源替代品。Mattermost 采用 Go 语言开发,是一个开源的团队通讯服务。为团队带来跨平台消息、文件分享,提供归档以及搜索功能。运行界面如下:

部署过程

下面说下如何在 Linux 系统,通过 Docker 来部署,需要提前准备好 Git 运行环境。执行下面代码可实现一键部署 Docker 运行环境:

1
curl -fsSL https://get.docker.com | bash -s docker

使用 Git 下载 Mattermost 官方 Docker 部署代码库,并进入代码库:

1
2
git clone https://github.com/mattermost/docker
cd docker

复制环境变量模板文件,并修改其中的内容。将 DOMAIN 后的值改为自己的域名:

1
cp env.example .env

在上面的 docker 目录创建数据库映射目录,并修改目录所有者:

1
2
mkdir -p ./volumes/app/mattermost/{config,data,logs,plugins,client/plugins,bleve-indexes}
sudo chown -R 2000:2000 ./volumes/app/mattermost

使用命令 mkdir -p ./volumes/web/cert 创建证书的保存目录,并自行申请 SSL 证书将其重命名放入以下路径中,注意上方是 CERT 证书、下方是 KEY 证书:

1
2
./volumes/web/cert/cert.pem
./volumes/web/cert/key-no-password.pem

使用命令 sudo docker-compose -f docker-compose.yml -f docker-compose.nginx.yml up -d 完成服务的自动部署,即可通过之前绑定的域名访问了。如需停止服务,可以使用以下命令:

1
sudo docker-compose -f docker-compose.yml -f docker-compose.nginx.yml down

服务推广

杜老师在一台临时服务器上搭建了该服务,方便小伙伴们体验,地址如下:

注意事项

国内对于即时通信平台都有严格审核机制,自行搭建平台可能触发运营商的监管,部署前请慎重考虑。

另外建议可使用境外云平台部署,部署时不要使用主域名,防止境内网络挟持。

需要的小伙伴也可直接使用杜老师的聊天广场托管,无意外会长期运行,

最后进行免责声明,以上内容仅供技术交流,聊天广场平台仅供程序测试,所有用户发言均与杜老师说无关!

  •  

麒麟高级服务器操作系统安装非官方视频教程

今天录制了段视频,讲解如何在虚拟机中安装麒麟高级服务器操作系统,其中的虚拟化环境需要自行准备。本教程使用 VMware Workstation 17 Pro,如需获取同款虚拟机的安装文件或序列号,可在评论区中留言。

教程视频

教程补充

系统安装镜像文件可以前往麒麟官网自行下载「网址还请自行搜索」或在评论区中留言获取杜老师存于网盘的同款版本镜像。另外视频结尾提到的 VMTools 增强工具,还请前往《麒麟服务器操作系统安装 VMTools》一文查看。

  •  

帮杜老师选一张显卡吧

杜老师的台式电脑,用了一年半了,显卡的性能明显不够用「主要是 AMD 显卡,不支持 CUDA」所以一直惦记要换一个,目前有两张心仪的显卡,还在纠结中拿不定主意,了解的小伙伴帮忙推荐一下!

现有显卡

杜老师现有的显卡,是非公版的 6800XT,性能上没做过专业测试,但有明显感觉,是阉割版本的。

这个也能理解,很多品牌整机,为了运行的稳定性,及降低返修率,都会选择很保守的调校。

本来是想打开配套驱动,给小伙伴们截图看看性能参数的,奈何最近一段时间面板都打不开,所以也只能脑部了。

最后说下不满意的地方,一是不支持 CUDA,而是自带的灯效关不掉「没错,就是这个借口」

选择清单

目前中意的显卡有两款,都是英伟达的。其中一款是 4070Ti。下面是这张显卡的特性:

另外还有张专业显卡 A4500,下面是这款显卡的特性:

意向偏好

有的小伙伴可能会问道,为什么不选 4080 或更高的版本,主要不是经费问题。

CPU 和显卡是相辅相成的,显卡配置很高,但 CPU 跟不上是无法发挥显卡真实性能。

而且高端的显卡还需要升级电源功率,杜老师的意向是最小的替换成本完成升级。

杜老师玩游戏较少,主要是想学习一下目前主流的 AI 技术,但前文有提到过 6800XT 不支持 CUDA。

专业显卡 A4500 擅长 AI 处理,但娱乐性较差。而 4070Ti 是一张综合性显卡,所以就很纠结要选哪个!

写在最后

希望了解的小伙伴推荐一下,选哪款比较好。

另外附加一个问题,就是杜老师也在公版和非公版间纠结。

公版是英伟达的亲儿子,不管是用料还是兼容性都非常好,但缺点是价格较高,且定制性较弱。

非公版则是各大厂家定制的,有些会在原厂基础上通过换料来减少成本降低价格,有些则会通过加料提升性能「如加显存」并提供厂家定制的控制模块「如灯效调节等」

  •  

容器除了 Docker 还有 Podman

了解杜老师的小伙伴都知道,杜老师非常喜欢用 Docker 来部署相关服务。但可能有些小伙伴不太清楚,容器除了 Docker 还有 Podman,今天杜老师为大家简单介绍下 Podman。

什么是 Podman

Podman 是一个开源的容器运行时项目,可在大多数 Linux 平台使用。Podman 提供与 Docker 非常相似的功能。它不需要在系统上运行任何守护进程,并且它也可以在没有 root 权限的情况下运行。

Podman 可管理和运行任何符合 OCI 规范的容器和容器镜像。Podman 提供了一个与 Docker 兼容的命令行前端来管理 Docker 镜像。

主要区别

  1. Docker 在实现 OCI 的时候,需要一个守护进程,其次需要以 root 运行,因此也带来了安全隐患;

  2. Podman 不需要守护程序,不需要 root 用户运行,从逻辑架构上,比 Docker 更加合理;

  3. 在 Docker 的运行体系中,需要多个 daemon 才能调用到 OCI 的实现;

  4. 在容器管理链路中,Docker Engine 实现就是 dockerd;

  5. dockerd 调用 containerd,containerd 调用 containerd-shim。顾名思义 shim 起的作用也就是避免父进程退出影响容器的运行;

  6. Podman 直接调用 OCI,通过 common 作为容器进程的管理工具,但不需要 dockerd 这种以 root 身份运行的守护进程;

  7. Podman 体系中,有个称为 common 的守护进程,运行路径通常是 /usr/libexec/Podman/conmon,它是各个容器进程的父进程,每个容器各有一个,common 的父进程通常是 1 号进程。Podman 中的 common 其实相当于 Docker 体系的 containerd-shim;
    图片

  8. Podman 不需要守护进程,而 Docker 需要守护进程。

使用区别

  1. Podman 的定位也是与 Docker 兼容,因此在使用上面尽量靠近 Docker。使用方面,可以分成两个方面来说,一是系统构建者的角度,二是使用者的角度;

  2. 在系统构建者方面,Podman 的默认软件,与 Docker 区别不大,只在进程模型、进程关系方面有所区别。如果习惯 Docker 几个关联进程的调试方法,在 Podman 中则需要适应。总体来看,Podman 比 Docker 要简单。由于 Podman 比 Docker 少了一层 daemon,因此重启的机制也就不同了;

  3. 在使用者方面,Podman 与 Docker 的命令基本兼容,都包括容器运行时、本地镜像、镜像仓库几个方面。因此 Podman 命令行工具与 Docker 类似,比如构建镜像、启停容器;

  4. Docker/Podman 可进行替换。因此,即便使用了 Podman,仍然可使用 Docker 作为镜像仓库,这也是兼容性最关键的部分。

常用命令

容器相关命令如下:

命令作用
podman run创建启动容器
podman start启动容器
podman ps查看容器
podman stop终止容器
podman restart重启容器
podman exec进入容器
podman export导出容器
podman import导入容器快照
podman rm删除容器
podman logs查看日志

镜像相关命令如下:

命令作用
podman search检索镜像
podman pull获取镜像
podman images列出镜像
podman rmi删除镜像
podman save导出镜像
podman load导入镜像
  •  

1Panel 新一代 Linux 服务器运维管理面板

很多小伙伴都在用某塔控制面板,但随着商业化推进,越来越多的插件和服务,都开始收费了。近期杜老师发现了一款新一代的 Linux 服务器运维管理面板,主要是通过 Docker 来部署环境和服务,感兴趣的小伙伴可以试一下!

面板优点

  1. 快速建站:深度集成 WordPress 和 Halo 等,域名绑定、SSL 证书配置等一键搞定;

  2. 高效管理:通过 Web 端轻松管理 Linux 服务器,包括应用管理、主机监控、文件管理、容器管理、数据库管理等;

  3. 安全可靠:提供防火墙和安全审计功能;

  4. 一键备份:支持一键备份、恢复,备份数据云端存储,永不丢失。

环境要求

  1. 操作系统:支持主流 Linux 发行版;

  2. 支持架构:X86/ARM 等;

  3. 内存要求:建议可用内存在 1GB 以上;

  4. 访问要求:请使用 Chrome/Firefox/Edge 等现代浏览器。

面板安装

CentOS/RHEL 一键安装的命令如下:

1
curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && sh quick_start.sh

Ubuntu 一键安装的命令如下:

1
curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && sudo bash quick_start.sh

Debian 一键安装的命令如下:

1
curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && bash quick_start.sh

面板截图

面板安装速度很快,使用安装后提供的登录地址及相关信息进入到面板:

首页既是概览信息,包含网站、计划任务、数据库等数量,同时也显示了服务器的运行状态:

应用商店可以安装、升级、备份、恢复应用。在已安装列表,可对应用进行同步、升级、重启、启动、停止、删除、备份、恢复操作:

网站管理,主要用于管理和创建 Web 站点,快速创建各种架构网站。管理证书相关,包括申请证书、续约证书、ACME/DNS 账户管理等:

在数据库页面,支持 MySQL/Redis 数据库:

1Panel 的服务环境是通过 Docker 部署,可以通过该项管理所有服务,及查看其状态:

该页面主要用于管理需要定时执行的任务,如定期执行 Shell 脚本、定期备份、定期访问 URL 等,同时支持手动执行:

文件管理实现了很多实用的文件操作,除了基本剪切、复制、粘贴、删除操作,还支持上传和下载文件、压缩和解压缩、加密以及解密、批量操作。进入监控报表,直观了解服务器的运行状态,包含平均负载、性能监控、内存使用监控、磁盘监控、网络监控。进入终端页面,终端默认连接本地主机:

该页主要记录当前面板操作的日志及状态,如在面板上站点的添加,数据库的添加,支持资源、状态过滤:

支持面板一些基础设置,针对一些系统要求等级比较高的用户,支持设置是否开启服务器监控和监控日志保留天数,快照用于全量备份 1Panel 所产生数据:

  •  

猛玛无线领夹 LARK M1 麦克风体验文

杜老师上课时的习惯是走来走去「不然讲着讲着就会睡着,别不相信,这是真的」每次手持着麦克风杜老师都想着高歌一曲,为了方便,杜老师斥巨资买了款领夹麦克风。今天同小伙伴们分享下使用体验!

产品介绍

一键主动降噪。需要在接收端操作,点击侧边的降噪键后会激活主动降噪:

高质无损音质。录音音质非常不错,和杜老师的专业电容麦克风音质差不太多「可能是因为杜老师没有监听耳机,听不出来具体区别」

佩戴便携轻巧。小视频中的网红们大多用的都是罗德的麦克风,杜老师在专业的录播间体验过的,不过体积大比较重,这款配重更轻,佩戴几乎无感:

远距稳定传声。官方宣传 200 米,杜老师试过 50 米无压力,传声稳定且音质无改变:

全指向收音麦。无需确定指向,麦克风可全向收音,且效果很不错:

赠毛绒防风罩。安装方便,但使用效果杜老师没测试过,毕竟是放在领结上,不用担心口喷:

设备自动适应。拿出充电盒后自动配对,连接输出设备即可使用,无需特别配置:

支持多款设备。附赠多种类型线缆,可以连接手机、电脑及标准 3.5mm 设备:

使用体验

激活主动降噪后会降低音量,需要提高嗓门,还好杜老师有多年内力,不过运功久了还是挺费嗓子。

杜老师试过开启 Windows 音频输入侦听模式,然后通过扬声器播放采集的声音,再通过麦克风收音,看是否能收录场景音频,效果还是很令人满意的,且不会产生麦克风效应。

麦克风虽然轻,但建议夹在衬衫上,如果夹在圆领 T 恤上会变形。

连接电脑时尽量使用 3.5mm 接口,使用数据线连接时出现音量变小问题,联系了官方也未能得到有效解决方案。

另外在连接电脑时,如电脑只有单 3.5mm 接口时,需要设置单麦克风输入,不然会被识别为扬声器,影响音频正常输出。

最后建议有需要的小伙伴们不要在 618 期间购买,杜老师做了价格的对比,比平时的价格贵了很多!

  •  

一入骑行深似海从此钱包是路人

今天实在不知道写点什么好,干脆聊一下杜老师最近很关注的骑行好了。此篇没有什么营养,并且语言混乱,望小伙伴们别介意!同时希望小伙伴们也能分享一些骑行经历,帝都的小伙伴可以组队骑行~

初入骑行

不知小伙伴们第一次骑自行车是什么时候,想想杜老师应该是在小学一年级,那会也就七八岁吧!

骑的当然是儿童车,就是后面还带两个保护轮的那种。

现在摩托经常玩的压弯,在儿童车面前就是奢望,别说压弯,弯大一点都拐不过。

记得去掉保护论后,杜老师死活不敢再骑了,知道父亲说会在后扶着,才颤颤巍巍上车骑了会。

杜老师要感谢父亲大人善意欺骗,在父亲大人的悬空帮扶大法之下,杜老师学会了骑自行车。

那会经常骑着小车,同儿时的小伙伴们玩耍,想想童年也是极好~

第一辆车

杜老师出生在穷苦家庭,也就是在就读的初高中旁边都有房子而已,趴在地上爬回家也就五分钟。那会特别羡慕下课就打车回家的同学,杜老师这种不够起步价的都怕司机会拒载。

还好皇天不负有心人啊,在杜老师高三那会,用备战高考为理由,家人又砸锅卖铁买了个独栋,离学校远了不止是一星半点,这次至少爬上二十分钟以上,于是乎就偷偷攒钱打算买辆变速的山地车。

面黄肌瘦的杜老师辛辛苦苦攒了一周的零花钱,终于全款买了辆山地车,那会也不知道是啥牌子,反正花了 600 多大洋。

小伙伴们的车后座带过女同学吗?杜老师经验很丰富,并且前后换了好几个女同学,并非杜老师很花心,只是她们摔过之后不肯再坐~

本来此车可陪杜老师参加高考的,奈何一天晚课结束,它将杜老师送到了网吧门口,一夜通宵之后,车就丢了。

杜老师当时十分的心痛,还有好多女同学没坐过杜老师的车后座呢!

第二辆车

某久,就和永远一样,说着简单,但永远做不到。

这辆车是杜老师网购的,当时并非热爱骑行,只是早上去公司找不到共享单车。别问杜老师为何不开车,骑车十分钟开车半小时谁能信呢!

于是乎呵呵了~

车刚到时,杜老师足足兴奋了一秒,然后就被装车恶心到了。前前后后两个小时,终于装成功了,因天时已晚了,所以没做试骑直接睡了。

哪想到第二天一堆问题,车座固定不牢、车轮闸线太松、变速卡位不准。您能想象一个人站着骑全程,每每停车要靠脚刹的情形吗?

之后又调整了几次,但感觉越发难骑了,一气之下就给卖了。买家付款的一瞬间杜老师都在想,只要别退回来,宁愿搭钱!

第三辆车

杜老师目前的座驾,配图以示尊重:

真是一分钱一分货,当时想着花了近 3000 很是心疼,但上手后才发现什么是骑行体验,之前写过一文《喜德盛 2022 款极速 500 平把公路车体验文》感兴趣的小伙伴可以去看看:

人的欲望永远无法满足,直把公路车骑过了,就想试试弯把。禧玛诺变速器用过,就想试试高端的电子变速器。铝合金车架提过了,就想试试碳纤维的。

和车友交流心得后,被推荐了一款满足杜老师需求的,一看价位 17000 多,当杜老师还在思考是不是打劫时,人家已经在夸性价比了。

至今暂无换车打算,也许仅是用来通勤,没有必要上升到专业性,且骑行对男性不是很好「可以自行搜索」

最后为了我们的下半身和下半身,奉劝各位骑行爱好者们:一入骑行深似海从此钱包是路人!

  •  

诺为 N95 Pro Spotlight 翻页笔使用体验

因为授课需要,杜老师需要随身携带翻页笔。不过上课的教室很少使用投影仪,而是换上了大尺寸的 LED,传统翻页笔的红光很不明显,故决定采购款绿光的翻页笔,下面分享下选购的这款诺为 N95 Pro Spotlight 翻页笔使用体验!

红光绿光

在同功率的情况下,一般绿光的光柱会比红光更亮更明显。有些极端的环境中,如大型会议室、室外场景,绿光指示效果更好。

绿光在空气中散射比红光大,加上眼睛对绿色波长的敏感度要比红色大 8 倍左右,所以绿光的视觉效果要比红光大 10 倍左右。

外观设计

笔身塑料,但握持的手感不错,按键主要集中在笔身的上端。笔身左侧则是开关,右侧有个长条按键,下方是充电口:

接收器比一般的翻页笔大些,卡扣设计不错,拿取方便:

特色功能

接收器 U 盘二合一。接收器具有存储的功能,内置翻页笔的驱动程序,分别有 Mac 和 Windows 版本,安装简单:

突出显示焦点区域。翻页笔支持聚光灯功能,可以突出显示焦点区域,并且支持调整光圈大小,以及圈外明暗程度:

高倍放大演示细节。翻页笔支持放大镜功能,可以高倍放大演示细节,并且支持调整放大镜的大小,以及放大倍数:

一键切换全屏标注。翻页笔可一键全屏标注,无需手动切换标注模式,即可实现全屏划线标注,且不限制演示软件:

聊聊缺点

首先发光模块成本更高,所以笔身价格较贵,杜老师这款翻页笔,某东的价格为 209 元「还是 618 特惠价」

其次接收器的读写速度不是很快,接口是 USB2.0,与 32GB 的容量不相配。

再次是翻页笔内置了陀螺仪,可以实现空中鼠标功能,不过定位没有那么精确,在使用聚光灯等功能时,还需手稳一些,操作幅度不要太大!

最后是音量键,在修改时可以通过上下划来调整音量,不过灵敏度不太高,很难精确调整音量「非强迫症可以无视该条」

  •  

又一款碾压 ChatGPT 的 AI 人工智能应用

在上一篇分享文中,杜老师介绍了 3 款免费的 GPT-4 平台,今天杜老师又遇到一款能碾压 ChatGPT 的 AI 人工智能应用,并支持多平台「含 Web、安卓端等」该平台同样支持 GPT-4,可惜的是需要科学上网才可访问。

访问地址

访问地址如下,再次强调一下,需科学上网才可以访问:

食用方法

在使用平台的服务之前,需要先同意平台的隐私协议,这里需点击 Accept:

页面支持语言切换,无需我们使用浏览器的翻译功能,点击右上角的 EN 可选择中文:

手机端的小伙伴们可以下载对应端 APP,杜老师还没有试过,体验过的小伙伴可留言评测:

该平台支持根据关键词生成图像,相比平时的 ChatGPT 功能更加齐全:

这里的名人栏,可以切换不同角色,平台会模仿名人语气与我们对话,还挺像的:

测试一下文字对话,效果如下:

  •  

免费使用 ChatGPT-4 的 3 种方法

最近在小伙伴们的博客乱串,发现洪兄会经常分享一些 AI 站的使用体验,今天杜老师也蹭波热度,水一篇分享文。大家都知道目前可白嫖的 ChatGPT 几乎都是 GPT-3.5 版,文字缺失零星,杜老师为小伙伴们介绍免费使用 ChatGPT-4 的 3 种方法,希望能帮到有需要的小伙伴!

免费站一

点击 这里 访问「注意需要科学访问」该站无需注册。在页面上方选择 GPT-4。Active persona 对应了 AI 的角色,可以选择不同身份记性对话,它们语气语态也会有所不同。Access internet 为在模型无法处理时,是否进行网络请求,Never 对应着从不,Auto 对应着自动,Always 对应着总是请求。在页面下方输入框键入关键词即可,对话效果可见下图:

免费站二

点击 这里 访问「注意需要科学访问」该站已经无需审核,且不需要登录即可使用「但对话有次数限制,可通过登录解决限制的问题」点击立即聊天,在新页面中选择更有创造力的对话样式,该样式使用 GPT-4 模型。在页面下方输入框键入关键词即可,对话效果可见下图:

免费站三

点击 这里 访问「此站无需科学访问」该站无需注册,但需要自定义身份模型。Name 为 AI 的名称「这是机器人的显示名称,当用户与之交互时,将显示给用户」Prompt 为 AI 的身份「添加说明,让聊天机器人记住,可以使用它根据自己的喜好自定义聊天机器人」Description 为可选「使用它来描述聊天机器人的作用,将在用户与之交互时显示给用户」输入完成后点击 Create Bot:

页面跳转后即可在下方输入框键入关键词进行对话,效果可见下图:

写在最后

ChatGPT 确实方便了我们的工作和生活,就比如杜老师每次工作需要编写文稿,都会使用 ChatGPT 来生成大纲,写好的文稿也会通过其润色,这样提升了效率的同时,也获得更好的工作成果。

但随着博友间日常拜访,杜老师发现很多小伙伴开始使用 ChatGPT 来生成文章,拓展其博客文章量。在个人主观的角度,还是不建议如此操作的,毕竟 ChatGPT 生成的文字客观性很大的,但并无明确的态度以及思想,建议适度使用。

杜老师近日也是特别的繁忙,服务器被攻击来不及去处理,导致图床几个小时无法访问;留言来不及去回复,堆积了几天的留言还未回访;文章来不及去编写,只能用口水文代替。但仍感谢小伙伴们不断地支持和帮助。

最后,今天是 bill 小朋友的生日,祝他生日快乐!

  •  

下一代静态博客框架 Valaxy

杜老师一直在找 Hexo 替代框架,因为杜老师说博客文章量比较多,站点页面生成速度太慢,经晓雨童靴的推荐,了解到 Valaxy 框架。本文介绍 Valaxy 的特点,以及部署方式,感兴趣的小伙伴可以尝试下!

框架介绍

Valaxy 的目标是成为新一代静态博客框架与生成器。提供更好热更新与用户加载体验、更强大更便捷自定义开发可能性。支持配置、文章的热更新,而不像 Hexo 一样重新加载页面。

它与 Hexo 相比开发体验和速度上都更胜一筹,且与 VitePress/VuePress 相比拥有更多针对博客的集成功能,譬如文章列表钩子、自动路由、组件注册、可覆盖的布局与主题等。

Valaxy 基于 Vite 提供热更新与打包功能,基于 Vue 实现视图等客户端的功能。因此 Valaxy 兼容并可自由使用 Vite 与 Vue 生态所有插件。

Valaxy 已经默认集成 Open Graph 的 SEO 优化。需要注意的是,对于许多搜索引擎来说,它们可能只青睐 SSG 构建模式。

部署过程

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
penn@penn-PC:~/Desktop$ sudo npm i -g pnpm
请输入密码:
验证成功

added 1 package in 13s

1 package is looking for funding
run `npm fund` for details
penn@penn-PC:~/Desktop$ npm init valaxy
Need to install the following packages:
create-valaxy@0.14.30
Ok to proceed? (y)

🌌 Valaxy v0.14.30

Project name: … valaxy-blog
📁 /home/penn/Desktop/valaxy-blog

Scaffolding project in valaxy-blog ...
Done.

✔ Install and start it now? … yes
✔ Choose the agent › pnpm
Downloading registry.npmjs.org/typescript/4.8.4: 11.9 MB/11.9 MB, done
Packages: +435
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Packages are hard linked from the content-addressable store to the virtual store.
Content-addressable store is at: /home/penn/.local/share/pnpm/store/v3
Virtual store is at: node_modules/.pnpm
node_modules/.pnpm/vue-demi@0.14.5_vue@3.3.4/node_modules/vue-demi: Running postinstall script, done in 119ms
Progress: resolved 457, reused 0, downloaded 435, added 435, done
node_modules/.pnpm/esbuild@0.17.19/node_modules/esbuild: Running postinstall script, done in 73ms

dependencies:
+ valaxy 0.14.30
+ valaxy-theme-yun 0.14.30

devDependencies:
+ typescript 4.8.4 (5.1.3 is available)

 WARN  Issues with peer dependencies found
.
├─┬ valaxy 0.14.30
│ └─┬ vite-ssg 0.22.2
│ └── ✕ unmet peer critters@^0.0.16: found 0.0.17 in valaxy
└─┬ valaxy-theme-yun 0.14.30
└─┬ valaxy-addon-waline 0.1.0
└── ✕ unmet peer valaxy@latest: found 0.14.30

Done in 1m 34.2s

> valaxy-blog@0.14.30 dev /home/penn/Desktop/valaxy-blog
> valaxy

ℹ Resolve valaxyConfig from /home/penn/Desktop/valaxy-blog/valaxy.config.ts 03:31:05
ℹ Resolve siteConfig from /home/penn/Desktop/valaxy-blog/site.config.ts 03:31:05
ℹ Resolve valaxy.config.ts from theme(yun) 03:31:05
ℹ Resolve addons: 03:31:06

🌌 Valaxy v0.14.30

🪐 theme > yun
📁 /home/penn/Desktop/valaxy-blog

Preview > http://localhost:4859/
Network > http://192.168.36.141:4859/

shortcuts > restart | open | edit

注意:官方推荐使用 pnpm 来部署,所以杜老师第一步安装了 pnpm。另外在 Choose the agent 一步,需要选 pnpm。完成 Valaxy 的部署后会自动运行,默认端口号 4859。

博客更新

如需发布文章,进入到博客根目录的 pages/posts,新建.md 文件就行了,内容结构如下:

1
2
3
4
5
6
7
8
9
10
11
---
title: Title
hide: true
excerpt_type: text
---

这是摘要

<!-- more -->

这是正文

参数作用详见下表:

参数作用阈值
title文章标题暂无
hide临时隐藏某篇文章当设置为 true 或 all 时,文章仍然会被渲染,可以直接访问链接进行查看。但不会被显示在展示的文章卡片与归档中;当设置为 index 时,将只在首页隐藏归档中仍然展示。
excerpt_type预览列表摘要渲染类型md 展示原始 Markdown;html 以 HTML 的形式展示;text 以纯文本的形式展示。

从 Hexo 迁移

Hexo 博客目录与 Valaxy 博客目录对应的关系如下,将相关的内容复制至对应文件夹即可:

用途HexoValaxy
文章source/_postspages/posts
页面sourcepages
静态资源sourcepublic

托管部署

  1. GitHub Pages: 在创建模版项目时,已内置文件 .github/workflows/gh-pages.yml 以实现 GitHub Actions 的自动部署工作流。

  2. Netlify: 已内置 netlify.toml。

  3. Vercel: 将 Framework Preset 设置为 Other,并更改 Build and Output Settings,将 Output Directory 设置为 dist 后点击 Deploy。

  4. Cloudflare Pages: 点击创建应用程序——连接到 Git,然后选择点击开始设置,将构建输出目录设置为 dist 后添加一个环境变量。变量名称设置为 NODE_VERSION,阈值为 16.0,最后点击保存并部署就行了。

使用体验

杜老师将已发布的 590 篇文章迁移到 Valaxy,仅需 20 秒即可生成站点页面文件,而通过 Hexo 则需要 8 分钟「大概是因为杜老师说使用了太多插件」

不过毕竟是新型的框架,目前主题及插件比较少,并不足以满足杜老师的使用需求,想折腾的小伙伴可以尝试下,杜老师也在坐等着更多模板。

  •  

FreeDB 免费数据库托管服务

《Vercel 免费托管 Typecho 博客》一文中提到了免费的数据库托管,今天杜老师就来介绍下 FreeDB,它提供免费的远程 MySQL 数据库托管和优质的稳定服务,以满足项目的需求。本文详细说明其注册及使用方法!

什么是 FreeDB

FreeDB 是免费 MySQL 托管服务提供商,免费提供 50MB 数据库,可以通过获取专业计划进行扩展。

每小时最大查询数为 800,每小时最大更新数为 800,最大连接数 800。

服务条款:

  1. 数据库中不得包含任何非法内容;

  2. 数据库大小不应超过 50MB;

  3. 如滥用服务将导致终止;

  4. 如果数据库凭据在互联网上泄露,帐户将被终止;

  5. 每个人只允许拥有一个帐户;

  6. 一次性或者临时电子邮件帐户将自动终止.

服务配置

  1. 1 个 MySQL 数据库;

  2. 50MB 数据库存储空间;

  3. 允许远程连接 MySQL 数据库;

  4. MySQL 8数据库;

  5. phpMyAdmin 数据库管理面板;

  6. 每小时最大查询数为 800,每小时最大更新数为 800,最大连接数 800。

注册使用

点击 这里 访问 FreeDB 的官网,并点击 Get Started:

依次填入邮箱、昵称、密码,并进入邮箱内接收验证邮件:

通过验证邮件链接跳转页面,分别输入项目介绍、使用方式、用户名称:

在 FreeDB Free Database Panel 处依次输入数据库名称和数据库用户,并点击后面的创建:

完成创建即会显示连接信息,分别提供远程连接地址、连接端口、数据库名、用户名及密码:

如需管理,可点击下方的 PhpMyAdmin 5.1 进入到控制面板:

  •  

推荐一下 Fgaoxing 与武汉初柒公司提供的公益 CDN

杜老师一直都非常支持公益项目,近期发现博友圈内,又有小伙伴提供公益 CDN 服务。感谢 Fgaoxing 与武汉初柒公司提供的公益 CDN,杜老师亲测还不错,故发文推荐下!

项目官网

项目官网地址如下:

服务介绍

自从 jsD 被禁后,国内调用 GitHub 的文件愈发困难,虽然一些热心的小伙伴提供 NPM 公益镜像源,但调用时,仍然需要上传文件到 NPM 平台,操作十分不便。

CDNN 是一个独立于 jsDelivr 和 cdnjs 的公益 CDN,与 jsDelivr 用法类似,并且速度极快,可用于任何网站引用 GitHub/NPM/Gitee/cdnjs 等中的文件和图片。由 Fgaoxing 与武汉初柒公司合作搭建公益 CDN,使用数据库存储,缓存时长六个小时,部署于初柒云,目录结构于 jsD 类似。

使用规则

  1. 禁止大量请求,反复获取,对本站流量及带宽造成影响;

  2. 不得用其获得违法内容,否则本站概不负责;

  3. 如果存储隐私内容,并且使用使用 CDN 缓存后,导致无法删除,本站不会理睬。

  4. 如遇问题,可以前往官网支持群 115967669 获取帮助。

  •  

用脚本部署 Bitwarden 密码管理平台

应海阔蓝童鞋的需求分享如何使用 Docker 部署 Bitwarden 密码管理平台的教程。因杜老师近期出差时间紧张,没有精力细致整理排版,但确保可成功部署,需要的小伙伴可以参考,如有建议可在评论区中留言!

准备工作

在开始部署 Bitwarden 之前,请确保已经安装 Docker。这里以 Ubuntu 为例,更新软件包索引并安装软件包以允许使用基于 HTTPS 存储库:

1
2
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg

添加 Docker 官方 GPG 密钥:

1
2
3
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

使用以下命令设置软件包存储库:

1
echo "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

更新索引:

1
sudo apt-get update

安装 Docker Engine 等相关组件:

1
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

通过运行映像以验证 Docker 引擎安装是否成功「可选」

1
sudo docker run hello-world

拉取源码

1
curl -Lso bitwarden.sh https://go.btwrdn.co/bw-sh && chmod +x bitwarden.sh

注意:将 Bitwarden 安装脚本 bitwarden.sh 下载到计算机上。

部署项目

1 为设置访问域名;2 为是否申请安全访问证书「为了演示,杜老师这里选择否」3 为设置数据库的名称「可自定义」4 输入安装 ID「申请页见下图」5 输入安装 KEY;6 是否自定义安全证书「为了演示,杜老师这里选择否,如果遇到问题,可在评论区中留言」7 是否配置自签名证书:

1
2
3
4
5
6
7
8
penn@penn-virtual-machine:~$ sudo ./bitwarden.sh install
(1) Enter the domain name for your Bitwarden instance (ex. bitwarden.example.com): bw.dusays.com
(2) Do you want to use Let's Encrypt to generate a free SSL certificate? (y/n): n
(3) Enter the database name for your Bitwarden instance (ex. vault): bitwarden
(4) Enter your installation id (get at https://bitwarden.com/host):
(5) Enter your installation key:
(6) Do you have a SSL certificate to use? (y/n): n
(7) Do you want to generate a self-signed SSL certificate? (y/n): n

安装 ID 和 KEY 的申请页面如下:

启动服务

使用下面命令启动服务:

1
sudo ./bitwarden.sh start

其它指令列表如下:

指令作用
restart重新启动所有容器「与 start 相同」
stop停止所有容器
update更新所有容器和数据库
updatedb更新、初始化数据库
updaterun更新运行脚本文件
updateself更新此主脚本
updateconf在不重新启动正在运行实例的情况下更新所有容器
uninstall在执行此命令之前,系统将提示保存数据库文件。将创建数据库的 tar 文件,包括最新备份。停止容器,删除目录及其所有内容,并删除临时卷。执行后系统将询问是否要清除所有 Bitwarden 镜像
renewcert续订证书
rebuild从 config.yml 中重建生成的安装资产
help列出所有命令

访问页面

项目启动后根据之前设置的域名访问:

写在最后

前端建议用 Nginx 反向代理,并通过 SSL 加密,以保证密码的安全。

后期杜老师也会进一步整理此文,并尽可能增加应用实例。

  •  

Vercel 免费托管 Typecho 博客

应 bill 小朋友的需求分享如何使用 Vercel 免费托管 Typecho 博客教程。因杜老师近期出差时间紧张,没有精力细致整理排版,但确保可成功部署,需要的小伙伴可以参考,如有建议可在评论区中留言!

写在前面

Typecho 是由 type 和 echo 两个词合成的,来自于开发团队的头脑风暴。Typecho 基于 PHP 开发,支持多种类型的数据库,是款内核强健﹑扩展方便﹑体验友好﹑运行流畅的轻量级开源博客程序。

Vercel 是一个用来部署前端应用的云平台,但也可以用来构建轻量级的事件驱动,并部署到它的全球边缘网络。很多小伙伴喜欢使用 Vercel 部署博客,但大家可能不知道,Vercel 还支持 PHP 源码的部署。今天我们就用 Vercel 免费部署 Typecho 博客!

准备工作

  1. Typecho 非最新版本源码「1.2.0 版会检测目录是否能写入,推荐使用 这个 源码,感谢小伙伴的提醒」

  2. GitHub 账号及相关工具「推荐用 GitHub Desktop」

  3. MySQL 或其它类型数据库的托管平台「本文用 FreeDB 演示」

  4. Vercel 的账号「推荐用 GitHub 账号登录」

操作步骤

在 FreeDB 申请免费 MySQL 数据库:

在 Typecho 源码目录下新建文件 config.inc.phpvercel.jsonapi/index.php 等文件,效果如下:

其中 config.inc.php 文件的内容如下「注意 host/user/password/database 请根据实际信息修改」

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
define('__TYPECHO_SECURE__',true);
define('__TYPECHO_ROOT_DIR__', dirname(__FILE__));
define('__TYPECHO_PLUGIN_DIR__', '/usr/plugins');
define('__TYPECHO_THEME_DIR__', '/usr/themes');
define('__TYPECHO_ADMIN_DIR__', '/admin/');
@set_include_path(get_include_path() . PATH_SEPARATOR .
__TYPECHO_ROOT_DIR__ . '/var' . PATH_SEPARATOR .
__TYPECHO_ROOT_DIR__ . __TYPECHO_PLUGIN_DIR__);
require_once 'Typecho/Common.php';
Typecho_Common::init();
$db = new Typecho_Db('Pdo_Mysql', 'typecho_');
$db->addServer(array (
'host' => 'sql.freedb.tech',
'port' => 3306,
'user' => 'freedb_dusays',
'password' => 'sPyT&R#5NyFPSnP',
'charset' => 'utf8mb4',
'database' => 'freedb_dusays',
'engine' => 'MyISAM',
), Typecho_Db::READ | Typecho_Db::WRITE);
Typecho_Db::set($db);

vercel.json 文件的内容如下:

1
2
3
4
5
6
7
8
{
"functions": {
"api/index.php": {
"runtime": "vercel-php@0.4.0"
}
},
"routes": [{ "src": "/(.*)", "dest": "/api/index.php" }]
}

api/index.php 文件的内容如下:

1
2
3
4
5
6
7
8
9
10
<?php
$file= __DIR__ . '/..'.$_SERVER["PHP_SELF"];
if(file_exists($file))
{
return false;
}
else
{
require_once __DIR__ . '/../index.php';
}

在 GitHub Desktop 新建项目,并上传 Typecho 源码:

在 Vercel 导入刚新建的项目,部署后即可通过域名访问 Typecho 安装页面:

访问 Vercel 提供的域名,记得在域名结尾添加 /install.php

写在最后

杜老师首先要提醒使用这种方式的小伙伴,用于短期体验折腾没有问题,长期的话建议还是用服务器托管。

该种方式源码端的变更「例如上传文件」无法同步至 GitHub 仓库,这就会造成数据的丢失。

  •