Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
How-To-Secure-A-Linux-Server — 一步一步的指南,用于加固Linux服务器,涵盖SSH安全、防火墙、入侵检测、审计和系统配置,以减少攻击面并改进防御。 | Kitploit
工具/GitHubGitHub/imthenachoman/how-to-secure-a-linux-server
漏洞扫描器配置审计网络安全恶意软件分析身份验证入侵检测学习与教育事件响应精选资源

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
日志分析
GitHubimthenachoman/how-to-secure-a-linux-server

How-To-Secure-A-Linux-Server

一步一步的指南,用于加固Linux服务器,涵盖SSH安全、防火墙、入侵检测、审计和系统配置,以减少攻击面并改进防御。

查看仓库
30.3k2.0k21个月前Kitploit 审核通过

如何保护 Linux 服务器

一份持续更新的 Linux 服务器安全加固指南,同时也希望能让你了解一些安全知识及其重要性。

CC-BY-SA

目录

  • 引言
    • 指南目标
    • 为什么要保护你的服务器
    • 为什么又出一份指南
    • 其他指南
    • 待办/待添加
  • 指南概述
    • 关于本指南
    • 我的使用场景
    • 编辑配置文件——给懒人看的
    • 贡献
  • 开始之前
    • 明确你的原则
    • 选择 Linux 发行版
    • 安装 Linux
    • 安装前/后的要求
    • 其他重要说明
    • 使用 Ansible 剧本保护你的 Linux 服务器
  • SSH 服务器
    • 进行 SSH 更改前的重要说明
    • SSH 公钥/私钥
    • 为 AllowGroups 创建 SSH 组
    • 保护 /etc/ssh/sshd_config
    • 移除短 Diffie-Hellman 密钥
    • SSH 的 2FA/MFA
  • 基础
    • 限制谁可以使用 sudo
    • 限制谁可以使用 su
    • 使用 FireJail 在沙箱中运行应用程序
    • NTP 客户端
    • 保护 /proc
    • 强制账户使用安全密码
    • 自动安全更新和警报
    • 更安全的随机熵池(待完成)
    • 添加恐慌/备用/虚假密码登录安全系统
  • 网络
    • 用 UFW(简易防火墙)设置防火墙
    • 使用 PSAD 进行 iptables 入侵检测和防御
    • 使用 Fail2Ban 进行应用入侵检测和防御
    • 使用 CrowdSec 进行应用入侵检测和防御
  • 审计
    • 使用 AIDE 进行文件/文件夹完整性监控(待完成)
    • 使用 ClamAV 进行反病毒扫描(待完成)
    • 使用 Rkhunter 进行 Rootkit 检测(待完成)
    • 使用 chrootkit 进行 Rootkit 检测(待完成)
    • logwatch - 系统日志分析器和报告器
    • ss - 查看服务器正在监听的端口
    • Lynis - Linux 安全审计
    • OSSEC - 主机入侵检测
  • 危险区域
  • 杂项
    • MSMTP(简单 Sendmail)配合 Google
    • Gmail 和 Exim4 作为隐式 TLS 的 MTA
    • 独立的 iptables 日志文件
  • 遗留
    • 联系我
    • 有用链接
    • 致谢
    • 许可和版权

(目录使用 nGitHubTOC 生成)

引言

指南目标

本指南的目的是教你如何保护 Linux 服务器。

你可以采取很多措施来保护 Linux 服务器,本指南将尝试覆盖尽可能多的措施。随着我的学习,或者大家的贡献,会添加更多的主题/材料。

本指南对应的 Ansible 剧本可在 How To Secure A Linux Server With Ansible 找到,由 moltenbit 提供。

(返回目录)

为什么要保护你的服务器

我假设你使用本指南是因为你——希望如此——已经理解良好安全的重要性。这本身就是一个沉重的话题,详细讨论超出了本指南的范围。如果你不知道这个问题的答案,我建议你先研究一下。

概括来说,只要一台设备(比如服务器)处于公共领域——即对外部世界可见——它就会成为恶意行为者的目标。不安全的设备对恶意行为者来说是一个游乐场,他们想访问你的数据,或者将你的服务器用作大规模 DDoS 攻击的另一个节点。

更糟糕的是,如果没有良好的安全性,你可能永远不知道你的服务器是否已被入侵。恶意行为者可能已获得对服务器的未授权访问,并复制了你的数据却没有更改任何东西,因此你永远不会知道。或者你的服务器可能参与了 DDoS 攻击,而你也无从知晓。看看新闻中许多大规模数据泄露事件——公司往往在恶意行为者离开很久之后才发现数据泄露或入侵。

与普遍看法相反,恶意行为者并不总是想更改某些东西或锁住你的数据勒索钱财。有时他们只是想要你服务器上的数据用于他们的数据仓库(大数据中有巨大利润),或者秘密地将你的服务器用于他们的邪恶目的。

(返回目录)

为什么又出一份指南

这份指南可能看起来多余/不必要,因为网上有无数文章教你如何保护 Linux,但这些信息分散在不同的文章中,涵盖不同的内容,而且方式各异。谁有时间浏览数百篇文章呢?

在我为我的 Debian 构建进行研究时,我一直做笔记。最后我意识到,结合我已经知道的和我正在学习的,我已经掌握了一份操作指南的素材。我想把它放到网上,希望能帮助其他人学习并节省时间。

我从未找到一份涵盖所有方面的指南——本指南就是我的尝试。

本指南中涵盖的许多内容可能相当基础/琐碎,但我们大多数人不会每天都安装 Linux,很容易忘记这些基本内容。

(返回目录)

其他指南

有很多由专家、行业领袖以及发行版本身提供的指南。出于实际和版权原因,不可能包含所有内容。我建议你在开始本指南之前先看看它们。

  • 互联网安全中心 (CIS) 提供了基准,这些基准是详尽、行业信任的、一步步保护多种 Linux 变种的说明。查看他们的关于我们页面了解详情。我的建议是先读本指南(你现在读的这份),然后再读 CIS 的指南。这样他们的建议将优先于本指南中的任何内容。
  • 针对特定发行版的安全加固/安全指南,请查看你发行版的文档。
  • https://security.utexas.edu/os-hardening-checklist/linux-7 - Red Hat Enterprise Linux 7 加固检查清单
  • https://cloudpro.zone/index.php/2018/01/18/debian-9-3-server-setup-guide-part-1/ - # Debian 9.3 服务器设置指南
  • https://blog.vigilcode.com/2011/04/ubuntu-server-initial-security-quick-secure-setup-part-i/ - Ubuntu 服务器初始安全指南
  • https://www.tldp.org/LDP/sag/html/index.html
  • https://seifried.org/lasg/
  • https://news.ycombinator.com/item?id=19178964
  • https://wiki.archlinux.org/index.php/Security - 很多人也推荐了这个
  • https://securecompliance.co/linux-server-hardening-checklist/

(返回目录)

待办/待添加

  • Fail2ban 的自定义 Jail
  • MAC(强制访问控制)和 Linux 安全模块
    • https://wiki.archlinux.org/index.php/security#Mandatory_access_control
    • SELinux
      • https://en.wikipedia.org/wiki/Security-Enhanced_Linux
      • https://linuxtechlab.com/beginners-guide-to-selinux/
      • https://linuxtechlab.com/replicate-selinux-policies-among-linux-machines/
      • https://teamignition.us/how-to-stop-being-a-scrub-and-learn-to-use-selinux.html
    • AppArmor
      • https://wiki.archlinux.org/index.php/AppArmor
      • https://security.stackexchange.com/questions/29378/comparison-between-apparmor-and-selinux
      • http://www.insanitybit.com/2012/06/01/why-i-like-apparmor-more-than-selinux-5/
  • 磁盘加密
  • Rkhunter 和 chrootkit
    • http://www.chkrootkit.org/
    • http://rkhunter.sourceforge.net/
    • https://www.cyberciti.biz/faq/howto-check-linux-rootkist-with-detectors-software/
    • https://www.tecmint.com/install-rootkit-hunter-scan-for-rootkits-backdoors-in-linux/

(返回目录)

指南概述

关于本指南

本指南……

  • ……是一份持续更新中的作品。
  • ……专注于家庭环境下的 Linux 服务器。这里的所有概念/建议也适用于更大/专业的环境,但这些场景需要更高级和专门的配置,超出了本指南的范围。
  • ……不教你 Linux 是什么、如何安装 Linux 或如何使用它。如果你刚接触 Linux,请查看 https://linuxjourney.com/。
  • ……旨在成为发行版无关的指南。
  • ……不教你所有需要知道的安全知识,也不深入系统/服务器安全的各个方面。例如,物理安全不在本指南范围内。
  • ……不讨论程序/工具的工作原理,也不深入它们的细节。本指南引用的大多数程序/工具非常强大且高度可配置。目标是覆盖基本需求——足以吊起你的胃口,让你想进一步学习。
  • ……旨在通过提供可复制粘贴的代码来简化操作。你可能需要修改命令后再粘贴,所以手边最好有你喜欢的文本编辑器。
  • ……按照我觉得有逻辑的顺序组织——即先保护 SSH,再安装防火墙。因此,本指南建议按呈现的顺序进行,但并非必须。不过如果你以不同顺序操作要小心——某些部分可能依赖前面的内容。

(返回目录)

我的使用场景

服务器有许多类型和不同的使用场景。虽然我希望本指南尽可能通用,但有些内容可能不适用于所有/其他场景。请在你阅读本指南时自行判断。

为了给本指南中涵盖的许多主题提供背景,我的使用场景/配置是:

  • 一台桌面级计算机……
  • 拥有单个网卡……
  • 连接到消费级路由器……
  • 通过 ISP 获得动态 WAN IP……
  • WAN+LAN 运行在 IPv4……
  • LAN 使用NAT……
  • 我希望能够从未知计算机和未知位置(例如朋友家)通过 SSH 远程访问该服务器。

(返回目录)

编辑配置文件——给懒人看的

我非常懒,不喜欢在不需要时手动编辑文件。我还假设其他人都和我一样。:)

因此,在可能的情况下,我提供了 代码 片段来快速完成所需操作,比如在配置文件中添加或更改一行。

这些 代码 片段使用基本命令,如 echo、cat、sed、awk 和 grep。代码片段如何工作(比如每个命令/部分的作用)超出了本指南的范围——man 手册是你的朋友。

注意:代码 片段不会验证/确认更改是否生效——比如行是否真的被添加或更改了。我把验证部分留给你可靠的手。本指南中的步骤确实包括备份所有将被更改的文件。

并非所有更改都可以通过 代码 片段自动化。那些更改需要良好的、老式的手动编辑。例如,你不能简单地在 INI 类型的文件末尾附加一行。使用你喜欢的 Linux 文本编辑器。

(返回目录)

贡献

我想把本指南放在 GitHub 上,以便于协作。越多的人贡献,本指南就会变得越好越完整。

要贡献,你可以 fork 并提交 pull request,或者提交新的 issue。

(返回目录)

开始之前

明确你的原则

在开始之前,你需要明确你的原则是什么。你的威胁模型是什么?需要考虑的一些事情:

  • 你为什么想要保护你的服务器?
  • 你希望或不希望有多少安全性?
  • 你愿意为了安全性妥协多少便利性,反之亦然?
  • 你想要防范哪些威胁?你的情况有什么特殊之处?例如:
    • 物理接触你的服务器/网络是否是一个可能的攻击向量?
    • 你是否会在路由器上开放端口,以便从家庭网络外部访问你的服务器?
    • 你是否会在服务器上托管一个文件共享,并挂载到桌面级机器上?桌面机器被感染并进而感染服务器的可能性有多大?
  • 如果你的安全实现将你锁在服务器之外,你有恢复的方法吗?例如,你禁用了 root 登录或为 GRUB 设置了密码。

这些只是需要考虑的一些事情。在开始保护你的服务器之前,你需要了解你要防范什么以及为什么,这样你才知道你需要做什么。

(返回目录)

选择 Linux 发行版

本指南旨在与发行版无关,这样用户可以使用他们想要的任何发行版。话虽如此,有几点需要记住:

你想要的发行版应该……

  • ……稳定。除非你喜欢凌晨 2 点调试问题,否则你不希望无人值守升级或手动包/系统更新导致服务器无法运行。但这同时意味着你愿意不运行最新、最前沿的软件。
  • ……及时更新安全补丁。你可以保护服务器上的所有东西,但如果核心操作系统或你运行的应用程序有已知漏洞,你永远不安全。
  • ……你熟悉。如果你不懂 Linux,我建议你先玩玩再尝试保护它。你应该对它感到舒适,知道如何使用,比如如何安装软件、配置文件在哪等等。
  • ……有良好支持。即便是最有经验的管理员有时也需要帮助。有一个可以寻求帮助的地方能挽救你的理智。

(返回目录)

安装 Linux

安装 Linux 超出了本指南的范围,因为每个发行版做法不同,而且安装说明通常有详细文档。如果你需要帮助,先从你的发行版文档开始。不管是什么发行版,高级过程通常如下:

  1. 下载 ISO
  2. 将其刻录/复制/传输到你的安装介质(例如 CD 或 U 盘)
  3. 从安装介质启动你的服务器
  4. 按照提示安装

如果适用,使用专家安装选项,以便更紧密地控制服务器上运行的内容。只安装你绝对需要的东西。 我个人除了 SSH 外不安装任何其他东西。同时勾选磁盘加密选项。

(返回目录)

安装前/后的要求

  • 如果你要在路由器上开放端口以便从外部访问服务器,请在系统启动并保护之前禁用端口转发。
  • 除非你直接物理连接到服务器,否则你需要远程访问,因此请确保 SSH 正常工作。
  • 保持系统更新(例如,Debian 系统上使用 sudo apt update && sudo apt upgrade)。
  • 确保执行适用于你设置的特殊任务,例如:
    • 配置网络
    • 在 /etc/fstab 中配置挂载点
    • 创建初始用户账户
    • 安装你想要的核心软件,如 man
    • 等等……
  • 你的服务器需要能够发送电子邮件,以便你收到重要的安全警报。如果你没有设置邮件服务器,请查看Gmail 和 Exim4 作为隐式 TLS 的 MTA。
  • 我还建议你在开始本指南之前阅读CIS 基准,以便消化/理解他们的说法。我的建议是先读本指南(你现在读的这份),然后再读 CIS 的指南。这样他们的建议将优先于本指南中的任何内容。

(返回目录)

其他重要说明

  • 本指南是在 Debian 上编写和测试的。以下大多数内容应该可以在其他发行版上工作。如果你发现某些内容不工作,请联系我。每个发行版的主要区别在于其包管理系统。由于我使用 Debian,我将提供适用于所有基于 Debian 的发行版的 apt 命令。如果有人愿意提供其他发行版对应的命令,我将添加它们。
  • 文件路径和设置也可能略有不同——如果遇到问题,请查阅你的发行版文档。
  • 在开始之前,请通读整个指南。你的使用场景和/或原则可能要求你不做某些事情或更改顺序。
  • 不要盲目复制粘贴而不理解你粘贴的内容。某些命令需要根据你的需求进行修改才能工作——例如用户名。

(返回目录)

使用 Ansible 剧本保护你的 Linux 服务器

本指南对应的 Ansible 剧本可在 How To Secure A Linux Server With Ansible 找到。确保根据需要修改变量,并事先阅读所有任务以确认不会破坏您的系统。运行剧本后,确保所有设置都符合您的需求!

  1. 安装 Ansible
  2. git clone How To Secure A Linux Server With Ansible
  3. 创建 SSH 公钥/私钥 ``` ssh-keygen -t ed25519
root@kitploit:~
5. 根据你的需求更改 *group_vars/variables.yml* 中的所有变量。
6. 在运行 playbooks 之前启用 SSH root 访问:  ```
nano /etc/ssh/sshd_config
[...]
PermitRootLogin yes
[...]
  1. 推荐:在您的系统上配置静态 IP 地址。
  2. 将您系统的 IP 地址添加到 hosts.yml 中。

 

