首页
许愿池
友情链接
留言板
访客统计
软件下载
WIN软件
MAC软件
关于站长
Search
1
飞牛圣体-网心云OES一代安装ARM版FnOS全过程
587 阅读
2
2023 玩客云root以及绝育教程 1.3版本
478 阅读
3
移动光猫吉比特GM232改桥接+开启IPV6+开启Telnet方法
432 阅读
4
服务器被植入流量劫持后门(跳转世界杯赌球网站)的排查与解决方案
402 阅读
5
飞牛系统(FnOS)挂载SMB目录并设置开机自启
351 阅读
人物
动物
风景
数码
网络
硬件
系统
建站
软件
MacOS
Windows
NAS
docker
esxi
AI
情感
登录
/
注册
Search
标签搜索
mac mini
DSM7
宝塔面板
apple
黑苹果
EOS R6
映泰
验证码
m4
photoshop
云层
风景
摄影
人像
儿童
刀马旦
艺术
万泰
吉比特
RD450X风扇控制程序
RongYan
累计撰写
65
篇文章
累计收到
193
条评论
今日撰写
0
篇文章
首页
栏目
人物
动物
风景
数码
网络
硬件
系统
建站
软件
MacOS
Windows
NAS
docker
esxi
AI
情感
页面
许愿池
友情链接
留言板
访客统计
软件下载
WIN软件
MAC软件
关于站长
用户登录
登录
注册
搜索到
1
篇与
服务器安全运维
的结果
2026-06-26
从零到一:Linux 服务器安全加固 + 日报监控完整部署指南
一、前言我的服务器半个月前中过木马,具体见这篇文章: 服务器被植入流量劫持后门(跳转世界杯赌球网站)的排查与解决方案 后门连着海外的C2服务器,Docker里还藏着挖矿程序。清理干净之后我意识到一件事:没有防护的服务器,在互联网上就像没锁门的房子,是条狗都能进来撒泡尿。于是我试着弄了这么一个日报程序,这套每日汇报方案是经过我自己实操用了多台服务器布署后的实践总结,囊括了Ubuntu、CentOS、Debain等市面上主流Linux服务器系统,从系统加固、SSH安全、fail2ban防暴力破解,到每天自动发邮件汇报安全状况。从程序写出来到今天为止,三天了,经过不断优化、更迭,差不多能达到我理想中的状态了,所以我把它分享出来,希望能帮到同样在维护服务器的你。2026-07-22 更新说明macOS 客户端多服务器数据隔离 — 按 serverID 分目录缓存,切换服务器后不显示旧服务器数据打开配置目录 — 界面增加按钮,一键打开 ~/.config/server-report/ 目录服务器 IP 默认隐藏 — 列表 IP 以 *** 显示,👁 按钮可切换显示/隐藏Windows 客户端多服务器数据隔离 — 按 serverID 分目录缓存,切换服务器后不显示旧服务器数据服务器 IP 默认隐藏 — 列表 IP 以 *** 显示,👁 按钮可切换显示/隐藏2026-07-08 更新说明服务端新增 /api/v1/dates 接口 — 返回服务器所有存档日期列表,客户端据此按需同步缺失数据SSH 审计支持日期过滤 — `归档时按指定日期查询,不再显示实时数据fail2ban "本日封禁" — 实时报告和归档统一按日期过滤 IP 列表,只显示当日新增封禁数,不显示历史累计值封禁时间零"未知" — 同时提取 IP 和时间,消除封禁时间显示未知的问题实时报告日期策略 — 默认显示当日数据API 响应精简 — server 字段返回空字符串(服务器名称已由客户端侧边栏显示)macOS windows 客户端数据同步 — 同步对应服务器新增接口,对比本地日期,缺失的自动下载;开屏、刷新、切换服务器均触发同步标题居中 —实现日历按钮右侧覆盖,标题绝对居中日期格式 — 仅显示当前数据显示的日期时间戳标签 — 加 查询时间: 前缀界面精简 — 标题去掉服务器名称行和图标;左侧已有服务器信息,没必要多次显示运行时间本地化 — 直接中文显示如“15天1小时19分钟”,更直观网络超时 — 配置 30s 请求超时、60s 资源超时,不无限卡 loading防重入 — 客户端同步数据优化,自动跳过已有数据,避免数据错乱或闪烁列宽优化 —优化显示,解决封禁时间显示不全的问题邮件发送优化`改用新版数据采集 — 邮件发送不再使用旧版文本采集函数,容易导致卡死),改为调用新函数获取结构化数据,再格式化为邮件正文新增 构建邮件文本 — 从 JSON 报告生成邮件文本,按模块独立格式化函数,类型安全依赖变更客户端新增依赖:服务端 /api/v1/dates 接口(2026-07-08 后更新的服务端版本)中国 IP 市县细化依赖:ip-api.com(geoLookupDetail 接口),需服务器能访问外网2026-06-30 更新说明服务端增加api key功能,供客户端调用增加 Windows、macOS 客户端(付费)服务端改为定时采集 + 文件缓存策略,客户端查询毫秒级响应数据保留 180 天,每天自动清理超期数据服务端源代码、预编译二进制同步更新二、系统初始化2.1 更新系统刚买的服务器系统包可能比较旧,先更新到最新版本,避免因为旧版本的已知漏洞被入侵。# ------------------- Ubuntu / Debian 系统 ------------------- # apt 是 Ubuntu/Debian 的包管理器 # update = 更新软件源列表(检查有哪些新版本可用) # upgrade -y = 升级所有已安装的软件包(-y 表示自动确认,不弹询问) apt update && apt upgrade -y # ------------------- CentOS 系统 ------------------- # yum 是 CentOS 的包管理器,update 同时更新源和升级包 yum update -y2.2 安装基础工具安装一些后续操作会用到的常用命令行工具。工具作用curl用来下载文件、调用 API、测试网络请求wget下载文件(和 curl 类似,但更专注于文件下载)git用来克隆代码仓库(如果需要从 GitHub 下载源码时用到)vim一个命令行文本编辑器(编辑配置文件用)# ------------------- Ubuntu / Debian ------------------- apt install -y curl wget git vim # ------------------- CentOS ------------------- yum install -y curl wget git vim2.3 设置时区把服务器的时间设成北京时间(CST,东八区)。否则定时任务(比如每天 00:01 发日报)会按 UTC 时间执行,和你的预期差 8 个小时。# 设置时区为亚洲/上海(北京时间) timedatectl set-timezone Asia/Shanghai # 查看当前时间,确认是否生效 date # 正常应该输出类似:Thu Jun 25 00:01:00 CST 2026 # 注意末尾的 CST 表示中国标准时间2.4 设置主机名给服务器起一个容易辨识的名字,这样在终端提示符、邮件标题里都能看到,方便区分多台服务器。# 把 your-server-name 换成你想取的名字,例如: # hostnamectl set-hostname web-server # hostnamectl set-hostname mail-server hostnamectl set-hostname your-server-name三、SSH 安全加固(最重要的一步 ⭐)3.1 修改默认 SSH 端口SSH 默认端口 22 是互联网上扫描器的首选目标,新服务器上线几分钟内就会被扫描。改成一个不常用的高位端口,能过滤掉 99% 的自动扫描。# 用 vim 打开 SSH 配置文件(vim 是命令行文本编辑器) # 如果不会用 vim,也可以用 nano:nano /etc/ssh/sshd_config vim /etc/ssh/sshd_config在文件中找到这一行(一般在第 15 行左右):#Port 22把 # 删掉(去掉注释),把 22 改成你选的高位端口:Port 32958选端口的建议:✅ 推荐:32958、23254、18957、42196(4-5 位数字,好记就行)❌ 避免:2222、22222、8822(这些常见替代端口一样会被扫描)❌ 避免:22 附近的端口(21、23 等也会被批量扫描)三种系统注意: SSH 配置文件都在 /etc/ssh/sshd_config,位置一样,没有区别。3.2 生成密钥对(在自己电脑上操作,不是服务器)服务器登录方式有两种:密码(会被暴力破解)和密钥(几乎不可能被破解)。密钥登录的原理是生成一对文件——私钥和公钥。私钥你留着,公钥放服务器上,登录时服务器验证你是否有对应的私钥。没有私钥的人就算知道密码也登录不了。# 在你自己电脑的终端执行(Mac 的「终端」、Windows 的 PowerShell) # -t ed25519 = 指定密钥加密算法(ed25519 是目前最安全的) # -f ~/.ssh/... = 指定密钥保存路径,后面的名字改成你的服务器名方便管理 ssh-keygen -t ed25519 -f ~/.ssh/服务器名称_密钥执行后会问两次密码短语(passphrase),直接按两下回车跳过——这样登录时不需要额外输入。完成后,在 ~/.ssh/ 目录下会生成两个文件:~/.ssh/服务器名称_密钥 ← 私钥(相当于你的钥匙,绝对不能给别人看) ~/.ssh/服务器名称_密钥.pub ← 公钥(相当于锁芯,放在服务器上)⚠️ 私钥必须妥善保管,谁拿到它就能登录你的服务器,不要上传到公共代码仓库,不要复制到不安全的设备上。3.3 上传公钥到服务器把上一步生成的公钥(.pub 文件)放到服务器的 authorized_keys 文件中。有两种方式:方式一:用 ssh-copy-id(推荐,最简单)# -p 32743 = 指定 SSH 端口(改成你上一步设置的新端口) # -i ~/.ssh/xxx.pub = 指定公钥文件 # root@你的服务器IP = 以 root 用户登录你的服务器 ssh-copy-id -p 32743 -i ~/.ssh/服务器名称_密钥.pub root@你的服务器IP按提示输入当前 root 密码即可。命令会自动把公钥追加到服务器的正确位置。方式二:手动上传(如果方式一不可用)# 第一步:在服务器上创建 .ssh 目录(设置正确权限) ssh -p 32743 root@你的服务器IP "mkdir -p ~/.ssh && chmod 700 ~/.ssh" # 第二步:把本地公钥内容追加到服务器上的 authorized_keys 文件 cat ~/.ssh/服务器名称_密钥.pub | ssh -p 32743 root@你的服务器IP \ "cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"3.4 禁用密码登录,锁定 SSH 配置密钥上传成功后,就可以关闭不安全的密码登录方式了。再次编辑 SSH 配置文件:vim /etc/ssh/sshd_config把以下几项逐一修改(可以直接找到对应行改,也可以直接替换整个文件内容):# ===== 端口(改成你前面设置的值)===== Port 32743 # ===== 只允许 SSH 协议版本 2(版本 1 有已知漏洞)===== Protocol 2 # ===== 允许 root 登录,但只接受密钥方式(prohibit-password = 禁止密码)===== PermitRootLogin prohibit-password # ===== 启用公钥认证(刚才上传的密钥就是靠这个选项生效)===== PubkeyAuthentication yes # ===== 禁止密码认证(这步做完后,没有密钥就登录不了)===== PasswordAuthentication no # ===== 也禁止其他不安全的认证方式===== ChallengeResponseAuthentication no # ===== 只接受公钥认证===== AuthenticationMethods publickey # ===== 最多允许 3 次认证失败===== MaxAuthTries 3 # ===== 最多 5 个同时连接===== MaxSessions 5 # ===== 每 5 分钟检测客户端是否还活着===== ClientAliveInterval 300 # ===== 连续 2 次没响应就断开===== ClientAliveCountMax 2 # ===== 30 秒内必须完成登录===== LoginGraceTime 30 # ===== 只允许 root 用户通过 SSH 登录===== AllowUsers root # ===== 日志记录到系统日志===== SyslogFacility AUTH LogLevel VERBOSE # ===== 禁止 X11 转发(一般用不上)===== X11Forwarding no # ===== 只允许用安全的加密算法(防止算法攻击)===== KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256 Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com3.5 重启 SSH 并验证配置改完后,需要重启 SSH 服务才能生效。# ------------------- Ubuntu / Debian ------------------- # Ubuntu 和 Debian 的 SSH 服务名是 ssh(注意不是 sshd) systemctl restart ssh # ------------------- CentOS ------------------- # CentOS 的 SSH 服务名是 sshd systemctl restart sshd最关键的一步:验证密钥登录是否正常# 新开一个终端窗口(千万不要关当前这个窗口),测试密钥登录 ssh -p 32743 -i ~/.ssh/服务器名称_密钥 root@你的服务器IP如果成功登录了,恭喜你,SSH 安全加固完成。⚠️ 重要:在确定新窗口能登录之前,绝对不要关闭当前的 SSH 窗口。 万一密钥配置有问题,你还能通过当前窗口修复。确认新窗口正常后,再关闭旧窗口。🔑 之后的登录方式——只能用密钥登录:# 每次连接都需要指定端口和密钥文件 ssh -p 32743 -i ~/.ssh/服务器名称_密钥 root@你的服务器IP为了方便,可以把配置写进 ~/.ssh/config(这样就不用每次敲端口和密钥了):# 在本地电脑执行 echo " Host my-server HostName 你的服务器IP Port 32743 User root IdentityFile ~/.ssh/服务器名称_密钥 " >> ~/.ssh/config之后只需要 ssh my-server 就能连上了。四、防火墙防火墙的作用是控制哪些端口对外开放,防止不必要的服务暴露在公网上。原则是:默认拒绝所有入站流量,只放行需要的端口。Ubuntu / Debian 用 UFWUFW是 Ubuntu/Debian 自带的防火墙管理工具,用起来很简单。# ------------------- 安装 UFW ------------------- apt install -y ufw # ------------------- 设置默认策略 ------------------- # 默认拒绝所有入站连接(别人连不上你的服务器) ufw default deny incoming # 默认允许所有出站连接(你的服务器可以正常访问外网) ufw default allow outgoing # ------------------- 放行必要的端口 ------------------- # 注意:32958 要改成你前面设置的 SSH 端口 ufw allow 32958/tcp comment 'SSH' # 如果你要跑网站,需要放行 80(HTTP)和 443(HTTPS) ufw allow 80/tcp comment 'HTTP' ufw allow 443/tcp comment 'HTTPS' # 如果后续部署了其他服务(如数据库、VPN 等),按需增加 # ufw allow 8080/tcp comment '自定义服务' # ------------------- 启用防火墙 ------------------- # --force 表示直接启用,不弹确认询问 ufw --force enable # ------------------- 查看规则 ------------------- ufw status numbered后续管理命令:# 放行新端口 ufw allow 12345/tcp comment '新服务' # 删除规则 ufw delete allow 12345/tcp # 查看日志(看哪些 IP 被拦截了) tail -f /var/log/ufw.logCentOS 用 firewalldCentOS 默认使用 firewalld 管理防火墙,用法和 UFW 不同,但效果一样。# ------------------- 安装 firewalld(通常已预装)------------------- yum install -y firewalld # 启动并设置开机自启 systemctl enable --now firewalld # ------------------- 放行必要的端口 ------------------- # --zone=public = 应用到公共区域 # --add-port=... = 允许的端口/协议 # --permanent = 永久生效(重启后保留) # 注意:32958 要改成你的 SSH 端口 firewall-cmd --zone=public --add-port= 32958/tcp --permanent firewall-cmd --zone=public --add-port=80/tcp --permanent firewall-cmd --zone=public --add-port=443/tcp --permanent # 重新加载使规则生效 firewall-cmd --reload # ------------------- 查看规则 ------------------- firewall-cmd --list-all五、fail2ban 防暴力破解(核心 ⭐)虽然前面已经禁用了密码登录,但攻击者仍然会尝试连接你的 SSH 端口。fail2ban 会监控系统日志,发现有人尝试登录失败就自动封禁它的IP,连尝试的机会都不给。5.1 安装# ------------------- Ubuntu / Debian ------------------- # fail2ban = 暴力破解防护工具 # geoip-bin = IP 归属地查询工具(让日报能显示攻击者来自哪个国家) apt install -y fail2ban geoip-bin # ------------------- CentOS ------------------- yum install -y fail2ban geoip5.2 配置策略创建一个自定义配置文件,覆盖默认的 SSH 防护规则:# 创建配置目录 mkdir -p /etc/fail2ban/jail.d # 写入配置文件(cat > 文件 << 'EOF' 的意思是:将下面几行内容写入到文件中) cat > /etc/fail2ban/jail.d/sshd-custom.conf << 'EOF' [sshd] enabled = true port = 32958 maxretry = 1 bantime = -1 findtime = 600 backend = systemd journalmatch = _SYSTEMD_UNIT=ssh.service + _COMM=sshd EOF配置参数详解:参数值含义enabledtrue启用这个规则port32958监控你的 SSH 端口(改成你自己设置的)maxretry11 次失败就封禁。因为我们已经禁用了密码登录,任何密码尝试都是恶意的bantime-1永久封禁(-1 表示永远,不解封)findtime600在 10 分钟窗口内累计失败次数backendsystemd通过 systemd 的 journal 读取 SSH 日志journalmatch_COMM=sshd匹配 SSH 进程的日志条目(不同系统有差异)5.3 journalmatch 适配(不同系统有区别)journalmatch 的值取决于你的系统 SSH 服务名,配置错了 fail2ban 就检测不到登录尝试。# ----- 查看你的 SSH 服务名(用这个命令确认)----- systemctl list-units --type=service | grep ssh # 根据输出结果选择对应的配置: # # 如果输出 ssh.service(Ubuntu/Debian 常见): journalmatch = _SYSTEMD_UNIT=ssh.service + _COMM=sshd # 如果输出 sshd.service(CentOS 常见): journalmatch = _SYSTEMD_UNIT=sshd.service + _COMM=sshd systemctl list-units --type=service | grep ssh # 确认 fail2ban 能正确匹配日志 journalctl -u ssh.service --since "-5 min" | grep "Invalid user\|Failed password"5.4 启动并验证# 重启 fail2ban 使配置生效 systemctl restart fail2ban # 等待 2 秒让服务完全启动 sleep 2 # 查看 SSH 防护状态 # 如果显示 Active: active (running) 说明启动成功 fail2ban-client status sshd输出示例:Status for the jail: sshd |- Filter | |- Currently failed: 0 ← 当前累计失败次数 | |- Total failed: 0 ← 总失败次数 `- Actions |- Currently banned: 0 ← 当前被封禁的 IP 数 |- Total banned: 0 ← 累计封禁的 IP 数测试 fail2ban 是否真的能封禁:# 打开一个新终端,故意输错密码登录一次 # 注意:这里用密码方式尝试,你的密钥不会触发封禁 ssh -p 32958 root@你的服务器IP # 随便输入一个错误密码 # 回到原来终端,再次查看封禁状态 fail2ban-client status sshd如果看到 Currently banned: 1,说明 fail2ban 生效了——这个 IP 永远不能再用 SSH 连接你的服务器了。5.5 子网自动封段(可选但推荐)如果你留意日报数据,会发现攻击 IP 经常来自同一个 C 段(比如 213.209.159.x 有十几个不同 IP 在换着尝试)。这时只封单个 IP 不够,应该把整个 /24 段一起封了。这个功能内置在日报程序里,每 30 分钟自动扫描一次 fail2ban 的封禁列表,如果发现同一个 C 段有 ≥2 个 IP 被封,就自动通过 iptables 封禁整个子网。# 在 config.yml 中启用: # subnet_ban: # enabled: true # threshold: 2 # 同 C 段 ≥2 个 IP 触发封段 # check_interval: 30 # 每 30 分钟扫描一次具体配置在下一章「部署日报程序」中详细说明。六、部署日报程序6.1、项目结构server-report/ ├── go/ # 服务端 Go 源码 │ ├── main.go # 入口(--serve 启动API) │ ├── config.go # 配置管理 │ ├── serve.go # HTTP API 服务器 │ ├── report_api.go # 日报数据构建 │ ├── report_json.go # JSON 数据模型 │ ├── fail2ban.go # fail2ban 管理 + 地理位置 │ ├── system.go # 系统信息采集 │ ├── ssh_auth.go # SSH 审计 │ ├── network.go # 网络连接分析 │ ├── firewall.go # 防火墙统计 │ ├── services.go # 服务列表 │ ├── changes.go # 系统变更追踪 │ ├── security.go # 安全检测 │ ├── mail.go # 邮件发送 │ ├── subnet.go # 子网封禁 │ └── util.go # 工具函数 ├── gosrc/ # 编译好的服务端二进制程序 │ ├── server-report │ └── config.yml # 示例配置 ├── Client/ # 客户端 │ ├── ServerReport.app # macOS,付费 │ └── ServerReport.exe # Windows 付费 └── README.md# 创建目录 mkdir -p /data/server-report cd /data/server-report # 下载二进制(替换为实际下载地址) 下载日报程序压缩包后,上传到/data/server-report目录并解压 chmod 755 server-report6.2、服务器端自行编译cd go GOOS=linux GOARCH=amd64 go build -o ../data/server-report .或者直接使用预编译的二进制 /data/server-report6.3、上传到服务器scp server-report root@你的服务器IP:/data/server-report/server-report scp config.sample.yml root@你的服务器IP:/data/server-report/config.sample.yml ssh root@你的服务器IP "mv /data/server-report/config.sample.yml /data/server-report/config.yml" ssh root@你的服务器IP "chmod +x /data/server-report/server-report"6.4 修改配置文件# 编辑配置文件 ssh root@你的服务器IP "vi /data/server-report/config.yml"server: name: "myserver" # 你的服务器名称(邮件标题中用) ip: "" # 留空自动获取公网 IP ssh_port: 32958 # 改成你自己的SSH登陆端口 api_key: "your-api-key-here" # API 密钥(建议32位大小写字母加数字) api_port: 8080 smtp: server: "mail.example.com" # SMTP 服务器地址 port: 465 # 465=SSL / 587=STARTTLS ssl: true user: "user@example.com" # SMTP帐号 password: "your-password" # SMTP密码 mail: to: "admin@example.com" # 接收日报的邮箱 from: "user@example.com" # 发件人地址 subject: "服务器日报 - {name} / {ip} - {date}" # 发件邮箱标题 schedule: report_at: "00:01" # 每天发送时间,24小时制 modules: system: true # 系统健康 ssh_auth: true # SSH 登录审计 fail2ban: true # fail2ban 封禁统计 network: true # 网络连接 firewall: false # 防火墙(UWF/firewalld 统计) services: true # 服务列表 changes: true # 系统变更 security: true # 安全检测 security: fail2ban: enabled: true maxretry: 1 bantime: -1 findtime: 600 journalmatch: "_SYSTEMD_UNIT=ssh.service + _COMM=sshd" subnet_ban: enabled: true # 是否启用子网自动封段 threshold: 2 # 同 C 段 ≥2 个 IP 被封时封整个段 check_interval: 30 # 每 30 分钟扫描一次6.4.1、配置文件说明字段说明默认值server.name服务器名称,用于邮件标题必填server.ip固定 IP,留空自动获取自动server.ssh_portSSH 端口22server.api_keyAPI 认证密钥(建议32位随机字符串)必填server.api_portAPI 监听端口8080smtp.*邮件发送配置必填mail.*邮件接收配置必填modules.*各功能模块开关truesecurity.fail2ban.maxretry封禁阈值1security.fail2ban.bantime封禁时长(秒,-1=永久)-1security.subnet_ban.threshold封段阈值26.4.2、API Key 说明项目说明长度要求建议 32 位 随机字符串(如 a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6)字符范围建议使用大小写字母 + 数字(a-z, A-Z, 0-9),不支持中文或特殊符号生成方式在服务端 config.yml 中手动设置,客户端填相同的值用途认证请求来源,防止未授权访问 API安全性api_key 通过 URL 参数传输,建议搭配防火墙 IP 白名单使用6.4.3、生成示例命令:# Linux 生成32位随机API Key tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 32 | head -1 # macOS 生成32位随机API Key openssl rand -hex 166.5、预编译的二进制目录结构最终 /data/server-report/ 目录下应该只有两个文件:/data/server-report/ ├── server-report ← 二进制文件(7.8MB) └── config.yml ← 配置文件整个系统就这两个文件,迁移到新服务器时整个目录拷走就行。6.6、手动测试/data/server-report/server-report --run-once如果配置正确,你的邮箱会收到一封测试日报邮件。6.7、配置定时任务注:第6.7-6.8条为旧版定时发送邮件服务使用,新版仍可使用。# 每天 00:01 发送日报 cat > /etc/cron.d/server-report << 'EOF' 1 0 * * * root /data/server-report/server-report EOF # 每 30 分钟检查一次子网封禁(如果启用了 subnet_ban) cat > /etc/cron.d/ban-subnet << 'EOF' */30 * * * * root /data/server-report/server-report --subnet-scan EOF chmod 644 /etc/cron.d/server-report /etc/cron.d/ban-subnet关于 /etc/cron.d/ 的注意事项:文件必须有一个空行结尾(否则 cron 可能不执行)文件名不要包含 . 以外的特殊字符如果定时任务不执行,可以改用 crontab -e 方式:(crontab -l 2>/dev/null; echo "1 0 * * * /data/server-report/server-report") | crontab -6.8、验证定时任务# 查看已安装的 cron 任务 cat /etc/cron.d/server-report # 或查看用户 crontab(如果用 crontab 方式) crontab -l6.9、创建 systemd 服务cat > /etc/systemd/system/server-report-api.service << 'EOF' [Unit] Description=Server Report API Service After=network.target [Service] Type=simple User=root ExecStart=/data/server-report/server-report --serve Restart=always RestartSec=5 [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable server-report-api.service systemctl start server-report-api.service6.10、验证服务# 查看服务状态 systemctl status server-report-api.service # 测试 API curl "http://IP:8080/api/v1/report?key=your-api-key-here"6.11、API 端口放行如果使用客户端需要远程连接API,需在防火墙放行端口:ufw allow 8080/tcp # Ubuntu/Debian firewall-cmd --add-port=8080/tcp # CentOS/RHEL6.12、更新服务端# 停止服务 systemctl stop server-report-api.service # 备份旧版本 mv /data/server-report/server-report /data/server-report/server-report.bak # 上传新版本 scp server-report-linux root@服务器IP:/data/server-report/server-report ssh root@服务器IP "chmod +x /data/server-report/server-report" # 启动服务 systemctl start server-report-api.service6.13、定时任务(数据采集策略)服务端每小时自动采集一次系统数据,保存为 today.json,客户端查询时直接读文件返回(毫秒级响应)。每天凌晨将前一天数据归档为 YYYY-MM-DD.json,保留 180 天。时间任务说明每小时(0分)--save-report采集系统数据更新 today.json每天 00:01--save-report --archive将前一天数据归档为 YYYY-MM-DD.json每天 03:00journalctl 清理清理 180 天前的系统日志每天 03:00报告文件清理删除 reports/ 中超过 180 天的 .json 文件设置方式(已配置好,无需手动操作):crontab -l # 输出: # 0 * * * * /data/server-report/server-report --save-report # 1 0 * * * /data/server-report/server-report --save-report --archive # 0 3 * * * /usr/bin/journalctl --vacuum-time=180d --quiet # 0 3 * * * find /data/server-report/reports -name "*.json" -mtime +180 -delete6.14、日志管理服务状态和系统错误日志通过 journalctl 管理。每天凌晨 3 点自动清理 180 天前的日志和归档报告文件。手动清理:# 清理 180 天前的日志 journalctl --vacuum-time=180d # 删除旧归档报告 find /data/server-report/reports -name "*.json" -mtime +180 -delete6.15、命令说明命令说明server-report --serve启动 API 服务(供客户端调用)server-report --save-report立即采集一次数据并保存到 today.jsonserver-report --save-report --archive将前一天数据归档为 YYYY-MM-DD.jsonserver-report --run-once立即发送一次邮件日报server-report --subnet-scan手动扫描并封禁恶意子网server-report --version查看版本server-report --help查看帮助七、日报内容解读7.1、服务器安全日志客户端主界面7.2、SSH登陆审计封禁列表7.3、fail2ban封禁列表7.4、针对中国IP单独进行了市级显示7.5、IP-C段封禁效果以及其它模块八、常见问题排查Q1:收不到邮件检查步骤:# 1. 手动触发发送,看有没有报错 /data/server-report/server-report --run-once # 2. 确认 SMTP 配置是否正确 cat /data/server-report/config.yml | grep -E "smtp:|server:|port:|user:|password:|mail:" # 3. 确认 SSL 端口可连通 echo | openssl s_client -connect mail.example.com:465 -servername mail.example.com 2>/dev/null | head -5 # 4. 如果 SSL 证书验证失败,程序会自动降级,但需要确认 SMTP 账号密码正确常见问题:密码包含特殊字符('、;、$ 等),需要用双引号包裹:password: "your'pass;word"465端口被运营商屏蔽(尤其是家庭宽带),可以试试587(STARTTLS)SMTP服务商要求开启「允许低安全性应用访问」Q2:IP 归属地显示英文,没有中文# 检查是否安装了 geoip-bin geoiplookup 8.8.8.8 # 如果没安装 apt install -y geoip-bin # Ubuntu/Debian yum install -y geoip # CentOSQ3:成功登录记录出现 @ 方式: key这是新版 OpenSSH 日志格式变化导致的用户名解析问题,不影响功能。如果介意,可以升级到最新版二进制。Q4:系统错误日志里很多看不懂的提示日报已经内置了白噪音过滤列表,以下类型的错误会被自动过滤:错误类型原因是否影响安全no more sessionsSSH 并发限制❌ 正常AF_VSOCK CID虚拟机不支持 VSOCK❌ 正常systemd-ssh-generator同上❌ 正常soft lockupCPU 瞬时过载❌ 正常kdump / Crash recovery kernel内核崩溃转储服务未启动❌ 正常sendmail 相关sendmail 已卸载❌ 正常如果还有其他看不懂的错误,检查是否是服务器上的业务程序(如 MySQL、Nginx、PHP-FPM)的正常日志,也可以发给AI查询。也非常欢迎大家在文章下方给我留言,把系统错误日志贴给我(无伤大雅的并影响每日汇报内容需要去掉的),我将一一进行汇总,对程序进行更新并重新布发升级版。Q5:定时任务不执行# 1. 检查 cron 服务状态 systemctl is-active cron # Ubuntu/Debian systemctl is-active crond # CentOS # 2. 检查 /etc/cron.d/ 文件格式 cat -A /etc/cron.d/server-report # 正常输出应以 $ 结尾(表示有新行) # 3. 如果还不行,改用 crontab 方式: (crontab -l 2>/dev/null; echo "1 0 * * * /data/server-report/server-report") | crontab -Q6:不同系统版本 SSH 日志格式不同日报程序已经兼容了以下格式:系统版本SSH 日志格式Debian 12 (OpenSSH < 9.8)Failed password for invalid user xxxDebian 13 (OpenSSH ≥ 9.8)Invalid user xxx from IP + 旧格式并存Ubuntu 20.04+Failed password for invalid user xxxCentOS 7+Failed password for invalid user xxxQ7:如何更新日报程序# 下载新版二进制 经常访问本地址查看站长有无更新,若有新版重新下载上传到服务器即可。 # 设置权限 chmod 755 /data/server-report/server-report # 配置文件和之前的任务不受影响Q8:客户端提示"连接失败"或"获取日报失败"确认服务器 API 端口(默认 8080)在防火墙上已放行确认客户端填写的 API Key 与服务端 config.yml 中的 api_key 一致确认能从客户端网络访问服务器 IP 和端口:telnet 服务器IP 8080服务端每小时自动采集数据,客户端查询为毫秒级响应;如果刚好在第一小时部署还未生成缓存,会实时采集一次(约20-30秒),之后即可秒回Q9:客户端找不到配置文件macOS:~/.config/server-report/servers.jsonWindows:程序目录下的 config/servers.json使用"导入数据"功能(📂 按钮)可从备份目录恢复配置和日报缓存。九、API 接口获取日报GET /api/v1/report?key=你的API密钥响应格式:{ "status": "ok", "server": "服务器名称", "timestamp": "2026-06-29 10:30:00", "date": "2026-06-28 → 2026-06-29", "sections": [ { "id": "system", "title": "系统健康", "type": "system", "data": { "hostname": "...", "ip": "...", "uptime": "...", "load": "...", "cpu": "...", "memory": { "used": "...", "total": "...", "percent": 0 }, "disks": [{ "mount": "/", "used": "...", "total": "...", "percent": 0 }] } }, { "id": "ssh_auth", "title": "SSH 登录审计", "type": "ssh_auth", "data": { "failed_total": 0, "failed_ips": 0, "failed_detail": [{ "ip": "1.2.3.4", "count": 5, "users": ["root"], "first": "...", "last": "...", "location_cn": "中国", "location_en": "China", "location_detail": "广东省广州市" }], "success_total": 0, "success_list": [{ "ip": "1.2.3.4", "count": 1, "method": "publickey" }] } }, { "id": "fail2ban", "title": "fail2ban 封禁统计", "type": "fail2ban", "data": { "total_banned": 0, "current_banned": 0, "banned_ips": [{ "ip": "1.2.3.4", "location_cn": "美国", "location_en": "USA", "ban_time": "...", "users": ["root"], "attempts": 10, "subnet": "1.2.3.0/24" }], "banned_subnets": [{ "subnet": "1.2.3.0/24", "ip_count": 3 }] } }, { "id": "network", "title": "网络连接与流量", "type": "network", "data": { "established": 0, "time_wait": 0, "total": 0, "top_conns": [], "listening_ports": [], "traffic": [] } }, { "id": "firewall", "title": "防火墙拦截统计", "type": "firewall", "data": { "total_blocks": 0, "top_src": [], "top_dst": [] } }, { "id": "services", "title": "运行中的系统服务", "type": "services", "data": { "total": 0, "running": [] } }, { "id": "changes", "title": "系统变更记录", "type": "changes", "data": { "packages": [] } }, { "id": "security", "title": "安全检测", "type": "security", "data": { "suid_ok": true, "new_users": [], "suspicious": [], "online_users": [], "errors": [] } } ] }健康检查GET /api/v1/ping?key=你的API密钥十、客户端(付费)10.1 macOS 客户端运行: 拷贝 ServerReport.app 到应用程序目录直接打开即可使用。数据存储: ~/.config/server-report/servers.json — 服务器配置列表reports/*.json — 历史日报缓存10.2 Windows 客户端运行: 直接双击 ServerReport.exe数据存储: 程序所在目录下的 config/ 文件夹config/servers.json — 服务器配置列表config/reports/*.json — 历史日报缓存10.3、客户端功能列表:功能列表:功能说明多服务器管理左侧列表添加/编辑/删除多台服务器,右键菜单操作日报展示8 个功能区块,数据结构与服务端 API 完全对应SSH 审计表格展示:IP、国家(归属地)、封禁时间、尝试用户、次数,次数超 10 标红fail2ban累计/当前封禁数,国家下拉筛选,表头可排序(IP/国家/封禁时间/尝试用户/次数),C段子网点击展开日历📅 按钮弹出日历,可切换年月,有数据的日期加重颜色背景手动刷新↻ 按钮重新拉取日报导入数据📂 按钮从目录选择器导入配置和缓存显示切换👁 按钮(在 show/hide 间切换)控制服务器列表IP显示导出配置右键服务器 → 导出,下载 servers.json关于页面关于窗口,含版本、开发信息、GitHub 链接10.4、日报服务器程序下载,免费开放本项目已开源,您也可以到Github下载(下载地址回复可见):隐藏内容,请前往内页查看详情10.5、客户端下载(付费)10.6、项目反馈如果你在使用过程中遇到问题,或者有功能建议,下方留言吧,或者给我发邮件。本项目不提供技术支持,若需技术支持,可以有尝代部署,收费60元/台,B站或抖音粉丝半价。mail:me@rongyan.cc{lamp/}
2026年06月26日
222 阅读
15 评论
1 点赞