概要

本文记录我初始化 Linux 服务器的 标准作业程序(SOP) ,这并非通用指南,仅作为个人快速部署环境的速查手册。

关联阅读:

性能测试

我要「验牌」(法国音~)

刚拿到服务器机器,在重装系统前,建议对 Linux 服务器的硬件性能进行一次基准测试,使用 root 用户执行 YABS (Yet Another Bench Script) 脚本:

1
curl -sL yabs.sh | bash -s -- -5

下面是一个测试结果示例:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
root@ncrs1000:~# curl -sL yabs.sh | bash -s -- -5

# ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## #

#              Yet-Another-Bench-Script              #

#                     v2025-04-20                    #

# https://github.com/masonr/yet-another-bench-script #

# ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## #

Sat Feb 28 04:59:28 AM CET 2026

Basic System Information:

---------------------------------

Uptime     : 0 days, 0 hours, 1 minutes

Processor  : AMD EPYC 9634 84-Core Processor

CPU cores  : 4 @ 2246.622 MHz

AES-NI     : ✔ Enabled

VM-x/AMD-V : ❌ Disabled

RAM        : 7.8 GiB

Swap       : 0.0 KiB

Disk       : 503.9 GiB

Distro     : Debian GNU/Linux 13 (trixie)

Kernel     : 6.12.73+deb13-amd64

VM Type    : KVM

IPv4/IPv6  : ✔ Online / ✔ Online

IPv4 Network Information:

---------------------------------

ISP        : netcup GmbH

ASN        : AS197540 netcup GmbH

Host       : netcup GmbH

Location   : Karlsruhe, Baden-Wurttemberg (BW)

Country    : Germany

fio Disk Speed Tests (Mixed R/W 50/50) (Partition /dev/vda3):

---------------------------------

Block Size | 4k            (IOPS) | 64k           (IOPS)

  ------   | ---            ----  | ----           ----

Read       | 174.89 MB/s  (43.7k) | 716.07 MB/s  (11.1k)

Write      | 175.35 MB/s  (43.8k) | 719.84 MB/s  (11.2k)

Total      | 350.25 MB/s  (87.5k) | 1.43 GB/s    (22.4k)

           |                      |

Block Size | 512k          (IOPS) | 1m            (IOPS)

  ------   | ---            ----  | ----           ----

Read       | 1.29 GB/s     (2.5k) | 1.89 GB/s     (1.8k)

Write      | 1.36 GB/s     (2.6k) | 2.01 GB/s     (1.9k)

Total      | 2.65 GB/s     (5.1k) | 3.91 GB/s     (3.8k)

iperf3 Network Speed Tests (IPv4):

---------------------------------

Provider        | Location (Link)           | Send Speed      | Recv Speed      | Ping

-----           | -----                     | ----            | ----            | ----

Clouvider       | London, UK (10G)          | 1.85 Gbits/sec  | 1.19 Gbits/sec  | 15.0 ms

Eranium         | Amsterdam, NL (100G)      | 2.69 Gbits/sec  | 2.36 Gbits/sec  | 10.1 ms

Uztelecom       | Tashkent, UZ (10G)        | 2.49 Gbits/sec  | 1.14 Gbits/sec  | 82.2 ms

Leaseweb        | Singapore, SG (10G)       | 577 Mbits/sec   | 1.79 Gbits/sec  | --

Clouvider       | Los Angeles, CA, US (10G) | 1.10 Gbits/sec  | 442 Mbits/sec   | 158 ms

Leaseweb        | NYC, NY, US (10G)         | 2.21 Gbits/sec  | 2.14 Gbits/sec  | 89.9 ms

Edgoo           | Sao Paulo, BR (1G)        | 2.13 Gbits/sec  | 785 Mbits/sec   | 217 ms

iperf3 Network Speed Tests (IPv6):

---------------------------------

Provider        | Location (Link)           | Send Speed      | Recv Speed      | Ping

-----           | -----                     | ----            | ----            | ----

Clouvider       | London, UK (10G)          | 2.71 Gbits/sec  | busy            | 14.8 ms

Eranium         | Amsterdam, NL (100G)      | 2.69 Gbits/sec  | 2.31 Gbits/sec  | 10.1 ms