使用您在安装服务器时指定的 root 密码运行 requirements playbook:

root@kitploit:~
ansible-playbook --inventory hosts.yml --ask-pass requirements-playbook.yml

 

使用您在 variables.yml 文件中指定的新用户密码运行主 playbook:

root@kitploit:~
ansible-playbook --inventory hosts.yml --ask-pass main-playbook.yml

 

如果您需要多次运行 playbook,请记得使用 SSH 密钥和新的 SSH 端口:

root@kitploit:~
ansible-playbook --inventory hosts.yml -e ansible_ssh_port=SSH_PORT --key-file /PATH/TO/SSH/KEY main-playbook.yml

(返回目录)

SSH 服务器

在进行 SSH 更改之前的重要说明

强烈建议您在修改并应用 SSH 配置之前,保持服务器的第二个终端会话处于打开状态。这样,如果您锁定了第一个终端会话,您仍有另一个已连接的会话可以修复问题。

感谢 Sonnenbrand 提出这个 建议。

SSH 公钥/私钥

为什么

使用 SSH 公钥/私钥比使用密码更安全。同时,这也让连接到我们的服务器更加简便和快捷,因为您无需输入密码。

工作原理

有关更多详细信息,请参阅后面的参考资料。简单来说,公钥/私钥通过使用一对密钥来验证身份。

  1. 其中一个密钥,即公钥,只能加密数据,不能解密。
  2. 另一个密钥,即私钥,可以解密数据。

对于 SSH,需要在客户端创建一个公钥和私钥。您必须确保两个密钥的安全,尤其是私钥。尽管公钥本身是公开的,但避免任何密钥落入他人之手是明智的。

当您连接到 SSH 服务器时,SSH 会检查您所连接的服务器上的 ~/.ssh/authorized_keys 文件中是否存在与客户端匹配的公钥。注意,该文件位于您尝试登录的用户主文件夹中。因此,在创建公钥后,需要将其追加到 ~/.ssh/authorized_keys 中。一种方法是将其复制到 U 盘并物理传输到服务器。另一种方法是使用 ssh-copy-id 传输并追加公钥。

创建密钥并将公钥追加到服务器上的 ~/.ssh/authorized_keys 后,SSH 将使用公钥和私钥来验证身份并建立安全连接。身份验证的过程很复杂,但 Digital Ocean 有一篇很好的文章介绍了其工作原理。简而言之,服务器使用公钥加密一个挑战消息,然后发送给客户端。如果客户端无法使用私钥解密该挑战消息,则身份验证失败,连接将无法建立。

它们被认为更安全,因为您需要私钥才能建立 SSH 连接。如果您在 /etc/ssh/sshd_config 中设置了 PasswordAuthentication no,则 SSH 将不允许您在没有私钥的情况下连接。

您还可以为密钥设置密码短语,这样在通过公钥/私钥连接时,您需要输入密钥密码短语。请注意,这样做意味着您无法在自动化脚本中使用该密钥,因为无法在脚本中发送密码短语。ssh-agent 是一个在大多数 Linux 发行版中附带(且通常已运行)的程序,它允许您将解密的私钥保存在内存中一段可配置的时间。只需运行 ssh-add,它会提示您输入密码短语。在可配置的时间段内,您将不再被提示输入密码短语。

我们将使用 Ed25519 密钥。根据 https://linux-audit.com/ 的说法:

它使用椭圆曲线签名方案,提供了比 ECDSA 和 DSA 更好的安全性。同时,它也具有很好的性能。

目标

  • Ed25519 公钥/私钥对:
    • 私钥保存在客户端
    • 公钥保存在服务器上

注意事项

  • 您需要为将要连接到服务器的每台计算机和每个账户执行此步骤。

参考资料

  • https://www.ssh.com/ssh/public-key-authentication
  • https://help.ubuntu.com/community/SSH/OpenSSH/Keys
  • https://linux-audit.com/using-ed25519-openssh-keys-instead-of-dsa-rsa-ecdsa/
  • https://www.digitalocean.com/community/tutorials/understanding-the-ssh-encryption-and-connection-process
  • https://wiki.archlinux.org/index.php/SSH_Keys
  • https://www.ssh.com/ssh/copy-id
  • man ssh-keygen
  • man ssh-copy-id
  • man ssh-add

步骤

  1. 在将要用于连接服务器的计算机(客户端,而非服务器本机)上,使用 ssh-keygen 创建 Ed25519 密钥:

    root@kitploit:~
    ssh-keygen -t ed25519
    
    root@kitploit:~
    Generating public/private ed25519 key pair.
    Enter file in which to save the key (/home/user/.ssh/id_ed25519):
    Created directory '/home/user/.ssh'.
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in /home/user/.ssh/id_ed25519.
    Your public key has been saved in /home/user/.ssh/id_ed25519.pub.
    The key fingerprint is:
    SHA256:F44D4dr2zoHqgj0i2iVIHQ32uk/Lx4P+raayEAQjlcs user@client
    The key's randomart image is:
    +--[ED25519 256]--+
    |xxxx  x          |
    |o.o +. .         |
    | o o oo   .      |
    |. E oo . o .     |
    | o o. o S o      |
    |... .. o o       |
    |.+....+ o        |
    |+.=++o.B..       |
    |+..=**=o=.       |
    +----[SHA256]-----+
    

    注意:如果您设置了密码短语,那么每次使用此密钥连接到服务器时都需要输入该密码短语,除非您使用 ssh-agent。

  2. 现在,您需要将客户端上的公钥 ~/.ssh/id_ed25519.pub 追加到服务器上的 ~/.ssh/authorized_keys 文件中。由于我们很可能仍在家庭局域网中,可能免受 的威胁,因此我们将使用 来传输并追加公钥:

现在是一个好时机去执行针对您设置的任何特定任务。

(返回目录)

创建用于 AllowGroups 的 SSH 组

为什么

为了能够轻松控制哪些用户可以 SSH 到服务器。通过使用组,我们可以快速地将账户添加或移出该组,从而快速允许或禁止 SSH 访问。

工作原理

我们将在 SSH 的配置文件 /etc/ssh/sshd_config 中使用 AllowGroups 选项,告诉 SSH 服务器仅允许属于某个特定 UNIX 组的用户通过 SSH 登录。不在该组中的任何人都无法 SSH 连接。

目标

  • 创建一个 UNIX 组,我们将在 安全配置 /etc/ssh/sshd_config 中使用它来限制谁可以 SSH 到服务器。

注意事项

  • 这是支持在 安全配置 /etc/ssh/sshd_config 中设置 AllowGroup 的先决步骤。

参考资料

  • man groupadd
  • man usermod

步骤

  1. 创建一个组:

    root@kitploit:~
    sudo groupadd sshusers
    
  2. 将账户添加到组中:

    root@kitploit:~
    sudo usermod -a -G sshusers user1
    sudo usermod -a -G sshusers user2
    sudo usermod -a -G sshusers ...
    

    您需要为服务器上每个需要 SSH 访问的账户执行此操作。

(返回目录)

安全配置 /etc/ssh/sshd_config

为什么

SSH 是进入您服务器的一扇门。如果您在路由器上打开端口以便从家庭网络外部 SSH 到服务器,这一点尤其重要。如果没有正确配置,恶意行为者可能会利用它获得对系统的未授权访问。

工作原理

/etc/ssh/sshd_config 是 SSH 服务器使用的默认配置文件。我们将使用此文件来告诉 SSH 服务器应使用哪些选项。

目标

  • 一个安全的 SSH 配置

注意事项

  • 确保您首先完成了创建用于 AllowGroups 的 SSH 组。

参考资料

  • Mozilla 针对 OpenSSH 6.7+ 的 OpenSSH 指南:https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67
  • https://linux-audit.com/audit-and-harden-your-ssh-configuration/
  • https://www.ssh.com/ssh/sshd_config/
  • https://www.techbrown.com/harden-ssh-secure-linux-vps-server/ (已失效;可尝试 http://web.archive.org/web/20200413100933/https://www.techbrown.com/harden-ssh-secure-linux-vps-server/)
  • https://serverfault.com/questions/660160/openssh-difference-between-internal-sftp-and-sftp-server/660325
  • man sshd_config
  • 感谢 than0s 提供了查找重复设置的方法。

