Initial commit
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
关于 Netflix 界面切换为简中。(2025年04月01日)
|
||||
|
||||
如果是新账号或合租账号,刚开始登录可能是简中或者繁重,我感觉是看运气。我开始是简中。但是当我(好奇宝宝)手动改了设置里的语言设置之后,再改回中文手机和电脑就总是繁重了,虽然字幕还是简中,但也是怪怪的。
|
||||
|
||||
忍受了几天之后,我打算看看怎么回事,自己也找了一些网上的方法基本是两种:
|
||||
|
||||
1. IP 切换。(我自己尝试是无效的。)
|
||||
1. 新加坡、印度、马来西亚等地区的 IP 地址是简体中文。
|
||||
2. 香港、台湾、美国等地区的 IP 地址是繁体中文。
|
||||
2. 浏览器控制台找到保存语言时的 `pathEvaluator` 请求。
|
||||
|
||||
这里使用第二种方式成功的,但是现在 Netflix 已经不是 `pathEvaluator` 接口了。换成了 `graphql` 接口。
|
||||
|
||||
所以你只需要:
|
||||
|
||||
1. 打开浏览器控制台捕捉到 `/graphql` 请求。
|
||||
2. 右键复制 cURL。
|
||||
3. 记事本打开,找到 `primaryLanguage` 字段,改为 `zh-SG`。
|
||||
4. 然后将请求发出去就可以了。(这里我是把 bash 的 cURL 放到了 Postman 中请求了一下。大家可以任意发挥,只要是能请求通就行啦。)
|
||||
5. 然后你的电脑和手机都会变为简中。
|
||||
|
||||

|
||||
|
||||
> [!TIP]
|
||||
>
|
||||
> 当修改成功之后就不要再动 设置语言偏好 - 显示语言 的设置了。
|
||||
>
|
||||
> 它可能是空白或者 Dansk,不用管,后台配置已经是简中了。
|
||||
|
||||