Uztelecom       | Tashkent, UZ (10G)        | 2.38 Gbits/sec  | 1.91 Gbits/sec  | 82.2 ms

Leaseweb        | Singapore, SG (10G)       | 2.15 Gbits/sec  | 1.86 Gbits/sec  | --

Clouvider       | Los Angeles, CA, US (10G) | 1.10 Gbits/sec  | 593 Mbits/sec   | 157 ms

Leaseweb        | NYC, NY, US (10G)         | 2.21 Gbits/sec  | 2.11 Gbits/sec  | 89.9 ms

Edgoo           | Sao Paulo, BR (1G)        | 1.95 Gbits/sec  | 591 Mbits/sec   | 217 ms

Geekbench 5 Benchmark Test:

---------------------------------

Test            | Value

                |

Single Core     | 1412

Multi Core      | 4832

Full Test       | https://browser.geekbench.com/v5/cpu/24146433

YABS completed in 8 min 44 sec

测试完成后,首先核对 CPU、内存、硬盘容量及网络带宽等基础信息,确认是否与服务商的承诺相符。

其次,Geekbench 5 的单核跑分是衡量服务器绝对性能的核心指标,我们可以按以下几个梯队来评估其可用性:

  • 单核 400 分左右: 入门级性能,适合运行简单的代理服务、静态网页、轻量级定时任务或个人博客,不适合处理高并发或高性能占用的应用;
  • 单核 800 分左右: 主流及格线,足以应对日常建站需求,例如稳定运行中等流量的 WordPress、部署基础的 Docker 容器、搭建个人网盘或小型数据库;
  • 单核 1200 分左右: 优秀的高性能表现,能够流畅承载负载较重的 Web 应用、中型关系型数据库(MySQL/PostgreSQL)、CI/CD 流水线,以及多容器并行运行;
  • 单核 2000 分以上: 顶级的旗舰性能,计算能力充沛,完美胜任吃单核性能的游戏服务端、重度视频转码、高并发电商后端及复杂的数据处理。

此外,对于 KVM 虚拟化的服务器,多核得分通常应大致等于 核心数 × 单核得分 。如果比例严重失衡,通常意味着服务器存在严重的超售现象,「邻居」抢占资源的情况较为恶劣,实际体验会大打折扣。

如果以上结果都没啥问题,现在就可以开始设置新服务器,准备使用了。

重装操作系统

重装有风险,本文不为任何脚本的安全性背书,请自行衡量并承担后果。如果条件允许,请尽可能使用自定义 ISO 镜像手动安装。

使用一键 DD 脚本

对于不支持自定义 ISO 镜像的服务商,使用一键 DD 脚本比较方便。开始前,务必花费几分钟读下作者的说明文档,这远比盲目粘贴命令重要。

  1. bin456789/reinstall 支持重装的系统类型更多
  2. bohanwood/debi 专注于纯净、精简的 Debian 系统环境

以 Oracle ARM 机器安装 Debian 为例,使用 debi 脚本的操作流程如下:

下载脚本

1
curl -fLO https://raw.githubusercontent.com/bohanyang/debi/master/debi.sh && chmod +x debi.sh

重装配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
sudo ./debi.sh \

  --version 13 \

  --architecture arm64 \

  --cloudflare \

  --user viamoe \

  --authorized-keys-url https://github.com/githubUserName.keys \

  --ssh-port 22122