步骤

  1. 备份 OpenSSH 服务器的配置文件 /etc/ssh/sshd_config,并移除注释使其更易阅读:

    root@kitploit:~
    sudo cp --archive /etc/ssh/sshd_config /etc/ssh/sshd_config-COPY-$(date +"%Y%m%d%H%M%S")
    sudo sed -i -r -e '/^#|^$/ d' /etc/ssh/sshd_config
    
  2. 编辑 /etc/ssh/sshd_config,然后查找并编辑或添加这些应始终应用的设置(无论您的配置/设置如何):

    注意:SSH 不喜欢重复且矛盾的设置。例如,如果您同时有 ChallengeResponseAuthentication no 和 ChallengeResponseAuthentication yes,SSH 将尊重第一个设置而忽略第二个。您的 /etc/ssh/sshd_config 文件可能已经包含下面的一些设置/行。为避免问题,您需要手动检查 /etc/ssh/sshd_config 文件并解决任何重复且矛盾的设置。

    注意:如果您运行的是 OpenSSH 9.1 或更高版本,请取消下面配置中 RequiredRSASize 3072 一行的注释。这会强制要求 RSA 密钥的最小大小为 3072 位,并在身份验证期间拒绝更小的 RSA 密钥。这仅影响 RSA 密钥。如果您使用 ED25519 或 ECDSA 密钥,则不受影响。您可以通过 ssh-keygen -l -f ~/.ssh/id_rsa 检查您的密钥类型和大小。在较旧的 OpenSSH 版本上,请保持该行被注释,因为它会阻止 sshd 启动。

    root@kitploit:~
    ########################################################################################################
    # 配置开始,根据 https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67,2019-01-01 版本
    ########################################################################################################
    
    # 按优先顺序排列的受支持的主机密钥算法。
    HostKey /etc/ssh/ssh_host_ed25519_key
    HostKey /etc/ssh/ssh_host_rsa_key
    HostKey /etc/ssh/ssh_host_ecdsa_key
    
    KexAlgorithms [email protected],ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
    
    Ciphers [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr
    
    MACs [email protected],[email protected],hmac-sha2-512,hmac-sha2-256,[email protected]
    
    # LogLevel VERBOSE 会在登录时记录用户的密钥指纹。这对于拥有清晰的审计跟踪以确定使用了哪个密钥登录是必要的。
    LogLevel VERBOSE
    
    # 在非特权进程中尽可能使用内核沙箱机制
    # OpenBSD 使用 Systrace,Linux 使用 Seccomp,MacOSX/Darwin 使用 seatbelt,其他平台使用 rlimit。
    # 注意:此设置在 OpenSSH 7.5 中已弃用 (https://www.openssh.com/txt/release-7.5)
    # UsePrivilegeSeparation sandbox
    
    ########################################################################################################
    # 配置结束,根据 https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67,2019-01-01 版本
    ########################################################################################################
    
    # 不允许用户设置环境变量
    PermitUserEnvironment no
    
    # 记录 sftp 级别的文件访问(读/写等),否则这些不易记录。
    Subsystem sftp  internal-sftp -f AUTHPRIV -l INFO
    
    # 禁用 X11 转发,因为 X11 非常不安全
    # 您实际上不应该在服务器上运行 X
    X11Forwarding no
    
    # 禁用端口转发
    AllowTcpForwarding no
    AllowStreamLocalForwarding no
    GatewayPorts no
    PermitTunnel no
    
    # 不允许空密码账户登录
    PermitEmptyPasswords no
    
    # 忽略 .rhosts 和 .shosts
    IgnoreRhosts yes
    
    # 验证主机名是否与 IP 匹配
    UseDNS yes
    
    Compression no
    
    # TCP keepalive 是可伪造的(在加密通道外部运行)
    # 改用 ClientAlive(在加密通道内部运行)
    TCPKeepAlive no
    
    AllowAgentForwarding no
    PermitRootLogin no
    
    # 不允许 .rhosts 或 /etc/hosts.equiv
    HostbasedAuthentication no
    
    # OpenSSH 9.1 及更高版本
    # 强制要求 RSA 密钥的最小大小为 3072 位
    # https://www.keylength.com/en/compare/
    # RequiredRSASize 3072
    
    # https://github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/115
    HashKnownHosts yes
    

(返回目录)

移除短 Diffie-Hellman 密钥

为什么

根据 Mozilla 针对 OpenSSH 6.7+ 的 OpenSSH 指南:“所有使用的 Diffie-Hellman 模数应至少为 3072 位”。

Diffie-Hellman 算法用于 SSH 建立安全连接。模数(密钥长度)越大,加密强度越高。

目标

  • 移除所有长度小于 3072 位的 Diffie-Hellman 密钥。

参考资料

  • Mozilla 针对 OpenSSH 6.7+ 的 OpenSSH 指南:https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67
  • https://infosec.mozilla.org/guidelines/key_management
  • man moduli

步骤

  1. 备份 SSH 的模数文件 /etc/ssh/moduli:

    root@kitploit:~
    sudo cp --archive /etc/ssh/moduli /etc/ssh/moduli-COPY-$(date +"%Y%m%d%H%M%S")
    
  2. 移除短模数:

    root@kitploit:~
    sudo awk '$5 >= 3071' /etc/ssh/moduli | sudo tee /etc/ssh/moduli.tmp
    sudo mv /etc/ssh/moduli.tmp /etc/ssh/moduli
    

(返回目录)

SSH 的双因素认证/多因素认证

为什么

尽管 SSH 是您门窗的相当不错的安全卫士,但它仍然是一扇可见的门,恶意行为者可以看到并尝试暴力破解。Fail2ban 会监控这些暴力尝试,但安全没有过度一说。要求双因素认证增加了一层额外的安全保护。

使用双因素认证(2FA)或多因素认证(MFA)要求每个进入者拥有两把钥匙才能进入,这使得恶意行为者更难得逞。这两把钥匙是:

  1. 他们的密码
  2. 每 30 秒变化一次的 6 位数字令牌

缺少任何一把钥匙,他们都将无法进入。

为什么不

许多人可能会觉得这种体验繁琐或烦人。而且,能否访问您的系统取决于生成验证码的配套验证器应用。

工作原理

在 Linux 上,PAM 负责身份验证。PAM 有四个任务,您可以阅读 https://en.wikipedia.org/wiki/Linux_PAM 了解更多信息。本节讨论的是身份验证任务。

当您登录服务器时(无论是直接从控制台还是通过 SSH),您所通过的“门”会将请求发送到 PAM 的身份验证任务,PAM 会要求并验证您的密码。您可以自定义每个“门”使用的规则。例如,您可以为直接从控制台登录设置一组规则,为通过 SSH 登录设置另一组规则。

本节将修改通过 SSH 登录时的身份验证规则,要求同时提供密码和 6 位数字验证码。我们将使用 Google 的 libpam-google-authenticator PAM 模块来创建和验证 TOTP 密钥。https://fastmail.blog/2016/07/22/how-totp-authenticator-apps-work/ 和 https://jemurai.com/2018/10/11/how-it-works-totp-based-mfa/ 对 TOTP 的工作方式有非常详细的说明。

我们要做的是,让服务器的 SSH PAM 配置要求用户先输入密码,再输入数字令牌。PAM 会先验证用户的密码,如果正确,它会将认证请求路由到 libpam-google-authenticator,后者会要求并验证您的 6 位数字令牌。只有当一切正常时,认证才会成功,用户才能登录。

目标

  • 对所有 SSH 连接启用 2FA/MFA

注意事项

  • 在开始之前,您应该了解 2FA/MFA 的工作原理,并且需要在手机上安装一个验证器应用才能继续。
  • 我们将使用 google-authenticator-libpam。
  • 根据以下配置,用户只有在使用密码登录时才需要输入 2FA/MFA 代码,但如果他们使用 SSH 公钥/私钥 则不需要。请查阅文档了解如何更改此行为以满足您的需求。

参考

  • https://github.com/google/google-authenticator-libpam
  • https://en.wikipedia.org/wiki/Linux_PAM
  • https://en.wikipedia.org/wiki/Time-based_One-time_Password_algorithm
  • https://fastmail.blog/2016/07/22/how-totp-authenticator-apps-work/
  • https://jemurai.com/2018/10/11/how-it-works-totp-based-mfa/

步骤

  1. 安装 libpam-google-authenticator。

    在基于 Debian 的系统上:

    root@kitploit:~
    sudo apt install libpam-google-authenticator
    
  2. 确保您以要启用 2FA/MFA 的用户身份登录,然后执行 google-authenticator 来创建必要的令牌数据:

    root@kitploit:~
    google-authenticator
    
    root@kitploit:~
    Do you want authentication tokens to be time-based (y/n) y
    https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/user@host%3Fsecret%3DR4ZWX34FQKZROVX7AGLJ64684Y%26issuer%3Dhost
    
    ...
    
    Your new secret key is: R3NVX3FFQKZROVX7AGLJUGGESY
    Your verification code is 751419
    Your emergency scratch codes are:
      12345678
      90123456
      78901234
      56789012
      34567890
    
    Do you want me to update your "/home/user/.google_authenticator" file (y/n) y
    
    Do you want to disallow multiple uses of the same authentication
    token? This restricts you to one login about every 30s, but it increases
    your chances to notice or even prevent man-in-the-middle attacks (y/n) Do you want to disallow multiple uses of the same authentication
    token? This restricts you to one login about every 30s, but it increases
    your chances to notice or even prevent man-in-the-middle attacks (y/n) y
    
    By default, tokens are good for 30 seconds. In order to compensate for
    possible time-skew between the client and the server, we allow an extra
    token before and after the current time. If you experience problems with
    poor time synchronization, you can increase the window from its default
    size of +-1min (window size of 3) to about +-4min (window size of
    17 acceptable tokens).
    Do you want to do so? (y/n) y
    
    If the computer that you are logging into isn't hardened against brute-force
    login attempts, you can enable rate-limiting for the authentication module.
    By default, this limits attackers to no more than 3 login attempts every 30s.
    Do you want to enable rate-limiting (y/n) y
    

(返回目录)

基础

限制可使用 sudo 的用户

原因

sudo 允许账户以其他账户身份运行命令,包括 root。我们需要确保只有我们指定的账户才能使用 sudo。

目标

  • sudo 权限仅限于我们指定的组成员

注意事项

  • 您的安装可能已经完成了此操作,或者可能已经有一个用于此目的的特殊组,因此请先检查。
    • Debian 创建了 sudo 组。要查看属于此组(因此具有 sudo 权限)的用户,请执行:

      root@kitploit:~
      cat /etc/group | grep "sudo"
      
    • RedHat 创建了 wheel 组

  • 请参见 https://github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/39 了解关于某些发行版使 sudo 无需密码的说明。感谢 sbrl 分享。

步骤

  1. 创建一个组:

    root@kitploit:~
    sudo groupadd sudousers
    
  2. 将账户添加到该组:

    root@kitploit:~
    sudo usermod -a -G sudousers user1
    sudo usermod -a -G sudousers user2
    sudo usermod -a -G sudousers  ...
    

    您需要为每台服务器上需要 sudo 权限的账户执行此操作。

  3. 备份 sudo 的配置文件 /etc/sudoers:

    root@kitploit:~
    sudo cp --archive /etc/sudoers /etc/sudoers-COPY-$(date +"%Y%m%d%H%M%S")
    
  4. 编辑 sudo 的配置文件 /etc/sudoers:

    root@kitploit:~
    sudo visudo
    
  5. 告诉 sudo 只允许 sudousers 组中的用户使用 sudo,如果该行尚不存在,则添加以下行:

    root@kitploit:~
    %sudousers   ALL=(ALL:ALL) ALL
    

(返回目录)

限制可使用 su 的用户

原因

su 也允许账户以其他账户身份运行命令,包括 root。我们需要确保只有我们指定的账户才能使用 su。

目标

  • su 权限仅限于我们指定的组成员

参考

  • 感谢 olavim 分享 这个想法

步骤

  1. 创建一个组:

    root@kitploit:~
    sudo groupadd suusers
    
  2. 将账户添加到该组:

    root@kitploit:~
    sudo usermod -a -G suusers user1
    sudo usermod -a -G suusers user2
    sudo usermod -a -G suusers  ...
    

    您需要为每台服务器上需要 sudo 权限的账户执行此操作。

  3. 使只有此组中的用户可以执行 /bin/su:

    root@kitploit:~
    sudo dpkg-statoverride --update --add root suusers 4750 /bin/su
    

(返回目录)

使用 FireJail 在沙盒中运行应用程序

原因

对于许多应用程序来说,在沙盒中运行绝对更好。

浏览器(尤其是闭源浏览器)和邮件客户端强烈建议这样做。

目标

  • 将应用程序限制在监狱(几个安全目录)中,并阻止访问系统的其余部分

参考

  • 感谢 FireJail

步骤

  1. 安装软件:

    root@kitploit:~
    sudo apt install firejail firejail-profiles
    

    注意:对于 Debian 10 稳定版,建议使用官方 Backport:

    root@kitploit:~
    sudo apt install -t buster-backports firejail firejail-profiles
    
  2. 允许一个应用程序(安装在 /usr/bin 或 /bin)仅在沙盒中运行(以下是一些示例):

    root@kitploit:~
    sudo ln -s /usr/bin/firejail /usr/local/bin/google-chrome-stable
    sudo ln -s /usr/bin/firejail /usr/local/bin/firefox
    sudo ln -s /usr/bin/firejail /usr/local/bin/chromium
    sudo ln -s /usr/bin/firejail /usr/local/bin/evolution
    sudo ln -s /usr/bin/firejail /usr/local/bin/thunderbird
    
  3. 照常运行应用程序(通过终端或启动器),并检查它是否在监狱中运行:

    root@kitploit:~
    firejail --list
    
  4. 允许沙盒化的应用程序像以前一样再次运行(示例:firefox)

    root@kitploit:~
    sudo rm /usr/local/bin/firefox
    

(返回目录)

NTP 客户端

原因

许多安全协议都依赖于时间。如果您的系统时间不正确,可能会对服务器产生负面影响。NTP 客户端可以通过将系统时间与全局 NTP 服务器保持同步来解决这个问题。

工作原理

NTP 代表网络时间协议。在本指南的上下文中,服务器上的 NTP 客户端用于使用从官方服务器拉取的官方时间来更新服务器时间。请查看 https://www.pool.ntp.org/en/ 获取所有公共 NTP 服务器。

注意: 从 Debian 13 (Trixie) 开始,经典的 ntp 软件包已被移除。运行 sudo apt install ntp 将失败,显示 "Package ntp has no installation candidate"。由于本指南仅将 NTP 用作客户端(以同步服务器时钟),因此在 Debian 13+ 上的推荐方法是使用 systemd-timesyncd,它已经预装,不需要额外的软件包。请参见下面的 Debian 13+ 步骤。

目标

  • 安装 NTP 客户端并使服务器时间保持同步

参考

  • https://cloudpro.zone/index.php/2018/01/27/debian-9-3-server-setup-guide-part-4/
  • https://en.wikipedia.org/wiki/Network_Time_Protocol
  • https://www.pool.ntp.org/en/
  • https://serverfault.com/questions/957302/securing-hardening-ntp-client-on-linux-servers-config-file/957450#957450
  • https://tf.nist.gov/tf-cgi/servers.cgi

步骤

Debian 13 (Trixie) 及更高版本:systemd-timesyncd

systemd-timesyncd 是一个轻量级的 SNTP 客户端,已包含在 Debian 中。与完整的 ntpd 守护进程不同,它不监听任何端口,因此攻击面更小。对于本指南的目的——保持服务器时钟同步——它已经足够了。

  1. 启用 NTP 同步:

    root@kitploit:~
    sudo timedatectl set-ntp true
    
  2. 验证其是否正常工作:

    root@kitploit:~
    timedatectl status
    

    您应该在输出中看到 NTP service: active 和 System clock synchronized: yes。

  3. 配置可信的 NTP 服务器。备份配置文件,然后编辑它:

    root@kitploit:~
    sudo cp --archive /etc/systemd/timesyncd.conf /etc/systemd/timesyncd.conf-COPY-$(date +"%Y%m%d%H%M%S")
    

    编辑 /etc/systemd/timesyncd.conf 并取消注释/设置 [Time] 部分:

    root@kitploit:~
    [Time]
    NTP=pool.ntp.org
    FallbackNTP=0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org
    

    对于懒人:

    root@kitploit:~
    sudo sed -i -r -e "s/^#?NTP=.*$/NTP=pool.ntp.org         # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/" /etc/systemd/timesyncd.conf
    sudo sed -i -r -e "s/^#?FallbackNTP=.*$/FallbackNTP=0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org         # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/" /etc/systemd/timesyncd.conf
    
Debian 12 (Bookworm) 及更早版本:ntp 软件包

注意: 这些步骤仅适用于 Debian 12 及更早版本。在 Debian 13+ 上,ntp 软件包不再可用——请改用上面的 systemd-timesyncd 步骤。

  1. 安装 ntp。

    在基于 Debian 的系统上:

    root@kitploit:~
    sudo apt install ntp
    
  2. 备份 NTP 客户端的配置文件 /etc/ntp.conf:

    root@kitploit:~
    sudo cp --archive /etc/ntp.conf /etc/ntp.conf-COPY-$(date +"%Y%m%d%H%M%S")
    
  3. 默认配置(至少在 Debian 上)已经相当安全。我们唯一需要确保的是使用 pool 指令而不是任何 server 指令。pool 指令允许 NTP 客户端在服务器无响应或提供错误时间时停止使用它。通过注释掉所有 server 指令并在 /etc/ntp.conf 中添加以下内容来做到这一点。

    root@kitploit:~
    pool pool.ntp.org iburst
    

    对于懒人:

    root@kitploit:~
    sudo sed -i -r -e "s/^((server|pool).*)/# \1         # commented by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/" /etc/ntp.conf
    echo -e "\npool pool.ntp.org iburst         # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")" | sudo tee -a /etc/ntp.conf
    

(返回目录)

保护 /proc

原因

引用 https://linux-audit.com/linux-system-hardening-adding-hidepid-to-proc/ 的内容:

当查看 /proc 时,您会发现大量文件和目录。其中许多只是数字,代表特定进程 ID (PID) 的信息。默认情况下,Linux 系统被部署为允许所有本地用户查看所有这些信息。这包括来自其他用户的进程信息。这可能包含您不希望与其他用户共享的敏感细节。通过应用一些文件系统配置调整,我们可以改变这种行为并提高系统的安全性。

注意:这可能会在某些 systemd 系统上导致问题。更多信息请参见 https://github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/37。感谢 nlgranger 分享。

目标

  • 使用 hidepid=2 挂载 /proc,使用户只能看到关于自己进程的信息

参考

  • https://linux-audit.com/linux-system-hardening-adding-hidepid-to-proc/
  • https://likegeeks.com/secure-linux-server-hardening-best-practices/#Hardening-proc-Directory
  • https://www.cyberciti.biz/faq/linux-hide-processes-from-other-users/

步骤

  1. 备份 /etc/fstab:

    root@kitploit:~
    sudo cp --archive /etc/fstab /etc/fstab-COPY-$(date +"%Y%m%d%H%M%S")
    
  2. 向 /etc/fstab 添加以下行,以便使用 hidepid=2 挂载 /proc:

    root@kitploit:~
    proc     /proc     proc     defaults,hidepid=2     0     0
    

    对于懒人:

    root@kitploit:~
    echo -e "\nproc     /proc     proc     defaults,hidepid=2     0     0         # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")" | sudo tee -a /etc/fstab
    
  3. 重启系统:

    root@kitploit:~
    sudo reboot now
    

    注意:或者,您可以在不重启的情况下重新挂载 /proc,使用 sudo mount -o remount,hidepid=2 /proc

(返回目录)

强制账户使用安全密码

原因

默认情况下,账户可以使用他们想要的任何密码,包括弱密码。pwquality/pam_pwquality 通过提供“一种配置系统密码默认质量要求的方法”并“针对系统字典和一组用于识别不良选择的规则检查其强度”来解决这个安全缺口。

工作原理

在 Linux 上,PAM 负责身份验证。PAM 有四个任务,您可以在 https://en.wikipedia.org/wiki/Linux_PAM 上阅读。这一节讨论的是密码任务。当需要设置或更改账户密码时,PAM 的密码任务会处理该请求。在本节中,我们将告诉 PAM 的密码任务将请求的新密码传递给 libpam-pwquality,以确保其符合我们的要求。如果符合要求,则使用/设置该密码;如果不符合要求,则会报错并通知用户。

目标

  • 强制使用强密码

步骤

  1. 安装 libpam-pwquality。

    在基于 Debian 的系统中:

    root@kitploit:~
    sudo apt install libpam-pwquality
    
  2. 备份 PAM 密码配置文件 /etc/pam.d/common-password:

    root@kitploit:~
    sudo cp --archive /etc/pam.d/common-password /etc/pam.d/common-password-COPY-$(date +"%Y%m%d%H%M%S")
    
  3. 通过编辑文件 /etc/pam.d/common-password 并修改以如下内容开头的行,告诉 PAM 使用 libpam-pwquality 来强制使用强密码:

    root@kitploit:~
    password        requisite                       pam_pwquality.so
    

    修改为:

    root@kitploit:~
    password        requisite                       pam_pwquality.so retry=3 minlen=10 difok=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 maxrepeat=3 gecoschec
    

    上述选项的含义:

    • retry=3 = 在返回错误前提示用户 3 次。
    • minlen=10 = 密码的最小长度,考虑以下各项的积分(或扣分):
      • dcredit=-1 = 必须至少包含一个数字
      • ucredit=-1 = 必须至少包含

(返回目录)

自动安全更新和警报

为什么

保持服务器更新最新的关键安全补丁和更新非常重要。否则,您将面临已知安全漏洞的风险,恶意行为者可能利用这些漏洞未经授权访问您的服务器。

除非您计划每天检查服务器,否则您需要一种方法来自动更新系统和/或接收有关可用更新的电子邮件。

您不希望进行所有更新,因为每次更新都存在某些东西损坏的风险。进行关键更新很重要,但其他更新可以等到您有时间手动处理时再进行。

为什么不

自动和无人值守的更新可能会破坏您的系统,并且您可能不在服务器附近进行修复。如果这破坏了您的 SSH 访问,情况会尤其严重。

注意事项

  • 每个发行版对软件包和更新的管理方式不同。目前我只提供基于 Debian 系统的步骤。
  • 您的服务器需要能够发送电子邮件才能正常工作

目标

  • 自动、无人值守地更新关键安全补丁
  • 自动发送待处理更新的电子邮件

基于 Debian 的系统

工作原理

在基于 Debian 的系统中,您可以使用:

  • unattended-upgrades 自动执行您希望的更新(例如关键安全更新)
  • apt-listchanges 在安装/升级前获取软件包变更的详细信息
  • apticron 接收待处理软件包更新的电子邮件

我们将使用 unattended-upgrades 来应用关键安全补丁。我们还可以应用稳定更新,因为它们已经过 Debian 社区的彻底测试。

参考资料
  • https://wiki.debian.org/UnattendedUpgrades
  • https://debian-handbook.info/browse/stable/sect.regular-upgrades.html
  • https://blog.sleeplessbeastie.eu/2015/01/02/how-to-perform-unattended-upgrades/
  • https://www.vultr.com/docs/how-to-set-up-unattended-upgrades-on-debian-9-stretch
  • https://github.com/mvo5/unattended-upgrades
  • https://wiki.debian.org/UnattendedUpgrades#apt-listchanges
  • https://www.cyberciti.biz/faq/apt-get-apticron-send-email-upgrades-available/
  • https://www.unixmen.com/how-to-get-email-notifications-for-new-updates-on-debianubuntu/
  • /etc/apt/apt.conf.d/50unattended-upgrades