|
||||
@@ -0,0 +1,239 @@
|
||||
# 更新软件包管理器的源列表 将可更新的软件包升级到新版本
|
||||
|
||||
```bash
|
||||
sudo apt update && sudo apt full-upgrade -y
|
||||
```
|
||||
|
||||
# SSH
|
||||
|
||||
## 检查是否安装了 SSH 服务
|
||||
|
||||
```bash
|
||||
sudo dpkg -l | grep openssh-server
|
||||
```
|
||||
|
||||
## 安装 SSH 服务
|
||||
|
||||
```bash
|
||||
sudo apt install openssh-server
|
||||
```
|
||||
|
||||
## 检查 SSH 服务状态
|
||||
|
||||
```bash
|
||||
sudo systemctl status ssh
|
||||
```
|
||||
|
||||
## 启动 SSH 服务
|
||||
|
||||
```bash
|
||||
sudo systemctl start ssh
|
||||
```
|
||||
|
||||
## 开启 SSH 服务开机自启动
|
||||
|
||||
```bash
|
||||
sudo systemctl enable ssh
|
||||
```
|
||||
|
||||
## 检查防火墙设置
|
||||
|
||||
```bash
|
||||
sudo ufw status
|
||||
```
|
||||
|
||||
```bash
|
||||
sudo ufw allow ssh
|
||||
```
|
||||
|
||||
# 网络设置
|
||||
|
||||
```bash
|
||||
sudo vim /etc/netplan/
|
||||
|
||||
sudo netplan apply
|
||||
```
|
||||
|
||||
```yml
|
||||
network:
|
||||
version: 2
|
||||
renderer: networkd
|
||||
ethernets:
|
||||
ens33:
|
||||
dhcp4: no
|
||||
addresses:
|
||||
- 192.168.126.100/24 # 固定IP地址和子网掩码
|
||||
routes:
|
||||
- to: default
|
||||
via: 192.168.126.2 # 默认网关
|
||||
nameservers:
|
||||
addresses:
|
||||
- 8.8.8.8 # DNS服务器
|
||||
- 8.8.4.4
|
||||
```
|
||||
|
||||
# 开启 root 登录
|
||||
|
||||
在 Ubuntu 系统中,默认情况下是禁用了 `root` 账号的直接登录,但可以通过设置来启用 `root` 账号。以下是启用 `root` 账号并设置密码的步骤:
|
||||
|
||||
## 切换到 `root` 用户并设置密码
|
||||
|
||||
首先,你需要给 `root` 账号设置一个密码,默认情况下,Ubuntu 是没有为 `root` 账号分配密码的。
|
||||
|
||||
1. 打开终端,输入以下命令,切换到 `root` 权限(输入当前用户的密码):
|
||||
|
||||
```bash
|
||||
sudo -i
|
||||
```
|
||||
|
||||
1. 设置 `root` 密码,执行以下命令并输入你希望为 `root` 账号设置的密码:
|
||||
|
||||
```bash
|
||||
passwd root
|
||||
```
|
||||
|
||||
1. 系统会提示你输入两次密码进行确认。
|
||||
|
||||
## 启用 `root` 用户登录
|
||||
|
||||
虽然你已经设置了 `root` 账号的密码,但在默认情况下,Ubuntu 禁止 `root` 用户通过 SSH 或 GUI(图形界面)登录。如果你需要启用 `root` 登录,还需要做以下操作:
|
||||
|
||||
### 启用 SSH 远程登录(可选)
|
||||
|
||||
如果你希望允许 `root` 用户通过 SSH 远程登录,还需要修改 SSH 配置文件。
|
||||
|
||||
1. 打开 SSH 配置文件:
|
||||
|
||||
```bash
|
||||
sudo vim /etc/ssh/sshd_config
|
||||
```
|
||||
|
||||
1. 找到以下内容:
|
||||
|
||||
```
|
||||
PermitRootLogin prohibit-password
|
||||
```
|
||||
|
||||
1. 将其修改为:
|
||||
|
||||
```shell
|
||||
PermitRootLogin yes
|
||||
```
|
||||
|
||||
1. 保存文件并退出编辑器(按 `Ctrl + O` 保存,按 `Ctrl + X` 退出)。
|
||||
2. 重启 SSH 服务:
|
||||
|
||||
```bash
|
||||
sudo systemctl restart ssh
|
||||
```
|
||||
|
||||
这样,你就可以使用 `root` 用户通过 SSH 登录了。
|
||||
|
||||
# Docker 安装
|
||||
|
||||
## 安装必要的依赖包
|
||||
|
||||
```bash
|
||||
apt update
|
||||
apt install -y apt-transport-https ca-certificates curl gnupg lsb-release software-properties-common
|
||||
```
|
||||
|
||||
## 添加 Docker 的官方 GPG 密钥
|
||||
|
||||
```bash
|
||||
# 官方
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
||||
|
||||
# 阿里
|
||||
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/aliyun-docker-archive-keyring.gpg
|
||||
```
|
||||
|
||||
## 设置 Docker 存储库
|
||||
|
||||
```bash
|
||||
# 官方
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
|
||||
# 阿里
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/aliyun-docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
```
|
||||
|
||||
## 更新包列表并安装 Docker
|
||||
|
||||
```bash
|
||||
apt update
|
||||
apt install docker-ce docker-ce-cli containerd.io
|
||||
```
|
||||
|
||||
## 检查 Docker 是否成功安装
|
||||
|
||||
```bash
|
||||
sudo systemctl status docker
|
||||
```
|
||||
|
||||
## 将当前用户添加到 Docker 用户组(可选,但推荐这样做以避免每次运行 Docker 都需要 sudo)
|
||||
|
||||
```bash
|
||||
sudo usermod -aG docker ${USER}
|
||||
```
|
||||
|
||||
之后,退出当前会话并重新登录以使更改生效。
|
||||
|
||||
## 配置镜像源
|
||||
|
||||
`touch /etc/docker/daemon.json`
|
||||
|
||||
```shell
|
||||
{
|
||||
"registry-mirrors": [
|
||||
"https://docker.hpcloud.cloud",
|
||||
"https://docker.m.daocloud.io",
|
||||
"https://docker.unsee.tech",
|
||||
"https://docker.1panel.live",
|
||||
"http://mirrors.ustc.edu.cn",
|
||||
"https://docker.chenby.cn",
|
||||
"http://mirror.azure.cn",
|
||||
"https://dockerpull.org",
|
||||
"https://dockerhub.icu",
|
||||
"https://hub.rat.dev"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 重启
|
||||
|
||||
```
|
||||
systemctl daemon-reload
|
||||
systemctl restart docker
|
||||
```
|
||||
|
||||
## 测试 Docker 安装
|
||||
|
||||
```bash
|
||||
docker run hello-world
|
||||
```
|
||||
|
||||
## 下载镜像及打包镜像
|
||||
|
||||
```bash
|
||||
docker pull nginx
|
||||
|
||||
docker save -o nginx_image.tar nginx:latest
|
||||
|
||||
docker load -i nginx_image.tar
|
||||
```
|
||||
|
||||
# Java 环境变量
|
||||
|
||||
```
|
||||
export JAVA_HOME=/usr/local/jdk
|
||||
export JRE_HOME=$JAVA_HOME/jre
|
||||
export CLASSPATH=.:$CLASSPATH:$JAVA_HOME/lib:$JRE_HOME/lib
|
||||
export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
|
||||
```
|
||||
|
||||
# nohup
|
||||
|
||||
```sh
|
||||
nohup /apprun/jdk/bin/java -jar test-mail-0.0.1-SNAPSHOT.jar > ./app.log 2>&1 &
|
||||
```
|
||||
@@ -0,0 +1,583 @@
|
||||
# LazyVim / Neovim 快捷键与操作手册
|
||||
|
||||
> 说明:本文是基于 LazyVim 的个人速查笔记,内容以“使用场景 → 快捷键 → 结果/备注”为主。
|
||||
>
|
||||
> 记号约定(尽量统一):
|
||||
>
|
||||
> - `Ctrl-x` 统一写作 `<C-x>`(例如 `Ctrl-r` → `<C-r>`)
|
||||
> - `Alt-x` 统一写作 `<A-x>`
|
||||
> - `<Space>` 表示 LazyVim 默认 `<leader>`
|
||||
|
||||
---
|
||||
|
||||
## 1. 常用模式切换与通用操作
|
||||
|
||||
| 快捷键 | 模式 | 作用与说明 |
|
||||
|---|---|---|
|
||||
| `<C-r>` | Insert | 进入“寄存器”迷你模式,可选择寄存器内容粘贴 |
|
||||
| `<C-r> +` | Insert | 从系统剪贴板粘贴文本 |
|
||||
| `<C-r>` | Normal | 重做 (Redo),撤销上一次的 `u` 操作 |
|
||||
| `"`(双引号) | Normal | 指定后续操作(如 `y`, `p`)要使用的寄存器 |
|
||||
| `gi` | Normal | 跳转至上次进入 Insert 的位置,并重新进入 Insert |
|
||||
| `g` | Normal | 进入 "Go To" 迷你模式,停顿会显示所有 `g` 开头命令 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 代码导航(Getting Around)
|
||||
|
||||
### 2.1 屏幕内快速跳转(flash.nvim / Seek)
|
||||
|
||||
| 快捷键 | 模式 | 作用与说明 |
|
||||
|---|---|---|
|
||||
| `s` | Normal | 进入 Seek 模式(flash.nvim):输入目标字符,按高亮标签跳转 |
|
||||
|
||||
### 2.2 屏幕与页面滚动
|
||||
|
||||
| 快捷键 | 模式 | 作用与说明 |
|
||||
|---|---|---|
|
||||
| `<C-d>` | Normal | 向下滚动半屏 (Down) |
|
||||
| `<C-u>` | Normal | 向上滚动半屏 (Up) |
|
||||
| `<C-f>` | Normal | 向下滚动整页 (Forward) |
|
||||
| `<C-b>` | Normal | 向上滚动整页 (Backward) |
|
||||
| `<C-e>` | Normal | 向上滚动一行(光标不动) |
|
||||
| `<C-y>` | Normal | 向下滚动一行(光标不动) |
|
||||
| `zt` | Normal | 将当前行滚动到屏幕顶部 (Top) |
|
||||
| `zz` | Normal | 将当前行滚动到屏幕中部 (Center) |
|
||||
| `zb` | Normal | 将当前行滚动到屏幕底部 (Bottom) |
|
||||
|
||||
### 2.3 光标移动(Motions)
|
||||
|
||||
| 分类 | 快捷键 | 模式 | 作用与说明 |
|
||||
|---|---|---|---|
|
||||
| 基础移动 | `h` / `j` / `k` / `l` | Normal | 左 / 下 / 上 / 右 |
|
||||
| 计数移动 | `<数字><命令>` | Normal | 重复执行命令 N 次;例:`5j` |
|
||||
| 行内查找 | `f<字符>` | Normal | 向后查找并跳到第 1 个指定字符 |
|
||||
| | `<数字>f<字符>` | Normal | 向后查找并跳到第 N 个指定字符 |
|
||||
| | `F<字符>` | Normal | 向前查找字符 |
|
||||
| | `t<字符>` / `T<字符>` | Normal | 向后/向前跳到指定字符的前一个/后一个位置 |
|
||||
| 按词移动 | `w` / `W` | Normal | 到下一个单词 / 大单词(空格分隔)开头 |
|
||||
| | `e` / `E` | Normal | 到下一个单词 / 大单词结尾 |
|
||||
| | `b` / `B` | Normal | 到上一个单词 / 大单词开头 |
|
||||
| | `ge` | Normal | 到上一个单词结尾 |
|
||||
| 行内跳转 | `0` | Normal | 行的绝对开头(第 0 列) |
|
||||
| | `^` | Normal | 行的第一个非空白字符 |
|
||||
| | `$` | Normal | 行尾 |
|
||||
| | `g_` | Normal | 行的最后一个非空白字符 |
|
||||
| 文件跳转 | `gg` | Normal | 文件第一行 |
|
||||
| | `G` | Normal | 文件最后一行 |
|
||||
| | `<数字>G` 或 `:<数字>` | Normal | 跳到指定行;例:`100G` |
|
||||
| 历史跳转 | `<C-o>` | Normal | 跳回上一个光标位置 |
|
||||
| | `<C-i>` | Normal | 前进到下一个光标位置(与 `<C-o>` 相反) |
|
||||
|
||||
---
|
||||
|
||||
## 3. 文件操作与管理
|
||||
|
||||
### 3.1 文件选择器(Telescope)
|
||||
|
||||
| 快捷键 | 模式 | 作用与说明 |
|
||||
|---|---|---|
|
||||
| `<Space><Space>` | Normal | 查找项目文件 (Root),最常用 |
|
||||
| `<Space>ff` | Normal | 查找项目文件 (Root) |
|
||||
| `<Space>fF` | Normal | 查找文件 (Cwd,当前工作目录) |
|
||||
|
||||
选择器内常用操作:
|
||||
|
||||
- `Tab`:标记多个文件
|
||||
- `<A-s>`:为条目添加标签,按标签字符快速选择
|
||||
- `<C-d>` / `<C-u>`:滚动结果列表
|
||||
|
||||
### 3.2 文件浏览器(Snacks.nvim Explorer)
|
||||
|
||||
| 快捷键 | 模式 | 作用与说明 |
|
||||
|---|---|---|
|
||||
| `<Space>e` | Normal | 打开文件浏览器 (Root) |
|
||||
| `<Space>E` | Normal | 打开文件浏览器 (Cwd) |
|
||||
| `?` | 浏览器内 | 显示帮助(查看所有可用操作) |
|
||||
| `a` / `d` / `r` | 浏览器内 | 添加 / 删除 / 重命名 文件或文件夹 |
|
||||
| `y` / `p` / `m` | 浏览器内 | 复制 / 粘贴 / 移动 |
|
||||
| `q` 或 `Esc` | 浏览器内 | 关闭浏览器 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 配置与插件(LazyVim / Lazy Extras)
|
||||
|
||||
### 4.1 LazyExtras 管理界面
|
||||
|
||||
| 命令/按键 | 模式 | 作用与说明 |
|
||||
|---|---|---|
|
||||
| `:LazyExtras` | Command | 打开 Lazy Extras 管理界面 |
|
||||
| `x` | LazyExtras 界面 | 安装或禁用选中的插件 |
|
||||
| `s` | LazyExtras 界面 | 使用 Seek 模式快速跳转 |
|
||||
|
||||
### 4.2 LazyVim 的三类插件(心智模型)
|
||||
|
||||
- 内置插件(默认启用):LazyVim 预装且预配置,通常默认不冲突;可自定义,但因集成深,偶尔需要技巧
|
||||
- Lazy Extras(可选增强):默认不启用;在 LazyVim 提供的“预期可协作”的配置下快速启用常见热门插件
|
||||
- 第三方未知插件(LazyVim 不特别支持):需要你从零配置,并自行排查键位/命令/UI 冲突;在 LazyVim 中通常数量较少
|
||||
|
||||
### 4.3 Lazy Extras 的启用与建议
|
||||
|
||||
- 进入方式:
|
||||
- Dashboard 按 `x`;或命令 `:LazyExtras`
|
||||
- Dashboard 也可用 `:lua Snacks.dashboard()` 打开(可自行绑键)
|
||||
- 操作方式:
|
||||
- 列表中移动到目标 extra,按 `x` 启用/安装;在 Enabled 区对同一项按 `x` 可禁用/卸载(记忆:x = Extra)
|
||||
- 可能需要重启 Neovim,让 Lazy.nvim 识别并同步依赖
|
||||
- 建议:
|
||||
- 启用常用语言的 `lang.*` extras
|
||||
- 安装 “Recommended plugins”(带星标)
|
||||
- 非推荐 extras 先别装太多,可能带来行为变化且不易预期
|
||||
- 深入信息:lazyvim.org → Extras,可查看每个 extra 安装的插件与 LazyVim 提供的配置
|
||||
|
||||
### 4.4 禁用内置插件(或关闭内置插件的某个功能)
|
||||
|
||||
- 配置目录通常为 `$HOME/.config/nvim`;Dashboard 按 `c` 或 `<Space>fc` 可快速打开配置文件
|
||||
- LazyVim 约定:`~/.config/nvim/lua/plugins/` 下任意 Lua 文件都会自动加载,文件名随意
|
||||
- 禁用某个内置插件:在 `lua/plugins/*.lua` 返回插件表并设置 `enabled = false`,例如禁用 bufferline:
|
||||
- `{ "akinsho/bufferline.nvim", enabled = false }`
|
||||
- 只关闭 Snacks.nvim 的某个功能而不是整个插件:
|
||||
- 在 `opts` 里关闭对应 feature(如 `explorer.enabled = false`)
|
||||
- 若要复用该功能占用的快捷键,可在 `keys` 中把对应键设为 `false` 以取消映射(例如 `<leader>e`、`<leader>E`)
|
||||
|
||||
### 4.5 修改键位:三种常见落点
|
||||
|
||||
- `lua/config/keymaps.lua`:更偏核心/全局的键位(非特定插件)
|
||||
- 某插件的配置表里写 `keys = { … }`:通常用于“全局键位”来启动/调用插件
|
||||
- 某插件的 `opts = { … }`:很多插件倾向通过 opts 定义“插件窗口/模式内”的局部键位与行为
|
||||
|
||||
#### 4.5.1 `keys` 条目的结构要点
|
||||
|
||||
- `keys` 是 Lazy.nvim/LazyVim 的机制:用于声明键位并由管理器统一注册(不是传给插件本身)
|
||||
- 每条 keys 通常包含:
|
||||
- 键位(如 `<leader>e`,LazyVim leader 通常是 `<Space>`)
|
||||
- 回调(Lua `function() … end`)或命令字符串
|
||||
- `desc` 描述(用于 Space 菜单/提示)
|
||||
- 特殊键使用 `<>` 表示:如 `<Right>`、`<Left>` 等
|
||||
|
||||
#### 4.5.2 LazyVim 的“合并(merge)”行为(关键理解)
|
||||
|
||||
- 你在插件文件里写的 `keys` 与 `opts` 会与 LazyVim(内置/extra)提供的默认配置进行合并
|
||||
- 若发生冲突(例如你重新定义了同一个键位),你的配置通常会覆盖默认值
|
||||
- 优点:无需复制整套默认配置,只写差异,升级更易维护
|
||||
- 代价:需要理解多来源键位/选项的叠加,冲突可能性更高
|
||||
|
||||
#### 4.5.3 mini.files 示例背后的概念(打开位置与 root/cwd)
|
||||
|
||||
- 需求示例:希望 mini.files 支持“在项目 root 打开”,并复用原本 Explorer 的键位
|
||||
- 概念区分:
|
||||
- root:根据项目标识文件(如 `package.json`、`Cargo.toml`)推断的项目顶层目录
|
||||
- cwd:编辑器当前工作目录(不一定等于 root)
|
||||
- 实现方式:在 `lua/plugins/` 新增一个覆盖文件(作者习惯用 `extend-` 前缀)为 mini.files 增加/覆盖 `keys`,并可额外通过 `opts` 改 mini.files 窗口内映射与窗口尺寸等
|
||||
|
||||
#### 4.5.4 当简单合并不够:`opts` 可以是函数
|
||||
|
||||
- 如果你要改的是“列表插入/函数行为”等,单纯用表合并不够用
|
||||
- `opts` 可写成 `function(_, opts) … end`:
|
||||
- 参数 `opts` 是 LazyVim 已生成的旧配置表
|
||||
- 你的函数要“就地修改”该表(不是返回新表)
|
||||
- 示例场景:给 Snacks dashboard 的 keys 列表用 `table.insert` 插入新入口(如 “Select Session”)
|
||||
|
||||
#### 4.5.5 安装 LazyVim 不认识的第三方插件
|
||||
|
||||
- 在 `lua/plugins/` 新建插件文件,返回一个表:
|
||||
- 第一个元素是 `"owner/repo"`
|
||||
- 再按需提供 `opts`、`keys` 等
|
||||
- `opts` 的来源:
|
||||
- 通常等价于插件 README 中 `setup({ … })` 需要的配置表;即使插件没写 Lazy.nvim 指南,也可直接把 setup 配置放进 `opts`
|
||||
- 若插件不自带键位:用 `keys` 声明并交由 Lazy.nvim 注册(常见做法是把键位与插件放在同一个文件,便于维护)
|
||||
- 插件发现渠道:`rockerBOO/awesome-neovim`(维护与清理较好)
|
||||
- 实务结论:LazyVim 已覆盖多数常用“最佳插件”(内置或 extra),你通常只需少量额外插件
|
||||
|
||||
#### 4.5.6 小结
|
||||
|
||||
- LazyVim 以“内置 / Extras / 第三方自理”的层级管理插件,提供合理默认配置并允许小幅覆盖
|
||||
- 日常改动主要落在 `lua/plugins/`:通过 `enabled`、`keys`、`opts`(以及必要时 `opts` 函数)实现禁用、改键与改行为
|
||||
- 你需要重点掌握:键位与选项的合并规则、冲突处理、以及 root 与 cwd 的概念差异
|
||||
|
||||
---
|
||||
|
||||
## 5. 基础编辑(编辑模型与常用命令)
|
||||
|
||||
> 本节保留“长表格”形式,便于全文搜索与对照(语法模型 + 示例混排)。
|
||||
|
||||
| 分类 | 快捷键 | 模式 | 作用与说明 |
|
||||
|---|---|---|---|
|
||||
| 心智模型/语法 | `<count><motion>` | Normal | 基本导航模型:计数 + 移动;count 通常表示重复次数;部分命令(如 `G`)把 count 当作绝对值;Seek 允许带 count 但会被忽略 |
|
||||
| 心智模型/语法 | `<verb><count><motion>` | Normal | 操作模型:先动词(operator/verb)再用 motion 指定范围;省略 verb 时默认是“只移动” |
|
||||
| 心智模型/语法 | `<count><verb><count><motion>` | Normal | 理论上 verb 和 motion 都可带 count;实践中更常见 `<count><verb><motion>` 或 `<verb><count><motion>` |
|
||||
| 插入模式(模型边界) | `i/I/a/A` + 可带 count(例:`5ifoo<Esc>`) | Normal → Insert → Normal | 进入 Insert 不属于 motion/verb,但可用 count 重复插入文本;例:`80i*<Esc>` 快速插入 80 个 `*`;这类命令不能像 motions 那样和 verbs 组合 |
|
||||
| 删除 | `d<motion>` | Normal | 删除光标到 motion 目标之间文本;执行后仍在 Normal,便于继续组合其他 `<verb><motion>` |
|
||||
| 删除示例 | `dh` | Normal | 删除光标左侧一个字符 |
|
||||
| 删除示例 | `d3w` | Normal | 删除 3 个词(按 `w` 的词移动定义) |
|
||||
| 删除示例 | `3dw` | Normal | 删除 1 个词,重复 3 次(语义是重复 operator;结果通常等价于 `d3w`,但属于不同组合方式) |
|
||||
| 删除示例 | `d^` | Normal | 删除从光标到行首第一个非空白字符的位置(含义由 `^` motion 决定) |
|
||||
| 删除示例 | `d2fe` | Normal | 删除到光标后第 2 个 `e`(包含该 `e`);`f` 是“到某字符并包含它” |
|
||||
| 删除示例 | `d2Ta` | Normal | 删除到光标前第 2 个 `a`(不包含该 `a`);`T` 是“到某字符之前” |
|
||||
| 删除示例(Seek 结合) | `dsfoos` | Normal | 使用 Seek 查找 `foo` 并选标签 `s`:删除当前光标与 Seek 跳转位置之间文本;Seek 总跳到匹配词开头:目标在光标后时会删到 `f`(可能不含 `oo`),目标在光标前时可能连 `foo` 三字母都被删掉。注意:录宏时不建议用 Seek(回放无法理解标签) |
|
||||
| 修改(删除后进入插入) | `c<motion>` | Normal → Insert | “change”:删除范围并立即进入 Insert;与 `d<motion>` 再进入插入相比更省键;也使 `.` 能完整重复“删除 + 插入” |
|
||||
| 行尾操作(按模型) | `d$` / `c$` | Normal / Normal → Insert | 删除/修改从光标到行尾;`$` 是到行尾的 motion |
|
||||
| 行尾操作(快捷) | `D` / `C` | Normal / Normal → Insert | `D` 等价 `d$`,`C` 等价 `c$` |
|
||||
| 行首方向(无单键反向快捷) | `d^` / `d0` | Normal | 用 `d^` 删到第一个非空白字符,或用 `d0` 删到第 1 列(无视空白) |
|
||||
| 整行操作(重复动词) | `dd` | Normal | 删除整行(“重复 verb”作为整行范围的特殊写法;motion 含义依赖 verb,算模型的一个“破例”) |
|
||||
| 整行操作(重复动词) | `cc` | Normal → Insert | 删除整行并进入 Insert,重写这一行 |
|
||||
| 整行计数 | `d3d` / `3dd` | Normal | 删除 3 行:两种写法都可;`3dd` 通常更好按 |
|
||||
| 单字符删除(按模型) | `dl` / `4dl` | Normal | `dl` 删除光标下字符(用 `l` 作为 motion);`4dl` 删除 4 个字符 |
|
||||
| 单字符删除(快捷) | `x` / `5x` | Normal | `x` 删除光标下 1 字符;可带 count |
|
||||
| 反向单字符删除 | `X` | Normal | 删除光标左侧字符;可带 count |
|
||||
| 单字符替换 | `r{char}` | Normal(短暂进入插入后立刻回 Normal) | 替换光标下字符为接下来输入的 1 个字符;`r` 可带 count(会把若干字符都替换为同一个字符) |
|
||||
| 合并行(删除换行) | `J` | Normal | Join Lines:合并当前行与下一行(删除行尾换行);可带 count;通常会“智能处理空白” |
|
||||
| 合并行(不改空白) | `gJ` | Normal | 合并行但不做空白规范化(更“原样”) |
|
||||
| 大小写:转大写范围 | `gU<motion>` | Normal | 把范围文本转为大写(这里 `gU` 是 verb) |
|
||||
| 大小写:转小写范围 | `gu<motion>` | Normal | 把范围文本转为小写 |
|
||||
| 大小写:反转单字符 | `~` | Normal | 反转光标下字符的大小写 |
|
||||
| 大小写:整行 | `gUU` / `guu` | Normal | 通过“重复动词”把整行转为大写/小写 |
|
||||
| 重复上次编辑 | `.` | Normal | dot repeat:重复上一次“verb 操作”(包括 `c` 的删除范围 + 插入内容) |
|
||||
| `.` 的计数细节 | `<count>.`(例:`2.`) | Normal | `.` 带 count 时不会简单“重复 N 次”,而是会替换被重复命令内部的 count;例:先 `3dd`,再 `2.` 会变为删除 2 行 |
|
||||
| 宏录制:开始 | `qq` | Normal | 开始录制宏;可录制导航、编辑、插入、搜索、甚至 `:` 命令序列;注意:不要在宏里用 Seek |
|
||||
| 宏录制:结束 | `q` | Normal | 停止录制并保存当前宏 |
|
||||
| 宏录制:追加 | `qQ` | Normal | 以追加方式继续录制到同一宏;需要确保光标位置使“拼接后的宏”逻辑成立 |
|
||||
| 宏回放(最近一次) | `Q` | Normal | 回放最近保存的录制宏;多个宏可用寄存器管理(寄存器章节待补) |
|
||||
| 撤销 | `u` | Normal | 撤销最近一次改动;一次“改动”可能很大(长时间未退出 Insert 时尤其明显) |
|
||||
| 重做 | `<C-r>` | Normal | 重做(redo)撤销的改动 |
|
||||
| Undo 历史分支(概念/建议) | `:help undo-branches` / `undotree` 插件 | Normal | Neovim 记录完整历史并支持类似“分支”的撤销树;少数复杂场景 `undotree` 很有帮助 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 速查表(LazyVim / Neovim)
|
||||
|
||||
### 6.1 句子/段落移动(Vim 原生 Motions)
|
||||
|
||||
| 目标 | 按键(Normal) | 含义/落点 | 计数 | 备注 |
|
||||
|---|---|---|---|---|
|
||||
| 下一句 | `)` | 跳到下一句(句末标点 `.?!` 后的空白之后的第一个字符) | `3)` | 也会在空行(段落边界)停下 |
|
||||
| 上一句/当前句首 | `(` | 跳到当前句开头/上一句 | `2(` | `(`/`)` 和“句子”强绑定 |
|
||||
| 下一段 | `}` | 跳到下一段(空行分隔的块) | `5}` | 写代码很常用 |
|
||||
| 上一段 | `{` | 跳到上一段 | `3{` | `{`/`}` 不是跳到花括号字符本身 |
|
||||
|
||||
### 6.2 Unimpaired 风格方括号导航(`[` / `]` 系列)
|
||||
|
||||
| 场景 | 按键 | 做什么 | 依赖/来源 | 重要备注/坑 |
|
||||
|---|---|---|---|---|
|
||||
| 打开提示菜单 | `[` 或 `]`(按一下停顿) | 弹出可用组合菜单 | LazyVim | 用来“记不住时查一下” |
|
||||
| 跳出括号块(到未匹配的括号) | `[{` `]}` `[( ](` `[< ]<` | 跳到上一/下一层的“括号边界”(像 jump out) | LazyVim 的 unimpaired 行为 | 不是找下一个字符;找字符用 `f{` / `F{` |
|
||||
| 跳到“包围我的那种括号”的边界 | `[%` / `]%` | 对当前所在的 `(){}<>[]` 自动识别并跳到开头/结尾 | LazyVim | `[[`/`]]` 不用于跳出 `[]`;跳出方括号常靠 `%`/`[%`/`]%` |
|
||||
|
||||
### 6.3 同文件引用跳转(符号引用)
|
||||
|
||||
| 场景 | 按键 | 做什么 | 依赖 | 备注 |
|
||||
|---|---|---|---|---|
|
||||
| 下一个引用 | `]]` | 跳到光标下变量/函数在同文件的下一处真实引用 | 通常 LSP | 比搜索更准;LazyVim 会高亮其他引用 |
|
||||
| 上一个引用 | `[[` | 跳到上一处真实引用 | 通常 LSP | `[[`/`]]` 被保留给“引用跳转”,不是“跳出方括号” |
|
||||
|
||||
### 6.4 按语言结构跳转(类/函数/方法)
|
||||
|
||||
| 目标 | 跳到开始 | 跳到结束(Shift) | 依赖 | 备注 |
|
||||
|---|---|---|---|---|
|
||||
| class/type | `[c` / `]c` | `[C` / `]C` | LSP/语法能力 | 质量取决于语言与 LSP 配置 |
|
||||
| function | `[f` / `]f` | `[F` / `]F` | LSP/语法能力 | `]F` 可能先跳到嵌套函数结尾(不是“跳出当前函数”) |
|
||||
| method | `[m` / `]m` | `[M` / `]M` | LSP/语法能力 | 同上 |
|
||||
|
||||
### 6.5 缩进层级跳转(Indent)
|
||||
|
||||
| 场景 | 按键 | 做什么 | 依赖/来源 | 适用 |
|
||||
|---|---|---|---|---|
|
||||
| 跳到当前缩进层顶部/底部 | `[i` / `]i` | 跳出当前缩进层(到该缩进引导线的顶/底) | `snacks.indent` | Python、HTML/JSX/Svelte 等 |
|
||||
|
||||
### 6.6 诊断(Diagnostics)、拼写、TODO
|
||||
|
||||
| 场景 | 上一个 | 下一个 | 备注 |
|
||||
|---|---|---|---|
|
||||
| 所有诊断(error/warn/hint) | `[d` | `]d` | 常用“跳到下一条波浪线/提示” |
|
||||
| 仅 error | `[e` | `]e` | 忽略 warning/hint |
|
||||
| 仅 warning | `[w` | `]w` | 只在警告间跳转 |
|
||||
| 拼写错误(spell) | `[s` | `]s` | 拼写不算 diagnostic;别指望 `]d` 去拼写波浪线 |
|
||||
| TODO/FIXME | `[t` | `]t` | 在注释标记间跳转 |
|
||||
|
||||
> 限制:诊断/某些跳转通常不能和动词组合(例如 `d[d` 不会“删到上一条诊断”)。
|
||||
|
||||
### 6.7 Git 修改块(Hunk)
|
||||
|
||||
| 场景 | 上一个 | 下一个 | 做什么 | 备注 |
|
||||
|---|---|---|---|---|
|
||||
| 跳转 git hunk | `[h` | `]h` | 在未暂存/未提交的改动块间跳转 | 同样一般不能和动词组合 |
|
||||
|
||||
### 6.8 文本对象(Text Objects)与 Operator-Pending 语法
|
||||
|
||||
#### 6.8.1 基本语法(最重要)
|
||||
|
||||
| 语法 | 解释 | 例子 |
|
||||
|---|---|---|
|
||||
| `<verb><a/i><object>` | 动词 + 语境 + 对象 | `di(`、`daw`、`cip`、`yig` |
|
||||
| `i`(inside) | 只作用于对象内部 | `di(` 删除括号内,保留括号 |
|
||||
| `a`(around) | 作用于对象及其边界/相关空白 | `da(` 删除括号+内容;`daw` 会顺带处理空格更自然 |
|
||||
|
||||
#### 6.8.2 文本类对象(word/sentence/paragraph)
|
||||
|
||||
| 对象 | `i`(inside)例 | `a`(around)例 | 差异要点 |
|
||||
|---|---|---|---|
|
||||
| word | `diw` | `daw` | `a` 往往会吃掉一侧空白,删除后更不留多余空格 |
|
||||
| WORD(空白分隔) | `diW` | `daW` | 不把标点当边界 |
|
||||
| sentence | `dis` | `das` | `a` 更会“对齐”句子周围空白 |
|
||||
| paragraph | `dip` | `dap` | `a` 往往会连多余空行一起处理 |
|
||||
|
||||
#### 6.8.3 引号/括号对象
|
||||
|
||||
| 目标 | inside(保留边界) | around(含边界) | 备注 |
|
||||
|---|---|---|---|
|
||||
| 双引号 | `ci"` / `di"` | `ca"` / `da"` | `c` 会进入插入模式 |
|
||||
| 单引号 | `ci'` | `da'` | 同理 |
|
||||
| 反引号 | ``ci` `` | ``da` `` | 同理 |
|
||||
| 任意最近引号 | `ciq` / `diq` | `caq` / `daq` | `q` 会自动判断 `"'`` 哪个最近 |
|
||||
| 圆括号 | `di(` | `da(` | 也可用于 `)` 作为对象字符 |
|
||||
| 花括号 | `di{` | `da{` | 同理 |
|
||||
| 方括号 | `di[` | `da[` | 同理 |
|
||||
| 尖括号 | `di<` | `da<` | 常用于泛型/标签等 |
|
||||
|
||||
#### 6.8.4 “最近的包围括号”快捷对象
|
||||
|
||||
| 对象 | 含义 | 例子 |
|
||||
|---|---|---|
|
||||
| `b` | bracket:最近的包围对(括号类) | `dib` / `cab` |
|
||||
|
||||
#### 6.8.5 计数:第 N 层包围(count 放在 `a/i` 前)
|
||||
|
||||
| 写法 | 含义 | 例子 |
|
||||
|---|---|---|
|
||||
| `d2a{` | 对第二层外侧的 `{…}` 执行删除(含花括号) | 光标在深层对象内,删外层 block |
|
||||
| `c3i(` | 改第三层外侧 `(…)` 的内部(保留括号) | 复杂嵌套时用 |
|
||||
|
||||
#### 6.8.6 整个文件(buffer)对象
|
||||
|
||||
| 目标 | 按键 | 含义 |
|
||||
|---|---|---|
|
||||
| entire buffer(inside) | `yig` | 复制整个文件内容 |
|
||||
| entire buffer(around) | `cag` / `dag` | 作用于整个 buffer(常用 `cag` 直接清空重写) |
|
||||
|
||||
#### 6.8.7 语言结构类文本对象(LazyVim 扩展)
|
||||
|
||||
| 对象字母 | 含义 | 示例(动词+对象) |
|
||||
|---|---|---|
|
||||
| `c` | class/type | `dac` / `cic` |
|
||||
| `f` | function/method | `yaf` / `dif` |
|
||||
| `o` | object(block/loop/conditional 等) | `cao` / `dio` |
|
||||
| `t` | tag(HTML/JSX) | `dat` / `cit` |
|
||||
| `i` | scope(缩进层级) | `dai` / `cii` |
|
||||
|
||||
#### 6.8.8 Git hunk 文本对象
|
||||
|
||||
| 对象 | 用法 | 含义 |
|
||||
|---|---|---|
|
||||
| `h` | `dih` | 对整个 git hunk 执行操作(例如删除该改动块) |
|
||||
|
||||
#### 6.8.9 “附近对象”扩展(mini.ai):Next / Last
|
||||
|
||||
| 前缀 | 含义 | 示例 | 作用 |
|
||||
|---|---|---|---|
|
||||
| `n` | next | `cin{` | 不必先把光标移入对象,直接操作“下一个 `{}` 对象内部” |
|
||||
| `l` | last | `dil"` | 操作“上一个”对象(靠近光标) |
|
||||
|
||||
### 6.9 flash.nvim:S / R / r(对象选择)
|
||||
|
||||
| 功能 | 按键形态 | 做什么 | 备注 |
|
||||
|---|---|---|---|
|
||||
| 就地选“周围对象” | `<verb>S` | 给光标周围结构打成对标签,选中后对标签之间范围操作 | 不需要 `a/i` |
|
||||
| 远程选“周围对象” | `<verb>R` | 先远程定位匹配,再切到“周围对象成对标签”选择范围 | R = Remote(大写是 surround 对象模式) |
|
||||
| 远程定位后继续选任意对象 | `<verb>r` | 远程 Seek 到某标签后回到 operator-pending,再输入如 `aw`/`i(` 等;完成后光标回原位 | 小写 r = Remote(普通 seek) |
|
||||
|
||||
### 6.10 mini.surround(可选 Extra):包围符/标签的增删改
|
||||
|
||||
> 说明:`mini.surround` 常作为 LazyVim 推荐 Extra;未必默认安装。
|
||||
|
||||
#### 6.10.1 添加包围(Add)
|
||||
|
||||
| 目标 | 按键 | 说明 | 例子效果 |
|
||||
|---|---|---|---|
|
||||
| 添加包围 | `gsa` +(motion/对象)+(包围字符) | 先选范围,再输入要包围的字符 | `gsa$"`:从光标到行尾加 `""` |
|
||||
| `(` vs `)` | 作为包围字符时 | `(` 会在内部加空格;`)` 不加 | `[foo]` 经 `gsai[(` → `[( foo )]`;经 `gsai[)` → `[(foo)]` |
|
||||
|
||||
#### 6.10.2 删除包围(Delete)
|
||||
|
||||
| 目标 | 按键 | 说明 |
|
||||
|---|---|---|
|
||||
| 删除某种包围对 | `gsd` + 字符 | `gsd[` 删除当前所在 `[]` |
|
||||
| 删除第 N 层外侧 | `<count>gsd` + 字符 | `2gsd{` 删除第二层外侧 `{}` |
|
||||
|
||||
#### 6.10.3 替换包围(Replace)
|
||||
|
||||
| 目标 | 按键 | 例子 |
|
||||
|---|---|---|
|
||||
| 替换包围符 | `gsr` + 旧 + 新 | `gsr"'`:`"hello"` → `'hello'` |
|
||||
|
||||
#### 6.10.4 仅跳转/查看包围边界
|
||||
|
||||
| 功能 | 按键 | 说明 |
|
||||
|---|---|---|
|
||||
| 括号匹配跳转 | `%` | 在括号端点上跳到匹配端;不支持引号类 |
|
||||
| 跳到最近左/右包围符 | `g[` + 字符 / `g]` + 字符 | 例:`g[(`、`g]]`;可加 count 跳多层 |
|
||||
| 高亮包围(检查用) | `gsh` + 字符 | 例:`gsh(` 用于“干跑”确认层级 |
|
||||
|
||||
#### 6.10.5 HTML/XML Tag 包围(Bonus)
|
||||
|
||||
| 目标 | 按键 | 说明 |
|
||||
|---|---|---|
|
||||
| 段落外包标签 | `gsaapt` | `ap` 选段落,`t` 表示 tag;随后输入标签名(如 `p`),可带属性 |
|
||||
|
||||
---
|
||||
|
||||
## 7. Buffers 与布局(Buffers and Layouts)
|
||||
|
||||
### 7.1 概念速查(一定先分清)
|
||||
|
||||
| 概念 | Vim/Neovim 的含义 | 你可能误以为 | 关键点/坑 |
|
||||
|---|---|---|---|
|
||||
| Server | Neovim 可作为“服务端”,允许多个客户端连接同一实例 | 不常见概念 | 一般不用管;但可做到连接已有 nvim 实例而不是新开 |
|
||||
| Client | 你运行的 Neovim 程序(终端 `nvim`、或 Neovide/VimR 等 GUI) | “就是 Neovim” | 一个 client 通常连自己的 server,也可连已有/远程 |
|
||||
| Tab | 一套“全屏布局”(更像 Layout/Workspace) | VS Code 的 tab 条 | Tab 之间布局可不同;一次只显示一个 tab;所有 tab 共享 buffers |
|
||||
| Window | 分屏/窗格/Pane/Split(屏幕区域) | OS 窗口 | 一个 window 显示一个 buffer 的“视图”;浮窗是例外(picker 等) |
|
||||
| Buffer | 已打开的文件内容实例(内存中的编辑对象) | Tab | 同一文件只有一个底层 buffer;可在多个 window/tab 同时显示 |
|
||||
| Fold | 折叠:把一段代码收成一行隐藏起来 | “缩进/大纲” | 只影响视图显示;可嵌套折叠 |
|
||||
| File | 磁盘上的文件 | Buffer | buffer 未保存时内容可与磁盘不一致;也可有无文件 buffer(scratch) |
|
||||
|
||||
### 7.2 Buffer(缓冲区)速查
|
||||
|
||||
#### 7.2.1 切换 Buffer
|
||||
|
||||
| 操作 | 快捷键 | 说明/记忆法 |
|
||||
|---|---|---|
|
||||
| 下一个/上一个 buffer(按 bufferline 顺序) | `L` / `H` | Shift-l/right,Shift-h/left |
|
||||
| 下一个/上一个 buffer(同上) | `]b` / `[b` | 方括号系列 |
|
||||
| 当前文件 ↔ 当前窗口最近的另一个文件(alternate file) | `<Space><Backtick>` | 快速来回切两个文件 |
|
||||
| 用列表过滤选择已打开 buffers | `<Space><comma>` | buffer picker:适合 buffer 很多时 |
|
||||
|
||||
#### 7.2.2 关闭 Buffer(不删磁盘文件)
|
||||
|
||||
| 操作 | 快捷键 | 说明/记忆法 |
|
||||
|---|---|---|
|
||||
| 关闭当前 buffer(保留分屏) | `<Space>bd` | b=buffer 子菜单,d=delete(删的是 buffer) |
|
||||
| 关闭当前 buffer + 关闭所在分屏 | `<Space>bD` | D 更大力度 |
|
||||
| 关闭左侧所有 buffers | `<Space>bl` | left |
|
||||
| 关闭右侧所有 buffers | `<Space>br` | right |
|
||||
| 只保留当前 buffer,其他全关 | `<Space>bo` | only |
|
||||
| 删除所有未 pin 的 buffers | `<Space>bP` | 批量清理 |
|
||||
| pin/取消 pin 当前 buffer | `<Space>bp` | 防止被 `<Space>bP` 清掉 |
|
||||
| 在 buffer picker 中关闭光标所在项 | `<C-x>` | 仅在 `<Space><comma>` 列表里 |
|
||||
|
||||
#### 7.2.3 Scratch Buffer(临时笔记)
|
||||
|
||||
| 操作 | 快捷键 | 说明 |
|
||||
|---|---|---|
|
||||
| 打开/回到当前 cwd 的 scratch | `<Space>..` | 按工作目录(cwd)绑定;重开 nvim 也还在 |
|
||||
| 关闭 scratch 浮窗 | `q` | 需在 Normal 模式(通常先 `<Escape>`) |
|
||||
| 列出所有 scratch(可选不同 cwd/分支) | `<Space>S` | picker 列表 |
|
||||
|
||||
### 7.3 Window(分屏)速查
|
||||
|
||||
#### 7.3.1 Window 子菜单入口
|
||||
|
||||
| 操作 | 快捷键 | 说明 |
|
||||
|---|---|---|
|
||||
| 打开 window 菜单 | `<Space>w` | LazyVim 统一入口 |
|
||||
| 传统入口 | `<C-w>` | Vim 默认体系;LazyVim 也增强了它 |
|
||||
|
||||
#### 7.3.2 创建分屏
|
||||
|
||||
| 操作 | 快捷键 | 说明/记忆法 |
|
||||
|---|---|---|
|
||||
| 垂直分屏(左右) | `<Space>wv` | v=vertical |
|
||||
| 水平分屏(上下) | `<Space>ws` | s=split |
|
||||
| 垂直分屏(替代键) | `<Space>|` | `|` = Shift-Backslash |
|
||||
| 水平分屏(替代键) | `<Space>-` | `-` 像横线 |
|
||||
|
||||
#### 7.3.3 打开文件时直接分屏(Explorer/Picker)
|
||||
|
||||
| 场景 | 快捷键 | 结果 |
|
||||
|---|---|---|
|
||||
| Snacks explorer 打开文件 | `<Enter>` | 当前窗口打开 |
|
||||
| Snacks explorer 垂直分屏打开 | `<C-v>` | 右侧/新列打开 |
|
||||
| Snacks explorer 水平分屏打开 | `<C-s>` | 下方/新行打开 |
|
||||
| Snacks 各种 picker | `<C-v>` / `<C-s>` | 同样可用 |
|
||||
| mini.files 打开到分屏 | `<Space>wv` / `<Space>ws` | 用“正常窗口分屏键”完成 |
|
||||
|
||||
#### 7.3.4 在窗口间移动
|
||||
|
||||
| 操作 | 快捷键 | 说明 |
|
||||
|---|---|---|
|
||||
| 向左/下/上/右窗口移动 | `<C-h>` / `<C-j>` / `<C-k>` / `<C-l>` | 支持 count,可跨过窗口 |
|
||||
| 同上(which-key 风格) | `<Space>wh/wj/wk/wl` | 先 `<Space>w` 再方向 |
|
||||
|
||||
#### 7.3.5 关闭窗口(只关分屏,不关 buffer)
|
||||
|
||||
| 操作 | 快捷键 | 行为差异 |
|
||||
|---|---|---|
|
||||
| 关闭窗口;若是唯一窗口则退出 Neovim | `<Space>wq` | q=quit |
|
||||
| 关闭窗口;若是唯一窗口则拒绝并报错 | `<Space>wc` | c=close |
|
||||
| 删除窗口(与 wc 实质相同) | `<Space>wd` | d=delete(对称 `<Space>bd`) |
|
||||
| 只保留当前窗口,关闭其他分屏 | `<Space>wo` | only window |
|
||||
|
||||
#### 7.3.6 调整窗口大小
|
||||
|
||||
| 操作 | 快捷键 | 说明 |
|
||||
|---|---|---|
|
||||
| 增加/减少高度(水平分屏) | `<Space>w+` / `<Space>w-` | 每次 1 行;常配合 count |
|
||||
| 增加/减少宽度(垂直分屏) | `<Space>w>` / `<Space>w<` | 每次 1 列;常配合 count |
|
||||
| 所有窗口等宽等高 | `<Space>w=` | 均分布局 |
|
||||
|
||||
#### 7.3.7 Hydra(窗口命令连发)
|
||||
|
||||
| 操作 | 快捷键 | 说明 |
|
||||
|---|---|---|
|
||||
| 进入 window Hydra 模式 | `<Space>w<Space>` | 固定窗口菜单,可连续按多条命令 |
|
||||
| 退出 Hydra | `<Escape>` | 回普通编辑 |
|
||||
|
||||
#### 7.3.8 Zen / Zoom
|
||||
|
||||
| 模式 | 快捷键 | 作用 |
|
||||
|---|---|---|
|
||||
| Zen mode | `<Space>uz` | 中央专注窗口、背景变暗、只在光标附近保留高亮(snacks.nvim) |
|
||||
| Zoom mode | `<Space>uZ` | 临时只显示当前窗口最大化 |
|
||||
|
||||
### 7.4 Tab(标签页/布局)速查
|
||||
|
||||
| 操作 | 快捷键 | 说明 |
|
||||
|---|---|---|
|
||||
| 打开 Tab 菜单 | `<Space><Tab>` | LazyVim tab 子菜单 |
|
||||
| 新建 tab | `<Space><Tab><Tab>` | 连按两次 Tab(第二次是动作) |
|
||||
| 把当前 split “移到”新 tab | `<Space>wT` | T 大写;当前窗口在原 tab 消失,新 tab 里出现 |
|
||||
| 下一个/上一个 tab(Vim 默认) | `gt` / `gT` | tab 导航 |
|
||||
| 切换 tab(LazyVim) | `<Space><Tab>]` / `<Space><Tab>[` | 右 / 左 |
|
||||
| 跳到第 N 个 tab | `Ngt` | 例:`3gt` 去 tab 3 |
|
||||
| 关闭当前 tab(方式 1) | 关闭该 tab 最后一个窗口(如 `<Space>wq`) | tab 自动消失 |
|
||||
| 关闭 tab(方式 2) | `<Space><Tab>d` | 关 tab 的所有窗口 + tab;buffers 仍保留 |
|
||||
| 关闭 tab(方式 3) | 点击 tab 区域右侧 `X` | bufferline 右侧数字旁 |
|
||||
|
||||
> 位置提示:tab 编号显示在 bufferline 最右侧;左侧那些“像标签页”的是 buffers,不是 tabs。
|
||||
|
||||
### 7.5 Folding(代码折叠,`z` 系列)
|
||||
|
||||
| 操作 | 快捷键 | 说明/记忆 |
|
||||
|---|---|---|
|
||||
| 折叠当前区域 | `zc` | c=collapse |
|
||||
| 打开当前折叠 | `zo` | o=open |
|
||||
| 折叠/打开切换 | `za` | a=toggle |
|
||||
| 打开所有折叠 | `zR` | 全展开 |
|
||||
| 递归打开(含嵌套) | `zO` | O=更强力的 open |
|
||||
|
||||
### 7.6 Session(会话,恢复现场)
|
||||
|
||||
| 操作 | 快捷键/流程 | 说明 |
|
||||
|---|---|---|
|
||||
| 退出并保存会话 | `<Space>qq` | 默认启用 session;退出即记录 |
|
||||
| 从 dashboard 恢复 | 打开 `nvim` 后按 `s` | 回到上次关闭时的 buffers/tabs/splits |
|
||||
| dashboard 不在时恢复 | `<Space>qs` | 恢复到上次退出时状态 |
|
||||
| 选择最近项目并恢复会话 | `<Space>qS` | picker:选目录后自动 `:cd` 并加载对应 session |
|
||||
| 本次不更新/不覆盖 session | `<Space>qd` | 临时打开 nvim 时防止覆盖旧 session |
|
||||
| 会话作用域 | 按 cwd(目录) | 进入项目前先 `cd`,或在 nvim 里 `:cd` |
|
||||
|
||||
---
|
||||
|
||||
## 8. 附录
|
||||
|
||||
### 8.1 普通 Vim 示意图
|
||||
|
||||

|
||||
@@ -0,0 +1,185 @@
|
||||
# 安装 PowerShell
|
||||
|
||||
官方安装教程
|
||||
|
||||
https://learn.microsoft.com/zh-cn/powershell/scripting/install/installing-powershell?view=powershell-7.5
|
||||
|
||||
查找 PowerShell 版本
|
||||
|
||||
```PowerShell
|
||||
winget search Microsoft.PowerShell
|
||||
```
|
||||
|
||||
```Output
|
||||
Name Id Version Source
|
||||
---------------------------------------------------------------
|
||||
PowerShell Microsoft.PowerShell 7.5.1.0 winget
|
||||
PowerShell Preview Microsoft.PowerShell.Preview 7.6.0.4 winget
|
||||
```
|
||||
|
||||
进行安装
|
||||
|
||||
```PowerShell
|
||||
winget install --id Microsoft.PowerShell --source winget
|
||||
```
|
||||
|
||||
```PowerShell
|
||||
winget install --id Microsoft.PowerShell.Preview --source winget
|
||||
```
|
||||
|
||||
更新操作
|
||||
|
||||
```PowerShell
|
||||
winget upgrade Microsoft.PowerShell
|
||||
```
|
||||
|
||||
## 配置 PowerShell
|
||||
|
||||
首次在系统上安装 PowerShell 时,配置文件脚本文件和它们所属的目录不存在。 以下命令创建“当前用户,当前主机”配置文件脚本文件(如果不存在)。
|
||||
|
||||
```PowerShell
|
||||
if (!(Test-Path $PROFILE)) { New-Item -Type File -Path $PROFILE -Force }
|
||||
```
|
||||
|
||||
添加个性化设置
|
||||
|
||||
```ps1
|
||||
function desk { Set-Location "C:\Users\docke\Desktop" }
|
||||
function gitl { git log --oneline --graph --decorate }
|
||||
function ep { code $PROFILE }
|
||||
function hosts { notepad C:\Windows\System32\drivers\etc\hosts }
|
||||
function vim { nvim $args }
|
||||
|
||||
Set-PSReadLineOption -PredictionSource History, Plugin
|
||||
Set-PSReadLineOption -PredictionViewStyle ListView
|
||||
Set-PSReadLineOption -EditMode Windows
|
||||
Set-PSReadLineKeyHandler -Key Tab -Function MenuComplete
|
||||
```
|
||||
|
||||
# 安装 Windows 终端
|
||||
|
||||
官方安装教程
|
||||
|
||||
https://learn.microsoft.com/zh-cn/windows/terminal/install
|
||||
|
||||
根据页面自行定制化设置即可,需确认好终端已将前边最新 PowerShell 设置为默认值。
|
||||
|
||||
# 安装 Nerd Fonts 字体
|
||||
|
||||
官网: https://www.nerdfonts.com/
|
||||
|
||||
Nerd Fonts 是一个为开发者量身定制的字体资源网站,通过将编程字体与图标字体结合,提供了一种功能强大且美观的方式来优化开发环境。无论是提升终端的视觉效果,还是增强代码的可读性和个性化,它都是一个非常有价值的工具。如果你是程序员或终端用户,这个网站值得一试。
|
||||
|
||||
其中我个人比较喜欢使用 JetBrainsMono Nerd Font。
|
||||
|
||||
# 安装 Oh My Posh
|
||||
|
||||
官方安装教程
|
||||
|
||||
https://ohmyposh.dev/
|
||||
|
||||
推荐 winget 安装。
|
||||
|
||||
安装后在 PowerShell 配置文件中增加启动项,这里使用了自带的 jandedobbeleer 主题,这也是作者自己的主题。
|
||||
|
||||
```ps1
|
||||
oh-my-posh init pwsh --config "$env:POSH_THEMES_PATH/jandedobbeleer.omp.json" | Invoke-Expression
|
||||
```
|
||||
|
||||
创建或修改 `$PROFILE` 文件后,需要重载它以应用更改。运行以下命令:
|
||||
|
||||
```PowerShell
|
||||
. $PROFILE
|
||||
```
|
||||
|
||||
Oh My Posh 同样支持使用远程配置(但个人实测会有卡顿),本地配置会更加流畅。
|
||||
|
||||
## 个人配置
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json",
|
||||
"console_title_template": "{{ .Shell }} in {{ .Folder }}",
|
||||
"final_space": true,
|
||||
"version": 3,
|
||||
"transient_prompt": {
|
||||
"background": "transparent",
|
||||
"foreground": "#ffffff",
|
||||
"template": "{{ .Shell }}> "
|
||||
},
|
||||
"blocks": [
|
||||
{
|
||||
"type": "prompt",
|
||||
"alignment": "left",
|
||||
"segments": [
|
||||
{
|
||||
"type": "path",
|
||||
"style": "diamond",
|
||||
"leading_diamond": "\ue0b6",
|
||||
"trailing_diamond": "\ue0b0",
|
||||
"foreground": "#ffffff",
|
||||
"background": "#ff479c",
|
||||
"properties": {
|
||||
"folder_separator_icon": " \ue0b1 ",
|
||||
"home_icon": "~",
|
||||
"style": "unique"
|
||||
},
|
||||
"template": " \uea83 {{ .Path }} "
|
||||
},
|
||||
{
|
||||
"type": "executiontime",
|
||||
"style": "plain",
|
||||
"foreground": "#ffffff",
|
||||
"background": "#83769c",
|
||||
"properties": {
|
||||
"always_enabled": true
|
||||
},
|
||||
"template": "<transparent>\ue0b0</> \ueba2 {{ .FormattedMs }}\u2800"
|
||||
},
|
||||
{
|
||||
"type": "status",
|
||||
"style": "diamond",
|
||||
"trailing_diamond": "\ue0b4",
|
||||
"foreground": "#ffffff",
|
||||
"background": "#00897b",
|
||||
"background_templates": ["{{ if gt .Code 0 }}#e91e63{{ end }}"],
|
||||
"properties": {
|
||||
"always_enabled": true
|
||||
},
|
||||
"template": "<parentBackground>\ue0b0</> \ue23a "
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "rprompt",
|
||||
"segments": [
|
||||
{
|
||||
"type": "sysinfo",
|
||||
"style": "plain",
|
||||
"foreground": "#ffffff",
|
||||
"template": "\uefc5 {{ round .PhysicalPercentUsed .Precision}}%"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
# 安装 Scoop
|
||||
|
||||
Scoop 是一款适用于 Windows 的命令行包管理器,类似于 Linux 上的 apt 或 macOS 上的 Homebrew。它可以帮助用户快速安装和管理软件,尤其适合开发者或喜欢命令行操作的用户。
|
||||
|
||||
主要参考此仓库教程: https://github.com/ScoopInstaller/Install
|
||||
|
||||
进行高级安装,可以下载安装程序并手动执行它,并附带参数。
|
||||
|
||||
```PowerShell
|
||||
irm get.scoop.sh -outfile 'install.ps1'
|
||||
```
|
||||
|
||||
可以将 Scoop 安装到自定义目录,配置 Scoop 将全局程序安装到自定义目录,并在安装过程中绕过系统代理。
|
||||
|
||||
```powershell
|
||||
.\install.ps1 -ScoopDir 'D:\Applications\Scoop' -ScoopGlobalDir 'F:\GlobalScoopApps' -NoProxy
|
||||
```
|
||||
@@ -0,0 +1,568 @@
|
||||
# Hugo 简介
|
||||
|
||||
Hugo 是一个开源的静态站点生成器,支持通过 Markdown 文件快速生成静态 HTML 页面。其主要优势包括:
|
||||
|
||||
1. **构建速度快**:Hugo 采用 Go 语言开发,单线程构建速度极快,适合处理大规模内容。
|
||||
2. **灵活性强**:支持多种主题和模块化设计,用户可根据需求定制站点外观与功能。
|
||||
3. **易于部署**:生成的静态文件可直接托管于任意 Web 服务器,无需复杂的后端支持。
|
||||
4. **学术友好性**:Hugo 支持 Markdown 格式,与学术写作常用的编辑工具(如 Obsidian)无缝衔接,便于内容管理和版本控制。
|
||||
|
||||
# 官网导航
|
||||
|
||||
[官方网站](https://gohugo.io/)
|
||||
|
||||
[官方论坛](https://discourse.gohugo.io/)
|
||||
|
||||
[中文官网](https://hugo.opendocs.io/)
|
||||
|
||||
# 流程概览
|
||||
|
||||
Obsidian (创作) → Hugo (本地预览) → Git (推送至 GitHub) → GitHub Actions (自动编译部署) → Nginx (静态服务) → Cloudflare (全球加速与HTTPS) → 全球用户访问
|
||||
|
||||
# 站点初始化
|
||||
|
||||
```shell
|
||||
# 创建一个新的 Hugo 站点,命名为 404-blog
|
||||
hugo new site 404-blog
|
||||
|
||||
# 进入新创建的站点目录
|
||||
cd 404-blog
|
||||
|
||||
# 初始化 Git 仓库,用于版本管理和代码托管
|
||||
git init
|
||||
# 设置 Git 的提交用户信息
|
||||
git config user.name "404"
|
||||
git config user.email "404@example.com"
|
||||
# 暂存所有文件,准备提交
|
||||
git add .
|
||||
# 提交更改,记录初始化的站点结构
|
||||
git commit -m "Initial commit"
|
||||
|
||||
# 添加 Hugo PaperMod 主题作为 Git 子模块,方便管理和更新主题
|
||||
git submodule add https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod
|
||||
# 在配置文件 hugo.toml 中设置主题为 PaperMod
|
||||
echo "theme = 'PaperMod'" >> hugo.toml
|
||||
|
||||
# (此处手动添加 .gitignore 文件,用于忽略不必要的文件,如 node_modules 或临时文件)
|
||||
|
||||
# 暂存所有更改,包括主题和 .gitignore 文件
|
||||
git add .
|
||||
# 提交更改,记录主题和忽略文件的添加
|
||||
git commit -m "Add PaperMod theme and .gitignore file"
|
||||
|
||||
# 启动 Hugo 本地服务器,预览站点效果
|
||||
hugo server
|
||||
```
|
||||
|
||||
其中 `.gitignore` 可参考 `PaperMod` 作者提供的文件。
|
||||
|
||||
```
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
|
||||
/public
|
||||
.DS_Store
|
||||
.hugo_build.lock
|
||||
resources/_gen/
|
||||
```
|
||||
|
||||
# 自动化部署与服务器配置
|
||||
|
||||
要实现每次推送到 GitHub 仓库时,自动构建 Hugo 博客并部署到云服务器的 Nginx 下,需要完成以下步骤:
|
||||
|
||||
## 1. 准备云服务器
|
||||
|
||||
首先,确保您的云服务器已安装 Nginx:
|
||||
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo apt update && sudo apt full-upgrade -y
|
||||
sudo apt install nginx
|
||||
```
|
||||
|
||||
## 2. 配置 Nginx
|
||||
|
||||
修改 Nginx 主配置文件:
|
||||
|
||||
```nginx
|
||||
# --- 基本运行环境配置 ---
|
||||
user www-data; # 指定 Nginx 运行的用户,确保权限安全
|
||||
worker_processes auto; # 自动匹配 CPU 核心数,优化并发处理
|
||||
worker_cpu_affinity auto; # 自动绑定 CPU 核心,提升缓存命中率
|
||||
pid /run/nginx.pid; # 定义主进程 ID 文件路径
|
||||
error_log /var/log/nginx/error.log warn; # 设置错误日志路径及警告级别
|
||||
include /etc/nginx/modules-enabled/*.conf; # 引入额外的模块配置文件
|
||||
|
||||
# --- 事件处理模块配置 ---
|
||||
events {
|
||||
worker_connections 1024; # 每个进程最大连接数,适配中型流量
|
||||
multi_accept on; # 启用多连接同时接受,提升并发效率
|
||||
use epoll; # 使用 epoll 事件模型,优化高并发性能
|
||||
}
|
||||
|
||||
# --- HTTP 服务核心配置 ---
|
||||
http {
|
||||
# 性能优化参数
|
||||
sendfile on; # 启用高效文件传输,适合静态文件
|
||||
tcp_nopush on; # 优化数据包传输,减少报文数量
|
||||
tcp_nodelay on; # 禁用 Nagle 算法,降低传输延迟
|
||||
types_hash_max_size 2048; # 优化 MIME 类型哈希表大小
|
||||
server_tokens off; # 隐藏 Nginx 版本信息,增强安全性
|
||||
|
||||
server_names_hash_bucket_size 64; # 域名哈希桶大小,支持长域名解析
|
||||
|
||||
# MIME 类型定义
|
||||
include /etc/nginx/mime.types; # 引入标准 MIME 类型配置
|
||||
default_type application/octet-stream; # 默认文件类型为二进制流
|
||||
|
||||
# SSL/TLS 安全优化
|
||||
ssl_protocols TLSv1.2 TLSv1.3; # 启用安全协议,优先 TLS 1.3
|
||||
ssl_prefer_server_ciphers on; # 优先使用服务器指定的加密套件
|
||||
ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH; # 高安全加密套件
|
||||
ssl_session_timeout 1d; # SSL 会话缓存有效期,减少握手开销
|
||||
ssl_session_cache shared:SSL:10m; # 共享 SSL 会话缓存,适配中型流量
|
||||
ssl_session_tickets off; # 禁用会话票据,增强安全性
|
||||
ssl_stapling on; # 启用 OCSP 装订,加速证书验证
|
||||
ssl_stapling_verify on; # 验证 OCSP 响应,确保安全
|
||||
resolver 8.8.8.8 8.8.4.4 valid=300s; # 指定 DNS 服务器,用于 OCSP 查询
|
||||
resolver_timeout 5s; # 设置 DNS 解析超时时间
|
||||
|
||||
# 日志记录配置
|
||||
log_format main # 定义标准日志格式,记录请求详情
|
||||
'$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
access_log /var/log/nginx/access.log main buffer=32k flush=5s; # 访问日志,优化写入性能
|
||||
|
||||
# Gzip 压缩优化
|
||||
gzip on; # 启用内容压缩,减少传输数据量
|
||||
gzip_vary on; # 添加 Vary 头,适配代理缓存
|
||||
gzip_proxied any; # 对所有代理请求启用压缩
|
||||
gzip_comp_level 6; # 压缩级别 6,平衡性能与效果
|
||||
gzip_buffers 16 8k; # 设置压缩缓冲区,优化内存使用
|
||||
gzip_http_version 1.1; # 最低支持 HTTP 1.1 进行压缩
|
||||
gzip_min_length 256; # 最小压缩文件长度,避免小文件开销
|
||||
gzip_types text/plain # 定义支持压缩的文件类型
|
||||
text/css
|
||||
application/json
|
||||
application/javascript
|
||||
text/xml
|
||||
application/xml
|
||||
application/xml+rss
|
||||
text/javascript
|
||||
application/x-font-ttf
|
||||
font/opentype
|
||||
image/svg+xml;
|
||||
|
||||
# 客户端请求限制
|
||||
client_max_body_size 10m; # 限制请求体大小,适配静态站点
|
||||
client_body_buffer_size 128k; # 请求体缓冲区,优化上传性能
|
||||
|
||||
# 文件缓存优化
|
||||
open_file_cache max=2000 inactive=20s; # 缓存文件句柄,加速静态文件访问
|
||||
open_file_cache_valid 30s; # 文件缓存有效性检查周期
|
||||
open_file_cache_min_uses 2; # 文件至少访问 2 次才缓存
|
||||
open_file_cache_errors on; # 缓存错误信息,减少重复检查
|
||||
|
||||
# Cloudflare 真实 IP 获取
|
||||
set_real_ip_from 173.245.48.0/20; # Cloudflare IP 范围,用于获取真实 IP
|
||||
set_real_ip_from 103.21.244.0/22;
|
||||
set_real_ip_from 103.22.200.0/22;
|
||||
set_real_ip_from 103.31.4.0/22;
|
||||
set_real_ip_from 141.101.64.0/18;
|
||||
set_real_ip_from 108.162.192.0/18;
|
||||
set_real_ip_from 190.93.240.0/20;
|
||||
set_real_ip_from 188.114.96.0/20;
|
||||
set_real_ip_from 197.234.240.0/22;
|
||||
set_real_ip_from 198.41.128.0/17;
|
||||
set_real_ip_from 162.158.0.0/15;
|
||||
set_real_ip_from 104.16.0.0/13;
|
||||
set_real_ip_from 104.24.0.0/14;
|
||||
set_real_ip_from 172.64.0.0/13;
|
||||
set_real_ip_from 131.0.72.0/22;
|
||||
real_ip_header CF-Connecting-IP; # 使用 Cloudflare 传递的真实客户端 IP
|
||||
|
||||
# 引入其他配置文件
|
||||
include /etc/nginx/conf.d/*.conf; # 加载额外的配置目录
|
||||
include /etc/nginx/sites-enabled/*; # 加载启用的站点配置文件
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
创建一个站点配置文件:
|
||||
|
||||
```bash
|
||||
sudo vim /etc/nginx/sites-available/404-blog
|
||||
```
|
||||
|
||||
添加以下配置(根据需要调整):
|
||||
|
||||
```nginx
|
||||
# --- 非 www 域名 HTTP 重定向配置 ---
|
||||
server {
|
||||
listen 80; # 监听 HTTP 80 端口
|
||||
server_name 404blog.org; # 匹配非 www 域名
|
||||
|
||||
access_log /var/log/nginx/404blog_redirect_access.log
|
||||
main
|
||||
buffer=16k; # 访问日志记录,设置缓冲
|
||||
error_log /var/log/nginx/404blog_redirect_error.log warn; # 错误日志记录,警告级别
|
||||
|
||||
return 301 https://www.404blog.org$request_uri; # 永久重定向到 HTTPS 的 www 域名
|
||||
}
|
||||
|
||||
# --- 非 www 域名 HTTPS 重定向配置 ---
|
||||
server {
|
||||
listen 443 ssl; # 监听 HTTPS 443 端口并启用 SSL
|
||||
http2 on; # 启用 HTTP/2 协议,提升性能
|
||||
server_name 404blog.org; # 匹配非 www 域名
|
||||
|
||||
include /etc/nginx/snippets/ssl-404blog.conf; # 引入预配置的 SSL 设置
|
||||
|
||||
access_log /var/log/nginx/404blog_ssl_redirect_access.log
|
||||
main
|
||||
buffer=16k; # 访问日志记录
|
||||
error_log /var/log/nginx/404blog_ssl_redirect_error.log warn; # 错误日志记录
|
||||
|
||||
return 301 https://www.404blog.org$request_uri; # 永久重定向到 HTTPS 的 www 域名
|
||||
}
|
||||
|
||||
# --- 主域名 www 的 HTTP 重定向配置 ---
|
||||
server {
|
||||
listen 80; # 监听 HTTP 80 端口
|
||||
server_name www.404blog.org; # 匹配 www 域名
|
||||
|
||||
access_log /var/log/nginx/404blog_www_http_access.log main buffer=16k; # 访问日志记录
|
||||
error_log /var/log/nginx/404blog_www_http_error.log warn; # 错误日志记录
|
||||
|
||||
return 301 https://$host$request_uri; # 重定向到 HTTPS,保留主机名和路径
|
||||
}
|
||||
|
||||
# --- 主域名 www 的 HTTPS 服务配置 ---
|
||||
server {
|
||||
listen 443 ssl; # 监听 HTTPS 443 端口并启用 SSL
|
||||
http2 on; # 启用 HTTP/2 协议,加速传输
|
||||
server_name www.404blog.org; # 匹配 www 域名
|
||||
|
||||
include /etc/nginx/snippets/ssl-404blog.conf; # 引入 SSL 相关配置片段
|
||||
|
||||
access_log /var/log/nginx/404blog_www_https_access.log
|
||||
main
|
||||
buffer=32k
|
||||
flush=5s; # 访问日志,设置更大缓冲和刷新时间
|
||||
error_log /var/log/nginx/404blog_www_https_error.log warn; # 错误日志记录
|
||||
|
||||
# 安全相关的 HTTP 响应头配置
|
||||
add_header X-Content-Type-Options "nosniff" always; # 防止浏览器嗅探 MIME 类型
|
||||
add_header X-Frame-Options "DENY" always; # 禁止页面被嵌入到 iframe 中
|
||||
add_header X-XSS-Protection "1; mode=block" always; # 启用 XSS 防护机制
|
||||
add_header Referrer-Policy
|
||||
"strict-origin-when-cross-origin"
|
||||
always; # 限制跨域时的 Referrer 信息
|
||||
add_header Content-Security-Policy
|
||||
"default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; img-src 'self' data: https:; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; font-src 'self' https://cdn.jsdelivr.net; connect-src 'self'; frame-src 'none'; object-src 'none'; base-uri 'self'; form-action 'self';"
|
||||
always; # CSP 策略,增强安全性
|
||||
add_header Strict-Transport-Security
|
||||
"max-age=63072000; includeSubDomains; preload"
|
||||
always; # HSTS 强制 HTTPS 连接
|
||||
add_header Permissions-Policy
|
||||
"geolocation=(), microphone=(), camera=()"
|
||||
always; # 限制浏览器敏感权限
|
||||
|
||||
root /var/www/404-blog; # 设置网站根目录,指向静态文件
|
||||
index index.html; # 默认首页文件
|
||||
|
||||
if ($request_method !~ ^(GET|HEAD)$) { # 限制请求方法,仅允许 GET 和 HEAD
|
||||
return 405; # 其他方法一律返回 405 错误
|
||||
}
|
||||
|
||||
# 基本路由配置
|
||||
location / {
|
||||
try_files $uri $uri/ =404; # 尝试匹配文件或目录,无匹配则返回 404
|
||||
}
|
||||
|
||||
# 特殊文件(如 robots.txt 和 favicon.ico)的处理
|
||||
location ~ ^/(robots\.txt|favicon\.ico)$ {
|
||||
access_log off; # 关闭访问日志,减少磁盘 I/O
|
||||
log_not_found off; # 关闭未找到文件的日志记录
|
||||
expires 30d; # 设置 30 天缓存过期时间
|
||||
add_header Cache-Control "public, immutable"; # 设置公开且不可变缓存
|
||||
}
|
||||
|
||||
# RSS 和 Sitemap 文件缓存策略
|
||||
location ~* \.(xml|json)$ {
|
||||
expires 12h; # 缓存时间设为 12 小时
|
||||
add_header Cache-Control "public, must-revalidate"; # 公开缓存但需验证
|
||||
}
|
||||
|
||||
# 图片等静态资源的缓存策略
|
||||
location ~* \.(jpg|jpeg|png|gif|ico|svg|webp)$ {
|
||||
expires 30d; # 图片资源缓存 30 天
|
||||
add_header Cache-Control "public, immutable"; # 不可变缓存,适合 CDN
|
||||
access_log off; # 关闭访问日志
|
||||
}
|
||||
|
||||
# CSS 和 JS 文件缓存策略
|
||||
location ~* \.(css|js)$ {
|
||||
expires 7d; # 缓存时间为 7 天
|
||||
add_header Cache-Control "public, immutable"; # 不可变缓存
|
||||
access_log off; # 关闭访问日志
|
||||
}
|
||||
|
||||
# 字体文件缓存策略
|
||||
location ~* \.(woff|woff2|ttf|eot|otf)$ {
|
||||
expires 90d; # 字体资源缓存 90 天
|
||||
add_header Cache-Control "public, immutable"; # 不可变缓存
|
||||
access_log off; # 关闭访问日志
|
||||
}
|
||||
|
||||
# HTML 文件缓存策略
|
||||
location ~* \.html$ {
|
||||
expires 1h; # HTML 文件缓存 1 小时
|
||||
add_header Cache-Control "public, must-revalidate"; # 公开缓存但需验证
|
||||
}
|
||||
|
||||
# 禁止访问隐藏文件和敏感目录
|
||||
location ~ /\. {
|
||||
deny all; # 拒绝访问以 . 开头的文件或目录
|
||||
access_log off; # 关闭访问日志
|
||||
log_not_found off; # 关闭未找到日志
|
||||
}
|
||||
|
||||
# 自定义错误页面配置
|
||||
error_page 404 /404.html; # 404 错误页面指向自定义文件
|
||||
error_page 500 502 503 504 /50x.html; # 5xx 错误页面指向自定义文件
|
||||
|
||||
location = /404.html {
|
||||
root /var/www/404-blog; # 404 页面文件所在根目录
|
||||
internal; # 仅限内部访问
|
||||
}
|
||||
|
||||
location = /50x.html {
|
||||
root /var/www/404-blog; # 5xx 页面文件所在根目录
|
||||
internal; # 仅限内部访问
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
启用站点并创建部署目录:
|
||||
|
||||
```bash
|
||||
sudo ln -s /etc/nginx/sites-available/your-blog /etc/nginx/sites-enabled/
|
||||
|
||||
sudo mkdir -p /var/www/your-blog
|
||||
|
||||
sudo chown -R $USER:$USER /var/www/your-blog # 确保部署用户有权限
|
||||
|
||||
sudo nginx -t # 测试配置
|
||||
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
## 3. 准备 SSH 密钥对
|
||||
|
||||
为了让 GitHub Actions 能够安全地连接到您的服务器,创建一个专用的 SSH 密钥:
|
||||
|
||||
```bash
|
||||
ssh-keygen -t rsa -b 4096 -C "github-actions-deploy" -f ~/.ssh/github-actions
|
||||
```
|
||||
|
||||
在您的服务器上,将公钥添加到 authorized_keys:
|
||||
|
||||
```bash
|
||||
cat ~/.ssh/github-actions.pub >> ~/.ssh/authorized_keys
|
||||
```
|
||||
|
||||
## 4. 配置 GitHub 仓库 Secrets
|
||||
|
||||
将私钥和其他必要信息添加到 GitHub 仓库的 Secrets 中:
|
||||
|
||||
1. 在 GitHub 仓库页面,点击 "Settings" → "Secrets and variables" → "Actions" → "New repository secret"
|
||||
2. 添加以下 Secrets:
|
||||
- `SSH_PRIVATE_KEY`: 您生成的私钥内容(整个文件内容)
|
||||
- `SERVER_HOST`: 您服务器的 IP 地址或域名
|
||||
- `SERVER_USERNAME`: SSH 登录用户名
|
||||
- `SERVER_PORT`: SSH 端口(通常是 22)
|
||||
- `SERVER_DEPLOY_PATH`: 部署路径(如 /var/www/your-blog)
|
||||
|
||||
## 5. 创建 GitHub Actions 工作流
|
||||
|
||||
在您的 Hugo 项目中创建 `.github/workflows/deploy.yml` 文件:
|
||||
|
||||
```yaml
|
||||
name: Deploy Hugo site to Server
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Hugo
|
||||
uses: peaceiris/actions-hugo@v2
|
||||
with:
|
||||
hugo-version: "latest"
|
||||
extended: true
|
||||
|
||||
- name: Build
|
||||
run: hugo --minify
|
||||
|
||||
- name: Install SSH Key
|
||||
uses: shimataro/ssh-key-action@v2
|
||||
with:
|
||||
key: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||
known_hosts: "just-a-placeholder"
|
||||
|
||||
- name: Adding Known Hosts
|
||||
run: ssh-keyscan -H -p ${{ secrets.SERVER_PORT }} ${{ secrets.SERVER_HOST }} >> ~/.ssh/known_hosts
|
||||
|
||||
- name: Deploy with rsync
|
||||
run: |
|
||||
rsync -avz --delete -e "ssh -p ${{ secrets.SERVER_PORT }}" \
|
||||
./public/ \
|
||||
${{ secrets.SERVER_USERNAME }}@${{ secrets.SERVER_HOST }}:${{ secrets.SERVER_DEPLOY_PATH }}
|
||||
|
||||
```
|
||||
|
||||
上述工作流在每次推送到主分支时触发,执行代码检出、Hugo 构建及静态文件部署等步骤,最终通过 `rsync` 工具将 `public` 目录同步到服务器。
|
||||
|
||||
# 图片管理策略
|
||||
|
||||
因为我这边更期望在 Obsidian 中进行编辑,所以只研究了两种图片管理方式:
|
||||
|
||||
## 1. 本地存储方案
|
||||
|
||||
此方案来源于 Hugo 论坛的 jmooring 最佳解决方案:
|
||||
|
||||
**Obsidian 配置**
|
||||
|
||||
```json
|
||||
{
|
||||
"attachmentFolderPath": "attachments",
|
||||
"useMarkdownLinks": true,
|
||||
"newLinkFormat": "absolute"
|
||||
}
|
||||
```
|
||||
|
||||
对应了设置中的如下配置,我图片存储在了 images 下:
|
||||
|
||||

|
||||
|
||||
**Hugo 配置**
|
||||
|
||||
```toml
|
||||
[markup.goldmark.renderHooks.image]
|
||||
enableDefault = true
|
||||
|
||||
[markup.goldmark.renderHooks.link]
|
||||
enableDefault = true
|
||||
|
||||
[[module.mounts]]
|
||||
source = 'assets'
|
||||
target = 'assets'
|
||||
|
||||
[[module.mounts]]
|
||||
source = 'attachments'
|
||||
target = 'assets/attachments'
|
||||
```
|
||||
|
||||
**目录结构**
|
||||
|
||||
```
|
||||
attachments/
|
||||
├── documents/
|
||||
│ ├── a.pdf
|
||||
│ └── b.pdf
|
||||
└── images/
|
||||
├── kitten-a.jpg
|
||||
└── kitten-b.jpg
|
||||
```
|
||||
|
||||
## 2. 图床存储方案
|
||||
|
||||
此时可以使用 Obsidian 的插件 Image Upload Toolkit。特别感谢作者,当我想使用此方案时,暂时还不支持 R2 上传,作者了解后,很快进行了适配。
|
||||
|
||||
我的配置如下:
|
||||
|
||||

|
||||
|
||||
上图重 `Attachment location` 需为 `/`,否则不适配插件会有找不到图片的异常信息。
|
||||
|
||||

|
||||
|
||||
上图所需要的配置在 R2 配置界面均可以找到:
|
||||
|
||||

|
||||
|
||||
存储桶设置中,推荐自定义域,当然前提时你需要在 Cloud flare 进行域名托管。才可以使用子域。
|
||||
|
||||

|
||||
|
||||
# 缓存加速
|
||||
|
||||
本设计主要聚焦于 Ng 和 Cloudflare 的配置,操作简单,基本通过点击即可完成。重点内容通过截图展示,一目了然。如果您想深入学习更专业的使用方法,建议参考相关教程。
|
||||
|
||||
## 1. Ng 加速配置
|
||||
|
||||
使用上述 Ng 配置已经处理好了大多数缓存配置和安全策略。
|
||||
|
||||
## 2. Cloud flare 缓存
|
||||
|
||||
将域名托管到 Cf 后,可以新增 Cache Rules。
|
||||
|
||||

|
||||
|
||||
具体规则如下:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## 3. SSL/TLS 加密
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
CloudFlare 为用户提供的源服务器证书是由 Cloudflare 签名的免费 TLS 证书,该域名证书属于泛域名证书,最长支持 15 年,主要用于源服务器和 Cloudflare 之间的流量加密。但是这个证书属于自签名证书,证书链不完整,缺少根证书。
|
||||
|
||||
使用如下网址下载 CloudFlare 的根证书/证书链文件,并上传到您的源 Web 服务器。请注意, CloudFlare 提供了 ECC 和 RSA 版本两个文件,具体下载哪一个参考上图,根据自己申请源服务器证书时选择的“私钥类型”来决定。
|
||||
|
||||
[Cloud flare 根证书下载](https://developers.cloudflare.com/ssl/origin-configuration/origin-ca/#cloudflare-origin-ca-root-certificate)
|
||||
|
||||
[RSA 下载](https://developers.cloudflare.com/ssl/static/origin_ca_rsa_root.pem)
|
||||
|
||||
根证书下载上传后 Ng 需要对应的配置,我是放到了 snippets 配置片段下,进行统一的引用。
|
||||
@@ -0,0 +1,27 @@
|
||||
# 问题 1
|
||||
|
||||
使用组策略编辑器(仅适用于专业版、企业版和教育版):
|
||||
|
||||
a. 打开 “运行” 对话框,可以按下 Win + R 键,然后输入 “gpedit.msc” 并按 Enter。
|
||||
|
||||
b. 在 “组策略编辑器” 中,导航至以下路径:
|
||||
|
||||
计算机配置 -> 管理模板 -> 网络 -> DNS客户端
|
||||
|
||||
c. 在右侧窗格中,找到并双击 “禁用智能多宿主名称解析”(Turn off Multicast Name Resolution)。
|
||||
|
||||
d. 在弹出的窗口中,选择 “已启用”(Enabled),然后点击 “确定”。
|
||||
|
||||

|
||||
|
||||
# 问题 2
|
||||
|
||||
```
|
||||
edge://flags/#enable-quic
|
||||
```
|
||||
|
||||

|
||||
|
||||
# 问题 3
|
||||
|
||||

|
||||
@@ -0,0 +1,104 @@
|
||||
解决方案:https://github.com/MetaCubeX/mihomo/discussions/1920
|
||||
|
||||
# 如何在 Tun 模式下让公司域名走公司 VPN?
|
||||
|
||||
各位社区的大佬好,最近遇到了一个关于 **Tun 模式与公司 VPN 共存** 的问题,希望能得到大家的帮助。
|
||||
|
||||
# 🎯 目标
|
||||
|
||||
我希望在 **登录公司 VPN** 的同时,使用 **Tun 模式**,并且能够正常访问公司的内部域名。
|
||||
|
||||
# 📌 现状
|
||||
|
||||
- **使用系统代理模式时**,公司域名可以正常解析和访问,因为配置了规则 `DIRECT` 转向 `system` 后,系统代理模式会识别到公司 VPN 的 DNS 解析。
|
||||
- 但是 **启用 Tun 模式后**,公司域名解析失败,无法访问。
|
||||
|
||||
# 🛠️ 配置
|
||||
|
||||
当前 `Clash` 配置中的 `dns` 相关部分如下:
|
||||
|
||||
```yaml
|
||||
dns:
|
||||
enable: true
|
||||
ipv6: true
|
||||
prefer-h3: true
|
||||
listen: 0.0.0.0:1053
|
||||
respect-rules: false
|
||||
enhanced-mode: fake-ip
|
||||
fake-ip-range: 198.18.0.1/16
|
||||
fake-ip-filter-mode: blacklist
|
||||
fake-ip-filter:
|
||||
- "+.stun.*.*"
|
||||
- "+.stun.*.*.*"
|
||||
- "+.stuns.*.*"
|
||||
- "+.stuns.*.*.*"
|
||||
- "+.wns.windows.com"
|
||||
- "+.msftncsi.com"
|
||||
- "+.msftconnecttest.com"
|
||||
- "rule-set:private_domain,cn_domain"
|
||||
default-nameserver:
|
||||
- 223.5.5.5
|
||||
- 119.29.29.29
|
||||
proxy-server-nameserver:
|
||||
- https://dns.alidns.com/dns-query
|
||||
nameserver-policy:
|
||||
rule-set:private_domain,cn_domain:
|
||||
- 223.5.5.5
|
||||
rule-set:geolocation-!cn:
|
||||
- https://cloudflare-dns.com/dns-query
|
||||
- https://dns.google/dns-query
|
||||
nameserver:
|
||||
- 119.29.29.29
|
||||
fallback:
|
||||
- tls://1.1.1.1:853
|
||||
- tls://9.9.9.9:853
|
||||
direct-nameserver:
|
||||
- system
|
||||
```
|
||||
|
||||
`rules` 相关如下:
|
||||
|
||||
```yaml
|
||||
rules:
|
||||
# >>>>>>>>>>>>>>>> Custom Rules >>>>>>>>>>>>>>>>
|
||||
- DOMAIN-SUFFIX,公司域名.net,DIRECT
|
||||
# <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
- RULE-SET,private_ip,DIRECT,no-resolve
|
||||
- RULE-SET,private_domain,DIRECT
|
||||
- RULE-SET,cn_ip,DIRECT,no-resolve
|
||||
- RULE-SET,cn_domain,DIRECT
|
||||
- RULE-SET,steamcn_domain,DIRECT
|
||||
- RULE-SET,apple_domain,DIRECT
|
||||
- RULE-SET,youtube_domain,YouTube
|
||||
- RULE-SET,telegram_domain,Telegram
|
||||
- RULE-SET,telegram_ip,Telegram
|
||||
- RULE-SET,x_domain,X
|
||||
- RULE-SET,facebook_domain,Facebook
|
||||
- RULE-SET,facebook_ip,Facebook
|
||||
- RULE-SET,instagram_domain,Instagram
|
||||
- RULE-SET,openai_domain,OpenAi
|
||||
- RULE-SET,github_domain,GitHub
|
||||
- RULE-SET,onedrive_domain,OneDrive
|
||||
- RULE-SET,netflix_ip,Netflix,no-resolve
|
||||
- RULE-SET,netflix_domain,Netflix
|
||||
- RULE-SET,paypal_domain,PayPal
|
||||
- RULE-SET,steam_domain,Steam
|
||||
- RULE-SET,google_ip,Google,no-resolve
|
||||
- RULE-SET,google_domain,Google
|
||||
- RULE-SET,microsoft_domain,Microsoft
|
||||
- MATCH,Final
|
||||
```
|
||||
|
||||
# 🔍 观察
|
||||
|
||||
- **VPN 启动后会创建一个新的网卡**,但在 Tun 模式下,公司内部域名似乎不会走公司 VPN 提供的 DNS 解析,从而导致解析失败。
|
||||
- **猜测原因**:
|
||||
1. Tun 模式可能会导致 DNS 请求不走公司 VPN 解析。
|
||||
|
||||

|
||||
|
||||
# ❓ 求助
|
||||
|
||||
- 在 **Tun 模式下**,如何让 **公司域名走公司 VPN** 进行解析和访问?
|
||||
|
||||
如果有大佬遇到过类似问题,或者有任何建议,万分感谢!🙏
|
||||
@@ -0,0 +1,150 @@
|
||||
基于 Ubuntu 的服务器,安装和配置 `shadowsocks-libev`,并结合 `v2ray-plugin` 插件来增强其伪装能力。
|
||||
|
||||
[官网](https://shadowsocks.org/)
|
||||
|
||||
# 一、安装并管理 Shadowsocks-libev
|
||||
|
||||
首先,我们需要安装 Shadowsocks 的 libev 实现版本,它以高性能和低资源占用著称。
|
||||
|
||||
## 1. 安装 Shadowsocks
|
||||
|
||||
使用 `apt` 包管理器一键安装:
|
||||
|
||||
```bash
|
||||
sudo apt update && sudo apt full-upgrade -y
|
||||
sudo apt install shadowsocks-libev
|
||||
```
|
||||
|
||||
如果在源中找不到包优先排查 Ubuntu 版本问题,推荐 LTS 版本。
|
||||
|
||||
## 2. 管理服务
|
||||
|
||||
安装后,`shadowsocks-libev` 会被注册为一个 systemd 服务,方便我们进行管理。
|
||||
|
||||
- 查看服务状态:检查服务是否正在运行。
|
||||
|
||||
```bash
|
||||
systemctl status shadowsocks-libev.service
|
||||
```
|
||||
|
||||
- 重启服务:当配置文件修改后,需要重启来使更改生效。
|
||||
|
||||
```bash
|
||||
systemctl restart shadowsocks-libev.service
|
||||
```
|
||||
|
||||
- 查看实时日志:排查连接问题或监控运行状态时非常有用。
|
||||
|
||||
```bash
|
||||
journalctl -u shadowsocks-libev.service -f
|
||||
```
|
||||
|
||||
# 二、安装 v2ray-plugin 插件
|
||||
|
||||
为了更好地伪装流量,我们选择安装 `v2ray-plugin`。
|
||||
|
||||
## 1. 安装插件
|
||||
|
||||
同样使用 `apt`进行安装:
|
||||
|
||||
```bash
|
||||
sudo apt install shadowsocks-v2ray-plugin
|
||||
```
|
||||
|
||||
## 2. 验证安装
|
||||
|
||||
可以通过 `dpkg` 命令查看插件安装后释放了哪些文件,以确认安装成功。
|
||||
|
||||
```bash
|
||||
dpkg -L shadowsocks-v2ray-plugin
|
||||
```
|
||||
|
||||
# 三、配置 Shadowsocks 服务器
|
||||
|
||||
接下来是最关键的一步:编辑配置文件,设定服务器的参数。
|
||||
|
||||
## 1. 编辑配置文件
|
||||
|
||||
使用 `vim` 或你喜欢的其他文本编辑器打开默认的配置文件:
|
||||
|
||||
```bash
|
||||
sudo vim /etc/shadowsocks-libev/config.json
|
||||
```
|
||||
|
||||
## 2. 写入配置
|
||||
|
||||
将文件内容替换为以下 JSON 配置。**请务必将 `password` 字段的值修改为您自己的强密码!**
|
||||
|
||||
```json
|
||||
{
|
||||
"server": ["::", "0.0.0.0"],
|
||||
"mode": "tcp_and_udp",
|
||||
"server_port": 8388,
|
||||
"local_port": 1080,
|
||||
"password": "vS52NAL6NqWJ",
|
||||
"timeout": 86400,
|
||||
"method": "chacha20-ietf-poly1305",
|
||||
"plugin": "ss-v2ray-plugin",
|
||||
"plugin_opts": "server"
|
||||
}
|
||||
```
|
||||
|
||||
配置项说明:
|
||||
|
||||
- `server`: 监听的 IP 地址。监听所有 IPv4、IPv6 接口。
|
||||
- `server_port`: 服务器监听的端口,客户端需要连接此端口。
|
||||
- `password`: 连接密码,**务必修改**。
|
||||
- `method`: 加密方法,推荐使用 `chacha20-ietf-poly1305`。
|
||||
- `plugin`: 指定要使用的插件,这里是 `ss-v2ray-plugin`。
|
||||
- `plugin_opts`: 插件的选项,`server` 表示在服务器模式下运行。
|
||||
|
||||
## 3. 应用配置
|
||||
|
||||
配置修改完成后,不要忘记**重启 Shadowsocks 服务**以使新配置生效。
|
||||
|
||||
```bash
|
||||
sudo systemctl restart shadowsocks-libev.service
|
||||
```
|
||||
|
||||
# 四、配置防火墙 (UFW)
|
||||
|
||||
为了让外部客户端能够连接到我们的服务,需要在服务器的防火墙上放行指定的端口。这里以 `UFW` (Uncomplicated Firewall) 为例。
|
||||
|
||||
- 启动防火墙(如果尚未启动):
|
||||
|
||||
```bash
|
||||
sudo ufw enable
|
||||
```
|
||||
|
||||
- 查看防火墙状态:
|
||||
|
||||
```bash
|
||||
sudo ufw status
|
||||
```
|
||||
|
||||
- 开放服务端口(重要!):这里的 `8388` 必须与 `config.json` 文件中的 `server_port` 一致。
|
||||
|
||||
```bash
|
||||
sudo ufw allow 8388
|
||||
```
|
||||
|
||||
- 其他常用命令:
|
||||
- 拒绝端口访问: `sudo ufw deny 8388`
|
||||
- 删除已有规则: `sudo ufw delete allow 8388`
|
||||
- 关闭防火墙: `sudo ufw disable`
|
||||
|
||||
# 五、客户端下载与配置
|
||||
|
||||
服务器搭建完成后,您需要在自己的设备(如 Windows、Mac、手机)上安装相应的客户端进行连接。
|
||||
|
||||
- Shadowsocks Windows 客户端:
|
||||
|
||||
> [https://github.com/shadowsocks/shadowsocks-windows](https://github.com/shadowsocks/shadowsocks-windows)
|
||||
|
||||
- v2ray-plugin 插件 (客户端也需要安装此插件):
|
||||
|
||||
> [https://github.com/shadowsocks/v2ray-plugin](https://github.com/shadowsocks/v2ray-plugin)
|
||||
|
||||
在客户端中,你需要填入与服务器 `config.json` 文件完全一致的**服务器IP**、**端口(8388)**、**密码**和**加密方法**,并在插件设置中选择 `v2ray` 插件即可。
|
||||
|
||||
至此,您的 Shadowsocks + v2ray-plugin 服务器已全部搭建并配置完毕。
|
||||
@@ -0,0 +1,234 @@
|
||||
# Trojan-Go 从零到一
|
||||
|
||||
Trojan-Go 是一个基于 Trojan 协议的代理工具,它通过将流量伪装成正常的 HTTPS 流量,从而有效地规避网络审查。相比原版 Trojan,Trojan-Go 提供了更多高级功能,如多路复用、路由、WebSocket 支持等,性能优异且配置灵活。
|
||||
|
||||
- **项目地址**:[https://github.com/p4gefau1t/trojan-go](https://github.com/p4gefau1t/trojan-go)
|
||||
- **官方文档**:[https://p4gefau1t.github.io/trojan-go/](https://p4gefau1t.github.io/trojan-go/)
|
||||
|
||||
# 一、准备工作
|
||||
|
||||
在开始之前,请确保你已具备以下条件:
|
||||
|
||||
1. 一台境外 VPS:拥有 root 或 sudo 权限,并已安装好一个主流的 Linux 发行版(如 Ubuntu, Debian, CentOS)。
|
||||
2. 一个域名:并将该域名解析到你的 VPS 公网 IP 地址。本文将以 `your.domain.com` 为例。
|
||||
3. 基础的 Linux 操作能力:熟悉使用 SSH 连接服务器及执行基本命令。
|
||||
|
||||
# 二、申请 SSL/TLS 证书
|
||||
|
||||
Trojan 协议的核心是使用真实的 TLS 加密来伪装流量。因此,一个有效的域名证书是必不可少的。我们推荐使用 `acme.sh` 自动申请和续签 Let's Encrypt 等免费证书。
|
||||
|
||||
## 1. 安装 acme.sh
|
||||
|
||||
```bash
|
||||
# 安装 acme.sh 工具
|
||||
curl https://get.acme.sh | sh -s
|
||||
|
||||
# 如果提示 curl: command not found, 请先安装 curl
|
||||
# apt update && apt install curl -y (Debian/Ubuntu)
|
||||
# yum update && yum install curl -y (CentOS)
|
||||
|
||||
# 创建软链接,方便全局调用
|
||||
ln -s /root/.acme.sh/acme.sh /usr/local/bin/acme.sh
|
||||
|
||||
# 注册 acme.sh 账户(邮箱会用于接收证书到期提醒)
|
||||
acme.sh --register-account -m my@example.com
|
||||
```
|
||||
|
||||
## 2. 安装依赖并开放端口
|
||||
|
||||
`acme.sh` 的 `standalone` 模式需要在 80 端口上启动一个临时验证服务器。
|
||||
|
||||
```bash
|
||||
# 安装 socat,standalone 模式依赖它
|
||||
apt update
|
||||
apt install socat -y # Debian/Ubuntu
|
||||
# yum install socat -y # CentOS
|
||||
|
||||
# 确保防火墙开放 80 端口(用于证书申请)和 443 端口(Trojan-Go 服务)
|
||||
ufw allow 80
|
||||
ufw allow 443
|
||||
ufw reload
|
||||
```
|
||||
|
||||
## 3. 申请证书
|
||||
|
||||
我们使用 ECC 证书(`ec-256`),它具有更好的性能和更小的密钥体积。
|
||||
|
||||
```bash
|
||||
# --standalone 模式会自动监听 80 端口完成验证
|
||||
acme.sh --issue -d your.domain.com --standalone -k ec-256
|
||||
```
|
||||
|
||||
证书签发失败怎么办?
|
||||
|
||||
默认的 CA 服务商可能因为各种原因无法成功签发。你可以尝试切换到其他 CA:
|
||||
|
||||
```bash
|
||||
# 切换到 Let’s Encrypt
|
||||
acme.sh --set-default-ca --server letsencrypt
|
||||
# 切换到 Buypass
|
||||
acme.sh --set-default-ca --server buypass
|
||||
# 切换到 ZeroSSL
|
||||
acme.sh --set-default-ca --server zerossl
|
||||
```
|
||||
|
||||
切换后,重新执行上面的申请命令即可。
|
||||
|
||||
## 4. 安装证书到指定目录
|
||||
|
||||
为了方便管理,我们将证书和密钥统一部署到一个目录,例如 `/root/trojan/`。
|
||||
|
||||
这里为了方便可以放到 trojan 目录下。
|
||||
|
||||
```bash
|
||||
# 创建目录
|
||||
mkdir -p /root/trojan
|
||||
|
||||
# 使用 --installcert 命令将证书文件复制到指定位置
|
||||
# acme.sh 会在证书续签后自动将新证书部署到这里
|
||||
acme.sh --installcert -d your.domain.com --ecc \
|
||||
--key-file /root/trojan/server.key \
|
||||
--fullchain-file /root/trojan/server.crt
|
||||
```
|
||||
|
||||
备选方案:使用自签名证书
|
||||
|
||||
如果你只是为了临时测试或在内网环境使用,可以快速生成自签名证书。**注意:客户端连接时需要禁用证书验证,安全性较低,不推荐在生产环境使用。**
|
||||
|
||||
```bash
|
||||
# 生成私钥
|
||||
openssl ecparam -genkey -name prime256v1 -out /root/trojan/server.key
|
||||
|
||||
# 生成证书(-subj 参数可以自定义,CN需要是你的域名)
|
||||
openssl req -new -x509 -days 36500 -key /root/trojan/server.key -out /root/trojan/server.crt -subj "/CN=your.domain.com"
|
||||
|
||||
```
|
||||
|
||||
# 三、下载并配置 Trojan-Go
|
||||
|
||||
#### 1. 下载 Trojan-Go
|
||||
|
||||
前往 Trojan-Go 的 [GitHub Releases](https://github.com/p4gefau1t/trojan-go/releases) 页面,找到最新的版本,复制对应你服务器架构的 `linux-amd64` 版本下载链接。
|
||||
|
||||
```bash
|
||||
# 进入一个临时目录
|
||||
cd /tmp
|
||||
|
||||
# 下载(请替换为最新的版本链接)
|
||||
wget https://github.com/p4gefau1t/trojan-go/releases/download/v0.10.6/trojan-go-linux-amd64.zip
|
||||
|
||||
# 解压
|
||||
unzip trojan-go-linux-amd64.zip
|
||||
|
||||
# 将可执行文件移动到系统路径
|
||||
mv trojan-go /usr/local/bin/
|
||||
|
||||
# 创建配置文件目录
|
||||
mkdir -p /etc/trojan-go
|
||||
```
|
||||
|
||||
#### 2. 编写配置文件
|
||||
|
||||
创建一个配置文件 `config.json`。
|
||||
|
||||
```bash
|
||||
vim /etc/trojan-go/config.json
|
||||
```
|
||||
|
||||
将以下内容粘贴进去,并根据你的实际情况进行修改:
|
||||
|
||||
```json
|
||||
{
|
||||
"run_type": "server",
|
||||
"local_addr": "0.0.0.0",
|
||||
"local_port": 443,
|
||||
"remote_addr": "127.0.0.1",
|
||||
"remote_port": 80,
|
||||
"password": [
|
||||
"your_strong_password" // 请修改为你自己的强密码
|
||||
],
|
||||
"ssl": {
|
||||
"cert": "/root/trojan/server.crt", // 证书路径
|
||||
"key": "/root/trojan/server.key", // 私钥路径
|
||||
"sni": "your.domain.com" // 你的域名
|
||||
},
|
||||
"router": {
|
||||
"enabled": true,
|
||||
"block": [
|
||||
"geoip:private"
|
||||
],
|
||||
"geoip": "/usr/local/bin/geoip.dat",
|
||||
"geosite": "/usr/local/bin/geosite.dat"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**配置文件关键参数解析:**
|
||||
|
||||
- `run_type`: 运行类型,服务端设置为 `server`。
|
||||
- `local_addr` & `local_port`: Trojan-Go 监听的地址和端口,`0.0.0.0:443` 表示监听所有网络接口的 443 端口。
|
||||
- `remote_addr` & `remote_port`: **伪装目标地址**。当有非 Trojan 协议的流量(如直接用浏览器访问你的域名)访问 `443` 端口时,Trojan-Go 会将该流量转发到此地址。通常,我们会在本地 80 端口搭建一个简单的 Nginx 网站,来完美伪装成一个真实网站。`127.0.0.1:80` 是最常见的配置。
|
||||
- `password`: 客户端连接时需要使用的密码,可以设置多个。
|
||||
- `ssl`: TLS 相关配置。
|
||||
- `cert` & `key`: 指向你刚刚申请并安装的证书和私钥文件。
|
||||
- `sni`: Server Name Indication,客户端必须指定此域名才能成功连接。这里填写你的域名。
|
||||
- `router`: Trojan-Go 内置的简易路由器,可以用来屏蔽特定流量(如BT、私网IP等),增强安全性。`geoip.dat` 和 `geosite.dat` 文件随 Trojan-Go 压缩包一起提供,记得将它们也移动到 `/usr/local/bin/`。
|
||||
|
||||
# 四、设置后台运行与开机自启(Systemd)
|
||||
|
||||
为了让 Trojan-Go 能在后台稳定运行,并且在服务器重启后自动启动,我们为它创建一个 Systemd 服务。
|
||||
|
||||
```bash
|
||||
nano /etc/systemd/system/trojan-go.service
|
||||
```
|
||||
|
||||
将以下内容粘贴到文件中:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Trojan-Go
|
||||
Documentation=https://github.com/p4gefau1t/trojan-go
|
||||
After=network.target nss-lookup.target
|
||||
|
||||
[Service]
|
||||
User=root
|
||||
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
|
||||
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
|
||||
NoNewPrivileges=true
|
||||
ExecStart=/usr/local/bin/trojan-go -config /etc/trojan-go/config.json
|
||||
Restart=on-failure
|
||||
RestartSec=10s
|
||||
LimitNOFILE=infinity
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
现在,使用以下命令来管理 Trojan-Go 服务:
|
||||
|
||||
```bash
|
||||
# 重新加载 Systemd 配置
|
||||
systemctl daemon-reload
|
||||
|
||||
# 启动 Trojan-Go 服务
|
||||
systemctl start trojan-go
|
||||
|
||||
# 设置开机自启
|
||||
systemctl enable trojan-go
|
||||
|
||||
# 查看服务运行状态
|
||||
systemctl status trojan-go
|
||||
```
|
||||
|
||||
如果状态显示 `active (running)`,则表示服务已成功启动。
|
||||
|
||||
# 五、客户端配置示例
|
||||
|
||||
在你的本地设备上,使用支持 Trojan 协议的客户端(如 V2RayN, Shadowrocket, Clash 等),并参考以下配置进行连接:
|
||||
|
||||
- **地址/服务器 (Address/Server)**: `your.domain.com`
|
||||
- **端口 (Port)**: `443`
|
||||
- **密码 (Password)**: `your_strong_password` (你在服务端设置的密码)
|
||||
- **SNI/服务器名称指示 (SNI/Peer)**: `your.domain.com`
|
||||
- **允许不安全 (Allow Insecure)**: `false` 或 `关闭` (因为我们用的是可信证书)
|
||||
- **协议 (Protocol)**: `trojan`
|
||||
@@ -0,0 +1,89 @@
|
||||
|
||||
**环境配置**
|
||||
|
||||
Win + scoop + WinSW + sing-box 1.12.14 裸核
|
||||
|
||||
**问题一:切换 mixed 模式断网与防火墙路径**
|
||||
|
||||
之前一直用的 tun 的 gvisor 堆栈,最近看群里讨论 mixed 模式(也是默认模式),就想换过来试试,结果一改配置直接断网。
|
||||
|
||||
**排查与解决:**
|
||||
|
||||
在群友提醒下怀疑是防火墙问题。
|
||||
|
||||
1. 尝试直接关闭防火墙,网络恢复,确认锅在防火墙。
|
||||
2. 检查防火墙规则,发现确实有一条 `sing-tun` 的放行规则,路径指向 `E:\MyScoop\Scoop\apps\sing-box\current\sing-box.exe`。
|
||||
3. **关键点来了**:Scoop 的 `current` 是一个软连接。我尝试把防火墙规则改为实际的版本路径 `E:\MyScoop\Scoop\apps\sing-box\1.12.14\sing-box.exe`,启用防火墙后网络正常了。
|
||||
|
||||
**求教:** 看来 Windows 防火墙似乎不认 Scoop 的 `current` 软连接路径?有没有懂这块底层机制的佬友科普一下原理?
|
||||
|
||||
**问题二:关于公司 VPN 并存与 local DNS 的源码发现**
|
||||
|
||||
顺道分享一个近期折腾 VPN 并存时发现的坑。
|
||||
|
||||
场景是日常挂 sing-box 和公司 VPN。VPN 启动后会生成独立虚拟网卡。
|
||||
|
||||
**目前的笨办法:**
|
||||
|
||||
必须显式指定出站接口和 DNS 转发。
|
||||
|
||||
创建绑定 VPN 网卡的 outbound:
|
||||
|
||||
```json
|
||||
{
|
||||
"tag": "company-network",
|
||||
"type": "direct",
|
||||
"bind_interface": "controller" // controller 为网卡名称
|
||||
}
|
||||
```
|
||||
|
||||
定义内网 DNS 并指定出口:
|
||||
|
||||
```json
|
||||
{
|
||||
"tag": "Company-DNS",
|
||||
"type": "udp",
|
||||
"server": "12.0.0.1", // 公司内网DNS
|
||||
"detour": "company-network"
|
||||
}
|
||||
```
|
||||
|
||||
路由规则指定域名走该 DNS:
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "route",
|
||||
"domain_suffix": ["company.net"],
|
||||
"server": "Company-DNS",
|
||||
"strategy": "prefer_ipv4"
|
||||
}
|
||||
```
|
||||
|
||||
**尝试简化失败:**
|
||||
|
||||
原本以为可以用官方文档里的 `local` 服务来简化配置,让 sing-box 自动读取系统 DNS:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "local",
|
||||
"tag": "dns_local"
|
||||
}
|
||||
```
|
||||
|
||||
配置后发现无法解析公司内网域名。
|
||||
|
||||
**原因分析:**
|
||||
|
||||
大概翻了一下 sing-box 源码,`local` 确实是读取系统里的上游 DNS 列表,但它在发查询时会检查网关。
|
||||
|
||||
由于我们公司的 VPN 网卡(controller)没有配置 IPv4 默认网关,源码里有一句判断:
|
||||
|
||||
```go
|
||||
if address.FirstGatewayAddress == nil {
|
||||
continue
|
||||
}
|
||||
```
|
||||
|
||||
导致这张网卡直接被跳过了。给同样有 VPN 并存需求的兄弟排个雷。
|
||||
|
||||
**求教:** 佬友们有没有需要公司 VPN 和代理工具同时使用的场景呢?可以分享下使用技巧。
|
||||
@@ -0,0 +1,427 @@
|
||||
# 底层协议
|
||||
|
||||
## 1、TCP
|
||||
|
||||
Transmission Control Protocol,传输控制协议
|
||||
|
||||
- **特点**:面向连接、可靠传输、按顺序传输数据、错误检测和修复、流量控制、拥塞控制。
|
||||
- **应用**:常用于需要高可靠性的应用,如网页浏览(HTTP)、文件传输(FTP)、电子邮件(SMTP/POP3/IMAP)等。
|
||||
|
||||
## 2、UDP
|
||||
|
||||
User Datagram Protocol,用户数据报协议
|
||||
|
||||
- **特点**:无连接、速度较快、没有流量控制和拥塞控制、数据可能丢失或乱序。
|
||||
- **应用**:适用于对速度要求较高、容忍数据丢失的应用,如视频流、实时语音通信、在线游戏等。
|
||||
|
||||
## 3、SCTP
|
||||
|
||||
Stream Control Transmission Protocol,流控制传输协议
|
||||
|
||||
- **特点**:面向连接、可靠传输,具有多流(multi-streaming)和多宿主(multi-homing)支持,可以提供对多条路径的冗余传输,提高了容错性。
|
||||
- **应用**:主要用于电信、网络电话(VoIP)等领域,尤其是在需要多条数据流并且要在多个网络路径中传输数据的场景。
|
||||
|
||||
## 4、DCCP
|
||||
|
||||
Datagram Congestion Control Protocol,数据报拥塞控制协议
|
||||
|
||||
- **特点**:提供拥塞控制,但不像 TCP 那样进行可靠性保证。DCCP 的目标是在低延迟和拥塞控制之间取得平衡。
|
||||
- **应用**:适用于那些需要控制拥塞但又不需要完全可靠传输的应用,如流媒体传输。
|
||||
|
||||
## 5、RUDP
|
||||
|
||||
Reliable User Datagram Protocol,可靠用户数据报协议
|
||||
|
||||
- **特点**:结合了 UDP 和 TCP 的特性,提供 UDP 的低延迟和 TCP 的可靠性。
|
||||
- **应用**:在一些实时性要求较高的应用中(如实时视频通话)使用,提供可靠的传输机制,同时保持较低的延迟。
|
||||
|
||||
## 6、QUIC
|
||||
|
||||
Quick UDP Internet Connections,快速 UDP 互联网连接协议
|
||||
|
||||
- **特点**:基于 UDP,但结合了 TCP 的某些功能,如流量控制、错误纠正等,同时增加了加密和连接恢复等功能。由 Google 提出并在 HTTP/3 中使用。
|
||||
- **应用**:主要用于网页浏览,特别是在 Google Chrome 和 HTTP/3 协议中,以提高传输速度和可靠性。
|
||||
|
||||
## 7、MPTCP
|
||||
|
||||
Multipath TCP,多路径 TCP
|
||||
|
||||
- **特点**:允许通过多条网络路径进行数据传输,增强了传输的可靠性和带宽利用率。
|
||||
- **应用**:主要用于移动设备中,支持多个网络接口(例如 Wi-Fi 和移动数据)同时进行数据传输,提高连接的稳定性和性能。
|
||||
|
||||
## 8、IPX
|
||||
|
||||
Internetwork Packet Exchange,网络包交换协议
|
||||
|
||||
- **特点**:一种较早的网络协议,曾广泛应用于 Novell NetWare 操作系统中。虽然现在较为过时,但它是一种面向连接的协议。
|
||||
- **应用**:在 1980s 和 1990s,广泛应用于局域网环境中,但现在已被 TCP/IP 协议取代。
|
||||
|
||||
## 9、X.25
|
||||
|
||||
- **特点**:一种老式的面向连接的协议,曾用于广域网(WAN)环境中,提供可靠的数据传输,但速度较慢。
|
||||
- **应用**:曾广泛应用于金融和政府领域,现在已被现代的 TCP/IP 协议所取代。
|
||||
|
||||
## 10、L2TP
|
||||
|
||||
Layer 2 Tunneling Protocol,第二层隧道协议
|
||||
|
||||
- **特点**:L2TP 本身并不提供加密和认证,但常用于虚拟专用网络(VPN)协议中,结合 IPsec 提供安全性。
|
||||
- **应用**:VPN 技术,特别是在需要建立跨多个网络的虚拟专用连接时。
|
||||
|
||||
# 加密协议
|
||||
|
||||
## 早期阶段(以简单代理和基础加密为主)
|
||||
|
||||
1. **Socks5**
|
||||
- 功能:简单的代理协议,不提供加密功能,适用于基本的代理需求。
|
||||
- 特点:轻量,但安全性较低,通常需要其他工具配合加密。
|
||||
2. **HTTP**
|
||||
- 功能:通过HTTP协议进行明文传输,主要用于传统代理。
|
||||
- 特点:未加密,安全性低,不适合绕过防火墙或隐私保护。
|
||||
3. **HTTPS**
|
||||
- 功能:HTTP的加密版本,使用TLS/SSL加密数据。
|
||||
- 特点:安全性高,隐蔽性好,常用于现代Web流量代理。
|
||||
4. **SSH**
|
||||
- 功能:基于Secure Shell协议的加密传输,用于保护远程连接。
|
||||
- 特点:安全性高,速度较慢,多用于远程登录,偶尔用于翻墙。
|
||||
|
||||
## 中期阶段(注重加密和混淆的代理协议):
|
||||
|
||||
1. **Shadowsocks (SS)**
|
||||
- 时间:2012年
|
||||
- 功能:基于SOCKS5代理,增加了数据加密功能(AES-256-GCM、ChaCha20等)。
|
||||
- 特点:轻量、高效,主要用于绕过防火墙。
|
||||
2. **ShadowsocksR (SSR)**
|
||||
- 时间:2016年(Shadowsocks的分支)
|
||||
- 功能:在Shadowsocks基础上增加了协议混淆和多种加密方式。
|
||||
- 特点:抗封锁能力更强,但已停止更新,逐渐被其他协议取代。
|
||||
3. **Vmess**
|
||||
- 时间:2017年(随V2Ray推出)
|
||||
- 功能:V2Ray的核心协议,支持数据加密和动态端口。
|
||||
- 特点:灵活性强,可搭配多种传输协议(TCP、WebSocket、mKCP等)。
|
||||
4. **VLESS**
|
||||
- 时间:2020年
|
||||
- 功能:Vmess的改进版本,去除了数据加密,仅进行身份验证。
|
||||
- 特点:效率更高,适合与TLS等协议结合使用。
|
||||
5. **Relay**
|
||||
- 功能:一种中继协议,通过中间节点转发流量,提高隐私性。
|
||||
- 特点:通常与其他工具配合使用,隐蔽性较高。
|
||||
6. **Socks5 Over TLS**
|
||||
- 功能:将Socks5协议与TLS加密结合,增强安全性。
|
||||
- 特点:适合需要高隐私的代理场景。
|
||||
7. **HTTP2**
|
||||
- 功能:基于HTTP的升级协议,支持多路复用和TLS加密。
|
||||
- 特点:传输效率高,隐蔽性强,多用于机场节点伪装。
|
||||
|
||||
## 现代阶段(高效传输和高级伪装):
|
||||
|
||||
1. **Trojan**
|
||||
- 时间:2019年
|
||||
- 功能:基于HTTPS协议伪装正常Web流量。
|
||||
- 特点:隐蔽性强,抗封锁能力优秀,支持TLS加密。
|
||||
2. **WireGuard**
|
||||
- 时间:2019年
|
||||
- 功能:轻量级VPN协议,使用ChaCha20加密。
|
||||
- 特点:速度快,效率高,适合对性能要求高的用户。
|
||||
3. **Hysteria**
|
||||
- 时间:2021年
|
||||
- 功能:基于UDP的传输协议,专注于低延迟和高吞吐量。
|
||||
- 特点:速度极快,适合游戏和流媒体需求。
|
||||
4. **Hysteria2**
|
||||
- 时间:2023年
|
||||
- 功能:Hysteria的升级版本,优化了性能和抗封锁能力。
|
||||
- 特点:更高效,适应复杂网络环境。
|
||||
5. **TUIC**
|
||||
- 时间:2023年
|
||||
- 功能:新一代代理协议,支持多路复用和TLS加密。
|
||||
- 特点:隐蔽性强,传输效率高。
|
||||
6. **Juicity**
|
||||
- 功能:基于现代加密技术的新协议。
|
||||
- 特点:多用于对隐私和安全性要求高的场景。
|
||||
7. **Snell**
|
||||
- 时间:2020年
|
||||
- 功能:Simple-obfs作者开发的一种代理协议。
|
||||
- 特点:轻量化,隐蔽性较好。
|
||||
8. **Brook**
|
||||
- 时间:2018年
|
||||
- 功能:跨平台代理工具,支持多种混淆技术。
|
||||
- 特点:轻量、简单,但抗封锁能力一般。
|
||||
9. **Lua**
|
||||
- 功能:一种嵌入式脚本语言,有时用于自定义代理逻辑。
|
||||
- 特点:灵活,可嵌入其他工具中实现特殊需求。
|
||||
|
||||
# 线路介绍
|
||||
|
||||
## CN2 线路
|
||||
|
||||
CN2(ChinaNet Next Carrying Network)是中国电信的下一代骨干网络,主要面向高端用户和企业级业务。它提供更高的服务质量(QoS),支持多种网络协议,具有更低的延迟和更高的稳定性。
|
||||
|
||||
- **特点:**
|
||||
- **多协议标签交换(MPLS)技术**:提高了网络的传输效率和灵活性。
|
||||
- **更优的路由选择**:通常经过优化的传输路径,减少中转节点。
|
||||
- **高带宽低延迟**:特别适用于对网络质量要求较高的应用,比如游戏、视频会议和跨境通信。
|
||||
|
||||
### QoS(Quality of Service)
|
||||
|
||||
QoS 是指网络传输中的服务质量,主要包括带宽、延迟、抖动、丢包率等多个方面。它的目标是保障关键数据传输的优先级,从而提升用户体验。
|
||||
|
||||
- **主要功能:**
|
||||
- **带宽管理**:分配固定带宽给关键任务。
|
||||
- **延迟控制**:减少延迟对实时应用(如视频通话、在线游戏)的影响。
|
||||
- **数据优先级**:确保高优先级任务在拥堵时优先处理。
|
||||
|
||||
---
|
||||
|
||||
### “被 QoS”是什么意思?
|
||||
|
||||
“被 QoS”是指网络服务供应商对用户的网络带宽进行限制或调控,通常出现在运营商为确保网络资源公平分配时。用户体验的表现是网速下降,尤其是下载速度、视频加载速度或跨境访问。
|
||||
|
||||
- **常见情形:**
|
||||
- 运营商为节约成本或在高峰时段保障总体网络稳定性而对部分用户限制速度。
|
||||
- 用户使用的带宽超出了运营商约定的范围(如无限流量套餐)。
|
||||
|
||||
---
|
||||
|
||||
### CN2 的缺点
|
||||
|
||||
虽然 CN2 线路的性能优秀,但也存在一些局限性:
|
||||
|
||||
- **高成本**:CN2 线路的价格通常比普通线路更高。
|
||||
- **出口带宽有限**:在跨境通信时,部分地区的 CN2 出口可能会有瓶颈。
|
||||
- **覆盖范围有限**:不如传统骨干网络广泛覆盖。
|
||||
|
||||
---
|
||||
|
||||
### CN2 GT 和 CN2 GIA
|
||||
|
||||
- **CN2 GT(Global Transit)**
|
||||
- 标准 CN2 服务,适用于普通国际访问,路由质量较好。
|
||||
- 相较于 CN2 GIA,价格较低但优先级也较低。
|
||||
- **CN2 GIA(Global Internet Access)**
|
||||
- 高级服务,提供更优质的路由和更稳定的传输。
|
||||
- 适合对国际网络质量有高要求的企业和用户,价格昂贵。
|
||||
|
||||
## BGP 协议(Border Gateway Protocol)
|
||||
|
||||
BGP 是边界网关协议,用于管理互联网中的路由信息,是互联网的核心协议之一。
|
||||
|
||||
- **功能:**
|
||||
- **路由选择**:通过动态路由表,选择最佳的网络路径。
|
||||
- **自治系统(AS)之间的通信**:在多个 AS 之间共享路由信息。
|
||||
- **冗余路由**:提供备选路径以防止网络故障。
|
||||
|
||||
## GCP、AWS、Azure 的特点和问题
|
||||
|
||||
这些是三大云计算服务提供商,各有优势和劣势。
|
||||
|
||||
### Google Cloud Platform (GCP)
|
||||
|
||||
- **特点**:
|
||||
- 强大的数据分析和机器学习能力(如 BigQuery)。
|
||||
- 卓越的全球网络性能。
|
||||
- 对开发者友好。
|
||||
- **问题**:
|
||||
- 企业级生态不如 AWS 成熟。
|
||||
- 定价策略较复杂。
|
||||
|
||||
### Amazon Web Services (AWS)
|
||||
|
||||
- **特点**:
|
||||
- 最全面的服务范围,行业领导者。
|
||||
- 广泛的全球数据中心分布。
|
||||
- 强大的开发者和企业支持生态。
|
||||
- **问题**:
|
||||
- 价格昂贵。
|
||||
- 初学者可能觉得复杂。
|
||||
|
||||
## Microsoft Azure
|
||||
|
||||
- **特点**:
|
||||
- 与微软产品(如 Office 365、Windows Server)深度集成。
|
||||
- 强大的混合云支持。
|
||||
- **问题**:
|
||||
- 开发者工具生态略逊于 AWS 和 GCP。
|
||||
- 部分服务的性能略显滞后。
|
||||
|
||||
## PCCW 线路、HKT、HKBN 线路
|
||||
|
||||
这些是香港地区的主要网络服务提供商。
|
||||
|
||||
### PCCW(Pacific Century CyberWorks)线路
|
||||
|
||||
- 香港最大的电信公司之一,提供高性能国际线路。
|
||||
- 多用于企业和跨境业务。
|
||||
|
||||
### HKT(Hong Kong Telecommunications)
|
||||
|
||||
- 另一家主要的电信服务提供商,专注于家庭和中小企业市场。
|
||||
- 提供多种宽带服务,但国际出口不如 PCCW 强。
|
||||
|
||||
### HKBN(Hong Kong Broadband Network)
|
||||
|
||||
- 以高性价比宽带服务著称,服务家庭用户。
|
||||
- 国际出口相较 PCCW 和 HKT 略逊,但价格更具吸引力。
|
||||
|
||||
---
|
||||
|
||||
## IPLC(International Private Leased Circuit)
|
||||
|
||||
IPLC 是国际专线,是一种专门用于点对点国际数据传输的通信线路。
|
||||
|
||||
- **特点:**
|
||||
- **高带宽、低延迟**:适合跨境视频会议、数据传输等高要求场景。
|
||||
- **固定费用**:适合流量需求稳定的企业。
|
||||
- **缺点**:
|
||||
- 价格昂贵。
|
||||
- 缺乏灵活性,不适用于动态流量需求。
|
||||
|
||||
## 163 网
|
||||
|
||||
**163 网**是中国电信的一个传统互联网骨干网络,也是中国最早的大规模商用互联网之一。它的名字来源于中国电信的全国拨号上网接入号码“163”,因此得名。
|
||||
|
||||
1. **传统互联网骨干网**:
|
||||
- 是中国早期的互联网基础设施,主要用于国内互联网流量的承载。
|
||||
- 连接中国电信的宽带用户到全球互联网。
|
||||
2. **路由优先国内**:
|
||||
- 对于国内访问优化较好,适合访问国内网站、应用和服务。
|
||||
- 国际访问通常通过海底光缆或者与国外运营商的合作线路,但路径较复杂,可能造成高延迟和丢包。
|
||||
3. **普通用户网络**:
|
||||
- 面向大众用户,带宽和性能受限于线路负载和流量情况。
|
||||
- 对国际访问的体验不如**CN2 线路**优质。
|
||||
|
||||
## 163 网与 CN2 的对比
|
||||
|
||||
|特性|163 网(ChinaNet)|CN2(ChinaNet Next Carrying Network)|
|
||||
|---|---|---|
|
||||
|**定位**|普通宽带用户互联网|高端用户和企业级网络服务|
|
||||
|**国内访问**|优化良好|同样优化良好|
|
||||
|**国际访问**|路径较复杂,延迟较高|优化路由,低延迟,稳定性更强|
|
||||
|**用户群体**|普通家庭和小型企业|高端家庭用户、大型企业|
|
||||
|**技术架构**|传统互联网架构|使用 MPLS 技术优化路由|
|
||||
|**价格**|成本低,价格便宜|成本高,价格昂贵|
|
||||
|
||||
### 163 网的主要问题
|
||||
|
||||
1. **国际访问体验差**:
|
||||
- 对于访问国际网站或服务(如国外服务器、游戏、视频等),通常存在延迟高、丢包严重的问题。
|
||||
- 原因是国际出口带宽不足,且路由优化不够。
|
||||
2. **拥堵现象明显**:
|
||||
- 高峰时段可能出现网络拥堵,导致网速变慢。
|
||||
3. **服务质量有限**:
|
||||
- 缺乏针对企业或高端用户的优化服务,服务质量相对普通。
|
||||
|
||||
## 中国移动的骨干网络
|
||||
|
||||
- **CMI(China Mobile International)**:
|
||||
- 中国移动的国际网络品牌,专门为跨境通信服务。
|
||||
- 其骨干网络被称为 **CMNET**,主要用于国内和国际的互联网通信。
|
||||
- **特点**:
|
||||
- **国内流量为主**:CMNET 网络优化主要面向国内用户,国际通信能力不如 CN2。
|
||||
- **性价比高**:宽带套餐通常便宜,但国际访问性能稍差,延迟较高。
|
||||
- **高延迟问题**:特别是在访问海外网站和服务时,跨境通信路径长,性能不佳。
|
||||
- **国际出口优化**:
|
||||
- 中国移动近年来通过 CMI 增加了对国际流量的优化,提供了部分高质量国际线路,但整体仍不如 CN2。
|
||||
|
||||
## 中国联通的骨干网络
|
||||
|
||||
- **CUG(China Unicom Global)**:
|
||||
- 中国联通的国际网络品牌,骨干网络通常被称为 **CNCNET**。
|
||||
- **特点**:
|
||||
- **国际访问表现较好**:CNCNET 的国际出口相对稳定,在北美、欧洲和亚洲地区的国际访问体验好于中国移动。
|
||||
- **国际线路优化**:相比 163 网,中国联通的国际访问质量更高,但整体仍低于 CN2。
|
||||
- **性价比中等**:比 CN2 便宜,但国际通信质量优于 CMNET。
|
||||
- **联通优质国际线路**:
|
||||
- 中国联通也提供一些专门针对高端用户和企业的国际专线服务,与 CN2 GIA 相似。
|
||||
- 国际访问的优化效果一般优于 CMNET,但在稳定性和延迟上稍逊于 CN2。
|
||||
|
||||
## 三大运营商骨干网络的对比
|
||||
|
||||
|特性|中国电信(CN2)|中国移动(CMNET)|中国联通(CNCNET)|
|
||||
|---|---|---|---|
|
||||
|**国际访问质量**|优秀(特别是 CN2 GIA)|较差(国际延迟较高)|良好(优于 CMNET,低于 CN2)|
|
||||
|**国内访问优化**|优秀|优秀|优秀|
|
||||
|**网络稳定性**|高|中|中高|
|
||||
|**国际出口带宽**|较大(特别是 CN2 GIA)|一般|较大|
|
||||
|**用户群体**|普通用户和高端用户|普通家庭用户|普通用户和企业用户|
|
||||
|**性价比**|中(CN2 GIA 成本较高)|高|中|
|
||||
|**适用场景**|高端国际通信需求、游戏、企业网络|日常家庭网络|国际通信和企业网络|
|
||||
|
||||
## 中国电信(China Telecom)
|
||||
|
||||
### 出口线路
|
||||
|
||||
- **CN2(ChinaNet Next Carrying Network)**
|
||||
- **CN2 GIA(Global Internet Access)**:专为高端国际访问设计,低延迟、高稳定性,适合企业和高要求用户。
|
||||
- **CN2 GT(Global Transit)**:面向普通用户,质量较好,但优先级低于 GIA。
|
||||
- **163 骨干网(ChinaNet)**:普通用户常用的传统网络,国际出口较慢,路径复杂,延迟和丢包率较高。
|
||||
|
||||
### 适用场景
|
||||
|
||||
- **CN2 GIA**:跨境电商、视频会议、外贸企业、高质量需求的国际访问。
|
||||
- **CN2 GT**:一般国际访问需求。
|
||||
- **163 网**:低成本国际访问,但不适合高要求场景。
|
||||
|
||||
## 中国移动(China Mobile)
|
||||
|
||||
### 出口线路
|
||||
|
||||
- **CMNET(China Mobile Network)**
|
||||
- 中国移动的传统骨干网,出口优化主要面向国内用户,国际访问体验一般。
|
||||
- **CMI(China Mobile International)**
|
||||
- 中国移动为国际通信专门设置的网络品牌,近年来逐步优化跨境流量。
|
||||
|
||||
### 适用场景
|
||||
|
||||
- 性价比高,适合对国际访问要求不高的普通家庭用户。
|
||||
- 对国际通信优化有限,适合轻量级跨境应用(如普通浏览、邮件)。
|
||||
|
||||
## 中国联通(China Unicom)
|
||||
|
||||
### 出口线路
|
||||
|
||||
- **CNCNET(China Unicom Network)**
|
||||
- 中国联通的骨干网络,对国际流量有较好的优化。
|
||||
- **联通国际专线**:
|
||||
- 提供类似于 CN2 GIA 的高端国际线路,专注于企业和高质量用户。
|
||||
|
||||
### 适用场景
|
||||
|
||||
- 对国际访问体验要求较高,但预算较低于 CN2 GIA 的场景。
|
||||
- 北美、欧洲等地区访问表现优于 CMNET。
|
||||
|
||||
## 香港运营商和特殊线路
|
||||
|
||||
部分用户会选择通过香港运营商或专线出墙,这些线路可以绕开中国大陆的国际出口限制。
|
||||
|
||||
### 常见的香港线路
|
||||
|
||||
- **PCCW(电讯盈科)**:香港最大的国际出口提供商,性能优秀,适合高质量国际访问。
|
||||
- **HKT(香港电讯)**:服务家庭用户和中小企业,提供稳定的国际出口。
|
||||
- **HKBN(香港宽频)**:以性价比闻名,适合预算有限的用户。
|
||||
|
||||
### 国际专线
|
||||
|
||||
- **IPLC(International Private Leased Circuit)**:点对点的国际专线,适合跨境企业的高质量通信需求。
|
||||
- **IEPL(International Ethernet Private Line)**:类似 IPLC,但基于以太网技术,成本较低。
|
||||
|
||||
## 主要跨境通信方式
|
||||
|
||||
### 海底光缆
|
||||
|
||||
中国的网络国际出口高度依赖于多条海底光缆连接:
|
||||
|
||||
- **亚太地区(APCN-2, AAG)**:连接中国与日本、韩国、东南亚国家。
|
||||
- **欧美地区(SMW-3, FLAG, TPE)**:连接中国与北美和欧洲。
|
||||
- **跨太平洋光缆(TPE)**:主要负责中美之间的高速通信。
|
||||
|
||||
---
|
||||
|
||||
## 总结:中国出墙的主要运营商和骨干网络
|
||||
|
||||
| 运营商 | 网络干线 | 特点 |
|
||||
| ----- | ---------------------- | ------------------------------------ |
|
||||
| 中国电信 | CN2 GIA, CN2 GT, 163 网 | 高端用户选 CN2 GIA;普通用户多使用 163 网,性能较差。 |
|
||||
| 中国移动 | CMNET, CMI | 性价比高,但国际访问体验一般,适合国内为主、国际需求轻的用户。 |
|
||||
| 中国联通 | CNCNET, 联通国际专线 | 国际出口较稳定,性能介于电信和移动之间,适合国际需求适中的场景。 |
|
||||
| 香港运营商 | PCCW, HKT, HKBN | 高质量的国际访问,适合对网络质量有高要求的企业和个人。 |
|
||||
| 国际专线 | IPLC, IEPL | 高带宽低延迟,但成本较高,适合跨境业务场景(如外贸、电商、视频会议等)。 |
|
||||
Reference in New Issue
Block a user