参数说明:

  • --version 13 指定 Debian 13(代号 Trixie
  • --architecture arm64 指定系统架构,这里的 arm64 匹配 ARM 架构机器
  • --cloudflare 预设 Cloudflare 作为默认 DNS
  • --user viamoe 创建具有 sudo 权限的普通用户 viamoe
  • --authorized-keys-url https://github.com/githubUserName.keys 导入 SSH 公钥,实现无密码登录
  • --ssh-port 22122 更改默认 SSH 端口,规避低级暴力扫描

开始重装

重启后,机器将自动联网重装系统

1
sudo reboot

期间可通过 VNC 观察安装进度,一般几分钟后新系统即可就绪。

使用自定义 ISO 镜像

若服务商支持上传自定义 ISO 镜像手动安装,这是最为推荐的方式,能让我们从源头掌控系统环境的纯净度。针对 Netcup 服务器的具体操作可参考: Netcup 服务器安装自定义 ISO 镜像

完成重装后,使用预设的用户凭据登录,开始后续配置。

配置用户

赋予普通用户 sudo 权限,方便后续使用和管理。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# 切换到 root 用户

su

# 安装 sudo

apt update && apt install -y sudo

# sudo 免密码

# 替换 dejavu 为实际用户名

echo "dejavu ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/dejavu

# 设置权限

chmod 440 /etc/sudoers.d/dejavu

# 退出 root 用户

exit

安装基础软件包

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
sudo apt update && apt upgrade

sudo apt install \

    apt-transport-https \

    build-essential \

    git \

    curl \

    wget \

    unzip \

    tmux \

    btop \

    bind9-dnsutils \

    tree \

    vim

SSH 安全加固

配置公钥登录

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 创建公钥目录

mkdir -p ~/.ssh

# 粘贴 SSH 公钥

vim ~/.ssh/authorized_keys

# 或者上传 SSH 公钥

# ssh -i /path/to/your/ed25519_key username@<IP> -p <port>

chmod 700 ~/.ssh

chmod 600 ~/.ssh/authorized_keys

优化 SSH 配置

1
sudo vim /etc/ssh/sshd_config

重点修改以下配置:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# 修改默认 SSH 端口

Port 22122

# 登录宽限时间

# 超过 1 分钟不输入密码/密钥自动断开

LoginGraceTime 1m

# 禁止 root 用户直接登录

PermitRootLogin no

# 严格模式,检查主目录权限

StrictModes yes

# 开启 SSH 公钥登录方式

PubkeyAuthentication yes

# 禁止传统密码登录方式

PasswordAuthentication no

# 禁止空密码登录

PermitEmptyPasswords no

# 禁用键盘交互式认证(防止通过 PAM 绕过密码限制)

KbdInteractiveAuthentication no

# Debian 默认需要 yes,否则可能会影响部分会话功能。

UsePAM yes

# 关闭 X11 转发

X11Forwarding no

# 保持 SSH 会话连接

# 服务器每 60 秒发一次心跳包

ClientAliveInterval 60

# 如果客户端 5 次没回应才断开

ClientAliveCountMax 5

# 禁止 DNS 反向解析

UseDNS no

保持当前终端会话,新开一个 SSH 连接,确认正常,否则回到保持的 SSH 会话中检查配置。

1
2
3
4
5
6
7
# 检查 SSH 配置

sudo sshd -t

# 使新的 SSH 配置生效

sudo systemctl restart sshd

IPv6 静态路由

Netcup 服务器提供 /64 的 IPv6,建议设置静态路由(不同服务商配置有所区别)

1
sudo vim /etc/network/interfaces

添加

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
iface ens3 inet6 static

    address <静态 IPv6 地址>

    netmask 64

    # Netcup network gateway

    gateway fe80::1

    # 接受路由公告

    accept_ra 2

然后执行

1
sudo ip addr flush dev ens3

更换 Linux 内核

推荐使用针对虚拟化优化、更加轻量和高效的 Cloud 内核。

1
sudo apt install -y linux-image-cloud-amd64

重启加载新内核

1
2
3
4
5
6
7
sudo reboot

uname -r

# 输出

6.12.63+deb13-cloud-amd64

清理旧内核

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 列出已安装的内核包

sudo dpkg --list | grep linux-image

# 输出示例

ii  linux-image-6.12.63+deb13-amd64       6.12.63-1                            amd64        Linux 6.12 for 64-bit PCs (signed)

ii  linux-image-6.12.63+deb13-cloud-amd64 6.12.63-1                            amd64        Linux 6.12 for x86-64 cloud (signed)

ii  linux-image-amd64                     6.12.63-1                            amd64        Linux for 64-bit PCs (meta-package)

ii  linux-image-cloud-amd64               6.12.63-1                            amd64        Linux for x86-64 cloud (meta-package)

# 移除常规内核元包及具体版本(请根据实际输出的版本号替换)

sudo apt purge -y linux-image-amd64 linux-image-6.12.63+deb13-amd64

# 更新引导

sudo update-grub

# 运行清理

sudo apt autoremove --purge -y

安装 Docker

参考 Docker 官方文档 说明的步骤,下列命令不保证时效性

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 添加 Docker 官方的 GPG 密钥

sudo apt-get update

sudo apt-get install ca-certificates curl

sudo install -m 0755 -d /etc/apt/keyrings

sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc

sudo chmod a+r /etc/apt/keyrings/docker.asc

# 添加软件源

echo \

  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \

  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \

  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

sudo systemctl status docker

补充资料: 给 Docker 启用 IPv6 支持

安装 Nginx

同样地,参考 Nginx 项目文档——在 Debian 上的 安装步骤

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
sudo apt install curl gnupg2 ca-certificates lsb-release debian-archive-keyring

# 导入 GPG 密钥

curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \

    | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null

    

# 验证 GPG 密钥

mkdir -m 700 ~/.gnupg

gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg

echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \

http://nginx.org/packages/debian \`lsb_release -cs\` nginx" \

    | sudo tee /etc/apt/sources.list.d/nginx.list

# 设置仓库锁定,优先使用 Nginx 官方提供的软件包

echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \

    | sudo tee /etc/apt/preferences.d/99nginx

# 安装 Nginx

sudo apt update && sudo apt install nginx

# 启动 Nginx

sudo systemctl start nginx

使用自签 SSL/TLS 证书,设置 Nginx 默认回退 (Fallback) 虚拟主机。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 准备目录

sudo mkdir -p /etc/nginx/cert

sudo chmod 700 /etc/nginx/cert

# 生成证书

sudo openssl req -x509 -new -nodes -newkey rsa:2048 \

  -sha256 \

  -days 3650 \

  -keyout /etc/nginx/cert/deny.key \

  -out /etc/nginx/cert/deny.pem \

  -subj "/C=XX/ST=Denied/L=Denied/O=Denied/CN=invalid.local" \

  -addext "subjectAltName=DNS:invalid.local"

  

# 设置权限

sudo chmod 600 /etc/nginx/cert/deny.key

sudo chmod 644 /etc/nginx/cert/deny.pem

新建虚拟主机配置文件

1
sudo vim /etc/nginx/conf.d/00-default.conf

内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
server {

    listen 80 default_server;

    listen [::]:80 default_server;

    server_name _;

    return 444; 

}

server {

    listen 443 ssl default_server;

    listen [::]:443 ssl default_server;

    server_name _;

    

    ssl_certificate /etc/nginx/cert/deny.pem; 

    ssl_certificate_key /etc/nginx/cert/deny.key;

    ssl_protocols TLSv1.2 TLSv1.3;

    ssl_prefer_server_ciphers off;

    error_page 497 =444 /dev/null;

    return 444;

}

重载 Nginx 配置

1
2
3
sudo nginx -t

sudo nginx -s reload

设置 ZRAM 和 Swap

合理配置 ZRAM 和 Swap,平衡硬盘 I/O 性能和 CPU 开销。

配置 ZRAM

ZRAM 通过在 RAM 中划分一块区域压缩,速度远快于硬盘上的 Swap 空间。

1
2
3
# 安装 zram-tools 管理工具

sudo apt update && sudo apt install -y zram-tools

编辑 ZRAM 配置

1
sudo vim /etc/default/zramswap

参数说明:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 选择 zstd 算法,最佳平衡压缩比和速度

ALGO=zstd

# 分配 ZRAM 比例

# 1GB RAM 建议 100%

# 2~4GB RAM 建议 60%

# 8GB RAM 以上建议 25%

PERCENT=70

# 优先级 100,确保系统优先使用 ZRAM

PRIORITY=100

让 ZRAM 配置生效

1
sudo systemctl restart zramswap

配置 Swap

Swapfile 比 Swap 分区更为灵活

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 创建 2GB 的 Swapfile

# 1024 * 2 = 2048

sudo dd if=/dev/zero of=/swapfile bs=1M count=2048 status=progress

# 设置权限

sudo chmod 600 /swapfile

# 格式化

sudo mkswap /swapfile

# Swap 启用优先级低于 ZRAM

sudo swapon --priority -2 /swapfile

# 启动时自动挂载

echo '/swapfile none swap sw,pri=-2 0 0' | sudo tee -a /etc/fstab

# 检查挂载

sudo mount -a

系统内核调整

根据物理 RAM 大小,调整设置系统使用 Swap 的「积极性」。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 1GB RAM(激进)

echo "vm.swappiness=100" | sudo tee -a /etc/sysctl.conf

# 2GB/4GB RAM(积极)

echo "vm.swappiness=60" | sudo tee -a /etc/sysctl.conf

# 8GB RAM 以上(保守)

echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.conf

对于 2GB RAM 以下的机器,应当更倾向于释放文件缓存:

1
echo "vm.vfs_cache_pressure=50" | sudo tee -a /etc/sysctl.conf

应用配置

1
sudo sysctl -p

验证状态

1
2
3
sudo swapon --show

sudo zramctl

SSD Trim 优化

如果 VPS/VDS 使用的是 NVMe SSD,建议启用 Trim 自动优化。

1
2
3
# 定时任务

sudo systemctl enable --now fstrim.timer

并非所有服务商提供的 VPS/VDS 都支持 Trim,可以验证下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# DISC-MAX 列不为 0

lsblk -D

NAME   DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO

sr0           0        0B       0B         0

zram0         0        4K       2T         0

vda           0      512B       2G         0

├─vda1        0      512B       2G         0

└─vda2        0      512B       2G         0

# 尝试手动触发

sudo fstrim -v /

/: 434.4 GiB (466435428352 bytes) trimmed

NTP 时区同步

设置 UTC 时区

无论服务器位于何处,我都习惯将时区统一设置为 UTC(世界协调时),避免跨时区运维时产生的日志混乱和时间差纠纷,是一个非常省心的「隐性福利」。

1
sudo timedatectl set-timezone UTC

使用 Chrony 同步时间

与默认的 systemd-timesyncd 比,Chrony 的精度和性能更佳。

1
2
3
4
5
# 安装 Chrony 客户端

sudo apt update

sudo apt install chrony -y

添加 NTP 服务器

1
sudo vim /etc/chrony/chrony.conf

注释默认的 poolserver 行,添加 Cloudflare NTP 节点:

1
2
3
4
5
6
7
server time.cloudflare.com iburst

server time.cloudflare.com iburst

server time.cloudflare.com iburst

server time.cloudflare.com iburst

启动 Chrony 服务

1
2
3
sudo systemctl mask systemd-timesyncd.service

sudo systemctl enable --now chrony

验证同步状态

1
chronyc sources -v

配置 nftables 防火墙

nftables 是 Linux 内核现代化的包过滤框架。在 Debian 13 中,我们应该摒弃过时的 iptables 和 UFW,直接拥抱原生且高效的 nftables。

检查环境

从 Debian 10 开始,nftables 是默认安装的,但通常处于未启用状态,检查:

1
2
3
4
5
6
7
# 确保 nftables 已安装

sudo apt update && sudo apt install nftables -y

# 默认 inactive 状态是正常的

sudo systemctl status nftables

若此前安装过 UFW,建议卸载以免冲突

1
sudo ufw disable && sudo apt purge ufw -y

理解配置

在编写规则前,只需掌握三个层级:

  • 表(Table) :规则的顶级容器
  • 链(Chain) :绑定在网络钩子(INPUT/FORWARD/OUTPUT)上的规则集,定义默认策略(Drop 或 Accept)
  • 规则(Rule) :具体的匹配条件与行动

开始使用

以下配置是典型的「安全」服务器方案:仅允许 Cloudflare CDN 回源访问 80/443 端口,除 SSH 端口外全部切断。

1
2
3
# 编辑配置文件

sudo vim /etc/nftables.conf

语法很简单,可以看注释

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#!/usr/sbin/nft -f

# 刷新规则

flush ruleset

table inet filter {

    # ============================================================

    # IP 集合 (Sets)

    # ============================================================

    set cloudflare_v4 {

        type ipv4_addr; flags interval;

        elements = {

            173.245.48.0/20,

            103.21.244.0/22,

            103.22.200.0/22,

            103.31.4.0/22,

            141.101.64.0/18,

            108.162.192.0/18,

            190.93.240.0/20,

            188.114.96.0/20,

            197.234.240.0/22,

            198.41.128.0/17,

            162.158.0.0/15,

            104.16.0.0/13,

            104.24.0.0/14,

            172.64.0.0/13,

            131.0.72.0/22

        }

    }

    set cloudflare_v6 {

        type ipv6_addr; flags interval;

        elements = {

            2400:cb00::/32,

            2606:4700::/32,

            2803:f800::/32,

            2405:b500::/32,

            2405:8100::/32,

            2a06:98c0::/29,

            2c0f:f248::/32

        }

    }

    # ============================================================

    # INPUT 链 (入站)

    # ============================================================

    chain input {

       # 规则外流量拒绝

        type filter hook input priority filter; policy drop;

        # 放行已建立连接

        ct state established, related accept

        # 丢弃无效包

        ct state invalid drop

        # 允许回环接口

        iif "lo" accept

        # 允许 IPv6 NDP

        ip6 nexthdr icmpv6 icmpv6 type { nd-neighbor-solicit, nd-neighbor-advert, nd-router-advert } accept

        # 允许 ICMP (速率限速)

        ip protocol icmp limit rate 4/second accept

        ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate 4/second accept

        # 允许 SSH 端口

        tcp dport 22122 accept

        # 仅限 Cloudflare IP 段访问 80/443

        ip saddr @cloudflare_v4 tcp dport { 80, 443 } accept

        ip6 saddr @cloudflare_v6 tcp dport { 80, 443 } accept

    }

    # ============================================================

    # FORWARD 链 (转发)

    # ============================================================

    chain forward {

        # 规则外流量拒绝

        type filter hook forward priority filter; policy drop;

        # 放行已建立连接

        ct state established, related accept

        # 丢弃无效包

        ct state invalid drop

        # 允许 Docker 出站 (覆盖默认网桥和自定义网桥)

        iifname "docker0" accept

        iifname "br-*" accept

        # 允许 Docker 容器间通信

        iifname "docker0" oifname "docker0" accept

        iifname "br-*" oifname "br-*" accept

    }

    # ============================================================

    # OUTPUT 链 (出站)

    # ============================================================

    chain output {

        # 默认允许所有出站

        type filter hook output priority filter; policy accept;

    }

}

应用规则

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 检查语法

sudo nft -c -f /etc/nftables.conf

# 启动服务

sudo systemctl enable --now nftables

# Docker 重启后会自动注入规则

sudo systemctl restart nftables && sudo systemctl restart docker

# 测试 Docker 出站

sudo docker run --rm busybox ping -c 4 dejavu.moe

安装配置 Fail2ban

1
2
3
4
5
6
7
# 安装 Fail2ban

sudo apt update && sudo apt install fail2ban -y

# 创建一个最小的 SSH 服务保护配置

sudo vim /etc/fail2ban/jail.local

配置内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
[DEFAULT]

# 本机地址自动忽略,防止误封自己

ignoreip = 127.0.0.1/8 ::1

# 封禁 1 天

bantime  = 1d

# 在 10 分钟内累计失败即触发

findtime = 10m

# 触发封禁的失败次数阈值

maxretry = 3

# 自动 nftables 规则插入

banaction = nftables-multiport

banaction_allports = nftables-allports

[sshd]

# 启用 SSH 保护

enabled = true

# SSH 服务的监听端口(务必正确匹配)

port    = 22122

# 使用 systemd 日志后端

backend = systemd

# 严格地匹配失败日志

mode    = aggressive

启动 Fail2ban 服务

1
2
3
sudo systemctl enable --now fail2ban

sudo systemctl restart nftables && sudo systemctl restart fail2ban

测试一下封禁

1
2
3
4
5
6
7
# 封禁一个「黑户」

sudo fail2ban-client set sshd banip 2400:6180:0:d2:0:2:9699:d000

# 检查 nftables 规则中是否存在 f2b 动态表

sudo nft list ruleset | grep f2b

检查 Fail2ban 配置

1
2
3
4
5
6
7
# 巡查「监狱」

sudo fail2ban-client status

# 查封禁 IP

sudo fail2ban-client status sshd

至此,一台纯净、安全的服务器已经准备就绪。Happy Hosting!