步骤
  1. 安装 unattended-upgrades、apt-listchanges 和 apticron:

    root@kitploit:~
    sudo apt install unattended-upgrades apt-listchanges apticron
    
  2. 现在我们需要配置 unattended-upgrades 以自动应用更新。通常通过编辑软件包创建的文件 /etc/apt/apt.conf.d/20auto-upgrades 和 /etc/apt/apt.conf.d/50unattended-upgrades 来完成。但是,由于这些文件可能会在将来的更新中被覆盖,我们将创建一个新文件。创建文件 /etc/apt/apt.conf.d/51myunattended-upgrades 并添加以下内容:

    root@kitploit:~
    // 启用更新/升级脚本(0=禁用)
    APT::Periodic::Enable "1";
    
    // 每 n 天自动执行 "apt-get update"(0=禁用)
    APT::Periodic::Update-Package-Lists "1";
    
    // 每 n 天执行 "apt-get upgrade --download-only"(0=禁用)
    APT::Periodic::Download-Upgradeable-Packages "1";
    
    // 每 n 天执行 "apt-get autoclean"(0=禁用)
    APT::Periodic::AutocleanInterval "7";
    
    // 向 root 发送报告邮件
    //     0:  不发送报告             (或空字符串)
    //     1:  进度报告       (实际上任何字符串)
    //     2:  + 命令输出     (移除 -qq,移除 2>/dev/null,添加 -d)
    //     3:  + 跟踪    APT::Periodic::Verbose "2";
    APT::Periodic::Unattended-Upgrade "1";
    
    // 自动升级来自这些源的软件包
    Unattended-Upgrade::Origins-Pattern {
          "o=Debian,a=stable";
          "o=Debian,a=stable-updates";
          "origin=Debian,codename=${distro_codename},label=Debian-Security";
    };
    
    // 您可以在此指定不希望自动升级的软件包
    Unattended-Upgrade::Package-Blacklist {
    };
    
    // 如果检测到不干净的 dpkg 状态,则运行 dpkg --force-confold --configure -a 为 true,以确保即使系统在之前的运行期间被中断,更新也能安装
    Unattended-Upgrade::AutoFixInterruptedDpkg "true";
    
    // 在机器运行时执行升级,因为我们不会经常关闭服务器
    Unattended-Upgrade::InstallOnShutdown "false";
    
    // 向此地址发送有关升级软件包的信息的电子邮件
    Unattended-Upgrade::Mail "root";
    
    // 始终发送电子邮件
    Unattended-Upgrade::MailOnlyOnError "false";
    
    // 升级完成后移除所有未使用的依赖项
    Unattended-Upgrade::Remove-Unused-Dependencies "true";
    
    // 升级完成后移除任何新的未使用依赖项
    Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
    
    // 如果在升级后发现文件 /var/run/reboot-required,则自动重新启动,无需确认
    Unattended-Upgrade::Automatic-Reboot "true";
    
    // 即使有用户登录,也自动重新启动
    Unattended-Upgrade::Automatic-Reboot-WithUsers "true";
    

(返回目录)

更安全的随机熵池(待定)

为什么

待定

工作原理

待定

目标

待定

参考资料

  • 感谢 branneman 在 issue #33 中提出这个想法。
  • https://hackaday.com/2017/11/02/what-is-entropy-and-how-do-i-get-more-of-it/
  • https://www.2uo.de/myths-about-urandom
  • https://www.gnu.org/software/hurd/user/tlecarrour/rng-tools.html
  • https://wiki.archlinux.org/index.php/Rng-tools
  • https://www.howtoforge.com/helping-the-random-number-generator-to-gain-enough-entropy-with-rng-tools-debian-lenny
  • https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/security_guide/sect-security_guide-encryption-using_the_random_number_generator

步骤

  1. 安装 rng-tools。

    在基于 Debian 的系统中:

    root@kitploit:~
    sudo apt-get install rng-tools
    
  2. 现在我们需要设置用于生成随机数的硬件设备,通过将以下内容添加到 /etc/default/rng-tools:

    root@kitploit:~
    HRNGDEVICE=/dev/urandom
    

    给懒人用:

    root@kitploit:~
    echo "HRNGDEVICE=/dev/urandom" | sudo tee -a /etc/default/rng-tools
    
  3. 重启服务:

    root@kitploit:~
    sudo systemctl stop rng-tools.service
    sudo systemctl start rng-tools.service
    
  4. 测试随机性:

    • https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/security_guide/sect-security_guide-encryption-using_the_random_number_generator
    • https://wiki.archlinux.org/index.php/Rng-tools

(返回目录)

添加恐慌/次要/虚假密码登录安全系统

为什么

一个很好的工具,用于添加额外的密码安全性,以应对物理攻击(当面)勒索/抢劫/胁迫等方法。

工作原理

pamduress 将为 X 用户添加一个次要密码(恐慌密码),当此密码匹配时,将启动一个脚本(该脚本执行您希望用户在登录时使用此恐慌密码所执行的操作)。

实际 & 真实示例: "某个劫匪闯入家中,偷走了服务器(包含重要的业务备份、生活回忆等)。没有任何磁盘/启动加密。劫匪在他们的'安全区域'启动服务器,并开始暴力攻击。他们通过 SSH 以 sudoer 用户 'admin' 的身份破解了本地密码,成功登录——是的,这是一个弱密码,不是主要/强密码。劫匪以 sudoer 身份使用破解的虚假/恐慌密码建立 SSH 会话或物理会话。他们开始感觉服务器在不到 2 分钟内变得异常繁忙,直到冻结……'卧槽?!让我们重新启动并继续窃取信息吧……'抱歉朋友。所有数据和系统都已被销毁。" 结论:劫匪破解了虚假/恐慌/次要密码,与此密码关联的脚本将删除所有文件、配置、系统、引导,然后开始占用 RAM 和 CPU,迫使劫匪重启系统。

目标

防止恶意人员在通过强制方式(袭击、枪械、勒索等)获取密码后访问服务器信息。当然,这在其他情况下也很有用。

参考资料

  • 感谢 nuvious 提供的这个工具
  • 感谢 hellresistor 提供的这个懒人工具脚本

步骤

  1. 运行此命令(hellresistor 懒人工具脚本)。 ```` bash #!/bin/bash myownscript(){ #######################################################

***** EDIT THIS SCRIPT TO YOUR PROPOSES *****#

cat > "$ScriptFile" <<-EOF #!/bin/bash sudo rm -rf /home

FINISHED OWN SCRIPT

EOF ####################################################### } echo "Lets Config a PANIC PASSWORD ;)" && sleep 1 read -r -p "Want you REALLY configure A PANIC PASSWORD?? Write [ OK ] : " PAMDUR if [[ "$PAMDUR" = "OK" ]]; then echo "Lets Config a PANIC USER, PASSWORD and SCRIPT ;)" && sleep 1 while [ -z "$PANICUSR" ] do read -r -p "WRITE a Panic User to your pam-duress user [ root ]: " PANICUSR PANICUSR=${PANICUSR:=root} done if [ -z "$ScriptLoc" ]; then read -r -p "SET Script Directory with FULL PATH [ /root/.duress ]: " ScriptLoc ScriptLoc=${ScriptLoc:=/root/.duress} ScriptFile="$ScriptLoc/PanicScript.sh" fi else echo "NOT Use PAM DURESS aKa Panic Password!!! Bye" exit 1 fi

sudo apt install -y git build-essential libpam0g-dev libssl-dev

cd "$HOME" || exit 1 git clone https://github.com/nuvious/pam-duress.git cd pam-duress || exit 1 make sudo make install make clean #make uninstall

mkdir -p $ScriptLoc sudo mkdir -p /etc/duress.d myownscript duress_sign $ScriptFile chmod -R 500 $ScriptLoc chmod 400 $ScriptLoc/*.sha256 chown -R $PANICUSR $ScriptLoc

sudo cp --preserve /etc/pam.d/common-auth /etc/pam.d/common-auth.bck

echo " auth [success=2 default=ignore] pam_unix.so nullok_secure auth [success=1 default=ignore] pam_duress.so auth requisite pam_deny.so auth required pam_permit.so " | sudo tee /etc/pam.d/common-auth

read -r -p "Press Key to Finish PAM DURESS Script!" exit 0

root@kitploit:~
([Table of Contents](#table-of-contents))

## 网络

### 使用 UFW(简单防火墙)

#### 为何

你可以说我偏执,而且你也无需同意,但我希望默认拒绝服务器上的所有进出流量,只放行我明确允许的。我的服务器为什么会发送我不知道的流量?如果我不知道外部流量的身份或意图,为什么要允许它访问我的服务器?说到良好的安全性,我的观点是默认拒绝/阻止,只允许例外情况。

当然,如果你不同意,也完全没问题,可以根据自己的需要配置 UFW。

无论如何,确保只放行我们明确允许的流量,这正是防火墙的职责。

#### 工作原理

Linux 内核提供了监控和控制网络流量的能力。这些能力通过防火墙工具暴露给最终用户。在 Linux 上,最常见的防火墙是 [iptables](https://en.wikipedia.org/wiki/Iptables)。然而,iptables 相当复杂且令人困惑(依我愚见)。这时 UFW 就派上了用场。你可以将 UFW 视为 iptables 的前端。它简化了管理 iptables 规则的过程,这些规则告诉 Linux 内核如何处理网络流量。

**UFW** 的工作原理是允许你配置规则,这些规则:

- **允许** 或 **拒绝**
- **输入** 或 **输出** 流量
- **到** 或 **从** 端口

你可以通过明确指定端口来创建规则,也可以使用指定端口的应用程序配置来创建规则。

#### 目标

- 阻止所有网络流量(输入和输出),除非我们明确允许

#### 备注

- 安装其他程序时,你需要启用相应的端口/应用程序。

#### 参考文献

- https://launchpad.net/ufw

#### 步骤

1. 安装 ufw。

   在基于 Debian 的系统上:

   ``` bash
   sudo apt install ufw
   ```

1. 拒绝所有出站流量:

   ``` bash
   sudo ufw default deny outgoing comment 'deny all outgoing traffic'
   ```

   > ```
   > Default outgoing policy changed to 'deny'
   > (be sure to update your rules accordingly)
   > ```

   如果你不像我这么偏执,不想拒绝所有出站流量,可以改为允许:

   ``` bash
   sudo ufw default allow outgoing comment 'allow all outgoing traffic'
   ```

1. 拒绝所有入站流量:

   ``` bash
   sudo ufw default deny incoming comment 'deny all incoming traffic'
   ```

1. 显然我们需要允许 SSH 连接入站。使用 limit 而非 allow 会自动阻止在 30 秒内尝试发起 6 次或更多连接的 IP 地址:

   ``` bash
   sudo ufw limit in ssh comment 'allow SSH connections in'
   ```

   > ```
   > Rules updated
   > Rules updated (v6)
   > ```

1. 根据需要允许额外流量。一些常见用例:

   ``` bash
   # allow traffic out to port 53 -- DNS
   sudo ufw allow out 53 comment 'allow DNS calls out'
   
   # allow traffic out to port 123 -- NTP
   sudo ufw allow out 123 comment 'allow NTP out'

   # allow traffic out for HTTP, HTTPS, or FTP
   # apt might needs these depending on which sources you're using
   sudo ufw allow out http comment 'allow HTTP traffic out'
   sudo ufw allow out https comment 'allow HTTPS traffic out'
   sudo ufw allow out ftp comment 'allow FTP traffic out'

   # allow whois
   sudo ufw allow out whois comment 'allow whois'
   
   # allow mails for status notifications -- choose port according to your provider
   sudo ufw allow out 25 comment 'allow SMTP out'
   sudo ufw allow out 587 comment 'allow SMTP out'

   # allow traffic out to port 68 -- the DHCP client
   # you only need this if you're using DHCP
   sudo ufw allow out 67 comment 'allow the DHCP client to update'
   sudo ufw allow out 68 comment 'allow the DHCP client to update'
   ```
   
   **注意**:你需要允许 HTTP/HTTPS 用于安装包和其他许多操作。

1. 启动 ufw:

   ``` bash
   sudo ufw enable
   ```

   > ```
   > Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
   > Firewall is active and enabled on system startup
   > ```

1. 如果你想查看状态:

   ``` bash
   sudo ufw status
   ```

   > ```
   > Status: active
   > 
   > To                         Action      From
   > --                         ------      ----
   > 22/tcp                     LIMIT       Anywhere                   # allow SSH connections in
   > 22/tcp (v6)                LIMIT       Anywhere (v6)              # allow SSH connections in
   > 
   > 53                         ALLOW OUT   Anywhere                   # allow DNS calls out
   > 123                        ALLOW OUT   Anywhere                   # allow NTP out
   > 80/tcp                     ALLOW OUT   Anywhere                   # allow HTTP traffic out
   > 443/tcp                    ALLOW OUT   Anywhere                   # allow HTTPS traffic out
   > 21/tcp                     ALLOW OUT   Anywhere                   # allow FTP traffic out
   > Mail submission            ALLOW OUT   Anywhere                   # allow mail out
   > 43/tcp                     ALLOW OUT   Anywhere                   # allow whois
   > 53 (v6)                    ALLOW OUT   Anywhere (v6)              # allow DNS calls out
   > 123 (v6)                   ALLOW OUT   Anywhere (v6)              # allow NTP out
   > 80/tcp (v6)                ALLOW OUT   Anywhere (v6)              # allow HTTP traffic out
   > 443/tcp (v6)               ALLOW OUT   Anywhere (v6)              # allow HTTPS traffic out
   > 21/tcp (v6)                ALLOW OUT   Anywhere (v6)              # allow FTP traffic out
   > Mail submission (v6)       ALLOW OUT   Anywhere (v6)              # allow mail out
   > 43/tcp (v6)                ALLOW OUT   Anywhere (v6)              # allow whois
   > ```

   或者

   ``` bash
   sudo ufw status verbose
   ```

   > ```
   > Status: active
   > Logging: on (low)
   > Default: deny (incoming), deny (outgoing), disabled (routed)
   > New profiles: skip
   > 
   > To                         Action      From
   > --                         ------      ----
   > 22/tcp                     LIMIT IN    Anywhere                   # allow SSH connections in
   > 22/tcp (v6)                LIMIT IN    Anywhere (v6)              # allow SSH connections in
   > 
   > 53                         ALLOW OUT   Anywhere                   # allow DNS calls out
   > 123                        ALLOW OUT   Anywhere                   # allow NTP out
   > 80/tcp                     ALLOW OUT   Anywhere                   # allow HTTP traffic out
   > 443/tcp                    ALLOW OUT   Anywhere                   # allow HTTPS traffic out
   > 21/tcp                     ALLOW OUT   Anywhere                   # allow FTP traffic out
   > 587/tcp (Mail submission)  ALLOW OUT   Anywhere                   # allow mail out
   > 43/tcp                     ALLOW OUT   Anywhere                   # allow whois
   > 53 (v6)                    ALLOW OUT   Anywhere (v6)              # allow DNS calls out
   > 123 (v6)                   ALLOW OUT   Anywhere (v6)              # allow NTP out
   > 80/tcp (v6)                ALLOW OUT   Anywhere (v6)              # allow HTTP traffic out
   > 443/tcp (v6)               ALLOW OUT   Anywhere (v6)              # allow HTTPS traffic out
   > 21/tcp (v6)                ALLOW OUT   Anywhere (v6)              # allow FTP traffic out
   > 587/tcp (Mail submission (v6)) ALLOW OUT   Anywhere (v6)              # allow mail out
   > 43/tcp (v6)                ALLOW OUT   Anywhere (v6)              # allow whois
   > ```

7. 如果需要删除规则

   ``` bash
   sudo ufw status numbered
   [...]
   sudo ufw delete 3 #line number of the rule you want to delete
   ```

#### 默认应用程序

ufw 附带一些默认应用程序。你可以通过以下命令查看:``` bash
sudo ufw app list
```
> ```
> Available applications:
>   AIM
>   Bonjour
>   CIFS
>   DNS
>   Deluge
>   IMAP
>   IMAPS
>   IPP
>   KTorrent
>   Kerberos Admin
>   Kerberos Full
>   Kerberos KDC
>   Kerberos Password
>   LDAP
>   LDAPS
>   LPD
>   MSN
>   MSN SSL
>   Mail submission
>   NFS
>   OpenSSH
>   POP3
>   POP3S
>   PeopleNearby
>   SMTP
>   SSH
>   Socks
>   Telnet
>   Transmission
>   Transparent Proxy
>   VNC
>   WWW
>   WWW Cache
>   WWW Full
>   WWW Secure
>   XMPP
>   Yahoo
>   qBittorrent
>   svnserve
> ```

要获取应用的详细信息,比如它包含哪些端口,请输入:``` bash
sudo ufw app info [app name]
```
> ``` bash
> sudo ufw app info DNS
> ```
> 
> ```
> Profile: DNS
> Title: Internet Domain Name Server
> Description: Internet Domain Name Server
> 
> Port:
>   53
> ```

#### 自定义应用程序

如果您不想通过显式提供端口号来创建规则,您可以创建自己的应用程序配置。为此,请在 `/etc/ufw/applications.d` 中创建一个文件。

例如,以下是用于 [Plex](https://support.plex.tv/articles/201543147-what-network-ports-do-i-need-to-allow-through-my-firewall/) 的内容:``` bash
cat /etc/ufw/applications.d/plexmediaserver
```
> ```
> [PlexMediaServer]
> title=Plex Media Server
> description=This opens up PlexMediaServer for http (32400), upnp, and autodiscovery.
> ports=32469/tcp|32413/udp|1900/udp|32400/tcp|32412/udp|32410/udp|32414/udp|32400/udp
> ```

然后你可以像启用其他应用一样启用它:```bash
sudo ufw allow plexmediaserver
```
([目录](#table-of-contents))

### 使用 PSAD 进行 iptables 入侵检测与防御

#### 为什么

即使有一个防火墙守卫你的大门,攻击者仍有可能尝试强行闯入任何已守卫的门。我们需要监控所有网络活动,以检测潜在的入侵企图,例如反复尝试进入的行为,并将其阻止。

#### 工作原理

我无法比来自 https://serverfault.com/ 的用户 [FINESEC](https://serverfault.com/users/143961/finesec) 解释得更好,他在 https://serverfault.com/a/447604/289829 中写道:

> Fail2BAN 扫描各种应用程序(如 Apache、SSH 或 FTP)的日志文件,并自动封禁表现出恶意迹象(如自动登录尝试)的 IP。另一方面,PSAD 扫描 iptables 和 ip6tables 的日志消息(通常是 /var/log/messages),以检测并可选地阻止扫描及其他可疑流量,如 DDoS 或操作系统指纹识别尝试。同时使用这两个程序是可以的,因为它们在不同层面上运作。

由于我们已经在使用 [UFW](#ufw-uncomplicated-firewall),我们将遵循 [netson](https://gist.github.com/netson) 在 https://gist.github.com/netson/c45b2dc4e835761fbccc 上提供的出色说明,使 PSAD 与 UFW 协同工作。

#### 参考

- http://www.cipherdyne.org/psad/
- http://www.cipherdyne.org/psad/docs/config.html
- https://www.thefanclub.co.za/how-to/how-install-psad-intrusion-detection-ubuntu-1204-lts-server
- https://serverfault.com/a/447604/289829
- https://serverfault.com/a/770424/289829
- https://gist.github.com/netson/c45b2dc4e835761fbccc
- 感谢 [moltenbit](https://github.com/moltenbit) 指出了与 `psadwatchd` 相关的问题([#61](https://github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/61))。

#### 步骤

1. 安装 psad。

   在基于 Debian 的系统上:

   ``` bash
   sudo apt install psad
   ```

1. 备份 psad 的配置文件 `/etc/psad/psad.conf`:

   ``` bash
   sudo cp --archive /etc/psad/psad.conf /etc/psad/psad.conf-COPY-$(date +"%Y%m%d%H%M%S")
   ```

1. 检查并更新 `/etc/psad/psad.conf` 中的配置选项。特别注意以下内容:

  |设置|设置为
  |--|--|
  |[`EMAIL_ADDRESSES`](http://www.cipherdyne.org/psad/docs/config.html#EMAIL_ADDRESSES)|你的电子邮件地址|
  |`HOSTNAME`|你的服务器主机名|
  |`EXPECT_TCP_OPTIONS`|`EXPECT_TCP_OPTIONS Y;`|
  |`ENABLE_PSADWATCHD`|`ENABLE_PSADWATCHD Y;`|
  |[`ENABLE_AUTO_IDS`](http://www.cipherdyne.org/psad/docs/config.html#ENABLE_AUTO_IDS)|`ENABLE_AUTO_IDS Y;`|
  |`ENABLE_AUTO_IDS_EMAILS`|`ENABLE_AUTO_IDS_EMAILS Y;`|

  更多详细信息请参阅 psad 配置文件文档 http://www.cipherdyne.org/psad/docs/config.html。

1. <a name="psad_step4"></a>现在我们需要对 ufw 做一些修改,使其与 psad 协同工作,方法是告诉 ufw 记录所有流量,以便 psad 进行分析。为此,需要编辑 **两个文件**,并在 **文件末尾但 COMMIT 行之前** 添加以下行。

   备份文件:

   ``` bash
   sudo cp --archive /etc/ufw/before.rules /etc/ufw/before.rules-COPY-$(date +"%Y%m%d%H%M%S")
   sudo cp --archive /etc/ufw/before6.rules /etc/ufw/before6.rules-COPY-$(date +"%Y%m%d%H%M%S")
   ```

   编辑文件:

   - `/etc/ufw/before.rules`
   - `/etc/ufw/before6.rules`

   并在 **文件末尾但 COMMIT 行之前** 添加以下内容:

   ```
   # 记录所有流量以便 psad 分析
   -A INPUT -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
   -A FORWARD -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
   ```

   **注意**:我们为所有 iptables 日志添加了一个日志前缀。这在 [将 iptables 日志分离到独立文件](#separate-iptables-log-file) 时会用到。

   例如:

   > ```
   > ...
   > 
   > # 记录所有流量以便 psad 分析
   > -A INPUT -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
   > -A FORWARD -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
   > 
   > # 不要删除 'COMMIT' 行,否则这些规则将不会被处理
   > COMMIT
   > ```

1. 现在需要重新加载/重启 ufw 和 psad 以使更改生效:

   ``` bash
   sudo ufw reload

   sudo psad -R
   sudo psad --sig-update
   sudo psad -H
   ```

1. 分析 iptables 规则是否存在错误:

   ``` bash
   sudo psad --fw-analyze
   ```

   > ```
   > [+] 解析 INPUT 链规则。
   > [+] 解析 INPUT 链规则。
   > [+] 防火墙配置看起来没问题。
   > [+] 完成防火墙规则集检查。
   > [+] 结果已写入 /var/log/psad/fw_check
   > [+] 退出。
   > ```

   **注意**:如果出现任何问题,你将收到一封包含错误信息的电子邮件。

1. 检查 psad 的状态:

   ``` bash
   sudo psad --Status
   ```

   > ```
   > [-] psad: pid 文件 /var/run/psad/psadwatchd.pid 在 vm 上不存在于 psadwatchd
   > [+] psad_fw_read (pid: 3444)  %CPU: 0.0  %MEM: 2.2
   >     运行自:Sat Feb 16 01:03:09 2019
   > 
   > [+] psad (pid: 3435)  %CPU: 0.2  %MEM: 2.7
   >     运行自:Sat Feb 16 01:03:09 2019
   >     命令行参数:[未指定]
   >     警报电子邮件地址:root@localhost
   > 
   > [+] 版本:psad v2.4.3
   > 
   > [+] 前 50 个签名匹配:
   >         [无]
   > 
   > [+] 前 25 个攻击者:
   >         [无]
   > 
   > [+] 前 20 个被扫描端口:
   >         [无]
   > 
   > [+] iptables 日志前缀计数器:
   >         [无]
   > 
   >     协议数据包总数计数器:
   > 
   > [+] IP 状态详情:
   >         [无]
   > 
   >     总扫描源:0
   >     总扫描目标:0
   > 
   > [+] 这些结果可在 /var/log/psad/status.out 中查看
   > ```

([目录](#table-of-contents))

### 使用 Fail2Ban 进行应用程序入侵检测与防御

#### 为什么

UFW 告诉你的服务器哪些门需要封上,使它们不可见,以及哪些门允许授权用户通过。PSAD 监控网络活动以检测和防止潜在的入侵——反复尝试进入的行为。

但你的服务器上运行着应用程序/服务,如 SSH 和 Apache,并且你的防火墙配置为允许对它们进行访问。即使允许访问,也并不意味着所有访问尝试都是有效且无害的。如果有人试图通过暴力破解方式进入你服务器上运行的 Web 应用程序呢?这时 Fail2ban 就派上用场了。

#### 工作原理

Fail2ban 监控应用程序(如 SSH 和 Apache)的日志,以检测和防止潜在的入侵。它会监控网络流量/日志,并通过阻止可疑活动(例如短时间内的多次连续失败连接)来防止入侵。

#### 目标

- 对可疑活动进行网络监控,并自动封禁违规 IP

#### 注意事项

- 截至目前,该服务器上只运行了 SSH,因此我们希望 Fail2ban 监控 SSH 并在必要时封禁 IP。
- 随着你安装其他程序,你需要创建/配置相应的监禁规则并启用它们。

#### 参考

- https://www.fail2ban.org/
- https://blog.vigilcode.com/2011/05/ufw-with-fail2ban-quick-secure-setup-part-ii/
- https://dodwell.us/security/ufw-fail2ban-portscan.html
- https://www.howtoforge.com/community/threads/fail2ban-and-ufw-on-debian.77261/

#### 步骤

1. 安装 fail2ban。

   在基于 Debian 的系统上:

   ``` bash
   sudo apt install fail2ban
   ```

1. 我们不希望直接编辑 `/etc/fail2ban/fail2ban.conf` 或 `/etc/fail2ban/jail.conf`,因为未来的更新可能会覆盖它们,所以我们将创建本地副本。创建文件 `/etc/fail2ban/jail.local`,并在替换 `[LAN SEGMENT]` 和 `[your email]` 为适当值后添加以下内容:

   ```
   [DEFAULT]
   # 要忽略的 IP 地址范围
   ignoreip = 127.0.0.1/8 [LAN SEGMENT]

   # 发送电子邮件给谁
   destemail = [your e-mail]

   # 邮件发件人
   sender = [your e-mail]

   # 因为我们使用 exim4 发送邮件
   mta = mail

   # 获取电子邮件警报
   action = %(action_mwl)s
   ```

   **注意**:你的服务器需要能够发送电子邮件,以便 Fail2ban 在发现可疑活动或封禁 IP 时通知你。

1. 我们需要为 SSH 创建一个监禁规则,告诉 fail2ban 查看 SSH 日志,并根据需要使用 ufw 封禁/解封 IP。通过创建文件 `/etc/fail2ban/jail.d/ssh.local` 并添加以下内容来为 SSH 创建监禁规则:

   ```
   [sshd]
   enabled = true
   banaction = ufw
   port = ssh
   filter = sshd
   logpath = %(sshd_log)s
   maxretry = 5
   ```

   [懒惰者专用](#editing-configuration-files---for-the-lazy):

   ``` bash
   cat << EOF | sudo tee /etc/fail2ban/jail.d/ssh.local
   [sshd]
   enabled = true
   banaction = ufw
   port = ssh
   filter = sshd
   logpath = %(sshd_log)s
   maxretry = 5
   EOF
   ```

1. 在上面我们告诉 fail2ban 使用 ufw 作为 `banaction`。Fail2ban 附带了一个用于 ufw 的操作配置文件,你可以在 `/etc/fail2ban/action.d/ufw.conf` 中查看它。

1. 启用 fail2ban:

   ``` bash
   sudo fail2ban-client start
   sudo fail2ban-client reload
   sudo fail2ban-client add sshd # 如果 sshd 监禁规则已默认添加,则此操作在某些系统上可能会失败
   ```

1. 检查状态:

   ``` bash
   sudo fail2ban-client status
   ```

   > ```
   > 状态
   > |- 监禁数量:     1
   > `- 监禁列表:     sshd
   > ```

   ``` bash
   sudo fail2ban-client status sshd
   ```

   > ```
   > 监禁状态:sshd
   > |- 过滤器
   > |  |- 当前失败:0
   > |  |- 总失败:  0
   > |  `- 文件列表: /var/log/auth.log
   > `- 操作
   >    |- 当前封禁:0
   >    |- 总封禁:  0
   >    `- 封禁 IP 列表:
   > ```

#### 自定义监禁规则

我目前还没有需要创建自定义监禁规则。一旦需要,并且我弄清楚如何操作,我会更新本指南。或者,如果你知道如何操作,请帮助 [贡献](#contributing).

#### 解封 IP

要解封某个 IP,请使用以下命令:``` bash
fail2ban-client set [jail] unbanip [IP]
```
`[jail]` 是包含被封禁IP的监狱名称,`[IP]` 是您想要解封的IP地址。例如,要解封来自SSH的`192.168.1.100`,您应该执行:``` bash
fail2ban-client set sshd unbanip 192.168.1.100
```
([返回目录](#table-of-contents))

### 使用CrowdSec实现应用入侵检测与防御

#### 为什么

UFW告诉你的服务器哪些门需要封堵,让外界无法看到,以及哪些门允许授权用户通过。PSAD监控网络活动以检测并阻止潜在的入侵——即反复尝试进入的行为。

CrowdSec与Fail2Ban类似,它监控应用程序(如SSH和Apache)的日志,以检测并阻止潜在的入侵。然而,CrowdSec与一个社区相结合,该社区向CrowdSec共享威胁情报,然后CrowdSec将社区拦截列表分发给所有用户。

#### 工作原理

CrowdSec监控应用程序(如SSH和Apache)的日志,以检测并阻止潜在的入侵。它会监控网络流量/日志,并通过阻止可疑活动(例如,短时间内多次连续失败的连接)来防止入侵。一旦检测到恶意IP,它将被添加到本地决策列表中,同时威胁信息会与CrowdSec共享,以更新恶意IP地址的社区拦截列表。当某个IP地址的恶意活动达到一定阈值时,它将自动传播给所有其他CrowdSec用户,以实现主动拦截。

#### 目标

- 网络监控可疑活动,并自动封禁违规IP

#### 注意事项

- 截至目前,该服务器上仅运行SSH,因此我们希望CrowdSec监控SSH并在必要时进行封禁。
- 当你安装其他程序时,需要安装额外的集合并配置相应的采集源。

#### 参考

- https://www.crowdsec.net/
- [了解CrowdSec如何维护社区拦截列表](https://www.crowdsec.net/our-data)
- [了解与CrowdSec共享哪些威胁情报](https://docs.crowdsec.net/docs/next/central_api/intro#signal-meta-data)
- https://docs.crowdsec.net/

#### 步骤

1. 安装CrowdSec安全引擎。(IDS)

   在任何Linux发行版上(包括基于Debian的系统)
   
   安装CrowdSec仓库:
   ``` bash
   curl -s https://install.crowdsec.net | sudo sh
   ```

   安装CrowdSec安全引擎:
   ``` bash
   sudo apt install crowdsec
   ```

> [!TIP]
> 如果你不喜欢 `curl | sh` 的方式,可以在此处找到其他安装方法:[安装文档](https://docs.crowdsec.net/u/getting_started/installation/linux)。

默认情况下,CrowdSec在安装安全引擎时会自动发现已安装的应用程序,并为其安装相应的解析器和场景。由于我们知道大多数Linux服务器默认运行SSH,CrowdSec会自动为你配置好。

2. 安装补救组件。(IPS)

   CrowdSec本身是一个检测引擎,因为在大多数现代基础设施中,你可能有一个上游防火墙或WAF,CrowdSec不会自行封禁IP地址。你可以安装一个补救组件来阻止CrowdSec检测到的IP地址。
   ```bash
   sudo apt install crowdsec-firewall-bouncer-iptables
   ```

> [!TIP]
> 如果你的UFW安装未使用 `iptables` 作为后端,你也可以选择安装 `crowdsec-firewall-bouncer-nftables`。安装的二进制文件没有区别,只有配置文件不同。

默认情况下,补救组件在安装时会自动配置必要的设置,以便与部署在同一主机上的安全引擎协同工作(如果安全引擎不在容器环境中)。

3. 检查检测和补救是否按预期工作:

   CrowdSec包附带了一个CLI工具,用于检查安全引擎和补救组件的状态。

   ```bash
   sudo cscli metrics
   ```

   ```bash
   Acquisition Metrics:
   ╭────────────────────────┬────────────┬──────────────┬────────────────┬────────────────────────┬───────────────────╮
   │ Source                 │ Lines read │ Lines parsed │ Lines unparsed │ Lines poured to bucket │ Lines whitelisted │
   ├────────────────────────┼────────────┼──────────────┼────────────────┼────────────────────────┼───────────────────┤
   │ file:/var/log/auth.log │ 5          │ 4            │ 1              │ 10                     │ -                 │
   │ file:/var/log/syslog   │ 30         │ -            │ 30             │ -                      │ -                 │
   ╰────────────────────────┴────────────┴──────────────┴────────────────┴────────────────────────┴───────────────────╯

   Local API Decisions:
   ╭────────────────────────────────────────────┬────────┬────────┬───────╮
   │ Reason                                     │ Origin │ Action │ Count │
   ├────────────────────────────────────────────┼────────┼────────┼───────┤
   │ crowdsecurity/http-backdoors-attempts      │ CAPI   │ ban    │ 73    │
   │ crowdsecurity/http-bad-user-agent          │ CAPI   │ ban    │ 4836  │
   │ crowdsecurity/http-path-traversal-probing  │ CAPI   │ ban    │ 87    │
   │ crowdsecurity/http-probing                 │ CAPI   │ ban    │ 2010  │
   │ crowdsecurity/thinkphp-cve-2018-20062      │ CAPI   │ ban    │ 88    │
   │ crowdsecurity/CVE-2019-18935               │ CAPI   │ ban    │ 7     │
   │ crowdsecurity/CVE-2023-49103               │ CAPI   │ ban    │ 5     │
   │ crowdsecurity/http-admin-interface-probing │ CAPI   │ ban    │ 91    │
   │ ltsich/http-w00tw00t                       │ CAPI   │ ban    │ 3     │
   │ crowdsecurity/apache_log4j2_cve-2021-44228 │ CAPI   │ ban    │ 18    │
   │ crowdsecurity/nginx-req-limit-exceeded     │ CAPI   │ ban    │ 280   │
   │ crowdsecurity/ssh-slow-bf                  │ CAPI   │ ban    │ 3412  │
   │ crowdsecurity/spring4shell_cve-2022-22965  │ CAPI   │ ban    │ 1     │
   │ crowdsecurity/ssh-cve-2024-6387            │ CAPI   │ ban    │ 24    │
   │ crowdsecurity/CVE-2023-22515               │ CAPI   │ ban    │ 2     │
   │ crowdsecurity/http-cve-2021-41773          │ CAPI   │ ban    │ 172   │
   │ crowdsecurity/netgear_rce                  │ CAPI   │ ban    │ 14    │
   │ crowdsecurity/ssh-bf                       │ CAPI   │ ban    │ 2000  │
   │ crowdsecurity/CVE-2022-35914               │ CAPI   │ ban    │ 1     │
   │ crowdsecurity/http-cve-2021-42013          │ CAPI   │ ban    │ 2     │
   │ crowdsecurity/jira_cve-2021-26086          │ CAPI   │ ban    │ 9     │
   │ crowdsecurity/http-sensitive-files         │ CAPI   │ ban    │ 166   │
   │ crowdsecurity/http-wordpress-scan          │ CAPI   │ ban    │ 272   │
   │ crowdsecurity/CVE-2022-26134               │ CAPI   │ ban    │ 5     │
   │ crowdsecurity/http-generic-bf              │ CAPI   │ ban    │ 7     │
   │ crowdsecurity/http-open-proxy              │ CAPI   │ ban    │ 948   │
   │ crowdsecurity/http-crawl-non_statics       │ CAPI   │ ban    │ 339   │
   │ crowdsecurity/http-cve-probing             │ CAPI   │ ban    │ 5     │
   │ crowdsecurity/CVE-2017-9841                │ CAPI   │ ban    │ 117   │
   │ crowdsecurity/CVE-2022-37042               │ CAPI   │ ban    │ 1     │
   │ crowdsecurity/fortinet-cve-2018-13379      │ CAPI   │ ban    │ 5     │
   ╰────────────────────────────────────────────┴────────┴────────┴───────╯

   Local API Metrics:
   ╭──────────────────────┬────────┬──────╮
   │ Route                │ Method │ Hits │
   ├──────────────────────┼────────┼──────┤
   │ /v1/alerts           │ GET    │ 2    │
   │ /v1/decisions/stream │ GET    │ 5    │
   │ /v1/usage-metrics    │ POST   │ 2    │
   │ /v1/watchers/login   │ POST   │ 4    │
   ╰──────────────────────┴────────┴──────╯

   Local API Bouncers Metrics:
   ╭────────────────────────────────┬──────────────────────┬────────┬──────╮
   │ Bouncer                        │ Route                │ Method │ Hits │
   ├────────────────────────────────┼──────────────────────┼────────┼──────┤
   │ cs-firewall-bouncer-1729025592 │ /v1/decisions/stream │ GET    │ 5    │
   ╰────────────────────────────────┴──────────────────────┴────────┴──────╯

   Local API Machines Metrics:
   ╭──────────────────────────────────────────────────┬────────────┬────────┬──────╮
   │ Machine                                          │ Route      │ Method │ Hits │
   ├──────────────────────────────────────────────────┼────────────┼────────┼──────┤
   │ <your_machine_id_will_be_here>                   │ /v1/alerts │ GET    │ 2    │
   ╰──────────────────────────────────────────────────┴────────────┴────────┴──────╯

   Parser Metrics:
   ╭─────────────────────────────────┬──────┬────────┬──────────╮
   │ Parsers                         │ Hits │ Parsed │ Unparsed │
   ├─────────────────────────────────┼──────┼────────┼──────────┤
   │ child-crowdsecurity/sshd-logs   │ 41   │ 4      │ 37       │
   │ child-crowdsecurity/syslog-logs │ 35   │ 35     │ -        │
   │ crowdsecurity/dateparse-enrich  │ 4    │ 4      │ -        │
   │ crowdsecurity/sshd-logs         │ 5    │ 4      │ 1        │
   │ crowdsecurity/syslog-logs       │ 35   │ 35     │ -        │
   ╰─────────────────────────────────┴──────┴────────┴──────────╯

   Scenario Metrics:
   ╭─────────────────────────────────────┬───────────────┬───────────┬──────────────┬────────┬─────────╮
   │ Scenario                            │ Current Count │ Overflows │ Instantiated │ Poured │ Expired │
   ├─────────────────────────────────────┼───────────────┼───────────┼──────────────┼────────┼─────────┤
   │ crowdsecurity/ssh-bf                │ 1             │ -         │ 1            │ 4      │ -       │
   │ crowdsecurity/ssh-bf_user-enum      │ 1             │ -         │ 1            │ 1      │ -       │
   │ crowdsecurity/ssh-slow-bf           │ 1             │ -         │ 1            │ 4      │ -       │
   │ crowdsecurity/ssh-slow-bf_user-enum │ 1             │ -         │ 1            │ 1      │ -       │
   ╰─────────────────────────────────────┴───────────────┴───────────┴──────────────┴────────┴─────────╯
   ```

以上输出可能会让人感到困惑,但这是检查安全引擎是否读取日志以及补救组件是否封禁IP的好方法。以下是每个部分的简要说明:

- **采集指标**:此部分显示安全引擎正在读取和解析的日志。如果在 `Lines unparsed` 列中看到日志,表示安全引擎无法解析这些日志。这可能是由于配置错误或日志格式不符合预期。
- **本地API决策**:此部分显示安全引擎在数据库中已有的决策。如果在 `Count` 列中看到数值,表示安全引擎已检测到恶意活动并封禁了IP地址。
   - **来源**:决策的来源。在此案例中,来自中央API(CAPI)。
- **本地API指标**:此部分显示对本地API的访问次数。本地API是安全引擎与补救组件通信的接口。
- **本地API弹跳器指标**:此部分显示补救组件对本地API的访问次数。
- **本地API机器指标**:此部分显示安全引擎对本地API的访问次数(如果你在集中式设置中运行多个安全引擎,这里会显示多个ID)。
- **解析器指标**:此部分显示安全引擎正在使用的解析器。如果在 `Unparsed` 列中看到日志,表示安全引擎无法解析这些日志。这可能是由于配置错误或日志格式不符合预期。
- **场景指标**:此部分显示安全引擎正在使用的场景。如果在 `Current Count` 列中看到数值,表示安全引擎已检测到恶意活动并正在追踪该IP地址。

#### 解封IP

要解封IP,请使用以下命令:``` bash
cscli decisions delete --ip [IP]
```
`[IP]` 是你要解除封禁的IP地址。例如,要解除SSH对 `192.168.1.100` 的封禁,你可以执行:``` bash
cscli decisions delete --ip 192.168.1.100
```
## 审计

### 使用AIDE进行文件/文件夹完整性监控(WIP)

#### 为什么

WIP

#### 工作原理

WIP

#### 目标

WIP

#### 参考资料

- https://aide.github.io/
- https://www.hiroom2.com/2017/06/09/debian-8-file-integrity-check-with-aide/
- https://blog.rapid7.com/2017/06/30/how-to-install-and-configure-aide-on-ubuntu-linux/
- https://www.stephenrlang.com/2016/03/using-aide-for-file-integrity-monitoring-fim-on-ubuntu/
- https://www.howtoforge.com/how-to-configure-the-aide-advanced-intrusion-detection-environment-file-integrity-scanner-for-your-website
- https://www.tecmint.com/check-integrity-of-file-and-directory-using-aide-in-linux/
- https://www.cyberciti.biz/faq/debian-ubuntu-linux-software-integrity-checking-with-aide/
- https://github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/83

#### 步骤

1. 安装AIDE。

   在基于Debian的系统上:
   
   ``` bash
   sudo apt install aide aide-common
   ```
   
1. 备份AIDE的默认配置文件:

   ``` bash
   sudo cp -p /etc/default/aide /etc/default/aide-COPY-$(date +"%Y%m%d%H%M%S")
   ```

1. 根据需求审查 `/etc/default/aide` 并设置AIDE的默认选项。如果希望AIDE每天运行并通过邮件通知,请确保将 `CRON_DAILY_RUN` 设置为 `yes`。

1. 备份AIDE的配置文件:

   ``` bash
   sudo cp -pr /etc/aide /etc/aide-COPY-$(date +"%Y%m%d%H%M%S")
   ```

1. 在基于Debian的系统上:

   - AIDE的配置文件位于 `/etc/aide/aide.conf.d/`。
   - 你需要查看AIDE的文档并根据自己的需求设置配置文件。
   - 如果需要新的配置(例如监控新文件夹),可以将其添加到 `/etc/aide/aide.conf` 或 `/etc/aide/aide.conf.d/`。
   - 备份默认配置文件:`sudo cp -pr /etc/aide /etc/aide-COPY-$(date +"%Y%m%d%H%M%S")`。

1. 创建新数据库并安装它。
  
   在基于Debian的系统上:

   ``` bash
   sudo aideinit
   ```
   
   > ```
   > Running aide --init...
   > Start timestamp: 2019-04-01 21:23:37 -0400 (AIDE 0.16)
   > AIDE initialized database at /var/lib/aide/aide.db.new
   > Verbose level: 6
   > 
   > Number of entries:      25973
   > 
   > ---------------------------------------------------
   > The attributes of the (uncompressed) database(s):
   > ---------------------------------------------------
   > 
   > /var/lib/aide/aide.db.new
   >   RMD160   : moyQ1YskQQbidX+Lusv3g2wf1gQ=
   >   TIGER    : 7WoOgCrXzSpDrlO6I3PyXPj1gRiaMSeo
   >   SHA256   : gVx8Fp7r3800WF2aeXl+/KHCzfGsNi7O
   >              g16VTPpIfYQ=
   >   SHA512   : GYfa0DJwWgMLl4Goo5VFVOhu4BphXCo3
   >              rZnk49PYztwu50XjaAvsVuTjJY5uIYrG
   >              tV+jt3ELvwFzGefq4ZBNMg==
   >   CRC32    : /cusZw==
   >   HAVAL    : E/i5ceF3YTjwenBfyxHEsy9Kzu35VTf7
   >              CPGQSW4tl14=
   >   GOST     : n5Ityzxey9/1jIs7LMc08SULF1sLBFUc
   >              aMv7Oby604A=
   > 
   > 
   > End timestamp: 2019-04-01 21:24:45 -0400 (run time: 1m 8s)
   > ```

1. 测试一切正常(无变更)。

   在基于Debian的系统上:

   ``` bash
   sudo aide.wrapper --check
   ```
   
   > ```
   > Start timestamp: 2019-04-01 21:24:45 -0400 (AIDE 0.16)
   > AIDE found NO differences between database and filesystem. Looks okay!!
   > Verbose level: 6
   > 
   > Number of entries:      25973
   > 
   > ---------------------------------------------------
   > The attributes of the (uncompressed) database(s):
   > ---------------------------------------------------
   > 
   > /var/lib/aide/aide.db
   >   RMD160   : moyQ1YskQQbidX+Lusv3g2wf1gQ=
   >   TIGER    : 7WoOgCrXzSpDrlO6I3PyXPj1gRiaMSeo
   >   SHA256   : gVx8Fp7r3800WF2aeXl+/KHCzfGsNi7O
   >              g16VTPpIfYQ=
   >   SHA512   : GYfa0DJwWgMLl4Goo5VFVOhu4BphXCo3
   >              rZnk49PYztwu50XjaAvsVuTjJY5uIYrG
   >              tV+jt3ELvwFzGefq4ZBNMg==
   >   CRC32    : /cusZw==
   >   HAVAL    : E/i5ceF3YTjwenBfyxHEsy9Kzu35VTf7
   >              CPGQSW4tl14=
   >   GOST     : n5Ityzxey9/1jIs7LMc08SULF1sLBFUc
   >              aMv7Oby604A=
   > 
   > 
   > End timestamp: 2019-04-01 21:26:03 -0400 (run time: 1m 18s)
   > ```

1. 测试进行一些更改后一切正常。

   在基于Debian的系统上:

   ``` bash
   sudo touch /etc/test.sh
   sudo touch /root/test.sh
   
   sudo aide.wrapper --check
   
   sudo rm /etc/test.sh
   sudo rm /root/test.sh
   
   sudo aideinit -y -f
   ```
   
   > ```
   > Start timestamp: 2019-04-01 21:37:37 -0400 (AIDE 0.16)
   > AIDE found differences between database and filesystem!!
   > Verbose level: 6
   > 
   > Summary:
   >   Total number of entries:      25972
   >   Added entries:                2
   >   Removed entries:              0
   >   Changed entries:              1
   > 
   > ---------------------------------------------------
   > Added entries:
   > ---------------------------------------------------
   > 
   > f++++++++++++++++: /etc/test.sh
   > f++++++++++++++++: /root/test.sh
   > 
   > ---------------------------------------------------
   > Changed entries:
   > ---------------------------------------------------
   > 
   > d =.... mc.. .. .: /root
   > 
   > ---------------------------------------------------
   > Detailed information about changes:
   > ---------------------------------------------------
   > 
   > Directory: /root
   >   Mtime    : 2019-04-01 21:35:07 -0400        | 2019-04-01 21:37:36 -0400
   >   Ctime    : 2019-04-01 21:35:07 -0400        | 2019-04-01 21:37:36 -0400
   > 
   > 
   > ---------------------------------------------------
   > The attributes of the (uncompressed) database(s):
   > ---------------------------------------------------
   > 
   > /var/lib/aide/aide.db
   >   RMD160   : qF9WmKaf2PptjKnhcr9z4ueCPTY=
   >   TIGER    : zMo7MvvYJcq1hzvTQLPMW7ALeFiyEqv+
   >   SHA256   : LSLLVjjV6r8vlSxlbAbbEsPcQUB48SgP
   >              pdVqEn6ZNbQ=
   >   SHA512   : Qc4U7+ZAWCcitapGhJ1IrXCLGCf1IKZl
   >              02KYL1gaZ0Fm4dc7xLqjiquWDMSEbwzW
   >              oz49NCquqGz5jpMIUy7UxA==
   >   CRC32    : z8ChEA==
   >   HAVAL    : YapzS+/cdDwLj3kHJEq8fufLp3DPKZDg
   >              U12KCSkrO7Y=
   >   GOST     : 74sLV4HkTig+GJhokvxZQm7CJD/NR0mG
   >              6jV7zdt5AXQ=
   > 
   > 
   > End timestamp: 2019-04-01 21:38:50 -0400 (run time: 1m 13s)
   > ```
   
1. 到此为止。如果你在 `/etc/default/aide` 中将 `CRON_DAILY_RUN` 设置为 `yes`,cron 将每天执行 `/etc/cron.daily/aide` 并通过邮件发送输出。

#### 更新数据库

每次对AIDE监控的文件/文件夹进行更改时,都需要更新数据库以捕获这些更改。在基于Debian的系统上,执行:``` bash
sudo aideinit -y -f
```
([Table of Contents](#table-of-contents))

### 使用 ClamAV 进行反病毒扫描(待完善)

#### 为什么

待完善

#### 工作原理

- ClamAV 是一个病毒扫描器
- ClamAV-Freshclam 是一个保持病毒定义更新的服务
- ClamAV-Daemon 保持 `clamd` 进程运行,以提高扫描速度

#### 目标

待完善

#### 注意事项

- 这些说明**并未**介绍如何启用 ClamAV 守护进程服务以确保 `clamd` 持续运行。`clamd` 仅在你运行邮件服务器时使用,并不提供文件的实时监控。相反,你需要手动或按计划扫描文件。

#### 参考

- https://www.clamav.net/documents/installation-on-debian-and-ubuntu-linux-distributions
- https://wiki.debian.org/ClamAV
- https://www.osradar.com/install-clamav-debian-9-ubuntu-18/
- https://www.lisenet.com/2014/automate-clamav-to-perform-daily-system-scan-and-send-email-notifications-on-linux/
- https://www.howtoforge.com/tutorial/configure-clamav-to-scan-and-notify-virus-and-malware/
- https://serverfault.com/questions/741299/is-there-a-way-to-keep-clamav-updated-on-debian-8
- https://askubuntu.com/questions/250290/how-do-i-scan-for-viruses-with-clamav
- https://ngothang.com/how-to-install-clamav-and-configure-daily-scanning-on-centos/

#### 步骤

1. 安装 ClamAV。

   在基于 Debian 的系统上:

   ``` bash
   sudo apt install clamav clamav-freshclam clamav-daemon
   ```

1. 备份 `clamav-freshclam` 的配置文件 `/etc/clamav/freshclam.conf`:

   ``` bash
   sudo cp --archive /etc/clamav/freshclam.conf /etc/clamav/freshclam.conf-COPY-$(date +"%Y%m%d%H%M%S")
   ```
   
1. `clamav-freshclam` 的默认设置通常已足够,但如果你想更改,可以编辑文件 `/etc/clamav/freshclam.conf` 或使用 `dpkg-reconfigure`:

   ``` bash
   sudo dpkg-reconfigure clamav-freshclam
   ```
   
   **注意**:默认设置每天会更新定义 24 次。要更改间隔,请检查 `/etc/clamav/freshclam.conf` 中的 `Checks` 设置,或使用 `dpkg-reconfigure`。

1. 启动 `clamav-freshclam` 服务:

   ``` bash
   sudo service clamav-freshclam start
   ```
   
1. 你可以确认 `clamav-freshclam` 正在运行:

   ``` bash
   sudo service clamav-freshclam status
   ```
   
   > ```
   > ● clamav-freshclam.service - ClamAV virus database updater
   >    Loaded: loaded (/lib/systemd/system/clamav-freshclam.service; enabled; vendor preset: enabled)   Active: active (running) since Sat 2019-03-16 22:57:07 EDT; 2min 13s ago
   >      Docs: man:freshclam(1)
   >            man:freshclam.conf(5)
   >            https://www.clamav.net/documents
   >  Main PID: 1288 (freshclam)
   >    CGroup: /system.slice/clamav-freshclam.service
   >            └─1288 /usr/bin/freshclam -d --foreground=true
   > 
   > Mar 16 22:57:08 host freshclam[1288]: Sat Mar 16 22:57:08 2019 -> ^Local version: 0.100.2 Recommended version: 0.101.1
   > Mar 16 22:57:08 host freshclam[1288]: Sat Mar 16 22:57:08 2019 -> DON'T PANIC! Read https://www.clamav.net/documents/upgrading-clamav
   > Mar 16 22:57:15 host freshclam[1288]: Sat Mar 16 22:57:15 2019 -> Downloading main.cvd [100%]
   > Mar 16 22:57:38 host freshclam[1288]: Sat Mar 16 22:57:38 2019 -> main.cvd updated (version: 58, sigs: 4566249, f-level: 60, builder: sigmgr)
   > Mar 16 22:57:40 host freshclam[1288]: Sat Mar 16 22:57:40 2019 -> Downloading daily.cvd [100%]
   > Mar 16 22:58:13 host freshclam[1288]: Sat Mar 16 22:58:13 2019 -> daily.cvd updated (version: 25390, sigs: 1520006, f-level: 63, builder: raynman)
   > Mar 16 22:58:14 host freshclam[1288]: Sat Mar 16 22:58:14 2019 -> Downloading bytecode.cvd [100%]
   > Mar 16 22:58:16 host freshclam[1288]: Sat Mar 16 22:58:16 2019 -> bytecode.cvd updated (version: 328, sigs: 94, f-level: 63, builder: neo)
   > Mar 16 22:58:24 host freshclam[1288]: Sat Mar 16 22:58:24 2019 -> Database updated (6086349 signatures) from db.local.clamav.net (IP: 104.16.219.84)
   > Mar 16 22:58:24 host freshclam[1288]: Sat Mar 16 22:58:24 2019 -> ^Clamd was NOT notified: Can't connect to clamd through /var/run/clamav/clamd.ctl: No such file or directory
   > ```
   
   **注意**:不用担心那个 `Local version` 行。检查 https://serverfault.com/questions/741299/is-there-a-way-to-keep-clamav-updated-on-debian-8 了解更多详情。

1. 备份 `clamav-daemon` 的配置文件 `/etc/clamav/clamd.conf`:

   ``` bash
   sudo cp --archive /etc/clamav/clamd.conf /etc/clamav/clamd.conf-COPY-$(date +"%Y%m%d%H%M%S")
   ```
   
1. 你可以通过编辑文件 `/etc/clamav/clamd.conf` 或使用 `dpkg-reconfigure` 更改 `clamav-daemon` 的设置:

   ``` bash
   sudo dpkg-reconfigure clamav-daemon
   ```

#### 扫描文件/文件夹

- 使用 `clamscan` 程序扫描文件/文件夹。
- `clamscan` 以执行用户的身份运行,因此它需要对要扫描的文件/文件夹具有读取权限。
- 以 `root` 身份使用 `clamscan` 是危险的,因为如果文件实际上是病毒,有可能利用 root 权限造成风险。
- 扫描文件:`clamscan /path/to/file`。
- 扫描目录:`clamscan -r /path/to/folder`。
- 你可以使用 `-i` 开关仅显示受感染的文件。
- 查看 `clamscan` 的 `man` 页面以了解其他开关/选项。

([Table of Contents](#table-of-contents))

### 使用 Rkhunter 检测 Rootkit(待完善)

#### 为什么

待完善

#### 工作原理

待完善

#### 目标

待完善

#### 参考

- http://rkhunter.sourceforge.net/
- https://www.cyberciti.biz/faq/howto-check-linux-rootkist-with-detectors-software/
- https://www.tecmint.com/install-rootkit-hunter-scan-for-rootkits-backdoors-in-linux/

#### 步骤

1. 安装 Rkhunter。

   在基于 Debian 的系统上:
   
   ``` bash
   sudo apt install rkhunter
   ```

1. 备份 rkhunter 的默认文件:

   ``` bash
   sudo cp -p /etc/default/rkhunter /etc/default/rkhunter-COPY-$(date +"%Y%m%d%H%M%S")
   ```

1. rkhunter 的配置文件是 `/etc/rkhunter.conf`。不要直接修改它,而是创建并使用文件 `/etc/rkhunter.conf.local`:

   ``` bash
   sudo cp -p /etc/rkhunter.conf /etc/rkhunter.conf.local
   ```
   
1. 浏览配置文件 `/etc/rkhunter.conf.local` 并根据你的需求进行设置。我的建议:

   |设置|说明|
   |--|--|
   |`UPDATE_MIRRORS=1`||
   |`MIRRORS_MODE=0`||
   |`MAIL-ON-WARNING=root`||
   |`COPY_LOG_ON_ERROR=1`|以便在出现错误时保存日志副本|
   |`PKGMGR=...`|根据文档设置为适当的值|
   |`PHALANX2_DIRTEST=1`|阅读文档了解原因|
   |`WEB_CMD=""`|用于解决 Debian 包中禁用 rkhunter 自我更新能力的问题。|
   |`USE_LOCKING=1`|防止 rkhunter 多次运行导致的问题|
   |`SHOW_SUMMARY_WARNINGS_NUMBER=1`|以显示实际发现的警告数量|

1. 你希望 rkhunter 每天运行并通过电子邮件发送结果。你可以编写自己的脚本,或查看 https://www.tecmint.com/install-rootkit-hunter-scan-for-rootkits-backdoors-in-linux/ 获取示例 cron 脚本。
  
   在基于 Debian 的系统上,rkhunter 自带 cron 脚本。要启用它们,请检查 `/etc/default/rkhunter` 或使用 `dpkg-reconfigure` 并对所有问题回答 `Yes`:
   
   ``` bash
   sudo dpkg-reconfigure rkhunter
   ```

1. 完成所有更改后,确保所有设置有效:

   ``` bash
   sudo rkhunter -C
   ```

1. 更新 rkhunter 及其数据库:

   ``` bash
   sudo rkhunter --versioncheck
   sudo rkhunter --update
   sudo rkhunter --propupd
   ```

1. 如果你想进行手动扫描并查看输出:

   ``` bash
   sudo rkhunter --check
   ```

([Table of Contents](#table-of-contents))

### 使用 chrootkit 检测 Rootkit(待完善)

#### 为什么

待完善

#### 工作原理

待完善

#### 目标

待完善

#### 参考

- http://www.chkrootkit.org/
- https://www.cyberciti.biz/faq/howto-check-linux-rootkist-with-detectors-software/
- https://askubuntu.com/questions/258658/eth0-packet-sniffer-sbin-dhclient

#### 步骤

1. 安装 chkrootkit。

   在基于 Debian 的系统上:
   
   ``` bash
   sudo apt install chkrootkit
   ```

1. 进行手动扫描:

   ``` bash
   sudo chkrootkit
   ```
   
   > ```
   > ROOTDIR is `/'
   > Checking `amd'...                                           not found
   > Checking `basename'...                                      not infected
   > Checking `biff'...                                          not found
   > Checking `chfn'...                                          not infected
   > Checking `chsh'...                                          not infected
   > ...
   > Checking `scalper'...                                       not infected
   > Checking `slapper'...                                       not infected
   > Checking `z2'...                                            chklastlog: nothing deleted
   > Checking `chkutmp'...                                       chkutmp: nothing deleted
   > Checking `OSX_RSPLUG'...                                    not infected
   > ```

1. 备份 chkrootkit 的配置文件 `/etc/chkrootkit.conf`:

   ``` bash
   sudo cp --archive /etc/chkrootkit.conf /etc/chkrootkit.conf-COPY-$(date +"%Y%m%d%H%M%S")
   ```

1. 你希望 chkrootkit 每天运行并通过电子邮件发送结果。
  
   在基于 Debian 的系统上,chkrootkit 自带 cron 脚本。要启用它们,请检查 `/etc/chkrootkit.conf` 或使用 `dpkg-reconfigure` 并对第一个问题回答 `Yes`:
   
   ``` bash
   sudo dpkg-reconfigure chkrootkit
   ```

([Table of Contents](#table-of-contents))

### logwatch - 系统日志分析器和报告器

#### 为什么

你的服务器会产生大量可能包含重要信息的日志。除非你计划每天检查服务器,否则你需要一种方式来获取服务器日志的电子邮件摘要。为此,我们将使用 [logwatch](https://sourceforge.net/projects/logwatch/)。

#### 工作原理

logwatch 扫描系统日志文件并进行汇总。你可以直接从命令行运行它,或安排它按计划重复运行。logwatch 使用服务文件来知道如何读取/汇总日志文件。你可以在 `/usr/share/logwatch/scripts/services` 中查看所有预设的服务文件。

logwatch 的配置文件 `/usr/share/logwatch/default.conf/logwatch.conf` 指定默认选项。你可以通过命令行参数覆盖它们。

#### 目标

- 配置 Logwatch 以每天发送服务器状态和日志的电子邮件摘要

#### 注意事项

- 你的服务器需要能够发送电子邮件才能使其工作
- 以下步骤将导致 logwatch 每天运行。如果你想更改计划,请修改 cron 作业以满足你的需求。你还需要更改 `range` 选项以覆盖你的重复窗口。参见 https://www.badpenguin.org/configure-logwatch-for-weekly-email-and-html-output-format 获取示例。
- 如果 logwatch 因电子邮件中有长行而无法投递邮件,请检查 https://blog.dhampir.no/content/exim4-line-length-in-debian-stretch-mail-delivery-failed-returning-message-to-sender,如 [issue #29](https://github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/29) 所述。如果你遵循了 [Gmail 和 Exim4 作为 MTA 并使用了隐式 TLS](#gmail-and-exim4-as-mta-with-implicit-tls),那么我们在步骤 #7 中已经处理了这个问题。

#### 参考

- 感谢 [amacheema](https://github.com/amacheema) 修复了步骤中的一些问题,并告知我 exim4 的长行错误,如 [issue #29](https://github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/29) 所述。
- https://sourceforge.net/projects/logwatch/
- https://www.digitalocean.com/community/tutorials/how-to-install-and-use-logwatch-log-analyzer-and-reporter-on-a-vps

#### 步骤

1. 安装 logwatch。

   在基于 Debian 的系统上:

   ``` bash
   sudo apt install logwatch
   ```

1. 要查看 logwatch 收集内容的示例,你可以直接运行它:

   ``` bash
   sudo /usr/sbin/logwatch --output stdout --format text --range yesterday --service all
   ```

   > ```
   > 
   >  ################### Logwatch 7.4.3 (12/07/16) ####################
   >         Processing Initiated: Mon Mar  4 00:05:50 2019
   >         Date Range Processed: yesterday
   >                               ( 2019-Mar-03 )
   >                               Period is day.
   >         Detail Level of Output: 5
   >         Type of Output/Format: stdout / text
   >         Logfiles for Host: host
   >  ##################################################################
   > 
   >  --------------------- Cron Begin ------------------------
   > ...
   > ...
   >  ---------------------- Disk Space End -------------------------
   > 
   > 
   >  ###################### Logwatch End #########################
   > ```

1. 在继续之前,浏览 logwatch 的自我文档配置文件 `/usr/share/logwatch/default.conf/logwatch.conf`。无需在此更改任何内容,但请特别注意 `Output`、`Format`、`MailTo`、`Range` 和 `Service`,因为这些是我们将要用到的。为了我们的目的,我们不会在配置文件中指定选项,而是将它们作为命令行参数传递给执行 logwatch 的每日 cron 作业。这样,即使配置文件在更新期间被修改,我们的选项仍然存在。

1. 备份 logwatch 的每日 cron 文件 `/etc/cron.daily/00logwatch` 并取消执行位:

   ``` bash
   sudo cp --archive /etc/cron.daily/00logwatch /etc/cron.daily/00logwatch-COPY-$(date +"%Y%m%d%H%M%S")
   sudo chmod -x /etc/cron.daily/00logwatch-COPY*
   ```

1. 默认情况下,logwatch 输出到 `stdout`。由于目标是每天获取电子邮件,我们需要更改 logwatch 的输出类型,使其改用邮件发送。我们可以通过上面的配置文件来做到这一点,但这将适用于每次运行——即使我们手动运行并希望将输出显示在屏幕上。相反,我们将修改执行 logwatch 的 cron 作业以发送电子邮件。这样,手动运行时我们仍然获得 `stdout` 输出,而由 cron 运行时,它将发送电子邮件。我们还将确保它检查所有服务,并将输出格式更改为 html,以便更易于阅读,无论配置文件如何设置。在文件 `/etc/cron.daily/00logwatch` 中找到执行行,并将其更改为:

   ```
   /usr/sbin/logwatch --output mail --format html --mailto root --range yesterday --service all
   ```

   > ```
   > #!/bin/bash
   > 
   > #Check if removed-but-not-purged
   > test -x /usr/share/logwatch/scripts/logwatch.pl || exit 0
   > 
   > #execute
   > /usr/sbin/logwatch --output mail --format html --mailto root --range yesterday --service all
   > 
   > #Note: It's possible to force the recipient in above command
   > #Just pass --mailto [email protected] instead of --output mail
   > ```

   [对于懒惰的人](#editing-configuration-files---for-the-lazy):
   
   ``` bash
   sudo sed -i -r -e "s,^($(sudo which logwatch).*?),# \1         # commented by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")\n$(sudo which logwatch) --output mail --format html --mailto root --range yesterday --service all         # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")," /etc/cron.daily/00logwatch
   ```

1. 你可以通过执行 cron 作业来测试它:

   ``` bash
   sudo /etc/cron.daily/00logwatch
   ```
   
   **注意**:如果 logwatch 因电子邮件中有长行而无法投递邮件,请检查 https://blog.dhampir.no/content/exim4-line-length-in-debian-stretch-mail-delivery-failed-returning-message-to-sender,如 [issue #29](https://github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/29) 所述。如果你遵循了 [Gmail 和 Exim4 作为 MTA 并使用了隐式 TLS](#gmail-and-exim4-as-mta-with-implicit-tls),那么我们在步骤 #7 中已经处理了这个问题。

([Table of Contents](#table-of-contents))

### ss - 查看服务器正在监听的端口

#### 为什么

端口是应用程序、服务和进程相互通信的方式——无论是在服务器内部还是在网络中与其他设备通信。当你的服务器上运行某个应用程序或服务(如 SSH 或 Apache)时,它们会在特定端口上监听请求。

显然,我们不希望服务器监听未知的端口。我们将使用 `ss` 来查看所有服务正在监听的端口。这将帮助我们追踪并停止潜在危险的恶意服务。

#### 目标

- 找出非本地主机的开放端口并监听连接

#### 参考

- https://www.reddit.com/r/linux/comments/arx7st/howtosecurealinuxserver_an_evolving_howto_guide/egrib6o/
- https://www.reddit.com/r/linux/comments/arx7st/howtosecurealinuxserver_an_evolving_howto_guide/egs1rev/
- https://www.tecmint.com/find-open-ports-in-linux/
- `man ss`

#### 步骤

1. 查看所有监听流量的端口:

   ``` bash
   sudo ss -lntup
   ```
   
   > ```
   > Netid  State      Recv-Q Send-Q     Local Address:Port     Peer Address:Port
   > udp    UNCONN     0      0                      *:68                  *:*        users:(("dhclient",pid=389,fd=6))
   > tcp    LISTEN     0      128                    *:22                  *:*        users:(("sshd",pid=4390,fd=3))
   > tcp    LISTEN     0      128                   :::22                 :::*        users:(("sshd",pid=4390,fd=4))
   > ```
   
   **参数解释**:
   - `l` = 显示监听套接字
   - `n` = 不尝试解析服务名称
   - `t` = 显示 TCP 套接字
   - `u` = 显示 UDP 套接字
   - `p` = 显示进程信息

1. 如果你发现任何可疑内容,例如你不知道的端口或未知进程,请进行调查并根据需要进行补救。

([Table of Contents](#table-of-contents))

### Lynis - Linux 安全审计

#### 为什么

来自 [https://cisofy.com/lynis/](https://cisofy.com/lynis/):

> Lynis 是一个久经考验的安全工具,适用于运行 Linux、macOS 或基于 Unix 的操作系统的系统。它对系统进行广泛的健康扫描,以支持系统加固和合规性测试。

#### 目标

- 安装 Lynis

#### 注意事项

- CISOFY 为许多发行版提供软件包。请查看 https://packages.cisofy.com/ 获取特定发行版的安装说明。

#### 参考

- https://cisofy.com/documentation/lynis/get-started/
- https://packages.cisofy.com/community/#debian-ubuntu
- https://thelinuxcode.com/audit-lynis-ubuntu-server/
- https://www.vultr.com/docs/install-lynis-on-debian-8

#### 步骤

1. 安装 lynis。https://cisofy.com/lynis/#installation 上提供了针对你发行版的详细安装说明。

   在基于 Debian 的系统上,使用 CISOFY 的社区软件仓库:

   ``` bash
   sudo apt install ca-certificates host
   sudo mkdir -p /etc/apt/keyrings

Read more

下载工具
  • 发送/备份日志 - https://news.ycombinator.com/item?id=19178681
  • CIS-CAT - https://learn.cisecurity.org/cis-cat-landing-page
  • debsums - https://blog.sleeplessbeastie.eu/2015/03/02/how-to-verify-installed-packages/
  • 中间人攻击
    ssh-copy-id
    root@kitploit:~
    ssh-copy-id user@server
    
    root@kitploit:~
    /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/user/.ssh/id_ed25519.pub"
    The authenticity of host 'host (192.168.1.96)' can't be established.
    ECDSA key fingerprint is SHA256:QaDQb/X0XyVlogh87sDXE7MR8YIK7ko4wS5hXjRySJE.
    Are you sure you want to continue connecting (yes/no)? yes
    /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
    /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
    user@host's password:
    
    Number of key(s) added: 1
    
    Now try logging into the machine, with:   "ssh 'user@host'"
    and check to make sure that only the key(s) you wanted were added.
    
  • 然后查找并编辑或添加这些设置,并根据您的要求设置值:

    设置项有效值示例描述备注
    AllowGroups本地 UNIX 组名AllowGroups sshusers允许 SSH 访问的组
    ClientAliveCountMax数字ClientAliveCountMax 3未收到响应的客户端存活消息最大数量
    ClientAliveInterval秒数ClientAliveInterval 15发送响应请求之前的超时秒数
    ListenAddress空格分隔的本地地址列表
    • ListenAddress 0.0.0.0
    • ListenAddress 192.168.1.100
    sshd 应监听的本地地址有关重要细节,请参阅问题 #1。
    LoginGraceTime秒数LoginGraceTime 30登录超时前的秒数
    MaxAuthTries数字MaxAuthTries 2允许的最大登录尝试次数
    MaxSessions数字MaxSessions 2最大打开的会话数
    MaxStartups数字MaxStartups 2最大登录会话数
    PasswordAuthenticationyes 或 noPasswordAuthentication no是否允许使用密码登录
    Port任何打开/可用的端口号Port 22sshd 应监听的端口

    有关这些设置项的更多详细信息,请查看 man sshd_config。

  • 确保没有重复且矛盾的设置。以下命令应该没有任何输出。

    root@kitploit:~
    awk 'NF && $1!~/^(#|HostKey)/{print $1}' /etc/ssh/sshd_config | sort | uniq -c | grep -v ' 1 '
    
  • 重启 ssh:

    root@kitploit:~
    sudo service sshd restart
    
  • 您可以使用 sshd -T 验证配置是否生效,并检查输出:

    root@kitploit:~
    sudo sshd -T
    
    root@kitploit:~
    port 22
    addressfamily any
    listenaddress [::]:22
    listenaddress 0.0.0.0:22
    usepam yes
    logingracetime 30
    x11displayoffset 10
    maxauthtries 2
    maxsessions 2
    clientaliveinterval 15
    clientalivecountmax 3
    streamlocalbindmask 0177
    permitrootlogin no
    ignorerhosts yes
    ignoreuserknownhosts no
    hostbasedauthentication no
    ...
    subsystem sftp internal-sftp -f AUTHPRIV -l INFO
    maxstartups 2:30:2
    permittunnel no
    ipqos lowdelay throughput
    rekeylimit 0 0
    permitopen any
    
  • 注意不要以 root 身份运行。

    对于所有问题选择默认选项(在大多数情况下选 y),并记住保存紧急备用码。

  • 备份 PAM 的 SSH 配置文件 /etc/pam.d/sshd:

    root@kitploit:~
    sudo cp --archive /etc/pam.d/sshd /etc/pam.d/sshd-COPY-$(date +"%Y%m%d%H%M%S")
    
  • 现在需要将其作为 SSH 的认证方法启用,方法是向 /etc/pam.d/sshd 添加以下行:

    root@kitploit:~
    auth       required     pam_google_authenticator.so nullok
    

    注意:查看此处了解 nullok 的含义。

    对于懒人:

    root@kitploit:~
    echo -e "\nauth       required     pam_google_authenticator.so nullok         # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")" | sudo tee -a /etc/pam.d/sshd
    
  • 告诉 SSH 使用它,方法是在 /etc/ssh/sshd_config 中添加或编辑以下行:

    root@kitploit:~
    ChallengeResponseAuthentication yes
    

    对于懒人:

    root@kitploit:~
    sudo sed -i -r -e "s/^(challengeresponseauthentication .*)$/# \1         # commented by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/I" /etc/ssh/sshd_config
    echo -e "\nChallengeResponseAuthentication yes         # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")" | sudo tee -a /etc/ssh/sshd_config
    
  • 重启 ssh:

    root@kitploit:~
    sudo service sshd restart
    
  • 重新启动服务以应用更改:

    root@kitploit:~
    sudo systemctl restart systemd-timesyncd
    
  • 检查同步状态:

    root@kitploit:~
    timedatectl timesync-status
    
    root@kitploit:~
           Server: 108.61.56.35 (pool.ntp.org)
    Poll interval: 32s (min: 32s; max: 34min 8s)
             Leap: normal
          Version: 4
          Stratum: 2
        Reference: C342F10A
        Precision: 1us (2^0)
     Root distance: 24.054ms (max: 5s)
           Offset: +2.156ms
            Delay: 48.567ms
           Jitter: 1.452ms
     Packet count: 3
    
  • 示例 /etc/ntp.conf:

    root@kitploit:~
    driftfile /var/lib/ntp/ntp.drift
    statistics loopstats peerstats clockstats
    filegen loopstats file loopstats type day enable
    filegen peerstats file peerstats type day enable
    filegen clockstats file clockstats type day enable
    restrict -4 default kod notrap nomodify nopeer noquery limited
    restrict -6 default kod notrap nomodify nopeer noquery limited
    restrict 127.0.0.1
    restrict ::1
    restrict source notrap nomodify noquery
    pool pool.ntp.org iburst         # added by user on 2019-03-09 @ 10:23:35
    
  • 重启 ntp:

    root@kitploit:~
    sudo service ntp restart
    
  • 检查 ntp 服务的状态:

    root@kitploit:~
    sudo systemctl status ntp
    
    root@kitploit:~
    ● ntp.service - LSB: Start NTP daemon
       Loaded: loaded (/etc/init.d/ntp; generated; vendor preset: enabled)
       Active: active (running) since Sat 2019-03-09 15:19:46 EST; 4s ago
         Docs: man:systemd-sysv-generator(8)
      Process: 1016 ExecStop=/etc/init.d/ntp stop (code=exited, status=0/SUCCESS)
      Process: 1028 ExecStart=/etc/init.d/ntp start (code=exited, status=0/SUCCESS)
        Tasks: 2 (limit: 4915)
       CGroup: /system.slice/ntp.service
               └─1038 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 108:113
    
    Mar 09 15:19:46 host ntpd[1038]: Listen and drop on 0 v6wildcard [::]:123
    Mar 09 15:19:46 host ntpd[1038]: Listen and drop on 1 v4wildcard 0.0.0.0:123
    Mar 09 15:19:46 host ntpd[1038]: Listen normally on 2 lo 127.0.0.1:123
    Mar 09 15:19:46 host ntpd[1038]: Listen normally on 3 enp0s3 10.10.20.96:123
    Mar 09 15:19:46 host ntpd[1038]: Listen normally on 4 lo [::1]:123
    Mar 09 15:19:46 host ntpd[1038]: Listen normally on 5 enp0s3 [fe80::a00:27ff:feb6:ed8e%2]:123
    Mar 09 15:19:46 host ntpd[1038]: Listening on routing socket on fd #22 for interface updates
    Mar 09 15:19:47 host ntpd[1038]: Soliciting pool server 108.61.56.35
    Mar 09 15:19:48 host ntpd[1038]: Soliciting pool server 69.89.207.199
    Mar 09 15:19:49 host ntpd[1038]: Soliciting pool server 45.79.111.114
    
  • 检查 ntp 的状态:

    root@kitploit:~
    sudo ntpq -p
    
    root@kitploit:~
         remote           refid      st t when poll reach   delay   offset  jitter
    ==============================================================================
     pool.ntp.org    .POOL.          16 p    -   64    0    0.000    0.000   0.000
    *lithium.constan 198.30.92.2      2 u    -   64    1   19.900    4.894   3.951
     ntp2.wiktel.com 212.215.1.157    2 u    2   64    1   48.061   -0.431   0.104
    
  • 一个大写字母
  • lcredit=-1 = 必须至少包含一个小写字母
  • ocredit=-1 = 必须至少包含一个非字母数字字符
  • difok=3 = 新密码中至少有 3 个字符不能与旧密码相同
  • maxrepeat=3 = 最多允许 3 个重复字符
  • gecoschec = 不允许包含账户名称的密码
  • 给懒人用:

    root@kitploit:~
    sudo sed -i -r -e "s/^(password\s+requisite\s+pam_pwquality.so)(.*)$/# \1\2         # commented by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")\n\1 retry=3 minlen=10 difok=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 maxrepeat=3 gecoschec         # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/" /etc/pam.d/common-password
    

    注意:

    • 有关 APT::Periodic 选项的详细信息,请查看 /usr/lib/apt/apt.systemd.daily
    • 有关 Unattended-Upgrade 选项的详细信息,请查看 https://github.com/mvo5/unattended-upgrades
  • 运行 unattended-upgrades 的试运行以确保配置文件正确:

    root@kitploit:~
    sudo unattended-upgrade -d --dry-run
    

    如果一切正常,您可以让它按计划运行,或者使用 unattended-upgrade -d 强制运行。

  • 根据需要配置 apt-listchanges:

    root@kitploit:~
    sudo dpkg-reconfigure apt-listchanges
    
  • 对于 apticron,默认设置已经足够,但如果您想更改,可以检查 /etc/apticron/apticron.conf。例如,我的配置如下所示:

    root@kitploit:~
    EMAIL="root"
    NOTIFY_NO_UPDATES="1"